diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm index cb963246b394..a470f776aa87 100644 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm +++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm @@ -6,52 +6,62 @@ /turf/simulated/mineral/random/volcanic, /area/lavaland/surface/outdoors) "c" = ( +/obj/effect/mapping_helpers/no_lava, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "d" = ( /obj/structure/stone_tile/block{ dir = 8 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "e" = ( /obj/structure/stone_tile{ dir = 8 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "f" = ( /obj/structure/stone_tile/cracked{ dir = 1 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "g" = ( /obj/structure/stone_tile/cracked{ dir = 8 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "h" = ( /obj/structure/stone_tile/block{ dir = 4 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "i" = ( /obj/structure/stone_tile{ dir = 4 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "j" = ( /obj/structure/stone_tile, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "k" = ( /obj/structure/stone_tile/cracked{ dir = 4 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "l" = ( @@ -59,6 +69,7 @@ /obj/structure/stone_tile{ dir = 4 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "m" = ( @@ -68,22 +79,26 @@ /obj/structure/stone_tile{ dir = 1 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "n" = ( /obj/structure/stone_tile/block/cracked{ dir = 4 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "o" = ( /obj/structure/stone_tile/block, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "p" = ( /obj/structure/stone_tile/block/cracked{ dir = 1 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "q" = ( @@ -99,6 +114,7 @@ /obj/structure/stone_tile/block{ dir = 1 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "s" = ( @@ -129,6 +145,7 @@ dir = 4 }, /obj/structure/stone_tile/cracked, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "w" = ( @@ -145,10 +162,16 @@ /obj/structure/stone_tile/block{ dir = 1 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "y" = ( /obj/structure/stone_tile/cracked, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"I" = ( +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) @@ -157,13 +180,15 @@ a a a b +a b +a b b b b a -a +b a a a @@ -171,10 +196,12 @@ a (2,1,1) = {" a a +a +b +b +b b b -c -c b b b @@ -185,75 +212,85 @@ a a "} (3,1,1) = {" +a b b b -c -d -c -c -b b +I +d +I +I +I +I +I b b b b -a "} (4,1,1) = {" b b -c -c +b +I +I +I k o +I +I c -c -c -c -b -b +I +I b b +a "} (5,1,1) = {" +a b -c +I +I d g -c +I p -c +I v -c -c -c -c +I +I +I +I b b "} (6,1,1) = {" b -c -c +b +I +I +I h l e s j -c +I d e -c -c +I +b b "} (7,1,1) = {" +a b -c -c -c -c +I +I +I +I +I q t w @@ -261,86 +298,96 @@ x y p e -c +b b "} (8,1,1) = {" b -c +b +I +I e i m j u e -c +I f d y -c +b b "} (9,1,1) = {" b -c +b +I +I f j -c +I r -c +I o -c -c -c -c +I +I +I +I b b "} (10,1,1) = {" +a b b -c -c -c +I +I +I +k o -c -c -b -b -c -b +I +I +I +I +I b b +a "} (11,1,1) = {" b b b -c -n -c -c b b +I +n +I +I +I +I +I b b b b -a "} (12,1,1) = {" a +a +a +b +b +b +b b b -c -c -c b b b b b -a a a "} @@ -348,15 +395,17 @@ a a a b +a +a +a b b b -b -a -a a +b a a +b a a "} diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm index 3d224a617d6f..4007379ec985 100644 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm +++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm @@ -9,65 +9,69 @@ /obj/structure/stone_tile/surrounding_tile{ dir = 4 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "d" = ( /obj/structure/stone_tile/block{ dir = 1 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "e" = ( /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 1 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "f" = ( /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"g" = ( -/obj/structure/stone_tile{ - dir = 4 - }, -/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) "h" = ( /obj/structure/stone_tile/block/cracked{ dir = 8 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "i" = ( /obj/structure/stone_tile/surrounding_tile/cracked, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "j" = ( /obj/structure/stone_tile/block/cracked{ dir = 4 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "k" = ( /obj/structure/stone_tile/surrounding_tile{ dir = 8 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "l" = ( /obj/structure/stone_tile/surrounding_tile, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "m" = ( /obj/structure/stone_tile/cracked{ dir = 4 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "n" = ( /obj/structure/stone_tile/block{ dir = 4 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "o" = ( @@ -78,6 +82,7 @@ /obj/structure/stone_tile/cracked{ dir = 8 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "p" = ( @@ -85,6 +90,7 @@ /obj/structure/stone_tile/block/cracked{ dir = 1 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "q" = ( @@ -94,6 +100,7 @@ /obj/structure/stone_tile{ dir = 1 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "r" = ( @@ -101,6 +108,7 @@ dir = 8 }, /obj/structure/stone_tile/cracked, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "s" = ( @@ -113,75 +121,101 @@ /obj/structure/stone_tile/cracked{ dir = 8 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "t" = ( /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 4 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "v" = ( /obj/structure/stone_tile/block/cracked, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "w" = ( /obj/structure/stone_tile/block, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "x" = ( /obj/structure/stone_tile/block/cracked{ dir = 1 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "y" = ( /obj/structure/stone_tile, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "z" = ( /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 8 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "A" = ( /obj/structure/stone_tile/cracked{ dir = 8 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "B" = ( /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/guidance{ dir = 8 }, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"G" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"Q" = ( +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) (1,1,1) = {" a +b a b b b b a +a +b +b b b a -a -a -a +b a a "} (2,1,1) = {" -a b b b b b +f +b +b +b +b b b b @@ -189,153 +223,207 @@ b b a a +"} +(3,1,1) = {" a +b +Q +Q +Q +Q +Q +Q +Q +Q +Q +Q +b +f +b +b a "} -(3,1,1) = {" +(4,1,1) = {" b b +Q c h k -f -f -f +Q +Q +Q k -f +Q +Q +Q +Q +b b b -a -a -a "} -(4,1,1) = {" +(5,1,1) = {" b b +Q d c l -f -f -f +Q +Q +Q v -f -b +Q +Q +Q +Q +Q b -b -a a "} -(5,1,1) = {" -b +(6,1,1) = {" +a b +Q e i m k -f +Q t w -f -f -b +Q +Q +Q +Q +Q b b -a "} -(6,1,1) = {" +(7,1,1) = {" a b -f -f -f +b +Q +Q +G o r q w -f -f -f -f +Q +Q +Q +Q +Q b b "} -(7,1,1) = {" +(8,1,1) = {" b b b -f -f +Q +Q +Q p B s -f -f +Q +Q q n A -f +Q b -"} -(8,1,1) = {" b +"} +(9,1,1) = {" +a b -g -f +Q +Q +Q c q s q k x -f +Q z d -f +Q +b b "} -(9,1,1) = {" -a +(10,1,1) = {" b -f +b +Q +G j n j -f +Q e n y -f +Q n y +Q +b +a +"} +(11,1,1) = {" b b +Q +Q +Q +Q +Q +Q +Q +Q +Q +Q +Q +Q +b +b +a "} -(10,1,1) = {" +(12,1,1) = {" a b -b -f -f -f -f -f +Q +Q +Q +Q +Q +Q +Q +Q +Q +Q f b b -f -f b b "} -(11,1,1) = {" -a -a +(13,1,1) = {" b b b b b +f +f +b +b b b b @@ -345,8 +433,7 @@ b b a "} -(12,1,1) = {" -a +(14,1,1) = {" a a b @@ -355,10 +442,13 @@ b b b b -a +b a b b a a +b +a +a "} diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm index 0f6c96fb0413..808acab4c180 100644 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm +++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm @@ -15,6 +15,7 @@ /obj/structure/stone_tile/block{ dir = 4 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "e" = ( @@ -24,6 +25,7 @@ /obj/structure/stone_tile/block/cracked{ dir = 4 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "f" = ( @@ -33,18 +35,21 @@ /obj/structure/stone_tile/block/cracked{ dir = 8 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "g" = ( /obj/structure/stone_tile{ dir = 4 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "h" = ( /obj/structure/stone_tile{ dir = 1 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "i" = ( @@ -55,6 +60,7 @@ dir = 1 }, /obj/structure/stone_tile/cracked, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "k" = ( @@ -65,6 +71,7 @@ /obj/structure/stone_tile/cracked{ dir = 8 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "l" = ( @@ -75,6 +82,7 @@ /obj/structure/stone_tile{ dir = 1 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "m" = ( @@ -85,6 +93,7 @@ /obj/structure/stone_tile/cracked{ dir = 4 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "n" = ( @@ -95,12 +104,14 @@ dir = 8 }, /obj/structure/stone_tile/cracked, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "o" = ( /obj/structure/stone_tile/cracked{ dir = 4 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "p" = ( @@ -111,6 +122,7 @@ dir = 8 }, /obj/structure/stone_tile, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "q" = ( @@ -121,6 +133,7 @@ /obj/structure/stone_tile{ dir = 8 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "r" = ( @@ -131,20 +144,24 @@ dir = 8 }, /obj/structure/stone_tile, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "s" = ( /obj/structure/stone_tile/surrounding_tile/cracked, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "t" = ( /obj/structure/stone_tile/block/cracked, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "u" = ( /obj/structure/stone_tile/surrounding_tile{ dir = 8 }, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "v" = ( @@ -152,6 +169,7 @@ dir = 6 }, /obj/structure/stone_tile/center, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "w" = ( @@ -162,18 +180,52 @@ dir = 4 }, /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/hunter, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) +"E" = ( +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"U" = ( +/turf/simulated/mineral/random/volcanic, +/area/template_noop) (1,1,1) = {" a a a a +b +a +a +a +b +a +b +a +b +b +a +a a a a a +"} +(2,1,1) = {" +a +b +b +b +b +b +a +b +b +b +b +b b b b @@ -183,80 +235,166 @@ a a a "} -(2,1,1) = {" +(3,1,1) = {" +a a b b b +b +b +a +b +b +E +E +E +b +b +b +b +b +a +a +"} +(4,1,1) = {" a a b +E +E +E b b -c -c b +E +E +c b +E +E +E +E b a a "} -(3,1,1) = {" +(5,1,1) = {" +a b b b b +E +E +b +E +E +c +E +E +E b b b b +b +a +"} +(6,1,1) = {" +b +b +E +E +b c -g -n +E +E +E c +E +E +c +b +b +b c b b a "} -(4,1,1) = {" +(7,1,1) = {" +a +b b +E +E +E c +E +E +E +E c +E +g +n +E +E +b +b +b +"} +(8,1,1) = {" +b b b b c -c +E +E +E +E +E +E +E g l h q -c -c +E +E b b "} -(5,1,1) = {" +(9,1,1) = {" b -c -c -c -c -c -c +b +b +E +E +E +E +E +E +E +E g i -c -c +E +E h s -c -c +E b +a "} -(6,1,1) = {" +(10,1,1) = {" +b b +c +c +E d e e @@ -270,67 +408,145 @@ w f t v -c +b b "} -(7,1,1) = {" +(11,1,1) = {" b -c -c -c -c -c -c +b +b +E +E +E +E +E +E +E +E h k -c -c +E +E o u -c +E b b "} -(8,1,1) = {" +(12,1,1) = {" +a b b b c -c -c -c -c +E +E +E +E +E +E +E h m o r -c -b -b +E +E b +a "} -(9,1,1) = {" +(13,1,1) = {" a b +c +E +E +E +c +E +E +E +E +c +E +h +p +E +E +c +b +b +"} +(14,1,1) = {" b b +E +E b c +E +E +E c +E +E c +b +b c -h -p +b +b +b +b +"} +(15,1,1) = {" +a +b +b +b +b +E +E c +E +E c +E +E +E +b +b +b b b a "} -(10,1,1) = {" +(16,1,1) = {" a +b +b +E +E +E +b +b +c +E +E +b +b +E +E +E +E +b a a +"} +(17,1,1) = {" +b +b +b b b b @@ -338,18 +554,23 @@ b b c c -c -c +E +E +E +b +b +b b b a a "} -(11,1,1) = {" -a -a +(18,1,1) = {" a +b a +b +b a b b @@ -361,5 +582,30 @@ b b b a +b +a +a +a +"} +(19,1,1) = {" +a +a +a +b +a +a +a +b +a +U +b +b +a +a +a +a +a +a +a a "} diff --git a/code/__DEFINES/preferences_defines.dm b/code/__DEFINES/preferences_defines.dm index 6da88d175092..8272092d330d 100644 --- a/code/__DEFINES/preferences_defines.dm +++ b/code/__DEFINES/preferences_defines.dm @@ -63,8 +63,9 @@ #define PREFTOGGLE_2_DANCE_DISCO (1<<16) // 65536 #define PREFTOGGLE_2_MOD_ACTIVATION_METHOD (1<<17) // 131072 #define PREFTOGGLE_2_PARALLAX_IN_DARKNESS (1<<18) // 262144 +#define PREFTOGGLE_2_DISABLE_TGUI_LISTS (1<<19) // 524288 -#define TOGGLES_2_TOTAL 524287 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined. +#define TOGGLES_2_TOTAL 1048575 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined. #define TOGGLES_2_DEFAULT (PREFTOGGLE_2_FANCYUI|PREFTOGGLE_2_ITEMATTACK|PREFTOGGLE_2_WINDOWFLASHING|PREFTOGGLE_2_RUNECHAT|PREFTOGGLE_2_DEATHMESSAGE|PREFTOGGLE_2_EMOTE_BUBBLE|PREFTOGGLE_2_SEE_ITEM_OUTLINES|PREFTOGGLE_2_THOUGHT_BUBBLE|PREFTOGGLE_2_DANCE_DISCO|PREFTOGGLE_2_MOD_ACTIVATION_METHOD) diff --git a/code/__HELPERS/path.dm b/code/__HELPERS/path.dm index 10daae7ee77a..5c4a4095c559 100644 --- a/code/__HELPERS/path.dm +++ b/code/__HELPERS/path.dm @@ -1,3 +1,5 @@ +#define GET_DIST_REAL(turf_a, turf_b) sqrt((turf_a.x - turf_b.x) ** 2 + (turf_a.y - turf_b.y) ** 2) + /** * This file contains the stuff you need for using JPS (Jump Point Search) pathing, an alternative to A* that skips * over large numbers of uninteresting tiles resulting in much quicker pathfinding solutions. @@ -65,18 +67,21 @@ var/jumps /// Nodes store the endgoal so they can process their heuristic without a reference to the pathfind datum var/turf/node_goal + /// Multiplier for making diagonals more expensive + var/diagonal_move_mult = 1 -/datum/jps_node/New(turf/our_tile, datum/jps_node/incoming_previous_node, jumps_taken, turf/incoming_goal) +/datum/jps_node/New(turf/our_tile, datum/jps_node/incoming_previous_node, jumps_taken, turf/incoming_goal, is_diagonal) tile = our_tile jumps = jumps_taken + diagonal_move_mult = (is_diagonal ? SQRT_2 : 1) if(incoming_goal) // if we have the goal argument, this must be the first/starting node node_goal = incoming_goal else if(incoming_previous_node) // if we have the parent, this is from a direct lateral/diagonal scan, we can fill it all out now previous_node = incoming_previous_node number_tiles = previous_node.number_tiles + jumps node_goal = previous_node.node_goal - heuristic = get_dist(tile, node_goal) - f_value = number_tiles + heuristic + heuristic = GET_DIST_REAL(tile, node_goal) + f_value = heuristic + previous_node.number_tiles + (jumps * diagonal_move_mult) // otherwise, no parent node means this is from a subscan lateral scan, so we just need the tile for now until we call [datum/jps/proc/update_parent] on it /datum/jps_node/Destroy(force, ...) @@ -86,10 +91,10 @@ /datum/jps_node/proc/update_parent(datum/jps_node/new_parent) previous_node = new_parent node_goal = previous_node.node_goal - jumps = get_dist(tile, previous_node.tile) + jumps = GET_DIST_REAL(tile, previous_node.tile) number_tiles = previous_node.number_tiles + jumps - heuristic = get_dist(tile, node_goal) - f_value = number_tiles + heuristic + heuristic = GET_DIST_REAL(tile, node_goal) + f_value = heuristic + previous_node.number_tiles + (jumps * diagonal_move_mult) /// TODO: Macro this to reduce proc overhead /proc/HeapPathWeightCompare(datum/jps_node/a, datum/jps_node/b) @@ -149,7 +154,7 @@ return if(start.z != end.z || start == end) //no pathfinding between z levels return - if(max_distance && (max_distance < get_dist(start, end))) //if start turf is farther than max_distance from end turf, no need to do anything + if(max_distance && (max_distance < GET_DIST_REAL(start, end))) //if start turf is farther than max_distance from end turf, no need to do anything return //initialization @@ -260,7 +265,7 @@ if(!CAN_STEP(lag_turf, current_turf)) return - if(current_turf == end || (mintargetdist && (get_dist(current_turf, end) <= mintargetdist))) + if(current_turf == end || (mintargetdist && (GET_DIST_REAL(current_turf, end) <= mintargetdist))) var/datum/jps_node/final_node = new(current_turf, parent_node, steps_taken) sources[current_turf] = original_turf if(parent_node) // if this is a direct lateral scan we can wrap up, if it's a subscan from a diag, we need to let the diag make their node first, then finish @@ -321,8 +326,8 @@ if(!CAN_STEP(lag_turf, current_turf)) return - if(current_turf == end || (mintargetdist && (get_dist(current_turf, end) <= mintargetdist))) - var/datum/jps_node/final_node = new(current_turf, parent_node, steps_taken) + if(current_turf == end || (mintargetdist && (GET_DIST_REAL(current_turf, end) <= mintargetdist))) + var/datum/jps_node/final_node = new(current_turf, parent_node, steps_taken, is_diagonal = TRUE) sources[current_turf] = original_turf unwind_path(final_node) return @@ -360,12 +365,12 @@ possible_child_node = (lateral_scan_spec(current_turf, SOUTH) || lateral_scan_spec(current_turf, EAST)) if(interesting || possible_child_node) - var/datum/jps_node/newnode = new(current_turf, parent_node, steps_taken) + var/datum/jps_node/newnode = new(current_turf, parent_node, steps_taken, is_diagonal = TRUE) open.Insert(newnode) if(possible_child_node) possible_child_node.update_parent(newnode) open.Insert(possible_child_node) - if(possible_child_node.tile == end || (mintargetdist && (get_dist(possible_child_node.tile, end) <= mintargetdist))) + if(possible_child_node.tile == end || (mintargetdist && (GET_DIST_REAL(possible_child_node.tile, end) <= mintargetdist))) unwind_path(possible_child_node) return @@ -437,3 +442,4 @@ #undef CAN_STEP #undef STEP_NOT_HERE_BUT_THERE +#undef GET_DIST_REAL diff --git a/code/__HELPERS/trait_helpers.dm b/code/__HELPERS/trait_helpers.dm index 532d3a10336e..71e15c25375a 100644 --- a/code/__HELPERS/trait_helpers.dm +++ b/code/__HELPERS/trait_helpers.dm @@ -221,6 +221,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_IPC_JOINTS_SEALED "ipc_joints_sealed" // The IPC's limbs will not pop off bar sharp damage (aka like a human), but will take slightly more stamina damage #define TRAIT_HAS_GPS "has_gps" // used for /Stat #define TRAIT_CAN_VIEW_HEALTH "can_view_health" // Also used for /Stat +#define TRAIT_MAGPULSE "magnetificent" // Used for anything that is magboot related //***** MIND TRAITS *****/ #define TRAIT_HOLY "is_holy" // The mob is holy in regards to religion diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index 3a9bd855c7a1..361f75b4846e 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -85,7 +85,8 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_DODGE_ALL_THROWN_OBJECTS" = TRAIT_DODGE_ALL_OBJECTS, "TRAIT_SUPERMATTER_IMMUNE" = TRAIT_SUPERMATTER_IMMUNE, "TRAIT_BADASS" = TRAIT_BADASS, - "TRAIT_FORCED_STANDING" = TRAIT_FORCED_STANDING + "TRAIT_FORCED_STANDING" = TRAIT_FORCED_STANDING, + "TRAIT_MAGPULSE" = TRAIT_MAGPULSE ), /datum/mind = list( diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index d7898ccf2a32..582366258b0d 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -117,14 +117,20 @@ GLOBAL_LIST_EMPTY(PDA_Manifest) break var/list/all_jobs = get_job_datums() + var/is_custom_job = TRUE for(var/datum/job/J in all_jobs) var/list/alttitles = get_alternate_titles(J.title) - if(!J) continue + if(J.title == real_title) + is_custom_job = FALSE if(assignment in alttitles) real_title = J.title + is_custom_job = FALSE break + if(is_custom_job) + real_title = foundrecord.fields["real_rank"] + if(foundrecord) foundrecord.fields["rank"] = assignment foundrecord.fields["real_rank"] = real_title diff --git a/code/datums/outfits/outfit_admin.dm b/code/datums/outfits/outfit_admin.dm index b9c3e8c7ebf6..9c457d9c7209 100644 --- a/code/datums/outfits/outfit_admin.dm +++ b/code/datums/outfits/outfit_admin.dm @@ -1020,7 +1020,7 @@ /obj/item/stack/tile/plasteel = 7 ) -/datum/outfit/admin/tournament_janitor/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) +/datum/outfit/admin/tournament/tournament_janitor/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) . = ..() if(visualsOnly) return diff --git a/code/datums/outfits/vv_outfit.dm b/code/datums/outfits/vv_outfit.dm index 5ab0e3aba83a..1b986aa12140 100644 --- a/code/datums/outfits/vv_outfit.dm +++ b/code/datums/outfits/vv_outfit.dm @@ -3,10 +3,10 @@ /datum/outfit/varedit var/list/vv_values var/list/stored_access - var/update_id_name = FALSE //If the name of the human is same as the name on the id they're wearing we'll update provided id when equipping + var/update_id_name = FALSE // If the name of the human is same as the name on the id they're wearing we'll update provided id when equipping /datum/outfit/varedit/pre_equip(mob/living/carbon/human/H, visualsOnly) - H.delete_equipment() //Applying VV to wrong objects is not reccomended. + H.delete_equipment() // Applying VV to wrong objects is not reccomended. . = ..() /datum/outfit/varedit/proc/set_equipment_by_slot(slot, item_path) @@ -46,27 +46,29 @@ /proc/collect_vv(obj/item/I) - //Temporary/Internal stuff, do not copy these. - var/static/list/ignored_vars = list("vars","x","y","z","plane","layer","override","animate_movement","pixel_step_size","screen_loc","fingerprintslast","tip_timer") - - if(istype(I)) - var/list/vedits = list() - for(var/varname in I.vars) - if(!I.can_vv_get(varname)) - continue - if(varname in ignored_vars) - continue - var/vval = I.vars[varname] // Can't check initial() because it doesn't work on a list index - //Only text/numbers and icons variables to make it less weirdness prone. - if(!istext(vval) && !isnum(vval) && !isicon(vval)) - continue - vedits[varname] = I.vars[varname] - return vedits + if(!istype(I)) + return + + // Temporary/Internal stuff, do not copy these. + var/static/list/ignored_vars = list("vars", "x", "y", "z", "plane", "layer", "override", "animate_movement", "pixel_step_size", "screen_loc", "fingerprintslast", "tip_timer") + + var/list/vedits = list() + for(var/varname in I.vars) + if(!I.can_vv_get(varname)) + continue + if(varname in ignored_vars) + continue + var/vval = I.vars[varname] // Can't check initial() because it doesn't work on a list index + // Only text/numbers and icons variables to make it less weirdness prone. + if(!istext(vval) && !isnum(vval) && !isicon(vval)) + continue + vedits[varname] = I.vars[varname] + return vedits /mob/living/carbon/human/proc/copy_outfit() var/datum/outfit/varedit/O = new - //Copy equipment + // Copy equipment var/list/result = list() var/list/slots_to_check = list(SLOT_HUD_JUMPSUIT, SLOT_HUD_BACK, SLOT_HUD_OUTER_SUIT, SLOT_HUD_BELT, SLOT_HUD_GLOVES, SLOT_HUD_SHOES, SLOT_HUD_HEAD, SLOT_HUD_WEAR_MASK, SLOT_HUD_LEFT_EAR, SLOT_HUD_RIGHT_EAR, SLOT_HUD_GLASSES, SLOT_HUD_WEAR_ID, SLOT_HUD_WEAR_PDA, SLOT_HUD_SUIT_STORE, SLOT_HUD_LEFT_STORE, SLOT_HUD_RIGHT_STORE) for(var/s in slots_to_check) @@ -77,7 +79,7 @@ if(istype(I)) O.set_equipment_by_slot(s, I.type) - //Copy access + // Copy access O.stored_access = list() var/obj/item/id_slot = get_item_by_slot(SLOT_HUD_WEAR_ID) if(id_slot) @@ -86,8 +88,8 @@ if(ID && ID.registered_name == real_name) O.update_id_name = TRUE - //Copy hands - if(l_hand || r_hand) //Not in the mood to let outfits transfer amputees + // Copy hands + if(l_hand || r_hand) // Not in the mood to let outfits transfer amputees var/obj/item/left_hand = l_hand var/obj/item/right_hand = r_hand if(istype(left_hand)) @@ -102,7 +104,7 @@ result["RHAND"] = vedits O.vv_values = result - //Copy backpack contents if exist. + // Copy backpack contents if exist. var/obj/item/backpack = get_item_by_slot(SLOT_HUD_BACK) if(istype(backpack) && LAZYLEN(backpack.contents) > 0) var/list/typecounts = list() @@ -112,9 +114,9 @@ else typecounts[I.type] = 1 O.backpack_contents = typecounts - //TODO : Copy varedits from backpack stuff too. + // TODO : Copy varedits from backpack stuff too. - //Copy implants + // Copy implants O.implants = list() for(var/obj/item/implant/I in contents) if(istype(I)) @@ -134,7 +136,7 @@ if(istype(A)) O.accessories |= A - //Copy to outfit cache + // Copy to outfit cache var/outfit_name = stripped_input(usr, "Enter the outfit name") O.name = outfit_name GLOB.custom_outfits += O @@ -142,7 +144,8 @@ /datum/outfit/varedit/post_equip(mob/living/carbon/human/H, visualsOnly) . = ..() - //Apply VV + + // Apply VV for(var/slot in vv_values) var/list/edits = vv_values[slot] var/obj/item/I @@ -155,15 +158,18 @@ I = H.get_item_by_slot(text2num(slot)) for(var/vname in edits) I.vv_edit_var(vname,edits[vname]) - //Apply access + + // Apply access var/obj/item/id_slot = H.get_item_by_slot(SLOT_HUD_WEAR_ID) - if(id_slot) - var/obj/item/card/id/card = id_slot.GetID() - if(istype(card)) - card.access |= stored_access - if(update_id_name) - card.registered_name = H.real_name - card.update_label() + if(!id_slot) + return + + var/obj/item/card/id/card = id_slot.GetID() + if(istype(card)) + card.access |= stored_access + if(update_id_name) + card.registered_name = H.real_name + card.update_label() /datum/outfit/varedit/get_json_data() . = .. () diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm index d3d82d73aadf..57abc708635d 100644 --- a/code/datums/ruins/lavaland.dm +++ b/code/datums/ruins/lavaland.dm @@ -125,8 +125,8 @@ cost = 0 allow_duplicates = FALSE //will only spawn one variant of the ruin -/datum/map_template/ruin/lavaland/blood_drunk_miner/guidance - name = "Blood-Drunk Miner (Guidance)" +/datum/map_template/ruin/lavaland/blood_drunk_miner/guardian + name = "Blood-Drunk Miner (Guardian)" suffix = "lavaland_surface_blooddrunk2.dmm" /datum/map_template/ruin/lavaland/blood_drunk_miner/hunter diff --git a/code/datums/spells/banana_touch.dm b/code/datums/spells/banana_touch.dm index fc4f0dd3f684..ed44996ce455 100644 --- a/code/datums/spells/banana_touch.dm +++ b/code/datums/spells/banana_touch.dm @@ -19,6 +19,17 @@ icon_state = "banana_touch" item_state = "banana_touch" +/obj/effect/proc_holder/spell/touch/banana/apprentice + hand_path = /obj/item/melee/touch_attack/banana/apprentice + +/obj/item/melee/touch_attack/banana/apprentice + +/obj/item/melee/touch_attack/banana/apprentice/afterattack(atom/target, mob/living/carbon/user, proximity) + if(iswizard(target) && target != user) + to_chat(user, "Seriously?! Honk THEM, not me!") + return + ..() + /obj/item/melee/touch_attack/banana/afterattack(atom/target, mob/living/carbon/user, proximity) if(!proximity || target == user || !ishuman(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) return diff --git a/code/datums/spells/wizard_spells.dm b/code/datums/spells/wizard_spells.dm index cee4dbb07286..8951fb00ffc2 100644 --- a/code/datums/spells/wizard_spells.dm +++ b/code/datums/spells/wizard_spells.dm @@ -190,6 +190,29 @@ /obj/effect/proc_holder/spell/area_teleport/teleport/create_new_targeting() return new /datum/spell_targeting/self +/obj/effect/proc_holder/spell/return_to_teacher + name = "Return to Teacher" + desc = "This spell teleports you back to your teacher." + + school = "abjuration" + base_cooldown = 30 SECONDS + clothes_req = TRUE + invocation = "SCYAR TESO" + invocation_type = "shout" + cooldown_min = 10 SECONDS + + action_icon_state = "spell_teleport" + var/datum/mind/teacher + +/obj/effect/proc_holder/spell/return_to_teacher/create_new_targeting() + return new /datum/spell_targeting/self + +/obj/effect/proc_holder/spell/return_to_teacher/cast(list/targets, mob/living/user = usr) + if(!(teacher && teacher.current)) + to_chat(user, "The link to your teacher is broken!") + return + do_teleport(user, teacher.current, 1, sound_in = 'sound/magic/blink.ogg', sound_out = 'sound/magic/blink.ogg', safe_turf_pick = TRUE) + /obj/effect/proc_holder/spell/forcewall name = "Force Wall" desc = "This spell creates a 3 tile wide unbreakable wall that only you can pass through, and does not need wizard garb. Lasts 30 seconds." @@ -332,6 +355,9 @@ active = FALSE +/obj/effect/proc_holder/spell/fireball/apprentice + centcom_cancast = FALSE + /obj/effect/proc_holder/spell/fireball/create_new_targeting() var/datum/spell_targeting/clicked_atom/C = new() C.range = 20 diff --git a/code/datums/uplink_items/uplink_general.dm b/code/datums/uplink_items/uplink_general.dm index 5005f9e4ffdc..e04640fa3ae0 100644 --- a/code/datums/uplink_items/uplink_general.dm +++ b/code/datums/uplink_items/uplink_general.dm @@ -171,9 +171,9 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) category = "Highly Visible and Dangerous Weapons" /datum/uplink_item/dangerous/pistol - name = "FK-69 Pistol Kit" + name = "FK-69 Stechkin Pistol" reference = "SPI" - desc = "A box containing a small, easily concealable handgun and two eight-round magazines chambered in 10mm auto rounds. Compatible with suppressors." + desc = "A small, easily concealable handgun that uses 10mm auto rounds in 8-round magazines and is compatible with suppressors." item = /obj/item/gun/projectile/automatic/pistol cost = 20 diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 4fe169e79ae7..032046134e81 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -467,7 +467,7 @@ if(!istype(M)) // Rather not have non-humans get hit with a THUNK return - if(istype(M.shoes, /obj/item/clothing/shoes/magboots) && (M.shoes.flags & NOSLIP)) // Only humans can wear magboots, so we give them a chance to. + if(HAS_TRAIT(M, TRAIT_MAGPULSE)) // Only humans can wear magboots, so we give them a chance to. return if(M.dna.species.spec_thunk(M)) //Species level thunk overrides diff --git a/code/game/atoms.dm b/code/game/atoms.dm index dccb7ee6f7a3..f7b86265a862 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -544,7 +544,7 @@ addtimer(CALLBACK(src, PROC_REF(hitby_react), AM), 2) /// This proc applies special effects of a carbon mob hitting something, be it a wall, structure, or window. You can set mob_hurt to false to avoid double dipping through subtypes if returning ..() -/atom/proc/hit_by_thrown_carbon(mob/living/carbon/human/C, datum/thrownthing/throwingdatum, damage, mob_hurt = FALSE, self_hurt = FALSE) +/atom/proc/hit_by_thrown_mob(mob/living/C, datum/thrownthing/throwingdatum, damage, mob_hurt = FALSE, self_hurt = FALSE) return /atom/proc/hitby_react(atom/movable/AM) diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 74238dbda2b2..7bfca0d25861 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -40,34 +40,8 @@ new /obj/effect/particle_effect/smoke(H.loc) var/mob/living/carbon/human/M = new/mob/living/carbon/human(H.loc) M.key = C.key - to_chat(M, "You are the [H.real_name]'s apprentice! You are bound by magic contract to follow [H.p_their()] orders and help [H.p_them()] in accomplishing their goals.") - switch(action) - if("destruction") - M.mind.AddSpell(new /obj/effect/proc_holder/spell/projectile/magic_missile(null)) - M.mind.AddSpell(new /obj/effect/proc_holder/spell/fireball(null)) - to_chat(M, "Your service has not gone unrewarded, however. Studying under [H.real_name], you have learned powerful, destructive spells. You are able to cast magic missile and fireball.") - if("bluespace") - M.mind.AddSpell(new /obj/effect/proc_holder/spell/area_teleport/teleport(null)) - M.mind.AddSpell(new /obj/effect/proc_holder/spell/ethereal_jaunt(null)) - to_chat(M, "Your service has not gone unrewarded, however. Studying under [H.real_name], you have learned reality bending mobility spells. You are able to cast teleport and ethereal jaunt.") - if("healing") - M.mind.AddSpell(new /obj/effect/proc_holder/spell/charge(null)) - M.mind.AddSpell(new /obj/effect/proc_holder/spell/forcewall(null)) - M.equip_to_slot_or_del(new /obj/item/gun/magic/staff/healing(M), SLOT_HUD_RIGHT_HAND) - to_chat(M, "Your service has not gone unrewarded, however. Studying under [H.real_name], you have learned livesaving survival spells. You are able to cast charge and forcewall.") - if("robeless") - M.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/knock(null)) - M.mind.AddSpell(new /obj/effect/proc_holder/spell/mind_transfer(null)) - to_chat(M, "Your service has not gone unrewarded, however. Studying under [H.real_name], you have learned stealthy, robeless spells. You are able to cast knock and mindswap.") - - M.equip_to_slot_or_del(new /obj/item/radio/headset(M), SLOT_HUD_LEFT_EAR) - M.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(M), SLOT_HUD_JUMPSUIT) - M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), SLOT_HUD_SHOES) - M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(M), SLOT_HUD_OUTER_SUIT) - M.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(M), SLOT_HUD_HEAD) - M.equip_to_slot_or_del(new /obj/item/storage/backpack(M), SLOT_HUD_BACK) - M.equip_to_slot_or_del(new /obj/item/storage/box(M), SLOT_HUD_IN_BACKPACK) - M.equip_to_slot_or_del(new /obj/item/teleportation_scroll/apprentice(M), SLOT_HUD_RIGHT_STORE) + to_chat(M, "You are [H.real_name]'s apprentice! You are bound by magic contract to follow [H.p_their()] orders and help [H.p_them()] in accomplishing [H.p_their()] goals.") + equip_apprentice(action, M, H) var/wizard_name_first = pick(GLOB.wizard_first) var/wizard_name_second = pick(GLOB.wizard_second) var/randomname = "[wizard_name_first] [wizard_name_second]" @@ -80,9 +54,8 @@ M.name = newname var/datum/objective/protect/new_objective = new /datum/objective/protect - new_objective.owner = M.mind new_objective.target = H.mind - new_objective.explanation_text = "Protect [H.real_name], the wizard." + new_objective.explanation_text = "Protect and obey [H.real_name], your teacher." M.mind.add_mind_objective(new_objective) SSticker.mode.apprentices += M.mind @@ -105,6 +78,68 @@ ui_interact(user) +/obj/item/contract/proc/equip_apprentice(action, mob/living/carbon/human/M, mob/living/carbon/human/H) + M.equip_to_slot_or_del(new /obj/item/radio/headset(M), SLOT_HUD_LEFT_EAR) + if(action == "stealth") + M.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey(M), SLOT_HUD_JUMPSUIT) + else + M.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(M), SLOT_HUD_JUMPSUIT) + M.equip_to_slot_or_del(new /obj/item/storage/backpack(M), SLOT_HUD_BACK) + M.equip_to_slot_or_del(new /obj/item/storage/box(M), SLOT_HUD_IN_BACKPACK) + M.equip_to_slot_or_del(new /obj/item/teleportation_scroll/apprentice(M), SLOT_HUD_RIGHT_STORE) + switch(action) + if("fire") + M.mind.AddSpell(new /obj/effect/proc_holder/spell/fireball/apprentice(null)) + M.mind.AddSpell(new /obj/effect/proc_holder/spell/sacred_flame(null)) + ADD_TRAIT(M, TRAIT_RESISTHEAT, MAGIC_TRAIT) + ADD_TRAIT(M, TRAIT_RESISTHIGHPRESSURE, MAGIC_TRAIT) + M.mind.AddSpell(new /obj/effect/proc_holder/spell/ethereal_jaunt(null)) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), SLOT_HUD_SHOES) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/red(M), SLOT_HUD_OUTER_SUIT) + M.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/red(M), SLOT_HUD_HEAD) + to_chat(M, "Your service has not gone unrewarded. Under the tutelage of [H.real_name], you've acquired proficiency in the fundamentals of Firebending, enabling you to cast spells like Fireball, Sacred Flame, and Ethereal Jaunt.") + to_chat(M, "You are immune to fire, but you are NOT immune to the explosions caused by your fireballs. Neither is your teacher, for that matter. Be careful!") + if("translocation") + M.mind.AddSpell(new /obj/effect/proc_holder/spell/area_teleport/teleport(null)) + M.mind.AddSpell(new /obj/effect/proc_holder/spell/turf_teleport/blink(null)) + M.mind.AddSpell(new /obj/effect/proc_holder/spell/ethereal_jaunt(null)) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), SLOT_HUD_SHOES) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(M), SLOT_HUD_OUTER_SUIT) + M.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(M), SLOT_HUD_HEAD) + to_chat(M, "Your service has not gone unrewarded. While studying under [H.real_name], you mastered reality-bending mobility spells, allowing you to cast Teleport, Blink, and Ethereal Jaunt.") + if("restoration") + M.mind.AddSpell(new /obj/effect/proc_holder/spell/charge(null)) + M.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/knock(null)) + var/obj/effect/proc_holder/spell/return_to_teacher/S = new /obj/effect/proc_holder/spell/return_to_teacher(null) + S.teacher = H.mind + M.mind.AddSpell(S) + M.equip_to_slot_or_del(new /obj/item/gun/magic/staff/healing(M), SLOT_HUD_RIGHT_HAND) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/marisa(M), SLOT_HUD_SHOES) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/marisa(M), SLOT_HUD_OUTER_SUIT) + M.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/marisa(M), SLOT_HUD_HEAD) + to_chat(M, "Your service has not gone unrewarded. Under the guidance of [H.real_name], you've acquired life-saving survival spells. You can now cast Charge and Knock, and possess the ability to teleport back to your mentor.") + to_chat(M, "Your Charge spell can be used to recharge your Staff of Healing or reduce the cooldowns of your teacher, if you are grabbing them with empty hands.") + if("stealth") + M.mind.AddSpell(new /obj/effect/proc_holder/spell/mind_transfer(null)) + M.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/knock(null)) + M.mind.AddSpell(new /obj/effect/proc_holder/spell/fireball/toolbox(null)) + M.mind.AddSpell(new /obj/effect/proc_holder/spell/summonitem(null)) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), SLOT_HUD_SHOES) + M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas(M), SLOT_HUD_WEAR_MASK) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/yellow(M), SLOT_HUD_GLOVES) + M.equip_to_slot_or_del(new /obj/item/storage/belt/utility/full(M), SLOT_HUD_BELT) + to_chat(M, "Your service has not gone unrewarded. Under the mentorship of [H.real_name], you've mastered stealthy, robeless spells. You can now cast Mindswap, Knock, Homing Toolbox, Forcewall, and Instant Summons without the need for wizard robes.") + if("honk") + M.mind.AddSpell(new /obj/effect/proc_holder/spell/touch/banana/apprentice(null)) + M.mind.AddSpell(new /obj/effect/proc_holder/spell/ethereal_jaunt(null)) + M.mind.AddSpell(new /obj/effect/proc_holder/spell/summonitem(null)) + M.equip_to_slot_or_del(new /obj/item/gun/magic/staff/slipping(M), SLOT_HUD_RIGHT_HAND) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/clown_shoes/magical/nodrop(M), SLOT_HUD_SHOES) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/clown(M), SLOT_HUD_OUTER_SUIT) + M.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/clown(M), SLOT_HUD_HEAD) + M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clownwiz(M), SLOT_HUD_WEAR_MASK) + to_chat(M, "Your dedication pays off! Under [H.real_name]'s guidance, you've mastered magical honkings, seamlessly casting spells like Banana Touch, Ethereal Jaunt, and Instant Summons, while skillfully wielding a Staff of Slipping. Honk!") + ///////////////////////////Veil Render////////////////////// /obj/item/veilrender diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index c63ce948f07f..a0849e4c800c 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -615,6 +615,8 @@ desc = "A magical contract binding an apprentice wizard to your service, using it will summon them to your side." item_path = /obj/item/contract category = "Summons" + limit = 1 + is_ragin_restricted = TRUE //We have enough wizards already! Sheesh! /datum/spellbook_entry/item/tarotdeck name = "Guardian Deck" diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index f10b2b741e8c..e16579faae95 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -177,10 +177,9 @@ if(I.use_tool(src, user, 20, volume = I.tool_volume)) deconstruct(TRUE, user) -/obj/machinery/computer/hit_by_thrown_carbon(mob/living/carbon/human/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt) +/obj/machinery/computer/hit_by_thrown_mob(mob/living/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt) if(!self_hurt && prob(50 * (damage / 15))) obj_break(MELEE) take_damage(damage, BRUTE) self_hurt = TRUE return ..() - diff --git a/code/game/machinery/vendors/vending.dm b/code/game/machinery/vendors/vending.dm index 2e9e0f3d21bd..813208452d3c 100644 --- a/code/game/machinery/vendors/vending.dm +++ b/code/game/machinery/vendors/vending.dm @@ -987,14 +987,13 @@ attacker.visible_message("[attacker] lightly presses [target] against [src].", "You lightly press [target] against [src], you don't want to hurt [target.p_them()]!") return TRUE -/obj/machinery/economy/vending/hit_by_thrown_carbon(mob/living/carbon/human/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt) +/obj/machinery/economy/vending/hit_by_thrown_mob(mob/living/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt) if(HAS_TRAIT(C, TRAIT_FLATTENED)) return ..() tilt(C, from_combat = TRUE) mob_hurt = TRUE return ..() - /* * Vending machine types */ diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index d1e235a9c9dc..b4b65c935bc3 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -129,7 +129,7 @@ for(var/mob/living/M in range(0, src)) gravShock(M) for(var/mob/living/M in orange(4, src)) - if(!M.mob_negates_gravity()) + if(!M.mob_negates_gravity() && !issilicon(M)) step_towards(M,src) for(var/obj/O in range(0, src)) if(!O.anchored && O.loc != src && O.move_resist < MOVE_FORCE_OVERPOWERING) // so it cannot throw the anomaly core or super big things diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 8e70132e6780..0c5600e7f080 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -13,13 +13,6 @@ var/gravity_check = TRUE hud_possible = list(JANI_HUD) -/obj/effect/decal/cleanable/Initialize(mapload) - . = ..() - var/datum/atom_hud/data/janitor/jani_hud = GLOB.huds[DATA_HUD_JANITOR] - prepare_huds() - jani_hud.add_to_hud(src) - jani_hud_set_sign() - /obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal if(mergeable_decal) return TRUE @@ -103,10 +96,16 @@ QUEUE_SMOOTH_NEIGHBORS(src) if(iswallturf(loc) && plane == FLOOR_PLANE) plane = GAME_PLANE // so they can be seen above walls + var/datum/atom_hud/data/janitor/jani_hud = GLOB.huds[DATA_HUD_JANITOR] + prepare_huds() + jani_hud.add_to_hud(src) + jani_hud_set_sign() /obj/effect/decal/cleanable/Destroy() if(smoothing_flags) QUEUE_SMOOTH_NEIGHBORS(src) + var/datum/atom_hud/data/janitor/jani_hud = GLOB.huds[DATA_HUD_JANITOR] + jani_hud.remove_from_hud(src) return ..() /obj/effect/decal/cleanable/proc/try_merging_decal(turf/T) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 312577306607..d3eddd8b963d 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -297,7 +297,7 @@ // In the event that the object doesn't have an overriden version of this proc to do it, log a runtime so one can be added. CRASH("Proc force_eject_occupant() is not overridden on a machine containing a mob.") -/obj/hit_by_thrown_carbon(mob/living/carbon/human/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt) +/obj/hit_by_thrown_mob(mob/living/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt) damage *= 0.75 //Define this probably somewhere, we want objects to hurt less than walls, unless special impact effects. playsound(src, 'sound/weapons/punch1.ogg', 35, 1) if(mob_hurt) //Density check probably not needed, one should only bump into something if it is dense, and blob tiles are not dense, because of course they are not. @@ -306,4 +306,7 @@ C.take_organ_damage(damage) if(!self_hurt) take_damage(damage, BRUTE) - C.KnockDown(3 SECONDS) + if(issilicon(C)) + C.Weaken(3 SECONDS) + else + C.KnockDown(3 SECONDS) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index e0b232ac2342..0129aecfa718 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -456,14 +456,14 @@ if(exposed_temperature > (T0C + heat_resistance)) take_damage(round(exposed_volume / 100), BURN, 0, 0) -/obj/structure/window/hit_by_thrown_carbon(mob/living/carbon/human/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt) +/obj/structure/window/hit_by_thrown_mob(mob/living/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt) var/shattered = FALSE if(damage * 2 >= obj_integrity && shardtype && !mob_hurt) shattered = TRUE - var/obj/item/S = new shardtype(loc) - S.embedded_ignore_throwspeed_threshold = TRUE - S.throw_impact(C) - S.embedded_ignore_throwspeed_threshold = FALSE + var/obj/item/shard = new shardtype(loc) + shard.embedded_ignore_throwspeed_threshold = TRUE + shard.throw_impact(C) + shard.embedded_ignore_throwspeed_threshold = FALSE damage *= (4/3) //Inverts damage loss from being a structure, since glass breaking on you hurts var/turf/T = get_turf(src) for(var/obj/structure/grille/G in T.contents) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index a60da9933cd3..a931c24989aa 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -569,10 +569,14 @@ return I -/turf/hit_by_thrown_carbon(mob/living/carbon/human/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt) +/turf/hit_by_thrown_mob(mob/living/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt) if(mob_hurt || !density) return playsound(src, 'sound/weapons/punch1.ogg', 35, 1) C.visible_message("[C] slams into [src]!", "You slam into [src]!") - C.take_organ_damage(damage) - C.KnockDown(3 SECONDS) + if(issilicon(C)) + C.adjustBruteLoss(damage) + C.Weaken(3 SECONDS) + else + C.take_organ_damage(damage) + C.KnockDown(3 SECONDS) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 542d9f6cdc3c..add4b2a57f3d 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -663,7 +663,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) ) var/list/outfits = list() - var/list/paths = subtypesof(/datum/outfit) - typesof(/datum/outfit/job) + var/list/paths = subtypesof(/datum/outfit) - typesof(/datum/outfit/job) - list(/datum/outfit/varedit, /datum/outfit/admin) for(var/path in paths) var/datum/outfit/O = path //not much to initalize here but whatever if(initial(O.can_be_admin_equipped)) diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm index 339fde58bbc9..9dbe8cd39146 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -42,19 +42,30 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/Destroy(force, ...) qdel(objective_holder) - remove_owner_from_gamemode() GLOB.antagonists -= src + if(!QDELETED(owner)) + detach_from_owner() + + return ..() + +/** + * Removes owner's dependencies on this antag datum. + * For example: removal of antag datum from owner's `antag_datums`, antag datum related teams etc. + * If your `/datum/antagonist` subtype adds more dependencies on `owner` - they should be cleared there. + */ +/datum/antagonist/proc/detach_from_owner() + SHOULD_CALL_PARENT(TRUE) + + remove_owner_from_gamemode() if(!silent) farewell() remove_innate_effects() antag_memory = null var/datum/team/team = get_team() team?.remove_member(owner) - if(owner) - LAZYREMOVE(owner.antag_datums, src) + LAZYREMOVE(owner.antag_datums, src) restore_last_hud_and_role() owner = null - return ..() /** * Adds the owner to their respective gamemode's list. For example `SSticker.mode.traitors |= owner`. diff --git a/code/modules/atmospherics/machinery/atmospherics.dm b/code/modules/atmospherics/machinery/atmospherics.dm index 005cf14e393f..2ab54354bd13 100644 --- a/code/modules/atmospherics/machinery/atmospherics.dm +++ b/code/modules/atmospherics/machinery/atmospherics.dm @@ -210,32 +210,25 @@ Pipelines + Other Objects -> Pipe network playsound(loc, W.usesound, 50, 1) to_chat(user, "You begin to unfasten \the [src]...") - for(var/obj/item/clothing/shoes/magboots/usermagboots in user.get_equipped_items()) - if(usermagboots.magpulse) - safefromgusts = TRUE - for(var/obj/item/clothing/shoes/mod/usermodboots in user.get_equipped_items()) - if(usermodboots.magbooted) - safefromgusts = TRUE + if(HAS_TRAIT(user, TRAIT_MAGPULSE)) + safefromgusts = TRUE - if(internal_pressure > 2*ONE_ATMOSPHERE) + if(internal_pressure > 2 * ONE_ATMOSPHERE) unsafe_wrenching = TRUE //Oh dear oh dear if(internal_pressure > 1750 && !safefromgusts) // 1750 is the pressure limit to do 60 damage when thrown - to_chat(user, "As you struggle to unwrench \the [src] a huge gust of gas blows in your face! This seems like a terrible idea!") + to_chat(user, "As you struggle to unwrench [src] a huge gust of gas blows in your face! This seems like a terrible idea!") else - to_chat(user, "As you begin unwrenching \the [src] a gust of air blows in your face... maybe you should reconsider?") + to_chat(user, "As you begin unwrenching [src] a gust of air blows in your face... maybe you should reconsider?") if(do_after(user, 40 * W.toolspeed, target = src) && !QDELETED(src)) safefromgusts = FALSE - for(var/obj/item/clothing/shoes/magboots/usermagboots in user.get_equipped_items()) - if(usermagboots.magpulse) // Check again, incase they change magpulse mid-wrench - safefromgusts = TRUE - for(var/obj/item/clothing/shoes/mod/usermodboots in user.get_equipped_items()) - if(usermodboots.magbooted) - safefromgusts = TRUE + + if(HAS_TRAIT(user, TRAIT_MAGPULSE)) + safefromgusts = TRUE user.visible_message( \ - "[user] unfastens \the [src].", \ - "You have unfastened \the [src].", \ + "[user] unfastens [src].", \ + "You have unfastened [src].", \ "You hear ratcheting.") investigate_log("was REMOVED by [key_name(usr)]", "atmos") diff --git a/code/modules/client/preference/link_processing.dm b/code/modules/client/preference/link_processing.dm index 9400cb7438af..3f06e358e58b 100644 --- a/code/modules/client/preference/link_processing.dm +++ b/code/modules/client/preference/link_processing.dm @@ -961,6 +961,9 @@ if("tgui") toggles2 ^= PREFTOGGLE_2_FANCYUI + if("input_lists") + toggles2 ^= PREFTOGGLE_2_DISABLE_TGUI_LISTS + if("ghost_att_anim") toggles2 ^= PREFTOGGLE_2_ITEMATTACK diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 29f964014969..beffea1f9b2f 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -416,6 +416,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts if(user.client.donator_level > 0) dat += "Donator Publicity: [(toggles & PREFTOGGLE_DONATOR_PUBLIC) ? "Public" : "Hidden"]
" dat += "Fancy TGUI: [(toggles2 & PREFTOGGLE_2_FANCYUI) ? "Yes" : "No"]
" + dat += "Input Lists: [(toggles2 & PREFTOGGLE_2_DISABLE_TGUI_LISTS) ? "Default" : "TGUI"]
" dat += "FPS: [clientfps]
" dat += "Ghost Ears: [(toggles & PREFTOGGLE_CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]
" dat += "Ghost Radio: [(toggles & PREFTOGGLE_CHAT_GHOSTRADIO) ? "All Chatter" : "Nearest Speakers"]
" diff --git a/code/modules/client/preference/preferences_toggles.dm b/code/modules/client/preference/preferences_toggles.dm index 688b5e7becb3..c252a2d8d1f9 100644 --- a/code/modules/client/preference/preferences_toggles.dm +++ b/code/modules/client/preference/preferences_toggles.dm @@ -226,6 +226,14 @@ to_chat(src, "You will no longer hear musical instruments.") SSblackbox.record_feedback("tally", "toggle_verbs", 1, "Toggle Instruments") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/client/verb/toggle_input() + set name = "Toggle TGUI Input Lists" + set category = "Preferences" + set desc = "Switches input lists between the TGUI and the standard one" + prefs.toggles2 ^= PREFTOGGLE_2_DISABLE_TGUI_LISTS + prefs.save_preferences(src) + to_chat(src, "You will [(prefs.toggles2 & PREFTOGGLE_2_DISABLE_TGUI_LISTS) ? "no longer" : "now"] use TGUI Input Lists.") + /client/verb/Toggle_disco() //to toggle off the disco machine locally, in case it gets too annoying set name = "Hear/Silence Dance Machine" set category = "Preferences" diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 22b63fff7cb9..de356a7bd45e 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -357,7 +357,7 @@ if(H.w_uniform == src) H.update_suit_sensors() -/obj/item/clothing/under/AltShiftClick(mob/user) +/obj/item/clothing/under/AltClick(mob/user) set_sensors(user) //Head @@ -815,14 +815,14 @@ if(SUIT_SENSOR_TRACKING) . += "Its vital tracker and tracking beacon appear to be enabled." if(has_sensor == 1) - . += "Alt-shift-click to toggle the sensors mode." + . += "Alt-click to toggle the sensors mode." else . += "This suit does not have any sensors." if(length(accessories)) for(var/obj/item/clothing/accessory/A in accessories) . += "\A [A] is attached to it." - . += "Alt-click to remove an accessory." + . += "Alt-Shift-Click to remove an accessory." . += "Ctrl-Shift-Click to roll down this jumpsuit." @@ -856,7 +856,7 @@ body_parts_covered &= ~LOWER_TORSO body_parts_covered &= ~ARMS -/obj/item/clothing/under/AltClick(mob/user) +/obj/item/clothing/under/AltShiftClick(mob/user) if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user)) return if(!length(accessories)) diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index c2d32904979c..b91d89b178e6 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -13,31 +13,31 @@ put_on_delay = 70 resistance_flags = FIRE_PROOF -/obj/item/clothing/shoes/magboots/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - /obj/item/clothing/shoes/magboots/water_act(volume, temperature, source, method) . = ..() if(magpulse && slowdown_active > SHOES_SLOWDOWN) slowdown = slowdown_active -/obj/item/clothing/shoes/magboots/atmos - desc = "Magnetic boots, made to withstand gusts of space wind over 500kmph." - name = "atmospheric magboots" - icon_state = "atmosmagboots0" - magboot_state = "atmosmagboots" +/obj/item/clothing/shoes/magboots/equipped(mob/user, slot, initial) + . = ..() + if(slot != SLOT_HUD_SHOES || !ishuman(user)) + return + check_mag_pulse() + +/obj/item/clothing/shoes/magboots/dropped(mob/user, silent) + . = ..() + if(!ishuman(user)) + return + check_mag_pulse() /obj/item/clothing/shoes/magboots/attack_self(mob/user, forced = FALSE) toggle_magpulse(user, forced) /obj/item/clothing/shoes/magboots/proc/toggle_magpulse(mob/user, forced) if(magpulse) - START_PROCESSING(SSobj, src) //Gravboots flags &= ~NOSLIP slowdown = slowdown_passive else - STOP_PROCESSING(SSobj, src) flags |= NOSLIP slowdown = slowdown_active magpulse = !magpulse @@ -49,6 +49,16 @@ for(var/X in actions) var/datum/action/A = X A.UpdateButtonIcon() + check_mag_pulse(user) + +/obj/item/clothing/shoes/magboots/proc/check_mag_pulse(mob/user) + if(!user) + return + if(magpulse) + ADD_TRAIT(user, TRAIT_MAGPULSE, "magboots") + return + if(HAS_TRAIT(user, TRAIT_MAGPULSE)) // User has trait and the magboots were turned off, remove trait + REMOVE_TRAIT(user, TRAIT_MAGPULSE, "magboots") /obj/item/clothing/shoes/magboots/negates_gravity() return flags & NOSLIP @@ -57,6 +67,11 @@ . = ..() . += "Its [magpulse_name] appears to be [magpulse ? "enabled" : "disabled"]." +/obj/item/clothing/shoes/magboots/atmos + name = "atmospheric magboots" + desc = "Magnetic boots, made to withstand gusts of space wind over 500kmph." + icon_state = "atmosmagboots0" + magboot_state = "atmosmagboots" /obj/item/clothing/shoes/magboots/advance name = "advanced magboots" diff --git a/code/modules/clothing/shoes/misc_shoes.dm b/code/modules/clothing/shoes/misc_shoes.dm index c53a3982043d..a6925603b28d 100644 --- a/code/modules/clothing/shoes/misc_shoes.dm +++ b/code/modules/clothing/shoes/misc_shoes.dm @@ -119,6 +119,10 @@ desc = "Standard-issue shoes of the wizarding class clown. Damn they're huge! And powerful! Somehow." magical = TRUE +/obj/item/clothing/shoes/clown_shoes/magical/nodrop + desc = "Standard-issue shoes of the wizarding class clown. Damn they're huge! And stuck to your feet!" + flags = NODROP + /obj/item/clothing/shoes/clown_shoes/slippers actions_types = list(/datum/action/item_action/slipping) enabled_waddle = FALSE diff --git a/code/modules/events/blob/theblob.dm b/code/modules/events/blob/theblob.dm index 5faa9464cae1..9b616928aef6 100644 --- a/code/modules/events/blob/theblob.dm +++ b/code/modules/events/blob/theblob.dm @@ -267,7 +267,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) return B.blob_reagent_datum.description return "something unknown" -/obj/structure/blob/hit_by_thrown_carbon(mob/living/carbon/human/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt) +/obj/structure/blob/hit_by_thrown_mob(mob/living/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt) damage *= 0.25 // Lets not have sorium be too much of a blender / rapidly kill itself return ..() diff --git a/code/modules/events/event_procs.dm b/code/modules/events/event_procs.dm index 994cddf841b6..95690d946422 100644 --- a/code/modules/events/event_procs.dm +++ b/code/modules/events/event_procs.dm @@ -27,6 +27,7 @@ /area/shuttle, /area/station/maintenance, /area/station/science/toxins/test, + /area/space, /area/station/public/sleep)) //These are needed because /area/station/engineering has to be removed from the list, but we still want these areas to get fucked up. diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 09f263d90d9a..3e7b91df663b 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -617,9 +617,9 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven var/damage = 10 + 1.5 * speed // speed while thrower is standing still is 2, while walking with an aggressive grab is 2.4, highest speed is 14 - hit_atom.hit_by_thrown_carbon(src, throwingdatum, damage, FALSE, FALSE) + hit_atom.hit_by_thrown_mob(src, throwingdatum, damage, FALSE, FALSE) -/mob/living/carbon/hit_by_thrown_carbon(mob/living/carbon/human/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt) +/mob/living/carbon/hit_by_thrown_mob(mob/living/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt) for(var/obj/item/dualsaber/D in contents) if(HAS_TRAIT(D, TRAIT_WIELDED) && D.force) visible_message("[src] impales [C] with [D], before dropping them on the ground!") diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 30cd59debc07..705ae6ee6560 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -759,11 +759,11 @@ emp_act return for(var/obj/O in list(head, wear_suit, back, l_hand, r_hand)) - O.water_act(src, volume, temperature, source, method) + O.water_act(volume, temperature, source, method) if((head?.flags & THICKMATERIAL) && (wear_suit?.flags & THICKMATERIAL)) // fully pierce proof clothing is also water proof! return for(var/obj/O in list(w_uniform, shoes, belt, gloves, glasses, l_ear, r_ear, wear_id, wear_pda, r_store, l_store, s_store)) - O.water_act(src, volume, temperature, source, method) + O.water_act(volume, temperature, source, method) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index f07f801b4b41..b84208fba692 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -268,11 +268,12 @@ /mob/living/run_pointed(atom/A) if(!..()) return FALSE - var/obj/item/hand_item = get_active_hand() var/pointed_object = "\the [A]" if(A.loc in src) pointed_object += " inside [A.loc]" - if(HAS_TRAIT(hand_item, TRAIT_CAN_POINT_WITH) && A != hand_item) + + var/obj/item/hand_item = get_active_hand() + if(!QDELETED(hand_item) && istype(hand_item) && HAS_TRAIT(hand_item, TRAIT_CAN_POINT_WITH) && A != hand_item) if(a_intent == INTENT_HELP || !ismob(A)) visible_message("[src] points to [pointed_object] with [hand_item]") return TRUE @@ -1102,7 +1103,7 @@ stop_pulling() return ..() -/mob/living/hit_by_thrown_carbon(mob/living/carbon/human/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt) +/mob/living/hit_by_thrown_mob(mob/living/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt) if(C == src || flying || !density) return playsound(src, 'sound/weapons/punch1.ogg', 50, 1) @@ -1110,8 +1111,12 @@ return if(!self_hurt) take_organ_damage(damage) - C.take_organ_damage(damage) - C.KnockDown(3 SECONDS) + if(issilicon(C)) + C.adjustBruteLoss(damage) + C.Weaken(3 SECONDS) + else + C.take_organ_damage(damage) + C.KnockDown(3 SECONDS) C.visible_message("[C] crashes into [src], knocking them both over!", "You violently crash into [src]!") /** diff --git a/code/modules/mob/living/silicon/robot/drone/maint_drone.dm b/code/modules/mob/living/silicon/robot/drone/maint_drone.dm index aed0e9b16b45..d02c563d5d56 100644 --- a/code/modules/mob/living/silicon/robot/drone/maint_drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/maint_drone.dm @@ -15,7 +15,6 @@ has_camera = FALSE req_one_access = list(ACCESS_ENGINE, ACCESS_ROBOTICS) ventcrawler = VENTCRAWLER_ALWAYS - magpulse = TRUE mob_size = MOB_SIZE_SMALL pull_force = MOVE_FORCE_VERY_WEAK // Can only drag small items modules_break = FALSE @@ -79,7 +78,9 @@ module = new /obj/item/robot_module/drone(src) // Give us our action button var/datum/action/innate/hide/drone_hide/hide = new() + var/datum/action/innate/robot_magpulse/pulse = new() hide.Grant(src) + pulse.Grant(src) //Allows Drones to hear the Engineering channel. module.channels = list("Engineering" = 1) diff --git a/code/modules/mob/living/silicon/robot/robot_mob.dm b/code/modules/mob/living/silicon/robot/robot_mob.dm index a874776febc8..341079ffdc9e 100644 --- a/code/modules/mob/living/silicon/robot/robot_mob.dm +++ b/code/modules/mob/living/silicon/robot/robot_mob.dm @@ -105,7 +105,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( hud_possible = list(SPECIALROLE_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD) var/default_cell_type = /obj/item/stock_parts/cell/high - var/magpulse = FALSE var/ionpulse = FALSE // Jetpack-like effect. var/ionpulse_on = FALSE // Jetpack-like effect. /// Does it clean the tile under it? @@ -463,7 +462,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( module.channels = list("Engineering" = 1) if(camera && ("Robots" in camera.network)) camera.network += "Engineering" - magpulse = TRUE if("Janitor") module = new /obj/item/robot_module/janitor(src) module.channels = list("Service" = 1) @@ -543,7 +541,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( speed = 0 // Remove upgrades. ionpulse = FALSE - magpulse = FALSE weapons_unlock = FALSE add_language("Robot Talk", TRUE) if("lava" in weather_immunities) // Remove the lava-immunity effect given by a printable upgrade @@ -1366,7 +1363,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( has_camera = FALSE req_one_access = list(ACCESS_CENT_SPECOPS) ionpulse = TRUE - magpulse = TRUE pdahide = TRUE eye_protection = 2 // Immunity to flashes and the visual part of flashbangs ear_protection = TRUE // Immunity to the audio part of flashbangs @@ -1446,7 +1442,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( force_modules = list("Combat", "Engineering", "Medical") damage_protection = 5 // Reduce all incoming damage by this number eprefix = "Gamma" - magpulse = TRUE /mob/living/silicon/robot/destroyer @@ -1460,7 +1455,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( has_camera = FALSE req_one_access = list(ACCESS_CENT_SPECOPS) ionpulse = TRUE - magpulse = TRUE pdahide = TRUE eye_protection = 2 // Immunity to flashes and the visual part of flashbangs ear_protection = TRUE // Immunity to the audio part of flashbangs diff --git a/code/modules/mob/living/silicon/robot/robot_module_actions.dm b/code/modules/mob/living/silicon/robot/robot_module_actions.dm index 4facbe646d87..f77436a87c0d 100644 --- a/code/modules/mob/living/silicon/robot/robot_module_actions.dm +++ b/code/modules/mob/living/silicon/robot/robot_module_actions.dm @@ -35,3 +35,25 @@ sight_mode = BORGMESON icon_icon = 'icons/obj/clothing/glasses.dmi' button_icon_state = "meson" + +/datum/action/innate/robot_magpulse + name = "Magnetic pulse" + icon_icon = 'icons/obj/clothing/shoes.dmi' + button_icon_state = "magboots0" + var/slowdown_active = 2 // Same as magboots + +/datum/action/innate/robot_magpulse/Activate() + ADD_TRAIT(owner, TRAIT_MAGPULSE, "innate boots") + to_chat(owner, "You turn your magboots on.") + var/mob/living/silicon/robot/robot = owner + robot.speed += slowdown_active + button_icon_state = "magboots1" + active = TRUE + +/datum/action/innate/robot_magpulse/Deactivate() + REMOVE_TRAIT(owner, TRAIT_MAGPULSE, "innate boots") + to_chat(owner, "You turn your magboots off.") + var/mob/living/silicon/robot/robot = owner + robot.speed -= slowdown_active + button_icon_state = initial(button_icon_state) + active = FALSE diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 29b1f6ed24f3..6d779daa3b98 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -385,7 +385,7 @@ name = "engineering robot module" module_type = "Engineer" subsystems = list(/mob/living/silicon/proc/subsystem_power_monitor) - module_actions = list(/datum/action/innate/robot_sight/meson) + module_actions = list(/datum/action/innate/robot_sight/meson, /datum/action/innate/robot_magpulse) basic_modules = list( /obj/item/flash/cyborg, /obj/item/rpd, @@ -615,7 +615,7 @@ /obj/item/robot_module/deathsquad name = "NT advanced combat module" module_type = "Malf" - module_actions = list(/datum/action/innate/robot_sight/thermal) + module_actions = list(/datum/action/innate/robot_sight/thermal, /datum/action/innate/robot_magpulse) basic_modules = list( /obj/item/flash/cyborg, /obj/item/melee/energy/sword/cyborg, @@ -706,7 +706,7 @@ /obj/item/robot_module/destroyer name = "destroyer robot module" module_type = "Malf" - module_actions = list(/datum/action/innate/robot_sight/thermal) + module_actions = list(/datum/action/innate/robot_sight/thermal, /datum/action/innate/robot_magpulse) basic_modules = list( /obj/item/flash/cyborg, /obj/item/gun/energy/immolator/multi/cyborg, // See comments on /robot_module/combat below @@ -723,6 +723,7 @@ /obj/item/robot_module/combat name = "combat robot module" module_type = "Malf" + module_actions = list(/datum/action/innate/robot_magpulse) basic_modules = list( /obj/item/flash/cyborg, /obj/item/gun/energy/immolator/multi/cyborg, // primary weapon, strong at close range (ie: against blob/terror/xeno), but consumes a lot of energy per shot. diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm index b5fd0a1b1c8a..99caad61a714 100644 --- a/code/modules/mob/living/silicon/robot/robot_movement.dm +++ b/code/modules/mob/living/silicon/robot/robot_movement.dm @@ -14,11 +14,11 @@ . += GLOB.configuration.movement.robot_delay /mob/living/silicon/robot/mob_negates_gravity() - return magpulse + return HAS_TRAIT(src, TRAIT_MAGPULSE) /mob/living/silicon/robot/mob_has_gravity() return ..() || mob_negates_gravity() /mob/living/silicon/robot/experience_pressure_difference(pressure_difference, direction) - if(!magpulse) + if(!HAS_TRAIT(src, TRAIT_MAGPULSE)) return ..() diff --git a/code/modules/mob/living/silicon/silicon_mob.dm b/code/modules/mob/living/silicon/silicon_mob.dm index 4b5249662bec..3197196e4c58 100644 --- a/code/modules/mob/living/silicon/silicon_mob.dm +++ b/code/modules/mob/living/silicon/silicon_mob.dm @@ -432,3 +432,8 @@ /mob/living/silicon/on_standing_up() return // Silicons are always standing by default. + +/mob/living/silicon/throw_impact(atom/hit_atom, throwingdatum, speed = 1) + . = ..() + var/damage = 10 + 1.5 * speed + hit_atom.hit_by_thrown_mob(src, throwingdatum, damage, FALSE, FALSE) diff --git a/code/modules/mod/mod_clothes.dm b/code/modules/mod/mod_clothes.dm index 5b896c2eb47f..bb2640cdd65e 100644 --- a/code/modules/mod/mod_clothes.dm +++ b/code/modules/mod/mod_clothes.dm @@ -83,7 +83,3 @@ "Unathi" = 'icons/mob/clothing/modsuit/species/modsuits_younahthee.dmi', "Vox" = 'icons/mob/clothing/modsuit/species/vox_modsuits.dmi' ) - var/magbooted - -/obj/item/clothing/shoes/mod/negates_gravity() - return magbooted diff --git a/code/modules/mod/modules/modules_engineering.dm b/code/modules/mod/modules/modules_engineering.dm index 998b0ebc67a9..0b2f5a456cbb 100644 --- a/code/modules/mod/modules/modules_engineering.dm +++ b/code/modules/mod/modules/modules_engineering.dm @@ -59,7 +59,7 @@ return mod.boots.flags |= NOSLIP mod.slowdown += slowdown_active - mod.boots.magbooted = TRUE + ADD_TRAIT(mod.wearer, TRAIT_MAGPULSE, "magbooted") /obj/item/mod/module/magboot/on_deactivation(display_message = TRUE, deleting = FALSE) . = ..() @@ -67,7 +67,7 @@ return mod.boots.flags ^= NOSLIP mod.slowdown -= slowdown_active - mod.boots.magbooted = FALSE + REMOVE_TRAIT(mod.wearer, TRAIT_MAGPULSE, "magbooted") /obj/item/mod/module/magboot/advanced name = "MOD advanced magnetic stability module" diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index 19c9da11ba97..48736aab74b4 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -481,6 +481,7 @@ desc = "A modification to a users arm, allowing them to use a vortex core energy feedback, to parry, reflect, and even empower projectile attacks. Rumors that it runs on the user's blood are unconfirmed." icon_state = "v1_arm" item_state = "v1_arm" + icon = 'icons/obj/items.dmi' sprite_sheets_inhand = list("Drask" = 'icons/mob/clothing/species/drask/held.dmi', "Vox" = 'icons/mob/clothing/species/vox/held.dmi') force = 20 //bonk, not sharp attack_verb = list("slamed", "punched", "parried", "judged", "styled on", "disrespected", "interrupted", "gored") diff --git a/code/modules/tgui/modules/tgui_input_list.dm b/code/modules/tgui/modules/tgui_input_list.dm index f9ede158930c..b9b34fffc9b4 100644 --- a/code/modules/tgui/modules/tgui_input_list.dm +++ b/code/modules/tgui/modules/tgui_input_list.dm @@ -19,6 +19,11 @@ return var/client/client = user user = client.mob + + /// Client does NOT have tgui_input on: Returns regular input + if(user.client?.prefs?.toggles2 & PREFTOGGLE_2_DISABLE_TGUI_LISTS) + return input(user, message, title) as null|anything in buttons + var/datum/tgui_list_input/input = new(user, message, title, buttons, timeout) input.ui_interact(user) input.wait() diff --git a/modular_ss220/maps220/code/objects.dm b/modular_ss220/maps220/code/objects.dm index a42859388653..7ff1fb2de788 100644 --- a/modular_ss220/maps220/code/objects.dm +++ b/modular_ss220/maps220/code/objects.dm @@ -595,7 +595,7 @@ shielded = FALSE update_appearance() -/mob/living/simple_animal/hostile/blackmesa/xen/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharp = NONE, attack_direction = null, attacking_item) +/mob/living/simple_animal/hostile/blackmesa/xen/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharp = NONE, used_weapon, attack_direction = null, attacking_item) if(shielded) visible_message("ineffective!") return FALSE diff --git a/tgui/docs/component-reference.md b/tgui/docs/component-reference.md index 4070b5d46c36..c892cb628be9 100644 --- a/tgui/docs/component-reference.md +++ b/tgui/docs/component-reference.md @@ -44,15 +44,12 @@ Make sure to add new items to this list if you document new components. - [`Table`](#table) - [`Table.Row`](#tablerow) - [`Table.Cell`](#tablecell) - - [`Table.Sortable`](#tablesortable) - [`Tabs`](#tabs) - [`Tabs.Tab`](#tabstab) - [`Tooltip`](#tooltip) - [`tgui/layouts`](#tguilayouts) - [`Window`](#window) - [`Window.Content`](#windowcontent) -- [`tgui/interfaces/common`](#tguiinterfacescommon) - - [`RecordsTable`](#recordstable) ## General Concepts @@ -847,103 +844,6 @@ A straight forward mapping to `` element. - `collapsing: boolean` - Collapses table cell to the smallest possible size, and stops any text inside from wrapping. -### `Table.Sortable` - -A managed sortable table. - -**Props:** - -- See inherited props: [Table](#table) -- `columns: Column[]` - A list of data fields to be - used. The order in which columns are specified is the order in which they - appear in the UI. -- `columnDefaults: UnnamedColumn` - Default values for all columns. - `columnDefaults.datum.children` can be used to specify the default children, - but will get overriden by children defined at each column. - `columnDefaults.datum.props` and `columnDefaults.header.props` can be used to - specify additional props for the datum and header respectively. -- `data: object[]` - The data to put into the table. -- `datumID: object => object` - A function which takes in a datum and returns - an id. -- `filter: object[] => object[]` - A function applied to the data before - sorting the table. The `createSearch` function can be applied here. -- `headerRowProps: object` - Props to apply to the header row. -- `datumRowProps: object | object => object` - Props to apply to the data - rows. If a function is specified instead, the data associated with that row - is passed into it. -- `...rest` - The rest of the props are applied on the table. -- `children: Component[]` - Not supported. Do not use. - -The column types is defined as such: - -```ts -interface UnnamedColumn { - // ? signifies optional - datum?: { - // Pass the children directly or pass a function which takes the value of - // the cell and returns the props. Setting this property overrides the - // default children. - children?: React.ReactNode | ((value: object) => React.ReactNode); - // Pass the additional props directly or pass a function which takes the - // value of the cell and returns the additional props. - props?: CellProps | ((value: object) => CellProps); - }; - header?: { - // Additional props for the header cell. - props?: HeaderProps; - }; -} - -// Inherits properties from UnnamedColumn -type Column = UnnamedColumn & { - id: string; - name: string; -}; -``` - -The following is an example of how to use `Table.Sortable`. - -```jsx -const data = [ - { 'account_number': 6224001, 'name': 'Command Account', 'suspended': 'Active', 'money': 7000, }, - { 'account_number': 3099002, 'name': 'Security Account', 'suspended': 'Active', 'money': 14000, }, - { 'account_number': 8652003, 'name': 'Science Account', 'suspended': 'Active', 'money': 7000, }, - { 'account_number': 8422004, 'name': 'Service Account', 'suspended': 'Active', 'money': 7000, }, - { 'account_number': 9853005, 'name': 'Supply Account', 'suspended': 'Active', 'money': 7000, }, - { 'account_number': 1866006, 'name': 'Engineering Account', 'suspended': 'Active', 'money': 7250, }, - { 'account_number': 3811007, 'name': 'Medical Account', 'suspended': 'Active', 'money': 7000, }, - { 'account_number': 3945008, 'name': 'Assistant Account', 'suspended': 'Active', 'money': 4500, }, -] - - datum.account_number} - - datumRowProps={(datum) => ({ - className: `AccountsUplinkTerminal__listRow--${datum.suspended}`, - })} - datumCellChildren={{ - name: (value) => <> {value}, - }} -/> -``` - -In the above example, the `columns` prop defines the fields in the data that -are used. `columns.id` is the key or the name of the property on the data, -while `columns.name` is what the user sees on the UI. `datumID` selects which -field in the data to use as the key for render caching. `datumID` can return -anything, but it must be unique. - -`datumRowProps` applies a class to a row if the account associated with that -row is suspended, and `datumCellChildren` prepends a wallet to the contents -of the `name` column. - ### `Tabs` Tabs make it easy to explore and switch between different views. @@ -1068,19 +968,3 @@ Can be scrollable. - `className: string` - Applies a CSS class to the element. - `scrollable: boolean` - Shows or hides the scrollbar. - `children: any` - Main content of your window. - -## `tgui/interfaces/common` - -## `RecordsTable` - -An extension to [`Table.Sortable`](#tablesortable) which provides a search -function and slots for buttons. - -**Props:** - -- See inherited props: [`Table.Sortable`](#tablesortable) -- `leftButtons: Component` - Optional buttons to add left of the search box. -- `rightButtons: Component` - Optional buttons to add right of the search box. -- `searchPlaceholder: string` - The default text in the search box. - -Use a ``(or `<>`) to specify multiple buttons. diff --git a/tgui/packages/tgui/components/Table.js b/tgui/packages/tgui/components/Table.js index 14228caa20f5..681a795ed42c 100644 --- a/tgui/packages/tgui/components/Table.js +++ b/tgui/packages/tgui/components/Table.js @@ -1,8 +1,5 @@ import { classes, pureComponentHooks } from 'common/react'; -import { computeBoxClassName, computeBoxProps } from './Box'; -import { Component } from 'inferno'; -import { Button } from './Button'; -import { Icon } from './Icon'; +import { Box, computeBoxClassName, computeBoxProps } from './Box'; export const Table = (props) => { const { className, collapsing, children, ...rest } = props; @@ -56,159 +53,7 @@ export const TableCell = (props) => { ); }; -const resolveFunctionalProp = (props, ...data) => - props ? (props instanceof Function ? props(...data) : props) : undefined; -class HoverableIcon extends Component { - constructor() { - super(); - this.state = { - hovering: false, - }; - this.handleMouseOver = (e) => { - this.setState({ hovering: true }); - }; - this.handleMouseOut = (e) => { - this.setState({ hovering: false }); - }; - } - - render() { - const { hoverIcon, name, ...rest } = this.props; - const { hovering } = this.state; - return ( - - ); - } -} - -class SortableTable extends Component { - constructor(props) { - super(); - this.state = { - // Allow null - sortId: props.sortId === undefined ? props.columns[0].id : props.sortId, - sortOrder: props.sortOrder ?? 1, - }; - } - - render() { - const { - className, - columnDefaults, - columns, - data, - datumID, - filter, - headerRowProps, - datumRowProps, - ...rest - } = this.props; - const { sortId, sortOrder } = this.state; - - const columnHeaders = columns.map( - ({ id, name, header: { props } = {} }) => { - const { - header: { props: defaultProps }, - } = columnDefaults; - return ( - - - - ); - } - ); - const dataRows = (filter ? filter(data) : data) - .sort((a, b) => { - if (sortId) { - const i = sortOrder ? 1 : -1; - return a[sortId].toString().localeCompare(b[sortId].toString()) * i; - } else { - return 0; - } - }) - .map((datum) => { - let cells = columns.map( - ({ id, name, datum: { props, children } = {} }) => { - const { - datum: { children: defaultChildren, props: defaultProps }, - } = columnDefaults; - return ( - - {resolveFunctionalProp(children, datum[id]) ?? - resolveFunctionalProp(defaultChildren, datum[id]) ?? - datum[id]} - - ); - } - ); - return ( - - {cells} - - ); - }); - return ( - - - {columnHeaders} - - {dataRows} -
- ); - } -} - TableCell.defaultHooks = pureComponentHooks; Table.Row = TableRow; Table.Cell = TableCell; -Table.Sortable = SortableTable; diff --git a/tgui/packages/tgui/interfaces/AccountsUplinkTerminal.js b/tgui/packages/tgui/interfaces/AccountsUplinkTerminal.js index b509baced50f..ecd2d7a397c9 100644 --- a/tgui/packages/tgui/interfaces/AccountsUplinkTerminal.js +++ b/tgui/packages/tgui/interfaces/AccountsUplinkTerminal.js @@ -1,7 +1,9 @@ +import { createSearch } from 'common/string'; import { Fragment } from 'inferno'; import { useBackend, useLocalState } from '../backend'; import { Button, + Flex, Icon, Input, LabeledList, @@ -9,10 +11,11 @@ import { Table, Tabs, } from '../components'; +import { FlexItem } from '../components/Flex'; +import { TableCell } from '../components/Table'; import { Window } from '../layouts'; import { LoginInfo } from './common/LoginInfo'; import { LoginScreen } from './common/LoginScreen'; -import { RecordsTable } from './common/RecordsTable'; export const AccountsUplinkTerminal = (properties, context) => { const { act, data } = useBackend(context); @@ -39,7 +42,7 @@ export const AccountsUplinkTerminal = (properties, context) => { return ( - + {body} @@ -78,95 +81,159 @@ const AccountsUplinkTerminalContent = (props, context) => { } }; -const AccountsRecordList = (props, context) => { +const AccountsRecordList = (properties, context) => { const { act, data } = useBackend(context); const { accounts } = data; + const [searchText, setSearchText] = useLocalState(context, 'searchText', ''); + const [sortId, _setSortId] = useLocalState(context, 'sortId', 'owner_name'); + const [sortOrder, _setSortOrder] = useLocalState(context, 'sortOrder', true); return ( - ( - <> - {value} - - ), - }, - }, - { - id: 'account_number', - name: 'Account Number', - datum: { children: (value) => <>#{value} }, - }, - { id: 'suspended', name: 'Account Status' }, - { id: 'money', name: 'Account Balance' }, - ]} - data={accounts} - datumID={(datum) => datum.account_number} - leftButtons={ - + + ); +}; + +const AccountsActions = (properties, context) => { + const { act, data } = useBackend(context); + const { is_printing } = data; + const [searchText, setSearchText] = useLocalState(context, 'searchText', ''); + return ( + + + + ); +}; + +const SortButton2 = (properties, context) => { + const [sortId2, setSortId2] = useLocalState(context, 'sortId2', 'name'); + const [sortOrder2, setSortOrder2] = useLocalState( + context, + 'sortOrder2', + true + ); + const { id, children } = properties; + return ( + + + + ); +}; + const MedicalRecordsNavigation = (_properties, context) => { const { act, data } = useBackend(context); const { screen, general } = data; diff --git a/tgui/packages/tgui/interfaces/SecurityRecords.js b/tgui/packages/tgui/interfaces/SecurityRecords.js index e49a3ff98706..b908f6d7ff36 100644 --- a/tgui/packages/tgui/interfaces/SecurityRecords.js +++ b/tgui/packages/tgui/interfaces/SecurityRecords.js @@ -1,13 +1,23 @@ -import { decodeHtmlEntities } from 'common/string'; +import { createSearch, decodeHtmlEntities } from 'common/string'; import { Fragment } from 'inferno'; -import { useBackend } from '../backend'; -import { Box, Button, Icon, LabeledList, Section, Tabs } from '../components'; +import { useBackend, useLocalState } from '../backend'; +import { + Box, + Button, + Flex, + Icon, + Input, + LabeledList, + Section, + Table, + Tabs, +} from '../components'; +import { FlexItem } from '../components/Flex'; import { Window } from '../layouts'; import { ComplexModal, modalOpen } from './common/ComplexModal'; import { LoginInfo } from './common/LoginInfo'; import { LoginScreen } from './common/LoginScreen'; import { TemporaryNotice } from './common/TemporaryNotice'; -import { RecordsTable } from './common/RecordsTable'; const statusStyles = { '*Execute*': 'execute', @@ -85,56 +95,128 @@ const SecurityRecordsNavigation = (properties, context) => { ); }; -const SecurityRecordsPageList = (props, context) => { +const SecurityRecordsPageList = (properties, context) => { const { act, data } = useBackend(context); - const { isPrinting, records } = data; + const { records } = data; + const [searchText, setSearchText] = useLocalState(context, 'searchText', ''); + const [sortId, _setSortId] = useLocalState(context, 'sortId', 'name'); + const [sortOrder, _setSortOrder] = useLocalState(context, 'sortOrder', true); return ( - ( - <> - {value} - - ), - }, - }, - { id: 'id', name: 'ID' }, - { id: 'rank', name: 'Assignment' }, - { id: 'fingerprint', name: 'Fingerprint' }, - { id: 'status', name: 'Criminal Status' }, - ]} - data={records} - datumID={(datum) => datum.id} - leftButtons={ - <> - + + ); +}; + +const SecurityRecordsActions = (properties, context) => { + const { act, data } = useBackend(context); + const { isPrinting } = data; + const [searchText, setSearchText] = useLocalState(context, 'searchText', ''); + return ( + + +