diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index aa7b5ef0c55a..a200c6302c79 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -14,7 +14,6 @@ # CI + Tooling /.github/workflows/ @AffectedArc07 -/code/modules/unit_tests/ @AffectedArc07 /tools/ci/ @AffectedArc07 _build_dependencies.sh @AffectedArc07 @@ -24,10 +23,14 @@ _build_dependencies.sh @AffectedArc07 # Executables that need to be security-cleared dreamchecker.exe @AffectedArc07 -milla.dll @AffectedArc07 +rustlibs.dll @AffectedArc07 rust_g.dll @AffectedArc07 ### S34NW # TGUI stuff /tgui/bin @S34NW + + +### Overrides for the above +/tools/ci/check_grep2.py @ParadiseSS13/commit-access diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm index db896ab95c5e..7bde2d91f8f5 100644 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm +++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm @@ -656,7 +656,7 @@ /turf/simulated/floor/plasteel/lavaland_air, /area/ruin/powered/clownplanet) "bf" = ( -/turf/simulated/mineral/clown/volcanic, +/turf/simulated/mineral/volcanic/clown, /area/ruin/powered/clownplanet) "bg" = ( /obj/item/pickaxe, @@ -1006,7 +1006,7 @@ /obj/structure/disposalpipe/segment/corner{ dir = 8 }, -/turf/simulated/mineral/clown/volcanic, +/turf/simulated/mineral/volcanic/clown, /area/ruin/powered/clownplanet) "pv" = ( /obj/machinery/light{ diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_althland_facility.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_althland_facility.dmm index bc2ac1d5611a..9c204680046b 100644 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_althland_facility.dmm +++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_althland_facility.dmm @@ -1,6 +1,7 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "aa" = ( /obj/effect/landmark/burnturf, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/lavaland/surface/outdoors) "ab" = ( @@ -126,6 +127,11 @@ }, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) +"dq" = ( +/obj/effect/spawner/random_spawners/wall_rusted_maybe, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/wall/r_wall, +/area/lavaland/surface/outdoors) "du" = ( /obj/effect/mapping_helpers/no_lava, /obj/machinery/light_construct/small{ @@ -357,12 +363,6 @@ /obj/item/storage/box/donkpockets/empty, /turf/simulated/floor/plasteel/lavaland_air, /area/ruin/unpowered/althland_processing) -"lr" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/damageturf, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) "lZ" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/door_assembly/door_assembly_ext{ @@ -380,6 +380,12 @@ }, /turf/simulated/floor/plating/lavaland_air, /area/ruin/unpowered/althland_processing) +"nj" = ( +/obj/structure/grille, +/obj/item/shard, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/lavaland_air, +/area/lavaland/surface/outdoors) "nm" = ( /obj/structure/disposalpipe/broken{ dir = 2 @@ -405,6 +411,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/glass, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/lavaland/surface/outdoors) "nQ" = ( @@ -418,6 +425,7 @@ /area/ruin/unpowered/althland_processing) "oG" = ( /obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/lavaland/surface/outdoors) "pn" = ( @@ -437,6 +445,13 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/landmark/damageturf, /obj/effect/decal/cleanable/glass, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/lavaland_air, +/area/lavaland/surface/outdoors) +"pQ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/damageturf, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/lavaland/surface/outdoors) "qh" = ( @@ -491,6 +506,7 @@ /obj/effect/decal/remains/human, /obj/item/clothing/under/rank/cargo/miner, /obj/item/paper/fluff/ruins/althland/journal, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/lavaland/surface/outdoors) "sa" = ( @@ -503,6 +519,7 @@ /area/ruin/unpowered/althland_processing) "sg" = ( /obj/effect/landmark/damageturf, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/lavaland/surface/outdoors) "su" = ( @@ -513,6 +530,7 @@ amount = 5 }, /obj/effect/landmark/damageturf, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/lavaland/surface/outdoors) "sB" = ( @@ -529,6 +547,7 @@ /obj/structure/marker_beacon/dock_marker, /obj/effect/decal/cleanable/dirt, /obj/effect/landmark/damageturf, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/lavaland/surface/outdoors) "tv" = ( @@ -627,6 +646,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/remains/human, /obj/item/clothing/under/rank/cargo/miner, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/ruin/unpowered/althland_processing) "vM" = ( @@ -634,6 +654,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/landmark/damageturf, /obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/lavaland/surface/outdoors) "wZ" = ( @@ -710,6 +731,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/landmark/damageturf, /obj/effect/decal/cleanable/glass, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/lavaland/surface/outdoors) "zR" = ( @@ -752,6 +774,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /obj/effect/landmark/damageturf, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/lavaland/surface/outdoors) "BB" = ( @@ -767,6 +790,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/landmark/damageturf, /obj/effect/decal/cleanable/glass, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/ruin/unpowered/althland_processing) "BM" = ( @@ -927,6 +951,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/remains/human, /obj/item/clothing/under/rank/cargo/miner, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/ruin/unpowered/althland_processing) "Gt" = ( @@ -1020,6 +1045,11 @@ /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating/lavaland_air, /area/ruin/unpowered/althland_processing) +"JJ" = ( +/obj/effect/mapping_helpers/lava_magnet, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) "JT" = ( /obj/structure/grille, /obj/item/shard, @@ -1087,6 +1117,7 @@ /obj/structure/girder, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/lavaland/surface/outdoors) "Mu" = ( @@ -1175,14 +1206,10 @@ /obj/effect/decal/cleanable/glass, /turf/simulated/floor/plating/lavaland_air, /area/ruin/unpowered/althland_processing) -"PJ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/damageturf, -/turf/simulated/floor/plating/lavaland_air, -/area/lavaland/surface/outdoors) "PY" = ( /obj/structure/marker_beacon/dock_marker, /obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/lavaland/surface/outdoors) "Qj" = ( @@ -1223,9 +1250,15 @@ /obj/effect/landmark/damageturf, /turf/simulated/floor/plasteel/lavaland_air, /area/ruin/unpowered/althland_processing) +"Tn" = ( +/obj/effect/spawner/random_spawners/wall_rusted_always, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/wall/r_wall, +/area/lavaland/surface/outdoors) "TN" = ( /obj/effect/landmark/damageturf, /obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/lavaland/surface/outdoors) "TX" = ( @@ -1234,6 +1267,12 @@ }, /turf/simulated/floor/plating/lavaland_air, /area/ruin/unpowered/althland_processing) +"Uq" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/damageturf, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/lavaland_air, +/area/ruin/unpowered/althland_processing) "UP" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, @@ -1253,6 +1292,13 @@ }, /turf/simulated/floor/plating/lavaland_air, /area/ruin/unpowered/althland_processing) +"VA" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/damageturf, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/lavaland_air, +/area/lavaland/surface/outdoors) "VJ" = ( /obj/effect/mapping_helpers/no_lava, /obj/structure/sign/nosmoking_1{ @@ -1293,6 +1339,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/landmark/burnturf, /obj/effect/decal/cleanable/glass, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/lavaland/surface/outdoors) "WQ" = ( @@ -1327,6 +1374,7 @@ /obj/item/clothing/under/rank/cargo/miner, /obj/effect/decal/cleanable/dirt, /obj/effect/landmark/damageturf, +/obj/effect/mapping_helpers/no_lava, /turf/simulated/floor/plating/lavaland_air, /area/lavaland/surface/outdoors) "XO" = ( @@ -1528,10 +1576,10 @@ bU ab KZ ab -ab +yh bT -ab -cb +yh +yh ab ab ab @@ -1566,8 +1614,8 @@ ab ab bT bT -ab -bL +yh +yh bL ab Dg @@ -1602,7 +1650,7 @@ ui ui bT bT -ab +yh ab bL ab @@ -1805,7 +1853,7 @@ bV bL ab af -hI +dq bT ab ab @@ -1895,7 +1943,7 @@ ab bT bT af -be +Tn af ui vf @@ -1946,9 +1994,9 @@ bL "} (15,1,1) = {" bV -ab -ab -ab +yh +yh +yh bT bT bL @@ -1981,10 +2029,10 @@ ab bL "} (16,1,1) = {" -bV -bL -ab -ab +yh +yh +yh +yh bT bT ab @@ -2017,10 +2065,10 @@ ab bL "} (17,1,1) = {" -bV -bL -bL -ab +yh +yh +yh +yh bT bT ab @@ -2034,7 +2082,7 @@ sQ ui ab ab -ab +JJ ab cb ab @@ -2053,10 +2101,10 @@ ab bL "} (18,1,1) = {" -bV -bL -bL -ab +yh +yh +yh +yh bT bT ab @@ -2085,14 +2133,14 @@ rd af bT ab -ab -bL +yh +yh "} (19,1,1) = {" bV -bL -bV -ab +yh +yh +yh bT bT ab @@ -2121,8 +2169,8 @@ af bT bT hI -ab -bL +yh +yh "} (20,1,1) = {" bV @@ -2156,9 +2204,9 @@ ui af bT bT -ab -ab -bL +yh +yh +yh "} (21,1,1) = {" bV @@ -2190,18 +2238,18 @@ bT bT bT bT -hI +dq af -bT -ab -bL +yh +yh +yh "} (22,1,1) = {" bV bL ab ab -hI +dq af bT bT @@ -2228,9 +2276,9 @@ bT bT bT bT -ab -ab -bL +yh +yh +yh "} (23,1,1) = {" bV @@ -2242,7 +2290,7 @@ ab bT bT bT -hI +dq bT bT bT @@ -2264,9 +2312,9 @@ bT bT bT ab -ab -ab -bL +yh +yh +yh "} (24,1,1) = {" bV @@ -2290,19 +2338,19 @@ nK um lZ ui -Yd +nj nN hI af AL af af -hI +dq bT ab -ab -ab -bL +yh +yh +yh "} (25,1,1) = {" bV @@ -2317,7 +2365,7 @@ bT bT af af -hI +dq af bT ui @@ -2329,16 +2377,16 @@ ui af af zO -PJ +pQ AL -PJ -lr +pQ +VA to bT bT bT -ab -bL +yh +yh "} (26,1,1) = {" bV @@ -2347,7 +2395,7 @@ bV cb ab bT -PJ +pQ ui ui ui @@ -2364,17 +2412,17 @@ Fa ui bT Gk -PJ +pQ af af XD -PJ +pQ af bT bT bT -ab -bU +yh +yh "} (27,1,1) = {" bV @@ -2382,8 +2430,8 @@ bL bL ab bT -lr -lr +VA +VA ui zp vl @@ -2398,7 +2446,7 @@ fm Jw fc bP -BV +Uq BG vM bT @@ -2435,12 +2483,12 @@ Io hj ui vo -BV +Uq rY bT -PJ -PJ -lr +pQ +pQ +VA af bT bT @@ -2475,7 +2523,7 @@ bT PY pP bT -PJ +pQ bT af bT @@ -2489,7 +2537,7 @@ bV bL ab ab -lr +VA bT bT bT @@ -2526,7 +2574,7 @@ bL ab ab ab -lr +VA bT sg ui @@ -2607,7 +2655,7 @@ bT bT bT bT -hI +dq bT bT bT @@ -2716,9 +2764,9 @@ ab ab ab ab -ab -ab -ab +yh +yh +yh cM cM cM @@ -2752,9 +2800,9 @@ bV bV bV bV -bV -bV -bV +yh +yh +yh cM cM cM diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_shuttlecrash.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_shuttlecrash.dmm index d6bbb5279bdf..7914ee1fcda7 100644 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_shuttlecrash.dmm +++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_shuttlecrash.dmm @@ -32,6 +32,9 @@ "dD" = ( /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) +"dM" = ( +/turf/template_noop, +/area/lavaland/surface/outdoors/unexplored) "dS" = ( /obj/structure/chair/comfy/shuttle{ dir = 8 @@ -571,6 +574,10 @@ "Sj" = ( /turf/simulated/floor/plating/lavaland_air, /area/ruin/unpowered/misc_lavaruin) +"Sy" = ( +/obj/effect/mapping_helpers/lava_magnet, +/turf/simulated/floor/lava/mapping_lava, +/area/lavaland/surface/outdoors) "SH" = ( /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface{ icon_state = "basalt_dug" @@ -1018,8 +1025,8 @@ dD Fy "} (17,1,1) = {" -NG -dD +dM +dM dD hK dD @@ -1036,11 +1043,11 @@ Et SH dD It -Gt +dM "} (18,1,1) = {" -NG -dD +dM +dM hK hK dD @@ -1056,11 +1063,11 @@ mN Et Gt Gt -Gt -Gt +dM +dM "} (19,1,1) = {" -dD +dM hK hK hK @@ -1077,11 +1084,11 @@ Aj hK dD hK -dD -Gt +dM +dM "} (20,1,1) = {" -dD +dM hK hK hK @@ -1132,7 +1139,7 @@ hK hK hK hK -hK +Sy hK hK hK @@ -1183,11 +1190,11 @@ dD hK dD hK -dD +dM "} (25,1,1) = {" hK -dD +dM hK dD Gt @@ -1203,12 +1210,12 @@ cl Gt cl Gt -Gt -Gt +dM +dM "} (26,1,1) = {" -Gt -Gt +dM +dM Gt Gt wf @@ -1225,11 +1232,11 @@ It It It Gt -dD +dM "} (27,1,1) = {" -NG -dD +dM +dM It Gt cl @@ -1249,8 +1256,8 @@ dD NG "} (28,1,1) = {" -NG -dD +dM +dM dD Gt It @@ -1270,7 +1277,7 @@ dD NG "} (29,1,1) = {" -NG +dM dD It Gt diff --git a/_maps/map_files/generic/Lavaland.dmm b/_maps/map_files/generic/Lavaland.dmm index a3047e86d7a3..c1955a7c2c53 100644 --- a/_maps/map_files/generic/Lavaland.dmm +++ b/_maps/map_files/generic/Lavaland.dmm @@ -73,7 +73,7 @@ /turf/simulated/mineral/random/volcanic, /area/lavaland/surface/outdoors/unexplored) "an" = ( -/turf/simulated/mineral/random/labormineral/volcanic, +/turf/simulated/mineral/random/volcanic/labormineral, /area/lavaland/surface/outdoors) "ao" = ( /obj/effect/spawner/random_spawners/dirt_maybe, diff --git a/_maps/map_files/generic/centcomm.dmm b/_maps/map_files/generic/centcomm.dmm index c3a33227e959..be9617854081 100644 --- a/_maps/map_files/generic/centcomm.dmm +++ b/_maps/map_files/generic/centcomm.dmm @@ -319,15 +319,6 @@ icon_state = "dark" }, /area/ghost_bar) -"bj" = ( -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/obj/machinery/light{ - dir = 4 - }, -/turf/simulated/floor/mineral/plastitanium/red, -/area/shuttle/assault_pod) "bo" = ( /turf/simulated/floor/holofloor{ dir = 4; @@ -5315,7 +5306,7 @@ /area/shuttle/assault_pod) "rJ" = ( /obj/machinery/computer/shuttle/syndicate/drop_pod, -/turf/simulated/floor/mineral/plastitanium/red, +/turf/simulated/wall/mineral/plastitanium, /area/shuttle/assault_pod) "rK" = ( /obj/effect/spawner/lootdrop/trade_sol/sci, @@ -68871,11 +68862,11 @@ aN Yi nO ov -bj +qs qo rL qo -bj +qs ov tp Yi @@ -69131,7 +69122,7 @@ ou ov qs qo -qo +qs ov ou tp diff --git a/_maps/map_files220/generic/Lavaland.dmm b/_maps/map_files220/generic/Lavaland.dmm index 45a19b839226..304d7de4595c 100644 --- a/_maps/map_files220/generic/Lavaland.dmm +++ b/_maps/map_files220/generic/Lavaland.dmm @@ -76,7 +76,7 @@ /turf/simulated/mineral/random/volcanic, /area/lavaland/surface/outdoors/unexplored) "an" = ( -/turf/simulated/mineral/random/labormineral/volcanic, +/turf/simulated/mineral/random/volcanic/labormineral, /area/lavaland/surface/outdoors) "ap" = ( /obj/effect/spawner/window/reinforced/plasma/grilled, diff --git a/code/__DEFINES/dcs/mob_signals.dm b/code/__DEFINES/dcs/mob_signals.dm index 487a1eb2d85e..2922c06f9f9a 100644 --- a/code/__DEFINES/dcs/mob_signals.dm +++ b/code/__DEFINES/dcs/mob_signals.dm @@ -212,3 +212,6 @@ /// Sent from datum/spell/ethereal_jaunt/cast, before the mob enters jaunting as a pre-check: (mob/jaunter) #define COMSIG_MOB_PRE_JAUNT "spell_mob_pre_jaunt" #define COMPONENT_BLOCK_JAUNT (1<<0) + +/// from remove_ventcrawler(): (mob/living/crawler) +#define COMSIG_LIVING_EXIT_VENTCRAWL "living_exit_ventcrawl" diff --git a/code/__DEFINES/pipes.dm b/code/__DEFINES/pipes.dm index 8eadcae54e6f..ec5fbd01cd98 100644 --- a/code/__DEFINES/pipes.dm +++ b/code/__DEFINES/pipes.dm @@ -1,5 +1,4 @@ -//Atmospherics pipes - +// MARK: Atmospherics pipes #define PIPE_SIMPLE_STRAIGHT 0 #define PIPE_SIMPLE_BENT 1 #define PIPE_HE_STRAIGHT 2 @@ -41,8 +40,7 @@ #define PIPE_GAS_SENSOR 98 #define PIPE_METER 99 -//Disposals pipes - +// MARK: Disposals pipes #define PIPE_DISPOSALS_STRAIGHT 100 #define PIPE_DISPOSALS_BENT 101 #define PIPE_DISPOSALS_JUNCTION_RIGHT 102 @@ -55,7 +53,7 @@ #define PIPE_DISPOSALS_SORT_RIGHT 109 #define PIPE_DISPOSALS_SORT_LEFT 110 -// Transit tubes +// MARK: Transit tubes #define PIPE_TRANSIT_POD 200 #define PIPE_TRANSIT_TUBE 201 #define PIPE_TRANSIT_TUBE_DIAGONAL 202 @@ -65,8 +63,7 @@ #define PIPE_TRANSIT_TUBE_TERMINUS_DISPENSER 206 #define PIPE_TRANSIT_TUBE_DISPENSER_STATION 207 -//RPD stuff - +// MARK: RPD stuff #define RPD_ATMOS_MODE 1 #define RPD_DISPOSALS_MODE 2 #define RPD_ROTATE_MODE 3 @@ -84,8 +81,9 @@ #define PIPETYPE_DISPOSAL 2 #define PIPETYPE_TRANSIT 3 -// Connection types +#define RPD_TOOL_SUCCESS (1<<1) +// MARK: Connection types #define CONNECT_TYPE_NORMAL 1 #define CONNECT_TYPE_SUPPLY 2 #define CONNECT_TYPE_SCRUBBER 3 diff --git a/code/__DEFINES/turfs.dm b/code/__DEFINES/turfs.dm index b1104bbf7132..9306a89a6165 100644 --- a/code/__DEFINES/turfs.dm +++ b/code/__DEFINES/turfs.dm @@ -10,3 +10,6 @@ /// Returns a list of around us #define TURF_NEIGHBORS(turf) (CORNER_BLOCK_OFFSET(turf, 3, 3, -1, -1) - turf) + +#define MINERAL_PREVENT_DIG 0 //! A mineral turf should not be changed when mined. +#define MINERAL_ALLOW_DIG 1 //! A mineral turf should be dug out when mined. diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index 21ecb3caf4f5..15b11466300d 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -102,7 +102,8 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ABSTRACT_HANDS" = TRAIT_ABSTRACT_HANDS, "TRAIT_LANGUAGE_LOCKED" = TRAIT_LANGUAGE_LOCKED, "TRAIT_NON_INFECTIOUS_ZOMBIE" = TRAIT_NON_INFECTIOUS_ZOMBIE, - "TRAIT_CANNOT_PULL" = TRAIT_CANNOT_PULL + "TRAIT_CANNOT_PULL" = TRAIT_CANNOT_PULL, + "TRAIT_FLYING" = TRAIT_FLYING ), /datum/mind = list( diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 479be6b86acb..2cf74f2d8a86 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -615,9 +615,9 @@ so as to remain in compliance with the most up-to-date laws." /atom/movable/screen/alert/ghost name = "Ghost" - desc = "Would you like to ghost? You will be notified when your body is removed from the nest." + desc = "Would you like to ghost?" icon_state = "template" - timeout = 5 MINUTES // longer than any infection should be + timeout = 5 MINUTES /atom/movable/screen/alert/ghost/Initialize(mapload) . = ..() @@ -626,7 +626,21 @@ so as to remain in compliance with the most up-to-date laws." I.plane = FLOAT_PLANE overlays += I +/atom/movable/screen/alert/ghost/proc/handle_ghosting(mob/living/carbon/human/target) + target.ghost() + /atom/movable/screen/alert/ghost/Click() + if(!..()) + return + handle_ghosting(usr) + +/atom/movable/screen/alert/ghost/cryo + desc = "Would you like to ghost? Your body will automatically be moved into cryostorage." + +/atom/movable/screen/alert/ghost/xeno + desc = "Would you like to ghost? You will be notified when your body is removed from the nest." + +/atom/movable/screen/alert/ghost/xeno/Click() if(!..()) return var/mob/living/carbon/human/infected_user = usr diff --git a/code/datums/ores.dm b/code/datums/ores.dm new file mode 100644 index 000000000000..7e0747669ab1 --- /dev/null +++ b/code/datums/ores.dm @@ -0,0 +1,204 @@ +/datum/ore + /// The type of ore that is dropped. Expected to be a subtype of [/obj/item/stack/ore]. + var/drop_type + /// The lower bound for the amount of randomized ore dropped. + var/drop_min = 1 + /// The upper bound for the amount of randomized ore dropped. + var/drop_max = 5 + /// The probability that the ore will spread to nearby [/turf/simulated/mineral]s when placed. + var/spread_chance = 0 + /// The icon state of the ore used for mining scanner overlays. + var/scan_icon_state = "" + +/** + * Called when the containing turf is "mined", such as with a pickaxe or other + * digging implement. + * + * Returns [MINERAL_ALLOW_DIG] if the containing turf should be changed to its + * "dug" state, [MINERAL_PREVENT_DIG] if it should remain as is. + */ +/datum/ore/proc/on_mine(turf/source, mob/user, triggered_by_explosion = FALSE) + var/amount = rand(drop_min, drop_max) + + if(ispath(drop_type, /obj/item/stack/ore)) + new drop_type(source, amount) + SSticker.score?.score_ore_mined++ + SSblackbox.record_feedback("tally", "ore_mined", amount, type) + else + stack_trace("[source.type] [COORD(source)] had non-ore stack [drop_type]") + + return MINERAL_ALLOW_DIG + +/datum/ore/iron + drop_type = /obj/item/stack/ore/iron + spread_chance = 20 + scan_icon_state = "rock_Iron" + +/datum/ore/uranium + drop_type = /obj/item/stack/ore/uranium + spread_chance = 5 + scan_icon_state = "rock_Uranium" + +/datum/ore/diamond + drop_type = /obj/item/stack/ore/diamond + scan_icon_state = "rock_Diamond" + +/datum/ore/gold + drop_type = /obj/item/stack/ore/gold + spread_chance = 5 + scan_icon_state = "rock_Gold" + +/datum/ore/silver + drop_type = /obj/item/stack/ore/silver + spread_chance = 5 + scan_icon_state = "rock_Silver" + +/datum/ore/titanium + drop_type = /obj/item/stack/ore/titanium + spread_chance = 5 + scan_icon_state = "rock_Titanium" + +/datum/ore/plasma + drop_type = /obj/item/stack/ore/plasma + spread_chance = 8 + scan_icon_state = "rock_Plasma" + +/datum/ore/bluespace + drop_type = /obj/item/stack/ore/bluespace_crystal + drop_min = 1 + drop_max = 1 + scan_icon_state = "rock_BScrystal" + +/datum/ore/bananium + drop_type = /obj/item/stack/ore/bananium + drop_min = 3 + drop_max = 3 + scan_icon_state = "rock_Clown" + +/datum/ore/tranquillite + drop_type = /obj/item/stack/ore/tranquillite + drop_min = 3 + drop_max = 3 + +/datum/ore/ancient_basalt + drop_type = /obj/item/stack/ore/glass/basalt/ancient + drop_min = 2 + drop_max = 2 + +#define GIBTONITE_UNSTRUCK 0 //! The gibtonite ore is dormant. +#define GIBTONITE_ACTIVE 1 //! The gibtonite ore is in its detonation countdown. +#define GIBTONITE_STABLE 2 //! The gibtonite ore has been stabilized and its detonation countdown is cancelled. +#define GIBTONITE_DETONATE 3 //! The gibtonite ore is about to explode. + +/datum/ore/gibtonite + drop_max = 1 + scan_icon_state = "rock_Gibtonite" + /// Amount of time from mining before gibtonite explodes. + var/detonate_time + /// The world.time that the detonate countdown started at. + var/detonate_start_time + /// The amount of time remaining if the gibtonite was stabilized before explosion, in half-seconds. + var/remaining_time + /// The state the ore is in. One of [GIBTONITE_UNSTRUCK], [GIBTONITE_ACTIVE], [GIBTONITE_STABLE], or [GIBTONITE_DETONATE]. + var/stage = GIBTONITE_UNSTRUCK + /// The overlay used for when the gibtonite is in its detonation countdown mode. + var/mutable_appearance/activated_overlay + /// Whether an admin log should be generated for this gibtonite's detonation. + /// Typically enabled if the detonation doesn't occur on the station z-level. + /// Note that this is only for explosions caused while the gibtonite is still + /// unmined, in contrast to [/obj/item/gibtonite/proc/GibtoniteReaction]. + var/notify_admins = FALSE + +/datum/ore/gibtonite/New() + // So you don't know exactly when the hot potato will explode + detonate_time = rand(4 SECONDS, 5 SECONDS) + +/datum/ore/gibtonite/proc/explosive_reaction(turf/source, mob/user, triggered_by_explosion = FALSE) + activated_overlay = mutable_appearance(source.icon, "rock_Gibtonite_active", ON_EDGED_TURF_LAYER) + source.add_overlay(activated_overlay) + source.name = "gibtonite deposit" + source.desc = "An active gibtonite reserve. Run!" + stage = GIBTONITE_ACTIVE + source.visible_message("There was gibtonite inside! It's going to explode!") + + if(!is_mining_level(source.z)) + notify_admins = TRUE + if(!triggered_by_explosion) + message_admins("[key_name_admin(user)] has triggered a gibtonite deposit reaction at [ADMIN_VERBOSEJMP(source)].") + else + message_admins("An explosion has triggered a gibtonite deposit reaction at [ADMIN_VERBOSEJMP(source)].") + + if(!triggered_by_explosion) + log_game("[key_name(user)] has triggered a gibtonite deposit reaction at [AREACOORD(source)].") + else + log_game("An explosion has triggered a gibtonite deposit reaction at [AREACOORD(source)].") + + RegisterSignal(source, COMSIG_PARENT_ATTACKBY, PROC_REF(on_parent_attackby)) + detonate_start_time = world.time + addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/ore/gibtonite, detonate), source), detonate_time) + +/datum/ore/gibtonite/on_mine(turf/source, mob/user, triggered_by_explosion = FALSE) + switch(stage) + if(GIBTONITE_UNSTRUCK) + playsound(src,'sound/effects/hit_on_shattered_glass.ogg', 50, TRUE) + explosive_reaction(source, user, triggered_by_explosion) + return MINERAL_PREVENT_DIG + if(GIBTONITE_ACTIVE) + detonate(source) + + return MINERAL_ALLOW_DIG + if(GIBTONITE_STABLE) + var/obj/item/gibtonite/gibtonite = new(source) + if(remaining_time <= 0) + gibtonite.quality = 3 + gibtonite.icon_state = "Gibtonite ore 3" + if(remaining_time >= 1 && remaining_time <= 2) + gibtonite.quality = 2 + gibtonite.icon_state = "Gibtonite ore 2" + + return MINERAL_ALLOW_DIG + + return MINERAL_PREVENT_DIG + +/datum/ore/gibtonite/proc/on_parent_attackby(turf/source, obj/item/attacker, mob/user) + SIGNAL_HANDLER // COMSIG_PARENT_ATTACKBY + + if(istype(attacker, /obj/item/mining_scanner) || istype(attacker, /obj/item/t_scanner/adv_mining_scanner) && stage == GIBTONITE_ACTIVE) + user.visible_message("[user] holds [attacker] to [src]...", "You use [attacker] to locate where to cut off the chain reaction and attempt to stop it...") + defuse(source) + return COMPONENT_NO_AFTERATTACK + +/datum/ore/gibtonite/proc/detonate(turf/simulated/mineral/source) + if(stage == GIBTONITE_STABLE) + return + + stage = GIBTONITE_DETONATE + explosion(source, 1, 3, 5, adminlog = notify_admins) + + if(!istype(source)) + return + + // Dunno where else to put this + source.ChangeTurf(source.turf_type, source.defer_change) + addtimer(CALLBACK(source, TYPE_PROC_REF(/turf, AfterChange)), 1, TIMER_UNIQUE) + +/datum/ore/gibtonite/proc/defuse(turf/source) + var/world_time = world.time // Grab this immediately so we're fairly calculating countdown time + if(stage == GIBTONITE_ACTIVE) + source.cut_overlay(activated_overlay) + activated_overlay.icon_state = "rock_Gibtonite_inactive" + source.add_overlay(activated_overlay) + source.desc = "An inactive gibtonite reserve. The ore can be extracted." + stage = GIBTONITE_STABLE + + // ticks remaining / 10 = seconds remaining * 2 countdown decrements every second + remaining_time = floor((detonate_time - (world_time - detonate_start_time)) / 5) + + if(remaining_time < 0) + remaining_time = 0 + source.visible_message("The chain reaction was stopped! The gibtonite had [remaining_time] reactions left till the explosion!") + +#undef GIBTONITE_UNSTRUCK +#undef GIBTONITE_ACTIVE +#undef GIBTONITE_STABLE +#undef GIBTONITE_DETONATE diff --git a/code/game/gamemodes/autotraitor/autotraitor.dm b/code/game/gamemodes/autotraitor/autotraitor.dm index 9752d190b916..25203e503e12 100644 --- a/code/game/gamemodes/autotraitor/autotraitor.dm +++ b/code/game/gamemodes/autotraitor/autotraitor.dm @@ -64,10 +64,12 @@ var/list/possible_traitors = list() for(var/mob/living/player in GLOB.mob_list) if(player.client && player.stat != DEAD) - player_count += 1 if(!player.mind) continue - if(player.mind.special_role) + if(player.mind.offstation_role) //Don't count as crew. + continue + player_count += 1 + if(player.mind.has_antag_datum(/datum/antagonist/traitor)) traitor_count += 1 continue if(ishuman(player) || isAI(player)) diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index 3dce596278e8..624ac346f7b9 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -622,7 +622,7 @@ /datum/spellbook_entry/item/pulsedemonbottle name = "Living Lightbulb" - desc = "A magically sealed lightbulb confining some manner of electricity based creature. Beware, these creatures are indiscriminate in their shocking antics, and you yourself may become a victim." + desc = "A magically sealed lightbulb confining some manner of electricity based creature. Beware, these creatures are indiscriminate in their shocking antics, and you yourself may become a victim. It is *heavily* advised not to summon it in maintenance areas." item_path = /obj/item/antag_spawner/pulse_demon category = "Summons" limit = 3 diff --git a/code/game/machinery/airlock_control/airlock_controllers.dm b/code/game/machinery/airlock_control/airlock_controllers.dm index fd30655fe805..4328b3063ee2 100644 --- a/code/game/machinery/airlock_control/airlock_controllers.dm +++ b/code/game/machinery/airlock_control/airlock_controllers.dm @@ -263,7 +263,8 @@ if(QDELETED(V)) vents -= vent_uid continue - + if(V.on == FALSE && power == FALSE) // Don't bother if it's already off + continue V.on = power V.releasing = direction V.external_pressure_bound = pressure diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index f83285fc6afb..2870683a5c3f 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -352,7 +352,7 @@ if("make_cc_announcement") if(!ADMIN_CHECK(ui.user)) return - if(!text2bool(params["classified"])) + if(params["classified"] != 1) // this uses 1/0 on the js side instead of "true" or "false" GLOB.major_announcement.Announce( params["text"], new_title = "Central Command Report", diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 6d17e55271a6..07a63c0574f8 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -501,6 +501,7 @@ icon_state = occupied_icon_state + M.throw_alert("cryopod", /atom/movable/screen/alert/ghost/cryo) to_chat(M, "[on_enter_occupant_message]") to_chat(M, "If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.") @@ -585,6 +586,7 @@ icon_state = occupied_icon_state to_chat(E, "[on_enter_occupant_message]") to_chat(E, "If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.") + E.throw_alert("cryopod", /atom/movable/screen/alert/ghost/cryo) occupant = E name = "[name] ([occupant.name])" time_entered = world.time @@ -606,6 +608,7 @@ return occupant.forceMove(get_turf(src)) + occupant.clear_alert("cryopod") occupant = null icon_state = base_icon_state name = initial(name) diff --git a/code/game/machinery/pipe/pipe_construction.dm b/code/game/machinery/pipe/pipe_construction.dm index 51304148e0e6..2a8771237ccd 100644 --- a/code/game/machinery/pipe/pipe_construction.dm +++ b/code/game/machinery/pipe/pipe_construction.dm @@ -341,7 +341,6 @@ /obj/item/pipe/wrench_act(mob/user, obj/item/I) . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) return @@ -528,6 +527,7 @@ "You fasten [src].", "You hear a ratchet.") qdel(src) // remove the pipe item + . |= RPD_TOOL_SUCCESS /obj/item/pipe_meter name = "meter" diff --git a/code/game/objects/items/devices/radio/radio_objects.dm b/code/game/objects/items/devices/radio/radio_objects.dm index 307c2e0f87f3..a12c35c1a2de 100644 --- a/code/game/objects/items/devices/radio/radio_objects.dm +++ b/code/game/objects/items/devices/radio/radio_objects.dm @@ -82,6 +82,8 @@ GLOBAL_LIST_EMPTY(deadsay_radio_systems) var/requires_tcomms = FALSE // Does this device require tcomms to work.If TRUE it wont function at all without tcomms. If FALSE, it will work without tcomms, just slowly var/instant = FALSE // Should this device instantly communicate if there isnt tcomms + /// A timer that, when going off, will turn this radio on again + var/radio_enable_timer /obj/item/radio/proc/set_frequency(new_frequency) SSradio.remove_object(src, frequency) diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 6776d7fdeded..9ad6b1cc5a3b 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -74,6 +74,8 @@ if(ismob(AM) && AM.stat == CONSCIOUS) to_chat(user, "You can't get the [src] to stick to [AM]! Perhaps if [AM] was asleep or dead you could attach it?") return + if(isstorage(AM) || ismodcontrol(AM)) + return ..() //Let us not have people c4 themselfs. Especially with a now 1.5 second do_after if(isobserver(AM)) to_chat(user, "Your hand just phases through [AM]!") return diff --git a/code/game/objects/items/weapons/rpd.dm b/code/game/objects/items/weapons/rpd.dm index 89043519bfe2..bc55bdcf4c6f 100644 --- a/code/game/objects/items/weapons/rpd.dm +++ b/code/game/objects/items/weapons/rpd.dm @@ -39,6 +39,7 @@ var/ranged = FALSE var/primary_sound = 'sound/machines/click.ogg' var/alt_sound = null + var/auto_wrench_toggle = TRUE //Lists of things var/list/mainmenu = list( @@ -114,8 +115,7 @@ else if(!iconrotation) //If user selected a rotation P.dir = user.dir to_chat(user, "[src] rapidly dispenses [P]!") - if(istype(user.get_inactive_hand(), /obj/item/wrench) && (user.can_reach(P, user.get_inactive_hand()))) - P.wrench_act(user, user.get_inactive_hand()) + automatic_wrench_down(user, P) activate_rpd(TRUE) /obj/item/rpd/proc/create_disposals_pipe(mob/user, turf/T) //Make a disposals pipe / construct @@ -127,8 +127,7 @@ if(!iconrotation && whatdpipe != PIPE_DISPOSALS_JUNCTION_RIGHT) //Disposals pipes are in the opposite direction to atmos pipes, so we need to flip them. Junctions don't have this quirk though P.flip() to_chat(user, "[src] rapidly dispenses [P]!") - if(istype(user.get_inactive_hand(), /obj/item/wrench) && (user.can_reach(P, user.get_inactive_hand()))) - P.attackby(user.get_inactive_hand(), user) + automatic_wrench_down(user, P) activate_rpd(TRUE) /obj/item/rpd/proc/create_transit_tube(mob/user, turf/dest) @@ -144,8 +143,7 @@ S.dir = iconrotation ? iconrotation : user.dir to_chat(user, "[src] rapidly dispenses [S]!") - if(istype(user.get_inactive_hand(), /obj/item/wrench) && (user.can_reach(S, user.get_inactive_hand()))) - S.wrench_act(user, user.get_inactive_hand()) + automatic_wrench_down(user, S) activate_rpd(TRUE) /obj/item/rpd/proc/rotate_all_pipes(mob/user, turf/T) //Rotate all pipes on a turf @@ -195,6 +193,22 @@ QDEL_NULL(P) activate_rpd() +/** + * Automatically wrenches down an atmos device/pipe if the auto_wrench_toggle is TRUE. + * Arguments: + * * user - the user of the RPD. + * * target - the pipe/device/tube being placed by the RPD. + */ +/obj/item/rpd/proc/automatic_wrench_down(mob/living/user, obj/item/target) + if(!auto_wrench_toggle) + return + if(mode == RPD_TRANSIT_MODE) + if(target.screwdriver_act(user, src) & RPD_TOOL_SUCCESS) + playsound(src, 'sound/items/impactwrench.ogg', 50, TRUE) + return + if(target.wrench_act(user, src) & RPD_TOOL_SUCCESS) + playsound(src, 'sound/items/impactwrench.ogg', 50, TRUE) + return // TGUI stuff /obj/item/rpd/attack_self(mob/user) @@ -228,6 +242,7 @@ data["whatdpipe"] = whatdpipe data["whatpipe"] = whatpipe data["whatttube"] = whatttube + data["auto_wrench_toggle"] = auto_wrench_toggle return data /obj/item/rpd/ui_act(action, list/params) @@ -249,6 +264,8 @@ pipe_category = isnum(params[action]) ? params[action] : text2num(params[action]) if("mode") mode = isnum(params[action]) ? params[action] : text2num(params[action]) + if("auto_wrench_toggle") + auto_wrench_toggle = !auto_wrench_toggle //RPD radial menu /obj/item/rpd/proc/check_menu(mob/living/user) @@ -325,14 +342,17 @@ // If we get here, then we're effectively acting on the turf, probably placing a pipe. if(ranged) //woosh beam if bluespaced at a distance - if(get_dist(src, T) <= (user.client.maxview() + 2))\ - user.Beam(T, icon_state = "rped_upgrade", icon = 'icons/effects/effects.dmi', time = 5) - else + if(get_dist(src, T) >= (user.client.maxview() + 2)) message_admins("\[EXPLOIT] [key_name_admin(user)] attempted to place pipes with a BRPD via a camera console. (Attempted range exploit)") playsound(src, 'sound/machines/synth_no.ogg', 15, TRUE) to_chat(user, "ERROR: \The [T] is out of [src]'s range!") return + if(!(user in viewers(12, T))) // Checks if the user can see the target turf + to_chat(user, "[src] needs full visibility to determine the dispensing location.") + playsound(src, 'sound/machines/synth_no.ogg', 50, TRUE) + return + user.Beam(T, icon_state = "rped_upgrade", icon = 'icons/effects/effects.dmi', time = 0.5 SECONDS) T.rpd_act(user, src) /obj/item/rpd/attack_obj(obj/O, mob/living/user) diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 012ed2e4e148..2b0976e3af51 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -373,23 +373,23 @@ /obj/item/melee/baton/flayerprod/baton_stun(mob/living/L, mob/user, skip_cooldown, ignore_shield_check = FALSE) if(..()) disable_radio(L) - L.radio_enable_timer = addtimer(CALLBACK(src, PROC_REF(enable_radio), L), radio_disable_time, TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_STOPPABLE | TIMER_DELETE_ME) return TRUE return FALSE /obj/item/melee/baton/flayerprod/proc/disable_radio(mob/living/L) var/list/all_items = L.GetAllContents() for(var/obj/item/radio/R in all_items) + R.radio_enable_timer = addtimer(CALLBACK(src, PROC_REF(enable_radio), R), radio_disable_time, TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_STOPPABLE | TIMER_DELETE_ME) R.on = FALSE R.listening = FALSE R.broadcasting = FALSE L.visible_message("[R] buzzes loudly as it short circuits!", blind_message = "You hear a loud, electronic buzzing.") -/obj/item/melee/baton/flayerprod/proc/enable_radio(mob/living/L) - var/list/all_items = L.GetAllContents() - for(var/obj/item/radio/R in all_items) - R.on = TRUE - R.listening = TRUE +/obj/item/melee/baton/flayerprod/proc/enable_radio(obj/item/radio/R) + if(QDELETED(R)) + return + R.on = TRUE + R.listening = TRUE /obj/item/melee/baton/flayerprod/deductcharge(amount) if(cell.charge < hitcost) diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index e6921569f7b8..09cf587e2e8b 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -271,6 +271,7 @@ icon_state = "plant-eye" if(icon_state == "random_plant") icon_state = "plant-[rand(1, 34)]" + update_appearance(UPDATE_ICON_STATE) AddComponent(/datum/component/two_handed, require_twohands = TRUE) /obj/item/kirbyplants/Destroy() diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm index ab6b352db2c6..355dbfb687a8 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm @@ -78,7 +78,7 @@ if(istype(hugger_mask) && !hugger_mask.sterile && (locate(/obj/item/organ/internal/body_egg/alien_embryo) in buckled_mob.internal_organs)) if(user && !isalien(user)) return - buckled_mob.throw_alert("ghost_nest", /atom/movable/screen/alert/ghost) + buckled_mob.throw_alert("ghost_nest", /atom/movable/screen/alert/ghost/xeno) to_chat(buckled_mob, "You may now click on the ghost prompt on your screen to leave your body. You will be alerted when you're removed from the nest.") if(tgui_alert(buckled_mob, "You may now ghost and keep respawnability, you will be notified if you leave the nest, would you like to do so?", "Ghosting", list("Yes", "No")) != "Yes") return diff --git a/code/game/objects/structures/transit_tubes/transit_tube_construction.dm b/code/game/objects/structures/transit_tubes/transit_tube_construction.dm index 9836fb7343f4..0878ca196be4 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube_construction.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube_construction.dm @@ -9,6 +9,7 @@ var/installed_type = null var/installed_type_flipped = null var/flipped = FALSE + var/is_station = FALSE /obj/structure/transit_tube_construction/proc/rotate() setDir(turn(dir, -90)) @@ -43,20 +44,25 @@ . = TRUE var/turf/T = get_turf(src) if(!isfloorturf(T) && !isspaceturf(T)) - to_chat(user, "You cannot install [src] here.") + to_chat(user, "You cannot install [src] here.") return for(var/obj/turf_contents in T) // It's okay for tube parts to be installed over existing pods. if(!istype(turf_contents, /obj/structure/transit_tube_pod) && turf_contents.density) - to_chat(user, "There is not enough space to install [src] here.") + to_chat(user, "There is not enough space to install [src] here.") return + if(is_station && !user.can_reach(src)) + to_chat(user, "[src] must be installed manually.") + return var/install_type = flipped ? installed_type_flipped : installed_type var/atom/installed = new install_type(T) installed.dir = dir user.visible_message("[user] installs [src].") + I.play_tool_sound(src, I.tool_volume) qdel(src) + . |= RPD_TOOL_SUCCESS /obj/structure/transit_tube_construction/wrench_act(mob/living/user, obj/item/I) . = TRUE @@ -93,7 +99,7 @@ qdel(src) - to_chat(user, "[src] can only be installed in a transit tube!") + to_chat(user, "[src] can only be installed in a transit tube!") /obj/structure/transit_tube_construction/straight installed_type = /obj/structure/transit_tube @@ -121,14 +127,17 @@ installed_type = /obj/structure/transit_tube/station base_icon_state = "transit_station" icon_state = "transit_station" + is_station = TRUE /obj/structure/transit_tube_construction/terminus/dispenser installed_type = /obj/structure/transit_tube/station/dispenser/reverse installed_type_flipped = /obj/structure/transit_tube/station/dispenser/reverse/flipped base_icon_state = "transit_dispenser_terminus" icon_state = "transit_dispenser_terminus" + is_station = TRUE /obj/structure/transit_tube_construction/station/dispenser installed_type = /obj/structure/transit_tube/station/dispenser base_icon_state = "transit_dispenser_station" icon_state = "transit_dispenser_station" + is_station = TRUE diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm index 3d9e34d57062..fdba192ee859 100644 --- a/code/game/turfs/simulated/minerals.dm +++ b/code/game/turfs/simulated/minerals.dm @@ -20,37 +20,54 @@ color = COLOR_ROCK var/environment_type = "asteroid" var/turf/simulated/floor/plating/turf_type = /turf/simulated/floor/plating/asteroid/airless - var/mineralType = null - var/mineralAmt = 3 - var/spread = 0 //will the seam spread? - var/spreadChance = 0 //the percentile chance of an ore spreading to the neighboring tiles var/last_act = 0 - var/scan_state = "" //Holder for the image we display when we're pinged by a mining scanner + var/defer_change = 0 var/mine_time = 4 SECONDS //Changes how fast the turf is mined by pickaxes, multiplied by toolspeed /// Should this be set to the normal rock colour on init? var/should_reset_color = TRUE + /// The ore type, if any, that should spawn in the wall on Initialize. + /// Expected to be a subtype of [/datum/ore]. + var/preset_ore_type + /// The representation of the unmined ore in the wall, if any. + var/datum/ore/ore + /turf/simulated/mineral/Initialize(mapload) . = ..() + if(should_reset_color) color = COLOR_ROCK - if(mineralType && mineralAmt && spread && spreadChance) - for(var/dir in GLOB.cardinal) - if(prob(spreadChance)) - var/turf/T = get_step(src, dir) - if(istype(T, /turf/simulated/mineral/random)) - Spread(T) + if(preset_ore_type) + set_ore(preset_ore_type) + AddComponent(/datum/component/debris, DEBRIS_ROCK, -20, 10, 1) -/turf/simulated/mineral/proc/Spread(turf/T) - T.ChangeTurf(type) +/turf/simulated/mineral/proc/set_ore(ore_type) + if(!ore_type) + return + + if(ore) + qdel(ore) + + ore = new ore_type() + if(ore.spread_chance) + for(var/dir in GLOB.cardinal) + if(prob(ore.spread_chance)) + var/turf/simulated/mineral/T = get_step(src, dir) + if(istype(T)) + T.set_ore(ore_type) /turf/simulated/mineral/shuttleRotate(rotation) QUEUE_SMOOTH(src) /turf/simulated/mineral/attackby(obj/item/I, mob/user, params) + // TODO: Just sticking this here for now because attack chain refactor is coming later + // No point in threading this through everything right now + if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, I, user, params) & COMPONENT_NO_AFTERATTACK) + return + if(!user.IsAdvancedToolUser()) to_chat(usr, "You don't have the dexterity to do this!") return @@ -75,13 +92,19 @@ else return attack_hand(user) -/turf/simulated/mineral/proc/gets_drilled() - if(mineralType && (mineralAmt > 0)) - new mineralType(src, mineralAmt) - SSticker.score?.score_ore_mined++ - SSblackbox.record_feedback("tally", "ore_mined", mineralAmt, mineralType) +/turf/simulated/mineral/proc/mine_ore(mob/user, triggered_by_explosion) + if(!ore) + return MINERAL_ALLOW_DIG + for(var/obj/effect/temp_visual/mining_overlay/M in src) qdel(M) + + return ore.on_mine(src, user, triggered_by_explosion) + +/turf/simulated/mineral/proc/gets_drilled(mob/user, triggered_by_explosion = FALSE) + if(mine_ore(user, triggered_by_explosion) == MINERAL_PREVENT_DIG) + return + ChangeTurf(turf_type, defer_change) addtimer(CALLBACK(src, PROC_REF(AfterChange)), 1, TIMER_UNIQUE) playsound(src, 'sound/effects/break_stone.ogg', 50, 1) //beautiful destruction @@ -135,29 +158,27 @@ gets_drilled(null, 1) /turf/simulated/mineral/random - var/mineralSpawnChanceList = list(/turf/simulated/mineral/uranium = 5, /turf/simulated/mineral/diamond = 1, /turf/simulated/mineral/gold = 10, - /turf/simulated/mineral/silver = 12, /turf/simulated/mineral/plasma = 20, /turf/simulated/mineral/iron = 40, /turf/simulated/mineral/titanium = 11, - /turf/simulated/mineral/gibtonite = 4, /turf/simulated/mineral/bscrystal = 1) - //Currently, Adamantine won't spawn as it has no uses. -Durandan - var/mineralChance = 13 + var/mineralSpawnChanceList = list( + /datum/ore/iron = 40, + /datum/ore/plasma = 20, + /datum/ore/silver = 12, + /datum/ore/titanium = 11, + /datum/ore/gold = 10, + /datum/ore/uranium = 5, + /datum/ore/gibtonite = 4, + /datum/ore/bluespace = 1, + /datum/ore/diamond = 1, + ) + + var/mineralChance = 10 /turf/simulated/mineral/random/Initialize(mapload) + . = ..() mineralSpawnChanceList = typelist("mineralSpawnChanceList", mineralSpawnChanceList) - - . = ..() if(prob(mineralChance)) - var/path = pickweight(mineralSpawnChanceList) - var/turf/T = ChangeTurf(path, FALSE, TRUE, TRUE) - - if(T && ismineralturf(T)) - var/turf/simulated/mineral/M = T - M.mineralAmt = rand(1, 5) - M.environment_type = environment_type - M.turf_type = turf_type - M.baseturf = baseturf - src = M - M.levelupdate() + var/new_ore_type = pickweight(mineralSpawnChanceList) + set_ore(new_ore_type) /turf/simulated/mineral/ancient name = "ancient rock" @@ -169,8 +190,6 @@ layer = MAP_EDITOR_TURF_LAYER real_layer = TURF_LAYER should_reset_color = FALSE - mineralAmt = 2 - mineralType = /obj/item/stack/ore/glass/basalt/ancient baseturf = /turf/simulated/floor/plating/asteroid/ancient /turf/simulated/mineral/ancient/attackby(obj/item/I, mob/user, params) @@ -269,14 +288,27 @@ color = COLOR_YELLOW mineralChance = 25 mineralSpawnChanceList = list( - /turf/simulated/mineral/uranium = 35, /turf/simulated/mineral/diamond = 30, /turf/simulated/mineral/gold = 45, /turf/simulated/mineral/titanium = 45, - /turf/simulated/mineral/silver = 50, /turf/simulated/mineral/plasma = 50, /turf/simulated/mineral/bscrystal = 20) + /datum/ore/silver = 50, + /datum/ore/plasma = 50, + /datum/ore/gold = 45, + /datum/ore/titanium = 45, + /datum/ore/uranium = 35, + /datum/ore/diamond = 30, + /datum/ore/bluespace = 20, + ) /turf/simulated/mineral/random/high_chance/clown mineralChance = 40 mineralSpawnChanceList = list( - /turf/simulated/mineral/uranium = 35, /turf/simulated/mineral/diamond = 2, /turf/simulated/mineral/gold = 5, /turf/simulated/mineral/silver = 5, - /turf/simulated/mineral/iron = 30, /turf/simulated/mineral/clown = 15, /turf/simulated/mineral/mime = 15, /turf/simulated/mineral/bscrystal = 10) + /datum/ore/uranium = 35, + /datum/ore/iron = 30, + /datum/ore/bananium = 15, + /datum/ore/tranquillite = 15, + /datum/ore/bluespace = 10, + /datum/ore/gold = 5, + /datum/ore/silver = 5, + /datum/ore/diamond = 2, + ) /turf/simulated/mineral/random/high_chance/volcanic environment_type = "basalt" @@ -289,16 +321,29 @@ atmos_environment = ENVIRONMENT_LAVALAND defer_change = 1 mineralSpawnChanceList = list( - /turf/simulated/mineral/uranium/volcanic = 35, /turf/simulated/mineral/diamond/volcanic = 30, /turf/simulated/mineral/gold/volcanic = 45, /turf/simulated/mineral/titanium/volcanic = 45, - /turf/simulated/mineral/silver/volcanic = 50, /turf/simulated/mineral/plasma/volcanic = 50, /turf/simulated/mineral/bscrystal/volcanic = 20) + /datum/ore/silver = 50, + /datum/ore/plasma = 50, + /datum/ore/gold = 45, + /datum/ore/titanium = 45, + /datum/ore/uranium = 35, + /datum/ore/diamond = 30, + /datum/ore/bluespace = 20, + ) /turf/simulated/mineral/random/low_chance color = COLOR_VIOLET mineralChance = 6 mineralSpawnChanceList = list( - /turf/simulated/mineral/uranium = 2, /turf/simulated/mineral/diamond = 1, /turf/simulated/mineral/gold = 4, /turf/simulated/mineral/titanium = 4, - /turf/simulated/mineral/silver = 6, /turf/simulated/mineral/plasma = 15, /turf/simulated/mineral/iron = 40, - /turf/simulated/mineral/gibtonite = 2, /turf/simulated/mineral/bscrystal = 1) + /datum/ore/iron = 40, + /datum/ore/plasma = 15, + /datum/ore/silver = 6, + /datum/ore/gold = 4, + /datum/ore/titanium = 4, + /datum/ore/gibtonite = 2, + /datum/ore/uranium = 2, + /datum/ore/diamond = 1, + /datum/ore/bluespace = 1, + ) /turf/simulated/mineral/random/volcanic environment_type = "basalt" @@ -311,204 +356,37 @@ atmos_environment = ENVIRONMENT_LAVALAND defer_change = 1 - mineralChance = 10 - mineralSpawnChanceList = list( - /turf/simulated/mineral/uranium/volcanic = 5, - /turf/simulated/mineral/diamond/volcanic = 1, - /turf/simulated/mineral/gold/volcanic = 10, - /turf/simulated/mineral/titanium/volcanic = 11, - /turf/simulated/mineral/silver/volcanic = 12, - /turf/simulated/mineral/plasma/volcanic = 20, - /turf/simulated/mineral/iron/volcanic = 40, - /turf/simulated/mineral/gibtonite/volcanic = 4, - /turf/simulated/mineral/bscrystal/volcanic = 1 - ) - /turf/simulated/mineral/random/labormineral mineralSpawnChanceList = list( - /turf/simulated/mineral/uranium = 3, /turf/simulated/mineral/diamond = 1, /turf/simulated/mineral/gold = 8, /turf/simulated/mineral/titanium = 8, - /turf/simulated/mineral/silver = 20, /turf/simulated/mineral/plasma = 30, /turf/simulated/mineral/iron = 95, - /turf/simulated/mineral/gibtonite = 2) + /datum/ore/iron = 95, + /datum/ore/plasma = 30, + /datum/ore/silver = 20, + /datum/ore/gold = 8, + /datum/ore/titanium = 8, + /datum/ore/uranium = 3, + /datum/ore/gibtonite = 2, + /datum/ore/diamond = 1, + ) color = COLOR_MAROON -/turf/simulated/mineral/random/labormineral/volcanic - environment_type = "basalt" - turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - baseturf = /turf/simulated/floor/lava/mapping_lava - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - defer_change = 1 +/turf/simulated/mineral/random/volcanic/labormineral mineralSpawnChanceList = list( - /turf/simulated/mineral/uranium/volcanic = 3, /turf/simulated/mineral/diamond/volcanic = 1, /turf/simulated/mineral/gold/volcanic = 8, /turf/simulated/mineral/titanium/volcanic = 8, - /turf/simulated/mineral/silver/volcanic = 20, /turf/simulated/mineral/plasma/volcanic = 30, /turf/simulated/mineral/bscrystal/volcanic = 1, /turf/simulated/mineral/gibtonite/volcanic = 2, - /turf/simulated/mineral/iron/volcanic = 95) + /datum/ore/iron = 95, + /datum/ore/plasma = 30, + /datum/ore/silver = 20, + /datum/ore/titanium = 8, + /datum/ore/gold = 8, + /datum/ore/uranium = 3, + /datum/ore/gibtonite = 2, + /datum/ore/bluespace = 1, + /datum/ore/diamond = 1, + ) // Actual minerals -/turf/simulated/mineral/iron - mineralType = /obj/item/stack/ore/iron - spreadChance = 20 - spread = 1 - scan_state = "rock_Iron" - -/turf/simulated/mineral/iron/volcanic - environment_type = "basalt" - turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - baseturf = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - defer_change = 1 - -/turf/simulated/mineral/uranium - mineralType = /obj/item/stack/ore/uranium - spreadChance = 5 - spread = 1 - scan_state = "rock_Uranium" - -/turf/simulated/mineral/uranium/volcanic - environment_type = "basalt" - turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - baseturf = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - defer_change = 1 - -/turf/simulated/mineral/diamond - mineralType = /obj/item/stack/ore/diamond - spreadChance = 0 - spread = 1 - scan_state = "rock_Diamond" - -/turf/simulated/mineral/diamond/volcanic - environment_type = "basalt" - turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - baseturf = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - defer_change = 1 - -/turf/simulated/mineral/gold - mineralType = /obj/item/stack/ore/gold - spreadChance = 5 - spread = 1 - scan_state = "rock_Gold" - -/turf/simulated/mineral/gold/volcanic - environment_type = "basalt" - turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - baseturf = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - defer_change = 1 - -/turf/simulated/mineral/silver - mineralType = /obj/item/stack/ore/silver - spreadChance = 5 - spread = 1 - scan_state = "rock_Silver" - -/turf/simulated/mineral/silver/volcanic - environment_type = "basalt" - turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - baseturf = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - defer_change = 1 - -/turf/simulated/mineral/titanium - mineralType = /obj/item/stack/ore/titanium - spreadChance = 5 - spread = 1 - scan_state = "rock_Titanium" - -/turf/simulated/mineral/titanium/volcanic - environment_type = "basalt" - turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - baseturf = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - defer_change = 1 - -/turf/simulated/mineral/plasma - mineralType = /obj/item/stack/ore/plasma - spreadChance = 8 - spread = 1 - scan_state = "rock_Plasma" - -/turf/simulated/mineral/plasma/volcanic - environment_type = "basalt" - turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - baseturf = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - defer_change = 1 - /turf/simulated/mineral/clown - mineralType = /obj/item/stack/ore/bananium - mineralAmt = 3 - spreadChance = 0 - spread = 0 - scan_state = "rock_Clown" - -/turf/simulated/mineral/clown/volcanic - environment_type = "basalt" - turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - baseturf = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - defer_change = 1 + preset_ore_type = /datum/ore/bananium -/turf/simulated/mineral/mime - mineralType = /obj/item/stack/ore/tranquillite - mineralAmt = 3 - spreadChance = 0 - spread = 0 - -/turf/simulated/mineral/mime/volcanic - environment_type = "basalt" - turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - baseturf = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - defer_change = 1 - -/turf/simulated/mineral/bscrystal - mineralType = /obj/item/stack/ore/bluespace_crystal - mineralAmt = 1 - spreadChance = 0 - spread = 0 - scan_state = "rock_BScrystal" - -/turf/simulated/mineral/bscrystal/volcanic +/turf/simulated/mineral/volcanic environment_type = "basalt" turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface baseturf = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface @@ -519,135 +397,11 @@ atmos_environment = ENVIRONMENT_LAVALAND defer_change = 1 -/turf/simulated/mineral/volcanic - environment_type = "basalt" - turf_type = /turf/simulated/floor/plating/asteroid/basalt - baseturf = /turf/simulated/floor/plating/asteroid/basalt - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND +/turf/simulated/mineral/volcanic/clown + preset_ore_type = /datum/ore/bananium /turf/simulated/mineral/volcanic/lava_land_surface environment_type = "basalt" turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface baseturf = /turf/simulated/floor/lava/mapping_lava defer_change = 1 - -//gibtonite state defines -#define GIBTONITE_UNSTRUCK 0 -#define GIBTONITE_ACTIVE 1 -#define GIBTONITE_STABLE 2 -#define GIBTONITE_DETONATE 3 - -// Gibtonite -/turf/simulated/mineral/gibtonite - mineralAmt = 1 - spreadChance = 0 - spread = 0 - scan_state = "rock_Gibtonite" - var/det_time = 8 //Countdown till explosion, but also rewards the player for how close you were to detonation when you defuse it - var/stage = GIBTONITE_UNSTRUCK //How far into the lifecycle of gibtonite we are - var/activated_ckey = null //These are to track who triggered the gibtonite deposit for logging purposes - var/activated_name = null - var/mutable_appearance/activated_overlay - -/turf/simulated/mineral/gibtonite/Initialize(mapload) - det_time = rand(8,10) //So you don't know exactly when the hot potato will explode - . = ..() - -/turf/simulated/mineral/gibtonite/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/mining_scanner) || istype(I, /obj/item/t_scanner/adv_mining_scanner) && stage == 1) - user.visible_message("[user] holds [I] to [src]...", "You use [I] to locate where to cut off the chain reaction and attempt to stop it...") - defuse() - else - return ..() - -/turf/simulated/mineral/gibtonite/proc/explosive_reaction(mob/user = null, triggered_by_explosion = 0) - if(stage == GIBTONITE_UNSTRUCK) - activated_overlay = mutable_appearance(icon, "rock_Gibtonite_active", ON_EDGED_TURF_LAYER) - add_overlay(activated_overlay) - name = "gibtonite deposit" - desc = "An active gibtonite reserve. Run!" - stage = GIBTONITE_ACTIVE - visible_message("There was gibtonite inside! It's going to explode!") - var/turf/bombturf = get_turf(src) - var/area/A = get_area(bombturf) - - var/notify_admins = 0 - if(!is_mining_level(z)) - notify_admins = 1 - if(!triggered_by_explosion) - message_admins("[key_name_admin(user)] has triggered a gibtonite deposit reaction at [A.name] (JMP).") - else - message_admins("An explosion has triggered a gibtonite deposit reaction at [A.name] (JMP).") - - if(!triggered_by_explosion) - log_game("[key_name(user)] has triggered a gibtonite deposit reaction at [A.name] ([A.x], [A.y], [A.z]).") - else - log_game("An explosion has triggered a gibtonite deposit reaction at [A.name]([bombturf.x],[bombturf.y],[bombturf.z])") - - countdown(notify_admins) - -/turf/simulated/mineral/gibtonite/proc/countdown(notify_admins = 0) - set waitfor = 0 - while(istype(src, /turf/simulated/mineral/gibtonite) && stage == GIBTONITE_ACTIVE && det_time > 0 && mineralAmt >= 1) - det_time-- - sleep(5) - if(istype(src, /turf/simulated/mineral/gibtonite)) - if(stage == GIBTONITE_ACTIVE && det_time <= 0 && mineralAmt >= 1) - var/turf/bombturf = get_turf(src) - mineralAmt = 0 - stage = GIBTONITE_DETONATE - explosion(bombturf, 1, 3, 5, adminlog = notify_admins) - -/turf/simulated/mineral/gibtonite/proc/defuse() - if(stage == GIBTONITE_ACTIVE) - cut_overlay(activated_overlay) - activated_overlay.icon_state = "rock_Gibtonite_inactive" - add_overlay(activated_overlay) - desc = "An inactive gibtonite reserve. The ore can be extracted." - stage = GIBTONITE_STABLE - if(det_time < 0) - det_time = 0 - visible_message("The chain reaction was stopped! The gibtonite had [det_time] reactions left till the explosion!") - -/turf/simulated/mineral/gibtonite/gets_drilled(mob/user, triggered_by_explosion = 0) - if(stage == GIBTONITE_UNSTRUCK && mineralAmt >= 1) //Gibtonite deposit is activated - playsound(src,'sound/effects/hit_on_shattered_glass.ogg', 50, TRUE) - explosive_reaction(user, triggered_by_explosion) - return - if(stage == GIBTONITE_ACTIVE && mineralAmt >= 1) //Gibtonite deposit goes kaboom - var/turf/bombturf = get_turf(src) - mineralAmt = 0 - stage = GIBTONITE_DETONATE - explosion(bombturf,1,2,5, adminlog = 0) - if(stage == GIBTONITE_STABLE) //Gibtonite deposit is now benign and extractable. Depending on how close you were to it blowing up before defusing, you get better quality ore. - var/obj/item/gibtonite/G = new(src) - if(det_time <= 0) - G.quality = 3 - G.icon_state = "Gibtonite ore 3" - if(det_time >= 1 && det_time <= 2) - G.quality = 2 - G.icon_state = "Gibtonite ore 2" - - ChangeTurf(turf_type, defer_change) - addtimer(CALLBACK(src, PROC_REF(AfterChange)), 1, TIMER_UNIQUE) - - -/turf/simulated/mineral/gibtonite/volcanic - environment_type = "basalt" - turf_type = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - baseturf = /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface - oxygen = LAVALAND_OXYGEN - nitrogen = LAVALAND_NITROGEN - temperature = LAVALAND_TEMPERATURE - atmos_mode = ATMOS_MODE_EXPOSED_TO_ENVIRONMENT - atmos_environment = ENVIRONMENT_LAVALAND - defer_change = 1 - -#undef GIBTONITE_UNSTRUCK -#undef GIBTONITE_ACTIVE -#undef GIBTONITE_STABLE -#undef GIBTONITE_DETONATE diff --git a/code/game/turfs/simulated/river.dm b/code/game/turfs/simulated/river.dm index 7c9034b9ea5c..384f75a953fd 100644 --- a/code/game/turfs/simulated/river.dm +++ b/code/game/turfs/simulated/river.dm @@ -4,6 +4,8 @@ #define RIVER_MIN_X 50 #define RIVER_MIN_Y 50 +GLOBAL_LIST_EMPTY(river_waypoint_presets) + /obj/effect/landmark/river_waypoint name = "river waypoint" /// Whether the turf of this landmark has already been linked to others during river generation. @@ -43,15 +45,22 @@ /datum/river_spawner/proc/generate(nodes = 4, min_x = RIVER_MIN_X, min_y = RIVER_MIN_Y, max_x = RIVER_MAX_X, max_y = RIVER_MAX_Y) var/list/river_nodes = list() var/num_spawned = 0 + var/list/possible_locs = block(min_x, min_y, target_z, max_x, max_y, target_z) while(num_spawned < nodes && length(possible_locs)) - var/turf/T = pick(possible_locs) - var/area/A = get_area(T) - if(!istype(A, whitelist_area_type) || (T.flags & NO_LAVA_GEN)) - possible_locs -= T - else - river_nodes += new /obj/effect/landmark/river_waypoint(T) + // Random chance of pulling a pre-mapped river waypoint instead. + if(length(GLOB.river_waypoint_presets) && prob(50)) + var/obj/effect/landmark/river_waypoint/waypoint = pick_n_take(GLOB.river_waypoint_presets) + river_nodes += waypoint num_spawned++ + else + var/turf/T = pick(possible_locs) + var/area/A = get_area(T) + if(!istype(A, whitelist_area_type) || (T.flags & NO_LAVA_GEN)) + possible_locs -= T + else + river_nodes += new /obj/effect/landmark/river_waypoint(T) + num_spawned++ //make some randomly pathing rivers for(var/A in river_nodes) @@ -60,7 +69,8 @@ continue W.connected = TRUE var/turf/cur_turf = get_turf(W) - cur_turf.ChangeTurf(river_turf_type, ignore_air = TRUE) + if(istype(get_area(cur_turf), whitelist_area_type) && !(cur_turf.flags & NO_LAVA_GEN)) + cur_turf.ChangeTurf(river_turf_type, ignore_air = TRUE) var/turf/target_turf = get_turf(pick(river_nodes - W)) if(!target_turf) break diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm index 2c37ec951b8b..51648d390449 100644 --- a/code/modules/antagonists/_common/antag_spawner.dm +++ b/code/modules/antagonists/_common/antag_spawner.dm @@ -398,7 +398,7 @@ /obj/item/antag_spawner/pulse_demon name = "living lightbulb" - desc = "A magically sealed lightbulb confining some manner of electricity based creature." + desc = "A magically sealed lightbulb confining some manner of electricity based creature. It is *heavily* advised not to summon it in maintenance areas." icon = 'icons/obj/lighting.dmi' icon_state = "lbulb" var/shatter_msg = "You shatter the bulb, no turning back now!" @@ -422,7 +422,7 @@ return used = TRUE - to_chat(user, "You break the seal on the bulb, waiting for the creature to spark to life...") + to_chat(user, "You break the seal on the bulb, waiting for the creature to spark to life... you might wish to get to safety!") var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a pulse demon summoned by [user.real_name]?", ROLE_DEMON, TRUE, 10 SECONDS, source = demon_type) diff --git a/code/modules/atmospherics/machinery/atmospherics.dm b/code/modules/atmospherics/machinery/atmospherics.dm index 21f7103bab23..44bff7a7d017 100644 --- a/code/modules/atmospherics/machinery/atmospherics.dm +++ b/code/modules/atmospherics/machinery/atmospherics.dm @@ -101,8 +101,8 @@ Pipelines + Other Objects -> Pipe network plane = GAME_PLANE layer = GAS_PIPE_VISIBLE_LAYER + layer_offset -/obj/machinery/atmospherics/proc/update_pipe_image() - pipe_image = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) //the 20 puts it above Byond's darkness (not its opacity view) +/obj/machinery/atmospherics/proc/update_pipe_image(overlay = src) + pipe_image = image(overlay, loc, layer = ABOVE_HUD_LAYER, dir = dir) //the 20 puts it above Byond's darkness (not its opacity view) pipe_image.plane = HUD_PLANE /obj/machinery/atmospherics/proc/check_icon_cache() @@ -322,6 +322,7 @@ Pipelines + Other Objects -> Pipe network // Ventcrawling #define VENT_SOUND_DELAY 30 /obj/machinery/atmospherics/relaymove(mob/living/user, direction) + var/datum/pipeline/current_pipenet = returnPipenet(src) direction &= initialize_directions if(!direction || !(direction in GLOB.cardinal)) //cant go this way. return @@ -332,6 +333,7 @@ Pipelines + Other Objects -> Pipe network var/obj/machinery/atmospherics/target_move = findConnecting(direction) if(target_move) if(is_type_in_list(target_move, GLOB.ventcrawl_machinery) && target_move.can_crawl_through()) + current_pipenet.crawlers -= user user.remove_ventcrawl() user.forceMove(target_move.loc) //handles entering and so on user.visible_message("You hear something squeezing through the ducts.", "You climb out of the ventilation system.") @@ -344,6 +346,7 @@ Pipelines + Other Objects -> Pipe network playsound(src, 'sound/machines/ventcrawl.ogg', 50, TRUE, -3) else if((direction & initialize_directions) || is_type_in_list(src, GLOB.ventcrawl_machinery)) //if we move in a way the pipe can connect, but doesn't - or we're in a vent + current_pipenet.crawlers -= user user.remove_ventcrawl() user.forceMove(loc) user.visible_message("You hear something squeezing through the pipes.", "You climb out of the ventilation system.") diff --git a/code/modules/atmospherics/machinery/components/unary_devices/unary_base.dm b/code/modules/atmospherics/machinery/components/unary_devices/unary_base.dm index 293538e76e12..a831588f4014 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/unary_base.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/unary_base.dm @@ -50,6 +50,13 @@ build_network() . = 1 +/obj/machinery/atmospherics/unary/update_pipe_image() + . = ..() + if(parent) + for(var/mob/crawler in parent.crawlers) + var/mob/living/current_crawler = crawler + current_crawler.update_pipe_vision(src) + /obj/machinery/atmospherics/unary/build_network(remove_deferral = FALSE) if(!parent) parent = new /datum/pipeline() 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 e252d7598b6a..12e3d2bf01a4 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -88,8 +88,7 @@ vent_icon += "[on ? "[releasing ? "out" : "in"]" : "off"]" . += GLOB.pipe_icon_manager.get_atmos_icon("device", state = vent_icon) - - update_pipe_image() + update_pipe_image(.) /obj/machinery/atmospherics/unary/vent_pump/update_underlays() if(..()) 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 5ba4847cf80a..3066b5308b01 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -83,7 +83,7 @@ scrubber_icon = "scrubberweld" . += GLOB.pipe_icon_manager.get_atmos_icon("device", state = scrubber_icon) - update_pipe_image() + update_pipe_image(.) /obj/machinery/atmospherics/unary/vent_scrubber/update_underlays() if(..()) diff --git a/code/modules/atmospherics/machinery/datum_pipeline.dm b/code/modules/atmospherics/machinery/datum_pipeline.dm index d55f9da5e81c..fb77f74cc462 100644 --- a/code/modules/atmospherics/machinery/datum_pipeline.dm +++ b/code/modules/atmospherics/machinery/datum_pipeline.dm @@ -7,6 +7,8 @@ var/update = TRUE + var/list/crawlers = list() + /datum/pipeline/New() SSair.pipenets += src @@ -220,3 +222,12 @@ GL += C.portableConnectorReturnAir() share_many_airs(GL) + +/datum/pipeline/proc/add_ventcrawler(mob/living/crawler) + if(!(crawler in crawlers)) + RegisterSignal(crawler, COMSIG_LIVING_EXIT_VENTCRAWL, PROC_REF(remove_ventcrawler), crawler) + crawlers += crawler + +/datum/pipeline/proc/remove_ventcrawler(mob/living/crawler) + UnregisterSignal(crawler, COMSIG_LIVING_EXIT_VENTCRAWL) + crawlers -= crawler diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index b4df1a7be771..3fdcf020870a 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -341,11 +341,12 @@ return var/atom/target = get_edge_target_turf(user, user.dir) //gets the user's direction + ADD_TRAIT(user, TRAIT_FLYING, "gravity_boots") if(user.throw_at(target, jumpdistance, jumpspeed, spin = FALSE, diagonals_first = TRUE, callback = CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(callback_remove_trait), user, TRAIT_FLYING, "gravity_boots"))) - ADD_TRAIT(user, TRAIT_FLYING, "gravity_boots") playsound(src, 'sound/effects/stealthoff.ogg', 50, TRUE, 1) user.visible_message("[usr] dashes forward into the air!") recharging_time = world.time + recharging_rate cell.use(dash_cost) else + REMOVE_TRAIT(user, TRAIT_FLYING, "gravity_boots") to_chat(user, "Something prevents you from dashing forward!") diff --git a/code/modules/clothing/shoes/misc_shoes.dm b/code/modules/clothing/shoes/misc_shoes.dm index eb4cb5436ab5..5ce6c2dff669 100644 --- a/code/modules/clothing/shoes/misc_shoes.dm +++ b/code/modules/clothing/shoes/misc_shoes.dm @@ -472,12 +472,13 @@ return var/atom/target = get_edge_target_turf(user, user.dir) //gets the user's direction + ADD_TRAIT(user, TRAIT_FLYING, "bhop_shoes") if(user.throw_at(target, jumpdistance, jumpspeed, spin = FALSE, diagonals_first = TRUE, callback = CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(callback_remove_trait), user, TRAIT_FLYING, "bhop_shoes"))) - ADD_TRAIT(user, TRAIT_FLYING, "bhop_shoes") playsound(src, 'sound/effects/stealthoff.ogg', 50, TRUE, 1) user.visible_message("[usr] dashes forward into the air!") recharging_time = world.time + recharging_rate else + REMOVE_TRAIT(user, TRAIT_FLYING, "bhop_shoes") to_chat(user, "Something prevents you from dashing forward!") /obj/item/clothing/shoes/ducky diff --git a/code/modules/lavaland/caves_theme.dm b/code/modules/lavaland/caves_theme.dm index 6a47985fcf41..2b69cfd5ee1f 100644 --- a/code/modules/lavaland/caves_theme.dm +++ b/code/modules/lavaland/caves_theme.dm @@ -137,7 +137,7 @@ GLOBAL_LIST_INIT(caves_default_flora_spawns, list( perlin_upper_range = 0.3 /datum/caves_theme/burrows/on_change(turf/T) - if(prob(9)) + if(prob(7)) new /obj/structure/flora/ash/rock/style_random(T) else if(prob(5)) lavaland_caves_spawn_flora(T) diff --git a/code/modules/mapping/mapping_helpers.dm b/code/modules/mapping/mapping_helpers.dm index ce504e0e2f04..275bfea1921c 100644 --- a/code/modules/mapping/mapping_helpers.dm +++ b/code/modules/mapping/mapping_helpers.dm @@ -77,6 +77,19 @@ T.flags |= NO_LAVA_GEN ..() +/obj/effect/mapping_helpers/lava_magnet + name = "lava magnet" + icon_state = "lava_magnet" + layer = ON_EDGED_TURF_LAYER + +/obj/effect/mapping_helpers/lava_magnet/New() + . = ..() + + var/turf/T = get_turf(src) + if(istype(T) && T.z == level_name_to_num(MINING)) + var/obj/effect/landmark/river_waypoint/waypoint = new(T) + GLOB.river_waypoint_presets += waypoint + /obj/effect/mapping_helpers/airlock layer = DOOR_HELPER_LAYER late = TRUE diff --git a/code/modules/mining/equipment/mineral_scanner.dm b/code/modules/mining/equipment/mineral_scanner.dm index e610361bdd67..77b915f94272 100644 --- a/code/modules/mining/equipment/mineral_scanner.dm +++ b/code/modules/mining/equipment/mineral_scanner.dm @@ -26,8 +26,8 @@ /obj/item/mining_scanner/admin/attack_self(mob/user) for(var/turf/simulated/mineral/M in world) - if(M.scan_state) - M.icon_state = M.scan_state + if(M.ore?.scan_icon_state) + M.icon_state = M.ore.scan_icon_state qdel(src) /obj/item/t_scanner/adv_mining_scanner @@ -61,7 +61,7 @@ /proc/mineral_scan_pulse(turf/T, range = world.view) var/list/minerals = list() for(var/turf/simulated/mineral/M in range(range, T)) - if(M.scan_state) + if(M.ore?.scan_icon_state) minerals += M if(LAZYLEN(minerals)) for(var/turf/simulated/mineral/M in minerals) @@ -69,7 +69,7 @@ if(oldC) qdel(oldC) var/obj/effect/temp_visual/mining_overlay/C = new /obj/effect/temp_visual/mining_overlay(M) - C.icon_state = M.scan_state + C.icon_state = M.ore.scan_icon_state /obj/effect/temp_visual/mining_overlay plane = FULLSCREEN_PLANE diff --git a/code/modules/mining/equipment/mining_charges.dm b/code/modules/mining/equipment/mining_charges.dm index 6a1c104327a4..74454a4b4ab8 100644 --- a/code/modules/mining/equipment/mining_charges.dm +++ b/code/modules/mining/equipment/mining_charges.dm @@ -82,8 +82,10 @@ for(var/turf/simulated/mineral/rock in circlerangeturfs(location, boom_sizes[3])) var/distance = get_dist_euclidian(location, rock) if(distance <= boom_sizes[3]) - rock.mineralAmt += 3 // if rock is going to get drilled, add bonus mineral amount - rock.gets_drilled() + if(rock.ore) + rock.ore.drop_max += 3 // if rock is going to get drilled, add bonus mineral amount + rock.ore.drop_min += 3 + rock.gets_drilled(triggered_by_explosion = TRUE) for(var/mob/living/carbon/C in circlerange(location, boom_sizes[3])) var/distance = get_dist_euclidian(location, C) C.flash_eyes() diff --git a/code/modules/mob/living/carbon/carbon_procs.dm b/code/modules/mob/living/carbon/carbon_procs.dm index 7c3a1a2e86c3..6724f788eb7b 100644 --- a/code/modules/mob/living/carbon/carbon_procs.dm +++ b/code/modules/mob/living/carbon/carbon_procs.dm @@ -539,10 +539,15 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven /mob/living/proc/add_ventcrawl(obj/machinery/atmospherics/starting_machine, obj/machinery/atmospherics/target_move) if(!istype(starting_machine) || !starting_machine.returnPipenet(target_move) || !starting_machine.can_see_pipes()) return - var/datum/pipeline/pipeline = starting_machine.returnPipenet(target_move) + var/datum/pipeline/pipenet = starting_machine.returnPipenet(target_move) + pipenet.add_ventcrawler(src) + add_ventcrawl_images(pipenet) + + +/mob/living/proc/add_ventcrawl_images(datum/pipeline/pipenet) var/list/totalMembers = list() - totalMembers |= pipeline.members - totalMembers |= pipeline.other_atmosmch + totalMembers |= pipenet.members + totalMembers |= pipenet.other_atmosmch for(var/obj/machinery/atmospherics/A in totalMembers) if(!A.pipe_image) A.update_pipe_image() @@ -551,6 +556,10 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven client.images += A.pipe_image /mob/living/proc/remove_ventcrawl() + SEND_SIGNAL(src, COMSIG_LIVING_EXIT_VENTCRAWL) + remove_ventcrawl_images() + +/mob/living/proc/remove_ventcrawl_images() if(client) for(var/image/current_image in pipes_shown) client.images -= current_image @@ -572,8 +581,10 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven else if(is_ventcrawling(src)) if(target_move) - remove_ventcrawl() - add_ventcrawl(loc, target_move) + remove_ventcrawl_images() + var/obj/machinery/atmospherics/current_pipe = loc + var/datum/pipeline/pipenet = current_pipe.returnPipenet(target_move) + add_ventcrawl_images(pipenet) //Throwing stuff diff --git a/code/modules/mob/living/default_language.dm b/code/modules/mob/living/default_language.dm index 82f1ffc2ceb0..06bc251fe9e2 100644 --- a/code/modules/mob/living/default_language.dm +++ b/code/modules/mob/living/default_language.dm @@ -2,7 +2,7 @@ set name = "Set Default Language" set category = "IC" - if(!(language in languages)) + if(!(language in languages) && !isnull(language)) to_chat(src, "You don't seem to know how to speak [language].") return if(language) @@ -16,7 +16,7 @@ set name = "Set Default Language" set category = "IC" - if(!(language in speech_synthesizer_langs)) + if(!(language in speech_synthesizer_langs) && !isnull(language)) to_chat(src, "You don't seem to know how to speak [language].") return if(language) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 36acc6b64077..8bccc0b57c25 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -117,6 +117,3 @@ var/last_taste_text ///If a creature gets to be super special and have extra range on their chat messages var/extra_message_range = 0 - - /// A timer that, when going off, will enable all the mob's radios again - var/radio_enable_timer diff --git a/code/modules/mob/living/simple_animal/corpse.dm b/code/modules/mob/living/simple_animal/corpse.dm index b70492d567a0..78496dbe6117 100644 --- a/code/modules/mob/living/simple_animal/corpse.dm +++ b/code/modules/mob/living/simple_animal/corpse.dm @@ -102,9 +102,9 @@ /datum/outfit/sovietcorpse name = "Corpse of a Soviet" - uniform = /obj/item/clothing/under/costume/soviet + uniform = /obj/item/clothing/under/new_soviet shoes = /obj/item/clothing/shoes/jackboots - head = /obj/item/clothing/head/bearpelt + head = /obj/item/clothing/head/sovietsidecap /obj/effect/mob_spawn/human/corpse/soviet/ranged @@ -112,7 +112,7 @@ /datum/outfit/sovietcorpse/ranged name = "Corpse of a Ranged Soviet" - head = /obj/item/clothing/head/ushanka + suit = /obj/item/clothing/suit/sovietcoat /obj/effect/mob_spawn/human/corpse/wizard diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 5655085d2aa9..c1dcedd9158c 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -792,6 +792,12 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \ src:cameraFollow = null /mob/Topic(href, href_list) + if(href_list["flavor_more"]) + usr << browse(text("