diff --git a/_maps/RandomRooms/10x10/sk_rdm133_oldoffice.dmm b/_maps/RandomRooms/10x10/sk_rdm133_oldoffice.dmm index 8cbe46e0e8763..d277af8357646 100644 --- a/_maps/RandomRooms/10x10/sk_rdm133_oldoffice.dmm +++ b/_maps/RandomRooms/10x10/sk_rdm133_oldoffice.dmm @@ -31,7 +31,7 @@ /turf/open/floor/plating, /area/template_noop) "g" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/plating, /area/template_noop) "h" = ( diff --git a/_maps/RandomRooms/10x5/sk_rdm045_deltacafeteria.dmm b/_maps/RandomRooms/10x5/sk_rdm045_deltacafeteria.dmm index 7e07e671dc62d..d7e9f12af0d93 100644 --- a/_maps/RandomRooms/10x5/sk_rdm045_deltacafeteria.dmm +++ b/_maps/RandomRooms/10x5/sk_rdm045_deltacafeteria.dmm @@ -129,7 +129,7 @@ /turf/open/floor/plasteel, /area/template_noop) "J" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/decal/cleanable/cobweb, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, /turf/open/floor/plasteel/dark, @@ -190,7 +190,7 @@ /turf/open/floor/plasteel/white, /area/template_noop) "S" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, /turf/open/floor/plasteel/dark, diff --git a/_maps/RandomRooms/10x5/sk_rdm161_kilovault.dmm b/_maps/RandomRooms/10x5/sk_rdm161_kilovault.dmm index 0c3480538a6ae..6f1b3039482a3 100644 --- a/_maps/RandomRooms/10x5/sk_rdm161_kilovault.dmm +++ b/_maps/RandomRooms/10x5/sk_rdm161_kilovault.dmm @@ -280,7 +280,7 @@ "hm" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/bot, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/stripes/corner{ dir = 8 }, diff --git a/_maps/RandomRooms/5x3/sk_rdm101_minibreakroom.dmm b/_maps/RandomRooms/5x3/sk_rdm101_minibreakroom.dmm index 721dafef15d56..25386dcedf979 100644 --- a/_maps/RandomRooms/5x3/sk_rdm101_minibreakroom.dmm +++ b/_maps/RandomRooms/5x3/sk_rdm101_minibreakroom.dmm @@ -1,12 +1,12 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( /obj/effect/decal/cleanable/dirt, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/plasteel, /area/template_noop) "b" = ( /obj/effect/decal/cleanable/dirt, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/machinery/light/small{ dir = 1 }, diff --git a/_maps/RandomRooms/fland/sk_rdm_fln_03_vendingminimarket.dmm b/_maps/RandomRooms/fland/sk_rdm_fln_03_vendingminimarket.dmm index 4f3db23bd5f22..609be7f01ceff 100644 --- a/_maps/RandomRooms/fland/sk_rdm_fln_03_vendingminimarket.dmm +++ b/_maps/RandomRooms/fland/sk_rdm_fln_03_vendingminimarket.dmm @@ -3,7 +3,7 @@ /turf/closed/wall, /area/template_noop) "b" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/yellow{ dir = 4 @@ -266,7 +266,7 @@ }, /area/template_noop) "S" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/machinery/light{ dir = 8 }, diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm index babc68c68cc13..5b86d86acac37 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm @@ -525,7 +525,7 @@ "bG" = ( /obj/machinery/computer/shuttle_flight{ dir = 4; - icon_state = "computer" + icon_state = "computer-0" }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/carpet/purple, @@ -661,7 +661,7 @@ "ce" = ( /obj/machinery/computer/monitor/secret{ dir = 1; - icon_state = "computer" + icon_state = "computer-0" }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/pod/dark, @@ -699,7 +699,7 @@ "ck" = ( /obj/machinery/computer/operating{ dir = 4; - icon_state = "computer" + icon_state = "computer-0" }, /turf/open/floor/pod/dark, /area/ruin/powered/golem_ship) diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm index 362ad815f9f84..77109279a7cd1 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm @@ -497,7 +497,7 @@ "wa" = ( /obj/machinery/computer/shuttle_flight{ dir = 4; - icon_state = "computer" + icon_state = "computer-0" }, /turf/open/floor/pod/light, /area/ruin/powered/seedvault) @@ -1079,7 +1079,7 @@ "Po" = ( /obj/machinery/computer/monitor/secret{ dir = 4; - icon_state = "computer" + icon_state = "computer-0" }, /turf/open/floor/pod/light, /area/ruin/powered/seedvault) diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm index 869afaec6e76d..d2ce56022a547 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm @@ -203,7 +203,9 @@ /turf/open/floor/plasteel/dark, /area/ruin/unpowered/syndicate_lava_base/telecomms) "bt" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola{ + hacked = 1 + }, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 @@ -4521,7 +4523,9 @@ /turf/open/floor/plasteel, /area/ruin/unpowered/syndicate_lava_base/cargo) "xu" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack{ + hacked = 1 + }, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/red/anticorner/contrasted{ diff --git a/_maps/RandomRuins/SpaceRuins/Fast_Food.dmm b/_maps/RandomRuins/SpaceRuins/Fast_Food.dmm index 82374d1978269..bde56382bca93 100644 --- a/_maps/RandomRuins/SpaceRuins/Fast_Food.dmm +++ b/_maps/RandomRuins/SpaceRuins/Fast_Food.dmm @@ -715,7 +715,7 @@ /turf/open/floor/plasteel/cafeteria, /area/ruin/space/has_grav/powered/macspace) "cK" = ( -/obj/item/reagent_containers/food/snacks/burrito, +/obj/item/food/burrito, /obj/structure/table/wood/fancy/blue, /turf/open/floor/plasteel/cafeteria, /area/ruin/space/has_grav/powered/macspace) @@ -731,7 +731,7 @@ /turf/open/floor/plasteel/cafeteria, /area/ruin/space/has_grav/powered/macspace) "cO" = ( -/obj/item/reagent_containers/food/snacks/carneburrito, +/obj/item/food/carneburrito, /obj/structure/table/wood/fancy/blue, /turf/open/floor/plasteel/cafeteria, /area/ruin/space/has_grav/powered/macspace) diff --git a/_maps/RandomRuins/SpaceRuins/clownplanet.dmm b/_maps/RandomRuins/SpaceRuins/clownplanet.dmm index 57c2635a55787..ba0ca2ea286cc 100644 --- a/_maps/RandomRuins/SpaceRuins/clownplanet.dmm +++ b/_maps/RandomRuins/SpaceRuins/clownplanet.dmm @@ -346,7 +346,7 @@ /turf/open/floor/bluespace, /area/ruin/powered/clownplanet) "bh" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/stripes/white/box, /turf/open/floor/bluespace, /area/ruin/powered/clownplanet) @@ -360,7 +360,7 @@ }, /area/ruin/powered/clownplanet) "bk" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/stripes/white/box, /turf/open/floor/bluespace, /area/ruin/powered/clownplanet) diff --git a/_maps/RandomRuins/SpaceRuins/listeningstation.dmm b/_maps/RandomRuins/SpaceRuins/listeningstation.dmm index f4629a0669545..d97d88637250e 100644 --- a/_maps/RandomRuins/SpaceRuins/listeningstation.dmm +++ b/_maps/RandomRuins/SpaceRuins/listeningstation.dmm @@ -322,7 +322,7 @@ /turf/open/floor/plasteel, /area/ruin/space/has_grav/listeningstation) "aY" = ( -/obj/effect/spawner/randomsnackvend{ +/obj/effect/spawner/randomvend/snack{ hacked = 1 }, /obj/effect/decal/cleanable/dirt, @@ -405,7 +405,7 @@ /turf/open/floor/plasteel/white/side, /area/ruin/space/has_grav/listeningstation) "bh" = ( -/obj/effect/spawner/randomcolavend{ +/obj/effect/spawner/randomvend/cola{ hacked = 1 }, /obj/effect/decal/cleanable/dirt, diff --git a/_maps/RandomZLevels/TheBeach.dmm b/_maps/RandomZLevels/TheBeach.dmm index 1851ecdb01378..5911997c41f0e 100644 --- a/_maps/RandomZLevels/TheBeach.dmm +++ b/_maps/RandomZLevels/TheBeach.dmm @@ -747,7 +747,7 @@ /area/awaymission/beach) "ce" = ( /obj/effect/turf_decal/sand, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/plating/beach/sand, /area/awaymission/beach) "cf" = ( diff --git a/_maps/RandomZLevels/snowdin.dmm b/_maps/RandomZLevels/snowdin.dmm index e9973ba5bf2f0..e8b4806168efa 100644 --- a/_maps/RandomZLevels/snowdin.dmm +++ b/_maps/RandomZLevels/snowdin.dmm @@ -12412,7 +12412,7 @@ /turf/open/floor/plasteel, /area/awaymission/snowdin/post/mining_dock) "PO" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, /turf/open/floor/plasteel, /area/awaymission/snowdin/post/research) @@ -12735,7 +12735,7 @@ /turf/open/floor/plasteel/dark, /area/awaymission/snowdin/cave) "RD" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, /turf/open/floor/plasteel, /area/awaymission/snowdin/post/research) diff --git a/_maps/RuinGeneration/13x13_ai-lab.dmm b/_maps/RuinGeneration/13x13_ai-lab.dmm index 8566903aa4e3a..a39a1b500a593 100644 --- a/_maps/RuinGeneration/13x13_ai-lab.dmm +++ b/_maps/RuinGeneration/13x13_ai-lab.dmm @@ -130,9 +130,6 @@ /area/ruin/unpowered) "tD" = ( /obj/effect/abstract/doorway_marker, -/obj/machinery/door/airlock/grunge{ - name = "Artificial Intelligence research" - }, /turf/open/floor/plasteel/tech/grid, /area/ruin/unpowered) "tJ" = ( diff --git a/_maps/RuinGeneration/13x13_corgrobotics.dmm b/_maps/RuinGeneration/13x13_corgrobotics.dmm index 516ff2e23b4b4..b3c70b525cef1 100644 --- a/_maps/RuinGeneration/13x13_corgrobotics.dmm +++ b/_maps/RuinGeneration/13x13_corgrobotics.dmm @@ -82,9 +82,7 @@ /turf/open/floor/plasteel/dark, /area/ruin/unpowered) "j" = ( -/obj/machinery/door/firedoor/border_only{ - dir = 8 - }/obj/effect/turf_decal/stripes/line{ +/obj/effect/turf_decal/stripes/line{ dir = 4 }, /obj/effect/turf_decal/stripes/line{ diff --git a/_maps/RuinGeneration/13x13_donutroom.dmm b/_maps/RuinGeneration/13x13_donutroom.dmm index 9fee02a715eda..e30f1792da350 100644 --- a/_maps/RuinGeneration/13x13_donutroom.dmm +++ b/_maps/RuinGeneration/13x13_donutroom.dmm @@ -4,7 +4,7 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "k" = ( -/obj/structure/chair/comfy, +/obj/structure/chair/fancy/comfy, /turf/open/floor/plasteel, /area/ruin/unpowered) "o" = ( @@ -16,7 +16,7 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "u" = ( -/obj/structure/chair/comfy{ +/obj/structure/chair/fancy/comfy{ dir = 1 }, /turf/open/floor/plasteel, @@ -31,7 +31,7 @@ /turf/template_noop, /area/template_noop) "G" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/plasteel, /area/ruin/unpowered) "J" = ( @@ -43,7 +43,7 @@ /turf/template_noop, /area/template_noop) "Q" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/plasteel, /area/ruin/unpowered) "R" = ( diff --git a/_maps/RuinGeneration/13x13_listening_base.dmm b/_maps/RuinGeneration/13x13_listening_base.dmm index 6a249a9cf61cf..1962dbeda488e 100644 --- a/_maps/RuinGeneration/13x13_listening_base.dmm +++ b/_maps/RuinGeneration/13x13_listening_base.dmm @@ -17,7 +17,7 @@ /turf/open/floor/plasteel/dark, /area/ruin/space/has_grav/listeningstation) "cX" = ( -/obj/effect/spawner/randomsnackvend{ +/obj/effect/spawner/randomvend/snack{ hacked = 1 }, /obj/effect/decal/cleanable/dirt, @@ -39,7 +39,6 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4; - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -96,7 +95,6 @@ }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4; - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -156,7 +154,6 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4; - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -210,7 +207,6 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -229,7 +225,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4; - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -245,7 +240,6 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4; - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -274,7 +268,6 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4; - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -302,8 +295,6 @@ "rx" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2; - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -399,14 +390,13 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6; - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, /turf/open/floor/plasteel, /area/ruin/space/has_grav/listeningstation) "xC" = ( -/obj/effect/spawner/randomcolavend{ +/obj/effect/spawner/randomvend/cola{ hacked = 1 }, /obj/effect/decal/cleanable/dirt, @@ -418,7 +408,6 @@ "xP" = ( /obj/structure/table/reinforced, /obj/machinery/firealarm{ - dir = 2; pixel_y = 24 }, /obj/effect/decal/cleanable/dirt, @@ -454,7 +443,6 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -471,7 +459,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10; - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -553,7 +540,6 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4; - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -621,7 +607,6 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4; - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -641,7 +626,6 @@ dir = 1 }, /obj/machinery/firealarm{ - dir = 2; pixel_y = 24 }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -649,7 +633,6 @@ }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1; - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -662,7 +645,6 @@ /obj/structure/chair/stool, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4; - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -732,7 +714,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9; - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -745,7 +726,6 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -763,7 +743,6 @@ }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8; - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -852,7 +831,6 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -874,7 +852,6 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5; - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -883,7 +860,6 @@ "XB" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -894,7 +870,6 @@ /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, @@ -914,9 +889,7 @@ /turf/open/floor/plasteel, /area/ruin/space/has_grav/listeningstation) "YS" = ( -/obj/machinery/computer/message_monitor{ - dir = 2 - }, +/obj/machinery/computer/message_monitor, /obj/machinery/airalarm/syndicate{ pixel_y = 24 }, @@ -934,7 +907,6 @@ "Zp" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1; - piping_layer = 3; pixel_x = 5; pixel_y = 5 }, diff --git a/_maps/RuinGeneration/13x13_shotelroom.dmm b/_maps/RuinGeneration/13x13_shotelroom.dmm index ae44e142ffb7f..78beb6efbe922 100644 --- a/_maps/RuinGeneration/13x13_shotelroom.dmm +++ b/_maps/RuinGeneration/13x13_shotelroom.dmm @@ -175,7 +175,7 @@ /turf/open/floor/wood, /area/ruin/unpowered) "L" = ( -/obj/structure/chair/comfy/black, +/obj/structure/chair/fancy/corp, /turf/open/floor/carpet/orange, /area/ruin/unpowered) "M" = ( @@ -195,7 +195,7 @@ /turf/open/floor/wood, /area/ruin/unpowered) "P" = ( -/obj/structure/chair/comfy/black{ +/obj/structure/chair/fancy/corp{ dir = 1 }, /turf/open/floor/carpet/orange, diff --git a/_maps/RuinGeneration/13x17_chapel.dmm b/_maps/RuinGeneration/13x17_chapel.dmm index 8e26afd259c99..804c90a3559c4 100644 --- a/_maps/RuinGeneration/13x17_chapel.dmm +++ b/_maps/RuinGeneration/13x17_chapel.dmm @@ -18,13 +18,13 @@ /turf/open/floor/plasteel/dark, /area/ruin/unpowered) "fw" = ( -/obj/structure/chair/pew{ +/obj/structure/chair/fancy/bench/pew{ dir = 1 }, /turf/open/floor/plasteel/chapel, /area/ruin/unpowered) "fx" = ( -/obj/structure/chair/pew/right{ +/obj/structure/chair/fancy/bench/pew/left{ dir = 1 }, /turf/open/floor/plasteel/chapel{ @@ -32,7 +32,7 @@ }, /area/ruin/unpowered) "gk" = ( -/obj/structure/chair/pew/right{ +/obj/structure/chair/fancy/bench/pew/left{ dir = 1 }, /turf/open/floor/plasteel/chapel{ @@ -102,7 +102,7 @@ /turf/open/floor/plasteel/dark, /area/ruin/unpowered) "qg" = ( -/obj/structure/chair/pew{ +/obj/structure/chair/fancy/bench/pew{ dir = 1 }, /turf/open/floor/plasteel/chapel{ @@ -142,7 +142,7 @@ /turf/open/floor/plasteel/dark, /area/ruin/unpowered) "rW" = ( -/obj/structure/chair/pew{ +/obj/structure/chair/fancy/bench/pew{ dir = 1 }, /turf/open/floor/plasteel/chapel{ @@ -205,7 +205,7 @@ /turf/open/floor/grass/fakebasalt, /area/ruin/unpowered) "Gz" = ( -/obj/structure/chair/pew/left{ +/obj/structure/chair/fancy/bench/pew/right{ dir = 1 }, /turf/open/floor/plasteel/chapel{ @@ -246,7 +246,7 @@ }, /area/ruin/unpowered) "Ni" = ( -/obj/structure/chair/pew/right{ +/obj/structure/chair/fancy/bench/pew/left{ dir = 1 }, /turf/open/floor/plasteel/chapel, @@ -267,7 +267,7 @@ /turf/open/floor/plasteel/dark, /area/ruin/unpowered) "Ry" = ( -/obj/structure/chair/pew{ +/obj/structure/chair/fancy/bench/pew{ dir = 1 }, /turf/open/floor/plasteel/chapel{ @@ -275,7 +275,7 @@ }, /area/ruin/unpowered) "TA" = ( -/obj/structure/chair/pew/left{ +/obj/structure/chair/fancy/bench/pew/right{ dir = 1 }, /turf/open/floor/plasteel/chapel{ @@ -283,7 +283,7 @@ }, /area/ruin/unpowered) "TD" = ( -/obj/structure/chair/pew/left{ +/obj/structure/chair/fancy/bench/pew/right{ dir = 1 }, /turf/open/floor/plasteel/chapel{ @@ -291,7 +291,7 @@ }, /area/ruin/unpowered) "UA" = ( -/obj/structure/chair/pew/right{ +/obj/structure/chair/fancy/bench/pew/left{ dir = 1 }, /turf/open/floor/plasteel/chapel{ @@ -306,7 +306,7 @@ /turf/open/floor/grass/fakebasalt, /area/ruin/unpowered) "Yh" = ( -/obj/structure/chair/pew/left{ +/obj/structure/chair/fancy/bench/pew/right{ dir = 1 }, /turf/open/floor/plasteel/chapel{ diff --git a/_maps/RuinGeneration/13x17_permabrig.dmm b/_maps/RuinGeneration/13x17_permabrig.dmm index 08f874bedbabb..4e500047f993e 100644 --- a/_maps/RuinGeneration/13x17_permabrig.dmm +++ b/_maps/RuinGeneration/13x17_permabrig.dmm @@ -8,6 +8,13 @@ "aW" = ( /turf/template_noop, /area/template_noop) +"bv" = ( +/obj/structure/chair/stool{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/unpowered) "bO" = ( /turf/open/floor/plasteel, /area/ruin/unpowered) @@ -18,7 +25,7 @@ /area/ruin/unpowered) "dn" = ( /obj/effect/decal/cleanable/dirt, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/plasteel, /area/ruin/unpowered) "dG" = ( @@ -40,6 +47,13 @@ }, /turf/open/floor/plasteel/freezer, /area/ruin/unpowered) +"gN" = ( +/obj/structure/chair/stool{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/ruin/unpowered) "hq" = ( /obj/structure/table, /obj/item/pen, @@ -519,7 +533,7 @@ KP Nf xe NR -RC +bv NR VL dn @@ -558,7 +572,7 @@ UG vY NR NR -RC +gN NR NR lv @@ -614,7 +628,7 @@ NR jz NR NR -RC +bv NR NR NR diff --git a/_maps/RuinGeneration/13x9_medical.dmm b/_maps/RuinGeneration/13x9_medical.dmm index 1ad23add9d8fa..3107c69fd6b88 100644 --- a/_maps/RuinGeneration/13x9_medical.dmm +++ b/_maps/RuinGeneration/13x9_medical.dmm @@ -30,21 +30,6 @@ }, /turf/open/floor/plasteel/white, /area/ruin/unpowered) -"ag" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/machinery/atmospherics/components/unary/thermomachine/freezer, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "ah" = ( /obj/machinery/atmospherics/pipe/manifold/general/visible, /obj/effect/turf_decal/tile/blue{ @@ -59,15 +44,6 @@ /obj/effect/turf_decal/tile/blue/fourcorners/contrasted, /turf/open/floor/plasteel/white, /area/ruin/unpowered) -"aj" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "ak" = ( /turf/open/floor/plasteel/white, /area/ruin/unpowered) @@ -98,58 +74,12 @@ }, /turf/open/floor/plasteel, /area/ruin/unpowered) -"ap" = ( -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, -/obj/structure/window/reinforced, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "aq" = ( /obj/effect/abstract/doorway_marker{ dir = 1 }, /turf/open/floor/plasteel, /area/ruin/unpowered) -"ar" = ( -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"as" = ( -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"at" = ( -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/structure/closet/crate/freezer/blood, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"au" = ( -/obj/effect/turf_decal/tile/blue, -/obj/structure/table/glass, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/spawner/lootdrop/ruinloot/medical, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "av" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -166,61 +96,12 @@ }, /turf/open/floor/plasteel/white, /area/ruin/unpowered) -"ax" = ( -/obj/effect/turf_decal/tile/blue, -/obj/machinery/sleeper{ - dir = 8 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "ay" = ( /obj/effect/turf_decal/stripes/corner{ dir = 4 }, /turf/open/floor/plasteel, /area/ruin/unpowered) -"az" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/machinery/atmospherics/components/unary/cryo_cell, -/obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"aA" = ( -/obj/effect/turf_decal/tile/blue, -/obj/structure/table/glass, -/obj/item/reagent_containers/glass/bottle/charcoal, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/spawner/lootdrop/ruinloot/medical, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"aB" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/spawner/lootdrop/ruinloot/medical, -/obj/structure/table/glass, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "aC" = ( /obj/structure/closet/crate/freezer/blood, /obj/effect/turf_decal/tile/blue/half/contrasted, @@ -235,14 +116,6 @@ }, /turf/open/floor/plasteel/white, /area/ruin/unpowered) -"aE" = ( -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/stripes/corner, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "aF" = ( /obj/structure/table/glass, /obj/effect/spawner/lootdrop/ruinloot/medical, @@ -263,12 +136,6 @@ }, /turf/open/floor/plasteel/white, /area/ruin/unpowered) -"aI" = ( -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/stripes/line, -/obj/structure/window/reinforced, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "aJ" = ( /obj/structure/table/glass, /obj/item/reagent_containers/glass/beaker/cryoxadone{ @@ -289,37 +156,12 @@ }, /turf/open/floor/plasteel/white, /area/ruin/unpowered) -"aK" = ( -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "aL" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 9 }, /turf/open/floor/plasteel/white, /area/ruin/unpowered) -"aM" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/machinery/atmospherics/components/unary/cryo_cell, -/obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/effect/turf_decal/tile/blue, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "aN" = ( /obj/machinery/atmospherics/components/unary/cryo_cell, /obj/effect/turf_decal/delivery, @@ -367,18 +209,6 @@ /obj/effect/turf_decal/tile/blue, /turf/open/floor/plasteel/white, /area/ruin/unpowered) -"aU" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "aV" = ( /obj/effect/spawner/lootdrop/ruinloot/medical, /obj/structure/table/glass, @@ -393,58 +223,6 @@ /obj/effect/turf_decal/tile/blue/opposingcorners, /turf/open/floor/plasteel/white, /area/ruin/unpowered) -"aX" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/structure/table/glass, -/obj/item/reagent_containers/glass/beaker/cryoxadone{ - pixel_x = 9; - pixel_y = 11 - }, -/obj/item/reagent_containers/glass/beaker/cryoxadone{ - pixel_x = 6; - pixel_y = 5 - }, -/obj/item/wrench/medical{ - pixel_y = 2 - }, -/obj/effect/turf_decal/bot, -/obj/effect/spawner/lootdrop/ruinloot/medical, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"aY" = ( -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"aZ" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/machinery/portable_atmospherics/canister/oxygen, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/delivery, -/obj/machinery/atmospherics/components/unary/portables_connector/visible, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "hM" = ( /obj/effect/turf_decal/tile/blue/opposingcorners, /turf/open/floor/plasteel/white, diff --git a/_maps/RuinGeneration/13x9_researchlab.dmm b/_maps/RuinGeneration/13x9_researchlab.dmm index 0ca2fd67b8bbf..1fb2d79625c6f 100644 --- a/_maps/RuinGeneration/13x9_researchlab.dmm +++ b/_maps/RuinGeneration/13x9_researchlab.dmm @@ -1,38 +1,4 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/machinery/vending/wardrobe/science_wardrobe, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"ab" = ( -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"ac" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/structure/table, -/obj/machinery/cell_charger, -/obj/item/stock_parts/cell/high{ - charge = 100; - maxcharge = 15000 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple, -/turf/open/floor/plasteel, -/area/ruin/unpowered) "ad" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -47,41 +13,6 @@ }, /turf/open/floor/plasteel/white, /area/ruin/unpowered) -"ag" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/structure/table, -/obj/item/disk/tech_disk{ - pixel_x = -2; - pixel_y = -3 - }, -/obj/item/disk/tech_disk{ - pixel_x = -2; - pixel_y = -3 - }, -/obj/item/disk/design_disk, -/obj/machinery/light{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/spawner/lootdrop/ruinloot/science, -/obj/effect/spawner/lootdrop/ruinloot/science, -/turf/open/floor/plasteel, -/area/ruin/unpowered) -"ah" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/ruin/unpowered) "ai" = ( /obj/item/kirbyplants/random, /obj/machinery/light, @@ -96,41 +27,6 @@ }, /turf/open/floor/plasteel/white, /area/ruin/unpowered) -"ak" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/obj/structure/table, -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/item/clothing/glasses/science, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/spawner/lootdrop/ruinloot/science, -/turf/open/floor/plasteel, -/area/ruin/unpowered) -"al" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"am" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "an" = ( /obj/effect/turf_decal/tile/purple/fourcorners/contrasted, /turf/open/floor/plasteel/white, @@ -142,54 +38,13 @@ "ap" = ( /turf/open/floor/plasteel, /area/ruin/unpowered) -"aq" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "ar" = ( /obj/machinery/door/airlock/science, /turf/open/floor/plasteel/white, /area/ruin/unpowered) -"as" = ( -/obj/effect/turf_decal/tile/purple, -/obj/effect/spawner/lootdrop/ruinloot/science, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"at" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/obj/machinery/computer/cargo/request{ - dir = 8 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple, -/turf/open/floor/plasteel, -/area/ruin/unpowered) "au" = ( /turf/closed/wall, /area/ruin/unpowered) -"av" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/obj/machinery/rnd/production/protolathe/department/science, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/ruin/unpowered) "aw" = ( /obj/machinery/door/window/eastleft{ name = "Research and Development Deliveries"; @@ -198,60 +53,12 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/ruin/unpowered) -"ax" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"ay" = ( -/obj/item/kirbyplants/random, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"az" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "aA" = ( /obj/effect/turf_decal/tile/purple{ dir = 4 }, /turf/open/floor/plasteel/white, /area/ruin/unpowered) -"aB" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/rnd/destructive_analyzer, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/ruin/unpowered) "aC" = ( /obj/structure/table, /obj/item/stack/sheet/iron/fifty, @@ -263,120 +70,12 @@ /obj/effect/spawner/lootdrop/ruinloot/science, /turf/open/floor/plasteel/white, /area/ruin/unpowered) -"aE" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/structure/table, -/obj/item/folder/white{ - pixel_x = 4; - pixel_y = 4 - }, -/obj/item/folder/white{ - pixel_x = 4; - pixel_y = 4 - }, -/obj/item/crowbar, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/spawner/lootdrop/ruinloot/science, -/obj/effect/spawner/lootdrop/ruinloot/science, -/turf/open/floor/plasteel, -/area/ruin/unpowered) -"aF" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"aG" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/obj/machinery/rnd/production/circuit_imprinter/department/science, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/ruin/unpowered) -"aH" = ( -/obj/structure/chair/stool, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"aI" = ( -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"aJ" = ( -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"aK" = ( -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"aL" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "aM" = ( /obj/effect/abstract/open_area_marker{ dir = 1 }, /turf/open/floor/plasteel, /area/ruin/unpowered) -"aN" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/obj/structure/table, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/item/hand_labeler, -/obj/effect/spawner/lootdrop/ruinloot/science, -/turf/open/floor/plasteel, -/area/ruin/unpowered) "aO" = ( /turf/open/floor/plasteel/white, /area/ruin/unpowered) @@ -384,72 +83,6 @@ /obj/effect/spawner/lootdrop/ruinloot/important, /turf/open/floor/plasteel/white, /area/ruin/unpowered) -"aQ" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/structure/table, -/obj/structure/window/reinforced, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/item/circuitboard/computer/nanite_chamber_control, -/obj/item/circuitboard/computer/nanite_cloud_controller, -/obj/item/circuitboard/machine/nanite_chamber, -/obj/item/circuitboard/machine/nanite_program_hub, -/obj/effect/spawner/lootdrop/ruinloot/science, -/obj/effect/spawner/lootdrop/ruinloot/science, -/turf/open/floor/plasteel, -/area/ruin/unpowered) -"aR" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"aS" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/ruin/unpowered) -"aT" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"aU" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/obj/structure/chair/stool, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "aV" = ( /obj/structure/table/reinforced, /obj/item/paper_bin, @@ -457,48 +90,6 @@ /obj/machinery/door/firedoor, /turf/open/floor/plasteel/white, /area/ruin/unpowered) -"aW" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/obj/effect/turf_decal/tile/purple, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"aX" = ( -/obj/item/kirbyplants/random, -/obj/machinery/light, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) -"aY" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/computer/rdconsole/core{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/ruin/unpowered) -"aZ" = ( -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/ruin/unpowered) "bh" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 diff --git a/_maps/RuinGeneration/17x17_charliecrew.dmm b/_maps/RuinGeneration/17x17_charliecrew.dmm index c3a6a2e3d8a11..7195a766252ee 100644 --- a/_maps/RuinGeneration/17x17_charliecrew.dmm +++ b/_maps/RuinGeneration/17x17_charliecrew.dmm @@ -368,9 +368,7 @@ /turf/open/floor/plasteel/white, /area/ruin/unpowered) "GF" = ( -/obj/machinery/modular_fabricator/exosuit_fab{ - auto_link = 0 - }, +/obj/machinery/modular_fabricator/exosuit_fab, /obj/effect/turf_decal/tile/purple/anticorner/contrasted{ dir = 4 }, diff --git a/_maps/RuinGeneration/17x9_pubbybridgehall.dmm b/_maps/RuinGeneration/17x9_pubbybridgehall.dmm index 3d347155138e8..138e39f6d94ee 100644 --- a/_maps/RuinGeneration/17x9_pubbybridgehall.dmm +++ b/_maps/RuinGeneration/17x9_pubbybridgehall.dmm @@ -55,7 +55,7 @@ /turf/open/floor/plating, /area/ruin/unpowered) "v" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/stripes/line{ dir = 1 }, diff --git a/_maps/RuinGeneration/21x17_shuttledock.dmm b/_maps/RuinGeneration/21x17_shuttledock.dmm index c8a364480401a..53cd313d289ad 100644 --- a/_maps/RuinGeneration/21x17_shuttledock.dmm +++ b/_maps/RuinGeneration/21x17_shuttledock.dmm @@ -23,11 +23,11 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "q" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/plasteel, /area/ruin/unpowered) "u" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/plasteel, /area/ruin/unpowered) "v" = ( diff --git a/_maps/RuinGeneration/21x21_singularity.dmm b/_maps/RuinGeneration/21x21_singularity.dmm index 36413cb2d2f71..16a76514104dd 100644 --- a/_maps/RuinGeneration/21x21_singularity.dmm +++ b/_maps/RuinGeneration/21x21_singularity.dmm @@ -73,10 +73,6 @@ }, /turf/open/floor/plasteel, /area/ruin) -"N" = ( -/obj/effect/decal/fakelattice, -/turf/template_noop/open, -/area/template_noop) "R" = ( /obj/effect/spawner/structure/window/plasma/reinforced, /turf/open/floor/plating, @@ -240,13 +236,13 @@ c c C t -N +a t -N +a t -N +a t -N +a t C x @@ -262,7 +258,7 @@ c c c R -N +a o t S @@ -270,7 +266,7 @@ S S t o -N +a R E c @@ -308,7 +304,7 @@ c c c R -N +a S a S @@ -316,7 +312,7 @@ S S a S -N +a R E c @@ -354,7 +350,7 @@ c c c R -N +a S a S @@ -362,7 +358,7 @@ S S a S -N +a R E c @@ -400,7 +396,7 @@ c c c R -N +a o t S @@ -408,7 +404,7 @@ S S t o -N +a R E c @@ -424,13 +420,13 @@ c c C t -N +a t -N +a t -N +a t -N +a t C x diff --git a/_maps/RuinGeneration/41x41_corgasteroid.dmm b/_maps/RuinGeneration/41x41_corgasteroid.dmm index b8d35acea240d..7afc4841096b1 100644 --- a/_maps/RuinGeneration/41x41_corgasteroid.dmm +++ b/_maps/RuinGeneration/41x41_corgasteroid.dmm @@ -207,8 +207,8 @@ /turf/open/floor/plating, /area/ruin/unpowered) "lO" = ( -/obj/structure/chair/comfy/black{ - dir = 1 +/obj/structure/chair/stool{ + dir = 8 }, /turf/open/floor/plating/asteroid, /area/ruin/unpowered) @@ -220,15 +220,11 @@ /turf/open/floor/plating, /area/ruin/unpowered) "mi" = ( -/obj/structure/chair/stool, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/structure/chair/stool{ dir = 4 }, -/turf/open/floor/plating/asteroid, -/area/ruin/unpowered) -"mj" = ( -/obj/structure/chair/comfy/black{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 }, /turf/open/floor/plating/asteroid, /area/ruin/unpowered) @@ -425,12 +421,6 @@ }, /turf/open/floor/plating, /area/ruin/unpowered) -"wl" = ( -/obj/structure/chair/comfy/black{ - dir = 4 - }, -/turf/open/floor/plating/asteroid, -/area/ruin/unpowered) "wr" = ( /obj/machinery/advanced_airlock_controller/directional/east, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -824,10 +814,6 @@ }, /turf/open/floor/plating/asteroid, /area/ruin/unpowered) -"Nz" = ( -/obj/structure/chair/comfy/black, -/turf/open/floor/plating/asteroid, -/area/ruin/unpowered) "Ok" = ( /obj/structure/cable{ icon_state = "2-4" @@ -1093,7 +1079,9 @@ /turf/open/floor/plating/asteroid, /area/ruin/unpowered) "YT" = ( -/obj/structure/chair/stool, +/obj/structure/chair/stool{ + dir = 4 + }, /turf/open/floor/plating/asteroid, /area/ruin/unpowered) @@ -2623,13 +2611,13 @@ sq jZ jZ jZ -YT -YT -YT +lO +lO +lO +jZ jZ jZ jZ -wl eq vZ vZ @@ -2715,7 +2703,7 @@ jZ jZ jZ jZ -mj +jZ eq vZ vZ @@ -2754,9 +2742,9 @@ zL zL nz nz -Nz +jZ Vo -lO +jZ zL zL zL diff --git a/_maps/RuinGeneration/5x5_hern_damaged.dmm b/_maps/RuinGeneration/5x5_hern_damaged.dmm index 0442ec166e27d..58451b6218673 100644 --- a/_maps/RuinGeneration/5x5_hern_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hern_damaged.dmm @@ -16,12 +16,12 @@ /turf/open/floor/plating, /area/ruin/unpowered) "y" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "A" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "D" = ( /obj/structure/closet/emcloset, /turf/open/floor/plasteel, @@ -30,7 +30,7 @@ /turf/closed/wall, /area/ruin/unpowered) "V" = ( -/obj/item/twohanded/required/kirbyplants/random, +/obj/item/kirbyplants/random, /turf/open/floor/plating, /area/ruin/unpowered) "W" = ( diff --git a/_maps/RuinGeneration/5x5_hernsw_damaged.dmm b/_maps/RuinGeneration/5x5_hernsw_damaged.dmm index e77e7095c0503..ae4ef4e00e1bb 100644 --- a/_maps/RuinGeneration/5x5_hernsw_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hernsw_damaged.dmm @@ -6,8 +6,8 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "u" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "x" = ( /obj/effect/abstract/doorway_marker, /turf/open/floor/plasteel, @@ -29,8 +29,8 @@ /area/ruin/unpowered) "L" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "Q" = ( /obj/effect/abstract/open_area_marker{ dir = 4 diff --git a/_maps/RuinGeneration/5x5_hernw.dmm b/_maps/RuinGeneration/5x5_hernw.dmm index f7a8da12cc22d..9d4e54c70e334 100644 --- a/_maps/RuinGeneration/5x5_hernw.dmm +++ b/_maps/RuinGeneration/5x5_hernw.dmm @@ -3,7 +3,7 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "q" = ( -/obj/item/twohanded/required/kirbyplants/random, +/obj/item/kirbyplants/random, /turf/open/floor/plasteel, /area/ruin/unpowered) "u" = ( @@ -37,9 +37,9 @@ U "} (2,1,1) = {" U +q o o -q U "} (3,1,1) = {" diff --git a/_maps/RuinGeneration/5x5_hernw_damaged.dmm b/_maps/RuinGeneration/5x5_hernw_damaged.dmm index ef91feed8b24e..ec59d2221ea11 100644 --- a/_maps/RuinGeneration/5x5_hernw_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hernw_damaged.dmm @@ -13,8 +13,8 @@ /area/ruin/unpowered) "h" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "l" = ( /obj/effect/abstract/open_area_marker{ dir = 4 @@ -22,8 +22,8 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "o" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "y" = ( /turf/closed/wall, /area/ruin/unpowered) diff --git a/_maps/RuinGeneration/5x5_hers.dmm b/_maps/RuinGeneration/5x5_hers.dmm index b951da3bc063f..fc7c5eef945de 100644 --- a/_maps/RuinGeneration/5x5_hers.dmm +++ b/_maps/RuinGeneration/5x5_hers.dmm @@ -20,7 +20,7 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "A" = ( -/obj/item/twohanded/required/kirbyplants/random, +/obj/item/kirbyplants/random, /turf/open/floor/plasteel, /area/ruin/unpowered) "W" = ( diff --git a/_maps/RuinGeneration/5x5_hers_damaged.dmm b/_maps/RuinGeneration/5x5_hers_damaged.dmm index 7c602776d0c3f..925341959b8cf 100644 --- a/_maps/RuinGeneration/5x5_hers_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hers_damaged.dmm @@ -8,8 +8,8 @@ /area/ruin/unpowered) "o" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "s" = ( /turf/open/floor/plating, /area/ruin/unpowered) @@ -17,8 +17,8 @@ /turf/closed/wall, /area/ruin/unpowered) "F" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "J" = ( /obj/effect/abstract/doorway_marker, /turf/open/floor/plasteel, diff --git a/_maps/RuinGeneration/5x5_hersw.dmm b/_maps/RuinGeneration/5x5_hersw.dmm index 2e6ffef975f16..01296b03c918e 100644 --- a/_maps/RuinGeneration/5x5_hersw.dmm +++ b/_maps/RuinGeneration/5x5_hersw.dmm @@ -1,6 +1,6 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "s" = ( -/obj/item/twohanded/required/kirbyplants/random, +/obj/item/kirbyplants/random, /turf/open/floor/plasteel, /area/ruin/unpowered) "w" = ( @@ -35,9 +35,9 @@ C "} (2,1,1) = {" C -s K K +s C "} (3,1,1) = {" diff --git a/_maps/RuinGeneration/5x5_hersw_damaged.dmm b/_maps/RuinGeneration/5x5_hersw_damaged.dmm index d1cd7b66d42eb..5670110963974 100644 --- a/_maps/RuinGeneration/5x5_hersw_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hersw_damaged.dmm @@ -1,8 +1,8 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "g" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "j" = ( /obj/effect/abstract/doorway_marker{ dir = 8 @@ -29,8 +29,8 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "Z" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) (1,1,1) = {" B diff --git a/_maps/RuinGeneration/5x5_hesrnw_damaged.dmm b/_maps/RuinGeneration/5x5_hesrnw_damaged.dmm index 6dede296d823e..f63a73c565b7b 100644 --- a/_maps/RuinGeneration/5x5_hesrnw_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hesrnw_damaged.dmm @@ -1,7 +1,7 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "b" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "d" = ( /turf/open/floor/plasteel, /area/ruin/unpowered) @@ -16,8 +16,8 @@ /area/ruin/unpowered) "l" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "n" = ( /obj/effect/abstract/doorway_marker{ dir = 1 diff --git a/_maps/RuinGeneration/5x5_heswrn_damaged.dmm b/_maps/RuinGeneration/5x5_heswrn_damaged.dmm index 9117d52a4c8f1..5a0075dc8be45 100644 --- a/_maps/RuinGeneration/5x5_heswrn_damaged.dmm +++ b/_maps/RuinGeneration/5x5_heswrn_damaged.dmm @@ -22,11 +22,11 @@ /area/ruin/unpowered) "A" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "F" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "G" = ( /obj/effect/abstract/open_area_marker{ dir = 8 diff --git a/_maps/RuinGeneration/5x5_hew_damaged.dmm b/_maps/RuinGeneration/5x5_hew_damaged.dmm index 96d27e447ce8f..c97aa61812613 100644 --- a/_maps/RuinGeneration/5x5_hew_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hew_damaged.dmm @@ -3,8 +3,8 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "f" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "s" = ( /obj/effect/abstract/open_area_marker{ dir = 8 @@ -13,8 +13,8 @@ /area/ruin/unpowered) "D" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "F" = ( /turf/closed/wall, /area/ruin/unpowered) diff --git a/_maps/RuinGeneration/5x5_hewrn_damaged.dmm b/_maps/RuinGeneration/5x5_hewrn_damaged.dmm index 12466ede3cc98..b8bf593184720 100644 --- a/_maps/RuinGeneration/5x5_hewrn_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hewrn_damaged.dmm @@ -18,8 +18,8 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "A" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "G" = ( /turf/open/floor/plasteel, /area/ruin/unpowered) @@ -28,8 +28,8 @@ /area/ruin/unpowered) "W" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "Z" = ( /turf/open/floor/plating, /area/ruin/unpowered) diff --git a/_maps/RuinGeneration/5x5_hewrns_damaged.dmm b/_maps/RuinGeneration/5x5_hewrns_damaged.dmm index 7f55caea0eb40..a4d608f0a62ee 100644 --- a/_maps/RuinGeneration/5x5_hewrns_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hewrns_damaged.dmm @@ -5,8 +5,8 @@ /area/ruin/unpowered) "d" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "h" = ( /turf/closed/wall, /area/ruin/unpowered) diff --git a/_maps/RuinGeneration/5x5_hewrs_damaged.dmm b/_maps/RuinGeneration/5x5_hewrs_damaged.dmm index d52736be05569..492611df0089e 100644 --- a/_maps/RuinGeneration/5x5_hewrs_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hewrs_damaged.dmm @@ -20,11 +20,11 @@ /area/ruin/unpowered) "w" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "F" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "L" = ( /obj/effect/abstract/open_area_marker{ dir = 4 diff --git a/_maps/RuinGeneration/5x5_hnersw_damaged.dmm b/_maps/RuinGeneration/5x5_hnersw_damaged.dmm index 68fe14ba3e8fb..1c96b947f3c61 100644 --- a/_maps/RuinGeneration/5x5_hnersw_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hnersw_damaged.dmm @@ -4,8 +4,8 @@ /area/ruin/unpowered) "o" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "p" = ( /obj/effect/abstract/doorway_marker, /turf/open/floor/plasteel, diff --git a/_maps/RuinGeneration/5x5_hnesrw_damaged.dmm b/_maps/RuinGeneration/5x5_hnesrw_damaged.dmm index 0a44ec53be926..2668b23cdad59 100644 --- a/_maps/RuinGeneration/5x5_hnesrw_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hnesrw_damaged.dmm @@ -9,15 +9,15 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "i" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "p" = ( /turf/closed/wall, /area/ruin/unpowered) "C" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "G" = ( /turf/open/floor/plating, /area/ruin/unpowered) diff --git a/_maps/RuinGeneration/5x5_hnewrs_damaged.dmm b/_maps/RuinGeneration/5x5_hnewrs_damaged.dmm index b379b4aa22210..9cab4c6b3bfab 100644 --- a/_maps/RuinGeneration/5x5_hnewrs_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hnewrs_damaged.dmm @@ -26,8 +26,8 @@ /area/ruin/unpowered) "X" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "Z" = ( /obj/effect/abstract/open_area_marker{ dir = 8 diff --git a/_maps/RuinGeneration/5x5_hnresw_damaged.dmm b/_maps/RuinGeneration/5x5_hnresw_damaged.dmm index 276f8c0cf6e07..bef93d9c32c02 100644 --- a/_maps/RuinGeneration/5x5_hnresw_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hnresw_damaged.dmm @@ -32,8 +32,8 @@ /area/ruin/unpowered) "X" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) (1,1,1) = {" m diff --git a/_maps/RuinGeneration/5x5_hns_damaged.dmm b/_maps/RuinGeneration/5x5_hns_damaged.dmm index f3ff795b14e57..2215483c8ee9f 100644 --- a/_maps/RuinGeneration/5x5_hns_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hns_damaged.dmm @@ -9,16 +9,16 @@ /turf/closed/wall, /area/ruin/unpowered) "z" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "D" = ( /obj/effect/abstract/open_area_marker, /turf/open/floor/plasteel, /area/ruin/unpowered) "F" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "J" = ( /obj/effect/abstract/open_area_marker{ dir = 1 diff --git a/_maps/RuinGeneration/5x5_hnswre_damaged.dmm b/_maps/RuinGeneration/5x5_hnswre_damaged.dmm index b49ce929f3c0b..b70c55b676acb 100644 --- a/_maps/RuinGeneration/5x5_hnswre_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hnswre_damaged.dmm @@ -7,8 +7,8 @@ /area/ruin/unpowered) "n" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "q" = ( /obj/effect/abstract/doorway_marker{ dir = 4 @@ -25,8 +25,8 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "D" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "G" = ( /turf/closed/wall, /area/ruin/unpowered) diff --git a/_maps/RuinGeneration/5x5_hnwres_damaged.dmm b/_maps/RuinGeneration/5x5_hnwres_damaged.dmm index 6318dc36d0461..242dfdc1af828 100644 --- a/_maps/RuinGeneration/5x5_hnwres_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hnwres_damaged.dmm @@ -1,8 +1,8 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "c" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "k" = ( /turf/open/floor/plating, /area/ruin/unpowered) diff --git a/_maps/RuinGeneration/5x5_hsrnew_damaged.dmm b/_maps/RuinGeneration/5x5_hsrnew_damaged.dmm index 63947669ffa57..79edb8a0cac53 100644 --- a/_maps/RuinGeneration/5x5_hsrnew_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hsrnew_damaged.dmm @@ -19,8 +19,8 @@ /turf/open/floor/plating, /area/ruin/unpowered) "v" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "E" = ( /turf/closed/wall, /area/ruin/unpowered) @@ -35,8 +35,8 @@ /area/ruin/unpowered) "X" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) (1,1,1) = {" E diff --git a/_maps/RuinGeneration/5x5_hswrne_damaged.dmm b/_maps/RuinGeneration/5x5_hswrne_damaged.dmm index bc50fa4ae1d1f..df7ad4986ba46 100644 --- a/_maps/RuinGeneration/5x5_hswrne_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hswrne_damaged.dmm @@ -8,8 +8,8 @@ /area/ruin/unpowered) "o" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "q" = ( /obj/effect/abstract/open_area_marker{ dir = 8 @@ -20,8 +20,8 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "H" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "N" = ( /turf/open/floor/plating, /area/ruin/unpowered) diff --git a/_maps/RuinGeneration/5x5_hwres.dmm b/_maps/RuinGeneration/5x5_hwres.dmm index 4eb7b3b9767a4..e61c959c3c8a4 100644 --- a/_maps/RuinGeneration/5x5_hwres.dmm +++ b/_maps/RuinGeneration/5x5_hwres.dmm @@ -1,6 +1,6 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( -/obj/item/twohanded/required/kirbyplants/random, +/obj/item/kirbyplants/random, /turf/open/floor/plasteel, /area/ruin/unpowered) "f" = ( @@ -49,9 +49,9 @@ q "} (4,1,1) = {" w -a f f +a w "} (5,1,1) = {" diff --git a/_maps/RuinGeneration/5x5_hwres_damaged.dmm b/_maps/RuinGeneration/5x5_hwres_damaged.dmm index 6cc1d664af2a7..789c38b347d13 100644 --- a/_maps/RuinGeneration/5x5_hwres_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hwres_damaged.dmm @@ -9,23 +9,22 @@ /turf/open/floor/plating, /area/ruin/unpowered) "m" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "p" = ( /obj/effect/abstract/doorway_marker, /turf/open/floor/plasteel, /area/ruin/unpowered) "t" = ( -/obj/item/twohanded/required/kirbyplants/random, /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "C" = ( /turf/open/floor/plasteel, /area/ruin/unpowered) "D" = ( -/obj/structure/lattice, -/turf/open/space/basic, +/obj/item/kirbyplants/random, +/turf/open/floor/plasteel, /area/ruin/unpowered) "F" = ( /turf/closed/wall, @@ -46,7 +45,7 @@ F "} (2,1,1) = {" m -D +t d C F @@ -54,7 +53,7 @@ F (3,1,1) = {" m m -D +t d p "} @@ -62,7 +61,7 @@ p m t d -C +D F "} (5,1,1) = {" diff --git a/_maps/RuinGeneration/5x5_hwrn.dmm b/_maps/RuinGeneration/5x5_hwrn.dmm index fc70fbb0b9ad7..b03ed9baf35de 100644 --- a/_maps/RuinGeneration/5x5_hwrn.dmm +++ b/_maps/RuinGeneration/5x5_hwrn.dmm @@ -7,7 +7,7 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "o" = ( -/obj/item/twohanded/required/kirbyplants/random, +/obj/item/kirbyplants/random, /turf/open/floor/plasteel, /area/ruin/unpowered) "q" = ( diff --git a/_maps/RuinGeneration/5x5_hwrn_damaged.dmm b/_maps/RuinGeneration/5x5_hwrn_damaged.dmm index 02b581cd3cbca..88388ade574c2 100644 --- a/_maps/RuinGeneration/5x5_hwrn_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hwrn_damaged.dmm @@ -5,8 +5,8 @@ /area/ruin/unpowered) "t" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "u" = ( /obj/effect/abstract/open_area_marker{ dir = 8 @@ -14,8 +14,8 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "v" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "A" = ( /obj/effect/abstract/doorway_marker{ dir = 1 diff --git a/_maps/RuinGeneration/5x5_hwrne.dmm b/_maps/RuinGeneration/5x5_hwrne.dmm index 41759950024c9..1ad8708776afc 100644 --- a/_maps/RuinGeneration/5x5_hwrne.dmm +++ b/_maps/RuinGeneration/5x5_hwrne.dmm @@ -6,7 +6,7 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "o" = ( -/obj/item/twohanded/required/kirbyplants/random, +/obj/item/kirbyplants/random, /turf/open/floor/plasteel, /area/ruin/unpowered) "r" = ( @@ -51,9 +51,9 @@ s "} (4,1,1) = {" s +o G G -o s "} (5,1,1) = {" diff --git a/_maps/RuinGeneration/5x5_hwrne_damaged.dmm b/_maps/RuinGeneration/5x5_hwrne_damaged.dmm index 78f6d7a88e8f8..0ff6cc2bba492 100644 --- a/_maps/RuinGeneration/5x5_hwrne_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hwrne_damaged.dmm @@ -1,12 +1,11 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "b" = ( -/obj/item/twohanded/required/kirbyplants/random, -/obj/structure/lattice, -/turf/open/space/basic, +/obj/item/kirbyplants/random, +/turf/open/floor/plasteel, /area/ruin/unpowered) "e" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "h" = ( /obj/effect/abstract/doorway_marker{ dir = 4 @@ -15,8 +14,8 @@ /area/ruin/unpowered) "v" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "x" = ( /turf/open/floor/plating, /area/ruin/unpowered) @@ -62,10 +61,10 @@ v "} (4,1,1) = {" N -X -x b x +v +x "} (5,1,1) = {" N diff --git a/_maps/RuinGeneration/5x5_hwrnes_damaged.dmm b/_maps/RuinGeneration/5x5_hwrnes_damaged.dmm index af1e61a7726ba..7e4d17cbf21a8 100644 --- a/_maps/RuinGeneration/5x5_hwrnes_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hwrnes_damaged.dmm @@ -22,8 +22,8 @@ /area/ruin/unpowered) "D" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "G" = ( /turf/closed/wall, /area/ruin/unpowered) diff --git a/_maps/RuinGeneration/5x5_hwrns.dmm b/_maps/RuinGeneration/5x5_hwrns.dmm index 7d7a8cc236f27..02ca603905eb9 100644 --- a/_maps/RuinGeneration/5x5_hwrns.dmm +++ b/_maps/RuinGeneration/5x5_hwrns.dmm @@ -1,6 +1,6 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "e" = ( -/obj/item/twohanded/required/kirbyplants/random, +/obj/item/kirbyplants/random, /turf/open/floor/plasteel, /area/ruin/unpowered) "f" = ( diff --git a/_maps/RuinGeneration/5x5_hwrns_damaged.dmm b/_maps/RuinGeneration/5x5_hwrns_damaged.dmm index bf5a71c97a766..0e4ad0aa60170 100644 --- a/_maps/RuinGeneration/5x5_hwrns_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hwrns_damaged.dmm @@ -15,12 +15,12 @@ /turf/closed/wall, /area/ruin/unpowered) "I" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "J" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "O" = ( /obj/effect/abstract/doorway_marker, /turf/open/floor/plasteel, diff --git a/_maps/RuinGeneration/5x5_hwrs.dmm b/_maps/RuinGeneration/5x5_hwrs.dmm index c6cd1894dba1f..59dd72973fa70 100644 --- a/_maps/RuinGeneration/5x5_hwrs.dmm +++ b/_maps/RuinGeneration/5x5_hwrs.dmm @@ -11,7 +11,7 @@ /turf/closed/wall, /area/ruin/unpowered) "G" = ( -/obj/item/twohanded/required/kirbyplants/random, +/obj/item/kirbyplants/random, /turf/open/floor/plasteel, /area/ruin/unpowered) "I" = ( @@ -23,7 +23,7 @@ /area/ruin/unpowered) "Z" = ( /obj/effect/abstract/open_area_marker{ - dir = 4 + dir = 8 }, /turf/open/floor/plasteel, /area/ruin/unpowered) diff --git a/_maps/RuinGeneration/5x5_hwrs_damaged.dmm b/_maps/RuinGeneration/5x5_hwrs_damaged.dmm index 47e5db2901d05..a00116207b7a6 100644 --- a/_maps/RuinGeneration/5x5_hwrs_damaged.dmm +++ b/_maps/RuinGeneration/5x5_hwrs_damaged.dmm @@ -5,7 +5,7 @@ /area/ruin/unpowered) "C" = ( /obj/effect/abstract/open_area_marker{ - dir = 4 + dir = 8 }, /turf/open/floor/plasteel, /area/ruin/unpowered) @@ -13,8 +13,8 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "L" = ( -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) "N" = ( /obj/effect/abstract/doorway_marker, /turf/open/floor/plasteel, @@ -27,8 +27,8 @@ /area/ruin/unpowered) "Y" = ( /obj/structure/lattice, -/turf/open/space/basic, -/area/ruin/unpowered) +/turf/template_noop, +/area/template_noop) (1,1,1) = {" U diff --git a/_maps/RuinGeneration/5x9_lounge.dmm b/_maps/RuinGeneration/5x9_lounge.dmm index 3a5a28aaa8ecc..0d875168bd867 100644 --- a/_maps/RuinGeneration/5x9_lounge.dmm +++ b/_maps/RuinGeneration/5x9_lounge.dmm @@ -13,17 +13,17 @@ /turf/open/floor/plasteel, /area/ruin/unpowered) "q" = ( -/obj/structure/chair/comfy{ - dir = 4 +/obj/structure/chair/fancy/comfy{ + dir = 8 }, /turf/open/floor/plasteel, /area/ruin/unpowered) "t" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/plasteel, /area/ruin/unpowered) "G" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/plasteel, /area/ruin/unpowered) "J" = ( @@ -50,9 +50,9 @@ Z (2,1,1) = {" Z c -q -q -q +h +h +h h h t @@ -75,8 +75,8 @@ h h h h -h -h +q +q G Z "} diff --git a/_maps/RuinGeneration/9x9_elevator.dmm b/_maps/RuinGeneration/9x9_elevator.dmm deleted file mode 100644 index 7841166ec06e8..0000000000000 --- a/_maps/RuinGeneration/9x9_elevator.dmm +++ /dev/null @@ -1,253 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"b" = ( -/obj/machinery/computer/turbolift, -/turf/open/floor/carpet/red, -/area/ruin/unpowered) -"f" = ( -/obj/effect/mob_spawn/human/corpse/assistant, -/turf/open/floor/carpet/red, -/area/ruin/unpowered) -"g" = ( -/turf/closed/wall, -/area/ruin/unpowered) -"l" = ( -/turf/closed/wall/r_wall, -/area/ruin/unpowered) -"o" = ( -/obj/machinery/door/airlock/turbolift, -/turf/open/floor/plating, -/area/ruin/unpowered) -"q" = ( -/obj/effect/abstract/open_area_marker{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/ruin/unpowered) -"s" = ( -/turf/open/floor/carpet/red, -/area/ruin/unpowered) -"t" = ( -/turf/open/floor/plasteel, -/area/ruin/unpowered) -"C" = ( -/obj/effect/abstract/open_area_marker, -/turf/open/floor/plasteel, -/area/ruin/unpowered) -"G" = ( -/obj/machinery/turbolift_button{ - pixel_y = 32 - }, -/turf/open/floor/plasteel, -/area/ruin/unpowered) -"V" = ( -/obj/effect/abstract/open_area_marker{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/ruin/unpowered) -"W" = ( -/obj/effect/abstract/open_area_marker{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/ruin/unpowered) -"Z" = ( -/obj/machinery/food_cart, -/turf/open/floor/carpet/red, -/area/ruin/unpowered) - -(1,1,1) = {" -g -g -g -g -g -t -V -t -g -g -g -g -g -"} -(2,1,1) = {" -g -t -t -t -t -t -t -t -t -t -t -t -g -"} -(3,1,1) = {" -g -t -t -t -t -t -t -t -t -t -t -t -g -"} -(4,1,1) = {" -g -t -t -t -t -t -t -t -t -t -t -t -g -"} -(5,1,1) = {" -g -t -t -t -l -l -l -l -l -G -t -t -g -"} -(6,1,1) = {" -t -t -t -t -l -Z -f -s -o -t -t -t -t -"} -(7,1,1) = {" -W -t -t -t -l -b -s -s -o -t -t -t -C -"} -(8,1,1) = {" -t -t -t -t -l -s -s -s -o -t -t -t -t -"} -(9,1,1) = {" -g -t -t -t -l -l -l -l -l -t -t -t -g -"} -(10,1,1) = {" -g -t -t -t -t -t -t -t -t -t -t -t -g -"} -(11,1,1) = {" -g -t -t -t -t -t -t -t -t -t -t -t -g -"} -(12,1,1) = {" -g -t -t -t -t -t -t -t -t -t -t -t -g -"} -(13,1,1) = {" -g -g -g -g -g -t -q -t -g -g -g -g -g -"} diff --git a/_maps/arenas/dorms.dmm b/_maps/arenas/dorms.dmm index 8df48b8e5da04..64db7908b0242 100644 --- a/_maps/arenas/dorms.dmm +++ b/_maps/arenas/dorms.dmm @@ -82,7 +82,7 @@ /turf/open/floor/plasteel, /area/tdome/arena) "ak" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/corner, /turf/open/floor/plasteel, diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index d625752d6e749..7879b992b238e 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -227,6 +227,7 @@ /obj/structure/table/wood, /obj/item/radio/off, /obj/item/taperecorder, +/obj/item/book/manual/wiki/sopsecurity, /turf/open/floor/carpet/red, /area/crew_quarters/heads/hos) "abl" = ( @@ -645,6 +646,7 @@ pixel_x = -3; pixel_y = 7 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/red, /area/crew_quarters/heads/hos) "acS" = ( @@ -1291,6 +1293,7 @@ /obj/structure/table, /obj/item/restraints/handcuffs, /obj/item/assembly/timer, +/obj/item/book/manual/wiki/sopsecurity, /turf/open/floor/plasteel, /area/security/main) "afW" = ( @@ -2516,7 +2519,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/fore) "aoF" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/hallway/primary/fore) @@ -5194,7 +5197,7 @@ /turf/open/floor/wood, /area/crew_quarters/bar) "aMC" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/wood, /area/crew_quarters/bar) "aMG" = ( @@ -5402,7 +5405,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "aOf" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/stripes/line{ dir = 9 }, @@ -5420,7 +5423,7 @@ /turf/open/floor/plasteel/grimy, /area/hallway/secondary/entry) "aOk" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/plasteel/dark, /area/hallway/secondary/entry) "aOl" = ( @@ -5631,7 +5634,7 @@ /turf/open/floor/plasteel/grimy, /area/hallway/secondary/entry) "aPy" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/plasteel/dark, /area/hallway/secondary/entry) "aPz" = ( @@ -5770,7 +5773,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/locker) "aQR" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aQS" = ( @@ -9351,6 +9354,7 @@ pixel_x = -24 }, /obj/item/folder/yellow, +/obj/item/book/manual/wiki/sopsupply, /turf/open/floor/plasteel, /area/quartermaster/office) "bty" = ( @@ -9823,6 +9827,7 @@ pixel_y = 5; req_access_txt = "47" }, +/obj/item/book/manual/wiki/sopscience, /turf/open/floor/carpet/purple, /area/crew_quarters/heads/hor) "byp" = ( @@ -10299,6 +10304,7 @@ /obj/machinery/camera/autoname{ dir = 1 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/plasteel/cafeteria, /area/crew_quarters/heads/hor) "bCh" = ( @@ -16041,6 +16047,7 @@ /obj/item/hand_labeler{ pixel_y = 8 }, +/obj/item/book/manual/wiki/sopsupply, /turf/open/floor/carpet/blue, /area/crew_quarters/heads/hop) "cjV" = ( @@ -16208,7 +16215,7 @@ /turf/open/floor/plating, /area/maintenance/aft) "clh" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/machinery/light{ dir = 4 }, @@ -17347,11 +17354,11 @@ /turf/open/floor/plasteel, /area/hallway/primary/aft) "cto" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/plasteel, /area/hallway/primary/central) "ctp" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/tile/blue{ dir = 8 }, @@ -18049,9 +18056,8 @@ /obj/structure/cable/yellow{ icon_state = "0-8" }, -/obj/machinery/power/emitter/anchored{ - dir = 4; - state = 2 +/obj/machinery/power/emitter/welded{ + dir = 4 }, /turf/open/floor/plating, /area/engine/engineering) @@ -19379,9 +19385,8 @@ /obj/structure/cable/yellow{ icon_state = "0-4" }, -/obj/machinery/power/emitter/anchored{ - dir = 8; - state = 2 +/obj/machinery/power/emitter/welded{ + dir = 8 }, /turf/open/floor/plating, /area/engine/engineering) @@ -20347,6 +20352,7 @@ pixel_x = 5; pixel_y = 3 }, +/obj/item/book/manual/wiki/sopservice, /turf/open/floor/carpet/blue, /area/crew_quarters/heads/hop) "dbF" = ( @@ -20714,7 +20720,7 @@ /obj/effect/turf_decal/trimline/dark_blue/filled/line{ dir = 5 }, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/plasteel/dark, /area/hallway/secondary/command) "djC" = ( @@ -21407,7 +21413,7 @@ icon_state = "4-8" }, /obj/machinery/door/firedoor, -/turf/open/floor/plasteel/dark/telecomms, +/turf/open/floor/plasteel/dark, /area/tcommsat/computer) "dBA" = ( /obj/machinery/suit_storage_unit/captain, @@ -21434,6 +21440,7 @@ /obj/effect/turf_decal/tile/blue/opposingcorners{ dir = 1 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/plasteel/white, /area/crew_quarters/heads/cmo) "dCJ" = ( @@ -23430,7 +23437,7 @@ /obj/effect/turf_decal/tile/neutral/anticorner/contrasted{ dir = 4 }, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "eCd" = ( @@ -23573,6 +23580,7 @@ /obj/machinery/cell_charger, /obj/item/clothing/glasses/meson, /obj/effect/turf_decal/tile/yellow/anticorner/contrasted, +/obj/item/book/manual/wiki/sopengineering, /turf/open/floor/plasteel, /area/engine/break_room) "eFB" = ( @@ -25673,7 +25681,7 @@ /obj/machinery/light{ dir = 8 }, -/turf/open/floor/plasteel/dark/telecomms, +/turf/open/floor/plasteel/dark, /area/tcommsat/computer) "fRr" = ( /obj/structure/cable/yellow{ @@ -31921,6 +31929,7 @@ dir = 9 }, /obj/item/crowbar, +/obj/item/book/manual/wiki/sopmedical, /turf/open/floor/plasteel/white, /area/medical/storage) "iVN" = ( @@ -33842,7 +33851,7 @@ /area/crew_quarters/dorms) "jSi" = ( /obj/effect/decal/cleanable/dirt, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/plasteel, /area/security/prison) "jSj" = ( @@ -34571,6 +34580,7 @@ "khb" = ( /obj/structure/table, /obj/item/kitchen/rollingpin, +/obj/item/book/manual/wiki/sopservice, /turf/open/floor/plasteel, /area/hallway/secondary/service) "khd" = ( @@ -44251,6 +44261,7 @@ pixel_x = 24 }, /obj/structure/disposalpipe/segment, +/obj/item/book/manual/wiki/sopscience, /turf/open/floor/plasteel/white, /area/science/lab) "oVr" = ( @@ -44570,6 +44581,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer2{ dir = 1 }, +/obj/item/book/manual/wiki/sopengineering, /turf/open/floor/plasteel, /area/crew_quarters/heads/chief) "piD" = ( @@ -47606,6 +47618,7 @@ /obj/machinery/keycard_auth{ pixel_y = -28 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/blue, /area/crew_quarters/heads/hop) "qDZ" = ( @@ -48325,6 +48338,7 @@ /obj/item/paper/monitorkey, /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/plasteel, /area/crew_quarters/heads/chief) "qWM" = ( @@ -48417,7 +48431,7 @@ /area/construction/mining/aux_base) "qZp" = ( /obj/effect/turf_decal/tile/neutral/half/contrasted, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "qZy" = ( @@ -49209,7 +49223,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/turf/open/floor/plasteel/dark/telecomms, +/turf/open/floor/plasteel/dark, /area/tcommsat/computer) "rqE" = ( /obj/structure/lattice, @@ -49712,7 +49726,7 @@ /obj/structure/cable/yellow{ icon_state = "1-4" }, -/turf/open/floor/plasteel/dark/telecomms, +/turf/open/floor/plasteel/dark, /area/tcommsat/computer) "rBC" = ( /obj/machinery/door/firedoor, @@ -53365,7 +53379,7 @@ /obj/machinery/camera/autoname{ dir = 9 }, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/plasteel, /area/maintenance/aft) "tjy" = ( @@ -53454,6 +53468,7 @@ pixel_x = -7 }, /obj/item/melee/chainofcommand, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/royalblue, /area/crew_quarters/heads/captain) "tnN" = ( @@ -54610,7 +54625,7 @@ /obj/effect/turf_decal/caution{ dir = 4 }, -/turf/open/floor/plasteel/dark/telecomms, +/turf/open/floor/plasteel/dark, /area/tcommsat/computer) "tLO" = ( /obj/structure/chair/office{ @@ -54988,7 +55003,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "tXO" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/machinery/status_display/evac{ layer = 4; pixel_y = 32 @@ -55579,9 +55594,6 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) -"umG" = ( -/turf/open/floor/plasteel/dark/telecomms, -/area/security/checkpoint/engineering) "umR" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -57154,16 +57166,6 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai_upload) -"vkT" = ( -/obj/structure/table/reinforced, -/obj/item/storage/fancy/donut_box, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "kitchen"; - name = "kitchen shutters" - }, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel/cafeteria, -/area/crew_quarters/kitchen) "vlj" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable/yellow{ @@ -57779,7 +57781,7 @@ /obj/structure/chair/office{ dir = 8 }, -/turf/open/floor/plasteel/dark/telecomms, +/turf/open/floor/plasteel/dark, /area/tcommsat/computer) "vEN" = ( /obj/structure/table/glass, @@ -57792,6 +57794,7 @@ /obj/effect/turf_decal/tile/blue/opposingcorners{ dir = 1 }, +/obj/item/book/manual/wiki/sopmedical, /turf/open/floor/plasteel/white, /area/crew_quarters/heads/cmo) "vFr" = ( @@ -58169,7 +58172,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer2{ dir = 4 }, -/turf/open/floor/plasteel/dark/telecomms, +/turf/open/floor/plasteel/dark, /area/tcommsat/computer) "vOh" = ( /obj/effect/decal/cleanable/dirt, @@ -93799,7 +93802,7 @@ bRx wwP mIb bWQ -umG +bWQ bYN kjp caA @@ -101212,7 +101215,7 @@ aTM aVB aVz aVz -vkT +kVI bbz aYV aYV diff --git a/_maps/map_files/CorgStation/CorgStation.dmm b/_maps/map_files/CorgStation/CorgStation.dmm index 9d1f042f8fa52..56e6ad1257c2a 100644 --- a/_maps/map_files/CorgStation/CorgStation.dmm +++ b/_maps/map_files/CorgStation/CorgStation.dmm @@ -992,9 +992,8 @@ /turf/open/floor/plating, /area/science/test_area) "aja" = ( -/obj/machinery/power/emitter/anchored{ - dir = 4; - state = 2 +/obj/machinery/power/emitter/welded{ + dir = 4 }, /obj/structure/cable/yellow{ icon_state = "0-4" @@ -1094,10 +1093,11 @@ pixel_x = 1; pixel_y = -25 }, +/obj/item/book/manual/wiki/sopengineering, /turf/open/floor/plasteel/dark, /area/engine/storage_shared) "akq" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/tile/green/opposingcorners, /obj/effect/turf_decal/tile/yellow{ dir = 8 @@ -2205,9 +2205,8 @@ /turf/open/floor/plating, /area/hallway/primary/fore) "aAP" = ( -/obj/machinery/power/emitter/anchored{ - dir = 8; - state = 2 +/obj/machinery/power/emitter/welded{ + dir = 8 }, /obj/structure/cable/yellow{ icon_state = "0-8" @@ -4579,6 +4578,7 @@ pixel_x = 6; pixel_y = 1 }, +/obj/item/book/manual/wiki/sopsupply, /turf/open/floor/carpet/blue, /area/crew_quarters/heads/hop) "bgw" = ( @@ -5346,7 +5346,7 @@ /turf/open/floor/plasteel, /area/engine/atmos) "buQ" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/siding/wood{ dir = 4 }, @@ -6535,7 +6535,7 @@ /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "bOo" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/tile/blue/anticorner/contrasted{ dir = 8 }, @@ -10956,7 +10956,7 @@ /turf/open/floor/plasteel/white, /area/crew_quarters/kitchen/coldroom) "dpW" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/tile/green/half/contrasted{ dir = 8 @@ -12668,7 +12668,7 @@ /turf/open/floor/plasteel, /area/science/mixing) "dUz" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/plasteel/cafeteria{ dir = 5 }, @@ -15237,6 +15237,7 @@ }, /obj/machinery/fax/med, /obj/structure/table/glass, +/obj/item/book/manual/wiki/sopmedical, /turf/open/floor/plasteel/white, /area/medical/storage) "ePd" = ( @@ -23983,7 +23984,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/exit) "hJm" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/item/radio/intercom{ pixel_x = 29; pixel_y = -2 @@ -24522,7 +24523,7 @@ /turf/open/floor/plasteel/dark, /area/security/execution/education) "hSS" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/tile/green/anticorner/contrasted, /turf/open/floor/plasteel, @@ -24721,6 +24722,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{ dir = 4 }, +/obj/item/book/manual/wiki/sopsecurity, /turf/open/floor/plasteel, /area/security/main) "hWl" = ( @@ -25950,6 +25952,7 @@ pixel_y = 4 }, /obj/effect/turf_decal/tile/blue/half/contrasted, +/obj/item/book/manual/wiki/sopmedical, /turf/open/floor/plasteel/white, /area/crew_quarters/heads/cmo) "ipz" = ( @@ -27305,7 +27308,7 @@ /turf/open/floor/plating, /area/maintenance/port) "iNB" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/machinery/light, /turf/open/floor/grass, /area/hallway/primary/fore) @@ -28628,7 +28631,7 @@ /turf/open/floor/plasteel, /area/engine/engineering) "jjS" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/tile/blue/fourcorners/contrasted, /turf/open/floor/plasteel, @@ -32767,7 +32770,7 @@ /turf/open/floor/carpet/red, /area/security/detectives_office) "kDs" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/tile/green/anticorner/contrasted, /turf/open/floor/plasteel, /area/security/prison) @@ -36916,7 +36919,7 @@ /area/bridge) "lVf" = ( /obj/structure/table/reinforced, -/obj/item/reagent_containers/food/snacks/dough, +/obj/item/food/dough, /obj/item/kitchen/rollingpin, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{ dir = 4 @@ -44398,6 +44401,7 @@ /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 1 }, +/obj/item/book/manual/wiki/sopservice, /turf/open/floor/plasteel, /area/hallway/secondary/service) "oqr" = ( @@ -44927,6 +44931,7 @@ /obj/effect/turf_decal/tile/blue/anticorner/contrasted{ dir = 4 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/plasteel/white, /area/crew_quarters/heads/cmo) "oze" = ( @@ -46181,6 +46186,7 @@ pixel_x = 5; pixel_y = 8 }, +/obj/item/book/manual/wiki/sopengineering, /turf/open/floor/carpet/orange, /area/crew_quarters/heads/chief) "oVN" = ( @@ -47703,7 +47709,6 @@ pixel_y = 28; req_access_txt = "28" }, -/obj/item/storage/fancy/donut_box, /turf/open/floor/plasteel/white, /area/crew_quarters/kitchen) "pzb" = ( @@ -51991,7 +51996,7 @@ /turf/open/floor/plasteel, /area/science/mixing) "qQB" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/tile/yellow/fourcorners/contrasted, /turf/open/floor/plasteel, /area/engine/atmos) @@ -52005,7 +52010,7 @@ /turf/open/floor/plating, /area/maintenance/department/bridge) "qQT" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/tile/blue/fourcorners/contrasted, /turf/open/floor/plasteel, @@ -53375,6 +53380,7 @@ "rou" = ( /obj/structure/table/reinforced, /obj/item/flashlight/lamp, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/orange, /area/crew_quarters/heads/chief) "roy" = ( @@ -55349,6 +55355,7 @@ dir = 8 }, /obj/effect/turf_decal/tile/neutral/opposingcorners, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/plasteel/dark, /area/crew_quarters/heads/hos) "rUN" = ( @@ -56871,6 +56878,7 @@ /obj/item/hand_labeler, /obj/item/laser_pointer, /obj/effect/turf_decal/tile/purple/opposingcorners, +/obj/item/book/manual/wiki/sopscience, /turf/open/floor/plasteel, /area/science/lab) "suf" = ( @@ -57273,6 +57281,7 @@ /obj/machinery/keycard_auth{ pixel_x = 26 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/blue, /area/crew_quarters/heads/hop) "sAZ" = ( @@ -58675,7 +58684,7 @@ /turf/closed/wall/r_wall, /area/science/robotics) "sZN" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/machinery/camera/autoname, /turf/open/floor/plasteel/cafeteria{ dir = 5 @@ -60514,7 +60523,7 @@ /obj/machinery/firealarm{ pixel_y = -24 }, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/siding/wood{ dir = 6 }, @@ -63544,6 +63553,7 @@ }, /obj/item/camera, /obj/item/camera_film, +/obj/item/book/manual/wiki/sopscience, /turf/open/floor/plasteel/cafeteria{ dir = 5 }, @@ -64611,6 +64621,7 @@ pixel_x = 4; pixel_y = 4 }, +/obj/item/book/manual/wiki/sopservice, /turf/open/floor/carpet/blue, /area/crew_quarters/heads/hop) "vbN" = ( @@ -64677,7 +64688,7 @@ /turf/open/floor/plasteel, /area/security/brig) "vcO" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/tile/green/fourcorners/contrasted, /turf/open/floor/plasteel, /area/hallway/primary/central) @@ -65222,7 +65233,7 @@ /turf/open/floor/plasteel, /area/science/storage) "vmr" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, @@ -67130,6 +67141,7 @@ pixel_x = -1; pixel_y = 9 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/wood, /area/crew_quarters/heads/captain) "vOx" = ( @@ -67546,6 +67558,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/item/book/manual/wiki/sopsupply, /turf/open/floor/plasteel/dark, /area/quartermaster/office) "vWy" = ( @@ -68886,6 +68899,7 @@ dir = 8 }, /obj/effect/turf_decal/tile/neutral, +/obj/item/book/manual/wiki/sopsecurity, /turf/open/floor/plasteel/dark, /area/crew_quarters/heads/hos) "wvu" = ( @@ -71449,6 +71463,7 @@ pixel_x = 3; pixel_y = 2 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/purple, /area/crew_quarters/heads/hor) "xoV" = ( @@ -72278,7 +72293,7 @@ /turf/open/floor/plating, /area/maintenance/starboard/central) "xBu" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/tile/green, /obj/effect/turf_decal/tile/yellow{ dir = 4 diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 93fe048c3550c..90d0f9e348b10 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -861,7 +861,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "afb" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/machinery/light{ dir = 1 }, @@ -910,7 +910,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "afz" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/hallway/secondary/entry) @@ -1950,7 +1950,6 @@ /area/hallway/secondary/entry) "ams" = ( /obj/structure/table/wood, -/obj/item/storage/fancy/donut_box, /turf/open/floor/plasteel/grimy, /area/hallway/secondary/entry) "amu" = ( @@ -2805,9 +2804,8 @@ /obj/structure/cable{ icon_state = "0-2" }, -/obj/machinery/power/emitter/anchored{ - dir = 1; - state = 2 +/obj/machinery/power/emitter/welded{ + dir = 1 }, /turf/open/floor/circuit/green, /area/engine/atmospherics_engine) @@ -2892,7 +2890,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "arO" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/decal/cleanable/dirt, /obj/machinery/camera{ c_tag = "Arrivals - Aft"; @@ -2902,7 +2900,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "arP" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/item/radio/intercom{ pixel_y = 26 }, @@ -6332,6 +6330,7 @@ /obj/structure/table, /obj/item/paper_bin, /obj/item/pen, +/obj/item/book/manual/wiki/sopservice, /turf/open/floor/plasteel, /area/hallway/secondary/service) "aHs" = ( @@ -9977,7 +9976,6 @@ id = "kitchencounter"; name = "Kitchen Counter Shutters" }, -/obj/item/storage/fancy/donut_box, /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/delivery, /obj/machinery/door/firedoor, @@ -11000,7 +10998,7 @@ /area/crew_quarters/kitchen) "bhQ" = ( /obj/structure/table/reinforced, -/obj/item/reagent_containers/food/snacks/dough, +/obj/item/food/dough, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/crew_quarters/kitchen) @@ -12253,6 +12251,7 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/red, /area/crew_quarters/heads/hos) "bnY" = ( @@ -17523,6 +17522,7 @@ dir = 1; layer = 2.9 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/royalblue, /area/crew_quarters/heads/captain) "bSM" = ( @@ -20684,12 +20684,14 @@ }, /obj/item/folder/blue, /obj/item/pen, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/wood, /area/crew_quarters/heads/hop) "cjB" = ( /obj/structure/table/wood, /obj/item/paper_bin, /obj/structure/disposalpipe/segment, +/obj/item/book/manual/wiki/sopsupply, /turf/open/floor/carpet/royalblue, /area/crew_quarters/heads/hop) "cjD" = ( @@ -23531,7 +23533,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/command) "cvE" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/hallway/secondary/command) @@ -27507,13 +27509,13 @@ /turf/open/floor/plating, /area/medical/medbay/central) "cNE" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/machinery/light, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/hallway/primary/central) "cNF" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/hallway/primary/central) @@ -27889,7 +27891,7 @@ /turf/open/floor/plasteel/grimy, /area/crew_quarters/dorms) "cPX" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) @@ -28039,7 +28041,7 @@ /turf/open/floor/plasteel/grimy, /area/crew_quarters/dorms) "cRw" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/structure/extinguisher_cabinet{ pixel_x = -26 }, @@ -28337,7 +28339,6 @@ /area/crew_quarters/dorms) "cTd" = ( /obj/structure/table, -/obj/item/storage/fancy/donut_box, /obj/effect/turf_decal/tile/neutral{ dir = 8 }, @@ -30198,6 +30199,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/item/book/manual/wiki/sopscience, /turf/open/floor/plasteel, /area/science/lab) "deh" = ( @@ -31712,6 +31714,7 @@ network = list("ss13","rd") }, /obj/effect/turf_decal/bot, +/obj/item/book/manual/wiki/sopscience, /turf/open/floor/plasteel, /area/crew_quarters/heads/hor) "dsc" = ( @@ -36037,7 +36040,7 @@ }, /area/chapel/main) "eaE" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) @@ -36126,7 +36129,7 @@ /obj/machinery/light{ dir = 8 }, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) @@ -36354,6 +36357,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 4 }, +/obj/item/book/manual/wiki/sopengineering, /turf/open/floor/plasteel, /area/engine/storage_shared) "ecZ" = ( @@ -45794,6 +45798,7 @@ /obj/item/clipboard, /obj/item/toy/figure/ce, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/plasteel, /area/crew_quarters/heads/chief) "hhy" = ( @@ -46218,7 +46223,7 @@ /obj/structure/cable/yellow{ icon_state = "2-8" }, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/stripes/corner{ dir = 4 }, @@ -46676,7 +46681,6 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/item/storage/fancy/donut_box, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, /turf/open/floor/plasteel/dark, /area/crew_quarters/heads/hos) @@ -46885,7 +46889,7 @@ /turf/open/floor/plasteel/dark, /area/bridge) "hAU" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/decal/cleanable/cobweb, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, /turf/open/floor/plasteel/dark, @@ -53143,7 +53147,6 @@ /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 8 }, -/obj/item/storage/fancy/donut_box, /turf/open/floor/plasteel, /area/security/brig) "jOr" = ( @@ -55543,6 +55546,7 @@ /obj/item/folder/red, /obj/item/clothing/mask/gas/sechailer, /obj/effect/turf_decal/tile/red/fourcorners/contrasted, +/obj/item/book/manual/wiki/sopsecurity, /turf/open/floor/plasteel, /area/security/main) "kCi" = ( @@ -58010,7 +58014,7 @@ /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "ltx" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/machinery/light{ dir = 8 }, @@ -59987,6 +59991,7 @@ /obj/item/folder/white, /obj/item/stamp/research_director, /obj/effect/turf_decal/tile/purple/half/contrasted, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/plasteel/white, /area/crew_quarters/heads/hor) "lZP" = ( @@ -61779,6 +61784,7 @@ /obj/structure/window/reinforced{ dir = 4 }, +/obj/item/book/manual/wiki/sopmedical, /turf/open/floor/plasteel, /area/medical/storage) "mGa" = ( @@ -62249,7 +62255,7 @@ /area/maintenance/port/fore) "mMY" = ( /obj/effect/turf_decal/bot, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/plasteel, /area/hallway/primary/central) "mNo" = ( @@ -64711,6 +64717,7 @@ /obj/item/folder/yellow, /obj/item/lighter, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, +/obj/item/book/manual/wiki/sopengineering, /turf/open/floor/plasteel, /area/crew_quarters/heads/chief) "nBr" = ( @@ -65825,7 +65832,7 @@ /turf/open/floor/circuit/green/telecomms/mainframe, /area/tcommsat/server) "nUP" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/structure/sign/poster/official/ian{ pixel_y = -32 }, @@ -65997,7 +66004,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/starboard) "nXr" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/tile/blue/half/contrasted{ dir = 4 }, @@ -71777,7 +71784,7 @@ /turf/open/floor/carpet/royalblue, /area/ai_monitored/turret_protected/aisat_interior) "qat" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/machinery/light, /obj/machinery/status_display/evac{ pixel_y = -32 @@ -73194,6 +73201,7 @@ }, /obj/item/flashlight/lamp, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, +/obj/item/book/manual/wiki/sopservice, /turf/open/floor/plasteel/dark, /area/crew_quarters/heads/hop) "qxS" = ( @@ -73886,6 +73894,7 @@ /obj/machinery/keycard_auth{ pixel_y = -24 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/plasteel/white, /area/crew_quarters/heads/cmo) "qMh" = ( @@ -74937,7 +74946,7 @@ /obj/structure/extinguisher_cabinet{ pixel_x = 26 }, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/tile/red/opposingcorners, /obj/effect/turf_decal/tile/yellow/opposingcorners{ dir = 1 @@ -75914,6 +75923,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{ dir = 4 }, +/obj/item/book/manual/wiki/sopsecurity, /turf/open/floor/carpet/red, /area/crew_quarters/heads/hos) "rwl" = ( @@ -76525,10 +76535,6 @@ c_tag = "Security - Office Fore" }, /obj/structure/table/reinforced, -/obj/effect/spawner/lootdrop/donkpockets{ - pixel_x = 2; - pixel_y = 4 - }, /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 4 }, @@ -78895,7 +78901,7 @@ /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai_upload) "sul" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/machinery/newscaster{ pixel_x = 32 }, @@ -83189,7 +83195,7 @@ /turf/open/floor/plasteel/dark, /area/security/nuke_storage) "ubH" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/machinery/firealarm/directional/north, /obj/effect/turf_decal/tile/blue/half/contrasted{ dir = 4 @@ -84109,6 +84115,7 @@ /obj/machinery/newscaster{ pixel_y = -30 }, +/obj/item/book/manual/wiki/sopmedical, /turf/open/floor/plasteel/white, /area/crew_quarters/heads/cmo) "usG" = ( @@ -90411,7 +90418,6 @@ /area/science/research) "wvO" = ( /obj/structure/table, -/obj/item/storage/fancy/donut_box, /obj/item/radio/intercom{ pixel_y = -26 }, @@ -92312,7 +92318,6 @@ /area/science/shuttledock) "wZo" = ( /obj/structure/table, -/obj/item/storage/fancy/donut_box, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, /turf/open/floor/plasteel, /area/crew_quarters/locker) @@ -94165,7 +94170,6 @@ "xEE" = ( /obj/structure/table/reinforced, /obj/item/clipboard, -/obj/item/reagent_containers/food/snacks/donut/jelly/choco, /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 }, @@ -95091,6 +95095,7 @@ /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 8 }, +/obj/item/book/manual/wiki/sopsupply, /turf/open/floor/plasteel, /area/quartermaster/office) "xSY" = ( diff --git a/_maps/map_files/FlandStation/FlandStation.dmm b/_maps/map_files/FlandStation/FlandStation.dmm index ca8484357df8c..179620e1fe6b3 100644 --- a/_maps/map_files/FlandStation/FlandStation.dmm +++ b/_maps/map_files/FlandStation/FlandStation.dmm @@ -1388,7 +1388,7 @@ /turf/closed/wall/r_wall, /area/asteroid/nearstation) "asL" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -1816,7 +1816,7 @@ /area/crew_quarters/heads/cmo) "ayx" = ( /obj/effect/turf_decal/delivery, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/tile/blue{ dir = 4 }, @@ -10420,6 +10420,7 @@ icon_state = "map-right-fland"; pixel_y = 32 }, +/obj/item/book/manual/wiki/sopmedical, /turf/open/floor/plasteel/dark, /area/medical/storage) "cLH" = ( @@ -10664,6 +10665,7 @@ /obj/effect/turf_decal/tile/yellow/opposingcorners{ dir = 1 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/plasteel, /area/crew_quarters/heads/chief) "cPp" = ( @@ -11146,7 +11148,7 @@ /turf/open/floor/plasteel/dark/side, /area/engine/atmos) "cUp" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -12143,7 +12145,7 @@ /area/hallway/secondary/entry) "diY" = ( /obj/effect/turf_decal/delivery, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/tile/yellow, /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -12795,7 +12797,7 @@ /turf/open/floor/plating, /area/bridge) "dsm" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/carpet, /area/hallway/secondary/entry) "dst" = ( @@ -12854,7 +12856,7 @@ pixel_y = 24 }, /obj/effect/turf_decal/delivery, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/tile/yellow, /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -13010,7 +13012,7 @@ /turf/open/floor/plating, /area/maintenance/port/fore) "dva" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/machinery/light{ dir = 4 }, @@ -15477,7 +15479,7 @@ /turf/open/floor/wood, /area/bridge/meeting_room/council) "edp" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel/sepia, /area/engine/break_room) @@ -15759,7 +15761,7 @@ /turf/open/floor/plasteel/techmaint, /area/maintenance/central) "eiZ" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/tile/dark_blue/fourcorners/contrasted, /turf/open/floor/plasteel/dark, /area/bridge) @@ -18930,6 +18932,7 @@ /obj/effect/turf_decal/tile/brown/opposingcorners{ dir = 1 }, +/obj/item/book/manual/wiki/sopsupply, /turf/open/floor/plasteel, /area/quartermaster/office) "eWg" = ( @@ -20778,7 +20781,7 @@ /turf/open/floor/plasteel/techmaint, /area/maintenance/department/medical) "fuY" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/machinery/light, /obj/machinery/computer/security/telescreen/entertainment{ pixel_y = -32 @@ -20920,7 +20923,7 @@ /turf/open/floor/plasteel/techmaint, /area/security/prison) "fwE" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel/dark, /area/bridge/meeting_room/council) @@ -22005,7 +22008,7 @@ /turf/open/floor/plasteel/dark, /area/engine/engine_room) "fKk" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel/dark, /area/hallway/primary/port) @@ -24480,6 +24483,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/item/book/manual/wiki/sopsupply, /turf/open/floor/carpet/blue, /area/crew_quarters/heads/hop) "grU" = ( @@ -29042,6 +29046,7 @@ }, /obj/item/pinpointer/nuke, /obj/item/paper/fluff/gateway, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/royalblue, /area/crew_quarters/heads/captain/private) "hFt" = ( @@ -29158,7 +29163,7 @@ /area/crew_quarters/heads/captain/private) "hGA" = ( /obj/effect/turf_decal/delivery, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "hGC" = ( @@ -29258,6 +29263,7 @@ pixel_x = -1; pixel_y = -1 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/blue, /area/crew_quarters/heads/hop) "hIw" = ( @@ -31875,6 +31881,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2, /obj/structure/table/wood/fancy/blue, /obj/machinery/recharger, +/obj/item/book/manual/wiki/sopservice, /turf/open/floor/carpet/blue, /area/crew_quarters/heads/hop) "ipR" = ( @@ -35614,7 +35621,7 @@ }, /area/maintenance/starboard/central) "jrf" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -41465,6 +41472,7 @@ /obj/item/storage/firstaid/fire{ pixel_y = 6 }, +/obj/item/book/manual/wiki/sopengineering, /turf/open/floor/plasteel/dark, /area/engine/storage_shared) "kUm" = ( @@ -42379,7 +42387,7 @@ }, /area/hallway/primary/starboard) "ldV" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/tile/dark_blue/fourcorners/contrasted, /turf/open/floor/plasteel/dark, /area/bridge) @@ -43984,6 +43992,7 @@ dir = 1 }, /obj/effect/turf_decal/tile/red/opposingcorners, +/obj/item/book/manual/wiki/sopengineering, /turf/open/floor/plasteel, /area/crew_quarters/heads/chief) "lwl" = ( @@ -47746,7 +47755,7 @@ /turf/open/floor/plasteel/dark, /area/bridge) "mwS" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/tile/dark_blue/fourcorners/contrasted, /turf/open/floor/plasteel/dark, /area/hallway/primary/starboard) @@ -48146,7 +48155,6 @@ pixel_x = -32 }, /obj/structure/table/wood, -/obj/item/storage/fancy/donut_box, /turf/open/floor/carpet/red, /area/crew_quarters/heads/hos) "mCk" = ( @@ -48644,7 +48652,7 @@ /turf/open/floor/plasteel/dark, /area/engine/atmos) "mIj" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/tile/blue/opposingcorners{ dir = 1 }, @@ -51277,6 +51285,7 @@ /obj/item/stamp/hos, /obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/red, /area/crew_quarters/heads/hos) "nqD" = ( @@ -59134,7 +59143,7 @@ /turf/open/floor/plasteel/dark, /area/crew_quarters/locker) "pvZ" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -60494,7 +60503,7 @@ /turf/open/floor/plasteel/dark, /area/gateway) "pLW" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/tile/blue/opposingcorners{ dir = 1 }, @@ -66810,7 +66819,7 @@ /turf/open/floor/plasteel/techmaint, /area/security/brig) "rmj" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -69241,9 +69250,8 @@ }, /area/engine/atmos) "rOz" = ( -/obj/machinery/power/emitter/anchored{ - dir = 4; - state = 2 +/obj/machinery/power/emitter/welded{ + dir = 4 }, /obj/structure/cable/orange{ icon_state = "0-4" @@ -70548,7 +70556,7 @@ /turf/open/floor/plasteel/dark, /area/crew_quarters/bar) "sei" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel/dark, /area/crew_quarters/bar/atrium) @@ -71660,6 +71668,7 @@ /obj/item/paper_bin, /obj/item/pen, /obj/effect/turf_decal/tile/blue/fourcorners/contrasted, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/plasteel/cafeteria, /area/crew_quarters/heads/cmo) "stN" = ( @@ -71872,7 +71881,7 @@ /area/hallway/primary/port) "swe" = ( /obj/effect/turf_decal/delivery, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/tile/blue{ dir = 4 }, @@ -72918,8 +72927,7 @@ /mob/living/basic/cockroach{ desc = "carlos."; maxHealth = 2; - name = "carlos"; - + name = "carlos" }, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer2{ dir = 4 @@ -74892,9 +74900,8 @@ /turf/open/floor/plasteel/techmaint, /area/maintenance/starboard/fore) "tjh" = ( -/obj/machinery/power/emitter/anchored{ - dir = 8; - state = 2 +/obj/machinery/power/emitter/welded{ + dir = 8 }, /obj/structure/cable/orange{ icon_state = "0-8" @@ -75989,6 +75996,7 @@ /obj/machinery/status_display/ai{ pixel_x = 32 }, +/obj/item/book/manual/wiki/sopsecurity, /turf/open/floor/carpet/red, /area/crew_quarters/heads/hos) "twx" = ( @@ -77894,7 +77902,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "tTY" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -78388,6 +78396,7 @@ /obj/item/radio/intercom{ pixel_x = -28 }, +/obj/item/book/manual/wiki/sopsecurity, /turf/open/floor/plasteel/dark, /area/security/main) "ubb" = ( @@ -78426,7 +78435,7 @@ /turf/open/floor/plasteel, /area/security/checkpoint/supply) "ubo" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -78855,7 +78864,7 @@ /turf/open/floor/plating, /area/maintenance/starboard/aft) "uir" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/delivery, /obj/machinery/light/small{ dir = 8 @@ -79751,7 +79760,7 @@ /turf/open/floor/plasteel/techmaint, /area/crew_quarters/fitness/recreation) "usO" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/tile/blue{ dir = 4 @@ -80272,7 +80281,6 @@ /obj/effect/turf_decal/bot, /obj/structure/table/reinforced, /obj/item/clipboard, -/obj/item/reagent_containers/food/snacks/donut/jelly/choco, /obj/item/lighter{ pixel_x = 4; pixel_y = 4 @@ -80774,7 +80782,7 @@ /turf/open/floor/plasteel/dark, /area/security/prison) "uDC" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/bot, /obj/machinery/light, /turf/open/floor/plasteel/sepia, @@ -81077,7 +81085,7 @@ /turf/open/floor/plating, /area/maintenance/aft) "uIa" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel/dark, /area/hallway/primary/port) @@ -82358,6 +82366,7 @@ /obj/effect/turf_decal/tile/green/opposingcorners, /obj/structure/table, /obj/machinery/fax/service, +/obj/item/book/manual/wiki/sopservice, /turf/open/floor/plasteel, /area/hallway/secondary/service) "uXD" = ( @@ -83028,10 +83037,6 @@ /obj/effect/turf_decal/trimline/red/filled/line{ dir = 8 }, -/obj/effect/spawner/lootdrop/donkpockets{ - pixel_x = 2; - pixel_y = 4 - }, /turf/open/floor/plasteel/dark, /area/security/main) "vfj" = ( @@ -83573,7 +83578,6 @@ /area/security/prison) "vlF" = ( /obj/structure/table/reinforced, -/obj/item/storage/fancy/donut_box, /obj/structure/disposalpipe/segment, /obj/machinery/door/poddoor/shutters{ id = "barcounter"; @@ -87240,7 +87244,7 @@ /area/hallway/primary/central) "vYN" = ( /obj/effect/turf_decal/delivery, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/structure/railing{ dir = 8 }, @@ -87254,7 +87258,7 @@ /area/hallway/secondary/exit/departure_lounge) "vYX" = ( /obj/effect/turf_decal/delivery, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/tile/blue{ dir = 4 }, @@ -88320,6 +88324,7 @@ /obj/effect/turf_decal/tile/blue/fourcorners/contrasted, /obj/machinery/firealarm/directional/north, /obj/item/toy/figure/cmo, +/obj/item/book/manual/wiki/sopmedical, /turf/open/floor/plasteel/cafeteria, /area/crew_quarters/heads/cmo) "wmR" = ( @@ -88957,7 +88962,7 @@ /turf/open/floor/plating, /area/security/range) "wuq" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel/dark, /area/crew_quarters/bar/atrium) @@ -91146,6 +91151,7 @@ pixel_x = -6; pixel_y = 2 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/purple, /area/crew_quarters/heads/hor) "wUA" = ( @@ -91311,7 +91317,7 @@ /area/maintenance/disposal/incinerator) "wVw" = ( /obj/effect/turf_decal/delivery, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/tile/yellow, /obj/effect/turf_decal/tile/blue{ dir = 4 @@ -91331,6 +91337,7 @@ /obj/structure/table/reinforced, /obj/item/paper_bin, /obj/item/pen, +/obj/item/book/manual/wiki/sopscience, /turf/open/floor/carpet/purple, /area/crew_quarters/heads/hor) "wVN" = ( @@ -93218,7 +93225,7 @@ /obj/effect/turf_decal/bot, /obj/item/reagent_containers/glass/bowl, /obj/item/reagent_containers/food/snacks/grown/tomato, -/obj/item/reagent_containers/food/snacks/dough, +/obj/item/food/dough, /obj/effect/turf_decal/tile/bar/opposingcorners, /turf/open/floor/plasteel/cafeteria, /area/crew_quarters/kitchen) @@ -93557,6 +93564,7 @@ /obj/machinery/status_display/evac{ pixel_y = -32 }, +/obj/item/book/manual/wiki/sopscience, /turf/open/floor/plasteel/dark, /area/science/lab) "xqT" = ( @@ -94943,7 +94951,7 @@ /area/engine/atmos) "xDT" = ( /obj/effect/turf_decal/delivery, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "xDU" = ( @@ -96398,7 +96406,7 @@ /turf/open/floor/plasteel, /area/vacant_room/commissary/commissary2) "xSF" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/delivery, /obj/machinery/camera{ c_tag = "Locker Room - Arcade"; diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm index 1afb6d8c53f03..c97481150b60e 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -2628,7 +2628,7 @@ /turf/open/floor/engine, /area/ai_monitored/turret_protected/aisat/foyer) "aiS" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/tile/red{ dir = 4 }, @@ -17007,6 +17007,7 @@ /obj/item/hand_labeler, /obj/machinery/light/small, /obj/machinery/fax/service, +/obj/item/book/manual/wiki/sopservice, /turf/open/floor/plating{ icon_state = "panelscorched" }, @@ -17136,7 +17137,7 @@ /area/maintenance/port) "bqA" = ( /obj/effect/turf_decal/bot, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/structure/extinguisher_cabinet{ pixel_x = 24 }, @@ -24604,7 +24605,7 @@ /turf/open/floor/plasteel/dark, /area/hallway/secondary/entry) "bUi" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel/dark, /area/hallway/secondary/entry) @@ -37468,6 +37469,7 @@ /obj/machinery/keycard_auth{ pixel_y = 24 }, +/obj/item/book/manual/wiki/sopservice, /turf/open/floor/carpet/blue, /area/crew_quarters/heads/hop) "cIK" = ( @@ -38091,11 +38093,13 @@ pixel_y = 1 }, /obj/item/toy/figure/hos, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/red, /area/crew_quarters/heads/hos) "cKH" = ( /obj/structure/table/wood, /obj/machinery/computer/med_data/laptop, +/obj/item/book/manual/wiki/sopsecurity, /turf/open/floor/carpet/red, /area/crew_quarters/heads/hos) "cKI" = ( @@ -39254,9 +39258,8 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "cNf" = ( -/obj/machinery/power/emitter/anchored{ - dir = 4; - state = 2 +/obj/machinery/power/emitter/welded{ + dir = 4 }, /obj/effect/decal/cleanable/dirt, /obj/structure/cable/yellow{ @@ -39291,9 +39294,8 @@ }, /area/maintenance/solars/starboard/aft) "cNr" = ( -/obj/machinery/power/emitter/anchored{ - dir = 8; - state = 2 +/obj/machinery/power/emitter/welded{ + dir = 8 }, /obj/effect/decal/cleanable/dirt, /obj/structure/cable/yellow{ @@ -40046,9 +40048,8 @@ /obj/machinery/light{ dir = 8 }, -/obj/machinery/power/emitter/anchored{ - dir = 4; - state = 2 +/obj/machinery/power/emitter/welded{ + dir = 4 }, /obj/effect/decal/cleanable/dirt, /obj/structure/cable/yellow, @@ -44320,7 +44321,7 @@ /turf/open/floor/plasteel/showroomfloor, /area/science/robotics/lab) "eHc" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/bot, /obj/effect/turf_decal/stripes/corner{ dir = 4 @@ -44630,6 +44631,7 @@ pixel_x = -20; pixel_y = 22 }, +/obj/item/book/manual/wiki/sopengineering, /turf/open/floor/plasteel/dark, /area/engine/break_room) "eMz" = ( @@ -45622,6 +45624,7 @@ /obj/effect/turf_decal/tile/blue/half/contrasted{ dir = 1 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/plasteel/dark, /area/crew_quarters/heads/hop) "fgG" = ( @@ -45717,6 +45720,7 @@ /obj/machinery/newscaster{ pixel_x = -28 }, +/obj/item/book/manual/wiki/sopsupply, /turf/open/floor/carpet/blue, /area/crew_quarters/heads/hop) "fia" = ( @@ -46745,6 +46749,7 @@ /obj/item/folder/blue, /obj/item/clothing/glasses/hud/health, /obj/effect/turf_decal/tile/blue, +/obj/item/book/manual/wiki/sopmedical, /turf/open/floor/plasteel/showroomfloor, /area/crew_quarters/heads/cmo) "fCk" = ( @@ -48041,7 +48046,7 @@ /obj/structure/extinguisher_cabinet{ pixel_x = -26 }, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/tile/neutral/half/contrasted, /turf/open/floor/plasteel/dark, /area/science/research) @@ -51899,7 +51904,7 @@ /turf/open/floor/plasteel/showroomfloor, /area/medical/chemistry) "hRm" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/stripes/corner, /obj/structure/sign/poster/official/no_erp{ @@ -55771,6 +55776,7 @@ }, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/blue/opposingcorners, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/plasteel/showroomfloor, /area/crew_quarters/heads/cmo) "jty" = ( @@ -56764,6 +56770,7 @@ /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 8 }, +/obj/item/book/manual/wiki/sopmedical, /turf/open/floor/plasteel/dark, /area/medical/storage) "jLq" = ( @@ -60092,7 +60099,7 @@ /turf/open/floor/plasteel/dark, /area/security/warden) "lqS" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel/dark, /area/science/shuttledock) @@ -67044,6 +67051,7 @@ /obj/item/hand_labeler, /obj/item/hand_labeler, /obj/effect/turf_decal/tile/neutral/anticorner/contrasted, +/obj/item/book/manual/wiki/sopsupply, /turf/open/floor/plasteel/dark, /area/quartermaster/storage) "osk" = ( @@ -68096,8 +68104,8 @@ /area/security/main) "oSL" = ( /obj/structure/table, -/obj/item/reagent_containers/food/snacks/dough, -/obj/item/reagent_containers/food/snacks/dough, +/obj/item/food/dough, +/obj/item/food/dough, /obj/item/kitchen/rollingpin, /obj/item/kitchen/rollingpin, /obj/effect/turf_decal/tile/neutral/half/contrasted{ @@ -68644,6 +68652,7 @@ /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 8 }, +/obj/item/book/manual/wiki/sopscience, /turf/open/floor/plasteel/dark, /area/crew_quarters/heads/hor) "pdx" = ( @@ -74162,6 +74171,7 @@ /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 4 }, +/obj/item/book/manual/wiki/sopsecurity, /turf/open/floor/plasteel/dark, /area/security/main) "rmO" = ( @@ -75578,6 +75588,7 @@ /obj/effect/turf_decal/tile/neutral/anticorner/contrasted{ dir = 8 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/plasteel/dark, /area/crew_quarters/heads/hor) "rQa" = ( @@ -75734,6 +75745,7 @@ /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 4 }, +/obj/item/book/manual/wiki/sopengineering, /turf/open/floor/plasteel/dark, /area/crew_quarters/heads/chief) "rST" = ( @@ -78200,7 +78212,7 @@ /area/quartermaster/warehouse) "sQx" = ( /obj/effect/turf_decal/bot, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/machinery/firealarm{ dir = 4; pixel_x = -26 @@ -81767,7 +81779,6 @@ /area/quartermaster/warehouse) "uxt" = ( /obj/structure/table, -/obj/item/storage/fancy/donut_box, /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 1 }, @@ -85744,7 +85755,7 @@ /area/security/warden) "waT" = ( /obj/effect/turf_decal/bot, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/stripes/corner, /obj/machinery/light/small{ dir = 1 @@ -86631,7 +86642,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/aft) "wrQ" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/machinery/light{ dir = 1 }, @@ -87489,7 +87500,7 @@ /turf/open/floor/plasteel/dark, /area/engine/engineering) "wHL" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/machinery/airalarm{ dir = 1; pixel_y = -22 @@ -87538,6 +87549,7 @@ /obj/item/lighter, /obj/item/clothing/mask/cigarette/cigar/cohiba, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/plasteel, /area/crew_quarters/heads/chief) "wIP" = ( @@ -87579,7 +87591,7 @@ /turf/open/floor/plating, /area/maintenance/solars/port/aft) "wJD" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/machinery/light, /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 4 @@ -88077,7 +88089,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/fore) "wSD" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/structure/sign/poster/official/the_owl{ pixel_x = 32 }, @@ -88529,7 +88541,7 @@ /area/crew_quarters/bar/atrium) "xbi" = ( /obj/effect/turf_decal/bot, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/stripes/corner, /obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4, @@ -88890,7 +88902,7 @@ /area/security/warden) "xla" = ( /obj/effect/turf_decal/bot, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/tile/neutral/anticorner/contrasted{ dir = 8 }, @@ -89973,7 +89985,7 @@ /turf/open/floor/plasteel/showroomfloor, /area/science/lab) "xLB" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/bot, /obj/machinery/airalarm{ dir = 8; @@ -90944,6 +90956,7 @@ /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 8 }, +/obj/item/book/manual/wiki/sopscience, /turf/open/floor/plasteel/dark, /area/science/lab) "ygX" = ( @@ -91107,7 +91120,7 @@ /turf/open/floor/plasteel/dark, /area/quartermaster/warehouse) "yjL" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/bot, /obj/effect/turf_decal/tile/neutral/anticorner/contrasted{ dir = 8 diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 5a9b334cf0100..507d596575ddc 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -1621,6 +1621,7 @@ "agh" = ( /obj/structure/table/wood, /obj/item/flashlight/lamp, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/red, /area/crew_quarters/heads/hos) "agi" = ( @@ -1639,6 +1640,7 @@ pixel_y = -1 }, /obj/structure/table/wood, +/obj/item/book/manual/wiki/sopsecurity, /turf/open/floor/carpet/red, /area/crew_quarters/heads/hos) "agk" = ( @@ -3432,6 +3434,7 @@ /obj/structure/table, /obj/item/folder/red, /obj/item/assembly/flash/handheld, +/obj/item/book/manual/wiki/sopsecurity, /turf/open/floor/plasteel, /area/security/main) "apX" = ( @@ -12786,6 +12789,7 @@ req_access_txt = "28" }, /obj/structure/table/wood, +/obj/item/book/manual/wiki/sopservice, /turf/open/floor/wood, /area/crew_quarters/heads/hop) "bmp" = ( @@ -12800,6 +12804,7 @@ /obj/machinery/computer/security/telescreen/vault{ pixel_y = 30 }, +/obj/item/book/manual/wiki/sopsupply, /turf/open/floor/wood, /area/crew_quarters/heads/hop) "bmq" = ( @@ -12808,6 +12813,7 @@ pixel_x = 34 }, /obj/structure/table/wood, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/wood, /area/crew_quarters/heads/hop) "bmr" = ( @@ -13562,7 +13568,7 @@ /turf/open/floor/plasteel/grimy, /area/hallway/primary/port) "bqi" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/machinery/newscaster{ pixel_x = -28; pixel_y = 1 @@ -14035,7 +14041,7 @@ /turf/open/floor/plating, /area/hallway/secondary/entry) "bsl" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/hallway/secondary/entry) @@ -14092,7 +14098,7 @@ /turf/open/floor/plasteel/grimy, /area/hallway/primary/port) "bst" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/plasteel/dark, /area/hallway/primary/port) "bsv" = ( @@ -14205,7 +14211,7 @@ /obj/machinery/light_switch{ pixel_y = -25 }, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/plasteel/dark, /area/bridge) "bsW" = ( @@ -14252,7 +14258,7 @@ /obj/structure/window/reinforced{ dir = 4 }, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/plasteel/dark, /area/bridge) "btc" = ( @@ -15727,7 +15733,7 @@ /turf/closed/wall, /area/hallway/secondary/command) "bzK" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/plasteel/dark, /area/hallway/secondary/command) "bzL" = ( @@ -17964,7 +17970,7 @@ }, /area/crew_quarters/kitchen) "bKl" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/machinery/newscaster{ pixel_y = -29 }, @@ -17991,7 +17997,7 @@ /turf/open/floor/carpet, /area/crew_quarters/bar) "bKp" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/carpet, /area/crew_quarters/bar) "bKq" = ( @@ -20420,7 +20426,7 @@ /turf/open/floor/wood, /area/library) "bTD" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/machinery/newscaster{ pixel_x = -30 }, @@ -22598,7 +22604,7 @@ dir = 8; pixel_x = 24 }, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/plasteel/white/side{ dir = 4 }, @@ -23370,6 +23376,7 @@ /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 8 }, +/obj/item/book/manual/wiki/sopengineering, /turf/open/floor/plasteel, /area/crew_quarters/heads/chief) "cqd" = ( @@ -24373,6 +24380,7 @@ dir = 5; network = list("ss13","medbay") }, +/obj/item/book/manual/wiki/sopmedical, /turf/open/floor/plasteel, /area/medical/storage) "cyz" = ( @@ -27869,9 +27877,8 @@ /obj/structure/cable/white{ icon_state = "0-2" }, -/obj/machinery/power/emitter/anchored{ - dir = 1; - state = 2 +/obj/machinery/power/emitter/welded{ + dir = 1 }, /obj/machinery/light{ dir = 4 @@ -31848,6 +31855,7 @@ /obj/structure/table/glass, /obj/item/folder, /obj/item/toy/figure/engineer, +/obj/item/book/manual/wiki/sopengineering, /turf/open/floor/plasteel, /area/engine/storage_shared) "eyr" = ( @@ -35354,6 +35362,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer2{ dir = 8 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/wood, /area/crew_quarters/heads/captain/private) "fSO" = ( @@ -37349,9 +37358,7 @@ /area/hallway/secondary/exit/departure_lounge) "gRa" = ( /obj/structure/cable/white, -/obj/machinery/power/emitter/anchored{ - state = 2 - }, +/obj/machinery/power/emitter/welded, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4, /turf/open/floor/plating, /area/engine/engineering) @@ -37433,7 +37440,7 @@ /turf/open/floor/plasteel/techmaint, /area/science/shuttledock) "gSL" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, /turf/open/floor/plasteel/dark, /area/hallway/primary/central) @@ -41216,6 +41223,7 @@ pixel_x = -9; pixel_y = 11 }, +/obj/item/book/manual/wiki/sopmedical, /turf/open/floor/carpet/blue, /area/crew_quarters/heads/cmo) "ium" = ( @@ -42221,7 +42229,7 @@ /area/hallway/primary/starboard) "iOP" = ( /obj/machinery/light, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, /turf/open/floor/plasteel/dark, /area/crew_quarters/fitness/recreation) @@ -42834,7 +42842,7 @@ pixel_x = 28 }, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, -/obj/effect/loot_jobscale/armoury/bulletproof_vest, +/obj/effect/loot_jobscale/armoury/riot_suit, /obj/effect/loot_jobscale/armoury/riot_helmet, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) @@ -44019,6 +44027,7 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4, /obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2, +/obj/item/book/manual/wiki/sopsupply, /turf/open/floor/plasteel, /area/quartermaster/storage) "jFI" = ( @@ -50577,6 +50586,7 @@ dir = 1 }, /obj/item/kitchen/rollingpin, +/obj/item/book/manual/wiki/sopservice, /turf/open/floor/plasteel, /area/hallway/secondary/service) "msp" = ( @@ -51275,6 +51285,7 @@ dir = 4 }, /obj/effect/turf_decal/siding/wideplating/dark, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/blue, /area/crew_quarters/heads/cmo) "mFf" = ( @@ -59748,6 +59759,7 @@ /obj/item/stock_parts/capacitor, /obj/item/stock_parts/micro_laser, /obj/item/stock_parts/micro_laser, +/obj/item/book/manual/wiki/sopscience, /turf/open/floor/plasteel, /area/science/lab) "qeZ" = ( @@ -60476,7 +60488,7 @@ /turf/open/floor/plasteel, /area/security/checkpoint/medical) "qvc" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/structure/sign/map/right{ desc = "A framed picture of the station. Clockwise from security in red at the top, you see engineering in yellow, science in purple, escape in checkered red-and-white, medbay in green, arrivals in checkered red-and-blue, and then cargo in brown."; icon_state = "map-right-MS"; @@ -63753,7 +63765,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "rSL" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/trimline/black/filled/line{ dir = 8 }, @@ -64608,7 +64620,7 @@ /turf/open/floor/plasteel, /area/science/mixing) "slA" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, /turf/open/floor/plasteel/dark, /area/hallway/secondary/command) @@ -64799,8 +64811,8 @@ }, /obj/structure/table/reinforced, /obj/item/restraints/handcuffs, -/obj/item/implant/radio, /obj/machinery/firealarm/directional/north, +/obj/item/radio/off, /turf/open/floor/plasteel, /area/security/checkpoint/medical) "sql" = ( @@ -65618,6 +65630,7 @@ /obj/effect/turf_decal/tile/black/opposingcorners{ dir = 1 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/plasteel/white, /area/crew_quarters/heads/hor) "sIB" = ( @@ -67300,6 +67313,7 @@ /obj/effect/turf_decal/tile/black/opposingcorners{ dir = 1 }, +/obj/item/book/manual/wiki/sopscience, /turf/open/floor/plasteel/white, /area/crew_quarters/heads/hor) "ttF" = ( @@ -68229,7 +68243,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/locker) "tPc" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/bot, /obj/effect/turf_decal/siding/dark{ dir = 1 @@ -69448,9 +69462,8 @@ /obj/structure/cable/white{ icon_state = "0-2" }, -/obj/machinery/power/emitter/anchored{ - dir = 1; - state = 2 +/obj/machinery/power/emitter/welded{ + dir = 1 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4, /turf/open/floor/plating, @@ -71834,7 +71847,7 @@ pixel_x = -1; pixel_y = -30 }, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/bot, /obj/effect/turf_decal/siding/dark{ dir = 1 @@ -76130,6 +76143,7 @@ /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 8 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/plasteel, /area/crew_quarters/heads/chief) "xeJ" = ( diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm index 7fde1b26619da..13b78a5e441b7 100644 --- a/_maps/map_files/Mining/Lavaland.dmm +++ b/_maps/map_files/Mining/Lavaland.dmm @@ -175,7 +175,7 @@ /turf/open/floor/plasteel, /area/mine/science) "bf" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/plasteel, /area/mine/living_quarters) "bg" = ( @@ -1726,7 +1726,7 @@ /turf/open/floor/plasteel/techmaint, /area/mine/eva) "lt" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/plasteel, /area/mine/living_quarters) "lu" = ( diff --git a/_maps/map_files/RadStation/RadStation.dmm b/_maps/map_files/RadStation/RadStation.dmm index fddee210cb46f..c3c12a8d19479 100644 --- a/_maps/map_files/RadStation/RadStation.dmm +++ b/_maps/map_files/RadStation/RadStation.dmm @@ -184,6 +184,7 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4, /obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/blue, /area/crew_quarters/heads/hos) "abL" = ( @@ -505,6 +506,7 @@ /obj/structure/cable/yellow{ icon_state = "2-4" }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/plasteel/white, /area/crew_quarters/heads/cmo) "agM" = ( @@ -1425,6 +1427,7 @@ pixel_y = 1 }, /obj/machinery/airalarm/directional/north, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/purple, /area/crew_quarters/heads/hor) "awd" = ( @@ -2428,7 +2431,7 @@ /obj/structure/disposalpipe/segment{ dir = 6 }, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/bot, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, /obj/machinery/power/apc/auto_name/north{ @@ -3112,6 +3115,9 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, +/obj/item/book/manual/wiki/sopcommand, +/obj/item/book/manual/wiki/sopservice, +/obj/item/book/manual/wiki/sopsupply, /turf/open/floor/wood, /area/crew_quarters/heads/hop) "aWV" = ( @@ -4875,6 +4881,7 @@ pixel_y = 4 }, /obj/item/powertool/jaws_of_life, +/obj/item/book/manual/wiki/sopengineering, /turf/open/floor/carpet/royalblue, /area/crew_quarters/heads/chief) "bDe" = ( @@ -5702,10 +5709,10 @@ /area/hallway/primary/central) "bOn" = ( /obj/structure/table, -/obj/item/reagent_containers/food/snacks/dough{ +/obj/item/food/dough{ pixel_x = -4 }, -/obj/item/reagent_containers/food/snacks/dough{ +/obj/item/food/dough{ pixel_y = 1 }, /obj/item/kitchen/rollingpin{ @@ -6892,6 +6899,7 @@ pixel_x = 1; pixel_y = 5 }, +/obj/item/book/manual/wiki/sopsecurity, /turf/open/floor/carpet/blue, /area/crew_quarters/heads/hos) "cjc" = ( @@ -9535,6 +9543,7 @@ pixel_x = 8; pixel_y = 4 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/carpet/royalblue, /area/crew_quarters/heads/chief) "cZw" = ( @@ -14074,9 +14083,8 @@ name = "Brig Cell 3" }) "ert" = ( -/obj/machinery/power/emitter/anchored{ - dir = 2; - state = 2 +/obj/machinery/power/emitter/welded{ + dir = 2 }, /obj/structure/cable/yellow{ icon_state = "0-4" @@ -14204,7 +14212,7 @@ /area/crew_quarters/dorms) "etz" = ( /obj/effect/turf_decal/bot, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/floor/plasteel/dark, /area/hallway/secondary/exit/departure_lounge) "etB" = ( @@ -17039,6 +17047,7 @@ pixel_y = 29 }, /obj/item/hand_labeler, +/obj/item/book/manual/wiki/sopmedical, /turf/open/floor/plasteel, /area/medical/storage) "fiM" = ( @@ -21598,7 +21607,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/bot, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, /obj/machinery/firealarm/directional/north, @@ -23219,7 +23228,7 @@ dir = 10; layer = 3.1 }, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/siding/wideplating/dark{ dir = 10 }, @@ -26455,6 +26464,7 @@ /obj/structure/disposalpipe/segment{ dir = 2 }, +/obj/item/book/manual/wiki/sopscience, /turf/open/floor/plasteel, /area/science/lab) "ibG" = ( @@ -28873,7 +28883,6 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "iUD" = ( -/obj/item/reagent_containers/food/snacks/butter/on_a_stick, /obj/effect/decal/cleanable/crayon, /obj/machinery/light/small{ brightness = 3; @@ -29874,7 +29883,7 @@ pixel_y = 1 }, /obj/effect/turf_decal/stripes/corner, -/obj/item/reagent_containers/food/snacks/piedough, +/obj/item/food/piedough, /obj/machinery/light_switch{ pixel_x = 21 }, @@ -30103,7 +30112,7 @@ /obj/structure/sign/painting/library{ pixel_y = 32 }, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/machinery/firealarm/directional/east, /turf/open/floor/plasteel, /area/medical/break_room) @@ -32195,6 +32204,7 @@ /obj/item/radio/intercom{ pixel_y = 23 }, +/obj/item/book/manual/wiki/sopscience, /turf/open/floor/carpet/purple, /area/crew_quarters/heads/hor) "jVS" = ( @@ -32818,6 +32828,7 @@ /obj/effect/turf_decal/tile/neutral, /obj/structure/rack, /obj/item/stack/sticky_tape, +/obj/item/book/manual/wiki/sopservice, /turf/open/floor/plasteel, /area/hallway/secondary/service) "khE" = ( @@ -40245,7 +40256,7 @@ }) "mAV" = ( /obj/machinery/airalarm/directional/west, -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/science/research) @@ -41920,11 +41931,6 @@ /area/engine/engineering) "mYY" = ( /obj/structure/table/reinforced, -/obj/item/storage/fancy/donut_box{ - name = "Emergency donut box"; - pixel_x = -2; - pixel_y = 15 - }, /obj/item/gun/energy/e_gun/dragnet{ pixel_x = -2; pixel_y = 1 @@ -46633,7 +46639,6 @@ /turf/open/floor/plasteel, /area/gateway) "ovR" = ( -/obj/item/reagent_containers/food/snacks/butteredtoast, /obj/effect/decal/cleanable/crayon, /turf/open/floor/plating{ icon_state = "platingdmg3" @@ -47758,9 +47763,8 @@ }, /area/quartermaster/exploration_prep) "oOw" = ( -/obj/machinery/power/emitter/anchored{ - dir = 2; - state = 2 +/obj/machinery/power/emitter/welded{ + dir = 2 }, /obj/structure/cable/yellow, /obj/structure/cable/yellow{ @@ -48920,7 +48924,7 @@ /turf/open/floor/plasteel/dark, /area/quartermaster/storage) "pkb" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/tile/neutral/half/contrasted, /obj/effect/turf_decal/guideline/guideline_edge/yellow{ dir = 4 @@ -49471,6 +49475,7 @@ pixel_x = -32; pixel_y = -2 }, +/obj/item/book/manual/wiki/sopcommand, /turf/open/floor/wood, /area/crew_quarters/heads/captain) "psf" = ( @@ -51462,7 +51467,7 @@ /obj/effect/turf_decal/guideline/guideline_edge/red{ dir = 1 }, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/plasteel, /area/security/brig) "pWx" = ( @@ -54020,6 +54025,7 @@ pixel_x = 14; pixel_y = 4 }, +/obj/item/book/manual/wiki/sopsupply, /turf/open/floor/plasteel/sepia, /area/quartermaster/office) "qLC" = ( @@ -56867,6 +56873,7 @@ pixel_y = 1 }, /obj/item/folder/white, +/obj/item/book/manual/wiki/sopmedical, /turf/open/floor/plasteel/white, /area/crew_quarters/heads/cmo) "rKZ" = ( @@ -59167,6 +59174,7 @@ pixel_y = 3 }, /obj/item/pipe_dispenser, +/obj/item/book/manual/wiki/sopengineering, /turf/open/floor/plasteel/dark, /area/engine/engineering) "sBR" = ( @@ -63141,7 +63149,7 @@ /obj/machinery/light{ dir = 1 }, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/bot, /obj/effect/turf_decal/tile/neutral/fourcorners/contrasted, /obj/item/radio/intercom{ @@ -63532,6 +63540,7 @@ /obj/structure/cable/yellow{ icon_state = "1-8" }, +/obj/item/book/manual/wiki/sopsecurity, /turf/open/floor/plasteel, /area/security/main{ name = "Security Locker Room" @@ -68477,7 +68486,7 @@ /turf/open/floor/wood, /area/library) "vtj" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/science/research) @@ -70187,7 +70196,6 @@ /turf/closed/wall/r_wall, /area/engine/atmos) "vWl" = ( -/obj/item/food/butterdog, /obj/effect/decal/cleanable/crayon, /turf/open/floor/plating, /area/maintenance/department/medical) @@ -70555,9 +70563,8 @@ /turf/open/floor/plasteel, /area/maintenance/department/medical) "wcw" = ( -/obj/machinery/power/emitter/anchored{ - dir = 2; - state = 2 +/obj/machinery/power/emitter/welded{ + dir = 2 }, /obj/structure/cable/yellow{ icon_state = "0-8" @@ -71689,7 +71696,7 @@ alpha = 180; dir = 8 }, -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /obj/item/radio/intercom{ dir = 8; freerange = 1; @@ -76371,7 +76378,6 @@ /turf/open/floor/noslip/white, /area/crew_quarters/heads/captain/private) "xSK" = ( -/obj/item/food/spaghetti/butternoodles, /obj/effect/decal/cleanable/crayon, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt/dust, diff --git a/_maps/shuttles/emergency/emergency_corg.dmm b/_maps/shuttles/emergency/emergency_corg.dmm index b10b6df792099..739996268dc3d 100644 --- a/_maps/shuttles/emergency/emergency_corg.dmm +++ b/_maps/shuttles/emergency/emergency_corg.dmm @@ -183,7 +183,7 @@ dir = 4 }, /obj/structure/table/reinforced, -/obj/item/reagent_containers/food/snacks/dough, +/obj/item/food/dough, /obj/item/kitchen/rollingpin, /turf/open/floor/plasteel, /area/shuttle/escape) diff --git a/_maps/shuttles/emergency/emergency_luxury.dmm b/_maps/shuttles/emergency/emergency_luxury.dmm index fe8f8c48b3521..3bb25889e476c 100644 --- a/_maps/shuttles/emergency/emergency_luxury.dmm +++ b/_maps/shuttles/emergency/emergency_luxury.dmm @@ -154,7 +154,7 @@ /area/shuttle/escape/luxury) "aC" = ( /obj/structure/table/wood/fancy, -/obj/item/reagent_containers/food/snacks/enchiladas, +/obj/item/food/enchiladas, /turf/open/floor/carpet, /area/shuttle/escape/luxury) "aD" = ( @@ -194,7 +194,7 @@ /area/shuttle/escape/luxury) "aK" = ( /obj/structure/table/wood/fancy, -/obj/item/reagent_containers/food/snacks/carneburrito, +/obj/item/food/carneburrito, /turf/open/floor/carpet, /area/shuttle/escape/luxury) "aL" = ( diff --git a/_maps/shuttles/pirate/pirate_default.dmm b/_maps/shuttles/pirate/pirate_default.dmm index b8dc307e12514..4d989a7aa7f6e 100644 --- a/_maps/shuttles/pirate/pirate_default.dmm +++ b/_maps/shuttles/pirate/pirate_default.dmm @@ -748,7 +748,7 @@ /obj/item/ammo_box/magazine/m12g, /obj/item/ammo_box/magazine/m12g, /obj/item/ammo_box/magazine/m12g, -/obj/item/gun/ballistic/shotgun/bulldog/unrestricted, +/obj/item/gun/ballistic/shotgun/automatic/bulldog/unrestricted, /turf/open/floor/pod/light, /area/shuttle/pirate) "wR" = ( diff --git a/_maps/shuttles/whiteship/whiteship_box.dmm b/_maps/shuttles/whiteship/whiteship_box.dmm index 407ccd5d289ec..ae480e2b57674 100644 --- a/_maps/shuttles/whiteship/whiteship_box.dmm +++ b/_maps/shuttles/whiteship/whiteship_box.dmm @@ -1905,7 +1905,7 @@ }, /obj/item/reagent_containers/food/snacks/muffin/berry, /obj/item/reagent_containers/food/snacks/tofu, -/obj/item/reagent_containers/food/snacks/burrito, +/obj/item/food/burrito, /obj/structure/cable/yellow{ icon_state = "0-8" }, diff --git a/_maps/templates/shelter_3.dmm b/_maps/templates/shelter_3.dmm index bb1cf090ae56d..ac53b420e236c 100644 --- a/_maps/templates/shelter_3.dmm +++ b/_maps/templates/shelter_3.dmm @@ -236,7 +236,7 @@ /turf/open/floor/carpet/black, /area/survivalpod) "L" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/floor/carpet/black, /area/survivalpod) "M" = ( diff --git a/_maps/templates/warped_room.dmm b/_maps/templates/warped_room.dmm index 2a31d57426503..c8c87db0e8828 100644 --- a/_maps/templates/warped_room.dmm +++ b/_maps/templates/warped_room.dmm @@ -133,11 +133,11 @@ /turf/open/indestructible/hotelwood, /area/warped_room) "A" = ( -/obj/effect/spawner/randomcolavend, +/obj/effect/spawner/randomvend/cola, /turf/open/indestructible/hotelwood, /area/warped_room) "B" = ( -/obj/effect/spawner/randomsnackvend, +/obj/effect/spawner/randomvend/snack, /turf/open/indestructible/hotelwood, /area/warped_room) "C" = ( diff --git a/beestation.dme b/beestation.dme index 3c01074ec9950..149998da611ec 100644 --- a/beestation.dme +++ b/beestation.dme @@ -459,8 +459,8 @@ #include "code\controllers\subsystem\zclear.dm" #include "code\controllers\subsystem\zcopy.dm" #include "code\controllers\subsystem\movement\ai_movement.dm" -#include "code\controllers\subsystem\movement\hyperspace_drift.dm" #include "code\controllers\subsystem\movement\conveyors.dm" +#include "code\controllers\subsystem\movement\hyperspace_drift.dm" #include "code\controllers\subsystem\movement\move_handler.dm" #include "code\controllers\subsystem\movement\movement.dm" #include "code\controllers\subsystem\movement\movement_types.dm" @@ -613,7 +613,6 @@ #include "code\datums\components\edit_complainer.dm" #include "code\datums\components\effect_remover.dm" #include "code\datums\components\embedded.dm" -#include "code\datums\components\empprotection.dm" #include "code\datums\components\explodable.dm" #include "code\datums\components\footstep.dm" #include "code\datums\components\force_move.dm" @@ -783,6 +782,7 @@ #include "code\datums\elements\digital_camo.dm" #include "code\datums\elements\earhealing.dm" #include "code\datums\elements\embed.dm" +#include "code\datums\elements\empprotection.dm" #include "code\datums\elements\firestacker.dm" #include "code\datums\elements\forced_gravity.dm" #include "code\datums\elements\frozen.dm" @@ -796,6 +796,8 @@ #include "code\datums\elements\ranged_attacks.dm" #include "code\datums\elements\rust.dm" #include "code\datums\elements\squish.dm" +#include "code\datums\elements\update_icon_blocker.dm" +#include "code\datums\elements\update_icon_updates_onmob.dm" #include "code\datums\elements\strippable.dm" #include "code\datums\elements\undertile.dm" #include "code\datums\elements\weather_listener.dm" @@ -816,6 +818,7 @@ #include "code\datums\helper_datums\events.dm" #include "code\datums\helper_datums\getrev.dm" #include "code\datums\helper_datums\icon_snapshot.dm" +#include "code\datums\helper_datums\stack_end_detector.dm" #include "code\datums\helper_datums\teleport.dm" #include "code\datums\keybinding\_defines.dm" #include "code\datums\keybinding\admin.dm" @@ -1397,6 +1400,8 @@ #include "code\game\objects\items\food\bread.dm" #include "code\game\objects\items\food\burgers.dm" #include "code\game\objects\items\food\cake.dm" +#include "code\game\objects\items\food\dough.dm" +#include "code\game\objects\items\food\mexican.dm" #include "code\game\objects\items\food\pizza.dm" #include "code\game\objects\items\food\spaghetti.dm" #include "code\game\objects\items\grenades\_grenade.dm" @@ -2549,7 +2554,6 @@ #include "code\modules\food_and_drinks\food\snacks_sandwichtoast.dm" #include "code\modules\food_and_drinks\food\snacks_soup.dm" #include "code\modules\food_and_drinks\food\snacks_vend.dm" -#include "code\modules\food_and_drinks\food\snacks\dough.dm" #include "code\modules\food_and_drinks\food\snacks\meat.dm" #include "code\modules\food_and_drinks\kitchen_machinery\deep_fryer.dm" #include "code\modules\food_and_drinks\kitchen_machinery\food_cart.dm" @@ -2570,6 +2574,7 @@ #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_egg.dm" #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_frozen.dm" #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_meat.dm" +#include "code\modules\food_and_drinks\recipes\tablecraft\recipes_mexican.dm" #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_misc.dm" #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_pastry.dm" #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_pie.dm" @@ -2579,6 +2584,7 @@ #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_soup.dm" #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_spaghetti.dm" #include "code\modules\games\cas.dm" +#include "code\modules\games\tarot.dm" #include "code\modules\games\unum.dm" #include "code\modules\holiday\easter.dm" #include "code\modules\holiday\holidays.dm" @@ -2890,6 +2896,7 @@ #include "code\modules\mob\living\death.dm" #include "code\modules\mob\living\emote.dm" #include "code\modules\mob\living\inhand_holder.dm" +#include "code\modules\mob\living\init_signals.dm" #include "code\modules\mob\living\life.dm" #include "code\modules\mob\living\living.dm" #include "code\modules\mob\living\living_defense.dm" @@ -3652,6 +3659,7 @@ #include "code\modules\research\nanites\extra_settings\type.dm" #include "code\modules\research\nanites\nanite_programs\buffing.dm" #include "code\modules\research\nanites\nanite_programs\healing.dm" +#include "code\modules\research\nanites\nanite_programs\protocol.dm" #include "code\modules\research\nanites\nanite_programs\rogue.dm" #include "code\modules\research\nanites\nanite_programs\sensor.dm" #include "code\modules\research\nanites\nanite_programs\suppression.dm" @@ -4072,8 +4080,8 @@ #include "code\modules\wiremod\components\string\tostring.dm" #include "code\modules\wiremod\components\utility\clock.dm" #include "code\modules\wiremod\components\utility\delay.dm" -#include "code\modules\wiremod\components\utility\iterator.dm" #include "code\modules\wiremod\components\utility\getter.dm" +#include "code\modules\wiremod\components\utility\iterator.dm" #include "code\modules\wiremod\components\utility\router.dm" #include "code\modules\wiremod\components\utility\setter.dm" #include "code\modules\wiremod\components\utility\typecast.dm" diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm index 980970b1891c7..973196b2a269d 100644 --- a/code/__DEFINES/construction.dm +++ b/code/__DEFINES/construction.dm @@ -73,32 +73,33 @@ #define MAXCOIL 30 // tablecrafting defines -#define CAT_NONE "" -#define CAT_WEAPONRY "Weaponry" -#define CAT_WEAPON "Weapons" -#define CAT_AMMO "Ammunition" -#define CAT_ROBOT "Robots" -#define CAT_MISC "Misc" -#define CAT_PRIMAL "Tribal" -#define CAT_CLOTHING "Clothing" -#define CAT_EYEWEAR "Eyewear" -#define CAT_FOOD "Foods" -#define CAT_BREAD "Breads" -#define CAT_BURGER "Burgers" -#define CAT_CAKE "Cakes" -#define CAT_EGG "Egg-Based Food" -#define CAT_MEAT "Meats" -#define CAT_MISCFOOD "Misc. Food" -#define CAT_PASTRY "Pastries" -#define CAT_PIE "Pies" -#define CAT_PIZZA "Pizzas" -#define CAT_SALAD "Salads" -#define CAT_SANDWICH "Sandwiches" -#define CAT_SOUP "Soups" -#define CAT_SPAGHETTI "Spaghettis" -#define CAT_ICE "Frozen" -#define CAT_DRINK "Drinks" -#define CAT_STRUCTURE "Structures" +#define CAT_NONE "" +#define CAT_WEAPONRY "Weaponry" +#define CAT_WEAPON "Weapons" +#define CAT_AMMO "Ammunition" +#define CAT_ROBOT "Robots" +#define CAT_MISC "Misc" +#define CAT_PRIMAL "Tribal" +#define CAT_CLOTHING "Clothing" +#define CAT_EYEWEAR "Eyewear" +#define CAT_FOOD "Foods" +#define CAT_BREAD "Breads" +#define CAT_BURGER "Burgers" +#define CAT_CAKE "Cakes" +#define CAT_EGG "Egg-Based Food" +#define CAT_MEAT "Meats" +#define CAT_MISCFOOD "Misc. Food" +#define CAT_MEXICAN "Mexican Food" +#define CAT_PASTRY "Pastries" +#define CAT_PIE "Pies" +#define CAT_PIZZA "Pizzas" +#define CAT_SALAD "Salads" +#define CAT_SANDWICH "Sandwiches" +#define CAT_SOUP "Soups" +#define CAT_SPAGHETTI "Spaghettis" +#define CAT_ICE "Frozen" +#define CAT_DRINK "Drinks" +#define CAT_STRUCTURE "Structures" // rcd buildtype defines #define RCD_FLOORWALL 1 diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_living.dm index a089a3995c0f7..0651d6667790c 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_living.dm @@ -3,11 +3,18 @@ // All signals send the source datum of the signal as the first argument // /mob/living signals -#define COMSIG_LIVING_REVIVE "living_revive" //! from base of mob/living/revive() (/mob/living, full_heal, admin_revive) -#define COMSIG_LIVING_RESIST "living_resist" //! from base of mob/living/resist() (/mob/living) -#define COMSIG_LIVING_IGNITED "living_ignite" //! from base of mob/living/IgniteMob() (/mob/living) -#define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //! from base of mob/living/ExtinguishMob() (/mob/living) -#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //! from base of mob/living/electrocute_act(): (shock_damage) +///from base of mob/living/resist() (/mob/living) +#define COMSIG_LIVING_RESIST "living_resist" +///from base of mob/living/IgniteMob() (/mob/living) +#define COMSIG_LIVING_IGNITED "living_ignite" +///from base of mob/living/extinguish_mob() (/mob/living) +#define COMSIG_LIVING_EXTINGUISHED "living_extinguished" +///from base of mob/living/electrocute_act(): (shock_damage, source, siemens_coeff, flags) +#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" +///from base of mob/living/revive() (full_heal, admin_revive) +#define COMSIG_LIVING_REVIVE "living_revive" +///from base of mob/living/set_buckled(): (new_buckled) +#define COMSIG_LIVING_SET_BUCKLED "living_set_buckled" #define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //! sent by stuff like stunbatons and tasers: () #define COMSIG_PROCESS_BORGCHARGER_OCCUPANT "living_charge" //! sent from borg recharge stations: (amount, repairs) #define COMSIG_LIVING_TRY_SYRINGE "living_try_syringe" ///From post-can inject check of syringe after attack (mob/user) diff --git a/code/__DEFINES/dcs/signals/signals_movable.dm b/code/__DEFINES/dcs/signals/signals_movable.dm index 5a39adb57ad77..0da2cee47caf2 100644 --- a/code/__DEFINES/dcs/signals/signals_movable.dm +++ b/code/__DEFINES/dcs/signals/signals_movable.dm @@ -33,6 +33,10 @@ #define HEARING_MESSAGE_MODE 7 #define COMSIG_MOVABLE_DISPOSING "movable_disposing" //! called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source) + +///from base of atom/movable/setGrabState(): (newstate) +#define COMSIG_MOVABLE_SET_GRAB_STATE "living_set_grab_state" + // called when movable is expelled from a disposal pipe, bin or outlet on obj/pipe_eject: (direction) #define COMSIG_MOVABLE_PIPE_EJECTING "movable_pipe_ejecting" diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index 062929388c080..0039cc07119ef 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -73,6 +73,8 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define BLOCK_SUICIDE (1<<8) /// Can the Xenobio management console transverse this area by default? #define XENOBIOLOGY_COMPATIBLE (1<<9) +/// Are hidden stashes allowed to spawn here? +#define HIDDEN_STASH_LOCATION (1<<10) /* These defines are used specifically with the atom/pass_flags bitmask diff --git a/code/__DEFINES/icon_smoothing.dm b/code/__DEFINES/icon_smoothing.dm index 5ee61045c703c..f5daf0f095a17 100644 --- a/code/__DEFINES/icon_smoothing.dm +++ b/code/__DEFINES/icon_smoothing.dm @@ -11,7 +11,10 @@ #define SMOOTH_QUEUED (1<<4) /// Smooths with objects, and will thus need to scan turfs for contents. #define SMOOTH_OBJ (1<<5) - +/// Smooths with atoms facing the same direction only +#define SMOOTH_DIRECTIONAL (1<<6) +/// Skips the corner step of bitmask smoothing (does nothing without SMOOTH_BITMASK) +#define SMOOTH_BITMASK_SKIP_CORNERS (1<<7) DEFINE_BITFIELD(smoothing_flags, list( "SMOOTH_CORNERS" = SMOOTH_CORNERS, @@ -20,6 +23,8 @@ DEFINE_BITFIELD(smoothing_flags, list( "SMOOTH_BORDER" = SMOOTH_BORDER, "SMOOTH_QUEUED" = SMOOTH_QUEUED, "SMOOTH_OBJ" = SMOOTH_OBJ, + "SMOOTH_DIRECTIONAL" = SMOOTH_DIRECTIONAL, + "SMOOTH_BITMASK_SKIP_CORNERS" = SMOOTH_BITMASK_SKIP_CORNERS, )) @@ -114,6 +119,7 @@ DEFINE_BITFIELD(smoothing_flags, list( #define SMOOTH_GROUP_HEDGE_FLUFF S_OBJ(65) ///obj/structure/fluff/hedge #define SMOOTH_GROUP_SHUTTLE_PARTS S_OBJ(66) ///obj/structure/window/shuttle, /obj/structure/window/plasma/reinforced/plastitanium, /turf/closed/indestructible/opsglass, /obj/structure/shuttle #define SMOOTH_GROUP_CLEANABLE_DIRT S_OBJ(67) ///obj/effect/decal/cleanable/dirt +#define SMOOTH_GROUP_COMPUTERS S_OBJ(68) ///obj/machinery/computer/_computer //LIQUIDS diff --git a/code/__DEFINES/jobs.dm b/code/__DEFINES/jobs.dm index e0383f51ddb5d..e17898c697df3 100644 --- a/code/__DEFINES/jobs.dm +++ b/code/__DEFINES/jobs.dm @@ -96,9 +96,8 @@ #define JOB_DISPLAY_ORDER_DETECTIVE 30 #define JOB_DISPLAY_ORDER_SECURITY_OFFICER 31 #define JOB_DISPLAY_ORDER_BRIG_PHYS 32 -#define JOB_DISPLAY_ORDER_DEPUTY 33 -#define JOB_DISPLAY_ORDER_AI 34 -#define JOB_DISPLAY_ORDER_CYBORG 35 +#define JOB_DISPLAY_ORDER_AI 33 +#define JOB_DISPLAY_ORDER_CYBORG 34 #define DEPT_BITFLAG_COM (1<<0) diff --git a/code/__DEFINES/logging.dm b/code/__DEFINES/logging.dm index 60aea0158b562..0d4c034ef0a17 100644 --- a/code/__DEFINES/logging.dm +++ b/code/__DEFINES/logging.dm @@ -1,21 +1,22 @@ //Investigate logging defines -#define INVESTIGATE_ATMOS "atmos" -#define INVESTIGATE_BOTANY "botany" -#define INVESTIGATE_CARGO "cargo" -#define INVESTIGATE_EXPERIMENTOR "experimentor" -#define INVESTIGATE_GRAVITY "gravity" -#define INVESTIGATE_RECORDS "records" -#define INVESTIGATE_ENGINES "engines" -#define INVESTIGATE_TELESCI "telesci" -#define INVESTIGATE_WIRES "wires" -#define INVESTIGATE_PORTAL "portals" -#define INVESTIGATE_RESEARCH "research" -#define INVESTIGATE_HALLUCINATIONS "hallucinations" -#define INVESTIGATE_RADIATION "radiation" -#define INVESTIGATE_EXONET "exonet" -#define INVESTIGATE_NANITES "nanites" -#define INVESTIGATE_PRESENTS "presents" -#define INVESTIGATE_ITEMS "items" +#define INVESTIGATE_ATMOS "atmos" +#define INVESTIGATE_BOTANY "botany" +#define INVESTIGATE_CARGO "cargo" +#define INVESTIGATE_DEATHS "deaths" +#define INVESTIGATE_ENGINES "engines" +#define INVESTIGATE_EXONET "exonet" +#define INVESTIGATE_EXPERIMENTOR "experimentor" +#define INVESTIGATE_GRAVITY "gravity" +#define INVESTIGATE_HALLUCINATIONS "hallucinations" +#define INVESTIGATE_ITEMS "items" +#define INVESTIGATE_NANITES "nanites" +#define INVESTIGATE_PORTAL "portals" +#define INVESTIGATE_PRESENTS "presents" +#define INVESTIGATE_RADIATION "radiation" +#define INVESTIGATE_RECORDS "records" +#define INVESTIGATE_RESEARCH "research" +#define INVESTIGATE_TELESCI "telesci" +#define INVESTIGATE_WIRES "wires" #define INVESTIGATE_VERB_PICKEDUP "picked up" #define INVESTIGATE_VERB_DROPPED "dropped" diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm index 19a4e9fcdca51..f3d432443c1d1 100644 --- a/code/__DEFINES/maths.dm +++ b/code/__DEFINES/maths.dm @@ -22,7 +22,7 @@ #define TICK_USAGE_TO_MS(starting_tickusage) (TICK_DELTA_TO_MS(TICK_USAGE_REAL - starting_tickusage)) #define PERCENT(val) (round((val)*100, 0.1)) -#define CLAMP01(x) (CLAMP(x, 0, 1)) +#define CLAMP01(x) (clamp(x, 0, 1)) //time of day but automatically adjusts to the server going into the next day within the same round. //for when you need a reliable time number that doesn't depend on byond time. @@ -39,19 +39,14 @@ /// `round()` acts like `floor(x, 1)` by default but can't handle other values #define FLOOR(x, y) ( round((x) / (y)) * (y) ) -#define CLAMP(CLVALUE,CLMIN,CLMAX) clamp(CLVALUE, CLMIN, CLMAX) - /// Similar to clamp but the bottom rolls around to the top and vice versa. min is inclusive, max is exclusive #define WRAP(val, min, max) ( min == max ? min : (val) - (round(((val) - (min))/((max) - (min))) * ((max) - (min))) ) /// Real modulus that handles decimals #define MODULUS(x, y) ( (x) - FLOOR(x, y)) -/// Tangent -#define TAN(x) tan(x) - /// Cotangent -#define COT(x) (1 / TAN(x)) +#define COT(x) (1 / tan(x)) /// Secant #define SEC(x) (1 / cos(x)) @@ -191,8 +186,8 @@ while(pixel_y < -16) pixel_y += 32 new_y-- - new_x = CLAMP(new_x, 0, world.maxx) - new_y = CLAMP(new_y, 0, world.maxy) + new_x = clamp(new_x, 0, world.maxx) + new_y = clamp(new_y, 0, world.maxy) return locate(new_x, new_y, starting.z) /// Returns a list where [1] is all x values and [2] is all y values that overlap between the given pair of rectangles @@ -217,7 +212,7 @@ #define EXP_DISTRIBUTION(desired_mean) ( -(1/(1/desired_mean)) * log(rand(1, 1000) * 0.001) ) -#define LORENTZ_DISTRIBUTION(x, s) ( s*TAN(TODEGREES(PI*(rand()-0.5))) + x ) +#define LORENTZ_DISTRIBUTION(x, s) ( s*tan(TODEGREES(PI*(rand()-0.5))) + x ) #define LORENTZ_CUMULATIVE_DISTRIBUTION(x, y, s) ( (1/PI)*TORADIANS(arctan((x-y)/s)) + 1/2 ) #define RULE_OF_THREE(a, b, x) ((a*x)/b) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 1e650b93c7e30..d2e7a2f047554 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -515,6 +515,9 @@ #define VOMIT_TOXIC 1 /// The mob will vomit a purple color #define VOMIT_PURPLE 2 +/// The mob will vomit up nanites +#define VOMIT_NANITE 3 + /// Messages when (something) lays an egg #define EGG_LAYING_MESSAGES list("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.") diff --git a/code/__DEFINES/nanites.dm b/code/__DEFINES/nanites.dm index 8915070e8024a..cf5a3431d1c85 100644 --- a/code/__DEFINES/nanites.dm +++ b/code/__DEFINES/nanites.dm @@ -48,9 +48,24 @@ #define NES_ICON "Icon" #define NES_COLOR "Color" #define NES_RULE_LOGIC "Logic" +#define NES_NUTRITION "Nutrition" +#define NES_BLOOD_PERCENT "Blood Percent" +#define NES_SIGNAL_FREQUENCY "Signal Frequency" +#define NES_SIGNAL_CODE "Signal Code" +#define NES_ACTIVATION_CODE "Sent Activation Code" +#define NES_DEACTIVATION_CODE "Sent Deactivation Code" //Nanite Logic #define NL_AND "AND" #define NL_OR "OR" #define NL_NOR "NOR" #define NL_NAND "NAND" +#define NL_ALL list(NL_AND, NL_OR, NL_NOR, NL_NAND) + +//Nanite excess thresholds +#define NANITE_EXCESS_MINOR 25 +#define NANITE_EXCESS_VOMIT 100 +#define NANITE_EXCESS_BURST 350 + +/// How many nanites/sec to add to the regen rate once nanite harmonics are researched +#define HARMONIC_REGEN_BOOST 0.1 diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm index 811fd56ad21bf..3ec2ac2811aa5 100644 --- a/code/__DEFINES/obj_flags.dm +++ b/code/__DEFINES/obj_flags.dm @@ -31,6 +31,7 @@ #define WAS_THROWN (1<<14) //if the item was thrown and shouldn't have the drop_item animation applied #define ISWEAPON (1<<15) //! If this item should hit living mobs when used on harm intent #define EXAMINE_SKIP (1<<16) //! Examine will not read out this item +#define ISCARVABLE (1<<17) //! Examine will not read out this item // Flags for the clothing_flags var on /obj/item/clothing diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index efb6b9ad75774..c9da8c7c4b4a1 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -144,12 +144,45 @@ GLOBAL_LIST_INIT(helmet_styles, list( #define PREFERENCE_TAG_PAI_DESCRIPTION "pai_description" #define PREFERENCE_TAG_PAI_COMMENT "pai_comment" +GLOBAL_LIST_INIT(undatumized_preference_tags_player, list( + PREFERENCE_TAG_LAST_CL, + PREFERENCE_TAG_DEFAULT_SLOT, + PREFERENCE_TAG_IGNORING, + PREFERENCE_TAG_KEYBINDS, + PREFERENCE_TAG_PURCHASED_GEAR, + PREFERENCE_TAG_ROLE_PREFERENCES_GLOBAL, + PREFERENCE_TAG_PAI_NAME, + PREFERENCE_TAG_PAI_DESCRIPTION, + PREFERENCE_TAG_PAI_COMMENT, +)) + +GLOBAL_PROTECT(undatumized_preference_tags_player) + #define CHARACTER_PREFERENCE_RANDOMIZE "randomize" #define CHARACTER_PREFERENCE_JOB_PREFERENCES "job_preferences" #define CHARACTER_PREFERENCE_ALL_QUIRKS "all_quirks" #define CHARACTER_PREFERENCE_EQUIPPED_GEAR "equipped_gear" #define CHARACTER_PREFERENCE_ROLE_PREFERENCES "role_preferences" +GLOBAL_LIST_INIT(undatumized_preference_tags_character, list( + CHARACTER_PREFERENCE_RANDOMIZE, + CHARACTER_PREFERENCE_JOB_PREFERENCES, + CHARACTER_PREFERENCE_ALL_QUIRKS, + CHARACTER_PREFERENCE_EQUIPPED_GEAR, + CHARACTER_PREFERENCE_ROLE_PREFERENCES, +)) + +GLOBAL_PROTECT(undatumized_preference_tags_character) + #define PREFERENCE_SHEET_NORMAL "preferences" #define PREFERENCE_SHEET_LARGE "preferences_l" #define PREFERENCE_SHEET_HUGE "preferences_h" + +/// Stop loading immediately, inform the user. Do not save the data. +#define PREFERENCE_LOAD_ERROR 0 +/// There is no data to load, they are a guest and will never have this data. +#define PREFERENCE_LOAD_IGNORE 1 +/// No data found - create a new character, continue loading +#define PREFERENCE_LOAD_NO_DATA 2 +/// Normal behavior - success! +#define PREFERENCE_LOAD_SUCCESS 3 diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm index 6187a67825a47..9825cd118b682 100644 --- a/code/__DEFINES/tgs.dm +++ b/code/__DEFINES/tgs.dm @@ -1,6 +1,6 @@ // tgstation-server DMAPI -#define TGS_DMAPI_VERSION "6.5.3" +#define TGS_DMAPI_VERSION "6.6.0" // All functions and datums outside this document are subject to change with any version and should not be relied on. @@ -129,6 +129,13 @@ /// DreamDaemon Ultrasafe security level. #define TGS_SECURITY_ULTRASAFE 2 +/// DreamDaemon public visibility level. +#define TGS_VISIBILITY_PUBLIC 0 +/// DreamDaemon private visibility level. +#define TGS_VISIBILITY_PRIVATE 1 +/// DreamDaemon invisible visibility level. +#define TGS_VISIBILITY_INVISIBLE 2 + //REQUIRED HOOKS /** @@ -458,6 +465,10 @@ /world/proc/TgsSecurityLevel() return +/// Returns the current BYOND visibility level as a TGS_VISIBILITY_ define if TGS is present, null otherwise. Requires TGS to be using interop API version 5 or higher otherwise the string "___unimplemented" wil be returned. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! +/world/proc/TgsVisibility() + return + /// Returns a list of active [/datum/tgs_revision_information/test_merge]s if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsTestMerges() return diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index fc4186ed9c8b1..8db354a4fe56c 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -122,15 +122,34 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming traits. */ -/* -Remember to update _globalvars/traits.dm if you're adding/removing/renaming traits. +// mob traits for temporary carbon states/status_effects. // TODO: Systematically dismember update_mobility and replace all its checks and updates with these traits, or offload to stat + +/// Forces the user to stay unconscious. This shouldn't be used in a check outside of code related to stat and update_stat, or when its being intentionally applied from a specific source +#define TRAIT_KNOCKEDOUT "knockedout" +/// Prevents voluntary movement. +#define TRAIT_IMMOBILIZED "immobilized" +/* All to replace update_mobility with traits +/// Prevents voluntary standing or staying up on its own. +#define TRAIT_FLOORED "floored" +/// Forces user to stay standing (ensures the unconscious/immobilized dont enter a lying position in cryopods) +#define TRAIT_FORCED_STANDING "forcedstanding" +/// Prevents usage of manipulation appendages (picking, holding or using items, manipulating storage). +#define TRAIT_HANDS_BLOCKED "handsblocked" +/// Inability to access UI hud elements. Turned into a trait from [MOBILITY_UI] to be able to track sources. +#define TRAIT_UI_BLOCKED "uiblocked" +/// Inability to pull things. Turned into a trait from [MOBILITY_PULL] to be able to track sources. +#define TRAIT_PULL_BLOCKED "pullblocked" +/// Abstract condition that prevents movement if being pulled and might be resisted against. Handcuffs and straight jackets, basically. +#define TRAIT_RESTRAINED "restrained" */ +#define TRAIT_INCAPACITATED "incapacitated" //mob traits -#define TRAIT_INCAPACITATED "incapacitated" -#define TRAIT_BLIND "blind" -#define TRAIT_MUTE "mute" -#define TRAIT_EMOTEMUTE "emotemute" +#define TRAIT_BLIND "blind" +/// Mute. Can't talk. +#define TRAIT_MUTE "mute" +/// Emotemute. Can't... emote. +#define TRAIT_EMOTEMUTE "emotemute" #define TRAIT_DEAF "deaf" #define TRAIT_NEARSIGHT "nearsighted" #define TRAIT_FAT "fat" @@ -177,6 +196,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_NOLIMBDISABLE "no_limb_disable" #define TRAIT_EASYLIMBDISABLE "easy_limb_disable" #define TRAIT_TOXINLOVER "toxinlover" +#define TRAIT_NOHAIRLOSS "no_hair_loss" #define TRAIT_NOBREATH "no_breath" #define TRAIT_ANTIMAGIC "anti_magic" #define TRAIT_HOLY "holy" @@ -285,6 +305,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_LIVING_HEART "living_heart" /// Prevents stripping this equipment #define TRAIT_NO_STRIP "no_strip" +/// Buckling yourself to objects with this trait won't immobilize you +#define TRAIT_NO_IMMOBILIZE "no_immobilize" //quirk traits #define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance" @@ -342,6 +364,14 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define CLOTHING_FEET_TRAIT "feet" #define VEHICLE_TRAIT "vehicle" // inherited from riding vehicles #define INNATE_TRAIT "innate" +#define CRIT_HEALTH_TRAIT "crit_health" +#define OXYLOSS_TRAIT "oxyloss" +//trait associated to being buckled +#define BUCKLED_TRAIT "buckled" +//trait associated to being held in a chokehold +#define CHOKEHOLD_TRAIT "chokehold" +//trait associated to resting +#define RESTING_TRAIT "resting" #define GLASSES_TRAIT "glasses" #define CURSE_TRAIT "eldritch" #define STATION_TRAIT "station-trait" @@ -401,7 +431,10 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define BATTLE_ROYALE_TRAIT "battleroyale_trait" #define MADE_UNCLONEABLE "made-uncloneable" #define TRAIT_JAWS_OF_LIFE "jaws-of-life" -#define STICKY_NODROP "sticky-nodrop" //sticky nodrop sounds like a bad soundcloud rapper's name +#define STICKY_NODROP "sticky-nodrop" //sticky nodrop sounds like a good soundcloud rapper's name +//#define SKILLCHIP_TRAIT "skillchip" +#define PULLED_WHILE_SOFTCRIT_TRAIT "pulled-while-softcrit" +#define LOCKED_BORG_TRAIT "locked-borg" #define TRAIT_PRESERVE_UI_WITHOUT_CLIENT "preserve_ui_without_client" //this mob should never close ui even if it doesn't have a client #define EXPERIMENTAL_SURGERY_TRAIT "experimental_surgery" #define NINJA_KIDNAPPED_TRAIT "ninja_kidnapped" diff --git a/code/__DEFINES/uplink.dm b/code/__DEFINES/uplink.dm index 7f55c3128ec28..59dbf000fae26 100644 --- a/code/__DEFINES/uplink.dm +++ b/code/__DEFINES/uplink.dm @@ -11,3 +11,6 @@ /// This item is purchasable to clown ops #define UPLINK_CLOWN_OPS (1 << 3) + +/// This item is purchasable to excommunicates +#define UPLINK_EXCOMMUNICATE (1 << 4) diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index 8dfac33476a7f..16f72cccfc694 100644 --- a/code/__HELPERS/_logging.dm +++ b/code/__HELPERS/_logging.dm @@ -253,6 +253,10 @@ entry += ":\n[text]" WRITE_LOG(GLOB.tgui_log, entry) +/proc/log_preferences(text) + if(CONFIG_GET(flag/log_preferences)) + WRITE_LOG(GLOB.prefs_log, 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/icon_smoothing.dm b/code/__HELPERS/icon_smoothing.dm index 1e11a6ec1ccff..6cfa33ad1c6a6 100644 --- a/code/__HELPERS/icon_smoothing.dm +++ b/code/__HELPERS/icon_smoothing.dm @@ -241,29 +241,36 @@ DEFINE_BITFIELD(smoothing_junction, list( if((source_area.area_limited_icon_smoothing && !istype(target_area, source_area.area_limited_icon_smoothing)) || (target_area.area_limited_icon_smoothing && !istype(source_area, target_area.area_limited_icon_smoothing))) return NO_ADJ_FOUND + var/atom/match //Used later in a special check + if(isnull(canSmoothWith)) //special case in which it will only smooth with itself if(isturf(src)) - return (type == target_turf.type) ? ADJ_FOUND : NO_ADJ_FOUND - var/atom/matching_obj = locate(type) in target_turf - return (matching_obj && matching_obj.type == type) ? ADJ_FOUND : NO_ADJ_FOUND + match = (type == target_turf.type) ? target_turf : null + else + var/atom/matching_obj = locate(type) in target_turf + match = (matching_obj && matching_obj.type == type) ? matching_obj : null - if(!isnull(target_turf.smoothing_groups)) + if(isnull(match) && !isnull(target_turf.smoothing_groups)) for(var/target in canSmoothWith) - if(!(canSmoothWith[target] & target_turf.smoothing_groups[target])) - continue - return ADJ_FOUND + if(canSmoothWith[target] & target_turf.smoothing_groups[target]) + match = target_turf - if(smoothing_flags & SMOOTH_OBJ) + if(isnull(match) && smoothing_flags & SMOOTH_OBJ) for(var/am in target_turf) var/atom/movable/thing = am if(!thing.anchored || isnull(thing.smoothing_groups)) continue for(var/target in canSmoothWith) - if(!(canSmoothWith[target] & thing.smoothing_groups[target])) - continue - return ADJ_FOUND + if(canSmoothWith[target] & thing.smoothing_groups[target]) + match = thing - return NO_ADJ_FOUND + if(isnull(match)) + return NO_ADJ_FOUND + . = ADJ_FOUND + + if(smoothing_flags & SMOOTH_DIRECTIONAL) + if(match.dir != dir) + return NO_ADJ_FOUND /** * Basic smoothing proc. The atom checks for adjacent directions to smooth with and changes the icon_state based on that. @@ -279,6 +286,15 @@ DEFINE_BITFIELD(smoothing_junction, list( var/smooth_border = (smoothing_flags & SMOOTH_BORDER) var/smooth_obj = (smoothing_flags & SMOOTH_OBJ) + var/smooth_directional = (smoothing_flags & SMOOTH_DIRECTIONAL) + var/skip_corners = (smoothing_flags & SMOOTH_BITMASK_SKIP_CORNERS) + + #define EXTRA_CHECKS(atom) \ + if(smooth_directional) { \ + if(atom.dir != dir) { \ + break set_adj_in_dir; \ + }; \ + }; \ #define SET_ADJ_IN_DIR(direction, direction_flag) \ set_adj_in_dir: { \ @@ -289,6 +305,7 @@ DEFINE_BITFIELD(smoothing_junction, list( if(neighbor_smoothing_groups) { \ for(var/target in canSmoothWith) { \ if(canSmoothWith[target] & neighbor_smoothing_groups[target]) { \ + EXTRA_CHECKS(neighbor); \ new_junction |= direction_flag; \ break set_adj_in_dir; \ }; \ @@ -302,6 +319,7 @@ DEFINE_BITFIELD(smoothing_junction, list( }; \ for(var/target in canSmoothWith) { \ if(canSmoothWith[target] & thing_smoothing_groups[target]) { \ + EXTRA_CHECKS(thing); \ new_junction |= direction_flag; \ break set_adj_in_dir; \ }; \ @@ -317,7 +335,7 @@ DEFINE_BITFIELD(smoothing_junction, list( for(var/direction in GLOB.cardinals) //Cardinal case first. SET_ADJ_IN_DIR(direction, direction) - if(!(new_junction & (NORTH|SOUTH)) || !(new_junction & (EAST|WEST))) + if(skip_corners || !(new_junction & (NORTH|SOUTH)) || !(new_junction & (EAST|WEST))) set_smoothed_icon_state(new_junction) return @@ -338,7 +356,7 @@ DEFINE_BITFIELD(smoothing_junction, list( set_smoothed_icon_state(new_junction) #undef SET_ADJ_IN_DIR - + #undef EXTRA_CHECKS ///Changes the icon state based on the new junction bitmask. Returns the old junction value. /atom/proc/set_smoothed_icon_state(new_junction) diff --git a/code/__HELPERS/mouse_control.dm b/code/__HELPERS/mouse_control.dm index aee348da6cfa1..f29b53d5ce053 100644 --- a/code/__HELPERS/mouse_control.dm +++ b/code/__HELPERS/mouse_control.dm @@ -50,3 +50,54 @@ p_x = text2num(screen_loc_X[2]) p_y = text2num(screen_loc_Y[2]) return new /datum/position(x, y, z, p_x, p_y) + +GLOBAL_LIST_INIT(mouse_cooldowns, list( + 'icons/effects/cooldown_cursors/cooldown_1.dmi', + 'icons/effects/cooldown_cursors/cooldown_2.dmi', + 'icons/effects/cooldown_cursors/cooldown_3.dmi', + 'icons/effects/cooldown_cursors/cooldown_4.dmi', + 'icons/effects/cooldown_cursors/cooldown_5.dmi', + 'icons/effects/cooldown_cursors/cooldown_6.dmi', + 'icons/effects/cooldown_cursors/cooldown_7.dmi', + 'icons/effects/cooldown_cursors/cooldown_8.dmi', + 'icons/effects/cooldown_cursors/cooldown_9.dmi', +)) + +/client/var/cooldown_cursor_time + +/client/proc/give_cooldown_cursor(time, override = FALSE) + set waitfor = FALSE + // Ignore the cooldown cursor if we have a longer one already applied + if (world.time + time < cooldown_cursor_time && !override) + return + cooldown_cursor_time = world.time + time + var/end_time = cooldown_cursor_time + var/previous_cursor = mouse_pointer_icon + var/start_time = world.time + var/current_cursor = 1 + for (var/cursor_icon in GLOB.mouse_cooldowns) + // Set the cursor and wait + mouse_pointer_icon = cursor_icon + // Sleep until we are where we should be + var/next_cursor_time = start_time + current_cursor * time / length(GLOB.mouse_cooldowns) + sleep(next_cursor_time - world.time) + // Someone else is managing the cursor + // Someone else is managing a cooldown timer, allow them since they overrode us + if (mouse_pointer_icon != cursor_icon || cooldown_cursor_time != end_time) + return + current_cursor ++ + // Somehow we finished a bit early + if (world.time < end_time) + sleep(end_time - world.time) + if (mouse_pointer_icon != GLOB.mouse_cooldowns[length(GLOB.mouse_cooldowns)] || cooldown_cursor_time != end_time) + return + if (previous_cursor in GLOB.mouse_cooldowns) + mouse_pointer_icon = initial(mouse_pointer_icon) + else + mouse_pointer_icon = previous_cursor + +/client/proc/clear_cooldown_cursor(time) + if (!(mouse_pointer_icon in GLOB.mouse_cooldowns)) + return + mouse_pointer_icon = initial(mouse_pointer_icon) + cooldown_cursor_time = 0 diff --git a/code/__HELPERS/radio.dm b/code/__HELPERS/radio.dm index 7ab21d0402810..a143406717cb3 100644 --- a/code/__HELPERS/radio.dm +++ b/code/__HELPERS/radio.dm @@ -2,9 +2,9 @@ /proc/sanitize_frequency(frequency, free = FALSE) . = round(frequency) if(free) - . = CLAMP(frequency, MIN_FREE_FREQ, MAX_FREE_FREQ) + . = clamp(frequency, MIN_FREE_FREQ, MAX_FREE_FREQ) else - . = CLAMP(frequency, MIN_FREQ, MAX_FREQ) + . = clamp(frequency, MIN_FREQ, MAX_FREQ) if(!(. % 2)) // Ensure the last digit is an odd number . += 1 diff --git a/code/__HELPERS/turfs.dm b/code/__HELPERS/turfs.dm index a1875bde3727d..ed8f943975f07 100644 --- a/code/__HELPERS/turfs.dm +++ b/code/__HELPERS/turfs.dm @@ -247,8 +247,8 @@ Turf and target are separate in case you want to teleport some distance from a t tX = text2num(tX[2]) tZ = origin.z var/list/actual_view = getviewsize(C ? C.view : world.view) - tX = CLAMP(origin.x + round(actual_view[1] / 2) - tX, 1, world.maxx) - tY = CLAMP(origin.y + round(actual_view[2] / 2) - tY, 1, world.maxy) + tX = clamp(origin.x + round(actual_view[1] / 2) - tX, 1, world.maxx) + tY = clamp(origin.y + round(actual_view[2] / 2) - tY, 1, world.maxy) return locate(tX, tY, tZ) ///similar function to RANGE_TURFS(), but will search spiralling outwards from the center (like the above, but only turfs) diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index c626316f73a81..3451174523e01 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -40,6 +40,7 @@ DEFINE_BITFIELD(area_flags, list( "UNIQUE_AREA" = UNIQUE_AREA, "BLOCK_SUICIDE" = BLOCK_SUICIDE, "XENOBIOLOGY_COMPATIBLE" = XENOBIOLOGY_COMPATIBLE, + "HIDDEN_STASH_LOCATION" = HIDDEN_STASH_LOCATION, )) DEFINE_BITFIELD(sight, list( diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm index 07a19fa068bbe..c84f67738ff21 100644 --- a/code/_globalvars/logging.dm +++ b/code/_globalvars/logging.dm @@ -48,6 +48,8 @@ GLOBAL_VAR(href_exploit_attempt_log) GLOBAL_PROTECT(href_exploit_attempt_log) GLOBAL_VAR(tgui_log) GLOBAL_PROTECT(tgui_log) +GLOBAL_VAR(prefs_log) +GLOBAL_PROTECT(prefs_log) GLOBAL_LIST_EMPTY(bombers) GLOBAL_PROTECT(bombers) diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index fe6acb9992e0b..77bf631288877 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -14,7 +14,7 @@ if(check_click_intercept(params,A)) return - if(stat || lockcharge || IsParalyzed() || IsStun() || IsUnconscious()) + if(stat || lockcharge || IsParalyzed() || IsStun()) return var/list/modifiers = params2list(params) diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm index d73e39784363c..d8313a8e922c1 100644 --- a/code/_onclick/hud/action_button.dm +++ b/code/_onclick/hud/action_button.dm @@ -43,7 +43,7 @@ /atom/movable/screen/movable/action_button/Click(location,control,params) if (!can_use(usr)) - return + return FALSE var/list/modifiers = params2list(params) if(LAZYACCESS(modifiers, SHIFT_CLICK)) @@ -75,10 +75,26 @@ desc = "Shift-click any button to reset its position, and Control-click it to lock it in place. Alt-click this button to reset all buttons to their default positions." icon = 'icons/mob/actions.dmi' icon_state = "bg_default" - var/hidden = 0 + var/hidden = FALSE var/hide_icon = 'icons/mob/actions.dmi' var/hide_state = "hide" var/show_state = "show" + var/mutable_appearance/hide_appearance + var/mutable_appearance/show_appearance + +/atom/movable/screen/movable/action_button/hide_toggle/Initialize(mapload) + . = ..() + var/static/list/icon_cache = list() + + var/cache_key = "[hide_icon][hide_state]" + hide_appearance = icon_cache[cache_key] + if(!hide_appearance) + hide_appearance = icon_cache[cache_key] = mutable_appearance(hide_icon, hide_state) + + cache_key = "[hide_icon][show_state]" + show_appearance = icon_cache[cache_key] + if(!show_appearance) + show_appearance = icon_cache[cache_key] = mutable_appearance(hide_icon, show_state) /atom/movable/screen/movable/action_button/hide_toggle/Click(location,control,params) if (!can_use(usr)) @@ -121,7 +137,7 @@ name = "Show Buttons" else name = "Hide Buttons" - update_icon() + update_appearance() usr.update_action_buttons() /atom/movable/screen/movable/action_button/hide_toggle/AltClick(mob/user) @@ -142,12 +158,11 @@ hide_icon = settings["toggle_icon"] hide_state = settings["toggle_hide"] show_state = settings["toggle_show"] - update_icon() - -/atom/movable/screen/movable/action_button/hide_toggle/update_icon() - cut_overlays() - add_overlay(mutable_appearance(hide_icon, hidden ? show_state : hide_state)) + update_appearance() +/atom/movable/screen/movable/action_button/hide_toggle/update_overlays() + . = ..() + . += hidden ? show_appearance : hide_appearance /atom/movable/screen/movable/action_button/MouseEntered(location,control,params) if(!QDELETED(src)) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index b550262dce4fe..1d3272f786fa6 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -157,9 +157,9 @@ /obj/item/proc/get_clamped_volume() if(w_class) if(force) - return CLAMP((force + w_class) * 4, 30, 100)// Add the item's force to its weight class and multiply by 4, then clamp the value between 30 and 100 + return clamp((force + w_class) * 4, 30, 100)// Add the item's force to its weight class and multiply by 4, then clamp the value between 30 and 100 else - return CLAMP(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100 + return clamp(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100 /mob/living/proc/send_item_attack_message(obj/item/I, mob/living/user, hit_area) var/message_verb = "attacked" diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm index 21b0530a24d2d..0bf692a36b742 100644 --- a/code/_onclick/telekinesis.dm +++ b/code/_onclick/telekinesis.dm @@ -196,9 +196,8 @@ focus.layer = old_layer focus.plane = old_plane -/obj/item/tk_grab/suicide_act(mob/user) +/obj/item/tk_grab/suicide_act(mob/living/user) user.visible_message("[user] is using [user.p_their()] telekinesis to choke [user.p_them()]self! It looks like [user.p_theyre()] trying to commit suicide!") - return (OXYLOSS) - + return OXYLOSS #undef TK_MAXRANGE diff --git a/code/controllers/configuration/config_entry.dm b/code/controllers/configuration/config_entry.dm index b8a4782be977c..49970f5daf6c2 100644 --- a/code/controllers/configuration/config_entry.dm +++ b/code/controllers/configuration/config_entry.dm @@ -98,7 +98,7 @@ return FALSE var/temp = text2num(trim(str_val)) if(!isnull(temp)) - config_entry_value = CLAMP(integer ? round(temp) : temp, min_val, max_val) + config_entry_value = clamp(integer ? round(temp) : temp, min_val, max_val) if(config_entry_value != temp && !(datum_flags & DF_VAR_EDITED)) log_config("Changing [name] from [temp] to [config_entry_value]!") return TRUE diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index 5539b7e1244a7..55e778dc9d2f5 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -83,6 +83,8 @@ /datum/config_entry/flag/log_world_topic // log all world.Topic() calls +/datum/config_entry/flag/log_preferences // log all preferences loading and changes + /// log speech indicators(started/stopped speaking) /datum/config_entry/flag/log_speech_indicators diff --git a/code/controllers/failsafe.dm b/code/controllers/failsafe.dm index 7e7c62667bec8..1611e038abbdc 100644 --- a/code/controllers/failsafe.dm +++ b/code/controllers/failsafe.dm @@ -66,19 +66,32 @@ GLOBAL_REAL(Failsafe, /datum/controller/failsafe) // Only poke it if overrides are not in effect. if(processing_interval > 0) if(Master.processing && Master.iteration) + if (defcon > 1 && (!Master.stack_end_detector || !Master.stack_end_detector.check())) + + to_chat(GLOB.admins, "ERROR: The Master Controller code stack has exited unexpectedly, Restarting...") + defcon = 0 + var/rtn = Recreate_MC() + if(rtn > 0) + master_iteration = 0 + to_chat(GLOB.admins, "MC restarted successfully") + else if(rtn < 0) + log_game("FailSafe: Could not restart MC, runtime encountered. Entering defcon 0") + to_chat(GLOB.admins, "ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.") // Check if processing is done yet. if(Master.iteration == master_iteration) switch(defcon) if(4,5) --defcon + if(3) message_admins("Notice: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks.") --defcon + if(2) to_chat(GLOB.admins, "Warning: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.") --defcon - if(1) + if(1) to_chat(GLOB.admins, "Warning: DEFCON [defcon_pretty()]. The Master Controller has still not fired within the last [(5-defcon) * processing_interval] ticks. Killing and restarting...") --defcon var/rtn = Recreate_MC() @@ -91,6 +104,7 @@ GLOBAL_REAL(Failsafe, /datum/controller/failsafe) to_chat(GLOB.admins, "ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.") //if the return number was 0, it just means the mc was restarted too recently, and it just needs some time before we try again //no need to handle that specially when defcon 0 can handle it + if(0) //DEFCON 0! (mc failed to restart) var/rtn = Recreate_MC() if(rtn > 0) diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 230d880be63d9..b68431d3f3b59 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -22,15 +22,17 @@ GLOBAL_REAL(Master, /datum/controller/master) = new /datum/controller/master name = "Master" - // Are we processing (higher values increase the processing delay by n ticks) + /// Are we processing (higher values increase the processing delay by n ticks) var/processing = TRUE - // How many times have we ran + /// How many times have we ran var/iteration = 0 + /// Stack end detector to detect stack overflows that kill the mc's main loop + var/datum/stack_end_detector/stack_end_detector - // world.time of last fire, for tracking lag outside of the mc + /// world.time of last fire, for tracking lag outside of the mc var/last_run - // List of subsystems to process(). + /// List of subsystems to process(). var/list/subsystems // Vars for keeping track of tick drift. @@ -38,25 +40,26 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/init_time var/tickdrift = 0 + /// How long is the MC sleeping between runs, read only (set by Loop() based off of anti-tick-contention heuristics) var/sleep_delta = 1 - //only run ticker subsystems for next n ticks. + /// Only run ticker subsystems for the next n ticks. var/skip_ticks = 0 var/make_runtime = 0 var/initializations_finished_with_no_players_logged_in //I wonder what this could be? - // The type of the last subsystem to be process()'d. + /// The type of the last subsystem to be fire()'d. var/last_type_processed - var/datum/controller/subsystem/queue_head //Start of queue linked list - var/datum/controller/subsystem/queue_tail //End of queue linked list (used for appending to the list) + var/datum/controller/subsystem/queue_head //!Start of queue linked list + var/datum/controller/subsystem/queue_tail //!End of queue linked list (used for appending to the list) var/queue_priority_count = 0 //Running total so that we don't have to loop thru the queue each run to split up the tick var/queue_priority_count_bg = 0 //Same, but for background subsystems - var/map_loading = FALSE //Are we loading in a new map? + var/map_loading = FALSE //!Are we loading in a new map? - var/current_runlevel //for scheduling different subsystems for different stages of the round + var/current_runlevel //!for scheduling different subsystems for different stages of the round var/sleep_offline_after_initializations = TRUE /// During initialization, will be the instanced subsytem that is currently initializing. @@ -69,8 +72,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/static/random_seed - //current tick limit, assigned before running a subsystem. - //used by CHECK_TICK as well so that the procs subsystems call can obey that SS's tick limits + ///current tick limit, assigned before running a subsystem. + ///used by CHECK_TICK as well so that the procs subsystems call can obey that SS's tick limits var/static/current_ticklimit = TICK_LIMIT_RUNNING /datum/controller/master/New() @@ -234,7 +237,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new // Sort subsystems by display setting for easy access. sortTim(subsystems, GLOBAL_PROC_REF(cmp_subsystem_display)) // Set world options. - world.fps = CONFIG_GET(number/fps) + world.change_fps(CONFIG_GET(number/fps)) var/initialized_tod = REALTIMEOFDAY if(sleep_offline_after_initializations) @@ -329,8 +332,12 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/error_level = 0 var/sleep_delta = 1 var/list/subsystems_to_check - //the actual loop. + //setup the stack overflow detector + stack_end_detector = new() + var/datum/stack_canary/canary = stack_end_detector.prime_canary() + canary.use_variable() + //the actual loop. var/anti_tick_contention_sleep_time = 0 while (1) diff --git a/code/controllers/subsystem/preferences.dm b/code/controllers/subsystem/preferences.dm index 8a4d5f3266063..30d4b48025086 100644 --- a/code/controllers/subsystem/preferences.dm +++ b/code/controllers/subsystem/preferences.dm @@ -19,12 +19,13 @@ SUBSYSTEM_DEF(preferences) return datums[ckey] = WEAKREF(prefs) prefs.ui_update() // for queue preview + log_preferences("[ckey]: Queued preference write.") /datum/controller/subsystem/preferences/fire(resumed) for(var/ckey in datums) var/datum/weakref/ref = datums[ckey] var/datum/preferences/prefs = ref.resolve() - if(!prefs) + if(QDELETED(prefs)) datums -= ckey continue if(prefs.save_locked) // don't save right now, but stay queued diff --git a/code/controllers/subsystem/processing/processing.dm b/code/controllers/subsystem/processing/processing.dm index 61b321abfc4ae..72e612ac25b62 100644 --- a/code/controllers/subsystem/processing/processing.dm +++ b/code/controllers/subsystem/processing/processing.dm @@ -25,7 +25,7 @@ SUBSYSTEM_DEF(processing) if (!resumed) currentrun = processing.Copy() - var/continuous_delta_time = last_time_fired == 0 ? wait : (CLAMP(world.timeofday - last_time_fired, 0.5 * wait, 2 * wait)) + var/continuous_delta_time = last_time_fired == 0 ? wait : (clamp(world.timeofday - last_time_fired, 0.5 * wait, 2 * wait)) last_time_fired = world.timeofday //cache for sanic speed (lists are references anyways) diff --git a/code/controllers/subsystem/profiler.dm b/code/controllers/subsystem/profiler.dm index 4c00a98df86a4..da8a7fd9c9c56 100644 --- a/code/controllers/subsystem/profiler.dm +++ b/code/controllers/subsystem/profiler.dm @@ -17,7 +17,7 @@ SUBSYSTEM_DEF(profiler) /datum/controller/subsystem/profiler/stat_entry(msg) msg += "F:[round(fetch_cost,1)]ms" msg += "|W:[round(write_cost,1)]ms" - ..(msg) + return ..(msg) /datum/controller/subsystem/profiler/Initialize() if(CONFIG_GET(flag/auto_profile)) diff --git a/code/controllers/subsystem/sound.dm b/code/controllers/subsystem/sound.dm index 4bcb281f6494b..58c8ad2025e8b 100644 --- a/code/controllers/subsystem/sound.dm +++ b/code/controllers/subsystem/sound.dm @@ -114,7 +114,7 @@ SUBSYSTEM_DEF(sound_effects) SSsound_effects.acting_effects[effect_id] = src /datum/sound_effect/fade/update_effect() - var/time_multiplier = CLAMP((world.time - start_tick) / (end_tick - start_tick), 0, 1) + var/time_multiplier = clamp((world.time - start_tick) / (end_tick - start_tick), 0, 1) current_vol = (time_multiplier * out_vol) + ((1-time_multiplier) * in_vol) sound.status = SOUND_UPDATE sound.volume = current_vol diff --git a/code/controllers/subsystem/zcopy.dm b/code/controllers/subsystem/zcopy.dm index 4f126a55f9a7c..e4abe9034ac30 100644 --- a/code/controllers/subsystem/zcopy.dm +++ b/code/controllers/subsystem/zcopy.dm @@ -122,7 +122,7 @@ SUBSYSTEM_DEF(zcopy) "\tT: { T: [openspace_turfs] O: [openspace_overlays] } Sk: { T: [multiqueue_skips_turf] O: [multiqueue_skips_object] }", "\tF: { H: [fixup_hit] M: [fixup_miss] N: [fixup_noop] FC: [fixup_cache.len] FKG: [fixup_known_good.len] }", // Fixup stats. ) - return ..() + entries.Join("\n") + return ..(entries.Join("\n")) // 1, 2, 3..=7, 8 /datum/controller/subsystem/zcopy/proc/build_zstack_display() diff --git a/code/datums/action.dm b/code/datums/action.dm index 344a8bd46de91..1f17ccfd06930 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -33,6 +33,7 @@ /datum/action/proc/link_to(Target) target = Target + RegisterSignal(Target, COMSIG_ATOM_UPDATED_ICON, PROC_REF(OnUpdatedIcon)) /datum/action/Destroy() if(owner) @@ -154,6 +155,10 @@ current_button.add_overlay(mutable_appearance(icon_icon, button_icon_state)) current_button.button_icon_state = button_icon_state +/datum/action/proc/OnUpdatedIcon() + SIGNAL_HANDLER + UpdateButtonIcon() + //Presets for item actions /datum/action/item_action check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_LYING|AB_CHECK_CONSCIOUS diff --git a/code/datums/ai/hunting_behavior/hunting_behaviors.dm b/code/datums/ai/hunting_behavior/hunting_behaviors.dm index 1cd4e8dab2d0a..f838ba0586167 100644 --- a/code/datums/ai/hunting_behavior/hunting_behaviors.dm +++ b/code/datums/ai/hunting_behavior/hunting_behaviors.dm @@ -111,6 +111,7 @@ if(isliving(hunted)) // Are we hunting a living mob? var/mob/living/living_target = hunted hunter.manual_emote("[hunt_emote] [living_target]!") + living_target.investigate_log("has been killed by [key_name(hunter)].", INVESTIGATE_DEATHS) living_target.death() else if(IS_EDIBLE(hunted)) diff --git a/code/datums/brain_damage/obsessed_trauma.dm b/code/datums/brain_damage/obsessed_trauma.dm index 7505d52126360..80a810af35832 100644 --- a/code/datums/brain_damage/obsessed_trauma.dm +++ b/code/datums/brain_damage/obsessed_trauma.dm @@ -1,7 +1,9 @@ +#define OBSESSION_REVEAL_TIME 7.5 MINUTES //! After this amount of time is spent near the target, the obsession trauma will reveal its true nature to health analyzers. + /datum/brain_trauma/special/obsessed name = "Psychotic Schizophrenia" desc = "Patient has a subtype of delusional disorder, becoming irrationally attached to someone." - scan_desc = "psychotic schizophrenic delusions" + scan_desc = "monophobia" gain_text = "If you see this message, make a github issue report. The trauma initialized wrong." lose_text = "The voices in your head fall silent." can_gain = TRUE @@ -11,6 +13,8 @@ var/datum/objective/spendtime/attachedobsessedobj var/datum/antagonist/obsessed/antagonist var/viewing = FALSE //it's a lot better to store if the owner is watching the obsession than checking it twice between two procs + var/revealed = FALSE + var/static/true_scan_desc = "psychotic schizophrenic delusions" var/total_time_creeping = 0 //just for roundend fun var/time_spent_away = 0 @@ -50,6 +54,8 @@ if(viewing) SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "creeping", /datum/mood_event/creeping, obsession.name) total_time_creeping += 2 SECONDS + if(!revealed && (total_time_creeping >= OBSESSION_REVEAL_TIME)) + reveal() time_spent_away = 0 if(attachedobsessedobj)//if an objective needs to tick down, we can do that since traumas coexist with the antagonist datum attachedobsessedobj.timer -= 2 SECONDS //mob subsystem ticks every 2 seconds(?), remove 20 deciseconds from the timer. sure, that makes sense. @@ -73,6 +79,11 @@ if(hugged == obsession.current) obsession_hug_count++ +/datum/brain_trauma/special/obsessed/proc/reveal() + revealed = TRUE + scan_desc = true_scan_desc + to_chat(owner, "The deep, overwhelming concern for [obsession.name] within you continues to blossom, making you suddenly feel as if your obsessive behavior is somewhat more obvious...") + /datum/brain_trauma/special/obsessed/proc/on_obsession_cryoed() SIGNAL_HANDLER @@ -107,3 +118,5 @@ if(length(possible_targets)) chosen_victim = pick_weight(possible_targets) return chosen_victim + +#undef OBSESSION_REVEAL_TIME diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm index 59c80b87ed849..8a9a468055691 100644 --- a/code/datums/chatmessage.dm +++ b/code/datums/chatmessage.dm @@ -469,7 +469,7 @@ if(show_in_chat) to_chat(viewer, "[text].") -/atom/proc/balloon_alert_to_viewers(message, self_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs) +/atom/proc/balloon_alert_to_viewers(message, self_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs, show_in_chat = TRUE) var/list/hearers = get_hearers_in_view(vision_distance, src) hearers -= ignored_mobs @@ -477,7 +477,7 @@ if (hearer.is_blind()) continue - balloon_alert(hearer, (hearer == src && self_message) || message) + balloon_alert(hearer, (hearer == src && self_message) || message, show_in_chat = show_in_chat) /datum/chatmessage/balloon_alert tgt_color = "#ffffff" //default color diff --git a/code/datums/components/aiming.dm b/code/datums/components/aiming.dm index 4fbc1b08f03c0..a7f53dc4da89a 100644 --- a/code/datums/components/aiming.dm +++ b/code/datums/components/aiming.dm @@ -1,5 +1,10 @@ // Aiming component, ported from NSV +// Defines for aiming "levels" +#define GUN_NOT_AIMED 0 +#define GUN_AIMED 1 +#define GUN_AIMED_POINTBLANK 2 + // Defines for stages and radial choices #define START "start" #define RAISE_HANDS "raise_hands" @@ -9,6 +14,8 @@ #define SHOOT "shoot" #define SURRENDER "surrender" #define IGNORE "ignore" +#define POINTBLANK "pointblank" +#define LET_GO "let_go" /datum/component/aiming can_transfer = FALSE @@ -17,6 +24,7 @@ var/obj/item/target_held = null var/datum/radial_menu/persistent/choice_menu // Radial menu for the user var/datum/radial_menu/persistent/choice_menu_target // Radial menu for the target + var/holding_at_gunpoint = FALSE // used for boosting shot damage COOLDOWN_DECLARE(aiming_cooldown) // 5 second cooldown so you can't spam aiming for faster bullets COOLDOWN_DECLARE(voiceline_cooldown) // 2 seconds, prevents spamming commands COOLDOWN_DECLARE(notification_cooldown) // 5 seconds, prevents spamming the equip notification/sound @@ -131,6 +139,21 @@ Methods to alert the aimer about events (Surrendering/equipping an item/dropping user.balloon_alert(user, "You can't see [target] anymore!") stop_aiming() +/datum/component/aiming/proc/on_resist() + SIGNAL_HANDLER + target.balloon_alert(user, "Tries to break free!") + +/datum/component/aiming/proc/stop_holding() + SIGNAL_HANDLER + var/obj/item/held = user.get_active_held_item() + user.visible_message("[user] stops holding \the [held] at [target]'s temple!", \ + "You stop holding \the [held] at [target]'s temple", ignored_mobs = list(target)) + to_chat(target, "[user] stops holding \the [held] at your temple!") + user.balloon_alert_to_viewers("Lets go of [target]", "Let go of [target]", ignored_mobs = list(target), show_in_chat = FALSE) + user.balloon_alert(target, "[user] Lets go of you", show_in_chat = FALSE) + remove_pointblank() + show_ui(user, target, START) + /** Method to show a radial menu to the person who's aiming, in stages: @@ -148,16 +171,26 @@ AIMING_DROP_WEAPON means they selected the "drop your weapon" command if(START) possible_actions += RAISE_HANDS possible_actions += DROP_WEAPON + possible_actions += POINTBLANK if(RAISE_HANDS) possible_actions += DROP_TO_FLOOR possible_actions += RAISE_HANDS + possible_actions += POINTBLANK if(DROP_WEAPON) possible_actions += DROP_TO_FLOOR possible_actions += DROP_WEAPON possible_actions += RAISE_HANDS + possible_actions += POINTBLANK if(DROP_TO_FLOOR) possible_actions += DROP_TO_FLOOR possible_actions += DROP_WEAPON + possible_actions += POINTBLANK + if(LET_GO) + possible_actions += RAISE_HANDS + possible_actions += DROP_WEAPON + possible_actions += POINTBLANK + if(holding_at_gunpoint) + possible_actions += LET_GO for(var/option in possible_actions) options[option] = image(icon = 'icons/effects/aiming.dmi', icon_state = option) if(choice_menu) @@ -187,7 +220,10 @@ AIMING_DROP_WEAPON means they selected the "drop your weapon" command stop_aiming() return if(SHOOT) - shoot() + if(holding_at_gunpoint) + shoot(4) + else + shoot() return if(RAISE_HANDS) user.say(pick("Put your hands above your head!", "Hands! Now!", "Hands up!"), forced = "Weapon aiming") @@ -195,10 +231,64 @@ AIMING_DROP_WEAPON means they selected the "drop your weapon" command user.say(pick("Drop your weapon!", "Weapon down! Now!", "Drop it!"), forced = "Weapon aiming") if(DROP_TO_FLOOR) user.say(pick("On the ground! Now!", "Lie down and place your hands behind your head!", "Get down on the ground!"), forced = "Weapon aiming") + if(POINTBLANK) + if(get_dist(target, user) > 1) + to_chat(user, "You need to be closer to [target] to hold [target.p_them()] at gunpoint!") + return + if(isdead(target)) + to_chat(user, "You can't hold dead things at gunpoint!") + return + var/obj/item/held = user.get_active_held_item() + if(!held) + to_chat(user, "You can't hold someone at gunpoint with an empty hand!") + return + if(!user.pulling || user.pulling != target) + to_chat(user, "You start to grab \the [target].") + to_chat(target, "[user] starts to grab you!") + if(!do_after(user, 2 SECONDS, target)) + to_chat(user, "You start to strengthen your grip on [target].") + to_chat(target, "[user] starts to strengthen their grip on you!") + if(!do_after(user, 2 SECONDS, target)) + to_chat(user, "[user] lines up \the [held] with [target]'s temple!", \ + "You line up \the [held] with [target]'s temple", ignored_mobs = list(target)) + to_chat(target, "[user] lines up \the [held] with your temple!") + user.balloon_alert_to_viewers("Holds [target] at gunpoint!", "Holding [target] at gunpoint!", ignored_mobs = list(target), show_in_chat = FALSE) + user.balloon_alert(target, "Holds you at gunpoint!", show_in_chat = FALSE) + setup_pointblank() + if(LET_GO) + stop_holding() aim_react(target) COOLDOWN_START(src, voiceline_cooldown, 2 SECONDS) show_ui(user, target, choice) +/datum/component/aiming/proc/setup_pointblank() + holding_at_gunpoint = TRUE + RegisterSignal(src.target, COMSIG_LIVING_RESIST, PROC_REF(on_resist)) + RegisterSignal(src.target, COMSIG_MOVABLE_NO_LONGER_PULLED, PROC_REF(stop_holding)) + +/datum/component/aiming/proc/remove_pointblank() + if(!holding_at_gunpoint) + return + holding_at_gunpoint = FALSE + UnregisterSignal(src.target, COMSIG_LIVING_RESIST) + UnregisterSignal(src.target, COMSIG_MOVABLE_NO_LONGER_PULLED) + /datum/component/aiming/proc/shoot() var/obj/item/held = user.get_active_held_item() if(held != parent) @@ -206,7 +296,10 @@ AIMING_DROP_WEAPON means they selected the "drop your weapon" command return FALSE if(istype(parent, /obj/item/gun)) // If we have a gun, shoot it at the target var/obj/item/gun/G = parent - G.afterattack(target, user, null, null, TRUE) + if(holding_at_gunpoint) + G.afterattack(target, user, null, null, GUN_AIMED_POINTBLANK) + else + G.afterattack(target, user, null, null, GUN_AIMED) stop_aiming() return TRUE if(isitem(parent)) // Otherwise, just wave it at them @@ -227,6 +320,7 @@ AIMING_DROP_WEAPON means they selected the "drop your weapon" command // Clean up the menu if it's still open QDEL_NULL(choice_menu) QDEL_NULL(choice_menu_target) + remove_pointblank() target = null /datum/component/aiming/proc/aim_react(mob/target) @@ -269,3 +363,5 @@ AIMING_DROP_WEAPON means they selected the "drop your weapon" command #undef SHOOT #undef SURRENDER #undef IGNORE +#undef POINTBLANK +#undef LET_GO diff --git a/code/datums/components/armor_plate.dm b/code/datums/components/armor_plate.dm index f721f84324bfe..97255a13ea039 100644 --- a/code/datums/components/armor_plate.dm +++ b/code/datums/components/armor_plate.dm @@ -12,6 +12,8 @@ RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(examine)) RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, PROC_REF(applyplate)) RegisterSignal(parent, COMSIG_PARENT_PREQDELETED, PROC_REF(dropplates)) + if(istype(parent, /obj/mecha/working/ripley)) + RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(apply_mech_overlays)) if(_maxamount) maxamount = _maxamount @@ -82,3 +84,14 @@ if(ismecha(parent)) //items didn't drop the plates before and it causes erroneous behavior for the time being with collapsible helmets for(var/i in 1 to amount) new upgrade_item(get_turf(parent)) + +/datum/component/armor_plate/proc/apply_mech_overlays(obj/mecha/mech, list/overlays) + SIGNAL_HANDLER + + if(amount) + var/overlay_string = "ripley-g" + if(amount >= 3) + overlay_string += "-full" + if(!LAZYLEN(mech.occupant)) + overlay_string += "-open" + overlays += overlay_string diff --git a/code/datums/components/butchering.dm b/code/datums/components/butchering.dm index 60c9a33695970..b8f66d204cac0 100644 --- a/code/datums/components/butchering.dm +++ b/code/datums/components/butchering.dm @@ -56,7 +56,7 @@ var/item_force = source.force if(!item_force) //Division by 0 protection item_force = 1 - if(do_after(user, CLAMP(500 / item_force, 30, 100), H) && H.Adjacent(source)) + if(do_after(user, clamp(500 / item_force, 30, 100), H) && H.Adjacent(source)) if(H.has_status_effect(/datum/status_effect/neck_slice)) user.show_message("[H]'s neck has already been already cut, you can't make the bleeding any worse!", 1, \ "Their neck has already been already cut, you can't make the bleeding any worse!") @@ -65,7 +65,7 @@ H.visible_message("[user] slits [H]'s throat!", \ "[user] slits your throat...") H.apply_damage(item_force, BRUTE, BODY_ZONE_HEAD) - H.bleed_rate = CLAMP(H.bleed_rate + 20, 0, 30) + H.bleed_rate = clamp(H.bleed_rate + 20, 0, 30) H.apply_status_effect(/datum/status_effect/neck_slice) /datum/component/butchering/proc/Butcher(mob/living/butcher, mob/living/meat) @@ -98,6 +98,8 @@ "You butcher [meat].") ButcherEffects(meat) meat.harvest(butcher) + meat.log_message("has been butchered by [key_name(butcher)]", LOG_ATTACK) + meat.investigate_log("was gibbed via butchering", INVESTIGATE_DEATHS) meat.gib(FALSE, FALSE, TRUE) /datum/component/butchering/proc/ButcherEffects(mob/living/meat) //extra effects called on butchering, override this via subtypes diff --git a/code/datums/components/chasm.dm b/code/datums/components/chasm.dm index bf0ab993a21e8..2838e70c19450 100644 --- a/code/datums/components/chasm.dm +++ b/code/datums/components/chasm.dm @@ -116,8 +116,7 @@ if (isliving(AM)) var/mob/living/L = AM L.notransform = TRUE - L.Stun(200) - L.resting = TRUE + L.Paralyze(20 SECONDS) var/oldtransform = AM.transform var/oldcolor = AM.color diff --git a/code/datums/components/embedded.dm b/code/datums/components/embedded.dm index 4e0b168d6f8ce..5334171425b8f 100644 --- a/code/datums/components/embedded.dm +++ b/code/datums/components/embedded.dm @@ -133,7 +133,7 @@ var/damage = weapon.w_class * pain_mult var/max_damage = weapon.w_class * max_damage_mult + weapon.throwforce var/pain_chance_current = DT_PROB_RATE(pain_chance / 100, delta_time) * 100 - if(pain_stam_pct && victim.stam_paralyzed) //if it's a less-lethal embed, give them a break if they're already stamcritted + if(pain_stam_pct && HAS_TRAIT_FROM(victim, TRAIT_INCAPACITATED, STAMINA)) //if it's a less-lethal embed, give them a break if they're already stamcritted pain_chance_current *= 0.2 damage *= 0.5 else if(victim.mobility_flags & ~MOBILITY_STAND) @@ -142,7 +142,7 @@ if(harmful && prob(pain_chance_current)) var/damage_left = max_damage - limb.get_damage() var/damage_wanted = (1-pain_stam_pct) * damage - var/damage_to_deal = CLAMP(damage_wanted, 0, damage_left) + var/damage_to_deal = clamp(damage_wanted, 0, damage_left) var/damage_as_stam = damage_wanted - damage_to_deal if(!damage_to_deal) to_chat(victim, "[weapon] embedded in your [limb.name] stings a little!") diff --git a/code/datums/components/empprotection.dm b/code/datums/components/empprotection.dm deleted file mode 100644 index bb94b08e55a9b..0000000000000 --- a/code/datums/components/empprotection.dm +++ /dev/null @@ -1,13 +0,0 @@ -/datum/component/empprotection - var/flags = NONE - -/datum/component/empprotection/Initialize(_flags) - if(!istype(parent, /atom)) - return COMPONENT_INCOMPATIBLE - flags = _flags - RegisterSignal(parent, list(COMSIG_ATOM_EMP_ACT), PROC_REF(getEmpFlags)) - -/datum/component/empprotection/proc/getEmpFlags(datum/source, severity) - SIGNAL_HANDLER - - return flags diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm index ef2ae7346db6d..161e6c05d6a17 100644 --- a/code/datums/components/food/edible.dm +++ b/code/datums/components/food/edible.dm @@ -200,14 +200,14 @@ Behavior that's still missing from this component that original food items had t for(var/obj/item/crafted_part in this_food.contents) crafted_part.reagents?.trans_to(this_food.reagents, crafted_part.reagents.maximum_volume, CRAFTED_FOOD_INGREDIENT_REAGENT_MODIFIER) - var/list/objects_to_delete = list() + var/list/objects_to_delete = this_food.contents.Copy() // Remove all non recipe objects from the contents for(var/content_object in this_food.contents) - for(var/recipe_object in recipe.real_parts) + for(var/recipe_object in recipe.parts) if(istype(content_object, recipe_object)) - continue - objects_to_delete += content_object + objects_to_delete -= content_object + break QDEL_LIST(objects_to_delete) diff --git a/code/datums/components/nanites.dm b/code/datums/components/nanites.dm index cd0c49d93bfd2..4b0ce2501eee2 100644 --- a/code/datums/components/nanites.dm +++ b/code/datums/components/nanites.dm @@ -8,11 +8,11 @@ var/safety_threshold = 50 //how low nanites will get before they stop processing/triggering var/cloud_id = 0 //0 if not connected to the cloud, 1-100 to set a determined cloud backup to draw from var/cloud_active = TRUE //if false, won't sync to the cloud - var/next_sync = 0 var/list/datum/nanite_program/programs = list() var/max_programs = NANITE_PROGRAM_LIMIT + COOLDOWN_DECLARE(next_sync) - var/list/datum/nanite_program/protocol/protocols = list() ///Separate list of protocol programs, to avoid looping through the whole programs list when cheking for conflicts + var/list/datum/nanite_program/protocol/protocols = list() /// Separate list of protocol programs, to avoid looping through the whole programs list when cheking for conflicts var/start_time = 0 ///Timestamp to when the nanites were first inserted in the host var/stealth = FALSE //if TRUE, does not appear on HUDs and health scans var/diagnostics = TRUE //if TRUE, displays program list when scanned by nanite scanners @@ -103,42 +103,40 @@ /datum/component/nanites/InheritComponent(datum/component/nanites/new_nanites, i_am_original, amount, cloud) if(new_nanites) - adjust_nanites(null, new_nanites.nanite_volume) + adjust_nanites(amount = new_nanites.nanite_volume) else - adjust_nanites(null, amount) //just add to the nanite volume + adjust_nanites(amount = amount) //just add to the nanite volume /datum/component/nanites/process(delta_time) if(!IS_IN_STASIS(host_mob)) - adjust_nanites(null, regen_rate * delta_time) + adjust_nanites(amount = (regen_rate + (SSresearch.science_tech.researched_nodes["nanite_harmonic"] ? HARMONIC_REGEN_BOOST : 0)) * delta_time) add_research() - for(var/X in programs) - var/datum/nanite_program/NP = X - NP.on_process() - if(cloud_id && cloud_active && world.time > next_sync) + for(var/datum/nanite_program/program as anything in programs) + program.on_process() + if(cloud_id && cloud_active && COOLDOWN_FINISHED(src, next_sync)) cloud_sync() - next_sync = world.time + NANITE_SYNC_DELAY + COOLDOWN_START(src, next_sync, NANITE_SYNC_DELAY) set_nanite_bar() +/// Deletes nanites! /datum/component/nanites/proc/delete_nanites() SIGNAL_HANDLER qdel(src) -//Syncs the nanite component to another, making it so programs are the same with the same programming (except activation status) +/// Syncs the nanite component to another, making it so programs are the same with the same programming (except activation status) /datum/component/nanites/proc/sync(datum/signal_source, datum/component/nanites/source, full_overwrite = TRUE, copy_settings = TRUE, copy_activation = FALSE) SIGNAL_HANDLER var/list/programs_to_remove = programs.Copy() var/list/programs_to_add = source.programs.Copy() - for(var/X in programs) - var/datum/nanite_program/NP = X - for(var/Y in programs_to_add) - var/datum/nanite_program/SNP = Y - if(NP.type == SNP.type) - programs_to_remove -= NP - programs_to_add -= SNP - SNP.copy_programming(NP, copy_activation) + for(var/datum/nanite_program/current_program as anything in programs) + for(var/datum/nanite_program/new_program as anything in programs_to_add) + if(current_program.type == new_program.type) + programs_to_remove -= current_program + programs_to_add -= new_program + new_program.copy_programming(current_program, copy_activation) break if(full_overwrite) for(var/X in programs_to_remove) @@ -148,9 +146,10 @@ cloud_id = source.cloud_id safety_threshold = source.safety_threshold for(var/X in programs_to_add) - var/datum/nanite_program/SNP = X - add_program(null, SNP.copy()) + for(var/datum/nanite_program/program as anything in programs_to_add) + add_program(new_program = program.copy()) +/// Syncs the nanites to their assigned cloud copy, if it is available. If it is not, there is a small chance of a software error instead. /datum/component/nanites/proc/cloud_sync() if(cloud_id) var/datum/nanite_cloud_backup/backup = SSnanites.get_cloud_backup(cloud_id) @@ -164,13 +163,13 @@ var/datum/nanite_program/NP = pick(programs) NP.software_error() +/// Adds a nanite program, replacing existing unique programs of the same type. A source program can be specified to copy its programming onto the new one. /datum/component/nanites/proc/add_program(datum/source, datum/nanite_program/new_program, datum/nanite_program/source_program) SIGNAL_HANDLER - for(var/X in programs) - var/datum/nanite_program/NP = X - if(NP.unique && NP.type == new_program.type) - qdel(NP) + for(var/datum/nanite_program/program as anything in programs) + if(program.unique && program.type == new_program.type) + qdel(program) if(programs.len >= max_programs) return COMPONENT_PROGRAM_NOT_INSTALLED if(source_program) @@ -182,16 +181,70 @@ /datum/component/nanites/proc/consume_nanites(amount, force = FALSE) if(!force && safety_threshold && (nanite_volume - amount < safety_threshold)) return FALSE - adjust_nanites(null, -amount) + adjust_nanites(amount = -amount) return (nanite_volume > 0) +/// Modifies the current nanite volume, then checks if the nanites are depleted or exceeding the maximum amount /datum/component/nanites/proc/adjust_nanites(datum/source, amount) SIGNAL_HANDLER - nanite_volume = clamp(nanite_volume + amount, 0, max_nanites) + nanite_volume += amount + if(nanite_volume > max_nanites) + reject_excess_nanites() if(nanite_volume <= 0) //oops we ran out qdel(src) +/** + * Handles how nanites leave the host's body if they find out that they're currently exceeding the maximum supported amount + * + * IC explanation: + * Normally nanites simply discard excess volume by slowing replication or 'sweating' it out in imperceptible amounts, + * but if there is a large excess volume, likely due to a programming change that leaves them unable to support their current volume, + * the nanites attempt to leave the host as fast as necessary to prevent nanite poisoning. This can range from minor oozing to nanites + * rapidly bursting out from every possible pathway, causing temporary inconvenience to the host. + */ +/datum/component/nanites/proc/reject_excess_nanites() + var/excess = nanite_volume - max_nanites + nanite_volume = max_nanites + + switch(excess) + if(0 to NANITE_EXCESS_MINOR) //Minor excess amount, the extra nanites are quietly expelled without visible effects + return + if((NANITE_EXCESS_MINOR + 0.1) to NANITE_EXCESS_VOMIT) //Enough nanites getting rejected at once to be visible to the naked eye + host_mob.visible_message("A grainy grey slurry starts oozing out of [host_mob].", "A grainy grey slurry starts oozing out of your skin.", vision_distance = 4); + if((NANITE_EXCESS_VOMIT + 0.1) to NANITE_EXCESS_BURST) //Nanites getting rejected in massive amounts, but still enough to make a semi-orderly exit through vomit + if(iscarbon(host_mob)) + var/mob/living/carbon/C = host_mob + host_mob.visible_message("[host_mob] vomits a grainy grey slurry!", "You suddenly vomit a metallic-tasting grainy grey slurry!"); + C.vomit(0, FALSE, TRUE, FLOOR(excess / 100, 1), FALSE, VOMIT_NANITE, FALSE) + else + host_mob.visible_message("A metallic grey slurry bursts out of [host_mob]'s skin!", "A metallic grey slurry violently bursts out of your skin!"); + if(isturf(host_mob.drop_location())) + var/turf/T = host_mob.drop_location() + T.add_vomit_floor(host_mob, VOMIT_NANITE, FALSE) + if((NANITE_EXCESS_BURST + 0.1) to INFINITY) //Way too many nanites, they just leave through the closest exit before they harm/poison the host + host_mob.visible_message("A torrent of metallic grey slurry violently bursts out of [host_mob]'s face and floods out of [host_mob.p_their()] skin!", + "A torrent of metallic grey slurry violently bursts out of your eyes, ears, and mouth, and floods out of your skin!"); + + host_mob.adjust_blindness(15) //nanites coming out of your eyes + host_mob.Paralyze(12 SECONDS) + if(iscarbon(host_mob)) + var/mob/living/carbon/C = host_mob + var/obj/item/organ/ears/ears = C.getorganslot(ORGAN_SLOT_EARS) + if(ears) + ears.adjustEarDamage(0, 30) //nanites coming out of your ears + C.vomit(0, FALSE, TRUE, 2, FALSE, VOMIT_NANITE, FALSE) //nanites coming out of your mouth + + //nanites everywhere + if(isturf(host_mob.drop_location())) + var/turf/T = host_mob.drop_location() + T.add_vomit_floor(host_mob, VOMIT_NANITE, FALSE) + for(var/turf/adjacent_turf in oview(host_mob, 1)) + if(adjacent_turf.density || !adjacent_turf.Adjacent(T)) + continue + adjacent_turf.add_vomit_floor(host_mob, VOMIT_NANITE, FALSE) + +/// Updates the nanite volume bar visible in diagnostic HUDs /datum/component/nanites/proc/set_nanite_bar(remove = FALSE) var/image/holder = host_mob.hud_list[DIAG_NANITE_FULL_HUD] var/icon/I = icon(host_mob.icon, host_mob.icon_state, host_mob.dir) @@ -207,7 +260,7 @@ SIGNAL_HANDLER nanite_volume *= (rand(60, 90) * 0.01) //Lose 10-40% of nanites - adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume + adjust_nanites(amount = -(rand(5, 50))) //Lose 5-50 flat nanite volume if(prob(40/severity)) cloud_id = 0 for(var/X in programs) @@ -223,18 +276,16 @@ if(!HAS_TRAIT_NOT_FROM(host_mob, TRAIT_SHOCKIMMUNE, "nanites"))//Another shock protection must protect nanites too, but nanites protect only host nanite_volume *= (rand(45, 80) * 0.01) //Lose 20-55% of nanites - adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume - for(var/X in programs) - var/datum/nanite_program/NP = X - NP.on_shock(shock_damage) + adjust_nanites(amount = -(rand(5, 50))) //Lose 5-50 flat nanite volume + for(var/datum/nanite_program/program as anything in programs) + program.on_shock(shock_damage) /datum/component/nanites/proc/on_minor_shock(datum/source) SIGNAL_HANDLER - adjust_nanites(null, -(rand(5, 15))) //Lose 5-15 flat nanite volume - for(var/X in programs) - var/datum/nanite_program/NP = X - NP.on_minor_shock() + adjust_nanites(amount = -(rand(5, 15))) //Lose 5-15 flat nanite volume + for(var/datum/nanite_program/program as anything in programs) + program.on_minor_shock() /datum/component/nanites/proc/check_stealth(datum/source) SIGNAL_HANDLER @@ -244,24 +295,20 @@ /datum/component/nanites/proc/on_death(datum/source, gibbed) SIGNAL_HANDLER - for(var/X in programs) - var/datum/nanite_program/NP = X - NP.on_death(gibbed) + for(var/datum/nanite_program/program as anything in programs) + program.on_death(gibbed) /datum/component/nanites/proc/receive_signal(datum/source, code, source = "an unidentified source") SIGNAL_HANDLER - for(var/X in programs) - var/datum/nanite_program/NP = X - NP.receive_signal(code, source) + for(var/datum/nanite_program/program as anything in programs) + program.receive_nanite_signal(code, source) /datum/component/nanites/proc/receive_comm_signal(datum/source, comm_code, comm_message, comm_source = "an unidentified source") SIGNAL_HANDLER - for(var/X in programs) - if(istype(X, /datum/nanite_program/comm)) - var/datum/nanite_program/comm/NP = X - NP.receive_comm_signal(comm_code, comm_message, comm_source) + for(var/datum/nanite_program/comm/program in programs) + program.receive_comm_signal(comm_code, comm_message, comm_source) /datum/component/nanites/proc/check_viable_biotype() SIGNAL_HANDLER @@ -287,7 +334,7 @@ /datum/component/nanites/proc/set_max_volume(datum/source, amount) SIGNAL_HANDLER - max_nanites = max(1, max_nanites) + max_nanites = max(1, amount) /datum/component/nanites/proc/set_cloud(datum/source, amount) SIGNAL_HANDLER @@ -368,10 +415,9 @@ if(!diagnostics) message += "Diagnostics Disabled" else - for(var/X in programs) - var/datum/nanite_program/program = X + for(var/datum/nanite_program/program as anything in programs) message += "[program.name] | [program.activated ? "Active" : "Inactive"]" - for(var/datum/nanite_rule/rule in program.rules) + for(var/datum/nanite_rule/rule as anything in program.rules) message += "[GLOB.TAB][rule.display()]" . = TRUE if(length(message)) @@ -382,32 +428,31 @@ data["has_nanites"] = TRUE data["nanite_volume"] = nanite_volume - data["regen_rate"] = regen_rate + data["regen_rate"] = regen_rate + (SSresearch.science_tech.researched_nodes["nanite_harmonic"] ? HARMONIC_REGEN_BOOST : 0) data["safety_threshold"] = safety_threshold data["cloud_id"] = cloud_id data["cloud_active"] = cloud_active var/list/mob_programs = list() var/id = 1 - for(var/X in programs) - var/datum/nanite_program/P = X + for(var/datum/nanite_program/program as anything in programs) var/list/mob_program = list() - mob_program["name"] = P.name - mob_program["desc"] = P.desc + mob_program["name"] = program.name + mob_program["desc"] = program.desc mob_program["id"] = id if(scan_level >= 2) - mob_program["activated"] = P.activated - mob_program["use_rate"] = P.use_rate - mob_program["can_trigger"] = P.can_trigger - mob_program["trigger_cost"] = P.trigger_cost - mob_program["trigger_cooldown"] = P.trigger_cooldown / 10 + mob_program["activated"] = program.activated + mob_program["use_rate"] = program.use_rate + mob_program["can_trigger"] = program.can_trigger + mob_program["trigger_cost"] = program.trigger_cost + mob_program["trigger_cooldown"] = program.trigger_cooldown / 10 if(scan_level >= 3) - mob_program["timer_restart"] = P.timer_restart / 10 - mob_program["timer_shutdown"] = P.timer_shutdown / 10 - mob_program["timer_trigger"] = P.timer_trigger / 10 - mob_program["timer_trigger_delay"] = P.timer_trigger_delay / 10 - var/list/extra_settings = P.get_extra_settings_frontend() + mob_program["timer_restart"] = program.timer_restart / 10 + mob_program["timer_shutdown"] = program.timer_shutdown / 10 + mob_program["timer_trigger"] = program.timer_trigger / 10 + mob_program["timer_trigger_delay"] = program.timer_trigger_delay / 10 + var/list/extra_settings = program.get_extra_settings_frontend() mob_program["extra_settings"] = extra_settings if(LAZYLEN(extra_settings)) mob_program["has_extra_settings"] = TRUE @@ -415,14 +460,13 @@ mob_program["has_extra_settings"] = FALSE if(scan_level >= 4) - mob_program["activation_code"] = P.activation_code - mob_program["deactivation_code"] = P.deactivation_code - mob_program["kill_code"] = P.kill_code - mob_program["trigger_code"] = P.trigger_code + mob_program["activation_code"] = program.activation_code + mob_program["deactivation_code"] = program.deactivation_code + mob_program["kill_code"] = program.kill_code + mob_program["trigger_code"] = program.trigger_code var/list/rules = list() var/rule_id = 1 - for(var/Z in P.rules) - var/datum/nanite_rule/nanite_rule = Z + for(var/datum/nanite_rule/nanite_rule as anything in program.rules) var/list/rule = list() rule["display"] = nanite_rule.display() rule["program_id"] = id diff --git a/code/datums/components/storage/concrete/bag_of_holding.dm b/code/datums/components/storage/concrete/bag_of_holding.dm index def1aef30e398..28f3cde185955 100644 --- a/code/datums/components/storage/concrete/bag_of_holding.dm +++ b/code/datums/components/storage/concrete/bag_of_holding.dm @@ -29,6 +29,7 @@ message_admins("[ADMIN_LOOKUPFLW(user)] detonated a bag of holding at [ADMIN_VERBOSEJMP(loccheck)].") log_game("[key_name(user)] detonated a bag of holding at [loc_name(loccheck)].") + user.investigate_log("has been gibbed by a bag of holding recursive insertion.", INVESTIGATE_DEATHS) user.gib(TRUE, TRUE, TRUE) new/obj/boh_tear(loccheck) qdel(A) diff --git a/code/datums/components/storage/concrete/pockets.dm b/code/datums/components/storage/concrete/pockets.dm index 1f7c822b17473..fd9ad899d4394 100644 --- a/code/datums/components/storage/concrete/pockets.dm +++ b/code/datums/components/storage/concrete/pockets.dm @@ -17,6 +17,7 @@ /datum/component/storage/concrete/pockets/small max_items = 1 + max_w_class = WEIGHT_CLASS_SMALL attack_hand_interact = FALSE /datum/component/storage/concrete/pockets/tiny diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index 4d9865bd8b3d1..27f419f677271 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -335,8 +335,8 @@ numbered_contents = _process_numerical_display() adjusted_contents = numbered_contents.len - var/columns = CLAMP(max_items, 1, screen_max_columns) - var/rows = CLAMP(CEILING(adjusted_contents / columns, 1), 1, screen_max_rows) + var/columns = clamp(max_items, 1, screen_max_columns) + var/rows = clamp(CEILING(adjusted_contents / columns, 1), 1, screen_max_rows) standard_orient_objs(rows, columns, numbered_contents) //This proc draws out the inventory and places the items on it. It uses the standard position. diff --git a/code/datums/components/wet_floor.dm b/code/datums/components/wet_floor.dm index 5bf3b39a87b52..66831e30a094d 100644 --- a/code/datums/components/wet_floor.dm +++ b/code/datums/components/wet_floor.dm @@ -180,7 +180,7 @@ /datum/component/wet_floor/proc/_do_add_wet(type, duration_minimum, duration_add, duration_maximum) var/time = 0 if(LAZYACCESS(time_left_list, "[type]")) - time = CLAMP(LAZYACCESS(time_left_list, "[type]") + duration_add, duration_minimum, duration_maximum) + time = clamp(LAZYACCESS(time_left_list, "[type]") + duration_add, duration_minimum, duration_maximum) else time = min(duration_minimum, duration_maximum) LAZYSET(time_left_list, "[type]", time) diff --git a/code/datums/dash_weapon.dm b/code/datums/dash_weapon.dm index 410b5e0a42983..de768730c96f3 100644 --- a/code/datums/dash_weapon.dm +++ b/code/datums/dash_weapon.dm @@ -47,7 +47,7 @@ to_chat(user, "You cannot dash here!") /datum/action/innate/dash/proc/charge() - current_charges = CLAMP(current_charges + 1, 0, max_charges) + current_charges = clamp(current_charges + 1, 0, max_charges) owner.update_action_buttons_icon() if(recharge_sound) playsound(dashing_item, recharge_sound, 50, 1) diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index c5857fadb9359..efb0b9fe6727c 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -282,7 +282,7 @@ SetSpread() permeability_mod = max(CEILING(0.4 * transmission, 1), 1) - cure_chance = 15 - CLAMP(resistance, -5, 5) // can be between 10 and 20 + cure_chance = 15 - clamp(resistance, -5, 5) // can be between 10 and 20 stage_prob = max(stage_rate, 2) SetDanger(severity) GenerateCure() @@ -357,7 +357,7 @@ // Will generate a random cure, the less resistance the symptoms have, the harder the cure. /datum/disease/advance/proc/GenerateCure() - var/res = CLAMP(resistance - (symptoms.len / 2), 1, advance_cures.len) + var/res = clamp(resistance - (symptoms.len / 2), 1, advance_cures.len) if(archivecure != res) cures = list(pick(advance_cures[res])) // Get the cure name from the cure_id @@ -548,12 +548,12 @@ var/datum/disease/advance/A = make_copy ? Copy() : src if(!initial && A.mutable && (spread_flags & DISEASE_SPREAD_CONTACT_FLUIDS)) var/minimum = 1 - if(prob(CLAMP(35-(A.resistance + A.stealth - A.speed), 0, 50) * (A.mutability)))//stealthy/resistant diseases are less likely to mutate. this means diseases used to farm mutations should be easier to cure. hypothetically. + if(prob(clamp(35-(A.resistance + A.stealth - A.speed), 0, 50) * (A.mutability)))//stealthy/resistant diseases are less likely to mutate. this means diseases used to farm mutations should be easier to cure. hypothetically. if(infectee.job == "clown" || infectee.job == "mime" || prob(1))//infecting a clown or mime can evolve l0 symptoms/. they can also appear very rarely minimum = 0 else - minimum = CLAMP(A.severity - 1, 1, 7) - A.Evolve(minimum, CLAMP(A.severity + 4, minimum, 9)) + minimum = clamp(A.severity - 1, 1, 7) + A.Evolve(minimum, clamp(A.severity + 4, minimum, 9)) A.id = GetDiseaseID() A.keepid = TRUE//this is really janky, but basically mutated diseases count as the original disease //if you want to evolve a higher level symptom you need to test and spread a deadly virus among test subjects. diff --git a/code/datums/diseases/advance/symptoms/alcohol.dm b/code/datums/diseases/advance/symptoms/alcohol.dm index 2e0e5ebff4f92..31d476d0a7f5f 100644 --- a/code/datums/diseases/advance/symptoms/alcohol.dm +++ b/code/datums/diseases/advance/symptoms/alcohol.dm @@ -41,6 +41,6 @@ warningstrings = list("ahyguabngaghabyugbauwf", "You feel sick", "It feels like you drank too much", "You feel like doing something unwise") else warningstrings = list("You feel buzzed", "You feel a bit tipsy") - M.drunkenness = CLAMP(M.drunkenness + target * ((A.stage - 1) * 0.1), M.drunkenness, target) + M.drunkenness = clamp(M.drunkenness + target * ((A.stage - 1) * 0.1), M.drunkenness, target) if(prob(5 * A.stage)) to_chat(M, "[pick(warningstrings)]") diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm index d7bf4065ad374..5be972687faf0 100644 --- a/code/datums/diseases/advance/symptoms/heal.dm +++ b/code/datums/diseases/advance/symptoms/heal.dm @@ -121,13 +121,13 @@ ADD_TRAIT(M, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT) if(HAS_TRAIT(M, TRAIT_DEATHCOMA)) return power - else if(M.IsUnconscious() || M.stat == UNCONSCIOUS) + if(M.IsSleeping()) + return power * 0.25 //Voluntary unconsciousness yields lower healing. + if(M.stat == UNCONSCIOUS) return power * 0.9 - else if(M.stat == SOFT_CRIT) + if(M.stat == SOFT_CRIT) return power * 0.5 - else if(M.IsSleeping()) - return power * 0.25 - else if(M.getBruteLoss() + M.getFireLoss() >= 70 && !active_coma) + if(M.getBruteLoss() + M.getFireLoss() >= 70 && !active_coma) to_chat(M, "You feel yourself slip into a deep, regenerative slumber.") active_coma = TRUE addtimer(CALLBACK(src, PROC_REF(coma), M), 60) @@ -137,7 +137,6 @@ M.fakedeath(TRAIT_REGEN_COMA) else M.Unconscious(300, TRUE, TRUE) - M.update_stat() M.update_mobility() addtimer(CALLBACK(src, PROC_REF(uncoma), M), 300) @@ -149,7 +148,6 @@ M.cure_fakedeath(TRAIT_REGEN_COMA) else M.SetUnconscious(0) - M.update_stat() M.update_mobility() /datum/symptom/heal/coma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) @@ -502,7 +500,7 @@ im not even gonna bother with these for the following symptoms. typed em out, co var/mob/living/carbon/M = A.affected_mob ownermind = M.mind if(!A.carrier && !A.dormant) - sizemult = CLAMP((0.5 + A.stage_rate / 10), 1.1, 1.5) + sizemult = clamp((0.5 + A.stage_rate / 10), 1.1, 1.5) M.resize = sizemult M.update_transform() @@ -759,7 +757,7 @@ im not even gonna bother with these for the following symptoms. typed em out, co var/excess = max(((min(amt, C.blood_volume) - (BLOOD_VOLUME_NORMAL - H.blood_volume)) / 4), 0) H.blood_volume = min(H.blood_volume + min(amt, C.blood_volume), BLOOD_VOLUME_NORMAL) C.blood_volume = max(C.blood_volume - amt, 0) - gainedpoints = CLAMP(excess, 0, maxbloodpoints - bloodpoints) + gainedpoints = clamp(excess, 0, maxbloodpoints - bloodpoints) C.visible_message("Blood flows from [C.name]'s wounds into [H.name]!", "Blood flows from your wounds into [H.name]!") playsound(C.loc, 'sound/magic/exit_blood.ogg', 25, 1) return gainedpoints @@ -793,7 +791,7 @@ im not even gonna bother with these for the following symptoms. typed em out, co if(gainedpoints) playsound(M.loc, 'sound/magic/exit_blood.ogg', 50, 1) M.visible_message("Blood flows from the floor into [M.name]!", "You consume the errant blood") - return CLAMP(gainedpoints, 0, maxbloodpoints - bloodpoints) + return clamp(gainedpoints, 0, maxbloodpoints - bloodpoints) if(ishuman(M) && aggression)//finally, attack mobs touching the host. var/mob/living/carbon/human/H = M for(var/mob/living/carbon/human/C in ohearers(1, H)) @@ -805,9 +803,9 @@ im not even gonna bother with these for the following symptoms. typed em out, co var/excess = max(((min(amt, C.blood_volume) - (BLOOD_VOLUME_NORMAL - H.blood_volume)) / 4 * power), 0) H.blood_volume = min(H.blood_volume + min(amt, C.blood_volume), BLOOD_VOLUME_NORMAL) C.blood_volume = max(C.blood_volume - amt, 0) - gainedpoints += CLAMP(excess, 0, maxbloodpoints - bloodpoints) + gainedpoints += clamp(excess, 0, maxbloodpoints - bloodpoints) C.visible_message("Blood flows from [C.name]'s wounds into [H.name]!", "Blood flows from your wounds into [H.name]!") - return CLAMP(gainedpoints, 0, maxbloodpoints - bloodpoints) + return clamp(gainedpoints, 0, maxbloodpoints - bloodpoints) /datum/symptom/parasite diff --git a/code/datums/diseases/advance/symptoms/shedding.dm b/code/datums/diseases/advance/symptoms/shedding.dm index 7c241301a017f..1adfc9eb453e6 100644 --- a/code/datums/diseases/advance/symptoms/shedding.dm +++ b/code/datums/diseases/advance/symptoms/shedding.dm @@ -33,6 +33,9 @@ BONUS return var/mob/living/M = A.affected_mob + + if(HAS_TRAIT(M, TRAIT_NOHAIRLOSS)) + return if(prob(base_message_chance)) to_chat(M, "[pick("Your scalp itches.", "Your skin feels flaky.")]") if(ishuman(M)) diff --git a/code/datums/diseases/gbs.dm b/code/datums/diseases/gbs.dm index 2be16dd8c49cf..742c6e2316bb0 100644 --- a/code/datums/diseases/gbs.dm +++ b/code/datums/diseases/gbs.dm @@ -26,6 +26,7 @@ if(4) to_chat(affected_mob, "Your body feels as if it's trying to rip itself apart!") if(prob(50)) + affected_mob.investigate_log("has been gibbed by GBS.", INVESTIGATE_DEATHS) affected_mob.gib() else return diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 9a8da6bb3e2f4..fba41e9067f1b 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -665,11 +665,14 @@ else switch(rand(0,5)) if(0) + investigate_log("has been gibbed by DNA instability.", INVESTIGATE_DEATHS) gib() if(1) + investigate_log("has been dusted by DNA instability.", INVESTIGATE_DEATHS) dust() if(2) + investigate_log("has been killed by DNA instability.", INVESTIGATE_DEATHS) death() petrify(INFINITY) if(3) @@ -678,6 +681,7 @@ if(BP) BP.dismember() else + investigate_log("has been gibbed by DNA instability.", INVESTIGATE_DEATHS) gib() else set_species(/datum/species/dullahan) diff --git a/code/datums/elements/empprotection.dm b/code/datums/elements/empprotection.dm new file mode 100644 index 0000000000000..8d5d798c3cb89 --- /dev/null +++ b/code/datums/elements/empprotection.dm @@ -0,0 +1,20 @@ +/datum/element/empprotection + element_flags = ELEMENT_DETACH | ELEMENT_BESPOKE + id_arg_index = 2 + var/flags = NONE + +/datum/element/empprotection/Attach(datum/target, _flags) + . = ..() + if(. == ELEMENT_INCOMPATIBLE || !isatom(target)) + return ELEMENT_INCOMPATIBLE + flags = _flags + RegisterSignal(target, COMSIG_ATOM_EMP_ACT, PROC_REF(getEmpFlags)) + +/datum/element/empprotection/Detach(atom/target) + UnregisterSignal(target, COMSIG_ATOM_EMP_ACT) + return ..() + +/datum/element/empprotection/proc/getEmpFlags(datum/source, severity) + SIGNAL_HANDLER + + return flags diff --git a/code/datums/elements/mirage_border.dm b/code/datums/elements/mirage_border.dm index c3b3eecc3e347..c23f2c6110ba0 100644 --- a/code/datums/elements/mirage_border.dm +++ b/code/datums/elements/mirage_border.dm @@ -20,9 +20,9 @@ if(istext(range)) range = max(getviewsize(range)[1], getviewsize(range)[2]) - var/z = CLAMP(target_turf.z, 1, world.maxz) - var/turf/southwest = locate(CLAMP(x - (direction & WEST ? range : 0), 1, world.maxx), CLAMP(y - (direction & SOUTH ? range : 0), 1, world.maxy), z) - var/turf/northeast = locate(CLAMP(x + (direction & EAST ? range : 0), 1, world.maxx), CLAMP(y + (direction & NORTH ? range : 0), 1, world.maxy), z) + var/z = clamp(target_turf.z, 1, world.maxz) + var/turf/southwest = locate(clamp(x - (direction & WEST ? range : 0), 1, world.maxx), clamp(y - (direction & SOUTH ? range : 0), 1, world.maxy), z) + var/turf/northeast = locate(clamp(x + (direction & EAST ? range : 0), 1, world.maxx), clamp(y + (direction & NORTH ? range : 0), 1, world.maxy), z) holder.vis_contents += block(southwest, northeast) if(direction & SOUTH) holder.pixel_y -= world.icon_size * range diff --git a/code/datums/elements/update_icon_blocker.dm b/code/datums/elements/update_icon_blocker.dm new file mode 100644 index 0000000000000..674b314ec9c15 --- /dev/null +++ b/code/datums/elements/update_icon_blocker.dm @@ -0,0 +1,12 @@ +//Prevents calling anything in update_icon() like update_icon_state() or update_overlays() + +/datum/element/update_icon_blocker/Attach(datum/target) + . = ..() + if(!istype(target, /atom)) + return ELEMENT_INCOMPATIBLE + RegisterSignal(target, COMSIG_ATOM_UPDATE_ICON, PROC_REF(block_update_icon)) + +/datum/element/update_icon_blocker/proc/block_update_icon() + SIGNAL_HANDLER + + return COMSIG_ATOM_NO_UPDATE_ICON_STATE | COMSIG_ATOM_NO_UPDATE_OVERLAYS diff --git a/code/datums/elements/update_icon_updates_onmob.dm b/code/datums/elements/update_icon_updates_onmob.dm new file mode 100644 index 0000000000000..0ec9a472e64f6 --- /dev/null +++ b/code/datums/elements/update_icon_updates_onmob.dm @@ -0,0 +1,18 @@ +//update_icon() may change the onmob icons +//Very good name, I know + +/datum/element/update_icon_updates_onmob/Attach(datum/target) + . = ..() + if(!istype(target, /obj/item)) + return ELEMENT_INCOMPATIBLE + RegisterSignal(target, COMSIG_ATOM_UPDATED_ICON, PROC_REF(update_onmob)) + +/datum/element/update_icon_updates_onmob/proc/update_onmob(obj/item/target) + SIGNAL_HANDLER + + if(ismob(target.loc)) + var/mob/M = target.loc + if(M.is_holding(target)) + M.update_inv_hands() + else + M.regenerate_icons() //yeah this is shit, but we don't know which update_foo() proc to call instead so we'll call them all diff --git a/code/datums/helper_datums/stack_end_detector.dm b/code/datums/helper_datums/stack_end_detector.dm new file mode 100644 index 0000000000000..fd700ac8f21ae --- /dev/null +++ b/code/datums/helper_datums/stack_end_detector.dm @@ -0,0 +1,31 @@ +/** + Stack End Detector. + Can detect if a given code stack has exited, used by the mc for stack overflow detection. + **/ +/datum/stack_end_detector + var/datum/weakref/_WF + var/datum/stack_canary/_canary + +/datum/stack_end_detector/New() + _canary = new() + _WF = WEAKREF(_canary) + +/** Prime the stack overflow detector. + Store the return value of this proc call in a proc level var. + Can only be called once. +**/ +/datum/stack_end_detector/proc/prime_canary() + if (!_canary) + CRASH("Prime_canary called twice") + . = _canary + _canary = null + +/// Returns true if the stack is still going. Calling before the canary has been primed also returns true +/datum/stack_end_detector/proc/check() + return !!_WF.resolve() + +/// Stack canary. Will go away if the stack it was primed by is ended by byond for return or stack overflow reasons. +/datum/stack_canary + +/// empty proc to avoid warnings about unused variables. Call this proc on your canary in the stack it's watching. +/datum/stack_canary/proc/use_variable() diff --git a/code/datums/martial/krav_maga.dm b/code/datums/martial/krav_maga.dm index 6236dd249ff1a..643845af95e97 100644 --- a/code/datums/martial/krav_maga.dm +++ b/code/datums/martial/krav_maga.dm @@ -105,7 +105,7 @@ "[A] slams your chest! You can't breathe!", null, COMBAT_MESSAGE_RANGE) playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1) if(D.losebreath <= 10) - D.losebreath = CLAMP(D.losebreath + 5, 0, 10) + D.losebreath = clamp(D.losebreath + 5, 0, 10) D.adjustOxyLoss(10) log_combat(A, D, "quickchoked") return 1 @@ -116,7 +116,7 @@ playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1) D.apply_damage(5, A.dna.species.attack_type) if(D.silent <= 10) - D.silent = CLAMP(D.silent + 10, 0, 10) + D.silent = clamp(D.silent + 10, 0, 10) log_combat(A, D, "neck chopped") return 1 diff --git a/code/datums/martial/tribal_claw.dm b/code/datums/martial/tribal_claw.dm index d59e853ed14c8..d7e6dc2b951bd 100644 --- a/code/datums/martial/tribal_claw.dm +++ b/code/datums/martial/tribal_claw.dm @@ -61,7 +61,7 @@ Deals 15 brute to head(reduced by armor) and causes a rapid bleeding effect simi D.visible_message("[A] cuts [D]'s jugular vein with their claws!", \ "[A] cuts your jugular vein!") D.apply_damage(15, BRUTE, BODY_ZONE_HEAD, def_check) - D.bleed_rate = CLAMP(D.bleed_rate + 20, 0, 30) + D.bleed_rate = clamp(D.bleed_rate + 20, 0, 30) D.apply_status_effect(/datum/status_effect/neck_slice) A.do_attack_animation(D, ATTACK_EFFECT_CLAW) playsound(get_turf(D), 'sound/weapons/slash.ogg', 50, 1, -1) @@ -77,7 +77,7 @@ Deals 15 brute to head(reduced by armor) and causes a rapid bleeding effect simi D.Knockdown(5) //Without knockdown target still stands up while T3 grabbed. A.setGrabState(GRAB_NECK) if(D.silent <= 10) - D.silent = CLAMP(D.silent + 10, 0, 10) + D.silent = clamp(D.silent + 10, 0, 10) /datum/martial_art/tribal_claw/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) add_to_streak("H",D) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 6f949de012d3c..a5f2331ff4383 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -353,6 +353,8 @@ var/datum/component/uplink/U = uplink_loc.AddComponent(/datum/component/uplink, traitor_mob.key, TRUE, FALSE, gamemode, telecrystals) if(src.has_antag_datum(/datum/antagonist/incursion)) U.uplink_flag = UPLINK_INCURSION + if(src.has_antag_datum(/datum/antagonist/traitor/excommunicate)) + U.uplink_flag = UPLINK_EXCOMMUNICATE if(!U) CRASH("Uplink creation failed.") U.setup_unlock_code() diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm index 0f90293d9a941..f0a253f66fde0 100644 --- a/code/datums/mutations.dm +++ b/code/datums/mutations.dm @@ -5,6 +5,8 @@ var/quality var/static/list/visual_indicators = list() var/obj/effect/proc_holder/spell/power + /// A list of traits to apply to the user whenever this mutation is active. + var/list/traits var/layer_used = MUTATIONS_LAYER //which mutation layer to use var/list/species_allowed = list() //to restrict mutation to only certain species var/list/mobtypes_allowed = list() //to restrict mutation to only certain mobs @@ -46,9 +48,11 @@ timed = TRUE if(copymut && istype(copymut, /datum/mutation)) copy_mutation(copymut) + if(traits && !islist(traits)) + traits = list(traits) /datum/mutation/proc/on_acquiring(mob/living/carbon/C) - if(!C || !istype(C) || C.stat == DEAD || !C.has_dna() || (src in C.dna.mutations)) + if(!istype(C) || C.stat == DEAD || !C.has_dna() || (src in C.dna.mutations)) return TRUE if(length(mobtypes_allowed) && !mobtypes_allowed.Find(C.type)) return TRUE @@ -78,6 +82,8 @@ if(!modified && can_chromosome == CHROMOSOME_USED) addtimer(CALLBACK(src, PROC_REF(modify), 5)) //gonna want children calling ..() to run first RegisterSignal(owner, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) + for(var/trait in traits) + ADD_TRAIT(C, trait, "[type]") /datum/mutation/proc/get_visual_indicator() return @@ -96,7 +102,7 @@ return /datum/mutation/proc/on_losing(mob/living/carbon/owner) - if(owner && istype(owner) && (owner.dna.mutations.Remove(src))) + if(istype(owner) && (owner.dna.mutations.Remove(src))) if(length(visual_indicators)) var/list/mut_overlay = list() if(owner.overlays_standing[layer_used]) @@ -109,8 +115,9 @@ owner.RemoveSpell(power) qdel(src) UnregisterSignal(owner, COMSIG_MOVABLE_MOVED) - return 0 - return 1 + REMOVE_TRAITS_IN(owner, "[type]") + return FALSE + return TRUE /mob/living/carbon/proc/update_mutations_overlay() if(!has_dna()) @@ -143,7 +150,7 @@ modified = TRUE /datum/mutation/proc/copy_mutation(datum/mutation/HM) - if(!HM) + if(!istype(HM)) return chromosome_name = HM.chromosome_name stabilizer_coeff = HM.stabilizer_coeff @@ -173,7 +180,10 @@ if(!ispath(power) || !owner) return FALSE - power = new power() + if(ispath(power, /obj/effect/proc_holder/spell/targeted/touch/mutation)) + power = new power(null, src) + else + power = new power() power.action_background_icon_state = "bg_tech_blue_on" power.panel = "Genetic" owner.AddSpell(power) diff --git a/code/datums/mutations/actions.dm b/code/datums/mutations/actions.dm index 43194c541e0e2..e74bca0a8e492 100644 --- a/code/datums/mutations/actions.dm +++ b/code/datums/mutations/actions.dm @@ -5,8 +5,6 @@ difficulty = 12 power = /obj/effect/proc_holder/spell/targeted/telepathy instability = 10 - energy_coeff = 1 - /datum/mutation/olfaction name = "Transcendent Olfaction" @@ -15,13 +13,12 @@ difficulty = 12 power = /obj/effect/proc_holder/spell/targeted/olfaction instability = 30 - synchronizer_coeff = 1 - var/reek = 200 + energy_coeff = 1 /obj/effect/proc_holder/spell/targeted/olfaction name = "Remember the Scent" desc = "Get a scent off of the item you're currently holding to track it. With an empty hand, you'll track the scent you've remembered." - charge_max = 100 + charge_max = 10 SECONDS clothes_req = FALSE range = -1 include_user = TRUE @@ -35,13 +32,13 @@ var/old_target = tracking_target possible = list() var/list/prints = sniffed.return_fingerprints() - for(var/mob/living/carbon/C in GLOB.carbon_list) - if(prints[rustg_hash_string(RUSTG_HASH_MD5, C.dna.uni_identity)]) - possible |= C + for(var/mob/living/carbon/potential_target in GLOB.carbon_list) + if(prints[rustg_hash_string(RUSTG_HASH_MD5, potential_target.dna.uni_identity)]) + possible |= potential_target if(!length(possible)) - to_chat(user,"Despite your best efforts, there are no scents to be found on [sniffed]...") + to_chat(user, "Despite your best efforts, there are no scents to be found on [sniffed]...") return - tracking_target = input(user, "Choose a scent to remember.", "Scent Tracking") as null|anything in sort_names(possible) + tracking_target = tgui_input_list(user, "Choose a scent to remember.", "Scent Tracking", sort_names(possible)) if(!tracking_target) if(!old_target) to_chat(user,"You decide against remembering any scents. Instead, you notice your own nose in your peripheral vision. This goes on to remind you of that one time you started breathing manually and couldn't stop. What an awful day that was.") @@ -49,7 +46,7 @@ tracking_target = old_target on_the_trail(user) return - to_chat(user,"You pick up the scent of [tracking_target]. The hunt begins.") + to_chat(user,"You pick up the scent of [tracking_target]. The hunt begins.") on_the_trail(user) return @@ -74,7 +71,7 @@ return var/direction_text = "[dir2text(get_dir(usr, tracking_target))]" if(direction_text) - to_chat(user,"You consider [tracking_target]'s scent. The trail leads [direction_text].") + to_chat(user,"You consider [tracking_target]'s scent. The trail leads [direction_text].") /datum/mutation/firebreath name = "Fire Breath" @@ -91,8 +88,8 @@ /datum/mutation/firebreath/modify() ..() if(power) - var/obj/effect/proc_holder/spell/aimed/firebreath/S = power - S.strength = GET_MUTATION_POWER(src) + var/obj/effect/proc_holder/spell/aimed/firebreath/firebreath = power + firebreath.strength = GET_MUTATION_POWER(src) /obj/effect/proc_holder/spell/aimed/firebreath name = "Fire Breath" @@ -100,7 +97,7 @@ school = "evocation" invocation = "" invocation_type = INVOCATION_NONE - charge_max = 600 + charge_max = 1 MINUTES clothes_req = FALSE range = 20 projectile_type = /obj/projectile/magic/fireball/firebreath @@ -113,27 +110,27 @@ /obj/effect/proc_holder/spell/aimed/firebreath/before_cast(list/targets) . = ..() - if(iscarbon(usr)) - var/mob/living/carbon/C = usr - if(C.is_mouth_covered()) - C.adjust_fire_stacks(2) - C.IgniteMob() - to_chat(C,"Something in front of your mouth caught fire!") - return FALSE + var/mob/living/carbon/user = usr + if(!istype(user)) + return + if(user.is_mouth_covered()) + user.adjust_fire_stacks(2) + user.IgniteMob() + to_chat(user, "Something in front of your mouth caught fire!") + return FALSE -/obj/effect/proc_holder/spell/aimed/firebreath/ready_projectile(obj/projectile/P, atom/target, mob/user, iteration) - if(!istype(P, /obj/projectile/magic/fireball)) +/obj/effect/proc_holder/spell/aimed/firebreath/ready_projectile(obj/projectile/magic/fireball/fireball, atom/target, mob/user, iteration) + if(!istype(fireball)) return - var/obj/projectile/magic/fireball/F = P - F.exp_light = strength-1 - F.exp_fire += strength + fireball.exp_light = strength - 1 + fireball.exp_fire += strength /obj/projectile/magic/fireball/firebreath name = "fire breath" exp_heavy = 0 exp_light = 0 exp_flash = 0 - exp_fire= 4 + exp_fire = 4 magic = FALSE /datum/mutation/void @@ -148,7 +145,7 @@ /datum/mutation/void/on_life() if(!isturf(owner.loc)) return - if(prob((0.5+((100-dna.stability)/20))) * GET_MUTATION_SYNCHRONIZER(src)) //very rare, but enough to annoy you hopefully. +0.5 probability for every 10 points lost in stability + if(prob((0.5 + ((100 - dna.stability) / 20))) * GET_MUTATION_SYNCHRONIZER(src)) //very rare, but enough to annoy you hopefully. +0.5 probability for every 10 points lost in stability new /obj/effect/immortality_talisman/void(get_turf(owner), owner) /obj/effect/proc_holder/spell/self/void @@ -156,15 +153,15 @@ desc = "A rare genome that attracts odd forces not usually observed. May sometimes pull you in randomly." school = "evocation" clothes_req = FALSE - charge_max = 600 + charge_max = 1 MINUTES invocation = "DOOOOOOOOOOOOOOOOOOOOM!!!" invocation_type = INVOCATION_SHOUT action_icon_state = "void_magnet" /obj/effect/proc_holder/spell/self/void/can_cast(mob/user = usr) - . = ..() if(!isturf(user.loc)) return FALSE + return ..() /obj/effect/proc_holder/spell/self/void/cast(mob/user = usr) . = ..() @@ -176,37 +173,28 @@ quality = POSITIVE instability = 30 power = /obj/effect/proc_holder/spell/self/self_amputation - energy_coeff = 1 - synchronizer_coeff = 1 /obj/effect/proc_holder/spell/self/self_amputation name = "Drop a limb" desc = "Concentrate to make a random limb pop right off your body." clothes_req = FALSE human_req = FALSE - charge_max = 100 + charge_max = 10 SECONDS action_icon_state = "autotomy" -/obj/effect/proc_holder/spell/self/self_amputation/cast(mob/user = usr) - if(!iscarbon(user)) +/obj/effect/proc_holder/spell/self/self_amputation/cast(mob/living/carbon/user = usr) + if(!istype(user) || HAS_TRAIT(user, TRAIT_NODISMEMBER)) return - - var/mob/living/carbon/C = user - if(HAS_TRAIT(C, TRAIT_NODISMEMBER)) - return - var/list/parts = list() - for(var/obj/item/bodypart/BP as() in C.bodyparts) - if(BP.body_part != HEAD && BP.body_part != CHEST) - if(BP.dismemberable) - parts += BP - if(!parts.len) - to_chat(usr, "You can't shed any more limbs!") + for(var/obj/item/bodypart/part as() in user.bodyparts) + if(part.body_part != HEAD && part.body_part != CHEST && part.dismemberable) + parts += part + if(!length(parts)) + to_chat(user, "You can't shed any more limbs!") return - - var/obj/item/bodypart/BP = pick(parts) - BP.dismember() + var/obj/item/bodypart/yeeted_limb = pick(parts) + yeeted_limb.dismember() /datum/mutation/overload name = "Overload" @@ -216,84 +204,30 @@ instability = 30 power = /obj/effect/proc_holder/spell/self/overload species_allowed = list(SPECIES_ETHEREAL) + energy_coeff = 1 + power_coeff = 1 + +/datum/mutation/overload/modify() + ..() + if(power) + var/static/max_range = min(getviewsize(world.view)[1], getviewsize(world.view)[2]) - 2 + var/obj/effect/proc_holder/spell/self/overload/overload = power + overload.max_distance = min(max_range, initial(overload.max_distance) * GET_MUTATION_POWER(src)) /obj/effect/proc_holder/spell/self/overload name = "Overload" desc = "Concentrate to make your skin energize." clothes_req = FALSE human_req = FALSE - charge_max = 400 + charge_max = 40 SECONDS action_icon_state = "blind" var/max_distance = 4 -/obj/effect/proc_holder/spell/self/overload/cast(mob/user = usr) +/obj/effect/proc_holder/spell/self/overload/cast(mob/living/carbon/human/user) if(!isethereal(user)) return - var/list/mob/targets = oviewers(max_distance, get_turf(user)) visible_message("[user] emits a blinding light!") - for(var/mob/living/carbon/C in targets) - if(C.flash_act(1)) - C.Paralyze(10 + (5*max_distance)) - -/datum/mutation/overload/modify() - if(power) - var/obj/effect/proc_holder/spell/self/overload/S = power - S.max_distance = 4 * GET_MUTATION_POWER(src) - -/datum/mutation/acidooze - name = "Acidic Hands" - desc = "Allows an Oozeling to metabolize some of their blood into acid, concentrated on their hands." - quality = POSITIVE - locked = TRUE - instability = 30 - power = /obj/effect/proc_holder/spell/targeted/touch/acidooze - species_allowed = list(SPECIES_OOZELING) - -/obj/effect/proc_holder/spell/targeted/touch/acidooze - name = "Acidic Hands" - desc = "Concentrate to make some of your blood become acidic." - clothes_req = FALSE - human_req = FALSE - charge_max = 100 - action_icon_state = "summons" - var/volume = 10 - hand_path = /obj/item/melee/touch_attack/acidooze - drawmessage = "You secrete acid into your hand." - dropmessage = "You let the acid in your hand dissipate." - -/obj/item/melee/touch_attack/acidooze - name = "\improper acidic hand" - desc = "Keep away from children, paperwork, and children doing paperwork." - catchphrase = null - icon = 'icons/effects/blood.dmi' - var/icon_left = "bloodhand_left" - var/icon_right = "bloodhand_right" - icon_state = "bloodhand_left" - item_state = "fleshtostone" - -/obj/item/melee/touch_attack/acidooze/equipped(mob/user, slot) - . = ..() - //these are intentionally inverted - var/i = user.get_held_index_of_item(src) - if(!(i % 2)) - icon_state = icon_left - else - icon_state = icon_right - -/obj/item/melee/touch_attack/acidooze/afterattack(atom/target, mob/living/carbon/user, proximity) - if(!proximity || !isoozeling(user)) - return - var/mob/living/carbon/C = user - if(!target || user.incapacitated()) - return FALSE - if(C.blood_volume < 40) - to_chat(user, "You don't have enough blood to do that!") - return FALSE - if(target.acid_act(50, 15)) - user.visible_message("[user] rubs globs of vile stuff all over [target].") - C.blood_volume = max(C.blood_volume - 20, 0) - return ..() - else - to_chat(user, "You cannot dissolve this object.") - return FALSE + for(var/mob/living/carbon/target in targets) + if(target.flash_act(1)) + target.Paralyze(10 + (5 * max_distance)) diff --git a/code/datums/mutations/antenna.dm b/code/datums/mutations/antenna.dm index 23cf729cbae13..bb04b532f32de 100644 --- a/code/datums/mutations/antenna.dm +++ b/code/datums/mutations/antenna.dm @@ -6,16 +6,6 @@ difficulty = 8 var/datum/weakref/radio_weakref -/obj/item/implant/radio/antenna - name = "internal antenna organ" - desc = "The internal organ part of the antenna. Science has not yet given it a good name." - icon = 'icons/obj/radio.dmi'//maybe make a unique sprite later. not important - icon_state = "walkietalkie" - -/obj/item/implant/radio/antenna/Initialize(mapload) - ..() - radio.name = "internal antenna" - /datum/mutation/antenna/on_acquiring(mob/living/carbon/owner) if(..()) return @@ -37,3 +27,13 @@ /datum/mutation/antenna/get_visual_indicator() return visual_indicators[type][1] + +/obj/item/implant/radio/antenna + name = "internal antenna organ" + desc = "The internal organ part of the antenna. Science has not yet given it a good name." + icon = 'icons/obj/radio.dmi'//maybe make a unique sprite later. not important + icon_state = "walkietalkie" + +/obj/item/implant/radio/antenna/Initialize() + . = ..() + radio.name = "internal antenna" diff --git a/code/datums/mutations/body.dm b/code/datums/mutations/body.dm index bc4f6f2ccac15..cde24cbb591d0 100644 --- a/code/datums/mutations/body.dm +++ b/code/datums/mutations/body.dm @@ -14,7 +14,7 @@ owner.Unconscious(200 * GET_MUTATION_POWER(src)) owner.Jitter(1000 * GET_MUTATION_POWER(src)) SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "epilepsy", /datum/mood_event/epilepsy) - addtimer(CALLBACK(src, PROC_REF(jitter_less)), 90) + addtimer(CALLBACK(src, PROC_REF(jitter_less)), 9 SECONDS) /datum/mutation/epilepsy/proc/jitter_less() if(owner) @@ -105,17 +105,7 @@ name = "Clumsiness" desc = "A genome that inhibits certain brain functions, causing the holder to appear clumsy. Honk" quality = MINOR_NEGATIVE - -/datum/mutation/clumsy/on_acquiring(mob/living/carbon/owner) - if(..()) - return - ADD_TRAIT(owner, TRAIT_CLUMSY, GENETIC_MUTATION) - -/datum/mutation/clumsy/on_losing(mob/living/carbon/owner) - if(..()) - return - REMOVE_TRAIT(owner, TRAIT_CLUMSY, GENETIC_MUTATION) - + traits = TRAIT_CLUMSY //Tourettes causes you to randomly stand in place and shout. /datum/mutation/tourettes @@ -134,8 +124,8 @@ owner.say("[prob(50) ? ";" : ""][pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]", forced="tourette's syndrome") var/x_offset_old = owner.pixel_x var/y_offset_old = owner.pixel_y - var/x_offset = owner.pixel_x + rand(-2,2) - var/y_offset = owner.pixel_y + rand(-1,1) + var/x_offset = owner.pixel_x + rand(-2, 2) + var/y_offset = owner.pixel_y + rand(-1, 1) animate(owner, pixel_x = x_offset, pixel_y = y_offset, time = 1) animate(owner, pixel_x = x_offset_old, pixel_y = y_offset_old, time = 1) @@ -145,19 +135,13 @@ name = "Deafness" desc = "The holder of this genome is completely deaf." quality = NEGATIVE + traits = TRAIT_DEAF /datum/mutation/deaf/on_acquiring(mob/living/carbon/owner) if(..()) return - ADD_TRAIT(owner, TRAIT_DEAF, GENETIC_MUTATION) SEND_SOUND(owner, sound(null)) -/datum/mutation/deaf/on_losing(mob/living/carbon/owner) - if(..()) - return - REMOVE_TRAIT(owner, TRAIT_DEAF, GENETIC_MUTATION) - - //Monified turns you into a monkey. /datum/mutation/race name = "Monkified" @@ -174,7 +158,7 @@ . = owner.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE | TR_KEEPAI, FALSE, TRUE) /datum/mutation/race/on_losing(mob/living/carbon/monkey/owner) - if(owner && ismonkey(owner) && owner.stat != DEAD && !..()) + if(istype(owner) && owner.stat != DEAD && !..()) . = owner.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE | TR_KEEPAI, TRUE, original_species) /datum/mutation/glow @@ -182,28 +166,26 @@ desc = "You permanently emit a light with a random color and intensity." quality = POSITIVE instability = 5 + power_coeff = 1 + conflicts = list(ANTIGLOWY) var/obj/effect/dummy/luminescent_glow/glowth //shamelessly copied from luminescents var/glow = 2.5 var/range = 2.5 - power_coeff = 1 - conflicts = list(/datum/mutation/glow/anti) /datum/mutation/glow/on_acquiring(mob/living/carbon/owner) - . = ..() - if(.) + if(..()) return glowth = new(owner) modify() /datum/mutation/glow/modify() - if(!glowth) + if(QDELETED(glowth)) return var/power = GET_MUTATION_POWER(src) glowth.set_light_range_power_color(range * power, glow * power, "#[dna.features["mcolor"]]") /datum/mutation/glow/on_losing(mob/living/carbon/owner) - . = ..() - if(.) + if(..()) return QDEL_NULL(glowth) @@ -211,7 +193,7 @@ name = "Anti-Glow" desc = "Your skin seems to attract and absorb nearby light creating 'darkness' around you." glow = -3.5 //Slightly stronger, since negating light tends to be harder than making it. - conflicts = list(/datum/mutation/glow) + conflicts = list(GLOWY) locked = TRUE /datum/mutation/strong @@ -226,16 +208,7 @@ quality = POSITIVE difficulty = 16 instability = 25 - -/datum/mutation/insulated/on_acquiring(mob/living/carbon/owner) - if(..()) - return - ADD_TRAIT(owner, TRAIT_SHOCKIMMUNE, "genetics") - -/datum/mutation/insulated/on_losing(mob/living/carbon/owner) - if(..()) - return - REMOVE_TRAIT(owner, TRAIT_SHOCKIMMUNE, "genetics") + traits = TRAIT_SHOCKIMMUNE /datum/mutation/fire name = "Fiery Sweat" @@ -278,13 +251,13 @@ /datum/mutation/badblink/on_life() if(prob(warpchance)) var/warpmessage = pick( - "With a sickening 720 degree twist of their back, [owner] vanishes into thin air.", - "[owner] does some sort of strange backflip into another dimension. It looks pretty painful.", - "[owner] does a jump to the left, a step to the right, and warps out of reality.", - "[owner]'s torso starts folding inside out until it vanishes from reality, taking [owner] with it.", - "One moment, you see [owner]. The next, [owner] is gone.") + "With a sickening 720 degree twist of their back, [owner] vanishes into thin air.", + "[owner] does some sort of strange backflip into another dimension. It looks pretty painful.", + "[owner] does a jump to the left, a step to the right, and warps out of reality.", + "[owner]'s torso starts folding inside out until it vanishes from reality, taking [owner] with it.", + "One moment, you see [owner]. The next, [owner] is gone.") owner.visible_message(warpmessage, "You feel a wave of nausea as you fall through reality!") - var/warpdistance = rand(10,15) * GET_MUTATION_POWER(src) + var/warpdistance = rand(10, 15) * GET_MUTATION_POWER(src) do_teleport(owner, get_turf(owner), warpdistance, channel = TELEPORT_CHANNEL_BLINK) owner.adjust_disgust(GET_MUTATION_SYNCHRONIZER(src) * (warpchance * warpdistance)) warpchance = 0 @@ -297,17 +270,17 @@ desc = "Subject has acidic chemicals building up underneath their skin. This is often lethal." quality = NEGATIVE difficulty = 18//high so it's hard to unlock and use on others - var/msgcooldown = 0 + COOLDOWN_DECLARE(message_cooldown) /datum/mutation/acidflesh/on_life() if(prob(25)) - if(world.time > msgcooldown) + if(COOLDOWN_FINISHED(src, message_cooldown)) to_chat(owner, "Your acid flesh bubbles...") - msgcooldown = world.time + 200 + COOLDOWN_START(src, message_cooldown, 20 SECONDS) if(prob(15)) - owner.acid_act(rand(30,50), 10) + owner.acid_act(rand(30, 50), 10) owner.visible_message("[owner]'s skin bubbles and pops.", "Your bubbling flesh pops! It burns!") - playsound(owner,'sound/weapons/sear.ogg', 50, 1) + playsound(owner, 'sound/weapons/sear.ogg', vol = 50, vary = TRUE) /datum/mutation/gigantism name = "Gigantism"//negative version of dwarfism @@ -351,15 +324,18 @@ desc = "A mutation that disrupts coordination in the legs. It makes standing up after getting knocked down very difficult." quality = NEGATIVE difficulty = 16 - var/stun_cooldown = 0 + COOLDOWN_DECLARE(stun_cooldown) /datum/mutation/extrastun/on_life() - if(world.time > stun_cooldown) - if(owner.AmountKnockdown() || owner.AmountStun()) - owner.SetKnockdown(owner.AmountKnockdown()*2) - owner.SetStun(owner.AmountStun()*2) - owner.visible_message("[owner] tries to stand up, but trips!", "You trip over your own feet!") - stun_cooldown = world.time + 300 + if(!COOLDOWN_FINISHED(src, stun_cooldown)) + return + var/knockdown = owner.AmountKnockdown() + var/stun = owner.AmountStun() + if(knockdown || stun) + owner.SetKnockdown(knockdown * 2) + owner.SetStun(stun * 2) + owner.visible_message("[owner] tries to stand up, but trips!", "You trip over your own feet!") + COOLDOWN_START(src, stun_cooldown, 30 SECONDS) /datum/mutation/strongwings name = "Strengthened Wings" @@ -368,12 +344,13 @@ locked = TRUE difficulty = 12 instability = 15 + power_coeff = 1 species_allowed = list(SPECIES_APID, SPECIES_MOTH) /datum/mutation/strongwings/on_acquiring() if(..()) return - var/obj/item/organ/wings/wings = locate(/obj/item/organ/wings) in owner.internal_organs + var/obj/item/organ/wings/wings = owner.getorganslot(ORGAN_SLOT_WINGS) if(!wings) to_chat(owner, "You don't have wings to strengthen!") return @@ -383,7 +360,7 @@ moth_wings.Refresh(owner) else if(istype(wings, /obj/item/organ/wings/bee)) var/obj/item/organ/wings/bee/bee_wings = wings - bee_wings.jumpdist += (6 * GET_MUTATION_POWER(src)) - 3 + bee_wings.jumpdist = initial(bee_wings.jumpdist) + (6 * GET_MUTATION_POWER(src)) - 3 else to_chat(owner, "Those wings are incompatible with the mutation!") return @@ -392,7 +369,7 @@ /datum/mutation/strongwings/on_losing() if(..()) return - var/obj/item/organ/wings/wings = locate(/obj/item/organ/wings) in owner.internal_organs + var/obj/item/organ/wings/wings = owner.getorganslot(ORGAN_SLOT_WINGS) if(!wings) return if(istype(wings, /obj/item/organ/wings/moth)) @@ -402,9 +379,14 @@ to_chat(owner, "Your wings feel weak.") else if(istype(wings, /obj/item/organ/wings/bee)) var/obj/item/organ/wings/bee/bee_wings = wings - bee_wings.jumpdist -= (6 * GET_MUTATION_POWER(src)) - 3 + bee_wings.jumpdist = initial(bee_wings.jumpdist) to_chat(owner, "Your wings feel weak.") +/datum/mutation/strongwings/modify() + ..() + var/obj/item/organ/wings/bee/bee_wings = owner.getorganslot(ORGAN_SLOT_WINGS) + if(istype(bee_wings)) + bee_wings.jumpdist = initial(bee_wings.jumpdist) + (6 * GET_MUTATION_POWER(src)) - 3 /datum/mutation/catclaws name = "Cat Claws" desc = "Subject's hands grow sharpened claws." @@ -412,22 +394,32 @@ locked = TRUE difficulty = 12 instability = 25 + power_coeff = 1 species_allowed = list(SPECIES_FELINID) var/added_damage = 6 /datum/mutation/catclaws/on_acquiring() if(..()) return - added_damage = min(17, 6 * GET_MUTATION_POWER(src) + owner.dna.species.punchdamage) - added_damage -= owner.dna.species.punchdamage + added_damage = min(17, initial(added_damage) * GET_MUTATION_POWER(src) + owner.dna.species.punchdamage) - owner.dna.species.punchdamage owner.dna.species.punchdamage += added_damage - to_chat(owner, "Claws extend from your fingertips.") owner.dna.species.attack_verb = "slash" + owner.dna.species.attack_sound = 'sound/weapons/slash.ogg' + owner.dna.species.miss_sound = 'sound/weapons/slashmiss.ogg' + to_chat(owner, "Claws extend from your fingertips.") /datum/mutation/catclaws/on_losing() if(..()) return - owner.dna.species.punchdamage -= added_damage to_chat(owner, " Your claws retract into your hand.") + owner.dna.species.punchdamage -= added_damage owner.dna.species.attack_verb = initial(owner.dna.species.attack_verb) - + owner.dna.species.attack_sound = initial(owner.dna.species.attack_sound) + owner.dna.species.miss_sound = initial(owner.dna.species.miss_sound) + +/datum/mutation/catclaws/modify() + ..() + if(added_damage) + owner.dna.species.punchdamage -= added_damage + added_damage = min(17, initial(added_damage) * GET_MUTATION_POWER(src) + owner.dna.species.punchdamage) - owner.dna.species.punchdamage + owner.dna.species.punchdamage += added_damage diff --git a/code/datums/mutations/chameleon.dm b/code/datums/mutations/chameleon.dm index 7c78011ee9337..9c9e06915347c 100644 --- a/code/datums/mutations/chameleon.dm +++ b/code/datums/mutations/chameleon.dm @@ -5,6 +5,8 @@ quality = POSITIVE difficulty = 16 instability = 25 + power_coeff = 1 + /// How much the user's alpha is reduced every life tick they are not moving. var/effect_speed = 25 /datum/mutation/chameleon/on_acquiring(mob/living/carbon/owner) @@ -12,6 +14,11 @@ return owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY +/datum/mutation/chameleon/on_losing(mob/living/carbon/owner) + if(..()) + return + owner.alpha = 255 + /datum/mutation/chameleon/on_life() owner.alpha = max(0, owner.alpha - effect_speed) @@ -21,9 +28,7 @@ /datum/mutation/chameleon/on_attack_hand(atom/target, proximity) if(proximity) //stops tk from breaking chameleon owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY - return -/datum/mutation/chameleon/on_losing(mob/living/carbon/owner) - if(..()) - return - owner.alpha = 255 +/datum/mutation/chameleon/modify() + ..() + effect_speed = round(initial(effect_speed) * GET_MUTATION_POWER(src)) diff --git a/code/datums/mutations/cluwne.dm b/code/datums/mutations/cluwne.dm index 437ad8b68e163..318e5e63db173 100644 --- a/code/datums/mutations/cluwne.dm +++ b/code/datums/mutations/cluwne.dm @@ -11,7 +11,7 @@ owner.dna.add_mutation(EPILEPSY) owner.setOrganLoss(ORGAN_SLOT_BRAIN, 199) - playsound(owner.loc, 'sound/misc/bikehorn_creepy.ogg', 50, 1) + playsound(owner.loc, 'sound/misc/bikehorn_creepy.ogg', vol = 50, vary = TRUE) owner.equip_to_slot_or_del(new /obj/item/storage/backpack/clown(owner), ITEM_SLOT_BACK) // this is purely for cosmetic purposes incase they aren't wearing anything in that slot if(!istype(owner.wear_mask, /obj/item/clothing/mask/cluwne)) if(!owner.doUnEquip(owner.wear_mask)) diff --git a/code/datums/mutations/cold.dm b/code/datums/mutations/cold.dm index f46d8df38cc78..be012a988cce0 100644 --- a/code/datums/mutations/cold.dm +++ b/code/datums/mutations/cold.dm @@ -4,15 +4,14 @@ quality = POSITIVE instability = 10 difficulty = 10 - synchronizer_coeff = 1 + energy_coeff = 1 power = /obj/effect/proc_holder/spell/targeted/conjure_item/snow /obj/effect/proc_holder/spell/targeted/conjure_item/snow name = "Create Snow" desc = "Concentrates cryokinetic forces to create snow, useful for snow-like construction." item_type = /obj/item/stack/sheet/snow - - charge_max = 50 + charge_max = 5 SECONDS delete_old = FALSE action_icon_state = "snow" @@ -22,7 +21,7 @@ quality = POSITIVE instability = 10 difficulty = 10 - synchronizer_coeff = 1 + energy_coeff = 1 locked = TRUE power = /obj/effect/proc_holder/spell/targeted/conjure_item/wax @@ -30,7 +29,7 @@ name = "Secrete Wax" desc = "Concentrate to spit out some wax, useful for bee-themed construction." item_type = /obj/item/stack/sheet/wax - charge_max = 50 + charge_max = 5 SECONDS delete_old = FALSE action_icon_state = "honey" @@ -40,14 +39,21 @@ quality = POSITIVE //upsides and downsides instability = 20 difficulty = 12 - synchronizer_coeff = 1 + energy_coeff = 1 + power_coeff = 1 power = /obj/effect/proc_holder/spell/aimed/cryo +/datum/mutation/cryokinesis/modify() + ..() + if(power) + var/obj/effect/proc_holder/spell/aimed/cryo/cryobeam = power + cryobeam.power = GET_MUTATION_POWER(src) + /obj/effect/proc_holder/spell/aimed/cryo name = "Cryobeam" desc = "This power fires a frozen bolt at a target." - charge_max = 150 - cooldown_min = 150 + charge_max = 15 SECONDS + cooldown_min = 15 SECONDS clothes_req = FALSE range = 3 projectile_type = /obj/projectile/temp/cryo @@ -56,4 +62,9 @@ active_msg = "You focus your cryokinesis!" deactive_msg = "You relax." active = FALSE + var/power = 1 +/obj/effect/proc_holder/spell/aimed/cryo/ready_projectile(obj/projectile/temp/cryo/cryobeam, atom/target, mob/user, iteration) + if(!istype(cryobeam)) + return + cryobeam.temperature *= power diff --git a/code/datums/mutations/hulk.dm b/code/datums/mutations/hulk.dm index 5d6679d521c3c..96fe31b2ba3ad 100644 --- a/code/datums/mutations/hulk.dm +++ b/code/datums/mutations/hulk.dm @@ -10,16 +10,18 @@ health_req = 25 instability = 40 locked = TRUE + traits = list( + TRAIT_STUNIMMUNE, + TRAIT_PUSHIMMUNE, + TRAIT_CONFUSEIMMUNE, + TRAIT_IGNOREDAMAGESLOWDOWN, + TRAIT_NOSTAMCRIT, + TRAIT_NOLIMBDISABLE + ) /datum/mutation/hulk/on_acquiring(mob/living/carbon/human/owner) if(..()) return - ADD_TRAIT(owner, TRAIT_STUNIMMUNE, TRAIT_HULK) - ADD_TRAIT(owner, TRAIT_PUSHIMMUNE, TRAIT_HULK) - ADD_TRAIT(owner, TRAIT_CONFUSEIMMUNE, TRAIT_HULK) - ADD_TRAIT(owner, TRAIT_IGNOREDAMAGESLOWDOWN, TRAIT_HULK) - ADD_TRAIT(owner, TRAIT_NOSTAMCRIT, TRAIT_HULK) - ADD_TRAIT(owner, TRAIT_NOLIMBDISABLE, TRAIT_HULK) SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "hulk", /datum/mood_event/hulk) RegisterSignal(owner, COMSIG_MOB_SAY, PROC_REF(handle_speech)) owner.update_body_parts() @@ -36,12 +38,6 @@ /datum/mutation/hulk/on_losing(mob/living/carbon/human/owner) if(..()) return - REMOVE_TRAIT(owner, TRAIT_STUNIMMUNE, TRAIT_HULK) - REMOVE_TRAIT(owner, TRAIT_PUSHIMMUNE, TRAIT_HULK) - REMOVE_TRAIT(owner, TRAIT_CONFUSEIMMUNE, TRAIT_HULK) - REMOVE_TRAIT(owner, TRAIT_IGNOREDAMAGESLOWDOWN, TRAIT_HULK) - REMOVE_TRAIT(owner, TRAIT_NOSTAMCRIT, TRAIT_HULK) - REMOVE_TRAIT(owner, TRAIT_NOLIMBDISABLE, TRAIT_HULK) SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "hulk") owner.update_body_parts() UnregisterSignal(owner, COMSIG_MOB_SAY) diff --git a/code/datums/mutations/radioactive.dm b/code/datums/mutations/radioactive.dm index 03d89f6d763b5..2dd8630e6710e 100644 --- a/code/datums/mutations/radioactive.dm +++ b/code/datums/mutations/radioactive.dm @@ -6,14 +6,13 @@ difficulty = 8 power_coeff = 1 - -/datum/mutation/radioactive/on_life() - radiation_pulse(owner, 20 * GET_MUTATION_POWER(src)) - /datum/mutation/radioactive/New(class_ = MUT_OTHER, timer, datum/mutation/copymut) ..() if(!(type in visual_indicators)) visual_indicators[type] = list(mutable_appearance('icons/effects/genetics.dmi', "radiation", -MUTATIONS_LAYER)) +/datum/mutation/radioactive/on_life() + radiation_pulse(owner, 20 * GET_MUTATION_POWER(src)) + /datum/mutation/radioactive/get_visual_indicator() return visual_indicators[type][1] diff --git a/code/datums/mutations/sight.dm b/code/datums/mutations/sight.dm index f41646bc08ae1..9ca7f2c107d85 100644 --- a/code/datums/mutations/sight.dm +++ b/code/datums/mutations/sight.dm @@ -39,19 +39,16 @@ difficulty = 18 instability = 25 locked = TRUE - var/visionflag = TRAIT_THERMAL_VISION + traits = TRAIT_THERMAL_VISION /datum/mutation/thermal/on_acquiring(mob/living/carbon/owner) if(..()) return - - ADD_TRAIT(owner, visionflag, GENETIC_MUTATION) owner.update_sight() /datum/mutation/thermal/on_losing(mob/living/carbon/owner) if(..()) return - REMOVE_TRAIT(owner, visionflag, GENETIC_MUTATION) owner.update_sight() //X-ray Vision lets you see through walls. @@ -60,7 +57,7 @@ desc = "A strange mutation that allows the user to see between the spaces of walls." //actual x-ray would mean you'd constantly be blasting rads, wich might be fun for later //hmb instability = 35 locked = TRUE - visionflag = TRAIT_XRAY_VISION + traits = TRAIT_XRAY_VISION //Laser Eyes lets you shoot lasers from your eyes! /datum/mutation/laser_eyes diff --git a/code/datums/mutations/space_adaptation.dm b/code/datums/mutations/space_adaptation.dm index e5d294e6925b1..837c0235c6ada 100644 --- a/code/datums/mutations/space_adaptation.dm +++ b/code/datums/mutations/space_adaptation.dm @@ -5,6 +5,7 @@ quality = POSITIVE difficulty = 16 instability = 30 + traits = list(TRAIT_RESISTCOLD, TRAIT_RESISTLOWPRESSURE) /datum/mutation/space_adaptation/New(class_ = MUT_OTHER, timer, datum/mutation/copymut) ..() @@ -13,16 +14,3 @@ /datum/mutation/space_adaptation/get_visual_indicator() return visual_indicators[type][1] - -/datum/mutation/space_adaptation/on_acquiring(mob/living/carbon/owner) - if(..()) - return - ADD_TRAIT(owner, TRAIT_RESISTCOLD, "space_adaptation") - ADD_TRAIT(owner, TRAIT_RESISTLOWPRESSURE, "space_adaptation") - -/datum/mutation/space_adaptation/on_losing(mob/living/carbon/owner) - if(..()) - return - REMOVE_TRAIT(owner, TRAIT_RESISTCOLD, "space_adaptation") - REMOVE_TRAIT(owner, TRAIT_RESISTLOWPRESSURE, "space_adaptation") - diff --git a/code/datums/mutations/speech.dm b/code/datums/mutations/speech.dm index dfce6b4e4681f..2e55f493b662b 100644 --- a/code/datums/mutations/speech.dm +++ b/code/datums/mutations/speech.dm @@ -10,7 +10,6 @@ if(prob(10)) owner.stuttering = max(10, owner.stuttering) - /datum/mutation/wacky name = "Wacky" desc = "Effects not tested..." @@ -35,17 +34,7 @@ name = "Mute" desc = "Inherited mutation that completely inhibits the vocal section of the brain." quality = NEGATIVE - -/datum/mutation/mute/on_acquiring(mob/living/carbon/owner) - if(..()) - return - ADD_TRAIT(owner, TRAIT_MUTE, GENETIC_MUTATION) - -/datum/mutation/mute/on_losing(mob/living/carbon/owner) - if(..()) - return - REMOVE_TRAIT(owner, TRAIT_MUTE, GENETIC_MUTATION) - + traits = TRAIT_MUTE /datum/mutation/smile name = "Smile" @@ -116,16 +105,7 @@ name = "Unintelligible" desc = "Hereditary mutation that partially inhibits the vocal center of the brain, resulting in a severe speech disorder." quality = NEGATIVE - -/datum/mutation/unintelligible/on_acquiring(mob/living/carbon/owner) - if(..()) - return - ADD_TRAIT(owner, TRAIT_UNINTELLIGIBLE_SPEECH, GENETIC_MUTATION) - -/datum/mutation/unintelligible/on_losing(mob/living/carbon/owner) - if(..()) - return - REMOVE_TRAIT(owner, TRAIT_UNINTELLIGIBLE_SPEECH, GENETIC_MUTATION) + traits = TRAIT_UNINTELLIGIBLE_SPEECH /datum/mutation/swedish name = "Swedish" diff --git a/code/datums/mutations/touch.dm b/code/datums/mutations/touch.dm index de3d60e650530..e7ae13357265e 100644 --- a/code/datums/mutations/touch.dm +++ b/code/datums/mutations/touch.dm @@ -4,50 +4,103 @@ quality = POSITIVE locked = TRUE difficulty = 16 - power = /obj/effect/proc_holder/spell/targeted/touch/shock + power = /obj/effect/proc_holder/spell/targeted/touch/mutation/shock instability = 30 locked = TRUE + energy_coeff = 1 + power_coeff = 1 -/obj/effect/proc_holder/spell/targeted/touch/shock +/obj/effect/proc_holder/spell/targeted/touch/mutation/shock name = "Shock Touch" desc = "Channel electricity to your hand to shock people with." drawmessage = "You channel electricity into your hand." dropmessage = "You let the electricity from your hand dissipate." - hand_path = /obj/item/melee/touch_attack/shock - charge_max = 100 - clothes_req = FALSE + hand_path = /obj/item/melee/touch_attack/mutation/shock + charge_max = 10 SECONDS action_icon_state = "zap" -/obj/item/melee/touch_attack/shock +/obj/item/melee/touch_attack/mutation/shock name = "\improper shock touch" desc = "This is kind of like when you rub your feet on a shag rug so you can zap your friends, only a lot less safe." - catchphrase = null on_use_sound = 'sound/weapons/zapbang.ogg' icon_state = "zapper" item_state = "zapper" -/obj/item/melee/touch_attack/shock/afterattack(atom/target, mob/living/carbon/user, proximity) - user.Beam(target, icon_state="lightning[rand(1,12)]", time=5, maxdistance = 32) +/obj/item/melee/touch_attack/mutation/shock/afterattack(atom/target, mob/living/carbon/user, proximity) + if(QDELETED(target) || isturf(target)) + return + user.Beam(target, icon_state = "lightning[rand(1, 12)]", time = 5, maxdistance = 32) + var/zap = 15 * GET_MUTATION_POWER(parent_mutation) if(iscarbon(target)) - var/mob/living/carbon/C = target - if(C.electrocute_act(15, user, 1, FALSE, FALSE, FALSE, FALSE, FALSE))//doesnt stun. never let this stun - C.dropItemToGround(C.get_active_held_item()) - C.dropItemToGround(C.get_inactive_held_item()) - C.confused += 15 - C.visible_message("[user] electrocutes [target]!","[user] electrocutes you!") - use_charge(user) - return ..() + var/mob/living/carbon/ctarget = target + if(ctarget.electrocute_act(zap, user, stun = FALSE)) //doesnt stun. never let this stun + ctarget.drop_all_held_items() + ctarget.confused += zap + ctarget.visible_message("[user] electrocutes [target]!","[user] electrocutes you!") else user.visible_message("[user] fails to electrocute [target]!") - use_charge(user) - return ..() else if(isliving(target)) - var/mob/living/L = target - L.electrocute_act(15, user, 1, FALSE, FALSE, FALSE, FALSE) - L.visible_message("[user] electrocutes [target]!","[user] electrocutes you!") - use_charge(user) - return ..() + var/mob/living/ltarget = target + ltarget.electrocute_act(zap, user, stun = FALSE) + ltarget.visible_message("[user] electrocutes [target]!","[user] electrocutes you!") else to_chat(user,"The electricity doesn't seem to affect [target]...") - use_charge(user) + use_charge(user) + return ..() + +/datum/mutation/acidooze + name = "Acidic Hands" + desc = "Allows an Oozeling to metabolize some of their blood into acid, concentrated on their hands." + quality = POSITIVE + locked = TRUE + instability = 30 + power = /obj/effect/proc_holder/spell/targeted/touch/mutation/acidooze + power_coeff = 1 + energy_coeff = 1 + synchronizer_coeff = 1 + species_allowed = list(SPECIES_OOZELING) + +/obj/effect/proc_holder/spell/targeted/touch/mutation/acidooze + name = "Acidic Hands" + desc = "Concentrate to make some of your blood become acidic." + clothes_req = FALSE + human_req = FALSE + charge_max = 10 SECONDS + action_icon_state = "summons" + hand_path = /obj/item/melee/touch_attack/mutation/acidooze + drawmessage = "You secrete acid into your hand." + dropmessage = "You let the acid in your hand dissipate." + +/obj/item/melee/touch_attack/mutation/acidooze + name = "\improper acidic hand" + desc = "Keep away from children, paperwork, and children doing paperwork." + icon = 'icons/effects/blood.dmi' + icon_state = "bloodhand_left" + item_state = "fleshtostone" + var/static/base_acid_volume = 15 + var/static/base_blood_cost = 20 + var/static/icon_left = "bloodhand_left" + var/static/icon_right = "bloodhand_right" + +/obj/item/melee/touch_attack/mutation/acidooze/equipped(mob/user, slot) + . = ..() + //these are intentionally inverted + icon_state = (user.get_held_index_of_item(src) % 2) ? icon_right : icon_left + +/obj/item/melee/touch_attack/mutation/acidooze/afterattack(atom/target, mob/living/carbon/user, proximity) + if(!proximity || !isoozeling(user)) + return + if(!target || user.incapacitated()) + return FALSE + var/acid_volume = base_acid_volume * GET_MUTATION_POWER(parent_mutation) + var/blood_cost = base_blood_cost * GET_MUTATION_SYNCHRONIZER(parent_mutation) + if(user.blood_volume < (blood_cost * 2)) + to_chat(user, "You don't have enough blood to do that!") + return FALSE + if(target.acid_act(50, acid_volume)) + user.visible_message("[user] rubs globs of vile stuff all over [target].") + user.blood_volume = max(user.blood_volume - blood_cost, 0) return ..() + else + to_chat(user, "You cannot dissolve this object.") + return FALSE diff --git a/code/datums/progressbar.dm b/code/datums/progressbar.dm index 3d00f3cd6bb5b..3dc2a6572d5d3 100644 --- a/code/datums/progressbar.dm +++ b/code/datums/progressbar.dm @@ -42,7 +42,7 @@ if (user.client) user.client.images += bar - progress = CLAMP(progress, 0, goal) + progress = clamp(progress, 0, goal) last_progress = progress bar.icon_state = "prog_bar_[round(((progress / goal) * 100), 5)]" if (!shown) diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index db2a786170f95..e969ec3acbf14 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -484,6 +484,7 @@ healSnake.desc = "A mystical snake previously trapped upon the Rod of Asclepius, now freed of its burden. Unlike the average snake, its bites contain chemicals with minor healing properties." new /obj/effect/decal/cleanable/ash(owner.loc) new /obj/item/rod_of_asclepius(owner.loc) + owner.investigate_log("has been consumed by the Rod of Asclepius.", INVESTIGATE_DEATHS) qdel(owner) else if(iscarbon(owner)) diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 8a447462570ef..944e109ec07a5 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -33,9 +33,11 @@ if(!.) return ADD_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id)) + ADD_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id)) /datum/status_effect/incapacitating/stun/on_remove() REMOVE_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id)) + REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id)) return ..() //KNOCKDOWN @@ -46,6 +48,16 @@ /datum/status_effect/incapacitating/immobilized id = "immobilized" +/datum/status_effect/incapacitating/immobilized/on_apply() + . = ..() + if(!.) + return + ADD_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id)) + +/datum/status_effect/incapacitating/immobilized/on_remove() + REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id)) + return ..() + /datum/status_effect/incapacitating/paralyzed id = "paralyzed" @@ -54,9 +66,11 @@ if(!.) return ADD_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id)) + ADD_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id)) /datum/status_effect/incapacitating/paralyzed/on_remove() REMOVE_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id)) + REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id)) return ..() //UNCONSCIOUS @@ -68,10 +82,10 @@ . = ..() if(!.) return - ADD_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id)) + ADD_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id)) /datum/status_effect/incapacitating/unconscious/on_remove() - REMOVE_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id)) + REMOVE_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id)) return ..() /datum/status_effect/incapacitating/unconscious/tick() @@ -99,6 +113,16 @@ human_owner = null return ..() +/datum/status_effect/incapacitating/sleeping/on_apply() + . = ..() + if(!.) + return + ADD_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id)) + +/datum/status_effect/incapacitating/sleeping/on_remove() + REMOVE_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id)) + return ..() + /datum/status_effect/incapacitating/sleeping/tick() if(owner.maxHealth) var/health_ratio = owner.health / owner.maxHealth @@ -149,26 +173,22 @@ if(.) update_time_of_death() owner.reagents?.end_metabolization(owner, FALSE) - owner.update_mobility() SEND_SIGNAL(owner, COMSIG_LIVING_ENTER_STASIS) -/* Mobility refactor /datum/status_effect/grouped/stasis/on_apply() . = ..() if(!.) return ADD_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id)) - ADD_TRAIT(owner, TRAIT_HANDS_BLOCKED, TRAIT_STATUS_EFFECT(id)) -*/ + //ADD_TRAIT(owner, TRAIT_HANDS_BLOCKED, TRAIT_STATUS_EFFECT(id)) + owner.update_mobility() // TEMPORARY /datum/status_effect/grouped/stasis/tick() update_time_of_death() /datum/status_effect/grouped/stasis/on_remove() - /* Mobility refactor REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id)) - REMOVE_TRAIT(owner, TRAIT_HANDS_BLOCKED, TRAIT_STATUS_EFFECT(id)) - */ + //REMOVE_TRAIT(owner, TRAIT_HANDS_BLOCKED, TRAIT_STATUS_EFFECT(id)) owner.update_mobility() update_time_of_death() SEND_SIGNAL(owner, COMSIG_LIVING_EXIT_STASIS) diff --git a/code/datums/status_effects/gas.dm b/code/datums/status_effects/gas.dm index 42715522e8f30..f5fa401c6622e 100644 --- a/code/datums/status_effects/gas.dm +++ b/code/datums/status_effects/gas.dm @@ -6,6 +6,16 @@ var/icon/cube var/can_melt = TRUE +/datum/status_effect/freon/on_apply() + . = ..() + if(!.) + return + ADD_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id)) + +/datum/status_effect/freon/on_remove() + REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id)) + return ..() + /atom/movable/screen/alert/status_effect/freon name = "Frozen Solid" desc = "You're frozen inside an ice cube, and cannot move! You can still do stuff, like shooting. Resist out of the cube!" diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm index a548abf750f3f..b9b821bf46b73 100644 --- a/code/datums/wires/airlock.dm +++ b/code/datums/wires/airlock.dm @@ -53,7 +53,7 @@ var/list/status = list() status += "The door bolts [A.locked ? "have fallen!" : "look up."]" status += "The test light is [A.hasPower() ? (A.isElectrified() ? "bright and flicking" : "on") : "off"]." - status += "The AI connection light is [A.aiControlDisabled || (A.obj_flags & EMAGGED) ? "off" : "on"]." + status += "The AI connection light is [A.aiControlDisabled ? "off" : "on"]." status += "The check wiring light is [A.safe ? "off" : "on"]." status += "The timer is powered [A.autoclose ? "on" : "off"]." status += "The speed light is [A.normalspeed ? "on" : "off"]." @@ -68,15 +68,14 @@ if(isliving(usr) && A.hasPower() && A.isElectrified()) if (A.shock(usr, 100)) return - if(A.hasPower()) //Multitool has no effect at all if the door has lost power + switch(wire) + if(WIRE_POWER1, WIRE_POWER2) // Pulse to lose power, or reset the delay before restoring power if already lost + A.loseMainPower() + if(WIRE_BACKUP1, WIRE_BACKUP2) // Pulse to lose backup power, or reset the delay before restoring power if already lost + A.loseBackupPower() + if(A.hasPower()) //Multitool has no effect on other wires if the door has no power switch(wire) - if(WIRE_POWER1, WIRE_POWER2) // Pulse to loose power. - A.loseMainPower() - if(WIRE_BACKUP1, WIRE_BACKUP2) // Pulse to loose backup power. - A.loseBackupPower() - if(WIRE_OPEN) // Pulse to open door (only works not emagged and ID wire is cut or no access is required). - if(A.obj_flags & EMAGGED) - return + if(WIRE_OPEN) // Pulse to open door if(A.id_scan_hacked() || A.check_access(null)) if(A.density) INVOKE_ASYNC(A, TYPE_PROC_REF(/obj/machinery/door/airlock, open)) diff --git a/code/game/area/Space_Station_13_areas.dm b/code/game/area/Space_Station_13_areas.dm index cd378dc4b9151..ad9e520ff63fa 100644 --- a/code/game/area/Space_Station_13_areas.dm +++ b/code/game/area/Space_Station_13_areas.dm @@ -121,6 +121,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station ambience_index = AMBIENCE_MAINT ambient_buzz = 'sound/ambience/source_corridor2.ogg' ambient_buzz_vol = 20 + area_flags = HIDDEN_STASH_LOCATION | VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA rare_ambient_sounds = list( 'sound/machines/airlock.ogg', 'sound/effects/snap.ogg', @@ -153,10 +154,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/maintenance/department/chapel name = "Chapel Maintenance" icon_state = "maint_chapel" + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA /area/maintenance/department/chapel/monastery name = "Monastery Maintenance" icon_state = "maint_monastery" + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA /area/maintenance/department/crew_quarters/bar name = "Bar Maintenance" @@ -179,14 +182,17 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/maintenance/department/engine/atmos name = "Atmospherics Maintenance" icon_state = "maint_atmos" + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA /area/maintenance/department/security name = "Security Maintenance" icon_state = "maint_sec" + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA /area/maintenance/department/security/brig name = "Brig Maintenance" icon_state = "maint_brig" + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA /area/maintenance/department/medical name = "Medbay Maintenance" @@ -215,6 +221,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/maintenance/department/bridge name = "Bridge Maintenance" icon_state = "maint_bridge" + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA /area/maintenance/department/engine name = "Engineering Maintenance" @@ -369,10 +376,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station //Hallway /area/hallway - sound_environment = SOUND_AREA_STANDARD_STATION - lights_always_start_on = TRUE /area/hallway + area_flags = HIDDEN_STASH_LOCATION | VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA + sound_environment = SOUND_AREA_STANDARD_STATION + lights_always_start_on = TRUE lighting_colour_tube = "#ffce99" lighting_colour_bulb = "#ffdbb4" lighting_brightness_tube = 8 @@ -403,6 +411,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/hallway/secondary/command name = "Command Hallway" icon_state = "bridge_hallway" + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA /area/hallway/secondary/construction name = "Construction Area" @@ -455,6 +464,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/hallway/upper/secondary/command name = "Upper Command Hallway" icon_state = "bridge_hallway" + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA /area/hallway/upper/secondary/construction name = "Upper Construction Area" @@ -507,6 +517,9 @@ NOTE: there are two lists of areas in the end of this file: centcom and station icon_state = "showroom" sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR +/area/crew_quarters + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA + /area/crew_quarters/heads/captain name = "Captain's Office" icon_state = "captain" @@ -571,6 +584,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station //Crew /area/crew_quarters + area_flags = HIDDEN_STASH_LOCATION | VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA lighting_colour_tube = "#ffce99" lighting_colour_bulb = "#ffdbb4" lighting_brightness_tube = 8 @@ -581,10 +595,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/crew_quarters/dorms name = "Dormitories" icon_state = "dorms" - area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA mood_bonus = 3 mood_message = "There's no place like the dorms!\n" +/area/commons + area_flags = HIDDEN_STASH_LOCATION | VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA + /area/commons/dorms/barracks name = "Sleep Barracks" @@ -684,6 +700,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station icon_state = "bar" mood_bonus = 5 mood_message = "I love being in the bar!\n" + lights_always_start_on = TRUE lighting_colour_tube = "#fff4d6" lighting_colour_bulb = "#ffebc1" sound_environment = SOUND_AREA_WOODFLOOR @@ -704,13 +721,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station . = ..() GLOB.bar_areas += src -/area/service/bar - lights_always_start_on = TRUE - -/area/service/bar/Initialize(mapload) - . = ..() - GLOB.bar_areas += src - /area/crew_quarters/bar/atrium name = "Atrium" icon_state = "bar" @@ -748,6 +758,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "Library" icon_state = "library" flags_1 = NONE + area_flags = HIDDEN_STASH_LOCATION | VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA lighting_colour_tube = "#ffce99" lighting_colour_bulb = "#ffdbb4" @@ -768,6 +779,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/chapel icon_state = "chapel" ambience_index = AMBIENCE_HOLY + area_flags = HIDDEN_STASH_LOCATION | VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA flags_1 = NONE clockwork_warp_allowed = FALSE clockwork_warp_fail = "The consecration here prevents you from warping in." @@ -801,6 +813,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station icon_state = "law" sound_environment = SOUND_AREA_SMALL_SOFTFLOOR airlock_hack_difficulty = AIRLOCK_WIRE_SECURITY_PROTECTED + area_flags = HIDDEN_STASH_LOCATION | VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA //Engineering @@ -939,6 +952,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/maintenance/solars name = "Solar Maintenance" icon_state = "yellow" + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA /area/maintenance/solars/port name = "Port Solar Maintenance" @@ -984,6 +998,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/medical name = "Medical" icon_state = "medbay" + area_flags = HIDDEN_STASH_LOCATION | VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA ambience_index = AMBIENCE_MEDICAL sound_environment = SOUND_AREA_STANDARD_STATION mood_bonus = 2 @@ -1024,10 +1039,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/medical/storage name = "Medbay Storage" icon_state = "med_storage" + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA /area/medical/office name = "Medical Office" icon_state = "med_office" + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA /area/medical/break_room name = "Medical Break Room" @@ -1056,6 +1073,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station ambience_index = AMBIENCE_VIROLOGY flags_1 = NONE airlock_hack_difficulty = AIRLOCK_WIRE_SECURITY_PROTECTED + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA /area/medical/morgue name = "Morgue" @@ -1070,6 +1088,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "Chemistry" icon_state = "chem" airlock_hack_difficulty = AIRLOCK_WIRE_SECURITY_PROTECTED + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA /area/medical/chemistry/upper name = "Upper Chemistry" @@ -1083,6 +1102,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "Surgery" icon_state = "surgery" airlock_hack_difficulty = AIRLOCK_WIRE_SECURITY_ADVANCED + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA /area/medical/surgery/aux name = "Auxillery Surgery" @@ -1091,6 +1111,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/medical/cryo name = "Cryogenics" icon_state = "cryo" + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA /area/medical/exam_room name = "Exam Room" @@ -1100,6 +1121,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "Genetics Lab" icon_state = "genetics" airlock_hack_difficulty = AIRLOCK_WIRE_SECURITY_PROTECTED + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA /area/medical/genetics/cloning name = "Cloning Lab" @@ -1108,6 +1130,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/medical/sleeper name = "Medbay Treatment Center" icon_state = "exam_room" + area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA //Security @@ -1348,6 +1371,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "Hydroponics" icon_state = "hydro" sound_environment = SOUND_AREA_STANDARD_STATION + area_flags = HIDDEN_STASH_LOCATION | VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA airlock_hack_difficulty = AIRLOCK_WIRE_SECURITY_SIMPLE color_correction = /datum/client_colour/area_color/cold_ish diff --git a/code/game/area/area_color_correction.dm b/code/game/area/area_color_correction.dm index 679598092d18c..63dd18fbda70d 100644 --- a/code/game/area/area_color_correction.dm +++ b/code/game/area/area_color_correction.dm @@ -8,7 +8,7 @@ var/current_correction /datum/client_colour/area_color - colour = "" + colour = list(rgb(255, 0, 0), rgb(0, 255, 0), rgb(0, 0, 255)) priority = PRIORITY_LOW fade_in = 10 SECONDS fade_out = 10 SECONDS diff --git a/code/game/area/areas/holodeck.dm b/code/game/area/areas/holodeck.dm index b8873b4e9d07e..f8e4e7feb0569 100644 --- a/code/game/area/areas/holodeck.dm +++ b/code/game/area/areas/holodeck.dm @@ -3,7 +3,7 @@ icon_state = "holodeck" dynamic_lighting = DYNAMIC_LIGHTING_DISABLED flags_1 = NONE - area_flags = VALID_TERRITORY | UNIQUE_AREA | HIDDEN_AREA + area_flags = HIDDEN_STASH_LOCATION | VALID_TERRITORY | UNIQUE_AREA | HIDDEN_AREA sound_environment = SOUND_ENVIRONMENT_PADDED_CELL var/obj/machinery/computer/holodeck/linked diff --git a/code/game/atoms.dm b/code/game/atoms.dm index e3a30b90c967b..3dc7447bccf82 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -429,7 +429,6 @@ * Otherwise it simply forceMoves the atom into this atom */ /atom/proc/CheckParts(list/parts_list, datum/crafting_recipe/R) - SEND_SIGNAL(src, COMSIG_ATOM_CHECKPARTS, parts_list, R) if(parts_list) for(var/A in parts_list) if(istype(A, /datum/reagent)) @@ -445,6 +444,7 @@ else M.forceMove(src) parts_list.Cut() + SEND_SIGNAL(src, COMSIG_ATOM_CHECKPARTS, parts_list, R) ///Take air from the passed in gas mixture datum /atom/proc/assume_air(datum/gas_mixture/giver) @@ -1625,6 +1625,10 @@ filter_data[name]["priority"] = new_priority update_filters() +/obj/item/update_filters() + . = ..() + update_action_buttons() + /atom/proc/get_filter(name) if(filter_data && filter_data[name]) return filters[filter_data.Find(name)] @@ -1810,4 +1814,3 @@ qdel(src) return TRUE return FALSE - diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index b614606746325..b303c2908d74a 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -164,7 +164,7 @@ log_combat(AM, AM.pulledby, "pulled from", src) AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once. pulling = AM - AM.pulledby = src + AM.set_pulledby(src) setGrabState(state) if(ismob(AM)) var/mob/M = AM @@ -177,19 +177,26 @@ /atom/movable/proc/stop_pulling() if(pulling) - pulling.pulledby = null + pulling.set_pulledby(null) if(ismob(usr)) log_combat(usr, pulling, "has stopped pulling", addition = "at [AREACOORD(usr)]") if(ismob(pulling)) log_combat(pulling, usr, "stopped being pulled by", addition = "at [AREACOORD(pulling)]") var/mob/living/ex_pulled = pulling + setGrabState(GRAB_PASSIVE) pulling = null - setGrabState(0) if(isliving(ex_pulled)) var/mob/living/L = ex_pulled L.update_mobility()// mob gets up if it was lyng down in a chokehold SEND_SIGNAL(ex_pulled, COMSIG_MOVABLE_NO_LONGER_PULLED) +///Reports the event of the change in value of the pulledby variable. +/atom/movable/proc/set_pulledby(new_pulledby) + if(new_pulledby == pulledby) + return FALSE //null signals there was a change, be sure to return FALSE if none happened here. + . = pulledby + pulledby = new_pulledby + /atom/movable/proc/Move_Pulled(atom/A) if(!pulling) return @@ -1062,7 +1069,19 @@ /// Updates the grab state of the movable /// This exists to act as a hook for behaviour /atom/movable/proc/setGrabState(newstate) + if(newstate == grab_state) + return + SEND_SIGNAL(src, COMSIG_MOVABLE_SET_GRAB_STATE, newstate) + . = grab_state grab_state = newstate + switch(.) //Previous state. + if(GRAB_PASSIVE, GRAB_AGGRESSIVE) + if(grab_state >= GRAB_NECK) + ADD_TRAIT(pulling, TRAIT_IMMOBILIZED, CHOKEHOLD_TRAIT) + switch(grab_state) //Current state. + if(GRAB_PASSIVE, GRAB_AGGRESSIVE) + if(. >= GRAB_NECK) + REMOVE_TRAIT(pulling, TRAIT_IMMOBILIZED, CHOKEHOLD_TRAIT) /obj/item/proc/do_pickup_animation(atom/target) set waitfor = FALSE diff --git a/code/game/gamemodes/clown_ops/clown_weapons.dm b/code/game/gamemodes/clown_ops/clown_weapons.dm index f0c7dabdc45b8..db080a8a3d44f 100644 --- a/code/game/gamemodes/clown_ops/clown_weapons.dm +++ b/code/game/gamemodes/clown_ops/clown_weapons.dm @@ -119,7 +119,7 @@ /obj/item/melee/transforming/energy/sword/bananium/ignition_effect(atom/A, mob/user) return "" -/obj/item/melee/transforming/energy/sword/bananium/suicide_act(mob/user) +/obj/item/melee/transforming/energy/sword/bananium/suicide_act(mob/living/user) if(!active) transform_weapon(user, TRUE) user.visible_message("[user] is [pick("slitting [user.p_their()] stomach open with", "falling on")] [src]! It looks like [user.p_theyre()] trying to commit seppuku, but the blade slips off of [user.p_them()] harmlessly!") @@ -213,11 +213,11 @@ . = ..() QDEL_NULL(bomb) -/obj/item/grown/bananapeel/bombanana/suicide_act(mob/user) +/obj/item/grown/bananapeel/bombanana/suicide_act(mob/living/user) user.visible_message("[user] is deliberately slipping on the [src.name]! It looks like \he's trying to commit suicide.") playsound(loc, 'sound/misc/slip.ogg', 50, 1, -1) bomb.preprime(user, 0, FALSE) - return (BRUTELOSS) + return BRUTELOSS //TEARSTACHE GRENADE diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index d5032b56ff746..c8249413d7364 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -558,7 +558,7 @@ if (prob(meteorminutes/2)) wavetype = GLOB.meteors_catastrophic - var/ramp_up_final = CLAMP(round(meteorminutes/rampupdelta), 1, 10) + var/ramp_up_final = clamp(round(meteorminutes/rampupdelta), 1, 10) spawn_meteors(ramp_up_final, wavetype) @@ -649,7 +649,7 @@ var/datum/team/incursion/incursion_team /datum/dynamic_ruleset/roundstart/incursion/ready(population, forced = FALSE) - required_candidates = CLAMP(get_antag_cap(population), CONFIG_GET(number/incursion_count_min), CONFIG_GET(number/incursion_count_max)) + required_candidates = clamp(get_antag_cap(population), CONFIG_GET(number/incursion_count_min), CONFIG_GET(number/incursion_count_max)) return ..() /datum/dynamic_ruleset/roundstart/incursion/pre_execute(population) diff --git a/code/game/gamemodes/incursion/incursion.dm b/code/game/gamemodes/incursion/incursion.dm index c66f7d2f0f69b..5f66a751c64f1 100644 --- a/code/game/gamemodes/incursion/incursion.dm +++ b/code/game/gamemodes/incursion/incursion.dm @@ -36,7 +36,7 @@ var/pop = GLOB.player_details.len var/team_size = (2 * pop) / ((2 * cost_base) + ((pop - 1) * cost_increment)) log_game("Spawning [team_size] incursionists.") - team_size = CLAMP(team_size, CONFIG_GET(number/incursion_count_min), CONFIG_GET(number/incursion_count_max)) + team_size = clamp(team_size, CONFIG_GET(number/incursion_count_min), CONFIG_GET(number/incursion_count_max)) for(var/k = 1 to team_size) var/datum/mind/incursion = antag_pick(antag_candidates, /datum/role_preference/antagonist/incursionist) diff --git a/code/game/gamemodes/meteor/meteor.dm b/code/game/gamemodes/meteor/meteor.dm index 9ed3060b7165f..14dacc54017f0 100644 --- a/code/game/gamemodes/meteor/meteor.dm +++ b/code/game/gamemodes/meteor/meteor.dm @@ -27,7 +27,7 @@ if (prob(meteorminutes/2)) wavetype = GLOB.meteors_catastrophic - var/ramp_up_final = CLAMP(round(meteorminutes/rampupdelta), 1, 10) + var/ramp_up_final = clamp(round(meteorminutes/rampupdelta), 1, 10) spawn_meteors(ramp_up_final, wavetype) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index c1159acd3941b..d637e46021bb4 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -172,7 +172,7 @@ r_pocket = /obj/item/tank/internals/emergency_oxygen/engi internals_slot = ITEM_SLOT_RPOCKET belt = /obj/item/storage/belt/military - r_hand = /obj/item/gun/ballistic/shotgun/bulldog + r_hand = /obj/item/gun/ballistic/shotgun/automatic/bulldog backpack_contents = list(/obj/item/storage/box/syndie=1,\ /obj/item/tank/jetpack/oxygen/harness=1,\ /obj/item/gun/ballistic/automatic/pistol=1,\ diff --git a/code/game/gamemodes/objectives/_objective.dm b/code/game/gamemodes/objectives/_objective.dm index f4b78489db487..b4f0840a6cb80 100644 --- a/code/game/gamemodes/objectives/_objective.dm +++ b/code/game/gamemodes/objectives/_objective.dm @@ -224,20 +224,6 @@ GLOBAL_LIST(admin_objective_list) //Prefilled admin assignable objective list switch (pick_weight(list("airlock" = 3))) if("airlock") atom_text = "An airlock" - //Valid areas - var/static/list/valid_areas = list( - /area/medical, - /area/commons, - /area/crew_quarters, - /area/service, - /area/library, - /area/maintenance, - /area/hallway, - /area/chapel, - /area/hydroponics, - /area/holodeck, - /area/lawoffice, - ) // If our airlock isn't accessible to these accesses, then we won't allow the item to spawn here var/list/safe_access_list = list(ACCESS_CARGO, ACCESS_MAINT_TUNNELS, ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_JANITOR, ACCESS_CHAPEL_OFFICE, ACCESS_THEATRE, ACCESS_LAWYER, ACCESS_CONSTRUCTION, ACCESS_MAILSORTING) //Pick a valid airlock @@ -248,12 +234,7 @@ GLOBAL_LIST(admin_objective_list) //Prefilled admin assignable objective list continue //Make sure its publicly accessible var/area/area = get_area(A) - var/valid = FALSE - for(var/area_type in valid_areas) - if(istype(area, area_type)) - valid = TRUE - break - if(!valid) + if (!(area.area_flags & HIDDEN_STASH_LOCATION)) continue //This airlock is good for us A.AddComponent(/datum/component/stash, receiver, secret_bag) diff --git a/code/game/gamemodes/objectives/basic/steal.dm b/code/game/gamemodes/objectives/basic/steal.dm index 987427736f4ba..bfbf85290dbf9 100644 --- a/code/game/gamemodes/objectives/basic/steal.dm +++ b/code/game/gamemodes/objectives/basic/steal.dm @@ -81,9 +81,12 @@ GLOBAL_LIST_EMPTY(possible_items) if(!isliving(M.current)) continue - var/list/all_items = M.current.GetAllContents() //this should get things in cheesewheels, books, etc. + var/list/all_items = M.current.GetAllContents(/obj/item) //this should get things in cheesewheels, books, etc. - for(var/obj/I in all_items) //Check for items + for(var/mob/living/simple_animal/hostile/holoparasite/holopara as() in M.holoparasite_holder?.holoparasites) + all_items |= holopara.GetAllContents(/obj/item) + + for(var/obj/I as() in all_items) //Check for items if(istype(I, steal_target)) if(!targetinfo) //If there's no targetinfo, then that means it was a custom objective. At this point, we know you have the item, so return 1. return TRUE diff --git a/code/game/gamemodes/objectives/open/destroy_equipment.dm b/code/game/gamemodes/objectives/open/destroy_equipment.dm index 3803d7315d76e..d586eeebd0f6c 100644 --- a/code/game/gamemodes/objectives/open/destroy_equipment.dm +++ b/code/game/gamemodes/objectives/open/destroy_equipment.dm @@ -8,7 +8,7 @@ "security" = list(/area/security), "the cargo bay" = list(/area/quartermaster, /area/cargo), "the bridge" = list(/area/bridge), - "the communications relay" = list(/area/comms, /area/server), + "the communications relay" = list(/area/comms, /area/server, /area/tcommsat), "the science lab" = list(/area/science), "the research division server room" = list(/area/science/server), // Anywhere monitored by the AI will do diff --git a/code/game/gamemodes/objectives/open/explosion.dm b/code/game/gamemodes/objectives/open/explosion.dm index fd99a977178f6..5f5cfe04fa983 100644 --- a/code/game/gamemodes/objectives/open/explosion.dm +++ b/code/game/gamemodes/objectives/open/explosion.dm @@ -9,7 +9,7 @@ "security" = list(/area/security), "the cargo bay" = list(/area/quartermaster, /area/cargo), "the bridge" = list(/area/bridge), - "the communications relay" = list(/area/comms, /area/server), + "the communications relay" = list(/area/comms, /area/server, /area/tcommsat), "the science lab" = list(/area/science), "the research division server room" = list(/area/science/server), // Anywhere monitored by the AI will do diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 08d728282c5d1..707db1969de02 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -244,6 +244,20 @@ Class Procs: var/datum/controller/subsystem/processing/subsystem = locate(subsystem_type) in Master.subsystems STOP_PROCESSING(subsystem, src) +/obj/machinery/LateInitialize() + . = ..() + power_change() + RegisterSignal(src, COMSIG_MOVABLE_ENTERED_AREA, PROC_REF(power_change)) + +/obj/machinery/Destroy() + GLOB.machines.Remove(src) + if(datum_flags & DF_ISPROCESSING) // A sizeable portion of machines stops processing before qdel + end_processing() + dump_inventory_contents() + QDEL_LIST(component_parts) + QDEL_NULL(circuit) + return ..() + /obj/machinery/proc/locate_machinery() return @@ -901,6 +915,9 @@ Class Procs: . = ..() if (gone == occupant) set_occupant(null) + if(gone == circuit) + LAZYREMOVE(component_parts, gone) + circuit = null /obj/machinery/proc/adjust_item_drop_location(atom/movable/AM) // Adjust item drop location to a 3x3 grid inside the tile, returns slot id from 0 to 8 var/md5 = rustg_hash_string(RUSTG_HASH_MD5, AM.name) // Oh, and it's deterministic too. A specific item will always drop from the same slot. diff --git a/code/game/machinery/airlock_cycle_control.dm b/code/game/machinery/airlock_cycle_control.dm index d0fd454fe76ec..a9c06882e13b5 100644 --- a/code/game/machinery/airlock_cycle_control.dm +++ b/code/game/machinery/airlock_cycle_control.dm @@ -742,16 +742,16 @@ scan() . = TRUE if("interior_pressure") - interior_pressure = CLAMP(text2num(params["pressure"]), 0, ONE_ATMOSPHERE) + interior_pressure = clamp(text2num(params["pressure"]), 0, ONE_ATMOSPHERE) . = TRUE if("exterior_pressure") - exterior_pressure = CLAMP(text2num(params["pressure"]), 0, ONE_ATMOSPHERE) + exterior_pressure = clamp(text2num(params["pressure"]), 0, ONE_ATMOSPHERE) . = TRUE if("depressurization_margin") - depressurization_margin = CLAMP(text2num(params["pressure"]), 0.15, 40) + depressurization_margin = clamp(text2num(params["pressure"]), 0.15, 40) . = TRUE if("skip_delay") - skip_delay = CLAMP(text2num(params["skip_delay"]), 0, 1200) + skip_delay = clamp(text2num(params["skip_delay"]), 0, 1200) . = TRUE if(.) diff --git a/code/game/machinery/bank_machine.dm b/code/game/machinery/bank_machine.dm index 1b4c728fb9f9c..7229a190f2d4f 100644 --- a/code/game/machinery/bank_machine.dm +++ b/code/game/machinery/bank_machine.dm @@ -3,6 +3,10 @@ desc = "A machine used to deposit and withdraw station funds." icon = 'goon/icons/obj/goon_terminals.dmi' idle_power_usage = 100 + base_icon_state = null // remove these 4 when we start using our own icon. + smoothing_flags = NONE + smoothing_groups = null + canSmoothWith = null var/siphoning = FALSE var/next_warning = 0 var/obj/item/radio/radio diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 6fd3f051fc198..3357092dd9e23 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -47,7 +47,6 @@ // Upgrades bitflag var/upgrades = 0 - var/datum/component/empprotection/emp_component var/internal_light = TRUE //Whether it can light up when an AI views it @@ -130,7 +129,6 @@ LAZYREMOVE(myarea.cameras, src) QDEL_NULL(alarm_manager) QDEL_NULL(assembly_ref) - QDEL_NULL(emp_component) if(bug) bug.bugged_cameras -= c_tag if(bug.current == src) diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm index e61f2bf717c4d..483767911f1ca 100644 --- a/code/game/machinery/camera/presets.dm +++ b/code/game/machinery/camera/presets.dm @@ -75,7 +75,7 @@ /obj/machinery/camera/proc/upgradeEmpProof(malf_upgrade, ignore_malf_upgrades) if(isEmpProof(ignore_malf_upgrades)) //pass a malf upgrade to ignore_malf_upgrades so we can replace the malf module with the normal one return //that way if someone tries to upgrade an already malf-upgraded camera, it'll just upgrade it to a normal version. - emp_component = AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES | EMP_PROTECT_CONTENTS) + AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES | EMP_PROTECT_CONTENTS) var/obj/structure/camera_assembly/assembly = assembly_ref?.resolve() if(malf_upgrade) assembly.malf_emp_firmware_active = TRUE //don't add parts to drop, update icon, ect. reconstructing it will also retain the upgrade. @@ -91,7 +91,7 @@ /obj/machinery/camera/proc/removeEmpProof(ignore_malf_upgrades) if(ignore_malf_upgrades) //don't downgrade it if malf software is forced onto it. return - emp_component.RemoveComponent() + RemoveElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES | EMP_PROTECT_CONTENTS) upgrades &= ~CAMERA_UPGRADE_EMP_PROOF diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm index 539354d02050c..6c9a9abf01450 100644 --- a/code/game/machinery/computer/_computer.dm +++ b/code/game/machinery/computer/_computer.dm @@ -1,7 +1,11 @@ /obj/machinery/computer name = "computer" icon = 'icons/obj/computer.dmi' - icon_state = "computer" + icon_state = "computer-0" + base_icon_state = "computer" + smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIRECTIONAL | SMOOTH_BITMASK_SKIP_CORNERS | SMOOTH_OBJ //SMOOTH_OBJ is needed because of narsie_act using initial() to restore + smoothing_groups = list(SMOOTH_GROUP_COMPUTERS) + canSmoothWith = list(SMOOTH_GROUP_COMPUTERS) density = TRUE use_power = IDLE_POWER_USE idle_power_usage = 300 @@ -26,9 +30,14 @@ /obj/machinery/computer/Initialize(mapload) . = ..() - + QUEUE_SMOOTH(src) + QUEUE_SMOOTH_NEIGHBORS(src) power_change() +/obj/machinery/computer/Destroy() + QUEUE_SMOOTH_NEIGHBORS(src) + return ..() + /obj/machinery/computer/process() if(machine_stat & (NOPOWER|BROKEN)) return 0 @@ -41,6 +50,9 @@ icon_keyboard = "ratvar_key[rand(1, 2)]" icon_state = "ratvarcomputer" broken_overlay_emissive = TRUE + smoothing_groups = null + QUEUE_SMOOTH_NEIGHBORS(src) + smoothing_flags = NONE update_appearance() /obj/machinery/computer/narsie_act() @@ -48,8 +60,15 @@ clockwork = FALSE icon_screen = initial(icon_screen) icon_keyboard = initial(icon_keyboard) - icon_state = initial(icon_state) broken_overlay_emissive = initial(broken_overlay_emissive) + smoothing_flags = initial(smoothing_flags) + smoothing_groups = list(SMOOTH_GROUP_COMPUTERS) + canSmoothWith = list(SMOOTH_GROUP_COMPUTERS) + SET_BITFLAG_LIST(smoothing_groups) + SET_BITFLAG_LIST(canSmoothWith) + QUEUE_SMOOTH(src) + if(smoothing_flags) + QUEUE_SMOOTH_NEIGHBORS(src) update_appearance() /obj/machinery/computer/update_overlays() @@ -125,6 +144,7 @@ var/obj/structure/frame/computer/A = new /obj/structure/frame/computer(src.loc) A.setDir(dir) A.circuit = circuit + // Circuit removal code is handled in /obj/machinery/Exited() circuit.forceMove(A) A.setAnchored(TRUE) if(machine_stat & BROKEN) @@ -141,7 +161,6 @@ to_chat(user, "You disconnect the monitor.") A.state = 4 A.icon_state = "4" - circuit = null for(var/obj/C in src) C.forceMove(loc) qdel(src) diff --git a/code/game/machinery/computer/apc_control.dm b/code/game/machinery/computer/apc_control.dm index eaee7d4e5d3f0..fee8f4cabb914 100644 --- a/code/game/machinery/computer/apc_control.dm +++ b/code/game/machinery/computer/apc_control.dm @@ -151,7 +151,7 @@ return log_activity("changed greater than charge filter to \"[new_filter]\"") if(new_filter) - new_filter = CLAMP(new_filter, 0, 100) + new_filter = clamp(new_filter, 0, 100) playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) result_filters["Charge Above"] = new_filter if(href_list["below_filter"]) @@ -161,7 +161,7 @@ return log_activity("changed lesser than charge filter to \"[new_filter]\"") if(new_filter) - new_filter = CLAMP(new_filter, 0, 100) + new_filter = clamp(new_filter, 0, 100) playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) result_filters["Charge Below"] = new_filter if(href_list["access_filter"]) diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 15e29e7cc4546..d51c257609e22 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -71,11 +71,18 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( icon_state = "arcade" icon_keyboard = "no_keyboard" icon_screen = "invaders" + + //these muthafuckas arent supposed to smooth + base_icon_state = null + smoothing_flags = null + smoothing_groups = null + canSmoothWith = null + clockwork = TRUE //it'd look weird broken_overlay_emissive = TRUE + light_color = LIGHT_COLOR_GREEN var/list/prize_override var/prizeselect = /obj/item/coin/arcade_token - light_color = LIGHT_COLOR_GREEN /obj/machinery/computer/arcade/proc/Reset() return @@ -319,6 +326,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( temp = "You have been crushed! GAME OVER" playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff_exponent = 10) if(obj_flags & EMAGGED) + usr.investigate_log("has been gibbed by an emagged Orion Trail game.", INVESTIGATE_DEATHS) usr.gib() SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "hp", (obj_flags & EMAGGED ? "emagged":"normal"))) @@ -523,6 +531,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( if(obj_flags & EMAGGED) to_chat(user, "You're never going to make it to Orion...") + user.investigate_log("has been killed by an emagged Orion Trail game.", INVESTIGATE_DEATHS) user.death() obj_flags &= ~EMAGGED //removes the emagged status after you lose gameStatus = ORION_STATUS_START @@ -730,6 +739,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( if(settlers.len == 0 || alive == 0) say("The last crewmember [sheriff], shot themselves, GAME OVER!") if(obj_flags & EMAGGED) + usr.investigate_log("has been killed by an emagged Orion Trail game.", INVESTIGATE_DEATHS) usr.death(0) obj_flags &= EMAGGED gameStatus = ORION_STATUS_GAMEOVER @@ -742,6 +752,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( else if(obj_flags & EMAGGED) if(usr.name == sheriff) say("The crew of the ship chose to kill [usr.name]!") + usr.investigate_log("has been killed by an emagged Orion Trail game.", INVESTIGATE_DEATHS) usr.death(0) if(event == ORION_TRAIL_LING) //only ends the ORION_TRAIL_LING event, since you can do this action in multiple places diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm index 1b0feb1bc5e6a..98ca8c0d0d025 100644 --- a/code/game/machinery/computer/atmos_alert.dm +++ b/code/game/machinery/computer/atmos_alert.dm @@ -2,8 +2,6 @@ name = "atmospheric alert console" desc = "Used to monitor the station's air alarms." circuit = /obj/item/circuitboard/computer/atmos_alert - - icon_screen = "alert:0" icon_keyboard = "atmos_key" var/list/priority_alarms = list() diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index bf2627496eaea..9d968c7b3fefe 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -227,6 +227,13 @@ icon_state = "television" icon_keyboard = "no_keyboard" icon_screen = "detective_tv" + + //these muthafuckas arent supposed to smooth + base_icon_state = null + smoothing_flags = null + smoothing_groups = null + canSmoothWith = null + clockwork = TRUE //it'd look weird broken_overlay_emissive = TRUE pass_flags = PASSTABLE @@ -270,6 +277,13 @@ desc = "Used for watching an empty arena." icon = 'icons/obj/stationobjs.dmi' icon_state = "telescreen" + + //these muthafuckas arent supposed to smooth + base_icon_state = null + smoothing_flags = null + smoothing_groups = null + canSmoothWith = null + layer = SIGN_LAYER network = list("thunder") density = FALSE diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index 47ef94de0934b..37fc014ee75b4 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -16,7 +16,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) name = "identification console" desc = "You can use this to manage jobs and ID access." icon_screen = "id" - icon_keyboard = "id_key" + icon_keyboard = "generic_key" req_one_access = list(ACCESS_HEADS, ACCESS_CHANGE_IDS) circuit = /obj/item/circuitboard/computer/card var/mode = 0 diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm index 6bee8ce4c83f5..17334db4e8ded 100644 --- a/code/game/machinery/computer/dna_console.dm +++ b/code/game/machinery/computer/dna_console.dm @@ -23,6 +23,27 @@ /// Flag for the mutation ref search system. Search will include advanced injector mutations #define SEARCH_ADV_INJ 8 +/// Boilerplate define for whenever a cooldown is upgraded. +/// This will recalculate the current timeout if the given cooldown is currently active. +#define CALCULATE_UPGRADED_TIMEOUT(cd_index, to_index, new_length) \ + do { \ + var/_L = FLOOR(##new_length, 5 SECONDS); \ + var/_CT = src.to_index##_timeout; \ + if(!isnum_safe(_CT) || _CT <= 0) { \ + src.cd_index##_cooldown = 0; \ + src.to_index##_timeout = _L; \ + break; \ + } else if(_L >= _CT) { \ + break; \ + } \ + src.to_index##_timeout = _L; \ + var/_CD = src.cd_index##_cooldown; \ + if(!isnum_safe(_CD) || world.time >= _CD) { \ + break; \ + } \ + src.cd_index##_cooldown = FLOOR(_L * FLOOR((_CD - world.time) / _CT, 0.05), 1 SECONDS); \ + } while(0) + /obj/machinery/computer/scan_consolenew name = "\improper DNA scanner access console" @@ -60,9 +81,28 @@ ///the max instability of the advanced injector. var/max_injector_instability = 40 - var/injectorready = 0 //world timer cooldown var - var/jokerready = 0 - var/scrambleready = 0 + /// Cooldown for dispensing injectors. + COOLDOWN_DECLARE(injector_cooldown) + /// Cooldown for scrambling DNA. + COOLDOWN_DECLARE(scramble_cooldown) + /// Cooldown for using the joker thingy. + COOLDOWN_DECLARE(joker_cooldown) + /// The timeout for dispensing DNA activators. + var/activator_timeout = INJECTOR_TIMEOUT + /// The timeout for dispensing DNA mutators. + var/mutator_timeout = INJECTOR_TIMEOUT * 5 + /// The timeout for dispensing DNA nullifiers. + var/nullifier_timeout = INJECTOR_TIMEOUT * 3 + /// The timeout for dispensing advanced DNA injectors. + var/advanced_timeout = INJECTOR_TIMEOUT * 8 + /// The timeout for activating a gene on someone actually in the scanner. + var/activate_timeout = INJECTOR_TIMEOUT * 0.1 + /// The timeout for mutating a gene on someone actually in the scanner. + var/mutate_timeout = INJECTOR_TIMEOUT * 0.5 + /// The timeout for scrambling DNA. + var/scramble_timeout = SCRAMBLE_TIMEOUT + /// The timeout for joker. + var/joker_timeout = JOKER_TIMEOUT var/current_screen = "mainmenu" var/current_mutation //what block are we inspecting? only used when screen = "info" var/current_storage //what storage block are we looking at? @@ -73,7 +113,7 @@ /// Index of the enzyme being modified during delayed enzyme pulse operations var/rad_pulse_index = 0 /// World time when the enzyme pulse should complete - var/rad_pulse_timer = 0 + COOLDOWN_DECLARE(rad_pulse_timer) /// Used for setting tgui data - Whether the connected DNA Scanner is usable var/can_use_scanner = FALSE @@ -124,20 +164,14 @@ // This is for pulsing the UI element with radiation as part of genetic makeup // If rad_pulse_index > 0 then it means we're attempting a rad pulse - if((rad_pulse_index > 0) && (rad_pulse_timer <= world.time)) + if((rad_pulse_index > 0) && !COOLDOWN_FINISHED(src, rad_pulse_timer)) rad_pulse() return /obj/machinery/computer/scan_consolenew/attackby(obj/item/I, mob/user, params) - if (istype(I, /obj/item/disk/data)) //INSERT SOME DISKETTES - if (!src.diskette) - if (!user.transferItemToLoc(I,src)) - return - src.diskette = I - to_chat(user, "You insert [I].") - src.updateUsrDialog() - return - if (istype(I, /obj/item/chromosome)) + if(insert_disk(user, I)) //INSERT SOME DISKETTES + return + if(istype(I, /obj/item/chromosome)) if(LAZYLEN(stored_chromosomes) < max_chromosomes) I.forceMove(src) stored_chromosomes += I @@ -148,14 +182,14 @@ if(istype(I, /obj/item/dnainjector/activator)) var/obj/item/dnainjector/activator/A = I if(A.used) - to_chat(user,"Recycled [I].") + to_chat(user, "Recycled [I].") if(A.filled) var/c_typepath = generate_chromosome() var/obj/item/chromosome/CM = new c_typepath (drop_location()) if(LAZYLEN(stored_chromosomes) < max_chromosomes) CM.forceMove(src) stored_chromosomes += CM - to_chat(user,"[capitalize(CM.name)] added to storage.") + to_chat(user, "[capitalize(CM.name)] added to storage.") qdel(I) return @@ -172,9 +206,21 @@ // Make sure the user can interact with the machine. if(!user.canUseTopic(src, !issilicon(user))) return - eject_disk(user) +/obj/machinery/computer/scan_consolenew/proc/calculate_timeouts() + if(!scanner_operational()) + return + var/precision = max(1, connected_scanner.precision_coeff) + var/precise_injector_timeout = INJECTOR_TIMEOUT * (1 - 0.1 * precision) + CALCULATE_UPGRADED_TIMEOUT(injector, mutator, precise_injector_timeout * 5) + CALCULATE_UPGRADED_TIMEOUT(injector, activator, precise_injector_timeout) + CALCULATE_UPGRADED_TIMEOUT(injector, nullifier, precise_injector_timeout * 3) + CALCULATE_UPGRADED_TIMEOUT(injector, advanced, precise_injector_timeout * 8) + CALCULATE_UPGRADED_TIMEOUT(injector, activate, precise_injector_timeout * 0.1) + CALCULATE_UPGRADED_TIMEOUT(injector, mutate, precise_injector_timeout * 0.5) + CALCULATE_UPGRADED_TIMEOUT(joker, joker, JOKER_TIMEOUT - (JOKER_UPGRADE * (precision - 1))) + /obj/machinery/computer/scan_consolenew/proc/connect_to_scanner() var/obj/machinery/dna_scannernew/test_scanner = null var/obj/machinery/dna_scannernew/broken_scanner = null @@ -189,8 +235,7 @@ if(test_scanner.is_operational) connect_scanner(test_scanner) return - else - broken_scanner = test_scanner + broken_scanner = test_scanner // Ultimately, if we have a broken scanner, we'll attempt to connect to it as // a fallback case, but the code above will prefer a working scanner @@ -207,6 +252,7 @@ RegisterSignal(scanner, COMSIG_MACHINE_CLOSE, PROC_REF(on_scanner_close)) connected_scanner = scanner + calculate_timeouts() /obj/machinery/computer/scan_consolenew/Initialize(mapload) . = ..() @@ -216,9 +262,9 @@ // Set the default tgui state set_default_state() - injectorready = world.time + INJECTOR_TIMEOUT - scrambleready = world.time + SCRAMBLE_TIMEOUT - jokerready = world.time + JOKER_TIMEOUT + COOLDOWN_START(src, injector_cooldown, INJECTOR_TIMEOUT) + COOLDOWN_START(src, scramble_cooldown, scramble_timeout) + COOLDOWN_START(src, joker_cooldown, joker_timeout) stored_research = SSresearch.science_tech @@ -250,17 +296,17 @@ build_genetic_makeup_list() // Populate variables for passing to tgui interface - is_scramble_ready = (scrambleready < world.time) - time_to_scramble = round((scrambleready - world.time)/10) + is_scramble_ready = COOLDOWN_FINISHED(src, scramble_cooldown) + time_to_scramble = round(COOLDOWN_TIMELEFT(src, scramble_cooldown) / 10) - is_joker_ready = (jokerready < world.time) - time_to_joker = round((jokerready - world.time)/10) + is_injector_ready = COOLDOWN_FINISHED(src, injector_cooldown) + time_to_injector = round(COOLDOWN_TIMELEFT(src, injector_cooldown) / 10) - is_injector_ready = (injectorready < world.time) - time_to_injector = round((injectorready - world.time)/10) + is_joker_ready = COOLDOWN_FINISHED(src, joker_cooldown) + time_to_joker = round(COOLDOWN_TIMELEFT(src, joker_cooldown) / 10) - is_pulsing_rads = ((rad_pulse_index > 0) && (rad_pulse_timer > world.time)) - time_to_pulse = round((rad_pulse_timer - world.time)/10) + is_pulsing_rads = ((rad_pulse_index > 0) && !COOLDOWN_FINISHED(src, rad_pulse_timer)) + time_to_pulse = round(COOLDOWN_TIMELEFT(src, rad_pulse_timer) / 10) // Attempt to update tgui ui, open and update if needed. ui = SStgui.try_update_ui(user, src, ui) @@ -271,10 +317,10 @@ /obj/machinery/computer/scan_consolenew/examine(mob/user) . = ..() - if(jokerready < world.time) + if(COOLDOWN_FINISHED(src, joker_cooldown)) . += "JOKER algorithm available." else - . += "JOKER algorithm available in about [round(0.00166666667 * (jokerready - world.time))] minutes." + . += "JOKER algorithm available in around [DisplayTimeText(round(COOLDOWN_TIMELEFT(src, joker_cooldown), 15 SECONDS))]." /obj/machinery/computer/scan_consolenew/ui_assets() . = ..() || list() @@ -413,14 +459,14 @@ // GUARD CHECK - Can we genetically modify the occupant? Includes scanner // operational guard checks. // GUARD CHECK - Is scramble DNA actually ready? - if(!can_modify_occupant() || !(scrambleready < world.time)) + if(!can_modify_occupant() || !COOLDOWN_FINISHED(src, scramble_cooldown)) return scanner_occupant.dna.remove_all_mutations(list(MUT_NORMAL, MUT_EXTRA)) scanner_occupant.dna.generate_dna_blocks() - scrambleready = world.time + SCRAMBLE_TIMEOUT - to_chat(usr,"DNA scrambled.") - scanner_occupant.radiation += RADIATION_STRENGTH_MULTIPLIER*50/(connected_scanner.damage_coeff ** 2) + COOLDOWN_START(src, scramble_cooldown, SCRAMBLE_TIMEOUT) + to_chat(usr, "DNA scrambled.") + scanner_occupant.radiation += RADIATION_STRENGTH_MULTIPLIER * 50 / (connected_scanner.damage_coeff ** 2) return // Check whether a specific mutation is eligible for discovery within the @@ -493,7 +539,7 @@ // GUARD CHECK - Is the occupant currently undergoing some form of // transformation? If so, we don't want to be pulsing genes. if(scanner_occupant.transformation_timer) - to_chat(usr,"Gene pulse failed: The scanner occupant undergoing a transformation.") + to_chat(usr, "Gene pulse failed: The scanner occupant undergoing a transformation.") return // Resolve mutation's BYOND path from the alias @@ -515,10 +561,10 @@ // If the new gene is J, this means we're dealing with a JOKER // GUARD CHECK - Is JOKER actually ready? - if((newgene == "J") && (jokerready < world.time)) + if((newgene == "J") && COOLDOWN_FINISHED(src, joker_cooldown)) var/truegenes = GET_SEQUENCE(path) newgene = truegenes[genepos] - jokerready = world.time + JOKER_TIMEOUT - (JOKER_UPGRADE * (connected_scanner.precision_coeff-1)) + COOLDOWN_START(src, joker_cooldown, joker_timeout) // If the gene is an X, we want to update the default genes with the new // X to allow highlighting logic to work on the tgui interface. @@ -531,7 +577,7 @@ // we've increased the occupant rads sequence = copytext_char(sequence, 1, genepos) + newgene + copytext_char(sequence, genepos + 1) scanner_occupant.dna.mutation_index[path] = sequence - scanner_occupant.radiation += RADIATION_STRENGTH_MULTIPLIER/connected_scanner.damage_coeff + scanner_occupant.radiation += RADIATION_STRENGTH_MULTIPLIER / connected_scanner.damage_coeff scanner_occupant.domutcheck() // GUARD CHECK - Modifying genetics can lead to edge cases where the @@ -605,7 +651,7 @@ // identify mutations from big ol' lists // GUARD CHECK - Is the injector actually ready? - if(world.time < injectorready) + if(!COOLDOWN_FINISHED(src, injector_cooldown)) return var/search_flags = 0 @@ -643,9 +689,9 @@ // printing nullifiers a lot wouldn't be good, so it has some cooldown if(scanner_operational()) I.damage_coeff = connected_scanner.damage_coeff - injectorready = world.time + INJECTOR_TIMEOUT * 3 * (1 - 0.1 * connected_scanner.precision_coeff) + COOLDOWN_START(src, injector_cooldown, nullifier_timeout) else - injectorready = world.time + INJECTOR_TIMEOUT * 3 + COOLDOWN_START(src, injector_cooldown, initial(nullifier_timeout)) return @@ -663,10 +709,10 @@ // If there's an operational connected scanner, we can use its upgrades // to improve our injector's radiation generation if(scanner_operational()) - I.damage_coeff = connected_scanner.damage_coeff*4 - injectorready = world.time + INJECTOR_TIMEOUT * (1 - 0.1 * connected_scanner.precision_coeff) + I.damage_coeff = connected_scanner.damage_coeff * 4 + COOLDOWN_START(src, injector_cooldown, activator_timeout) else - injectorready = world.time + INJECTOR_TIMEOUT + COOLDOWN_START(src, injector_cooldown, initial(activator_timeout)) else I.name = "DNA mutator" I.desc = "Adds the current mutation on injection, at the cost of genetic stability." @@ -675,9 +721,9 @@ // to improve our injector's radiation generation if(scanner_operational()) I.damage_coeff = connected_scanner.damage_coeff - injectorready = world.time + INJECTOR_TIMEOUT * 5 * (1 - 0.1 * connected_scanner.precision_coeff) + COOLDOWN_START(src, injector_cooldown, mutator_timeout) else - injectorready = world.time + INJECTOR_TIMEOUT * 5 + COOLDOWN_START(src, injector_cooldown, initial(mutator_timeout)) return @@ -695,11 +741,7 @@ scanner_occupant.dna.activate_mutation(HM) log_game("[key_name(usr)] activated [HM] in [key_name(scanner_occupant)] [loc_name(usr)]") - - if(scanner_operational()) - injectorready = world.time + INJECTOR_TIMEOUT * 0.1 * (1 - 0.1 * connected_scanner.precision_coeff) - else - injectorready = world.time + INJECTOR_TIMEOUT * 0.1 + COOLDOWN_START(src, injector_cooldown, scanner_operational() ? activate_timeout : initial(activate_timeout)) if(scanner_occupant?.client) var/c_typepath = generate_chromosome() @@ -707,7 +749,7 @@ if(LAZYLEN(stored_chromosomes) < max_chromosomes) CM.forceMove(src) stored_chromosomes += CM - to_chat(usr,"[capitalize(CM.name)] added to storage.") + to_chat(usr, "[capitalize(CM.name)] added to storage.") //Creates a new MUT_EXTRA mutation in subject if("add_mutation") @@ -732,10 +774,7 @@ else scanner_occupant.dna.add_mutation(HM, MUT_EXTRA) - if(scanner_operational()) - injectorready = world.time + INJECTOR_TIMEOUT * 0.5 * (1 - 0.1 * connected_scanner.precision_coeff) - else - injectorready = world.time + INJECTOR_TIMEOUT * 0.5 + COOLDOWN_START(src, injector_cooldown, scanner_operational() ? mutate_timeout : initial(mutate_timeout)) log_game("[key_name(usr)] added [HM] to [key_name(scanner_occupant)] [loc_name(usr)]") @@ -762,7 +801,7 @@ // GUARD CHECK - Is mutation storage full? if(LAZYLEN(stored_mutations) >= max_storage) - to_chat(usr,"Mutation storage is full.") + to_chat(usr, "Mutation storage is full.") return var/bref = params["mutref"] @@ -775,7 +814,7 @@ var/datum/mutation/A = new HM.type() A.copy_mutation(HM) stored_mutations += A - to_chat(usr,"Mutation successfully stored.") + to_chat(usr, "Mutation successfully stored.") return // Save a mutation to the diskette's storage buffer. @@ -793,13 +832,13 @@ // GUARD CHECK - Make sure the disk is not full if(LAZYLEN(diskette.mutations) >= diskette.max_mutations) - to_chat(usr,"Disk storage is full.") + to_chat(usr, "Disk storage is full.") return // GUARD CHECK - Make sure the disk isn't set to read only, as we're // attempting to write to it if(diskette.read_only) - to_chat(usr,"Disk is set to read only mode.") + to_chat(usr, "Disk is set to read only mode.") return var/search_flags = 0 @@ -825,7 +864,7 @@ var/datum/mutation/A = new HM.type() A.copy_mutation(HM) diskette.mutations += A - to_chat(usr,"Mutation successfully stored to disk.") + to_chat(usr, "Mutation successfully stored to disk.") return // Completely removes a MUT_EXTRA mutation or mutation with corrupt gene @@ -847,7 +886,7 @@ // GUARD CHECK - Nullify should only be used on scrambled or "extra" // mutations. - if(!HM.scrambled && !(HM.class == MUT_EXTRA)) + if(!HM.scrambled && HM.class != MUT_EXTRA) return scanner_occupant.dna.remove_mutation(HM.type) @@ -878,7 +917,7 @@ // GUARD CHECK - Make sure the disk isn't set to read only, as we're // attempting to write to it (via deletion) if(diskette.read_only) - to_chat(usr,"Disk is set to read only mode.") + to_chat(usr, "Disk is set to read only mode.") return var/bref = params["mutref"] @@ -914,7 +953,7 @@ // GUaRD CHECK - Make sure mutation storage isn't full. If it is, we won't // be able to store the new combo mutation if(LAZYLEN(stored_mutations) >= max_storage) - to_chat(usr,"Mutation storage is full.") + to_chat(usr, "Mutation storage is full.") return // GUARD CHECK - We're running a research-type operation. If, for some @@ -970,13 +1009,13 @@ // GUARD CHECK - Make sure the disk is not full. if(LAZYLEN(diskette.mutations) >= diskette.max_mutations) - to_chat(usr,"Disk storage is full.") + to_chat(usr, "Disk storage is full.") return // GUARD CHECK - Make sure the disk isn't set to read only, as we're // attempting to write to it if(diskette.read_only) - to_chat(usr,"Disk is set to read only mode.") + to_chat(usr, "Disk is set to read only mode.") return // GUARD CHECK - We're running a research-type operation. If, for some @@ -1050,7 +1089,7 @@ // GUARD CHECK - Make sure the disk isn't set to read only, as we're // attempting to write to it if(diskette.read_only) - to_chat(usr,"Disk is set to read only mode.") + to_chat(usr, "Disk is set to read only mode.") return // Convert the index to a number and clamp within the array range @@ -1099,7 +1138,7 @@ // GUARD CHECK - Make sure the disk isn't set to read only, as we're // attempting to write (via deletion) to it if(diskette.read_only) - to_chat(usr,"Disk is set to read only mode.") + to_chat(usr, "Disk is set to read only mode.") return diskette.genetic_makeup_buffer.Cut() @@ -1123,11 +1162,12 @@ // Set the new information genetic_makeup_buffer[buffer_index] = list( - "label"="Slot [buffer_index]:[scanner_occupant.real_name]", - "UI"=scanner_occupant.dna.uni_identity, - "UE"=scanner_occupant.dna.unique_enzymes, - "name"=scanner_occupant.real_name, - "blood_type"=scanner_occupant.dna.blood_type) + "name" = scanner_occupant.real_name, + "label" = "Slot [buffer_index]:[scanner_occupant.real_name]", + "UI" = scanner_occupant.dna.uni_identity, + "UE" = scanner_occupant.dna.unique_enzymes, + "blood_type" = scanner_occupant.dna.blood_type + ) return @@ -1188,11 +1228,11 @@ // However, if this is the case, we can't make a complete injector and // this catches that edge case if(!buffer_slot["UI"]) - to_chat(usr,"Genetic data corrupted, unable to create injector.") + to_chat(usr, "Genetic data corrupted, unable to create injector.") return I = new /obj/item/dnainjector/timed(loc) - I.fields = list("UI"=buffer_slot["UI"]) + I.fields = list("UI" = buffer_slot["UI"]) // If there is a connected scanner, we can use its upgrades to reduce // the radiation generated by this injector @@ -1203,11 +1243,15 @@ // However, if this is the case, we can't make a complete injector and // this catches that edge case if(!buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["blood_type"]) - to_chat(usr,"Genetic data corrupted, unable to create injector.") + to_chat(usr, "Genetic data corrupted, unable to create injector.") return I = new /obj/item/dnainjector/timed(loc) - I.fields = list("name"=buffer_slot["name"], "UE"=buffer_slot["UE"], "blood_type"=buffer_slot["blood_type"]) + I.fields = list( + "name" = buffer_slot["name"], + "UE" = buffer_slot["UE"], + "blood_type" = buffer_slot["blood_type"] + ) // If there is a connected scanner, we can use its upgrades to reduce // the radiation generated by this injector @@ -1218,11 +1262,16 @@ // However, if this is the case, we can't make a complete injector and // this catches that edge case if(!buffer_slot["UI"] || !buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["blood_type"]) - to_chat(usr,"Genetic data corrupted, unable to create injector.") + to_chat(usr, "Genetic data corrupted, unable to create injector.") return I = new /obj/item/dnainjector/timed(loc) - I.fields = list("UI"=buffer_slot["UI"],"name"=buffer_slot["name"], "UE"=buffer_slot["UE"], "blood_type"=buffer_slot["blood_type"]) + I.fields = list( + "name" = buffer_slot["name"], + "UI" = buffer_slot["UI"], + "UE" = buffer_slot["UE"], + "blood_type" = buffer_slot["blood_type"] + ) // If there is a connected scanner, we can use its upgrades to reduce // the radiation generated by this injector @@ -1232,7 +1281,7 @@ // If we successfully created an injector, don't forget to set the new // ready timer. if(I) - injectorready = world.time + INJECTOR_TIMEOUT + COOLDOWN_START(src, injector_cooldown, mutator_timeout) return @@ -1316,8 +1365,8 @@ // Set the appropriate timer and index to pulse. This is then managed // later on in process() var/len = length_char(scanner_occupant.dna.uni_identity) - rad_pulse_timer = world.time + (radduration*10) - rad_pulse_index = WRAP(text2num(params["index"]), 1, len+1) + COOLDOWN_START(src, rad_pulse_timer, radduration * 10) + rad_pulse_index = WRAP(text2num(params["index"]), 1, len + 1) START_PROCESSING(SSobj, src) return @@ -1377,7 +1426,7 @@ // identify mutations from big ol' lists. // GUARD CHECK - Is the injector actually ready? - if(world.time < injectorready) + if(!COOLDOWN_FINISHED(src, injector_cooldown)) return var/inj_name = params["name"] @@ -1405,9 +1454,9 @@ // to improve our injector's radiation generation if(scanner_operational()) I.damage_coeff = connected_scanner.damage_coeff - injectorready = world.time + INJECTOR_TIMEOUT * 8 * (1 - 0.1 * connected_scanner.precision_coeff) + COOLDOWN_START(src, injector_cooldown, advanced_timeout) else - injectorready = world.time + INJECTOR_TIMEOUT * 8 + COOLDOWN_START(src, injector_cooldown, initial(advanced_timeout)) return @@ -1432,7 +1481,7 @@ // GUARD CHECK - Make sure we limit the number of mutations appropriately if(LAZYLEN(injector_selection[adv_inj]) >= max_injector_mutations) - to_chat(usr,"Advanced injector mutation storage is full.") + to_chat(usr, "Advanced injector mutation storage is full.") return var/mut_source = params["source"] @@ -1469,7 +1518,7 @@ // If this would take us over the max instability, we inform the user. if(instability_total > max_injector_instability) - to_chat(usr,"Extra mutation would make the advanced injector too instable.") + to_chat(usr, "Extra mutation would make the advanced injector too instable.") return // If we've got here, all our checks are passed and we can successfully @@ -1477,7 +1526,7 @@ var/datum/mutation/A = new HM.type() A.copy_mutation(HM) injector_selection[adv_inj] += A - to_chat(usr,"Mutation successfully added to advanced injector.") + to_chat(usr, "Mutation successfully added to advanced injector.") return // Deletes a mutation from an advanced injector @@ -1530,7 +1579,7 @@ // Pre-calc the rad increase since we'll be using it in all the possible // operations - var/rad_increase = rand(100/(connected_scanner.damage_coeff ** 2),250/(connected_scanner.damage_coeff ** 2)) + var/rad_increase = rand(100 / (connected_scanner.damage_coeff ** 2), 250 / (connected_scanner.damage_coeff ** 2)) switch(type) if("ui") @@ -1538,10 +1587,10 @@ // However, if this is the case, we can't make a complete injector and // this catches that edge case if(!buffer_slot["UI"]) - to_chat(usr,"Genetic data corrupted, unable to apply genetic data.") + to_chat(usr, "Genetic data corrupted, unable to apply genetic data.") return FALSE scanner_occupant.dna.uni_identity = buffer_slot["UI"] - scanner_occupant.updateappearance(mutations_overlay_update=1) + scanner_occupant.updateappearance(mutations_overlay_update = 1) scanner_occupant.radiation += rad_increase scanner_occupant.domutcheck() return TRUE @@ -1550,7 +1599,7 @@ // However, if this is the case, we can't make a complete injector and // this catches that edge case if(!buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["blood_type"]) - to_chat(usr,"Genetic data corrupted, unable to apply genetic data.") + to_chat(usr, "Genetic data corrupted, unable to apply genetic data.") return FALSE scanner_occupant.real_name = buffer_slot["name"] scanner_occupant.name = buffer_slot["name"] @@ -1564,10 +1613,10 @@ // However, if this is the case, we can't make a complete injector and // this catches that edge case if(!buffer_slot["UI"] || !buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["blood_type"]) - to_chat(usr,"Genetic data corrupted, unable to apply genetic data.") + to_chat(usr, "Genetic data corrupted, unable to apply genetic data.") return FALSE scanner_occupant.dna.uni_identity = buffer_slot["UI"] - scanner_occupant.updateappearance(mutations_overlay_update=1) + scanner_occupant.updateappearance(mutations_overlay_update = 1) scanner_occupant.real_name = buffer_slot["name"] scanner_occupant.name = buffer_slot["name"] scanner_occupant.dna.unique_enzymes = buffer_slot["UE"] @@ -1582,10 +1631,7 @@ * Checks if there is a connected DNA Scanner that is operational */ /obj/machinery/computer/scan_consolenew/proc/scanner_operational() - if(!connected_scanner) - return FALSE - - return (connected_scanner && connected_scanner.is_operational && !connected_scanner.wires.is_cut(WIRE_LIMIT)) + return !QDELETED(connected_scanner) && connected_scanner.is_operational && !connected_scanner.wires?.is_cut(WIRE_LIMIT) /** * Checks if there is a valid DNA Scanner occupant for genetic modification @@ -1654,7 +1700,7 @@ // If we had a radiation pulse action ongoing, we want to stop this. // Imagine it being like a microwave stopping when you open the door. rad_pulse_index = 0 - rad_pulse_timer = 0 + COOLDOWN_RESET(src, rad_pulse_timer) STOP_PROCESSING(SSobj, src) scanner_occupant = null @@ -2000,7 +2046,7 @@ */ /obj/machinery/computer/scan_consolenew/proc/randomize_radiation_accuracy(position, radduration, number_of_blocks) var/val = round(gaussian(0, RADIATION_ACCURACY_MULTIPLIER/radduration) + position, 1) - return WRAP(val, 1, number_of_blocks+1) + return WRAP(val, 1, number_of_blocks + 1) /** * Scrambles an enzyme element value for the enzyme pulse functionality. @@ -2013,14 +2059,15 @@ */ /obj/machinery/computer/scan_consolenew/proc/scramble(input,rs) var/length = length(input) - var/ran = gaussian(0, rs*RADIATION_STRENGTH_MULTIPLIER) - if(ran == 0) - ran = pick(-1,1) //hacky, statistically should almost never happen. 0-chance makes people mad though - else if(ran < 0) - ran = round(ran) //negative, so floor it - else - ran = -round(-ran) //positive, so ceiling it - return num2hex(WRAP(hex2num(input)+ran, 0, 16**length), length) + var/ran = gaussian(0, rs * RADIATION_STRENGTH_MULTIPLIER) + switch(ran) + if(0) + ran = pick(-1, 1) //hacky, statistically should almost never happen. 0-chance makes people mad though + if(-INFINITY to 0) + ran = round(ran) //negative, so floor it + else + ran = -round(-ran) //positive, so ceiling it + return num2hex(WRAP(hex2num(input) + ran, 0, 16 ** length), length) /** * Performs the enzyme radiation pulse. @@ -2039,11 +2086,11 @@ var/len = length_char(scanner_occupant.dna.uni_identity) var/num = randomize_radiation_accuracy(rad_pulse_index, radduration + (connected_scanner.precision_coeff ** 2), len) //Each manipulator level above 1 makes randomization as accurate as selected time + manipulator lvl^2 //Value is this high for the same reason as with laser - not worth the hassle of upgrading if the bonus is low - var/hex = copytext_char(scanner_occupant.dna.uni_identity, num, num+1) + var/hex = copytext_char(scanner_occupant.dna.uni_identity, num, num + 1) hex = scramble(hex, radstrength, radduration) scanner_occupant.dna.uni_identity = copytext_char(scanner_occupant.dna.uni_identity, 1, num) + hex + copytext_char(scanner_occupant.dna.uni_identity, num + 1) - scanner_occupant.updateappearance(mutations_overlay_update=1) + scanner_occupant.updateappearance(mutations_overlay_update = 1) rad_pulse_index = 0 STOP_PROCESSING(SSobj, src) @@ -2058,6 +2105,24 @@ tgui_view_state["storageConsSubMode"] = "mutations" tgui_view_state["storageDiskSubMode"] = "mutations" +/obj/machinery/computer/scan_consolenew/proc/insert_disk(mob/living/user, obj/item/disk/data/diskie) + if(!QDELETED(diskette) || !istype(user) || !istype(diskie) || !user.transferItemToLoc(diskie, src)) + return FALSE + diskette = diskie + to_chat(user, "You insert [diskie].") + if(stored_research) + var/list/upload_names + for(var/datum/mutation/upload in diskie.mutations) + var/path = upload.type + if(stored_research.discovered_mutations[path]) + continue + stored_research.discovered_mutations[path] = TRUE + LAZYADD(upload_names, upload.name) + if(LAZYLEN(upload_names)) + say("Successfully uploaded [english_list(upload_names)] from disk.") + updateUsrDialog() + return TRUE + /** * Ejects the DNA Disk from the console. * @@ -2088,6 +2153,8 @@ to_chat(user, "You bypass [src]'s access requirements.") /////////////////////////// DNA MACHINES + +#undef CALCULATE_UPGRADED_TIMEOUT #undef INJECTOR_TIMEOUT #undef NUMBER_OF_BUFFERS #undef SCRAMBLE_TIMEOUT diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 3ab882a2eda29..51308b21e7b83 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -604,6 +604,13 @@ icon_state = "laptop" icon_screen = "medlaptop" icon_keyboard = "laptop_key" + + //these muthafuckas arent supposed to smooth + base_icon_state = null + smoothing_flags = null + smoothing_groups = null + canSmoothWith = null + clockwork = TRUE //it'd look weird broken_overlay_emissive = TRUE pass_flags = PASSTABLE diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index 41a46cc5df31f..fc73d48a5caae 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -88,15 +88,15 @@ data["cyborgs"] += list(cyborg_data) data["drones"] = list() - for(var/mob/living/simple_animal/drone/D in GLOB.drones_list) - if(D.hacked) + for(var/mob/living/simple_animal/drone/drone in GLOB.drones_list) + if(drone.hacked) continue - if(get_virtual_z_level() != (get_turf(D)).get_virtual_z_level()) + if(get_virtual_z_level() != (get_turf(drone)).get_virtual_z_level()) continue var/list/drone_data = list( - name = D.name, - status = D.stat, - ref = REF(D) + name = drone.name, + status = drone.stat, + ref = REF(drone) ) data["drones"] += list(drone_data) @@ -168,6 +168,7 @@ s.set_up(3, TRUE, D) s.start() D.visible_message("\the [D] self-destructs!") + D.investigate_log("has been gibbed by a robotics console.", INVESTIGATE_DEATHS) D.gib() if("extract") if(!GLOB.upload_code) diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index ff114675818b8..0393a4813d9d2 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -180,6 +180,13 @@ icon_state = "laptop" icon_screen = "seclaptop" icon_keyboard = "laptop_key" + + //these muthafuckas arent supposed to smooth + base_icon_state = null + smoothing_flags = null + smoothing_groups = null + canSmoothWith = null + clockwork = TRUE //it'd look weird broken_overlay_emissive = TRUE pass_flags = PASSTABLE @@ -583,7 +590,7 @@ What a mess.*/ default_description += "[c.crimeDetails]\n" var/headerText = stripped_input(usr, "Please enter Poster Heading (Max 7 Chars):", "Print Wanted Poster", "WANTED", 8) - var/posternum = CLAMP((input("Number of posters to print (Max 5):","Number:",1) as num|null), 1, 5) + var/posternum = clamp((input("Number of posters to print (Max 5):","Number:",1) as num|null), 1, 5) var/info = stripped_multiline_input(usr, "Please input a description for the poster:", "Print Wanted Poster", default_description, null) if(info) printing = 1 @@ -602,7 +609,7 @@ What a mess.*/ var/default_description = "A poster declaring [missing_name] to be a missing individual, missed by Nanotrasen. Report any sightings to security immediately." var/headerText = stripped_input(usr, "Please enter Poster Heading (Max 7 Chars):", "Print Missing Persons Poster", "MISSING", 8) - var/posternum = CLAMP((input("Number of posters to print (Max 5):","Number:",1) as num|null), 1, 5) + var/posternum = clamp((input("Number of posters to print (Max 5):","Number:",1) as num|null), 1, 5) var/info = stripped_multiline_input(usr, "Please input a description for the poster:", "Print Missing Persons Poster", default_description, null) if(info) printing = 1 diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm index 70abe70b40292..05bf4d60f341f 100644 --- a/code/game/machinery/computer/teleporter.dm +++ b/code/game/machinery/computer/teleporter.dm @@ -37,6 +37,7 @@ for(var/direction in GLOB.cardinals) power_station = locate(/obj/machinery/teleport/station, get_step(src, direction)) if(power_station) + power_station.link_console_and_hub() break ui_update() return power_station diff --git a/code/game/machinery/dna_scanner.dm b/code/game/machinery/dna_scanner.dm index 06670913cac59..f1931a655c929 100644 --- a/code/game/machinery/dna_scanner.dm +++ b/code/game/machinery/dna_scanner.dm @@ -35,6 +35,9 @@ precision_coeff = M.rating for(var/obj/item/stock_parts/micro_laser/P in component_parts) damage_coeff = P.rating + for(var/obj/machinery/computer/scan_consolenew/console in view(1)) + if(console.connected_scanner == src) + console.calculate_timeouts() /obj/machinery/dna_scannernew/examine(mob/user) . = ..() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 78f1e89468a66..9df5f25bcb8d8 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -383,7 +383,7 @@ update_icon() /obj/machinery/door/airlock/Bumped(atom/movable/AM) - if(operating || (obj_flags & EMAGGED)) + if(operating) return if(ismecha(AM)) var/obj/mecha/mecha = AM @@ -493,19 +493,20 @@ ui_update() update_icon() -/obj/machinery/door/airlock/proc/loseMainPower() - if(secondsMainPowerLost <= 0) +/obj/machinery/door/airlock/proc/loseMainPower(emagged_powerloss) + if(emagged_powerloss) + secondsMainPowerLost = 36000 //Ten hours, effectively indefinite - may be reset by power cycling the airlock with a multitool or wirecutters + secondsBackupPowerLost = 36000 + else secondsMainPowerLost = 60 - if(secondsBackupPowerLost < 10) - secondsBackupPowerLost = 10 + secondsBackupPowerLost = clamp(10, secondsBackupPowerLost, 60) if(!spawnPowerRestoreRunning) spawnPowerRestoreRunning = TRUE handlePowerRestoreLoop() update_icon() /obj/machinery/door/airlock/proc/loseBackupPower() - if(secondsBackupPowerLost < 60) - secondsBackupPowerLost = 60 + secondsBackupPowerLost = 60 if(!spawnPowerRestoreRunning) spawnPowerRestoreRunning = TRUE handlePowerRestoreLoop() @@ -710,8 +711,6 @@ /obj/machinery/door/airlock/examine(mob/user) . = ..() - if(obj_flags & EMAGGED) - . += "Its access panel is smoking slightly." if(charge && !panel_open && in_range(user, src)) . += "The maintenance panel seems haphazardly fastened." if(charge && panel_open) @@ -758,9 +757,6 @@ return else to_chat(user, "Airlock AI control has been blocked with a firewall. Unable to hack.") - if(obj_flags & EMAGGED) - to_chat(user, "Unable to interface: Airlock is unresponsive.") - return if(detonated) to_chat(user, "Unable to interface. Airlock control panel damaged.") return @@ -1047,8 +1043,6 @@ if(!panel_open || security_level) to_chat(user, "The maintenance panel must be open to apply [C]!") return - if(obj_flags & EMAGGED) - return if(charge && !detonated) to_chat(user, "There's already a charge hooked up to this door!") return @@ -1151,7 +1145,7 @@ charge.forceMove(get_turf(user)) charge = null return - if(!security_level && (beingcrowbarred && panel_open && ((obj_flags & EMAGGED) || (density && welded && !operating && !hasPower() && !locked)))) + if(!security_level && (beingcrowbarred && panel_open && (density && welded && !operating && !hasPower() && !locked))) user.visible_message("[user] removes the electronics from the airlock assembly.", \ "You start to remove electronics from the airlock assembly...") if(I.use_tool(src, user, 40, volume=100)) @@ -1170,7 +1164,7 @@ INVOKE_ASYNC(src, (density ? PROC_REF(open) : PROC_REF(close)), 2) -/obj/machinery/door/airlock/open(forced=0, ignore_emagged = FALSE) +/obj/machinery/door/airlock/open(forced=0) if( operating || welded || locked ) return FALSE if(!forced) @@ -1191,8 +1185,6 @@ H.apply_damage(40, BRUTE, BODY_ZONE_CHEST) return if(forced < 2) - if(!ignore_emagged && (obj_flags & EMAGGED)) - return FALSE if(!protected_door) use_power(50) playsound(src, doorOpen, 30, 1) @@ -1243,8 +1235,6 @@ return if(forced < 2) - if(obj_flags & EMAGGED) - return if(!protected_door) use_power(50) playsound(src, doorClose, 30, TRUE) @@ -1286,8 +1276,6 @@ return TRUE /obj/machinery/door/airlock/proc/prison_open() - if(obj_flags & EMAGGED) - return locked = FALSE open() locked = TRUE @@ -1329,9 +1317,8 @@ //Airlock is passable if it is open (!density), bot has access, and is not bolted shut or powered off) return !density || (check_access(ID) && !locked && hasPower()) +///This does not call parent because airlocks should be possible to emag multiple times. We only care that the door is closed, not protected and has power. /obj/machinery/door/airlock/should_emag(mob/user) - if(!..()) - return FALSE if(protected_door) to_chat(user, "[src] has no maintenance panel!") return FALSE @@ -1351,12 +1338,10 @@ if(QDELETED(src)) return operating = FALSE - if(!open(ignore_emagged = TRUE)) + if(!open()) update_icon(AIRLOCK_CLOSED, 1) - lights = FALSE - locked = TRUE - loseMainPower() - loseBackupPower() + bolt() + loseMainPower(TRUE) /obj/machinery/door/airlock/attack_alien(mob/living/carbon/alien/humanoid/user) add_fingerprint(user) @@ -1451,9 +1436,6 @@ if(!disassembled) if(A) A.obj_integrity = A.max_integrity * 0.5 - else if(obj_flags & EMAGGED) - if(user) - to_chat(user, "You discard the damaged electronics.") else if(user) to_chat(user, "You remove the airlock electronics.") diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index c3087a4e3e4c4..39af859b4576a 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -93,7 +93,7 @@ /obj/machinery/door/Bumped(atom/movable/AM) . = ..() - if(operating || (obj_flags & EMAGGED)) + if(operating) return if(ismob(AM)) var/mob/B = AM @@ -148,7 +148,7 @@ /// Helper method for bumpopen() and try_to_activate_door(). Don't override. /obj/machinery/door/proc/activate_door_base(mob/user, can_close_door) add_fingerprint(user) - if(operating || (obj_flags & EMAGGED)) + if(operating) return // Cutting WIRE_IDSCAN disables normal entry if(!id_scan_hacked() && allowed(user)) @@ -366,7 +366,7 @@ L.emote("roar") else if(ishuman(L)) //For humans var/armour = L.run_armor_check(BODY_ZONE_CHEST, MELEE) - var/multiplier = CLAMP(1 - (armour * 0.01), 0, 1) + var/multiplier = clamp(1 - (armour * 0.01), 0, 1) L.adjustBruteLoss(multiplier * DOOR_CRUSH_DAMAGE) L.emote("scream") if(!L.IsParalyzed()) diff --git a/code/game/machinery/fabricators/modular_fabricator.dm b/code/game/machinery/fabricators/modular_fabricator.dm index 8bab13aaf825c..12debf92aa0b0 100644 --- a/code/game/machinery/fabricators/modular_fabricator.dm +++ b/code/game/machinery/fabricators/modular_fabricator.dm @@ -399,7 +399,7 @@ //Only items that can stack should be build en mass, since we now have queues. if(is_stack) multiplier = item_queue[requested_design_id]["amount"] - multiplier = CLAMP(multiplier,1,50) + multiplier = clamp(multiplier,1,50) ///////////////// diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm index 5f53c27414d07..9a97a73531a14 100644 --- a/code/game/machinery/harvester.dm +++ b/code/game/machinery/harvester.dm @@ -4,6 +4,7 @@ density = TRUE icon = 'icons/obj/machines/harvester.dmi' icon_state = "harvester" + base_icon_state = "harvester" verb_say = "states" state_open = FALSE idle_power_usage = 50 @@ -11,6 +12,7 @@ light_color = LIGHT_COLOR_BLUE var/interval = 20 var/harvesting = FALSE + var/warming_up = FALSE var/list/operation_order = list() //Order of which we harvest limbs. var/allow_clothing = FALSE var/allow_living = FALSE @@ -27,21 +29,24 @@ max_time -= L.rating interval = max(max_time,1) -/obj/machinery/harvester/update_icon(warming_up) - if(warming_up) - icon_state = initial(icon_state)+"-charging" - return +/obj/machinery/harvester/update_icon_state() if(state_open) - icon_state = initial(icon_state)+"-open" - else if(harvesting) - icon_state = initial(icon_state)+"-active" - else - icon_state = initial(icon_state) + icon_state = "[base_icon_state]-open" + return ..() + if(warming_up) + icon_state = "[base_icon_state]-charging" + return ..() + if(harvesting) + icon_state = "[base_icon_state]-active" + return ..() + icon_state = base_icon_state + return ..() /obj/machinery/harvester/open_machine(drop = TRUE) if(panel_open) return . = ..() + warming_up = FALSE harvesting = FALSE /obj/machinery/harvester/attack_hand(mob/user) @@ -84,14 +89,16 @@ return var/mob/living/carbon/C = occupant operation_order = reverseList(C.bodyparts) //Chest and head are first in bodyparts, so we invert it to make them suffer more + warming_up = TRUE harvesting = TRUE visible_message("The [name] begins warming up!") say("Initializing harvest protocol.") - update_icon(TRUE) + update_appearance() addtimer(CALLBACK(src, PROC_REF(harvest)), interval) /obj/machinery/harvester/proc/harvest() - update_icon() + warming_up = FALSE + update_appearance() if(!harvesting || state_open || !powered() || !occupant || !iscarbon(occupant)) return playsound(src, 'sound/machines/juicer.ogg', 20, 1) @@ -125,6 +132,7 @@ addtimer(CALLBACK(src, PROC_REF(harvest)), interval) /obj/machinery/harvester/proc/end_harvesting() + warming_up = FALSE harvesting = FALSE open_machine() say("Subject has been successfully harvested.") diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index f040c0b14fddb..3ee853795d291 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -259,15 +259,18 @@ can_convert = FALSE /obj/machinery/iv_drip/saline/Initialize(mapload) - . = ..() - beaker = new /obj/item/reagent_containers/glass/saline(src) + . = ..() + beaker = new /obj/item/reagent_containers/glass/saline(src) -/obj/machinery/iv_drip/saline/update_icon() - return +/obj/machinery/iv_drip/saline/ComponentInitialize() + . = ..() + AddElement(/datum/element/update_icon_blocker) /obj/machinery/iv_drip/saline/eject_beaker() - return + return + /obj/machinery/iv_drip/saline/toggle_mode() return + #undef IV_TAKING #undef IV_INJECTING diff --git a/code/game/machinery/newscaster/newspaper.dm b/code/game/machinery/newscaster/newspaper.dm index 29da9452d0122..759aabbd55c2c 100644 --- a/code/game/machinery/newscaster/newspaper.dm +++ b/code/game/machinery/newscaster/newspaper.dm @@ -24,7 +24,7 @@ I am begging someone to remake this to be more like the paper UI, it's so bad. var/wantedPhoto var/creation_time -/obj/item/newspaper/suicide_act(mob/user) +/obj/item/newspaper/suicide_act(mob/living/user) user.visible_message("[user] is focusing intently on [src]! It looks like [user.p_theyre()] trying to commit sudoku... until [user.p_their()] eyes light up with realization!") user.say(";JOURNALISM IS MY CALLING! EVERYBODY APPRECIATES UNBIASED REPORTI-GLORF", forced="newspaper suicide") var/mob/living/carbon/human/H = user @@ -32,7 +32,6 @@ I am begging someone to remake this to be more like the paper UI, it's so bad. playsound(H.loc, 'sound/items/drink.ogg', rand(10,50), TRUE) W.reagents.trans_to(H, W.reagents.total_volume, transfered_by = user) user.visible_message("[user] downs the contents of [W.name] in one gulp! Shoulda stuck to sudoku!") - return TOXLOSS /obj/item/newspaper/attack_self(mob/user) diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 37caeb0d0bb21..66e32708181a7 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -176,7 +176,7 @@ Buildable meters ..() T.flipped = flipped -/obj/item/pipe/directional/suicide_act(mob/user) +/obj/item/pipe/directional/suicide_act(mob/living/user) user.visible_message("[user] shoves [src] in [user.p_their()] mouth and turns it on! It looks like [user.p_theyre()] trying to commit suicide!") if(iscarbon(user)) var/mob/living/carbon/C = user diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index b56efbce182ca..d14f2afab970c 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -55,9 +55,9 @@ new /obj/item/pipe_meter(loc) wait = world.time + 15 if(href_list["layer_up"]) - piping_layer = CLAMP(++piping_layer, PIPING_LAYER_MIN, PIPING_LAYER_MAX) + piping_layer = clamp(++piping_layer, PIPING_LAYER_MIN, PIPING_LAYER_MAX) if(href_list["layer_down"]) - piping_layer = CLAMP(--piping_layer, PIPING_LAYER_MIN, PIPING_LAYER_MAX) + piping_layer = clamp(--piping_layer, PIPING_LAYER_MIN, PIPING_LAYER_MAX) return /obj/machinery/pipedispenser/attackby(obj/item/W, mob/user, params) diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index 93cb744a7e5ef..020917a6f0ffd 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -688,7 +688,7 @@ DEFINE_BUFFER_HANDLER(/obj/machinery/porta_turret) /obj/machinery/porta_turret/syndicate/ComponentInitialize() . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) + AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) /obj/machinery/porta_turret/syndicate/setup() return @@ -805,7 +805,7 @@ DEFINE_BUFFER_HANDLER(/obj/machinery/porta_turret) /obj/machinery/porta_turret/centcom_shuttle/ComponentInitialize() . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) + AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) /obj/machinery/porta_turret/centcom_shuttle/assess_perp(mob/living/carbon/human/perp) return 0 diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index f21c26c7a695a..b4822b0f07940 100755 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -50,11 +50,12 @@ START_PROCESSING(SSmachines, src) update_use_power(ACTIVE_POWER_USE) //finished_recharging = TRUE - update_icon(scan = TRUE) + using_power = TRUE + update_appearance() else update_use_power(IDLE_POWER_USE) - //using_power = FALSE - update_icon() + using_power = FALSE + update_appearance() /obj/machinery/recharger/attackby(obj/item/G, mob/user, params) if(G.tool_behaviour == TOOL_WRENCH) @@ -95,7 +96,8 @@ return 1 if(anchored && !charging) - if(default_deconstruction_screwdriver(user, "rechargeropen", "recharger0", G)) + if(default_deconstruction_screwdriver(user, "recharger", "recharger", G)) + update_appearance() return if(panel_open && G.tool_behaviour == TOOL_CROWBAR) @@ -117,10 +119,11 @@ setCharging(null) /obj/machinery/recharger/attack_tk(mob/user) - if(charging) - charging.update_icon() - charging.forceMove(drop_location()) - setCharging(null) + if(!charging) + return + charging.update_icon() + charging.forceMove(drop_location()) + setCharging(null) /obj/machinery/recharger/process(delta_time) if(machine_stat & (NOPOWER|BROKEN) || !anchored) @@ -163,20 +166,16 @@ B.cell.charge = 0 -/obj/machinery/recharger/update_icon(scan) //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier. +/obj/machinery/recharger/update_icon_state() + . = ..() if(machine_stat & (NOPOWER|BROKEN) || !anchored) icon_state = "rechargeroff" - return - if(scan) - icon_state = "rechargeroff" - return - if(panel_open) + else if(panel_open) icon_state = "rechargeropen" - return - if(charging) + else if(charging) if(using_power) icon_state = "recharger1" else icon_state = "recharger2" - return - icon_state = "recharger0" + else + icon_state = "recharger0" diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index 2b31a902bbf6d..630854a3998d2 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -252,13 +252,13 @@ GLOBAL_LIST_EMPTY(req_console_ckey_departments) to_department = GLOB.req_console_ckey_departments[to_department] message = new_message screen = REQ_SCREEN_AUTHENTICATE - priority = CLAMP(text2num(href_list["priority"]), REQ_NORMAL_MESSAGE_PRIORITY, REQ_EXTREME_MESSAGE_PRIORITY) + priority = clamp(text2num(href_list["priority"]), REQ_NORMAL_MESSAGE_PRIORITY, REQ_EXTREME_MESSAGE_PRIORITY) if(href_list["writeAnnouncement"]) var/new_message = reject_bad_text(stripped_input(usr, "Write your message:", "Awaiting Input", "", MAX_MESSAGE_LEN)) if(new_message) message = new_message - priority = CLAMP(text2num(href_list["priority"]) || REQ_NORMAL_MESSAGE_PRIORITY, REQ_NORMAL_MESSAGE_PRIORITY, REQ_EXTREME_MESSAGE_PRIORITY) + priority = clamp(text2num(href_list["priority"]) || REQ_NORMAL_MESSAGE_PRIORITY, REQ_NORMAL_MESSAGE_PRIORITY, REQ_EXTREME_MESSAGE_PRIORITY) else message = "" announceAuth = FALSE @@ -333,7 +333,7 @@ GLOBAL_LIST_EMPTY(req_console_ckey_departments) //Handle screen switching if(href_list["setScreen"]) - var/set_screen = CLAMP(text2num(href_list["setScreen"]) || 0, REQ_SCREEN_MAIN, REQ_SCREEN_ANNOUNCE) + var/set_screen = clamp(text2num(href_list["setScreen"]) || 0, REQ_SCREEN_MAIN, REQ_SCREEN_ANNOUNCE) switch(set_screen) if(REQ_SCREEN_MAIN) to_department = "" diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 31c48463f1326..8b78128888462 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -270,7 +270,7 @@ use_stored_power(50) /obj/machinery/shieldwallgen/proc/use_stored_power(amount) - power = CLAMP(power - amount, 0, maximum_stored_power) + power = clamp(power - amount, 0, maximum_stored_power) update_activity() /obj/machinery/shieldwallgen/proc/update_activity() @@ -425,6 +425,7 @@ setDir(get_dir(gen_primary, gen_secondary)) for(var/mob/living/L in get_turf(src)) visible_message("\The [src] is suddenly occupying the same space as \the [L]!") + L.investigate_log("has been gibbed by [src].", INVESTIGATE_DEATHS) L.gib() RegisterSignal(src, COMSIG_ATOM_SINGULARITY_TRY_MOVE, PROC_REF(block_singularity)) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 85633e6806a24..3f286fac82848 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -58,6 +58,10 @@ /// How fast it charges cells in a suit var/charge_rate = 250 +/obj/machinery/suit_storage_unit/Initialize(mapload) + . = ..() + interaction_flags_machine |= INTERACT_MACHINE_OFFLINE + /obj/machinery/suit_storage_unit/standard_unit suit_type = /obj/item/clothing/suit/space/eva helmet_type = /obj/item/clothing/head/helmet/space/eva @@ -71,6 +75,7 @@ /obj/machinery/suit_storage_unit/engine suit_type = /obj/item/clothing/suit/space/hardsuit/engine mask_type = /obj/item/clothing/mask/breath + storage_type= /obj/item/clothing/shoes/magboots /obj/machinery/suit_storage_unit/ce suit_type = /obj/item/clothing/suit/space/hardsuit/engine/elite @@ -164,43 +169,51 @@ if(storage_type) storage = new storage_type(src) RefreshParts() - update_icon() + update_appearance() /obj/machinery/suit_storage_unit/Destroy() QDEL_NULL(wires) dump_inventory_contents() return ..() -/obj/machinery/suit_storage_unit/update_icon() - cut_overlays() +/obj/machinery/suit_storage_unit/update_overlays() + . = ..() if(uv) if(uv_super || (obj_flags & EMAGGED)) - add_overlay("super") - else if(occupant) - add_overlay("uvhuman") - else - add_overlay("uv") - else if(state_open) + . += "super" + return + if(occupant) + . += "uvhuman" + return + + . += "uv" + return + + if(state_open) if(machine_stat & BROKEN) - add_overlay("broken") - else - add_overlay("open") - if(suit) - add_overlay("suit") - if(helmet) - add_overlay("helm") - if(storage) - add_overlay("storage") - else if(occupant) - add_overlay("human") + . += "broken" + return + + . += "open" + if(suit) + . += "suit" + if(helmet) + . += "helm" + if(storage) + . += "storage" + return + + if(occupant) + . += "human" + return /obj/machinery/suit_storage_unit/power_change() . = ..() if(!is_operational && state_open) open_machine() dump_inventory_contents() - update_icon() + update_appearance() /obj/machinery/suit_storage_unit/RefreshParts() var/calculated_laser_rating = 0 @@ -240,6 +253,104 @@ component_parts.Cut() qdel(src) +/obj/machinery/suit_storage_unit/interact(mob/living/user) + var/static/list/items + + if (!items) + items = list( + "suit" = create_silhouette_of(/obj/item/clothing/suit/space/eva), + "helmet" = create_silhouette_of(/obj/item/clothing/head/helmet/space/eva), + "mask" = create_silhouette_of(/obj/item/clothing/mask/breath), + "storage" = create_silhouette_of(/obj/item/tank/internals/oxygen), + ) + + . = ..() + if (.) + return + + if (!check_interactable(user)) + return + + var/list/choices = list() + + if (locked) + choices["unlock"] = icon('icons/mob/radial.dmi', "radial_unlock") + else if (state_open) + choices["close"] = icon('icons/mob/radial.dmi', "radial_close") + + for (var/item_key in items) + var/item = vars[item_key] + if (item) + choices[item_key] = item + else + // If the item doesn't exist, put a silhouette in its place + choices[item_key] = items[item_key] + else + choices["open"] = icon('icons/mob/radial.dmi', "radial_open") + choices["disinfect"] = icon('icons/mob/radial.dmi', "radial_disinfect") + choices["lock"] = icon('icons/mob/radial.dmi', "radial_lock") + + var/choice = show_radial_menu( + user, + src, + choices, + custom_check = CALLBACK(src, PROC_REF(check_interactable), user), + ) + + if (!choice) + return + + switch (choice) + if ("open") + if (!state_open) + open_machine(drop = FALSE) + if (occupant) + dump_contents() + if ("close") + if (state_open) + close_machine() + if ("disinfect") + if (occupant && safeties) + return + else if (!helmet && !mask && !suit && !storage && !occupant) + return + else + if (occupant) + var/mob/living/mob_occupant = occupant + to_chat(mob_occupant, "[src]'s confines grow warm, then hot, then scorching. You're being burned [!mob_occupant.stat ? "alive" : "away"]!") + cook() + if ("lock", "unlock") + if (!state_open) + locked = !locked + else + var/obj/item/item_to_dispense = vars[choice] + if (item_to_dispense) + vars[choice] = null + user.put_in_hands(item_to_dispense) + + interact(user) + +/obj/machinery/suit_storage_unit/proc/check_interactable(mob/user) + if (state_open && !powered()) + return FALSE + + if (!state_open && !can_interact(user)) + return FALSE + + if (panel_open) + return FALSE + + if (uv) + return FALSE + + return TRUE + +/obj/machinery/suit_storage_unit/proc/create_silhouette_of(atom/item) + var/image/image = image(initial(item.icon), initial(item.icon_state)) + image.alpha = 128 + image.color = COLOR_RED + return image + /obj/machinery/suit_storage_unit/MouseDrop_T(atom/A, mob/living/user) if(!istype(user) || user.stat || !Adjacent(user) || !Adjacent(A) || !isliving(A)) return @@ -287,7 +398,7 @@ uv_cycles-- uv = TRUE locked = TRUE - update_icon() + update_appearance() if(mob_occupant) mob_occupant.adjustFireLoss(rand(burn_damage, burn_damage * 1.5)) mob_occupant.emote("scream") @@ -435,8 +546,7 @@ storage = I visible_message("[user] inserts [I] into [src]", "You load [I] into [src].") - update_icon() - ui_update() + update_appearance() return if(panel_open && is_wire_tool(I)) @@ -444,7 +554,6 @@ return if(!state_open) if(default_deconstruction_screwdriver(user, "panel", "close", I)) - ui_update() // Wires might've changed availability of decontaminate button return if(is_empty()) if(default_deconstruction_crowbar(I)) @@ -472,86 +581,3 @@ I.play_tool_sound(src, 50) visible_message("[usr] pries open \the [src].", "You pry open \the [src].") open_machine() - - -/obj/machinery/suit_storage_unit/ui_state(mob/user) - return GLOB.notcontained_state - -/obj/machinery/suit_storage_unit/ui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "SuitStorageUnit") - ui.open() - -/obj/machinery/suit_storage_unit/ui_data() - var/list/data = list() - data["locked"] = locked - data["open"] = state_open - data["safeties"] = safeties - data["uv_active"] = uv - data["uv_super"] = uv_super - if(helmet) - data["helmet"] = helmet.name - else - data["helmet"] = null - if(suit) - data["suit"] = suit.name - else - data["suit"] = null - if(mask) - data["mask"] = mask.name - else - data["mask"] = null - if(storage) - data["storage"] = storage.name - else - data["storage"] = null - if(occupant) - data["occupied"] = TRUE - else - data["occupied"] = FALSE - return data - -/obj/machinery/suit_storage_unit/ui_act(action, params) - if(..() || uv) - return - switch(action) - if("door") - if(state_open) - close_machine() - else - open_machine(0) - if(occupant) - dump_inventory_contents() // Dump out contents if someone is in there. - . = TRUE - if("lock") - if(state_open) - return - locked = !locked - . = TRUE - if("uv") - if(occupant && safeties) - return - else if(!helmet && !mask && !suit && !storage && !occupant) - return - else - if(occupant) - var/mob/living/mob_occupant = occupant - to_chat(mob_occupant, "[src]'s confines grow warm, then hot, then scorching. You're being burned [!mob_occupant.stat ? "alive" : "away"]!") - cook() - . = TRUE - if("dispense") - if(!state_open) - return - - var/static/list/valid_items = list("helmet", "suit", "mask", "storage") - var/item_name = params["item"] - if(item_name in valid_items) - var/obj/item/I = vars[item_name] - vars[item_name] = null - if(I) - I.forceMove(loc) - . = TRUE - - if(.) - update_icon() diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index 9823acd3d2360..3e21586a9863a 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -221,7 +221,7 @@ /obj/machinery/syndicatebomb/proc/settings(mob/user) var/new_timer = input(user, "Please set the timer.", "Timer", "[timer_set]") as num if(in_range(src, user) && isliving(user)) //No running off and setting bombs from across the station - timer_set = CLAMP(new_timer, minimum_timer, maximum_timer) + timer_set = clamp(new_timer, minimum_timer, maximum_timer) loc.visible_message("[icon2html(src, viewers(src))] timer set for [timer_set] seconds.") if(alert(user,"Would you like to start the countdown now?",,"Yes","No") == "Yes" && in_range(src, user) && isliving(user)) if(active) diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index b88c15bb69f28..f703c91d3107c 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -44,6 +44,7 @@ for(var/direction in GLOB.cardinals) power_station = locate(/obj/machinery/teleport/station, get_step(src, direction)) if(power_station) + power_station.link_console_and_hub() break return power_station @@ -136,7 +137,7 @@ if(!panel_open) . += "The panel is screwed in, obstructing the linking device and wiring panel." else - . += "The linking device is now able to be scanned with a multitool.
The wiring can be connected to a nearby console and hub with a pair of wirecutters.
" + . += "The linking device is now able to be scanned with a multitool." if(in_range(user, src) || isobserver(user)) . += "The status display reads: This station can be linked to [efficiency] other station(s)." @@ -173,12 +174,6 @@ else if(default_deconstruction_crowbar(W)) return - - else if(W.tool_behaviour == TOOL_WIRECUTTER) - if(panel_open) - link_console_and_hub() - to_chat(user, "You reconnect the station to nearby machinery.") - return else return ..() diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index c85426593c0cf..f391abebf6e9c 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -228,6 +228,7 @@ GLOBAL_LIST_INIT(dye_registry, list( /mob/living/simple_animal/pet/machine_wash(obj/machinery/washing_machine/WM) WM.bloody_mess = TRUE + investigate_log("has been gibbed by a washing machine.", INVESTIGATE_DEATHS) gib() /obj/item/machine_wash(obj/machinery/washing_machine/WM) diff --git a/code/game/mecha/equipment/tools/mining_tools.dm b/code/game/mecha/equipment/tools/mining_tools.dm index ccbc3991466fb..44b98a94ed8e5 100644 --- a/code/game/mecha/equipment/tools/mining_tools.dm +++ b/code/game/mecha/equipment/tools/mining_tools.dm @@ -121,6 +121,7 @@ var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering) butchering.Butcher(chassis, target) else + investigate_log("has been gibbed by [src] (attached to [chassis]).", INVESTIGATE_DEATHS) target.gib() else //drill makes a hole diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm index 2c644a494fe29..162c0427098fa 100644 --- a/code/game/mecha/mech_bay.dm +++ b/code/game/mecha/mech_bay.dm @@ -153,11 +153,11 @@ else recharge_port = null -/obj/machinery/computer/mech_bay_power_console/update_icon() - ..() +/obj/machinery/computer/mech_bay_power_console/update_overlays() + . = ..() if(!recharge_port || !recharge_port.recharging_mech || !recharge_port.recharging_mech.cell || !(recharge_port.recharging_mech.cell.charge < recharge_port.recharging_mech.cell.maxcharge) || machine_stat & (NOPOWER|BROKEN)) return - add_overlay("recharge_comp_on") + . += "recharge_comp_on" /obj/machinery/computer/mech_bay_power_console/Initialize(mapload) . = ..() diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index a5bedff3ee04c..c5dd1f1e15b36 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -151,10 +151,10 @@ become_hearing_sensitive(trait_source = ROUNDSTART_TRAIT) update_step_speed() -/obj/mecha/update_icon() - if (silicon_pilot && silicon_icon_state) +/obj/mecha/update_icon_state() + if(silicon_pilot && silicon_icon_state) icon_state = silicon_icon_state - . = ..() + return ..() /obj/mecha/get_cell() return cell @@ -167,11 +167,11 @@ if(occupant) occupant.SetSleeping(destruction_sleep_duration) go_out() - var/mob/living/silicon/ai/AI + var/mob/living/silicon/ai/ai for(var/mob/M in src) //Let's just be ultra sure if(isAI(M)) occupant = null - AI = M //AIs are loaded into the mech computer itself. When the mech dies, so does the AI. They can be recovered with an AI card from the wreck. + ai = M //AIs are loaded into the mech computer itself. When the mech dies, so does the AI. They can be recovered with an AI card from the wreck. else M.forceMove(loc) for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) @@ -185,8 +185,9 @@ qdel(capacitor) if(internal_tank) qdel(internal_tank) - if(AI) - AI.gib() //No wreck, no AI to recover + if(ai) + ai.investigate_log("has been gibbed by having their mech destroyed.", INVESTIGATE_DEATHS) + ai.gib() //No wreck, no AI to recover STOP_PROCESSING(SSobj, src) equipment.Cut() cell = null @@ -1055,6 +1056,7 @@ var/mob/living/silicon/ai/AI = occupant if(forced)//This should only happen if there are multiple AIs in a round, and at least one is Malf. RemoveActions(occupant) + occupant.investigate_log("has been gibbed by being forced out of their mech by another AI.", INVESTIGATE_DEATHS) occupant.gib() //If one Malf decides to steal a mech from another AI (even other Malfs!), they are destroyed, as they have nowhere to go when replaced. occupant = null silicon_pilot = FALSE diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm index 35850c15dd97c..c04ae0e93bc7f 100644 --- a/code/game/mecha/working/ripley.dm +++ b/code/game/mecha/working/ripley.dm @@ -51,16 +51,6 @@ ..() update_icon() -/obj/mecha/working/ripley/update_icon() - ..() - var/datum/component/armor_plate/C = GetComponent(/datum/component/armor_plate) - if (C.amount) - cut_overlays() - if(C.amount < 3) - add_overlay(occupant ? "ripley-g" : "ripley-g-open") - else - add_overlay(occupant ? "ripley-g-full" : "ripley-g-full-open") - /obj/mecha/working/ripley/check_for_internal_damage(list/possible_int_damage,ignore_threshold=null) if (!enclosed) possible_int_damage -= (MECHA_INT_TEMP_CONTROL + MECHA_INT_TANK_BREACH) //if we don't even have an air tank, these two doesn't make a ton of sense. diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index 6ff54ceb0814e..1434c998ed1e5 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -99,7 +99,7 @@ M.forceMove(loc) M.buckling = null - M.buckled = src + M.set_buckled(src) M.setDir(dir) buckled_mobs |= M M.update_mobility() @@ -127,7 +127,7 @@ /atom/movable/proc/unbuckle_mob(mob/living/buckled_mob, force=FALSE) if(istype(buckled_mob) && buckled_mob.buckled == src && (buckled_mob.can_unbuckle() || force)) . = buckled_mob - buckled_mob.buckled = null + buckled_mob.set_buckled(null) buckled_mob.anchored = initial(buckled_mob.anchored) buckled_mob.update_mobility() buckled_mob.clear_alert("buckled") diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm index 5c252eb8f402c..2b9436c9c8970 100644 --- a/code/game/objects/effects/spawners/lootdrop.dm +++ b/code/game/objects/effects/spawners/lootdrop.dm @@ -116,7 +116,7 @@ /obj/item/reagent_containers/food/snacks/salad/aesirsalad) var/mains = list( /obj/item/reagent_containers/food/snacks/bearsteak, - /obj/item/reagent_containers/food/snacks/enchiladas, + /obj/item/food/enchiladas, /obj/item/reagent_containers/food/snacks/stewedsoymeat, /obj/item/food/burger/bigbite, /obj/item/food/burger/superbite, diff --git a/code/game/objects/effects/spawners/vending.dm b/code/game/objects/effects/spawners/vending.dm index b3730d2af3035..5f793269430c8 100644 --- a/code/game/objects/effects/spawners/vending.dm +++ b/code/game/objects/effects/spawners/vending.dm @@ -1,12 +1,16 @@ -/obj/effect/spawner/randomsnackvend +/obj/effect/spawner/randomvend icon = 'icons/obj/vending.dmi' + name = "spawn random vending machine"// THIS IS A PARENT, only use the subtype vendors + desc = "Automagically transforms into a random vendor. If you see this while in a shift, please create a bug report." + ///whether it hacks the vendor on spawn currently used only by stinky mapedits + var/hacked = FALSE + +/obj/effect/spawner/randomvend/snack icon_state = "random_snack" name = "spawn random snack vending machine" desc = "Automagically transforms into a random snack vendor. If you see this while in a shift, please create a bug report." - ///whether it hacks the vendor on spawn currently used only by stinky mapedits - var/hacked = FALSE -/obj/effect/spawner/randomsnackvend/Initialize(mapload) +/obj/effect/spawner/randomvend/snack/Initialize(mapload) ..() var/random_vendor = pick(subtypesof(/obj/machinery/vending/snack)) @@ -16,15 +20,12 @@ return INITIALIZE_HINT_QDEL -/obj/effect/spawner/randomcolavend - icon = 'icons/obj/vending.dmi' +/obj/effect/spawner/randomvend/cola icon_state = "random_cola" name = "spawn random cola vending machine" desc = "Automagically transforms into a random cola vendor. If you see this while in a shift, please create a bug report." - ///whether it hacks the vendor on spawn currently used only by stinky mapedits - var/hacked = FALSE -/obj/effect/spawner/randomcolavend/Initialize(mapload) +/obj/effect/spawner/randomvend/cola/Initialize(mapload) ..() var/random_vendor = pick(subtypesof(/obj/machinery/vending/cola)) diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 26c999cccb39c..ba0804b0e383f 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -145,10 +145,6 @@ /obj/effect/temp_visual/dir_setting/curse/hand icon_state = "cursehand" -/obj/effect/temp_visual/dir_setting/curse/hand/Initialize(mapload, set_dir, handedness) - . = ..() - update_icon() - /obj/effect/temp_visual/bsa_splash name = "\improper Bluespace energy wave" desc = "A massive, rippling wave of bluepace energy, all rapidly exhausting itself the moment it leaves the concentrated beam of light." @@ -497,16 +493,20 @@ else update_icon() -/obj/effect/constructing_effect/update_icon() +/obj/effect/constructing_effect/update_icon_state() icon_state = "rcd" if (delay < 10) icon_state += "_shortest" + return ..() else if (delay < 20) icon_state += "_shorter" + return ..() else if (delay < 37) icon_state += "_short" + return ..() if (status == RCD_DECONSTRUCT) icon_state += "_reverse" + return ..() /obj/effect/constructing_effect/proc/end_animation() if (status == RCD_DECONSTRUCT) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 2740ed4653b32..0d4c8a5600d43 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -305,7 +305,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) //TOXLOSS = 4 //OXYLOSS = 8 //Output a creative message and then return the damagetype done -/obj/item/proc/suicide_act(mob/user) +/obj/item/proc/suicide_act(mob/living/user) return /obj/item/set_greyscale(list/colors, new_config, new_worn_config, new_inhand_left, new_inhand_right) @@ -1357,6 +1357,17 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) #undef MAX_MATS_PER_BITE +/** + * Updates all action buttons associated with this item + * + * Arguments: + * * status_only - Update only current availability status of the buttons to show if they are ready or not to use + * * force - Force buttons update even if the given button icon state has not changed + */ +/obj/item/proc/update_action_buttons(status_only = FALSE, force = FALSE) + for(var/datum/action/current_action as anything in actions) + current_action.UpdateButtonIcon(status_only, force) + /** * * An interrupt for offering an item to other people, called mainly from [/mob/living/carbon/proc/give], in case you want to run your own offer behavior instead. * diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index 074992b8f980f..98614edca7ccb 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -207,9 +207,9 @@ RLD /// Integrated airlock electronics for setting access to a newly built airlocks var/obj/item/electronics/airlock/airlock_electronics -/obj/item/construction/rcd/suicide_act(mob/user) +/obj/item/construction/rcd/suicide_act(mob/living/user) user.visible_message("[user] sets the RCD to 'Wall' and points it down [user.p_their()] throat! It looks like [user.p_theyre()] trying to commit suicide..") - return (BRUTELOSS) + return BRUTELOSS /obj/item/construction/rcd/verb/toggle_window_type_verb() set name = "RCD : Toggle Window Type" @@ -529,12 +529,11 @@ RLD explosion(src, 0, 0, 3, 1, flame_range = 1) qdel(src) -/obj/item/construction/rcd/update_icon() - ..() +/obj/item/construction/rcd/update_overlays() + . = ..() if(has_ammobar) var/ratio = CEILING((matter / max_matter) * ammo_sections, 1) - cut_overlays() //To prevent infinite stacking of overlays - add_overlay("[icon_state]_charge[ratio]") + . += "[icon_state]_charge[ratio]" /obj/item/construction/rcd/Initialize(mapload) . = ..() @@ -664,11 +663,10 @@ RLD else ..() -/obj/item/construction/rld/update_icon() +/obj/item/construction/rld/update_icon_state() // "infinite matter/35" from a debug tool will give a big number, but "rld-5" is the maximum icon_state = "rld-[min(round(matter/35), 5)]" - ..() - + return ..() /obj/item/construction/rld/attack_self(mob/user) ..() diff --git a/code/game/objects/items/RCL.dm b/code/game/objects/items/RCL.dm index 02bfbbe5ac92d..02a23725a2abe 100644 --- a/code/game/objects/items/RCL.dm +++ b/code/game/objects/items/RCL.dm @@ -31,6 +31,7 @@ /obj/item/rcl/ComponentInitialize() . = ..() AddComponent(/datum/component/two_handed) + AddElement(/datum/element/update_icon_updates_onmob) /// triggered on wield of two handed item /obj/item/rcl/proc/on_wield(obj/item/source, mob/user) @@ -112,11 +113,11 @@ QDEL_NULL(wiring_gui_menu) return ..() -/obj/item/rcl/update_icon() +/obj/item/rcl/update_icon_state() if(!loaded) icon_state = "rcl-0" item_state = "rcl-0" - return + return ..() switch(loaded.amount) if(61 to INFINITY) icon_state = "rcl-30" @@ -130,6 +131,7 @@ else icon_state = "rcl-0" item_state = "rcl-0" + return ..() /obj/item/rcl/proc/is_empty(mob/user, loud = 1) update_icon() @@ -331,11 +333,11 @@ name = "makeshift rapid cable layer" ghetto = TRUE -/obj/item/rcl/ghetto/update_icon() +/obj/item/rcl/ghetto/update_icon_state() if(!loaded) icon_state = "rclg-0" item_state = "rclg-0" - return + return ..() switch(loaded.amount) if(1 to INFINITY) icon_state = "rclg-1" @@ -343,3 +345,4 @@ else icon_state = "rclg-1" item_state = "rclg-1" + return ..() diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm index a2dccf179b13d..2a62669454c7d 100644 --- a/code/game/objects/items/RPD.dm +++ b/code/game/objects/items/RPD.dm @@ -324,11 +324,11 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list( playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE) qdel(rpd_up) -/obj/item/pipe_dispenser/suicide_act(mob/user) +/obj/item/pipe_dispenser/suicide_act(mob/living/user) user.visible_message("[user] points the end of the RPD down [user.p_their()] throat and presses a button! It looks like [user.p_theyre()] trying to commit suicide...") playsound(get_turf(user), 'sound/machines/click.ogg', 50, 1) playsound(get_turf(user), 'sound/items/deconstruct.ogg', 50, 1) - return(BRUTELOSS) + return BRUTELOSS /obj/item/pipe_dispenser/ui_assets(mob/user) return list( diff --git a/code/game/objects/items/airlock_painter.dm b/code/game/objects/items/airlock_painter.dm index 5cfdfa871e43c..2067ebffecb85 100644 --- a/code/game/objects/items/airlock_painter.dm +++ b/code/game/objects/items/airlock_painter.dm @@ -89,7 +89,7 @@ else return TRUE -/obj/item/airlock_painter/suicide_act(mob/user) +/obj/item/airlock_painter/suicide_act(mob/living/user) var/obj/item/organ/lungs/L = user.getorganslot(ORGAN_SLOT_LUNGS) if(can_use(user) && L) diff --git a/code/game/objects/items/candle.dm b/code/game/objects/items/candle.dm index 7b7e7d0ef13d5..e3ddb05a1c219 100644 --- a/code/game/objects/items/candle.dm +++ b/code/game/objects/items/candle.dm @@ -20,8 +20,9 @@ if(start_lit) light() -/obj/item/candle/update_icon() +/obj/item/candle/update_icon_state() icon_state = "candle[(wax > 800) ? ((wax > 1500) ? 1 : 2) : 3][lit ? "_lit" : ""]" + return ..() /obj/item/candle/attackby(obj/item/W, mob/user, params) var/msg = W.ignition_effect(src, user) diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index 6398a7c817689..671667baf0184 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -41,13 +41,13 @@ .=..() update_icon() -/obj/item/card/data/update_icon() - cut_overlays() +/obj/item/card/data/update_overlays() + . = ..() if(detail_color == COLOR_FLOORTILE_GRAY) return var/mutable_appearance/detail_overlay = mutable_appearance('icons/obj/card.dmi', "[icon_state]-color") detail_overlay.color = detail_color - add_overlay(detail_overlay) + . += detail_overlay /obj/item/card/data/full_color desc = "A plastic magstripe card for simple and speedy data storage and transfer. This one has the entire card colored." @@ -180,6 +180,7 @@ . = ..() if(mapload && access_txt) access = text2access(access_txt) + //RegisterSignal(src, COMSIG_ATOM_UPDATED_ICON, PROC_REFupdate_in_wallet)) /obj/item/card/id/Destroy() if (registered_account) @@ -396,6 +397,18 @@ /obj/item/card/id/RemoveID() return src +/* +/// Called on COMSIG_ATOM_UPDATED_ICON. Updates the visuals of the wallet this card is in. +/obj/item/card/id/proc/update_in_wallet() + SIGNAL_HANDLER + + if(istype(loc, /obj/item/storage/wallet)) + var/obj/item/storage/wallet/powergaming = loc + if(powergaming.front_id == src) + powergaming.update_label() + powergaming.update_appearance() +*/ + /* Usage: update_label() diff --git a/code/game/objects/items/chainsaw.dm b/code/game/objects/items/chainsaw.dm index a3ced95701ef9..ca68817e888aa 100644 --- a/code/game/objects/items/chainsaw.dm +++ b/code/game/objects/items/chainsaw.dm @@ -44,7 +44,7 @@ else user.visible_message("[user] smashes [src] into [user.p_their()] neck, destroying [user.p_their()] esophagus! It looks like [user.p_theyre()] trying to commit suicide!") playsound(src, 'sound/weapons/genhit1.ogg', 100, TRUE) - return(BRUTELOSS) + return BRUTELOSS /obj/item/chainsaw/attack_self(mob/user) on = !on @@ -62,9 +62,7 @@ if(src == user.get_active_held_item()) //update inhands user.update_inv_hands() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() // DOOMGUY CHAINSAW /obj/item/chainsaw/doomslayer @@ -124,9 +122,7 @@ if(src == user.get_active_held_item()) user.update_inv_hands() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() // DOOMGUY ENERGY CHAINSAW /obj/item/chainsaw/energy/doom diff --git a/code/game/objects/items/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm index 4de67383e30d0..5b317ac9ab2c9 100644 --- a/code/game/objects/items/chrono_eraser.dm +++ b/code/game/objects/items/chrono_eraser.dm @@ -65,8 +65,9 @@ TED = new(src.loc) return INITIALIZE_HINT_QDEL -/obj/item/gun/energy/chrono_gun/update_icon() - return +/obj/item/gun/energy/chrono_gun/ComponentInitialize() + . = ..() + AddElement(/datum/element/update_icon_blocker) /obj/item/gun/energy/chrono_gun/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0) if(field) @@ -207,7 +208,7 @@ /obj/structure/chrono_field/update_icon() var/ttk_frame = 1 - (timetokill / initial(timetokill)) - ttk_frame = CLAMP(CEILING(ttk_frame * CHRONO_FRAME_COUNT, 1), 1, CHRONO_FRAME_COUNT) + ttk_frame = clamp(CEILING(ttk_frame * CHRONO_FRAME_COUNT, 1), 1, CHRONO_FRAME_COUNT) if(ttk_frame != RPpos) RPpos = ttk_frame underlays -= mob_underlay diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index 2e116884d0da8..dfdd563230ced 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -143,7 +143,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/smoke_all = FALSE /// Should we smoke all of the chems in the cig before it runs out. Splits each puff to take a portion of the overall chems so by the end you'll always have consumed all of the chems inside. var/list/list_reagents = list(/datum/reagent/drug/nicotine = 15) -/obj/item/clothing/mask/cigarette/suicide_act(mob/user) +/obj/item/clothing/mask/cigarette/suicide_act(mob/living/user) user.visible_message("[user] is huffing [src] as quickly as [user.p_they()] can! It looks like [user.p_theyre()] trying to give [user.p_them()]self cancer.") return (TOXLOSS|OXYLOSS) @@ -629,11 +629,16 @@ CIGARETTE PACKETS ARE IN FANCY.DM user.visible_message("[user] begins whacking [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") return BRUTELOSS -/obj/item/lighter/update_icon() - cut_overlays() - var/mutable_appearance/lighter_overlay = mutable_appearance(icon,"lighter_overlay_[overlay_state][lit ? "-on" : ""]") +/obj/item/lighter/update_overlays() + . = ..() + . += create_lighter_overlay() + +/obj/item/lighter/update_icon_state() icon_state = "[initial(icon_state)][lit ? "-on" : ""]" - add_overlay(lighter_overlay) + return ..() + +/obj/item/lighter/proc/create_lighter_overlay() + return mutable_appearance(icon, "lighter_overlay_[overlay_state][lit ? "-on" : ""]") /obj/item/lighter/ignition_effect(atom/A, mob/user) if(is_hot()) @@ -772,12 +777,10 @@ CIGARETTE PACKETS ARE IN FANCY.DM lighter_color = pick(color_list) update_icon() -/obj/item/lighter/greyscale/update_icon() - cut_overlays() - var/mutable_appearance/lighter_overlay = mutable_appearance(icon,"lighter_overlay_[overlay_state][lit ? "-on" : ""]") - icon_state = "[initial(icon_state)][lit ? "-on" : ""]" +/obj/item/lighter/greyscale/create_lighter_overlay() + var/mutable_appearance/lighter_overlay = ..() lighter_overlay.color = lighter_color - add_overlay(lighter_overlay) + return lighter_overlay /obj/item/lighter/greyscale/ignition_effect(atom/A, mob/user) if(is_hot()) @@ -840,7 +843,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/screw = FALSE // kinky var/super = FALSE //for the fattest vapes dude. -/obj/item/clothing/mask/vape/suicide_act(mob/user) +/obj/item/clothing/mask/vape/suicide_act(mob/living/user) user.visible_message("[user] is puffin hard on dat vape, [user.p_they()] trying to join the vape life on a whole notha plane!")//it doesn't give you cancer, it is cancer return (TOXLOSS|OXYLOSS) diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index 1b38f839ce94e..c976427405fe9 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -945,7 +945,7 @@ var/new_cloud = input("Set the public nanite chamber's Cloud ID (1-100).", "Cloud ID", cloud_id) as num|null if(new_cloud == null) return - cloud_id = CLAMP(round(new_cloud, 1), 1, 100) + cloud_id = clamp(round(new_cloud, 1), 1, 100) /obj/item/circuitboard/machine/public_nanite_chamber/examine(mob/user) . = ..() diff --git a/code/game/objects/items/clown_items.dm b/code/game/objects/items/clown_items.dm index ce20d2bc87112..8a9c55e2c1610 100644 --- a/code/game/objects/items/clown_items.dm +++ b/code/game/objects/items/clown_items.dm @@ -72,11 +72,11 @@ icon_state = "soapsyndie" cleanspeed = 5 //faster than mop so it is useful for traitors who want to clean crime scenes -/obj/item/soap/suicide_act(mob/user) +/obj/item/soap/suicide_act(mob/living/user) user.say(";FFFFFFFFFFFFFFFFUUUUUUUDGE!!", forced="soap suicide") user.visible_message("[user] lifts [src] to [user.p_their()] mouth and gnaws on it furiously, producing a thick froth! [user.p_they(TRUE)]'ll never get that BB gun now!") new /obj/effect/particle_effect/foam(loc) - return (TOXLOSS) + return TOXLOSS /obj/item/soap/proc/decreaseUses(mob/user) uses-- @@ -168,10 +168,10 @@ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "honk", /datum/mood_event/honk) return ..() -/obj/item/bikehorn/suicide_act(mob/user) +/obj/item/bikehorn/suicide_act(mob/living/user) user.visible_message("[user] solemnly points [src] at [user.p_their()] temple! It looks like [user.p_theyre()] trying to commit suicide!") playsound(src, 'sound/items/bikehorn.ogg', 50, TRUE) - return (BRUTELOSS) + return BRUTELOSS //air horn /obj/item/bikehorn/airhorn diff --git a/code/game/objects/items/cosmetics.dm b/code/game/objects/items/cosmetics.dm index 1b19b16310f5b..1690f6e9a1957 100644 --- a/code/game/objects/items/cosmetics.dm +++ b/code/game/objects/items/cosmetics.dm @@ -254,9 +254,9 @@ var/extended_throwforce = 7 var/extended_icon_state = "straightrazor_open" -/obj/item/razor/straightrazor/suicide_act(mob/user) +/obj/item/razor/straightrazor/suicide_act(mob/living/user) user.visible_message("[user] is slitting [user.p_their()] own throat with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) + return BRUTELOSS /obj/item/razor/attack(mob/M, mob/user) . = ..() diff --git a/code/game/objects/items/courtroom.dm b/code/game/objects/items/courtroom.dm index 11c1a521db790..516360f38ae8b 100644 --- a/code/game/objects/items/courtroom.dm +++ b/code/game/objects/items/courtroom.dm @@ -13,10 +13,10 @@ attack_verb = list("bashed", "battered", "judged", "whacked") resistance_flags = FLAMMABLE -/obj/item/gavelhammer/suicide_act(mob/user) +/obj/item/gavelhammer/suicide_act(mob/living/user) user.visible_message("[user] has sentenced [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS /obj/item/gavelblock name = "gavel block" diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 45f1329e95136..98c3b1454b9c4 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -74,7 +74,7 @@ /obj/item/toy/crayon/proc/isValidSurface(surface) return istype(surface, /turf/open/floor) -/obj/item/toy/crayon/suicide_act(mob/user) +/obj/item/toy/crayon/suicide_act(mob/living/user) user.visible_message("[user] is jamming [src] up [user.p_their()] nose and into [user.p_their()] brain. It looks like [user.p_theyre()] trying to commit suicide!") return (BRUTELOSS|OXYLOSS) @@ -540,10 +540,10 @@ new /obj/item/toy/crayon/black(src) update_icon() -/obj/item/storage/crayons/update_icon() - cut_overlays() +/obj/item/storage/crayons/update_overlays() + . = ..() for(var/obj/item/toy/crayon/crayon in contents) - add_overlay(mutable_appearance('icons/obj/crayons.dmi', crayon.crayon_color)) + . += mutable_appearance('icons/obj/crayons.dmi', crayon.crayon_color) /obj/item/storage/crayons/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/toy/crayon)) @@ -613,7 +613,7 @@ return (istype(surface, /turf/open/floor) || istype(surface, /turf/closed/wall)) -/obj/item/toy/crayon/spraycan/suicide_act(mob/user) +/obj/item/toy/crayon/spraycan/suicide_act(mob/living/user) var/mob/living/carbon/human/H = user if(is_capped || !actually_paints) user.visible_message("[user] shakes up [src] with a rattle and lifts it to [user.p_their()] mouth, but nothing happens!") @@ -635,8 +635,7 @@ var/fraction = min(1, used / reagents.maximum_volume) reagents.reaction(user, VAPOR, fraction * volume_multiplier) reagents.trans_to(user, used, volume_multiplier, transfered_by = user) - - return (OXYLOSS) + return OXYLOSS /obj/item/toy/crayon/spraycan/Initialize(mapload) . = ..() @@ -736,13 +735,16 @@ . = ..() -/obj/item/toy/crayon/spraycan/update_icon() +/obj/item/toy/crayon/spraycan/update_icon_state() icon_state = is_capped ? icon_capped : icon_uncapped + return ..() + +/obj/item/toy/crayon/spraycan/update_overlays() + . = ..() if(use_overlays) - cut_overlays() var/mutable_appearance/spray_overlay = mutable_appearance('icons/obj/crayons.dmi', "[is_capped ? "spraycan_cap_colors" : "spraycan_colors"]") spray_overlay.color = paint_color - add_overlay(spray_overlay) + . += spray_overlay /obj/item/toy/crayon/spraycan/borg name = "cyborg spraycan" diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index 906943f790834..e4561d4fac963 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -32,14 +32,14 @@ /obj/item/defibrillator/Initialize(mapload) //starts without a cell for rnd . = ..() paddles = make_paddles() - update_icon() + update_power() return /obj/item/defibrillator/loaded/Initialize(mapload) //starts with hicap . = ..() paddles = make_paddles() cell = new(src) - update_icon() + update_power() return /obj/item/defibrillator/fire_act(exposed_temperature, exposed_volume) @@ -52,9 +52,7 @@ if(paddles?.loc == src) paddles.extinguish() -/obj/item/defibrillator/update_overlays() - . = ..() - +/obj/item/defibrillator/proc/update_power() if(!QDELETED(cell)) if(QDELETED(paddles) || cell.charge < paddles.revivecost) powered = FALSE @@ -62,6 +60,12 @@ powered = TRUE else powered = FALSE + update_appearance() + if(istype(loc, /obj/machinery/defibrillator_mount)) + loc.update_appearance() + +/obj/item/defibrillator/update_overlays() + . = ..() if(!on) . += "[initial(icon_state)]-paddles" @@ -78,7 +82,7 @@ /obj/item/defibrillator/CheckParts(list/parts_list) ..() cell = locate(/obj/item/stock_parts/cell) in contents - update_icon() + update_power() /obj/item/defibrillator/ui_action_click() toggle_paddles() @@ -125,15 +129,14 @@ return cell = W to_chat(user, "You install a cell in [src].") - update_icon() - + update_power() else if(W.tool_behaviour == TOOL_SCREWDRIVER) if(cell) - cell.update_icon() + cell.update_appearance() cell.forceMove(get_turf(src)) cell = null to_chat(user, "You remove the cell from [src].") - update_icon() + update_power() else return ..() @@ -148,7 +151,7 @@ else safety = TRUE to_chat(user, "You silently enable [src]'s safety protocols with the cryptographic sequencer.") - update_icon() + update_power() /obj/item/defibrillator/emp_act(severity) . = ..() @@ -156,15 +159,16 @@ deductcharge(1000 / severity) if (. & EMP_PROTECT_SELF) return + if(safety) safety = FALSE visible_message("[src] beeps: Safety protocols disabled!") - playsound(src, 'sound/machines/defib_saftyOff.ogg', 50, 0) + playsound(src, 'sound/machines/defib_saftyOff.ogg', 50, FALSE) else safety = TRUE visible_message("[src] beeps: Safety protocols enabled!") - playsound(src, 'sound/machines/defib_saftyOn.ogg', 50, 0) - update_icon() + playsound(src, 'sound/machines/defib_saftyOn.ogg', 50, FALSE) + update_power() /obj/item/defibrillator/proc/toggle_paddles() set name = "Toggle Paddles" @@ -177,16 +181,14 @@ if(!usr.put_in_hands(paddles)) on = FALSE to_chat(user, "You need a free hand to hold the paddles!") - update_icon() + update_power() return else //Remove from their hands and back onto the defib unit remove_paddles(user) update_icon() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() /obj/item/defibrillator/proc/make_paddles() return new paddle_type(src) @@ -195,7 +197,7 @@ ..() if((slot_flags == ITEM_SLOT_BACK && slot != ITEM_SLOT_BACK) || (slot_flags == ITEM_SLOT_BELT && slot != ITEM_SLOT_BELT)) remove_paddles(user) - update_icon() + update_power() /obj/item/defibrillator/item_action_slot_check(slot, mob/user) if(slot == user.getBackSlot()) @@ -212,19 +214,18 @@ var/M = get(paddles, /mob) remove_paddles(M) QDEL_NULL(paddles) + QDEL_NULL(cell) . = ..() - update_icon() /obj/item/defibrillator/proc/deductcharge(chrgdeductamt) if(cell) if(cell.charge < (paddles.revivecost+chrgdeductamt)) powered = FALSE - update_icon() + update_power() if(cell.use(chrgdeductamt)) - update_icon() + update_power() return TRUE else - update_icon() return FALSE @@ -240,8 +241,8 @@ visible_message("[src] beeps: Charge depleted.") playsound(src, 'sound/machines/defib_failed.ogg', 50, 0) paddles.cooldown = FALSE - paddles.update_icon() - update_icon() + paddles.update_appearance() + update_power() /obj/item/defibrillator/compact name = "compact defibrillator" @@ -260,7 +261,7 @@ . = ..() paddles = make_paddles() cell = new(src) - update_icon() + update_power() /obj/item/defibrillator/compact/combat name = "combat defibrillator" @@ -274,12 +275,11 @@ . = ..() paddles = make_paddles() cell = new /obj/item/stock_parts/cell/infinite(src) - update_icon() + update_power() /obj/item/defibrillator/compact/combat/loaded/attackby(obj/item/W, mob/user, params) if(W == paddles) toggle_paddles() - update_icon() return //paddles @@ -319,6 +319,7 @@ /obj/item/shockpaddles/ComponentInitialize() . = ..() + AddElement(/datum/element/update_icon_updates_onmob) AddComponent(/datum/component/two_handed, force_unwielded=8, force_wielded=12) /obj/item/shockpaddles/Destroy() @@ -362,13 +363,13 @@ if(req_defib || !time) return cooldown = TRUE - update_icon() + update_appearance() sleep(time) var/turf/T = get_turf(src) T.audible_message("[src] beeps: Unit is recharged.") - playsound(src, 'sound/machines/defib_ready.ogg', 50, 0) + playsound(src, 'sound/machines/defib_ready.ogg', 50, FALSE) cooldown = FALSE - update_icon() + update_appearance() /obj/item/shockpaddles/Initialize(mapload) . = ..() @@ -379,24 +380,22 @@ return INITIALIZE_HINT_QDEL defib = loc busy = FALSE - update_icon() + update_appearance() -/obj/item/shockpaddles/update_icon() +/obj/item/shockpaddles/update_icon_state() var/wielded = ISWIELDED(src) - icon_state = "defibpaddles[wielded]" - item_state = "defibpaddles[wielded]" + icon_state = "[base_icon_state][wielded]" + item_state = icon_state if(cooldown) - icon_state = "defibpaddles[wielded]_cooldown" - if(iscarbon(loc)) - var/mob/living/carbon/C = loc - C.update_inv_hands() + icon_state = "[base_icon_state][wielded]_cooldown" + return ..() -/obj/item/shockpaddles/suicide_act(mob/user) +/obj/item/shockpaddles/suicide_act(mob/living/user) user.visible_message("[user] is putting the live paddles on [user.p_their()] chest! It looks like [user.p_theyre()] trying to commit suicide!") if(req_defib) defib.deductcharge(revivecost) playsound(src, 'sound/machines/defib_zap.ogg', 50, 1, -1) - return (OXYLOSS) + return OXYLOSS /obj/item/shockpaddles/dropped(mob/user) ..() @@ -431,7 +430,7 @@ defib.on = FALSE listeningTo = null - defib.update_icon() + defib.update_power() /obj/item/shockpaddles/attack(mob/M, mob/user) if(busy) diff --git a/code/game/objects/items/deployable/barricade.dm b/code/game/objects/items/deployable/barricade.dm index 9ce3325dfbb4e..ee8c46727a671 100644 --- a/code/game/objects/items/deployable/barricade.dm +++ b/code/game/objects/items/deployable/barricade.dm @@ -60,7 +60,7 @@ to_chat(user, "You begin repairing [src]...") if(I.use_tool(src, user, 40, volume=40)) - obj_integrity = CLAMP(obj_integrity + 20, 0, max_integrity) + obj_integrity = clamp(obj_integrity + 20, 0, max_integrity) else if(I.GetID() && initial(locked_down)) if(allowed(user)) diff --git a/code/game/objects/items/deployable/bodybag.dm b/code/game/objects/items/deployable/bodybag.dm index 33f95d7a962bc..8a5f5ff822bad 100644 --- a/code/game/objects/items/deployable/bodybag.dm +++ b/code/game/objects/items/deployable/bodybag.dm @@ -10,7 +10,7 @@ . = ..() AddComponent(/datum/component/deployable, bag_type) -/obj/item/bodybag/suicide_act(mob/user) +/obj/item/bodybag/suicide_act(mob/living/user) if(isopenturf(user.loc)) user.visible_message("[user] is crawling into [src]! It looks like [user.p_theyre()] trying to commit suicide!") SEND_SIGNAL(src, COMSIG_DEPLOYABLE_FORCE_DEPLOY, user.loc) @@ -20,8 +20,7 @@ qdel(user) return OXYLOSS user.forceMove(R) - return (OXYLOSS) - ..() + return OXYLOSS // Bluespace bodybag diff --git a/code/game/objects/items/devices/desynchronizer.dm b/code/game/objects/items/devices/desynchronizer.dm index 74b8786802d8c..02c49cac0485d 100644 --- a/code/game/objects/items/devices/desynchronizer.dm +++ b/code/game/objects/items/devices/desynchronizer.dm @@ -37,7 +37,7 @@ var/new_duration = input(user, "Set the duration (5-300):", "Desynchronizer", duration / 10) as null|num if(new_duration) new_duration = new_duration SECONDS - new_duration = CLAMP(new_duration, 50, max_duration) + new_duration = clamp(new_duration, 50, max_duration) duration = new_duration to_chat(user, "You set the duration to [DisplayTimeText(duration)].") diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 463878c0e7dea..0a1f423d445d1 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -44,9 +44,7 @@ /obj/item/flashlight/attack_self(mob/user) on = !on update_brightness(user) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() return 1 /obj/item/flashlight/suicide_act(mob/living/carbon/human/user) @@ -54,7 +52,7 @@ user.visible_message("[user] is putting [src] close to [user.p_their()] eyes and turning it on... but [user.p_theyre()] blind!") return SHAME user.visible_message("[user] is putting [src] close to [user.p_their()] eyes and turning it on! It looks like [user.p_theyre()] trying to commit suicide!") - return (FIRELOSS) + return FIRELOSS /obj/item/flashlight/attack(mob/living/carbon/M, mob/living/carbon/human/user) add_fingerprint(user) @@ -516,7 +514,7 @@ return SHAME user.visible_message("[user] is squirting [src]'s fluids into [user.p_their()] eyes! It looks like [user.p_theyre()] trying to commit suicide!") fuel = 0 - return (FIRELOSS) + return FIRELOSS /obj/item/flashlight/glowstick/red name = "red glowstick" diff --git a/code/game/objects/items/devices/geiger_counter.dm b/code/game/objects/items/devices/geiger_counter.dm index ba318e4d61c6f..dc19c9b0e74fe 100644 --- a/code/game/objects/items/devices/geiger_counter.dm +++ b/code/game/objects/items/devices/geiger_counter.dm @@ -79,13 +79,14 @@ . += "The last radiation amount detected was [last_tick_amount]" -/obj/item/geiger_counter/update_icon() +/obj/item/geiger_counter/update_icon_state() if(!scanning) icon_state = "geiger_off" - return 1 - if(obj_flags & EMAGGED) + return ..() + else if(obj_flags & EMAGGED) icon_state = "geiger_on_emag" - return 1 + return ..() + switch(radiation_count) if(-INFINITY to RAD_LEVEL_NORMAL) icon_state = "geiger_on_1" @@ -99,7 +100,7 @@ icon_state = "geiger_on_4" if(RAD_LEVEL_CRITICAL + 1 to INFINITY) icon_state = "geiger_on_5" - ..() + return ..() /obj/item/geiger_counter/proc/update_sound() var/datum/looping_sound/geiger/loop = soundloop diff --git a/code/game/objects/items/devices/glue.dm b/code/game/objects/items/devices/glue.dm index 09d80523efd49..308f7af67ee22 100644 --- a/code/game/objects/items/devices/glue.dm +++ b/code/game/objects/items/devices/glue.dm @@ -10,7 +10,7 @@ /obj/item/syndie_glue/suicide_act(mob/living/M) M.visible_message("[M] is drinking the whole bottle of glue! It looks like [M.p_theyre()] trying to commit suicide!") - return (OXYLOSS) // read the warning n00b + return OXYLOSS // read the warning n00b /obj/item/syndie_glue/afterattack(atom/target, mob/user, proximity) . = ..() diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index c06342e3ebdae..22839c4067bbc 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -159,8 +159,9 @@ ReplaceLight(target, user) to_chat(user, status_string()) -/obj/item/lightreplacer/update_icon() +/obj/item/lightreplacer/update_icon_state() icon_state = "lightreplacer[(obj_flags & EMAGGED ? 1 : 0)]" + return ..() /obj/item/lightreplacer/proc/status_string() return "It has [uses] light\s remaining (plus [bulb_shards] fragment\s)." @@ -172,7 +173,7 @@ // Negative numbers will subtract /obj/item/lightreplacer/proc/AddUses(amount = 1) - uses = CLAMP(uses + amount, 0, max_uses) + uses = clamp(uses + amount, 0, max_uses) /obj/item/lightreplacer/proc/AddShards(amount = 1, user) bulb_shards += amount diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index d630c66c41207..aa3c1e2ff42b8 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -27,7 +27,7 @@ var/obj/structure/cable/attached // the attached cable item_flags = NO_PIXEL_RANDOM_DROP -/obj/item/powersink/update_icon() +/obj/item/powersink/update_icon_state() icon_state = "powersink[mode == OPERATING]" return ..() diff --git a/code/game/objects/items/devices/quantum_keycard.dm b/code/game/objects/items/devices/quantum_keycard.dm index fc9ccddaf9e15..86051885c65cc 100644 --- a/code/game/objects/items/devices/quantum_keycard.dm +++ b/code/game/objects/items/devices/quantum_keycard.dm @@ -25,8 +25,6 @@ to_chat(user, "The keycard beeps twice and disconnects the quantum link.") qpad = null -/obj/item/quantum_keycard/update_icon() - if(qpad) - icon_state = "quantum_keycard_on" - else - icon_state = initial(icon_state) +/obj/item/quantum_keycard/update_icon_state() + icon_state = qpad ? "quantum_keycard_on" : initial(icon_state) + return ..() diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index e4e62ae722c8d..ba2f41a689bb9 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -24,9 +24,9 @@ SSradio.remove_object(src, frequency) return ..() -/obj/item/electropack/suicide_act(mob/user) +/obj/item/electropack/suicide_act(mob/living/user) user.visible_message("[user] hooks [user.p_them()]self to the electropack and spams the trigger! It looks like [user.p_theyre()] trying to commit suicide!") - return (FIRELOSS) + return FIRELOSS //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/electropack/attack_hand(mob/user) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 7eb65c58fa70c..b7cfcc6de2c19 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -110,7 +110,7 @@ /obj/item/radio/ComponentInitialize() . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_WIRES) + AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES) /obj/item/radio/AltClick(mob/user) if(headset) diff --git a/code/game/objects/items/devices/reverse_bear_trap.dm b/code/game/objects/items/devices/reverse_bear_trap.dm index 2597bea3b625f..296bc9981a0df 100644 --- a/code/game/objects/items/devices/reverse_bear_trap.dm +++ b/code/game/objects/items/devices/reverse_bear_trap.dm @@ -112,6 +112,7 @@ playsound(src, 'sound/effects/snap.ogg', 75, TRUE, frequency = 0.5) playsound(src, 'sound/effects/splat.ogg', 50, TRUE, frequency = 0.5) jill.apply_damage(9999, BRUTE, BODY_ZONE_HEAD) + jill.investigate_log("has been killed by [src].", INVESTIGATE_DEATHS) jill.death() //just in case, for some reason, they're still alive flash_color(jill, flash_color = "#FF0000", flash_time = 100) diff --git a/code/game/objects/items/devices/swapper.dm b/code/game/objects/items/devices/swapper.dm index ccb5fa00f3475..a2fb41bba6de7 100644 --- a/code/game/objects/items/devices/swapper.dm +++ b/code/game/objects/items/devices/swapper.dm @@ -16,16 +16,13 @@ /obj/item/swapper/Destroy() if(linked_swapper) linked_swapper.linked_swapper = null //*inception music* - linked_swapper.update_icon() + linked_swapper.update_appearance() linked_swapper = null return ..() -/obj/item/swapper/update_icon() - if(linked_swapper) - icon_state = "swapper-linked" - else - icon_state = "swapper" - ..() +/obj/item/swapper/update_icon_state() + icon_state = "swapper[linked_swapper ? "-linked" : null]" + return ..() /obj/item/swapper/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/swapper)) @@ -39,8 +36,8 @@ to_chat(user, "You establish a quantum link between the two devices.") linked_swapper = other_swapper other_swapper.linked_swapper = src - update_icon() - linked_swapper.update_icon() + update_appearance() + linked_swapper.update_appearance() else return ..() @@ -75,9 +72,9 @@ to_chat(user, "You break the current quantum link.") if(!QDELETED(linked_swapper)) linked_swapper.linked_swapper = null - linked_swapper.update_icon() + linked_swapper.update_appearance() linked_swapper = null - update_icon() + update_appearance() //Gets the topmost teleportable container /obj/item/swapper/proc/get_teleportable_container() diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm index b2b614e4d0489..6e63f012d6634 100644 --- a/code/game/objects/items/devices/taperecorder.dm +++ b/code/game/objects/items/devices/taperecorder.dm @@ -88,15 +88,18 @@ eject(usr) -/obj/item/taperecorder/update_icon() +/obj/item/taperecorder/update_icon_state() if(!mytape) icon_state = "taperecorder_empty" - else if(recording) + return ..() + if(recording) icon_state = "taperecorder_recording" - else if(playing) + return ..() + if(playing) icon_state = "taperecorder_playing" - else - icon_state = "taperecorder_idle" + return ..() + icon_state = "taperecorder_idle" + return ..() /obj/item/taperecorder/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, list/message_mods = list()) diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index 6705e9c977078..c9c0d8de64791 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -248,7 +248,7 @@ effective or pretty fucking useless. charge = max(0, charge - 12.5 * delta_time)//Quick decrease in light else charge = min(max_charge,charge + 25 * delta_time) //Charge in the dark - animate(user,alpha = CLAMP(255 - charge,0,255),time = 10) + animate(user,alpha = clamp(255 - charge,0,255),time = 10) /obj/item/shadowcloak/magician name = "magician's cape" diff --git a/code/game/objects/items/dice.dm b/code/game/objects/items/dice.dm index 02bb4c26e617a..c78c84c598f45 100644 --- a/code/game/objects/items/dice.dm +++ b/code/game/objects/items/dice.dm @@ -31,9 +31,9 @@ if(special_die == "100") new /obj/item/dice/d100(src) -/obj/item/storage/pill_bottle/dice/suicide_act(mob/user) +/obj/item/storage/pill_bottle/dice/suicide_act(mob/living/user) user.visible_message("[user] is gambling with death! It looks like [user.p_theyre()] trying to commit suicide!") - return (OXYLOSS) + return OXYLOSS /obj/item/storage/pill_bottle/dice_cup name = "dice cup" @@ -72,9 +72,9 @@ . = ..() . += "[result] is face up." -/obj/item/dice/suicide_act(mob/user) +/obj/item/dice/suicide_act(mob/living/user) user.visible_message("[user] is gambling with death! It looks like [user.p_theyre()] trying to commit suicide!") - return (OXYLOSS) + return OXYLOSS /obj/item/dice/d1 name = "d1" @@ -155,8 +155,9 @@ w_class = WEIGHT_CLASS_SMALL sides = 100 -/obj/item/dice/d100/update_icon() - return +/obj/item/dice/d100/ComponentInitialize() + . = ..() + AddElement(/datum/element/update_icon_blocker) /obj/item/dice/eightbd20 name = "strange d20" @@ -165,8 +166,9 @@ sides = 20 special_faces = list("It is certain","It is decidedly so","Without a doubt","Yes, definitely","You may rely on it","As I see it, yes","Most likely","Outlook good","Yes","Signs point to yes","Reply hazy try again","Ask again later","Better not tell you now","Cannot predict now","Concentrate and ask again","Don't count on it","My reply is no","My sources say no","Outlook not so good","Very doubtful") -/obj/item/dice/eightbd20/update_icon() - return +/obj/item/dice/eightbd20/ComponentInitialize() + . = ..() + AddElement(/datum/element/update_icon_blocker) /obj/item/dice/fourdd6 name = "4d d6" @@ -175,8 +177,9 @@ sides = 48 special_faces = list("Cube-Side: 1-1","Cube-Side: 1-2","Cube-Side: 1-3","Cube-Side: 1-4","Cube-Side: 1-5","Cube-Side: 1-6","Cube-Side: 2-1","Cube-Side: 2-2","Cube-Side: 2-3","Cube-Side: 2-4","Cube-Side: 2-5","Cube-Side: 2-6","Cube-Side: 3-1","Cube-Side: 3-2","Cube-Side: 3-3","Cube-Side: 3-4","Cube-Side: 3-5","Cube-Side: 3-6","Cube-Side: 4-1","Cube-Side: 4-2","Cube-Side: 4-3","Cube-Side: 4-4","Cube-Side: 4-5","Cube-Side: 4-6","Cube-Side: 5-1","Cube-Side: 5-2","Cube-Side: 5-3","Cube-Side: 5-4","Cube-Side: 5-5","Cube-Side: 5-6","Cube-Side: 6-1","Cube-Side: 6-2","Cube-Side: 6-3","Cube-Side: 6-4","Cube-Side: 6-5","Cube-Side: 6-6","Cube-Side: 7-1","Cube-Side: 7-2","Cube-Side: 7-3","Cube-Side: 7-4","Cube-Side: 7-5","Cube-Side: 7-6","Cube-Side: 8-1","Cube-Side: 8-2","Cube-Side: 8-3","Cube-Side: 8-4","Cube-Side: 8-5","Cube-Side: 8-6") -/obj/item/dice/fourdd6/update_icon() - return +/obj/item/dice/fourdd6/ComponentInitialize() + . = ..() + AddElement(/datum/element/update_icon_blocker) /obj/item/dice/attack_self(mob/user) diceroll(user) @@ -190,7 +193,7 @@ /obj/item/dice/proc/diceroll(mob/user) result = roll(sides) if(rigged != DICE_NOT_RIGGED && result != rigged_value) - if(rigged == DICE_BASICALLY_RIGGED && prob(CLAMP(1/(sides - 1) * 100, 25, 80))) + if(rigged == DICE_BASICALLY_RIGGED && prob(clamp(1/(sides - 1) * 100, 25, 80))) result = rigged_value else if(rigged == DICE_TOTALLY_RIGGED) result = rigged_value @@ -215,9 +218,9 @@ else if(!src.throwing) //Dice was thrown and is coming to rest visible_message("[src] rolls to a stop, landing on [result]. [comment]") -/obj/item/dice/update_icon() - cut_overlays() - add_overlay("[src.icon_state]-[src.result]") +/obj/item/dice/update_overlays() + . = ..() + . += "[icon_state]-[result]" /obj/item/dice/microwave_act(obj/machinery/microwave/M) if(microwave_riggable) diff --git a/code/game/objects/items/etherealdiscoball.dm b/code/game/objects/items/etherealdiscoball.dm index 0052b8b139f2f..9bb1a5195e072 100644 --- a/code/game/objects/items/etherealdiscoball.dm +++ b/code/game/objects/items/etherealdiscoball.dm @@ -64,9 +64,12 @@ update_icon() TimerID = addtimer(CALLBACK(src, PROC_REF(DiscoFever)), 5, TIMER_STOPPABLE) //Call ourselves every 0.5 seconds to change colors -/obj/structure/etherealball/update_icon() - cut_overlays() +/obj/structure/etherealball/update_icon_state() icon_state = "ethdisco_head_[TurnedOn]" + return ..() + +/obj/structure/etherealball/update_overlays() + . = ..() var/mutable_appearance/base_overlay = mutable_appearance(icon, "ethdisco_base") base_overlay.appearance_flags = RESET_COLOR - add_overlay(base_overlay) + . += base_overlay diff --git a/code/game/objects/items/fireaxe.dm b/code/game/objects/items/fireaxe.dm index accd29957222a..2023b63f773f3 100644 --- a/code/game/objects/items/fireaxe.dm +++ b/code/game/objects/items/fireaxe.dm @@ -33,9 +33,9 @@ icon_state = "[icon_prefix]0" ..() -/obj/item/fireaxe/suicide_act(mob/user) +/obj/item/fireaxe/suicide_act(mob/living/user) user.visible_message("[user] axes [user.p_them()]self from head to toe! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) + return BRUTELOSS /obj/item/fireaxe/afterattack(atom/A, mob/user, proximity) . = ..() diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm index e48e1674f9d45..d23d1efddf076 100644 --- a/code/game/objects/items/flamethrower.dm +++ b/code/game/objects/items/flamethrower.dm @@ -33,6 +33,10 @@ var/igniter_type = /obj/item/assembly/igniter trigger_guard = TRIGGER_GUARD_NORMAL +/obj/item/flamethrower/ComponentInitialize() + . = ..() + AddElement(/datum/element/update_icon_updates_onmob) + /obj/item/flamethrower/Destroy() if(weldtool) qdel(weldtool) @@ -55,21 +59,18 @@ igniter.flamethrower_process(location) -/obj/item/flamethrower/update_icon() - cut_overlays() +/obj/item/flamethrower/update_icon_state() + item_state = "flamethrower_[lit]" + return ..() + +/obj/item/flamethrower/update_overlays() + . = ..() if(igniter) - add_overlay("+igniter[status]") + . += "+igniter[status]" if(ptank) - add_overlay("+ptank") + . += "+ptank" if(lit) - add_overlay("+lit") - item_state = "flamethrower_1" - else - item_state = "flamethrower_0" - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands() - return + . += "+lit" /obj/item/flamethrower/afterattack(atom/target, mob/user, flag) . = ..() diff --git a/code/game/objects/items/food/dough.dm b/code/game/objects/items/food/dough.dm new file mode 100644 index 0000000000000..12fe92f56d52d --- /dev/null +++ b/code/game/objects/items/food/dough.dm @@ -0,0 +1,151 @@ + + +/////////////////// Dough Ingredients //////////////////////// + +/obj/item/food/dough + name = "dough" + desc = "A piece of dough." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "dough" + microwaved_type = /obj/item/food/bread/plain + food_reagents = list(/datum/reagent/consumable/nutriment = 6) + tastes = list("dough" = 1) + foodtypes = GRAIN + +/* +/obj/item/food/dough/make_microwaveable() + AddElement(/datum/element/microwavable, /obj/item/food/bread/plain) +*/ + +// Dough + rolling pin = flat dough +/obj/item/food/dough/make_processable() + AddElement(/datum/element/processable, TOOL_ROLLINGPIN, /obj/item/food/flatdough, 1, 3 SECONDS, table_required = TRUE, /*screentip_verb = "Flatten"*/) + +/obj/item/food/flatdough + name = "flat dough" + desc = "A flattened dough." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "flat dough" + microwaved_type = /obj/item/food/pizzabread + food_reagents = list(/datum/reagent/consumable/nutriment = 6) + tastes = list("dough" = 1) + foodtypes = GRAIN + +/* +/obj/item/food/flatdough/make_microwaveable() + AddElement(/datum/element/microwavable, /obj/item/food/pizzabread) +*/ + +// sliceable into 3xdoughslices +/obj/item/food/flatdough/make_processable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/doughslice, 3, 3 SECONDS, table_required = TRUE, /*screentip_verb = "Slice"*/) + +/obj/item/food/pizzabread + name = "pizza bread" + desc = "Add ingredients to make a pizza." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "pizzabread" + food_reagents = list(/datum/reagent/consumable/nutriment = 7) + tastes = list("bread" = 1) + foodtypes = GRAIN + +/* +/obj/item/food/pizzabread/Initialize(mapload) + . = ..() + AddComponent(/datum/component/customizable_reagent_holder, /obj/item/food/pizza/margherita, CUSTOM_INGREDIENT_ICON_SCATTER, max_ingredients = 12) +*/ + +/obj/item/food/doughslice + name = "dough slice" + desc = "A slice of dough. Can be cooked into a bun." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "doughslice" + microwaved_type = /obj/item/food/bun + food_reagents = list(/datum/reagent/consumable/nutriment = 2) + w_class = WEIGHT_CLASS_SMALL + tastes = list("dough" = 1) + foodtypes = GRAIN + +/* +/obj/item/food/doughslice/make_microwaveable() + AddElement(/datum/element/microwavable, /obj/item/food/bun) +*/ + +/obj/item/food/bun + name = "bun" + desc = "A base for any self-respecting burger." + icon = 'icons/obj/food/burgerbread.dmi' + icon_state = "bun" + food_reagents = list(/datum/reagent/consumable/nutriment = 3) + w_class = WEIGHT_CLASS_SMALL + tastes = list("bun" = 1) // the bun tastes of bun. + foodtypes = GRAIN + +/* +/obj/item/food/bun/Initialize(mapload) + . = ..() + AddComponent(/datum/component/customizable_reagent_holder, /obj/item/food/burger/empty, CUSTOM_INGREDIENT_ICON_STACKPLUSTOP) +*/ + +/obj/item/food/cakebatter + name = "cake batter" + desc = "Bake it to get a cake." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "cakebatter" + microwaved_type = /obj/item/food/cake/plain + food_reagents = list(/datum/reagent/consumable/nutriment = 9) + tastes = list("batter" = 1) + foodtypes = GRAIN | DAIRY + +/* +/obj/item/food/cakebatter/make_microwaveable() + AddElement(/datum/element/microwavable, /obj/item/food/cake/plain) +*/ + +// Cake batter + rolling pin = pie dough +/obj/item/food/cakebatter/make_processable() + AddElement(/datum/element/processable, TOOL_ROLLINGPIN, /obj/item/food/piedough, 1, 3 SECONDS, table_required = TRUE, /*screentip_verb = "Flatten"*/) + +/obj/item/food/piedough + name = "pie dough" + desc = "Cook it to get a pie." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "piedough" + microwaved_type = /obj/item/reagent_containers/food/snacks/pie/plain + food_reagents = list(/datum/reagent/consumable/nutriment = 9) + tastes = list("dough" = 1) + foodtypes = GRAIN | DAIRY + +/* +/obj/item/food/piedough/make_microwaveable() + AddElement(/datum/element/microwavable, /obj/item/food/pie/plain) +*/ + +/obj/item/food/piedough/make_processable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/rawpastrybase, 6, 3 SECONDS, table_required = TRUE, /*screentip_verb = "Slice"*/) + +/obj/item/food/rawpastrybase + name = "raw pastry base" + desc = "Must be cooked before use." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "rawpastrybase" + microwaved_type = /obj/item/food/pastrybase + food_reagents = list(/datum/reagent/consumable/nutriment = 2) + w_class = WEIGHT_CLASS_SMALL + tastes = list("raw pastry" = 1) + foodtypes = GRAIN | DAIRY + +/* +/obj/item/food/rawpastrybase/make_microwaveable() + AddElement(/datum/element/microwavable, /obj/item/food/pastrybase) +*/ + +/obj/item/food/pastrybase + name = "pastry base" + desc = "A base for any self-respecting pastry." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "pastrybase" + food_reagents = list(/datum/reagent/consumable/nutriment = 3) + w_class = WEIGHT_CLASS_SMALL + tastes = list("pastry" = 1) + foodtypes = GRAIN | DAIRY diff --git a/code/game/objects/items/food/mexican.dm b/code/game/objects/items/food/mexican.dm new file mode 100644 index 0000000000000..2bb7967fe262f --- /dev/null +++ b/code/game/objects/items/food/mexican.dm @@ -0,0 +1,164 @@ +/obj/item/food/tortilla + name = "tortilla" + desc = "The base for all your burritos." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "tortilla" + food_reagents = list( + /datum/reagent/consumable/nutriment = 3, + /datum/reagent/consumable/nutriment/vitamin = 1, + ) + tastes = list("tortilla" = 1) + foodtypes = GRAIN + w_class = WEIGHT_CLASS_TINY + +/obj/item/food/burrito + name = "burrito" + desc = "Tortilla wrapped goodness." + icon = 'icons/obj/food/mexican.dmi' + icon_state = "burrito" + food_reagents = list( + /datum/reagent/consumable/nutriment = 2, + /datum/reagent/consumable/nutriment/vitamin = 1, + ) + tastes = list("tortilla" = 2, "beans" = 3) + foodtypes = GRAIN + w_class = WEIGHT_CLASS_SMALL + +/obj/item/food/cheesyburrito + name = "cheesy burrito" + desc = "It's a burrito filled with cheese." + icon = 'icons/obj/food/mexican.dmi' + icon_state = "cheesyburrito" + food_reagents = list( + /datum/reagent/consumable/nutriment = 3, + /datum/reagent/consumable/nutriment/vitamin = 2, + ) + tastes = list("tortilla" = 2, "beans" = 3, "cheese" = 1) + foodtypes = GRAIN | DAIRY + w_class = WEIGHT_CLASS_SMALL + +/obj/item/food/carneburrito + name = "carne asada burrito" + desc = "The best burrito for meat lovers." + icon = 'icons/obj/food/mexican.dmi' + icon_state = "carneburrito" + food_reagents = list( + /datum/reagent/consumable/nutriment = 2, + /datum/reagent/consumable/nutriment/protein = 6, + /datum/reagent/consumable/nutriment/vitamin = 1, + ) + tastes = list("tortilla" = 2, "meat" = 4) + foodtypes = GRAIN | MEAT + w_class = WEIGHT_CLASS_SMALL + +/obj/item/food/fuegoburrito + name = "fuego plasma burrito" + desc = "A super spicy burrito." + icon = 'icons/obj/food/mexican.dmi' + icon_state = "fuegoburrito" + food_reagents = list( + /datum/reagent/consumable/nutriment = 3, + /datum/reagent/consumable/nutriment/protein = 2, + /datum/reagent/consumable/capsaicin = 5, + /datum/reagent/consumable/nutriment/vitamin = 3, + ) + tastes = list("tortilla" = 2, "beans" = 3, "hot peppers" = 1) + foodtypes = GRAIN + w_class = WEIGHT_CLASS_SMALL + +/obj/item/food/nachos + name = "nachos" + desc = "Chips from Space Mexico." + icon = 'icons/obj/food/mexican.dmi' + icon_state = "nachos" + food_reagents = list( + /datum/reagent/consumable/nutriment = 6, + /datum/reagent/consumable/nutriment/vitamin = 2, + ) + tastes = list("nachos" = 1) + foodtypes = GRAIN | FRIED + w_class = WEIGHT_CLASS_SMALL + +/obj/item/food/cheesynachos + name = "cheesy nachos" + desc = "The delicious combination of nachos and melting cheese." + icon = 'icons/obj/food/mexican.dmi' + icon_state = "cheesynachos" + food_reagents = list( + /datum/reagent/consumable/nutriment = 6, + /datum/reagent/consumable/nutriment/protein = 1, + /datum/reagent/consumable/nutriment/vitamin = 3, + ) + tastes = list("nachos" = 2, "cheese" = 1) + foodtypes = GRAIN | FRIED | DAIRY + w_class = WEIGHT_CLASS_SMALL + +/obj/item/food/cubannachos + name = "Cuban nachos" + desc = "That's some dangerously spicy nachos." + icon = 'icons/obj/food/mexican.dmi' + icon_state = "cubannachos" + food_reagents = list( + /datum/reagent/consumable/nutriment = 7, + /datum/reagent/consumable/capsaicin = 8, + /datum/reagent/consumable/nutriment/vitamin = 4, + ) + tastes = list("nachos" = 2, "hot pepper" = 1) + foodtypes = VEGETABLES | FRIED | DAIRY + w_class = WEIGHT_CLASS_SMALL + +/obj/item/food/taco + name = "classic taco" + desc = "A traditional taco with meat, cheese, and lettuce." + icon = 'icons/obj/food/mexican.dmi' + icon_state = "taco" + food_reagents = list( + /datum/reagent/consumable/nutriment = 2, + /datum/reagent/consumable/nutriment/protein = 3, + /datum/reagent/consumable/nutriment/vitamin = 2, + ) + tastes = list("taco" = 4, "meat" = 2, "cheese" = 2, "lettuce" = 1) + foodtypes = MEAT | DAIRY | GRAIN | VEGETABLES + w_class = WEIGHT_CLASS_SMALL + +/obj/item/food/taco/plain + name = "plain taco" + desc = "A traditional taco with meat and cheese, minus the rabbit food." + icon_state = "taco_plain" + food_reagents = list( + /datum/reagent/consumable/nutriment = 2, + /datum/reagent/consumable/nutriment/protein = 2, + /datum/reagent/consumable/nutriment/vitamin = 1, + ) + tastes = list("taco" = 4, "meat" = 2, "cheese" = 2) + foodtypes = MEAT | DAIRY | GRAIN + +/obj/item/food/enchiladas + name = "enchiladas" + desc = "Viva La Mexico!" + icon = 'icons/obj/food/mexican.dmi' + icon_state = "enchiladas" + bite_consumption = 4 + food_reagents = list( + /datum/reagent/consumable/nutriment = 4, + /datum/reagent/consumable/nutriment/protein = 7, + /datum/reagent/consumable/capsaicin = 6, + /datum/reagent/consumable/nutriment/vitamin = 2 + ) + tastes = list("hot peppers" = 1, "meat" = 3, "cheese" = 1, "sour cream" = 1) + foodtypes = MEAT | GRAIN + w_class = WEIGHT_CLASS_SMALL + +/obj/item/food/stuffedlegion + name = "stuffed legion" + desc = "The former skull of a damned human, filled with goliath meat. It has a decorative lava pool made of ketchup and hotsauce." + icon_state = "stuffed_legion" + food_reagents = list( + /datum/reagent/consumable/nutriment = 2, + /datum/reagent/consumable/nutriment/protein = 5, + /datum/reagent/consumable/nutriment/vitamin = 5, + /datum/reagent/consumable/capsaicin = 2, + ) + tastes = list("death" = 2, "rock" = 1, "meat" = 1, "hot peppers" = 1) + foodtypes = MEAT + w_class = WEIGHT_CLASS_SMALL diff --git a/code/game/objects/items/food/pizza.dm b/code/game/objects/items/food/pizza.dm index 00489fbb6e176..afddd4b3c03ae 100644 --- a/code/game/objects/items/food/pizza.dm +++ b/code/game/objects/items/food/pizza.dm @@ -244,6 +244,7 @@ /obj/item/food/proc/i_kill_you(obj/item/I, mob/user) if(istype(I, /obj/item/reagent_containers/food/snacks/pineappleslice)) to_chat(user, "If you want something crazy like pineapple, I'll kill you.") //this is in bigger text because it's hard to spam something that gibs you, and so that you're perfectly aware of the reason why you died + user.investigate_log("has been gibbed by putting pineapple on an arnold pizza.", INVESTIGATE_DEATHS) user.gib() //if you want something crazy like pineapple, i'll kill you else if(istype(I, /obj/item/reagent_containers/food/snacks/grown/mushroom) && iscarbon(user)) to_chat(user, "So, if you want mushroom, shut up.") //not as large as the pineapple text, because you could in theory spam it diff --git a/code/game/objects/items/gift.dm b/code/game/objects/items/gift.dm index e15249f791e01..569e622ad49cb 100644 --- a/code/game/objects/items/gift.dm +++ b/code/game/objects/items/gift.dm @@ -28,9 +28,9 @@ GLOBAL_LIST_EMPTY(possible_gifts) contains_type = get_gift_type() -/obj/item/a_gift/suicide_act(mob/user) +/obj/item/a_gift/suicide_act(mob/living/user) user.visible_message("[user] peeks inside [src] and cries [user.p_them()]self to death! It looks like [user.p_they()] [user.p_were()] on the naughty list...") - return (BRUTELOSS) + return BRUTELOSS /obj/item/a_gift/examine(mob/M) . = ..() diff --git a/code/game/objects/items/grenades/chem_grenade.dm b/code/game/objects/items/grenades/chem_grenade.dm index 4d6f0f2b9b64a..114822d13d90d 100644 --- a/code/game/objects/items/grenades/chem_grenade.dm +++ b/code/game/objects/items/grenades/chem_grenade.dm @@ -18,7 +18,7 @@ /obj/item/grenade/chem_grenade/ComponentInitialize() . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_WIRES) + AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES) /obj/item/grenade/chem_grenade/Initialize(mapload) . = ..() diff --git a/code/game/objects/items/grenades/plastic.dm b/code/game/objects/items/grenades/plastic.dm index a2a0374933e11..0d7efe7c2aa12 100644 --- a/code/game/objects/items/grenades/plastic.dm +++ b/code/game/objects/items/grenades/plastic.dm @@ -31,7 +31,7 @@ /obj/item/grenade/plastic/ComponentInitialize() . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_WIRES) + AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES) /obj/item/grenade/plastic/Destroy() qdel(nadeassembly) @@ -106,7 +106,7 @@ return var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num if(user.get_active_held_item() == src) - newtime = CLAMP(newtime, 10, 60000) + newtime = clamp(newtime, 10, 60000) det_time = newtime to_chat(user, "Timer set for [det_time] seconds.") @@ -165,7 +165,7 @@ message_say = "VIVA LA REVOLUTION!" M.say(message_say, forced="C4 suicide") -/obj/item/grenade/plastic/suicide_act(mob/user) +/obj/item/grenade/plastic/suicide_act(mob/living/user) message_admins("[ADMIN_LOOKUPFLW(user)] suicided with [src] at [ADMIN_VERBOSEJMP(user)]") log_game("[key_name(user)] suicided with [src] at [AREACOORD(user)]") user.visible_message("[user] activates [src] and holds it above [user.p_their()] head! It looks like [user.p_theyre()] going out with a bang!") @@ -201,7 +201,7 @@ target = null return ..() -/obj/item/grenade/plastic/c4/suicide_act(mob/user) +/obj/item/grenade/plastic/c4/suicide_act(mob/living/user) user.visible_message("[user] activates the [src.name] and holds it above [user.p_their()] head! It looks like [user.p_theyre()] going out with a bang!") shout_syndicate_crap(user) target = user diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index cf5478cfbd15b..4cd68a1414652 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -4,7 +4,7 @@ /obj/item/restraints/suicide_act(mob/living/carbon/user) user.visible_message("[user] is strangling [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return(OXYLOSS) + return OXYLOSS /obj/item/restraints/Destroy() if(iscarbon(loc)) @@ -230,24 +230,25 @@ ) AddElement(/datum/element/connect_loc, loc_connections) -/obj/item/restraints/legcuffs/beartrap/update_icon() +/obj/item/restraints/legcuffs/beartrap/update_icon_state() icon_state = "[initial(icon_state)][armed]" + return ..() -/obj/item/restraints/legcuffs/beartrap/suicide_act(mob/user) +/obj/item/restraints/legcuffs/beartrap/suicide_act(mob/living/user) user.visible_message("[user] is sticking [user.p_their()] head in the [src.name]! It looks like [user.p_theyre()] trying to commit suicide!") playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS /obj/item/restraints/legcuffs/beartrap/attack_self(mob/user) ..() if(ishuman(user) && !user.stat && !user.restrained()) armed = !armed - update_icon() + update_appearance() to_chat(user, "[src] is now [armed ? "armed" : "disarmed"]") /obj/item/restraints/legcuffs/beartrap/proc/close_trap() armed = FALSE - update_icon() + update_appearance() playsound(src, 'sound/effects/snap.ogg', 50, TRUE) /obj/item/restraints/legcuffs/beartrap/proc/spring_trap(datum/source, AM as mob|obj) diff --git a/code/game/objects/items/his_grace.dm b/code/game/objects/items/his_grace.dm index e302a94a462a0..c47136f77d836 100644 --- a/code/game/objects/items/his_grace.dm +++ b/code/game/objects/items/his_grace.dm @@ -201,9 +201,9 @@ /obj/item/his_grace/proc/adjust_bloodthirst(amt) prev_bloodthirst = bloodthirst if(prev_bloodthirst < HIS_GRACE_CONSUME_OWNER && !ascended) - bloodthirst = CLAMP(bloodthirst + amt, HIS_GRACE_SATIATED, HIS_GRACE_CONSUME_OWNER) + bloodthirst = clamp(bloodthirst + amt, HIS_GRACE_SATIATED, HIS_GRACE_CONSUME_OWNER) else if(!ascended) - bloodthirst = CLAMP(bloodthirst + amt, HIS_GRACE_CONSUME_OWNER, HIS_GRACE_FALL_ASLEEP) + bloodthirst = clamp(bloodthirst + amt, HIS_GRACE_CONSUME_OWNER, HIS_GRACE_FALL_ASLEEP) update_stats() /obj/item/his_grace/proc/update_stats() diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index 39d03f44ab1e4..7cdd4c7c48c8f 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -298,7 +298,7 @@ on_clear_callback = CALLBACK(src, PROC_REF(on_cult_rune_removed)), \ effects_we_clear = list(/obj/effect/rune, /obj/effect/heretic_rune)) -/obj/item/nullrod/suicide_act(mob/user) +/obj/item/nullrod/suicide_act(mob/living/user) user.visible_message("[user] is killing [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to get closer to god!") return (BRUTELOSS|FIRELOSS) diff --git a/code/game/objects/items/hot_potato.dm b/code/game/objects/items/hot_potato.dm index a2633f5870fd5..9d05a23523b47 100644 --- a/code/game/objects/items/hot_potato.dm +++ b/code/game/objects/items/hot_potato.dm @@ -77,7 +77,7 @@ L.SetImmobilized(0) L.SetParalyzed(0) L.SetUnconscious(0) - L.reagents.add_reagent(/datum/reagent/medicine/muscle_stimulant, CLAMP(5 - L.reagents.get_reagent_amount(/datum/reagent/medicine/muscle_stimulant), 0, 5)) //If you don't have legs or get bola'd, tough luck! + L.reagents.add_reagent(/datum/reagent/medicine/muscle_stimulant, clamp(5 - L.reagents.get_reagent_amount(/datum/reagent/medicine/muscle_stimulant), 0, 5)) //If you don't have legs or get bola'd, tough luck! colorize(L) /obj/item/hot_potato/examine(mob/user) @@ -157,8 +157,9 @@ colorize(null) active = FALSE -/obj/item/hot_potato/update_icon() - icon_state = active? icon_on : icon_off +/obj/item/hot_potato/update_icon_state() + icon_state = active ? icon_on : icon_off + return ..() /obj/item/hot_potato/syndicate detonate_light_range = 4 diff --git a/code/game/objects/items/hourglass.dm b/code/game/objects/items/hourglass.dm index 7451142356fd7..e62d7d8d5c792 100644 --- a/code/game/objects/items/hourglass.dm +++ b/code/game/objects/items/hourglass.dm @@ -29,11 +29,9 @@ to_chat(user,"You stop the [src].") //Sand magically flows back because that's more convinient to use. stop() -/obj/item/hourglass/update_icon() - if(timing_id) - icon_state = "hourglass_active" - else - icon_state = "hourglass_idle" +/obj/item/hourglass/update_icon_state() + icon_state = "hourglass_[timing_id ? "active" : "idle"]" + return ..() /obj/item/hourglass/proc/start() finish_time = world.time + time diff --git a/code/game/objects/items/implants/implant_explosive.dm b/code/game/objects/items/implants/implant_explosive.dm index be032cd839c2d..ee76e644aa2b7 100644 --- a/code/game/objects/items/implants/implant_explosive.dm +++ b/code/game/objects/items/implants/implant_explosive.dm @@ -47,7 +47,8 @@ if(delay <= 7) explosion(src,heavy,medium,weak,weak, flame_range = weak) if(imp_in) - imp_in.gib(1) + imp_in.investigate_log("has been gibbed by an explosive implant.", INVESTIGATE_DEATHS) + imp_in.gib(TRUE) qdel(src) return TRUE timed_explosion() @@ -80,7 +81,8 @@ sleep(delay*0.25) explosion(src,heavy,medium,weak,weak, flame_range = weak) if(imp_in) - imp_in.gib(1) + imp_in.investigate_log("has been gibbed by an explosive implant.", INVESTIGATE_DEATHS) + imp_in.gib(TRUE) qdel(src) /obj/item/implant/explosive/macro diff --git a/code/game/objects/items/implants/implantcase.dm b/code/game/objects/items/implants/implantcase.dm index 8999086d185fc..69004904a9516 100644 --- a/code/game/objects/items/implants/implantcase.dm +++ b/code/game/objects/items/implants/implantcase.dm @@ -14,49 +14,40 @@ var/imp_type -/obj/item/implantcase/update_icon() - if(imp) - icon_state = "implantcase-[imp.implant_color]" - reagents = imp.reagents - else - icon_state = "implantcase-0" - reagents = null - +/obj/item/implantcase/update_icon_state() + icon_state = "implantcase-[imp ? imp.implant_color : 0]" + return ..() -/obj/item/implantcase/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/pen)) +/obj/item/implantcase/attackby(obj/item/used_item, mob/living/user, params) + if(istype(used_item, /obj/item/pen)) if(!user.is_literate()) to_chat(user, "You scribble illegibly on the side of [src]!") return - var/t = stripped_input(user, "What would you like the label to be?", name, null) - if(user.get_active_held_item() != W) + var/new_name = stripped_input(user, "What would you like the label to be?", name, null) + if(user.get_active_held_item() != used_item) return if(!user.canUseTopic(src, BE_CLOSE)) return - if(t) - name = "implant case - '[t]'" + if(new_name) + name = "implant case - '[new_name]'" else name = "implant case" - else if(istype(W, /obj/item/implanter)) - var/obj/item/implanter/I = W - if(I.imp) - if(imp || I.imp.imp_in) - return - I.imp.forceMove(src) - imp = I.imp - I.imp = null - update_icon() - I.update_icon() - else - if(imp) - if(I.imp) - return - imp.forceMove(I) - I.imp = imp - imp = null - update_icon() - I.update_icon() - + else if(istype(used_item, /obj/item/implanter)) + var/obj/item/implanter/used_implanter = used_item + if(used_implanter.imp && !imp) + used_implanter.imp.forceMove(src) + imp = used_implanter.imp + used_implanter.imp = null + update_appearance() + reagents = imp.reagents + used_implanter.update_appearance() + else if(!used_implanter.imp && imp) + imp.forceMove(used_implanter) + used_implanter.imp = imp + imp = null + reagents = null + update_appearance() + used_implanter.update_appearance() else return ..() @@ -64,7 +55,9 @@ . = ..() if(imp_type) imp = new imp_type(src) - update_icon() + update_appearance() + if(imp) + reagents = imp.reagents /obj/item/implantcase/tracking diff --git a/code/game/objects/items/implants/implantchair.dm b/code/game/objects/items/implants/implantchair.dm index 4c8ad227a2ff5..132b29b719923 100644 --- a/code/game/objects/items/implants/implantchair.dm +++ b/code/game/objects/items/implants/implantchair.dm @@ -96,16 +96,18 @@ visible_message("[M] has been implanted by [src].") return TRUE -/obj/machinery/implantchair/update_icon() +/obj/machinery/implantchair/update_icon_state() icon_state = initial(icon_state) if(state_open) icon_state += "_open" if(occupant) icon_state += "_occupied" + return ..() + +/obj/machinery/implantchair/update_overlays() + . = ..() if(ready) - add_overlay("ready") - else - cut_overlays() + . += "ready" /obj/machinery/implantchair/proc/replenish() if(ready_implants < max_implants) diff --git a/code/game/objects/items/implants/implanter.dm b/code/game/objects/items/implants/implanter.dm index bfa06589c23cd..9991c55150a68 100644 --- a/code/game/objects/items/implants/implanter.dm +++ b/code/game/objects/items/implants/implanter.dm @@ -13,17 +13,14 @@ var/obj/item/implant/imp = null var/imp_type = null - -/obj/item/implanter/update_icon() - if(imp) - icon_state = "implanter1" - else - icon_state = "implanter0" - +/obj/item/implanter/update_icon_state() + icon_state = "implanter[imp ? 1 : 0]" + return ..() /obj/item/implanter/attack(mob/living/M, mob/user) if(!istype(M)) return + if(user && imp) if(M != user) M.visible_message("[user] is attempting to implant [M].", \ diff --git a/code/game/objects/items/implants/implantpad.dm b/code/game/objects/items/implants/implantpad.dm index 82fdf8131cb98..800f589742e5f 100644 --- a/code/game/objects/items/implants/implantpad.dm +++ b/code/game/objects/items/implants/implantpad.dm @@ -11,8 +11,9 @@ w_class = WEIGHT_CLASS_SMALL var/obj/item/implantcase/case = null -/obj/item/implantpad/update_icon() +/obj/item/implantpad/update_icon_state() icon_state = "implantpad-[!QDELETED(case)]" + return ..() /obj/item/implantpad/examine(mob/user) . = ..() diff --git a/code/game/objects/items/inducer.dm b/code/game/objects/items/inducer.dm index f0d32cf422051..c56fd8b8574e7 100644 --- a/code/game/objects/items/inducer.dm +++ b/code/game/objects/items/inducer.dm @@ -176,13 +176,13 @@ if(opened) . += "Its battery compartment is open." -/obj/item/inducer/update_icon() - cut_overlays() +/obj/item/inducer/update_overlays() + . = ..() if(opened) if(!cell) - add_overlay("inducer-nobat") + . += "inducer-nobat" else - add_overlay("inducer-bat") + . += "inducer-bat" ///Starts empty for engineering protolathe /obj/item/inducer/eng diff --git a/code/game/objects/items/knives.dm b/code/game/objects/items/knives.dm index 12561ce5fe64e..81203389c7a6f 100644 --- a/code/game/objects/items/knives.dm +++ b/code/game/objects/items/knives.dm @@ -42,11 +42,11 @@ /obj/item/knife/proc/set_butchering() AddComponent(/datum/component/butchering, 8 SECONDS - force, 100, force - 10) //bonus chance increases depending on force -/obj/item/knife/suicide_act(mob/user) +/obj/item/knife/suicide_act(mob/living/user) user.visible_message(pick("[user] is slitting [user.p_their()] wrists with the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.", \ "[user] is slitting [user.p_their()] throat with the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.", \ "[user] is slitting [user.p_their()] stomach open with the [src.name]! It looks like [user.p_theyre()] trying to commit seppuku.")) - return (BRUTELOSS) + return BRUTELOSS /obj/item/knife/ritual name = "ritual knife" @@ -174,6 +174,6 @@ embedding = list("embedded_pain_multiplier" = 6, "embed_chance" = 40, "embedded_fall_chance" = 5, "armour_block" = 30) // Incentive to disengage/stop chasing when stuck attack_verb = list("stuck", "shanked") -/obj/item/knife/shank/suicide_act(mob/user) +/obj/item/knife/shank/suicide_act(mob/living/user) user.visible_message("[user] is slitting [user.p_their()] [pick("wrists", "throat")] with the shank! It looks like [user.p_theyre()] trying to commit suicide.") - return (BRUTELOSS) + return BRUTELOSS diff --git a/code/game/objects/items/manuals.dm b/code/game/objects/items/manuals.dm index 968ce6317c124..07dfcc1e840b8 100644 --- a/code/game/objects/items/manuals.dm +++ b/code/game/objects/items/manuals.dm @@ -409,7 +409,7 @@ title = "Toxins or: How I Learned to Stop Worrying and Love the Maxcap" page_link = "Guide_to_toxins" -/obj/item/book/manual/wiki/toxins/suicide_act(mob/user) +/obj/item/book/manual/wiki/toxins/suicide_act(mob/living/user) var/mob/living/carbon/human/H = user user.visible_message("[user] starts dancing to the Rhumba Beat! It looks like [user.p_theyre()] trying to commit suicide!") playsound(loc, 'sound/effects/spray.ogg', 10, 1, -3) @@ -428,7 +428,7 @@ H.spawn_gibs() H.spill_organs() H.spread_bodyparts() - return (BRUTELOSS) + return BRUTELOSS /obj/item/book/manual/wiki/plumbing name = "Chemical Factories Without Narcotics" @@ -443,3 +443,52 @@ author = "Phillippe French" title = "Xenoarchaeology Fieldguide" page_link = "Guide_to_Artifacts" + +/obj/item/book/manual/wiki/sopcommand + name = "Command Standard Operating Procedures" + icon_state ="sop1" + author = "Nanotrasen Department of Employee Resources" + title = "Command Standard Operating Procedures" + page_link = "Department_Standard_Operating_Procedure:_Command" + +/obj/item/book/manual/wiki/sopsecurity + name = "Security Standard Operating Procedures" + icon_state ="sop2" + author = "Nanotrasen Department of Employee Resources" + title = "Security Standard Operating Procedures" + page_link = "Department_Standard_Operating_Procedure:_Security" + +/obj/item/book/manual/wiki/sopengineering + name = "Engineering Standard Operating Procedures" + icon_state ="sop3" + author = "Nanotrasen Department of Employee Resources" + title = "Engineering Standard Operating Procedures" + page_link = "Department_Standard_Operating_Procedure:_Engineering" + +/obj/item/book/manual/wiki/sopsupply + name = "Supply Standard Operating Procedures" + icon_state ="sop4" + author = "Nanotrasen Department of Employee Resources" + title = "Supply Standard Operating Procedures" + page_link = "Department_Standard_Operating_Procedure:_Supply" + +/obj/item/book/manual/wiki/sopscience + name = "Science Standard Operating Procedures" + icon_state ="sop5" + author = "Nanotrasen Department of Employee Resources" + title = "Science Standard Operating Procedures" + page_link = "Department_Standard_Operating_Procedure:_Science" + +/obj/item/book/manual/wiki/sopmedical + name = "Medical Standard Operating Procedures" + icon_state ="sop6" + author = "Nanotrasen Department of Employee Resources" + title = "Medical Standard Operating Procedures" + page_link = "Department_Standard_Operating_Procedure:_Medical" + +/obj/item/book/manual/wiki/sopservice + name = "Service Standard Operating Procedures" + icon_state ="sop7" + author = "Nanotrasen Department of Employee Resources" + title = "Service Standard Operating Procedures" + page_link = "Department_Standard_Operating_Procedure:_Service" diff --git a/code/game/objects/items/melee/energy.dm b/code/game/objects/items/melee/energy.dm index ba3b679c356fe..f74a0cb7d1734 100644 --- a/code/game/objects/items/melee/energy.dm +++ b/code/game/objects/items/melee/energy.dm @@ -20,7 +20,7 @@ STOP_PROCESSING(SSobj, src) return ..() -/obj/item/melee/transforming/energy/suicide_act(mob/user) +/obj/item/melee/transforming/energy/suicide_act(mob/living/user) if(!active) transform_weapon(user, TRUE) user.visible_message("[user] is [pick("slitting [user.p_their()] stomach open with", "falling on")] [src]! It looks like [user.p_theyre()] trying to commit seppuku!") @@ -84,7 +84,7 @@ attack_verb_on = list() light_color = "#40ceff" -/obj/item/melee/transforming/energy/axe/suicide_act(mob/user) +/obj/item/melee/transforming/energy/axe/suicide_act(mob/living/user) user.visible_message("[user] swings [src] towards [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!") return (BRUTELOSS|FIRELOSS) @@ -135,6 +135,7 @@ w_class = WEIGHT_CLASS_NORMAL sharpness = IS_SHARP light_color = "#40ceff" + tool_behaviour = TOOL_SAW toolspeed = 0.7 //faster as a saw /obj/item/melee/transforming/energy/sword/cyborg diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index 4cb503ea7afe9..6777799073f26 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -25,9 +25,9 @@ hitsound = 'sound/weapons/chainhit.ogg' materials = list(/datum/material/iron = 1000) -/obj/item/melee/chainofcommand/suicide_act(mob/user) +/obj/item/melee/chainofcommand/suicide_act(mob/living/user) user.visible_message("[user] is strangling [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (OXYLOSS) + return OXYLOSS /obj/item/melee/synthetic_arm_blade name = "synthetic arm blade" @@ -355,7 +355,7 @@ return ..() return 0 -/obj/item/melee/classic_baton/telescopic/suicide_act(mob/user) +/obj/item/melee/classic_baton/telescopic/suicide_act(mob/living/user) var/mob/living/carbon/human/H = user var/obj/item/organ/brain/B = H.getorgan(/obj/item/organ/brain) @@ -371,7 +371,7 @@ H.internal_organs -= B qdel(B) new /obj/effect/gibspawner/generic(H.drop_location(), H) - return (BRUTELOSS) + return BRUTELOSS /obj/item/melee/classic_baton/police/telescopic/attack_self(mob/user) on = !on @@ -662,7 +662,7 @@ consume_everything(P) return BULLET_ACT_HIT -/obj/item/melee/supermatter_sword/suicide_act(mob/user) +/obj/item/melee/supermatter_sword/suicide_act(mob/living/user) user.visible_message("[user] touches [src]'s blade. It looks like [user.p_theyre()] tired of waiting for the radiation to kill [user.p_them()]!") user.dropItemToGround(src, TRUE) shard.Bumped(user) @@ -798,12 +798,10 @@ held_sausage = null update_icon() -/obj/item/melee/roastingstick/update_icon() +/obj/item/melee/roastingstick/update_overlays() . = ..() - cut_overlays() if (held_sausage) - var/mutable_appearance/sausage = mutable_appearance(icon, "roastingstick_sausage") - add_overlay(sausage) + . += mutable_appearance(icon, "roastingstick_sausage") /obj/item/melee/roastingstick/proc/extend(user) to_chat(user, "You extend [src].") diff --git a/code/game/objects/items/pet_carrier.dm b/code/game/objects/items/pet_carrier.dm index 5efe3a176391e..a7e7cfefec59a 100644 --- a/code/game/objects/items/pet_carrier.dm +++ b/code/game/objects/items/pet_carrier.dm @@ -6,6 +6,7 @@ name = "pet carrier" desc = "A big white-and-blue pet carrier. Good for carrying meat to the chef cute animals around." icon = 'icons/obj/pet_carrier.dmi' + base_icon_state = "pet_carrier" icon_state = "pet_carrier_open" item_state = "pet_carrier" lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' @@ -142,14 +143,17 @@ update_icon() remove_occupant(user) -/obj/item/pet_carrier/update_icon() - cut_overlay("unlocked") - cut_overlay("locked") +/obj/item/pet_carrier/update_icon_state() if(open) icon_state = initial(icon_state) - else - icon_state = "pet_carrier_[!occupants.len ? "closed" : "occupied"]" - add_overlay("[locked ? "" : "un"]locked") + return ..() + icon_state = "[base_icon_state]_[!occupants.len ? "closed" : "occupied"]" + return ..() + +/obj/item/pet_carrier/update_overlays() + . = ..() + if(!open) + . += "[locked ? "" : "un"]locked" /obj/item/pet_carrier/MouseDrop(atom/over_atom) . = ..() diff --git a/code/game/objects/items/pinpointer.dm b/code/game/objects/items/pinpointer.dm index b1e27989383b0..14e9596a6f145 100644 --- a/code/game/objects/items/pinpointer.dm +++ b/code/game/objects/items/pinpointer.dm @@ -75,12 +75,12 @@ /obj/item/pinpointer/proc/scan_for_target() return -/obj/item/pinpointer/update_icon() - cut_overlays() +/obj/item/pinpointer/update_overlays() + . = ..() if(!active) return if(!target || (!isnull(jamming_resistance) && src.is_jammed(jamming_resistance))) - add_overlay("pinon[alert ? "alert" : ""]null[icon_suffix]") + . += "pinon[alert ? "alert" : ""]null[icon_suffix]" return var/turf/here = get_turf(src) var/turf/there = get_turf(target) @@ -101,15 +101,15 @@ if(pin_z_result) var/result = compare_z(here_zlevel, there_zlevel) if(isnull(result)) // null: no good to track z levels - add_overlay("pinon[alert ? "alert" : ""]null[icon_suffix]") + . += "pinon[alert ? "alert" : ""]null[icon_suffix]" return else if(!result) // FALSE: z-levels are in different groups. (i.e. Station v.s. Lavaland) if(!tracks_grand_z) - add_overlay("pinon[alert ? "alert" : ""]null[icon_suffix]") + . += "pinon[alert ? "alert" : ""]null[icon_suffix]" return else z_level_direction = "located at [SSorbits.get_orbital_map_name_from_z(there_zlevel) || scramble_message_replace_chars("???????", replaceprob=85)]" - add_overlay("pinon[alert ? "alert" : ""]z[icon_suffix]") + . += "pinon[alert ? "alert" : ""]z[icon_suffix]" return else // TRUE: z-levels are in the same group (i.e. multi-floored station) z_level_direction = "located [abs(there_zlevel - here_zlevel)] floors [pin_z_result]" @@ -131,13 +131,13 @@ // building overlays with sprite components - add_overlay(alert ? "pincomp_base_alert[icon_suffix]" : "pincomp_base[icon_suffix]") + . += alert ? "pincomp_base_alert[icon_suffix]" : "pincomp_base[icon_suffix]" if(pin_z_result) - add_overlay("pincomp_z_[pin_z_result][icon_suffix]") - add_overlay("pincomp_arrow_[pin_xy_result][icon_suffix]") + . += "pincomp_z_[pin_z_result][icon_suffix]" + . += "pincomp_arrow_[pin_xy_result][icon_suffix]" if(alert) pin_xy_result = pin_xy_result=="direct" ? "direct_" : "" - add_overlay("pincomp_arrow_[pin_xy_result]alert[icon_suffix]") + . += "pincomp_arrow_[pin_xy_result]alert[icon_suffix]" /obj/item/pinpointer/proc/trackable(atom/target) return checks_trackable_core(src, target, tracks_grand_z, jamming_resistance) diff --git a/code/game/objects/items/pitchfork.dm b/code/game/objects/items/pitchfork.dm index 462111bd1a808..41f97943791cb 100644 --- a/code/game/objects/items/pitchfork.dm +++ b/code/game/objects/items/pitchfork.dm @@ -55,9 +55,9 @@ . = ..() AddComponent(/datum/component/two_handed, force_unwielded=100, force_wielded=500000) // Kills you DEAD -/obj/item/pitchfork/suicide_act(mob/user) +/obj/item/pitchfork/suicide_act(mob/living/user) user.visible_message("[user] impales [user.p_them()]self in [user.p_their()] abdomen with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) + return BRUTELOSS /obj/item/pitchfork/demonic/pickup(mob/living/user) . = ..() diff --git a/code/game/objects/items/pneumaticCannon.dm b/code/game/objects/items/pneumaticCannon.dm index 61a115980ad44..81914cd9ba3d3 100644 --- a/code/game/objects/items/pneumaticCannon.dm +++ b/code/game/objects/items/pneumaticCannon.dm @@ -206,8 +206,8 @@ return target var/x_o = (target.x - starting.x) var/y_o = (target.y - starting.y) - var/new_x = CLAMP((starting.x + (x_o * range_multiplier)), 0, world.maxx) - var/new_y = CLAMP((starting.y + (y_o * range_multiplier)), 0, world.maxy) + var/new_x = clamp((starting.x + (x_o * range_multiplier)), 0, world.maxx) + var/new_y = clamp((starting.y + (y_o * range_multiplier)), 0, world.maxy) var/turf/newtarget = locate(new_x, new_y, starting.z) return newtarget @@ -247,11 +247,11 @@ tank = thetank update_icon() -/obj/item/pneumatic_cannon/update_icon() - cut_overlays() +/obj/item/pneumatic_cannon/update_overlays() + . = ..() if(!tank) return - add_overlay(tank.icon_state) + . += tank.icon_state /obj/item/pneumatic_cannon/proc/fill_with_type(type, amount) if(!ispath(type, /obj) && !ispath(type, /mob)) diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index 1b959715ec7d7..e902adef54df6 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -160,9 +160,9 @@ var/static/list/charge_machines = typecacheof(list(/obj/machinery/cell_charger, /obj/machinery/recharger, /obj/machinery/recharge_station, /obj/machinery/mech_bay_recharge_port)) var/static/list/charge_items = typecacheof(list(/obj/item/stock_parts/cell, /obj/item/gun/energy)) -/obj/item/borg/charger/update_icon() - ..() +/obj/item/borg/charger/update_icon_state() icon_state = "charger_[mode]" + return ..() /obj/item/borg/charger/attack_self(mob/user) if(mode == MODE_DRAW) @@ -170,7 +170,7 @@ else mode = MODE_DRAW balloon_alert(user, "You toggle [src] to [mode] mode") - update_icon() + update_appearance() /obj/item/borg/charger/afterattack(obj/item/target, mob/living/silicon/robot/user, proximity_flag) . = ..() @@ -684,11 +684,12 @@ to_chat(user, "[src]'s safety cutoff prevents you from activating it due to living beings being ontop of you!") else deactivate_field() - update_icon() + update_appearance() to_chat(user, "You [active? "activate":"deactivate"] [src].") -/obj/item/borg/projectile_dampen/update_icon() +/obj/item/borg/projectile_dampen/update_icon_state() icon_state = "[initial(icon_state)][active]" + return ..() /obj/item/borg/projectile_dampen/proc/activate_field() if(istype(dampening_field)) @@ -747,7 +748,7 @@ continue usage += projectile_tick_speed_ecost * delta_time usage += (tracked[I] * projectile_damage_tick_ecost_coefficient * delta_time) - energy = CLAMP(energy - usage, 0, maxenergy) + energy = clamp(energy - usage, 0, maxenergy) if(energy <= 0) deactivate_field() visible_message("[src] blinks \"ENERGY DEPLETED\".") @@ -757,7 +758,7 @@ if(iscyborg(host.loc)) host = host.loc else - energy = CLAMP(energy + energy_recharge * delta_time, 0, maxenergy) + energy = clamp(energy + energy_recharge * delta_time, 0, maxenergy) return if(host.cell && (host.cell.charge >= (host.cell.maxcharge * cyborg_cell_critical_percentage)) && (energy < maxenergy)) host.cell.use(energy_recharge * delta_time * energy_recharge_cyborg_drain_coefficient) @@ -955,23 +956,22 @@ . += "Nothing." . += "Alt-click will drop the currently stored [stored].
" -/obj/item/borg/apparatus/beaker/update_icon() - cut_overlays() +/obj/item/borg/apparatus/beaker/update_overlays() + . = ..() + var/mutable_appearance/arm = mutable_appearance(icon = icon, icon_state = "borg_beaker_apparatus_arm") if(stored) COMPILE_OVERLAYS(stored) stored.pixel_x = 0 stored.pixel_y = 0 - var/image/img = image("icon"=stored, "layer"=FLOAT_LAYER) - var/image/arm = image("icon"="borg_beaker_apparatus_arm", "layer"=FLOAT_LAYER) + var/mutable_appearance/stored_copy = new /mutable_appearance(stored) if(istype(stored, /obj/item/reagent_containers/glass/beaker)) arm.pixel_y = arm.pixel_y - 3 - img.plane = FLOAT_PLANE - add_overlay(img) - add_overlay(arm) + stored_copy.layer = FLOAT_LAYER + stored_copy.plane = FLOAT_PLANE + . += stored_copy else - var/image/arm = image("icon"="borg_beaker_apparatus_arm", "layer"=FLOAT_LAYER) arm.pixel_y = arm.pixel_y - 5 - add_overlay(arm) + . += arm /obj/item/borg/apparatus/beaker/attack_self(mob/living/silicon/robot/user) if(stored && !user.client?.keys_held["Alt"] && user.a_intent != "help") @@ -1000,24 +1000,20 @@ . = ..() update_icon() -/obj/item/borg/apparatus/circuit/update_icon() - cut_overlays() +/obj/item/borg/apparatus/circuit/update_overlays() + . = ..() + var/mutable_appearance/arm = mutable_appearance(icon, "borg_hardware_apparatus_arm1") if(stored) COMPILE_OVERLAYS(stored) stored.pixel_x = -3 stored.pixel_y = 0 - var/image/arm - if(istype(stored, /obj/item/circuitboard)) - arm = image("icon"="borg_hardware_apparatus_arm1", "layer"=FLOAT_LAYER) - else - arm = image("icon"="borg_hardware_apparatus_arm2", "layer"=FLOAT_LAYER) - var/image/img = image("icon"=stored, "layer"=FLOAT_LAYER) - img.plane = FLOAT_PLANE - add_overlay(arm) - add_overlay(img) - else - var/image/arm = image("icon"="borg_hardware_apparatus_arm1", "layer"=FLOAT_LAYER) - add_overlay(arm) + if(!istype(stored, /obj/item/circuitboard)) + arm.icon_state = "borg_hardware_apparatus_arm2" + var/mutable_appearance/stored_copy = new /mutable_appearance(stored) + stored_copy.layer = FLOAT_LAYER + stored_copy.plane = FLOAT_PLANE + . += stored_copy + . += arm /obj/item/borg/apparatus/circuit/examine() . = ..() diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index ea09a028e6856..d593e23866fdd 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -40,20 +40,20 @@ chest.cell = new /obj/item/stock_parts/cell/high/plus(chest) update_icon() -/obj/item/robot_suit/update_icon() - cut_overlays() +/obj/item/robot_suit/update_overlays() + . = ..() if(l_arm) - add_overlay("[l_arm.icon_state]+o") + . += "[l_arm.icon_state]+o" if(r_arm) - add_overlay("[r_arm.icon_state]+o") + . += "[r_arm.icon_state]+o" if(chest) - add_overlay("[chest.icon_state]+o") + . += "[chest.icon_state]+o" if(l_leg) - add_overlay("[l_leg.icon_state]+o") + . += "[l_leg.icon_state]+o" if(r_leg) - add_overlay("[r_leg.icon_state]+o") + . += "[r_leg.icon_state]+o" if(head) - add_overlay("[head.icon_state]+o") + . += "[head.icon_state]+o" /obj/item/robot_suit/proc/check_completion() if(src.l_arm && src.r_arm) @@ -327,8 +327,7 @@ O.robot_suit = src if(!locomotion) - O.lockcharge = TRUE - O.update_mobility() + O.set_lockcharge(TRUE) to_chat(O, "Error: Servo motors unresponsive.") else @@ -369,8 +368,7 @@ forceMove(O) O.robot_suit = src if(!locomotion) - O.lockcharge = TRUE - O.update_mobility() + O.set_lockcharge(TRUE) else if(istype(W, /obj/item/pen)) to_chat(user, "You need to use a multitool to name [src]!") diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 10f26f65e92f3..9094c2668aa7e 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -384,22 +384,20 @@ playsound(cyborg.loc, 'sound/effects/turbolift/turbolift-close.ogg', 90) to_chat(cyborg, "You deactivate the self-repair module.") STOP_PROCESSING(SSobj, src) - update_icon() + update_appearance() -/obj/item/borg/upgrade/selfrepair/update_icon() +/obj/item/borg/upgrade/selfrepair/update_icon_state() if(cyborg) icon_state = "selfrepair_[on ? "on" : "off"]" - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() else icon_state = "cyborg_upgrade5" + return ..() /obj/item/borg/upgrade/selfrepair/proc/deactivate_sr() playsound(cyborg.loc, 'sound/effects/turbolift/turbolift-close.ogg', 90) STOP_PROCESSING(SSobj, src) on = FALSE - update_icon() + update_appearance() /obj/item/borg/upgrade/selfrepair/process() if(world.time < next_repair) diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index 4bb85d92ddfba..f70000d5dbb90 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -193,6 +193,10 @@ . = ..() embedded_flash = new(src) +/obj/item/shield/riot/flash/ComponentInitialize() + . = .. () + AddElement(/datum/element/update_icon_updates_onmob) + /obj/item/shield/riot/flash/attack(mob/living/M, mob/user) . = embedded_flash.attack(M, user) update_icon() @@ -232,13 +236,14 @@ embedded_flash.emp_act(severity) update_icon() -/obj/item/shield/riot/flash/update_icon() +/obj/item/shield/riot/flash/update_icon_state() if(!embedded_flash || embedded_flash.burnt_out) icon_state = "riot" item_state = "riot" else icon_state = "flashshield" item_state = "flashshield" + return ..() /obj/item/shield/riot/flash/examine(mob/user) . = ..() diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 988b1341f3313..71d41d697e3cd 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -95,7 +95,7 @@ user.visible_message("[user] starts to apply [src] on [user.p_them()]self...", "You begin applying [src] on yourself...") if(!do_after(user, self_delay, M)) return - //After the do_mob to ensure metabolites have had time to process at least one tick. + //After the do_mob to ensure metabolites have had time to process at least one tick. if(reagent && (C.reagents.get_reagent_amount(/datum/reagent/metabolite/medicine/styptic_powder) || C.reagents.get_reagent_amount(/datum/reagent/metabolite/medicine/silver_sulfadiazine))) to_chat(user, "That stuff really hurt! You'll need to wait for the pain to go away before you can apply [src] to your wounds again, maybe someone else can help put it on for you.") return @@ -125,9 +125,9 @@ /obj/item/stack/medical/bruise_pack/one amount = 1 -/obj/item/stack/medical/bruise_pack/suicide_act(mob/user) +/obj/item/stack/medical/bruise_pack/suicide_act(mob/living/user) user.visible_message("[user] is bludgeoning [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) + return BRUTELOSS /obj/item/stack/medical/ointment name = "ointment" diff --git a/code/game/objects/items/stacks/rods/rods.dm b/code/game/objects/items/stacks/rods/rods.dm index c4740895e710c..3376a344309fe 100644 --- a/code/game/objects/items/stacks/rods/rods.dm +++ b/code/game/objects/items/stacks/rods/rods.dm @@ -37,9 +37,10 @@ if(proximity_flag) target.attackby(src, user, click_parameters) -/obj/item/stack/rods/update_icon() +/obj/item/stack/rods/update_icon_state() + . = ..() var/amount = get_amount() - if((amount <= 5) && (amount > 0)) + if(amount <= 5) icon_state = "rods-[amount]" else icon_state = "rods" diff --git a/code/game/objects/items/stacks/rods/rods_recipes.dm b/code/game/objects/items/stacks/rods/rods_recipes.dm index bf94b9308c076..39e5a34cc6ce5 100644 --- a/code/game/objects/items/stacks/rods/rods_recipes.dm +++ b/code/game/objects/items/stacks/rods/rods_recipes.dm @@ -12,7 +12,8 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \ is_cyborg = 1 cost = 250 -/obj/item/stack/rods/cyborg/update_icon() - return +/obj/item/stack/rods/cyborg/ComponentInitialize() + . = ..() + AddElement(/datum/element/update_icon_blocker) STACKSIZE_MACRO(/obj/item/stack/rods) diff --git a/code/game/objects/items/stacks/sheets/mineral/glass.dm b/code/game/objects/items/stacks/sheets/mineral/glass.dm index accee2d559f84..7acb5fb24fc6d 100644 --- a/code/game/objects/items/stacks/sheets/mineral/glass.dm +++ b/code/game/objects/items/stacks/sheets/mineral/glass.dm @@ -206,9 +206,9 @@ embedding = list("embed_chance" = 65) -/obj/item/shard/suicide_act(mob/user) +/obj/item/shard/suicide_act(mob/living/user) user.visible_message("[user] is slitting [user.p_their()] [pick("wrists", "throat")] with the shard of glass! It looks like [user.p_theyre()] trying to commit suicide.") - return (BRUTELOSS) + return BRUTELOSS /obj/item/shard/Initialize(mapload) diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index e51845d150755..177985ea11379 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -85,21 +85,22 @@ /obj/item/stack/proc/update_weight() if(amount <= (max_amount * (1/3))) - w_class = CLAMP(full_w_class-2, WEIGHT_CLASS_TINY, full_w_class) + w_class = clamp(full_w_class-2, WEIGHT_CLASS_TINY, full_w_class) else if(amount <= (max_amount * (2/3))) - w_class = CLAMP(full_w_class-1, WEIGHT_CLASS_TINY, full_w_class) + w_class = clamp(full_w_class-1, WEIGHT_CLASS_TINY, full_w_class) else w_class = full_w_class -/obj/item/stack/update_icon() +/obj/item/stack/update_icon_state() if(novariants) - return ..() + return if(amount <= (max_amount * (1/3))) icon_state = initial(icon_state) - else if(amount <= (max_amount * (2/3))) + return ..() + if(amount <= (max_amount * (2/3))) icon_state = "[initial(icon_state)]_2" - else - icon_state = "[initial(icon_state)]_3" + return ..() + icon_state = "[initial(icon_state)]_3" return ..() /obj/item/stack/examine(mob/user) diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 9ade0c512a85d..2395c65aef8ad 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -66,6 +66,7 @@ user.Stun(100, ignore_canstun = TRUE) sleep(20) playsound(src, "rustle", 50, 1, -5) + user.suicide_log() qdel(user) /obj/item/storage/backpack/holding/singularity_act(current_size) @@ -110,9 +111,9 @@ STR.max_w_class = WEIGHT_CLASS_NORMAL STR.max_combined_w_class = 60 -/obj/item/storage/backpack/santabag/suicide_act(mob/user) +/obj/item/storage/backpack/santabag/suicide_act(mob/living/user) user.visible_message("[user] places [src] over [user.p_their()] head and pulls it tight! It looks like [user.p_they()] [user.p_are()]n't in the Christmas spirit...") - return (OXYLOSS) + return OXYLOSS /obj/item/storage/backpack/santabag/proc/regenerate_presents() addtimer(CALLBACK(src, PROC_REF(regenerate_presents)), 30 SECONDS) @@ -581,7 +582,7 @@ desc = "A large duffel bag containing a Bulldog, some drums, and a pair of thermal imaging glasses." /obj/item/storage/backpack/duffelbag/syndie/bulldogbundle/PopulateContents() - new /obj/item/gun/ballistic/shotgun/bulldog(src) + new /obj/item/gun/ballistic/shotgun/automatic/bulldog(src) new /obj/item/ammo_box/magazine/m12g(src) new /obj/item/ammo_box/magazine/m12g(src) new /obj/item/clothing/glasses/thermal/syndi(src) diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm index 129bb471d4a1c..cddcee9523247 100644 --- a/code/game/objects/items/storage/bags.dm +++ b/code/game/objects/items/storage/bags.dm @@ -52,19 +52,22 @@ STR.cant_hold = typecacheof(list(/obj/item/disk/nuclear)) STR.can_be_opened = FALSE //Have to dump a trash bag out to look at its contents -/obj/item/storage/bag/trash/suicide_act(mob/user) +/obj/item/storage/bag/trash/suicide_act(mob/living/user) user.visible_message("[user] puts [src] over [user.p_their()] head and starts chomping at the insides! Disgusting!") playsound(loc, 'sound/items/eatfood.ogg', 50, 1, -1) - return (TOXLOSS) - -/obj/item/storage/bag/trash/update_icon() - if(contents.len == 0) - icon_state = "[initial(icon_state)]" - else if(contents.len < 12) - icon_state = "[initial(icon_state)]1" - else if(contents.len < 21) - icon_state = "[initial(icon_state)]2" - else icon_state = "[initial(icon_state)]3" + return TOXLOSS + +/obj/item/storage/bag/trash/update_icon_state() + switch(contents.len) + if(20 to INFINITY) + icon_state = "[initial(icon_state)]3" + if(11 to 20) + icon_state = "[initial(icon_state)]2" + if(1 to 11) + icon_state = "[initial(icon_state)]1" + else + icon_state = "[initial(icon_state)]" + return ..() /obj/item/storage/bag/trash/cyborg insertable = FALSE @@ -364,10 +367,13 @@ source.lifetime = count * new_delay source.delay = new_delay -/obj/item/storage/bag/tray/update_icon() - cut_overlays() +/obj/item/storage/bag/tray/update_overlays() + . = ..() for(var/obj/item/I in contents) - add_overlay(new /mutable_appearance(I)) + var/mutable_appearance/I_copy = new(I) + I_copy.plane = FLOAT_PLANE + I_copy.layer = FLOAT_LAYER + . += I_copy /obj/item/storage/bag/tray/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs) . = ..() diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 91ee8cce36fcb..e409ed4788fe3 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -16,13 +16,11 @@ user.visible_message("[user] begins belting [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") return BRUTELOSS -/obj/item/storage/belt/update_icon() - cut_overlays() +/obj/item/storage/belt/update_overlays() + . = ..() if(content_overlays) for(var/obj/item/I in contents) - var/mutable_appearance/M = I.get_belt_overlay() - add_overlay(M) - ..() + . += I.get_belt_overlay() /obj/item/storage/belt/Initialize(mapload) . = ..() @@ -541,9 +539,9 @@ /obj/item/reagent_containers/food/snacks/syndicake, /obj/item/reagent_containers/food/snacks/spacetwinkie, /obj/item/reagent_containers/food/snacks/cheesiehonkers, - /obj/item/reagent_containers/food/snacks/nachos, - /obj/item/reagent_containers/food/snacks/cheesynachos, - /obj/item/reagent_containers/food/snacks/cubannachos, + /obj/item/food/nachos, + /obj/item/food/cheesynachos, + /obj/item/food/cubannachos, /obj/item/reagent_containers/food/snacks/nugget, /obj/item/food/spaghetti/pastatomato, /obj/item/reagent_containers/food/snacks/rofflewaffles, @@ -836,6 +834,7 @@ /obj/item/storage/belt/sabre/ComponentInitialize() . = ..() + AddElement(/datum/element/update_icon_updates_onmob) var/datum/component/storage/STR = GetComponent(/datum/component/storage) STR.max_items = 1 STR.rustle_sound = FALSE @@ -857,11 +856,11 @@ var/obj/item/I = contents[1] user.visible_message("[user] takes [I] out of [src].", "You take [I] out of [src].") user.put_in_hands(I) - update_icon() + update_appearance() else to_chat(user, "[src] is empty.") -/obj/item/storage/belt/sabre/update_icon() +/obj/item/storage/belt/sabre/update_icon_state() icon_state = initial(icon_state) item_state = initial(item_state) worn_icon_state = initial(worn_icon_state) @@ -869,14 +868,11 @@ icon_state += "-sabre" item_state += "-sabre" worn_icon_state += "-sabre" - if(loc && isliving(loc)) - var/mob/living/L = loc - L.regenerate_icons() - ..() + return ..() /obj/item/storage/belt/sabre/PopulateContents() new /obj/item/melee/sabre(src) - update_icon() + update_appearance() /obj/item/storage/belt/sabre/mime name = "Baguette" diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm index ca57ac8d7251d..838735bb692ab 100644 --- a/code/game/objects/items/storage/book.dm +++ b/code/game/objects/items/storage/book.dm @@ -40,9 +40,9 @@ . = ..() AddComponent(/datum/component/anti_magic, FALSE, TRUE, _allowed_slots = ITEM_SLOT_HANDS) -/obj/item/storage/book/bible/suicide_act(mob/user) +/obj/item/storage/book/bible/suicide_act(mob/living/user) user.visible_message("[user] is offering [user.p_them()]self to [deity_name]! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) + return BRUTELOSS /obj/item/storage/book/bible/attack_self(mob/living/carbon/human/H) if(!istype(H)) diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm index ce233af042a19..3221b2eb8b2ed 100644 --- a/code/game/objects/items/storage/boxes.dm +++ b/code/game/objects/items/storage/boxes.dm @@ -50,11 +50,10 @@ user.visible_message("[user] beating [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") return BRUTELOSS -/obj/item/storage/box/update_icon() +/obj/item/storage/box/update_overlays() . = ..() if(illustration) - cut_overlays() - add_overlay(illustration) + . += illustration /obj/item/storage/box/attack_self(mob/user) ..() @@ -834,9 +833,9 @@ illustration = "heart" foldable = null -/obj/item/storage/box/hug/suicide_act(mob/user) +/obj/item/storage/box/hug/suicide_act(mob/living/user) user.visible_message("[user] clamps the box of hugs on [user.p_their()] jugular! Guess it wasn't such a hugbox after all..") - return (BRUTELOSS) + return BRUTELOSS /obj/item/storage/box/hug/attack_self(mob/user) ..() @@ -960,10 +959,12 @@ foldable = null var/design = NODESIGN -/obj/item/storage/box/papersack/update_icon() +/obj/item/storage/box/papersack/update_icon_state() if(contents.len == 0) icon_state = "[item_state]" - else icon_state = "[item_state]_closed" + else + icon_state = "[item_state]_closed" + return ..() /obj/item/storage/box/papersack/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/pen)) @@ -1052,7 +1053,7 @@ theme_name = "fiesta" /obj/item/storage/box/ingredients/fiesta/PopulateContents() - new /obj/item/reagent_containers/food/snacks/tortilla(src) + new /obj/item/food/tortilla(src) for(var/i in 1 to 2) new /obj/item/reagent_containers/food/snacks/grown/corn(src) new /obj/item/reagent_containers/food/snacks/grown/soybeans(src) diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm index 6086e37c675f4..02596917bc03d 100644 --- a/code/game/objects/items/storage/fancy.dm +++ b/code/game/objects/items/storage/fancy.dm @@ -29,11 +29,12 @@ for(var/i = 1 to STR.max_items) new spawn_type(src) -/obj/item/storage/fancy/update_icon() +/obj/item/storage/fancy/update_icon_state() if(fancy_open) icon_state = "[icon_type]box[contents.len]" else icon_state = "[icon_type]box" + return ..() /obj/item/storage/fancy/examine(mob/user) . = ..() @@ -68,7 +69,7 @@ icon_type = "donut" name = "donut box" desc = "Mmm. Donuts." - spawn_type = /obj/item/reagent_containers/food/snacks/donut + spawn_type = /obj/item/reagent_containers/food/snacks/donut/premade fancy_open = TRUE /obj/item/storage/fancy/donut_box/ComponentInitialize() @@ -109,8 +110,8 @@ icon_state = "candlebox5" icon_type = "candle" item_state = "candlebox5" + w_class = WEIGHT_CLASS_NORMAL throwforce = 2 - slot_flags = ITEM_SLOT_BELT spawn_type = /obj/item/candle fancy_open = TRUE @@ -118,6 +119,7 @@ . = ..() var/datum/component/storage/STR = GetComponent(/datum/component/storage) STR.max_items = 5 + STR.can_hold = typecacheof(list(/obj/item/candle, /obj/item/lighter, /obj/item/storage/box/matches)) /obj/item/storage/fancy/candle_box/attack_self(mob_user) return @@ -174,30 +176,34 @@ else to_chat(user, "There is no lighter in the pack.") -/obj/item/storage/fancy/cigarettes/update_icon() +/obj/item/storage/fancy/cigarettes/update_icon_state() + . = ..() if(fancy_open || !contents.len) - cut_overlays() if(!contents.len) icon_state = "[initial(icon_state)]_empty" else icon_state = initial(icon_state) - add_overlay("[icon_state]_open") - var/cig_position = 1 - for(var/C in contents) - var/mutable_appearance/inserted_overlay = mutable_appearance(icon) - - if(istype(C, /obj/item/lighter/greyscale)) - inserted_overlay.icon_state = "lighter_in" - else if(istype(C, /obj/item/lighter)) - inserted_overlay.icon_state = "zippo_in" - else - inserted_overlay.icon_state = "cigarette" - - inserted_overlay.icon_state = "[inserted_overlay.icon_state]_[cig_position]" - add_overlay(inserted_overlay) - cig_position++ - else - cut_overlays() + +/obj/item/storage/fancy/cigarettes/update_overlays() + . = ..() + if(fancy_open && contents.len) + . += "[icon_state]_open" + var/cig_position = 1 + for(var/C in contents) + var/mutable_appearance/inserted_overlay = mutable_appearance(icon) + + if(istype(C, /obj/item/lighter/greyscale)) + inserted_overlay.icon_state = "lighter_in" + else if(istype(C, /obj/item/lighter)) + inserted_overlay.icon_state = "zippo_in" + //else if(candy) + // inserted_overlay.icon_state = "candy" + else + inserted_overlay.icon_state = "cigarette" + + inserted_overlay.icon_state = "[inserted_overlay.icon_state]_[cig_position]" + . += inserted_overlay + cig_position++ /obj/item/storage/fancy/cigarettes/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) if(!ismob(M)) @@ -293,10 +299,10 @@ STR.max_items = 10 STR.can_hold = typecacheof(list(/obj/item/rollingpaper)) -/obj/item/storage/fancy/rollingpapers/update_icon() - cut_overlays() +/obj/item/storage/fancy/rollingpapers/update_overlays() + . = ..() if(!contents.len) - add_overlay("[icon_state]_empty") + . += "[icon_state]_empty" ///////////// //CIGAR BOX// @@ -318,19 +324,20 @@ STR.can_hold = typecacheof(list(/obj/item/clothing/mask/cigarette/cigar)) /obj/item/storage/fancy/cigarettes/cigars/update_icon() - cut_overlays() if(fancy_open) icon_state = "[initial(icon_state)]_open" + else + icon_state = "[initial(icon_state)]" +/obj/item/storage/fancy/cigarettes/cigars/update_overlays() + . = ..() + if(fancy_open) var/cigar_position = 1 //generate sprites for cigars in the box for(var/obj/item/clothing/mask/cigarette/cigar/smokes in contents) var/mutable_appearance/cigar_overlay = mutable_appearance(icon, "[smokes.icon_off]_[cigar_position]") - add_overlay(cigar_overlay) + . += cigar_overlay cigar_position++ - else - icon_state = "[initial(icon_state)]" - /obj/item/storage/fancy/cigarettes/cigars/cohiba name = "\improper Cohiba Robusto cigar case" desc = "A case of imported Cohiba cigars, renowned for their strong flavor." diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index 615419e31acfd..325d45fb3394d 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -453,9 +453,9 @@ STR.click_gather = TRUE STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/dice)) -/obj/item/storage/pill_bottle/suicide_act(mob/user) +/obj/item/storage/pill_bottle/suicide_act(mob/living/user) user.visible_message("[user] is trying to get the cap off [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (TOXLOSS) + return TOXLOSS /obj/item/storage/pill_bottle/charcoal name = "bottle of charcoal pills" diff --git a/code/game/objects/items/storage/lockbox.dm b/code/game/objects/items/storage/lockbox.dm index 6bca42420136f..5df956d461d46 100644 --- a/code/game/objects/items/storage/lockbox.dm +++ b/code/game/objects/items/storage/lockbox.dm @@ -117,13 +117,11 @@ for(var/i in 1 to 3) new /obj/item/clothing/accessory/medal/conduct(src) -/obj/item/storage/lockbox/medal/update_icon() - cut_overlays() +/obj/item/storage/lockbox/medal/update_icon_state() var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED) if(locked) icon_state = "[base_icon_state]+l" item_state = "[base_icon_state]+l" - open = FALSE else icon_state = "[base_icon_state]" item_state = "[base_icon_state]" @@ -132,16 +130,24 @@ if(broken) icon_state += "+b" item_state = "[base_icon_state]+b" - if(contents && open) - for (var/i in 1 to contents.len) - var/obj/item/clothing/accessory/medal/M = contents[i] - var/mutable_appearance/medalicon = mutable_appearance(initial(icon), M.medaltype) - if(i > 1 && i <= 5) - medalicon.pixel_x += ((i-1)*4) - else if(i > 5) - medalicon.pixel_y -= 7 - medalicon.pixel_x += ((i-6)*4) - add_overlay(medalicon) + return ..() + +/obj/item/storage/lockbox/medal/update_overlays() + . = ..() + if(!contents || !open) + return + var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED) + if(locked) + return + for (var/i in 1 to contents.len) + var/obj/item/clothing/accessory/medal/M = contents[i] + var/mutable_appearance/medalicon = mutable_appearance(initial(icon), M.medaltype) + if(i > 1 && i <= 5) + medalicon.pixel_x += ((i-1)*4) + else if(i > 5) + medalicon.pixel_y -= 7 + medalicon.pixel_x += ((i-6)*4) + . += medalicon /obj/item/storage/lockbox/medal/sec name = "security medal box" diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index 2d5b4f8ec0eec..f57bfda3cb2fb 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -30,16 +30,15 @@ latches = "triple_latch" update_icon() -/obj/item/storage/toolbox/update_icon() - ..() - cut_overlays() +/obj/item/storage/toolbox/update_overlays() + . = ..() if(has_latches) - add_overlay(latches) + . += latches -/obj/item/storage/toolbox/suicide_act(mob/user) +/obj/item/storage/toolbox/suicide_act(mob/living/user) user.visible_message("[user] robusts [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) + return BRUTELOSS /obj/item/storage/toolbox/emergency name = "emergency toolbox" diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm index 33d6321ea8ece..6e10be5442d00 100644 --- a/code/game/objects/items/storage/uplink_kits.dm +++ b/code/game/objects/items/storage/uplink_kits.dm @@ -118,7 +118,7 @@ if("metaops") new /obj/item/clothing/suit/space/hardsuit/syndi(src) // 8 tc - new /obj/item/gun/ballistic/shotgun/bulldog/unrestricted(src) // 8 tc + new /obj/item/gun/ballistic/shotgun/automatic/bulldog/unrestricted(src) // 8 tc new /obj/item/implanter/explosive(src) // 2 tc new /obj/item/ammo_box/magazine/m12g(src) // 2 tc new /obj/item/ammo_box/magazine/m12g(src) // 2 tc diff --git a/code/game/objects/items/storage/wallets.dm b/code/game/objects/items/storage/wallets.dm index 477b5df0f46ee..61dfadfc94014 100644 --- a/code/game/objects/items/storage/wallets.dm +++ b/code/game/objects/items/storage/wallets.dm @@ -43,6 +43,7 @@ /obj/item/storage/wallet/proc/refreshID() LAZYCLEARLIST(combined_access) + if(!(front_id in src)) front_id = null for(var/obj/item/card/id/I in contents) diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index 62af59007e1cc..475cb3f6a910a 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -23,9 +23,9 @@ /obj/item/melee/baton/get_cell() return cell -/obj/item/melee/baton/suicide_act(mob/user) +/obj/item/melee/baton/suicide_act(mob/living/user) user.visible_message("[user] is putting the live [name] in [user.p_their()] mouth! It looks like [user.p_theyre()] trying to commit suicide!") - return (FIRELOSS) + return FIRELOSS /obj/item/melee/baton/Initialize(mapload) . = ..() @@ -71,7 +71,7 @@ playsound(src, "sparks", 75, TRUE, -1) -/obj/item/melee/baton/update_icon() +/obj/item/melee/baton/update_icon_state() if(obj_flags & OBJ_EMPED) icon_state = "[initial(icon_state)]" else if(turned_on) @@ -80,6 +80,7 @@ icon_state = "[initial(icon_state)]_nocell" else icon_state = "[initial(icon_state)]" + return ..() /obj/item/melee/baton/examine(mob/user) . = ..() diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm index 8e946e4fb370a..793c43a44f1c8 100644 --- a/code/game/objects/items/tanks/jetpack.dm +++ b/code/game/objects/items/tanks/jetpack.dm @@ -52,9 +52,7 @@ else turn_off(user) to_chat(user, "You turn the jetpack off.") - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() /obj/item/tank/jetpack/equipped(mob/user, slot) ..() @@ -133,14 +131,13 @@ return TRUE -/obj/item/tank/jetpack/suicide_act(mob/user) - if (istype(user, /mob/living/carbon/human/)) - var/mob/living/carbon/human/H = user - H.say(";WHAT THE FUCK IS CARBON DIOXIDE?", forced="jetpack suicide") - H.visible_message("[user] is suffocating [user.p_them()]self with [src]! It looks like [user.p_they()] didn't read what that jetpack says!") - return (OXYLOSS) - else - ..() +/obj/item/tank/jetpack/suicide_act(mob/living/user) + if (!ishuman(user)) + return + var/mob/living/carbon/human/H = user + H.say(";WHAT THE FUCK IS CARBON DIOXIDE?", forced="jetpack suicide") + H.visible_message("[user] is suffocating [user.p_them()]self with [src]! It looks like [user.p_they()] didn't read what that jetpack says!") + return OXYLOSS /obj/item/tank/jetpack/improvised name = "improvised jetpack" diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index 2ebdc264ddadb..11e41735ed6a6 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -128,25 +128,25 @@ playsound(src.loc, 'sound/effects/spray.ogg', 10, 1, -3) qdel(src) -/obj/item/tank/suicide_act(mob/user) - var/mob/living/carbon/human/H = user +/obj/item/tank/suicide_act(mob/living/user) + var/mob/living/carbon/human/human_user = user user.visible_message("[user] is putting [src]'s valve to [user.p_their()] lips! It looks like [user.p_theyre()] trying to commit suicide!") playsound(loc, 'sound/effects/spray.ogg', 10, 1, -3) - if (!QDELETED(H) && air_contents && air_contents.return_pressure() >= 1000) - for(var/obj/item/W in H) - H.dropItemToGround(W) + if (!QDELETED(human_user) && air_contents && air_contents.return_pressure() >= 1000) + for(var/obj/item/W in human_user) + human_user.dropItemToGround(W) if(prob(50)) step(W, pick(GLOB.alldirs)) - ADD_TRAIT(H, TRAIT_DISFIGURED, TRAIT_GENERIC) - H.bleed_rate = 5 - H.gib_animation() + ADD_TRAIT(human_user, TRAIT_DISFIGURED, TRAIT_GENERIC) + human_user.bleed_rate = 5 + human_user.gib_animation() sleep(3) - H.adjustBruteLoss(1000) //to make the body super-bloody - H.spawn_gibs() - H.spill_organs() - H.spread_bodyparts() + human_user.adjustBruteLoss(1000) //to make the body super-bloody + human_user.spawn_gibs() + human_user.spill_organs() + human_user.spread_bodyparts() - return (BRUTELOSS) + return BRUTELOSS /obj/item/tank/attackby(obj/item/W, mob/user, params) add_fingerprint(user) @@ -204,7 +204,7 @@ pressure = text2num(pressure) . = TRUE if(.) - distribute_pressure = CLAMP(round(pressure), TANK_MIN_RELEASE_PRESSURE, TANK_MAX_RELEASE_PRESSURE) + distribute_pressure = clamp(round(pressure), TANK_MIN_RELEASE_PRESSURE, TANK_MAX_RELEASE_PRESSURE) /obj/item/tank/remove_air(amount) return air_contents.remove(amount) diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index d1dee414c8895..a3607fa5188e8 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -251,7 +251,7 @@ return DESTINATION_PORTAL return FALSE -/obj/item/hand_tele/suicide_act(mob/user) +/obj/item/hand_tele/suicide_act(mob/living/user) if(iscarbon(user)) user.visible_message("[user] is creating a weak portal and sticking [user.p_their()] head through! It looks like [user.p_theyre()] trying to commit suicide!") var/mob/living/carbon/itemUser = user @@ -263,7 +263,7 @@ itemUser.visible_message("The portal snaps closed taking [user]'s head with it!") else itemUser.visible_message("[user] looks even further depressed as they realize they do not have a head...and suddenly dies of shame!") - return (BRUTELOSS) + return BRUTELOSS /* * Syndicate Teleporter diff --git a/code/game/objects/items/theft_tools.dm b/code/game/objects/items/theft_tools.dm index f22f9a5e77ca4..e92289f30efa1 100644 --- a/code/game/objects/items/theft_tools.dm +++ b/code/game/objects/items/theft_tools.dm @@ -36,9 +36,9 @@ flick(pulseicon, src) radiation_pulse(src, 400, 2) -/obj/item/nuke_core/suicide_act(mob/user) +/obj/item/nuke_core/suicide_act(mob/living/user) user.visible_message("[user] is rubbing [src] against [user.p_them()]self! It looks like [user.p_theyre()] trying to commit suicide!") - return (TOXLOSS) + return TOXLOSS //nuke core box, for carrying the core /obj/item/nuke_core_container @@ -156,13 +156,14 @@ ..() if(!iscarbon(user)) return FALSE - var/mob/ded = user - user.visible_message("[ded] reaches out and tries to pick up [src]. [ded.p_their()] body starts to glow and bursts into flames before flashing into dust!",\ + var/mob/victim = user + user.visible_message("[victim] reaches out and tries to pick up [src]. [victim.p_their()] body starts to glow and bursts into flames before flashing into dust!",\ "You reach for [src] with your hands. That was dumb.",\ "Everything suddenly goes silent.") radiation_pulse(user, 500, 2) playsound(get_turf(user), 'sound/effects/supermatter.ogg', 50, 1) - ded.dust() + victim.investigate_log("has been dusted by [src].", INVESTIGATE_DEATHS) + victim.dust() /obj/item/nuke_core_container/supermatter name = "supermatter bin" @@ -227,11 +228,10 @@ QDEL_NULL(sliver) return ..() -/obj/item/hemostat/supermatter/update_icon() - if(sliver) - icon_state = "supermatter_tongs_loaded" - else - icon_state = "supermatter_tongs" +/obj/item/hemostat/supermatter/update_icon_state() + icon_state = "supermatter_tongs[sliver ? "_loaded" : null]" + //item_state = "supermatter_tongs[sliver ? "_loaded" : null]" + return ..() /obj/item/hemostat/supermatter/afterattack(atom/O, mob/user, proximity) . = ..() @@ -251,6 +251,7 @@ /obj/item/hemostat/supermatter/proc/Consume(atom/movable/AM, mob/user) if(ismob(AM)) var/mob/victim = AM + victim.investigate_log("has been dusted by [src].", INVESTIGATE_DEATHS) victim.dust() message_admins("[src] has consumed [key_name_admin(victim)] [ADMIN_JMP(src)].") investigate_log("has consumed [key_name(victim)].", "supermatter") @@ -261,6 +262,7 @@ user.visible_message("As [user] touches [AM] with \the [src], both flash into dust and silence fills the room...",\ "You touch [AM] with [src], and everything suddenly goes silent.\n[AM] and [sliver] flash into dust, and soon as you can register this, you do as well.",\ "Everything suddenly goes silent.") + user.investigate_log("has been dusted by [src].", INVESTIGATE_DEATHS) user.dust() radiation_pulse(src, 500, 2) playsound(src, 'sound/effects/supermatter.ogg', 50, 1) diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm index ed19e270bcf82..7b780e9219cea 100644 --- a/code/game/objects/items/tools/crowbar.dm +++ b/code/game/objects/items/tools/crowbar.dm @@ -20,10 +20,10 @@ drop_sound = 'sound/items/handling/crowbar_drop.ogg' pickup_sound = 'sound/items/handling/crowbar_pickup.ogg' -/obj/item/crowbar/suicide_act(mob/user) +/obj/item/crowbar/suicide_act(mob/living/user) user.visible_message("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS /obj/item/crowbar/red icon_state = "crowbar_red" diff --git a/code/game/objects/items/tools/powertools.dm b/code/game/objects/items/tools/powertools.dm index 57447b8904e8c..1e8aa0544a917 100644 --- a/code/game/objects/items/tools/powertools.dm +++ b/code/game/objects/items/tools/powertools.dm @@ -62,7 +62,7 @@ attack_verb = list("drilled", "screwed", "jabbed") throw_range = 3 -/obj/item/powertool/hand_drill/suicide_act(mob/user) +/obj/item/powertool/hand_drill/suicide_act(mob/living/user) if(tool_behaviour == TOOL_SCREWDRIVER) user.visible_message("[user] is putting [src] to [user.p_their()] temple. It looks like [user.p_theyre()] trying to commit suicide!") else @@ -133,7 +133,7 @@ ADD_TRAIT(src, TRAIT_DOOR_PRYER, TRAIT_JAWS_OF_LIFE) -/obj/item/powertool/jaws_of_life/suicide_act(mob/user) +/obj/item/powertool/jaws_of_life/suicide_act(mob/living/user) if(tool_behaviour == TOOL_CROWBAR) user.visible_message("[user] is putting [user.p_their()] head in [src], it looks like [user.p_theyre()] trying to commit suicide!") playsound(loc, 'sound/items/jaws_pry.ogg', 50, 1, -1) diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm index 3d0820099f5c7..3875a5ec30b1b 100644 --- a/code/game/objects/items/tools/screwdriver.dm +++ b/code/game/objects/items/tools/screwdriver.dm @@ -40,9 +40,9 @@ "yellow" = "#ffa500" ) -/obj/item/screwdriver/suicide_act(mob/user) +/obj/item/screwdriver/suicide_act(mob/living/user) user.visible_message("[user] is stabbing [src] into [user.p_their()] [pick("temple", "heart")]! It looks like [user.p_theyre()] trying to commit suicide!") - return(BRUTELOSS) + return BRUTELOSS /obj/item/screwdriver/Initialize(mapload) if(random_color) diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 7050a76a5d3de..2b940add3b50c 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -50,22 +50,25 @@ reagents.add_reagent(/datum/reagent/fuel, max_fuel) update_icon() -/obj/item/weldingtool/proc/update_torch() +/obj/item/weldingtool/ComponentInitialize() + . = ..() + AddElement(/datum/element/update_icon_updates_onmob) + +/obj/item/weldingtool/update_icon_state() if(welding) - add_overlay("[initial(icon_state)]-on") item_state = "[initial(item_state)]1" else item_state = "[initial(item_state)]" + return ..() - -/obj/item/weldingtool/update_icon() - cut_overlays() +/obj/item/weldingtool/update_overlays() + . = ..() if(change_icons) var/ratio = get_fuel() / max_fuel ratio = CEILING(ratio*4, 1) * 25 - add_overlay("[initial(icon_state)][ratio]") - update_torch() - return + . += "[initial(icon_state)][ratio]" + if(welding) + . += "[initial(icon_state)]-on" /obj/item/weldingtool/process(delta_time) @@ -90,9 +93,9 @@ open_flame() -/obj/item/weldingtool/suicide_act(mob/user) +/obj/item/weldingtool/suicide_act(mob/living/user) user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!") - return (FIRELOSS) + return FIRELOSS /obj/item/weldingtool/attackby(obj/item/I, mob/user, params) @@ -182,11 +185,6 @@ set_light_on(FALSE) switched_on(user) update_icon() - //mob icon update - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands(0) - return 0 return 1 diff --git a/code/game/objects/items/tools/wirecutters.dm b/code/game/objects/items/tools/wirecutters.dm index a21ee3a523953..e075719e454f3 100644 --- a/code/game/objects/items/tools/wirecutters.dm +++ b/code/game/objects/items/tools/wirecutters.dm @@ -41,13 +41,13 @@ add_atom_colour(wirecutter_colors[our_color], FIXED_COLOUR_PRIORITY) update_icon() -/obj/item/wirecutters/update_icon() +/obj/item/wirecutters/update_overlays() + . = ..() if(!random_color) //icon override return - cut_overlays() var/mutable_appearance/base_overlay = mutable_appearance(icon, "cutters_cutty_thingy") base_overlay.appearance_flags = RESET_COLOR - add_overlay(base_overlay) + . += base_overlay /obj/item/wirecutters/attack(mob/living/carbon/C, mob/user) if(istype(C) && C.handcuffed && istype(C.handcuffed, /obj/item/restraints/handcuffs/cable)) @@ -62,10 +62,10 @@ else ..() -/obj/item/wirecutters/suicide_act(mob/user) +/obj/item/wirecutters/suicide_act(mob/living/user) user.visible_message("[user] is cutting at [user.p_their()] arteries with [src]! It looks like [user.p_theyre()] trying to commit suicide!") playsound(loc, usesound, 50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS /obj/item/wirecutters/brass name = "brass wirecutters" diff --git a/code/game/objects/items/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm index cbf292b4591a7..d26adbbd39f1f 100644 --- a/code/game/objects/items/tools/wrench.dm +++ b/code/game/objects/items/tools/wrench.dm @@ -19,10 +19,10 @@ toolspeed = 1 armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30, STAMINA = 0) -/obj/item/wrench/suicide_act(mob/user) +/obj/item/wrench/suicide_act(mob/living/user) user.visible_message("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS /obj/item/wrench/brass name = "brass wrench" diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 41c3dd6466be3..4f6587231abad 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -224,8 +224,9 @@ materials = list(/datum/material/iron=10, /datum/material/glass=10) var/amount_left = 7 -/obj/item/toy/ammo/gun/update_icon() - src.icon_state = "357OLD-[src.amount_left]" +/obj/item/toy/ammo/gun/update_icon_state() + icon_state = "357OLD-[amount_left]" + return ..() /obj/item/toy/ammo/gun/examine(mob/user) . = ..() @@ -674,6 +675,8 @@ || A Deck of Cards for playing various games of chance || */ + + /obj/item/toy/cards resistance_flags = FLAMMABLE max_integrity = 50 @@ -690,7 +693,7 @@ /obj/item/toy/cards/suicide_act(mob/living/carbon/user) user.visible_message("[user] is slitting [user.p_their()] wrists with \the [src]! It looks like [user.p_they()] [user.p_have()] a crummy hand!") - playsound(src, 'sound/items/cardshuffle.ogg', 50, 1) + playsound(src, 'sound/items/cardshuffle.ogg', 50, TRUE) return BRUTELOSS /obj/item/toy/cards/proc/apply_card_vars(obj/item/toy/cards/newobj, obj/item/toy/cards/sourceobj) // Applies variables for supporting multiple types of card deck @@ -713,29 +716,15 @@ . = ..() populate_deck() +///Generates all the cards within the deck. /obj/item/toy/cards/deck/proc/populate_deck() icon_state = "deck_[deckstyle]_full" - for(var/i in 2 to 10) - cards += "[i] of Hearts" - cards += "[i] of Spades" - cards += "[i] of Clubs" - cards += "[i] of Diamonds" - cards += "King of Hearts" - cards += "King of Spades" - cards += "King of Clubs" - cards += "King of Diamonds" - cards += "Queen of Hearts" - cards += "Queen of Spades" - cards += "Queen of Clubs" - cards += "Queen of Diamonds" - cards += "Jack of Hearts" - cards += "Jack of Spades" - cards += "Jack of Clubs" - cards += "Jack of Diamonds" - cards += "Ace of Hearts" - cards += "Ace of Spades" - cards += "Ace of Clubs" - cards += "Ace of Diamonds" + for(var/suit in list("Hearts", "Spades", "Clubs", "Diamonds")) + cards += "Ace of [suit]" + for(var/i in 2 to 10) + cards += "[i] of [suit]" + for(var/person in list("Jack", "Queen", "King")) + cards += "[person] of [suit]" //ATTACK HAND IGNORING PARENT RETURN VALUE //ATTACK HAND NOT CALLING PARENT @@ -748,7 +737,7 @@ if(!(L.mobility_flags & MOBILITY_PICKUP)) return var/choice = null - if(!LAZYLEN(cards)) + if(cards.len == 0) to_chat(user, "There are no more cards to draw!") return var/obj/item/toy/cards/singlecard/H = new/obj/item/toy/cards/singlecard(user.loc) @@ -759,25 +748,29 @@ H.parentdeck = src var/O = src H.apply_card_vars(H,O) - cards.Cut(1,2) //Removes the top card from the list + popleft(cards) + H.pickup(user) user.put_in_hands(H) user.visible_message("[user] draws a card from the deck.", "You draw a card from the deck.") update_icon() - -/obj/item/toy/cards/deck/update_icon() - if(LAZYLEN(cards) > original_size/2) - icon_state = "deck_[deckstyle]_full" - else if(LAZYLEN(cards) > original_size/4) - icon_state = "deck_[deckstyle]_half" - else if(LAZYLEN(cards)) - icon_state = "deck_[deckstyle]_low" - else if(!LAZYLEN(cards)) - icon_state = "deck_[deckstyle]_empty" + return H + +/obj/item/toy/cards/deck/update_icon_state() + switch(cards.len) + if(27 to INFINITY) + icon_state = "deck_[deckstyle]_full" + if(11 to 27) + icon_state = "deck_[deckstyle]_half" + if(1 to 11) + icon_state = "deck_[deckstyle]_low" + else + icon_state = "deck_[deckstyle]_empty" + return ..() /obj/item/toy/cards/deck/attack_self(mob/user) if(cooldown < world.time - 50) cards = shuffle(cards) - playsound(src, 'sound/items/cardshuffle.ogg', 50, 1) + playsound(src, 'sound/items/cardshuffle.ogg', 50, TRUE) user.visible_message("[user] shuffles the deck.", "You shuffle the deck.") cooldown = world.time @@ -810,22 +803,22 @@ return ..() /obj/item/toy/cards/deck/MouseDrop(atom/over_object) - . = ..() - var/mob/living/M = usr - if(!istype(M) || !(M.mobility_flags & MOBILITY_PICKUP)) - return - if(Adjacent(usr)) - if(over_object == M && loc != M) - M.put_in_hands(src) - to_chat(usr, "You pick up the deck.") + . = ..() + var/mob/living/M = usr + if(!istype(M) || !(M.mobility_flags & MOBILITY_PICKUP)) + return + if(Adjacent(usr)) + if(over_object == M && loc != M) + M.put_in_hands(src) + to_chat(usr, "You pick up the deck.") - else if(istype(over_object, /atom/movable/screen/inventory/hand)) - var/atom/movable/screen/inventory/hand/H = over_object - if(M.putItemFromInventoryInHandIfPossible(src, H.held_index)) - to_chat(usr, "You pick up the deck.") + else if(istype(over_object, /atom/movable/screen/inventory/hand)) + var/atom/movable/screen/inventory/hand/H = over_object + if(M.putItemFromInventoryInHandIfPossible(src, H.held_index)) + to_chat(usr, "You pick up the deck.") - else - to_chat(usr, "You can't reach it from here!") + else + to_chat(usr, "You can't reach it from here!") @@ -838,56 +831,43 @@ var/list/currenthand = list() var/choice = null - /obj/item/toy/cards/cardhand/attack_self(mob/user) - user.set_machine(src) + var/list/handradial = list() interact(user) -/obj/item/toy/cards/cardhand/ui_interact(mob/user) - . = ..() - var/dat = "You have:
" for(var/t in currenthand) - dat += "A [t].
" - dat += "Which card will you remove next?" - var/datum/browser/popup = new(user, "cardhand", "Hand of Cards", 400, 240) - popup.set_content(dat) - popup.open() - -/obj/item/toy/cards/cardhand/Topic(href, href_list) - if(..()) - return + handradial[t] = image(icon = src.icon, icon_state = "sc_[t]_[deckstyle]") + if(usr.stat || !ishuman(usr)) return var/mob/living/carbon/human/cardUser = usr if(!(cardUser.mobility_flags & MOBILITY_USE)) return var/O = src - if(href_list["pick"]) - if (cardUser.is_holding(src)) - var/choice = href_list["pick"] - if(!(choice in src.currenthand)) - log_href_exploit(usr) - return - var/obj/item/toy/cards/singlecard/C = new/obj/item/toy/cards/singlecard(cardUser.loc) - src.currenthand -= choice - C.parentdeck = src.parentdeck - C.cardname = choice - C.apply_card_vars(C,O) - cardUser.put_in_hands(C) - cardUser.visible_message("[cardUser] draws a card from [cardUser.p_their()] hand.", "You take the [C.cardname] from your hand.") - - interact(cardUser) - update_sprite() - if(src.currenthand.len == 1) - var/obj/item/toy/cards/singlecard/N = new/obj/item/toy/cards/singlecard(src.loc) - N.parentdeck = src.parentdeck - N.cardname = src.currenthand[1] - N.apply_card_vars(N,O) - qdel(src) - cardUser.put_in_hands(N) - to_chat(cardUser, "You also take [currenthand[1]] and hold it.") - cardUser << browse(null, "window=cardhand") - return + var/choice = show_radial_menu(usr,src, handradial, custom_check = CALLBACK(src, PROC_REF(check_menu), user), radius = 36, require_near = TRUE) + if(!choice) + return FALSE + var/obj/item/toy/cards/singlecard/C = new/obj/item/toy/cards/singlecard(cardUser.loc) + currenthand -= choice + handradial -= choice + C.parentdeck = parentdeck + C.cardname = choice + C.apply_card_vars(C,O) + C.pickup(cardUser) + cardUser.put_in_hands(C) + cardUser.visible_message("[cardUser] draws a card from [cardUser.p_their()] hand.", "You take the [C.cardname] from your hand.") + + interact(cardUser) + update_sprite() + if(length(currenthand) == 1) + var/obj/item/toy/cards/singlecard/N = new/obj/item/toy/cards/singlecard(loc) + N.parentdeck = parentdeck + N.cardname = currenthand[1] + N.apply_card_vars(N,O) + qdel(src) + N.pickup(cardUser) + cardUser.put_in_hands(N) + to_chat(cardUser, "You also take [currenthand[1]] and hold it.") /obj/item/toy/cards/cardhand/attackby(obj/item/toy/cards/singlecard/C, mob/living/user, params) if(istype(C)) @@ -914,6 +894,22 @@ newobj.card_attack_verb = sourceobj.card_attack_verb newobj.resistance_flags = sourceobj.resistance_flags +/** + * check_menu: Checks if we are allowed to interact with a radial menu + * + * Arguments: + * * user The mob interacting with a menu + */ +/obj/item/toy/cards/cardhand/proc/check_menu(mob/living/user) + if(!istype(user)) + return FALSE + if(user.incapacitated()) + return FALSE + return TRUE + +/** + * This proc updates the sprite for when you create a hand of cards + */ /obj/item/toy/cards/cardhand/proc/update_sprite() cut_overlays() var/overlay_cards = currenthand.len @@ -925,10 +921,10 @@ /obj/item/toy/cards/singlecard name = "card" - desc = "a card" + desc = "A playing card used to play card games like poker." icon = 'icons/obj/toy.dmi' icon_state = "singlecard_down_nanotrasen" - w_class = WEIGHT_CLASS_SMALL + w_class = WEIGHT_CLASS_TINY var/cardname = null var/flipped = 0 pixel_x = -5 @@ -983,6 +979,7 @@ to_chat(user, "You combine the [C.cardname] and the [src.cardname] into a hand.") qdel(C) qdel(src) + H.pickup(user) user.put_in_active_hand(H) else to_chat(user, "You can't mix cards from other decks!") @@ -1022,11 +1019,9 @@ newobj.card_attack_verb = sourceobj.card_attack_verb newobj.attack_verb = newobj.card_attack_verb - /* || Syndicate playing cards, for pretending you're Gambit and playing poker for the nuke disk. || */ - /obj/item/toy/cards/deck/syndicate name = "suspicious looking deck of cards" desc = "A deck of space-grade playing cards. They seem unusually rigid." diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 7835f3f62aaf7..80f458e96eb38 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -15,9 +15,9 @@ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 70, STAMINA = 0) resistance_flags = FIRE_PROOF -/obj/item/banhammer/suicide_act(mob/user) - user.visible_message("[user] is hitting [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to ban [user.p_them()]self from life.") - return (BRUTELOSS|FIRELOSS|TOXLOSS|OXYLOSS) +/obj/item/banhammer/suicide_act(mob/living/user) + user.visible_message("[user] is hitting [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to ban [user.p_them()]self from life.") + return (BRUTELOSS|FIRELOSS|TOXLOSS|OXYLOSS) /* oranges says: This is a meme relating to the english translation of the ss13 russian wiki page on lurkmore. mrdoombringer sez: and remember kids, if you try and PR a fix for this item's grammar, you are admitting that you are, indeed, a newfriend. @@ -48,7 +48,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 hitsound = 'sound/weapons/bladeslice.ogg' attack_verb = list("attacked", "slashed", "stabbed", "sliced", "tore", "ripped", "diced", "cut") -/obj/item/sord/suicide_act(mob/user) +/obj/item/sord/suicide_act(mob/living/user) user.visible_message("[user] is trying to impale [user.p_them()]self with [src]! It might be a suicide attempt if it weren't so shitty.", \ "You try to impale yourself with [src], but it's USELESS...") return SHAME @@ -90,9 +90,9 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 . = ..() AddComponent(/datum/component/butchering, 40, 105) -/obj/item/claymore/suicide_act(mob/user) +/obj/item/claymore/suicide_act(mob/living/user) user.visible_message("[user] is falling on [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return(BRUTELOSS) + return BRUTELOSS /obj/item/claymore/highlander //ALL COMMENTS MADE REGARDING THIS SWORD MUST BE MADE IN ALL CAPS desc = "THERE CAN BE ONLY ONE, AND IT WILL BE YOU!!!\nActivate it in your hand to point to the nearest victim." @@ -149,6 +149,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 user.fully_heal() //STEAL THE LIFE OF OUR FALLEN FOES add_notch(user) target.visible_message("[target] crumbles to dust beneath [user]'s blows!", "As you fall, your body crumbles to dust!") + target.investigate_log("has been dusted by a highlander claymore.", INVESTIGATE_DEATHS) target.dust() /obj/item/claymore/highlander/attack_self(mob/living/user) @@ -264,9 +265,9 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/katana/cursed slot_flags = null -/obj/item/katana/suicide_act(mob/user) +/obj/item/katana/suicide_act(mob/living/user) user.visible_message("[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!") - return(BRUTELOSS) + return BRUTELOSS /obj/item/wirerod name = "wired rod" @@ -399,9 +400,9 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 hitsound = 'sound/weapons/genhit.ogg' sharpness = IS_BLUNT -/obj/item/switchblade/suicide_act(mob/user) +/obj/item/switchblade/suicide_act(mob/living/user) user.visible_message("[user] is slitting [user.p_their()] own throat with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) + return BRUTELOSS /obj/item/switchblade/kitchen name = "iron switchblade" @@ -437,12 +438,12 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 attack_verb = list("called", "rang") hitsound = 'sound/weapons/ring.ogg' -/obj/item/phone/suicide_act(mob/user) +/obj/item/phone/suicide_act(mob/living/user) if(locate(/obj/structure/chair/stool) in user.loc) user.visible_message("[user] begins to tie a noose with [src]'s cord! It looks like [user.p_theyre()] trying to commit suicide!") else user.visible_message("[user] is strangling [user.p_them()]self with [src]'s cord! It looks like [user.p_theyre()] trying to commit suicide!") - return(OXYLOSS) + return OXYLOSS /obj/item/cane name = "cane" @@ -505,9 +506,9 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon = 'icons/obj/wizard.dmi' icon_state = "ectoplasm" -/obj/item/ectoplasm/suicide_act(mob/user) +/obj/item/ectoplasm/suicide_act(mob/living/user) user.visible_message("[user] is inhaling [src]! It looks like [user.p_theyre()] trying to visit the astral plane!") - return (OXYLOSS) + return OXYLOSS /obj/item/ectoplasm/angelic icon = 'icons/obj/wizard.dmi' @@ -758,24 +759,27 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/melee/flyswatter/Initialize(mapload) . = ..() strong_against = typecacheof(list( - /mob/living/simple_animal/hostile/poison/bees/, - /mob/living/simple_animal/butterfly, - /mob/living/basic/cockroach, - /obj/item/queen_bee + /mob/living/simple_animal/hostile/poison/bees/, + /mob/living/simple_animal/butterfly, + /mob/living/basic/cockroach, + /obj/item/queen_bee )) /obj/item/melee/flyswatter/afterattack(atom/target, mob/user, proximity_flag) . = ..() - if(proximity_flag) - if(is_type_in_typecache(target, strong_against)) - new /obj/effect/decal/cleanable/insectguts(target.drop_location()) - to_chat(user, "You easily splat the [target].") - if(istype(target, /mob/living/)) - var/mob/living/bug = target - bug.death(1) - else - qdel(target) + if(!proximity_flag || HAS_TRAIT(user, TRAIT_PACIFISM)) + return + + if(is_type_in_typecache(target, strong_against)) + new /obj/effect/decal/cleanable/insectguts(target.drop_location()) + to_chat(user, "You easily splat the [target].") + if(istype(target, /mob/living/)) + var/mob/living/bug = target + bug.investigate_log("has been splatted by a flyswatter.", INVESTIGATE_DEATHS) + bug.death(1) + else + qdel(target) /obj/item/circlegame name = "circled hand" diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 52fdb93c3f106..3443f1b65a5a3 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -33,7 +33,7 @@ if(damage_flag) armor_protection = armor.getRating(damage_flag) if(armor_protection) //Only apply weak-against-armor/hollowpoint effects if there actually IS armor. - armor_protection = CLAMP(armor_protection - armour_penetration, min(armor_protection, 0), 100) + armor_protection = clamp(armor_protection - armour_penetration, min(armor_protection, 0), 100) return round(damage_amount * (100 - armor_protection)*0.01, DAMAGE_PRECISION) //the sound played when the obj is damaged. @@ -228,7 +228,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e if(T.intact && HAS_TRAIT(src, TRAIT_T_RAY_VISIBLE)) return if(exposed_temperature && !(resistance_flags & FIRE_PROOF)) - take_damage(CLAMP(0.02 * exposed_temperature, 0, 20), BURN, FIRE, 0) + take_damage(clamp(0.02 * exposed_temperature, 0, 20), BURN, FIRE, 0) if(!(resistance_flags & ON_FIRE) && (resistance_flags & FLAMMABLE) && !(resistance_flags & FIRE_PROOF)) resistance_flags |= ON_FIRE SSfire_burning.processing[src] = src @@ -259,7 +259,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e if(has_buckled_mobs()) for(var/m in buckled_mobs) var/mob/living/buckled_mob = m - buckled_mob.electrocute_act((CLAMP(round(strength/400), 10, 90) + rand(-5, 5)), src, tesla_shock = 1) + buckled_mob.electrocute_act((clamp(round(strength/400), 10, 90) + rand(-5, 5)), src, tesla_shock = 1) /obj/proc/reset_shocked() obj_flags &= ~BEING_SHOCKED diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index 62501363e11ea..b01676702fadc 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -339,6 +339,14 @@ item_chair = null icon_state = "officechair_dark" +/obj/structure/chair/office/relaymove(mob/user, direction) + if(!direction) + return FALSE + if(direction == dir) + return + setDir(direction) + return FALSE + /obj/structure/chair/office/Moved() . = ..() if(has_gravity()) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index d70ade784ac5b..735e16b6f7cd5 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -582,12 +582,12 @@ step_towards(user, T2) T1 = get_turf(user) if(T1 == T2) - user.resting = TRUE //so people can jump into crates without slamming the lid on their head + user.set_resting(TRUE) //so people can jump into crates without slamming the lid on their head if(!close(user)) to_chat(user, "You can't get [src] to close!") - user.resting = FALSE + user.set_resting(FALSE) return - user.resting = FALSE + user.set_resting(FALSE) togglelock(user) T1.visible_message("[user] dives into [src]!") diff --git a/code/game/objects/structures/divine.dm b/code/game/objects/structures/divine.dm index 8667804dab1b9..353697111bb3d 100644 --- a/code/game/objects/structures/divine.dm +++ b/code/game/objects/structures/divine.dm @@ -17,6 +17,7 @@ if(!L) return to_chat(user, "You attempt to sacrifice [L] by invoking the sacrificial ritual.") + L.investigate_log("has been sacrificially gibbed on an altar.", INVESTIGATE_DEATHS) L.gib() message_admins("[ADMIN_LOOKUPFLW(user)] has sacrificed [key_name_admin(L)] on the sacrificial altar at [AREACOORD(src)].") diff --git a/code/game/objects/structures/fireplace.dm b/code/game/objects/structures/fireplace.dm index 13eaacdfa589f..6b610992d9aa6 100644 --- a/code/game/objects/structures/fireplace.dm +++ b/code/game/objects/structures/fireplace.dm @@ -129,7 +129,7 @@ if(burn_time_remaining() < MAXIMUM_BURN_TIMER) flame_expiry_timer = world.time + MAXIMUM_BURN_TIMER else - fuel_added = CLAMP(fuel_added + amount, 0, MAXIMUM_BURN_TIMER) + fuel_added = clamp(fuel_added + amount, 0, MAXIMUM_BURN_TIMER) /obj/structure/fireplace/proc/burn_time_remaining() if(lit) diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 388d58bfaddcc..7e98be116ca57 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -273,7 +273,9 @@ GLOBAL_LIST_EMPTY(crematoriums) log_combat(user, M, "cremated") else M.log_message("was cremated", LOG_ATTACK) - M.death(1) + if(user.stat != DEAD) + user.investigate_log("has died from being cremated.", INVESTIGATE_DEATHS) + M.death(TRUE) if(M) //some animals get automatically deleted on death. M.ghostize() qdel(M) diff --git a/code/game/objects/structures/petrified_statue.dm b/code/game/objects/structures/petrified_statue.dm index 1b2702f2d3cf4..b54adca7ecda7 100644 --- a/code/game/objects/structures/petrified_statue.dm +++ b/code/game/objects/structures/petrified_statue.dm @@ -68,8 +68,9 @@ /obj/structure/statue/petrified/deconstruct(disassembled = TRUE) if(!disassembled) if(petrified_mob) + petrified_mob.investigate_log("has been dusted by statue deconstruction.", INVESTIGATE_DEATHS) petrified_mob.dust() - visible_message("[src] shatters!.") + visible_message("[src] shatters!") qdel(src) diff --git a/code/game/objects/structures/showcase.dm b/code/game/objects/structures/showcase.dm index c7d4f98f248f4..038134f41c3d5 100644 --- a/code/game/objects/structures/showcase.dm +++ b/code/game/objects/structures/showcase.dm @@ -15,18 +15,18 @@ name = "\improper CentCom identification console" desc = "You can use this to change ID's." icon = 'icons/obj/computer.dmi' - icon_state = "computer" + icon_state = "computer-0" /obj/structure/showcase/fakeid/Initialize(mapload) . = ..() add_overlay("id") - add_overlay("id_key") + add_overlay("generic_key") /obj/structure/showcase/fakesec name = "\improper CentCom security records" desc = "Used to view and edit personnel's security records." icon = 'icons/obj/computer.dmi' - icon_state = "computer" + icon_state = "computer-0" /obj/structure/showcase/fakesec/Initialize(mapload) . = ..() diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm index ba71167abf40f..144e39881e4fe 100644 --- a/code/game/turfs/change_turf.dm +++ b/code/game/turfs/change_turf.dm @@ -287,9 +287,9 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( if(depth) var/list/target_baseturfs if(length(copytarget.baseturfs)) - // with default inputs this would be Copy(CLAMP(2, -INFINITY, baseturfs.len)) + // with default inputs this would be Copy(clamp(2, -INFINITY, baseturfs.len)) // Don't forget a lower index is lower in the baseturfs stack, the bottom is baseturfs[1] - target_baseturfs = copytarget.baseturfs.Copy(CLAMP(1 + ignore_bottom, 1 + copytarget.baseturfs.len - depth, copytarget.baseturfs.len)) + target_baseturfs = copytarget.baseturfs.Copy(clamp(1 + ignore_bottom, 1 + copytarget.baseturfs.len - depth, copytarget.baseturfs.len)) else if(!ignore_bottom) target_baseturfs = list(copytarget.baseturfs) if(target_baseturfs) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index f56ae01bdb9d5..b6221d1419d1e 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -525,7 +525,7 @@ GLOBAL_LIST_EMPTY(created_baseturf_lists) /turf/AllowDrop() return TRUE -/turf/proc/add_vomit_floor(mob/living/M, toxvomit = NONE) +/turf/proc/add_vomit_floor(mob/living/M, toxvomit = NONE, purge = TRUE) var/obj/effect/decal/cleanable/vomit/V = new /obj/effect/decal/cleanable/vomit(src, M.get_static_viruses()) @@ -539,7 +539,11 @@ GLOBAL_LIST_EMPTY(created_baseturf_lists) V.icon_state = "vomitpurp_[pick(1,4)]" else if (toxvomit == VOMIT_TOXIC) V.icon_state = "vomittox_[pick(1,4)]" - if (iscarbon(M)) + else if (toxvomit == VOMIT_NANITE) + V.name = "metallic slurry" + V.desc = "A puddle of metallic slurry that looks vaguely like very fine sand. It almost seems like it's moving..." + V.icon_state = "vomitnanite_[pick(1,4)]" + if (purge && iscarbon(M)) var/mob/living/carbon/C = M if(C.reagents) clear_reagents_to_vomit_pool(C,V) diff --git a/code/game/world.dm b/code/game/world.dm index a9d2320094faa..fac2213f04d4e 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -160,6 +160,7 @@ GLOBAL_VAR(restart_counter) GLOB.world_job_debug_log = "[GLOB.log_directory]/job_debug.log" GLOB.world_paper_log = "[GLOB.log_directory]/paper.log" GLOB.tgui_log = "[GLOB.log_directory]/tgui.log" + GLOB.prefs_log = "[GLOB.log_directory]/preferences.log" #ifdef UNIT_TESTS GLOB.test_log = file("[GLOB.log_directory]/tests.log") @@ -180,6 +181,7 @@ GLOBAL_VAR(restart_counter) start_log(GLOB.world_job_debug_log) start_log(GLOB.world_id_log) start_log(GLOB.tgui_log) + start_log(GLOB.prefs_log) GLOB.changelog_hash = md5('html/changelog.html') //for telling if the changelog has changed recently if(fexists(GLOB.config_error_log)) @@ -411,6 +413,29 @@ GLOBAL_VAR(restart_counter) /world/proc/refresh_atmos_grid() +/world/proc/change_fps(new_value = 20) + if(new_value <= 0) + CRASH("change_fps() called with [new_value] new_value.") + if(fps == new_value) + return //No change required. + + fps = new_value + on_tickrate_change() + +/* UNUSED. uncomment if using +/world/proc/change_tick_lag(new_value = 0.5) + if(new_value <= 0) + CRASH("change_tick_lag() called with [new_value] new_value.") + if(tick_lag == new_value) + return //No change required. + + tick_lag = new_value + on_tickrate_change() +*/ + +/world/proc/on_tickrate_change() + SStimer?.reset_buckets() + /world/proc/init_byond_tracy() var/library diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index 802c7b0c7ebe8..dcba7faa8990f 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -11,23 +11,25 @@ return var/list/investigates = list( - INVESTIGATE_RESEARCH, - INVESTIGATE_EXONET, - INVESTIGATE_PORTAL, - INVESTIGATE_ENGINES, - INVESTIGATE_WIRES, - INVESTIGATE_TELESCI, - INVESTIGATE_GRAVITY, - INVESTIGATE_RECORDS, - INVESTIGATE_CARGO, INVESTIGATE_ATMOS, - INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, + INVESTIGATE_CARGO, + INVESTIGATE_DEATHS, + INVESTIGATE_ENGINES, + INVESTIGATE_EXONET, + INVESTIGATE_EXPERIMENTOR, + INVESTIGATE_GRAVITY, INVESTIGATE_HALLUCINATIONS, - INVESTIGATE_RADIATION, + INVESTIGATE_ITEMS, INVESTIGATE_NANITES, + INVESTIGATE_PORTAL, INVESTIGATE_PRESENTS, - INVESTIGATE_ITEMS) + INVESTIGATE_RADIATION, + INVESTIGATE_RECORDS, + INVESTIGATE_RESEARCH, + INVESTIGATE_TELESCI, + INVESTIGATE_WIRES, + ) var/list/logs_present = list("notes, memos, watchlist") var/list/logs_missing = list("---") diff --git a/code/modules/admin/battle_royale.dm b/code/modules/admin/battle_royale.dm index 1c6e4f8fcf9bc..3326bfb73e400 100644 --- a/code/modules/admin/battle_royale.dm +++ b/code/modules/admin/battle_royale.dm @@ -434,10 +434,10 @@ GLOBAL_DATUM(battle_royale, /datum/battle_royale_controller) center_turf = center /obj/effect/death_wall/proc/decrease_size() - var/minx = CLAMP(center_turf.x - current_radius, 1, 255) - var/maxx = CLAMP(center_turf.x + current_radius, 1, 255) - var/miny = CLAMP(center_turf.y - current_radius, 1, 255) - var/maxy = CLAMP(center_turf.y + current_radius, 1, 255) + var/minx = clamp(center_turf.x - current_radius, 1, 255) + var/maxx = clamp(center_turf.x + current_radius, 1, 255) + var/miny = clamp(center_turf.y - current_radius, 1, 255) + var/maxy = clamp(center_turf.y + current_radius, 1, 255) if(y == maxy || y == miny) //We have nowhere to move to so are deleted if(x == minx || x == minx + 1 || x == maxx || x == maxx - 1) diff --git a/code/modules/admin/fun_balloon.dm b/code/modules/admin/fun_balloon.dm index 33308c17d44e7..619cb5c34bb3d 100644 --- a/code/modules/admin/fun_balloon.dm +++ b/code/modules/admin/fun_balloon.dm @@ -60,7 +60,7 @@ to_chat(body, "Your mob has been taken over by a ghost!") message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(body)])") - body.ghostize(0) + body.ghostize(FALSE) body.key = C.key new /obj/effect/temp_visual/gravpush(get_turf(body)) diff --git a/code/modules/admin/sound_emitter.dm b/code/modules/admin/sound_emitter.dm index 0fee3c6ba8ad4..5644e8694d119 100644 --- a/code/modules/admin/sound_emitter.dm +++ b/code/modules/admin/sound_emitter.dm @@ -95,7 +95,7 @@ var/new_volume = input(user, "Choose a volume.", "Sound Emitter", sound_volume) as null|num if(isnull(new_volume)) return - new_volume = CLAMP(new_volume, 0, 100) + new_volume = clamp(new_volume, 0, 100) sound_volume = new_volume to_chat(user, "Volume set to [sound_volume]%.") if(href_list["edit_mode"]) @@ -118,7 +118,7 @@ var/new_radius = input(user, "Choose a radius.", "Sound Emitter", sound_volume) as null|num if(isnull(new_radius)) return - new_radius = CLAMP(new_radius, 0, 127) + new_radius = clamp(new_radius, 0, 127) play_radius = new_radius to_chat(user, "Audible radius set to [play_radius].") if(href_list["play"]) diff --git a/code/modules/admin/sql_message_system.dm b/code/modules/admin/sql_message_system.dm index 84150c0c36588..be27255532cfe 100644 --- a/code/modules/admin/sql_message_system.dm +++ b/code/modules/admin/sql_message_system.dm @@ -502,7 +502,7 @@ var/nsd = CONFIG_GET(number/note_stale_days) var/nfd = CONFIG_GET(number/note_fresh_days) if (agegate && type == "note" && isnum_safe(nsd) && isnum_safe(nfd) && nsd > nfd) - var/alpha = CLAMP(100 - (age - nfd) * (85 / (nsd - nfd)), 15, 100) + var/alpha = clamp(100 - (age - nfd) * (85 / (nsd - nfd)), 15, 100) if (alpha < 100) if (alpha <= 15) if (skipped) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index afd5152e6276c..04b7a43267539 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1418,7 +1418,7 @@ return var/list/offset = splittext(href_list["offset"],",") - var/number = CLAMP(text2num(href_list["object_count"]), 1, 100) + var/number = clamp(text2num(href_list["object_count"]), 1, 100) var/X = offset.len > 0 ? text2num(offset[1]) : 0 var/Y = offset.len > 1 ? text2num(offset[2]) : 0 var/Z = offset.len > 2 ? text2num(offset[3]) : 0 diff --git a/code/modules/admin/verbs/_help.dm b/code/modules/admin/verbs/_help.dm index 2952233cbf01a..bf9c7a9c534a1 100644 --- a/code/modules/admin/verbs/_help.dm +++ b/code/modules/admin/verbs/_help.dm @@ -233,10 +233,19 @@ for(var/datum/help_ticket/AH in l) if(AH.initiator) tab_data["#[AH.id]. [AH.initiator_key_name]"] = list( - text = AH.name, + text = AH.stat_text, type = STAT_BUTTON, action = "open_ticket", params = list("id" = AH.id), + multirow = TRUE, + buttons = list( + list( + "title" = AH.claimee_key_name ? "Claimed by [AH.claimee_key_name]" : "Claim", + "color" = AH.claimee_key_name ? "red" : "green", + "action_id" = "claim_ticket", + "params" = list("id" = AH.id) + ) + ) ) else ++num_disconnected @@ -311,6 +320,7 @@ /datum/help_ticket var/id var/name + var/stat_text var/state = TICKET_UNCLAIMED /// The first (sanitized) message for this ticket var/initial_msg @@ -359,6 +369,7 @@ opened_at = world.time name = copytext_char(msg, 1, 100) + stat_text = copytext_char(msg, 1, 500) var/datum/help_tickets/data_glob = get_data_glob() if(!istype(data_glob)) diff --git a/code/modules/admin/verbs/borgpanel.dm b/code/modules/admin/verbs/borgpanel.dm index ef88eba0544f5..77e2b5acb12bc 100644 --- a/code/modules/admin/verbs/borgpanel.dm +++ b/code/modules/admin/verbs/borgpanel.dm @@ -89,7 +89,7 @@ if ("set_charge") var/newcharge = input("New charge (0-[borg.cell.maxcharge]):", borg.name, borg.cell.charge) as num|null if (newcharge) - borg.cell.charge = CLAMP(newcharge, 0, borg.cell.maxcharge) + borg.cell.charge = clamp(newcharge, 0, borg.cell.maxcharge) message_admins("[key_name_admin(user)] set the charge of [ADMIN_LOOKUPFLW(borg)] to [borg.cell.charge].") log_admin("[key_name(user)] set the charge of [key_name(borg)] to [borg.cell.charge].") if ("remove_cell") diff --git a/code/modules/admin/verbs/fps.dm b/code/modules/admin/verbs/fps.dm index 2b65d2a44c5a0..a738955052612 100644 --- a/code/modules/admin/verbs/fps.dm +++ b/code/modules/admin/verbs/fps.dm @@ -23,4 +23,4 @@ SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Set Server FPS", "[new_fps]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! CONFIG_SET(number/fps, new_fps) - world.fps = new_fps + world.change_fps(new_fps) diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm index f08ee0db993e5..c5038cc2de77c 100644 --- a/code/modules/admin/verbs/playsound.dm +++ b/code/modules/admin/verbs/playsound.dm @@ -13,7 +13,7 @@ var/vol = input(usr, "What volume would you like the sound to play at?",, 100) as null|num if(!vol) return - vol = CLAMP(vol, 1, 100) + vol = clamp(vol, 1, 100) var/sound/admin_sound = new() admin_sound.file = S diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm index 127f032e9c24b..8922b68e23d64 100644 --- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm +++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm @@ -58,9 +58,7 @@ if(ishuman(loc)) var/mob/living/carbon/human/H = loc H.update_inv_wear_suit() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() /obj/item/clothing/suit/armor/abductor/vest/item_action_slot_check(slot, mob/user) if(slot == ITEM_SLOT_OCLOTHING) //we only give the mob the ability to activate the vest if he's actually wearing it. diff --git a/code/modules/antagonists/abductor/machinery/camera.dm b/code/modules/antagonists/abductor/machinery/camera.dm index 1d15a2c5772a0..2fc5400c6d91e 100644 --- a/code/modules/antagonists/abductor/machinery/camera.dm +++ b/code/modules/antagonists/abductor/machinery/camera.dm @@ -13,6 +13,10 @@ icon = 'icons/obj/abductor.dmi' icon_state = "camera" + base_icon_state = null + smoothing_flags = NONE + smoothing_groups = null + canSmoothWith = null resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF reveal_camera_mob = TRUE diff --git a/code/modules/antagonists/blob/blob_mobs.dm b/code/modules/antagonists/blob/blob_mobs.dm index e2c9356645a03..6763875819065 100644 --- a/code/modules/antagonists/blob/blob_mobs.dm +++ b/code/modules/antagonists/blob/blob_mobs.dm @@ -55,7 +55,7 @@ /mob/living/simple_animal/hostile/blob/fire_act(exposed_temperature, exposed_volume) ..() if(exposed_temperature) - adjustFireLoss(CLAMP(0.01 * exposed_temperature, 1, 5)) + adjustFireLoss(clamp(0.01 * exposed_temperature, 1, 5)) else adjustFireLoss(5) diff --git a/code/modules/antagonists/blob/blobstrains/zombifying_pods.dm b/code/modules/antagonists/blob/blobstrains/zombifying_pods.dm index 5a165e8bf4aaa..41a28d5204e14 100644 --- a/code/modules/antagonists/blob/blobstrains/zombifying_pods.dm +++ b/code/modules/antagonists/blob/blobstrains/zombifying_pods.dm @@ -36,6 +36,7 @@ reac_volume = ..() M.apply_damage(0.6*reac_volume, TOX) if(O && ishuman(M) && M.stat == UNCONSCIOUS) + M.investigate_log("has been killed by distributed neurons (blob).", INVESTIGATE_DEATHS) M.death() //sleeping in a fight? bad plan. var/points = rand(5, 10) var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(get_turf(M)) diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm index afb8c1e3ab2f9..fb2e7fba7d486 100644 --- a/code/modules/antagonists/blob/overmind.dm +++ b/code/modules/antagonists/blob/overmind.dm @@ -148,6 +148,8 @@ GLOBAL_LIST_EMPTY(blob_nodes) if(!(FACTION_BLOB in L.faction)) playsound(L, 'sound/effects/splat.ogg', 50, 1) + if(L.stat != DEAD) + L.investigate_log("has died from blob takeover.", INVESTIGATE_DEATHS) L.death() new/mob/living/simple_animal/hostile/blob/blobspore(T) else @@ -215,7 +217,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) B.hud_used.blobpwrdisplay.maptext = MAPTEXT("
[round(blob_core.obj_integrity)]
") /mob/camera/blob/proc/add_points(points) - blob_points = CLAMP(blob_points + points, 0, max_blob_points) + blob_points = clamp(blob_points + points, 0, max_blob_points) hud_used.blobpwrdisplay.maptext = MAPTEXT("
[round(blob_points)]
") /mob/camera/blob/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null) diff --git a/code/modules/antagonists/changeling/powers/absorb.dm b/code/modules/antagonists/changeling/powers/absorb.dm index 3792b36b3639b..7313a5989a885 100644 --- a/code/modules/antagonists/changeling/powers/absorb.dm +++ b/code/modules/antagonists/changeling/powers/absorb.dm @@ -142,6 +142,8 @@ changeling.isabsorbing = 0 changeling.canrespec = 1 - target.death(0) + if(target.stat != DEAD) + target.investigate_log("has died from being changeling absorbed.", INVESTIGATE_DEATHS) + target.death(FALSE) target.Drain() return TRUE diff --git a/code/modules/antagonists/changeling/powers/fakedeath.dm b/code/modules/antagonists/changeling/powers/fakedeath.dm index 2d66d264db427..13a40871292d9 100644 --- a/code/modules/antagonists/changeling/powers/fakedeath.dm +++ b/code/modules/antagonists/changeling/powers/fakedeath.dm @@ -24,7 +24,6 @@ else to_chat(user, "We begin our stasis, preparing energy to arise once more.") user.fakedeath("changeling") //play dead - user.update_stat() user.update_mobility() addtimer(CALLBACK(src, PROC_REF(ready_to_regenerate), user.mind), LING_FAKEDEATH_TIME, TIMER_UNIQUE) return TRUE diff --git a/code/modules/antagonists/changeling/powers/headcrab.dm b/code/modules/antagonists/changeling/powers/headcrab.dm index 85cf9dd85961a..7f75daae24be3 100644 --- a/code/modules/antagonists/changeling/powers/headcrab.dm +++ b/code/modules/antagonists/changeling/powers/headcrab.dm @@ -56,5 +56,6 @@ if(crab.origin) crab.origin.active = 1 crab.origin.transfer_to(crab) + user.investigate_log("has been gibbed by using their Last Resort headcrab ability.", INVESTIGATE_DEATHS) user.gib() to_chat(crab, "You burst out of the remains of your former body in a shower of gore!") diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm index 34ad063d6e5bd..c974b8aa2194e 100644 --- a/code/modules/antagonists/changeling/powers/mutations.dm +++ b/code/modules/antagonists/changeling/powers/mutations.dm @@ -248,10 +248,9 @@ if(charges == 0) qdel(src) -/obj/item/gun/magic/tentacle/suicide_act(mob/user) +/obj/item/gun/magic/tentacle/suicide_act(mob/living/user) user.visible_message("[user] coils [src] tightly around [user.p_their()] neck! It looks like [user.p_theyre()] trying to commit suicide!") - return (OXYLOSS) - + return OXYLOSS /obj/item/ammo_casing/magic/tentacle name = "tentacle" diff --git a/code/modules/antagonists/clock_cult/items/replica_fabricator.dm b/code/modules/antagonists/clock_cult/items/replica_fabricator.dm index 4377824f1987a..3ede705c2568a 100644 --- a/code/modules/antagonists/clock_cult/items/replica_fabricator.dm +++ b/code/modules/antagonists/clock_cult/items/replica_fabricator.dm @@ -57,12 +57,12 @@ return GLOB.clockcult_power -= 200 to_chat(user, "You repair some of the damage on \the [C].") - C.obj_integrity = CLAMP(C.obj_integrity + 15, 0, C.max_integrity) + C.obj_integrity = clamp(C.obj_integrity + 15, 0, C.max_integrity) else to_chat(user, "You fail to repair the damage of \the [C]...") /obj/item/clockwork/replica_fabricator/proc/fabricate_sheets(turf/target, mob/user) - var/sheets = FLOOR(CLAMP(GLOB.clockcult_power / BRASS_POWER_COST, 0, 50), 1) + var/sheets = FLOOR(clamp(GLOB.clockcult_power / BRASS_POWER_COST, 0, 50), 1) if(sheets == 0) return GLOB.clockcult_power -= sheets * BRASS_POWER_COST diff --git a/code/modules/antagonists/clock_cult/scriptures/kindle.dm b/code/modules/antagonists/clock_cult/scriptures/kindle.dm index c8593f36bb13e..3a572894dde09 100644 --- a/code/modules/antagonists/clock_cult/scriptures/kindle.dm +++ b/code/modules/antagonists/clock_cult/scriptures/kindle.dm @@ -54,7 +54,7 @@ M.Paralyze(150) else to_chat(invoker, "[M] seems somewhat resistant to your powers!") - M.confused = CLAMP(M.confused, 50, INFINITY) + M.confused = clamp(M.confused, 50, INFINITY) if(issilicon(M)) var/mob/living/silicon/S = M S.emp_act(EMP_HEAVY) diff --git a/code/modules/antagonists/clock_cult/scriptures/sigil_of_vitality.dm b/code/modules/antagonists/clock_cult/scriptures/sigil_of_vitality.dm index 0d80bd2aa4790..d5e4010d9c490 100644 --- a/code/modules/antagonists/clock_cult/scriptures/sigil_of_vitality.dm +++ b/code/modules/antagonists/clock_cult/scriptures/sigil_of_vitality.dm @@ -61,7 +61,7 @@ else visible_message("\The [src] fails to revive [M]!") return - var/healing_performed = CLAMP(M.maxHealth - M.health, 0, 5) //5 Vitality to heal 5 of all damage types at once + var/healing_performed = clamp(M.maxHealth - M.health, 0, 5) //5 Vitality to heal 5 of all damage types at once if(GLOB.clockcult_vitality >= healing_performed * 0.3) GLOB.clockcult_vitality -= healing_performed * 0.3 //Do healing diff --git a/code/modules/antagonists/clock_cult/structure/clockwork_camera.dm b/code/modules/antagonists/clock_cult/structure/clockwork_camera.dm index 55eb9795502b5..0cc0a9d8a8a3a 100644 --- a/code/modules/antagonists/clock_cult/structure/clockwork_camera.dm +++ b/code/modules/antagonists/clock_cult/structure/clockwork_camera.dm @@ -57,6 +57,10 @@ icon_screen = "ratvar1" icon_keyboard = "ratvar_key1" icon_state = "ratvarcomputer" + base_icon_state = null + smoothing_flags = NONE + smoothing_groups = null + canSmoothWith = null clockwork = TRUE lock_override = CAMERA_LOCK_STATION broken_overlay_emissive = TRUE diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 3dc4b39cd7727..644f52368d8a4 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -335,9 +335,11 @@ structure_check() searches for nearby cultist structures required for the invoca if(sacrificial) if(iscyborg(sacrificial)) playsound(sacrificial, 'sound/magic/disable_tech.ogg', 100, 1) + sacrificial.investigate_log("has been sacrificially dusted by the cult.", INVESTIGATE_DEATHS) sacrificial.dust() //To prevent the MMI from remaining else playsound(sacrificial, 'sound/magic/disintegrate.ogg', 100, 1) + sacrificial.investigate_log("has been sacrificially gibbed by the cult.", INVESTIGATE_DEATHS) sacrificial.gib() return TRUE @@ -934,7 +936,7 @@ structure_check() searches for nearby cultist structures required for the invoca affecting.add_atom_colour(RUNE_COLOR_DARKRED, ADMIN_COLOUR_PRIORITY) affecting.visible_message("[affecting] freezes statue-still, glowing an unearthly red.", \ "You see what lies beyond. All is revealed. In this form you find that your voice booms louder and you can mark targets for the entire cult") - var/mob/dead/observer/G = affecting.ghostize(1) + var/mob/dead/observer/G = affecting.ghostize(TRUE) var/datum/action/innate/cult/comm/spirit/CM = new var/datum/action/innate/cult/ghostmark/GM = new G.name = "Dark Spirit of [G.name]" diff --git a/code/modules/antagonists/heretic/influences.dm b/code/modules/antagonists/heretic/influences.dm index 8b394c5d71477..fbf5e092f56d4 100644 --- a/code/modules/antagonists/heretic/influences.dm +++ b/code/modules/antagonists/heretic/influences.dm @@ -183,6 +183,7 @@ qdel(head) else human_user.gib() + human_user.investigate_log("has died from using telekinesis on a heretic influence.", INVESTIGATE_DEATHS) var/datum/effect_system/reagents_explosion/explosion = new() explosion.set_up(1, get_turf(human_user), TRUE, 0) diff --git a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm index 9d696dd4f9f4b..fee23bad30d2a 100644 --- a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm +++ b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm @@ -482,6 +482,7 @@ sac_target.spill_organs() sac_target.apply_damage(250, BRUTE) if(sac_target.stat != DEAD) + sac_target.investigate_log("has been killed by heretic sacrifice.", INVESTIGATE_DEATHS) sac_target.death() sac_target.visible_message( "[sac_target]'s organs are pulled out of [sac_target.p_their()] chest by shadowy hands!", diff --git a/code/modules/antagonists/heretic/magic/mansus_grasp.dm b/code/modules/antagonists/heretic/magic/mansus_grasp.dm index b41a8fc8e46f8..0fb467dce66db 100644 --- a/code/modules/antagonists/heretic/magic/mansus_grasp.dm +++ b/code/modules/antagonists/heretic/magic/mansus_grasp.dm @@ -16,7 +16,7 @@ catchphrase = "R'CH T'H TR'TH!" on_use_sound = 'sound/items/welder.ogg' -/obj/item/melee/touch_attack/mansus_fist/Initialize(mapload) +/obj/item/melee/touch_attack/mansus_fist/Initialize(mapload, obj/effect/proc_holder/spell/targeted/touch/_spell) . = ..() AddComponent(/datum/component/effect_remover, \ success_feedback = "You remove %THEEFFECT.", \ @@ -86,7 +86,7 @@ return TRUE -/obj/item/melee/touch_attack/mansus_fist/suicide_act(mob/user) +/obj/item/melee/touch_attack/mansus_fist/suicide_act(mob/living/user) user.visible_message("[user] covers [user.p_their()] face with [user.p_their()] sickly-looking hand! It looks like [user.p_theyre()] trying to commit suicide!") var/mob/living/carbon/carbon_user = user //iscarbon already used in spell's parent if(!IS_HERETIC(user)) diff --git a/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm b/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm index 9b63424954158..0c484e312d3dd 100644 --- a/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm +++ b/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm @@ -24,6 +24,7 @@ continue //This is essentially a death mark, use this to finish your opponent quicker. if(target.InCritical() && !HAS_TRAIT(target, TRAIT_NODEATH)) + target.investigate_log("has been killed by fiery rebirth.", INVESTIGATE_DEATHS) target.death() target.adjustFireLoss(20) diff --git a/code/modules/antagonists/incursion/incursion.dm b/code/modules/antagonists/incursion/incursion.dm index bde2dc75b0a03..306168009d6c4 100644 --- a/code/modules/antagonists/incursion/incursion.dm +++ b/code/modules/antagonists/incursion/incursion.dm @@ -171,7 +171,7 @@ objectives = list() var/is_hijacker = GLOB.player_details.len >= 35 ? prob(15) : 0 for(var/i = 1 to max(1, CONFIG_GET(number/incursion_objective_amount))) - forge_single_objective(CLAMP((5 + !is_hijacker)-i, 1, 3), restricted_jobs) //Hijack = 3, 2, 1, 1 no hijack = 3, 3, 2, 1 + forge_single_objective(clamp((5 + !is_hijacker)-i, 1, 3), restricted_jobs) //Hijack = 3, 2, 1, 1 no hijack = 3, 3, 2, 1 if(is_hijacker) if(!(locate(/datum/objective/hijack) in objectives)) add_objective(new/datum/objective/hijack) @@ -179,7 +179,7 @@ add_objective(new/datum/objective/escape/single, FALSE) /datum/team/incursion/proc/forge_single_objective(difficulty=1, list/restricted_jobs) - difficulty = CLAMP(difficulty, 1, 3) + difficulty = clamp(difficulty, 1, 3) switch(difficulty) if(3) if(LAZYLEN(active_ais()) && prob(25)) //25 % diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm index 946ea478f5c5a..a62ef4234ab55 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm @@ -612,6 +612,8 @@ return for(var/mob/M in GLOB.mob_list) if(M.stat != DEAD && M.get_virtual_z_level() == z) + to_chat(M, "You are shredded to atoms!") + M.investigate_log("has been gibbed by a nuclear blast.", INVESTIGATE_DEATHS) M.gib() /* @@ -733,7 +735,7 @@ This is here to make the tiles around the station mininuke change when it's arme return TRUE return ..() -/obj/item/disk/nuclear/suicide_act(mob/user) +/obj/item/disk/nuclear/suicide_act(mob/living/user) user.visible_message("[user] is going delta! It looks like [user.p_theyre()] trying to commit suicide!") playsound(src, 'sound/machines/alarm.ogg', 50, -1, TRUE) for(var/i in 1 to 100) @@ -745,7 +747,7 @@ This is here to make the tiles around the station mininuke change when it's arme user.remove_atom_colour(ADMIN_COLOUR_PRIORITY) user.visible_message("[user] is destroyed by the nuclear blast!") user.adjustOxyLoss(200) - user.death(0) + user.death(FALSE) /obj/item/disk/nuclear/fake fake = TRUE diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm index ed585f33f995a..1f147c110d771 100644 --- a/code/modules/antagonists/revenant/revenant.dm +++ b/code/modules/antagonists/revenant/revenant.dm @@ -530,10 +530,10 @@ revenant = null qdel(src) -/obj/item/ectoplasm/revenant/suicide_act(mob/user) +/obj/item/ectoplasm/revenant/suicide_act(mob/living/user) user.visible_message("[user] is inhaling [src]! It looks like [user.p_theyre()] trying to visit the shadow realm!") scatter() - return (OXYLOSS) + return OXYLOSS /obj/item/ectoplasm/revenant/Destroy() if(!QDELETED(revenant)) diff --git a/code/modules/antagonists/revenant/revenant_abilities.dm b/code/modules/antagonists/revenant/revenant_abilities.dm index 230014931f5f6..484ad8cc40f3d 100644 --- a/code/modules/antagonists/revenant/revenant_abilities.dm +++ b/code/modules/antagonists/revenant/revenant_abilities.dm @@ -72,7 +72,7 @@ if(orbiting) to_chat(src, "You can't siphon essence during orbiting!") return - if(!target.stat && !target.stam_paralyzed) + if(!target.stat && !HAS_TRAIT_FROM(target, TRAIT_INCAPACITATED, STAMINA)) to_chat(src, "[target.p_their(TRUE)] soul is too strong to harvest.") if(prob(10)) to_chat(target, "You feel as if you are being watched.") @@ -100,7 +100,7 @@ if(90 to INFINITY) to_chat(src, "Ah, the perfect soul. [target] will yield massive amounts of essence to you.") if(do_after(src, rand(15, 25), target, timed_action_flags = IGNORE_HELD_ITEM)) //how about now - if(!target.stat && !target.stam_paralyzed) + if(!target.stat && !HAS_TRAIT_FROM(target, TRAIT_INCAPACITATED, STAMINA)) to_chat(src, "[target.p_theyre(TRUE)] now powerful enough to fight off your draining.") to_chat(target, "You feel something tugging across your body before subsiding.") draining = 0 @@ -134,7 +134,9 @@ target.visible_message("[target] slumps onto the ground.", \ "Violets lights, dancing in your vision, getting clo--") drained_mobs.Add(target) - target.death(0) + if(target.stat != DEAD) + target.investigate_log("has died from revenant harvest.", INVESTIGATE_DEATHS) + target.death(FALSE) else to_chat(src, "[target ? "[target] has":"[target.p_theyve(TRUE)]"] been drawn out of your grasp. The link has been broken.") if(target) //Wait, target is WHERE NOW? diff --git a/code/modules/antagonists/revenant/revenant_blight.dm b/code/modules/antagonists/revenant/revenant_blight.dm index a87a518d7f5dc..5ac98e68db402 100644 --- a/code/modules/antagonists/revenant/revenant_blight.dm +++ b/code/modules/antagonists/revenant/revenant_blight.dm @@ -30,7 +30,7 @@ ..() affected_mob.adjustStaminaLoss(1) //Provides gradual exhaustion, but mostly to prevent regeneration and set an upper limit on disease duration to about five minutes if(!(affected_mob.mobility_flags & MOBILITY_STAND)) - if(affected_mob.stam_paralyzed && !finalstage) + if(HAS_TRAIT_FROM(affected_mob, TRAIT_INCAPACITATED, STAMINA) && !finalstage) stage = 5 if(!startresting || restingat != get_turf(affected_mob)) startresting = world.time diff --git a/code/modules/antagonists/slaughter/slaughter.dm b/code/modules/antagonists/slaughter/slaughter.dm index fc7269fbf6afb..b16db081ffad9 100644 --- a/code/modules/antagonists/slaughter/slaughter.dm +++ b/code/modules/antagonists/slaughter/slaughter.dm @@ -154,11 +154,12 @@ /mob/living/simple_animal/slaughter/laughter/ex_act(severity) switch(severity) - if(1) + if(EXPLODE_DEVASTATE) + investigate_log("has died from a devastating explosion.", INVESTIGATE_DEATHS) death() - if(2) + if(EXPLODE_HEAVY) adjustBruteLoss(60) - if(3) + if(EXPLODE_LIGHT) adjustBruteLoss(30) /mob/living/simple_animal/slaughter/laughter/proc/release_friends() diff --git a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm index a6ac41c762e78..f184949b58fe5 100644 --- a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm +++ b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm @@ -391,6 +391,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( if(issilicon(L)) continue to_chat(L, "The blast wave from [src] tears you atom from atom!") + L.investigate_log("has been dusted by a doomsday device.", INVESTIGATE_DEATHS) L.dust() to_chat(world, "The AI cleansed the station of life with the Doomsday device!") SSticker.force_ending = 1 @@ -412,7 +413,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( turret.max_integrity = 200 turret.obj_integrity = 200 turret.emp_proofing = TRUE - turret.AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_CONTENTS | EMP_PROTECT_WIRES) + turret.AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES | EMP_PROTECT_CONTENTS) turret.stun_projectile = /obj/projectile/beam/disabler/pass_glass //// AI defenses are often built with glass, so this is big. turret.stun_projectile_sound = 'sound/weapons/lasercannonfire.ogg' turret.lethal_projectile = /obj/projectile/beam/laser/heavylaser //Once you see it, you will know what it means to FEAR. diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm index 8e1aa524513bc..cdb3511ea8235 100644 --- a/code/modules/antagonists/wizard/equipment/artefact.dm +++ b/code/modules/antagonists/wizard/equipment/artefact.dm @@ -147,6 +147,7 @@ return C.vomit(0, TRUE, TRUE, 3, TRUE) C.spew_organ(3, 2) + C.investigate_log("has died from using telekinesis on a tear in reality.", INVESTIGATE_DEATHS) C.death() /obj/tear_in_reality/Bump(atom/A) @@ -415,7 +416,7 @@ /obj/item/voodoo/suicide_act(mob/living/carbon/user) user.visible_message("[user] links the voodoo doll to [user.p_them()]self and sits on it, infinitely crushing [user.p_them()]self! It looks like [user.p_theyre()] trying to commit suicide!") user.gib() - return(BRUTELOSS) + return BRUTELOSS /obj/item/voodoo/fire_act(exposed_temperature, exposed_volume) if(target) diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 1ed13726a57bd..c4e3a6e1b1347 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -36,9 +36,7 @@ else user.visible_message("[user]'s [src] receives a signal and [user.p_they()] die[user.p_s()] like a gamer!") user.adjustOxyLoss(200)//it sends an electrical pulse to their heart, killing them. or something. - user.death(0) - user.set_suicide(TRUE) - user.suicide_log() + user.death(FALSE) playsound(user, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE) qdel(src) @@ -204,7 +202,6 @@ /obj/item/assembly/signaler/anomaly/manual_suicide(mob/living/carbon/user) user.visible_message("[user]'s [src] is reacting to the radio signal, warping [user.p_their()] body!") user.set_suicide(TRUE) - user.suicide_log() user.gib() /obj/item/assembly/signaler/anomaly/attackby(obj/item/I, mob/user, params) diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index e6ffbfcba0d40..830a8c32f8efc 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -21,7 +21,7 @@ /obj/item/assembly/timer/proc/manual_suicide(mob/living/user) user.visible_message("[user]'s time is up!") user.adjustOxyLoss(200) - user.death(0) + user.death(FALSE) /obj/item/assembly/timer/Initialize(mapload) . = ..() diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm index 756161ee84ef6..5af7263477686 100644 --- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm +++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm @@ -225,7 +225,7 @@ /turf/proc/handle_decompression_floor_rip() /turf/open/floor/handle_decompression_floor_rip(sum) - if(sum > 20 && prob(CLAMP(sum / 20, 0, 15))) + if(sum > 20 && prob(clamp(sum / 20, 0, 15))) if(floor_tile) new floor_tile(src) make_plating() @@ -277,13 +277,13 @@ move_prob = (pressure_difference/pressure_resistance*PROBABILITY_BASE_PRECENT)-PROBABILITY_OFFSET move_prob += pressure_resistance_prob_delta if(move_prob > PROBABILITY_OFFSET && prob(move_prob) && (move_resist != INFINITY) && (!anchored && (max_force >= (move_resist * MOVE_FORCE_PUSH_RATIO))) || (anchored && (max_force >= (move_resist * MOVE_FORCE_FORCEPUSH_RATIO)))) - var/move_force = max_force * CLAMP(move_prob, 0, 100) / 100 + var/move_force = max_force * clamp(move_prob, 0, 100) / 100 if(move_force > 6000) // WALLSLAM HELL TIME OH BOY var/turf/throw_turf = get_ranged_target_turf(get_turf(src), direction, round(move_force / 2000)) if(throw_target && (get_dir(src, throw_target) & direction)) throw_turf = get_turf(throw_target) - var/throw_speed = CLAMP(round(move_force / 3000), 1, 10) + var/throw_speed = clamp(round(move_force / 3000), 1, 10) throw_at(throw_turf, move_force / 3000, throw_speed) else step(src, direction) diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index 43c7b983ff0bd..23e7c52f50a80 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -600,5 +600,5 @@ if(energy_released) var/new_heat_capacity = air.heat_capacity() if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) - air.set_temperature(CLAMP((air.return_temperature()*old_heat_capacity + energy_released)/new_heat_capacity,TCMB,INFINITY)) + air.set_temperature(clamp((air.return_temperature()*old_heat_capacity + energy_released)/new_heat_capacity,TCMB,INFINITY)) return REACTING diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index 2a7638cd6222a..e8f3d97f87275 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -316,6 +316,8 @@ if(world.time - user.last_played_vent > VENT_SOUND_DELAY) user.last_played_vent = world.time playsound(src, 'sound/machines/ventcrawl.ogg', 50, 1, -3) + if(prob(1)) + audible_message("You hear something crawling through the ducts...") else if(is_type_in_typecache(src, GLOB.ventcrawl_machinery) && can_crawl_through()) //if we move in a way the pipe can connect, but doesn't - or we're in a vent user.forceMove(loc) user.visible_message("You hear something squeezing through the ducts...", "You climb out the ventilation system.") @@ -328,7 +330,7 @@ L.handle_ventcrawl(src) return - +/// Whether ventcrawling creatures can move in or out of this machine. /obj/machinery/atmospherics/proc/can_crawl_through() return TRUE diff --git a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm index 2e4a86b9f0149..298b46b58133d 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm @@ -164,13 +164,13 @@ pump_direction = 1 if("set_input_pressure" in signal.data) - input_pressure_min = CLAMP(text2num(signal.data["set_input_pressure"]),0,ONE_ATMOSPHERE*50) + input_pressure_min = clamp(text2num(signal.data["set_input_pressure"]),0,ONE_ATMOSPHERE*50) if("set_output_pressure" in signal.data) - output_pressure_max = CLAMP(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50) + output_pressure_max = clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50) if("set_external_pressure" in signal.data) - external_pressure_bound = CLAMP(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50) + external_pressure_bound = clamp(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50) if("status" in signal.data) spawn(2) @@ -202,7 +202,7 @@ . += "It seems welded shut." /obj/machinery/atmospherics/components/binary/dp_vent_pump/can_crawl_through() - return !welded + return !(machine_stat & BROKEN) && !welded /obj/machinery/atmospherics/components/binary/dp_vent_pump/attack_alien(mob/user) if(!welded || !(do_after(user, 20, target = src))) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index a4152557933bd..7496fa99b06d6 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -177,6 +177,8 @@ to_chat(user, "You cannot unwrench [src], turn it off first!") return FALSE +/obj/machinery/atmospherics/components/binary/pump/can_crawl_through() + return on // If a pump is off, it'll block even when not powered /obj/machinery/atmospherics/components/binary/pump/layer2 piping_layer = 2 diff --git a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm index fd6d447f8c2fe..d751f7f9dad35 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm @@ -40,6 +40,9 @@ It's like a regular ol' straight pipe, but you can turn it on and off. flick("[valve_type]valve_[on][!on]-[set_overlay_offset(piping_layer)]", src) icon_state = "[valve_type]valve_[on ? "on" : "off"]-[set_overlay_offset(piping_layer)]" +/obj/machinery/atmospherics/components/binary/valve/can_crawl_through() + return !(machine_stat & BROKEN) && on // valves should block whatever is trying to go through them, regardless of power + /** * Called by finish_interact(), switch between open and closed, reconcile the air between two pipelines */ diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm index 72567fed7d644..638527e13f1cf 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -166,7 +166,7 @@ if("set_transfer_rate" in signal.data) var/datum/gas_mixture/air1 = airs[1] - transfer_rate = CLAMP(text2num(signal.data["set_transfer_rate"]),0,air1.return_volume()) + transfer_rate = clamp(text2num(signal.data["set_transfer_rate"]),0,air1.return_volume()) if(on != old_on) investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS) @@ -194,6 +194,9 @@ to_chat(user, "The pump quiets down as you turn its limiters back on.") return TRUE +/obj/machinery/atmospherics/components/binary/volume_pump/can_crawl_through() + return on + // mapping /obj/machinery/atmospherics/components/binary/volume_pump/layer2 diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index b0b41bc67b8b9..13a0f189ff778 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -455,7 +455,7 @@ user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/impaired, 1) /obj/machinery/atmospherics/components/unary/cryo_cell/can_crawl_through() - return // can't ventcrawl in or out of cryo. + return FALSE // can't ventcrawl in or out of cryo. /obj/machinery/atmospherics/components/unary/cryo_cell/can_see_pipes() return 0 // you can't see the pipe network when inside a cryo cell. diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm index 1c4789c306ef2..47a12d462d568 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm @@ -133,7 +133,7 @@ if("set_volume_rate" in signal.data) var/number = text2num(signal.data["set_volume_rate"]) var/datum/gas_mixture/air_contents = airs[1] - volume_rate = CLAMP(number, 0, air_contents.return_volume()) + volume_rate = clamp(number, 0, air_contents.return_volume()) addtimer(CALLBACK(src, PROC_REF(broadcast_status)), 2) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm b/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm index adfe8079bab1e..1fa5221e38eac 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm @@ -42,7 +42,7 @@ update_parents() /obj/machinery/atmospherics/components/unary/passive_vent/can_crawl_through() - return TRUE + return TRUE // we don't care about power or being broken /obj/machinery/atmospherics/components/unary/passive_vent/layer2 piping_layer = 2 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 c2da6f4ad18d8..1168685df2b64 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -219,13 +219,13 @@ if("set_internal_pressure" in signal.data) var/old_pressure = internal_pressure_bound - internal_pressure_bound = CLAMP(text2num(signal.data["set_internal_pressure"]),0,ONE_ATMOSPHERE*50) + internal_pressure_bound = clamp(text2num(signal.data["set_internal_pressure"]),0,ONE_ATMOSPHERE*50) if(old_pressure != internal_pressure_bound) investigate_log(" internal pressure was set to [internal_pressure_bound] by [key_name(signal_sender)]",INVESTIGATE_ATMOS) if("set_external_pressure" in signal.data) var/old_pressure = external_pressure_bound - external_pressure_bound = CLAMP(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50) + external_pressure_bound = clamp(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50) if(old_pressure != external_pressure_bound) investigate_log(" external pressure was set to [external_pressure_bound] by [key_name(signal_sender)]",INVESTIGATE_ATMOS) @@ -236,10 +236,10 @@ internal_pressure_bound = 0 if("adjust_internal_pressure" in signal.data) - internal_pressure_bound = CLAMP(internal_pressure_bound + text2num(signal.data["adjust_internal_pressure"]),0,ONE_ATMOSPHERE*50) + internal_pressure_bound = clamp(internal_pressure_bound + text2num(signal.data["adjust_internal_pressure"]),0,ONE_ATMOSPHERE*50) if("adjust_external_pressure" in signal.data) - external_pressure_bound = CLAMP(external_pressure_bound + text2num(signal.data["adjust_external_pressure"]),0,ONE_ATMOSPHERE*50) + external_pressure_bound = clamp(external_pressure_bound + text2num(signal.data["adjust_external_pressure"]),0,ONE_ATMOSPHERE*50) if("init" in signal.data) name = signal.data["init"] @@ -280,13 +280,13 @@ if(welded) . += "It seems welded shut." +/obj/machinery/atmospherics/components/unary/vent_pump/can_crawl_through() + return !(machine_stat & BROKEN) && !welded + /obj/machinery/atmospherics/components/unary/vent_pump/power_change() . = ..() update_icon_nopipes() -/obj/machinery/atmospherics/components/unary/vent_pump/can_crawl_through() - return !welded - /obj/machinery/atmospherics/components/unary/vent_pump/attack_alien(mob/user) if(!welded || !(do_after(user, 20, target = src))) return 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 66b71df3eb503..1f11984bee46b 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -260,7 +260,7 @@ . += "It seems welded shut." /obj/machinery/atmospherics/components/unary/vent_scrubber/can_crawl_through() - return !welded + return !(machine_stat & BROKEN) && !welded /obj/machinery/atmospherics/components/unary/vent_scrubber/attack_alien(mob/user) if(!welded || !(do_after(user, 20, target = src))) diff --git a/code/modules/atmospherics/machinery/pipes/layermanifold.dm b/code/modules/atmospherics/machinery/pipes/layermanifold.dm index 8e6223551b6af..a7c18ebc430a5 100644 --- a/code/modules/atmospherics/machinery/pipes/layermanifold.dm +++ b/code/modules/atmospherics/machinery/pipes/layermanifold.dm @@ -130,9 +130,9 @@ if(initialize_directions & dir) return ..() if((NORTH|EAST) & dir) - user.ventcrawl_layer = CLAMP(user.ventcrawl_layer + 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX) + user.ventcrawl_layer = clamp(user.ventcrawl_layer + 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX) if((SOUTH|WEST) & dir) - user.ventcrawl_layer = CLAMP(user.ventcrawl_layer - 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX) + user.ventcrawl_layer = clamp(user.ventcrawl_layer - 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX) to_chat(user, "You align yourself with the [user.ventcrawl_layer]\th output.") /obj/machinery/atmospherics/pipe/layer_manifold/visible diff --git a/code/modules/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm index e602f3b17804b..a3af0fd37d364 100644 --- a/code/modules/awaymissions/capture_the_flag.dm +++ b/code/modules/awaymissions/capture_the_flag.dm @@ -591,6 +591,7 @@ return if(!(src.team in L.faction)) to_chat(L, "Stay out of the enemy spawn!") + L.investigate_log("has died from entering the enemy spawn in CTF.", INVESTIGATE_DEATHS) L.death() /obj/structure/trap/ctf/red diff --git a/code/modules/awaymissions/mission_code/challenge.dm b/code/modules/awaymissions/mission_code/challenge.dm index 73c3eea8d800d..4df8fbf32f894 100644 --- a/code/modules/awaymissions/mission_code/challenge.dm +++ b/code/modules/awaymissions/mission_code/challenge.dm @@ -30,7 +30,7 @@ active = TRUE locked = TRUE - state = 2 + welded = TRUE /obj/machinery/power/emitter/energycannon/RefreshParts() return diff --git a/code/modules/cargo/bounties/chef.dm b/code/modules/cargo/bounties/chef.dm index a4405e20943d2..0847416702ed6 100644 --- a/code/modules/cargo/bounties/chef.dm +++ b/code/modules/cargo/bounties/chef.dm @@ -43,7 +43,7 @@ name = "Bread" description = "Problems with central planning have led to bread prices skyrocketing. Ship some bread to ease tensions." reward = 1000 - wanted_types = list(/obj/item/food/bread, /obj/item/food/breadslice, /obj/item/reagent_containers/food/snacks/bun, /obj/item/reagent_containers/food/snacks/pizzabread, /obj/item/reagent_containers/food/snacks/rawpastrybase) + wanted_types = list(/obj/item/food/bread, /obj/item/food/breadslice, /obj/item/food/bun, /obj/item/food/pizzabread, /obj/item/food/rawpastrybase) /datum/bounty/item/chef/pie name = "Pie" diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index 014f4147dc900..2175bd891b559 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -473,7 +473,7 @@ /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." + desc = "Officer Paul bought all the handcuffs? Then refill the security vendor with ths crate." cost = 1200 max_supply = 3 contains = list(/obj/item/vending_refill/security) diff --git a/code/modules/client/loadout/loadout_general.dm b/code/modules/client/loadout/loadout_general.dm index 575e800f7636e..35aa804d73e00 100644 --- a/code/modules/client/loadout/loadout_general.dm +++ b/code/modules/client/loadout/loadout_general.dm @@ -16,6 +16,12 @@ path = /obj/item/toy/eightball cost = 500 +/datum/gear/misc/tarotdeck + display_name = "Tarot Deck" + description = "A full 78 card deck of Tarot Cards, no refunds on false predicitons." + path = /obj/item/toy/cards/deck/tarot + cost = 600 + /datum/gear/misc/antagtoken display_name = "Discount Antag Token" description = "Says \"Made in China\" on the back. Seems fishy." diff --git a/code/modules/client/preferences/middleware/antags.dm b/code/modules/client/preferences/middleware/antags.dm index 909b2e8191666..b778531ba1366 100644 --- a/code/modules/client/preferences/middleware/antags.dm +++ b/code/modules/client/preferences/middleware/antags.dm @@ -80,10 +80,13 @@ var/any_changed = FALSE for (var/sent_antag in sent_antags) if(!(sent_antag in valid_antags)) + log_preferences("[preferences?.parent?.ckey]: WARN - Filtered role preference edit for [sent_antag] to [toggled] due to being invalid.") continue if(per_character) + log_preferences("[preferences?.parent?.ckey]: Set per-character role preference for [sent_antag] to [toggled].") preferences.role_preferences["[sent_antag]"] = toggled else + log_preferences("[preferences?.parent?.ckey]: Set global role preference for [sent_antag] to [toggled].") preferences.role_preferences_global["[sent_antag]"] = toggled any_changed = TRUE if(any_changed) diff --git a/code/modules/client/preferences/middleware/keybindings.dm b/code/modules/client/preferences/middleware/keybindings.dm index ba17ee71683be..4c06684595967 100644 --- a/code/modules/client/preferences/middleware/keybindings.dm +++ b/code/modules/client/preferences/middleware/keybindings.dm @@ -27,6 +27,7 @@ /datum/preference_middleware/keybindings/proc/reset_all_keybinds(list/params, mob/user) preferences.set_default_key_bindings(save = TRUE) // this also updates special keybinds preferences.update_static_data(user) + log_preferences("[preferences?.parent?.ckey]: Reset all keybinds.") return TRUE /datum/preference_middleware/keybindings/proc/reset_keybinds_to_defaults(list/params, mob/user) diff --git a/code/modules/client/preferences/middleware/loadout.dm b/code/modules/client/preferences/middleware/loadout.dm index aab738899f3ec..b3de622c806ab 100644 --- a/code/modules/client/preferences/middleware/loadout.dm +++ b/code/modules/client/preferences/middleware/loadout.dm @@ -58,6 +58,7 @@ preferences.purchased_gear += TG.id TG.purchase(user.client) user.client.inc_metabalance((TG.cost * -1), TRUE, "Purchased [TG.display_name].") + log_preferences("[preferences?.parent?.ckey]: Purchased loadout gear: [TG.id] ([TG.display_name])") preferences.mark_undatumized_dirty_player() return TRUE else @@ -69,6 +70,7 @@ return if(TG.id in preferences.equipped_gear) preferences.equipped_gear -= TG.id + log_preferences("[preferences?.parent?.ckey]: Unequipped loadout gear: [TG.id] ([TG.display_name])") preferences.character_preview_view?.update_body() preferences.mark_undatumized_dirty_character() return TRUE @@ -85,6 +87,7 @@ if((TG.id in preferences.purchased_gear)) if(!(TG.subtype_path in type_blacklist) || !(TG.slot in slot_blacklist)) preferences.equipped_gear += TG.id + log_preferences("[preferences?.parent?.ckey]: Equipped loadout gear: [TG.id] ([TG.display_name])") preferences.character_preview_view?.update_body() preferences.mark_undatumized_dirty_character() return TRUE diff --git a/code/modules/client/preferences/middleware/names.dm b/code/modules/client/preferences/middleware/names.dm index 4f9e716a2e304..e1d9930edd1ab 100644 --- a/code/modules/client/preferences/middleware/names.dm +++ b/code/modules/client/preferences/middleware/names.dm @@ -53,4 +53,5 @@ if (!istype(name_preference)) return FALSE + log_preferences("[preferences?.parent?.ckey]: Randomized name preference [name_preference.type]") return preferences.update_preference(name_preference, name_preference.create_random_value(preferences), in_menu = TRUE) diff --git a/code/modules/client/preferences/middleware/quirks.dm b/code/modules/client/preferences/middleware/quirks.dm index 874afb70103d7..0a5269ab2ff9a 100644 --- a/code/modules/client/preferences/middleware/quirks.dm +++ b/code/modules/client/preferences/middleware/quirks.dm @@ -34,11 +34,14 @@ for (var/quirk_name in quirks) var/datum/quirk/quirk = quirks[quirk_name] + if(!ispath(quirk)) + CRASH("Error: invalid quirk value in quirks for quirk_name [quirk_name]: [quirk]") quirk_info[sanitize_css_class_name(quirk_name)] = list( "description" = initial(quirk.desc), "icon" = initial(quirk.icon), "name" = quirk_name, "value" = initial(quirk.value), + "path" = quirk ) return list( diff --git a/code/modules/client/preferences/middleware/random.dm b/code/modules/client/preferences/middleware/random.dm index cbf7ec927b9ed..1b7d5149e2ef9 100644 --- a/code/modules/client/preferences/middleware/random.dm +++ b/code/modules/client/preferences/middleware/random.dm @@ -25,6 +25,7 @@ ) /datum/preference_middleware/random/proc/randomize_character() + log_preferences("[preferences?.parent?.ckey]: Force randomized their character.") for (var/datum/preference/preference as anything in get_preferences_in_priority_order()) if (preferences.should_randomize(preference)) preferences.write_preference(preference, preference.create_random_value(preferences)) @@ -44,6 +45,8 @@ if (!requested_preference.is_randomizable()) return FALSE + log_preferences("[preferences?.parent?.ckey]: Set randomization for [requested_preference.type] to [value].") + if (value == RANDOM_ANTAG_ONLY) preferences.randomize[requested_preference_key] = RANDOM_ANTAG_ONLY else if (value == RANDOM_ENABLED) diff --git a/code/modules/client/preferences/preference_entry.dm b/code/modules/client/preferences/preference_entry.dm index 6464d229af1e4..49ee69d77e192 100644 --- a/code/modules/client/preferences/preference_entry.dm +++ b/code/modules/client/preferences/preference_entry.dm @@ -181,9 +181,12 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key()) /datum/preferences/proc/get_preference_holder(datum/preference/preference_entry) RETURN_TYPE(/datum/preferences_holder) - if(preference_entry.preference_type == PREFERENCE_CHARACTER) - return character_data - return player_data + switch(preference_entry.preference_type) + if(PREFERENCE_CHARACTER) + return character_data + if(PREFERENCE_PLAYER) + return player_data + return null /// Read a /datum/preference type and return its value, only using cached values and queueing any necessary writes. /datum/preferences/proc/read_preference(preference_typepath) @@ -213,8 +216,8 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key()) CRASH("Preference type `[preference_typepath]` is invalid! [extra_info]") - if (preference_entry.preference_type == PREFERENCE_CHARACTER) - CRASH("read_player_preference called on PREFERENCE_CHARACTER type preference [preference_typepath].") + if (preference_entry.preference_type != PREFERENCE_PLAYER) + CRASH("read_player_preference called on [preference_entry.preference_type] type preference [preference_typepath].") return player_data.read_preference(src, preference_entry) @@ -232,9 +235,8 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key()) CRASH("Preference type `[preference_typepath]` is invalid! [extra_info]") - if (preference_entry.preference_type == PREFERENCE_PLAYER) - CRASH("read_character_preference called on PREFERENCE_PLAYER type preference [preference_typepath].") - + if (preference_entry.preference_type != PREFERENCE_CHARACTER) + CRASH("read_character_preference called on [preference_entry.preference_type] type preference [preference_typepath].") return character_data.read_preference(src, preference_entry) /// Set a /datum/preference entry. @@ -258,8 +260,12 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key()) if (!preference.is_accessible(src, ignore_page = !in_menu)) return FALSE + log_preferences("[parent.ckey]: Updating preference [preference.type] TO \"[preference_value]\".") + write_preference(preference, preference_value) + log_preferences("[parent.ckey]: Applying updated preference [preference.type].") + if (preference.preference_type == PREFERENCE_PLAYER) preference.apply_to_client_updated(parent, read_preference(preference.type)) else diff --git a/code/modules/client/preferences/preferences.dm b/code/modules/client/preferences/preferences.dm index ee25bb082ee68..59b14eff55779 100644 --- a/code/modules/client/preferences/preferences.dm +++ b/code/modules/client/preferences/preferences.dm @@ -106,6 +106,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) qdel(src) return src.parent = parent + log_preferences("[parent.ckey]: Preferences datum created.") for (var/middleware_type in subtypesof(/datum/preference_middleware)) middleware += new middleware_type(src) @@ -115,6 +116,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) unlock_content = !!parent.IsByondMember() if(unlock_content) max_save_slots = 8 + log_preferences("[parent.ckey]: Checked BYOND membership: [unlock_content ? "MEMBER" : "NONMEMBER"].") else CRASH("attempted to create a preferences datum without a client!") @@ -124,43 +126,66 @@ GLOBAL_LIST_EMPTY(preferences_datums) save_locked = TRUE - var/loaded_preferences_successfully = load_preferences() - if(loaded_preferences_successfully) + var/pref_load = load_preferences() + var/char_load + if(pref_load == PREFERENCE_LOAD_SUCCESS || pref_load == PREFERENCE_LOAD_NO_DATA) + log_preferences("[parent?.ckey]: Player preferences loaded and applied.") if("6030fe461e610e2be3a2c3e75c06067e" in purchased_gear) //MD5 hash of, "extra character slot" max_save_slots += 1 - if(load_character()) // This returns true if there is a database and character in the active slot. - // Get the profile data - fetch_character_profiles() - create_character_preview_view() - save_locked = FALSE - return - // Begin no database / new player logic. This ONLY fires if there is an SQL error or no database / the player and character is new. + // Apply the loaded preferences!! + if(istype(parent)) + apply_all_client_preferences() + char_load = load_character() + else if(istype(parent) && istype(player_data)) // defaults should already exist because player_data generates them + log_preferences("[parent?.ckey]: Player preferences generated and applied.") + apply_all_client_preferences() + else // Ok what the fuck - abort mission + log_preferences("[parent?.ckey]: ERROR - Player preferences FAILED to load or apply. DELETING.") + save_locked = FALSE + qdel(src) // this will also remove us from the write queue + return - if(!loaded_preferences_successfully) // create a new character object + // character_data is null, so we need to just set it up manually with defaults. + // This means either there is no DB or we are a guest key. + if(pref_load == PREFERENCE_LOAD_IGNORE) + log_preferences("[parent?.ckey]: Applying guest character preferences.") character_data = new(src, default_slot) - // Get the profile data - fetch_character_profiles() + character_data.provide_defaults(src, should_use_informed = FALSE) + + // New player or guest/no DB. Use the fallback species + if(pref_load == PREFERENCE_LOAD_IGNORE || pref_load == PREFERENCE_LOAD_NO_DATA) + log_preferences("[parent?.ckey]: Applying fallback species.") var/new_species_path = GLOB.species_list[get_fallback_species_id() || "human"] character_data.write_preference(src, GLOB.preference_entries[/datum/preference/choiced/species], new_species_path) - // We couldn't load character data so just randomize the character appearance - randomize_appearance_prefs() - if(parent) - apply_all_client_preferences() // apply now since normally this is done in load_preferences(). Defaults were set in preferences_player - // The character name is fresh, update the character list. - update_current_character_profile() + // If the character is fresh in any way, we need to randomize it. + var/fresh_character = pref_load == PREFERENCE_LOAD_IGNORE || char_load == PREFERENCE_LOAD_IGNORE || char_load == PREFERENCE_LOAD_NO_DATA + if(fresh_character) + log_preferences("[parent?.ckey]: New character created - randomizing appearance.") + randomize_appearance_prefs() + + // Provide informed defaults for guests/no DB - these depend on other preferences, so we do that after randomizing. + if(pref_load == PREFERENCE_LOAD_IGNORE) + character_data.provide_defaults(src, should_use_informed = TRUE) + + // Get character profiles, since they haven't been fetched at all yet + fetch_character_profiles() + // The database won't have the correct name yet, so manually load it, if it changed. + if(fresh_character) + update_current_character_profile() create_character_preview_view() save_locked = FALSE // If this was a NEW CKEY ENTRY, and not a guest key (handled in save_preferences()), save it. // Guest keys are ignored by mark_undatumized_dirty - if(!loaded_preferences_successfully) + if(pref_load == PREFERENCE_LOAD_NO_DATA) // This will essentially force a write, while also using the queueing system. // For new ckeys, it is almost guaranteed we already hit the queue, since write_preference (used for when a datumized entry is null) // Will also queue the CKEY. But this will also ensure that undatumized prefs get written. mark_undatumized_dirty_player() - mark_undatumized_dirty_character() + if(char_load == PREFERENCE_LOAD_NO_DATA) + mark_undatumized_dirty_character() /datum/preferences/ui_interact(mob/user, datum/tgui/ui) // IMPORTANT: If someone opens the prefs menu before jobs load, then the jobs menu will be empty for everyone. @@ -249,18 +274,23 @@ GLOBAL_LIST_EMPTY(preferences_datums) /// No switching slots during a save if(save_locked) return + log_preferences("[parent?.ckey]: Slot change event from [default_slot] to [new_slot].") save_locked = TRUE // Save previous character (immediately, delaying this could mean data is lost) save_character() // SAFETY: `load_character` performs sanitization the slot number - if (!load_character(new_slot)) + var/character_load_result = load_character(new_slot) + + if (character_load_result == PREFERENCE_LOAD_NO_DATA || character_load_result == PREFERENCE_LOAD_IGNORE) + log_preferences("[parent?.ckey]: Generating new character in new slot [new_slot].") // there is no character in the slot. Make a new one. Save it. update_current_character_profile() randomize_appearance_prefs() + if(character_load_result == PREFERENCE_LOAD_NO_DATA) // Queue an undatumized save, just in case (it's likely already queued, but we should write undatumized data as well) mark_undatumized_dirty_character() - + log_preferences("[parent?.ckey]: Slot change complete.") for (var/datum/preference_middleware/preference_middleware as anything in middleware) preference_middleware.on_new_character(usr) @@ -382,6 +412,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) /// Applies all PREFERENCE_PLAYER preferences immediately /datum/preferences/proc/apply_all_client_preferences() + log_preferences("[parent?.ckey]: Applying client preferences.") for (var/datum/preference/preference as anything in get_preferences_in_priority_order()) if (preference.preference_type != PREFERENCE_PLAYER) continue @@ -391,6 +422,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) /datum/preferences/proc/update_current_character_profile() if(!islist(character_profiles_cached)) return + log_preferences("[parent?.ckey]: Updating cached character profile.") character_profiles_cached[default_slot] = read_character_preference(/datum/preference/name/real_name) /// Immediately refetch the character list @@ -398,7 +430,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) character_data.get_all_character_names(src) /// Applies the given preferences to a human mob. -/datum/preferences/proc/apply_prefs_to(mob/living/carbon/human/character, icon_updates = TRUE) +/datum/preferences/proc/apply_prefs_to(mob/living/carbon/human/character, icon_updates = TRUE, log = TRUE) + if(log) + log_preferences("[parent?.ckey]: Applying character preferences to mob [key_name(character)] ([REF(character)]).") character.dna.features = list() for (var/datum/preference/preference as anything in get_preferences_in_priority_order()) diff --git a/code/modules/client/preferences/serialization/preferences_character.dm b/code/modules/client/preferences/serialization/preferences_character.dm index eab3a87bec608..5bdaebf54c7ab 100644 --- a/code/modules/client/preferences/serialization/preferences_character.dm +++ b/code/modules/client/preferences/serialization/preferences_character.dm @@ -1,5 +1,6 @@ /// A cache for character preferences data /datum/preferences_holder/preferences_character + pref_type = PREFERENCE_CHARACTER /// INT: Slot number. Used for internal tracking. The slot number also correspnds to the number of slots in the characters list var/slot_number = 0 /// List of column names to be queried @@ -17,23 +18,10 @@ column_names = get_column_names() ..(prefs) -/datum/preferences_holder/preferences_character/proc/load_from_database(datum/preferences/prefs) - if(IS_GUEST_KEY(prefs.parent.key) || !query_data(prefs)) // Query direct, otherwise create informed defaults - for (var/preference_type in GLOB.preference_entries) - var/datum/preference/preference = GLOB.preference_entries[preference_type] - if (preference.preference_type != pref_type) - continue - preference_data[preference.db_key] = preference.deserialize(preference.create_informed_default_value(prefs), prefs) - return FALSE - if(!istype(prefs.parent)) // Client was nulled during query execution - return FALSE - return TRUE - -/datum/preferences_holder/preferences_character/proc/query_data(datum/preferences/prefs) - if(!SSdbcore.IsConnected()) - return FALSE - if(!istype(prefs.parent)) - return FALSE +/datum/preferences_holder/preferences_character/query_data(datum/preferences/prefs) + . = ..() + if(. != PREFERENCE_LOAD_SUCCESS) + return . var/list/values var/datum/DBQuery/Q = SSdbcore.NewQuery( "SELECT [db_column_list(column_names)] FROM [format_table_name("characters")] WHERE ckey=:ckey AND slot=:slot", @@ -41,59 +29,67 @@ ) if(!Q.warn_execute()) qdel(Q) - return FALSE + log_preferences("[prefs.parent.ckey]: ERROR - Datumized character preferences load query failed.") + return PREFERENCE_LOAD_ERROR if(Q.NextRow()) values = Q.item if(!length(values)) // There is no character qdel(Q) - return FALSE + log_preferences("[prefs.parent.ckey]: Datumized character preferences load found no results in row.") + return PREFERENCE_LOAD_NO_DATA else qdel(Q) - return FALSE + log_preferences("[prefs.parent.ckey]: Datumized character preferences load found no rows.") + return PREFERENCE_LOAD_NO_DATA qdel(Q) if(length(values) != length(column_names)) + log_preferences("[prefs.parent.ckey]: ERROR - Datumized character preferences load found the wrong amount of columns.") CRASH("Error querying character data: the returned value length is not equal to the number of columns requested.") for(var/index in 1 to length(values)) var/db_key = column_names[index] var/datum/preference/preference = GLOB.preference_entries_by_key[db_key] if(!istype(preference)) + log_preferences("[prefs.parent.ckey]: ERROR - Datumized character preferences failed to find preference column [db_key] in game, but it was in the database.") CRASH("Could not find preference with db_key [db_key] when querying database.") var/value = values[index] preference_data[db_key] = isnull(value) ? null : preference.deserialize(value, prefs) - return TRUE - -/datum/preferences_holder/preferences_character/proc/write_to_database(datum/preferences/prefs) - . = write_data(prefs) - dirty_prefs.Cut() // clear all dirty preferences + log_preferences("[prefs.parent.ckey]: Successfully loaded datumized character preferences.") + return PREFERENCE_LOAD_SUCCESS -/datum/preferences_holder/preferences_character/proc/write_data(datum/preferences/prefs) - if(!SSdbcore.IsConnected() || !istype(prefs.parent) || IS_GUEST_KEY(prefs.parent.key)) - return FALSE +/datum/preferences_holder/preferences_character/write_data(datum/preferences/prefs) + . = ..() + if(. != PREFERENCE_LOAD_SUCCESS) + return . var/list/column_names_short = list() var/list/new_data = list() for(var/db_key in dirty_prefs) if(!(db_key in preference_data)) + log_preferences("[prefs.parent.ckey]: ERROR - Datumized character preferences write found invalid db_key [db_key] in dirty preferences list.") CRASH("Invalid db_key found in dirty preferences list: [db_key].") var/datum/preference/preference = GLOB.preference_entries_by_key[db_key] if(!istype(preference)) + log_preferences("[prefs.parent.ckey]: ERROR - Datumized character preferences write found invalid db_key [db_key] in dirty preferences list (2).") CRASH("Could not find preference with db_key [db_key] when writing to database.") + if(preference.preference_type != pref_type) + log_preferences("[prefs.parent.ckey]: ERROR - Datumized character preferences write found invalid preference type [preference.preference_type] for [db_key] (want [pref_type]).") + CRASH("Invalid preference located from db_key [db_key] for the preference type [pref_type] (had [preference.preference_type])") new_data[db_key] = preference.serialize(preference_data[db_key]) var/column_name = clean_column_name(preference) if(length(column_name)) column_names_short += column_name if(!length(column_names_short)) // nothing to update - return TRUE + log_preferences("[prefs.parent.ckey]: Datumized character preferences write - no columns to write.") + return PREFERENCE_LOAD_NO_DATA new_data["ckey"] = prefs.parent.ckey new_data["slot"] = slot_number var/datum/DBQuery/Q = SSdbcore.NewQuery( "INSERT INTO [format_table_name("characters")] (ckey, slot, [db_column_list(column_names_short)]) VALUES (:ckey, :slot, [db_column_list(column_names_short, TRUE)]) ON DUPLICATE KEY UPDATE [db_column_values(column_names_short)]", new_data ) var/success = Q.warn_execute() - if(!success) - to_chat(prefs.parent, "Failed to save your character. Please inform the server operator or a maintainer of this error.") qdel(Q) prefs.fail_state = success - return success + log_preferences("[prefs.parent.ckey]: Datumized character preferences write result [success ? "GOOD" : "ERROR"].") + return success ? PREFERENCE_LOAD_SUCCESS : PREFERENCE_LOAD_ERROR /datum/preferences_holder/preferences_character/proc/get_column_names() var/list/result = list() @@ -168,6 +164,7 @@ ) if(!Q.warn_execute()) qdel(Q) + log_preferences("[prefs.parent.ckey]: ERROR - SQL error while retrieving character profiles.") CRASH("An SQL error occurred while retrieving character profile data.") var/list/data = list() for(var/index in 1 to TRUE_MAX_SAVE_SLOTS) @@ -185,3 +182,4 @@ data[values[1]] = values[2] // data[1] = "John Smith" qdel(Q) prefs.character_profiles_cached = data + log_preferences("[prefs.parent.ckey]: Successfully retrieved character profiles.") diff --git a/code/modules/client/preferences/serialization/preferences_database.dm b/code/modules/client/preferences/serialization/preferences_database.dm index e3e26d6ebaa07..2f5e92ff949bc 100644 --- a/code/modules/client/preferences/serialization/preferences_database.dm +++ b/code/modules/client/preferences/serialization/preferences_database.dm @@ -8,6 +8,7 @@ if(parent && IS_GUEST_KEY(parent.key)) // NO saving guests to the DB! return FALSE dirty_undatumized_preferences_player = TRUE + log_preferences("[parent?.ckey]: Undatumized player preference changed.") SSpreferences.queue_write(src) /// Marks undatumized preferences as dirty, so it will be serialized on the next preference write. @@ -17,6 +18,7 @@ if(parent && IS_GUEST_KEY(parent.key)) // NO saving guests to the DB! return FALSE dirty_undatumized_preferences_character = TRUE + log_preferences("[parent?.ckey]: Undatumized character preference changed.") SSpreferences.queue_write(src) /// If any character preference is dirty. @@ -43,14 +45,21 @@ /datum/preferences/proc/load_preferences() if(!istype(parent)) - return FALSE + return PREFERENCE_LOAD_ERROR // Cache their ckey because they can disconnect while datumized prefs read. var/parent_ckey = parent.ckey // Get the datumized stuff first player_data = new(src) - if(!player_data.load_from_database(src)) // checks db connection - return FALSE - + var/load_result = player_data.load_from_database(src) + if(load_result == PREFERENCE_LOAD_ERROR || load_result == null) + log_preferences("[parent_ckey]: ERROR - player_data failed to load datumized player preferences.") + if(istype(parent)) + to_chat(parent, "Failed to load your datumized preferences. Please inform the server operator or a maintainer of this error.") + return PREFERENCE_LOAD_ERROR + if(load_result == PREFERENCE_LOAD_IGNORE) + log_preferences("[parent_ckey]: WARN - player_data load ignored.") + return PREFERENCE_LOAD_IGNORE + log_preferences("[parent_ckey]: Undatumized player preferences loading.") var/datum/DBQuery/read_player_data = SSdbcore.NewQuery( "SELECT CAST(preference_tag AS CHAR) AS ptag, preference_value FROM [format_table_name("preferences")] WHERE ckey=:ckey", list("ckey" = parent_ckey) @@ -62,7 +71,8 @@ if(!read_player_data.Execute()) qdel(read_player_data) - return FALSE + log_preferences("[parent_ckey]: ERROR - Undatumized player preferences load query failed.") + return PREFERENCE_LOAD_ERROR else while(read_player_data.NextRow()) prefmap[read_player_data.item[1]] = read_player_data.item[2] @@ -103,9 +113,12 @@ if(istype(entry)) continue role_preferences_global -= preference + log_preferences("[parent_ckey]: WARN - Cleaned up invalid global role preference entry [preference].") + mark_undatumized_dirty_player() if (!length(key_bindings)) set_default_key_bindings(save = TRUE) + log_preferences("[parent_ckey]: Created default keybindings on load.") else var/any_changed = FALSE for(var/key_name in GLOB.keybindings_by_name) @@ -116,12 +129,12 @@ set_keybind(key_name, keybind.keys.Copy()) any_changed = TRUE if(any_changed) + log_preferences("[parent_ckey]: Assigned new keybind data on load.") if(parent) parent.update_special_keybinds(src) mark_undatumized_dirty_player() // Write the new keybinds to the database. - if(parent) - apply_all_client_preferences() - return TRUE + log_preferences("[parent_ckey]: Player preferences load result: [length(prefmap)] records.") + return length(prefmap) ? PREFERENCE_LOAD_SUCCESS : PREFERENCE_LOAD_NO_DATA #undef READPREF_STR #undef READPREF_INT @@ -136,14 +149,24 @@ if(!istype(parent)) return FALSE if(IS_GUEST_KEY(parent.key)) // NO saving guests to the DB! + log_preferences("[parent.ckey]: WARN - Preference save ignored due to guest key.") return FALSE // Cache their ckey because they can disconnect while datumized prefs write. // DO NOT RENAME THIS SHIT. it will break the defines var/parent_ckey = parent.ckey - if(!player_data?.write_to_database(src)) + var/write_result = player_data?.write_to_database(src) + if(write_result == PREFERENCE_LOAD_ERROR || write_result == null) + log_preferences("[parent_ckey]: ERROR - player_data failed to save datumized player preferences.") + if(istype(parent)) + to_chat(parent, "Failed to save your datumized preferences. Please inform the server operator or a maintainer of this error.") + return FALSE + if(write_result == PREFERENCE_LOAD_IGNORE) + log_preferences("[parent_ckey]: WARN - player_data save ignored.") return FALSE if(!dirty_undatumized_preferences_player) // Nothing to write. Call it a success. + log_preferences("[parent_ckey]: Undatumized player preferences save skipped due to no changes.") return TRUE + log_preferences("[parent_ckey]: Undatumized player preferences saving.") dirty_undatumized_preferences_player = FALSE // we edit this immediately, since the DB query sleeps, the var could be modified during the sleep. var/list/datum/DBQuery/write_queries = list() // do not rename this you muppet @@ -161,6 +184,7 @@ // QuerySelect can execute many queries at once. That name is dumb but w/e SSdbcore.QuerySelect(write_queries, TRUE, TRUE) + log_preferences("[parent_ckey]: Undatumized player preferences saved.") return TRUE #undef PREP_WRITEPREF_STR @@ -181,21 +205,33 @@ /datum/preferences/proc/load_character(slot) if(!istype(parent)) - return FALSE + return PREFERENCE_LOAD_ERROR if(!slot) slot = default_slot slot = sanitize_integer(slot, 1, max_save_slots, initial(default_slot)) if(slot != default_slot) + log_preferences("[parent.ckey]: Slot change applying, from [default_slot] to [slot].") default_slot = slot mark_undatumized_dirty_player() // Cache their ckey because they can disconnect while datumized prefs read. var/parent_ckey = parent.ckey - character_data = new(src, slot) - if(!character_data.load_from_database(src)) // checks db connection - return FALSE + if(character_data) + qdel(character_data) + character_data = new(src, slot) + var/read_result = character_data.load_from_database(src) + + if(read_result == PREFERENCE_LOAD_ERROR || read_result == null) + log_preferences("[parent_ckey]: ERROR - character_data failed to load datumized character preferences.") + if(istype(parent)) + to_chat(parent, "Failed to load your datumized character preferences. Please inform the server operator or a maintainer of this error.") + return PREFERENCE_LOAD_ERROR + if(read_result == PREFERENCE_LOAD_IGNORE) + log_preferences("[parent_ckey]: WARN - character_data load ignored.") + return PREFERENCE_LOAD_IGNORE + log_preferences("[parent_ckey]: Undatumized character preferences loading.") // Do NOT statically cache this or I will kill you. You are asking an evil vareditor to break the DB in a BAD way // also DO NOT rename this var/list/column_names = list( @@ -216,17 +252,21 @@ var/list/values if(!Q.warn_execute()) qdel(Q) - return FALSE + log_preferences("[parent_ckey]: ERROR - Undatumized character preferences load query failed.") + return PREFERENCE_LOAD_ERROR if(Q.NextRow()) values = Q.item if(!length(values)) // There is no character qdel(Q) - return FALSE + log_preferences("[parent_ckey]: Undatumized character preferences load found no results in row.") + return PREFERENCE_LOAD_NO_DATA else qdel(Q) - return FALSE + log_preferences("[parent_ckey]: Undatumized character preferences load found no rows.") + return PREFERENCE_LOAD_NO_DATA qdel(Q) if(length(values) != length(column_names)) + log_preferences("[parent_ckey]: ERROR - Undatumized character preferences load found the wrong amount of columns.") CRASH("Error querying character data: the returned value length is not equal to the number of columns requested.") // Decode @@ -247,6 +287,7 @@ for(var/j in job_preferences) if(job_preferences[j] != JP_LOW && job_preferences[j] != JP_MEDIUM && job_preferences[j] != JP_HIGH) job_preferences -= j + log_preferences("[parent_ckey]: WARN - Cleaned up invalid job preference entry: [j]") mark_undatumized_dirty_character() // Validate role prefs @@ -256,6 +297,7 @@ if(istype(entry) && entry.per_character) continue role_preferences -= preference + log_preferences("[parent_ckey]: WARN - Cleaned up invalid character role preference entry [preference].") mark_undatumized_dirty_character() // Validate equipped gear @@ -272,7 +314,7 @@ equipped_gear -= gear_id mark_undatumized_dirty_character() - return TRUE + return PREFERENCE_LOAD_SUCCESS #undef JSONREAD_PREF @@ -285,13 +327,25 @@ if(!istype(parent)) return FALSE if(IS_GUEST_KEY(parent.key)) // NO saving guests to the DB! + log_preferences("[parent.ckey]: WARN - Character preference save ignored due to guest key.") return FALSE // Cache their ckey because they can disconnect while datumized prefs write. var/parent_ckey = parent.ckey - if(!character_data?.write_to_database(src)) + + var/write_result = character_data?.write_to_database(src) + if(write_result == PREFERENCE_LOAD_ERROR || write_result == null) + log_preferences("[parent_ckey]: ERROR - character_data failed to save datumized character preferences.") + if(istype(parent)) + to_chat(parent, "Failed to save your datumized character preferences. Please inform the server operator or a maintainer of this error.") + return FALSE + if(write_result == PREFERENCE_LOAD_IGNORE) + log_preferences("[parent_ckey]: WARN - character_data save ignored.") return FALSE + if(!dirty_undatumized_preferences_character) // Nothing to write. Call it a success. + log_preferences("[parent_ckey]: Undatumized character preferences save skipped due to no changes.") return TRUE + log_preferences("[parent_ckey]: Undatumized character preferences saving.") dirty_undatumized_preferences_character = FALSE // we edit this immediately, since the DB query sleeps, the var could be modified during the sleep. // DO NOT RENAME THESE LISTS! THANKS!! <3 @@ -311,9 +365,10 @@ ) var/success = Q.warn_execute() if(!success && istype(parent)) - to_chat(parent, "Failed to save your character. Please inform the server operator or a maintainer of this error.") + to_chat(parent, "Failed to save your undatumized character preferences. Please inform the server operator or a maintainer of this error.") qdel(Q) fail_state = success + log_preferences("[parent_ckey]: Undatumized character preferences save status: [success ? "GOOD" : "ERROR"].") return success #undef WRITEPREF_STR @@ -328,25 +383,48 @@ var/pref_type /datum/preferences_holder/New(datum/preferences/prefs) + if(!pref_type) + CRASH("Preferences holder pref_type is [pref_type]") preference_data = list() dirty_prefs = list() - // Read everything into cache + log_preferences("[prefs?.parent?.ckey]: Holder created of type [pref_type].") + +/datum/preferences_holder/proc/provide_defaults(datum/preferences/prefs, should_use_informed) + log_preferences("[prefs?.parent?.ckey]: Holder of type [pref_type] providing defaults (informed: [should_use_informed]).") for (var/preference_type in GLOB.preference_entries) var/datum/preference/preference = GLOB.preference_entries[preference_type] - if (preference.preference_type != pref_type || preference.informed) + if (preference.preference_type != pref_type || (preference.informed != should_use_informed)) continue - // we can't use informed values here. The name will get populated manually - preference_data[preference.db_key] = preference.deserialize(preference.create_default_value(), prefs) + if(should_use_informed) + preference_data[preference.db_key] = preference.deserialize(preference.create_informed_default_value(prefs), prefs) + else + preference_data[preference.db_key] = preference.deserialize(preference.create_default_value(), prefs) + +/datum/preferences_holder/proc/load_from_database(datum/preferences/prefs) + var/result = !IS_GUEST_KEY(prefs.parent.key) ? query_data(prefs) : PREFERENCE_LOAD_IGNORE + if(!istype(prefs.parent)) // Client was nulled during query execution + return PREFERENCE_LOAD_ERROR + return result + +/datum/preferences_holder/proc/query_data(datum/preferences/prefs) + SHOULD_CALL_PARENT(TRUE) + if(!SSdbcore.IsConnected()) + return PREFERENCE_LOAD_IGNORE + if(!istype(prefs.parent)) + return PREFERENCE_LOAD_ERROR + return PREFERENCE_LOAD_SUCCESS /datum/preferences_holder/proc/read_preference(datum/preferences/preferences, datum/preference/preference) SHOULD_NOT_SLEEP(TRUE) var/value = read_raw(preferences, preference) if (isnull(value)) + log_preferences("[preferences?.parent?.ckey]: Creating default value for [preference.type].") value = preference.create_informed_default_value(preferences) if (write_preference(preferences, preference, value)) return value else + log_preferences("[preferences?.parent?.ckey]: Failed to write default value. See runtime log.") CRASH("Couldn't write the default value for [preference.type] (received [value])") return value @@ -361,10 +439,26 @@ /datum/preferences_holder/proc/write_preference(datum/preferences/preferences, datum/preference/preference, value) var/new_value = preference.deserialize(value, preferences) if (!preference.is_valid(new_value)) + log_preferences("[preferences?.parent?.ckey]: Preference value write for [preference.type] TO \"[new_value]\" ignored due to being invalid.") return FALSE preference_data[preference.db_key] = new_value if(!istype(preferences.parent) || IS_GUEST_KEY(preferences.parent.key)) // NO saving guests to the DB! return TRUE dirty_prefs |= preference.db_key SSpreferences.queue_write(preferences) + log_preferences("[preferences?.parent?.ckey]: Preference value write for [preference.type] TO \"[value]\" created.") return TRUE + +/datum/preferences_holder/proc/write_to_database(datum/preferences/prefs) + . = write_data(prefs) + dirty_prefs.Cut() // clear all dirty preferences + +/datum/preferences_holder/proc/write_data(datum/preferences/prefs) + SHOULD_CALL_PARENT(TRUE) + if(!SSdbcore.IsConnected()) + return PREFERENCE_LOAD_IGNORE + if(!istype(prefs.parent)) + return PREFERENCE_LOAD_ERROR + if(IS_GUEST_KEY(prefs.parent.key)) + return PREFERENCE_LOAD_IGNORE + return PREFERENCE_LOAD_SUCCESS diff --git a/code/modules/client/preferences/serialization/preferences_player.dm b/code/modules/client/preferences/serialization/preferences_player.dm index 62e833862bc7e..9f318d9f74a9c 100644 --- a/code/modules/client/preferences/serialization/preferences_player.dm +++ b/code/modules/client/preferences/serialization/preferences_player.dm @@ -2,73 +2,67 @@ /datum/preferences_holder/preferences_player pref_type = PREFERENCE_PLAYER -/datum/preferences_holder/preferences_player/proc/load_from_database(datum/preferences/prefs) - if(IS_GUEST_KEY(prefs.parent.key) || !query_data(prefs)) // Query direct, otherwise create informed defaults - for (var/preference_type in GLOB.preference_entries) - var/datum/preference/preference = GLOB.preference_entries[preference_type] - if (preference.preference_type != pref_type) - continue - preference_data[preference.db_key] = preference.deserialize(preference.create_informed_default_value(prefs), prefs) - // Give the developers +1 sanity points - if(Debugger?.enabled) - prefs.update_preference(/datum/preference/toggle/sound_ambience, FALSE) - prefs.update_preference(/datum/preference/toggle/sound_ship_ambience, FALSE) - prefs.update_preference(/datum/preference/toggle/sound_lobby, FALSE) - return FALSE - if(!istype(prefs.parent)) // Client was nulled during query execution - return FALSE - return TRUE +/datum/preferences_holder/preferences_player/load_from_database(datum/preferences/prefs) + . = ..() + // Give the developers +1 sanity points + if(. == PREFERENCE_LOAD_IGNORE && Debugger?.enabled) + prefs.update_preference(/datum/preference/toggle/sound_ambience, FALSE) + prefs.update_preference(/datum/preference/toggle/sound_ship_ambience, FALSE) + prefs.update_preference(/datum/preference/toggle/sound_lobby, FALSE) + return . -/datum/preferences_holder/preferences_player/proc/query_data(datum/preferences/prefs) - if(!SSdbcore.IsConnected()) - return FALSE - if(!istype(prefs.parent)) - return FALSE +/datum/preferences_holder/preferences_player/query_data(datum/preferences/prefs) + . = ..() + if(. != PREFERENCE_LOAD_SUCCESS) + return . var/datum/DBQuery/Q = SSdbcore.NewQuery( "SELECT CAST(preference_tag AS CHAR) AS ptag, preference_value FROM [format_table_name("preferences")] WHERE ckey=:ckey", list("ckey" = prefs.parent.ckey) ) if(!Q.warn_execute()) qdel(Q) - return FALSE + log_preferences("[prefs.parent.ckey]: ERROR - Datumized player preferences load query failed.") + return PREFERENCE_LOAD_ERROR var/any_data = FALSE while(Q.NextRow()) var/db_key = Q.item[1] var/value = Q.item[2] var/datum/preference/preference = GLOB.preference_entries_by_key[db_key] if(!preference) - // If you ever want to error for unknown tags, this would be helpful. - // As of now we don't really care since it doesn't help anything to throw runtimes everywhere. - //CRASH("Unknown preference tag in database: [db_key] for ckey [prefs.parent.ckey]") + if(!(db_key in GLOB.undatumized_preference_tags_player)) + log_preferences("[prefs.parent.ckey]: WARN - Datumized player preferences failed to find preference [db_key] in game, but it was in the database.") continue preference_data[db_key] = isnull(value) ? null : preference.deserialize(value, prefs) any_data = TRUE qdel(Q) - return any_data + log_preferences("[prefs.parent.ckey]: Successfully loaded datumized character preferences[!any_data ? " (no records found)" : ""].") + return any_data ? PREFERENCE_LOAD_SUCCESS : PREFERENCE_LOAD_NO_DATA -/datum/preferences_holder/preferences_player/proc/write_to_database(datum/preferences/prefs) - . = write_data(prefs) - dirty_prefs.Cut() // clear all dirty preferences - -/datum/preferences_holder/preferences_player/proc/write_data(datum/preferences/prefs) - if(!SSdbcore.IsConnected() || !istype(prefs.parent) || IS_GUEST_KEY(prefs.parent.key)) - return FALSE +/datum/preferences_holder/preferences_player/write_data(datum/preferences/prefs) + . = ..() + if(. != PREFERENCE_LOAD_SUCCESS) + return . var/list/sql_inserts = list() for(var/db_key in dirty_prefs) if(!(db_key in preference_data)) + log_preferences("[prefs.parent.ckey]: ERROR - Datumized player preferences write found invalid db_key [db_key] in dirty preferences list.") CRASH("Invalid db_key found in dirty preferences list: [db_key].") var/datum/preference/preference = GLOB.preference_entries_by_key[db_key] if(!istype(preference)) + log_preferences("[prefs.parent.ckey]: ERROR - Datumized player preferences write found invalid db_key [db_key] in dirty preferences list (2).") CRASH("Could not find preference with db_key [db_key] when writing to database.") + if(preference.preference_type != pref_type) + log_preferences("[prefs.parent.ckey]: ERROR - Datumized player preferences write found invalid preference type [preference.preference_type] for [db_key] (want [pref_type]).") + CRASH("Invalid preference located from db_key [db_key] for the preference type [pref_type] (had [preference.preference_type])") sql_inserts += list(list( "ckey" = prefs.parent.ckey, "preference_tag" = db_key, "preference_value" = preference.serialize(preference_data[db_key]) )) if(!length(sql_inserts)) // nothing to update - return TRUE + log_preferences("[prefs.parent.ckey]: Datumized player preferences write - no columns to write.") + return PREFERENCE_LOAD_NO_DATA var/success = SSdbcore.MassInsert(format_table_name("preferences"), sql_inserts, duplicate_key = TRUE, warn = TRUE) - if(!success) - to_chat(prefs.parent, "Failed to save your player preferences. Please inform the server operator or a maintainer of this error.") prefs.fail_state = success - return success + log_preferences("[prefs.parent.ckey]: Datumized player preferences write result [success ? "GOOD" : "ERROR"].") + return success ? PREFERENCE_LOAD_SUCCESS : PREFERENCE_LOAD_ERROR diff --git a/code/modules/client/preferences/submodules/preference_character_preview.dm b/code/modules/client/preferences/submodules/preference_character_preview.dm index ff228bc69ee07..90fbc06d3ae5f 100644 --- a/code/modules/client/preferences/submodules/preference_character_preview.dm +++ b/code/modules/client/preferences/submodules/preference_character_preview.dm @@ -15,7 +15,7 @@ return image('icons/mob/robots.dmi', icon_state = "robot", dir = SOUTH) // Set up the dummy for its photoshoot - apply_prefs_to(mannequin, TRUE) + apply_prefs_to(mannequin, TRUE, log = FALSE) // Normalize size, since it doesn't scale properly in the preview. mannequin.dna.features["body_size"] = "Normal" mannequin.dna.update_body_size() diff --git a/code/modules/client/preferences/submodules/preference_jobs.dm b/code/modules/client/preferences/submodules/preference_jobs.dm index f384538b987ac..e1785a6dfbee1 100644 --- a/code/modules/client/preferences/submodules/preference_jobs.dm +++ b/code/modules/client/preferences/submodules/preference_jobs.dm @@ -2,6 +2,8 @@ if (!job) return FALSE + log_preferences("[parent?.ckey]: Set [job.title] preference to level [level].") + if (level == JP_HIGH) var/datum/job/overflow_role = SSjob.overflow_role var/overflow_role_title = initial(overflow_role.title) @@ -11,8 +13,10 @@ // Overflow role needs to go to NEVER, not medium! if(other_job == overflow_role_title) job_preferences[other_job] = null + log_preferences("[parent?.ckey]: Set [other_job] preference to level null.") else job_preferences[other_job] = JP_MEDIUM + log_preferences("[parent?.ckey]: Set [other_job] preference to level [JP_MEDIUM].") if(level == null) job_preferences -= job.title diff --git a/code/modules/client/preferences/submodules/preference_keybindings.dm b/code/modules/client/preferences/submodules/preference_keybindings.dm index d54c1fc066f03..4fdf3014f676b 100644 --- a/code/modules/client/preferences/submodules/preference_keybindings.dm +++ b/code/modules/client/preferences/submodules/preference_keybindings.dm @@ -28,6 +28,7 @@ return FALSE if(!islist(hotkeys)) return + log_preferences("[parent?.ckey]: Set keybind [keybind_name] to [english_list(hotkeys)].") key_bindings[keybind_name] = hotkeys key_bindings_by_key = get_key_bindings_by_key(key_bindings) mark_undatumized_dirty_player() diff --git a/code/modules/client/preferences/submodules/preference_randomization.dm b/code/modules/client/preferences/submodules/preference_randomization.dm index 70ffa96944def..9c557d2c9a523 100644 --- a/code/modules/client/preferences/submodules/preference_randomization.dm +++ b/code/modules/client/preferences/submodules/preference_randomization.dm @@ -5,6 +5,7 @@ continue if (preference.is_randomizable()) + log_preferences("[parent?.ckey]: Randomizing [preference.type] from flags [randomize_flags == ALL ? "ALL" : randomize_flags].") write_preference(preference, preference.create_random_value(src)) /// Randomizes the character according to preferences. @@ -18,6 +19,7 @@ for (var/datum/preference/preference as anything in get_preferences_in_priority_order()) if (should_randomize(preference, antag_override)) + log_preferences("[parent?.ckey]: Randomizing [preference.type] according to randomization options.") write_preference(preference, preference.create_random_value(src)) /// Returns the default `randomize` variable ouptut diff --git a/code/modules/client/verbs/suicide.dm b/code/modules/client/verbs/suicide.dm index c2943b1c67c54..93e95ab50e35a 100644 --- a/code/modules/client/verbs/suicide.dm +++ b/code/modules/client/verbs/suicide.dm @@ -75,12 +75,15 @@ adjustOxyLoss(200/damage_mod) if(damagetype & MANUAL_SUICIDE) //Assume the object will handle the death. + investigate_log("has died from committing suicide[held_item ? " with [held_item]" : ""].", INVESTIGATE_DEATHS) return //If something went wrong, just do normal oxyloss if(!(damagetype & (BRUTELOSS | FIRELOSS | TOXLOSS | OXYLOSS) )) adjustOxyLoss(max(200 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0)) + investigate_log("has died from committing suicide[held_item ? " with [held_item]" : ""].", INVESTIGATE_DEATHS) + death(FALSE) ghostize(FALSE,SENTIENCE_ERASE) // Disallows reentering body and disassociates mind @@ -113,6 +116,7 @@ suicide_log() adjustOxyLoss(max(200 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0)) + investigate_log("has died from committing suicide[held_item ? " with [held_item]" : ""].", INVESTIGATE_DEATHS) death(FALSE) /mob/living/brain/verb/suicide() @@ -241,6 +245,7 @@ ghostize(FALSE,SENTIENCE_ERASE) // Disallows reentering body and disassociates mind /mob/living/proc/suicide_log() + investigate_log("has died from committing suicide.", INVESTIGATE_DEATHS) log_game("[key_name(src)] committed suicide at [AREACOORD(src)] as [src.type].") if(CONFIG_GET(flag/restricted_suicide)) message_admins("[key_name(src)] committed suicide at [AREACOORD(src)] as [src.type].") diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 33307f56c9e7e..2161a31b30e1f 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -415,9 +415,7 @@ BLIND // can't see anything if(iscarbon(user)) var/mob/living/carbon/C = user C.head_update(src, forced = TRUE) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() return TRUE /obj/item/clothing/proc/visor_toggling() //handles all the actual toggling of flags diff --git a/code/modules/clothing/glasses/engine_goggles.dm b/code/modules/clothing/glasses/engine_goggles.dm index 39e3e700cd279..35f4c2a09b928 100644 --- a/code/modules/clothing/glasses/engine_goggles.dm +++ b/code/modules/clothing/glasses/engine_goggles.dm @@ -52,9 +52,7 @@ H.update_sight() update_icon() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() /obj/item/clothing/glasses/meson/engine/attack_self(mob/user) toggle_mode(user, TRUE) diff --git a/code/modules/clothing/head/beanie.dm b/code/modules/clothing/head/beanie.dm index f8a26ac036135..aebb48b24e90e 100644 --- a/code/modules/clothing/head/beanie.dm +++ b/code/modules/clothing/head/beanie.dm @@ -87,7 +87,7 @@ name = "durathread beanie" desc = "A beanie made from durathread, its resilient fibres provide some protection to the wearer." icon_state = "beaniedurathread" - armor = list(MELEE = 15, BULLET = 5, LASER = 15, ENERGY = 5, BOMB = 10, BIO = 0, RAD = 0, FIRE = 30, ACID = 5, STAMINA = 20) + armor = list(MELEE = 15, BULLET = 25, LASER = 15, ENERGY = 5, BOMB = 10, BIO = 0, RAD = 0, FIRE = 30, ACID = 5, STAMINA = 20) /obj/item/clothing/head/beanie/waldo name = "red striped bobble hat" diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index 116eeedf7d66f..6f3549bbfe48d 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -83,6 +83,9 @@ cold_protection = HEAD heat_protection = HEAD dog_fashion = null + flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEFACIALHAIR|HIDESNOUT|HIDEMASK + flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH + /obj/item/clothing/head/hardhat/white name = "white hard hat" diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 970d9d6cc047a..4db0948bde051 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -66,9 +66,7 @@ var/mob/living/carbon/human/H = loc H.update_inv_head() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() /obj/item/clothing/head/helmet/attackby(obj/item/I, mob/user, params) @@ -391,11 +389,11 @@ /obj/item/clothing/head/helmet/durathread name = "durathread helmet" - desc = "A helmet made from durathread and leather." + desc = "A helmet made from durathread, a strong material commonly used for ballistic protection." icon_state = "durathread" item_state = "durathread" resistance_flags = FLAMMABLE - armor = list(MELEE = 20, BULLET = 10, LASER = 30, ENERGY = 5, BOMB = 15, BIO = 0, RAD = 0, FIRE = 40, ACID = 50, STAMINA = 30) + armor = list(MELEE = 20, BULLET = 40, LASER = 30, ENERGY = 5, BOMB = 15, BIO = 0, RAD = 0, FIRE = 40, ACID = 50, STAMINA = 30) strip_delay = 60 /obj/item/clothing/head/helmet/rus_helmet diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 6b8381be237c3..a8452422465fe 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -15,7 +15,7 @@ dynamic_hair_suffix = "" dog_fashion = /datum/dog_fashion/head/chef -/obj/item/clothing/head/chefhat/suicide_act(mob/user) +/obj/item/clothing/head/chefhat/suicide_act(mob/living/user) user.visible_message("[user] is donning [src]! It looks like [user.p_theyre()] trying to become a chef.") user.say("Bork Bork Bork!", forced = "chef hat suicide") sleep(20) @@ -145,7 +145,7 @@ name = "durathread beret" desc = "A beret made from durathread, its resilient fibres provide some protection to the wearer." icon_state = "beretdurathread" - armor = list(MELEE = 15, BULLET = 5, LASER = 15, ENERGY = 20, BOMB = 10, BIO = 0, RAD = 0, FIRE = 30, ACID = 5, STAMINA = 20) + armor = list(MELEE = 15, BULLET = 25, LASER = 15, ENERGY = 20, BOMB = 10, BIO = 0, RAD = 0, FIRE = 30, ACID = 5, STAMINA = 20) //Security diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index bcc6790770d8e..a4374a061b093 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -200,15 +200,15 @@ desc = "A really cool hat if you're a mobster. A really lame hat if you're not." pocket_storage_component_path = /datum/component/storage/concrete/pockets/small -/obj/item/clothing/head/fedora/suicide_act(mob/user) +/obj/item/clothing/head/fedora/suicide_act(mob/living/user) if(user.gender == FEMALE) - return 0 + return var/mob/living/carbon/human/H = user user.visible_message("[user] is donning [src]! It looks like [user.p_theyre()] trying to be nice to girls.") user.say("M'lady.", forced = "fedora suicide") sleep(10) H.facial_hair_style = "Neckbeard" - return(BRUTELOSS) + return BRUTELOSS /obj/item/clothing/head/sombrero name = "sombrero" diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index 92427e6120d87..daf35b7ed9bc0 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -22,7 +22,7 @@ RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(clean_blood)) /obj/item/clothing/shoes/suicide_act(mob/living/carbon/user) - if(rand(2)>1) + if(prob(50)) user.visible_message("[user] begins tying \the [src] up waaay too tightly! It looks like [user.p_theyre()] trying to commit suicide!") var/obj/item/bodypart/l_leg = user.get_bodypart(BODY_ZONE_L_LEG) var/obj/item/bodypart/r_leg = user.get_bodypart(BODY_ZONE_R_LEG) @@ -37,8 +37,8 @@ user.visible_message("[user] is bashing [user.p_their()] own head in with [src]! Ain't that a kick in the head?") for(var/i in 1 to 3) sleep(3) - playsound(user, 'sound/weapons/genhit2.ogg', 50, 1) - return(BRUTELOSS) + playsound(user, 'sound/weapons/genhit2.ogg', 50, TRUE) + return BRUTELOSS /obj/item/clothing/shoes/worn_overlays(mutable_appearance/standing, isinhands = FALSE) . = list() diff --git a/code/modules/clothing/shoes/bananashoes.dm b/code/modules/clothing/shoes/bananashoes.dm index 8fee7440072fb..b58cdcd7c86a3 100644 --- a/code/modules/clothing/shoes/bananashoes.dm +++ b/code/modules/clothing/shoes/bananashoes.dm @@ -62,6 +62,4 @@ else icon_state = "clown_prototype_off" usr.update_inv_shoes() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index 75913d615fa1d..d2475cf7ac92a 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -33,9 +33,7 @@ to_chat(user, "You [magpulse ? "enable" : "disable"] the mag-pulse traction system.") user.update_inv_shoes() //so our mob-overlays update user.update_gravity(user.has_gravity()) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() /obj/item/clothing/shoes/magboots/negates_gravity() return isspaceturf(get_turf(src)) ? FALSE : magpulse //We don't mimick gravity on space turfs @@ -79,9 +77,7 @@ to_chat(user, "You [magpulse ? "enable" : "disable"] the mag-pulse traction system.") user.update_inv_shoes() user.update_gravity(user.has_gravity()) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() /obj/item/clothing/shoes/magboots/crushing desc = "Normal looking magboots that are altered to increase magnetic pull to crush anything underfoot." diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index b160f9943c167..f6ab865e2ff16 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -51,9 +51,7 @@ set_light_on(on) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() /obj/item/clothing/head/helmet/space/hardsuit/dropped(mob/user) ..() @@ -454,9 +452,7 @@ if(iscarbon(user)) var/mob/living/carbon/C = user C.head_update(src, forced = 1) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() /obj/item/clothing/head/helmet/space/hardsuit/syndi/proc/toggle_hardsuit_mode(mob/user) //Helmet Toggles Suit Mode if(linkedsuit) diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index f192eec651e13..f19bba0ef3643 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -285,14 +285,14 @@ /obj/item/clothing/suit/armor/vest/durathread name = "durathread vest" - desc = "A vest made of durathread with strips of leather acting as trauma plates." + desc = "A bulletproof vest made from durathread, an inexpesive but relatively effective form of protection." icon_state = "durathread" item_state = "durathread" strip_delay = 60 equip_delay_other = 40 max_integrity = 200 resistance_flags = FLAMMABLE - armor = list(MELEE = 20, BULLET = 10, LASER = 30, ENERGY = 40, BOMB = 15, BIO = 0, RAD = 0, FIRE = 40, ACID = 50, STAMINA = 30) + armor = list(MELEE = 20, BULLET = 40, LASER = 30, ENERGY = 40, BOMB = 15, BIO = 0, RAD = 0, FIRE = 40, ACID = 50, STAMINA = 30) /obj/item/clothing/suit/armor/vest/russian name = "russian vest" diff --git a/code/modules/clothing/suits/cloaks.dm b/code/modules/clothing/suits/cloaks.dm index 935fd3ac08407..4405c35131a2c 100644 --- a/code/modules/clothing/suits/cloaks.dm +++ b/code/modules/clothing/suits/cloaks.dm @@ -11,9 +11,9 @@ flags_inv = HIDESUITSTORAGE pocket_storage_component_path = /datum/component/storage/concrete/pockets/exo/cloak -/obj/item/clothing/neck/cloak/suicide_act(mob/user) +/obj/item/clothing/neck/cloak/suicide_act(mob/living/user) user.visible_message("[user] is strangling [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return(OXYLOSS) + return OXYLOSS /obj/item/clothing/neck/cloak/hos name = "head of security's cloak" diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index c6480626984f8..b728ad9424bd9 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -579,6 +579,7 @@ body_parts_covered = CHEST|GROIN attack_verb = list("warned", "cautioned", "smashed") armor = list(MELEE = 5, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, STAMINA = 0) + pocket_storage_component_path = null @@ -969,11 +970,11 @@ name = "durathread hoodie" desc = "A hoodie made from durathread, its resilient fibres provide some protection to the wearer." color = "#8291a1" - armor = list(MELEE = 15, LASER = 10, FIRE = 40, ACID = 10, BOMB = 5, STAMINA = 30) + armor = list(MELEE = 15, BULLET = 25, LASER = 10, FIRE = 40, ACID = 10, BOMB = 5, STAMINA = 30) hoodtype = /obj/item/clothing/head/hooded/hoodie/durathread /obj/item/clothing/head/hooded/hoodie/durathread name = "durathread hoodie hood" desc = "A duratread hood attached to your hoodie, robust as." - armor = list(MELEE = 5, LASER = 5, FIRE = 20, ACID = 5, BOMB = 5, STAMINA = 15) + armor = list(MELEE = 5, BULLET = 5, LASER = 5, FIRE = 20, ACID = 5, BOMB = 5, STAMINA = 15) color = "#8291a1" diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm index ac7a8f2d2c737..a079a0db3e03f 100644 --- a/code/modules/clothing/suits/toggles.dm +++ b/code/modules/clothing/suits/toggles.dm @@ -49,9 +49,8 @@ hood.moveToNullspace() //Hides hood in nullspace instead of within the pocket of whatever it's on if(qdel_hood) QDEL_NULL(hood) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + + update_action_buttons() /obj/item/clothing/suit/hooded/dropped() ..() @@ -78,9 +77,7 @@ suittoggled = TRUE icon_state = "[initial(icon_state)]_t" H.update_inv_wear_suit() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() else RemoveHood() @@ -134,9 +131,7 @@ src.worn_icon_state = "[initial(icon_state)]_t" src.suittoggled = TRUE usr.update_inv_wear_suit() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() /obj/item/clothing/suit/toggle/examine(mob/user) . = ..() diff --git a/code/modules/clothing/under/color.dm b/code/modules/clothing/under/color.dm index defc0c9d0200c..d40e27fd49778 100644 --- a/code/modules/clothing/under/color.dm +++ b/code/modules/clothing/under/color.dm @@ -213,13 +213,13 @@ name = "durathread jumpsuit" desc = "A jumpsuit made from durathread, its resilient fibres provide some protection to the wearer." greyscale_colors = "#8291a1" - armor = list(MELEE = 10, LASER = 10, FIRE = 40, ACID = 10, BOMB = 5, ENERGY = 20, STAMINA = 20) + armor = list(MELEE = 10, BULLET = 15, LASER = 10, FIRE = 40, ACID = 10, BOMB = 5, ENERGY = 20, STAMINA = 20) /obj/item/clothing/under/color/jumpskirt/durathread name = "durathread jumpskirt" desc = "A jumpskirt made from durathread, its resilient fibres provide some protection to the wearer." greyscale_colors = "#8291a1" - armor = list(MELEE = 10, LASER = 10, FIRE = 40, ACID = 10, BOMB = 5, ENERGY = 20, STAMINA = 20) + armor = list(MELEE = 10, BULLET = 15, LASER = 10, FIRE = 40, ACID = 10, BOMB = 5, ENERGY = 20, STAMINA = 20) /obj/item/clothing/under/color/rainbow name = "rainbow jumpsuit" diff --git a/code/modules/detectivework/footprints_and_rag.dm b/code/modules/detectivework/footprints_and_rag.dm index 3757f5c985c79..1957c914783e5 100644 --- a/code/modules/detectivework/footprints_and_rag.dm +++ b/code/modules/detectivework/footprints_and_rag.dm @@ -19,9 +19,9 @@ volume = 5 spillable = FALSE -/obj/item/reagent_containers/glass/rag/suicide_act(mob/user) +/obj/item/reagent_containers/glass/rag/suicide_act(mob/living/user) user.visible_message("[user] is smothering [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (OXYLOSS) + return OXYLOSS /obj/item/reagent_containers/glass/rag/afterattack(atom/A as obj|turf|area, mob/user,proximity) . = ..() diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 8c5c3a584cfcd..a6fee0fa45704 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -267,7 +267,7 @@ name = "cup ramen" desc = "Just add 5ml of water, self heats! A taste that reminds you of your school years. Now new with salty flavour!" icon_state = "ramen" - list_reagents = list(/datum/reagent/consumable/dry_ramen = 15, /datum/reagent/consumable/sodiumchloride = 3) + list_reagents = list(/datum/reagent/consumable/dry_ramen = 15, /datum/reagent/consumable/sodiumchloride = 3, /datum/reagent/consumable/maltodextrin = 10) foodtype = GRAIN isGlass = FALSE custom_price = 38 diff --git a/code/modules/food_and_drinks/food/condiment.dm b/code/modules/food_and_drinks/food/condiment.dm index 169a1832828d2..2a06c93634a65 100644 --- a/code/modules/food_and_drinks/food/condiment.dm +++ b/code/modules/food_and_drinks/food/condiment.dm @@ -152,7 +152,7 @@ volume = 20 list_reagents = list(/datum/reagent/consumable/sodiumchloride = 20) -/obj/item/reagent_containers/food/condiment/saltshaker/suicide_act(mob/user) +/obj/item/reagent_containers/food/condiment/saltshaker/suicide_act(mob/living/user) user.visible_message("[user] begins to swap forms with the salt shaker! It looks like [user.p_theyre()] trying to commit suicide!") var/newname = "[name]" name = "[user.name]" @@ -198,7 +198,7 @@ desc = "A big bag of flour. Good for baking!" icon_state = "flour" item_state = "flour" - list_reagents = list(/datum/reagent/consumable/flour = 30) + list_reagents = list(/datum/reagent/consumable/flour = 50) /obj/item/reagent_containers/food/condiment/soymilk name = "soy milk" @@ -214,7 +214,7 @@ desc = "A big bag of rice. Good for cooking!" icon_state = "rice" item_state = "flour" - list_reagents = list(/datum/reagent/consumable/rice = 30) + list_reagents = list(/datum/reagent/consumable/rice = 50) /obj/item/reagent_containers/food/condiment/soysauce name = "soy sauce" diff --git a/code/modules/food_and_drinks/food/snacks/dough.dm b/code/modules/food_and_drinks/food/snacks/dough.dm deleted file mode 100644 index f8849de2ed06b..0000000000000 --- a/code/modules/food_and_drinks/food/snacks/dough.dm +++ /dev/null @@ -1,131 +0,0 @@ - - -/////////////////// Dough Ingredients //////////////////////// - -/obj/item/reagent_containers/food/snacks/dough - name = "dough" - desc = "A piece of dough." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "dough" - cooked_type = /obj/item/food/bread/plain - list_reagents = list(/datum/reagent/consumable/nutriment = 6) - w_class = WEIGHT_CLASS_NORMAL - tastes = list("dough" = 1) - foodtype = GRAIN - - -// Dough + rolling pin = flat dough -/obj/item/reagent_containers/food/snacks/dough/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/kitchen/rollingpin)) - if(isturf(loc)) - new /obj/item/reagent_containers/food/snacks/flatdough(loc) - to_chat(user, "You flatten [src].") - qdel(src) - else - to_chat(user, "You need to put [src] on a surface to roll it out!") - else - ..() - - -// sliceable into 3xdoughslices -/obj/item/reagent_containers/food/snacks/flatdough - name = "flat dough" - desc = "A flattened dough." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "flat dough" - slice_path = /obj/item/reagent_containers/food/snacks/doughslice - slices_num = 3 - cooked_type = /obj/item/reagent_containers/food/snacks/pizzabread - list_reagents = list(/datum/reagent/consumable/nutriment = 6) - w_class = WEIGHT_CLASS_NORMAL - tastes = list("dough" = 1) - foodtype = GRAIN - -/obj/item/reagent_containers/food/snacks/pizzabread - name = "pizza bread" - desc = "Add ingredients to make a pizza." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "pizzabread" - list_reagents = list(/datum/reagent/consumable/nutriment = 7) - w_class = WEIGHT_CLASS_NORMAL - tastes = list("bread" = 1) - foodtype = GRAIN - - -/obj/item/reagent_containers/food/snacks/doughslice - name = "dough slice" - desc = "A slice of dough. Can be cooked into a bun." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "doughslice" - cooked_type = /obj/item/reagent_containers/food/snacks/bun - filling_color = "#CD853F" - tastes = list("dough" = 1) - foodtype = GRAIN - - -/obj/item/reagent_containers/food/snacks/bun - name = "bun" - desc = "A base for any self-respecting burger." - icon = 'icons/obj/food/burgerbread.dmi' - icon_state = "bun" - list_reagents = list(/datum/reagent/consumable/nutriment = 1) - filling_color = "#CD853F" - tastes = list("bun" = 1) // the bun tastes of bun. - foodtype = GRAIN - -/obj/item/reagent_containers/food/snacks/cakebatter - name = "cake batter" - desc = "Cook it to get a cake." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "cakebatter" - cooked_type = /obj/item/food/cake/plain - list_reagents = list(/datum/reagent/consumable/nutriment = 9) - w_class = WEIGHT_CLASS_NORMAL - tastes = list("batter" = 1) - foodtype = GRAIN | DAIRY - -// Cake batter + rolling pin = pie dough -/obj/item/reagent_containers/food/snacks/cakebatter/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/kitchen/rollingpin)) - if(isturf(loc)) - new /obj/item/reagent_containers/food/snacks/piedough(loc) - to_chat(user, "You flatten [src].") - qdel(src) - else - to_chat(user, "You need to put [src] on a surface to roll it out!") - else - ..() - -/obj/item/reagent_containers/food/snacks/piedough - name = "pie dough" - desc = "Cook it to get a pie." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "piedough" - slice_path = /obj/item/reagent_containers/food/snacks/rawpastrybase - slices_num = 3 - cooked_type = /obj/item/reagent_containers/food/snacks/pie/plain - list_reagents = list(/datum/reagent/consumable/nutriment = 9) - w_class = WEIGHT_CLASS_NORMAL - tastes = list("dough" = 1) - foodtype = GRAIN | DAIRY - -/obj/item/reagent_containers/food/snacks/rawpastrybase - name = "raw pastry base" - desc = "Must be cooked before use." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "rawpastrybase" - cooked_type = /obj/item/reagent_containers/food/snacks/pastrybase - filling_color = "#CD853F" - list_reagents = list(/datum/reagent/consumable/nutriment = 1) - tastes = list("raw pastry" = 1) - foodtype = GRAIN | DAIRY - -/obj/item/reagent_containers/food/snacks/pastrybase - name = "pastry base" - desc = "A base for any self-respecting pastry." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "pastrybase" - list_reagents = list(/datum/reagent/consumable/nutriment = 1) - filling_color = "#CD853F" - tastes = list("pastry" = 1) - foodtype = GRAIN | DAIRY diff --git a/code/modules/food_and_drinks/food/snacks_meat.dm b/code/modules/food_and_drinks/food/snacks_meat.dm index 98accce5e82e0..45ce6763d777c 100644 --- a/code/modules/food_and_drinks/food/snacks_meat.dm +++ b/code/modules/food_and_drinks/food/snacks_meat.dm @@ -203,17 +203,6 @@ tastes = list("the jungle" = 1, "bananas" = 1, "jimmies" = 1) spawned_mob = /mob/living/simple_animal/hostile/gorilla -/obj/item/reagent_containers/food/snacks/enchiladas - name = "enchiladas" - desc = "Viva La Mexico!" - icon_state = "enchiladas" - bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 2) - bitesize = 4 - filling_color = "#FFA07A" - list_reagents = list(/datum/reagent/consumable/nutriment = 8, /datum/reagent/consumable/capsaicin = 6) - tastes = list("hot peppers" = 1, "meat" = 3, "cheese" = 1, "sour cream" = 1) - foodtype = MEAT - /obj/item/reagent_containers/food/snacks/stewedsoymeat name = "stewed soy meat" desc = "Even non-vegetarians will LOVE this!" diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm index dbf44ce3a4a1c..ab3ffc31564bf 100644 --- a/code/modules/food_and_drinks/food/snacks_other.dm +++ b/code/modules/food_and_drinks/food/snacks_other.dm @@ -291,56 +291,6 @@ tastes = list("eggplant" = 3, "cheese" = 1) foodtype = VEGETABLES | DAIRY -/obj/item/reagent_containers/food/snacks/tortilla - name = "tortilla" - desc = "The base for all your burritos." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "tortilla" - list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 1) - filling_color = "#FFEFD5" - tastes = list("tortilla" = 1) - foodtype = GRAIN - -/obj/item/reagent_containers/food/snacks/burrito - name = "burrito" - desc = "Tortilla wrapped goodness." - icon_state = "burrito" - bonus_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/vitamin = 2) - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 1) - filling_color = "#FFEFD5" - tastes = list("tortilla" = 2) - foodtype = GRAIN - -/obj/item/reagent_containers/food/snacks/cheesyburrito - name = "cheesy burrito" - desc = "It's a burrito filled with cheese." - icon_state = "cheesyburrito" - bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 2) - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 2) - filling_color = "#FFD800" - tastes = list("tortilla" = 2, "cheese" = 1) - foodtype = GRAIN | DAIRY - -/obj/item/reagent_containers/food/snacks/carneburrito - name = "carne asada burrito" - desc = "The best burrito for meat lovers." - icon_state = "carneburrito" - bonus_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/vitamin = 1) - list_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 1) - filling_color = "#A0522D" - tastes = list("tortilla" = 2, "meat" = 4) - foodtype = GRAIN | MEAT - -/obj/item/reagent_containers/food/snacks/fuegoburrito - name = "fuego plasma burrito" - desc = "A super spicy burrito." - icon_state = "fuegoburrito" - bonus_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/vitamin = 3) - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/capsaicin = 5, /datum/reagent/consumable/nutriment/vitamin = 3) - filling_color = "#FF2000" - tastes = list("tortilla" = 2, "hot peppers" = 1) - foodtype = GRAIN - /obj/item/reagent_containers/food/snacks/yakiimo name = "yaki imo" desc = "Made with roasted sweet potatoes!" @@ -372,36 +322,6 @@ tastes = list("melon" = 1) foodtype = FRUIT -/obj/item/reagent_containers/food/snacks/nachos - name = "nachos" - desc = "Chips from Space Mexico." - icon_state = "nachos" - bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 1) - list_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/vitamin = 2) - filling_color = "#F4A460" - tastes = list("nachos" = 1) - foodtype = VEGETABLES | FRIED - -/obj/item/reagent_containers/food/snacks/cheesynachos - name = "cheesy nachos" - desc = "The delicious combination of nachos and melting cheese." - icon_state = "cheesynachos" - bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 2) - list_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/vitamin = 3) - filling_color = "#FFD700" - tastes = list("nachos" = 2, "cheese" = 1) - foodtype = VEGETABLES | FRIED | DAIRY - -/obj/item/reagent_containers/food/snacks/cubannachos - name = "Cuban nachos" - desc = "That's some dangerously spicy nachos." - icon_state = "cubannachos" - bonus_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/vitamin = 3) - list_reagents = list(/datum/reagent/consumable/nutriment = 7, /datum/reagent/consumable/capsaicin = 8, /datum/reagent/consumable/nutriment/vitamin = 4) - filling_color = "#DC143C" - tastes = list("nachos" = 2, "hot pepper" = 1) - foodtype = VEGETABLES | FRIED | DAIRY - /obj/item/reagent_containers/food/snacks/melonkeg name = "melon keg" desc = "Who knew vodka was a fruit?" @@ -426,15 +346,6 @@ /*food_flags = FOOD_FINGER_FOOD*/ w_class = WEIGHT_CLASS_SMALL -/obj/item/reagent_containers/food/snacks/stuffedlegion - name = "stuffed legion" - desc = "The former skull of a damned human, filled with goliath meat. It has a decorative lava pool made of ketchup and hotsauce." - icon_state = "stuffed_legion" - bonus_reagents = list(/datum/reagent/consumable/nutriment/vitamin = 3, /datum/reagent/consumable/capsaicin = 1, /datum/reagent/medicine/tricordrazine = 5) - list_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/consumable/capsaicin = 2, /datum/reagent/medicine/tricordrazine = 10) - tastes = list("death" = 2, "rock" = 1, "meat" = 1, "hot peppers" = 1) - foodtype = MEAT - /obj/item/reagent_containers/food/snacks/powercrepe name = "Powercrepe" desc = "With great power, comes great crepes. It looks like a pancake filled with jelly but packs quite a punch." @@ -580,24 +491,6 @@ if(spamchecking) qdel(src) -/obj/item/reagent_containers/food/snacks/taco - name = "taco" - desc = "A traditional taco with meat, cheese, and lettuce." - icon_state = "taco" - bonus_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 2) - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 2) - filling_color = "F0D830" - tastes = list("taco" = 4, "meat" = 2, "cheese" = 2, "lettuce" = 1) - foodtype = MEAT | DAIRY | GRAIN | VEGETABLES - -/obj/item/reagent_containers/food/snacks/taco/plain - desc = "A traditional taco with meat and cheese, minus the rabbit food." - icon_state = "taco_plain" - bonus_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/vitamin = 2) - list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 1) - tastes = list("taco" = 4, "meat" = 2, "cheese" = 2) - foodtype = MEAT | DAIRY | GRAIN - /obj/item/reagent_containers/food/snacks/branrequests name = "Bran Requests Cereal" desc = "A dry cereal that satiates your requests for bran. Tastes uniquely like raisins and salt." diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm index 949d0e52d551a..cc08fd1832968 100644 --- a/code/modules/food_and_drinks/food/snacks_pastry.dm +++ b/code/modules/food_and_drinks/food/snacks_pastry.dm @@ -148,6 +148,12 @@ is_decorated = TRUE filling_color = "#879630" +/obj/item/reagent_containers/food/snacks/donut/premade + name = "prepackaged donut" + desc = "A mass produced donut, goes great with a cup of coffee." + icon_state = "donut" + list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/sprinkles = 1, /datum/reagent/consumable/sugar = 2, /datum/reagent/consumable/maltodextrin = 6) + //////////////////////JELLY DONUTS///////////////////////// /obj/item/reagent_containers/food/snacks/donut/jelly @@ -456,7 +462,7 @@ name = "\improper Donk-pocket" desc = "The food of choice for the seasoned traitor." icon_state = "donkpocket" - list_reagents = list(/datum/reagent/consumable/nutriment = 4) + list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/maltodextrin = 6) cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/warm filling_color = "#CD853F" tastes = list("meat" = 2, "dough" = 2, "laziness" = 1) @@ -468,7 +474,7 @@ name = "warm Donk-pocket" desc = "The heated food of choice for the seasoned traitor." bonus_reagents = list(/datum/reagent/medicine/omnizine = 3) //The original donk pocket has the most omnizine, can't beat the original on everything... - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/omnizine = 3) + list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/omnizine = 3, /datum/reagent/consumable/maltodextrin = 4) cooked_type = null tastes = list("meat" = 2, "dough" = 2, "laziness" = 1) foodtype = GRAIN @@ -477,7 +483,7 @@ name = "\improper Dank-pocket" desc = "The food of choice for the seasoned botanist." icon_state = "dankpocket" - list_reagents = list(/datum/reagent/toxin/lipolicide = 3, /datum/reagent/drug/space_drugs = 3, /datum/reagent/consumable/nutriment = 4) + list_reagents = list(/datum/reagent/toxin/lipolicide = 3, /datum/reagent/drug/space_drugs = 3, /datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/maltodextrin = 2) cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/dank/warm filling_color = "#00FF00" tastes = list("meat" = 2, "dough" = 2, "cannabis" = 2) @@ -488,7 +494,7 @@ desc = "The food of choice for the baked botanist." icon_state = "dankpocket" bonus_reagents = list(/datum/reagent/medicine/omnizine = 1, /datum/reagent/drug/space_drugs = 2) - list_reagents = list(/datum/reagent/toxin/lipolicide = 3, /datum/reagent/drug/space_drugs = 3, /datum/reagent/consumable/nutriment = 4) + list_reagents = list(/datum/reagent/toxin/lipolicide = 3, /datum/reagent/drug/space_drugs = 3, /datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/maltodextrin = 2) cooked_type = null tastes = list("meat" = 2, "dough" = 2, "cannabis" = 2) foodtype = GRAIN | VEGETABLES @@ -497,7 +503,7 @@ name = "\improper Spicy-pocket" desc = "The classic snack food, now with a heat-activated spicy flair." icon_state = "donkpocketspicy" - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/capsaicin = 2) + list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/capsaicin = 2, /datum/reagent/consumable/maltodextrin = 4) cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/spicy/warm filling_color = "#CD853F" tastes = list("meat" = 2, "dough" = 2, "spice" = 1) @@ -507,7 +513,7 @@ name = "warm Spicy-pocket" desc = "The classic snack food, now maybe a bit too spicy." bonus_reagents = list(/datum/reagent/medicine/omnizine = 1, /datum/reagent/consumable/capsaicin = 3) - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/omnizine = 1, /datum/reagent/consumable/capsaicin = 2) + list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/omnizine = 1, /datum/reagent/consumable/capsaicin = 2, /datum/reagent/consumable/maltodextrin = 4) tastes = list("meat" = 2, "dough" = 2, "weird spices" = 2) foodtype = GRAIN @@ -515,7 +521,7 @@ name = "\improper Teriyaki-pocket" desc = "An east-asian take on the classic stationside snack." icon_state = "donkpocketteriyaki" - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/soysauce = 2) + list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/soysauce = 2, /datum/reagent/consumable/maltodextrin = 4) cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/teriyaki/warm filling_color = "#CD853F" tastes = list("meat" = 2, "dough" = 2, "soy sauce" = 2) @@ -525,7 +531,7 @@ name = "warm Teriyaki-pocket" desc = "An east-asian take on the classic stationside snack, now steamy and warm." bonus_reagents = list(/datum/reagent/medicine/omnizine = 1) - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/omnizine = 1, /datum/reagent/consumable/soysauce = 2) + list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/omnizine = 1, /datum/reagent/consumable/soysauce = 2, /datum/reagent/consumable/maltodextrin = 4) tastes = list("meat" = 2, "dough" = 2, "soy sauce" = 2) foodtype = GRAIN @@ -533,7 +539,7 @@ name = "\improper Pizza-pocket" desc = "Delicious, cheesy and surprisingly filling." icon_state = "donkpocketpizza" - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/tomatojuice = 2) + list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/tomatojuice = 2, /datum/reagent/consumable/maltodextrin = 4) cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/pizza/warm filling_color = "#CD853F" tastes = list("meat" = 2, "dough" = 2, "cheese"= 2) @@ -543,7 +549,7 @@ name = "warm Pizza-pocket" desc = "Delicious, cheesy, and even better when hot." bonus_reagents = list(/datum/reagent/medicine/omnizine = 1) - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/omnizine = 1, /datum/reagent/consumable/tomatojuice = 2) + list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/omnizine = 1, /datum/reagent/consumable/tomatojuice = 2, /datum/reagent/consumable/maltodextrin = 4) tastes = list("meat" = 2, "dough" = 2, "melty cheese"= 2) foodtype = GRAIN @@ -551,7 +557,7 @@ name = "\improper Honk-pocket" desc = "The award-winning donk-pocket that won the hearts of clowns and humans alike." icon_state = "donkpocketbanana" - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/banana = 4) + list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/banana = 4, /datum/reagent/consumable/maltodextrin = 4) cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/honk/warm filling_color = "#XXXXXX" tastes = list("banana" = 2, "dough" = 2, "children's antibiotics" = 1) @@ -561,7 +567,7 @@ name = "warm Honk-pocket" desc = "The award-winning donk-pocket, now warm and toasty." bonus_reagents = list(/datum/reagent/medicine/omnizine = 1, /datum/reagent/consumable/laughter = 3) - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/omnizine = 1, /datum/reagent/consumable/banana = 4, /datum/reagent/consumable/laughter = 3) + list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/omnizine = 1, /datum/reagent/consumable/banana = 4, /datum/reagent/consumable/laughter = 3, /datum/reagent/consumable/maltodextrin = 4) tastes = list("dough" = 2, "children's antibiotics" = 1) foodtype = GRAIN @@ -569,7 +575,7 @@ name = "\improper Berry-pocket" desc = "A relentlessly sweet donk-pocket first created for use in Operation Dessert Storm." icon_state = "donkpocketberry" - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/berryjuice = 3) + list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/berryjuice = 3, /datum/reagent/consumable/maltodextrin = 4) cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/berry/warm filling_color = "#CD853F" tastes = list("dough" = 2, "jam" = 2) @@ -579,7 +585,7 @@ name = "warm Berry-pocket" desc = "A relentlessly sweet donk-pocket, now warm and delicious." bonus_reagents = list(/datum/reagent/medicine/omnizine = 1) - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/omnizine = 1, /datum/reagent/consumable/berryjuice = 3) + list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/omnizine = 1, /datum/reagent/consumable/berryjuice = 3, /datum/reagent/consumable/maltodextrin = 4) tastes = list("dough" = 2, "warm jam" = 2) foodtype = GRAIN @@ -587,7 +593,7 @@ name = "\improper Gondola-pocket" desc = "The choice to use real gondola meat in the recipe is controversial, to say the least." //Only a monster would craft this. icon_state = "donkpocketgondola" - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/tranquility = 5) + list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/tranquility = 5, /datum/reagent/consumable/maltodextrin = 4) cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/gondola/warm filling_color = "#CD853F" tastes = list("meat" = 2, "dough" = 2, "inner peace" = 1) @@ -597,7 +603,7 @@ name = "warm Gondola-pocket" desc = "The choice to use real gondola meat in the recipe is controversial, to say the least." bonus_reagents = list(/datum/reagent/medicine/omnizine = 1, /datum/reagent/tranquility = 5) - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/omnizine = 1, /datum/reagent/tranquility = 5) + list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/omnizine = 1, /datum/reagent/tranquility = 5, /datum/reagent/consumable/maltodextrin = 4) tastes = list("meat" = 2, "dough" = 2, "inner peace" = 1) foodtype = GRAIN diff --git a/code/modules/food_and_drinks/food/snacks_vend.dm b/code/modules/food_and_drinks/food/snacks_vend.dm index 0c3982cf4a7cf..1ba827ba63078 100644 --- a/code/modules/food_and_drinks/food/snacks_vend.dm +++ b/code/modules/food_and_drinks/food/snacks_vend.dm @@ -7,7 +7,7 @@ desc = "Nougat love it or hate it." icon_state = "candy" trash = /obj/item/trash/candy - list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/sugar = 3) + list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/sugar = 3, /datum/reagent/consumable/maltodextrin = 3) junkiness = 25 filling_color = "#D2691E" tastes = list("candy" = 1) @@ -20,7 +20,7 @@ icon_state = "sosjerky" desc = "Beef jerky made from the finest space cows." trash = /obj/item/trash/sosjerky - list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/sugar = 3, /datum/reagent/consumable/sodiumchloride = 2) + list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/sugar = 3, /datum/reagent/consumable/sodiumchloride = 2, /datum/reagent/consumable/maltodextrin = 3) junkiness = 25 filling_color = "#8B0000" tastes = list("dried meat" = 1) @@ -38,7 +38,7 @@ icon_state = "chips" trash = /obj/item/trash/chips bitesize = 1 - list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/sugar = 3, /datum/reagent/consumable/sodiumchloride = 1) + list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/sugar = 3, /datum/reagent/consumable/sodiumchloride = 1, /datum/reagent/consumable/maltodextrin = 3) junkiness = 20 filling_color = "#FFD700" tastes = list("salt" = 1, "crisps" = 1) @@ -49,7 +49,7 @@ icon_state = "4no_raisins" desc = "Best raisins in the universe. Not sure why." trash = /obj/item/trash/raisins - list_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/sugar = 4) + list_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/sugar = 4, /datum/reagent/consumable/maltodextrin = 4) junkiness = 25 filling_color = "#8B0000" tastes = list("dried raisins" = 1) @@ -69,7 +69,7 @@ name = "space twinkie" icon_state = "space_twinkie" desc = "Guaranteed to survive longer than you will." - list_reagents = list(/datum/reagent/consumable/sugar = 4) + list_reagents = list(/datum/reagent/consumable/sugar = 4, /datum/reagent/consumable/maltodextrin = 2) junkiness = 25 filling_color = "#FFD700" foodtype = JUNKFOOD | GRAIN | SUGAR @@ -82,7 +82,7 @@ desc = "Bite sized cheesie snacks that will honk all over your mouth." icon_state = "cheesie_honkers" trash = /obj/item/trash/cheesie - list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/sugar = 3) + list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/sugar = 3, /datum/reagent/consumable/maltodextrin = 3) junkiness = 25 filling_color = "#FFD700" tastes = list("cheese" = 5, "crisps" = 2) @@ -94,7 +94,7 @@ icon_state = "syndi_cakes" desc = "An extremely moist snack cake that tastes just as good after being nuked." trash = /obj/item/trash/syndi_cakes - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/doctor_delight = 5) + list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/doctor_delight = 5, /datum/reagent/consumable/maltodextrin = 4) filling_color = "#F5F5DC" tastes = list("sweetness" = 3, "cake" = 1) foodtype = GRAIN | FRUIT | VEGETABLES diff --git a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm index 4bad80b5a4537..b6950478f4699 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm @@ -123,7 +123,7 @@ break if(href_list["portion"]) - portion = CLAMP(input("How much drink do you want to dispense per glass?") as num, 0, 50) + portion = clamp(input("How much drink do you want to dispense per glass?") as num, 0, 50) if(href_list["pour"] || href_list["m_pour"]) if(glasses-- <= 0) diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index e835d08b41dbe..34c979f870f86 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -197,7 +197,8 @@ skin = new typeofskin log_combat(user, occupant, "gibbed") - mob_occupant.death(1) + mob_occupant.investigate_log("has been gibbed by [src].", INVESTIGATE_DEATHS) + mob_occupant.death(TRUE) mob_occupant.ghostize() set_occupant(null) qdel(mob_occupant) diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm index 6585527e27e61..8339ff01f1e46 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm @@ -213,9 +213,9 @@ var/atom/movable/O = I if (!QDELETED(O)) - var/md5name = rustg_hash_string(RUSTG_HASH_MD5, O.name) // This needs to happen because of a bug in a TGUI component, https://github.com/ractivejs/ractive/issues/744 - if (listofitems[md5name]) // which is fixed in a version we cannot use due to ie8 incompatibility - listofitems[md5name]["amount"]++ // The good news is, #30519 made smartfridge UIs non-auto-updating + var/md5name = rustg_hash_string(RUSTG_HASH_MD5, O.name) + if (listofitems[md5name]) + listofitems[md5name]["amount"]++ else listofitems[md5name] = list("name" = O.name, "type" = O.type, "amount" = 1) sort_list(listofitems) diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm index b12e76999a13c..32bf8497f2d1d 100644 --- a/code/modules/food_and_drinks/pizzabox.dm +++ b/code/modules/food_and_drinks/pizzabox.dm @@ -175,6 +175,17 @@ return else to_chat(user, "Close [open ? src : newbox] first!") + else if(istype(I, /obj/item/food/pizza)) + if(open) + if(pizza) + to_chat(user, "[src] already has \a [pizza.name]!") + return + if(!user.transferItemToLoc(I, src)) + return + pizza = I + to_chat(user, "You put [I] in [src].") + update_icon() + return else if(istype(I, /obj/item/bombcore/miniature/pizza)) if(open && !bomb) if(!user.transferItemToLoc(I, src)) diff --git a/code/modules/food_and_drinks/recipes/food_mixtures.dm b/code/modules/food_and_drinks/recipes/food_mixtures.dm index 7694ec2ee5c12..44254ea74eae6 100644 --- a/code/modules/food_and_drinks/recipes/food_mixtures.dm +++ b/code/modules/food_and_drinks/recipes/food_mixtures.dm @@ -148,7 +148,7 @@ /datum/chemical_reaction/dough/on_reaction(datum/reagents/holder, created_volume) var/location = get_turf(holder.my_atom) for(var/i in 1 to created_volume) - new /obj/item/reagent_containers/food/snacks/dough(location) + new /obj/item/food/dough(location) /datum/chemical_reaction/cakebatter name = "Cake Batter" @@ -159,7 +159,7 @@ /datum/chemical_reaction/cakebatter/on_reaction(datum/reagents/holder, created_volume) var/location = get_turf(holder.my_atom) for(var/i in 1 to created_volume) - new /obj/item/reagent_containers/food/snacks/cakebatter(location) + new /obj/item/food/cakebatter(location) /datum/chemical_reaction/cakebatter/vegan id = "vegancakebatter" diff --git a/code/modules/food_and_drinks/recipes/processor_recipes.dm b/code/modules/food_and_drinks/recipes/processor_recipes.dm index a11bb1866e3fe..f07884fce2c69 100644 --- a/code/modules/food_and_drinks/recipes/processor_recipes.dm +++ b/code/modules/food_and_drinks/recipes/processor_recipes.dm @@ -33,15 +33,15 @@ output = /obj/item/reagent_containers/food/snacks/soydope /datum/food_processor_process/spaghetti - input = /obj/item/reagent_containers/food/snacks/doughslice + input = /obj/item/food/doughslice output = /obj/item/food/spaghetti/raw /datum/food_processor_process/corn input = /obj/item/reagent_containers/food/snacks/grown/corn - output = /obj/item/reagent_containers/food/snacks/tortilla + output = /obj/item/food/tortilla /datum/food_processor_process/tortilla - input = /obj/item/reagent_containers/food/snacks/tortilla + input = /obj/item/food/tortilla output = /obj/item/reagent_containers/food/snacks/cornchips /datum/food_processor_process/parsnip diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_bread.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_bread.dm index 9ce9c46b90998..ab46d52db3661 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_bread.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_bread.dm @@ -88,7 +88,7 @@ /datum/crafting_recipe/food/butterbiscuit name = "Butter Biscuit" reqs = list( - /obj/item/reagent_containers/food/snacks/bun = 1, + /obj/item/food/bun = 1, /obj/item/reagent_containers/food/snacks/butter = 1 ) result = /obj/item/food/butterbiscuit @@ -97,7 +97,7 @@ /datum/crafting_recipe/food/butterdog name = "Butterdog" reqs = list( - /obj/item/reagent_containers/food/snacks/bun = 1, + /obj/item/food/bun = 1, /obj/item/reagent_containers/food/snacks/butter = 3, ) result = /obj/item/food/butterdog @@ -120,7 +120,7 @@ name = "Hot dog" reqs = list( /datum/reagent/consumable/ketchup = 5, - /obj/item/reagent_containers/food/snacks/bun = 1, + /obj/item/food/bun = 1, /obj/item/reagent_containers/food/snacks/sausage = 1 ) result = /obj/item/reagent_containers/food/snacks/hotdog diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_burger.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_burger.dm index be2360fe5ecc1..d494e0e607dbe 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_burger.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_burger.dm @@ -7,7 +7,7 @@ /datum/crafting_recipe/food/humanburger name = "Human burger" reqs = list( - /obj/item/reagent_containers/food/snacks/bun = 1, + /obj/item/food/bun = 1, /obj/item/reagent_containers/food/snacks/meat/steak/plain/human = 1 ) parts = list( @@ -20,7 +20,7 @@ name = "Burger" reqs = list( /obj/item/reagent_containers/food/snacks/meat/steak/plain = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/plain @@ -30,7 +30,7 @@ name = "Corgi burger" reqs = list( /obj/item/reagent_containers/food/snacks/meat/slab/corgi = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/corgi @@ -40,7 +40,7 @@ name = "Appendix burger" reqs = list( /obj/item/organ/appendix = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/appendix subcategory = CAT_BURGER @@ -49,7 +49,7 @@ name = "Brain burger" reqs = list( /obj/item/organ/brain = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/brain subcategory = CAT_BURGER @@ -58,7 +58,7 @@ name = "Xeno burger" reqs = list( /obj/item/reagent_containers/food/snacks/meat/steak/xeno = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/xeno subcategory = CAT_BURGER @@ -67,7 +67,7 @@ name = "Bearger" reqs = list( /obj/item/reagent_containers/food/snacks/meat/steak/bear = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/bearger subcategory = CAT_BURGER @@ -77,7 +77,7 @@ reqs = list( /obj/item/reagent_containers/food/snacks/carpmeat = 1, /obj/item/reagent_containers/food/snacks/cheesewedge = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/fish subcategory = CAT_BURGER @@ -86,7 +86,7 @@ name = "Tofu burger" reqs = list( /obj/item/reagent_containers/food/snacks/tofu = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/tofu subcategory = CAT_BURGER @@ -96,7 +96,7 @@ reqs = list( /obj/item/ectoplasm = 1, /datum/reagent/consumable/sodiumchloride = 2, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/ghost subcategory = CAT_BURGER @@ -105,7 +105,7 @@ name = "Clown burger" reqs = list( /obj/item/clothing/mask/gas/clown_hat = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/clown subcategory = CAT_BURGER @@ -114,7 +114,7 @@ name = "Mime burger" reqs = list( /obj/item/clothing/mask/gas/mime = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/mime subcategory = CAT_BURGER @@ -124,7 +124,7 @@ reqs = list( /obj/item/reagent_containers/food/snacks/meat/steak/plain = 1, /obj/item/toy/crayon/red = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/red subcategory = CAT_BURGER @@ -134,7 +134,7 @@ reqs = list( /obj/item/reagent_containers/food/snacks/meat/steak/plain = 1, /obj/item/toy/crayon/orange = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/orange subcategory = CAT_BURGER @@ -144,7 +144,7 @@ reqs = list( /obj/item/reagent_containers/food/snacks/meat/steak/plain = 1, /obj/item/toy/crayon/yellow = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/yellow subcategory = CAT_BURGER @@ -154,7 +154,7 @@ reqs = list( /obj/item/reagent_containers/food/snacks/meat/steak/plain = 1, /obj/item/toy/crayon/green = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/green subcategory = CAT_BURGER @@ -164,7 +164,7 @@ reqs = list( /obj/item/reagent_containers/food/snacks/meat/steak/plain = 1, /obj/item/toy/crayon/blue = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/blue subcategory = CAT_BURGER @@ -174,7 +174,7 @@ reqs = list( /obj/item/reagent_containers/food/snacks/meat/steak/plain = 1, /obj/item/toy/crayon/purple = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/purple subcategory = CAT_BURGER @@ -184,7 +184,7 @@ reqs = list( /obj/item/reagent_containers/food/snacks/meat/steak/plain = 1, /obj/item/toy/crayon/black = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/black subcategory = CAT_BURGER @@ -194,25 +194,16 @@ reqs = list( /obj/item/reagent_containers/food/snacks/meat/steak/plain = 1, /obj/item/toy/crayon/white = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/white subcategory = CAT_BURGER /datum/crafting_recipe/food/spellburger - name = "Spell burger" - reqs = list( - /obj/item/clothing/head/wizard/fake = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 - ) - result = /obj/item/food/burger/spell - subcategory = CAT_BURGER - -/datum/crafting_recipe/food/spellburger2 name = "Spell burger" reqs = list( /obj/item/clothing/head/wizard = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/spell subcategory = CAT_BURGER @@ -222,7 +213,7 @@ reqs = list( /obj/item/reagent_containers/food/snacks/meat/steak/plain = 3, /obj/item/reagent_containers/food/snacks/cheesewedge = 2, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/bigbite subcategory = CAT_BURGER @@ -237,7 +228,7 @@ /obj/item/reagent_containers/food/snacks/cheesewedge = 3, /obj/item/reagent_containers/food/snacks/boiledegg = 1, /obj/item/reagent_containers/food/snacks/meat/bacon = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/superbite @@ -247,7 +238,7 @@ name = "Jelly burger" reqs = list( /datum/reagent/toxin/slimejelly = 5, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/jelly/slime subcategory = CAT_BURGER @@ -256,7 +247,7 @@ name = "Jelly burger" reqs = list( /datum/reagent/consumable/cherryjelly = 5, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/jelly/cherry subcategory = CAT_BURGER @@ -266,7 +257,7 @@ reqs = list( /obj/item/reagent_containers/food/snacks/meat/steak/plain = 1, /obj/item/reagent_containers/food/snacks/grown/ghost_chili = 2, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/fivealarm subcategory = CAT_BURGER @@ -275,7 +266,7 @@ name = "Rat burger" reqs = list( /obj/item/reagent_containers/food/snacks/deadmouse = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/rat subcategory = CAT_BURGER @@ -284,7 +275,7 @@ name = "Home run baseball burger" reqs = list( /obj/item/melee/baseball_bat = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/baseball subcategory = CAT_BURGER @@ -293,7 +284,7 @@ name = "Bacon Burger" reqs = list( /obj/item/reagent_containers/food/snacks/meat/bacon = 3, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/baconburger @@ -303,7 +294,7 @@ name = "Empowered Burger" reqs = list( /obj/item/stack/sheet/mineral/plasma = 2, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/empoweredburger @@ -313,7 +304,7 @@ name = "Crab Burger" reqs = list( /obj/item/reagent_containers/food/snacks/meat/crab = 2, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/crab @@ -324,7 +315,7 @@ reqs = list( /obj/item/reagent_containers/food/snacks/meat/steak/plain = 1, /obj/item/reagent_containers/food/snacks/cheesewedge = 1, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/cheese subcategory = CAT_BURGER @@ -334,7 +325,7 @@ reqs = list( /obj/item/reagent_containers/food/snacks/soylentgreen = 1, //two full meats worth. /obj/item/reagent_containers/food/snacks/cheesewedge = 2, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/soylent subcategory = CAT_BURGER @@ -344,7 +335,7 @@ reqs = list( /obj/item/reagent_containers/food/snacks/bbqribs = 1, //The sauce is already included in the ribs /obj/item/reagent_containers/food/snacks/onion_slice = 1, //feel free to remove if too burdensome. - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/rib subcategory = CAT_BURGER @@ -354,7 +345,7 @@ reqs = list( /obj/item/reagent_containers/food/snacks/friedegg = 1, /obj/item/reagent_containers/food/snacks/meat/bacon = 2, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/mcguffin subcategory = CAT_BURGER @@ -364,7 +355,7 @@ reqs = list( /obj/item/reagent_containers/food/snacks/meat/steak/chicken = 1, /datum/reagent/consumable/mayonnaise = 5, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/chicken subcategory = CAT_BURGER @@ -377,7 +368,7 @@ /datum/reagent/consumable/cooking_oil = 20, /obj/item/reagent_containers/food/snacks/grown/nettle/death = 2, // closest thing to "grass of death" /obj/item/reagent_containers/food/snacks/cheesewedge = 4, - /obj/item/reagent_containers/food/snacks/bun = 1 + /obj/item/food/bun = 1 ) result = /obj/item/food/burger/crazy subcategory = CAT_BURGER diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm index 3844033a3fa29..9bd3052b6cf16 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm @@ -75,7 +75,7 @@ name = "Fish fingers" reqs = list( /datum/reagent/consumable/flour = 5, - /obj/item/reagent_containers/food/snacks/bun = 1, + /obj/item/food/bun = 1, /obj/item/reagent_containers/food/snacks/carpmeat = 1 ) result = /obj/item/reagent_containers/food/snacks/fishfingers @@ -125,16 +125,6 @@ result = /obj/item/reagent_containers/food/snacks/bearsteak subcategory = CAT_MEAT -/datum/crafting_recipe/food/enchiladas - name = "Enchiladas" - reqs = list( - /obj/item/reagent_containers/food/snacks/meat/cutlet = 2, - /obj/item/reagent_containers/food/snacks/grown/chili = 2, - /obj/item/reagent_containers/food/snacks/tortilla = 2 - ) - result = /obj/item/reagent_containers/food/snacks/enchiladas - subcategory = CAT_MEAT - /datum/crafting_recipe/food/stewedsoymeat name = "Stewed soymeat" reqs = list( @@ -165,7 +155,7 @@ /datum/crafting_recipe/food/rawkhinkali name = "Raw Khinkali" reqs = list( - /obj/item/reagent_containers/food/snacks/doughslice = 1, + /obj/item/food/doughslice = 1, /obj/item/reagent_containers/food/snacks/grown/garlic = 1, /obj/item/reagent_containers/food/snacks/meatball = 1 ) @@ -175,7 +165,7 @@ /datum/crafting_recipe/food/pigblanket name = "Pig in a Blanket" reqs = list( - /obj/item/reagent_containers/food/snacks/bun = 1, + /obj/item/food/bun = 1, /obj/item/reagent_containers/food/snacks/butter = 1, /obj/item/reagent_containers/food/snacks/meat/cutlet = 1 ) diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_mexican.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_mexican.dm new file mode 100644 index 0000000000000..f5ca4ea5a0115 --- /dev/null +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_mexican.dm @@ -0,0 +1,114 @@ +// see code/module/crafting/table.dm + +// MEXICAN + +/datum/crafting_recipe/food/burrito + name ="Burrito" + reqs = list( + /obj/item/food/tortilla = 1, + /obj/item/reagent_containers/food/snacks/grown/soybeans = 2 + ) + result = /obj/item/food/burrito + subcategory = CAT_MEXICAN + +/datum/crafting_recipe/food/cheesyburrito + name ="Cheesy burrito" + reqs = list( + /obj/item/reagent_containers/food/snacks/cheesewedge = 2, + /obj/item/food/tortilla = 1, + /obj/item/reagent_containers/food/snacks/grown/soybeans = 1 + ) + result = /obj/item/food/cheesyburrito + subcategory = CAT_MEXICAN + +/datum/crafting_recipe/food/carneburrito + name ="Carne de asada burrito" + reqs = list( + /obj/item/food/tortilla = 1, + /obj/item/reagent_containers/food/snacks/meat/cutlet = 2, + /obj/item/reagent_containers/food/snacks/grown/soybeans = 1 + ) + result = /obj/item/food/carneburrito + subcategory = CAT_MEXICAN + +/datum/crafting_recipe/food/fuegoburrito + name ="Fuego plasma burrito" + reqs = list( + /obj/item/food/tortilla = 1, + /obj/item/reagent_containers/food/snacks/grown/ghost_chili = 2, + /obj/item/reagent_containers/food/snacks/grown/soybeans = 1 + ) + result = /obj/item/food/fuegoburrito + subcategory = CAT_MEXICAN + +/datum/crafting_recipe/food/nachos + name ="Nachos" + reqs = list( + /datum/reagent/consumable/sodiumchloride = 1, + /obj/item/food/tortilla = 1 + ) + result = /obj/item/food/nachos + subcategory = CAT_MEXICAN + +/datum/crafting_recipe/food/cheesynachos + name ="Cheesy nachos" + reqs = list( + /datum/reagent/consumable/sodiumchloride = 1, + /obj/item/reagent_containers/food/snacks/cheesewedge = 1, + /obj/item/food/tortilla = 1 + ) + result = /obj/item/food/cheesynachos + subcategory = CAT_MEXICAN + +/datum/crafting_recipe/food/cubannachos + name ="Cuban nachos" + reqs = list( + /datum/reagent/consumable/ketchup = 5, + /obj/item/reagent_containers/food/snacks/grown/chili = 2, + /obj/item/food/tortilla = 1 + ) + result = /obj/item/food/cubannachos + subcategory = CAT_MEXICAN + +/datum/crafting_recipe/food/taco + name ="Classic Taco" + reqs = list( + /obj/item/food/tortilla = 1, + /obj/item/reagent_containers/food/snacks/cheesewedge = 1, + /obj/item/reagent_containers/food/snacks/meat/cutlet = 1, + /obj/item/reagent_containers/food/snacks/grown/cabbage = 1, + ) + result = /obj/item/food/taco + subcategory = CAT_MEXICAN + +/datum/crafting_recipe/food/tacoplain + name ="Plain Taco" + reqs = list( + /obj/item/food/tortilla = 1, + /obj/item/reagent_containers/food/snacks/cheesewedge = 1, + /obj/item/reagent_containers/food/snacks/meat/cutlet = 1, + ) + result = /obj/item/food/taco/plain + subcategory = CAT_MEXICAN + +/datum/crafting_recipe/food/enchiladas + name = "Enchiladas" + reqs = list( + /obj/item/reagent_containers/food/snacks/meat/cutlet = 2, + /obj/item/reagent_containers/food/snacks/grown/chili = 2, + /obj/item/food/tortilla = 2 + ) + result = /obj/item/food/enchiladas + subcategory = CAT_MEAT + +/datum/crafting_recipe/food/stuffedlegion + name = "Stuffed legion" + time = 40 + reqs = list( + /obj/item/reagent_containers/food/snacks/meat/steak/goliath = 1, + /obj/item/organ/regenerative_core/legion = 1, + /datum/reagent/consumable/ketchup = 2, + /datum/reagent/consumable/capsaicin = 2 + ) + result = /obj/item/food/stuffedlegion + subcategory = CAT_MEXICAN diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm index f10dc0f9a1d06..7c45a9b86b3a7 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm @@ -100,7 +100,7 @@ time = 40 reqs = list(/datum/reagent/consumable/sodiumchloride = 1, /datum/reagent/consumable/blackpepper = 1, - /obj/item/reagent_containers/food/snacks/pastrybase = 2 + /obj/item/food/pastrybase = 2 ) result = /obj/item/food/baguette subcategory = CAT_MISCFOOD @@ -143,45 +143,6 @@ result = /obj/item/reagent_containers/food/snacks/twobread subcategory = CAT_MISCFOOD -/datum/crafting_recipe/food/burrito - name ="Burrito" - reqs = list( - /obj/item/reagent_containers/food/snacks/tortilla = 1, - /obj/item/reagent_containers/food/snacks/grown/soybeans = 2 - ) - result = /obj/item/reagent_containers/food/snacks/burrito - subcategory = CAT_MISCFOOD - -/datum/crafting_recipe/food/cheesyburrito - name ="Cheesy burrito" - reqs = list( - /obj/item/reagent_containers/food/snacks/tortilla = 1, - /obj/item/reagent_containers/food/snacks/cheesewedge = 2, - /obj/item/reagent_containers/food/snacks/grown/soybeans = 1 - ) - result = /obj/item/reagent_containers/food/snacks/cheesyburrito - subcategory = CAT_MISCFOOD - -/datum/crafting_recipe/food/carneburrito - name ="Carne de asada burrito" - reqs = list( - /obj/item/reagent_containers/food/snacks/tortilla = 1, - /obj/item/reagent_containers/food/snacks/meat/cutlet = 2, - /obj/item/reagent_containers/food/snacks/grown/soybeans = 1 - ) - result = /obj/item/reagent_containers/food/snacks/carneburrito - subcategory = CAT_MISCFOOD - -/datum/crafting_recipe/food/fuegoburrito - name ="Fuego plasma burrito" - reqs = list( - /obj/item/reagent_containers/food/snacks/tortilla = 1, - /obj/item/reagent_containers/food/snacks/grown/ghost_chili = 2, - /obj/item/reagent_containers/food/snacks/grown/soybeans = 1 - ) - result = /obj/item/reagent_containers/food/snacks/fuegoburrito - subcategory = CAT_MISCFOOD - /datum/crafting_recipe/food/melonfruitbowl name ="Melon fruit bowl" reqs = list( @@ -195,35 +156,6 @@ result = /obj/item/reagent_containers/food/snacks/melonfruitbowl subcategory = CAT_MISCFOOD -/datum/crafting_recipe/food/nachos - name ="Nachos" - reqs = list( - /datum/reagent/consumable/sodiumchloride = 1, - /obj/item/reagent_containers/food/snacks/tortilla = 1 - ) - result = /obj/item/reagent_containers/food/snacks/nachos - subcategory = CAT_MISCFOOD - -/datum/crafting_recipe/food/cheesynachos - name ="Cheesy nachos" - reqs = list( - /datum/reagent/consumable/sodiumchloride = 1, - /obj/item/reagent_containers/food/snacks/cheesewedge = 1, - /obj/item/reagent_containers/food/snacks/tortilla = 1 - ) - result = /obj/item/reagent_containers/food/snacks/cheesynachos - subcategory = CAT_MISCFOOD - -/datum/crafting_recipe/food/cubannachos - name ="Cuban nachos" - reqs = list( - /datum/reagent/consumable/ketchup = 5, - /obj/item/reagent_containers/food/snacks/grown/chili = 2, - /obj/item/reagent_containers/food/snacks/tortilla = 1 - ) - result = /obj/item/reagent_containers/food/snacks/cubannachos - subcategory = CAT_MISCFOOD - /datum/crafting_recipe/food/melonkeg name ="Melon keg" reqs = list( @@ -244,24 +176,11 @@ result = /obj/item/reagent_containers/food/snacks/honeybar subcategory = CAT_MISCFOOD - -/datum/crafting_recipe/food/stuffedlegion - name = "Stuffed legion" - time = 40 - reqs = list( - /obj/item/reagent_containers/food/snacks/meat/steak/goliath = 1, - /obj/item/organ/regenerative_core/legion = 1, - /datum/reagent/consumable/ketchup = 2, - /datum/reagent/consumable/capsaicin = 2 - ) - result = /obj/item/reagent_containers/food/snacks/stuffedlegion - subcategory = CAT_MISCFOOD - /datum/crafting_recipe/food/powercrepe name = "Powercrepe" time = 40 reqs = list( - /obj/item/reagent_containers/food/snacks/flatdough = 1, + /obj/item/food/flatdough = 1, /datum/reagent/consumable/milk = 1, /datum/reagent/consumable/cherryjelly = 5, /obj/item/stock_parts/cell/super =1, @@ -270,27 +189,6 @@ result = /obj/item/reagent_containers/food/snacks/powercrepe subcategory = CAT_MISCFOOD -/datum/crafting_recipe/food/taco - name ="Classic Taco" - reqs = list( - /obj/item/reagent_containers/food/snacks/tortilla = 1, - /obj/item/reagent_containers/food/snacks/cheesewedge = 1, - /obj/item/reagent_containers/food/snacks/meat/cutlet = 1, - /obj/item/reagent_containers/food/snacks/grown/cabbage = 1, - ) - result = /obj/item/reagent_containers/food/snacks/taco - subcategory = CAT_MISCFOOD - -/datum/crafting_recipe/food/tacoplain - name ="Plain Taco" - reqs = list( - /obj/item/reagent_containers/food/snacks/tortilla = 1, - /obj/item/reagent_containers/food/snacks/cheesewedge = 1, - /obj/item/reagent_containers/food/snacks/meat/cutlet = 1, - ) - result = /obj/item/reagent_containers/food/snacks/taco/plain - subcategory = CAT_MISCFOOD - /datum/crafting_recipe/food/branrequests name = "Bran Requests Cereal" reqs = list( @@ -326,7 +224,7 @@ /datum/crafting_recipe/food/crab_rangoon name = "Crab Rangoon" reqs = list( - /obj/item/reagent_containers/food/snacks/doughslice = 1, + /obj/item/food/doughslice = 1, /datum/reagent/consumable/cream = 5, /obj/item/reagent_containers/food/snacks/cheesewedge = 1, /obj/item/reagent_containers/food/snacks/meat/rawcrab = 1 diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm index e1f698a345f6c..a208118cde8ba 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm @@ -8,7 +8,7 @@ name = "Donut" reqs = list( /datum/reagent/consumable/sugar = 1, - /obj/item/reagent_containers/food/snacks/pastrybase = 1 + /obj/item/food/pastrybase = 1 ) result = /obj/item/reagent_containers/food/snacks/donut/plain subcategory = CAT_PASTRY @@ -19,7 +19,7 @@ reqs = list( /datum/reagent/consumable/frostoil = 5, /datum/reagent/consumable/capsaicin = 5, - /obj/item/reagent_containers/food/snacks/pastrybase = 1 + /obj/item/food/pastrybase = 1 ) result = /obj/item/reagent_containers/food/snacks/donut/chaos @@ -28,7 +28,7 @@ name = "Meat donut" reqs = list( /obj/item/reagent_containers/food/snacks/meat/rawcutlet = 1, - /obj/item/reagent_containers/food/snacks/pastrybase = 1 + /obj/item/food/pastrybase = 1 ) result = /obj/item/reagent_containers/food/snacks/donut/meat @@ -36,7 +36,7 @@ name = "Jelly donut" reqs = list( /datum/reagent/consumable/berryjuice = 5, - /obj/item/reagent_containers/food/snacks/pastrybase = 1 + /obj/item/food/pastrybase = 1 ) result = /obj/item/reagent_containers/food/snacks/donut/jelly/plain @@ -44,7 +44,7 @@ name = "Slime jelly donut" reqs = list( /datum/reagent/toxin/slimejelly = 5, - /obj/item/reagent_containers/food/snacks/pastrybase = 1 + /obj/item/food/pastrybase = 1 ) result = /obj/item/reagent_containers/food/snacks/donut/jelly/slimejelly/plain @@ -254,7 +254,7 @@ time = 15 name = "Waffles" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 2 + /obj/item/food/pastrybase = 2 ) result = /obj/item/reagent_containers/food/snacks/waffles subcategory = CAT_PASTRY @@ -263,7 +263,7 @@ /datum/crafting_recipe/food/soylenviridians name = "Soylent viridians" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 2, + /obj/item/food/pastrybase = 2, /obj/item/reagent_containers/food/snacks/grown/soybeans = 1 ) result = /obj/item/reagent_containers/food/snacks/soylenviridians @@ -272,7 +272,7 @@ /datum/crafting_recipe/food/soylentgreen name = "Soylent green" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 2, + /obj/item/food/pastrybase = 2, /obj/item/reagent_containers/food/snacks/meat/slab/human = 2 ) result = /obj/item/reagent_containers/food/snacks/soylentgreen @@ -283,7 +283,7 @@ name = "Roffle waffles" reqs = list( /datum/reagent/drug/mushroomhallucinogen = 5, - /obj/item/reagent_containers/food/snacks/pastrybase = 2 + /obj/item/food/pastrybase = 2 ) result = /obj/item/reagent_containers/food/snacks/rofflewaffles subcategory = CAT_PASTRY @@ -291,7 +291,7 @@ /datum/crafting_recipe/food/pancakes name = "Pancake" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1 + /obj/item/food/pastrybase = 1 ) result = /obj/item/reagent_containers/food/snacks/pancakes subcategory = CAT_PASTRY @@ -299,7 +299,7 @@ /datum/crafting_recipe/food/bbpancakes name = "Blueberry pancake" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/reagent_containers/food/snacks/grown/berries = 1 ) result = /obj/item/reagent_containers/food/snacks/pancakes/blueberry @@ -308,7 +308,7 @@ /datum/crafting_recipe/food/ccpancakes name = "Chocolate chip pancake" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/reagent_containers/food/snacks/chocolatebar = 1 ) result = /obj/item/reagent_containers/food/snacks/pancakes/chocolatechip @@ -321,7 +321,7 @@ time = 15 name = "Donk-pocket" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/reagent_containers/food/snacks/meatball = 1 ) result = /obj/item/reagent_containers/food/snacks/donkpocket @@ -331,7 +331,7 @@ time = 15 name = "Dank-pocket" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/reagent_containers/food/snacks/grown/cannabis = 1 ) result = /obj/item/reagent_containers/food/snacks/donkpocket/dank @@ -341,7 +341,7 @@ time = 15 name = "Spicy-pocket" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/reagent_containers/food/snacks/grown/chili = 1 ) result = /obj/item/reagent_containers/food/snacks/donkpocket/spicy @@ -351,7 +351,7 @@ time = 15 name = "Teriyaki-pocket" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /datum/reagent/consumable/soysauce = 3 ) result = /obj/item/reagent_containers/food/snacks/donkpocket/teriyaki @@ -361,7 +361,7 @@ time = 15 name = "Pizza-pocket" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/reagent_containers/food/snacks/grown/tomato = 1 ) result = /obj/item/reagent_containers/food/snacks/donkpocket/pizza @@ -371,7 +371,7 @@ time = 15 name = "Honk-Pocket" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/reagent_containers/food/snacks/grown/banana = 1, /datum/reagent/consumable/sugar = 3 ) @@ -382,7 +382,7 @@ time = 15 name = "Berry-pocket" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/reagent_containers/food/snacks/grown/berries = 1 ) result = /obj/item/reagent_containers/food/snacks/donkpocket/berry @@ -392,7 +392,7 @@ time = 15 name = "Gondola-pocket" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /datum/reagent/tranquility = 5 ) result = /obj/item/reagent_containers/food/snacks/donkpocket/gondola @@ -405,7 +405,7 @@ name = "Muffin" reqs = list( /datum/reagent/consumable/milk = 5, - /obj/item/reagent_containers/food/snacks/pastrybase = 1 + /obj/item/food/pastrybase = 1 ) result = /obj/item/reagent_containers/food/snacks/muffin subcategory = CAT_PASTRY @@ -414,7 +414,7 @@ name = "Berry muffin" reqs = list( /datum/reagent/consumable/milk = 5, - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/reagent_containers/food/snacks/grown/berries = 1 ) result = /obj/item/reagent_containers/food/snacks/muffin/berry @@ -424,7 +424,7 @@ name = "Booberry muffin" reqs = list( /datum/reagent/consumable/milk = 5, - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/reagent_containers/food/snacks/grown/berries = 1, /obj/item/ectoplasm = 1 ) @@ -435,7 +435,7 @@ name = "Moffin" reqs = list( /datum/reagent/consumable/milk = 5, - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/stack/sheet/cotton/cloth = 1, ) result = /obj/item/reagent_containers/food/snacks/muffin/moffin @@ -458,7 +458,7 @@ name = "Meat bun" reqs = list( /datum/reagent/consumable/soysauce = 5, - /obj/item/reagent_containers/food/snacks/bun = 1, + /obj/item/food/bun = 1, /obj/item/reagent_containers/food/snacks/meatball = 1, /obj/item/reagent_containers/food/snacks/grown/cabbage = 1 ) @@ -480,7 +480,7 @@ name = "Sugar cookie" reqs = list( /datum/reagent/consumable/sugar = 5, - /obj/item/reagent_containers/food/snacks/pastrybase = 1 + /obj/item/food/pastrybase = 1 ) result = /obj/item/reagent_containers/food/snacks/sugarcookie subcategory = CAT_PASTRY @@ -489,7 +489,7 @@ time = 15 name = "Fortune cookie" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/paper = 1 ) parts = list( @@ -503,7 +503,7 @@ name = "Poppy pretzel" reqs = list( /obj/item/seeds/flower/poppy = 1, - /obj/item/reagent_containers/food/snacks/pastrybase = 1 + /obj/item/food/pastrybase = 1 ) result = /obj/item/reagent_containers/food/snacks/poppypretzel subcategory = CAT_PASTRY @@ -512,7 +512,7 @@ time = 15 name = "Plumphelmet biscuit" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/reagent_containers/food/snacks/grown/mushroom/plumphelmet = 1 ) result = /obj/item/reagent_containers/food/snacks/plumphelmetbiscuit @@ -523,7 +523,7 @@ name = "Cracker" reqs = list( /datum/reagent/consumable/sodiumchloride = 1, - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, ) result = /obj/item/reagent_containers/food/snacks/cracker subcategory = CAT_PASTRY @@ -532,7 +532,7 @@ name = "Choco cornet" reqs = list( /datum/reagent/consumable/sodiumchloride = 1, - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/reagent_containers/food/snacks/chocolatebar = 1 ) result = /obj/item/reagent_containers/food/snacks/chococornet @@ -541,7 +541,7 @@ /datum/crafting_recipe/food/oatmealcookie name = "Oatmeal cookie" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/reagent_containers/food/snacks/grown/oat = 1 ) result = /obj/item/reagent_containers/food/snacks/oatmealcookie @@ -551,7 +551,7 @@ name = "Raisin cookie" reqs = list( /obj/item/reagent_containers/food/snacks/no_raisin = 1, - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/reagent_containers/food/snacks/grown/oat = 1 ) result = /obj/item/reagent_containers/food/snacks/raisincookie @@ -560,7 +560,7 @@ /datum/crafting_recipe/food/cherrycupcake name = "Cherry cupcake" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/reagent_containers/food/snacks/grown/cherries = 1 ) result = /obj/item/reagent_containers/food/snacks/cherrycupcake @@ -569,7 +569,7 @@ /datum/crafting_recipe/food/bluecherrycupcake name = "Blue cherry cupcake" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/reagent_containers/food/snacks/grown/bluecherries = 1 ) result = /obj/item/reagent_containers/food/snacks/cherrycupcake/blue @@ -578,7 +578,7 @@ /datum/crafting_recipe/food/honeybun name = "Honey bun" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /datum/reagent/consumable/honey = 5 ) result = /obj/item/reagent_containers/food/snacks/honeybun @@ -587,7 +587,7 @@ /datum/crafting_recipe/food/ravtart name = "Rav'tart" reqs = list( - /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/food/pastrybase = 1, /obj/item/stack/sheet/bronze = 1, /obj/item/reagent_containers/food/snacks/grown/berries = 2, /obj/item/reagent_containers/food/snacks/grown/citrus/orange = 1 diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pie.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pie.dm index af06b908d6012..296f522cb3d07 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pie.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pie.dm @@ -201,7 +201,7 @@ name = "Baklava pie" reqs = list( /obj/item/reagent_containers/food/snacks/butter = 2, - /obj/item/reagent_containers/food/snacks/tortilla = 4, //Layers + /obj/item/food/tortilla = 4, //Layers /obj/item/seeds/wheat/oat = 4 ) result = /obj/item/reagent_containers/food/snacks/pie/baklava diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pizza.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pizza.dm index 89206e1ad7da8..d4e4d08465e9f 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pizza.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pizza.dm @@ -6,7 +6,7 @@ /datum/crafting_recipe/food/margheritapizza name = "Margherita pizza" reqs = list( - /obj/item/reagent_containers/food/snacks/pizzabread = 1, + /obj/item/food/pizzabread = 1, /obj/item/reagent_containers/food/snacks/cheesewedge = 4, /obj/item/reagent_containers/food/snacks/grown/tomato = 1 ) @@ -16,7 +16,7 @@ /datum/crafting_recipe/food/meatpizza name = "Meat pizza" reqs = list( - /obj/item/reagent_containers/food/snacks/pizzabread = 1, + /obj/item/food/pizzabread = 1, /obj/item/reagent_containers/food/snacks/meat/cutlet = 4, /obj/item/reagent_containers/food/snacks/cheesewedge = 1, /obj/item/reagent_containers/food/snacks/grown/tomato = 1 @@ -27,7 +27,7 @@ /datum/crafting_recipe/food/arnold name = "Arnold pizza" reqs = list( - /obj/item/reagent_containers/food/snacks/pizzabread = 1, + /obj/item/food/pizzabread = 1, /obj/item/reagent_containers/food/snacks/meat/cutlet = 3, /obj/item/ammo_casing/c9mm = 8, /obj/item/reagent_containers/food/snacks/cheesewedge = 1, @@ -39,7 +39,7 @@ /datum/crafting_recipe/food/mushroompizza name = "Mushroom pizza" reqs = list( - /obj/item/reagent_containers/food/snacks/pizzabread = 1, + /obj/item/food/pizzabread = 1, /obj/item/reagent_containers/food/snacks/grown/mushroom = 5 ) result = /obj/item/food/pizza/mushroom @@ -48,7 +48,7 @@ /datum/crafting_recipe/food/vegetablepizza name = "Vegetable pizza" reqs = list( - /obj/item/reagent_containers/food/snacks/pizzabread = 1, + /obj/item/food/pizzabread = 1, /obj/item/reagent_containers/food/snacks/grown/eggplant = 1, /obj/item/reagent_containers/food/snacks/grown/carrot = 1, /obj/item/reagent_containers/food/snacks/grown/corn = 1, @@ -60,7 +60,7 @@ /datum/crafting_recipe/food/donkpocketpizza name = "Donkpocket pizza" reqs = list( - /obj/item/reagent_containers/food/snacks/pizzabread = 1, + /obj/item/food/pizzabread = 1, /obj/item/reagent_containers/food/snacks/donkpocket/warm = 3, /obj/item/reagent_containers/food/snacks/cheesewedge = 1, /obj/item/reagent_containers/food/snacks/grown/tomato = 1 @@ -71,7 +71,7 @@ /datum/crafting_recipe/food/dankpizza name = "Dank pizza" reqs = list( - /obj/item/reagent_containers/food/snacks/pizzabread = 1, + /obj/item/food/pizzabread = 1, /obj/item/reagent_containers/food/snacks/grown/ambrosia/vulgaris = 3, /obj/item/reagent_containers/food/snacks/cheesewedge = 1, /obj/item/reagent_containers/food/snacks/grown/tomato = 1 @@ -82,7 +82,7 @@ /datum/crafting_recipe/food/sassysagepizza name = "Sassysage pizza" reqs = list( - /obj/item/reagent_containers/food/snacks/pizzabread = 1, + /obj/item/food/pizzabread = 1, /obj/item/reagent_containers/food/snacks/meatball = 3, /obj/item/reagent_containers/food/snacks/cheesewedge = 1, /obj/item/reagent_containers/food/snacks/grown/tomato = 1 @@ -93,7 +93,7 @@ /datum/crafting_recipe/food/pineapplepizza name = "Hawaiian pizza" reqs = list( - /obj/item/reagent_containers/food/snacks/pizzabread = 1, + /obj/item/food/pizzabread = 1, /obj/item/reagent_containers/food/snacks/meat/cutlet = 2, /obj/item/reagent_containers/food/snacks/pineappleslice = 3, /obj/item/reagent_containers/food/snacks/cheesewedge = 1, diff --git a/code/modules/games/tarot.dm b/code/modules/games/tarot.dm new file mode 100644 index 0000000000000..8be9bf1676e22 --- /dev/null +++ b/code/modules/games/tarot.dm @@ -0,0 +1,29 @@ +//Some silly tarot cards for predicting when the Clown will die. Ported from TG. https://github.com/tgstation/tgstation/pull/51318/ +/obj/item/toy/cards/deck/tarot + name = "Tarot Card Deck" + desc = "A full 78 card deck of Tarot Cards, no refunds on false predicitons." + icon = 'icons/obj/toy.dmi' + icon_state = "deck_tarot_full" + deckstyle = "tarot" + +/obj/item/toy/cards/deck/tarot/populate_deck() + for(var/suit in list("Cups", "Wands", "Swords", "Coins")) + for(var/i in 1 to 10) + cards += "[i] of [suit]" + for(var/person in list("Page", "Champion", "Queen", "King")) + cards += "[person] of [suit]" + for(var/trump in list("The Magician", "The High Priestess", "The Empress", "The Emperor", "The Hierophant", "The Lover", "The Chariot", "Justice", "The Hermit", "The Wheel of Fortune", "Strength", "The Hanged Man", "Death", "Temperance", "The Devil", "The Tower", "The Star", "The Moon", "The Sun", "Judgement", "The World", "The Fool")) + cards += "[trump]" + +/obj/item/toy/cards/deck/tarot/draw_card(mob/user) + . = ..() + if(prob(50)) + var/obj/item/toy/cards/singlecard/C = . + if(!C) + return FALSE + + var/matrix/M = matrix() + M.Turn(180) + C.transform = M + + diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm index 7daf32062ecda..e9037774051b1 100644 --- a/code/modules/hydroponics/grown/banana.dm +++ b/code/modules/hydroponics/grown/banana.dm @@ -27,18 +27,18 @@ juice_results = list(/datum/reagent/consumable/banana = 0) distill_reagent = /datum/reagent/consumable/ethanol/bananahonk -/obj/item/reagent_containers/food/snacks/grown/banana/suicide_act(mob/user) +/obj/item/reagent_containers/food/snacks/grown/banana/suicide_act(mob/living/user) user.visible_message("[user] is aiming [src] at [user.p_them()]self! It looks like [user.p_theyre()] trying to commit suicide!") playsound(loc, 'sound/items/bikehorn.ogg', 50, 1, -1) sleep(25) if(!user) - return (OXYLOSS) + return OXYLOSS user.say("BANG!", forced = /datum/reagent/consumable/banana) sleep(25) if(!user) - return (OXYLOSS) + return OXYLOSS user.visible_message("[user] laughs so hard they begin to suffocate!") - return (OXYLOSS) + return OXYLOSS //Banana Peel /obj/item/grown/bananapeel @@ -54,10 +54,10 @@ throw_speed = 3 throw_range = 7 -/obj/item/grown/bananapeel/suicide_act(mob/user) +/obj/item/grown/bananapeel/suicide_act(mob/living/user) user.visible_message("[user] is deliberately slipping on [src]! It looks like [user.p_theyre()] trying to commit suicide!") playsound(loc, 'sound/misc/slip.ogg', 50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS // Mimana - invisible sprites are totally a feature! diff --git a/code/modules/hydroponics/grown/cotton.dm b/code/modules/hydroponics/grown/cotton.dm index 34ff4696efd1e..07cfee24cab52 100644 --- a/code/modules/hydroponics/grown/cotton.dm +++ b/code/modules/hydroponics/grown/cotton.dm @@ -48,7 +48,7 @@ //reinforced mutated variant /obj/item/seeds/cotton/durathread name = "pack of durathread seeds" - desc = "A pack of seeds that'll grow into an extremely durable thread that could easily rival plasteel if woven properly." + desc = "A pack of seeds that'll grow into an extremely durable thread that could easily rival plasteel if woven properly. In its woven state, it is incredibly effective at resisting high-energy ballistic attacks making it sought after by organisations that specialise in personal defense." icon_state = "seed-durathread" species = "durathread" plantname = "Durathread" diff --git a/code/modules/hydroponics/grown/kudzu.dm b/code/modules/hydroponics/grown/kudzu.dm index c3aa666ccc97f..799a3aca66511 100644 --- a/code/modules/hydroponics/grown/kudzu.dm +++ b/code/modules/hydroponics/grown/kudzu.dm @@ -21,10 +21,10 @@ S.mutations = mutations.Copy() return S -/obj/item/seeds/kudzu/suicide_act(mob/user) +/obj/item/seeds/kudzu/suicide_act(mob/living/user) user.visible_message("[user] swallows the pack of kudzu seeds! It looks like [user.p_theyre()] trying to commit suicide!") plant(user) - return (BRUTELOSS) + return BRUTELOSS /obj/item/seeds/kudzu/proc/plant(mob/user) if(isspaceturf(user.loc)) diff --git a/code/modules/hydroponics/grown/melon.dm b/code/modules/hydroponics/grown/melon.dm index ff19627c3d6c2..7c2851e06426f 100644 --- a/code/modules/hydroponics/grown/melon.dm +++ b/code/modules/hydroponics/grown/melon.dm @@ -14,7 +14,7 @@ mutatelist = list(/obj/item/seeds/watermelon/holy, /obj/item/seeds/watermelon/ballolon) reagents_add = list(/datum/reagent/water = 0.2, /datum/reagent/consumable/nutriment/vitamin = 0.04, /datum/reagent/consumable/nutriment = 0.2) -/obj/item/seeds/watermelon/suicide_act(mob/user) +/obj/item/seeds/watermelon/suicide_act(mob/living/user) user.visible_message("[user] is swallowing [src]! It looks like [user.p_theyre()] trying to commit suicide!") user.gib() new product(drop_location()) diff --git a/code/modules/hydroponics/grown/nettle.dm b/code/modules/hydroponics/grown/nettle.dm index 154a3cdbcda33..ca826554c87cc 100644 --- a/code/modules/hydroponics/grown/nettle.dm +++ b/code/modules/hydroponics/grown/nettle.dm @@ -45,7 +45,7 @@ throw_range = 3 attack_verb = list("stung") -/obj/item/reagent_containers/food/snacks/grown/nettle/suicide_act(mob/user) +/obj/item/reagent_containers/food/snacks/grown/nettle/suicide_act(mob/living/user) user.visible_message("[user] is eating some of [src]! It looks like [user.p_theyre()] trying to commit suicide!") return (BRUTELOSS|TOXLOSS) diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm index 98ae2bc0a3533..1b364a9d23c96 100644 --- a/code/modules/hydroponics/hydroitemdefines.dm +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -27,9 +27,9 @@ volume = 100 list_reagents = list(/datum/reagent/toxin/plantbgone/weedkiller = 100) -/obj/item/reagent_containers/spray/weedspray/suicide_act(mob/user) +/obj/item/reagent_containers/spray/weedspray/suicide_act(mob/living/user) user.visible_message("[user] is huffing [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (TOXLOSS) + return TOXLOSS /obj/item/reagent_containers/spray/pestspray // -- Skie desc = "It's some pest eliminator spray! Do not inhale!" @@ -42,9 +42,9 @@ volume = 100 list_reagents = list(/datum/reagent/toxin/pestkiller = 100) -/obj/item/reagent_containers/spray/pestspray/suicide_act(mob/user) +/obj/item/reagent_containers/spray/pestspray/suicide_act(mob/living/user) user.visible_message("[user] is huffing [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (TOXLOSS) + return TOXLOSS /obj/item/cultivator name = "cultivator" @@ -62,9 +62,9 @@ attack_verb = list("slashed", "sliced", "cut", "clawed") hitsound = 'sound/weapons/bladeslice.ogg' -/obj/item/cultivator/suicide_act(mob/user) +/obj/item/cultivator/suicide_act(mob/living/user) user.visible_message("[user] is scratching [user.p_their()] back as hard as [user.p_they()] can with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) + return BRUTELOSS /obj/item/hatchet name = "hatchet" @@ -90,10 +90,10 @@ . = ..() AddComponent(/datum/component/butchering, 70, 100) -/obj/item/hatchet/suicide_act(mob/user) +/obj/item/hatchet/suicide_act(mob/living/user) user.visible_message("[user] is chopping at [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") playsound(src, 'sound/weapons/bladeslice.ogg', 50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS /obj/item/scythe icon_state = "scythe0" @@ -118,7 +118,7 @@ . = ..() AddComponent(/datum/component/butchering, 90, 105) -/obj/item/scythe/suicide_act(mob/user) +/obj/item/scythe/suicide_act(mob/living/user) user.visible_message("[user] is beheading [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") if(iscarbon(user)) var/mob/living/carbon/C = user @@ -126,7 +126,7 @@ if(BP) BP.drop_limb() playsound(src,pick('sound/misc/desecration-01.ogg','sound/misc/desecration-02.ogg','sound/misc/desecration-01.ogg') ,50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS /obj/item/scythe/pre_attack(atom/A, mob/living/user, params) if(swiping || !istype(A, /obj/structure/spacevine) || get_turf(A) == get_turf(user)) diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index bbc176043c518..6d82f397c7884 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -939,26 +939,26 @@ /// Tray Setters - The following procs adjust the tray or plants variables, and make sure that the stat doesn't go out of bounds./// /obj/machinery/hydroponics/proc/adjustNutri(adjustamt) - nutrilevel = CLAMP(nutrilevel + adjustamt, 0, maxnutri) + nutrilevel = clamp(nutrilevel + adjustamt, 0, maxnutri) /obj/machinery/hydroponics/proc/adjustWater(adjustamt) - waterlevel = CLAMP(waterlevel + adjustamt, 0, maxwater) + waterlevel = clamp(waterlevel + adjustamt, 0, maxwater) if(adjustamt>0) adjustToxic(-round(adjustamt/4))//Toxicity dilutation code. The more water you put in, the lesser the toxin concentration. /obj/machinery/hydroponics/proc/adjustHealth(adjustamt) if(myseed && !dead) - plant_health = CLAMP(plant_health + adjustamt, 0, myseed.endurance) + plant_health = clamp(plant_health + adjustamt, 0, myseed.endurance) /obj/machinery/hydroponics/proc/adjustToxic(adjustamt) - toxic = CLAMP(toxic + adjustamt, 0, 100) + toxic = clamp(toxic + adjustamt, 0, 100) /obj/machinery/hydroponics/proc/adjustPests(adjustamt) - pestlevel = CLAMP(pestlevel + adjustamt, 0, 10) + pestlevel = clamp(pestlevel + adjustamt, 0, 10) /obj/machinery/hydroponics/proc/adjustWeeds(adjustamt) - weedlevel = CLAMP(weedlevel + adjustamt, 0, 10) + weedlevel = clamp(weedlevel + adjustamt, 0, 10) /obj/machinery/hydroponics/proc/spawnplant() // why would you put strange reagent in a hydro tray you monster I bet you also feed them blood var/list/livingplants = list(/mob/living/simple_animal/hostile/tree, /mob/living/simple_animal/hostile/killertomato) diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm index 5987fc61442c9..bbeac338500b1 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seeds.dm @@ -253,7 +253,7 @@ /// Setters procs /// /obj/item/seeds/proc/adjust_yield(adjustamt) if(yield != -1) // Unharvestable shouldn't suddenly turn harvestable - yield = CLAMP(yield + adjustamt, 0, 10) + yield = clamp(yield + adjustamt, 0, 10) if(yield <= 0 && get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism)) yield = 1 // Mushrooms always have a minimum yield of 1. @@ -262,39 +262,39 @@ C.value = yield /obj/item/seeds/proc/adjust_lifespan(adjustamt) - lifespan = CLAMP(lifespan + adjustamt, 10, 100) + lifespan = clamp(lifespan + adjustamt, 10, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/lifespan) if(C) C.value = lifespan /obj/item/seeds/proc/adjust_endurance(adjustamt) - endurance = CLAMP(endurance + adjustamt, 10, 100) + endurance = clamp(endurance + adjustamt, 10, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/endurance) if(C) C.value = endurance /obj/item/seeds/proc/adjust_production(adjustamt) if(yield != -1) - production = CLAMP(production + adjustamt, 1, 10) + production = clamp(production + adjustamt, 1, 10) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/production) if(C) C.value = production /obj/item/seeds/proc/adjust_potency(adjustamt) if(potency != -1) - potency = CLAMP(potency + adjustamt, 0, 100) + potency = clamp(potency + adjustamt, 0, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/potency) if(C) C.value = potency /obj/item/seeds/proc/adjust_weed_rate(adjustamt) - weed_rate = CLAMP(weed_rate + adjustamt, 0, 10) + weed_rate = clamp(weed_rate + adjustamt, 0, 10) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_rate) if(C) C.value = weed_rate /obj/item/seeds/proc/adjust_weed_chance(adjustamt) - weed_chance = CLAMP(weed_chance + adjustamt, 0, 67) + weed_chance = clamp(weed_chance + adjustamt, 0, 67) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_chance) if(C) C.value = weed_chance @@ -303,7 +303,7 @@ /obj/item/seeds/proc/set_yield(adjustamt) if(yield != -1) // Unharvestable shouldn't suddenly turn harvestable - yield = CLAMP(adjustamt, 0, 10) + yield = clamp(adjustamt, 0, 10) if(yield <= 0 && get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism)) yield = 1 // Mushrooms always have a minimum yield of 1. @@ -312,39 +312,39 @@ C.value = yield /obj/item/seeds/proc/set_lifespan(adjustamt) - lifespan = CLAMP(adjustamt, 10, 100) + lifespan = clamp(adjustamt, 10, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/lifespan) if(C) C.value = lifespan /obj/item/seeds/proc/set_endurance(adjustamt) - endurance = CLAMP(adjustamt, 10, 100) + endurance = clamp(adjustamt, 10, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/endurance) if(C) C.value = endurance /obj/item/seeds/proc/set_production(adjustamt) if(yield != -1) - production = CLAMP(adjustamt, 1, 10) + production = clamp(adjustamt, 1, 10) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/production) if(C) C.value = production /obj/item/seeds/proc/set_potency(adjustamt) if(potency != -1) - potency = CLAMP(adjustamt, 0, 100) + potency = clamp(adjustamt, 0, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/potency) if(C) C.value = potency /obj/item/seeds/proc/set_weed_rate(adjustamt) - weed_rate = CLAMP(adjustamt, 0, 10) + weed_rate = clamp(adjustamt, 0, 10) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_rate) if(C) C.value = weed_rate /obj/item/seeds/proc/set_weed_chance(adjustamt) - weed_chance = CLAMP(adjustamt, 0, 67) + weed_chance = clamp(adjustamt, 0, 67) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_chance) if(C) C.value = weed_chance diff --git a/code/modules/instruments/items.dm b/code/modules/instruments/items.dm index 8f8e716f63cce..dde806fa765e5 100644 --- a/code/modules/instruments/items.dm +++ b/code/modules/instruments/items.dm @@ -27,9 +27,9 @@ /obj/item/instrument/proc/should_stop_playing(mob/user) return user.incapacitated() || !((loc == user) || (isturf(loc) && Adjacent(user))) // sorry, no more TK playing. -/obj/item/instrument/suicide_act(mob/user) +/obj/item/instrument/suicide_act(mob/living/user) user.visible_message("[user] begins to play 'Gloomy Sunday'! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) + return BRUTELOSS /obj/item/instrument/attack_self(mob/user) if(!user.IsAdvancedToolUser()) diff --git a/code/modules/jobs/job_exp.dm b/code/modules/jobs/job_exp.dm index 8596a9af07e2b..89ef4ced24114 100644 --- a/code/modules/jobs/job_exp.dm +++ b/code/modules/jobs/job_exp.dm @@ -56,6 +56,12 @@ GLOBAL_PROTECT(exp_to_update) for(var/job in typelist["titles"]) if(job in explist) amount += explist[job] + // Removed job support + typelist = GLOB.exp_removed_jobsmap[exptype] + if(typelist) + for(var/job in typelist["titles"]) + if(job in explist) + amount += explist[job] return amount /client/proc/get_exp_living(pure_numeric = FALSE) @@ -107,6 +113,9 @@ GLOBAL_PROTECT(exp_to_update) for(var/rtype in SSjob.name_occupations) if(!play_records[rtype]) play_records[rtype] = 0 + for(var/rtype in GLOB.exp_removed_jobs) + if(!play_records[rtype]) + play_records[rtype] = 0 for(var/rtype in GLOB.exp_specialmap) if(!play_records[rtype]) play_records[rtype] = 0 diff --git a/code/modules/jobs/job_report.dm b/code/modules/jobs/job_report.dm index 49f50f72c64de..4a404e3a8a7f4 100644 --- a/code/modules/jobs/job_report.dm +++ b/code/modules/jobs/job_report.dm @@ -29,12 +29,17 @@ var/list/data = list() data["jobPlaytimes"] = list() + data["jobRemovedPlaytimes"] = list() data["specialPlaytimes"] = list() for (var/job_name in SSjob.name_occupations) var/playtime = play_records[job_name] ? text2num(play_records[job_name]) : 0 data["jobPlaytimes"][job_name] = playtime + for (var/job_name in GLOB.exp_removed_jobs) + var/playtime = play_records[job_name] ? text2num(play_records[job_name]) : 0 + data["jobRemovedPlaytimes"][job_name] = playtime + for (var/special_name in GLOB.exp_specialmap[EXP_TYPE_SPECIAL]) var/playtime = play_records[special_name] ? text2num(play_records[special_name]) : 0 data["specialPlaytimes"][special_name] = playtime diff --git a/code/modules/jobs/job_types/deputy.dm b/code/modules/jobs/job_types/deputy.dm index ba3acbdce2f97..79fd85d2776d0 100644 --- a/code/modules/jobs/job_types/deputy.dm +++ b/code/modules/jobs/job_types/deputy.dm @@ -24,7 +24,7 @@ payment_per_department = list(ACCOUNT_SEC_ID = PAYCHECK_EASY) mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM) - display_order = JOB_DISPLAY_ORDER_DEPUTY //see code/__DEFINES/jobs.dm + show_in_prefs = FALSE /datum/outfit/job/deputy name = JOB_NAME_DEPUTY diff --git a/code/modules/jobs/job_types/security_officer.dm b/code/modules/jobs/job_types/security_officer.dm index 88885ba498262..804918e162d3d 100644 --- a/code/modules/jobs/job_types/security_officer.dm +++ b/code/modules/jobs/job_types/security_officer.dm @@ -163,6 +163,11 @@ GLOBAL_LIST_INIT(available_depts, list(SEC_DEPT_ENGINEERING, SEC_DEPT_MEDICAL, S chameleon_extras = list(/obj/item/gun/energy/disabler, /obj/item/clothing/glasses/hud/security/sunglasses, /obj/item/clothing/head/helmet) //The helmet is necessary because /obj/item/clothing/head/helmet/sec is overwritten in the chameleon list by the standard helmet, which has the same name and icon state +/datum/outfit/job/security_officer/bulletproof + name = "Security Officer (Bulletproof)" + head = /obj/item/clothing/head/helmet/alt + suit = /obj/item/clothing/suit/armor/bulletproof + /obj/item/radio/headset/headset_sec/alt/department/Initialize(mapload) . = ..() diff --git a/code/modules/jobs/jobs.dm b/code/modules/jobs/jobs.dm index 08d8da75aa13a..0c3764e702b3d 100644 --- a/code/modules/jobs/jobs.dm +++ b/code/modules/jobs/jobs.dm @@ -228,7 +228,18 @@ GLOBAL_LIST_INIT(security_positions_hud, list( JOB_HUD_DEPUTY, JOB_HUD_RAWSECURITY)) +/// Put any removed jobs here so they can still show in playtime listings. +GLOBAL_LIST_INIT(exp_removed_jobs, list( +// "Virologist", +)) +GLOBAL_PROTECT(exp_removed_jobs) +/// Put any removed jobs here so they can still show in playtime listings. +GLOBAL_LIST_INIT(exp_removed_jobsmap, list( +// EXP_TYPE_CREW = list("titles" = list("Virologist")), +// EXP_TYPE_MEDICAL = list("titles" = list("Virologist")), +)) +GLOBAL_PROTECT(exp_removed_jobsmap) GLOBAL_LIST_INIT(exp_jobsmap, list( EXP_TYPE_CREW = list("titles" = command_positions | engineering_positions | medical_positions | science_positions | supply_positions | security_positions | civilian_positions | gimmick_positions | list(JOB_NAME_AI,JOB_NAME_CYBORG)), // crew positions diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index c6fd689d57a2c..40bf496b3246d 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -19,15 +19,22 @@ icon_state = "oldcomp" icon_screen = "library" icon_keyboard = null + + //these muthafuckas arent supposed to smooth + base_icon_state = null + smoothing_flags = null + smoothing_groups = null + canSmoothWith = null + circuit = /obj/item/circuitboard/computer/libraryconsole desc = "Checked out books MUST be returned on time." + clockwork = TRUE //it'd look weird + broken_overlay_emissive = TRUE var/screenstate = 0 var/title var/category = "Any" var/author var/search_page = 0 - clockwork = TRUE //it'd look weird - broken_overlay_emissive = TRUE /obj/machinery/computer/libraryconsole/ui_interact(mob/user) . = ..() @@ -297,7 +304,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums dat += "(Order book by SS13BN)

" dat += "" dat += "" - dat += libcomp_menu[CLAMP(page,1,libcomp_menu.len)] + dat += libcomp_menu[clamp(page,1,libcomp_menu.len)] dat += "" dat += "
AUTHORTITLECATEGORY
<<<< >>>>
" dat += "
(Return to main menu)
" @@ -336,6 +343,13 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums dat += "\[Bible\]
" dat += "\[Space Law\]
" dat += "\[Poster\]
" + dat += "\[Command SOP\]
" + dat += "\[Security SOP\]
" + dat += "\[Engineering SOP\]
" + dat += "\[Supply SOP\]
" + dat += "\[Science SOP\]
" + dat += "\[Medical SOP\]
" + dat += "\[Service SOP\]
" dat += "(Return to main menu)
" if(8) dat += "

Accessing Forbidden Lore Vault v 1.3

" @@ -540,6 +554,55 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums cooldown = world.time + PRINTER_COOLDOWN else say("Printer currently unavailable, please wait a moment.") + if(href_list["printsopcmd"]) + if(cooldown < world.time) + new /obj/item/book/manual/wiki/sopcommand(src.loc) + cooldown = world.time + PRINTER_COOLDOWN + else + say("Printer currently unavailable, please wait a moment.") + + if(href_list["printsopsec"]) + if(cooldown < world.time) + new /obj/item/book/manual/wiki/sopsecurity(src.loc) + cooldown = world.time + PRINTER_COOLDOWN + else + say("Printer currently unavailable, please wait a moment.") + + if(href_list["printsopeng"]) + if(cooldown < world.time) + new /obj/item/book/manual/wiki/sopengineering(src.loc) + cooldown = world.time + PRINTER_COOLDOWN + else + say("Printer currently unavailable, please wait a moment.") + + if(href_list["printsopsup"]) + if(cooldown < world.time) + new /obj/item/book/manual/wiki/sopsupply(src.loc) + cooldown = world.time + PRINTER_COOLDOWN + else + say("Printer currently unavailable, please wait a moment.") + + if(href_list["printsopsci"]) + if(cooldown < world.time) + new /obj/item/book/manual/wiki/sopscience(src.loc) + cooldown = world.time + PRINTER_COOLDOWN + else + say("Printer currently unavailable, please wait a moment.") + + if(href_list["printsopmed"]) + if(cooldown < world.time) + new /obj/item/book/manual/wiki/sopmedical(src.loc) + cooldown = world.time + PRINTER_COOLDOWN + else + say("Printer currently unavailable, please wait a moment.") + + if(href_list["printsopsvc"]) + if(cooldown < world.time) + new /obj/item/book/manual/wiki/sopservice(src.loc) + cooldown = world.time + PRINTER_COOLDOWN + else + say("Printer currently unavailable, please wait a moment.") + add_fingerprint(usr) updateUsrDialog() diff --git a/code/modules/mapping/mapping_items/job_scaling_loot_spawners.dm b/code/modules/mapping/mapping_items/job_scaling_loot_spawners.dm index 581d2eecbfb28..830f6227b1483 100644 --- a/code/modules/mapping/mapping_items/job_scaling_loot_spawners.dm +++ b/code/modules/mapping/mapping_items/job_scaling_loot_spawners.dm @@ -23,7 +23,7 @@ for (var/job_name in jobs) var/datum/job/located = SSjob.GetJob(job_name) total += located.current_positions - total = CEILING(CLAMP(total * linear_scaling_rate, minimum, maximum), 1) + total = CEILING(clamp(total * linear_scaling_rate, minimum, maximum), 1) lootcount = total if(!length(loot)) qdel(src) diff --git a/code/modules/mining/aux_base.dm b/code/modules/mining/aux_base.dm index 031c27d016f8f..03a8b3704e911 100644 --- a/code/modules/mining/aux_base.dm +++ b/code/modules/mining/aux_base.dm @@ -15,6 +15,10 @@ name = "auxillary base management console" icon = 'icons/obj/terminals.dmi' icon_state = "dorm_available" + base_icon_state = null + smoothing_flags = NONE + smoothing_groups = null + canSmoothWith = null var/shuttleId = "colony_drop" desc = "Allows a deployable expedition base to be dropped from the station to a designated mining location. It can also \ interface with the mining shuttle at the landing site if a mobile beacon is also deployed." diff --git a/code/modules/mining/coins.dm b/code/modules/mining/coins.dm index ffa3762eb7c22..04fc89ab5c7c6 100644 --- a/code/modules/mining/coins.dm +++ b/code/modules/mining/coins.dm @@ -49,10 +49,10 @@ /obj/item/coin/proc/manual_suicide(mob/living/user) var/index = sideslist.Find(coinflip) - if (index==2)//tails + if (index == 2)//tails user.visible_message("\the [src] lands on [coinflip]! [user] promptly falls over, dead!") user.adjustOxyLoss(200) - user.death(0) + user.death(FALSE) user.set_suicide(TRUE) user.suicide_log() else diff --git a/code/modules/mining/equipment/regenerative_core.dm b/code/modules/mining/equipment/regenerative_core.dm index 108dc6d6e6ac6..1198114e63252 100644 --- a/code/modules/mining/equipment/regenerative_core.dm +++ b/code/modules/mining/equipment/regenerative_core.dm @@ -128,16 +128,16 @@ /obj/item/organ/regenerative_core/legion/Initialize(mapload) . = ..() - update_icon() + update_appearance() -/obj/item/organ/regenerative_core/update_icon() +/obj/item/organ/regenerative_core/update_icon_state() icon_state = inert ? "legion_soul_inert" : "legion_soul" - cut_overlays() + return ..() + +/obj/item/organ/regenerative_core/update_overlays() + . = ..() if(!inert && !preserved) - add_overlay("legion_soul_crackle") - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + . += "legion_soul_crackle" /obj/item/organ/regenerative_core/legion/go_inert() ..() diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index 2f62f52412d6b..23087b95ac556 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -75,7 +75,8 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) if(isliving(A)) var/mob/living/M = A M.Paralyze(320) // Keep them from moving during the duration of the extraction - M.buckled?.unbuckle_mob(M, TRUE) // Unbuckle them to prevent anchoring problems + if(M.buckled) + M.buckled.unbuckle_mob(M, TRUE) // Unbuckle them to prevent anchoring problems else A.anchored = TRUE A.set_density(FALSE) diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 0c1f07b4577f7..c7a98b9fb6479 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -734,7 +734,7 @@ "Both modes will build up existing bleed effects, doing a burst of high damage if the bleed is built up high enough.\n"+\ "Transforming it immediately after an attack causes the next attack to come out faster.
" -/obj/item/melee/transforming/cleaving_saw/suicide_act(mob/user) +/obj/item/melee/transforming/cleaving_saw/suicide_act(mob/living/user) user.visible_message("[user] is [active ? "closing [src] on [user.p_their()] neck" : "opening [src] into [user.p_their()] chest"]! It looks like [user.p_theyre()] trying to commit suicide!") transform_cooldown = 0 transform_weapon(user, TRUE) @@ -891,13 +891,13 @@ force = 0 var/ghost_counter = ghost_check() - force = CLAMP((ghost_counter * 4), 0, 75) + force = clamp((ghost_counter * 4), 0, 75) user.visible_message("[user] strikes with the force of [ghost_counter] vengeful spirits!") ..() /obj/item/melee/ghost_sword/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) var/ghost_counter = ghost_check() - final_block_chance += CLAMP((ghost_counter * 5), 0, 75) + final_block_chance += clamp((ghost_counter * 5), 0, 75) owner.visible_message("[owner] is protected by a ring of [ghost_counter] ghosts!") return ..() diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm index 9fd05c70674ee..eeadddad65ceb 100644 --- a/code/modules/mining/machine_processing.dm +++ b/code/modules/mining/machine_processing.dm @@ -155,7 +155,7 @@ machine.toggle_auto_shutdown() if("set_smelt_amount") - machine.smelt_amount_limit = CLAMP(text2num(params["amount"]), 1, 100) + machine.smelt_amount_limit = clamp(text2num(params["amount"]), 1, 100) /obj/machinery/mineral/processing_unit_console/Destroy() machine.console = null diff --git a/code/modules/mining/machine_silo.dm b/code/modules/mining/machine_silo.dm index 9c5326fb4fc57..7a8a6a40fcb1c 100644 --- a/code/modules/mining/machine_silo.dm +++ b/code/modules/mining/machine_silo.dm @@ -130,7 +130,7 @@ GLOBAL_LIST_EMPTY(silo_access_logs) var/list/logs = GLOB.silo_access_logs[REF(src)] var/len = LAZYLEN(logs) var/num_pages = 1 + round((len - 1) / 30) - var/page = CLAMP(log_page, 1, num_pages) + var/page = clamp(log_page, 1, num_pages) if(num_pages > 1) for(var/i in 1 to num_pages) if(i == page) diff --git a/code/modules/mob/dead/new_player/sprite_accessories.dm b/code/modules/mob/dead/new_player/sprite_accessories.dm index ab0f6af9a3c04..8362eec68acb6 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories.dm @@ -2113,6 +2113,14 @@ name = "Moon Fly" icon_state = "moonfly" +/datum/sprite_accessory/moth_wings/witchwingi + name = "Witch Wing" + icon_state = "witchwing" + +/datum/sprite_accessory/moth_wingsopen/witchwing + name = "Witch Wing" + icon_state = "witchwing" + /datum/sprite_accessory/moth_wings/snow name = "Snow" icon_state = "snow" @@ -2204,6 +2212,10 @@ name = "Snow" icon_state = "snow" +/datum/sprite_accessory/moth_antennae/witchwing + name = "Witch Wing" + icon_state = "witchwing" + /datum/sprite_accessory/moth_markings // the markings that moths can have. finally something other than the boring tan icon = 'icons/mob/moth_markings.dmi' color_src = null @@ -2257,6 +2269,10 @@ name = "Moon Fly" icon_state = "moonfly" +/datum/sprite_accessory/moth_markings/witchwing + name = "Witch Wing" + icon_state = "witchwing" + // IPC accessories. /datum/sprite_accessory/ipc_screens diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index c59a2060159d8..310ed36a29751 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -308,7 +308,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(stat != DEAD) succumb() if(stat == DEAD) - ghostize(1) + ghostize(TRUE) else var/response = tgui_alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you may not play again this round! You can't change your mind so choose wisely!!)", "Are you sure you want to ghost?", list("Ghost", "Stay in body")) if(response != "Ghost") diff --git a/code/modules/mob/living/basic/basic_defense.dm b/code/modules/mob/living/basic/basic_defense.dm index ac5c261a85a6f..0e4c2e221b3f5 100644 --- a/code/modules/mob/living/basic/basic_defense.dm +++ b/code/modules/mob/living/basic/basic_defense.dm @@ -157,6 +157,7 @@ if(prob(bomb_armor)) adjustBruteLoss(500) else + investigate_log("has been gibbed by an explosion.", INVESTIGATE_DEATHS) gib() return if (EXPLODE_HEAVY) diff --git a/code/modules/mob/living/bloodcrawl.dm b/code/modules/mob/living/bloodcrawl.dm index c0577c6a6dfb3..9edaa6d1706db 100644 --- a/code/modules/mob/living/bloodcrawl.dm +++ b/code/modules/mob/living/bloodcrawl.dm @@ -127,7 +127,9 @@ src.revive(full_heal = 1) // No defib possible after laughter - victim.adjustBruteLoss(1000) + victim.apply_damage(1000, BRUTE) + if(victim.stat != DEAD) + victim.investigate_log("has been killed by being consumed by a slaugter demon.", INVESTIGATE_DEATHS) victim.death() bloodcrawl_swallow(victim) return TRUE diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm index 3536574d11252..7718d6f255f3c 100644 --- a/code/modules/mob/living/brain/brain.dm +++ b/code/modules/mob/living/brain/brain.dm @@ -26,8 +26,8 @@ /mob/living/brain/Destroy() if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting. - if(stat!=DEAD) //If not dead. - death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA + if(stat != DEAD) + death(TRUE) if(mind) //You aren't allowed to return to brains that don't exist mind.set_current(null) ghostize() //Ghostize checks for key so nothing else is necessary. diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index e9be3a75242ab..d251ef72d5936 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -178,6 +178,7 @@ /obj/item/organ/brain/on_life() if(damage >= BRAIN_DAMAGE_DEATH) //rip to_chat(owner, "The last spark of life in your brain fizzles out.") + owner.investigate_log("has been killed by brain damage.", INVESTIGATE_DEATHS) owner.death() brain_death = TRUE diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 4ac6dad9bb3e7..b9c664f5252f5 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -9,6 +9,7 @@ maxHealth = 25 health = 25 + hardcrit_threshold = HEALTH_THRESHOLD_CRIT var/amount_grown = 0 var/max_grown = 100 diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index b26d2978befaf..fe53dfa71772e 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -18,15 +18,12 @@ if(health<= -maxHealth || !getorgan(/obj/item/organ/brain)) death() return - if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (HAS_TRAIT(src, TRAIT_DEATHCOMA)) || health <= crit_threshold) - if(stat == CONSCIOUS) - set_stat(UNCONSCIOUS) - become_blind(UNCONSCIOUS_BLIND) - update_mobility() + if((HAS_TRAIT(src, TRAIT_KNOCKEDOUT))) + set_stat(UNCONSCIOUS) else if(stat == UNCONSCIOUS) - set_stat(CONSCIOUS) - cure_blind(UNCONSCIOUS_BLIND) set_resting(FALSE) + set_stat(CONSCIOUS) + update_mobility() update_damage_hud() update_health_hud() diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm index 8500172811799..c91f2cb9b9b88 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -54,9 +54,6 @@ STOP_PROCESSING(SSobj, src) /obj/item/organ/body_egg/alien_embryo/egg_process() - var/mob/living/L = owner - if(IS_IN_STASIS(L)) - return if(!next_stage_time) COOLDOWN_START(src, next_stage_time, 30 SECONDS) return @@ -78,8 +75,6 @@ return AttemptGrow() - - /obj/item/organ/body_egg/alien_embryo/proc/AttemptGrow(kill_on_success = TRUE) if(!owner || bursting) return @@ -132,6 +127,7 @@ new_xeno.visible_message("[new_xeno] wriggles out of [owner]!", "You exit [owner], your previous host.") owner.adjustBruteLoss(40) host.cut_overlay(overlay) + owner.investigate_log("has been killed by an alien larva chestburst.", INVESTIGATE_DEATHS) qdel(src) diff --git a/code/modules/mob/living/carbon/alien/status_procs.dm b/code/modules/mob/living/carbon/alien/status_procs.dm index 7fd1d31872346..0affc187a12f0 100644 --- a/code/modules/mob/living/carbon/alien/status_procs.dm +++ b/code/modules/mob/living/carbon/alien/status_procs.dm @@ -17,4 +17,4 @@ /mob/living/carbon/alien/AdjustStun(amount, updating = 1, ignore_canstun = 0) . = ..() if(!.) - move_delay_add = CLAMP(move_delay_add + round(amount/2), 0, 10) + move_delay_add = clamp(move_delay_add + round(amount/2), 0, 10) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 22784852973bd..608db51f5a737 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -404,7 +404,7 @@ return 0 return ..() -/mob/living/carbon/proc/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, toxic = FALSE) +/mob/living/carbon/proc/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, toxic = VOMIT_TOXIC, purge = FALSE) if(HAS_TRAIT(src, TRAIT_NOHUNGER)) return 1 @@ -452,10 +452,10 @@ adjustBruteLoss(3) else if(src.reagents.has_reagent(/datum/reagent/consumable/ethanol/blazaam, needs_metabolizing = TRUE)) if(T) - T.add_vomit_floor(src, VOMIT_PURPLE) + T.add_vomit_floor(src, toxic || VOMIT_PURPLE, purge) else if(T) - T.add_vomit_floor(src, VOMIT_TOXIC)//toxic barf looks different + T.add_vomit_floor(src, toxic, purge)//toxic barf looks different T = get_step(T, dir) if (T.is_blocked_turf()) break @@ -496,7 +496,7 @@ total_brute += (BP.brute_dam * BP.body_damage_coeff) total_burn += (BP.burn_dam * BP.body_damage_coeff) total_stamina += (BP.stamina_dam * BP.stam_damage_coeff) - health = round(maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute, DAMAGE_PRECISION) + set_health(round(maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute, DAMAGE_PRECISION)) staminaloss = round(total_stamina, DAMAGE_PRECISION) update_stat() update_mobility() @@ -513,11 +513,12 @@ /mob/living/carbon/update_stamina(extend_stam_crit = FALSE) var/stam = getStaminaLoss() if(stam >= DAMAGE_PRECISION && (maxHealth - stam) <= crit_threshold && !stat && !HAS_TRAIT(src, TRAIT_NOSTAMCRIT)) - if(extend_stam_crit || !stam_paralyzed) + if(extend_stam_crit || !HAS_TRAIT_FROM(src, TRAIT_INCAPACITATED, STAMINA)) enter_stamcrit() - else if(stam_paralyzed) - stam_paralyzed = FALSE - REMOVE_TRAIT(src,TRAIT_INCAPACITATED, STAMINA) + else if(HAS_TRAIT_FROM(src, TRAIT_INCAPACITATED, STAMINA)) + REMOVE_TRAIT(src, TRAIT_INCAPACITATED, STAMINA) + REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, STAMINA) + /*REMOVE_TRAIT(src, TRAIT_FLOORED, STAMINA)*/ else return update_health_hud() @@ -724,28 +725,34 @@ if(hud_used && hud_used.internals) hud_used.internals.icon_state = "internal[internal_state]" +/mob/living/carbon/set_health(new_value) + . = ..() + if(. > hardcrit_threshold) + if(health <= hardcrit_threshold && !HAS_TRAIT(src, TRAIT_NOHARDCRIT)) + ADD_TRAIT(src, TRAIT_KNOCKEDOUT, CRIT_HEALTH_TRAIT) + else if(health > hardcrit_threshold) + REMOVE_TRAIT(src, TRAIT_KNOCKEDOUT, CRIT_HEALTH_TRAIT) + if(CONFIG_GET(flag/near_death_experience)) + if(. > HEALTH_THRESHOLD_NEARDEATH) + if(health <= HEALTH_THRESHOLD_NEARDEATH && !HAS_TRAIT(src, TRAIT_NODEATH)) + ADD_TRAIT(src, TRAIT_SIXTHSENSE, "near-death") + else if(health > HEALTH_THRESHOLD_NEARDEATH) + REMOVE_TRAIT(src, TRAIT_SIXTHSENSE, "near-death") + /mob/living/carbon/update_stat() if(status_flags & GODMODE) return if(stat != DEAD) if(health <= HEALTH_THRESHOLD_DEAD && !HAS_TRAIT(src, TRAIT_NODEATH)) death() - cure_blind(UNCONSCIOUS_BLIND) return - if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (HAS_TRAIT(src, TRAIT_DEATHCOMA)) || (health <= HEALTH_THRESHOLD_FULLCRIT && !HAS_TRAIT(src, TRAIT_NOHARDCRIT))) + if(HAS_TRAIT(src, TRAIT_KNOCKEDOUT)) set_stat(UNCONSCIOUS) - become_blind(UNCONSCIOUS_BLIND) - if(CONFIG_GET(flag/near_death_experience) && health <= HEALTH_THRESHOLD_NEARDEATH && !HAS_TRAIT(src, TRAIT_NODEATH)) - ADD_TRAIT(src, TRAIT_SIXTHSENSE, "near-death") - else - REMOVE_TRAIT(src, TRAIT_SIXTHSENSE, "near-death") else if(health <= crit_threshold && !HAS_TRAIT(src, TRAIT_NOSOFTCRIT)) set_stat(SOFT_CRIT) else set_stat(CONSCIOUS) - cure_blind(UNCONSCIOUS_BLIND) - REMOVE_TRAIT(src, TRAIT_SIXTHSENSE, "near-death") update_mobility() update_damage_hud() update_health_hud() diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 939c17e615e57..6da3904611ec1 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -434,3 +434,24 @@ var/obj/item/organ/ears/ears = getorganslot(ORGAN_SLOT_EARS) if(istype(ears) && !ears.deaf) . = TRUE + +/mob/living/carbon/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE) + . = ..() + if(isnull(.)) + return + if(. <= 50) + if(getOxyLoss() > 50) + ADD_TRAIT(src, TRAIT_KNOCKEDOUT, OXYLOSS_TRAIT) + else if(getOxyLoss() <= 50) + REMOVE_TRAIT(src, TRAIT_KNOCKEDOUT, OXYLOSS_TRAIT) + + +/mob/living/carbon/setOxyLoss(amount, updating_health = TRUE, forced = FALSE) + . = ..() + if(isnull(.)) + return + if(. <= 50) + if(getOxyLoss() > 50) + ADD_TRAIT(src, TRAIT_KNOCKEDOUT, OXYLOSS_TRAIT) + else if(getOxyLoss() <= 50) + REMOVE_TRAIT(src, TRAIT_KNOCKEDOUT, OXYLOSS_TRAIT) diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 53a95b17b1244..22b8bf553a97a 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -72,7 +72,6 @@ var/drunkenness = 0 //Overall drunkenness - check handle_alcohol() in life.dm for effects var/stam_regen_start_time = 0 //used to halt stamina regen temporarily - var/stam_paralyzed = FALSE //knocks you down var/stam_heal = 10 //Stamina healed per 2 seconds overall. When the mob has taken more than 60 stamina damage, the rate of stamina regeneration will be increased, up to 20 per second when the mob has taken 120 stamina damage. /// Timer id of any transformation diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 0de5ea66f2428..83277ddece517 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -91,6 +91,27 @@ //Death dust(TRUE) return + if(key) // Prevents log spamming of keyless mob deaths (like xenobio monkeys) + investigate_log("has died at [loc_name(src)].
\ + BRUTE: [src.getBruteLoss()] BURN: [src.getFireLoss()] TOX: [src.getToxLoss()] OXY: [src.getOxyLoss()] CLONE: [src.getCloneLoss()] STAM: [src.getStaminaLoss()]
\ + Brain damage: [src.getOrganLoss(ORGAN_SLOT_BRAIN) || "0"]
\ + Blood volume: [src.blood_volume]cl ([round((src.blood_volume / BLOOD_VOLUME_NORMAL) * 100, 0.1)]%)
\ + Reagents:
[reagents_readout()]", INVESTIGATE_DEATHS) + to_chat(src, "You have died. Barring complete bodyloss, you can in most cases be revived by other players. If you do not wish to be brought back, use the \"Do Not Resuscitate\" verb in the ghost tab.
") + +/mob/living/carbon/human/proc/reagents_readout() + var/readout = "Blood:" + for(var/datum/reagent/reagent in reagents?.reagent_list) + readout += "
[round(reagent.volume, 0.001)] units of [reagent.name]" + /* + readout += "
Stomach:" + var/obj/item/organ/internal/stomach/belly = getorganslot(ORGAN_SLOT_STOMACH) + for(var/datum/reagent/bile in belly?.reagents?.reagent_list) + if(!belly.food_reagents[bile.type]) + readout += "
[round(bile.volume, 0.001)] units of [bile.name]" + */ + + return readout /mob/living/carbon/human/proc/makeSkeleton() ADD_TRAIT(src, TRAIT_DISFIGURED, TRAIT_GENERIC) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 46103244cabed..4359e07bd7794 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -412,6 +412,7 @@ SSexplosions.med_mov_atom += thing if(EXPLODE_LIGHT) SSexplosions.low_mov_atom += thing + investigate_log("has been gibbed by an explosion.", INVESTIGATE_DEATHS) gib() return else diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index f4a4722b3b87d..f355edb53254a 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -23,9 +23,9 @@ /mob/living/carbon/human/experience_pressure_difference(pressure_difference) if(pressure_difference > 100) - playsound_local(null, 'sound/effects/space_wind_big.ogg', CLAMP(pressure_difference / 50, 10, 100), 1) + playsound_local(null, 'sound/effects/space_wind_big.ogg', clamp(pressure_difference / 50, 10, 100), 1) else - playsound_local(null, 'sound/effects/space_wind.ogg', CLAMP(pressure_difference, 10, 100), 1) + playsound_local(null, 'sound/effects/space_wind.ogg', clamp(pressure_difference, 10, 100), 1) if(shoes && isclothing(shoes)) var/obj/item/clothing/S = shoes if((S.clothing_flags & NOSLIP)) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 8bb0349378919..4a327a85284cb 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1429,7 +1429,7 @@ GLOBAL_LIST_EMPTY(features_by_species) H.domutcheck() if(radiation > RAD_MOB_HAIRLOSS) - if(prob(15) && !(H.hair_style == "Bald") && (HAIR in species_traits)) + if(prob(15) && !(H.hair_style == "Bald") && (HAIR in species_traits) && !HAS_TRAIT(H, TRAIT_NOHAIRLOSS)) to_chat(H, "Your hair starts to fall out in clumps.") addtimer(CALLBACK(src, PROC_REF(go_bald), H), 50) diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm index e7222cbe951ef..9539e0a6cb596 100644 --- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm +++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm @@ -44,14 +44,15 @@ H.regenerate_limb(BODY_ZONE_HEAD,FALSE) ..() -/datum/species/dullahan/spec_life(mob/living/carbon/human/H) +/datum/species/dullahan/spec_life(mob/living/carbon/human/human) if(QDELETED(myhead)) myhead = null - H.gib() - var/obj/item/bodypart/head/head2 = H.get_bodypart(BODY_ZONE_HEAD) + human.investigate_log("has been gibbed by the loss of [human.p_their()] head.", INVESTIGATE_DEATHS) + human.gib() + var/obj/item/bodypart/head/head2 = human.get_bodypart(BODY_ZONE_HEAD) if(head2) myhead = null - H.gib() + human.gib() /datum/species/dullahan/proc/update_vision_perspective(mob/living/carbon/human/H) var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES) @@ -179,6 +180,7 @@ if(H.dna.species.id == SPECIES_DULLAHAN) var/datum/species/dullahan/D = H.dna.species D.myhead = null + owner.investigate_log("has been gibbed by the destruction of their head/body relay.", INVESTIGATE_DEATHS) owner.gib() owner = null return ..() diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index 3ea22e48eeab2..9f5c8c81f8704 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -129,6 +129,7 @@ if(H.bodytemperature > 850 && H.on_fire && prob(25)) explosion(get_turf(H),1,2,4,flame_range = 5) if(H) + H.investigate_log("has been gibbed as [H.p_their()] body explodes.", INVESTIGATE_DEATHS) H.gib() if(H.fire_stacks < 2) //flammable H.adjust_fire_stacks(1) @@ -437,7 +438,7 @@ var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) // redirect the projectile P.firer = H - P.preparePixelProjectile(locate(CLAMP(new_x, 1, world.maxx), CLAMP(new_y, 1, world.maxy), H.z), H) + P.preparePixelProjectile(locate(clamp(new_x, 1, world.maxx), clamp(new_y, 1, world.maxy), H.z), H) return BULLET_ACT_FORCE_PIERCE return ..() diff --git a/code/modules/mob/living/carbon/human/species_types/oozelings.dm b/code/modules/mob/living/carbon/human/species_types/oozelings.dm index 99eb6a57d49e0..53c16edcf9da5 100644 --- a/code/modules/mob/living/carbon/human/species_types/oozelings.dm +++ b/code/modules/mob/living/carbon/human/species_types/oozelings.dm @@ -4,7 +4,7 @@ bodyflag = FLAG_OOZELING default_color = "00FF90" species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR) - inherent_traits = list(TRAIT_TOXINLOVER,TRAIT_NOFIRE,TRAIT_ALWAYS_CLEAN,TRAIT_EASYDISMEMBER) + inherent_traits = list(TRAIT_TOXINLOVER,TRAIT_NOHAIRLOSS,TRAIT_NOFIRE,TRAIT_ALWAYS_CLEAN,TRAIT_EASYDISMEMBER) hair_color = "mutcolor" hair_alpha = 150 mutantlungs = /obj/item/organ/lungs/slime @@ -104,11 +104,14 @@ /datum/species/oozeling/proc/Cannibalize_Body(mob/living/carbon/human/H) var/list/limbs_to_consume = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) - H.get_missing_limbs() var/obj/item/bodypart/consumed_limb + for(var/L in limbs_to_consume) //Check every bodypart the oozeling has, see if they're organic or not + if(!IS_ORGANIC_LIMB(H.get_bodypart(L))) //Get actual limb, list only has body zone + limbs_to_consume -= L //If it's inorganic, remove it from the consumption list if(!limbs_to_consume.len) H.losebreath++ return - if(H.get_num_legs(FALSE)) //Legs go before arms - limbs_to_consume -= list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM) + if((BODY_ZONE_L_LEG in limbs_to_consume) || (BODY_ZONE_R_LEG in limbs_to_consume)) //Check if there are any organic legs left + limbs_to_consume -= list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM) //If there are, autocannibalize those first consumed_limb = H.get_bodypart(pick(limbs_to_consume)) consumed_limb.drop_limb() to_chat(H, "Your [consumed_limb] is drawn back into your body, unable to maintain its shape!") diff --git a/code/modules/mob/living/carbon/human/species_types/pumpkin_man.dm b/code/modules/mob/living/carbon/human/species_types/pumpkin_man.dm index aac7938637606..a64f6f5a4eebb 100644 --- a/code/modules/mob/living/carbon/human/species_types/pumpkin_man.dm +++ b/code/modules/mob/living/carbon/human/species_types/pumpkin_man.dm @@ -9,7 +9,9 @@ attack_sound = 'sound/weapons/punch1.ogg' miss_sound = 'sound/weapons/punchmiss.ogg' changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | ERT_SPAWN + mutant_brain = /obj/item/organ/brain/pumpkin_brain + mutanttongue = /obj/item/organ/tongue/podperson/pumpkin species_chest = /obj/item/bodypart/chest/pumpkin_man species_head = /obj/item/bodypart/head/pumpkin_man @@ -24,6 +26,16 @@ return TRUE return ..() +/datum/species/pod/pumpkin_man/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load) + . = ..() + //They can't speak! + //Register signal for carving + RegisterSignal(C, COMSIG_MOB_ITEM_ATTACKBY, PROC_REF(handle_carving)) + +/datum/species/pod/pumpkin_man/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load) + . = ..() + UnregisterSignal(C, COMSIG_MOB_ITEM_ATTACKBY) + /datum/species/pod/pumpkin_man/get_species_description() return "A rare subspecies of the Podpeople, Pumpkinpeople are gourdy and orange, appearing every halloween." @@ -44,6 +56,32 @@ return to_add +//Handler for face carving! +/datum/species/pod/pumpkin_man/proc/handle_carving(datum/_source, mob/living/_user, obj/item/_item) + //Check if the item is sharp - give owner a random face if applicable + var/mob/living/carbon/human/M = _source + var/obj/item/bodypart/head/pumpkin_man/head = M.get_bodypart(BODY_ZONE_HEAD) + if(_item.is_sharp() && head?.item_flags & ISCARVABLE && _user.a_intent == INTENT_HELP && _user.zone_selected == BODY_ZONE_HEAD) + to_chat(_user, "You begin to carve a face into [_source]...") + //Do after for *flourish* + if(do_after(_user, 3 SECONDS)) + //generate option list + var/list/face_options = list() + for(var/i in 0 to 8) + face_options += list("face[i]" = image('icons/mob/pumpkin_faces.dmi', "face[i]")) + var/face_choosen = show_radial_menu(_user, _source, face_options, require_near = TRUE) + //Reset overlays + M.cut_overlay(head.carved_overlay) //This is needed in addition to the head icon getter's - for some reason? + head.carved_overlay.icon_state = face_choosen + M.update_body_parts_head_only() + to_chat(_user, "You carve a face into [_source].") + //Adjust the tongue + var/obj/item/organ/tongue/podperson/pumpkin/P = M.internal_organs_slot[ORGAN_SLOT_TONGUE] + if(istype(P)) + P?.carved = TRUE + else + to_chat(_user, "You fail to carve a face into [_source]!") + /obj/item/organ/brain/pumpkin_brain name = "pumpkinperson brain" actions_types = list(/datum/action/item_action/organ_action/pumpkin_head_candy) diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm index 06fe781f3ffca..eceba5b0827f1 100644 --- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm @@ -91,12 +91,13 @@ name = "Nightmare" id = "nightmare" burnmod = 1.5 - no_equip = list(ITEM_SLOT_MASK, ITEM_SLOT_OCLOTHING, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_ICLOTHING, ITEM_SLOT_SUITSTORE) + no_equip = list(ITEM_SLOT_OCLOTHING, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_ICLOTHING, ITEM_SLOT_SUITSTORE) species_traits = list(NOBLOOD,NO_UNDERWEAR,NO_DNA_COPY,NOTRANSSTING,NOEYESPRITES,NOFLASH) inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER) mutanteyes = /obj/item/organ/eyes/night_vision/nightmare mutant_organs = list(/obj/item/organ/heart/nightmare) mutant_brain = /obj/item/organ/brain/nightmare + nojumpsuit = 1 var/info_text = "You are a Nightmare. The ability shadow walk allows unlimited, unrestricted movement in the dark while activated. \ Your light eater will destroy any light producing objects you attack, as well as destroy any lights a living creature may be holding. You will automatically dodge gunfire and melee attacks when on a dark tile. If killed, you will eventually revive if left in darkness." diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm index 987bb28e2e0f5..50a4022c48485 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -50,6 +50,7 @@ var/obj/shapeshift_holder/H = locate() in C if(H) H.shape.dust() //make sure we're killing the bat if you are out of blood, if you don't it creates weird situations where the bat is alive but the caster is dusted. + C.investigate_log("has been dusted by a lack of blood (vampire).", INVESTIGATE_DEATHS) C.dust() var/area/A = get_area(C) if(istype(A, /area/chapel)) @@ -173,8 +174,8 @@ to_chat(victim, "[H] is draining your blood!") to_chat(H, "You drain some blood!") playsound(H, 'sound/items/drink.ogg', 30, 1, -2) - victim.blood_volume = CLAMP(victim.blood_volume - drained_blood, 0, BLOOD_VOLUME_MAXIMUM) - H.blood_volume = CLAMP(H.blood_volume + drained_blood, 0, BLOOD_VOLUME_MAXIMUM) + victim.blood_volume = clamp(victim.blood_volume - drained_blood, 0, BLOOD_VOLUME_MAXIMUM) + H.blood_volume = clamp(H.blood_volume + drained_blood, 0, BLOOD_VOLUME_MAXIMUM) if(!victim.blood_volume) to_chat(H, "You finish off [victim]'s blood supply!") diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm index aaeca112ee2f9..42cb19e967d95 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -68,6 +68,7 @@ heal_amt *= 2 C.heal_overall_damage(heal_amt,heal_amt) C.adjustToxLoss(-heal_amt) + C.adjustOrganLoss(ORGAN_SLOT_BRAIN, -heal_amt) if(!C.InCritical() && prob(4)) playsound(C, pick(spooks), 50, TRUE, 10) diff --git a/code/modules/mob/living/carbon/human/suicides.dm b/code/modules/mob/living/carbon/human/suicides.dm index 2670149965bc7..e7d7ff3c75b3c 100644 --- a/code/modules/mob/living/carbon/human/suicides.dm +++ b/code/modules/mob/living/carbon/human/suicides.dm @@ -1,6 +1,7 @@ /mob/living/carbon/human/proc/delayed_suicide() suicide_log() adjustBruteLoss(max(200 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0)) + investigate_log("has died from committing suicide.", INVESTIGATE_DEATHS) death(FALSE) ghostize(FALSE,SENTIENCE_ERASE) // Disallows reentering body and disassociates mind diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index a2697f42d0585..edae3d614415c 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -230,7 +230,7 @@ //TOXINS/PLASMA if(Toxins_partialpressure > safe_tox_max) var/ratio = (breath.get_moles(GAS_PLASMA)/safe_tox_max) * 10 - adjustToxLoss(CLAMP(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE)) + adjustToxLoss(clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE)) throw_alert("too_much_tox", /atom/movable/screen/alert/too_much_tox) else clear_alert("too_much_tox") @@ -301,7 +301,7 @@ var/stam_regen = FALSE if(stam_regen_start_time <= world.time) stam_regen = TRUE - if(stam_paralyzed) + if(HAS_TRAIT_FROM(src, TRAIT_INCAPACITATED, STAMINA)) . |= BODYPART_LIFE_UPDATE_HEALTH //make sure we remove the stamcrit var/bodyparts_with_stam = 0 var/stam_heal_multiplier = 1 @@ -317,7 +317,7 @@ force_heal = max(0, total_stamina_loss - 120) / max(bodyparts_with_stam, 1) //Increase damage the more stam damage //Incraesed stamina healing when above 50 stamloss, up to 2x healing rate when at 100 stamloss. - stam_heal_multiplier = CLAMP(total_stamina_loss / 50, 1, 2) + stam_heal_multiplier = clamp(total_stamina_loss / 50, 1, 2) //Heal bodypart stamina damage for(var/obj/item/bodypart/BP as() in bodyparts) if(BP.needs_processing) diff --git a/code/modules/mob/living/carbon/monkey/monkey_defense.dm b/code/modules/mob/living/carbon/monkey/monkey_defense.dm index c72bc3dcd6547..1dd266a6ebb7b 100644 --- a/code/modules/mob/living/carbon/monkey/monkey_defense.dm +++ b/code/modules/mob/living/carbon/monkey/monkey_defense.dm @@ -48,7 +48,7 @@ apply_damage(damage, BRUTE, affecting) log_combat(M, src, "attacked") if("disarm") - if(!IsUnconscious()) + if(stat < UNCONSCIOUS) M.do_attack_animation(src, ATTACK_EFFECT_DISARM) Knockdown(40) playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) diff --git a/code/modules/mob/living/carbon/status_procs.dm b/code/modules/mob/living/carbon/status_procs.dm index ed6f9e48d3f4f..77d834ff7d06c 100644 --- a/code/modules/mob/living/carbon/status_procs.dm +++ b/code/modules/mob/living/carbon/status_procs.dm @@ -4,18 +4,18 @@ /mob/living/carbon/IsParalyzed(include_stamcrit = TRUE) - return ..() || (include_stamcrit && stam_paralyzed) + return ..() || (include_stamcrit && HAS_TRAIT_FROM(src, TRAIT_INCAPACITATED, STAMINA)) /mob/living/carbon/proc/enter_stamcrit() if(!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)) return if(absorb_stun(0)) //continuous effect, so we don't want it to increment the stuns absorbed. return - if(!IsParalyzed()) - to_chat(src, "You're too exhausted to keep going.") + to_chat(src, "You're too exhausted to keep going...") stam_regen_start_time = world.time + STAMINA_CRIT_TIME - stam_paralyzed = TRUE ADD_TRAIT(src, TRAIT_INCAPACITATED, STAMINA) + ADD_TRAIT(src, TRAIT_IMMOBILIZED, STAMINA) + //ADD_TRAIT(src, TRAIT_FLOORED, STAMINA) update_mobility() /mob/living/carbon/adjust_drugginess(amount) @@ -41,10 +41,10 @@ clear_alert("high") /mob/living/carbon/adjust_disgust(amount) - disgust = CLAMP(disgust+amount, 0, DISGUST_LEVEL_MAXEDOUT) + disgust = clamp(disgust+amount, 0, DISGUST_LEVEL_MAXEDOUT) /mob/living/carbon/set_disgust(amount) - disgust = CLAMP(amount, 0, DISGUST_LEVEL_MAXEDOUT) + disgust = clamp(amount, 0, DISGUST_LEVEL_MAXEDOUT) ////////////////////////////////////////TRAUMAS///////////////////////////////////////// diff --git a/code/modules/mob/living/carbon/update_icons.dm b/code/modules/mob/living/carbon/update_icons.dm index f17b256005c03..4c8fa62f3af7e 100644 --- a/code/modules/mob/living/carbon/update_icons.dm +++ b/code/modules/mob/living/carbon/update_icons.dm @@ -95,7 +95,7 @@ overlays_standing[DAMAGE_LAYER] = damage_overlay for(var/obj/item/bodypart/BP as() in bodyparts) - if(BP.dmg_overlay_type) + if(BP.dmg_overlay_type && !BP.is_husked) if(BP.brutestate) damage_overlay.add_overlay("[BP.dmg_overlay_type]_[BP.body_zone]_[BP.brutestate]0") //we're adding icon_states of the base image as overlays if(BP.burnstate) diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index e1cfb5f5f5e4e..33b6207fb00a7 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -149,7 +149,7 @@ /mob/living/proc/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_status) if(!forced && (status_flags & GODMODE)) return FALSE - bruteloss = CLAMP((bruteloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) + bruteloss = clamp((bruteloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) if(updating_health) updatehealth() return amount @@ -159,19 +159,19 @@ /mob/living/proc/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE) if(!forced && (status_flags & GODMODE)) - return FALSE - oxyloss = CLAMP((oxyloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) + return + . = oxyloss + oxyloss = clamp((oxyloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) if(updating_health) updatehealth() - return amount /mob/living/proc/setOxyLoss(amount, updating_health = TRUE, forced = FALSE) - if(status_flags & GODMODE) - return 0 + if(!forced && status_flags & GODMODE) + return + . = oxyloss oxyloss = amount if(updating_health) updatehealth() - return amount /mob/living/proc/getToxLoss() return toxloss @@ -179,7 +179,7 @@ /mob/living/proc/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE) if(!forced && (status_flags & GODMODE)) return FALSE - toxloss = CLAMP((toxloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) + toxloss = clamp((toxloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) if(updating_health) updatehealth() return amount @@ -198,7 +198,7 @@ /mob/living/proc/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE) if(!forced && (status_flags & GODMODE)) return FALSE - fireloss = CLAMP((fireloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) + fireloss = clamp((fireloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) if(updating_health) updatehealth() return amount @@ -209,7 +209,7 @@ /mob/living/proc/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE) if(!forced && ((status_flags & GODMODE) || HAS_TRAIT(src, TRAIT_NOCLONELOSS))) return FALSE - cloneloss = CLAMP((cloneloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) + cloneloss = clamp((cloneloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) if(updating_health) updatehealth() return amount diff --git a/code/modules/mob/living/init_signals.dm b/code/modules/mob/living/init_signals.dm new file mode 100644 index 0000000000000..0d4013b78790e --- /dev/null +++ b/code/modules/mob/living/init_signals.dm @@ -0,0 +1,27 @@ +///Called on /mob/living/Initialize(), for the mob to register to relevant signals. +/mob/living/proc/register_init_signals() + RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_KNOCKEDOUT), PROC_REF(on_knockedout_trait_gain)) + RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_KNOCKEDOUT), PROC_REF(on_knockedout_trait_loss)) + + RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_DEATHCOMA), PROC_REF(on_deathcoma_trait_gain)) + RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_DEATHCOMA), PROC_REF(on_deathcoma_trait_loss)) + + +///Called when TRAIT_KNOCKEDOUT is added to the mob. +/mob/living/proc/on_knockedout_trait_gain(datum/source) + if(stat < UNCONSCIOUS) + set_stat(UNCONSCIOUS) + +///Called when TRAIT_KNOCKEDOUT is removed from the mob. +/mob/living/proc/on_knockedout_trait_loss(datum/source) + if(stat < DEAD) + update_stat() + + +///Called when TRAIT_DEATHCOMA is added to the mob. +/mob/living/proc/on_deathcoma_trait_gain(datum/source) + ADD_TRAIT(src, TRAIT_KNOCKEDOUT, TRAIT_DEATHCOMA) + +///Called when TRAIT_DEATHCOMA is removed from the mob. +/mob/living/proc/on_deathcoma_trait_loss(datum/source) + REMOVE_TRAIT(src, TRAIT_KNOCKEDOUT, TRAIT_DEATHCOMA) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index b5c5e511ad380..9389fd41ff0b8 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -8,6 +8,7 @@ /mob/living/Initialize(mapload) . = ..() + register_init_signals() if(unique_name) name = "[name] ([rand(1, 1000)])" real_name = name @@ -288,7 +289,7 @@ AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once. pulling = AM - AM.pulledby = src + AM.set_pulledby(src) SEND_SIGNAL(src, COMSIG_LIVING_START_PULL, AM, state, force) @@ -403,8 +404,6 @@ /mob/living/pointed(atom/A as mob|obj|turf in view()) if(incapacitated()) return FALSE - if(HAS_TRAIT(src, TRAIT_DEATHCOMA)) - return FALSE if(!..()) return FALSE visible_message("[src] points at [A].", "You point at [A].") @@ -422,6 +421,7 @@ if (src.client) client.give_award(/datum/award/achievement/misc/succumb, client.mob) + investigate_log("has succumbed to death.", INVESTIGATE_DEATHS) death() /mob/living/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, ignore_stasis = FALSE) @@ -496,19 +496,25 @@ else to_chat(src, "You fail to get up.") +///Proc to hook behavior to the change of value in the resting variable. /mob/living/proc/set_resting(rest, silent = TRUE) + if(rest == resting) + return if(!silent) if(rest) to_chat(src, "You are now resting.") else to_chat(src, "You get up.") + . = rest resting = rest update_resting() + /mob/living/proc/update_resting() update_rest_hud_icon() update_mobility() + //Recursive function to find everything a mob is holding. Really shitty proc tbh. /mob/living/get_contents() var/list/ret = list() @@ -538,10 +544,15 @@ /mob/living/is_drawable(mob/user, allowmobs = TRUE) return (allowmobs && reagents && can_inject(user)) +///Sets the current mob's health value. Do not call directly if you don't know what you are doing, use the damage procs, instead. +/mob/living/proc/set_health(new_value) + . = health + health = new_value + /mob/living/proc/updatehealth() if(status_flags & GODMODE) return - health = maxHealth - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss() + set_health(maxHealth - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss()) staminaloss = getStaminaLoss() update_stat() med_hud_set_health() @@ -1122,7 +1133,7 @@ update_fire() /mob/living/proc/adjust_fire_stacks(add_fire_stacks) //Adjusting the amount of fire_stacks we have on person - fire_stacks = CLAMP(fire_stacks + add_fire_stacks, -20, 20) + fire_stacks = clamp(fire_stacks + add_fire_stacks, -20, 20) if(on_fire && fire_stacks <= 0) ExtinguishMob() @@ -1170,21 +1181,19 @@ /mob/living/proc/update_mobility() var/stat_softcrit = stat == SOFT_CRIT var/stat_conscious = (stat == CONSCIOUS) || stat_softcrit - var/conscious = !IsUnconscious() && stat_conscious && !HAS_TRAIT(src, TRAIT_DEATHCOMA) var/chokehold = pulledby && pulledby.grab_state >= GRAB_NECK var/restrained = restrained() var/has_legs = get_num_legs() var/has_arms = get_num_arms() var/paralyzed = IsParalyzed() - var/stun = IsStun() var/knockdown = IsKnockdown() var/ignore_legs = get_leg_ignore() - var/canmove = !IsImmobilized() && !stun && conscious && !paralyzed && !buckled && (!stat_softcrit || !pulledby) && !chokehold && !IsFrozen() && !IS_IN_STASIS(src) && (has_arms || ignore_legs || has_legs) + var/canmove = !HAS_TRAIT(src, TRAIT_IMMOBILIZED) && (has_arms || ignore_legs || has_legs) if(canmove) mobility_flags |= MOBILITY_MOVE else mobility_flags &= ~MOBILITY_MOVE - var/canstand_involuntary = conscious && !stat_softcrit && !knockdown && !chokehold && !paralyzed && (ignore_legs || has_legs) && !(buckled && buckled.buckle_lying) + var/canstand_involuntary = stat_conscious && !stat_softcrit && !knockdown && !chokehold && !paralyzed && (ignore_legs || has_legs) && !(buckled && buckled.buckle_lying) var/canstand = canstand_involuntary && !resting if(buckled && buckled.buckle_lying != -1) @@ -1211,7 +1220,7 @@ if(stat == UNCONSCIOUS) drop_all_held_items() - var/canitem = !paralyzed && !stun && conscious && !chokehold && !restrained && has_arms + var/canitem = !paralyzed && !IsStun() && stat_conscious && !chokehold && !restrained && has_arms if(canitem) mobility_flags |= (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_STORAGE) else @@ -1280,6 +1289,58 @@ reset_perspective() update_mobility() //if the mob was asleep inside a container and then got forceMoved out we need to make them fall. +/mob/living/set_stat(new_stat) + . = ..() + if(isnull(.)) + return + switch(.) //Previous stat. + if(CONSCIOUS) + if(stat >= UNCONSCIOUS) + ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) + if(SOFT_CRIT) + if(stat >= UNCONSCIOUS) + ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) //adding trait sources should come before removing to avoid unnecessary updates + if(pulledby) + REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, PULLED_WHILE_SOFTCRIT_TRAIT) + if(UNCONSCIOUS) + cure_blind(UNCONSCIOUS_BLIND) + switch(stat) //Current stat. + if(CONSCIOUS) + if(. >= UNCONSCIOUS) + REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) + if(SOFT_CRIT) + if(pulledby) + ADD_TRAIT(src, TRAIT_IMMOBILIZED, PULLED_WHILE_SOFTCRIT_TRAIT) //adding trait sources should come before removing to avoid unnecessary updates + if(. >= UNCONSCIOUS) + REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) + if(UNCONSCIOUS) + become_blind(UNCONSCIOUS_BLIND) + +///Reports the event of the change in value of the buckled variable. +/mob/living/proc/set_buckled(new_buckled) + if(new_buckled == buckled) + return + SEND_SIGNAL(src, COMSIG_LIVING_SET_BUCKLED, new_buckled) + . = buckled + buckled = new_buckled + if(buckled) + if(!.) + if(!HAS_TRAIT(buckled, TRAIT_NO_IMMOBILIZE)) //check if the object being buckled to that would normally immobilize has the NO_Immobilize trait, i.e. Wheelchairs. People buckled to wheelchairs obviously have more free movement that those buckled to stasis beds + ADD_TRAIT(src, TRAIT_IMMOBILIZED, BUCKLED_TRAIT) + else if(.) + REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, BUCKLED_TRAIT) + + +/mob/living/set_pulledby(new_pulledby) + . = ..() + if(. == FALSE) //null is a valid value here, we only want to return if FALSE is explicitly passed. + return + if(pulledby) + if(!. && stat == SOFT_CRIT) + ADD_TRAIT(src, TRAIT_IMMOBILIZED, PULLED_WHILE_SOFTCRIT_TRAIT) + else if(. && stat == SOFT_CRIT) + REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, PULLED_WHILE_SOFTCRIT_TRAIT) + /mob/living/proc/update_z(new_z) // 1+ to register, null to unregister if (registered_z != new_z) if (registered_z) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index bfc9b490d2a8e..14eb83aed3f3a 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -79,9 +79,9 @@ /obj/item/proc/get_volume_by_throwforce_and_or_w_class() if(throwforce && w_class) - return CLAMP((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100 + return clamp((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100 else if(w_class) - return CLAMP(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100 + return clamp(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100 else return 0 @@ -404,6 +404,7 @@ investigate_log("([key_name(src)]) has been consumed by the singularity.", INVESTIGATE_ENGINES) //Oh that's where the clown ended up! + investigate_log("has been gibbed by the singularity.", INVESTIGATE_DEATHS) gib() return(gain) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index dc4caba554f16..ea23fa21a1f89 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -23,6 +23,8 @@ var/cloneloss = 0 //Damage caused by being cloned or ejected from the cloner early. slimes also deal cloneloss damage to victims var/staminaloss = 0 //Stamina damage, or exhaustion. You recover it slowly naturally, and are knocked down if it gets too high. Holodeck and hallucinations deal this. var/crit_threshold = HEALTH_THRESHOLD_CRIT // when the mob goes from "normal" to crit + ///When the mob enters hard critical state and is fully incapacitated. + var/hardcrit_threshold = HEALTH_THRESHOLD_FULLCRIT var/mobility_flags = MOBILITY_FLAGS_DEFAULT diff --git a/code/modules/mob/living/silicon/ai/ai_defense.dm b/code/modules/mob/living/silicon/ai/ai_defense.dm index c5cbfb4d37c55..bfbd22526a0ac 100644 --- a/code/modules/mob/living/silicon/ai/ai_defense.dm +++ b/code/modules/mob/living/silicon/ai/ai_defense.dm @@ -35,13 +35,14 @@ /mob/living/silicon/ai/ex_act(severity, target) switch(severity) - if(1) + if(EXPLODE_DEVASTATE) + investigate_log("has been gibbed by an explosion.", INVESTIGATE_DEATHS) gib() - if(2) + if(EXPLODE_HEAVY) if (stat != DEAD) adjustBruteLoss(60) adjustFireLoss(60) - if(3) + if(EXPLODE_LIGHT) if (stat != DEAD) adjustBruteLoss(30) diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 21fbb6684b727..f7406543fa794 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -63,7 +63,7 @@ /mob/living/silicon/ai/updatehealth() if(status_flags & GODMODE) return - health = maxHealth - getOxyLoss() - getToxLoss() - getBruteLoss() - getFireLoss() + set_health(maxHealth - getOxyLoss() - getToxLoss() - getBruteLoss() - getFireLoss()) update_stat() diag_hud_set_health() disconnect_shell() diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 569d1a1d3de86..0f9a1bc893bb7 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -341,12 +341,12 @@ /mob/living/silicon/pai/updatehealth() if(status_flags & GODMODE) return - health = maxHealth - getBruteLoss() - getFireLoss() + set_health(maxHealth - getBruteLoss() - getFireLoss()) update_stat() SEND_SIGNAL(src, COMSIG_LIVING_UPDATE_HEALTH) /mob/living/silicon/pai/process(delta_time) - emitterhealth = CLAMP((emitterhealth + (emitterregen * delta_time)), -50, emittermaxhealth) + emitterhealth = clamp((emitterhealth + (emitterregen * delta_time)), -50, emittermaxhealth) /mob/living/silicon/pai/can_interact_with(atom/A) if(A == signaler) // Bypass for signaler diff --git a/code/modules/mob/living/silicon/pai/pai_defense.dm b/code/modules/mob/living/silicon/pai/pai_defense.dm index 67134d957c09c..fe5594d050ff2 100644 --- a/code/modules/mob/living/silicon/pai/pai_defense.dm +++ b/code/modules/mob/living/silicon/pai/pai_defense.dm @@ -62,7 +62,7 @@ return FALSE //No we're not flammable /mob/living/silicon/pai/proc/take_holo_damage(amount) - emitterhealth = CLAMP((emitterhealth - amount), -50, emittermaxhealth) + emitterhealth = clamp((emitterhealth - amount), -50, emittermaxhealth) if(emitterhealth < 0) fold_in(force = TRUE) to_chat(src, "The impact degrades your holochassis!") diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index c0b9560139a22..ae385075567dd 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -99,7 +99,7 @@ cut_overlay(fire_overlay) /mob/living/silicon/robot/update_mobility() - if(stat || buckled || lockcharge || incapacitated()) + if(HAS_TRAIT(src, TRAIT_IMMOBILIZED)) mobility_flags &= ~MOBILITY_MOVE else mobility_flags = MOBILITY_FLAGS_DEFAULT diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index a95e9a8a7b0f9..9f38adbc636d0 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -120,7 +120,7 @@ spark_system.attach(src) wires = new /datum/wires/robot(src) - AddComponent(/datum/component/empprotection, EMP_PROTECT_WIRES) + AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES) RegisterSignal(src, COMSIG_PROCESS_BORGCHARGER_OCCUPANT, PROC_REF(charge)) robot_modules_background = new() @@ -617,7 +617,7 @@ cut_overlays() SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) icon_state = module.cyborg_base_icon - if(stat != DEAD && !(IsUnconscious() || IsStun() || IsParalyzed() || low_power_mode)) //Not dead, not stunned. + if(stat != DEAD && !(IsUnconscious() || low_power_mode)) //Not dead, not stunned. if(!eye_lights) eye_lights = new() if(last_flashed && last_flashed + 30 SECONDS >= world.time) //We want to make sure last_flashed isn't zero because otherwise roundstart borgs blink for 30 seconds @@ -658,6 +658,7 @@ explosion(src.loc,1,2,4,flame_range = 2) else explosion(src.loc,-1,0,2) + investigate_log("has self-destructed.", INVESTIGATE_DEATHS) gib() /mob/living/silicon/robot/proc/UnlinkSelf() @@ -665,8 +666,7 @@ connected_ai.connected_robots -= src src.connected_ai = null lawupdate = FALSE - lockcharge = FALSE - mobility_flags |= MOBILITY_FLAGS_DEFAULT + set_lockcharge(FALSE) scrambledcodes = TRUE_DEVIL //Disconnect it's camera so it's not so easily tracked. if(!QDELETED(builtInCamera)) @@ -697,10 +697,23 @@ throw_alert("locked", /atom/movable/screen/alert/locked) else clear_alert("locked") - lockcharge = state + set_lockcharge(state) + +///Reports the event of the change in value of the lockcharge variable. +/mob/living/silicon/robot/proc/set_lockcharge(new_lockcharge) + if(new_lockcharge == lockcharge) + return + . = lockcharge + lockcharge = new_lockcharge + if(lockcharge) + if(!.) + ADD_TRAIT(src, TRAIT_IMMOBILIZED, LOCKED_BORG_TRAIT) + else if(.) + REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, LOCKED_BORG_TRAIT) update_mobility() logevent("System lockdown [lockcharge?"triggered":"released"].") + /mob/living/silicon/robot/proc/SetEmagged(new_state) emagged = new_state module.rebuild_modules() @@ -1013,16 +1026,11 @@ death() toggle_headlamp(1) return - if(IsUnconscious() || IsStun() || IsKnockdown() || IsParalyzed() || getOxyLoss() > maxHealth*0.5) - if(stat == CONSCIOUS) - set_stat(UNCONSCIOUS) - become_blind(UNCONSCIOUS_BLIND) - update_mobility() + if(HAS_TRAIT(src, TRAIT_KNOCKEDOUT) || IsStun() || IsKnockdown() || IsParalyzed()) + set_stat(UNCONSCIOUS) else - if(stat == UNCONSCIOUS) - set_stat(CONSCIOUS) - cure_blind(UNCONSCIOUS_BLIND) - update_mobility() + set_stat(CONSCIOUS) + update_mobility() diag_hud_set_status() diag_hud_set_health() diag_hud_set_aishell() diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index 4c89d6dd5d85c..4327ac64e5c91 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -175,19 +175,20 @@ if(stat != DEAD) adjustBruteLoss(30) else + investigate_log("has been gibbed a blob.", INVESTIGATE_DEATHS) gib() return TRUE /mob/living/silicon/robot/ex_act(severity, target) switch(severity) - if(1) + if(EXPLODE_DEVASTATE) gib() return - if(2) + if(EXPLODE_HEAVY) if (stat != DEAD) adjustBruteLoss(60) adjustFireLoss(60) - if(3) + if(EXPLODE_LIGHT) if (stat != DEAD) adjustBruteLoss(30) @@ -196,3 +197,24 @@ updatehealth() if(prob(75) && Proj.damage > 0) spark_system.start() + +/mob/living/silicon/robot/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE) + . = ..() + if(isnull(.)) + return + if(. <= (maxHealth * 0.5)) + if(getOxyLoss() > (maxHealth * 0.5)) + ADD_TRAIT(src, TRAIT_KNOCKEDOUT, OXYLOSS_TRAIT) + else if(getOxyLoss() <= (maxHealth * 0.5)) + REMOVE_TRAIT(src, TRAIT_KNOCKEDOUT, OXYLOSS_TRAIT) + + +/mob/living/silicon/robot/setOxyLoss(amount, updating_health = TRUE, forced = FALSE) + . = ..() + if(isnull(.)) + return + if(. <= (maxHealth * 0.5)) + if(getOxyLoss() > (maxHealth * 0.5)) + ADD_TRAIT(src, TRAIT_KNOCKEDOUT, OXYLOSS_TRAIT) + else if(getOxyLoss() <= (maxHealth * 0.5)) + REMOVE_TRAIT(src, TRAIT_KNOCKEDOUT, OXYLOSS_TRAIT) diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index 67a7ea5dbff75..3f8b456cfd78e 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -153,6 +153,7 @@ if(prob(bomb_armor)) adjustBruteLoss(500) else + investigate_log("has been gibbed by an explosion.", INVESTIGATE_DEATHS) gib() return if (EXPLODE_HEAVY) diff --git a/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm b/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm index 33266d519e6df..671f5bf797887 100644 --- a/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm +++ b/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm @@ -28,7 +28,7 @@ /mob/living/simple_animal/bot/secbot/grievous/nullcrate/ComponentInitialize() . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_CONTENTS | EMP_PROTECT_WIRES) + AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_CONTENTS | EMP_PROTECT_WIRES) /mob/living/simple_animal/bot/secbot/grievous/bullet_act(obj/projectile/P) visible_message("[src] deflects [P] with its energy swords!") diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 1d3fe678c2d54..458afe1cceac6 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -1075,7 +1075,7 @@ Pass a positive integer as an argument to override a bot's default speed. else if(paicard.pai) paicard.pai.key = key else - ghostize(0) // The pAI card that just got ejected was dead. + ghostize(FALSE) // The pAI card that just got ejected was dead. key = null paicard.forceMove(loc) if(user) diff --git a/code/modules/mob/living/simple_animal/damage_procs.dm b/code/modules/mob/living/simple_animal/damage_procs.dm index eda19be7af450..ee9fa2526bc5f 100644 --- a/code/modules/mob/living/simple_animal/damage_procs.dm +++ b/code/modules/mob/living/simple_animal/damage_procs.dm @@ -2,7 +2,7 @@ /mob/living/simple_animal/proc/adjustHealth(amount, updating_health = TRUE, forced = FALSE) if(!forced && (status_flags & GODMODE)) return FALSE - bruteloss = round(CLAMP(bruteloss + amount, 0, maxHealth),DAMAGE_PRECISION) + bruteloss = round(clamp(bruteloss + amount, 0, maxHealth),DAMAGE_PRECISION) if(updating_health) updatehealth() return amount diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index e56c81f0661b9..d198c210daf20 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -512,6 +512,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( playsound(src, 'sound/magic/demon_dies.ogg', 75, TRUE) var/mob/living/simple_animal/pet/dog/corgi/narsie/N = new(loc) N.setDir(dir) + investigate_log("has been gibbed by Nar'Sie.", INVESTIGATE_DEATHS) gib() /mob/living/simple_animal/pet/dog/corgi/narsie @@ -540,6 +541,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( P.mind.hasSoul = FALSE //Nars-Ian ate your soul; you don't have one anymore else visible_message("... Aw, someone beat me to this one.") + P.investigate_log("has been gibbed by [src].", INVESTIGATE_DEATHS) P.gib() /mob/living/simple_animal/pet/dog/corgi/narsie/update_corgi_fluff() diff --git a/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm b/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm index 41b4c2687f7c6..d03eab4ca56f9 100644 --- a/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm +++ b/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm @@ -172,7 +172,7 @@ continue else var/healthdiff = 10-round(H.health/10) - Targets[H] = CLAMP(healthdiff,1,12) + Targets[H] = clamp(healthdiff,1,12) if(!Targets.len)//sanity check return return pick_weight(Targets)//Pick the remaining targets (if any) at random diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index da9b4466e37bf..8771d9ae17c1e 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -185,6 +185,7 @@ if(isliving(cocoon_target)) var/mob/living/L = cocoon_target if(L.stat != DEAD) + L.investigate_log("has been killed by being wrapped in a cocoon.", INVESTIGATE_DEATHS) L.death() //If it's not already dead, we want it dead regardless of nourishment if(L.blood_volume >= BLOOD_VOLUME_BAD && !isipc(L)) //IPCs and drained mobs are not nourishing. L.blood_volume = 0 //Remove all fluids from this mob so they are no longer nourishing. diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm index 604be9d15a7cb..233dcdd9bc358 100644 --- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm +++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm @@ -56,10 +56,7 @@ var/time /obj/item/organ/body_egg/changeling_egg/egg_process() - // Changeling eggs grow in dead people, but not people in stasis - var/mob/living/L = owner - if(IS_IN_STASIS(L)) - return + // Changeling eggs grow in dead people time++ if(time >= EGG_INCUBATION_TIME) Pop() @@ -84,6 +81,7 @@ C.purchasedpowers += hf C.regain_powers() M.key = origin.key + owner.investigate_log("has been gibbed by a changeling egg burst.", INVESTIGATE_DEATHS) owner.gib() #undef EGG_INCUBATION_TIME diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm index 104fb9cfaf1ec..dfa67b826d1c8 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm @@ -159,6 +159,7 @@ Difficulty: Medium adjustHealth(-L.maxHealth) else adjustHealth(-(L.maxHealth * 0.5)) + L.investigate_log("has been gibbed by [src].", INVESTIGATE_DEATHS) L.gib() return TRUE changeNext_move(CLICK_CD_MELEE) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index a36d021a2df01..63911a0bdc5e8 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -106,8 +106,8 @@ Difficulty: Hard if(charging) return - anger_modifier = CLAMP(((maxHealth - health)/30),0,20) - enrage_time = initial(enrage_time) * CLAMP(anger_modifier / 20, 0.5, 1) + anger_modifier = clamp(((maxHealth - health)/30),0,20) + enrage_time = initial(enrage_time) * clamp(anger_modifier / 20, 0.5, 1) ranged_cooldown = world.time + 50 if(client) @@ -560,7 +560,7 @@ Difficulty: Hard /mob/living/simple_animal/hostile/megafauna/bubblegum/proc/slaughterlings() visible_message("[src] summons a shoal of slaughterlings!") - var/max_amount = CLAMP(anger_modifier / 4, 3, 5) + var/max_amount = clamp(anger_modifier / 4, 3, 5) for(var/H in get_pools(get_turf(src), 1)) if(!max_amount) break 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 5b83b06d32576..3c15e33bd7259 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -86,7 +86,7 @@ Difficulty: Very Hard /mob/living/simple_animal/hostile/megafauna/colossus/OpenFire() ranged_cooldown = world.time + 600 //prevents abilities from being spammed by AttackingTarget() while an attack is already underway. - anger_modifier = CLAMP(((maxHealth - health)/20),0,20) + anger_modifier = clamp(((maxHealth - health)/20),0,20) if(client) //Player controlled handled a bit differently. switch(chosen_attack) @@ -811,6 +811,7 @@ GLOBAL_DATUM(blackbox, /obj/machinery/smartfridge/black_box) if(holder_animal) if(holder_animal.stat == DEAD) dump_contents() + holder_animal.investigate_log("has been gibbed by [src].", INVESTIGATE_DEATHS) holder_animal.gib() return @@ -832,7 +833,7 @@ GLOBAL_DATUM(blackbox, /obj/machinery/smartfridge/black_box) holder_animal.mind.AddSpell(P) holder_animal.remove_verb(/mob/living/verb/pulled) -/obj/structure/closet/stasis/dump_contents(var/kill = 1) +/obj/structure/closet/stasis/dump_contents(kill = TRUE) STOP_PROCESSING(SSobj, src) for(var/mob/living/L in src) REMOVE_TRAIT(L, TRAIT_MUTE, STASIS_MUTE) @@ -842,7 +843,8 @@ GLOBAL_DATUM(blackbox, /obj/machinery/smartfridge/black_box) holder_animal.mind.transfer_to(L) L.mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/exit_possession) if(kill || !isanimal(loc)) - L.death(0) + L.investigate_log("has died from [src].", INVESTIGATE_DEATHS) + L.death(FALSE) ..() /obj/structure/closet/stasis/emp_act() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm index 06263dcb17e68..6eccca975f992 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -96,7 +96,7 @@ Difficulty: Medium if(swooping) return - anger_modifier = CLAMP(((maxHealth - health)/25),0,20) + anger_modifier = clamp(((maxHealth - health)/25),0,20) ranged_cooldown = world.time + ranged_cooldown_time if(client) @@ -353,6 +353,7 @@ Difficulty: Medium for(var/mob/living/L in orange(1, src)) if(L.stat) visible_message("[src] slams down on [L], crushing [L.p_them()]!") + L.investigate_log("has been gibbed by lava swoop.", INVESTIGATE_DEATHS) L.gib() else L.adjustBruteLoss(75) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm index 435716e38ab0e..b021a5321b190 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -473,7 +473,7 @@ Difficulty: Hard /mob/living/simple_animal/hostile/megafauna/hierophant/proc/calculate_rage() //how angry we are overall did_reset = FALSE //oh hey we're doing SOMETHING, clearly we might need to heal if we recall - anger_modifier = CLAMP(((maxHealth - health) / 21),0,50) + anger_modifier = clamp(((maxHealth - health) / 21),0,50) burst_range = initial(burst_range) + round(anger_modifier * 0.08) beam_range = initial(beam_range) + round(anger_modifier * 0.12) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm index 4bc2a4358ae2f..00688edf2d482 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -126,6 +126,7 @@ for(var/obj/item/W in L) if(!L.dropItemToGround(W)) qdel(W) + L.investigate_log("has been devoured by [src].", INVESTIGATE_DEATHS) L.gib() return TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm index 36223308241ad..44af7d8b8b987 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm @@ -51,11 +51,12 @@ /mob/living/simple_animal/hostile/asteroid/basilisk/ex_act(severity, target) switch(severity) - if(1) + if(EXPLODE_DEVASTATE) + investigate_log("has been gibbed by an explosion.", INVESTIGATE_DEATHS) gib() - if(2) + if(EXPLODE_HEAVY) adjustBruteLoss(140) - if(3) + if(EXPLODE_LIGHT) adjustBruteLoss(110) //Watcher diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm index ac1ec44739b04..0f3efa611b6bb 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm @@ -10,9 +10,9 @@ icon_gib = "syndicate_gib" mob_biotypes = list(MOB_ORGANIC, MOB_BEAST) mouse_opacity = MOUSE_OPACITY_ICON - move_to_delay = 40 + move_to_delay = 2 SECONDS ranged = 1 - ranged_cooldown_time = 120 + ranged_cooldown_time = 80 friendly = "wails at" speak_emote = list("bellows") vision_range = 4 @@ -187,7 +187,8 @@ if((!QDELETED(spawner) && spawner.faction_check_mob(L)) || L.stat == DEAD) continue visible_message("[src] grabs hold of [L]!") - L.Stun(100) + L.Stun(1 SECONDS) + L.Knockdown(6 SECONDS) L.adjustBruteLoss(rand(10,15)) latched = TRUE if(!latched) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm index 08f3ea7678c37..dbc912eda4a84 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm @@ -189,6 +189,7 @@ else L = new(H.loc) visible_message("[L] staggers to [L.p_their()] feet!") + H.investigate_log("has been killed by hivelord infestation.", INVESTIGATE_DEATHS) H.death() H.adjustBruteLoss(1000) L.stored_mob = H diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 2d8af223958c7..b4ed7b8f686ba 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -141,14 +141,14 @@ ..() /mob/living/simple_animal/updatehealth() - ..() - health = CLAMP(health, 0, maxHealth) + . = ..() + health = clamp(health, 0, maxHealth) update_health_hud() /mob/living/simple_animal/update_health_hud() if(!hud_used) return - var/severity = 5 - CLAMP(FLOOR((health / maxHealth) * 5, 1), 0, 5) + var/severity = 5 - clamp(FLOOR((health / maxHealth) * 5, 1), 0, 5) if(severity > 0) overlay_fullscreen("brute", /atom/movable/screen/fullscreen/brute, severity) else @@ -462,8 +462,15 @@ else ..() +/mob/living/simple_animal/update_resting() + if(resting) + ADD_TRAIT(src, TRAIT_IMMOBILIZED, RESTING_TRAIT) + else + REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, RESTING_TRAIT) + return ..() + /mob/living/simple_animal/update_mobility(value_otherwise = TRUE) - if(IsUnconscious() || IsParalyzed() || IsStun() || IsKnockdown() || stat || resting) + if(HAS_TRAIT_NOT_FROM(src, TRAIT_IMMOBILIZED, BUCKLED_TRAIT)) drop_all_held_items() mobility_flags = NONE else if(buckled || IsImmobilized()) diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index d80246b52f557..e9ff1bebe679f 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -428,7 +428,6 @@ REMOVE_TRAIT(src, TRAIT_DEATHCOMA, source) if(stat != DEAD) tod = null - update_stat() /mob/living/proc/fakedeath(source, silent = FALSE) if(stat == DEAD) @@ -442,7 +441,6 @@ ADD_TRAIT(src, TRAIT_FAKEDEATH, source) ADD_TRAIT(src, TRAIT_DEATHCOMA, source) tod = station_time_timestamp() - update_stat() /mob/living/proc/unignore_slowdown(source) REMOVE_TRAIT(src, TRAIT_IGNORESLOWDOWN, source) diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm index f2ce9e75a0ef8..b5e93b3fe0e0a 100644 --- a/code/modules/mob/living/ventcrawling.dm +++ b/code/modules/mob/living/ventcrawling.dm @@ -35,8 +35,9 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list( if(!vent_found) for(var/obj/machinery/atmospherics/machine in range(1,src)) - if(is_type_in_typecache(machine, GLOB.ventcrawl_machinery)) - vent_found = machine + if(!is_type_in_typecache(machine, GLOB.ventcrawl_machinery)) + continue + vent_found = machine if(!vent_found.can_crawl_through()) vent_found = null diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 20376364bf4e5..01ff49834b284 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -504,7 +504,7 @@ var/mob/dead/observer/C = pick(candidates) to_chat(M, "Your mob has been taken over by a ghost!") message_admins("[key_name_admin(C)] has taken control of ([ADMIN_LOOKUPFLW(M)])") - M.ghostize(0) + M.ghostize(FALSE) M.key = C.key return TRUE else diff --git a/code/modules/mob/mob_stat.dm b/code/modules/mob/mob_stat.dm index 7edaf26220dfe..b1d12dbb86399 100644 --- a/code/modules/mob/mob_stat.dm +++ b/code/modules/mob/mob_stat.dm @@ -1,5 +1,25 @@ +/// How many items per tile until we just completely give up? +#define MAX_ITEMS_TO_READ 500 +/// How many unique entries should we show per-tile before giving up? #define MAX_ICONS_PER_TILE 50 +/// Determine the priority of this item in the stat panel +/// I decided to do it this way to reduce the amount of memory wasted on all atoms. +/// There is a reason for this madness +#define STAT_PANEL_TAG(atom) ishuman(atom) \ + ? "Human" \ + : ismob(atom) \ + ? "Mob" \ + : isitem(atom) \ + ? "Item" \ + : isstructure(atom) \ + ? "Structure" \ + : ismachinery(atom) \ + ? "Machinery" \ + : isturf(atom) \ + ? "Turf" \ + : "Other" + /client var/stat_update_mode = STAT_FAST_UPDATE var/stat_update_time = 0 @@ -73,32 +93,8 @@ // ===== NON CONSTANT TABS (Tab names which can change) ===== // ===== LISTEDS TURFS ===== if(listed_turf && sanitize(listed_turf.name) == selected_tab) - client.stat_update_mode = STAT_MEDIUM_UPDATE - var/list/overrides = list() - for(var/image/I in client.images) - if(I.loc && I.loc.loc == listed_turf && I.override) - overrides += I.loc - tab_data[REF(listed_turf)] = list( - text="[listed_turf.name]", - type=STAT_ATOM - ) - var/sanity = MAX_ICONS_PER_TILE - for(var/atom/A in listed_turf) - if(!A.mouse_opacity) - continue - if(A.invisibility > see_invisible) - continue - if(overrides.len && (A in overrides)) - continue - if(A.IsObscured()) - continue - sanity -- - tab_data[REF(A)] = list( - text="[A.name]", - type=STAT_ATOM - ) - if(sanity < 0) - break + // Check if we can actually see the turf + listed_turf.render_stat_information(client, tab_data) if(mind) tab_data += get_spell_stat_data(mind.spell_list, selected_tab) tab_data += get_spell_stat_data(mob_spell_list, selected_tab) @@ -108,6 +104,81 @@ return list() return tab_data +/turf/proc/render_stat_information(client/client, list/tab_data) + client.stat_update_mode = STAT_MEDIUM_UPDATE + // Display the turf + var/list/overrides = list() + for(var/image/I in client.images) + if(I.loc && I.loc.loc == src && I.override) + overrides[I.loc] = I + tab_data[REF(src)] = list( + text="[name]", + tag = STAT_PANEL_TAG(src), + type=STAT_ATOM + ) + var/max_item_sanity = MAX_ITEMS_TO_READ + var/icon_count_sanity = MAX_ICONS_PER_TILE + var/list/atom_count = list() + var/list/image_overrides = list() + // Caching for A.IsObscured to improve performance, in is faster than dictionary lookups for + // small (and even quite large) lists. + var/list/checked_layers = list() + var/list/obscured_layers = list() + // Find items and group them by both name and count + for (var/atom/A as() in src) + // Too many items read + if(max_item_sanity-- < 0) + break + if(!A.mouse_opacity) + continue + if(A.invisibility > client.mob.see_invisible) + continue + if(A.layer in checked_layers) + if (A.layer in obscured_layers) + continue + else + checked_layers += A.layer + if (A.IsObscured()) + obscured_layers += A.layer + var/atom_type = A.type + var/atom_name = A.name + if(overrides.len && overrides[A]) + var/image/override_image = overrides[A] + atom_name = override_image.name + image_overrides[A] = override_image + var/list/item_group = atom_count["[atom_type][atom_name]"] + if (item_group) + item_group += A + else + atom_count["[A.type][A.name]"] = list(A) + // To many icon types per tile + if (icon_count_sanity-- <= 0) + break + // Display the atoms + for(var/atom_type in atom_count) + var/atom_items = atom_count[atom_type] + var/item_count = length(atom_items) + var/atom/first_atom = atom_items[1] + if (istype(first_atom, /obj/item/stack)) + item_count = 0 + for (var/obj/item/stack/stack_item as() in atom_items) + item_count += stack_item.amount + var/atom_name = first_atom.name + if (image_overrides[first_atom]) + var/image/override_image = image_overrides[first_atom] + atom_name = override_image.name + tab_data[REF(first_atom)] = list( + text = "[atom_name][item_count > 1 ? " (x[item_count])" : ""]", + tag = STAT_PANEL_TAG(first_atom), + type = STAT_ATOM + ) + // Display self + tab_data[REF(client.mob)] = list( + text = client.mob.name, + tag = "You", + type = STAT_ATOM + ) + /mob/proc/get_all_verbs() var/list/all_verbs = new @@ -254,18 +325,33 @@ return switch(button_pressed) if("browsetickets") + if (!client.holder) + return GLOB.ahelp_tickets.BrowseTickets(src) if("browseinterviews") + if (!check_rights(R_ADMIN)) + return GLOB.interviews.BrowseInterviews(src) if("open_interview") + if (!check_rights(R_ADMIN)) + return var/datum/interview/I = GLOB.interviews.interview_by_id(text2num(params["id"])) if (I && client.holder) I.ui_interact(src) if("open_ticket") + if (!client.holder) + return var/ticket_id = text2num(params["id"]) var/datum/help_ticket/AH = GLOB.ahelp_tickets.TicketByID(ticket_id) if(AH && client.holder) AH.ui_interact(src) + if ("claim_ticket") + if (!check_rights(R_ADMIN)) + return + var/ticket_id = text2num(params["id"]) + var/datum/help_ticket/AH = GLOB.ahelp_tickets.TicketByID(ticket_id) + if(AH && client.holder) + AH.Claim() if("atomClick") var/atomRef = params["ref"] var/atom/atom_actual = locate(atomRef) @@ -305,13 +391,19 @@ var/verb_name = params["verb"] winset(client, null, "command=[replacetext(verb_name, " ", "-")]") if("sdql2debug") + if (!check_rights(R_DEBUG)) + return client.debug_variables(GLOB.sdql2_queries) if("sdql2delete") + if (!check_rights(R_DEBUG)) + return var/query_id = params["qid"] var/datum/SDQL2_query/query = sdqlQueryByID(text2num(query_id)) if(query) query.delete_click() if("sdql2toggle") + if (!check_rights(R_DEBUG)) + return var/query_id = params["qid"] var/datum/SDQL2_query/query = sdqlQueryByID(text2num(query_id)) if(query) @@ -378,4 +470,5 @@ var/list/status_data = get_stat(client.selected_stat_tab) client.tgui_panel.set_panel_infomation(status_data) +#undef MAX_ITEMS_TO_READ #undef MAX_ICONS_PER_TILE diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm index 77aead3e44d6b..e1429e4af3e37 100644 --- a/code/modules/mob/status_procs.dm +++ b/code/modules/mob/status_procs.dm @@ -28,7 +28,7 @@ */ /mob/proc/adjust_blindness(amount) var/old_eye_blind = eye_blind - eye_blind += amount + eye_blind = max(eye_blind + amount, 0) if(!old_eye_blind || !eye_blind && !HAS_TRAIT(src, TRAIT_BLIND)) update_blindness() @@ -103,4 +103,4 @@ ///Adjust the body temperature of a mob, with min/max settings /mob/proc/adjust_bodytemperature(amount,min_temp=0,max_temp=INFINITY) if(bodytemperature >= min_temp && bodytemperature <= max_temp) - bodytemperature = CLAMP(bodytemperature + amount,min_temp,max_temp) + bodytemperature = clamp(bodytemperature + amount,min_temp,max_temp) diff --git a/code/modules/modular_computers/computers/machinery/modular_console.dm b/code/modules/modular_computers/computers/machinery/modular_console.dm index b38815fa4ebb4..5d0a751441e5f 100644 --- a/code/modules/modular_computers/computers/machinery/modular_console.dm +++ b/code/modules/modular_computers/computers/machinery/modular_console.dm @@ -3,9 +3,13 @@ desc = "A stationary computer." icon = 'icons/obj/modular_console.dmi' - icon_state = "console" + icon_state = "console-0" + base_icon_state = "console" + smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIRECTIONAL | SMOOTH_BITMASK_SKIP_CORNERS + smoothing_groups = list(SMOOTH_GROUP_COMPUTERS) + canSmoothWith = list(SMOOTH_GROUP_COMPUTERS) icon_state_powered = "console" - icon_state_unpowered = "console-off" + icon_state_unpowered = "console" //These are the same because the base modifies the icon, which messes with smoothing screen_icon_state_menu = "menu" hardware_flag = PROGRAM_CONSOLE density = TRUE @@ -30,6 +34,8 @@ /obj/machinery/modular_computer/console/Initialize(mapload) . = ..() + QUEUE_SMOOTH(src) + QUEUE_SMOOTH_NEIGHBORS(src) var/obj/item/computer_hardware/battery/battery_module = cpu.all_components[MC_CELL] if(battery_module) qdel(battery_module) @@ -53,3 +59,20 @@ if(cpu) cpu.screen_on = 1 update_icon() + +/obj/machinery/modular_computer/console/Destroy() + QUEUE_SMOOTH_NEIGHBORS(src) + . = ..() + +/obj/machinery/modular_computer/console/update_icon() + . = ..() + + var/keyboard = "keyboard" + if ((machine_stat & NOPOWER) || !(cpu?.use_power())) + keyboard = "keyboard_off" + add_overlay(keyboard) + + icon_state = "[icon_state]-[smoothing_junction]" + + if(machine_stat & BROKEN) + add_overlay("broken-[smoothing_junction]") diff --git a/code/modules/modular_computers/file_system/programs/borg_self_monitor.dm b/code/modules/modular_computers/file_system/programs/borg_self_monitor.dm index e988ce3ed8783..dda9a6c99d9ed 100644 --- a/code/modules/modular_computers/file_system/programs/borg_self_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/borg_self_monitor.dm @@ -130,7 +130,7 @@ borgo.toggle_ionpulse() if("lampIntensity") - borgo.lamp_intensity = CLAMP(text2num(params["ref"]), 1, 5) + borgo.lamp_intensity = clamp(text2num(params["ref"]), 1, 5) borgo.toggle_headlamp(FALSE, TRUE) if("selfDestruct") diff --git a/code/modules/paperwork/contract.dm b/code/modules/paperwork/contract.dm index aafc1e3148ef5..9120f2c7a6075 100644 --- a/code/modules/paperwork/contract.dm +++ b/code/modules/paperwork/contract.dm @@ -99,7 +99,7 @@ target = nTarget update_text() -/obj/item/paper/contract/infernal/suicide_act(mob/user) +/obj/item/paper/contract/infernal/suicide_act(mob/living/user) if(signed && (user == target.current) && istype(user, /mob/living/carbon/human/)) var/mob/living/carbon/human/H = user H.say("OH GREAT INFERNO! I DEMAND YOU COLLECT YOUR BOUNTY IMMEDIATELY!", forced = "infernal contract suicide") diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm index de0daed22f05f..f0dd2c4295287 100644 --- a/code/modules/paperwork/handlabeler.dm +++ b/code/modules/paperwork/handlabeler.dm @@ -9,7 +9,7 @@ var/labels_left = 30 var/mode = 0 -/obj/item/hand_labeler/suicide_act(mob/user) +/obj/item/hand_labeler/suicide_act(mob/living/user) user.visible_message("[user] is pointing [src] at [user.p_them()]self. [user.p_theyre(TRUE)] going to label [user.p_them()]self as a suicide!") labels_left = max(labels_left - 1, 0) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index d76e2be4fa24a..07183d755d97d 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -301,9 +301,9 @@ add_fingerprint(usr) update_static_data() -/obj/item/paper/suicide_act(mob/user) +/obj/item/paper/suicide_act(mob/living/user) user.visible_message("[user] scratches a grid on [user.p_their()] wrist with the paper! It looks like [user.p_theyre()] trying to commit sudoku...") - return (BRUTELOSS) + return BRUTELOSS /obj/item/paper/examine(mob/user) . = ..() diff --git a/code/modules/paperwork/paper_cutter.dm b/code/modules/paperwork/paper_cutter.dm index 7a176a6c183d0..48b3fa8f9279a 100644 --- a/code/modules/paperwork/paper_cutter.dm +++ b/code/modules/paperwork/paper_cutter.dm @@ -18,7 +18,7 @@ update_icon() -/obj/item/papercutter/suicide_act(mob/user) +/obj/item/papercutter/suicide_act(mob/living/user) if(storedcutter) user.visible_message("[user] is beheading [user.p_them()]self with [src.name]! It looks like [user.p_theyre()] trying to commit suicide!") if(iscarbon(user)) @@ -27,11 +27,11 @@ if(BP) BP.drop_limb() playsound(loc,pick('sound/misc/desecration-01.ogg','sound/misc/desecration-02.ogg','sound/misc/desecration-01.ogg') ,50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS else user.visible_message("[user] repeatedly bashes [src.name] against [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!") playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS /obj/item/papercutter/update_icon() diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm index 984927bb91f0d..325c26c405cea 100644 --- a/code/modules/paperwork/paperplane.dm +++ b/code/modules/paperwork/paperplane.dm @@ -20,7 +20,7 @@ if(eyes) eyes.applyOrganDamage(rand(6,8)) sleep(10) - return (BRUTELOSS) + return BRUTELOSS /obj/item/origami/paperplane/update_icon() cut_overlays() diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 8afff2d9a863d..57362d7b7e01d 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -30,9 +30,9 @@ var/degrees = 0 var/font = PEN_FONT -/obj/item/pen/suicide_act(mob/user) +/obj/item/pen/suicide_act(mob/living/user) user.visible_message("[user] is scribbling numbers all over [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit sudoku...") - return(BRUTELOSS) + return BRUTELOSS /obj/item/pen/blue desc = "It's a normal blue ink pen." diff --git a/code/modules/paperwork/stamps.dm b/code/modules/paperwork/stamps.dm index e8c97233dbc1d..47b3def2bf615 100644 --- a/code/modules/paperwork/stamps.dm +++ b/code/modules/paperwork/stamps.dm @@ -12,7 +12,7 @@ pressure_resistance = 2 attack_verb = list("stamped") -/obj/item/stamp/suicide_act(mob/user) +/obj/item/stamp/suicide_act(mob/living/user) user.visible_message("[user] stamps 'VOID' on [user.p_their()] forehead, then promptly falls over, dead.") playsound(src, 'sound/items/handling/standard_stamp.ogg', 50, vary = TRUE) return OXYLOSS diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm index f4ac0c3d9b421..3f28aea4d5cfd 100644 --- a/code/modules/photography/camera/camera.dm +++ b/code/modules/photography/camera/camera.dm @@ -65,8 +65,8 @@ /obj/item/camera/proc/adjust_zoom(mob/user) var/desired_x = input(user, "How high do you want the camera to shoot, between [picture_size_x_min] and [picture_size_x_max]?", "Zoom", picture_size_x) as num var/desired_y = input(user, "How wide do you want the camera to shoot, between [picture_size_y_min] and [picture_size_y_max]?", "Zoom", picture_size_y) as num - picture_size_x = min(CLAMP(desired_x, picture_size_x_min, picture_size_x_max), CAMERA_PICTURE_SIZE_HARD_LIMIT) - picture_size_y = min(CLAMP(desired_y, picture_size_y_min, picture_size_y_max), CAMERA_PICTURE_SIZE_HARD_LIMIT) + picture_size_x = min(clamp(desired_x, picture_size_x_min, picture_size_x_max), CAMERA_PICTURE_SIZE_HARD_LIMIT) + picture_size_y = min(clamp(desired_y, picture_size_y_min, picture_size_y_max), CAMERA_PICTURE_SIZE_HARD_LIMIT) /obj/item/camera/AltClick(mob/user) if(!user.canUseTopic(src, BE_CLOSE)) @@ -172,8 +172,8 @@ if(!isturf(target_turf)) blending = FALSE return FALSE - size_x = CLAMP(size_x, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT) - size_y = CLAMP(size_y, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT) + size_x = clamp(size_x, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT) + size_y = clamp(size_y, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT) var/list/desc = list("This is a photo of an area of [(2*size_x)+1] meters by [(2*size_y)+1] meters.") var/list/mobs_spotted = list() var/list/minds_spotted = list() diff --git a/code/modules/plumbing/plumbers/bottle_dispenser.dm b/code/modules/plumbing/plumbers/bottle_dispenser.dm index fb6cc6a8462bc..0ed32ee8714bb 100644 --- a/code/modules/plumbing/plumbers/bottle_dispenser.dm +++ b/code/modules/plumbing/plumbers/bottle_dispenser.dm @@ -63,7 +63,7 @@ return switch(action) if("change_bottle_size") - bottle_size = CLAMP(text2num(params["volume"]), 0, 30) + bottle_size = clamp(text2num(params["volume"]), 0, 30) . = TRUE if("change_bottle_name") var/new_name = stripped_input(usr, "Enter a bottle name.", name, bottle_name) diff --git a/code/modules/plumbing/plumbers/patch_dispenser.dm b/code/modules/plumbing/plumbers/patch_dispenser.dm index 48ebf6169fa38..0f21f9027d68d 100644 --- a/code/modules/plumbing/plumbers/patch_dispenser.dm +++ b/code/modules/plumbing/plumbers/patch_dispenser.dm @@ -65,7 +65,7 @@ return switch(action) if("change_patch_size") - patch_size = CLAMP(text2num(params["volume"]), 0, 40) + patch_size = clamp(text2num(params["volume"]), 0, 40) . = TRUE if("change_patch_name") var/new_name = stripped_input(usr, "Enter a patch name.", name, patch_name) diff --git a/code/modules/plumbing/plumbers/pill_press.dm b/code/modules/plumbing/plumbers/pill_press.dm index 67fba33785a21..6783a1ede8f80 100644 --- a/code/modules/plumbing/plumbers/pill_press.dm +++ b/code/modules/plumbing/plumbers/pill_press.dm @@ -98,7 +98,7 @@ chosen_pill_style = "[params["id"]]" . = TRUE if("change_pill_size") - pill_size = CLAMP(text2num(params["volume"]), minimum_pill, maximum_pill) + pill_size = clamp(text2num(params["volume"]), minimum_pill, maximum_pill) . = TRUE if("change_pill_name") var/new_name = stripped_input(usr, "Enter a pill name.", name, pill_name) diff --git a/code/modules/plumbing/plumbers/splitters.dm b/code/modules/plumbing/plumbers/splitters.dm index 13f9bbc2c795b..0c098a3e14920 100644 --- a/code/modules/plumbing/plumbers/splitters.dm +++ b/code/modules/plumbing/plumbers/splitters.dm @@ -46,7 +46,7 @@ switch(action) if("set_amount") var/direction = params["target"] - var/value = CLAMP(text2num(params["amount"]), 1, max_transfer) + var/value = clamp(text2num(params["amount"]), 1, max_transfer) switch(direction) if("straight") transfer_straight = value diff --git a/code/modules/pool/components/swimming.dm b/code/modules/pool/components/swimming.dm index e2c77c299da72..9404eb45ee9fd 100644 --- a/code/modules/pool/components/swimming.dm +++ b/code/modules/pool/components/swimming.dm @@ -125,14 +125,19 @@ /datum/component/swimming/proc/drown(mob/living/victim) if(victim.losebreath < 1) victim.losebreath += 1 + var/shouldemote = TRUE + if(victim.stat > CONSCIOUS) + shouldemote = FALSE //Unconscious/dead people shouldn't emote ticks_drowned ++ - if(prob(20)) - victim.emote("cough") - else if(prob(25)) - victim.emote("gasp") + if(shouldemote) + if(prob(20)) + victim.emote("cough") + else if(prob(25)) + victim.emote("gasp") if(ticks_drowned > 20) if(prob(10)) - victim.visible_message("[victim] falls unconscious for a moment!") + if(shouldemote) + victim.visible_message("[victim] falls unconscious for a moment!") victim.Unconscious(10) /datum/component/swimming/proc/start_drowning(mob/living/victim) diff --git a/code/modules/pool/pool.dm b/code/modules/pool/pool.dm index a8e9e71fc7029..df6ece93da93d 100644 --- a/code/modules/pool/pool.dm +++ b/code/modules/pool/pool.dm @@ -231,7 +231,7 @@ GLOBAL_LIST_EMPTY(pool_filters) var/newTemp = input(user, "Set a new temperature for [src] (Kelvin).", "[src]", null) as num if(!newTemp) return - newTemp = CLAMP(newTemp, T0C, 320) + newTemp = clamp(newTemp, T0C, 320) desired_temperature = newTemp return FALSE @@ -241,7 +241,7 @@ GLOBAL_LIST_EMPTY(pool_filters) use_power(idle_power_usage) var/delta = ((current_temperature > desired_temperature) ? -0.25 : 0.25 ) * delta_time current_temperature += delta - current_temperature = CLAMP(current_temperature, T0C, desired_temperature) + current_temperature = clamp(current_temperature, T0C, desired_temperature) var/trans_amount = reagents.total_volume / pool.len //Split up the reagents equally. for(var/turf/open/indestructible/sound/pool/water as() in pool) if(reagents.reagent_list.len) diff --git a/code/modules/pool/pool_items.dm b/code/modules/pool/pool_items.dm index af27a493e0ed3..a954867baab2c 100644 --- a/code/modules/pool/pool_items.dm +++ b/code/modules/pool/pool_items.dm @@ -54,7 +54,7 @@ /obj/item/pool/pool_noodle/proc/jedi_spin(mob/living/user) //rip complex code, but this fucked up blocking user.emote("flip") -/obj/item/pool/pool_noodle/suicide_act(mob/user) +/obj/item/pool/pool_noodle/suicide_act(mob/living/user) if(suiciding) return SHAME suiciding = TRUE diff --git a/code/modules/power/apc/apc_attack.dm b/code/modules/power/apc/apc_attack.dm index 0465f67091474..730d8e32d34d4 100644 --- a/code/modules/power/apc/apc_attack.dm +++ b/code/modules/power/apc/apc_attack.dm @@ -271,7 +271,7 @@ /obj/machinery/power/apc/proc/set_broken() if(malfai && operating) - malfai.malf_picker.processing_time = CLAMP(malfai.malf_picker.processing_time - 10,0,1000) + malfai.malf_picker.processing_time = clamp(malfai.malf_picker.processing_time - 10,0,1000) machine_stat |= BROKEN operating = FALSE if(occupier) diff --git a/code/modules/power/apc/apc_main.dm b/code/modules/power/apc/apc_main.dm index d2df58c269070..eaf421597d315 100644 --- a/code/modules/power/apc/apc_main.dm +++ b/code/modules/power/apc/apc_main.dm @@ -175,7 +175,7 @@ GLOB.apcs_list -= src if(malfai && operating) - malfai.malf_picker.processing_time = CLAMP(malfai.malf_picker.processing_time - 10,0,1000) + malfai.malf_picker.processing_time = clamp(malfai.malf_picker.processing_time - 10,0,1000) if(area) area.power_light = FALSE area.power_equip = FALSE @@ -578,7 +578,7 @@ //=====Clock Cult===== if(integration_cog && cell.charge >= cell.maxcharge/2) - var/power_delta = CLAMP(cell.charge - 20, 0, 20) + var/power_delta = clamp(cell.charge - 20, 0, 20) GLOB.clockcult_power += power_delta cell.charge -= power_delta diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 992e025f44816..71e5297764a07 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -219,7 +219,7 @@ By design, d1 is the smallest direction and d2 is the highest /obj/structure/cable/proc/surplus() if(powernet) - return CLAMP(powernet.avail-powernet.load, 0, powernet.avail) + return clamp(powernet.avail-powernet.load, 0, powernet.avail) else return 0 @@ -235,7 +235,7 @@ By design, d1 is the smallest direction and d2 is the highest /obj/structure/cable/proc/delayed_surplus() if(powernet) - return CLAMP(powernet.newavail - powernet.delayedload, 0, powernet.newavail) + return clamp(powernet.newavail - powernet.delayedload, 0, powernet.newavail) else return 0 @@ -510,12 +510,12 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai cable_color = picked update_icon() -/obj/item/stack/cable_coil/suicide_act(mob/user) +/obj/item/stack/cable_coil/suicide_act(mob/living/user) if(locate(/obj/structure/chair/stool) in get_turf(user)) user.visible_message("[user] is making a noose with [src]! It looks like [user.p_theyre()] trying to commit suicide!") else user.visible_message("[user] is strangling [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return(OXYLOSS) + return OXYLOSS /obj/item/stack/cable_coil/get_recipes() return GLOB.cable_coil_recipes diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 0e4d088cb444a..552b247a2e21b 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -107,9 +107,9 @@ else . += "The charge meter reads [round(src.percent() )]%." -/obj/item/stock_parts/cell/suicide_act(mob/user) +/obj/item/stock_parts/cell/suicide_act(mob/living/user) user.visible_message("[user] is licking the electrodes of [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (FIRELOSS) + return FIRELOSS /obj/item/stock_parts/cell/on_reagent_change(changetype) rigged = !isnull(reagents.has_reagent(/datum/reagent/toxin/plasma, 5)) //has_reagent returns the reagent datum @@ -205,7 +205,7 @@ /obj/item/stock_parts/cell/proc/get_electrocute_damage() if(charge >= 1000) - return CLAMP(20 + round(charge/25000), 20, 195) + rand(-5,5) + return clamp(20 + round(charge/25000), 20, 195) + rand(-5,5) else return 0 @@ -380,7 +380,7 @@ /obj/item/stock_parts/cell/emproof/empty/ComponentInitialize() . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF) + AddElement(/datum/element/empprotection, EMP_PROTECT_SELF) /obj/item/stock_parts/cell/emproof/corrupt() return @@ -398,7 +398,7 @@ . = ..() if(. & EMP_PROTECT_SELF) return - charge = CLAMP((charge-(10000/severity)),0,maxcharge) + charge = clamp((charge-(10000/severity)),0,maxcharge) /obj/item/stock_parts/cell/emergency_light name = "miniature power cell" diff --git a/code/modules/power/lighting/light_items.dm b/code/modules/power/lighting/light_items.dm index 8bed56028dac2..a902e00d8361d 100644 --- a/code/modules/power/lighting/light_items.dm +++ b/code/modules/power/lighting/light_items.dm @@ -17,11 +17,10 @@ /obj/item/light/suicide_act(mob/living/carbon/user) if (status == LIGHT_BROKEN) user.visible_message("[user] begins to stab [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return BRUTELOSS else user.visible_message("[user] begins to eat \the [src]! It looks like [user.p_theyre()] not very bright!") shatter() - return BRUTELOSS + return BRUTELOSS /obj/item/light/tube name = "light tube" diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index a0688ebf439d4..25bb6d26e7a78 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -42,7 +42,7 @@ /obj/machinery/power/proc/surplus() if(powernet) - return CLAMP(powernet.avail-powernet.load, 0, powernet.avail) + return clamp(powernet.avail-powernet.load, 0, powernet.avail) else return 0 @@ -58,7 +58,7 @@ /obj/machinery/power/proc/delayed_surplus() if(powernet) - return CLAMP(powernet.newavail - powernet.delayedload, 0, powernet.newavail) + return clamp(powernet.newavail - powernet.delayedload, 0, powernet.newavail) else return 0 diff --git a/code/modules/power/powernet.dm b/code/modules/power/powernet.dm index 3dcbafa3f630d..fda63a0271af8 100644 --- a/code/modules/power/powernet.dm +++ b/code/modules/power/powernet.dm @@ -96,6 +96,6 @@ /datum/powernet/proc/get_electrocute_damage() if(avail >= 1000) - return CLAMP(20 + round(avail/25000), 20, 195) + rand(-5,5) + return clamp(20 + round(avail/25000), 20, 195) + rand(-5,5) else return 0 diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm index a02c5b7cd66a8..fdeda81ddd307 100644 --- a/code/modules/power/singularity/containment_field.dm +++ b/code/modules/power/singularity/containment_field.dm @@ -68,7 +68,7 @@ FG1.calc_power(INFINITY) //rip that 'containment' field M.adjustHealth(-M.obj_damage) else - ..() + return ..() /obj/machinery/field/containment/proc/on_entered(datum/source, atom/movable/AM) SIGNAL_HANDLER diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 29731cf1d394b..5a6dc3a8c493c 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -1,13 +1,10 @@ -//emitter construction defines -#define EMITTER_UNWRENCHED 0 -#define EMITTER_WRENCHED 1 -#define EMITTER_WELDED 2 /obj/machinery/power/emitter name = "emitter" desc = "A heavy-duty industrial laser, often used in containment fields and power generation." icon = 'icons/obj/singularity.dmi' icon_state = "emitter" + base_icon_state = "emitter" anchored = FALSE density = TRUE @@ -20,49 +17,59 @@ var/icon_state_on = "emitter_+a" var/icon_state_underpowered = "emitter_+u" + ///Is the machine active? var/active = FALSE + ///Does the machine have power? var/powered = FALSE - var/fire_delay = 100 - var/maximum_fire_delay = 100 - var/minimum_fire_delay = 20 + ///Seconds before the next shot + var/fire_delay = 10 SECONDS + ///Max delay before firing + var/maximum_fire_delay = 10 SECONDS + ///Min delay before firing + var/minimum_fire_delay = 2 SECONDS + ///When was the last shot var/last_shot = 0 + ///Number of shots made (gets reset every few shots) var/shot_number = 0 - var/state = EMITTER_UNWRENCHED + ///if it's welded down to the ground or not. the emitter will not fire while unwelded. if set to true, the emitter will start anchored as well. + var/welded = FALSE + ///Is the emitter id locked? var/locked = FALSE + ///Used to stop interactions with the object (mainly in the wabbajack statue) var/allow_switch_interact = TRUE - + ///What projectile type are we shooting? var/projectile_type = /obj/projectile/beam/emitter + ///What's the projectile sound? var/projectile_sound = 'sound/weapons/emitter.ogg' + ///Sparks emitted with every shot var/datum/effect_system/spark_spread/sparks - + ///Stores the type of gun we are using inside the emitter var/obj/item/gun/energy/gun + ///List of all the properties of the inserted gun var/list/gun_properties - var/mode = 0 + //only used to always have the gun properties on non-letal (no other instances found) + var/mode = FALSE // The following 3 vars are mostly for the prototype + ///manual shooting? (basically you hop onto the emitter and choose the shooting direction, is very janky since you can only shoot at the 8 directions and i don't think is ever used since you can't build those) var/manual = FALSE + ///Amount of power inside var/charge = 0 + ///stores the direction and orientation of the last projectile var/last_projectile_params -/obj/machinery/power/emitter/anchored - anchored = TRUE - -/obj/machinery/power/emitter/ctf - name = "Energy Cannon" - active = TRUE - active_power_usage = 0 - idle_power_usage = 0 - locked = TRUE - req_access_txt = "100" - state = EMITTER_WELDED - use_power = NO_POWER_USE +/obj/machinery/power/emitter/welded/Initialize() + welded = TRUE + . = ..() /obj/machinery/power/emitter/Initialize(mapload) . = ..() RefreshParts() wires = new /datum/wires/emitter(src) - if(state == EMITTER_WELDED && anchored) + if(welded) + if(!anchored) + setAnchored(TRUE) connect_to_network() sparks = new @@ -71,149 +78,165 @@ /obj/machinery/power/emitter/ComponentInitialize() . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) + AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) + +/obj/machinery/power/emitter/setAnchored(anchorvalue) + . = ..() + if(!anchored && welded) //make sure they're keep in sync in case it was forcibly unanchored by badmins or by a megafauna. + welded = FALSE /obj/machinery/power/emitter/RefreshParts() - var/max_firedelay = 120 - var/firedelay = 120 - var/min_firedelay = 24 + var/max_fire_delay = 12 SECONDS + var/fire_shoot_delay = 12 SECONDS + var/min_fire_delay = 2.4 SECONDS var/power_usage = 350 - for(var/obj/item/stock_parts/micro_laser/L in component_parts) - max_firedelay -= 20 * L.rating - min_firedelay -= 4 * L.rating - firedelay -= 20 * L.rating - maximum_fire_delay = max_firedelay - minimum_fire_delay = min_firedelay - fire_delay = firedelay - for(var/obj/item/stock_parts/manipulator/M in component_parts) - power_usage -= 50 * M.rating + for(var/obj/item/stock_parts/micro_laser/laser in component_parts) + max_fire_delay -= 2 SECONDS * laser.rating + min_fire_delay -= 0.4 SECONDS * laser.rating + fire_shoot_delay -= 2 SECONDS * laser.rating + maximum_fire_delay = max_fire_delay + minimum_fire_delay = min_fire_delay + fire_delay = fire_shoot_delay + for(var/obj/item/stock_parts/manipulator/manipulator in component_parts) + power_usage -= 50 * manipulator.rating update_mode_power_usage(ACTIVE_POWER_USE, power_usage) - if(anchored && state == EMITTER_UNWRENCHED) - state = EMITTER_WRENCHED /obj/machinery/power/emitter/examine(mob/user) . = ..() - if(in_range(user, src) || isobserver(user)) - . += "The status display reads: Emitting one beam each [fire_delay*0.1] seconds.
Power consumption at [active_power_usage]W.
" + if(welded) + . += "It's moored firmly to the floor. You can unsecure its moorings with a welder." + else if(anchored) + . += "It's currently anchored to the floor. You can secure its moorings with a welder, or remove it with a wrench." + else + . += "It's not anchored to the floor. You can secure it in place with a wrench." + + if(!in_range(user, src) || !isobserver(user)) + return + + if(!active) + . += "Its status display is currently turned off." + else if(!powered) + . += "Its status display is glowing faintly." + else + . += "Its status display reads: Emitting one beam every [DisplayTimeText(fire_delay)]." + . += "Power consumption at [display_power(active_power_usage)]." /obj/machinery/power/emitter/ComponentInitialize() . = ..() AddComponent(/datum/component/simple_rotation, ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS, null, CALLBACK(src, PROC_REF(can_be_rotated))) -/obj/machinery/power/emitter/proc/can_be_rotated(mob/user,rotation_type) - if (anchored) - to_chat(user, "It is fastened to the floor!") - return FALSE - return TRUE +/obj/machinery/power/emitter/proc/can_be_rotated(mob/user, rotation_type) + if(!anchored) + return TRUE + to_chat(user, "It is fastened to the floor!") + return FALSE /obj/machinery/power/emitter/Destroy() if(SSticker.IsRoundInProgress()) var/turf/T = get_turf(src) - message_admins("Emitter deleted at [ADMIN_VERBOSEJMP(T)]") - log_game("Emitter deleted at [AREACOORD(T)]") + message_admins("[src] deleted at [ADMIN_VERBOSEJMP(T)]") + log_game("[src] deleted at [AREACOORD(T)]") investigate_log("deleted at [AREACOORD(T)]", INVESTIGATE_ENGINES) QDEL_NULL(sparks) QDEL_NULL(wires) return ..() -/obj/machinery/power/emitter/update_icon() - if(active && powernet) - icon_state = avail(active_power_usage) ? icon_state_on : icon_state_underpowered - else - icon_state = initial(icon_state) +/obj/machinery/power/emitter/update_icon_state() + if(!active || !powernet) + icon_state = base_icon_state + return ..() + icon_state = avail(active_power_usage) ? icon_state_on : icon_state_underpowered + return ..() /obj/machinery/power/emitter/interact(mob/user) add_fingerprint(user) - if(state == EMITTER_WELDED) - if(!powernet && active_power_usage) - to_chat(user, "\The [src] isn't connected to a wire!") - return TRUE - if(!locked && allow_switch_interact) - if(active == TRUE) - active = FALSE - to_chat(user, "You turn off [src].") - else - active = TRUE - to_chat(user, "You turn on [src].") - shot_number = 0 - fire_delay = maximum_fire_delay - - message_admins("Emitter turned [active ? "ON" : "OFF"] by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(src)]") - log_game("Emitter turned [active ? "ON" : "OFF"] by [key_name(user)] in [AREACOORD(src)]") - investigate_log("turned [active ? "ON" : "OFF"] by [key_name(user)] at [AREACOORD(src)]", INVESTIGATE_ENGINES) - - update_icon() + if(!welded) + to_chat(user, "[src] needs to be firmly secured to the floor first!") + return FALSE + if(!powernet) + to_chat(user, "\The [src] isn't connected to a wire!") + return FALSE + if(locked || !allow_switch_interact) + to_chat(user, "The controls are locked!") + return FALSE - else - to_chat(user, "The controls are locked!") + if(active) + active = FALSE else - to_chat(user, "[src] needs to be firmly secured to the floor first!") - return TRUE + active = TRUE + shot_number = 0 + fire_delay = maximum_fire_delay + + to_chat(user, "You turn [active ? "on" : "off"] [src].") + message_admins("Emitter turned [active ? "ON" : "OFF"] by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(src)]") + log_game("Emitter turned [active ? "ON" : "OFF"] by [key_name(user)] in [AREACOORD(src)]") + investigate_log("turned [active ? "ON" : "OFF"] by [key_name(user)] at [AREACOORD(src)]", INVESTIGATE_ENGINES) + update_appearance() /obj/machinery/power/emitter/attack_animal(mob/living/simple_animal/M) if(ismegafauna(M) && anchored) - state = EMITTER_UNWRENCHED - anchored = FALSE + setAnchored(FALSE) M.visible_message("[M] rips [src] free from its moorings!") else - ..() - if(!anchored) + . = ..() + if(. && !anchored) step(src, get_dir(M, src)) /obj/machinery/power/emitter/process(delta_time) if(machine_stat & (BROKEN)) return - if(state != EMITTER_WELDED || (!powernet && active_power_usage)) + if(!welded || (!powernet && active_power_usage)) active = FALSE - update_icon() + update_appearance() return - if(active == TRUE) - if(!active_power_usage || surplus() >= active_power_usage) - add_load(active_power_usage) - if(!powered) - powered = TRUE - update_icon() - investigate_log("regained power and turned ON at [AREACOORD(src)]", INVESTIGATE_ENGINES) - else - if(powered) - powered = FALSE - update_icon() - investigate_log("lost power and turned OFF at [AREACOORD(src)]", INVESTIGATE_ENGINES) - log_game("Emitter lost power in [AREACOORD(src)]") - return - if(charge <= 80) - charge += 2.5 * delta_time - if(!check_delay() || manual == TRUE) - return FALSE - fire_beam() + if(!active) + return + if(active_power_usage && surplus() < active_power_usage) + if(powered) + powered = FALSE + update_appearance() + investigate_log("lost power and turned OFF at [AREACOORD(src)]", INVESTIGATE_ENGINES) + log_game("Emitter lost power in [AREACOORD(src)]") + return + + add_load(active_power_usage) + if(!powered) + powered = TRUE + update_appearance() + investigate_log("regained power and turned ON at [AREACOORD(src)]", INVESTIGATE_ENGINES) + if(charge <= 80) + charge += 2.5 * delta_time + if(!check_delay() || manual == TRUE) + return FALSE + fire_beam() /obj/machinery/power/emitter/proc/check_delay() - if((src.last_shot + src.fire_delay) <= world.time) + if((last_shot + fire_delay) <= world.time) return TRUE return FALSE /obj/machinery/power/emitter/proc/fire_beam_pulse() if(!check_delay()) return FALSE - if(state != EMITTER_WELDED) + if(!welded) return FALSE if(surplus() >= active_power_usage) add_load(active_power_usage) fire_beam() /obj/machinery/power/emitter/proc/fire_beam(mob/user) - var/obj/projectile/P = new projectile_type(get_turf(src)) - playsound(get_turf(src), projectile_sound, 50, TRUE) + var/obj/projectile/projectile = new projectile_type(get_turf(src)) + playsound(src, projectile_sound, 50, TRUE) if(prob(35)) sparks.start() - P.firer = user ? user : src - P.fired_from = src + projectile.firer = user ? user : src + projectile.fired_from = src if(last_projectile_params) - P.p_x = last_projectile_params[2] - P.p_y = last_projectile_params[3] - P.fire(last_projectile_params[1]) + projectile.p_x = last_projectile_params[2] + projectile.p_y = last_projectile_params[3] + projectile.fire(last_projectile_params[1]) else - P.fire(dir2angle(dir)) + projectile.fire(dir2angle(dir)) if(!manual) last_shot = world.time if(shot_number < 3) @@ -222,7 +245,7 @@ else fire_delay = rand(minimum_fire_delay,maximum_fire_delay) shot_number = 0 - return P + return projectile /obj/machinery/power/emitter/can_be_unfasten_wrench(mob/user, silent) if(active) @@ -230,100 +253,95 @@ to_chat(user, "Turn \the [src] off first!") return FAILED_UNFASTEN - else if(state == EMITTER_WELDED) + else if(welded) if(!silent) to_chat(user, "[src] is welded to the floor!") return FAILED_UNFASTEN return ..() -/obj/machinery/power/emitter/default_unfasten_wrench(mob/user, obj/item/I, time = 20) +/obj/machinery/power/emitter/wrench_act(mob/living/user, obj/item/item) . = ..() - if(. == SUCCESSFUL_UNFASTEN) - if(anchored) - state = EMITTER_WRENCHED - else - state = EMITTER_UNWRENCHED - -/obj/machinery/power/emitter/wrench_act(mob/living/user, obj/item/I) - default_unfasten_wrench(user, I) + default_unfasten_wrench(user, item) return TRUE -/obj/machinery/power/emitter/welder_act(mob/living/user, obj/item/I) +/obj/machinery/power/emitter/welder_act(mob/living/user, obj/item/item) + . = ..() if(active) - to_chat(user, "Turn \the [src] off first.") + to_chat(user, "Turn [src] off first!") return TRUE - switch(state) - if(EMITTER_UNWRENCHED) - to_chat(user, "The [src.name] needs to be wrenched to the floor!") - if(EMITTER_WRENCHED) - if(!I.tool_start_check(user, amount=0)) - return TRUE - user.visible_message("[user.name] starts to weld the [name] to the floor.", \ - "You start to weld \the [src] to the floor...", \ - "You hear welding.") - if(I.use_tool(src, user, 20, volume=50) && state == EMITTER_WRENCHED) - state = EMITTER_WELDED - to_chat(user, "You weld \the [src] to the floor.") - connect_to_network() - if(EMITTER_WELDED) - if(!I.tool_start_check(user, amount=0)) - return TRUE - user.visible_message("[user.name] starts to cut the [name] free from the floor.", \ - "You start to cut \the [src] free from the floor...", \ - "You hear welding.") - if(I.use_tool(src, user, 20, volume=50) && state == EMITTER_WELDED) - state = EMITTER_WRENCHED - to_chat(user, "You cut \the [src] free from the floor.") - disconnect_from_network() + if(welded) + if(!item.tool_start_check(user, amount=0)) + return TRUE + user.visible_message("[user.name] starts to cut the [name] free from the floor.", \ + "You start to cut [src] free from the floor...", \ + "You hear welding.") + if(!item.use_tool(src, user, 20, volume=50) || !welded) + return + welded = FALSE + to_chat(user, "You cut [src] free from the floor.") + disconnect_from_network() + //update_cable_icons_on_turf(get_turf(src)) + return TRUE + if(!anchored) + to_chat(user, "[src] needs to be wrenched to the floor!") + return TRUE + if(!item.tool_start_check(user, amount=0)) + return TRUE + user.visible_message("[user.name] starts to weld the [name] to the floor.", \ + "You start to weld [src] to the floor...", \ + "You hear welding.") + if(!item.use_tool(src, user, amount=20, volume=50) || !anchored) + return + welded = TRUE + to_chat(user, "You weld [src] to the floor.") + connect_to_network() + //update_cable_icons_on_turf(get_turf(src)) return TRUE -/obj/machinery/power/emitter/crowbar_act(mob/living/user, obj/item/I) +/obj/machinery/power/emitter/crowbar_act(mob/living/user, obj/item/item) if(panel_open && gun) return remove_gun(user) - default_deconstruction_crowbar(I) + default_deconstruction_crowbar(item) return TRUE -/obj/machinery/power/emitter/screwdriver_act(mob/living/user, obj/item/I) +/obj/machinery/power/emitter/screwdriver_act(mob/living/user, obj/item/item) if(..()) return TRUE - default_deconstruction_screwdriver(user, "emitter_open", "emitter", I) + default_deconstruction_screwdriver(user, "emitter_open", "emitter", item) return TRUE - -/obj/machinery/power/emitter/attackby(obj/item/I, mob/user, params) - if(I.GetID()) +/obj/machinery/power/emitter/attackby(obj/item/item, mob/user, params) + if(item.GetID()) if(obj_flags & EMAGGED) - to_chat(user, "The lock seems to be broken!") - return - if(allowed(user)) - if(active) - locked = !locked - to_chat(user, "You [src.locked ? "lock" : "unlock"] the controls.") - else - to_chat(user, "The controls can only be locked when \the [src] is online!") - else to_chat(user, "Access denied.") + return + if(!active) + to_chat(user, "The controls can only be locked when \the [src] is online!") + return + locked = !locked + to_chat(user, "You [src.locked ? "lock" : "unlock"] the controls.") return - else if(is_wire_tool(I) && panel_open) + if(is_wire_tool(item) && panel_open) wires.interact(user) return - else if(panel_open && !gun && istype(I,/obj/item/gun/energy)) - if(integrate(I,user)) + if(panel_open && !gun && istype(item,/obj/item/gun/energy)) + if(integrate(item,user)) return return ..() -/obj/machinery/power/emitter/proc/integrate(obj/item/gun/energy/E,mob/user) - if(istype(E, /obj/item/gun/energy)) - if(!user.transferItemToLoc(E, src)) - return - gun = E - gun_properties = gun.get_turret_properties() - set_projectile() - return TRUE +/obj/machinery/power/emitter/proc/integrate(obj/item/gun/energy/energy_gun, mob/user) + if(!istype(energy_gun, /obj/item/gun/energy)) + return + if(!user.transferItemToLoc(energy_gun, src)) + return + gun = energy_gun + gun_properties = gun.get_turret_properties() + set_projectile() + return TRUE /obj/machinery/power/emitter/proc/remove_gun(mob/user) if(!gun) @@ -357,21 +375,24 @@ name = "Prototype Emitter" icon = 'icons/obj/turrets.dmi' icon_state = "protoemitter" + base_icon_state = "protoemitter" icon_state_on = "protoemitter_+a" icon_state_underpowered = "protoemitter_+u" can_buckle = TRUE buckle_lying = FALSE + ///Sets the view size for the user var/view_range = 4.5 - var/datum/action/innate/protoemitter/firing/auto + ///Grants the buckled mob the action button + var/datum/action/innate/proto_emitter/firing/auto //BUCKLE HOOKS /obj/machinery/power/emitter/prototype/unbuckle_mob(mob/living/buckled_mob,force = 0) playsound(src,'sound/mecha/mechmove01.ogg', 50, TRUE) manual = FALSE - for(var/obj/item/I in buckled_mob.held_items) - if(istype(I, /obj/item/turret_control)) - qdel(I) + for(var/obj/item/item in buckled_mob.held_items) + if(istype(item, /obj/item/turret_control)) + qdel(item) if(istype(buckled_mob)) buckled_mob.pixel_x = buckled_mob.base_pixel_x buckled_mob.pixel_y = buckled_mob.base_pixel_y @@ -380,67 +401,73 @@ auto.Remove(buckled_mob) . = ..() -/obj/machinery/power/emitter/prototype/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE) +/obj/machinery/power/emitter/prototype/user_buckle_mob(mob/living/buckled_mob, mob/user, check_loc = TRUE) if(user.incapacitated() || !istype(user)) return - for(var/atom/movable/A in get_turf(src)) - if(A.density && (A != src && A != M)) + for(var/atom/movable/atom in get_turf(src)) + if(atom.density && (atom != src && atom != buckled_mob)) return - M.forceMove(get_turf(src)) + buckled_mob.forceMove(get_turf(src)) ..() playsound(src,'sound/mecha/mechmove01.ogg', 50, TRUE) - M.pixel_y = 14 + buckled_mob.pixel_y = 14 layer = 4.1 - if(M.client) - M.client.view_size.setTo(view_range) + if(buckled_mob.client) + buckled_mob.client.view_size.setTo(view_range) if(!auto) auto = new() - auto.Grant(M, src) + auto.Grant(buckled_mob, src) -/datum/action/innate/protoemitter +/datum/action/innate/proto_emitter check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUN | AB_CHECK_CONSCIOUS - var/obj/machinery/power/emitter/prototype/PE - var/mob/living/carbon/U - + ///Stores the emitter the user is currently buckled on + var/obj/machinery/power/emitter/prototype/proto_emitter + ///Stores the mob instance that is buckled to the emitter + var/mob/living/carbon/buckled_mob + +/datum/action/innate/proto_emitter/Destroy() + proto_emitter = null + buckled_mob = null + return ..() -/datum/action/innate/protoemitter/Grant(mob/living/carbon/L, obj/machinery/power/emitter/prototype/proto) - PE = proto - U = L +/datum/action/innate/proto_emitter/Grant(mob/living/carbon/user, obj/machinery/power/emitter/prototype/proto) + proto_emitter = proto + buckled_mob = user . = ..() -/datum/action/innate/protoemitter/firing +/datum/action/innate/proto_emitter/firing name = "Switch to Manual Firing" desc = "The emitter will only fire on your command and at your designated target" button_icon_state = "mech_zoom_on" -/datum/action/innate/protoemitter/firing/Activate() - if(PE.manual) - playsound(PE,'sound/mecha/mechmove01.ogg', 50, TRUE) - PE.manual = FALSE +/datum/action/innate/proto_emitter/firing/Activate() + if(proto_emitter.manual) + playsound(proto_emitter,'sound/mecha/mechmove01.ogg', 50, TRUE) + proto_emitter.manual = FALSE name = "Switch to Manual Firing" desc = "The emitter will only fire on your command and at your designated target" button_icon_state = "mech_zoom_on" - for(var/obj/item/I in U.held_items) - if(istype(I, /obj/item/turret_control)) - qdel(I) + for(var/obj/item/item in buckled_mob.held_items) + if(istype(item, /obj/item/turret_control)) + qdel(item) UpdateButtonIcon() return - else - playsound(PE,'sound/mecha/mechmove01.ogg', 50, TRUE) - name = "Switch to Automatic Firing" - desc = "Emitters will switch to periodic firing at your last target" - button_icon_state = "mech_zoom_off" - PE.manual = TRUE - for(var/V in U.held_items) - var/obj/item/I = V - if(istype(I)) - if(U.dropItemToGround(I)) - var/obj/item/turret_control/TC = new /obj/item/turret_control() - U.put_in_hands(TC) - else //Entries in the list should only ever be items or null, so if it's not an item, we can assume it's an empty hand - var/obj/item/turret_control/TC = new /obj/item/turret_control() - U.put_in_hands(TC) - UpdateButtonIcon() + playsound(proto_emitter,'sound/mecha/mechmove01.ogg', 50, TRUE) + name = "Switch to Automatic Firing" + desc = "Emitters will switch to periodic firing at your last target" + button_icon_state = "mech_zoom_off" + proto_emitter.manual = TRUE + for(var/things in buckled_mob.held_items) + var/obj/item/item = things + if(istype(item)) + if(!buckled_mob.dropItemToGround(item)) + continue + var/obj/item/turret_control/turret_control = new /obj/item/turret_control() + buckled_mob.put_in_hands(turret_control) + else //Entries in the list should only ever be items or null, so if it's not an item, we can assume it's an empty hand + var/obj/item/turret_control/turret_control = new /obj/item/turret_control() + buckled_mob.put_in_hands(turret_control) + UpdateButtonIcon() /obj/item/turret_control @@ -449,6 +476,7 @@ w_class = WEIGHT_CLASS_HUGE item_flags = ABSTRACT | NOBLUDGEON resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF + ///Ticks before being able to shoot var/delay = 0 /obj/item/turret_control/Initialize(mapload) @@ -457,53 +485,58 @@ /obj/item/turret_control/afterattack(atom/targeted_atom, mob/user, proxflag, clickparams) . = ..() - var/obj/machinery/power/emitter/E = user.buckled - E.setDir(get_dir(E,targeted_atom)) - user.setDir(E.dir) - switch(E.dir) + var/obj/machinery/power/emitter/emitter = user.buckled + emitter.setDir(get_dir(emitter,targeted_atom)) + user.setDir(emitter.dir) + switch(emitter.dir) if(NORTH) - E.layer = 3.9 + emitter.layer = 3.9 user.pixel_x = 0 user.pixel_y = -14 if(NORTHEAST) - E.layer = 3.9 + emitter.layer = 3.9 user.pixel_x = -8 user.pixel_y = -12 if(EAST) - E.layer = 4.1 + emitter.layer = 4.1 user.pixel_x = -14 user.pixel_y = 0 if(SOUTHEAST) - E.layer = 3.9 + emitter.layer = 3.9 user.pixel_x = -8 user.pixel_y = 12 if(SOUTH) - E.layer = 4.1 + emitter.layer = 4.1 user.pixel_x = 0 user.pixel_y = 14 if(SOUTHWEST) - E.layer = 3.9 + emitter.layer = 3.9 user.pixel_x = 8 user.pixel_y = 12 if(WEST) - E.layer = 4.1 + emitter.layer = 4.1 user.pixel_x = 14 user.pixel_y = 0 if(NORTHWEST) - E.layer = 3.9 + emitter.layer = 3.9 user.pixel_x = 8 user.pixel_y = -12 - E.last_projectile_params = calculate_projectile_angle_and_pixel_offsets(user, clickparams) + emitter.last_projectile_params = calculate_projectile_angle_and_pixel_offsets(user, clickparams) - if(E.charge >= 10 && world.time > delay) - E.charge -= 10 - E.fire_beam(user) + if(emitter.charge >= 10 && world.time > delay) + emitter.charge -= 10 + emitter.fire_beam(user) delay = world.time + 10 - else if (E.charge < 10) + else if (emitter.charge < 10) playsound(src,'sound/machines/buzz-sigh.ogg', 50, TRUE) - -#undef EMITTER_UNWRENCHED -#undef EMITTER_WRENCHED -#undef EMITTER_WELDED +/obj/machinery/power/emitter/ctf + name = "Energy Cannon" + active = TRUE + active_power_usage = FALSE + idle_power_usage = FALSE + locked = TRUE + req_access_txt = "100" + welded = TRUE + use_power = NO_POWER_USE diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index 195e611398cdb..f05ed4eedfe24 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -52,7 +52,7 @@ field_generator power level display /obj/machinery/field/generator/ComponentInitialize() . = ..() - AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) + AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) /obj/machinery/field/generator/update_icon() cut_overlays() diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index 42d305ba4c822..a5e384eefd8d9 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -257,7 +257,11 @@ name = "solar panel control" desc = "A controller for solar panel arrays." icon = 'icons/obj/computer.dmi' - icon_state = "computer" + icon_state = "computer-0" + base_icon_state = "computer" + smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIRECTIONAL | SMOOTH_BITMASK_SKIP_CORNERS + smoothing_groups = list(SMOOTH_GROUP_COMPUTERS) + canSmoothWith = list(SMOOTH_GROUP_COMPUTERS) density = TRUE use_power = IDLE_POWER_USE idle_power_usage = 250 @@ -278,6 +282,8 @@ /obj/machinery/power/solar_control/Initialize(mapload) . = ..() + QUEUE_SMOOTH(src) + QUEUE_SMOOTH_NEIGHBORS(src) if(powernet) set_panels(currentdir) connect_to_network() @@ -287,6 +293,7 @@ M.unset_control() if(connected_tracker) connected_tracker.unset_control() + QUEUE_SMOOTH_NEIGHBORS(src) return ..() /obj/machinery/power/solar_control/disconnect_from_network() @@ -378,7 +385,7 @@ if(adjust) value = currentdir + adjust if(value != null) - currentdir = CLAMP((360 + value) % 360, 0, 359) + currentdir = clamp((360 + value) % 360, 0, 359) targetdir = currentdir set_panels(currentdir) . = TRUE @@ -388,7 +395,7 @@ if(adjust) value = trackrate + adjust if(value != null) - trackrate = CLAMP(value, -7200, 7200) + trackrate = clamp(value, -7200, 7200) if(trackrate) nexttime = world.time + 36000 / abs(trackrate) . = TRUE diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index f199faa3346bd..5c709c1c827ce 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -383,7 +383,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) power_changes = TRUE //Atmos has run at least one full tick recently, resume processing. if(power) - soundloop.volume = CLAMP((50 + (power / 50)), 50, 100) + soundloop.volume = clamp((50 + (power / 50)), 50, 100) if(damage >= 300) soundloop.mid_sounds = list('sound/machines/sm/loops/delamming.ogg' = 1) else @@ -417,7 +417,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) else if(takes_damage) //causing damage - damage = max(damage + (max(CLAMP(removed.total_moles() / 200, 0.5, 1) * removed.return_temperature() - ((T0C + HEAT_PENALTY_THRESHOLD)*dynamic_heat_resistance), 0) * mole_heat_penalty / 150 ) * DAMAGE_INCREASE_MULTIPLIER, 0) + damage = max(damage + (max(clamp(removed.total_moles() / 200, 0.5, 1) * removed.return_temperature() - ((T0C + HEAT_PENALTY_THRESHOLD)*dynamic_heat_resistance), 0) * mole_heat_penalty / 150 ) * DAMAGE_INCREASE_MULTIPLIER, 0) damage = max(damage + (max(power - POWER_PENALTY_THRESHOLD, 0)/500) * DAMAGE_INCREASE_MULTIPLIER, 0) damage = max(damage + (max(combined_gas - MOLE_PENALTY_THRESHOLD, 0)/80) * DAMAGE_INCREASE_MULTIPLIER, 0) @@ -458,10 +458,10 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) mole_heat_penalty = max(combined_gas / MOLE_HEAT_PENALTY, 0.25) if (combined_gas > POWERLOSS_INHIBITION_MOLE_THRESHOLD && co2comp > POWERLOSS_INHIBITION_GAS_THRESHOLD) - powerloss_dynamic_scaling = CLAMP(powerloss_dynamic_scaling + CLAMP(co2comp - powerloss_dynamic_scaling, -0.02, 0.02), 0, 1) + powerloss_dynamic_scaling = clamp(powerloss_dynamic_scaling + clamp(co2comp - powerloss_dynamic_scaling, -0.02, 0.02), 0, 1) else - powerloss_dynamic_scaling = CLAMP(powerloss_dynamic_scaling - 0.05,0, 1) - powerloss_inhibitor = CLAMP(1-(powerloss_dynamic_scaling * CLAMP(combined_gas/POWERLOSS_INHIBITION_MOLE_BOOST_THRESHOLD,1 ,1.5)),0 ,1) + powerloss_dynamic_scaling = clamp(powerloss_dynamic_scaling - 0.05,0, 1) + powerloss_inhibitor = clamp(1-(powerloss_dynamic_scaling * clamp(combined_gas/POWERLOSS_INHIBITION_MOLE_BOOST_THRESHOLD,1 ,1.5)),0 ,1) if(matter_power) var/removed_matter = max(matter_power/MATTER_POWER_CONVERSION, 40) @@ -514,7 +514,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) continue var/D = sqrt(1 / max(1, get_dist(l, src))) l.hallucination += power * config_hallucination_power * D - l.hallucination = CLAMP(0, 200, l.hallucination) + l.hallucination = clamp(0, 200, l.hallucination) // Checks if the status has changed, in order to update the displacement effect var/current_status = get_status() @@ -539,7 +539,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) supermatter_zap(src, 5, min(power*2, 20000)) else if (damage > damage_penalty_point && prob(20)) playsound(src.loc, 'sound/weapons/emitter2.ogg', 100, 1, extrarange = 10) - supermatter_zap(src, 5, CLAMP(power*2, 4000, 20000)) + supermatter_zap(src, 5, clamp(power*2, 4000, 20000)) if(prob(15) && power > POWER_PENALTY_THRESHOLD) supermatter_pull(src, power/750) @@ -778,6 +778,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) return message_admins("[src] has consumed [key_name_admin(user)] [ADMIN_JMP(src)].") investigate_log("has consumed [key_name(user)].", INVESTIGATE_ENGINES) + user.investigate_log("has been dusted by [src].", INVESTIGATE_DEATHS) user.dust(force = TRUE) if(is_power_processing()) matter_power += 200 diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index 4efbb21bf4a53..0c506f8ad484b 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -70,7 +70,7 @@ for (var/ball in orbiting_balls) if(TICK_CHECK) return - var/range = rand(1, CLAMP(orbiting_balls.len, 3, 7)) + var/range = rand(1, clamp(orbiting_balls.len, 3, 7)) //Miniballs don't explode. tesla_zap(ball, range, TESLA_MINI_POWER/7*range, TESLA_ENERGY_MINI_BALL_FLAGS) @@ -151,8 +151,9 @@ var/mob/living/carbon/C = user to_chat(C, "That was a shockingly dumb idea.") var/obj/item/organ/brain/rip_u = locate(/obj/item/organ/brain) in C.internal_organs - C.ghostize(0) + C.ghostize(FALSE) qdel(rip_u) + C.investigate_log("had [C.p_their()] brain dusted by touching [src] with telekinesis.", INVESTIGATE_DEATHS) C.death() /obj/anomaly/energy_ball/proc/dust_mobs(atom/A) @@ -166,6 +167,7 @@ if(GR.anchored) return var/mob/living/carbon/C = A + C.investigate_log("has been dusted by an energy ball.", INVESTIGATE_DEATHS) C.dust() //Less intensive energy ball for the orbiting ones. diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 2790d499dcbbe..943fd27dd9e76 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -23,7 +23,7 @@ var/vary_fire_sound = TRUE var/fire_sound_volume = 50 var/dry_fire_sound = 'sound/weapons/gun_dry_fire.ogg' - var/suppressed = null //whether or not a message is displayed when fired + var/suppressed = null //whether or not a message is displayed when fired var/can_suppress = FALSE var/suppressed_sound = 'sound/weapons/gunshot_silenced.ogg' var/suppressed_volume = 10 @@ -32,7 +32,10 @@ var/clumsy_check = TRUE var/obj/item/ammo_casing/chambered = null trigger_guard = TRIGGER_GUARD_NORMAL //trigger guard on the weapon, hulks can't fire them with their big meaty fingers + var/can_sawoff = FALSE + var/sawn_name = null //used if gun has a special sawn-off rename var/sawn_desc = null //description change if weapon is sawn-off + var/sawn_item_state = null //used if gun has a special sawn-off in-hand sprite var/sawn_off = FALSE var/burst_size = 1 //how large a burst is var/fire_delay = 0 //rate of fire for burst firing and semi auto @@ -277,10 +280,19 @@ if(clumsy_check) if(istype(user)) if (HAS_TRAIT(user, TRAIT_CLUMSY) && prob(40)) - to_chat(user, "You shoot yourself in the foot with [src]!") - var/shot_leg = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) - process_fire(user, user, FALSE, params, shot_leg) - user.dropItemToGround(src, TRUE) + if(aimed == GUN_AIMED_POINTBLANK) + to_chat(user, "In a cruel twist of fate you fumble your grip and accidentally shoot yourself in the head!") + process_fire(user, user, FALSE, params, BODY_ZONE_HEAD) + user.dropItemToGround(src, TRUE) + if(chambered.harmful) + var/obj/item/organ/brain/target_brain = user.getorganslot(ORGAN_SLOT_BRAIN) + target_brain.Remove(user) //Rip you, unlucky + target_brain.forceMove(get_turf(user)) + else + to_chat(user, "You shoot yourself in the foot with [src]!") + var/shot_leg = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) + process_fire(user, user, FALSE, params, shot_leg) + user.dropItemToGround(src, TRUE) return if(weapon_weight == WEAPON_HEAVY && !is_wielded) @@ -300,7 +312,11 @@ loop_counter++ addtimer(CALLBACK(G, TYPE_PROC_REF(/obj/item/gun, process_fire), target, user, TRUE, params, null, bonus_spread, flag), loop_counter) - process_fire(target, user, TRUE, params, null, bonus_spread, aimed) + var/zone_override = null + if(aimed == GUN_AIMED_POINTBLANK) + zone_override = BODY_ZONE_HEAD //Shooting while pressed against someone's temple + + process_fire(target, user, TRUE, params, zone_override, bonus_spread, aimed) /obj/item/gun/can_trigger_gun(mob/living/user) . = ..() @@ -364,8 +380,10 @@ add_fingerprint(user) if(fire_rate) ranged_cooldown = world.time + 10 / fire_rate + user.client?.give_cooldown_cursor(10 / fire_rate) else ranged_cooldown = world.time + CLICK_CD_RANGE + user.client?.give_cooldown_cursor(CLICK_CD_RANGE) if(semicd) return @@ -635,9 +653,7 @@ /obj/item/gun/proc/update_gunlight() update_icon() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() /obj/item/gun/pickup(mob/user) ..() @@ -650,6 +666,8 @@ azoom.Remove(user) if(zoomed) zoom(user, user.dir) + update_icon() + user.client?.clear_cooldown_cursor() /obj/item/gun/proc/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params, bypass_timer) if(!ishuman(user) || !ishuman(target)) @@ -695,9 +713,12 @@ //Happens before the actual projectile creation /obj/item/gun/proc/before_firing(atom/target, mob/user, aimed) - if(aimed && chambered?.BB) + if(aimed == GUN_AIMED && chambered?.BB) chambered.BB.speed = initial(chambered.BB.speed) * 0.75 // Faster bullets to account for the fact you've given the target a big warning they're about to be shot chambered.BB.damage = initial(chambered.BB.damage) * 1.25 + if(aimed == GUN_AIMED_POINTBLANK) + chambered.BB.speed = initial(chambered.BB.speed) * 0.25 // Much faster bullets because you're holding them literally at the barrel of the gun + chambered.BB.damage = initial(chambered.BB.damage) * 4 // Execution ///////////// // ZOOMING // diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index a6005e0c43606..1d31564eee747 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -67,9 +67,15 @@ update_icon() /obj/item/gun/ballistic/fire_sounds() - var/frequency_to_use = sin((90/magazine?.max_ammo) * get_ammo()) + var/frequency_to_use + var/play_click + if(magazine) + frequency_to_use = sin((90/magazine?.max_ammo) * get_ammo()) + play_click = round(sqrt(magazine?.max_ammo * 2)) > get_ammo() + else + frequency_to_use = sin((90) * get_ammo()) + play_click = round(sqrt(2)) > get_ammo() var/click_frequency_to_use = 1 - frequency_to_use * 0.75 - var/play_click = round(sqrt(magazine?.max_ammo * 2)) > get_ammo() if(suppressed) playsound(src, suppressed_sound, suppressed_volume, vary_fire_sound, ignore_walls = FALSE, extrarange = SILENCED_SOUND_EXTRARANGE, falloff_distance = 0) @@ -263,6 +269,9 @@ to_chat(user, "You screw \the [S] onto \the [src].") install_suppressor(A) return + if((A.tool_behaviour == TOOL_SAW || istype(A, /obj/item/gun/energy/plasmacutter)) && can_sawoff == TRUE) + sawoff(user) + return return FALSE /obj/item/gun/ballistic/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0) @@ -381,7 +390,8 @@ #define BRAINS_BLOWN_THROW_RANGE 3 #define BRAINS_BLOWN_THROW_SPEED 1 -/obj/item/gun/ballistic/suicide_act(mob/user) + +/obj/item/gun/ballistic/suicide_act(mob/living/user) var/obj/item/organ/brain/B = user.getorganslot(ORGAN_SLOT_BRAIN) if (B && chambered && chambered.BB && can_trigger_gun(user) && !chambered.BB.nodamage) user.visible_message("[user] is putting the barrel of [src] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide!") @@ -395,19 +405,18 @@ B.forceMove(T) var/datum/callback/gibspawner = CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(spawn_atom_to_turf), /obj/effect/gibspawner/generic, B, 1, FALSE, user) B.throw_at(target, BRAINS_BLOWN_THROW_RANGE, BRAINS_BLOWN_THROW_SPEED, callback=gibspawner) - return(BRUTELOSS) + return BRUTELOSS else user.visible_message("[user] panics and starts choking to death!") - return(OXYLOSS) + return OXYLOSS else user.visible_message("[user] is pretending to blow [user.p_their()] brain[user.p_s()] out with [src]! It looks like [user.p_theyre()] trying to commit suicide!") playsound(src, dry_fire_sound, 30, TRUE) - return (OXYLOSS) + return OXYLOSS #undef BRAINS_BLOWN_THROW_SPEED #undef BRAINS_BLOWN_THROW_RANGE -//TODO: sawing off guns with TOOL_SAW /obj/item/gun/ballistic/proc/sawoff(mob/user) if(sawn_off) to_chat(user, "\The [src] is already shortened!") @@ -424,13 +433,31 @@ if(sawn_off) return user.visible_message("[user] shortens \the [src]!", "You shorten \the [src].") - name = "sawn-off [src.name]" + if (bayonet) + bayonet.forceMove(drop_location()) + clear_bayonet() + if (suppressed) + if (istype(suppressed, /obj/item/suppressor)) + //weight class is set later, don't need to worry about removing extra weight from the suppressor + var/obj/S = suppressed + S.forceMove(drop_location()) + //If it's integrally suppressed, you're messing that up by chopping off most of it from the tip + suppressed = null + if (sawn_name) + name = sawn_name + else + name = "sawn-off [src.name]" desc = sawn_desc w_class = WEIGHT_CLASS_NORMAL - item_state = "gun" + if (sawn_item_state) + item_state = sawn_item_state + else + item_state = "gun" slot_flags &= ~ITEM_SLOT_BACK //you can't sling it on your back - slot_flags |= ITEM_SLOT_BELT //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally) + slot_flags |= ITEM_SLOT_BELT //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally) recoil = SAWN_OFF_RECOIL + can_bayonet = FALSE //you got rid of the mounting lug with the rest of the barrel, dumbass + can_suppress = FALSE //ditto for the threaded barrel sawn_off = TRUE spread_multiplier = 1.6 update_icon() diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index 4578c888b3d41..37c5cbfd08186 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -53,9 +53,7 @@ playsound(user, 'sound/weapons/empty.ogg', 100, 1) update_icon() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() autofire_target = null /obj/item/gun/ballistic/automatic/c20r diff --git a/code/modules/projectiles/guns/ballistic/rifle.dm b/code/modules/projectiles/guns/ballistic/rifle.dm index 8328c0ea98ace..f03259356974e 100644 --- a/code/modules/projectiles/guns/ballistic/rifle.dm +++ b/code/modules/projectiles/guns/ballistic/rifle.dm @@ -20,6 +20,9 @@ add_overlay("[icon_state]_bolt[bolt_locked ? "_locked" : ""]") /obj/item/gun/ballistic/rifle/rack(mob/user = null) + if(!is_wielded) + to_chat(user, "You require your other hand to be free to rack the [bolt_wording] of \the [src]!") + return if(bolt_locked == FALSE) to_chat(user, "You open the bolt of \the [src].") playsound(src, rack_sound, rack_sound_volume, rack_sound_vary) @@ -35,7 +38,7 @@ return ..() /obj/item/gun/ballistic/rifle/attackby(obj/item/A, mob/user, params) - if (!bolt_locked) + if ((istype(A, /obj/item/ammo_casing/a762) || istype(A, /obj/item/ammo_box/a762)) && !bolt_locked) to_chat(user, "The bolt is closed!") return return ..() @@ -44,6 +47,14 @@ . = ..() . += "The bolt is [bolt_locked ? "open" : "closed"]." +/obj/item/gun/ballistic/rifle/shoot_live_shot(mob/living/user, pointblank, atom/pbtarget, message) + if(sawn_off == TRUE) + if(!is_wielded) + recoil = 5 + else + recoil = SAWN_OFF_RECOIL + . = ..() + /////////////////////// // BOLT ACTION RIFLE // /////////////////////// @@ -53,6 +64,10 @@ desc = "This piece of junk looks like something that could have been used 700 years ago. It feels slightly moist." icon_state = "moistnugget" item_state = "moistnugget" + can_sawoff = TRUE + sawn_name = "\improper Mosin Obrez" + sawn_desc = "A hand cannon of a rifle, try not to break your wrists." + sawn_item_state = "halfnugget" slot_flags = ITEM_SLOT_BACK mag_type = /obj/item/ammo_box/magazine/internal/boltaction can_bayonet = TRUE @@ -61,9 +76,20 @@ w_class = WEIGHT_CLASS_BULKY weapon_weight = WEAPON_HEAVY +/obj/item/gun/ballistic/rifle/boltaction/sawoff(mob/user) + . = ..() + //Has 25 bonus spread due to sawn-off accuracy penalties + if (.) + //Wild spread only applies to innate and unwielded spread + spread = 10 + wild_spread = TRUE + wild_factor = 0.5 + weapon_weight = WEAPON_MEDIUM + /obj/item/gun/ballistic/rifle/boltaction/enchanted name = "enchanted bolt action rifle" desc = "Careful not to lose your head." + can_sawoff = FALSE var/guns_left = 30 mag_type = /obj/item/ammo_box/magazine/internal/boltaction/enchanted diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index af68f2328bf7d..3055a7e4f9a4c 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -46,25 +46,15 @@ icon_state = "riotshotgun" item_state = "shotgun" mag_type = /obj/item/ammo_box/magazine/internal/shot/riot + can_sawoff = TRUE sawn_desc = "Come with me if you want to live." -/obj/item/gun/ballistic/shotgun/riot/attackby(obj/item/A, mob/user, params) - ..() - if(istype(A, /obj/item/circular_saw) || istype(A, /obj/item/gun/energy/plasmacutter)) - sawoff(user) - if(istype(A, /obj/item/melee/transforming/energy)) - var/obj/item/melee/transforming/energy/W = A - if(W.active) - sawoff(user) - // Automatic Shotguns// /obj/item/gun/ballistic/shotgun/automatic weapon_weight = WEAPON_HEAVY - -/obj/item/gun/ballistic/shotgun/automatic/shoot_live_shot(mob/living/user, pointblank = 0, atom/pbtarget = null, message = 1) - ..() - rack() + semi_auto = TRUE + casing_ejector = TRUE /obj/item/gun/ballistic/shotgun/automatic/combat name = "combat shotgun" @@ -74,6 +64,19 @@ mag_type = /obj/item/ammo_box/magazine/internal/shot/com w_class = WEIGHT_CLASS_HUGE +/obj/item/gun/ballistic/shotgun/automatic/combat/AltClick(mob/user) + if(loc == user) + if(!user.is_holding(src)) + return + semi_auto = !semi_auto + playsound(src, 'sound/weapons/effects/ballistic_click.ogg', 20, FALSE) + to_chat(user, "You toggle \the [src] to [semi_auto ? "automatic" : "manual"] operation.") + +/obj/item/gun/ballistic/shotgun/automatic/combat/examine(mob/user) + . = ..() + . += "You can select the firing mode with alt+click" + . += "It is operating in [semi_auto ? "automatic" : "manual"] mode." + /obj/item/gun/ballistic/shotgun/automatic/combat/compact name = "compact combat shotgun" desc = "A compact version of the semi automatic combat shotgun. For close encounters." @@ -108,7 +111,7 @@ w_class = WEIGHT_CLASS_HUGE var/toggled = FALSE var/obj/item/ammo_box/magazine/internal/shot/alternate_magazine - semi_auto = TRUE + //semi_auto = TRUE /obj/item/gun/ballistic/shotgun/automatic/dual_tube/examine(mob/user) . = ..() @@ -143,7 +146,7 @@ // Bulldog shotgun // -/obj/item/gun/ballistic/shotgun/bulldog +/obj/item/gun/ballistic/shotgun/automatic/bulldog name = "\improper Bulldog Shotgun" desc = "A semi-auto, mag-fed shotgun for combat in narrow corridors with a built in recoil dampening system, nicknamed 'Bulldog' by boarding parties. Compatible only with specialized 8-round drum magazines." icon_state = "bulldog" @@ -155,8 +158,6 @@ w_class = WEIGHT_CLASS_NORMAL weapon_weight = WEAPON_MEDIUM mag_type = /obj/item/ammo_box/magazine/m12g - can_suppress = FALSE - burst_size = 1 fire_delay = 0 pin = /obj/item/firing_pin/implant/pindicate spread_unwielded = 15 @@ -165,7 +166,6 @@ empty_indicator = TRUE empty_alarm = TRUE special_mags = TRUE - semi_auto = TRUE internal_magazine = FALSE tac_reloads = TRUE fire_rate = 2 @@ -174,7 +174,7 @@ bolt_type = BOLT_TYPE_STANDARD //Not using a pump full_auto = TRUE -/obj/item/gun/ballistic/shotgun/bulldog/unrestricted +/obj/item/gun/ballistic/shotgun/automatic/bulldog/unrestricted pin = /obj/item/firing_pin ///////////////////////////// // DOUBLE BARRELED SHOTGUN // @@ -191,6 +191,7 @@ flags_1 = CONDUCT_1 slot_flags = ITEM_SLOT_BACK mag_type = /obj/item/ammo_box/magazine/internal/shot/dual + can_sawoff = TRUE sawn_desc = "Omar's coming!" obj_flags = UNIQUE_RENAME rack_sound_volume = 0 @@ -227,15 +228,6 @@ ) . = ..() -/obj/item/gun/ballistic/shotgun/doublebarrel/attackby(obj/item/A, mob/user, params) - ..() - if(istype(A, /obj/item/melee/transforming/energy)) - var/obj/item/melee/transforming/energy/W = A - if(W.active) - sawoff(user) - if(istype(A, /obj/item/circular_saw) || istype(A, /obj/item/gun/energy/plasmacutter)) - sawoff(user) - // IMPROVISED SHOTGUN // /obj/item/gun/ballistic/shotgun/doublebarrel/improvised @@ -255,6 +247,9 @@ /obj/item/gun/ballistic/shotgun/doublebarrel/improvised/attackby(obj/item/A, mob/user, params) ..() if(istype(A, /obj/item/stack/cable_coil) && !sawn_off) + if(slung) + to_chat(user, "There is already a sling on [src]!") + return var/obj/item/stack/cable_coil/C = A if(C.use(10)) slot_flags = ITEM_SLOT_BACK @@ -273,9 +268,14 @@ . = ..() if(. && slung) //sawing off the gun removes the sling new /obj/item/stack/cable_coil(get_turf(src), 10) - slung = 0 + slung = FALSE update_icon() +/obj/item/gun/ballistic/shotgun/doublebarrel/improvised/examine(mob/user) + . = ..() + if (slung) + . += "It has a shoulder sling fashioned from spare wiring attached." + /obj/item/gun/ballistic/shotgun/doublebarrel/improvised/sawn name = "sawn-off improvised shotgun" desc = "A single-shot shotgun. Better not miss." @@ -295,6 +295,7 @@ mag_type = /obj/item/ammo_box/magazine/internal/shot/bounty w_class = WEIGHT_CLASS_BULKY weapon_weight = WEAPON_MEDIUM + can_sawoff = FALSE force = 10 //it has a hook on it attack_verb = list("slashed", "hooked", "stabbed") hitsound = 'sound/weapons/bladeslice.ogg' diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 5febba8c47753..959adc7d8b3b6 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -190,7 +190,7 @@ ..() if(!automatic_charge_overlays) return - var/ratio = CEILING(CLAMP(cell.charge / cell.maxcharge, 0, 1) * charge_sections, 1) + var/ratio = CEILING(clamp(cell.charge / cell.maxcharge, 0, 1) * charge_sections, 1) //Display no power if EMPed if(obj_flags & OBJ_EMPED) ratio = 0 @@ -257,11 +257,11 @@ return(FIRELOSS) else user.visible_message("[user] panics and starts choking to death!") - return(OXYLOSS) + return OXYLOSS else user.visible_message("[user] is pretending to melt [user.p_their()] face off with [src]! It looks like [user.p_theyre()] trying to commit suicide!") playsound(src, dry_fire_sound, 30, TRUE) - return (OXYLOSS) + return OXYLOSS /obj/item/gun/energy/vv_edit_var(var_name, var_value) diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index a298f8e133086..aa6973956383a 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -86,14 +86,14 @@ if(!holds_charge) empty() -/obj/item/gun/energy/kinetic_accelerator/shoot_live_shot() +/obj/item/gun/energy/kinetic_accelerator/shoot_live_shot(mob/user) . = ..() - attempt_reload() + attempt_reload(user) /obj/item/gun/energy/kinetic_accelerator/equipped(mob/user) . = ..() if(!can_shoot()) - attempt_reload() + attempt_reload(user) /obj/item/gun/energy/kinetic_accelerator/dropped() ..() @@ -111,7 +111,7 @@ cell.use(cell.charge) update_icon() -/obj/item/gun/energy/kinetic_accelerator/proc/attempt_reload(recharge_time) +/obj/item/gun/energy/kinetic_accelerator/proc/attempt_reload(mob/user, recharge_time) if(!cell) return if(overheat) @@ -130,8 +130,11 @@ else carried = 1 - deltimer(recharge_timerid) + // If we are overriding a crosshair, then clear it + if (deltimer(recharge_timerid)) + user?.client.clear_cooldown_cursor() recharge_timerid = addtimer(CALLBACK(src, PROC_REF(reload)), recharge_time * carried, TIMER_STOPPABLE) + user?.client?.give_cooldown_cursor(recharge_time * carried + 1) /obj/item/gun/energy/kinetic_accelerator/proc/reload() cell.give(cell.maxcharge) @@ -431,7 +434,7 @@ valid_repeat = TRUE if(valid_repeat) KA.overheat = FALSE - KA.attempt_reload(KA.overheat_time * 0.25) //If you hit, the cooldown drops to 0.75 seconds. + KA.attempt_reload(K.firer, KA.overheat_time * 0.25) //If you hit, the cooldown drops to 0.75 seconds. /obj/item/borg/upgrade/modkit/lifesteal name = "lifesteal crystal" diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm index ac91d2be593bd..0a8f988dde6c5 100644 --- a/code/modules/projectiles/guns/magic.dm +++ b/code/modules/projectiles/guns/magic.dm @@ -92,10 +92,10 @@ /obj/item/gun/magic/shoot_with_empty_chamber(mob/living/user as mob|obj) to_chat(user, "The [name] whizzles quietly.") -/obj/item/gun/magic/suicide_act(mob/user) +/obj/item/gun/magic/suicide_act(mob/living/user) user.visible_message("[user] is twisting [src] above [user.p_their()] head, releasing a magical blast! It looks like [user.p_theyre()] trying to commit suicide!") playsound(loc, fire_sound, 50, 1, -1) - return (FIRELOSS) + return FIRELOSS /obj/item/gun/magic/vv_edit_var(var_name, var_value) . = ..() diff --git a/code/modules/projectiles/guns/misc/beam_rifle.dm b/code/modules/projectiles/guns/misc/beam_rifle.dm index 9c8e43da53cb0..d81f15dcb0cc2 100644 --- a/code/modules/projectiles/guns/misc/beam_rifle.dm +++ b/code/modules/projectiles/guns/misc/beam_rifle.dm @@ -317,7 +317,7 @@ AC.sync_stats() /obj/item/gun/energy/beam_rifle/proc/delay_penalty(amount) - aiming_time_left = CLAMP(aiming_time_left + amount, 0, aiming_time) + aiming_time_left = clamp(aiming_time_left + amount, 0, aiming_time) /obj/item/ammo_casing/energy/beam_rifle name = "particle acceleration lens" @@ -368,11 +368,11 @@ HS_BB.stun = projectile_stun HS_BB.impact_structure_damage = impact_structure_damage HS_BB.aoe_mob_damage = aoe_mob_damage - HS_BB.aoe_mob_range = CLAMP(aoe_mob_range, 0, 15) //Badmin safety lock + HS_BB.aoe_mob_range = clamp(aoe_mob_range, 0, 15) //Badmin safety lock HS_BB.aoe_fire_chance = aoe_fire_chance HS_BB.aoe_fire_range = aoe_fire_range HS_BB.aoe_structure_damage = aoe_structure_damage - HS_BB.aoe_structure_range = CLAMP(aoe_structure_range, 0, 15) //Badmin safety lock + HS_BB.aoe_structure_range = clamp(aoe_structure_range, 0, 15) //Badmin safety lock HS_BB.wall_devastate = wall_devastate HS_BB.wall_pierce_amount = wall_pierce_amount HS_BB.structure_pierce_amount = structure_piercing diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index a5bde41f37348..86973b9ec8cdb 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -61,7 +61,7 @@ var/phasing_ignore_direct_target = FALSE /// Bitflag for things the projectile should just phase through entirely - No hitting unless direct target and [phasing_ignore_direct_target] is FALSE. Uses pass_flags flags. var/projectile_phasing = NONE - /// Bitflag for things the projectile should hit, but pierce through without deleting itself. Defers to projectile_phasing. Uses pass_flags flags. + /// Bitflag for things the projectile should hit, but pierce through without deleting itself. Considered before just purely phasing. Uses pass_flags flags. var/projectile_piercing = NONE /// number of times we've pierced something. Incremented BEFORE bullet_act and on_hit proc! var/pierces = 0 @@ -288,7 +288,7 @@ /obj/projectile/proc/vol_by_damage() if(src.damage) - return CLAMP((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then CLAMP the value between 30 and 100 + return clamp((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100 else return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume @@ -570,10 +570,10 @@ * Return PROJECTILE_DELETE_WITHOUT_HITTING to delete projectile without hitting at all! */ /obj/projectile/proc/prehit_pierce(atom/A) - if((projectile_phasing & A.pass_flags_self) && (!phasing_ignore_direct_target || original != A)) - return PROJECTILE_PIERCE_PHASE if(projectile_piercing & A.pass_flags_self) return PROJECTILE_PIERCE_HIT + if((projectile_phasing & A.pass_flags_self) && (!phasing_ignore_direct_target || original != A)) + return PROJECTILE_PIERCE_PHASE if(ismovable(A)) var/atom/movable/AM = A if(AM.throwing) @@ -656,7 +656,7 @@ stack_trace("WARNING: Projectile [type] deleted due to being unable to resolve a target after angle was null!") qdel(src) return - var/turf/target = locate(CLAMP(starting + xo, 1, world.maxx), CLAMP(starting + yo, 1, world.maxy), starting.z) + var/turf/target = locate(clamp(starting + xo, 1, world.maxx), clamp(starting + yo, 1, world.maxy), starting.z) setAngle(get_angle(src, target)) original_angle = Angle if(!nondirectional_sprite) @@ -789,10 +789,10 @@ if(!homing_target) return FALSE var/datum/point/PT = RETURN_PRECISE_POINT(homing_target) - PT.x += CLAMP(homing_offset_x, 1, world.maxx) - PT.y += CLAMP(homing_offset_y, 1, world.maxy) + PT.x += clamp(homing_offset_x, 1, world.maxx) + PT.y += clamp(homing_offset_y, 1, world.maxy) var/angle = closer_angle_difference(Angle, angle_between_points(RETURN_PRECISE_POINT(src), PT)) - setAngle(Angle + CLAMP(angle, -homing_turn_speed, homing_turn_speed)) + setAngle(Angle + clamp(angle, -homing_turn_speed, homing_turn_speed)) /obj/projectile/proc/set_homing_target(atom/A) if(!A || (!isturf(A) && !isturf(A.loc))) diff --git a/code/modules/projectiles/projectile/bullets/revolver.dm b/code/modules/projectiles/projectile/bullets/revolver.dm index 5e5e877f92f63..9ff042723fa56 100644 --- a/code/modules/projectiles/projectile/bullets/revolver.dm +++ b/code/modules/projectiles/projectile/bullets/revolver.dm @@ -2,7 +2,8 @@ /obj/projectile/bullet/n762 name = "7.62x38mmR bullet" - damage = 60 + damage = 55 + armour_penetration = 12 // .50AE (Desert Eagle) diff --git a/code/modules/projectiles/projectile/bullets/rifle.dm b/code/modules/projectiles/projectile/bullets/rifle.dm index a60f1a3ae64fb..92f0ef7f65ac7 100644 --- a/code/modules/projectiles/projectile/bullets/rifle.dm +++ b/code/modules/projectiles/projectile/bullets/rifle.dm @@ -8,7 +8,8 @@ /obj/projectile/bullet/a762 name = "7.62 bullet" - damage = 60 + damage = 40 + armour_penetration = 30 /obj/projectile/bullet/a762_enchanted name = "enchanted 7.62 bullet" diff --git a/code/modules/projectiles/projectile/energy/accelerator_particle.dm b/code/modules/projectiles/projectile/energy/accelerator_particle.dm index 5654d62869fce..328c56c543ede 100644 --- a/code/modules/projectiles/projectile/energy/accelerator_particle.dm +++ b/code/modules/projectiles/projectile/energy/accelerator_particle.dm @@ -5,7 +5,7 @@ range = 10 speed = 1 projectile_piercing = PASSMOB | PASSANOMALY | PASSMACHINE - projectile_phasing = (ALL & (~PASSMOB) & (~PASSBLOB) & (~PASSANOMALY) & (~PASSMACHINE)) + projectile_phasing = (ALL & ~(PASSMOB | PASSBLOB | PASSANOMALY | PASSMACHINE)) suppressed = SUPPRESSED_VERY //we don't want every machine that gets hit to spam chat hitsound = null irradiate = 60 diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index bddd7878e4d8b..91bd35daf915d 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -601,7 +601,7 @@ var/mob/dead/observer/C = pick(candidates) to_chat(M, "You have been noticed by a ghost, and it has possessed you!") var/oldkey = M.key - M.ghostize(0) + M.ghostize(FALSE) M.key = C.key trauma.friend.key = oldkey trauma.friend.reset_perspective(null) diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index ed01d09278635..5b47029c4b827 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -631,7 +631,7 @@ /datum/reagents/proc/adjust_thermal_energy(J, min_temp = 2.7, max_temp = 1000) var/S = specific_heat() - chem_temp = CLAMP(chem_temp + (J / (S * total_volume)), 2.7, 1000) + chem_temp = clamp(chem_temp + (J / (S * total_volume)), 2.7, 1000) /datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = 300, no_react = 0) if(!isnum_safe(amount) || !amount) @@ -722,7 +722,7 @@ if (R.type == reagent) //clamp the removal amount to be between current reagent amount //and zero, to prevent removing more than the holder has stored - amount = CLAMP(amount, 0, R.volume) + amount = clamp(amount, 0, R.volume) R.volume -= amount update_total() if(!safety)//So it does not handle reactions when it need not to diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 053c3ad5db322..e5380697512c5 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -1,7 +1,7 @@ #define REM REAGENTS_EFFECT_MULTIPLIER #define METABOLITE_RATE 0.5 // How much of a reagent is converted metabolites if one is defined #define MAX_METABOLITES 15 // The maximum amount of a given metabolite someone can have at a time -#define METABOLITE_PENALTY(path) clamp(M.reagents.get_reagent_amount(path)/2.5, 1, 5) //Ranges from 1 to 5 depending on level of metabolites. +#define METABOLITE_PENALTY(path) clamp(M.reagents.get_reagent_amount(path)/2.5, 1, 5) //Ranges from 1 to 5 depending on level of metabolites. GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) @@ -55,7 +55,7 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) return FALSE if(method == VAPOR) //smoke, foam, spray if(M.reagents) - var/modifier = CLAMP((1 - touch_protection), 0, 1) + var/modifier = clamp((1 - touch_protection), 0, 1) var/amount = round(reac_volume*modifier, 0.1) if(amount >= 0.5) M.reagents.add_reagent(type, amount) diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 3557adc89aefd..fc238727f552b 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -1139,7 +1139,7 @@ All effects don't start immediately, but rather get worse over time; the rate is var/datum/antagonist/changeling/changeling = M.mind.has_antag_datum(/datum/antagonist/changeling) if(changeling) changeling.chem_charges += metabolization_rate - changeling.chem_charges = CLAMP(changeling.chem_charges, 0, changeling.chem_storage) + changeling.chem_charges = clamp(changeling.chem_charges, 0, changeling.chem_storage) return ..() /datum/reagent/consumable/ethanol/irishcarbomb diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index d27ea83e154d5..fa4ebdd48ec5c 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -897,6 +897,9 @@ chem_flags = CHEMICAL_RNG_BOTANY quality = DRINK_NICE taste_description = "chocolate milk" + glass_icon_state = null // Overrides white glass inherited from normal milk + glass_name = "glass of chocolate milk" + glass_desc = "Brown and delicious goodness!" /datum/reagent/consumable/menthol name = "Menthol" diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index 40b4f3ed936fd..e14aae5324add 100755 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -667,6 +667,20 @@ M.adjust_nutrition(-3*nutriment_factor) ..() +/datum/reagent/consumable/maltodextrin + name = "Maltodextrin" + description = "A common filler found in processed foods. Leaves you feeling full without providing substantial nutritional value." + color = "#ffffff" + chem_flags = CHEMICAL_RNG_GENERAL + taste_mult = 0.1 // Taste the salt and sugar not the cheap carbs + taste_description = "processed goodness" + nutriment_factor = 0 // Actual nutriment provided by other reagents + metabolization_rate = 0.075 * REAGENTS_METABOLISM + +/datum/reagent/consumable/maltodextrin/on_mob_end_metabolize(mob/living/M) + M.adjust_nutrition(current_cycle*-0.7) + ..() + ////Lavaland Flora Reagents//// diff --git a/code/modules/reagents/chemistry/reagents/log.txt b/code/modules/reagents/chemistry/reagents/log.txt new file mode 100644 index 0000000000000..9c361768a4e9e --- /dev/null +++ b/code/modules/reagents/chemistry/reagents/log.txt @@ -0,0 +1,6 @@ +02:47:01 [mob_243] (168,154,2) || Anna Polson has been dusted by the supermatter crystal.
+02:47:01 [mob_243] (168,154,2) || Anna Polson has died at (Supermatter Engine (168, 154, 2)).
BRUTE: 0 BURN: 0 TOX: 0 OXY: 0 CLONE: 0 STAM: 0
Brain damage: 0
Blood volume: 560cl (100%)
Reagents:
Blood:
+02:55:35 [mob_252] (141,126,2) || Anna Polson (as Central Command) has died at (Bar (141, 126, 2)).
BRUTE: 97 BURN: 0 TOX: 0 OXY: 0 CLONE: 0 STAM: 0
Brain damage: 0
Blood volume: 560cl (100%)
Reagents:
Blood:
79.6 units of Nutriment
42.8 units of Mint Toxin
+02:56:38 [mob_255] (107,143,2) || Central Command has died at (Central Primary Hallway (107, 143, 2)).
BRUTE: 160 BURN: 0 TOX: 0 OXY: 66.7 CLONE: 0 STAM: 0
Brain damage: 0
Blood volume: 555.84cl (99.3%)
Reagents:
Blood:
+02:56:38 [mob_255] (107,143,2) || Central Command has succumbed to death.
+ diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index d67f678e080d6..e72c87d0575e3 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -2075,9 +2075,9 @@ /datum/reagent/peaceborg/confuse/on_mob_life(mob/living/carbon/M) if(M.confused < 6) - M.confused = CLAMP(M.confused + 3, 0, 5) + M.confused = clamp(M.confused + 3, 0, 5) if(M.dizziness < 6) - M.dizziness = CLAMP(M.dizziness + 3, 0, 5) + M.dizziness = clamp(M.dizziness + 3, 0, 5) if(prob(20)) to_chat(M, "You feel confused and disorientated.") ..() diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 8e2ec12a2d201..e603217b92b76 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -127,6 +127,7 @@ /datum/reagent/toxin/minttoxin/on_mob_life(mob/living/carbon/M) if(HAS_TRAIT_FROM(M, TRAIT_FAT, OBESITY)) M.client?.give_award(/datum/award/achievement/misc/mintgib, M) + M.investigate_log("has been gibbed by consuming [src] while fat.", INVESTIGATE_DEATHS) M.gib() return ..() diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index 57609f04879f9..2d1c3f947c43d 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -214,7 +214,7 @@ return holder.remove_reagent(/datum/reagent/sorium, created_volume*4) var/turf/T = get_turf(holder.my_atom) - var/range = CLAMP(sqrt(created_volume*4), 1, 6) + var/range = clamp(sqrt(created_volume*4), 1, 6) goonchem_vortex(T, 1, range) /datum/chemical_reaction/sorium_vortex @@ -225,7 +225,7 @@ /datum/chemical_reaction/sorium_vortex/on_reaction(datum/reagents/holder, created_volume) var/turf/T = get_turf(holder.my_atom) - var/range = CLAMP(sqrt(created_volume), 1, 6) + var/range = clamp(sqrt(created_volume), 1, 6) goonchem_vortex(T, 1, range) /datum/chemical_reaction/liquid_dark_matter @@ -239,7 +239,7 @@ return holder.remove_reagent(/datum/reagent/liquid_dark_matter, created_volume*3) var/turf/T = get_turf(holder.my_atom) - var/range = CLAMP(sqrt(created_volume*3), 1, 6) + var/range = clamp(sqrt(created_volume*3), 1, 6) goonchem_vortex(T, 0, range) /datum/chemical_reaction/ldm_vortex @@ -250,7 +250,7 @@ /datum/chemical_reaction/ldm_vortex/on_reaction(datum/reagents/holder, created_volume) var/turf/T = get_turf(holder.my_atom) - var/range = CLAMP(sqrt(created_volume/2), 1, 6) + var/range = clamp(sqrt(created_volume/2), 1, 6) goonchem_vortex(T, 0, range) /datum/chemical_reaction/flash_powder diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 34b008465ea10..d8d07bda23061 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -121,7 +121,7 @@ if(total_reagent_weight && amount_of_reagents) //don't bother if the container is empty - DIV/0 var/average_reagent_weight = total_reagent_weight / amount_of_reagents - spray_range = CLAMP(round((initial(spray_range) / average_reagent_weight) - ((amount_of_reagents - 1) * 1)), 3, 5) //spray distance between 3 and 5 tiles rounded down; extra reagents lose a tile + spray_range = clamp(round((initial(spray_range) / average_reagent_weight) - ((amount_of_reagents - 1) * 1)), 3, 5) //spray distance between 3 and 5 tiles rounded down; extra reagents lose a tile else spray_range = initial(spray_range) if(stream_mode == 0) @@ -136,7 +136,7 @@ amount_per_transfer_from_this = 2 stream_amount = 5 -/obj/item/reagent_containers/spray/cleaner/suicide_act(mob/user) +/obj/item/reagent_containers/spray/cleaner/suicide_act(mob/living/user) user.visible_message("[user] is putting the nozzle of \the [src] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide!") if(do_after(user, 3 SECONDS)) if(reagents.total_volume >= amount_per_transfer_from_this)//if not empty diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 6a38973430692..4e87c99db3e7d 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -200,7 +200,7 @@ cut_overlays() var/rounded_vol if(reagents?.total_volume) - rounded_vol = CLAMP(round((reagents.total_volume / volume * 15),5), 1, 15) + rounded_vol = clamp(round((reagents.total_volume / volume * 15),5), 1, 15) var/image/filling_overlay = mutable_appearance('icons/obj/reagentfillings.dmi', "syringe[rounded_vol]") filling_overlay.color = mix_color_from_reagents(reagents.reagent_list) add_overlay(filling_overlay) diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 3d97ac577c1d7..1c60282c71880 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -65,8 +65,8 @@ reagent_id = /datum/reagent/fuel /obj/structure/reagent_dispensers/fueltank/boom() - var/light_explosion_range = CLAMP(round(reagents.get_reagent_amount(/datum/reagent/fuel)/200, 1), 1, 5) //explosion range should decrease when there is less fuel in the tank - var/flame_explosion_range = CLAMP(light_explosion_range + 1, 1, 5) //Fire explosion is always one bigger than light explosion + var/light_explosion_range = clamp(round(reagents.get_reagent_amount(/datum/reagent/fuel)/200, 1), 1, 5) //explosion range should decrease when there is less fuel in the tank + var/flame_explosion_range = clamp(light_explosion_range + 1, 1, 5) //Fire explosion is always one bigger than light explosion var/heavy_explosion_range = round(light_explosion_range/5, 1) //if there is less than 500 fuel in the tank, no heavy explosion explosion(get_turf(src), 0, heavy_explosion_range, light_explosion_range, flame_range = flame_explosion_range) qdel(src) diff --git a/code/modules/research/designs/electronics_designs.dm b/code/modules/research/designs/electronics_designs.dm index 83bf900dee9a2..f289307d61293 100644 --- a/code/modules/research/designs/electronics_designs.dm +++ b/code/modules/research/designs/electronics_designs.dm @@ -46,6 +46,16 @@ category = list("Electronics") departmental_flags = DEPARTMENTAL_FLAG_SCIENCE +/datum/design/nanite_comm_remote + name = "Nanite Communication Remote" + desc = "Allows for the construction of a nanite communication remote." + id = "nanite_comm_remote" + build_type = PROTOLATHE + materials = list(/datum/material/glass = 500, /datum/material/iron = 500, /datum/material/copper = 200) + build_path = /obj/item/nanite_remote/comm + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + /datum/design/nanite_scanner name = "Nanite Scanner" desc = "Allows for the construction of a nanite scanner." diff --git a/code/modules/research/designs/nanite_designs.dm b/code/modules/research/designs/nanite_designs.dm index 566fb5e5de933..ef9eb1e109f8c 100644 --- a/code/modules/research/designs/nanite_designs.dm +++ b/code/modules/research/designs/nanite_designs.dm @@ -60,6 +60,13 @@ program_type = /datum/nanite_program/dermal_button category = list("Utility Nanites") +/datum/design/nanites/dermal_toggle + name = "Dermal Toggle" + desc = "Displays a switch on the host's skin, which can be used to send a signal to the nanites." + id = "dermal_toggle_nanites" + program_type = /datum/nanite_program/dermal_button/toggle + category = list("Utility Nanites") + /datum/design/nanites/stealth name = "Stealth" desc = "The nanites hide their activity and programming from superficial scans." @@ -128,11 +135,25 @@ /datum/design/nanites/mitosis name = "Mitosis" desc = "The nanites gain the ability to self-replicate, using bluespace to power the process, instead of drawing from a template. This rapidly speeds up the replication rate,\ - but it causes occasional software errors due to faulty copies. Not compatible with cloud sync." + but it causes occasional software errors due to faulty copies." id = "mitosis_nanites" program_type = /datum/nanite_program/mitosis category = list("Utility Nanites") +/datum/design/nanites/signaler + name = "Remote Signaler" + desc = "The nanites send a pulse to all remote signalers on a given frequency and code." + id = "remote_signal_nanites" + program_type = /datum/nanite_program/signaler + category = list("Utility Nanites") + +/datum/design/nanites/vampire + name = "Vampiric Synthesis" + desc = "The nanites can consume the host's blood in order to replicate much faster. Does not have a built-in safety limiter." + id = "vampire_nanites" + program_type = /datum/nanite_program/vampire + category = list("Utility Nanites") + ////////////////////MEDICAL NANITES////////////////////////////////////// /datum/design/nanites/regenerative name = "Accelerated Regeneration" @@ -396,6 +417,13 @@ program_type = /datum/nanite_program/haste category = list("Weaponized Nanites") +/datum/design/nanites/armblade + name = "Nanite Blade" + desc = "The nanites form a sharp blade around the user's arm when activated." + id = "armblade_nanites" + program_type = /datum/nanite_program/armblade + category = list("Weaponized Nanites") + ////////////////////SUPPRESSION NANITES////////////////////////////////////// /datum/design/nanites/shock @@ -539,3 +567,85 @@ id = "sensor_species_nanites" program_type = /datum/nanite_program/sensor/species category = list("Sensor Nanites") + +/datum/design/nanites/sensor_nutrition + name = "Nutrition Sensor" + desc = "The nanites receive a signal when the host's nutrition level is above/below a certain percentage." + id = "sensor_nutrition_nanites" + program_type = /datum/nanite_program/sensor/nutrition + category = list("Sensor Nanites") + +/datum/design/nanites/sensor_blood + name = "Blood Sensor" + desc = "The nanites receive a signal when the host's blood level is above/below a certain percentage." + id = "sensor_blood_nanites" + program_type = /datum/nanite_program/sensor/blood + category = list("Sensor Nanites") + +/datum/design/nanites/sensor_receiver + name = "Remote Signal Receiver" + desc = "The nanites receive signals from remote signalers, and translate them into nanite signals." + id = "sensor_receiver_nanites" + program_type = /datum/nanite_program/sensor/receiver + category = list("Sensor Nanites") + + +////////////////////NANITE PROTOCOLS////////////////////////////////////// +//Note about the category name: The UI cuts the last 8 characters from the category name to remove the " Nanites" in the other categories +//Because of this, Protocols was getting cut down to "P", so i had to add some padding +/datum/design/nanites/kickstart + name = "Kickstart Protocol" + desc = "Replication Protocol: the nanites focus on early growth, heavily boosting replication rate for a few minutes after the initial implantation." + id = "kickstart_nanites" + program_type = /datum/nanite_program/protocol/kickstart + category = list("Protocols_Nanites") + +/datum/design/nanites/factory + name = "Factory Protocol" + desc = "Replication Protocol: the nanites build a factory matrix within the host, gradually increasing replication speed over time. The factory decays if the protocol is not active." + id = "factory_nanites" + program_type = /datum/nanite_program/protocol/factory + category = list("Protocols_Nanites") + +/datum/design/nanites/pyramid + name = "Pyramid Protocol" + desc = "Replication Protocol: the nanites implement an alternate cooperative replication protocol that is more efficient as long as the saturation level is above 80%." + id = "pyramid_nanites" + program_type = /datum/nanite_program/protocol/pyramid + category = list("Protocols_Nanites") + +/datum/design/nanites/offline + name = "Eclipse Protocol" + desc = "Replication Protocol: while the host is asleep or otherwise unconcious, the nanites exploit the reduced interference to replicate more quickly." + id = "offline_nanites" + program_type = /datum/nanite_program/protocol/offline + category = list("Protocols_Nanites") + +/datum/design/nanites/hive + name = "Hive Protocol" + desc = "Storage Protocol: the nanites use a more efficient grid arrangment for volume storage, increasing maximum volume in a host." + id = "hive_nanites" + program_type = /datum/nanite_program/protocol/hive + category = list("Protocols_Nanites") + +/datum/design/nanites/zip + name = "Zip Protocol" + desc = "Storage Protocol: the nanites are disassembled and compacted when unused, greatly increasing the maximum volume while in a host. However, the process slows down the replication rate slightly." + id = "zip_nanites" + program_type = /datum/nanite_program/protocol/zip + category = list("Protocols_Nanites") + +/datum/design/nanites/free_range + name = "Free-range Protocol" + desc = "Storage Protocol: the nanites discard their default storage protocols in favour of a cheaper and more organic approach. Reduces maximum volume, but increases the replication rate." + id = "free_range_nanites" + program_type = /datum/nanite_program/protocol/free_range + category = list("Protocols_Nanites") + +/datum/design/nanites/unsafe_storage + name = "S.L.O. Protocol" + desc = "Storage Protocol: 'S.L.O.P.', or Storage Level Override Protocol, completely disables the safety measures normally present in nanites,\ + allowing them to reach much higher saturation levels, but at the risk of causing internal damage to the host." + id = "unsafe_storage_nanites" + program_type = /datum/nanite_program/protocol/unsafe_storage + category = list("Protocols_Nanites") diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index 07608d3359fa9..029854dd6f647 100644 --- a/code/modules/research/destructive_analyzer.dm +++ b/code/modules/research/destructive_analyzer.dm @@ -85,8 +85,10 @@ Note: Must be placed within 3 tiles of the R&D Console for(var/obj/item/innerthing in food) destroy_item(innerthing, TRUE) reclaim_materials_from(thing) - for(var/mob/M in thing) - M.death() + for(var/mob/living/victim in thing) + if(victim.stat != DEAD) + victim.investigate_log("has been killed by a destructive analyzer.", INVESTIGATE_DEATHS) + victim.death() if(istype(thing, /obj/item/stack/sheet)) var/obj/item/stack/sheet/S = thing if(S.amount > 1 && !innermode) diff --git a/code/modules/research/machinery/_production.dm b/code/modules/research/machinery/_production.dm index d115c4cdcd963..9c52a14d4a802 100644 --- a/code/modules/research/machinery/_production.dm +++ b/code/modules/research/machinery/_production.dm @@ -286,7 +286,7 @@ materials.set_local_size(total_storage) var/total_rating = 1.2 for(var/obj/item/stock_parts/manipulator/M in component_parts) - total_rating = CLAMP(total_rating - (M.rating * 0.1), 0, 1) + total_rating = clamp(total_rating - (M.rating * 0.1), 0, 1) if(total_rating == 0) efficiency_coeff = INFINITY else @@ -348,7 +348,7 @@ say("Mineral access is on hold, please contact the quartermaster.") return FALSE var/power = 1000 - amount = CLAMP(amount, 1, 10) + amount = clamp(amount, 1, 10) for(var/M in D.materials) power += round(D.materials[M] * amount / 35) power = min(3000, power) diff --git a/code/modules/research/nanites/nanite_cloud_controller.dm b/code/modules/research/nanites/nanite_cloud_controller.dm index ca86ce3b9bda4..c577e5616818f 100644 --- a/code/modules/research/nanites/nanite_cloud_controller.dm +++ b/code/modules/research/nanites/nanite_cloud_controller.dm @@ -5,7 +5,11 @@ icon_state = "nanite_cloud_controller" circuit = /obj/item/circuitboard/computer/nanite_cloud_controller - + //these muthafuckas arent supposed to smooth + base_icon_state = null + smoothing_flags = null + smoothing_groups = null + canSmoothWith = null var/obj/item/disk/nanite_program/disk var/list/datum/nanite_cloud_backup/cloud_backups = list() @@ -191,6 +195,7 @@ playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE) cloud_id = clamp(round(cloud_id, 1),1,100) generate_backup(cloud_id, usr) + balloon_alert(usr, "created backup") . = TRUE if("delete_backup") var/datum/nanite_cloud_backup/backup = get_backup(current_view) @@ -198,6 +203,7 @@ playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE) qdel(backup) investigate_log("[key_name(usr)] deleted the nanite cloud backup #[current_view]", INVESTIGATE_NANITES) + balloon_alert(usr, "deleted backup") . = TRUE if("upload_program") if(disk && disk.program) @@ -207,6 +213,7 @@ var/datum/component/nanites/nanites = backup.nanites nanites.add_program(null, disk.program.copy()) investigate_log("[key_name(usr)] uploaded program [disk.program.name] to cloud #[current_view]", INVESTIGATE_NANITES) + balloon_alert(usr, "uploaded program") . = TRUE if("remove_program") var/datum/nanite_cloud_backup/backup = get_backup(current_view) @@ -215,6 +222,7 @@ var/datum/component/nanites/nanites = backup.nanites var/datum/nanite_program/P = nanites.programs[text2num(params["program_id"])] investigate_log("[key_name(usr)] deleted program [P.name] from cloud #[current_view]", INVESTIGATE_NANITES) + balloon_alert(usr, "removed program") qdel(P) . = TRUE if("add_rule") @@ -228,6 +236,7 @@ var/datum/component/nanites/nanites = backup.nanites var/datum/nanite_program/P = nanites.programs[text2num(params["program_id"])] var/datum/nanite_rule/rule = rule_template.make_rule(P) + balloon_alert(usr, "added rule") investigate_log("[key_name(usr)] added rule [rule.display()] to program [P.name] in cloud #[current_view]", INVESTIGATE_NANITES) . = TRUE @@ -239,9 +248,51 @@ var/datum/nanite_program/P = nanites.programs[text2num(params["program_id"])] var/datum/nanite_rule/rule = P.rules[text2num(params["rule_id"])] rule.remove() + balloon_alert(usr, "removed rule") investigate_log("[key_name(usr)] removed rule [rule.display()] from program [P.name] in cloud #[current_view]", INVESTIGATE_NANITES) . = TRUE + if("combine_rules") + var/datum/nanite_cloud_backup/backup = get_backup(current_view) + if(backup) + playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) + var/datum/component/nanites/nanites = backup.nanites + var/datum/nanite_program/program = nanites.programs[text2num(params["program_id"])] + if(!islist(params["rule_ids"])) + return + if(length(params["rule_ids"]) <= 1) + to_chat(usr, "Warning: you need to combine at least 2 rules.") + balloon_alert(usr, "not enough rules to combine") + return + if(length(params["rule_ids"]) > 5) + to_chat(usr, "Warning: cannot combine more than 5 rules.") + balloon_alert(usr, "too many rules to combine") + return + var/list/datum/nanite_rule/rules_to_copy = list() + var/list/rule_displays = list() + for(var/rule_id in params["rule_ids"]) + var/datum/nanite_rule/rule = program.rules[text2num(rule_id)] + if(!rule) + continue + if(!rule.combinable) + balloon_alert(usr, "rules cannot be combined") + to_chat(usr, "Warning: rule '[rule.display()]' cannot be combined.") + return + rule_displays += rule.display() + rules_to_copy += rule + if(!length(rules_to_copy)) + balloon_alert(usr, "no rules to combine") + to_chat(usr, "Warning: no rules to combine!") + return + var/list/datum/nanite_rule/copied_rules = list() + for(var/R in rules_to_copy) + var/datum/nanite_rule/rule = R + copied_rules += rule.copy_to(program, FALSE) + rule.remove() + new /datum/nanite_rule/combined(program, TRUE, copied_rules, params["op"]) + balloon_alert(usr, "rules combined") + investigate_log("[key_name(usr)] combined rules [english_list(rule_displays)] from program [program.name] in cloud #[current_view]", INVESTIGATE_NANITES) + . = TRUE /datum/nanite_cloud_backup var/cloud_id = 0 diff --git a/code/modules/research/nanites/nanite_misc_items.dm b/code/modules/research/nanites/nanite_misc_items.dm index 6837543d11190..5d7a16cf08118 100644 --- a/code/modules/research/nanites/nanite_misc_items.dm +++ b/code/modules/research/nanites/nanite_misc_items.dm @@ -6,4 +6,5 @@ icon_state = "nanite_remote" /obj/item/nanite_injector/attack_self(mob/user) - user.AddComponent(/datum/component/nanites, 150) + var/cloud_id = tgui_input_number(user, "Input Cloud ID", "Nanite Injector", 1, 99, 1) + user.AddComponent(/datum/component/nanites, 150, cloud_id) diff --git a/code/modules/research/nanites/nanite_programs.dm b/code/modules/research/nanites/nanite_programs.dm index 365f2fc052362..992247e12ee4c 100644 --- a/code/modules/research/nanites/nanite_programs.dm +++ b/code/modules/research/nanites/nanite_programs.dm @@ -11,6 +11,8 @@ var/trigger_cost = 0 //Amount of nanites required to trigger var/trigger_cooldown = 50 //Deciseconds required between each trigger activation var/next_trigger = 0 //World time required for the next trigger activation + var/activate_cooldown = 0 //Deciseconds required between each activation + COOLDOWN_DECLARE(next_activate) var/program_flags = NONE var/passive_enabled = FALSE //If the nanites have an on/off-style effect, it's tracked by this var @@ -173,9 +175,14 @@ deactivate() /datum/nanite_program/proc/activate() + if(!COOLDOWN_FINISHED(src, next_activate)) + deactivate() + return activated = TRUE if(timer_shutdown) timer_shutdown_next = world.time + timer_shutdown + if(activate_cooldown) + COOLDOWN_START(src, next_activate, activate_cooldown) /datum/nanite_program/proc/deactivate() if(passive_enabled) @@ -217,36 +224,38 @@ //If false, disables active and passive effects, but doesn't consume nanites //Can be used to avoid consuming nanites for nothing /datum/nanite_program/proc/check_conditions() - var/datum/nanite_extra_setting/logictype = extra_settings[NES_RULE_LOGIC] - if(logictype) - switch(logictype.get_value()) - if(NL_AND) - for(var/R in rules) - var/datum/nanite_rule/rule = R - if(!rule.check_rule()) - return FALSE - if(NL_OR) - for(var/R in rules) - var/datum/nanite_rule/rule = R - if(rule.check_rule()) - return TRUE - return FALSE - if(NL_NOR) - for(var/R in rules) - var/datum/nanite_rule/rule = R - if(rule.check_rule()) - return FALSE - if(NL_NAND) - for(var/R in rules) - var/datum/nanite_rule/rule = R - if(!rule.check_rule()) - return TRUE - return FALSE - else - for(var/R in rules) - var/datum/nanite_rule/rule = R - if(!rule.check_rule()) - return FALSE + var/rule_amt = length(rules) + if(rule_amt) + var/datum/nanite_extra_setting/logictype = extra_settings[NES_RULE_LOGIC] + if(logictype) + switch(logictype.get_value()) + if(NL_AND) + for(var/R in 1 to min(rule_amt, 5)) + var/datum/nanite_rule/rule = rules[R] + if(!rule.check_rule()) + return FALSE + if(NL_OR) + for(var/R in 1 to min(rule_amt, 5)) + var/datum/nanite_rule/rule = rules[R] + if(rule.check_rule()) + return TRUE + return FALSE + if(NL_NOR) + for(var/R in 1 to min(rule_amt, 5)) + var/datum/nanite_rule/rule = rules[R] + if(rule.check_rule()) + return FALSE + if(NL_NAND) + for(var/R in 1 to min(rule_amt, 5)) + var/datum/nanite_rule/rule = rules[R] + if(!rule.check_rule()) + return TRUE + return FALSE + else + for(var/R in 1 to min(rule_amt, 5)) + var/datum/nanite_rule/rule = rules[R] + if(!rule.check_rule()) + return FALSE return TRUE //Constantly procs as long as the program is active @@ -326,7 +335,7 @@ nanites.add_program(null, rogue, src) qdel(src) -/datum/nanite_program/proc/receive_signal(code, source) +/datum/nanite_program/proc/receive_nanite_signal(code, source) if(activation_code && code == activation_code && !activated) activate() host_mob.investigate_log("'s [name] nanite program was activated by [source] with code [code]. Cloud No.[nanites.cloud_id]", INVESTIGATE_NANITES) diff --git a/code/modules/research/nanites/nanite_programs/buffing.dm b/code/modules/research/nanites/nanite_programs/buffing.dm index 9e4137e079c2a..3a3e0c357cc2c 100644 --- a/code/modules/research/nanites/nanite_programs/buffing.dm +++ b/code/modules/research/nanites/nanite_programs/buffing.dm @@ -137,3 +137,42 @@ to_chat(host_mob, "Your body feels lighter and your legs feel relaxed!") host_mob.set_resting(FALSE) host_mob.reagents.add_reagent(/datum/reagent/medicine/amphetamine, 3) + +/datum/nanite_program/armblade + name = "Nanite Blade" + desc = "The nanites form a sharp blade around the user's arm when activated." + use_rate = 1 + activate_cooldown = 10 SECONDS + rogue_types = list(/datum/nanite_program/necrotic, /datum/nanite_program/skin_decay) + var/obj/item/melee/arm_blade/nanite/blade + +/datum/nanite_program/armblade/enable_passive_effect() + . = ..() + if(blade) + QDEL_NULL(blade) + if(!host_mob) + return + blade = new(host_mob) + host_mob.dropItemToGround(host_mob.get_active_held_item()) + if(!host_mob.put_in_hands(blade)) + to_chat(host_mob, "You feel an intense pain as your nanites fail to form a blade!") + host_mob.adjustBruteLoss(10) + QDEL_NULL(blade) + return + host_mob.visible_message("A metallic blade rapidly forms around [host_mob]'s arm!", "A nanite blade quickly forms around our arm!") + +/datum/nanite_program/armblade/disable_passive_effect() + . = ..() + if(blade) + host_mob.visible_message("The metallic blade around [host_mob]'s arm retracts and dissolves!", "Our nanite blade dissipates.") + QDEL_NULL(blade) + +/obj/item/melee/arm_blade/nanite + name = "metallic armblade" + desc = "Nanites have formed this extremely sharp blade around your arm. Owie." + force = 15 + icon = 'icons/obj/nanite.dmi' + icon_state = "nanite_blade" + item_state = "nanite_blade" + lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' diff --git a/code/modules/research/nanites/nanite_programs/protocol.dm b/code/modules/research/nanites/nanite_programs/protocol.dm new file mode 100644 index 0000000000000..67df9864a5055 --- /dev/null +++ b/code/modules/research/nanites/nanite_programs/protocol.dm @@ -0,0 +1,302 @@ +///A nanite program containing a behaviour protocol. Only one protocol of each class can be active at once. +/datum/nanite_program/protocol + name = "Nanite Protocol" + var/protocol_class = NONE + +/datum/nanite_program/protocol/check_conditions() + . = ..() + for(var/datum/nanite_program/protocol/protocol as anything in nanites.protocols) + if(protocol != src && protocol.activated && protocol.protocol_class == protocol_class) + return FALSE + +/datum/nanite_program/protocol/on_add(datum/component/nanites/_nanites) + ..() + nanites.protocols += src + +/datum/nanite_program/protocol/Destroy() + if(nanites) + nanites.protocols -= src + return ..() + +//Replication Protocols +/datum/nanite_program/protocol/kickstart + name = "Kickstart Protocol" + desc = "Replication Protocol: the nanites focus on early growth, heavily boosting replication rate for a few minutes after the initial implantation, \ + resulting in an additional 420 nanite volume being produced during the first two minutes." + use_rate = 0 + rogue_types = list(/datum/nanite_program/necrotic) + protocol_class = NANITE_PROTOCOL_REPLICATION + var/boost_duration = 2 MINUTES + +/datum/nanite_program/protocol/kickstart/check_conditions() + if(!(world.time < nanites.start_time + boost_duration)) + return FALSE + return ..() + +/datum/nanite_program/protocol/kickstart/active_effect() + nanites.adjust_nanites(amount = 3.5) + + +/datum/nanite_program/protocol/factory + name = "Factory Protocol" + desc = "Replication Protocol: the nanites build a factory matrix within the host, gradually increasing replication speed over time, \ + granting a maximum of 2 additional nanite production after roughly 17 minutes. \ + The factory decays if the protocol is not active, or if the nanites are disrupted by shocks or EMPs." + use_rate = 0 + rogue_types = list(/datum/nanite_program/necrotic) + protocol_class = NANITE_PROTOCOL_REPLICATION + var/factory_efficiency = 0 + var/max_efficiency = 1000 //Goes up to 2 bonus regen per tick after 16 minutes and 40 seconds + +/datum/nanite_program/protocol/factory/on_process() + if(!activated || !check_conditions()) + factory_efficiency = max(0, factory_efficiency - 5) + ..() + +/datum/nanite_program/protocol/factory/on_emp(severity) + ..() + factory_efficiency = max(0, factory_efficiency - 300) + +/datum/nanite_program/protocol/factory/on_shock(shock_damage) + ..() + factory_efficiency = max(0, factory_efficiency - 200) + +/datum/nanite_program/protocol/factory/on_minor_shock() + ..() + factory_efficiency = max(0, factory_efficiency - 100) + +/datum/nanite_program/protocol/factory/active_effect() + factory_efficiency = min(factory_efficiency + 1, max_efficiency) + nanites.adjust_nanites(amount = round(0.002 * factory_efficiency, 0.1)) + + +/datum/nanite_program/protocol/pyramid + name = "Pyramid Protocol" + desc = "Replication Protocol: the nanites implement an alternate cooperative replication protocol that is active as long as the nanite saturation level is above 80%, \ + resulting in an additional volume production of 1.2 per second." + use_rate = 0 + rogue_types = list(/datum/nanite_program/necrotic) + protocol_class = NANITE_PROTOCOL_REPLICATION + var/boost = 1.2 + +/datum/nanite_program/protocol/pyramid/check_conditions() + if((nanites.nanite_volume / nanites.max_nanites) < 0.8) + return FALSE + + return ..() + +/datum/nanite_program/protocol/pyramid/active_effect() + nanites.adjust_nanites(amount = boost) + + +/datum/nanite_program/protocol/offline + name = "Eclipse Protocol" + desc = "Replication Protocol: while the host is asleep or otherwise unconcious, the nanites exploit the reduced interference to replicate more quickly." + use_rate = 0 + rogue_types = list(/datum/nanite_program/necrotic) + protocol_class = NANITE_PROTOCOL_REPLICATION + var/boost = 3 + +/datum/nanite_program/protocol/offline/check_conditions() + if(nanites.host_mob.stat == CONSCIOUS) + return FALSE + return ..() + +/datum/nanite_program/protocol/offline/active_effect() + nanites.adjust_nanites(amount = boost) + + +/datum/nanite_program/protocol/hive + name = "Hive Protocol" + desc = "Storage Protocol: the nanites use a more efficient grid arrangment for volume storage, increasing maximum volume to 750." + use_rate = 0 + rogue_types = list(/datum/nanite_program/necrotic) + protocol_class = NANITE_PROTOCOL_STORAGE + var/extra_volume = 250 + +/datum/nanite_program/protocol/hive/enable_passive_effect() + . = ..() + nanites.set_max_volume(amount = nanites.max_nanites + extra_volume) + +/datum/nanite_program/protocol/hive/disable_passive_effect() + . = ..() + nanites.set_max_volume(amount = nanites.max_nanites - extra_volume) + + +/datum/nanite_program/protocol/zip + name = "Zip Protocol" + desc = "Storage Protocol: the nanites are disassembled and compacted when unused, increasing the maximum volume to 1000. However, the process slows down their replication rate slightly." + use_rate = 0.2 + rogue_types = list(/datum/nanite_program/necrotic) + protocol_class = NANITE_PROTOCOL_STORAGE + var/extra_volume = 500 + +/datum/nanite_program/protocol/zip/enable_passive_effect() + . = ..() + nanites.set_max_volume(amount = nanites.max_nanites + extra_volume) + +/datum/nanite_program/protocol/zip/disable_passive_effect() + . = ..() + nanites.set_max_volume(amount = nanites.max_nanites - extra_volume) + + +/datum/nanite_program/protocol/free_range + name = "Free-range Protocol" + desc = "Storage Protocol: the nanites discard their default storage protocols in favour of a cheaper and more organic approach. Reduces maximum volume to 250, but increases the replication rate by 0.5." + use_rate = 0 + rogue_types = list(/datum/nanite_program/necrotic) + protocol_class = NANITE_PROTOCOL_STORAGE + var/boost = 0.5 + var/extra_volume = -250 + +/datum/nanite_program/protocol/free_range/enable_passive_effect() + . = ..() + nanites.set_max_volume(amount = nanites.max_nanites + extra_volume) + +/datum/nanite_program/protocol/free_range/disable_passive_effect() + . = ..() + nanites.set_max_volume(amount = nanites.max_nanites - extra_volume) + +/datum/nanite_program/protocol/free_range/active_effect() + nanites.adjust_nanites(amount = boost) + + +/datum/nanite_program/protocol/unsafe_storage + name = "S.L.O. Protocol" + desc = "Storage Protocol: 'S.L.O.P.', or Storage Level Override Protocol, completely disables the safety measures normally present in nanites, \ + allowing them to reach a whopping maximum volume level of 2000, but at the risk of causing damage to the host at nanite concentrations above the standard limit of 500." + use_rate = 0 + rogue_types = list(/datum/nanite_program/necrotic) + protocol_class = NANITE_PROTOCOL_STORAGE + var/extra_volume = 1500 + var/next_warning = 0 + var/min_warning_cooldown = 120 + var/max_warning_cooldown = 350 + var/volume_warnings_stage_1 = list("You feel a dull pain in your abdomen.", + "You feel a tickling sensation in your abdomen.") + var/volume_warnings_stage_2 = list("You feel a dull pain in your stomach.", + "You feel a dull pain when breathing.", + "Your stomach grumbles.", + "You feel a tickling sensation in your throat.", + "You feel a tickling sensation in your lungs.", + "You feel a tickling sensation in your stomach.", + "Your lungs feel stiff.") + var/volume_warnings_stage_3 = list("You feel a dull pain in your chest.", + "You hear a faint buzzing coming from nowhere.", + "You hear a faint buzzing inside your head.", + "Your head aches.") + var/volume_warnings_stage_4 = list("You feel a dull pain in your ears.", + "You feel a dull pain behind your eyes.", + "You hear a loud, echoing buzz inside your ears.", + "You feel dizzy.", + "You feel an itch coming from behind your eyes.", + "Your eardrums itch.", + "You see tiny grey motes drifting in your field of view.") + var/volume_warnings_stage_5 = list("You feel sick.", + "You feel a dull pain from every part of your body.", + "You feel nauseous.") + var/volume_warnings_stage_6 = list("Your skin itches and burns.", + "Your muscles ache.", + "You feel tired.", + "You feel something skittering under your skin.",) + +/datum/nanite_program/protocol/unsafe_storage/enable_passive_effect() + . = ..() + nanites.set_max_volume(amount = nanites.max_nanites + extra_volume) + +/datum/nanite_program/protocol/unsafe_storage/disable_passive_effect() + . = ..() + nanites.set_max_volume(amount = nanites.max_nanites - extra_volume) + +/datum/nanite_program/protocol/unsafe_storage/active_effect() + if(!iscarbon(host_mob)) + if(prob(10)) + host_mob.adjustBruteLoss(((max(nanites.nanite_volume - 450, 0) / 450) ** 2 ) * 0.5) // 0.5 -> 2 -> 4.5 -> 8 damage per successful tick + return + + var/mob/living/carbon/C = host_mob + + if(nanites.nanite_volume < 500) + return + + var/current_stage = 0 + if(nanites.nanite_volume > 500) //Liver is the main hub of nanite replication and the first to be threatened by excess volume + if(prob(10)) + var/obj/item/organ/liver/liver = C.getorganslot(ORGAN_SLOT_LIVER) + if(liver) + liver.applyOrganDamage(0.6) + current_stage++ + if(nanites.nanite_volume > 750) //Extra volume spills out in other central organs + if(prob(10)) + var/obj/item/organ/stomach/stomach = C.getorganslot(ORGAN_SLOT_STOMACH) + if(stomach) + stomach.applyOrganDamage(0.75) + if(prob(10)) + var/obj/item/organ/lungs/lungs = C.getorganslot(ORGAN_SLOT_LUNGS) + if(lungs) + lungs.applyOrganDamage(0.75) + current_stage++ + if(nanites.nanite_volume > 1000) //Extra volume spills out in more critical organs + if(prob(10)) + var/obj/item/organ/heart/heart = C.getorganslot(ORGAN_SLOT_HEART) + if(heart) + heart.applyOrganDamage(0.75) + if(prob(10)) + var/obj/item/organ/brain/brain = C.getorganslot(ORGAN_SLOT_BRAIN) + if(brain) + brain.applyOrganDamage(0.75) + current_stage++ + if(nanites.nanite_volume > 1250) //Excess nanites start invading smaller organs for more space, including sensory organs + if(prob(13)) + var/obj/item/organ/eyes/eyes = C.getorganslot(ORGAN_SLOT_EYES) + if(eyes) + eyes.applyOrganDamage(0.75) + if(prob(13)) + var/obj/item/organ/ears/ears = C.getorganslot(ORGAN_SLOT_EARS) + if(ears) + ears.applyOrganDamage(0.75) + current_stage++ + if(nanites.nanite_volume > 1500) //Nanites start spilling into the bloodstream, causing toxicity + if(prob(15)) + C.adjustToxLoss(0.5, TRUE, forced = TRUE) //Not healthy for slimepeople either + current_stage++ + if(nanites.nanite_volume > 1750) //Nanites have almost reached their physical limit, and the pressure itself starts causing tissue damage + if(prob(15)) + C.adjustBruteLoss(0.75, TRUE) + current_stage++ + + volume_warning(current_stage) + +/datum/nanite_program/protocol/unsafe_storage/proc/volume_warning(tier) + if(world.time < next_warning) + return + + var/list/main_warnings + var/list/extra_warnings + + switch(tier) + if(1) + main_warnings = volume_warnings_stage_1 + extra_warnings = null + if(2) + main_warnings = volume_warnings_stage_2 + extra_warnings = volume_warnings_stage_1 + if(3) + main_warnings = volume_warnings_stage_3 + extra_warnings = volume_warnings_stage_1 + volume_warnings_stage_2 + if(4) + main_warnings = volume_warnings_stage_4 + extra_warnings = volume_warnings_stage_1 + volume_warnings_stage_2 + volume_warnings_stage_3 + if(5) + main_warnings = volume_warnings_stage_5 + extra_warnings = volume_warnings_stage_1 + volume_warnings_stage_2 + volume_warnings_stage_3 + volume_warnings_stage_4 + if(6) + main_warnings = volume_warnings_stage_6 + extra_warnings = volume_warnings_stage_1 + volume_warnings_stage_2 + volume_warnings_stage_3 + volume_warnings_stage_4 + volume_warnings_stage_5 + + if(prob(35)) + to_chat(host_mob, "[pick(main_warnings)]") + next_warning = world.time + rand(min_warning_cooldown, max_warning_cooldown) + else if(islist(extra_warnings)) + to_chat(host_mob, "[pick(extra_warnings)]") + next_warning = world.time + rand(min_warning_cooldown, max_warning_cooldown) diff --git a/code/modules/research/nanites/nanite_programs/sensor.dm b/code/modules/research/nanites/nanite_programs/sensor.dm index 3664058f4e89c..dfbecbfb451bb 100644 --- a/code/modules/research/nanites/nanite_programs/sensor.dm +++ b/code/modules/research/nanites/nanite_programs/sensor.dm @@ -328,3 +328,136 @@ rule.mode_rule = mode.get_value() rule.species_name_rule = species_name.get_value() return rule + +/datum/nanite_program/sensor/nutrition + name = "Nutrition Sensor" + desc = "The nanites receive a signal when the host's nutrition is above/below a target percentage." + can_rule = TRUE + var/static/list/possible_nutrition_values = list( + "Fat (100%)" = NUTRITION_LEVEL_FAT, + "Full (90%)" = NUTRITION_LEVEL_FULL, + "Well Fed (75%)" = NUTRITION_LEVEL_WELL_FED, + "Fed (60%)" = NUTRITION_LEVEL_FED, + "Hungry (40%)" = NUTRITION_LEVEL_HUNGRY, + "Starving (25%)" = NUTRITION_LEVEL_STARVING + ) + var/spent = TRUE + +/datum/nanite_program/sensor/nutrition/check_conditions() + return ..() && !HAS_TRAIT(host_mob, TRAIT_NOHUNGER) + +/datum/nanite_program/sensor/nutrition/register_extra_settings() + . = ..() + extra_settings[NES_NUTRITION] = new /datum/nanite_extra_setting/type("Fed (60%)", assoc_to_keys(possible_nutrition_values)) + extra_settings[NES_DIRECTION] = new /datum/nanite_extra_setting/boolean(TRUE, "Above", "Below") + +/datum/nanite_program/sensor/nutrition/check_event() + var/datum/nanite_extra_setting/nutrition = extra_settings[NES_NUTRITION] + var/threshold = possible_nutrition_values[nutrition.get_value()] + var/datum/nanite_extra_setting/direction = extra_settings[NES_DIRECTION] + var/detected = FALSE + if(direction.get_value()) + if(host_mob.nutrition >= threshold) + detected = TRUE + else + if(host_mob.nutrition < threshold) + detected = TRUE + + if(detected) + if(!spent) + spent = TRUE + return TRUE + return FALSE + else + spent = FALSE + return FALSE + +/datum/nanite_program/sensor/nutrition/make_rule(datum/nanite_program/target) + var/datum/nanite_rule/nutrition/rule = new(target) + var/datum/nanite_extra_setting/direction = extra_settings[NES_DIRECTION] + var/datum/nanite_extra_setting/nutrition = extra_settings[NES_NUTRITION] + rule.above = direction.get_value() + rule.threshold = possible_nutrition_values[nutrition.get_value()] + return rule + +/datum/nanite_program/sensor/blood + name = "Blood Sensor" + desc = "The nanites receive a signal when the host's blood level is above/below a target percentage." + can_rule = TRUE + var/spent = FALSE + +/datum/nanite_program/sensor/blood/register_extra_settings() + . = ..() + extra_settings[NES_BLOOD_PERCENT] = new /datum/nanite_extra_setting/number(80, -99, 100, "%") + extra_settings[NES_DIRECTION] = new /datum/nanite_extra_setting/boolean(TRUE, "Above", "Below") + +/datum/nanite_program/sensor/blood/check_conditions() + . = ..() + if(!.) + return FALSE + if(!iscarbon(host_mob)) + return FALSE + if(ishuman(host_mob)) + var/mob/living/carbon/human/host_human = host_mob + if(NOBLOOD in host_human.dna?.species?.species_traits) + return FALSE + +/datum/nanite_program/sensor/blood/check_event() + var/blood_percent = round((host_mob.blood_volume / BLOOD_VOLUME_NORMAL) * 100) + var/datum/nanite_extra_setting/percent = extra_settings[NES_HEALTH_PERCENT] + var/datum/nanite_extra_setting/direction = extra_settings[NES_DIRECTION] + var/detected = FALSE + if(direction.get_value()) + if(blood_percent >= percent.get_value()) + detected = TRUE + else + if(blood_percent < percent.get_value()) + detected = TRUE + + if(detected) + if(!spent) + spent = TRUE + return TRUE + return FALSE + else + spent = FALSE + return FALSE + +/datum/nanite_program/sensor/blood/make_rule(datum/nanite_program/target) + var/datum/nanite_rule/blood/rule = new(target) + var/datum/nanite_extra_setting/direction = extra_settings[NES_DIRECTION] + var/datum/nanite_extra_setting/percent = extra_settings[NES_BLOOD_PERCENT] + rule.above = direction.get_value() + rule.threshold = percent.get_value() + return rule + +/datum/nanite_program/sensor/receiver + name = "Remote Signal Receiver" + desc = "The nanites receive signals from remote signalers, and translate them into nanite signals." + var/datum/radio_frequency/radio_connection + +/datum/nanite_program/sensor/receiver/register_extra_settings() + . = ..() + extra_settings[NES_SIGNAL_FREQUENCY] = new /datum/nanite_extra_setting/number(FREQ_SIGNALER, MIN_FREQ, MAX_FREQ) + extra_settings[NES_SIGNAL_CODE] = new /datum/nanite_extra_setting/number(DEFAULT_SIGNALER_CODE, 1, 99) + extra_settings[NES_SENT_CODE] = new /datum/nanite_extra_setting/number(0, 1, 9999) + +/datum/nanite_program/sensor/receiver/enable_passive_effect() + . = ..() + var/datum/nanite_extra_setting/frequency = extra_settings[NES_SIGNAL_FREQUENCY] + radio_connection = SSradio.add_object(src, frequency.get_value(), RADIO_SIGNALER) + +/datum/nanite_program/sensor/receiver/disable_passive_effect() + . = ..() + var/datum/nanite_extra_setting/frequency = extra_settings[NES_SIGNAL_FREQUENCY] + SSradio.remove_object(src, frequency.get_value()) + +/datum/nanite_program/sensor/receiver/proc/receive_signal(datum/signal/signal) + . = FALSE + if(!signal || !radio_connection) + return + var/datum/nanite_extra_setting/code = extra_settings[NES_SIGNAL_CODE] + if(signal.data["code"] != code.get_value()) + return + send_code() + return TRUE diff --git a/code/modules/research/nanites/nanite_programs/utility.dm b/code/modules/research/nanites/nanite_programs/utility.dm index 8ebcee6a8958d..04e0a280b94db 100644 --- a/code/modules/research/nanites/nanite_programs/utility.dm +++ b/code/modules/research/nanites/nanite_programs/utility.dm @@ -146,20 +146,19 @@ /datum/nanite_program/metabolic_synthesis name = "Metabolic Synthesis" - desc = "The nanites use the metabolic cycle of the host to speed up their replication rate, using their extra nutrition as fuel." + desc = "The nanites use the metabolic cycle of the host to speed up their replication rate, using their extra nutrition as fuel. Does not have a built-in safety limiter." use_rate = -0.5 //generates nanites rogue_types = list(/datum/nanite_program/toxic) /datum/nanite_program/metabolic_synthesis/check_conditions() if(!iscarbon(host_mob)) return FALSE - var/mob/living/carbon/C = host_mob - if(C.nutrition <= NUTRITION_LEVEL_WELL_FED) + if(host_mob.nutrition <= 0) return FALSE return ..() /datum/nanite_program/metabolic_synthesis/active_effect() - host_mob.adjust_nutrition(-0.5) + host_mob.adjust_nutrition(-min(0.5, host_mob.nutrition)) /datum/nanite_program/research name = "Distributed Computing" @@ -227,6 +226,9 @@ current_item = host_mob.get_inactive_held_item() if(current_item) nanite_access |= current_item.GetAccess() + current_item = host_mob.pulling + if(isitem(current_item)) + nanite_access |= current_item.GetAccess() if(ishuman(host_mob)) var/mob/living/carbon/human/H = host_mob current_item = H.wear_id @@ -244,27 +246,30 @@ resulting in an extremely infective strain of nanites." use_rate = 1.50 rogue_types = list(/datum/nanite_program/aggressive_replication, /datum/nanite_program/necrotic) - var/spread_cooldown = 0 + COOLDOWN_DECLARE(spread_cooldown) /datum/nanite_program/spreading/active_effect() - if(spread_cooldown < world.time) + if(!COOLDOWN_FINISHED(src, spread_cooldown)) return - spread_cooldown = world.time + 50 var/list/mob/living/target_hosts = list() - for(var/mob/living/L in ohearers(5, host_mob)) - if(!prob(25)) + for(var/mob/living/target in ohearers(5, host_mob)) + if(prob(15 * max(get_dist(host_mob, target) - 1, 0))) continue - if(!(MOB_ORGANIC in L.mob_biotypes) && !(MOB_UNDEAD in L.mob_biotypes) && !HAS_TRAIT(host_mob, TRAIT_NANITECOMPATIBLE)) + if(!(MOB_ORGANIC in target.mob_biotypes) && !(MOB_UNDEAD in target.mob_biotypes) && !HAS_TRAIT(host_mob, TRAIT_NANITECOMPATIBLE)) continue - target_hosts += L + target_hosts += target if(!target_hosts.len) + COOLDOWN_START(src, spread_cooldown, 2 SECONDS) return var/mob/living/infectee = pick(target_hosts) if(prob(100 - (infectee.get_permeability_protection() * 100))) + COOLDOWN_START(src, spread_cooldown, 7.5 SECONDS) //this will potentially take over existing nanites! infectee.AddComponent(/datum/component/nanites, 10) SEND_SIGNAL(infectee, COMSIG_NANITE_SYNC, nanites) infectee.investigate_log("was infected by spreading nanites by [key_name(host_mob)] at [AREACOORD(infectee)].", INVESTIGATE_NANITES) + else + COOLDOWN_START(src, spread_cooldown, 2 SECONDS) /datum/nanite_program/nanite_sting name = "Nanite Sting" @@ -303,7 +308,7 @@ /datum/nanite_program/mitosis/active_effect() var/rep_rate = round(nanites.nanite_volume / 50, 1) //0.5 per 50 nanite volume rep_rate *= 0.5 - nanites.adjust_nanites(null, rep_rate) + nanites.adjust_nanites(amount = rep_rate) if(prob(rep_rate)) var/datum/nanite_program/fault = pick(nanites.programs) if(fault == src) @@ -319,16 +324,15 @@ /datum/nanite_program/dermal_button/register_extra_settings() extra_settings[NES_SENT_CODE] = new /datum/nanite_extra_setting/number(1, 1, 9999) extra_settings[NES_BUTTON_NAME] = new /datum/nanite_extra_setting/text("Button") - extra_settings[NES_ICON] = new /datum/nanite_extra_setting/type("power", list("one","two","three","four","five","plus","minus","power")) - extra_settings[NES_COLOR] = new /datum/nanite_extra_setting/type("green", list("green","red","yellow","blue")) + extra_settings[NES_ICON] = new /datum/nanite_extra_setting/type("power", list("one", "two", "three", "four", "five", "plus", "minus", "power")) + extra_settings[NES_COLOR] = new /datum/nanite_extra_setting/type("green", list("green", "red", "yellow", "blue")) /datum/nanite_program/dermal_button/enable_passive_effect() . = ..() var/datum/nanite_extra_setting/bn_name = extra_settings[NES_BUTTON_NAME] var/datum/nanite_extra_setting/bn_icon = extra_settings[NES_ICON] - var/datum/nanite_extra_setting/bn_color = extra_settings[NES_COLOR] if(!button) - button = new(src, bn_name.get_value(), bn_icon.get_value(), bn_color.get_value()) + button = new(src, bn_name.get_value(), bn_icon.get_value(), "red") button.target = host_mob button.Grant(host_mob) @@ -363,3 +367,74 @@ /datum/action/innate/nanite_button/Activate() program.press() + +/datum/action/innate/nanite_button/proc/update_icon(icon, color) + button_icon_state = "[icon]_[color]" + UpdateButtonIcon() + +/datum/nanite_program/dermal_button/toggle + name = "Dermal Toggle" + desc = "Displays a switch on the host's skin, which can be used to send an activation and deactivation signal to the nanites." + var/active = FALSE + +/datum/nanite_program/dermal_button/toggle/register_extra_settings() + extra_settings[NES_ACTIVATION_CODE] = new /datum/nanite_extra_setting/number(1, 1, 9999) + extra_settings[NES_DEACTIVATION_CODE] = new /datum/nanite_extra_setting/number(1, 1, 9999) + extra_settings[NES_BUTTON_NAME] = new /datum/nanite_extra_setting/text("Toggle") + extra_settings[NES_ICON] = new /datum/nanite_extra_setting/type("power", list("one", "two", "three", "four", "five", "plus", "minus", "power")) + +/datum/nanite_program/dermal_button/toggle/press() + if(!activated) + return + + var/datum/nanite_extra_setting/icon = extra_settings[NES_ICON] + var/datum/nanite_extra_setting/sent_code = extra_settings[active ? NES_DEACTIVATION_CODE : NES_ACTIVATION_CODE] + button.update_icon(icon.get_value(), active ? "red" : "green") + host_mob.visible_message("[host_mob] flicks a switch on [host_mob.p_their()] forearm.", + "You flick the nanite button on your forearm [active ? "off" : "on"].", null, 2) + active = !active + SEND_SIGNAL(host_mob, COMSIG_NANITE_SIGNAL, sent_code.get_value(), "a [name] program") + +/datum/nanite_program/signaler + name = "Remote Signaler" + desc = "The nanites send a pulse to all remote signalers on a given frequency and code." + can_trigger = TRUE + trigger_cost = 10 + trigger_cooldown = 5 + var/datum/radio_frequency/radio_connection + +/datum/nanite_program/signaler/register_extra_settings() + extra_settings[NES_SIGNAL_FREQUENCY] = new /datum/nanite_extra_setting/number(FREQ_SIGNALER, MIN_FREQ, MAX_FREQ) + extra_settings[NES_SIGNAL_CODE] = new /datum/nanite_extra_setting/number(DEFAULT_SIGNALER_CODE, 1, 99) + +/datum/nanite_program/signaler/enable_passive_effect() + . = ..() + var/datum/nanite_extra_setting/frequency = extra_settings[NES_SIGNAL_FREQUENCY] + radio_connection = SSradio.return_frequency(frequency.get_value()) + +/datum/nanite_program/signaler/on_trigger() + if(!radio_connection) + return + var/datum/nanite_extra_setting/code = extra_settings[NES_SIGNAL_CODE] + radio_connection.post_signal(src, new /datum/signal(list("code" = code.get_value())), filter = RADIO_SIGNALER) + +/datum/nanite_program/vampire + name = "Vampiric Synthesis" + desc = "The nanites can consume the host's blood in order to replicate much faster. Does not have a built-in safety limiter." + use_rate = -0.75 + +/datum/nanite_program/vampire/check_conditions() + . = ..() + if(!.) + return FALSE + if(!iscarbon(host_mob)) + return FALSE + if(host_mob.blood_volume <= 0) + return FALSE + if(ishuman(host_mob)) + var/mob/living/carbon/human/host_human = host_mob + if(NOBLOOD in host_human.dna?.species?.species_traits) + return FALSE + +/datum/nanite_program/vampire/active_effect() + host_mob.blood_volume = max(host_mob.blood_volume - 1.5, 0) diff --git a/code/modules/research/nanites/nanite_remote.dm b/code/modules/research/nanites/nanite_remote.dm index 99ec99eb7c37a..1e36f2e78b61f 100644 --- a/code/modules/research/nanites/nanite_remote.dm +++ b/code/modules/research/nanites/nanite_remote.dm @@ -173,7 +173,6 @@ /obj/item/nanite_remote/comm name = "nanite communication remote" desc = "A device that can send text messages to specific programs." - icon_state = "nanite_comm_remote" var/comm_message = "" /obj/item/nanite_remote/comm/afterattack(atom/target, mob/user, etc) diff --git a/code/modules/research/nanites/rules.dm b/code/modules/research/nanites/rules.dm index f58835fdae870..c34a0527f6d56 100644 --- a/code/modules/research/nanites/rules.dm +++ b/code/modules/research/nanites/rules.dm @@ -1,14 +1,13 @@ /datum/nanite_rule var/name = "Generic Condition" var/desc = "When triggered, the program is active" + var/combinable = TRUE var/datum/nanite_program/program -/datum/nanite_rule/New(datum/nanite_program/new_program) +/datum/nanite_rule/New(datum/nanite_program/new_program, copy_to_rules = TRUE) program = new_program - if(LAZYLEN(new_program.rules) <= 5) //Avoid infinite stacking rules + if(copy_to_rules) new_program.rules += src - else - qdel(src) /datum/nanite_rule/proc/remove() program.rules -= src @@ -21,8 +20,8 @@ /datum/nanite_rule/proc/display() return name -/datum/nanite_rule/proc/copy_to(datum/nanite_program/new_program) - new type(new_program) +/datum/nanite_rule/proc/copy_to(datum/nanite_program/new_program, copy_to_rules = TRUE) + return new type(new_program, copy_to_rules) /datum/nanite_rule/health name = "Health" @@ -42,12 +41,13 @@ return FALSE /datum/nanite_rule/health/display() - return "[name] [above ? ">" : "<"] [threshold]%" + return "[name] [above ? ">=" : "<"] [threshold]%" -/datum/nanite_rule/health/copy_to(datum/nanite_program/new_program) - var/datum/nanite_rule/health/rule = new(new_program) +/datum/nanite_rule/health/copy_to(datum/nanite_program/new_program, copy_to_rules = TRUE) + var/datum/nanite_rule/health/rule = new(new_program, copy_to_rules) rule.above = above rule.threshold = threshold + return rule //TODO allow inversion /datum/nanite_rule/crit @@ -79,9 +79,10 @@ else return !program.nanites.cloud_active -/datum/nanite_rule/cloud_sync/copy_to(datum/nanite_program/new_program) - var/datum/nanite_rule/cloud_sync/rule = new(new_program) +/datum/nanite_rule/cloud_sync/copy_to(datum/nanite_program/new_program, copy_to_rules = TRUE) + var/datum/nanite_rule/cloud_sync/rule = new(new_program, copy_to_rules) rule.check_type = check_type + return rule /datum/nanite_rule/cloud_sync/display() return "[name]:[check_type]" @@ -103,13 +104,14 @@ return TRUE return FALSE -/datum/nanite_rule/nanites/copy_to(datum/nanite_program/new_program) - var/datum/nanite_rule/nanites/rule = new(new_program) +/datum/nanite_rule/nanites/copy_to(datum/nanite_program/new_program, copy_to_rules = TRUE) + var/datum/nanite_rule/nanites/rule = new(new_program, copy_to_rules) rule.above = above rule.threshold = threshold + return rule /datum/nanite_rule/nanites/display() - return "[name] [above ? ">" : "<"] [threshold]%" + return "[name] [above ? ">=" : "<"] [threshold]%" /datum/nanite_rule/damage name = "Damage" @@ -141,14 +143,15 @@ return TRUE return FALSE -/datum/nanite_rule/damage/copy_to(datum/nanite_program/new_program) - var/datum/nanite_rule/damage/rule = new(new_program) +/datum/nanite_rule/damage/copy_to(datum/nanite_program/new_program, copy_to_rules = TRUE) + var/datum/nanite_rule/damage/rule = new(new_program, copy_to_rules) rule.above = above rule.threshold = threshold rule.damage_type = damage_type + return rule /datum/nanite_rule/damage/display() - return "[damage_type] [above ? ">" : "<"] [threshold]" + return "[damage_type] [above ? ">=" : "<"] [threshold]" /datum/nanite_rule/species name = "Species" @@ -172,11 +175,112 @@ return species_match_rule ? mode_rule : !mode_rule -/datum/nanite_rule/species/copy_to(datum/nanite_program/new_program) - var/datum/nanite_rule/species/rule = new(new_program) +/datum/nanite_rule/species/copy_to(datum/nanite_program/new_program, copy_to_rules = TRUE) + var/datum/nanite_rule/species/rule = new(new_program, copy_to_rules) rule.species_rule = species_rule rule.mode_rule = mode_rule rule.species_name_rule = species_name_rule + return rule /datum/nanite_rule/species/display() return "[mode_rule ? "IS" : "IS NOT"] [species_name_rule]" + +/datum/nanite_rule/nutrition + name = "Nutrition" + desc = "Checks the host's nutrition" + + var/above = FALSE + var/threshold = NUTRITION_LEVEL_HUNGRY + +/datum/nanite_rule/nutrition/check_rule() + if(above) + return program.host_mob.nutrition >= threshold + else + return program.host_mob.nutrition < threshold + +/datum/nanite_rule/nutrition/copy_to(datum/nanite_program/new_program, copy_to_rules = TRUE) + var/datum/nanite_rule/nutrition/rule = new(new_program, copy_to_rules) + rule.above = above + rule.threshold = threshold + return rule + +/datum/nanite_rule/nutrition/display() + return "Nutrition [above ? ">=" : "<"] [min(round(threshold / NUTRITION_LEVEL_FAT, 5), 100)]%" + +/datum/nanite_rule/blood + name = "Blood" + desc = "Checks the host's blood level." + + var/threshold = 80 + var/above = TRUE + +/datum/nanite_rule/blood/check_rule() + var/blood_percent = round((program.host_mob.blood_volume / BLOOD_VOLUME_NORMAL) * 100) + if(above) + if(blood_percent >= threshold) + return TRUE + else + if(blood_percent < threshold) + return TRUE + return FALSE + +/datum/nanite_rule/blood/display() + return "[name] [above ? ">=" : "<"] [threshold]%" + +/datum/nanite_rule/blood/copy_to(datum/nanite_program/new_program, copy_to_rules = TRUE) + var/datum/nanite_rule/blood/rule = new(new_program, copy_to_rules) + rule.above = above + rule.threshold = threshold + return rule + +/datum/nanite_rule/combined + name = "Combined" + desc = "Combines multiple nanite rules into one." + combinable = FALSE + var/list/datum/nanite_rule/rules = list() + var/op = NL_AND + +/datum/nanite_rule/combined/New(datum/nanite_program/new_program, copy_to_rules, list/datum/nanite_rule/rules, op = NL_AND) + ..() + if(!length(rules) || length(rules) > 5) + qdel(src) + return + src.rules = rules + src.op = sanitize_inlist(op, NL_ALL, NL_AND) + +/datum/nanite_rule/combined/display() + var/list/rule_displays = list() + for(var/datum/nanite_rule/rule as anything in rules) + rule_displays += rule.display() + return "[op]([rule_displays.Join(", ")])" + +/datum/nanite_rule/combined/check_rule() + switch(op) + if(NL_AND) + for(var/datum/nanite_rule/rule as anything in rules) + if(!rule.check_rule()) + return FALSE + if(NL_OR) + for(var/datum/nanite_rule/rule as anything in rules) + if(rule.check_rule()) + return TRUE + return FALSE + if(NL_NOR) + for(var/datum/nanite_rule/rule as anything in rules) + if(rule.check_rule()) + return FALSE + if(NL_NAND) + for(var/datum/nanite_rule/rule as anything in rules) + if(!rule.check_rule()) + return TRUE + return FALSE + return TRUE + +/datum/nanite_rule/combined/copy_to(datum/nanite_program/new_program, copy_to_rules = TRUE) + var/datum/nanite_rule/combined/rule = new(new_program, copy_to_rules) + rule.op = op + for(var/datum/nanite_rule/subrule as anything in rules) + var/datum/nanite_rule/new_subrule = subrule.copy_to(new_program, FALSE) + if(new_subrule) + rule.rules += new_subrule + return rule diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 0c8ba1c7c58d8..343584355fc93 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -2116,6 +2116,7 @@ "nanite_program_hub", "nanite_programmer", "nanite_remote", + "nanite_comm_remote", "nanite_scanner", "public_nanite_chamber", "red_diag_nanites", @@ -2146,6 +2147,8 @@ "sensor_voice_nanites", "stealth_nanites", "voice_nanites", + "sensor_receiver_nanites", + "remote_signal_nanites", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 500, TECHWEB_POINT_TYPE_NANITES = 500) export_price = 4000 @@ -2168,6 +2171,7 @@ "refractive_nanites", "shock_nanites", "temperature_nanites", + "dermal_toggle_nanites", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 500, TECHWEB_POINT_TYPE_NANITES = 500) export_price = 5000 @@ -2191,6 +2195,8 @@ "sensor_damage_nanites", "sensor_death_nanites", "sensor_health_nanites", + "sensor_nutrition_nanites", + "sensor_blood_nanites", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 500, TECHWEB_POINT_TYPE_NANITES = 500) export_price = 5000 @@ -2238,7 +2244,7 @@ id = "nanite_harmonic" tech_tier = 4 display_name = "Harmonic Nanite Programming" - description = "Nanite programs that require seamless integration between nanites and biology." + description = "Nanite programs that require seamless integration between nanites and biology. Passively increases nanite regeneration rate for all clouds upon researching." prereq_ids = list( "nanite_bio", "nanite_mesh", @@ -2253,10 +2259,39 @@ "purging_plus_nanites", "regenerative_plus_nanites", "sensor_species_nanites", + "vampire_nanites", ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000, TECHWEB_POINT_TYPE_NANITES = 2000) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000, TECHWEB_POINT_TYPE_NANITES = 3000) export_price = 8000 +/datum/techweb_node/nanite_replication_protocols + id = "nanite_replication_protocols" + tech_tier = 4 + display_name = "Nanite Replication Protocols" + description = "Protocols that overwrite the default nanite replication routine to achieve more efficiency in certain circumstances." + prereq_ids = list("nanite_smart") + design_ids = list( + "factory_nanites", + "kickstart_nanites", + "offline_nanites", + "pyramid_nanites", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000, TECHWEB_POINT_TYPE_NANITES = 2500) + +/datum/techweb_node/nanite_storage_protocols + id = "nanite_storage_protocols" + tech_tier = 4 + display_name = "Nanite Storage Protocols" + description = "Protocols that overwrite the default nanite storage routine to achieve more efficiency or greater capacity." + prereq_ids = list("nanite_smart") + design_ids = list( + "free_range_nanites", + "hive_nanites", + "unsafe_storage_nanites", + "zip_nanites", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000, TECHWEB_POINT_TYPE_NANITES = 2500) + /datum/techweb_node/nanite_combat id = "nanite_military" tech_tier = 5 @@ -2273,6 +2308,7 @@ "nanite_sting_nanites", "pyro_nanites", "viral_nanites", + "armblade_nanites", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500, TECHWEB_POINT_TYPE_NANITES = 2500) export_price = 12500 @@ -2281,7 +2317,7 @@ id = "nanite_hazard" tech_tier = 5 display_name = "Hazard Nanite Programs" - description = "Extremely advanced Nanite programs with the potential of being extremely dangerous." + description = "Extremely advanced nanite programs using knowledge gained from advanced alien technology." prereq_ids = list( "alientech", "nanite_harmonic", @@ -2289,7 +2325,7 @@ design_ids = list( "mindcontrol_nanites", "mitosis_nanites", - "spreading_nanites", + "spreading_nanites" ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000, TECHWEB_POINT_TYPE_NANITES = 4000) export_price = 15000 diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 4ef153e4255d8..fab0f6e393734 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -459,6 +459,7 @@ if(do_after(user, 6 SECONDS, target = user)) to_chat(user, "You explode!") explosion(get_turf(user), 1 ,3, 6) + user.investigate_log("has been gibbed by an oil slime extract explosion.", INVESTIGATE_DEATHS) user.gib() return 60 SECONDS to_chat(user, "You stop feeding [src], and the feeling passes.") @@ -877,7 +878,7 @@ return to_chat(user, "You feed the slime the stabilizer. It is now less likely to mutate.") - M.mutation_chance = CLAMP(M.mutation_chance-15,0,100) + M.mutation_chance = clamp(M.mutation_chance-15,0,100) qdel(src) /obj/item/slimepotion/slime/mutator @@ -901,7 +902,7 @@ return to_chat(user, "You feed the slime the mutator. It is now more likely to mutate.") - M.mutation_chance = CLAMP(M.mutation_chance+12,0,100) + M.mutation_chance = clamp(M.mutation_chance+12,0,100) M.mutator_used = TRUE qdel(src) diff --git a/code/modules/ruins/lavalandruin_code/puzzle.dm b/code/modules/ruins/lavalandruin_code/puzzle.dm index 21d8652a405d6..664391ced3b9c 100644 --- a/code/modules/ruins/lavalandruin_code/puzzle.dm +++ b/code/modules/ruins/lavalandruin_code/puzzle.dm @@ -284,6 +284,7 @@ /obj/effect/sliding_puzzle/prison/Destroy() if(prisoner) to_chat(prisoner,"With the cube broken by force, you can feel your body falling apart.") + prisoner.investigate_log("has died from their prison puzzle being destroyed.", INVESTIGATE_DEATHS) prisoner.death() qdel(prisoner) . = ..() diff --git a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm index 459b4e8e40fd4..3868fae6c6298 100644 --- a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm +++ b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm @@ -58,6 +58,7 @@ meat_counter += 20 else meat_counter++ + H.investigate_log("has been gibbed by the necropolis tendril.", INVESTIGATE_DEATHS) H.gib() obj_integrity = min(obj_integrity + max_integrity*0.05,max_integrity)//restores 5% hp of tendril for(var/mob/living/L in viewers(5, src)) diff --git a/code/modules/ruins/objects_and_mobs/sin_ruins.dm b/code/modules/ruins/objects_and_mobs/sin_ruins.dm index ba1bf0ecbbbf4..1d7d43d198513 100644 --- a/code/modules/ruins/objects_and_mobs/sin_ruins.dm +++ b/code/modules/ruins/objects_and_mobs/sin_ruins.dm @@ -23,6 +23,7 @@ if(user.stat) to_chat(user, "No... just one more try...") + user.investigate_log("has been gibbed by [src].", INVESTIGATE_DEATHS) user.gib() else user.visible_message("[user] pulls [src]'s lever with a glint in [user.p_their()] eyes!", "You feel a draining as you pull the lever, but you \ diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index 1938e97185e1f..f868dfb08f35a 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -606,6 +606,13 @@ possible_destinations = "pod_asteroid" icon = 'icons/obj/terminals.dmi' icon_state = "dorm_available" + + //these muthafuckas arent supposed to smooth + base_icon_state = null + smoothing_flags = null + smoothing_groups = null + canSmoothWith = null + light_color = LIGHT_COLOR_BLUE density = FALSE clockwork = TRUE //it'd look weird diff --git a/code/modules/shuttle/super_cruise/orbital_poi_generator/ruin_generator/mapping.dm b/code/modules/shuttle/super_cruise/orbital_poi_generator/ruin_generator/mapping.dm index 6bf26335320e6..e56455f32a2cf 100644 --- a/code/modules/shuttle/super_cruise/orbital_poi_generator/ruin_generator/mapping.dm +++ b/code/modules/shuttle/super_cruise/orbital_poi_generator/ruin_generator/mapping.dm @@ -1,7 +1,7 @@ /obj/effect/abstract/open_area_marker name = "open area marker" icon = 'icons/obj/device.dmi' - icon_state = "pinonfar" + icon_state = "pincomp_arrow_far" /obj/effect/abstract/open_area_marker/Initialize(mapload) return INITIALIZE_HINT_QDEL @@ -9,7 +9,7 @@ /obj/effect/abstract/doorway_marker name = "doorway marker" icon = 'icons/obj/device.dmi' - icon_state = "pinonmedium" + icon_state = "pincomp_arrow_medium" /obj/effect/abstract/doorway_marker/Initialize(mapload) return INITIALIZE_HINT_QDEL diff --git a/code/modules/shuttle/super_cruise/orbital_poi_generator/ruin_generator/ruin_part_types.dm b/code/modules/shuttle/super_cruise/orbital_poi_generator/ruin_generator/ruin_part_types.dm index 6c43fa37b7636..ae9c4b97318b3 100644 --- a/code/modules/shuttle/super_cruise/orbital_poi_generator/ruin_generator/ruin_part_types.dm +++ b/code/modules/shuttle/super_cruise/orbital_poi_generator/ruin_generator/ruin_part_types.dm @@ -166,12 +166,6 @@ file_name = "5x5_shower" weight = 2 -//its 13x13 lol -// !! Map file uses broken turbo-lift components !! -/*/datum/map_template/ruin_part/elevator - file_name = "9x9_elevator" - weight = 4*/ - /datum/map_template/ruin_part/hallwaymaints file_name = "9x5_hallwaymaints" weight = 4 diff --git a/code/modules/shuttle/super_cruise/shuttle_components/shuttle_console.dm b/code/modules/shuttle/super_cruise/shuttle_components/shuttle_console.dm index f5a4f782664ab..0516a799feb7e 100644 --- a/code/modules/shuttle/super_cruise/shuttle_components/shuttle_console.dm +++ b/code/modules/shuttle/super_cruise/shuttle_components/shuttle_console.dm @@ -271,7 +271,7 @@ GLOBAL_VAR_INIT(shuttle_docking_jammed, FALSE) if(shuttleObject.autopilot) to_chat(usr, "Shuttle is controlled by autopilot.") return - shuttleObject.thrust = CLAMP(params["thrust"], 0, 100) + shuttleObject.thrust = clamp(params["thrust"], 0, 100) if("setAngle") if(QDELETED(shuttleObject)) say("Shuttle not in flight.") diff --git a/code/modules/spells/spell_types/godhand.dm b/code/modules/spells/spell_types/godhand.dm index 485fac26a5c69..11de3da023f0f 100644 --- a/code/modules/spells/spell_types/godhand.dm +++ b/code/modules/spells/spell_types/godhand.dm @@ -17,9 +17,11 @@ throw_speed = 0 var/charges = 1 -/obj/item/melee/touch_attack/Initialize(mapload) +/obj/item/melee/touch_attack/Initialize(mapload, obj/effect/proc_holder/spell/targeted/touch/_spell) . = ..() ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) + if(istype(_spell)) + attached_spell = _spell /obj/item/melee/touch_attack/attack(mob/target, mob/living/carbon/user) if(!iscarbon(user)) //Look ma, no hands @@ -190,3 +192,13 @@ . = ..() M.forceMove(pie) + +/obj/item/melee/touch_attack/mutation + catchphrase = null + var/datum/mutation/parent_mutation + +/obj/item/melee/touch_attack/mutation/Initialize(_mapload, obj/effect/proc_holder/spell/targeted/touch/_spell, datum/mutation/_parent) + . = ..() + if(!istype(_parent)) + return INITIALIZE_HINT_QDEL + parent_mutation = _parent diff --git a/code/modules/spells/spell_types/mind_transfer.dm b/code/modules/spells/spell_types/mind_transfer.dm index 809a28b020a1d..71745871137db 100644 --- a/code/modules/spells/spell_types/mind_transfer.dm +++ b/code/modules/spells/spell_types/mind_transfer.dm @@ -90,7 +90,7 @@ Also, you never added distance checking after target is selected. I've went ahea var/mob/living/caster = user//The wizard/whomever doing the body transferring. //MIND TRANSFER BEGIN - var/mob/dead/observer/ghost = victim.ghostize(0) + var/mob/dead/observer/ghost = victim.ghostize(FALSE) caster.mind.transfer_to(victim) ghost.mind.transfer_to(caster) diff --git a/code/modules/spells/spell_types/rightandwrong.dm b/code/modules/spells/spell_types/rightandwrong.dm index 39bcb37186cb9..7e5371b6d878a 100644 --- a/code/modules/spells/spell_types/rightandwrong.dm +++ b/code/modules/spells/spell_types/rightandwrong.dm @@ -39,7 +39,7 @@ GLOBAL_LIST_INIT(summoned_guns, list( /obj/item/gun/energy/plasmacutter/adv, /obj/item/gun/energy/wormhole_projector, /obj/item/gun/ballistic/automatic/wt550, - /obj/item/gun/ballistic/shotgun/bulldog, + /obj/item/gun/ballistic/shotgun/automatic/bulldog, /obj/item/gun/ballistic/revolver/grenadelauncher, /obj/item/gun/ballistic/revolver/golden, /obj/item/gun/ballistic/sniper_rifle, diff --git a/code/modules/spells/spell_types/shapeshift.dm b/code/modules/spells/spell_types/shapeshift.dm index edab5c1660551..f924410198597 100644 --- a/code/modules/spells/spell_types/shapeshift.dm +++ b/code/modules/spells/spell_types/shapeshift.dm @@ -138,6 +138,7 @@ if(source.revert_on_death) restore(death=TRUE) else + shape.investigate_log("has been killed whilst shapeshifted.", INVESTIGATE_DEATHS) shape.death() /obj/shapeshift_holder/proc/shapeDeath(death=TRUE) diff --git a/code/modules/spells/spell_types/telepathy.dm b/code/modules/spells/spell_types/telepathy.dm index a27f3eb4ab01e..72e0cbfce0ede 100644 --- a/code/modules/spells/spell_types/telepathy.dm +++ b/code/modules/spells/spell_types/telepathy.dm @@ -13,14 +13,14 @@ var/magic_check = FALSE var/holy_check = FALSE -/obj/effect/proc_holder/spell/targeted/telepathy/cast(list/targets, mob/living/simple_animal/revenant/user = usr) +/obj/effect/proc_holder/spell/targeted/telepathy/cast(list/targets, mob/living/user = usr) for(var/mob/living/M in targets) if(istype(M.get_item_by_slot(ITEM_SLOT_HEAD), /obj/item/clothing/head/foilhat)) to_chat(user, "It appears the target's mind is ironclad! No getting a message in there!") return - var/msg = stripped_input(usr, "What do you wish to tell [M]?", null, "") - if(!msg) - charge_counter = charge_max + var/msg = tgui_input_text(usr, "What do you wish to tell [M]?", "Telepathy") + if(!length(msg)) + revert_cast(user) return if(CHAT_FILTER_CHECK(msg)) to_chat(user, "Your message contains forbidden words.") diff --git a/code/modules/spells/spell_types/touch_attacks.dm b/code/modules/spells/spell_types/touch_attacks.dm index b2dc3ba4ad2cd..43c8f54d5dfb5 100644 --- a/code/modules/spells/spell_types/touch_attacks.dm +++ b/code/modules/spells/spell_types/touch_attacks.dm @@ -33,21 +33,21 @@ to_chat(user, "[dropmessage]") return - for(var/mob/living/carbon/C in targets) - if(!attached_hand) - if(ChargeHand(C)) - recharging = FALSE - return + for(var/mob/living/carbon/target in targets) + if(!attached_hand && charge_hand(target)) + recharging = FALSE + return /obj/effect/proc_holder/spell/targeted/touch/charge_check(mob/user,silent = FALSE) if(!QDELETED(attached_hand)) //Charge doesn't matter when putting the hand away. return TRUE - else - return ..() + return ..() -/obj/effect/proc_holder/spell/targeted/touch/proc/ChargeHand(mob/living/carbon/user) - attached_hand = new hand_path(src) - attached_hand.attached_spell = src +/obj/effect/proc_holder/spell/targeted/touch/proc/create_hand() + return new hand_path(null, src) + +/obj/effect/proc_holder/spell/targeted/touch/proc/charge_hand(mob/living/carbon/user) + attached_hand = create_hand() if(!user.put_in_hands(attached_hand)) remove_hand() if (user.get_num_arms() <= 0) @@ -84,3 +84,16 @@ action_icon_state = "statue" sound = 'sound/magic/fleshtostone.ogg' + +/obj/effect/proc_holder/spell/targeted/touch/mutation + clothes_req = FALSE + var/datum/mutation/parent_mutation + +/obj/effect/proc_holder/spell/targeted/touch/mutation/Initialize(_mapload, datum/mutation/_parent) + . = ..() + if(!istype(_parent)) + return INITIALIZE_HINT_QDEL + parent_mutation = _parent + +/obj/effect/proc_holder/spell/targeted/touch/mutation/create_hand() + return new hand_path(null, src, parent_mutation) diff --git a/code/modules/spells/spell_types/wizard.dm b/code/modules/spells/spell_types/wizard.dm index ffef4081e3b99..ec8dbc86a02fc 100644 --- a/code/modules/spells/spell_types/wizard.dm +++ b/code/modules/spells/spell_types/wizard.dm @@ -293,7 +293,7 @@ var/mob/living/M = AM M.Paralyze(stun_amt) to_chat(M, "You're thrown back by [user]!") - AM.safe_throw_at(throwtarget, ((CLAMP((maxthrow - (CLAMP(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1,user, force = repulse_force)//So stuff gets tossed around at the same time. + AM.safe_throw_at(throwtarget, ((clamp((maxthrow - (clamp(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1,user, force = repulse_force)//So stuff gets tossed around at the same time. /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno //i fixed conflicts only to find out that this is in the WIZARD file instead of the xeno file?! name = "Tail Sweep" diff --git a/code/modules/station_goals/bluespace_tap.dm b/code/modules/station_goals/bluespace_tap.dm index fd1cbddff2fab..3d536aba2842b 100644 --- a/code/modules/station_goals/bluespace_tap.dm +++ b/code/modules/station_goals/bluespace_tap.dm @@ -156,7 +156,7 @@ /obj/item/reagent_containers/food/snacks/soup/monkeysdelight, /obj/item/reagent_containers/food/snacks/soup/stew, /obj/item/reagent_containers/food/snacks/soup/hotchili, - /obj/item/reagent_containers/food/snacks/burrito, + /obj/item/food/burrito, /obj/item/food/burger/fish, /obj/item/reagent_containers/food/snacks/cubancarp, /obj/item/reagent_containers/food/snacks/fishandchips, diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm index 3b92fedb64c76..6d709bd0ad0fc 100644 --- a/code/modules/station_goals/bsa.dm +++ b/code/modules/station_goals/bsa.dm @@ -245,6 +245,10 @@ DEFINE_BUFFER_HANDLER(/obj/machinery/bsa/middle) circuit = /obj/item/circuitboard/computer/bsa_control icon = 'icons/obj/machines/particle_accelerator.dmi' icon_state = "control_boxp" + base_icon_state = null + smoothing_flags = NONE + smoothing_groups = null + canSmoothWith = null diff --git a/code/modules/surgery/advanced/brainwashing.dm b/code/modules/surgery/advanced/brainwashing.dm index 3a9d98ee7e685..a16e93a09898d 100644 --- a/code/modules/surgery/advanced/brainwashing.dm +++ b/code/modules/surgery/advanced/brainwashing.dm @@ -16,6 +16,7 @@ target_mobtypes = list(/mob/living/carbon/human) possible_locs = list(BODY_ZONE_HEAD) + abductor_surgery_blacklist = TRUE /datum/surgery/advanced/brainwashing/can_start(mob/user, mob/living/carbon/target) if(!..()) diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm index e9c4d411168f6..3a1158c48c822 100644 --- a/code/modules/surgery/bodyparts/bodyparts.dm +++ b/code/modules/surgery/bodyparts/bodyparts.dm @@ -207,7 +207,7 @@ var/current_damage = get_damage(TRUE) //This time around, count stamina loss too. var/available_damage = max_damage - current_damage var/applied_damage = min(max_stamina_damage - stamina_dam, available_damage) - stamina_dam += round(CLAMP(stamina, 0, applied_damage), DAMAGE_PRECISION) + stamina_dam += round(clamp(stamina, 0, applied_damage), DAMAGE_PRECISION) if(owner && updating_health) @@ -327,7 +327,6 @@ dmg_overlay_type = "" //no damage overlay shown when husked is_husked = TRUE else - dmg_overlay_type = initial(dmg_overlay_type) is_husked = FALSE if(!dropping_limb && C.dna?.check_mutation(HULK)) //Please remove hulk from the game. I beg you. diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 4b609171e05ce..86deb37be5a1c 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -16,7 +16,7 @@ return FALSE var/obj/item/bodypart/affecting = C.get_bodypart(BODY_ZONE_CHEST) - affecting.receive_damage(CLAMP(brute_dam/2 * affecting.body_damage_coeff, 15, 50), CLAMP(burn_dam/2 * affecting.body_damage_coeff, 0, 50)) //Damage the chest based on limb's existing damage + affecting.receive_damage(clamp(brute_dam/2 * affecting.body_damage_coeff, 15, 50), clamp(burn_dam/2 * affecting.body_damage_coeff, 0, 50)) //Damage the chest based on limb's existing damage C.visible_message("[C]'s [src.name] has been violently dismembered!") if(C.stat <= SOFT_CRIT)//No more screaming while unconsious diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm index 5321da254718a..3d0ff10c90b4f 100644 --- a/code/modules/surgery/bodyparts/helpers.dm +++ b/code/modules/surgery/bodyparts/helpers.dm @@ -2,6 +2,7 @@ return /mob/living/carbon/get_bodypart(zone) + RETURN_TYPE(/obj/item/bodypart) if(!zone) zone = BODY_ZONE_CHEST for(var/obj/item/bodypart/L as() in bodyparts) diff --git a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm index 675eab6a90ee7..4f8c20b65098f 100644 --- a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm @@ -514,6 +514,18 @@ limb_id = "pumpkin_man" is_dimorphic = FALSE should_draw_greyscale = FALSE + item_flags = ISCARVABLE + ///Carved overlay + var/image/carved_overlay + +/obj/item/bodypart/head/pumpkin_man/Initialize(mapload) + . = ..() + carved_overlay = image('icons/mob/pumpkin_faces.dmi', "blank", -BODY_LAYER) + +/obj/item/bodypart/head/pumpkin_man/get_limb_icon(dropped) + . = ..() + owner.cut_overlay(carved_overlay) + . += carved_overlay /obj/item/bodypart/chest/pumpkin_man limb_id = "pumpkin_man" diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index 069b3739b4180..54ba8243951f2 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -123,6 +123,7 @@ Unlike regular jetpacks, this device has no stabilization system." slot = ORGAN_SLOT_THRUSTERS icon_state = "imp_jetpack" + base_icon_state = "imp_jetpack" implant_overlay = null implant_color = null actions_types = list(/datum/action/item_action/organ_action/toggle) @@ -166,14 +167,9 @@ on = FALSE update_icon() -/obj/item/organ/cyberimp/chest/thrusters/update_icon() - if(on) - icon_state = "imp_jetpack-on" - else - icon_state = "imp_jetpack" - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() +/obj/item/organ/cyberimp/chest/thrusters/update_icon_state() + icon_state = "[base_icon_state][on ? "-on" : null]" + return ..() /obj/item/organ/cyberimp/chest/thrusters/proc/move_react() SIGNAL_HANDLER diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index b525e99db37d2..cbc4afcb91e23 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -254,7 +254,7 @@ return var/range = input(user, "Enter range (0 - [max_light_beam_distance])", "Range Select", 0) as null|num - set_distance(CLAMP(range, 0, max_light_beam_distance)) + set_distance(clamp(range, 0, max_light_beam_distance)) assume_rgb(C) /obj/item/organ/eyes/robotic/glow/proc/assume_rgb(newcolor) diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 804e16bcac8e2..6d004190bca6d 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -72,20 +72,22 @@ INITIALIZE_IMMEDIATE(/obj/item/organ) STOP_PROCESSING(SSobj, src) //Special is for instant replacement like autosurgeons -/obj/item/organ/proc/Remove(mob/living/carbon/M, special = FALSE, pref_load = FALSE) +/obj/item/organ/proc/Remove(mob/living/carbon/organ_owner, special = FALSE, pref_load = FALSE) owner = null - if(M) - M.internal_organs -= src - if(M.internal_organs_slot[slot] == src) - M.internal_organs_slot.Remove(slot) - if((organ_flags & ORGAN_VITAL) && !special && !(M.status_flags & GODMODE)) - M.death() + if(organ_owner) + organ_owner.internal_organs -= src + if(organ_owner.internal_organs_slot[slot] == src) + organ_owner.internal_organs_slot.Remove(slot) + if((organ_flags & ORGAN_VITAL) && !special && !(organ_owner.status_flags & GODMODE)) + if(organ_owner.stat != DEAD) + organ_owner.investigate_log("has been killed by losing a vital organ ([src]).", INVESTIGATE_DEATHS) + organ_owner.death() for(var/X in actions) var/datum/action/A = X - A.Remove(M) + A.Remove(organ_owner) - SEND_SIGNAL(src, COMSIG_ORGAN_REMOVED, M) - SEND_SIGNAL(M, COMSIG_CARBON_LOSE_ORGAN, src) + SEND_SIGNAL(src, COMSIG_ORGAN_REMOVED, organ_owner) + SEND_SIGNAL(organ_owner, COMSIG_CARBON_LOSE_ORGAN, src) START_PROCESSING(SSobj, src) @@ -167,7 +169,7 @@ INITIALIZE_IMMEDIATE(/obj/item/organ) return if(maximum < damage) return - damage = CLAMP(damage + d, 0, maximum) + damage = clamp(damage + d, 0, maximum) var/mess = check_damage_thresholds(owner) prev_damage = damage if(mess && owner) diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm index 955e38046bf9d..372da507f6b61 100644 --- a/code/modules/surgery/organs/tongue.dm +++ b/code/modules/surgery/organs/tongue.dm @@ -364,3 +364,16 @@ desc = "It's an odd tongue, seemingly made of plant matter." disliked_food = MEAT | DAIRY liked_food = VEGETABLES | FRUIT | GRAIN | CLOTH //cannibals apparently + +/obj/item/organ/tongue/podperson/pumpkin + modifies_speech = TRUE + ///Is this tongue carved? + var/carved = FALSE + +/obj/item/organ/tongue/podperson/pumpkin/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + if((message[1] != "*" || message[1] != "#") && !carved) + message = "..." + to_chat(owner, "Something is covering your mouth!") + to_chat(owner, "Try carving your head.") + speech_args[SPEECH_MESSAGE] = message diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index a0b4eb823de22..a37abc9c01583 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -111,12 +111,12 @@ tool_behaviour = TOOL_DRILL toolspeed = 1 -/obj/item/surgicaldrill/suicide_act(mob/user) +/obj/item/surgicaldrill/suicide_act(mob/living/user) user.visible_message("[user] rams [src] into [user.p_their()] chest! It looks like [user.p_theyre()] trying to commit suicide!") addtimer(CALLBACK(user, TYPE_PROC_REF(/mob/living/carbon, gib), null, null, TRUE, TRUE), 25) user.SpinAnimation(3, 10) playsound(user, 'sound/machines/juicer.ogg', 20, TRUE) - return (MANUAL_SUICIDE) + return MANUAL_SUICIDE /obj/item/surgicaldrill/augment name = "surgical drill" @@ -174,10 +174,9 @@ hitsound = 'sound/weapons/bladeslice.ogg' sharpness = IS_SHARP_ACCURATE -/obj/item/scalpel/suicide_act(mob/user) +/obj/item/scalpel/suicide_act(mob/living/user) user.visible_message("[user] is slitting [user.p_their()] [pick("wrists", "throat", "stomach")] with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) - + return BRUTELOSS /obj/item/circular_saw name = "circular saw" diff --git a/code/modules/tgs/core/core.dm b/code/modules/tgs/core/core.dm index 41a0473394525..b9a9f27a28ae8 100644 --- a/code/modules/tgs/core/core.dm +++ b/code/modules/tgs/core/core.dm @@ -153,4 +153,9 @@ /world/TgsSecurityLevel() var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs) if(api) - api.SecurityLevel() + return api.SecurityLevel() + +/world/TgsVisibility() + var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs) + if(api) + return api.Visibility() diff --git a/code/modules/tgs/core/datum.dm b/code/modules/tgs/core/datum.dm index 68b0330fe8606..93377079aa73f 100644 --- a/code/modules/tgs/core/datum.dm +++ b/code/modules/tgs/core/datum.dm @@ -57,3 +57,6 @@ TGS_PROTECT_DATUM(/datum/tgs_api) /datum/tgs_api/proc/SecurityLevel() return TGS_UNIMPLEMENTED + +/datum/tgs_api/proc/Visibility() + return TGS_UNIMPLEMENTED diff --git a/code/modules/tgs/v5/__interop_version.dm b/code/modules/tgs/v5/__interop_version.dm index 5d3d491a7362b..1b52b31d6a73e 100644 --- a/code/modules/tgs/v5/__interop_version.dm +++ b/code/modules/tgs/v5/__interop_version.dm @@ -1 +1 @@ -"5.6.1" +"5.6.2" diff --git a/code/modules/tgs/v5/_defines.dm b/code/modules/tgs/v5/_defines.dm index f973338daa032..bdcd4e4dd58e6 100644 --- a/code/modules/tgs/v5/_defines.dm +++ b/code/modules/tgs/v5/_defines.dm @@ -48,6 +48,7 @@ #define DMAPI5_RUNTIME_INFORMATION_REVISION "revision" #define DMAPI5_RUNTIME_INFORMATION_TEST_MERGES "testMerges" #define DMAPI5_RUNTIME_INFORMATION_SECURITY_LEVEL "securityLevel" +#define DMAPI5_RUNTIME_INFORMATION_VISIBILITY "visibility" #define DMAPI5_CHAT_UPDATE_CHANNELS "channels" diff --git a/code/modules/tgs/v5/api.dm b/code/modules/tgs/v5/api.dm index 34cc43f8762f7..45250efc46271 100644 --- a/code/modules/tgs/v5/api.dm +++ b/code/modules/tgs/v5/api.dm @@ -4,6 +4,7 @@ var/instance_name var/security_level + var/visibility var/reboot_mode = TGS_REBOOT_MODE_NORMAL @@ -54,6 +55,7 @@ version = new /datum/tgs_version(runtime_information[DMAPI5_RUNTIME_INFORMATION_SERVER_VERSION]) security_level = runtime_information[DMAPI5_RUNTIME_INFORMATION_SECURITY_LEVEL] + visibility = runtime_information[DMAPI5_RUNTIME_INFORMATION_VISIBILITY] instance_name = runtime_information[DMAPI5_RUNTIME_INFORMATION_INSTANCE_NAME] var/list/revisionData = runtime_information[DMAPI5_RUNTIME_INFORMATION_REVISION] @@ -252,3 +254,7 @@ /datum/tgs_api/v5/SecurityLevel() RequireInitialBridgeResponse() return security_level + +/datum/tgs_api/v5/Visibility() + RequireInitialBridgeResponse() + return visibility diff --git a/code/modules/tgs/v5/undefs.dm b/code/modules/tgs/v5/undefs.dm index c679737dfc496..f163adaaafe3b 100644 --- a/code/modules/tgs/v5/undefs.dm +++ b/code/modules/tgs/v5/undefs.dm @@ -48,6 +48,7 @@ #undef DMAPI5_RUNTIME_INFORMATION_REVISION #undef DMAPI5_RUNTIME_INFORMATION_TEST_MERGES #undef DMAPI5_RUNTIME_INFORMATION_SECURITY_LEVEL +#undef DMAPI5_RUNTIME_INFORMATION_VISIBILITY #undef DMAPI5_CHAT_UPDATE_CHANNELS diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index 74ba63c071c5b..399c075014490 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -83,10 +83,12 @@ #include "ntnetwork_tests.dm" #include "preference_species.dm" #include "projectiles.dm" +#include "stat_mc.dm" #include "subsystem_init.dm" #include "subsystem_metric_sanity.dm" #include "surgery_linking.dm" #include "techweb_sanity.dm" +#include "teleporters.dm" #include "tgui_create_message.dm" #include "timer_sanity.dm" #include "unit_test.dm" diff --git a/code/modules/unit_tests/stat_mc.dm b/code/modules/unit_tests/stat_mc.dm new file mode 100644 index 0000000000000..28d31c4080c18 --- /dev/null +++ b/code/modules/unit_tests/stat_mc.dm @@ -0,0 +1,59 @@ +/datum/unit_test/stat_mc_validation/Run() + var/list/failures = list() + main_loop: + for (var/datum/controller/subsystem/ss in Master.subsystems) + var/list/result = ss.stat_entry() + // Rejected + if (isnull(result)) + failures += "The subsystem [ss.name] has an invalid stat_entry proc, it returns null." + continue + // Rejected for not returning a list + if (!islist(result)) + failures += "The subsystem [ss.name] has an invalid stat_entry proc, it did not return a list." + continue + // The list should be associative and contain stat types + for (var/key in result) + var/list/value = result[key] + if (!islist(value)) + failures += "The subsystem [ss.name] has an invalid stat_entry proc, it does not properly use the new system of stat panel component types." + continue main_loop + var/comp_type = value["type"] + if (!comp_type) + failures += "The subsystem [ss.name] has an invalid stat_entry proc, it does not properly use the new system of stat panel component types." + continue main_loop + switch (comp_type) + if (STAT_TEXT) + var/text = value["text"] + if (isnull(text)) + failures += "The subsystem [ss.name] has an invalid stat_entry proc, it contains a text component with no text parameter." + continue main_loop + continue + if (STAT_BUTTON) + var/text = value["text"] + var/action = value["action"] + if (isnull(text) || isnull(action)) + failures += "The subsystem [ss.name] has an invalid stat_entry proc, it has a button which has either no text, or no action." + continue main_loop + continue + if (STAT_ATOM) + var/text = value["text"] + if (isnull(text)) + failures += "The subsystem [ss.name] has an invalid stat_entry proc, it contains an atom component with no text parameter." + continue main_loop + continue + if (STAT_DIVIDER) + continue + if (STAT_VERB) + var/action = value["action"] + if (isnull(action)) + failures += "The subsystem [ss.name] has an invalid stat_entry proc, it has a verb which has no action." + continue main_loop + continue + if (STAT_BLANK) + continue + else + failures += "The subsystem [ss.name] has an invalid stat_entry proc, it attempted to display a component with a type that was not recognised." + continue main_loop + if (!length(failures)) + return + Fail(jointext(failures, "\n")) diff --git a/code/modules/unit_tests/teleporters.dm b/code/modules/unit_tests/teleporters.dm new file mode 100644 index 0000000000000..2cb047304fbb5 --- /dev/null +++ b/code/modules/unit_tests/teleporters.dm @@ -0,0 +1,10 @@ +/datum/unit_test/auto_teleporter_linking/Run() + // Put down the teleporter machinery + var/obj/machinery/teleport/hub/hub = allocate(/obj/machinery/teleport/hub) + var/obj/machinery/teleport/station/station = allocate(/obj/machinery/teleport/station, locate(run_loc_floor_bottom_left.x + 1, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z)) + var/obj/machinery/computer/teleporter/computer = allocate(/obj/machinery/computer/teleporter, locate(run_loc_floor_bottom_left.x + 2, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z)) + + TEST_ASSERT_EQUAL(hub.power_station, station, "Hub didn't link to the station") + TEST_ASSERT_EQUAL(station.teleporter_console, computer, "Station didn't link to the teleporter console") + TEST_ASSERT_EQUAL(station.teleporter_hub, hub, "Station didn't link to the hub") + TEST_ASSERT_EQUAL(computer.power_station, station, "Teleporter console didn't link to the hub") diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index e9c6d1c287be9..59f3568dec195 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -519,7 +519,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) name = "Bulldog Shotgun" desc = "A fully-loaded semi-automatic drum-fed shotgun. Compatible with all 12g rounds. Designed for close \ quarter anti-personnel engagements." - item = /obj/item/gun/ballistic/shotgun/bulldog + item = /obj/item/gun/ballistic/shotgun/automatic/bulldog cost = 8 surplus = 40 purchasable_from = UPLINK_NUKE_OPS @@ -1847,7 +1847,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/encryptionkey/syndicate cost = 2 surplus = 75 - purchasable_from = ~UPLINK_INCURSION + purchasable_from = ~(UPLINK_INCURSION | UPLINK_EXCOMMUNICATE) restricted = TRUE /datum/uplink_item/device_tools/syndietome @@ -1937,7 +1937,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) Used just like a regular headset, but can be disabled to use external headsets normally and to avoid detection." item = /obj/item/storage/box/syndie_kit/imp_radio cost = 4 - purchasable_from = ~UPLINK_INCURSION //To prevent traitors from immediately outing the hunters to security. + purchasable_from = ~(UPLINK_INCURSION | UPLINK_EXCOMMUNICATE) //To prevent traitors from immediately outing the hunters to security. restricted = TRUE /datum/uplink_item/implants/reviver diff --git a/code/modules/vehicles/wheelchair.dm b/code/modules/vehicles/wheelchair.dm index 1c8211ca56bac..76c70302ec73f 100644 --- a/code/modules/vehicles/wheelchair.dm +++ b/code/modules/vehicles/wheelchair.dm @@ -21,6 +21,7 @@ D.set_vehicle_dir_layer(NORTH, ABOVE_MOB_LAYER) D.set_vehicle_dir_layer(EAST, OBJ_LAYER) D.set_vehicle_dir_layer(WEST, OBJ_LAYER) + ADD_TRAIT(src, TRAIT_NO_IMMOBILIZE, INNATE_TRAIT) //the wheelchair doesnt immobilize us like a bed would /obj/vehicle/ridden/wheelchair/ComponentInitialize() //Since it's technically a chair I want it to have chair properties . = ..() diff --git a/code/modules/vending/games.dm b/code/modules/vending/games.dm index 428c611ec76fd..abe44ffc5eb06 100644 --- a/code/modules/vending/games.dm +++ b/code/modules/vending/games.dm @@ -10,6 +10,7 @@ /obj/item/toy/cards/deck/cas = 3, /obj/item/toy/cards/deck/cas/black = 3, /obj/item/toy/cards/deck/unum = 3, + /obj/item/toy/cards/deck/tarot = 3, /obj/item/hourglass = 2) contraband = list(/obj/item/dice/fudge = 9, /obj/item/instrument/musicalmoth = 1) diff --git a/code/modules/vending/security.dm b/code/modules/vending/security.dm index daa124896f1c4..6d9b5029cd2a0 100644 --- a/code/modules/vending/security.dm +++ b/code/modules/vending/security.dm @@ -1,7 +1,7 @@ /obj/machinery/vending/security name = "\improper SecTech" desc = "A security equipment vendor." - product_ads = "Crack capitalist skulls!;Beat some heads in!;Don't forget - harm is good!;Your weapons are right here.;Handcuffs!;Freeze, scumbag!;Don't tase me bro!;Tase them, bro.;Why not have a donut?" + product_ads = "Crack capitalist skulls!;Beat some heads in!;Don't forget - harm is good!;Your weapons are right here.;Handcuffs!;Freeze, scumbag!;Don't tase me bro!;Tase them, bro." icon_state = "sec" icon_deny = "sec-deny" light_color = LIGHT_COLOR_BLUE @@ -11,14 +11,12 @@ /obj/item/grenade/flashbang = 4, /obj/item/assembly/flash/handheld = 5, /obj/item/book/manual/wiki/security_space_law = 3, - /obj/item/reagent_containers/food/snacks/donut = 12, /obj/item/storage/box/evidence = 6, /obj/item/flashlight/seclite = 4, /obj/item/holosign_creator/security = 3, /obj/item/restraints/legcuffs/bola/energy = 7, /obj/item/club = 5) - contraband = list(/obj/item/clothing/glasses/sunglasses/advanced = 2, - /obj/item/storage/fancy/donut_box = 2) + contraband = list(/obj/item/clothing/glasses/sunglasses/advanced = 2) premium = list(/obj/item/storage/belt/security/webbing = 5, /obj/item/storage/backpack/duffelbag/sec/deputy = 4, /obj/item/coin/antagtoken = 1, diff --git a/code/modules/wiremod/components/list/index_table.dm b/code/modules/wiremod/components/list/index_table.dm index eb9a10f45cc9b..043e32e922569 100644 --- a/code/modules/wiremod/components/list/index_table.dm +++ b/code/modules/wiremod/components/list/index_table.dm @@ -35,4 +35,9 @@ output_list.set_output(null) return - output_list.set_output(target_list[index]) + var/list/new_list = new /list() + for(var/target_list_column as anything in target_list[index]) + //Add the actual value of the column to the list, rather than the table index itself + new_list += target_list[index][target_list_column] + + output_list.set_output(new_list) diff --git a/code/modules/wiremod/core/usb_cable.dm b/code/modules/wiremod/core/usb_cable.dm index 1c5398cd2ca08..13aa624436403 100644 --- a/code/modules/wiremod/core/usb_cable.dm +++ b/code/modules/wiremod/core/usb_cable.dm @@ -80,7 +80,7 @@ return ..() -/obj/item/usb_cable/suicide_act(mob/user) +/obj/item/usb_cable/suicide_act(mob/living/user) user.visible_message("[user] is wrapping [src] around [user.p_their()] neck! It looks like [user.p_theyre()] trying to commit suicide!") return OXYLOSS diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm index d3bf42e72b6a7..675ec355535d8 100644 --- a/code/modules/zombie/items.dm +++ b/code/modules/zombie/items.dm @@ -56,20 +56,17 @@ infection = new() infection.Insert(target) - - -/obj/item/zombie_hand/suicide_act(mob/user) +/obj/item/zombie_hand/suicide_act(mob/living/user) user.visible_message("[user] is ripping [user.p_their()] brains out! It looks like [user.p_theyre()] trying to commit suicide!") - if(isliving(user)) - var/mob/living/L = user - var/obj/item/bodypart/O = L.get_bodypart(BODY_ZONE_HEAD) - if(O) - O.dismember() - return (BRUTELOSS) + var/obj/item/bodypart/head = user.get_bodypart(BODY_ZONE_HEAD) + if(head) + head.dismember() + return BRUTELOSS /obj/item/zombie_hand/proc/check_feast(mob/living/target, mob/living/user) if(target.stat == DEAD) var/hp_gained = target.maxHealth + target.investigate_log("has been devoured by a zombie.", INVESTIGATE_DEATHS) target.gib() // zero as argument for no instant health update user.adjustBruteLoss(-hp_gained, 0) diff --git a/code/modules/zombie/organs.dm b/code/modules/zombie/organs.dm index 5078c5c945329..1f262066d1aa7 100644 --- a/code/modules/zombie/organs.dm +++ b/code/modules/zombie/organs.dm @@ -9,8 +9,8 @@ var/living_transformation_time = 30 var/converts_living = FALSE - var/revive_time_min = 450 - var/revive_time_max = 700 + var/revive_time_min = 60 SECONDS + var/revive_time_max = 100 SECONDS var/timer_id /obj/item/organ/zombie_infection/Initialize(mapload) @@ -43,14 +43,10 @@ /obj/item/organ/zombie_infection/process(delta_time) if(!owner) return - if(IS_IN_STASIS(owner)) - return if(!(src in owner.internal_organs)) Remove(owner, TRUE) if (causes_damage && !iszombie(owner) && owner.stat != DEAD) - owner.adjustToxLoss(0.5 * delta_time, forced = TRUE) - if(DT_PROB(5, delta_time)) - to_chat(owner, "You feel sick...") + owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1 * delta_time) if(timer_id) return if(owner.suiciding) @@ -82,12 +78,12 @@ //Fully heal the zombie's damage the first time they rise C.setToxLoss(0, 0) C.setOxyLoss(0, 0) + C.setOrganLoss(ORGAN_SLOT_BRAIN, 0) C.heal_overall_damage(INFINITY, INFINITY, INFINITY, null, TRUE) C.revive() - - C.grab_ghost() + C.visible_message("[owner] suddenly convulses, as [owner.p_they()][stand_up ? " stagger to [owner.p_their()] feet and" : ""] gain a ravenous hunger in [owner.p_their()] eyes!", "You HUNGER!") playsound(C.loc, 'sound/hallucinations/far_noise.ogg', 50, 1) C.do_jitter_animation(living_transformation_time) diff --git a/config/config.txt b/config/config.txt index b46fff95e27a8..b0f7c33d17470 100644 --- a/config/config.txt +++ b/config/config.txt @@ -157,6 +157,9 @@ LOG_MANIFEST ## log all world.Topic() calls # LOG_WORLD_TOPIC +## Log changes to preferences, loading, saving, etc. +LOG_PREFERENCES + ## enables use of the proc twitterize() that lets you take a large list of strings and turn it into a JSON file of tweet sized strings. ## As an example of how this could be """useful""" look towards Poly (https://twitter.com/Poly_the_Parrot) # LOG_TWITTER diff --git a/html/changelog.html b/html/changelog.html index 771e2f226de17..223ee5747d3e5 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,383 @@ -->
+

24 October 2023

+

Penwin0 updated:

+
    +
  • Firefighter helmet now mechanically covers your face, as show by the sprite
  • +
+ +

23 October 2023

+

DrDuckedGoose updated:

+
    +
  • Added the ability to carve Pumpkin People's heads
  • +
  • Pumpkin People are now pseudo-mute until carved
  • +
+

rkz updated:

+
    +
  • Whoever made all the batongs into pool noodles has been shot! (fixed immobilization not applying through stamcrit)
  • +
+ +

22 October 2023

+

Absolucy, XDTM updated:

+
    +
  • Added Nanite Protocols, special programs that allow for you to 'upgrade' some part of your nanites, usually with some tradeoff or downside.
  • +
  • Added Blood Sensor and Nutrition Sensor nanite programs.
  • +
  • Added the Nanite Blade program to nanites, which allows you to manifest an armblade similar to the xenobio one, locked behind illegal tech.
  • +
  • Added the Vampiric Synthesis program to nanites, which allows you to generate nanite volume using your own blood volume. This WILL suck you dry if you let it, please use this with a blood sensor or something! No, you can't cheese it with Blood Regeneration.
  • +
  • Added the Remote Signaler program to nanites, which functions similarly to, well, a remote signaler!
  • +
  • Added the Remote Signal Receiver program to nanites, which allows you to receive remote signaler signals and translate them into nanite signals!
  • +
  • Added the Dermal Toggle program to nanites, which is similar to a dermal button, but it's an on/off toggle instead.
  • +
  • You can now combine nanite rules, for more advanced logic!
  • +
  • Nanite Cloud Controllers now have neat lil' popup bubbles whenever you do an action on 'em.
  • +
  • Researching harmonic nanite tech now provides a 0.1/sec passive regen rate boost to all nanites!
  • +
  • Metabolic Synthesis no longer has a built in-limiter, and can consume ALL your nutrition if you allow it to.
  • +
  • Infective exo-locomotion shouldn't be completely useless anymore.
  • +
  • Nanite communication remotes, which can send text communications to certain nanite programs, are now actually buildable
  • +
+

DarnTheMarn updated:

+
    +
  • Adds a new reagent, maltodextrin.
  • +
  • Adds maltodextrin to donk pockets and vendor food.
  • +
  • Removed donuts and their references from the SecTech
  • +
+

HowToLoLu updated:

+
    +
  • The engineering security office of BoxStation no longer is filled with cold air roundstart
  • +
  • The air in the control room of Box's Telecomms is no longer filled with cold air either
  • +
+

PowerfulBacon updated:

+
    +
  • Ventcrawling works again
  • +
+

RKz, MrStonedOne updated:

+
    +
  • adds stack overflow detection for the Master Controller
  • +
+

Rukofamicom updated:

+
    +
  • Cryptographic Sequencers (Emags) no longer cause permanent damage to airlocks. They will still bolt doors open and cause them to completely lose power indefinitely (which means no silicon access). Pulse or cut/repair power wires to fix emagged doors.
  • +
  • Removes the smoking panel message from airlocks that have been emagged, since they are no longer permanently damaged
  • +
  • Pulsing power wires now resets the time before power comes back on.
  • +
+ +

21 October 2023

+

Absolucy updated:

+
    +
  • The Obsessed trauma now disguises itself to scanners as monophobia until a certain amount of time has been spent near the obsession.
  • +
+

AgentCitrus updated:

+
    +
  • Oozelings no longer lose hair from radiation or alopecia
  • +
+

DarnTheMarn updated:

+
    +
  • Adds SOP books for each department, found by the techfab and the respective head's room. Extras can be printed at the library.
  • +
+

Penwin0 updated:

+
    +
  • The game compiles again
  • +
  • fixed damage overlays
  • +
+

PowerfulBacon updated:

+
    +
  • Increased durathread bullet armour (40 from armour, 15 from jumpsuit; 49 total bullet protection from both)
  • +
  • Reverts AFK players showing up as SSD on examine.
  • +
+

Varo; @FuryMcFlurry updated:

+
    +
  • new moth wing sprites
  • +
  • new moth open wing sprites
  • +
+

mystery3525 updated:

+
    +
  • Vent crawling now has a 1% chance every 3 seconds of constant movement of giving notice to everyone nearby that can hear it, meaning once per 5 minutes of vent crawling does it play a sound to hearing mobs.
  • +
  • Closed/broken/offline atmospherics machinery now prevents creatures from vent-crawling through them, though vents/scrubbers remain unchanged and require being welded still.
  • +
+

rkz updated:

+
    +
  • converted random vendors into a spawner, less garbage.dm del horrors.
  • +
  • nightmares can actually utilize their pocket, belt, and ID slots. It was checking for a jumpsuit on a race that cant wear jumpsuits
  • +
  • removed restriction prohibiting nightmares from wearing masks
  • +
+

rkz, MrPerson updated:

+
    +
  • Rechargers now have a panel_open state when you screwdriver them! I fixed it on accident, woops.
  • +
  • converts a few dozen update_icons into their respective update_overlays or update_icon_states. Adds parent calls. Modernizes them all to update_appearance.
  • +
+

rkz, Rohesie, RandomGamer123 updated:

+
    +
  • Immobilization is now a trait. Cleaned up its usage in mobility which should make it perform a lot quicker and generate less edge-cases
  • +
  • grabbed states and buckled states now have signals we can append to or check for
  • +
+ +

20 October 2023

+

PowerfulBacon updated:

+
    +
  • Objective stashes may no longer spawn in the bathrooms of head's offices.
  • +
+

RKz, Timberpoes, MrMelbert updated:

+
    +
  • machine components are now stored inside the machines themselves, instead of sent to a magical nullspace and creating errors
  • +
  • As a result of making circuitboards components, you can now do things like place a bomb on circuitboard, build it in a machine, and it will blow up like you expect it to!
  • +
  • machines no longer vend their own components accidentally
  • +
  • machines that are supposed to eject contents should actually do so more, and those that shouldn't, should do so less
  • +
+

itsmeow updated:

+
    +
  • Added code support for the ability to view playtime of removed jobs.
  • +
+

rkz, Tattle updated:

+
    +
  • added investigate deaths to shed some more light on unusual demises, dustings, and gibbings
  • +
+ +

19 October 2023

+

Absolucy, stylemistake updated:

+
    +
  • AFK players will now have flavor text indicating that they're AFK when examined.
  • +
  • AFK detection now works properly again.
  • +
+

XeonMations updated:

+
    +
  • Replaced metastation's medbay post's radio implant with a radio
  • +
+

itsmeow updated:

+
    +
  • Cleaned up preference serialization and error handling. Cleaned up guest/databaseless default value generation.
  • +
  • Added logging to preference loading, saving, and edits for better debugging.
  • +
+ +

18 October 2023

+

HowToLoLu updated:

+
    +
  • Simple animals are no longer immortal
  • +
+

Impish_Delights updated:

+
    +
  • New outfit preset; Bulletproof SecOff. Can be chosen via the select equipment menu, and through chameleon clothing
  • +
  • Mosin Nagant deals less damage (40 down from 60) but has armor penetration (30% AP)
  • +
  • Nagant Revolver deals less damage (55 down from 60) but has armor penetration (10% AP)
  • +
+

PowerfulBacon updated:

+
    +
  • Light mode stat panel atom tab will now be readable (Text when you alt click a tile)
  • +
+

Programs-The-Station updated:

+
    +
  • Fixes the Index Table Component not outputting the values of the table row.
  • +
+ +

17 October 2023

+

BeeLover66 updated:

+
    +
  • Some recipes that wouldn't get reagents from their ingredients now do
  • +
+

PowerfulBacon updated:

+
    +
  • Gun cooldown crosshair.
  • +
+

RKz, Rohesie updated:

+
    +
  • unconsciousness is now a trait, cleaned up its usage in mobility and stat, which should make it perform a lot quicker and generate less edge-cases
  • +
  • being woken up from unconsciousness should always clear trauma-induced monochromatic vision
  • +
  • moves a sleeping check in regenerative coma a few lines ahead. It's intended use in code that voluntarily sleeping provides less healing benefit than entering a coma through trauma/medicine.
  • +
  • Which... now technically makes it a balance change. It was always intended, but using the sleep verb will now heal you less than involuntary unconciousness, in terms of the regen rate of the regenerative coma
  • +
+ +

16 October 2023

+

HowToLoLu updated:

+
    +
  • Modular Console on/off icon states are now separated into body and keyboard states instead of being combined
  • +
  • Added another bitflag for smoothing, SMOOTH_BITMASK_SKIP_CORNERS
  • +
  • Modular Consoles no longer look fully broken when only the CPU is broken
  • +
  • Fixed computers becoming invisible in certain arrangements
  • +
  • Some computers with special icons no longer become invisible
  • +
  • Computers now handle smoothing properly when acted on by Narsie or Ratvar
  • +
  • Broken computers now show up properly
  • +
+

Programs-The-Station updated:

+
    +
  • Fixes the Sabotage and Explosives Objective for "the telecommunications relay".
  • +
+ +

15 October 2023

+

HowToLoLu updated:

+
    +
  • Pizzaboxes now accept pizza being put in once again
  • +
+

Impish_Delights updated:

+
    +
  • Combat shotguns can now be toggled in-hand to function like manual pump-action shotguns
  • +
  • Combat shotguns will 'click' when cycling firing modes.
  • +
  • Compact combat shotgun will now cycle properly when fired one-handed
  • +
  • Fixes runtime when firing a ballistic gun without a magazine installed
  • +
  • Removes unneeded proc for automatic shotguns, functionally the same
  • +
  • Retypes bulldog to be a child of shotgun/automatic
  • +
+ +

14 October 2023

+

Impish_Delights updated:

+
    +
  • Mosin Obrez! Sawn-off Mosin Nagant; has innate & wild spread, kicks like a mule, and can be fired 1-handed
  • +
  • Any saw type item (and plasmacutters) can be used to saw guns short
  • +
  • Energy saws can be used as saws now (similar to chainsaws)
  • +
  • You cannot add multiple slings to an improvised shotgun, and it shows on examine text now
  • +
  • Mosin Nagant and Obrez require 2-hands to cycle the bolt (up from 1-hand)
  • +
  • Added icon and in-hand sprites for Mosin Obrez
  • +
  • removed redundant sawoff code for shotguns, now part of the parent gun/ballistic item
  • +
  • rewrites some boltaction code to make it less weird for item interactions/attaching bayonets
  • +
  • sawing checks for TOOL_SAW instead of using bespoke items, is an innate ballistic gun function, and is more configurable.
  • +
+

Penwin0 updated:

+
    +
  • Excommunicates can no longer purchase syndicate communication keys or implants
  • +
+ +

12 October 2023

+

EvilDragonfiend updated:

+
    +
  • Input box (the thing that's used in naming things) now accepts Enter and Esc.
  • +
+

Impish_Delights updated:

+
    +
  • Oozelings no longer autocannibalize inorganic limbs while at low blood
  • +
+

Penwin0 updated:

+
    +
  • Fland loads again
  • +
+

Rukofamicom updated:

+
    +
  • Goliaths no longer stun with tendril attacks, instead tripping the victim. They move faster and can more frequently use their tendril attacks instead.
  • +
  • Damaging zombie tumors deal brain damage instead of toxin damage.
  • +
  • Hostile zombies now heal brain damage over time as well, and fully heal brain damage upon conversion
  • +
  • Brain damage progresses twice as fast as toxin damage so patients die sooner (this is done because brain damage cannot cause crit)
  • +
  • The delay between death and resurrection as a zombie has been increased by 50% to make up for the lack of time spent in crit.
  • +
+

XeonMations updated:

+
    +
  • Fixes metastation's duplicate bulletproof armour
  • +
+

rkz updated:

+
    +
  • Death upon ye, ancient math!
  • +
+

rkz, Arkatos1, ShizCalev updated:

+
    +
  • adds proc to update an item's action_buttons, removes duplicate code
  • +
+ +

10 October 2023

+

BeeLover66 updated:

+
    +
  • Duplicate spell burger recipe has been removed
  • +
+

PowerfulBacon updated:

+
    +
  • Fixes the MC tab breaking in stat again due to a null returned stat entry.
  • +
+

rkz, Mothblocks updated:

+
    +
  • Suit Storage Units now use radials!
  • +
  • All engineer Suit Storage Units now start with magboots in them.
  • +
  • SSU radials
  • +
  • convert SSU code to update_appearance
  • +
+ +

09 October 2023

+

DrDuckedGoose updated:

+
    +
  • Fix color correction runtiming
  • +
+

HowToLoLu updated:

+
    +
  • The Particles shot out of the Particle Accelerator no longer phase through machines
  • +
  • In Projectiles, Piercing behaviour is now prioritized over Phasing behaviour (the difference between the two is whether it deals damage as it's passing through)
  • +
+

Penwin0 updated:

+
    +
  • Removed Deputy from preferences menu
  • +
+

PowerfulBacon updated:

+
    +
  • Reverts changes to clown farting
  • +
+

Rukofamicom updated:

+
    +
  • The server repo has officially reached 10,000 pull requests. Thank you everyone for all the contributions you make to the game!
  • +
  • To honor this momentous occasion, clowns struggling to fart when they shouldn't be able to may now occasionally fart a random organ out instead. This may be lethal.
  • +
+

WhereAmI, RaveRadbury, Inept, softcerv updated:

+
    +
  • Adds Tarot Cards, for any thematic fortune tellings you might require! Find them in the General loadout tab or Fun Vendor.
  • +
  • Radial Menu for Cards, easier to navigate while playing!
  • +
+

XeonMations updated:

+
    +
  • Added the ability to choose the direction of any office chair you are sitting in by moving
  • +
+

rkz updated:

+
    +
  • fix nanite cloud controllers disappearing (my fault)
  • +
+ +

07 October 2023

+

Absolucy updated:

+
    +
  • All action mutations now properly take energy chromosomes (which reduce ability cooldowns) rather than synchronizer chromosomes.
  • +
  • Cat Claws and Strengthened Wings now properly accept power chromosomes — they already had code that took the power chromosome into account, but couldn't actually have said chromosome applied to them.
  • +
  • Shock touch, cryokinesis, and chameleon can now accept power chromosomes to improve their respective powers.
  • +
  • Acid hands can take a power or sync chromosome, to increase the acid power or decrease the blood loss respectively.
  • +
  • Cat Claws now changes your attack sound to slashing noises, similar to moths or lizards.
  • +
  • Upgrading a DNA scanner will accordingly update any cooldowns (joker and injector) for linked genetics consoles.
  • +
  • Inserting a genetics diskette into a genetics console will now actually mark any mutations on said disk as discovered. This likely won't change anything during actual rounds, but this will be useful during debugging or perhaps adminbus.
  • +
  • You won't waste shock touch charges accidentally clicking on the floor or a wall anymore.
  • +
  • Cleaned up the code of a lot of mutations quite a bit.
  • +
  • You can no longer obtain a negative temporary blindness duration, which would lead to permanent blindness. As a result, healing holoparas don't blind people anymore.
  • +
+

BeeLover66 updated:

+
    +
  • Glass of chocolate milk now looks different from glass of (normal) milk
  • +
+

CydiaLamiales updated:

+
    +
  • fixed a runtime in godhand.dm
  • +
+

PestoVerde322 updated:

+
    +
  • fixed Reinforced tables' wrong inner corner icons.
  • +
+

PowerfulBacon updated:

+
    +
  • Adds in unit testing for MC stat panels.
  • +
+

mystery3525 updated:

+
    +
  • Abductors can no longer permanently brainwash victims via surgery.
  • +
+ +

06 October 2023

+

Absolucy updated:

+
    +
  • Fix html encoding (which messed up apostrophes and such) with brainwashing objectives in the tgui popup
  • +
+

PowerfulBacon updated:

+
    +
  • Xeno eggs, Changeling eggs and Zombie tumours are no longer slowed by stasis beds.
  • +
  • Fixes stat panel buttons overrunning the screen on the MC tab.
  • +
  • Enforces permission requirement on stat button presses.
  • +
  • Adds support for multi-row stat buttons which have sub-buttons.
  • +
+

RKz, Rohesie updated:

+
    +
  • SStimers wont runtime out of bounds if you change world.fps
  • +
+

rkz, ninjanomnom updated:

+
    +
  • hiding action_buttons will no longer clear all overlays
  • +
+

05 October 2023

CydiaLamiales updated:

    @@ -572,383 +949,6 @@

    EvilDragonfiend, HowToLoLu(sprite) updated:

  • handheld genetic sequence scanner now tells the genetic stability level
  • dna nullifier sprite
- -

22 August 2023

-

CydiaLamiales updated:

-
    -
  • Fixed the logging for the gas tanks rupturing not working correctly
  • -
-

bluezorua updated:

-
    -
  • Certain Medical Banners on some maps no longer magically heal
  • -
- -

21 August 2023

-

AnturK, esainane, MrMelbert, Son-of-Space, san7890, Ghommie, ported by mystery3525 updated:

-
    -
  • Various fixes to the UpdatePaths tool
  • -
  • UpdatePaths will now handle lists that contain strings.
  • -
  • Adds support for simple subtype repathing, outright deletion, for UpdatePaths scripts
  • -
  • Orginizes UpdatePaths folder and adds a well-documented readme.md
  • -
-

itsmeow updated:

-
    -
  • Fixed the jobless role preference (Join as assistant, random job, return to lobby, etc) not saving properly.
  • -
  • Fixed a runtime from prefs if a player disconnected during their client initialization.
  • -
- -

20 August 2023

-

Absolucy updated:

-
    -
  • Adds a specific preference to enable/disable AI VOX (text-to-speech) announcements.
  • -
  • You can now examine organs and implants to see which part of the body it fits in.
  • -
-

Absolucy, Rukofamicom updated:

-
    -
  • Fixed the obsessed "take picture" objective.
  • -
  • Fixed some possible edge cases with obsession targets being cloned or body swapped or whatever.
  • -
  • Obsessed people now get a protect instead of a kill objective on their obsession, and new flavor text leaning more into the whole 'yandere' thing.
  • -
  • Obsession trauma now requires a lobotomy to cure.
  • -
  • Obsessed people are now guaranteed to pick someone who is on-station as their obsession target.
  • -
  • Obsession targets are much more likely to be someone who will likely remain ON-station.
  • -
  • Headpats now count as hugs for the sake of the 'hug x times' obsession objective.
  • -
  • Admins can now give someone a specific obsession.
  • -
-

EvilDragonfiend updated:

-
    -
  • abductor gland storage now uses smartfridge UI instead of too-alieny-UI.
  • -
  • gland names will be revealed when these are in abductor's new organ storage.
  • -
  • abductor gland storage now has 2~7 glands per each at starting.
  • -
  • broken glands will be restored once you put these into a new storage (old one doesn't work)
  • -
  • antagonists can open abductor gland storage even if they're not an abductor species.
  • -
-

HowToLoLu updated:

-
    -
  • Reworked all of Lavaland Mining Station Airlocks to use Tiny Fans instead of Airlock Controllers.
  • -
  • Mining EVA now has wider doorways, and moved Officer Fastmosky to inside the emergency locker.
  • -
  • Lavaland's Laborcamp External Access now has its own atmosbot (Sergeant Airhead) inside an emergency locker.
  • -
  • Put tiny fans under the shutters at the Science Shuttle Dock on Lavaland
  • -
- -

19 August 2023

-

CydiaLamiales updated:

-
    -
  • The Syndicate has upgraded its chameleon gear with the ability to completely hide any and all chameleon functionality with a multitool. Be sure not to confuse your own gear for a plain old piece of clothing, agent!
  • -
  • Fixed maps having the "omnibelt" parent object instead of toolbelts
  • -
-

Impish_Delights updated:

-
    -
  • Hoods for winter coats/hoodies/explorer suits are now stored in nullspace instead of the suit's inventory
  • -
-

itsmeow updated:

-
    -
  • Fixed runtimes and fingerprints not getting properly applied when a stack merges with something during deconstruction.
  • -
  • Fixed a load of runtimes
  • -
  • Fixed assets not properly sending in the permissions panel
  • -
- -

18 August 2023

-

CydiaLamiales updated:

-
    -
  • made examining the power fist show mols and pressure of the mounted tank
  • -
  • fixes the power fist not working
  • -
  • Fixed Infrared emitters not being alligned with their "lazers"
  • -
-

itsmeow updated:

-
    -
  • Refactored mentor loading, and moved it before preferences fixing mentor-related prefs and keybinds.
  • -
  • Improved handling of "mentor datum created without a ckey" case, making it more clear what caused it.
  • -
  • Added a check to prevent admins from adding an empty ckey as a mentor.
  • -
- -

17 August 2023

-

PowerfulBacon updated:

-
    -
  • Refactors multitool buffers to use a component, removing some hard-delete potential.
  • -
- -

16 August 2023

-

BriggsIDP updated:

-
    -
  • Aux doc to Rad dorms
  • -
  • Explo shuttle area in Rad
  • -
-

PowerfulBacon updated:

-
    -
  • Mech movement speed is now proportional to player movement speed, increasing their movement delay by 33%.
  • -
-

Tyranicranger4 updated:

-
    -
  • Abductors no longer have access to necrotic revival surgery
  • -
  • Added TRAIT_ABDUCTOR_SURGEON, seperate from the normal SURGEON trait - to be used for Abductors.
  • -
  • Fixed a runtime in supermatter.dm
  • -
- -

15 August 2023

-

Penwin0 updated:

-
    -
  • Corg Janitor Closet camera is no longer floating
  • -
-

bluezorua updated:

-
    -
  • Carp spawners in Corg Armoury, to prevent unintended antagonists from spawning in there
  • -
- -

14 August 2023

-

Antops12 updated:

-
    -
  • designed science cargo shuttle
  • -
-

Bokkiewokkie updated:

-
    -
  • Fixed VV menu not showing new turfs after deleting a turf
  • -
  • Fixed admins adding components not logging the object it was added to
  • -
-

boombaklops updated:

-
    -
  • the edagger's attacks are now quieter
  • -
-

itsmeow updated:

-
    -
  • Fixed build mode's map regenerator not working.
  • -
  • Fixed build mode's map regenerator not properly hiding undertile elements.
  • -
-

mystery3525 updated:

-
    -
  • Radstation AI Satellite no longer depowers 30 minutes into a shift.
  • -
- -

13 August 2023

-

Absolucy updated:

-
    -
  • You can now properly place slime speed potions on tables, in lockers, etc.
  • -
  • Using a slime speed potion on something that has no slowdown in the first place will no longer waste it.
  • -
  • Slime renaming potions will now offer better feedback as to why a rename didn't occur.
  • -
  • Slime renaming potions now let you rename playerless, mindless mobs.
  • -
  • Slime renaming potion prompts now use tgui input.
  • -
  • Slime renaming potion prompts now time out after 2 minutes, so you can't just deadlock the potion forever.
  • -
  • Offering a slime speed potion to a player mob whose client is either disconnected or AFK will just tell you to try again later.
  • -
-

EvilDragonfiend updated:

-
    -
  • mimic mob only takes self-damage when they do not mind instead of not-ckey
  • -
-

PowerfulBacon updated:

-
    -
  • Fixes a runtime in mech building.
  • -
-

RKz, tralezab updated:

-
    -
  • you can milk anything! Componentizes milking.
  • -
  • just kidding, only stuff that coders define as milkable.
  • -
-

itsmeow updated:

-
    -
  • Optimized spawner and decals init, saving ~0.25sec init
  • -
  • Added a new preference for darkened flashes, which flash to black rather than white.
  • -
  • Fixed fugitives being unable to spawn if more than 4 people signed up for it.
  • -
- -

12 August 2023

-

Absolucy updated:

-
    -
  • Fixed an improperly wired APC in the Medbay lobby on RadStation.
  • -
  • Swapped the position of a plant and water cooler in the Medbay lobby on RadStation, to allow for easier access to the APC.
  • -
-

PowerfulBacon updated:

-
    -
  • Fixes space ninjas being missing from dynamic rulesets.
  • -
  • The capture ninja objective will now return captured mobs.
  • -
  • Fixes the round not rebooting properly.
  • -
  • Adds in a task library for asynchronous behaviour handling.
  • -
  • Following wakes with the hand teleporter takes 10 seconds, is visible on the other side and only teleports the holder of the hand teleporter.
  • -
- -

11 August 2023

-

Bokkiewokkie updated:

-
    -
  • changed how suit boxes apply slowdown
  • -
-

CydiaLamiales updated:

-
    -
  • Fixes light switches that start turned off due to an empty department, turning their lights on instantly and silently for the first time
  • -
  • Refactored the process for making un-staffed departments be dark at roundstart
  • -
  • Slightly reduced the processing cost of flicking light switches
  • -
  • Removed leftover testing code for light switches
  • -
-

itsmeow updated:

-
    -
  • Say-related keys can now be rebound (T, M, O, Y, U, etc).
  • -
  • Added TGUI Asay, Msay, and Dsay for admins and mentors. There is also a preference for this.
  • -
  • Fixed TGUI Say not updating the typing indicator in the Me channel if you are browsing your history, like in Say and Radio.
  • -
-

itsmeow, Mothblocks, Absolucy, Rukofamicom, Ghommie, JohnFulpWillard, Watermelon914, PeterMorrison1, Y0SH1M4S73R, AnturK, GoldenAlpharex, Seris02, tralezab, AndrewL97, MrMelbert, Tastyfish, LemonInTheDark, vinylspiders, kriskog, Couls, MrStonedOne, jlsnow301, actioninja, Synclt21, KoJIT2009 updated:

-
    -
  • Rewrote the entire preferences UI.
  • -
  • Rewrote the entire preferences backend and serialization system to reduce database usage, datumized the addition of preferences.
  • -
  • Flattened some preference database schema stuff, migration is required.
  • -
  • Loadouts now preview the items you equip on your mob, and will replace existing items in the preview window to ensure they preview correctly.
  • -
  • Deadminned admins now retain their access to Donator loadout items.
  • -
  • You can now purchase multiple antag tokens from loadouts.
  • -
  • You can now bind up to 3 keybinds to one overall action.
  • -
  • You can now select specific preferences to be randomized on join rather than globally randomizing your body. You can also make specific preferences only randomize if you are an antagonist.
  • -
  • PDA Theme can now be customized per-character.
  • -
  • Failed job selection now defaults to "Return to lobby" instead of "Be random job"
  • -
  • TGUI Dropdowns now have improved UX experience, and exist outside of the object they are within, instead existing above other UI elements. This means they cannot cause windows to scroll by overflowing, for example.
  • -
  • You can now select preferences to be randomized only when you are an antagonist
  • -
  • Per-character antagonist preferences can now be toggled globally, with per-character prefs only affecting if it's set to off.
  • -
- -

10 August 2023

-

Absolucy updated:

-
    -
  • Hypnoflashes now properly work on sleeping targets again.
  • -
-

BriggsIDP updated:

-
    -
  • replaces meta & delta chem locker with gear locker
  • -
-

Dejaku51 updated:

-
    -
  • fixed wiremod USBs not working
  • -
-

JikkaJoestar updated:

-
    -
  • added library computer, table, and stool
  • -
-

boombaklops updated:

-
    -
  • edaggers are now sharp
  • -
- -

09 August 2023

-

Absolucy updated:

-
    -
  • Added a search bar to the morph stomach UI.
  • -
  • Morphs can now digest nutritious food to recover small amounts of health, however this healing is capped - a morph can only recover up to 20% of its health over the course of 2.5 minutes by digesting food.
  • -
  • Being husked by morph digestion is now considered a burn husk, meaning that synthflesh or rezadone can fix morph digestion victims.
  • -
-

HowToLoLu updated:

-
    -
  • Dense objects can no longer be hidden under the floor, and will now produce a runtime when attempted.
  • -
- -

08 August 2023

-

EvilDragonfiend updated:

-
    -
  • BB implant chat colour will be randomly chosen
  • -
-

Haliris updated:

-
    -
  • Changed and improved some strings used by traumas for forced speech to make them more in line with RP standards.
  • -
-

PowerfulBacon updated:

-
    -
  • Fixes some minor issues with the supermatter distortion effect.
  • -
  • Fixes the causality field not appearing due to being mispelt
  • -
- -

07 August 2023

-

Absolucy & Tamumus updated:

-
    -
  • Fix 'false' Observe targets that would blank your screen or crash you
  • -
-

CydiaLamiales updated:

-
    -
  • Made the air alarm set the lights to vacuum emergency blue mode whenever they send out an alarm, rather than when only manually triggered
  • -
  • Fixed radial menus becoming transparent together with the user
  • -
-

Penwin0 updated:

-
    -
  • Control click grabs are now affected by blocking, as their normal counterparts are.
  • -
-

PowerfulBacon updated:

-
    -
  • Open objectives, objectives which are not tracked by win/lose but have a numeric outcome.
  • -
  • Sabotage machinery objectives
  • -
  • Obtain and detonate explosive objective
  • -
  • Gimmick objective
  • -
  • Refactors traitor objective item spawning to start in "stashes" rather than in the backpack.
  • -
  • You can no longer get steal objectives for certain items when there is no head to own them.
  • -
  • Improves objective code file organisation.
  • -
  • Pizza bombs and the syndicate lavaland base will now properly explode.
  • -
  • The hand teleporter can now lock onto slipspace wakes left behind by bluespace, cult and magic teleportations.
  • -
  • Portals closed by the hand teleporter take 3 seconds to be dispeled. Portals will have an animation upon expiring rather than instantly disappearing.
  • -
  • The hand teleporter will no longer open entry portals inside windows and airlocks
  • -
  • Armour now stacks compoundly rather than additively. 2 sets of 50% armour will result in a total armour rating of 75% rather than 100%.
  • -
  • Refactors the code for armour penetration.
  • -
  • Armour now has a maximum of 75% protection when coming from combat sources (Radsuits won't be capped at 75% protection).
  • -
  • When the amount of armour a player has exceeds 50, additional armour will increase the armour however it will have a diminishing returns effect. This maps [50, Infinity] -> [50, 75] in a way such that adding more armour is always better for you and is guaranteed to result in an improved defense, but having infinite armour will only give you a total protection rating of 75%.
  • -
-

itsmeow updated:

-
    -
  • Optimized autoname camera init, saving 88ms init on MetaStation.
  • -
  • Reverted some verb optimizations, fixing verbs not getting added properly
  • -
- -

06 August 2023

-

CydiaLamiales updated:

-
    -
  • Added a cooldown for dragging mobs into turfs with dense objects through the alt-click menu
  • -
  • Added a new verb for toggling all lights on or off, found in the Secrets panel
  • -
-

ike709 updated:

-
    -
  • Pill code no longer needlessly picks redpill lines unless the pill is actually redpilled.
  • -
-

updooter updated:

-
    -
  • fixed the reviver implant not working
  • -
- -

05 August 2023

-

Absolucy updated:

-
    -
  • Fixed roundstart lighting not properly turning on.
  • -
  • Fix operating computer automatic linking only working if you built the computer first, and the table/bed last.
  • -
  • Operating tables now display when examined if they're linked to a computer or not (and if they are, which computer).
  • -
  • Stasis beds now display WHICH operating computer they're linked to when examined
  • -
-

BriggsIDP updated:

-
    -
  • Updated Meta medbay with feedback
  • -
  • Updated Delta medbay with feedback
  • -
-

HowToLoLu updated:

-
    -
  • Monkey Sentience Helmets now properly ghost players when subjected to: mind transfers, death, and disconnection/ghosting. Note that if you do lose connection you immediately lose control of the monkey.
  • -
  • Stasis Beds can now be rotated by using a wrench while no-one is buckled to it and the maintenance panel is open.
  • -
  • Beds now properly rotate the mob buckled to them. No more waking up on the wrong side of the bed.
  • -
-

PowerfulBacon updated:

-
    -
  • Fixes some internal dynamic calculations, fixes dynamic simulations, fixes default dynamic server config.
  • -
  • Fixes ethereal lighting and luminescent eyes.
  • -
-

RKz, LemonInTheDark updated:

-
    -
  • adds load testing macros, letting you simulate load, without the perils of live sage.
  • -
-

itsmeow updated:

-
    -
  • The SM now has a max positive gas composition accumulation of 5% per tick. This should reduce SM instability, but from testing it does not appear to fix the notorious "SM delam bug".
  • -
  • The SM's power will not update when it is not supposed to.
  • -
  • Fixed double parsing of gas strings.
  • -
- -

04 August 2023

-

PowerfulBacon updated:

-
    -
  • Removes the random artifact name 'bacon'.
  • -
-

Rukofamicom updated:

-
    -
  • Simplemobs can no longer walk through grilles like they don't exist.
  • -
-

itsmeow updated:

-
    -
  • Coder OOC will now sort into the correct chat filters.
  • -
GoonStation 13 Development Team diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 62a19c4084a26..719badc7b24b8 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -41030,3 +41030,314 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - bugfix: wall-mounted sparkers work again rkz, itseasytosee: - code_imp: repathed knives, removing unecessary nesting +2023-10-06: + Absolucy: + - bugfix: Fix html encoding (which messed up apostrophes and such) with brainwashing + objectives in the tgui popup + PowerfulBacon: + - balance: Xeno eggs, Changeling eggs and Zombie tumours are no longer slowed by + stasis beds. + - bugfix: Fixes stat panel buttons overrunning the screen on the MC tab. + - bugfix: Enforces permission requirement on stat button presses. + - rscadd: Adds support for multi-row stat buttons which have sub-buttons. + RKz, Rohesie: + - code_imp: SStimers wont runtime out of bounds if you change world.fps + rkz, ninjanomnom: + - bugfix: hiding action_buttons will no longer clear all overlays +2023-10-07: + Absolucy: + - bugfix: All action mutations now properly take energy chromosomes (which reduce + ability cooldowns) rather than synchronizer chromosomes. + - bugfix: "Cat Claws and Strengthened Wings now properly accept power chromosomes\ + \ \u2014 they already had code that took the power chromosome into account,\ + \ but couldn't actually have said chromosome applied to them." + - rscadd: Shock touch, cryokinesis, and chameleon can now accept power chromosomes + to improve their respective powers. + - rscadd: Acid hands can take a power or sync chromosome, to increase the acid power + or decrease the blood loss respectively. + - soundadd: Cat Claws now changes your attack sound to slashing noises, similar + to moths or lizards. + - tweak: Upgrading a DNA scanner will accordingly update any cooldowns (joker and + injector) for linked genetics consoles. + - rscadd: Inserting a genetics diskette into a genetics console will now actually + mark any mutations on said disk as discovered. This likely won't change anything + during actual rounds, but this will be useful during debugging or perhaps adminbus. + - tweak: You won't waste shock touch charges accidentally clicking on the floor + or a wall anymore. + - code_imp: Cleaned up the code of a lot of mutations quite a bit. + - bugfix: You can no longer obtain a negative temporary blindness duration, which + would lead to permanent blindness. As a result, healing holoparas don't blind + people anymore. + BeeLover66: + - bugfix: Glass of chocolate milk now looks different from glass of (normal) milk + CydiaLamiales: + - bugfix: fixed a runtime in godhand.dm + PestoVerde322: + - bugfix: fixed Reinforced tables' wrong inner corner icons. + PowerfulBacon: + - rscadd: Adds in unit testing for MC stat panels. + mystery3525: + - balance: Abductors can no longer permanently brainwash victims via surgery. +2023-10-09: + DrDuckedGoose: + - bugfix: Fix color correction runtiming + HowToLoLu: + - bugfix: The Particles shot out of the Particle Accelerator no longer phase through + machines + - code_imp: In Projectiles, Piercing behaviour is now prioritized over Phasing behaviour + (the difference between the two is whether it deals damage as it's passing through) + Penwin0: + - rscdel: Removed Deputy from preferences menu + PowerfulBacon: + - rscdel: Reverts changes to clown farting + Rukofamicom: + - rscadd: The server repo has officially reached 10,000 pull requests. Thank you + everyone for all the contributions you make to the game! + - rscadd: To honor this momentous occasion, clowns struggling to fart when they + shouldn't be able to may now occasionally fart a random organ out instead. This + may be lethal. + WhereAmI, RaveRadbury, Inept, softcerv: + - rscadd: Adds Tarot Cards, for any thematic fortune tellings you might require! + Find them in the General loadout tab or Fun Vendor. + - rscadd: Radial Menu for Cards, easier to navigate while playing! + XeonMations: + - rscadd: Added the ability to choose the direction of any office chair you are + sitting in by moving + rkz: + - bugfix: fix nanite cloud controllers disappearing (my fault) +2023-10-10: + BeeLover66: + - bugfix: Duplicate spell burger recipe has been removed + PowerfulBacon: + - bugfix: Fixes the MC tab breaking in stat again due to a null returned stat entry. + rkz, Mothblocks: + - rscadd: Suit Storage Units now use radials! + - rscadd: All engineer Suit Storage Units now start with magboots in them. + - rscadd: SSU radials + - code_imp: convert SSU code to update_appearance +2023-10-12: + EvilDragonfiend: + - bugfix: Input box (the thing that's used in naming things) now accepts Enter and + Esc. + Impish_Delights: + - bugfix: Oozelings no longer autocannibalize inorganic limbs while at low blood + Penwin0: + - bugfix: Fland loads again + Rukofamicom: + - tweak: Goliaths no longer stun with tendril attacks, instead tripping the victim. + They move faster and can more frequently use their tendril attacks instead. + - tweak: Damaging zombie tumors deal brain damage instead of toxin damage. + - tweak: Hostile zombies now heal brain damage over time as well, and fully heal + brain damage upon conversion + - tweak: Brain damage progresses twice as fast as toxin damage so patients die sooner + (this is done because brain damage cannot cause crit) + - tweak: The delay between death and resurrection as a zombie has been increased + by 50% to make up for the lack of time spent in crit. + XeonMations: + - bugfix: Fixes metastation's duplicate bulletproof armour + rkz: + - code_imp: Death upon ye, ancient math! + rkz, Arkatos1, ShizCalev: + - code_imp: adds proc to update an item's action_buttons, removes duplicate code +2023-10-14: + Impish_Delights: + - rscadd: Mosin Obrez! Sawn-off Mosin Nagant; has innate & wild spread, kicks like + a mule, and can be fired 1-handed + - tweak: Any saw type item (and plasmacutters) can be used to saw guns short + - tweak: Energy saws can be used as saws now (similar to chainsaws) + - tweak: You cannot add multiple slings to an improvised shotgun, and it shows on + examine text now + - balance: Mosin Nagant and Obrez require 2-hands to cycle the bolt (up from 1-hand) + - imageadd: Added icon and in-hand sprites for Mosin Obrez + - refactor: removed redundant sawoff code for shotguns, now part of the parent gun/ballistic + item + - code_imp: rewrites some boltaction code to make it less weird for item interactions/attaching + bayonets + - code_imp: sawing checks for TOOL_SAW instead of using bespoke items, is an innate + ballistic gun function, and is more configurable. + Penwin0: + - balance: Excommunicates can no longer purchase syndicate communication keys or + implants +2023-10-15: + HowToLoLu: + - bugfix: Pizzaboxes now accept pizza being put in once again + Impish_Delights: + - rscadd: Combat shotguns can now be toggled in-hand to function like manual pump-action + shotguns + - rscadd: Combat shotguns will 'click' when cycling firing modes. + - bugfix: Compact combat shotgun will now cycle properly when fired one-handed + - code_imp: Fixes runtime when firing a ballistic gun without a magazine installed + - code_imp: Removes unneeded proc for automatic shotguns, functionally the same + - code_imp: Retypes bulldog to be a child of shotgun/automatic +2023-10-16: + HowToLoLu: + - imageadd: Modular Console on/off icon states are now separated into body and keyboard + states instead of being combined + - code_imp: Added another bitflag for smoothing, SMOOTH_BITMASK_SKIP_CORNERS + - bugfix: Modular Consoles no longer look fully broken when only the CPU is broken + - bugfix: Fixed computers becoming invisible in certain arrangements + - bugfix: Some computers with special icons no longer become invisible + - bugfix: Computers now handle smoothing properly when acted on by Narsie or Ratvar + - bugfix: Broken computers now show up properly + Programs-The-Station: + - bugfix: Fixes the Sabotage and Explosives Objective for "the telecommunications + relay". +2023-10-17: + BeeLover66: + - bugfix: Some recipes that wouldn't get reagents from their ingredients now do + PowerfulBacon: + - rscadd: Gun cooldown crosshair. + RKz, Rohesie: + - code_imp: unconsciousness is now a trait, cleaned up its usage in mobility and + stat, which should make it perform a lot quicker and generate less edge-cases + - bugfix: being woken up from unconsciousness should always clear trauma-induced + monochromatic vision + - bugfix: moves a sleeping check in regenerative coma a few lines ahead. It's intended + use in code that voluntarily sleeping provides less healing benefit than entering + a coma through trauma/medicine. + - balance: Which... now technically makes it a balance change. It was always intended, + but using the sleep verb will now heal you less than involuntary unconciousness, + in terms of the regen rate of the regenerative coma +2023-10-18: + HowToLoLu: + - bugfix: Simple animals are no longer immortal + Impish_Delights: + - rscadd: New outfit preset; Bulletproof SecOff. Can be chosen via the select equipment + menu, and through chameleon clothing + - balance: Mosin Nagant deals less damage (40 down from 60) but has armor penetration + (30% AP) + - balance: Nagant Revolver deals less damage (55 down from 60) but has armor penetration + (10% AP) + PowerfulBacon: + - bugfix: Light mode stat panel atom tab will now be readable (Text when you alt + click a tile) + Programs-The-Station: + - bugfix: Fixes the Index Table Component not outputting the values of the table + row. +2023-10-19: + Absolucy, stylemistake: + - rscadd: AFK players will now have flavor text indicating that they're AFK when + examined. + - bugfix: AFK detection now works properly again. + XeonMations: + - bugfix: Replaced metastation's medbay post's radio implant with a radio + itsmeow: + - code_imp: Cleaned up preference serialization and error handling. Cleaned up guest/databaseless + default value generation. + - rscadd: Added logging to preference loading, saving, and edits for better debugging. +2023-10-20: + PowerfulBacon: + - bugfix: Objective stashes may no longer spawn in the bathrooms of head's offices. + RKz, Timberpoes, MrMelbert: + - refactor: machine components are now stored inside the machines themselves, instead + of sent to a magical nullspace and creating errors + - rscadd: As a result of making circuitboards components, you can now do things + like place a bomb on circuitboard, build it in a machine, and it will blow up + like you expect it to! + - bugfix: machines no longer vend their own components accidentally + - bugfix: machines that are supposed to eject contents should actually do so more, + and those that shouldn't, should do so less + itsmeow: + - code_imp: Added code support for the ability to view playtime of removed jobs. + rkz, Tattle: + - admin: added investigate deaths to shed some more light on unusual demises, dustings, + and gibbings +2023-10-21: + Absolucy: + - rscadd: The Obsessed trauma now disguises itself to scanners as monophobia until + a certain amount of time has been spent near the obsession. + AgentCitrus: + - tweak: Oozelings no longer lose hair from radiation or alopecia + DarnTheMarn: + - rscadd: Adds SOP books for each department, found by the techfab and the respective + head's room. Extras can be printed at the library. + Penwin0: + - code_imp: The game compiles again + - bugfix: fixed damage overlays + PowerfulBacon: + - balance: Increased durathread bullet armour (40 from armour, 15 from jumpsuit; + 49 total bullet protection from both) + - rscdel: Reverts AFK players showing up as SSD on examine. + 'Varo; @FuryMcFlurry ': + - rscadd: new moth wing sprites + - rscadd: new moth open wing sprites + mystery3525: + - tweak: Vent crawling now has a 1% chance every 3 seconds of constant movement + of giving notice to everyone nearby that can hear it, meaning once per 5 minutes + of vent crawling does it play a sound to hearing mobs. + - balance: Closed/broken/offline atmospherics machinery now prevents creatures from + vent-crawling through them, though vents/scrubbers remain unchanged and require + being welded still. + rkz: + - refactor: converted random vendors into a spawner, less garbage.dm del horrors. + - bugfix: nightmares can actually utilize their pocket, belt, and ID slots. It was + checking for a jumpsuit on a race that cant wear jumpsuits + - balance: removed restriction prohibiting nightmares from wearing masks + rkz, MrPerson: + - bugfix: Rechargers now have a panel_open state when you screwdriver them! I fixed + it on accident, woops. + - code_imp: converts a few dozen update_icons into their respective update_overlays + or update_icon_states. Adds parent calls. Modernizes them all to update_appearance. + rkz, Rohesie, RandomGamer123: + - code_imp: Immobilization is now a trait. Cleaned up its usage in mobility which + should make it perform a lot quicker and generate less edge-cases + - code_imp: grabbed states and buckled states now have signals we can append to + or check for +2023-10-22: + Absolucy, XDTM: + - rscadd: Added Nanite Protocols, special programs that allow for you to 'upgrade' + some part of your nanites, usually with some tradeoff or downside. + - rscadd: Added Blood Sensor and Nutrition Sensor nanite programs. + - rscadd: Added the Nanite Blade program to nanites, which allows you to manifest + an armblade similar to the xenobio one, locked behind illegal tech. + - rscadd: Added the Vampiric Synthesis program to nanites, which allows you to generate + nanite volume using your own blood volume. This WILL suck you dry if you let + it, please use this with a blood sensor or something! No, you can't cheese it + with Blood Regeneration. + - rscadd: Added the Remote Signaler program to nanites, which functions similarly + to, well, a remote signaler! + - rscadd: Added the Remote Signal Receiver program to nanites, which allows you + to receive remote signaler signals and translate them into nanite signals! + - rscadd: Added the Dermal Toggle program to nanites, which is similar to a dermal + button, but it's an on/off toggle instead. + - rscadd: You can now combine nanite rules, for more advanced logic! + - rscadd: Nanite Cloud Controllers now have neat lil' popup bubbles whenever you + do an action on 'em. + - balance: Researching harmonic nanite tech now provides a 0.1/sec passive regen + rate boost to all nanites! + - tweak: Metabolic Synthesis no longer has a built in-limiter, and can consume ALL + your nutrition if you allow it to. + - balance: Infective exo-locomotion shouldn't be completely useless anymore. + - rscadd: Nanite communication remotes, which can send text communications to certain + nanite programs, are now actually buildable + DarnTheMarn: + - rscadd: Adds a new reagent, maltodextrin. + - rscadd: Adds maltodextrin to donk pockets and vendor food. + - rscdel: Removed donuts and their references from the SecTech + HowToLoLu: + - bugfix: The engineering security office of BoxStation no longer is filled with + cold air roundstart + - bugfix: The air in the control room of Box's Telecomms is no longer filled with + cold air either + PowerfulBacon: + - bugfix: Ventcrawling works again + RKz, MrStonedOne: + - server: adds stack overflow detection for the Master Controller + Rukofamicom: + - tweak: Cryptographic Sequencers (Emags) no longer cause permanent damage to airlocks. + They will still bolt doors open and cause them to completely lose power indefinitely + (which means no silicon access). Pulse or cut/repair power wires to fix emagged + doors. + - tweak: Removes the smoking panel message from airlocks that have been emagged, + since they are no longer permanently damaged + - tweak: Pulsing power wires now resets the time before power comes back on. +2023-10-23: + DrDuckedGoose: + - rscadd: Added the ability to carve Pumpkin People's heads + - tweak: Pumpkin People are now pseudo-mute until carved + rkz: + - bugfix: Whoever made all the batongs into pool noodles has been shot! (fixed immobilization + not applying through stamcrit) +2023-10-24: + Penwin0: + - bugfix: Firefighter helmet now mechanically covers your face, as show by the sprite diff --git a/html/changelogs/AutoChangeLog-pr-9881.yml b/html/changelogs/AutoChangeLog-pr-9881.yml new file mode 100644 index 0000000000000..34d89e40b86b8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9881.yml @@ -0,0 +1,5 @@ +author: RKz, Mothblocks +delete-after: true +changes: + - tweak: teleporter machinery now autolinks. + - code_imp: adds unit test to ensure this does not regress diff --git a/icons/effects/aiming.dmi b/icons/effects/aiming.dmi index 55df5abc37241..0b46a1f7ee219 100644 Binary files a/icons/effects/aiming.dmi and b/icons/effects/aiming.dmi differ diff --git a/icons/effects/blood.dmi b/icons/effects/blood.dmi index 0aaab7e236372..0d46775b270bc 100644 Binary files a/icons/effects/blood.dmi and b/icons/effects/blood.dmi differ diff --git a/icons/effects/cooldown_cursors/cooldown_1.dmi b/icons/effects/cooldown_cursors/cooldown_1.dmi new file mode 100644 index 0000000000000..7dc48c278f1a7 Binary files /dev/null and b/icons/effects/cooldown_cursors/cooldown_1.dmi differ diff --git a/icons/effects/cooldown_cursors/cooldown_2.dmi b/icons/effects/cooldown_cursors/cooldown_2.dmi new file mode 100644 index 0000000000000..d06103c5657ee Binary files /dev/null and b/icons/effects/cooldown_cursors/cooldown_2.dmi differ diff --git a/icons/effects/cooldown_cursors/cooldown_3.dmi b/icons/effects/cooldown_cursors/cooldown_3.dmi new file mode 100644 index 0000000000000..de2a862d75df6 Binary files /dev/null and b/icons/effects/cooldown_cursors/cooldown_3.dmi differ diff --git a/icons/effects/cooldown_cursors/cooldown_4.dmi b/icons/effects/cooldown_cursors/cooldown_4.dmi new file mode 100644 index 0000000000000..1a500ac145431 Binary files /dev/null and b/icons/effects/cooldown_cursors/cooldown_4.dmi differ diff --git a/icons/effects/cooldown_cursors/cooldown_5.dmi b/icons/effects/cooldown_cursors/cooldown_5.dmi new file mode 100644 index 0000000000000..a5e086e5609c8 Binary files /dev/null and b/icons/effects/cooldown_cursors/cooldown_5.dmi differ diff --git a/icons/effects/cooldown_cursors/cooldown_6.dmi b/icons/effects/cooldown_cursors/cooldown_6.dmi new file mode 100644 index 0000000000000..5f0588e8e48f3 Binary files /dev/null and b/icons/effects/cooldown_cursors/cooldown_6.dmi differ diff --git a/icons/effects/cooldown_cursors/cooldown_7.dmi b/icons/effects/cooldown_cursors/cooldown_7.dmi new file mode 100644 index 0000000000000..e88bc13800e67 Binary files /dev/null and b/icons/effects/cooldown_cursors/cooldown_7.dmi differ diff --git a/icons/effects/cooldown_cursors/cooldown_8.dmi b/icons/effects/cooldown_cursors/cooldown_8.dmi new file mode 100644 index 0000000000000..fd68a86b0e9a6 Binary files /dev/null and b/icons/effects/cooldown_cursors/cooldown_8.dmi differ diff --git a/icons/effects/cooldown_cursors/cooldown_9.dmi b/icons/effects/cooldown_cursors/cooldown_9.dmi new file mode 100644 index 0000000000000..ab69f54bda637 Binary files /dev/null and b/icons/effects/cooldown_cursors/cooldown_9.dmi differ diff --git a/icons/mob/inhands/weapons/guns_lefthand.dmi b/icons/mob/inhands/weapons/guns_lefthand.dmi index 08a8c113dcb81..959282b8b17e7 100644 Binary files a/icons/mob/inhands/weapons/guns_lefthand.dmi and b/icons/mob/inhands/weapons/guns_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/guns_righthand.dmi b/icons/mob/inhands/weapons/guns_righthand.dmi index e8f8d9c21f631..6871d331415b7 100644 Binary files a/icons/mob/inhands/weapons/guns_righthand.dmi and b/icons/mob/inhands/weapons/guns_righthand.dmi differ diff --git a/icons/mob/inhands/weapons/melee_lefthand.dmi b/icons/mob/inhands/weapons/melee_lefthand.dmi index 14865d65f01d3..a86107178a34b 100644 Binary files a/icons/mob/inhands/weapons/melee_lefthand.dmi and b/icons/mob/inhands/weapons/melee_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/melee_righthand.dmi b/icons/mob/inhands/weapons/melee_righthand.dmi index 0b12721f1e8b3..7bfe2506a467c 100644 Binary files a/icons/mob/inhands/weapons/melee_righthand.dmi and b/icons/mob/inhands/weapons/melee_righthand.dmi differ diff --git a/icons/mob/moth_antennae.dmi b/icons/mob/moth_antennae.dmi index f1af2cc15807e..34983fef80ef6 100644 Binary files a/icons/mob/moth_antennae.dmi and b/icons/mob/moth_antennae.dmi differ diff --git a/icons/mob/moth_wings.dmi b/icons/mob/moth_wings.dmi index b849886850c77..7bfbdcb477d4d 100644 Binary files a/icons/mob/moth_wings.dmi and b/icons/mob/moth_wings.dmi differ diff --git a/icons/mob/moth_wingsopen.dmi b/icons/mob/moth_wingsopen.dmi index 3c67d76fe4911..595e48b319d81 100644 Binary files a/icons/mob/moth_wingsopen.dmi and b/icons/mob/moth_wingsopen.dmi differ diff --git a/icons/mob/pumpkin_faces.dmi b/icons/mob/pumpkin_faces.dmi new file mode 100644 index 0000000000000..9bda05364f7a3 Binary files /dev/null and b/icons/mob/pumpkin_faces.dmi differ diff --git a/icons/mob/radial.dmi b/icons/mob/radial.dmi index 1ea84e38119cd..d0c94f15ad86c 100644 Binary files a/icons/mob/radial.dmi and b/icons/mob/radial.dmi differ diff --git a/icons/obj/computer.dmi b/icons/obj/computer.dmi index cd93e4d3878ac..c302a2a28390c 100644 Binary files a/icons/obj/computer.dmi and b/icons/obj/computer.dmi differ diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index 3b7a692b02c7b..8864da94ae60c 100644 Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ diff --git a/icons/obj/food/mexican.dmi b/icons/obj/food/mexican.dmi new file mode 100644 index 0000000000000..912a8a89bb7f6 Binary files /dev/null and b/icons/obj/food/mexican.dmi differ diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index 3bc8fb1398ba3..b69972dd60e2d 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index c73e234b70f30..5a2ab14820f70 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/modular_console.dmi b/icons/obj/modular_console.dmi index fba79f7a8879e..ace5449346bdf 100644 Binary files a/icons/obj/modular_console.dmi and b/icons/obj/modular_console.dmi differ diff --git a/icons/obj/nanite.dmi b/icons/obj/nanite.dmi new file mode 100644 index 0000000000000..7a362e2fdaad8 Binary files /dev/null and b/icons/obj/nanite.dmi differ diff --git a/icons/obj/smooth_structures/tables/reinforced_table.dmi b/icons/obj/smooth_structures/tables/reinforced_table.dmi index e8320d9222666..f603c36e131e6 100644 Binary files a/icons/obj/smooth_structures/tables/reinforced_table.dmi and b/icons/obj/smooth_structures/tables/reinforced_table.dmi differ diff --git a/icons/obj/toy.dmi b/icons/obj/toy.dmi index 65b5da4d125c6..3ef7f3258cfd4 100644 Binary files a/icons/obj/toy.dmi and b/icons/obj/toy.dmi differ diff --git a/icons/obj/turrets.dmi b/icons/obj/turrets.dmi index e4dfee09735e5..5d26a08665515 100644 Binary files a/icons/obj/turrets.dmi and b/icons/obj/turrets.dmi differ diff --git a/tgui/docs/tutorial-and-examples.md b/tgui/docs/tutorial-and-examples.md index 3dba803c959ac..5f8c9dd8e5549 100644 --- a/tgui/docs/tutorial-and-examples.md +++ b/tgui/docs/tutorial-and-examples.md @@ -310,7 +310,7 @@ upon code review): if("copypasta") var/newvar = params["var"] // A demo of proper input sanitation. - var = CLAMP(newvar, min_val, max_val) + var = clamp(newvar, min_val, max_val) . = TRUE update_icon() // Not applicable to all objects. ``` diff --git a/tgui/packages/tgui-panel/stat/StatText.js b/tgui/packages/tgui-panel/stat/StatText.js index 1273c70b1ef2e..aa844f2a21642 100644 --- a/tgui/packages/tgui-panel/stat/StatText.js +++ b/tgui/packages/tgui-panel/stat/StatText.js @@ -4,6 +4,7 @@ import { useSettings } from '../settings'; import { selectStatPanel } from './selectors'; import { Divider, Table } from '../../tgui/components'; import { STAT_TEXT, STAT_BUTTON, STAT_ATOM, STAT_DIVIDER, STAT_BLANK } from './constants'; +import { capitalize } from 'common/string'; export const StatText = (props, context) => { const stat = useSelector(context, selectStatPanel); @@ -19,24 +20,31 @@ export const StatText = (props, context) => {
{statPanelData - ? Object.keys(statPanelData).map( - (key) => - !!statPanelData[key] && - ((statPanelData[key].type === STAT_TEXT && ) || - (statPanelData[key].type === STAT_BUTTON && ( - - )) || - (statPanelData[key].type === STAT_ATOM && ( - - )) || - (statPanelData[key].type === STAT_DIVIDER && ) || - (statPanelData[key].type === STAT_BLANK &&
)) - ) + ? Object.keys(statPanelData) + .filter((x) => x !== null) + .sort((a, b) => { + return StatTagToPriority(statPanelData[b].tag) - StatTagToPriority(statPanelData[a].tag); + }) + .map( + (key) => + !!statPanelData[key] && + ((statPanelData[key].type === STAT_TEXT && ) || + (statPanelData[key].type === STAT_BUTTON && ( + + )) || + (statPanelData[key].type === STAT_ATOM && ( + + )) || + (statPanelData[key].type === STAT_DIVIDER && ) || + (statPanelData[key].type === STAT_BLANK &&
)) + ) : 'No data'} {Object.keys(verbs).map((verb) => ( @@ -46,6 +54,46 @@ export const StatText = (props, context) => { ); }; +const StatTagToPriority = (text) => { + switch (text) { + case 'You': + return 11; + case 'Human': + return 10; + case 'Mob': + return 9; + case 'Structure': + return 8; + case 'Machinery': + return 7; + case 'Item': + return 6; + case 'Turf': + return 4; + } + return 5; +}; + +const StatTagToClassName = (text) => { + switch (text) { + case 'You': + return 'StatAtomTag Self'; + case 'Turf': + return 'StatAtomTag Turf'; + case 'Human': + return 'StatAtomTag Human'; + case 'Mob': + return 'StatAtomTag Mob'; + case 'Structure': + return 'StatAtomTag Structure'; + case 'Machinery': + return 'StatAtomTag Machinery'; + case 'Item': + return 'StatAtomTag Item'; + } + return 'StatAtomTag Other'; +}; + /* * FLEX COMPATIBLE */ @@ -61,10 +109,12 @@ export const StatTextText = (props, context) => { }; export const StatTextButton = (props, context) => { - const { title, text, action_id, params = [] } = props; + const { title, text, action_id, params = [], multirow = false, buttons = [] } = props; return ( + + ))} + + {text} + + + ) : ( + <> + + {title} + {buttons.map((buttonInfo) => ( + + + + ))} + + + {text} + + + )} ); @@ -86,13 +189,16 @@ const storeAtomRef = (value) => { const retrieveAtomRef = () => janky_storage; export const StatTextAtom = (props, context) => { - const { atom_name, atom_ref } = props; + const { atom_name, atom_ref, atom_tag } = props; storeAtomRef(null); return ( - + ); diff --git a/tgui/packages/tgui-panel/styles/components/Stat.scss b/tgui/packages/tgui-panel/styles/components/Stat.scss index 832b765a32be5..3ac44c7cfe527 100644 --- a/tgui/packages/tgui-panel/styles/components/Stat.scss +++ b/tgui/packages/tgui-panel/styles/components/Stat.scss @@ -57,3 +57,46 @@ $border-color: color.scale(colors.fg(colors.$primary), $lightness: 75%) !default .StatTabBackground { border-bottom: math.div(1em, 6) solid #666666; } + +.StatAtomElement { + cursor: pointer; +} + +.StatAtomTag { + background-color: #ff94f1; + color: #2b2b2b; + border-radius: 5px; + text-align: center; + + &.Structure { + background-color: #b2aaf1; + } + + &.Turf { + background-color: #f1eaaa; + } + + &.Self { + background-color: #fafafa; + } + + &.Human { + background-color: #aff1aa; + } + + &.Mob { + background-color: #aaf1d3; + } + + &.Machinery { + background-color: #f5b59c; + } + + &.Item { + background-color: #f59cbb; + } + + &.Other { + background-color: #adadad; + } +} diff --git a/tgui/packages/tgui/components/Button.js b/tgui/packages/tgui/components/Button.js index a4662f3db63a5..ba8486765e8a1 100644 --- a/tgui/packages/tgui/components/Button.js +++ b/tgui/packages/tgui/components/Button.js @@ -254,12 +254,12 @@ export class ButtonInput extends Component { this.commitResult(e); }} onKeyDown={(e) => { - if (e.keyCode === KEY_ENTER) { + if (e.key === 'Enter' || e.keyCode === KEY_ENTER) { this.setInInput(false); this.commitResult(e); return; } - if (e.keyCode === KEY_ESCAPE) { + if (e.key === 'Esc' || e.keyCode === KEY_ESCAPE) { this.setInInput(false); } }} diff --git a/tgui/packages/tgui/interfaces/AntagInfoBrainwashed.tsx b/tgui/packages/tgui/interfaces/AntagInfoBrainwashed.tsx index ec189eba36351..b8c018dd76933 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoBrainwashed.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoBrainwashed.tsx @@ -2,6 +2,7 @@ import { useBackend } from '../backend'; import { Icon, Section, Stack } from '../components'; import { BooleanLike } from 'common/react'; import { Window } from '../layouts'; +import { sanitizeText } from '../sanitize'; type Objective = { count: number; @@ -44,7 +45,7 @@ export const AntagInfoBrainwashed = () => { ); }; -const ObjectivePrintout = (props, context) => { +const ObjectivePrintout = (_props, context) => { const { data } = useBackend(context); const { objectives } = data; return ( @@ -57,7 +58,13 @@ const ObjectivePrintout = (props, context) => { objectives.map((objective) => ( <> - {objective.count}. {objective.explanation} + {objective.count}.{' '} + This Directive must be followed. diff --git a/tgui/packages/tgui/interfaces/NaniteCloudControl.js b/tgui/packages/tgui/interfaces/NaniteCloudControl.js index 8a65b4943cb45..50698257db936 100644 --- a/tgui/packages/tgui/interfaces/NaniteCloudControl.js +++ b/tgui/packages/tgui/interfaces/NaniteCloudControl.js @@ -1,5 +1,5 @@ -import { useBackend } from '../backend'; -import { Box, Button, Collapsible, Grid, LabeledList, NoticeBox, NumberInput, Section } from '../components'; +import { useBackend, useLocalState } from '../backend'; +import { Box, Button, Collapsible, Dropdown, Grid, LabeledList, NoticeBox, NumberInput, Section, Stack } from '../components'; import { Window } from '../layouts'; export const NaniteDiskBox = (props, context) => { @@ -133,9 +133,12 @@ export const NaniteCloudBackupList = (props, context) => { )); }; -export const NaniteCloudBackupDetails = (props, context) => { +export const NaniteCloudBackupDetails = (_props, context) => { const { act, data } = useBackend(context); const { current_view, disk, has_program, cloud_backup } = data; + const [combineSelection, setCombineSelection] = useLocalState(context, 'combineSelection', false); + const [toCombine, setToCombine] = useLocalState(context, 'toCombine', []); + const [combineOp, setCombineOp] = useLocalState(context, 'combineOp', 'AND'); const can_rule = (disk && disk.can_rule) || false; @@ -178,21 +181,70 @@ export const NaniteCloudBackupDetails = (props, context) => { level={2} buttons={ !!can_rule && ( -