diff --git a/.editorconfig b/.editorconfig
index df93ae3a16..13dcd5e029 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -6,3 +6,6 @@ indent_size = 4
[*.yml]
indent_style = space
indent_size = 2
+
+[*.txt]
+insert_final_newline = false
diff --git a/README.md b/README.md
index ed82fb08e6..2a1ffe65ec 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,5 @@
-
-##Citadel Station 13
-Based and maintained from /tg/station.
+## Citadel Station 13
+Based and maintained from /tg/station.
[](https://forthebadge.com) [](https://forthebadge.com) [](http://forthebadge.com)
@@ -10,18 +9,19 @@ Based and maintained from /tg/station.
[](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Percentage of issues still open") [](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Average time to resolve an issue")
-**Upstream Information**
-**Website:** http://www.tgstation13.org
-**Code:** https://github.com/tgstation/tgstation
-**Wiki** http://tgstation13.org/wiki/Main_Page
-**IRC:** irc://irc.rizon.net/coderbus or if you dont have an IRC client, you can click [here](https://kiwiirc.com/client/irc.rizon.net:6667/?&theme=cli#coderbus).
-
-**Citadel Station Information**
-**Forums:** http://citadel-station.net/forum/
-**Ban Appeals:** http://citadel-station.net/forum/forumdisplay.php?fid=8
-**Code:** https://github.com/Citadel-Station-13/Citadel-Station-13
-**Discord:** [Here](https://discord.gg/E6SQuhz).
-
+**Upstream Information**
+**Website:** https://tgstation13.org
+**Code:** https://github.com/tgstation/tgstation
+**Wiki** https://tgstation13.org/wiki/Main_Page
+**IRC:** irc://irc.rizon.net/coderbus or if you dont have an IRC client, you can click [here](https://kiwiirc.com/client/irc.rizon.net:6667/?&theme=cli#coderbus).
+
+**Citadel Station Information**
+**Website:** http://citadel-station.net
+**Forums:** http://citadel-station.net/forum
+**Ban Appeals:** http://citadel-station.net/forum/forumdisplay.php?fid=8
+**Code:** https://github.com/Citadel-Station-13/Citadel-Station-13
+**Discord:** [Here](https://discord.gg/E6SQuhz)
+
## DOWNLOADING
There are a number of ways to download the source code. Some are described here, an alternative all-inclusive guide is also located at http://www.tgstation13.org/wiki/Downloading_the_source_code
diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index 56126c6e37..f5b76d1ba9 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -173,6 +173,19 @@
"aay" = (
/turf/open/floor/plating,
/area/security/prison)
+"aaz" = (
+/obj/structure/lattice/catwalk,
+/obj/item/stack/marker_beacon{
+ anchored = 1;
+ icon_state = "markerburgundy-on";
+ light_color = "#FA644B";
+ light_power = 3;
+ light_range = 3;
+ name = "Docking Beacon";
+ picked_color = "Burgundy"
+ },
+/turf/open/space/basic,
+/area/space/nearstation)
"aaA" = (
/obj/machinery/seed_extractor,
/turf/open/floor/plasteel,
@@ -234,10 +247,46 @@
/obj/structure/chair/stool,
/turf/open/floor/plasteel,
/area/security/prison)
+"aaK" = (
+/obj/structure/lattice/catwalk,
+/obj/item/stack/marker_beacon{
+ anchored = 1;
+ icon_state = "markerburgundy-on";
+ light_color = "#FA644B";
+ light_power = 3;
+ light_range = 3;
+ name = "Docking Beacon";
+ picked_color = "Burgundy"
+ },
+/turf/open/floor/plating,
+/area/space/nearstation)
+"aaL" = (
+/obj/machinery/photocopier,
+/turf/open/floor/wood,
+/area/library)
+"aaM" = (
+/obj/structure/disposalpipe/segment,
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/obj/structure/cable{
+ icon_state = "2-8"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/obj/effect/turf_decal/tile/brown,
+/obj/effect/turf_decal/tile/brown{
+ dir = 8
+ },
+/turf/open/floor/plasteel,
+/area/quartermaster/office)
"aaN" = (
/obj/structure/chair/sofa/right,
/turf/open/floor/plasteel,
/area/security/prison)
+"aaO" = (
+/obj/effect/spawner/lootdrop/keg,
+/turf/open/floor/plating,
+/area/maintenance/starboard/aft)
"aaP" = (
/obj/machinery/computer/cryopod{
dir = 8;
@@ -248,6 +297,12 @@
},
/turf/open/floor/plasteel,
/area/security/prison)
+"aaQ" = (
+/obj/structure/sign/poster/contraband/random{
+ pixel_y = 32
+ },
+/turf/open/floor/plating,
+/area/maintenance/starboard/aft)
"aaR" = (
/obj/structure/lattice,
/obj/structure/sign/warning/securearea{
@@ -285,6 +340,15 @@
},
/turf/open/floor/plasteel,
/area/security/prison)
+"aaY" = (
+/obj/structure/closet,
+/obj/effect/spawner/lootdrop/maintenance{
+ lootcount = 4;
+ name = "4maintenance loot spawner"
+ },
+/obj/item/poster/random_official,
+/turf/open/floor/plating,
+/area/maintenance/starboard/aft)
"aaZ" = (
/turf/closed/wall/r_wall,
/area/ai_monitored/security/armory)
@@ -505,6 +569,11 @@
"abF" = (
/turf/open/floor/plasteel/freezer,
/area/security/prison)
+"abG" = (
+/obj/structure/door_assembly/door_assembly_mai,
+/obj/item/electronics/airlock,
+/turf/open/floor/plating,
+/area/maintenance/starboard/aft)
"abH" = (
/obj/structure/table,
/obj/item/storage/box/chemimp{
@@ -1565,6 +1634,10 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/carpet,
/area/crew_quarters/heads/hos)
+"adO" = (
+/obj/effect/spawner/structure/window/shuttle,
+/turf/open/floor/plating/airless,
+/area/space/nearstation)
"adP" = (
/obj/structure/cable{
icon_state = "2-8"
@@ -1979,6 +2052,34 @@
},
/turf/open/floor/plating,
/area/maintenance/fore/secondary)
+"aeD" = (
+/obj/structure/grille/broken,
+/turf/open/floor/plating/airless,
+/area/space/nearstation)
+"aeE" = (
+/obj/structure/girder,
+/turf/open/floor/plating/airless,
+/area/space/nearstation)
+"aeF" = (
+/obj/machinery/airalarm{
+ dir = 4;
+ pixel_x = -23
+ },
+/obj/machinery/computer/station_alert{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/neutral,
+/obj/effect/turf_decal/tile/neutral{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 8
+ },
+/turf/open/floor/plasteel/dark,
+/area/ai_monitored/turret_protected/aisat_interior)
"aeG" = (
/obj/structure/cable,
/obj/machinery/power/solar{
@@ -2357,6 +2458,12 @@
},
/turf/open/floor/plasteel,
/area/security/main)
+"afn" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
+ dir = 4
+ },
+/turf/open/floor/plasteel/grimy,
+/area/ai_monitored/turret_protected/aisat_interior)
"afo" = (
/obj/machinery/door/airlock/external{
name = "Escape Pod Three"
@@ -2377,6 +2484,39 @@
},
/turf/open/space/basic,
/area/space)
+"afq" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/open/floor/plasteel/grimy,
+/area/ai_monitored/turret_protected/aisat_interior)
+"afr" = (
+/obj/machinery/atmospherics/pipe/manifold4w/scrubbers,
+/turf/open/floor/plasteel/grimy,
+/area/ai_monitored/turret_protected/aisat_interior)
+"afs" = (
+/obj/machinery/computer/security/telescreen/entertainment{
+ pixel_x = -31
+ },
+/obj/machinery/computer/monitor{
+ dir = 4
+ },
+/obj/structure/cable{
+ icon_state = "0-4"
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/neutral,
+/obj/effect/turf_decal/tile/neutral{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 8
+ },
+/turf/open/floor/plasteel/dark,
+/area/ai_monitored/turret_protected/aisat_interior)
"aft" = (
/obj/machinery/atmospherics/pipe/simple/general/visible{
dir = 5
@@ -2687,6 +2827,15 @@
/obj/machinery/atmospherics/pipe/manifold4w/general/visible,
/turf/open/floor/plasteel,
/area/engine/atmos)
+"age" = (
+/obj/structure/chair/office/dark{
+ dir = 8
+ },
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/turf/open/floor/plasteel/grimy,
+/area/ai_monitored/turret_protected/aisat_interior)
"agf" = (
/obj/structure/table,
/obj/item/stack/sheet/metal,
@@ -2836,6 +2985,10 @@
/obj/machinery/suit_storage_unit/security,
/turf/open/floor/plasteel/showroomfloor,
/area/security/warden)
+"agv" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
+/turf/open/floor/plasteel/grimy,
+/area/ai_monitored/turret_protected/aisat_interior)
"agw" = (
/obj/structure/table,
/obj/machinery/syndicatebomb/training,
@@ -2965,6 +3118,14 @@
},
/turf/open/floor/plasteel,
/area/security/main)
+"agH" = (
+/obj/machinery/bluespace_beacon,
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/obj/effect/landmark/start/cyborg,
+/turf/open/floor/plasteel/dark,
+/area/ai_monitored/turret_protected/aisat_interior)
"agI" = (
/obj/machinery/airalarm{
pixel_y = 23
@@ -3094,6 +3255,12 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/security/warden)
+"agX" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on{
+ dir = 4
+ },
+/turf/open/floor/plasteel/grimy,
+/area/ai_monitored/turret_protected/aisat_interior)
"agY" = (
/obj/structure/table,
/obj/item/storage/fancy/donut_box,
@@ -3334,6 +3501,16 @@
},
/turf/open/floor/plasteel/showroomfloor,
/area/security/warden)
+"ahw" = (
+/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden,
+/obj/structure/cable{
+ icon_state = "2-4"
+ },
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/turf/open/floor/plasteel/grimy,
+/area/ai_monitored/turret_protected/aisat_interior)
"ahx" = (
/obj/structure/cable{
icon_state = "4-8"
@@ -4474,6 +4651,16 @@
/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden,
/turf/open/floor/plasteel,
/area/security/brig)
+"ajC" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/turf/open/floor/plasteel/grimy,
+/area/ai_monitored/turret_protected/aisat_interior)
"ajD" = (
/obj/structure/cable{
icon_state = "4-8"
@@ -4682,6 +4869,18 @@
/obj/effect/mapping_helpers/airlock/cyclelink_helper,
/turf/open/floor/plating,
/area/maintenance/solars/port/fore)
+"ajX" = (
+/obj/machinery/computer/teleporter{
+ dir = 8
+ },
+/turf/open/floor/plating,
+/area/ai_monitored/turret_protected/aisat_interior)
+"ajY" = (
+/obj/machinery/holopad,
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/obj/effect/landmark/start/cyborg,
+/turf/open/floor/plasteel/dark,
+/area/ai_monitored/turret_protected/aisat/atmos)
"ajZ" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/sign/warning/vacuum/external{
@@ -4965,6 +5164,18 @@
},
/turf/open/floor/plasteel,
/area/security/courtroom)
+"akz" = (
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/obj/machinery/holopad,
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/obj/effect/landmark/start/cyborg,
+/turf/open/floor/plasteel/dark,
+/area/ai_monitored/turret_protected/aisat_interior)
"akA" = (
/obj/structure/chair{
dir = 8;
@@ -29979,17 +30190,6 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/central)
-"bwc" = (
-/obj/structure/disposalpipe/segment,
-/obj/structure/cable{
- icon_state = "1-2"
- },
-/obj/structure/cable{
- icon_state = "2-8"
- },
-/obj/machinery/atmospherics/pipe/simple/supply/hidden,
-/turf/open/floor/plasteel,
-/area/quartermaster/office)
"bwd" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
@@ -49288,47 +49488,9 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
-"ctu" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
- dir = 4
- },
-/obj/effect/landmark/start/cyborg,
-/turf/open/floor/plasteel/grimy,
-/area/ai_monitored/turret_protected/aisat_interior)
"ctv" = (
/turf/closed/wall/r_wall,
/area/space/nearstation)
-"ctw" = (
-/obj/machinery/airalarm{
- dir = 4;
- pixel_x = -23
- },
-/obj/machinery/computer/station_alert,
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 8
- },
-/turf/open/floor/plasteel/dark,
-/area/ai_monitored/turret_protected/aisat_interior)
-"ctx" = (
-/obj/machinery/atmospherics/pipe/manifold4w/scrubbers,
-/obj/effect/landmark/start/cyborg,
-/turf/open/floor/plasteel/grimy,
-/area/ai_monitored/turret_protected/aisat_interior)
-"cty" = (
-/obj/machinery/atmospherics/pipe/simple/supply/hidden,
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
- dir = 4
- },
-/obj/effect/landmark/start/cyborg,
-/turf/open/floor/plasteel/grimy,
-/area/ai_monitored/turret_protected/aisat_interior)
"ctz" = (
/obj/machinery/door/poddoor/shutters{
id = "teledoor";
@@ -49373,41 +49535,6 @@
},
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
-"ctG" = (
-/obj/structure/chair/office/dark{
- dir = 8
- },
-/obj/structure/cable{
- icon_state = "4-8"
- },
-/obj/effect/landmark/start/cyborg,
-/turf/open/floor/plasteel/grimy,
-/area/ai_monitored/turret_protected/aisat_interior)
-"ctH" = (
-/obj/machinery/computer/security/telescreen/entertainment{
- pixel_x = -31
- },
-/obj/machinery/computer/monitor,
-/obj/structure/cable{
- icon_state = "0-4"
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 8
- },
-/turf/open/floor/plasteel/dark,
-/area/ai_monitored/turret_protected/aisat_interior)
-"ctI" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
-/obj/effect/landmark/start/cyborg,
-/turf/open/floor/plasteel/grimy,
-/area/ai_monitored/turret_protected/aisat_interior)
"ctJ" = (
/obj/machinery/holopad,
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
@@ -49431,13 +49558,6 @@
},
/turf/open/floor/plating,
/area/ai_monitored/turret_protected/aisat_interior)
-"ctM" = (
-/obj/machinery/bluespace_beacon,
-/obj/effect/turf_decal/stripes/line{
- dir = 4
- },
-/turf/open/floor/plasteel/dark,
-/area/ai_monitored/turret_protected/aisat_interior)
"ctN" = (
/obj/machinery/atmospherics/pipe/simple/yellow/visible{
dir = 10
@@ -49445,13 +49565,6 @@
/obj/structure/lattice,
/turf/open/space,
/area/space/nearstation)
-"ctP" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on{
- dir = 4
- },
-/obj/effect/landmark/start/cyborg,
-/turf/open/floor/plasteel/grimy,
-/area/ai_monitored/turret_protected/aisat_interior)
"ctQ" = (
/obj/structure/table,
/obj/machinery/microwave{
@@ -49477,28 +49590,6 @@
/obj/structure/sign/warning/radiation/rad_area,
/turf/closed/wall,
/area/engine/engineering)
-"ctS" = (
-/obj/machinery/atmospherics/pipe/simple/supply/hidden{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
-/obj/structure/cable{
- icon_state = "4-8"
- },
-/obj/effect/landmark/start/cyborg,
-/turf/open/floor/plasteel/grimy,
-/area/ai_monitored/turret_protected/aisat_interior)
-"ctT" = (
-/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden,
-/obj/structure/cable{
- icon_state = "2-4"
- },
-/obj/structure/cable{
- icon_state = "1-2"
- },
-/obj/effect/landmark/start/cyborg,
-/turf/open/floor/plasteel/grimy,
-/area/ai_monitored/turret_protected/aisat_interior)
"ctU" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
@@ -49521,10 +49612,6 @@
/obj/structure/chair,
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
-"ctW" = (
-/obj/machinery/computer/teleporter,
-/turf/open/floor/plating,
-/area/ai_monitored/turret_protected/aisat_interior)
"ctX" = (
/obj/machinery/camera{
c_tag = "MiniSat Teleporter";
@@ -49805,11 +49892,6 @@
},
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat/atmos)
-"cuC" = (
-/obj/machinery/holopad,
-/obj/machinery/atmospherics/pipe/simple/supply/hidden,
-/turf/open/floor/plasteel/dark,
-/area/ai_monitored/turret_protected/aisat/atmos)
"cuD" = (
/obj/machinery/light/small{
dir = 8
@@ -49858,17 +49940,6 @@
},
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
-"cuG" = (
-/obj/structure/cable{
- icon_state = "1-2"
- },
-/obj/machinery/holopad,
-/obj/machinery/atmospherics/pipe/simple/supply/hidden,
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
- dir = 4
- },
-/turf/open/floor/plasteel/dark,
-/area/ai_monitored/turret_protected/aisat_interior)
"cuH" = (
/obj/machinery/light/small{
dir = 8
@@ -53259,13 +53330,6 @@
},
/turf/open/floor/mineral/titanium/blue,
/area/crew_quarters/dorms)
-"dkk" = (
-/obj/machinery/photocopier{
- pixel_x = -5;
- pixel_y = -5
- },
-/turf/open/floor/wood,
-/area/library)
"dok" = (
/obj/item/twohanded/required/kirbyplants{
icon_state = "plant-22"
@@ -53692,18 +53756,6 @@
dir = 1
},
/area/crew_quarters/fitness)
-"fsk" = (
-/obj/structure/lattice/catwalk,
-/obj/item/stack/marker_beacon{
- anchored = 1;
- icon_state = "markerburgundy-on";
- light_power = 3;
- light_range = 3;
- name = "Docking Beacon";
- picked_color = "Burgundy"
- },
-/turf/open/floor/plating,
-/area/space/nearstation)
"ftv" = (
/obj/structure/table,
/obj/effect/spawner/lootdrop/maintenance{
@@ -54203,18 +54255,6 @@
dir = 1
},
/area/crew_quarters/fitness)
-"hho" = (
-/obj/structure/lattice/catwalk,
-/obj/item/stack/marker_beacon{
- anchored = 1;
- icon_state = "markerburgundy-on";
- light_power = 3;
- light_range = 3;
- name = "Docking Beacon";
- picked_color = "Burgundy"
- },
-/turf/open/space/basic,
-/area/space/nearstation)
"hik" = (
/obj/structure/lattice/catwalk,
/obj/structure/cable{
@@ -54439,9 +54479,6 @@
"iiW" = (
/turf/open/floor/wood,
/area/maintenance/bar)
-"ikx" = (
-/turf/open/floor/plating/foam,
-/area/space/nearstation)
"ilJ" = (
/obj/effect/turf_decal/tile/red,
/obj/machinery/light{
@@ -55678,10 +55715,6 @@
/obj/structure/extinguisher_cabinet,
/turf/closed/wall/r_wall,
/area/hallway/primary/central)
-"mwb" = (
-/obj/effect/spawner/structure/window/shuttle,
-/turf/open/floor/plating,
-/area/space/nearstation)
"mwO" = (
/obj/structure/cable{
icon_state = "1-4"
@@ -56489,7 +56522,8 @@
icon_state = "4-8"
},
/obj/machinery/door/airlock/command{
- name = "Command Access To Vault"
+ name = "Command Access To Vault";
+ req_access = "19"
},
/turf/open/floor/plasteel/dark,
/area/bridge/meeting_room)
@@ -56803,10 +56837,6 @@
/obj/item/target/syndicate,
/turf/open/floor/plating,
/area/security/prison)
-"rxH" = (
-/obj/structure/girder,
-/turf/open/floor/plating,
-/area/space/nearstation)
"rzg" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
@@ -57253,12 +57283,6 @@
},
/turf/open/floor/plating,
/area/maintenance/port/aft)
-"thr" = (
-/obj/structure/frame/computer{
- dir = 1
- },
-/turf/open/floor/plating,
-/area/space/nearstation)
"tkU" = (
/turf/open/floor/wood{
icon_state = "wood-broken5"
@@ -58554,10 +58578,6 @@
},
/turf/open/space/basic,
/area/space/nearstation)
-"xWM" = (
-/obj/structure/grille/broken,
-/turf/open/floor/plating,
-/area/space/nearstation)
"xXY" = (
/obj/structure/closet/lasertag/red,
/obj/item/clothing/under/pj/red,
@@ -64623,11 +64643,11 @@ aaa
aaa
aaa
aaa
-fsk
+aaK
aaa
aaa
aaa
-fsk
+aaK
aaa
aaa
aaa
@@ -64874,9 +64894,9 @@ aaa
aaa
aaa
aaa
-fsk
+aaK
aaa
-fsk
+aaK
aaa
aaa
aaa
@@ -64888,9 +64908,9 @@ gXs
aaa
aaa
aaa
-fsk
+aaK
aaa
-fsk
+aaK
aaa
aaa
aaa
@@ -81103,7 +81123,7 @@ bpB
bpB
brR
bsV
-bwc
+aaM
bxA
bvI
bwX
@@ -95688,9 +95708,9 @@ aaa
aaa
aaa
aaa
-hho
+aaz
aaa
-hho
+aaz
aaa
aaa
aaa
@@ -96072,7 +96092,7 @@ aaf
ctZ
cui
cuq
-cuC
+ajY
cuO
cuz
cvm
@@ -96580,8 +96600,8 @@ czk
cti
cua
cua
-ctw
-ctH
+aeF
+afs
ctQ
cuc
cuj
@@ -96837,9 +96857,9 @@ ctb
cth
cua
ctr
-ctu
-ctG
-ctP
+afn
+age
+agX
cub
cuj
cur
@@ -97094,13 +97114,13 @@ ctc
ctc
cto
ctt
-cty
+afq
ctJ
-ctT
+ahw
cue
cul
cuu
-cuG
+akz
cuS
cve
cvo
@@ -97351,9 +97371,9 @@ ctb
ctj
ctk
cts
-ctx
-ctI
-ctS
+afr
+agv
+ajC
cud
cuk
cus
@@ -98123,7 +98143,7 @@ aaa
aaf
cua
ctF
-ctM
+agH
ctX
cuf
cum
@@ -98381,7 +98401,7 @@ aaf
cua
ctE
ctL
-ctW
+ajX
cuf
cum
cuw
@@ -101379,7 +101399,7 @@ bbE
aIr
bav
aLf
-dkk
+aaL
kLR
aRO
aQp
@@ -101961,10 +101981,10 @@ aaa
aaa
aaa
aaa
-ikx
-mwb
-xWM
-rxH
+aaH
+adO
+aeD
+aeE
aaa
aaa
aaa
@@ -102219,10 +102239,10 @@ xNY
kvb
aaa
aaa
-ikx
-ikx
-ikx
-rxH
+aaH
+aaH
+aaH
+aeE
aaa
aaa
aaa
@@ -102473,13 +102493,13 @@ czZ
cOT
aaa
jmC
-dbM
-dbM
-ikx
-ikx
-ikx
-thr
-mwb
+aaH
+aaH
+aaH
+aaH
+aaH
+aaH
+adO
aaa
aaa
aaa
@@ -102732,8 +102752,8 @@ gXs
xNY
kvb
gJg
-dbM
-dbM
+aaH
+aaH
aaa
aaa
gJg
@@ -102990,8 +103010,8 @@ aaa
aaa
gJg
gJg
-mwb
-ikx
+adO
+aaH
gXs
aaa
aaa
@@ -106072,7 +106092,7 @@ cNW
clt
cQw
cNW
-cNW
+abG
cNW
cNW
aaf
@@ -106328,7 +106348,7 @@ aaa
cOT
clt
cQw
-cOe
+aaO
cOe
cOe
cNW
@@ -106585,11 +106605,11 @@ aaa
cOT
clt
cQw
+aaQ
cOe
cOe
-cOe
-cOe
-sQX
+cNW
+aaa
jzi
jzi
jzi
@@ -106842,11 +106862,11 @@ aaa
cNW
clt
cQw
-cOe
+bNB
cOe
cOe
cNW
-aaf
+lCL
aaS
aaa
aaf
@@ -107099,7 +107119,7 @@ cNW
cNW
clt
cQw
-cOe
+aaY
cOe
cOe
cNW
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 7fbd2921e8..cd50d90edb 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -44934,7 +44934,7 @@
/area/maintenance/port)
"bKY" = (
/obj/machinery/power/apc{
- areastring = "/area/vacant_room/office";
+ areastring = "/area/security/vacantoffice";
dir = 8;
name = "Vacant Office APC";
pixel_x = -25
diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm
index 4052dce40d..6913473e88 100644
--- a/code/__DEFINES/DNA.dm
+++ b/code/__DEFINES/DNA.dm
@@ -136,8 +136,12 @@
#define ORGAN_SLOT_TESTICLES "testicles"
#define ORGAN_SLOT_BREASTS "breasts"
-
////organ defines
#define STANDARD_ORGAN_THRESHOLD 100
#define STANDARD_ORGAN_HEALING 0.001
-#define STANDARD_ORGAN_DECAY 0.00222 //designed to fail organs when left to decay for ~15 minutes
\ No newline at end of file
+#define STANDARD_ORGAN_DECAY 0.00222 //designed to fail organs when left to decay for ~15 minutes
+
+#define G_MALE 1
+#define G_FEMALE 2
+#define G_PLURAL 3
+#define G_NEUTER 4
diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm
index cc1b474c49..4304af77f3 100644
--- a/code/__DEFINES/combat.dm
+++ b/code/__DEFINES/combat.dm
@@ -184,7 +184,7 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
#define BODY_ZONE_PRECISE_R_FOOT "r_foot"
//We will round to this value in damage calculations.
-#define DAMAGE_PRECISION 0.1
+#define DAMAGE_PRECISION 0.01
//items total mass, used to calculate their attacks' stamina costs. If not defined, the cost will be (w_class * 1.25)
#define TOTAL_MASS_TINY_ITEM 1.25
@@ -202,4 +202,4 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
#define BULLET_ACT_HIT "HIT" //It's a successful hit, whatever that means in the context of the thing it's hitting.
#define BULLET_ACT_BLOCK "BLOCK" //It's a blocked hit, whatever that means in the context of the thing it's hitting.
#define BULLET_ACT_FORCE_PIERCE "PIERCE" //It pierces through the object regardless of the bullet being piercing by default.
-#define BULLET_ACT_TURF "TURF" //It hit us but it should hit something on the same turf too. Usually used for turfs.
\ No newline at end of file
+#define BULLET_ACT_TURF "TURF" //It hit us but it should hit something on the same turf too. Usually used for turfs.
diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index 20679a95e6..a4ee7cc3cc 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -123,6 +123,7 @@
#define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new" //from base of turf/New(): (turf/source, direction)
// /atom/movable signals
+#define COMSIG_MOVABLE_PRE_MOVE "movable_pre_move" //from base of atom/movable/Moved(): (/atom)
#define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (/atom, dir)
#define COMSIG_MOVABLE_CROSS "movable_cross" //from base of atom/movable/Cross(): (/atom/movable)
#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (/atom/movable)
diff --git a/code/__DEFINES/configuration.dm b/code/__DEFINES/configuration.dm
index 3034876e36..6b70eb1e0f 100644
--- a/code/__DEFINES/configuration.dm
+++ b/code/__DEFINES/configuration.dm
@@ -1,6 +1,7 @@
//config files
#define CONFIG_GET(X) global.config.Get(/datum/config_entry/##X)
#define CONFIG_SET(X, Y) global.config.Set(/datum/config_entry/##X, ##Y)
+#define CONFIG_GET_ENTRY(X) global.config.GetEntryDatum(/datum/config_entry/##X)
#define CONFIG_MAPS_FILE "maps.txt"
diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm
index 36ea64de2c..54f4648006 100644
--- a/code/__DEFINES/reagents.dm
+++ b/code/__DEFINES/reagents.dm
@@ -8,7 +8,7 @@
#define REAGENT_PURITY_ACCURACY 0.001
#define DEFAULT_SPECIFIC_HEAT 200
-// container_type defines
+//reagents_holder_flags defines
#define INJECTABLE (1<<0) // Makes it possible to add reagents through droppers and syringes.
#define DRAWABLE (1<<1) // Makes it possible to remove reagents through syringes.
@@ -29,6 +29,11 @@
#define PATCH 4 // patches
#define INJECT 5 // injection
+//container_flags
+#define PH_WEAK (1 << 0)
+#define TEMP_WEAK (1 << 1)
+#define APTFT_VERB (1 << 2) //APTFT stands for "amount per transfer from this"
+#define APTFT_ALTCLICK (1 << 3)
//defines passed through to the on_reagent_change proc
#define DEL_REAGENT 1 // reagent deleted (fully cleared)
diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index d5e3f828b8..28a04c2a51 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -37,7 +37,7 @@
#define ROLE_GANG "gangster"
#define ROLE_BLOODSUCKER "bloodsucker"
//#define ROLE_MONSTERHUNTER "monster hunter" Disabled for now
-
+#define ROLE_GHOSTCAFE "ghostcafe"
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
//(in game days played) to play that role
diff --git a/code/__DEFINES/tools.dm b/code/__DEFINES/tools.dm
index 3fd6b069d4..7e391caaed 100644
--- a/code/__DEFINES/tools.dm
+++ b/code/__DEFINES/tools.dm
@@ -14,7 +14,9 @@
#define TOOL_DRILL "drill"
#define TOOL_SCALPEL "scalpel"
#define TOOL_SAW "saw"
-
+//Glasswork Tools
+#define TOOL_BLOW "blowing_rod"
+#define TOOL_GLASS_CUT "glasskit"
// If delay between the start and the end of tool operation is less than MIN_TOOL_SOUND_DELAY,
// tool sound is only played when op is started. If not, it's played twice.
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 033636017d..d707f7e58a 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -234,6 +234,7 @@
#define ABDUCTOR_ANTAGONIST "abductor-antagonist"
#define NUKEOP_ANTAGONIST "nukeop-antagonist"
#define MADE_UNCLONEABLE "made-uncloneable"
+#define TIMESTOP_TRAIT "timestop"
#define NUKEOP_TRAIT "nuke-op"
#define MEGAFAUNA_TRAIT "megafauna"
#define DEATHSQUAD_TRAIT "deathsquad"
diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm
index 0aa9476fad..6ea1de0e2c 100644
--- a/code/__HELPERS/_logging.dm
+++ b/code/__HELPERS/_logging.dm
@@ -165,6 +165,12 @@
/proc/log_mapping(text)
WRITE_LOG(GLOB.world_map_error_log, text)
+/proc/log_reagent(text)
+ WRITE_LOG(GLOB.reagent_log, text)
+
+/proc/log_reagent_transfer(text)
+ log_reagent("TRANSFER: [text]")
+
/* For logging round startup. */
/proc/start_log(log)
WRITE_LOG(log, "Starting up round ID [GLOB.round_id].\n-------------------------")
diff --git a/code/__HELPERS/areas.dm b/code/__HELPERS/areas.dm
index 4b52187e13..d7378abfa6 100644
--- a/code/__HELPERS/areas.dm
+++ b/code/__HELPERS/areas.dm
@@ -1,5 +1,81 @@
#define BP_MAX_ROOM_SIZE 300
+//Repopulates sortedAreas list
+/proc/repopulate_sorted_areas()
+ GLOB.sortedAreas = list()
+
+ for(var/area/A in world)
+ GLOB.sortedAreas.Add(A)
+
+ sortTim(GLOB.sortedAreas, /proc/cmp_name_asc)
+
+/area/proc/addSorted()
+ GLOB.sortedAreas.Add(src)
+ sortTim(GLOB.sortedAreas, /proc/cmp_name_asc)
+
+//Takes: Area type as a text string from a variable.
+//Returns: Instance for the area in the world.
+/proc/get_area_instance_from_text(areatext)
+ if(istext(areatext))
+ areatext = text2path(areatext)
+ return GLOB.areas_by_type[areatext]
+
+//Takes: Area type as text string or as typepath OR an instance of the area.
+//Returns: A list of all areas of that type in the world.
+/proc/get_areas(areatype, subtypes=TRUE)
+ if(istext(areatype))
+ areatype = text2path(areatype)
+ else if(isarea(areatype))
+ var/area/areatemp = areatype
+ areatype = areatemp.type
+ else if(!ispath(areatype))
+ return null
+
+ var/list/areas = list()
+ if(subtypes)
+ var/list/cache = typecacheof(areatype)
+ for(var/V in GLOB.sortedAreas)
+ var/area/A = V
+ if(cache[A.type])
+ areas += V
+ else
+ for(var/V in GLOB.sortedAreas)
+ var/area/A = V
+ if(A.type == areatype)
+ areas += V
+ return areas
+
+//Takes: Area type as text string or as typepath OR an instance of the area.
+//Returns: A list of all turfs in areas of that type of that type in the world.
+/proc/get_area_turfs(areatype, target_z = 0, subtypes=FALSE)
+ if(istext(areatype))
+ areatype = text2path(areatype)
+ else if(isarea(areatype))
+ var/area/areatemp = areatype
+ areatype = areatemp.type
+ else if(!ispath(areatype))
+ return null
+
+ var/list/turfs = list()
+ if(subtypes)
+ var/list/cache = typecacheof(areatype)
+ for(var/V in GLOB.sortedAreas)
+ var/area/A = V
+ if(!cache[A.type])
+ continue
+ for(var/turf/T in A)
+ if(target_z == 0 || target_z == T.z)
+ turfs += T
+ else
+ for(var/V in GLOB.sortedAreas)
+ var/area/A = V
+ if(A.type != areatype)
+ continue
+ for(var/turf/T in A)
+ if(target_z == 0 || target_z == T.z)
+ turfs += T
+ return turfs
+
// Gets an atmos isolated contained space
// Returns an associative list of turf|dirs pairs
// The dirs are connected turfs in the same space
@@ -103,4 +179,62 @@
to_chat(creator, "You have created a new area, named [newA.name]. It is now weather proof, and constructing an APC will allow it to be powered.")
return TRUE
+
+/**
+ * Returns the base area the target is located in if there is one.
+ * Alternatively, returns the area as is.
+ */
+/proc/get_base_area(atom/target)
+ var/area/A = get_area(target)
+ if(A?.base_area)
+ return A.base_area
+ return A
+
+/**
+ * Returns either null, or a list containing every sub area associated with our base area.
+ * If include_base is TRUE, the base area will also be added to the return list.
+ */
+/proc/get_sub_areas(atom/target, include_base = TRUE)
+ var/area/A = get_area(target)
+ if(!A)
+ return
+ . = list()
+ if(A.base_area)
+ A = A.base_area
+ if(include_base)
+ . += A
+ if(A.sub_areas)
+ . += A.sub_areas
+
+/**
+ * Proc used for purposes similar to get_areas_turfs(), but aimed to include associated areas.
+ * Only accepts area instances and paths for the first arg, no text strings.
+ * Returns a list of all turfs found in the sub areas (including the base's if include_base is TRUE)
+ * and located in a z level matching target_z, or anywhere if target_z is 0
+ */
+
+/proc/get_sub_areas_turfs(area/A, target_z = 0, include_base = TRUE)
+ var/list/contents = get_sub_areas_contents(A, include_base)
+ . = list()
+ for(var/turf/T in contents)
+ if(target_z == 0 || target_z == T.z)
+ . += T
+/**
+ * Simple proc that returns a sum of all contents from every sub area,
+ * Think of the above but for all contents, not just turfs, and without target z.
+ */
+
+/proc/get_sub_areas_contents(area/A, include_base = TRUE)
+ if(ispath(A))
+ A = GLOB.areas_by_type[A]
+ else
+ A = get_area(A) //in case it's called on other atoms.
+ if(!A)
+ return
+ if(A.base_area)
+ A = A.base_area
+ . = list(A.contents)
+ for(var/i in A.sub_areas)
+ . += A.sub_areas[i].contents
+
#undef BP_MAX_ROOM_SIZE
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index ca4b913369..605f7f8ae7 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -8,8 +8,8 @@
#define Z_TURFS(ZLEVEL) block(locate(1,1,ZLEVEL), locate(world.maxx, world.maxy, ZLEVEL))
#define CULT_POLL_WAIT 2400
-/proc/get_area_name(atom/X, format_text = FALSE)
- var/area/A = isarea(X) ? X : get_area(X)
+/proc/get_area_name(atom/X, format_text = FALSE, get_base_area = FALSE)
+ var/area/A = get_base_area ? get_base_area(X) : get_area(X)
if(!A)
return null
return format_text ? format_text(A.name) : A.name
@@ -145,20 +145,6 @@
turfs += T
return turfs
-
-//This is the new version of recursive_mob_check, used for say().
-//The other proc was left intact because morgue trays use it.
-//Sped this up again for real this time
-/proc/recursive_hear_check(O)
- var/list/processing_list = list(O)
- . = list()
- while(processing_list.len)
- var/atom/A = processing_list[1]
- if(A.flags_1 & HEAR_1)
- . += A
- processing_list.Cut(1, 2)
- processing_list += A.contents
-
/** recursive_organ_check
* inputs: O (object to start with)
* outputs:
@@ -238,35 +224,30 @@
return found_mobs
-
/proc/get_hearers_in_view(R, atom/source)
- // Returns a list of hearers in view(R) from source (ignoring luminosity). Used in saycode.
var/turf/T = get_turf(source)
. = list()
-
if(!T)
return
-
- var/list/processing_list = list()
- if (R == 0) // if the range is zero, we know exactly where to look for, we can skip view
- processing_list += T.contents // We can shave off one iteration by assuming turfs cannot hear
- else // A variation of get_hear inlined here to take advantage of the compiler's fastpath for obj/mob in view
+ var/list/processing = list()
+ if(R == 0)
+ processing += T.contents
+ else
var/lum = T.luminosity
- T.luminosity = 6 // This is the maximum luminosity
- var/list/cachedview = view(R, T)
- for(var/mob/M in cachedview)
- processing_list += M
- for(var/obj/O in cachedview)
- processing_list += O
+ T.luminosity = 6
+ var/list/cached_view = view(R, T)
+ for(var/mob/M in cached_view)
+ processing += M
+ for(var/obj/O in cached_view)
+ processing += O
T.luminosity = lum
-
- while(processing_list.len) // recursive_hear_check inlined here
- var/atom/A = processing_list[1]
+ var/i = 0
+ while(i < length(processing))
+ var/atom/A = processing[++i]
if(A.flags_1 & HEAR_1)
. += A
- SEND_SIGNAL(A, COMSIG_ATOM_HEARER_IN_VIEW, processing_list, .)
- processing_list.Cut(1, 2)
- processing_list += A.contents
+ SEND_SIGNAL(A, COMSIG_ATOM_HEARER_IN_VIEW, processing, .)
+ processing += A.contents
/proc/get_mobs_in_radio_ranges(list/obj/item/radio/radios)
. = list()
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index e916b2532a..2f960e350b 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -457,36 +457,35 @@ Turf and target are separate in case you want to teleport some distance from a t
/atom/proc/GetAllContents(var/T)
var/list/processing_list = list(src)
- var/list/assembled = list()
if(T)
- while(processing_list.len)
- var/atom/A = processing_list[1]
- processing_list.Cut(1, 2)
+ . = list()
+ var/i = 0
+ while(i < length(processing_list))
+ var/atom/A = processing_list[++i]
//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
if(istype(A,T))
- assembled += A
+ . += A
else
- while(processing_list.len)
- var/atom/A = processing_list[1]
- processing_list.Cut(1, 2)
+ var/i = 0
+ while(i < length(processing_list))
+ var/atom/A = processing_list[++i]
processing_list += A.contents
- assembled += A
- return assembled
+ return processing_list
/atom/proc/GetAllContentsIgnoring(list/ignore_typecache)
if(!length(ignore_typecache))
return GetAllContents()
var/list/processing = list(src)
- var/list/assembled = list()
- while(processing.len)
- var/atom/A = processing[1]
- processing.Cut(1,2)
+ . = list()
+ var/i = 0
+ while(i < length(processing))
+ var/atom/A = processing[++i]
if(!ignore_typecache[A.type])
processing += A.contents
- assembled += A
- return assembled
+ . += A
+
//Step-towards method of determining whether one atom can see another. Similar to viewers()
/proc/can_see(atom/source, atom/target, length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate.
@@ -566,82 +565,6 @@ Turf and target are separate in case you want to teleport some distance from a t
else
return 0
-//Repopulates sortedAreas list
-/proc/repopulate_sorted_areas()
- GLOB.sortedAreas = list()
-
- for(var/area/A in world)
- GLOB.sortedAreas.Add(A)
-
- sortTim(GLOB.sortedAreas, /proc/cmp_name_asc)
-
-/area/proc/addSorted()
- GLOB.sortedAreas.Add(src)
- sortTim(GLOB.sortedAreas, /proc/cmp_name_asc)
-
-//Takes: Area type as a text string from a variable.
-//Returns: Instance for the area in the world.
-/proc/get_area_instance_from_text(areatext)
- if(istext(areatext))
- areatext = text2path(areatext)
- return GLOB.areas_by_type[areatext]
-
-//Takes: Area type as text string or as typepath OR an instance of the area.
-//Returns: A list of all areas of that type in the world.
-/proc/get_areas(areatype, subtypes=TRUE)
- if(istext(areatype))
- areatype = text2path(areatype)
- else if(isarea(areatype))
- var/area/areatemp = areatype
- areatype = areatemp.type
- else if(!ispath(areatype))
- return null
-
- var/list/areas = list()
- if(subtypes)
- var/list/cache = typecacheof(areatype)
- for(var/V in GLOB.sortedAreas)
- var/area/A = V
- if(cache[A.type])
- areas += V
- else
- for(var/V in GLOB.sortedAreas)
- var/area/A = V
- if(A.type == areatype)
- areas += V
- return areas
-
-//Takes: Area type as text string or as typepath OR an instance of the area.
-//Returns: A list of all turfs in areas of that type of that type in the world.
-/proc/get_area_turfs(areatype, target_z = 0, subtypes=FALSE)
- if(istext(areatype))
- areatype = text2path(areatype)
- else if(isarea(areatype))
- var/area/areatemp = areatype
- areatype = areatemp.type
- else if(!ispath(areatype))
- return null
-
- var/list/turfs = list()
- if(subtypes)
- var/list/cache = typecacheof(areatype)
- for(var/V in GLOB.sortedAreas)
- var/area/A = V
- if(!cache[A.type])
- continue
- for(var/turf/T in A)
- if(target_z == 0 || target_z == T.z)
- turfs += T
- else
- for(var/V in GLOB.sortedAreas)
- var/area/A = V
- if(A.type != areatype)
- continue
- for(var/turf/T in A)
- if(target_z == 0 || target_z == T.z)
- turfs += T
- return turfs
-
/proc/get_cardinal_dir(atom/A, atom/B)
var/dx = abs(B.x - A.x)
var/dy = abs(B.y - A.y)
diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm
index a13a958ef7..2d5d2388ec 100644
--- a/code/_globalvars/logging.dm
+++ b/code/_globalvars/logging.dm
@@ -32,6 +32,8 @@ GLOBAL_VAR(world_map_error_log)
GLOBAL_PROTECT(world_map_error_log)
GLOBAL_VAR(subsystem_log)
GLOBAL_PROTECT(subsystem_log)
+GLOBAL_VAR(reagent_log)
+GLOBAL_PROTECT(reagent_log)
GLOBAL_VAR(world_crafting_log)
GLOBAL_PROTECT(world_crafting_log)
diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm
index 8592383a4f..25a49c8d6b 100755
--- a/code/_onclick/hud/parallax.dm
+++ b/code/_onclick/hud/parallax.dm
@@ -146,6 +146,8 @@
/datum/hud/proc/update_parallax_motionblur(client/C, animatedir, new_parallax_movedir, matrix/newtransform)
+ if(!C)
+ return
C.parallax_animate_timer = FALSE
for(var/thing in C.parallax_layers)
var/obj/screen/parallax_layer/L = thing
@@ -167,7 +169,7 @@
/datum/hud/proc/update_parallax()
var/client/C = mymob.client
var/turf/posobj = get_turf(C.eye)
- if(!posobj)
+ if(!posobj)
return
var/area/areaobj = posobj.loc
diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm
index 4ce0ccf361..ad1f869057 100644
--- a/code/controllers/configuration/configuration.dm
+++ b/code/controllers/configuration/configuration.dm
@@ -193,6 +193,13 @@
stat("[name]:", statclick)
/datum/controller/configuration/proc/Get(entry_type)
+ var/datum/config_entry/E = GetEntryDatum(entry_type)
+ if((E.protection & CONFIG_ENTRY_HIDDEN) && IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "[REF(src)]")
+ log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]")
+ return
+ return E.config_entry_value
+
+/datum/controller/configuration/proc/GetEntryDatum(entry_type)
var/datum/config_entry/E = entry_type
var/entry_is_abstract = initial(E.abstract_type) == entry_type
if(entry_is_abstract)
@@ -200,10 +207,7 @@
E = entries_by_type[entry_type]
if(!E)
CRASH("Missing config entry for [entry_type]!")
- if((E.protection & CONFIG_ENTRY_HIDDEN) && IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "[REF(src)]")
- log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]")
- return
- return E.config_entry_value
+ return E
/datum/controller/configuration/proc/Set(entry_type, new_val)
var/datum/config_entry/E = entry_type
diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm
index 6efc9eab12..a3bc47ac91 100644
--- a/code/controllers/configuration/entries/game_options.dm
+++ b/code/controllers/configuration/entries/game_options.dm
@@ -249,6 +249,18 @@
/datum/config_entry/number/movedelay/walk_delay
+/datum/config_entry/number/movedelay/sprint_speed_increase
+ config_entry_value = 1
+
+/datum/config_entry/number/movedelay/sprint_buffer_max
+ config_entry_value = 42
+
+/datum/config_entry/number/movedelay/sprint_stamina_cost
+ config_entry_value = 0.7
+
+/datum/config_entry/number/movedelay/sprint_buffer_regen_per_ds
+ config_entry_value = 0.3
+
/////////////////////////////////////////////////Outdated move delay
/datum/config_entry/number/outdated_movedelay
deprecated_by = /datum/config_entry/keyed_list/multiplicative_movespeed
diff --git a/code/controllers/subsystem/fail2topic.dm b/code/controllers/subsystem/fail2topic.dm
index a589ae2462..d17cce70f9 100644
--- a/code/controllers/subsystem/fail2topic.dm
+++ b/code/controllers/subsystem/fail2topic.dm
@@ -31,8 +31,8 @@ SUBSYSTEM_DEF(fail2topic)
return ..()
/datum/controller/subsystem/fail2topic/fire()
- while (rate_limiting.len)
- var/ip = rate_limiting[1]
+ for(var/i in 1 to length(rate_limiting))
+ var/ip = rate_limiting[i]
var/last_attempt = rate_limiting[ip]
if (world.time - last_attempt > rate_limit)
diff --git a/code/datums/brain_damage/brain_trauma.dm b/code/datums/brain_damage/brain_trauma.dm
index 1aa1341c9c..eaaab8da45 100644
--- a/code/datums/brain_damage/brain_trauma.dm
+++ b/code/datums/brain_damage/brain_trauma.dm
@@ -14,7 +14,7 @@
var/can_gain = TRUE
var/random_gain = TRUE //can this be gained through random traumas?
var/resilience = TRAUMA_RESILIENCE_BASIC //how hard is this to cure?
- var/clonable = TRUE // will this transfer if the brain is cloned?
+ var/clonable = TRUE // will this transfer if the brain is cloned? - currently has no effect
/datum/brain_trauma/Destroy()
if(brain && brain.traumas)
diff --git a/code/datums/components/dejavu.dm b/code/datums/components/dejavu.dm
new file mode 100644
index 0000000000..1bad589c97
--- /dev/null
+++ b/code/datums/components/dejavu.dm
@@ -0,0 +1,107 @@
+/**
+ * A component to reset the parent to its previous state after some time passes
+ */
+/datum/component/dejavu
+ /// The turf the parent was on when this components was applied, they get moved back here after the duration
+ var/turf/starting_turf
+ /// Determined by the type of the parent so different behaviours can happen per type
+ var/rewind_type
+ /// How many rewinds will happen before the effect ends
+ var/rewinds_remaining
+ /// How long to wait between each rewind
+ var/rewind_interval
+
+ /// The starting value of clone loss at the beginning of the effect
+ var/clone_loss = 0
+ /// The starting value of toxin loss at the beginning of the effect
+ var/tox_loss = 0
+ /// The starting value of oxygen loss at the beginning of the effect
+ var/oxy_loss = 0
+ /// The starting value of brain loss at the beginning of the effect
+ var/brain_loss = 0
+ /// The starting value of brute loss at the beginning of the effect
+ /// This only applies to simple animals
+ var/brute_loss
+ /// The starting value of integrity at the beginning of the effect
+ /// This only applies to objects
+ var/integrity
+ /// A list of body parts saved at the beginning of the effect
+ var/list/datum/saved_bodypart/saved_bodyparts
+
+/datum/component/dejavu/Initialize(rewinds = 1, interval = 10 SECONDS)
+ if(!isatom(parent))
+ return COMPONENT_INCOMPATIBLE
+
+ starting_turf = get_turf(parent)
+ rewinds_remaining = rewinds
+ rewind_interval = interval
+
+ if(isliving(parent))
+ var/mob/living/L = parent
+ clone_loss = L.getCloneLoss()
+ tox_loss = L.getToxLoss()
+ oxy_loss = L.getOxyLoss()
+ brain_loss = L.getOrganLoss(ORGAN_SLOT_BRAIN)
+ rewind_type = .proc/rewind_living
+
+ if(iscarbon(parent))
+ var/mob/living/carbon/C = parent
+ saved_bodyparts = C.save_bodyparts()
+ rewind_type = .proc/rewind_carbon
+
+ else if(isanimal(parent))
+ var/mob/living/simple_animal/M = parent
+ brute_loss = M.bruteloss
+ rewind_type = .proc/rewind_animal
+
+ else if(isobj(parent))
+ var/obj/O = parent
+ integrity = O.obj_integrity
+ rewind_type = .proc/rewind_obj
+
+ addtimer(CALLBACK(src, rewind_type), rewind_interval)
+
+/datum/component/dejavu/Destroy()
+ starting_turf = null
+ saved_bodyparts = null
+ return ..()
+
+/datum/component/dejavu/proc/rewind()
+ to_chat(parent, "You remember a time not so long ago...")
+
+ //comes after healing so new limbs comically drop to the floor
+ if(starting_turf)
+ var/atom/movable/master = parent
+ master.forceMove(starting_turf)
+
+ rewinds_remaining --
+ if(rewinds_remaining)
+ addtimer(CALLBACK(src, rewind_type), rewind_interval)
+ else
+ to_chat(parent, "But the memory falls out of your reach.")
+ qdel(src)
+
+/datum/component/dejavu/proc/rewind_living()
+ var/mob/living/master = parent
+ master.setCloneLoss(clone_loss)
+ master.setToxLoss(tox_loss)
+ master.setOxyLoss(oxy_loss)
+ master.setOrganLoss(ORGAN_SLOT_BRAIN, brain_loss)
+ rewind()
+
+/datum/component/dejavu/proc/rewind_carbon()
+ if(saved_bodyparts)
+ var/mob/living/carbon/master = parent
+ master.apply_saved_bodyparts(saved_bodyparts)
+ rewind_living()
+
+/datum/component/dejavu/proc/rewind_animal()
+ var/mob/living/simple_animal/master = parent
+ master.bruteloss = brute_loss
+ master.updatehealth()
+ rewind_living()
+
+/datum/component/dejavu/proc/rewind_obj()
+ var/obj/master = parent
+ master.obj_integrity = integrity
+ rewind()
diff --git a/code/datums/components/virtual_reality.dm b/code/datums/components/virtual_reality.dm
index 2f0405af2e..63e4f4f092 100644
--- a/code/datums/components/virtual_reality.dm
+++ b/code/datums/components/virtual_reality.dm
@@ -229,7 +229,7 @@
UnregisterSignal(mastermind, COMSIG_PRE_MIND_TRANSFER)
mastermind = null
if(cleanup)
- var/obj/effect/vr_clean_master/cleanbot = locate() in get_area(M)
+ var/obj/effect/vr_clean_master/cleanbot = locate() in get_base_area(M)
if(cleanbot)
LAZYOR(cleanbot.corpse_party, M)
qdel(src)
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index ebfba43852..1622cc9dbf 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -236,7 +236,12 @@
G.fields["fingerprint"] = md5(H.dna.uni_identity)
G.fields["p_stat"] = "Active"
G.fields["m_stat"] = "Stable"
- G.fields["sex"] = H.gender
+ if(H.gender == MALE)
+ G.fields["gender"] = "Male"
+ else if(H.gender == FEMALE)
+ G.fields["gender"] = "Female"
+ else
+ G.fields["gender"] = "Other"
G.fields["photo_front"] = photo_front
G.fields["photo_side"] = photo_side
general += G
@@ -274,7 +279,12 @@
L.fields["name"] = H.real_name
L.fields["rank"] = H.mind.assigned_role
L.fields["age"] = H.age
- L.fields["sex"] = H.gender
+ if(H.gender == MALE)
+ G.fields["gender"] = "Male"
+ else if(H.gender == FEMALE)
+ G.fields["gender"] = "Female"
+ else
+ G.fields["gender"] = "Other"
L.fields["blood_type"] = H.dna.blood_type
L.fields["b_dna"] = H.dna.unique_enzymes
L.fields["enzymes"] = H.dna.struc_enzymes
diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm
index 6b72f2fdfc..1c21fb9528 100644
--- a/code/datums/diseases/advance/advance.dm
+++ b/code/datums/diseases/advance/advance.dm
@@ -110,7 +110,7 @@
// Randomly pick a symptom to activate.
/datum/disease/advance/stage_act()
..()
- if(carrier)
+ if(carrier || QDELETED(src)) // Could be cured in parent call.
return
if(symptoms && symptoms.len)
diff --git a/code/datums/diseases/advance/symptoms/choking.dm b/code/datums/diseases/advance/symptoms/choking.dm
index 559d8f4754..6946a6a1d8 100644
--- a/code/datums/diseases/advance/symptoms/choking.dm
+++ b/code/datums/diseases/advance/symptoms/choking.dm
@@ -41,7 +41,7 @@ Bonus
suppress_warning = TRUE
/datum/symptom/choking/Activate(datum/disease/advance/A)
- if(!..())
+ if(!..() || HAS_TRAIT(A.affected_mob,TRAIT_NOBREATH))
return
var/mob/living/M = A.affected_mob
switch(A.stage)
@@ -112,7 +112,7 @@ Bonus
power = 2
/datum/symptom/asphyxiation/Activate(datum/disease/advance/A)
- if(!..())
+ if(!..() || HAS_TRAIT(A.affected_mob,TRAIT_NOBREATH))
return
var/mob/living/M = A.affected_mob
switch(A.stage)
diff --git a/code/datums/diseases/advance/symptoms/cough.dm b/code/datums/diseases/advance/symptoms/cough.dm
index b1767d7cb5..62c64159d1 100644
--- a/code/datums/diseases/advance/symptoms/cough.dm
+++ b/code/datums/diseases/advance/symptoms/cough.dm
@@ -50,7 +50,7 @@ BONUS
symptom_delay_max = 10
/datum/symptom/cough/Activate(datum/disease/advance/A)
- if(!..())
+ if(!..() || HAS_TRAIT(A.affected_mob,TRAIT_NOBREATH))
return
var/mob/living/M = A.affected_mob
switch(A.stage)
diff --git a/code/datums/diseases/advance/symptoms/sneeze.dm b/code/datums/diseases/advance/symptoms/sneeze.dm
index 5d4d40fb95..9f1696c963 100644
--- a/code/datums/diseases/advance/symptoms/sneeze.dm
+++ b/code/datums/diseases/advance/symptoms/sneeze.dm
@@ -39,7 +39,7 @@ Bonus
suppress_warning = TRUE
/datum/symptom/sneeze/Activate(datum/disease/advance/A)
- if(!..())
+ if(!..() || HAS_TRAIT(A.affected_mob,TRAIT_NOBREATH))
return
var/mob/living/M = A.affected_mob
switch(A.stage)
diff --git a/code/datums/diseases/wizarditis.dm b/code/datums/diseases/wizarditis.dm
index 230a074bb1..71a5bcb99e 100644
--- a/code/datums/diseases/wizarditis.dm
+++ b/code/datums/diseases/wizarditis.dm
@@ -94,7 +94,7 @@ STI KALY - blind
var/area/thearea = pick(theareas)
var/list/L = list()
- for(var/turf/T in get_area_turfs(thearea.type))
+ for(var/turf/T in thearea)
if(T.z != affected_mob.z)
continue
if(T.name == "space")
diff --git a/code/datums/dna.dm b/code/datums/dna.dm
index 67dbbdfef7..5fa991c10c 100644
--- a/code/datums/dna.dm
+++ b/code/datums/dna.dm
@@ -92,7 +92,15 @@
. = ""
var/list/L = new /list(DNA_UNI_IDENTITY_BLOCKS)
- L[DNA_GENDER_BLOCK] = construct_block((holder.gender!=MALE)+1, 2)
+ switch(holder.gender)
+ if(MALE)
+ L[DNA_GENDER_BLOCK] = construct_block(G_MALE, 4)
+ if(FEMALE)
+ L[DNA_GENDER_BLOCK] = construct_block(G_FEMALE, 4)
+ if(PLURAL)
+ L[DNA_GENDER_BLOCK] = construct_block(G_PLURAL, 4)
+ else
+ L[DNA_GENDER_BLOCK] = construct_block(G_NEUTER, 4)
if(ishuman(holder))
var/mob/living/carbon/human/H = holder
if(!GLOB.hair_styles_list.len)
@@ -165,7 +173,15 @@
if(DNA_EYE_COLOR_BLOCK)
setblock(uni_identity, blocknumber, sanitize_hexcolor(H.eye_color))
if(DNA_GENDER_BLOCK)
- setblock(uni_identity, blocknumber, construct_block((H.gender!=MALE)+1, 2))
+ switch(H.gender)
+ if(MALE)
+ setblock(uni_identity, blocknumber, construct_block(G_MALE, 4))
+ if(FEMALE)
+ setblock(uni_identity, blocknumber, construct_block(G_FEMALE, 4))
+ if(PLURAL)
+ setblock(uni_identity, blocknumber, construct_block(G_PLURAL, 4))
+ else
+ setblock(uni_identity, blocknumber, construct_block(G_NEUTER, 4))
if(DNA_FACIAL_HAIR_STYLE_BLOCK)
setblock(uni_identity, blocknumber, construct_block(GLOB.facial_hair_styles_list.Find(H.facial_hair_style), GLOB.facial_hair_styles_list.len))
if(DNA_HAIR_STYLE_BLOCK)
@@ -307,7 +323,16 @@
/mob/living/carbon/proc/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0)
if(!has_dna())
return
- gender = (deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? FEMALE : MALE
+
+ switch(deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 4))
+ if(G_MALE)
+ gender = MALE
+ if(G_FEMALE)
+ gender = FEMALE
+ if(G_PLURAL)
+ gender = PLURAL
+ else
+ gender = NEUTER
/mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0)
..()
diff --git a/code/datums/elements/dusts_on_leaving_area.dm b/code/datums/elements/dusts_on_leaving_area.dm
new file mode 100644
index 0000000000..9527e1fd3a
--- /dev/null
+++ b/code/datums/elements/dusts_on_leaving_area.dm
@@ -0,0 +1,28 @@
+/datum/element/dusts_on_leaving_area
+ element_flags = ELEMENT_DETACH | ELEMENT_BESPOKE
+ id_arg_index = 2
+ var/list/attached_mobs = list()
+ var/list/area_types = list()
+
+/datum/element/dusts_on_leaving_area/Attach(datum/target,types)
+ . = ..()
+ if(!ismob(target))
+ return ELEMENT_INCOMPATIBLE
+ attached_mobs += target
+ area_types = types
+ START_PROCESSING(SSprocessing,src)
+
+/datum/element/dusts_on_leaving_area/Detach(mob/M)
+ . = ..()
+ if(M in attached_mobs)
+ attached_mobs -= M
+ if(!attached_mobs.len)
+ STOP_PROCESSING(SSprocessing,src)
+
+/datum/element/dusts_on_leaving_area/process()
+ for(var/m in attached_mobs)
+ var/mob/M = m
+ var/area/A = get_area(M)
+ if(!(A.type in area_types))
+ M.dust(force = TRUE)
+ Detach(M)
diff --git a/code/datums/traits/_quirk.dm b/code/datums/traits/_quirk.dm
index 12e34b0c90..d68b11135f 100644
--- a/code/datums/traits/_quirk.dm
+++ b/code/datums/traits/_quirk.dm
@@ -15,6 +15,7 @@
/datum/quirk/New(mob/living/quirk_mob, spawn_effects)
if(!quirk_mob || (human_only && !ishuman(quirk_mob)) || quirk_mob.has_quirk(type))
qdel(src)
+ return
quirk_holder = quirk_mob
SSquirks.quirk_objects += src
to_chat(quirk_holder, gain_text)
diff --git a/code/datums/traits/good.dm b/code/datums/traits/good.dm
index b74f24c469..0d4a6a7b3f 100644
--- a/code/datums/traits/good.dm
+++ b/code/datums/traits/good.dm
@@ -201,13 +201,12 @@
medical_record_text = "Patient's blood tests report an abnormal concentration of red blood cells in their bloodstream."
/datum/quirk/bloodpressure/add()
- var/mob/living/M = quirk_holder
- M.blood_ratio = 1.2
- M.blood_volume += 150
+ quirk_holder.blood_ratio = 1.2
+ quirk_holder.blood_volume += 150
/datum/quirk/bloodpressure/remove()
- var/mob/living/M = quirk_holder
- M.blood_ratio = 1
+ if(quirk_holder)
+ quirk_holder.blood_ratio = 1
/datum/quirk/night_vision
name = "Night Vision"
diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm
index c5217d8e4b..b19c6a71f7 100644
--- a/code/datums/traits/negative.dm
+++ b/code/datums/traits/negative.dm
@@ -400,3 +400,12 @@
/datum/quirk/blindness/remove()
quirk_holder?.cure_blind(ROUNDSTART_TRAIT)
+
+/datum/quirk/coldblooded
+ name = "Cold-blooded"
+ desc = "Your body doesn't create its own internal heat, requiring external heat regulation."
+ value = -2
+ medical_record_text = "Patient is ectothermic."
+ mob_trait = TRAIT_COLDBLOODED
+ gain_text = "You feel cold-blooded."
+ lose_text = "You feel more warm-blooded."
diff --git a/code/datums/traits/neutral.dm b/code/datums/traits/neutral.dm
index d19efe486d..ab2a69e7e9 100644
--- a/code/datums/traits/neutral.dm
+++ b/code/datums/traits/neutral.dm
@@ -104,15 +104,6 @@
gain_text = "You desire to be hurt."
lose_text = "Pain has become less exciting for you."
-/datum/quirk/coldblooded
- name = "Cold-blooded"
- desc = "Your body doesn't create its own internal heat, requiring external heat regulation."
- value = 0
- medical_record_text = "Patient is ectothermic."
- mob_trait = TRAIT_COLDBLOODED
- gain_text = "You feel cold-blooded."
- lose_text = "You feel more warm-blooded."
-
/datum/quirk/alcohol_intolerance
name = "Alcohol Intolerance"
desc = "You take toxin damage from alcohol rather than getting drunk."
diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm
index a3b666dcc6..01b9facbb8 100644
--- a/code/datums/weather/weather.dm
+++ b/code/datums/weather/weather.dm
@@ -50,7 +50,10 @@
stage = STARTUP_STAGE
var/list/affectareas = list()
for(var/V in get_areas(area_type))
- affectareas += V
+ var/area/A = V
+ affectareas |= A
+ if(A.sub_areas)
+ affectareas |= A.sub_areas
for(var/V in protected_areas)
affectareas -= get_areas(V)
for(var/V in affectareas)
diff --git a/code/datums/wires/airalarm.dm b/code/datums/wires/airalarm.dm
index 6eb4dc04db..0c4715e27e 100644
--- a/code/datums/wires/airalarm.dm
+++ b/code/datums/wires/airalarm.dm
@@ -46,7 +46,7 @@
A.mode = 1 // AALARM_MODE_SCRUB
A.apply_mode()
if(WIRE_ALARM) // Clear alarms.
- var/area/AA = get_area(A)
+ var/area/AA = get_base_area(A)
if(AA.atmosalert(0, holder))
A.post_alert(0)
A.update_icon()
@@ -68,7 +68,7 @@
A.mode = 3 // AALARM_MODE_PANIC
A.apply_mode()
if(WIRE_ALARM) // Post alarm.
- var/area/AA = get_area(A)
+ var/area/AA = get_base_area(A)
if(AA.atmosalert(2, holder))
A.post_alert(2)
A.update_icon()
\ No newline at end of file
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index 2d256aad27..99b8165306 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -63,6 +63,15 @@
var/xenobiology_compatible = FALSE //Can the Xenobio management console transverse this area by default?
var/list/canSmoothWithAreas //typecache to limit the areas that atoms in this area can smooth with
+/**
+ * These two vars allow for multiple unique areas to be linked to a master area
+ * and share some functionalities such as APC powernet nodes, fire alarms etc, without sacrificing
+ * their own flags, statuses, variables and more snowflakes.
+ * Friendly reminder: no map edited areas.
+ */
+ var/list/area/sub_areas //list of typepaths of the areas you wish to link here, will be replaced with a list of references on mapload.
+ var/area/base_area //The area we wish to use in place of src for certain actions such as APC area linking.
+
var/nightshift_public_area = NIGHTSHIFT_AREA_NONE //considered a public area for nightshift
/*Adding a wizard area teleport list because motherfucking lag -- Urist*/
@@ -123,10 +132,35 @@ GLOBAL_LIST_EMPTY(teleportlocs)
reg_in_areas_in_z()
+ //so far I'm only implementing it on mapped unique areas, it's easier this way.
+ if(unique && sub_areas)
+ if(type in sub_areas)
+ WARNING("\"[src]\" typepath found inside its own sub-areas list, please make sure it doesn't share its parent type initial sub-areas value.")
+ sub_areas = null
+ else
+ var/paths = sub_areas.Copy()
+ sub_areas = null
+ for(var/type in paths)
+ var/area/A = GLOB.areas_by_type[type]
+ if(!A) //By chance an area not loaded in the current world, no warning report.
+ continue
+ if(A == src)
+ WARNING("\"[src]\" area a attempted to link with itself.")
+ continue
+ if(A.base_area)
+ WARNING("[src] attempted to link with [A] while the latter is already linked to another area ([A.base_area]).")
+ continue
+ LAZYADD(sub_areas, A)
+ A.base_area = src
+ else if(LAZYLEN(sub_areas))
+ WARNING("sub-areas are currently not supported for non-unique areas such as [src].")
+ sub_areas = null
+
return INITIALIZE_HINT_LATELOAD
/area/LateInitialize()
- power_change() // all machines set to current power level, also updates icon
+ if(!base_area) //we don't want to run it twice.
+ power_change() // all machines set to current power level, also updates icon
/area/proc/reg_in_areas_in_z()
if(contents.len)
@@ -149,6 +183,19 @@ GLOBAL_LIST_EMPTY(teleportlocs)
/area/Destroy()
if(GLOB.areas_by_type[type] == src)
GLOB.areas_by_type[type] = null
+ if(base_area)
+ LAZYREMOVE(base_area, src)
+ base_area = null
+ if(sub_areas)
+ for(var/i in sub_areas)
+ var/area/A = i
+ A.base_area = null
+ sub_areas -= A
+ if(A.requires_power)
+ A.power_light = FALSE
+ A.power_equip = FALSE
+ A.power_environ = FALSE
+ INVOKE_ASYNC(A, .proc/power_change)
STOP_PROCESSING(SSobj, src)
return ..()
@@ -214,9 +261,12 @@ GLOBAL_LIST_EMPTY(teleportlocs)
var/datum/computer_file/program/alarm_monitor/p = item
p.cancelAlarm("Atmosphere", src, source)
- src.atmosalm = danger_level
- return 1
- return 0
+ atmosalm = danger_level
+ for(var/i in sub_areas)
+ var/area/A = i
+ A.atmosalm = danger_level
+ return TRUE
+ return FALSE
/area/proc/ModifyFiredoors(opening)
if(firedoors)
@@ -241,11 +291,8 @@ GLOBAL_LIST_EMPTY(teleportlocs)
return
if (!fire)
- set_fire_alarm_effect()
+ set_fire_alarm_effects(TRUE)
ModifyFiredoors(FALSE)
- for(var/item in firealarms)
- var/obj/machinery/firealarm/F = item
- F.update_icon()
for (var/item in GLOB.alert_consoles)
var/obj/machinery/computer/station_alert/a = item
@@ -264,11 +311,8 @@ GLOBAL_LIST_EMPTY(teleportlocs)
/area/proc/firereset(obj/source)
if (fire)
- unset_fire_alarm_effects()
+ set_fire_alarm_effects(FALSE)
ModifyFiredoors(TRUE)
- for(var/item in firealarms)
- var/obj/machinery/firealarm/F = item
- F.update_icon()
for (var/item in GLOB.silicon_mobs)
var/mob/living/silicon/aiPlayer = item
@@ -300,9 +344,9 @@ GLOBAL_LIST_EMPTY(teleportlocs)
return
//Trigger alarm effect
- set_fire_alarm_effect()
+ set_fire_alarm_effects(TRUE)
//Lockdown airlocks
- for(var/obj/machinery/door/DOOR in src)
+ for(var/obj/machinery/door/DOOR in get_sub_areas_contents(src))
close_and_lock_door(DOOR)
for (var/i in GLOB.silicon_mobs)
@@ -311,23 +355,20 @@ GLOBAL_LIST_EMPTY(teleportlocs)
//Cancel silicon alert after 1 minute
addtimer(CALLBACK(SILICON, /mob/living/silicon.proc/cancelAlarm,"Burglar",src,trigger), 600)
-/area/proc/set_fire_alarm_effect()
- fire = TRUE
+/area/proc/set_fire_alarm_effects(boolean)
+ fire = boolean
+ for(var/i in sub_areas)
+ var/area/A = i
+ A.fire = boolean
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
for(var/alarm in firealarms)
var/obj/machinery/firealarm/F = alarm
F.update_fire_light(fire)
- for(var/obj/machinery/light/L in src)
+ F.update_icon()
+ for(var/obj/machinery/light/L in get_sub_areas_contents(src))
L.update()
-/area/proc/unset_fire_alarm_effects()
- fire = FALSE
- mouse_opacity = MOUSE_OPACITY_TRANSPARENT
- for(var/alarm in firealarms)
- var/obj/machinery/firealarm/F = alarm
- F.update_fire_light(fire)
- for(var/obj/machinery/light/L in src)
- L.update()
+/area/proc/updateicon()
/**
* Update the icon state of the area
*
@@ -380,26 +421,35 @@ GLOBAL_LIST_EMPTY(teleportlocs)
/area/proc/power_change()
for(var/obj/machinery/M in src) // for each machine in the area
M.power_change() // reverify power status (to update icons etc.)
+ if(sub_areas)
+ for(var/i in sub_areas)
+ var/area/A = i
+ A.power_light = power_light
+ A.power_equip = power_equip
+ A.power_environ = power_environ
+ INVOKE_ASYNC(A, .proc/power_change)
update_icon()
/area/proc/usage(chan)
- var/used = 0
switch(chan)
if(LIGHT)
- used += used_light
+ . += used_light
if(EQUIP)
- used += used_equip
+ . += used_equip
if(ENVIRON)
- used += used_environ
+ . += used_environ
if(TOTAL)
- used += used_light + used_equip + used_environ
+ . += used_light + used_equip + used_environ
if(STATIC_EQUIP)
- used += static_equip
+ . += static_equip
if(STATIC_LIGHT)
- used += static_light
+ . += static_light
if(STATIC_ENVIRON)
- used += static_environ
- return used
+ . += static_environ
+ if(sub_areas)
+ for(var/i in sub_areas)
+ var/area/A = i
+ . += A.usage(chan)
/area/proc/addStaticPower(value, powerchannel)
switch(powerchannel)
@@ -414,6 +464,10 @@ GLOBAL_LIST_EMPTY(teleportlocs)
used_equip = 0
used_light = 0
used_environ = 0
+ if(sub_areas)
+ for(var/i in sub_areas)
+ var/area/A = i
+ A.clear_usage()
/area/proc/use_power(amount, chan)
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 829b66a060..42ccc4bbba 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -163,7 +163,7 @@
/atom/movable/proc/Move_Pulled(atom/A)
if(!pulling)
return
- if(pulling.anchored || !pulling.Adjacent(src))
+ if(pulling.anchored || pulling.move_resist > move_force || !pulling.Adjacent(src))
stop_pulling()
return
if(isliving(pulling))
@@ -190,7 +190,7 @@
log_game("DEBUG:[src]'s pull on [pullee] wasn't broken despite [pullee] being in [pullee.loc]. Pull stopped manually.")
stop_pulling()
return
- if(pulling.anchored)
+ if(pulling.anchored || pulling.move_resist > move_force)
stop_pulling()
return
diff --git a/code/game/gamemodes/brother/traitor_bro.dm b/code/game/gamemodes/brother/traitor_bro.dm
index df4a38cf60..718ed2c103 100644
--- a/code/game/gamemodes/brother/traitor_bro.dm
+++ b/code/game/gamemodes/brother/traitor_bro.dm
@@ -5,6 +5,7 @@
/datum/game_mode/traitor/bros
name = "traitor+brothers"
config_tag = "traitorbro"
+ required_players = 25
restricted_jobs = list("AI", "Cyborg")
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm
index d010da465e..b296ba7273 100644
--- a/code/game/gamemodes/events.dm
+++ b/code/game/gamemodes/events.dm
@@ -12,7 +12,7 @@
var/list/skipped_areas = list(/area/engine/engineering, /area/engine/supermatter, /area/engine/atmospherics_engine, /area/ai_monitored/turret_protected/ai)
for(var/area/A in world)
- if( !A.requires_power || A.always_unpowered )
+ if( !A.requires_power || A.always_unpowered || A.base_area)
continue
var/skip = 0
@@ -61,8 +61,9 @@
S.output_attempt = 1
S.update_icon()
S.power_change()
+
for(var/area/A in world)
- if(!istype(A, /area/space) && !istype(A, /area/shuttle) && !istype(A, /area/arrival))
+ if(!istype(A, /area/space) && !istype(A, /area/shuttle) && !istype(A, /area/arrival) && !A.always_unpowered && !A.base_area)
A.power_light = TRUE
A.power_equip = TRUE
A.power_environ = TRUE
diff --git a/code/game/gamemodes/gangs/dominator.dm b/code/game/gamemodes/gangs/dominator.dm
index 8c1272dcbd..db060a6539 100644
--- a/code/game/gamemodes/gangs/dominator.dm
+++ b/code/game/gamemodes/gangs/dominator.dm
@@ -101,7 +101,7 @@
playsound(loc, 'sound/items/timer.ogg', 10, 0)
if(!warned && (time_remaining < 180))
warned = TRUE
- var/area/domloc = get_area(loc)
+ var/area/domloc = get_base_area(loc)
gang.message_gangtools("Less than 3 minutes remains in hostile takeover. Defend your dominator at [domloc.map_name]!")
for(var/G in GLOB.gangs)
var/datum/team/gang/tempgang = G
@@ -179,7 +179,7 @@
if((tempgang.domination_time != NOT_DOMINATING) || !tempgang.dom_attempts || !in_range(src, user) || !isturf(loc))
return 0
- var/area/A = get_area(loc)
+ var/area/A = get_base_area(loc)
var/locname = A.map_name
gang = tempgang
diff --git a/code/game/gamemodes/gangs/gang_decals.dm b/code/game/gamemodes/gangs/gang_decals.dm
index 6e5cb58891..7aaed769d9 100644
--- a/code/game/gamemodes/gangs/gang_decals.dm
+++ b/code/game/gamemodes/gangs/gang_decals.dm
@@ -19,7 +19,7 @@
return INITIALIZE_HINT_QDEL
gang = G
var/newcolor = G.color
- var/area/territory = get_area(src)
+ var/area/territory = get_base_area(src)
icon_state = G.name
G.new_territories |= list(territory.type = territory.name)
//If this isn't tagged by a specific gangster there's no bonus income.
@@ -27,7 +27,7 @@
/obj/effect/decal/cleanable/crayon/gang/Destroy()
if(gang)
- var/area/territory = get_area(src)
+ var/area/territory = get_base_area(src)
gang.territories -= territory.type
gang.new_territories -= territory.type
gang.lost_territories |= list(territory.type = territory.name)
diff --git a/code/game/gamemodes/gangs/gang_items.dm b/code/game/gamemodes/gangs/gang_items.dm
index 2e9ca4dcc0..688af3beea 100644
--- a/code/game/gamemodes/gangs/gang_items.dm
+++ b/code/game/gamemodes/gangs/gang_items.dm
@@ -401,7 +401,7 @@ datum/gang_item/equipment/gangsheild
return "This device requires a 5x5 area clear of walls to FUNCTION. (Estimated Takeover Time: [round(gang.determine_domination_time()/60,0.1)] minutes)"
/datum/gang_item/equipment/dominator/purchase(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool)
- var/area/userarea = get_area(user)
+ var/area/userarea = get_base_area(user)
if(!(userarea.type in gang.territories|gang.new_territories))
to_chat(user,"The dominator can be spawned only on territory controlled by your gang!")
return FALSE
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index 6d681f8108..cfb4c9a120 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -21,16 +21,16 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
//Meteor spawning global procs
///////////////////////////////
-/proc/spawn_meteors(number = 10, list/meteortypes)
+/proc/spawn_meteors(number = 10, list/meteortypes, dir)
for(var/i = 0; i < number; i++)
- spawn_meteor(meteortypes)
+ spawn_meteor(meteortypes, dir)
-/proc/spawn_meteor(list/meteortypes)
+/proc/spawn_meteor(list/meteortypes, dir)
var/turf/pickedstart
var/turf/pickedgoal
var/max_i = 10//number of tries to spawn meteor.
while(!isspaceturf(pickedstart))
- var/startSide = pick(GLOB.cardinals)
+ var/startSide = dir || pick(GLOB.cardinals)
var/startZ = pick(SSmapping.levels_by_trait(ZTRAIT_STATION))
pickedstart = spaceDebrisStartLoc(startSide, startZ)
pickedgoal = spaceDebrisFinishLoc(startSide, startZ)
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index f99fe5c3e4..b7003e4f1e 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -527,7 +527,7 @@ GLOBAL_LIST_EMPTY(possible_items)
else if(targetinfo.check_special_completion(I))//Returns 1 by default. Items with special checks will return 1 if the conditions are fulfilled.
return TRUE
- if(targetinfo && I.type in targetinfo.altitems) //Ok, so you don't have the item. Do you have an alternative, at least?
+ if(targetinfo && (I.type in targetinfo.altitems)) //Ok, so you don't have the item. Do you have an alternative, at least?
if(targetinfo.check_special_completion(I))//Yeah, we do! Don't return 0 if we don't though - then you could fail if you had 1 item that didn't pass and got checked first!
return TRUE
return FALSE
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index bef5effb54..22c1ff811c 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -319,7 +319,8 @@
if(status)
change_msg = "reactivates"
triggerCameraAlarm()
- addtimer(CALLBACK(src, .proc/cancelCameraAlarm), 100)
+ if(!QDELETED(src)) //We'll be doing it anyway in destroy
+ addtimer(CALLBACK(src, .proc/cancelCameraAlarm), 100)
if(displaymessage)
if(user)
visible_message("[user] [change_msg] [src]!")
diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm
index fc6cac785a..991577e123 100644
--- a/code/game/machinery/cell_charger.dm
+++ b/code/game/machinery/cell_charger.dm
@@ -46,7 +46,7 @@
var/area/a = loc.loc // Gets our locations location, like a dream within a dream
if(!isarea(a))
return
- if(a.power_equip == 0) // There's no APC in this area, don't try to cheat power!
+ if(!a.powered(EQUIP)) // There's no APC in this area, don't try to cheat power!
to_chat(user, "[src] blinks red as you try to insert the cell!")
return
if(!user.transferItemToLoc(W,src))
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 711b221c54..afb882598e 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -4,7 +4,7 @@
//Potential replacement for genetics revives or something I dunno (?)
#define CLONE_INITIAL_DAMAGE 150 //Clones in clonepods start with 150 cloneloss damage and 150 brainloss damage, thats just logical
-#define MINIMUM_HEAL_LEVEL 40
+#define MINIMUM_HEAL_LEVEL 20
#define SPEAK(message) radio.talk_into(src, message, radio_channel)
@@ -61,18 +61,15 @@
QDEL_LIST(unattached_flesh)
. = ..()
-/obj/machinery/clonepod/RefreshParts()
+/obj/machinery/clonepod/RefreshParts()
speed_coeff = 0
efficiency = 0
for(var/obj/item/stock_parts/scanning_module/S in component_parts)
efficiency += S.rating
for(var/obj/item/stock_parts/manipulator/P in component_parts)
- speed_coeff += P.rating
- heal_level = (efficiency * 15) + 10
- if(heal_level < MINIMUM_HEAL_LEVEL)
- heal_level = MINIMUM_HEAL_LEVEL
- if(heal_level > 100)
- heal_level = 100
+ speed_coeff += (P.rating / 2)
+ speed_coeff = max(1, speed_coeff)
+ heal_level = CLAMP((efficiency * 10) + 10, MINIMUM_HEAL_LEVEL, 100)
//The return of data disks?? Just for transferring between genetics machine/cloning machine.
//TO-DO: Make the genetics machine accept them.
@@ -169,9 +166,7 @@
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
H.hardset_dna(ui, se, H.real_name, null, mrace, features)
-
- if(prob(50 - efficiency*10)) //Chance to give a bad mutation.
- H.randmutb() //100% bad mutation. Can be cured with mutadone.
+ H.randmutb() //100% bad mutation. Can be cured with mutadone.
H.silent = 20 //Prevents an extreme edge case where clones could speak if they said something at exactly the right moment.
occupant = H
diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm
index a238c4a451..b007bc0161 100644
--- a/code/game/machinery/constructable_frame.dm
+++ b/code/game/machinery/constructable_frame.dm
@@ -119,6 +119,9 @@
if(istype(P, /obj/item/circuitboard/machine))
var/obj/item/circuitboard/machine/B = P
+ if(!B.build_path)
+ to_chat(user, "This circuitboard seems to be broken.")
+ return
if(!anchored && B.needs_anchored)
to_chat(user, "The frame needs to be secured first!")
return
diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm
index 91306585b8..c6b4f2fcf5 100644
--- a/code/game/machinery/dance_machine.dm
+++ b/code/game/machinery/dance_machine.dm
@@ -406,12 +406,11 @@
lying_prev = 0
/obj/machinery/jukebox/proc/dance_over()
- SSjukeboxes.removejukebox(SSjukeboxes.findjukeboxindex(src))
+ var/position = SSjukeboxes.findjukeboxindex(src)
+ if(!position)
+ return
+ SSjukeboxes.removejukebox(position)
STOP_PROCESSING(SSobj, src)
- for(var/mob/living/L in rangers)
- if(!L || !L.client)
- continue
- L.stop_sound_channel(CHANNEL_JUKEBOX)
rangers = list()
/obj/machinery/jukebox/disco/dance_over()
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index ad0f372530..9db98b8314 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -288,9 +288,10 @@
return
operating = TRUE
-
do_animate("closing")
layer = closingLayer
+ if(!safe)
+ crush()
sleep(5)
density = TRUE
sleep(5)
@@ -302,8 +303,6 @@
update_freelook_sight()
if(safe)
CheckForMobs()
- else
- crush()
return 1
/obj/machinery/door/proc/CheckForMobs()
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index f5bf8c8a1b..cb133978b2 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -44,7 +44,7 @@
/obj/machinery/door/firedoor/proc/CalculateAffectingAreas()
remove_from_areas()
- affecting_areas = get_adjacent_open_areas(src) | get_area(src)
+ affecting_areas = get_adjacent_open_areas(src) | get_base_area(src)
for(var/I in affecting_areas)
var/area/A = I
LAZYADD(A.firedoors, src)
diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm
index 1ef3fc0a74..5555e05eb0 100644
--- a/code/game/machinery/firealarm.dm
+++ b/code/game/machinery/firealarm.dm
@@ -44,7 +44,7 @@
pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0
update_icon()
- myarea = get_area(src)
+ myarea = get_base_area(src)
LAZYADD(myarea.firealarms, src)
/obj/machinery/firealarm/Destroy()
@@ -124,7 +124,7 @@
if(!is_operational() || (last_alarm+FIREALARM_COOLDOWN > world.time))
return
last_alarm = world.time
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
A.firealert(src)
playsound(loc, 'goon/sound/machinery/FireAlarm.ogg', 75)
if(user)
@@ -133,7 +133,7 @@
/obj/machinery/firealarm/proc/reset(mob/user)
if(!is_operational())
return
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
A.firereset(src)
if(user)
log_game("[user] reset a fire alarm at [COORD(src)]")
@@ -142,7 +142,7 @@
if(buildstage != 2)
return ..()
add_fingerprint(user)
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
if(A.fire)
reset(user)
else
@@ -198,7 +198,7 @@
return
else if(W.force) //hit and turn it on
..()
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
if(!A.fire)
alarm()
return
@@ -322,7 +322,7 @@
/obj/machinery/firealarm/partyalarm/reset()
if (stat & (NOPOWER|BROKEN))
return
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
if (!A || !A.party)
return
A.party = FALSE
@@ -331,7 +331,7 @@
/obj/machinery/firealarm/partyalarm/alarm()
if (stat & (NOPOWER|BROKEN))
return
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
if (!A || A.party || A.name == "Space")
return
A.party = TRUE
diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm
index 2211397f3e..f777c893f8 100755
--- a/code/game/machinery/recharger.dm
+++ b/code/game/machinery/recharger.dm
@@ -70,7 +70,7 @@
//Checks to make sure he's not in space doing it, and that the area got proper power.
var/area/a = get_area(src)
- if(!isarea(a) || a.power_equip == 0)
+ if(!a || !a.powered(EQUIP))
to_chat(user, "[src] blinks red as you try to insert [G].")
return 1
diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm
index fdb620cc67..5a907804ce 100644
--- a/code/game/mecha/equipment/tools/other_tools.dm
+++ b/code/game/mecha/equipment/tools/other_tools.dm
@@ -283,7 +283,7 @@
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_charge()
if(equip_ready) //disabled
return
- var/area/A = get_area(chassis)
+ var/area/A = get_base_area(chassis)
var/pow_chan = get_power_channel(A)
if(pow_chan)
return 1000 //making magic
@@ -328,7 +328,7 @@
occupant_message("No powercell detected.")
return
if(cur_charge < chassis.cell.maxcharge)
- var/area/A = get_area(chassis)
+ var/area/A = get_base_area(chassis)
if(A)
var/pow_chan
for(var/c in list(EQUIP,ENVIRON,LIGHT))
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index f556a75434..1dfd5c4143 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -49,6 +49,7 @@
var/lights = FALSE
var/lights_power = 6
var/last_user_hud = 1 // used to show/hide the mecha hud while preserving previous preference
+ var/completely_disabled = FALSE //stops the mech from doing anything
var/breach_time = 0
var/recharge_rate = 0
@@ -431,6 +432,8 @@
return
if(!locate(/turf) in list(target,target.loc)) // Prevents inventory from being drilled
return
+ if(completely_disabled)
+ return
if(phasing)
occupant_message("Unable to interact with objects while phasing")
return
@@ -508,6 +511,8 @@
return 1
/obj/mecha/relaymove(mob/user,direction)
+ if(completely_disabled)
+ return
if(!direction)
return
if(user != occupant) //While not "realistic", this piece is player friendly.
diff --git a/code/game/objects/effects/effect_system/effect_system.dm b/code/game/objects/effects/effect_system/effect_system.dm
index ddc805f3ff..05077bf898 100644
--- a/code/game/objects/effects/effect_system/effect_system.dm
+++ b/code/game/objects/effects/effect_system/effect_system.dm
@@ -48,6 +48,8 @@ would spawn and follow the beaker, even if it is carried or thrown.
holder = atom
/datum/effect_system/proc/start()
+ if(QDELETED(src))
+ return
for(var/i in 1 to number)
if(total_effects > 20)
return
@@ -69,7 +71,8 @@ would spawn and follow the beaker, even if it is carried or thrown.
for(var/j in 1 to steps_amt)
sleep(5)
step(E,direction)
- addtimer(CALLBACK(src, .proc/decrement_total_effect), 20)
+ if(!QDELETED(src))
+ addtimer(CALLBACK(src, .proc/decrement_total_effect), 20)
/datum/effect_system/proc/decrement_total_effect()
total_effects--
diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm
index aabf9acafa..38a1a6089e 100644
--- a/code/game/objects/effects/effect_system/effects_foam.dm
+++ b/code/game/objects/effects/effect_system/effects_foam.dm
@@ -126,7 +126,7 @@
T.PlaceOnTop(/turf/open/floor/plating/foam, flags = CHANGETURF_INHERIT_AIR)
for(var/direction in GLOB.cardinals)
var/turf/cardinal_turf = get_step(T, direction)
- if(get_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf!
+ if(get_base_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf!
new/obj/structure/foamedmetal(T)
break
flick("[icon_state]-disolve", src)
diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm
index 8f09827bd2..3d63f4a553 100644
--- a/code/game/objects/effects/landmarks.dm
+++ b/code/game/objects/effects/landmarks.dm
@@ -456,7 +456,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
if(!SSmapping.station_room_templates[t])
log_world("Station room spawner placed at ([T.x], [T.y], [T.z]) has invalid ruin name of \"[t]\" in its list")
templates -= t
- template_name = pickweight(templates)
+ template_name = pickweightAllowZero(templates)
if(!template_name)
GLOB.stationroom_landmarks -= src
qdel(src)
@@ -485,4 +485,4 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
// Landmark for the mining station
/obj/effect/landmark/stationroom/lavaland/station
templates = list("Public Mining Base" = 3)
- icon = 'icons/rooms/Lavaland/Mining.dmi'
\ No newline at end of file
+ icon = 'icons/rooms/Lavaland/Mining.dmi'
diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm
index 49985f5c23..1186ea8001 100644
--- a/code/game/objects/items/cigs_lighters.dm
+++ b/code/game/objects/items/cigs_lighters.dm
@@ -146,7 +146,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(!proximity || lit) //can't dip if cigarette is lit (it will heat the reagents in the glass instead)
return
if(istype(glass)) //you can dip cigarettes into beakers
- if(glass.reagents.trans_to(src, chem_volume)) //if reagents were transfered, show the message
+ if(glass.reagents.trans_to(src, chem_volume, log = "cigar fill: dip cigarette")) //if reagents were transfered, show the message
to_chat(user, "You dip \the [src] into \the [glass].")
else //if not, either the beaker was empty, or the cigarette was full
if(!glass.reagents.total_volume)
@@ -154,7 +154,6 @@ CIGARETTE PACKETS ARE IN FANCY.DM
else
to_chat(user, "[src] is full.")
-
/obj/item/clothing/mask/cigarette/proc/light(flavor_text = null)
if(lit)
return
@@ -438,7 +437,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
packeditem = 1
name = "[O.name]-packed [initial(name)]"
if(O.reagents)
- O.reagents.trans_to(src, O.reagents.total_volume)
+ O.reagents.trans_to(src, O.reagents.total_volume, log = "cigar fill: pipe pack")
qdel(O)
else
to_chat(user, "It has to be dried first!")
@@ -687,7 +686,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(O.dry)
var/obj/item/clothing/mask/cigarette/rollie/R = new /obj/item/clothing/mask/cigarette/rollie(user.loc)
R.chem_volume = target.reagents.total_volume
- target.reagents.trans_to(R, R.chem_volume)
+ target.reagents.trans_to(R, R.chem_volume, log = "cigar fill: rolling paper afterattack")
qdel(target)
qdel(src)
user.put_in_active_hand(R)
@@ -903,7 +902,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
//Transfer reagents and remove the plant
user.show_message("You stuff the [DP] into the [src]'s bowl.", MSG_VISUAL)
- DP.reagents.trans_to(src, 100)
+ DP.reagents.trans_to(src, 100, log = "cigar fill: bong")
qdel(DP)
return
else
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index 143354b496..cb77a58769 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -427,7 +427,7 @@
/obj/item/toy/crayon/proc/can_claim_for_gang(mob/user, atom/target)
// Check area validity.
// Reject space, player-created areas, and non-station z-levels.
- var/area/A = get_area(target)
+ var/area/A = get_base_area(target)
if(!A || (!is_station_level(A.z)) || !A.valid_territory)
to_chat(user, "[A] is unsuitable for tagging.")
return FALSE
@@ -461,7 +461,7 @@
qdel(old_marking)
var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang)
- var/area/territory = get_area(target)
+ var/area/territory = get_base_area(target)
new /obj/effect/decal/cleanable/crayon/gang(target,G.gang,"graffiti",0,user) // Heres the gang tag.
to_chat(user, "You tagged [territory] for your gang!")
diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm
index 07d58c1754..386b1fe668 100644
--- a/code/game/objects/items/defib.dm
+++ b/code/game/objects/items/defib.dm
@@ -452,14 +452,15 @@
return TRUE
/obj/item/twohanded/shockpaddles/proc/shock_touching(dmg, mob/H)
- if(req_defib)
- if(defib.pullshocksafely && isliving(H.pulledby))
- H.visible_message("The defibrillator safely discharges the excessive charge into the floor!")
- else
- var/mob/living/M = H.pulledby
- if(M.electrocute_act(30, src))
- M.visible_message("[M] is electrocuted by [M.p_their()] contact with [H]!")
- M.emote("scream")
+ if(!H.pulledby || !isliving(H.pulledby))
+ return
+ if(req_defib && defib.pullshocksafely)
+ H.visible_message("The defibrillator safely discharges the excessive charge into the floor!")
+ return
+ var/mob/living/M = H.pulledby
+ if(M.electrocute_act(30, src))
+ M.visible_message("[M] is electrocuted by [M.p_their()] contact with [H]!")
+ M.emote("scream")
/obj/item/twohanded/shockpaddles/proc/do_disarm(mob/living/M, mob/living/user)
if(req_defib && defib.safety)
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index f80dd366be..51d8a88df8 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -1,4 +1,3 @@
-
//The advanced pea-green monochrome lcd of tomorrow.
GLOBAL_LIST_EMPTY(PDAs)
diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm
index e4fa241907..ba3fdce9b9 100644
--- a/code/game/objects/items/devices/PDA/cart.dm
+++ b/code/game/objects/items/devices/PDA/cart.dm
@@ -326,7 +326,7 @@ Code:
if(active1 in GLOB.data_core.general)
menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]
"
- menu += "Sex: [active1.fields["sex"]]
"
+ menu += "Sex: [active1.fields["gender"]]
"
menu += "Age: [active1.fields["age"]]
"
menu += "Rank: [active1.fields["rank"]]
"
menu += "Fingerprint: [active1.fields["fingerprint"]]
"
@@ -370,7 +370,7 @@ Code:
if(active1 in GLOB.data_core.general)
menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]
"
- menu += "Sex: [active1.fields["sex"]]
"
+ menu += "Sex: [active1.fields["gender"]]
"
menu += "Age: [active1.fields["age"]]
"
menu += "Rank: [active1.fields["rank"]]
"
menu += "Fingerprint: [active1.fields["fingerprint"]]
"
diff --git a/code/game/objects/items/devices/desynchronizer.dm b/code/game/objects/items/devices/desynchronizer.dm
index ff58af2405..0fa557f666 100644
--- a/code/game/objects/items/devices/desynchronizer.dm
+++ b/code/game/objects/items/devices/desynchronizer.dm
@@ -14,6 +14,7 @@
var/last_use = 0
var/next_use = 0
var/obj/effect/abstract/sync_holder/sync_holder
+ var/resync_timer
/obj/item/desynchronizer/attack_self(mob/living/user)
if(world.time < next_use)
@@ -56,16 +57,20 @@
SEND_SIGNAL(AM, COMSIG_MOVABLE_SECLUDED_LOCATION)
last_use = world.time
icon_state = "desynchronizer-on"
- addtimer(CALLBACK(src, .proc/resync), duration)
+ resync_timer = addtimer(CALLBACK(src, .proc/resync), duration , TIMER_STOPPABLE)
/obj/item/desynchronizer/proc/resync()
new /obj/effect/temp_visual/desynchronizer(sync_holder.drop_location())
QDEL_NULL(sync_holder)
+ if(resync_timer)
+ deltimer(resync_timer)
+ resync_timer = null
icon_state = initial(icon_state)
next_use = world.time + (world.time - last_use) // Could be 2*world.time-last_use but that would just be confusing
/obj/item/desynchronizer/Destroy()
- resync()
+ if(sync_holder)
+ resync()
return ..()
/obj/effect/abstract/sync_holder
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index 8c6666085e..e04501144e 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -26,6 +26,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
slot_flags = ITEM_SLOT_EARS
var/obj/item/encryptionkey/keyslot2 = null
dog_fashion = null
+ var/bowman = FALSE
/obj/item/radio/headset/suicide_act(mob/living/carbon/user)
user.visible_message("[user] begins putting \the [src]'s antenna up [user.p_their()] nose! It looks like [user.p_theyre()] trying to give [user.p_them()]self cancer!")
@@ -52,6 +53,11 @@ GLOBAL_LIST_INIT(channel_tokens, list(
else
. += "A small screen on the headset flashes, it's too small to read without holding or wearing the headset."
+/obj/item/radio/headset/ComponentInitialize()
+ . = ..()
+ if (bowman)
+ AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
+
/obj/item/radio/headset/Initialize()
. = ..()
recalculateChannels()
@@ -81,10 +87,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs."
icon_state = "syndie_headset"
item_state = "syndie_headset"
-
-/obj/item/radio/headset/syndicate/alt/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
+ bowman = TRUE
/obj/item/radio/headset/syndicate/alt/leader
name = "team leader headset"
@@ -112,10 +115,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
desc = "This is used by your elite security force. Protects ears from flashbangs."
icon_state = "sec_headset_alt"
item_state = "sec_headset_alt"
-
-/obj/item/radio/headset/headset_sec/alt/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
+ bowman = TRUE
/obj/item/radio/headset/headset_eng
name = "engineering radio headset"
@@ -161,10 +161,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
desc = "The headset of the boss. Protects ears from flashbangs."
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
-
-/obj/item/radio/headset/heads/captain/alt/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
+ bowman = TRUE
/obj/item/radio/headset/heads/rd
name = "\proper the research director's headset"
@@ -183,10 +180,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs."
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
-
-/obj/item/radio/headset/heads/hos/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
+ bowman = TRUE
/obj/item/radio/headset/heads/ce
name = "\proper the chief engineer's headset"
@@ -258,10 +252,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
icon_state = "cent_headset_alt"
item_state = "cent_headset_alt"
keyslot = null
-
-/obj/item/radio/headset/headset_cent/alt/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
+ bowman = TRUE
/obj/item/radio/headset/ai
name = "\proper Integrated Subspace Transceiver "
@@ -273,7 +264,11 @@ GLOBAL_LIST_INIT(channel_tokens, list(
/obj/item/radio/headset/attackby(obj/item/W, mob/user, params)
user.set_machine(src)
-
+ if (istype(W,/obj/item/headsetupgrader))
+ if (!bowman)
+ to_chat(user,"You upgrade [src].")
+ bowmanize()
+ qdel(W)
if(istype(W, /obj/item/screwdriver))
if(keyslot || keyslot2)
for(var/ch_name in channels)
@@ -341,3 +336,24 @@ GLOBAL_LIST_INIT(channel_tokens, list(
use_command = !use_command
to_chat(user, "You toggle high-volume mode [use_command ? "on" : "off"].")
return TRUE
+
+/obj/item/radio/headset/proc/bowmanize()
+ cut_overlays()
+ var/icon/yeas = icon(icon,icon_state)
+ icon_state = "antenna_alt"
+ var/mutable_appearance/center = mutable_appearance(icon,"center_alt")
+ center.color = yeas.GetPixel(15,18)
+ var/mutable_appearance/centeralt = mutable_appearance(icon,"centeralt_alt")
+ centeralt.color = yeas.GetPixel(14,22)
+ var/mutable_appearance/centercenter = mutable_appearance(icon,"centercenter_alt")
+ centercenter.color = yeas.GetPixel(13,19)
+ var/mutable_appearance/centerpixel = mutable_appearance(icon,"centerpixel_alt")
+ centerpixel.color = yeas.GetPixel(13,21)
+ add_overlay(center)
+ add_overlay(centeralt)
+ add_overlay(centercenter)
+ add_overlay(centerpixel)
+ name = replacetext(name,"headset", "bowman headset")
+ desc = "[desc] Protects ears from flashbangs."
+ bowman = TRUE
+ AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm
index fc768cd38e..64e2830dd4 100644
--- a/code/game/objects/items/devices/traitordevices.dm
+++ b/code/game/objects/items/devices/traitordevices.dm
@@ -251,3 +251,9 @@ effective or pretty fucking useless.
else
GLOB.active_jammers -= src
update_icon()
+
+/obj/item/headsetupgrader
+ name = "headset upgrader"
+ desc = "A tool that can be used to upgrade a normal headset to be able to protect from flashbangs."
+ icon = 'icons/obj/device.dmi'
+ icon_state = "headset_upgrade"
diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm
index f6f14554ed..8ce0f33307 100644
--- a/code/game/objects/items/handcuffs.dm
+++ b/code/game/objects/items/handcuffs.dm
@@ -310,6 +310,7 @@
trap_damage = 0
item_flags = DROPDEL
flags_1 = NONE
+ breakouttime = 50
/obj/item/restraints/legcuffs/beartrap/energy/New()
..()
diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm
index f6bff2f880..21de34faa1 100644
--- a/code/game/objects/items/stacks/sheets/glass.dm
+++ b/code/game/objects/items/stacks/sheets/glass.dm
@@ -10,7 +10,15 @@
*/
GLOBAL_LIST_INIT(glass_recipes, list ( \
new/datum/stack_recipe("directional window", /obj/structure/window/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \
- new/datum/stack_recipe("fulltile window", /obj/structure/window/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \
+ new/datum/stack_recipe("fulltile window", /obj/structure/window/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
+ null, \
+ new/datum/stack_recipe_list("glass working bases", list( \
+ new/datum/stack_recipe("chem dish", /obj/item/glasswork/glass_base/dish, 10), \
+ new/datum/stack_recipe("lens", /obj/item/glasswork/glass_base/glass_lens, 15), \
+ new/datum/stack_recipe("spout flask", /obj/item/glasswork/glass_base/spouty, 20), \
+ new/datum/stack_recipe("small bulb flask", /obj/item/glasswork/glass_base/flask_small, 5), \
+ new/datum/stack_recipe("large bottle flask", /obj/item/glasswork/glass_base/flask_large, 15), \
+ )), \
))
/obj/item/stack/sheet/glass
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index a80f0d5a3b..31dd6d32a3 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -277,6 +277,9 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
recipes = GLOB.wood_recipes
return ..()
+/obj/item/stack/sheet/mineral/wood/twenty
+ amount = 20
+
/obj/item/stack/sheet/mineral/wood/fifty
amount = 50
@@ -306,6 +309,15 @@ GLOBAL_LIST_INIT(bamboo_recipes, list ( \
recipes = GLOB.bamboo_recipes
return ..()
+/obj/item/stack/sheet/mineral/bamboo/ten
+ amount = 10
+
+/obj/item/stack/sheet/mineral/bamboo/twenty
+ amount = 20
+
+/obj/item/stack/sheet/mineral/bamboo/fifty
+ amount = 50
+
/*
* Cloth
*/
@@ -782,3 +794,4 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra
merge_type = /obj/item/stack/sheet/cotton/durathread
pull_effort = 70
loom_result = /obj/item/stack/sheet/durathread
+
diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm
index 18acb5e14d..fa4e5a3886 100644
--- a/code/game/objects/items/stacks/tiles/tile_types.dm
+++ b/code/game/objects/items/stacks/tiles/tile_types.dm
@@ -233,39 +233,111 @@
turf_type = /turf/open/floor/carpet/royalblue
tableVariant = /obj/structure/table/wood/fancy/royalblue
+/obj/item/stack/tile/carpet/ten
+ amount = 10
+
+/obj/item/stack/tile/carpet/twenty
+ amount = 20
+
/obj/item/stack/tile/carpet/fifty
amount = 50
+/obj/item/stack/tile/carpet/black/ten
+ amount = 10
+
+/obj/item/stack/tile/carpet/black/twenty
+ amount = 20
+
/obj/item/stack/tile/carpet/black/fifty
amount = 50
+/obj/item/stack/tile/carpet/blackred/ten
+ amount = 10
+
+/obj/item/stack/tile/carpet/blackred/twenty
+ amount = 20
+
/obj/item/stack/tile/carpet/blackred/fifty
amount = 50
+/obj/item/stack/tile/carpet/monochrome/ten
+ amount = 10
+
+/obj/item/stack/tile/carpet/monochrome/twenty
+ amount = 20
+
/obj/item/stack/tile/carpet/monochrome/fifty
amount = 50
+/obj/item/stack/tile/carpet/blue/ten
+ amount = 10
+
+/obj/item/stack/tile/carpet/blue/twenty
+ amount = 20
+
/obj/item/stack/tile/carpet/blue/fifty
amount = 50
+/obj/item/stack/tile/carpet/cyan/ten
+ amount = 10
+
+/obj/item/stack/tile/carpet/cyan/twenty
+ amount = 20
+
/obj/item/stack/tile/carpet/cyan/fifty
amount = 50
+/obj/item/stack/tile/carpet/green/ten
+ amount = 10
+
+/obj/item/stack/tile/carpet/green/twenty
+ amount = 20
+
/obj/item/stack/tile/carpet/green/fifty
amount = 50
+/obj/item/stack/tile/carpet/orange/ten
+ amount = 10
+
+/obj/item/stack/tile/carpet/orange/twenty
+ amount = 20
+
/obj/item/stack/tile/carpet/orange/fifty
amount = 50
+/obj/item/stack/tile/carpet/purple/ten
+ amount = 10
+
+/obj/item/stack/tile/carpet/purple/twenty
+ amount = 20
+
/obj/item/stack/tile/carpet/purple/fifty
amount = 50
+/obj/item/stack/tile/carpet/red/ten
+ amount = 10
+
+/obj/item/stack/tile/carpet/red/twenty
+ amount = 20
+
/obj/item/stack/tile/carpet/red/fifty
amount = 50
+/obj/item/stack/tile/carpet/royalblack/ten
+ amount = 10
+
+/obj/item/stack/tile/carpet/royalblack/twenty
+ amount = 20
+
/obj/item/stack/tile/carpet/royalblack/fifty
amount = 50
+/obj/item/stack/tile/carpet/royalblue/ten
+ amount = 10
+
+/obj/item/stack/tile/carpet/royalblue/twenty
+ amount = 20
+
/obj/item/stack/tile/carpet/royalblue/fifty
amount = 50
diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm
index 31efabf210..880b714f76 100644
--- a/code/game/objects/items/storage/toolbox.dm
+++ b/code/game/objects/items/storage/toolbox.dm
@@ -293,7 +293,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
desc = replacetext(desc, "robust", "safe")
desc = replacetext(desc, "heavier", "bouncier")
DISABLE_BITFIELD(flags_1, CONDUCT_1)
- materials = null
+ materials = typelist("materials", null)
damtype = STAMINA
force += 3 //to compensate the higher stamina K.O. threshold compared to actual health.
throwforce += 3
@@ -317,8 +317,8 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
flags_1 = null
materials = null
damtype = STAMINA
- force = 17
- throwforce = 17
+ force = 15
+ throwforce = 15
attack_verb = list("robusted", "bounced")
can_rubberify = FALSE //we are already the future.
diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm
index b9862c3423..28a6fd66ee 100644
--- a/code/game/objects/items/twohanded.dm
+++ b/code/game/objects/items/twohanded.dm
@@ -25,8 +25,8 @@
*/
/obj/item/twohanded
var/wielded = 0
- var/force_unwielded = 0
- var/force_wielded = 0
+ var/force_unwielded // default to null, the number force will be set to on unwield()
+ var/force_wielded // same as above but for wield()
var/wieldsound = null
var/unwieldsound = null
var/slowdown_wielded = 0
@@ -73,7 +73,7 @@
to_chat(user, "You don't have enough intact hands.")
return
wielded = 1
- if(force_wielded)
+ if(!isnull(force_wielded))
force = force_wielded
name = "[name] (Wielded)"
update_icon()
@@ -738,7 +738,7 @@
on = !on
to_chat(user, "As you pull the starting cord dangling from [src], [on ? "it begins to whirr." : "the chain stops moving."]")
force = on ? force_on : initial(force)
- throwforce = on ? force_on : initial(force)
+ throwforce = on ? force_on : force
icon_state = "chainsaw_[on ? "on" : "off"]"
var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
butchering.butchering_enabled = on
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 5f3fc48eb7..0c1239e887 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -178,7 +178,7 @@
machine = null
//called when the user unsets the machine.
-/atom/movable/proc/on_unset_machine(mob/user)
+/atom/proc/on_unset_machine(mob/user)
return
/mob/proc/set_machine(obj/O)
diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm
index 5b9a764925..fcd1f80a4f 100644
--- a/code/game/objects/structures/ai_core.dm
+++ b/code/game/objects/structures/ai_core.dm
@@ -52,7 +52,7 @@
var/area/A = get_area(src)
if(!A.blob_allowed)
return FALSE
- if(!A.power_equip)
+ if(!A.powered(EQUIP))
return FALSE
if(!SSmapping.level_trait(T.z,ZTRAIT_STATION))
return FALSE
diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm
index 053512a256..b72a4b816e 100644
--- a/code/game/objects/structures/barsigns.dm
+++ b/code/game/objects/structures/barsigns.dm
@@ -305,7 +305,7 @@
/datum/barsign/meow_mix
name = "Meow Mix"
- icon = "meow_mix"
+ icon = "Meow Mix"
desc = "No, we don't serve catnip, officer!"
/datum/barsign/hiddensigns
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 9a095bf69d..daf15832fb 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -532,7 +532,7 @@
/obj/structure/closet/CtrlShiftClick(mob/living/user)
if(!HAS_TRAIT(user, TRAIT_SKITTISH))
return ..()
- if(!user.canUseTopic(src) || !isturf(user.loc))
+ if(!user.canUseTopic(src) || !isturf(user.loc) || !user.Adjacent(src) || !user.CanReach(src))
return
dive_into(user)
diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm
index 8c25a2ca5c..70533df0ad 100644
--- a/code/game/objects/structures/displaycase.dm
+++ b/code/game/objects/structures/displaycase.dm
@@ -80,7 +80,7 @@
/obj/structure/displaycase/proc/trigger_alarm()
//Activate Anti-theft
if(alert)
- var/area/alarmed = get_area(src)
+ var/area/alarmed = get_base_area(src)
alarmed.burglaralert(src)
playsound(src, 'sound/effects/alert.ogg', 50, 1)
diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm
index 271ae72d47..f35e9e7d55 100644
--- a/code/game/objects/structures/door_assembly.dm
+++ b/code/game/objects/structures/door_assembly.dm
@@ -205,6 +205,9 @@
if(!mineral)
if(istype(G, /obj/item/stack/sheet/mineral) && G.sheettype)
var/M = G.sheettype
+ var/mineralassembly = text2path("/obj/structure/door_assembly/door_assembly_[M]")
+ if(!mineralassembly)
+ return
if(G.get_amount() >= 2)
playsound(src, 'sound/items/crowbar.ogg', 100, 1)
user.visible_message("[user] adds [G.name] to the airlock assembly.", \
@@ -214,7 +217,6 @@
return
to_chat(user, "You install [M] plating into the airlock assembly.")
G.use(2)
- var/mineralassembly = text2path("/obj/structure/door_assembly/door_assembly_[M]")
var/obj/structure/door_assembly/MA = new mineralassembly(loc)
transfer_assembly_vars(src, MA, TRUE)
else
diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm
index d7e2d5564a..52441c2987 100644
--- a/code/game/objects/structures/false_walls.dm
+++ b/code/game/objects/structures/false_walls.dm
@@ -7,7 +7,7 @@
anchored = TRUE
icon = 'icons/turf/walls/wall.dmi'
icon_state = "wall"
- layer = CLOSED_TURF_LAYER
+ layer = LOW_OBJ_LAYER
density = TRUE
opacity = 1
max_integrity = 100
diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm
index 92fb13c947..3ba9fea006 100644
--- a/code/game/objects/structures/ghost_role_spawners.dm
+++ b/code/game/objects/structures/ghost_role_spawners.dm
@@ -619,7 +619,7 @@
assignedrole = "Ghost Cafe Visitor"
flavour_text = "Is this what life after death is like?"
skip_reentry_check = TRUE
- banType = "ghostcafe"
+ banType = ROLE_GHOSTCAFE
/datum/action/toggle_dead_chat_mob
icon_icon = 'icons/mob/mob.dmi'
@@ -642,12 +642,14 @@
/obj/effect/mob_spawn/human/ghostcafe/special(mob/living/carbon/human/new_spawn)
if(new_spawn.client)
new_spawn.client.prefs.copy_to(new_spawn)
+ var/area/A = get_area(src)
var/datum/outfit/O = new /datum/outfit/ghostcafe()
O.equip(new_spawn, FALSE, new_spawn.client)
SSjob.equip_loadout(null, new_spawn, FALSE)
SSquirks.AssignQuirks(new_spawn, new_spawn.client, TRUE, TRUE, null, FALSE, new_spawn)
new_spawn.AddElement(/datum/element/ghost_role_eligibility)
new_spawn.AddElement(/datum/element/dusts_on_catatonia)
+ new_spawn.AddElement(/datum/element/dusts_on_leaving_area,list(A.type,/area/hilbertshotel))
ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, GHOSTROLE_TRAIT)
ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT)
ADD_TRAIT(new_spawn,TRAIT_PACIFISM,GHOSTROLE_TRAIT)
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index 94619e1858..7c373f2734 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -166,6 +166,9 @@
if(S.sheettype && S.sheettype != "runed")
var/M = S.sheettype
if(state == GIRDER_DISPLACED)
+ var/F = text2path("/obj/structure/falsewall/[M]")
+ if(!F)
+ return
if(S.get_amount() < 2)
to_chat(user, "You need at least two sheets to create a false wall!")
return
@@ -174,11 +177,13 @@
return
S.use(2)
to_chat(user, "You create a false wall. Push on it to open or close the passage.")
- var/F = text2path("/obj/structure/falsewall/[M]")
var/obj/structure/FW = new F (loc)
transfer_fingerprints_to(FW)
qdel(src)
else
+ var/F = text2path("/turf/closed/wall/mineral/[M]")
+ if(!F)
+ return
if(S.get_amount() < 2)
to_chat(user, "You need at least two sheets to add plating!")
return
@@ -189,7 +194,7 @@
S.use(2)
to_chat(user, "You add the plating.")
var/turf/T = get_turf(src)
- T.PlaceOnTop(text2path("/turf/closed/wall/mineral/[M]"))
+ T.PlaceOnTop(F)
transfer_fingerprints_to(T)
qdel(src)
return
diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm
index 3b4bbea559..611a6d024d 100644
--- a/code/game/objects/structures/guillotine.dm
+++ b/code/game/objects/structures/guillotine.dm
@@ -97,7 +97,7 @@
icon_state = "guillotine_raised"
/obj/structure/guillotine/proc/drop_blade(mob/user)
- if (buckled_mobs.len && blade_sharpness)
+ if (has_buckled_mobs() && blade_sharpness)
var/mob/living/carbon/human/H = buckled_mobs[1]
if (!H)
diff --git a/code/game/objects/structures/headpike.dm b/code/game/objects/structures/headpike.dm
index ceed9cb759..81433b562d 100644
--- a/code/game/objects/structures/headpike.dm
+++ b/code/game/objects/structures/headpike.dm
@@ -42,8 +42,9 @@
if(.)
return
to_chat(user, "You take down [src].")
- victim.forceMove(drop_location())
- victim = null
+ if(victim)
+ victim.forceMove(drop_location())
+ victim = null
spear.forceMove(drop_location())
spear = null
qdel(src)
\ No newline at end of file
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index 0a5794c59d..90408472e9 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -20,14 +20,14 @@
return
if(broken || !Adjacent(user))
return
-
+
if(ishuman(user))
var/mob/living/carbon/human/H = user
//see code/modules/mob/dead/new_player/preferences.dm at approx line 545 for comments!
//this is largely copypasted from there.
//handle facial hair (if necessary)
- if(H.gender == MALE)
+ if(H.gender != FEMALE)
var/new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in GLOB.facial_hair_styles_list
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return //no tele-grooming
diff --git a/code/game/turfs/simulated/wall/mineral_walls.dm b/code/game/turfs/simulated/wall/mineral_walls.dm
index be46d124ea..d55cb0b475 100644
--- a/code/game/turfs/simulated/wall/mineral_walls.dm
+++ b/code/game/turfs/simulated/wall/mineral_walls.dm
@@ -138,7 +138,8 @@
var/duration = (48/W.force) * 2 //In seconds, for now.
if(istype(W, /obj/item/hatchet) || istype(W, /obj/item/twohanded/fireaxe))
duration /= 4 //Much better with hatchets and axes.
- if(do_after(user, duration*10, target=src)) //Into deciseconds.
+ var/src_type = type
+ if(do_after(user, duration*10, target=src) && type == src_type) //Into deciseconds.
dismantle_wall(FALSE,FALSE)
return
return ..()
diff --git a/code/game/world.dm b/code/game/world.dm
index 7afaf62bb8..8c3e848106 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -116,6 +116,7 @@ GLOBAL_LIST(topic_status_cache)
GLOB.query_debug_log = "[GLOB.log_directory]/query_debug.log"
GLOB.world_job_debug_log = "[GLOB.log_directory]/job_debug.log"
GLOB.subsystem_log = "[GLOB.log_directory]/subsystem.log"
+ GLOB.reagent_log = "[GLOB.log_directory]/reagents.log"
GLOB.world_crafting_log = "[GLOB.log_directory]/crafting.log"
#ifdef UNIT_TESTS
@@ -132,6 +133,7 @@ GLOBAL_LIST(topic_status_cache)
start_log(GLOB.world_runtime_log)
start_log(GLOB.world_job_debug_log)
start_log(GLOB.subsystem_log)
+ start_log(GLOB.reagent_log)
start_log(GLOB.world_crafting_log)
GLOB.changelog_hash = md5('html/changelog.html') //for telling if the changelog has changed recently
diff --git a/code/modules/VR/vr_sleeper.dm b/code/modules/VR/vr_sleeper.dm
index 7cda24d98b..29d7224950 100644
--- a/code/modules/VR/vr_sleeper.dm
+++ b/code/modules/VR/vr_sleeper.dm
@@ -222,18 +222,23 @@
/obj/effect/vr_clean_master/Initialize()
. = ..()
- vr_area = get_area(src)
- addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES)
+ vr_area = get_base_area(src)
+ if(!vr_area)
+ return INITIALIZE_HINT_QDEL
+ addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES, TIMER_LOOP)
/obj/effect/vr_clean_master/proc/clean_up()
- if (vr_area)
- for (var/obj/item/ammo_casing/casing in vr_area)
- qdel(casing)
- for(var/obj/effect/decal/cleanable/C in vr_area)
- qdel(C)
- for (var/A in corpse_party)
- var/mob/M = A
- if(M && M.stat == DEAD && get_area(M) == vr_area)
- qdel(M)
- corpse_party -= M
- addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES)
+ if (!vr_area)
+ qdel(src)
+ return
+ var/list/contents = get_sub_areas_contents(vr_area)
+ for (var/obj/item/ammo_casing/casing in contents)
+ qdel(casing)
+ for(var/obj/effect/decal/cleanable/C in contents)
+ qdel(C)
+ for (var/A in corpse_party)
+ var/mob/M = A
+ if(!QDELETED(M) && (M in contents) && M.stat == DEAD)
+ qdel(M)
+ corpse_party -= M
+ addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES)
diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm
index 70ae133a31..d7af763244 100644
--- a/code/modules/admin/secrets.dm
+++ b/code/modules/admin/secrets.dm
@@ -408,7 +408,7 @@
var/obj/item/organ/tail/cat/tail = new
ears.Insert(H, drop_if_replaced=FALSE)
tail.Insert(H, drop_if_replaced=FALSE)
- var/list/honorifics = list("[MALE]" = list("kun"), "[FEMALE]" = list("chan","tan"), "[NEUTER]" = list("san")) //John Robust -> Robust-kun
+ var/list/honorifics = list("[MALE]" = list("kun"), "[FEMALE]" = list("chan","tan"), "[NEUTER]" = list("san"), "[PLURAL]" = list("san")) //John Robust -> Robust-kun
var/list/names = splittext(H.real_name," ")
var/forename = names.len > 1 ? names[2] : names[1]
var/newname = "[forename]-[pick(honorifics["[H.gender]"])]"
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index c66927b856..c76ecb52f5 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -845,7 +845,11 @@
dat += "
Lavaland | "
else
dat += "Lavaland | "
-
+ // Ghost cafe
+ if(jobban_isbanned(M,ROLE_GHOSTCAFE))
+ dat += "Lavaland | "
+ else
+ dat += "Lavaland | "
dat += ""
//Antagonist (Orange)
@@ -2878,6 +2882,8 @@
return
if(SSdbcore.Connect())
var/datum/DBQuery/query_get_mentor = SSdbcore.NewQuery("SELECT id FROM [format_table_name("mentor")] WHERE ckey = '[ckey]'")
+ if(!query_get_mentor.warn_execute())
+ return
if(query_get_mentor.NextRow())
to_chat(usr, "[ckey] is already a mentor.")
return
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index f08112939a..ad2eeb7289 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -541,7 +541,9 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
var/list/areas_all = list()
var/list/areas_with_APC = list()
var/list/areas_with_multiple_APCs = list()
+ var/list/sub_areas_APC = list()
var/list/areas_with_air_alarm = list()
+ var/list/sub_areas_air_alarm = list()
var/list/areas_with_RC = list()
var/list/areas_with_light = list()
var/list/areas_with_LS = list()
@@ -578,6 +580,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
if(!A)
dat += "Skipped over [APC] in invalid location, [APC.loc]."
continue
+ LAZYSET(sub_areas_APC, A.type, get_sub_areas(A, FALSE))
if(!(A.type in areas_with_APC))
areas_with_APC.Add(A.type)
else if(A.type in areas_all)
@@ -585,10 +588,11 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
CHECK_TICK
for(var/obj/machinery/airalarm/AA in GLOB.machines)
- var/area/A = get_area(AA)
+ var/area/A = get_base_area(AA)
if(!A) //Make sure the target isn't inside an object, which results in runtimes.
dat += "Skipped over [AA] in invalid location, [AA.loc].
"
continue
+ LAZYSET(sub_areas_air_alarm, A.type, get_sub_areas(A, FALSE))
if(!(A.type in areas_with_air_alarm))
areas_with_air_alarm.Add(A.type)
CHECK_TICK
@@ -638,8 +642,8 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
areas_with_camera.Add(A.type)
CHECK_TICK
- var/list/areas_without_APC = areas_all - areas_with_APC
- var/list/areas_without_air_alarm = areas_all - areas_with_air_alarm
+ var/list/areas_without_APC = areas_all - (areas_with_APC + flatten_list(sub_areas_APC))
+ var/list/areas_without_air_alarm = areas_all - (areas_with_air_alarm + flatten_list(sub_areas_air_alarm))
var/list/areas_without_RC = areas_all - areas_with_RC
var/list/areas_without_light = areas_all - areas_with_light
var/list/areas_without_LS = areas_all - areas_with_LS
@@ -656,12 +660,18 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
dat += "AREAS WITH MULTIPLE APCS:
"
for(var/areatype in areas_with_multiple_APCs)
dat += "[areatype]
"
+ if(sub_areas_APC[areatype])
+ dat += " SUB-AREAS:
"
+ dat += jointext(sub_areas_APC[areatype], "
")
CHECK_TICK
if(areas_without_air_alarm.len)
dat += "AREAS WITHOUT AN AIR ALARM:
"
for(var/areatype in areas_without_air_alarm)
dat += "[areatype]
"
+ if(sub_areas_air_alarm[areatype])
+ dat += " SUB-AREAS:
"
+ dat += jointext(sub_areas_air_alarm[areatype], "
")
CHECK_TICK
if(areas_without_RC.len)
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 1437555af1..f30e47c68e 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -419,7 +419,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(record_found)//If they have a record we can determine a few things.
new_character.real_name = record_found.fields["name"]
- new_character.gender = record_found.fields["sex"]
+ new_character.gender = record_found.fields["gender"]
new_character.age = record_found.fields["age"]
new_character.hardset_dna(record_found.fields["identity"], record_found.fields["enzymes"], record_found.fields["name"], record_found.fields["blood_type"], new record_found.fields["species"], record_found.fields["features"])
else
diff --git a/code/modules/antagonists/abductor/abductee/abductee.dm b/code/modules/antagonists/abductor/abductee/abductee.dm
new file mode 100644
index 0000000000..901d2f5b11
--- /dev/null
+++ b/code/modules/antagonists/abductor/abductee/abductee.dm
@@ -0,0 +1,34 @@
+/datum/antagonist/abductee
+ name = "Abductee"
+ roundend_category = "abductees"
+ antagpanel_category = "Abductee"
+ var/datum/brain_trauma/abductee/brain_trauma
+
+/datum/antagonist/abductee/on_gain()
+ give_objective()
+ . = ..()
+
+/datum/antagonist/abductee/greet()
+ to_chat(owner, "Your mind snaps!")
+ to_chat(owner, "You can't remember how you got here...")
+ owner.announce_objectives()
+
+/datum/antagonist/abductee/proc/give_objective()
+ var/mob/living/carbon/human/H = owner.current
+ if(istype(H))
+ H.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_LOBOTOMY)
+ var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random))
+ var/datum/objective/abductee/O = new objtype()
+ objectives += O
+
+/datum/antagonist/abductee/apply_innate_effects(mob/living/mob_override)
+ update_abductor_icons_added(mob_override ? mob_override.mind : owner,"abductee")
+ var/mob/living/carbon/C = mob_override || owner?.current
+ if(istype(C))
+ if(brain_trauma)
+ qdel(brain_trauma) //make sure there's no lingering trauma
+ brain_trauma = C.gain_trauma(/datum/brain_trauma/abductee, TRAUMA_RESILIENCE_SURGERY)
+
+/datum/antagonist/abductee/remove_innate_effects(mob/living/mob_override)
+ update_abductor_icons_removed(mob_override ? mob_override.mind : owner)
+ qdel(brain_trauma)
diff --git a/code/modules/antagonists/abductor/abductee/abductee_objectives.dm b/code/modules/antagonists/abductor/abductee/abductee_objectives.dm
index f188319644..2d62bf1ac9 100644
--- a/code/modules/antagonists/abductor/abductee/abductee_objectives.dm
+++ b/code/modules/antagonists/abductor/abductee/abductee_objectives.dm
@@ -18,7 +18,7 @@
/datum/objective/abductee/paint/New()
var/color = pick(list("red", "blue", "green", "yellow", "orange", "purple", "black", "in rainbows", "in blood"))
- explanation_text+= " [color]!"
+ explanation_text = " [color]!"
/datum/objective/abductee/speech
explanation_text = "Your brain is broken... you can only communicate in"
diff --git a/code/modules/antagonists/abductor/abductee/trauma.dm b/code/modules/antagonists/abductor/abductee/trauma.dm
new file mode 100644
index 0000000000..1518825e1b
--- /dev/null
+++ b/code/modules/antagonists/abductor/abductee/trauma.dm
@@ -0,0 +1,18 @@
+/datum/brain_trauma/abductee
+ name = "abductee mindsnapped"
+ desc = "The patient's brain has been scrambled by experimental procedures."
+ scan_desc = "brain scrambling"
+ gain_text = "Your mind snaps.. you feel fragmented."
+ lose_text = "Your mind heals itself and you feel whole again."
+ random_gain = FALSE
+ clonable = TRUE
+
+/datum/brain_trauma/abductee/on_gain()
+ . = ..()
+ if(owner.mind)
+ if(!owner.mind.has_antag_datum(/datum/antagonist/abductee))
+ owner.mind.add_antag_datum(/datum/antagonist/abductee)
+
+/datum/brain_trauma/abductee/on_lose()
+ . = ..()
+ owner.mind?.remove_antag_datum(/datum/antagonist/abductee)
diff --git a/code/modules/antagonists/abductor/abductor.dm b/code/modules/antagonists/abductor/abductor.dm
index 92504641a9..564e9a8617 100644
--- a/code/modules/antagonists/abductor/abductor.dm
+++ b/code/modules/antagonists/abductor/abductor.dm
@@ -159,35 +159,6 @@
return "[result.Join("
")]
"
-/datum/antagonist/abductee
- name = "Abductee"
- roundend_category = "abductees"
- antagpanel_category = "Abductee"
-
-/datum/antagonist/abductee/on_gain()
- give_objective()
- . = ..()
-
-/datum/antagonist/abductee/greet()
- to_chat(owner, "Your mind snaps!")
- to_chat(owner, "You can't remember how you got here...")
- owner.announce_objectives()
-
-/datum/antagonist/abductee/proc/give_objective()
- var/mob/living/carbon/human/H = owner.current
- if(istype(H))
- H.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_LOBOTOMY)
- var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random))
- var/datum/objective/abductee/O = new objtype()
- objectives += O
-
-/datum/antagonist/abductee/apply_innate_effects(mob/living/mob_override)
- update_abductor_icons_added(mob_override ? mob_override.mind : owner,"abductee")
-
-/datum/antagonist/abductee/remove_innate_effects(mob/living/mob_override)
- update_abductor_icons_removed(mob_override ? mob_override.mind : owner)
-
-
// LANDMARKS
/obj/effect/landmark/abductor
var/team_number = 1
diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm
index dc6d12453d..332329a221 100644
--- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm
+++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm
@@ -29,6 +29,11 @@
var/stealth_armor = list("melee" = 15, "bullet" = 15, "laser" = 15, "energy" = 15, "bomb" = 15, "bio" = 15, "rad" = 15, "fire" = 70, "acid" = 70)
var/combat_armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 50, "rad" = 50, "fire" = 90, "acid" = 90)
+/obj/item/clothing/suit/armor/abductor/vest/Initialize()
+ . = ..()
+ stealth_armor = getArmor(arglist(stealth_armor))
+ combat_armor = getArmor(arglist(combat_armor))
+
/obj/item/clothing/suit/armor/abductor/vest/proc/toggle_nodrop()
if(HAS_TRAIT_FROM(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT))
REMOVE_TRAIT(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT)
@@ -629,15 +634,12 @@
icon_state = "abductor_headset"
item_state = "abductor_headset"
keyslot2 = new /obj/item/encryptionkey/heads/captain
+ bowman = TRUE
/obj/item/radio/headset/abductor/Initialize(mapload)
. = ..()
make_syndie()
-/obj/item/radio/headset/abductor/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
-
/obj/item/radio/headset/abductor/attackby(obj/item/W, mob/user, params)
if(W.tool_behaviour == TOOL_SCREWDRIVER)
return // Stops humans from disassembling abductor headsets.
diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm
index da002e568c..7948b30035 100644
--- a/code/modules/antagonists/cult/runes.dm
+++ b/code/modules/antagonists/cult/runes.dm
@@ -22,7 +22,7 @@ Runes can either be invoked by one's self or with many different cultists. Each
icon = 'icons/obj/rune.dmi'
icon_state = "1"
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
- layer = LOW_OBJ_LAYER
+ layer = SIGIL_LAYER
color = RUNE_COLOR_RED
var/invocation = "Aiy ele-mayo." //This is said by cultists when the rune is invoked.
diff --git a/code/modules/antagonists/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm
index ce455d9e67..f2296d239f 100644
--- a/code/modules/antagonists/swarmer/swarmer.dm
+++ b/code/modules/antagonists/swarmer/swarmer.dm
@@ -274,7 +274,8 @@
/obj/machinery/camera/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S.DisIntegrate(src)
- toggle_cam(S, 0)
+ if(!QDELETED(S)) //If it got blown up no need to turn it off.
+ toggle_cam(S, 0)
return TRUE
/obj/machinery/particle_accelerator/control_box/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
diff --git a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
index 3cc3b48e50..e6ca95472e 100644
--- a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
+++ b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
@@ -22,11 +22,19 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
desc = "You aren't entirely sure what this does, but it's very beepy and boopy."
background_icon_state = "bg_tech_blue"
icon_icon = 'icons/mob/actions/actions_AI.dmi'
+ check_flags = AB_CHECK_CONSCIOUS //can't doomsday if dead.
var/mob/living/silicon/ai/owner_AI //The owner AI, so we don't have to typecast every time
var/uses //If we have multiple uses of the same power
var/auto_use_uses = TRUE //If we automatically use up uses on each activation
var/cooldown_period //If applicable, the time in deciseconds we have to wait before using any more modules
+
+/datum/action/innate/ai/New()
+ ..()
+ if(uses > 1)
+ desc = "[desc] It has [uses] use\s remaining."
+ button.desc = desc
+
/datum/action/innate/ai/Grant(mob/living/L)
. = ..()
if(!isAI(owner))
@@ -38,7 +46,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/IsAvailable()
. = ..()
if(owner_AI && owner_AI.malf_cooldown > world.time)
- return
+ return FALSE
/datum/action/innate/ai/Trigger()
. = ..()
@@ -49,12 +57,16 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/proc/adjust_uses(amt, silent)
uses += amt
- if(!silent && uses)
- to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.")
- if(!uses)
- if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway!
- to_chat(owner, "[name] has run out of uses!")
- qdel(src)
+ if(uses)
+ if(!silent)
+ to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.")
+ desc = "[initial(desc)] It has [uses] use\s remaining."
+ UpdateButtonIcon()
+ return
+ if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway!
+ to_chat(owner, "[name] has run out of uses!")
+ qdel(src)
+
//Framework for ranged abilities that can have different effects by left-clicking stuff.
/datum/action/innate/ai/ranged
@@ -74,13 +86,16 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/ranged/adjust_uses(amt, silent)
uses += amt
- if(!silent && uses)
- to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.")
- if(!uses)
- if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway!
- to_chat(owner, "[name] has run out of uses!")
- Remove(owner)
- QDEL_IN(src, 100) //let any active timers on us finish up
+ if(uses)
+ if(!silent)
+ to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.")
+ desc = "[initial(desc)] It has [uses] use\s remaining."
+ UpdateButtonIcon()
+ return
+ if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway!
+ to_chat(owner, "[name] has run out of uses!")
+ Remove(owner)
+ QDEL_IN(src, 100) //let any active timers on us finish up
/datum/action/innate/ai/ranged/Destroy()
QDEL_NULL(linked_ability)
@@ -97,7 +112,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
var/datum/action/innate/ai/ranged/attached_action
/obj/effect/proc_holder/ranged_ai/Destroy()
- QDEL_NULL(attached_action)
+ attached_action = null
return ..()
/obj/effect/proc_holder/ranged_ai/proc/toggle(mob/user)
@@ -185,6 +200,8 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
A.playsound_local(A, AM.unlock_sound, 50, 0)
else //Adding uses to an existing module
action.uses += initial(action.uses)
+ action.desc = "[initial(action.desc)] It has [action.uses] use\s remaining."
+ action.UpdateButtonIcon()
temp = "Additional use[action.uses > 1 ? "s" : ""] added to [action.name]!"
processing_time -= AM.cost
@@ -238,6 +255,8 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
return
if(alert(owner, "Send arming signal? (true = arm, false = cancel)", "purge_all_life()", "confirm = TRUE;", "confirm = FALSE;") != "confirm = TRUE;")
return
+ if (active)
+ return //prevent the AI from activating an already active doomsday
active = TRUE
set_us_up_the_bomb(owner)
@@ -245,64 +264,64 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
set waitfor = FALSE
to_chat(owner, "run -o -a 'selfdestruct'")
sleep(5)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Running executable 'selfdestruct'...")
sleep(rand(10, 30))
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
owner.playsound_local(owner, 'sound/misc/bloblarm.ogg', 50, 0)
to_chat(owner, "!!! UNAUTHORIZED SELF-DESTRUCT ACCESS !!!")
to_chat(owner, "This is a class-3 security violation. This incident will be reported to Central Command.")
for(var/i in 1 to 3)
sleep(20)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Sending security report to Central Command.....[rand(0, 9) + (rand(20, 30) * i)]%")
sleep(3)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "auth 'akjv9c88asdf12nb' ******************")
owner.playsound_local(owner, 'sound/items/timer.ogg', 50, 0)
sleep(30)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Credentials accepted. Welcome, akjv9c88asdf12nb.")
owner.playsound_local(owner, 'sound/misc/server-ready.ogg', 50, 0)
sleep(5)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Arm self-destruct device? (Y/N)")
owner.playsound_local(owner, 'sound/misc/compiler-stage1.ogg', 50, 0)
sleep(20)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Y")
sleep(15)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Confirm arming of self-destruct device? (Y/N)")
owner.playsound_local(owner, 'sound/misc/compiler-stage2.ogg', 50, 0)
sleep(10)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Y")
sleep(rand(15, 25))
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Please repeat password to confirm.")
owner.playsound_local(owner, 'sound/misc/compiler-stage2.ogg', 50, 0)
sleep(14)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "******************")
sleep(40)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Credentials accepted. Transmitting arming signal...")
owner.playsound_local(owner, 'sound/misc/server-ready.ogg', 50, 0)
sleep(30)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", "aimalf")
set_security_level("delta")
@@ -724,9 +743,10 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/blackout
name = "Blackout"
- desc = "Overloads lights across the station."
+ desc = "Overloads random lights across the station."
button_icon_state = "blackout"
uses = 3
+ auto_use_uses = FALSE
/datum/action/innate/ai/blackout/Activate()
for(var/obj/machinery/power/apc/apc in GLOB.apcs_list)
@@ -736,6 +756,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
apc.overload++
to_chat(owner, "Overcurrent applied to the powernet.")
owner.playsound_local(owner, "sparks", 50, 0)
+ adjust_uses(-1)
//Disable Emergency Lights
@@ -784,11 +805,6 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
auto_use_uses = FALSE
cooldown_period = 30
-/datum/action/innate/ai/reactivate_cameras/New()
- ..()
- desc = "[desc] There are 30 reactivations remaining."
- button.desc = desc
-
/datum/action/innate/ai/reactivate_cameras/Activate()
var/fixed_cameras = 0
for(var/V in GLOB.cameranet.cameras)
@@ -803,8 +819,6 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
to_chat(owner, "Diagnostic complete! Cameras reactivated: [fixed_cameras]. Reactivations remaining: [uses].")
owner.playsound_local(owner, 'sound/items/wirecutter.ogg', 50, 0)
adjust_uses(0, TRUE) //Checks the uses remaining
- if(src && uses) //Not sure if not having src here would cause a runtime, so it's here to be safe
- desc = "[initial(desc)] There are [uses] reactivations remaining."
//Upgrade Camera Network: EMP-proofs all cameras, in addition to giving them X-ray vision.
diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm
index bd4f1a8acd..70cb29e7a3 100644
--- a/code/modules/antagonists/wizard/equipment/spellbook.dm
+++ b/code/modules/antagonists/wizard/equipment/spellbook.dm
@@ -163,7 +163,7 @@
/datum/spellbook_entry/timestop
name = "Time Stop"
- spell_type = /obj/effect/proc_holder/spell/aoe_turf/conjure/timestop
+ spell_type = /obj/effect/proc_holder/spell/aoe_turf/timestop
category = "Defensive"
/datum/spellbook_entry/smoke
diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm
index c67b79478e..7c8952eb33 100644
--- a/code/modules/assembly/mousetrap.dm
+++ b/code/modules/assembly/mousetrap.dm
@@ -46,7 +46,7 @@
return FALSE
switch(type)
if("feet")
- if(!H.shoes)
+ if(!H.shoes || !(H.shoes.body_parts_covered & FEET))
affecting = H.get_bodypart(pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
H.Knockdown(60)
if(BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND)
diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm
index e49368016b..95063aadf6 100644
--- a/code/modules/atmospherics/machinery/airalarm.dm
+++ b/code/modules/atmospherics/machinery/airalarm.dm
@@ -207,7 +207,7 @@
pixel_y = (dir & 3)? (dir == 1 ? -24 : 24) : 0
if(name == initial(name))
- name = "[get_area_name(src)] Air Alarm"
+ name = "[get_area_name(src, get_base_area = TRUE)] Air Alarm"
power_change()
set_frequency(frequency)
@@ -250,7 +250,7 @@
"danger_level" = danger_level,
)
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
data["atmos_alarm"] = A.atmosalm
data["fire_alarm"] = A.fire
@@ -386,7 +386,7 @@
send_signal(device_id, list("checks" = text2num(params["val"])^2), usr)
. = TRUE
if("set_external_pressure", "set_internal_pressure")
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
var/target = input("New target pressure:", name, A.air_vent_info[device_id][(action == "set_external_pressure" ? "external" : "internal")]) as num|null
if(!isnull(target) && !..())
send_signal(device_id, list("[action]" = target), usr)
@@ -420,12 +420,12 @@
apply_mode()
. = TRUE
if("alarm")
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
if(A.atmosalert(2, src))
post_alert(2)
. = TRUE
if("reset")
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
if(A.atmosalert(0, src))
post_alert(0)
. = TRUE
@@ -456,7 +456,7 @@
return 0
/obj/machinery/airalarm/proc/refresh_all()
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
for(var/id_tag in A.air_vent_names)
var/list/I = A.air_vent_info[id_tag]
if(I && I["timestamp"] + AALARM_REPORT_TIMEOUT / 2 > world.time)
@@ -507,7 +507,7 @@
return "Flood"
/obj/machinery/airalarm/proc/apply_mode()
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
switch(mode)
if(AALARM_MODE_SCRUBBING)
for(var/device_id in A.air_scrub_names)
@@ -645,7 +645,7 @@
icon_state = "alarm1"
var/overlay_state = AALARM_OVERLAY_OFF
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
switch(max(danger_level, A.atmosalm))
if(0)
add_overlay(AALARM_OVERLAY_GREEN)
@@ -715,7 +715,7 @@
return
var/datum/signal/alert_signal = new(list(
- "zone" = get_area_name(src),
+ "zone" = get_area_name(src, get_base_area = TRUE),
"type" = "Atmospheric"
))
if(alert_level==2)
@@ -728,7 +728,7 @@
frequency.post_signal(src, alert_signal, range = -1)
/obj/machinery/airalarm/proc/apply_danger_level()
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
var/new_area_danger_level = 0
for(var/obj/machinery/airalarm/AA in A)
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/relief_valve.dm b/code/modules/atmospherics/machinery/components/binary_devices/relief_valve.dm
index 5835912cd3..bc58ef158f 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/relief_valve.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/relief_valve.dm
@@ -5,6 +5,7 @@
icon_state = "relief_valve-t-map"
can_unwrench = TRUE
construction_type = /obj/item/pipe/binary
+ interaction_flags_machine = INTERACT_MACHINE_OFFLINE | INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_SET_MACHINE
var/opened = FALSE
var/open_pressure = ONE_ATMOSPHERE * 3
var/close_pressure = ONE_ATMOSPHERE
@@ -50,9 +51,11 @@
if(!is_operational())
return
- var/datum/gas_mixture/air_contents = airs[1]
- var/our_pressure = air_contents.return_pressure()
- if(opened && our_pressure < close_pressure)
+ var/datum/gas_mixture/air_one = airs[1]
+ var/datum/gas_mixture/air_two = airs[2]
+ var/air_one_pressure = air_one.return_pressure()
+ var/our_pressure = abs(air_one_pressure - air_two.return_pressure())
+ if(opened && air_one_pressure < close_pressure)
close()
else if(!opened && our_pressure >= open_pressure)
open()
diff --git a/code/modules/atmospherics/machinery/components/components_base.dm b/code/modules/atmospherics/machinery/components/components_base.dm
index ff2a655aac..86e8863b2b 100644
--- a/code/modules/atmospherics/machinery/components/components_base.dm
+++ b/code/modules/atmospherics/machinery/components/components_base.dm
@@ -30,7 +30,7 @@
underlays.Cut()
var/turf/T = loc
- if(level == 2 || !T.intact)
+ if(level == 2 || (istype(T) && !T.intact))
showpipe = TRUE
plane = GAME_PLANE
else
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/relief_valve.dm b/code/modules/atmospherics/machinery/components/unary_devices/relief_valve.dm
index 9da9e49e01..4b6a4a4c10 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/relief_valve.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/relief_valve.dm
@@ -4,6 +4,7 @@
icon = 'icons/obj/atmospherics/components/relief_valve.dmi'
icon_state = "relief_valve-e-map"
can_unwrench = TRUE
+ interaction_flags_machine = INTERACT_MACHINE_OFFLINE | INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_SET_MACHINE
var/opened = FALSE
var/open_pressure = ONE_ATMOSPHERE * 3
var/close_pressure = ONE_ATMOSPHERE
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
index 3cbf1b4d0e..f2f2329661 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
@@ -38,7 +38,7 @@
id_tag = assign_uid_vents()
/obj/machinery/atmospherics/components/unary/vent_pump/Destroy()
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
if (A)
A.air_vent_names -= id_tag
A.air_vent_info -= id_tag
@@ -155,7 +155,7 @@
"sigtype" = "status"
))
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
if(!A.air_vent_names[id_tag])
name = "\improper [A.name] vent pump #[A.air_vent_names.len + 1]"
A.air_vent_names[id_tag] = name
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
index 22cd9d7fca..10eac9c717 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
@@ -39,7 +39,7 @@
filter_types += gas_id2path(f)
/obj/machinery/atmospherics/components/unary/vent_scrubber/Destroy()
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
if (A)
A.air_scrub_names -= id_tag
A.air_scrub_info -= id_tag
@@ -112,7 +112,7 @@
"sigtype" = "status"
))
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
if(!A.air_scrub_names[id_tag])
name = "\improper [A.name] air scrubber #[A.air_scrub_names.len + 1]"
A.air_scrub_names[id_tag] = name
diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm
index e8704b4c40..e0cf903465 100644
--- a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm
+++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm
@@ -1,6 +1,6 @@
//3-Way Manifold
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold
- icon_state = "manifold"
+ icon_state = "manifold-2"
name = "pipe manifold"
desc = "A manifold composed of regular pipes."
diff --git a/code/modules/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm
index bd4e716357..8ceef76a06 100644
--- a/code/modules/awaymissions/capture_the_flag.dm
+++ b/code/modules/awaymissions/capture_the_flag.dm
@@ -7,8 +7,6 @@
#define AMMO_DROP_LIFETIME 300
#define CTF_REQUIRED_PLAYERS 4
-
-
/obj/item/twohanded/ctf
name = "banner"
icon = 'icons/obj/items_and_weapons.dmi'
@@ -210,7 +208,6 @@
toggle_all_ctf(user)
return
-
people_who_want_to_play |= user.ckey
var/num = people_who_want_to_play.len
var/remaining = CTF_REQUIRED_PLAYERS - num
@@ -438,9 +435,9 @@
. = FALSE
if(istype(target, /obj/structure/barricade/security/ctf))
. = TRUE
- if(ishuman(target))
- var/mob/living/carbon/human/H = target
- if(istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit/shielded/ctf))
+ if(isliving(target))
+ var/mob/living/H = target
+ if((RED_TEAM in H.faction) || (BLUE_TEAM in H.faction))
. = TRUE
// RED TEAM GUNS
diff --git a/code/modules/cargo/bounties/silly.dm b/code/modules/cargo/bounties/silly.dm
index f790126cf2..e0d2c87a2d 100644
--- a/code/modules/cargo/bounties/silly.dm
+++ b/code/modules/cargo/bounties/silly.dm
@@ -64,4 +64,3 @@
description = "Nanotrasen has secured a contract in a reenactment of a famous movie, but we only have lethal energy based swords. Send us some convincing replicas so we save on medical costs."
reward = 1200
required_count = 3
- wanted_types = list(/obj/item/toy/sword, /obj/item/toy/sword/cx)
\ No newline at end of file
diff --git a/code/modules/cargo/exports/parts.dm b/code/modules/cargo/exports/parts.dm
index e53db0bf7b..e4efaf0810 100644
--- a/code/modules/cargo/exports/parts.dm
+++ b/code/modules/cargo/exports/parts.dm
@@ -92,11 +92,42 @@
export_types = list(/obj/item/stock_parts/cell/bluespace)
/datum/export/cellyellow
- cost = 40
+ cost = 200
unit_name = "slime power cell"
export_types = list(/obj/item/stock_parts/cell/high/slime)
/datum/export/cellyellowhyper
- cost = 120 //Takes a lot to make and is really good
+ cost = 1200 //Takes a lot to make and is really good
unit_name = "hyper slime power cell"
- export_types = list(/obj/item/stock_parts/cell/high/slime/hypercharged)
\ No newline at end of file
+ export_types = list(/obj/item/stock_parts/cell/high/slime/hypercharged)
+
+//Glass working stuff
+
+/datum/export/glasswork_dish
+ cost = 300
+ unit_name = "small glass dish"
+ export_types = list(/obj/item/reagent_containers/glass/beaker/glass_dish)
+ include_subtypes = FALSE
+
+/datum/export/glasswork_lens
+ cost = 1800
+ unit_name = "small glass lens"
+ export_types = list(/obj/item/lens)
+
+/datum/export/glasswork_spouty
+ cost = 1200
+ unit_name = "flask with spout"
+ export_types = list(/obj/item/reagent_containers/glass/beaker/flask/spouty)
+ include_subtypes = FALSE
+
+/datum/export/glasswork_smallflask
+ cost = 600
+ unit_name = "small flask"
+ export_types = list(/obj/item/reagent_containers/glass/beaker/flask)
+ include_subtypes = FALSE
+
+/datum/export/glasswork_largeflask
+ cost = 1000
+ unit_name = "large flask"
+ export_types = list(/obj/item/reagent_containers/glass/beaker/flask/large)
+ include_subtypes = FALSE
diff --git a/code/modules/cargo/packs/armory.dm b/code/modules/cargo/packs/armory.dm
index 259ea2d7e3..ea8ef8ba0f 100644
--- a/code/modules/cargo/packs/armory.dm
+++ b/code/modules/cargo/packs/armory.dm
@@ -226,7 +226,7 @@
crate_name = "swat taser crate"
/datum/supply_pack/security/armory/woodstock
- name = "Classic WoodStock Shotguns Crate"
+ name = "WoodStock Classic Shotguns Crate"
desc = "Contains three rustic, pumpaction shotguns. Requires Armory access to open."
cost = 3000
contains = list(/obj/item/gun/ballistic/shotgun,
diff --git a/code/modules/cargo/packs/costumes_toys.dm b/code/modules/cargo/packs/costumes_toys.dm
index 40d21e4505..4a64979502 100644
--- a/code/modules/cargo/packs/costumes_toys.dm
+++ b/code/modules/cargo/packs/costumes_toys.dm
@@ -3,12 +3,18 @@
// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
// cost = 700- Minimum cost, or infinite points are possible.
//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Costumes & Toys /////////////////////////////////
+////////////////////////////////// Toys //////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/datum/supply_pack/costumes_toys
group = "Costumes & Toys"
+/datum/supply_pack/costumes_toys/randomised/fill(obj/structure/closet/crate/C)
+ var/list/L = contains.Copy()
+ for(var/i in 1 to num_contained)
+ var/item = pick_n_take(L)
+ new item(C)
+
/datum/supply_pack/costumes_toys/randomised
name = "Collectable Hats Crate"
desc = "Flaunt your status with three unique, highly-collectable hats!"
@@ -92,40 +98,6 @@
/obj/item/ammo_box/magazine/toy/pistol)
crate_name = "foam force crate"
-/datum/supply_pack/costumes_toys/formalwear
- name = "Formalwear Crate"
- desc = "You're gonna like the way you look, I guaranteed it. Contains an asston of fancy clothing."
- cost = 4750 //Lots of fancy clothing that can be sold back!
- contains = list(/obj/item/clothing/under/blacktango,
- /obj/item/clothing/under/assistantformal,
- /obj/item/clothing/under/assistantformal,
- /obj/item/clothing/under/lawyer/bluesuit,
- /obj/item/clothing/suit/toggle/lawyer,
- /obj/item/clothing/under/lawyer/purpsuit,
- /obj/item/clothing/suit/toggle/lawyer/purple,
- /obj/item/clothing/under/lawyer/blacksuit,
- /obj/item/clothing/suit/toggle/lawyer/black,
- /obj/item/clothing/accessory/waistcoat,
- /obj/item/clothing/neck/tie/blue,
- /obj/item/clothing/neck/tie/red,
- /obj/item/clothing/neck/tie/black,
- /obj/item/clothing/head/bowler,
- /obj/item/clothing/head/fedora,
- /obj/item/clothing/head/flatcap,
- /obj/item/clothing/head/beret,
- /obj/item/clothing/head/that,
- /obj/item/clothing/shoes/laceup,
- /obj/item/clothing/shoes/laceup,
- /obj/item/clothing/shoes/laceup,
- /obj/item/clothing/under/suit_jacket/charcoal,
- /obj/item/clothing/under/suit_jacket/navy,
- /obj/item/clothing/under/suit_jacket/burgundy,
- /obj/item/clothing/under/suit_jacket/checkered,
- /obj/item/clothing/under/suit_jacket/tan,
- /obj/item/lipstick/random)
- crate_name = "formalwear crate"
- crate_type = /obj/structure/closet/crate/wooden
-
/datum/supply_pack/costumes_toys/clownpin
name = "Hilarious Firing Pin Crate"
desc = "I uh... I'm not really sure what this does. Wanna buy it?"
@@ -167,47 +139,6 @@
contains = list(/obj/item/storage/box/lasertagpins)
crate_name = "laser tag crate"
-/datum/supply_pack/costumes_toys/costume_original
- name = "Original Costume Crate"
- desc = "Reenact Shakespearean plays with this assortment of outfits. Contains eight different costumes!"
- cost = 1750
- contains = list(/obj/item/clothing/head/snowman,
- /obj/item/clothing/suit/snowman,
- /obj/item/clothing/head/chicken,
- /obj/item/clothing/suit/chickensuit,
- /obj/item/clothing/mask/gas/monkeymask,
- /obj/item/clothing/suit/monkeysuit,
- /obj/item/clothing/head/cardborg,
- /obj/item/clothing/suit/cardborg,
- /obj/item/clothing/head/xenos,
- /obj/item/clothing/suit/xenos,
- /obj/item/clothing/suit/hooded/ian_costume,
- /obj/item/clothing/suit/hooded/carp_costume,
- /obj/item/clothing/suit/hooded/bee_costume)
- crate_name = "original costume crate"
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/costume
- name = "Standard Costume Crate"
- desc = "Supply the station's entertainers with the equipment of their trade with these Nanotrasen-approved costumes! Contains a full clown and mime outfit, along with a bike horn and a bottle of nothing."
- cost = 1300
- access = ACCESS_THEATRE
- contains = list(/obj/item/storage/backpack/clown,
- /obj/item/clothing/shoes/clown_shoes,
- /obj/item/clothing/mask/gas/clown_hat,
- /obj/item/clothing/under/rank/clown,
- /obj/item/bikehorn,
- /obj/item/clothing/under/rank/mime,
- /obj/item/clothing/shoes/sneakers/black,
- /obj/item/clothing/gloves/color/white,
- /obj/item/clothing/mask/gas/mime,
- /obj/item/clothing/head/beret,
- /obj/item/clothing/suit/suspenders,
- /obj/item/reagent_containers/food/drinks/bottle/bottleofnothing,
- /obj/item/storage/backpack/mime)
- crate_name = "standard costume crate"
- crate_type = /obj/structure/closet/crate/wooden
-
/datum/supply_pack/costumes_toys/randomised/toys
name = "Toy Crate"
desc = "Who cares about pride and accomplishment? Skip the gaming and get straight to the sweet rewards with this product! Contains five random toys. Warranty void if used to prank research directors."
@@ -278,6 +209,86 @@
crate_name = "plushie crate"
crate_type = /obj/structure/closet/crate/wooden
+
+//////////////////////////////////////////////////////////////////////////////
+///////////////////////////////// Costumes //////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/costumes_toys/formalwear
+ name = "Formalwear Crate"
+ desc = "You're gonna like the way you look, I guaranteed it. Contains an asston of fancy clothing."
+ cost = 4750 //Lots of fancy clothing that can be sold back!
+ contains = list(/obj/item/clothing/under/blacktango,
+ /obj/item/clothing/under/assistantformal,
+ /obj/item/clothing/under/assistantformal,
+ /obj/item/clothing/under/lawyer/bluesuit,
+ /obj/item/clothing/suit/toggle/lawyer,
+ /obj/item/clothing/under/lawyer/purpsuit,
+ /obj/item/clothing/suit/toggle/lawyer/purple,
+ /obj/item/clothing/under/lawyer/blacksuit,
+ /obj/item/clothing/suit/toggle/lawyer/black,
+ /obj/item/clothing/accessory/waistcoat,
+ /obj/item/clothing/neck/tie/blue,
+ /obj/item/clothing/neck/tie/red,
+ /obj/item/clothing/neck/tie/black,
+ /obj/item/clothing/head/bowler,
+ /obj/item/clothing/head/fedora,
+ /obj/item/clothing/head/flatcap,
+ /obj/item/clothing/head/beret,
+ /obj/item/clothing/head/that,
+ /obj/item/clothing/shoes/laceup,
+ /obj/item/clothing/shoes/laceup,
+ /obj/item/clothing/shoes/laceup,
+ /obj/item/clothing/under/suit_jacket/charcoal,
+ /obj/item/clothing/under/suit_jacket/navy,
+ /obj/item/clothing/under/suit_jacket/burgundy,
+ /obj/item/clothing/under/suit_jacket/checkered,
+ /obj/item/clothing/under/suit_jacket/tan,
+ /obj/item/lipstick/random)
+ crate_name = "formalwear crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/costume_original
+ name = "Original Costume Crate"
+ desc = "Reenact Shakespearean plays with this assortment of outfits. Contains eight different costumes!"
+ cost = 1750
+ contains = list(/obj/item/clothing/head/snowman,
+ /obj/item/clothing/suit/snowman,
+ /obj/item/clothing/head/chicken,
+ /obj/item/clothing/suit/chickensuit,
+ /obj/item/clothing/mask/gas/monkeymask,
+ /obj/item/clothing/suit/monkeysuit,
+ /obj/item/clothing/head/cardborg,
+ /obj/item/clothing/suit/cardborg,
+ /obj/item/clothing/head/xenos,
+ /obj/item/clothing/suit/xenos,
+ /obj/item/clothing/suit/hooded/ian_costume,
+ /obj/item/clothing/suit/hooded/carp_costume,
+ /obj/item/clothing/suit/hooded/bee_costume)
+ crate_name = "original costume crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/costume
+ name = "Standard Costume Crate"
+ desc = "Supply the station's entertainers with the equipment of their trade with these Nanotrasen-approved costumes! Contains a full clown and mime outfit, along with a bike horn and a bottle of nothing."
+ cost = 1300
+ access = ACCESS_THEATRE
+ contains = list(/obj/item/storage/backpack/clown,
+ /obj/item/clothing/shoes/clown_shoes,
+ /obj/item/clothing/mask/gas/clown_hat,
+ /obj/item/clothing/under/rank/clown,
+ /obj/item/bikehorn,
+ /obj/item/clothing/under/rank/mime,
+ /obj/item/clothing/shoes/sneakers/black,
+ /obj/item/clothing/gloves/color/white,
+ /obj/item/clothing/mask/gas/mime,
+ /obj/item/clothing/head/beret,
+ /obj/item/clothing/suit/suspenders,
+ /obj/item/reagent_containers/food/drinks/bottle/bottleofnothing,
+ /obj/item/storage/backpack/mime)
+ crate_name = "standard costume crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
/datum/supply_pack/costumes_toys/wizard
name = "Wizard Costume Crate"
desc = "Pretend to join the Wizard Federation with this full wizard outfit! Nanotrasen would like to remind its employees that actually joining the Wizard Federation is subject to termination of job and life."
@@ -288,82 +299,3 @@
/obj/item/clothing/head/wizard/fake)
crate_name = "wizard costume crate"
crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/randomised/fill(obj/structure/closet/crate/C)
- var/list/L = contains.Copy()
- for(var/i in 1 to num_contained)
- var/item = pick_n_take(L)
- new item(C)
-
-/datum/supply_pack/costumes_toys/wardrobes/autodrobe
- name = "Autodrobe Supply Crate"
- desc = "Autodrobe missing your favorite dress? Solve that issue today with this autodrobe refill."
- cost = 1500
- contains = list(/obj/item/vending_refill/autodrobe)
- crate_name = "autodrobe supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/cargo
- name = "Cargo Wardrobe Supply Crate"
- desc = "This crate contains a refill for the CargoDrobe."
- cost = 750
- contains = list(/obj/item/vending_refill/wardrobe/cargo_wardrobe)
- crate_name = "cargo department supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/engineering
- name = "Engineering Wardrobe Supply Crate"
- desc = "This crate contains refills for the EngiDrobe and AtmosDrobe."
- cost = 1500
- contains = list(/obj/item/vending_refill/wardrobe/engi_wardrobe,
- /obj/item/vending_refill/wardrobe/atmos_wardrobe)
- crate_name = "engineering department wardrobe supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/general
- name = "General Wardrobes Supply Crate"
- desc = "This crate contains refills for the CuraDrobe, BarDrobe, ChefDrobe, JaniDrobe, ChapDrobe."
- cost = 3750
- contains = list(/obj/item/vending_refill/wardrobe/curator_wardrobe,
- /obj/item/vending_refill/wardrobe/bar_wardrobe,
- /obj/item/vending_refill/wardrobe/chef_wardrobe,
- /obj/item/vending_refill/wardrobe/jani_wardrobe,
- /obj/item/vending_refill/wardrobe/chap_wardrobe)
- crate_name = "general wardrobes vendor refills"
-
-/datum/supply_pack/costumes_toys/wardrobes/hydroponics
- name = "Hydrobe Supply Crate"
- desc = "This crate contains a refill for the Hydrobe."
- cost = 750
- contains = list(/obj/item/vending_refill/wardrobe/hydro_wardrobe)
- crate_name = "hydrobe supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/medical
- name = "Medical Wardrobe Supply Crate"
- desc = "This crate contains refills for the MediDrobe, ChemDrobe, GeneDrobe, and ViroDrobe."
- cost = 3000
- contains = list(/obj/item/vending_refill/wardrobe/medi_wardrobe,
- /obj/item/vending_refill/wardrobe/chem_wardrobe,
- /obj/item/vending_refill/wardrobe/gene_wardrobe,
- /obj/item/vending_refill/wardrobe/viro_wardrobe)
- crate_name = "medical department wardrobe supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/science
- name = "Science Wardrobe Supply Crate"
- desc = "This crate contains refills for the SciDrobe and RoboDrobe."
- cost = 1500
- contains = list(/obj/item/vending_refill/wardrobe/robo_wardrobe,
- /obj/item/vending_refill/wardrobe/science_wardrobe)
- crate_name = "science department wardrobe supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/security
- name = "Security Wardrobe Supply Crate"
- desc = "This crate contains refills for the SecDrobe and LawDrobe."
- cost = 1500
- contains = list(/obj/item/vending_refill/wardrobe/sec_wardrobe,
- /obj/item/vending_refill/wardrobe/law_wardrobe)
- crate_name = "security department supply crate"
-
-/datum/supply_pack/costumes_toys/kinkmate
- name = "Kinkmate construction kit"
- cost = 2000
- contraband = TRUE
- contains = list(/obj/item/vending_refill/kink, /obj/item/circuitboard/machine/kinkmate)
- crate_name = "Kinkmate construction kit"
diff --git a/code/modules/cargo/packs/emergency.dm b/code/modules/cargo/packs/emergency.dm
index 747e820f52..e32811f2d0 100644
--- a/code/modules/cargo/packs/emergency.dm
+++ b/code/modules/cargo/packs/emergency.dm
@@ -11,11 +11,13 @@
/datum/supply_pack/emergency/vehicle
name = "Biker Gang Kit" //TUNNEL SNAKES OWN THIS TOWN
- desc = "TUNNEL SNAKES OWN THIS TOWN. Contains an unbranded All Terrain Vehicle, and a complete gang outfit -- consists of black gloves, a menacing skull bandanna, and a SWEET leather overcoat!"
+ desc = "TUNNEL SNAKES OWN THIS TOWN. Contains an unbranded All Terrain Vehicle, two cans of spraypaint, and a complete gang outfit -- consists of black gloves, a menacing skull bandanna, and a SWEET leather overcoat!"
cost = 2500
contraband = TRUE
contains = list(/obj/vehicle/ridden/atv,
/obj/item/key,
+ /obj/item/toy/crayon/spraycan,
+ /obj/item/toy/crayon/spraycan,
/obj/item/clothing/suit/jacket/leather/overcoat,
/obj/item/clothing/gloves/color/black,
/obj/item/clothing/head/soft,
@@ -126,21 +128,6 @@
crate_name = "emergency rcds"
crate_type = /obj/structure/closet/crate/internals
-/datum/supply_pack/emergency/soft_suit
- name = "Emergency Space Suit"
- desc = "Are there bombs going off left and right? Are there meteors shooting around the station? Well then! Here's two fragile space suits for emergencies. Comes with air and masks."
- cost = 1200
- contains = list(/obj/item/tank/internals/air,
- /obj/item/tank/internals/air,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/suit/space/fragile,
- /obj/item/clothing/suit/space/fragile,
- /obj/item/clothing/head/helmet/space/fragile,
- /obj/item/clothing/head/helmet/space/fragile)
- crate_name = "emergency crate"
- crate_type = /obj/structure/closet/crate/internals
-
/datum/supply_pack/emergency/bomb
name = "Explosive Emergency Crate"
desc = "Science gone bonkers? Beeping behind the airlock? Buy now and be the hero the station des... I mean needs! (Time not included.)"
@@ -208,7 +195,7 @@
crate_name = "metal foam grenade crate"
/datum/supply_pack/emergency/mre
- name = "MRE supply kit (emergency rations)"
+ name = "MRE Packs (Emergency Rations)"
desc = "The lights are out. Oxygen's running low. You've run out of food except space weevils. Don't let this be you! Order our NT branded MRE kits today! This pack contains 5 MRE packs with a randomized menu and an oxygen tank."
cost = 2000
contains = list(/obj/item/storage/box/mre/menu1/safe,
@@ -296,6 +283,21 @@
crate_name = "space suit crate"
crate_type = /obj/structure/closet/crate/secure
+/datum/supply_pack/emergency/soft_suit
+ name = "Space Suits (Fragile)"
+ desc = "Are there bombs going off left and right? Are there meteors shooting around the station? Well then! Here's two fragile space suits for emergencies. Comes with air and masks."
+ cost = 1200
+ contains = list(/obj/item/tank/internals/air,
+ /obj/item/tank/internals/air,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/suit/space/fragile,
+ /obj/item/clothing/suit/space/fragile,
+ /obj/item/clothing/head/helmet/space/fragile,
+ /obj/item/clothing/head/helmet/space/fragile)
+ crate_name = "emergency crate"
+ crate_type = /obj/structure/closet/crate/internals
+
/datum/supply_pack/emergency/spacejets
name = "Spare EVA Jetpacks"
desc = "Contains three EVA grade jectpaks. Requires EVA access to open."
diff --git a/code/modules/cargo/packs/engineering.dm b/code/modules/cargo/packs/engineering.dm
index 6492df5215..22258d19a7 100644
--- a/code/modules/cargo/packs/engineering.dm
+++ b/code/modules/cargo/packs/engineering.dm
@@ -3,7 +3,7 @@
// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
// cost = 700- Minimum cost, or infinite points are possible.
//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Engineering /////////////////////////////////////
+///////////////////////////// Engineering ////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/datum/supply_pack/engineering
@@ -45,6 +45,7 @@
/obj/item/clothing/glasses/meson/engine,
/obj/item/clothing/glasses/meson/engine)
crate_name = "engineering gear crate"
+ crate_type = /obj/structure/closet/crate/secure/engineering
/datum/supply_pack/engineering/engihardsuit
name = "Engineering Hardsuit"
@@ -55,6 +56,7 @@
/obj/item/clothing/mask/gas,
/obj/item/clothing/suit/space/hardsuit/engine)
crate_name = "engineering hardsuit"
+ crate_type = /obj/structure/closet/crate/secure/engineering
/datum/supply_pack/engineering/atmoshardsuit
name = "Atmospherics Hardsuit"
@@ -114,6 +116,22 @@
crate_name = "PACMAN generator crate"
crate_type = /obj/structure/closet/crate/engineering/electrical
+/datum/supply_pack/engineering/airpump
+ name = "Portable Air Pump Crate"
+ desc = "We all know you work in a high pressure workplace. Keep it that way with two additional air pumps!"
+ cost = 3000
+ contains = list(/obj/machinery/portable_atmospherics/pump,
+ /obj/machinery/portable_atmospherics/pump)
+ crate_name = "portable air pump crate"
+
+/datum/supply_pack/engineering/airscrubber
+ name = "Portable Scrubber Crate"
+ desc = "Miasma got you down? Plasma in the vents? Freshen up with these two brand-new air scrubbers!"
+ cost = 3000
+ contains = list(/obj/machinery/portable_atmospherics/scrubber,
+ /obj/machinery/portable_atmospherics/scrubber)
+ crate_name = "portable scrubber crate"
+
/datum/supply_pack/engineering/power
name = "Power Cell Crate"
desc = "Looking for power overwhelming? Look no further. Contains three high-voltage power cells."
diff --git a/code/modules/cargo/packs/materials.dm b/code/modules/cargo/packs/materials.dm
index c9862282dc..6c1742896f 100644
--- a/code/modules/cargo/packs/materials.dm
+++ b/code/modules/cargo/packs/materials.dm
@@ -69,6 +69,11 @@
contains = list(/obj/item/grown/log)
crate_name = "lumber crate"
+/datum/supply_pack/materials/rawlumber/generate()
+ . = ..()
+ for(var/i in 1 to 49)
+ new /obj/item/grown/log(.)
+
/datum/supply_pack/materials/wood50
name = "50 Wood Planks"
desc = "Turn cargo's boring metal groundwork into beautiful panelled flooring and much more with fifty wooden planks!"
@@ -89,7 +94,7 @@
/datum/supply_pack/materials/rawcottonbulk
name = "Raw Cotton Crate (Bulk)"
desc = "We have so much of this stuff we need to get rid of it in -bulk- now. This crate contains 240 raw cotton sheets."
- cost = 1300 // 100 net cost (per 40 cotton) , 20 x 20 = 400. 300 profit if turned into cloth sheets or more if turned to silk then 10 x 200 = 2000
+ cost = 1300 // 600 net cost 20 x 120 = 2400 profit if turned into cloth sheets or if turned into silk 200 x 60 = 12000
contains = list(/obj/item/stack/sheet/cotton/thirty,
/obj/item/stack/sheet/cotton/thirty,
/obj/item/stack/sheet/cotton/thirty,
@@ -102,13 +107,8 @@
crate_name = "bulk cotton crate"
crate_type = /obj/structure/closet/crate/hydroponics
-/datum/supply_pack/critter/animal_feed/generate()
- . = ..()
- for(var/i in 1 to 49)
- new /obj/item/grown/log(.)
-
/datum/supply_pack/materials/rcdammo
- name = "Spare RDC ammo"
+ name = "Spare RCD ammo"
desc = "This crate contains sixteen RCD compressed matter packs, to help with any holes or projects people might be working on."
cost = 3750
contains = list(/obj/item/rcd_ammo,
diff --git a/code/modules/cargo/packs/medical.dm b/code/modules/cargo/packs/medical.dm
index a60afe4f7a..ea327ae820 100644
--- a/code/modules/cargo/packs/medical.dm
+++ b/code/modules/cargo/packs/medical.dm
@@ -10,6 +10,10 @@
group = "Medical"
crate_type = /obj/structure/closet/crate/medical
+//////////////////////////////////////////////////////////////////////////////
+/////////////////////////////// Equipment ////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
/datum/supply_pack/medical/bodybags
name = "Bodybags"
desc = "For when the bodies hit the floor. Contains 4 boxes of bodybags."
@@ -20,24 +24,6 @@
/obj/item/storage/box/bodybags,)
crate_name = "bodybag crate"
-/datum/supply_pack/medical/firstaidbruises
- name = "Bruise Treatment Kit Crate"
- desc = "Contains three first aid kits focused on healing bruises and broken bones."
- cost = 1000
- contains = list(/obj/item/storage/firstaid/brute,
- /obj/item/storage/firstaid/brute,
- /obj/item/storage/firstaid/brute)
- crate_name = "brute treatment kit crate"
-
-/datum/supply_pack/medical/firstaidburns
- name = "Burn Treatment Kit Crate"
- desc = "Contains three first aid kits focused on healing severe burns."
- cost = 1000
- contains = list(/obj/item/storage/firstaid/fire,
- /obj/item/storage/firstaid/fire,
- /obj/item/storage/firstaid/fire)
- crate_name = "burn treatment kit crate"
-
/datum/supply_pack/medical/bloodpacks
name = "Blood Pack Variety Crate"
desc = "Contains nine different blood packs for reintroducing blood to patients, plus two universal synthetic blood packs."
@@ -86,16 +72,6 @@
/obj/item/defibrillator/loaded)
crate_name = "defibrillator crate"
-/datum/supply_pack/medical/firstaid
- name = "First Aid Kit Crate"
- desc = "Contains four first aid kits for healing most types of wounds."
- cost = 1000
- contains = list(/obj/item/storage/firstaid/regular,
- /obj/item/storage/firstaid/regular,
- /obj/item/storage/firstaid/regular,
- /obj/item/storage/firstaid/regular)
- crate_name = "first aid kit crate"
-
/datum/supply_pack/medical/iv_drip
name = "IV Drip Crate"
desc = "Contains a single IV drip stand for intravenous delivery."
@@ -103,17 +79,6 @@
contains = list(/obj/machinery/iv_drip)
crate_name = "iv drip crate"
-/datum/supply_pack/science/adv_surgery_tools
- name = "Med-Co Advanced surgery tools"
- desc = "A full set of Med-Co advanced surgery tools! In addition to that it contains both a can of synthflesh and a can of sterilizine. Requires Surgery access to open."
- cost = 5500
- access = ACCESS_SURGERY
- contains = list(/obj/item/storage/belt/medical/surgery_belt_adv,
- /obj/item/reagent_containers/medspray/synthflesh,
- /obj/item/reagent_containers/medspray/sterilizine)
- crate_name = "medco newest surgery tools"
- crate_type = /obj/structure/closet/crate/medical
-
/datum/supply_pack/medical/medicalhardsuit
name = "Medical Hardsuit"
desc = "Got people being spaced left and right? Hole in the same room as the dead body of Hos or cap? Fear not, now you can buy one medical hardsuit with a mask and air tank to save your fellow crewmembers. Requires medical access to open."
@@ -151,13 +116,57 @@
/obj/item/storage/pill_bottle/stimulant)
crate_name = "medical supplies crate"
-/datum/supply_pack/medical/vending
- name = "Medical Vending Crate"
- desc = "Contains refills for medical vending machines."
- cost = 2000
- contains = list(/obj/item/vending_refill/medical,
- /obj/item/vending_refill/wallmed)
- crate_name = "medical vending crate"
+/datum/supply_pack/medical/adv_surgery_tools
+ name = "Med-Co Advanced Surgery Tools"
+ desc = "A full set of Med-Co advanced surgery tools, this crate also comes with a spay of synth flesh as well as a can of . Requires Surgery access to open."
+ cost = 5500
+ access = ACCESS_SURGERY
+ contains = list(/obj/item/storage/belt/medical/surgery_belt_adv,
+ /obj/item/reagent_containers/medspray/synthflesh,
+ /obj/item/reagent_containers/medspray/sterilizine)
+ crate_name = "medco surgery tools"
+ crate_type = /obj/structure/closet/crate/medical
+
+/datum/supply_pack/medical/surgery
+ name = "Surgical Supplies Crate"
+ desc = "Do you want to perform surgery, but don't have one of those fancy shmancy degrees? Just get started with this crate containing a medical duffelbag, Sterilizine spray and collapsible roller bed."
+ cost = 1300
+ contains = list(/obj/item/storage/backpack/duffelbag/med/surgery,
+ /obj/item/reagent_containers/medspray/sterilizine,
+ /obj/item/roller)
+ crate_name = "surgical supplies crate"
+
+//////////////////////////////////////////////////////////////////////////////
+///////////////////////////// Medical Kits ///////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/medical/firstaidbruises
+ name = "Bruise Treatment Kit Crate"
+ desc = "Contains three first aid kits focused on healing bruises and broken bones."
+ cost = 1000
+ contains = list(/obj/item/storage/firstaid/brute,
+ /obj/item/storage/firstaid/brute,
+ /obj/item/storage/firstaid/brute)
+ crate_name = "brute treatment kit crate"
+
+/datum/supply_pack/medical/firstaidburns
+ name = "Burn Treatment Kit Crate"
+ desc = "Contains three first aid kits focused on healing severe burns."
+ cost = 1000
+ contains = list(/obj/item/storage/firstaid/fire,
+ /obj/item/storage/firstaid/fire,
+ /obj/item/storage/firstaid/fire)
+ crate_name = "burn treatment kit crate"
+
+/datum/supply_pack/medical/firstaid
+ name = "First Aid Kit Crate"
+ desc = "Contains four first aid kits for healing most types of wounds."
+ cost = 1000
+ contains = list(/obj/item/storage/firstaid/regular,
+ /obj/item/storage/firstaid/regular,
+ /obj/item/storage/firstaid/regular,
+ /obj/item/storage/firstaid/regular)
+ crate_name = "first aid kit crate"
/datum/supply_pack/medical/sprays
name = "Medical Sprays"
@@ -193,6 +202,15 @@
/obj/item/storage/firstaid/o2)
crate_name = "oxygen deprivation kit crate"
+/datum/supply_pack/medical/firstaidtoxins
+ name = "Toxin Treatment Kit Crate"
+ desc = "Contains three first aid kits focused on healing damage dealt by heavy toxins."
+ cost = 1000
+ contains = list(/obj/item/storage/firstaid/toxin,
+ /obj/item/storage/firstaid/toxin,
+ /obj/item/storage/firstaid/toxin)
+ crate_name = "toxin treatment kit crate"
+
/datum/supply_pack/medical/advrad
name = "Radiation Treatment Crate Deluxe"
desc = "A crate for when radiation is out of hand... Contains two rad-b-gone kits, one bottle of anti radiation deluxe pills, as well as a radiation treatment deluxe pill bottle!"
@@ -206,23 +224,9 @@
crate_name = "radiation protection crate"
crate_type = /obj/structure/closet/crate/radiation
-/datum/supply_pack/medical/surgery
- name = "Surgical Supplies Crate"
- desc = "Do you want to perform surgery, but don't have one of those fancy shmancy degrees? Just get started with this crate containing a medical duffelbag, Sterilizine spray and collapsible roller bed."
- cost = 1300
- contains = list(/obj/item/storage/backpack/duffelbag/med/surgery,
- /obj/item/reagent_containers/medspray/sterilizine,
- /obj/item/roller)
- crate_name = "surgical supplies crate"
-
-/datum/supply_pack/medical/firstaidtoxins
- name = "Toxin Treatment Kit Crate"
- desc = "Contains three first aid kits focused on healing damage dealt by heavy toxins."
- cost = 1000
- contains = list(/obj/item/storage/firstaid/toxin,
- /obj/item/storage/firstaid/toxin,
- /obj/item/storage/firstaid/toxin)
- crate_name = "toxin treatment kit crate"
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////// Virology ////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
/datum/supply_pack/medical/virus
name = "Virus Crate"
@@ -266,4 +270,4 @@
/obj/item/storage/box/syringes,
/obj/item/storage/box/beakers)
crate_name = "virus containment unit crate"
- crate_type = /obj/structure/closet/crate/secure/plasma
+ crate_type = /obj/structure/closet/crate/secure/plasma
\ No newline at end of file
diff --git a/code/modules/cargo/packs/misc.dm b/code/modules/cargo/packs/misc.dm
index f8656ef761..b53b7761e5 100644
--- a/code/modules/cargo/packs/misc.dm
+++ b/code/modules/cargo/packs/misc.dm
@@ -13,16 +13,6 @@
//////////////////// Paperwork and Writing Supplies //////////////////////////
//////////////////////////////////////////////////////////////////////////////
-/datum/supply_pack/misc/abandonedcrate
- name = "Loot Box"
- desc = "Try your luck with these highly secure loot boxes! Solve the lock, win great prizes! WARNING: EXPLOSIVE FAILURE."
- contraband = TRUE
- cost = 15000
- contains = list(/obj/structure/closet/crate/secure/loot)
- crate_name = "abandoned crate"
- crate_type = /obj/structure/closet/crate/large
- dangerous = TRUE
-
/datum/supply_pack/misc/artsupply
name = "Art Supplies"
desc = "Make some happy little accidents with six canvasses, two easels, two boxes of crayons, and a rainbow crayon!"
@@ -83,7 +73,7 @@
name = "Captain Pen"
desc = "A spare Captain fountain pen."
access = ACCESS_CAPTAIN
- cost = 10000
+ cost = 5000
contains = list(/obj/item/pen/fountain/captain)
crate_name = "captain pen"
crate_type = /obj/structure/closet/crate/secure/weapon //It is a combat pen
@@ -153,7 +143,7 @@
/obj/item/bedsheet/purple,
/obj/item/bedsheet/red,
/obj/item/bedsheet/yellow,
- /obj/item/bedsheet/brown,
+ /obj/item/bedsheet/brown,
/obj/item/bedsheet/black,
/obj/item/bedsheet/rainbow)
crate_name = "colored bedsheet crate"
@@ -182,18 +172,6 @@
/obj/structure/piano/unanchored)
crate_type = /obj/structure/closet/crate/wooden
-/datum/supply_pack/misc/cbtpack
- name = "CBT Equipment"
- desc = "(*!&@#CBT is a special term coined by high ranking syndicate operatives for a special form of information extraction. While the training required to use this shipment is highly classified, the distribution of it's contents are not. In addition to this crates unusual contents, we have added a bar of soap.#@*$"
- hidden = TRUE
- cost = 2400
- contains = list(/mob/living/simple_animal/chicken,
- /obj/item/toy/beach_ball/holoball,
- /obj/item/melee/baton/cattleprod,
- /obj/item/soap/syndie)
- crate_name = "cbt crate"
- crate_type = /obj/structure/closet/crate/large
-
/datum/supply_pack/misc/casinocrate
name = "Casino Crate"
desc = "Start up your own grand casino with this crate filled with slot machine and arcade boards!"
@@ -216,8 +194,8 @@
name = "Coin Crate"
desc = "Psssst, hey, you. Yes, you. I've heard that coins can do some special things on your station, give you access to some pretty cool stuff. Here's the deal, you give me some credits, and I give so some coins. Sound like a deal? I'll give you 10 for 10000 creds."
contraband = TRUE
- cost = 10000
- contains = list(/obj/item/coin/silver)
+ cost = 3000
+ contains = list(/obj/item/coin/silver) // 400 x 10 = 2 sheets of silver for 2300cr
crate_name = "coin crate"
crate_type = /obj/structure/closet/crate/large
@@ -226,10 +204,41 @@
for(var/i in 1 to 9)
new /obj/item/coin/silver(.)
+/datum/supply_pack/misc/dirtymags
+ name = "Dirty Magazines"
+ desc = "Get your mind out of the gutter operative, you have work to do. Three items per order. Possible Results: .357 Speedloaders, Kitchen Gun Mags, Stetchkin Mags."
+ hidden = TRUE
+ cost = 12000
+ var/num_contained = 3
+ contains = list(/obj/item/ammo_box/a357,
+ /obj/item/ammo_box/a357,
+ /obj/item/ammo_box/a357,
+ /obj/item/ammo_box/magazine/pistolm9mm,
+ /obj/item/ammo_box/magazine/pistolm9mm,
+ /obj/item/ammo_box/magazine/pistolm9mm,
+ /obj/item/ammo_box/magazine/m45/kitchengun,
+ /obj/item/ammo_box/magazine/m45/kitchengun)
+ crate_name = "crate"
+
+/datum/supply_pack/misc/dirtymags/fill(obj/structure/closet/crate/C)
+ var/list/L = contains.Copy()
+ for(var/i in 1 to num_contained)
+ var/item = pick_n_take(L)
+ new item(C)
+
//////////////////////////////////////////////////////////////////////////////
-//////////////////////////////// Misc Supplies ///////////////////////////////
+///////////////////////////////// Misc Supplies //////////////////////////////
//////////////////////////////////////////////////////////////////////////////
+/datum/supply_pack/misc/candles
+ name = "Candle Crate"
+ desc = "Set up a romantic dinner or host a séance with these extra candles and crayons."
+ cost = 850
+ contains = list(/obj/item/storage/fancy/candle_box,
+ /obj/item/storage/fancy/candle_box,
+ /obj/item/storage/box/matches)
+ crate_name = "candle crate"
+
/datum/supply_pack/misc/exoticfootwear
name = "Exotic Footwear Crate"
desc = "Popularised by lizards and exotic dancers, the footwear included in this shipment is sure to give your feet the breathing room they deserve. Sweet Kicks Inc. is not responsible for any damage, distress, or @r0u$a1 caused by this shipment."
@@ -246,13 +255,24 @@
/obj/item/clothing/shoes/kindleKicks)
crate_name = "footie crate"
-/datum/supply_pack/misc/wrapping_paper
- name = "Festive Wrapping Paper Crate"
- desc = "Want to mail your loved ones gift-wrapped chocolates, stuffed animals, or the Clown's severed head? You can do all that, with this crate full of wrapping paper."
- cost = 1000
- contains = list(/obj/item/stack/wrapping_paper)
- crate_type = /obj/structure/closet/crate/wooden
- crate_name = "festive wrapping paper crate"
+/datum/supply_pack/misc/funeral
+ name = "Funeral Supplies"
+ desc = "Mourn your dead properly buy sending them off with love filled notes, clean clothes, and a proper ceremony. Contains two candle packs, funeral garb, flowers, a paperbin , and crayons to help aid in religious rituals. Coffin included."
+ cost = 1200
+ contains = list(/obj/item/clothing/under/burial,
+ /obj/item/storage/fancy/candle_box,
+ /obj/item/storage/fancy/candle_box,
+ /obj/item/reagent_containers/food/snacks/grown/harebell,
+ /obj/item/reagent_containers/food/snacks/grown/harebell,
+ /obj/item/reagent_containers/food/snacks/grown/poppy/geranium,
+ /obj/item/reagent_containers/food/snacks/grown/poppy/geranium,
+ /obj/item/reagent_containers/food/snacks/grown/poppy/lily,
+ /obj/item/reagent_containers/food/snacks/grown/poppy/lily,
+ /obj/item/storage/crayons,
+ /obj/item/paper_bin
+ )
+ crate_name = "coffin"
+ crate_type = /obj/structure/closet/crate/coffin
/datum/supply_pack/misc/jukebox
name = "Jukebox"
@@ -260,6 +280,16 @@
contains = list(/obj/machinery/jukebox)
crate_name = "Jukebox"
+/datum/supply_pack/misc/abandonedcrate
+ name = "Loot Box"
+ desc = "Try your luck with these highly secure loot boxes! Solve the lock, win great prizes! WARNING: EXPLOSIVE FAILURE."
+ contraband = TRUE
+ cost = 15000
+ contains = list(/obj/structure/closet/crate/secure/loot)
+ crate_name = "abandoned crate"
+ crate_type = /obj/structure/closet/crate/large
+ dangerous = TRUE
+
/datum/supply_pack/misc/potted_plants
name = "Potted Plants Crate"
desc = "Spruce up the station with these lovely plants! Contains a random assortment of five potted plants from Nanotrasen's potted plant research division. Warranty void if thrown."
@@ -284,25 +314,6 @@
/obj/item/clothing/suit/hooded/chaplain_hoodie)
crate_name = "religious supplies crate"
-/datum/supply_pack/misc/funeral
- name = "Funeral Supplies"
- desc = "Mourn your dead properly buy sending them off with love filled notes, clean clothes, and a proper ceremony. Contains two candle packs, funeral garb, flowers, a paperbin , and crayons to help aid in religious rituals. Coffin included."
- cost = 1200
- contains = list(/obj/item/clothing/under/burial,
- /obj/item/storage/fancy/candle_box,
- /obj/item/storage/fancy/candle_box,
- /obj/item/reagent_containers/food/snacks/grown/harebell,
- /obj/item/reagent_containers/food/snacks/grown/harebell,
- /obj/item/reagent_containers/food/snacks/grown/poppy/geranium,
- /obj/item/reagent_containers/food/snacks/grown/poppy/geranium,
- /obj/item/reagent_containers/food/snacks/grown/poppy/lily,
- /obj/item/reagent_containers/food/snacks/grown/poppy/lily,
- /obj/item/storage/crayons,
- /obj/item/paper_bin
- )
- crate_name = "coffin"
- crate_type = /obj/structure/closet/crate/coffin
-
/datum/supply_pack/misc/shower
name = "Shower Supplies"
desc = "Everyone needs a bit of R&R. Make sure you get can get yours by ordering this crate filled with towels, rubber duckies, and some soap!"
@@ -362,29 +373,6 @@
/obj/item/stack/tile/carpet/monochrome/fifty)
crate_name = "premium carpet crate"
-/datum/supply_pack/misc/party
- name = "Party Equipment"
- desc = "Celebrate both life and death on the station with Nanotrasen's Party Essentials(tm)! Contains seven colored glowsticks, four beers, two ales, a drinking shaker, and a bottle of patron & goldschlager!"
- cost = 2000
- contains = list(/obj/item/storage/box/drinkingglasses,
- /obj/item/reagent_containers/food/drinks/shaker,
- /obj/item/reagent_containers/food/drinks/bottle/patron,
- /obj/item/reagent_containers/food/drinks/bottle/goldschlager,
- /obj/item/reagent_containers/food/drinks/ale,
- /obj/item/reagent_containers/food/drinks/ale,
- /obj/item/reagent_containers/food/drinks/beer,
- /obj/item/reagent_containers/food/drinks/beer,
- /obj/item/reagent_containers/food/drinks/beer,
- /obj/item/reagent_containers/food/drinks/beer,
- /obj/item/flashlight/glowstick,
- /obj/item/flashlight/glowstick/red,
- /obj/item/flashlight/glowstick/blue,
- /obj/item/flashlight/glowstick/cyan,
- /obj/item/flashlight/glowstick/orange,
- /obj/item/flashlight/glowstick/yellow,
- /obj/item/flashlight/glowstick/pink)
- crate_name = "party equipment crate"
-
/datum/supply_pack/misc/noslipfloor
name = "High-traction Floor Tiles"
desc = "Make slipping a thing of the past with sixty industrial-grade anti-slip floortiles!"
diff --git a/code/modules/cargo/packs/organic.dm b/code/modules/cargo/packs/organic.dm
index dd0f987d25..4aa991fc3f 100644
--- a/code/modules/cargo/packs/organic.dm
+++ b/code/modules/cargo/packs/organic.dm
@@ -3,22 +3,47 @@
// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
// cost = 700- Minimum cost, or infinite points are possible.
//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Organic /////////////////////////////////////////
+//////////////////////////////// Organic /////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/datum/supply_pack/organic
group = "Food & Hydroponics"
crate_type = /obj/structure/closet/crate/freezer
+/datum/supply_pack/organic/randomized
+ var/num_contained = 15
+
+/datum/supply_pack/organic/randomized/fill(obj/structure/closet/crate/C)
+ for(var/i in 1 to num_contained)
+ var/item = pick(contains)
+ new item(C)
+
//////////////////////////////////////////////////////////////////////////////
-/////////////////////////////// Food /////////////////////////////////////////
+//////////////////////////////// Meals ///////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
-/datum/supply_pack/organic/candy/randomised
+/datum/supply_pack/organic/combomeal2
+ name = "Burger Combo #2"
+ desc = "We value our customers at the Greasy Griddle, so much so that we're willing to deliver -just for you.- This combo meal contains two burgers, a soda, fries, a toy, and some chicken nuggets."
+ cost = 3200
+ contains = list(/obj/item/reagent_containers/food/snacks/burger/bigbite,
+ /obj/item/reagent_containers/food/snacks/burger/cheese,
+ /obj/item/reagent_containers/food/snacks/fries,
+ /obj/item/reagent_containers/food/condiment/pack/ketchup,
+ /obj/item/reagent_containers/food/condiment/pack/ketchup,
+ /obj/item/reagent_containers/food/snacks/nugget,
+ /obj/item/reagent_containers/food/snacks/nugget,
+ /obj/item/reagent_containers/food/snacks/nugget,
+ /obj/item/reagent_containers/food/snacks/nugget,
+ /obj/item/toy/plush/random)
+ crate_name = "combo meal w/toy"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/organic/randomized/candy
name = "Candy Crate"
desc = "For people that have an insatiable sweet tooth! Has ten candies to be eaten up.."
cost = 2500
- var/num_contained = 10 //number of items picked to be contained in a randomised crate
+ num_contained = 10
contains = list(/obj/item/reagent_containers/food/snacks/candy,
/obj/item/reagent_containers/food/snacks/lollipop,
/obj/item/reagent_containers/food/snacks/gumball,
@@ -47,91 +72,6 @@
/obj/item/storage/fancy/donut_box)
crate_name = "candy crate"
-/datum/supply_pack/organic/randomized/chef
- name = "Excellent Meat Crate"
- desc = "The best cuts in the whole galaxy."
- cost = 2000
- contains = list(/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime,
- /obj/item/reagent_containers/food/snacks/meat/slab/killertomato,
- /obj/item/reagent_containers/food/snacks/meat/slab/bear,
- /obj/item/reagent_containers/food/snacks/meat/slab/xeno,
- /obj/item/reagent_containers/food/snacks/meat/slab/spider,
- /obj/item/reagent_containers/food/snacks/meat/rawbacon,
- /obj/item/reagent_containers/food/snacks/spiderleg,
- /obj/item/reagent_containers/food/snacks/carpmeat,
- /obj/item/reagent_containers/food/snacks/meat/slab/human)
- crate_name = "food crate"
-
-/datum/supply_pack/organic/randomized/chef/fill(obj/structure/closet/crate/C)
- for(var/i in 1 to 15)
- var/item = pick(contains)
- new item(C)
-
-/datum/supply_pack/organic/exoticseeds
- name = "Exotic Seeds Crate"
- desc = "Any entrepreneuring botanist's dream. Contains twelve different seeds, including three replica-pod seeds and two mystery seeds!"
- cost = 1500
- contains = list(/obj/item/seeds/nettle,
- /obj/item/seeds/replicapod,
- /obj/item/seeds/replicapod,
- /obj/item/seeds/replicapod,
- /obj/item/seeds/plump,
- /obj/item/seeds/liberty,
- /obj/item/seeds/amanita,
- /obj/item/seeds/reishi,
- /obj/item/seeds/banana,
- /obj/item/seeds/bamboo,
- /obj/item/seeds/eggplant/eggy,
- /obj/item/seeds/random,
- /obj/item/seeds/random)
- crate_name = "exotic seeds crate"
- crate_type = /obj/structure/closet/crate/hydroponics
-
-/datum/supply_pack/organic/food
- name = "Food Crate"
- desc = "Get things cooking with this crate full of useful ingredients! Contains a two dozen eggs, three bananas, and two bags of flour and rice, two cartons of milk, soymilk, as well as salt and pepper shakers, an enzyme and sugar bottle, and three slabs of monkeymeat."
- cost = 1000
- contains = list(/obj/item/reagent_containers/food/condiment/flour,
- /obj/item/reagent_containers/food/condiment/flour,
- /obj/item/reagent_containers/food/condiment/rice,
- /obj/item/reagent_containers/food/condiment/rice,
- /obj/item/reagent_containers/food/condiment/milk,
- /obj/item/reagent_containers/food/condiment/milk,
- /obj/item/reagent_containers/food/condiment/soymilk,
- /obj/item/reagent_containers/food/condiment/saltshaker,
- /obj/item/reagent_containers/food/condiment/peppermill,
- /obj/item/storage/fancy/egg_box,
- /obj/item/storage/fancy/egg_box,
- /obj/item/reagent_containers/food/condiment/enzyme,
- /obj/item/reagent_containers/food/condiment/sugar,
- /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
- /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
- /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
- /obj/item/reagent_containers/food/snacks/grown/banana,
- /obj/item/reagent_containers/food/snacks/grown/banana,
- /obj/item/reagent_containers/food/snacks/grown/banana)
- crate_name = "food crate"
-
-/datum/supply_pack/organic/randomized/chef/fruits
- name = "Fruit Crate"
- desc = "Rich in vitamins, may contain oranges."
- cost = 1500
- contains = list(/obj/item/reagent_containers/food/snacks/grown/citrus/lime,
- /obj/item/reagent_containers/food/snacks/grown/citrus/orange,
- /obj/item/reagent_containers/food/snacks/grown/banana,
- /obj/item/reagent_containers/food/snacks/grown/watermelon,
- /obj/item/reagent_containers/food/snacks/grown/apple,
- /obj/item/reagent_containers/food/snacks/grown/berries,
- /obj/item/reagent_containers/food/snacks/grown/citrus/lemon,
- /obj/item/reagent_containers/food/snacks/grown/pineapple,
- /obj/item/reagent_containers/food/snacks/grown/cherries,
- /obj/item/reagent_containers/food/snacks/grown/grapes,
- /obj/item/reagent_containers/food/snacks/grown/grapes/green,
- /obj/item/reagent_containers/food/snacks/grown/eggplant,
- /obj/item/reagent_containers/food/snacks/grown/peach,
- /obj/item/reagent_containers/food/snacks/grown/strawberry)
- crate_name = "food crate"
-
/datum/supply_pack/organic/fiestatortilla
name = "Fiesta Crate"
desc = "Spice up the kitchen with this fiesta themed food order! Contains 8 tortilla based food items, as well as a sombrero, moustache, and cloak!"
@@ -151,79 +91,6 @@
/obj/item/reagent_containers/glass/bottle/capsaicin)
crate_name = "fiesta crate"
-/datum/supply_pack/organic/grill
- name = "Grilling Starter Kit"
- desc = "Hey dad I'm Hungry. Hi Hungry I'm THE NEW GRILLING STARTER KIT ONLY 5000 BUX GET NOW! Contains a cooking grill and five fuel coal sheets."
- cost = 3000
- crate_type = /obj/structure/closet/crate
- contains = list(/obj/item/stack/sheet/mineral/coal/five,
- /obj/machinery/grill/unwrenched)
- crate_name = "grilling starter kit crate"
-
-/datum/supply_pack/organic/grillfuel
- name = "Grilling Fuel Kit"
- desc = "Contains coal and coal accessories. (Note: only ten coal sheets.)"
- cost = 1000
- crate_type = /obj/structure/closet/crate
- contains = list(/obj/item/stack/sheet/mineral/coal/ten)
- crate_name = "grilling fuel kit crate"
-
-/datum/supply_pack/organic/cream_piee
- name = "High-yield Clown-grade Cream Pie Crate"
- desc = "Designed by Aussec's Advanced Warfare Research Division, these high-yield, Clown-grade cream pies are powered by a synergy of performance and efficiency. Guaranteed to provide maximum results."
- cost = 6000
- contains = list(/obj/item/storage/backpack/duffelbag/clown/cream_pie)
- crate_name = "party equipment crate"
- contraband = TRUE
- access = ACCESS_THEATRE
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/organic/fakemeat
- name = "Meat Crate"
- desc = "Run outta meat already? Keep the lizards content with this freezer filled with cruelty-free chemically compounded meat! Contains 12 slabs of meat product, and 4 slabs of *carp*."
- cost = 1200 // Buying 3 food crates nets you 9 meat for 900 points, plus like, 6 bags of rice, flour, and egg boxes. This is 12 for 500, but you -only- get meat and carp.
- contains = list(/obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
- /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
- /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
- /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
- /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
- /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
- /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
- /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
- /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
- /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
- /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
- /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
- /obj/item/reagent_containers/food/snacks/carpmeat/imitation,
- /obj/item/reagent_containers/food/snacks/carpmeat/imitation,
- /obj/item/reagent_containers/food/snacks/carpmeat/imitation,
- /obj/item/reagent_containers/food/snacks/carpmeat/imitation)
- crate_name = "meaty crate"
- crate_type = /obj/structure/closet/crate/freezer
-
-/datum/supply_pack/organic/monkeydripmeat
- name = "*Meat* Crate"
- desc = "Need some meat? With this do-it-yourself kit you'll be swimming in it! Contains a monkey cube, an IV drip, and some cryoxadone!"
- cost = 2150
- contraband = TRUE
- contains = list(/obj/item/reagent_containers/food/snacks/monkeycube,
- /obj/item/restraints/handcuffs/cable,
- /obj/machinery/iv_drip,
- /obj/item/reagent_containers/glass/beaker/cryoxadone,
- /obj/item/reagent_containers/glass/beaker/cryoxadone)
- crate_name = "monkey meat crate"
-
-/datum/supply_pack/organic/mixedboxes
- name = "Mixed Ingredient Boxes"
- desc = "Get overwhelmed with inspiration by ordering these boxes of surprise ingredients! Get four boxes filled with an assortment of products!"
- cost = 2300
- contains = list(/obj/item/storage/box/ingredients/wildcard,
- /obj/item/storage/box/ingredients/wildcard,
- /obj/item/storage/box/ingredients/wildcard,
- /obj/item/storage/box/ingredients/wildcard)
- crate_name = "wildcard food crate"
- crate_type = /obj/structure/closet/crate/freezer
-
/datum/supply_pack/organic/pizza
name = "Pizza Crate"
desc = "Best prices on this side of the galaxy. All deliveries are guaranteed to be 99% anomaly-free!"
@@ -258,9 +125,129 @@
considered \[REDACTED\] and returned at your leisure. Note that objects the anomaly produces are specifically attuned exactly to the individual opening the anomaly; regardless \
of species, the individual will find the object edible and it will taste great according to their personal definitions, which vary significantly based on person and species.")
-/datum/supply_pack/organic/randomized/chef/vegetables
- name = "Vegetables Crate"
- desc = "Grown in vats."
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Raw Ingredients /////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/organic/food
+ name = "Food Crate"
+ desc = "Get things cooking with this crate full of useful ingredients! Contains a two dozen eggs, three bananas, and two bags of flour and rice, two cartons of milk, soymilk, as well as salt and pepper shakers, an enzyme and sugar bottle, and three slabs of monkeymeat."
+ cost = 1000
+ contains = list(/obj/item/reagent_containers/food/condiment/flour,
+ /obj/item/reagent_containers/food/condiment/flour,
+ /obj/item/reagent_containers/food/condiment/rice,
+ /obj/item/reagent_containers/food/condiment/rice,
+ /obj/item/reagent_containers/food/condiment/milk,
+ /obj/item/reagent_containers/food/condiment/milk,
+ /obj/item/reagent_containers/food/condiment/soymilk,
+ /obj/item/reagent_containers/food/condiment/saltshaker,
+ /obj/item/reagent_containers/food/condiment/peppermill,
+ /obj/item/storage/fancy/egg_box,
+ /obj/item/storage/fancy/egg_box,
+ /obj/item/reagent_containers/food/condiment/enzyme,
+ /obj/item/reagent_containers/food/condiment/sugar,
+ /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
+ /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
+ /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
+ /obj/item/reagent_containers/food/snacks/grown/banana,
+ /obj/item/reagent_containers/food/snacks/grown/banana,
+ /obj/item/reagent_containers/food/snacks/grown/banana)
+ crate_name = "food crate"
+
+/datum/supply_pack/organic/randomized/fruits
+ name = "Fruit Crate"
+ desc = "Rich in vitamins and possibly sugar. Contains 15 assorted fruits."
+ cost = 1500
+ contains = list(/obj/item/reagent_containers/food/snacks/grown/citrus/lime,
+ /obj/item/reagent_containers/food/snacks/grown/citrus/orange,
+ /obj/item/reagent_containers/food/snacks/grown/banana,
+ /obj/item/reagent_containers/food/snacks/grown/watermelon,
+ /obj/item/reagent_containers/food/snacks/grown/apple,
+ /obj/item/reagent_containers/food/snacks/grown/berries,
+ /obj/item/reagent_containers/food/snacks/grown/citrus/lemon,
+ /obj/item/reagent_containers/food/snacks/grown/pineapple,
+ /obj/item/reagent_containers/food/snacks/grown/cherries,
+ /obj/item/reagent_containers/food/snacks/grown/grapes,
+ /obj/item/reagent_containers/food/snacks/grown/grapes/green,
+ /obj/item/reagent_containers/food/snacks/grown/eggplant,
+ /obj/item/reagent_containers/food/snacks/grown/peach,
+ /obj/item/reagent_containers/food/snacks/grown/strawberry)
+ crate_name = "fruit crate"
+
+/datum/supply_pack/organic/cream_piee
+ name = "High-yield Clown-grade Cream Pie Crate"
+ desc = "Designed by Aussec's Advanced Warfare Research Division, these high-yield, Clown-grade cream pies are powered by a synergy of performance and efficiency. Guaranteed to provide maximum results."
+ cost = 6000
+ contains = list(/obj/item/storage/backpack/duffelbag/clown/cream_pie)
+ crate_name = "party equipment crate"
+ contraband = TRUE
+ access = ACCESS_THEATRE
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/organic/randomized
+ name = "Meat Crate (Exotic)"
+ desc = "The best cuts in the whole galaxy. Contains 15 assorted exotic meats."
+ cost = 2000
+ contains = list(/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime,
+ /obj/item/reagent_containers/food/snacks/meat/slab/killertomato,
+ /obj/item/reagent_containers/food/snacks/meat/slab/bear,
+ /obj/item/reagent_containers/food/snacks/meat/slab/xeno,
+ /obj/item/reagent_containers/food/snacks/meat/slab/spider,
+ /obj/item/reagent_containers/food/snacks/meat/rawbacon,
+ /obj/item/reagent_containers/food/snacks/spiderleg,
+ /obj/item/reagent_containers/food/snacks/carpmeat,
+ /obj/item/reagent_containers/food/snacks/meat/slab/human)
+ crate_name = "exotic meat crate"
+
+/datum/supply_pack/organic/monkeydripmeat
+ name = "Meat Crate (Fresh)"
+ desc = "Need some meat? With this do-it-yourself kit you'll be swimming in it! Contains a monkey cube, an IV drip, and some cryoxadone!"
+ cost = 2150
+ contraband = TRUE
+ contains = list(/obj/item/reagent_containers/food/snacks/monkeycube,
+ /obj/item/restraints/handcuffs/cable,
+ /obj/machinery/iv_drip,
+ /obj/item/reagent_containers/glass/beaker/cryoxadone,
+ /obj/item/reagent_containers/glass/beaker/cryoxadone)
+ crate_name = "monkey meat crate"
+
+/datum/supply_pack/organic/fakemeat
+ name = "Meat Crate 'Synthetic'"
+ desc = "Run outta meat already? Keep the lizards content with this freezer filled with cruelty-free chemically compounded meat! Contains 12 slabs of meat product, and 4 slabs of *carp*."
+ cost = 1200 // Buying 3 food crates nets you 9 meat for 900 points, plus like, 6 bags of rice, flour, and egg boxes. This is 12 for 500, but you -only- get meat and carp.
+ contains = list(/obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
+ /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
+ /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
+ /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
+ /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
+ /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
+ /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
+ /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
+ /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
+ /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
+ /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
+ /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct,
+ /obj/item/reagent_containers/food/snacks/carpmeat/imitation,
+ /obj/item/reagent_containers/food/snacks/carpmeat/imitation,
+ /obj/item/reagent_containers/food/snacks/carpmeat/imitation,
+ /obj/item/reagent_containers/food/snacks/carpmeat/imitation)
+ crate_name = "meaty crate"
+ crate_type = /obj/structure/closet/crate/freezer
+
+/datum/supply_pack/organic/mixedboxes
+ name = "Mixed Ingredient Boxes"
+ desc = "Get overwhelmed with inspiration by ordering these boxes of surprise ingredients! Get four boxes filled with an assortment of products!"
+ cost = 2300
+ contains = list(/obj/item/storage/box/ingredients/wildcard,
+ /obj/item/storage/box/ingredients/wildcard,
+ /obj/item/storage/box/ingredients/wildcard,
+ /obj/item/storage/box/ingredients/wildcard)
+ crate_name = "wildcard food crate"
+ crate_type = /obj/structure/closet/crate/freezer
+
+/datum/supply_pack/organic/randomized/vegetables
+ name = "Vegetable Crate"
+ desc = "Grown in vats. Contains 15 assorted vegetables."
cost = 1300
contains = list(/obj/item/reagent_containers/food/snacks/grown/chili,
/obj/item/reagent_containers/food/snacks/grown/corn,
@@ -270,7 +257,7 @@
/obj/item/reagent_containers/food/snacks/grown/mushroom/chanterelle,
/obj/item/reagent_containers/food/snacks/grown/onion,
/obj/item/reagent_containers/food/snacks/grown/pumpkin)
- crate_name = "food crate"
+ crate_name = "veggie crate"
//////////////////////////////////////////////////////////////////////////////
//////////////////////////// Hydroponics /////////////////////////////////////
@@ -302,42 +289,6 @@
crate_name = "beekeeping starter crate"
crate_type = /obj/structure/closet/crate/hydroponics
-/datum/supply_pack/organic/exoticseeds
- name = "Exotic Seeds Crate"
- desc = "Any entrepreneuring botanist's dream. Contains twelve different seeds, including three replica-pod seeds and two mystery seeds!"
- cost = 1500
- contains = list(/obj/item/seeds/nettle,
- /obj/item/seeds/replicapod,
- /obj/item/seeds/replicapod,
- /obj/item/seeds/replicapod,
- /obj/item/seeds/plump,
- /obj/item/seeds/liberty,
- /obj/item/seeds/amanita,
- /obj/item/seeds/reishi,
- /obj/item/seeds/banana,
- /obj/item/seeds/eggplant/eggy,
- /obj/item/seeds/random,
- /obj/item/seeds/random)
- crate_name = "exotic seeds crate"
- crate_type = /obj/structure/closet/crate/hydroponics
-
-/* Maintenance Garden Crate basically does this and more.
-/datum/supply_pack/organic/hydroponics
- name = "Hydroponics Crate"
- desc = "Supplies for growing a great garden! Contains two bottles of ammonia, two Plant-B-Gone spray bottles, a hatchet, cultivator, plant analyzer, as well as a pair of leather gloves and a botanist's apron."
- cost = 1750
- contains = list(/obj/item/reagent_containers/spray/plantbgone,
- /obj/item/reagent_containers/spray/plantbgone,
- /obj/item/reagent_containers/glass/bottle/ammonia,
- /obj/item/reagent_containers/glass/bottle/ammonia,
- /obj/item/hatchet,
- /obj/item/cultivator,
- /obj/item/plant_analyzer,
- /obj/item/clothing/gloves/botanic_leather,
- /obj/item/clothing/suit/apron)
- crate_name = "hydroponics crate"
- crate_type = /obj/structure/closet/crate/hydroponics
-*/
/datum/supply_pack/organic/hydroponics/hydrotank
name = "Hydroponics Backpack Crate"
desc = "Bring on the flood with this high-capacity backpack crate. Contains 500 units of life-giving H2O. Requires hydroponics access to open."
@@ -390,10 +341,30 @@
/obj/item/seeds/sunflower,
/obj/item/seeds/chanter,
/obj/item/seeds/potato,
- /obj/item/seeds/sugarcane)
+ /obj/item/seeds/sugarcane,
+ /obj/item/seeds/ambrosia)
crate_name = "seeds crate"
crate_type = /obj/structure/closet/crate/hydroponics
+/datum/supply_pack/organic/exoticseeds
+ name = "Seeds Crate (Exotic)"
+ desc = "Any entrepreneuring botanist's dream. Contains twelve different seeds, including three replica-pod seeds and two mystery seeds!"
+ cost = 1500
+ contains = list(/obj/item/seeds/nettle,
+ /obj/item/seeds/replicapod,
+ /obj/item/seeds/replicapod,
+ /obj/item/seeds/replicapod,
+ /obj/item/seeds/plump,
+ /obj/item/seeds/liberty,
+ /obj/item/seeds/amanita,
+ /obj/item/seeds/reishi,
+ /obj/item/seeds/banana,
+ /obj/item/seeds/eggplant/eggy,
+ /obj/item/seeds/random,
+ /obj/item/seeds/random)
+ crate_name = "exotic seeds crate"
+ crate_type = /obj/structure/closet/crate/hydroponics
+
//////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// Misc /////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -414,6 +385,29 @@
crate_name = "sporting crate"
crate_type = /obj/structure/closet/crate/secure // Would have liked a wooden crate but access >:(
+/datum/supply_pack/organic/party
+ name = "Party Equipment"
+ desc = "Celebrate both life and death on the station with Nanotrasen's Party Essentials(tm)! Contains seven colored glowsticks, four beers, two ales, a drinking shaker, and a bottle of patron & goldschlager!"
+ cost = 2000
+ contains = list(/obj/item/storage/box/drinkingglasses,
+ /obj/item/reagent_containers/food/drinks/shaker,
+ /obj/item/reagent_containers/food/drinks/bottle/patron,
+ /obj/item/reagent_containers/food/drinks/bottle/goldschlager,
+ /obj/item/reagent_containers/food/drinks/ale,
+ /obj/item/reagent_containers/food/drinks/ale,
+ /obj/item/reagent_containers/food/drinks/beer,
+ /obj/item/reagent_containers/food/drinks/beer,
+ /obj/item/reagent_containers/food/drinks/beer,
+ /obj/item/reagent_containers/food/drinks/beer,
+ /obj/item/flashlight/glowstick,
+ /obj/item/flashlight/glowstick/red,
+ /obj/item/flashlight/glowstick/blue,
+ /obj/item/flashlight/glowstick/cyan,
+ /obj/item/flashlight/glowstick/orange,
+ /obj/item/flashlight/glowstick/yellow,
+ /obj/item/flashlight/glowstick/pink)
+ crate_name = "party equipment crate"
+
/datum/supply_pack/organic/vday
name = "Surplus Valentine Crate"
desc = "Turns out we got warehouses of this love-y dove-y crap. We're sending out small bargain buddle of Valentine gear. This crate has two boxes of chocolate, three poppy flowers, five candy hearts, and three cards."
diff --git a/code/modules/cargo/packs/science.dm b/code/modules/cargo/packs/science.dm
index f14bc37371..79675cf3ec 100644
--- a/code/modules/cargo/packs/science.dm
+++ b/code/modules/cargo/packs/science.dm
@@ -24,13 +24,12 @@
name = "Advanced Alien Alloy Crate Crate"
desc = "Hello brothers from the stars!!! Our fellow brethren have made contact at long last and gave us gifts man! They really did build the prymi- Connection Error- Bro we’ll send you a sheet of advanced alien alloy."
cost = 15000
- contraband = TRUE
DropPodOnly = TRUE
contains = list(/obj/item/stack/sheet/mineral/abductor)
crate_name = "alien bro alloy crate"
/datum/supply_pack/science/beakers
- name = "Chemistry Beackers Crate"
+ name = "Chemistry Beakers Crate"
desc = "Glassware for any chemistry lab! Contains four small beakers, three large, two plastic, and one metamaterial. As well as three droppers and two pairs of latex gloves."
cost = 1500
contains = list(/obj/item/reagent_containers/glass/beaker,
@@ -82,6 +81,16 @@
/obj/item/integrated_electronics/wirer)
crate_name = "circuitry starter pack crate"
+/datum/supply_pack/science/glasswork
+ name = "Glass Blower Kit Crate"
+ desc = "Learn and make glassworks of usefull things for a profit! Contains glassworking tools and blowing rods. Glass not included."
+ cost = 1000
+ contains = list(/obj/item/glasswork/glasskit,
+ /obj/item/glasswork/glasskit,
+ /obj/item/glasswork/blowing_rod,
+ /obj/item/glasswork/blowing_rod)
+ crate_name = "glassblower gear crate"
+
/datum/supply_pack/science/monkey
name = "Monkey Cube Crate"
desc = "Stop monkeying around! Contains seven monkey cubes. Just add water!"
diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm
index 69967d65d1..3b602d54d2 100644
--- a/code/modules/cargo/packs/security.dm
+++ b/code/modules/cargo/packs/security.dm
@@ -163,13 +163,6 @@
/obj/item/storage/box/handcuffs)
crate_name = "security supply crate"
-/datum/supply_pack/security/vending/security
- name = "SecTech Supply Crate"
- desc = "Officer Paul bought all the donuts? Then refill the security vendor with ths crate."
- cost = 1500
- contains = list(/obj/machinery/vending/security)
- crate_name = "SecTech supply crate"
-
/datum/supply_pack/security/firingpins
name = "Standard Firing Pins Crate"
desc = "Upgrade your arsenal with 10 standard firing pins. Requires Security access to open."
diff --git a/code/modules/cargo/packs/service.dm b/code/modules/cargo/packs/service.dm
index 01524b1910..942720dd6b 100644
--- a/code/modules/cargo/packs/service.dm
+++ b/code/modules/cargo/packs/service.dm
@@ -10,9 +10,24 @@
group = "Service"
//////////////////////////////////////////////////////////////////////////////
-/////////////////////////////// Cargo ////////////////////////////////////////
+//////////////////////////////// Cargo ///////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
+/datum/supply_pack/service/wrapping_paper
+ name = "Cargo Packaging Crate"
+ desc = "Want to mail your loved ones gift-wrapped chocolates, stuffed animals, or the Clown's severed head? You can do all that, with this crate full of festive (and normal) wrapping paper. Also contains a hand labeler and a destination tagger for easy shipping!"
+ cost = 1000
+ contains = list(/obj/item/stack/wrapping_paper,
+ /obj/item/stack/wrapping_paper,
+ /obj/item/stack/wrapping_paper,
+ /obj/item/stack/packageWrap,
+ /obj/item/stack/packageWrap,
+ /obj/item/stack/packageWrap,
+ /obj/item/destTagger,
+ /obj/item/hand_labeler)
+ crate_type = /obj/structure/closet/crate/wooden
+ crate_name = "wrapping paper crate"
+
/datum/supply_pack/service/cargo_supples
name = "Cargo Supplies Crate"
desc = "Sold everything that wasn't bolted down? You can get right back to work with this crate containing stamps, an export scanner, destination tagger, hand labeler and some package wrapping. Now with extra toner cartidges!"
@@ -101,6 +116,23 @@
crate_name = "ice cream vat crate"
crate_type = /obj/structure/closet/crate
+/datum/supply_pack/service/grill
+ name = "Grilling Starter Kit"
+ desc = "Hey dad I'm Hungry. Hi Hungry I'm THE NEW GRILLING STARTER KIT ONLY 5000 BUX GET NOW! Contains a cooking grill and five fuel coal sheets."
+ cost = 3000
+ contains = list(/obj/item/stack/sheet/mineral/coal/five,
+ /obj/machinery/grill/unwrenched)
+ crate_name = "grilling starter kit crate"
+ crate_type = /obj/structure/closet/crate
+
+/datum/supply_pack/service/grillfuel
+ name = "Grilling Fuel Kit"
+ desc = "Contains coal and coal accessories. (Note: only ten coal sheets.)"
+ cost = 1000
+ contains = list(/obj/item/stack/sheet/mineral/coal/ten)
+ crate_name = "grilling fuel kit crate"
+ crate_type = /obj/structure/closet/crate
+
/datum/supply_pack/service/cutlery
name = "Kitchen Cutlery Deluxe Set"
desc = "Need to slice and dice away those \"Tomatoes\"? Well we got what you need! From a nice set of knifes, forks, plates, glasses, and a whetstone for when you got some grizzle that is a bit harder to slice then normal."
@@ -115,7 +147,7 @@
/obj/item/kitchen/knife,
/obj/item/kitchen/knife/butcher,
/obj/item/kitchen/knife/butcher,
- /obj/item/kitchen/rollingpin,
+ /obj/item/kitchen/rollingpin,
/obj/item/trash/plate,
/obj/item/trash/plate,
/obj/item/trash/plate,
@@ -240,45 +272,3 @@
crate_name = "janitorial cart crate"
crate_type = /obj/structure/closet/crate/large
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Vendor Refills //////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/service/vending/bartending
- name = "Bartending Supply Crate"
- desc = "Bring on the booze with vending machine refills, as well as a free book containing the well-kept secrets to the bartending trade!"
- cost = 2000
- contains = list(/obj/item/vending_refill/boozeomat,
- /obj/item/vending_refill/coffee,
- /obj/item/book/granter/action/drink_fling)
- crate_name = "bartending supply crate"
-
-/datum/supply_pack/service/vending/cigarette
- name = "Cigarette Supply Crate"
- desc = "Don't believe the reports - smoke today! Contains a cigarette vending machine refill."
- cost = 1500
- contains = list(/obj/item/vending_refill/cigarette)
- crate_name = "cigarette supply crate"
- crate_type = /obj/structure/closet/crate
-
-/datum/supply_pack/service/vending/games
- name = "Games Supply Crate"
- desc = "Get your game on with this game vending machine refill."
- cost = 1000
- contains = list(/obj/item/vending_refill/games)
- crate_name = "games supply crate"
- crate_type = /obj/structure/closet/crate
-
-/datum/supply_pack/service/vending/snack
- name = "Snack Supply Crate"
- desc = "One vending machine refill of cavity-bringin' goodness! The number one dentist recommended order!"
- cost = 1500
- contains = list(/obj/item/vending_refill/snack)
- crate_name = "snacks supply crate"
-
-/datum/supply_pack/service/vending/cola
- name = "Softdrinks Supply Crate"
- desc = "Got whacked by a toolbox, but you still have those pesky teeth? Get rid of those pearly whites with this soda machine refill, today!"
- cost = 1500
- contains = list(/obj/item/vending_refill/cola)
- crate_name = "soft drinks supply crate"
diff --git a/code/modules/cargo/packs/vending.dm b/code/modules/cargo/packs/vending.dm
new file mode 100644
index 0000000000..f9982d17b6
--- /dev/null
+++ b/code/modules/cargo/packs/vending.dm
@@ -0,0 +1,148 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+/////////////////////////////// Vending //////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/vending
+ group = "Vending"
+
+//////////////////////////////////////////////////////////////////////////////
+///////////////////////// Service, Medical, Sec //////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/vending/bartending
+ name = "Bartending Supply Crate"
+ desc = "Bring on the booze with vending machine refills, as well as a free book containing the well-kept secrets to the bartending trade!"
+ cost = 2000
+ contains = list(/obj/item/vending_refill/boozeomat,
+ /obj/item/vending_refill/coffee,
+ /obj/item/book/granter/action/drink_fling)
+ crate_name = "bartending supply crate"
+
+/datum/supply_pack/vending/cigarette
+ name = "Cigarette Supply Crate"
+ desc = "Don't believe the reports - smoke today! Contains a cigarette vending machine refill."
+ cost = 1500
+ contains = list(/obj/item/vending_refill/cigarette)
+ crate_name = "cigarette supply crate"
+ crate_type = /obj/structure/closet/crate
+
+/datum/supply_pack/vending/games
+ name = "Games Supply Crate"
+ desc = "Get your game on with this game vending machine refill."
+ cost = 1000
+ contains = list(/obj/item/vending_refill/games)
+ crate_name = "games supply crate"
+ crate_type = /obj/structure/closet/crate
+
+/datum/supply_pack/vending/kinkmate
+ name = "Kinkmate Supply and Construction Kit"
+ cost = 2000
+ contraband = TRUE
+ contains = list(/obj/item/vending_refill/kink, /obj/item/circuitboard/machine/kinkmate)
+ crate_name = "Kinkmate construction kit"
+
+/datum/supply_pack/vending/medical
+ name = "Medical Vending Crate"
+ desc = "Contains refills for medical vending machines."
+ cost = 2000
+ contains = list(/obj/item/vending_refill/medical,
+ /obj/item/vending_refill/wallmed)
+ crate_name = "medical vending crate"
+ crate_type = /obj/structure/closet/crate/medical
+
+/datum/supply_pack/vending/security
+ name = "SecTech Supply Crate"
+ desc = "Officer Paul bought all the donuts? Then refill the security vendor with ths crate. Requires Security Access to open."
+ cost = 1500
+ access = ACCESS_SECURITY
+ contains = list(/obj/machinery/vending/security)
+ crate_name = "SecTech supply crate"
+ crate_type = /obj/structure/closet/crate/secure/gear
+
+/datum/supply_pack/vending/snack
+ name = "Snack Supply Crate"
+ desc = "One vending machine refill of cavity-bringin' goodness! The number one dentist recommended order!"
+ cost = 1500
+ contains = list(/obj/item/vending_refill/snack)
+ crate_name = "snacks supply crate"
+
+/datum/supply_pack/vending/cola
+ name = "Softdrinks Supply Crate"
+ desc = "Got whacked by a toolbox, but you still have those pesky teeth? Get rid of those pearly whites with this soda machine refill, today!"
+ cost = 1500
+ contains = list(/obj/item/vending_refill/cola)
+ crate_name = "soft drinks supply crate"
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Wardrobe Vendors ////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/vending/wardrobes/autodrobe
+ name = "Autodrobe Supply Crate"
+ desc = "Autodrobe missing your favorite dress? Solve that issue today with this autodrobe refill."
+ cost = 1500
+ contains = list(/obj/item/vending_refill/autodrobe)
+ crate_name = "autodrobe supply crate"
+
+/datum/supply_pack/vending/wardrobes/cargo
+ name = "Cargo Wardrobe Supply Crate"
+ desc = "This crate contains a refill for the CargoDrobe."
+ cost = 750
+ contains = list(/obj/item/vending_refill/wardrobe/cargo_wardrobe)
+ crate_name = "cargo department supply crate"
+
+/datum/supply_pack/vending/wardrobes/engineering
+ name = "Engineering Wardrobe Supply Crate"
+ desc = "This crate contains refills for the EngiDrobe and AtmosDrobe."
+ cost = 1500
+ contains = list(/obj/item/vending_refill/wardrobe/engi_wardrobe,
+ /obj/item/vending_refill/wardrobe/atmos_wardrobe)
+ crate_name = "engineering department wardrobe supply crate"
+
+/datum/supply_pack/vending/wardrobes/general
+ name = "General Wardrobes Supply Crate"
+ desc = "This crate contains refills for the CuraDrobe, BarDrobe, ChefDrobe, JaniDrobe, ChapDrobe."
+ cost = 3750
+ contains = list(/obj/item/vending_refill/wardrobe/curator_wardrobe,
+ /obj/item/vending_refill/wardrobe/bar_wardrobe,
+ /obj/item/vending_refill/wardrobe/chef_wardrobe,
+ /obj/item/vending_refill/wardrobe/jani_wardrobe,
+ /obj/item/vending_refill/wardrobe/chap_wardrobe)
+ crate_name = "general wardrobes vendor refills"
+
+/datum/supply_pack/vending/wardrobes/hydroponics
+ name = "Hydrobe Supply Crate"
+ desc = "This crate contains a refill for the Hydrobe."
+ cost = 750
+ contains = list(/obj/item/vending_refill/wardrobe/hydro_wardrobe)
+ crate_name = "hydrobe supply crate"
+
+/datum/supply_pack/vending/wardrobes/medical
+ name = "Medical Wardrobe Supply Crate"
+ desc = "This crate contains refills for the MediDrobe, ChemDrobe, GeneDrobe, and ViroDrobe."
+ cost = 3000
+ contains = list(/obj/item/vending_refill/wardrobe/medi_wardrobe,
+ /obj/item/vending_refill/wardrobe/chem_wardrobe,
+ /obj/item/vending_refill/wardrobe/gene_wardrobe,
+ /obj/item/vending_refill/wardrobe/viro_wardrobe)
+ crate_name = "medical department wardrobe supply crate"
+
+/datum/supply_pack/vending/wardrobes/science
+ name = "Science Wardrobe Supply Crate"
+ desc = "This crate contains refills for the SciDrobe and RoboDrobe."
+ cost = 1500
+ contains = list(/obj/item/vending_refill/wardrobe/robo_wardrobe,
+ /obj/item/vending_refill/wardrobe/science_wardrobe)
+ crate_name = "science department wardrobe supply crate"
+
+/datum/supply_pack/vending/wardrobes/security
+ name = "Security Wardrobe Supply Crate"
+ desc = "This crate contains refills for the SecDrobe and LawDrobe."
+ cost = 1500
+ contains = list(/obj/item/vending_refill/wardrobe/sec_wardrobe,
+ /obj/item/vending_refill/wardrobe/law_wardrobe)
+ crate_name = "security department supply crate"
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 08ecefb91f..75daaabb99 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -482,12 +482,20 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(gender == MALE)
hair_style = sanitize_inlist(hair_style, GLOB.hair_styles_male_list)
facial_hair_style = sanitize_inlist(facial_hair_style, GLOB.facial_hair_styles_male_list)
- else
+ undershirt = sanitize_inlist(undershirt, GLOB.undershirt_m)
+ underwear = sanitize_inlist(underwear, GLOB.underwear_m)
+ else if(gender == FEMALE)
hair_style = sanitize_inlist(hair_style, GLOB.hair_styles_female_list)
facial_hair_style = sanitize_inlist(facial_hair_style, GLOB.facial_hair_styles_female_list)
- underwear = sanitize_inlist(underwear, GLOB.underwear_list)
+ undershirt = sanitize_inlist(undershirt, GLOB.undershirt_f)
+ underwear = sanitize_inlist(underwear, GLOB.underwear_f)
+ else
+ hair_style = sanitize_inlist(hair_style, GLOB.hair_styles_list)
+ facial_hair_style = sanitize_inlist(facial_hair_style, GLOB.facial_hair_styles_list)
+ underwear = sanitize_inlist(underwear, GLOB.underwear_list)
+ undershirt = sanitize_inlist(undershirt, GLOB.undershirt_list)
+
undie_color = sanitize_hexcolor(undie_color, 3, FALSE, initial(undie_color))
- undershirt = sanitize_inlist(undershirt, GLOB.undershirt_list)
shirt_color = sanitize_hexcolor(shirt_color, 3, FALSE, initial(shirt_color))
socks = sanitize_inlist(socks, GLOB.socks_list)
socks_color = sanitize_hexcolor(socks_color, 3, FALSE, initial(socks_color))
diff --git a/code/modules/clothing/outfits/ert.dm b/code/modules/clothing/outfits/ert.dm
index 1532f50808..bdbac1165e 100644
--- a/code/modules/clothing/outfits/ert.dm
+++ b/code/modules/clothing/outfits/ert.dm
@@ -18,8 +18,9 @@
R.freqlock = TRUE
var/obj/item/card/id/W = H.wear_id
- W.registered_name = H.real_name
- W.update_label(W.registered_name, W.assignment)
+ if(W)
+ W.registered_name = H.real_name
+ W.update_label(W.registered_name, W.assignment)
/datum/outfit/ert/commander
name = "ERT Commander"
diff --git a/code/modules/clothing/suits/cloaks.dm b/code/modules/clothing/suits/cloaks.dm
index b8287c7f4c..7d56fbe6dd 100644
--- a/code/modules/clothing/suits/cloaks.dm
+++ b/code/modules/clothing/suits/cloaks.dm
@@ -81,7 +81,7 @@
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
- resistance_flags = FIRE_PROOF | ACID_PROOF
+ resistance_flags = FIRE_PROOF | ACID_PROOF | GOLIATH_RESISTANCE
/obj/item/clothing/head/hooded/cloakhood/drake
name = "drake helm"
@@ -90,4 +90,4 @@
armor = list("melee" = 70, "bullet" = 30, "laser" = 50, "energy" = 40, "bomb" = 70, "bio" = 60, "rad" = 50, "fire" = 100, "acid" = 100)
heat_protection = HEAD
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
- resistance_flags = FIRE_PROOF | ACID_PROOF
+ resistance_flags = FIRE_PROOF | ACID_PROOF | GOLIATH_RESISTANCE
diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm
index a2081851e1..a4b8c920d3 100644
--- a/code/modules/clothing/under/miscellaneous.dm
+++ b/code/modules/clothing/under/miscellaneous.dm
@@ -945,4 +945,59 @@
icon_state = "christmasfemaleg"
item_state = "christmasfemaleg"
body_parts_covered = CHEST|GROIN
- can_adjust = FALSE
\ No newline at end of file
+ can_adjust = FALSE
+
+// Lunar Clothes
+/obj/item/clothing/under/lunar/qipao
+ name = "Black Qipao"
+ desc = "A Qipao, traditionally worn in ancient Earth China by women during social events and lunar new years. This one is black."
+ icon_state = "qipao"
+ item_state = "qipao"
+ body_parts_covered = CHEST|GROIN
+ can_adjust = FALSE
+ mutantrace_variation = NONE
+
+/obj/item/clothing/under/lunar/qipao/white
+ name = "White Qipao"
+ desc = "A Qipao, traditionally worn in ancient Earth China by women during social events and lunar new years. This one is white."
+ icon_state = "qipao_white"
+ item_state = "qipao_white"
+ body_parts_covered = CHEST|GROIN
+ can_adjust = FALSE
+ mutantrace_variation = NONE
+
+/obj/item/clothing/under/lunar/qipao/red
+ name = "Red Qipao"
+ desc = "A Qipao, traditionally worn in ancient Earth China by women during social events and lunar new years. This one is red."
+ icon_state = "qipao_red"
+ item_state = "qipao_red"
+ body_parts_covered = CHEST|GROIN
+ can_adjust = FALSE
+ mutantrace_variation = NONE
+
+/obj/item/clothing/under/lunar/cheongsam
+ name = "Black Cheongsam"
+ desc = "A Cheongsam, traditionally worn in ancient Earth China by men during social events and lunar new years. This one is black."
+ icon_state = "cheong"
+ item_state = "cheong"
+ body_parts_covered = CHEST|GROIN
+ can_adjust = FALSE
+ mutantrace_variation = NONE
+
+/obj/item/clothing/under/lunar/cheongsam/white
+ name = "White Cheongsam"
+ desc = "A Cheongsam, traditionally worn in ancient Earth China by men during social events and lunar new years. This one is white."
+ icon_state = "cheongw"
+ item_state = "cheongw"
+ body_parts_covered = CHEST|GROIN
+ can_adjust = FALSE
+ mutantrace_variation = NONE
+
+/obj/item/clothing/under/lunar/cheongsam/red
+ name = "Red Cheongsam"
+ desc = "A Cheongsam, traditionally worn in ancient Earth China by men during social events and lunar new years. This one is red.."
+ icon_state = "cheongr"
+ item_state = "cheongr"
+ body_parts_covered = CHEST|GROIN
+ can_adjust = FALSE
+ mutantrace_variation = NONE
\ No newline at end of file
diff --git a/code/modules/crafting/glassware.dm b/code/modules/crafting/glassware.dm
new file mode 100644
index 0000000000..22d7e01f8a
--- /dev/null
+++ b/code/modules/crafting/glassware.dm
@@ -0,0 +1,299 @@
+//This file is for glass working types of things!
+
+/obj/item/glasswork
+ name = "This is a bug report it!"
+ desc = "Failer to code. Contact your local bug remover..."
+ icon = 'icons/obj/glassworks.dmi'
+ w_class = WEIGHT_CLASS_SMALL
+ force = 1
+ throw_speed = 1
+ throw_range = 3
+ tool_behaviour = null
+
+/obj/item/glasswork/glasskit
+ name = "Glass working tools"
+ desc = "A lovely belt of most the tools you will need to shape, mold, and refine glass into more advanced shapes."
+ icon_state = "glass_tools"
+ tool_behaviour = TOOL_GLASS_CUT
+
+/obj/item/glasswork/blowing_rod
+ name = "Glass working blow rod"
+ desc = "A hollow metal stick made for glass blowing."
+ icon_state = "blowing_rods_unused"
+ tool_behaviour = TOOL_BLOW
+
+/obj/item/glasswork/glass_base
+ name = "Glass fodder sheet"
+ desc = "A sheet of glass set aside for glass working"
+ icon_state = "glass_base"
+ var/next_step = null
+ var/rod = /obj/item/glasswork/blowing_rod
+
+/obj/item/lens
+ name = "Optical lens"
+ desc = "Good for selling or crafting, by itself its useless"
+ icon = 'icons/obj/chemical.dmi'
+ icon_state = "glass_optics"
+
+//////////////////////Chem Disk/////////////////////
+//Two Steps //
+//Sells for 300 cr, takes 10 glass shets //
+//Usefull for chem spliting //
+////////////////////////////////////////////////////
+
+/obj/item/glasswork/glass_base/dish
+ name = "Glass fodder sheet"
+ desc = "A set of glass sheets set aside for glass working, this one is ideal for a small glass dish. Needs to be cut with some tools."
+ next_step = /obj/item/glasswork/glass_base/dish_part1
+
+/obj/item/glasswork/glass_base/dish/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(I.tool_behaviour == TOOL_GLASS_CUT)
+ new next_step(user.loc, 1)
+ qdel(src)
+
+/obj/item/glasswork/glass_base/dish_part1
+ name = "Half chem dish sheet"
+ desc = "A sheet of glass cut in half, looks like it still needs some more cutting down"
+ icon_state = "glass_base_half"
+ next_step = /obj/item/reagent_containers/glass/beaker/glass_dish
+
+/obj/item/glasswork/glass_base/dish_part1/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(I.tool_behaviour == TOOL_GLASS_CUT)
+ new next_step(user.loc, 1)
+ qdel(src)
+
+//////////////////////Lens//////////////////////////
+//Six Steps //
+//Sells for 1800 cr, takes 15 glass shets //
+//Usefull for selling and later crafting //
+////////////////////////////////////////////////////
+
+/obj/item/glasswork/glass_base/glass_lens
+ name = "Glass fodder sheet"
+ desc = "A set of glass sheets set aside for glass working, this one is ideal for a small glass lens. Needs to be cut with some tools."
+ next_step = /obj/item/glasswork/glass_base/glass_lens_part1
+
+/obj/item/glasswork/glass_base/glass_lens/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(I.tool_behaviour == TOOL_GLASS_CUT)
+ new next_step(user.loc, 1)
+ qdel(src)
+
+/obj/item/glasswork/glass_base/glass_lens_part1
+ name = "Glass fodder sheet"
+ desc = "Cut glass ready to be heated. Needs to be heated with some tools."
+ icon_state = "glass_base_half"
+ next_step = /obj/item/glasswork/glass_base/glass_lens_part2
+
+/obj/item/glasswork/glass_base/glass_lens_part1/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(I.tool_behaviour == TOOL_WELDER)
+ new next_step(user.loc, 1)
+ qdel(src)
+
+/obj/item/glasswork/glass_base/glass_lens_part2
+ name = "Glass fodder sheet"
+ desc = "Cut glass that has been heated. Needs to be heated more with some tools."
+ icon_state = "glass_base_heat"
+ next_step = /obj/item/glasswork/glass_base/glass_lens_part3
+
+/obj/item/glasswork/glass_base/glass_lens_part2/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(I.tool_behaviour == TOOL_WELDER)
+ new next_step(user.loc, 1)
+ qdel(src)
+
+/obj/item/glasswork/glass_base/glass_lens_part3
+ name = "Glass fodder sheet"
+ desc = "Cut glass that has been heated into a blob of hot glass. Needs to be placed onto a blow tube."
+ icon_state = "glass_base_molding"
+ next_step = /obj/item/glasswork/glass_base/glass_lens_part4
+
+/obj/item/glasswork/glass_base/glass_lens_part3/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(I.tool_behaviour == TOOL_BLOW)
+ new next_step(user.loc, 1)
+ qdel(src)
+ qdel(I)
+
+/obj/item/glasswork/glass_base/glass_lens_part4
+ name = "Glass fodder sheet"
+ desc = "Cut glass that has been heated into a blob of hot glass. Needs to be cut off onto a blow tube."
+ icon_state = "blowing_rods_inuse"
+ next_step = /obj/item/glasswork/glass_base/glass_lens_part5
+
+/obj/item/glasswork/glass_base/glass_lens_part4/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(I.tool_behaviour == TOOL_GLASS_CUT)
+ new next_step(user.loc, 1)
+ new rod(user.loc, 1)
+ qdel(src)
+
+/obj/item/glasswork/glass_base/glass_lens_part5
+ name = "Unpolished glass lens"
+ desc = "A small unpolished glass lens. Could be polished with some cloth."
+ icon = 'icons/obj/chemical.dmi'
+ icon_state = "glass_optics"
+ next_step = /obj/item/glasswork/glass_base/glass_lens_part6
+
+/obj/item/glasswork/glass_base/glass_lens_part5/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(istype(I, /obj/item/stack/sheet/cloth))
+ new next_step(user.loc, 1)
+ qdel(src)
+
+/obj/item/glasswork/glass_base/glass_lens_part6
+ name = "Unrefined glass lens"
+ desc = "A small polished glass lens. Just needs to be refined with some sandstone."
+ icon = 'icons/obj/chemical.dmi'
+ icon_state = "glass_optics"
+ next_step = /obj/item/lens
+
+/obj/item/glasswork/glass_base/glass_lens_part6/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(istype(I, /obj/item/stack/sheet/mineral/sandstone))
+ new next_step(user.loc, 1)
+ qdel(src)
+
+//////////////////////Spouty Flask//////////////////
+//Four Steps //
+//Sells for 1200 cr, takes 20 glass shets //
+//Usefull for selling and chemical things //
+////////////////////////////////////////////////////
+
+/obj/item/glasswork/glass_base/spouty
+ name = "Glass fodder sheet"
+ desc = "A set of glass sheets set aside for glass working, this one is ideal for a spout beaker. Needs to be cut with some tools."
+ next_step = /obj/item/glasswork/glass_base/spouty_part2
+
+/obj/item/glasswork/glass_base/spouty/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(I.tool_behaviour == TOOL_GLASS_CUT)
+ new next_step(user.loc, 1)
+ qdel(src)
+
+/obj/item/glasswork/glass_base/spouty_part2
+ name = "Glass fodder sheet"
+ desc = "Cut glass that has been heated. Needs to be heated with some tools."
+ icon_state = "glass_base_half"
+ next_step = /obj/item/glasswork/glass_base/spouty_part3
+
+/obj/item/glasswork/glass_base/spouty_part2/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(I.tool_behaviour == TOOL_WELDER)
+ new next_step(user.loc, 1)
+ qdel(src)
+
+/obj/item/glasswork/glass_base/spouty_part3
+ name = "Glass fodder sheet"
+ desc = "Cut glass that has been heated into a blob of hot glass. Needs to be placed onto a blow tube."
+ icon_state = "glass_base_molding"
+ next_step = /obj/item/glasswork/glass_base/spouty_part4
+
+/obj/item/glasswork/glass_base/spouty_part3/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(I.tool_behaviour == TOOL_BLOW)
+ new next_step(user.loc, 1)
+ qdel(src)
+ qdel(I)
+
+/obj/item/glasswork/glass_base/spouty_part4
+ name = "Glass fodder sheet"
+ desc = "Cut glass that has been heated into a blob of hot glass. Needs to be cut off onto a blow tube."
+ icon_state = "blowing_rods_inuse"
+ next_step = /obj/item/reagent_containers/glass/beaker/flask/spouty
+
+/obj/item/glasswork/glass_base/spouty_part4/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(I.tool_behaviour == TOOL_GLASS_CUT)
+ new next_step(user.loc, 1)
+ new rod(user.loc, 1)
+ qdel(src)
+
+//////////////////////Small Bulb Flask//////////////
+//Two Steps //
+//Sells for 600 cr, takes 5 glass shets //
+//Usefull for selling and chemical things //
+////////////////////////////////////////////////////
+
+/obj/item/glasswork/glass_base/flask_small
+ name = "Glass fodder sheet"
+ desc = "A set of glass sheets set aside for glass working, this one is ideal for a small flask. Needs to be heated with some tools."
+ next_step = /obj/item/glasswork/glass_base/flask_small_part1
+
+/obj/item/glasswork/glass_base/flask_small/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(I.tool_behaviour == TOOL_WELDER)
+ new next_step(user.loc, 1)
+ qdel(src)
+
+/obj/item/glasswork/glass_base/flask_small_part1
+ name = "Metled glass"
+ desc = "A blob of metled glass, this one is ideal for a small flask. Needs to be blown with some tools."
+ icon_state = "glass_base_molding"
+ next_step = /obj/item/glasswork/glass_base/flask_small_part2
+
+/obj/item/glasswork/glass_base/flask_small_part1/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(I.tool_behaviour == TOOL_BLOW)
+ new next_step(user.loc, 1)
+ qdel(src)
+ qdel(I)
+
+/obj/item/glasswork/glass_base/flask_small_part2
+ name = "Metled glass"
+ desc = "A blob of metled glass on the end of a blowing rod. Needs to be cut off with some tools."
+ icon_state = "blowing_rods_inuse"
+ next_step = /obj/item/reagent_containers/glass/beaker/flask
+
+/obj/item/glasswork/glass_base/flask_small_part2/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(I.tool_behaviour == TOOL_GLASS_CUT)
+ new next_step(user.loc, 1)
+ new rod(user.loc, 1)
+ qdel(src)
+
+//////////////////////Large Bulb Flask//////////////
+//Two Steps //
+//Sells for 1000 cr, takes 15 glass shets //
+//Usefull for selling and chemical things //
+////////////////////////////////////////////////////
+
+/obj/item/glasswork/glass_base/flask_large
+ name = "Glass fodder sheet"
+ desc = "A set of glass sheets set aside for glass working, this one is ideal for a large flask. Needs to be heated with some tools."
+ next_step = /obj/item/glasswork/glass_base/flask_large_part1
+
+/obj/item/glasswork/glass_base/flask_large/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(I.tool_behaviour == TOOL_WELDER)
+ new next_step(user.loc, 1)
+ qdel(src)
+
+/obj/item/glasswork/glass_base/flask_large_part1
+ name = "Metled glass"
+ desc = "A blob of metled glass, this one is ideal for a large flask. Needs to be blown with some tools."
+ icon_state = "glass_base_molding"
+ next_step = /obj/item/glasswork/glass_base/flask_large_part2
+
+/obj/item/glasswork/glass_base/flask_large_part1/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(I.tool_behaviour == TOOL_BLOW)
+ new next_step(user.loc, 1)
+ qdel(src)
+ qdel(I)
+
+/obj/item/glasswork/glass_base/flask_large_part2
+ name = "Metled glass"
+ desc = "A blob of metled glass on the end of a blowing rod. Needs to be cut off with some tools."
+ icon_state = "blowing_rods_inuse"
+ next_step = /obj/item/reagent_containers/glass/beaker/flask/large
+
+/obj/item/glasswork/glass_base/flask_large_part2/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(I.tool_behaviour == TOOL_GLASS_CUT)
+ new next_step(user.loc, 1)
+ new rod(user.loc, 1)
+ qdel(src)
diff --git a/code/modules/events/meteor_wave.dm b/code/modules/events/meteor_wave.dm
index a1a82ea5f7..d4eb6ded4c 100644
--- a/code/modules/events/meteor_wave.dm
+++ b/code/modules/events/meteor_wave.dm
@@ -18,6 +18,7 @@
announceWhen = 1
var/list/wave_type
var/wave_name = "normal"
+ var/direction
/datum/round_event/meteor_wave/setup()
announceWhen = 1
@@ -26,7 +27,6 @@
startWhen *= 1 - min(GLOB.singularity_counter * SINGULO_BEACON_DISTURBANCE, SINGULO_BEACON_MAX_DISTURBANCE)
endWhen = startWhen + 60
-
/datum/round_event/meteor_wave/New()
..()
if(!wave_type)
@@ -38,6 +38,8 @@
"normal" = 50,
"threatening" = 40,
"catastrophic" = 10))
+ if(!direction)
+ direction = pick(GLOB.cardinals)
switch(wave_name)
if("normal")
wave_type = GLOB.meteors_normal
@@ -59,11 +61,21 @@
kill()
/datum/round_event/meteor_wave/announce(fake)
- priority_announce("Meteors have been detected on collision course with the station. Estimated time until impact: [round(startWhen/60)] minutes.[GLOB.singularity_counter ? " Warning: Anomalous gravity pulse detected, Syndicate technology interference likely." : ""]", "Meteor Alert", "meteors")
+ var/directionstring
+ switch(direction)
+ if(NORTH)
+ directionstring = " towards the fore"
+ if(SOUTH)
+ directionstring = " towards the aft"
+ if(EAST)
+ directionstring = " towards starboard"
+ if(WEST)
+ directionstring = " towards port"
+ priority_announce("Meteors have been detected on collision course with the station[directionstring]. Estimated time until impact: [round((startWhen * SSevents.wait) / 10, 0.1)] seconds.[GLOB.singularity_counter ? " Warning: Anomalous gravity pulse detected, Syndicate technology interference likely." : ""]", "Meteor Alert", "meteors")
/datum/round_event/meteor_wave/tick()
if(ISMULTIPLE(activeFor, 3))
- spawn_meteors(5, wave_type) //meteor list types defined in gamemode/meteor/meteors.dm
+ spawn_meteors(5, wave_type, direction) //meteor list types defined in gamemode/meteor/meteors.dm
/datum/round_event_control/meteor_wave/threatening
name = "Meteor Wave: Threatening"
diff --git a/code/modules/events/shuttle_loan.dm b/code/modules/events/shuttle_loan.dm
index f006f2b358..c585961604 100644
--- a/code/modules/events/shuttle_loan.dm
+++ b/code/modules/events/shuttle_loan.dm
@@ -133,7 +133,7 @@
shuttle_spawns.Add(/mob/living/simple_animal/hostile/syndicate/ranged/infiltrator)
if(RUSKY_PARTY)
- var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/misc/party]
+ var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/organic/party]
pack.generate(pick_n_take(empty_shuttle_turfs))
shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian)
diff --git a/code/modules/fields/timestop.dm b/code/modules/fields/timestop.dm
index c59a8004ca..56abef8cd6 100644
--- a/code/modules/fields/timestop.dm
+++ b/code/modules/fields/timestop.dm
@@ -9,7 +9,7 @@
pixel_x = -64
pixel_y = -64
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
- var/list/immune = list() // the one who creates the timestop is immune
+ var/list/immune = list() // the one who creates the timestop is immune, which includes wizards and the dead slime you murdered to make this chronofield
var/turf/target
var/freezerange = 2
var/duration = 140
@@ -27,10 +27,10 @@
for(var/A in immune_atoms)
immune[A] = TRUE
for(var/mob/living/L in GLOB.player_list)
- if(locate(/obj/effect/proc_holder/spell/aoe_turf/conjure/timestop) in L.mind.spell_list) //People who can stop time are immune to its effects
+ if(locate(/obj/effect/proc_holder/spell/aoe_turf/timestop) in L.mind.spell_list) //People who can stop time are immune to its effects
immune[L] = TRUE
for(var/mob/living/simple_animal/hostile/guardian/G in GLOB.parasites)
- if(G.summoner && locate(/obj/effect/proc_holder/spell/aoe_turf/conjure/timestop) in G.summoner.mind.spell_list) //It would only make sense that a person's stand would also be immune.
+ if(G.summoner && locate(/obj/effect/proc_holder/spell/aoe_turf/timestop) in G.summoner.mind.spell_list) //It would only make sense that a person's stand would also be immune.
immune[G] = TRUE
if(start)
timestop()
@@ -46,9 +46,8 @@
chronofield = make_field(/datum/proximity_monitor/advanced/timestop, list("current_range" = freezerange, "host" = src, "immune" = immune, "check_anti_magic" = check_anti_magic, "check_holy" = check_holy))
QDEL_IN(src, duration)
-/obj/effect/timestop/wizard
+/obj/effect/timestop/magic
check_anti_magic = TRUE
- duration = 100
/datum/proximity_monitor/advanced/timestop
name = "chronofield"
@@ -56,9 +55,10 @@
field_shape = FIELD_SHAPE_RADIUS_SQUARE
requires_processing = TRUE
var/list/immune = list()
- var/list/mob/living/frozen_mobs = list()
- var/list/obj/item/projectile/frozen_projectiles = list()
- var/list/atom/movable/frozen_throws = list()
+ var/list/frozen_things = list()
+ var/list/frozen_mobs = list() //cached separately for processing
+ var/list/frozen_structures = list() //Also machinery, and only frozen aestethically
+ var/list/frozen_turfs = list() //Only aesthetically
var/check_anti_magic = FALSE
var/check_holy = FALSE
@@ -74,85 +74,125 @@
/datum/proximity_monitor/advanced/timestop/proc/freeze_atom(atom/movable/A)
if(immune[A] || global_frozen_atoms[A] || !istype(A))
return FALSE
- if(A.throwing)
- freeze_throwing(A)
+ if(ismob(A))
+ var/mob/M = A
+ if(M.anti_magic_check(check_anti_magic, check_holy))
+ immune[A] = TRUE
+ return
+ var/frozen = TRUE
if(isliving(A))
freeze_mob(A)
else if(istype(A, /obj/item/projectile))
freeze_projectile(A)
+ else if(istype(A, /obj/mecha))
+ freeze_mecha(A)
+ else if((ismachinery(A) && !istype(A, /obj/machinery/light)) || isstructure(A)) //Special exception for light fixtures since recoloring causes them to change light
+ freeze_structure(A)
else
- return FALSE
+ frozen = FALSE
+ if(A.throwing)
+ freeze_throwing(A)
+ frozen = TRUE
+ if(!frozen)
+ return
+ frozen_things[A] = A.move_resist
+ A.move_resist = INFINITY
+ global_frozen_atoms[A] = src
into_the_negative_zone(A)
+ RegisterSignal(A, COMSIG_MOVABLE_PRE_MOVE, .proc/unfreeze_atom)
+ RegisterSignal(A, COMSIG_ITEM_PICKUP, .proc/unfreeze_atom)
return TRUE
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_all()
- for(var/i in frozen_projectiles)
- unfreeze_projectile(i)
- for(var/i in frozen_mobs)
- unfreeze_mob(i)
- for(var/i in frozen_throws)
- unfreeze_throw(i)
+ for(var/i in frozen_things)
+ unfreeze_atom(i)
+ for(var/T in frozen_turfs)
+ unfreeze_turf(T)
+
+/datum/proximity_monitor/advanced/timestop/proc/unfreeze_atom(atom/movable/A)
+ if(A.throwing)
+ unfreeze_throwing(A)
+ if(isliving(A))
+ unfreeze_mob(A)
+ else if(istype(A, /obj/item/projectile))
+ unfreeze_projectile(A)
+ else if(istype(A, /obj/mecha))
+ unfreeze_mecha(A)
+
+ UnregisterSignal(A, COMSIG_MOVABLE_PRE_MOVE)
+ UnregisterSignal(A, COMSIG_ITEM_PICKUP)
+ escape_the_negative_zone(A)
+ A.move_resist = frozen_things[A]
+ frozen_things -= A
+ global_frozen_atoms -= A
+
+/datum/proximity_monitor/advanced/timestop/proc/freeze_mecha(obj/mecha/M)
+ M.completely_disabled = TRUE
+
+/datum/proximity_monitor/advanced/timestop/proc/unfreeze_mecha(obj/mecha/M)
+ M.completely_disabled = FALSE
/datum/proximity_monitor/advanced/timestop/proc/freeze_throwing(atom/movable/AM)
var/datum/thrownthing/T = AM.throwing
T.paused = TRUE
- frozen_throws[AM] = T
- global_frozen_atoms[AM] = TRUE
-/datum/proximity_monitor/advanced/timestop/proc/unfreeze_throw(atom/movable/AM)
- var/datum/thrownthing/T = frozen_throws[AM]
- T.paused = FALSE
- frozen_throws -= AM
- global_frozen_atoms -= AM
+/datum/proximity_monitor/advanced/timestop/proc/unfreeze_throwing(atom/movable/AM)
+ var/datum/thrownthing/T = AM.throwing
+ if(T)
+ T.paused = FALSE
+
+/datum/proximity_monitor/advanced/timestop/proc/freeze_turf(turf/T)
+ into_the_negative_zone(T)
+ frozen_turfs += T
+
+/datum/proximity_monitor/advanced/timestop/proc/unfreeze_turf(turf/T)
+ escape_the_negative_zone(T)
+
+/datum/proximity_monitor/advanced/timestop/proc/freeze_structure(obj/O)
+ into_the_negative_zone(O)
+ frozen_structures += O
+
+/datum/proximity_monitor/advanced/timestop/proc/unfreeze_structure(obj/O)
+ escape_the_negative_zone(O)
/datum/proximity_monitor/advanced/timestop/process()
for(var/i in frozen_mobs)
var/mob/living/m = i
- if(get_dist(get_turf(m), get_turf(host)) > current_range)
- unfreeze_mob(m)
- else
- m.Stun(20, 1, 1)
+ m.Stun(20, 1, 1)
/datum/proximity_monitor/advanced/timestop/setup_field_turf(turf/T)
for(var/i in T.contents)
freeze_atom(i)
+ freeze_turf(T)
return ..()
-/datum/proximity_monitor/advanced/timestop/proc/unfreeze_projectile(obj/item/projectile/P)
- escape_the_negative_zone(P)
- frozen_projectiles -= P
- P.paused = FALSE
- global_frozen_atoms -= P
-
/datum/proximity_monitor/advanced/timestop/proc/freeze_projectile(obj/item/projectile/P)
- frozen_projectiles[P] = TRUE
P.paused = TRUE
- global_frozen_atoms[P] = TRUE
+
+/datum/proximity_monitor/advanced/timestop/proc/unfreeze_projectile(obj/item/projectile/P)
+ P.paused = FALSE
/datum/proximity_monitor/advanced/timestop/proc/freeze_mob(mob/living/L)
- if(L.anti_magic_check(check_anti_magic, check_holy))
- immune += L
- return
+ frozen_mobs += L
L.Stun(20, 1, 1)
- frozen_mobs[L] = L.anchored
- L.anchored = TRUE
- global_frozen_atoms[L] = TRUE
- if(ishostile(L))
- var/mob/living/simple_animal/hostile/H = L
- H.toggle_ai(AI_OFF)
- H.LoseTarget()
+ ADD_TRAIT(L, TRAIT_MUTE, TIMESTOP_TRAIT)
+ walk(L, 0) //stops them mid pathing even if they're stunimmune
+ if(isanimal(L))
+ var/mob/living/simple_animal/S = L
+ S.toggle_ai(AI_OFF)
+ if(ishostile(L))
+ var/mob/living/simple_animal/hostile/H = L
+ H.LoseTarget()
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_mob(mob/living/L)
- escape_the_negative_zone(L)
L.AdjustStun(-20, 1, 1)
- L.anchored = frozen_mobs[L]
+ REMOVE_TRAIT(L, TRAIT_MUTE, TIMESTOP_TRAIT)
frozen_mobs -= L
- global_frozen_atoms -= L
- if(ishostile(L))
- var/mob/living/simple_animal/hostile/H = L
- H.toggle_ai(initial(H.AIStatus))
+ if(isanimal(L))
+ var/mob/living/simple_animal/S = L
+ S.toggle_ai(initial(S.AIStatus))
//you don't look quite right, is something the matter?
/datum/proximity_monitor/advanced/timestop/proc/into_the_negative_zone(atom/A)
@@ -160,4 +200,4 @@
//let's put some colour back into your cheeks
/datum/proximity_monitor/advanced/timestop/proc/escape_the_negative_zone(atom/A)
- A.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY)
\ No newline at end of file
+ A.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY)
diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm
index c28ae3b4c5..f459e97814 100644
--- a/code/modules/hydroponics/seeds.dm
+++ b/code/modules/hydroponics/seeds.dm
@@ -186,8 +186,8 @@ obj/item/seeds/proc/is_gene_forbidden(typepath)
product_name = parent.myseed.plantname
if(getYield() >= 1)
SSblackbox.record_feedback("tally", "food_harvested", getYield(), product_name)
+ parent.investigate_log("[user] harvested [getYield()] of [src], with seed traits [english_list(genes)] and reagents_add [english_list(reagents_add)] and potency [potency].", INVESTIGATE_BOTANY)
parent.update_tray(user)
-
return result
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm b/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm
index d11299fd5b..34988f5656 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm
@@ -7,6 +7,26 @@
// please make sure they're sorted alphabetically and categorized
+/datum/sprite_accessory/facial_hair/threeoclock
+ name = "Beard (3 o\'Clock)"
+ icon_state = "facial_3oclock"
+
+/datum/sprite_accessory/facial_hair/fiveoclock
+ name = "Beard (5 o\'Clock)"
+ icon_state = "facial_5oclock"
+
+/datum/sprite_accessory/facial_hair/fiveoclockm
+ name = "Beard (5 o\'Clock with Moustache)"
+ icon_state = "facial_5oclockmoustache"
+
+/datum/sprite_accessory/facial_hair/sevenoclock
+ name = "Beard (7 o\'Clock)"
+ icon_state = "facial_7oclock"
+
+/datum/sprite_accessory/facial_hair/sevenoclockm
+ name = "Beard (7 o\'Clock with Moustache)"
+ icon_state = "facial_7oclockmoustache"
+
/datum/sprite_accessory/facial_hair/abe
name = "Beard (Abraham Lincoln)"
icon_state = "facial_abe"
@@ -23,10 +43,6 @@
name = "Beard (Dwarf)"
icon_state = "facial_dwarf"
-/datum/sprite_accessory/facial_hair/fiveoclock
- name = "Beard (Five o Clock Shadow)"
- icon_state = "facial_fiveoclock"
-
/datum/sprite_accessory/facial_hair/fullbeard
name = "Beard (Full)"
icon_state = "facial_fullbeard"
@@ -35,6 +51,10 @@
name = "Beard (Goatee)"
icon_state = "facial_gt"
+/datum/sprite_accessory/facial_hair/goatee
+ name = "Beard (Goatee 2)"
+ icon_state = "facial_goatee"
+
/datum/sprite_accessory/facial_hair/hip
name = "Beard (Hipster)"
icon_state = "facial_hip"
@@ -43,18 +63,38 @@
name = "Beard (Jensen)"
icon_state = "facial_jensen"
+/datum/sprite_accessory/facial_hair/martialartist
+ name = "Beard (Martial Artist)"
+ icon_state = "facial_martialartist"
+
+/datum/sprite_accessory/facial_hair/moonshiner
+ name = "Beard (Moonshiner)"
+ icon_state = "facial_moonshiner"
+
/datum/sprite_accessory/facial_hair/neckbeard
name = "Beard (Neckbeard)"
icon_state = "facial_neckbeard"
+/datum/sprite_accessory/facial_hair/tribeard
+ name = "Beard (Tribeard)"
+ icon_state = "facial_tribeard"
+
/datum/sprite_accessory/facial_hair/vlongbeard
name = "Beard (Very Long)"
icon_state = "facial_wise"
+/datum/sprite_accessory/facial_hair/volaju
+ name = "Beard (Volaju)"
+ icon_state = "facial_volaju"
+
/datum/sprite_accessory/facial_hair/longbeard
name = "Beard (Long)"
icon_state = "facial_longbeard"
+/datum/sprite_accessory/facial_hair/moustache
+ name = "Moustache"
+ icon_state = "facial_moustache"
+
/datum/sprite_accessory/facial_hair/fu
name = "Moustache (Fu Manchu)"
icon_state = "facial_fumanchu"
@@ -63,6 +103,10 @@
name = "Moustache (Hulk Hogan)"
icon_state = "facial_hogan" //-Neek
+/datum/sprite_accessory/facial_hair/pencil
+ name = "Moustache (Pencil)"
+ icon_state = "facial_pencilstache"
+
/datum/sprite_accessory/facial_hair/selleck
name = "Moustache (Selleck)"
icon_state = "facial_selleck"
@@ -75,56 +119,31 @@
name = "Moustache (Van Dyke)"
icon_state = "facial_vandyke"
+/datum/sprite_accessory/facial_hair/walrus
+ name = "Moustache (Walrus)"
+ icon_state = "facial_walrus"
+
/datum/sprite_accessory/facial_hair/watson
name = "Moustache (Watson)"
icon_state = "facial_watson"
+/datum/sprite_accessory/facial_hair/mutton
+ name = "Mutton Chops"
+ icon_state = "facial_mutton"
+
+/datum/sprite_accessory/facial_hair/muttonmus
+ name = "Mutton Chops with Moustache"
+ icon_state = "facial_muttonmus"
+
/datum/sprite_accessory/facial_hair/shaved
name = "Shaved"
icon_state = null
gender = NEUTER
+/datum/sprite_accessory/facial_hair/sideburn
+ name = "Sideburns"
+ icon_state = "facial_sideburns"
+
/datum/sprite_accessory/facial_hair/elvis
name = "Sideburns (Elvis)"
- icon_state = "facial_elvis"
-
-#define VFACE(_name, new_state) /datum/sprite_accessory/facial_hair/##new_state/icon_state=#new_state;;/datum/sprite_accessory/facial_hair/##new_state/name= #_name + " (Virgo)"
-VFACE("Watson", facial_watson_s)
-VFACE("Chaplin", facial_chaplin_s)
-VFACE("Fullbeard", facial_fullbeard_s)
-VFACE("Vandyke", facial_vandyke_s)
-VFACE("Elvis", facial_elvis_s)
-VFACE("Abe", facial_abe_s)
-VFACE("Chin", facial_chin_s)
-VFACE("GT", facial_gt_s)
-VFACE("Hip", facial_hip_s)
-VFACE("Hogan", facial_hogan_s)
-VFACE("Selleck", facial_selleck_s)
-VFACE("Neckbeard", facial_neckbeard_s)
-VFACE("Longbeard", facial_longbeard_s)
-VFACE("Dwarf", facial_dwarf_s)
-VFACE("Sideburn", facial_sideburn_s)
-VFACE("Mutton", facial_mutton_s)
-VFACE("Moustache", facial_moustache_s)
-VFACE("Pencilstache", facial_pencilstache_s)
-VFACE("Goatee", facial_goatee_s)
-VFACE("Smallstache", facial_smallstache_s)
-VFACE("Volaju", facial_volaju_s)
-VFACE("3 O\'clock", facial_3oclock_s)
-VFACE("5 O\'clock", facial_5oclock_s)
-VFACE("7 O\'clock", facial_7oclock_s)
-VFACE("5 O\'clock Moustache", facial_5oclockmoustache_s)
-VFACE("7 O\'clock", facial_7oclockmoustache_s)
-VFACE("Walrus", facial_walrus_s)
-VFACE("Muttonmus", facial_muttonmus_s)
-VFACE("Wise", facial_wise_s)
-VFACE("Martial Artist", facial_martialartist_s)
-VFACE("Dorsalfnil", facial_dorsalfnil_s)
-VFACE("Hornadorns", facial_hornadorns_s)
-VFACE("Spike", facial_spike_s)
-VFACE("Chinhorns", facial_chinhorns_s)
-VFACE("Cropped Fullbeard", facial_croppedfullbeard_s)
-VFACE("Chinless Beard", facial_chinlessbeard_s)
-VFACE("Moonshiner", facial_moonshiner_s)
-VFACE("Tribearder", facial_tribearder_s)
-#undef VFACE
\ No newline at end of file
+ icon_state = "facial_elvis"
\ No newline at end of file
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm b/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm
index abcc90c0ee..b0ed2000a6 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm
@@ -27,7 +27,7 @@
/datum/sprite_accessory/hair/bald
name = "Bald"
- icon_state = null
+ icon_state = "bald"
/datum/sprite_accessory/hair/balding
name = "Balding Hair"
@@ -37,6 +37,14 @@
name = "Bedhead"
icon_state = "hair_bedhead"
+/datum/sprite_accessory/hair/bedhead_long
+ name = "Bedhead (Long)"
+ icon_state = "hair_long_bedhead"
+
+/datum/sprite_accessory/hair/bedhead_longer
+ name = "Bedhead (Longer)"
+ icon_state = "hair_longer_bedhead"
+
/datum/sprite_accessory/hair/bedhead2
name = "Bedhead 2"
icon_state = "hair_bedheadv2"
@@ -51,7 +59,7 @@
/datum/sprite_accessory/hair/beehive2
name = "Beehive 2"
- icon_state = "hair_beehivev2"
+ icon_state = "hair_beehive2"
/datum/sprite_accessory/hair/bob
name = "Bob Hair"
@@ -69,6 +77,14 @@
name = "Bobcurl"
icon_state = "hair_bobcurl"
+/datum/sprite_accessory/hair/bobcut
+ name = "Bobcut"
+ icon_state = "hair_bobcut"
+
+/datum/sprite_accessory/hair/bobcutalt
+ name = "Bobcut (Alt)"
+ icon_state = "hair_bobcutalt"
+
/datum/sprite_accessory/hair/boddicker
name = "Boddicker"
icon_state = "hair_boddicker"
@@ -77,6 +93,10 @@
name = "Bowl"
icon_state = "hair_bowlcut"
+/datum/sprite_accessory/hair/bowl2
+ name = "Bowl 2"
+ icon_state = "hair_bowlcut2"
+
/datum/sprite_accessory/hair/braid
name = "Braid (Floorlength)"
icon_state = "hair_braid"
@@ -89,6 +109,10 @@
name = "Braided Front"
icon_state = "hair_braidfront"
+/datum/sprite_accessory/hair/grandebraid
+ name = "Braid (Grande)"
+ icon_state = "hair_grande"
+
/datum/sprite_accessory/hair/not_floorlength_braid
name = "Braid (High)"
icon_state = "hair_braid2"
@@ -113,10 +137,26 @@
name = "Bun Head 2"
icon_state = "hair_bunhead2"
+/datum/sprite_accessory/hair/bun3
+ name = "Bun Head 3"
+ icon_state = "hair_bunhead3"
+
+/datum/sprite_accessory/hair/bun4
+ name = "Bun Head 4"
+ icon_state = "hair_bunhead4"
+
+/datum/sprite_accessory/hair/doublebun
+ name = "Bun Head (Double)"
+ icon_state = "hair_doublebun"
+
/datum/sprite_accessory/hair/largebun
- name = "Bun (Large)"
+ name = "Bun Head (Large)"
icon_state = "hair_largebun"
+/datum/sprite_accessory/hair/tightbun
+ name = "Bun Head (Tight)"
+ icon_state = "hair_tightbun"
+
/datum/sprite_accessory/hair/business
name = "Business Hair"
icon_state = "hair_business"
@@ -137,10 +177,22 @@
name = "Buzzcut"
icon_state = "hair_buzzcut"
+/datum/sprite_accessory/hair/cia
+ name = "CIA"
+ icon_state = "hair_cia"
+
/datum/sprite_accessory/hair/combover
name = "Combover"
icon_state = "hair_combover"
+/datum/sprite_accessory/hair/coffeehouse
+ name = "Coffee House"
+ icon_state = "hair_coffeehouse"
+
+/datum/sprite_accessory/hair/country
+ name = "Country"
+ icon_state = "hair_country"
+
/datum/sprite_accessory/hair/crew
name = "Crewcut"
icon_state = "hair_crewcut"
@@ -149,13 +201,21 @@
name = "Curls"
icon_state = "hair_curls"
+/datum/sprite_accessory/hair/curly
+ name = "Curly"
+ icon_state = "hair_curly"
+
/datum/sprite_accessory/hair/cut
name = "Cut Hair"
icon_state = "hair_c"
+/datum/sprite_accessory/hair/dave
+ name = "Dave"
+ icon_state = "hair_dave"
+
/datum/sprite_accessory/hair/devillock
name = "Devil Lock"
- icon_state = "hair_devilock"
+ icon_state = "hair_devillock"
/datum/sprite_accessory/hair/dreadlocks
name = "Dreadlocks"
@@ -173,22 +233,66 @@
name = "Emo"
icon_state = "hair_emo"
+/datum/sprite_accessory/hair/emo2
+ name = "Emo 2"
+ icon_state = "hair_emo2"
+
+/datum/sprite_accessory/hair/emo_fringe
+ name = "Emo (Fringe)"
+ icon_state = "hair_emofringe"
+
+/datum/sprite_accessory/hair/emo_long
+ name = "Emo (Long)"
+ icon_state = "hair_emolong"
+
+/datum/sprite_accessory/hair/lowfade
+ name = "Fade (Low)"
+ icon_state = "hair_lowfade"
+
+/datum/sprite_accessory/hair/medfade
+ name = "Fade (Medium)"
+ icon_state = "hair_medfade"
+
+/datum/sprite_accessory/hair/highfade
+ name = "Fade (High)"
+ icon_state = "hair_highfade"
+
+/datum/sprite_accessory/hair/baldfade
+ name = "Fade (Bald)"
+ icon_state = "hair_baldfade"
+
+/datum/sprite_accessory/hair/nofade
+ name = "Fade (None)"
+ icon_state = "hair_nofade"
+
+/datum/sprite_accessory/hair/father
+ name = "Father"
+ icon_state = "hair_father"
+
/datum/sprite_accessory/hair/feather
name = "Feather"
icon_state = "hair_feather"
+/datum/sprite_accessory/hair/flair
+ name = "Flair"
+ icon_state = "hair_flair"
+
/datum/sprite_accessory/hair/sargeant
name = "Flat Top"
- icon_state = "hair_sargeant"
+ icon_state = "hair_sergeant"
/datum/sprite_accessory/hair/bigflattop
name = "Flat Top (Big)"
icon_state = "hair_bigflattop"
-/datum/sprite_accessory/hair/fag
+/datum/sprite_accessory/hair/fag //grimacing emoji
name = "Flow Hair"
icon_state = "hair_f"
+/datum/sprite_accessory/hair/fringetail
+ name = "Fringe Tail"
+ icon_state = "hair_fringetail"
+
/datum/sprite_accessory/hair/gelled
name = "Gelled Back"
icon_state = "hair_gelled"
@@ -205,10 +309,22 @@
name = "Half-banged Hair 2"
icon_state = "hair_halfbang2"
+/datum/sprite_accessory/hair/halfbangalt
+ name = "Half-banged Hair (Alt)"
+ icon_state = "hair_halfbang_alt"
+
+/datum/sprite_accessory/hair/halfshaved
+ name = "Half-shaved Hair"
+ icon_state = "hair_halfshaved"
+
/datum/sprite_accessory/hair/hedgehog
name = "Hedgehog Hair"
icon_state = "hair_hedgehog"
+/datum/sprite_accessory/hair/hightight
+ name = "High and Tight"
+ icon_state = "hair_hightight"
+
/datum/sprite_accessory/hair/himecut
name = "Hime Cut"
icon_state = "hair_himecut"
@@ -217,6 +333,10 @@
name = "Hime Cut 2"
icon_state = "hair_himecut2"
+/datum/sprite_accessory/hair/shorthime
+ name = "Hime Cut (Short)"
+ icon_state = "hair_shorthime"
+
/datum/sprite_accessory/hair/himeup
name = "Hime Updo"
icon_state = "hair_himeup"
@@ -225,16 +345,28 @@
name = "Hitop"
icon_state = "hair_hitop"
+/datum/sprite_accessory/hair/jade
+ name = "Jade"
+ icon_state = "hair_jade"
+
/datum/sprite_accessory/hair/jensen
- name = "Jensen Hair"
+ name = "Jensen"
icon_state = "hair_jensen"
+/datum/sprite_accessory/hair/joestar
+ name = "Joestar"
+ icon_state = "hair_joestar"
+
+/datum/sprite_accessory/hair/kagami
+ name = "Kagami"
+ icon_state = "hair_kagami"
+
/datum/sprite_accessory/hair/keanu
- name = "Keanu Hair"
+ name = "Keanu"
icon_state = "hair_keanu"
/datum/sprite_accessory/hair/kusangi
- name = "Kusanagi Hair"
+ name = "Kusanagi"
icon_state = "hair_kusanagi"
/datum/sprite_accessory/hair/long
@@ -249,6 +381,10 @@
name = "Long Hair 3"
icon_state = "hair_long3"
+/datum/sprite_accessory/hair/longalt
+ name = "Long Hair (Alt)"
+ icon_state = "hair_longeralt"
+
/datum/sprite_accessory/hair/long_over_eye
name = "Long Over Eye"
icon_state = "hair_longovereye"
@@ -269,6 +405,10 @@
name = "Long Side Part"
icon_state = "hair_longsidepart"
+/datum/sprite_accessory/hair/manbun
+ name = "Manbun"
+ icon_state = "hair_manbun"
+
/datum/sprite_accessory/hair/megaeyebrows
name = "Mega Eyebrows"
icon_state = "hair_megaeyebrows"
@@ -277,6 +417,10 @@
name = "Messy"
icon_state = "hair_messy"
+/datum/sprite_accessory/hair/modern
+ name = "Modern"
+ icon_state = "hair_modern"
+
/datum/sprite_accessory/hair/mohawk
name = "Mohawk"
icon_state = "hair_d"
@@ -285,6 +429,26 @@
name = "Mohawk (Reverse)"
icon_state = "hair_reversemohawk"
+/datum/sprite_accessory/hair/shavedmohawk
+ name = "Mohawk (Shaved)"
+ icon_state = "hair_shavedmohawk"
+
+/datum/sprite_accessory/hair/mohawk_unshaven
+ name = "Mohawk (Unshaven)"
+ icon_state = "hair_unshaven_mohawk"
+
+/datum/sprite_accessory/hair/mulder
+ name = "Mulder"
+ icon_state = "hair_mulder"
+
+/datum/sprite_accessory/hair/nia
+ name = "Nia"
+ icon_state = "hair_nia"
+
+/datum/sprite_accessory/hair/nitori
+ name = "Nitori"
+ icon_state = "hair_nitori"
+
/datum/sprite_accessory/hair/odango
name = "Odango"
icon_state = "hair_odango"
@@ -301,6 +465,10 @@
name = "Over Eye"
icon_state = "hair_shortovereye"
+/datum/sprite_accessory/hair/oxton
+ name = "Oxton"
+ icon_state = "hair_oxton"
+
//Donator item - fractious
/datum/sprite_accessory/hair/over_eye_fr
name = "Over Eye (fract)"
@@ -331,6 +499,10 @@
name = "Pixie Cut"
icon_state = "hair_pixie"
+/datum/sprite_accessory/hair/plait
+ name = "Plait"
+ icon_state = "hair_plait"
+
/datum/sprite_accessory/hair/pompadour
name = "Pompadour"
icon_state = "hair_pompadour"
@@ -383,10 +555,66 @@
name = "Ponytail (Side) 4"
icon_state = "hair_sidetail4"
+/datum/sprite_accessory/hair/spikytail
+ name = "Ponytail (Spiky)"
+ icon_state = "hair_spikyponytail"
+
+/datum/sprite_accessory/hair/poofy
+ name = "Poofy"
+ icon_state = "hair_poofy"
+
+/datum/sprite_accessory/hair/poofy2
+ name = "Poofy 2"
+ icon_state = "hair_poofy2"
+
/datum/sprite_accessory/hair/quiff
name = "Quiff"
icon_state = "hair_quiff"
+/datum/sprite_accessory/hair/ronin
+ name = "Ronin"
+ icon_state = "hair_ronin"
+
+/datum/sprite_accessory/hair/row
+ name = "Rows"
+ icon_state = "hair_rows1"
+
+/datum/sprite_accessory/hair/row2
+ name = "Rows 2"
+ icon_state = "hair_rows2"
+
+/datum/sprite_accessory/hair/rowbun
+ name = "Rows (Bun)"
+ icon_state = "hair_rowbun"
+
+/datum/sprite_accessory/hair/rowdualtail
+ name = "Rows (Pigtails)"
+ icon_state = "hair_rowdualtail"
+
+/datum/sprite_accessory/hair/rowbraid
+ name = "Rows (Braid)"
+ icon_state = "hair_rowbraid"
+
+/datum/sprite_accessory/hair/scully
+ name = "Scully"
+ icon_state = "hair_scully"
+
+/datum/sprite_accessory/hair/shaggy
+ name = "Shaggy"
+ icon_state = "hair_shaggy"
+
+/datum/sprite_accessory/hair/shaved
+ name = "Shaved"
+ icon_state = "hair_shaved"
+
+/datum/sprite_accessory/hair/shavedpart
+ name = "Shaved (Part)"
+ icon_state = "hair_shavedpart"
+
+/datum/sprite_accessory/hair/bangs_short
+ name = "Short Bangs"
+ icon_state = "hair_shortbangs"
+
/datum/sprite_accessory/hair/short
name = "Short Hair"
icon_state = "hair_a"
@@ -399,10 +627,30 @@
name = "Short Hair 3"
icon_state = "hair_shorthair3"
+/datum/sprite_accessory/hair/shorthair4
+ name = "Short Hair 4"
+ icon_state = "hair_shorthair4"
+
+/datum/sprite_accessory/hair/shorthair80s
+ name = "Short Hair 80s"
+ icon_state = "hair_80s"
+
+/datum/sprite_accessory/hair/shorthairrosa
+ name = "Short Hair Rosa"
+ icon_state = "hair_rosa"
+
+/datum/sprite_accessory/hair/stail
+ name = "Short Tail"
+ icon_state = "hair_stail"
+
/datum/sprite_accessory/hair/shoulderlength
name = "Shoulder-length Hair"
icon_state = "hair_b"
+/datum/sprite_accessory/hair/shy
+ name = "Shy"
+ icon_state = "hair_shy"
+
/datum/sprite_accessory/hair/sidecut
name = "Sidecut"
icon_state = "hair_sidecut"
@@ -411,6 +659,10 @@
name = "Skinhead"
icon_state = "hair_skinhead"
+/datum/sprite_accessory/hair/sleaze
+ name = "Sleaze"
+ icon_state = "hair_sleaze"
+
/datum/sprite_accessory/hair/protagonist
name = "Slightly Long Hair"
icon_state = "hair_protagonist"
@@ -435,14 +687,58 @@
name = "Swept Back Hair 2"
icon_state = "hair_swept2"
+/datum/sprite_accessory/hair/thinning
+ name = "Thinning"
+ icon_state = "hair_thinning"
+
+/datum/sprite_accessory/hair/thinningfront
+ name = "Thinning (Front)"
+ icon_state = "hair_thinningfront"
+
+/datum/sprite_accessory/hair/thinningrear
+ name = "Thinning (Rear)"
+ icon_state = "hair_thinningrear"
+
+/datum/sprite_accessory/hair/topknot
+ name = "Topknot"
+ icon_state = "hair_topknot"
+
+/datum/sprite_accessory/hair/toriyama
+ name = "Toriyama"
+ icon_state = "hair_toriyama"
+
+/datum/sprite_accessory/hair/toriyama2
+ name = "Toriyama 2"
+ icon_state = "hair_toriyama2"
+
/datum/sprite_accessory/hair/tressshoulder
name = "Tress Shoulder"
icon_state = "hair_tressshoulder"
+/datum/sprite_accessory/hair/trimmed
+ name = "Trimmed"
+ icon_state = "hair_trimmed"
+
+/datum/sprite_accessory/hair/trimflat
+ name = "Trimmed (Flat)"
+ icon_state = "hair_trimflat"
+
+/datum/sprite_accessory/hair/twintails
+ name = "Twintails"
+ icon_state = "hair_twintail"
+
/datum/sprite_accessory/hair/longtwintails
name = "Twintails (Long)"
icon_state = "hair_longstraighttwintails"
+/datum/sprite_accessory/hair/undercut
+ name = "Undercut"
+ icon_state = "hair_undercut"
+
+/datum/sprite_accessory/hair/unkempt
+ name = "Unkempt"
+ icon_state = "hair_unkempt"
+
/datum/sprite_accessory/hair/updo
name = "Updo"
icon_state = "hair_updo"
@@ -463,161 +759,22 @@
name = "Very Long with Fringe"
icon_state = "hair_vlongfringe"
-/*************** VIRGO PORTED HAIRS ****************************/
-#define VHAIR(_name, new_state) /datum/sprite_accessory/hair/##new_state/icon_state=#new_state;/datum/sprite_accessory/hair/##new_state/name = #_name + " (Virgo)"
-//VIRGO PORTED HAIRS
-VHAIR("Short Hair Rosa", hair_rosa_s)
-VHAIR("Short Hair 80s", hair_80s_s)
-VHAIR("Long Bedhead", hair_long_bedhead_s)
-VHAIR("Dave", hair_dave_s)
-VHAIR("Country", hair_country_s)
-VHAIR("Shy", hair_shy_s)
-VHAIR("Unshaven Mohawk", hair_unshaven_mohawk_s)
-VHAIR("Manbun", hair_manbun_s)
-VHAIR("Longer Bedhead", hair_longer_bedhead_s)
-VHAIR("Ponytail", hair_ponytail_s)
-VHAIR("Ziegler", hair_ziegler_s)
-VHAIR("Emo Fringe", hair_emofringe_s)
-VHAIR("Very Short Over Eye Alt", hair_veryshortovereyealternate_s)
-VHAIR("Shorthime", hair_shorthime_s)
-VHAIR("High Tight", hair_hightight_s)
-VHAIR("Thinning Front", hair_thinningfront_s)
-VHAIR("Big Afro", hair_bigafro_s)
-VHAIR("Afro", hair_afro_s)
-VHAIR("High Braid", hair_hbraid_s)
-VHAIR("Braid", hair_braid_s)
-VHAIR("Sargeant", hair_sargeant_s)
-VHAIR("Gelled", hair_gelled_s)
-VHAIR("Kagami", hair_kagami_s)
-VHAIR("ShortTail", hair_stail_s)
-VHAIR("Gentle", hair_gentle_s)
-VHAIR("Grande", hair_grande_s)
-VHAIR("Bobcurl", hair_bobcurl_s)
-VHAIR("Pompadeur", hair_pompadour_s)
-VHAIR("Plait", hair_plait_s)
-VHAIR("Long", hair_long_s)
-VHAIR("Rattail", hair_rattail_s)
-VHAIR("Tajspiky", hair_tajspiky_s)
-VHAIR("Messy", hair_messy_s)
-VHAIR("Bangs", hair_bangs_s)
-VHAIR("TBraid", hair_tbraid_s)
-VHAIR("Toriyama2", hair_toriyama2_s)
-VHAIR("CIA", hair_cia_s)
-VHAIR("Mulder", hair_mulder_s)
-VHAIR("Scully", hair_scully_s)
-VHAIR("Nitori", hair_nitori_s)
-VHAIR("Joestar", hair_joestar_s)
-VHAIR("Ponytail4", hair_ponytail4_s)
-VHAIR("Ponytail5", hair_ponytail5_s)
-VHAIR("Beehive2", hair_beehive2_s)
-VHAIR("Short Braid", hair_shortbraid_s)
-VHAIR("Reverse Mohawk", hair_reversemohawk_s)
-VHAIR("SHort Bangs", hair_shortbangs_s)
-VHAIR("Half Shaved", hair_halfshaved_s)
-VHAIR("Longer Alt 2", hair_longeralt2_s)
-VHAIR("Bun", hair_bun_s)
-VHAIR("Curly", hair_curly_s)
-VHAIR("Victory", hair_victory_s)
-VHAIR("Ponytail6", hair_ponytail6_s)
-VHAIR("Undercut3", hair_undercut3_s)
-VHAIR("Bobcut Alt", hair_bobcultalt_s)
-VHAIR("Fingerwave", hair_fingerwave_s)
-VHAIR("Oxton", hair_oxton_s)
-VHAIR("Poofy2", hair_poofy2_s)
-VHAIR("Fringe Tail", hair_fringetail_s)
-VHAIR("Bun3", hair_bun3_s)
-VHAIR("Wisp", hair_wisp_s)
-VHAIR("Undercut2", hair_undercut2_s)
-VHAIR("TBob", hair_tbob_s)
-VHAIR("Spiky Ponytail", hair_spikyponytail_s)
-VHAIR("Rowbun", hair_rowbun_s)
-VHAIR("Rowdualtail", hair_rowdualtail_s)
-VHAIR("Rowbraid", hair_rowbraid_s)
-VHAIR("Shaved Mohawk", hair_shavedmohawk_s)
-VHAIR("Topknot", hair_topknot_s)
-VHAIR("Ronin", hair_ronin_s)
-VHAIR("Bowlcut2", hair_bowlcut2_s)
-VHAIR("Thinning Rear", hair_thinningrear_s)
-VHAIR("Thinning", hair_thinning_s)
-VHAIR("Jade", hair_jade_s)
-VHAIR("Bedhead", hair_bedhead_s)
-VHAIR("Dreadlocks", hair_dreads_s)
-VHAIR("Very Long", hair_vlong_s)
-VHAIR("Jensen", hair_jensen_s)
-VHAIR("Halfbang", hair_halfbang_s)
-VHAIR("Kusangi", hair_kusangi_s)
-VHAIR("Ponytail", hair_ponytail_s)
-VHAIR("Ponytail3", hair_ponytail3_s)
-VHAIR("Halfbang Alt", hair_halfbang_alt_s)
-VHAIR("Bedhead V2", hair_bedheadv2_s)
-VHAIR("Long Fringe", hair_longfringe_s)
-VHAIR("Flair", hair_flair_s)
-VHAIR("Bedhead V3", hair_bedheadv3_s)
-VHAIR("Himecut", hair_himecut_s)
-VHAIR("Curls", hair_curls_s)
-VHAIR("Very Long Fringe", hair_vlongfringe_s)
-VHAIR("Longest", hair_longest_s)
-VHAIR("Father", hair_father_s)
-VHAIR("Emo Long", hair_emolong_s)
-VHAIR("Short Hair 3", hair_shorthair3_s)
-VHAIR("Double Bun", hair_doublebun_s)
-VHAIR("Sleeze", hair_sleeze_s)
-VHAIR("Twintail", hair_twintail_s)
-VHAIR("Emo 2", hair_emo2_s)
-VHAIR("Low Fade", hair_lowfade_s)
-VHAIR("Med Fade", hair_medfade_s)
-VHAIR("High Fade", hair_highfade_s)
-VHAIR("Bald Fade", hair_baldfade_s)
-VHAIR("No Fade", hair_nofade_s)
-VHAIR("Trim Flat", hair_trimflat_s)
-VHAIR("Shaved", hair_shaved_s)
-VHAIR("Trimmed", hair_trimmed_s)
-VHAIR("Tight Bun", hair_tightbun_s)
-VHAIR("Short Hair 4", hair_d_s)
-VHAIR("Short Hair 5", hair_e_s)
-VHAIR("Short Hair 6", hair_f_s)
-VHAIR("Skinhead", hair_skinhead_s)
-VHAIR("Afro2", hair_afro2_s)
-VHAIR("Bobcut", hair_bobcut_s)
-VHAIR("Emo", hair_emo_s)
-VHAIR("Long Over Eye", hair_longovereye_s)
-VHAIR("Feather", hair_feather_s)
-VHAIR("Hitop", hair_hitop_s)
-VHAIR("Short Over Eye", hair_shortoverye_s)
-VHAIR("Straight", hair_straight_s)
-VHAIR("Buzzcut", hair_buzzcut_s)
-VHAIR("Combover", hair_combover_s)
-VHAIR("Crewcut", hair_crewcut_s)
-VHAIR("Devillock", hair_devilock_s)
-VHAIR("Clean", hair_clean_s)
-VHAIR("Shaggy", hair_shaggy_s)
-VHAIR("Updo", hair_updo_s)
-VHAIR("Mohawk", hair_mohawk_s)
-VHAIR("Odango", hair_odango_s)
-VHAIR("Ombre", hair_ombre_s)
-VHAIR("Parted", hair_parted_s)
-VHAIR("Quiff", hair_quiff_s)
-VHAIR("Volaju", hair_volaju_s)
-VHAIR("Bun2", hair_bun2_s)
-VHAIR("Rows1", hair_rows1_s)
-VHAIR("Rows2", hair_rows2_s)
-VHAIR("Dandy Pompadour", hair_dandypompadour_s)
-VHAIR("Poofy", hair_poofy_s)
-VHAIR("Toriyama", hair_toriyama_s)
-VHAIR("Drillruru", hair_drillruru_s)
-VHAIR("Bowlcut", hair_bowlcut_s)
-VHAIR("Coffee House", hair_coffeehouse_s)
-VHAIR("Family Man", hair_thefamilyman_s)
-VHAIR("Shaved Part", hair_shavedpart_s)
-VHAIR("Modern", hair_modern_s)
-VHAIR("One Shoulder", hair_oneshoulder_s)
-VHAIR("Very Short Over Eye", hair_veryshortovereye_s)
-VHAIR("Unkept", hair_unkept_s)
-VHAIR("Wife", hair_wife_s)
-VHAIR("Nia", hair_nia_s)
-VHAIR("Undercut", hair_undercut_s)
-VHAIR("Bobcut Alt", hair_bobcutalt_s)
-VHAIR("Short Hair 4 alt", hair_shorthair4_s)
-VHAIR("Tressshoulder", hair_tressshoulder_s)
- //END
-#undef VHAIR
\ No newline at end of file
+/datum/sprite_accessory/hair/short_oe
+ name = "Very Short Over Eye"
+ icon_state = "hair_veryshortovereye"
+
+/datum/sprite_accessory/hair/short_oe_alt
+ name = "Very Short Over Eye (Alt)"
+ icon_state = "hair_veryshortovereyealternate"
+
+/datum/sprite_accessory/hair/volaju
+ name = "Volaju"
+ icon_state = "hair_volaju"
+
+/datum/sprite_accessory/hair/wisp
+ name = "Wisp"
+ icon_state = "hair_wisp"
+
+/datum/sprite_accessory/hair/ziegler
+ name = "Ziegler"
+ icon_state = "hair_ziegler"
\ No newline at end of file
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index f2ea4f2b01..15cab5fc64 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -389,6 +389,7 @@
if(resilience)
actual_trauma.resilience = resilience
SSblackbox.record_feedback("tally", "traumas", 1, actual_trauma.type)
+ return actual_trauma
//Add a random trauma of a certain subtype
/obj/item/organ/brain/proc/gain_trauma_type(brain_trauma_type = /datum/brain_trauma, resilience)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
index 1333bc4399..6141a97c12 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
@@ -13,7 +13,7 @@
var/alt_inhands_file = 'icons/mob/alienqueen.dmi'
-/mob/living/carbon/alien/humanoid/royal/can_inject()
+/mob/living/carbon/alien/humanoid/royal/can_inject(mob/user, error_msg, target_zone, penetrate_thick = FALSE, bypass_immunity = FALSE)
return 0
/mob/living/carbon/alien/humanoid/royal/queen
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index a6595100a1..d6f6b6d9ae 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -44,7 +44,8 @@
if(M.occupant == src)
M.go_out()
- dna.species.spec_death(gibbed, src)
+ if(!QDELETED(dna)) //The gibbed param is bit redundant here since dna won't exist at this point if they got deleted.
+ dna.species.spec_death(gibbed, src)
if(SSticker.HasRoundStarted())
SSblackbox.ReportDeath(src)
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 8edd5847de..ef8a745b89 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -385,20 +385,17 @@
else if(isobserver(user) && traitstring)
. += "Traits: [traitstring]"
- if(print_flavor_text())
- if(get_visible_name() == "Unknown") //Are we sure we know who this is? Don't show flavor text unless we can recognize them. Prevents certain metagaming with impersonation.
- . += "...?"
- else if(skipface) //Sometimes we're not unknown, but impersonating someone in a hardsuit, let's not reveal our flavor text then either.
- . += "...?"
- else
- . += "[print_flavor_text()]"
- if(print_flavor_text_2())
- if(get_visible_name() == "Unknown") //Are we sure we know who this is? Don't show flavor text unless we can recognize them. Prevents certain metagaming with impersonation.
- . += "...?"
- else if(skipface) //Sometimes we're not unknown, but impersonating someone in a hardsuit, let's not reveal our flavor text then either.
- . += "...?"
- else
- . += "[print_flavor_text_2()]"
+ //No flavor text unless the face can be seen. Prevents certain metagaming with impersonation.
+ var/invisible_man = skipface || get_visible_name() == "Unknown"
+ if(invisible_man)
+ . += "...?"
+ else
+ var/flavor = print_flavor_text()
+ if(flavor)
+ . += flavor
+ var/temp_flavor = print_flavor_text_2()
+ if(temp_flavor)
+ . += temp_flavor
. += "*---------*"
/mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects!
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 934e0f08dc..accaab3ac1 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -336,7 +336,8 @@
if(bomb_armor < EXPLODE_GIB_THRESHOLD) //gibs the mob if their bomb armor is lower than EXPLODE_GIB_THRESHOLD
for(var/I in contents)
var/atom/A = I
- A.ex_act(severity)
+ if(!QDELETED(A))
+ A.ex_act(severity)
gib()
return
else
diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
index 2a5ec51b55..eb1e194c0f 100644
--- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
@@ -849,6 +849,8 @@
linked_mobs.Add(M)
if(!selflink)
to_chat(M, "You are now connected to [slimelink_owner.real_name]'s Slime Link.")
+ RegisterSignal(M, COMSIG_MOB_DEATH , .proc/unlink_mob)
+ RegisterSignal(M, COMSIG_PARENT_QDELETING, .proc/unlink_mob)
var/datum/action/innate/linked_speech/action = new(src)
linked_actions.Add(action)
action.Grant(M)
@@ -858,6 +860,7 @@
var/link_id = linked_mobs.Find(M)
if(!(link_id))
return
+ UnregisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING))
var/datum/action/innate/linked_speech/action = linked_actions[link_id]
action.Remove(M)
to_chat(M, "You are no longer connected to [slimelink_owner.real_name]'s Slime Link.")
@@ -890,18 +893,11 @@
Remove(H)
return
- if(QDELETED(H) || H.stat == DEAD)
- species.unlink_mob(H)
- return
-
if(message)
var/msg = "\[[species.slimelink_owner.real_name]'s Slime Link\] [H]: [message]"
log_directed_talk(H, species.slimelink_owner, msg, LOG_SAY, "slime link")
for(var/X in species.linked_mobs)
var/mob/living/M = X
- if(QDELETED(M) || M.stat == DEAD)
- species.unlink_mob(M)
- continue
to_chat(M, msg)
for(var/X in GLOB.dead_mob_list)
diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
index 5a7710fe29..4a7399f287 100644
--- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
@@ -54,7 +54,7 @@
..()
/datum/species/plasmaman/before_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE)
- var/current_job = J.title
+ var/current_job = J?.title
var/datum/outfit/plasmaman/O = new /datum/outfit/plasmaman
switch(current_job)
if("Chaplain")
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index c4088317b1..cd68dabbef 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -382,9 +382,6 @@ There are several things that need to be remembered:
if(wear_suit)
var/obj/item/clothing/suit/S = wear_suit
- var/item_level_support = FALSE // LISTEN! If you must degrade the code with further snowflake checks, at least keep it compatible with worn non-clothing items!
- if(!istype(S))
- item_level_support = TRUE
wear_suit.screen_loc = ui_oclothing
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown)
@@ -400,7 +397,7 @@ There are several things that need to be remembered:
if("taur" in dna.species.mutant_bodyparts)
T = GLOB.taur_list[dna.features["taur"]]
- if(!item_level_support && S.mutantrace_variation)
+ if(S.mutantrace_variation)
if(T?.taur_mode)
var/init_worn_icon = worn_icon
variation_flag |= S.mutantrace_variation & T.taur_mode || S.mutantrace_variation & T.alt_taur_mode
diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm
index 33b9dffaf0..e83f67f796 100644
--- a/code/modules/mob/living/carbon/monkey/life.dm
+++ b/code/modules/mob/living/carbon/monkey/life.dm
@@ -30,6 +30,9 @@
/mob/living/carbon/monkey/handle_mutations_and_radiation()
if(radiation)
+ if(radiation > RAD_MOB_MUTATE && prob((radiation - RAD_MOB_MUTATE) / 25))
+ gorillize()
+ return
if(radiation > RAD_MOB_KNOCKDOWN && prob(RAD_MOB_KNOCKDOWN_PROB))
if(!IsKnockdown())
emote("collapse")
@@ -41,10 +44,6 @@
randmutb()
emote("gasp")
domutcheck()
-
- if(radiation > RAD_MOB_MUTATE * 2 && prob(50))
- gorillize()
- return
if(radiation > RAD_MOB_VOMIT && prob(RAD_MOB_VOMIT_PROB))
vomit(10, TRUE)
return ..()
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 72b7b580f7..90ada3d718 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -90,8 +90,10 @@
if(now_pushing)
return TRUE
+ var/they_can_move = TRUE
if(isliving(M))
var/mob/living/L = M
+ they_can_move = L.canmove //L.mobility_flags & MOBILITY_MOVE
//Also spread diseases
for(var/thing in diseases)
var/datum/disease/D = thing
@@ -144,13 +146,17 @@
return 1
if(!M.buckled && !M.has_buckled_mobs())
- var/mob_swap
- //the puller can always swap with its victim if on grab intent
- if(M.pulledby == src && a_intent == INTENT_GRAB)
- mob_swap = 1
- //restrained people act if they were on 'help' intent to prevent a person being pulled from being separated from their puller
- else if((M.restrained() || M.a_intent == INTENT_HELP) && (restrained() || a_intent == INTENT_HELP))
- mob_swap = 1
+ var/mob_swap = FALSE
+ var/too_strong = (M.move_resist > move_force) //can't swap with immovable objects unless they help us
+ if(!they_can_move) //we have to physically move them
+ if(!too_strong)
+ mob_swap = TRUE
+ else
+ if(M.pulledby == src && a_intent == INTENT_GRAB)
+ mob_swap = TRUE
+ //restrained people act if they were on 'help' intent to prevent a person being pulled from being separated from their puller
+ else if((M.restrained() || M.a_intent == INTENT_HELP) && (restrained() || a_intent == INTENT_HELP))
+ mob_swap = TRUE
if(mob_swap)
//switch our position with M
if(loc && !loc.Adjacent(M.loc))
@@ -453,7 +459,7 @@
return ret
// Living mobs use can_inject() to make sure that the mob is not syringe-proof in general.
-/mob/living/proc/can_inject()
+/mob/living/proc/can_inject(mob/user, error_msg, target_zone, penetrate_thick = FALSE, bypass_immunity = FALSE)
return TRUE
/mob/living/is_injectable(allowmobs = TRUE)
diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm
index 15a04235cc..1147042c8c 100644
--- a/code/modules/mob/living/silicon/ai/life.dm
+++ b/code/modules/mob/living/silicon/ai/life.dm
@@ -53,11 +53,11 @@
if(NONE)
return FALSE
if(POWER_REQ_ALL)
- return !T || !A || ((!A.power_equip || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha)))
+ return !T || !A || ((!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha)))
if(POWER_REQ_CLOCKCULT)
for(var/obj/effect/clockwork/sigil/transmission/ST in range(src, SIGIL_ACCESS_RANGE))
return FALSE
- return !T || !A || (!istype(T, /turf/open/floor/clockwork) && (!A.power_equip || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha)))
+ return !T || !A || (!istype(T, /turf/open/floor/clockwork) && (!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha)))
/mob/living/silicon/ai/updatehealth()
if(status_flags & GODMODE)
@@ -100,7 +100,7 @@
sleep(50)
var/turf/T = get_turf(src)
var/area/AIarea = get_area(src)
- if(AIarea && AIarea.power_equip)
+ if(AIarea && AIarea.powered(EQUIP))
if(!isspaceturf(T))
ai_restore_power()
return
@@ -120,7 +120,7 @@
var/PRP //like ERP with the code, at least this stuff is no more 4x sametext
for (PRP=1, PRP<=4, PRP++)
T = get_turf(src)
- AIarea = get_area(src)
+ AIarea = get_base_area(src)
if(AIarea)
for (var/obj/machinery/power/apc/APC in AIarea)
if (!(APC.stat & BROKEN))
@@ -134,7 +134,7 @@
to_chat(src, "Lost connection with the APC!")
aiRestorePowerRoutine = POWER_RESTORATION_SEARCH_APC
return
- if(AIarea.power_equip)
+ if(AIarea.powered(EQUIP))
if(!isspaceturf(T))
ai_restore_power()
return
diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm
index 8215f84c50..55f4bdd65d 100644
--- a/code/modules/mob/living/silicon/pai/software.dm
+++ b/code/modules/mob/living/silicon/pai/software.dm
@@ -438,7 +438,7 @@
if(1)
. += "Medical Record
"
if(medicalActive1 in GLOB.data_core.general)
- . += "Name: [medicalActive1.fields["name"]] ID: [medicalActive1.fields["id"]]
\nSex: [medicalActive1.fields["sex"]]
\nAge: [medicalActive1.fields["age"]]
\nFingerprint: [medicalActive1.fields["fingerprint"]]
\nPhysical Status: [medicalActive1.fields["p_stat"]]
\nMental Status: [medicalActive1.fields["m_stat"]]
"
+ . += "Name: [medicalActive1.fields["name"]] ID: [medicalActive1.fields["id"]]
\nGender: [medicalActive1.fields["gender"]]
\nAge: [medicalActive1.fields["age"]]
\nFingerprint: [medicalActive1.fields["fingerprint"]]
\nPhysical Status: [medicalActive1.fields["p_stat"]]
\nMental Status: [medicalActive1.fields["m_stat"]]
"
else
. += "Requested medical record not found.
"
if(medicalActive2 in GLOB.data_core.medical)
@@ -460,7 +460,7 @@
if(1)
. += "Security Record
"
if(securityActive1 in GLOB.data_core.general)
- . += "Name: [securityActive1.fields["name"]] ID: [securityActive1.fields["id"]]
\nSex: [securityActive1.fields["sex"]]
\nAge: [securityActive1.fields["age"]]
\nRank: [securityActive1.fields["rank"]]
\nFingerprint: [securityActive1.fields["fingerprint"]]
\nPhysical Status: [securityActive1.fields["p_stat"]]
\nMental Status: [securityActive1.fields["m_stat"]]
"
+ . += "Name: [securityActive1.fields["name"]] ID: [securityActive1.fields["id"]]
\nGender: [securityActive1.fields["gender"]]
\nAge: [securityActive1.fields["age"]]
\nRank: [securityActive1.fields["rank"]]
\nFingerprint: [securityActive1.fields["fingerprint"]]
\nPhysical Status: [securityActive1.fields["p_stat"]]
\nMental Status: [securityActive1.fields["m_stat"]]
"
else
. += "Requested security record not found,
"
if(securityActive2 in GLOB.data_core.security)
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 33c66079d5..e5881848d5 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -151,7 +151,7 @@
for(var/key in alarm_types_clear)
alarm_types_clear[key] = 0
-/mob/living/silicon/can_inject(mob/user, error_msg)
+/mob/living/silicon/can_inject(mob/user, error_msg, target_zone, penetrate_thick = FALSE, bypass_immunity = FALSE)
if(error_msg)
to_chat(user, "[p_their(TRUE)] outer shell is too tough.")
return FALSE
diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm
index 2371cfd7f1..554d03991a 100644
--- a/code/modules/mob/living/simple_animal/friendly/dog.dm
+++ b/code/modules/mob/living/simple_animal/friendly/dog.dm
@@ -207,7 +207,11 @@
switch(add_to)
if("collar")
- add_collar(usr.get_active_held_item(), usr)
+ var/obj/item/clothing/neck/petcollar/P = usr.get_active_held_item()
+ if(!istype(P))
+ to_chat(usr,"That's not a collar.")
+ return
+ add_collar(P, usr)
update_corgi_fluff()
if(BODY_ZONE_HEAD)
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 71465f23f9..65ee6a69f2 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
@@ -479,31 +479,33 @@ Difficulty: Very Hard
NewTerrainTables = /obj/structure/table/abductor
/obj/machinery/anomalous_crystal/theme_warp/ActivationReaction(mob/user, method)
- if(..())
- var/area/A = get_area(src)
- if(!A.outdoors && !(A in affected_targets))
- for(var/atom/Stuff in A)
- if(isturf(Stuff))
- var/turf/T = Stuff
- if((isspaceturf(T) || isfloorturf(T)) && NewTerrainFloors)
- var/turf/open/O = T.ChangeTurf(NewTerrainFloors, flags = CHANGETURF_INHERIT_AIR)
- if(prob(florachance) && NewFlora.len && !is_blocked_turf(O, TRUE))
- var/atom/Picked = pick(NewFlora)
- new Picked(O)
- continue
- if(iswallturf(T) && NewTerrainWalls)
- T.ChangeTurf(NewTerrainWalls)
- continue
- if(istype(Stuff, /obj/structure/chair) && NewTerrainChairs)
- var/obj/structure/chair/Original = Stuff
- var/obj/structure/chair/C = new NewTerrainChairs(Original.loc)
- C.setDir(Original.dir)
- qdel(Stuff)
- continue
- if(istype(Stuff, /obj/structure/table) && NewTerrainTables)
- new NewTerrainTables(Stuff.loc)
- continue
- affected_targets += A
+ . = ..()
+ if(!.)
+ return
+ for(var/i in get_sub_areas(src))
+ var/area/A = i
+ if(A.outdoors || (A in affected_targets))
+ continue
+ affected_targets += A
+ for(var/stuff in A)
+ var/atom/target = stuff
+ if(isturf(target))
+ var/turf/T = target
+ if((isspaceturf(T) || isfloorturf(T)) && NewTerrainFloors)
+ var/turf/open/O = T.ChangeTurf(NewTerrainFloors, flags = CHANGETURF_INHERIT_AIR)
+ if(NewFlora.len && prob(florachance) && !is_blocked_turf(O, TRUE))
+ var/atom/Picked = pick(NewFlora)
+ new Picked(O)
+ else if(iswallturf(T) && NewTerrainWalls)
+ T.ChangeTurf(NewTerrainWalls)
+ else if(NewTerrainChairs && istype(target, /obj/structure/chair))
+ var/obj/structure/chair/Original = target
+ var/obj/structure/chair/C = new NewTerrainChairs(Original.loc)
+ C.setDir(Original.dir)
+ qdel(target)
+ else if(NewTerrainTables && istype(target, /obj/structure/table))
+ new NewTerrainTables(target.loc)
+ qdel(target)
/obj/machinery/anomalous_crystal/emitter //Generates a projectile when interacted with
observer_desc = "This crystal generates a projectile when activated."
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
index 49b56d0950..43ce940d57 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
@@ -170,7 +170,7 @@ Difficulty: Medium
to_chat(user, "The staff is still recharging!")
return
- var/area/user_area = get_area(user)
+ var/area/user_area = get_base_area(user)
var/turf/user_turf = get_turf(user)
if(!user_area || !user_turf || (user_area.type in excluded_areas))
to_chat(user, "Something is preventing you from using the staff here.")
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 6082bdf705..8b2ef507d9 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -84,6 +84,7 @@
var/datum/personal_crafting/handcrafting
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever), AI_Z_OFF (Temporarily off due to nonpresence of players)
+ var/can_have_ai = TRUE //once we have become sentient, we can never go back
var/shouldwakeup = FALSE //convenience var for forcibly waking up an idling AI on next check.
@@ -425,6 +426,9 @@
canmove = FALSE
else
canmove = value_otherwise
+ if(!canmove) // !(mobility_flags & MOBILITY_MOVE)
+ walk(src, 0) //stop mid walk
+
update_transform()
update_action_buttons_icon()
return canmove
@@ -443,6 +447,7 @@
/mob/living/simple_animal/proc/sentience_act() //Called when a simple animal gains sentience via gold slime potion
toggle_ai(AI_OFF) // To prevent any weirdness.
+ can_have_ai = FALSE
/mob/living/simple_animal/update_sight()
if(!client)
@@ -557,6 +562,8 @@
LoadComponent(/datum/component/riding)
/mob/living/simple_animal/proc/toggle_ai(togglestatus)
+ if(!can_have_ai && (togglestatus != AI_OFF))
+ return
if (AIStatus != togglestatus)
if (togglestatus > 0 && togglestatus < 5)
if (togglestatus == AI_Z_OFF || AIStatus == AI_Z_OFF)
diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm
index 29b4689317..fd6cecf926 100644
--- a/code/modules/mob/living/simple_animal/slime/life.dm
+++ b/code/modules/mob/living/simple_animal/slime/life.dm
@@ -41,7 +41,7 @@
AIproc = 1
while(AIproc && stat != DEAD && (attacked || hungry || rabid || buckled))
- if(buckled) // can't eat AND have this little process at the same time
+ if(!canmove) // !(mobility_flags & MOBILITY_MOVE) //also covers buckling. Not sure why buckled is in the while condition if we're going to immediately break, honestly
break
if(!Target || client)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 630ce54261..33cc2c6e20 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -456,8 +456,10 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
return
/mob/proc/transfer_ckey(mob/new_mob, send_signal = TRUE)
- if(!ckey || !new_mob)
- CRASH("transfer_ckey() called [ckey ? "" : "on a ckey-less mob[new_mob ? "" : " and "]"][new_mob ? "" : "without a valid mob target"]!")
+ if(!new_mob || (!ckey && new_mob.ckey))
+ CRASH("transfer_ckey() called [new_mob ? "on ckey-less mob with a player mob as target" : "without a valid mob target"]!")
+ if(!ckey)
+ return
SEND_SIGNAL(new_mob, COMSIG_MOB_PRE_PLAYER_CHANGE, new_mob, src)
if (client && client.prefs && client.prefs.auto_ooc)
if (client.prefs.chat_toggles & CHAT_OOC && isliving(new_mob))
@@ -964,4 +966,4 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
/mob/setMovetype(newval)
. = ..()
- update_movespeed(FALSE)
\ No newline at end of file
+ update_movespeed(FALSE)
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 8dae1f30f7..1402b78908 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -26,7 +26,7 @@
var/computer_id = null
var/list/logging = list()
- var/obj/machinery/machine = null
+ var/atom/machine = null
var/next_move = null
var/create_area_cooldown
diff --git a/code/modules/modular_computers/computers/item/computer_damage.dm b/code/modules/modular_computers/computers/item/computer_damage.dm
index 001cf3aa65..6664b449bd 100644
--- a/code/modules/modular_computers/computers/item/computer_damage.dm
+++ b/code/modules/modular_computers/computers/item/computer_damage.dm
@@ -23,6 +23,8 @@
new /obj/item/stack/sheet/metal(newloc, round(steel_sheet_cost/2))
for(var/C in all_components)
var/obj/item/computer_hardware/H = all_components[C]
+ if(QDELETED(H))
+ return
uninstall_component(H)
H.forceMove(newloc)
if(prob(25))
diff --git a/code/modules/modular_computers/computers/item/laptop_presets.dm b/code/modules/modular_computers/computers/item/laptop_presets.dm
index 102397037b..e50392e3b3 100644
--- a/code/modules/modular_computers/computers/item/laptop_presets.dm
+++ b/code/modules/modular_computers/computers/item/laptop_presets.dm
@@ -13,11 +13,11 @@
-/obj/item/modular_computer/laptop/preset/civillian
+/obj/item/modular_computer/laptop/preset/civilian
desc = "A low-end laptop often used for personal recreation."
-/obj/item/modular_computer/laptop/preset/civillian/install_programs()
+/obj/item/modular_computer/laptop/preset/civilian/install_programs()
var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD]
hard_drive.store_file(new/datum/computer_file/program/chatclient())
- hard_drive.store_file(new/datum/computer_file/program/nttransfer())
\ No newline at end of file
+ hard_drive.store_file(new/datum/computer_file/program/nttransfer())
diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm
index aa1fd7dbfb..4120c81a78 100644
--- a/code/modules/paperwork/filingcabinet.dm
+++ b/code/modules/paperwork/filingcabinet.dm
@@ -126,7 +126,7 @@
continue
var/obj/item/paper/P = new /obj/item/paper(src)
P.info = "Security Record
"
- P.info += "Name: [G.fields["name"]] ID: [G.fields["id"]]
\nSex: [G.fields["sex"]]
\nAge: [G.fields["age"]]
\nFingerprint: [G.fields["fingerprint"]]
\nPhysical Status: [G.fields["p_stat"]]
\nMental Status: [G.fields["m_stat"]]
"
+ P.info += "Name: [G.fields["name"]] ID: [G.fields["id"]]
\nGender: [G.fields["gender"]]
\nAge: [G.fields["age"]]
\nFingerprint: [G.fields["fingerprint"]]
\nPhysical Status: [G.fields["p_stat"]]
\nMental Status: [G.fields["m_stat"]]
"
P.info += "
\nSecurity Data
\nCriminal Status: [S.fields["criminal"]]
\n
\nMinor Crimes: [S.fields["mi_crim"]]
\nDetails: [S.fields["mi_crim_d"]]
\n
\nMajor Crimes: [S.fields["ma_crim"]]
\nDetails: [S.fields["ma_crim_d"]]
\n
\nImportant Notes:
\n\t[S.fields["notes"]]
\n
\nComments/Log
"
var/counter = 1
while(S.fields["com_[counter]"])
@@ -159,7 +159,7 @@
continue
var/obj/item/paper/P = new /obj/item/paper(src)
P.info = "Medical Record
"
- P.info += "Name: [G.fields["name"]] ID: [G.fields["id"]]
\nSex: [G.fields["sex"]]
\nAge: [G.fields["age"]]
\nFingerprint: [G.fields["fingerprint"]]
\nPhysical Status: [G.fields["p_stat"]]
\nMental Status: [G.fields["m_stat"]]
"
+ P.info += "Name: [G.fields["name"]] ID: [G.fields["id"]]
\nGender: [G.fields["gender"]]
\nAge: [G.fields["age"]]
\nFingerprint: [G.fields["fingerprint"]]
\nPhysical Status: [G.fields["p_stat"]]
\nMental Status: [G.fields["m_stat"]]
"
P.info += "
\nMedical Data
\nBlood Type: [M.fields["blood_type"]]
\nDNA: [M.fields["b_dna"]]
\n
\nMinor Disabilities: [M.fields["mi_dis"]]
\nDetails: [M.fields["mi_dis_d"]]
\n
\nMajor Disabilities: [M.fields["ma_dis"]]
\nDetails: [M.fields["ma_dis_d"]]
\n
\nAllergies: [M.fields["alg"]]
\nDetails: [M.fields["alg_d"]]
\n
\nCurrent Diseases: [M.fields["cdi"]] (per disease info placed in log/comment section)
\nDetails: [M.fields["cdi_d"]]
\n
\nImportant Notes:
\n\t[M.fields["notes"]]
\n
\nComments/Log
"
var/counter = 1
while(M.fields["com_[counter]"])
diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm
index cfd028c4df..076d8b026a 100644
--- a/code/modules/paperwork/paperplane.dm
+++ b/code/modules/paperwork/paperplane.dm
@@ -34,7 +34,9 @@
/obj/item/paperplane/handle_atom_del(atom/A)
if(A == internalPaper)
+ var/obj/item/paper/P = internalPaper
internalPaper = null
+ P.moveToNullspace() //So we're not deleting it twice when deleting our contents.
if(!QDELETED(src))
qdel(src)
return ..()
diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm
index 125219d809..140167c2f0 100644
--- a/code/modules/photography/camera/camera.dm
+++ b/code/modules/photography/camera/camera.dm
@@ -33,6 +33,8 @@
var/picture_size_y_min = 1
var/picture_size_x_max = 4
var/picture_size_y_max = 4
+ var/can_customise = TRUE
+ var/default_picture_name
/obj/item/camera/attack_self(mob/user)
if(!disk)
@@ -199,8 +201,10 @@
user.put_in_hands(p)
pictures_left--
to_chat(user, "[pictures_left] photos left.")
- var/customize = alert(user, "Do you want to customize the photo?", "Customization", "Yes", "No")
- if(customize == "Yes")
+ var/customise = "No"
+ if(can_customise)
+ customise = alert(user, "Do you want to customize the photo?", "Customization", "Yes", "No")
+ if(customise == "Yes")
var/name1 = stripped_input(user, "Set a name for this photo, or leave blank. 32 characters max.", "Name", max_length = 32)
var/desc1 = stripped_input(user, "Set a description to add to photo, or leave blank. 128 characters max.", "Caption", max_length = 128)
var/caption = stripped_input(user, "Set a caption for this photo, or leave blank. 256 characters max.", "Caption", max_length = 256)
@@ -210,6 +214,10 @@
picture.picture_desc = "[desc1] - [picture.picture_desc]"
if(caption)
picture.caption = caption
+ else
+ if(default_picture_name)
+ picture.picture_name = default_picture_name
+
p.set_picture(picture, TRUE, TRUE)
if(CONFIG_GET(flag/picture_logging_camera))
picture.log_to_file()
\ No newline at end of file
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index b7cbcdb9d8..78294e988d 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -56,6 +56,8 @@
integrity_failure = 50
var/damage_deflection = 10
resistance_flags = FIRE_PROOF
+ armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 100, "bomb" = 30, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 50)
+ req_access = list(ACCESS_ENGINE_EQUIP)
interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON
var/lon_range = 1.5
@@ -148,12 +150,40 @@
if(terminal)
terminal.connect_to_network()
-/obj/machinery/power/apc/New(turf/loc, var/ndir, var/building=0)
- if (!req_access)
- req_access = list(ACCESS_ENGINE_EQUIP)
- if (!armor)
- armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 100, "bomb" = 30, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 50)
- ..()
+/obj/machinery/power/apc/Initialize(mapload, ndir, building = FALSE)
+ . = ..()
+ var/area/A = get_base_area(src)
+ if(!building)
+ has_electronics = APC_ELECTRONICS_SECURED
+ // is starting with a power cell installed, create it and set its charge level
+ if(cell_type)
+ cell = new cell_type
+ cell.charge = start_charge * cell.maxcharge / 100 // (convert percentage to actual value)
+
+ //if area isn't specified use current
+ if(areastring)
+ area = get_area_instance_from_text(areastring)
+ if(!area)
+ area = A
+ stack_trace("Bad areastring path for [src], [src.areastring]")
+ else if(isarea(A) && !areastring)
+ area = A
+ if(auto_name)
+ name = "\improper [A.name] APC"
+ update_icon()
+
+ make_terminal()
+ update_nightshift_auth_requirement()
+
+ else
+ area = A
+ opened = APC_COVER_OPENED
+ operating = FALSE
+ name = "\improper [A.name] APC"
+ stat |= MAINT
+ update_icon()
+ addtimer(CALLBACK(src, .proc/update), 5)
+
GLOB.apcs_list += src
wires = new /datum/wires/apc(src)
@@ -164,9 +194,6 @@
src.tdir = dir // to fix Vars bug
setDir(SOUTH)
- if(auto_name)
- name = "\improper [get_area(src)] APC"
-
switch(tdir)
if(NORTH)
pixel_y = 23
@@ -176,14 +203,6 @@
pixel_x = 24
if(WEST)
pixel_x = -25
- if (building)
- area = get_area(src)
- opened = APC_COVER_OPENED
- operating = FALSE
- name = "[area.name] APC"
- stat |= MAINT
- src.update_icon()
- addtimer(CALLBACK(src, .proc/update), 5)
/obj/machinery/power/apc/Destroy()
GLOB.apcs_list -= src
@@ -217,33 +236,6 @@
terminal.setDir(tdir)
terminal.master = src
-/obj/machinery/power/apc/Initialize(mapload)
- . = ..()
- if(!mapload)
- return
- has_electronics = APC_ELECTRONICS_SECURED
- // is starting with a power cell installed, create it and set its charge level
- if(cell_type)
- cell = new cell_type
- cell.charge = start_charge * cell.maxcharge / 100 // (convert percentage to actual value)
-
- var/area/A = src.loc.loc
-
- //if area isn't specified use current
- if(areastring)
- src.area = get_area_instance_from_text(areastring)
- if(!src.area)
- src.area = A
- stack_trace("Bad areastring path for [src], [src.areastring]")
- else if(isarea(A) && src.areastring == null)
- src.area = A
- update_icon()
-
- make_terminal()
- update_nightshift_auth_requirement()
-
- addtimer(CALLBACK(src, .proc/update), 5)
-
/obj/machinery/power/apc/examine(mob/user)
. = ..()
if(stat & BROKEN)
@@ -1432,7 +1424,7 @@
return
for(var/A in GLOB.ai_list)
var/mob/living/silicon/ai/I = A
- if(get_area(I) == area)
+ if(get_base_area(I) == area)
return
failure_timer = max(failure_timer, round(duration))
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index 903f63e22c..441eb27621 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -193,9 +193,9 @@
var/on = FALSE // 1 if on, 0 if off
var/on_gs = FALSE
var/static_power_used = 0
- var/brightness = 8 // luminosity when on, also used in power calculation
+ var/brightness = 11 // luminosity when on, also used in power calculation
var/bulb_power = 0.75 // basically the alpha of the emitted light source
- var/bulb_colour = "#FFEEDD" // befault colour of the light.
+ var/bulb_colour = "#FFF6ED" // befault colour of the light.
var/status = LIGHT_OK // LIGHT_OK, _EMPTY, _BURNED or _BROKEN
var/flickering = FALSE
var/light_type = /obj/item/light/tube // the type of light item
@@ -231,7 +231,7 @@
icon_state = "bulb"
base_state = "bulb"
fitting = "bulb"
- brightness = 4
+ brightness = 6
bulb_colour = "#FFDDBB"
desc = "A small lighting fixture."
light_type = /obj/item/light/bulb
@@ -272,11 +272,11 @@
spawn(2)
switch(fitting)
if("tube")
- brightness = 8
+ brightness = 11
if(prob(2))
break_light_tube(1)
if("bulb")
- brightness = 4
+ brightness = 6
if(prob(5))
break_light_tube(1)
spawn(1)
@@ -294,7 +294,7 @@
cut_overlays()
switch(status) // set icon_states
if(LIGHT_OK)
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
if(emergency_mode || (A && A.fire))
icon_state = "[base_state]_emergency"
else
@@ -323,7 +323,7 @@
var/CO = bulb_colour
if(color)
CO = color
- var/area/A = get_area(src)
+ var/area/A = get_base_area(src)
if (A && A.fire)
CO = bulb_emergency_colour
else if (nightshift_enabled)
@@ -351,11 +351,11 @@
set_light(0)
update_icon()
- active_power_usage = (brightness * 10)
+ active_power_usage = (brightness * 7.2)
if(on != on_gs)
on_gs = on
if(on)
- static_power_used = brightness * 20 //20W per unit luminosity
+ static_power_used = brightness * 14.4 //20W per unit luminosity
addStaticPower(static_power_used, STATIC_LIGHT)
else
removeStaticPower(static_power_used, STATIC_LIGHT)
@@ -738,7 +738,7 @@
icon_state = "ltube"
base_state = "ltube"
item_state = "c_tube"
- brightness = 8
+ brightness = 11
/obj/item/light/tube/broken
status = LIGHT_BROKEN
@@ -751,7 +751,7 @@
item_state = "contvapour"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
- brightness = 4
+ brightness = 6
/obj/item/light/bulb/broken
status = LIGHT_BROKEN
@@ -820,7 +820,7 @@
icon = 'icons/obj/lighting.dmi'
base_state = "floor" // base description and icon_state
icon_state = "floor"
- brightness = 4
+ brightness = 6
layer = 2.5
light_type = /obj/item/light/bulb
fitting = "bulb"
diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm
index d2d3d60066..fba526edbd 100644
--- a/code/modules/power/power.dm
+++ b/code/modules/power/power.dm
@@ -382,6 +382,7 @@
return null
/area/proc/get_apc()
+ var/target = base_area ? base_area : src
for(var/obj/machinery/power/apc/APC in GLOB.apcs_list)
- if(APC.area == src)
+ if(APC.area == target)
return APC
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm
index ab9dd6d6a6..611f8c57bd 100644
--- a/code/modules/projectiles/guns/ballistic/revolver.dm
+++ b/code/modules/projectiles/guns/ballistic/revolver.dm
@@ -96,15 +96,20 @@
"Gold Trim" = "detective_gold",
"The Peacemaker" = "detective_peacemaker"
)
+ var/list/safe_calibers
+
+/obj/item/gun/ballistic/revolver/detective/Initialize()
+ . = ..()
+ safe_calibers = magazine.caliber
/obj/item/gun/ballistic/revolver/detective/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
- if(magazine.caliber != initial(magazine.caliber))
+ if(chambered && !(chambered.caliber in safe_calibers))
if(prob(70 - (magazine.ammo_count() * 10))) //minimum probability of 10, maximum of 60
playsound(user, fire_sound, 50, 1)
to_chat(user, "[src] blows up in your face!")
user.take_bodypart_damage(0,20)
user.dropItemToGround(src)
- return 0
+ return FALSE
..()
/obj/item/gun/ballistic/revolver/detective/screwdriver_act(mob/living/user, obj/item/I)
diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
index ecd906f2a9..1495ff61ba 100644
--- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
+++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
@@ -374,14 +374,18 @@
desc = "Decreases the cooldown of a kinetic accelerator. Not rated for minebot use."
modifier = 2.5
minebot_upgrade = FALSE
+ var/decreased
/obj/item/borg/upgrade/modkit/cooldown/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user)
. = ..()
if(.)
- KA.overheat_time -= modifier
+ var/old = KA.overheat_time
+ KA.overheat_time = max(0, KA.overheat_time - modifier)
+ decreased = old - KA.overheat_time
+
/obj/item/borg/upgrade/modkit/cooldown/uninstall(obj/item/gun/energy/kinetic_accelerator/KA)
- KA.overheat_time += modifier
+ KA.overheat_time += decreased
..()
/obj/item/borg/upgrade/modkit/cooldown/minebot
diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm
index bf3c4220b4..95e104ba68 100644
--- a/code/modules/reagents/chemistry/holder.dm
+++ b/code/modules/reagents/chemistry/holder.dm
@@ -171,7 +171,7 @@
return master
-/datum/reagents/proc/trans_to(obj/target, amount=1, multiplier=1, preserve_data=1, no_react = 0)//if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred.
+/datum/reagents/proc/trans_to(obj/target, amount = 1, multiplier = 1, preserve_data = 1, no_react = 0, log = FALSE)//if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred.
var/list/cached_reagents = reagent_list
if(!target || !total_volume)
return
@@ -188,17 +188,23 @@
amount = min(min(amount, src.total_volume), R.maximum_volume-R.total_volume)
var/part = amount / src.total_volume
var/trans_data = null
+ var/list/transferred = list()
for(var/reagent in cached_reagents)
var/datum/reagent/T = reagent
var/transfer_amount = T.volume * part
if(preserve_data)
trans_data = copy_data(T)
-
+ transferred += "[T] - [transfer_amount]"
R.add_reagent(T.type, transfer_amount * multiplier, trans_data, chem_temp, T.purity, pH, no_react = TRUE, ignore_pH = TRUE) //we only handle reaction after every reagent has been transfered.
-
remove_reagent(T.type, transfer_amount, ignore_pH = TRUE)
+ if(log && amount > 0)
+ var/atom/us = my_atom
+ var/atom/them = R.my_atom
+ var/location_string = "FROM [(us && "[us] ([REF(us)]) [COORD(us)]") || "NULL"] TO [(them && "[them] ([REF(them)]) [COORD(them)]") || "NULL"]"
+ log_reagent_transfer("[location_string] - [key_name(usr)][istext(log) ? " - [log]" : ""]: trans_to with arguments [target] [amount] [multiplier] [preserve_data] [no_react] and reagents [english_list(transferred)]")
+
update_total()
R.update_total()
if(!no_react)
@@ -237,7 +243,7 @@
src.handle_reactions()
return amount
-/datum/reagents/proc/trans_id_to(obj/target, reagent, amount=1, preserve_data=1)//Not sure why this proc didn't exist before. It does now! /N
+/datum/reagents/proc/trans_id_to(obj/target, reagent, amount = 1, preserve_data = TRUE, log = FALSE)//Not sure why this proc didn't exist before. It does now! /N
var/list/cached_reagents = reagent_list
if (!target)
return
@@ -257,8 +263,12 @@
if(preserve_data)
trans_data = current_reagent.data
R.add_reagent(current_reagent.type, amount, trans_data, chem_temp, current_reagent.purity, pH, no_react = TRUE)
-
remove_reagent(current_reagent.type, amount, 1)
+ if(log && amount > 0)
+ var/atom/us = my_atom
+ var/atom/them = R.my_atom
+ var/location_string = "FROM [(us && "[us] ([REF(us)]) [COORD(us)]") || "NULL"] TO [(them && "[them] ([REF(them)]) [COORD(them)]") || "NULL"]"
+ log_reagent_transfer("[location_string] - [key_name(usr)][istext(log) ? " - [log]" : ""]: trans_id_to with arguments [target] [reagent] [amount] [preserve_data]")
break
src.update_total()
diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm
index 9c877fc053..b779ad5d44 100644
--- a/code/modules/reagents/chemistry/machinery/chem_master.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_master.dm
@@ -148,8 +148,8 @@
/obj/machinery/chem_master/on_deconstruction()
var/atom/A = drop_location()
- beaker.forceMove(A)
- bottle.forceMove(A)
+ beaker?.forceMove(A)
+ bottle?.forceMove(A)
return ..()
/obj/machinery/chem_master/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
index 62a8d97b2d..103f7cb28f 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
@@ -887,7 +887,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/barefoot/on_mob_life(mob/living/carbon/M)
if(ishuman(M)) //Barefoot causes the imbiber to quickly regenerate brute trauma if they're not wearing shoes.
var/mob/living/carbon/human/H = M
- if(!H.shoes)
+ if(!H.shoes || !(H.shoes.body_parts_covered & FEET))
H.adjustBruteLoss(-3, 0)
. = 1
return ..() || .
diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
index ad3a2c90a4..a32cb94401 100644
--- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -153,20 +153,37 @@
color = "#669900" // rgb: 102, 153, 0
toxpwr = 0.5
taste_description = "death"
+ var/fakedeath_active = FALSE
pH = 13
/datum/reagent/toxin/zombiepowder/on_mob_metabolize(mob/living/L)
..()
- L.fakedeath(type)
+ ADD_TRAIT(L, TRAIT_FAKEDEATH, type)
/datum/reagent/toxin/zombiepowder/on_mob_end_metabolize(mob/living/L)
L.cure_fakedeath(type)
..()
-/datum/reagent/toxin/zombiepowder/on_mob_life(mob/living/carbon/M)
- M.adjustOxyLoss(0.5*REM, 0)
+/datum/reagent/toxin/zombiepowder/reaction_mob(mob/living/L, method=TOUCH, reac_volume)
+ L.adjustOxyLoss(0.5*REM, 0)
+ if(method == INGEST)
+ fakedeath_active = TRUE
+ L.fakedeath(type)
+
+/datum/reagent/toxin/zombiepowder/on_mob_life(mob/living/M)
..()
- . = 1
+ if(fakedeath_active)
+ return TRUE
+ switch(current_cycle)
+ if(1 to 5)
+ M.confused += 1
+ M.drowsyness += 1
+ M.slurring += 3
+ if(5 to 8)
+ M.adjustStaminaLoss(40, 0)
+ if(9 to INFINITY)
+ fakedeath_active = TRUE
+ M.fakedeath(type)
/datum/reagent/toxin/ghoulpowder
name = "Ghoul Powder"
diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
index 2890d02d09..eb473950d5 100644
--- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm
+++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
@@ -70,6 +70,14 @@
required_other = TRUE
required_container = /obj/item/slime_extract/green
+/datum/chemical_reaction/slime/slimemammal
+ name = "Mammal Mutation Toxin"
+ id = /datum/reagent/mutationtoxin/mammal
+ results = list(/datum/reagent/mutationtoxin/mammal = 1)
+ required_reagents = list(/datum/reagent/water = 1)
+ required_other = TRUE
+ required_container = /obj/item/slime_extract/green
+
//Metal
/datum/chemical_reaction/slime/slimemetal
name = "Slime Metal"
@@ -565,9 +573,16 @@
required_other = TRUE
/datum/chemical_reaction/slime/slimestop/on_reaction(datum/reagents/holder)
+ sleep(50)
+ var/obj/item/slime_extract/sepia/extract = holder.my_atom
var/turf/T = get_turf(holder.my_atom)
- var/list/M = list(get_mob_by_key(holder.my_atom.fingerprintslast))
- new /obj/effect/timestop(T, null, null, M)
+ new /obj/effect/timestop(T, null, null, null)
+ if(istype(extract))
+ if(extract.Uses > 0)
+ var/mob/lastheld = get_mob_by_key(holder.my_atom.fingerprintslast)
+ if(lastheld && !lastheld.equip_to_slot_if_possible(extract, SLOT_HANDS, disable_warning = TRUE))
+ extract.forceMove(get_turf(lastheld))
+
..()
/datum/chemical_reaction/slime/slimecamera
diff --git a/code/modules/reagents/chemistry/recipes/special.dm b/code/modules/reagents/chemistry/recipes/special.dm
index 5ad9728b22..cc63a8c692 100644
--- a/code/modules/reagents/chemistry/recipes/special.dm
+++ b/code/modules/reagents/chemistry/recipes/special.dm
@@ -186,6 +186,7 @@ GLOBAL_LIST_INIT(food_reagents, build_reagents_to_food()) //reagentid = related
var/datum/chemical_reaction/recipe = get_chemical_reaction(recipe_id)
if(!recipe)
info = "This recipe is illegible."
+ return
var/list/dat = list("")
for(var/rid in recipe.required_reagents)
var/datum/reagent/R = GLOB.chemical_reagents_list[rid]
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index f311537641..23176f8a05 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -1,6 +1,3 @@
-#define PH_WEAK (1 << 0)
-#define TEMP_WEAK (1 << 1)
-
/obj/item/reagent_containers
name = "Container"
desc = "..."
@@ -9,14 +6,13 @@
w_class = WEIGHT_CLASS_TINY
var/amount_per_transfer_from_this = 5
var/list/possible_transfer_amounts = list(5,10,15,20,25,30)
- var/APTFT_altclick = TRUE //will the set amount_per_transfer_from_this proc be called on AltClick() ?
var/volume = 30
- var/reagent_flags
+ var/reagent_flags //used to determine the reagent holder flags on add_initial_reagents()
var/list/list_reagents = null
var/spawned_disease = null
var/disease_amount = 20
var/spillable = FALSE
- var/beaker_weakness_bitflag = NONE//Bitflag!
+ var/container_flags = APTFT_ALTCLICK|APTFT_VERB //the container item flags
var/container_HP = 2
var/cached_icon
@@ -24,7 +20,7 @@
. = ..()
if(isnum(vol) && vol > 0)
volume = vol
- if(length(possible_transfer_amounts))
+ if(container_flags & APTFT_VERB && length(possible_transfer_amounts))
verbs += /obj/item/reagent_containers/proc/set_APTFT
create_reagents(volume, reagent_flags)
if(spawned_disease)
@@ -37,12 +33,12 @@
. = ..()
if(length(possible_transfer_amounts) > 1)
. += "Currently transferring [amount_per_transfer_from_this] units per use."
- if(APTFT_altclick && user.Adjacent(src))
+ if(container_flags & APTFT_ALTCLICK && user.Adjacent(src))
. += "Alt-click it to set its transfer amount."
/obj/item/reagent_containers/AltClick(mob/user)
. = ..()
- if(APTFT_altclick && length(possible_transfer_amounts) > 1 && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
+ if(container_flags & APTFT_ALTCLICK && length(possible_transfer_amounts) > 1 && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
set_APTFT()
return TRUE
@@ -108,10 +104,12 @@
/obj/item/reagent_containers/proc/bartender_check(atom/target)
. = FALSE
- if(target.CanPass(src, get_turf(src)) && thrownby && thrownby.actions)
- for(var/datum/action/innate/drink_fling/D in thrownby.actions)
- if(D.active)
- return TRUE
+ var/turf/T = get_turf(src)
+ if(!T || target.CanPass(src, T) || !thrownby || !thrownby.actions)
+ return
+ for(var/datum/action/innate/drink_fling/D in thrownby.actions)
+ if(D.active)
+ return TRUE
/obj/item/reagent_containers/proc/ForceResetRotation()
transform = initial(transform)
@@ -155,7 +153,7 @@
//melts plastic beakers
/obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M)
reagents.expose_temperature(1000)
- if(beaker_weakness_bitflag & TEMP_WEAK)
+ if(container_flags & TEMP_WEAK)
var/list/seen = viewers(5, get_turf(src))
var/iconhtml = icon2html(src, seen)
for(var/mob/H in seen)
@@ -170,13 +168,13 @@
temp_check()
/obj/item/reagent_containers/proc/temp_check()
- if(beaker_weakness_bitflag & TEMP_WEAK)
+ if(container_flags & TEMP_WEAK)
if(reagents.chem_temp >= 444)//assuming polypropylene
START_PROCESSING(SSobj, src)
//melts glass beakers
/obj/item/reagent_containers/proc/pH_check()
- if(beaker_weakness_bitflag & PH_WEAK)
+ if(container_flags & PH_WEAK)
if((reagents.pH < 1.5) || (reagents.pH > 12.5))
START_PROCESSING(SSobj, src)
else if((reagents.pH < -3) || (reagents.pH > 17))
@@ -190,7 +188,7 @@
cached_icon = icon_state
var/damage
var/cause
- if(beaker_weakness_bitflag & PH_WEAK)
+ if(container_flags & PH_WEAK)
if(reagents.pH < 2)
damage = (2 - reagents.pH)/20
cause = "from the extreme pH"
@@ -201,7 +199,7 @@
cause = "from the extreme pH"
playsound(get_turf(src), 'sound/FermiChem/bufferadd.ogg', 50, 1)
- if(beaker_weakness_bitflag & TEMP_WEAK)
+ if(container_flags & TEMP_WEAK)
if(reagents.chem_temp >= 444)
if(damage)
damage += (reagents.chem_temp/444)/5
diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm
index 624a5e62cb..db0aa8ce99 100644
--- a/code/modules/reagents/reagent_containers/glass.dm
+++ b/code/modules/reagents/reagent_containers/glass.dm
@@ -8,7 +8,6 @@
resistance_flags = ACID_PROOF
container_HP = 2
-
/obj/item/reagent_containers/glass/attack(mob/M, mob/user, obj/target)
if(!canconsume(M, user))
return
@@ -22,13 +21,9 @@
if(istype(M))
if(user.a_intent == INTENT_HARM)
- var/R
M.visible_message("[user] splashes the contents of [src] onto [M]!", \
"[user] splashes the contents of [src] onto [M]!")
- if(reagents)
- for(var/datum/reagent/A in reagents.reagent_list)
- R += A.type + " ("
- R += num2text(A.volume) + "),"
+ var/R = reagents?.log_list()
if(isturf(target) && reagents.reagent_list.len && thrownby)
log_combat(thrownby, target, "splashed (thrown) [english_list(reagents.reagent_list)]")
message_admins("[ADMIN_LOOKUPFLW(thrownby)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] at [ADMIN_VERBOSEJMP(target)].")
@@ -36,7 +31,8 @@
log_combat(user, M, "splashed", R)
reagents.clear_reagents()
else
- if(M != user)
+ var/self_fed = M == user
+ if(!self_fed)
M.visible_message("[user] attempts to feed something to [M].", \
"[user] attempts to feed something to you.")
if(!do_mob(user, M))
@@ -49,7 +45,7 @@
to_chat(user, "You swallow a gulp of [src].")
var/fraction = min(5/reagents.total_volume, 1)
reagents.reaction(M, INGEST, fraction)
- addtimer(CALLBACK(reagents, /datum/reagents.proc/trans_to, M, 5), 5)
+ addtimer(CALLBACK(reagents, /datum/reagents.proc/trans_to, M, 5, null, null, null, self_fed? "self swallowed" : "fed by [user]"), 5)
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
/obj/item/reagent_containers/glass/afterattack(obj/target, mob/user, proximity)
@@ -66,7 +62,7 @@
to_chat(user, "[target] is full.")
return
- var/trans = reagents.trans_to(target, amount_per_transfer_from_this)
+ var/trans = reagents.trans_to(target, amount_per_transfer_from_this, log = "reagentcontainer-glass afterattack transfer to")
to_chat(user, "You transfer [trans] unit\s of the solution to [target].")
else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us.
@@ -78,7 +74,7 @@
to_chat(user, "[src] is full.")
return
- var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
+ var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, log = "reagentcontainer-glass afterattack fill from")
to_chat(user, "You fill [src] with [trans] unit\s of the contents of [target].")
else if(reagents.total_volume)
@@ -101,12 +97,11 @@
to_chat(user, "[src] is full.")
else
to_chat(user, "You break [E] in [src].")
- E.reagents.trans_to(src, E.reagents.total_volume)
+ E.reagents.trans_to(src, E.reagents.total_volume, log = "reagentcontainer-glass break egg in")
qdel(E)
return
..()
-
/obj/item/reagent_containers/glass/beaker
name = "beaker"
desc = "A beaker. It can hold up to 60 units. Unable to withstand extreme pHes."
@@ -116,7 +111,7 @@
item_state = "beaker"
materials = list(MAT_GLASS=500)
possible_transfer_amounts = list(5,10,15,20,25,30,50,60)
- beaker_weakness_bitflag = PH_WEAK
+ container_flags = PH_WEAK|APTFT_ALTCLICK|APTFT_VERB
/obj/item/reagent_containers/glass/beaker/Initialize()
. = ..()
@@ -159,8 +154,37 @@
/obj/item/reagent_containers/glass/beaker/jar
name = "honey jar"
desc = "A jar for honey. It can hold up to 60 units of sweet delight. Unable to withstand reagents of an extreme pH."
- icon = 'icons/obj/chemical.dmi'
- icon_state = "vapour"
+ icon_state = "honey"
+
+/obj/item/reagent_containers/glass/beaker/glass_dish
+ name = "glass dish"
+ desc = "A tiny glass dish. It can hold up to 3 units. Unable to withstand reagents of an extreme pH."
+ materials = list(MAT_GLASS=500)
+ icon_state = "glass_disk"
+ possible_transfer_amounts = list(0.1,0.5,0.75,1,2,3)
+ volume = 3
+
+/obj/item/reagent_containers/glass/beaker/flask/large
+ name = "large flask"
+ desc = "A large flask. It can hold up to 80 units. Unable to withstand reagents of an extreme pH."
+ materials = list(MAT_GLASS=2500)
+ icon_state = "flasklarge"
+ volume = 80
+
+/obj/item/reagent_containers/glass/beaker/flask
+ name = "small flask"
+ desc = "A small flask. It can hold up to 40 units. Unable to withstand reagents of an extreme pH."
+ materials = list(MAT_GLASS=1000)
+ icon_state = "flasksmall"
+ volume = 40
+
+/obj/item/reagent_containers/glass/beaker/flask/spouty
+ name = "flask with spout"
+ desc = "A flask with a spout! It can hold up to 120 units. Unable to withstand reagents of an extreme pH."
+ materials = list(MAT_GLASS=2500)
+ icon_state = "flaskspouty"
+ possible_transfer_amounts = list(1,2,3,4,5,10,15,20,25,30,50,100,120)
+ volume = 120
/obj/item/reagent_containers/glass/beaker/large
name = "large beaker"
@@ -180,11 +204,7 @@
volume = 180
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,40,50,60,120,180)
-
-/obj/item/reagent_containers/glass/beaker/plastic/Initialize()
- beaker_weakness_bitflag &= ~PH_WEAK
- beaker_weakness_bitflag |= TEMP_WEAK
- . = ..()
+ container_flags = TEMP_WEAK|APTFT_ALTCLICK|APTFT_VERB
/obj/item/reagent_containers/glass/beaker/plastic/update_icon()
icon_state = "beakerlarge" // hack to lets us reuse the large beaker reagent fill states
@@ -199,10 +219,7 @@
volume = 240
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,40,50,60,120,200,240)
-
-/obj/item/reagent_containers/glass/beaker/meta/Initialize() // why the fuck can't you just set the beaker weakness bitflags to nothing? fuck you
- beaker_weakness_bitflag &= ~PH_WEAK
- . = ..()
+ container_flags = APTFT_ALTCLICK|APTFT_VERB
/obj/item/reagent_containers/glass/beaker/noreact
name = "cryostasis beaker"
@@ -213,13 +230,9 @@
reagent_flags = OPENCONTAINER | NO_REACT
volume = 50
amount_per_transfer_from_this = 10
+ container_flags = APTFT_ALTCLICK|APTFT_VERB
container_HP = 10//shouldn't be needed
-/obj/item/reagent_containers/glass/beaker/noreact/Initialize()
- beaker_weakness_bitflag &= ~PH_WEAK
- . = ..()
- //reagents.set_reacting(FALSE) was this removed in a recent pr?
-
/obj/item/reagent_containers/glass/beaker/bluespace
name = "bluespace beaker"
desc = "A bluespace beaker, powered by experimental bluespace technology \
@@ -287,18 +300,15 @@
SLOT_L_STORE, SLOT_R_STORE,\
SLOT_GENERC_DEXTROUS_STORAGE
)
+ container_flags = APTFT_ALTCLICK|APTFT_VERB
container_HP = 1
-/obj/item/reagent_containers/glass/bucket/Initialize()
- beaker_weakness_bitflag |= TEMP_WEAK
- . = ..()
-
/obj/item/reagent_containers/glass/bucket/attackby(obj/O, mob/user, params)
if(istype(O, /obj/item/mop))
if(reagents.total_volume < 1)
to_chat(user, "[src] is out of water!")
else
- reagents.trans_to(O, 5)
+ reagents.trans_to(O, 5, log = "reagentcontainer-bucket fill mop")
to_chat(user, "You wet [O] in [src].")
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
else if(isprox(O))
@@ -342,12 +352,9 @@
volume = 50
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50)
+ container_flags = TEMP_WEAK|APTFT_ALTCLICK|APTFT_VERB
container_HP = 1
-/obj/item/reagent_containers/glass/beaker/waterbottle/Initialize()
- beaker_weakness_bitflag |= TEMP_WEAK
- . = ..()
-
/obj/item/reagent_containers/glass/beaker/waterbottle/empty
list_reagents = list()
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index f509ad0b10..f4bb5e0d08 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -362,30 +362,14 @@
return
/obj/item/hypospray/mkii/afterattack(atom/target, mob/user, proximity)
- if(!vial)
+ if(!vial || !proximity || !isliving(target))
+ return
+ var/mob/living/L = target
+
+ if(!L.reagents || !L.can_inject(user, TRUE, user.zone_selected, penetrates))
return
- if(!proximity)
- return
-
- if(!ismob(target))
- return
-
- var/mob/living/L
- if(isliving(target))
- L = target
- if(!penetrates && !L.can_inject(user, 1)) //This check appears another four times, since otherwise the penetrating sprays will break in do_mob.
- return
-
- if(!L && !target.is_injectable()) //only checks on non-living mobs, due to how can_inject() handles
- to_chat(user, "You cannot directly fill [target]!")
- return
-
- if(target.reagents.total_volume >= target.reagents.maximum_volume)
- to_chat(user, "[target] is full.")
- return
-
- if(ishuman(L))
+ if(iscarbon(L))
var/obj/item/bodypart/affecting = L.get_bodypart(check_zone(user.zone_selected))
if(!affecting)
to_chat(user, "The limb is missing!")
@@ -394,84 +378,40 @@
to_chat(user, "Medicine won't work on a robotic limb!")
return
+ //Always log attemped injections for admins
var/contained = vial.reagents.log_list()
log_combat(user, L, "attemped to inject", src, addition="which had [contained]")
-//Always log attemped injections for admins
- if(vial != null)
- switch(mode)
- if(HYPO_INJECT)
- if(L) //living mob
- if(L != user)
- L.visible_message("[user] is trying to inject [L] with [src]!", \
- "[user] is trying to inject [L] with [src]!")
- if(!do_mob(user, L, inject_wait))
- return
- if(!penetrates && !L.can_inject(user, 1))
- return
- if(!vial.reagents.total_volume)
- return
- if(L.reagents.total_volume >= L.reagents.maximum_volume)
- return
- L.visible_message("[user] uses the [src] on [L]!", \
- "[user] uses the [src] on [L]!")
- else
- if(!do_mob(user, L, inject_self))
- return
- if(!penetrates && !L.can_inject(user, 1))
- return
- if(!vial.reagents.total_volume)
- return
- if(L.reagents.total_volume >= L.reagents.maximum_volume)
- return
- log_attack("[user.name] ([user.ckey]) applied [src] to [L.name] ([L.ckey]), which had [contained] (INTENT: [uppertext(user.a_intent)]) (MODE: [src.mode])")
- L.log_message("applied [src] to themselves ([contained]).", INDIVIDUAL_ATTACK_LOG)
- var/fraction = min(vial.amount_per_transfer_from_this/vial.reagents.total_volume, 1)
- vial.reagents.reaction(L, INJECT, fraction)
- vial.reagents.trans_to(target, vial.amount_per_transfer_from_this)
- if(vial.amount_per_transfer_from_this >= 15)
- playsound(loc,'sound/items/hypospray_long.ogg',50, 1, -1)
- if(vial.amount_per_transfer_from_this < 15)
- playsound(loc, pick('sound/items/hypospray.ogg','sound/items/hypospray2.ogg'), 50, 1, -1)
- to_chat(user, "You inject [vial.amount_per_transfer_from_this] units of the solution. The hypospray's cartridge now contains [vial.reagents.total_volume] units.")
-
- if(HYPO_SPRAY)
- if(L) //living mob
- if(L != user)
- L.visible_message("[user] is trying to spray [L] with [src]!", \
- "[user] is trying to spray [L] with [src]!")
- if(!do_mob(user, L, spray_wait))
- return
- if(!penetrates && !L.can_inject(user, 1))
- return
- if(!vial.reagents.total_volume)
- return
- if(L.reagents.total_volume >= L.reagents.maximum_volume)
- return
- L.visible_message("[user] uses the [src] on [L]!", \
- "[user] uses the [src] on [L]!")
- else
- if(!do_mob(user, L, spray_self))
- return
- if(!penetrates && !L.can_inject(user, 1))
- return
- if(!vial.reagents.total_volume)
- return
- if(L.reagents.total_volume >= L.reagents.maximum_volume)
- return
- log_attack("[user.name] ([user.ckey]) applied [src] to [L.name] ([L.ckey]), which had [contained] (INTENT: [uppertext(user.a_intent)]) (MODE: [src.mode])")
- L.log_message("applied [src] to themselves ([contained]).", INDIVIDUAL_ATTACK_LOG)
- var/fraction = min(vial.amount_per_transfer_from_this/vial.reagents.total_volume, 1)
- vial.reagents.reaction(L, PATCH, fraction)
- vial.reagents.trans_to(target, vial.amount_per_transfer_from_this)
- if(vial.amount_per_transfer_from_this >= 15)
- playsound(loc,'sound/items/hypospray_long.ogg',50, 1, -1)
- if(vial.amount_per_transfer_from_this < 15)
- playsound(loc, pick('sound/items/hypospray.ogg','sound/items/hypospray2.ogg'), 50, 1, -1)
- to_chat(user, "You spray [vial.amount_per_transfer_from_this] units of the solution. The hypospray's cartridge now contains [vial.reagents.total_volume] units.")
- else
- to_chat(user, "[src] doesn't work here!")
+ if(!vial)
+ to_chat(user, "[src] doesn't have any vial installed!")
return
+ if(!vial.reagents.total_volume)
+ to_chat(user, "[src]'s vial is empty!")
+ return
+
+ var/fp_verb = mode == HYPO_SPRAY ? "spray" : "inject"
+ var/method = mode == HYPO_SPRAY ? TOUCH : INJECT
+
+ if(L != user)
+ L.visible_message("[user] is trying to [fp_verb] [L] with [src]!", \
+ "[user] is trying to [fp_verb] you with [src]!")
+ if(!do_mob(user, L, inject_wait, extra_checks = CALLBACK(L, /mob/living/proc/can_inject, user, FALSE, user.zone_selected, penetrates)))
+ return
+ if(!vial.reagents.total_volume)
+ return
+ log_attack("[user.name] ([user.ckey]) applied [src] to [L.name] ([L.ckey]), which had [contained] (INTENT: [uppertext(user.a_intent)]) (MODE: [mode])")
+ if(L != user)
+ L.visible_message("[user] uses the [src] on [L]!", \
+ "[user] uses the [src] on you!")
+ else
+ L.log_message("applied [src] to themselves ([contained]).", INDIVIDUAL_ATTACK_LOG)
+
+ var/fraction = min(vial.amount_per_transfer_from_this/vial.reagents.total_volume, 1)
+ vial.reagents.reaction(L, method, fraction)
+ vial.reagents.trans_to(target, vial.amount_per_transfer_from_this)
+ var/long_sound = vial.amount_per_transfer_from_this >= 15
+ playsound(loc, long_sound ? 'sound/items/hypospray_long.ogg' : pick('sound/items/hypospray.ogg','sound/items/hypospray2.ogg'), 50, 1, -1)
+ to_chat(user, "You [fp_verb] [vial.amount_per_transfer_from_this] units of the solution. The hypospray's cartridge now contains [vial.reagents.total_volume] units.")
/obj/item/hypospray/mkii/attack_self(mob/living/user)
if(user)
diff --git a/code/modules/reagents/reagent_containers/hypovial.dm b/code/modules/reagents/reagent_containers/hypovial.dm
index c0db92e0e8..db2d73c697 100644
--- a/code/modules/reagents/reagent_containers/hypovial.dm
+++ b/code/modules/reagents/reagent_containers/hypovial.dm
@@ -7,7 +7,7 @@
spillable = FALSE
volume = 10
possible_transfer_amounts = list(1,2,5,10)
- APTFT_altclick = FALSE
+ container_flags = APTFT_VERB
obj_flags = UNIQUE_RENAME
unique_reskin = list("hypovial" = "hypovial",
"red hypovial" = "hypovial-b",
@@ -25,9 +25,6 @@
if(!icon_state)
icon_state = "hypovial"
update_icon()
-// beaker_weakness_bitflag |= PH_WEAK // fuck you if you're using these like beakers
-// beaker_weakness_bitflag |= TEMP_WEAK
-
/obj/item/reagent_containers/glass/bottle/vial/on_reagent_change()
update_icon()
diff --git a/code/modules/reagents/reagent_containers/rags.dm b/code/modules/reagents/reagent_containers/rags.dm
index 812b3144e9..59c956acd6 100644
--- a/code/modules/reagents/reagent_containers/rags.dm
+++ b/code/modules/reagents/reagent_containers/rags.dm
@@ -8,7 +8,7 @@
reagent_flags = REFILLABLE | DRAINABLE
amount_per_transfer_from_this = 5
possible_transfer_amounts = list()
- APTFT_altclick = FALSE
+ container_flags = APTFT_VERB
volume = 5
spillable = FALSE
var/wipe_sound
@@ -118,6 +118,7 @@
item_flags = NOBLUDGEON | NO_UNIFORM_REQUIRED //so it can be worn on the belt slot even with no uniform.
force = 1
w_class = WEIGHT_CLASS_NORMAL
+ mutantrace_variation = STYLE_DIGITIGRADE
attack_verb = list("whipped")
hitsound = 'sound/items/towelwhip.ogg'
volume = 10
diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm
index edaa5ce269..e8c8d14141 100644
--- a/code/modules/reagents/reagent_containers/spray.dm
+++ b/code/modules/reagents/reagent_containers/spray.dm
@@ -23,6 +23,7 @@
amount_per_transfer_from_this = 5
volume = 250
possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
+ container_flags = NONE //APTFT is alternated between the initial value and stream_amount and shouldn't be exploited.
/obj/item/reagent_containers/spray/afterattack(atom/A, mob/user)
. = ..()
diff --git a/code/modules/research/designs/autobotter_designs.dm b/code/modules/research/designs/autobotter_designs.dm
index d2a38a29f9..6eb7e8354b 100644
--- a/code/modules/research/designs/autobotter_designs.dm
+++ b/code/modules/research/designs/autobotter_designs.dm
@@ -151,77 +151,76 @@
name = "Export Design (Wine)"
desc = "Allows for the blowing, and bottling of Wine bottles."
id = "wine_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/wine = 100)
+ reagents_list = list(/datum/reagent/consumable/ethanol/wine = 50)
build_path = /obj/item/export/bottle/wine
/datum/design/bottle/export/rum
name = "Export Design (Rum)"
desc = "Allows for the blowing, and bottling of Rum bottles."
id = "rum_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/rum = 100)
+ reagents_list = list(/datum/reagent/consumable/ethanol/rum = 50)
build_path = /obj/item/export/bottle/rum
/datum/design/bottle/export/gin
name = "Export Design (Gin)"
desc = "Allows for the blowing, and bottling of Gin bottles."
id = "gin_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/gin = 100)
build_path = /obj/item/export/bottle/gin
/datum/design/bottle/export/whiskey
name = "Export Design (Whiskey)"
desc = "Allows for the blowing, and bottling of Whiskey bottles."
id = "whiskey_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/whiskey = 100)
+ reagents_list = list(/datum/reagent/consumable/ethanol/whiskey = 50)
build_path = /obj/item/export/bottle/whiskey
/datum/design/bottle/export/vodka
name = "Export Design (Vodka)"
desc = "Allows for the blowing, and bottling of 99% Vodka bottles."
id = "vodka_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/vodka = 99, /datum/reagent/water = 1)
+ reagents_list = list(/datum/reagent/consumable/ethanol/vodka = 45, /datum/reagent/water = 1)
build_path = /obj/item/export/bottle/vodka
/datum/design/bottle/export/tequila
name = "Export Design (Tequila)"
desc = "Allows for the blowing, and bottling of Tequila bottles."
id = "tequila_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/tequila = 80, /datum/reagent/consumable/lemonjuice = 20)
+ reagents_list = list(/datum/reagent/consumable/ethanol/tequila = 40, /datum/reagent/consumable/lemonjuice = 10)
build_path = /obj/item/export/bottle/tequila
/datum/design/bottle/export/patron
name = "Export Design (Patron)"
desc = "Allows for the blowing, and bottling of Patron bottles."
id = "patron_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/patron = 100)
+ reagents_list = list(/datum/reagent/consumable/ethanol/patron = 50)
build_path = /obj/item/export/bottle/patron
/datum/design/bottle/export/kahlua
name = "Export Design (Kahlua)"
desc = "Allows for the blowing, and bottling of Kahlua bottles."
id = "kahlua_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/kahlua = 100)
+ reagents_list = list(/datum/reagent/consumable/ethanol/kahlua = 50)
build_path = /obj/item/export/bottle/kahlua
/datum/design/bottle/export/sake
name = "Export Design (Sake)"
desc = "Allows for the blowing, and bottling of Sake bottles."
id = "sake_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/sake = 80, /datum/reagent/consumable/rice = 10, /datum/reagent/consumable/sugar = 10)
+ reagents_list = list(/datum/reagent/consumable/ethanol/sake = 40, /datum/reagent/consumable/rice = 10, /datum/reagent/consumable/sugar = 10)
build_path = /obj/item/export/bottle/sake
/datum/design/bottle/export/vermouth
name = "Export Design (Vermouth)"
desc = "Allows for the blowing, and bottling of Vermouth bottles."
id = "vermouth_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/vermouth = 100)
+ reagents_list = list(/datum/reagent/consumable/ethanol/vermouth = 50)
build_path = /obj/item/export/bottle/vermouth
/datum/design/bottle/export/goldschlager
name = "Export Design (Goldschlager)"
desc = "Allows for the blowing, and bottling of Goldschlager bottles."
id = "goldschlager_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/goldschlager = 100)
+ reagents_list = list(/datum/reagent/consumable/ethanol/goldschlager = 50)
build_path = /obj/item/export/bottle/goldschlager
/datum/design/bottle/export/hcider
@@ -235,13 +234,13 @@
name = "Export Design (Cognac)"
desc = "Allows for the blowing, and bottling of Cognac bottles."
id = "cognac_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/cognac = 100)
+ reagents_list = list(/datum/reagent/consumable/ethanol/cognac = 50)
build_path = /obj/item/export/bottle/cognac
/datum/design/bottle/export/absinthe
name = "Export Design (Absinthe)"
desc = "Allows for the blowing, and bottling of Absinthe bottles."
- reagents_list = list(/datum/reagent/consumable/ethanol/absinthe = 100)
+ reagents_list = list(/datum/reagent/consumable/ethanol/absinthe = 50)
id = "absinthe_export"
build_path = /obj/item/export/bottle/absinthe
@@ -249,49 +248,49 @@
name = "Export Design (Grappa)"
desc = "Allows for the blowing, and bottling of Grappa bottles."
id = "grappa_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/grappa = 100)
+ reagents_list = list(/datum/reagent/consumable/ethanol/grappa = 50)
build_path = /obj/item/export/bottle/grappa
/datum/design/bottle/export/fernet
name = "Export Design (Fernet)"
desc = "Allows for the blowing, and bottling of Fernet bottles."
id = "fernet_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/fernet = 100)
+ reagents_list = list(/datum/reagent/consumable/ethanol/fernet = 50)
build_path = /obj/item/export/bottle/fernet
/datum/design/bottle/export/applejack
name = "Export Design (Applejack)"
desc = "Allows for the blowing, and bottling of Applejack bottles."
id = "applejack_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/applejack = 50, /datum/reagent/consumable/ethanol/gin = 10)
+ reagents_list = list(/datum/reagent/consumable/ethanol/applejack = 35, /datum/reagent/consumable/ethanol/gin = 10)
build_path = /obj/item/export/bottle/applejack
/datum/design/bottle/export/champagne
name = "Export Design (Champagne)"
desc = "Allows for the blowing, and bottling of Champagne bottles."
id = "champagne_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/champagne = 90, /datum/reagent/carbondioxide = 10)
+ reagents_list = list(/datum/reagent/consumable/ethanol/champagne = 30, /datum/reagent/carbondioxide = 10)
build_path = /obj/item/export/bottle/champagne
/datum/design/bottle/export/blazaam
name = "Export Design (Blazaam)"
desc = "Allows for the blowing, and bottling of Blazaam bottles."
id = "blazaam_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/blazaam = 80, /datum/reagent/water/holywater = 20)
+ reagents_list = list(/datum/reagent/consumable/ethanol/blazaam = 40, /datum/reagent/water/holywater = 20)
build_path = /obj/item/export/bottle/blazaam
/datum/design/bottle/export/trappist
name = "Export Design (Trappist)"
desc = "Allows for the blowing, and bottling of Trappist bottles."
id = "trappist_export"
- reagents_list = list(/datum/reagent/consumable/ethanol/trappist = 100)
+ reagents_list = list(/datum/reagent/consumable/ethanol/trappist = 50)
build_path = /obj/item/export/bottle/trappist
/datum/design/bottle/export/grenadine
name = "Export Design (Grenadine)"
desc = "Allows for the blowing, and bottling of Grenadine bottles."
id = "grenadine_export"
- reagents_list = list(/datum/reagent/consumable/grenadine = 100)
+ reagents_list = list(/datum/reagent/consumable/grenadine = 50)
build_path = /obj/item/export/bottle/grenadine
/datum/design/bottle/export/minikeg
@@ -299,7 +298,7 @@
desc = "Allows for the fabication, and bottling of Minikeg of craft beer."
id = "minikeg"
category = list("Beers")
- reagents_list = list(/datum/reagent/consumable/ethanol/beer/light = 100)
+ reagents_list = list(/datum/reagent/consumable/ethanol/beer/light = 50)
build_path = /obj/item/export/bottle/minikeg
/datum/design/bottle/export/blooddrop
@@ -315,7 +314,7 @@
desc = "Allows for the blowing, and bottling of Slim Gold bottles."
id = "slim_gold"
category = list("Beers")
- reagents_list = list(/datum/reagent/gold = 10, /datum/reagent/carbondioxide = 10, /datum/reagent/consumable/ethanol/rum = 30, /datum/reagent/consumable/ethanol/beer = 40)
+ reagents_list = list(/datum/reagent/gold = 10, /datum/reagent/carbondioxide = 10, /datum/reagent/consumable/ethanol/rum = 15, /datum/reagent/consumable/ethanol/beer = 20)
build_path = /obj/item/export/bottle/slim_gold
/datum/design/bottle/export/white_bloodmoon
@@ -323,13 +322,13 @@
desc = "Allows for the blowing, and bottling of White Bloodmoon bottles."
id = "white_bloodmoon"
category = list("Wines")
- reagents_list = list(/datum/reagent/medicine/synthflesh = 50, /datum/reagent/blood = 50, /datum/reagent/liquidgibs = 10)
+ reagents_list = list(/datum/reagent/medicine/synthflesh = 20, /datum/reagent/blood = 30, /datum/reagent/liquidgibs = 10)
build_path = /obj/item/export/bottle/white_bloodmoon
/datum/design/bottle/export/greenroad
name = "Export Design (Greenroad)"
desc = "Allows for the blowing, and bottling of Greenroad bottles."
id = "greenroad"
- reagents_list = list(/datum/reagent/consumable/vitfro = 50, /datum/reagent/consumable/ethanol/rum = 50, /datum/reagent/ash = 10)
+ reagents_list = list(/datum/reagent/consumable/vitfro = 50, /datum/reagent/consumable/ethanol/rum = 30, /datum/reagent/ash = 10)
category = list("Beers")
build_path = /obj/item/export/bottle/greenroad
\ No newline at end of file
diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm
index 681195bcc3..fd68a393f9 100644
--- a/code/modules/research/experimentor.dm
+++ b/code/modules/research/experimentor.dm
@@ -573,7 +573,8 @@
else if(loc == user)
cooldown = TRUE
call(src,realProc)(user)
- addtimer(CALLBACK(src, .proc/cd), cooldownMax)
+ if(!QDELETED(src))
+ addtimer(CALLBACK(src, .proc/cd), cooldownMax)
else
to_chat(user, "You aren't quite sure what to do with this yet.")
diff --git a/code/modules/research/xenobiology/crossbreeding/burning.dm b/code/modules/research/xenobiology/crossbreeding/burning.dm
index e5b30962ae..48e6f720b0 100644
--- a/code/modules/research/xenobiology/crossbreeding/burning.dm
+++ b/code/modules/research/xenobiology/crossbreeding/burning.dm
@@ -154,7 +154,7 @@ Burning extracts:
/obj/item/slimecross/burning/sepia/do_effect(mob/user)
user.visible_message("[src] shapes itself into a camera!")
- new /obj/item/camera/timefreeze(get_turf(user))
+ new /obj/item/camera/rewind(get_turf(user))
..()
/obj/item/slimecross/burning/cerulean
@@ -289,25 +289,88 @@ Burning extracts:
//Misc. things added
+//Rewind camera - I'm already Burning Sepia
+/obj/item/camera/rewind
+ name = "sepia-tinted camera"
+ desc = "They say a picture is like a moment stopped in time."
+ pictures_left = 1
+ pictures_max = 1
+ can_customise = FALSE
+ default_picture_name = "A nostalgic picture"
+ var/used = FALSE
+
+/datum/saved_bodypart
+ var/obj/item/bodypart/old_part
+ var/bodypart_type
+ var/brute_dam
+ var/burn_dam
+ var/stamina_dam
+
+/datum/saved_bodypart/New(obj/item/bodypart/part)
+ old_part = part
+ bodypart_type = part.type
+ brute_dam = part.brute_dam
+ burn_dam = part.burn_dam
+ stamina_dam = part.stamina_dam
+
+/mob/living/carbon/proc/apply_saved_bodyparts(list/datum/saved_bodypart/parts)
+ var/list/dont_chop = list()
+ for(var/zone in parts)
+ var/datum/saved_bodypart/saved_part = parts[zone]
+ var/obj/item/bodypart/already = get_bodypart(zone)
+ if(QDELETED(saved_part.old_part))
+ saved_part.old_part = new saved_part.bodypart_type
+ if(!already || already != saved_part.old_part)
+ saved_part.old_part.replace_limb(src, TRUE)
+ saved_part.old_part.heal_damage(INFINITY, INFINITY, INFINITY, null, FALSE)
+ saved_part.old_part.receive_damage(saved_part.brute_dam, saved_part.burn_dam, saved_part.stamina_dam)
+ dont_chop[zone] = TRUE
+ for(var/_part in bodyparts)
+ var/obj/item/bodypart/part = _part
+ if(dont_chop[part.body_zone])
+ continue
+ part.drop_limb(TRUE)
+
+/mob/living/carbon/proc/save_bodyparts()
+ var/list/datum/saved_bodypart/ret = list()
+ for(var/_part in bodyparts)
+ var/obj/item/bodypart/part = _part
+ var/datum/saved_bodypart/saved_part = new(part)
+
+ ret[part.body_zone] = saved_part
+ return ret
+
+/obj/item/camera/rewind/afterattack(atom/target, mob/user, flag)
+ if(!on || !pictures_left || !isturf(target.loc))
+ return
+ if(!used)//selfie time
+ if(user == target)
+ to_chat(user, "You take a selfie!")
+ else
+ to_chat(user, "You take a photo with [target]!")
+ to_chat(target, "[user] takes a photo with you!")
+ to_chat(target, "You'll remember this moment forever!")
+
+ used = TRUE
+ target.AddComponent(/datum/component/dejavu, 2)
+ .=..()
+
+//Timefreeze camera - Old Burning Sepia result. Kept in case admins want to spawn it
/obj/item/camera/timefreeze
name = "sepia-tinted camera"
desc = "They say a picture is like a moment stopped in time."
pictures_left = 1
pictures_max = 1
+ var/used = FALSE
/obj/item/camera/timefreeze/afterattack(atom/target, mob/user, flag)
if(!on || !pictures_left || !isturf(target.loc))
return
- new /obj/effect/timestop(get_turf(target), 2, 50, list(user))
- . = ..()
- var/text = "The camera fades away"
- if(disk)
- text += ", leaving the disk behind!"
- user.put_in_hands(disk)
- else
- text += "!"
- to_chat(user,"[text]")
- qdel(src)
+ if(!used) //refilling the film does not refill the timestop
+ new /obj/effect/timestop(get_turf(target), 2, 50, list(user))
+ used = TRUE
+ desc = "This camera has seen better days."
+ return ..()
/obj/item/slimepotion/extract_cloner
name = "extract cloning potion"
diff --git a/code/modules/research/xenobiology/crossbreeding/consuming.dm b/code/modules/research/xenobiology/crossbreeding/consuming.dm
index 0e8bf1e11f..af37a70232 100644
--- a/code/modules/research/xenobiology/crossbreeding/consuming.dm
+++ b/code/modules/research/xenobiology/crossbreeding/consuming.dm
@@ -212,7 +212,7 @@ Consuming extracts:
taste = "sugar and starlight"
/obj/item/slime_cookie/bluespace/do_effect(mob/living/M, mob/user)
- var/list/L = get_area_turfs(get_area(get_turf(M)))
+ var/list/L = get_sub_areas_turfs(get_area(M))
var/turf/target
while (L.len && !target)
var/I = rand(1, L.len)
diff --git a/code/modules/research/xenobiology/crossbreeding/regenerative.dm b/code/modules/research/xenobiology/crossbreeding/regenerative.dm
index 55865d1ae2..d230c22d2f 100644
--- a/code/modules/research/xenobiology/crossbreeding/regenerative.dm
+++ b/code/modules/research/xenobiology/crossbreeding/regenerative.dm
@@ -148,8 +148,9 @@ Regenerative extracts:
/obj/item/slimecross/regenerative/sepia
colour = "sepia"
-/obj/item/slimecross/regenerative/sepia/core_effect(mob/living/target, mob/user)
- new /obj/effect/timestop(get_turf(target), 2, 50, list(user,target))
+/obj/item/slimecross/regenerative/sepia/core_effect_before(mob/living/target, mob/user)
+ to_chat(target, "You try to forget how you feel.")
+ target.AddComponent(/datum/component/dejavu)
/obj/item/slimecross/regenerative/cerulean
colour = "cerulean"
diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm
index 8eecf1f635..eddd5b2b0c 100644
--- a/code/modules/research/xenobiology/xenobiology.dm
+++ b/code/modules/research/xenobiology/xenobiology.dm
@@ -909,12 +909,15 @@
to_chat(user, "The potion can only be used on gendered things!")
return
- if(L.gender == MALE)
+ if(L.gender == MALE && (L.client?.prefs.cit_toggles & FORCED_FEM))
L.gender = FEMALE
L.visible_message("[L] suddenly looks more feminine!", "You suddenly feel more feminine!")
- else
+ else if(L.gender == FEMALE && (L.client?.prefs.cit_toggles & FORCED_MASC))
L.gender = MALE
L.visible_message("[L] suddenly looks more masculine!", "You suddenly feel more masculine!")
+ else
+ to_chat(user,"It won't work on [L]!")
+ return
L.regenerate_icons()
qdel(src)
diff --git a/code/modules/ruins/spaceruin_code/hilbertshotel.dm b/code/modules/ruins/spaceruin_code/hilbertshotel.dm
index dc721506a5..8648e46cb9 100644
--- a/code/modules/ruins/spaceruin_code/hilbertshotel.dm
+++ b/code/modules/ruins/spaceruin_code/hilbertshotel.dm
@@ -12,6 +12,7 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337)
var/datum/map_template/hilbertshotel/lore/hotelRoomTempLore
var/list/activeRooms = list()
var/list/storedRooms = list()
+ var/list/checked_in_ckeys = list()
var/storageTurf
//Lore Stuff
var/ruinSpawned = FALSE
@@ -44,7 +45,7 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337)
/obj/item/hilbertshotel/proc/promptAndCheckIn(mob/user)
var/chosenRoomNumber = input(user, "What number room will you be checking into?", "Room Number") as null|num
- if(!chosenRoomNumber)
+ if(!chosenRoomNumber || !user.CanReach(src))
return
if(chosenRoomNumber > SHORT_REAL_LIMIT)
to_chat(user, "You have to check out the first [SHORT_REAL_LIMIT] rooms before you can go to a higher numbered one!")
@@ -52,8 +53,8 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337)
if((chosenRoomNumber < 1) || (chosenRoomNumber != round(chosenRoomNumber)))
to_chat(user, "That is not a valid room number!")
return
- if(ismob(loc))
- if(user == loc) //Not always the same as user
+ if(!isturf(loc))
+ if((loc == user) || (loc.loc == user) || (loc.loc in user.contents) || (loc in user.GetAllContents(type))) //short circuit, first three checks are cheaper and covers almost all cases (loc.loc covers hotel in box in backpack).
forceMove(get_turf(user))
if(!storageTurf) //Blame subsystems for not allowing this to be in Initialize
if(!GLOB.hhStorageTurf)
@@ -63,13 +64,13 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337)
GLOB.hhStorageTurf = locate(storageReservation.bottom_left_coords[1]+1, storageReservation.bottom_left_coords[2]+1, storageReservation.bottom_left_coords[3])
else
storageTurf = GLOB.hhStorageTurf
+ checked_in_ckeys |= user.ckey //if anything below runtimes, guess you're outta luck!
if(tryActiveRoom(chosenRoomNumber, user))
return
if(tryStoredRoom(chosenRoomNumber, user))
return
sendToNewRoom(chosenRoomNumber, user)
-
/obj/item/hilbertshotel/proc/tryActiveRoom(var/roomNumber, var/mob/user)
if(activeRooms["[roomNumber]"])
var/datum/turf_reservation/roomReservation = activeRooms["[roomNumber]"]
@@ -102,6 +103,7 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337)
else
return FALSE
+/// This is a BLOCKING OPERATION. Note the room load call, and the block reservation calls.
/obj/item/hilbertshotel/proc/sendToNewRoom(var/roomNumber, var/mob/user)
var/datum/turf_reservation/roomReservation = SSmapping.RequestBlockReservation(hotelRoomTemp.width, hotelRoomTemp.height)
if(ruinSpawned)
@@ -200,7 +202,6 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337)
name = "Hilbert's Hotel Storage"
mappath = '_maps/templates/hilbertshotelstorage.dmm'
-
//Turfs and Areas
/turf/closed/indestructible/hotelwall
name = "hotel wall"
@@ -359,6 +360,7 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337)
. = ..()
if(ismob(AM))
var/mob/M = AM
+ parentSphere?.checked_in_ckeys -= M.ckey
if(M.mind)
var/stillPopulated = FALSE
var/list/currentLivingMobs = GetAllContents(/mob/living) //Got to catch anyone hiding in anything
diff --git a/code/modules/spells/spell_types/aimed.dm b/code/modules/spells/spell_types/aimed.dm
index 73a428af71..5ba85bef6b 100644
--- a/code/modules/spells/spell_types/aimed.dm
+++ b/code/modules/spells/spell_types/aimed.dm
@@ -94,9 +94,9 @@
name = "Lightning Bolt"
desc = "Fire a high powered lightning bolt at your foes!"
school = "evocation"
- charge_max = 200
+ charge_max = 150
clothes_req = 1
- invocation = "UN'LTD P'WAH"
+ invocation = "ZAP MUTHA'FUCKA"
invocation_type = "shout"
cooldown_min = 30
active_icon_state = "lightning"
@@ -112,12 +112,12 @@
name = "Fireball"
desc = "This spell fires a fireball at a target and does not require wizard garb."
school = "evocation"
- charge_max = 60
+ charge_max = 100
clothes_req = 0
invocation = "ONI SOMA"
invocation_type = "shout"
range = 20
- cooldown_min = 20 //10 deciseconds reduction per rank
+ cooldown_min = 20 //20 deciseconds reduction per rank
projectile_type = /obj/item/projectile/magic/aoe/fireball
base_icon_state = "fireball"
action_icon_state = "fireball0"
diff --git a/code/modules/spells/spell_types/emplosion.dm b/code/modules/spells/spell_types/emplosion.dm
index a5ba0a3914..98723273ae 100644
--- a/code/modules/spells/spell_types/emplosion.dm
+++ b/code/modules/spells/spell_types/emplosion.dm
@@ -1,6 +1,8 @@
/obj/effect/proc_holder/spell/targeted/emplosion
name = "Emplosion"
desc = "This spell emplodes an area."
+ charge_max = 250
+ cooldown_min = 50
var/emp_heavy = 2
var/emp_light = 3
diff --git a/code/modules/spells/spell_types/forcewall.dm b/code/modules/spells/spell_types/forcewall.dm
index ed78e3315a..aa2fa5ab8b 100644
--- a/code/modules/spells/spell_types/forcewall.dm
+++ b/code/modules/spells/spell_types/forcewall.dm
@@ -2,7 +2,7 @@
name = "Forcewall"
desc = "Create a magical barrier that only you can pass through. Does not require wizard garb."
school = "transmutation"
- charge_max = 100
+ charge_max = 80
clothes_req = 0
invocation = "TARCOL MINTI ZHERI"
invocation_type = "shout"
@@ -10,7 +10,7 @@
action_icon_state = "shield"
range = -1
include_user = 1
- cooldown_min = 50 //12 deciseconds reduction per rank
+ cooldown_min = 15 //15 deciseconds reduction per rank
var/wall_type = /obj/effect/forcefield/wizard
/obj/effect/proc_holder/spell/targeted/forcewall/cast(list/targets,mob/user = usr)
diff --git a/code/modules/spells/spell_types/lightning.dm b/code/modules/spells/spell_types/lightning.dm
index 8363e28624..56d7dc771f 100644
--- a/code/modules/spells/spell_types/lightning.dm
+++ b/code/modules/spells/spell_types/lightning.dm
@@ -2,7 +2,7 @@
name = "Tesla Blast"
desc = "Blast lightning at your foes!"
charge_type = "recharge"
- charge_max = 300
+ charge_max = 270
clothes_req = 1
invocation = "UN'LTD P'WAH!"
invocation_type = "shout"
diff --git a/code/modules/spells/spell_types/wizard.dm b/code/modules/spells/spell_types/wizard.dm
index a2d7612681..e098fe389d 100644
--- a/code/modules/spells/spell_types/wizard.dm
+++ b/code/modules/spells/spell_types/wizard.dm
@@ -152,19 +152,21 @@
sound1 = 'sound/magic/teleport_diss.ogg'
sound2 = 'sound/magic/teleport_app.ogg'
-/obj/effect/proc_holder/spell/aoe_turf/conjure/timestop
+/obj/effect/proc_holder/spell/aoe_turf/timestop
name = "Stop Time"
desc = "This spell stops time for everyone except for you, allowing you to move freely while your enemies and even projectiles are frozen."
charge_max = 500
clothes_req = 1
- invocation = "TOKI WO TOMARE"
+ invocation = "TOKI YO TOMARE"
invocation_type = "shout"
range = 0
cooldown_min = 100
- summon_amt = 1
action_icon_state = "time"
+ var/timestop_range = 2
+ var/timestop_duration = 100
- summon_type = list(/obj/effect/timestop/wizard)
+/obj/effect/proc_holder/spell/aoe_turf/timestop/cast(list/targets, mob/user = usr)
+ new /obj/effect/timestop/magic(get_turf(user), timestop_range, timestop_duration, list(user))
/obj/effect/proc_holder/spell/aoe_turf/conjure/carp
name = "Summon Carp"
diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm
index 93ed149a2b..b2beeebe78 100644
--- a/code/modules/surgery/organs/augments_chest.dm
+++ b/code/modules/surgery/organs/augments_chest.dm
@@ -84,6 +84,8 @@
to_chat(owner, "You feel a faint buzzing as your reviver implant starts patching your wounds...")
/obj/item/organ/cyberimp/chest/reviver/proc/heal()
+ if(!owner)
+ return
if(owner.getOxyLoss())
owner.adjustOxyLoss(-5)
revive_cost += 0.5 SECONDS
diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm
index 2ddbd672c5..c09d1ac1fc 100644
--- a/code/modules/surgery/organs/eyes.dm
+++ b/code/modules/surgery/organs/eyes.dm
@@ -43,7 +43,7 @@
else
eye_color = H.eye_color
if(!special)
- H.dna?.species?.handle_body() //regenerate eyeballs overlays.
+ H.dna?.species?.handle_body(H) //regenerate eyeballs overlays.
M.update_tint()
owner.update_sight()
diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm
index bc59ee397c..fc70e64a82 100755
--- a/code/modules/surgery/organs/liver.dm
+++ b/code/modules/surgery/organs/liver.dm
@@ -60,9 +60,10 @@
//Just in case
/obj/item/organ/liver/Remove(mob/living/carbon/M, special = 0)
..()
- M.remove_movespeed_modifier(LIVER_SWELLING_MOVE_MODIFY)
- M.ResetBloodVol() //At the moment, this shouldn't allow application twice. You either have this OR a thirsty ferret.
- sizeMoveMod(1, M)
+ if(!QDELETED(M))
+ M.remove_movespeed_modifier(LIVER_SWELLING_MOVE_MODIFY)
+ M.ResetBloodVol() //At the moment, this shouldn't allow application twice. You either have this OR a thirsty ferret.
+ sizeMoveMod(1, M)
//Applies some of the effects to the patient.
/obj/item/organ/liver/proc/pharmacokinesis()
diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm
index 18dc34e34b..3acdf6c827 100644
--- a/code/modules/uplink/uplink_items.dm
+++ b/code/modules/uplink/uplink_items.dm
@@ -164,4 +164,4 @@
//Discounts (dynamically filled above)
/datum/uplink_item/discounts
- category = "Discounted Gear"
+ category = "Discounted Gear"
\ No newline at end of file
diff --git a/code/modules/uplink/uplink_items/uplink_devices.dm b/code/modules/uplink/uplink_items/uplink_devices.dm
index 70c70a61b9..7ed84ffdf4 100644
--- a/code/modules/uplink/uplink_items/uplink_devices.dm
+++ b/code/modules/uplink/uplink_items/uplink_devices.dm
@@ -135,6 +135,12 @@
item = /obj/item/aiModule/syndicate
cost = 9
+/datum/uplink_item/device_tools/headsetupgrade
+ name = "Headset Upgrader"
+ desc = "A device that can be used to make one headset immune to flashbangs."
+ item = /obj/item/headsetupgrader
+ cost = 3
+
/datum/uplink_item/device_tools/medgun
name = "Medbeam Gun"
desc = "A wonder of Syndicate engineering, the Medbeam gun, or Medi-Gun enables a medic to keep his fellow \
diff --git a/code/modules/vending/clothesmate.dm b/code/modules/vending/clothesmate.dm
index 0b1d8e1072..af720f6d4e 100644
--- a/code/modules/vending/clothesmate.dm
+++ b/code/modules/vending/clothesmate.dm
@@ -144,7 +144,13 @@
/obj/item/clothing/head/cowboyhat/white = 3,
/obj/item/clothing/head/cowboyhat/pink = 3,
/obj/item/clothing/shoes/cowboyboots = 3,
- /obj/item/clothing/shoes/cowboyboots/black = 3)
+ /obj/item/clothing/shoes/cowboyboots/black = 3,
+ /obj/item/clothing/under/lunar/qipao = 3,
+ /obj/item/clothing/under/lunar/qipao/white = 3,
+ /obj/item/clothing/under/lunar/qipao/red = 3,
+ /obj/item/clothing/under/lunar/cheongsam = 3,
+ /obj/item/clothing/under/lunar/cheongsam/white = 3,
+ /obj/item/clothing/under/lunar/cheongsam/red = 3)
contraband = list(/obj/item/clothing/under/syndicate/tacticool = 3,
/obj/item/clothing/under/syndicate/tacticool/skirt = 3,
/obj/item/clothing/mask/balaclava = 3,
diff --git a/code/modules/vore/eating/belly_obj.dm b/code/modules/vore/eating/belly_obj.dm
index ad54c8a0c8..f88f6bd6e8 100644
--- a/code/modules/vore/eating/belly_obj.dm
+++ b/code/modules/vore/eating/belly_obj.dm
@@ -1,4 +1,5 @@
-//#define VORE_SOUND_FALLOFF 0.05
+#define VORE_SOUND_FALLOFF 0.1
+#define VORE_SOUND_RANGE 3
//
// Belly system 2.0, now using objects instead of datums because EH at datums.
@@ -164,7 +165,12 @@
. = ..()
// Called whenever an atom enters this belly
-/obj/belly/Entered(var/atom/movable/thing,var/atom/OldLoc)
+/obj/belly/Entered(atom/movable/thing, atom/OldLoc)
+ . = ..()
+ var/mob/living/L //for chat messages and blindness
+ if(isliving(thing))
+ L = thing
+ L.become_blind("belly_[REF(src)]")
if(OldLoc in contents)
return //Someone dropping something (or being stripdigested)
@@ -175,7 +181,7 @@
if(vore_sound && !recent_sound)
if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, owner))
+ for(var/mob/living/H in get_hearers_in_view(VORE_SOUND_RANGE, owner))
if(!H.client || !(H.client.prefs.cit_toggles & EATING_NOISES))
continue
LAZYADD(hearing_mobs, H)
@@ -189,11 +195,14 @@
SEND_SOUND(H,eating)
recent_sound = TRUE
- //Messages if it's a mob
- if(isliving(thing))
- var/mob/living/M = thing
- if(desc)
- to_chat(M, "[desc]")
+ if(L && desc)
+ to_chat(L, "[desc]")
+
+/obj/belly/Exited(atom/movable/AM, atom/newloc)
+ . = ..()
+ if(isliving(AM))
+ var/mob/living/L = AM
+ L.cure_blind("belly_[REF(src)]")
// Release all contents of this belly into the owning mob's location.
// If that location is another mob, contents are transferred into whichever of its bellies the owning mob is in.
@@ -214,7 +223,6 @@
continue
L.absorbed = FALSE
L.stop_sound_channel(CHANNEL_PREYLOOP)
- L.cure_blind("belly_[REF(src)]")
SEND_SIGNAL(OW, COMSIG_CLEAR_MOOD_EVENT, "fedpred", /datum/mood_event/fedpred)
SEND_SIGNAL(L, COMSIG_CLEAR_MOOD_EVENT, "fedprey", /datum/mood_event/fedprey)
SEND_SIGNAL(OW, COMSIG_ADD_MOOD_EVENT, "emptypred", /datum/mood_event/emptypred)
@@ -229,7 +237,7 @@
if(release_sound && !recent_sound)
if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, owner))
+ for(var/mob/living/H in get_hearers_in_view(VORE_SOUND_RANGE, owner))
if(!H.client || !(H.client.prefs.cit_toggles & EATING_NOISES))
continue
LAZYADD(hearing_mobs, H)
@@ -237,7 +245,7 @@
for(var/mob/living/H in hearing_mobs)
if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
var/sound/releasement = GLOB.pred_release_sounds[release_sound]
- SEND_SOUND(H,releasement)
+ H.playsound_local(owner.loc, releasement, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF)
else if(H && H in contents && H.client)
var/sound/releasement = GLOB.prey_release_sounds[release_sound]
SEND_SOUND(H,releasement)
@@ -262,7 +270,6 @@
var/mob/living/OW = owner
if(ML.client)
ML.stop_sound_channel(CHANNEL_PREYLOOP) //Stop the internal loop, it'll restart if the isbelly check on next tick anyway
- ML.cure_blind("belly_[REF(src)]")
SEND_SIGNAL(OW, COMSIG_CLEAR_MOOD_EVENT, "fedpred", /datum/mood_event/fedpred)
SEND_SIGNAL(ML, COMSIG_CLEAR_MOOD_EVENT, "fedprey", /datum/mood_event/fedprey)
SEND_SIGNAL(OW, COMSIG_ADD_MOOD_EVENT, "emptypred", /datum/mood_event/emptypred)
@@ -294,7 +301,7 @@
for(var/mob/living/H in hearing_mobs)
if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
var/sound/releasement = GLOB.pred_release_sounds[release_sound]
- SEND_SOUND(H,releasement)
+ H.playsound_local(owner.loc, releasement, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF)
else if(H && H in contents && H.client)
var/sound/releasement = GLOB.prey_release_sounds[release_sound]
SEND_SOUND(H,releasement)
@@ -325,7 +332,6 @@
for(var/mob/living/M in contents)
M.updateVRPanel()
- M.become_blind("belly_[REF(src)]")
// Setup the autotransfer checks if needed
if(transferlocation != null && autotransferchance > 0)
@@ -345,13 +351,11 @@
if(!(content in src) || !istype(target))
return
content.forceMove(target)
- for(var/mob/living/M in contents)
- M.cure_blind("belly_[REF(src)]")
-// target.nom_mob(content, target.owner)
+
if(vore_sound && !recent_sound && !silent)
if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, owner))
+ for(var/mob/living/H in get_hearers_in_view(VORE_SOUND_RANGE, owner))
if(!H.client || !(H.client.prefs.cit_toggles & EATING_NOISES))
continue
LAZYADD(hearing_mobs, H)
@@ -359,7 +363,7 @@
for(var/mob/living/H in hearing_mobs)
if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
var/sound/eating = GLOB.pred_vore_sounds[vore_sound]
- SEND_SOUND(H,eating)
+ H.playsound_local(owner.loc, eating, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF)
else if(H && H in contents && H.client)
var/sound/eating = GLOB.prey_vore_sounds[vore_sound]
SEND_SOUND(H,eating)
@@ -576,7 +580,7 @@
var/sound/struggle_rustle = sound(get_sfx("rustle"))
LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, owner))
+ for(var/mob/living/H in get_hearers_in_view(VORE_SOUND_RANGE, owner))
if(!H.client || !(H.client.prefs.cit_toggles & EATING_NOISES))
continue
LAZYADD(hearing_mobs, H)
@@ -584,14 +588,14 @@
if(is_wet)
for(var/mob/living/H in hearing_mobs)
if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
- SEND_SOUND(H,pred_struggle_snuggle)
+ H.playsound_local(owner.loc, pred_struggle_snuggle, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF)
else if(H && H in contents && H.client)
SEND_SOUND(H,prey_struggle_snuggle)
else
for(var/mob/living/H in hearing_mobs)
if(H && H.client)
- SEND_SOUND(H, struggle_rustle)
+ H.playsound_local(owner.loc, struggle_rustle, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF)
for(var/mob/living/H in hearing_mobs)
if(H && H.client && (isturf(H.loc)))
diff --git a/code/modules/vore/eating/bellymodes.dm b/code/modules/vore/eating/bellymodes.dm
index 0ecaf49abc..6942a2d5a9 100644
--- a/code/modules/vore/eating/bellymodes.dm
+++ b/code/modules/vore/eating/bellymodes.dm
@@ -18,7 +18,8 @@
return SSBELLIES_PROCESSED
next_process = times_fired + (6 SECONDS/wait) //Set up our next process time.
- var/to_update = FALSE
+ var/play_sound //Potential sound to play at the end to avoid code duplication.
+ var/to_update = FALSE //Did anything update worthy happen?
/////////////////////////// Auto-Emotes ///////////////////////////
if(contents.len && next_emote <= times_fired)
@@ -40,7 +41,7 @@
if(M.client.prefs.cit_toggles & DIGESTION_NOISES)
var/sound/preyloop = sound('sound/vore/prey/loop.ogg')
M.playsound_local(get_turf(src),preyloop, 80,0, channel = CHANNEL_PREYLOOP)
- M.next_preyloop = (world.time + 51 SECONDS)
+ M.next_preyloop = (world.time + 52 SECONDS)
/////////////////////////// Exit Early ////////////////////////////
@@ -71,18 +72,9 @@
for (var/mob/living/M in contents)
if(prob(25))
- if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
- LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, owner))
- if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES))
- continue
- LAZYADD(hearing_mobs, H)
- last_hearcheck = world.time
- for(var/mob/living/H in hearing_mobs)
- if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
- SEND_SOUND(H,pred_digest)
- else if(H && H in contents && H.client)
- SEND_SOUND(H,prey_digest)
+ if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
+ SEND_SOUND(M,prey_digest)
+ play_sound = pick(pred_digest)
//Pref protection!
if (!M.digestable || M.absorbed)
@@ -108,18 +100,9 @@
M.visible_message("You watch as [owner]'s form loses its additions.")
owner.nutrition += 400 // so eating dead mobs gives you *something*.
- if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
- LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, owner))
- if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES))
- continue
- LAZYADD(hearing_mobs, H)
- last_hearcheck = world.time
- for(var/mob/living/H in hearing_mobs)
- if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
- SEND_SOUND(H,pred_death)
- else if(H && H in contents && H.client)
- SEND_SOUND(H,prey_death)
+ play_sound = pick(pred_death)
+ if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
+ SEND_SOUND(M,prey_death)
M.stop_sound_channel(CHANNEL_PREYLOOP)
digestion_death(M)
owner.update_icons()
@@ -142,19 +125,9 @@
if(digest_mode == DM_HEAL)
for (var/mob/living/M in contents)
if(prob(25))
- if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
- LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, owner))
- if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES))
- continue
- LAZYADD(hearing_mobs, H)
- last_hearcheck = world.time
- for(var/mob/living/H in hearing_mobs)
- if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
- SEND_SOUND(H,pred_digest)
- else if(H && H in contents && H.client)
- SEND_SOUND(H,prey_digest)
-
+ if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
+ SEND_SOUND(M,prey_digest)
+ play_sound = pick(pred_digest)
if(M.stat != DEAD)
if(owner.nutrition >= NUTRITION_LEVEL_STARVING && (M.health < M.maxHealth))
M.adjustBruteLoss(-3)
@@ -165,18 +138,10 @@
//for when you just want people to squelch around
if(digest_mode == DM_NOISY)
if(prob(35))
- if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
- LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, owner))
- if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES))
- continue
- LAZYADD(hearing_mobs, H)
- last_hearcheck = world.time
- for(var/mob/living/H in hearing_mobs)
- if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
- SEND_SOUND(H,pred_digest)
- else if(H && H in contents && H.client)
- SEND_SOUND(H,prey_digest)
+ for(var/mob/M in contents)
+ if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
+ SEND_SOUND(M,prey_digest)
+ play_sound = pick(pred_digest)
//////////////////////////// DM_ABSORB ////////////////////////////
@@ -185,18 +150,9 @@
for (var/mob/living/M in contents)
if(prob(10))//Less often than gurgles. People might leave this on forever.
- if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
- LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, owner))
- if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES))
- continue
- LAZYADD(hearing_mobs, H)
- last_hearcheck = world.time
- for(var/mob/living/H in hearing_mobs)
- if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
- SEND_SOUND(H,pred_digest)
- else if(H && H in contents && H.client)
- SEND_SOUND(H,prey_digest)
+ if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
+ SEND_SOUND(M,prey_digest)
+ play_sound = pick(pred_digest)
if(M.absorbed)
continue
@@ -262,18 +218,9 @@
to_chat(owner, "[digest_alert_owner]")
to_chat(M, "[digest_alert_prey]")
M.visible_message("You watch as [owner]'s guts loudly rumble as it finishes off a meal.")
- if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
- LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, owner))
- if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES))
- continue
- LAZYADD(hearing_mobs, H)
- last_hearcheck = world.time
- for(var/mob/living/H in hearing_mobs)
- if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
- SEND_SOUND(H,pred_death)
- else if(H && H in contents && H.client)
- SEND_SOUND(H,prey_death)
+ play_sound = pick(pred_death)
+ if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
+ SEND_SOUND(M,prey_death)
M.spill_organs(FALSE,TRUE,TRUE)
M.stop_sound_channel(CHANNEL_PREYLOOP)
digestion_death(M)
@@ -293,6 +240,19 @@
if(istype(T,/obj/item/reagent_containers/food) || istype(T,/obj/item/organ))
digest_item(T)
+/////////////////////////// Make any noise ///////////////////////////
+ if(play_sound)
+ if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
+ LAZYCLEARLIST(hearing_mobs)
+ for(var/mob/M in hearers(VORE_SOUND_RANGE, owner))
+ if(!M.client || !(M.client.prefs.cit_toggles & DIGESTION_NOISES))
+ continue
+ LAZYADD(hearing_mobs, M)
+ last_hearcheck = world.time
+ for(var/mob/M in hearing_mobs) //so we don't fill the whole room with the sound effect
+ if(M && M.client && (isturf(M.loc) || (M.loc != src.contents))) //to avoid people on the inside getting the outside sounds and their direct sounds + built in sound pref check
+ M.playsound_local(owner.loc, play_sound, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF)
+ //these are all external sound triggers now, so it's ok.
if(to_update)
for(var/mob/living/M in contents)
if(M.client)
diff --git a/config/game_options.txt b/config/game_options.txt
index 9fc50fcd0f..97c5ff3a68 100644
--- a/config/game_options.txt
+++ b/config/game_options.txt
@@ -39,7 +39,7 @@ WALK_DELAY 4
## Entries completely override all subtypes. Later entries have precedence over earlier entries.
## This means if you put /mob 0 on the last entry, it will null out all changes, while if you put /mob as the first entry and
## /mob/living/carbon/human on the last entry, the last entry will override the first.
-##MULTIPLICATIVE_MOVESPEED /mob/living/carbon/human 0
+MULTIPLICATIVE_MOVESPEED /mob/living/carbon/human 1
##MULTIPLICATIVE_MOVESPEED /mob/living/silicon/robot 0
##MULTIPLICATIVE_MOVESPEED /mob/living/carbon/monkey 0
##MULTIPLICATIVE_MOVESPEED /mob/living/carbon/alien 0
diff --git a/html/changelog.html b/html/changelog.html
index 60412299cf..349a8ce012 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -50,6 +50,463 @@
-->
+
27 January 2020
+
4dplanner, CRITAWAKETS, XDTM, ninjanomnom updated:
+
+ - sepia slime extract has a delay before activating
+ - the user of a sepia slime extract is no longer immune to the time field
+ - chilling sepia is now the support extract - it always freezes the user, but not other marked people. give one to your golem!
+ - burning sepia spawns the rewind camera. Take a selfie with someone and give it to them to make sure they remember the moment forever! You don't actually need to give them the photo, they'll remember anyway. Keep it as a reminder.
+ - rewinding (deja vu) effect resets your location to the turf you were on after 10 seconds as well as resetting limbs/mobs/objects damage to the point it was added.
+ - The deja vu effect cannot resurrect the dead, but will heal their corpse. New limbs fall off, old ones re-attach
+ - Regenerative sepia cores add a deja vu effect before healing instead of a timestop remove: timefreeze camera is admin spawn only.
+ - recurring sepia recalls to the hand of the last person to touch it after activating. Reusable timestop grenades!
+ - some special cameras don't prompt for customisation
+ - timefreeze camera actually makes a photo
+ - timestop stops pathing and mechs.
+ - adds a check to make sure simple_animals don't get their AI toggled while sentient
+ - Adds the timestop overlay to frozen projectiles
+ - Timestopped things have INFINITY move_resist as opposed to being anchored
+ - Timestop will now unfreeze things that somehow leave it
+ - mobs in the middle of a walk_to will have their walk stopped by timestop
+ - mobs that are stunned will be stopped mid walk as well
+ - pulling respects changes in move_force
+ - swapping places respects move_force if the participant is not willing
+ - timestop is properly defeated by antimagic.
+ - timestop only checks antimagic once
+ - Time stop now applies its visual effect on floors, walls and static structures (with no change otherwise)
+ - Movable structures are now anchored while time stopped.
+ - Timestop effects now prevent speech.
+
+
AffectedArc07 updated:
+
+ - All code files are now in the LF line format, please stick to it
+ - Added CI step to check for CRLF files
+ - Line ending CI works now
+
+
Arkatos, Zxaber, Ghommie updated:
+
+ - Certain AI abilities now dynamically show their remaining uses on the mouse hover over their respective action buttons.
+ - Malfunctioning AIs can no longer abuse the confirmation popup to create extra (unstoppable) doomsdays.
+ - Fixed AIs being able to use some of their abilities such as the doomsday whilst dead, and the doomsday loading phase not halting upon AI death.
+
+
Arturlang updated:
+
+ - Vampires are no longer as tanky
+ - Added modular computers to the loadout
+
+
Bhijn updated:
+
+ - Limbs now regenerate their stamina faster while disabled
+ - Limbs now have the same incoming stamina damage multiplier mechanics as spacemen, where the more staminaloss they take while disabled, the less staminaloss they'll take.
+ - Limbs have had their base stamina regen rate doubled to match the doubled stamina regen rate of standard spacemen.
+ - Added a preference to make the sprint hotkey be a toggle instead of a hold bind
+ - Added a preference to bind the sprint hotkey to space instead of shift.
+ - server_hop can no longer be used to remotely lobotomize a spaceman
+
+
Bhijn helped updated:
+
+ - Fixes Dragon's Tooth Sword 50% armor penetration by making it 35%
+
+
BonniePandora updated:
+
+ - Added another SDQL option. Using "UPDATE selectors SET #null=value" will now resolve value and discard the return. This is useful if you only care about the side effect of a proc.
+
+
CameronWoof updated:
+
+ - Ghost Cafe patrons now spawn with chameleon kits. Dress up! Be fancy!
+ - Robots can now check the crew manifest from anywhere with the "View Crew Manifest" verb.
+ - Lizard tails are now viable options for humans and anthromorphs.
+
+
Commandersand updated:
+
+ - fixed some clothnig sprites
+ - lightning bolt,tesla,forcewall,emp spells have lower cooldown
+ - fireball has a 10 second starting cooldown
+
+
DeltaFire15 updated:
+
+ - Vitality matrixes now correctly succ slimes
+
+
Denton, ported by Hatterhat updated:
+
+ - Most upgradeable machines now show their upgrade status when examined while standing right next to them.
+ - Added examine messages to teleporter stations that hint at their multitool/wirecutter interactions.
+ - Renamed teleporter stations from station to teleporter station.
+ - Changed the teleporter hub accurate var to accuracy; the old name misled people into thinking that it was a boolean.
+
+
Detective-Google updated:
+
+ - replaced the sprites with new ones requested.
+
+
EmeraldSundisk updated:
+
+ - Adds a sign outside MetaStation's custodial closet
+
+
FantasticFwoosh, ported by Hatterhat updated:
+
+ - Both reagent universal enzyme & sacks of flour are now available for their respective costs from the biogenerator.
+ - New crafting recipies for donut boxes, eggboxes & candle boxes have been added to cardboard recipes for the collective benefit of service personnel and the station.
+
+
Ghommie updated:
+
+ - Attached kevlar/soft/plastic padding accessories are now stealthier and will no longer be displayed on mob examine.
+ - Refactored that mess of a code for alternate worn clothing sprites for digitigrade and taurs.
+ - Fixed some issues with the aforementioned feature you may or may not have experienced because it was pretty lame.
+ - Fixed missing digi versions fishnet sprites and wrong digitigrade left dir purple stockings sprite.
+ - Add digitigrade versions for boxers and the long johns.
+ - Fixed the secret sauce recipe being randomized every round.
+ - Fixed singularity pulls duping rods out of engine floors.
+ - Removed an old pair of zipties from the captain closet.
+ - Chestbursters won't delete the host's brain somewhat anymore.
+ - Fixed roundstart mushpeople being unable to MUSH PUUUUUUUUUUUUNCH!!
+ - Lattices can be examined yet again.
+ - Made reagent containers examine text less annoying.
+ - Virus food dispensers dispense virus food again.
+ - Borg hypos inputs do not display typepaths anymore.
+ - Restored chem dispensers alphabetical order.
+ - Sanitized cargo export messages for reagents.
+ - Riot foam dart (not the ammo box) design cost is yet again consistent with the result's material amount.
+ - Fixed a little exploit with ventcrawlers being capable of escaping closed turfs by printing scrubbers/vents into them.
+ - deconstructing a rubber toolbox with the destructive analyzer won't "lock" the machine anymore.
+ - Something about empty hand combat mode right click waving hands defying common sense and being spammy.
+ - Towels are now "digitigrade-friendly".
+ - The Barefoot drink and mousetraps will now work even if wearing certain "feet-less shoes".
+ - Refactored code to allow all living mobs to use shields and not only humans.
+ - Monkys will now retaliate against aliens attacking them (as if they even posed a threat to start with).
+ - add a click cooldown to the overly spammable table slamming.
+
+
Ghommie (original PRs by Kevinz000, ShivCalez, 4dplanner, Barhandar, 81Denton, zxaber, Fox-McCloud) updated:
+
+ - All atom movables now have move force and move resist, and pull force An atom can only pull another atom if its pull force is stronger than that atom's move resist
+ - Mobs with a higher move force than an atom's move resist will automatically try to force the atom out of its way. This might not always work, depending on how snowflakey code is. experimental: As of right now, everything has a move force and resist of 100, and a pull force of 101. Things take (resist - force) damage when bumped into experimental: Failing to move onto a tile will now still bump up your last move timer. However, successfully pushing something out of your way will result in you automatically moving into where it was.
+ - Bolted AIs can no longer be teleported by launchpads.
+ - Megafauna cannot teleport
+
+
Hatterhat updated:
+
+ - Beakers are generally more useful now, with slight capacity increases.
+ - Transfer amounts are different now. Adjust your muscle memory to compensate.
+ - ore redemption machines actually get affected by lasers again kthx
+ - crusher trophy drop chance on mining mobs increased to 1 in 4 (from 1 in 20)
+ - Blood-drunk buff from blood-drunk eye crusher trophy is less likely to cripple its user.
+ - Forcefield projectors now fit on toolbelts.
+ - New sprites for ATMOS holofan and forcefield projectors!
+ - tweaks some values around with beaker transfer amounts, adds a transfer value verb (altclick)
+ - Syndicate sleepers (read: the ones that're red and have controls in them) can now be recreated with a sufficient basis in nonstandard (read: illegal) technologies!
+ - Explorer hoods on standard explorer suits can be reinforced with goliath hide plates again.
+ - A shipment of Staff Assistant jumpsuits from the Goon-operated stations appear to have made their way into your loadout selections - and into the contraband list from ClothesMates...
+ - Dropped Exo-suit armor to put it more in line with being an explorer suit sidegrade and not a straight upgrade for Lavaland usage.
+ - You can now print .357 AP speedloaders from Security techfabs after you pick up the Advanced Non-Standard Ballistics node.
+ - Forensic scanner removed from Advanced Biotechnology node.
+ - Ash Drake armor now has goliath resistance, same as the Exo-suit.
+
+
KathrinBailey updated:
+
+ - Empty engineering lockers for mappers.
+ - Industrial welding tools to the engineer welding locker.
+ - Removed the multitool, airlock painter, mechanical toolbox, brown sneakers, hazard vest and airlock painter from the CE's locker.
+
+
KeRSedChaplain updated:
+
+ - The clockwork cuirass can now support slithering taur bodies.
+
+
Kevinz000 updated:
+
+ - Fixes successful projectile hits also striking another atom on the same turf should the first one be not the target the projectile was meant for.
+ - Removes infinite reflector loops.
+
+
Kraseo updated:
+
+ - Jelly donuts and pink jelly donuts will now properly display sprinkled icon state.
+ - Jelly donuts and its variants will properly spawn with berry juice.
+ - Slime jelly donuts have slime jelly in them now. (thanks ghommie)
+ - Virgo hairstyles no longer have those annoying quotation marks. Rejoice for you will no longer have to use the scrollbar.
+ - Got rid of some strange-looking hairstyles. (Tbob, fingerweave, etc.)
+
+
LetterN updated:
+
+ - Doppler logs
+ - Shockcolar and electropack uses the new signaler ui
+ - Renaming shockcolar requires a pen
+ - Adds banjo
+
+
Linzolle updated:
+
+ - fixes matchboxes runtiming every time they spawn
+
+
MrJWhit updated:
+
+ - Increases plasma usage in radiation collectors
+
+
Naksu updated:
+
+ - reagent IDs have been removed in favor using reagent typepaths where applicable
+ - mechas, borg hyposprays etc no longer display internal reagent ids to the player
+
+
Owai-Seek updated:
+
+ - Four New Bounties
+ - tweaked several bounties
+ - reorganised several bounties
+ - balanced several bounties
+ - added shady jims to vendor
+ - Towel, Bedsheet, and Colored bedsheet bins to Dojo. Some lockers with carpets and wood, another bathroom/shower, tons of cleaning supplies, some additional trash cans, a tiny medical area, and some vendors/vendor resupplies. Also added some Ambrosia Gaia seeds.
+ - Moved some lights around, extended the dojo a bit to make it feel more spacious.
+ - Cafe Newsfeed Frame
+
+
PersianXerxes updated:
+
+ - Reduces the range of the forcefield projector from 7 tiles to 2 tiles.
+
+
Putnam updated:
+
+ - Alcohol intolerance trait, which forces vomiting on any alcohol ingestion
+ - Arousal damage is gone, and with it the arousal damage heart on the UI.
+ - As exhibitionist relied on arousal damage, that's gone too.
+ - Bonermeter and electronic stimulation circuit modules are gone.
+ - Masturbation is no longer an option in the climax menu. It was identical to climax alone in every way but text. Emote it out.
+ - Arousal on genitals can now be displayed manually, on a case-by-case basis.
+ - "Climax alone" and "climax with partner" now only display to the people directly involved in the interaction. rework: Catnip tea, catnip, crocin, hexacrocin, camphor, hexacamphor all had functions or bits of functions reworked.
+ - "Climax with partner" now requires consent from both parties--it can no longer be used on mindless mobs, and it asks the mob getting climaxed with if they consent first.
+ - A lot of MKUltra behaviors have been moved to hypno checks or removed due to reliance on maso/nympho/exhib.
+ - Cold-blooded quirk
+ - Two relief valves for atmospherics, available in your RPD today: a unary one that opens to air and a binary one that connects two pipenets, like a manual valve.
+ - The atmos waste outlet injector on box has been replaced with an atmos waste relief valve.
+
+
Putnam3145 updated:
+
+ - Dynamic storytellers, a new voting paradigm for dynamic
+ - Support for approval voting and condorcet (ranked choice) voting in server votes
+ - Ghost cafe mobs can now ghostize
+ - Ghost cafe now has a cremator
+ - Ghost cafe mobs are now eligible for ghost roles
+ - Ghost roles now use an element for eligibility purposes
+ - You can toggle some prefs properly now.
+ - no ass slap is no longer the same thing as no aphro
+ - Devastating bombs kills bomb armor'd mobs again
+ - Added a sort of "game mode ban" by way of having people rank their game modes favorite to least favorite after the secret/extended vote.
+ - Turns out the schulze scoring was written wrong and it was setting things to 0 that shouldn't have been, so that's fixed.
+ - Random engines are now weighted.
+ - Ghost dojo now has an autoylathe.
+ - Ghost dojo no longer has VR or modular computer access.
+ - Ghost dojo mobs are pacifists.
+ - Ghost dojo booze-o-mat is now all access.
+ - Ghost dojo crematorium now has a button.
+ - Traitor objectives don't take a dump when they try to add an assassinate anymore
+ - Objective removal with antag panel no longer commented out silently while still being an option that gives useful feedback on stuff it's not doing in any respect
+ - Second, temporary flavor text!
+ - Limb damage works now
+ - Score instead of ranked choice for mode tiers
+ - Chemistry not :b:roke
+ - Ghost dojo spawns will dust if their owner suicides or uses the "ghost" verb.
+ - Crafting is logged in a file now
+ - temporary flavor text now pops up properly
+ - demodularized player panel code, mostly
+ - added ghost role eligibility delay removal to player panel
+ - Metabolic synthesis disables if user isn't well-fed rather than if user is starving
+ - Gibtonite no longer instantly explodes upon being pickaxe'd.
+ - Cold-blooded costs -2 quirk points now
+ - Added suicide to the config.
+ - Ghost cafe mobs are super duper attached to the ghost cafe.
+ - Meow Mix bar sign works
+ - Fixed a few relief valve behaviors
+
+
Ryll/Shaps, ported by Hatterhat updated:
+
+ - Point-blanking people with shotguns actually throws them backwards!
+
+
Savotta updated:
+
+
Seris02 updated:
+
+ - made it so trait blacklisting removes random positives instead of removing everything
+ - added atmos holofirelocks and temperature blocking
+ - tweaked how atmos holofan looks
+ - stunglasses
+ - disabler sechuds
+ - adds coconut
+ - adds a coconut bong
+ - Auto ooc
+ - changed "assume direct control" from m.ckey = src.ckey to adminmob.transfer_ckey(M) so it works with auto ooc
+ - marshmallow
+ - telescopic IV drip
+ - cardboard box speed
+ - makes gorilla shuttle emag only
+ - changed where the observe verb is.
+ - the way chameleon clothes update on change
+ - chameleon cloak icon
+ - Explosions now cause knockdown instead of KOs, with the amount of time scaling off bomb armor. Heavy explosions still cause a ~2 second KO for follow up attacks.
+ - Devastating explosions now no longer gib players with more than 50 bomb armor. This used to be more or less random depending on the amount of bomb armor.
+ - Removed reagent explosion code that would trigger for <1 amount reactions.
+ - traitor tool for bowmanizing headsets + bowmanizing headsets
+ - durathread winter coats from hyper station
+ - conveyor belt now are stacks instead of single item
+ - conveyor crate has 30 belts
+ - printing a conveyor costs 3000 metal
+ - you can press the conveyor switch in hand to link any not deployed belts to it
+ - sniffing sneezing etc doing anything if they don't breathe
+ - probably fixes the make mentor button
+ - the sprites for the conveyor belts to look more directional
+
+
Skoglol updated:
+
+ - Falsewalls now properly hide pipes and wires.
+
+
SpaceManiac, bobbahbrown, ShizCalev, SpaceManiac (ported by Ghommie) updated:
+
+ - It is now possible to set a different most-base-turf per z-level.
+ - Removed unlawful reference to Disney's Star Wars franchise in map logging.
+ - Moved mapping related errors to their own log file.
+ - Destruction on Lavaland will no longer reveal space in rare situations.
+
+
Tlaltecuhtli, Nemvar, Trilby, Hatterhat updated:
+
+ - russian surplus crate, sec ammo crate, meat/veggie/fruit crate, rped crate, bomb suit crate, bio suit crate, parrot crate, chem crate, db crate
+ - lowered price of some crates which are overpriced for no reason aka the tablet crate and the mech circuits crates, track implant crate has also track .38 ammo
+ - sectech vendor has a refill pack
+
+
Trilbyspaceclone updated:
+
+ - Fermi plushie can be made once again
+ - range on Engi Tray scanners and Rad-Scanners
+ - issues with mapping done my Trilby
+ - Grass now makes light beer when distilled
+ - allows bandoliers to hold any ammo type as long as it has a casing
+ - Cleans out the last years of changlogs
+ - rouge cases of #$39; in bottle/pill/patch/condiments
+ - Adds missing but needed flags to MASON RIG
+ - missing sprites with crushed cans
+ - Halfs the nutriments in sugar
+ - Glitter is now makeable with ground plastic and some crayons
+ - Makes more folders and files for uplink.
+ - Seed packs now have RnD points inside them
+ - New tips that reflect the now use seed packs have for Rnd / Chems affect on plants
+ - Made the research file look nice rather then an eye harming list
+ - Fixed fragile space suits breaking from weak and non-damaging "weapons" (such as the Sord, toys and foam darts).
+ - tip of the round: Cleanbot can withstand lava and burning hot ash. Its a god
+ - more glassware
+ - Few new packs and glassmaker kit!
+ - prices/chems of crates/autobottler
+ - some crates ungettable as well as some broken crates
+
+
Trilbyspaceclone, Ghommie updated:
+
+ - More types of glass can now be used to make a solar panel, with different sturdiness and efficiency depending the type.
+
+
Tupinambis updated:
+
+ - Replaces new fire alarms with a slightly updated version of the old ones.
+ - Fixed bug where Amber alert had no proper alert lights, and red alert had amber lights.
+ - RLDs now cost more to use, have reduced matter capacity, and sheets are worth less when refilling them.
+
+
Unit2E & JMoldy, ported by Hatterhat updated:
+
+ - the powerfist now punches people away at high velocity depending on setting.
+ - the powerfist now leaks the gas it uses onto the tile you're on.
+ - Adds weak punch variations for empty and near-empty punching.
+
+
Xantholne updated:
+
+ - Christmas clothes that where missing stuff should work again
+ - Christmas clothes moved from clothesmate and loadout to premium autodrobe, hoodies and boots remain.
+ - Botany bee pet, Bumbles
+ - New bee models that aren't 1 tile big of 0 opacity pixels
+ - Cheongsam and Qipao clothing added to loadout and clothesmates
+
+
dapnee updated:
+
+ - new toxin's uniform and accessories
+ - old toxin's uniform and accessories
+
+
deathride58 updated:
+
+ - The stamina buffer no longer uses stamina while recharging.
+
+
jakeramsay007 updated:
+
+ - The assorted .357 revolvers (except russian revolver) can now also load .38, like real life.
+
+
kappa-sama updated:
+
+ - loot crates in cargo contraband
+ - modular_citadel file movement
+ - modular citadel loses some files
+ - dragnet snares can now be removed in 5 seconds
+
+
keronshb updated:
+
+ - Adds new features for nanites
+ - fixed the missing icons from Dermal Button nanites
+ - Ports the special nanite remote, mood programs, and research generating nanites
+ - rebalances some nanites
+ - fixed my messup
+
+
kevinz000 updated:
+
+ - throwing things no longer makes them randomly turned as long as you aren't on harm intent
+ - Custom holoforms have been added for pAIs and AIs. oh and cyborg holograms of specific modules too.
+ - pais are no longer indestructible-flagged while in card form. pai radios now short out if they are forcefully collapsed from damage.
+ - telescopic iv drips now have the proper sanity checks for deployment.
+ - megafauna can hear again
+ - Cargo passive gen is now 500 down from 750.
+ - Added a few more nightshift config entries
+ - nightshift_public_area variable in areas to determine how public an area is.
+ - NIGHT_SHIFT_PUBLIC_AREAS_ONLY config entry allows the server to be configured to only nightshift areas of that level and below (so areas that are more public)
+ - Config entries added for requiring authorizations to toggle nightshift. Defaults to only requiring on public areas as determined by above
+ - nuclear fist buffed.
+ - cogscarabs are now fulltile-hitbox.
+ - emitters are now hitscan
+ - monkies gorrilize easier now
+ - Ghosting no longer stops abductors from using you.
+ - guests can now looc
+ - tableslamming has 0.4 second cooldown instead of 0.8
+ - health analyzers now work
+ - Mapping helpers added for power cables and atmos pipes.
+ - Blood duplication is gone, but viruses now react up to 5 times, 1 time per unit, for virus mix.
+ - you can now block people on your PDA
+ - Grenades can now have their timers adjusted.
+ - Cloning has been nerfed.
+ - hilbert hotel is now less of an exploity mess
+ - Doorcrushes are once again instant.
+
+
nik707 updated:
+
+ - engraving light_power from 1 to 0.3
+
+
r4d6 updated:
+
+ - Added a Radiation Hardsuit
+ - Added a Radiation Hardsuit crate
+ - Added 3 SM Engine variations.
+ - Added a way to make opaque plastic flaps change: Change the already existing flap recipe to show that they are see-through
+ - Animations for the RCD
+ - Said animations being pulled by the Singulo
+ - Prevent Reinforced Doors from being RCD'ed
+ - Deconstructing Floors now cost MUs like everything else
+ - changed the RCD's upgrades into flags
+ - Allow RCDs to print APC, Firelocks and Fire Alarms with the right upgrade
+ - Allow Engineers to print RCDs and RPDs from their protolathe without needing to hack one.
+ - Added a playback device
+ - Made the Voice Analyzer actually care about languages
+ - fixed SM's piping
+ - Added a message when pulsing the open wire.
+ - fixed being able to use a playback device and a voice analyzer to activate each others
+ - added passive vent to the arsenal of atmospheric devices.
+ - Mining base now has a common area accessible via a new shuttle on the medium-highpop maps, and a security office connecting the gulag and the mining base. Gulag also has functional atmos.
+ - Added more Cyborg Landmarks
+ - better code for passive vents
+ - fixed a hole in Meta
+ - Added the ability to easily add variations of the mining base
+ - fixed a sprite
+
+
timothyteakettle updated:
+
+ - fixed not being able to remove trait genes without a disk being inserted into the dna manipulator
+
+
30 December 2019
AnturK updated:
@@ -371,503 +828,6 @@
- Adds Insect markings
- Adds three new moth wings.
-
-
07 December 2019
-
AffectedArc07 updated:
-
- - Fixes a LOT of code edge cases
-
-
Anonymous updated:
-
- - Added NEET-- I mean, DAB Suit and Helmet into loadout. Exclusive to Assistants, for obvious reasons, and don't provide any armor. Goes well with balaclava, finger-less gloves and jackboots for that true tactic~~f~~ool experience.
- - Renamed loadout name appropriately (ASSU -> DAB)
-
-
Arturlang updated:
-
- - PDA catridges cant be irradiated anymore.
-
-
Bhijn updated:
-
- - Item mousedrop() now provides a return value indicating whether or not behavior has been overridden somehow.
- - Defibs now properly check that their loc is the same as the user for mousedrop() calls, meaning ghosts can no longer make you equip defibs. Plus extra sanity checks.
- - Pet carriers no longer attack turfs while trying to unload their contents.
- - Decks of cards now function as they originally intended when attempting to use their drag and drop behavior.
- - Paper bins and papercutters no longer act wonky when you're trying to pull a piece of paper from them.
- - Adds clothing drag n drop sanity checks.
- - Sythetic hats now have extra sanity checks
-
-
Coconutwarrior97 updated:
-
- - Can only wrench down two transit tubes per turf.
-
-
Commandersand updated:
-
- - Added more stuff to loadout,check uniforms mask and backpack
-
-
DeltaFire15 updated:
-
- - Adds eight new plushies
- - Adds icons for the new plushies and adds a new icon for the skylar plush
- - Deleted a old, no-longer used icon for the skylar plush
- - Fixed a typo in the trilby plush
-
-
Fermis updated:
-
- - tweaks botany reagent pHes
- - Purity, Astral, RNG, MK, SMilk, SDGF, furranium, hatmium, eigen, nanite.
- - Eigen and purity.
- - refactored sleepers!
- - Organ fridges to all maps near surgery with a random sensible organ, steralizine and synthtissue.
- - the med hand scanner to be less of a mishmash of random things
- - a little icon to the HUD if someone's heart has failed.
- - Lets neurine's brain splash attack work via syringe.
- - a new surgery; Emergency Cardioversion Induction for use on the recently deceased
- - Synthtissue to be less demanding on growth size for organ regeneration and improves clarify of it's growth gated effects.
- - Synthtissue now is more useful than synthflesh on the dead
-
-
Fox McCloud updated:
-
- - Fixes a very longstanding LINDA bug where turfs adjacent to a hotspot would be less prone to igniting
-
-
Fox McCloud, Ghommie updated:
-
- - Fixes being able to mech-punch other mobs, as a pacifist
- - Fixes being able to hurt people, as a pacifist, by throwing them into a wall or other mob, or by using most martial arts (save for the unpredictable psychotic brawl, and the stamina-damage-only boxing).
- - Buffs boxing to outdamage natural stamina regeneration. Made the chance of outright missing your opponent actually possible.
- - Pacifists can now engage in the (laughably not harmful) sweet sweet art of boxing now.
-
-
Ghommie updated:
-
- - Fixing implant cases being lost inside implant pads when trying to eject them with your active hand full.
- - Moved the implant pad's case ejection from attack_hand() to AltClick(), added examination infos about it.
- - Fixed holodeck sleepers leaving sleeper buffers behind when deleted.
- - Fixed traitor codewords highlight and some other hear signal hooks spans highlight (phobias, split personality, hypnosis) or modifiers (mind echo)
- - Fixed traitor codewords highlight not passing down with the mind datum and stickying to the first mob.
- - Fixed the incongruent bone satchel description.
- - Fixed sofa overlays doing nothing, because their layer wasn't properly set.
- - Suicide and cryo now prevents ghost/midround roles for a definite duration of 30 minutes (and more if that was done before 30 minutes in the game passed), down from the rest of the round.
- - fixed several midround roles bypassing and nulling the aforementioned prevention measures.
- - Fixed the little issue of PDA skins not updating on job equip.
- - Anomaly Crystals of the clowning type will now rename the victim to their clown name preference when triggered, instead of giving them a random clown name.
- - Lowered blob event earliest start from 1 hour to 40 minutes (ergo one third), and the required player population from 40 to 35.
- - Several fixes and QoL for dullahans. They can see and hear visible and audible messages now, don't need a space helmet they can't wear anyway to be space/temperature proof, can examine things through shiftclick, and, most of all, fixed their head being unpickable. Fixed dullahans gibbing when revived or had their limbs regenerated.
- - humans should now drop gibs when gibbed again.
- - synths (not to be confused with IPCs), android and corporate species, as well as robotic simple mobs, will now spawn robotic giblets instead of organic ones.
- - You can't wear dakimakuras in any other inappropriate slots save for the back slot anymore, degenerates.
- - Insert snarky remark about clock welders actually displaying the welder flame overlay when turned on now here.
- - Minor ninja tweaks and stealth nerfs. The stealth penalty for the many combat-related actions, bumping and now teleporting/dashing or firing guns has been increased a by a third. There is now a cooldown of 5 seconds on toggling stealth as well as a slighty slowed stealth in/out animation.
- - Ported slighty better matchbox sprites from CEV-Eris, also resprited cigar boxes myself.
- - Fixed abductors/abductees objectives by porting an objective code.
- - Riding component fix
- - fixing a few runtimes on lightgeists, libido trait, rcd, one admin transformation topic, chem dispensers, glowing robotic eyes...
- - Porting CEV-eris delivery packages sprites and dunking the old syndie cybernetics box sprite.
- - Certain objects shouldn't be able to become radioactive because of a bitflag that previously was checked nowhere in the code anymore.
- - Added a new PDA reskin, sprites from CEV-Eris
- - Clock cult starts with some spare vitality matrix charge scaled of the number of starter servants.
- - Made the vitality matrix sigil slighty more visible, also allowed conversion runes to heal fresh converts at the cost of some vitality charge.
- - Crawling won't save you from the wrath of ocular wardens and pressure sensors anymore, heretics. fix: Pressure sensors are no more triggered by floating/flying mobs.
- - Strawberry milk and tea have sprites now.
- - Fixed the Aux base camera door settings and toggle window type actions. Also enabling the user to modify both door access and type.
- - Improved the two grayscale towel item sprites a little.
- - Fixed towels onmob suit overlays. Again.
- - Fixed some reagents taste descriptions.
- - Fixed hidden random event reports only priting a paper message without sending the message to the consoles' message list.
- - Rosary beads prayer now works on non-carbon mobs too, and won't break when performed on a monkey or other humanoids.
- - You can flagellate people with rosary beads on harm intent. It's even mediocrer than the sord though.
- - Moved the `Stealth and Camouflage Items` uplink category next to `Devices and Tools`.
- - Deleted a duplicate phatom thief mask entry from the uplink.
- - Fixed missing delivery packages sprites
- - fixed a few minor issues with console frames building.
- - Wizards can use the teleport spell from their den once again.
- - Wizards will now receive feedback messages when attempting to cast teleport or use the warp whistle while in a no-teleport area.
- - New clockwork cultist, gondola, monkey and securitron cardboard cutouts.
- - Fixed aliens gasping randomly once in a while.
- - fixed superlube waterflower, my bad.
- - Fixed closing the aux base construction RCD's door access settings window throwing you out of camera mode when closed.
- - Removed not functional aux base RCD's door type menu. Use airlock painters, maybe.
- - Honkbot oil spills are of the slippery kind now. Honk.
- - local code scavenger finds forgotten slighty improved apc sprites left buried in old dusty folders.
- - Seven old and otherwordly pAI holochassis icons have crawled their way out of the modular citadel catacombs.
- - chem dispenser beakers end up in your hand yet again.
- - Bikehorns squeak yet again, the world is safe.
- - Cyborgs can now actually use cameras from a distance.
- - Suicides are yet again painful and instant and won't throw people in deep crit from full health.
- - fixed rogue pixels on the energy gu- ahem blaster carbine... and a few apc lights states being neigh-indistinguishable.
- - Fixed several "behind" layer tail sprites skipping areas normally covered by bodyparts.
- - Morgues' original alert beeping sound has been restored, they no longer go "ammunition depleted"
- - Fixed missing hypereutactic left inhand sprites.
- - Dying, ghosting, having your mind / ckey transferred to another mob, going softcrit or otherwise unconscious now properly turn off combat mode.
- - combat mode can't be toggled on while non fully conscious anymore.
- - Fixed limbs' set_disabled NOT dropping your held items, updating your hand slot inventory screen image, prompting chat messages and making your character scream like a sissy.
- - Lusty xenomoprh maids will now actually clean tiles they travel onto yet again.
- - Fixed double whitespace gap in human and AI examine. Fixed single whitespace in carbon examine.
- - Removed a few useless supply packs: "Siezed" power cells, means of production and promiscous organs.
- - Merged the synthetic blood supply pack into the standard blood supply pack, effectively removing a random type blood pack in favor of two synthetic ones.
- - Merged together premium carpet pack n°1 and n°2 to hold one of each standard pattern.
- - You can no longer estimate the amount of reagents found inside a damp rag.
- - You can now squeeze a rag's reagents into another open container, as long as the other one is not full.
- - Fixed ED-209 being unbuildable past the welding step.
- - Fixed ai displays status being reset to "Neutral" on login, regardless of choice.
- - Fixed tinfoil hats giving random traumas.
-
-
Ghommie (original PR by Denton) updated:
-
- - Added three new .38 ammo types. TRAC bullets, which embed a tracking implant inside the target's body. The implant only lasts for five minutes and doesn't work as a teleport beacon. Hot Shot bullets set targets on fire; Iceblox bullets drastically lower the target's body temperature. They are available after researching the Subdermal Implants node (TRAC) or Exotic Ammunition node (Hot Shot/Iceblox).
- - Renamed the Technological Shells research node to Exotic Ammunition.
- - The "lifespan_postmortem" var now determines how long tracking implants work after death.
- - .357 AP speedloaders can now be ordered from syndicate uplinks.
- - lowered the cost of uplink's .357 speedloaderd from 4 to 3.
-
-
Ghommie (original PR by nicbn and Menshin) updated:
-
- - You can click on things that are under flaps or holo barriers.
-
-
Ghommie (original PRs by ShizCalev, CRTXBacon and Niknakflak) updated:
-
- - Adds the intelliLantern, a big ol' spooky intelliCard skin
- - crafting recipe for the new intelliCard skin (requires 1 pumpkin, 1 intelliCard, 5 cables and a wirecutter as a tool)
- - changed the intelliTater crafting recipe to match the intelliLantern recipe (but with a potato for obvious reasons) add:cute pai gameboy face :3
-
-
Ghommie, porting lot of PRs by MrDoomBringer, AnturK, nemvar and coiax. updated:
-
- - Admins can now launch supplypods the old, slightly quicker way as well
- - Centcom-launched supplypods will now properly delimb you (if they are designated to do so) instead of touching you then literally yeeting all of your internal organs out of your body.
- - Centcom can now specify if they want to yeet all of your organs out of your body with a supplypod
- - Supplypods sound a bit nicer as the land now.
- - admins can now adjust the animation duration for centcom-launched supplypods
- - admins can adjust any sounds that are played as the supplypod lands
- - Reverse-Supplypods (the admin-launched ones) no longer stay behind after rising up, and also auto-delete from centcom.
- - The centcom podlauncher now has better logging
- - Admins can now allow ghosts to follow the delivery of Centcom-launched supply pods
- - Admins can now use the Centcom Podlauncher to launch things without the things looking like they're being sent inside a pod.
- - sparks will not generate if the quietLanding effect is on, for the centcom podlauncher
- - makes input text clearer for the centcom podlauncher
- - New 'Podspawn' verb, which functions like 'Spawn', except any atoms movable spawned will be dropped in via a no-damage, no-explosion Centcom supply pod.
- - Removed an oversight that made many obj/effect subtypes accidentally bombproof.
-
-
GrayRachnid updated:
-
- - Added saboteur syndicate engiborg
- - changed cyborg tool icons and the secborg taser/laser icons.
- - Fixes golden toolbox missing inhand sprite
- - Added traumas
- - Added science powergame tool
- - a few hearing args
- - fixed my mistakes
- - tweaked the number of ingredients/pancakes you can stack.
-
-
Hatterhat updated:
-
- - The Big Red Button now sets bomb timers to 2 seconds, instead of 5.
- - Gloves of the North Star (not Hugs of the North Star) now use all their intents very, very fast. This does not apply to grabs' click cooldown, nor shoving people.
- - The seedvault/alien plant DNA manipulator can now be printed off with Alien Biotechnology.
-
-
Iroquois-Pliskin updated:
-
- - Removed Clockwork Cult Surgical facility from Reebe
-
-
Jerry Derpington, baldest of the balds, and nemvar. updated:
-
- - Nanotrasen has lost communication to two away mission sites that contained a beach for Nanotrasen employees.
- - Nanotrasen has been able to locate a new away mission site that ALSO has a beach. Nanotrasen employees will be able to enjoy the beach after all!
- - Seashells have been added to the game.
-
-
KathrinBailey updated:
-
- - Two extra 'luxury' dorms rooms!
- - Gas miners to atmos.
- - Posters around the station.
- - Vacant room added to the Starboard Bow with it's own APC, above electrical maintenance.
- - New trendy clothes to the locker room, giving variety and bringing fashion back onto Nanotrasen stations.
- - Coloured bedsheet and towel bin.
- - Maid uniforms for the janitor.
- - Completely reworked bar. Milk kegs added in bar office. The bar has been changed for a homey restaurant feel just in time for Christmas! You can now run it as an actual restaurant! Local Bartender Icktsie III loved it so much he rolled around on the new floor smiling happily.
- - Dorms rework. Fitness room now has lots of costumes and outfits.
- - Junk removed from engineering, welding goggles added.
- - Welding tools in engineering replaced with industrial welding tools.
- - Package wrappers and hand labellers now in major departments.
- - Cell charger moved from engineering lobby to the protolathe room, just like how it is in all of the other maps and just where the cell charger is actually needed.
- - Library redesigned to have a private room and a 3x3 private study that is cleaned up.
- - Paper bins have gone big or gone home, with premium stationery scattered around. Engineering and security now have a labeller and packaging supplies.
- - Dark spot top left of Botany fixed.
- - Huge galactic-sized dark spot in bar fixed.
- - Light replacers now are less horrifically overpowered and PTSD-inducing for the server.
- - Fixes issue 9706: https://github.com/Citadel-Station-13/Citadel-Station-13/issues/9706 Part of maint getting hit by radstorms.
-_Kathrin's Box Beautification:_
- - Ports TG's pews https://github.com/tgstation/tgstation/pull/42712
- - The first step of a corporate incursion of Space IKEA into Nanotrasen.
-
-
Kevinz000, Cruix, MrStonedOne, Denton, Kmc2000, Anturk, MrDoomBringer, Dennok, TheChosenEvilOne, Ghommie updated:
-
- - Added support for Multi-Z power, atmospherics and disposals
- - massive service department nerf: space can no longer be extra crispy.
-
-
Knouli updated:
-
- - attack_self proc for the legion core which triggers a self-heal al la the previous 'afterattack' proc, as if clicking on the character's own sprite to self-heal
- - admin logging for all three use cases of legion core healing - afterattack, attack_self, and implanted ui_action_click
-
-
Krysonism, Ghommie updated:
-
- - NT has made breakthroughs in ice cream science, ice creams can now be flavoured with any reagent!
- - The ice cream vat now accepts beakers.
- - Grape and Peach icecreams have scoop overlays yet again.
-
-
Linzolle updated:
-
- - butchering component update
- - hat tossing can no longer knock hats off
- - strange reagent being unable to revive simplemobs
- - jitter animation and more clear text to strange reagent revival
-
-
Mickyy5 updated:
-
- - Nanotrasen are now issuing Plasmamen with plasma in their survival boxes
-
-
MrJWhit updated:
-
- - tweaked brain damage line
-
-
Naksu, ShizCalev updated:
-
- - Refactored examine-code
- - Examining a human with a burned prosthetic limb will no longer tell you that the limb is blistered.
- - Items will now inform you if they are resistant to frost, fire, acid, and lava when examined.
-
-
Owai-Seek updated:
-
- - "silly" bounties
- - "gardenchef" bounties
- - several bounties that require seriously good RNG to pull off.
- - moved several chef and assistant bounties to silly and gardenchef
- - modified several bounty point rewards
- - added new files "silly.dm" and "gardenchef.dm"
- - 15+ new crates for cargo
- - organizes crates and moving them to proper categories
- - some dumb stuff like toner crates re
- - leg wraps and sweaters to clothesmate
- - screwdriver and cable coil to janidrobe
- - screwdriver and cable coil to janibelt whitelist (for fixing/placing light fixtures)
- - monkey cube, syringe, enzyme, soy sauce, and cryoxadone to chef's vendor (contraband and premium)
- - add cracker, beans, honey bars, lollipops, chocolate coin, and spider lollipop to snack vendors (contraband and premium)
- - newspaper to loadout menu for bapping purposes
- - removed poppy pretzels from snack vendor premium
- - maid uniform (janimaid alt) to kinkmate.
- - moves gear harness from premium to normal stock in kinkmate
- - re-balanced metal shield bounty
- - cryoxadone bottle (for use in chef vendor)
-
-
PersianXerxes updated:
-
- - Reduces the grace period for meteors from a minimum of 5 and maximum of 10 to 3 and 6 minutes respectively.
- - Adds a pair of VR sleepers to Box Station's permabrig
- - Adds a pair of VR sleepers to Delta Station's permabrig
- - Adds a pair of VR sleepers to Pubby Station's permabrig
- - Adds a pair of VR sleepers to Meta Station's permabrig
-
-
Putnam updated:
-
- - From-ghosts dynamic rulesets now actually listen to "required candidates"
- - Every dynamic-triggered event is now blacklisted from being triggered by the random events system when dynamic can trigger them.
- - Dynamic voting now features extended, if recent rounds have been chaotic.
- - Roundstart rulesets now scale on population ready rather than total population.
- - Threat log now accurately represents what actually used the threat.
- - Verbose threat log (admin-only) now shows ALL threat level changes.
- - VR mobs can no longer be dynamic midround antags.
- - Personal closets can use anything that holds an ID card now.
-
-
Putnam3145 updated:
-
- - traitors work now
- - Gas filters now push gas the same way volume pumps do.
- - Gas filters now won't clog if only one output is clogged.
- - Glowsticks can no longer be radioactively contaminated (one more supermatter contam exploit gone)
- - traitor removal is no longer borked
- - Dynamic voting
- - Added DYNAMIC_VOTING to game_options
- - SDGF now copies memories as well as antag data and factions.
- - Summon events now properly costs threat.
- - Refunded spells refund threat, too.
- - Made wizard spells inherently have a requirement and cost.
- - Meteor wave is no longer repeatable in dynamic.
- - tweaked nuke ops
- - Organs can no longer be radioactively contaminated.
-
-
Robustin, Subject217 updated:
-
- - The NukeOp Shuttle hull has been dramatically hardened. The walls are now "R-Walls" with far greater explosion resistance.
- - The NukeOp Shuttle guns have been significantly buffed. They now rapidly fire a new type of penetrator round, at a greater range, and have far greater explosion resistance.
- - The nuclear device on the NukeOp Shuttle is now in an anchored state by default, the Nuke can only be unanchored by inserting the disk and entering the proper code.
- - Non-Syndicate cyborgs are now unable to access the NukeOp Shuttle Console.
- - You can now unanchor Nukes even when the floor under them has been destroyed
-
-
Seris02 updated:
-
- - added sleeping carp hallucination
- - Centcom + Assistant's formal winter coat + loadout + narsian + ratvarian winter coats
- - GPS location on examine
- - fixed the meteor hallucination
- - tweaked the way the tapered penis looks
- - Added nine winter coats
- - added images for the winter coats
- - adds the mining winter coat to mining wardrobes and mining lockers
-
-
ShizCalev updated:
-
- - Ghosts can now see active AI cameras.
- - Fixed a couple of laser / energy guns never switching to the empty icon despite being unable to fire.
-
-
Swindly updated:
-
- - Fixed MMIs not being able to use mecha equipment
- - Fixed MMIs not getting mecha mouse pointers
- - Fixed MMIs not getting medical HUDs in Odysseuses
- - Brains can now switch to harm intent
-
-
Tetr4 updated:
-
- - Turning a tile with gas effects into space now gets rid of the effects.
-
-
Trilbyspaceclone updated:
-
- - plastic trash cart crafting with plastic
- - wallets are known for now holding more items
- - shades and clowns HP
- - six more crates, A barrel, A Loom, 40 cotton sheets, two sets of fruit crates, raw lumber crate
- - All fermi chems, Boozes, Medical, food chems now sell
- - Loads more to sell - Mech gear, Cooking and more!
- - Moved around the vaule of some things and removed elastic of most items
- - Rebreather implants will now loss vaule, Do to being just metal and glass
- - lowered how many chems are in lewd chem kegs to be around 150-100 as well as the fancy booze kegs
- - bad returns and tools used
- - 8 new cargo crates!
- - tablet cargo crate by -3k
- - Closes a bunch of issues
- - updates changlogs and such
- - fixed a catnip not having sprites
- - Boh cant hold WEIGHT_CLASS_GIGANTIC, just Bulky. Makes katana, chainsaw and base ball bat into bulky items so they may fit
- - changes header to be more cit-like
- - new clothing for the hotel staff and a hat
-
-
Ty-the-Smonk updated:
-
- - You can now interact with self sustaining crossbreeds
-
-
Useroth updated:
-
- - Colored fairygrass variants.
- - Added a missing cherrybulb seedpack sprite
- - numbered storages now are sorted in a consistent way, instead of depending on ordering of their contents var
- - strange seeds as a buyable traitor botanist item
- - resolves the issues revolving around blackpowder exploding where the reaction happened, instead of where it actually is through making it explode instantly
- - the explosion delay moved from blackpowder directly into bomb cherries, to keep them functioning as intended
- - A bunch of newer tg plants
- - A bunch of newer tg plant traits
- - A couple of newer tg plant reagents
- - the new plants now properly get their reagents and reagent genes instead of being empty with UNKNOWN reagents listed in the DNA machine
- - extradimensional oranges now contain haloperidol
- - extradimensional oranges now actually grow properly and give proper seeds.
-
-
Weblure updated:
-
- - Button added to slime console that prints out the hotkey commands to the user. [Includes DMI update]
- - Shift-click a slime to pick it up, or the floor to drop all held slimes. (Requires Basic Slime Console upgrade)
- - Ctrl-click a slime to scan it.
- - Alt-click a slime to feed it a potion. (Requires Advanced Slime Console upgrade)
- - Ctrl-click on a dead monkey to recycle it, or the floor to place a new monkey. (Requires Monkey Console upgrade)
- - If the console does not have the required upgrade, an error message will print to the user.
- - You can now pick up a single slime from a pile, instead of all of them at once.
- - When recycling monkeys, the console will now report how many monkeys it has (will not report decimal increases).
- - Console now alerts you when you're out of monkeys and reports your current decimal amount.
- - Console messages are now styled consistently.
-
-
XDTM, ShizCalev, Naksu, Skoglol, cacogen, Rohesie (ported by Ghommie) updated:
-
- - Holding an ID in your hands uses it instead of your worn ID for authentication purposes.
- - If you don't have an ID in your id slot, the belt slot will be checked as well.
- - small cleanup to id and bounty console html generation
- - Hop console now hurts your eyes less. Red button text replaced with green.
- - IDs with ID console access now go into the Confirm Identity slot by default like they used to, similarly IDs without it go into the Target slot by default again
- - Can easily swap out IDs by clicking the machine or the UI fields with another ID
- - ID console now names which IDs are added/removed in its visible messages
- - Labels the ID slot fields when logged in so you know which is which
- - Can use Job Management without an ID provided the console is logged in (matches how the console now stays logged in even without an ID)
- - Can log in without an ID in the Target field (matches how the machine now stays logged in even after the ID is removed from the Target field)
- - Cleans up UI slightly (had some duplicate/conflicting buttons)
- - Fixes ID console duping issues. Includes some ID containers, such as PDAs, tablets and wallets, into the swapping behavior when an ID card is being removed and the item is being held.
-
-
Xantholne updated:
-
- - New Berets for most heads and departments available in their autodrobes or lockers
-
-
YakumoChen updated:
-
- - New AI Holograms and Displays! Ported from /vg/station.
-
-
actioninja updated:
-
- - med records no longer can eat id cards for no reason
- - Chat is properly sent to legacy window if goonchat fails to load again.
-
-
dapnee updated:
-
- - fixed closet initialisation being broken
- - emergency closets no longer have a 1% chance to delete themselves
- - Communications console window no longer updates, won't steal focus anymore.
- - Trimline neutral end exists now.
-
-
dzahlus updated:
-
- - added a new gun sounds
- - removed an old gun sounds
-
-
him updated:
-
- - hos and aeg guns now conform to le epic taser rework standards
-
-
kappa-sama updated:
-
- - changed flavor text of alien tech on uplink
- - added TG's icons for traitor, russian, and golden revolver
-
-
kevinz000 updated:
-
- - you can now choose never for this round for magical antags
- - Cargo has passive point generation again at 750 points/minute
- - Mindshield crate price increased from 3000 to 4000
- - Miasma sell price reduced from 15/mol to 4/mol
- - bluespace wizard apprentice now has blink instead of targeted area teleportation
- - Emagged medibots now charcoal toxinlovers.
- - disablers buffed 0.7 --> 0.6 speed 24 --> 28 damage
- - kinetic crushers no longer drop if you try to use it with one hand
- - added multi_keyed_list, delimiter defaults to |.
- - Light pink extracts no longer speed you up. Instead, they give stamina regeneration and free sprinting.
-
-
kiwedespars updated:
-
- - removed moth fluff coloring you like your wings
- - made insect not so bad.
-
-
nemvar updated:
-
- - You now get a message if your PDA explodes while you are holding it.
- - The lavaland clown ruin has some new pranks ready.
- - Added a new loot item to the lavaland clown ruin.
- - Removed the slime core from said ruin.
- - The clown PDA now properly slips people on jogging move intent regardless of fatigue. Honkmother's will.
-
-
nemvar, ShizCalev, Qustinnus/Floyd, Ghommie updated:
-
- - You can now unfasten the loom.
- - it now takes 4 strands to make one piece of durathread cloth
- - Looms can now be attacked.
- - Durathread golem weaves his magic
- - Supply ordered looms are unanchored. Bring a wrench.
-
-
r4d6 updated:
-
- - Added Departements Winter Coats to the loadout list.
-
GoonStation 13 Development Team
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index db9c8e6d08..464340ef24 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -23980,3 +23980,475 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
shellspeed1:
- rscadd: Adds Insect markings
- rscadd: Adds three new moth wings.
+2020-01-27:
+ 4dplanner, CRITAWAKETS, XDTM, ninjanomnom:
+ - rscadd: sepia slime extract has a delay before activating
+ - balance: the user of a sepia slime extract is no longer immune to the time field
+ - balance: chilling sepia is now the support extract - it always freezes the user,
+ but not other marked people. give one to your golem!
+ - rscadd: burning sepia spawns the rewind camera. Take a selfie with someone and
+ give it to them to make sure they remember the moment forever! You don't actually
+ need to give them the photo, they'll remember anyway. Keep it as a reminder.
+ - rscadd: rewinding (deja vu) effect resets your location to the turf you were on
+ after 10 seconds as well as resetting limbs/mobs/objects damage to the point
+ it was added.
+ - rscadd: The deja vu effect cannot resurrect the dead, but will heal their corpse.
+ New limbs fall off, old ones re-attach
+ - rscadd: 'Regenerative sepia cores add a deja vu effect before healing instead
+ of a timestop remove: timefreeze camera is admin spawn only.'
+ - rscadd: recurring sepia recalls to the hand of the last person to touch it after
+ activating. Reusable timestop grenades!
+ - tweak: some special cameras don't prompt for customisation
+ - bugfix: timefreeze camera actually makes a photo
+ - bugfix: timestop stops pathing and mechs.
+ - bugfix: adds a check to make sure simple_animals don't get their AI toggled while
+ sentient
+ - bugfix: Adds the timestop overlay to frozen projectiles
+ - bugfix: Timestopped things have INFINITY move_resist as opposed to being anchored
+ - bugfix: Timestop will now unfreeze things that somehow leave it
+ - bugfix: mobs in the middle of a walk_to will have their walk stopped by timestop
+ - bugfix: mobs that are stunned will be stopped mid walk as well
+ - bugfix: pulling respects changes in move_force
+ - bugfix: swapping places respects move_force if the participant is not willing
+ - bugfix: timestop is properly defeated by antimagic.
+ - bugfix: timestop only checks antimagic once
+ - tweak: Time stop now applies its visual effect on floors, walls and static structures
+ (with no change otherwise)
+ - tweak: Movable structures are now anchored while time stopped.
+ - tweak: Timestop effects now prevent speech.
+ AffectedArc07:
+ - code_imp: All code files are now in the LF line format, please stick to it
+ - tweak: Added CI step to check for CRLF files
+ - code_imp: Line ending CI works now
+ Arkatos, Zxaber, Ghommie:
+ - rscadd: Certain AI abilities now dynamically show their remaining uses on the
+ mouse hover over their respective action buttons.
+ - bugfix: Malfunctioning AIs can no longer abuse the confirmation popup to create
+ extra (unstoppable) doomsdays.
+ - bugfix: Fixed AIs being able to use some of their abilities such as the doomsday
+ whilst dead, and the doomsday loading phase not halting upon AI death.
+ Arturlang:
+ - tweak: Vampires are no longer as tanky
+ - rscadd: Added modular computers to the loadout
+ Bhijn:
+ - rscadd: Limbs now regenerate their stamina faster while disabled
+ - rscadd: Limbs now have the same incoming stamina damage multiplier mechanics as
+ spacemen, where the more staminaloss they take while disabled, the less staminaloss
+ they'll take.
+ - balance: Limbs have had their base stamina regen rate doubled to match the doubled
+ stamina regen rate of standard spacemen.
+ - rscadd: Added a preference to make the sprint hotkey be a toggle instead of a
+ hold bind
+ - rscadd: Added a preference to bind the sprint hotkey to space instead of shift.
+ - bugfix: server_hop can no longer be used to remotely lobotomize a spaceman
+ Bhijn helped:
+ - bugfix: Fixes Dragon's Tooth Sword 50% armor penetration by making it 35%
+ BonniePandora:
+ - admin: 'Added another SDQL option. Using "UPDATE selectors SET #null=value" will
+ now resolve value and discard the return. This is useful if you only care about
+ the side effect of a proc.'
+ CameronWoof:
+ - rscadd: Ghost Cafe patrons now spawn with chameleon kits. Dress up! Be fancy!
+ - rscadd: Robots can now check the crew manifest from anywhere with the "View Crew
+ Manifest" verb.
+ - tweak: Lizard tails are now viable options for humans and anthromorphs.
+ Commandersand:
+ - bugfix: fixed some clothnig sprites
+ - balance: lightning bolt,tesla,forcewall,emp spells have lower cooldown
+ - balance: fireball has a 10 second starting cooldown
+ DeltaFire15:
+ - bugfix: Vitality matrixes now correctly succ slimes
+ Denton, ported by Hatterhat:
+ - tweak: Most upgradeable machines now show their upgrade status when examined while
+ standing right next to them.
+ - tweak: Added examine messages to teleporter stations that hint at their multitool/wirecutter
+ interactions.
+ - tweak: Renamed teleporter stations from station to teleporter station.
+ - code_imp: Changed the teleporter hub accurate var to accuracy; the old name misled
+ people into thinking that it was a boolean.
+ Detective-Google:
+ - tweak: replaced the sprites with new ones requested.
+ EmeraldSundisk:
+ - rscadd: Adds a sign outside MetaStation's custodial closet
+ FantasticFwoosh, ported by Hatterhat:
+ - rscadd: Both reagent universal enzyme & sacks of flour are now available for their
+ respective costs from the biogenerator.
+ - rscadd: New crafting recipies for donut boxes, eggboxes & candle boxes have been
+ added to cardboard recipes for the collective benefit of service personnel and
+ the station.
+ Ghommie:
+ - tweak: Attached kevlar/soft/plastic padding accessories are now stealthier and
+ will no longer be displayed on mob examine.
+ - refactor: Refactored that mess of a code for alternate worn clothing sprites for
+ digitigrade and taurs.
+ - bugfix: Fixed some issues with the aforementioned feature you may or may not have
+ experienced because it was pretty lame.
+ - bugfix: Fixed missing digi versions fishnet sprites and wrong digitigrade left
+ dir purple stockings sprite.
+ - imageadd: Add digitigrade versions for boxers and the long johns.
+ - bugfix: Fixed the secret sauce recipe being randomized every round.
+ - bugfix: Fixed singularity pulls duping rods out of engine floors.
+ - rscdel: Removed an old pair of zipties from the captain closet.
+ - bugfix: Chestbursters won't delete the host's brain somewhat anymore.
+ - bugfix: Fixed roundstart mushpeople being unable to MUSH PUUUUUUUUUUUUNCH!!
+ - bugfix: Lattices can be examined yet again.
+ - bugfix: Made reagent containers examine text less annoying.
+ - bugfix: Virus food dispensers dispense virus food again.
+ - bugfix: Borg hypos inputs do not display typepaths anymore.
+ - bugfix: Restored chem dispensers alphabetical order.
+ - bugfix: Sanitized cargo export messages for reagents.
+ - bugfix: Riot foam dart (not the ammo box) design cost is yet again consistent
+ with the result's material amount.
+ - bugfix: Fixed a little exploit with ventcrawlers being capable of escaping closed
+ turfs by printing scrubbers/vents into them.
+ - bugfix: deconstructing a rubber toolbox with the destructive analyzer won't "lock"
+ the machine anymore.
+ - bugfix: Something about empty hand combat mode right click waving hands defying
+ common sense and being spammy.
+ - imageadd: Towels are now "digitigrade-friendly".
+ - bugfix: The Barefoot drink and mousetraps will now work even if wearing certain
+ "feet-less shoes".
+ - rscadd: Refactored code to allow all living mobs to use shields and not only humans.
+ - tweak: Monkys will now retaliate against aliens attacking them (as if they even
+ posed a threat to start with).
+ - tweak: add a click cooldown to the overly spammable table slamming.
+ Ghommie (original PRs by Kevinz000, ShivCalez, 4dplanner, Barhandar, 81Denton, zxaber, Fox-McCloud):
+ - rscadd: All atom movables now have move force and move resist, and pull force
+ An atom can only pull another atom if its pull force is stronger than that atom's
+ move resist
+ - rscadd: 'Mobs with a higher move force than an atom''s move resist will automatically
+ try to force the atom out of its way. This might not always work, depending
+ on how snowflakey code is. experimental: As of right now, everything has a move
+ force and resist of 100, and a pull force of 101. Things take (resist - force)
+ damage when bumped into experimental: Failing to move onto a tile will now still
+ bump up your last move timer. However, successfully pushing something out of
+ your way will result in you automatically moving into where it was.'
+ - bugfix: Bolted AIs can no longer be teleported by launchpads.
+ - balance: Megafauna cannot teleport
+ Hatterhat:
+ - balance: Beakers are generally more useful now, with slight capacity increases.
+ - tweak: Transfer amounts are different now. Adjust your muscle memory to compensate.
+ - balance: ore redemption machines actually get affected by lasers again kthx
+ - tweak: crusher trophy drop chance on mining mobs increased to 1 in 4 (from 1 in
+ 20)
+ - bugfix: Blood-drunk buff from blood-drunk eye crusher trophy is less likely to
+ cripple its user.
+ - tweak: Forcefield projectors now fit on toolbelts.
+ - imageadd: New sprites for ATMOS holofan and forcefield projectors!
+ - tweak: tweaks some values around with beaker transfer amounts, adds a transfer
+ value verb (altclick)
+ - rscadd: 'Syndicate sleepers (read: the ones that''re red and have controls in
+ them) can now be recreated with a sufficient basis in nonstandard (read: illegal)
+ technologies!'
+ - bugfix: Explorer hoods on standard explorer suits can be reinforced with goliath
+ hide plates again.
+ - rscadd: A shipment of Staff Assistant jumpsuits from the Goon-operated stations
+ appear to have made their way into your loadout selections - and into the contraband
+ list from ClothesMates...
+ - balance: Dropped Exo-suit armor to put it more in line with being an explorer
+ suit sidegrade and not a straight upgrade for Lavaland usage.
+ - rscadd: You can now print .357 AP speedloaders from Security techfabs after you
+ pick up the Advanced Non-Standard Ballistics node.
+ - rscdel: Forensic scanner removed from Advanced Biotechnology node.
+ - tweak: Ash Drake armor now has goliath resistance, same as the Exo-suit.
+ KathrinBailey:
+ - rscadd: Empty engineering lockers for mappers.
+ - rscadd: Industrial welding tools to the engineer welding locker.
+ - rscdel: Removed the multitool, airlock painter, mechanical toolbox, brown sneakers,
+ hazard vest and airlock painter from the CE's locker.
+ KeRSedChaplain:
+ - imageadd: The clockwork cuirass can now support slithering taur bodies.
+ Kevinz000:
+ - bugfix: Fixes successful projectile hits also striking another atom on the same
+ turf should the first one be not the target the projectile was meant for.
+ - rscdel: Removes infinite reflector loops.
+ Kraseo:
+ - bugfix: Jelly donuts and pink jelly donuts will now properly display sprinkled
+ icon state.
+ - bugfix: Jelly donuts and its variants will properly spawn with berry juice.
+ - bugfix: Slime jelly donuts have slime jelly in them now. (thanks ghommie)
+ - bugfix: Virgo hairstyles no longer have those annoying quotation marks. Rejoice
+ for you will no longer have to use the scrollbar.
+ - imagedel: Got rid of some strange-looking hairstyles. (Tbob, fingerweave, etc.)
+ LetterN:
+ - rscadd: Doppler logs
+ - tweak: Shockcolar and electropack uses the new signaler ui
+ - tweak: Renaming shockcolar requires a pen
+ - rscadd: Adds banjo
+ Linzolle:
+ - bugfix: fixes matchboxes runtiming every time they spawn
+ MrJWhit:
+ - tweak: Increases plasma usage in radiation collectors
+ Naksu:
+ - code_imp: reagent IDs have been removed in favor using reagent typepaths where
+ applicable
+ - bugfix: mechas, borg hyposprays etc no longer display internal reagent ids to
+ the player
+ Owai-Seek:
+ - rscadd: Four New Bounties
+ - tweak: tweaked several bounties
+ - tweak: reorganised several bounties
+ - balance: balanced several bounties
+ - bugfix: added shady jims to vendor
+ - rscadd: Towel, Bedsheet, and Colored bedsheet bins to Dojo. Some lockers with
+ carpets and wood, another bathroom/shower, tons of cleaning supplies, some additional
+ trash cans, a tiny medical area, and some vendors/vendor resupplies. Also added
+ some Ambrosia Gaia seeds.
+ - tweak: Moved some lights around, extended the dojo a bit to make it feel more
+ spacious.
+ - rscdel: Cafe Newsfeed Frame
+ PersianXerxes:
+ - tweak: Reduces the range of the forcefield projector from 7 tiles to 2 tiles.
+ Putnam:
+ - rscadd: Alcohol intolerance trait, which forces vomiting on any alcohol ingestion
+ - rscdel: Arousal damage is gone, and with it the arousal damage heart on the UI.
+ - rscdel: As exhibitionist relied on arousal damage, that's gone too.
+ - rscdel: Bonermeter and electronic stimulation circuit modules are gone.
+ - rscdel: Masturbation is no longer an option in the climax menu. It was identical
+ to climax alone in every way but text. Emote it out.
+ - rscadd: Arousal on genitals can now be displayed manually, on a case-by-case basis.
+ - rscadd: '"Climax alone" and "climax with partner" now only display to the people
+ directly involved in the interaction. rework: Catnip tea, catnip, crocin, hexacrocin,
+ camphor, hexacamphor all had functions or bits of functions reworked.'
+ - tweak: '"Climax with partner" now requires consent from both parties--it can no
+ longer be used on mindless mobs, and it asks the mob getting climaxed with if
+ they consent first.'
+ - tweak: A lot of MKUltra behaviors have been moved to hypno checks or removed due
+ to reliance on maso/nympho/exhib.
+ - rscadd: Cold-blooded quirk
+ - rscadd: 'Two relief valves for atmospherics, available in your RPD today: a unary
+ one that opens to air and a binary one that connects two pipenets, like a manual
+ valve.'
+ - tweak: The atmos waste outlet injector on box has been replaced with an atmos
+ waste relief valve.
+ Putnam3145:
+ - rscadd: Dynamic storytellers, a new voting paradigm for dynamic
+ - rscadd: Support for approval voting and condorcet (ranked choice) voting in server
+ votes
+ - rscadd: Ghost cafe mobs can now ghostize
+ - rscadd: Ghost cafe now has a cremator
+ - rscadd: Ghost cafe mobs are now eligible for ghost roles
+ - refactor: Ghost roles now use an element for eligibility purposes
+ - bugfix: You can toggle some prefs properly now.
+ - bugfix: no ass slap is no longer the same thing as no aphro
+ - balance: Devastating bombs kills bomb armor'd mobs again
+ - rscadd: Added a sort of "game mode ban" by way of having people rank their game
+ modes favorite to least favorite after the secret/extended vote.
+ - bugfix: Turns out the schulze scoring was written wrong and it was setting things
+ to 0 that shouldn't have been, so that's fixed.
+ - config: Random engines are now weighted.
+ - rscadd: Ghost dojo now has an autoylathe.
+ - rscdel: Ghost dojo no longer has VR or modular computer access.
+ - tweak: Ghost dojo mobs are pacifists.
+ - tweak: Ghost dojo booze-o-mat is now all access.
+ - bugfix: Ghost dojo crematorium now has a button.
+ - bugfix: Traitor objectives don't take a dump when they try to add an assassinate
+ anymore
+ - admin: Objective removal with antag panel no longer commented out silently while
+ still being an option that gives useful feedback on stuff it's not doing in
+ any respect
+ - rscadd: Second, temporary flavor text!
+ - bugfix: Limb damage works now
+ - tweak: Score instead of ranked choice for mode tiers
+ - bugfix: Chemistry not :b:roke
+ - tweak: Ghost dojo spawns will dust if their owner suicides or uses the "ghost"
+ verb.
+ - admin: Crafting is logged in a file now
+ - bugfix: temporary flavor text now pops up properly
+ - code_imp: demodularized player panel code, mostly
+ - admin: added ghost role eligibility delay removal to player panel
+ - balance: Metabolic synthesis disables if user isn't well-fed rather than if user
+ is starving
+ - bugfix: Gibtonite no longer instantly explodes upon being pickaxe'd.
+ - balance: Cold-blooded costs -2 quirk points now
+ - config: Added suicide to the config.
+ - tweak: Ghost cafe mobs are super duper attached to the ghost cafe.
+ - bugfix: Meow Mix bar sign works
+ - bugfix: Fixed a few relief valve behaviors
+ Ryll/Shaps, ported by Hatterhat:
+ - rscadd: Point-blanking people with shotguns actually throws them backwards!
+ Savotta:
+ - rscadd: snout
+ - imageadd: snout
+ Seris02:
+ - tweak: made it so trait blacklisting removes random positives instead of removing
+ everything
+ - rscadd: added atmos holofirelocks and temperature blocking
+ - tweak: tweaked how atmos holofan looks
+ - rscadd: stunglasses
+ - rscadd: disabler sechuds
+ - rscadd: adds coconut
+ - rscadd: adds a coconut bong
+ - rscadd: Auto ooc
+ - admin: changed "assume direct control" from m.ckey = src.ckey to adminmob.transfer_ckey(M)
+ so it works with auto ooc
+ - rscadd: marshmallow
+ - rscadd: telescopic IV drip
+ - bugfix: cardboard box speed
+ - tweak: makes gorilla shuttle emag only
+ - tweak: changed where the observe verb is.
+ - tweak: the way chameleon clothes update on change
+ - bugfix: chameleon cloak icon
+ - balance: Explosions now cause knockdown instead of KOs, with the amount of time
+ scaling off bomb armor. Heavy explosions still cause a ~2 second KO for follow
+ up attacks.
+ - balance: Devastating explosions now no longer gib players with more than 50 bomb
+ armor. This used to be more or less random depending on the amount of bomb armor.
+ - code_imp: Removed reagent explosion code that would trigger for <1 amount reactions.
+ - rscadd: traitor tool for bowmanizing headsets + bowmanizing headsets
+ - rscadd: durathread winter coats from hyper station
+ - tweak: conveyor belt now are stacks instead of single item
+ - tweak: conveyor crate has 30 belts
+ - tweak: printing a conveyor costs 3000 metal
+ - rscadd: you can press the conveyor switch in hand to link any not deployed belts
+ to it
+ - tweak: sniffing sneezing etc doing anything if they don't breathe
+ - bugfix: probably fixes the make mentor button
+ - tweak: the sprites for the conveyor belts to look more directional
+ Skoglol:
+ - bugfix: Falsewalls now properly hide pipes and wires.
+ SpaceManiac, bobbahbrown, ShizCalev, SpaceManiac (ported by Ghommie):
+ - code_imp: It is now possible to set a different most-base-turf per z-level.
+ - spellcheck: Removed unlawful reference to Disney's Star Wars franchise in map
+ logging.
+ - tweak: Moved mapping related errors to their own log file.
+ - bugfix: Destruction on Lavaland will no longer reveal space in rare situations.
+ Tlaltecuhtli, Nemvar, Trilby, Hatterhat:
+ - rscadd: russian surplus crate, sec ammo crate, meat/veggie/fruit crate, rped crate,
+ bomb suit crate, bio suit crate, parrot crate, chem crate, db crate
+ - tweak: lowered price of some crates which are overpriced for no reason aka the
+ tablet crate and the mech circuits crates, track implant crate has also track
+ .38 ammo
+ - bugfix: sectech vendor has a refill pack
+ Trilbyspaceclone:
+ - bugfix: Fermi plushie can be made once again
+ - tweak: range on Engi Tray scanners and Rad-Scanners
+ - bugfix: issues with mapping done my Trilby
+ - rscadd: Grass now makes light beer when distilled
+ - tweak: allows bandoliers to hold any ammo type as long as it has a casing
+ - server: Cleans out the last years of changlogs
+ - bugfix: 'rouge cases of #$39; in bottle/pill/patch/condiments'
+ - tweak: Adds missing but needed flags to MASON RIG
+ - bugfix: missing sprites with crushed cans
+ - tweak: Halfs the nutriments in sugar
+ - rscadd: Glitter is now makeable with ground plastic and some crayons
+ - code_imp: Makes more folders and files for uplink.
+ - rscadd: Seed packs now have RnD points inside them
+ - rscadd: New tips that reflect the now use seed packs have for Rnd / Chems affect
+ on plants
+ - code_imp: Made the research file look nice rather then an eye harming list
+ - bugfix: Fixed fragile space suits breaking from weak and non-damaging "weapons"
+ (such as the Sord, toys and foam darts).
+ - rscadd: 'tip of the round: Cleanbot can withstand lava and burning hot ash. Its
+ a god'
+ - rscadd: more glassware
+ - rscadd: Few new packs and glassmaker kit!
+ - tweak: prices/chems of crates/autobottler
+ - bugfix: some crates ungettable as well as some broken crates
+ Trilbyspaceclone, Ghommie:
+ - rscadd: More types of glass can now be used to make a solar panel, with different
+ sturdiness and efficiency depending the type.
+ Tupinambis:
+ - tweak: Replaces new fire alarms with a slightly updated version of the old ones.
+ - bugfix: Fixed bug where Amber alert had no proper alert lights, and red alert
+ had amber lights.
+ - balance: RLDs now cost more to use, have reduced matter capacity, and sheets are
+ worth less when refilling them.
+ Unit2E & JMoldy, ported by Hatterhat:
+ - balance: the powerfist now punches people away at high velocity depending on setting.
+ - rscadd: the powerfist now leaks the gas it uses onto the tile you're on.
+ - tweak: Adds weak punch variations for empty and near-empty punching.
+ Xantholne:
+ - bugfix: Christmas clothes that where missing stuff should work again
+ - tweak: Christmas clothes moved from clothesmate and loadout to premium autodrobe,
+ hoodies and boots remain.
+ - rscadd: Botany bee pet, Bumbles
+ - rscadd: New bee models that aren't 1 tile big of 0 opacity pixels
+ - rscadd: Cheongsam and Qipao clothing added to loadout and clothesmates
+ dapnee:
+ - imageadd: new toxin's uniform and accessories
+ - imagedel: old toxin's uniform and accessories
+ deathride58:
+ - balance: The stamina buffer no longer uses stamina while recharging.
+ jakeramsay007:
+ - rscadd: The assorted .357 revolvers (except russian revolver) can now also load
+ .38, like real life.
+ kappa-sama:
+ - rscadd: loot crates in cargo contraband
+ - code_imp: modular_citadel file movement
+ - code_imp: modular citadel loses some files
+ - balance: dragnet snares can now be removed in 5 seconds
+ keronshb:
+ - rscadd: Adds new features for nanites
+ - bugfix: fixed the missing icons from Dermal Button nanites
+ - rscadd: Ports the special nanite remote, mood programs, and research generating
+ nanites
+ - balance: rebalances some nanites
+ - bugfix: fixed my messup
+ kevinz000:
+ - rscadd: throwing things no longer makes them randomly turned as long as you aren't
+ on harm intent
+ - rscadd: Custom holoforms have been added for pAIs and AIs. oh and cyborg holograms
+ of specific modules too.
+ - balance: pais are no longer indestructible-flagged while in card form. pai radios
+ now short out if they are forcefully collapsed from damage.
+ - bugfix: telescopic iv drips now have the proper sanity checks for deployment.
+ - bugfix: megafauna can hear again
+ - balance: Cargo passive gen is now 500 down from 750.
+ - config: Added a few more nightshift config entries
+ - rscadd: nightshift_public_area variable in areas to determine how public an area
+ is.
+ - rscadd: NIGHT_SHIFT_PUBLIC_AREAS_ONLY config entry allows the server to be configured
+ to only nightshift areas of that level and below (so areas that are more public)
+ - rscadd: Config entries added for requiring authorizations to toggle nightshift.
+ Defaults to only requiring on public areas as determined by above
+ - balance: nuclear fist buffed.
+ - balance: cogscarabs are now fulltile-hitbox.
+ - balance: emitters are now hitscan
+ - balance: monkies gorrilize easier now
+ - rscadd: Ghosting no longer stops abductors from using you.
+ - rscadd: guests can now looc
+ - tweak: tableslamming has 0.4 second cooldown instead of 0.8
+ - bugfix: health analyzers now work
+ - code_imp: Mapping helpers added for power cables and atmos pipes.
+ - rscdel: Blood duplication is gone, but viruses now react up to 5 times, 1 time
+ per unit, for virus mix.
+ - rscadd: you can now block people on your PDA
+ - bugfix: Grenades can now have their timers adjusted.
+ - balance: Cloning has been nerfed.
+ - bugfix: hilbert hotel is now less of an exploity mess
+ - balance: Doorcrushes are once again instant.
+ nik707:
+ - tweak: engraving light_power from 1 to 0.3
+ r4d6:
+ - rscadd: Added a Radiation Hardsuit
+ - rscadd: Added a Radiation Hardsuit crate
+ - rscadd: Added 3 SM Engine variations.
+ - rscadd: 'Added a way to make opaque plastic flaps change: Change the already existing
+ flap recipe to show that they are see-through'
+ - rscadd: Animations for the RCD
+ - bugfix: Said animations being pulled by the Singulo
+ - balance: Prevent Reinforced Doors from being RCD'ed
+ - bugfix: Deconstructing Floors now cost MUs like everything else
+ - tweak: changed the RCD's upgrades into flags
+ - rscadd: Allow RCDs to print APC, Firelocks and Fire Alarms with the right upgrade
+ - balance: Allow Engineers to print RCDs and RPDs from their protolathe without
+ needing to hack one.
+ - rscadd: Added a playback device
+ - bugfix: Made the Voice Analyzer actually care about languages
+ - bugfix: fixed SM's piping
+ - rscadd: Added a message when pulsing the open wire.
+ - bugfix: fixed being able to use a playback device and a voice analyzer to activate
+ each others
+ - rscadd: added passive vent to the arsenal of atmospheric devices.
+ - rscadd: Mining base now has a common area accessible via a new shuttle on the
+ medium-highpop maps, and a security office connecting the gulag and the mining
+ base. Gulag also has functional atmos.
+ - rscadd: Added more Cyborg Landmarks
+ - refactor: better code for passive vents
+ - bugfix: fixed a hole in Meta
+ - rscadd: Added the ability to easily add variations of the mining base
+ - bugfix: fixed a sprite
+ timothyteakettle:
+ - bugfix: fixed not being able to remove trait genes without a disk being inserted
+ into the dna manipulator
diff --git a/html/changelogs/AutoChangeLog-pr-10097.yml b/html/changelogs/AutoChangeLog-pr-10097.yml
deleted file mode 100644
index 9b9a2c9a58..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10097.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - tweak: "Attached kevlar/soft/plastic padding accessories are now stealthier and will no longer be displayed on mob examine."
diff --git a/html/changelogs/AutoChangeLog-pr-10112.yml b/html/changelogs/AutoChangeLog-pr-10112.yml
deleted file mode 100644
index f09d8fa9ef..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10112.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - refactor: "Refactored that mess of a code for alternate worn clothing sprites for digitigrade and taurs."
- - bugfix: "Fixed some issues with the aforementioned feature you may or may not have experienced because it was pretty lame."
diff --git a/html/changelogs/AutoChangeLog-pr-10123.yml b/html/changelogs/AutoChangeLog-pr-10123.yml
deleted file mode 100644
index 208b17b930..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10123.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - rscadd: "throwing things no longer makes them randomly turned as long as you aren't on harm intent"
diff --git a/html/changelogs/AutoChangeLog-pr-10125.yml b/html/changelogs/AutoChangeLog-pr-10125.yml
deleted file mode 100644
index 951b69ccb3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10125.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Kevinz000"
-delete-after: True
-changes:
- - bugfix: "Fixes successful projectile hits also striking another atom on the same turf should the first one be not the target the projectile was meant for."
- - rscdel: "Removes infinite reflector loops."
diff --git a/html/changelogs/AutoChangeLog-pr-10165.yml b/html/changelogs/AutoChangeLog-pr-10165.yml
deleted file mode 100644
index be6f9dedf7..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10165.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixed missing digi versions fishnet sprites and wrong digitigrade left dir purple stockings sprite."
- - imageadd: "Add digitigrade versions for boxers and the long johns."
diff --git a/html/changelogs/AutoChangeLog-pr-10189.yml b/html/changelogs/AutoChangeLog-pr-10189.yml
deleted file mode 100644
index 5889e127d2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10189.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - rscadd: "Dynamic storytellers, a new voting paradigm for dynamic"
- - rscadd: "Support for approval voting and condorcet (ranked choice) voting in server votes"
diff --git a/html/changelogs/AutoChangeLog-pr-10191.yml b/html/changelogs/AutoChangeLog-pr-10191.yml
deleted file mode 100644
index c1366727bd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10191.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - rscadd: "Custom holoforms have been added for pAIs and AIs. oh and cyborg holograms of specific modules too."
- - balance: "pais are no longer indestructible-flagged while in card form. pai radios now short out if they are forcefully collapsed from damage."
diff --git a/html/changelogs/AutoChangeLog-pr-10224.yml b/html/changelogs/AutoChangeLog-pr-10224.yml
deleted file mode 100644
index b7d07abe5c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10224.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Seris02"
-delete-after: True
-changes:
- - tweak: "made it so trait blacklisting removes random positives instead of removing everything"
diff --git a/html/changelogs/AutoChangeLog-pr-10238.yml b/html/changelogs/AutoChangeLog-pr-10238.yml
deleted file mode 100644
index dda40c86c9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10238.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "SpaceManiac, bobbahbrown, ShizCalev, SpaceManiac (ported by Ghommie)"
-delete-after: True
-changes:
- - code_imp: "It is now possible to set a different most-base-turf per z-level."
- - spellcheck: "Removed unlawful reference to Disney's Star Wars franchise in map logging."
- - tweak: "Moved mapping related errors to their own log file."
- - bugfix: "Destruction on Lavaland will no longer reveal space in rare situations."
diff --git a/html/changelogs/AutoChangeLog-pr-10247.yml b/html/changelogs/AutoChangeLog-pr-10247.yml
deleted file mode 100644
index b78e5c415d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10247.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Seris02"
-delete-after: True
-changes:
- - rscadd: "added atmos holofirelocks and temperature blocking"
- - tweak: "tweaked how atmos holofan looks"
diff --git a/html/changelogs/AutoChangeLog-pr-10255.yml b/html/changelogs/AutoChangeLog-pr-10255.yml
deleted file mode 100644
index ebaccd0af6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10255.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Xantholne"
-delete-after: True
-changes:
- - bugfix: "Christmas clothes that where missing stuff should work again"
diff --git a/html/changelogs/AutoChangeLog-pr-10256.yml b/html/changelogs/AutoChangeLog-pr-10256.yml
deleted file mode 100644
index eb14f716cc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10256.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Putnam"
-delete-after: True
-changes:
- - rscadd: "Alcohol intolerance trait, which forces vomiting on any alcohol ingestion"
diff --git a/html/changelogs/AutoChangeLog-pr-10270.yml b/html/changelogs/AutoChangeLog-pr-10270.yml
deleted file mode 100644
index b47a249f9a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10270.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixed the secret sauce recipe being randomized every round."
diff --git a/html/changelogs/AutoChangeLog-pr-10278.yml b/html/changelogs/AutoChangeLog-pr-10278.yml
deleted file mode 100644
index 76ada12f20..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10278.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "Fermi plushie can be made once again"
diff --git a/html/changelogs/AutoChangeLog-pr-10285.yml b/html/changelogs/AutoChangeLog-pr-10285.yml
deleted file mode 100644
index 89b0bbae43..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10285.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixed singularity pulls duping rods out of engine floors."
diff --git a/html/changelogs/AutoChangeLog-pr-10287.yml b/html/changelogs/AutoChangeLog-pr-10287.yml
deleted file mode 100644
index f59cd0bd7f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10287.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - rscdel: "Removed an old pair of zipties from the captain closet."
diff --git a/html/changelogs/AutoChangeLog-pr-10295.yml b/html/changelogs/AutoChangeLog-pr-10295.yml
new file mode 100644
index 0000000000..a776275e6e
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10295.yml
@@ -0,0 +1,4 @@
+author: "kevinz000"
+delete-after: True
+changes:
+ - balance: "Abductor mindsnapping (aka abductee objectives) can now be \"cured\" with brain surgery."
diff --git a/html/changelogs/AutoChangeLog-pr-10301.yml b/html/changelogs/AutoChangeLog-pr-10301.yml
deleted file mode 100644
index 2acac559e9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10301.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "range on Engi Tray scanners and Rad-Scanners"
diff --git a/html/changelogs/AutoChangeLog-pr-10306.yml b/html/changelogs/AutoChangeLog-pr-10306.yml
deleted file mode 100644
index 9ab82dbda0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10306.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Arturlang"
-delete-after: True
-changes:
- - tweak: "Vampires are no longer as tanky"
diff --git a/html/changelogs/AutoChangeLog-pr-10309.yml b/html/changelogs/AutoChangeLog-pr-10309.yml
deleted file mode 100644
index a59ebff156..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10309.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Seris02"
-delete-after: True
-changes:
- - rscadd: "disabler sechuds"
diff --git a/html/changelogs/AutoChangeLog-pr-10319.yml b/html/changelogs/AutoChangeLog-pr-10319.yml
deleted file mode 100644
index 88235aab8e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10319.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Seris02"
-delete-after: True
-changes:
- - rscadd: "adds coconut"
- - rscadd: "adds a coconut bong"
diff --git a/html/changelogs/AutoChangeLog-pr-10329.yml b/html/changelogs/AutoChangeLog-pr-10329.yml
deleted file mode 100644
index e5d78ddf96..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10329.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Naksu"
-delete-after: True
-changes:
- - code_imp: "reagent IDs have been removed in favor using reagent typepaths where applicable"
- - bugfix: "mechas, borg hyposprays etc no longer display internal reagent ids to the player"
diff --git a/html/changelogs/AutoChangeLog-pr-10330.yml b/html/changelogs/AutoChangeLog-pr-10330.yml
deleted file mode 100644
index b2a46ef605..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10330.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "keronshb"
-delete-after: True
-changes:
- - rscadd: "Adds new features for nanites"
diff --git a/html/changelogs/AutoChangeLog-pr-10333.yml b/html/changelogs/AutoChangeLog-pr-10333.yml
deleted file mode 100644
index b5c11a4646..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10333.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Grass now makes light beer when distilled"
diff --git a/html/changelogs/AutoChangeLog-pr-10337.yml b/html/changelogs/AutoChangeLog-pr-10337.yml
deleted file mode 100644
index 370a8fdc04..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10337.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Seris02"
-delete-after: True
-changes:
- - rscadd: "Auto ooc"
- - admin: "changed \"assume direct control\" from m.ckey = src.ckey to adminmob.transfer_ckey(M) so it works with auto ooc"
diff --git a/html/changelogs/AutoChangeLog-pr-10338.yml b/html/changelogs/AutoChangeLog-pr-10338.yml
deleted file mode 100644
index c4816a3fbe..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10338.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Seris02"
-delete-after: True
-changes:
- - rscadd: "marshmallow"
diff --git a/html/changelogs/AutoChangeLog-pr-10339.yml b/html/changelogs/AutoChangeLog-pr-10339.yml
deleted file mode 100644
index c313c4bf80..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10339.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Seris02"
-delete-after: True
-changes:
- - rscadd: "telescopic IV drip"
diff --git a/html/changelogs/AutoChangeLog-pr-10344.yml b/html/changelogs/AutoChangeLog-pr-10344.yml
deleted file mode 100644
index e0381c6a43..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10344.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Chestbursters won't delete the host's brain somewhat anymore."
diff --git a/html/changelogs/AutoChangeLog-pr-10345.yml b/html/changelogs/AutoChangeLog-pr-10345.yml
deleted file mode 100644
index a95653cdda..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10345.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "allows bandoliers to hold any ammo type as long as it has a casing"
diff --git a/html/changelogs/AutoChangeLog-pr-10346.yml b/html/changelogs/AutoChangeLog-pr-10346.yml
deleted file mode 100644
index 3a0cd6dae4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10346.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Bhijn"
-delete-after: True
-changes:
- - rscadd: "Limbs now regenerate their stamina faster while disabled"
- - rscadd: "Limbs now have the same incoming stamina damage multiplier mechanics as spacemen, where the more staminaloss they take while disabled, the less staminaloss they'll take."
- - balance: "Limbs have had their base stamina regen rate doubled to match the doubled stamina regen rate of standard spacemen."
diff --git a/html/changelogs/AutoChangeLog-pr-10347.yml b/html/changelogs/AutoChangeLog-pr-10347.yml
deleted file mode 100644
index c0508aa279..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10347.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "The stamina buffer no longer uses stamina while recharging."
diff --git a/html/changelogs/AutoChangeLog-pr-10349.yml b/html/changelogs/AutoChangeLog-pr-10349.yml
deleted file mode 100644
index fad3179c6e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10349.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "KathrinBailey"
-delete-after: True
-changes:
- - rscadd: "Empty engineering lockers for mappers."
- - rscadd: "Industrial welding tools to the engineer welding locker."
- - rscdel: "Removed the multitool, airlock painter, mechanical toolbox, brown sneakers, hazard vest and airlock painter from the CE's locker."
diff --git a/html/changelogs/AutoChangeLog-pr-10350.yml b/html/changelogs/AutoChangeLog-pr-10350.yml
deleted file mode 100644
index 580f1d68cf..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10350.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - rscadd: "Ghost cafe mobs can now ghostize"
- - rscadd: "Ghost cafe now has a cremator"
- - rscadd: "Ghost cafe mobs are now eligible for ghost roles"
- - refactor: "Ghost roles now use an element for eligibility purposes"
diff --git a/html/changelogs/AutoChangeLog-pr-10356.yml b/html/changelogs/AutoChangeLog-pr-10356.yml
deleted file mode 100644
index 1016b559ee..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10356.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Bhijn"
-delete-after: True
-changes:
- - rscadd: "Added a preference to make the sprint hotkey be a toggle instead of a hold bind"
- - rscadd: "Added a preference to bind the sprint hotkey to space instead of shift."
diff --git a/html/changelogs/AutoChangeLog-pr-10357.yml b/html/changelogs/AutoChangeLog-pr-10357.yml
deleted file mode 100644
index 048baa3041..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10357.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - bugfix: "You can toggle some prefs properly now."
diff --git a/html/changelogs/AutoChangeLog-pr-10358.yml b/html/changelogs/AutoChangeLog-pr-10358.yml
deleted file mode 100644
index a578e6e336..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10358.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - server: "Cleans out the last years of changlogs"
diff --git a/html/changelogs/AutoChangeLog-pr-10361.yml b/html/changelogs/AutoChangeLog-pr-10361.yml
deleted file mode 100644
index 0224bdcb49..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10361.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CameronWoof"
-delete-after: True
-changes:
- - rscadd: "Ghost Cafe patrons now spawn with chameleon kits. Dress up! Be fancy!"
diff --git a/html/changelogs/AutoChangeLog-pr-10362.yml b/html/changelogs/AutoChangeLog-pr-10362.yml
deleted file mode 100644
index f92e16302a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10362.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "rouge cases of #$39; in bottle/pill/patch/condiments"
diff --git a/html/changelogs/AutoChangeLog-pr-10364.yml b/html/changelogs/AutoChangeLog-pr-10364.yml
deleted file mode 100644
index 8834c494ad..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10364.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - bugfix: "telescopic iv drips now have the proper sanity checks for deployment."
diff --git a/html/changelogs/AutoChangeLog-pr-10365.yml b/html/changelogs/AutoChangeLog-pr-10365.yml
deleted file mode 100644
index f7ba047fc7..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10365.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - bugfix: "no ass slap is no longer the same thing as no aphro"
diff --git a/html/changelogs/AutoChangeLog-pr-10366.yml b/html/changelogs/AutoChangeLog-pr-10366.yml
deleted file mode 100644
index ec8d234edd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10366.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Hatterhat"
-delete-after: True
-changes:
- - balance: "Beakers are generally more useful now, with slight capacity increases."
- - tweak: "Transfer amounts are different now. Adjust your muscle memory to compensate."
diff --git a/html/changelogs/AutoChangeLog-pr-10368.yml b/html/changelogs/AutoChangeLog-pr-10368.yml
deleted file mode 100644
index e6486f2815..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10368.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Hatterhat"
-delete-after: True
-changes:
- - balance: "ore redemption machines actually get affected by lasers again kthx"
diff --git a/html/changelogs/AutoChangeLog-pr-10369.yml b/html/changelogs/AutoChangeLog-pr-10369.yml
deleted file mode 100644
index c292d948fb..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10369.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Hatterhat"
-delete-after: True
-changes:
- - tweak: "crusher trophy drop chance on mining mobs increased to 1 in 4 (from 1 in 20)"
diff --git a/html/changelogs/AutoChangeLog-pr-10370.yml b/html/changelogs/AutoChangeLog-pr-10370.yml
deleted file mode 100644
index 6674fd2e17..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10370.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Hatterhat"
-delete-after: True
-changes:
- - bugfix: "Blood-drunk buff from blood-drunk eye crusher trophy is less likely to cripple its user."
diff --git a/html/changelogs/AutoChangeLog-pr-10371.yml b/html/changelogs/AutoChangeLog-pr-10371.yml
deleted file mode 100644
index e4322d70f1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10371.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kappa-sama"
-delete-after: True
-changes:
- - rscadd: "loot crates in cargo contraband"
diff --git a/html/changelogs/AutoChangeLog-pr-10372.yml b/html/changelogs/AutoChangeLog-pr-10372.yml
deleted file mode 100644
index 6bb60c3d8d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10372.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Hatterhat"
-delete-after: True
-changes:
- - tweak: "Forcefield projectors now fit on toolbelts."
- - imageadd: "New sprites for ATMOS holofan and forcefield projectors!"
diff --git a/html/changelogs/AutoChangeLog-pr-10374.yml b/html/changelogs/AutoChangeLog-pr-10374.yml
deleted file mode 100644
index 376f49a4d4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10374.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Bhijn helped"
-delete-after: True
-changes:
- - bugfix: "Fixes Dragon's Tooth Sword 50% armor penetration by making it 35%"
diff --git a/html/changelogs/AutoChangeLog-pr-10375.yml b/html/changelogs/AutoChangeLog-pr-10375.yml
deleted file mode 100644
index 7d0cc2bf44..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10375.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "r4d6"
-delete-after: True
-changes:
- - rscadd: "Added a Radiation Hardsuit"
- - rscadd: "Added a Radiation Hardsuit crate"
diff --git a/html/changelogs/AutoChangeLog-pr-10378.yml b/html/changelogs/AutoChangeLog-pr-10378.yml
deleted file mode 100644
index c7ab7d42c1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10378.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "EmeraldSundisk"
-delete-after: True
-changes:
- - rscadd: "Adds a sign outside MetaStation's custodial closet"
diff --git a/html/changelogs/AutoChangeLog-pr-10379.yml b/html/changelogs/AutoChangeLog-pr-10379.yml
deleted file mode 100644
index 9623f815d6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10379.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ryll/Shaps, ported by Hatterhat"
-delete-after: True
-changes:
- - rscadd: "Point-blanking people with shotguns actually throws them backwards!"
diff --git a/html/changelogs/AutoChangeLog-pr-10380.yml b/html/changelogs/AutoChangeLog-pr-10380.yml
deleted file mode 100644
index 4604329137..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10380.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Unit2E & JMoldy, ported by Hatterhat"
-delete-after: True
-changes:
- - balance: "the powerfist now punches people away at high velocity depending on setting."
- - rscadd: "the powerfist now leaks the gas it uses onto the tile you're on."
- - tweak: "Adds weak punch variations for empty and near-empty punching."
diff --git a/html/changelogs/AutoChangeLog-pr-10383.yml b/html/changelogs/AutoChangeLog-pr-10383.yml
deleted file mode 100644
index c6787bbafe..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10383.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - bugfix: "megafauna can hear again"
diff --git a/html/changelogs/AutoChangeLog-pr-10384.yml b/html/changelogs/AutoChangeLog-pr-10384.yml
deleted file mode 100644
index 315a62dadd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10384.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Tlaltecuhtli, Nemvar, Trilby, Hatterhat"
-delete-after: True
-changes:
- - rscadd: "russian surplus crate, sec ammo crate, meat/veggie/fruit crate, rped crate, bomb suit crate, bio suit crate, parrot crate, chem crate, db crate"
- - tweak: "lowered price of some crates which are overpriced for no reason aka the tablet crate and the mech circuits crates, track implant crate has also track .38 ammo"
- - bugfix: "sectech vendor has a refill pack"
diff --git a/html/changelogs/AutoChangeLog-pr-10388.yml b/html/changelogs/AutoChangeLog-pr-10388.yml
deleted file mode 100644
index fd06a5db3f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10388.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CameronWoof"
-delete-after: True
-changes:
- - rscadd: "Robots can now check the crew manifest from anywhere with the \"View Crew Manifest\" verb."
diff --git a/html/changelogs/AutoChangeLog-pr-10399.yml b/html/changelogs/AutoChangeLog-pr-10399.yml
deleted file mode 100644
index cbdb00630c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10399.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - balance: "Cargo passive gen is now 500 down from 750."
diff --git a/html/changelogs/AutoChangeLog-pr-10401.yml b/html/changelogs/AutoChangeLog-pr-10401.yml
deleted file mode 100644
index 2aa8d91244..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10401.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "r4d6"
-delete-after: True
-changes:
- - rscadd: "Added 3 SM Engine variations."
diff --git a/html/changelogs/AutoChangeLog-pr-10403.yml b/html/changelogs/AutoChangeLog-pr-10403.yml
deleted file mode 100644
index 321789a546..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10403.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "r4d6"
-delete-after: True
-changes:
- - rscadd: "Added a way to make opaque plastic flaps
-change: Change the already existing flap recipe to show that they are see-through"
diff --git a/html/changelogs/AutoChangeLog-pr-10404.yml b/html/changelogs/AutoChangeLog-pr-10404.yml
deleted file mode 100644
index 5f88a991ff..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10404.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Xantholne"
-delete-after: True
-changes:
- - tweak: "Christmas clothes moved from clothesmate and loadout to premium autodrobe, hoodies and boots remain."
diff --git a/html/changelogs/AutoChangeLog-pr-10410.yml b/html/changelogs/AutoChangeLog-pr-10410.yml
deleted file mode 100644
index c6c9d24749..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10410.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CameronWoof"
-delete-after: True
-changes:
- - tweak: "Lizard tails are now viable options for humans and anthromorphs."
diff --git a/html/changelogs/AutoChangeLog-pr-10412.yml b/html/changelogs/AutoChangeLog-pr-10412.yml
deleted file mode 100644
index b838dbb680..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10412.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Linzolle"
-delete-after: True
-changes:
- - bugfix: "fixes matchboxes runtiming every time they spawn"
diff --git a/html/changelogs/AutoChangeLog-pr-10413.yml b/html/changelogs/AutoChangeLog-pr-10413.yml
deleted file mode 100644
index 6d6378675b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10413.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "nik707"
-delete-after: True
-changes:
- - tweak: "engraving light_power from 1 to 0.3"
diff --git a/html/changelogs/AutoChangeLog-pr-10414.yml b/html/changelogs/AutoChangeLog-pr-10414.yml
new file mode 100644
index 0000000000..25750a889d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10414.yml
@@ -0,0 +1,4 @@
+author: "CameronWoof"
+delete-after: True
+changes:
+ - tweak: "Lighting looks better now. I can say that because the PR wouldn't be merged and you wouldn't be reading this if it wasn't true."
diff --git a/html/changelogs/AutoChangeLog-pr-10416.yml b/html/changelogs/AutoChangeLog-pr-10416.yml
deleted file mode 100644
index 13432b283c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10416.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-author: "r4d6"
-delete-after: True
-changes:
- - rscadd: "Animations for the RCD"
- - bugfix: "Said animations being pulled by the Singulo"
- - balance: "Prevent Reinforced Doors from being RCD'ed"
- - bugfix: "Deconstructing Floors now cost MUs like everything else"
- - tweak: "changed the RCD's upgrades into flags"
- - rscadd: "Allow RCDs to print APC, Firelocks and Fire Alarms with the right upgrade"
- - balance: "Allow Engineers to print RCDs and RPDs from their protolathe without needing to hack one."
diff --git a/html/changelogs/AutoChangeLog-pr-10417.yml b/html/changelogs/AutoChangeLog-pr-10417.yml
deleted file mode 100644
index 31ac154ac9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10417.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - config: "Added a few more nightshift config entries"
- - rscadd: "nightshift_public_area variable in areas to determine how public an area is."
- - rscadd: "NIGHT_SHIFT_PUBLIC_AREAS_ONLY config entry allows the server to be configured to only nightshift areas of that level and below (so areas that are more public)"
- - rscadd: "Config entries added for requiring authorizations to toggle nightshift. Defaults to only requiring on public areas as determined by above"
diff --git a/html/changelogs/AutoChangeLog-pr-10420.yml b/html/changelogs/AutoChangeLog-pr-10420.yml
deleted file mode 100644
index b719eca84c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10420.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "MrJWhit"
-delete-after: True
-changes:
- - tweak: "Increases plasma usage in radiation collectors"
diff --git a/html/changelogs/AutoChangeLog-pr-10427.yml b/html/changelogs/AutoChangeLog-pr-10427.yml
deleted file mode 100644
index 5f4fe73988..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10427.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Hatterhat"
-delete-after: True
-changes:
- - tweak: "tweaks some values around with beaker transfer amounts, adds a transfer value verb (altclick)"
diff --git a/html/changelogs/AutoChangeLog-pr-10428.yml b/html/changelogs/AutoChangeLog-pr-10428.yml
deleted file mode 100644
index 2cd635d0a2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10428.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - balance: "Devastating bombs kills bomb armor'd mobs again"
diff --git a/html/changelogs/AutoChangeLog-pr-10429.yml b/html/changelogs/AutoChangeLog-pr-10429.yml
deleted file mode 100644
index cc83f8abb6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10429.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "Adds missing but needed flags to MASON RIG"
diff --git a/html/changelogs/AutoChangeLog-pr-10430.yml b/html/changelogs/AutoChangeLog-pr-10430.yml
deleted file mode 100644
index 4fd03a5b2b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10430.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - balance: "nuclear fist buffed."
diff --git a/html/changelogs/AutoChangeLog-pr-10432.yml b/html/changelogs/AutoChangeLog-pr-10432.yml
deleted file mode 100644
index a0b40baa45..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10432.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "missing sprites with crushed cans"
diff --git a/html/changelogs/AutoChangeLog-pr-10433.yml b/html/changelogs/AutoChangeLog-pr-10433.yml
deleted file mode 100644
index 036e74a804..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10433.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - balance: "cogscarabs are now fulltile-hitbox."
diff --git a/html/changelogs/AutoChangeLog-pr-10435.yml b/html/changelogs/AutoChangeLog-pr-10435.yml
deleted file mode 100644
index 6b684a57a5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10435.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "FantasticFwoosh, ported by Hatterhat"
-delete-after: True
-changes:
- - rscadd: "Both reagent universal enzyme & sacks of flour are now available for their respective costs from the biogenerator."
- - rscadd: "New crafting recipies for donut boxes, eggboxes & candle boxes have been added to cardboard recipes for the collective benefit of service personnel and the station."
diff --git a/html/changelogs/AutoChangeLog-pr-10437.yml b/html/changelogs/AutoChangeLog-pr-10437.yml
deleted file mode 100644
index ee454f47b9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10437.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixed roundstart mushpeople being unable to MUSH PUUUUUUUUUUUUNCH!!"
diff --git a/html/changelogs/AutoChangeLog-pr-10439.yml b/html/changelogs/AutoChangeLog-pr-10439.yml
deleted file mode 100644
index 92b151b883..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10439.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "LetterN"
-delete-after: True
-changes:
- - rscadd: "Doppler logs"
diff --git a/html/changelogs/AutoChangeLog-pr-10440.yml b/html/changelogs/AutoChangeLog-pr-10440.yml
deleted file mode 100644
index e942f4056f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10440.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - rscadd: "Added a sort of \"game mode ban\" by way of having people rank their game modes favorite to least favorite after the secret/extended vote."
- - bugfix: "Turns out the schulze scoring was written wrong and it was setting things to 0 that shouldn't have been, so that's fixed."
diff --git a/html/changelogs/AutoChangeLog-pr-10450.yml b/html/changelogs/AutoChangeLog-pr-10450.yml
deleted file mode 100644
index d2c5d8b40a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10450.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - balance: "emitters are now hitscan"
diff --git a/html/changelogs/AutoChangeLog-pr-10452.yml b/html/changelogs/AutoChangeLog-pr-10452.yml
deleted file mode 100644
index e51b9ff752..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10452.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Lattices can be examined yet again."
diff --git a/html/changelogs/AutoChangeLog-pr-10454.yml b/html/changelogs/AutoChangeLog-pr-10454.yml
deleted file mode 100644
index d89603959e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10454.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Commandersand"
-delete-after: True
-changes:
- - bugfix: "fixed some clothnig sprites"
diff --git a/html/changelogs/AutoChangeLog-pr-10456.yml b/html/changelogs/AutoChangeLog-pr-10456.yml
deleted file mode 100644
index 4c94455e47..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10456.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-author: "Putnam"
-delete-after: True
-changes:
- - rscdel: "Arousal damage is gone, and with it the arousal damage heart on the UI."
- - rscdel: "As exhibitionist relied on arousal damage, that's gone too."
- - rscdel: "Bonermeter and electronic stimulation circuit modules are gone."
- - rscdel: "Masturbation is no longer an option in the climax menu. It was identical to climax alone in every way but text. Emote it out."
- - rscadd: "Arousal on genitals can now be displayed manually, on a case-by-case basis."
- - rscadd: "\"Climax alone\" and \"climax with partner\" now only display to the people directly involved in the interaction.
-rework: Catnip tea, catnip, crocin, hexacrocin, camphor, hexacamphor all had functions or bits of functions reworked."
- - tweak: "\"Climax with partner\" now requires consent from both parties--it can no longer be used on mindless mobs, and it asks the mob getting climaxed with if they consent first."
- - tweak: "A lot of MKUltra behaviors have been moved to hypno checks or removed due to reliance on maso/nympho/exhib."
diff --git a/html/changelogs/AutoChangeLog-pr-10457.yml b/html/changelogs/AutoChangeLog-pr-10457.yml
deleted file mode 100644
index 203842b0b6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10457.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "r4d6"
-delete-after: True
-changes:
- - rscadd: "Added a playback device"
- - bugfix: "Made the Voice Analyzer actually care about languages"
diff --git a/html/changelogs/AutoChangeLog-pr-10459.yml b/html/changelogs/AutoChangeLog-pr-10459.yml
deleted file mode 100644
index 77de8eb193..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10459.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Putnam"
-delete-after: True
-changes:
- - rscadd: "Cold-blooded quirk"
diff --git a/html/changelogs/AutoChangeLog-pr-10463.yml b/html/changelogs/AutoChangeLog-pr-10463.yml
deleted file mode 100644
index 70e97975ce..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10463.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - config: "Random engines are now weighted."
diff --git a/html/changelogs/AutoChangeLog-pr-10465.yml b/html/changelogs/AutoChangeLog-pr-10465.yml
deleted file mode 100644
index 26dff901b2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10465.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - rscadd: "Ghost dojo now has an autoylathe."
- - rscdel: "Ghost dojo no longer has VR or modular computer access."
- - tweak: "Ghost dojo mobs are pacifists."
- - tweak: "Ghost dojo booze-o-mat is now all access."
- - bugfix: "Ghost dojo crematorium now has a button."
diff --git a/html/changelogs/AutoChangeLog-pr-10467.yml b/html/changelogs/AutoChangeLog-pr-10467.yml
deleted file mode 100644
index 7fa379f088..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10467.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Seris02"
-delete-after: True
-changes:
- - bugfix: "cardboard box speed"
diff --git a/html/changelogs/AutoChangeLog-pr-10468.yml b/html/changelogs/AutoChangeLog-pr-10468.yml
deleted file mode 100644
index 055411d0f2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10468.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - rscadd: "Ghosting no longer stops abductors from using you."
diff --git a/html/changelogs/AutoChangeLog-pr-10472.yml b/html/changelogs/AutoChangeLog-pr-10472.yml
deleted file mode 100644
index 9404d70b7b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10472.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "keronshb"
-delete-after: True
-changes:
- - bugfix: "fixed the missing icons from Dermal Button nanites"
diff --git a/html/changelogs/AutoChangeLog-pr-10473.yml b/html/changelogs/AutoChangeLog-pr-10473.yml
deleted file mode 100644
index f1821a3cce..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10473.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Bhijn"
-delete-after: True
-changes:
- - bugfix: "server_hop can no longer be used to remotely lobotomize a spaceman"
diff --git a/html/changelogs/AutoChangeLog-pr-10474.yml b/html/changelogs/AutoChangeLog-pr-10474.yml
deleted file mode 100644
index ae7b5b3fcb..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10474.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - bugfix: "Traitor objectives don't take a dump when they try to add an assassinate anymore"
- - admin: "Objective removal with antag panel no longer commented out silently while still being an option that gives useful feedback on stuff it's not doing in any respect"
diff --git a/html/changelogs/AutoChangeLog-pr-10478.yml b/html/changelogs/AutoChangeLog-pr-10478.yml
deleted file mode 100644
index b174a5e8ee..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10478.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Seris02"
-delete-after: True
-changes:
- - tweak: "makes gorilla shuttle emag only"
diff --git a/html/changelogs/AutoChangeLog-pr-10480.yml b/html/changelogs/AutoChangeLog-pr-10480.yml
deleted file mode 100644
index 7ecfd7057e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10480.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - rscadd: "Second, temporary flavor text!"
diff --git a/html/changelogs/AutoChangeLog-pr-10481.yml b/html/changelogs/AutoChangeLog-pr-10481.yml
deleted file mode 100644
index c884a45ec9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10481.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "dapnee"
-delete-after: True
-changes:
- - imageadd: "new toxin's uniform and accessories"
- - imagedel: "old toxin's uniform and accessories"
diff --git a/html/changelogs/AutoChangeLog-pr-10482.yml b/html/changelogs/AutoChangeLog-pr-10482.yml
deleted file mode 100644
index e97c8870d4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10482.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kappa-sama"
-delete-after: True
-changes:
- - code_imp: "modular_citadel file movement"
diff --git a/html/changelogs/AutoChangeLog-pr-10483.yml b/html/changelogs/AutoChangeLog-pr-10483.yml
deleted file mode 100644
index 1f016b1591..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10483.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - bugfix: "Limb damage works now"
diff --git a/html/changelogs/AutoChangeLog-pr-10485.yml b/html/changelogs/AutoChangeLog-pr-10485.yml
deleted file mode 100644
index 6bf082f8ba..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10485.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Detective-Google"
-delete-after: True
-changes:
- - tweak: "replaced the sprites with new ones requested."
diff --git a/html/changelogs/AutoChangeLog-pr-10486.yml b/html/changelogs/AutoChangeLog-pr-10486.yml
deleted file mode 100644
index 448bbc162c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10486.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Seris02"
-delete-after: True
-changes:
- - tweak: "changed where the observe verb is."
diff --git a/html/changelogs/AutoChangeLog-pr-10489.yml b/html/changelogs/AutoChangeLog-pr-10489.yml
deleted file mode 100644
index 4e393bd4b1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10489.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Seris02"
-delete-after: True
-changes:
- - tweak: "the way chameleon clothes update on change"
- - bugfix: "chameleon cloak icon"
diff --git a/html/changelogs/AutoChangeLog-pr-10492.yml b/html/changelogs/AutoChangeLog-pr-10492.yml
deleted file mode 100644
index de6ab309ab..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10492.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Glitter is now makeable with ground plastic and some crayons"
diff --git a/html/changelogs/AutoChangeLog-pr-10493.yml b/html/changelogs/AutoChangeLog-pr-10493.yml
deleted file mode 100644
index 201eaad5b5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10493.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - tweak: "Score instead of ranked choice for mode tiers"
diff --git a/html/changelogs/AutoChangeLog-pr-10495.yml b/html/changelogs/AutoChangeLog-pr-10495.yml
deleted file mode 100644
index 02ffedf5fc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10495.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - rscadd: "guests can now looc"
diff --git a/html/changelogs/AutoChangeLog-pr-10497.yml b/html/changelogs/AutoChangeLog-pr-10497.yml
deleted file mode 100644
index 5acb6f8c47..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10497.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - code_imp: "Makes more folders and files for uplink."
diff --git a/html/changelogs/AutoChangeLog-pr-10498.yml b/html/changelogs/AutoChangeLog-pr-10498.yml
deleted file mode 100644
index 986abc77c2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10498.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - tweak: "tableslamming has 0.4 second cooldown instead of 0.8"
diff --git a/html/changelogs/AutoChangeLog-pr-10501.yml b/html/changelogs/AutoChangeLog-pr-10501.yml
deleted file mode 100644
index 27e7ddbb8e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10501.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Putnam"
-delete-after: True
-changes:
- - rscadd: "Two relief valves for atmospherics, available in your RPD today: a unary one that opens to air and a binary one that connects two pipenets, like a manual valve."
- - tweak: "The atmos waste outlet injector on box has been replaced with an atmos waste relief valve."
diff --git a/html/changelogs/AutoChangeLog-pr-10503.yml b/html/changelogs/AutoChangeLog-pr-10503.yml
deleted file mode 100644
index b067aa6c55..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10503.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "r4d6"
-delete-after: True
-changes:
- - bugfix: "fixed SM's piping"
diff --git a/html/changelogs/AutoChangeLog-pr-10504.yml b/html/changelogs/AutoChangeLog-pr-10504.yml
deleted file mode 100644
index 7e35ac6e72..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10504.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Xantholne"
-delete-after: True
-changes:
- - rscadd: "Botany bee pet, Bumbles"
- - rscadd: "New bee models that aren't 1 tile big of 0 opacity pixels"
diff --git a/html/changelogs/AutoChangeLog-pr-10505.yml b/html/changelogs/AutoChangeLog-pr-10505.yml
deleted file mode 100644
index dd0932c50e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10505.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "LetterN"
-delete-after: True
-changes:
- - tweak: "Shockcolar and electropack uses the new signaler ui"
- - tweak: "Renaming shockcolar requires a pen"
diff --git a/html/changelogs/AutoChangeLog-pr-10507.yml b/html/changelogs/AutoChangeLog-pr-10507.yml
deleted file mode 100644
index 70d82d9cf6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10507.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "LetterN"
-delete-after: True
-changes:
- - rscadd: "Adds banjo"
diff --git a/html/changelogs/AutoChangeLog-pr-10509.yml b/html/changelogs/AutoChangeLog-pr-10509.yml
deleted file mode 100644
index 4e1ede0631..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10509.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Made reagent containers examine text less annoying."
diff --git a/html/changelogs/AutoChangeLog-pr-10511.yml b/html/changelogs/AutoChangeLog-pr-10511.yml
deleted file mode 100644
index 5f3bf739cb..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10511.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - bugfix: "health analyzers now work"
diff --git a/html/changelogs/AutoChangeLog-pr-10513.yml b/html/changelogs/AutoChangeLog-pr-10513.yml
deleted file mode 100644
index 6428c4e281..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10513.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "r4d6"
-delete-after: True
-changes:
- - rscadd: "Added a message when pulsing the open wire."
diff --git a/html/changelogs/AutoChangeLog-pr-10516.yml b/html/changelogs/AutoChangeLog-pr-10516.yml
deleted file mode 100644
index 39dd05a4db..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10516.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BonniePandora"
-delete-after: True
-changes:
- - admin: "Added another SDQL option. Using \"UPDATE selectors SET #null=value\" will now resolve value and discard the return. This is useful if you only care about the side effect of a proc."
diff --git a/html/changelogs/AutoChangeLog-pr-10518.yml b/html/changelogs/AutoChangeLog-pr-10518.yml
deleted file mode 100644
index 29de186e50..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10518.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Seris02"
-delete-after: True
-changes:
- - balance: "Explosions now cause knockdown instead of KOs, with the amount of time scaling off bomb armor. Heavy explosions still cause a ~2 second KO for follow up attacks."
- - balance: "Devastating explosions now no longer gib players with more than 50 bomb armor. This used to be more or less random depending on the amount of bomb armor."
- - code_imp: "Removed reagent explosion code that would trigger for <1 amount reactions."
diff --git a/html/changelogs/AutoChangeLog-pr-10520.yml b/html/changelogs/AutoChangeLog-pr-10520.yml
deleted file mode 100644
index ae23c082d8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10520.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Denton, ported by Hatterhat"
-delete-after: True
-changes:
- - tweak: "Most upgradeable machines now show their upgrade status when examined while standing right next to them."
- - tweak: "Added examine messages to teleporter stations that hint at their multitool/wirecutter interactions."
- - tweak: "Renamed teleporter stations from station to teleporter station."
- - code_imp: "Changed the teleporter hub accurate var to accuracy; the old name misled people into thinking that it was a boolean."
diff --git a/html/changelogs/AutoChangeLog-pr-10522.yml b/html/changelogs/AutoChangeLog-pr-10522.yml
deleted file mode 100644
index b03b990762..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10522.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Hatterhat"
-delete-after: True
-changes:
- - rscadd: "Syndicate sleepers (read: the ones that're red and have controls in them) can now be recreated with a sufficient basis in nonstandard (read: illegal) technologies!"
diff --git a/html/changelogs/AutoChangeLog-pr-10523.yml b/html/changelogs/AutoChangeLog-pr-10523.yml
deleted file mode 100644
index 999fc1dd92..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10523.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Hatterhat"
-delete-after: True
-changes:
- - bugfix: "Explorer hoods on standard explorer suits can be reinforced with goliath hide plates again."
diff --git a/html/changelogs/AutoChangeLog-pr-10530.yml b/html/changelogs/AutoChangeLog-pr-10530.yml
deleted file mode 100644
index 16cc66adb9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10530.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kappa-sama"
-delete-after: True
-changes:
- - code_imp: "modular citadel loses some files"
diff --git a/html/changelogs/AutoChangeLog-pr-10531.yml b/html/changelogs/AutoChangeLog-pr-10531.yml
deleted file mode 100644
index 6c1125a687..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10531.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Seed packs now have RnD points inside them"
- - rscadd: "New tips that reflect the now use seed packs have for Rnd / Chems affect on plants"
- - code_imp: "Made the research file look nice rather then an eye harming list"
diff --git a/html/changelogs/AutoChangeLog-pr-10532.yml b/html/changelogs/AutoChangeLog-pr-10532.yml
deleted file mode 100644
index cf742b47f7..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10532.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Virus food dispensers dispense virus food again."
- - bugfix: "Borg hypos inputs do not display typepaths anymore."
- - bugfix: "Restored chem dispensers alphabetical order."
diff --git a/html/changelogs/AutoChangeLog-pr-10535.yml b/html/changelogs/AutoChangeLog-pr-10535.yml
deleted file mode 100644
index db37120317..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10535.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Hatterhat"
-delete-after: True
-changes:
- - rscadd: "A shipment of Staff Assistant jumpsuits from the Goon-operated stations appear to have made their way into your loadout selections - and into the contraband list from ClothesMates..."
diff --git a/html/changelogs/AutoChangeLog-pr-10538.yml b/html/changelogs/AutoChangeLog-pr-10538.yml
deleted file mode 100644
index 01119f886f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10538.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - bugfix: "Chemistry not :b:roke"
diff --git a/html/changelogs/AutoChangeLog-pr-10539.yml b/html/changelogs/AutoChangeLog-pr-10539.yml
deleted file mode 100644
index 66a03ee573..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10539.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Savotta"
-delete-after: True
-changes:
- - rscadd: "snout"
- - imageadd: "snout"
diff --git a/html/changelogs/AutoChangeLog-pr-10544.yml b/html/changelogs/AutoChangeLog-pr-10544.yml
deleted file mode 100644
index a27ffad716..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10544.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "AffectedArc07"
-delete-after: True
-changes:
- - code_imp: "All code files are now in the LF line format, please stick to it"
diff --git a/html/changelogs/AutoChangeLog-pr-10546.yml b/html/changelogs/AutoChangeLog-pr-10546.yml
deleted file mode 100644
index a49c2027e5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10546.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "r4d6"
-delete-after: True
-changes:
- - bugfix: "fixed being able to use a playback device and a voice analyzer to activate each others"
diff --git a/html/changelogs/AutoChangeLog-pr-10547.yml b/html/changelogs/AutoChangeLog-pr-10547.yml
deleted file mode 100644
index 41d255e991..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10547.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - tweak: "Ghost dojo spawns will dust if their owner suicides or uses the \"ghost\" verb."
diff --git a/html/changelogs/AutoChangeLog-pr-10549.yml b/html/changelogs/AutoChangeLog-pr-10549.yml
deleted file mode 100644
index 11a770945d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10549.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Seris02"
-delete-after: True
-changes:
- - rscadd: "durathread winter coats from hyper station"
diff --git a/html/changelogs/AutoChangeLog-pr-10552.yml b/html/changelogs/AutoChangeLog-pr-10552.yml
deleted file mode 100644
index 846667ea2a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10552.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - tweak: "Replaces new fire alarms with a slightly updated version of the old ones."
- - bugfix: "Fixed bug where Amber alert had no proper alert lights, and red alert had amber lights."
diff --git a/html/changelogs/AutoChangeLog-pr-10556.yml b/html/changelogs/AutoChangeLog-pr-10556.yml
deleted file mode 100644
index af42a9eee6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10556.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "AffectedArc07"
-delete-after: True
-changes:
- - tweak: "Added CI step to check for CRLF files"
diff --git a/html/changelogs/AutoChangeLog-pr-10557.yml b/html/changelogs/AutoChangeLog-pr-10557.yml
deleted file mode 100644
index f5b37f6cee..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10557.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "timothyteakettle"
-delete-after: True
-changes:
- - bugfix: "fixed not being able to remove trait genes without a disk being inserted into the dna manipulator"
diff --git a/html/changelogs/AutoChangeLog-pr-10558.yml b/html/changelogs/AutoChangeLog-pr-10558.yml
deleted file mode 100644
index 09186767f3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10558.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "DeltaFire15"
-delete-after: True
-changes:
- - bugfix: "Vitality matrixes now correctly succ slimes"
diff --git a/html/changelogs/AutoChangeLog-pr-10563.yml b/html/changelogs/AutoChangeLog-pr-10563.yml
deleted file mode 100644
index 5efc4cfdb1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10563.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "Fixed fragile space suits breaking from weak and non-damaging \"weapons\" (such as the Sord, toys and foam darts)."
diff --git a/html/changelogs/AutoChangeLog-pr-10567.yml b/html/changelogs/AutoChangeLog-pr-10567.yml
deleted file mode 100644
index 9d73d1d947..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10567.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Sanitized cargo export messages for reagents."
diff --git a/html/changelogs/AutoChangeLog-pr-10568.yml b/html/changelogs/AutoChangeLog-pr-10568.yml
deleted file mode 100644
index 6916f1289f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10568.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "r4d6"
-delete-after: True
-changes:
- - rscadd: "added passive vent to the arsenal of atmospheric devices."
diff --git a/html/changelogs/AutoChangeLog-pr-10569.yml b/html/changelogs/AutoChangeLog-pr-10569.yml
deleted file mode 100644
index 0b9cb0b992..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10569.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "keronshb"
-delete-after: True
-changes:
- - rscadd: "Ports the special nanite remote, mood programs, and research generating nanites"
- - balance: "rebalances some nanites"
diff --git a/html/changelogs/AutoChangeLog-pr-10570.yml b/html/changelogs/AutoChangeLog-pr-10570.yml
deleted file mode 100644
index 9eaf2168a8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10570.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - code_imp: "Mapping helpers added for power cables and atmos pipes."
diff --git a/html/changelogs/AutoChangeLog-pr-10571.yml b/html/changelogs/AutoChangeLog-pr-10571.yml
deleted file mode 100644
index 1d6844aa53..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10571.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Riot foam dart (not the ammo box) design cost is yet again consistent with the result's material amount."
diff --git a/html/changelogs/AutoChangeLog-pr-10578.yml b/html/changelogs/AutoChangeLog-pr-10578.yml
deleted file mode 100644
index a84fa5ba21..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10578.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "r4d6"
-delete-after: True
-changes:
- - rscadd: "Mining base now has a common area accessible via a new shuttle on the medium-highpop maps, and a security office connecting the gulag and the mining base. Gulag also has functional atmos."
diff --git a/html/changelogs/AutoChangeLog-pr-10579.yml b/html/changelogs/AutoChangeLog-pr-10579.yml
deleted file mode 100644
index c428c0109d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10579.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "r4d6"
-delete-after: True
-changes:
- - rscadd: "Added more Cyborg Landmarks"
diff --git a/html/changelogs/AutoChangeLog-pr-10580.yml b/html/changelogs/AutoChangeLog-pr-10580.yml
deleted file mode 100644
index 6cb625d7af..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10580.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - admin: "Crafting is logged in a file now"
diff --git a/html/changelogs/AutoChangeLog-pr-10582.yml b/html/changelogs/AutoChangeLog-pr-10582.yml
deleted file mode 100644
index 2024088fb8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10582.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - bugfix: "temporary flavor text now pops up properly"
diff --git a/html/changelogs/AutoChangeLog-pr-10584.yml b/html/changelogs/AutoChangeLog-pr-10584.yml
deleted file mode 100644
index e2c9f93ac8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10584.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "AffectedArc07"
-delete-after: True
-changes:
- - code_imp: "Line ending CI works now"
diff --git a/html/changelogs/AutoChangeLog-pr-10586.yml b/html/changelogs/AutoChangeLog-pr-10586.yml
deleted file mode 100644
index eb90213398..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10586.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - balance: "RLDs now cost more to use, have reduced matter capacity, and sheets are worth less when refilling them."
diff --git a/html/changelogs/AutoChangeLog-pr-10588.yml b/html/changelogs/AutoChangeLog-pr-10588.yml
deleted file mode 100644
index d3771298b2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10588.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "PersianXerxes"
-delete-after: True
-changes:
- - tweak: "Reduces the range of the forcefield projector from 7 tiles to 2 tiles."
diff --git a/html/changelogs/AutoChangeLog-pr-10590.yml b/html/changelogs/AutoChangeLog-pr-10590.yml
new file mode 100644
index 0000000000..e59c8decf0
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10590.yml
@@ -0,0 +1,11 @@
+author: "KathrinBailey"
+delete-after: True
+changes:
+ - bugfix: "Missing turf_decals in Cargo Office."
+ - bugfix: "Turns on the docking beacons on Box."
+ - bugfix: "Fixes Starboard Quarter maint room being spaced. It was never intended to be like how it was."
+ - bugfix: "The aforementioned maint room not having stuff in it."
+ - bugfix: "varedited photocopier sometimes not opening any UI."
+ - bugfix: "Atmos differences in Starboard Quarter maint."
+ - bugfix: "Atmos differences in destroyed shuttle/EVA bridge. Plating replaced with airless plating."
+ - bugfix: "Rotates AI satellite computers. These have probably been like this since computers had the old sprites and no directional ones. You shouldn't sit at a chair to operate a sideways computer."
diff --git a/html/changelogs/AutoChangeLog-pr-10591.yml b/html/changelogs/AutoChangeLog-pr-10591.yml
deleted file mode 100644
index ac8504ec9c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10591.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - rscdel: "Blood duplication is gone, but viruses now react up to 5 times, 1 time per unit, for virus mix."
diff --git a/html/changelogs/AutoChangeLog-pr-10597.yml b/html/changelogs/AutoChangeLog-pr-10597.yml
deleted file mode 100644
index 9f28c4f84c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10597.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - code_imp: "demodularized player panel code, mostly"
- - admin: "added ghost role eligibility delay removal to player panel"
diff --git a/html/changelogs/AutoChangeLog-pr-10598.yml b/html/changelogs/AutoChangeLog-pr-10598.yml
deleted file mode 100644
index 91b52b7043..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10598.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - balance: "Metabolic synthesis disables if user isn't well-fed rather than if user is starving"
diff --git a/html/changelogs/AutoChangeLog-pr-10599.yml b/html/changelogs/AutoChangeLog-pr-10599.yml
deleted file mode 100644
index 33435979c7..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10599.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - bugfix: "Gibtonite no longer instantly explodes upon being pickaxe'd."
diff --git a/html/changelogs/AutoChangeLog-pr-10600.yml b/html/changelogs/AutoChangeLog-pr-10600.yml
deleted file mode 100644
index ab0c5ac964..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10600.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Kraseo"
-delete-after: True
-changes:
- - bugfix: "Jelly donuts and pink jelly donuts will now properly display sprinkled icon state."
- - bugfix: "Jelly donuts and its variants will properly spawn with berry juice."
- - bugfix: "Slime jelly donuts have slime jelly in them now. (thanks ghommie)"
diff --git a/html/changelogs/AutoChangeLog-pr-10602.yml b/html/changelogs/AutoChangeLog-pr-10602.yml
deleted file mode 100644
index 9394c83671..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10602.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixed a little exploit with ventcrawlers being capable of escaping closed turfs by printing scrubbers/vents into them."
diff --git a/html/changelogs/AutoChangeLog-pr-10603.yml b/html/changelogs/AutoChangeLog-pr-10603.yml
deleted file mode 100644
index 0f1acbf0be..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10603.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "KeRSedChaplain"
-delete-after: True
-changes:
- - imageadd: "The clockwork cuirass can now support slithering taur bodies."
diff --git a/html/changelogs/AutoChangeLog-pr-10606.yml b/html/changelogs/AutoChangeLog-pr-10606.yml
deleted file mode 100644
index c6cc269cbe..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10606.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "r4d6"
-delete-after: True
-changes:
- - refactor: "better code for passive vents"
diff --git a/html/changelogs/AutoChangeLog-pr-10608.yml b/html/changelogs/AutoChangeLog-pr-10608.yml
deleted file mode 100644
index 1c2015813e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10608.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - rscadd: "you can now block people on your PDA"
diff --git a/html/changelogs/AutoChangeLog-pr-10610.yml b/html/changelogs/AutoChangeLog-pr-10610.yml
deleted file mode 100644
index e413574fa1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10610.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "Owai-Seek"
-delete-after: True
-changes:
- - rscadd: "Four New Bounties"
- - tweak: "tweaked several bounties"
- - tweak: "reorganised several bounties"
- - balance: "balanced several bounties"
- - bugfix: "added shady jims to vendor"
diff --git a/html/changelogs/AutoChangeLog-pr-10614.yml b/html/changelogs/AutoChangeLog-pr-10614.yml
deleted file mode 100644
index 4c4d8bfdbd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10614.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Putnam3145"
-delete-after: True
-changes:
- - config: "Added suicide to the config."
diff --git a/html/changelogs/AutoChangeLog-pr-10615.yml b/html/changelogs/AutoChangeLog-pr-10615.yml
deleted file mode 100644
index f67392cd7f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10615.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "keronshb"
-delete-after: True
-changes:
- - bugfix: "fixed my messup"
diff --git a/html/changelogs/AutoChangeLog-pr-10617.yml b/html/changelogs/AutoChangeLog-pr-10617.yml
deleted file mode 100644
index 923913a043..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10617.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - bugfix: "Grenades can now have their timers adjusted."
diff --git a/html/changelogs/AutoChangeLog-pr-10619.yml b/html/changelogs/AutoChangeLog-pr-10619.yml
deleted file mode 100644
index acb76034ac..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10619.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Seris02"
-delete-after: True
-changes:
- - tweak: "conveyor belt now are stacks instead of single item"
- - tweak: "conveyor crate has 30 belts"
- - tweak: "printing a conveyor costs 3000 metal"
- - rscadd: "you can press the conveyor switch in hand to link any not deployed belts to it"
diff --git a/html/changelogs/AutoChangeLog-pr-10620.yml b/html/changelogs/AutoChangeLog-pr-10620.yml
deleted file mode 100644
index 8f5c990234..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10620.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Hatterhat"
-delete-after: True
-changes:
- - balance: "Dropped Exo-suit armor to put it more in line with being an explorer suit sidegrade and not a straight upgrade for Lavaland usage."
diff --git a/html/changelogs/AutoChangeLog-pr-10621.yml b/html/changelogs/AutoChangeLog-pr-10621.yml
deleted file mode 100644
index 0bb08dee2c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10621.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Hatterhat"
-delete-after: True
-changes:
- - rscadd: "You can now print .357 AP speedloaders from Security techfabs after you pick up the Advanced Non-Standard Ballistics node."
diff --git a/html/changelogs/AutoChangeLog-pr-10622.yml b/html/changelogs/AutoChangeLog-pr-10622.yml
deleted file mode 100644
index 3aa4159cb8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10622.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-author: "Owai-Seek"
-delete-after: True
-changes:
- - rscadd: "Towel, Bedsheet, and Colored bedsheet bins to Dojo. Some lockers with carpets and wood, another bathroom/shower, tons of cleaning supplies, some additional trash cans, a tiny medical area, and some vendors/vendor resupplies. Also added some Ambrosia Gaia seeds."
- - tweak: "Moved some lights around, extended the dojo a bit to make it feel more spacious."
- - rscdel: "Cafe Newsfeed Frame"
- - rscadd: "Towel, Bedsheet, and Colored bedsheet bins to Dojo. Some lockers with carpets and wood, another bathroom/shower, tons of cleaning supplies, some additional trash cans, a tiny medical area, and some vendors/vendor resupplies. Also added some Ambrosia Gaia seeds."
- - tweak: "Moved some lights around, extended the dojo a bit to make it feel more spacious."
- - rscdel: "Cafe Newsfeed Frame"
- - rscadd: "Towel, Bedsheet, and Colored bedsheet bins to Dojo. Some lockers with carpets and wood, another bathroom/shower, tons of cleaning supplies, some additional trash cans, a tiny medical area, and some vendors/vendor resupplies. Also added some Ambrosia Gaia seeds."
- - tweak: "Moved some lights around, extended the dojo a bit to make it feel more spacious."
diff --git a/html/changelogs/AutoChangeLog-pr-10635.yml b/html/changelogs/AutoChangeLog-pr-10635.yml
deleted file mode 100644
index 66c90808d6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10635.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Hatterhat"
-delete-after: True
-changes:
- - rscdel: "Forensic scanner removed from Advanced Biotechnology node."
diff --git a/html/changelogs/AutoChangeLog-pr-10636.yml b/html/changelogs/AutoChangeLog-pr-10636.yml
deleted file mode 100644
index a6354ef6b5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10636.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone, Ghommie"
-delete-after: True
-changes:
- - rscadd: "More types of glass can now be used to make a solar panel, with different sturdiness and efficiency depending the type."
diff --git a/html/changelogs/AutoChangeLog-pr-10640.yml b/html/changelogs/AutoChangeLog-pr-10640.yml
deleted file mode 100644
index f51f892d8d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10640.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "r4d6"
-delete-after: True
-changes:
- - bugfix: "fixed a hole in Meta"
diff --git a/html/changelogs/AutoChangeLog-pr-10641.yml b/html/changelogs/AutoChangeLog-pr-10641.yml
deleted file mode 100644
index 479729e1f2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10641.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "jakeramsay007"
-delete-after: True
-changes:
- - rscadd: "The assorted .357 revolvers (except russian revolver) can now also load .38, like real life."
diff --git a/html/changelogs/AutoChangeLog-pr-10643.yml b/html/changelogs/AutoChangeLog-pr-10643.yml
deleted file mode 100644
index 8fd496e0bc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10643.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "tip of the round: Cleanbot can withstand lava and burning hot ash. Its a god"
diff --git a/html/changelogs/AutoChangeLog-pr-10645.yml b/html/changelogs/AutoChangeLog-pr-10645.yml
deleted file mode 100644
index 16ef8b2056..0000000000
--- a/html/changelogs/AutoChangeLog-pr-10645.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "r4d6"
-delete-after: True
-changes:
- - rscadd: "Added the ability to easily add variations of the mining base"
diff --git a/html/changelogs/AutoChangeLog-pr-10706.yml b/html/changelogs/AutoChangeLog-pr-10706.yml
new file mode 100644
index 0000000000..8bf1cd449c
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10706.yml
@@ -0,0 +1,5 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Stopped the ellipsis question mark from being displayed twice in the examine message for masked/unknown human mobs."
+ - tweak: "Made the aforementioned ellipsis question mark display on flavor-text-less masked/unknown human mobs too for consistency."
diff --git a/html/changelogs/AutoChangeLog-pr-10307.yml b/html/changelogs/AutoChangeLog-pr-10709.yml
similarity index 50%
rename from html/changelogs/AutoChangeLog-pr-10307.yml
rename to html/changelogs/AutoChangeLog-pr-10709.yml
index 279dbe2840..8c9d74c5f1 100644
--- a/html/changelogs/AutoChangeLog-pr-10307.yml
+++ b/html/changelogs/AutoChangeLog-pr-10709.yml
@@ -1,4 +1,4 @@
author: "Seris02"
delete-after: True
changes:
- - rscadd: "stunglasses"
+ - rscadd: "recipe for mammal mutation toxin"
diff --git a/html/changelogs/AutoChangeLog-pr-10728.yml b/html/changelogs/AutoChangeLog-pr-10728.yml
new file mode 100644
index 0000000000..9023844565
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10728.yml
@@ -0,0 +1,4 @@
+author: "kevinz000"
+delete-after: True
+changes:
+ - balance: "meteor waves are now directional and announces the direction on the command report."
diff --git a/html/changelogs/AutoChangeLog-pr-10733.yml b/html/changelogs/AutoChangeLog-pr-10733.yml
new file mode 100644
index 0000000000..33e2ee216c
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10733.yml
@@ -0,0 +1,4 @@
+author: "Hatterhat"
+delete-after: True
+changes:
+ - balance: "Zombie powder is now instant when ingested, but delayed when injected or applied through touch."
diff --git a/html/changelogs/AutoChangeLog-pr-10737.yml b/html/changelogs/AutoChangeLog-pr-10737.yml
new file mode 100644
index 0000000000..fa4023c148
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10737.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Stopped an APTFT exploit with spray bottles."
diff --git a/html/changelogs/AutoChangeLog-pr-10742.yml b/html/changelogs/AutoChangeLog-pr-10742.yml
new file mode 100644
index 0000000000..ece862d112
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10742.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Fixed the detective revolver being quite risky to use."
diff --git a/html/changelogs/AutoChangeLog-pr-10743.yml b/html/changelogs/AutoChangeLog-pr-10743.yml
new file mode 100644
index 0000000000..d9775f7bc3
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10743.yml
@@ -0,0 +1,4 @@
+author: "necromanceranne"
+delete-after: True
+changes:
+ - rscdel: "You can no longer order spinfusors or their ammo from cargo."
diff --git a/html/changelogs/AutoChangeLog-pr-10317.yml b/html/changelogs/AutoChangeLog-pr-10748.yml
similarity index 52%
rename from html/changelogs/AutoChangeLog-pr-10317.yml
rename to html/changelogs/AutoChangeLog-pr-10748.yml
index 7db50240e3..a2afda81aa 100644
--- a/html/changelogs/AutoChangeLog-pr-10317.yml
+++ b/html/changelogs/AutoChangeLog-pr-10748.yml
@@ -1,4 +1,4 @@
author: "Trilbyspaceclone"
delete-after: True
changes:
- - bugfix: "issues with mapping done my Trilby"
+ - bugfix: "Vault hallway door being all access"
diff --git a/html/changelogs/AutoChangeLog-pr-10751.yml b/html/changelogs/AutoChangeLog-pr-10751.yml
new file mode 100644
index 0000000000..c5b54bd4ed
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10751.yml
@@ -0,0 +1,4 @@
+author: "kevinz000"
+delete-after: True
+changes:
+ - balance: "traitor+bro gamemode minimum population set to 25 until there can be more in depth configuration systems for gamemodes."
diff --git a/html/changelogs/AutoChangeLog-pr-10752.yml b/html/changelogs/AutoChangeLog-pr-10752.yml
new file mode 100644
index 0000000000..9bb50f1da1
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10752.yml
@@ -0,0 +1,9 @@
+author: "Owai-Seek"
+delete-after: True
+changes:
+ - rscadd: "Burger, Cargo Packaging, Dirty Magazine, Air Pump, and Scrubber crates."
+ - rscdel: "Duplicate Crate, Festive Wrapping Paper Crate, Contraband Monkey Meat Crate"
+ - tweak: "Gave Seed Crate Ambrosia Seed, gave Biker Gang Crate Spraypaint."
+ - tweak: "Organised some crates with sub-categories. Also, moved all vendor refills to a new tab."
+ - tweak: "Moved Grill to Service Tab"
+ - bugfix: "Engineering Hardsuit Access"
diff --git a/html/changelogs/AutoChangeLog-pr-10442.yml b/html/changelogs/AutoChangeLog-pr-10753.yml
similarity index 56%
rename from html/changelogs/AutoChangeLog-pr-10442.yml
rename to html/changelogs/AutoChangeLog-pr-10753.yml
index f407ae9e15..c1b3615c3d 100644
--- a/html/changelogs/AutoChangeLog-pr-10442.yml
+++ b/html/changelogs/AutoChangeLog-pr-10753.yml
@@ -1,4 +1,4 @@
author: "Trilbyspaceclone"
delete-after: True
changes:
- - tweak: "Halfs the nutriments in sugar"
+ - server: "Updates change logs"
diff --git a/html/changelogs/AutoChangeLog-pr-10754.yml b/html/changelogs/AutoChangeLog-pr-10754.yml
new file mode 100644
index 0000000000..0537347443
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10754.yml
@@ -0,0 +1,5 @@
+author: "MalricB"
+delete-after: True
+changes:
+ - rscadd: "\"Shaggy\" sprite from virgo"
+ - rscadd: "\"shaggy\" option in the character customization"
diff --git a/html/changelogs/AutoChangeLog-pr-10761.yml b/html/changelogs/AutoChangeLog-pr-10761.yml
new file mode 100644
index 0000000000..5a5b7281ef
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10761.yml
@@ -0,0 +1,4 @@
+author: "Putnam3145"
+delete-after: True
+changes:
+ - bugfix: "gender change potion now respects prefs"
diff --git a/html/changelogs/AutoChangeLog-pr-10764.yml b/html/changelogs/AutoChangeLog-pr-10764.yml
new file mode 100644
index 0000000000..25dfebd5fb
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10764.yml
@@ -0,0 +1,4 @@
+author: "deathride58"
+delete-after: True
+changes:
+ - bugfix: "Spacemen no longer run at lightspeed on local servers."
diff --git a/html/changelogs/AutoChangeLog-pr-10765.yml b/html/changelogs/AutoChangeLog-pr-10765.yml
new file mode 100644
index 0000000000..975a3ac5c5
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10765.yml
@@ -0,0 +1,4 @@
+author: "kevinz000"
+delete-after: True
+changes:
+ - bugfix: "no more bluespace skittish locker diving,"
diff --git a/html/changelogs/AutoChangeLog-pr-9601.yml b/html/changelogs/AutoChangeLog-pr-9601.yml
deleted file mode 100644
index c54279627f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9601.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-author: "Ghommie (original PRs by Kevinz000, ShivCalez, 4dplanner, Barhandar, 81Denton, zxaber, Fox-McCloud)"
-delete-after: True
-changes:
- - rscadd: "All atom movables now have move force and move resist, and pull force An atom can only pull another atom if its pull force is stronger than that atom's move resist"
- - rscadd: "Mobs with a higher move force than an atom's move resist will automatically try to force the atom out of its way. This might not always work, depending on how snowflakey code is.
-experimental: As of right now, everything has a move force and resist of 100, and a pull force of 101. Things take (resist - force) damage when bumped into
-experimental: Failing to move onto a tile will now still bump up your last move timer. However, successfully pushing something out of your way will result in you automatically moving into where it was."
- - bugfix: "Bolted AIs can no longer be teleported by launchpads."
- - balance: "Megafauna cannot teleport"
diff --git a/html/changelogs/AutoChangeLog-pr-9856.yml b/html/changelogs/AutoChangeLog-pr-9856.yml
deleted file mode 100644
index 697c1c78f5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9856.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - rscadd: "Refactored code to allow all living mobs to use shields and not only humans."
- - tweak: "Monkys will now retaliate against aliens attacking them (as if they even posed a threat to start with)."
diff --git a/html/changelogs/AutoChangeLog-pr-9878.yml b/html/changelogs/AutoChangeLog-pr-9878.yml
deleted file mode 100644
index ef9c704003..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9878.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - tweak: "add a click cooldown to the overly spammable table slamming."
diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi
index 772a263358..6e95eae960 100644
Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ
diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi
index 04e2e3cc75..b0ea63611d 100644
Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ
diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi
index 74a5164844..b13e06e824 100644
Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ
diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi
index 89f9a6fd93..901adb905d 100644
Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index c5a6914cf4..8c2abcd3b9 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/icons/obj/fireplace.dmi b/icons/obj/fireplace.dmi
index d1a157e009..df03958368 100644
Binary files a/icons/obj/fireplace.dmi and b/icons/obj/fireplace.dmi differ
diff --git a/icons/obj/glassworks.dmi b/icons/obj/glassworks.dmi
new file mode 100644
index 0000000000..de033f08d5
Binary files /dev/null and b/icons/obj/glassworks.dmi differ
diff --git a/icons/obj/radio.dmi b/icons/obj/radio.dmi
index 64642b8a6c..dbfc7b1f93 100644
Binary files a/icons/obj/radio.dmi and b/icons/obj/radio.dmi differ
diff --git a/icons/obj/recycling.dmi b/icons/obj/recycling.dmi
index 4e072c9006..9604d6b97e 100644
Binary files a/icons/obj/recycling.dmi and b/icons/obj/recycling.dmi differ
diff --git a/icons/turf/areas.dmi b/icons/turf/areas.dmi
index fe60cf6c0d..aad3e78590 100644
Binary files a/icons/turf/areas.dmi and b/icons/turf/areas.dmi differ
diff --git a/modular_citadel/code/_onclick/other_mobs.dm b/modular_citadel/code/_onclick/other_mobs.dm
index 51a5c6c5c3..6d9ffdd6ca 100644
--- a/modular_citadel/code/_onclick/other_mobs.dm
+++ b/modular_citadel/code/_onclick/other_mobs.dm
@@ -9,21 +9,43 @@
return TRUE
/mob/living/carbon/human/AltRangedAttack(atom/A, params)
+ if(isturf(A) || incapacitated()) // pretty annoying to wave your fist at floors and walls. And useless.
+ return TRUE
+ changeNext_move(CLICK_CD_RANGE)
+ var/list/target_viewers = viewers(11, A) //Byond proc, doesn't check for blindness.
+ if(!(src in target_viewers)) //click catcher issuing calls for out of view objects.
+ return TRUE
if(!has_active_hand())
to_chat(src, "You ponder your life choices and sigh.")
return TRUE
+ var/list/src_viewers = viewers(DEFAULT_MESSAGE_RANGE, src) - src // src has a different message.
+ var/the_action = "waves to [A]"
+ var/what_action = "waves to something you can't see"
+ var/self_action = "wave to [A]"
- if(!incapacitated())
- switch(a_intent)
- if(INTENT_HELP)
- visible_message("[src] waves to [A].", "You wave to [A].")
- if(INTENT_DISARM)
- visible_message("[src] shoos away [A].", "You shoo away [A].")
- if(INTENT_GRAB)
- visible_message("[src] beckons [A] to come.", "You beckon [A] to come.") //This sounds lewder than it actually is. Fuck.
- if(INTENT_HARM)
- visible_message("[src] shakes [p_their()] fist at [A].", "You shake your fist at [A].")
- return TRUE
+ switch(a_intent)
+ if(INTENT_DISARM)
+ the_action = "shoos away [A]"
+ what_action = "shoo away something you can't see"
+ self_action = "shoo away [A]"
+ if(INTENT_GRAB)
+ the_action = "beckons [A] to come"
+ what_action = "beckons something you can't see to come"
+ self_action = "beckon [A] to come"
+ if(INTENT_HARM)
+ var/pronoun = "[p_their()]"
+ the_action = "shakes [pronoun] fist at [A]"
+ what_action = "shakes [pronoun] fist at something you can't see"
+ self_action = "shake your fist at [A]"
+
+ if(!eye_blind)
+ to_chat(src, "You [self_action].")
+ for(var/B in src_viewers)
+ var/mob/M = B
+ if(!M.eye_blind)
+ var/message = (M in target_viewers) ? the_action : what_action
+ to_chat(M, "[src] [message].")
+ return TRUE
/atom/proc/alt_attack_hand(mob/user)
return FALSE
diff --git a/modular_citadel/code/modules/client/loadout/__donator.dm b/modular_citadel/code/modules/client/loadout/__donator.dm
index cf68666532..8b5e8f6522 100644
--- a/modular_citadel/code/modules/client/loadout/__donator.dm
+++ b/modular_citadel/code/modules/client/loadout/__donator.dm
@@ -305,7 +305,7 @@ datum/gear/darksabresheath
/datum/gear/flagcape
name = "US Flag Cape"
category = SLOT_IN_BACKPACK
- path = /obj/item/bedsheet/custom/flagcape
+ path = /obj/item/clothing/neck/flagcape
ckeywhitelist = list("darnchacha")
/datum/gear/luckyjack
diff --git a/modular_citadel/code/modules/client/loadout/backpack.dm b/modular_citadel/code/modules/client/loadout/backpack.dm
index 82fe89eb6e..48608e713e 100644
--- a/modular_citadel/code/modules/client/loadout/backpack.dm
+++ b/modular_citadel/code/modules/client/loadout/backpack.dm
@@ -115,4 +115,17 @@
name = "A fancy pen"
category = SLOT_IN_BACKPACK
path = /obj/item/pen/fountain
- cost = 2
\ No newline at end of file
+ cost = 2
+
+/datum/gear/modular_tablet
+ name = "A modular tablet"
+ category = SLOT_IN_BACKPACK
+ path = /obj/item/modular_computer/tablet/preset/cheap/
+ cost = 4
+
+/datum/gear/modular_laptop
+ name = "A modular laptop"
+ category = SLOT_IN_BACKPACK
+ path = /obj/item/modular_computer/laptop/preset/civilian
+ cost = 7
+
diff --git a/modular_citadel/code/modules/client/loadout/uniform.dm b/modular_citadel/code/modules/client/loadout/uniform.dm
index 46692ea7a9..b6b72669c2 100644
--- a/modular_citadel/code/modules/client/loadout/uniform.dm
+++ b/modular_citadel/code/modules/client/loadout/uniform.dm
@@ -424,3 +424,38 @@
path = /obj/item/clothing/under/stripper_green
cost = 3
+/datum/gear/qipao
+ name = "Qipao, Black"
+ category = SLOT_W_UNIFORM
+ path = /obj/item/clothing/under/lunar/qipao
+ cost = 3
+
+/datum/gear/qipao/white
+ name = "Qipao, White"
+ category = SLOT_W_UNIFORM
+ path = /obj/item/clothing/under/lunar/qipao/white
+ cost = 3
+
+/datum/gear/qipao/red
+ name = "Qipao, Red"
+ category = SLOT_W_UNIFORM
+ path = /obj/item/clothing/under/lunar/qipao/red
+ cost = 3
+
+/datum/gear/cheongsam
+ name = "Cheongsam, Black"
+ category = SLOT_W_UNIFORM
+ path = /obj/item/clothing/under/lunar/cheongsam
+ cost = 3
+
+/datum/gear/cheongsam/white
+ name = "Cheongsam, White"
+ category = SLOT_W_UNIFORM
+ path = /obj/item/clothing/under/lunar/cheongsam/white
+ cost = 3
+
+/datum/gear/cheongsam/red
+ name = "Cheongsam, Red"
+ category = SLOT_W_UNIFORM
+ path = /obj/item/clothing/under/lunar/cheongsam/red
+ cost = 3
\ No newline at end of file
diff --git a/modular_citadel/code/modules/custom_loadout/custom_items.dm b/modular_citadel/code/modules/custom_loadout/custom_items.dm
index eaf128626d..03a4a56147 100644
--- a/modular_citadel/code/modules/custom_loadout/custom_items.dm
+++ b/modular_citadel/code/modules/custom_loadout/custom_items.dm
@@ -364,10 +364,11 @@
worn_x_dimension = 64
worn_y_dimension = 34
-/obj/item/bedsheet/custom/flagcape
+/obj/item/clothing/neck/flagcape
name = "Flag Cape"
desc = "A truly patriotic form of heroic attire."
icon = 'icons/obj/custom.dmi'
+ resistance_flags = FLAMMABLE
alternate_worn_icon = 'icons/mob/custom_w.dmi'
icon_state = "flagcape"
item_state = "flagcape"
diff --git a/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm b/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm
index 0b6903c9fe..bd43d96ba4 100644
--- a/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm
@@ -12,8 +12,11 @@
/mob/living/carbon/human/movement_delay()
. = 0
- if(!resting && m_intent == MOVE_INTENT_RUN && !sprinting)
- . += 1
+ if(!resting && m_intent == MOVE_INTENT_RUN && sprinting)
+ var/static/datum/config_entry/number/movedelay/sprint_speed_increase/SSI
+ if(!SSI)
+ SSI = CONFIG_GET_ENTRY(number/movedelay/sprint_speed_increase)
+ . -= SSI.config_entry_value
if(wrongdirmovedelay)
. += 1
. += ..()
diff --git a/modular_citadel/code/modules/mob/living/living.dm b/modular_citadel/code/modules/mob/living/living.dm
index 513a80cae0..0caf548196 100644
--- a/modular_citadel/code/modules/mob/living/living.dm
+++ b/modular_citadel/code/modules/mob/living/living.dm
@@ -17,6 +17,12 @@
var/sprint_stamina_cost = 0.70 //stamina loss per tile while insufficient sprint buffer.
//---End
+/mob/living/update_config_movespeed()
+ . = ..()
+ sprint_buffer_max = CONFIG_GET(number/movedelay/sprint_buffer_max)
+ sprint_buffer_regen_ds = CONFIG_GET(number/movedelay/sprint_buffer_regen_per_ds)
+ sprint_stamina_cost = CONFIG_GET(number/movedelay/sprint_stamina_cost)
+
/mob/living/movement_delay(ignorewalk = 0)
. = ..()
if(resting)
diff --git a/modular_citadel/code/modules/projectiles/guns/ballistic/spinfusor.dm b/modular_citadel/code/modules/projectiles/guns/ballistic/spinfusor.dm
index 9e965ec7a7..3c0a47bfd7 100644
--- a/modular_citadel/code/modules/projectiles/guns/ballistic/spinfusor.dm
+++ b/modular_citadel/code/modules/projectiles/guns/ballistic/spinfusor.dm
@@ -65,18 +65,4 @@
icon_state = "spinfusorbox"
ammo_type = /obj/item/ammo_casing/caseless/spinfusor
w_class = WEIGHT_CLASS_NORMAL
- max_ammo = 4
-
-/datum/supply_pack/security/armory/spinfusor
- name = "Stormhammer Spinfusor Crate"
- cost = 14000
- contains = list(/obj/item/gun/ballistic/automatic/spinfusor,
- /obj/item/gun/ballistic/automatic/spinfusor)
- crate_name = "spinfusor crate"
-
-/datum/supply_pack/security/armory/spinfusorammo
- name = "Spinfusor Disk Crate"
- cost = 7000
- contains = list(/obj/item/ammo_box/aspinfusor,
- /obj/item/ammo_box/aspinfusor)
- crate_name = "spinfusor disk crate"
+ max_ammo = 4
\ No newline at end of file
diff --git a/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm b/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm
index 31e319edd3..63c0c01a58 100644
--- a/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm
+++ b/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm
@@ -200,8 +200,10 @@
FermiExplode = TRUE
PurityMin = 0.1
-/datum/chemical_reaction/fermi/breast_enlarger/FermiFinish(datum/reagents/holder, var/atom/my_atom)
+/datum/chemical_reaction/fermi/breast_enlarger/FermiFinish(datum/reagents/holder, atom/my_atom)
var/datum/reagent/fermi/breast_enlarger/BE = locate(/datum/reagent/fermi/breast_enlarger) in my_atom.reagents.reagent_list
+ if(!BE)
+ return
var/cached_volume = BE.volume
if(BE.purity < 0.35)
holder.remove_reagent(type, cached_volume)
@@ -249,8 +251,10 @@
P.length = ((PE.volume * PE.purity) / 10)//half as effective.
my_atom.reagents.clear_reagents()
-/datum/chemical_reaction/fermi/penis_enlarger/FermiFinish(datum/reagents/holder, var/atom/my_atom)
+/datum/chemical_reaction/fermi/penis_enlarger/FermiFinish(datum/reagents/holder, atom/my_atom)
var/datum/reagent/fermi/penis_enlarger/PE = locate(/datum/reagent/fermi/penis_enlarger) in my_atom.reagents.reagent_list
+ if(!PE)
+ return
var/cached_volume = PE.volume
if(PE.purity < 0.35)
holder.remove_reagent(type, cached_volume)
@@ -306,13 +310,11 @@
/datum/chemical_reaction/fermi/enthrall/FermiFinish(datum/reagents/holder, var/atom/my_atom)
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in my_atom.reagents.reagent_list
var/datum/reagent/fermi/enthrall/E = locate(/datum/reagent/fermi/enthrall) in my_atom.reagents.reagent_list
- if(!B)
+ if(!B || !E)
return
if(!B.data)
- var/list/seen = viewers(5, get_turf(my_atom))
- for(var/mob/M in seen)
- to_chat(M, "The reaction splutters and fails to react properly.") //Just in case
- E.purity = 0
+ my_atom.visible_message("The reaction splutters and fails to react properly.") //Just in case
+ E.purity = 0
if (B.data["gender"] == "female")
E.data["creatorGender"] = "Mistress"
E.creatorGender = "Mistress"
@@ -332,11 +334,11 @@
/datum/chemical_reaction/fermi/enthrall/slime/FermiFinish(datum/reagents/holder, var/atom/my_atom)
var/datum/reagent/blood/jellyblood/B = locate(/datum/reagent/blood/jellyblood) in my_atom.reagents.reagent_list//The one line change.
var/datum/reagent/fermi/enthrall/E = locate(/datum/reagent/fermi/enthrall) in my_atom.reagents.reagent_list
+ if(!B || !E)
+ return
if(!B.data)
- var/list/seen = viewers(5, get_turf(my_atom))
- for(var/mob/M in seen)
- to_chat(M, "The reaction splutters and fails to react.") //Just in case
- E.purity = 0
+ my_atom.visible_message("The reaction splutters and fails to react properly.") //Just in case
+ E.purity = 0
if (B.data["gender"] == "female")
E.data["creatorGender"] = "Mistress"
E.creatorGender = "Mistress"
@@ -466,9 +468,9 @@
/datum/chemical_reaction/fermi/acidic_buffer/FermiFinish(datum/reagents/holder, var/atom/my_atom) //might need this
- if(!locate(/datum/reagent/fermi/acidic_buffer) in my_atom.reagents.reagent_list)
- return
var/datum/reagent/fermi/acidic_buffer/Fa = locate(/datum/reagent/fermi/acidic_buffer) in my_atom.reagents.reagent_list
+ if(!Fa)
+ return
Fa.data = 0.1//setting it to 0 means byond thinks it's not there.
/datum/chemical_reaction/fermi/basic_buffer//done test
@@ -493,10 +495,10 @@
FermiChem = TRUE
-/datum/chemical_reaction/fermi/basic_buffer/FermiFinish(datum/reagents/holder, var/atom/my_atom) //might need this
- if(!locate(/datum/reagent/fermi/basic_buffer) in my_atom.reagents.reagent_list)
- return
+/datum/chemical_reaction/fermi/basic_buffer/FermiFinish(datum/reagents/holder, atom/my_atom) //might need this
var/datum/reagent/fermi/basic_buffer/Fb = locate(/datum/reagent/fermi/basic_buffer) in my_atom.reagents.reagent_list
+ if(!Fb)
+ return
Fb.data = 14
//secretcatchemcode, shh!! Of couse I hide it amongst cats. Though, I moved it with your requests.
diff --git a/tgstation.dme b/tgstation.dme
index 719275bcef..5a8549e27f 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -362,6 +362,7 @@
#include "code\datums\components\chasm.dm"
#include "code\datums\components\construction.dm"
#include "code\datums\components\decal.dm"
+#include "code\datums\components\dejavu.dm"
#include "code\datums\components\earprotection.dm"
#include "code\datums\components\edit_complainer.dm"
#include "code\datums\components\empprotection.dm"
@@ -474,6 +475,7 @@
#include "code\datums\elements\_element.dm"
#include "code\datums\elements\cleaning.dm"
#include "code\datums\elements\dusts_on_catatonia.dm"
+#include "code\datums\elements\dusts_on_leaving_area.dm"
#include "code\datums\elements\earhealing.dm"
#include "code\datums\elements\ghost_role_eligibility.dm"
#include "code\datums\elements\wuv.dm"
@@ -1227,7 +1229,9 @@
#include "code\modules\antagonists\_common\antag_spawner.dm"
#include "code\modules\antagonists\_common\antag_team.dm"
#include "code\modules\antagonists\abductor\abductor.dm"
+#include "code\modules\antagonists\abductor\abductee\abductee.dm"
#include "code\modules\antagonists\abductor\abductee\abductee_objectives.dm"
+#include "code\modules\antagonists\abductor\abductee\trauma.dm"
#include "code\modules\antagonists\abductor\equipment\abduction_gear.dm"
#include "code\modules\antagonists\abductor\equipment\abduction_outfits.dm"
#include "code\modules\antagonists\abductor\equipment\abduction_surgery.dm"
@@ -1599,6 +1603,7 @@
#include "code\modules\cargo\packs\science.dm"
#include "code\modules\cargo\packs\security.dm"
#include "code\modules\cargo\packs\service.dm"
+#include "code\modules\cargo\packs\vending.dm"
#include "code\modules\chatter\chatter.dm"
#include "code\modules\client\asset_cache.dm"
#include "code\modules\client\client_colour.dm"
@@ -1702,6 +1707,7 @@
#include "code\modules\clothing\under\jobs\Plasmaman\medsci.dm"
#include "code\modules\clothing\under\jobs\Plasmaman\security.dm"
#include "code\modules\crafting\craft.dm"
+#include "code\modules\crafting\glassware.dm"
#include "code\modules\crafting\guncrafting.dm"
#include "code\modules\crafting\recipes.dm"
#include "code\modules\crafting\recipes\recipes_clothing.dm"