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. [![forthebadge](http://forthebadge.com/images/badges/60-percent-of-the-time-works-every-time.svg)](https://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/pretty-risque.svg)](https://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/you-didnt-ask-for-this.svg)](http://forthebadge.com) @@ -10,18 +9,19 @@ Based and maintained from /tg/station.
[![Percentage of issues still open](http://isitmaintained.com/badge/open/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Percentage of issues still open") [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/Citadel-Station-13/Citadel-Station-13.svg)](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..d41fbc69e1 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" @@ -58002,10 +58026,10 @@ }, /obj/item/clothing/head/russobluecamohat, /obj/item/clothing/head/russobluecamohat, -/obj/item/clothing/head/russofurhat, -/obj/item/clothing/head/russofurhat, -/obj/item/clothing/head/russofurhat, -/obj/item/clothing/head/russofurhat, +/obj/item/clothing/head/helmet/rus_ushanka, +/obj/item/clothing/head/helmet/rus_ushanka, +/obj/item/clothing/head/helmet/rus_ushanka, +/obj/item/clothing/head/helmet/rus_ushanka, /obj/item/clothing/under/mw2_russian_para, /obj/item/clothing/under/mw2_russian_para, /obj/item/clothing/under/mw2_russian_para, @@ -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/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index a0467cde6c..905b2cdb1b 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -506,6 +506,7 @@ "bx" = ( /obj/structure/table, /obj/machinery/readybutton, +/obj/item/storage/lockbox/dueling/hugbox/stamina, /turf/open/floor/holofloor/basalt, /area/holodeck/rec_center/thunderdome) "by" = ( @@ -522,6 +523,7 @@ /area/holodeck/rec_center/thunderdome) "bA" = ( /obj/machinery/readybutton, +/obj/item/storage/lockbox/dueling/hugbox/stamina, /obj/effect/turf_decal/tile/red{ dir = 1 }, 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/admin.dm b/code/__DEFINES/admin.dm index 3acd1443af..c6be8318fd 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -87,5 +87,5 @@ #define MAX_KEYPRESS_COMMANDLENGTH 16 ///Max amount of keypress messages per second over two seconds before client is autokicked #define MAX_KEYPRESS_AUTOKICK 100 -///Length of held key rolling buffer -#define HELD_KEY_BUFFER_LENGTH 15 +///Length of max held keys +#define MAX_HELD_KEYS 15 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/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/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index 41dfce6261..db8f4a1d0d 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 012a7fa02f..b803a328a5 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 f9b9927e72..ba75fbfc9c 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/air.dm b/code/controllers/subsystem/air.dm index 2a59558bcd..52d2fe45cd 100644 --- a/code/controllers/subsystem/air.dm +++ b/code/controllers/subsystem/air.dm @@ -239,7 +239,6 @@ SUBSYSTEM_DEF(air) if (MC_TICK_CHECK) return - /datum/controller/subsystem/air/proc/remove_from_active(turf/open/T) active_turfs -= T SSair_turfs.currentrun -= T @@ -257,7 +256,7 @@ SUBSYSTEM_DEF(air) #ifdef VISUALIZE_ACTIVE_TURFS T.add_atom_colour("#00ff00", TEMPORARY_COLOUR_PRIORITY) #endif - T.excited = 1 + T.excited = TRUE active_turfs |= T SSair_turfs.currentrun |= T if(blockchanges && T.excited_group) diff --git a/code/controllers/subsystem/air_turfs.dm b/code/controllers/subsystem/air_turfs.dm index 2902940bf9..9dd41aede5 100644 --- a/code/controllers/subsystem/air_turfs.dm +++ b/code/controllers/subsystem/air_turfs.dm @@ -11,7 +11,6 @@ SUBSYSTEM_DEF(air_turfs) /datum/controller/subsystem/air_turfs/fire(resumed = 0) var/fire_count = times_fired - //cache for sanic speed if (!resumed) src.currentrun = SSair.active_turfs.Copy() //cache for sanic speed (lists are references anyways) diff --git a/code/controllers/subsystem/fail2topic.dm b/code/controllers/subsystem/fail2topic.dm index a589ae2462..b358cc2c5f 100644 --- a/code/controllers/subsystem/fail2topic.dm +++ b/code/controllers/subsystem/fail2topic.dm @@ -31,10 +31,9 @@ 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) rate_limiting -= ip fail_counts -= ip diff --git a/code/controllers/subsystem/input.dm b/code/controllers/subsystem/input.dm index cc09ca816e..0970b23a16 100644 --- a/code/controllers/subsystem/input.dm +++ b/code/controllers/subsystem/input.dm @@ -114,6 +114,6 @@ SUBSYSTEM_DEF(input) /datum/controller/subsystem/input/fire() var/list/clients = GLOB.clients // Let's sing the list cache song - for(var/i in 1 to clients.len) + for(var/i in 1 to length(clients)) var/client/C = clients[i] C.keyLoop() diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 8c8ad2d337..4850a67646 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -37,6 +37,8 @@ SUBSYSTEM_DEF(mapping) var/datum/space_level/empty_space var/num_of_res_levels = 1 + var/stat_map_name = "Loading..." + //dlete dis once #39770 is resolved /datum/controller/subsystem/mapping/proc/HACK_LoadMapConfig() if(!config) @@ -45,6 +47,7 @@ SUBSYSTEM_DEF(mapping) #else config = load_map_config(error_if_missing = FALSE) #endif + stat_map_name = config.map_name /datum/controller/subsystem/mapping/Initialize(timeofday) HACK_LoadMapConfig() @@ -330,7 +333,10 @@ GLOBAL_LIST_EMPTY(the_station_areas) return next_map_config = VM - return TRUE + + . = TRUE + + stat_map_name = "[config.map_name] (Next: [next_map_config.map_name])" /datum/controller/subsystem/mapping/proc/preloadTemplates(path = "_maps/templates/") //see master controller setup var/list/filelist = flist(path) diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index b406a8ccad..4d9eefae5b 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -30,6 +30,7 @@ SUBSYSTEM_DEF(shuttle) var/list/hostileEnvironments = list() //Things blocking escape shuttle from leaving var/list/tradeBlockade = list() //Things blocking cargo from leaving. var/supplyBlocked = FALSE + var/emergency_shuttle_stat_text //supply shuttle stuff var/obj/docking_port/mobile/supply/supply @@ -118,6 +119,9 @@ SUBSYSTEM_DEF(shuttle) points += point_gain //Cargo stuff end + var/esETA = emergency?.getModeStr() + emergency_shuttle_stat_text = "[esETA? "[esETA] [emergency.getTimerStr()]" : ""]" + if(!SSmapping.clearing_reserved_turfs) while(transit_requesters.len) var/requester = popleft(transit_requesters) diff --git a/code/controllers/subsystem/time_track.dm b/code/controllers/subsystem/time_track.dm index 3b19ae31cd..779b186d08 100644 --- a/code/controllers/subsystem/time_track.dm +++ b/code/controllers/subsystem/time_track.dm @@ -1,6 +1,6 @@ SUBSYSTEM_DEF(time_track) name = "Time Tracking" - wait = 600 + wait = 1 SECONDS flags = SS_NO_INIT|SS_NO_TICK_CHECK runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT @@ -16,23 +16,33 @@ SUBSYSTEM_DEF(time_track) var/last_tick_byond_time = 0 var/last_tick_tickcount = 0 + var/last_measurement = 0 + var/measurement_delay = 60 + + var/stat_time_text + var/time_dilation_text + /datum/controller/subsystem/time_track/fire() + stat_time_text = "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]\n\nRound Time: [WORLDTIME2TEXT("hh:mm:ss")]\n\nStation Time: [STATION_TIME_TIMESTAMP("hh:mm:ss")]\n\n[time_dilation_text]" - var/current_realtime = REALTIMEOFDAY - var/current_byondtime = world.time - var/current_tickcount = world.time/world.tick_lag + if(++last_measurement == measurement_delay) + last_measurement = 0 + var/current_realtime = REALTIMEOFDAY + var/current_byondtime = world.time + var/current_tickcount = world.time/world.tick_lag - if (!first_run) - var/tick_drift = max(0, (((current_realtime - last_tick_realtime) - (current_byondtime - last_tick_byond_time)) / world.tick_lag)) + if (!first_run) + var/tick_drift = max(0, (((current_realtime - last_tick_realtime) - (current_byondtime - last_tick_byond_time)) / world.tick_lag)) - time_dilation_current = tick_drift / (current_tickcount - last_tick_tickcount) * 100 + time_dilation_current = tick_drift / (current_tickcount - last_tick_tickcount) * 100 - time_dilation_avg_fast = MC_AVERAGE_FAST(time_dilation_avg_fast, time_dilation_current) - time_dilation_avg = MC_AVERAGE(time_dilation_avg, time_dilation_avg_fast) - time_dilation_avg_slow = MC_AVERAGE_SLOW(time_dilation_avg_slow, time_dilation_avg) - else - first_run = FALSE - last_tick_realtime = current_realtime - last_tick_byond_time = current_byondtime - last_tick_tickcount = current_tickcount - SSblackbox.record_feedback("associative", "time_dilation_current", 1, list("[SQLtime()]" = list("current" = "[time_dilation_current]", "avg_fast" = "[time_dilation_avg_fast]", "avg" = "[time_dilation_avg]", "avg_slow" = "[time_dilation_avg_slow]"))) + time_dilation_avg_fast = MC_AVERAGE_FAST(time_dilation_avg_fast, time_dilation_current) + time_dilation_avg = MC_AVERAGE(time_dilation_avg, time_dilation_avg_fast) + time_dilation_avg_slow = MC_AVERAGE_SLOW(time_dilation_avg_slow, time_dilation_avg) + else + first_run = FALSE + last_tick_realtime = current_realtime + last_tick_byond_time = current_byondtime + last_tick_tickcount = current_tickcount + SSblackbox.record_feedback("associative", "time_dilation_current", 1, list("[SQLtime()]" = list("current" = "[time_dilation_current]", "avg_fast" = "[time_dilation_avg_fast]", "avg" = "[time_dilation_avg]", "avg_slow" = "[time_dilation_avg_slow]"))) + time_dilation_text = "Time Dilation: [round(time_dilation_current,1)]% AVG:([round(time_dilation_avg_fast,1)]%, [round(time_dilation_avg,1)]%, [round(time_dilation_avg_slow,1)]%)" 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/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 134bdfc814..5ca4a095d9 100644 --- a/code/datums/diseases/advance/symptoms/choking.dm +++ b/code/datums/diseases/advance/symptoms/choking.dm @@ -43,7 +43,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) @@ -116,7 +116,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 ef318d7da3..cf15ec407a 100644 --- a/code/datums/diseases/advance/symptoms/cough.dm +++ b/code/datums/diseases/advance/symptoms/cough.dm @@ -51,7 +51,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 5655cbc9c7..439f391fe4 100644 --- a/code/datums/diseases/advance/symptoms/sneeze.dm +++ b/code/datums/diseases/advance/symptoms/sneeze.dm @@ -41,7 +41,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/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/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..4dba8dae93 100644 --- a/code/game/gamemodes/gangs/gang_items.dm +++ b/code/game/gamemodes/gangs/gang_items.dm @@ -290,12 +290,6 @@ datum/gang_item/clothing/shades //Addition: Why not have cool shades on a gang m cost = 5 item_path = /obj/item/grenade/syndieminibomb/concussion/frag -/datum/gang_item/equipment/stimpack - name = "Black Market Stimulants" - id = "stimpack" - cost = 12 - item_path = /obj/item/reagent_containers/syringe/stimulants - /datum/gang_item/equipment/implant_breaker name = "Implant Breaker" id = "implant_breaker" @@ -401,7 +395,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/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/machinery/telecomms/computers/message.dm b/code/game/machinery/telecomms/computers/message.dm index 07028ba2d3..884c2bb37d 100644 --- a/code/game/machinery/telecomms/computers/message.dm +++ b/code/game/machinery/telecomms/computers/message.dm @@ -421,7 +421,7 @@ "name" = "[customsender]", "job" = "[customjob]", "message" = custommessage, - "emoji_message" = emoji_parse(custommessage), + "emojis" = TRUE, "targets" = list("[customrecepient.owner] ([customrecepient.ownjob])") )) // this will log the signal and transmit it to the target diff --git a/code/game/machinery/telecomms/machines/message_server.dm b/code/game/machinery/telecomms/machines/message_server.dm index 0cf356ad3d..1960080856 100644 --- a/code/game/machinery/telecomms/machines/message_server.dm +++ b/code/game/machinery/telecomms/machines/message_server.dm @@ -106,11 +106,10 @@ return "Everyone" return data["targets"][1] -/datum/signal/subspace/pda/proc/format_message(emojify = FALSE) - var/message = emojify ? data["emoji_message"] : data["message"] +/datum/signal/subspace/pda/proc/format_message() if (logged && data["photo"]) - return "\"[message]\" (Photo)" - return "\"[message]\"" + return "\"[data["message"]]\" (Photo)" + return "\"[data["message"]]\"" /datum/signal/subspace/pda/broadcast() if (!logged) // Can only go through if a message server logs it 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/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..abab4af770 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) @@ -77,6 +76,7 @@ GLOBAL_LIST_EMPTY(PDAs) var/hidden = FALSE // Is the PDA hidden from the PDA list? var/emped = FALSE var/equipped = FALSE //used here to determine if this is the first time its been picked up + var/allow_emojis = TRUE //if the pda can send emojis and actually have them parsed as such var/obj/item/card/id/id = null //Making it possible to slot an ID card into the PDA so it can function as both. var/ownjob = null //related to above @@ -255,10 +255,14 @@ GLOBAL_LIST_EMPTY(PDAs) var/datum/asset/spritesheet/assets = get_asset_datum(/datum/asset/spritesheet/simple/pda) assets.send(user) + var/datum/asset/spritesheet/emoji_s = get_asset_datum(/datum/asset/spritesheet/goonchat) + emoji_s.send(user) //Already sent by chat but no harm doing this + user.set_machine(src) var/dat = "Personal Data Assistant" dat += assets.css_tag() + dat += emoji_s.css_tag() dat += "[PDAIMG(refresh)]Refresh" @@ -338,6 +342,8 @@ GLOBAL_LIST_EMPTY(PDAs) dat += "
  • [PDAIMG(medbot)]Bots Access
  • " if (cartridge.access & CART_JANITOR) dat += "
  • [PDAIMG(bucket)]Custodial Locator
  • " + if(cartridge.access & CART_MIME) + dat += "
  • [PDAIMG(emoji)]Emoji Guidebook
  • " if (istype(cartridge.radio)) dat += "
  • [PDAIMG(signaler)]Signaler System
  • " if (cartridge.access & CART_NEWSCASTER) @@ -753,7 +759,6 @@ GLOBAL_LIST_EMPTY(PDAs) return if((last_text && world.time < last_text + 10) || (everyone && last_everyone && world.time < last_everyone + PDA_SPAM_DELAY)) return - var/emoji_message = emoji_parse(message) if(prob(1)) message += "\nSent from my PDA" // Send the signal @@ -782,7 +787,7 @@ GLOBAL_LIST_EMPTY(PDAs) "job" = "[ownjob]", "message" = message, "targets" = string_targets, - "emoji_message" = emoji_message + "emojis" = allow_emojis )) if (picture) signal.data["photo"] = picture @@ -796,15 +801,18 @@ GLOBAL_LIST_EMPTY(PDAs) playsound(src, 'sound/machines/terminal_error.ogg', 15, 1) var/target_text = signal.format_target() + if(allow_emojis) + message = emoji_parse(message)//already sent- this just shows the sent emoji as one to the sender in the to_chat + signal.data["message"] = emoji_parse(signal.data["message"]) // Log it in our logs tnote += "→ To [target_text]:
    [signal.format_message()]
    " // Show it to ghosts - var/ghost_message = "[owner] PDA Message --> [target_text]: [signal.format_message(TRUE)]" + var/ghost_message = "[owner] PDA Message --> [target_text]: [signal.format_message()]" for(var/i in GLOB.dead_mob_list) var/mob/M = i if(M?.client && M.client.prefs.chat_toggles & CHAT_GHOSTPDA) to_chat(M, "[FOLLOW_LINK(M, user)] [ghost_message]") - to_chat(user, "Message sent to [target_text]: \"[emoji_message]\"") + to_chat(user, "Message sent to [target_text]: \"[message]\"") // Log in the talk log user.log_talk(message, LOG_PDA, tag="PDA: [initial(name)] to [target_text] (BLOCKED:[string_blocked])") if (!silent) @@ -835,7 +843,11 @@ GLOBAL_LIST_EMPTY(PDAs) hrefstart = "" hrefend = "" - to_chat(L, "[icon2html(src)] Message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], [signal.format_message(TRUE)] (Reply) (BLOCK/UNBLOCK)") + var/inbound_message = signal.format_message() + if(signal.data["emojis"] == TRUE)//so will not parse emojis as such from pdas that don't send emojis + inbound_message = emoji_parse(inbound_message) + + to_chat(L, "[icon2html(src)] Message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], [inbound_message] (Reply) (BLOCK/UNBLOCK)") update_icon(TRUE) diff --git a/code/game/objects/items/devices/PDA/PDA_types.dm b/code/game/objects/items/devices/PDA/PDA_types.dm index 2da47d481e..b604bec258 100644 --- a/code/game/objects/items/devices/PDA/PDA_types.dm +++ b/code/game/objects/items/devices/PDA/PDA_types.dm @@ -19,6 +19,26 @@ if(istype(cart) && cart.charges < 5) cart.charges++ +//Mime PDA sends "silent" messages. +/obj/item/pda/mime + name = "mime PDA" + default_cartridge = /obj/item/cartridge/virus/mime + inserted_item = /obj/item/toy/crayon/mime + icon_state = "pda-mime" + desc = "A portable microcomputer by Thinktronic Systems, LTD. The hardware has been modified for compliance with the vows of silence." + silent = TRUE + ttone = "silence" + +/obj/item/pda/mime/msg_input(mob/living/U = usr) + if(emped || toff) + return + var/emojis = emoji_sanitize(stripped_input(U, "Please enter emojis", name)) + if(!emojis) + return + if(!U.canUseTopic(src, BE_CLOSE)) + return + return emojis + // Special AI/pAI PDAs that cannot explode. /obj/item/pda/ai icon = null @@ -79,14 +99,6 @@ icon_state = "pda-science" ttone = "boom" -/obj/item/pda/mime - name = "mime PDA" - default_cartridge = /obj/item/cartridge/virus/mime - inserted_item = /obj/item/toy/crayon/mime - icon_state = "pda-mime" - silent = TRUE - ttone = "silence" - /obj/item/pda/heads default_cartridge = /obj/item/cartridge/head icon_state = "pda-hop" diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index e4fa241907..5fb97ef17f 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"]]
    " @@ -579,6 +579,22 @@ Code: if (54) // Beepsky, Medibot, Floorbot, and Cleanbot access menu = "

    [PDAIMG(medbot)] Bots Interlink

    " bot_control() + if (55) // Emoji Guidebook for mimes + menu = "

    [PDAIMG(emoji)] Emoji Guidebook

    " + var/static/list/emoji_icon_states + var/static/emoji_table + if(!emoji_table) + var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/goonchat) + var/list/collate = list("
    ") + for(var/emoji in sortList(icon_states(icon('icons/emoji.dmi')))) + var/tag = sheet.icon_tag("emoji-[emoji]") + collate += "" + collate += "
    [emoji][tag]

    " + emoji_table = collate.Join() + + menu += "
    To use an emoji in a pda message, refer to the guide and add \":\" around the emoji. Your PDA supports the following emoji:
    " + menu += emoji_table + if (99) //Newscaster message permission error menu = "
    ERROR : NOT AUTHORIZED [host_pda.id ? "" : "- ID SLOT EMPTY"]
    " @@ -679,6 +695,11 @@ Code: return playsound(src, 'sound/machines/terminal_select.ogg', 50, 1) + //emoji previews + if(href_list["emoji"]) + var/parse = emoji_parse(":[href_list["emoji"]]:") + to_chat(usr, parse) + //Bot control section! Viciously ripped from radios for being laggy and terrible. if(href_list["op"]) switch(href_list["op"]) 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/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index e958345d4f..31dd6d32a3 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -309,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 */ 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 7690320159..e9d9e4ce77 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -637,7 +637,7 @@ short_desc = "You are a Ghost Cafe Visitor!" flavour_text = "You know one thing for sure. You arent actually alive. Are you in a simulation?" skip_reentry_check = TRUE - banType = "ghostcafe" + banType = ROLE_GHOSTCAFE /datum/action/toggle_dead_chat_mob icon_icon = 'icons/mob/mob.dmi' @@ -660,12 +660,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 3c067a5038..8e18f2ea51 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -117,6 +117,7 @@ GLOBAL_LIST(topic_status_cache) GLOB.world_job_debug_log = "[GLOB.log_directory]/job_debug.log" GLOB.tgui_log = "[GLOB.log_directory]/tgui.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" @@ -135,6 +136,7 @@ GLOBAL_LIST(topic_status_cache) start_log(GLOB.world_job_debug_log) start_log(GLOB.tgui_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 e6af9fa487..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) 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 0371c0ebdf..7680d61034 100644 --- a/code/modules/antagonists/swarmer/swarmer.dm +++ b/code/modules/antagonists/swarmer/swarmer.dm @@ -275,7 +275,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/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 aa1f59ef69..f7c5dce30f 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,8 +386,10 @@ send_signal(device_id, list("checks" = text2num(params["val"])^2), usr) . = TRUE if("set_external_pressure", "set_internal_pressure") + var/target = params["value"] if(!isnull(target)) + send_signal(device_id, list("[action]" = target), usr) . = TRUE if("reset_external_pressure") @@ -419,12 +421,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 @@ -455,7 +457,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) @@ -506,7 +508,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) @@ -644,7 +646,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) @@ -714,7 +716,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) @@ -727,7 +729,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..ce4aba6ab7 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm @@ -1,6 +1,7 @@ //3-Way Manifold /obj/machinery/atmospherics/pipe/heat_exchanging/manifold - icon_state = "manifold" + icon = 'icons/obj/atmospherics/pipes/he-manifold.dmi' + icon_state = "manifold-2" name = "pipe manifold" desc = "A manifold composed of regular pipes." @@ -15,7 +16,7 @@ var/mutable_appearance/center -/obj/machinery/atmospherics/pipe/manifold/Initialize() +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/Initialize() icon_state = "" center = mutable_appearance(icon, "manifold_center") return ..() diff --git a/code/modules/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm index bd4e716357..3562350473 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 @@ -267,6 +264,8 @@ M.key = new_team_member.key M.faction += team M.equipOutfit(ctf_gear) + M.dna.species.punchdamagehigh = 25 + M.dna.species.punchdamagelow = 25 spawned_mobs += M /obj/machinery/capture_the_flag/Topic(href, href_list) @@ -371,6 +370,10 @@ CTF.ctf_gear = initial(ctf_gear) CTF.respawn_cooldown = DEFAULT_RESPAWN +/proc/ctf_floor_vanish(atom/target) + if(isturf(target.loc)) + qdel(target) + /obj/item/gun/ballistic/automatic/pistol/deagle/ctf desc = "This looks like it could really hurt in melee." force = 75 @@ -378,11 +381,7 @@ /obj/item/gun/ballistic/automatic/pistol/deagle/ctf/dropped() . = ..() - addtimer(CALLBACK(src, .proc/floor_vanish), 1) - -/obj/item/gun/ballistic/automatic/pistol/deagle/ctf/proc/floor_vanish() - if(isturf(loc)) - qdel(src) + addtimer(CALLBACK(GLOBAL_PROC, /proc/ctf_floor_vanish, src), 1) /obj/item/ammo_box/magazine/m50/ctf ammo_type = /obj/item/ammo_casing/a50/ctf @@ -405,22 +404,14 @@ /obj/item/gun/ballistic/automatic/laser/ctf/dropped() . = ..() - addtimer(CALLBACK(src, .proc/floor_vanish), 1) - -/obj/item/gun/ballistic/automatic/laser/ctf/proc/floor_vanish() - if(isturf(loc)) - qdel(src) + addtimer(CALLBACK(GLOBAL_PROC, /proc/ctf_floor_vanish, src), 1) /obj/item/ammo_box/magazine/recharge/ctf ammo_type = /obj/item/ammo_casing/caseless/laser/ctf /obj/item/ammo_box/magazine/recharge/ctf/dropped() . = ..() - addtimer(CALLBACK(src, .proc/floor_vanish), 1) - -/obj/item/ammo_box/magazine/recharge/ctf/proc/floor_vanish() - if(isturf(loc)) - qdel(src) + addtimer(CALLBACK(GLOBAL_PROC, /proc/ctf_floor_vanish, src), 1) /obj/item/ammo_casing/caseless/laser/ctf projectile_type = /obj/item/projectile/beam/ctf @@ -438,9 +429,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 @@ -473,6 +464,19 @@ icon_state = "bluelaser" impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser +// MELEE GANG +/obj/item/claymore/ctf + slot_flags = SLOT_BACK + +/obj/item/claymore/ctf/pre_attack(atom/target, mob/user, params) + if(!is_ctf_target(target)) + return FALSE + return ..() + +/obj/item/claymore/ctf/dropped() + . = ..() + addtimer(CALLBACK(GLOBAL_PROC, /proc/ctf_floor_vanish, src), 1) + /datum/outfit/ctf name = "CTF" ears = /obj/item/radio/headset @@ -486,6 +490,7 @@ l_pocket = /obj/item/ammo_box/magazine/recharge/ctf r_pocket = /obj/item/ammo_box/magazine/recharge/ctf r_hand = /obj/item/gun/ballistic/automatic/laser/ctf + back = /obj/item/claymore/ctf /datum/outfit/ctf/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source) if(visualsOnly) diff --git a/code/modules/cargo/exports/gear.dm b/code/modules/cargo/exports/gear.dm index 77b57466d9..d15fc18b6e 100644 --- a/code/modules/cargo/exports/gear.dm +++ b/code/modules/cargo/exports/gear.dm @@ -229,12 +229,12 @@ /datum/export/gear/magboots cost = 50 unit_name = "magboots" - export_types = list(/obj/item/clothing/shoes/magboots, /obj/item/clothing/shoes/magboots/atmos) + export_types = list(/obj/item/clothing/shoes/magboots) /datum/export/gear/nosellboots cost = -5000 //We DONT want scew antags unit_name = "error shipment stolen" - export_types = list(/obj/item/clothing/shoes/magboots/advance, /obj/item/clothing/shoes/magboots/deathsquad) + export_types = list(/obj/item/clothing/shoes/magboots/advance) /datum/export/gear/syndamagboots cost = 250 @@ -279,7 +279,7 @@ /datum/export/gear/magicboots //Magic as in Antag - Wiz/Cults cost = 450 unit_name = "magic shoes" - export_types = list(/obj/item/clothing/shoes/sandal/marisa, /obj/item/clothing/shoes/sandal/magic, /obj/item/clothing/shoes/cult, /obj/item/clothing/shoes/clockwork, /obj/item/clothing/shoes/clown_shoes/taeclowndo, /obj/item/clothing/shoes/sandal/slippers) + export_types = list(/obj/item/clothing/shoes/sandal/marisa, /obj/item/clothing/shoes/sandal/magic, /obj/item/clothing/shoes/cult, /obj/item/clothing/shoes/clockwork, /obj/item/clothing/shoes/clown_shoes/taeclowndo) include_subtypes = TRUE //Headsets/Ears @@ -585,8 +585,7 @@ datum/export/gear/glasses //glasses are not worth selling export_types = list(/obj/item/clothing/under/scratch, /obj/item/clothing/under/sl_suit, /obj/item/clothing/under/rank/vice, /obj/item/clothing/under/suit_jacket, \ /obj/item/clothing/under/burial, /obj/item/clothing/under/skirt/black, /obj/item/clothing/under/captainparade, /obj/item/clothing/under/hosparademale, \ /obj/item/clothing/under/hosparadefem, /obj/item/clothing/under/assistantformal, /obj/item/clothing/under/stripeddress, /obj/item/clothing/under/redeveninggown, \ - /obj/item/clothing/under/plaid_skirt, /obj/item/clothing/under/geisha, /obj/item/clothing/under/trek, /obj/item/clothing/under/wedding, /obj/item/clothing/under/aviatoruniform,\ - /obj/item/clothing/under/mega, /obj/item/clothing/under/cia, /obj/item/clothing/under/casualwear, /obj/item/clothing/under/rank) + /obj/item/clothing/under/plaid_skirt, /obj/item/clothing/under/geisha, /obj/item/clothing/under/trek, /obj/item/clothing/under/rank) include_subtypes = TRUE /datum/export/gear/armored_jumpsuit diff --git a/code/modules/cargo/packs/armory.dm b/code/modules/cargo/packs/armory.dm index 372824c8e4..ea8ef8ba0f 100644 --- a/code/modules/cargo/packs/armory.dm +++ b/code/modules/cargo/packs/armory.dm @@ -201,22 +201,6 @@ var/item = pick(contains) new item(C) -/datum/supply_pack/security/armory/spinfusor - name = "Stormhammer Spinfusor Crate" - cost = 14000 - desc = "Got yourself a code red? Blob, nukies or even worst knocking on your door? Well with the Stormhammer Spinfusor you can stop crime in one shot, dont miss! Contains two Stormhammer Spinfusors (Note, guns may or may not be loaded). Requires Armory access to open." - 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 - desc = "Need more ammo for a Stormhammer? Well we got some for a price! Contains two boxes of Spinfusor disks. Requires Armory access to open." - contains = list(/obj/item/ammo_box/aspinfusor, - /obj/item/ammo_box/aspinfusor) - crate_name = "spinfusor disk crate" - /datum/supply_pack/security/armory/swat name = "SWAT Crate" desc = "Contains two fullbody sets of tough, fireproof, pressurized suits designed in a joint effort by IS-ERI and Nanotrasen. Each set contains a suit, helmet, mask, combat belt, and combat gloves. Requires Armory access to open." diff --git a/code/modules/cargo/packs/costumes_toys.dm b/code/modules/cargo/packs/costumes_toys.dm index f41a43070d..4a64979502 100644 --- a/code/modules/cargo/packs/costumes_toys.dm +++ b/code/modules/cargo/packs/costumes_toys.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. ////////////////////////////////////////////////////////////////////////////// -//////////////////////////// Costumes & Toys ///////////////////////////////// +////////////////////////////////// Toys ////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// /datum/supply_pack/costumes_toys @@ -98,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?" @@ -173,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." @@ -284,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." @@ -294,76 +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/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/medical.dm b/code/modules/cargo/packs/medical.dm index d4fcdab962..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." @@ -140,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" @@ -182,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!" @@ -195,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" @@ -255,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 898f82c6ce..deac656109 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!" @@ -214,10 +204,70 @@ for(var/i in 1 to 9) new /obj/item/coin/silver(.) +/datum/supply_pack/misc/dueling_stam + name = "Dueling Pistols" + desc = "Resolve all your quarrels with some nonlethal fun." + cost = 2000 + contains = list(/obj/item/storage/lockbox/dueling/hugbox/stamina, + /obj/item/storage/lockbox/dueling/hugbox/stamina, + /obj/item/storage/lockbox/dueling/hugbox/stamina, + /obj/item/storage/lockbox/dueling/hugbox/stamina, + /obj/item/storage/lockbox/dueling/hugbox/stamina) + crate_name = "dueling pistols" + +/datum/supply_pack/misc/dueling_lethal + name = "Lethal Dueling Pistols" + desc = "Settle your differences the true spaceman way." + cost = 3000 + contraband = TRUE + contains = list(/obj/item/storage/lockbox/dueling/hugbox, + /obj/item/storage/lockbox/dueling/hugbox, + /obj/item/storage/lockbox/dueling/hugbox) + crate_name = "dueling pistols (lethal)" + +/datum/supply_pack/misc/dueling_death + name = "Elimination Dueling Pistols" + desc = "It's high noon." + cost = 5000 + hidden = TRUE + contains = list(/obj/item/storage/lockbox/dueling) + crate_name = "dueling pistols (elimination)" + +/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." @@ -234,14 +284,6 @@ /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." @@ -267,6 +309,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." diff --git a/code/modules/cargo/packs/organic.dm b/code/modules/cargo/packs/organic.dm index 2d0af18670..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,97 +72,6 @@ /obj/item/storage/fancy/donut_box) crate_name = "candy crate" -/datum/supply_pack/organic/candy/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/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!" @@ -157,102 +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/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/pizza name = "Pizza Crate" desc = "Best prices on this side of the galaxy. All deliveries are guaranteed to be 99% anomaly-free!" @@ -287,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, @@ -299,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 ///////////////////////////////////// @@ -331,25 +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 - /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." @@ -402,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 ///////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -426,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 a009c998a3..79675cf3ec 100644 --- a/code/modules/cargo/packs/science.dm +++ b/code/modules/cargo/packs/science.dm @@ -29,7 +29,7 @@ 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,7 +82,7 @@ crate_name = "circuitry starter pack crate" /datum/supply_pack/science/glasswork - name = "Glass blower kit Crate" + 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, @@ -91,17 +91,6 @@ /obj/item/glasswork/blowing_rod) crate_name = "glassblower gear crate" -/datum/supply_pack/science/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 newest surgery tools" - crate_type = /obj/structure/closet/crate/medical - /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 34b8bbc249..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." @@ -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/asset_cache.dm b/code/modules/client/asset_cache.dm index 4acae30d11..902b442403 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -465,7 +465,8 @@ GLOBAL_LIST_EMPTY(asset_datums) "scanner" = 'icons/pda_icons/pda_scanner.png', "signaler" = 'icons/pda_icons/pda_signaler.png', "status" = 'icons/pda_icons/pda_status.png', - "dronephone" = 'icons/pda_icons/pda_dronephone.png' + "dronephone" = 'icons/pda_icons/pda_dronephone.png', + "emoji" = 'icons/pda_icons/pda_emoji.png' ) /datum/asset/spritesheet/simple/paper 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/client/verbs/ping.dm b/code/modules/client/verbs/ping.dm index de19d0d52c..02c5b5a7fd 100644 --- a/code/modules/client/verbs/ping.dm +++ b/code/modules/client/verbs/ping.dm @@ -14,9 +14,9 @@ /client/verb/display_ping(time as num) set instant = TRUE set name = ".display_ping" - to_chat(src, "Round trip ping took [round(pingfromtime(time),1)]ms") + to_chat(src, "Round trip ping took [round(pingfromtime(time),1)]ms (Avg: [round(avgping, 1)]ms])") /client/verb/ping() set name = "Ping" set category = "OOC" - winset(src, null, "command=.display_ping+[world.time+world.tick_lag*TICK_USAGE_REAL/100]") \ No newline at end of file + winset(src, null, "command=.display_ping+[world.time+world.tick_lag*TICK_USAGE_REAL/100]") diff --git a/code/modules/clothing/glasses/vg_glasses.dm b/code/modules/clothing/glasses/vg_glasses.dm deleted file mode 100644 index a51a03242c..0000000000 --- a/code/modules/clothing/glasses/vg_glasses.dm +++ /dev/null @@ -1,41 +0,0 @@ - -//VG rip - -/obj/item/clothing/glasses/sunglasses/purple - desc = "Strangely ancient technology used to help provide rudimentary eye cover. Enhanced shielding blocks many flashes, and the colored lenses let you see the world in purple." - name = "purple sunglasses" - icon_state = "sun_purple" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/glasses/sunglasses/star - name = "star-shaped sunglasses" - desc = "Novelty sunglasses, both lenses are in the shape of a star." - icon_state = "sun_star" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/glasses/sunglasses/rockstar - name = "red star-shaped sunglasses" - desc = "Novelty sunglasses with a fancy silver frame and two red-tinted star-shaped lenses. You should probably stomp on them and get a pair of normal ones." - icon_state = "sun_star_silver" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/glasses/gglasses - name = "Green Glasses" - desc = "Forest green glasses, like the kind you'd wear when hatching a nasty scheme." - icon_state = "gglasses" - item_state = "gglasses" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/glasses/welding/superior - name = "superior welding goggles" - desc = "Welding goggles made from more expensive materials, strangely smells like potatoes. Allows for better vision than normal goggles.." - icon_state = "rwelding-g" - item_state = "rwelding-g" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - actions_types = list(/datum/action/item_action/toggle) - flash_protect = 2 - tint = 1 - visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT - flags_cover = GLASSESCOVERSEYES - visor_flags_inv = HIDEEYES - glass_colour_type = /datum/client_colour/glass_colour/green \ No newline at end of file diff --git a/code/modules/clothing/gloves/vg_gloves.dm b/code/modules/clothing/gloves/vg_gloves.dm deleted file mode 100644 index 6d7e775314..0000000000 --- a/code/modules/clothing/gloves/vg_gloves.dm +++ /dev/null @@ -1,70 +0,0 @@ - -/obj/item/clothing/gloves/batmangloves - desc = "Used for handling all things bat related." - name = "batgloves" - icon_state = "bmgloves" - item_state = "bmgloves" - item_color = "bmgloves" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -obj/item/clothing/gloves/bikergloves - name = "Biker's Gloves" - icon_state = "biker-gloves" - item_state = "biker-gloves" - item_color = "bikergloves" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/gloves/megagloves - desc = "Uncomfortably bulky armored gloves." - name = "DRN-001 Gloves" - icon_state = "megagloves" - item_state = "megagloves" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/gloves/protogloves - desc = "Funcionally identical to the DRN-001 model's, but in red!" - name = "Prototype Gloves" - icon_state = "protogloves" - item_state = "protogloves" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/gloves/megaxgloves - desc = "An upgrade to the DRN-001's gauntlets, retains the uncomfortable armor, but comes with white gloves!" - name = "Maverick Hunter gloves" - icon_state = "megaxgloves" - item_state = "megaxgloves" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/gloves/joegloves - desc = "Large grey gloves, very similar to the Prototype's." - name = "Sniper Gloves" - icon_state = "joegloves" - item_state = "joegloves" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/gloves/doomguy - desc = "" - name = "Doomguy's gloves" - icon_state = "doom" - item_state = "doom" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/gloves/anchor_arms - name = "Anchor Arms" - desc = "When you're a jerk, everybody loves you." - icon_state = "anchorarms" - item_state = "anchorarms" - -/obj/item/clothing/gloves/neorussian - name = "neo-Russian gloves" - desc = "Utilizes a non-slip technology that allows you to never drop your precious bottles of vodka." - icon_state = "nr_gloves" - item_state = "nr_gloves" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/gloves/neorussian/fingerless - name = "neo-Russian fingerless gloves" - desc = "For these tense combat situations when you just have to pick your nose." - icon_state = "nr_fgloves" - item_state = "nr_fgloves" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' \ No newline at end of file diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index 696ff1346c..189fb46e46 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -423,3 +423,15 @@ desc = "A security cowboy hat, perfect for any true lawman" icon_state = "cowboyhat_sec" item_state= "cowboyhat_sec" + +/obj/item/clothing/head/squatter_hat + name = "slav squatter hat" + icon_state = "squatter_hat" + item_state = "squatter_hat" + desc = "Cyka blyat." + +/obj/item/clothing/head/russobluecamohat + name = "russian blue camo beret" + desc = "A symbol of discipline, honor, and lots and lots of removal of some type of skewered food." + icon_state = "russobluecamohat" + item_state = "russobluecamohat" diff --git a/code/modules/clothing/head/vg_hats.dm b/code/modules/clothing/head/vg_hats.dm deleted file mode 100644 index 87f64baf13..0000000000 --- a/code/modules/clothing/head/vg_hats.dm +++ /dev/null @@ -1,155 +0,0 @@ -/obj/item/clothing/head/helmet/dredd - name = "Judge Helmet" - desc = "Judge, Jury, and Executioner." - icon_state = "dredd-helmet" - item_state = "dredd-helmet" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - armor = list(melee = 40, bullet = 30, laser = 30,energy = 30, bomb = 50, bio = 90, rad = 20, fire = 50, acid = 50) - cold_protection = HEAD - min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT - heat_protection = HEAD - max_heat_protection_temperature = SPACE_HELM_MAX_TEMP_PROTECT - strip_delay = 80 - dog_fashion = null - -/obj/item/clothing/head/helmet/aviatorhelmet - name = "Aviator Helmet" - desc = "Help the Bombardier!" - armor = list(melee = 25, bullet = 0, laser = 20, energy = 10, bomb = 10, bio = 0, rad = 0) - item_state = "aviator_helmet" - icon_state = "aviator_helmet" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/helmet/biker - name = "Biker's Helmet" - desc = "This helmet should protect you from russians and masked vigilantes." - armor = list(melee = 25, bullet = 15, laser = 20, energy = 10, bomb = 10, bio = 0, rad = 0) - icon_state = "biker_helmet" - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR - -/obj/item/clothing/head/helmet/richard - name = "Richard" - desc = "Do you like hurting people?" - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) - icon_state = "richard" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR - -/obj/item/clothing/head/helmet/megahelmet - name = "DRN-001 Helmet" - desc = "The helmet of the DRN-001 model. A simple, sturdy blue helmet." - icon_state = "megahelmet" - item_state = "megahelmet" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - siemens_coefficient = 1 - -/obj/item/clothing/head/helmet/protohelmet - name = "Prototype Helmet" - desc = "Shiny red helmet with white accents and a built in shaded visor that does absolutely nothing, nothing but look rad as hell." - icon_state = "protohelmet" - item_state = "protohelmet" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - siemens_coefficient = 1 - -/obj/item/clothing/head/helmet/megaxhelmet - name = "Maverick Hunter Helmet" - desc = "Heavily armored upgrade to the DRN-001 model's helmet, now comes with a pointless red crystal thing!" - icon_state = "megaxhelmet" - item_state = "megaxhelmet" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/helmet/joehelmet - name = "Sniper Helmet" - desc = "Helmet belonging to one of the many mass produced 'Joe' type robots." - icon_state = "joehelmet" - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR - item_state = "joehelmet" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/helmet/doomguy - name = "Doomguy's helmet" - desc = "" - icon_state = "doom" - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR - item_state = "doom" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - armor = list(melee = 50, bullet = 40, laser = 40,energy = 40, bomb = 5, bio = 0, rad = 0) - -/obj/item/clothing/head/helmet/neorussian - name = "neo-Russian helmet" - desc = "This piece of equipment can double as a pillow, a bowl, an emergency toilet, and sometimes as a helmet." - icon_state = "nr_helmet" - item_state = "nr_helmet" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/panzer - name = "Panzer Cap" - desc = "Command any mech in style." - icon_state = "panzercap" - item_state = "panzercap" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/russobluecamohat - name = "russian blue camo beret" - desc = "A symbol of discipline, honor, and lots and lots of removal of some type of skewered food." - icon_state = "russobluecamohat" - item_state = "russobluecamohat" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/russofurhat - name = "russian fur hat" - desc = "Russian winter got you down? Maybe your enemy, but not you!" - icon_state = "russofurhat" - item_state = "russofurhat" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/squatter_hat - name = "slav squatter hat" - icon_state = "squatter_hat" - item_state = "squatter_hat" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - desc = "Cyka blyat." - -/obj/item/clothing/head/snake - name = "snake head" - desc = "Reenact acts of violence against reptiles, or sneak into a swamp unnoticed." - icon_state = "snakehead" - item_state = "snakehead" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' -/obj/item/clothing/head/mummy_rags - name = "mummy rags" - desc = "Ancient rags taken off from some mummy." - icon_state = "mummy" - item_state = "mummy" - item_color = "mummy" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS - -/obj/item/clothing/head/clownpiece - name = "Clownpiece's jester hat" - desc = "A purple polka-dotted jester's hat with yellow pompons." - icon_state = "clownpiece" - item_state = "clownpiece" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/mitre - name = "mitre" - desc = "A funny hat worn by extremely boring people." - icon_state = "mitre" - item_state = "mitre" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/tinfoil - name = "tinfoil hat" - desc = "There's no evidence that the security staff is NOT out to get you." - icon_state = "foilhat" - item_state = "paper" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - siemens_coefficient = 2 - -/obj/item/clothing/head/celtic - name = "\improper Celtic crown" - desc = "According to legend, Celtic kings would use crowns like this one to shield their subjects from harsh winters back on Earth." - icon_state = "celtic_crown" - item_state = "celtic_crown" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' diff --git a/code/modules/clothing/masks/vg_masks.dm b/code/modules/clothing/masks/vg_masks.dm deleted file mode 100644 index 29b65a6b8e..0000000000 --- a/code/modules/clothing/masks/vg_masks.dm +++ /dev/null @@ -1,17 +0,0 @@ -/obj/item/clothing/mask/gas/clown_hat/wiz - name = "purple clown wig and mask" - desc = "Some pranksters are truly magical." - icon_state = "wizzclown" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/mask/chapmask - name = "venetian mask" - desc = "A plain porcelain mask that covers the entire face. Standard attire for particularly unspeakable religions. The eyes are wide shut." - icon_state = "chapmask" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/mask/neorussian - name = "neo-Russian mask" - desc = "Somehow, it makes you act and look way more polite than usual." - icon_state = "nr_mask" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' 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/shoes/vg_shoes.dm b/code/modules/clothing/shoes/vg_shoes.dm deleted file mode 100644 index 53b093dc72..0000000000 --- a/code/modules/clothing/shoes/vg_shoes.dm +++ /dev/null @@ -1,124 +0,0 @@ - -/obj/item/clothing/shoes/leather - name = "leather shoes" - desc = "A sturdy pair of leather shoes." - icon_state = "leather" - item_color = "leather" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/magboots/deathsquad - desc = "Very expensive and advanced magnetic boots, used only by the elite during extravehicular activity to ensure the user remains safely attached to the vehicle." - name = "deathsquad magboots" - icon_state = "DS-magboots0" - magboot_state = "DS-magboots" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF - mutantrace_variation = NONE - -/obj/item/clothing/shoes/magboots/atmos - desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle. These are painted in the colors of an atmospheric technician." - name = "atmospherics magboots" - icon_state = "atmosmagboots0" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - magboot_state = "atmosmagboots" - resistance_flags = FIRE_PROOF - mutantrace_variation = NONE - -/obj/item/clothing/shoes/simonshoes - name = "Simon's Shoes" - desc = "Simon's Shoes." - icon_state = "simonshoes" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/kneesocks - name = "kneesocks" - desc = "A pair of girly knee-high socks." - icon_state = "kneesock" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/jestershoes - name = "Jester Shoes" - desc = "As worn by the clowns of old." - icon_state = "jestershoes" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/aviatorboots - name = "Aviator Boots" - desc = "Boots suitable for just about any occasion." - icon_state = "aviator_boots" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/libertyshoes - name = "Liberty Shoes" - desc = "Freedom isn't free, neither were these shoes." - icon_state = "libertyshoes" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/megaboots - name = "DRN-001 Boots" - desc = "Large armored boots, very weak to large spikes." - icon_state = "megaboots" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/protoboots - name = "Prototype Boots" - desc = "Functionally identical to the DRN-001 model's boots, but in red." - icon_state = "protoboots" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/megaxboots - name = "Maverick Hunter boots" - desc = "Regardless of how much stronger these boots are than the DRN-001 model's, they're still extremely easy to pierce with a large spike." - icon_state = "megaxboots" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/joeboots - name = "Sniper Boots" - desc = "Nearly identical to the Prototype's boots, except in black." - icon_state = "joeboots" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/doomguy - name = "Doomguy's boots" - desc = "If you look closely, you might see skull fragments still buried in these boots." - icon_state = "doom" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/rottenshoes - name = "rotten shoes" - desc = "These shoes seem perfect for sneaking around." - icon_state = "rottenshoes" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/sandal/slippers - name = "magic slippers" - icon_state = "slippers" - desc = "For the wizard that puts comfort first. Who's going to laugh?" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/slippers_worn - name = "worn bunny slippers" - desc = "Fluffy..." - icon_state = "slippers_worn" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/jackboots/neorussian - name = "neo-Russian boots" - desc = "Tovarish, no one will realize you stepped on a pile of shit if your pair already looks like shit." - icon_state = "nr_boots" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index c9753b3053..703fe26287 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -693,6 +693,29 @@ listeningTo = null return ..() +/obj/item/clothing/head/helmet/space/hardsuit/soviet + name = "soviet hardhelmet" + desc = "Crafted with the pride of the proletariat. The vengeful gaze of the visor roots out all fascists and capitalists." + item_state = "rig0-soviet" + item_color = "soviet" + icon_state = "rig0-soviet" + armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 75) + mutantrace_variation = NONE + +/obj/item/clothing/suit/space/hardsuit/soviet + name = "soviet hardsuit" + desc = "Crafted with the pride of the proletariat. The last thing the enemy sees is the bottom of this armor's boot." + item_state = "rig-soviet" + icon_state = "rig-soviet" + slowdown = 0.8 + armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 75) + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/soviet + mutantrace_variation = NONE + +/obj/item/clothing/suit/space/hardsuit/soviet/Initialize() + . = ..() + allowed = GLOB.security_hardsuit_allowed + /////////////SHIELDED////////////////////////////////// /obj/item/clothing/suit/space/hardsuit/shielded diff --git a/code/modules/clothing/spacesuits/vg_spess.dm b/code/modules/clothing/spacesuits/vg_spess.dm deleted file mode 100644 index 517539f3af..0000000000 --- a/code/modules/clothing/spacesuits/vg_spess.dm +++ /dev/null @@ -1,120 +0,0 @@ - - //VG Ports - -/obj/item/clothing/head/helmet/space/hardsuit/soviet - name = "soviet hardhelmet" - desc = "Crafted with the pride of the proletariat. The vengeful gaze of the visor roots out all fascists and capitalists." - item_state = "hardsuit0-soviet" - icon_state = "hardsuit0-soviet" - armor = list(melee = 40, bullet = 30, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 20) - item_color = "soviet" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/suit/space/hardsuit/soviet - name = "soviet hardsuit" - desc = "Crafted with the pride of the proletariat. The last thing the enemy sees is the bottom of this armor's boot." - item_state = "hardsuit-soviet" - icon_state = "hardsuit-soviet" - slowdown = 1 - armor = list(melee = 40, bullet = 30, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 20) - allowed = list(/obj/item/gun,/obj/item/flashlight,/obj/item/tank,/obj/item/melee/) - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/soviet - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/helmet/space/hardsuit/knight - name = "Space-Knight helm" - desc = "A well polished helmet belonging to a Space-Knight. Favored by space-jousters for its ability to stay on tight after being launched from a mass driver." - icon_state = "hardsuit0-knight" - item_state = "hardsuit0-knight" - armor = list(melee = 60, bullet = 40, laser = 40,energy = 30, bomb = 50, bio = 100, rad = 60) - max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - item_color="knight" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/suit/space/hardsuit/knight - name = "Space-Knight armour" - desc = "A well polished set of armour belonging to a Space-Knight. Maidens Rescued in Space: 100, Maidens who have slept with me in Space: 0." - icon_state = "hardsuit-knight" - item_state = "hardsuit-knight" - slowdown = 1 - allowed = list(/obj/item/gun,/obj/item/melee/baton,/obj/item/tank,/obj/item/shield/energy,/obj/item/claymore) - armor = list(melee = 60, bullet = 40, laser = 40,energy = 30, bomb = 50, bio = 100, rad = 60) - max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - siemens_coefficient = 0.5 - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/knight - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/helmet/space/hardsuit/knight/black - name = "Black Knight's helm" - desc = "An ominous black helmet with a gold trim. The small viewports create an intimidating look, while also making it nearly impossible to see anything." - icon_state = "hardsuit0-blackknight" - item_state = "hardsuit0-blackknight" - armor = list(melee = 70, bullet = 65, laser = 50,energy = 25, bomb = 60, bio = 100, rad = 60) - item_color="blackknight" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/suit/space/hardsuit/knight/black - name = "Black Knight's armour" - desc = "An ominous black suit of armour with a gold trim. Surprisingly good at preventing accidental loss of limbs." - icon_state = "hardsuit-blackknight" - item_state = "hardsuit-blackknight" - armor = list(melee = 70, bullet = 65, laser = 50,energy = 25, bomb = 60, bio = 100, rad = 60) - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/knight/black - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/helmet/space/hardsuit/knight/solaire - name = "Solar helm" - desc = "A simple helmet. 'Made in Astora' is inscribed on the back." - icon_state = "hardsuit0-solaire" - item_state = "hardsuit0-solaire" - armor = list(melee = 60, bullet = 65, laser = 90,energy = 30, bomb = 60, bio = 100, rad = 100) - item_color="solaire" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/suit/space/hardsuit/knight/solaire - name = "Solar armour" - desc = "A solar powered hardsuit with a fancy insignia on the chest. Perfect for stargazers and adventurers alike." - icon_state = "hardsuit-solaire" - item_state = "hardsuit-solaire" - armor = list(melee = 60, bullet = 65, laser = 90,energy = 30, bomb = 60, bio = 100, rad = 100) - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/knight/solaire - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/helmet/space/hardsuit/t51b - name = "T-51b Power Armor" - desc = "Relic of a bygone era, the T-51b is powered by a TX-28 MicroFusion Pack, which holds enough fuel to power its internal hydraulics for a century!" - icon_state = "hardsuit0-t51b" - item_state = "hardsuit0-t51b" - armor = list(melee = 35, bullet = 35, laser = 40, energy = 40, bomb = 80, bio = 100, rad = 100) - item_color="t51b" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/suit/space/hardsuit/t51b - name = "T-51b Power Armor" - desc = "Relic of a bygone era, the T-51b is powered by a TX-28 MicroFusion Pack, which holds enough fuel to power its internal hydraulics for a century!" - icon_state = "hardsuit-t51b" - item_state = "hardsuit-t51b" - armor = list(melee = 35, bullet = 35, laser = 40, energy = 40, bomb = 80, bio = 100, rad = 100) - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/t51b - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - - -/obj/item/clothing/head/helmet/space/bomberman - name = "Bomberman head" - desc = "Terrorism has never looked so adorable." - icon_state = "bomberman" - item_state = "bomberman" - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 100, bio = 0, rad = 0) - siemens_coefficient = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -obj/item/clothing/suit/space/bomberman - name = "Bomberman's suit" - desc = "Doesn't actually make you immune to bombs!" - icon_state = "bomberman" - item_state = "bomberman" - slowdown = 0 - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 100, bio = 0, rad = 0) - siemens_coefficient = 0 - max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' \ No newline at end of file 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/suits/vg_suits.dm b/code/modules/clothing/suits/vg_suits.dm deleted file mode 100644 index be6cd9938e..0000000000 --- a/code/modules/clothing/suits/vg_suits.dm +++ /dev/null @@ -1,138 +0,0 @@ - -/obj/item/clothing/suit/armor/xcomsquaddie - name = "Squaddie Armor" - desc = "A suit of armor with heavy padding to protect against projectile and laser attacks. Distributed to shadow organization squaddies." - icon_state = "xcomarmor2" - item_state = "xcomarmor2" - body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - armor = list(melee = 50, bullet = 50, laser = 50, energy = 30, bomb = 60, bio = 30, rad = 20) - siemens_coefficient = 0.5 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/armor/xcomsquaddie/dredd - name = "Judge Armor" - desc = "A large suit of heavy armor, fit for a Judge." - icon_state = "dredd-suit" - item_state = "dredd-suit" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - - -/obj/item/clothing/suit/armor/xcomarmor - name = "Mysterious Armor" - desc = "A suit of armor with heavy plating to protect against melee attacks. Distributed to shadow organization squaddies." - icon_state = "xcomarmor1" - item_state = "xcomarmor1" - body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - armor = list(melee = 50, bullet = 50, laser = 50, energy = 30, bomb = 60, bio = 30, rad = 20) - slowdown = 1 - siemens_coefficient = 0.5 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/armor/vest/neorussian - name = "neo-Russian vest" - desc = "The narkotiki camo pattern will come useful for botany raids." - icon_state = "nr_vest" - item_state = "nr_vest" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/armor/doomguy - name = "Doomguy's armor" - desc = "" - icon_state = "doom" - item_state = "doom" - body_parts_covered = CHEST|GROIN - slowdown = 0 - armor = list(melee = 50, bullet = 30, laser = 20, energy = 20, bomb = 30, bio = 0, rad = 0) - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - - -/obj/item/clothing/suit/kaminacape - name = "Kamina's Cape" - desc = "Don't believe in yourself, dumbass. Believe in me. Believe in the Kamina who believes in you." - icon_state = "kaminacape" - body_parts_covered = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/officercoat - name = "Officer's Coat" - desc = "Ein Mantel gemacht, um die Juden zu bestrafen." - icon_state = "officersuit" - body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/soldiercoat - name = "Soldier's Coat" - desc = "Und das heißt: Erika." - icon_state = "soldiersuit" - body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/russofurcoat - name = "russian fur coat" - desc = "Let the land do the fighting for you." - icon_state = "russofurcoat" - allowed = list(/obj/item/gun) - body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/doshjacket - name = "Plasterer's Jacket" - desc = "Perfect for doing up the house." - icon_state = "doshjacket" - body_parts_covered = CHEST|GROIN|ARMS - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/maidapron - name = "Apron" - desc = "Simple white apron." - icon_state = "maidapron" - body_parts_covered = CHEST|GROIN - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/clownpiece - name = "small fairy wings" - desc = "Some small and translucid insect-like wings." - icon_state = "clownpiece" - body_parts_covered = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/clownpiece/flying - name = "small fairy wings" - desc = "Some small and translucid insect-like wings. Looks like these are the real deal!" - icon_state = "clownpiece-fly" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/raincoat - name = "Raincoat" - desc = "Do you like Huey Lewis and the News?" - icon_state = "raincoat" - body_parts_covered =CHEST|GROIN|LEGS|ARMS|HANDS - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - - diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index a2081851e1..251ff50173 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -945,4 +945,144 @@ 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 + +/obj/item/clothing/under/squatter_outfit + name = "slav squatter tracksuit" + desc = "Cyka blyat." + icon_state = "squatteroutfit" + item_state = "squatteroutfit" + item_color = "squatteroutfit" + can_adjust = FALSE + mutantrace_variation = NONE + +/obj/item/clothing/under/russobluecamooutfit + name = "russian blue camo" + desc = "Drop and give me dvadtsat!" + icon_state = "russobluecamo" + item_state = "russobluecamo" + item_color = "russobluecamo" + can_adjust = FALSE + mutantrace_variation = NONE + +/obj/item/clothing/under/keyholesweater + name = "keyhole sweater" + desc = "What is the point of this, anyway?" + icon_state = "keyholesweater" + item_state = "keyholesweater" + item_color = "keyholesweater" + can_adjust = FALSE + mutantrace_variation = NONE + +/obj/item/clothing/under/stripper_pink + name = "pink stripper outfit" + icon_state = "stripper_p" + item_state = "stripper_p" + item_color = "stripper_p" + +/obj/item/clothing/under/stripper_green + name = "green stripper outfit" + icon_state = "stripper_g" + item_state = "stripper_g" + item_color = "stripper_g" + can_adjust = FALSE + +/obj/item/clothing/under/mankini + name = "pink mankini" + icon_state = "mankini" + item_state = "mankini" + item_color = "mankini" + can_adjust = FALSE + mutantrace_variation = NONE + +/obj/item/clothing/under/wedding + name = "white wedding dress" + desc = "A white wedding gown made from the finest silk." + icon_state = "bride_white" + item_state = "bride_white" + item_color = "bride_white" + can_adjust = FALSE + mutantrace_variation = NONE + +/obj/item/clothing/under/wedding/orange + name = "orange wedding dress" + desc = "A big and puffy orange dress." + icon_state = "bride_orange" + item_state = "bride_orange" + item_color = "bride_orange" + +/obj/item/clothing/under/wedding/purple + name = "purple wedding dress" + desc = "A big and puffy purple dress." + icon_state = "bride_purple" + item_state = "bride_purple" + item_color = "bride_purple" + +/obj/item/clothing/under/wedding/blue + name = "blue wedding dress" + desc = "A big and puffy blue dress." + icon_state = "bride_blue" + item_state = "bride_blue" + item_color = "bride_blue" + +/obj/item/clothing/under/wedding/red + name = "red wedding dress" + desc = "A big and puffy red dress." + icon_state = "bride_red" + item_state = "bride_red" + item_color = "bride_red" diff --git a/code/modules/clothing/under/vg_under.dm b/code/modules/clothing/under/vg_under.dm deleted file mode 100644 index 555ed3b795..0000000000 --- a/code/modules/clothing/under/vg_under.dm +++ /dev/null @@ -1,436 +0,0 @@ -// Fixed to work with Citadel code. Apparently none of them had NO_MUTANTRACE flags. -// I was pissy when I realised how to fix this because it's so fucking easy and nobody apparently had done it. - -/obj/item/clothing/under/stripper_pink - name = "pink stripper outfit" - icon_state = "stripper_p" - item_state = "stripper_p" - item_color = "stripper_p" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/stripper_green - name = "green stripper outfit" - icon_state = "stripper_g" - item_state = "stripper_g" - item_color = "stripper_g" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/wedding/bride_orange - name = "orange wedding dress" - desc = "A big and puffy orange dress." - icon_state = "bride_orange" - item_state = "bride_orange" - item_color = "bride_orange" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/wedding/bride_purple - name = "purple wedding dress" - desc = "A big and puffy purple dress." - icon_state = "bride_purple" - item_state = "bride_purple" - item_color = "bride_purple" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/wedding/bride_blue - name = "blue wedding dress" - desc = "A big and puffy blue dress." - icon_state = "bride_blue" - item_state = "bride_blue" - item_color = "bride_blue" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/wedding/bride_red - name = "red wedding dress" - desc = "A big and puffy red dress." - icon_state = "bride_red" - item_state = "bride_red" - item_color = "bride_red" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/wedding/bride_white - name = "white wedding dress" - desc = "A white wedding gown made from the finest silk." - icon_state = "bride_white" - item_state = "bride_white" - item_color = "bride_white" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/mankini - name = "pink mankini" - icon_state = "mankini" - item_state = "mankini" - item_color = "mankini" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE -/* - -/obj/item/clothing/under/psysuit - name = "dark undersuit" - desc = "A thick, layered grey undersuit lined with power cables. Feels a little like wearing an electrical storm." - icon_state = "psysuit" - item_state = "psysuit" - item_color = "psysuit" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - - -/obj/item/clothing/under/officeruniform - name = "officer's uniform" - desc = "Bestraft die Juden fur ihre Verbrechen." - icon_state = "officeruniform" - item_state = "officeruniform" - item_color = "officeruniform" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - - -/obj/item/clothing/under/soldieruniform - name = "soldier's uniform" - desc = "Bestraft die Verbundeten fur ihren Widerstand." - icon_state = "soldieruniform" - item_state = "soldieruniform" - item_color = "soldieruniform" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - -*/ -/obj/item/clothing/under/squatter_outfit - name = "slav squatter tracksuit" - desc = "Cyka blyat." - icon_state = "squatteroutfit" - item_state = "squatteroutfit" - item_color = "squatteroutfit" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/russobluecamooutfit - name = "russian blue camo" - desc = "Drop and give me dvadtsat!" - icon_state = "russobluecamo" - item_state = "russobluecamo" - item_color = "russobluecamo" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/stilsuit - name = "stillsuit" - desc = "Designed to preserve bodymoisture." - icon_state = "stilsuit" - item_state = "stilsuit" - item_color = "stilsuit" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/aviatoruniform - name = "aviator uniform" - desc = "Now you can look absolutely dashing!" - icon_state = "aviator_uniform" - item_state = "aviator_uniform" - item_color = "aviator_uniform" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/bikersuit - name = "biker's outfit" - icon_state = "biker" - item_state = "biker" - item_color = "biker" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/jacketsuit - name = "richard's outfit" - desc = "Do you know what time it is?" - icon_state = "jacket" - item_state = "jacket" - item_color = "jacket" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -obj/item/clothing/under/mega - name = "\improper DRN-001 suit" - desc = "The original. Simple, yet very adaptable." - icon_state = "mega" - item_state = "mega" - item_color = "mega" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/proto - name = "The Prototype Suit" - desc = "Even robots know scarves are the perfect accessory for a brooding rival." - icon_state = "proto" - item_state = "proto" - item_color = "proto" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/megax - name = "\improper Maverick Hunter regalia" - desc = "The best outfit for taking out rogue borgs." - icon_state = "megax" - item_state = "megax" - item_color = "megax" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/joe - name = "The Sniper Suit" - desc = "Mass produced combat robots with a rather unfitting name." - icon_state = "joe" - item_state = "joe" - item_color = "joe" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/roll - name = "\improper DRN-002 Dress" - desc = "A simple red dress, the good doctor's second robot wasn't quite as exciting as the first." - icon_state = "roll" - item_state = "roll" - item_color = "roll" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/gokugidown - name = "turtle hermit undershirt" - desc = "Something seems oddly familiar about this outfit..." - icon_state = "gokugidown" - item_state = "gokugidown" - item_color = "gokugidown" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/gokugi - name = "turtle hermit outfit" - desc = "An outfit from one trained by the great Turtle Hermit." - icon_state = "gokugi" - item_state = "gokugi" - item_color = "gokugi" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/doomguy - name = "\improper Doomguy's pants" - desc = "" - icon_state = "doom" - item_state = "doom" - item_color = "doom" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/vault13 - name = "vault 13 Jumpsuit" - desc = "Oddly similar to the station's usual jumpsuits, but with a rustic charm to it. Has a large thirteen emblazened on the back." - icon_state = "v13-jumpsuit" - item_state = "v13-jumpsuit" - item_color = "v13-jumpsuit" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/vault - name = "vault jumpsuit" - desc = "Oddly similar to the station's usual jumpsuits, but with a rustic charm to it." - icon_state = "v-jumpsuit" - item_state = "v-jumpsuit" - item_color = "v-jumpsuit" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/clownpiece - name = "Clownpiece's Pierrot suit" - desc = "A female-sized set of leggings and shirt with a pattern similar to the American flag, featuring a frilled collar." - icon_state = "clownpiece" - item_state = "clownpiece" - item_color = "clownpiece" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/cia - name = "casual IAA outfit" - desc = "Just looking at this makes you feel in charge." - icon_state = "cia" - item_state = "cia" - item_color = "cia" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/greaser - name = "greaser outfit" - desc = "The one that you want!" - icon_state = "greaser_default" - item_state = "greaser_default" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/greaser/New() - var/greaser_colour = "default" - switch(rand(1,4)) - if(1) - greaser_colour = "default" - if(2) - greaser_colour = "cult" - if(3) - greaser_colour = "spider" - if(4) - greaser_colour = "snakes" - desc = "Tunnel Snakes Rule!" - icon_state = "greaser_[greaser_colour]" - item_state = "greaser_[greaser_colour]" - item_color = "greaser_[greaser_colour]" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - - -/obj/item/clothing/under/wintercasualwear - name = "winter casualwear" - desc = "Perfect for winter!" - icon_state = "shizunewinter" - item_state = "shizunewinter" - item_color = "shizunewinter" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/casualwear - name = "spring casualwear" - desc = "Perfect for spring!" - icon_state = "shizunenormal" - item_state = "shizunenormal" - item_color = "shizunenormal" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/keyholesweater - name = "keyhole sweater" - desc = "What is the point of this, anyway?" - icon_state = "keyholesweater" - item_state = "keyholesweater" - item_color = "keyholesweater" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/casualhoodie - name = "casual hoodie" - desc = "Pefect for lounging about in." - icon_state = "hoodiejeans" - item_state = "hoodiejeans" - item_color = "hoodiejeans" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/casualhoodie/skirt - icon_state = "hoodieskirt" - item_state = "hoodieskirt" - item_color = "hoodieskirt" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/* -/obj/item/clothing/under/mummy_rags - name = "mummy rags" - desc = "Ancient rags taken off from some mummy." - icon_state = "mummy" - item_state = "mummy" - item_color = "mummy" - can_adjust = 0 - has_sensor = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - - -/obj/item/clothing/under/neorussian - name = "neo-Russian uniform" - desc = "Employs a special toshnit pattern, will render you invisible when you eat a potato on an empty stomach." - icon_state = "nr_uniform" - item_state = "nr_uniform" - item_color = "nr_uniform" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' -*/ - -/obj/item/clothing/under/rottensuit - name = "rotten suit" - desc = "This suit seems perfect for wearing underneath a disguise." - icon_state = "rottensuit" - item_state = "rottensuit" - item_color = "rottensuit" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - diff --git a/code/modules/emoji/emoji_parse.dm b/code/modules/emoji/emoji_parse.dm index 2f4a84c646..db46ca09ca 100644 --- a/code/modules/emoji/emoji_parse.dm +++ b/code/modules/emoji/emoji_parse.dm @@ -1,4 +1,4 @@ -/proc/emoji_parse(text) +/proc/emoji_parse(text) //turns :ai: into an emoji in text. . = text if(!CONFIG_GET(flag/emojis)) return @@ -30,3 +30,24 @@ break return parsed +/proc/emoji_sanitize(text) //cuts any text that would not be parsed as an emoji + . = text + if(!CONFIG_GET(flag/emojis)) + return + var/static/list/emojis = icon_states(icon('icons/emoji.dmi')) + var/final = "" //only tags are added to this + var/pos = 1 + var/search = 0 + while(1) + search = findtext(text, ":", pos) + if(search) + pos = search + search = findtext(text, ":", pos+1) + if(search) + var/word = lowertext(copytext(text, pos+1, search)) + if(word in emojis) + final += lowertext(copytext(text, pos, search+1)) + pos = search + 1 + continue + break + return final 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/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/keybindings/bindings_atom.dm b/code/modules/keybindings/bindings_atom.dm index 4aac76bd67..5f3e879237 100644 --- a/code/modules/keybindings/bindings_atom.dm +++ b/code/modules/keybindings/bindings_atom.dm @@ -15,4 +15,4 @@ movement_dir &= ~(NORTH|SOUTH) if((movement_dir & EAST) && (movement_dir & WEST)) movement_dir &= ~(EAST|WEST) - user.Move(get_step(src, movement_dir), movement_dir) \ No newline at end of file + user.Move(get_step(src, movement_dir), movement_dir) diff --git a/code/modules/keybindings/bindings_client.dm b/code/modules/keybindings/bindings_client.dm index dec5c25eb9..6030362a61 100644 --- a/code/modules/keybindings/bindings_client.dm +++ b/code/modules/keybindings/bindings_client.dm @@ -5,7 +5,7 @@ set hidden = TRUE client_keysend_amount += 1 - + var/cache = client_keysend_amount if(keysend_tripped && next_keysend_trip_reset <= world.time) @@ -20,7 +20,7 @@ //don't want to kick people if a lag spike results in a huge flood of commands being sent if(cache >= MAX_KEYPRESS_AUTOKICK) if(!keysend_tripped) - keysend_tripped = TRUE + keysend_tripped = TRUE next_keysend_trip_reset = world.time + (2 SECONDS) else log_admin("Client [ckey] was just autokicked for flooding keysends; likely abuse but potentially lagspike.") @@ -35,11 +35,10 @@ message_admins("Client [ckey] just attempted to send an invalid keypress. Keymessage was over [MAX_KEYPRESS_COMMANDLENGTH] characters, autokicking due to likely abuse.") QDEL_IN(src, 1) return - //offset by 1 because the buffer address is 0 indexed because the math was simpler - keys_held[current_key_address + 1] = _key - //the time a key was pressed isn't actually used anywhere (as of 2019-9-10) but this allows easier access usage/checking - keys_held[_key] = world.time - current_key_address = ((current_key_address + 1) % HELD_KEY_BUFFER_LENGTH) + + if(length(keys_held) > MAX_HELD_KEYS) + keys_held.Cut(1,2) + keys_held[_key] = TRUE var/movement = SSinput.movement_keys[_key] if(!(next_move_dir_sub & movement) && !keys_held["Ctrl"]) next_move_dir_add |= movement @@ -70,11 +69,7 @@ set instant = TRUE set hidden = TRUE - //Can't just do a remove because it would alter the length of the rolling buffer, instead search for the key then null it out if it exists - for(var/i in 1 to HELD_KEY_BUFFER_LENGTH) - if(keys_held[i] == _key) - keys_held[i] = null - break + keys_held -= _key var/movement = SSinput.movement_keys[_key] if(!(next_move_dir_add & movement)) next_move_dir_sub |= movement diff --git a/code/modules/keybindings/setup.dm b/code/modules/keybindings/setup.dm index 8433c9bf5a..9a13bfb11c 100644 --- a/code/modules/keybindings/setup.dm +++ b/code/modules/keybindings/setup.dm @@ -1,8 +1,6 @@ /client - /// A rolling buffer of any keys held currently + /// Keys currently held var/list/keys_held = list() - ///used to keep track of the current rolling buffer position - var/current_key_address = 0 /// These next two vars are to apply movement for keypresses and releases made while move delayed. /// Because discarding that input makes the game less responsive. /// On next move, add this dir to the move that would otherwise be done @@ -36,10 +34,7 @@ /client/proc/set_macros() set waitfor = FALSE - //Reset and populate the rolling buffer keys_held.Cut() - for(var/i in 1 to HELD_KEY_BUFFER_LENGTH) - keys_held += null erase_all_macros() 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 827f56b634..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 @@ -599,6 +599,10 @@ 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" 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 a2689f0b5f..90ada3d718 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -459,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/mob.dm b/code/modules/mob/mob.dm index 630ce54261..333a7826d2 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)) @@ -569,29 +571,23 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) M.show_inv(user) /mob/proc/is_muzzled() - return 0 + return FALSE /mob/Stat() ..() - if(statpanel("Status")) - if (client) - stat(null, "Ping: [round(client.lastping, 1)]ms (Average: [round(client.avgping, 1)]ms)") - stat(null, "Map: [SSmapping.config?.map_name || "Loading..."]") - var/datum/map_config/cached = SSmapping.next_map_config - if(cached) - stat(null, "Next Map: [cached.map_name]") - stat(null, "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]") - stat(null, "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]") - stat(null, "Round Time: [WORLDTIME2TEXT("hh:mm:ss")]") - stat(null, "Station Time: [STATION_TIME_TIMESTAMP("hh:mm:ss")]") - stat(null, "Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)") - if(SSshuttle.emergency) - var/ETA = SSshuttle.emergency.getModeStr() - if(ETA) - stat(null, "[ETA] [SSshuttle.emergency.getTimerStr()]") + //This is only called from client/Stat(), let's assume client exists. - if(client && client.holder) + if(statpanel("Status")) + var/list/L = list() + L += "Ping: [round(client.lastping,1)]ms (Avg: [round(client.avgping,1)]ms)" + L += SSmapping.stat_map_name + L += "Round ID: [GLOB.round_id || "NULL"]" + L += SStime_track.stat_time_text + L += SSshuttle.emergency_shuttle_stat_text + stat(null, "[L.Join("\n\n")]") + + if(client.holder) if(statpanel("MC")) var/turf/T = get_turf(client.eye) stat("Location:", COORD(T)) @@ -641,8 +637,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) if(A.IsObscured()) continue statpanel(listed_turf.name, null, A) - - if(mind) add_spells_to_statpanel(mind.spell_list) var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling) @@ -964,4 +958,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/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index a1feb899c6..b11d1632c8 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -9,37 +9,36 @@ mob.dropItemToGround(mob.get_active_held_item()) return -/client/proc/Move_object(direct) +/client/proc/Move_object(direction) if(mob && mob.control_object) if(mob.control_object.density) - step(mob.control_object,direct) + step(mob.control_object,direction) if(!mob.control_object) return - mob.control_object.setDir(direct) + mob.control_object.setDir(direction) else - mob.control_object.forceMove(get_step(mob.control_object,direct)) + mob.control_object.forceMove(get_step(mob.control_object,direction)) #define MOVEMENT_DELAY_BUFFER 0.75 #define MOVEMENT_DELAY_BUFFER_DELTA 1.25 -/client/Move(n, direct) +/client/Move(n, direction) if(world.time < move_delay) //do not move anything ahead of this check please return FALSE else - next_move_dir_add = 0 - next_move_dir_sub = 0 + next_move_dir_add = next_move_dir_sub = NONE var/old_move_delay = move_delay move_delay = world.time + world.tick_lag //this is here because Move() can now be called mutiple times per tick - if(!mob || !mob.loc) - return FALSE - if(!n || !direct) + if(!n || !direction || !mob?.loc) return FALSE + //GET RID OF THIS SOON AS MOBILITY FLAGS IS DONE if(mob.notransform) - return FALSE //This is sota the goto stop mobs from moving var + return FALSE + if(mob.control_object) - return Move_object(direct) + return Move_object(direction) if(!isliving(mob)) - return mob.Move(n, direct) + return mob.Move(n, direction) if(mob.stat == DEAD) mob.ghostize() return FALSE @@ -48,29 +47,29 @@ var/mob/living/L = mob //Already checked for isliving earlier if(L.incorporeal_move) //Move though walls - Process_Incorpmove(direct) + Process_Incorpmove(direction) return FALSE if(mob.remote_control) //we're controlling something, our movement is relayed to it - return mob.remote_control.relaymove(mob, direct) + return mob.remote_control.relaymove(mob, direction) if(isAI(mob)) - return AIMove(n,direct,mob) + return AIMove(n,direction,mob) if(Process_Grab()) //are we restrained by someone's grip? return if(mob.buckled) //if we're buckled to something, tell it we moved. - return mob.buckled.relaymove(mob, direct) + return mob.buckled.relaymove(mob, direction) if(!mob.canmove) return FALSE if(isobj(mob.loc) || ismob(mob.loc)) //Inside an object, tell it we moved var/atom/O = mob.loc - return O.relaymove(mob, direct) + return O.relaymove(mob, direction) - if(!mob.Process_Spacemove(direct)) + if(!mob.Process_Spacemove(direction)) return FALSE //We are now going to move var/add_delay = mob.movement_delay() @@ -85,16 +84,16 @@ if(L.confused > 40) newdir = pick(GLOB.alldirs) else if(prob(L.confused * 1.5)) - newdir = angle2dir(dir2angle(direct) + pick(90, -90)) + newdir = angle2dir(dir2angle(direction) + pick(90, -90)) else if(prob(L.confused * 3)) - newdir = angle2dir(dir2angle(direct) + pick(45, -45)) + newdir = angle2dir(dir2angle(direction) + pick(45, -45)) if(newdir) - direct = newdir - n = get_step(L, direct) + direction = newdir + n = get_step(L, direction) . = ..() - if((direct & (direct - 1)) && mob.loc == n) //moved diagonally successfully + if((direction & (direction - 1)) && mob.loc == n) //moved diagonally successfully add_delay *= 2 move_delay += add_delay if(.) // If mob is null here, we deserve the runtime @@ -102,7 +101,7 @@ mob.throwing.finalize(FALSE) for(var/obj/O in mob.user_movement_hooks) - O.intercept_user_move(direct, mob, n, oldloc) + O.intercept_user_move(direction, mob, n, oldloc) var/atom/movable/P = mob.pulling if(P && !ismob(P) && P.density) @@ -126,22 +125,22 @@ ///Process_Incorpmove ///Called by client/Move() ///Allows mobs to run though walls -/client/proc/Process_Incorpmove(direct) +/client/proc/Process_Incorpmove(direction) var/turf/mobloc = get_turf(mob) if(!isliving(mob)) return var/mob/living/L = mob switch(L.incorporeal_move) if(INCORPOREAL_MOVE_BASIC) - var/T = get_step(L,direct) + var/T = get_step(L,direction) if(T) L.forceMove(T) - L.setDir(direct) + L.setDir(direction) if(INCORPOREAL_MOVE_SHADOW) if(prob(50)) var/locx var/locy - switch(direct) + switch(direction) if(NORTH) locx = mobloc.x locy = (mobloc.y+2) @@ -175,12 +174,12 @@ break else new /obj/effect/temp_visual/dir_setting/ninja/shadow(mobloc, L.dir) - var/T = get_step(L,direct) + var/T = get_step(L,direction) if(T) L.forceMove(T) - L.setDir(direct) + L.setDir(direction) if(INCORPOREAL_MOVE_JAUNT) //Incorporeal move, but blocked by holy-watered tiles and salt piles. - var/turf/open/floor/stepTurf = get_step(L, direct) + var/turf/open/floor/stepTurf = get_step(L, direction) if(stepTurf) for(var/obj/effect/decal/cleanable/salt/S in stepTurf) to_chat(L, "[S] bars your passage!") @@ -197,7 +196,7 @@ return L.forceMove(stepTurf) - L.setDir(direct) + L.setDir(direction) return TRUE 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/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 += "
    \n
    Security 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
    \n
    Comments/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 += "
    \n
    Medical 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
    \n
    Comments/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/power/apc.dm b/code/modules/power/apc.dm index 3f92fc573b..0326486032 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/gun.dm b/code/modules/projectiles/gun.dm index 531c6082b0..fe5c4a1bbf 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -237,7 +237,7 @@ sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread), 1) else //Smart spread sprd = round((((rand_spr/burst_size) * iteration) - (0.5 + (rand_spr * 0.25))) * (randomized_gun_spread + randomized_bonus_spread), 1) - + before_firing(target,user) if(!chambered.fire_casing(target, user, params, ,suppressed, zone_override, sprd, src)) shoot_with_empty_chamber(user) firing_burst = FALSE @@ -281,6 +281,7 @@ else if(chambered) sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread)) + before_firing(target,user) if(!chambered.fire_casing(target, user, params, , suppressed, zone_override, sprd, src)) shoot_with_empty_chamber(user) return @@ -466,6 +467,10 @@ qdel(pin) pin = new /obj/item/firing_pin +//Happens before the actual projectile creation +/obj/item/gun/proc/before_firing(atom/target,mob/user) + return + ///////////// // ZOOMING // ///////////// 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/dueling.dm b/code/modules/projectiles/guns/energy/dueling.dm new file mode 100644 index 0000000000..b1d7ab7166 --- /dev/null +++ b/code/modules/projectiles/guns/energy/dueling.dm @@ -0,0 +1,375 @@ +#define DUEL_IDLE 1 +#define DUEL_PREPARATION 2 +#define DUEL_READY 3 +#define DUEL_COUNTDOWN 4 +#define DUEL_FIRING 5 + +//paper rock scissors +#define DUEL_SETTING_A "wide" +#define DUEL_SETTING_B "cone" +#define DUEL_SETTING_C "pinpoint" + +#define DUEL_HUGBOX_NONE 0 //dismember head +#define DUEL_HUGBOX_LETHAL 1 //200 damage to chest +#define DUEL_HUGBOX_NONLETHAL 2 //stamcrit + +/datum/duel + var/obj/item/gun/energy/dueling/gun_A + var/obj/item/gun/energy/dueling/gun_B + var/state = DUEL_IDLE + var/required_distance = 5 + var/list/confirmations = list() + var/list/fired = list() + var/countdown_length = 10 + var/countdown_step = 0 + +/datum/duel/proc/try_begin() + //Check if both guns are held and if so begin. + var/mob/living/A = get_duelist(gun_A) + var/mob/living/B = get_duelist(gun_B) + if(!A || !B) + message_duelists("To begin the duel, both participants need to be holding paired dueling pistols.") + return + begin() + +/datum/duel/proc/begin() + state = DUEL_PREPARATION + confirmations.Cut() + fired.Cut() + countdown_step = countdown_length + + message_duelists("Set your gun setting and move [required_distance] steps away from your opponent.") + + START_PROCESSING(SSobj,src) + +/datum/duel/proc/get_duelist(obj/gun) + var/mob/living/G = gun.loc + if(!istype(G) || !G.is_holding(gun)) + return null + return G + +/datum/duel/proc/message_duelists(message) + var/mob/living/LA = get_duelist(gun_A) + if(LA) + to_chat(LA,message) + var/mob/living/LB = get_duelist(gun_B) + if(LB) + to_chat(LB,message) + +/datum/duel/proc/other_gun(obj/item/gun/energy/dueling/G) + return G == gun_A ? gun_B : gun_A + +/datum/duel/proc/end() + message_duelists("Duel finished. Re-engaging safety.") + STOP_PROCESSING(SSobj,src) + state = DUEL_IDLE + +/datum/duel/process() + switch(state) + if(DUEL_PREPARATION) + if(check_positioning()) + confirm_positioning() + else if (!get_duelist(gun_A) && !get_duelist(gun_B)) + end() + if(DUEL_READY) + if(!check_positioning()) + back_to_prep() + else if(confirmations.len == 2) + confirm_ready() + if(DUEL_COUNTDOWN) + if(!check_positioning()) + back_to_prep() + else + countdown_step() + if(DUEL_FIRING) + if(check_fired()) + end() + +/datum/duel/proc/back_to_prep() + message_duelists("Positions invalid. Please move to valid positions [required_distance] steps aways from each other to continue.") + state = DUEL_PREPARATION + confirmations.Cut() + countdown_step = countdown_length + +/datum/duel/proc/confirm_positioning() + message_duelists("Position confirmed. Confirm readiness by pulling the trigger once.") + state = DUEL_READY + +/datum/duel/proc/confirm_ready() + message_duelists("Readiness confirmed. Starting countdown. Commence firing at zero mark.") + state = DUEL_COUNTDOWN + +/datum/duel/proc/countdown_step() + countdown_step-- + if(countdown_step == 0) + state = DUEL_FIRING + message_duelists("Fire!") + else + message_duelists("[countdown_step]!") + +/datum/duel/proc/check_fired() + if(fired.len == 2) + return TRUE + //Let's say if gun was dropped/stowed the user is finished + if(!get_duelist(gun_A)) + return TRUE + if(!get_duelist(gun_B)) + return TRUE + return FALSE + +/datum/duel/proc/check_positioning() + var/mob/living/A = get_duelist(gun_A) + var/mob/living/B = get_duelist(gun_B) + if(!A || !B) + return FALSE + if(!isturf(A.loc) || !isturf(B.loc)) + return FALSE + if(get_dist(A,B) != required_distance) + return FALSE + for(var/turf/T in getline(get_turf(A),get_turf(B))) + if(is_blocked_turf(T,TRUE)) + return FALSE + return TRUE + +/obj/item/gun/energy/dueling + name = "dueling pistol" + desc = "High-tech dueling pistol. Launches chaff and projectile according to preset settings." + icon_state = "dueling_pistol" + item_state = "gun" + ammo_x_offset = 2 + w_class = WEIGHT_CLASS_SMALL + ammo_type = list(/obj/item/ammo_casing/energy/duel) + automatic_charge_overlays = FALSE + var/unlocked = FALSE + var/setting = DUEL_SETTING_A + var/datum/duel/duel + var/mutable_appearance/setting_overlay + var/hugbox = DUEL_HUGBOX_NONE + +/obj/item/gun/energy/dueling/hugbox + hugbox = DUEL_HUGBOX_LETHAL + +/obj/item/gun/energy/dueling/hugbox/stamina + hugbox = DUEL_HUGBOX_NONLETHAL + +/obj/item/gun/energy/dueling/Initialize() + . = ..() + setting_overlay = mutable_appearance(icon,setting_iconstate()) + add_overlay(setting_overlay) + +/obj/item/gun/energy/dueling/proc/setting_iconstate() + switch(setting) + if(DUEL_SETTING_A) + return "duel_red" + if(DUEL_SETTING_B) + return "duel_green" + if(DUEL_SETTING_C) + return "duel_blue" + return "duel_red" + +/obj/item/gun/energy/dueling/attack_self(mob/living/user) + . = ..() + if(duel.state == DUEL_IDLE) + duel.try_begin() + else + toggle_setting(user) + +/obj/item/gun/energy/dueling/proc/toggle_setting(mob/living/user) + switch(setting) + if(DUEL_SETTING_A) + setting = DUEL_SETTING_B + if(DUEL_SETTING_B) + setting = DUEL_SETTING_C + if(DUEL_SETTING_C) + setting = DUEL_SETTING_A + to_chat(user,"You switch [src] setting to [setting] mode.") + update_icon() + +/obj/item/gun/energy/dueling/update_icon(force_update) + . = ..() + if(setting_overlay) + cut_overlay(setting_overlay) + setting_overlay.icon_state = setting_iconstate() + add_overlay(setting_overlay) + +/obj/item/gun/energy/dueling/Destroy() + . = ..() + if(duel.gun_A == src) + duel.gun_A = null + if(duel.gun_B == src) + duel.gun_B = null + duel = null + +/obj/item/gun/energy/dueling/can_trigger_gun(mob/living/user) + . = ..() + switch(duel.state) + if(DUEL_FIRING) + return . && !duel.fired[src] + if(DUEL_READY) + return . + else + to_chat(user,"[src] is locked. Wait for FIRE signal before shooting.") + return FALSE + +/obj/item/gun/energy/dueling/proc/is_duelist(mob/living/L) + if(!istype(L)) + return FALSE + if(!L.is_holding(duel.other_gun(src))) + return FALSE + return TRUE + +/obj/item/gun/energy/dueling/process_fire(atom/target, mob/living/user, message, params, zone_override, bonus_spread) + if(duel.state == DUEL_READY) + duel.confirmations[src] = TRUE + to_chat(user,"You confirm your readiness.") + return + else if(!is_duelist(target)) //I kinda want to leave this out just to see someone shoot a bystander or missing. + to_chat(user,"[src] safety system prevents shooting anyone but your designated opponent.") + return + else + duel.fired[src] = TRUE + . = ..() + +/obj/item/gun/energy/dueling/before_firing(target,user) + var/obj/item/ammo_casing/energy/duel/D = chambered + D.setting = setting + D.hugbox = hugbox + +/obj/effect/temp_visual/dueling_chaff + icon = 'icons/effects/effects.dmi' + icon_state = "shield-old" + duration = 30 + var/setting + +/obj/effect/temp_visual/dueling_chaff/update_icon() + . = ..() + switch(setting) + if(DUEL_SETTING_A) + color = "red" + if(DUEL_SETTING_B) + color = "green" + if(DUEL_SETTING_C) + color = "blue" + +//Casing + +/obj/item/ammo_casing/energy/duel + e_cost = 0 + projectile_type = /obj/item/projectile/energy/duel + var/setting + var/hugbox = DUEL_HUGBOX_NONE + +/obj/item/ammo_casing/energy/duel/ready_proj(atom/target, mob/living/user, quiet, zone_override) + . = ..() + var/obj/item/projectile/energy/duel/D = BB + D.setting = setting + D.hugbox = hugbox + D.update_icon() + +/obj/item/ammo_casing/energy/duel/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread, atom/fired_from) + . = ..() + var/obj/effect/temp_visual/dueling_chaff/C = new(get_turf(user)) + C.setting = setting + C.update_icon() + +//Projectile + +/obj/item/projectile/energy/duel + name = "dueling beam" + icon_state = "declone" + is_reflectable = FALSE + homing = TRUE + var/setting + var/hugbox = DUEL_HUGBOX_NONE + +/obj/item/projectile/energy/duel/update_icon() + . = ..() + switch(setting) + if(DUEL_SETTING_A) + color = "red" + if(DUEL_SETTING_B) + color = "green" + if(DUEL_SETTING_C) + color = "blue" + +/obj/item/projectile/energy/duel/on_hit(atom/target, blocked) + . = ..() + var/turf/T = get_turf(target) + var/obj/effect/temp_visual/dueling_chaff/C = locate() in T + if(C) + var/counter_setting + switch(setting) + if(DUEL_SETTING_A) + counter_setting = DUEL_SETTING_B + if(DUEL_SETTING_B) + counter_setting = DUEL_SETTING_C + if(DUEL_SETTING_C) + counter_setting = DUEL_SETTING_A + if(C.setting == counter_setting) + return BULLET_ACT_BLOCK + + var/mob/living/L = target + if(!istype(target)) + return BULLET_ACT_BLOCK + + switch(hugbox) + if(DUEL_HUGBOX_NONE) + var/obj/item/bodypart/B = L.get_bodypart(BODY_ZONE_HEAD) + B.dismember() + qdel(B) + if(DUEL_HUGBOX_LETHAL) + L.adjustBruteLoss(180) + L.death() //Die, powergamers. + if(DUEL_HUGBOX_NONLETHAL) + L.adjustStaminaLoss(200, forced = TRUE) //Die, powergamers x 2 + L.Knockdown(100, override_hardstun = 100) //For good measure. + +//Storage case. +/obj/item/storage/lockbox/dueling + name = "dueling pistol case" + desc = "Let's solve this like gentlespacemen." + icon_state = "medalbox+l" + item_state = "syringe_kit" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + w_class = WEIGHT_CLASS_NORMAL + req_access = list(ACCESS_CAPTAIN) + icon_locked = "medalbox+l" + icon_closed = "medalbox" + icon_broken = "medalbox+b" + var/gun_type = /obj/item/gun/energy/dueling + +/obj/item/storage/lockbox/dueling/ComponentInitialize() + . = ..() + var/datum/component/storage/STR = GetComponent(/datum/component/storage) + STR.max_w_class = WEIGHT_CLASS_SMALL + STR.max_items = 2 + STR.can_hold = typecacheof(/obj/item/gun/energy/dueling) + +/obj/item/storage/lockbox/dueling/update_icon() + cut_overlays() + var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED) + if(locked) + icon_state = "medalbox+l" + else + icon_state = "medalbox" + if(open) + icon_state += "open" + if(broken) + icon_state += "+b" + +/obj/item/storage/lockbox/dueling/PopulateContents() + . = ..() + var/obj/item/gun/energy/dueling/gun_A = new gun_type(src) + var/obj/item/gun/energy/dueling/gun_B = new gun_type(src) + var/datum/duel/D = new + gun_A.duel = D + gun_B.duel = D + D.gun_A = gun_A + D.gun_B = gun_B + +/obj/item/storage/lockbox/dueling/hugbox + gun_type = /obj/item/gun/energy/dueling/hugbox + +/obj/item/storage/lockbox/dueling/hugbox/stamina + gun_type = /obj/item/gun/energy/dueling/hugbox/stamina 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 f5db2e8c40..44148c85a7 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 e08fba604d..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" 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("