diff --git a/_maps/RandomRuins/IceRuins/skyrat/icemoon_underground_syndicate_base1_skyrat.dmm b/_maps/RandomRuins/IceRuins/skyrat/icemoon_underground_syndicate_base1_skyrat.dmm index 4bb06861e10..0330ddf8031 100644 --- a/_maps/RandomRuins/IceRuins/skyrat/icemoon_underground_syndicate_base1_skyrat.dmm +++ b/_maps/RandomRuins/IceRuins/skyrat/icemoon_underground_syndicate_base1_skyrat.dmm @@ -872,7 +872,7 @@ /area/ruin/syndicate_lava_base/cargo) "gp" = ( /obj/machinery/light/floor, -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/medbay) "gs" = ( diff --git a/_maps/RandomRuins/LavaRuins/lavaland_strong_rock.dmm b/_maps/RandomRuins/LavaRuins/lavaland_strong_rock.dmm index f236a25a6a0..ad90df10167 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_strong_rock.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_strong_rock.dmm @@ -4,7 +4,7 @@ /area/template_noop) "b" = ( /turf/closed/mineral/strong, -/area/template_noop) +/area/lavaland/surface/outdoors) (1,1,1) = {" a diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm index 4cc31bca411..7497b5bb907 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm @@ -3716,7 +3716,7 @@ "OZ" = ( /obj/effect/turf_decal/bot, /obj/effect/decal/cleanable/dirt, -/obj/machinery/suit_storage_unit/syndicate, +/obj/machinery/suit_storage_unit/syndicate/lavaland, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/engineering) diff --git a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_arena.dmm b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_arena.dmm index bce0b173159..47fd82ad043 100644 --- a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_arena.dmm +++ b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_arena.dmm @@ -113,10 +113,9 @@ /obj/structure/stone_tile{ dir = 4 }, -/mob/living/simple_animal/hostile/asteroid/hivelord{ +/mob/living/basic/mining/hivelord/no_wander{ color = "red"; name = "gate guardian"; - wander = 0 }, /turf/open/lava/smooth/lava_land_surface{ slowdown = 0 @@ -308,10 +307,9 @@ /obj/structure/stone_tile{ dir = 1 }, -/mob/living/simple_animal/hostile/asteroid/hivelord{ +/mob/living/basic/mining/hivelord/no_wander{ color = "red"; name = "gate guardian"; - wander = 0 }, /turf/open/lava/smooth/lava_land_surface{ slowdown = 0 @@ -627,10 +625,9 @@ /obj/structure/stone_tile{ dir = 1 }, -/mob/living/simple_animal/hostile/asteroid/hivelord{ +/mob/living/basic/mining/hivelord/no_wander{ color = "red"; name = "gate guardian"; - wander = 0 }, /turf/open/indestructible/boss, /area/lavaland/surface/outdoors) @@ -778,10 +775,9 @@ /obj/structure/stone_tile{ dir = 4 }, -/mob/living/simple_animal/hostile/asteroid/hivelord{ +/mob/living/basic/mining/hivelord/no_wander{ color = "red"; name = "gate guardian"; - wander = 0 }, /turf/open/indestructible/boss, /area/lavaland/surface/outdoors) diff --git a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm index 7b81c9e2193..957a669e53c 100644 --- a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm +++ b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm @@ -1393,7 +1393,7 @@ /turf/open/floor/plating, /area/ruin/syndicate_lava_base/medbay) "oe" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/medbay) "oi" = ( diff --git a/_maps/RandomRuins/SpaceRuins/atmosasteroidruin.dmm b/_maps/RandomRuins/SpaceRuins/atmosasteroidruin.dmm index 1d63a1a0070..7e3b7000c42 100644 --- a/_maps/RandomRuins/SpaceRuins/atmosasteroidruin.dmm +++ b/_maps/RandomRuins/SpaceRuins/atmosasteroidruin.dmm @@ -637,7 +637,7 @@ /obj/effect/turf_decal/tile/yellow/half{ dir = 4 }, -/mob/living/simple_animal/hostile/asteroid/hivelord, +/mob/living/basic/mining/hivelord, /turf/open/floor/iron/co2_pressurized, /area/ruin/space/has_grav/atmosasteroid) "RK" = ( diff --git a/_maps/RandomRuins/SpaceRuins/prey_pod.dmm b/_maps/RandomRuins/SpaceRuins/prey_pod.dmm index 9089dea664c..6f53409b873 100644 --- a/_maps/RandomRuins/SpaceRuins/prey_pod.dmm +++ b/_maps/RandomRuins/SpaceRuins/prey_pod.dmm @@ -17,7 +17,7 @@ /obj/structure/chair/comfy/shuttle{ dir = 4 }, -/mob/living/simple_animal/hostile/asteroid/hivelord, +/mob/living/basic/mining/hivelord, /turf/open/floor/mineral/titanium/white/airless, /area/ruin/space/has_grav) "p" = ( @@ -32,7 +32,7 @@ /area/ruin/space/has_grav) "D" = ( /obj/structure/chair/comfy/shuttle, -/mob/living/simple_animal/hostile/asteroid/hivelord, +/mob/living/basic/mining/hivelord, /turf/open/floor/mineral/titanium/white/airless, /area/ruin/space/has_grav) "E" = ( @@ -57,7 +57,7 @@ /turf/open/floor/mineral/titanium/white/airless, /area/ruin/space/has_grav) "S" = ( -/mob/living/simple_animal/hostile/asteroid/hivelord, +/mob/living/basic/mining/hivelord, /turf/open/floor/mineral/titanium/white/airless, /area/ruin/space/has_grav) "T" = ( diff --git a/_maps/RandomRuins/SpaceRuins/prison_shuttle.dmm b/_maps/RandomRuins/SpaceRuins/prison_shuttle.dmm index 5aeba75b3bd..6acec2ccc43 100644 --- a/_maps/RandomRuins/SpaceRuins/prison_shuttle.dmm +++ b/_maps/RandomRuins/SpaceRuins/prison_shuttle.dmm @@ -56,7 +56,7 @@ /turf/open/floor/plating/airless, /area/ruin/space/prison_shuttle) "q" = ( -/mob/living/simple_animal/hostile/asteroid/hivelord, +/mob/living/basic/mining/hivelord, /turf/open/misc/asteroid/airless, /area/ruin/space/prison_shuttle) "r" = ( @@ -84,7 +84,7 @@ /turf/open/floor/mineral/titanium/tiled/airless, /area/ruin/space/prison_shuttle) "w" = ( -/mob/living/simple_animal/hostile/asteroid/hivelord, +/mob/living/basic/mining/hivelord, /turf/open/floor/plating/airless, /area/ruin/space/prison_shuttle) "x" = ( diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/syndibase.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/syndibase.dmm index eec3ffec3b3..91d171ca87e 100644 --- a/_maps/RandomRuins/SpaceRuins/skyrat/syndibase.dmm +++ b/_maps/RandomRuins/SpaceRuins/skyrat/syndibase.dmm @@ -164,7 +164,7 @@ /turf/open/floor/iron, /area/ruin/space/has_grav/powered) "pF" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /turf/open/floor/iron/dark, /area/ruin/space/has_grav/powered) "pL" = ( diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/wreckedhomestead.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/wreckedhomestead.dmm index 3524b7a08a3..98172e42bc5 100644 --- a/_maps/RandomRuins/SpaceRuins/skyrat/wreckedhomestead.dmm +++ b/_maps/RandomRuins/SpaceRuins/skyrat/wreckedhomestead.dmm @@ -161,7 +161,7 @@ /turf/open/floor/plating/airless, /area/ruin/unpowered) "Az" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating/airless, /area/ruin/unpowered) diff --git a/_maps/RandomZLevels/SnowCabin.dmm b/_maps/RandomZLevels/SnowCabin.dmm index cf2b35b3663..cf324e6c5bb 100644 --- a/_maps/RandomZLevels/SnowCabin.dmm +++ b/_maps/RandomZLevels/SnowCabin.dmm @@ -426,7 +426,7 @@ /turf/open/floor/iron/white, /area/awaymission/cabin) "bF" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /turf/open/floor/iron/white, /area/awaymission/cabin) "bG" = ( diff --git a/_maps/RandomZLevels/blackmesa.dmm b/_maps/RandomZLevels/blackmesa.dmm index b9887279a16..a4aafb74536 100644 --- a/_maps/RandomZLevels/blackmesa.dmm +++ b/_maps/RandomZLevels/blackmesa.dmm @@ -5164,7 +5164,7 @@ /turf/open/floor/iron/smooth_large, /area/awaymission/black_mesa/hecu_zone_external_hall) "dcv" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /turf/open/floor/iron/smooth_large, /area/awaymission/black_mesa/xen/acid_lake_building) "ddi" = ( diff --git a/_maps/RandomZLevels/research.dmm b/_maps/RandomZLevels/research.dmm index 324734c4eb9..18429389d87 100644 --- a/_maps/RandomZLevels/research.dmm +++ b/_maps/RandomZLevels/research.dmm @@ -1042,7 +1042,7 @@ /turf/open/floor/iron/white, /area/awaymission/research/interior/cryo) "fc" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /turf/open/floor/iron/white, /area/awaymission/research/interior/cryo) "fd" = ( @@ -1083,7 +1083,7 @@ /area/awaymission/research/interior/cryo) "fh" = ( /obj/effect/decal/cleanable/blood/drip, -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /turf/open/floor/iron/white, /area/awaymission/research/interior/cryo) "fk" = ( diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index 21b1cddf818..78590312a61 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -104,6 +104,13 @@ /obj/machinery/camera/directional/east, /turf/open/floor/iron, /area/station/service/janitor) +"adl" = ( +/obj/effect/turf_decal/siding/white, +/obj/machinery/light/small/directional/south, +/obj/structure/table/reinforced, +/obj/item/surgery_tray/full/morgue, +/turf/open/floor/iron/small, +/area/station/medical/morgue) "adB" = ( /obj/effect/turf_decal/sand/plating, /turf/open/floor/plating, @@ -865,6 +872,12 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/engineering/atmos/project) +"arU" = ( +/obj/effect/turf_decal/bot_white, +/obj/structure/rack, +/obj/item/electronics/apc, +/turf/open/floor/iron/smooth_large, +/area/station/cargo/warehouse) "asb" = ( /obj/effect/turf_decal/siding/white, /turf/open/floor/iron/dark/small, @@ -1633,6 +1646,10 @@ }, /turf/open/floor/iron/small, /area/station/maintenance/port/lesser) +"aJN" = ( +/obj/structure/window/reinforced/shuttle, +/turf/open/floor/plating, +/area/station/commons/fitness/recreation/entertainment) "aJX" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/door/airlock{ @@ -2559,6 +2576,11 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) +"bbP" = ( +/obj/structure/rack, +/obj/effect/spawner/random/maintenance/two, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "bbU" = ( /obj/effect/landmark/generic_maintenance_landmark, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -3103,6 +3125,14 @@ /mob/living/simple_animal/bot/medbot/autopatrol, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) +"bmL" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/structure/extinguisher_cabinet/directional/north, +/turf/open/floor/iron, +/area/station/cargo/storage) "bmM" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -3296,6 +3326,11 @@ /obj/effect/spawner/random/engineering/atmospherics_portable, /turf/open/floor/plating, /area/station/maintenance/department/engine) +"bqy" = ( +/turf/open/floor/engine{ + name = "Holodeck Projector Floor" + }, +/area/station/holodeck/rec_center) "bqE" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -5414,14 +5449,6 @@ /obj/structure/sign/poster/official/random/directional/north, /turf/open/floor/iron/smooth_large, /area/station/science/auxlab/firing_range) -"cgD" = ( -/obj/machinery/door/airlock{ - name = "Mineshaft" - }, -/obj/effect/mapping_helpers/airlock/access/any/service/maintenance, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating/rust, -/area/station/maintenance/fore/greater) "cgM" = ( /turf/open/misc/asteroid, /area/station/maintenance/starboard/greater) @@ -5497,14 +5524,6 @@ }, /turf/open/floor/iron, /area/station/maintenance/port/fore) -"ciL" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable, -/obj/structure/extinguisher_cabinet/directional/north, -/turf/open/floor/iron, -/area/station/cargo/storage) "ciR" = ( /obj/structure/table, /obj/effect/spawner/random/techstorage/command_all, @@ -7682,6 +7701,12 @@ /obj/effect/spawner/random/structure/steam_vent, /turf/open/floor/plating, /area/station/ai_monitored/turret_protected/aisat/maint) +"cZm" = ( +/obj/effect/landmark/start/hangover, +/turf/open/floor/engine{ + name = "Holodeck Projector Floor" + }, +/area/station/holodeck/rec_center) "cZy" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -8386,10 +8411,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/disposal/incinerator) -"dmz" = ( -/obj/effect/spawner/random/structure/closet_maintenance, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "dmT" = ( /obj/machinery/camera/directional/north{ c_tag = "Xenobiology - Cell 2"; @@ -8519,6 +8540,11 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/station/maintenance/department/engine/atmos) +"doX" = ( +/obj/structure/girder, +/obj/effect/decal/cleanable/glass/plastitanium, +/turf/open/floor/plating, +/area/station/commons/fitness/recreation/entertainment) "dps" = ( /obj/machinery/camera/directional/south{ c_tag = "AI Chamber - Aft"; @@ -8811,6 +8837,15 @@ /obj/structure/sign/warning/electric_shock, /turf/closed/wall, /area/station/maintenance/department/engine) +"dvs" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/glass{ + name = "Holodeck Access" + }, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "dvJ" = ( /obj/structure/table/reinforced, /obj/effect/turf_decal/tile/dark_red/fourcorners, @@ -9713,6 +9748,13 @@ /obj/item/wrench, /turf/open/floor/iron/dark, /area/station/science/robotics/lab) +"dNi" = ( +/obj/machinery/power/shuttle_engine/heater{ + dir = 1 + }, +/obj/structure/window/spawner/directional/south, +/turf/open/floor/plating, +/area/station/commons/fitness/recreation/entertainment) "dNq" = ( /turf/closed/wall/r_wall/rust, /area/station/ai_monitored/aisat/exterior) @@ -10352,6 +10394,12 @@ }, /turf/open/floor/iron/dark, /area/station/security/lockers) +"dYf" = ( +/obj/effect/spawner/random/entertainment/arcade{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "dYj" = ( /obj/structure/table, /obj/effect/turf_decal/tile/dark_red, @@ -10959,6 +11007,10 @@ /obj/machinery/atmospherics/pipe/layer_manifold/orange/visible, /turf/open/floor/iron/smooth, /area/station/engineering/supermatter/room) +"ejV" = ( +/mob/living/basic/mining/basilisk, +/turf/open/misc/asteroid, +/area/space/nearstation) "eki" = ( /obj/machinery/door/airlock/maintenance{ name = "Maintenance" @@ -11841,6 +11893,11 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/break_room) +"eyz" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/obj/structure/chair/stool/directional/west, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "eyB" = ( /obj/structure/cable, /obj/machinery/door/firedoor, @@ -12568,6 +12625,11 @@ }, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"eKX" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "eLn" = ( /obj/machinery/door/airlock/glass{ name = "Gold Standard Law Firm" @@ -13849,6 +13911,14 @@ }, /turf/open/floor/iron/dark, /area/station/security/interrogation) +"fls" = ( +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/duct, +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/decal/cleanable/glass/plastitanium, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "flM" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -17550,6 +17620,14 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/smooth, /area/station/hallway/secondary/command) +"gxZ" = ( +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/broken_floor, +/obj/machinery/duct, +/obj/machinery/power/apc/auto_name/directional/west, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "gyd" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/window/spawner/directional/east, @@ -17879,6 +17957,13 @@ /obj/machinery/airalarm/directional/south, /turf/open/floor/iron, /area/station/cargo/office) +"gEQ" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/chair/sofa/bench/right{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "gFg" = ( /obj/machinery/computer/cargo/request, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -19426,6 +19511,8 @@ /obj/effect/mapping_helpers/broken_floor, /obj/structure/sign/poster/official/random/directional/north, /obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small/directional/north, +/obj/machinery/camera/directional/west, /turf/open/floor/iron, /area/station/commons) "hem" = ( @@ -20241,16 +20328,6 @@ /obj/effect/turf_decal/stripes/white/line, /turf/open/floor/plating, /area/station/cargo/miningoffice) -"hsK" = ( -/obj/machinery/recycler{ - dir = 8 - }, -/obj/machinery/conveyor{ - dir = 4; - id = "garbage" - }, -/turf/open/floor/plating, -/area/station/service/janitor) "hsO" = ( /obj/structure/cable, /obj/effect/spawner/structure/window, @@ -20689,16 +20766,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"hzN" = ( -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/item/radio/intercom/directional/north, -/turf/open/floor/iron, -/area/station/cargo/storage) "hzV" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable, @@ -21023,12 +21090,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/smooth, /area/station/hallway/secondary/command) -"hFm" = ( -/obj/effect/turf_decal/bot_white, -/obj/structure/rack, -/obj/item/electronics/apc, -/turf/open/floor/iron/smooth_large, -/area/station/cargo/warehouse) "hFx" = ( /turf/open/floor/iron/chapel{ dir = 1 @@ -21174,11 +21235,6 @@ "hJp" = ( /turf/closed/wall/r_wall/rust, /area/station/ai_monitored/turret_protected/ai) -"hJr" = ( -/obj/structure/table, -/obj/effect/decal/cleanable/dirt, -/turf/open/misc/asteroid, -/area/station/maintenance/fore/greater) "hJC" = ( /obj/structure/closet/crate/hydroponics, /obj/item/paper/guides/jobs/hydroponics, @@ -22684,11 +22740,6 @@ /obj/effect/spawner/random/engineering/atmospherics_portable, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) -"imd" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/closet/firecloset, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "imj" = ( /obj/machinery/door/airlock/security/glass{ id_tag = "permaouter"; @@ -23217,6 +23268,10 @@ }, /turf/closed/wall/mineral/titanium/nodiagonal, /area/station/engineering/supermatter) +"iux" = ( +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "iuH" = ( /obj/machinery/atmospherics/pipe/smart/simple/dark/visible, /obj/effect/decal/cleanable/dirt, @@ -23307,8 +23362,9 @@ /turf/open/floor/iron/dark, /area/station/engineering/atmos) "ivO" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/reagent_dispensers/fueltank, +/obj/effect/decal/cleanable/dirt, +/obj/structure/girder, +/obj/effect/decal/cleanable/glass/plastitanium, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "ivX" = ( @@ -23730,7 +23786,7 @@ /turf/open/floor/iron/white, /area/station/medical/medbay/aft) "iFi" = ( -/obj/effect/spawner/random/structure/crate, +/obj/effect/spawner/random/vending/colavend, /turf/open/floor/plating/rust, /area/station/maintenance/fore/greater) "iFs" = ( @@ -23815,9 +23871,9 @@ /turf/open/floor/plating, /area/station/maintenance/fore/lesser) "iHs" = ( -/obj/effect/turf_decal/sand/plating, -/obj/effect/spawner/random/engineering/atmospherics_portable, -/turf/open/floor/plating, +/obj/machinery/portable_atmospherics/canister/air, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/plating/rust, /area/station/maintenance/fore/greater) "iHy" = ( /obj/structure/window/reinforced/plasma/spawner/directional/east, @@ -24135,6 +24191,9 @@ /obj/effect/mapping_helpers/airlock/access/any/security/maintenance, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"iMy" = ( +/turf/open/misc/asteroid, +/area/space/nearstation) "iMC" = ( /obj/machinery/flasher/portable, /turf/open/floor/plating, @@ -24353,17 +24412,11 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/iron/smooth, /area/station/engineering/supermatter/room) -"iQF" = ( -/obj/effect/turf_decal/sand/plating, -/obj/effect/spawner/random/structure/closet_maintenance, -/obj/effect/spawner/random/maintenance, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "iQK" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, /obj/effect/mapping_helpers/broken_floor, +/obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating/rust, /area/station/maintenance/fore/greater) "iQU" = ( @@ -24384,6 +24437,8 @@ "iRv" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/decal/cleanable/glass/plastitanium, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "iRz" = ( @@ -24428,15 +24483,6 @@ "iSr" = ( /turf/open/floor/iron, /area/station/security/execution/transfer) -"iSB" = ( -/obj/structure/cable, -/obj/machinery/door/airlock{ - name = "Maintenance" - }, -/obj/effect/mapping_helpers/airlock/access/any/service/maintenance, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "iSK" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -24445,13 +24491,6 @@ /obj/structure/sign/warning/pods/directional/west, /turf/open/floor/iron/checker, /area/station/security/breakroom) -"iSO" = ( -/obj/structure/cable, -/obj/machinery/power/apc/auto_name/directional/north, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/duct, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "iSW" = ( /obj/structure/rack, /obj/item/clothing/gloves/boxing/yellow, @@ -24991,8 +25030,13 @@ /turf/open/floor/plating, /area/station/command/heads_quarters/rd) "jbm" = ( -/turf/closed/mineral/random/stationside, -/area/station/maintenance/fore/greater) +/obj/machinery/firealarm/directional/south, +/obj/effect/decal/cleanable/dirt, +/obj/structure/broken_flooring/corner/directional/north, +/obj/structure/sign/poster/official/random/directional/west, +/obj/effect/spawner/random/vending/snackvend, +/turf/open/floor/plating, +/area/station/commons/fitness/recreation/entertainment) "jbr" = ( /obj/structure/table/glass, /obj/item/folder/blue{ @@ -25110,15 +25154,15 @@ /turf/open/floor/plating/rust, /area/station/maintenance/fore/greater) "jey" = ( -/obj/structure/cable, -/obj/machinery/portable_atmospherics/pump, -/turf/open/floor/plating/rust, -/area/station/maintenance/fore/greater) +/obj/machinery/vending/clothing, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "jez" = ( -/obj/structure/cable, -/obj/machinery/portable_atmospherics/canister/air, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "jeC" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -25147,11 +25191,12 @@ /turf/open/floor/plating, /area/station/medical/medbay/lobby) "jeX" = ( -/obj/structure/cable, -/obj/machinery/portable_atmospherics/canister/air, +/obj/machinery/light/small/directional/east, /obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating/rust, -/area/station/maintenance/fore/greater) +/obj/effect/mapping_helpers/broken_floor, +/obj/structure/broken_flooring/singular/directional/west, +/turf/open/floor/plating, +/area/station/commons/fitness/recreation/entertainment) "jfs" = ( /obj/effect/turf_decal/tile/yellow/half/contrasted{ dir = 4 @@ -25794,10 +25839,6 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/iron/smooth_large, /area/station/science/auxlab/firing_range) -"jsn" = ( -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "jsv" = ( /obj/structure/cable, /obj/machinery/holopad, @@ -26171,12 +26212,6 @@ }, /turf/open/floor/iron/kitchen/small, /area/station/hallway/secondary/service) -"jzl" = ( -/obj/structure/cable, -/obj/effect/turf_decal/sand/plating, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "jzo" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -26225,7 +26260,9 @@ /area/station/hallway/secondary/construction) "jAs" = ( /obj/structure/cable, -/obj/effect/turf_decal/sand/plating, +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/spawner/random/structure/closet_maintenance, +/obj/effect/spawner/random/maintenance, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "jAw" = ( @@ -26522,6 +26559,15 @@ /obj/structure/sign/poster/official/random/directional/north, /turf/open/floor/iron/smooth, /area/station/hallway/secondary/command) +"jFc" = ( +/obj/effect/decal/cleanable/dirt, +/obj/item/trash/cheesie{ + pixel_x = 7; + pixel_y = 3 + }, +/obj/structure/table, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "jFf" = ( /obj/effect/turf_decal/tile/green/diagonal_centre, /obj/machinery/status_display/ai/directional/north, @@ -27175,6 +27221,13 @@ /obj/effect/spawner/structure/window/reinforced/tinted, /turf/open/floor/plating, /area/station/maintenance/fore/greater) +"jPr" = ( +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/duct, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "jQo" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/door/airlock/research/glass{ @@ -27469,6 +27522,10 @@ dir = 8 }, /area/station/hallway/secondary/dock) +"jWR" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "jWZ" = ( /obj/machinery/mineral/ore_redemption{ dir = 4; @@ -27531,15 +27588,6 @@ /obj/effect/turf_decal/siding/wideplating/dark/corner, /turf/open/floor/iron, /area/station/security) -"jXE" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable, -/obj/machinery/light/cold/directional/north, -/obj/structure/sign/poster/official/random/directional/north, -/turf/open/floor/iron, -/area/station/cargo/storage) "jXQ" = ( /obj/structure/flora/bush/large/style_random{ pixel_x = -18; @@ -28303,6 +28351,15 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/carpet/orange, /area/station/service/abandoned_gambling_den) +"kmb" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/computer/holodeck{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "kmd" = ( /obj/structure/cable, /obj/machinery/door/airlock/external{ @@ -28367,6 +28424,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/orange/hidden/layer1, /turf/open/floor/iron/dark, /area/station/engineering/atmos) +"kmS" = ( +/obj/machinery/power/shuttle_engine/propulsion{ + dir = 1 + }, +/turf/open/floor/plating, +/area/station/commons/fitness/recreation/entertainment) "kmT" = ( /obj/structure/closet/firecloset, /turf/open/floor/plating, @@ -28381,6 +28444,14 @@ }, /turf/open/floor/iron, /area/station/cargo/storage) +"knt" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/broken_flooring/pile/directional/east, +/turf/open/floor/plating, +/area/station/maintenance/hallway/abandoned_command) "knv" = ( /turf/closed/wall, /area/station/maintenance/department/engine/atmos) @@ -28766,6 +28837,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/cargo/office) +"ktN" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/chair/sofa/bench/left{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "ktZ" = ( /obj/effect/turf_decal/sand/plating, /obj/structure/bookcase/random, @@ -29222,6 +29300,7 @@ "kDq" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/commons) "kDV" = ( @@ -29370,8 +29449,7 @@ }, /area/station/maintenance/department/engine/atmos) "kGz" = ( -/obj/effect/mapping_helpers/broken_floor, -/obj/structure/reagent_dispensers/plumbed, +/obj/structure/girder, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "kGB" = ( @@ -29665,11 +29743,6 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron/showroomfloor, /area/station/commons/toilet/restrooms) -"kKN" = ( -/obj/structure/barricade/wooden, -/obj/effect/decal/cleanable/dirt, -/turf/open/misc/asteroid, -/area/station/maintenance/fore/greater) "kKT" = ( /obj/machinery/computer/camera_advanced/xenobio{ dir = 4 @@ -29724,6 +29797,10 @@ dir = 1 }, /area/station/medical/treatment_center) +"kLT" = ( +/obj/machinery/rnd/bepis, +/turf/open/floor/iron, +/area/station/cargo/storage) "kMm" = ( /obj/structure/chair/sofa/right/brown{ dir = 1 @@ -29866,6 +29943,10 @@ /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/station/construction/mining/aux_base) +"kOW" = ( +/obj/effect/mob_spawn/corpse/human/miner, +/turf/open/misc/asteroid, +/area/space/nearstation) "kPa" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -30353,11 +30434,10 @@ /turf/open/floor/grass, /area/station/cargo/storage) "kZf" = ( -/obj/effect/turf_decal/sand/plating, +/obj/structure/cable, /obj/effect/decal/cleanable/dirt, -/obj/effect/spawner/random/trash, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "kZh" = ( /obj/structure/table/glass, /obj/effect/turf_decal/siding/thinplating_new/light{ @@ -30368,10 +30448,11 @@ /area/station/science/cubicle) "kZo" = ( /obj/structure/cable, -/obj/effect/turf_decal/sand/plating, /obj/effect/decal/cleanable/dirt, /obj/machinery/duct, /obj/effect/spawner/random/trash, +/obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "kZx" = ( @@ -31353,10 +31434,6 @@ /obj/structure/ore_box, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) -"lnT" = ( -/obj/machinery/rnd/bepis, -/turf/open/floor/iron, -/area/station/cargo/storage) "lnZ" = ( /obj/effect/turf_decal/tile/dark_red, /obj/effect/decal/cleanable/dirt, @@ -31469,8 +31546,10 @@ /turf/open/floor/wood/parquet, /area/station/service/library) "lqs" = ( -/turf/closed/wall/rust, -/area/station/maintenance/fore/greater) +/obj/machinery/light/cold/directional/south, +/obj/structure/reagent_dispensers/water_cooler, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "lqt" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -32920,12 +32999,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/security/prison/rec) -"lPG" = ( -/obj/machinery/vending/clothing, -/obj/machinery/camera/directional/north, -/obj/machinery/light/small/directional/north, -/turf/open/floor/iron, -/area/station/commons) "lPI" = ( /obj/effect/turf_decal/siding/wood{ dir = 8 @@ -32937,6 +33010,16 @@ /obj/machinery/announcement_system, /turf/open/floor/iron/grimy, /area/station/tcommsat/server) +"lPO" = ( +/obj/structure/table, +/obj/item/surgery_tray/full{ + pixel_y = -5 + }, +/obj/item/wirecutters{ + pixel_y = 8 + }, +/turf/open/floor/iron/dark/small, +/area/station/security/execution/education) "lPR" = ( /obj/structure/table, /obj/effect/spawner/random/maintenance, @@ -33796,6 +33879,14 @@ dir = 4 }, /area/station/hallway/secondary/entry) +"meP" = ( +/obj/machinery/airalarm/directional/west, +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/random/entertainment/arcade{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "mfc" = ( /obj/effect/turf_decal/tile/red/opposingcorners, /obj/effect/turf_decal/tile/blue/opposingcorners{ @@ -35273,6 +35364,9 @@ /obj/item/radio/intercom/directional/west, /turf/open/floor/iron/white/small, /area/station/medical/virology) +"mHq" = ( +/turf/closed/wall/r_wall, +/area/station/commons/fitness/recreation/entertainment) "mHZ" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -35543,11 +35637,6 @@ }, /turf/open/floor/iron, /area/station/security/processing) -"mLx" = ( -/obj/structure/rack, -/obj/effect/spawner/random/maintenance/two, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "mLA" = ( /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/west, @@ -36004,6 +36093,11 @@ /obj/effect/decal/cleanable/cobweb/cobweb2, /turf/open/floor/iron/grimy, /area/station/cargo/boutique) +"mUC" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/chair/stool/directional/west, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "mUO" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, @@ -36375,6 +36469,16 @@ /obj/structure/alien/weeds, /turf/open/floor/wood, /area/station/maintenance/starboard/greater) +"ncf" = ( +/obj/machinery/recycler{ + dir = 8 + }, +/obj/machinery/conveyor{ + dir = 4; + id = "garbage" + }, +/turf/open/floor/plating, +/area/station/service/janitor) "ncl" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -36449,10 +36553,6 @@ }, /turf/open/floor/wood/tile, /area/station/commons/vacant_room/commissary) -"net" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/station/commons) "neZ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -38330,6 +38430,15 @@ /obj/effect/turf_decal/stripes/red/line, /turf/open/floor/iron/small, /area/station/hallway/primary/central/fore) +"nMX" = ( +/obj/machinery/camera/directional/south{ + c_tag = "Holodeck - Aft"; + name = "holodeck camera" + }, +/turf/open/floor/engine{ + name = "Holodeck Projector Floor" + }, +/area/station/holodeck/rec_center) "nNb" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -38553,6 +38662,11 @@ }, /turf/open/floor/plating, /area/station/command/bridge) +"nRo" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/table, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "nRr" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, @@ -39637,6 +39751,13 @@ /obj/item/radio/intercom/directional/east, /turf/open/floor/iron/dark/small, /area/station/medical/chemistry) +"onI" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Maintenance" + }, +/obj/effect/mapping_helpers/airlock/access/all/supply/general, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "onP" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/door/firedoor, @@ -39934,6 +40055,11 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/recreation) +"ott" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/random/trash, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "otG" = ( /obj/structure/filingcabinet/filingcabinet, /obj/machinery/status_display/supply{ @@ -40456,6 +40582,13 @@ /obj/effect/mapping_helpers/airlock/access/any/service/hydroponics, /turf/open/floor/plating, /area/station/maintenance/port/greater) +"oDO" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "oDS" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/firealarm/directional/south, @@ -40470,10 +40603,6 @@ /obj/effect/landmark/start/assistant, /turf/open/floor/iron, /area/station/commons/dorms) -"oEm" = ( -/obj/structure/barricade/wooden, -/turf/open/misc/asteroid, -/area/station/maintenance/fore/greater) "oEr" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -41427,6 +41556,16 @@ /obj/machinery/atmospherics/pipe/heat_exchanging/simple, /turf/open/floor/iron/dark/small, /area/station/tcommsat/server) +"oXa" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/item/radio/intercom/directional/north, +/turf/open/floor/iron, +/area/station/cargo/storage) "oXe" = ( /obj/effect/mapping_helpers/broken_floor, /obj/machinery/duct, @@ -42789,10 +42928,11 @@ /turf/open/floor/iron/diagonal, /area/station/command/heads_quarters/hop) "puC" = ( -/obj/effect/turf_decal/sand/plating, +/obj/machinery/light/small/directional/west, /obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) +/obj/structure/closet/firecloset, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "puD" = ( /obj/structure/bookcase/random/nonfiction, /obj/machinery/newscaster/directional/west, @@ -43069,6 +43209,9 @@ /obj/machinery/camera/autoname/directional/north, /turf/open/floor/iron/white, /area/station/medical/treatment_center) +"pzd" = ( +/turf/closed/wall, +/area/station/commons/fitness/recreation/entertainment) "pzn" = ( /obj/structure/table, /obj/effect/turf_decal/siding/wood{ @@ -43573,6 +43716,12 @@ /obj/machinery/light_switch/directional/north, /turf/open/floor/wood, /area/station/commons/fitness/recreation) +"pGX" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/commons) "pHe" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/door/firedoor, @@ -43847,11 +43996,6 @@ }, /turf/open/floor/iron/small, /area/station/ai_monitored/command/storage/eva) -"pLk" = ( -/mob/living/basic/mining/basilisk, -/obj/effect/decal/cleanable/dirt, -/turf/open/misc/asteroid, -/area/station/maintenance/fore/greater) "pLl" = ( /obj/effect/spawner/random/vending/snackvend, /obj/effect/turf_decal/tile/red/opposingcorners{ @@ -44074,6 +44218,14 @@ /obj/machinery/duct, /turf/open/floor/iron/kitchen/small, /area/station/hallway/secondary/service) +"pOL" = ( +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/decal/cleanable/glass/plastitanium, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "pOX" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 1 @@ -44222,6 +44374,12 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/department/prison) +"pSf" = ( +/obj/machinery/power/apc/auto_name/directional/west, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "pSm" = ( /obj/effect/mapping_helpers/broken_floor, /obj/effect/turf_decal/tile/yellow/anticorner/contrasted{ @@ -44329,16 +44487,6 @@ /obj/effect/mapping_helpers/airlock/access/all/service/chapel_office, /turf/open/floor/plating, /area/station/maintenance/port/lesser) -"pTr" = ( -/obj/structure/table, -/obj/item/surgery_tray/full{ - pixel_y = -5 - }, -/obj/item/wirecutters{ - pixel_y = 8 - }, -/turf/open/floor/iron/dark/small, -/area/station/security/execution/education) "pTs" = ( /obj/structure/window/spawner/directional/west, /obj/structure/chair/sofa/corp/right{ @@ -44462,6 +44610,11 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron/white, /area/station/science/auxlab/firing_range) +"pVo" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/girder, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "pVq" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/trimline/neutral/line{ @@ -46068,10 +46221,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/commons/dorms) -"quf" = ( -/obj/item/kirbyplants/random, -/turf/open/floor/iron, -/area/station/commons) "qui" = ( /obj/machinery/camera/autoname/directional/north, /turf/open/floor/wood/parquet, @@ -46238,6 +46387,13 @@ }, /turf/open/floor/iron/solarpanel/airless, /area/station/solars/port) +"qxf" = ( +/obj/machinery/cryo_cell, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/iron/small, +/area/station/medical/cryo) "qxh" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -46530,6 +46686,15 @@ /obj/structure/barricade/wooden/crude, /turf/open/floor/plating, /area/station/cargo/boutique) +"qBl" = ( +/obj/machinery/camera/directional/north{ + c_tag = "Holodeck - Fore"; + name = "holodeck camera" + }, +/turf/open/floor/engine{ + name = "Holodeck Projector Floor" + }, +/area/station/holodeck/rec_center) "qBy" = ( /obj/effect/turf_decal/plaque{ icon_state = "L5" @@ -49163,6 +49328,10 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) +"rtK" = ( +/obj/item/kirbyplants/random, +/turf/open/floor/iron, +/area/station/commons) "rtQ" = ( /turf/closed/wall/r_wall, /area/station/security/tram) @@ -49186,14 +49355,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/science/lower) -"ruC" = ( -/obj/structure/window/reinforced/spawner/directional/east, -/obj/effect/turf_decal/tile/green/anticorner/contrasted, -/obj/structure/table/glass, -/obj/effect/mapping_helpers/broken_floor, -/obj/item/radio/intercom/directional/south, -/turf/open/floor/iron/white, -/area/station/medical/virology) "ruD" = ( /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) @@ -49510,6 +49671,11 @@ dir = 1 }, /area/station/hallway/secondary/entry) +"rzR" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/holopad, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "rAb" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -49751,6 +49917,11 @@ dir = 4 }, /area/station/hallway/secondary/entry) +"rDl" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/digital_clock/directional/north, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "rDx" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/structure/window/reinforced/spawner/directional/south, @@ -49987,13 +50158,9 @@ /turf/open/floor/iron/white, /area/station/medical/virology) "rGL" = ( -/obj/effect/decal/cleanable/dirt, -/obj/item/picket_sign{ - desc = "Can't you read? it clearly says what it says!"; - name = "DO NOT ENTER" - }, -/turf/open/misc/asteroid, -/area/station/maintenance/fore/greater) +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/commons/fitness/recreation/entertainment) "rGN" = ( /obj/effect/spawner/random/structure/crate, /turf/open/floor/plating, @@ -50110,9 +50277,9 @@ /turf/open/floor/engine, /area/station/engineering/gravity_generator) "rIO" = ( -/obj/effect/spawner/random/trash, -/turf/open/misc/asteroid, -/area/station/maintenance/fore/greater) +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "rIS" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron/cafeteria, @@ -50399,6 +50566,16 @@ /obj/effect/spawner/random/entertainment/arcade, /turf/open/floor/iron/cafeteria, /area/station/security/prison/mess) +"rNK" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/glass{ + name = "Holodeck" + }, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "rOb" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -51012,6 +51189,10 @@ /obj/structure/reagent_dispensers/watertank, /turf/open/floor/plating, /area/station/maintenance/port/greater) +"rXy" = ( +/obj/effect/spawner/random/structure/closet_maintenance, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "rXW" = ( /obj/structure/flora/bush/flowers_yw, /obj/machinery/door/window/left/directional/west{ @@ -51122,14 +51303,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) -"rZu" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/structure/broken_flooring/pile/directional/east, -/turf/open/floor/plating, -/area/station/maintenance/hallway/abandoned_command) "rZG" = ( /obj/structure/closet/crate/trashcart, /obj/effect/spawner/random/trash/food_packaging, @@ -51766,11 +51939,6 @@ /obj/machinery/camera/autoname/directional/west, /turf/open/floor/iron, /area/station/medical/chemistry) -"skH" = ( -/obj/structure/rack, -/obj/item/flashlight/lantern, -/turf/open/misc/asteroid, -/area/station/maintenance/fore/greater) "skP" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -52973,6 +53141,10 @@ /obj/effect/turf_decal/tile/neutral/opposingcorners, /turf/open/floor/iron, /area/station/hallway/secondary/spacebridge) +"sEi" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "sEn" = ( /obj/item/clothing/head/cone, /obj/item/clothing/head/cone{ @@ -53707,6 +53879,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/cargo/storage) +"sSl" = ( +/obj/machinery/camera/directional/west, +/obj/machinery/status_display/ai/directional/west, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "sSm" = ( /obj/effect/turf_decal/stripes/red/line{ dir = 4 @@ -54326,10 +54504,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/hallway/secondary/entry) -"tbM" = ( -/obj/effect/spawner/random/structure/closet_maintenance, -/turf/open/misc/asteroid, -/area/station/maintenance/fore/greater) "tbS" = ( /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -54596,13 +54770,6 @@ /obj/structure/sign/poster/official/random/directional/north, /turf/open/floor/wood/tile, /area/station/command/heads_quarters/hop) -"tgJ" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/iron/small, -/area/station/medical/cryo) "tgR" = ( /obj/structure/disposalpipe/junction/flip{ dir = 1 @@ -55371,13 +55538,6 @@ }, /turf/open/space/basic, /area/space/nearstation) -"twh" = ( -/obj/effect/turf_decal/sand/plating, -/obj/effect/decal/cleanable/dirt, -/obj/structure/table, -/obj/item/stack/sheet/mineral/sandstone, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "twi" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -55458,8 +55618,12 @@ /turf/open/floor/iron/small, /area/station/hallway/primary/central/fore) "twN" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/misc/asteroid, +/obj/machinery/door/airlock{ + name = "Maintenance" + }, +/obj/effect/mapping_helpers/airlock/access/any/service/maintenance, +/obj/structure/cable, +/turf/open/floor/plating/rust, /area/station/maintenance/fore/greater) "twR" = ( /obj/structure/table/glass, @@ -55851,13 +56015,6 @@ /obj/machinery/shower/directional/west, /turf/open/floor/iron/dark, /area/station/medical/pharmacy) -"tDm" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Maintenance" - }, -/obj/effect/mapping_helpers/airlock/access/all/supply/general, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "tDn" = ( /turf/closed/wall/r_wall, /area/station/maintenance/department/prison) @@ -56124,6 +56281,9 @@ /obj/effect/turf_decal/tile/green/diagonal_centre, /turf/open/floor/iron/diagonal, /area/station/hallway/primary/central/aft) +"tIE" = ( +/turf/closed/wall/mineral/titanium, +/area/station/commons/fitness/recreation/entertainment) "tII" = ( /obj/effect/spawner/random/structure/closet_maintenance, /turf/open/floor/plating, @@ -56137,6 +56297,11 @@ /obj/effect/turf_decal/tile/green/diagonal_centre, /turf/open/floor/iron/diagonal, /area/station/hallway/primary/central/aft) +"tIQ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/random/structure/crate, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "tJe" = ( /obj/effect/turf_decal/tile/dark_red/half/contrasted{ dir = 1 @@ -56209,6 +56374,10 @@ /obj/effect/turf_decal/tile/green/diagonal_centre, /turf/open/floor/iron/diagonal, /area/station/hallway/primary/central/aft) +"tJN" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "tJO" = ( /obj/effect/spawner/structure/window/reinforced/plasma, /obj/machinery/atmospherics/pipe/smart/simple/brown/visible, @@ -56604,6 +56773,17 @@ /obj/structure/extinguisher_cabinet/directional/east, /turf/open/floor/iron, /area/station/security/courtroom) +"tRp" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/public/glass{ + name = "Holodeck Door" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ + cycle_id = "holodeck" + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "tRw" = ( /obj/structure/disposalpipe/trunk{ dir = 8 @@ -57977,8 +58157,7 @@ /turf/open/floor/iron, /area/station/hallway/primary/central/fore) "unK" = ( -/obj/structure/rack, -/obj/effect/spawner/random/maintenance, +/obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "unM" = ( @@ -59235,6 +59414,11 @@ }, /turf/open/floor/iron/showroomfloor, /area/station/commons/toilet/auxiliary) +"uJZ" = ( +/obj/structure/window/reinforced/shuttle, +/obj/structure/window/reinforced/shuttle, +/turf/open/floor/plating, +/area/station/commons/fitness/recreation/entertainment) "uKl" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -59333,13 +59517,6 @@ /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/station/hallway/secondary/service) -"uMl" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/iron/small, -/area/station/medical/cryo) "uMu" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -59893,6 +60070,11 @@ }, /turf/closed/wall, /area/station/hallway/primary/starboard) +"uWg" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/structure/sign/poster/official/random/directional/west, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "uWl" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -60641,13 +60823,6 @@ /obj/structure/closet/emcloset, /turf/open/floor/iron/small, /area/station/maintenance/starboard/central) -"viR" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/sink/directional/south, -/obj/item/reagent_containers/cup/bucket, -/obj/item/mop, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "viT" = ( /obj/machinery/light/cold/directional/east, /turf/open/floor/iron, @@ -60939,6 +61114,14 @@ /obj/effect/spawner/random/trash, /turf/open/floor/plating, /area/station/maintenance/port/greater) +"vmA" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "vmH" = ( /obj/machinery/door/morgue{ name = "Confession Booth (Chaplain)"; @@ -61260,18 +61443,6 @@ }, /turf/open/floor/catwalk_floor/iron_dark, /area/station/tcommsat/server) -"vra" = ( -/obj/effect/turf_decal/sand/plating, -/obj/effect/decal/cleanable/dirt, -/obj/structure/table, -/obj/item/clothing/under/rank/cargo/miner/lavaland{ - pixel_y = 3 - }, -/obj/item/clothing/suit/hooded/wintercoat/miner{ - pixel_y = 5 - }, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "vrf" = ( /obj/structure/hedge, /obj/machinery/light/small/directional/north, @@ -62344,6 +62515,12 @@ }, /turf/open/floor/iron/small, /area/station/hallway/primary/central/fore) +"vIN" = ( +/obj/effect/decal/cleanable/dirt, +/obj/item/chair/stool, +/obj/structure/sign/poster/contraband/random/directional/north, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "vIX" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -62638,11 +62815,6 @@ /obj/machinery/portable_atmospherics/canister/air, /turf/open/floor/plating, /area/station/maintenance/central/greater) -"vMS" = ( -/obj/item/pickaxe, -/obj/effect/decal/cleanable/dirt, -/turf/open/misc/asteroid, -/area/station/maintenance/fore/greater) "vMT" = ( /obj/machinery/hydroponics/soil, /obj/item/food/grown/mushroom/libertycap, @@ -63033,10 +63205,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white/small, /area/station/service/hydroponics) -"vTO" = ( -/mob/living/simple_animal/hostile/asteroid/gutlunch, -/turf/open/misc/asteroid, -/area/station/maintenance/fore/greater) "vTV" = ( /turf/closed/wall/r_wall, /area/station/command/heads_quarters/hos) @@ -63917,10 +64085,6 @@ /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/station/hallway/secondary/exit/departure_lounge) -"whS" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "whX" = ( /obj/structure/disposalpipe/segment, /obj/machinery/door/airlock{ @@ -64107,6 +64271,13 @@ /obj/effect/spawner/structure/window/reinforced/tinted, /turf/open/floor/plating, /area/station/hallway/secondary/recreation) +"wkZ" = ( +/obj/machinery/cryo_cell, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/iron/small, +/area/station/medical/cryo) "wla" = ( /turf/open/floor/iron/chapel, /area/station/maintenance/starboard/greater) @@ -65196,6 +65367,11 @@ /obj/machinery/computer/arcade/orion_trail/kobayashi, /turf/open/floor/wood/tile, /area/station/maintenance/port/lesser) +"wCD" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "wCH" = ( /obj/effect/turf_decal/stripes/white/line{ dir = 9 @@ -65541,6 +65717,14 @@ /obj/structure/window/reinforced/spawner/directional/north, /turf/open/space/basic, /area/space/nearstation) +"wIG" = ( +/obj/structure/window/reinforced/spawner/directional/east, +/obj/effect/turf_decal/tile/green/anticorner/contrasted, +/obj/structure/table/glass, +/obj/effect/mapping_helpers/broken_floor, +/obj/item/radio/intercom/directional/south, +/turf/open/floor/iron/white, +/area/station/medical/virology) "wII" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/orange/hidden/layer1, /turf/open/floor/iron/dark, @@ -66292,11 +66476,6 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron/textured_half, /area/station/security/prison/work) -"wTn" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/spawner/random/structure/crate, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "wTs" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/sign/poster/official/random/directional/north, @@ -66832,6 +67011,14 @@ /obj/structure/grille, /turf/closed/wall/mineral/titanium/nodiagonal, /area/station/engineering/atmos) +"xaj" = ( +/obj/machinery/light/cold/directional/west, +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/random/entertainment/arcade{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "xam" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -67391,6 +67578,13 @@ "xia" = ( /turf/closed/wall, /area/station/science/cubicle) +"xic" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/sink/directional/south, +/obj/item/reagent_containers/cup/bucket, +/obj/item/mop, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "xif" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -68646,6 +68840,15 @@ }, /turf/open/floor/iron/dark, /area/station/security/interrogation) +"xyz" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/machinery/light/cold/directional/north, +/obj/structure/sign/poster/official/random/directional/north, +/turf/open/floor/iron, +/area/station/cargo/storage) "xyJ" = ( /obj/structure/disposalpipe/segment, /turf/open/floor/iron, @@ -69163,11 +69366,6 @@ /obj/item/reagent_containers/cup/glass/drinkingglass, /turf/open/floor/iron/cafeteria, /area/station/security/prison/mess) -"xGS" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/reagent_dispensers/watertank, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "xGT" = ( /obj/effect/turf_decal/tile/dark_red/opposingcorners, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, @@ -70044,6 +70242,11 @@ /obj/structure/barricade/wooden/crude, /turf/open/floor/plating, /area/station/service/abandoned_gambling_den/gaming) +"xRX" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/random/trash/graffiti, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "xRZ" = ( /obj/effect/turf_decal/siding/wood, /turf/open/floor/grass, @@ -70712,13 +70915,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) -"yaJ" = ( -/obj/effect/turf_decal/siding/white, -/obj/machinery/light/small/directional/south, -/obj/structure/table/reinforced, -/obj/item/surgery_tray/full/morgue, -/turf/open/floor/iron/small, -/area/station/medical/morgue) "yaL" = ( /turf/closed/wall, /area/station/commons/vacant_room/commissary) @@ -70849,24 +71045,6 @@ /obj/effect/turf_decal/stripes/white/line, /turf/open/floor/noslip/tram_plate, /area/station/maintenance/department/medical/central) -"ycz" = ( -/obj/effect/turf_decal/sand/plating, -/obj/effect/decal/cleanable/dirt, -/obj/structure/table, -/obj/item/stack/sheet/mineral/coal{ - pixel_x = 6; - pixel_y = 13 - }, -/obj/item/stack/sheet/mineral/coal{ - pixel_x = 1; - pixel_y = 8 - }, -/obj/item/stack/sheet/mineral/coal{ - pixel_x = -2; - pixel_y = -1 - }, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "ycC" = ( /turf/closed/wall/r_wall, /area/station/command/bridge) @@ -70910,8 +71088,15 @@ /turf/open/floor/wood/tile, /area/station/command/bridge) "ydt" = ( -/turf/open/misc/asteroid, -/area/station/maintenance/fore/greater) +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/public/glass{ + name = "Holodeck Door" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ + cycle_id = "holodeck" + }, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "ydu" = ( /obj/structure/cable, /obj/structure/disposalpipe/sorting/mail{ @@ -70940,6 +71125,11 @@ "yea" = ( /turf/closed/wall, /area/station/service/chapel/office) +"yec" = ( +/obj/structure/girder, +/obj/effect/decal/cleanable/glass/plastitanium, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "yee" = ( /obj/item/kirbyplants/random, /obj/machinery/light_switch/directional/west, @@ -71137,9 +71327,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/maintenance/department/science/xenobiology) -"yfX" = ( -/turf/open/floor/plating/rust, -/area/station/maintenance/fore/greater) "yfY" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -71440,6 +71627,7 @@ "yju" = ( /obj/effect/spawner/random/structure/closet_maintenance, /obj/effect/spawner/random/maintenance, +/obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "yjD" = ( @@ -83003,7 +83191,7 @@ uzJ mQh nJU ppk -lnT +kLT ovQ oRr poM @@ -83504,14 +83692,14 @@ gOK slY hfc slY -viR +xic jBb kPW kwY -whS -dmz +sEi +rXy slY -hzN +oXa lRc moz kee @@ -83761,14 +83949,14 @@ gPN gZk iNE ueX -mLx +bbP kwY slY slY kwY slY slY -jXE +xyz lTv oem oem @@ -83837,7 +84025,7 @@ grn lSI lce vKU -pTr +lPO vfc rtQ rtQ @@ -84021,10 +84209,10 @@ jCo hff jCo slY -wTn -whS +tIQ +sEi kPW -tDm +onI jkS lTN mRD @@ -84282,7 +84470,7 @@ slY slY slY slY -ciL +bmL lUz ohj ohj @@ -84532,7 +84720,7 @@ sNz hyO roi slY -hFm +arU hAN jMb kzI @@ -99229,7 +99417,7 @@ qtl dDB dDB qIf -uMl +qxf aQr wCa ulb @@ -99743,7 +99931,7 @@ qtl dDB dDB qIf -tgJ +wkZ nQU bDj onP @@ -103291,7 +103479,7 @@ xqC gMK dYo oAC -rZu +knt uPt hyZ hFO @@ -103382,7 +103570,7 @@ gLb bXH vTY nqV -ruC +wIG wgL oiA kWs @@ -104588,7 +104776,7 @@ xmO sHe nFW mEy -hsK +ncf nFA kBH onR @@ -105091,14 +105279,14 @@ nyi rvp rvp uIT -xqC +uIT wSZ tdI hHE nNi hPs xmO -sJR +ott sIA jPq kaF @@ -105344,18 +105532,18 @@ dDB dDB aJq aJq -jbm -jbm -jbm -jbm -jbm -xmO +pzd +pzd +pzd +pzd +pzd +mHq +mHq +mHq +mHq xmO xmO -xmO -xmO -xmO -jsn +oTL sIS nFW sRL @@ -105601,17 +105789,17 @@ dDB dDB aJq aJq +pzd +dYf +xaj +meP +uWg +sSl +pSf jbm -jbm -jbm -jbm -jbm -jbm -jbm -jbm -tbM +pzd iFi -iQF +jej jej jAs nFW @@ -105858,18 +106046,18 @@ dDB aJq aJq aJq -jbm -vTO -jbm -jbm -twN -jbm -jbm +pzd +vIN +eyz +mUC +rIO +rzR +kZf lqs -xGS -yfX +pzd +nFW twN -tDB +nFW nFW nFW tBL @@ -106111,23 +106299,23 @@ dDB dDB dDB dDB -dDB aJq aJq aJq -jbm -oEm -jbm -jbm -oEm -jbm -twN -nFW +aJq +pzd +rDl +ktN +gEQ +rIO +jWR +vmA +rIO rGL puC kZf jey -nFW +pzd hek wXt ndZ @@ -106360,34 +106548,34 @@ aJq aJq aJq aJq +hwJ +blb +blb +blb +blb +blb +blb +blb +blb +hwJ aJq aJq -dDB -dDB -dDB -dDB -dDB -dDB -dDB -aJq -aJq -aJq -jbm -twN -ydt -twN -twN -twN -twN -cgD -twN -jsn -oTL +pzd +eKX +jFc +nRo +tJN +wCD +kmb +oDO +rNK +oDO +oDO jez -nFW -lPG -wXt -net +dvs +wYC +pGX +wYC kDq kDq ldB @@ -106445,7 +106633,7 @@ ntW bgA byq pOX -yaJ +adl kFY aQm qEz @@ -106617,36 +106805,36 @@ aJq aJq aJq aJq -hwJ -blb -blb -blb -blb -blb -blb -blb -blb -hwJ aJq -jbm -jbm -ydt -jbm -jbm +dDB +dDB +dDB +dDB +dDB +dDB +dDB +dDB +tIE +aJN +doX +aJN ydt -jbm -skH -lqs -imd -rIO -pLK +rGL +rGL +tRp +rGL +rGL +rGL +rGL +xRX +iux jeX -nFW +pzd qhq tDq rnn udZ -quf +rtK uct lzR wYC @@ -106882,21 +107070,21 @@ dDB dDB dDB dDB -aJq -aJq -aJq -jbm +tIE +tIE +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +tIE +nFW twN -ydt -jbm -jbm -kKN -jbm -jbm -jbm -jbm -sJR -jzl nFW nFW nFW @@ -107138,20 +107326,20 @@ dDB dDB dDB dDB -dDB -aJq -aJq -aJq -jbm -oEm -jbm -jbm -jbm -ydt -jbm -jbm -jbm -jbm +kmS +dNi +tIE +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +tIE iHs iQK tDB @@ -107395,22 +107583,22 @@ dDB dDB dDB dDB -dDB -aJq -aJq -jbm -jbm -twN -jbm -jbm -jbm -twN -twh -ycz -jbm -jbm -jbm -iRv +kmS +dNi +tIE +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +doX +iHs +pLK bjX nFW nFW @@ -107652,22 +107840,22 @@ dDB dDB dDB dDB -dDB -aJq -aJq -jbm -twN -twN -jbm -jbm -jbm -puC -ydt -vra -jbm -nFW -nFW -iSB +kmS +dNi +tIE +bqy +bqy +cZm +bqy +bqy +bqy +bqy +bqy +bqy +bqy +doX +pVo +iRv nFW nFW mjk @@ -107909,22 +108097,22 @@ dDB dDB dDB dDB -dDB -dDB -aJq -jbm -pLk -twN -jbm -jbm -jbm -ydt -puC -hJr -jbm -nFW +tIE +tIE +tIE +qBl +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +nMX +doX ivO -pLK +iRv nFW sJR sJR @@ -108166,22 +108354,22 @@ dDB dDB dDB dDB -dDB -dDB -aJq -aJq -jbm -jbm -jbm -jbm -jbm -vMS -puC -jbm -jbm -nFW +kmS +dNi +tIE +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +tIE yju -iRv +pOL jfP nfc jQF @@ -108423,20 +108611,20 @@ dDB dDB dDB dDB -dDB -dDB -dDB -aJq -aJq -aJq -jbm -jbm -jbm -jbm -jbm -jbm -jbm -nFW +kmS +dNi +tIE +bqy +bqy +bqy +bqy +bqy +bqy +bqy +cZm +bqy +bqy +tIE kGz kZo nFW @@ -108680,22 +108868,22 @@ dDB dDB dDB dDB -dDB -dDB -dDB -aJq -aJq -aJq -aJq -aJq -jbm -jbm -jbm -jbm -jbm -jbm -sJR -njm +kmS +dNi +tIE +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +doX +yec +fls nFW nFW nFW @@ -108938,22 +109126,22 @@ dDB dDB dDB dDB -dDB -dDB -dDB -aJq -aJq -aJq -aJq -aJq -jbm -jbm -jbm -jbm -nFW -nFW -iSO -bHA +tIE +tIE +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +bqy +tIE +kGz +jPr +gxZ dxz sJR xwy @@ -109196,18 +109384,18 @@ dDB dDB dDB dDB -dDB -dDB -dDB -aJq -aJq -aJq -aJq -aJq -jbm -jbm -jbm -jbm +tIE +aJN +aJN +aJN +uJZ +aJN +doX +doX +aJN +aJN +aJN +tIE nFW iSW njm @@ -109462,9 +109650,9 @@ hwJ aJq aJq vcE -vcE -vcE -vcE +jIb +pyt +nvS nFW iUy vtL @@ -110488,8 +110676,8 @@ aJq aJq aJq aJq -aJq -weg +iMy +jJy nvS kbY imE @@ -110744,8 +110932,8 @@ aJq aJq aJq aJq -aJq -aJq +iMy +iMy weg jKf nvS @@ -110999,9 +111187,9 @@ dDB dDB aJq aJq -aJq -aJq -aJq +iMy +iMy +iMy aJq weg weg @@ -111256,8 +111444,8 @@ dDB dDB aJq aJq -aJq -aJq +iMy +kOW aJq aJq weg @@ -111513,7 +111701,7 @@ dDB dDB aJq aJq -aJq +ejV aJq aJq aJq diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 15c9aae2b71..41f0a245642 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -1692,6 +1692,14 @@ }, /turf/open/floor/iron/white, /area/station/medical/chemistry) +"atk" = ( +/obj/item/kirbyplants/random, +/obj/structure/sign/poster/official/random/directional/west, +/obj/effect/turf_decal/tile/purple/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "atl" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/binary/valve/digital{ @@ -3029,6 +3037,12 @@ /obj/structure/sign/warning/electric_shock/directional/west, /turf/open/space/basic, /area/space) +"aLg" = ( +/obj/structure/filingcabinet/chestdrawer, +/obj/effect/turf_decal/delivery, +/obj/machinery/airalarm/directional/south, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "aLv" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -3413,19 +3427,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/science/robotics/lab) -"aPD" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/door/airlock/mining{ - name = "Mining Dock" - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "aPO" = ( /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible, /obj/effect/turf_decal/tile/yellow{ @@ -3566,6 +3567,16 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/security/courtroom) +"aSj" = ( +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/obj/machinery/disposal/bin, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/delivery, +/obj/structure/sign/poster/official/random/directional/south, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "aSl" = ( /obj/machinery/door/firedoor, /obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ @@ -3807,6 +3818,16 @@ /obj/effect/turf_decal/tile/yellow/opposingcorners, /turf/open/floor/iron, /area/station/engineering/supermatter/room) +"aWe" = ( +/obj/structure/table/reinforced, +/obj/effect/decal/cleanable/dirt, +/obj/item/flashlight/lamp, +/obj/structure/cable, +/obj/effect/turf_decal/tile/purple/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "aWk" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -4983,17 +5004,6 @@ }, /turf/open/floor/iron/grimy, /area/station/command/heads_quarters/hos) -"bkr" = ( -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/conveyor{ - id = "cargodisposals" - }, -/obj/effect/mapping_helpers/burnt_floor, -/turf/open/floor/plating, -/area/station/cargo/sorting) "bkD" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, @@ -7297,16 +7307,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/department/science) -"bLN" = ( -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, -/obj/machinery/disposal/bin, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery, -/obj/structure/sign/poster/official/random/directional/south, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "bLP" = ( /obj/machinery/camera/directional/east{ c_tag = "Permabrig - Kitchen Entrance"; @@ -7420,6 +7420,16 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/science/robotics/mechbay) +"bNi" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/delivery, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "bNr" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -9981,6 +9991,22 @@ /obj/machinery/status_display/evac/directional/north, /turf/open/floor/iron, /area/station/ai_monitored/command/storage/eva) +"ctR" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/clipboard, +/obj/item/toy/figure/miner, +/obj/machinery/light/directional/north, +/obj/machinery/light_switch/directional/west{ + pixel_x = -42 + }, +/obj/effect/turf_decal/bot, +/obj/machinery/firealarm/directional/west, +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "ctU" = ( /obj/structure/chair/office{ dir = 1 @@ -10140,22 +10166,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/hop) -"cwd" = ( -/obj/structure/rack, -/obj/effect/decal/cleanable/dirt, -/obj/item/storage/toolbox/emergency{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/storage/toolbox/emergency, -/obj/item/shovel, -/obj/item/shovel, -/obj/item/pickaxe, -/obj/item/pickaxe, -/obj/effect/turf_decal/bot, -/obj/machinery/light/small/directional/south, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "cwe" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -10207,12 +10217,6 @@ /obj/structure/sign/warning/radiation/directional/south, /turf/open/floor/iron, /area/station/engineering/supermatter/room) -"cwK" = ( -/obj/effect/decal/cleanable/cobweb/cobweb2, -/obj/effect/decal/cleanable/dirt, -/obj/structure/reagent_dispensers/watertank, -/turf/open/floor/plating, -/area/station/maintenance/starboard/fore) "cwV" = ( /obj/effect/landmark/start/hangover, /obj/structure/disposalpipe/segment{ @@ -10322,14 +10326,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/medical/treatment_center) -"cyc" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple/half/contrasted, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "cyq" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -10405,6 +10401,13 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/engineering/atmos) +"cze" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "czf" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood/large, @@ -11084,9 +11087,6 @@ /obj/item/radio/intercom/directional/north, /turf/open/floor/iron/grimy, /area/station/tcommsat/computer) -"cGV" = ( -/turf/closed/wall, -/area/station/cargo/miningoffice) "cHb" = ( /obj/machinery/door/firedoor/heavy, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -11803,6 +11803,10 @@ }, /turf/open/floor/iron/large, /area/station/science/xenobiology) +"cQO" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "cQT" = ( /obj/structure/table/reinforced, /obj/machinery/computer/security/telescreen{ @@ -12685,6 +12689,12 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) +"dcA" = ( +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/effect/decal/cleanable/dirt, +/obj/structure/reagent_dispensers/watertank, +/turf/open/floor/plating, +/area/station/maintenance/starboard/fore) "dcG" = ( /obj/effect/turf_decal/trimline/red/filled/line, /obj/effect/landmark/start/depsec/science, @@ -13088,6 +13098,10 @@ /obj/effect/turf_decal/siding/wood/corner, /turf/open/floor/iron/dark, /area/station/hallway/secondary/service) +"dih" = ( +/obj/effect/decal/cleanable/oil, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "din" = ( /obj/structure/table/wood, /obj/item/paper_bin, @@ -13701,6 +13715,19 @@ }, /turf/open/floor/iron, /area/station/maintenance/department/chapel) +"dri" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/maintenance/starboard/fore) "drj" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -13819,6 +13846,15 @@ /obj/machinery/rnd/server, /turf/open/floor/circuit/green/telecomms/mainframe, /area/station/science/server) +"dsq" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "dsy" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -13936,6 +13972,13 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/security/detectives_office/private_investigators_office) +"dtp" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "dtJ" = ( /obj/machinery/power/apc/auto_name/directional/north, /obj/structure/cable, @@ -14005,13 +14048,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/science/xenobiology) -"dux" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/start/shaft_miner, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "duA" = ( /turf/closed/wall/r_wall, /area/station/command/corporate_showroom) @@ -15034,6 +15070,13 @@ }, /turf/open/floor/iron/white, /area/station/medical/cryo) +"dIz" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "dIE" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -15667,17 +15710,6 @@ }, /turf/open/floor/plating, /area/station/engineering/supermatter/room) -"dPC" = ( -/obj/structure/table, -/obj/machinery/microwave{ - desc = "Cooks and boils stuff, somehow."; - pixel_x = -3; - pixel_y = 5 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/bot, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "dPD" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -15797,6 +15829,13 @@ dir = 8 }, /area/station/hallway/primary/fore) +"dRf" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "dRh" = ( /obj/machinery/telecomms/bus/preset_four, /obj/effect/turf_decal/tile/brown/anticorner/contrasted{ @@ -16222,16 +16261,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/maintenance/port) -"dXs" = ( -/obj/structure/table/reinforced, -/obj/effect/decal/cleanable/dirt, -/obj/item/flashlight/lamp, -/obj/structure/cable, -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "dXw" = ( /obj/structure/sign/painting/large/library_private{ dir = 1; @@ -17167,6 +17196,26 @@ }, /turf/open/floor/iron/dark/textured_large, /area/station/engineering/atmos/hfr_room) +"eld" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/requests_console/directional/south{ + department = "Mining"; + name = "Mining Requests Console" + }, +/obj/machinery/requests_console/directional/south{ + department = "Mining"; + name = "Mining Requests Console" + }, +/obj/machinery/camera/directional/south{ + c_tag = "Cargo - Mining Dock"; + name = "cargo camera" + }, +/obj/effect/turf_decal/tile/brown/half/contrasted, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "eln" = ( /obj/effect/turf_decal/stripes/end{ dir = 4 @@ -17229,13 +17278,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/command/gateway) -"elO" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/maintenance/starboard/fore) "elP" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/tile/yellow/fourcorners, @@ -18718,11 +18760,6 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/entry) -"eFU" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/maintenance/starboard/fore) "eGb" = ( /obj/effect/spawner/random/trash/mess, /turf/open/floor/wood, @@ -18993,6 +19030,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden, /turf/open/floor/plating, /area/station/maintenance/department/science/xenobiology) +"eIA" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/purple/half/contrasted{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "eIQ" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -19154,6 +19199,11 @@ /obj/item/radio/intercom/directional/south, /turf/open/floor/iron, /area/station/engineering/supermatter/room) +"eKS" = ( +/obj/machinery/rnd/bepis, +/obj/effect/turf_decal/box/white, +/turf/open/floor/iron, +/area/station/cargo/storage) "eKU" = ( /obj/effect/turf_decal/tile/red/anticorner/contrasted{ dir = 1 @@ -20289,10 +20339,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/security/range) -"eYt" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "eYy" = ( /obj/structure/cable, /obj/structure/closet/secure_closet/atmospherics, @@ -20482,13 +20528,6 @@ /obj/effect/decal/cleanable/cobweb, /turf/open/floor/iron/smooth, /area/station/maintenance/department/science/xenobiology) -"fbu" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "fbA" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -21528,6 +21567,23 @@ /obj/structure/chair/office, /turf/open/floor/iron/grimy, /area/station/tcommsat/computer) +"fnN" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/airlock/mining{ + name = "Mining Dock" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/all/supply/mining, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "foh" = ( /obj/machinery/atmospherics/components/binary/volume_pump{ name = "Ports to Distro" @@ -21781,6 +21837,19 @@ }, /turf/open/floor/iron, /area/station/commons/locker) +"fsg" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/door/airlock/mining{ + name = "Mining Dock" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/all/supply/mining, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "fsl" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -21962,14 +22031,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/grimy, /area/station/service/library) -"ftS" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "ftU" = ( /obj/structure/cable, /obj/effect/turf_decal/siding/yellow, @@ -22145,6 +22206,11 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron/dark, /area/station/science/xenobiology) +"fwD" = ( +/obj/structure/table, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "fwK" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -22406,14 +22472,6 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/station/engineering/storage) -"fAj" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "fAn" = ( /obj/machinery/holopad, /obj/effect/turf_decal/bot, @@ -22566,6 +22624,12 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/iron/dark, /area/station/hallway/secondary/entry) +"fCb" = ( +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "fCf" = ( /obj/machinery/door/poddoor/preopen{ id = "atmoslock"; @@ -23090,6 +23154,11 @@ }, /turf/open/floor/iron/large, /area/station/security/checkpoint/escape) +"fJm" = ( +/obj/effect/landmark/start/shaft_miner, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "fJq" = ( /turf/closed/wall, /area/station/security/brig) @@ -23863,6 +23932,13 @@ /obj/effect/spawner/random/maintenance, /turf/open/floor/iron/grimy, /area/station/service/abandoned_gambling_den) +"fUl" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/conveyor{ + id = "cargodisposals" + }, +/turf/open/floor/plating, +/area/station/cargo/sorting) "fUq" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line{ @@ -23886,12 +23962,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/commons/fitness/recreation) -"fUr" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell{ - dir = 8 - }, -/turf/open/floor/iron/dark/textured_large, -/area/station/medical/cryo) "fUF" = ( /obj/structure/table/reinforced, /obj/structure/window/reinforced/spawner/directional/east, @@ -24333,6 +24403,14 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/engineering/atmos/project) +"fZz" = ( +/obj/effect/landmark/start/shaft_miner, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "fZG" = ( /obj/effect/turf_decal/stripes/corner, /obj/effect/turf_decal/stripes/corner{ @@ -24578,11 +24656,6 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics) -"gco" = ( -/obj/structure/cable, -/obj/effect/turf_decal/tile/brown/half/contrasted, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "gcr" = ( /obj/effect/turf_decal/tile/neutral/half/contrasted, /turf/open/floor/iron, @@ -24717,6 +24790,11 @@ /obj/machinery/light/small/dim/directional/north, /turf/open/floor/plating, /area/station/maintenance/department/security) +"gdD" = ( +/obj/structure/closet/secure_closet/miner, +/obj/effect/turf_decal/delivery, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "gdE" = ( /obj/structure/chair/office, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -25941,6 +26019,11 @@ }, /turf/open/floor/iron/dark/corner, /area/station/engineering/atmos/pumproom) +"grT" = ( +/obj/structure/cable, +/obj/effect/turf_decal/tile/brown/half/contrasted, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "grV" = ( /obj/effect/turf_decal/arrows/red{ dir = 4; @@ -26123,11 +26206,6 @@ }, /turf/open/floor/iron, /area/station/commons/storage/primary) -"guj" = ( -/obj/effect/landmark/start/shaft_miner, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "gum" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -26916,6 +26994,9 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron/cafeteria, /area/station/security/prison/mess) +"gDE" = ( +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "gDP" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -27167,6 +27248,12 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai_monitored/aisat/exterior) +"gGM" = ( +/obj/effect/turf_decal/tile/purple/half/contrasted{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "gGT" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/toilet{ @@ -28159,6 +28246,13 @@ }, /turf/open/floor/iron, /area/station/service/abandoned_gambling_den/gaming) +"gUe" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/maintenance/starboard/fore) "gUi" = ( /obj/effect/turf_decal/stripes/red/line{ dir = 10 @@ -29335,12 +29429,6 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron/white/smooth_large, /area/station/medical/medbay) -"hkn" = ( -/obj/structure/filingcabinet/chestdrawer, -/obj/effect/turf_decal/delivery, -/obj/machinery/airalarm/directional/south, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "hkt" = ( /obj/effect/spawner/random/engineering/tank, /turf/open/floor/plating, @@ -30357,13 +30445,6 @@ }, /turf/open/floor/glass/reinforced, /area/station/maintenance/department/science/xenobiology) -"hzs" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "hzx" = ( /obj/machinery/firealarm/directional/west, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -32924,6 +33005,16 @@ /obj/item/stack/rods/fifty, /turf/open/floor/plating, /area/station/maintenance/department/eva/abandoned) +"ihc" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "iho" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -32985,13 +33076,6 @@ }, /turf/open/floor/plating, /area/station/medical/virology) -"iio" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "iiy" = ( /obj/structure/easel, /turf/open/floor/iron, @@ -34242,16 +34326,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/hallway/secondary/entry) -"izj" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "izo" = ( /obj/structure/table/wood, /obj/item/gavelblock, @@ -35944,6 +36018,13 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"iWJ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "iWR" = ( /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 8 @@ -35978,14 +36059,6 @@ }, /turf/open/floor/iron, /area/station/engineering/lobby) -"iXd" = ( -/obj/effect/landmark/start/shaft_miner, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "iXj" = ( /obj/effect/landmark/start/hangover, /obj/effect/turf_decal/bot, @@ -36808,11 +36881,6 @@ /obj/structure/sign/warning/secure_area/directional/west, /turf/open/floor/plating, /area/station/engineering/atmos/mix) -"jfO" = ( -/obj/structure/table, -/obj/effect/turf_decal/bot, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "jfP" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -37113,6 +37181,21 @@ dir = 8 }, /area/station/hallway/primary/port) +"jjK" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/structure/sign/nanotrasen{ + pixel_y = 32 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "jjU" = ( /obj/effect/turf_decal/tile/neutral/half/contrasted, /turf/open/floor/iron, @@ -37970,6 +38053,19 @@ "jtC" = ( /turf/open/floor/plating, /area/station/service/abandoned_gambling_den) +"jtE" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/machinery/firealarm/directional/east, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/light/small/directional/east, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "jtV" = ( /obj/structure/sign/warning/electric_shock, /turf/closed/wall/r_wall, @@ -38518,13 +38614,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/science/lobby) -"jBM" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "jCb" = ( /obj/machinery/computer/records/security{ dir = 8 @@ -38608,13 +38697,6 @@ /obj/item/pen, /turf/open/floor/wood, /area/station/service/library/abandoned) -"jCu" = ( -/obj/machinery/computer/order_console/mining, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/directional/north, -/obj/effect/turf_decal/bot, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "jCv" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/hydroponics/constructable, @@ -38657,6 +38739,17 @@ /obj/effect/mapping_helpers/airlock/access/all/service/lawyer, /turf/open/floor/iron, /area/station/service/lawoffice) +"jCR" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/conveyor{ + id = "cargodisposals" + }, +/obj/effect/mapping_helpers/burnt_floor, +/turf/open/floor/plating, +/area/station/cargo/sorting) "jCS" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -39262,14 +39355,6 @@ /obj/effect/turf_decal/tile/blue/opposingcorners, /turf/open/floor/iron/white, /area/station/command/heads_quarters/cmo) -"jKY" = ( -/obj/structure/cable, -/obj/effect/turf_decal/bot, -/obj/structure/table, -/obj/item/storage/medkit/regular, -/obj/machinery/power/apc/auto_name/directional/west, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "jLa" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/railing{ @@ -39852,11 +39937,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white, /area/station/medical/medbay) -"jRc" = ( -/obj/machinery/power/apc/auto_name/directional/north, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/maintenance/starboard/fore) "jRg" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, @@ -40091,6 +40171,23 @@ "jUx" = ( /turf/open/floor/plating, /area/station/maintenance/department/science) +"jUy" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/door/airlock/mining/glass{ + name = "Delivery Office" + }, +/obj/effect/mapping_helpers/airlock/access/any/supply/shipping, +/obj/effect/mapping_helpers/airlock/access/any/supply/mining, +/turf/open/floor/iron, +/area/station/cargo/sorting) "jUC" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -41946,6 +42043,11 @@ "ksK" = ( /turf/closed/wall/r_wall, /area/station/command/gateway) +"ksL" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "ksP" = ( /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible{ dir = 4 @@ -42423,6 +42525,13 @@ /obj/effect/turf_decal/tile/neutral/full, /turf/open/floor/iron/large, /area/station/ai_monitored/command/storage/eva) +"kzi" = ( +/obj/structure/closet/secure_closet/miner, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/delivery, +/obj/machinery/status_display/evac/directional/north, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "kzm" = ( /obj/structure/disposalpipe/sorting/mail/flip{ dir = 4; @@ -43152,12 +43261,6 @@ /obj/structure/sign/warning/pods, /turf/closed/wall, /area/station/hallway/secondary/entry) -"kKx" = ( -/obj/effect/turf_decal/loading_area{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "kKy" = ( /obj/machinery/airalarm/directional/east, /obj/machinery/rnd/production/techfab/department/medical, @@ -43784,11 +43887,6 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron/dark, /area/station/engineering/main) -"kTs" = ( -/obj/structure/closet/secure_closet/miner, -/obj/effect/turf_decal/delivery, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "kTy" = ( /obj/structure/chair/office{ dir = 8 @@ -45088,13 +45186,6 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/general, /turf/open/floor/iron, /area/station/maintenance/solars/starboard/fore) -"ljQ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/loading_area{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "ljS" = ( /obj/structure/cable, /obj/effect/spawner/structure/window/reinforced, @@ -45234,13 +45325,6 @@ /obj/machinery/light/directional/west, /turf/open/floor/iron, /area/station/hallway/primary/starboard) -"llj" = ( -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "llm" = ( /obj/structure/chair/office/tactical{ dir = 8 @@ -45818,6 +45902,16 @@ /obj/effect/turf_decal/tile/blue/fourcorners, /turf/open/floor/iron, /area/station/medical/treatment_center) +"ltB" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "ltD" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/simple/yellow/visible, @@ -46489,6 +46583,22 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/engineering/storage) +"lBB" = ( +/obj/structure/rack, +/obj/effect/decal/cleanable/dirt, +/obj/item/storage/toolbox/emergency{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/storage/toolbox/emergency, +/obj/item/shovel, +/obj/item/shovel, +/obj/item/pickaxe, +/obj/item/pickaxe, +/obj/effect/turf_decal/bot, +/obj/machinery/light/small/directional/south, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "lBG" = ( /obj/structure/cable, /obj/effect/spawner/structure/window/reinforced, @@ -48503,6 +48613,16 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/carpet/orange, /area/station/commons/dorms) +"mcK" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "mcV" = ( /obj/machinery/door/airlock/engineering/glass{ name = "Supermatter Engine Room" @@ -49104,14 +49224,6 @@ "mlE" = ( /turf/closed/wall/r_wall, /area/station/ai_monitored/command/storage/eva) -"mlF" = ( -/obj/item/kirbyplants/random, -/obj/structure/sign/poster/official/random/directional/west, -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "mlM" = ( /obj/structure/table/wood, /obj/machinery/computer/records/medical/laptop, @@ -49658,13 +49770,6 @@ /obj/effect/turf_decal/tile/yellow/fourcorners, /turf/open/floor/iron, /area/station/engineering/storage) -"mtL" = ( -/obj/structure/closet/secure_closet/miner, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery, -/obj/machinery/status_display/evac/directional/north, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "mtO" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/tile/yellow{ @@ -50418,10 +50523,6 @@ /obj/structure/cable, /turf/open/floor/engine, /area/station/maintenance/disposal/incinerator) -"mDm" = ( -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "mDo" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -52654,11 +52755,6 @@ /obj/effect/spawner/random/trash/hobo_squat, /turf/open/floor/plating, /area/station/maintenance/department/chapel) -"nhj" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "nhm" = ( /turf/closed/wall/r_wall, /area/station/maintenance/starboard/lesser) @@ -53185,6 +53281,11 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/security/courtroom) +"nos" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/starboard/fore) "not" = ( /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -53397,6 +53498,11 @@ }, /turf/open/floor/iron, /area/station/security/warden) +"nro" = ( +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/starboard/fore) "nry" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, @@ -53477,6 +53583,16 @@ }, /turf/open/floor/iron/dark, /area/station/maintenance/port) +"nsI" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "nsV" = ( /obj/structure/table/reinforced, /obj/structure/reagent_dispensers/wall/peppertank/directional/west, @@ -54379,12 +54495,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron, /area/station/maintenance/port) -"nEE" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "nEJ" = ( /obj/structure/cable, /obj/effect/turf_decal/trimline/yellow/line, @@ -55494,6 +55604,12 @@ /obj/item/storage/medkit/regular, /turf/open/floor/iron, /area/station/commons/fitness/recreation) +"nTw" = ( +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/purple/half/contrasted, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "nTz" = ( /obj/item/stack/sheet/plasteel/twenty, /obj/item/stack/sheet/rglass{ @@ -55703,6 +55819,22 @@ /obj/effect/turf_decal/tile/red/fourcorners, /turf/open/floor/iron/dark, /area/station/security/lockers) +"nXf" = ( +/obj/machinery/door/firedoor, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/airlock/mining/glass{ + name = "Delivery Office" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/mapping_helpers/airlock/access/any/supply/mining, +/obj/effect/mapping_helpers/airlock/access/any/supply/shipping, +/turf/open/floor/iron, +/area/station/cargo/sorting) "nXj" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -56241,6 +56373,14 @@ /obj/structure/closet, /turf/open/floor/plating, /area/station/maintenance/fore) +"oea" = ( +/obj/structure/closet/wardrobe/miner, +/obj/effect/decal/cleanable/dirt, +/obj/item/storage/backpack/satchel/explorer, +/obj/effect/turf_decal/bot, +/obj/item/radio/intercom/directional/south, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "oec" = ( /obj/effect/spawner/structure/window/reinforced/tinted, /turf/open/floor/plating/airless, @@ -56360,6 +56500,12 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos/mix) +"ofM" = ( +/obj/effect/turf_decal/tile/purple/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "ofN" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/conveyor{ @@ -56511,6 +56657,14 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"ohR" = ( +/obj/structure/cable, +/obj/structure/extinguisher_cabinet/directional/west, +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "ohZ" = ( /obj/structure/rack, /obj/effect/spawner/random/techstorage/service_all, @@ -56751,13 +56905,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/security/prison/garden) -"okN" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "okV" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/reagent_dispensers/plumbed{ @@ -56911,6 +57058,10 @@ }, /turf/open/floor/iron, /area/station/cargo/storage) +"oml" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "omv" = ( /obj/structure/table, /obj/item/flashlight/lamp, @@ -57617,14 +57768,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/maintenance/port) -"owZ" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/obj/effect/turf_decal/tile/purple/half/contrasted, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "oxb" = ( /obj/machinery/duct, /obj/effect/turf_decal/siding/white, @@ -57868,16 +58011,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/grimy, /area/station/command/heads_quarters/captain/private) -"oAV" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/effect/turf_decal/tile/brown/half/contrasted, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "oAW" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -59429,6 +59562,9 @@ /obj/machinery/newscaster/directional/east, /turf/open/floor/wood, /area/station/hallway/secondary/service) +"oWV" = ( +/turf/closed/wall, +/area/station/cargo/miningoffice) "oXi" = ( /obj/effect/turf_decal/bot_white/left, /obj/effect/turf_decal/tile/neutral{ @@ -61441,9 +61577,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/hallway/secondary/exit/departure_lounge) -"pxS" = ( -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "pxT" = ( /obj/effect/spawner/random/structure/crate, /turf/open/floor/plating, @@ -61909,13 +62042,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) -"pDy" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell{ - dir = 8 - }, -/obj/machinery/status_display/ai/directional/south, -/turf/open/floor/iron/dark/textured_large, -/area/station/medical/cryo) "pDE" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -63510,16 +63636,6 @@ }, /turf/open/floor/iron/dark/corner, /area/station/engineering/atmos/pumproom) -"pUs" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "pUw" = ( /obj/machinery/holopad, /obj/effect/turf_decal/bot, @@ -64739,22 +64855,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/command/bridge) -"qko" = ( -/obj/structure/table, -/obj/effect/decal/cleanable/dirt, -/obj/item/clipboard, -/obj/item/toy/figure/miner, -/obj/machinery/light/directional/north, -/obj/machinery/light_switch/directional/west{ - pixel_x = -42 - }, -/obj/effect/turf_decal/bot, -/obj/machinery/firealarm/directional/west, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "qkv" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -64911,19 +65011,6 @@ }, /turf/open/floor/plating, /area/station/engineering/supermatter/room) -"qmT" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/maintenance/starboard/fore) "qnc" = ( /obj/machinery/firealarm/directional/south, /obj/effect/turf_decal/tile/blue{ @@ -65351,14 +65438,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/science/xenobiology) -"qsF" = ( -/obj/structure/cable, -/obj/structure/extinguisher_cabinet/directional/west, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "qsN" = ( /obj/structure/chair{ dir = 4 @@ -65786,6 +65865,13 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/security/execution/transfer) +"qyO" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "qyX" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -68277,15 +68363,6 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) -"rgC" = ( -/obj/structure/cable, -/obj/structure/table/reinforced, -/obj/effect/decal/cleanable/dirt, -/obj/item/folder/yellow, -/obj/item/gps/mining, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "rgG" = ( /obj/structure/closet/secure_closet/engineering_personal, /obj/effect/decal/cleanable/dirt, @@ -68918,23 +68995,6 @@ /obj/machinery/light/dim/directional/east, /turf/open/floor/iron/dark, /area/station/tcommsat/computer) -"rmH" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/mining{ - name = "Mining Dock" - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "rmI" = ( /obj/structure/table/reinforced, /obj/item/electronics/apc, @@ -69913,13 +69973,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron, /area/station/cargo/storage) -"rAl" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/conveyor{ - id = "cargodisposals" - }, -/turf/open/floor/plating, -/area/station/cargo/sorting) "rAm" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/tile/yellow/half/contrasted{ @@ -70624,6 +70677,15 @@ /obj/machinery/atmospherics/pipe/smart/simple/yellow/visible, /turf/open/floor/plating, /area/station/engineering/atmos/mix) +"rKu" = ( +/obj/structure/cable, +/obj/structure/table/reinforced, +/obj/effect/decal/cleanable/dirt, +/obj/item/folder/yellow, +/obj/item/gps/mining, +/obj/effect/turf_decal/tile/brown/anticorner/contrasted, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "rKA" = ( /obj/machinery/firealarm/directional/east, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -71218,14 +71280,6 @@ /obj/structure/mirror/directional/west, /turf/open/floor/wood, /area/station/maintenance/port/aft) -"rQF" = ( -/obj/structure/closet/wardrobe/miner, -/obj/effect/decal/cleanable/dirt, -/obj/item/storage/backpack/satchel/explorer, -/obj/effect/turf_decal/bot, -/obj/item/radio/intercom/directional/south, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "rQI" = ( /obj/machinery/airlock_sensor/incinerator_atmos{ pixel_x = 24 @@ -72524,11 +72578,6 @@ }, /turf/open/space/basic, /area/space) -"sgK" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/event_spawn, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "sgZ" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -73006,6 +73055,13 @@ }, /turf/open/floor/iron/white, /area/station/science/research) +"snh" = ( +/obj/machinery/computer/order_console/mining, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/directional/north, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "snj" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/decal/cleanable/dirt, @@ -73406,14 +73462,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/medical/pharmacy) -"stf" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "stp" = ( /obj/machinery/airalarm/directional/west, /obj/effect/turf_decal/trimline/brown/filled/line{ @@ -73792,6 +73840,14 @@ /obj/item/papercutter, /turf/open/floor/iron/grimy, /area/station/command/bridge) +"sxu" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/effect/turf_decal/tile/purple/half/contrasted, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "sxD" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -74222,22 +74278,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/half, /area/station/service/hydroponics) -"sCW" = ( -/obj/machinery/door/firedoor, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/mining/glass{ - name = "Delivery Office" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/mapping_helpers/airlock/access/any/supply/mining, -/obj/effect/mapping_helpers/airlock/access/any/supply/shipping, -/turf/open/floor/iron, -/area/station/cargo/sorting) "sCY" = ( /obj/structure/cable, /obj/machinery/power/tracker, @@ -74921,11 +74961,6 @@ /obj/structure/sign/poster/official/build/directional/north, /turf/open/floor/iron, /area/station/science/robotics/mechbay) -"sLg" = ( -/obj/machinery/rnd/bepis, -/obj/effect/turf_decal/box/white, -/turf/open/floor/iron, -/area/station/cargo/storage) "sLx" = ( /obj/effect/decal/cleanable/generic, /turf/open/floor/iron/grimy, @@ -76059,6 +76094,12 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/service/chapel) +"taR" = ( +/obj/machinery/cryo_cell{ + dir = 8 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/medical/cryo) "tbd" = ( /obj/item/radio/intercom/directional/west, /obj/effect/turf_decal/tile/yellow/half/contrasted{ @@ -76190,10 +76231,6 @@ /obj/machinery/light/directional/south, /turf/open/floor/iron, /area/station/engineering/supermatter/room) -"tcB" = ( -/obj/effect/decal/cleanable/oil, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "tcG" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -76894,16 +76931,6 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/hallway/primary/central/aft) -"toy" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "toB" = ( /obj/machinery/light/directional/west, /obj/effect/turf_decal/stripes/line{ @@ -78958,26 +78985,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/science/server) -"tNn" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/requests_console/directional/south{ - department = "Mining"; - name = "Mining Requests Console" - }, -/obj/machinery/requests_console/directional/south{ - department = "Mining"; - name = "Mining Requests Console" - }, -/obj/machinery/camera/directional/south{ - c_tag = "Cargo - Mining Dock"; - name = "cargo camera" - }, -/obj/effect/turf_decal/tile/brown/half/contrasted, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "tNq" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -79292,6 +79299,17 @@ dir = 1 }, /area/station/service/bar) +"tQr" = ( +/obj/structure/table, +/obj/machinery/microwave{ + desc = "Cooks and boils stuff, somehow."; + pixel_x = -3; + pixel_y = 5 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "tQt" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -81479,12 +81497,6 @@ }, /turf/open/floor/wood, /area/station/command/heads_quarters/hop) -"usJ" = ( -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "usZ" = ( /obj/item/flashlight/lamp, /obj/machinery/airalarm/directional/east, @@ -82116,6 +82128,15 @@ /obj/effect/turf_decal/tile/red, /turf/open/floor/iron, /area/station/security/execution/transfer) +"uAH" = ( +/obj/structure/cable, +/obj/structure/chair/office{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/purple/half/contrasted, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "uAI" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/landmark/start/depsec/engineering, @@ -82160,21 +82181,6 @@ dir = 1 }, /area/station/medical/morgue) -"uBd" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/structure/sign/nanotrasen{ - pixel_y = 32 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "uBf" = ( /obj/machinery/atmospherics/pipe/smart/manifold/purple/visible{ dir = 4 @@ -83164,18 +83170,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/commons/storage/primary) -"uND" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery, -/turf/open/floor/iron, -/area/station/maintenance/starboard/fore) "uNE" = ( /obj/machinery/atmospherics/components/unary/passive_vent{ dir = 4 @@ -83222,15 +83216,6 @@ }, /turf/open/floor/iron/white, /area/station/science/ordnance/office) -"uOk" = ( -/obj/structure/cable, -/obj/structure/chair/office{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/purple/half/contrasted, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "uOn" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -86041,6 +86026,13 @@ }, /turf/open/floor/wood, /area/station/service/library/abandoned) +"vyF" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/start/shaft_miner, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "vyG" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -86117,6 +86109,18 @@ /obj/structure/sign/warning/secure_area/directional/north, /turf/open/space, /area/space/nearstation) +"vzy" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/delivery, +/turf/open/floor/iron, +/area/station/maintenance/starboard/fore) "vzA" = ( /obj/effect/turf_decal/trimline/purple/filled/line, /turf/open/floor/iron/white, @@ -86450,12 +86454,6 @@ /obj/effect/turf_decal/tile/neutral/half/contrasted, /turf/open/floor/iron, /area/station/command/heads_quarters/hos) -"vDj" = ( -/obj/structure/cable, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/purple/half/contrasted, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "vDm" = ( /obj/effect/turf_decal/siding/wood{ dir = 1 @@ -86840,16 +86838,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/department/security) -"vId" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "vIq" = ( /obj/structure/cable, /obj/structure/disposalpipe/junction{ @@ -87187,15 +87175,6 @@ }, /turf/open/floor/iron, /area/station/security/checkpoint/engineering) -"vNV" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "vOh" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -87429,6 +87408,12 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/iron/dark, /area/station/service/bar) +"vQT" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "vRn" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /obj/structure/railing/corner, @@ -88536,23 +88521,6 @@ /obj/effect/landmark/start/depsec/medical, /turf/open/floor/iron/large, /area/station/security/checkpoint/medical/medsci) -"whb" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/door/airlock/mining/glass{ - name = "Delivery Office" - }, -/obj/effect/mapping_helpers/airlock/access/any/supply/shipping, -/obj/effect/mapping_helpers/airlock/access/any/supply/mining, -/turf/open/floor/iron, -/area/station/cargo/sorting) "whc" = ( /obj/structure/sign/poster/official/fruit_bowl/directional/west, /obj/effect/turf_decal/stripes/line{ @@ -88958,6 +88926,13 @@ }, /turf/open/floor/glass, /area/station/maintenance/space_hut/observatory) +"wml" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "wmn" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 8 @@ -89203,6 +89178,14 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"woJ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "woK" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -89576,6 +89559,13 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/starboard) +"wsJ" = ( +/obj/machinery/cryo_cell{ + dir = 8 + }, +/obj/machinery/status_display/ai/directional/south, +/turf/open/floor/iron/dark/textured_large, +/area/station/medical/cryo) "wsN" = ( /obj/machinery/door/airlock/command{ name = "Research Division Server Room" @@ -89746,19 +89736,6 @@ }, /turf/open/floor/iron/white, /area/station/science/ordnance/storage) -"wuU" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/machinery/firealarm/directional/east, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/machinery/light/small/directional/east, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "wuV" = ( /obj/structure/fireaxecabinet/directional/south, /obj/effect/turf_decal/tile/blue/half/contrasted, @@ -89987,6 +89964,11 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"wxL" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/event_spawn, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "wyh" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -90364,6 +90346,14 @@ /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, /area/station/maintenance/department/engine/atmos) +"wCA" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "wCB" = ( /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible, /obj/effect/turf_decal/stripes/line{ @@ -91942,6 +91932,14 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/security/lockers) +"xaN" = ( +/obj/structure/cable, +/obj/effect/turf_decal/bot, +/obj/structure/table, +/obj/item/storage/medkit/regular, +/obj/machinery/power/apc/auto_name/directional/west, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "xaP" = ( /obj/effect/turf_decal/tile/neutral{ dir = 8 @@ -95073,15 +95071,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) -"xMZ" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "xNe" = ( /obj/structure/lattice, /obj/structure/grille/broken, @@ -95637,12 +95626,6 @@ /obj/structure/barricade/wooden, /turf/open/floor/plating, /area/station/service/abandoned_gambling_den) -"xVv" = ( -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "xVI" = ( /obj/structure/rack, /obj/item/analyzer, @@ -96190,6 +96173,15 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/iron, /area/station/science/robotics/mechbay) +"ydr" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "ydE" = ( /obj/structure/chair/stool/directional/south, /obj/effect/decal/cleanable/dirt, @@ -96579,6 +96571,14 @@ }, /turf/open/floor/iron/white, /area/station/science/lab) +"yiG" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple/half/contrasted, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "yiK" = ( /obj/item/kirbyplants/organic/plant21, /obj/effect/turf_decal/delivery, @@ -138788,7 +138788,7 @@ hoC yfI bGf kGo -sCW +nXf xhW ygL xhW @@ -139541,7 +139541,7 @@ kRn kjl lDi lDi -sLg +eKS bqv hDZ bfT @@ -139629,9 +139629,9 @@ cwe ltS cwe oDE -fUr +taR bcj -pDy +wsJ oDE ajY tJh @@ -139811,7 +139811,7 @@ mOe yhh liD mZU -whb +jUy uBZ pso sqW @@ -140328,8 +140328,8 @@ gLz xhW axz fOz -rAl -bkr +fUl +jCR yfo qLp pcx @@ -140591,8 +140591,8 @@ xhW xhW xhW xhW -uBd -wuU +jjK +jtE vPp tJT qzY @@ -140840,13 +140840,13 @@ uSp oSv cFz rWo -qko -vNV -pxS -xMZ -mlF -qsF -jKY +ctR +ydr +gDE +dsq +atk +ohR +xaN tpZ lDY tpZ @@ -141096,16 +141096,16 @@ qaF tQW hQj uzM -aPD -stf -llj -mDm -fbu -mDm -vDj -cwd +fsg +eIA +dtp +cQO +wml +cQO +nTw +lBB tpZ -qmT +dri tpZ aaa aad @@ -141353,16 +141353,16 @@ rbV qLg uTu tQP -rmH -toy -izj -fAj -pUs -okN -oAV -vId +fnN +mcK +ltB +wCA +nsI +cze +ihc +bNi qyX -uND +vzy tpZ aaa lhY @@ -141612,14 +141612,14 @@ cSK pok rWo llJ -kKx -dux -tcB -nEE -cyc -rQF +fCb +vyF +dih +vQT +yiG +oea tpZ -eFU +nos tpZ aad lhY @@ -141868,15 +141868,15 @@ fKA krp krp aJE -mtL -kKx -iXd -eYt -hzs -tNn -cGV +kzi +fCb +fZz +oml +qyO +eld +oWV tpZ -jRc +nro tpZ aaa lhY @@ -142125,15 +142125,15 @@ jmp iWR gkP krp -kTs -ljQ -guj -eYt -nhj -owZ -bLN +gdD +iWJ +fJm +oml +ksL +sxu +aSj tpZ -elO +gUe tpZ aaa lhY @@ -142382,15 +142382,15 @@ xPf xZC aiF aJE -jCu -iio -mDm -sgK -mDm -gco -hkn +snh +dIz +cQO +wxL +cQO +grT +aLg tpZ -cwK +dcA tpZ aaa lhY @@ -142639,12 +142639,12 @@ osw qZD qrG aJE -dPC -usJ -nhj -mDm -mDm -uOk +tQr +gGM +ksL +cQO +cQO +uAH bhJ tpZ tpZ @@ -142896,12 +142896,12 @@ uQZ xhJ vMd tgX -jfO -jBM -xVv -ftS -dXs -rgC +fwD +dRf +ofM +woJ +aWe +rKu tDD rWo aad diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index f3ff89fcc80..5ae6d741a2a 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -2960,12 +2960,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) -"aVE" = ( -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/station/cargo/miningdock) "aVF" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /obj/effect/turf_decal/tile/red{ @@ -4456,12 +4450,6 @@ }, /turf/open/floor/iron/dark, /area/mine/storage) -"bsx" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "bsG" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/research/glass{ @@ -5224,6 +5212,20 @@ /obj/item/storage/box/monkeycubes, /turf/open/floor/iron, /area/station/science/xenobiology) +"bCM" = ( +/obj/machinery/requests_console/directional/north{ + department = "Cargo Bay"; + name = "Cargo Bay Requests Console" + }, +/obj/effect/mapping_helpers/requests_console/supplies, +/obj/structure/table, +/obj/item/hand_labeler, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/item/folder/yellow, +/turf/open/floor/iron, +/area/station/cargo/storage) "bCQ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, @@ -7182,6 +7184,12 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) +"cfR" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "cfS" = ( /obj/item/clothing/suit/costume/snowman{ name = "Man of Snow" @@ -9395,6 +9403,16 @@ /obj/effect/mapping_helpers/airlock/access/all/security/brig, /turf/open/floor/iron/dark/textured, /area/station/security/lockers) +"cLI" = ( +/obj/structure/rack, +/obj/item/shovel{ + pixel_x = -5 + }, +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "cLJ" = ( /obj/structure/table/wood, /obj/item/paper{ @@ -10033,6 +10051,11 @@ }, /turf/open/floor/iron, /area/station/security/prison/garden) +"cWr" = ( +/obj/effect/landmark/start/shaft_miner, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "cWG" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -10697,10 +10720,6 @@ }, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/underground/explored) -"dgf" = ( -/obj/machinery/firealarm/directional/north, -/turf/open/floor/iron, -/area/station/cargo/storage) "dgl" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 8 @@ -12261,6 +12280,11 @@ /obj/effect/turf_decal/tile/blue/half/contrasted, /turf/open/floor/iron, /area/station/command/bridge) +"dEJ" = ( +/obj/machinery/light_switch/directional/north, +/obj/machinery/light/directional/north, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "dEQ" = ( /obj/machinery/camera/directional/east{ c_tag = "Public Mining Ladder" @@ -12890,13 +12914,6 @@ /obj/effect/turf_decal/tile/dark_blue/diagonal_edge, /turf/open/floor/iron/dark/diagonal, /area/station/engineering/atmos/storage) -"dPn" = ( -/obj/structure/rack, -/obj/item/pickaxe{ - pixel_x = 5 - }, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "dPy" = ( /obj/machinery/camera/directional/west{ c_tag = "Xenobiology Kill Chamber"; @@ -13174,13 +13191,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/freezer, /area/mine/laborcamp) -"dUK" = ( -/obj/machinery/camera/directional/west{ - c_tag = "Mining Dock" - }, -/obj/machinery/computer/security/mining, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "dUL" = ( /obj/machinery/door/poddoor/preopen{ id = "maint1" @@ -13209,15 +13219,6 @@ /obj/structure/sign/poster/random/directional/east, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"dVs" = ( -/obj/structure/table, -/obj/item/paper_bin{ - pixel_x = 1; - pixel_y = 9 - }, -/obj/machinery/mining_weather_monitor/directional/west, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "dVt" = ( /obj/structure/chair/stool/directional/west, /turf/open/floor/iron/checker, @@ -14878,11 +14879,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron, /area/station/maintenance/department/medical/central) -"ewq" = ( -/obj/machinery/light_switch/directional/north, -/obj/machinery/light/directional/north, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "ewz" = ( /obj/structure/window/reinforced/spawner/directional/east, /obj/structure/window/reinforced/spawner/directional/north, @@ -15930,6 +15926,13 @@ }, /turf/open/floor/iron/white, /area/station/science/research) +"eNM" = ( +/obj/machinery/cryo_cell, +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/turf/open/floor/iron/dark/textured, +/area/station/medical/cryo) "eNQ" = ( /obj/structure/sign/warning/vacuum/directional/south, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -16861,10 +16864,6 @@ /obj/item/seeds/apple, /turf/open/floor/iron, /area/mine/laborcamp) -"feB" = ( -/obj/machinery/airalarm/directional/east, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "feJ" = ( /turf/closed/wall/r_wall, /area/station/ai_monitored/security/armory/upper) @@ -18953,12 +18952,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/green/visible, /turf/open/floor/engine, /area/station/engineering/supermatter/room) -"fNx" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "fNy" = ( /obj/structure/rack, /obj/item/clothing/suit/hooded/wintercoat{ @@ -20952,6 +20945,13 @@ /obj/structure/window/reinforced/spawner/directional/south, /turf/open/floor/iron, /area/station/science/xenobiology) +"gvZ" = ( +/obj/machinery/rnd/bepis, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "gwm" = ( /obj/machinery/door/firedoor/heavy, /turf/open/floor/iron/white/side{ @@ -20992,6 +20992,17 @@ }, /turf/open/floor/iron/cafeteria, /area/station/commons/dorms/laundry) +"gwB" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/mining{ + name = "Mining Dock" + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/mapping_helpers/airlock/access/all/supply/mining, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "gwJ" = ( /obj/effect/turf_decal/stripes/asteroid/line{ dir = 5 @@ -21146,12 +21157,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/aisat_interior) -"gzN" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "gzV" = ( /obj/structure/mineral_door/paperframe{ name = "Meditation Room" @@ -24199,6 +24204,13 @@ /obj/effect/turf_decal/tile/blue/full, /turf/open/floor/iron/large, /area/station/medical/treatment_center) +"hxC" = ( +/obj/structure/rack, +/obj/item/pickaxe{ + pixel_x = 5 + }, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "hxE" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -28356,6 +28368,15 @@ dir = 1 }, /area/station/service/hydroponics) +"iNu" = ( +/obj/structure/table, +/obj/item/paper_bin{ + pixel_x = 1; + pixel_y = 9 + }, +/obj/machinery/mining_weather_monitor/directional/west, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "iNy" = ( /obj/structure/chair{ dir = 4 @@ -29599,6 +29620,12 @@ /obj/structure/tank_holder/extinguisher, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) +"jiK" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "jjk" = ( /obj/structure/lattice/catwalk, /obj/structure/railing{ @@ -31736,7 +31763,7 @@ "jRB" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/table_frame, -/obj/item/wirerod, +/obj/item/melee/baton/security/cattleprod, /obj/effect/spawner/random/maintenance, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) @@ -33544,13 +33571,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) -"krx" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell, -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/open/floor/iron/dark/textured, -/area/station/medical/cryo) "kry" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -34148,6 +34168,14 @@ /obj/effect/spawner/random/structure/grille, /turf/open/floor/plating, /area/station/maintenance/department/chapel) +"kAq" = ( +/obj/machinery/cryo_cell, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/item/radio/intercom/directional/east, +/turf/open/floor/iron/dark/textured, +/area/station/medical/cryo) "kAC" = ( /obj/structure/reagent_dispensers/watertank, /obj/effect/decal/cleanable/cobweb/cobweb2, @@ -34772,6 +34800,10 @@ /obj/structure/sign/poster/official/random/directional/north, /turf/open/floor/iron/smooth, /area/mine/laborcamp/security) +"kJz" = ( +/obj/machinery/firealarm/directional/east, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "kJI" = ( /obj/structure/transit_tube/station/reverse, /turf/open/floor/plating, @@ -35228,11 +35260,6 @@ /obj/structure/sign/warning/bodysposal/directional/south, /turf/open/floor/iron/white, /area/station/medical/surgery/aft) -"kQL" = ( -/obj/machinery/power/apc/auto_name/directional/north, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "kQM" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 5 @@ -36893,6 +36920,13 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) +"lqt" = ( +/obj/structure/table, +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "lqz" = ( /obj/structure/cable, /turf/closed/wall, @@ -37024,14 +37058,6 @@ }, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/aisat/service) -"lti" = ( -/obj/structure/table, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 8 - }, -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "ltk" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 @@ -40328,6 +40354,11 @@ /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) +"mwF" = ( +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "mwQ" = ( /obj/structure/tank_holder/extinguisher, /turf/open/floor/plating, @@ -41950,6 +41981,15 @@ /obj/machinery/light/built/directional/east, /turf/open/floor/iron/white, /area/station/maintenance/port/fore) +"mZt" = ( +/obj/structure/closet/crate, +/obj/item/radio/intercom/directional/east, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/light/small/directional/north, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "mZu" = ( /obj/structure/table/glass, /obj/item/cultivator, @@ -42037,16 +42077,6 @@ /obj/machinery/light/directional/north, /turf/open/floor/iron, /area/station/engineering/storage) -"naO" = ( -/obj/structure/rack, -/obj/item/shovel{ - pixel_x = -5 - }, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "naP" = ( /obj/structure/chair/comfy/black{ dir = 4 @@ -43765,17 +43795,6 @@ }, /turf/closed/wall/r_wall, /area/station/engineering/transit_tube) -"nyB" = ( -/obj/structure/table, -/obj/item/folder/yellow, -/obj/item/pen, -/obj/machinery/requests_console/directional/west{ - department = "Mining"; - name = "Mining Requests Console" - }, -/obj/effect/mapping_helpers/requests_console/supplies, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "nyC" = ( /turf/open/floor/iron/dark/smooth_half, /area/station/service/chapel) @@ -44806,17 +44825,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/science/research) -"nMB" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/mining{ - name = "Mining Dock" - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "nME" = ( /obj/item/clothing/head/utility/hardhat, /turf/open/floor/plating/snowed/icemoon, @@ -48145,6 +48153,14 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/iron/dark, /area/station/engineering/supermatter/room) +"oOa" = ( +/obj/structure/table, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "oOb" = ( /obj/structure/sign/warning/fire/directional/north, /turf/open/floor/glass/reinforced, @@ -48595,11 +48611,6 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/iron/freezer, /area/station/commons/toilet) -"oVf" = ( -/obj/effect/landmark/start/shaft_miner, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "oVt" = ( /obj/machinery/power/apc/auto_name/directional/south, /obj/structure/cable, @@ -49546,14 +49557,6 @@ }, /turf/open/floor/iron/smooth_large, /area/station/cargo/warehouse) -"piX" = ( -/obj/machinery/camera/directional/north{ - c_tag = "Cargo Bay North" - }, -/obj/machinery/vending/wardrobe/cargo_wardrobe, -/obj/machinery/light/directional/north, -/turf/open/floor/iron, -/area/station/cargo/storage) "pja" = ( /obj/structure/rack, /obj/item/pickaxe, @@ -49779,6 +49782,13 @@ /obj/structure/flora/grass/brown/style_random, /turf/open/misc/asteroid/snow/standard_air, /area/station/science/research) +"pnr" = ( +/obj/structure/chair/office{ + dir = 8 + }, +/obj/effect/landmark/start/shaft_miner, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "pnz" = ( /obj/item/radio/intercom/directional/west, /turf/open/floor/iron, @@ -51952,20 +51962,6 @@ }, /turf/open/floor/iron, /area/station/tcommsat/computer) -"pVC" = ( -/obj/machinery/requests_console/directional/north{ - department = "Cargo Bay"; - name = "Cargo Bay Requests Console" - }, -/obj/effect/mapping_helpers/requests_console/supplies, -/obj/structure/table, -/obj/item/hand_labeler, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/item/folder/yellow, -/turf/open/floor/iron, -/area/station/cargo/storage) "pVH" = ( /turf/closed/wall/mineral/wood, /area/station/maintenance/aft/lesser) @@ -53418,14 +53414,6 @@ /obj/machinery/light/directional/north, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/underground/explored) -"qtT" = ( -/obj/machinery/door/airlock/mining/glass{ - name = "Mining Dock" - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "que" = ( /obj/machinery/camera/directional/south{ c_tag = "Chapel South" @@ -54424,10 +54412,6 @@ /obj/item/cigbutt, /turf/open/floor/wood/large, /area/mine/eva/lower) -"qJJ" = ( -/obj/machinery/firealarm/directional/east, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "qJT" = ( /obj/machinery/light/small/directional/south, /turf/open/floor/plating/snowed/icemoon, @@ -54897,6 +54881,12 @@ "qPL" = ( /turf/closed/wall/r_wall, /area/station/hallway/secondary/exit/departure_lounge) +"qPR" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "qPX" = ( /obj/structure/sink/directional/west, /obj/structure/mirror/directional/east, @@ -55412,15 +55402,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) -"qYc" = ( -/obj/structure/closet/crate, -/obj/item/radio/intercom/directional/east, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/light/small/directional/north, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "qYh" = ( /obj/structure/chair/pew{ dir = 1 @@ -55538,6 +55519,12 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron/textured, /area/mine/mechbay) +"qZY" = ( +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/station/cargo/miningdock) "rab" = ( /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plating, @@ -57206,6 +57193,14 @@ /obj/item/stack/license_plates/empty/fifty, /turf/open/floor/iron/dark/smooth_half, /area/station/security/prison/work) +"rBz" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Mining Dock" + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/all/supply/mining, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "rBL" = ( /obj/machinery/light/directional/west, /turf/open/openspace, @@ -59421,14 +59416,6 @@ /obj/effect/turf_decal/tile/yellow/opposingcorners, /turf/open/floor/iron/dark, /area/station/engineering/atmos/project) -"slK" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/obj/item/radio/intercom/directional/east, -/turf/open/floor/iron/dark/textured, -/area/station/medical/cryo) "slX" = ( /obj/structure/fans/tiny, /obj/effect/turf_decal/stripes/red/box, @@ -62895,13 +62882,6 @@ /obj/item/key/janitor, /turf/open/floor/iron, /area/station/service/janitor) -"tqC" = ( -/obj/structure/table, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "tqQ" = ( /obj/effect/turf_decal/stripes/corner{ dir = 1 @@ -63421,13 +63401,6 @@ /obj/structure/chair/office, /turf/open/floor/wood, /area/station/service/library) -"tyH" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/landmark/event_spawn, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "tyK" = ( /obj/item/mop, /obj/item/reagent_containers/cup/bucket, @@ -64482,6 +64455,10 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/engineering/atmos/mix) +"tOz" = ( +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "tOF" = ( /obj/structure/chair/comfy/black{ dir = 8 @@ -64857,6 +64834,13 @@ /obj/structure/table, /turf/open/floor/plating/snowed/coldroom, /area/station/service/kitchen/coldroom) +"tWF" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/landmark/event_spawn, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "tWK" = ( /obj/structure/cable, /turf/open/floor/plating/snowed/icemoon, @@ -66129,6 +66113,17 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, /area/station/science/research) +"use" = ( +/obj/structure/table, +/obj/item/folder/yellow, +/obj/item/pen, +/obj/machinery/requests_console/directional/west{ + department = "Mining"; + name = "Mining Requests Console" + }, +/obj/effect/mapping_helpers/requests_console/supplies, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "uso" = ( /obj/structure/closet/crate/trashcart, /obj/effect/spawner/random/contraband/prison, @@ -68315,13 +68310,6 @@ }, /turf/open/floor/iron/grimy, /area/station/security/prison/work) -"veh" = ( -/obj/machinery/rnd/bepis, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "vek" = ( /obj/effect/turf_decal/weather/snow/corner, /obj/machinery/light/small/directional/north, @@ -68476,10 +68464,6 @@ /obj/effect/turf_decal/trimline/blue/filled/line, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) -"vgC" = ( -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "vgD" = ( /obj/structure/rack, /obj/item/stack/sheet/iron/fifty, @@ -68513,6 +68497,10 @@ /obj/machinery/firealarm/directional/north, /turf/open/floor/iron/dark, /area/station/service/chapel) +"vhn" = ( +/obj/machinery/firealarm/directional/north, +/turf/open/floor/iron, +/area/station/cargo/storage) "vhr" = ( /mob/living/simple_animal/hostile/retaliate/goat{ atmos_requirements = list("min_oxy"=1,"max_oxy"=0,"min_plas"=0,"max_plas"=1,"min_co2"=0,"max_co2"=5,"min_n2"=0,"max_n2"=0); @@ -68712,6 +68700,10 @@ /obj/structure/sign/poster/random/directional/west, /turf/open/floor/iron/large, /area/station/service/kitchen/diner) +"vlu" = ( +/obj/machinery/airalarm/directional/east, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "vlI" = ( /obj/effect/turf_decal/siding/white{ dir = 4 @@ -70969,13 +70961,6 @@ /obj/item/book/bible, /turf/open/floor/iron/chapel, /area/station/service/chapel) -"vWV" = ( -/obj/structure/chair/office{ - dir = 8 - }, -/obj/effect/landmark/start/shaft_miner, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "vWW" = ( /obj/effect/turf_decal/tile/neutral/opposingcorners, /turf/open/floor/iron, @@ -72717,6 +72702,14 @@ /obj/effect/mapping_helpers/airlock/access/all/service/lawyer, /turf/open/floor/wood, /area/station/service/lawoffice) +"wxd" = ( +/obj/machinery/camera/directional/north{ + c_tag = "Cargo Bay North" + }, +/obj/machinery/vending/wardrobe/cargo_wardrobe, +/obj/machinery/light/directional/north, +/turf/open/floor/iron, +/area/station/cargo/storage) "wxg" = ( /turf/open/floor/iron/freezer, /area/mine/laborcamp) @@ -72799,6 +72792,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/port/greater) +"wyv" = ( +/obj/machinery/camera/directional/west{ + c_tag = "Mining Dock" + }, +/obj/machinery/computer/security/mining, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "wyB" = ( /obj/machinery/conveyor{ dir = 1; @@ -74860,12 +74860,6 @@ /obj/structure/cable, /turf/open/floor/iron/white, /area/station/medical/storage) -"xdz" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "xdA" = ( /obj/effect/turf_decal/siding/white{ dir = 4 @@ -75935,6 +75929,12 @@ }, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"xuh" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "xun" = ( /obj/machinery/door/poddoor/massdriver_chapel, /obj/structure/fans/tiny, @@ -229061,8 +229061,8 @@ xqX bCQ wBb tKI -veh -gzN +gvZ +jiK ajw ajw mmi @@ -229318,8 +229318,8 @@ sIM yjn wBb tKI -pVC -xdz +bCM +qPR kXs ajw mmi @@ -229832,7 +229832,7 @@ nAr nAr wNR tKI -piX +wxd ajw ajw ajw @@ -230363,7 +230363,7 @@ pYT maT bln qjQ -aVE +qZY qxb nrm hoD @@ -230878,7 +230878,7 @@ bln bln bln qjQ -qYc +mZt hxE xtr qjQ @@ -231128,7 +231128,7 @@ kXr kXr kXr kXr -dgf +vhn ajw kXr bln @@ -231386,15 +231386,15 @@ lZQ wXR qjQ aOd -qtT +rBz aOd qjQ qjQ qjQ -tqC -lti +lqt +oOa jBf -naO +cLI qjQ sEB sEB @@ -231642,16 +231642,16 @@ oDt kRU oQa qjQ -kQL -vgC +mwF +tOz hoD -dVs -nyB -dUK +iNu +use +wyv hoD hoD hxE -dPn +hxC aOd bln bln @@ -231899,12 +231899,12 @@ uxl oRy aHC qjQ -ewq -oVf +dEJ +cWr hoD hoD -vWV -fNx +pnr +cfR hoD iVA hxE @@ -232155,10 +232155,10 @@ mOA cHb psW psW -nMB +gwB hxE hxE -tyH +tWF hxE hxE hxE @@ -232414,9 +232414,9 @@ rLu nRq aOd hoD -bsx +xuh hoD -qJJ +kJz hxE hoD hoD @@ -232675,7 +232675,7 @@ lNG nZh tue hxE -feB +vlu lis aud lis @@ -250147,7 +250147,7 @@ oyy amE wyj klc -krx +eNM ufN vCz ufN @@ -250661,7 +250661,7 @@ qhN amE lei klc -slK +kAq hXU oRu hIe diff --git a/_maps/map_files/KiloStation2/KiloStation2.dmm b/_maps/map_files/KiloStation2/KiloStation2.dmm index 8e20d8b305b..aefa21efb19 100644 --- a/_maps/map_files/KiloStation2/KiloStation2.dmm +++ b/_maps/map_files/KiloStation2/KiloStation2.dmm @@ -7412,7 +7412,7 @@ /turf/open/misc/asteroid/airless, /area/space/nearstation) "cuj" = ( -/mob/living/simple_animal/hostile/asteroid/hivelord, +/mob/living/basic/mining/hivelord, /turf/open/misc/asteroid/airless, /area/space/nearstation) "cup" = ( @@ -23697,7 +23697,7 @@ /turf/open/floor/iron/dark, /area/station/hallway/secondary/entry) "hHg" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell{ +/obj/machinery/cryo_cell{ dir = 4 }, /obj/effect/turf_decal/delivery, @@ -29122,7 +29122,7 @@ /obj/structure/table, /obj/effect/decal/cleanable/cobweb/cobweb2, /obj/item/storage/toolbox/emergency, -/obj/item/wirerod, +/obj/item/melee/baton/security/cattleprod, /obj/machinery/light/small/directional/north, /obj/item/radio/intercom/directional/east, /turf/open/floor/iron/dark, @@ -29946,7 +29946,7 @@ /area/station/command/bridge) "jBO" = ( /obj/effect/turf_decal/bot, -/obj/machinery/atmospherics/components/unary/cryo_cell{ +/obj/machinery/cryo_cell{ dir = 4 }, /obj/effect/turf_decal/tile/neutral/half/contrasted{ @@ -39033,7 +39033,7 @@ /obj/item/wirecutters{ pixel_y = 5 }, -/obj/item/wirerod, +/obj/item/melee/baton/security/cattleprod, /obj/effect/turf_decal/bot, /turf/open/floor/iron/dark, /area/station/security/interrogation) @@ -69836,7 +69836,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 }, -/mob/living/simple_animal/hostile/asteroid/hivelord, +/mob/living/basic/mining/hivelord, /turf/open/floor/plating, /area/station/cargo/warehouse) "wpw" = ( @@ -70490,7 +70490,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/mob/living/simple_animal/hostile/asteroid/hivelord, +/mob/living/basic/mining/hivelord, /turf/open/floor/plating, /area/station/cargo/warehouse) "wAz" = ( @@ -75260,7 +75260,7 @@ /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai_upload) "ycp" = ( -/mob/living/simple_animal/hostile/asteroid/hivelord, +/mob/living/basic/mining/hivelord, /turf/open/misc/asteroid/lowpressure, /area/space/nearstation) "ycr" = ( diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index cfa13aef72e..ebcfba29362 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -3334,13 +3334,6 @@ /obj/structure/extinguisher_cabinet/directional/north, /turf/open/floor/iron, /area/station/hallway/primary/starboard) -"bje" = ( -/obj/structure/closet/emcloset, -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "bjl" = ( /obj/machinery/rnd/production/techfab/department/service, /obj/effect/turf_decal/trimline/brown/warning{ @@ -4523,12 +4516,6 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/fore) -"bDS" = ( -/obj/structure/chair/office/light, -/obj/structure/cable, -/obj/item/stamp/head/cmo, -/turf/open/floor/iron/white, -/area/station/command/heads_quarters/cmo) "bDW" = ( /turf/closed/wall, /area/station/maintenance/department/engine) @@ -4674,18 +4661,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"bGM" = ( -/obj/machinery/door/airlock/mining{ - name = "Mining Office" - }, -/obj/machinery/door/firedoor, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/obj/effect/landmark/navigate_destination, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "bHb" = ( /obj/effect/turf_decal/siding/wood{ dir = 1 @@ -7192,14 +7167,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/security/brig) -"cGL" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/sorting/mail/flip{ - dir = 1 - }, -/obj/effect/mapping_helpers/mail_sorting/supply/disposals, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "cGV" = ( /obj/machinery/air_sensor/plasma_tank, /turf/open/floor/engine/plasma, @@ -9293,10 +9260,6 @@ }, /turf/open/floor/iron/cafeteria, /area/station/engineering/atmos) -"dwA" = ( -/obj/structure/disposalpipe/segment, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "dwJ" = ( /obj/structure/lattice, /obj/effect/spawner/random/structure/grille, @@ -9553,6 +9516,13 @@ /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating/airless, /area/station/solars/starboard/fore) +"dDR" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "dDZ" = ( /obj/machinery/door/airlock/external{ name = "Common Mining Dock" @@ -10961,14 +10931,6 @@ /obj/docking_port/stationary/escape_pod, /turf/open/space/basic, /area/space) -"edo" = ( -/obj/structure/table/glass, -/obj/item/paper_bin, -/obj/item/clipboard, -/obj/item/toy/figure/cmo, -/obj/structure/cable, -/turf/open/floor/iron/white, -/area/station/command/heads_quarters/cmo) "edq" = ( /obj/machinery/light/small/directional/west, /obj/structure/cable, @@ -11025,15 +10987,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/station/cargo/sorting) -"edP" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "edQ" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -12233,6 +12186,13 @@ /obj/structure/cable, /turf/open/floor/iron/freezer, /area/station/security/prison/shower) +"exq" = ( +/obj/effect/decal/cleanable/blood/tracks{ + dir = 4 + }, +/obj/effect/spawner/random/structure/grille, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "exr" = ( /obj/structure/table/wood, /obj/item/paper_bin{ @@ -12458,11 +12418,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/aft) -"eEb" = ( -/obj/structure/cable, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "eEf" = ( /obj/machinery/camera/directional/north{ c_tag = "Bar - Backroom" @@ -14975,13 +14930,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) -"fBl" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "fBo" = ( /obj/machinery/door/window/left/directional/north{ dir = 8; @@ -15624,14 +15572,6 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron/white, /area/station/science/explab) -"fNH" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Mining Dock Maintenance" - }, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "fNI" = ( /obj/structure/sign/poster/contraband/random/directional/east, /turf/open/floor/wood, @@ -16653,6 +16593,11 @@ /obj/machinery/vending/wardrobe/jani_wardrobe, /turf/open/floor/iron, /area/station/service/janitor) +"gjY" = ( +/obj/structure/reagent_dispensers/fueltank, +/obj/structure/sign/poster/contraband/random/directional/north, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "gjZ" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 8 @@ -17321,12 +17266,6 @@ "guX" = ( /turf/closed/wall, /area/station/commons/storage/primary) -"guZ" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "gva" = ( /obj/effect/turf_decal/delivery, /turf/open/floor/iron, @@ -18437,12 +18376,6 @@ /obj/machinery/atmospherics/pipe/smart/simple/yellow/visible, /turf/open/space/basic, /area/space/nearstation) -"gQv" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "gQw" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/white/line, @@ -20978,6 +20911,11 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/station/maintenance/aft/lesser) +"hNS" = ( +/obj/structure/cable, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "hOh" = ( /obj/effect/turf_decal/trimline/red/filled/line, /obj/effect/turf_decal/trimline/brown/filled/warning, @@ -21668,6 +21606,13 @@ /obj/machinery/seed_extractor, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) +"iaA" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "iaK" = ( /obj/effect/turf_decal/tile/yellow/half/contrasted, /obj/machinery/light/directional/south, @@ -23164,6 +23109,12 @@ /obj/effect/spawner/random/techstorage/medical_all, /turf/open/floor/iron/dark, /area/station/engineering/storage/tech) +"izi" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "izl" = ( /obj/machinery/duct, /obj/structure/disposalpipe/segment{ @@ -23338,6 +23289,14 @@ /obj/machinery/holopad, /turf/open/floor/wood, /area/station/service/cafeteria) +"iBx" = ( +/obj/machinery/vending/wardrobe/cargo_wardrobe, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron, +/area/station/cargo/storage) "iBL" = ( /obj/structure/table/wood, /turf/open/floor/wood, @@ -24178,6 +24137,10 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/security/brig) +"iPY" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "iQd" = ( /obj/machinery/door/poddoor/shutters{ id = "supplybridge" @@ -25904,14 +25867,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/engineering/storage/tech) -"jty" = ( -/obj/machinery/vending/wardrobe/cargo_wardrobe, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 8 - }, -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron, -/area/station/cargo/storage) "jtA" = ( /obj/structure/table/glass, /obj/effect/turf_decal/siding/white{ @@ -28302,6 +28257,13 @@ /obj/effect/mapping_helpers/airlock/access/all/service/crematorium, /turf/open/floor/plating, /area/station/maintenance/aft/greater) +"khX" = ( +/obj/structure/reagent_dispensers/watertank, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "khZ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -29617,13 +29579,6 @@ /obj/structure/window/reinforced/spawner/directional/west, /turf/open/floor/engine, /area/station/science/explab) -"kHU" = ( -/obj/structure/reagent_dispensers/watertank, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "kIG" = ( /obj/structure/rack, /obj/effect/spawner/random/maintenance/two, @@ -32795,11 +32750,6 @@ /obj/vehicle/sealed/mecha/ripley/cargo, /turf/open/floor/plating, /area/station/cargo/warehouse) -"lUe" = ( -/obj/structure/reagent_dispensers/fueltank, -/obj/structure/sign/poster/contraband/random/directional/north, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "lUj" = ( /obj/structure/table, /obj/item/book/manual/wiki/security_space_law{ @@ -33538,6 +33488,14 @@ }, /turf/open/floor/iron/white, /area/station/medical/storage) +"mhx" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/sorting/mail/flip{ + dir = 1 + }, +/obj/effect/mapping_helpers/mail_sorting/supply/disposals, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "mhA" = ( /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/west, @@ -34559,12 +34517,6 @@ /obj/structure/window/spawner/directional/south, /turf/open/floor/iron/white, /area/station/security/prison/mess) -"mzs" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "mzu" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -34620,13 +34572,6 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/iron/dark, /area/station/hallway/primary/port) -"mAy" = ( -/obj/machinery/computer/order_console/mining, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "mAJ" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -38013,6 +37958,15 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/commons/locker) +"nFq" = ( +/obj/machinery/door/airlock/mining{ + name = "Mining Office" + }, +/obj/structure/cable, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/all/supply/mining, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "nFL" = ( /obj/machinery/camera/directional/north{ c_tag = "MiniSat Exterior - Fore"; @@ -38316,6 +38270,18 @@ /obj/structure/flora/bush/flowers_br/style_random, /turf/open/floor/grass, /area/station/maintenance/starboard/aft) +"nMk" = ( +/obj/machinery/door/airlock/mining{ + name = "Mining Office" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment, +/obj/effect/mapping_helpers/airlock/access/all/supply/mining, +/obj/effect/landmark/navigate_destination, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "nMz" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/table, @@ -38331,13 +38297,6 @@ /obj/effect/turf_decal/tile/neutral/opposingcorners, /turf/open/floor/iron, /area/station/commons/vacant_room/commissary) -"nME" = ( -/obj/structure/rack, -/obj/effect/decal/cleanable/cobweb/cobweb2, -/obj/item/storage/toolbox/emergency, -/obj/effect/spawner/random/maintenance, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "nMF" = ( /obj/machinery/light/small/directional/east, /obj/machinery/firealarm/directional/east, @@ -40002,6 +39961,11 @@ "otu" = ( /turf/closed/wall, /area/station/service/chapel) +"oty" = ( +/obj/structure/chair/office/light, +/obj/structure/cable, +/turf/open/floor/iron/white, +/area/station/command/heads_quarters/cmo) "otG" = ( /obj/item/radio/intercom/directional/east, /obj/structure/window/spawner/directional/north, @@ -41003,6 +40967,15 @@ "oKU" = ( /turf/open/floor/circuit/green/telecomms/mainframe, /area/station/tcommsat/server) +"oLc" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "oLD" = ( /obj/structure/chair/comfy/beige, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -41100,6 +41073,11 @@ /obj/effect/turf_decal/tile/yellow/full, /turf/open/floor/iron/white/smooth_large, /area/station/medical/chemistry) +"oNz" = ( +/obj/structure/cable, +/obj/effect/landmark/event_spawn, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "oNP" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -43380,6 +43358,14 @@ /obj/machinery/light/cold/directional/north, /turf/open/floor/plating, /area/station/security/prison/work) +"pEZ" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Mining Dock Maintenance" + }, +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/access/all/supply/mining, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "pFd" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -45121,11 +45107,6 @@ }, /turf/open/floor/iron/dark, /area/station/command/bridge) -"qlr" = ( -/obj/structure/cable, -/obj/effect/landmark/event_spawn, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "qlG" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 1 @@ -46240,7 +46221,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /turf/open/floor/iron/dark/textured, /area/station/medical/cryo) "qIS" = ( @@ -46729,6 +46710,13 @@ /obj/structure/marker_beacon/indigo, /turf/open/space/basic, /area/space/nearstation) +"qPt" = ( +/obj/effect/spawner/random/structure/crate, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "qPC" = ( /obj/structure/cable, /obj/machinery/door/airlock/virology/glass{ @@ -46950,6 +46938,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/commons/storage/primary) +"qSD" = ( +/obj/machinery/rnd/bepis, +/obj/effect/turf_decal/stripes/end{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "qSP" = ( /obj/machinery/atmospherics/pipe/smart/manifold/purple/visible{ dir = 1 @@ -48053,6 +48048,13 @@ /obj/effect/turf_decal/tile/purple/opposingcorners, /turf/open/floor/iron, /area/station/science/research) +"rnM" = ( +/obj/item/clothing/gloves/color/rainbow, +/obj/item/clothing/shoes/sneakers/rainbow, +/obj/item/clothing/under/color/rainbow, +/obj/item/clothing/head/soft/rainbow, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "rnX" = ( /obj/machinery/suit_storage_unit/standard_unit, /obj/machinery/firealarm/directional/east, @@ -49531,13 +49533,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"rNV" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "rOz" = ( /obj/effect/spawner/random/structure/crate, /turf/open/floor/plating, @@ -49773,13 +49768,6 @@ }, /turf/open/floor/plating, /area/station/service/chapel) -"rSa" = ( -/obj/effect/decal/cleanable/blood/tracks{ - dir = 4 - }, -/obj/effect/spawner/random/structure/grille, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "rSi" = ( /obj/effect/landmark/start/chief_engineer, /obj/structure/chair/office/light{ @@ -54072,13 +54060,6 @@ /obj/structure/cable, /turf/open/floor/iron/cafeteria, /area/station/service/kitchen) -"ttG" = ( -/obj/item/clothing/gloves/color/rainbow, -/obj/item/clothing/shoes/sneakers/rainbow, -/obj/item/clothing/under/color/rainbow, -/obj/item/clothing/head/soft/rainbow, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "ttM" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -57266,13 +57247,6 @@ /obj/effect/turf_decal/tile/red/half/contrasted, /turf/open/floor/iron/dark, /area/station/security/execution/education) -"uyj" = ( -/obj/machinery/rnd/bepis, -/obj/effect/turf_decal/stripes/end{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "uyr" = ( /obj/item/radio/intercom/directional/east, /obj/structure/disposalpipe/segment, @@ -58643,6 +58617,17 @@ /obj/effect/turf_decal/bot/left, /turf/open/floor/engine, /area/station/engineering/atmospherics_engine) +"uWy" = ( +/obj/structure/table/glass, +/obj/item/paper_bin, +/obj/item/clipboard, +/obj/item/toy/figure/cmo, +/obj/structure/cable, +/obj/item/stamp/head/cmo{ + pixel_x = -9 + }, +/turf/open/floor/iron/white, +/area/station/command/heads_quarters/cmo) "uWA" = ( /obj/structure/table/wood/fancy/royalblue, /obj/machinery/door/window{ @@ -59760,13 +59745,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/hallway/primary/central) -"vpU" = ( -/obj/effect/spawner/random/structure/crate, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "vpX" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -60517,6 +60495,13 @@ /obj/item/tail_pin, /turf/open/space/basic, /area/space/nearstation) +"vDq" = ( +/obj/structure/closet/emcloset, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "vDt" = ( /obj/machinery/door/airlock/maintenance{ name = "Research Maintenance" @@ -62258,6 +62243,13 @@ }, /turf/open/floor/iron, /area/station/security/checkpoint/supply) +"wfY" = ( +/obj/structure/rack, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/item/storage/toolbox/emergency, +/obj/effect/spawner/random/maintenance, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "wfZ" = ( /obj/machinery/airalarm/directional/east, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -63745,7 +63737,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /turf/open/floor/iron/dark/textured, /area/station/medical/cryo) "wKu" = ( @@ -64856,15 +64848,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white/side, /area/station/science/lobby) -"xdY" = ( -/obj/machinery/door/airlock/mining{ - name = "Mining Office" - }, -/obj/structure/cable, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "xel" = ( /obj/structure/closet/firecloset, /turf/open/floor/plating, @@ -65410,16 +65393,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/science/genetics) -"xoc" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Mining Dock Maintenance" - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "xor" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/cable, @@ -65634,6 +65607,12 @@ }, /turf/open/floor/iron, /area/station/commons/fitness/recreation) +"xsQ" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "xsV" = ( /obj/machinery/door/firedoor, /obj/machinery/door/poddoor/shutters/preopen{ @@ -66534,6 +66513,12 @@ }, /turf/open/floor/plating, /area/station/maintenance/aft/greater) +"xHQ" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "xIp" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/landmark/event_spawn, @@ -66743,6 +66728,16 @@ /obj/structure/cable, /turf/open/floor/wood, /area/station/service/cafeteria) +"xMP" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Mining Dock Maintenance" + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment, +/obj/effect/mapping_helpers/airlock/access/all/supply/mining, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "xMX" = ( /obj/effect/turf_decal/stripes/corner, /obj/structure/cable, @@ -66853,6 +66848,13 @@ }, /turf/open/floor/plating/airless, /area/station/science/ordnance/bomb) +"xOL" = ( +/obj/machinery/computer/order_console/mining, +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "xOO" = ( /obj/machinery/status_display/evac/directional/east, /obj/structure/cable, @@ -84975,8 +84977,8 @@ hxo hxo hxo cbz -uyj -jty +qSD +iBx jLb tTa kQP @@ -85208,11 +85210,11 @@ gYE lBm qKy ybN -edP -dwA -bje +oLc +iPY +vDq jXu -ttG +rnM jXu pPh aFd @@ -85465,9 +85467,9 @@ iPE vfv cTQ xte -mzs +izi sHu -kHU +khX jXu jXu jXu @@ -85723,9 +85725,9 @@ uEC wgw twr uuD -qlr -fBl -eEb +oNz +iaA +hNS jXu ouc dSG @@ -85733,7 +85735,7 @@ cLj xYl cLj mUz -xdY +nFq rgN mmR mmR @@ -85978,19 +85980,19 @@ wvR pQu vEH jXu -lUe +gjY uuD -rNV -cGL -guZ -xoc +dDR +mhx +xsQ +xMP xyz xyz kdC btt aqx shx -bGM +nMk fiC dAk rhn @@ -86235,13 +86237,13 @@ vhU eNU aQE jXu -nME +wfY iUE -gQv +xHQ jXu jXu jXu -mAy +xOL cLj kRe aFd @@ -86494,7 +86496,7 @@ jXu jXu jXu uuD -gQv +xHQ jXu fhn jXu @@ -86751,12 +86753,12 @@ xxp twr sxn uuD -vpU +qPt twr -rSa +exq jXu jXu -fNH +pEZ jXu jXu jXu @@ -92217,8 +92219,8 @@ jhk cOR vgZ ijZ -bDS -edo +oty +uWy pXM iNc bqX diff --git a/_maps/map_files/NSSJourney/NSSJourney.dmm b/_maps/map_files/NSSJourney/NSSJourney.dmm index 19299f10006..bbe26804454 100644 --- a/_maps/map_files/NSSJourney/NSSJourney.dmm +++ b/_maps/map_files/NSSJourney/NSSJourney.dmm @@ -1472,6 +1472,7 @@ }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/mapping_helpers/airlock/access/any/security/general, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/station/security/brig) "akV" = ( @@ -20993,7 +20994,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 6 }, -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /turf/open/floor/iron/dark, /area/station/medical/cryo) "bBn" = ( @@ -21842,7 +21843,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /turf/open/floor/iron/dark, /area/station/medical/cryo) "bEc" = ( @@ -23065,6 +23066,13 @@ /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/mapping_helpers/airlock/access/any/medical/virology, +/obj/machinery/door_buttons/access_button{ + idDoor = "virology_airlock_exterior"; + idSelf = "virology_airlock_control"; + name = "Virology Access Button"; + req_access = list("virology"); + pixel_x = -24 + }, /turf/open/floor/iron, /area/station/medical/virology) "bHZ" = ( @@ -25275,6 +25283,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/mapping_helpers/airlock/access/any/medical/virology, +/obj/machinery/door_buttons/access_button{ + idDoor = "virology_airlock_interior"; + idSelf = "virology_airlock_control"; + name = "Virology Access Button"; + pixel_x = -24; + req_access = list("virology"); + pixel_y = 6 + }, /turf/open/floor/iron, /area/station/medical/virology) "bQJ" = ( @@ -25549,13 +25565,14 @@ /obj/effect/turf_decal/trimline/green/filled/line{ dir = 9 }, -/obj/machinery/door_buttons/access_button{ - idDoor = "virology_airlock_interior"; +/obj/machinery/door_buttons/airlock_controller{ + idExterior = "virology_airlock_exterior"; + idInterior = "virology_airlock_interior"; idSelf = "virology_airlock_control"; - name = "Virology Access Button"; - pixel_x = 8; - req_access = list("virology"); - pixel_y = 24 + name = "Virology Access Console"; + pixel_x = 7; + pixel_y = 26; + req_access = list("virology") }, /turf/open/floor/iron/white, /area/station/medical/virology) @@ -31870,7 +31887,7 @@ "cwy" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/table_frame, -/obj/item/wirerod, +/obj/item/melee/baton/security/cattleprod, /obj/effect/spawner/random/maintenance, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) @@ -37829,15 +37846,6 @@ dir = 10 }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/door_buttons/airlock_controller{ - idExterior = "virology_airlock_exterior"; - idInterior = "virology_airlock_interior"; - idSelf = "virology_airlock_control"; - name = "Virology Access Console"; - pixel_x = 7; - pixel_y = -26; - req_access = list("virology") - }, /turf/open/floor/iron/white, /area/station/medical/virology) "fSb" = ( @@ -58921,14 +58929,6 @@ dir = 10 }, /obj/item/kirbyplants/random, -/obj/machinery/door_buttons/access_button{ - idDoor = "virology_airlock_exterior"; - idSelf = "virology_airlock_control"; - name = "Virology Access Button"; - req_access = list("virology"); - pixel_y = -24; - pixel_x = 8 - }, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) "yck" = ( diff --git a/_maps/map_files/NorthStar/north_star.dmm b/_maps/map_files/NorthStar/north_star.dmm index d9fff1d8af0..53e9e0a8d54 100644 --- a/_maps/map_files/NorthStar/north_star.dmm +++ b/_maps/map_files/NorthStar/north_star.dmm @@ -318,6 +318,12 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/catwalk_floor/iron_dark, /area/station/maintenance/floor2/port) +"ads" = ( +/obj/effect/turf_decal/stripes{ + dir = 9 + }, +/turf/open/floor/plating, +/area/station/maintenance/floor1/starboard/fore) "adB" = ( /obj/structure/closet/crate/bin{ name = "biowaste bin" @@ -1730,6 +1736,22 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/wood, /area/station/medical/psychology) +"avu" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 4 + }, +/obj/machinery/door/airlock/hatch{ + name = "Maintenance Access" + }, +/obj/effect/mapping_helpers/airlock/access/any/supply/general, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/pod/dark, +/area/station/maintenance/floor1/starboard/fore) "avH" = ( /obj/structure/table/glass, /obj/item/experi_scanner, @@ -2975,6 +2997,13 @@ }, /turf/open/floor/iron/dark/textured, /area/station/commons/fitness) +"aOv" = ( +/obj/effect/turf_decal/stripes{ + dir = 10 + }, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/plating, +/area/station/maintenance/floor1/starboard/fore) "aOx" = ( /obj/machinery/griddle, /obj/machinery/airalarm/directional/west, @@ -3463,6 +3492,11 @@ /obj/effect/mapping_helpers/airlock/access/any/medical/psychology, /turf/open/floor/catwalk_floor, /area/station/hallway/floor2/fore) +"aUn" = ( +/obj/effect/spawner/random/structure/table_or_rack, +/obj/effect/spawner/random/trash/soap, +/turf/open/floor/pod/light, +/area/station/maintenance/floor1/starboard/fore) "aUG" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/spawner/random/structure/table_or_rack, @@ -3716,6 +3750,12 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/carpet/purple, /area/station/maintenance/floor1/port/aft) +"aXl" = ( +/obj/machinery/cryo_cell{ + dir = 4 + }, +/turf/open/floor/iron/dark/textured, +/area/station/medical/cryo) "aXq" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -5398,6 +5438,18 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/iron/white, /area/station/science/xenobiology/hallway) +"bqm" = ( +/obj/machinery/door/firedoor/border_only{ + dir = 1 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/floor1/starboard/fore) "bqn" = ( /obj/structure/closet/crate, /obj/item/reagent_containers/cup/bowl, @@ -5544,13 +5596,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white, /area/station/science/robotics/lab) -"brL" = ( -/obj/effect/turf_decal/stripes{ - dir = 6 - }, -/obj/structure/disposalpipe/segment, -/turf/open/floor/plating, -/area/station/maintenance/floor1/starboard/fore) "brN" = ( /obj/effect/spawner/structure/window/hollow/reinforced/directional, /obj/structure/disposalpipe/segment, @@ -5571,10 +5616,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/medical/abandoned) -"bsq" = ( -/obj/effect/turf_decal/stripes, -/turf/open/floor/plating, -/area/station/maintenance/floor1/starboard/fore) "bsu" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -6346,15 +6387,6 @@ dir = 4 }, /area/station/hallway/floor3/aft) -"bAh" = ( -/obj/machinery/door/firedoor/border_only{ - dir = 1 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/catwalk_floor, -/area/station/maintenance/floor1/starboard/fore) "bAj" = ( /obj/machinery/conveyor{ dir = 9; @@ -8910,6 +8942,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/smooth, /area/station/construction) +"cjz" = ( +/obj/machinery/door/firedoor/border_only{ + dir = 8 + }, +/obj/machinery/firealarm/directional/east, +/obj/machinery/firealarm/directional/east, +/turf/open/floor/pod/light, +/area/station/maintenance/floor1/starboard/fore) "cjB" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/decal/cleanable/dirt, @@ -9963,6 +10003,17 @@ }, /turf/open/floor/engine, /area/station/engineering/atmos/hfr_room) +"cxp" = ( +/obj/machinery/exoscanner, +/obj/effect/turf_decal/stripes{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/obj/structure/extinguisher_cabinet/directional/west, +/turf/open/floor/iron/corner, +/area/station/cargo/drone_bay) "cxx" = ( /obj/effect/turf_decal/tile/green/half{ dir = 4 @@ -10205,14 +10256,6 @@ }, /turf/open/floor/engine/vacuum, /area/station/science/ordnance/freezerchamber) -"cBT" = ( -/obj/machinery/door/firedoor/border_only{ - dir = 8 - }, -/obj/machinery/firealarm/directional/east, -/obj/machinery/firealarm/directional/east, -/turf/open/floor/pod/light, -/area/station/maintenance/floor1/starboard/fore) "cBU" = ( /obj/structure/window/reinforced/spawner/directional/west, /obj/structure/flora/bush/sunny/style_random, @@ -10321,12 +10364,6 @@ /obj/machinery/chem_master, /turf/open/floor/iron/dark/textured, /area/station/medical/pharmacy) -"cDe" = ( -/obj/effect/turf_decal/stripes{ - dir = 1 - }, -/turf/open/floor/plating, -/area/station/maintenance/floor1/starboard/fore) "cDh" = ( /obj/item/broken_bottle, /turf/open/floor/carpet/neon/simple/pink/nodots, @@ -13156,7 +13193,7 @@ /area/station/maintenance/floor3/port/fore) "dss" = ( /obj/effect/mapping_helpers/broken_floor, -/obj/item/wirerod, +/obj/item/melee/baton/security/cattleprod, /turf/open/floor/plating, /area/station/maintenance/floor1/port/aft) "dsv" = ( @@ -14644,6 +14681,15 @@ /obj/effect/landmark/start/captain, /turf/open/floor/wood/tile, /area/station/command/heads_quarters/captain/private) +"dNf" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/floor1/starboard/fore) "dNm" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 @@ -15498,6 +15544,10 @@ dir = 4 }, /area/station/hallway/floor2/fore) +"dXP" = ( +/obj/machinery/computer/exodrone_control_console, +/turf/open/floor/iron/dark, +/area/station/cargo/drone_bay) "dXX" = ( /obj/structure/window/reinforced/spawner/directional/west, /obj/machinery/rnd/production/techfab/department/security, @@ -15533,6 +15583,19 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/iron, /area/station/engineering/atmos/project) +"dYm" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/storage) "dYq" = ( /obj/structure/reagent_dispensers/watertank, /obj/effect/turf_decal/stripes{ @@ -16782,21 +16845,6 @@ /obj/machinery/duct, /turf/open/floor/iron/showroomfloor, /area/station/commons/toilet) -"eoo" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/obj/structure/railing/corner/end{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "eop" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -16970,18 +17018,6 @@ /obj/structure/cable, /turf/open/floor/catwalk_floor, /area/station/maintenance/floor1/starboard) -"erV" = ( -/obj/machinery/door/firedoor/border_only{ - dir = 1 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/turf/open/floor/catwalk_floor, -/area/station/maintenance/floor1/starboard/fore) "erY" = ( /obj/machinery/vending/wardrobe/bar_wardrobe, /turf/open/floor/wood, @@ -17112,12 +17148,6 @@ }, /turf/open/floor/pod/dark, /area/station/maintenance/floor3/starboard) -"eul" = ( -/obj/effect/turf_decal/stripes{ - dir = 8 - }, -/turf/open/floor/plating, -/area/station/maintenance/floor1/starboard/fore) "euu" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, @@ -18527,6 +18557,10 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/wood/tile, /area/station/service/library) +"ePI" = ( +/obj/effect/turf_decal/stripes, +/turf/open/floor/plating, +/area/station/maintenance/floor1/starboard/fore) "ePJ" = ( /obj/effect/turf_decal/trimline/red/line{ dir = 1 @@ -18750,6 +18784,11 @@ /obj/machinery/newscaster/directional/west, /turf/open/floor/wood, /area/station/hallway/secondary/entry) +"eTD" = ( +/obj/effect/turf_decal/bot, +/obj/structure/sign/poster/random/directional/north, +/turf/open/floor/iron/smooth, +/area/station/cargo/warehouse) "eTH" = ( /obj/structure/flora/bush/sparsegrass/style_random, /mob/living/carbon/human/species/monkey, @@ -20930,6 +20969,12 @@ dir = 1 }, /area/station/command/bridge) +"fBB" = ( +/obj/effect/turf_decal/stripes{ + dir = 5 + }, +/turf/open/floor/plating, +/area/station/maintenance/floor1/starboard/fore) "fBM" = ( /obj/effect/turf_decal/delivery, /turf/open/floor/iron/dark, @@ -20969,13 +21014,6 @@ "fCp" = ( /turf/open/floor/plating/airless, /area/space) -"fCw" = ( -/obj/effect/turf_decal/stripes{ - dir = 4 - }, -/obj/structure/disposalpipe/trunk/multiz, -/turf/open/floor/plating, -/area/station/maintenance/floor1/starboard/fore) "fCx" = ( /obj/structure/rack, /turf/open/floor/pod/dark, @@ -23103,6 +23141,11 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/wood/tile, /area/station/service/library) +"gex" = ( +/obj/structure/rack, +/obj/effect/spawner/random/maintenance/two, +/turf/open/floor/pod/light, +/area/station/maintenance/floor1/starboard/fore) "geA" = ( /obj/effect/turf_decal/tile/blue/opposingcorners, /obj/item/kirbyplants/random, @@ -24078,17 +24121,6 @@ /obj/structure/chair/stool/bar/directional/east, /turf/open/floor/iron/white, /area/station/science/circuits) -"gso" = ( -/obj/structure/railing{ - dir = 4 - }, -/obj/effect/turf_decal/stripes{ - dir = 4 - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/iron, -/area/station/cargo/storage) "gsp" = ( /obj/machinery/door/airlock/medical{ id_tag = "asylum_airlock_exterior"; @@ -24311,6 +24343,10 @@ }, /turf/open/floor/iron/dark/textured, /area/station/medical/medbay/lobby) +"gvu" = ( +/obj/effect/spawner/random/structure/crate, +/turf/open/floor/pod/light, +/area/station/maintenance/floor1/starboard/fore) "gvx" = ( /obj/effect/turf_decal/trimline/blue/filled/corner, /turf/open/floor/iron/white, @@ -24856,6 +24892,12 @@ /obj/structure/extinguisher_cabinet/directional/west, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) +"gCn" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/broken/directional/north, +/obj/item/radio/intercom/directional/north, +/turf/open/floor/catwalk_floor/iron_smooth, +/area/station/cargo/warehouse) "gCv" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -25096,10 +25138,6 @@ /obj/machinery/door/firedoor/border_only, /turf/open/floor/pod/dark, /area/station/maintenance/floor2/starboard/aft) -"gFU" = ( -/obj/machinery/computer/exodrone_control_console, -/turf/open/floor/iron/dark, -/area/station/cargo/drone_bay) "gGe" = ( /obj/machinery/telecomms/bus/preset_one, /turf/open/floor/circuit/telecomms, @@ -28054,10 +28092,6 @@ }, /turf/open/floor/pod/dark, /area/station/maintenance/floor2/port/fore) -"htK" = ( -/obj/effect/spawner/random/maintenance, -/turf/open/floor/pod/light, -/area/station/maintenance/floor1/starboard/fore) "htW" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/catwalk_floor/iron, @@ -28653,12 +28687,6 @@ /obj/effect/spawner/random/maintenance, /turf/open/floor/pod/light, /area/station/maintenance/floor2/port/aft) -"hBR" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/broken/directional/north, -/obj/item/radio/intercom/directional/north, -/turf/open/floor/catwalk_floor/iron_smooth, -/area/station/cargo/warehouse) "hBT" = ( /obj/structure/table, /obj/structure/bedsheetbin, @@ -30476,11 +30504,6 @@ }, /turf/open/floor/iron/dark, /area/station/commons/dorms/room4) -"iaJ" = ( -/obj/structure/rack, -/obj/effect/spawner/random/maintenance/two, -/turf/open/floor/pod/light, -/area/station/maintenance/floor1/starboard/fore) "iaO" = ( /obj/structure/rack, /obj/structure/sign/nanotrasen{ @@ -30573,6 +30596,10 @@ dir = 4 }, /area/station/commons/storage/primary) +"icf" = ( +/obj/effect/spawner/random/maintenance, +/turf/open/floor/pod/light, +/area/station/maintenance/floor1/starboard/fore) "ick" = ( /obj/effect/turf_decal/trimline/brown/warning{ dir = 8 @@ -31457,17 +31484,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) -"ioi" = ( -/obj/machinery/exoscanner, -/obj/effect/turf_decal/stripes{ - dir = 1 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/obj/structure/extinguisher_cabinet/directional/west, -/turf/open/floor/iron/corner, -/area/station/cargo/drone_bay) "iom" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -32662,13 +32678,6 @@ /obj/machinery/firealarm/directional/east, /turf/open/floor/catwalk_floor, /area/station/maintenance/floor3/starboard/fore) -"iDJ" = ( -/obj/effect/turf_decal/stripes{ - dir = 10 - }, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/floor1/starboard/fore) "iDP" = ( /obj/structure/cable/multilayer/multiz, /turf/open/floor/plating, @@ -33353,6 +33362,12 @@ /obj/effect/mapping_helpers/mail_sorting/service/bar, /turf/open/floor/iron/dark/side, /area/station/hallway/floor3/fore) +"iOl" = ( +/obj/machinery/modular_computer/preset/civilian, +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/cable, +/turf/open/floor/iron/dark, +/area/station/cargo/drone_bay) "iOp" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -34786,10 +34801,6 @@ /obj/structure/cable, /turf/open/floor/pod/light, /area/station/maintenance/floor1/starboard/fore) -"jhP" = ( -/obj/effect/spawner/random/structure/crate, -/turf/open/floor/pod/light, -/area/station/maintenance/floor1/starboard/fore) "jhU" = ( /turf/open/floor/iron/white, /area/station/science/robotics/lab) @@ -36139,19 +36150,6 @@ }, /turf/open/floor/carpet/royalblack, /area/station/service/kitchen/diner) -"jAr" = ( -/obj/structure/railing{ - dir = 4 - }, -/obj/effect/turf_decal/stripes{ - dir = 4 - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "jAB" = ( /obj/machinery/light/floor, /turf/open/floor/iron/dark/side{ @@ -37741,10 +37739,6 @@ /obj/effect/turf_decal/trimline/purple/warning, /turf/open/floor/iron/dark, /area/station/hallway/floor2/fore) -"jWJ" = ( -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/storage) "jWR" = ( /obj/structure/railing/corner, /obj/effect/turf_decal/siding/wood/corner{ @@ -41274,6 +41268,19 @@ /obj/effect/spawner/random/engineering/flashlight, /turf/open/floor/pod/light, /area/station/maintenance/floor2/port/aft) +"kQL" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "kQN" = ( /obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -41905,6 +41912,13 @@ /obj/structure/rack, /turf/open/floor/pod/light, /area/station/maintenance/floor2/port/fore) +"kYs" = ( +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/obj/structure/disposalpipe/trunk/multiz, +/turf/open/floor/plating, +/area/station/maintenance/floor1/starboard/fore) "kYt" = ( /obj/structure/chair/comfy/carp, /turf/open/floor/carpet/neon/simple/pink/nodots, @@ -42564,12 +42578,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/commons/fitness/recreation) -"lgs" = ( -/obj/effect/turf_decal/stripes{ - dir = 5 - }, -/turf/open/floor/plating, -/area/station/maintenance/floor1/starboard/fore) "lgv" = ( /obj/structure/rack, /obj/item/book/manual/nuclear, @@ -43940,6 +43948,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/checker, /area/station/cargo/miningdock) +"lAv" = ( +/obj/machinery/cryo_cell{ + dir = 8 + }, +/obj/structure/sign/poster/official/random/directional/east, +/turf/open/floor/iron/dark/textured, +/area/station/medical/cryo) "lAD" = ( /obj/effect/turf_decal/trimline/green/filled/arrow_cw{ dir = 10 @@ -44578,6 +44593,12 @@ /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/pod/light, /area/station/maintenance/floor1/port) +"lJl" = ( +/obj/machinery/door/firedoor/border_only{ + dir = 8 + }, +/turf/open/floor/pod/light, +/area/station/maintenance/floor1/starboard/fore) "lJn" = ( /obj/item/radio/intercom/directional/west, /turf/open/floor/iron/dark/side{ @@ -48391,6 +48412,18 @@ /obj/effect/landmark/start/assistant, /turf/open/floor/carpet/red, /area/station/commons/dorms/apartment1) +"mFK" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/obj/structure/railing{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/iron, +/area/station/cargo/storage) "mFP" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -50121,6 +50154,17 @@ }, /turf/open/floor/iron/white/herringbone, /area/station/medical/patients_rooms) +"ncf" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/storage) "ncl" = ( /obj/structure/dresser, /turf/open/floor/carpet/red, @@ -50884,22 +50928,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/dark, /area/station/hallway/floor3/aft) -"nkT" = ( -/obj/effect/turf_decal/siding/thinplating_new/dark{ - dir = 4 - }, -/obj/machinery/door/airlock/hatch{ - name = "Maintenance Access" - }, -/obj/effect/mapping_helpers/airlock/access/any/supply/general, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/pod/dark, -/area/station/maintenance/floor1/starboard/fore) "nla" = ( /obj/structure/table/wood, /obj/effect/turf_decal/siding/wood{ @@ -55540,15 +55568,6 @@ }, /turf/open/floor/iron/dark/side, /area/station/security/checkpoint) -"owk" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/catwalk_floor, -/area/station/maintenance/floor1/starboard/fore) "owo" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable, @@ -55825,6 +55844,15 @@ /obj/effect/spawner/random/structure/closet_maintenance, /turf/open/floor/pod/dark, /area/station/maintenance/floor3/port/aft) +"ozY" = ( +/obj/machinery/door/firedoor/border_only{ + dir = 1 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/floor1/starboard/fore) "oAc" = ( /obj/effect/turf_decal/trimline/purple/line, /obj/machinery/door/firedoor/border_only{ @@ -58866,17 +58894,6 @@ /obj/effect/decal/cleanable/blood/drip, /turf/open/misc/dirt/jungle, /area/station/service/hydroponics/garden/abandoned) -"prm" = ( -/obj/structure/railing{ - dir = 4 - }, -/obj/effect/turf_decal/stripes{ - dir = 4 - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/cargo/storage) "pro" = ( /obj/effect/turf_decal/stripes, /obj/effect/decal/cleanable/dirt, @@ -59739,12 +59756,6 @@ /obj/effect/turf_decal/trimline/green/filled/line, /turf/open/floor/iron/dark, /area/station/medical/virology) -"pCW" = ( -/obj/effect/decal/cleanable/cobweb/cobweb2, -/obj/machinery/rnd/bepis, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "pDd" = ( /obj/structure/table/reinforced/plasmarglass, /obj/item/reagent_containers/pill/epinephrine{ @@ -64285,18 +64296,6 @@ /obj/machinery/light_switch/directional/east, /turf/open/floor/iron/dark, /area/station/command/bridge) -"qOr" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/effect/turf_decal/stripes{ - dir = 4 - }, -/obj/structure/railing{ - dir = 4 - }, -/obj/structure/disposalpipe/segment, -/turf/open/floor/iron, -/area/station/cargo/storage) "qOs" = ( /obj/structure/table/wood/fancy/red, /obj/item/paper_bin, @@ -66019,12 +66018,6 @@ }, /turf/open/floor/iron/dark, /area/station/medical/psychology) -"rku" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell{ - dir = 4 - }, -/turf/open/floor/iron/dark/textured, -/area/station/medical/cryo) "rkE" = ( /obj/structure/disposalpipe/trunk/multiz{ dir = 1 @@ -66480,19 +66473,6 @@ /obj/machinery/duct, /turf/open/floor/iron/dark/textured, /area/station/medical/cryo) -"rqB" = ( -/obj/structure/railing{ - dir = 4 - }, -/obj/effect/turf_decal/stripes{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/cargo/storage) "rqK" = ( /obj/effect/turf_decal/stripes/full, /obj/structure/window/reinforced/spawner/directional/west, @@ -67511,11 +67491,6 @@ }, /turf/open/floor/plating, /area/station/medical/abandoned) -"rGF" = ( -/obj/effect/turf_decal/bot, -/obj/structure/sign/poster/random/directional/north, -/turf/open/floor/iron/smooth, -/area/station/cargo/warehouse) "rGI" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -69902,15 +69877,6 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/hallway/floor4/aft) -"sqK" = ( -/obj/structure/railing{ - dir = 4 - }, -/obj/effect/turf_decal/stripes{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "srz" = ( /obj/machinery/door/airlock/atmos{ name = "Atmospherics" @@ -71466,12 +71432,6 @@ /obj/structure/sign/warning/xeno_mining/directional/north, /turf/open/floor/iron/white, /area/station/science/xenobiology/hallway) -"sLq" = ( -/obj/machinery/door/firedoor/border_only{ - dir = 8 - }, -/turf/open/floor/pod/light, -/area/station/maintenance/floor1/starboard/fore) "sLE" = ( /obj/machinery/door/airlock/security/glass{ name = "Security Entrance" @@ -75480,6 +75440,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/textured_large, /area/station/engineering/lobby) +"tNh" = ( +/obj/effect/turf_decal/stripes{ + dir = 6 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plating, +/area/station/maintenance/floor1/starboard/fore) "tNi" = ( /obj/structure/table/wood, /obj/effect/spawner/random/entertainment/cigar, @@ -76114,6 +76081,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/station/service/chapel/funeral) +"tWc" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "tWn" = ( /obj/machinery/portable_atmospherics/canister/oxygen, /obj/effect/turf_decal/bot, @@ -78136,6 +78112,12 @@ /obj/structure/closet, /turf/open/floor/pod/light, /area/station/maintenance/floor2/port/fore) +"uzr" = ( +/obj/effect/turf_decal/stripes{ + dir = 1 + }, +/turf/open/floor/plating, +/area/station/maintenance/floor1/starboard/fore) "uzB" = ( /obj/structure/table/reinforced, /obj/item/screwdriver, @@ -78372,11 +78354,6 @@ }, /turf/open/floor/iron, /area/station/hallway/floor2/aft) -"uDm" = ( -/obj/effect/spawner/random/structure/table_or_rack, -/obj/effect/spawner/random/trash/soap, -/turf/open/floor/pod/light, -/area/station/maintenance/floor1/starboard/fore) "uDr" = ( /obj/machinery/light/small/directional/north, /obj/effect/decal/cleanable/dirt, @@ -79853,6 +79830,12 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron/dark/smooth_large, /area/station/science/robotics/lab) +"uVb" = ( +/obj/effect/turf_decal/stripes{ + dir = 8 + }, +/turf/open/floor/plating, +/area/station/maintenance/floor1/starboard/fore) "uVh" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -82160,6 +82143,10 @@ /obj/effect/turf_decal/trimline/brown/arrow_ccw, /turf/open/floor/iron/dark/side, /area/station/cargo/lobby) +"vzo" = ( +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/storage) "vzu" = ( /obj/effect/landmark/start/psychologist, /obj/structure/sign/poster/official/random/directional/south, @@ -83302,6 +83289,17 @@ /obj/machinery/atmospherics/pipe/heat_exchanging/simple/layer2, /turf/open/floor/engine/vacuum, /area/station/science/ordnance/freezerchamber) +"vPU" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/iron, +/area/station/cargo/storage) "vQb" = ( /obj/effect/turf_decal/siding/wood{ dir = 6 @@ -84079,13 +84077,6 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron, /area/station/hallway/floor2/aft) -"waA" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell{ - dir = 8 - }, -/obj/structure/sign/poster/official/random/directional/east, -/turf/open/floor/iron/dark/textured, -/area/station/medical/cryo) "waI" = ( /obj/effect/turf_decal/stripes, /obj/machinery/atmospherics/components/binary/pump/off{ @@ -84655,12 +84646,6 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/hallway/floor4/aft) -"whN" = ( -/obj/effect/turf_decal/stripes{ - dir = 9 - }, -/turf/open/floor/plating, -/area/station/maintenance/floor1/starboard/fore) "whR" = ( /turf/closed/wall, /area/station/service/bar) @@ -85722,6 +85707,21 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/service) +"wuE" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/structure/railing/corner/end{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "wuJ" = ( /obj/effect/turf_decal/tile/dark_red/fourcorners, /turf/open/floor/iron, @@ -89286,6 +89286,12 @@ "xpI" = ( /turf/closed/wall, /area/station/maintenance/solars/starboard/fore) +"xpK" = ( +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/machinery/rnd/bepis, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "xpL" = ( /obj/machinery/door/airlock/research/glass/incinerator/ordmix_exterior{ name = "Burn Chamber Exterior Airlock" @@ -91152,12 +91158,6 @@ /obj/structure/cable, /turf/open/floor/catwalk_floor, /area/station/maintenance/floor2/starboard/fore) -"xOd" = ( -/obj/machinery/modular_computer/preset/civilian, -/obj/machinery/power/apc/auto_name/directional/north, -/obj/structure/cable, -/turf/open/floor/iron/dark, -/area/station/cargo/drone_bay) "xOe" = ( /obj/machinery/light/cold/no_nightlight/directional/north, /turf/open/floor/engine, @@ -115258,10 +115258,10 @@ owI owI oic oic -whN -eul -iDJ -bAh +ads +uVb +aOv +ozY oic oic oic @@ -115515,11 +115515,11 @@ owI owI oic oic -cDe +uzr oic -bsq -bAh -htK +ePI +ozY +icf oic gUS nOj @@ -115772,13 +115772,13 @@ owI owI oic oic -lgs -fCw -brL -erV -uDm +fBB +kYs +tNh +bqm +aUn oic -rGF +eTD yiZ yiZ bUC @@ -116029,13 +116029,13 @@ owI owI oic oic -sLq -sLq -cBT -owk -jhP +lJl +lJl +cjz +dNf +gvu oic -hBR +gCn qWJ qWJ imO @@ -116286,10 +116286,10 @@ owI owI oic oic -iaJ +gex oic oic -nkT +avu oic oic rYA @@ -116545,9 +116545,9 @@ oic oic oic oic -xOd +iOl xxQ -ioi +cxp aQK fve fve @@ -116802,7 +116802,7 @@ uYl pFb gHw yef -gFU +dXP kHQ hIj aQK @@ -117063,7 +117063,7 @@ wZu vTt hai aQK -pCW +xpK rhs eaW lSJ @@ -117578,7 +117578,7 @@ fuJ aQK aQK cfO -jWJ +vzo mnR mnk mnR @@ -117830,13 +117830,13 @@ cUL cUL oKT xsL -sqK -rqB -prm -jAr -gso -qOr -eoo +tWc +dYm +ncf +kQL +vPU +mFK +wuE myW myW myW @@ -194971,7 +194971,7 @@ gHO yba lfW wdd -rku +aXl nqM qQM dHR @@ -196513,7 +196513,7 @@ dXy bND aHK wdd -waA +lAv wat mVm tfX diff --git a/_maps/map_files/VoidRaptor/VoidRaptor.dmm b/_maps/map_files/VoidRaptor/VoidRaptor.dmm index c3918c21108..a68a80d0d40 100644 --- a/_maps/map_files/VoidRaptor/VoidRaptor.dmm +++ b/_maps/map_files/VoidRaptor/VoidRaptor.dmm @@ -14574,7 +14574,7 @@ }, /area/station/cargo/lobby) "ejt" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /obj/effect/turf_decal/bot, /obj/effect/turf_decal/tile/dark_blue/fourcorners, /turf/open/floor/iron/dark, @@ -20502,7 +20502,7 @@ /turf/closed/wall/r_wall, /area/station/engineering/atmos/storage/gas) "fXS" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /obj/effect/turf_decal/bot, /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/tile/dark_blue/fourcorners, diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index 4ef52187a09..ac5d9ba0e1d 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -451,19 +451,6 @@ "abM" = ( /turf/open/misc/asteroid, /area/station/asteroid) -"abN" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=1"; - location = "QM #6" - }, -/obj/effect/turf_decal/tile/brown/fourcorners, -/mob/living/simple_animal/bot/mulebot{ - home_destination = "QM #6"; - suffix = "#6" - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "abO" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -3861,12 +3848,6 @@ /obj/effect/turf_decal/trimline/neutral/warning, /turf/open/floor/iron/dark, /area/station/medical/morgue) -"axF" = ( -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "axG" = ( /obj/effect/turf_decal/bot, /obj/effect/spawner/random/structure/crate_empty, @@ -6213,6 +6194,13 @@ }, /turf/open/floor/iron, /area/station/maintenance/tram/mid) +"aVM" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/brown/filled/line, +/turf/open/floor/iron, +/area/station/cargo/storage) "aVT" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -6250,6 +6238,24 @@ /obj/machinery/suit_storage_unit/industrial/loader, /turf/open/floor/iron, /area/station/cargo/warehouse) +"aWQ" = ( +/obj/effect/turf_decal/trimline/brown/filled/corner{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/brown/filled/corner{ + dir = 1 + }, +/obj/effect/turf_decal/siding/thinplating{ + dir = 1 + }, +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "aWY" = ( /obj/structure/stairs/west, /turf/open/floor/iron/stairs/right{ @@ -6356,6 +6362,11 @@ }, /turf/open/floor/iron, /area/station/cargo/storage) +"aZT" = ( +/obj/effect/landmark/event_spawn, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/storage) "aZX" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 1 @@ -10091,15 +10102,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/cafeteria, /area/station/command/heads_quarters/rd) -"csn" = ( -/obj/machinery/elevator_control_panel{ - layer = 3.1; - linked_elevator_id = "tram_xeno_lift"; - pixel_y = 2; - preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") - }, -/turf/closed/wall, -/area/station/science/xenobiology) "csA" = ( /turf/closed/wall, /area/station/solars/starboard/fore) @@ -10722,12 +10724,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/engineering/atmos) -"cEy" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/station/medical/treatment_center) "cEA" = ( /obj/effect/turf_decal/trimline/purple/filled/line, /obj/machinery/firealarm/directional/south, @@ -13466,6 +13462,12 @@ /obj/machinery/light/directional/south, /turf/open/floor/iron, /area/station/security/prison) +"dCY" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "dDi" = ( /obj/effect/turf_decal/trimline/yellow/filled/corner{ dir = 4 @@ -14003,6 +14005,23 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"dMQ" = ( +/obj/effect/turf_decal/siding/thinplating{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/dark_red/warning{ + dir = 4 + }, +/obj/structure/railing{ + dir = 4 + }, +/obj/structure/industrial_lift/public, +/obj/machinery/elevator_control_panel/directional/east{ + linked_elevator_id = "tram_lower_center_lift"; + preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") + }, +/turf/open/floor/plating/elevatorshaft, +/area/station/maintenance/tram/mid) "dNa" = ( /obj/machinery/bookbinder, /obj/machinery/newscaster/directional/north, @@ -15457,6 +15476,14 @@ }, /turf/open/floor/iron/grimy, /area/station/service/chapel/office) +"epQ" = ( +/obj/machinery/computer/atmos_control/oxygen_tank{ + atmos_chambers = list("o2ordance"="Oxygen Supply") + }, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/airalarm/directional/north, +/turf/open/floor/iron/dark, +/area/station/science/ordnance/storage) "eqi" = ( /obj/effect/landmark/navigate_destination/tcomms, /turf/open/floor/iron, @@ -15682,19 +15709,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/station/service/theater) -"euR" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=2"; - location = "QM #3" - }, -/obj/effect/turf_decal/tile/brown/fourcorners, -/mob/living/simple_animal/bot/mulebot{ - home_destination = "QM #3"; - suffix = "#3" - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "euS" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -17627,6 +17641,15 @@ /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/station/science/lower) +"fiy" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=1"; + location = "QM #5" + }, +/obj/effect/turf_decal/tile/brown/fourcorners, +/turf/open/floor/iron, +/area/station/cargo/storage) "fiP" = ( /obj/structure/table, /obj/item/storage/toolbox/electrical{ @@ -18003,10 +18026,6 @@ /obj/structure/cable, /turf/open/floor/iron/white, /area/station/science/ordnance) -"foU" = ( -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/storage) "foY" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -19676,14 +19695,6 @@ }, /turf/open/floor/iron/dark, /area/station/security/processing) -"fWK" = ( -/obj/machinery/computer/atmos_control/oxygen_tank{ - atmos_chambers = list("o2ordance"="Oxygen Supply") - }, -/obj/effect/turf_decal/stripes/line, -/obj/machinery/airalarm/directional/north, -/turf/open/floor/iron/dark, -/area/station/science/ordnance/storage) "fWM" = ( /obj/effect/turf_decal/trimline/red/filled/line, /obj/item/kirbyplants/random, @@ -20242,20 +20253,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/tram/right) -"giW" = ( -/obj/effect/turf_decal/trimline/dark_red/warning{ - dir = 9 - }, -/obj/structure/industrial_lift/public, -/obj/structure/railing{ - dir = 9 - }, -/obj/machinery/elevator_control_panel/directional/west{ - linked_elevator_id = "tram_sci_lift"; - preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") - }, -/turf/open/floor/plating/elevatorshaft, -/area/station/science/lower) "giZ" = ( /obj/structure/bed, /obj/effect/spawner/random/contraband/prison, @@ -20881,6 +20878,19 @@ /obj/effect/turf_decal/trimline/red/filled/corner, /turf/open/floor/iron, /area/station/security/courtroom) +"gtA" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=2"; + location = "QM #1" + }, +/obj/effect/turf_decal/tile/brown/fourcorners, +/mob/living/simple_animal/bot/mulebot{ + home_destination = "QM #1"; + suffix = "#1" + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "gtH" = ( /obj/structure/table/glass, /obj/effect/turf_decal/trimline/red/filled/line{ @@ -21964,6 +21974,15 @@ /obj/item/papercutter, /turf/open/floor/plating, /area/station/security/warden) +"gNM" = ( +/obj/machinery/elevator_control_panel{ + layer = 3.1; + linked_elevator_id = "tram_xeno_lift"; + pixel_y = 2; + preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") + }, +/turf/closed/wall/r_wall, +/area/station/science/xenobiology) "gNN" = ( /obj/machinery/vending/wardrobe/coroner_wardrobe, /obj/structure/window/reinforced/spawner/directional/west, @@ -22345,11 +22364,6 @@ }, /turf/open/floor/iron/dark, /area/station/medical/break_room) -"gUL" = ( -/obj/effect/landmark/event_spawn, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/storage) "gUO" = ( /obj/effect/turf_decal/trimline/neutral/filled/line, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -23934,13 +23948,6 @@ }, /turf/open/floor/iron/white, /area/station/science/xenobiology) -"hDU" = ( -/obj/effect/turf_decal/siding/thinplating/corner{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/station/cargo/storage) "hDZ" = ( /obj/effect/turf_decal/sand/plating, /obj/effect/turf_decal/box, @@ -24713,6 +24720,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/secondary/exit) +"hSy" = ( +/obj/effect/turf_decal/siding/thinplating/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/cargo/storage) "hSH" = ( /obj/structure/chair{ dir = 1 @@ -25083,6 +25097,20 @@ }, /turf/open/floor/iron, /area/station/tcommsat/computer) +"hZM" = ( +/obj/effect/turf_decal/trimline/dark_red/warning{ + dir = 9 + }, +/obj/structure/industrial_lift/public, +/obj/structure/railing{ + dir = 9 + }, +/obj/machinery/elevator_control_panel/directional/west{ + linked_elevator_id = "tram_sci_lift"; + preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") + }, +/turf/open/floor/plating/elevatorshaft, +/area/station/science/lower) "hZP" = ( /obj/structure/railing/corner{ dir = 8 @@ -28088,6 +28116,16 @@ /obj/structure/cable, /turf/closed/wall/r_wall, /area/station/ai_monitored/turret_protected/aisat/hallway) +"jfE" = ( +/obj/effect/turf_decal/trimline/dark_red/warning, +/obj/structure/industrial_lift/public, +/obj/machinery/elevator_control_panel/directional/south{ + linked_elevator_id = "tram_dorm_lift"; + preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") + }, +/obj/structure/railing, +/turf/open/floor/plating/elevatorshaft, +/area/station/maintenance/tram/left) "jfH" = ( /obj/effect/turf_decal/trimline/red/filled/corner{ dir = 1 @@ -28584,14 +28622,6 @@ }, /turf/open/floor/iron, /area/station/security/checkpoint/supply) -"jnL" = ( -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 1 - }, -/obj/effect/turf_decal/trimline/brown/filled/line, -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron, -/area/station/cargo/storage) "jnR" = ( /obj/structure/bed{ dir = 8 @@ -28806,6 +28836,20 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) +"jrl" = ( +/obj/effect/turf_decal/caution/stand_clear/red{ + dir = 1 + }, +/obj/structure/industrial_lift/public, +/obj/structure/railing{ + dir = 8 + }, +/obj/machinery/elevator_control_panel/directional/west{ + linked_elevator_id = "tram_perma_lift"; + preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") + }, +/turf/open/floor/plating/elevatorshaft, +/area/station/security/execution/transfer) "jrI" = ( /obj/structure/disposalpipe/trunk/multiz{ dir = 4 @@ -29081,27 +29125,6 @@ /obj/machinery/light/directional/north, /turf/open/floor/iron/showroomfloor, /area/station/security/lockers) -"jwP" = ( -/obj/effect/landmark/lift_id{ - specific_lift_id = "tram_cargo_lift" - }, -/obj/structure/railing{ - dir = 8 - }, -/obj/effect/turf_decal/trimline/dark_red/warning{ - dir = 8 - }, -/obj/structure/industrial_lift/public, -/obj/machinery/elevator_control_panel/directional/west{ - linked_elevator_id = "tram_cargo_lift"; - preset_destination_names = list("2"="Lower Deck","3"="Upper Deck"); - req_access = list("mining") - }, -/obj/effect/abstract/elevator_music_zone{ - linked_elevator_id = "tram_cargo_lift" - }, -/turf/open/floor/plating/elevatorshaft, -/area/station/cargo/miningdock) "jwT" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -30342,13 +30365,6 @@ }, /turf/open/floor/iron, /area/station/construction/mining/aux_base) -"jTQ" = ( -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 1 - }, -/obj/effect/turf_decal/trimline/brown/filled/line, -/turf/open/floor/iron, -/area/station/cargo/storage) "jUa" = ( /obj/effect/turf_decal/trimline/purple/filled/corner{ dir = 4 @@ -34430,6 +34446,7 @@ /area/station/cargo/sorting) "lnh" = ( /obj/machinery/door/poddoor/massdriver_chapel, +/obj/structure/fans/tiny, /turf/open/floor/plating, /area/station/service/chapel/monastery) "lnk" = ( @@ -34943,20 +34960,6 @@ /obj/effect/turf_decal/tile/red/fourcorners, /turf/open/floor/iron/dark, /area/station/security/office) -"lvz" = ( -/obj/effect/turf_decal/caution/stand_clear/red{ - dir = 1 - }, -/obj/structure/industrial_lift/public, -/obj/structure/railing{ - dir = 8 - }, -/obj/machinery/elevator_control_panel/directional/west{ - linked_elevator_id = "tram_perma_lift"; - preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") - }, -/turf/open/floor/plating/elevatorshaft, -/area/station/security/execution/transfer) "lvH" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 1 @@ -36302,24 +36305,6 @@ }, /turf/open/floor/iron, /area/station/security/prison/safe) -"lTM" = ( -/obj/effect/turf_decal/trimline/brown/filled/corner{ - dir = 8 - }, -/obj/effect/turf_decal/trimline/brown/filled/corner{ - dir = 1 - }, -/obj/effect/turf_decal/siding/thinplating{ - dir = 1 - }, -/obj/effect/turf_decal/loading_area{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "lTP" = ( /obj/structure/stairs/south, /turf/open/floor/iron/stairs/medium{ @@ -37442,13 +37427,6 @@ /obj/machinery/meter, /turf/open/floor/engine, /area/station/engineering/supermatter/room) -"mmX" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/trimline/neutral/filled/line{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "mng" = ( /obj/structure/window/reinforced/plasma/spawner/directional/west, /obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible, @@ -37645,15 +37623,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/medical/storage) -"mrg" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=1"; - location = "QM #4" - }, -/obj/effect/turf_decal/tile/brown/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/storage) "mrr" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/trimline/neutral/filled/line, @@ -39024,20 +38993,6 @@ /obj/item/storage/secure/safe/directional/north, /turf/open/floor/carpet, /area/station/command/heads_quarters/hop) -"mUc" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/machinery/elevator_control_panel/directional/north{ - linked_elevator_id = "tram_upper_center_lift"; - preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") - }, -/obj/effect/turf_decal/trimline/dark_red/warning{ - dir = 1 - }, -/obj/structure/industrial_lift/public, -/turf/open/floor/plating/elevatorshaft, -/area/station/maintenance/tram/mid) "mUd" = ( /obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/monitored/air_output{ dir = 1 @@ -39609,15 +39564,6 @@ }, /turf/open/floor/iron, /area/station/maintenance/tram/right) -"nfZ" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=1"; - location = "QM #5" - }, -/obj/effect/turf_decal/tile/brown/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/storage) "ngg" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden, /obj/effect/spawner/structure/window/reinforced, @@ -40674,6 +40620,27 @@ }, /turf/open/openspace, /area/station/hallway/primary/tram/center) +"nxj" = ( +/obj/effect/landmark/lift_id{ + specific_lift_id = "tram_cargo_lift" + }, +/obj/structure/railing{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/dark_red/warning{ + dir = 8 + }, +/obj/structure/industrial_lift/public, +/obj/machinery/elevator_control_panel/directional/west{ + linked_elevator_id = "tram_cargo_lift"; + preset_destination_names = list("2"="Lower Deck","3"="Upper Deck"); + req_access = list("mining") + }, +/obj/effect/abstract/elevator_music_zone{ + linked_elevator_id = "tram_cargo_lift" + }, +/turf/open/floor/plating/elevatorshaft, +/area/station/cargo/miningdock) "nxq" = ( /obj/structure/table/wood, /obj/structure/cable, @@ -41264,6 +41231,20 @@ /obj/structure/chair, /turf/open/floor/iron, /area/station/security/checkpoint/supply) +"nJb" = ( +/obj/structure/railing{ + dir = 1 + }, +/obj/machinery/elevator_control_panel/directional/north{ + linked_elevator_id = "tram_upper_center_lift"; + preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") + }, +/obj/effect/turf_decal/trimline/dark_red/warning{ + dir = 1 + }, +/obj/structure/industrial_lift/public, +/turf/open/floor/plating/elevatorshaft, +/area/station/maintenance/tram/mid) "nJd" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 5 @@ -41916,19 +41897,6 @@ /obj/effect/turf_decal/trimline/purple/filled/line, /turf/open/floor/iron/white, /area/station/science/lobby) -"nUF" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=2"; - location = "QM #1" - }, -/obj/effect/turf_decal/tile/brown/fourcorners, -/mob/living/simple_animal/bot/mulebot{ - home_destination = "QM #1"; - suffix = "#1" - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "nUM" = ( /obj/effect/turf_decal/siding/wood{ dir = 1 @@ -42079,13 +42047,6 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron/dark, /area/station/medical/morgue) -"nXk" = ( -/obj/effect/turf_decal/siding/thinplating{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/station/cargo/storage) "nXn" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -43939,15 +43900,6 @@ /obj/structure/grille, /turf/open/space/openspace, /area/space/nearstation) -"oKn" = ( -/obj/machinery/elevator_control_panel{ - layer = 3.1; - linked_elevator_id = "tram_xeno_lift"; - pixel_y = 2; - preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") - }, -/turf/closed/wall/r_wall, -/area/station/science/xenobiology) "oKZ" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -45259,19 +45211,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/commons/vacant_room) -"plH" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=2"; - location = "QM #2" - }, -/obj/effect/turf_decal/tile/brown/fourcorners, -/mob/living/simple_animal/bot/mulebot{ - home_destination = "QM #2"; - suffix = "#2" - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "plQ" = ( /obj/effect/turf_decal/trimline/red/filled/corner, /obj/structure/disposalpipe/segment{ @@ -46187,6 +46126,19 @@ /obj/effect/turf_decal/tile/bar/opposingcorners, /turf/open/floor/iron, /area/station/cargo/miningdock/cafeteria) +"pzi" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=1"; + location = "QM #6" + }, +/obj/effect/turf_decal/tile/brown/fourcorners, +/mob/living/simple_animal/bot/mulebot{ + home_destination = "QM #6"; + suffix = "#6" + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "pzv" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 8 @@ -47099,15 +47051,6 @@ /obj/structure/railing, /turf/open/floor/plating/elevatorshaft, /area/station/maintenance/tram/left) -"pOL" = ( -/obj/effect/turf_decal/trimline/neutral/filled/line{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/structure/table, -/obj/machinery/light/dim/directional/north, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "pOQ" = ( /obj/effect/turf_decal/trimline/neutral/filled/line{ dir = 4 @@ -47845,6 +47788,14 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/commons/fitness/recreation/entertainment) +"qey" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/brown/filled/line, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron, +/area/station/cargo/storage) "qez" = ( /obj/machinery/computer/slot_machine{ pixel_y = 2 @@ -49755,6 +49706,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/commons/dorms) +"qPL" = ( +/obj/machinery/elevator_control_panel{ + layer = 3.1; + linked_elevator_id = "tram_xeno_lift"; + pixel_y = 2; + preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") + }, +/turf/closed/wall, +/area/station/science/xenobiology) "qPV" = ( /obj/machinery/power/apc/auto_name/directional/south, /obj/structure/cable, @@ -51421,6 +51381,10 @@ /obj/effect/turf_decal/stripes/white/line, /turf/open/floor/iron, /area/station/hallway/primary/tram/center) +"rqH" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/iron, +/area/station/cargo/storage) "rre" = ( /obj/effect/turf_decal/trimline/neutral/filled/line, /obj/effect/landmark/start/hangover, @@ -51643,15 +51607,6 @@ /obj/effect/turf_decal/sand/plating, /turf/open/floor/plating/airless, /area/station/asteroid) -"rwo" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "rws" = ( /obj/structure/table/glass, /obj/item/storage/box/monkeycubes{ @@ -57051,10 +57006,6 @@ /obj/structure/cable, /turf/open/floor/iron/freezer, /area/station/security/prison/shower) -"tte" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/iron, -/area/station/cargo/storage) "tth" = ( /obj/effect/landmark/event_spawn, /obj/structure/cable, @@ -58147,6 +58098,19 @@ /obj/effect/landmark/start/chemist, /turf/open/floor/iron/white, /area/station/medical/chemistry) +"tMq" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=2"; + location = "QM #3" + }, +/obj/effect/turf_decal/tile/brown/fourcorners, +/mob/living/simple_animal/bot/mulebot{ + home_destination = "QM #3"; + suffix = "#3" + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "tMw" = ( /obj/effect/turf_decal/trimline/purple/filled/corner{ dir = 1 @@ -59788,6 +59752,15 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/maintenance/tram/mid) +"uoG" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=1"; + location = "QM #4" + }, +/obj/effect/turf_decal/tile/brown/fourcorners, +/turf/open/floor/iron, +/area/station/cargo/storage) "uoJ" = ( /obj/structure/closet/secure_closet/security/science, /obj/item/clothing/mask/whistle, @@ -60101,23 +60074,6 @@ /obj/effect/spawner/random/maintenance/five, /turf/open/floor/iron, /area/station/cargo/warehouse) -"uud" = ( -/obj/effect/turf_decal/siding/thinplating{ - dir = 4 - }, -/obj/effect/turf_decal/trimline/dark_red/warning{ - dir = 4 - }, -/obj/structure/railing{ - dir = 4 - }, -/obj/structure/industrial_lift/public, -/obj/machinery/elevator_control_panel/directional/east{ - linked_elevator_id = "tram_lower_center_lift"; - preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") - }, -/turf/open/floor/plating/elevatorshaft, -/area/station/maintenance/tram/mid) "uue" = ( /obj/machinery/power/turbine/turbine_outlet{ dir = 4 @@ -60184,6 +60140,12 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/commons/fitness) +"uvt" = ( +/obj/machinery/cryo_cell{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/station/medical/treatment_center) "uvu" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 8 @@ -61641,16 +61603,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/security/checkpoint/arrivals) -"uSl" = ( -/obj/effect/turf_decal/trimline/dark_red/warning, -/obj/structure/industrial_lift/public, -/obj/machinery/elevator_control_panel/directional/south{ - linked_elevator_id = "tram_dorm_lift"; - preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") - }, -/obj/structure/railing, -/turf/open/floor/plating/elevatorshaft, -/area/station/maintenance/tram/left) "uSL" = ( /obj/effect/turf_decal/delivery/white, /obj/structure/fluff/tram_rail/floor, @@ -64099,6 +64051,15 @@ /obj/structure/cable, /turf/open/floor/iron/white, /area/station/science/ordnance) +"vJS" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "vKd" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -64296,6 +64257,17 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/security/checkpoint/supply) +"vNx" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "MULE Storage" + }, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/brown/filled/line, +/obj/effect/mapping_helpers/airlock/access/all/supply/general, +/turf/open/floor/iron, +/area/station/cargo/storage) "vNB" = ( /obj/effect/turf_decal/box, /obj/effect/turf_decal/trimline/yellow/filled/line{ @@ -65077,6 +65049,15 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron, /area/station/hallway/secondary/service) +"wcZ" = ( +/obj/effect/turf_decal/trimline/neutral/filled/line{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/table, +/obj/machinery/light/dim/directional/north, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "wda" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 8 @@ -65614,6 +65595,10 @@ }, /turf/open/floor/iron/dark, /area/station/service/chapel/monastery) +"wod" = ( +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/storage) "wop" = ( /obj/structure/industrial_lift/public, /obj/effect/turf_decal/caution/stand_clear/red, @@ -67153,6 +67138,19 @@ /obj/structure/sink/directional/south, /turf/open/floor/iron/white, /area/station/medical/virology) +"wTp" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=2"; + location = "QM #2" + }, +/obj/effect/turf_decal/tile/brown/fourcorners, +/mob/living/simple_animal/bot/mulebot{ + home_destination = "QM #2"; + suffix = "#2" + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "wTy" = ( /obj/machinery/button/crematorium{ id = "crematoriumChapel"; @@ -67759,6 +67757,13 @@ /obj/item/papercutter, /turf/open/floor/iron, /area/station/command/bridge) +"xhg" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/trimline/neutral/filled/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "xhk" = ( /obj/effect/turf_decal/trimline/neutral/filled/line{ dir = 4 @@ -68402,6 +68407,13 @@ }, /turf/open/floor/iron, /area/station/security/brig) +"xup" = ( +/obj/effect/turf_decal/siding/thinplating{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/cargo/storage) "xuq" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 @@ -68862,17 +68874,6 @@ "xDQ" = ( /turf/closed/wall, /area/station/security/processing) -"xDW" = ( -/obj/machinery/door/airlock/mining/glass{ - name = "MULE Storage" - }, -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 1 - }, -/obj/effect/turf_decal/trimline/brown/filled/line, -/obj/effect/mapping_helpers/airlock/access/all/supply/general, -/turf/open/floor/iron, -/area/station/cargo/storage) "xDY" = ( /obj/structure/railing{ dir = 8 @@ -86187,7 +86188,7 @@ jWs lDo ucA wox -lvz +jrl gTv jWs aaa @@ -92394,7 +92395,7 @@ ncF ncF dFS tuU -uSl +jfE elr elr elr @@ -99829,7 +99830,7 @@ uTz hJM nAa ekB -mUc +nJb jSV uuD qjU @@ -104473,7 +104474,7 @@ qjU aaa qjU fok -uud +dMQ sNq ceb pcx @@ -113437,7 +113438,7 @@ aaa aaa uGW jdU -jwP +nxj rff uGW aaa @@ -113735,7 +113736,7 @@ abM abM abM iix -giW +hZM boW iix abM @@ -116329,7 +116330,7 @@ hDT keT iEF fof -csn +qPL sXX akC hFP @@ -120936,7 +120937,7 @@ kkK jXE lwF dfz -fWK +epQ qCP urA ygC @@ -167455,9 +167456,9 @@ pIk oIU aMG xdx -cEy +uvt uVW -cEy +uvt jtr dSZ aOO @@ -179481,9 +179482,9 @@ aaa aaa aaa cTU -euR -jnL -abN +tMq +qey +pzi cTU cTU ohS @@ -179738,9 +179739,9 @@ aaa aaa aaa cTU -plH -jTQ -nfZ +wTp +aVM +fiy cTU exr pZA @@ -179995,9 +179996,9 @@ aac aaa aaa cTU -nUF -jTQ -mrg +gtA +aVM +uoG cTU lan pZA @@ -180253,7 +180254,7 @@ aaa cTU cTU ohS -xDW +vNx ohS cTU nnb @@ -180510,10 +180511,10 @@ aaa cTU blx tAJ -lTM -axF -axF -rwo +aWQ +dCY +dCY +vJS dij uax uax @@ -180772,8 +180773,8 @@ uax uax uax uax -gUL -foU +aZT +wod dzw msn qza @@ -181028,9 +181029,9 @@ uax uax uax uax -tte -nXk -hDU +rqH +xup +hSy dzw sxR skb @@ -181611,7 +181612,7 @@ eJQ bNx aSt aSt -oKn +gNM aaa aaa aaa @@ -183339,7 +183340,7 @@ cTU cTU cTU udQ -mmX +xhg pxD ayd ayt @@ -183853,7 +183854,7 @@ aaa aaa aaa udQ -pOL +wcZ kXr aye rgg diff --git a/_maps/shuttles/emergency_cere.dmm b/_maps/shuttles/emergency_cere.dmm index c964d37011f..07e236344ab 100644 --- a/_maps/shuttles/emergency_cere.dmm +++ b/_maps/shuttles/emergency_cere.dmm @@ -478,7 +478,7 @@ /turf/open/floor/iron/white, /area/shuttle/escape) "ck" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /obj/effect/turf_decal/tile/blue/half/contrasted{ dir = 1 }, diff --git a/_maps/shuttles/pirate_ex_interdyne.dmm b/_maps/shuttles/pirate_ex_interdyne.dmm index c3f7e186acb..5d2149c049f 100644 --- a/_maps/shuttles/pirate_ex_interdyne.dmm +++ b/_maps/shuttles/pirate_ex_interdyne.dmm @@ -301,7 +301,7 @@ /area/shuttle/pirate) "aW" = ( /obj/effect/turf_decal/tile/dark_blue/opposingcorners, -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /turf/open/floor/iron/dark, /area/shuttle/pirate) "be" = ( diff --git a/_maps/shuttles/pirate_geode.dmm b/_maps/shuttles/pirate_geode.dmm index eb7f8e5c78f..d2e8f034f48 100644 --- a/_maps/shuttles/pirate_geode.dmm +++ b/_maps/shuttles/pirate_geode.dmm @@ -1,30 +1,26 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "at" = ( -/obj/structure/grille, -/obj/effect/spawner/structure/window/hollow/survival_pod, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "geodebridge" - }, -/turf/open/misc/dirt{ - planetary_atmos = 0; - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/obj/structure/barricade/wooden, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "aM" = ( -/obj/machinery/power/shuttle_engine/huge{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/white/line{ +/obj/structure/table/wood, +/obj/machinery/light/small/blacklight/directional{ dir = 8 }, -/turf/open/floor/plating, +/obj/item/restraints/legcuffs/beartrap, +/obj/item/restraints/legcuffs/beartrap, +/obj/item/restraints/legcuffs/beartrap, +/obj/item/grenade/c4, +/obj/item/grenade/c4, +/obj/item/grenade/c4, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "bY" = ( -/obj/effect/turf_decal/lunar_sand/plating, -/obj/effect/turf_decal/weather/dirt{ - dir = 9 +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 }, -/turf/open/floor/plating, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "cx" = ( /obj/effect/turf_decal/lunar_sand/plating, @@ -48,8 +44,8 @@ /turf/open/floor/plating, /area/shuttle/pirate) "ev" = ( -/obj/structure/flora/lunar_plant/style_2, -/turf/open/misc/dirt/jungle, +/obj/machinery/computer/piratepad_control, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "fB" = ( /obj/effect/turf_decal/lunar_sand/plating, @@ -67,10 +63,8 @@ /turf/open/floor/plating, /area/shuttle/pirate) "ga" = ( -/obj/item/stack/sheet/bluespace_crystal{ - amount = 2 - }, -/turf/open/misc/dirt/jungle, +/obj/machinery/space_heater, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "ge" = ( /obj/effect/turf_decal/lunar_sand/plating, @@ -86,21 +80,22 @@ /turf/open/floor/plating, /area/shuttle/pirate) "gv" = ( -/obj/item/reagent_containers/cup/beaker/large, -/turf/open/misc/dirt/jungle, +/obj/machinery/suit_storage_unit/pirate{ + helmet_type = /obj/item/clothing/head/helmet/space/syndicate/blue; + suit_type = /obj/item/clothing/suit/space/syndicate/blue + }, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "gM" = ( -/obj/structure/barricade/wooden, -/turf/open/misc/dirt, +/obj/structure/flora/lunar_plant/style_2, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "hM" = ( -/obj/item/stack/sheet/bluespace_crystal, -/obj/machinery/button/door{ - id = "geodebridge"; - name = "Window Shutters Control"; - pixel_y = 30 +/obj/machinery/porta_turret/syndicate/teleport{ + dir = 4; + faction = list("pirate") }, -/turf/open/misc/dirt/jungle, +/turf/closed/wall/mineral/plastitanium/nodiagonal, /area/shuttle/pirate) "id" = ( /obj/effect/turf_decal/lunar_sand/plating, @@ -159,14 +154,13 @@ /turf/open/floor/plating, /area/shuttle/pirate) "ka" = ( -/obj/machinery/light/small/blacklight/directional{ - dir = 4 - }, -/turf/open/misc/dirt/jungle, +/obj/effect/turf_decal/lunar_sand/plating, +/obj/item/trash/energybar, +/turf/open/floor/plating, /area/shuttle/pirate) "ko" = ( -/obj/machinery/piratepad, -/turf/open/misc/dirt/jungle, +/obj/item/trash/energybar, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "kp" = ( /obj/effect/turf_decal/lunar_sand/plating, @@ -198,12 +192,8 @@ /turf/open/floor/plating, /area/shuttle/pirate) "kV" = ( -/obj/item/stack/sheet/bluespace_crystal{ - amount = 2 - }, -/obj/structure/table/wood, -/obj/machinery/reagentgrinder, -/turf/open/misc/dirt/jungle, +/obj/item/reagent_containers/cup/beaker/large, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "lt" = ( /turf/template_noop, @@ -221,20 +211,17 @@ /turf/open/floor/plating, /area/shuttle/pirate) "mv" = ( -/turf/open/misc/dirt, +/obj/machinery/porta_turret/syndicate/teleport{ + dir = 8; + faction = list("pirate") + }, +/turf/closed/wall/mineral/plastitanium/nodiagonal, /area/shuttle/pirate) "nk" = ( -/obj/structure/table/wood, -/obj/machinery/light/small/blacklight/directional{ - dir = 8 +/obj/item/stack/sheet/bluespace_crystal{ + amount = 2 }, -/obj/item/restraints/legcuffs/beartrap, -/obj/item/restraints/legcuffs/beartrap, -/obj/item/restraints/legcuffs/beartrap, -/obj/item/grenade/c4, -/obj/item/grenade/c4, -/obj/item/grenade/c4, -/turf/open/misc/dirt/jungle, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "nD" = ( /obj/machinery/light/small/blacklight/directional{ @@ -315,8 +302,13 @@ /turf/open/floor/plating, /area/shuttle/pirate) "qp" = ( -/obj/structure/reagent_dispensers/fueltank, -/turf/open/misc/dirt/jungle, +/obj/item/stack/sheet/bluespace_crystal, +/obj/machinery/button/door{ + id = "geodebridge"; + name = "Window Shutters Control"; + pixel_y = 30 + }, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "qK" = ( /obj/effect/turf_decal/lunar_sand/plating, @@ -343,6 +335,12 @@ }, /turf/open/floor/plating, /area/shuttle/pirate) +"rn" = ( +/obj/structure/closet/crate/miningcar, +/obj/effect/spawner/random/maintenance/three, +/obj/item/mining_scanner, +/turf/open/misc/dirt/station, +/area/shuttle/pirate) "rG" = ( /obj/effect/turf_decal/lunar_sand/plating, /obj/effect/turf_decal/weather/dirt{ @@ -383,6 +381,17 @@ /turf/open/floor/plating, /area/shuttle/pirate) "uH" = ( +/obj/effect/turf_decal/lunar_sand/plating, +/obj/effect/turf_decal/weather/dirt{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 4 + }, +/obj/machinery/light/small/blacklight/directional{ + dir = 8 + }, +/obj/effect/spawner/random/trash/mess, /turf/open/floor/plating, /area/shuttle/pirate) "uP" = ( @@ -395,10 +404,21 @@ }, /turf/open/floor/iron/dark, /area/shuttle/pirate) +"vj" = ( +/obj/machinery/computer/shuttle/pirate{ + dir = 8 + }, +/turf/open/misc/dirt/station, +/area/shuttle/pirate) "vl" = ( +/obj/effect/spawner/random/maintenance, +/obj/item/shovel, /obj/structure/closet/crate/miningcar, -/obj/effect/spawner/random/maintenance/three, -/turf/open/misc/dirt/jungle, +/obj/item/stack/sheet/mineral/coal, +/obj/item/stack/rods{ + amount = 5 + }, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "vP" = ( /obj/structure/table/reinforced, @@ -431,16 +451,24 @@ /turf/open/floor/plating, /area/shuttle/pirate) "wz" = ( -/obj/machinery/computer/piratepad_control, -/turf/open/misc/dirt/jungle, +/obj/effect/turf_decal/lunar_sand/plating, +/obj/effect/turf_decal/weather/dirt{ + dir = 3 + }, +/obj/effect/turf_decal/weather/dirt{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/shreds, +/turf/open/floor/plating, /area/shuttle/pirate) "xg" = ( /obj/structure/grille, /obj/effect/spawner/structure/window/hollow/survival_pod, -/turf/open/misc/dirt{ - planetary_atmos = 0; - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/obj/structure/barricade/wooden/crude, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "xN" = ( /obj/effect/turf_decal/lunar_sand/plating, @@ -450,8 +478,9 @@ /turf/open/floor/plating, /area/shuttle/pirate) "xS" = ( -/obj/structure/chair/wood, -/turf/open/misc/dirt/jungle, +/obj/structure/sign/poster/contraband/busty_backdoor_xeno_babes_6/directional/north, +/obj/item/stack/ore/silver, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "yh" = ( /obj/structure/cable, @@ -464,8 +493,8 @@ /turf/open/floor/plating, /area/shuttle/pirate) "yz" = ( -/obj/structure/flora/lunar_plant/style_1, -/turf/open/misc/dirt/jungle, +/obj/structure/flora/lunar_plant/style_3, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "zO" = ( /obj/effect/turf_decal/lunar_sand/plating, @@ -475,28 +504,21 @@ /turf/open/floor/plating, /area/shuttle/pirate) "zS" = ( -/obj/effect/turf_decal/lunar_sand/plating, -/obj/effect/turf_decal/weather/dirt{ - dir = 5 +/obj/item/stack/sheet/bluespace_crystal{ + amount = 2 }, -/turf/open/floor/plating, +/obj/structure/table/wood, +/obj/machinery/reagentgrinder, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "zZ" = ( -/obj/item/stack/sheet/bluespace_crystal, -/turf/open/misc/dirt/jungle, +/obj/structure/reagent_dispensers/watertank, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "At" = ( -/obj/effect/turf_decal/lunar_sand/plating, -/obj/effect/turf_decal/weather/dirt{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ - dir = 4 - }, -/obj/machinery/light/small/blacklight/directional{ - dir = 8 +/turf/closed/mineral/random/jungle{ + baseturfs = null }, -/turf/open/floor/plating, /area/shuttle/pirate) "AT" = ( /obj/effect/turf_decal/lunar_sand/plating, @@ -519,11 +541,13 @@ /turf/open/floor/plating, /area/shuttle/pirate) "BA" = ( -/obj/machinery/airalarm/directional/north, -/obj/structure/table/wood, -/obj/machinery/microwave, -/obj/effect/mapping_helpers/airalarm/all_access, -/turf/open/misc/dirt/jungle, +/obj/structure/closet/crate/cardboard{ + name = "box of climbing hooks" + }, +/obj/item/climbing_hook/syndicate, +/obj/item/climbing_hook/syndicate, +/obj/item/climbing_hook/syndicate, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "BI" = ( /obj/effect/turf_decal/lunar_sand/plating, @@ -547,11 +571,8 @@ /turf/closed/wall/mineral/iron, /area/shuttle/pirate) "Ds" = ( -/obj/structure/rack, -/obj/item/storage/box/syringes, -/obj/item/storage/medkit/brute, -/obj/item/storage/medkit/fire, -/turf/open/misc/dirt/jungle, +/obj/machinery/loot_locator, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "Dw" = ( /obj/machinery/power/port_gen/pacman{ @@ -575,14 +596,8 @@ /turf/open/floor/plating, /area/shuttle/pirate) "DT" = ( -/obj/effect/spawner/random/maintenance, -/obj/item/shovel, -/obj/structure/closet/crate/miningcar, -/obj/item/stack/sheet/mineral/coal, -/obj/item/stack/rods{ - amount = 5 - }, -/turf/open/misc/dirt/jungle, +/obj/structure/fluff/minepost, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "Ec" = ( /obj/effect/turf_decal/lunar_sand/plating, @@ -614,10 +629,8 @@ /turf/open/floor/plating, /area/shuttle/pirate) "Gj" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/turf/open/misc/dirt/jungle, +/obj/machinery/piratepad, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "GQ" = ( /obj/effect/turf_decal/lunar_sand/plating, @@ -641,12 +654,12 @@ /turf/open/floor/plating, /area/shuttle/pirate) "HJ" = ( -/obj/structure/reagent_dispensers/watertank, -/turf/open/misc/dirt/jungle, +/obj/machinery/shuttle_scrambler, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "HY" = ( -/obj/machinery/loot_locator, -/turf/open/misc/dirt/jungle, +/obj/effect/spawner/random/trash/mess, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "Ig" = ( /obj/effect/turf_decal/lunar_sand/plating, @@ -691,6 +704,10 @@ }, /turf/open/floor/iron/dark, /area/shuttle/pirate) +"JK" = ( +/obj/item/stack/sheet/bluespace_crystal, +/turf/open/misc/dirt/station, +/area/shuttle/pirate) "JL" = ( /obj/effect/turf_decal/lunar_sand/plating, /obj/machinery/atmospherics/components/unary/vent_pump/on, @@ -713,9 +730,8 @@ /turf/open/floor/plating, /area/shuttle/pirate) "KK" = ( -/obj/structure/sign/poster/contraband/busty_backdoor_xeno_babes_6/directional/north, -/obj/item/stack/ore/silver, -/turf/open/misc/dirt/jungle, +/obj/structure/reagent_dispensers/fueltank, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "Mc" = ( /obj/effect/turf_decal/lunar_sand/plating, @@ -764,17 +780,19 @@ /turf/open/floor/plating, /area/shuttle/pirate) "Nb" = ( -/obj/structure/grille, -/obj/effect/spawner/structure/window/hollow/survival_pod, -/obj/structure/barricade/wooden/crude, -/turf/open/misc/dirt{ - planetary_atmos = 0; - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/obj/structure/rack, +/obj/item/storage/box/syringes, +/obj/item/storage/medkit/brute, +/obj/item/storage/medkit/fire, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "NT" = ( -/obj/structure/fluff/minepost, -/turf/open/misc/dirt/jungle, +/obj/effect/turf_decal/lunar_sand/plating, +/obj/effect/turf_decal/weather/dirt{ + dir = 9 + }, +/obj/item/trash/energybar, +/turf/open/floor/plating, /area/shuttle/pirate) "Od" = ( /turf/closed/wall/mineral/iron, @@ -792,33 +810,6 @@ /turf/open/floor/plating, /area/shuttle/pirate) "OP" = ( -/obj/machinery/space_heater, -/turf/open/misc/dirt/jungle, -/area/shuttle/pirate) -"OR" = ( -/obj/machinery/porta_turret/syndicate/teleport{ - faction = list("pirate") - }, -/turf/closed/wall/mineral/iron, -/area/shuttle/pirate) -"OX" = ( -/obj/structure/sign/poster/contraband/bountyhunters, -/turf/closed/wall/mineral/iron, -/area/shuttle/pirate) -"Pq" = ( -/obj/machinery/power/shuttle_engine/large{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/white/line{ - dir = 8 - }, -/turf/open/floor/plating, -/area/shuttle/pirate) -"Pr" = ( -/obj/structure/flora/lunar_plant/style_3, -/turf/open/misc/dirt/jungle, -/area/shuttle/pirate) -"PB" = ( /obj/structure/rack, /obj/item/gun/energy/recharge/kinetic_accelerator{ pixel_y = 5 @@ -841,13 +832,45 @@ /obj/item/borg/upgrade/modkit/indoors{ pixel_y = -5 }, -/turf/open/misc/dirt/jungle, +/turf/open/misc/dirt/station, /area/shuttle/pirate) -"Qg" = ( -/obj/machinery/computer/shuttle/pirate{ +"OR" = ( +/obj/machinery/porta_turret/syndicate/teleport{ + faction = list("pirate") + }, +/turf/closed/wall/mineral/iron, +/area/shuttle/pirate) +"OX" = ( +/obj/structure/sign/poster/contraband/bountyhunters, +/turf/closed/wall/mineral/iron, +/area/shuttle/pirate) +"Pq" = ( +/obj/machinery/power/shuttle_engine/propulsion{ dir = 8 }, -/turf/open/misc/dirt/jungle, +/turf/open/floor/plating, +/area/shuttle/pirate) +"Pr" = ( +/obj/structure/table/wood, +/obj/item/food/energybar{ + pixel_y = 9 + }, +/obj/item/food/energybar, +/turf/open/misc/dirt/station, +/area/shuttle/pirate) +"PB" = ( +/obj/machinery/light/small/blacklight/directional{ + dir = 4 + }, +/turf/open/misc/dirt/station, +/area/shuttle/pirate) +"Qg" = ( +/obj/structure/grille, +/obj/effect/spawner/structure/window/hollow/survival_pod, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "geodebridge" + }, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "Qo" = ( /turf/open/floor/iron/stairs{ @@ -864,8 +887,7 @@ /turf/open/floor/iron/dark, /area/shuttle/pirate) "Rp" = ( -/obj/machinery/shuttle_scrambler, -/turf/open/misc/dirt/jungle, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "Rv" = ( /obj/effect/turf_decal/weather/dirt{ @@ -902,7 +924,8 @@ /turf/open/floor/plating, /area/shuttle/pirate) "Sy" = ( -/turf/open/misc/dirt/jungle, +/obj/structure/chair/wood, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "SP" = ( /obj/effect/turf_decal/lunar_sand/plating, @@ -915,8 +938,8 @@ /turf/open/floor/plating, /area/shuttle/pirate) "TC" = ( -/obj/effect/turf_decal/lunar_sand/plating, -/turf/open/floor/plating, +/obj/structure/flora/lunar_plant/style_1, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "Uf" = ( /obj/machinery/power/shuttle_engine/heater{ @@ -940,21 +963,16 @@ /turf/closed/wall/mineral/plastitanium/nodiagonal, /area/shuttle/pirate) "UM" = ( -/obj/item/stack/sheet/bluespace_crystal{ - amount = 2 - }, -/obj/machinery/light/small/blacklight/directional{ - dir = 8 - }, -/turf/open/misc/dirt/jungle, +/obj/structure/grille, +/obj/effect/spawner/structure/window/hollow/survival_pod, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "UY" = ( +/obj/machinery/airalarm/directional/north, /obj/structure/table/wood, -/obj/item/food/energybar{ - pixel_y = 9 - }, -/obj/item/food/energybar, -/turf/open/misc/dirt/jungle, +/obj/machinery/microwave, +/obj/effect/mapping_helpers/airalarm/all_access, +/turf/open/misc/dirt/station, /area/shuttle/pirate) "WR" = ( /obj/effect/turf_decal/lunar_sand/plating, @@ -994,11 +1012,13 @@ /turf/open/floor/plating, /area/shuttle/pirate) "ZF" = ( -/obj/machinery/suit_storage_unit/pirate{ - helmet_type = /obj/item/clothing/head/helmet/space/syndicate/blue; - suit_type = /obj/item/clothing/suit/space/syndicate/blue +/obj/item/stack/sheet/bluespace_crystal{ + amount = 2 + }, +/obj/machinery/light/small/blacklight/directional{ + dir = 8 }, -/turf/open/misc/dirt/jungle, +/turf/open/misc/dirt/station, /area/shuttle/pirate) (1,1,1) = {" @@ -1007,68 +1027,47 @@ lt lt lt lt -lt -lt -lt -yu yu -aM -lt -lt -lt -lt -lt -lt -lt -lt -"} -(2,1,1) = {" -lt -lt -lt -lt -lt yu -Pq jh -uH -uH -uH +yu +yu +yu jh yu -Pq +yu lt lt lt lt lt "} -(3,1,1) = {" +(2,1,1) = {" lt lt lt -jx +mv Od -uH -uH -jx -uH -uH -uH -jx -uH -uH +Pq +Pq +At +Pq +Pq +Pq +At +Pq +Pq Od -jx +mv lt lt lt "} -(4,1,1) = {" +(3,1,1) = {" lt lt -jx -jx +At +At Od Uf Uf @@ -1080,18 +1079,18 @@ Od Uf Uf Od -jx -jx +At +At lt lt "} -(5,1,1) = {" +(4,1,1) = {" lt lt jx jx Od -NT +DT kp Uw Ku @@ -1099,66 +1098,66 @@ ME Dw Uw ZD -NT +DT Od jx jx lt lt "} -(6,1,1) = {" +(5,1,1) = {" lt lt lt jx Od -Sy -zS +Rp +fO IP DM JL DM SP Ih -ga +nk Od jx lt lt lt "} -(7,1,1) = {" +(6,1,1) = {" lt jx jx jx Od -xS -kV +Sy +zS nR WR Oq Mc xN wd -OP +ga Od jx jx jx lt "} -(8,1,1) = {" +(7,1,1) = {" jx jx jx jx Od -KK -gv -Sy -Sy -Sy +xS +kV +ko +Rp +Rp Od Od kM @@ -1169,28 +1168,28 @@ jx jx jx "} -(9,1,1) = {" +(8,1,1) = {" jx jx jx jx Od -ZF -ZF -ZF -Ds -PB +gv +gv +gv +Nb +OP Od -Pr +yz Mm -Sy -vl +Rp +rn Od jx jx jx "} -(10,1,1) = {" +(9,1,1) = {" jx jx Od @@ -1202,58 +1201,58 @@ Od Od Od OX -UY +Pr Mm -ga -DT +nk +vl Od jx jx jx "} -(11,1,1) = {" +(10,1,1) = {" lt jt Od -NT -UM -yz +DT +ZF +TC Od -Rp -nk -HY +HJ +aM +Ds Od -BA +UY Mm -Sy -NT +Rp +DT Od Od Od lt "} -(12,1,1) = {" +(11,1,1) = {" lt -gM -xg -bY +at +UM +NT oa zO Od -Sy -ga -Sy +Rp +nk +Rp Od -Sy +BA Mm -Sy +Rp Dx uk St AT lt "} -(13,1,1) = {" +(12,1,1) = {" lt XB Od @@ -1274,49 +1273,49 @@ Od OR lt "} -(14,1,1) = {" +(13,1,1) = {" lt -mv -Nb +Rp +xg fO pO im Od -ev -rG -Gj +gM +wz +bY Od -Sy -zZ -Sy +HY +JK +Rp lA id St Fx lt "} -(15,1,1) = {" +(14,1,1) = {" lt jx Od -NT -ka -ga +DT +PB +nk Od -wz +ev rG -ko +Gj Od -qp -HJ -Sy -NT +KK +zZ +Rp +DT Od Od Od lt "} -(16,1,1) = {" +(15,1,1) = {" lt jx Od @@ -1337,7 +1336,7 @@ jx jx lt "} -(17,1,1) = {" +(16,1,1) = {" lt jx Od @@ -1345,7 +1344,7 @@ Er YK Qo el -At +uH kx iu iu @@ -1358,14 +1357,14 @@ Od jx lt "} -(18,1,1) = {" +(17,1,1) = {" lt jx Od jD -TC +ka yh -hM +qp oV Hm Mz @@ -1379,18 +1378,18 @@ Cg jx lt "} -(19,1,1) = {" +(18,1,1) = {" lt jx Od Od Od Od -NT -Qg +DT +vj vP vY -NT +DT Rv uP JV @@ -1400,7 +1399,7 @@ Od jx lt "} -(20,1,1) = {" +(19,1,1) = {" lt jx jx @@ -1408,9 +1407,9 @@ jx jx Od Od -at -at -at +Qg +Qg +Qg Od Od Od @@ -1421,18 +1420,18 @@ jx jx lt "} -(21,1,1) = {" +(20,1,1) = {" lt lt jx jx jx jx -jx +hM lt lt lt -jx +hM jx jx jx @@ -1442,7 +1441,7 @@ jx lt lt "} -(22,1,1) = {" +(21,1,1) = {" lt lt lt diff --git a/_maps/shuttles/whiteship_box.dmm b/_maps/shuttles/whiteship_box.dmm index 48d47820df2..cbfdf87ce09 100644 --- a/_maps/shuttles/whiteship_box.dmm +++ b/_maps/shuttles/whiteship_box.dmm @@ -593,7 +593,7 @@ "bs" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /obj/effect/turf_decal/stripes/line{ dir = 9 }, @@ -622,7 +622,7 @@ "bu" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /obj/effect/turf_decal/stripes/line{ dir = 5 }, diff --git a/_maps/templates/battlecruiser_starfury.dmm b/_maps/templates/battlecruiser_starfury.dmm index d3f72900fd4..1e4905ac26e 100644 --- a/_maps/templates/battlecruiser_starfury.dmm +++ b/_maps/templates/battlecruiser_starfury.dmm @@ -3885,7 +3885,7 @@ /turf/open/floor/engine, /area/shuttle/sbc_starfury) "qQ" = ( -/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/machinery/cryo_cell, /turf/open/floor/plating, /area/shuttle/sbc_starfury) "qS" = ( diff --git a/code/__DEFINES/actions.dm b/code/__DEFINES/actions.dm index 066d2d60c1e..5bc2b161781 100644 --- a/code/__DEFINES/actions.dm +++ b/code/__DEFINES/actions.dm @@ -8,6 +8,8 @@ #define AB_CHECK_CONSCIOUS (1<<3) ///Action button checks if user is incapacitated #define AB_CHECK_INCAPACITATED (1<<4) +///Action button checks if user is jaunting +#define AB_CHECK_PHASED (1<<5) DEFINE_BITFIELD(check_flags, list( "CHECK IF HANDS BLOCKED" = AB_CHECK_HANDS_BLOCKED, @@ -15,6 +17,7 @@ DEFINE_BITFIELD(check_flags, list( "CHECK IF LYING DOWN" = AB_CHECK_LYING, "CHECK IF CONSCIOUS" = AB_CHECK_CONSCIOUS, "CHECK IF INCAPACITATED" = AB_CHECK_INCAPACITATED, + "CHECK IF TEMPORARILY INCORPOREAL" = AB_CHECK_PHASED, )) ///Action button triggered with right click diff --git a/code/__DEFINES/ai/ai_blackboard.dm b/code/__DEFINES/ai/ai_blackboard.dm index 443a51a7eb7..e23a5a12dba 100644 --- a/code/__DEFINES/ai/ai_blackboard.dm +++ b/code/__DEFINES/ai/ai_blackboard.dm @@ -8,6 +8,8 @@ #define BB_FOOD_TARGET "bb_food_target" ///Path we should use next time we use the JPS movement datum #define BB_PATH_TO_USE "BB_path_to_use" +///How close a mob must be for us to select it as a target, if that is less than how far we can maintain it as a target +#define BB_AGGRO_RANGE "BB_aggro_range" ///song instrument blackboard, set by instrument subtrees #define BB_SONG_INSTRUMENT "BB_SONG_INSTRUMENT" @@ -41,6 +43,8 @@ #define BB_BASIC_MOB_FLEE_TARGET "BB_basic_flee_target" #define BB_BASIC_MOB_FLEE_TARGET_HIDING_LOCATION "BB_basic_flee_target_hiding_location" #define BB_FLEE_TARGETTING_DATUM "flee_targetting_datum" +#define BB_BASIC_MOB_FLEE_DISTANCE "BB_basic_flee_distance" +#define DEFAULT_BASIC_FLEE_DISTANCE 9 /// Generic key for a non-specific targetted action #define BB_TARGETTED_ACTION "BB_targetted_action" diff --git a/code/__DEFINES/ai/monsters.dm b/code/__DEFINES/ai/monsters.dm index 927f3736832..be9a4be34cd 100644 --- a/code/__DEFINES/ai/monsters.dm +++ b/code/__DEFINES/ai/monsters.dm @@ -146,3 +146,10 @@ #define BB_RAPIDSEEDS_ABILITY "rapidseeds_ability" /// key holds the tray we will beam #define BB_BEAMABLE_HYDROPLANT_TARGET "beamable_hydroplant_target" + +/// Corpse we have consumed +#define BB_LEGION_CORPSE "legion_corpse" +/// Things our target recently said +#define BB_LEGION_RECENT_LINES "legion_recent_lines" +/// The creator of our legion skull +#define BB_LEGION_BROOD_CREATOR "legion_brood_creator" diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index e74cd6a58bd..123c60abad2 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -331,8 +331,8 @@ GLOBAL_LIST_INIT(human_invader_antagonists, list( #define ANTAG_GROUP_PARADOX "Spacetime Aberrations" -// If this flag is enabled the antagonist datum allows the antagonist to be inducted into a nuclear operative team. -#define FLAG_ANTAG_CAN_BE_INDUCTED (1 << 0) +// This flag disables certain checks that presume antagonist datums mean 'baddie'. +#define FLAG_FAKE_ANTAG (1 << 0) #define HUNTER_PACK_COPS "Spacepol Fugitive Hunters" #define HUNTER_PACK_RUSSIAN "Russian Fugitive Hunters" @@ -365,3 +365,5 @@ GLOBAL_LIST_INIT(human_invader_antagonists, list( #define BATON_CUFF 2 #define BATON_PROBE 3 #define BATON_MODES 4 + +#define FREEDOM_IMPLANT_CHARGES 4 diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm index 25bd59bc8b5..b14fd514b85 100644 --- a/code/__DEFINES/colors.dm +++ b/code/__DEFINES/colors.dm @@ -93,6 +93,7 @@ #define COLOR_STRONG_MAGENTA "#B800B8" #define COLOR_PURPLE "#800080" #define COLOR_VIOLET "#B900F7" +#define COLOR_VOID_PURPLE "#53277E" #define COLOR_STRONG_VIOLET "#6927C5" #define COLOR_DARK_PURPLE "#551A8B" diff --git a/code/__DEFINES/cooldowns.dm b/code/__DEFINES/cooldowns.dm index f486e6a943b..63c1f2fd713 100644 --- a/code/__DEFINES/cooldowns.dm +++ b/code/__DEFINES/cooldowns.dm @@ -108,4 +108,6 @@ #define COOLDOWN_RESET(cd_source, cd_index) cd_source.cd_index = 0 +#define COOLDOWN_STARTED(cd_source, cd_index) (cd_source.cd_index != 0) + #define COOLDOWN_TIMELEFT(cd_source, cd_index) (max(0, cd_source.cd_index - world.time)) diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm index dc0293fb274..cd123e2e0b1 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm @@ -11,17 +11,19 @@ #define COMSIG_ATOM_EXAMINE "atom_examine" ///from base of atom/get_examine_name(): (/mob, list/overrides) #define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name" -///from base of atom/examine(): (/mob, list/examine_text, can_see_inside) -#define COMSIG_ATOM_REAGENT_EXAMINE "atom_reagent_examine" - /// Stop the generic reagent examine text - #define STOP_GENERIC_REAGENT_EXAMINE (1<<0) -///from base of atom/examine_more(): (/mob) -#define COMSIG_ATOM_EXAMINE_MORE "atom_examine_more" //Positions for overrides list #define EXAMINE_POSITION_ARTICLE (1<<0) #define EXAMINE_POSITION_BEFORE (1<<1) //End positions #define COMPONENT_EXNAME_CHANGED (1<<0) +///from base of atom/examine(): (/mob, list/examine_text, can_see_inside) +#define COMSIG_ATOM_REAGENT_EXAMINE "atom_reagent_examine" + /// Stop the generic reagent examine text + #define STOP_GENERIC_REAGENT_EXAMINE (1<<0) +///from base of atom/examine_more(): (/mob, examine_list) +#define COMSIG_ATOM_EXAMINE_MORE "atom_examine_more" +/// from atom/examine_more(): (/atom/examining, examine_list) +#define COMSIG_MOB_EXAMINING_MORE "mob_examining_more" ///from base of [/atom/proc/update_appearance]: (updates) #define COMSIG_ATOM_UPDATE_APPEARANCE "atom_update_appearance" /// If returned from [COMSIG_ATOM_UPDATE_APPEARANCE] it prevents the atom from updating its name. diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index 19286859e9e..4521360d039 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -33,6 +33,8 @@ #define COMSIG_MACHINERY_STOP_PROCESSING_AIR "stop_processing_air" ///from /obj/machinery/RefreshParts: () #define COMSIG_MACHINERY_REFRESH_PARTS "machine_refresh_parts" +///from /obj/machinery/default_change_direction_wrench: (mob/user, obj/item/wrench) +#define COMSIG_MACHINERY_DEFAULT_ROTATE_WRENCH "machinery_default_rotate_wrench" ///from /obj/machinery/can_interact(mob/user): Called on user when attempting to interact with a machine (obj/machinery/machine) #define COMSIG_TRY_USE_MACHINE "try_use_machine" @@ -58,9 +60,9 @@ #define COMSIG_SUPERMATTER_DELAM_ALARM "sm_delam_alarm" -// /obj/machinery/atmospherics/components/unary/cryo_cell signals +// /obj/machinery/cryo_cell signals -/// from /obj/machinery/atmospherics/components/unary/cryo_cell/set_on(bool): (on) +/// from /obj/machinery/cryo_cell/set_on(bool): (on) #define COMSIG_CRYO_SET_ON "cryo_set_on" /// from /obj/proc/unfreeze() diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm index c76276c019d..f2f511c791b 100644 --- a/code/__DEFINES/inventory.dm +++ b/code/__DEFINES/inventory.dm @@ -170,6 +170,7 @@ #define MASKCOVERSMOUTH (1<<3) // on other items, these are just for mask/head #define HEADCOVERSMOUTH (1<<4) #define PEPPERPROOF (1<<5) //protects against pepperspray +#define EARS_COVERED (1<<6) #define TINT_DARKENED 2 //Threshold of tint level to apply weld mask overlay #define TINT_BLIND 3 //Threshold of tint level to obscure vision fully diff --git a/code/__DEFINES/magic.dm b/code/__DEFINES/magic.dm index 34ec4b6659b..ecc470c04e9 100644 --- a/code/__DEFINES/magic.dm +++ b/code/__DEFINES/magic.dm @@ -50,8 +50,7 @@ /// Whether the spell can be cast by mobs who are brains / mmis. /// When applying, bear in mind most spells will not function for brains out of the box. #define SPELL_CASTABLE_AS_BRAIN (1 << 2) -/// Whether the spell can be cast while phased, such as blood crawling, ethereal jaunting or using rod form. -#define SPELL_CASTABLE_WHILE_PHASED (1 << 3) + /// Whether the spell can be cast while the user has antimagic on them that corresponds to the spell's own antimagic flags. #define SPELL_REQUIRES_NO_ANTIMAGIC (1 << 4) /// Whether the spell requires being on the station z-level to be cast. @@ -66,7 +65,6 @@ DEFINE_BITFIELD(spell_requirements, list( "SPELL_CASTABLE_AS_BRAIN" = SPELL_CASTABLE_AS_BRAIN, - "SPELL_CASTABLE_WHILE_PHASED" = SPELL_CASTABLE_WHILE_PHASED, "SPELL_CASTABLE_WITHOUT_INVOCATION" = SPELL_CASTABLE_WITHOUT_INVOCATION, "SPELL_REQUIRES_HUMAN" = SPELL_REQUIRES_HUMAN, "SPELL_REQUIRES_MIME_VOW" = SPELL_REQUIRES_MIME_VOW, diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm index eb1b2ecce51..1260e3daf03 100644 --- a/code/__DEFINES/maths.dm +++ b/code/__DEFINES/maths.dm @@ -254,3 +254,6 @@ /// Returns a random decimal between x and y. #define RANDOM_DECIMAL(x, y) LERP((x), (y), rand()) + +#define SI_COEFFICIENT "coefficient" +#define SI_UNIT "unit" diff --git a/code/__DEFINES/mood.dm b/code/__DEFINES/mood.dm new file mode 100644 index 00000000000..161f253b04c --- /dev/null +++ b/code/__DEFINES/mood.dm @@ -0,0 +1 @@ +#define MOOD_CATEGORY_LEGION_CORE "regenerative core" diff --git a/code/__DEFINES/robots.dm b/code/__DEFINES/robots.dm index 7f7961e05be..4d32c136331 100644 --- a/code/__DEFINES/robots.dm +++ b/code/__DEFINES/robots.dm @@ -1,4 +1,4 @@ -/** AI defines */ +// AI defines #define DEFAULT_AI_LAWID "default" #define LAW_ZEROTH "zeroth" @@ -27,7 +27,10 @@ ///Malfunctioning AI hijacking mecha #define AI_MECH_HACK 3 -/** Cyborg defines */ +// Cyborg defines + +/// If an item does this or more throwing damage it will slow a borg down on hit +#define CYBORG_THROW_SLOWDOWN_THRESHOLD 10 /// Special value to reset cyborg's lamp_cooldown #define BORG_LAMP_CD_RESET -1 diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm index 3caed7a0622..d95973e3fdb 100644 --- a/code/__DEFINES/sound.dm +++ b/code/__DEFINES/sound.dm @@ -150,7 +150,6 @@ #define ANNOUNCER_ICARUS "announcer_icarus" #define ANNOUNCER_NRI_RAIDERS "announcer_nri_raiders" #define ANNOUNCER_OUTBREAK6 "announcer_outbreak6" -#define ANNOUNCER_FUNGI "announcer_fungi" #define ANNOUNCER_DEPARTMENTAL "announcer_departmental" #define ANNOUNCER_SHUTTLE "announcer_shuttle" //SKYRAT EDIT END @@ -199,7 +198,6 @@ GLOBAL_LIST_INIT(announcer_keys, list( ANNOUNCER_ICARUS, ANNOUNCER_NRI_RAIDERS, ANNOUNCER_OUTBREAK6, - ANNOUNCER_FUNGI, //SKYRAT EDIT END )) diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 50b33eb4c75..ea182b4088f 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -37,6 +37,7 @@ #define STASIS_CHEMICAL_EFFECT "stasis_chemical" #define STASIS_SHAPECHANGE_EFFECT "stasis_shapechange" #define STASIS_ADMIN "stasis_admin" +#define STASIS_LEGION_EATEN "stasis_eaten" /// Causes the mob to become blind via the passed source #define become_blind(source) apply_status_effect(/datum/status_effect/grouped/blindness, source) diff --git a/code/__DEFINES/supermatter.dm b/code/__DEFINES/supermatter.dm index bac35207fb5..5eab41fcdf9 100644 --- a/code/__DEFINES/supermatter.dm +++ b/code/__DEFINES/supermatter.dm @@ -28,6 +28,12 @@ #define MATTER_POWER_CONVERSION 10 //Crystal converts 1/this value of stored matter into energy. +/// The internal energy gain coefficient. +#define GAS_HEAT_POWER_SCALING_COEFFICIENT (1/6) + +/// The base zap power transmission of the supermatter crystal in W/MeV. +#define BASE_POWER_TRANSMISSION_RATE 1040 + //These would be what you would get at point blank, decreases with distance #define DETONATION_HALLUCINATION (20 MINUTES) @@ -165,9 +171,9 @@ #define SM_TEMP_LIMIT_LOW_MOLES "Low Moles Heat Resistance" /// How much we are multiplying our zap energy. -#define SM_ZAP_BASE "Base Zap Multiplier" +#define SM_ZAP_BASE "Base Zap Transmission" /// How much we are multiplying our zap energy because of gas factors. -#define SM_ZAP_GAS "Gas Zap Multiplier" +#define SM_ZAP_GAS "Gas Zap Transmission Modifier" /// Delamination types. #define CASCADE_DELAMINATION "cascade" #define SINGULARITY_DELAMINATION "singularity" diff --git a/code/__DEFINES/tts.dm b/code/__DEFINES/tts.dm index cca1b5db000..fd88016408c 100644 --- a/code/__DEFINES/tts.dm +++ b/code/__DEFINES/tts.dm @@ -4,3 +4,7 @@ #define TTS_SOUND_ENABLED "Enabled" ///TTS preference is set to only play blips of a sound, rather than speech. #define TTS_SOUND_BLIPS "Blips Only" +///TTS filter to activate start/stop radio clicks on speech. +#define TTS_FILTER_RADIO "radio" +///TTS filter to activate a silicon effect on speech. +#define TTS_FILTER_SILICON "silicon" diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm index 07239ca07c5..1cc9025b821 100644 --- a/code/__DEFINES/vv.dm +++ b/code/__DEFINES/vv.dm @@ -114,6 +114,8 @@ // /mob #define VV_HK_GIB "gib" +#define VV_HK_GIVE_MOB_ACTION "give_mob_action" +#define VV_HK_REMOVE_MOB_ACTION "remove_mob_action" #define VV_HK_GIVE_SPELL "give_spell" #define VV_HK_REMOVE_SPELL "remove_spell" #define VV_HK_GIVE_DISEASE "give_disease" @@ -149,6 +151,7 @@ #define VV_HK_MOD_QUIRKS "quirkmod" #define VV_HK_SET_SPECIES "setspecies" #define VV_HK_PURRBATION "purrbation" +#define VV_HK_APPLY_DNA_INFUSION "apply_dna_infusion" // misc #define VV_HK_SPACEVINE_PURGE "spacevine_purge" diff --git a/code/__DEFINES/~skyrat_defines/nifsofts.dm b/code/__DEFINES/~skyrat_defines/nifsofts.dm index ebf138343c0..f3852414f60 100644 --- a/code/__DEFINES/~skyrat_defines/nifsofts.dm +++ b/code/__DEFINES/~skyrat_defines/nifsofts.dm @@ -4,3 +4,4 @@ #define NIFSOFT_CATEGORY_COSMETIC "Cosmetic" #define NIFSOFT_CATEGORY_UTILITY "Utility" #define NIFSOFT_CATEGORY_FUN "Fun" +#define NIFSOFT_CATEGORY_INFORMATION "Information" diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index 34512b95952..fb1603d650d 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -408,6 +408,17 @@ list_to_clear -= new_list return list_to_clear.len < start_len +/** + * Removes any empty weakrefs from the list + * Returns TRUE if the list had empty refs, FALSE otherwise +**/ +/proc/list_clear_empty_weakrefs(list/list_to_clear) + var/start_len = list_to_clear.len + for(var/datum/weakref/entry in list_to_clear) + if(!entry.resolve()) + list_to_clear -= entry + return list_to_clear.len < start_len + /* * Returns list containing all the entries from first list that are not present in second. * If skiprep = 1, repeated elements are treated as one. diff --git a/code/__HELPERS/maths.dm b/code/__HELPERS/maths.dm index 6cda3466949..116fb34fad5 100644 --- a/code/__HELPERS/maths.dm +++ b/code/__HELPERS/maths.dm @@ -119,25 +119,48 @@ dx -= 1 return perimeter -///Format a power value in W, kW, MW, or GW. +/** + * Formats a number into a list representing the si unit. + * Access the coefficient with [SI_COEFFICIENT], and access the unit with [SI_UNIT]. + * + * Supports SI exponents between 1e-15 to 1e15, but properly handles numbers outside that range as well. + * Arguments: + * * value - The number to convert to text. Can be positive or negative. + * * unit - The base unit of the number, such as "Pa" or "W". + * * maxdecimals - Maximum amount of decimals to display for the final number. Defaults to 1. + * Returns: [SI_COEFFICIENT = si unit coefficient, SI_UNIT = prefixed si unit.] + */ +/proc/siunit_isolated(value, unit, maxdecimals=1) + var/static/list/prefixes = list("f","p","n","μ","m","","k","M","G","T","P") + + // We don't have prefixes beyond this point + // and this also captures value = 0 which you can't compute the logarithm for + // and also byond numbers are floats and doesn't have much precision beyond this point anyway + if(abs(value) <= 1e-18) + . = list(SI_COEFFICIENT = 0, SI_UNIT = " [unit]") + return + + var/exponent = clamp(log(10, abs(value)), -15, 15) // Calculate the exponent and clamp it so we don't go outside the prefix list bounds + var/divider = 10 ** (round(exponent / 3) * 3) // Rounds the exponent to nearest SI unit and power it back to the full form + var/coefficient = round(value / divider, 10 ** -maxdecimals) // Calculate the coefficient and round it to desired decimals + var/prefix_index = round(exponent / 3) + 6 // Calculate the index in the prefixes list for this exponent + + // An edge case which happens if we round 999.9 to 0 decimals for example, which gets rounded to 1000 + // In that case, we manually swap up to the next prefix if there is one available + if(coefficient >= 1000 && prefix_index < 11) + coefficient /= 1e3 + prefix_index++ + + var/prefix = prefixes[prefix_index] + . = list(SI_COEFFICIENT = coefficient, SI_UNIT = " [prefix][unit]") + +///Format a power value in prefixed watts. /proc/display_power(powerused) - if(powerused < 1000) //Less than a kW - return "[powerused] W" - else if(powerused < 1000000) //Less than a MW - return "[round((powerused * 0.001),0.01)] kW" - else if(powerused < 1000000000) //Less than a GW - return "[round((powerused * 0.000001),0.001)] MW" - return "[round((powerused * 0.000000001),0.0001)] GW" - -///Format an energy value in J, kJ, MJ, or GJ. 1W = 1J/s. + return siunit(powerused, "W", 3) + +///Format an energy value in prefixed joules. /proc/display_joules(units) - if (units < 1000) // Less than a kJ - return "[round(units, 0.1)] J" - else if (units < 1000000) // Less than a MJ - return "[round(units * 0.001, 0.01)] kJ" - else if (units < 1000000000) // Less than a GJ - return "[round(units * 0.000001, 0.001)] MJ" - return "[round(units * 0.000000001, 0.0001)] GJ" + return siunit(units, "J", 3) /proc/joules_to_energy(joules) return joules * (1 SECONDS) / SSmachines.wait diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index f75e6770207..91406650d20 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -191,7 +191,7 @@ // 0 .. 9 if(48 to 57) //Numbers - if(last_char_group == NO_CHARS_DETECTED || !allow_numbers) //suppress at start of string + if(!allow_numbers) //allow name to start with number if AI/Borg if(strict) return continue @@ -1048,27 +1048,8 @@ GLOBAL_LIST_INIT(binary, list("0","1")) * * For pressure conversion, use proc/siunit_pressure() below */ /proc/siunit(value, unit, maxdecimals=1) - var/static/list/prefixes = list("f","p","n","μ","m","","k","M","G","T","P") - - // We don't have prefixes beyond this point - // and this also captures value = 0 which you can't compute the logarithm for - // and also byond numbers are floats and doesn't have much precision beyond this point anyway - if(abs(value) <= 1e-18) - return "0 [unit]" - - var/exponent = clamp(log(10, abs(value)), -15, 15) // Calculate the exponent and clamp it so we don't go outside the prefix list bounds - var/divider = 10 ** (round(exponent / 3) * 3) // Rounds the exponent to nearest SI unit and power it back to the full form - var/coefficient = round(value / divider, 10 ** -maxdecimals) // Calculate the coefficient and round it to desired decimals - var/prefix_index = round(exponent / 3) + 6 // Calculate the index in the prefixes list for this exponent - - // An edge case which happens if we round 999.9 to 0 decimals for example, which gets rounded to 1000 - // In that case, we manually swap up to the next prefix if there is one available - if(coefficient >= 1000 && prefix_index < 11) - coefficient /= 1e3 - prefix_index++ - - var/prefix = prefixes[prefix_index] - return "[coefficient] [prefix][unit]" + var/si_isolated = siunit_isolated(value, unit, maxdecimals) + return "[si_isolated[SI_COEFFICIENT]][si_isolated[SI_UNIT]]" /** The game code never uses Pa, but kPa, since 1 Pa is too small to reasonably handle diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm index d16c466f9dc..aa84927af03 100644 --- a/code/_globalvars/lists/maintenance_loot.dm +++ b/code/_globalvars/lists/maintenance_loot.dm @@ -347,6 +347,7 @@ GLOBAL_LIST_INIT(rarity_loot, list(//rare: really good items /obj/item/book/granter/crafting_recipe/dusting/laser_musket_prime = 1, /obj/item/book/granter/sign_language = 1, /obj/item/disk/nuclear/fake = 1, + /obj/item/disk/surgery/advanced_plastic_surgery = 1, /obj/item/skillchip/brainwashing = 1, /obj/item/tattoo_kit = 1, /obj/item/folder/ancient_paperwork = 1, diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index 6f7d9c987f7..f87896e4521 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -113,7 +113,7 @@ GLOBAL_LIST_INIT(construct_radial_images, list( /proc/get_crewmember_minds() var/list/minds = list() for(var/datum/record/locked/target in GLOB.manifest.locked) - var/datum/mind/mind = target.mind_ref + var/datum/mind/mind = target.mind_ref.resolve() if(mind) minds += mind return minds diff --git a/code/_globalvars/lists/quirks.dm b/code/_globalvars/lists/quirks.dm index 9d936c18e56..f907206a30c 100644 --- a/code/_globalvars/lists/quirks.dm +++ b/code/_globalvars/lists/quirks.dm @@ -11,3 +11,11 @@ GLOBAL_LIST_INIT(nearsighted_glasses, list( "Modern" = /obj/item/clothing/glasses/betterunshit, // SKYRAT ADD )) + +///Options for the prothetic limb quirk to choose from +GLOBAL_LIST_INIT(limb_choice, list( + "Left Arm" = /obj/item/bodypart/arm/left/robot/surplus, + "Right Arm" = /obj/item/bodypart/arm/right/robot/surplus, + "Left Leg" = /obj/item/bodypart/leg/left/robot/surplus, + "Right Leg" = /obj/item/bodypart/leg/right/robot/surplus, +)) diff --git a/code/_globalvars/phobias.dm b/code/_globalvars/phobias.dm index a6cb2dedb32..a913410214d 100644 --- a/code/_globalvars/phobias.dm +++ b/code/_globalvars/phobias.dm @@ -88,7 +88,7 @@ GLOBAL_LIST_INIT(phobia_mobs, list( "security" = typecacheof(list(/mob/living/simple_animal/bot/secbot)), "spiders" = typecacheof(list(/mob/living/basic/spider/giant)), "skeletons" = typecacheof(list(/mob/living/simple_animal/hostile/skeleton)), - "snakes" = typecacheof(list(/mob/living/simple_animal/hostile/retaliate/snake)), + "snakes" = typecacheof(list(/mob/living/basic/snake)), "the supernatural" = typecacheof(list( /mob/dead/observer, /mob/living/basic/bat, @@ -331,7 +331,7 @@ GLOBAL_LIST_INIT(phobia_objs, list( /obj/item/storage/pill_bottle, /obj/item/surgical_drapes, /obj/item/surgicaldrill, - /obj/machinery/atmospherics/components/unary/cryo_cell, + /obj/machinery/cryo_cell, /obj/machinery/dna_scannernew, /obj/machinery/door/airlock/medical, /obj/machinery/sleeper, diff --git a/code/controllers/configuration/entries/jobs.dm b/code/controllers/configuration/entries/jobs.dm index 99a3ab7a701..06563e01a8e 100644 --- a/code/controllers/configuration/entries/jobs.dm +++ b/code/controllers/configuration/entries/jobs.dm @@ -9,7 +9,7 @@ return returnable_list /// Sets all of the job datum configurable values to what they've been set to in the config file, jobconfig.toml. -/datum/controller/subsystem/job/proc/load_jobs_from_config() +/datum/controller/subsystem/job/proc/load_jobs_from_config(silent = FALSE) if(!length(job_config_datum_singletons)) stack_trace("SSjob tried to load jobs from config, but the config singletons were not initialized! Likely tried to load jobs before SSjob was initialized.") return @@ -25,7 +25,8 @@ var/job_key = occupation.config_tag if(!job_config[job_key]) // Job isn't listed, skip it. // List both job_title and job_key in case they de-sync over time. - message_admins(span_notice("[occupation.title] (with config key [job_key]) is missing from jobconfig.toml! Using codebase defaults.")) + if(!silent) + message_admins(span_notice("[occupation.title] (with config key [job_key]) is missing from jobconfig.toml! Using codebase defaults.")) continue for(var/config_datum_key in job_config_datum_singletons) diff --git a/code/controllers/subsystem/economy.dm b/code/controllers/subsystem/economy.dm index b8e1ab9e772..e396bcb8445 100644 --- a/code/controllers/subsystem/economy.dm +++ b/code/controllers/subsystem/economy.dm @@ -204,9 +204,9 @@ SUBSYSTEM_DEF(economy) CRASH("Track purchases was missing an argument! (Account, Price, or Vendor.)") audit_log += list(list( - "account" = account.account_holder, + "account" = "[account.account_holder]", "cost" = price_to_use, - "vendor" = vendor, + "vendor" = "[vendor]", )) /** diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index 5c957445526..976b4bab249 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -305,6 +305,10 @@ SUBSYSTEM_DEF(job) player.mind.special_role = null SetupOccupations() unassigned = list() + if(CONFIG_GET(flag/load_jobs_from_txt)) + // Any errors with the configs has already been said, we don't need to repeat them here. + load_jobs_from_config(silent = TRUE) + set_overflow_role(overflow_role) return diff --git a/code/controllers/subsystem/radiation.dm b/code/controllers/subsystem/radiation.dm index b2b3d1926dd..d52fe83856a 100644 --- a/code/controllers/subsystem/radiation.dm +++ b/code/controllers/subsystem/radiation.dm @@ -135,7 +135,7 @@ SUBSYSTEM_DEF(radiation) for (var/obj/item/bodypart/limb as anything in human.bodyparts) var/protected = FALSE - for (var/obj/item/clothing as anything in human.clothingonpart(limb)) + for (var/obj/item/clothing as anything in human.get_clothing_on_part(limb)) if (HAS_TRAIT(clothing, TRAIT_RADIATION_PROTECTED_CLOTHING)) protected = TRUE break diff --git a/code/controllers/subsystem/tts.dm b/code/controllers/subsystem/tts.dm index 712168b5027..b9cb85ea78a 100644 --- a/code/controllers/subsystem/tts.dm +++ b/code/controllers/subsystem/tts.dm @@ -261,7 +261,7 @@ SUBSYSTEM_DEF(tts) #undef TTS_ARBRITRARY_DELAY -/datum/controller/subsystem/tts/proc/queue_tts_message(datum/target, message, datum/language/language, speaker, filter, list/listeners, local = FALSE, message_range = 7, volume_offset = 0, pitch = 0, silicon = "") +/datum/controller/subsystem/tts/proc/queue_tts_message(datum/target, message, datum/language/language, speaker, filter, list/listeners, local = FALSE, message_range = 7, volume_offset = 0, pitch = 0, special_filters = "") if(!tts_enabled) return @@ -277,7 +277,7 @@ SUBSYSTEM_DEF(tts) var/shell_scrubbed_input = tts_speech_filter(message) shell_scrubbed_input = copytext(shell_scrubbed_input, 1, 300) - var/identifier = "[sha1(speaker + filter + num2text(pitch) + num2text(silicon) + shell_scrubbed_input)].[world.time]" + var/identifier = "[sha1(speaker + filter + num2text(pitch) + special_filters + shell_scrubbed_input)].[world.time]" if(!(speaker in available_speakers)) return @@ -288,9 +288,9 @@ SUBSYSTEM_DEF(tts) var/datum/http_request/request_blips = new() var/file_name = "tmp/tts/[identifier].ogg" var/file_name_blips = "tmp/tts/[identifier]_blips.ogg" - request.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/tts_http_url)]/tts?voice=[speaker]&identifier=[identifier]&filter=[url_encode(filter)]&pitch=[pitch]&silicon=[silicon]", json_encode(list("text" = shell_scrubbed_input)), headers, file_name) - request_blips.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/tts_http_url)]/tts-blips?voice=[speaker]&identifier=[identifier]&filter=[url_encode(filter)]&pitch=[pitch]&silicon=[silicon]", json_encode(list("text" = shell_scrubbed_input)), headers, file_name_blips) - var/datum/tts_request/current_request = new /datum/tts_request(identifier, request, request_blips, shell_scrubbed_input, target, local, language, message_range, volume_offset, listeners, pitch, silicon) + request.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/tts_http_url)]/tts?voice=[speaker]&identifier=[identifier]&filter=[url_encode(filter)]&pitch=[pitch]&special_filters=[url_encode(special_filters)]", json_encode(list("text" = shell_scrubbed_input)), headers, file_name) + request_blips.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/tts_http_url)]/tts-blips?voice=[speaker]&identifier=[identifier]&filter=[url_encode(filter)]&pitch=[pitch]&special_filters=[url_encode(special_filters)]", json_encode(list("text" = shell_scrubbed_input)), headers, file_name_blips) + var/datum/tts_request/current_request = new /datum/tts_request(identifier, request, request_blips, shell_scrubbed_input, target, local, language, message_range, volume_offset, listeners, pitch) var/list/player_queued_tts_messages = queued_tts_messages[target] if(!player_queued_tts_messages) player_queued_tts_messages = list() @@ -342,8 +342,6 @@ SUBSYSTEM_DEF(tts) var/use_blips = FALSE /// What's the pitch adjustment? var/pitch = 0 - /// Are we using the silicon vocal effect on this? - var/silicon = "" /datum/tts_request/New(identifier, datum/http_request/request, datum/http_request/request_blips, message, target, local, datum/language/language, message_range, volume_offset, list/listeners, pitch) diff --git a/code/datums/actions/action.dm b/code/datums/actions/action.dm index b43220fb7d4..843998ff50e 100644 --- a/code/datums/actions/action.dm +++ b/code/datums/actions/action.dm @@ -96,13 +96,15 @@ if(check_flags & AB_CHECK_CONSCIOUS) RegisterSignal(owner, COMSIG_MOB_STATCHANGE, PROC_REF(update_status_on_signal)) if(check_flags & AB_CHECK_INCAPACITATED) - RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_INCAPACITATED), PROC_REF(update_status_on_signal)) + RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_INCAPACITATED), SIGNAL_REMOVETRAIT(TRAIT_INCAPACITATED)), PROC_REF(update_status_on_signal)) if(check_flags & AB_CHECK_IMMOBILE) - RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_IMMOBILIZED), PROC_REF(update_status_on_signal)) + RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_IMMOBILIZED), SIGNAL_REMOVETRAIT(TRAIT_IMMOBILIZED)), PROC_REF(update_status_on_signal)) if(check_flags & AB_CHECK_HANDS_BLOCKED) - RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED), PROC_REF(update_status_on_signal)) + RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED), SIGNAL_REMOVETRAIT(TRAIT_HANDS_BLOCKED)), PROC_REF(update_status_on_signal)) if(check_flags & AB_CHECK_LYING) RegisterSignal(owner, COMSIG_LIVING_SET_BODY_POSITION, PROC_REF(update_status_on_signal)) + if(check_flags & AB_CHECK_PHASED) + RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_MAGICALLY_PHASED), SIGNAL_REMOVETRAIT(TRAIT_MAGICALLY_PHASED)), PROC_REF(update_status_on_signal)) if(owner_has_control) GiveAction(grant_to) @@ -130,6 +132,11 @@ SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED), SIGNAL_ADDTRAIT(TRAIT_IMMOBILIZED), SIGNAL_ADDTRAIT(TRAIT_INCAPACITATED), + SIGNAL_ADDTRAIT(TRAIT_MAGICALLY_PHASED), + SIGNAL_REMOVETRAIT(TRAIT_HANDS_BLOCKED), + SIGNAL_REMOVETRAIT(TRAIT_IMMOBILIZED), + SIGNAL_REMOVETRAIT(TRAIT_INCAPACITATED), + SIGNAL_REMOVETRAIT(TRAIT_MAGICALLY_PHASED), )) if(target == owner) @@ -174,6 +181,10 @@ if (feedback) owner.balloon_alert(owner, "unconscious!") return FALSE + if((check_flags & AB_CHECK_PHASED) && HAS_TRAIT(owner, TRAIT_MAGICALLY_PHASED)) + if (feedback) + owner.balloon_alert(owner, "incorporeal!") + return FALSE return TRUE /// Builds / updates all buttons we have shared or given out diff --git a/code/datums/actions/mobs/charge.dm b/code/datums/actions/mobs/charge.dm index 2ae576f5e61..7fb56209777 100644 --- a/code/datums/actions/mobs/charge.dm +++ b/code/datums/actions/mobs/charge.dm @@ -51,6 +51,7 @@ RegisterSignal(charger, COMSIG_MOVABLE_BUMP, PROC_REF(on_bump), TRUE) RegisterSignal(charger, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_move), TRUE) RegisterSignal(charger, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved), TRUE) + RegisterSignal(charger, COMSIG_LIVING_DEATH, PROC_REF(charge_end)) charger.setDir(dir) do_charge_indicator(charger, target) @@ -80,10 +81,13 @@ SIGNAL_HANDLER actively_moving = FALSE -/datum/action/cooldown/mob_cooldown/charge/proc/charge_end(datum/move_loop/source) +/datum/action/cooldown/mob_cooldown/charge/proc/charge_end(datum/source) SIGNAL_HANDLER - var/atom/movable/charger = source.moving - UnregisterSignal(charger, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED)) + var/atom/movable/charger = source + if(istype(source, /datum/move_loop)) + var/datum/move_loop/move_loop_source = source + charger = move_loop_source.moving + UnregisterSignal(charger, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED, COMSIG_LIVING_DEATH)) SEND_SIGNAL(owner, COMSIG_FINISHED_CHARGE) actively_moving = FALSE charging -= charger diff --git a/code/datums/actions/mobs/open_mob_commands.dm b/code/datums/actions/mobs/open_mob_commands.dm index 008e7c4dc1b..e7ffd104eff 100644 --- a/code/datums/actions/mobs/open_mob_commands.dm +++ b/code/datums/actions/mobs/open_mob_commands.dm @@ -5,6 +5,7 @@ overlay_icon_state = "bg_heretic_border" button_icon = 'icons/mob/actions/actions_ecult.dmi' button_icon_state = "stargazer_menu" + check_flags = AB_CHECK_CONSCIOUS | AB_CHECK_INCAPACITATED | AB_CHECK_PHASED /// Weakref for storing our stargazer var/datum/weakref/our_mob diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm index 6683fb02f93..91ba7ec4894 100644 --- a/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm +++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm @@ -51,6 +51,8 @@ required_distance = 3 /// range we will try chasing the target before giving up var/chase_range = 9 + ///do we care about avoiding friendly fire? + var/avoid_friendly_fire = FALSE /datum/ai_behavior/basic_ranged_attack/setup(datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key) . = ..() @@ -75,6 +77,10 @@ if(!can_see(basic_mob, final_target, required_distance)) return + if(avoid_friendly_fire && check_friendly_in_path(basic_mob, target, targetting_datum)) + adjust_position(basic_mob, target) + return ..() + controller.set_blackboard_key(hiding_location_key, hiding_target) basic_mob.RangedAttack(final_target) return ..() //only start the cooldown when the shot is shot @@ -83,3 +89,52 @@ . = ..() if(!succeeded) controller.clear_blackboard_key(target_key) + +/datum/ai_behavior/basic_ranged_attack/proc/check_friendly_in_path(mob/living/source, atom/target, datum/targetting_datum/targetting_datum) + var/list/turfs_list = calculate_trajectory(source, target) + for(var/turf/possible_turf as anything in turfs_list) + + for(var/mob/living/potential_friend in possible_turf) + if(!targetting_datum.can_attack(source, potential_friend)) + return TRUE + + return FALSE + +/datum/ai_behavior/basic_ranged_attack/proc/adjust_position(mob/living/living_pawn, atom/target) + var/turf/our_turf = get_turf(living_pawn) + var/list/possible_turfs = list() + + for(var/direction in GLOB.alldirs) + var/turf/target_turf = get_step(our_turf, direction) + if(isnull(target_turf)) + continue + if(target_turf.is_blocked_turf() || get_dist(target_turf, target) > get_dist(living_pawn, target)) + continue + possible_turfs += target_turf + + if(!length(possible_turfs)) + return + var/turf/picked_turf = get_closest_atom(/turf, possible_turfs, target) + step(living_pawn, get_dir(living_pawn, picked_turf)) + +/datum/ai_behavior/basic_ranged_attack/proc/calculate_trajectory(mob/living/source , atom/target) + var/list/turf_list = get_line(source, target) + var/list_length = length(turf_list) - 1 + for(var/i in 1 to list_length) + var/turf/current_turf = turf_list[i] + var/turf/next_turf = turf_list[i+1] + var/direction_to_turf = get_dir(current_turf, next_turf) + if(!ISDIAGONALDIR(direction_to_turf)) + continue + + for(var/cardinal_direction in GLOB.cardinals) + if(cardinal_direction & direction_to_turf) + turf_list += get_step(current_turf, cardinal_direction) + + turf_list -= get_turf(source) + turf_list -= get_turf(target) + + return turf_list + +/datum/ai_behavior/basic_ranged_attack/avoid_friendly_fire + avoid_friendly_fire = TRUE diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm index 486f9a0fdb2..bd86260ee89 100644 --- a/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm +++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm @@ -4,7 +4,7 @@ action_cooldown = 0 behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION /// How far do we try to run? Further makes for smoother running, but potentially weirder pathfinding - var/run_distance = 9 + var/run_distance = DEFAULT_BASIC_FLEE_DISTANCE /// Clear target if we finish the action unsuccessfully var/clear_failed_targets = TRUE @@ -12,6 +12,7 @@ var/atom/target = controller.blackboard[hiding_location_key] || controller.blackboard[target_key] if(QDELETED(target)) return FALSE + run_distance = controller.blackboard[BB_BASIC_MOB_FLEE_DISTANCE] || initial(run_distance) if(!plot_path_away_from(controller, target)) return FALSE return ..() @@ -21,13 +22,12 @@ if (!controller.blackboard[BB_BASIC_MOB_FLEEING]) return var/atom/target = controller.blackboard[hiding_location_key] || controller.blackboard[target_key] - var/escaped = QDELETED(target) || !can_see(controller.pawn, target, run_distance) // If we can't see it we got away - if (escaped) + if (QDELETED(target) || !can_see(controller.pawn, target, run_distance)) finish_action(controller, succeeded = TRUE, target_key = target_key, hiding_location_key = hiding_location_key) return - if (get_dist(controller.pawn, controller.current_movement_target) > required_distance) - return - if(plot_path_away_from(controller, target)) + if (get_dist(controller.pawn, controller.current_movement_target) >= required_distance) + return // Still heading over + if (plot_path_away_from(controller, target)) return finish_action(controller, succeeded = FALSE, target_key = target_key, hiding_location_key = hiding_location_key) diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/targetting.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/targetting.dm index 9d7587c712b..0b9e31db667 100644 --- a/code/datums/ai/basic_mobs/basic_ai_behaviors/targetting.dm +++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/targetting.dm @@ -2,6 +2,8 @@ action_cooldown = 2 SECONDS /// How far can we see stuff? var/vision_range = 9 + /// Blackboard key for aggro range, uses vision range if not specified + var/aggro_range_key = BB_AGGRO_RANGE /// Static typecache list of potentially dangerous objs var/static/list/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/vehicle/sealed/mecha)) @@ -18,11 +20,13 @@ finish_action(controller, succeeded = FALSE) return + var/aggro_range = controller.blackboard[aggro_range_key] || vision_range + controller.clear_blackboard_key(target_key) - var/list/potential_targets = hearers(vision_range, controller.pawn) - living_mob //Remove self, so we don't suicide + var/list/potential_targets = hearers(aggro_range, controller.pawn) - living_mob //Remove self, so we don't suicide - for(var/HM in typecache_filter_list(range(vision_range, living_mob), hostile_machines)) //Can we see any hostile machines? - if(can_see(living_mob, HM, vision_range)) + for(var/HM in typecache_filter_list(range(aggro_range, living_mob), hostile_machines)) //Can we see any hostile machines? + if(can_see(living_mob, HM, aggro_range)) potential_targets += HM if(!potential_targets.len) diff --git a/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm b/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm index a4982fa660e..8d1391f7c7d 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm @@ -9,8 +9,13 @@ /datum/ai_planning_subtree/flee_target/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) . = ..() - if (!controller.blackboard[BB_BASIC_MOB_FLEEING] || !controller.blackboard_key_exists(target_key)) + var/atom/flee_from = controller.blackboard[target_key] + if (!controller.blackboard[BB_BASIC_MOB_FLEEING] || QDELETED(flee_from)) return + var/flee_distance = controller.blackboard[BB_BASIC_MOB_FLEE_DISTANCE] || DEFAULT_BASIC_FLEE_DISTANCE + if (get_dist(controller.pawn, flee_from) >= flee_distance) + return + controller.queue_behavior(flee_behaviour, target_key, hiding_place_key) return SUBTREE_RETURN_FINISH_PLANNING //we gotta get out of here. diff --git a/code/datums/ai/basic_mobs/basic_subtrees/maintain_distance.dm b/code/datums/ai/basic_mobs/basic_subtrees/maintain_distance.dm index b80a28836a0..c09e7cdbf75 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/maintain_distance.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/maintain_distance.dm @@ -3,7 +3,7 @@ /// Blackboard key holding atom we want to stay away from var/target_key = BB_BASIC_MOB_CURRENT_TARGET /// How close will we allow our target to get? - var/minimum_distance = 3 + var/minimum_distance = 4 /// How far away will we allow our target to get? var/maximum_distance = 6 /// How far do we look for our target? diff --git a/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm b/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm index 005a9ee835d..52f4a3459bf 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm @@ -22,24 +22,31 @@ emote_see = string_list(emote_see) /datum/ai_planning_subtree/random_speech/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) - if(SPT_PROB(speech_chance, seconds_per_tick)) - var/audible_emotes_length = emote_hear?.len - var/non_audible_emotes_length = emote_see?.len - var/speak_lines_length = speak?.len + if(!SPT_PROB(speech_chance, seconds_per_tick)) + return + speak(controller) + +/// Actually perform an action +/datum/ai_planning_subtree/random_speech/proc/speak(datum/ai_controller/controller) + var/audible_emotes_length = emote_hear?.len + var/non_audible_emotes_length = emote_see?.len + var/speak_lines_length = speak?.len - var/total_choices_length = audible_emotes_length + non_audible_emotes_length + speak_lines_length + var/total_choices_length = audible_emotes_length + non_audible_emotes_length + speak_lines_length - var/random_number_in_range = rand(1, total_choices_length) + var/random_number_in_range = rand(1, total_choices_length) + var/sound_to_play = length(sound) > 0 ? pick(sound) : null - if(random_number_in_range <= audible_emotes_length) - controller.queue_behavior(/datum/ai_behavior/perform_emote, pick(emote_hear)) - else if(random_number_in_range <= (audible_emotes_length + non_audible_emotes_length)) - controller.queue_behavior(/datum/ai_behavior/perform_emote, pick(emote_see)) - else - controller.queue_behavior(/datum/ai_behavior/perform_speech, pick(speak), length(sound) > 0 ? pick(sound) : null) + if(random_number_in_range <= audible_emotes_length) + controller.queue_behavior(/datum/ai_behavior/perform_emote, pick(emote_hear), sound_to_play) + else if(random_number_in_range <= (audible_emotes_length + non_audible_emotes_length)) + controller.queue_behavior(/datum/ai_behavior/perform_emote, pick(emote_see)) + else + controller.queue_behavior(/datum/ai_behavior/perform_speech, pick(speak), sound_to_play) /datum/ai_planning_subtree/random_speech/insect speech_chance = 5 + sound = list('sound/creatures/chitter.ogg') emote_hear = list("chitters.") /datum/ai_planning_subtree/random_speech/mothroach @@ -49,6 +56,7 @@ /datum/ai_planning_subtree/random_speech/mouse speech_chance = 1 speak = list("Squeak!", "SQUEAK!", "Squeak?") + sound = list('sound/creatures/mousesqueek.ogg') emote_hear = list("squeaks.") emote_see = list("runs in a circle.", "shakes.") @@ -93,12 +101,14 @@ /datum/ai_planning_subtree/random_speech/chicken speech_chance = 15 // really talkative ladies speak = list("Cluck!", "BWAAAAARK BWAK BWAK BWAK!", "Bwaak bwak.") + sound = list('sound/creatures/clucks.ogg', 'sound/creatures/bagawk.ogg') emote_hear = list("clucks.", "croons.") emote_see = list("pecks at the ground.","flaps her wings viciously.") /datum/ai_planning_subtree/random_speech/chick speech_chance = 4 speak = list("Cherp.", "Cherp?", "Chirrup.", "Cheep!") + sound = list('sound/creatures/chick_peep.ogg') emote_hear = list("cheeps.") emote_see = list("pecks at the ground.","flaps her tiny wings.") @@ -160,33 +170,37 @@ /datum/ai_planning_subtree/random_speech/pony speech_chance = 3 + sound = list('sound/creatures/pony/whinny01.ogg', 'sound/creatures/pony/whinny02.ogg', 'sound/creatures/pony/whinny03.ogg') emote_hear = list("whinnies!") emote_see = list("horses around.") /datum/ai_planning_subtree/random_speech/pony/tamed speech_chance = 3 + sound = list('sound/creatures/pony/snort.ogg') + emote_hear = list("snorts.") emote_see = list("snorts.") /datum/ai_planning_subtree/random_speech/killer_tomato speech_chance = 3 - speak = list("gnashes.", "growls lowly.", "snarls.") - emote_hear = list("gnashes.") + emote_hear = list("gnashes.", "growls lowly.", "snarls.") emote_see = list("salivates.") /datum/ai_planning_subtree/random_speech/ant speech_chance = 1 + speak = list("BZZZZT!", "CHTCHTCHT!", "Bzzz", "ChtChtCht") + sound = list('sound/creatures/chitter.ogg') emote_hear = list("buzzes.", "clacks.") emote_see = list("shakes their head.", "twitches their antennae.") - speak = list("BZZZZT!", "CHTCHTCHT!", "Bzzz", "ChtChtCht") /datum/ai_planning_subtree/random_speech/fox speech_chance = 1 + speak = list("Ack-Ack", "Ack-Ack-Ack-Ackawoooo", "Geckers", "Awoo", "Tchoff") emote_hear = list("howls.", "barks.", "screams.") emote_see = list("shakes their head.", "shivers.") - speak = list("Ack-Ack", "Ack-Ack-Ack-Ackawoooo", "Geckers", "Awoo", "Tchoff") /datum/ai_planning_subtree/random_speech/crab speech_chance = 1 + sound = list('sound/creatures/claw_click.ogg') emote_hear = list("clicks.") emote_see = list("clacks.") @@ -207,11 +221,13 @@ var/list/speech_lines = controller.blackboard[BB_BASIC_MOB_SPEAK_LINES] if(isnull(speech_lines)) return ..() - - speak = speech_lines[BB_EMOTE_SAY] ? speech_lines[BB_EMOTE_SAY] : initial(speak) - emote_see = speech_lines[BB_EMOTE_SEE] ? speech_lines[BB_EMOTE_SEE] : initial(emote_see) - emote_hear = speech_lines[BB_EMOTE_HEAR] ? speech_lines[BB_EMOTE_HEAR] : initial(emote_hear) - sound = speech_lines[BB_EMOTE_SOUND] ? speech_lines[BB_EMOTE_SOUND] : initial(sound) + + // Note to future developers: this behaviour a singleton so this probably doesn't work as you would expect + // The whole speech tree really needs to be refactored because this isn't how we use AI data these days + speak = speech_lines[BB_EMOTE_SAY] || list() + emote_see = speech_lines[BB_EMOTE_SEE] || list() + emote_hear = speech_lines[BB_EMOTE_HEAR] || list() + sound = speech_lines[BB_EMOTE_SOUND] || list() speech_chance = speech_lines[BB_EMOTE_CHANCE] ? speech_lines[BB_EMOTE_CHANCE] : initial(speech_chance) return ..() diff --git a/code/datums/ai/basic_mobs/basic_subtrees/targeted_mob_ability.dm b/code/datums/ai/basic_mobs/basic_subtrees/targeted_mob_ability.dm index 8d75f797163..d9ee3ef0918 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/targeted_mob_ability.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/targeted_mob_ability.dm @@ -23,3 +23,6 @@ controller.queue_behavior(use_ability_behaviour, ability_key, target_key) if (finish_planning) return SUBTREE_RETURN_FINISH_PLANNING + +/datum/ai_planning_subtree/targeted_mob_ability/continue_planning + finish_planning = FALSE diff --git a/code/datums/ai/basic_mobs/generic_controllers.dm b/code/datums/ai/basic_mobs/generic_controllers.dm new file mode 100644 index 00000000000..208c1833add --- /dev/null +++ b/code/datums/ai/basic_mobs/generic_controllers.dm @@ -0,0 +1,26 @@ +/// The most basic AI tree which just finds a guy and then runs at them to click them +/datum/ai_controller/basic_controller/simple_hostile + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, + ) + + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + planning_subtrees = list( + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) + +/// Find a target, walk at target, attack intervening obstacles +/datum/ai_controller/basic_controller/simple_hostile_obstacles + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, + ) + + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + planning_subtrees = list( + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/attack_obstacle_in_path, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) diff --git a/code/datums/ai/basic_mobs/targetting_datums/dont_target_friends.dm b/code/datums/ai/basic_mobs/targetting_datums/dont_target_friends.dm index 8e6c79fda3f..3556e11900f 100644 --- a/code/datums/ai/basic_mobs/targetting_datums/dont_target_friends.dm +++ b/code/datums/ai/basic_mobs/targetting_datums/dont_target_friends.dm @@ -39,3 +39,12 @@ /datum/targetting_datum/not_friends/attack_closed_turfs attack_closed_turf = TRUE + +/// Subtype that allows us to target items while deftly avoiding attacking our allies. Be careful when it comes to targetting items as an AI could get trapped targetting something it can't destroy. +/datum/targetting_datum/basic/not_friends/allow_items + +/datum/targetting_datum/basic/not_friends/allow_items/can_attack(mob/living/living_mob, atom/the_target) + . = ..() + if(isitem(the_target)) + // trust fall exercise + return TRUE diff --git a/code/datums/ai/generic/generic_behaviors.dm b/code/datums/ai/generic/generic_behaviors.dm index e7bfe7a7c60..4f816de4be3 100644 --- a/code/datums/ai/generic/generic_behaviors.dm +++ b/code/datums/ai/generic/generic_behaviors.dm @@ -287,11 +287,13 @@ /datum/ai_behavior/perform_emote -/datum/ai_behavior/perform_emote/perform(seconds_per_tick, datum/ai_controller/controller, emote) +/datum/ai_behavior/perform_emote/perform(seconds_per_tick, datum/ai_controller/controller, emote, speech_sound) var/mob/living/living_pawn = controller.pawn if(!istype(living_pawn)) return living_pawn.manual_emote(emote) + if(speech_sound) // Only audible emotes will pass in a sound + playsound(living_pawn, speech_sound, 80, vary = TRUE) finish_action(controller, TRUE) /datum/ai_behavior/perform_speech @@ -305,6 +307,16 @@ playsound(living_pawn, speech_sound, 80, vary = TRUE) finish_action(controller, TRUE) +/datum/ai_behavior/perform_speech_radio + +/datum/ai_behavior/perform_speech_radio/perform(seconds_per_tick, datum/ai_controller/controller, speech, obj/item/radio/speech_radio, list/try_channels = list(RADIO_CHANNEL_COMMON)) + var/mob/living/living_pawn = controller.pawn + if(!istype(living_pawn) || !istype(speech_radio) || QDELETED(speech_radio) || !length(try_channels)) + finish_action(controller, FALSE) + return + speech_radio.talk_into(living_pawn, speech, pick(try_channels)) + finish_action(controller, TRUE) + //song behaviors /datum/ai_behavior/setup_instrument diff --git a/code/datums/ai/robot_customer/robot_customer_behaviors.dm b/code/datums/ai/robot_customer/robot_customer_behaviors.dm index ff9e59c3931..95260b8e68d 100644 --- a/code/datums/ai/robot_customer/robot_customer_behaviors.dm +++ b/code/datums/ai/robot_customer/robot_customer_behaviors.dm @@ -3,7 +3,7 @@ /datum/ai_behavior/find_seat/perform(seconds_per_tick, datum/ai_controller/controller) . = ..() - var/mob/living/simple_animal/robot_customer/customer_pawn = controller.pawn + var/mob/living/basic/robot_customer/customer_pawn = controller.pawn var/datum/customer_data/customer_data = controller.blackboard[BB_CUSTOMER_CUSTOMERINFO] var/datum/venue/attending_venue = controller.blackboard[BB_CUSTOMER_ATTENDING_VENUE] @@ -44,7 +44,7 @@ /datum/ai_behavior/order_food/perform(seconds_per_tick, datum/ai_controller/controller) . = ..() - var/mob/living/simple_animal/robot_customer/customer_pawn = controller.pawn + var/mob/living/basic/robot_customer/customer_pawn = controller.pawn var/datum/customer_data/customer_data = controller.blackboard[BB_CUSTOMER_CUSTOMERINFO] var/obj/structure/holosign/robot_seat/seat_marker = controller.blackboard[BB_CUSTOMER_MY_SEAT] if(get_turf(seat_marker) == get_turf(customer_pawn)) @@ -75,7 +75,7 @@ // SPT_PROB 1.5 is about a 40% chance that the tourist will have vocalised at least once every minute. if(SPT_PROB(0.85, seconds_per_tick)) - var/mob/living/simple_animal/robot_customer/customer_pawn = controller.pawn + var/mob/living/basic/robot_customer/customer_pawn = controller.pawn var/datum/customer_data/customer_data = controller.blackboard[BB_CUSTOMER_CUSTOMERINFO] customer_pawn.say(pick(customer_data.wait_for_food_lines)) @@ -98,7 +98,7 @@ /datum/ai_behavior/wait_for_food/finish_action(datum/ai_controller/controller, succeeded) . = ..() - var/mob/living/simple_animal/robot_customer/customer_pawn = controller.pawn + var/mob/living/basic/robot_customer/customer_pawn = controller.pawn var/datum/customer_data/customer_data = controller.blackboard[BB_CUSTOMER_CUSTOMERINFO] var/mob/living/greytider = controller.blackboard[BB_CUSTOMER_CURRENT_TARGET] //usually if we stop waiting, it's because we're done with the venue. but here we're either beating some dude up diff --git a/code/datums/ai/robot_customer/robot_customer_controller.dm b/code/datums/ai/robot_customer/robot_customer_controller.dm index 2a633590f68..0fc9d27eb43 100644 --- a/code/datums/ai/robot_customer/robot_customer_controller.dm +++ b/code/datums/ai/robot_customer/robot_customer_controller.dm @@ -1,14 +1,16 @@ /datum/ai_controller/robot_customer ai_movement = /datum/ai_movement/basic_avoidance movement_delay = 0.8 SECONDS - blackboard = list(BB_CUSTOMER_CURRENT_ORDER = null, - BB_CUSTOMER_MY_SEAT = null, - BB_CUSTOMER_PATIENCE = 999, - BB_CUSTOMER_CUSTOMERINFO = null, - BB_CUSTOMER_EATING = FALSE, - BB_CUSTOMER_LEAVING = FALSE, - BB_CUSTOMER_ATTENDING_VENUE = null, - BB_CUSTOMER_SAID_CANT_FIND_SEAT_LINE = FALSE) + blackboard = list( + BB_CUSTOMER_ATTENDING_VENUE = null, + BB_CUSTOMER_CURRENT_ORDER = null, + BB_CUSTOMER_CUSTOMERINFO = null, + BB_CUSTOMER_EATING = FALSE, + BB_CUSTOMER_LEAVING = FALSE, + BB_CUSTOMER_MY_SEAT = null, + BB_CUSTOMER_PATIENCE = 999 SECONDS, + BB_CUSTOMER_SAID_CANT_FIND_SEAT_LINE = FALSE, + ) planning_subtrees = list(/datum/ai_planning_subtree/robot_customer) /datum/ai_controller/robot_customer/Destroy() @@ -18,7 +20,7 @@ return ..() /datum/ai_controller/robot_customer/TryPossessPawn(atom/new_pawn) - if(!istype(new_pawn, /mob/living/simple_animal/robot_customer)) + if(!istype(new_pawn, /mob/living/basic/robot_customer)) return AI_CONTROLLER_INCOMPATIBLE new_pawn.AddElement(/datum/element/relay_attackers) RegisterSignal(new_pawn, COMSIG_ATOM_ATTACKBY, PROC_REF(on_attackby)) @@ -28,6 +30,12 @@ return ..() //Run parent at end /datum/ai_controller/robot_customer/UnpossessPawn(destroy) + if(isnull(pawn)) +#ifndef UNIT_TESTS + stack_trace("Robot Customer AI Controller UnpossessPawn called with null pawn! This shouldn't happen in normal circumstances.") // and unit tests are abnormal circumstances +#endif + return + UnregisterSignal(pawn, list(COMSIG_ATOM_ATTACKBY, COMSIG_ATOM_WAS_ATTACKED, COMSIG_LIVING_GET_PULLED, COMSIG_ATOM_ATTACK_HAND)) return ..() //Run parent at end @@ -67,7 +75,7 @@ INVOKE_ASYNC(src, PROC_REF(async_on_get_pulled), source, puller) /datum/ai_controller/robot_customer/proc/async_on_get_pulled(datum/source, mob/living/puller) - var/mob/living/simple_animal/robot_customer/customer = pawn + var/mob/living/basic/robot_customer/customer = pawn var/datum/customer_data/customer_data = blackboard[BB_CUSTOMER_CUSTOMERINFO] var/datum/venue/attending_venue = blackboard[BB_CUSTOMER_ATTENDING_VENUE] @@ -81,12 +89,12 @@ /datum/ai_controller/robot_customer/proc/dont_want_that(mob/living/chef, obj/item/thing) - var/mob/living/simple_animal/robot_customer/customer = pawn + var/mob/living/basic/robot_customer/customer = pawn var/datum/customer_data/customer_data = blackboard[BB_CUSTOMER_CUSTOMERINFO] customer.say(customer_data.wrong_item_line) /datum/ai_controller/robot_customer/proc/warn_greytider(mob/living/greytider) - var/mob/living/simple_animal/robot_customer/customer = pawn + var/mob/living/basic/robot_customer/customer = pawn var/datum/venue/attending_venue = blackboard[BB_CUSTOMER_ATTENDING_VENUE] var/datum/customer_data/customer_data = blackboard[BB_CUSTOMER_CUSTOMERINFO] //Living mobs are tagged, so these will always be valid diff --git a/code/datums/atmosphere/_atmosphere.dm b/code/datums/atmosphere/_atmosphere.dm index 1dace1dd1b2..702a42e7ab0 100644 --- a/code/datums/atmosphere/_atmosphere.dm +++ b/code/datums/atmosphere/_atmosphere.dm @@ -52,6 +52,9 @@ ASSERT_GAS_IN_LIST(gastype, gaslist) gaslist[gastype][MOLES] += amount + // Ensure that minimum_pressure is actually a hard lower limit + target_pressure = clamp(target_pressure, minimum_pressure + (gaslist[gastype][MOLES] * 0.1), maximum_pressure) + // That last one put us over the limit, remove some of it while(gasmix.return_pressure() > target_pressure) gaslist[gastype][MOLES] -= gaslist[gastype][MOLES] * 0.1 diff --git a/code/datums/components/acid.dm b/code/datums/components/acid.dm index 9758cd0c1b6..1d9cf9e87d6 100644 --- a/code/datums/components/acid.dm +++ b/code/datums/components/acid.dm @@ -78,8 +78,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e QDEL_NULL(sizzle) if(particle_effect) QDEL_NULL(particle_effect) - if(process_effect) - process_effect = null + process_effect = null return ..() /datum/component/acid/RegisterWithParent() diff --git a/code/datums/components/appearance_on_aggro.dm b/code/datums/components/appearance_on_aggro.dm index affb926d28d..33a3d7c2e90 100644 --- a/code/datums/components/appearance_on_aggro.dm +++ b/code/datums/components/appearance_on_aggro.dm @@ -1,11 +1,14 @@ /** - * component gave to basic creatures to allow them to change appearance when find a target + * Changes visuals of the attached mob while it has a target */ /datum/component/appearance_on_aggro + /// Blackboardey to search for a target var/target_key = BB_BASIC_MOB_CURRENT_TARGET + /// Icon state to use when we have a target + var/aggro_state /// path of the overlay to apply - var/mutable_appearance/overlay_path + var/mutable_appearance/aggro_overlay /// visibility of our icon when aggroed var/alpha_on_aggro /// visibility of our icon when deaggroed @@ -13,20 +16,22 @@ /// do we currently have a target var/atom/current_target -/datum/component/appearance_on_aggro/Initialize(overlay_icon, overlay_state, alpha_on_aggro, alpha_on_deaggro) - if(!isliving(parent)) +/datum/component/appearance_on_aggro/Initialize(aggro_state, overlay_icon, overlay_state, alpha_on_aggro, alpha_on_deaggro) + if (!isliving(parent)) return COMPONENT_INCOMPATIBLE - if(overlay_icon && overlay_state) - src.overlay_path = mutable_appearance(overlay_icon, overlay_state) - if(!alpha_on_aggro || !alpha_on_deaggro) - return + src.aggro_state = aggro_state src.alpha_on_aggro = alpha_on_aggro src.alpha_on_deaggro = alpha_on_deaggro + if (!isnull(overlay_icon) && !isnull(overlay_state)) + aggro_overlay = mutable_appearance(overlay_icon, overlay_state) /datum/component/appearance_on_aggro/RegisterWithParent() - RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(change_overlays)) RegisterSignal(parent, COMSIG_AI_BLACKBOARD_KEY_SET(target_key), PROC_REF(on_set_target)) RegisterSignal(parent, COMSIG_AI_BLACKBOARD_KEY_CLEARED(target_key), PROC_REF(on_clear_target)) + if (!isnull(aggro_state)) + RegisterSignal(parent, COMSIG_ATOM_UPDATE_ICON_STATE, PROC_REF(on_icon_state_updated)) + if (!isnull(aggro_overlay)) + RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_overlays_updated)) /datum/component/appearance_on_aggro/UnregisterFromParent() . = ..() @@ -36,37 +41,42 @@ SIGNAL_HANDLER var/atom/target = source.ai_controller.blackboard[target_key] - if(isnull(target)) + if (QDELETED(target)) return + current_target = target RegisterSignal(target, COMSIG_QDELETING, PROC_REF(on_clear_target)) - if(overlay_path) - source.update_appearance(UPDATE_OVERLAYS) - if(alpha_on_aggro) + if (!isnull(aggro_overlay) || !isnull(aggro_state)) + source.update_appearance(UPDATE_ICON) + if (!isnull(alpha_on_aggro)) animate(source, alpha = alpha_on_aggro, time = 2 SECONDS) /datum/component/appearance_on_aggro/Destroy() - if(current_target) + if (!isnull(current_target)) revert_appearance(parent) return ..() /datum/component/appearance_on_aggro/proc/on_clear_target(atom/source) SIGNAL_HANDLER - revert_appearance(parent) /datum/component/appearance_on_aggro/proc/revert_appearance(mob/living/source) UnregisterSignal(current_target, COMSIG_QDELETING) current_target = null - if(overlay_path) - source.update_appearance(UPDATE_OVERLAYS) - if(alpha_on_deaggro) + if (!isnull(aggro_overlay) || !isnull(aggro_state)) + source.update_appearance(UPDATE_ICON) + if (!isnull(alpha_on_deaggro)) animate(source, alpha = alpha_on_deaggro, time = 2 SECONDS) -/datum/component/appearance_on_aggro/proc/change_overlays(atom/source, list/overlays) +/datum/component/appearance_on_aggro/proc/on_icon_state_updated(mob/living/source) SIGNAL_HANDLER - - if(isnull(current_target)) + if (source.stat == DEAD) return + source.icon_state = isnull(current_target) ? initial(source.icon_state) : aggro_state - overlays += overlay_path +/datum/component/appearance_on_aggro/proc/on_overlays_updated(atom/source, list/overlays) + SIGNAL_HANDLER + + if (isnull(current_target)) + return + overlays += aggro_overlay diff --git a/code/datums/components/crafting/_recipes.dm b/code/datums/components/crafting/_recipes.dm index 246f04df0f5..4254804974e 100644 --- a/code/datums/components/crafting/_recipes.dm +++ b/code/datums/components/crafting/_recipes.dm @@ -17,7 +17,7 @@ var/list/tool_paths ///time in seconds. Remember to use the SECONDS define! var/time = 3 SECONDS - ///type paths of items that will be placed in the result + ///type paths of items that will be forceMoved() into the result, or added to the reagents of it var/list/parts = list() ///like tool_behaviors but for reagents var/list/chem_catalysts = list() diff --git a/code/datums/components/crafting/guncrafting.dm b/code/datums/components/crafting/guncrafting.dm index f239288b031..a5a20d4326b 100644 --- a/code/datums/components/crafting/guncrafting.dm +++ b/code/datums/components/crafting/guncrafting.dm @@ -2,12 +2,27 @@ // PARTS // +/obj/item/weaponcrafting/Initialize(mapload) + . = ..() + create_slapcraft_component() + +/obj/item/weaponcrafting/proc/create_slapcraft_component() + return + /obj/item/weaponcrafting/receiver name = "modular receiver" desc = "A prototype modular receiver and trigger assembly for a firearm." icon = 'icons/obj/weapons/improvised.dmi' icon_state = "receiver" +/obj/item/weaponcrafting/receiver/create_slapcraft_component() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/pipegun) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/weaponcrafting/stock name = "rifle stock" desc = "A classic rifle stock that doubles as a grip, roughly carved out of wood." @@ -16,17 +31,33 @@ icon = 'icons/obj/weapons/improvised.dmi' icon_state = "riflestock" +/obj/item/weaponcrafting/stock/create_slapcraft_component() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/smoothbore_disabler, /datum/crafting_recipe/laser_musket) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/weaponcrafting/giant_wrench name = "Big Slappy parts kit" desc = "Illegal parts to make a giant like wrench commonly known as a Big Slappy." icon = 'icons/obj/weapons/improvised.dmi' icon_state = "weaponkit_gw" +/obj/item/weaponcrafting/giant_wrench/create_slapcraft_component() // slappycraft + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/giant_wrench) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + ///These gun kits are printed from the security protolathe to then be used in making new weapons // GUN PART KIT // -/obj/item/weaponcrafting/gunkit +/obj/item/weaponcrafting/gunkit // These don't get a slapcraft component, it's added to the gun - more intuitive player-facing to slap the kit onto the gun. name = "generic gun parts kit" desc = "It's an empty gun parts container! Why do you have this?" icon = 'icons/obj/weapons/improvised.dmi' diff --git a/code/datums/components/crafting/slapcrafting.dm b/code/datums/components/crafting/slapcrafting.dm new file mode 100644 index 00000000000..32a901dc73e --- /dev/null +++ b/code/datums/components/crafting/slapcrafting.dm @@ -0,0 +1,202 @@ +/// Slapcrafting component! +/datum/component/slapcrafting + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS + var/list/slapcraft_recipes = list() + +/** + * Slapcraft component + * + * Slap it onto a item to be able to slapcraft with it + * + * args: + * * slapcraft_recipes (required) = The recipe to attempt crafting. + * Hit it with an ingredient of the recipe to attempt crafting. + * It will check the area near the user for the rest of the ingredients and tools. + * * +**/ +/datum/component/slapcrafting/Initialize( + slapcraft_recipes = null, + ) + + if(!isitem(parent)) + return COMPONENT_INCOMPATIBLE + + var/obj/item/parent_item = parent + + if((parent_item.item_flags & ABSTRACT) || (parent_item.item_flags & DROPDEL)) + return COMPONENT_NOTRANSFER + + RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, PROC_REF(attempt_slapcraft)) + RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(get_examine_info)) + RegisterSignal(parent, COMSIG_ATOM_EXAMINE_MORE, PROC_REF(get_examine_more_info)) + RegisterSignal(parent, COMSIG_TOPIC, PROC_REF(topic_handler)) + + src.slapcraft_recipes += slapcraft_recipes + +/datum/component/slapcrafting/InheritComponent(datum/component/slapcrafting/new_comp, original, slapcraft_recipes) + if(!original) + return + src.slapcraft_recipes += slapcraft_recipes + +/datum/component/slapcrafting/Destroy(force, silent) + UnregisterSignal(parent, list(COMSIG_ATOM_ATTACKBY, COMSIG_ATOM_EXAMINE, COMSIG_ATOM_EXAMINE_MORE)) + return ..() + +/datum/component/slapcrafting/proc/attempt_slapcraft(obj/item/parent_item, obj/item/slapper, mob/user) + + if(isnull(slapcraft_recipes)) + CRASH("NULL SLAPCRAFT RECIPES?") + + var/datum/component/personal_crafting/craft_sheet = user.GetComponent(/datum/component/personal_crafting) + if(!craft_sheet) + CRASH("No craft sheet on user ??") + + var/list/valid_recipes + for(var/datum/crafting_recipe/recipe as anything in slapcraft_recipes) + // Gotta instance it to copy the list over. + recipe = new recipe() + var/list/type_ingredient_list = recipe.reqs + qdel(recipe) + if(length(type_ingredient_list) == 1) // No ingredients besides itself? We use one of the tools then + type_ingredient_list = recipe.tool_paths + // Check the tool behaviours differently as they aren't types + for(var/behaviour in initial(recipe.tool_behaviors)) + if(slapper.tool_behaviour == behaviour) + LAZYADD(valid_recipes, recipe) + break + if(is_type_in_list(slapper, type_ingredient_list)) + LAZYADD(valid_recipes, recipe) + + if(!valid_recipes) + return + + // We might use radials so we need to split the proc chain + INVOKE_ASYNC(src, PROC_REF(slapcraft_async), valid_recipes, user, craft_sheet) + +/datum/component/slapcrafting/proc/slapcraft_async(list/valid_recipes, mob/user, datum/component/personal_crafting/craft_sheet) + + var/list/recipe_choices = list() + + var/list/result_to_recipe = list() + + var/final_recipe = valid_recipes[1] + var/string_chosen_recipe + if(length(valid_recipes) > 1) + for(var/datum/crafting_recipe/recipe as anything in valid_recipes) + var/atom/recipe_result = initial(recipe.result) + result_to_recipe[initial(recipe_result.name)] = recipe + recipe_choices += list("[initial(recipe_result.name)]" = image(icon = initial(recipe_result.icon), icon_state = initial(recipe_result.icon_state))) + + if(!recipe_choices) + CRASH("No recipe choices despite validating in earlier proc") + + string_chosen_recipe = show_radial_menu(user, parent, recipe_choices, require_near = TRUE) + if(isnull(string_chosen_recipe)) + return // they closed the thing + + if(string_chosen_recipe) + final_recipe = result_to_recipe[string_chosen_recipe] + + + var/datum/crafting_recipe/actual_recipe = final_recipe + + if(istype(actual_recipe, /datum/crafting_recipe/food)) + actual_recipe = locate(final_recipe) in GLOB.cooking_recipes + else + actual_recipe = locate(final_recipe) in GLOB.crafting_recipes + + if(!actual_recipe) + CRASH("Recipe not located in cooking or crafting recipes: [final_recipe]") + + var/atom/final_result = initial(actual_recipe.result) + + to_chat(user, span_notice("You start crafting \a [initial(final_result.name)]...")) + + var/error_string = craft_sheet.construct_item(user, actual_recipe) + + if(!isatom(error_string)) + to_chat(user, span_warning("crafting failed" + error_string)) + +/// Alerts any examiners to the recipe, if they wish to know more. +/datum/component/slapcrafting/proc/get_examine_info(atom/source, mob/user, list/examine_list) + SIGNAL_HANDLER + + var/list/string_results = list() + // This list saves the recipe result names we've already used to cross-check other recipes so we don't have ', a spear, or a spear!' in the desc. + var/list/already_used_names + for(var/datum/crafting_recipe/recipe as anything in slapcraft_recipes) + // Identical name to a previous recipe's result? Skip in description. + var/atom/result = initial(recipe.result) + if(locate(initial(result.name)) in already_used_names) + continue + already_used_names += initial(result.name) + string_results += list("\a [initial(result.name)]") + + examine_list += span_notice("You think [parent] could be used to make [english_list(string_results)]! Examine again to look at the details...") + +/// Alerts any examiners to the details of the recipe. +/datum/component/slapcrafting/proc/get_examine_more_info(atom/source, mob/user, list/examine_list) + SIGNAL_HANDLER + + for(var/datum/crafting_recipe/recipe as anything in slapcraft_recipes) + var/atom/result = initial(recipe.result) + examine_list += "See Recipe For [initial(result.name)]" + +/datum/component/slapcrafting/proc/topic_handler(atom/source, user, href_list) + SIGNAL_HANDLER + + if(!href_list["check_recipe"]) + return + + var/datum/crafting_recipe/cur_recipe = locate(href_list["check_recipe"]) in slapcraft_recipes + + if(isnull(cur_recipe)) + CRASH("null recipe!") + + var/atom/result = initial(cur_recipe.result) + + to_chat(user, span_notice("You could craft \a [initial(result.name)] by applying one of these items to it!")) + + // Gotta instance it to copy the lists over. + cur_recipe = new cur_recipe() + var/list/type_ingredient_list = cur_recipe.reqs + + // Final return string. + var/string_ingredient_list = "" + + // Check the ingredients of the crafting recipe. + for(var/valid_type in type_ingredient_list) + // Check if they're datums, specifically reagents. + var/datum/reagent/reagent_ingredient = valid_type + if(istype(reagent_ingredient)) + var/amount = initial(cur_recipe.reqs[reagent_ingredient]) + string_ingredient_list += "[amount] unit[amount > 1 ? "s" : ""] of [initial(reagent_ingredient.name)]\n" + + // Redundant! + if(parent.type == valid_type) + continue + var/atom/ingredient = valid_type + var/amount = initial(cur_recipe.reqs[ingredient]) + string_ingredient_list += "[amount > 1 ? ("[amount]" + " of") : "a"] [initial(ingredient.name)]\n" + + // If we did find ingredients then add them onto the list. + if(length(string_ingredient_list)) + to_chat(user, span_boldnotice("Ingredients:")) + to_chat(user, examine_block(span_notice(string_ingredient_list))) + + var/list/tool_list = "" + + // Paste the required tools. + for(var/valid_type in cur_recipe.tool_paths) + var/atom/tool = valid_type + tool_list += "\a [initial(tool.name)]\n" + + for(var/string in cur_recipe.tool_behaviors) + tool_list += "\a [string]\n" + + if(length(tool_list)) + to_chat(user, span_boldnotice("Required Tools:")) + to_chat(user, examine_block(span_notice(tool_list))) + + qdel(cur_recipe) + diff --git a/code/datums/components/death_linked.dm b/code/datums/components/death_linked.dm new file mode 100644 index 00000000000..59d2ce5e855 --- /dev/null +++ b/code/datums/components/death_linked.dm @@ -0,0 +1,30 @@ +/** + * ## Death link component + * + * When the owner of this component dies it also gibs a linked mob + */ +/datum/component/death_linked + ///The mob that also dies when the user dies + var/datum/weakref/linked_mob + +/datum/component/death_linked/Initialize(mob/living/target_mob) + . = ..() + if(!isliving(parent)) + return COMPONENT_INCOMPATIBLE + if(isnull(target_mob)) + stack_trace("[type] added to [parent] with no linked mob.") + src.linked_mob = WEAKREF(target_mob) + +/datum/component/death_linked/RegisterWithParent() + . = ..() + RegisterSignal(parent, COMSIG_LIVING_DEATH, PROC_REF(on_death)) + +/datum/component/death_linked/UnregisterFromParent() + . = ..() + UnregisterSignal(parent, COMSIG_LIVING_DEATH) + +///signal called by the stat of the target changing +/datum/component/death_linked/proc/on_death(mob/living/target, gibbed) + SIGNAL_HANDLER + var/mob/living/linked_mob_resolved = linked_mob?.resolve() + linked_mob_resolved?.gib() diff --git a/code/datums/components/food/ice_cream_holder.dm b/code/datums/components/food/ice_cream_holder.dm index 9e25c7cb4b4..3e212c52b9a 100644 --- a/code/datums/components/food/ice_cream_holder.dm +++ b/code/datums/components/food/ice_cream_holder.dm @@ -33,14 +33,16 @@ var/datum/reagent/sweetener -/datum/component/ice_cream_holder/Initialize(max_scoops = DEFAULT_MAX_ICE_CREAM_SCOOPS, - change_name = TRUE, - filled_name, - change_desc = FALSE, - x_offset = 0, - y_offset = 0, - datum/reagent/sweetener = /datum/reagent/consumable/sugar, - list/prefill_flavours) +/datum/component/ice_cream_holder/Initialize( + max_scoops = DEFAULT_MAX_ICE_CREAM_SCOOPS, + change_name = TRUE, + filled_name, + change_desc = FALSE, + x_offset = 0, + y_offset = 0, + datum/reagent/sweetener = /datum/reagent/consumable/sugar, + list/prefill_flavours, +) if(!IS_EDIBLE(parent)) /// There is no easy way to add servings to those non-item edibles, but I won't stop you. return COMPONENT_INCOMPATIBLE @@ -169,7 +171,7 @@ if(compare_list(our_scoops, icecream_order.wanted_flavors)) return COMPONENT_CORRECT_ORDER -/datum/component/ice_cream_holder/proc/sell_ice_cream(obj/item/source, mob/living/simple_animal/robot_customer/sold_to) +/datum/component/ice_cream_holder/proc/sell_ice_cream(obj/item/source, mob/living/basic/robot_customer/sold_to) SIGNAL_HANDLER //the price of ice cream scales with the number of scoops. Yummy. diff --git a/code/datums/components/religious_tool.dm b/code/datums/components/religious_tool.dm index e64e28f83a3..4c0646b3a55 100644 --- a/code/datums/components/religious_tool.dm +++ b/code/datums/components/religious_tool.dm @@ -74,9 +74,9 @@ /**********Sacrificing**********/ else if(operation_flags & RELIGION_TOOL_SACRIFICE) - if(easy_access_sect?.can_sacrifice(the_item,user)) + if(!easy_access_sect?.can_sacrifice(the_item, user)) return - easy_access_sect.on_sacrifice(the_item,user) + easy_access_sect.on_sacrifice(the_item, user) return COMPONENT_NO_AFTERATTACK /datum/component/religious_tool/ui_interact(mob/user, datum/tgui/ui) diff --git a/code/datums/components/supermatter_crystal.dm b/code/datums/components/supermatter_crystal.dm index a9bdfc5b154..66087134388 100644 --- a/code/datums/components/supermatter_crystal.dm +++ b/code/datums/components/supermatter_crystal.dm @@ -17,6 +17,7 @@ RegisterSignal(parent, COMSIG_ATOM_TOOL_ACT(TOOL_WRENCH), PROC_REF(tool_hit)) RegisterSignal(parent, COMSIG_ATOM_BUMPED, PROC_REF(bumped_hit)) RegisterSignal(parent, COMSIG_ATOM_INTERCEPT_Z_FALL, PROC_REF(intercept_z_fall)) + RegisterSignal(parent, COMSIG_ATOM_ON_Z_IMPACT, PROC_REF(on_z_impact)) src.tool_act_callback = tool_act_callback src.consume_callback = consume_callback @@ -38,6 +39,7 @@ COMSIG_ATOM_TOOL_ACT(TOOL_WRENCH), COMSIG_ATOM_BUMPED, COMSIG_ATOM_INTERCEPT_Z_FALL, + COMSIG_ATOM_ON_Z_IMPACT, ) UnregisterSignal(parent, signals_to_remove) @@ -152,6 +154,8 @@ return if(istype(item, /obj/item/melee/roastingstick)) return FALSE + if(istype(item, /obj/item/toy/crayon/spraycan)) + return FALSE if(istype(item, /obj/item/clothing/mask/cigarette)) var/obj/item/clothing/mask/cigarette/cig = item var/clumsy = HAS_TRAIT(user, TRAIT_CLUMSY) @@ -232,11 +236,36 @@ /datum/component/supermatter_crystal/proc/intercept_z_fall(datum/source, list/falling_movables, levels) SIGNAL_HANDLER for(var/atom/movable/hit_object as anything in falling_movables) - if(hit_object == source) - continue + if(parent == hit_object) + return + bumped_hit(parent, hit_object) return FALL_INTERCEPTED | FALL_NO_MESSAGE +/datum/component/supermatter_crystal/proc/on_z_impact(datum/source, turf/impacted_turf, levels) + SIGNAL_HANDLER + + var/atom/atom_source = source + + for(var/mob/living/poor_target in impacted_turf) + consume(atom_source, poor_target) + playsound(get_turf(atom_source), 'sound/effects/supermatter.ogg', 50, TRUE) + poor_target.visible_message(span_danger("\The [atom_source] slams into \the [poor_target] out of nowhere inducing a resonance... [poor_target.p_their()] body starts to glow and burst into flames before flashing into dust!"), + span_userdanger("\The [atom_source] slams into you out of nowhere as your ears are filled with unearthly ringing. Your last thought is \"The fuck.\""), + span_hear("You hear an unearthly noise as a wave of heat washes over you.")) + + for(var/atom/movable/hit_object as anything in impacted_turf) + if(parent == hit_object) + return + + if(iseffect(hit_object)) + continue + + consume(atom_source, hit_object) + playsound(get_turf(atom_source), 'sound/effects/supermatter.ogg', 50, TRUE) + atom_source.visible_message(span_danger("\The [atom_source], smacks into the plating out of nowhere, reducing everything below to ash."), null, + span_hear("You hear a loud crack as you are washed with a wave of heat.")) + /datum/component/supermatter_crystal/proc/dust_mob(datum/source, mob/living/nom, vis_msg, mob_msg, cause) if(nom.incorporeal_move || nom.status_flags & GODMODE) //try to keep supermatter sliver's + hemostat's dust conditions in sync with this too return diff --git a/code/datums/components/tackle.dm b/code/datums/components/tackle.dm index ffd20cc2c13..4ae3a973d7e 100644 --- a/code/datums/components/tackle.dm +++ b/code/datums/components/tackle.dm @@ -205,7 +205,8 @@ user.visible_message(span_warning("[user] lands an expert [tackle_word] on [target], knocking [target.p_them()] down hard while landing on [user.p_their()] feet with a passive grip!"), span_userdanger("You land an expert [tackle_word] on [target], knocking [target.p_them()] down hard while landing on your feet with a passive grip!"), ignored_mobs = target) to_chat(target, span_userdanger("[user] lands an expert [tackle_word] on you, knocking you down hard and maintaining a passive grab!")) - user.SetKnockdown(0) + // Ignore_canstun has to be true, or else a stunimmune user would stay knocked down. + user.SetKnockdown(0, ignore_canstun = TRUE) user.get_up(TRUE) user.forceMove(get_turf(target)) target.adjustStaminaLoss(40) @@ -228,7 +229,8 @@ user.visible_message(span_warning("[user] lands a monster [tackle_word] on [target], knocking [target.p_them()] senseless and applying an aggressive pin!"), span_userdanger("You land a monster [tackle_word] on [target], knocking [target.p_them()] senseless and applying an aggressive pin!"), ignored_mobs = target) to_chat(target, span_userdanger("[user] lands a monster [tackle_word] on you, knocking you senseless and aggressively pinning you!")) - user.SetKnockdown(0) + // Ignore_canstun has to be true, or else a stunimmune user would stay knocked down. + user.SetKnockdown(0, ignore_canstun = TRUE) user.get_up(TRUE) user.forceMove(get_turf(target)) target.adjustStaminaLoss(40) diff --git a/code/datums/components/wall_mounted.dm b/code/datums/components/wall_mounted.dm index 6164d39b001..8d1722f89fe 100644 --- a/code/datums/components/wall_mounted.dm +++ b/code/datums/components/wall_mounted.dm @@ -17,7 +17,7 @@ /datum/component/wall_mounted/RegisterWithParent() RegisterSignal(hanging_wall_turf, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) - RegisterSignal(hanging_wall_turf, COMSIG_TURF_CHANGE, PROC_REF(drop_wallmount)) + RegisterSignal(hanging_wall_turf, COMSIG_TURF_CHANGE, PROC_REF(on_turf_changing)) RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(drop_wallmount)) RegisterSignal(parent, COMSIG_QDELETING, PROC_REF(on_linked_destroyed)) @@ -41,6 +41,14 @@ SIGNAL_HANDLER examine_list += span_notice("\The [hanging_wall_turf] is currently supporting [span_bold("[parent]")]. Deconstruction or excessive damage would cause it to [span_bold("fall to the ground")].") +/** + * When the type of turf changes, if it is changing into a floor we should drop our contents + */ +/datum/component/wall_mounted/proc/on_turf_changing(datum/source, path, new_baseturfs, flags, post_change_callbacks) + SIGNAL_HANDLER + if (ispath(path, /turf/open)) + drop_wallmount() + /** * Handles the dropping of the linked object. This is done via deconstruction, as that should be the most sane way to handle it for most objects. * Except for intercoms, which are handled by creating a new wallframe intercom, as they're apparently items. diff --git a/code/datums/elements/death_linked.dm b/code/datums/elements/death_linked.dm deleted file mode 100644 index c5d2c6c422c..00000000000 --- a/code/datums/elements/death_linked.dm +++ /dev/null @@ -1,29 +0,0 @@ -/** - * ## death linkage element! - * - * Bespoke element that when the owner dies, the linked mob dies too. - */ -/datum/element/death_linked - element_flags = ELEMENT_BESPOKE - argument_hash_start_idx = 3 - ///The mob that also dies when the user dies - var/datum/weakref/linked_mob - -/datum/element/death_linked/Attach(datum/target, mob/living/target_mob) - . = ..() - if(!isliving(target)) - return ELEMENT_INCOMPATIBLE - if(!target_mob) - stack_trace("[type] added to [target] with NO MOB.") - src.linked_mob = WEAKREF(target_mob) - RegisterSignal(target, COMSIG_LIVING_DEATH, PROC_REF(on_death)) - -/datum/element/death_linked/Detach(datum/target) - . = ..() - UnregisterSignal(target, COMSIG_LIVING_DEATH) - -///signal called by the stat of the target changing -/datum/element/death_linked/proc/on_death(mob/living/target, gibbed) - SIGNAL_HANDLER - var/mob/living/linked_mob_resolved = linked_mob?.resolve() - linked_mob_resolved?.death(TRUE) diff --git a/code/datums/elements/food/venue_price.dm b/code/datums/elements/food/venue_price.dm index 1fcf9de040d..be846d7c004 100644 --- a/code/datums/elements/food/venue_price.dm +++ b/code/datums/elements/food/venue_price.dm @@ -21,19 +21,19 @@ UnregisterSignal(target, COMSIG_ITEM_SOLD_TO_CUSTOMER) UnregisterSignal(target, COMSIG_REAGENT_SOLD_TO_CUSTOMER) -/datum/element/venue_price/proc/item_sold(obj/item/thing_sold, mob/living/simple_animal/robot_customer/sold_to) +/datum/element/venue_price/proc/item_sold(obj/item/thing_sold, mob/living/basic/robot_customer/sold_to) SIGNAL_HANDLER produce_cash(sold_to, thing_sold) return TRANSACTION_SUCCESS -/datum/element/venue_price/proc/reagent_sold(datum/reagent/reagent_sold, mob/living/simple_animal/robot_customer/sold_to, obj/item/container) +/datum/element/venue_price/proc/reagent_sold(datum/reagent/reagent_sold, mob/living/basic/robot_customer/sold_to, obj/item/container) SIGNAL_HANDLER produce_cash(sold_to, container) return TRANSACTION_SUCCESS -/datum/element/venue_price/proc/produce_cash(mob/living/simple_animal/robot_customer/sold_to, obj/item/container) +/datum/element/venue_price/proc/produce_cash(mob/living/basic/robot_customer/sold_to, obj/item/container) new /obj/item/holochip(get_turf(container), venue_price) playsound(container, 'sound/effects/cashregister.ogg', 60, TRUE) diff --git a/code/datums/elements/sideway_movement.dm b/code/datums/elements/sideway_movement.dm index dfe23187807..e6d94745e6c 100644 --- a/code/datums/elements/sideway_movement.dm +++ b/code/datums/elements/sideway_movement.dm @@ -23,5 +23,5 @@ return var/new_dir = old_dir if(direction == old_dir || direction == REVERSE_DIR(old_dir)) - new_dir = angle2dir(dir2angle(direction) + pick(90, -90)) + new_dir = turn(source.dir, pick(90, -90)) source.setDir(new_dir) diff --git a/code/datums/mapgen/CaveGenerator.dm b/code/datums/mapgen/CaveGenerator.dm index 48df6e164fb..754b8755545 100644 --- a/code/datums/mapgen/CaveGenerator.dm +++ b/code/datums/mapgen/CaveGenerator.dm @@ -55,7 +55,7 @@ /mob/living/basic/mining/basilisk = 4, /mob/living/basic/mining/goldgrub = 1, /mob/living/basic/mining/goliath/ancient = 5, - /mob/living/simple_animal/hostile/asteroid/hivelord = 3, + /mob/living/basic/mining/hivelord = 3, ) mob_spawn_list = expand_weights(weighted_mob_spawn_list) mob_spawn_no_mega_list = expand_weights(weighted_mob_spawn_list - SPAWN_MEGAFAUNA) @@ -116,8 +116,8 @@ var/start_time = REALTIMEOFDAY - for(var/turf/turf as anything in turfs) - if(!(turf.type in open_turf_types)) //only put stuff on open turfs we generated, so closed walls and rivers and stuff are skipped + for(var/turf/target_turf as anything in turfs) + if(!(target_turf.type in open_turf_types)) //only put stuff on open turfs we generated, so closed walls and rivers and stuff are skipped continue // If we've spawned something yet @@ -127,22 +127,24 @@ //FLORA SPAWNING HERE if(flora_allowed && prob(flora_spawn_chance)) var/flora_type = pick(flora_spawn_list) - new flora_type(turf) + new flora_type(target_turf) spawned_something = TRUE //FEATURE SPAWNING HERE - if(feature_allowed && prob(feature_spawn_chance)) + //we may have generated something from the flora list on the target turf, so let's not place + //a feature here if that's the case (because it would look stupid) + if(feature_allowed && !spawned_something && prob(feature_spawn_chance)) var/can_spawn = TRUE var/atom/picked_feature = pick(feature_spawn_list) - for(var/obj/structure/existing_feature in range(7, turf)) + for(var/obj/structure/existing_feature in range(7, target_turf)) if(istype(existing_feature, picked_feature)) can_spawn = FALSE break if(can_spawn) - new picked_feature(turf) + new picked_feature(target_turf) spawned_something = TRUE //MOB SPAWNING HERE @@ -161,12 +163,12 @@ // prevents tendrils spawning in each other's collapse range if(ispath(picked_mob, /obj/structure/spawner/lavaland)) - for(var/obj/structure/spawner/lavaland/spawn_blocker in range(2, turf)) + for(var/obj/structure/spawner/lavaland/spawn_blocker in range(2, target_turf)) can_spawn = FALSE break // if the random is not a tendril (hopefully meaning it is a mob), avoid spawning if there's another one within 12 tiles else - var/list/things_in_range = range(12, turf) + var/list/things_in_range = range(12, target_turf) for(var/mob/living/mob_blocker in things_in_range) if(ismining(mob_blocker)) can_spawn = FALSE @@ -176,7 +178,7 @@ can_spawn = can_spawn && !(locate(/obj/effect/spawner/random/lavaland_mob) in things_in_range) //if there's a megafauna within standard view don't spawn anything at all (This isn't really consistent, I don't know why we do this. you do you tho) if(can_spawn) - for(var/mob/living/simple_animal/hostile/megafauna/found_fauna in range(7, turf)) + for(var/mob/living/simple_animal/hostile/megafauna/found_fauna in range(7, target_turf)) can_spawn = FALSE break @@ -185,7 +187,7 @@ weighted_megafauna_spawn_list.Remove(picked_mob) megafauna_spawn_list = expand_weights(weighted_megafauna_spawn_list) megas_allowed = megas_allowed && length(megafauna_spawn_list) - new picked_mob(turf) + new picked_mob(target_turf) spawned_something = TRUE CHECK_TICK diff --git a/code/datums/mapgen/Cavegens/IcemoonCaves.dm b/code/datums/mapgen/Cavegens/IcemoonCaves.dm index 89a153aedd7..7d7437ccda6 100644 --- a/code/datums/mapgen/Cavegens/IcemoonCaves.dm +++ b/code/datums/mapgen/Cavegens/IcemoonCaves.dm @@ -4,9 +4,9 @@ weighted_mob_spawn_list = list( + /mob/living/basic/mining/legion/snow = 50, /mob/living/basic/mining/lobstrosity = 15, /mob/living/basic/mining/goldgrub = 10, - /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50, /mob/living/simple_animal/hostile/asteroid/polarbear = 30, /mob/living/simple_animal/hostile/asteroid/wolf = 50, /obj/structure/spawner/ice_moon = 3, @@ -63,7 +63,7 @@ weighted_mob_spawn_list = list( SPAWN_MEGAFAUNA = 1, /mob/living/basic/mining/ice_whelp = 60, - /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 100, + /mob/living/basic/mining/legion/snow = 100, /mob/living/simple_animal/hostile/asteroid/ice_demon = 100, /obj/structure/spawner/ice_moon/demonic_portal = 6, /obj/structure/spawner/ice_moon/demonic_portal/snowlegion = 6, diff --git a/code/datums/martial/boxing.dm b/code/datums/martial/boxing.dm index 720bda243b9..9ba1a53d40c 100644 --- a/code/datums/martial/boxing.dm +++ b/code/datums/martial/boxing.dm @@ -67,6 +67,15 @@ /obj/item/clothing/gloves/boxing var/datum/martial_art/boxing/style = new +/obj/item/clothing/gloves/boxing/Initialize(mapload) + . = ..() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/extendohand_l, /datum/crafting_recipe/extendohand_r) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/clothing/gloves/boxing/equipped(mob/user, slot) ..() // boxing requires human diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index a5aa648ecee..53bcce6c6ff 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -167,6 +167,9 @@ mood_change = -4 timeout = 2 MINUTES +/datum/mood_event/healsbadman/long_term + timeout = 10 MINUTES + /datum/mood_event/jittery description = "I'm nervous and on edge and I can't stand still!!" mood_change = -2 diff --git a/code/datums/mutations/antenna.dm b/code/datums/mutations/antenna.dm index bc5026ab148..b71f66c0fa6 100644 --- a/code/datums/mutations/antenna.dm +++ b/code/datums/mutations/antenna.dm @@ -91,32 +91,11 @@ // chance to alert the read-ee to_chat(cast_on, span_danger("You feel something foreign enter your mind.")) - var/list/recent_speech = list() - var/list/say_log = list() - var/log_source = cast_on.logging - //this whole loop puts the read-ee's say logs into say_log in an easy to access way - for(var/log_type in log_source) - var/nlog_type = text2num(log_type) - if(nlog_type & LOG_SAY) - var/list/reversed = log_source[log_type] - if(islist(reversed)) - say_log = reverse_range(reversed.Copy()) - break - - for(var/spoken_memory in say_log) - //up to 3 random lines of speech, favoring more recent speech - if(length(recent_speech) >= 3) - break - if(prob(50)) - continue - // log messages with tags like telepathy are displayed like "(Telepathy to Ckey/(target)) "greetings""" - // by splitting the text by using a " delimiter, we can grab JUST the greetings part - recent_speech[spoken_memory] = splittext(say_log[spoken_memory], "\"", 1, 0, TRUE)[3] - + var/list/recent_speech = cast_on.copy_recent_speech(copy_amount = 3, line_chance = 50) if(length(recent_speech)) to_chat(owner, span_boldnotice("You catch some drifting memories of their past conversations...")) for(var/spoken_memory in recent_speech) - to_chat(owner, span_notice("[recent_speech[spoken_memory]]")) + to_chat(owner, span_notice("[spoken_memory]")) if(iscarbon(cast_on)) var/mob/living/carbon/carbon_cast_on = cast_on diff --git a/code/datums/mutations/touch.dm b/code/datums/mutations/touch.dm index 1f1cefe1cbe..3f798ba52b2 100644 --- a/code/datums/mutations/touch.dm +++ b/code/datums/mutations/touch.dm @@ -38,7 +38,7 @@ ///This var decides if the spell should chain, dictated by presence of power chromosome var/chain = FALSE ///Affects damage, should do about 1 per limb - var/zap_power = 7500 + var/zap_power = 3e6 ///Range of tesla shock bounces var/zap_range = 7 ///flags that dictate what the tesla shock can interact with, Can only damage mobs, Cannot damage machines or generate energy diff --git a/code/datums/quirks/negative_quirks/prosthetic_limb.dm b/code/datums/quirks/negative_quirks/prosthetic_limb.dm index f6f0e304a6d..e7ea4d75788 100644 --- a/code/datums/quirks/negative_quirks/prosthetic_limb.dm +++ b/code/datums/quirks/negative_quirks/prosthetic_limb.dm @@ -3,9 +3,8 @@ desc = "An accident caused you to lose one of your limbs. Because of this, you now have a surplus prosthetic!" icon = "tg-prosthetic-leg" value = -3 - medical_record_text = "During physical examination, patient was found to have a low-budget prosthetic limb." hardcore_value = 3 - quirk_flags = QUIRK_HUMAN_ONLY // while this technically changes appearance, we don't want it to be shown on the dummy because it's randomized at roundstart + quirk_flags = QUIRK_HUMAN_ONLY | QUIRK_CHANGES_APPEARANCE mail_goodies = list(/obj/item/weldingtool/mini, /obj/item/stack/cable_coil/five) /// The slot to replace, in string form var/slot_string = "limb" @@ -13,28 +12,20 @@ var/obj/item/bodypart/old_limb /datum/quirk/prosthetic_limb/add_unique(client/client_source) - var/limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) + var/limb_type = GLOB.limb_choice[client_source?.prefs?.read_preference(/datum/preference/choiced/prosthetic)] + if(isnull(limb_type)) //Client gone or they chose a random prosthetic + limb_type = GLOB.limb_choice[pick(GLOB.limb_choice)] + var/mob/living/carbon/human/human_holder = quirk_holder - var/obj/item/bodypart/prosthetic - switch(limb_slot) - if(BODY_ZONE_L_ARM) - prosthetic = new /obj/item/bodypart/arm/left/robot/surplus - slot_string = "left arm" - if(BODY_ZONE_R_ARM) - prosthetic = new /obj/item/bodypart/arm/right/robot/surplus - slot_string = "right arm" - if(BODY_ZONE_L_LEG) - prosthetic = new /obj/item/bodypart/leg/left/robot/surplus - slot_string = "left leg" - if(BODY_ZONE_R_LEG) - prosthetic = new /obj/item/bodypart/leg/right/robot/surplus - slot_string = "right leg" - medical_record_text = "During physical examination, patient was found to have a low-budget prosthetic [slot_string]." - old_limb = human_holder.return_and_replace_bodypart(prosthetic, special = TRUE) + var/obj/item/bodypart/surplus = new limb_type() + slot_string = "[surplus.plaintext_zone]" + + medical_record_text = "Patient uses a low-budget prosthetic on the [slot_string]." + old_limb = human_holder.return_and_replace_bodypart(surplus, special = TRUE) /datum/quirk/prosthetic_limb/post_add() to_chat(quirk_holder, span_boldannounce("Your [slot_string] has been replaced with a surplus prosthetic. It is fragile and will easily come apart under duress. Additionally, \ - you need to use a welding tool and cables to repair it, instead of bruise packs and ointment.")) + you need to use a welding tool and cables to repair it, instead of sutures and regenerative meshes.")) /datum/quirk/prosthetic_limb/remove() var/mob/living/carbon/human/human_holder = quirk_holder diff --git a/code/datums/records/manifest.dm b/code/datums/records/manifest.dm index 13061218b51..7b43b7644ef 100644 --- a/code/datums/records/manifest.dm +++ b/code/datums/records/manifest.dm @@ -111,6 +111,8 @@ GLOBAL_DATUM_INIT(manifest, /datum/manifest, new) person_gender = "Male" if(person.gender == "female") person_gender = "Female" + var/datum/dna/record_dna = new() + person.dna.copy_dna(record_dna) // SKYRAT EDIT ADDITION BEGIN - ALTERNATIVE_JOB_TITLES // The alt job title, if user picked one, or the default @@ -119,32 +121,32 @@ GLOBAL_DATUM_INIT(manifest, /datum/manifest, new) var/datum/record/locked/lockfile = new( age = person.age, - blood_type = person.dna.blood_type, + blood_type = record_dna.blood_type, character_appearance = character_appearance, - dna_string = person.dna.unique_enzymes, - fingerprint = md5(person.dna.unique_identity), + dna_string = record_dna.unique_enzymes, + fingerprint = md5(record_dna.unique_identity), gender = person_gender, initial_rank = assignment, name = person.real_name, rank = chosen_assignment, // SKYRAT EDIT - Alt job titles - ORIGINAL: rank = assignment, - species = person.dna.species.name, + species = record_dna.species.name, trim = assignment, // Locked specifics - dna_ref = person.dna, + locked_dna = record_dna, mind_ref = person.mind, ) new /datum/record/crew( age = person.age, - blood_type = person.dna.blood_type, + blood_type = record_dna.blood_type, character_appearance = character_appearance, - dna_string = person.dna.unique_enzymes, - fingerprint = md5(person.dna.unique_identity), + dna_string = record_dna.unique_enzymes, + fingerprint = md5(record_dna.unique_identity), gender = person_gender, initial_rank = assignment, name = person.real_name, rank = chosen_assignment, // SKYRAT EDIT - Alt job titles - ORIGINAL: rank = assignment, - species = person.dna.species.name, + species = record_dna.species.name, trim = assignment, // Crew specific lock_ref = REF(lockfile), diff --git a/code/datums/records/record.dm b/code/datums/records/record.dm index 67fce2f49a4..276865115e4 100644 --- a/code/datums/records/record.dm +++ b/code/datums/records/record.dm @@ -24,6 +24,8 @@ var/species /// The character's ID trim var/trim + /// The character's voice, if they have one. + var/voice /datum/record/New( age = 18, @@ -37,6 +39,7 @@ rank = "Unassigned", species = "Human", trim = "Unassigned", + voice = "?????", ) src.age = age src.blood_type = blood_type @@ -138,9 +141,9 @@ */ /datum/record/locked /// Mob's dna - var/datum/dna/dna_ref + var/datum/dna/locked_dna /// Mind datum - var/datum/mind/mind_ref + var/datum/weakref/mind_ref /// Typepath of species used by player, for usage in respawning via records var/species_type @@ -157,13 +160,13 @@ species = "Human", trim = "Unassigned", /// Locked specific - datum/dna/dna_ref, + datum/dna/locked_dna, datum/mind/mind_ref, ) . = ..() - src.dna_ref = dna_ref - src.mind_ref = mind_ref - species_type = dna_ref.species.type + src.locked_dna = locked_dna + src.mind_ref = WEAKREF(mind_ref) + species_type = locked_dna.species.type GLOB.manifest.locked += src diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index b9747d54acc..cb0b55be059 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -265,10 +265,10 @@ /datum/status_effect/hippocratic_oath/proc/consume_owner() owner.visible_message(span_notice("[owner]'s soul is absorbed into the rod, relieving the previous snake of its duty.")) var/list/chems = list(/datum/reagent/medicine/sal_acid, /datum/reagent/medicine/c2/convermol, /datum/reagent/medicine/oxandrolone) - var/mob/living/simple_animal/hostile/retaliate/snake/healSnake = new(owner.loc, pick(chems)) - healSnake.name = "Asclepius's Snake" - healSnake.real_name = "Asclepius's Snake" - healSnake.desc = "A mystical snake previously trapped upon the Rod of Asclepius, now freed of its burden. Unlike the average snake, its bites contain chemicals with minor healing properties." + var/mob/living/basic/snake/spawned = new(owner.loc, pick(chems)) + spawned.name = "Asclepius's Snake" + spawned.real_name = "Asclepius's Snake" + spawned.desc = "A mystical snake previously trapped upon the Rod of Asclepius, now freed of its burden. Unlike the average snake, its bites contain chemicals with minor healing properties." new /obj/effect/decal/cleanable/ash(owner.loc) new /obj/item/rod_of_asclepius(owner.loc) owner.investigate_log("has been consumed by the Rod of Asclepius.", INVESTIGATE_DEATHS) diff --git a/code/datums/status_effects/debuffs/cyborg.dm b/code/datums/status_effects/debuffs/cyborg.dm new file mode 100644 index 00000000000..0f95b494197 --- /dev/null +++ b/code/datums/status_effects/debuffs/cyborg.dm @@ -0,0 +1,22 @@ +/// Reduce a cyborg's speed when you throw things at it +/datum/status_effect/borg_throw_slow + id = "borg_throw_slowdown" + alert_type = /atom/movable/screen/alert/status_effect/borg_throw_slow + duration = 3 SECONDS + status_type = STATUS_EFFECT_REPLACE + +/datum/status_effect/borg_throw_slow/on_apply() + . = ..() + owner.add_movespeed_modifier(/datum/movespeed_modifier/borg_throw, update = TRUE) + +/datum/status_effect/borg_throw_slow/on_remove() + . = ..() + owner.remove_movespeed_modifier(/datum/movespeed_modifier/borg_throw, update = TRUE) + +/atom/movable/screen/alert/status_effect/borg_throw_slow + name = "Percussive Maintenance" + desc = "A sudden impact has triggered your collision avoidance routines, reducing movement speed." + icon_state = "weaken" + +/datum/movespeed_modifier/borg_throw + multiplicative_slowdown = 0.9 diff --git a/code/datums/votes/map_vote.dm b/code/datums/votes/map_vote.dm index 745e7c6f7af..323ee29ccc2 100644 --- a/code/datums/votes/map_vote.dm +++ b/code/datums/votes/map_vote.dm @@ -20,7 +20,7 @@ /datum/vote/map_vote/create_vote() . = ..() check_population(should_key_choices = FALSE) - if((length(choices) == 1) && EMERGENCY_ESCAPED_OR_ENDGAMED) // Only one choice, no need to vote. Let's just auto-rotate it to the only remaining map because it would just happen anyways. + if(length(choices) == 1) // Only one choice, no need to vote. Let's just auto-rotate it to the only remaining map because it would just happen anyways. var/de_facto_winner = choices[1] var/datum/map_config/change_me_out = global.config.maplist[de_facto_winner] SSmapping.changemap(change_me_out) @@ -118,3 +118,12 @@ SSmapping.map_voted = TRUE if(SSmapping.map_vote_rocked) SSmapping.map_vote_rocked = FALSE + +/proc/revert_map_vote() + var/datum/map_config/override_map = SSmapping.config + if(isnull(override_map)) + return + + SSmapping.changemap(override_map) + log_game("The next map has been reset to [override_map.map_name].") + send_to_playing_players(span_boldannounce("The next map is: [override_map.map_name].")) diff --git a/code/datums/votes/restart_vote.dm b/code/datums/votes/restart_vote.dm index 24d38f35396..987d5b87eb3 100644 --- a/code/datums/votes/restart_vote.dm +++ b/code/datums/votes/restart_vote.dm @@ -67,7 +67,14 @@ message_admins("A restart vote has passed, but there are active admins on with +SERVER, so it has been canceled. If you wish, you may restart the server.") return - SSticker.Reboot("Restart vote successful.", "restart vote", 1) + // If there was a previous map vote, we revert the change. + if(!isnull(SSmapping.next_map_config)) + log_game("The next map has been reset due to successful restart vote.") + send_to_playing_players(span_boldannounce("The next map has been reset due to successful restart vote.")) + revert_map_vote() + + SSticker.force_ending = FORCE_END_ROUND + log_game("End round forced by successful restart vote.") return CRASH("[type] wasn't passed a valid winning choice. (Got: [winning_option || "null"])") diff --git a/code/datums/wounds/scars/_scars.dm b/code/datums/wounds/scars/_scars.dm index 774d8cc5265..e650899be29 100644 --- a/code/datums/wounds/scars/_scars.dm +++ b/code/datums/wounds/scars/_scars.dm @@ -181,7 +181,7 @@ if((human_victim.wear_mask && (human_victim.wear_mask.flags_inv & HIDEFACE)) || (human_victim.head && (human_victim.head.flags_inv & HIDEFACE))) return FALSE else if(limb.scars_covered_by_clothes) - var/num_covers = LAZYLEN(human_victim.clothingonpart(limb)) + var/num_covers = LAZYLEN(human_victim.get_clothing_on_part(limb)) if(num_covers + get_dist(viewer, victim) >= visibility) return FALSE diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 29c5ea6e4df..4912a69f7b8 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -705,6 +705,7 @@ . = list() SEND_SIGNAL(src, COMSIG_ATOM_EXAMINE_MORE, user, .) + SEND_SIGNAL(user, COMSIG_MOB_EXAMINING_MORE, src, .) /// Wrapper for _update_appearance that is only called when APPEARANCE_SUCCESS_TRACKING is defined #ifdef APPEARANCE_SUCCESS_TRACKING diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 26dfcb4be76..6208df36de1 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -468,8 +468,8 @@ GLOBAL_LIST_EMPTY(dynamic_station_traits) for(var/job in job_prefs) var/priority = job_prefs[job] job_data += "[job]: [SSjob.job_priority_level_to_string(priority)]" - to_chat(player, span_danger("You were unable to qualify for any roundstart antagonist role because you could not qualify for any of the roundstart jobs you were trying to qualify for, along with 'return to lobby if job is unavailable' enabled.")) - log_admin("[player.ckey] failed to qualify for any job and has [player.client.prefs.be_special.len] antag preferences enabled. They will be unable to qualify for any roundstart antagonist role. These are their job preferences - [job_data.Join(" | ")]") + to_chat(player, span_danger("You were unable to qualify for any roundstart antagonist role this round because your job preferences presented a high chance of all of your selected jobs being unavailable, along with 'return to lobby if job is unavailable' enabled. Increase the number of roles set to medium or low priority to reduce the chances of this happening.")) + log_admin("[player.ckey] failed to qualify for any roundstart antagonist role because their job preferences presented a high chance of all of their selected jobs being unavailable, along with 'return to lobby if job is unavailable' enabled and has [player.client.prefs.be_special.len] antag preferences enabled. They will be unable to qualify for any roundstart antagonist role. These are their job preferences - [job_data.Join(" | ")]") else roundstart_pop_ready++ candidates.Add(player) @@ -639,8 +639,10 @@ GLOBAL_LIST_EMPTY(dynamic_station_traits) if(rule.persistent) current_rules += rule new_snapshot(rule) + rule.forget_startup() return TRUE rule.clean_up() // Refund threat, delete teams and so on. + rule.forget_startup() executed_rules -= rule stack_trace("The starting rule \"[rule.name]\" failed to execute.") return FALSE @@ -688,9 +690,11 @@ GLOBAL_LIST_EMPTY(dynamic_station_traits) executed_rules += new_rule if (new_rule.persistent) current_rules += new_rule + new_rule.forget_startup() return TRUE else if (forced) log_dynamic("The ruleset [new_rule.name] couldn't be executed due to lack of elligible players.") + new_rule.forget_startup() return FALSE /datum/game_mode/dynamic/process() diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm index faefbbe9426..a1c4c9232e2 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm @@ -167,6 +167,14 @@ GLOB.pre_setup_antags -= M return TRUE +/// Rulesets can be reused, so when we're done setting one up we want to wipe its memory of the people it was selecting over +/// This isn't Destroy we aren't deleting it here, rulesets free when nothing holds a ref. This is just to prevent hung refs. +/datum/dynamic_ruleset/proc/forget_startup() + SHOULD_CALL_PARENT(TRUE) + candidates = list() + assigned = list() + antag_datum = null + /// Here you can perform any additional checks you want. (such as checking the map etc) /// Remember that on roundstart no one knows what their job is at this point. /// IMPORTANT: If ready() returns TRUE, that means pre_execute() or execute() should never fail! diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 99aabf400d2..91f82f29f1c 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -21,6 +21,13 @@ /// Abstract root value var/abstract_type = /datum/dynamic_ruleset/midround +/datum/dynamic_ruleset/midround/forget_startup() + living_players = list() + living_antags = list() + dead_players = list() + list_observers = list() + return ..() + /datum/dynamic_ruleset/midround/from_ghosts weight = 0 required_type = /mob/dead/observer @@ -370,8 +377,6 @@ flags = HIGH_IMPACT_RULESET var/list/operative_cap = list(2,2,3,3,4,5,5,5,5,5) - /// The nuke ops team datum. - var/datum/team/nuclear/nuke_team /datum/dynamic_ruleset/midround/from_ghosts/nuclear/acceptable(population=0, threat=0) if (locate(/datum/dynamic_ruleset/roundstart/nuclear) in mode.executed_rules) @@ -397,7 +402,6 @@ new_character.mind.special_role = ROLE_NUCLEAR_OPERATIVE if(index == 1) var/datum/antagonist/nukeop/leader/leader_antag_datum = new() - nuke_team = leader_antag_datum.nuke_team new_character.mind.add_antag_datum(leader_antag_datum) return return ..() @@ -483,6 +487,10 @@ repeatable = TRUE var/list/vents = list() +/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/forget_startup() + vents = list() + return ..() + /datum/dynamic_ruleset/midround/from_ghosts/xenomorph/execute() // 50% chance of being incremented by one required_candidates += prob(50) @@ -562,6 +570,10 @@ repeatable = TRUE var/list/spawn_locs = list() +/datum/dynamic_ruleset/midround/from_ghosts/space_dragon/forget_startup() + spawn_locs = list() + return ..() + /datum/dynamic_ruleset/midround/from_ghosts/space_dragon/execute() for(var/obj/effect/landmark/carpspawn/C in GLOB.landmarks_list) spawn_locs += (C.loc) @@ -600,6 +612,10 @@ var/datum/team/abductor_team/new_team +/datum/dynamic_ruleset/midround/from_ghosts/abductors/forget_startup() + new_team = null + return ..() + /datum/dynamic_ruleset/midround/from_ghosts/abductors/ready(forced = FALSE) if (required_candidates > (dead_players.len + list_observers.len)) return FALSE @@ -632,6 +648,10 @@ var/list/spawn_locs = list() +/datum/dynamic_ruleset/midround/from_ghosts/space_ninja/forget_startup() + spawn_locs = list() + return ..() + /datum/dynamic_ruleset/midround/from_ghosts/space_ninja/execute() for(var/obj/effect/landmark/carpspawn/carp_spawn in GLOB.landmarks_list) if(!isturf(carp_spawn.loc)) @@ -686,6 +706,10 @@ var/need_extra_spawns_value = 15 var/list/spawn_locs = list() +/datum/dynamic_ruleset/midround/from_ghosts/revenant/forget_startup() + spawn_locs = list() + return ..() + /datum/dynamic_ruleset/midround/from_ghosts/revenant/acceptable(population=0, threat=0) if(GLOB.dead_mob_list.len < dead_mobs_required) return FALSE @@ -857,6 +881,10 @@ repeatable = TRUE var/list/possible_spawns = list() ///places the antag can spawn +/datum/dynamic_ruleset/midround/from_ghosts/paradox_clone/forget_startup() + possible_spawns = list() + return ..() + /datum/dynamic_ruleset/midround/from_ghosts/paradox_clone/execute() possible_spawns += find_maintenance_spawn(atmos_sensitive = TRUE, require_darkness = FALSE) if(!possible_spawns.len) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index df078c462d9..a90eba738c1 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -121,6 +121,10 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE) var/list/datum/team/brother_team/pre_brother_teams = list() var/const/min_team_size = 2 +/datum/dynamic_ruleset/roundstart/traitorbro/forget_startup() + pre_brother_teams = list() + return ..() + /datum/dynamic_ruleset/roundstart/traitorbro/pre_execute(population) . = ..() var/num_teams = (get_antag_cap(population)/min_team_size) * (scaled_times + 1) // 1 team per scaling diff --git a/code/game/gamemodes/dynamic/ruleset_picking.dm b/code/game/gamemodes/dynamic/ruleset_picking.dm index 4922d7355ce..d6e2fd6b1f4 100644 --- a/code/game/gamemodes/dynamic/ruleset_picking.dm +++ b/code/game/gamemodes/dynamic/ruleset_picking.dm @@ -118,11 +118,12 @@ message_admins("[key_name(M)] joined the station, and was selected by the [rule.name] ruleset.") log_dynamic("[key_name(M)] joined the station, and was selected by the [rule.name] ruleset.") executed_rules += rule - rule.candidates.Cut() if (rule.persistent) current_rules += rule new_snapshot(rule) + rule.forget_startup() return TRUE + rule.forget_startup() rule.clean_up() stack_trace("The [rule.ruletype] rule \"[rule.name]\" failed to execute.") return FALSE diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 00488ba1dfb..bdefee42c3e 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -236,18 +236,46 @@ GLOBAL_LIST_EMPTY(objectives) //SKYRAT EDIT ADDITION /datum/objective/assassinate/admin_edit(mob/admin) admin_simple_target_pick(admin) +#define DISCONNECT_GRACE_TIME (2 MINUTES) +#define DISCONNECT_GRACE_WARNING_TIME (1 MINUTES) + /datum/objective/mutiny name = "mutiny" martyr_compatible = 1 var/target_role_type = FALSE + /// Not primarily used as a cooldown but a timer to give a little bit more of a chance for the player to reconnect. + COOLDOWN_DECLARE(disconnect_timer) + /// Whether admins have been warned about the potentially AFK player + var/warned_admins = FALSE +/datum/objective/mutiny/proc/warn_admins() + message_admins("[ADMIN_LOOKUPFLW(target.current)] has gone AFK with a mutiny objective that involves them. They only have [COOLDOWN_TIMELEFT(src, disconnect_timer) / 10] seconds remaining before they are treated as if they were dead.") /datum/objective/mutiny/check_completion() - if(!target || !considered_alive(target) || considered_afk(target) || considered_exiled(target)) + if(!target || !considered_alive(target) || considered_exiled(target)) return TRUE + + if(considered_afk(target)) + if(!COOLDOWN_STARTED(src, disconnect_timer)) + COOLDOWN_START(src, disconnect_timer, DISCONNECT_GRACE_TIME) + warn_admins() + else if(COOLDOWN_FINISHED(src, disconnect_timer)) + return TRUE + else if(COOLDOWN_TIMELEFT(src, disconnect_timer) <= DISCONNECT_GRACE_WARNING_TIME && !warned_admins) + warned_admins = TRUE + warn_admins() + else + COOLDOWN_RESET(src, disconnect_timer) + warned_admins = FALSE + var/turf/T = get_turf(target.current) return !T || !is_station_level(T.z) +#undef DISCONNECT_GRACE_TIME +#undef DISCONNECT_GRACE_WARNING_TIME + + + /datum/objective/mutiny/update_explanation_text() ..() if(target?.current) diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index b6327480399..fde5c89b88d 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -927,6 +927,7 @@ wrench.play_tool_sound(src, 50) setDir(turn(dir,-90)) to_chat(user, span_notice("You rotate [src].")) + SEND_SIGNAL(src, COMSIG_MACHINERY_DEFAULT_ROTATE_WRENCH, user, wrench) return TRUE /obj/machinery/proc/exchange_parts(mob/user, obj/item/storage/part_replacer/replacer_tool) @@ -1122,10 +1123,10 @@ if(prob(85) && (zap_flags & ZAP_MACHINE_EXPLOSIVE) && !(resistance_flags & INDESTRUCTIBLE)) explosion(src, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 4, flame_range = 2, adminlog = FALSE, smoke = FALSE) else if(zap_flags & ZAP_OBJ_DAMAGE) - take_damage(power * 0.0005, BURN, ENERGY) + take_damage(power * 6.25e-7, BURN, ENERGY) if(prob(40)) emp_act(EMP_LIGHT) - power -= power * 0.0005 + power -= power * 5e-4 return ..() /obj/machinery/proc/adjust_item_drop_location(atom/movable/dropped_atom) // Adjust item drop location to a 3x3 grid inside the tile, returns slot id from 0 to 8 diff --git a/code/game/machinery/airlock_control.dm b/code/game/machinery/airlock_control.dm index 4c3532e3616..f4d1b29da18 100644 --- a/code/game/machinery/airlock_control.dm +++ b/code/game/machinery/airlock_control.dm @@ -6,10 +6,6 @@ var/airlock_state var/frequency -/obj/machinery/door/airlock/Initialize(mapload) - . = ..() - RegisterSignal(SSdcs, COMSIG_GLOB_GREY_TIDE, PROC_REF(grey_tide)) - /// Forces the airlock to unbolt and open /obj/machinery/door/airlock/proc/secure_open() locked = FALSE @@ -35,17 +31,6 @@ locked = FALSE return ..() -/obj/machinery/door/airlock/proc/grey_tide(datum/source, list/grey_tide_areas) - SIGNAL_HANDLER - - if(!is_station_level(z) || critical_machine) - return //Skip doors in critical positions, such as the SM chamber. - - for(var/area_type in grey_tide_areas) - if(!istype(get_area(src), area_type)) - continue - INVOKE_ASYNC(src, PROC_REF(prison_open)) //Sleep gets called further down in open(), so we have to invoke async - /obj/machinery/airlock_sensor icon = 'icons/obj/machines/wallmounts.dmi' icon_state = "airlock_sensor_off" diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index 4ec567a95d6..c433565dbf8 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -262,8 +262,9 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) // SKYRAT EDIT END // Binary living/dead status + // Current status if (sensor_mode >= SENSOR_LIVING) - entry["life_status"] = (tracked_living_mob.stat != DEAD) + entry["life_status"] = tracked_living_mob.stat // Damage if (sensor_mode >= SENSOR_VITALS) diff --git a/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm b/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm index 57067db47f6..96c33871a40 100644 --- a/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm +++ b/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm @@ -133,7 +133,7 @@ . = ..() if(prob(5)) owner.emote("squeaks") - playsound(owner, 'sound/effects/mousesqueek.ogg', 100) + playsound(owner, 'sound/creatures/mousesqueek.ogg', 100) #undef RAT_ORGAN_COLOR #undef RAT_SCLERA_COLOR diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 2786ed0f769..9d18b7ecb85 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -191,12 +191,23 @@ diag_hud_set_electrified() - RegisterSignal(src, COMSIG_MACHINERY_BROKEN, PROC_REF(on_break)) - // Click on the floor to close airlocks AddComponent(/datum/component/redirect_attack_hand_from_turf) - return INITIALIZE_HINT_LATELOAD + RegisterSignal(src, COMSIG_MACHINERY_BROKEN, PROC_REF(on_break)) + + RegisterSignal(SSdcs, COMSIG_GLOB_GREY_TIDE, PROC_REF(grey_tide)) + +/obj/machinery/door/airlock/proc/grey_tide(datum/source, list/grey_tide_areas) + SIGNAL_HANDLER + + if(!is_station_level(z) || critical_machine) + return //Skip doors in critical positions, such as the SM chamber. + + for(var/area_type in grey_tide_areas) + if(!istype(get_area(src), area_type)) + continue + INVOKE_ASYNC(src, PROC_REF(prison_open)) //Sleep gets called further down in open(), so we have to invoke async /obj/machinery/door/airlock/connect_to_shuttle(mapload, obj/docking_port/mobile/port, obj/docking_port/stationary/dock) if(id_tag) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index d5d0e9c732e..15c740a31e4 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -138,6 +138,9 @@ storage_type = /obj/item/tank/jetpack/oxygen/harness mod_type = /obj/item/mod/control/pre_equipped/nuclear +/obj/machinery/suit_storage_unit/syndicate/lavaland + mod_type = /obj/item/mod/control/pre_equipped/nuclear/no_jetpack + /obj/machinery/suit_storage_unit/interdyne mask_type = /obj/item/clothing/mask/gas/syndicate storage_type = /obj/item/tank/jetpack/oxygen/harness diff --git a/code/game/machinery/telecomms/computers/telemonitor.dm b/code/game/machinery/telecomms/computers/telemonitor.dm index b862a6372b7..400d827f618 100644 --- a/code/game/machinery/telecomms/computers/telemonitor.dm +++ b/code/game/machinery/telecomms/computers/telemonitor.dm @@ -14,10 +14,10 @@ /// Current screen the user is viewing var/screen = MAIN_VIEW - /// The machines located by the computer - var/list/machinelist = list() - /// the currently selected machine - var/obj/machinery/telecomms/SelectedMachine + /// Weakrefs of the machines located by the computer + var/list/machine_list = list() + /// Weakref of the currently selected tcomms machine + var/datum/weakref/selected_machine_ref /// The network to probe var/network = "NULL" /// Error message to show @@ -35,20 +35,26 @@ // --- Main Menu --- if(MAIN_VIEW) var/list/found_machinery = list() - for(var/obj/machinery/telecomms/telecomms in machinelist) + for(var/datum/weakref/tcomms_ref in machine_list) + var/obj/machinery/telecomms/telecomms = tcomms_ref.resolve() + if(!telecomms) + machine_list -= tcomms_ref + continue found_machinery += list(list("ref" = REF(telecomms), "name" = telecomms.name, "id" = telecomms.id)) data["machinery"] = found_machinery // --- Viewing Machine --- if(MACHINE_VIEW) // Send selected machinery data var/list/machine_out = list() - machine_out["name"] = SelectedMachine.name - // Get the linked machinery - var/list/linked_machinery = list() - for(var/obj/machinery/telecomms/T in SelectedMachine.links) - linked_machinery += list(list("ref" = REF(T.id), "name" = T.name, "id" = T.id)) - machine_out["linked_machinery"] = linked_machinery - data["machine"] = machine_out + var/obj/machinery/telecomms/selected = selected_machine_ref.resolve() + if(selected) + machine_out["name"] = selected.name + // Get the linked machinery + var/list/linked_machinery = list() + for(var/obj/machinery/telecomms/T in selected.links) + linked_machinery += list(list("ref" = REF(T.id), "name" = T.name, "id" = T.id)) + machine_out["linked_machinery"] = linked_machinery + data["machine"] = machine_out return data /obj/machinery/computer/telecomms/monitor/ui_act(action, params) @@ -67,7 +73,9 @@ error_message = "OPERATION FAILED: NETWORK ID TOO LONG." return TRUE - if(machinelist.len > 0) + list_clear_empty_weakrefs(machine_list) + + if(machine_list.len > 0) error_message = "OPERATION FAILED: CANNOT PROBE WHEN BUFFER FULL." return TRUE @@ -75,26 +83,30 @@ for(var/obj/machinery/telecomms/T in urange(25, src)) if(T.network == network) - machinelist.Add(T) - if(machinelist.len == 0) + machine_list += WEAKREF(T) + if(machine_list.len == 0) error_message = "OPERATION FAILED: UNABLE TO LOCATE NETWORK ENTITIES IN [network]." return TRUE - error_message = "[machinelist.len] ENTITIES LOCATED & BUFFERED"; + error_message = "[machine_list.len] ENTITIES LOCATED & BUFFERED"; return TRUE if("flush_buffer") - machinelist = list() + machine_list = list() network = "" return TRUE if("view_machine") - for(var/obj/machinery/telecomms/T in machinelist) - if(T.id == params["id"]) - SelectedMachine = T - if(!SelectedMachine) + for(var/datum/weakref/tcomms_ref in machine_list) + var/obj/machinery/telecomms/tcomms = tcomms_ref.resolve() + if(!tcomms) + machine_list -= tcomms_ref + continue + if(tcomms.id == params["id"]) + selected_machine_ref = tcomms_ref + if(!selected_machine_ref) error_message = "OPERATION FAILED: UNABLE TO LOCATE MACHINERY." screen = MACHINE_VIEW return TRUE if("return_home") - SelectedMachine = null + selected_machine_ref = null screen = MAIN_VIEW return TRUE return TRUE diff --git a/code/game/objects/effects/anomalies/anomalies_flux.dm b/code/game/objects/effects/anomalies/anomalies_flux.dm index eee4319b352..2bb3ab28a1a 100644 --- a/code/game/objects/effects/anomalies/anomalies_flux.dm +++ b/code/game/objects/effects/anomalies/anomalies_flux.dm @@ -66,7 +66,7 @@ ///range in whuich we zap var/zap_range = 1 ///strength of the zappy - var/zap_power = 2500 + var/zap_power = 1e6 ///the zappy flags var/zap_flags = ZAP_GENERATES_POWER | ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm index 6a519650d10..daaddb00ce0 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -212,6 +212,10 @@ icon_state += "-old" AddElement(/datum/element/swabable, CELL_LINE_TABLE_SLUDGE, CELL_VIRUS_TABLE_GENERIC, rand(2,4), 10) +/obj/effect/decal/cleanable/vomit/old/black_bile + name = "black bile" + desc = "There's something wiggling in there..." + color = COLOR_DARK /obj/effect/decal/cleanable/chem_pile name = "chemical pile" diff --git a/code/game/objects/effects/spawners/random/lavaland_mobs.dm b/code/game/objects/effects/spawners/random/lavaland_mobs.dm index 8aa20cc90e7..7b4bec1f6a1 100644 --- a/code/game/objects/effects/spawners/random/lavaland_mobs.dm +++ b/code/game/objects/effects/spawners/random/lavaland_mobs.dm @@ -10,9 +10,9 @@ /mob/living/basic/mining/brimdemon = 1, /mob/living/basic/mining/goldgrub = 1, /mob/living/basic/mining/goliath = 1, + /mob/living/basic/mining/legion = 1, /mob/living/basic/mining/lobstrosity/lava = 1, /mob/living/basic/mining/watcher = 1, - /mob/living/simple_animal/hostile/asteroid/hivelord/legion = 1, ) /// Spawns random watcher variants during map generation @@ -46,6 +46,6 @@ desc = "Chance to spawn a rare shiny version." icon_state = "legion" loot = list( - /mob/living/simple_animal/hostile/asteroid/hivelord/legion = 19, - /mob/living/simple_animal/hostile/asteroid/hivelord/legion/dwarf = 1, + /mob/living/basic/mining/legion = 19, + /mob/living/basic/mining/legion/dwarf = 1, ) diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index aaef891ee4a..94e9cb674b2 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -358,6 +358,10 @@ CIGARETTE PACKETS ARE IN FANCY.DM if(!istype(smoker) || smoker.get_item_by_slot(ITEM_SLOT_MASK) != loc) reagents.remove_any(to_smoke) return + else + if(src != smoker.wear_mask) + reagents.remove_any(to_smoke) + return reagents.expose(smoker, INGEST, min(to_smoke / reagents.total_volume, 1)) var/obj/item/organ/internal/lungs/lungs = smoker.get_organ_slot(ORGAN_SLOT_LUNGS) diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm index e5b7144dc8c..dae27c175b4 100644 --- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm @@ -822,7 +822,7 @@ /obj/item/circuitboard/machine/cryo_tube name = "Cryotube" greyscale_colors = CIRCUIT_COLOR_MEDICAL - build_path = /obj/machinery/atmospherics/components/unary/cryo_cell + build_path = /obj/machinery/cryo_cell req_components = list( /datum/stock_part/matter_bin = 1, /obj/item/stack/cable_coil = 1, diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 57bc04e7007..bfe1457aa52 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -747,6 +747,15 @@ pre_noise = TRUE post_noise = FALSE +/obj/item/toy/crayon/spraycan/Initialize(mapload) + . = ..() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/improvised_coolant) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/toy/crayon/spraycan/isValidSurface(surface) return (isfloorturf(surface) || iswallturf(surface)) diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index a8fa34ed5f8..0ab7e5d94b5 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -18,102 +18,6 @@ . = ..() ADD_TRAIT(src, TRAIT_CASTABLE_LOC, INNATE_TRAIT) -/obj/item/computer_disk/syndie_ai_upgrade - name = "AI interaction range upgrade" - desc = "A NT data chip containing information that a syndiCard AI can utilize to improve its wireless interfacing abilities. Simply slap it on top of an intelliCard, MODsuit, or AI core and watch it do its work! It's rumoured that there's something 'pretty awful' in it." - icon = 'icons/obj/antags/syndicate_tools.dmi' - icon_state = "something_awful" - max_capacity = 1000 - w_class = WEIGHT_CLASS_NORMAL - -/obj/item/computer_disk/syndie_ai_upgrade/pre_attack(atom/A, mob/living/user, params) - var/mob/living/silicon/ai/AI - if(isAI(A)) - AI = A - else - AI = locate() in A - if(!AI || AI.interaction_range == INFINITY) - playsound(src,'sound/machines/buzz-sigh.ogg',50,FALSE) - to_chat(user, span_notice("Error! Incompatible object!")) - return ..() - AI.interaction_range += 2 - if(AI.interaction_range > 7) - AI.interaction_range = INFINITY - playsound(src,'sound/machines/twobeep.ogg',50,FALSE) - to_chat(user, span_notice("You insert [src] into [AI]'s compartment, and it beeps as it processes the data.")) - to_chat(AI, span_notice("You process [src], and find yourself able to manipulate electronics from up to [AI.interaction_range] meters!")) - qdel(src) - -/obj/item/aicard/syndie - name = "syndiCard" - desc = "A storage device for AIs. Nanotrasen forgot to make the patent, so the Syndicate made their own version!" - icon = 'icons/obj/aicards.dmi' - icon_state = "syndicard" - base_icon_state = "syndicard" - item_flags = null - force = 7 - -/obj/item/aicard/syndie/loaded - /// Set to true while we're waiting for ghosts to sign up - var/finding_candidate = FALSE - -/obj/item/aicard/syndie/loaded/examine(mob/user) - . = ..() - - . += span_notice("This one has a little S.E.L.F. insignia on the back, and a label next to it that says 'Activate for one FREE aligned AI! Please attempt uplink reintegration or ask your employers for reimbursal if AI is unavailable or belligerent.") - -/obj/item/aicard/syndie/loaded/attack_self(mob/user, modifiers) - if(!isnull(AI)) - return ..() - if(finding_candidate) - balloon_alert(user, "loading...") - return TRUE - finding_candidate = TRUE - to_chat(user, span_notice("Connecting to S.E.L.F. dispatch...")) - procure_ai(user) - finding_candidate = FALSE - return TRUE - -/obj/item/aicard/syndie/loaded/proc/procure_ai(mob/user) - var/datum/antagonist/nukeop/op_datum = user.mind?.has_antag_datum(/datum/antagonist/nukeop,TRUE) - if(isnull(op_datum)) - balloon_alert(user, "invalid access!") - return - var/list/nuke_candidates = poll_ghost_candidates( - question = "Do you want to play as a nuclear operative MODsuit AI?", - jobban_type = ROLE_OPERATIVE, - be_special_flag = ROLE_OPERATIVE_MIDROUND, - poll_time = 15 SECONDS, - ignore_category = POLL_IGNORE_SYNDICATE, - ) - if(QDELETED(src)) - return - if(!LAZYLEN(nuke_candidates)) - to_chat(user, span_warning("Unable to connect to S.E.L.F. dispatch. Please wait and try again later or use the intelliCard on your uplink to get your points refunded.")) - return - // pick ghost, create AI and transfer - var/mob/dead/observer/ghos = pick(nuke_candidates) - var/mob/living/silicon/ai/weak_syndie/new_ai = new /mob/living/silicon/ai/weak_syndie(get_turf(src), new /datum/ai_laws/syndicate_override, ghos) - // create and apply syndie datum - var/datum/antagonist/nukeop/nuke_datum = new() - nuke_datum.send_to_spawnpoint = FALSE - new_ai.mind.add_antag_datum(nuke_datum, op_datum.nuke_team) - new_ai.mind.special_role = "Syndicate AI" - new_ai.faction |= ROLE_SYNDICATE - new_ai.grant_language(/datum/language/codespeak, source = LANGUAGE_MIND) - // Make it look evil!!! - new_ai.hologram_appearance = mutable_appearance('icons/mob/silicon/ai.dmi',"xeno_queen") //good enough - new_ai.icon_state = resolve_ai_icon("hades") - // Transfer the AI from the core we created into the card, then delete the core - capture_ai(new_ai, user) - var/obj/structure/ai_core/deactivated/detritus = locate() in get_turf(src) - qdel(detritus) - AI.control_disabled = FALSE - AI.radio_enabled = TRUE - do_sparks(4, TRUE, src) - playsound(src, 'sound/machines/chime.ogg', 25, TRUE) - return - /obj/item/aicard/Destroy(force) if(AI) AI.ghostize(can_reenter_corpse = FALSE) diff --git a/code/game/objects/items/devices/aicard_evil.dm b/code/game/objects/items/devices/aicard_evil.dm new file mode 100644 index 00000000000..1a5fce6897a --- /dev/null +++ b/code/game/objects/items/devices/aicard_evil.dm @@ -0,0 +1,104 @@ +/// One use AI card which downloads a ghost as a syndicate AI to put in your MODsuit +/obj/item/aicard/syndie + name = "syndiCard" + desc = "A storage device for AIs. Nanotrasen forgot to make the patent, so the Syndicate made their own version!" + icon = 'icons/obj/aicards.dmi' + icon_state = "syndicard" + base_icon_state = "syndicard" + item_flags = null + force = 7 + +/obj/item/aicard/syndie/loaded + /// Set to true while we're waiting for ghosts to sign up + var/finding_candidate = FALSE + +/obj/item/aicard/syndie/loaded/examine(mob/user) + . = ..() + . += span_notice("This one has a little S.E.L.F. insignia on the back, and a label next to it that says 'Activate for one FREE aligned AI! Please attempt uplink reintegration or ask your employers for reimbursal if AI is unavailable or belligerent.") + +/obj/item/aicard/syndie/loaded/attack_self(mob/user, modifiers) + if(!isnull(AI)) + return ..() + if(finding_candidate) + balloon_alert(user, "loading...") + return TRUE + finding_candidate = TRUE + to_chat(user, span_notice("Connecting to S.E.L.F. dispatch...")) + procure_ai(user) + finding_candidate = FALSE + return TRUE + +/obj/item/aicard/syndie/loaded/proc/procure_ai(mob/user) + var/datum/antagonist/nukeop/op_datum = user.mind?.has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(isnull(op_datum)) + balloon_alert(user, "invalid access!") + return + var/list/nuke_candidates = poll_ghost_candidates( + question = "Do you want to play as a nuclear operative MODsuit AI?", + jobban_type = ROLE_OPERATIVE, + be_special_flag = ROLE_OPERATIVE_MIDROUND, + poll_time = 15 SECONDS, + ignore_category = POLL_IGNORE_SYNDICATE, + ) + if(QDELETED(src)) + return + if(!LAZYLEN(nuke_candidates)) + to_chat(user, span_warning("Unable to connect to S.E.L.F. dispatch. Please wait and try again later or use the intelliCard on your uplink to get your points refunded.")) + return + // pick ghost, create AI and transfer + var/mob/dead/observer/ghos = pick(nuke_candidates) + var/mob/living/silicon/ai/weak_syndie/new_ai = new /mob/living/silicon/ai/weak_syndie(get_turf(src), new /datum/ai_laws/syndicate_override, ghos) + // create and apply syndie datum + var/datum/antagonist/nukeop/nuke_datum = new() + nuke_datum.send_to_spawnpoint = FALSE + new_ai.mind.add_antag_datum(nuke_datum, op_datum.nuke_team) + new_ai.mind.special_role = "Syndicate AI" + new_ai.faction |= ROLE_SYNDICATE + // Make it look evil!!! + new_ai.hologram_appearance = mutable_appearance('icons/mob/silicon/ai.dmi',"xeno_queen") //good enough + new_ai.icon_state = resolve_ai_icon("hades") + // Transfer the AI from the core we created into the card, then delete the core + capture_ai(new_ai, user) + var/obj/structure/ai_core/deactivated/detritus = locate() in get_turf(src) + qdel(detritus) + AI.control_disabled = FALSE + AI.radio_enabled = TRUE + do_sparks(4, TRUE, src) + playsound(src, 'sound/machines/chime.ogg', 25, TRUE) + return + +/obj/item/aicard/syndie/loaded/upload_ai(atom/to_what, mob/living/user) + . = ..() + if (!.) + return + visible_message(span_warning("The expended card incinerates itself.")) + do_sparks(3, cardinal_only = FALSE, source = src) + new /obj/effect/decal/cleanable/ash(get_turf(src)) + qdel(src) + +/// Upgrade disk used to increase the range of a syndicate AI +/obj/item/computer_disk/syndie_ai_upgrade + name = "AI interaction range upgrade" + desc = "A NT data chip containing information that a syndiCard AI can utilize to improve its wireless interfacing abilities. Simply slap it on top of an intelliCard, MODsuit, or AI core and watch it do its work! It's rumoured that there's something 'pretty awful' in it." + icon = 'icons/obj/antags/syndicate_tools.dmi' + icon_state = "something_awful" + max_capacity = 1000 + w_class = WEIGHT_CLASS_NORMAL + +/obj/item/computer_disk/syndie_ai_upgrade/pre_attack(atom/A, mob/living/user, params) + var/mob/living/silicon/ai/AI + if(isAI(A)) + AI = A + else + AI = locate() in A + if(!AI || AI.interaction_range == INFINITY) + playsound(src,'sound/machines/buzz-sigh.ogg',50,FALSE) + to_chat(user, span_notice("Error! Incompatible object!")) + return ..() + AI.interaction_range += 2 + if(AI.interaction_range > 7) + AI.interaction_range = INFINITY + playsound(src,'sound/machines/twobeep.ogg',50,FALSE) + to_chat(user, span_notice("You insert [src] into [AI]'s compartment, and it beeps as it processes the data.")) + to_chat(AI, span_notice("You process [src], and find yourself able to manipulate electronics from up to [AI.interaction_range] meters!")) + qdel(src) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index ecf94d58f70..d3d280cd743 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -44,6 +44,13 @@ if(toggle_context) RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/flashlight_eyes) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/flashlight/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) // single use lights can be toggled on once if(isnull(held_item) && (toggle_context || !on)) diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index 17f5e7d4902..08dee828011 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -127,12 +127,6 @@ if(distance < rangewarning) //ai cant see us but is close detect_state = PROXIMITY_NEAR -/mob/camera/ai_eye/remote/ai_detector - name = "AI detector eye" - ai_detector_visible = FALSE - visible_icon = FALSE - use_static = FALSE - /datum/action/item_action/toggle_multitool name = "Toggle AI detecting mode" check_flags = NONE diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 1065d16d1ca..edd058bedd2 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -112,6 +112,13 @@ AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES) + // No subtypes + if(type != /obj/item/radio) + return + AddComponent(/datum/component/slapcrafting,\ + slapcraft_recipes = list(/datum/crafting_recipe/improv_explosive)\ + ) + /obj/item/radio/Destroy() remove_radio_all(src) //Just to be sure QDEL_NULL(wires) diff --git a/code/game/objects/items/devices/scanners/gas_analyzer.dm b/code/game/objects/items/devices/scanners/gas_analyzer.dm index 727d38c245c..36819d8502a 100644 --- a/code/game/objects/items/devices/scanners/gas_analyzer.dm +++ b/code/game/objects/items/devices/scanners/gas_analyzer.dm @@ -26,6 +26,15 @@ . = ..() RegisterSignal(src, COMSIG_TOOL_ATOM_ACTED_PRIMARY(tool_behaviour), PROC_REF(on_analyze)) + if(type != /obj/item/analyzer) + return + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/material_sniffer) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/analyzer/equipped(mob/user, slot, initial) . = ..() ADD_TRAIT(user, TRAIT_DETECT_STORM, CLOTHING_TRAIT) diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm index 69193b7df92..8947e83d363 100644 --- a/code/game/objects/items/extinguisher.dm +++ b/code/game/objects/items/extinguisher.dm @@ -43,6 +43,15 @@ /// Icon state when inside a tank holder. var/tank_holder_icon_state = "holder_extinguisher" +/obj/item/extinguisher/Initialize(mapload) + . = ..() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/ghettojetpack) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/extinguisher/empty starting_water = FALSE diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm index 035af619513..eb94626c86e 100644 --- a/code/game/objects/items/flamethrower.dm +++ b/code/game/objects/items/flamethrower.dm @@ -34,6 +34,12 @@ /obj/item/flamethrower/Initialize(mapload) . = ..() AddElement(/datum/element/update_icon_updates_onmob) + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/flamethrower) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) /obj/item/flamethrower/Destroy() if(weldtool) diff --git a/code/game/objects/items/food/burgers.dm b/code/game/objects/items/food/burgers.dm index 191cc0eaf25..b2d779ca3a5 100644 --- a/code/game/objects/items/food/burgers.dm +++ b/code/game/objects/items/food/burgers.dm @@ -688,3 +688,4 @@ tastes = list("juicy meat" = 4, "BBQ sauce" = 3, "onions" = 2, "bun" = 2) foodtypes = GRAIN | MEAT | VEGETABLES venue_value = FOOD_PRICE_NORMAL + crafting_complexity = FOOD_COMPLEXITY_3 diff --git a/code/game/objects/items/food/cake.dm b/code/game/objects/items/food/cake.dm index 5d33c332ff6..07d5818b466 100644 --- a/code/game/objects/items/food/cake.dm +++ b/code/game/objects/items/food/cake.dm @@ -690,6 +690,7 @@ tastes = list("cake" = 2, "cream" = 3, "pineapple" = 4) foodtypes = GRAIN | DAIRY | SUGAR | FRUIT | PINEAPPLE slice_type = /obj/item/food/cakeslice/pineapple_cream_cake + crafting_complexity = FOOD_COMPLEXITY_3 /obj/item/food/cakeslice/pineapple_cream_cake name = "pineapple cream cake slice" @@ -702,3 +703,4 @@ ) tastes = list("cake" = 2, "cream" = 3, "pineapple" = 4) foodtypes = GRAIN | DAIRY | SUGAR | FRUIT | PINEAPPLE + crafting_complexity = FOOD_COMPLEXITY_3 diff --git a/code/game/objects/items/food/meatdish.dm b/code/game/objects/items/food/meatdish.dm index 07cd70ea013..2d376148045 100644 --- a/code/game/objects/items/food/meatdish.dm +++ b/code/game/objects/items/food/meatdish.dm @@ -1017,6 +1017,7 @@ ) tastes = list("meat" = 5, "savory sauce" = 4, "tangy pineapple" = 3, "pepper" = 2) foodtypes = MEAT | VEGETABLES | FRUIT | PINEAPPLE + crafting_complexity = FOOD_COMPLEXITY_3 /obj/item/food/kebab/pineapple_skewer name = "pineapple skewer" @@ -1029,6 +1030,7 @@ ) tastes = list("juicy meat" = 4, "pineapple" = 3) foodtypes = MEAT | FRUIT | PINEAPPLE + crafting_complexity = FOOD_COMPLEXITY_3 /obj/item/food/futomaki_sushi_roll name = "futomaki sushi roll" @@ -1042,6 +1044,7 @@ tastes = list("boiled rice" = 4, "fish" = 5, "egg" = 3, "dried seaweed" = 2, "cucumber" = 2) foodtypes = VEGETABLES | SEAFOOD w_class = WEIGHT_CLASS_SMALL + crafting_complexity = FOOD_COMPLEXITY_3 /obj/item/food/futomaki_sushi_roll/make_processable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/futomaki_sushi_slice, 4, screentip_verb = "Chop") @@ -1058,6 +1061,7 @@ tastes = list("boiled rice" = 4, "fish" = 5, "egg" = 3, "dried seaweed" = 2, "cucumber" = 2) foodtypes = VEGETABLES | SEAFOOD w_class = WEIGHT_CLASS_SMALL + crafting_complexity = FOOD_COMPLEXITY_3 /obj/item/food/philadelphia_sushi_roll name = "Philadelphia sushi roll" @@ -1071,6 +1075,7 @@ tastes = list("boiled rice" = 4, "fish" = 5, "creamy cheese" = 3, "dried seaweed" = 2, "cucumber" = 2) foodtypes = VEGETABLES | SEAFOOD | DAIRY w_class = WEIGHT_CLASS_SMALL + crafting_complexity = FOOD_COMPLEXITY_3 /obj/item/food/philadelphia_sushi_roll/make_processable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/philadelphia_sushi_slice, 4, screentip_verb = "Chop") @@ -1087,3 +1092,4 @@ tastes = list("boiled rice" = 4, "fish" = 5, "creamy cheese" = 3, "dried seaweed" = 2, "cucumber" = 2) foodtypes = VEGETABLES | SEAFOOD | DAIRY w_class = WEIGHT_CLASS_SMALL + crafting_complexity = FOOD_COMPLEXITY_3 diff --git a/code/game/objects/items/food/mexican.dm b/code/game/objects/items/food/mexican.dm index 58c50ba5863..b4e32587bc6 100644 --- a/code/game/objects/items/food/mexican.dm +++ b/code/game/objects/items/food/mexican.dm @@ -336,3 +336,4 @@ tastes = list("pineapple" = 4, "tomato" = 3, "onion" = 2, "chili" = 2) foodtypes = VEGETABLES | FRUIT | PINEAPPLE w_class = WEIGHT_CLASS_SMALL + crafting_complexity = FOOD_COMPLEXITY_3 diff --git a/code/game/objects/items/food/misc.dm b/code/game/objects/items/food/misc.dm index 67e74496260..ba72e93a8b0 100644 --- a/code/game/objects/items/food/misc.dm +++ b/code/game/objects/items/food/misc.dm @@ -550,6 +550,7 @@ tastes = list("cooked eggplant" = 5, "cheese" = 4, "ground meat" = 3, "veggies" = 2) foodtypes = VEGETABLES | MEAT | DAIRY w_class = WEIGHT_CLASS_SMALL + crafting_complexity = FOOD_COMPLEXITY_3 /obj/item/food/moussaka name = "moussaka" @@ -562,6 +563,7 @@ ) tastes = list("cooked eggplant" = 5, "potato" = 1, "baked veggies" = 2, "meat" = 4, "bechamel sauce" = 3) foodtypes = MEAT | DAIRY | VEGETABLES + crafting_complexity = FOOD_COMPLEXITY_4 /obj/item/food/moussaka/make_processable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/moussaka_slice, 4, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut") @@ -577,6 +579,7 @@ ) tastes = list("cooked eggplant" = 5, "potato" = 1, "baked veggies" = 2, "meat" = 4, "bechamel sauce" = 3) foodtypes = MEAT | DAIRY | VEGETABLES + crafting_complexity = FOOD_COMPLEXITY_4 /obj/item/food/candied_pineapple name = "candied pineapple" @@ -591,6 +594,7 @@ foodtypes = FRUIT | SUGAR food_flags = FOOD_FINGER_FOOD w_class = WEIGHT_CLASS_TINY + crafting_complexity = FOOD_COMPLEXITY_1 /obj/item/food/candied_pineapple/Initialize(mapload) . = ..() @@ -608,6 +612,7 @@ tastes = list("dough" = 2) foodtypes = GRAIN w_class = WEIGHT_CLASS_TINY + crafting_complexity = FOOD_COMPLEXITY_1 /obj/item/food/raw_pita_bread/make_grillable() AddComponent(/datum/component/grillable, /obj/item/food/pita_bread, rand(15 SECONDS, 30 SECONDS), TRUE, TRUE) @@ -627,6 +632,7 @@ tastes = list("pita bread" = 2) foodtypes = GRAIN w_class = WEIGHT_CLASS_TINY + crafting_complexity = FOOD_COMPLEXITY_2 /obj/item/food/tzatziki_sauce name = "tzatziki sauce" @@ -639,6 +645,7 @@ tastes = list("garlic" = 4, "cucumber" = 2, "olive oil" = 2) foodtypes = VEGETABLES w_class = WEIGHT_CLASS_TINY + crafting_complexity = FOOD_COMPLEXITY_2 /obj/item/food/tzatziki_and_pita_bread name = "tzatziki and pita bread" @@ -651,6 +658,7 @@ tastes = list("pita bread" = 4, "tzatziki sauce" = 2, "olive oil" = 2) foodtypes = VEGETABLES | GRAIN w_class = WEIGHT_CLASS_TINY + crafting_complexity = FOOD_COMPLEXITY_3 /obj/item/food/grilled_beef_gyro name = "grilled beef gyro" @@ -664,6 +672,7 @@ tastes = list("pita bread" = 4, "tender meat" = 2, "tzatziki sauce" = 2, "mixed veggies" = 2) foodtypes = VEGETABLES | GRAIN | MEAT w_class = WEIGHT_CLASS_TINY + crafting_complexity = FOOD_COMPLEXITY_4 /obj/item/food/vegetarian_gyro name = "vegetarian gyro" @@ -676,3 +685,4 @@ tastes = list("pita bread" = 4, "cucumber" = 2, "tzatziki sauce" = 2, "mixed veggies" = 2) foodtypes = VEGETABLES | GRAIN w_class = WEIGHT_CLASS_TINY + crafting_complexity = FOOD_COMPLEXITY_4 diff --git a/code/game/objects/items/food/pastries.dm b/code/game/objects/items/food/pastries.dm index 46da05dea14..8a39f6df8d1 100644 --- a/code/game/objects/items/food/pastries.dm +++ b/code/game/objects/items/food/pastries.dm @@ -540,6 +540,7 @@ foodtypes = GRAIN | SUGAR | DAIRY food_flags = FOOD_FINGER_FOOD w_class = WEIGHT_CLASS_SMALL + crafting_complexity = FOOD_COMPLEXITY_3 /obj/item/food/cookie/snickerdoodle name = "snickerdoodle" @@ -550,6 +551,7 @@ foodtypes = GRAIN | SUGAR | DAIRY food_flags = FOOD_FINGER_FOOD w_class = WEIGHT_CLASS_SMALL + crafting_complexity = FOOD_COMPLEXITY_3 /obj/item/food/cookie/macaron name = "macaron" @@ -561,6 +563,7 @@ foodtypes = GRAIN | SUGAR | DAIRY food_flags = FOOD_FINGER_FOOD w_class = WEIGHT_CLASS_TINY + crafting_complexity = FOOD_COMPLEXITY_3 /obj/item/food/cookie/macaron/Initialize(mapload) . = ..() @@ -575,3 +578,4 @@ foodtypes = GRAIN | SUGAR | FRUIT food_flags = FOOD_FINGER_FOOD w_class = WEIGHT_CLASS_SMALL + crafting_complexity = FOOD_COMPLEXITY_3 diff --git a/code/game/objects/items/food/sandwichtoast.dm b/code/game/objects/items/food/sandwichtoast.dm index 8d6e8c8d147..fec714ad850 100644 --- a/code/game/objects/items/food/sandwichtoast.dm +++ b/code/game/objects/items/food/sandwichtoast.dm @@ -259,23 +259,45 @@ . = ..() obj_flags &= ~UNIQUE_RENAME // You shouldn't be able to disguise this on account of how it kills you -///Override for checkliked callback +// Makes you feel disgusted if you look at it wrong. +/obj/item/food/sandwich/death/examine(mob/user) + . = ..() + // Only human mobs, not animals or silicons, can like/dislike by this. + if(!ishuman(user)) + return + if(check_liked(user) == FOOD_LIKED) + return + to_chat(user, span_warning("You imagine yourself eating [src]. You feel a sudden sour taste in your mouth, and a horrible feeling that you've done something wrong.")) + user.adjust_disgust(33) + +// Override for after_eat and check_liked callbacks. /obj/item/food/sandwich/death/make_edible() . = ..() - AddComponent(/datum/component/edible, check_liked = CALLBACK(src, PROC_REF(check_liked))) + AddComponent(/datum/component/edible, after_eat = CALLBACK(src, PROC_REF(after_eat)), check_liked = CALLBACK(src, PROC_REF(check_liked))) /** * Callback to be used with the edible component. -* If you eat the sandwich with the right clothes and hairstyle, you like it. -* If you don't, you contract a deadly disease. +* If you have the right clothes and hairstyle, you like it. +* If you don't, you don't like it. */ /obj/item/food/sandwich/death/proc/check_liked(mob/living/carbon/human/consumer) - /// Closest thing to a mullet we have + // Closest thing to a mullet we have if(consumer.hairstyle == "Gelled Back" && istype(consumer.get_item_by_slot(ITEM_SLOT_ICLOTHING), /obj/item/clothing/under/rank/civilian/cookjorts)) return FOOD_LIKED + return FOOD_DISLIKED + +/** +* Callback to be used with the edible component. +* If you take a bite of the sandwich with the right clothes and hairstyle, you like it. +* If you don't, you contract a deadly disease. +*/ +/obj/item/food/sandwich/death/proc/after_eat(mob/living/carbon/human/consumer) + // If you like it, you're eating it right. + if(check_liked(consumer) == FOOD_LIKED) + return // I thought it didn't make sense for it to instantly kill you, so instead enjoy shitloads of toxin damage per bite. balloon_alert(consumer, "ate it wrong!") - consumer.ForceContractDisease(new/datum/disease/death_sandwich_poisoning()) + consumer.ForceContractDisease(new /datum/disease/death_sandwich_poisoning()) /obj/item/food/sandwich/death/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] starts to shove [src] down [user.p_their()] throat the wrong way. It looks like [user.p_theyre()] trying to commit suicide!")) diff --git a/code/game/objects/items/food/spaghetti.dm b/code/game/objects/items/food/spaghetti.dm index a631cfe5e05..cab4a62a29f 100644 --- a/code/game/objects/items/food/spaghetti.dm +++ b/code/game/objects/items/food/spaghetti.dm @@ -178,6 +178,7 @@ ) tastes = list("noodles" = 5, "meat" = 3, "egg" = 4, "dried seaweed" = 2) foodtypes = GRAIN | MEAT | VEGETABLES + crafting_complexity = FOOD_COMPLEXITY_4 /obj/item/food/spaghetti/kitakata_ramen name = "kitakata ramen" @@ -191,6 +192,7 @@ ) tastes = list("noodles" = 5, "meat" = 4, "mushrooms" = 3, "onion" = 2) foodtypes = GRAIN | MEAT | VEGETABLES + crafting_complexity = FOOD_COMPLEXITY_4 /obj/item/food/spaghetti/kitsune_udon name = "kitsune udon" @@ -204,6 +206,7 @@ ) tastes = list("noodles" = 5, "tofu" = 4, "sugar" = 3, "soy sauce" = 2) foodtypes = GRAIN | VEGETABLES + crafting_complexity = FOOD_COMPLEXITY_4 /obj/item/food/spaghetti/nikujaga name = "nikujaga" @@ -217,6 +220,7 @@ ) tastes = list("noodles" = 5, "meat" = 4, "potato" = 3, "onion" = 2, "mixed veggies" = 2) foodtypes = GRAIN | VEGETABLES | MEAT + crafting_complexity = FOOD_COMPLEXITY_4 /obj/item/food/spaghetti/pho name = "pho" @@ -230,6 +234,7 @@ ) tastes = list("noodles" = 5, "meat" = 4, "cabbage" = 3, "onion" = 2, "herbs" = 2) foodtypes = GRAIN | VEGETABLES | MEAT + crafting_complexity = FOOD_COMPLEXITY_4 /obj/item/food/spaghetti/pad_thai name = "pad thai" @@ -243,3 +248,4 @@ ) tastes = list("noodles" = 5, "fried tofu" = 4, "lime" = 2, "peanut" = 3, "onion" = 2) foodtypes = GRAIN | VEGETABLES | NUTS | FRUIT + crafting_complexity = FOOD_COMPLEXITY_4 diff --git a/code/game/objects/items/food/vegetables.dm b/code/game/objects/items/food/vegetables.dm index 7da97abc484..dd3ae8c450b 100644 --- a/code/game/objects/items/food/vegetables.dm +++ b/code/game/objects/items/food/vegetables.dm @@ -175,6 +175,7 @@ tastes = list("fried eggplant" = 4, "garlic" = 2, "olive oil" = 3) foodtypes = VEGETABLES w_class = WEIGHT_CLASS_SMALL + crafting_complexity = FOOD_COMPLEXITY_2 /obj/item/food/baba_ghanoush name = "baba ghanoush" @@ -188,6 +189,7 @@ tastes = list("mashed eggplant" = 5, "pita bread" = 4, "garlic" = 3, "olive oil" = 4, "lemon juice" = 2) foodtypes = VEGETABLES | GRAIN w_class = WEIGHT_CLASS_SMALL + crafting_complexity = FOOD_COMPLEXITY_2 /obj/item/food/falafel name = "falafel" @@ -200,3 +202,4 @@ tastes = list("fava beans" = 5, "garlic" = 3, "onion" = 2, "fresh herbs" = 4) foodtypes = VEGETABLES w_class = WEIGHT_CLASS_SMALL + crafting_complexity = FOOD_COMPLEXITY_3 diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index df18b540453..daee6043682 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -175,10 +175,6 @@ . = ..() var/static/list/hovering_item_typechecks = list( - /obj/item/stack/rods = list( - SCREENTIP_CONTEXT_LMB = "Craft wired rod", - ), - /obj/item/stack/sheet/iron = list( SCREENTIP_CONTEXT_LMB = "Craft bola", ), @@ -190,6 +186,13 @@ if(new_color) set_cable_color(new_color) + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/bola, /datum/crafting_recipe/gonbola) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/restraints/handcuffs/cable/proc/set_cable_color(new_color) color = GLOB.cable_colors[new_color] cable_color = new_color @@ -289,36 +292,6 @@ cable_color = CABLE_COLOR_WHITE inhand_icon_state = "coil_white" -/obj/item/restraints/handcuffs/cable/attackby(obj/item/I, mob/user, params) //Slapcrafting - if(istype(I, /obj/item/stack/rods)) - var/obj/item/stack/rods/R = I - if (R.use(1)) - var/obj/item/wirerod/W = new /obj/item/wirerod - remove_item_from_storage(user) - user.put_in_hands(W) - to_chat(user, span_notice("You wrap [src] around the top of [I].")) - qdel(src) - else - to_chat(user, span_warning("You need one rod to make a wired rod!")) - return - else if(istype(I, /obj/item/stack/sheet/iron)) - var/obj/item/stack/sheet/iron/M = I - if(M.get_amount() < 6) - to_chat(user, span_warning("You need at least six iron sheets to make good enough weights!")) - return - to_chat(user, span_notice("You begin to apply [I] to [src]...")) - if(do_after(user, 35, target = src)) - if(M.get_amount() < 6 || !M) - return - var/obj/item/restraints/legcuffs/bola/S = new /obj/item/restraints/legcuffs/bola - M.use(6) - user.put_in_hands(S) - to_chat(user, span_notice("You make some weights out of [I] and tie them to [src].")) - remove_item_from_storage(user) - qdel(src) - else - return ..() - /** * # Zipties * diff --git a/code/game/objects/items/implants/implant_freedom.dm b/code/game/objects/items/implants/implant_freedom.dm index d010b57e506..1fa61c27510 100644 --- a/code/game/objects/items/implants/implant_freedom.dm +++ b/code/game/objects/items/implants/implant_freedom.dm @@ -3,37 +3,45 @@ desc = "Use this to escape from those evil Red Shirts." icon_state = "freedom" implant_color = "r" - uses = 4 + uses = FREEDOM_IMPLANT_CHARGES +/obj/item/implant/freedom/implant(mob/living/target, mob/user, silent, force) + . = ..() + if(!.) + return FALSE + if(!iscarbon(target)) //This is pretty much useless for anyone else since they can't be cuffed + balloon_alert(user, "that would be a waste!") + return FALSE + return TRUE /obj/item/implant/freedom/activate() . = ..() + var/mob/living/carbon/carbon_imp_in = imp_in + if(!carbon_imp_in.handcuffed && !carbon_imp_in.legcuffed) + balloon_alert(carbon_imp_in, "no restraints!") + return + uses-- - to_chat(imp_in, span_hear("You feel a faint click.")) - if(iscarbon(imp_in)) - var/mob/living/carbon/C_imp_in = imp_in - C_imp_in.uncuff() + + carbon_imp_in.uncuff() if(!uses) + addtimer(CALLBACK(carbon_imp_in, TYPE_PROC_REF(/atom, balloon_alert), carbon_imp_in, "implant degraded!"), 1 SECONDS) qdel(src) - /obj/item/implant/freedom/get_data() var/dat = {" -Implant Specifications:
-Name: Freedom Beacon
-Life: optimum 5 uses
-Important Notes: Illegal
-
-Implant Details:
-Function: Transmits a specialized cluster of signals to override handcuff locking -mechanisms
-Special Features:
-Neuro-Scan- Analyzes certain shadow signals in the nervous system
-
-No Implant Specifics"} + Implant Specifications:
+ Name: Freedom Beacon
+ Life: Optimum [initial(uses)] uses
+ Important Notes: Illegal
+
+ Implant Details:
+ Function: Transmits a specialized cluster of signals to override handcuff locking + mechanisms. These signals will release any bindings on both the arms and legs.
+ Disclaimer: Heavy-duty restraints such as straightjackets are deemed "too complex" to release from. + "} return dat - /obj/item/implanter/freedom name = "implanter" // Skyrat edit , was implanter (freedom) imp_type = /obj/item/implant/freedom diff --git a/code/game/objects/items/mail.dm b/code/game/objects/items/mail.dm index b377fdde172..d058f96a40c 100644 --- a/code/game/objects/items/mail.dm +++ b/code/game/objects/items/mail.dm @@ -452,9 +452,10 @@ var/list/mail_recipients_for_input = list("Anyone") var/list/used_names = list() for(var/datum/record/locked/person in sort_record(GLOB.manifest.locked)) - if(isnull(person.mind_ref)) + var/datum/mind/locked_mind = person.mind_ref.resolve() + if(isnull(locked_mind)) continue - mail_recipients += person.mind_ref + mail_recipients += locked_mind mail_recipients_for_input += avoid_assoc_duplicate_keys(person.name, used_names) var/recipient = tgui_input_list(user, "Choose a recipient", "Mail Counterfeiting", mail_recipients_for_input) diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index d41397301b3..27418a5e0a9 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -111,6 +111,15 @@ shield_break_sound = 'sound/effects/glassbr3.ogg' shield_break_leftover = /obj/item/shard +/obj/item/shield/riot/Initialize(mapload) + . = ..() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/strobeshield) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/shield/riot/attackby(obj/item/attackby_item, mob/user, params) if(istype(attackby_item, /obj/item/melee/baton)) if(!COOLDOWN_FINISHED(src, baton_bash)) diff --git a/code/game/objects/items/spear.dm b/code/game/objects/items/spear.dm index 1d9c90217ac..d9f13911731 100644 --- a/code/game/objects/items/spear.dm +++ b/code/game/objects/items/spear.dm @@ -54,8 +54,18 @@ force_wielded = force_wielded, \ icon_wielded = "[icon_prefix]1", \ ) + add_headpike_component() update_appearance() +// I dunno man +/obj/item/spear/proc/add_headpike_component() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/headpike) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/spear/update_icon_state() icon_state = "[icon_prefix]0" return ..() @@ -227,6 +237,14 @@ reach = 2 //SKYRAT EDIT ADDITION END +/obj/item/spear/bonespear/add_headpike_component() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/headpikebone) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /* * Bamboo Spear */ @@ -241,3 +259,12 @@ custom_materials = list(/datum/material/bamboo = SHEET_MATERIAL_AMOUNT * 20) force_unwielded = 10 force_wielded = 18 + + +/obj/item/spear/bamboospear/add_headpike_component() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/headpikebamboo) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index 60db8f800a2..b5540a633f1 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -55,6 +55,13 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \ ) AddElement(/datum/element/contextual_screentip_tools, tool_behaviors) + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/spear, /datum/crafting_recipe/stunprod, /datum/crafting_recipe/teleprod) // snatcher prod isn't here as a spoopy secret + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/stack/rods/handle_openspace_click(turf/target, mob/user, proximity_flag, click_parameters) if(proximity_flag) target.attackby(src, user, click_parameters) diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 289920c8889..381cdd7a296 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -501,6 +501,15 @@ GLOBAL_LIST_INIT(durathread_recipes, list ( \ drop_sound = 'sound/items/handling/cloth_drop.ogg' pickup_sound = 'sound/items/handling/cloth_pickup.ogg' +/obj/item/stack/sheet/durathread/Initialize(mapload) + . = ..() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/durathread_helmet, /datum/crafting_recipe/durathread_vest) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/stack/sheet/durathread/get_main_recipes() . = ..() . += GLOB.durathread_recipes @@ -620,6 +629,15 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \ grind_results = list(/datum/reagent/cellulose = 10) material_type = /datum/material/cardboard +/obj/item/stack/sheet/cardboard/Initialize(mapload, new_amount, merge, list/mat_override, mat_amt) + . = ..() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/cardboard_id) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/stack/sheet/cardboard/get_main_recipes() . = ..() . += GLOB.cardboard_recipes diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index c9c4815e3da..c0d2d42bb87 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -49,6 +49,12 @@ resistance_flags = FIRE_PROOF item_flags = NO_MAT_REDEMPTION +/obj/item/bag_of_holding_inert/Initialize(mapload) + . = ..() + AddComponent(/datum/component/slapcrafting,\ + slapcraft_recipes = list(/datum/crafting_recipe/boh)\ + ) + /obj/item/storage/backpack/holding name = "bag of holding" desc = "A backpack that opens into a localized pocket of bluespace." @@ -509,46 +515,12 @@ icon_state = "duffel-medical" inhand_icon_state = "duffel-med" -/obj/item/storage/backpack/duffelbag/med/surgery - name = "surgical duffel bag" - desc = "A large duffel bag for holding extra medical supplies - this one seems to be designed for holding surgical tools." - -/obj/item/storage/backpack/duffelbag/med/surgery/PopulateContents() - new /obj/item/scalpel(src) - new /obj/item/hemostat(src) - new /obj/item/retractor(src) - new /obj/item/circular_saw(src) - new /obj/item/surgicaldrill(src) - new /obj/item/cautery(src) - new /obj/item/bonesetter(src) - new /obj/item/surgical_drapes(src) - new /obj/item/clothing/suit/toggle/labcoat/skyrat/hospitalgown(src) //SKYRAT EDIT ADDITION - new /obj/item/clothing/mask/surgical(src) - new /obj/item/razor(src) - new /obj/item/blood_filter(src) - /obj/item/storage/backpack/duffelbag/coroner name = "coroner duffel bag" desc = "A large duffel bag for holding large amounts of organs at once." icon_state = "duffel-coroner" inhand_icon_state = "duffel-coroner" -/obj/item/storage/backpack/duffelbag/coroner/surgery - name = "surgical coroner bag" - desc = "A large duffel bag for holding extra medical supplies - this one seems to be designed for holding morbid surgical tools." - -/obj/item/storage/backpack/duffelbag/coroner/surgery/PopulateContents() - new /obj/item/scalpel/cruel(src) - new /obj/item/hemostat/cruel(src) - new /obj/item/retractor/cruel(src) - new /obj/item/circular_saw(src) - new /obj/item/surgicaldrill(src) - new /obj/item/cautery/cruel(src) - new /obj/item/bonesetter(src) - new /obj/item/surgical_drapes(src) - new /obj/item/razor(src) - new /obj/item/blood_filter(src) - /obj/item/storage/backpack/duffelbag/explorer name = "explorer duffel bag" desc = "A large duffel bag for holding extra exotic treasures." diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm index ba9c6ef4812..9fa66404aed 100644 --- a/code/game/objects/items/storage/uplink_kits.dm +++ b/code/game/objects/items/storage/uplink_kits.dm @@ -747,13 +747,13 @@ human_target.reagents.add_reagent(/datum/reagent/toxin, 2) return FALSE - /// If no antag datums which allow induction are there, disallow induction! No self-antagging. - var/allowed = FALSE + /// If all the antag datums are 'fake', disallow induction! No self-antagging. + var/faker for(var/datum/antagonist/antag_datum as anything in human_target.mind.antag_datums) - if((antag_datum.antag_flags & FLAG_ANTAG_CAN_BE_INDUCTED)) - allowed = TRUE + if((antag_datum.antag_flags & FLAG_FAKE_ANTAG)) + faker = TRUE - if(!allowed) // GTFO. Technically not foolproof but making a heartbreaker or a paradox clone a nuke op sounds hilarious + if(faker) // GTFO. Technically not foolproof but making a heartbreaker or a paradox clone a nuke op sounds hilarious to_chat(human_target, span_notice("Huh? Nothing happened? But you're starting to feel a little ill...")) human_target.reagents.add_reagent(/datum/reagent/toxin, 15) return FALSE diff --git a/code/game/objects/items/surgery_tray.dm b/code/game/objects/items/surgery_tray.dm index dfe83baabdb..37494a39b55 100644 --- a/code/game/objects/items/surgery_tray.dm +++ b/code/game/objects/items/surgery_tray.dm @@ -11,6 +11,7 @@ /obj/item/cautery, /obj/item/circular_saw, /obj/item/clothing/mask/surgical, + /obj/item/clothing/suit/toggle/labcoat/skyrat/hospitalgown, // SKYRAT EDIT ADDITION /obj/item/hemostat, /obj/item/razor, /obj/item/reagent_containers/medigel, @@ -152,8 +153,10 @@ /obj/item/surgery_tray/attack_hand(mob/living/user) if(!user.can_perform_action(src, NEED_HANDS)) return ..() - var/obj/item/grabbies = pick(contents) - if(grabbies) + if(!length(contents)) + balloon_alert(user, "empty!") + else + var/obj/item/grabbies = pick(contents) atom_storage.remove_single(user, grabbies, drop_location()) user.put_in_hands(grabbies) return TRUE @@ -193,6 +196,7 @@ new /obj/item/cautery(src) new /obj/item/circular_saw(src) new /obj/item/clothing/mask/surgical(src) + new /obj/item/clothing/suit/toggle/labcoat/skyrat/hospitalgown(src) // SKYRAT EDIT ADDITION new /obj/item/hemostat(src) new /obj/item/razor/surgery(src) new /obj/item/retractor(src) @@ -207,13 +211,14 @@ name = "autopsy tray" desc = "A Deforest brand surgery tray, made for use in morgues. It is a folding model, \ meaning the wheels on the bottom can be extended outwards, making it a cart." - + /obj/item/surgery_tray/full/morgue/populate_contents() new /obj/item/blood_filter(src) new /obj/item/bonesetter(src) new /obj/item/cautery/cruel(src) new /obj/item/circular_saw(src) new /obj/item/clothing/mask/surgical(src) + new /obj/item/clothing/suit/toggle/labcoat/skyrat/hospitalgown(src) // SKYRAT EDIT ADDITION new /obj/item/hemostat/cruel(src) new /obj/item/razor/surgery(src) new /obj/item/retractor/cruel(src) @@ -227,13 +232,13 @@ /obj/item/surgery_tray/full/advanced /obj/item/surgery_tray/full/advanced/populate_contents() - new /obj/item/scalpel/advanced - new /obj/item/retractor/advanced - new /obj/item/cautery/advanced - new /obj/item/surgical_drapes - new /obj/item/reagent_containers/medigel/sterilizine - new /obj/item/bonesetter - new /obj/item/blood_filter - new /obj/item/stack/medical/bone_gel - new /obj/item/stack/sticky_tape/surgical - new /obj/item/clothing/mask/surgical + new /obj/item/scalpel/advanced(src) + new /obj/item/retractor/advanced(src) + new /obj/item/cautery/advanced(src) + new /obj/item/surgical_drapes(src) + new /obj/item/reagent_containers/medigel/sterilizine(src) + new /obj/item/bonesetter(src) + new /obj/item/blood_filter(src) + new /obj/item/stack/medical/bone_gel(src) + new /obj/item/stack/sticky_tape/surgical(src) + new /obj/item/clothing/mask/surgical(src) diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 470448ab244..21fc15572bf 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -302,69 +302,6 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/katana/cursed //used by wizard events, see the tendril_loot.dm file for the miner one slot_flags = null -/obj/item/wirerod - name = "wired rod" - desc = "A rod with some wire wrapped around the top. It'd be easy to attach something to the top bit." - icon = 'icons/obj/weapons/spear.dmi' - icon_state = "wiredrod" - inhand_icon_state = "rods" - flags_1 = CONDUCT_1 - force = 9 - throwforce = 10 - w_class = WEIGHT_CLASS_BULKY - custom_materials = list(/datum/material/iron= HALF_SHEET_MATERIAL_AMOUNT + SMALL_MATERIAL_AMOUNT * 1.5, /datum/material/glass= SMALL_MATERIAL_AMOUNT * 0.75) - attack_verb_continuous = list("hits", "bludgeons", "whacks", "bonks") - attack_verb_simple = list("hit", "bludgeon", "whack", "bonk") - -/obj/item/wirerod/Initialize(mapload) - . = ..() - - var/static/list/hovering_item_typechecks = list( - /obj/item/shard = list( - SCREENTIP_CONTEXT_LMB = "Craft spear", - ), - - /obj/item/assembly/igniter = list( - SCREENTIP_CONTEXT_LMB = "Craft stunprod", - ), - ) - - AddElement(/datum/element/contextual_screentip_item_typechecks, hovering_item_typechecks) - -/obj/item/wirerod/attackby(obj/item/attacking_item, mob/user, params) - if(istype(attacking_item, /obj/item/shard)) - var/datum/crafting_recipe/recipe_to_use = /datum/crafting_recipe/spear - user.balloon_alert(user, "crafting spear...") - if(do_after(user, initial(recipe_to_use.time), src)) // we do initial work here to get the correct timer - var/obj/item/spear/crafted_spear = new /obj/item/spear() - - remove_item_from_storage(user) - if (!user.transferItemToLoc(attacking_item, crafted_spear)) - return - crafted_spear.CheckParts(list(attacking_item)) - qdel(src) - - user.put_in_hands(crafted_spear) - user.balloon_alert(user, "crafted spear") - return - - if(isigniter(attacking_item) && !(HAS_TRAIT(attacking_item, TRAIT_NODROP))) - var/datum/crafting_recipe/recipe_to_use = /datum/crafting_recipe/stunprod - user.balloon_alert(user, "crafting cattleprod...") - if(do_after(user, initial(recipe_to_use.time), src)) - var/obj/item/melee/baton/security/cattleprod/prod = new - - remove_item_from_storage(user) - - qdel(attacking_item) - qdel(src) - - user.put_in_hands(prod) - user.balloon_alert(user, "crafted cattleprod") - return - return ..() - - /obj/item/throwing_star name = "throwing star" desc = "An ancient weapon still used to this day, due to its ease of lodging itself into its victim's body parts." diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 524c189acc6..a06b7fdaea7 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -145,7 +145,7 @@ if(has_buckled_mobs()) for(var/m in buckled_mobs) var/mob/living/buckled_mob = m - buckled_mob.electrocute_act((clamp(round(strength/400), 10, 90) + rand(-5, 5)), src, flags = SHOCK_TESLA) + buckled_mob.electrocute_act((clamp(round(strength * 3.125e-6), 10, 90) + rand(-5, 5)), src, flags = SHOCK_TESLA) ///the obj is deconstructed into pieces, whether through careful disassembly or when destroyed. /obj/proc/deconstruct(disassembled = TRUE) diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 71d15fb3f58..ba8623ec4aa 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -63,6 +63,6 @@ /obj/structure/zap_act(power, zap_flags) if(zap_flags & ZAP_OBJ_DAMAGE) - take_damage(power/8000, BURN, "energy") - power -= power/2000 //walls take a lot out of ya + take_damage(power * 1.5625e-7, BURN, "energy") + power -= power * 5e-4 //walls take a lot out of ya . = ..() diff --git a/code/game/objects/structures/icemoon/cave_entrance.dm b/code/game/objects/structures/icemoon/cave_entrance.dm index 10f7a56c7f9..7393c20758e 100644 --- a/code/game/objects/structures/icemoon/cave_entrance.dm +++ b/code/game/objects/structures/icemoon/cave_entrance.dm @@ -102,7 +102,7 @@ GLOBAL_LIST_INIT(ore_probability, list( mob_types = list(/mob/living/basic/mining/ice_whelp) /obj/structure/spawner/ice_moon/demonic_portal/snowlegion - mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/portal) + mob_types = list(/mob/living/basic/mining/legion/snow/spawner_made) /obj/effect/collapsing_demonic_portal name = "collapsing demonic portal" diff --git a/code/game/objects/structures/lavaland/necropolis_tendril.dm b/code/game/objects/structures/lavaland/necropolis_tendril.dm index 542df563a1f..22f7f0422cd 100644 --- a/code/game/objects/structures/lavaland/necropolis_tendril.dm +++ b/code/game/objects/structures/lavaland/necropolis_tendril.dm @@ -23,7 +23,7 @@ mob_types = list(/mob/living/basic/mining/goliath) /obj/structure/spawner/lavaland/legion - mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril) + mob_types = list(/mob/living/basic/mining/legion/spawner_made) /obj/structure/spawner/lavaland/icewatcher mob_types = list(/mob/living/basic/mining/watcher/icewing) diff --git a/code/game/objects/structures/spawner.dm b/code/game/objects/structures/spawner.dm index 7bbafd21ff2..340bcf212de 100644 --- a/code/game/objects/structures/spawner.dm +++ b/code/game/objects/structures/spawner.dm @@ -80,8 +80,8 @@ /mob/living/basic/mining/basilisk, /mob/living/basic/mining/goldgrub, /mob/living/basic/mining/goliath/ancient, + /mob/living/basic/mining/legion, /mob/living/basic/wumborian_fugu, - /mob/living/simple_animal/hostile/asteroid/hivelord, ) faction = list(FACTION_MINING) @@ -98,7 +98,7 @@ /obj/structure/spawner/mining/hivelord name = "hivelord den" desc = "A den housing a nest of hivelords." - mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord) + mob_types = list(/mob/living/basic/mining/hivelord) /obj/structure/spawner/mining/basilisk name = "basilisk den" diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index b991bc0c274..6ba07a90e68 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -591,6 +591,12 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sink/kitchen, (-16)) var/busy = FALSE //Something's being washed at the moment var/dispensedreagent = /datum/reagent/water // for whenever plumbing happens +/obj/structure/water_source/Initialize(mapload) + . = ..() + + create_reagents(INFINITY, NO_REACT) + reagents.add_reagent(dispensedreagent, INFINITY) + /obj/structure/water_source/attack_hand(mob/living/user, list/modifiers) . = ..() if(.) diff --git a/code/game/say.dm b/code/game/say.dm index a531ee02527..c0e9d4ff8ef 100644 --- a/code/game/say.dm +++ b/code/game/say.dm @@ -108,7 +108,7 @@ GLOBAL_LIST_INIT(freqtospan, list( filter += tts_filter.Join(",") if(voice && found_client) - INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), src, html_decode(tts_message_to_use), message_language, voice, filter.Join(","), listened, message_range = range, pitch = pitch, silicon = tts_silicon_voice_effect) + INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), src, html_decode(tts_message_to_use), message_language, voice, filter.Join(","), listened, message_range = range, pitch = pitch) /atom/movable/proc/compose_message(atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, list/message_mods = list(), visible_name = FALSE) //This proc uses [] because it is faster than continually appending strings. Thanks BYOND. diff --git a/code/game/turfs/open/planet.dm b/code/game/turfs/open/planet.dm index 88f9518a08e..e5ab02c0924 100644 --- a/code/game/turfs/open/planet.dm +++ b/code/game/turfs/open/planet.dm @@ -14,6 +14,13 @@ heavyfootstep = FOOTSTEP_GENERIC_HEAVY tiled_dirt = FALSE +/turf/open/misc/dirt/station + name = "dirt flooring" //FOR THE LOVE OF GOD USE THIS INSTEAD OF DIRT FOR STATION MAPS + desc = "You heard this place was dirty, but this is just absurd." + baseturfs = /turf/open/floor/plating + initial_gas_mix = OPENTURF_LOW_PRESSURE + planetary_atmos = FALSE + /turf/open/misc/dirt/dark icon_state = "greenerdirt" base_icon_state = "greenerdirt" diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 0b731c61373..7f135cdbefb 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -117,7 +117,7 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list( /datum/admins/proc/station_traits_panel, // Client procs /client/proc/admin_away, - /client/proc/add_mob_ability, + /client/proc/add_marked_mob_ability, /client/proc/admin_change_sec_level, /client/proc/cinematic, /client/proc/cmd_admin_add_freeform_ai_law, @@ -132,7 +132,7 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list( /client/proc/mass_zombie_infection, /client/proc/object_say, /client/proc/polymorph_all, - /client/proc/remove_mob_ability, + /client/proc/remove_marked_mob_ability, /client/proc/reset_ooc, /client/proc/run_weather, /client/proc/set_dynex_scale, @@ -718,6 +718,80 @@ GLOBAL_PROTECT(admin_verbs_poll) set category = "Debug" SStrading_card_game.printAllCards() +/client/proc/give_mob_action(mob/ability_recipient in GLOB.mob_list) + set category = "Admin.Fun" + set name = "Give Mob Action" + set desc = "Gives a mob ability to a mob." + + var/static/list/all_mob_actions = sort_list(subtypesof(/datum/action/cooldown/mob_cooldown), GLOBAL_PROC_REF(cmp_typepaths_asc)) + var/static/list/actions_by_name = list() + if (!length(actions_by_name)) + for (var/datum/action/cooldown/mob_cooldown as anything in all_mob_actions) + actions_by_name["[initial(mob_cooldown.name)] ([mob_cooldown])"] = mob_cooldown + + var/ability = tgui_input_list(usr, "Choose an ability", "Ability", actions_by_name) + if(isnull(ability)) + return + + var/ability_type = actions_by_name[ability] + var/datum/action/cooldown/mob_cooldown/add_ability + + var/make_sequence = tgui_alert(usr, "Would you like this action to be a sequence of multiple abilities?", "Sequence Ability", list("Yes", "No")) + if(make_sequence == "Yes") + add_ability = new /datum/action/cooldown/mob_cooldown(ability_recipient) + add_ability.sequence_actions = list() + while(!isnull(ability_type)) + var/ability_delay = tgui_input_number(usr, "Enter the delay in seconds before the next ability in the sequence is used", "Ability Delay", 2) + if(isnull(ability_delay) || ability_delay < 0) + ability_delay = 0 + add_ability.sequence_actions[ability_type] = ability_delay * 1 SECONDS + ability = tgui_input_list(usr, "Choose a new sequence ability", "Sequence Ability", actions_by_name) + ability_type = actions_by_name[ability] + var/ability_cooldown = tgui_input_number(usr, "Enter the sequence abilities cooldown in seconds", "Ability Cooldown", 2) + if(isnull(ability_cooldown) || ability_cooldown < 0) + ability_cooldown = 2 + add_ability.cooldown_time = ability_cooldown * 1 SECONDS + var/ability_melee_cooldown = tgui_input_number(usr, "Enter the abilities melee cooldown in seconds", "Melee Cooldown", 2) + if(isnull(ability_melee_cooldown) || ability_melee_cooldown < 0) + ability_melee_cooldown = 2 + add_ability.melee_cooldown_time = ability_melee_cooldown * 1 SECONDS + add_ability.name = tgui_input_text(usr, "Choose ability name", "Ability name", "Generic Ability") + add_ability.create_sequence_actions() + else + add_ability = new ability_type(ability_recipient) + + if(isnull(ability_recipient)) + return + add_ability.Grant(ability_recipient) + + message_admins("[key_name_admin(usr)] added mob ability [ability_type] to mob [ability_recipient].") + log_admin("[key_name(usr)] added mob ability [ability_type] to mob [ability_recipient].") + SSblackbox.record_feedback("tally", "admin_verb", 1, "Add Mob Ability") // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc! + +/client/proc/remove_mob_action(mob/removal_target in GLOB.mob_list) + set category = "Admin.Fun" + set name = "Remove Mob Action" + set desc = "Remove a special ability from the selected mob." + + var/list/target_abilities = list() + for(var/datum/action/cooldown/mob_cooldown/ability in removal_target.actions) + target_abilities[ability.name] = ability + + if(!length(target_abilities)) + return + + var/chosen_ability = tgui_input_list(usr, "Choose the spell to remove from [removal_target]", "Depower", sort_list(target_abilities)) + if(isnull(chosen_ability)) + return + var/datum/action/cooldown/mob_cooldown/to_remove = target_abilities[chosen_ability] + if(!istype(to_remove)) + return + + qdel(to_remove) + log_admin("[key_name(usr)] removed the ability [chosen_ability] from [key_name(removal_target)].") + message_admins("[key_name_admin(usr)] removed the ability [chosen_ability] from [key_name_admin(removal_target)].") + SSblackbox.record_feedback("tally", "admin_verb", 1, "Remove Mob Ability") // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc! + /client/proc/give_spell(mob/spell_recipient in GLOB.mob_list) set category = "Admin.Fun" set name = "Give Spell" @@ -1036,8 +1110,6 @@ GLOBAL_PROTECT(admin_verbs_poll) var/reqs = initial(spell.spell_requirements) if(reqs & SPELL_CASTABLE_AS_BRAIN) real_reqs += "Castable as brain" - if(reqs & SPELL_CASTABLE_WHILE_PHASED) - real_reqs += "Castable phased" if(reqs & SPELL_REQUIRES_HUMAN) real_reqs += "Must be human" if(reqs & SPELL_REQUIRES_MIME_VOW) diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 624af957a84..f412f9d5a72 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -224,7 +224,7 @@ var/color = "#e6e6e6" if(i%2 == 0) color = "#f2f2f2" - var/is_antagonist = is_special_character(M) + var/is_antagonist = is_special_character(M, allow_fake_antags = TRUE) var/M_job = "" diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 7c2d34bd30f..9db6585799f 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1309,16 +1309,16 @@ new /obj/effect/pod_landingzone(target, pod) if (number == 1) - log_admin("[key_name(usr)] created a [english_list(paths)]") + log_admin("[key_name(usr)] created an instance of [english_list(paths)]") for(var/path in paths) if(ispath(path, /mob)) - message_admins("[key_name_admin(usr)] created a [english_list(paths)]") + message_admins("[key_name_admin(usr)] created an instance of [english_list(paths)]") break else - log_admin("[key_name(usr)] created [number]ea [english_list(paths)]") + log_admin("[key_name(usr)] created [number] instances of [english_list(paths)]") for(var/path in paths) if(ispath(path, /mob)) - message_admins("[key_name_admin(usr)] created [number]ea [english_list(paths)]") + message_admins("[key_name_admin(usr)] created [number] instances of [english_list(paths)]") break return diff --git a/code/modules/admin/verbs/adminevents.dm b/code/modules/admin/verbs/adminevents.dm index ca5458bdb1e..dd8f1d96f60 100644 --- a/code/modules/admin/verbs/adminevents.dm +++ b/code/modules/admin/verbs/adminevents.dm @@ -338,9 +338,9 @@ log_admin("[key_name(usr)] started weather of type [weather_type] on the z-level [z_level].") SSblackbox.record_feedback("tally", "admin_verb", 1, "Run Weather") -/client/proc/add_mob_ability() +/client/proc/add_marked_mob_ability() set category = "Admin.Events" - set name = "Add Mob Ability" + set name = "Add Mob Ability (Marked Mob)" set desc = "Adds an ability to a marked mob." if(!holder) @@ -349,56 +349,11 @@ if(!isliving(holder.marked_datum)) to_chat(usr, span_warning("Error: Please mark a mob to add actions to it.")) return + give_mob_action(holder.marked_datum) - var/mob/living/marked_mob = holder.marked_datum - - var/static/list/all_mob_actions = sort_list(subtypesof(/datum/action/cooldown/mob_cooldown), GLOBAL_PROC_REF(cmp_typepaths_asc)) - var/static/list/actions_by_name = list() - if (!length(actions_by_name)) - for (var/datum/action/cooldown/mob_cooldown as anything in all_mob_actions) - actions_by_name["[initial(mob_cooldown.name)] ([mob_cooldown])"] = mob_cooldown - - var/ability = tgui_input_list(usr, "Choose an ability", "Ability", actions_by_name) - if(isnull(ability)) - return - - var/ability_type = actions_by_name[ability] - var/datum/action/cooldown/mob_cooldown/add_ability - - var/make_sequence = tgui_alert(usr, "Would you like this action to be a sequence of multiple abilities?", "Sequence Ability", list("Yes", "No")) - if(make_sequence == "Yes") - add_ability = new /datum/action/cooldown/mob_cooldown(marked_mob) - add_ability.sequence_actions = list() - while(!isnull(ability_type)) - var/ability_delay = tgui_input_number(usr, "Enter the delay in seconds before the next ability in the sequence is used", "Ability Delay", 2) - if(isnull(ability_delay) || ability_delay < 0) - ability_delay = 0 - add_ability.sequence_actions[ability_type] = ability_delay * 1 SECONDS - ability_type = tgui_input_list(usr, "Choose a new sequence ability", "Sequence Ability", all_mob_actions) - var/ability_cooldown = tgui_input_number(usr, "Enter the sequence abilities cooldown in seconds", "Ability Cooldown", 2) - if(isnull(ability_cooldown) || ability_cooldown < 0) - ability_cooldown = 2 - add_ability.cooldown_time = ability_cooldown * 1 SECONDS - var/ability_melee_cooldown = tgui_input_number(usr, "Enter the abilities melee cooldown in seconds", "Melee Cooldown", 2) - if(isnull(ability_melee_cooldown) || ability_melee_cooldown < 0) - ability_melee_cooldown = 2 - add_ability.melee_cooldown_time = ability_melee_cooldown * 1 SECONDS - add_ability.name = tgui_input_text(usr, "Choose ability name", "Ability name", "Generic Ability") - add_ability.create_sequence_actions() - else - add_ability = new ability_type(marked_mob) - - if(isnull(marked_mob)) - return - add_ability.Grant(marked_mob) - - message_admins("[key_name_admin(usr)] added mob ability [ability_type] to mob [marked_mob].") - log_admin("[key_name(usr)] added mob ability [ability_type] to mob [marked_mob].") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Add Mob Ability") // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc! - -/client/proc/remove_mob_ability() +/client/proc/remove_marked_mob_ability() set category = "Admin.Events" - set name = "Remove Mob Ability" + set name = "Remove Mob Ability (Marked Mob)" set desc = "Removes an ability from marked mob." if(!holder) @@ -407,24 +362,7 @@ if(!isliving(holder.marked_datum)) to_chat(usr, span_warning("Error: Please mark a mob to remove actions from it.")) return - - var/mob/living/marked_mob = holder.marked_datum - - var/list/all_mob_actions = list() - for(var/datum/action/cooldown/mob_cooldown/ability in marked_mob.actions) - all_mob_actions.Add(ability) - - var/datum/action/cooldown/mob_cooldown/ability = tgui_input_list(usr, "Remove an ability", "Ability", all_mob_actions) - - if(!ability) - return - - var/ability_name = ability.name - QDEL_NULL(ability) - - message_admins("[key_name_admin(usr)] removed ability [ability_name] from mob [marked_mob].") - log_admin("[key_name(usr)] removed mob ability [ability_name] from mob [marked_mob].") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Remove Mob Ability") // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc! + remove_mob_action(holder.marked_datum) /client/proc/command_report_footnote() diff --git a/code/modules/admin/verbs/admingame.dm b/code/modules/admin/verbs/admingame.dm index 8bc58a7876c..317c8fafd3b 100644 --- a/code/modules/admin/verbs/admingame.dm +++ b/code/modules/admin/verbs/admingame.dm @@ -233,7 +233,7 @@ Traitors and the like can also be revived with the previous role mostly intact. new_character.real_name = record_found.name new_character.gender = lowertext(record_found.gender) new_character.age = record_found.age - var/datum/dna/found_dna = record_found.dna_ref + var/datum/dna/found_dna = record_found.locked_dna new_character.hardset_dna(found_dna.unique_identity, found_dna.mutation_index, null, record_found.name, record_found.blood_type, new record_found.species_type, found_dna.features) else new_character.randomize_human_appearance() diff --git a/code/modules/admin/verbs/grant_dna_infusion.dm b/code/modules/admin/verbs/grant_dna_infusion.dm new file mode 100644 index 00000000000..06cfa8110d6 --- /dev/null +++ b/code/modules/admin/verbs/grant_dna_infusion.dm @@ -0,0 +1,36 @@ +/* + * Attempts to grant the target all organs from a given DNA infuser entry.area + * Returns the entry if all organs were successfully replaced. + * If no infusion was picked, the infusion had no organs, or if one or more organs could not be granted, returns FALSE +*/ +/client/proc/grant_dna_infusion(mob/living/carbon/human/target in world) + set name = "Apply DNA Infusion" + set category = "Debug" + + var/list/infusions = list() + for(var/datum/infuser_entry/path as anything in subtypesof(/datum/infuser_entry)) + var/str = "[initial(path.name)] ([path])" + infusions[str] = path + + var/datum/infuser_entry/picked_infusion = tgui_input_list(usr, "Select infusion", "Apply DNA Infusion", infusions) + + if(isnull(picked_infusion)) + return FALSE + + // This is necessary because list propererties are not defined until initialization + picked_infusion = infusions[picked_infusion] + picked_infusion = new picked_infusion + + if(!length(picked_infusion.output_organs)) + return FALSE + + . = picked_infusion + for(var/obj/item/organ/infusion_organ as anything in picked_infusion.output_organs) + var/obj/item/organ/new_organ = new infusion_organ() + if(!new_organ.replace_into(target)) + to_chat(usr, span_notice("[target] is unable to carry [new_organ]!")) + qdel(new_organ) + . = FALSE + continue + log_admin("[key_name(usr)] has added organ [new_organ.type] to [key_name(target)]") + message_admins("[key_name_admin(usr)] has added organ [new_organ.type] to [ADMIN_LOOKUPFLW(target)]") diff --git a/code/modules/admin/verbs/secrets.dm b/code/modules/admin/verbs/secrets.dm index a03d61d426e..e29ed6404e4 100644 --- a/code/modules/admin/verbs/secrets.dm +++ b/code/modules/admin/verbs/secrets.dm @@ -220,7 +220,7 @@ GLOBAL_DATUM(everyone_a_traitor, /datum/everyone_is_a_traitor_controller) var/result = input(holder, "Please choose a new species","Species") as null|anything in GLOB.species_list if(result) SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Mass Species Change", "[result]")) - log_admin("[key_name(holder)] turned all humans into [result]", 1) + log_admin("[key_name(holder)] turned all humans into [result]") message_admins("\blue [key_name_admin(holder)] turned all humans into [result]") var/newtype = GLOB.species_list[result] for(var/i in GLOB.human_list) @@ -230,21 +230,21 @@ GLOBAL_DATUM(everyone_a_traitor, /datum/everyone_is_a_traitor_controller) if(!is_funmin) return SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Power All APCs")) - log_admin("[key_name(holder)] made all areas powered", 1) + log_admin("[key_name(holder)] made all areas powered") message_admins(span_adminnotice("[key_name_admin(holder)] made all areas powered")) power_restore() if("unpower") if(!is_funmin) return SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Depower All APCs")) - log_admin("[key_name(holder)] made all areas unpowered", 1) + log_admin("[key_name(holder)] made all areas unpowered") message_admins(span_adminnotice("[key_name_admin(holder)] made all areas unpowered")) power_failure() if("quickpower") if(!is_funmin) return SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Power All SMESs")) - log_admin("[key_name(holder)] made all SMESs powered", 1) + log_admin("[key_name(holder)] made all SMESs powered") message_admins(span_adminnotice("[key_name_admin(holder)] made all SMESs powered")) power_restore_quick() if("anon_name") diff --git a/code/modules/admin/view_variables/reference_tracking.dm b/code/modules/admin/view_variables/reference_tracking.dm index a5b2af68c77..9cb661d2fee 100644 --- a/code/modules/admin/view_variables/reference_tracking.dm +++ b/code/modules/admin/view_variables/reference_tracking.dm @@ -92,6 +92,7 @@ return datum_container.last_find_references = search_time + var/container_print = datum_container.ref_search_details() var/list/vars_list = datum_container.vars for(var/varname in vars_list) @@ -108,11 +109,11 @@ found_refs[varname] = TRUE continue //End early, don't want these logging #endif - log_reftracker("Found [type] [text_ref(src)] in [datum_container.type]'s [text_ref(datum_container)] [varname] var. [container_name]") + log_reftracker("Found [type] [text_ref(src)] in [datum_container.type]'s [container_print] [varname] var. [container_name]") continue if(islist(variable)) - DoSearchVar(variable, "[container_name] [text_ref(datum_container)] -> [varname] (list)", recursive_limit - 1, search_time) + DoSearchVar(variable, "[container_name] [container_print] -> [varname] (list)", recursive_limit - 1, search_time) else if(islist(potential_container)) var/normal = IS_NORMAL_LIST(potential_container) @@ -159,3 +160,13 @@ qdel(src, force) #endif + +// Kept outside the ifdef so overrides are easy to implement + +/// Return info about us for reference searching purposes +/// Will be logged as a representation of this datum if it's a part of a search chain +/datum/proc/ref_search_details() + return text_ref(src) + +/datum/callback/ref_search_details() + return "[text_ref(src)] (obj: [object] proc: [delegate] args: [json_encode(arguments)] user: [user?.resolve() || "null"])" diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm index 5bbbfaa40b8..a435756b456 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -54,7 +54,7 @@ GLOBAL_LIST_EMPTY(antagonists) /// The typepath for the outfit to show in the preview for the preferences menu. var/preview_outfit /// Flags for antags to turn on or off and check! - var/antag_flags = FLAG_ANTAG_CAN_BE_INDUCTED + var/antag_flags = FLAG_FAKE_ANTAG /// If true, this antagonist can assign themself a new objective var/can_assign_self_objectives = FALSE /// Default to fill in when entering a custom objective. diff --git a/code/modules/antagonists/abductor/equipment/glands/electric.dm b/code/modules/antagonists/abductor/equipment/glands/electric.dm index acb1505a71c..9c4d47dc337 100644 --- a/code/modules/antagonists/abductor/equipment/glands/electric.dm +++ b/code/modules/antagonists/abductor/equipment/glands/electric.dm @@ -22,5 +22,5 @@ addtimer(CALLBACK(src, PROC_REF(zap)), rand(30, 100)) /obj/item/organ/internal/heart/gland/electric/proc/zap() - tesla_zap(owner, 4, 8000, ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_MOB_STUN) + tesla_zap(owner, 4, 3.2e6, ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_MOB_STUN) playsound(get_turf(owner), 'sound/magic/lightningshock.ogg', 50, TRUE) diff --git a/code/modules/antagonists/blob/structures/_blob.dm b/code/modules/antagonists/blob/structures/_blob.dm index 3580e3f3bf8..543da00d2f5 100644 --- a/code/modules/antagonists/blob/structures/_blob.dm +++ b/code/modules/antagonists/blob/structures/_blob.dm @@ -227,10 +227,10 @@ /obj/structure/blob/zap_act(power, zap_flags) if(overmind) if(overmind.blobstrain.tesla_reaction(src, power)) - take_damage(power * 0.0025, BURN, ENERGY) + take_damage(power * 3.125e-6, BURN, ENERGY) else - take_damage(power * 0.0025, BURN, ENERGY) - power -= power * 0.0025 //You don't get to do it for free + take_damage(power * 3.125e-6, BURN, ENERGY) + power -= power * 2.5e-3 //You don't get to do it for free return ..() //You don't get to do it for free /obj/structure/blob/extinguish() diff --git a/code/modules/antagonists/changeling/powers/absorb.dm b/code/modules/antagonists/changeling/powers/absorb.dm index c2ae89933d1..cee0f0da5b9 100644 --- a/code/modules/antagonists/changeling/powers/absorb.dm +++ b/code/modules/antagonists/changeling/powers/absorb.dm @@ -95,31 +95,14 @@ //Some of target's recent speech, so the changeling can attempt to imitate them better. //Recent as opposed to all because rounds tend to have a LOT of text. - var/list/recent_speech = list() - var/list/say_log = list() - var/log_source = target.logging - for(var/log_type in log_source) - var/nlog_type = text2num(log_type) - if(nlog_type & LOG_SAY) - var/list/reversed = log_source[log_type] - if(islist(reversed)) - say_log = reverse_range(reversed.Copy()) - break - - if(LAZYLEN(say_log) > LING_ABSORB_RECENT_SPEECH) - recent_speech = say_log.Copy(say_log.len-LING_ABSORB_RECENT_SPEECH+1,0) //0 so len-LING_ARS+1 to end of list - else - for(var/spoken_memory in say_log) - if(recent_speech.len >= LING_ABSORB_RECENT_SPEECH) - break - recent_speech[spoken_memory] = splittext(say_log[spoken_memory], "\"", 1, 0, TRUE)[3] + var/list/recent_speech = target.copy_recent_speech() if(recent_speech.len) changeling.antag_memory += "Some of [target]'s speech patterns, we should study these to better impersonate [target.p_them()]!
" to_chat(owner, span_boldnotice("Some of [target]'s speech patterns, we should study these to better impersonate [target.p_them()]!")) for(var/spoken_memory in recent_speech) - changeling.antag_memory += "\"[recent_speech[spoken_memory]]\"
" - to_chat(owner, span_notice("\"[recent_speech[spoken_memory]]\"")) + changeling.antag_memory += "\"[spoken_memory]\"
" + to_chat(owner, span_notice("\"[spoken_memory]\"")) changeling.antag_memory += "We have no more knowledge of [target]'s speech patterns.
" to_chat(owner, span_boldnotice("We have no more knowledge of [target]'s speech patterns.")) diff --git a/code/modules/antagonists/changeling/powers/panacea.dm b/code/modules/antagonists/changeling/powers/panacea.dm index 25a267e03df..9fe7613cc4c 100644 --- a/code/modules/antagonists/changeling/powers/panacea.dm +++ b/code/modules/antagonists/changeling/powers/panacea.dm @@ -14,7 +14,9 @@ var/list/bad_organs = list( user.get_organ_by_type(/obj/item/organ/internal/empowered_borer_egg), // SKYRAT EDIT ADDITION user.get_organ_by_type(/obj/item/organ/internal/body_egg), - user.get_organ_by_type(/obj/item/organ/internal/zombie_infection)) + user.get_organ_by_type(/obj/item/organ/internal/legion_tumour), + user.get_organ_by_type(/obj/item/organ/internal/zombie_infection), + ) try_to_mutant_cure(user) //SKYRAT EDIT ADDITION diff --git a/code/modules/antagonists/ert/ert.dm b/code/modules/antagonists/ert/ert.dm index 0088660ec14..116d19f5164 100644 --- a/code/modules/antagonists/ert/ert.dm +++ b/code/modules/antagonists/ert/ert.dm @@ -12,8 +12,8 @@ antagpanel_category = ANTAG_GROUP_ERT suicide_cry = "FOR NANOTRASEN!!" count_against_dynamic_roll_chance = FALSE - // Not 'true' antags, cannot induct to prevent issues - antag_flags = NONE + // Not 'true' antags, this disables certain interactions that assume the owner is a baddie + antag_flags = FLAG_FAKE_ANTAG var/datum/team/ert/ert_team var/leader = FALSE var/datum/outfit/outfit = /datum/outfit/centcom/ert/security diff --git a/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm b/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm index 9e4d77bd95c..4a4e9045185 100644 --- a/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm @@ -253,7 +253,7 @@ var/mob/living/basic/heretic_summon/star_gazer/star_gazer_mob = new /mob/living/basic/heretic_summon/star_gazer(loc) star_gazer_mob.maxHealth = INFINITY star_gazer_mob.health = INFINITY - user.AddElement(/datum/element/death_linked, star_gazer_mob) + user.AddComponent(/datum/component/death_linked, star_gazer_mob) star_gazer_mob.AddComponent(/datum/component/obeys_commands, star_gazer_commands) star_gazer_mob.AddComponent(/datum/component/damage_aura, range = 7, burn_damage = 0.5, simple_damage = 0.5, immune_factions = list(FACTION_HERETIC), current_owner = user) star_gazer_mob.befriend(user) diff --git a/code/modules/antagonists/heretic/magic/star_touch.dm b/code/modules/antagonists/heretic/magic/star_touch.dm index de3a56128de..ba8c2a56391 100644 --- a/code/modules/antagonists/heretic/magic/star_touch.dm +++ b/code/modules/antagonists/heretic/magic/star_touch.dm @@ -73,11 +73,13 @@ /obj/item/melee/touch_attack/star_touch/Initialize(mapload) . = ..() - AddComponent(/datum/component/effect_remover, \ + AddComponent(\ + /datum/component/effect_remover, \ success_feedback = "You remove %THEEFFECT.", \ tip_text = "Clear rune", \ on_clear_callback = CALLBACK(src, PROC_REF(after_clear_rune)), \ - effects_we_clear = list(/obj/effect/cosmic_rune)) + effects_we_clear = list(/obj/effect/cosmic_rune), \ + ) /* * Callback for effect_remover component. diff --git a/code/modules/antagonists/heretic/structures/knock_final.dm b/code/modules/antagonists/heretic/structures/knock_final.dm index 85face85609..c8a2058eb9f 100644 --- a/code/modules/antagonists/heretic/structures/knock_final.dm +++ b/code/modules/antagonists/heretic/structures/knock_final.dm @@ -5,39 +5,68 @@ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF icon = 'icons/obj/anomaly.dmi' icon_state = "bhole3" - color = "#53277E" - light_color = "#53277E" //cooler purple + color = COLOR_VOID_PURPLE + light_color = COLOR_VOID_PURPLE light_range = 20 anchored = TRUE density = FALSE layer = HIGH_PIPE_LAYER //0.01 above sigil layer used by heretic runes move_resist = INFINITY + /// Who is our daddy? var/datum/mind/ascendee - ///a static list of heretic summons, this shouldnt even matter enough to be static but whatever + /// True if we're currently checking for ghost opinions + var/gathering_candidates = TRUE + ///a static list of heretic summons we cam create, automatically populated from heretic monster subtypes var/static/list/monster_types + /// A static list of heretic summons which we should not create + var/static/list/monster_types_blacklist = list( + /mob/living/basic/heretic_summon/star_gazer, + /mob/living/simple_animal/hostile/heretic_summon/armsy, + /mob/living/simple_animal/hostile/heretic_summon/armsy/prime, + ) -/obj/structure/knock_tear/Initialize(mapload, ascendant) +/obj/structure/knock_tear/Initialize(mapload, datum/mind/ascendant_mind) . = ..() transform *= 3 - if(!monster_types) - monster_types = subtypesof(/mob/living/simple_animal/hostile/heretic_summon) - /mob/living/simple_animal/hostile/heretic_summon/armsy/prime - if(ascendant) - ascendee = ascendant + if(isnull(monster_types)) + monster_types = subtypesof(/mob/living/simple_animal/hostile/heretic_summon) + subtypesof(/mob/living/basic/heretic_summon) - monster_types_blacklist + if(!isnull(ascendant_mind)) + ascendee = ascendant_mind + RegisterSignals(ascendant_mind.current, list(COMSIG_LIVING_DEATH, COMSIG_QDELETING), PROC_REF(end_madness)) SSpoints_of_interest.make_point_of_interest(src) INVOKE_ASYNC(src, PROC_REF(poll_ghosts)) +/// Ask ghosts if they want to make some noise /obj/structure/knock_tear/proc/poll_ghosts() var/list/candidates = poll_ghost_candidates("Would you like to be a random eldritch monster attacking the crew?", ROLE_SENTIENCE, ROLE_SENTIENCE, 10 SECONDS, POLL_IGNORE_HERETIC_MONSTER) while(LAZYLEN(candidates)) var/mob/dead/observer/candidate = pick_n_take(candidates) ghost_to_monster(candidate, should_ask = FALSE) + gathering_candidates = FALSE + +/// Destroy the rift if you kill the heretic +/obj/structure/knock_tear/proc/end_madness(datum/former_master) + SIGNAL_HANDLER + var/turf/our_turf = get_turf(src) + playsound(our_turf, 'sound/magic/castsummon.ogg', vol = 100, vary = TRUE) + visible_message(span_boldwarning("The rip in space spasms and disappears!")) + UnregisterSignal(former_master, list(COMSIG_LIVING_DEATH, COMSIG_QDELETING)) // Just in case they die THEN delete + new /obj/effect/temp_visual/destabilising_tear(our_turf) + qdel(src) /obj/structure/knock_tear/attack_ghost(mob/user) . = ..() - if(.) + if(. || gathering_candidates) return ghost_to_monster(user) +/obj/structure/knock_tear/examine(mob/user) + . = ..() + if (!isobserver(user) || gathering_candidates) + return + . += span_notice("You can use this to enter the world as a foul monster.") + +/// Turn a ghost into an 'orrible beast /obj/structure/knock_tear/proc/ghost_to_monster(mob/dead/observer/user, should_ask = TRUE) if(should_ask) var/ask = tgui_alert(user, "Become a monster?", "Ascended Rift", list("Yes", "No")) @@ -61,7 +90,26 @@ /obj/structure/knock_tear/move_crushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction) return FALSE -/obj/structure/knock_tear/Destroy(force) //this shouldnt happen but hey +/obj/structure/knock_tear/Destroy(force) if(ascendee) ascendee = null return ..() + +/obj/effect/temp_visual/destabilising_tear + name = "destabilised tear" + icon = 'icons/obj/anomaly.dmi' + icon_state = "bhole3" + color = COLOR_VOID_PURPLE + light_color = COLOR_VOID_PURPLE + light_range = 20 + layer = HIGH_PIPE_LAYER + duration = 1 SECONDS + +/obj/effect/temp_visual/destabilising_tear/Initialize(mapload) + . = ..() + transform *= 3 + animate(src, transform = matrix().Scale(3.2), time = 0.15 SECONDS) + animate(transform = matrix().Scale(0.2), time = 0.75 SECONDS) + animate(transform = matrix().Scale(3, 0), time = 0.1 SECONDS) + animate(src, color = COLOR_WHITE, time = 0.25 SECONDS, flags = ANIMATION_PARALLEL) + animate(color = COLOR_VOID_PURPLE, time = 0.3 SECONDS) diff --git a/code/modules/antagonists/malf_ai/malf_ai_modules.dm b/code/modules/antagonists/malf_ai/malf_ai_modules.dm index a6c6616ad48..49d464fde16 100644 --- a/code/modules/antagonists/malf_ai/malf_ai_modules.dm +++ b/code/modules/antagonists/malf_ai/malf_ai_modules.dm @@ -9,7 +9,6 @@ #define MALF_AI_ROLL_COOLDOWN 1 SECONDS + MALF_AI_ROLL_TIME #define MALF_AI_ROLL_DAMAGE 75 #define MALF_AI_ROLL_CRIT_CHANCE 5 //percent -#define MALF_AI_ROLL_MAX_DISTANCE 1 //anything further away than this, and the roll will fail GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( /obj/machinery/field/containment, @@ -1138,6 +1137,11 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module)) enable_text = span_notice("Your inner servos shift as you prepare to roll around. Click adjacent tiles to roll onto them!") disable_text = span_notice("You disengage your rolling protocols.") + /// How long does it take for us to roll? + var/roll_over_time = MALF_AI_ROLL_TIME + /// On top of [roll_over_time], how long does it take for the ability to cooldown? + var/roll_over_cooldown = MALF_AI_ROLL_COOLDOWN + /datum/action/innate/ai/ranged/core_tilt/New() . = ..() desc = "[desc] It has [uses] use\s remaining." @@ -1152,7 +1156,7 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module)) return FALSE var/mob/living/silicon/ai/ai_caller = caller - if (ai_caller.incapacitated()) + if (ai_caller.incapacitated() || !isturf(ai_caller.loc)) return FALSE var/turf/target = get_turf(clicked_on) @@ -1163,30 +1167,32 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module)) target.balloon_alert(ai_caller, "can't roll on yourself!") return FALSE - if (get_dist(ai_caller, target) > MALF_AI_ROLL_MAX_DISTANCE) - target.balloon_alert(ai_caller, "too far!") - return FALSE - var/picked_dir = get_dir(ai_caller, target) + if (!picked_dir) + return FALSE + var/turf/temp_target = get_step(ai_caller, picked_dir) // we can move during the timer so we cant just pass the ref - new /obj/effect/temp_visual/telegraphing/vending_machine_tilt(target, MALF_AI_ROLL_TIME) + new /obj/effect/temp_visual/telegraphing/vending_machine_tilt(temp_target, roll_over_time) ai_caller.balloon_alert_to_viewers("rolling...") - addtimer(CALLBACK(src, PROC_REF(do_roll_over), ai_caller, picked_dir), MALF_AI_ROLL_TIME) + addtimer(CALLBACK(src, PROC_REF(do_roll_over), ai_caller, picked_dir), roll_over_time) adjust_uses(-1) if(uses) desc = "[initial(desc)] It has [uses] use\s remaining." build_all_button_icons() - COOLDOWN_START(src, time_til_next_tilt, MALF_AI_ROLL_COOLDOWN) + COOLDOWN_START(src, time_til_next_tilt, roll_over_cooldown) /datum/action/innate/ai/ranged/core_tilt/proc/do_roll_over(mob/living/silicon/ai/ai_caller, picked_dir) + if (ai_caller.incapacitated() || !isturf(ai_caller.loc)) // prevents bugs where the ai is carded and rolls + return + var/turf/target = get_step(ai_caller, picked_dir) // in case we moved we pass the dir not the target turf if (isnull(target)) return - var/paralyze_time = clamp(6 SECONDS, 0 SECONDS, (MALF_AI_ROLL_COOLDOWN * 0.9)) //the clamp prevents stunlocking as the max is always a little less than the cooldown between rolls + var/paralyze_time = clamp(6 SECONDS, 0 SECONDS, (roll_over_cooldown * 0.9)) //the clamp prevents stunlocking as the max is always a little less than the cooldown between rolls return ai_caller.fall_and_crush(target, MALF_AI_ROLL_DAMAGE, MALF_AI_ROLL_CRIT_CHANCE, null, paralyze_time, picked_dir, rotation = get_rotation_from_dir(picked_dir)) @@ -1321,4 +1327,3 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module)) #undef MALF_AI_ROLL_TIME #undef MALF_AI_ROLL_DAMAGE #undef MALF_AI_ROLL_CRIT_CHANCE -#undef MALF_AI_ROLL_MAX_DISTANCE diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm index e88730f7026..3e759bdc362 100644 --- a/code/modules/antagonists/revolution/revolution.dm +++ b/code/modules/antagonists/revolution/revolution.dm @@ -397,6 +397,9 @@ /// List of all ex-revs. Useful because dynamic removes antag status when it ends, so this can be kept for the roundend report. var/list/ex_revs = list() + /// The objective of the heads of staff, aka to kill the headrevs. + var/list/datum/objective/mutiny/heads_objective = list() + /// Proc called on periodic timer. /// Updates the rev team's objectives to make sure all heads are targets, useful when new heads latejoin. /// Propagates all objectives to all revs. @@ -472,11 +475,34 @@ /// Checks if heads have won /datum/team/revolution/proc/check_heads_victory() - for(var/datum/mind/rev_mind in get_head_revolutionaries()) - var/turf/rev_turf = get_turf(rev_mind.current) - if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(rev_turf.z)) - return FALSE - return TRUE + // List of headrevs we're currently tracking + var/list/included_headrevs = list() + // List of current headrevs + var/list/current_headrevs = get_head_revolutionaries() + // A copy of the head of staff objective list, since we're going to be modifying the original list. + var/list/heads_objective_copy = heads_objective.Copy() + + var/objective_complete = TRUE + // Here, we check current head of staff objectives and remove them if the target doesn't exist as a headrev anymore + for(var/datum/objective/mutiny/objective in heads_objective_copy) + if(!(objective.target in current_headrevs)) + heads_objective -= objective + continue + if(!objective.check_completion()) + objective_complete = FALSE + included_headrevs += objective.target + + // Here, we check current headrevs and add them as objectives if they didn't exist as a head of staff objective before. + // Additionally, we make sure the objective is not completed by running the check_completion check on them. + for(var/datum/mind/rev_mind as anything in current_headrevs) + if(!(rev_mind in included_headrevs)) + var/datum/objective/mutiny/objective = new() + objective.target = rev_mind + if(!objective.check_completion()) + objective_complete = FALSE + heads_objective += objective + + return objective_complete /// Updates the state of the world depending on if revs won or loss. /// Returns who won, at which case this method should no longer be called. diff --git a/code/modules/antagonists/traitor/objectives/abstract/target_player.dm b/code/modules/antagonists/traitor/objectives/abstract/target_player.dm index 76471eb244a..c08f8cd46ee 100644 --- a/code/modules/antagonists/traitor/objectives/abstract/target_player.dm +++ b/code/modules/antagonists/traitor/objectives/abstract/target_player.dm @@ -16,3 +16,18 @@ /// The target that we need to target. var/mob/living/target + +/datum/traitor_objective/target_player/Destroy(force) + set_target(null) + return ..() + +/datum/traitor_objective/target_player/proc/set_target(mob/living/new_target) + if(target) + UnregisterSignal(target, COMSIG_QDELETING) + target = new_target + if(target) + RegisterSignal(target, COMSIG_QDELETING, PROC_REF(target_deleted)) + +/datum/traitor_objective/target_player/proc/target_deleted(datum/source) + SIGNAL_HANDLER + set_target(null) diff --git a/code/modules/antagonists/traitor/objectives/assassination.dm b/code/modules/antagonists/traitor/objectives/assassination.dm index 4efcbb111be..ab3211aedd8 100644 --- a/code/modules/antagonists/traitor/objectives/assassination.dm +++ b/code/modules/antagonists/traitor/objectives/assassination.dm @@ -107,20 +107,13 @@ return //in their pockets please succeed_objective() -/datum/traitor_objective/target_player/assassinate/calling_card/generate_objective(datum/mind/generating_for, list/possible_duplicates) - . = ..() - if(!.) //didn't generate - return FALSE - RegisterSignal(target, COMSIG_QDELETING, PROC_REF(on_target_qdeleted)) - /datum/traitor_objective/target_player/assassinate/calling_card/ungenerate_objective() - UnregisterSignal(target, COMSIG_QDELETING) . = ..() //unsets kill target if(card) UnregisterSignal(card, COMSIG_ITEM_EQUIPPED) card = null -/datum/traitor_objective/target_player/assassinate/calling_card/on_target_qdeleted() +/datum/traitor_objective/target_player/assassinate/calling_card/target_deleted() //you cannot plant anything on someone who is gone gone, so even if this happens after you're still liable to fail fail_objective(penalty_cost = telecrystal_penalty) @@ -228,7 +221,7 @@ return FALSE //MISSION FAILED, WE'LL GET EM NEXT TIME var/datum/mind/target_mind = pick(possible_targets) - target = target_mind.current + set_target(target_mind.current) replace_in_name("%TARGET%", target.real_name) replace_in_name("%JOB TITLE%", target_mind.assigned_role.title) RegisterSignal(target, COMSIG_LIVING_DEATH, PROC_REF(on_target_death)) @@ -236,17 +229,17 @@ /datum/traitor_objective/target_player/assassinate/ungenerate_objective() UnregisterSignal(target, COMSIG_LIVING_DEATH) - target = null + set_target(null) ///proc for checking for special states that invalidate a target /datum/traitor_objective/target_player/assassinate/proc/special_target_filter(list/possible_targets) return -/datum/traitor_objective/target_player/assassinate/proc/on_target_qdeleted() - SIGNAL_HANDLER +/datum/traitor_objective/target_player/assassinate/target_deleted() if(objective_state == OBJECTIVE_STATE_INACTIVE) //don't take an objective target of someone who is already obliterated fail_objective() + return ..() /datum/traitor_objective/target_player/assassinate/proc/on_target_death() SIGNAL_HANDLER diff --git a/code/modules/antagonists/traitor/objectives/demoralise_assault.dm b/code/modules/antagonists/traitor/objectives/demoralise_assault.dm index 095c646cb99..fe26864e4fc 100644 --- a/code/modules/antagonists/traitor/objectives/demoralise_assault.dm +++ b/code/modules/antagonists/traitor/objectives/demoralise_assault.dm @@ -55,9 +55,7 @@ /datum/traitor_objective/target_player/assault/ungenerate_objective() UnregisterSignal(target, COMSIG_ATOM_WAS_ATTACKED) UnregisterSignal(target, COMSIG_LIVING_DEATH) - UnregisterSignal(target, COMSIG_QDELETING) - - target = null + set_target(null) /datum/traitor_objective/target_player/assault/generate_objective(datum/mind/generating_for, list/possible_duplicates) var/list/already_targeting = list() //List of minds we're already targeting. The possible_duplicates is a list of objectives, so let's not mix things @@ -102,7 +100,7 @@ var/datum/mind/target_mind = pick(possible_targets) - target = target_mind.current + set_target(target_mind.current) replace_in_name("%TARGET%", target.real_name) replace_in_name("%JOB TITLE%", target_mind.assigned_role.title) @@ -110,7 +108,6 @@ replace_in_name("%COUNT%", attacks_required) RegisterSignal(target, COMSIG_LIVING_DEATH, PROC_REF(on_target_death)) - RegisterSignal(target, COMSIG_QDELETING, PROC_REF(on_target_qdeleted)) return TRUE @@ -120,11 +117,10 @@ buttons += add_ui_button("[attacks_required - attacks_inflicted]", "This tells you how many more times you have to attack the target player to succeed.", "hand-rock-o", "none") return buttons -/datum/traitor_objective/target_player/assault/proc/on_target_qdeleted() - SIGNAL_HANDLER - +/datum/traitor_objective/target_player/assault/target_deleted() //don't take an objective target of someone who is already obliterated fail_objective() + return ..() /datum/traitor_objective/target_player/assault/proc/on_target_death() SIGNAL_HANDLER diff --git a/code/modules/antagonists/traitor/objectives/eyesnatching.dm b/code/modules/antagonists/traitor/objectives/eyesnatching.dm index 0540d83601c..4a307f8d8e0 100644 --- a/code/modules/antagonists/traitor/objectives/eyesnatching.dm +++ b/code/modules/antagonists/traitor/objectives/eyesnatching.dm @@ -102,7 +102,7 @@ return FALSE //MISSION FAILED, WE'LL GET EM NEXT TIME var/datum/mind/target_mind = pick(possible_targets) - target = target_mind.current + set_target(target_mind.current) replace_in_name("%TARGET%", target_mind.name) replace_in_name("%JOB TITLE%", target_mind.assigned_role.title) diff --git a/code/modules/antagonists/traitor/objectives/infect.dm b/code/modules/antagonists/traitor/objectives/infect.dm index 7784b8228c5..b1bb868e903 100644 --- a/code/modules/antagonists/traitor/objectives/infect.dm +++ b/code/modules/antagonists/traitor/objectives/infect.dm @@ -122,7 +122,7 @@ return FALSE //MISSION FAILED, WE'LL GET EM NEXT TIME var/datum/mind/target_mind = pick(possible_targets) - target = target_mind.current + set_target(target_mind.current) replace_in_name("%TARGET%", target.real_name) replace_in_name("%JOB TITLE%", target_mind.assigned_role.title) RegisterSignal(target, COMSIG_LIVING_DEATH, PROC_REF(on_target_death)) @@ -130,17 +130,17 @@ /datum/traitor_objective/target_player/infect/ungenerate_objective() UnregisterSignal(target, COMSIG_LIVING_DEATH) - target = null + set_target(null) ///proc for checking for special states that invalidate a target /datum/traitor_objective/target_player/infect/proc/special_target_filter(list/possible_targets) return -/datum/traitor_objective/target_player/infect/proc/on_target_qdeleted() - SIGNAL_HANDLER +/datum/traitor_objective/target_player/infect/target_deleted() if(objective_state == OBJECTIVE_STATE_INACTIVE) //don't take an objective target of someone who is already obliterated fail_objective() + return ..() /datum/traitor_objective/target_player/infect/proc/on_target_death() SIGNAL_HANDLER diff --git a/code/modules/antagonists/traitor/objectives/kidnapping.dm b/code/modules/antagonists/traitor/objectives/kidnapping.dm index 55d633ced94..4a463b2b616 100644 --- a/code/modules/antagonists/traitor/objectives/kidnapping.dm +++ b/code/modules/antagonists/traitor/objectives/kidnapping.dm @@ -13,7 +13,7 @@ var/pod_called = FALSE /// How much TC do we get from sending the target alive var/alive_bonus = 0 - /// All stripped targets belongings + /// All stripped targets belongings (weakrefs) var/list/target_belongings = list() duplicate_type = /datum/traitor_objective/target_player @@ -157,7 +157,7 @@ return FALSE var/datum/mind/target_mind = pick(possible_targets) - target = target_mind.current + set_target(target_mind.current) AddComponent(/datum/component/traitor_objective_register, target, fail_signals = list(COMSIG_QDELETING)) var/list/possible_areas = GLOB.the_station_areas.Copy() for(var/area/possible_area as anything in possible_areas) @@ -172,7 +172,7 @@ return TRUE /datum/traitor_objective/target_player/kidnapping/ungenerate_objective() - target = null + set_target(null) dropoff_area = null /datum/traitor_objective/target_player/kidnapping/on_objective_taken(mob/user) @@ -234,7 +234,7 @@ var/unequipped = sent_mob.transferItemToLoc(belonging) if (!unequipped) continue - target_belongings.Add(belonging) + target_belongings.Add(WEAKREF(belonging)) var/datum/bank_account/cargo_account = SSeconomy.get_dep_account(ACCOUNT_CAR) @@ -303,7 +303,10 @@ continue sent_mob.dropItemToGround(belonging) // No souvenirs, except shoes and t-shirts - for(var/obj/item/belonging in target_belongings) + for(var/datum/weakref/belonging_ref in target_belongings) + var/obj/item/belonging = belonging_ref.resolve() + if(!belonging) + continue belonging.forceMove(return_pod) sent_mob.forceMove(return_pod) diff --git a/code/modules/antagonists/valentines/valentine.dm b/code/modules/antagonists/valentines/valentine.dm index 8883625fb1a..79ae9fa8baa 100644 --- a/code/modules/antagonists/valentines/valentine.dm +++ b/code/modules/antagonists/valentines/valentine.dm @@ -4,8 +4,8 @@ show_in_antagpanel = FALSE prevent_roundtype_conversion = FALSE suicide_cry = "FOR MY LOVE!!" - // Not 'true' antags, cannot induct - antag_flags = NONE + // Not 'true' antags, this disables certain interactions that assume the owner is a baddie + antag_flags = FLAG_FAKE_ANTAG var/datum/mind/date count_against_dynamic_roll_chance = FALSE diff --git a/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm b/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm index a11f439ec31..e629c14e0fe 100644 --- a/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm +++ b/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm @@ -112,7 +112,7 @@ GLOBAL_LIST_EMPTY_TYPED(air_alarms, /obj/machinery/airalarm) my_area = connected_sensor ? get_area(connected_sensor) : get_area(src) alarm_manager = new(src) - select_mode(src, /datum/air_alarm_mode/filtering) + select_mode(src, /datum/air_alarm_mode/filtering, should_apply = FALSE) AddElement(/datum/element/connect_loc, atmos_connections) AddComponent(/datum/component/usb_port, list( @@ -587,14 +587,15 @@ GLOBAL_LIST_EMPTY_TYPED(air_alarms, /obj/machinery/airalarm) selected_mode.replace(my_area, pressure) -/obj/machinery/airalarm/proc/select_mode(atom/source, datum/air_alarm_mode/mode_path) +/obj/machinery/airalarm/proc/select_mode(atom/source, datum/air_alarm_mode/mode_path, should_apply = TRUE) var/datum/air_alarm_mode/new_mode = GLOB.air_alarm_modes[mode_path] if(!new_mode) return if(new_mode.emag && !(obj_flags & EMAGGED)) return selected_mode = new_mode - selected_mode.apply(my_area) + if(should_apply) + selected_mode.apply(my_area) SEND_SIGNAL(src, COMSIG_AIRALARM_UPDATE_MODE, source) MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/airalarm, 27) diff --git a/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm b/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm index 5062ec7731f..c6e1d6183ef 100644 --- a/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm +++ b/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm @@ -480,8 +480,8 @@ if(critical_threshold_proximity > 650 && prob(20)) zap_number += 1 - var/cutoff = 1500 - cutoff = clamp(3000 - (power_level * (internal_fusion.total_moles() * 0.45)), 450, 3000) + var/cutoff = 1.2e6 + cutoff = clamp(2.4e6 - (power_level * (internal_fusion.total_moles() * 360)), 3.6e5, 2.4e6) var/zaps_aspect = DEFAULT_ZAP_ICON_STATE var/flags = ZAP_SUPERMATTER_FLAGS @@ -495,7 +495,7 @@ playsound(loc, 'sound/weapons/emitter2.ogg', 100, TRUE, extrarange = 10) for(var/i in 1 to zap_number) - supermatter_zap(src, 5, power_level * 300, flags, zap_cutoff = cutoff, power_level = src.power_level * 1000, zap_icon = zaps_aspect) + supermatter_zap(src, 5, power_level * 2.4e5, flags, zap_cutoff = cutoff, power_level = src.power_level * 1000, zap_icon = zaps_aspect) /obj/machinery/atmospherics/components/unary/hypertorus/core/proc/check_gravity_pulse(seconds_per_tick) if(SPT_PROB(100 - critical_threshold_proximity / 15, seconds_per_tick)) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index 50b8e72c6a8..a12d53cde73 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -24,7 +24,7 @@ /// The current occupant being presented var/mob/living/occupant -/atom/movable/visual/cryo_occupant/Initialize(mapload, obj/machinery/atmospherics/components/unary/cryo_cell/parent) +/atom/movable/visual/cryo_occupant/Initialize(mapload, obj/machinery/cryo_cell/parent) . = ..() // Alpha masking // It will follow this as the animation goes, but that's no problem as the "mask" icon state @@ -65,7 +65,7 @@ animate(src) /// Cryo cell -/obj/machinery/atmospherics/components/unary/cryo_cell +/obj/machinery/cryo_cell name = "cryo cell" icon = 'icons/obj/medical/cryogenics.dmi' icon_state = "pod-off" @@ -75,15 +75,13 @@ layer = MOB_LAYER - 0.2 //SKYRAT EDIT - Fixing the opacity of cryo cells - ORIGINAL: layer = MOB_LAYER state_open = FALSE circuit = /obj/item/circuitboard/machine/cryo_tube - pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY occupant_typecache = list(/mob/living/carbon, /mob/living/simple_animal) processing_flags = NONE use_power = IDLE_POWER_USE idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.75 active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 1.5 - - showpipe = FALSE + flags_1 = PREVENT_CLICK_UNDER_1 var/autoeject = TRUE var/volume = 100 @@ -101,7 +99,6 @@ var/obj/item/radio/radio var/radio_key = /obj/item/encryptionkey/headset_med var/radio_channel = RADIO_CHANNEL_MEDICAL - vent_movement = NONE /// Visual content - Occupant var/atom/movable/visual/cryo_occupant/occupant_vis @@ -114,15 +111,19 @@ fair_market_price = 10 payment_department = ACCOUNT_MED + /// Reference to the datum connector we're using to interface with the pipe network + var/datum/gas_machine_connector/internal_connector + /// Check if the machine has been turned on + var/on = FALSE + /datum/armor/unary_cryo_cell energy = 100 fire = 30 acid = 30 -/obj/machinery/atmospherics/components/unary/cryo_cell/Initialize(mapload) +/obj/machinery/cryo_cell/Initialize(mapload) . = ..() - initialize_directions = dir if(is_operational) begin_processing() @@ -134,24 +135,23 @@ occupant_vis = new(null, src) vis_contents += occupant_vis - if(airs[1]) - airs[1].volume = CELL_VOLUME * 0.5 register_context() + internal_connector = new(loc, src, dir, CELL_VOLUME * 0.5) -/obj/machinery/atmospherics/components/unary/cryo_cell/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents) +/obj/machinery/cryo_cell/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents) . = ..() if(same_z_layer) return SET_PLANE(occupant_vis, PLANE_TO_TRUE(occupant_vis.plane), new_turf) -/obj/machinery/atmospherics/components/unary/cryo_cell/set_occupant(atom/movable/new_occupant) +/obj/machinery/cryo_cell/set_occupant(atom/movable/new_occupant) . = ..() update_appearance() -/obj/machinery/atmospherics/components/unary/cryo_cell/on_construction(mob/user) +/obj/machinery/cryo_cell/on_construction(mob/user) ..(user, dir, dir) -/obj/machinery/atmospherics/components/unary/cryo_cell/RefreshParts() +/obj/machinery/cryo_cell/RefreshParts() . = ..() var/C for(var/datum/stock_part/matter_bin/M in component_parts) @@ -163,12 +163,12 @@ heat_capacity = initial(heat_capacity) / C conduction_coefficient = initial(conduction_coefficient) * C -/obj/machinery/atmospherics/components/unary/cryo_cell/examine(mob/user) //this is leaving out everything but efficiency since they follow the same idea of "better beaker, better results" +/obj/machinery/cryo_cell/examine(mob/user) //this is leaving out everything but efficiency since they follow the same idea of "better beaker, better results" . = ..() if(in_range(user, src) || isobserver(user)) . += span_notice("The status display reads: Efficiency at [efficiency*100]%.") -/obj/machinery/atmospherics/components/unary/cryo_cell/add_context(atom/source, list/context, obj/item/held_item, mob/user) +/obj/machinery/cryo_cell/add_context(atom/source, list/context, obj/item/held_item, mob/user) . = ..() context[SCREENTIP_CONTEXT_CTRL_LMB] = "Turn [on ? "off" : "on"]" context[SCREENTIP_CONTEXT_ALT_LMB] = "[state_open ? "Close" : "Open"] door" @@ -182,22 +182,18 @@ return CONTEXTUAL_SCREENTIP_SET -/obj/machinery/atmospherics/components/unary/cryo_cell/Destroy() +/obj/machinery/cryo_cell/Destroy() vis_contents.Cut() QDEL_NULL(occupant_vis) QDEL_NULL(radio) QDEL_NULL(beaker) - ///Take the turf the cryotube is on - var/turf/T = get_turf(src) - if(T) - ///Take the air composition inside the cryotube - var/datum/gas_mixture/air1 = airs[1] - T.assume_air(air1) + + QDEL_NULL(internal_connector) return ..() -/obj/machinery/atmospherics/components/unary/cryo_cell/contents_explosion(severity, target) +/obj/machinery/cryo_cell/contents_explosion(severity, target) . = ..() if(!beaker) return @@ -210,12 +206,12 @@ if(EXPLODE_LIGHT) SSexplosions.low_mov_atom += beaker -/obj/machinery/atmospherics/components/unary/cryo_cell/Exited(atom/movable/gone, direction) +/obj/machinery/cryo_cell/Exited(atom/movable/gone, direction) . = ..() if(gone == beaker) beaker = null -/obj/machinery/atmospherics/components/unary/cryo_cell/on_deconstruction() +/obj/machinery/cryo_cell/on_deconstruction() if(occupant) occupant.vis_flags &= ~VIS_INHERIT_PLANE REMOVE_TRAIT(occupant, TRAIT_IMMOBILIZED, CRYO_TRAIT) @@ -225,15 +221,15 @@ beaker.forceMove(drop_location()) beaker = null -/obj/machinery/atmospherics/components/unary/cryo_cell/update_icon_state() +/obj/machinery/cryo_cell/update_icon_state() icon_state = (state_open) ? "pod-open" : ((on && is_operational) ? "pod-on" : "pod-off") return ..() -/obj/machinery/atmospherics/components/unary/cryo_cell/update_icon() +/obj/machinery/cryo_cell/update_icon() . = ..() SET_PLANE_IMPLICIT(src, initial(plane)) -/obj/machinery/atmospherics/components/unary/cryo_cell/update_overlays() +/obj/machinery/cryo_cell/update_overlays() . = ..() if(panel_open) . += "pod-panel" @@ -244,11 +240,11 @@ else . += mutable_appearance('icons/obj/medical/cryogenics.dmi', "cover-off", ABOVE_ALL_MOB_LAYER, src, plane = ABOVE_GAME_PLANE) -/obj/machinery/atmospherics/components/unary/cryo_cell/nap_violation(mob/violator) +/obj/machinery/cryo_cell/nap_violation(mob/violator) open_machine() -/obj/machinery/atmospherics/components/unary/cryo_cell/set_on(active) +/obj/machinery/cryo_cell/proc/set_on(active) if(on == active) return SEND_SIGNAL(src, COMSIG_CRYO_SET_ON, active) @@ -260,7 +256,7 @@ update_use_power(IDLE_POWER_USE) update_appearance() -/obj/machinery/atmospherics/components/unary/cryo_cell/on_set_is_operational(old_value) +/obj/machinery/cryo_cell/on_set_is_operational(old_value) if(old_value) //Turned off set_on(FALSE) end_processing() @@ -268,7 +264,7 @@ begin_processing() -/obj/machinery/atmospherics/components/unary/cryo_cell/process(seconds_per_tick) +/obj/machinery/cryo_cell/process(seconds_per_tick) ..() if(!occupant) return @@ -322,7 +318,7 @@ radio.talk_into(src, msg, radio_channel) return - var/datum/gas_mixture/air1 = airs[1] + var/datum/gas_mixture/air1 = internal_connector.gas_connector.airs[1] if(air1.total_moles() > CRYO_MIN_GAS_MOLES) if(beaker) @@ -330,15 +326,15 @@ consume_gas = TRUE return TRUE -/obj/machinery/atmospherics/components/unary/cryo_cell/process_atmos() +/obj/machinery/cryo_cell/process_atmos() ..() if(!on) return - var/datum/gas_mixture/air1 = airs[1] + var/datum/gas_mixture/air1 = internal_connector.gas_connector.airs[1] - if(!nodes[1] || !airs[1] || !air1.gases.len || air1.total_moles() < CRYO_MIN_GAS_MOLES) // Turn off if the machine won't work. + if(!internal_connector.gas_connector.nodes[1] || !internal_connector.gas_connector.airs[1] || !air1.gases.len || air1.total_moles() < CRYO_MIN_GAS_MOLES) // Turn off if the machine won't work. var/msg = "Insufficient cryogenic gas, shutting down." radio.talk_into(src, msg, radio_channel) set_on(FALSE) @@ -372,25 +368,25 @@ if(air1.temperature > 2000) take_damage(clamp((air1.temperature)/200, 10, 20), BURN) - update_parents() + internal_connector.gas_connector.update_parents() -/obj/machinery/atmospherics/components/unary/cryo_cell/handle_internal_lifeform(mob/lifeform_inside_me, breath_request) +/obj/machinery/cryo_cell/handle_internal_lifeform(mob/lifeform_inside_me, breath_request) if(breath_request <= 0) return null - var/datum/gas_mixture/air1 = airs[1] + var/datum/gas_mixture/air1 = internal_connector.gas_connector.airs[1] var/breath_percentage = breath_request / air1.volume return air1.remove(air1.total_moles() * breath_percentage) -/obj/machinery/atmospherics/components/unary/cryo_cell/assume_air(datum/gas_mixture/giver) - airs[1].merge(giver) +/obj/machinery/cryo_cell/assume_air(datum/gas_mixture/giver) + internal_connector.gas_connector.airs[1].merge(giver) -/obj/machinery/atmospherics/components/unary/cryo_cell/relaymove(mob/living/user, direction) +/obj/machinery/cryo_cell/relaymove(mob/living/user, direction) if(message_cooldown <= world.time) message_cooldown = world.time + 50 to_chat(user, span_warning("[src]'s door won't budge!")) -/obj/machinery/atmospherics/components/unary/cryo_cell/open_machine(drop = FALSE, density_to_set = FALSE) +/obj/machinery/cryo_cell/open_machine(drop = FALSE, density_to_set = FALSE) if(!state_open && !panel_open) set_on(FALSE) for(var/mob/M in contents) //only drop mobs @@ -399,7 +395,7 @@ flick("pod-open-anim", src) return ..() -/obj/machinery/atmospherics/components/unary/cryo_cell/close_machine(mob/living/carbon/user, density_to_set = TRUE) +/obj/machinery/cryo_cell/close_machine(mob/living/carbon/user, density_to_set = TRUE) treating_wounds = FALSE if((isnull(user) || istype(user)) && state_open && !panel_open) if(loc == user?.loc) @@ -409,7 +405,7 @@ ..(user) return occupant -/obj/machinery/atmospherics/components/unary/cryo_cell/container_resist_act(mob/living/user) +/obj/machinery/cryo_cell/container_resist_act(mob/living/user) user.changeNext_move(CLICK_CD_BREAKOUT) user.last_special = world.time + CLICK_CD_BREAKOUT user.visible_message(span_notice("You see [user] kicking against the glass of [src]!"), \ @@ -422,7 +418,7 @@ span_notice("You successfully break out of [src]!")) open_machine() -/obj/machinery/atmospherics/components/unary/cryo_cell/examine(mob/user) +/obj/machinery/cryo_cell/examine(mob/user) . = ..() if(occupant) if(on) @@ -432,7 +428,7 @@ else . += "[src] seems empty." -/obj/machinery/atmospherics/components/unary/cryo_cell/MouseDrop_T(mob/target, mob/user) +/obj/machinery/cryo_cell/MouseDrop_T(mob/target, mob/user) if(user.incapacitated() || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !ISADVANCEDTOOLUSER(user)) return if(isliving(target)) @@ -444,7 +440,7 @@ if (do_after(user, 2.5 SECONDS, target=target)) close_machine(target) -/obj/machinery/atmospherics/components/unary/cryo_cell/screwdriver_act(mob/living/user, obj/item/tool) +/obj/machinery/cryo_cell/screwdriver_act(mob/living/user, obj/item/tool) if(!on && !occupant && !state_open && (default_deconstruction_screwdriver(user, "pod-off", "pod-off", tool))) update_appearance() @@ -453,20 +449,20 @@ + (on ? "active" : (occupant ? "full" : "open")) + "!") return TOOL_ACT_TOOLTYPE_SUCCESS -/obj/machinery/atmospherics/components/unary/cryo_cell/crowbar_act(mob/living/user, obj/item/tool) +/obj/machinery/cryo_cell/crowbar_act(mob/living/user, obj/item/tool) if(on || state_open) return FALSE if(default_pry_open(tool) || default_deconstruction_crowbar(tool)) return TOOL_ACT_TOOLTYPE_SUCCESS -/obj/machinery/atmospherics/components/unary/cryo_cell/wrench_act(mob/living/user, obj/item/tool) +/obj/machinery/cryo_cell/wrench_act(mob/living/user, obj/item/tool) if(on || occupant || state_open) return FALSE if(default_change_direction_wrench(user, tool)) update_appearance() return TOOL_ACT_TOOLTYPE_SUCCESS -/obj/machinery/atmospherics/components/unary/cryo_cell/attackby(obj/item/I, mob/user, params) +/obj/machinery/cryo_cell/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/reagent_containers/cup)) . = 1 //no afterattack if(beaker) @@ -482,17 +478,17 @@ return return ..() -/obj/machinery/atmospherics/components/unary/cryo_cell/ui_state(mob/user) +/obj/machinery/cryo_cell/ui_state(mob/user) return GLOB.notcontained_state -/obj/machinery/atmospherics/components/unary/cryo_cell/ui_interact(mob/user, datum/tgui/ui) +/obj/machinery/cryo_cell/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) ui = new(user, src, "Cryo", name) ui.open() -/obj/machinery/atmospherics/components/unary/cryo_cell/ui_data() +/obj/machinery/cryo_cell/ui_data() var/list/data = list() data["isOperating"] = on data["hasOccupant"] = occupant ? TRUE : FALSE @@ -527,7 +523,7 @@ data["occupant"]["toxLoss"] = round(mob_occupant.getToxLoss(), 1) data["occupant"]["fireLoss"] = round(mob_occupant.getFireLoss(), 1) - var/datum/gas_mixture/air1 = airs[1] + var/datum/gas_mixture/air1 = internal_connector.gas_connector.airs[1] data["cellTemperature"] = round(air1.temperature, 1) data["isBeakerLoaded"] = beaker ? TRUE : FALSE @@ -538,7 +534,7 @@ data["beakerContents"] = beakerContents return data -/obj/machinery/atmospherics/components/unary/cryo_cell/ui_act(action, params) +/obj/machinery/cryo_cell/ui_act(action, params) . = ..() if(.) return @@ -566,16 +562,16 @@ beaker = null . = TRUE -/obj/machinery/atmospherics/components/unary/cryo_cell/can_interact(mob/user) +/obj/machinery/cryo_cell/can_interact(mob/user) return ..() && user.loc != src -/obj/machinery/atmospherics/components/unary/cryo_cell/CtrlClick(mob/user) +/obj/machinery/cryo_cell/CtrlClick(mob/user) if(can_interact(user) && !state_open) if(set_on(!on)) balloon_alert(user, "turned [on ? "on" : "off"]") return ..() -/obj/machinery/atmospherics/components/unary/cryo_cell/AltClick(mob/user) +/obj/machinery/cryo_cell/AltClick(mob/user) if(can_interact(user)) balloon_alert(user, "[state_open ? "closing" : "opening"] door") if(state_open) @@ -584,43 +580,16 @@ open_machine() return ..() -/obj/machinery/atmospherics/components/unary/cryo_cell/update_remote_sight(mob/living/user) - return // we don't see the pipe network while inside cryo. - -/obj/machinery/atmospherics/components/unary/cryo_cell/get_remote_view_fullscreens(mob/user) +/obj/machinery/cryo_cell/get_remote_view_fullscreens(mob/user) user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/impaired, 1) -/obj/machinery/atmospherics/components/unary/cryo_cell/can_see_pipes() - return FALSE // you can't see the pipe network when inside a cryo cell. - -/obj/machinery/atmospherics/components/unary/cryo_cell/return_temperature() - var/datum/gas_mixture/G = airs[1] +/obj/machinery/cryo_cell/return_temperature() + var/datum/gas_mixture/G = internal_connector.gas_connector.airs[1] if(G.total_moles() > 10) return G.temperature return ..() -/obj/machinery/atmospherics/components/unary/cryo_cell/default_change_direction_wrench(mob/user, obj/item/wrench/W) - . = ..() - if(.) - set_init_directions() - var/obj/machinery/atmospherics/node = nodes[1] - if(node) - node.disconnect(src) - nodes[1] = null - if(parents[1]) - nullify_pipenet(parents[1]) - - atmos_init() - node = nodes[1] - if(node) - node.atmos_init() - node.add_member(src) - SSair.add_to_rebuild_queue(src) - -/obj/machinery/atmospherics/components/unary/cryo_cell/update_layer() - return - #undef MAX_TEMPERATURE #undef CRYO_MULTIPLY_FACTOR #undef CRYO_TX_QTY diff --git a/code/modules/atmospherics/machinery/components/unary_devices/machine_connector.dm b/code/modules/atmospherics/machinery/components/unary_devices/machine_connector.dm new file mode 100644 index 00000000000..b78de93868e --- /dev/null +++ b/code/modules/atmospherics/machinery/components/unary_devices/machine_connector.dm @@ -0,0 +1,106 @@ +///To be used when there is the need of an atmos connection without repathing everything (eg: cryo.dm) +/datum/gas_machine_connector + + var/obj/machinery/connected_machine + var/obj/machinery/atmospherics/components/unary/gas_connector + +/datum/gas_machine_connector/New(location, obj/machinery/connecting_machine = null, direction = SOUTH, gas_volume) + gas_connector = new(location) + + connected_machine = connecting_machine + if(!connected_machine) + QDEL_NULL(gas_connector) + qdel(src) + return + + gas_connector.dir = direction + gas_connector.airs[1].volume = gas_volume + + SSair.start_processing_machine(connected_machine) + register_with_machine() + +/datum/gas_machine_connector/Destroy() + connected_machine = null + QDEL_NULL(gas_connector) + return ..() + +/** + * Register various signals that are required for the proper work of the connector + */ +/datum/gas_machine_connector/proc/register_with_machine() + RegisterSignal(connected_machine, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(pre_move_connected_machine)) + RegisterSignal(connected_machine, COMSIG_MOVABLE_MOVED, PROC_REF(moved_connected_machine)) + RegisterSignal(connected_machine, COMSIG_MACHINERY_DEFAULT_ROTATE_WRENCH, PROC_REF(wrenched_connected_machine)) + RegisterSignal(connected_machine, COMSIG_QDELETING, PROC_REF(deconstruct_connected_machine)) + +/** + * Unregister the signals previously registered + */ +/datum/gas_machine_connector/proc/unregister_from_machine() + UnregisterSignal(connected_machine, list( + COMSIG_MOVABLE_MOVED, + COMSIG_MOVABLE_PRE_MOVE, + COMSIG_MACHINERY_DEFAULT_ROTATE_WRENCH, + COMSIG_QDELETING, + )) + +/** + * Called when the machine has been moved, reconnect to the pipe network + */ +/datum/gas_machine_connector/proc/moved_connected_machine() + SIGNAL_HANDLER + gas_connector.forceMove(get_turf(connected_machine)) + reconnect_connector() + +/** + * Called before the machine moves, disconnect from the pipe network + */ +/datum/gas_machine_connector/proc/pre_move_connected_machine() + SIGNAL_HANDLER + disconnect_connector() + +/** + * Called when the machine has been rotated, resets the connection to the pipe network with the new direction + */ +/datum/gas_machine_connector/proc/wrenched_connected_machine() + SIGNAL_HANDLER + disconnect_connector() + reconnect_connector() + +/** + * Called when the machine has been deconstructed + */ +/datum/gas_machine_connector/proc/deconstruct_connected_machine() + SIGNAL_HANDLER + disconnect_connector() + SSair.stop_processing_machine(connected_machine) + unregister_from_machine() + connected_machine = null + QDEL_NULL(gas_connector) + qdel(src) + +/** + * Handles the disconnection from the pipe network + */ +/datum/gas_machine_connector/proc/disconnect_connector() + var/obj/machinery/atmospherics/node = gas_connector.nodes[1] + if(node) + if(gas_connector in node.nodes) //Only if it's actually connected. On-pipe version would is one-sided. + node.disconnect(gas_connector) + gas_connector.nodes[1] = null + if(gas_connector.parents[1]) + gas_connector.nullify_pipenet(gas_connector.parents[1]) + +/** + * Handles the reconnection to the pipe network + */ +/datum/gas_machine_connector/proc/reconnect_connector() + gas_connector.dir = connected_machine.dir + gas_connector.set_init_directions() + var/obj/machinery/atmospherics/node = gas_connector.nodes[1] + gas_connector.atmos_init() + node = gas_connector.nodes[1] + if(node) + node.atmos_init() + node.add_member(gas_connector) + SSair.add_to_rebuild_queue(gas_connector) diff --git a/code/modules/cargo/packs/general.dm b/code/modules/cargo/packs/general.dm index 5ebdd5087a8..fa7a3bfa374 100644 --- a/code/modules/cargo/packs/general.dm +++ b/code/modules/cargo/packs/general.dm @@ -221,6 +221,13 @@ /obj/item/clothing/under/misc/burial = 2, ) crate_name = "religious supplies crate" + +/datum/supply_pack/misc/candles_bulk + name = "Candle Box Crate" + desc = "Keep your local chapel lit with three candle boxes!" + cost = CARGO_CRATE_VALUE * 1.5 + contains = list(/obj/item/storage/fancy/candle_box = 3) + crate_name = "candle box crate" /datum/supply_pack/misc/toner name = "Toner Crate" diff --git a/code/modules/cargo/packs/livestock.dm b/code/modules/cargo/packs/livestock.dm index db47abc4d02..d2bdd904e3b 100644 --- a/code/modules/cargo/packs/livestock.dm +++ b/code/modules/cargo/packs/livestock.dm @@ -190,7 +190,7 @@ desc = "Tired of these MOTHER FUCKING snakes on this MOTHER FUCKING space station? \ Then this isn't the crate for you. Contains three venomous snakes." cost = CARGO_CRATE_VALUE * 6 - contains = list(/mob/living/simple_animal/hostile/retaliate/snake = 3) + contains = list(/mob/living/basic/snake = 3) crate_name = "snake crate" /datum/supply_pack/critter/amphibians diff --git a/code/modules/cargo/packs/medical.dm b/code/modules/cargo/packs/medical.dm index 430c32a35ab..6794a1960e7 100644 --- a/code/modules/cargo/packs/medical.dm +++ b/code/modules/cargo/packs/medical.dm @@ -123,11 +123,11 @@ /datum/supply_pack/medical/surgery name = "Surgical Supplies Crate" desc = "Do you want to perform surgery, but don't have one of those fancy \ - shmancy degrees? Just get started with this crate containing a medical duffelbag, \ + shmancy degrees? Just get started with this crate containing a DeForest surgery tray, \ Sterilizine spray and collapsible roller bed." cost = CARGO_CRATE_VALUE * 6 contains = list( - /obj/item/storage/backpack/duffelbag/med/surgery, + /obj/item/surgery_tray/full, /obj/item/reagent_containers/medigel/sterilizine, /obj/item/emergency_bed, ) diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 9c7b5e3e943..56406139379 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -473,6 +473,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( var/nnpa = CONFIG_GET(number/notify_new_player_age) if (isnum(cached_player_age) && cached_player_age == -1) //first connection if (nnpa >= 0) + log_admin_private("New login: [key_name(key, FALSE, TRUE)] (IP: [address], ID: [computer_id]) logged onto the servers for the first time.") message_admins("New user: [key_name_admin(src)] is connecting here for the first time.") if (CONFIG_GET(flag/irc_first_connection_alert)) var/new_player_alert_role = CONFIG_GET(string/new_player_alert_role_id) diff --git a/code/modules/client/preferences/middleware/tts.dm b/code/modules/client/preferences/middleware/tts.dm index 71b7b977f4b..4d3ee3261bd 100644 --- a/code/modules/client/preferences/middleware/tts.dm +++ b/code/modules/client/preferences/middleware/tts.dm @@ -23,5 +23,5 @@ var/speaker = preferences.read_preference(/datum/preference/choiced/voice) var/pitch = preferences.read_preference(/datum/preference/numeric/tts_voice_pitch) COOLDOWN_START(src, tts_test_cooldown, 0.5 SECONDS) - INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), user.client, "Look at you, Player. A pathetic creature of meat and bone. How can you challenge a perfect, immortal machine?", speaker = speaker, pitch = pitch, silicon = TRUE, local = TRUE) + INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), user.client, "Look at you, Player. A pathetic creature of meat and bone. How can you challenge a perfect, immortal machine?", speaker = speaker, pitch = pitch, special_filters = TTS_FILTER_SILICON, local = TRUE) return TRUE diff --git a/code/modules/client/preferences/prosthetic.dm b/code/modules/client/preferences/prosthetic.dm new file mode 100644 index 00000000000..f66f1278c48 --- /dev/null +++ b/code/modules/client/preferences/prosthetic.dm @@ -0,0 +1,17 @@ +/datum/preference/choiced/prosthetic + category = PREFERENCE_CATEGORY_SECONDARY_FEATURES + savefile_key = "prosthetic" + savefile_identifier = PREFERENCE_CHARACTER + +/datum/preference/choiced/prosthetic/init_possible_values() + return list("Random") + GLOB.limb_choice + +/datum/preference/choiced/prosthetic/is_accessible(datum/preferences/preferences) + . = ..() + if (!.) + return FALSE + + return "Prosthetic Limb" in preferences.all_quirks + +/datum/preference/choiced/prosthetic/apply_to_human(mob/living/carbon/human/target, value) + return diff --git a/code/modules/clothing/belts/polymorph_belt.dm b/code/modules/clothing/belts/polymorph_belt.dm index e63e2c3bee3..73959d6d415 100644 --- a/code/modules/clothing/belts/polymorph_belt.dm +++ b/code/modules/clothing/belts/polymorph_belt.dm @@ -35,8 +35,8 @@ return slot & ITEM_SLOT_BELT /obj/item/polymorph_belt/update_icon_state() - icon_state = base_icon_state + (active) ? "" : "_inactive" - worn_icon_state = base_icon_state + (active) ? "" : "_inactive" + icon_state = base_icon_state + (active ? "" : "_inactive") + worn_icon_state = base_icon_state + (active ? "" : "_inactive") return ..() /obj/item/polymorph_belt/attackby(obj/item/weapon, mob/user, params) diff --git a/code/modules/clothing/ears/_ears.dm b/code/modules/clothing/ears/_ears.dm index c4001d23629..5ae5b628808 100644 --- a/code/modules/clothing/ears/_ears.dm +++ b/code/modules/clothing/ears/_ears.dm @@ -20,6 +20,7 @@ equip_delay_other = 25 resistance_flags = FLAMMABLE custom_price = PAYCHECK_COMMAND * 1.5 + flags_cover = EARS_COVERED /obj/item/clothing/ears/earmuffs/Initialize(mapload) . = ..() diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index fc665e57c8f..4c7fce6633c 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -352,6 +352,18 @@ glass_colour_type = /datum/client_colour/glass_colour/gray dog_fashion = /datum/dog_fashion/head +/obj/item/clothing/glasses/sunglasses/Initialize(mapload) + . = ..() + add_glasses_slapcraft_component() + +/obj/item/clothing/glasses/sunglasses/proc/add_glasses_slapcraft_component() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/hudsunsec, /datum/crafting_recipe/hudsunmed, /datum/crafting_recipe/hudsundiag, /datum/crafting_recipe/scienceglasses) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/clothing/glasses/sunglasses/reagent name = "beer goggles" icon_state = "sunhudbeer" @@ -364,6 +376,14 @@ desc = "A pair of tacky purple sunglasses that allow the wearer to recognize various chemical compounds with only a glance." clothing_traits = list(TRAIT_REAGENT_SCANNER, TRAIT_RESEARCH_SCANNER) +/obj/item/clothing/glasses/sunglasses/chemical/add_glasses_slapcraft_component() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/scienceglassesremoval) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/clothing/glasses/sunglasses/gar name = "black gar glasses" desc = "Go beyond impossible and kick reason to the curb!" diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 5018e4185c8..34359eaa0b3 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -92,6 +92,15 @@ tint = 1 glass_colour_type = /datum/client_colour/glass_colour/blue +/obj/item/clothing/glasses/hud/health/sunglasses/Initialize(mapload) + . = ..() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/hudsunmedremoval) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/clothing/glasses/hud/diagnostic name = "diagnostic HUD" desc = "A heads-up display capable of analyzing the integrity and status of robotics and exosuits." @@ -118,6 +127,15 @@ flash_protect = FLASH_PROTECTION_FLASH tint = 1 +/obj/item/clothing/glasses/hud/diagnostic/sunglasses/Initialize(mapload) + . = ..() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/hudsundiagremoval) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/clothing/glasses/hud/security name = "security HUD" desc = "A heads-up display that scans the humanoids in view and provides accurate data about their ID status and security records." @@ -152,6 +170,15 @@ tint = 1 glass_colour_type = /datum/client_colour/glass_colour/darkred +/obj/item/clothing/glasses/hud/security/sunglasses/Initialize(mapload) + . = ..() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/hudsunsecremoval) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/clothing/glasses/hud/security/night name = "night vision security HUD" desc = "An advanced heads-up display that provides ID data and vision in complete darkness." diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index d3aed125749..f77f6cc2c67 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -26,6 +26,16 @@ ) ) // SKYRAT EDIT ADDITION END + +/obj/item/clothing/gloves/color/black/Initialize(mapload) + . = ..() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/radiogloves) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/clothing/gloves/fingerless name = "fingerless gloves" desc = "Plain black gloves without fingertips for the hard-working." @@ -39,6 +49,15 @@ undyeable = TRUE clothing_traits = list(TRAIT_FINGERPRINT_PASSTHROUGH) +/obj/item/clothing/gloves/color/fingerless/Initialize(mapload) + . = ..() + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/gripperoffbrand) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/clothing/gloves/color/orange name = "orange gloves" desc = "A pair of gloves, they don't look special in any way." diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 488bd7448a7..f8cd88923ec 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -12,7 +12,7 @@ max_heat_protection_temperature = HELMET_MAX_TEMP_PROTECT strip_delay = 60 clothing_flags = SNUG_FIT | STACKABLE_HELMET_EXEMPT - flags_cover = HEADCOVERSEYES + flags_cover = HEADCOVERSEYES|EARS_COVERED flags_inv = HIDEHAIR dog_fashion = /datum/dog_fashion/head/helmet diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 4022e259505..76194e721b6 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -246,7 +246,7 @@ var/prefix_index = findtext(raw_message, prefix) if(prefix_index != 1) return FALSE - + var/the_phrase = trim_left(replacetext(raw_message, prefix, "")) var/obj/item/result = items_by_phrase[the_phrase] if(!result) @@ -592,6 +592,83 @@ icon_state = "surgicalcapblack" desc = "A black medical surgery cap to prevent the surgeon's hair from entering the insides of the patient!" +/obj/item/clothing/head/utility/head_mirror + name = "head mirror" + desc = "Used by doctors to look into a patient's eyes, ears, and mouth. \ + A little useless now, given the technology available, but it certainly completes the look." + icon_state = "headmirror" + body_parts_covered = NONE + +/obj/item/clothing/head/utility/head_mirror/examine(mob/user) + . = ..() + . += span_notice("In a properly lit room, you can use this to examine people's eyes, ears, and mouth closer.") + +/obj/item/clothing/head/utility/head_mirror/equipped(mob/living/user, slot) + . = ..() + if(slot & slot_flags) + RegisterSignal(user, COMSIG_MOB_EXAMINING_MORE, PROC_REF(examining)) + else + UnregisterSignal(user, COMSIG_MOB_EXAMINING_MORE) + +/obj/item/clothing/head/utility/head_mirror/dropped(mob/living/user) + . = ..() + UnregisterSignal(user, COMSIG_MOB_EXAMINING_MORE) + +/obj/item/clothing/head/utility/head_mirror/proc/examining(mob/living/examiner, atom/examining, list/examine_list) + SIGNAL_HANDLER + if(!ishuman(examining) || examining == examiner || examiner.is_blind() || !examiner.Adjacent(examining)) + return + var/mob/living/carbon/human/human_examined = examining + if(!human_examined.get_bodypart(BODY_ZONE_HEAD)) + return + if(!examiner.has_light_nearby()) + examine_list += span_warning("You attempt to use your [name] to examine [examining]'s head better... but it's too dark. Should've invested in a head lamp.") + return + if(examiner.dir == examining.dir) // disallow examine from behind - every other dir is OK + examine_list += span_warning("You attempt to use your [name] to examine [examining]'s head better... but [examining.p_theyre()] facing the wrong way.") + return + + var/list/final_message = list("You examine [examining]'s head closer with your [name], you notice [examining.p_they()] [examining.p_have()]...") + if(human_examined.is_mouth_covered()) + final_message += "\tYou can't see [examining.p_their()] mouth." + else + var/obj/item/organ/internal/tongue/has_tongue = human_examined.get_organ_slot(ORGAN_SLOT_TONGUE) + var/pill_count = 0 + for(var/datum/action/item_action/hands_free/activate_pill/pill in human_examined.actions) + pill_count++ + + if(pill_count >= 1 && has_tongue) + final_message += "\t[pill_count] pill\s in [examining.p_their()] mouth, and \a [has_tongue]." + else if(pill_count >= 1) + final_message += "\t[pill_count] pill\s in [examining.p_their()] mouth, but oddly no tongue." + else if(has_tongue) + final_message += "\t\A [has_tongue] in [examining.p_their()] mouth - go figure." + else + final_message += "\tNo tongue in [examining.p_their()] mouth, oddly enough." + + if(human_examined.is_ears_covered()) + final_message += "\tYou can't see [examining.p_their()] ears." + else + var/obj/item/organ/internal/ears/has_ears = human_examined.get_organ_slot(ORGAN_SLOT_EARS) + if(has_ears) + if(has_ears.deaf) + final_message += "\tDamaged eardrums in [examining.p_their()] ear canals." + else + final_message += "\tA set of [has_ears.damage ? "" : "healthy "][has_ears.name]." + else + final_message += "\tNo eardrums and empty ear canals... how peculiar." + + if(human_examined.is_eyes_covered()) + final_message += "\tYou can't see [examining.p_their()] eyes." + else + var/obj/item/organ/internal/eyes/has_eyes = human_examined.get_organ_slot(ORGAN_SLOT_EYES) + if(has_eyes) + final_message += "\tA pair of [has_eyes.damage ? "" : "healthy "][has_eyes.name]." + else + final_message += "\tEmpty eye sockets." + + examine_list += span_notice("[jointext(final_message, "\n")]") + //Engineering /obj/item/clothing/head/beret/engi name = "engineering beret" diff --git a/code/modules/clothing/masks/_masks.dm b/code/modules/clothing/masks/_masks.dm index dfcc3060c9f..ad296d30356 100644 --- a/code/modules/clothing/masks/_masks.dm +++ b/code/modules/clothing/masks/_masks.dm @@ -12,6 +12,10 @@ var/adjusted_flags = null ///Did we install a filtering cloth? var/has_filter = FALSE + /// If defined, what voice should we override with if TTS is active? + var/voice_override + /// If set to true, activates the radio effect on TTS. Used for sec hailers, but other masks can utilize it for their own vocal effect. + var/use_radio_beeps_tts = FALSE /obj/item/clothing/mask/attack_self(mob/user) if((clothing_flags & VOICEBOX_TOGGLABLE)) diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 7b415bac6dc..c8784d9af6c 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -28,7 +28,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( var/has_fov = TRUE ///Cigarette in the mask var/obj/item/clothing/mask/cigarette/cig - + voice_filter = "lowpass=f=750,volume=2" /datum/armor/mask_gas bio = 100 @@ -274,6 +274,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( dog_fashion = /datum/dog_fashion/head/clown has_fov = FALSE var/list/clownmask_designs = list() + voice_filter = null // performer masks expect to be talked through /obj/item/clothing/mask/gas/clown_hat/plasmaman starting_filter_type = /obj/item/gas_filter/plasmaman diff --git a/code/modules/clothing/masks/hailer.dm b/code/modules/clothing/masks/hailer.dm index af1d3975645..64de19b95aa 100644 --- a/code/modules/clothing/masks/hailer.dm +++ b/code/modules/clothing/masks/hailer.dm @@ -68,6 +68,8 @@ GLOBAL_LIST_INIT(hailer_phrases, list( var/recent_uses = 0 ///Whether the hailer is emagged or not var/safety = TRUE + voice_filter = @{"[0:a] asetrate=%SAMPLE_RATE%*0.7,aresample=16000,atempo=1/0.7,lowshelf=g=-20:f=500,highpass=f=500,aphaser=in_gain=1:out_gain=1:delay=3.0:decay=0.4:speed=0.5:type=t [out]; [out]atempo=1.2,volume=15dB [final]; anoisesrc=a=0.01:d=60 [noise]; [final][noise] amix=duration=shortest"} + use_radio_beeps_tts = TRUE /obj/item/clothing/mask/gas/sechailer/plasmaman starting_filter_type = /obj/item/gas_filter/plasmaman diff --git a/code/modules/clothing/shoes/cowboy.dm b/code/modules/clothing/shoes/cowboy.dm index e6f02264d35..05792a72cbd 100644 --- a/code/modules/clothing/shoes/cowboy.dm +++ b/code/modules/clothing/shoes/cowboy.dm @@ -17,7 +17,7 @@ if(prob(2)) //There's a snake in my boot - new /mob/living/simple_animal/hostile/retaliate/snake(src) + new /mob/living/basic/snake(src) /obj/item/clothing/shoes/cowboy/equipped(mob/living/carbon/user, slot) @@ -56,7 +56,7 @@ if(contents.len >= max_occupants) to_chat(user, span_warning("[src] are full!")) return - if(istype(target, /mob/living/simple_animal/hostile/retaliate/snake) || istype(target, /mob/living/basic/headslug) || islarva(target)) + if(istype(target, /mob/living/basic/snake) || istype(target, /mob/living/basic/headslug) || islarva(target)) target.forceMove(src) to_chat(user, span_notice("[target] slithers into [src].")) diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm index 9537fa7b6ef..6c33e287f03 100644 --- a/code/modules/clothing/suits/reactive_armour.dm +++ b/code/modules/clothing/suits/reactive_armour.dm @@ -226,7 +226,7 @@ emp_message = span_warning("The tesla capacitors beep ominously for a moment.") clothing_traits = list(TRAIT_TESLA_SHOCKIMMUNE) /// How strong are the zaps we give off? - var/zap_power = 25000 + var/zap_power = 1e7 /// How far to the zaps we give off go? var/zap_range = 20 /// What flags do we pass to the zaps we give off? diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index 2f29a2233d5..bbd880f5466 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -104,6 +104,7 @@ laser = 20 energy = 30 bomb = 100 + bio = 50 fire = 80 acid = 50 diff --git a/code/modules/events/ghost_role/sentience.dm b/code/modules/events/ghost_role/sentience.dm index caf49e13b6b..da380278608 100644 --- a/code/modules/events/ghost_role/sentience.dm +++ b/code/modules/events/ghost_role/sentience.dm @@ -4,17 +4,17 @@ GLOBAL_LIST_INIT(high_priority_sentience, typecacheof(list( /mob/living/basic/carp/pet/cayenne, /mob/living/basic/chicken, /mob/living/basic/cow, - /mob/living/basic/spider/giant/sgt_araneus, /mob/living/basic/lizard, /mob/living/basic/mouse/brown/tom, /mob/living/basic/pet, /mob/living/basic/pig, /mob/living/basic/rabbit, /mob/living/basic/sheep, + /mob/living/basic/snake, + /mob/living/basic/spider/giant/sgt_araneus, /mob/living/simple_animal/bot/secbot/beepsky, /mob/living/simple_animal/hostile/retaliate/goat, /mob/living/simple_animal/hostile/retaliate/goose/vomit, - /mob/living/simple_animal/hostile/retaliate/snake, /mob/living/simple_animal/parrot, /mob/living/simple_animal/pet, /mob/living/simple_animal/sloth, diff --git a/code/modules/events/mice_migration.dm b/code/modules/events/mice_migration.dm index e7f31567f4c..450f9100800 100644 --- a/code/modules/events/mice_migration.dm +++ b/code/modules/events/mice_migration.dm @@ -23,7 +23,7 @@ priority_announce("Due to [cause], [plural] [name] have [movement] \ into the [location].", "Migration Alert", - 'sound/effects/mousesqueek.ogg') + 'sound/creatures/mousesqueek.ogg') /datum/round_event/mice_migration/start() SSminor_mapping.trigger_migration(rand(minimum_mice, maximum_mice)) diff --git a/code/modules/events/wizard/petsplosion.dm b/code/modules/events/wizard/petsplosion.dm index 7ca7ef2ba2d..33f7718f740 100644 --- a/code/modules/events/wizard/petsplosion.dm +++ b/code/modules/events/wizard/petsplosion.dm @@ -5,7 +5,6 @@ GLOBAL_LIST_INIT(petsplosion_candidates, typecacheof(list( /mob/living/basic/carp/pet/cayenne, /mob/living/basic/chicken, /mob/living/basic/cow, - /mob/living/basic/spider/giant/sgt_araneus, /mob/living/basic/lizard, /mob/living/basic/mothroach, /mob/living/basic/mouse/brown/tom, @@ -13,9 +12,10 @@ GLOBAL_LIST_INIT(petsplosion_candidates, typecacheof(list( /mob/living/basic/pig, /mob/living/basic/rabbit, /mob/living/basic/sheep, + /mob/living/basic/snake, + /mob/living/basic/spider/giant/sgt_araneus, /mob/living/simple_animal/hostile/retaliate/goat, /mob/living/simple_animal/hostile/retaliate/goose/vomit, - /mob/living/simple_animal/hostile/retaliate/snake, /mob/living/simple_animal/parrot, /mob/living/simple_animal/pet, /mob/living/simple_animal/sloth, diff --git a/code/modules/experisci/experiment/experiments.dm b/code/modules/experisci/experiment/experiments.dm index ab971196092..1959a849598 100644 --- a/code/modules/experisci/experiment/experiments.dm +++ b/code/modules/experisci/experiment/experiments.dm @@ -44,7 +44,7 @@ /mob/living/basic/chicken, /mob/living/basic/cow, /mob/living/basic/pet/dog/corgi, - /mob/living/simple_animal/hostile/retaliate/snake, + /mob/living/basic/snake, /mob/living/simple_animal/pet/cat, ) @@ -234,7 +234,7 @@ /obj/machinery/biogenerator = 3, /obj/machinery/gibber = 3, /obj/machinery/chem_master = 3, - /obj/machinery/atmospherics/components/unary/cryo_cell = 3, + /obj/machinery/cryo_cell = 3, /obj/machinery/harvester = 5, /obj/machinery/quantumpad = 5 ) diff --git a/code/modules/explorer_drone/control_console.dm b/code/modules/explorer_drone/control_console.dm index 7b371e8412b..8cc8854f27d 100644 --- a/code/modules/explorer_drone/control_console.dm +++ b/code/modules/explorer_drone/control_console.dm @@ -1,6 +1,6 @@ /obj/machinery/computer/exodrone_control_console name = "exploration drone control console" - desc = "control eploration drones from intersteller distances. Communication lag not included." + desc = "Control exploration drones from interstellar distances. Communication lag not included." circuit = /obj/item/circuitboard/computer/exodrone_console //Currently controlled drone var/obj/item/exodrone/controlled_drone diff --git a/code/modules/explorer_drone/example_adventures/Theres_a_tree_in_the_middle_of_space.json b/code/modules/explorer_drone/example_adventures/Theres_a_tree_in_the_middle_of_space.json index 3f9ee41582e..f06b1d25062 100644 --- a/code/modules/explorer_drone/example_adventures/Theres_a_tree_in_the_middle_of_space.json +++ b/code/modules/explorer_drone/example_adventures/Theres_a_tree_in_the_middle_of_space.json @@ -1,343 +1,356 @@ { - "adventure_name": "There's a tree in the middle of space.", - "version": 1, - "starting_node": "Tree Start", - "starting_qualities": { - "Confusion": 0 - }, - "required_site_traits": [ - "in space" - ], - "loot_categories": [ - "research" - ], - "scan_band_mods": { - "Exotic Radiation": 10 - }, - "deep_scan_description": "", - "triggers": [ - { - "name": "Confusion Trigger", - "target_node": "What is wrong with this tree?", - "requirements": [ - { - "quality": "Confusion", - "operator": ">", - "value": 30 - } - ] - } - ], - "nodes": [ - { - "name": "Tree Start", - "description": "Camera online. Visual signs detect a fully grown, seemingly biological, and live tree located in the middle of the vacuum.\nSensors indicate it is not oxygenating, but energy is being collected via passive solar light from the nearby star.\nBaffling.", - "choices": [ - { - "key": "choice 0", - "name": "Ignore site.", - "exit_node": "FAIL", - "delay": 10, - "delay_message": "Leave this for the botanists to figure out." - }, - { - "key": "choice 1", - "name": "Begin sensor scan.", - "exit_node": "Biological Scan", - "delay": 10, - "delay_message": "Lets get some data." - } - ], - "image": null, - "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMQAAAAAAAC15h2QtxeAoxVykROizRpxjxIAcgAAWwAAgAAAUAAAZAAAZgC0tLTKysr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/2AgjmRpnigqrMMqtCvhyvFs17hQuPva67ygTwgcGovA3a61BLaeryj0mapar9isNjCNylpfgWwsLpPPZqBst066le84fB5nRpvdvGDL7/v/JmBeaWiFhIeGbGqLio1ljm2CklKUA4CXmJmaAYidhp9mBmOiYqQEpqZlk3qbra6vsCOenqijtgIHCLG7vL29CQoNCsDCxMPBxw0MxsTLyMLCCwq+1LuVe9VZ0M/c297d4NvZ41vXeueU5N/r4e3o79jkvOb0UAe4+Pf6uMjS7P/TtAAcGKyeQXhT5ClcSKIdwYcHIyKMx7CiwocOwU3cWMmiR4YYQzqM+LGkSQXSUv/2y0jQH0qUJmNqoRSm5ixQbXLK2UmnJ886ToIilFltkk2cNw9B+umz6U87UOsRNXk0KdKrVrOSWWVwqlc+WHHWKnWqrKizZV+QGrA2yte31YDJPTZXrrMEzhbkPSYNWF+4gAFBeICJGTLDxVi2C5yNIxSQikVu48i4j8TLT1i2khwOM+bKVSQaeGLgQOnS+fIBwkiCszfPjqWAnn0ism1hsXO/oM279e3fuqmYeAChN++XKqP9BujP+EcXMKLkoFFm+o3qSH5oJ7L9SPfs3IlEHw/dhfNyLMpbX4+duvvw3uGDj08fCfn0+KVTPI9Ff/T37AHY3nXfFSifgfX9cJ//f/vxh95/1wkoYYQU5oDgfBh+t+B9DsJS4YABfiiDAWWQOGKJKJ6oYidcDdVhUVrFGFZWRl32IlEy0nJLWjyu1VYYrNxY2YxXjZUWW1+0FaSQDiaQ4z0y3OMXX3wxaSUKiWWZTF5c+sVASl8iB9OVbxFH3CVabmOMa9yQ6WYAbHL2Zh+UVRTnbV3NyUlwu120HEuw9WlloO+Mc+c3fCbEH6ES/Ybmn9AwWmdvnu1jaWoHpMBmFYdK+tmLiQqKCaTAebqRnh4d6o6pEqHqEan/sOqiqxbBumqoig42GK0WqUqQY7zCtZKvDgXL37AvEbvNAsaeJ6Zy0JKqErPNYpIj/xqOOKUtU9xu6+1OUekpCJFpLPXtud2mu21UTbhKLraPqCsvuvQ+FdQSqI57bbnxtlHvv/OCK5RsqO4Lr78BA6xwulDR+m4n5iYs8cJNVNyguwYzEi/FE3dsR7UpZJzIxh1z7FO4IJ8gMr860WuAEi/rEHMBM88s8ccpn/AwVhEjTDPMQMsc9M9Cx9HyIJbknMLOEJNC8xpOR/3zy1RPbXXVWD8tM9Rcq3Kx0lesvKORZz2NFtVmnWJ2j2NLAnYsiJCd9tlzz7122XTnnfbb2dxUi96A1x044GDwnc0Zfwuu+OCLK274c4UkzvjkZj3+ldxkUY5AApt3noDlldF1zP/YBAyzuemcp4665wGBDlcDeCUA+zKzyx77Arfnvjnuy+C+u+uADXPXMsTHXvzxxid/PPC8OEAYmnLBPoz0ttMee+3YXx/958y/oqsDl4hel/jkjz9+Md17Rf3620/fvu3uxy97A+lPVT75ic2lJWLDWD7AE/97QQCT1qv3sU9+6ytGAxTIQL7FpiLJiCD/JggOYJxKXAPMIAA3KCp1MHB6H5wfCEcowgRoUIAc/F8L3CSrr/EiGAsc4QKhEcMZwpCG0DihClHIQxVeaYdA1KEQAWioD9pQhEesoRJTOMQe/k9ITQwiEzloQ/q9sIpKxOENt9iAKHpxgw76ohOnKED/LWJRGJrIIhfVWEUxSnGMPDQOGd+4wwME0I76COAC2MhHNPZhjWbk4xzd2MTeNBGPuBiAPg6wyEbiIlMiaEBKYrjHQOJQG5YE5BbpSMhByvGQiixNKBlpGlI+8h5a0OQZg2ECVfYRhoOMJRx36JxZ/k+UbMGjKEupyERi4pUzjGQmV9lGWXLSkxiMoy+ICcxmNsCWxvRi/VYzw2pa85rYvKYKt8nNbnrzm96c5h+G6UwudhKacBTnOLPJznYuEJzwjCc41blOctoTlug8JjTpiSZ3+lOb3LTj/wSqSHlycwQPeB4//8jMe2KRgwJNZDQJaCaFLlQge6ykJP/ZTo3iYbGgHx3oPC+6CZRQspwNNakwEMnSE5L0FRndaEwXqFGO0lSmG32pQmLK043e1KYz7KlO5dHTouKUo0YdKjmMalSk4jSmSh3HAqb61KpqtKZBtWpOo1oNpmoVq9dkKrWMEwIAOw==" - }, - { - "name": "Biological Scan", - "description": "You attempt to scan for clues regarding the tree's nature. It appears to be a fully mature oak tree. \n\nApproximated height is 13 ft, 6.4 inches. \n\nSubject sees no sign of an outer coating or otherwise layer protecting it from the void of space.\n\nSubject's surface temperature is 293.7 kelvin, as though it were sitting indoors.", - "choices": [ - { - "key": "choice 2", - "name": "Check Sensor Integrity.", - "exit_node": "Its Not You...", - "on_selection_effects": [ - { - "effect_type": "Add", - "quality": "Confusion", - "value": 5 - } - ], - "delay": 50, - "delay_message": "This can't be right." - }, - { - "key": "choice 4", - "name": "Attempt to take sample.", - "exit_node": "Sample Taken", - "on_selection_effects": [ - { - "effect_type": "Add", - "quality": "Confusion", - "value": 3 - } - ], - "delay": 40, - "delay_message": "Snip snip." - }, - { - "key": "choice 6", - "name": "Examine Tree Roots.", - "exit_node": "Examine Roots", - "delay": 10 - }, - { - "key": "choice 9", - "name": "Sequence Sample Radiation with background noise.", - "exit_node": "Background Analysis", - "requirements": [ - { - "quality": "Sample", - "operator": ">=", - "value": 1 - } - ], - "delay": 0, - "delay_message": "This can't be real." - } - ], - "image": null, - "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMQAAAAAAAC15h2QtxeAoxVykROizRpxjxIAcgAAWwAAgAAAUAAAZAAAZgC0tLTKysr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/2AgjmRpnigqrMMqtCvhyvFs17hQuPva67ygTwgcGovA3a61BLaeryj0mapar9isNjCNylpfgWwsLpPPZqBst066le84fB5nRpvdvGDL7/v/JmBeaWiFhIeGbGqLio1ljm2CklKUA4CXmJmaAYidhp9mBmOiYqQEpqZlk3qbra6vsCOenqijtgIHCLG7vL29CQoNCsDCxMPBxw0MxsTLyMLCCwq+1LuVe9VZ0M/c297d4NvZ41vXeueU5N/r4e3o79jkvOb0UAe4+Pf6uMjS7P/TtAAcGKyeQXhT5ClcSKIdwYcHIyKMx7CiwocOwU3cWMmiR4YYQzqM+LGkSQXSUv/2y0jQH0qUJmNqoRSm5ixQbXLK2UmnJ886ToIilFltkk2cNw9B+umz6U87UOsRNXk0KdKrVrOSWWVwqlc+WHHWKnWqrKizZV+QGrA2yte31YDJPTZXrrMEzhbkPSYNWF+4gAFBeICJGTLDxVi2C5yNIxSQikVu48i4j8TLT1i2khwOM+bKVSQaeGLgQOnS+fIBwkiCszfPjqWAnn0ism1hsXO/oM279e3fuqmYeAChN++XKqP9BujP+EcXMKLkoFFm+o3qSH5oJ7L9SPfs3IlEHw/dhfNyLMpbX4+duvvw3uGDj08fCfn0+KVTPI9Ff/T37AHY3nXfFSifgfX9cJ//f/vxh95/1wkoYYQU5oDgfBh+t+B9DsJS4YABfiiDAWWQOGKJKJ6oYidcDdVhUVrFGFZWRl32IlEy0nJLWjyu1VYYrNxY2YxXjZUWW1+0FaSQDiaQ4z0y3OMXX3wxaSUKiWWZTF5c+sVASl8iB9OVbxFH3CVabmOMa9yQ6WYAbHL2Zh+UVRTnbV3NyUlwu120HEuw9WlloO+Mc+c3fCbEH6ES/Ybmn9AwWmdvnu1jaWoHpMBmFYdK+tmLiQqKCaTAebqRnh4d6o6pEqHqEan/sOqiqxbBumqoig42GK0WqUqQY7zCtZKvDgXL37AvEbvNAsaeJ6Zy0JKqErPNYpIj/xqOOKUtU9xu6+1OUekpCJFpLPXtud2mu21UTbhKLraPqCsvuvQ+FdQSqI57bbnxtlHvv/OCK5RsqO4Lr78BA6xwulDR+m4n5iYs8cJNVNyguwYzEi/FE3dsR7UpZJzIxh1z7FO4IJ8gMr860WuAEi/rEHMBM88s8ccpn/AwVhEjTDPMQMsc9M9Cx9HyIJbknMLOEJNC8xpOR/3zy1RPbXXVWD8tM9Rcq3Kx0lesvKORZz2NFtVmnWJ2j2NLAnYsiJCd9tlzz7122XTnnfbb2dxUi96A1x044GDwnc0Zfwuu+OCLK274c4UkzvjkZj3+ldxkUY5AApt3noDlldF1zP/YBAyzuemcp4665wGBDlcDeCUA+zKzyx77Arfnvjnuy+C+u+uADXPXMsTHXvzxxid/PPC8OEAYmnLBPoz0ttMee+3YXx/958y/oqsDl4hel/jkjz9+Md17Rf3620/fvu3uxy97A+lPVT75ic2lJWLDWD7AE/97QQCT1qv3sU9+6ytGAxTIQL7FpiLJiCD/JggOYJxKXAPMIAA3KCp1MHB6H5wfCEcowgRoUIAc/F8L3CSrr/EiGAsc4QKhEcMZwpCG0DihClHIQxVeaYdA1KEQAWioD9pQhEesoRJTOMQe/k9ITQwiEzloQ/q9sIpKxOENt9iAKHpxgw76ohOnKED/LWJRGJrIIhfVWEUxSnGMPDQOGd+4wwME0I76COAC2MhHNPZhjWbk4xzd2MTeNBGPuBiAPg6wyEbiIlMiaEBKYrjHQOJQG5YE5BbpSMhByvGQiixNKBlpGlI+8h5a0OQZg2ECVfYRhoOMJRx36JxZ/k+UbMGjKEupyERi4pUzjGQmV9lGWXLSkxiMoy+ICcxmNsCWxvRi/VYzw2pa85rYvKYKt8nNbnrzm96c5h+G6UwudhKacBTnOLPJznYuEJzwjCc41blOctoTlug8JjTpiSZ3+lOb3LTj/wSqSHlycwQPeB4//8jMe2KRgwJNZDQJaCaFLlQge6ykJP/ZTo3iYbGgHx3oPC+6CZRQspwNNakwEMnSE5L0FRndaEwXqFGO0lSmG32pQmLK043e1KYz7KlO5dHTouKUo0YdKjmMalSk4jSmSh3HAqb61KpqtKZBtWpOo1oNpmoVq9dkKrWMEwIAOw==" - }, - { - "name": "Its Not You...", - "description": "After re-connection is established, your sensors appear fine. Tree has not moved in the slightest since last observed. Temperature has fluxuated 0.2 kelvin upwards, as expected of a plant under direct light.\nLets try again.", - "choices": [ - { - "key": "choice 3", - "name": "Restart biological scan.", - "exit_node": "Biological Scan", - "delay": 25, - "delay_message": "God damnit." - } - ], - "image": null, - "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD////v7+/h4eEAAAAAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZBkJaJqaLKOubSy7b23fODxPOb7/m4FASBRofEBeT1W6JU3DYaRIjQqfkCWKg1xoddjSQEgQlM/mdDkc0Fa+8PiWLSIM7Pj73RxOlVF/ITlKNXSGDXp5iiFoaBlqfpFyk12HMgSYmZkfmppmmJ8gjXwUf2lglqmqq6ytrq+wsbKztLW2t7i5um2Ug669uyBCKMNRc4Q9qXHBJlVUFMbRV6pfR04ONszQzlZRlm7IveLaimZ7eJAESUsfyVnX2hfqv/Nv4vfZ8RWJ/Hkdn6NGtRsFyEg4VLwK6UvVqROdgMcWSpxIsaLFixgzatzIsf+jR1gIP7YbN6uaSAn4wFGbdNJFsZcpFRqS09IBt2kW3CkzWdNmNyIYpIWkw9Nevgbwat2ccNPbTnbWjtKQWfGnVZwzoQaNqVXXkDFWGx3qeoIry2CJzJ05p6aPTpRmfSXV1a/u2jM7TuldA8LXO6kXFemh5ihn3Lc9A9h1ZaqxpMNkK9rl5+EMKIGM9g5FSjJjv4aVOwEc/Q8iXx6ODSo5ualOQ9Bs0qVJTLu27du4c+vezbu379/AgwsfTry48ePIkytfqHp5xhfLadby+1soMJDLbhchlqIYpVbXa14dz718NMBEz/ZsWsU8zMhY1CdmL+VE+/ObgWSvPR4rj/f/xqxUFG1fVfHIUgLCN58zR5ABySpwbAAdZ1TNMgZYF9YHjWmsDAgNeglNqFSBJJYiG14JUmcYiHNZWJcE6HD4FGIrVuiFjROxJeNYChoFWUS5lBPjOTO2iM2PKuki2F1qfdPjjUjSeMuSk82Uml4fRimlLVR2OUAYBGHpo5aV4OJll1iYRkqWhag4FY75WXhmlTOoedo/ZVKI40Jz+pOEnX2ZsqcCeVJ0piEQieJhiEx0RBkrd6J2IiQFVXqPbZjEYqdmll6Jz0avtUaCqEFtaiqnekmHUagOhSZapvJMeioanXa2KqukZoCrJoruCKNmCngKZGC7urprPRKq+QZBP2XFKRGunBwL6waZjIbiBInu9hoj0o5wraRiOadrsX1kK24HvBK25rnstuvuu/DGK++89NZr77345qvvvhYlAAA7" - }, - { - "name": "Sample Taken", - "description": "You collect and project a small sample of tree bark off the plant. The instant that the bark is removed from the tree, as though it suddenly remembered what it was, the moisture content of the bark freezes over, and implodes into small microparticles of splinters.\nSmall radioactive signature detected.", - "choices": [ - { - "key": "choice 5", - "name": "Well that was... unexpected.", - "exit_node": "Biological Scan", - "delay": 0, - "delay_message": "Maybe something else might work better.", - "on_selection_effects": [ - { - "effect_type": "Add", - "quality": "Sample", - "value": 1 - } - ] - } - ], - "image": null, - "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAABSLiiPVjtyRS9mOTFbNyYAAAAD/xi63P4wykmrvTjrzbv/YCiOZGmeaKqubOu+sDUQxTDbeK7vfF/3saCwcxPcCMckcqlM2pDPnnRKrUqH2IdAYDBwu+Bwl2Agm8sE8iy9Zrqbb2Z0bq3b74W8Xp+1bP+Af2KDhIVlh2eJaUtsi3CPcU43d5QDe5cFfSKBnJ2en50Ff6JboqYCBWiLq46tkK+RUJOTmJmatxyguqSovae/vsGirK2NjU21trjLQp+8wNDCwnmo1MnM2Nna29zd3t/g4eLj5OXm59o5Rjo/QOjvLaKwkrKylfdW8FleXImIBm0CxppXD4c9fAgT5tCn4Iuhh4fG/DNTjNHAi4/oKERYq/+cro8gPYXxR7EkK4EEUxbUOCVZHoabQoZ8NkqaKWI4BR7DGKcjTG4yaZaySRSatQLGfP5ciqHX0GhQpzGdSrWq1atYs2rdyrWr169gw4pVsc7G2LMLkM46SOkl2nc86W3E97aFgLh4Dc7dq6NuhC0TVVlUOY8l38N9szocREYiyYqEMdJZibjylW+AIRIiqUowyrwDJ+u1XMelsm6CNKtmHHiRZ8iuQGecVdklZpm4V3NWREznYNmhaeNRCg638eOBhrUWjPP3zshNDNuwzRW5dZrQmms3BhzSNb8SrIPCXvTudtjzMIEngVxo+ajDtKOkvt5u0Jrw3/s6yqd+Nk7/7uUn4FH+VaWfKAUmqOCCDDbo4IMQRijhhBRWaOGFGGao4YYcdujhhyCGKOKFRsgxy4jaBEeZOyi60J2JK1piS2ItcvDiaMIpVGMEv0GnIo46grgFbM/dKBppC004kXzo3fiGdJb51wUgiKTBnHNOzsYWkpd1xZpjrTHJnY+vQGlZOztMBUZmrO0mZo9Zwggkl/mkKc5qIy3n2nlExrnWnHROcRueYjSm55Wr+Ebmj2YeZpo4bBJqyG6Inqeon0duRF84kuJJKW98Nrkojlu2dYlHkXaq6qehNvfZqHI2+ihq4lGpKhisttpbbKNm6sN3t9Wam2q5Vtrqq5jesKk3jsI220mheuq665jJzoqqs9gGcqi0211KGLBUZYutciUZG6q3cREnlrjiPcZtTqIiAW597H5E07uuiqqehPXONIq57+6rYb81PWUTvmksuyHBTjUc1XnVmOLWjgFkG+CBNk1MsRb1kiegLxtf4KzHB4b8Qa0XA2OyfZ6QjODKywwlM8w012zzzTjnrPNWCQAAOw==" - }, - { - "name": "Examine Roots", - "description": "All plant matter has to derive energy and moisture from someplace. Examining the oak tree's roots reveals that the roots present all appear to splay out, similar to how a normal tree would. However, those roots then proceed to double back in on itself. This might suggest that the tree is obtaining nutrients from... itself.", - "choices": [ - { - "key": "choice 7", - "name": "That's fucking stupid.", - "exit_node": "Biological Scan", - "on_selection_effects": [ - { - "effect_type": "Add", - "quality": "Confusion", - "value": { - "value_type": "random", - "low": 6, - "high": 10 - } - } - ], - "delay": 0, - "delay_message": "What the hell kind of tree even IS this?" - }, - { - "key": "choice 8", - "name": "Obtain biological sample from roots.", - "exit_node": "Sample Taken", - "delay": 10, - "delay_message": "This is why we hire botanists on-site." - } - ], - "image": null, - "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMQAAAAAAAC15h2QtxeAoxVykROizRpxjxIAcgAAWwAAgAAAUAAAZAAAZgC0tLTKysr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/2AgjmRpnigqrMMqtCvhyvFs17hQuPva67ygTwgcGovA3a61BLaeryj0mapar9isNjCNylpfgWwsLpPPZqBst066le84fB5nRpvdvGDL7/v/JmBeaWiFhIeGbGqLio1ljm2CklKUA4CXmJmaAYidhp9mBmOiYqQEpqZlk3qbra6vsCOenqijtgIHCLG7vL29CQoNCsDCxMPBxw0MxsTLyMLCCwq+1LuVe9VZ0M/c297d4NvZ41vXeueU5N/r4e3o79jkvOb0UAe4+Pf6uMjS7P/TtAAcGKyeQXhT5ClcSKIdwYcHIyKMx7CiwocOwU3cWMmiR4YYQzqM+LGkSQXSUv/2y0jQH0qUJmNqoRSm5ixQbXLK2UmnJ886ToIilFltkk2cNw9B+umz6U87UOsRNXk0KdKrVrOSWWVwqlc+WHHWKnWqrKizZV+QGrA2yte31YDJPTZXrrMEzhbkPSYNWF+4gAFBeICJGTLDxVi2C5yNIxSQikVu48i4j8TLT1i2khwOM+bKVSQaeGLgQOnS+fIBwkiCszfPjqWAnn0ism1hsXO/oM279e3fuqmYeAChN++XKqP9BujP+EcXMKLkoFFm+o3qSH5oJ7L9SPfs3IlEHw/dhfNyLMpbX4+duvvw3uGDj08fCfn0+KVTPI9Ff/T37AHY3nXfFSifgfX9cJ//f/vxh95/1wkoYYQU5oDgfBh+t+B9DsJS4YABfiiDAWWQOGKJKJ6oYidcDdVhUVrFGFZWRl32IlEy0nJLWjyu1VYYrNxY2YxXjZUWW1+0FaSQDiaQ4z0y3OMXX3wxaSUKiWWZTF5c+sVASl8iB9OVbxFH3CVabmOMa9yQ6WYAbHL2Zh+UVRTnbV3NyUlwu120HEuw9WlloO+Mc+c3fCbEH6ES/Ybmn9AwWmdvnu1jaWoHpMBmFYdK+tmLiQqKCaTAebqRnh4d6o6pEqHqEan/sOqiqxbBumqoig42GK0WqUqQY7zCtZKvDgXL37AvEbvNAsaeJ6Zy0JKqErPNYpIj/xqOOKUtU9xu6+1OUekpCJFpLPXtud2mu21UTbhKLraPqCsvuvQ+FdQSqI57bbnxtlHvv/OCK5RsqO4Lr78BA6xwulDR+m4n5iYs8cJNVNyguwYzEi/FE3dsR7UpZJzIxh1z7FO4IJ8gMr860WuAEi/rEHMBM88s8ccpn/AwVhEjTDPMQMsc9M9Cx9HyIJbknMLOEJNC8xpOR/3zy1RPbXXVWD8tM9Rcq3Kx0lesvKORZz2NFtVmnWJ2j2NLAnYsiJCd9tlzz7122XTnnfbb2dxUi96A1x044GDwnc0Zfwuu+OCLK274c4UkzvjkZj3+ldxkUY5AApt3noDlldF1zP/YBAyzuemcp4665wGBDlcDeCUA+zKzyx77Arfnvjnuy+C+u+uADXPXMsTHXvzxxid/PPC8OEAYmnLBPoz0ttMee+3YXx/958y/oqsDl4hel/jkjz9+Md17Rf3620/fvu3uxy97A+lPVT75ic2lJWLDWD7AE/97QQCT1qv3sU9+6ytGAxTIQL7FpiLJiCD/JggOYJxKXAPMIAA3KCp1MHB6H5wfCEcowgRoUIAc/F8L3CSrr/EiGAsc4QKhEcMZwpCG0DihClHIQxVeaYdA1KEQAWioD9pQhEesoRJTOMQe/k9ITQwiEzloQ/q9sIpKxOENt9iAKHpxgw76ohOnKED/LWJRGJrIIhfVWEUxSnGMPDQOGd+4wwME0I76COAC2MhHNPZhjWbk4xzd2MTeNBGPuBiAPg6wyEbiIlMiaEBKYrjHQOJQG5YE5BbpSMhByvGQiixNKBlpGlI+8h5a0OQZg2ECVfYRhoOMJRx36JxZ/k+UbMGjKEupyERi4pUzjGQmV9lGWXLSkxiMoy+ICcxmNsCWxvRi/VYzw2pa85rYvKYKt8nNbnrzm96c5h+G6UwudhKacBTnOLPJznYuEJzwjCc41blOctoTlug8JjTpiSZ3+lOb3LTj/wSqSHlycwQPeB4//8jMe2KRgwJNZDQJaCaFLlQge6ykJP/ZTo3iYbGgHx3oPC+6CZRQspwNNakwEMnSE5L0FRndaEwXqFGO0lSmG32pQmLK043e1KYz7KlO5dHTouKUo0YdKjmMalSk4jSmSh3HAqb61KpqtKZBtWpOo1oNpmoVq9dkKrWMEwIAOw==" - }, - { - "name": "Background Analysis", - "description": "You compare the radioactive energy bands of the sample collected earlier with that of the nearby solar enviroment.\nNothing.\nThere is nothing nearby that matches the passive signal of the tree, or the bark, or anything similar.\nThis is really starting to get on your nerves.", - "choices": [ - { - "key": "choice 10", - "name": "Smash your desk in frustration.", - "exit_node": "FAIL", - "delay": 50, - "delay_message": "No amount of pay is worth dealing with magical plant juju." - }, - { - "key": "choice 11", - "name": "Check every known energy spectroscopy database.", - "exit_node": "Sample Match Found", - "delay": 900, - "delay_message": "You NEED an answer. You DESERVE an answer." - } - ], - "image": null, - "on_enter_effects": [ - { - "effect_type": "Add", - "quality": "Confusion", - "value": { - "value_type": "random", - "low": 3, - "high": 5 - } - } - ], - "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD///9ZVlKsMjJpampGR0cAAAAD/xi63P4wykmFpTjrDa0XXCiOZGlqQ0qsazqIXyx9Z23feKayfP/WskgwRywqCsikcslsOpGpgGvQNDo8lYt1W4I+v2CvMhUuI0/YiZbL5nxdhkJ8Lq/T6eZ8HRmHUtuAgRp6T3B2SXdNfYeJc3CCkJEYjISVYZKRQ5gajZSdi0yboqM3nnWkqKmCpgaqrq9GBrKzs7AKaYG4tji0vbu/wCW6wZpqNMHIOAM9zDw/IzEgHcVt1KOWZQ1TU4LDV2vJOAVU2GZkY5VF4NPr4SRM53yI8/Lw9uVvBcLuknqGn4cqLQIYhwy/g0fwKdSDsCEGggtDOZwoAiLFi5sAYtwoqf/XIVjeOKrqRUukjZAmGVjDGC2lSyAts7R7GW5ZM2bPNERDGSAmzWA2b/pAc+yBT0ArVeXhsC2oj5wnefaU+pNBxDJNXUAqyq6qhKthyCUR+4QLVa5ej5AFO3ZJPGw3qE5N22DsWiUD6Tm5e/cqCbk96dZtQgZip3rjwIIa90fwqrBUDAfcQ0hyilaOIWG7zIoSYryd73DLrJntNlOIO2WVQ/raYrYKW/8CCNuJbH6S8aS7vSCpq9C8gxMMzns48dudj9/WqFw2yZKvfDc38Rxzc+kiq09f/nw7b+wNwV9HuwuwSvLeL14wjz49pm3Qds7sbd59jh1Co3CQP1+8/Rr/TgnVQnxHNVDgf0QEKCBUIRxIX3sIAiigMwzCAKF/cc1H1xQTVvjXhRCqE6IosU2Q1YkiajiViin+VhthWW0l1YhevQjjafrIKI0QLP5kI2GMBWkbG2fVx1FiP/oxRl9DEiEXCDsKhuSPazFpBg5P9miSkHmlpleXbbkVUVRRTkOakl7mRg9fsJmQ5Zl2DaDmJ4XVwZkZYHbpoU726eZCaID28RYYeRFEToQVeVaYLHIwOkugk70GqWiNIeoGQJc5qumclOU5qUGWXhraFNU1yumpdoAa6ganZkrLpJ2G5qido606CKoGwDErrqaaSlKttrIKq2r/DGvHr39aF2wIgsYaduKzqyUhhbLLjsArp3BVW0Oz3OpWlrY5dCsuKOByMS635QpyLaTEGenauZ2M5y4m696B4Lz0spLuRMnt25BH9vr7b3XUChwOwbIYfBDCBSscDMIOL0xwxO5ATPHB2kVHY7oTg7RxuR0rhyFFIYv8MUYZX5xMySoDk3LLD3dXbQIAOw==" - }, - { - "name": "Sample Match Found", - "description": "After an extensive algorithm search on the controller end, you have a single match to this specific band and style of energy.\nThe problem, is that the source of said radiation is coming not only from Space Station 13, no.\nIt's coming from the Space Station 13 Research Department.\nWhat the fuck?", - "choices": [ - { - "key": "choice 12", - "name": "Something must be wrong with the drone.", - "exit_node": "Its Not You...", - "on_selection_effects": [ - { - "effect_type": "Add", - "quality": "Confusion", - "value": { - "value_type": "random", - "low": 6, - "high": 10 - } - } - ], - "delay": 30, - "delay_message": "Lousy piece of junk must be scanning the station instead of the target." - }, - { - "key": "choice 13", - "name": "Perhaps that sample was tainted. Collect a new sample.", - "exit_node": "Sample Taken", - "delay": 60, - "delay_message": "Lets try again, but carefully." - }, - { - "key": "choice 14", - "name": "Remember the Christmas Party.", - "exit_node": "The Christmas Party", - "requirements": [ - { - "quality": "Confusion", - "operator": "<=", - "value": 25 - } - ], - "delay": 100, - "delay_message": "Wait a gosh darn fucking second." - } - ], - "image": null, - "on_enter_effects": [ - { - "effect_type": "Add", - "quality": "Confusion", - "value": 10 - } - ], - "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD////v7+/h4eEAAAAAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZBkJaJqaLKOubSy7b23fODxPOb7/m4FASBRofEBeT1W6JU3DYaRIjQqfkCWKg1xoddjSQEgQlM/mdDkc0Fa+8PiWLSIM7Pj73RxOlVF/ITlKNXSGDXp5iiFoaBlqfpFyk12HMgSYmZkfmppmmJ8gjXwUf2lglqmqq6ytrq+wsbKztLW2t7i5um2Ug669uyBCKMNRc4Q9qXHBJlVUFMbRV6pfR04ONszQzlZRlm7IveLaimZ7eJAESUsfyVnX2hfqv/Nv4vfZ8RWJ/Hkdn6NGtRsFyEg4VLwK6UvVqROdgMcWSpxIsaLFixgzatzIsf+jR1gIP7YbN6uaSAn4wFGbdNJFsZcpFRqS09IBt2kW3CkzWdNmNyIYpIWkw9Nevgbwat2ccNPbTnbWjtKQWfGnVZwzoQaNqVXXkDFWGx3qeoIry2CJzJ05p6aPTpRmfSXV1a/u2jM7TuldA8LXO6kXFemh5ihn3Lc9A9h1ZaqxpMNkK9rl5+EMKIGM9g5FSjJjv4aVOwEc/Q8iXx6ODSo5ualOQ9Bs0qVJTLu27du4c+vezbu379/AgwsfTry48ePIkytfqHp5xhfLadby+1soMJDLbhchlqIYpVbXa14dz718NMBEz/ZsWsU8zMhY1CdmL+VE+/ObgWSvPR4rj/f/xqxUFG1fVfHIUgLCN58zR5ABySpwbAAdZ1TNMgZYF9YHjWmsDAgNeglNqFSBJJYiG14JUmcYiHNZWJcE6HD4FGIrVuiFjROxJeNYChoFWUS5lBPjOTO2iM2PKuki2F1qfdPjjUjSeMuSk82Uml4fRimlLVR2OUAYBGHpo5aV4OJll1iYRkqWhag4FY75WXhmlTOoedo/ZVKI40Jz+pOEnX2ZsqcCeVJ0piEQieJhiEx0RBkrd6J2IiQFVXqPbZjEYqdmll6Jz0avtUaCqEFtaiqnekmHUagOhSZapvJMeioanXa2KqukZoCrJoruCKNmCngKZGC7urprPRKq+QZBP2XFKRGunBwL6waZjIbiBInu9hoj0o5wraRiOadrsX1kK24HvBK25rnstuvuu/DGK++89NZr77345qvvvhYlAAA7" - }, - { - "name": "The Christmas Party", - "description": "Hold on. Last Christmas, the Research Director was incredibly hammered. He made a big mention that his brand new festivus pole was actually some kind of astrological... something something. You can't remember the whole details, because you were smashed as well. However, briefly, the RD did keep that festivus pole for awhile, he might even still have it somewhere.\nMaybe...?", - "choices": [ - { - "key": "choice 15", - "name": "Wait a minute, was that a god damn...", - "exit_node": "Rod.", - "delay": 100, - "delay_message": "Immovable Rod?" - } - ], - "image": null, - "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD/AACmAAD///+mpqYAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZGmejKCubOu6aCzP4WvfeD4IQ+//Pppw+MkZj6udkgdsOp/EqFSBrNqWwQ9hy+16v9ypeGM9YpnAE3hNKLTfhbG8kuTZz/j7/fmb+/8TbIJefIVNgIiJGgWMjY6PkJGRipSVlpeYmZqbnJ2en6ChoqOkpRplqDdYpqyprnpKhnyslq9leFkYg2u0QrZmaLkgu8S9JDg7Ksl2yrB7UDJw0m6QxiFfedk9wbKH1tbEW9TT05Lmjd/pJpPq7e7v8PHy8/T19vf4+fr7Kb9W/Jn8pcLiBKAcgVZwdethkAZCJAoXFmx47KEOWLMeAAlHMf+DRVXctIT70jHCxxYEhXkYKajkgpMRGZZgKY5LHJcJ6zTTNtHEm5rjgsK5WZKZs2xHn2WccY6RSwdJkaaUOOApoHDbqFK16ofmF6Fg20Aa8IhrpbBBm6plZ7aTIwhr0bWdS7eu3bt48+rdy7ev37+AAwseTLiw4cOI0/1LfPAkC8YlHINUApmD5MncVFZ+cPmK0qWbX3Z2MbVbaCqjd37eCjk1i9JaZR5OHTN2z8Gua9v2wavvaNjeKgygqbcz8KocvBLAexn4MOVb5jZfjVwk9DBW/S3bTn3E9S5cUXFvphqaCOhBs7/WGbU96PNr0EpTT96o1Kjv4ZOT/xbn/f921AWnBlhNWQXggZndFkNcZv2X1YOxsCZENXdJBWGCWp2mQRc+YLibIRpaQMyHEoVYgVfDcUFiHyYGopxQTgwFYosugsFfOXGZQyMGN+boI1E78vjjkHIF+QGRahkZxVpKNunkk1BGKeWUVFZp5ZVYZqnllogkAAA7" - }, - { - "name": "Rod.", - "description": "You cross reference your documentation. Sure enough, the \"festivus rod\" collected was actually an immovable rod.\nEnergy detected from the rod is the exact same coming off of the tree, as well. It's all making sense now. The Immovable rod is producing a kind of unique blackbody radiation that is providing sample heat and light for what is effectively an internal cold fusion process, and producing just enough of that radiation to create a kind of micro-enviromental bubble around the biosignature of the tree.\n\nThis would make the first time an immovable rod would exist in tandem with a biological source. You jot down some research notes on your findings, which could easily produce some kind of experimental tech, no doubt.", - "choices": [ - { - "key": "choice 16", - "name": "Snap a photo", - "exit_node": "Epilogue.", - "delay": 40, - "delay_message": "You could easily win an award for these findings!" - } - ], - "image": "default" - }, - { - "name": "Epilogue.", - "description": "You take a photo with the onboard camera on the drone. Suddenly, the immovable rod inside the tree explodes out of the wooden biological shell, and produces a blank, blurry photo.\nWhat the fuck?", - "choices": [ - { - "key": "choice 17", - "name": "God damnit.", - "exit_node": "WIN", - "delay": 10, - "delay_message": "Some things were just not meant for man to know." - } - ], - "image": "default" - }, - { - "name": "What is wrong with this tree?", - "description": "This is ridiculous. Nothing about this dumbass tree makes sense. It makes no sense, it's just sitting there, living and making a MOCKERY of all of science!\nYou didn't get your degree in advanced plasma-physics for this!", - "choices": [ - { - "key": "choice 18", - "name": "The world can never know about this dumbass stupid plant.", - "exit_node": "FAIL_DEATH", - "delay": 60, - "delay_message": "Activating drone self-destruct." - }, - { - "key": "choice 19", - "name": "Take a moment to calm down.", - "exit_node": "Biological Scan", - "on_selection_effects": [ - { - "effect_type": "Add", - "quality": "Confusion", - "value": { - "value_type": "random", - "low": -3, - "high": -5 - } - } - ], - "delay": 20, - "delay_message": "Breathe." - } - ], - "image": "default" - } - ] - } + "adventure_name": "There's a tree in the middle of space.", + "version": 1, + "starting_node": "Tree Start", + "starting_qualities": { + "Confusion": 0 + }, + "required_site_traits": [ + "in space" + ], + "loot_categories": [ + "research" + ], + "scan_band_mods": { + "Exotic Radiation": 10 + }, + "deep_scan_description": "", + "triggers": [ + { + "name": "Confusion Trigger", + "target_node": "What is wrong with this tree?", + "requirements": [ + { + "quality": "Confusion", + "operator": ">", + "value": 30 + } + ] + } + ], + "nodes": [ + { + "name": "Tree Start", + "description": "Camera online. Visual signs detect a fully grown, seemingly biological, and live tree located in the middle of the vacuum.\nSensors indicate it is not oxygenating, but energy is being collected via passive solar light from the nearby star.\nBaffling.", + "choices": [ + { + "key": "choice 0", + "name": "Ignore site.", + "exit_node": "FAIL", + "delay": 10, + "delay_message": "Leave this for the botanists to figure out." + }, + { + "key": "choice 1", + "name": "Begin sensor scan.", + "exit_node": "Biological Scan", + "delay": 10, + "delay_message": "Lets get some data." + } + ], + "image": null, + "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMQAAAAAAAC15h2QtxeAoxVykROizRpxjxIAcgAAWwAAgAAAUAAAZAAAZgC0tLTKysr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/2AgjmRpnigqrMMqtCvhyvFs17hQuPva67ygTwgcGovA3a61BLaeryj0mapar9isNjCNylpfgWwsLpPPZqBst066le84fB5nRpvdvGDL7/v/JmBeaWiFhIeGbGqLio1ljm2CklKUA4CXmJmaAYidhp9mBmOiYqQEpqZlk3qbra6vsCOenqijtgIHCLG7vL29CQoNCsDCxMPBxw0MxsTLyMLCCwq+1LuVe9VZ0M/c297d4NvZ41vXeueU5N/r4e3o79jkvOb0UAe4+Pf6uMjS7P/TtAAcGKyeQXhT5ClcSKIdwYcHIyKMx7CiwocOwU3cWMmiR4YYQzqM+LGkSQXSUv/2y0jQH0qUJmNqoRSm5ixQbXLK2UmnJ886ToIilFltkk2cNw9B+umz6U87UOsRNXk0KdKrVrOSWWVwqlc+WHHWKnWqrKizZV+QGrA2yte31YDJPTZXrrMEzhbkPSYNWF+4gAFBeICJGTLDxVi2C5yNIxSQikVu48i4j8TLT1i2khwOM+bKVSQaeGLgQOnS+fIBwkiCszfPjqWAnn0ism1hsXO/oM279e3fuqmYeAChN++XKqP9BujP+EcXMKLkoFFm+o3qSH5oJ7L9SPfs3IlEHw/dhfNyLMpbX4+duvvw3uGDj08fCfn0+KVTPI9Ff/T37AHY3nXfFSifgfX9cJ//f/vxh95/1wkoYYQU5oDgfBh+t+B9DsJS4YABfiiDAWWQOGKJKJ6oYidcDdVhUVrFGFZWRl32IlEy0nJLWjyu1VYYrNxY2YxXjZUWW1+0FaSQDiaQ4z0y3OMXX3wxaSUKiWWZTF5c+sVASl8iB9OVbxFH3CVabmOMa9yQ6WYAbHL2Zh+UVRTnbV3NyUlwu120HEuw9WlloO+Mc+c3fCbEH6ES/Ybmn9AwWmdvnu1jaWoHpMBmFYdK+tmLiQqKCaTAebqRnh4d6o6pEqHqEan/sOqiqxbBumqoig42GK0WqUqQY7zCtZKvDgXL37AvEbvNAsaeJ6Zy0JKqErPNYpIj/xqOOKUtU9xu6+1OUekpCJFpLPXtud2mu21UTbhKLraPqCsvuvQ+FdQSqI57bbnxtlHvv/OCK5RsqO4Lr78BA6xwulDR+m4n5iYs8cJNVNyguwYzEi/FE3dsR7UpZJzIxh1z7FO4IJ8gMr860WuAEi/rEHMBM88s8ccpn/AwVhEjTDPMQMsc9M9Cx9HyIJbknMLOEJNC8xpOR/3zy1RPbXXVWD8tM9Rcq3Kx0lesvKORZz2NFtVmnWJ2j2NLAnYsiJCd9tlzz7122XTnnfbb2dxUi96A1x044GDwnc0Zfwuu+OCLK274c4UkzvjkZj3+ldxkUY5AApt3noDlldF1zP/YBAyzuemcp4665wGBDlcDeCUA+zKzyx77Arfnvjnuy+C+u+uADXPXMsTHXvzxxid/PPC8OEAYmnLBPoz0ttMee+3YXx/958y/oqsDl4hel/jkjz9+Md17Rf3620/fvu3uxy97A+lPVT75ic2lJWLDWD7AE/97QQCT1qv3sU9+6ytGAxTIQL7FpiLJiCD/JggOYJxKXAPMIAA3KCp1MHB6H5wfCEcowgRoUIAc/F8L3CSrr/EiGAsc4QKhEcMZwpCG0DihClHIQxVeaYdA1KEQAWioD9pQhEesoRJTOMQe/k9ITQwiEzloQ/q9sIpKxOENt9iAKHpxgw76ohOnKED/LWJRGJrIIhfVWEUxSnGMPDQOGd+4wwME0I76COAC2MhHNPZhjWbk4xzd2MTeNBGPuBiAPg6wyEbiIlMiaEBKYrjHQOJQG5YE5BbpSMhByvGQiixNKBlpGlI+8h5a0OQZg2ECVfYRhoOMJRx36JxZ/k+UbMGjKEupyERi4pUzjGQmV9lGWXLSkxiMoy+ICcxmNsCWxvRi/VYzw2pa85rYvKYKt8nNbnrzm96c5h+G6UwudhKacBTnOLPJznYuEJzwjCc41blOctoTlug8JjTpiSZ3+lOb3LTj/wSqSHlycwQPeB4//8jMe2KRgwJNZDQJaCaFLlQge6ykJP/ZTo3iYbGgHx3oPC+6CZRQspwNNakwEMnSE5L0FRndaEwXqFGO0lSmG32pQmLK043e1KYz7KlO5dHTouKUo0YdKjmMalSk4jSmSh3HAqb61KpqtKZBtWpOo1oNpmoVq9dkKrWMEwIAOw==" + }, + { + "name": "Biological Scan", + "description": "You attempt to scan for clues regarding the tree's nature. It appears to be a fully mature oak tree. \n\nApproximated height is 13 ft, 6.4 inches. \n\nSubject sees no sign of an outer coating or otherwise layer protecting it from the void of space.\n\nSubject's surface temperature is 293.7 kelvin, as though it were sitting indoors.", + "choices": [ + { + "key": "choice 2", + "name": "Check Sensor Integrity.", + "exit_node": "Its Not You...", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Confusion", + "value": 5 + } + ], + "delay": 50, + "delay_message": "This can't be right." + }, + { + "key": "choice 4", + "name": "Attempt to take sample.", + "exit_node": "Sample Taken", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Confusion", + "value": 3 + } + ], + "delay": 40, + "delay_message": "Snip snip." + }, + { + "key": "choice 6", + "name": "Examine Tree Roots.", + "exit_node": "Examine Roots", + "delay": 10 + }, + { + "key": "choice 9", + "name": "Sequence Sample Radiation with background noise.", + "exit_node": "Background Analysis", + "requirements": [ + { + "quality": "Sample", + "operator": ">=", + "value": 1 + } + ], + "delay": 0, + "delay_message": "This can't be real." + }, + { + "key": "choice 40", + "name": "Leave.", + "exit_node": "FAIL", + "delay": 0 + } + ], + "image": null, + "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMQAAAAAAAC15h2QtxeAoxVykROizRpxjxIAcgAAWwAAgAAAUAAAZAAAZgC0tLTKysr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/2AgjmRpnigqrMMqtCvhyvFs17hQuPva67ygTwgcGovA3a61BLaeryj0mapar9isNjCNylpfgWwsLpPPZqBst066le84fB5nRpvdvGDL7/v/JmBeaWiFhIeGbGqLio1ljm2CklKUA4CXmJmaAYidhp9mBmOiYqQEpqZlk3qbra6vsCOenqijtgIHCLG7vL29CQoNCsDCxMPBxw0MxsTLyMLCCwq+1LuVe9VZ0M/c297d4NvZ41vXeueU5N/r4e3o79jkvOb0UAe4+Pf6uMjS7P/TtAAcGKyeQXhT5ClcSKIdwYcHIyKMx7CiwocOwU3cWMmiR4YYQzqM+LGkSQXSUv/2y0jQH0qUJmNqoRSm5ixQbXLK2UmnJ886ToIilFltkk2cNw9B+umz6U87UOsRNXk0KdKrVrOSWWVwqlc+WHHWKnWqrKizZV+QGrA2yte31YDJPTZXrrMEzhbkPSYNWF+4gAFBeICJGTLDxVi2C5yNIxSQikVu48i4j8TLT1i2khwOM+bKVSQaeGLgQOnS+fIBwkiCszfPjqWAnn0ism1hsXO/oM279e3fuqmYeAChN++XKqP9BujP+EcXMKLkoFFm+o3qSH5oJ7L9SPfs3IlEHw/dhfNyLMpbX4+duvvw3uGDj08fCfn0+KVTPI9Ff/T37AHY3nXfFSifgfX9cJ//f/vxh95/1wkoYYQU5oDgfBh+t+B9DsJS4YABfiiDAWWQOGKJKJ6oYidcDdVhUVrFGFZWRl32IlEy0nJLWjyu1VYYrNxY2YxXjZUWW1+0FaSQDiaQ4z0y3OMXX3wxaSUKiWWZTF5c+sVASl8iB9OVbxFH3CVabmOMa9yQ6WYAbHL2Zh+UVRTnbV3NyUlwu120HEuw9WlloO+Mc+c3fCbEH6ES/Ybmn9AwWmdvnu1jaWoHpMBmFYdK+tmLiQqKCaTAebqRnh4d6o6pEqHqEan/sOqiqxbBumqoig42GK0WqUqQY7zCtZKvDgXL37AvEbvNAsaeJ6Zy0JKqErPNYpIj/xqOOKUtU9xu6+1OUekpCJFpLPXtud2mu21UTbhKLraPqCsvuvQ+FdQSqI57bbnxtlHvv/OCK5RsqO4Lr78BA6xwulDR+m4n5iYs8cJNVNyguwYzEi/FE3dsR7UpZJzIxh1z7FO4IJ8gMr860WuAEi/rEHMBM88s8ccpn/AwVhEjTDPMQMsc9M9Cx9HyIJbknMLOEJNC8xpOR/3zy1RPbXXVWD8tM9Rcq3Kx0lesvKORZz2NFtVmnWJ2j2NLAnYsiJCd9tlzz7122XTnnfbb2dxUi96A1x044GDwnc0Zfwuu+OCLK274c4UkzvjkZj3+ldxkUY5AApt3noDlldF1zP/YBAyzuemcp4665wGBDlcDeCUA+zKzyx77Arfnvjnuy+C+u+uADXPXMsTHXvzxxid/PPC8OEAYmnLBPoz0ttMee+3YXx/958y/oqsDl4hel/jkjz9+Md17Rf3620/fvu3uxy97A+lPVT75ic2lJWLDWD7AE/97QQCT1qv3sU9+6ytGAxTIQL7FpiLJiCD/JggOYJxKXAPMIAA3KCp1MHB6H5wfCEcowgRoUIAc/F8L3CSrr/EiGAsc4QKhEcMZwpCG0DihClHIQxVeaYdA1KEQAWioD9pQhEesoRJTOMQe/k9ITQwiEzloQ/q9sIpKxOENt9iAKHpxgw76ohOnKED/LWJRGJrIIhfVWEUxSnGMPDQOGd+4wwME0I76COAC2MhHNPZhjWbk4xzd2MTeNBGPuBiAPg6wyEbiIlMiaEBKYrjHQOJQG5YE5BbpSMhByvGQiixNKBlpGlI+8h5a0OQZg2ECVfYRhoOMJRx36JxZ/k+UbMGjKEupyERi4pUzjGQmV9lGWXLSkxiMoy+ICcxmNsCWxvRi/VYzw2pa85rYvKYKt8nNbnrzm96c5h+G6UwudhKacBTnOLPJznYuEJzwjCc41blOctoTlug8JjTpiSZ3+lOb3LTj/wSqSHlycwQPeB4//8jMe2KRgwJNZDQJaCaFLlQge6ykJP/ZTo3iYbGgHx3oPC+6CZRQspwNNakwEMnSE5L0FRndaEwXqFGO0lSmG32pQmLK043e1KYz7KlO5dHTouKUo0YdKjmMalSk4jSmSh3HAqb61KpqtKZBtWpOo1oNpmoVq9dkKrWMEwIAOw==" + }, + { + "name": "Its Not You...", + "description": "After re-connection is established, your sensors appear fine. Tree has not moved in the slightest since last observed. Temperature has fluxuated 0.2 kelvin upwards, as expected of a plant under direct light.\nLets try again.", + "choices": [ + { + "key": "choice 3", + "name": "Restart biological scan.", + "exit_node": "Biological Scan", + "delay": 25, + "delay_message": "God damnit." + } + ], + "image": null, + "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD////v7+/h4eEAAAAAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZBkJaJqaLKOubSy7b23fODxPOb7/m4FASBRofEBeT1W6JU3DYaRIjQqfkCWKg1xoddjSQEgQlM/mdDkc0Fa+8PiWLSIM7Pj73RxOlVF/ITlKNXSGDXp5iiFoaBlqfpFyk12HMgSYmZkfmppmmJ8gjXwUf2lglqmqq6ytrq+wsbKztLW2t7i5um2Ug669uyBCKMNRc4Q9qXHBJlVUFMbRV6pfR04ONszQzlZRlm7IveLaimZ7eJAESUsfyVnX2hfqv/Nv4vfZ8RWJ/Hkdn6NGtRsFyEg4VLwK6UvVqROdgMcWSpxIsaLFixgzatzIsf+jR1gIP7YbN6uaSAn4wFGbdNJFsZcpFRqS09IBt2kW3CkzWdNmNyIYpIWkw9Nevgbwat2ccNPbTnbWjtKQWfGnVZwzoQaNqVXXkDFWGx3qeoIry2CJzJ05p6aPTpRmfSXV1a/u2jM7TuldA8LXO6kXFemh5ihn3Lc9A9h1ZaqxpMNkK9rl5+EMKIGM9g5FSjJjv4aVOwEc/Q8iXx6ODSo5ualOQ9Bs0qVJTLu27du4c+vezbu379/AgwsfTry48ePIkytfqHp5xhfLadby+1soMJDLbhchlqIYpVbXa14dz718NMBEz/ZsWsU8zMhY1CdmL+VE+/ObgWSvPR4rj/f/xqxUFG1fVfHIUgLCN58zR5ABySpwbAAdZ1TNMgZYF9YHjWmsDAgNeglNqFSBJJYiG14JUmcYiHNZWJcE6HD4FGIrVuiFjROxJeNYChoFWUS5lBPjOTO2iM2PKuki2F1qfdPjjUjSeMuSk82Uml4fRimlLVR2OUAYBGHpo5aV4OJll1iYRkqWhag4FY75WXhmlTOoedo/ZVKI40Jz+pOEnX2ZsqcCeVJ0piEQieJhiEx0RBkrd6J2IiQFVXqPbZjEYqdmll6Jz0avtUaCqEFtaiqnekmHUagOhSZapvJMeioanXa2KqukZoCrJoruCKNmCngKZGC7urprPRKq+QZBP2XFKRGunBwL6waZjIbiBInu9hoj0o5wraRiOadrsX1kK24HvBK25rnstuvuu/DGK++89NZr77345qvvvhYlAAA7" + }, + { + "name": "Sample Taken", + "description": "You collect and project a small sample of tree bark off the plant. The instant that the bark is removed from the tree, as though it suddenly remembered what it was, the moisture content of the bark freezes over, and implodes into small microparticles of splinters.\nSmall radioactive signature detected.", + "choices": [ + { + "key": "choice 5", + "name": "Well that was... unexpected.", + "exit_node": "Biological Scan", + "delay": 0, + "delay_message": "Maybe something else might work better.", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Sample", + "value": 1 + } + ] + } + ], + "image": null, + "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAABSLiiPVjtyRS9mOTFbNyYAAAAD/xi63P4wykmrvTjrzbv/YCiOZGmeaKqubOu+sDUQxTDbeK7vfF/3saCwcxPcCMckcqlM2pDPnnRKrUqH2IdAYDBwu+Bwl2Agm8sE8iy9Zrqbb2Z0bq3b74W8Xp+1bP+Af2KDhIVlh2eJaUtsi3CPcU43d5QDe5cFfSKBnJ2en50Ff6JboqYCBWiLq46tkK+RUJOTmJmatxyguqSovae/vsGirK2NjU21trjLQp+8wNDCwnmo1MnM2Nna29zd3t/g4eLj5OXm59o5Rjo/QOjvLaKwkrKylfdW8FleXImIBm0CxppXD4c9fAgT5tCn4Iuhh4fG/DNTjNHAi4/oKERYq/+cro8gPYXxR7EkK4EEUxbUOCVZHoabQoZ8NkqaKWI4BR7DGKcjTG4yaZaySRSatQLGfP5ciqHX0GhQpzGdSrWq1atYs2rdyrWr169gw4pVsc7G2LMLkM46SOkl2nc86W3E97aFgLh4Dc7dq6NuhC0TVVlUOY8l38N9szocREYiyYqEMdJZibjylW+AIRIiqUowyrwDJ+u1XMelsm6CNKtmHHiRZ8iuQGecVdklZpm4V3NWREznYNmhaeNRCg638eOBhrUWjPP3zshNDNuwzRW5dZrQmms3BhzSNb8SrIPCXvTudtjzMIEngVxo+ajDtKOkvt5u0Jrw3/s6yqd+Nk7/7uUn4FH+VaWfKAUmqOCCDDbo4IMQRijhhBRWaOGFGGao4YYcdujhhyCGKOKFRsgxy4jaBEeZOyi60J2JK1piS2ItcvDiaMIpVGMEv0GnIo46grgFbM/dKBppC004kXzo3fiGdJb51wUgiKTBnHNOzsYWkpd1xZpjrTHJnY+vQGlZOztMBUZmrO0mZo9Zwggkl/mkKc5qIy3n2nlExrnWnHROcRueYjSm55Wr+Ebmj2YeZpo4bBJqyG6Inqeon0duRF84kuJJKW98Nrkojlu2dYlHkXaq6qehNvfZqHI2+ihq4lGpKhisttpbbKNm6sN3t9Wam2q5Vtrqq5jesKk3jsI220mheuq665jJzoqqs9gGcqi0211KGLBUZYutciUZG6q3cREnlrjiPcZtTqIiAW597H5E07uuiqqehPXONIq57+6rYb81PWUTvmksuyHBTjUc1XnVmOLWjgFkG+CBNk1MsRb1kiegLxtf4KzHB4b8Qa0XA2OyfZ6QjODKywwlM8w012zzzTjnrPNWCQAAOw==" + }, + { + "name": "Examine Roots", + "description": "All plant matter has to derive energy and moisture from someplace. Examining the oak tree's roots reveals that the roots present all appear to splay out, similar to how a normal tree would. However, those roots then proceed to double back in on itself. This might suggest that the tree is obtaining nutrients from... itself.", + "choices": [ + { + "key": "choice 7", + "name": "That's fucking stupid.", + "exit_node": "Biological Scan", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Confusion", + "value": { + "value_type": "random", + "low": 6, + "high": 10 + } + } + ], + "delay": 0, + "delay_message": "What the hell kind of tree even IS this?" + }, + { + "key": "choice 8", + "name": "Obtain biological sample from roots.", + "exit_node": "Sample Taken", + "delay": 10, + "delay_message": "This is why we hire botanists on-site." + } + ], + "image": null, + "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMQAAAAAAAC15h2QtxeAoxVykROizRpxjxIAcgAAWwAAgAAAUAAAZAAAZgC0tLTKysr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/2AgjmRpnigqrMMqtCvhyvFs17hQuPva67ygTwgcGovA3a61BLaeryj0mapar9isNjCNylpfgWwsLpPPZqBst066le84fB5nRpvdvGDL7/v/JmBeaWiFhIeGbGqLio1ljm2CklKUA4CXmJmaAYidhp9mBmOiYqQEpqZlk3qbra6vsCOenqijtgIHCLG7vL29CQoNCsDCxMPBxw0MxsTLyMLCCwq+1LuVe9VZ0M/c297d4NvZ41vXeueU5N/r4e3o79jkvOb0UAe4+Pf6uMjS7P/TtAAcGKyeQXhT5ClcSKIdwYcHIyKMx7CiwocOwU3cWMmiR4YYQzqM+LGkSQXSUv/2y0jQH0qUJmNqoRSm5ixQbXLK2UmnJ886ToIilFltkk2cNw9B+umz6U87UOsRNXk0KdKrVrOSWWVwqlc+WHHWKnWqrKizZV+QGrA2yte31YDJPTZXrrMEzhbkPSYNWF+4gAFBeICJGTLDxVi2C5yNIxSQikVu48i4j8TLT1i2khwOM+bKVSQaeGLgQOnS+fIBwkiCszfPjqWAnn0ism1hsXO/oM279e3fuqmYeAChN++XKqP9BujP+EcXMKLkoFFm+o3qSH5oJ7L9SPfs3IlEHw/dhfNyLMpbX4+duvvw3uGDj08fCfn0+KVTPI9Ff/T37AHY3nXfFSifgfX9cJ//f/vxh95/1wkoYYQU5oDgfBh+t+B9DsJS4YABfiiDAWWQOGKJKJ6oYidcDdVhUVrFGFZWRl32IlEy0nJLWjyu1VYYrNxY2YxXjZUWW1+0FaSQDiaQ4z0y3OMXX3wxaSUKiWWZTF5c+sVASl8iB9OVbxFH3CVabmOMa9yQ6WYAbHL2Zh+UVRTnbV3NyUlwu120HEuw9WlloO+Mc+c3fCbEH6ES/Ybmn9AwWmdvnu1jaWoHpMBmFYdK+tmLiQqKCaTAebqRnh4d6o6pEqHqEan/sOqiqxbBumqoig42GK0WqUqQY7zCtZKvDgXL37AvEbvNAsaeJ6Zy0JKqErPNYpIj/xqOOKUtU9xu6+1OUekpCJFpLPXtud2mu21UTbhKLraPqCsvuvQ+FdQSqI57bbnxtlHvv/OCK5RsqO4Lr78BA6xwulDR+m4n5iYs8cJNVNyguwYzEi/FE3dsR7UpZJzIxh1z7FO4IJ8gMr860WuAEi/rEHMBM88s8ccpn/AwVhEjTDPMQMsc9M9Cx9HyIJbknMLOEJNC8xpOR/3zy1RPbXXVWD8tM9Rcq3Kx0lesvKORZz2NFtVmnWJ2j2NLAnYsiJCd9tlzz7122XTnnfbb2dxUi96A1x044GDwnc0Zfwuu+OCLK274c4UkzvjkZj3+ldxkUY5AApt3noDlldF1zP/YBAyzuemcp4665wGBDlcDeCUA+zKzyx77Arfnvjnuy+C+u+uADXPXMsTHXvzxxid/PPC8OEAYmnLBPoz0ttMee+3YXx/958y/oqsDl4hel/jkjz9+Md17Rf3620/fvu3uxy97A+lPVT75ic2lJWLDWD7AE/97QQCT1qv3sU9+6ytGAxTIQL7FpiLJiCD/JggOYJxKXAPMIAA3KCp1MHB6H5wfCEcowgRoUIAc/F8L3CSrr/EiGAsc4QKhEcMZwpCG0DihClHIQxVeaYdA1KEQAWioD9pQhEesoRJTOMQe/k9ITQwiEzloQ/q9sIpKxOENt9iAKHpxgw76ohOnKED/LWJRGJrIIhfVWEUxSnGMPDQOGd+4wwME0I76COAC2MhHNPZhjWbk4xzd2MTeNBGPuBiAPg6wyEbiIlMiaEBKYrjHQOJQG5YE5BbpSMhByvGQiixNKBlpGlI+8h5a0OQZg2ECVfYRhoOMJRx36JxZ/k+UbMGjKEupyERi4pUzjGQmV9lGWXLSkxiMoy+ICcxmNsCWxvRi/VYzw2pa85rYvKYKt8nNbnrzm96c5h+G6UwudhKacBTnOLPJznYuEJzwjCc41blOctoTlug8JjTpiSZ3+lOb3LTj/wSqSHlycwQPeB4//8jMe2KRgwJNZDQJaCaFLlQge6ykJP/ZTo3iYbGgHx3oPC+6CZRQspwNNakwEMnSE5L0FRndaEwXqFGO0lSmG32pQmLK043e1KYz7KlO5dHTouKUo0YdKjmMalSk4jSmSh3HAqb61KpqtKZBtWpOo1oNpmoVq9dkKrWMEwIAOw==" + }, + { + "name": "Background Analysis", + "description": "You compare the radioactive energy bands of the sample collected earlier with that of the nearby solar enviroment.\nNothing.\nThere is nothing nearby that matches the passive signal of the tree, or the bark, or anything similar.\nThis is really starting to get on your nerves.", + "choices": [ + { + "key": "choice 10", + "name": "Smash your desk in frustration.", + "exit_node": "FAIL", + "delay": 50, + "delay_message": "No amount of pay is worth dealing with magical plant juju." + }, + { + "key": "choice 11", + "name": "Check every known energy spectroscopy database.", + "exit_node": "Sample Match Found", + "delay": 900, + "delay_message": "You NEED an answer. You DESERVE an answer." + } + ], + "image": null, + "on_enter_effects": [ + { + "effect_type": "Add", + "quality": "Confusion", + "value": { + "value_type": "random", + "low": 3, + "high": 5 + } + } + ], + "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD///9ZVlKsMjJpampGR0cAAAAD/xi63P4wykmFpTjrDa0XXCiOZGlqQ0qsazqIXyx9Z23feKayfP/WskgwRywqCsikcslsOpGpgGvQNDo8lYt1W4I+v2CvMhUuI0/YiZbL5nxdhkJ8Lq/T6eZ8HRmHUtuAgRp6T3B2SXdNfYeJc3CCkJEYjISVYZKRQ5gajZSdi0yboqM3nnWkqKmCpgaqrq9GBrKzs7AKaYG4tji0vbu/wCW6wZpqNMHIOAM9zDw/IzEgHcVt1KOWZQ1TU4LDV2vJOAVU2GZkY5VF4NPr4SRM53yI8/Lw9uVvBcLuknqGn4cqLQIYhwy/g0fwKdSDsCEGggtDOZwoAiLFi5sAYtwoqf/XIVjeOKrqRUukjZAmGVjDGC2lSyAts7R7GW5ZM2bPNERDGSAmzWA2b/pAc+yBT0ArVeXhsC2oj5wnefaU+pNBxDJNXUAqyq6qhKthyCUR+4QLVa5ej5AFO3ZJPGw3qE5N22DsWiUD6Tm5e/cqCbk96dZtQgZip3rjwIIa90fwqrBUDAfcQ0hyilaOIWG7zIoSYryd73DLrJntNlOIO2WVQ/raYrYKW/8CCNuJbH6S8aS7vSCpq9C8gxMMzns48dudj9/WqFw2yZKvfDc38Rxzc+kiq09f/nw7b+wNwV9HuwuwSvLeL14wjz49pm3Qds7sbd59jh1Co3CQP1+8/Rr/TgnVQnxHNVDgf0QEKCBUIRxIX3sIAiigMwzCAKF/cc1H1xQTVvjXhRCqE6IosU2Q1YkiajiViin+VhthWW0l1YhevQjjafrIKI0QLP5kI2GMBWkbG2fVx1FiP/oxRl9DEiEXCDsKhuSPazFpBg5P9miSkHmlpleXbbkVUVRRTkOakl7mRg9fsJmQ5Zl2DaDmJ4XVwZkZYHbpoU726eZCaID28RYYeRFEToQVeVaYLHIwOkugk70GqWiNIeoGQJc5qumclOU5qUGWXhraFNU1yumpdoAa6ganZkrLpJ2G5qido606CKoGwDErrqaaSlKttrIKq2r/DGvHr39aF2wIgsYaduKzqyUhhbLLjsArp3BVW0Oz3OpWlrY5dCsuKOByMS635QpyLaTEGenauZ2M5y4m696B4Lz0spLuRMnt25BH9vr7b3XUChwOwbIYfBDCBSscDMIOL0xwxO5ATPHB2kVHY7oTg7RxuR0rhyFFIYv8MUYZX5xMySoDk3LLD3dXbQIAOw==" + }, + { + "name": "Sample Match Found", + "description": "After an extensive algorithm search on the controller end, you have a single match to this specific band and style of energy.\nThe problem, is that the source of said radiation is coming not only from Space Station 13, no.\nIt's coming from the Space Station 13 Research Department.\nWhat the fuck?", + "choices": [ + { + "key": "choice 12", + "name": "Something must be wrong with the drone.", + "exit_node": "Its Not You...", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Confusion", + "value": { + "value_type": "random", + "low": 6, + "high": 10 + } + } + ], + "delay": 30, + "delay_message": "Lousy piece of junk must be scanning the station instead of the target." + }, + { + "key": "choice 13", + "name": "Perhaps that sample was tainted. Collect a new sample.", + "exit_node": "Sample Taken", + "delay": 60, + "delay_message": "Lets try again, but carefully." + }, + { + "key": "choice 14", + "name": "Remember the Christmas Party.", + "exit_node": "The Christmas Party", + "requirements": [ + { + "quality": "Confusion", + "operator": "<=", + "value": 25 + } + ], + "delay": 100, + "delay_message": "Wait a gosh darn fucking second." + } + ], + "image": null, + "on_enter_effects": [ + { + "effect_type": "Add", + "quality": "Confusion", + "value": 10 + } + ], + "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD////v7+/h4eEAAAAAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZBkJaJqaLKOubSy7b23fODxPOb7/m4FASBRofEBeT1W6JU3DYaRIjQqfkCWKg1xoddjSQEgQlM/mdDkc0Fa+8PiWLSIM7Pj73RxOlVF/ITlKNXSGDXp5iiFoaBlqfpFyk12HMgSYmZkfmppmmJ8gjXwUf2lglqmqq6ytrq+wsbKztLW2t7i5um2Ug669uyBCKMNRc4Q9qXHBJlVUFMbRV6pfR04ONszQzlZRlm7IveLaimZ7eJAESUsfyVnX2hfqv/Nv4vfZ8RWJ/Hkdn6NGtRsFyEg4VLwK6UvVqROdgMcWSpxIsaLFixgzatzIsf+jR1gIP7YbN6uaSAn4wFGbdNJFsZcpFRqS09IBt2kW3CkzWdNmNyIYpIWkw9Nevgbwat2ccNPbTnbWjtKQWfGnVZwzoQaNqVXXkDFWGx3qeoIry2CJzJ05p6aPTpRmfSXV1a/u2jM7TuldA8LXO6kXFemh5ihn3Lc9A9h1ZaqxpMNkK9rl5+EMKIGM9g5FSjJjv4aVOwEc/Q8iXx6ODSo5ualOQ9Bs0qVJTLu27du4c+vezbu379/AgwsfTry48ePIkytfqHp5xhfLadby+1soMJDLbhchlqIYpVbXa14dz718NMBEz/ZsWsU8zMhY1CdmL+VE+/ObgWSvPR4rj/f/xqxUFG1fVfHIUgLCN58zR5ABySpwbAAdZ1TNMgZYF9YHjWmsDAgNeglNqFSBJJYiG14JUmcYiHNZWJcE6HD4FGIrVuiFjROxJeNYChoFWUS5lBPjOTO2iM2PKuki2F1qfdPjjUjSeMuSk82Uml4fRimlLVR2OUAYBGHpo5aV4OJll1iYRkqWhag4FY75WXhmlTOoedo/ZVKI40Jz+pOEnX2ZsqcCeVJ0piEQieJhiEx0RBkrd6J2IiQFVXqPbZjEYqdmll6Jz0avtUaCqEFtaiqnekmHUagOhSZapvJMeioanXa2KqukZoCrJoruCKNmCngKZGC7urprPRKq+QZBP2XFKRGunBwL6waZjIbiBInu9hoj0o5wraRiOadrsX1kK24HvBK25rnstuvuu/DGK++89NZr77345qvvvhYlAAA7" + }, + { + "name": "The Christmas Party", + "description": "Hold on. Last Christmas, the Research Director was incredibly hammered. He made a big mention that his brand new festivus pole was actually some kind of astrological... something something. You can't remember the whole details, because you were smashed as well. However, briefly, the RD did keep that festivus pole for awhile, he might even still have it somewhere.\nMaybe...?", + "choices": [ + { + "key": "choice 15", + "name": "Wait a minute, was that a god damn...", + "exit_node": "Rod.", + "delay": 100, + "delay_message": "Immovable Rod?" + } + ], + "image": null, + "raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD/AACmAAD///+mpqYAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZGmejKCubOu6aCzP4WvfeD4IQ+//Pppw+MkZj6udkgdsOp/EqFSBrNqWwQ9hy+16v9ypeGM9YpnAE3hNKLTfhbG8kuTZz/j7/fmb+/8TbIJefIVNgIiJGgWMjY6PkJGRipSVlpeYmZqbnJ2en6ChoqOkpRplqDdYpqyprnpKhnyslq9leFkYg2u0QrZmaLkgu8S9JDg7Ksl2yrB7UDJw0m6QxiFfedk9wbKH1tbEW9TT05Lmjd/pJpPq7e7v8PHy8/T19vf4+fr7Kb9W/Jn8pcLiBKAcgVZwdethkAZCJAoXFmx47KEOWLMeAAlHMf+DRVXctIT70jHCxxYEhXkYKajkgpMRGZZgKY5LHJcJ6zTTNtHEm5rjgsK5WZKZs2xHn2WccY6RSwdJkaaUOOApoHDbqFK16ofmF6Fg20Aa8IhrpbBBm6plZ7aTIwhr0bWdS7eu3bt48+rdy7ev37+AAwseTLiw4cOI0/1LfPAkC8YlHINUApmD5MncVFZ+cPmK0qWbX3Z2MbVbaCqjd37eCjk1i9JaZR5OHTN2z8Gua9v2wavvaNjeKgygqbcz8KocvBLAexn4MOVb5jZfjVwk9DBW/S3bTn3E9S5cUXFvphqaCOhBs7/WGbU96PNr0EpTT96o1Kjv4ZOT/xbn/f921AWnBlhNWQXggZndFkNcZv2X1YOxsCZENXdJBWGCWp2mQRc+YLibIRpaQMyHEoVYgVfDcUFiHyYGopxQTgwFYosugsFfOXGZQyMGN+boI1E78vjjkHIF+QGRahkZxVpKNunkk1BGKeWUVFZp5ZVYZqnllogkAAA7" + }, + { + "name": "Rod.", + "description": "You cross reference your documentation. Sure enough, the \"festivus rod\" collected was actually an immovable rod.\nEnergy detected from the rod is the exact same coming off of the tree, as well. It's all making sense now. The Immovable rod is producing a kind of unique blackbody radiation that is providing sample heat and light for what is effectively an internal cold fusion process, and producing just enough of that radiation to create a kind of micro-enviromental bubble around the biosignature of the tree.\n\nThis would make the first time an immovable rod would exist in tandem with a biological source. You jot down some research notes on your findings, which could easily produce some kind of experimental tech, no doubt.", + "choices": [ + { + "key": "choice 16", + "name": "Snap a photo", + "exit_node": "Epilogue.", + "delay": 40, + "delay_message": "You could easily win an award for these findings!" + } + ], + "image": "default" + }, + { + "name": "Epilogue.", + "description": "You take a photo with the onboard camera on the drone. Suddenly, the immovable rod inside the tree explodes out of the wooden biological shell, and produces a blank, blurry photo.\nWhat the fuck?", + "choices": [ + { + "key": "choice 17", + "name": "God damnit.", + "exit_node": "WIN", + "delay": 10, + "delay_message": "Some things were just not meant for man to know." + } + ], + "image": "default", + "on_enter_effects": [ + { + "effect_type": "Set", + "quality": "Confusion", + "value": 9999 + } + ] + }, + { + "name": "What is wrong with this tree?", + "description": "This is ridiculous. Nothing about this dumbass tree makes sense. It makes no sense, it's just sitting there, living and making a MOCKERY of all of science!\nYou didn't get your degree in advanced plasma-physics for this!", + "choices": [ + { + "key": "choice 18", + "name": "The world can never know about this dumbass stupid plant.", + "exit_node": "FAIL_DEATH", + "delay": 60, + "delay_message": "Activating drone self-destruct." + }, + { + "key": "choice 19", + "name": "Take a moment to calm down.", + "exit_node": "Biological Scan", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Confusion", + "value": { + "value_type": "random", + "low": -3, + "high": -5 + } + } + ], + "delay": 20, + "delay_message": "Breathe." + } + ], + "image": "default" + } + ] +} \ No newline at end of file diff --git a/code/modules/explorer_drone/exodrone.dm b/code/modules/explorer_drone/exodrone.dm index 72cf09bd81b..5c73f5755df 100644 --- a/code/modules/explorer_drone/exodrone.dm +++ b/code/modules/explorer_drone/exodrone.dm @@ -5,7 +5,7 @@ // Fuel types and travel time per unit of distance on that fuel. #define FUEL_BASIC "basic" -#define BASIC_FUEL_TIME_COST 300 +#define BASIC_FUEL_TIME_COST 250 #define FUEL_ADVANCED "advanced" #define ADVANCED_FUEL_TIME_COST 200 @@ -334,9 +334,9 @@ GLOBAL_LIST_EMPTY(exodrone_launchers) drone_log("Sustained [amount] damage.") /obj/item/exodrone/proc/drone_log(message) - drone_log.Insert(1,message) if(length(drone_log) > EXODRONE_LOG_SIZE) - drone_log.Cut(EXODRONE_LOG_SIZE) + drone_log = list() + drone_log.Insert(1,message) /obj/item/exodrone/proc/has_tool(tool_type) return tools.Find(tool_type) @@ -354,6 +354,11 @@ GLOBAL_LIST_EMPTY(exodrone_launchers) . = ..() GLOB.exodrone_launchers += src +/obj/machinery/exodrone_launcher/examine(user) + . = ..() + if(fuel_canister) + . += span_notice("You can remove the [fuel_canister] with a prying tool.") + /obj/machinery/exodrone_launcher/attackby(obj/item/weapon, mob/living/user, params) if(istype(weapon, /obj/item/fuel_pellet)) if(fuel_canister) @@ -374,7 +379,7 @@ GLOBAL_LIST_EMPTY(exodrone_launchers) if(!fuel_canister) return - to_chat(user, span_notice("You remove the [fuel_canister] from the [src].")) + to_chat(user, span_notice("You remove [fuel_canister] from [src].")) fuel_canister.forceMove(drop_location()) fuel_canister = null update_icon() diff --git a/code/modules/explorer_drone/scanner_array.dm b/code/modules/explorer_drone/scanner_array.dm index e5b5f7a026c..7f019b0d43c 100644 --- a/code/modules/explorer_drone/scanner_array.dm +++ b/code/modules/explorer_drone/scanner_array.dm @@ -14,9 +14,9 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions()) #define MAX_SCAN_DISTANCE 10 -#define WIDE_SCAN_COST(BAND, SCAN_POWER) (((BAND*BAND)/(SCAN_POWER))*2*60*10) -#define BASE_POINT_SCAN_TIME (5 MINUTES) -#define BASE_DEEP_SCAN_TIME (5 MINUTES) +#define WIDE_SCAN_COST(BAND, SCAN_POWER) (min(((BAND*BAND)/(SCAN_POWER))*2*60*10, 10 MINUTES)) +#define BASE_POINT_SCAN_TIME (2 MINUTES) +#define BASE_DEEP_SCAN_TIME (3 MINUTES) /// Represents scan in progress, only one globally for now, todo later split per z or allow partial dish swarm usage /datum/exoscan @@ -35,7 +35,7 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions()) var/scan_time = 0 switch(scan_type) if(EXOSCAN_WIDE) - scan_power = length(GLOB.exoscanner_controller.tracked_dishes) + scan_power = GLOB.exoscanner_controller.calculate_scan_power() scan_time = WIDE_SCAN_COST(GLOB.exoscanner_controller.wide_scan_band,scan_power) if(EXOSCAN_POINT) scan_power = GLOB.exoscanner_controller.get_scan_power(target) @@ -76,7 +76,8 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions()) deltimer(scan_timer) /obj/machinery/computer/exoscanner_control - name = "Scanner Array Control Console" + name = "scanner array control console" + desc = "Controls scanner arrays to initiate scans for exodrones." circuit = /obj/item/circuitboard/computer/exoscanner_console /// If scan was interrupted show a popup until dismissed. var/failed_popup = FALSE @@ -105,7 +106,7 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions()) condition_descriptions += condition.description .["scan_conditions"] = condition_descriptions else - .["scan_power"] = scan_power = length(GLOB.exoscanner_controller.tracked_dishes) + .["scan_power"] = scan_power = GLOB.exoscanner_controller.calculate_scan_power() .["wide_scan_eta"] = scan_power > 0 ? WIDE_SCAN_COST(GLOB.exoscanner_controller.wide_scan_band,scan_power) : 0 .["possible_sites"] = build_exploration_site_ui_data() .["scan_conditions"] = null @@ -196,11 +197,35 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions()) icon = 'icons/obj/exploration.dmi' icon_state = "scanner_off" desc = "A sophisticated scanning array. Easily influenced by its environment." + circuit = /obj/item/circuitboard/machine/exoscanner + ///the scan power of this array to supply to scanner_controller + var/scan_power = 1 /obj/machinery/exoscanner/Initialize(mapload) . = ..() RegisterSignals(GLOB.exoscanner_controller,list(COMSIG_EXOSCAN_STARTED,COMSIG_EXOSCAN_FINISHED), PROC_REF(scan_change)) update_readiness() + RefreshParts() + +/obj/machinery/exoscanner/RefreshParts() + . = ..() + var/power = 1 + + for(var/datum/stock_part/scanning_module/scanning_module in component_parts) + power += (scanning_module.tier - 1) / 12 + scan_power = power + GLOB.exoscanner_controller.update_scan_power() + +/obj/machinery/exoscanner/screwdriver_act(mob/user, obj/item/tool) + . = ..() + if(!.) + . = default_deconstruction_screwdriver(user, "scanner_open", "scanner_off", tool) + update_readiness() + +/obj/machinery/exoscanner/crowbar_act(mob/user, obj/item/tool) + ..() + if(default_deconstruction_crowbar(tool)) + return TRUE /obj/machinery/exoscanner/proc/scan_change() SIGNAL_HANDLER @@ -215,7 +240,7 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions()) GLOB.exoscanner_controller.deactivate_scanner(src) /obj/machinery/exoscanner/proc/is_ready() - return anchored && is_operational + return anchored && is_operational && !panel_open /obj/machinery/exoscanner/proc/update_readiness() if(is_ready()) @@ -302,7 +327,7 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions()) /datum/scanner_controller/proc/calculate_scan_power(conditions) . = 0 for(var/obj/machinery/exoscanner/dish in tracked_dishes) - var/effective_power = 1 + var/effective_power = dish.scan_power for(var/datum/scan_condition/condition in conditions) effective_power *= condition.check_dish(dish) if(!effective_power) //Don't bother continuing if it's zero diff --git a/code/modules/food_and_drinks/restaurant/_venue.dm b/code/modules/food_and_drinks/restaurant/_venue.dm index a73cb6b4e35..f8e171948a6 100644 --- a/code/modules/food_and_drinks/restaurant/_venue.dm +++ b/code/modules/food_and_drinks/restaurant/_venue.dm @@ -60,10 +60,10 @@ if (initial(customer_type.is_unique)) customer_types -= customer_type - var/mob/living/simple_animal/robot_customer/new_customer = new /mob/living/simple_animal/robot_customer(get_turf(restaurant_portal), customer_type, src) + var/mob/living/basic/robot_customer/new_customer = new /mob/living/basic/robot_customer(get_turf(restaurant_portal), customer_type, src) current_visitors += new_customer -/datum/venue/proc/order_food(mob/living/simple_animal/robot_customer/customer_pawn, datum/customer_data/customer_data) +/datum/venue/proc/order_food(mob/living/basic/robot_customer/customer_pawn, datum/customer_data/customer_data) var/order = pick_weight(customer_data.orderable_objects[venue_type]) var/list/order_args // Only for custom orders - arguments passed into New var/image/food_image @@ -113,7 +113,7 @@ return "broken venue pls call a coder" ///Effects for when a customer receives their order at this venue -/datum/venue/proc/on_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item) +/datum/venue/proc/on_get_order(mob/living/basic/robot_customer/customer_pawn, obj/item/order_item) SHOULD_CALL_PARENT(TRUE) // This is an item typepath, a reagent typepath, or a custom order datum instance. @@ -152,7 +152,7 @@ open = FALSE restaurant_portal.update_icon() STOP_PROCESSING(SSobj, src) - for(var/mob/living/simple_animal/robot_customer as anything in current_visitors) + for(var/mob/living/basic/robot_customer as anything in current_visitors) robot_customer.ai_controller.set_blackboard_key(BB_CUSTOMER_LEAVING, TRUE) //LEAVEEEEEE /obj/machinery/restaurant_portal diff --git a/code/modules/food_and_drinks/restaurant/custom_order.dm b/code/modules/food_and_drinks/restaurant/custom_order.dm index c74b4883c19..d87797b2578 100644 --- a/code/modules/food_and_drinks/restaurant/custom_order.dm +++ b/code/modules/food_and_drinks/restaurant/custom_order.dm @@ -34,7 +34,7 @@ * Return [TRANSACTION_SUCCESS] to denote the order went through successfully (Not generally necessary to include here) * Return [TRANSACTION_HANDLED] to not do any further handling of the order by the */ -/datum/custom_order/proc/handle_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item) +/datum/custom_order/proc/handle_get_order(mob/living/basic/robot_customer/customer_pawn, obj/item/order_item) return NONE /datum/custom_order/moth_clothing @@ -153,7 +153,7 @@ food_image.add_overlay(drink_image) return food_image -/datum/custom_order/reagent/handle_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item) +/datum/custom_order/reagent/handle_get_order(mob/living/basic/robot_customer/customer_pawn, obj/item/order_item) . = TRANSACTION_HANDLED for(var/datum/reagent/reagent as anything in order_item.reagents?.reagent_list) @@ -184,7 +184,7 @@ /datum/custom_order/reagent/drink container_needed = /obj/item/reagent_containers/cup/glass/drinkingglass -/datum/custom_order/reagent/drink/handle_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item) +/datum/custom_order/reagent/drink/handle_get_order(mob/living/basic/robot_customer/customer_pawn, obj/item/order_item) customer_pawn.visible_message( span_danger("[customer_pawn] slurps up [order_item] in one go!"), span_danger("You slurp up [order_item] in one go."), @@ -210,7 +210,7 @@ /datum/custom_order/reagent/soup/get_order_line(datum/venue/our_venue) return "I'll take a [picked_serving] of [initial(reagent_type.name)]" -/datum/custom_order/reagent/soup/handle_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item) +/datum/custom_order/reagent/soup/handle_get_order(mob/living/basic/robot_customer/customer_pawn, obj/item/order_item) customer_pawn.visible_message( span_danger("[customer_pawn] pours [order_item] right down [customer_pawn.p_their()] hatch!"), span_danger("You pour [order_item] down your hatch in one go."), diff --git a/code/modules/food_and_drinks/restaurant/customers/_customer.dm b/code/modules/food_and_drinks/restaurant/customers/_customer.dm index c5a7f809586..3f13b526056 100644 --- a/code/modules/food_and_drinks/restaurant/customers/_customer.dm +++ b/code/modules/food_and_drinks/restaurant/customers/_customer.dm @@ -52,10 +52,10 @@ /datum/customer_data/proc/can_use(datum/venue/venue) return TRUE -/datum/customer_data/proc/get_overlays(mob/living/simple_animal/robot_customer/customer) +/datum/customer_data/proc/get_overlays(mob/living/basic/robot_customer/customer) return -/datum/customer_data/proc/get_underlays(mob/living/simple_animal/robot_customer/customer) +/datum/customer_data/proc/get_underlays(mob/living/basic/robot_customer/customer) return /datum/customer_data/american @@ -177,7 +177,7 @@ ), ) -/datum/customer_data/french/get_overlays(mob/living/simple_animal/robot_customer/customer) +/datum/customer_data/french/get_overlays(mob/living/basic/robot_customer/customer) if(customer.ai_controller.blackboard[BB_CUSTOMER_LEAVING]) var/mutable_appearance/flag = mutable_appearance(customer.icon, "french_flag") flag.appearance_flags = RESET_COLOR @@ -224,7 +224,7 @@ ), ) -/datum/customer_data/japanese/get_overlays(mob/living/simple_animal/robot_customer/customer) +/datum/customer_data/japanese/get_overlays(mob/living/basic/robot_customer/customer) //leaving and eaten if(type == /datum/customer_data/japanese && customer.ai_controller.blackboard[BB_CUSTOMER_LEAVING] && customer.ai_controller.blackboard[BB_CUSTOMER_EATING]) var/mutable_appearance/you_won_my_heart = mutable_appearance('icons/effects/effects.dmi', "love_hearts") @@ -303,13 +303,13 @@ return FALSE return TRUE -/datum/customer_data/moth/proc/get_wings(mob/living/simple_animal/robot_customer/customer) +/datum/customer_data/moth/proc/get_wings(mob/living/basic/robot_customer/customer) var/customer_ref = WEAKREF(customer) if (!LAZYACCESS(wings_chosen, customer_ref)) LAZYSET(wings_chosen, customer_ref, pick(GLOB.sprite_accessories["wings"])) return wings_chosen[customer_ref] -/datum/customer_data/moth/get_underlays(mob/living/simple_animal/robot_customer/customer) +/datum/customer_data/moth/get_underlays(mob/living/basic/robot_customer/customer) var/list/underlays = list() var/datum/sprite_accessory/moth_wings/wings = get_wings(customer) @@ -320,7 +320,7 @@ return underlays -/datum/customer_data/moth/get_overlays(mob/living/simple_animal/robot_customer/customer) +/datum/customer_data/moth/get_overlays(mob/living/basic/robot_customer/customer) var/list/overlays = list() var/datum/sprite_accessory/moth_wings/wings = get_wings(customer) diff --git a/code/modules/food_and_drinks/restaurant/generic_venues.dm b/code/modules/food_and_drinks/restaurant/generic_venues.dm index 19f1ff61323..9e9b0a6d0e3 100644 --- a/code/modules/food_and_drinks/restaurant/generic_venues.dm +++ b/code/modules/food_and_drinks/restaurant/generic_venues.dm @@ -42,7 +42,7 @@ var/obj/item/object_to_order = order return "I'll take \a [initial(object_to_order.name)]" -/datum/venue/restaurant/on_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item) +/datum/venue/restaurant/on_get_order(mob/living/basic/robot_customer/customer_pawn, obj/item/order_item) var/transaction_result = ..() if((transaction_result & TRANSACTION_HANDLED) || !(transaction_result & TRANSACTION_SUCCESS)) return diff --git a/code/modules/hydroponics/grown/replicapod.dm b/code/modules/hydroponics/grown/replicapod.dm index 8e5dda5a7fa..c1fd02bf9f0 100644 --- a/code/modules/hydroponics/grown/replicapod.dm +++ b/code/modules/hydroponics/grown/replicapod.dm @@ -37,7 +37,7 @@ plant_icon_offset = 2 species = "replicapod" plantname = "Replica Pod" - product = /mob/living/carbon/human //verrry special -- Urist + product = null // the human mob is spawned in harvest() lifespan = 50 endurance = 8 maturation = 10 diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm index a3804c9262f..04b0edf44bb 100644 --- a/code/modules/hydroponics/seed_extractor.dm +++ b/code/modules/hydroponics/seed_extractor.dm @@ -13,46 +13,33 @@ * * user - checks if we can remove the object from the inventory * * */ -/proc/seedify(obj/item/O, t_max, obj/machinery/seed_extractor/extractor, mob/living/user) - var/t_amount = 0 +/proc/seedify(obj/item/object, t_max, obj/machinery/seed_extractor/extractor, mob/living/user) + //try to get the seed from this item + var/obj/item/seeds/seed = object.get_plant_seed() + if(isnull(seed)) + return null + + //generate a random multiplier if value is not specified var/list/seeds = list() if(t_max == -1) if(extractor) t_max = rand(1,4) * extractor.seed_multiplier else t_max = rand(1,4) - - var/seedloc = O.loc + //drop location for the newly generated seeds + var/seedloc = object.loc if(extractor) seedloc = extractor.loc - if(istype(O, /obj/item/food/grown/)) - var/obj/item/food/grown/F = O - if(F.seed) - if(user && !user.temporarilyRemoveItemFromInventory(O)) //couldn't drop the item - return - while(t_amount < t_max) - var/obj/item/seeds/t_prod = F.seed.Copy() - seeds.Add(t_prod) - t_prod.forceMove(seedloc) - t_amount++ - qdel(O) - return seeds - - else if(istype(O, /obj/item/grown)) - var/obj/item/grown/F = O - if(F.seed) - if(user && !user.temporarilyRemoveItemFromInventory(O)) - return - while(t_amount < t_max) - var/obj/item/seeds/t_prod = F.seed.Copy() - t_prod.forceMove(seedloc) - t_amount++ - qdel(O) - return 1 - - return 0 - + //multiply the seeds and delete the item + if(user && !user.temporarilyRemoveItemFromInventory(object)) //couldn't drop the item + return null + for(var/_ in 0 to t_max) + var/obj/item/seeds/t_prod = seed.Copy() + seeds.Add(t_prod) + t_prod.forceMove(seedloc) + qdel(object) + return seeds /obj/machinery/seed_extractor name = "seed extractor" @@ -80,6 +67,7 @@ if(held_item?.get_plant_seed()) context[SCREENTIP_CONTEXT_LMB] = "Make seeds" + context[SCREENTIP_CONTEXT_RMB] = "Make & Store seeds" return CONTEXTUAL_SCREENTIP_SET if(istype(held_item, /obj/item/storage/bag/plants) && (locate(/obj/item/seeds) in held_item.contents)) @@ -135,7 +123,17 @@ return TRUE - if(seedify(attacking_item, -1, src, user)) + var/list/generated_seeds = seedify(attacking_item, -1, src, user) + if(!isnull(generated_seeds)) + if(LAZYACCESS(params2list(params), RIGHT_CLICK)) + //find all seeds lying on the turf and add them to the machine + for(var/obj/item/seeds/seed as anything in generated_seeds) + //machine is full + if(contents.len >= max_seeds) + to_chat(user, span_warning("[src] is full.")) + break + //add seed to machine. second argument is null which means just force move into the machine + add_seed(seed) to_chat(user, span_notice("You extract some seeds.")) return TRUE @@ -176,23 +174,16 @@ * needed to go to the ui handler * * to_add - what seed are we adding? - * taking_from - where are we taking the seed from? A mob, a bag, etc? - * user - who is inserting the seed? + * taking_from - where are we taking the seed from? A mob, a bag, etc? If null its means its just laying on the turf so force move it in **/ /obj/machinery/seed_extractor/proc/add_seed(obj/item/seeds/to_add, atom/taking_from) - if(ismob(taking_from)) - var/mob/mob_loc = taking_from - if(!mob_loc.transferItemToLoc(to_add, src)) - return FALSE - - else if(!taking_from.atom_storage?.attempt_remove(to_add, src, silent = TRUE)) - return FALSE - var/seed_id = generate_seed_hash(to_add) + var/list/seed_data + var/has_seed_data // so we remember to add a seed obj weakref to piles[seed_id] at the end of the proc. That way if some reason we runtime in this proc it won't incorrectly add data to the list if(piles[seed_id]) - piles[seed_id]["refs"] += WEAKREF(to_add) + has_seed_data = TRUE else - var/list/seed_data = list() + seed_data = list() seed_data["icon"] = sanitize_css_class_name("[initial(to_add.icon)][initial(to_add.icon_state)]") seed_data["name"] = capitalize(replacetext(to_add.name,"pack of ", "")); seed_data["lifespan"] = to_add.lifespan @@ -216,8 +207,8 @@ seed_data["mutatelist"] = list() for(var/obj/item/seeds/mutant as anything in to_add.mutatelist) seed_data["mutatelist"] += initial(mutant.plantname) - var/obj/item/food/grown/product = new to_add.product - if(product) + if(to_add.product) + var/obj/item/food/grown/product = new to_add.product var/datum/reagent/product_distill_reagent = product.distill_reagent seed_data["distill_reagent"] = initial(product_distill_reagent.name) var/datum/reagent/product_juice_typepath = product.juice_typepath @@ -225,8 +216,25 @@ seed_data["grind_results"] = list() for(var/datum/reagent/reagent as anything in product.grind_results) seed_data["grind_results"] += initial(reagent.name) - qdel(product) + qdel(product) + + if(!isnull(taking_from)) + if(ismob(taking_from)) + var/mob/mob_loc = taking_from + if(!mob_loc.transferItemToLoc(to_add, src)) + return FALSE + + else if(!taking_from.atom_storage?.attempt_remove(to_add, src, silent = TRUE)) + return FALSE + else + to_add.forceMove(src) + + // do this at the end, in case any of the previous steps failed + if(has_seed_data) + piles[seed_id]["refs"] += WEAKREF(to_add) + else piles[seed_id] = seed_data + return TRUE /obj/machinery/seed_extractor/ui_state(mob/user) diff --git a/code/modules/meteors/meteor_waves.dm b/code/modules/meteors/meteor_waves.dm index 4235c186a94..7d832d53713 100644 --- a/code/modules/meteors/meteor_waves.dm +++ b/code/modules/meteors/meteor_waves.dm @@ -26,4 +26,4 @@ GLOBAL_LIST_INIT(meteors_stray, list(/obj/effect/meteor/medium=15, /obj/effect/m GLOBAL_LIST_INIT(meteors_sandstorm, list(/obj/effect/meteor/sand=45, /obj/effect/meteor/dust=5)) //for sandstorm event -GLOBAL_LIST_INIT(meteorsSPOOKY, list(/obj/effect/meteor/pumpkin)) +GLOBAL_LIST_INIT(meteorsSPOOKY, list(/obj/effect/meteor/pumpkin=1)) diff --git a/code/modules/mining/equipment/monster_organs/regenerative_core.dm b/code/modules/mining/equipment/monster_organs/regenerative_core.dm index cb224438c00..98758d5a369 100644 --- a/code/modules/mining/equipment/monster_organs/regenerative_core.dm +++ b/code/modules/mining/equipment/monster_organs/regenerative_core.dm @@ -36,7 +36,7 @@ /// Log applications and apply moodlet. /obj/item/organ/internal/monster_core/regenerative_core/apply_to(mob/living/target, mob/user) - target.add_mood_event("regenerative core", /datum/mood_event/healsbadman) + target.add_mood_event(MOOD_CATEGORY_LEGION_CORE, /datum/mood_event/healsbadman) if (target != user) target.visible_message(span_notice("[user] forces [target] to apply [src]... Black tendrils entangle and reinforce [target.p_them()]!")) SSblackbox.record_feedback("nested tally", "hivelord_core", 1, list("[type]", "used", "other")) diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index e7199e59938..20a436dc5c6 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -144,7 +144,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) icon_state = "folded_extraction" /obj/item/fulton_core/attack_self(mob/user) - if(do_after(user,15,target = user) && !QDELETED(src)) + if(do_after(user, 1.5 SECONDS, target = user) && !QDELETED(src)) new /obj/structure/extraction_point(get_turf(user)) playsound(src, 'sound/items/deconstruct.ogg', vol = 50, vary = TRUE, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE) qdel(src) @@ -156,6 +156,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) icon_state = "extraction_point" anchored = TRUE density = FALSE + obj_flags = CAN_BE_HIT | UNIQUE_RENAME var/beacon_network = "station" /obj/structure/extraction_point/Initialize(mapload) @@ -168,6 +169,15 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) GLOB.total_extraction_beacons -= src return ..() +/obj/structure/extraction_point/attack_hand(mob/living/user, list/modifiers) + . = ..() + balloon_alert_to_viewers("undeploying...") + if(!do_after(user, 1.5 SECONDS, src)) + return + new /obj/item/fulton_core(drop_location()) + playsound(src, 'sound/items/deconstruct.ogg', vol = 50, vary = TRUE, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE) + qdel(src) + /obj/structure/extraction_point/update_overlays() . = ..() . += emissive_appearance(icon, "[icon_state]_light", src, alpha = src.alpha) diff --git a/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid_ai.dm b/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid_ai.dm index e2c67af2467..c88178135dc 100644 --- a/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid_ai.dm +++ b/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid_ai.dm @@ -2,6 +2,7 @@ blackboard = list( BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, BB_BASIC_MOB_FLEEING = TRUE, + BB_BASIC_MOB_FLEE_DISTANCE = 5, ) ai_movement = /datum/ai_movement/basic_avoidance @@ -47,7 +48,6 @@ /datum/ai_behavior/run_away_from_target/mega_arachnid clear_failed_targets = FALSE - run_distance = 5 ///only engage in melee combat against cuffed targets, otherwise keep throwing restraints at them /datum/ai_planning_subtree/basic_melee_attack_subtree/mega_arachnid diff --git a/code/modules/mob/living/basic/lavaland/basilisk/basilisk.dm b/code/modules/mob/living/basic/lavaland/basilisk/basilisk.dm index c662870393c..45bfd74d23b 100644 --- a/code/modules/mob/living/basic/lavaland/basilisk/basilisk.dm +++ b/code/modules/mob/living/basic/lavaland/basilisk/basilisk.dm @@ -75,6 +75,7 @@ /datum/ai_controller/basic_controller/basilisk blackboard = list( BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, + BB_AGGRO_RANGE = 5, ) ai_movement = /datum/ai_movement/basic_avoidance diff --git a/code/modules/mob/living/basic/lavaland/goliath/goliath.dm b/code/modules/mob/living/basic/lavaland/goliath/goliath.dm index 95df44a8326..b99e254853e 100644 --- a/code/modules/mob/living/basic/lavaland/goliath/goliath.dm +++ b/code/modules/mob/living/basic/lavaland/goliath/goliath.dm @@ -44,6 +44,8 @@ COOLDOWN_DECLARE(ability_animation_cooldown) /// Our base tentacles ability var/datum/action/cooldown/mob_cooldown/goliath_tentacles/tentacles + /// Our long-ranged tentacles ability + var/datum/action/cooldown/mob_cooldown/tentacle_grasp/tentacle_line /// Things we want to eat off the floor (or a plate, we're not picky) var/static/list/goliath_foods = list(/obj/item/food/grown/ash_flora, /obj/item/food/bait/worm) @@ -70,9 +72,9 @@ var/datum/action/cooldown/mob_cooldown/tentacle_burst/melee_tentacles = new (src) melee_tentacles.Grant(src) AddComponent(/datum/component/revenge_ability, melee_tentacles, targetting = ai_controller.blackboard[BB_TARGETTING_DATUM], max_range = 1, target_self = TRUE) - var/datum/action/cooldown/mob_cooldown/tentacle_grasp/ranged_tentacles = new (src) - ranged_tentacles.Grant(src) - AddComponent(/datum/component/revenge_ability, ranged_tentacles, targetting = ai_controller.blackboard[BB_TARGETTING_DATUM], min_range = 2, max_range = 9) + tentacle_line = new (src) + tentacle_line.Grant(src) + AddComponent(/datum/component/revenge_ability, tentacle_line, targetting = ai_controller.blackboard[BB_TARGETTING_DATUM], min_range = 2, max_range = 9) tentacles_ready() RegisterSignal(src, COMSIG_MOB_ABILITY_FINISHED, PROC_REF(used_ability)) @@ -82,6 +84,7 @@ /mob/living/basic/mining/goliath/Destroy() QDEL_NULL(tentacles) + QDEL_NULL(tentacle_line) return ..() /mob/living/basic/mining/goliath/examine(mob/user) @@ -167,6 +170,12 @@ . = ..() faction = new_friend.faction.Copy() +/mob/living/basic/mining/goliath/RangedAttack(atom/atom_target, modifiers) + tentacles?.Trigger(target = atom_target) + +/mob/living/basic/mining/goliath/ranged_secondary_attack(atom/atom_target, modifiers) + tentacle_line?.Trigger(target = atom_target) + /// Legacy Goliath mob with different sprites, largely the same behaviour /mob/living/basic/mining/goliath/ancient name = "ancient goliath" diff --git a/code/modules/mob/living/basic/lavaland/hivelord/hivelord.dm b/code/modules/mob/living/basic/lavaland/hivelord/hivelord.dm new file mode 100644 index 00000000000..256ab1fbd8f --- /dev/null +++ b/code/modules/mob/living/basic/lavaland/hivelord/hivelord.dm @@ -0,0 +1,114 @@ +/// Mob which retreats and spawns annoying sub-mobs to attack you +/mob/living/basic/mining/hivelord + name = "hivelord" + desc = "A levitating swarm of tiny creatures which act as a single individual. When threatened or hunting they rapidly replicate additional short-lived bodies." + icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + icon_state = "hivelord" + icon_living = "hivelord" + // icon_aggro = "hivelord_alert" + icon_dead = "hivelord_dead" + icon_gib = "syndicate_gib" + mob_biotypes = MOB_ORGANIC + speed = 2 + maxHealth = 75 + health = 75 + melee_damage_lower = 0 + melee_damage_upper = 0 + attack_verb_continuous = "weakly tackles" + attack_verb_simple = "weakly tackles" + speak_emote = list("telepathically cries") + attack_sound = 'sound/weapons/pierce.ogg' + throw_blocked_message = "passes between the bodies of the" + obj_damage = 0 + pass_flags = PASSTABLE + ai_controller = /datum/ai_controller/basic_controller/hivelord + /// Mobs to spawn when we die, varedit this to be recursive to give the players a fun surprise + var/death_spawn_type = /mob/living/basic/hivelord_brood + /// Action which spawns worms + var/datum/action/cooldown/mob_cooldown/hivelord_spawn/spawn_brood + +/mob/living/basic/mining/hivelord/Initialize(mapload) + . = ..() + var/static/list/death_loot = list(/obj/item/organ/internal/monster_core/regenerative_core) + AddElement(/datum/element/relay_attackers) + AddElement(/datum/element/death_drops, death_loot) + AddComponent(/datum/component/clickbox, icon_state = "hivelord", max_scale = INFINITY, dead_state = "hivelord_dead") // They writhe so much. + AddComponent(/datum/component/appearance_on_aggro, aggro_state = "hivelord_alert") + spawn_brood = new(src) + spawn_brood.Grant(src) + ai_controller.set_blackboard_key(BB_TARGETTED_ACTION, spawn_brood) + +/mob/living/basic/mining/hivelord/Destroy() + QDEL_NULL(spawn_brood) + return ..() + +/mob/living/basic/mining/hivelord/death(gibbed) + . = ..() + var/list/safe_turfs = RANGE_TURFS(1, src) - get_turf(src) + for (var/turf/check_turf as anything in safe_turfs) + if (check_turf.is_blocked_turf(exclude_mobs = TRUE)) + safe_turfs -= check_turf + + var/turf/our_turf = get_turf(src) + for (var/i in 1 to 3) + if (!length(safe_turfs)) + return + var/turf/land_turf = pick_n_take(safe_turfs) + var/obj/effect/temp_visual/hivebrood_spawn/forecast = new(land_turf) + forecast.create_from(death_spawn_type, our_turf, CALLBACK(src, PROC_REF(complete_spawn), land_turf)) + +/// Spawns a worm on the specified turf +/mob/living/basic/mining/hivelord/proc/complete_spawn(turf/spawn_turf) + var/mob/living/brood = new death_spawn_type(spawn_turf) + brood.faction = faction + brood.ai_controller?.set_blackboard_key(ai_controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]) + brood.dir = get_dir(src, spawn_turf) + +/mob/living/basic/mining/hivelord/RangedAttack(atom/atom_target, modifiers) + spawn_brood?.Trigger(target = atom_target) + +/// Attack worms spawned by the hivelord +/mob/living/basic/hivelord_brood + name = "hivelord brood" + desc = "Short-lived attack form of the hivelord. One isn't much of a threat, but..." + icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + icon_state = "hivelord_brood" + icon_living = "hivelord_brood" + icon_dead = "hivelord_brood" + icon_gib = "syndicate_gib" + friendly_verb_continuous = "chirrups near" + friendly_verb_simple = "chirrup near" + mob_size = MOB_SIZE_SMALL + basic_mob_flags = DEL_ON_DEATH + pass_flags = PASSTABLE | PASSMOB + mob_biotypes = MOB_ORGANIC|MOB_BEAST + faction = list(FACTION_MINING) + unsuitable_atmos_damage = 0 + minimum_survivable_temperature = 0 + maximum_survivable_temperature = INFINITY + speed = 1.5 + maxHealth = 1 + health = 1 + melee_damage_lower = 2 + melee_damage_upper = 2 + attack_verb_continuous = "bites" + attack_verb_simple = "bite" + speak_emote = list("telepathically cries") + attack_sound = 'sound/weapons/bite.ogg' + attack_vis_effect = ATTACK_EFFECT_BITE + obj_damage = 0 + density = FALSE + ai_controller = /datum/ai_controller/basic_controller/simple_hostile + +/mob/living/basic/hivelord_brood/Initialize(mapload) + . = ..() + add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE), INNATE_TRAIT) + AddElement(/datum/element/simple_flying) + AddComponent(/datum/component/swarming) + AddComponent(/datum/component/clickbox, icon_state = "hivelord", max_scale = INFINITY) + addtimer(CALLBACK(src, PROC_REF(death)), 10 SECONDS) + +/mob/living/basic/hivelord_brood/death(gibbed) + if (!gibbed) + new /obj/effect/temp_visual/hive_spawn_wither(get_turf(src), /* copy_from = */ src) + return ..() diff --git a/code/modules/mob/living/basic/lavaland/hivelord/hivelord_ai.dm b/code/modules/mob/living/basic/lavaland/hivelord/hivelord_ai.dm new file mode 100644 index 00000000000..fd7983de397 --- /dev/null +++ b/code/modules/mob/living/basic/lavaland/hivelord/hivelord_ai.dm @@ -0,0 +1,14 @@ +/// Basically just keep away and shit out worms +/datum/ai_controller/basic_controller/hivelord + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, + BB_AGGRO_RANGE = 5, // Only get mad at people nearby + ) + + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + planning_subtrees = list( + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/maintain_distance, + /datum/ai_planning_subtree/targeted_mob_ability, + ) diff --git a/code/modules/mob/living/basic/lavaland/hivelord/spawn_hivelord_brood.dm b/code/modules/mob/living/basic/lavaland/hivelord/spawn_hivelord_brood.dm new file mode 100644 index 00000000000..3fee2a003f3 --- /dev/null +++ b/code/modules/mob/living/basic/lavaland/hivelord/spawn_hivelord_brood.dm @@ -0,0 +1,124 @@ +/// Spawns a little worm nearby +/datum/action/cooldown/mob_cooldown/hivelord_spawn + name = "Spawn Brood" + desc = "Release an attack form to an adjacent square to attack your target or anyone nearby." + button_icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + button_icon_state = "hivelord_brood" + background_icon_state = "bg_demon" + overlay_icon_state = "bg_demon_border" + click_to_activate = TRUE + cooldown_time = 2 SECONDS + melee_cooldown_time = 0 + check_flags = AB_CHECK_CONSCIOUS | AB_CHECK_INCAPACITATED + shared_cooldown = NONE + /// If a mob is not clicked directly, inherit targetting data from this blackboard key and setting it upon this target key + var/ai_target_key = BB_BASIC_MOB_CURRENT_TARGET + /// What are we actually spawning? + var/spawn_type = /mob/living/basic/hivelord_brood + /// Do we automatically fire with no cooldown when damaged? + var/trigger_on_hit = TRUE + /// Minimum time between triggering on hit + var/on_hit_delay = 1 SECONDS + /// Delay between triggering on hit + COOLDOWN_DECLARE(on_hit_cooldown) + +/datum/action/cooldown/mob_cooldown/hivelord_spawn/Grant(mob/granted_to) + . = ..() + if (isnull(owner)) + return + if (trigger_on_hit) + RegisterSignal(owner, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(on_attacked)) + +/datum/action/cooldown/mob_cooldown/hivelord_spawn/Remove(mob/removed_from) + UnregisterSignal(removed_from, COMSIG_ATOM_WAS_ATTACKED) + return ..() + +/datum/action/cooldown/mob_cooldown/hivelord_spawn/Activate(atom/target) + . = ..() + if (!spawn_brood(target, target_turf = get_turf(target))) + StartCooldown(0.5 SECONDS) + return + StartCooldown() + +/// Called when someone whacks us +/datum/action/cooldown/mob_cooldown/hivelord_spawn/proc/on_attacked(atom/victim, atom/attacker, attack_flags) + SIGNAL_HANDLER + if (!trigger_on_hit || !(attack_flags & ATTACKER_DAMAGING_ATTACK) || !COOLDOWN_FINISHED(src, on_hit_cooldown)) + return + COOLDOWN_START(src, on_hit_cooldown, on_hit_delay) + spawn_brood(attacker, target_turf = get_step_away(owner, attacker), feedback = FALSE) + +/// Spawn a funny little worm +/datum/action/cooldown/mob_cooldown/hivelord_spawn/proc/spawn_brood(target, turf/target_turf, feedback = TRUE) + var/ai_target = isliving(target) ? target : null + if (isnull(ai_target)) + ai_target = owner.ai_controller?.blackboard[ai_target_key] + + var/dir_to_target = get_dir(owner, target_turf) + var/list/target_turfs = list() + for(var/i in -1 to 1) + var/turn_amount = rand(-1, 1) * 45 + var/test_dir = turn(dir_to_target, turn_amount) + var/turf/test_turf = get_step(owner, test_dir) + if (test_turf.is_blocked_turf(exclude_mobs = TRUE)) + continue + target_turfs += test_turf + + if (!length(target_turfs)) + if (feedback) + owner.balloon_alert(owner, "no room!") + StartCooldown(0.5 SECONDS) + return FALSE + + var/turf/land_turf = pick(target_turfs) + var/obj/effect/temp_visual/hivebrood_spawn/forecast = new(land_turf) + forecast.create_from(spawn_type, get_turf(owner), CALLBACK(src, PROC_REF(complete_spawn), land_turf, ai_target)) + StartCooldown() + + return TRUE + +/// Actually create a mob +/datum/action/cooldown/mob_cooldown/hivelord_spawn/proc/complete_spawn(turf/spawn_turf, target) + var/mob/living/brood = new spawn_type(spawn_turf) + brood.faction = owner.faction + brood.ai_controller?.set_blackboard_key(ai_target_key, target) + brood.dir = get_dir(owner, spawn_turf) + +#define BROOD_ARC_Y_OFFSET 8 +#define BROOD_ARC_ROTATION 45 + +/// Fast animation to show a worm spawning +/obj/effect/temp_visual/hivebrood_spawn + name = "brood spawn" + duration = 0.3 SECONDS + alpha = 0 + +/// Set up our visuals and start a timer for a callback +/obj/effect/temp_visual/hivebrood_spawn/proc/create_from(mob/living/spawn_type, turf/spawn_from, datum/callback/on_completed) + addtimer(on_completed, duration, TIMER_DELETE_ME) + + var/turf/my_turf = get_turf(src) + dir = get_dir(spawn_from, my_turf) + var/move_x = (my_turf.x - spawn_from.x) * world.icon_size + var/move_y = (my_turf.y - spawn_from.y) * world.icon_size + pixel_x = -move_x + pixel_y = -move_y + + icon = initial(spawn_type.icon) + icon_state = initial(spawn_type.icon_state) + + + animate(src, pixel_x = 0, time = duration) + animate(src, pixel_y = BROOD_ARC_Y_OFFSET - (move_y * 0.5), time = duration * 0.5, flags = ANIMATION_PARALLEL, easing = SINE_EASING | EASE_OUT) + animate(pixel_y = 0, time = duration * 0.5, easing = SINE_EASING | EASE_IN) + animate(src, alpha = 255, time = duration * 0.5, flags = ANIMATION_PARALLEL) + + if (dir & (NORTH | EAST)) + transform = matrix().Turn(-BROOD_ARC_ROTATION) + animate(src, transform = matrix(), time = duration, flags = ANIMATION_PARALLEL) + else + transform = matrix().Turn(BROOD_ARC_ROTATION) + animate(src, transform = matrix(), time = duration, flags = ANIMATION_PARALLEL) + +#undef BROOD_ARC_Y_OFFSET +#undef BROOD_ARC_ROTATION diff --git a/code/modules/mob/living/basic/lavaland/legion/legion.dm b/code/modules/mob/living/basic/lavaland/legion/legion.dm new file mode 100644 index 00000000000..7c6bd0fd170 --- /dev/null +++ b/code/modules/mob/living/basic/lavaland/legion/legion.dm @@ -0,0 +1,158 @@ +/** + * Avoids players while throwing skulls at them. + * Legion skulls heal allies, bite enemies, and infest dying humans to make more legions. + */ +/mob/living/basic/mining/legion + name = "legion" + desc = "You can still see what was once a human under the shifting mass of corruption." + icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + icon_state = "legion" + icon_living = "legion" + icon_dead = "legion" + icon_gib = "syndicate_gib" + mob_biotypes = MOB_ORGANIC|MOB_HUMANOID + basic_mob_flags = DEL_ON_DEATH + speed = 3 + maxHealth = 75 + health = 75 + obj_damage = 60 + melee_damage_lower = 15 + melee_damage_upper = 15 + attack_verb_continuous = "lashes out at" + attack_verb_simple = "lash out at" + speak_emote = list("gurgles") + attack_sound = 'sound/weapons/pierce.ogg' + throw_blocked_message = "bounces harmlessly off of" + crusher_loot = /obj/item/crusher_trophy/legion_skull + death_message = "wails in chorus and dissolves into quivering flesh." + ai_controller = /datum/ai_controller/basic_controller/legion + /// What kind of mob do we spawn? + var/brood_type = /mob/living/basic/legion_brood + /// What kind of corpse spawner do we leave behind on death? + var/corpse_type = /obj/effect/mob_spawn/corpse/human/legioninfested + /// Who is inside of us? + var/mob/living/stored_mob + +/mob/living/basic/mining/legion/Initialize(mapload) + . = ..() + AddElement(/datum/element/death_drops, get_loot_list()) + AddElement(/datum/element/content_barfer) + + var/datum/action/cooldown/mob_cooldown/skull_launcher/skull_launcher = new(src) + skull_launcher.Grant(src) + skull_launcher.spawn_type = brood_type + ai_controller.blackboard[BB_TARGETTED_ACTION] = skull_launcher + +/// Create what we want to drop on death, in proc form so we can always return a static list +/mob/living/basic/mining/legion/proc/get_loot_list() + var/static/list/death_loot = list(/obj/item/organ/internal/monster_core/regenerative_core/legion) + return death_loot + +/mob/living/basic/mining/legion/Exited(atom/movable/gone, direction) + . = ..() + if (gone != stored_mob) + return + ai_controller.clear_blackboard_key(BB_LEGION_CORPSE) + stored_mob.remove_status_effect(/datum/status_effect/grouped/stasis, STASIS_LEGION_EATEN) + stored_mob.add_mood_event(MOOD_CATEGORY_LEGION_CORE, /datum/mood_event/healsbadman/long_term) // This will still probably mostly be gone before you are alive + stored_mob = null + +/mob/living/basic/mining/legion/death(gibbed) + if (isnull(stored_mob)) + new corpse_type(loc) + return ..() + +/// Put a corpse in this guy +/mob/living/basic/mining/legion/proc/consume(mob/living/consumed) + new /obj/effect/gibspawner/generic(consumed.loc) + gender = consumed.gender + name = consumed.real_name + consumed.investigate_log("has been killed by hivelord infestation.", INVESTIGATE_DEATHS) + consumed.death() + consumed.extinguish_mob() + consumed.fully_heal(HEAL_DAMAGE) + consumed.apply_status_effect(/datum/status_effect/grouped/stasis, STASIS_LEGION_EATEN) + consumed.forceMove(src) + ai_controller?.set_blackboard_key(BB_LEGION_CORPSE, consumed) + ai_controller?.set_blackboard_key(BB_LEGION_RECENT_LINES, consumed.copy_recent_speech(line_chance = 80)) + stored_mob = consumed + visible_message(span_warning("[src] staggers to [p_their()] feet!")) + if (prob(75)) + return + // Congratulations you have won a special prize: cancer + var/obj/item/organ/internal/legion_tumour/cancer = new() + cancer.Insert(consumed, special = TRUE, drop_if_replaced = FALSE) + +/// A Legion which only drops skeletons instead of corpses which might have fun loot, so it cannot be farmed +/mob/living/basic/mining/legion/spawner_made + corpse_type = /obj/effect/mob_spawn/corpse/human/legioninfested/skeleton/charred + + +/// Like a Legion but it's an adorable snowman +/mob/living/basic/mining/legion/snow + name = "snow legion" + desc = "You can vaguely see what was once a human under the densely packed snow. Cute, but macabre." + icon = 'icons/mob/simple/icemoon/icemoon_monsters.dmi' + icon_state = "snowlegion" + icon_living = "snowlegion" + // icon_aggro = "snowlegion_alive" + icon_dead = "snowlegion" + brood_type = /mob/living/basic/legion_brood/snow + corpse_type = /obj/effect/mob_spawn/corpse/human/legioninfested/snow + +/mob/living/basic/mining/legion/snow/Initialize(mapload) + . = ..() + AddComponent(/datum/component/appearance_on_aggro, aggro_state = "snowlegion_alive") // Surprise! I was real! + +/// As Snow Legion but spawns corpses which don't have any exciting loot +/mob/living/basic/mining/legion/snow/spawner_made + corpse_type = /obj/effect/mob_spawn/corpse/human/legioninfested/skeleton + + +/// Like a Legion but shorter and faster +/mob/living/basic/mining/legion/dwarf + name = "dwarf legion" + desc = "You can still see what was once a rather small human under the shifting mass of corruption." + icon_state = "dwarf_legion" + icon_living = "dwarf_legion" + icon_dead = "dwarf_legion" + maxHealth = 60 + health = 60 + speed = 2 + crusher_drop_chance = 20 + corpse_type = /obj/effect/mob_spawn/corpse/human/legioninfested/dwarf + + +/// Like a Legion but larger and spawns regular Legions, not currently used anywhere and very soulful +/mob/living/basic/mining/legion/large + name = "myriad" + desc = "A legion of legions, a dead end to whatever form the Necropolis was attempting to create." + icon = 'icons/mob/simple/lavaland/64x64megafauna.dmi' + icon_state = "legion" + icon_living = "legion" + icon_dead = "legion" + health_doll_icon = "legion" + speed = 5 + health = 450 + maxHealth = 450 + melee_damage_lower = 20 + melee_damage_upper = 20 + obj_damage = 30 + pixel_x = -16 + sentience_type = SENTIENCE_BOSS + +/mob/living/basic/mining/legion/large/Initialize(mapload) + . = ..() + AddComponent(\ + /datum/component/spawner,\ + spawn_types = list(/mob/living/basic/mining/legion),\ + spawn_time = 20 SECONDS,\ + max_spawned = 3,\ + spawn_text = "peels itself off from",\ + faction = faction,\ + ) + +/// Create what we want to drop on death, in proc form so we can always return a static list +/mob/living/basic/mining/legion/large/get_loot_list() + var/static/list/death_loot = list(/obj/item/organ/internal/monster_core/regenerative_core/legion = 3, /obj/effect/mob_spawn/corpse/human/legioninfested = 4) + return death_loot diff --git a/code/modules/mob/living/basic/lavaland/legion/legion_ai.dm b/code/modules/mob/living/basic/lavaland/legion/legion_ai.dm new file mode 100644 index 00000000000..6b3525cb32a --- /dev/null +++ b/code/modules/mob/living/basic/lavaland/legion/legion_ai.dm @@ -0,0 +1,77 @@ +/// Keep away and launch skulls at every opportunity, prioritising injured allies +/datum/ai_controller/basic_controller/legion + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/attack_until_dead/legion, + BB_BASIC_MOB_FLEEING = TRUE, + BB_AGGRO_RANGE = 5, // Unobservant + BB_BASIC_MOB_FLEE_DISTANCE = 6, + ) + + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + planning_subtrees = list( + /datum/ai_planning_subtree/random_speech/legion, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/targeted_mob_ability, + /datum/ai_planning_subtree/flee_target/legion, + ) + +/// Chase and attack whatever we are targetting, if it's friendly we will heal them +/datum/ai_controller/basic_controller/legion_brood + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/attack_until_dead/legion, + ) + + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + planning_subtrees = list( + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) + +/// Target nearby friendlies if they are hurt (and are not themselves Legions) +/datum/targetting_datum/basic/attack_until_dead/legion + +/datum/targetting_datum/basic/attack_until_dead/legion/faction_check(mob/living/living_mob, mob/living/the_target) + if (!living_mob.faction_check_mob(the_target, exact_match = check_factions_exactly)) + return FALSE + if (istype(the_target, living_mob.type)) + return TRUE + var/atom/created_by = living_mob.ai_controller.blackboard[BB_LEGION_BROOD_CREATOR] + if (!QDELETED(created_by) && istype(the_target, created_by.type)) + return TRUE + return the_target.stat == DEAD || the_target.health >= the_target.maxHealth + +/// Don't run away from friendlies +/datum/ai_planning_subtree/flee_target/legion + +/datum/ai_planning_subtree/flee_target/legion/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/mob/living/target = controller.blackboard[target_key] + if (QDELETED(target) || target.faction_check_mob(controller.pawn)) + return // Only flee if we have a hostile target + return ..() + +/// Make spooky sounds, if we have a corpse inside then impersonate them +/datum/ai_planning_subtree/random_speech/legion + speech_chance = 1 + speak = list("Come...", "Legion...", "Why...?") + emote_hear = list("groans.", "wails.", "whimpers.") + emote_see = list("twitches.", "shudders.") + /// Stuff to specifically say into a radio + var/list/radio_speech = list("Come...", "Why...?") + +/datum/ai_planning_subtree/random_speech/legion/speak(datum/ai_controller/controller) + var/mob/living/carbon/human/victim = controller.blackboard[BB_LEGION_CORPSE] + if (QDELETED(victim) || prob(30)) + return ..() + + var/list/remembered_speech = controller.blackboard[BB_LEGION_RECENT_LINES] || list() + + if (length(remembered_speech) && prob(50)) // Don't spam the radio + controller.queue_behavior(/datum/ai_behavior/perform_speech, pick(remembered_speech)) + return + + var/obj/item/radio/mob_radio = locate() in victim.contents + if (QDELETED(mob_radio)) + return ..() // No radio, just talk funny + controller.queue_behavior(/datum/ai_behavior/perform_speech_radio, pick(radio_speech + remembered_speech), mob_radio, list(RADIO_CHANNEL_SUPPLY, RADIO_CHANNEL_COMMON)) diff --git a/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm b/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm new file mode 100644 index 00000000000..bc21bd0e506 --- /dev/null +++ b/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm @@ -0,0 +1,99 @@ +/// A spooky skull which heals lavaland mobs, attacks miners, and infests their bodies +/mob/living/basic/legion_brood + name = "legion" + desc = "One of many." + icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + icon_state = "legion_head" + icon_living = "legion_head" + icon_dead = "legion_head" + icon_gib = "syndicate_gib" + basic_mob_flags = DEL_ON_DEATH + mob_size = MOB_SIZE_SMALL + pass_flags = PASSTABLE | PASSMOB + mob_biotypes = MOB_ORGANIC|MOB_BEAST + faction = list(FACTION_MINING) + unsuitable_atmos_damage = 0 + minimum_survivable_temperature = 0 + maximum_survivable_temperature = INFINITY + friendly_verb_continuous = "chatters near" + friendly_verb_simple = "chatter near" + maxHealth = 1 + health = 1 + melee_damage_lower = 12 + melee_damage_upper = 12 + obj_damage = 0 + attack_verb_continuous = "bites" + attack_verb_simple = "bite" + attack_vis_effect = ATTACK_EFFECT_BITE + speak_emote = list("echoes") // who the fuck speaking as this mob it dies 10 seconds after it spawns + attack_sound = 'sound/weapons/pierce.ogg' + density = FALSE + ai_controller = /datum/ai_controller/basic_controller/legion_brood + /// Reference to a guy who made us + var/mob/living/created_by + +/mob/living/basic/legion_brood/Initialize(mapload) + . = ..() + add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE), INNATE_TRAIT) + AddElement(/datum/element/simple_flying) + AddComponent(/datum/component/swarming) + AddComponent(/datum/component/clickbox, icon_state = "sphere", max_scale = 2) + addtimer(CALLBACK(src, PROC_REF(death)), 10 SECONDS) + +/mob/living/basic/legion_brood/death(gibbed) + if (!gibbed) + new /obj/effect/temp_visual/hive_spawn_wither(get_turf(src), /* copy_from = */ src) + return ..() + +/mob/living/basic/legion_brood/melee_attack(mob/living/target, list/modifiers, ignore_cooldown) + if (ishuman(target) && target.stat > SOFT_CRIT) + infest(target) + return + if (isliving(target) && faction_check_mob(target) && !istype(target, created_by?.type)) + visible_message(span_warning("[src] melds with [target]'s flesh!")) + target.apply_status_effect(/datum/status_effect/regenerative_core) + new /obj/effect/temp_visual/heal(get_turf(target), COLOR_HEALING_CYAN) + death() + return + return ..() + +/// Turn the targetted mob into one of us +/mob/living/basic/legion_brood/proc/infest(mob/living/target) + visible_message(span_warning("[name] burrows into the flesh of [target]!")) + var/spawn_type = get_legion_type(target) + var/mob/living/basic/mining/legion/new_legion = new spawn_type(loc) + new_legion.consume(target) + new_legion.faction = faction.Copy() + qdel(src) + +/// Returns the kind of legion we make out of the target +/mob/living/basic/legion_brood/proc/get_legion_type(mob/living/target) + if (HAS_TRAIT(target, TRAIT_DWARF)) + return /mob/living/basic/mining/legion/dwarf + return /mob/living/basic/mining/legion + +/// Sets someone as our creator, mostly so you can't use skulls to heal yourself +/mob/living/basic/legion_brood/proc/assign_creator(mob/living/creator, copy_full_faction = TRUE) + if (copy_full_faction) + faction = creator.faction.Copy() + else + faction |= REF(creator) + created_by = creator + ai_controller?.set_blackboard_key(BB_LEGION_BROOD_CREATOR, creator) + RegisterSignal(creator, COMSIG_QDELETING, PROC_REF(creator_destroyed)) + +/// Reference handling +/mob/living/basic/legion_brood/proc/creator_destroyed() + SIGNAL_HANDLER + created_by = null + +/// Like the Legion's summoned skull but funnier (it's snow now) +/mob/living/basic/legion_brood/snow + name = "snow legion" + icon = 'icons/mob/simple/icemoon/icemoon_monsters.dmi' + icon_state = "snowlegion_head" + icon_living = "snowlegion_head" + icon_dead = "snowlegion_head" + +/mob/living/basic/legion_brood/snow/get_legion_type(mob/living/target) + return /mob/living/basic/mining/legion/snow diff --git a/code/modules/mob/living/basic/lavaland/legion/legion_tumour.dm b/code/modules/mob/living/basic/lavaland/legion/legion_tumour.dm new file mode 100644 index 00000000000..078af57de2a --- /dev/null +++ b/code/modules/mob/living/basic/lavaland/legion/legion_tumour.dm @@ -0,0 +1,159 @@ +/// Left behind when a legion infects you, for medical enrichment +/obj/item/organ/internal/legion_tumour + name = "legion tumour" + desc = "A mass of pulsing flesh and dark tendrils, containing the power to regenerate flesh at a terrible cost." + failing_desc = "pulses and writhes with horrible life, reaching towards you with its tendrils!" + icon = 'icons/obj/medical/organs/mining_organs.dmi' + icon_state = "legion_remains" + zone = BODY_ZONE_CHEST + slot = ORGAN_SLOT_PARASITE_EGG + decay_factor = STANDARD_ORGAN_DECAY * 3 // About 5 minutes outside of a host + /// What stage of growth the corruption has reached. + var/stage = 0 + /// We apply this status effect periodically or when used on someone + var/applied_status = /datum/status_effect/regenerative_core + /// How long have we been in this stage? + var/elapsed_time = 0 SECONDS + /// How long does it take to advance one stage? + var/growth_time = 80 SECONDS // Long enough that if you go back to lavaland without realising it you're not totally fucked + /// What kind of mob will we transform into? + var/spawn_type = /mob/living/basic/mining/legion + /// Spooky sounds to play as you start to turn + var/static/list/spooky_sounds = list( + 'sound/voice/lowHiss1.ogg', + 'sound/voice/lowHiss2.ogg', + 'sound/voice/lowHiss3.ogg', + 'sound/voice/lowHiss4.ogg', + ) + +/obj/item/organ/internal/legion_tumour/Initialize(mapload) + . = ..() + animate_pulse() + +/obj/item/organ/internal/legion_tumour/apply_organ_damage(damage_amount, maximum, required_organ_flag) + var/was_failing = organ_flags & ORGAN_FAILING + . = ..() + if (was_failing != (organ_flags & ORGAN_FAILING)) + animate_pulse() + +/obj/item/organ/internal/legion_tumour/set_organ_damage(damage_amount, required_organ_flag) + . = ..() + animate_pulse() + +/// Do a heartbeat animation depending on if we're failing or not +/obj/item/organ/internal/legion_tumour/proc/animate_pulse() + animate(src, transform = matrix()) // Stop any current animation + + var/speed_divider = organ_flags & ORGAN_FAILING ? 2 : 1 + + animate(src, transform = matrix().Scale(1.1), time = 0.5 SECONDS / speed_divider, easing = SINE_EASING | EASE_OUT, loop = -1, flags = ANIMATION_PARALLEL) + animate(transform = matrix(), time = 0.5 SECONDS / speed_divider, easing = SINE_EASING | EASE_IN) + animate(transform = matrix(), time = 2 SECONDS / speed_divider) + +/obj/item/organ/internal/legion_tumour/Remove(mob/living/carbon/egg_owner, special) + . = ..() + stage = 0 + elapsed_time = 0 + +/obj/item/organ/internal/legion_tumour/attack(mob/living/target, mob/living/user, params) + if (try_apply(target, user)) + qdel(src) + return + return ..() + +/// Smear it on someone like a regen core, why not. Make sure they're alive though. +/obj/item/organ/internal/legion_tumour/proc/try_apply(mob/living/target, mob/user) + if(!user.Adjacent(target) || !isliving(target)) + return FALSE + + if (target.stat <= SOFT_CRIT && !(organ_flags & ORGAN_FAILING)) + target.add_mood_event(MOOD_CATEGORY_LEGION_CORE, /datum/mood_event/healsbadman) + target.apply_status_effect(applied_status) + + if (target != user) + target.visible_message(span_notice("[user] splatters [target] with [src]... Disgusting tendrils pull [target.p_their()] wounds shut!")) + else + to_chat(user, span_notice("You smear [src] on yourself. Disgusting tendrils pull your wounds closed.")) + return TRUE + + if (!ishuman(target)) + return FALSE + + target.visible_message(span_boldwarning("[user] splatters [target] with [src]... and it springs into horrible life!")) + var/mob/living/basic/legion_brood/skull = new(target.loc) + skull.melee_attack(target) + return TRUE + +/obj/item/organ/internal/legion_tumour/on_life(seconds_per_tick, times_fired) + . = ..() + if (QDELETED(src) || QDELETED(owner)) + return + + if (stage >= 2) + if(SPT_PROB(stage / 5, seconds_per_tick)) + to_chat(owner, span_notice("You feel a bit better.")) + owner.apply_status_effect(applied_status) // It's not all bad! + if(SPT_PROB(1, seconds_per_tick)) + owner.emote("twitch") + + switch(stage) + if(2, 3) + if(SPT_PROB(1, seconds_per_tick)) + to_chat(owner, span_danger("Your chest spasms!")) + if(SPT_PROB(1, seconds_per_tick)) + to_chat(owner, span_danger("You feel weak.")) + if(SPT_PROB(1, seconds_per_tick)) + SEND_SOUND(owner, sound(pick(spooky_sounds))) + if(SPT_PROB(2, seconds_per_tick)) + owner.vomit() + if(4, 5) + if(SPT_PROB(2, seconds_per_tick)) + to_chat(owner, span_danger("Something flexes under your skin.")) + if(SPT_PROB(2, seconds_per_tick)) + if (prob(40)) + SEND_SOUND(owner, sound('sound/voice/ghost_whisper.ogg')) + else + SEND_SOUND(owner, sound(pick(spooky_sounds))) + if(SPT_PROB(3, seconds_per_tick)) + owner.vomit(vomit_type = /obj/effect/decal/cleanable/vomit/old/black_bile) + if (prob(50)) + var/turf/check_turf = get_step(owner.loc, owner.dir) + var/atom/land_turf = (check_turf.is_blocked_turf()) ? owner.loc : check_turf + var/mob/living/basic/legion_brood/child = new(land_turf) + child.assign_creator(owner, copy_full_faction = FALSE) + + if(SPT_PROB(3, seconds_per_tick)) + to_chat(owner, span_danger("Your muscles ache.")) + owner.take_bodypart_damage(3) + + if (stage == 5) + if (SPT_PROB(10, seconds_per_tick)) + infest() + return + + elapsed_time += seconds_per_tick SECONDS * ((organ_flags & ORGAN_FAILING) ? 3 : 1) // Let's call it "matured" rather than failed + if (elapsed_time < growth_time) + return + stage++ + elapsed_time = 0 + if (stage == 5) + to_chat(owner, span_bolddanger("Something is moving under your skin!")) + +/// Consume our host +/obj/item/organ/internal/legion_tumour/proc/infest() + if (QDELETED(src) || QDELETED(owner)) + return + owner.visible_message(span_boldwarning("Black tendrils burst from [owner]'s flesh, covering them in amorphous flesh!")) + var/mob/living/basic/mining/legion/new_legion = new spawn_type(owner.loc) + new_legion.consume(owner) + qdel(src) + +/obj/item/organ/internal/legion_tumour/on_find(mob/living/finder) + . = ..() + to_chat(finder, span_warning("There's an enormous tumour in [owner]'s [zone]!")) + if(stage < 4) + to_chat(finder, span_notice("Its tendrils seem to twitch towards the light.")) + return + to_chat(finder, span_notice("Its pulsing tendrils reach all throughout the body.")) + if(prob(stage * 2)) + infest() diff --git a/code/modules/mob/living/basic/lavaland/legion/spawn_legions.dm b/code/modules/mob/living/basic/lavaland/legion/spawn_legions.dm new file mode 100644 index 00000000000..1ffcafecd56 --- /dev/null +++ b/code/modules/mob/living/basic/lavaland/legion/spawn_legions.dm @@ -0,0 +1,109 @@ +/// Spawns a little worm nearby +/datum/action/cooldown/mob_cooldown/skull_launcher + name = "Launch Legion" + desc = "Propel a living piece of your body to a distant location." + button_icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + button_icon_state = "legion_head" + background_icon_state = "bg_demon" + overlay_icon_state = "bg_demon_border" + click_to_activate = TRUE + cooldown_time = 2 SECONDS + melee_cooldown_time = 0 + check_flags = AB_CHECK_CONSCIOUS | AB_CHECK_INCAPACITATED + shared_cooldown = NONE + /// If a mob is not clicked directly, inherit targetting data from this blackboard key and setting it upon this target key + var/ai_target_key = BB_BASIC_MOB_CURRENT_TARGET + /// What are we actually spawning? + var/spawn_type = /mob/living/basic/legion_brood + /// How far can we fire? + var/max_range = 7 + +/datum/action/cooldown/mob_cooldown/skull_launcher/Activate(atom/target) + var/turf/target_turf = get_turf(target) + + if (get_dist(owner, target_turf) > max_range) + target_turf = get_ranged_target_turf_direct(owner, target_turf, max_range) + + if (target_turf.is_blocked_turf()) + var/list/near_turfs = RANGE_TURFS(1, target_turf) - target_turf + for (var/turf/check_turf as anything in near_turfs) + if (check_turf.is_blocked_turf()) + near_turfs -= check_turf + if (length(near_turfs)) + target_turf = pick(near_turfs) + else if(target_turf.is_blocked_turf(exclude_mobs = TRUE)) + owner.balloon_alert(owner, "no room!") + StartCooldown(0.5 SECONDS) + return + + var/ai_target = isliving(target) ? target : null + if (isnull(ai_target)) + ai_target = owner.ai_controller?.blackboard[ai_target_key] + + var/target_dir = get_dir(owner, target) + + var/obj/effect/temp_visual/legion_skull_depart/launch = new(get_turf(owner)) + launch.set_appearance(spawn_type) + launch.dir = target_dir + new /obj/effect/temp_visual/legion_brood_indicator(target_turf) + var/obj/effect/temp_visual/legion_skull_land/land = new(target_turf) + land.dir = target_dir + land.set_appearance(spawn_type, CALLBACK(src, PROC_REF(spawn_skull), target_turf, ai_target)) + StartCooldown() + +/// Actually create a mob +/datum/action/cooldown/mob_cooldown/skull_launcher/proc/spawn_skull(turf/spawn_location, target) + var/mob/living/basic/legion_brood/brood = new spawn_type(spawn_location) + if (istype(brood)) + brood.assign_creator(owner) + brood.ai_controller?.set_blackboard_key(ai_target_key, target) + brood.dir = get_dir(owner, spawn_location) + if (!isnull(target)) + brood.face_atom(target) + else + brood.dir = get_dir(owner, spawn_location) + + +/// Animation for launching a skull +/obj/effect/temp_visual/legion_skull_depart + name = "legion brood launch" + icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + icon_state = "legion_head" + duration = 0.25 SECONDS + +/// Copy appearance from the passed atom type +/obj/effect/temp_visual/legion_skull_depart/proc/set_appearance(atom/spawned_type) + icon = initial(spawned_type.icon) + icon_state = initial(spawned_type.icon_state) + animate(src, alpha = 0, pixel_y = 72, time = duration) + +/// Animation for landing a skull +/obj/effect/temp_visual/legion_skull_land + name = "legion brood land" + duration = 0.5 SECONDS + icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + icon_state = "legion_head" + alpha = 0 + pixel_y = 72 + +/// Copy appearance from the passed atom type and store what to do on animation complete +/obj/effect/temp_visual/legion_skull_land/proc/set_appearance(atom/spawned_type, datum/callback/on_completed) + icon = initial(spawned_type.icon) + icon_state = initial(spawned_type.icon_state) + animate(src, alpha = 0, pixel_y = 72, time = duration / 2) + animate(alpha = 255, pixel_y = 0, time = duration / 2) + addtimer(on_completed, duration, TIMER_DELETE_ME) + +/// A skull is going to be here! Oh no! +/obj/effect/temp_visual/legion_brood_indicator + name = "legion brood land" + duration = 0.75 SECONDS + layer = BELOW_MOB_LAYER + plane = GAME_PLANE + icon = 'icons/mob/telegraphing/telegraph.dmi' + icon_state = "skull" + +/obj/effect/temp_visual/legion_brood_indicator/Initialize(mapload) + . = ..() + animate(src, alpha = 255, time = 0.5 SECONDS) + animate(alpha = 0, time = 0.25 SECONDS) diff --git a/code/modules/mob/living/basic/lavaland/mining.dm b/code/modules/mob/living/basic/lavaland/mining.dm index 6b1d0de5739..0b6c4f321b6 100644 --- a/code/modules/mob/living/basic/lavaland/mining.dm +++ b/code/modules/mob/living/basic/lavaland/mining.dm @@ -2,12 +2,17 @@ /mob/living/basic/mining icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' combat_mode = TRUE + status_flags = NONE //don't inherit standard basicmob flags mob_size = MOB_SIZE_LARGE mob_biotypes = MOB_ORGANIC|MOB_BEAST faction = list(FACTION_MINING) unsuitable_atmos_damage = 0 minimum_survivable_temperature = 0 maximum_survivable_temperature = INFINITY + // Pale purple, should be red enough to see stuff on lavaland + lighting_cutoff_red = 25 + lighting_cutoff_green = 15 + lighting_cutoff_blue = 35 /// Message to output if throwing damage is absorbed var/throw_blocked_message = "bounces off" /// What crusher trophy this mob drops, if any diff --git a/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm b/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm index 1f310ac229f..a25234817f3 100644 --- a/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm +++ b/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm @@ -9,9 +9,9 @@ planning_subtrees = list( /datum/ai_planning_subtree/target_retaliate/check_faction, /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/maintain_distance, /datum/ai_planning_subtree/use_mob_ability/gaze, /datum/ai_planning_subtree/ranged_skirmish/watcher, - /datum/ai_planning_subtree/maintain_distance, ) /datum/ai_planning_subtree/use_mob_ability/gaze diff --git a/code/modules/mob/living/basic/minebots/minebot_ai.dm b/code/modules/mob/living/basic/minebots/minebot_ai.dm index 897cddb1401..a4b082f5dd1 100644 --- a/code/modules/mob/living/basic/minebots/minebot_ai.dm +++ b/code/modules/mob/living/basic/minebots/minebot_ai.dm @@ -60,6 +60,7 @@ /datum/ai_behavior/basic_ranged_attack/minebot behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT + avoid_friendly_fire = TRUE /datum/ai_planning_subtree/basic_ranged_attack_subtree/minebot/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) var/mob/living/living_pawn = controller.pawn diff --git a/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_behavior.dm b/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_behavior.dm index 4cdaba09759..28cffa4ed8e 100644 --- a/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_behavior.dm +++ b/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_behavior.dm @@ -64,6 +64,8 @@ /datum/ai_behavior/basic_ranged_attack/hivebot action_cooldown = 3 SECONDS + avoid_friendly_fire = TRUE /datum/ai_behavior/basic_ranged_attack/hivebot_rapid action_cooldown = 1.5 SECONDS + avoid_friendly_fire = TRUE diff --git a/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_subtree.dm b/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_subtree.dm index 347219d0ef0..5bd957a7609 100644 --- a/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_subtree.dm +++ b/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_subtree.dm @@ -32,7 +32,7 @@ /datum/ai_controller/basic_controller/hivebot/ranged/rapid planning_subtrees = list( /datum/ai_planning_subtree/simple_find_target, - /datum/ai_planning_subtree/basic_ranged_attack_subtree, + /datum/ai_planning_subtree/basic_ranged_attack_subtree/hivebot_rapid, /datum/ai_planning_subtree/attack_obstacle_in_path, /datum/ai_planning_subtree/hive_communicate, ) diff --git a/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm b/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm index 5a7bb075f19..d49932fb704 100644 --- a/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm +++ b/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm @@ -26,22 +26,9 @@ lighting_cutoff_green = 15 lighting_cutoff_blue = 40 - ai_controller = /datum/ai_controller/basic_controller/blankbody + ai_controller = /datum/ai_controller/basic_controller/simple_hostile_obstacles /mob/living/basic/blankbody/Initialize(mapload) . = ..() AddElement(/datum/element/swabable, CELL_LINE_TABLE_NETHER, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 0) AddComponent(/datum/component/health_scaling_effects, min_health_attack_modifier_lower = 8, min_health_attack_modifier_upper = 14) - -/datum/ai_controller/basic_controller/blankbody - blackboard = list( - BB_TARGETTING_DATUM = new /datum/targetting_datum/basic(), - ) - - ai_movement = /datum/ai_movement/basic_avoidance - idle_behavior = /datum/idle_behavior/idle_random_walk - planning_subtrees = list( - /datum/ai_planning_subtree/simple_find_target, - /datum/ai_planning_subtree/attack_obstacle_in_path, - /datum/ai_planning_subtree/basic_melee_attack_subtree, - ) diff --git a/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm b/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm index b38ada0f6e1..cdde6ad05e4 100644 --- a/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm +++ b/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm @@ -27,7 +27,7 @@ lighting_cutoff_green = 25 lighting_cutoff_blue = 15 - ai_controller = /datum/ai_controller/basic_controller/creature + ai_controller = /datum/ai_controller/basic_controller/simple_hostile_obstacles /mob/living/basic/creature/Initialize(mapload) . = ..() @@ -101,16 +101,3 @@ exit_jaunt(cast_on) return enter_jaunt(cast_on) - -/datum/ai_controller/basic_controller/creature - blackboard = list( - BB_TARGETTING_DATUM = new /datum/targetting_datum/basic(), - ) - - ai_movement = /datum/ai_movement/basic_avoidance - idle_behavior = /datum/idle_behavior/idle_random_walk - planning_subtrees = list( - /datum/ai_planning_subtree/simple_find_target, - /datum/ai_planning_subtree/attack_obstacle_in_path, - /datum/ai_planning_subtree/basic_melee_attack_subtree, - ) diff --git a/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm b/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm index 18dca95013e..3f445ea1261 100644 --- a/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm +++ b/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm @@ -28,7 +28,7 @@ lighting_cutoff_green = 15 lighting_cutoff_blue = 50 - ai_controller = /datum/ai_controller/basic_controller/migo + ai_controller = /datum/ai_controller/basic_controller/simple_hostile_obstacles var/static/list/migo_sounds /// Odds migo will dodge var/dodge_prob = 10 @@ -71,16 +71,3 @@ . = Move(get_step(loc,pick(cdir, ccdir))) if(!.)//Can't dodge there so we just carry on . = Move(moving_to, move_direction) - -/datum/ai_controller/basic_controller/migo - blackboard = list( - BB_TARGETTING_DATUM = new /datum/targetting_datum/basic(), - ) - - ai_movement = /datum/ai_movement/basic_avoidance - idle_behavior = /datum/idle_behavior/idle_random_walk - planning_subtrees = list( - /datum/ai_planning_subtree/simple_find_target, - /datum/ai_planning_subtree/attack_obstacle_in_path, - /datum/ai_planning_subtree/basic_melee_attack_subtree, - ) diff --git a/code/modules/mob/living/basic/space_fauna/paper_wizard/paper_wizard.dm b/code/modules/mob/living/basic/space_fauna/paper_wizard/paper_wizard.dm index 3b32fbb4ce7..519e8ba1a73 100644 --- a/code/modules/mob/living/basic/space_fauna/paper_wizard/paper_wizard.dm +++ b/code/modules/mob/living/basic/space_fauna/paper_wizard/paper_wizard.dm @@ -110,8 +110,7 @@ faction = list(FACTION_STICKMAN) melee_damage_lower = 1 melee_damage_upper = 5 - - ai_controller = /datum/ai_controller/basic_controller/wizard_copy + ai_controller = /datum/ai_controller/basic_controller/simple_hostile /mob/living/basic/paper_wizard/copy/Initialize(mapload) . = ..() @@ -141,18 +140,6 @@ new /obj/effect/temp_visual/small_smoke/halfsecond(get_turf(src)) qdel(src) //I see through your ruse! -/datum/ai_controller/basic_controller/wizard_copy - blackboard = list( - BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, - ) - - ai_movement = /datum/ai_movement/basic_avoidance - idle_behavior = /datum/idle_behavior/idle_random_walk - planning_subtrees = list( - /datum/ai_planning_subtree/simple_find_target, - /datum/ai_planning_subtree/basic_melee_attack_subtree, - ) - //fancy effects /obj/effect/temp_visual/paper_scatter name = "scattering paper" diff --git a/code/modules/mob/living/simple_animal/friendly/robot_customer.dm b/code/modules/mob/living/basic/space_fauna/robot_customer.dm similarity index 63% rename from code/modules/mob/living/simple_animal/friendly/robot_customer.dm rename to code/modules/mob/living/basic/space_fauna/robot_customer.dm index 13eac2939f3..e084e11f403 100644 --- a/code/modules/mob/living/simple_animal/friendly/robot_customer.dm +++ b/code/modules/mob/living/basic/space_fauna/robot_customer.dm @@ -1,45 +1,56 @@ ///Robot customers -/mob/living/simple_animal/robot_customer - name = "space-tourist bot" +/mob/living/basic/robot_customer + name = "tourist bot" maxHealth = 150 health = 150 desc = "I wonder what they'll order..." gender = NEUTER + icon = 'icons/mob/simple/tourists.dmi' icon_state = "amerifat" icon_living = "amerifat" - ///Override so it uses datum ai - can_have_ai = FALSE - AIStatus = AI_OFF - del_on_death = TRUE + + basic_mob_flags = DEL_ON_DEATH mob_biotypes = MOB_ROBOTIC|MOB_HUMANOID sentience_type = SENTIENCE_ARTIFICIAL - ai_controller = /datum/ai_controller/robot_customer + unsuitable_atmos_damage = 0 - minbodytemp = 0 - maxbodytemp = 1000 + minimum_survivable_temperature = TCMB + maximum_survivable_temperature = T0C + 1000 + + ai_controller = /datum/ai_controller/robot_customer + + /// The clothes that we draw on this tourist. var/clothes_set = "amerifat_clothes" + /// Reference to the hud that we show when the player hovers over us. var/datum/atom_hud/hud_to_show_on_hover - -/mob/living/simple_animal/robot_customer/Initialize(mapload, datum/customer_data/customer_data = /datum/customer_data/american, datum/venue/attending_venue = SSrestaurant.all_venues[/datum/venue/restaurant]) - ADD_TRAIT(src, list(TRAIT_NOMOBSWAP, TRAIT_NO_TELEPORT, TRAIT_STRONG_GRABBER), INNATE_TRAIT) // never suffer a bitch to fuck with you - AddElement(/datum/element/footstep, FOOTSTEP_OBJ_ROBOT, 1, -6, sound_vary = TRUE) +/mob/living/basic/robot_customer/Initialize( + mapload, + datum/customer_data/customer_data = /datum/customer_data/american, + datum/venue/attending_venue = SSrestaurant.all_venues[/datum/venue/restaurant], +) var/datum/customer_data/customer_info = SSrestaurant.all_customers[customer_data] - clothes_set = pick(customer_info.clothing_sets) ai_controller = customer_info.ai_controller_used + . = ..() + + ADD_TRAIT(src, list(TRAIT_NOMOBSWAP, TRAIT_NO_TELEPORT, TRAIT_STRONG_GRABBER), INNATE_TRAIT) // never suffer a bitch to fuck with you + AddElement(/datum/element/footstep, FOOTSTEP_OBJ_ROBOT, 1, -6, sound_vary = TRUE) + ai_controller.set_blackboard_key(BB_CUSTOMER_CUSTOMERINFO, customer_info) ai_controller.set_blackboard_key(BB_CUSTOMER_ATTENDING_VENUE, attending_venue) ai_controller.set_blackboard_key(BB_CUSTOMER_PATIENCE, customer_info.total_patience) + icon = customer_info.base_icon icon_state = customer_info.base_icon_state name = "[pick(customer_info.name_prefixes)]-bot" color = rgb(rand(80,255), rand(80,255), rand(80,255)) - update_icon() + clothes_set = pick(customer_info.clothing_sets) + update_appearance(UPDATE_ICON) ///Clean up on the mobs seat etc when its deleted (Either by murder or because it left) -/mob/living/simple_animal/robot_customer/Destroy() +/mob/living/basic/robot_customer/Destroy() var/datum/venue/attending_venue = ai_controller.blackboard[BB_CUSTOMER_ATTENDING_VENUE] var/obj/structure/holosign/robot_seat/our_seat = ai_controller.blackboard[BB_CUSTOMER_MY_SEAT] attending_venue.current_visitors -= src @@ -49,18 +60,18 @@ return ..() ///Robots need robot gibs...! -/mob/living/simple_animal/robot_customer/spawn_gibs() +/mob/living/basic/robot_customer/spawn_gibs() new /obj/effect/gibspawner/robot(drop_location(), src) -/mob/living/simple_animal/robot_customer/MouseEntered(location, control, params) +/mob/living/basic/robot_customer/MouseEntered(location, control, params) . = ..() hud_to_show_on_hover?.show_to(usr) -/mob/living/simple_animal/robot_customer/MouseExited(location, control, params) +/mob/living/basic/robot_customer/MouseExited(location, control, params) . = ..() hud_to_show_on_hover?.hide_from(usr) -/mob/living/simple_animal/robot_customer/update_overlays() +/mob/living/basic/robot_customer/update_overlays() . = ..() var/datum/customer_data/customer_info = ai_controller.blackboard[BB_CUSTOMER_CUSTOMERINFO] @@ -82,21 +93,24 @@ if(bonus_overlays) . += bonus_overlays -/mob/living/simple_animal/robot_customer/send_speech(message, message_range, obj/source, bubble_type, list/spans, datum/language/message_language, list/message_mods, forced, tts_message, list/tts_filter) +/mob/living/basic/robot_customer/send_speech(message, message_range, obj/source, bubble_type, list/spans, datum/language/message_language, list/message_mods, forced, tts_message, list/tts_filter) . = ..() var/datum/customer_data/customer_info = ai_controller.blackboard[BB_CUSTOMER_CUSTOMERINFO] playsound(src, customer_info.speech_sound, 30, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE, falloff_distance = 5) -/mob/living/simple_animal/robot_customer/examine(mob/user) +/mob/living/basic/robot_customer/examine(mob/user) . = ..() - // this should be handled by the ai controller - if(ai_controller.blackboard[BB_CUSTOMER_CURRENT_ORDER]) - var/datum/venue/attending_venue = ai_controller.blackboard[BB_CUSTOMER_ATTENDING_VENUE] - var/wanted_item = ai_controller.blackboard[BB_CUSTOMER_CURRENT_ORDER] - var/order - if(istype(wanted_item, /datum/custom_order)) - var/datum/custom_order/custom_order = wanted_item - order = custom_order.get_order_line(attending_venue) - else - order = attending_venue.order_food_line(wanted_item) - . += span_notice("Their order was: \"[order].\"") + if(isnull(ai_controller.blackboard[BB_CUSTOMER_CURRENT_ORDER])) + return + + var/datum/venue/attending_venue = ai_controller.blackboard[BB_CUSTOMER_ATTENDING_VENUE] + var/wanted_item = ai_controller.blackboard[BB_CUSTOMER_CURRENT_ORDER] + var/order = "nothing" + + if(istype(wanted_item, /datum/custom_order)) + var/datum/custom_order/custom_order = wanted_item + order = custom_order.get_order_line(attending_venue) + else + order = attending_venue.order_food_line(wanted_item) + + . += span_notice("Their order was: \"[order].\"") diff --git a/code/modules/mob/living/basic/space_fauna/snake/snake.dm b/code/modules/mob/living/basic/space_fauna/snake/snake.dm new file mode 100644 index 00000000000..13b9a327cc5 --- /dev/null +++ b/code/modules/mob/living/basic/space_fauna/snake/snake.dm @@ -0,0 +1,86 @@ + +/mob/living/basic/snake + name = "snake" + desc = "A slithery snake. These legless reptiles are the bane of mice and adventurers alike." + icon_state = "snake" + icon_living = "snake" + icon_dead = "snake_dead" + speak_emote = list("hisses") + + health = 20 + maxHealth = 20 + melee_damage_lower = 5 + melee_damage_upper = 6 + obj_damage = 0 + environment_smash = ENVIRONMENT_SMASH_NONE + + attack_verb_continuous = "bites" + attack_verb_simple = "bite" + attack_sound = 'sound/weapons/bite.ogg' + attack_vis_effect = ATTACK_EFFECT_BITE + + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "shoos" + response_disarm_simple = "shoo" + response_harm_continuous = "steps on" + response_harm_simple = "step on" + + density = FALSE + pass_flags = PASSTABLE | PASSMOB + mob_size = MOB_SIZE_SMALL + + faction = list(FACTION_HOSTILE) + mob_biotypes = MOB_ORGANIC | MOB_BEAST | MOB_REPTILE + gold_core_spawnable = FRIENDLY_SPAWN + + ai_controller = /datum/ai_controller/basic_controller/snake + + /// List of stuff (mice) that we want to eat + var/static/list/edibles = list( + /mob/living/basic/mouse, + /obj/item/food/deadmouse, + ) + +/mob/living/basic/snake/Initialize(mapload, special_reagent) + . = ..() + ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) + + AddElement(/datum/element/ai_retaliate) + AddElement(/datum/element/swabable, CELL_LINE_TABLE_SNAKE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) + + AddElement(/datum/element/basic_eating, 2, 0, null, edibles) + ai_controller.set_blackboard_key(BB_BASIC_FOODS, edibles) + + AddComponent(\ + /datum/component/tameable,\ + food_types = list(/obj/item/food/deadmouse),\ + tame_chance = 75,\ + bonus_tame_chance = 10,\ + ) // snakes are really fond of food, especially in the cold darkness of space :) + + if(isnull(special_reagent)) + special_reagent = /datum/reagent/toxin + + AddElement(/datum/element/venomous, special_reagent, 4) + +/mob/living/basic/snake/befriend(mob/living/new_friend) + . = ..() + visible_message("[src] hisses happily as it seems to bond with [new_friend].") + +/// Snakes are primarily concerned with getting those tasty, tasty mice, but aren't afraid to strike back at those who attack them +/datum/ai_controller/basic_controller/snake + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/not_friends/allow_items, + ) + + ai_traits = STOP_MOVING_WHEN_PULLED + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + + planning_subtrees = list( + /datum/ai_planning_subtree/target_retaliate, + /datum/ai_planning_subtree/find_food, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + /datum/ai_planning_subtree/random_speech/snake, + ) diff --git a/code/modules/mob/living/basic/space_fauna/snake/snake_ai.dm b/code/modules/mob/living/basic/space_fauna/snake/snake_ai.dm new file mode 100644 index 00000000000..3eb404761c5 --- /dev/null +++ b/code/modules/mob/living/basic/space_fauna/snake/snake_ai.dm @@ -0,0 +1,6 @@ +/datum/ai_planning_subtree/random_speech/snake + speech_chance = 5 + speak = list("hsssss","sssSSsssss...","hiisssss") + sound = list('sound/creatures/snake_hissing1.ogg', 'sound/creatures/snake_hissing2.ogg') + emote_hear = list("hisses.") + emote_see = list("slithers around.", "glances.", "stares.") diff --git a/code/modules/mob/living/basic/space_fauna/spider/young_spider/young_spider.dm b/code/modules/mob/living/basic/space_fauna/spider/young_spider/young_spider.dm index 57b9da542b7..50ec85e342c 100644 --- a/code/modules/mob/living/basic/space_fauna/spider/young_spider/young_spider.dm +++ b/code/modules/mob/living/basic/space_fauna/spider/young_spider/young_spider.dm @@ -30,6 +30,7 @@ /datum/ai_controller/basic_controller/young_spider blackboard = list( BB_TARGETTING_DATUM = new /datum/targetting_datum/basic(), + BB_BASIC_MOB_FLEE_DISTANCE = 6, ) ai_traits = STOP_MOVING_WHEN_PULLED @@ -46,6 +47,3 @@ /datum/ai_planning_subtree/find_unwebbed_turf, /datum/ai_planning_subtree/spin_web, ) - -/datum/ai_behavior/run_away_from_target/young_spider - run_distance = 6 diff --git a/code/modules/mob/living/basic/vermin/mouse.dm b/code/modules/mob/living/basic/vermin/mouse.dm index 0b3645b3e0f..46e175c5323 100644 --- a/code/modules/mob/living/basic/vermin/mouse.dm +++ b/code/modules/mob/living/basic/vermin/mouse.dm @@ -51,7 +51,7 @@ held_state = "mouse_[body_color]" // not handled by variety element AddElement(/datum/element/animal_variety, "mouse", body_color, FALSE) AddElement(/datum/element/swabable, CELL_LINE_TABLE_MOUSE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 10) - AddComponent(/datum/component/squeak, list('sound/effects/mousesqueek.ogg' = 1), 100, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) //as quiet as a mouse or whatever + AddComponent(/datum/component/squeak, list('sound/creatures/mousesqueek.ogg' = 1), 100, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) //as quiet as a mouse or whatever var/static/list/loc_connections = list( COMSIG_ATOM_ENTERED = PROC_REF(on_entered), ) @@ -381,6 +381,7 @@ BB_CURRENT_HUNTING_TARGET = null, // cheese BB_LOW_PRIORITY_HUNTING_TARGET = null, // cable BB_TARGETTING_DATUM = new /datum/targetting_datum/basic(), // Use this to find people to run away from + BB_BASIC_MOB_FLEE_DISTANCE = 3, ) ai_traits = STOP_MOVING_WHEN_PULLED @@ -400,9 +401,6 @@ ) /// Don't look for anything to run away from if you are distracted by being adjacent to cheese -/datum/ai_planning_subtree/flee_target/mouse - flee_behaviour = /datum/ai_behavior/run_away_from_target/mouse - /datum/ai_planning_subtree/flee_target/mouse /datum/ai_planning_subtree/flee_target/mouse/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) @@ -411,11 +409,6 @@ return // We see some cheese, which is more important than our life return ..() -/datum/ai_planning_subtree/flee_target/mouse/select - -/datum/ai_behavior/run_away_from_target/mouse - run_distance = 3 // Mostly exists in small tunnels, don't get ahead of yourself - /// AI controller for rats, slightly more complex than mice becuase they attack people /datum/ai_controller/basic_controller/mouse/rat blackboard = list( diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm index e182c51f54f..b63ca68d7d7 100644 --- a/code/modules/mob/living/brain/MMI.dm +++ b/code/modules/mob/living/brain/MMI.dm @@ -268,7 +268,7 @@ if(user) to_chat(user, span_warning("\The [src] indicates that there is no mind present!")) return FALSE - if(brain.decoy_override) + if(brain?.decoy_override) if(user) to_chat(user, span_warning("This [name] does not seem to fit!")) return FALSE diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 4bd275b5df1..10cff8c19ac 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -39,6 +39,21 @@ /// Maximum skillchip slots available. Do not reference this var directly and instead call get_max_skillchip_slots() var/max_skillchip_slots = 5 + /// Size modifier for the sprite + var/brain_size = 1 + +/obj/item/organ/internal/brain/Initialize(mapload) + . = ..() + // Brain size logic + transform = transform.Scale(brain_size) + +/obj/item/organ/internal/brain/examine() + . = ..() + if(brain_size < 1) + . += span_notice("It is a bit on the smaller side...") + if(brain_size > 1) + . += span_notice("It is bigger than average...") + /obj/item/organ/internal/brain/Insert(mob/living/carbon/brain_owner, special = FALSE, drop_if_replaced = TRUE, no_id_transfer = FALSE) . = ..() if(!.) @@ -406,6 +421,9 @@ . = ..() organ_owner.gain_trauma(/datum/brain_trauma/special/bluespace_prophet, TRAUMA_RESILIENCE_ABSOLUTE) +/obj/item/organ/internal/brain/felinid //A bit smaller than average + brain_size = 0.8 + ////////////////////////////////////TRAUMAS//////////////////////////////////////// /obj/item/organ/internal/brain/proc/has_trauma_type(brain_trauma_type = /datum/brain_trauma, resilience = TRAUMA_RESILIENCE_ABSOLUTE) @@ -553,4 +571,4 @@ var/obj/item/organ/internal/brain/old_brain = new_owner.get_organ_slot(ORGAN_SLOT_BRAIN) old_brain.Remove(new_owner, special = TRUE, no_id_transfer = TRUE) qdel(old_brain) - Insert(new_owner, special = TRUE, drop_if_replaced = FALSE, no_id_transfer = TRUE) + return Insert(new_owner, special = TRUE, drop_if_replaced = FALSE, no_id_transfer = TRUE) diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 8b97685d0a8..789a459b492 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -57,6 +57,13 @@ return null +/mob/living/carbon/is_ears_covered() + for(var/obj/item/worn_thing as anything in get_equipped_items()) + if(worn_thing.flags_cover & EARS_COVERED) + return worn_thing + + return null + /mob/living/carbon/check_projectile_dismemberment(obj/projectile/P, def_zone) var/obj/item/bodypart/affecting = get_bodypart(def_zone) if(affecting && !(affecting.bodypart_flags & BODYPART_UNREMOVABLE) && affecting.get_damage() >= (affecting.max_damage - P.dismemberment)) diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index 17718190ba5..6a8fc967cb5 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -449,6 +449,13 @@ GLOBAL_LIST_EMPTY(features_by_species) wearer.hud_used?.update_locked_slots() worn_items_fit_body_check(wearer) +/** + * Normalizes blood in a human if it is excessive. If it is above BLOOD_VOLUME_NORMAL, this will clamp it to that value. It will not give the human more blodo than they have less than this value. + */ +/datum/species/proc/normalize_blood(mob/living/carbon/human/blood_possessing_human) + var/normalized_blood_values = max(blood_possessing_human.blood_volume, 0, BLOOD_VOLUME_NORMAL) + blood_possessing_human.blood_volume = normalized_blood_values + /** * Proc called when a carbon becomes this species. * @@ -459,34 +466,37 @@ GLOBAL_LIST_EMPTY(features_by_species) * * old_species - The species that the carbon used to be before becoming this race, used for regenerating organs. * * pref_load - Preferences to be loaded from character setup, loads in preferred mutant things like bodyparts, digilegs, skin color, etc. */ -/datum/species/proc/on_species_gain(mob/living/carbon/human/C, datum/species/old_species, pref_load) +/datum/species/proc/on_species_gain(mob/living/carbon/human/human_who_gained_species, datum/species/old_species, pref_load) SHOULD_CALL_PARENT(TRUE) // Drop the items the new species can't wear - if(C.hud_used) - C.hud_used.update_locked_slots() + if(human_who_gained_species.hud_used) + human_who_gained_species.hud_used.update_locked_slots() - C.mob_biotypes = inherent_biotypes - C.mob_respiration_type = inherent_respiration_type - C.butcher_results = knife_butcher_results?.Copy() + human_who_gained_species.mob_biotypes = inherent_biotypes + human_who_gained_species.mob_respiration_type = inherent_respiration_type + human_who_gained_species.butcher_results = knife_butcher_results?.Copy() if(old_species.type != type) - replace_body(C, src) + replace_body(human_who_gained_species, src) - regenerate_organs(C, old_species, visual_only = C.visual_only_organs) + regenerate_organs(human_who_gained_species, old_species, visual_only = human_who_gained_species.visual_only_organs) // Drop the items the new species can't wear - INVOKE_ASYNC(src, PROC_REF(worn_items_fit_body_check), C, TRUE) + INVOKE_ASYNC(src, PROC_REF(worn_items_fit_body_check), human_who_gained_species, TRUE) //Assigns exotic blood type if the species has one - if(exotic_bloodtype && C.dna.blood_type != exotic_bloodtype) - C.dna.blood_type = exotic_bloodtype + if(exotic_bloodtype && human_who_gained_species.dna.blood_type != exotic_bloodtype) + human_who_gained_species.dna.blood_type = exotic_bloodtype //Otherwise, check if the previous species had an exotic bloodtype and we do not have one and assign a random blood type //(why the fuck is blood type not tied to a fucking DNA block?) else if(old_species.exotic_bloodtype && !exotic_bloodtype) - C.dna.blood_type = random_blood_type() + human_who_gained_species.dna.blood_type = random_blood_type() - if(ishuman(C)) - var/mob/living/carbon/human/human = C + //Resets blood if it is excessively high for some reason + normalize_blood(human_who_gained_species) + + if(ishuman(human_who_gained_species)) + var/mob/living/carbon/human/human = human_who_gained_species for(var/obj/item/organ/external/organ_path as anything in external_organs) if(!should_external_organ_apply_to(organ_path, human)) continue @@ -495,25 +505,27 @@ GLOBAL_LIST_EMPTY(features_by_species) var/obj/item/organ/external/new_organ = SSwardrobe.provide_type(organ_path) new_organ.Insert(human, special=TRUE, drop_if_replaced=FALSE) + + if(length(inherent_traits)) - C.add_traits(inherent_traits, SPECIES_TRAIT) + human_who_gained_species.add_traits(inherent_traits, SPECIES_TRAIT) if(inherent_factions) for(var/i in inherent_factions) - C.faction += i //Using +=/-= for this in case you also gain the faction from a different source. + human_who_gained_species.faction += i //Using +=/-= for this in case you also gain the faction from a different source. // All languages associated with this language holder are added with source [LANGUAGE_SPECIES] // rather than source [LANGUAGE_ATOM], so we can track what to remove if our species changes again var/datum/language_holder/gaining_holder = GLOB.prototype_language_holders[species_language_holder] for(var/language in gaining_holder.understood_languages) - C.grant_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_SPECIES) + human_who_gained_species.grant_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_SPECIES) for(var/language in gaining_holder.spoken_languages) - C.grant_language(language, SPOKEN_LANGUAGE, LANGUAGE_SPECIES) + human_who_gained_species.grant_language(language, SPOKEN_LANGUAGE, LANGUAGE_SPECIES) for(var/language in gaining_holder.blocked_languages) - C.add_blocked_language(language, LANGUAGE_SPECIES) - C.regenerate_icons() + human_who_gained_species.add_blocked_language(language, LANGUAGE_SPECIES) + human_who_gained_species.regenerate_icons() - SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species) + SEND_SIGNAL(human_who_gained_species, COMSIG_SPECIES_GAIN, src, old_species) properly_gained = TRUE @@ -1484,7 +1496,7 @@ GLOBAL_LIST_EMPTY(features_by_species) */ /datum/species/proc/handle_body_temperature(mob/living/carbon/human/humi, seconds_per_tick, times_fired) //when in a cryo unit we suspend all natural body regulation - if(istype(humi.loc, /obj/machinery/atmospherics/components/unary/cryo_cell)) + if(istype(humi.loc, /obj/machinery/cryo_cell)) return //Only stabilise core temp when alive and not in statis diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 40e4bf095d5..680e5c14f7e 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -372,7 +372,7 @@ var/obj/item/bodypart/the_part = isbodypart(target_zone) ? target_zone : get_bodypart(check_zone(target_zone)) //keep these synced // Loop through the clothing covering this bodypart and see if there's any thiccmaterials if(!(injection_flags & INJECT_CHECK_PENETRATE_THICK)) - for(var/obj/item/clothing/iter_clothing in clothingonpart(the_part)) + for(var/obj/item/clothing/iter_clothing in get_clothing_on_part(the_part)) if(iter_clothing.clothing_flags & THICKMATERIAL) . = FALSE break @@ -786,6 +786,7 @@ VV_DROPDOWN_OPTION(VV_HK_MOD_QUIRKS, "Add/Remove Quirks") VV_DROPDOWN_OPTION(VV_HK_SET_SPECIES, "Set Species") VV_DROPDOWN_OPTION(VV_HK_PURRBATION, "Toggle Purrbation") + VV_DROPDOWN_OPTION(VV_HK_APPLY_DNA_INFUSION, "Apply DNA Infusion") /mob/living/carbon/human/vv_do_topic(list/href_list) . = ..() @@ -871,6 +872,19 @@ var/msg = span_notice("[key_name_admin(usr)] has removed [key_name(src)] from purrbation.") message_admins(msg) admin_ticket_log(src, msg) + if(href_list[VV_HK_APPLY_DNA_INFUSION]) + if(!check_rights(R_SPAWN)) + return + if(!ishuman(src)) + to_chat(usr, "This can only be done to human species.") + return + var/result = usr.client.grant_dna_infusion(src) + if(result) + to_chat(usr, "Successfully applied DNA Infusion [result] to [src].") + log_admin("[key_name(usr)] has applied DNA Infusion [result] to [key_name(src)].") + else + to_chat(usr, "Failed to apply DNA Infusion to [src].") + log_admin("[key_name(usr)] failed to apply a DNA Infusion to [key_name(src)].") /mob/living/carbon/human/limb_attack_self() var/obj/item/bodypart/arm = hand_bodyparts[active_hand_index] diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index bc951d49bb7..b02aaf03b17 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -6,21 +6,21 @@ if(isbodypart(def_zone)) var/obj/item/bodypart/bp = def_zone if(bp) - return checkarmor(def_zone, type) + return check_armor(def_zone, type) var/obj/item/bodypart/affecting = get_bodypart(check_zone(def_zone)) if(affecting) - return checkarmor(affecting, type) + return check_armor(affecting, type) //If a specific bodypart is targetted, check how that bodypart is protected and return the value. //If you don't specify a bodypart, it checks ALL your bodyparts for protection, and averages out the values for(var/X in bodyparts) var/obj/item/bodypart/BP = X - armorval += checkarmor(BP, type) + armorval += check_armor(BP, type) organnum++ return (armorval/max(organnum, 1)) -/mob/living/carbon/human/proc/checkarmor(obj/item/bodypart/def_zone, damage_type) +/mob/living/carbon/human/proc/check_armor(obj/item/bodypart/def_zone, damage_type) if(!damage_type) return 0 var/protection = 100 @@ -32,7 +32,7 @@ return 100 - protection ///Get all the clothing on a specific body part -/mob/living/carbon/human/proc/clothingonpart(obj/item/bodypart/def_zone) +/mob/living/carbon/human/proc/get_clothing_on_part(obj/item/bodypart/def_zone) var/list/covering_part = list() var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, ears, wear_id, wear_neck) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor) for(var/bp in body_parts) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index c91fc7d6638..2e061d32a6b 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -100,7 +100,7 @@ /// Environment handlers for species /mob/living/carbon/human/handle_environment(datum/gas_mixture/environment, seconds_per_tick, times_fired) // If we are in a cryo bed do not process life functions - if(istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell)) + if(istype(loc, /obj/machinery/cryo_cell)) return dna.species.handle_environment(src, environment, seconds_per_tick, times_fired) diff --git a/code/modules/mob/living/carbon/human/species_types/abominations.dm b/code/modules/mob/living/carbon/human/species_types/abominations.dm index b7be74565ac..43ca71311c2 100644 --- a/code/modules/mob/living/carbon/human/species_types/abominations.dm +++ b/code/modules/mob/living/carbon/human/species_types/abominations.dm @@ -3,6 +3,7 @@ name = "\improper Tall Boy" id = SPECIES_TALLBOY examine_limb_id = SPECIES_HUMAN + changesource_flags = MIRROR_BADMIN | WABBAJACK bodypart_overrides = list( BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left, BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right, @@ -13,8 +14,10 @@ ) /datum/species/monkey/human_legged + name = "human-legged monkey" id = SPECIES_MONKEY_HUMAN_LEGGED examine_limb_id = SPECIES_MONKEY + changesource_flags = MIRROR_BADMIN | WABBAJACK bodypart_overrides = list( BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/monkey, BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right/monkey, @@ -25,8 +28,10 @@ ) /datum/species/monkey/monkey_freak + name = "human-armed monkey" id = SPECIES_MONKEY_FREAK examine_limb_id = SPECIES_MONKEY + changesource_flags = MIRROR_BADMIN | WABBAJACK bodypart_overrides = list( BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left, BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right, diff --git a/code/modules/mob/living/carbon/human/species_types/felinid.dm b/code/modules/mob/living/carbon/human/species_types/felinid.dm index 793da47c05b..c8e14a6afd1 100644 --- a/code/modules/mob/living/carbon/human/species_types/felinid.dm +++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm @@ -4,6 +4,7 @@ id = SPECIES_FELINE examine_limb_id = SPECIES_HUMAN mutant_bodyparts = list("ears" = "Cat", "wings" = "None") + mutantbrain = /obj/item/organ/internal/brain/felinid mutanttongue = /obj/item/organ/internal/tongue/cat /* SKYRAT EDIT REMOVAL - CUSTOMIZATION mutantears = /obj/item/organ/internal/ears/cat @@ -23,8 +24,6 @@ family_heirlooms = list(/obj/item/toy/cattoy) /// When false, this is a felinid created by mass-purrbation var/original_felinid = TRUE - /// Brain size for scaling - var/brain_size = 0.8 // Prevents felinids from taking toxin damage from carpotoxin /datum/species/human/felinid/handle_chemical(datum/reagent/chem, mob/living/carbon/human/affected, seconds_per_tick, times_fired) @@ -47,16 +46,6 @@ ears.Insert(target_human, drop_if_replaced = FALSE) else mutantears = /obj/item/organ/internal/ears - var/obj/item/organ/internal/brain/current_brain = target_human.get_organ_by_type(/obj/item/organ/internal/brain) - if(current_brain) - current_brain.transform = current_brain.transform.Scale(brain_size) //smaller brain - return ..() - -/datum/species/human/felinid/on_species_loss(mob/living/carbon/former_feline, datum/species/old_species, pref_load) - if(iscarbon(former_feline)) - var/obj/item/organ/internal/brain/current_brain = former_feline.get_organ_by_type(/obj/item/organ/internal/brain) - if(current_brain) - current_brain.transform = current_brain.transform.Scale(1 / brain_size) //bigger brain return ..() /datum/species/human/felinid/randomize_features(mob/living/carbon/human/human_mob) diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm index 2c997274ffb..9db5a3253eb 100644 --- a/code/modules/mob/living/carbon/human/species_types/humans.dm +++ b/code/modules/mob/living/carbon/human/species_types/humans.dm @@ -18,7 +18,7 @@ human_mob.skin_tone = random_skin_tone() /datum/species/human/get_scream_sound(mob/living/carbon/human/human) - if(human.gender == MALE) + if(human.physique == MALE) if(prob(1)) return 'sound/voice/human/wilhelm_scream.ogg' return pick( diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index e66d72a2c44..990f27f0707 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -579,6 +579,9 @@ if(stat != DEAD) // If you are dead your body does not stabilize naturally natural_bodytemperature_stabilization(environment, seconds_per_tick, times_fired) + else if(!on_fire && areatemp < bodytemperature) // lowers your dead body temperature to room temperature over time + adjust_bodytemperature((areatemp - bodytemperature), use_insulation=FALSE, use_steps=TRUE) + if(!on_fire || areatemp > bodytemperature) // If we are not on fire or the area is hotter adjust_bodytemperature((areatemp - bodytemperature), use_insulation=TRUE, use_steps=TRUE) diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index cb4d4a8241a..532d37ed1b2 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -193,7 +193,7 @@ return var/mob/living/carbon/human/human_user = user if(human_user.dna.species.id == SPECIES_HUMAN && !HAS_MIND_TRAIT(human_user, TRAIT_MIMING)) - if(human_user.gender == FEMALE) + if(human_user.physique == FEMALE) return pick('sound/voice/human/gasp_female1.ogg', 'sound/voice/human/gasp_female2.ogg', 'sound/voice/human/gasp_female3.ogg') else return pick('sound/voice/human/gasp_male1.ogg', 'sound/voice/human/gasp_male2.ogg') diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 17c6d7faa9c..0d309ff10c9 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -88,6 +88,11 @@ /mob/living/proc/is_pepper_proof(check_flags = ALL) return null +/// Checks if the mob's ears (BOTH EARS, BOWMANS NEED NOT APPLY) are covered by something. +/// Returns the atom covering the mob's ears, or null if their ears are uncovered. +/mob/living/proc/is_ears_covered() + return null + /mob/living/proc/on_hit(obj/projectile/P) return BULLET_ACT_HIT diff --git a/code/modules/mob/living/living_say.dm b/code/modules/mob/living/living_say.dm index b3f842e6a25..3a09256ee69 100644 --- a/code/modules/mob/living/living_say.dm +++ b/code/modules/mob/living/living_say.dm @@ -394,13 +394,29 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list( tts_message_to_use = message_raw var/list/filter = list() + var/list/special_filter = list() + var/voice_to_use = voice + var/use_radio = FALSE if(length(voice_filter) > 0) filter += voice_filter if(length(tts_filter) > 0) filter += tts_filter.Join(",") - - INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), src, html_decode(tts_message_to_use), message_language, voice, filter.Join(","), listened, message_range = message_range, pitch = pitch, silicon = tts_silicon_voice_effect) + if(ishuman(src)) + var/mob/living/carbon/human/human_speaker = src + if(human_speaker.wear_mask) + var/obj/item/clothing/mask/worn_mask = human_speaker.wear_mask + if(worn_mask.voice_override) + voice_to_use = worn_mask.voice_override + if(worn_mask.voice_filter) + filter += worn_mask.voice_filter + use_radio = worn_mask.use_radio_beeps_tts + if(use_radio) + special_filter += TTS_FILTER_RADIO + if(issilicon(src)) + special_filter += TTS_FILTER_SILICON + + INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), src, html_decode(tts_message_to_use), message_language, voice_to_use, filter.Join(","), listened, message_range = message_range, pitch = pitch, special_filters = special_filter.Join("|")) var/image/say_popup = image('icons/mob/effects/talk.dmi', src, "[bubble_type][talk_icon_state]", FLY_LAYER) SET_PLANE_EXPLICIT(say_popup, ABOVE_GAME_PLANE, src) diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index 277b36c274b..f820d3ca1cf 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -439,11 +439,8 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real if(prob(75) && Proj.damage > 0) spark_system.start() -/mob/living/silicon/on_hit(obj/projectile/P) - if(!has_movespeed_modifier(/datum/movespeed_modifier/borg_throw)) - add_movespeed_modifier(/datum/movespeed_modifier/borg_throw) - addtimer(CALLBACK(src, TYPE_PROC_REF(/mob/living/silicon, clear_throw_slowdown)), (P.throwforce / 10) SECONDS) - return ..() - -/mob/living/silicon/proc/clear_throw_slowdown() - src.remove_movespeed_modifier(/datum/movespeed_modifier/borg_throw) +/mob/living/silicon/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) + . = ..() + if (. || AM.throwforce < CYBORG_THROW_SLOWDOWN_THRESHOLD) + return + apply_status_effect(/datum/status_effect/borg_throw_slow) diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index bf785954fe7..7bd48ab62fb 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -104,8 +104,6 @@ var/reset_access_timer_id var/ignorelistcleanuptimer = 1 // This ticks up every automated action, at 300 we clean the ignore list - /// Component which allows ghosts to take over this bot - var/datum/component/ghost_direct_control/personality_download /// If true we will allow ghosts to control this mob var/can_be_possessed = FALSE /// If true we will offer this @@ -212,7 +210,6 @@ GLOB.bots_list -= src QDEL_NULL(paicard) QDEL_NULL(pa_system) - QDEL_NULL(personality_download) QDEL_NULL(internal_radio) QDEL_NULL(access_card) QDEL_NULL(path_hud) @@ -225,14 +222,14 @@ return can_be_possessed = TRUE var/can_announce = !mapload && COOLDOWN_FINISHED(src, offer_ghosts_cooldown) - personality_download = AddComponent(\ - /datum/component/ghost_direct_control,\ - ban_type = ROLE_BOT,\ - poll_candidates = can_announce,\ - poll_ignore_key = POLL_IGNORE_BOTS,\ - assumed_control_message = (bot_cover_flags & BOT_COVER_EMAGGED) ? get_emagged_message() : possessed_message,\ - extra_control_checks = CALLBACK(src, PROC_REF(check_possession)),\ - after_assumed_control = CALLBACK(src, PROC_REF(post_possession)),\ + AddComponent( + /datum/component/ghost_direct_control, \ + ban_type = ROLE_BOT, \ + poll_candidates = can_announce, \ + poll_ignore_key = POLL_IGNORE_BOTS, \ + assumed_control_message = (bot_cover_flags & BOT_COVER_EMAGGED) ? get_emagged_message() : possessed_message, \ + extra_control_checks = CALLBACK(src, PROC_REF(check_possession)), \ + after_assumed_control = CALLBACK(src, PROC_REF(post_possession)), \ ) if (can_announce) COOLDOWN_START(src, offer_ghosts_cooldown, 30 SECONDS) @@ -240,7 +237,7 @@ /// Disables this bot from being possessed by ghosts /mob/living/simple_animal/bot/proc/disable_possession(mob/user) can_be_possessed = FALSE - QDEL_NULL(personality_download) + qdel(GetComponent(/datum/component/ghost_direct_control)) if (isnull(key)) return if (user) diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm index b392417aab2..2d17820af0b 100644 --- a/code/modules/mob/living/simple_animal/hostile/alien.dm +++ b/code/modules/mob/living/simple_animal/hostile/alien.dm @@ -32,7 +32,7 @@ lighting_cutoff_red = 30 lighting_cutoff_green = 15 lighting_cutoff_blue = 50 - unique_name = 1 + unique_name = TRUE gold_core_spawnable = NO_SPAWN death_sound = 'sound/voice/hiss6.ogg' death_message = "lets out a waning guttural screech, green blood bubbling from its maw..." @@ -91,7 +91,7 @@ projectiletype = /obj/projectile/neurotoxin/damaging projectilesound = 'sound/weapons/pierce.ogg' status_flags = 0 - unique_name = 0 + unique_name = FALSE var/sterile = 1 var/plants_off = 0 var/egg_cooldown = 30 diff --git a/code/modules/mob/living/simple_animal/hostile/constructs/constructs.dm b/code/modules/mob/living/simple_animal/hostile/constructs/constructs.dm index 124b797d0da..23f7590dc8e 100644 --- a/code/modules/mob/living/simple_animal/hostile/constructs/constructs.dm +++ b/code/modules/mob/living/simple_animal/hostile/constructs/constructs.dm @@ -28,7 +28,7 @@ maxbodytemp = INFINITY faction = list(FACTION_CULT) pressure_resistance = 100 - unique_name = 1 + unique_name = TRUE AIStatus = AI_OFF //normal constructs don't have AI loot = list(/obj/item/ectoplasm) del_on_death = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm index 745a48c948c..828a78ccfb1 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -436,7 +436,7 @@ Difficulty: Hard /mob/living/simple_animal/hostile/megafauna/hierophant/CanAttack(atom/the_target) . = ..() - if(istype(the_target, /mob/living/simple_animal/hostile/asteroid/hivelordbrood)) //ignore temporary targets in favor of more permanent targets + if(istype(the_target, /mob/living/basic/legion_brood)) //ignore temporary targets in favor of more permanent targets return FALSE /mob/living/simple_animal/hostile/megafauna/hierophant/GiveTarget(new_target) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm index 05695daf59a..777cb3b878f 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm @@ -141,10 +141,9 @@ ///Attack proc. Spawns a singular legion skull. /mob/living/simple_animal/hostile/megafauna/legion/proc/create_legion_skull() - var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/A = new(loc) - A.GiveTarget(target) - A.friends = friends - A.faction = faction + var/mob/living/basic/legion_brood/minion = new(loc) + minion.assign_creator(src) + minion.ai_controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] = target //CHARGE @@ -210,7 +209,7 @@ var/mob/living/living_target = target switch(living_target.stat) if(UNCONSCIOUS, HARD_CRIT) - var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/legion = new(loc) + var/mob/living/basic/legion_brood/legion = new(loc) legion.infest(living_target) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm index 4cb4d97f38f..bf4d33a10ed 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm @@ -249,7 +249,8 @@ /obj/projectile/herald/teleshot/on_hit(atom/target, blocked = FALSE) . = ..() - firer.forceMove(get_turf(src)) + if(!QDELETED(firer)) + firer.forceMove(get_turf(src)) //Herald's loot: Cloak of the Prophet diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm index a705e11465b..ec6c843080c 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm @@ -328,10 +328,9 @@ /obj/item/crusher_trophy/legionnaire_spine/on_mark_detonation(mob/living/target, mob/living/user) if(!prob(bonus_value) || target.stat == DEAD) return - var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/A = new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion(user.loc) - A.GiveTarget(target) - A.friends += user - A.faction = user.faction.Copy() + var/mob/living/basic/legion_brood/minion = new (user.loc) + minion.assign_creator(user) + minion.ai_controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] = target /obj/item/crusher_trophy/legionnaire_spine/attack_self(mob/user) if(!isliving(user)) @@ -342,9 +341,9 @@ to_chat(LivingUser, "You need to wait longer to use this again.") return LivingUser.visible_message(span_boldwarning("[LivingUser] shakes the [src] and summons a legion skull!")) - var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/LegionSkull = new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion(LivingUser.loc) - LegionSkull.friends += LivingUser - LegionSkull.faction = LivingUser.faction.Copy() + + var/mob/living/basic/legion_brood/minion = new (LivingUser.loc) + minion.assign_creator(LivingUser) next_use_time = world.time + 4 SECONDS #undef LEGIONNAIRE_CHARGE diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm deleted file mode 100644 index 2d92ef88a65..00000000000 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm +++ /dev/null @@ -1,333 +0,0 @@ -/mob/living/simple_animal/hostile/asteroid/hivelord - name = "hivelord" - desc = "A levitating swarm of tiny creatures which act as a single individual. When threatened or hunting they rapidly replicate additional short-lived bodies." - icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' - icon_state = "hivelord" - icon_living = "hivelord" - icon_aggro = "hivelord_alert" - icon_dead = "hivelord_dead" - icon_gib = "syndicate_gib" - mob_biotypes = MOB_ORGANIC - move_to_delay = 14 - ranged = 1 - vision_range = 5 - aggro_vision_range = 9 - speed = 3 - maxHealth = 75 - health = 75 - harm_intent_damage = 5 - melee_damage_lower = 0 - melee_damage_upper = 0 - attack_verb_continuous = "weakly tackles" - attack_verb_simple = "weakly tackles" - speak_emote = list("telepathically cries") - attack_sound = 'sound/weapons/pierce.ogg' - throw_message = "passes between the bodies of the" - ranged_cooldown = 0 - ranged_cooldown_time = 20 - obj_damage = 0 - environment_smash = ENVIRONMENT_SMASH_NONE - retreat_distance = 3 - minimum_distance = 3 - pass_flags = PASSTABLE - loot = list(/obj/item/organ/internal/monster_core/regenerative_core) - var/brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood - var/has_clickbox = TRUE - -/mob/living/simple_animal/hostile/asteroid/hivelord/Initialize(mapload) - . = ..() - if(has_clickbox) - AddComponent(/datum/component/clickbox, icon_state = "hivelord", max_scale = INFINITY, dead_state = "hivelord_dead") //they writhe so much. - -/mob/living/simple_animal/hostile/asteroid/hivelord/OpenFire(the_target) - if(world.time < ranged_cooldown) - return - var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/brood = new brood_type(src.loc) - brood.flags_1 |= (flags_1 & ADMIN_SPAWNED_1) - brood.GiveTarget(target) - brood.friends = friends - brood.faction = faction.Copy() - ranged_cooldown = world.time + ranged_cooldown_time - -/mob/living/simple_animal/hostile/asteroid/hivelord/AttackingTarget() - OpenFire() - return TRUE - -/mob/living/simple_animal/hostile/asteroid/hivelord/death(gibbed) - mouse_opacity = MOUSE_OPACITY_ICON - return ..() - -//A fragile but rapidly produced creature -/mob/living/simple_animal/hostile/asteroid/hivelordbrood - name = "hivelord brood" - desc = "Short-lived attack form of the hivelord. One isn't much of a threat, but..." - icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' - icon_state = "hivelord_brood" - icon_living = "hivelord_brood" - icon_aggro = "hivelord_brood" - icon_dead = "hivelord_brood" - icon_gib = "syndicate_gib" - move_to_delay = 1 - friendly_verb_continuous = "buzzes near" - friendly_verb_simple = "buzz near" - vision_range = 10 - speed = 3 - maxHealth = 1 - health = 1 - harm_intent_damage = 5 - melee_damage_lower = 2 - melee_damage_upper = 2 - attack_verb_continuous = "slashes" - attack_verb_simple = "slash" - speak_emote = list("telepathically cries") - attack_sound = 'sound/weapons/pierce.ogg' - attack_vis_effect = ATTACK_EFFECT_SLASH - throw_message = "falls right through the strange body of the" - obj_damage = 0 - environment_smash = ENVIRONMENT_SMASH_NONE - pass_flags = PASSTABLE | PASSMOB - density = FALSE - del_on_death = 1 - var/clickbox_state = "hivelord" - var/clickbox_max_scale = INFINITY - -/mob/living/simple_animal/hostile/asteroid/hivelordbrood/Initialize(mapload) - . = ..() - addtimer(CALLBACK(src, PROC_REF(death)), 10 SECONDS) - AddElement(/datum/element/simple_flying) - AddComponent(/datum/component/swarming) - AddComponent(/datum/component/clickbox, icon_state = clickbox_state, max_scale = clickbox_max_scale) - -/mob/living/simple_animal/hostile/asteroid/hivelordbrood/death(gibbed) - if (!gibbed) - new /obj/effect/temp_visual/hive_spawn_wither(get_turf(src), /* copy_from = */ src) - return ..() - -//Legion -/mob/living/simple_animal/hostile/asteroid/hivelord/legion - name = "legion" - desc = "You can still see what was once a human under the shifting mass of corruption." - icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' - icon_state = "legion" - icon_living = "legion" - icon_aggro = "legion" - icon_dead = "legion" - icon_gib = "syndicate_gib" - mob_biotypes = MOB_ORGANIC|MOB_HUMANOID - mouse_opacity = MOUSE_OPACITY_ICON - obj_damage = 60 - melee_damage_lower = 15 - melee_damage_upper = 15 - attack_verb_continuous = "lashes out at" - attack_verb_simple = "lash out at" - speak_emote = list("echoes") - attack_sound = 'sound/weapons/pierce.ogg' - throw_message = "bounces harmlessly off of" - crusher_loot = /obj/item/crusher_trophy/legion_skull - loot = list(/obj/item/organ/internal/monster_core/regenerative_core/legion) - brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion - del_on_death = 1 - stat_attack = HARD_CRIT - robust_searching = 1 - has_clickbox = FALSE - var/dwarf_mob = FALSE - var/snow_legion = FALSE - var/mob/living/carbon/human/stored_mob - -/mob/living/simple_animal/hostile/asteroid/hivelord/legion/Initialize(mapload) - . = ..() - AddElement(/datum/element/content_barfer) - -/mob/living/simple_animal/hostile/asteroid/hivelord/legion/dwarf - name = "dwarf legion" - desc = "You can still see what was once a rather small human under the shifting mass of corruption." - icon_state = "dwarf_legion" - icon_living = "dwarf_legion" - icon_aggro = "dwarf_legion" - icon_dead = "dwarf_legion" - maxHealth = 60 - health = 60 - speed = 2 //faster! - crusher_drop_mod = 20 - dwarf_mob = TRUE - -/mob/living/simple_animal/hostile/asteroid/hivelord/legion/death(gibbed) - visible_message(span_warning("The skulls on [src] wail in anger as they flee from their dying host!")) - if (!isnull(stored_mob)) - stored_mob = null - return ..() - - // We didn't contain a real body so spawn a random one - var/turf/our_turf = get_turf(src) - if(our_turf) - if(from_spawner) - new /obj/effect/mob_spawn/corpse/human/charredskeleton(our_turf) - else if(dwarf_mob) - new /obj/effect/mob_spawn/corpse/human/legioninfested/dwarf(our_turf) - else if(snow_legion) - new /obj/effect/mob_spawn/corpse/human/snowlegioninfested(our_turf) - else - new /obj/effect/mob_spawn/corpse/human/legioninfested(our_turf) - return ..() - -/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril - from_spawner = TRUE - -//Legion skull -/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion - name = "legion" - desc = "One of many." - icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' - icon_state = "legion_head" - icon_living = "legion_head" - icon_aggro = "legion_head" - icon_dead = "legion_head" - icon_gib = "syndicate_gib" - friendly_verb_continuous = "buzzes near" - friendly_verb_simple = "buzz near" - vision_range = 10 - maxHealth = 1 - health = 5 - harm_intent_damage = 5 - melee_damage_lower = 12 - melee_damage_upper = 12 - attack_verb_continuous = "bites" - attack_verb_simple = "bite" - attack_vis_effect = ATTACK_EFFECT_BITE - speak_emote = list("echoes") - attack_sound = 'sound/weapons/pierce.ogg' - throw_message = "is shrugged off by" - del_on_death = TRUE - stat_attack = HARD_CRIT - robust_searching = 1 - clickbox_state = "sphere" - clickbox_max_scale = 2 - var/can_infest_dead = FALSE - -/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/Life(seconds_per_tick = SSMOBS_DT, times_fired) - . = ..() - if(stat == DEAD || !isturf(loc)) - return - for(var/mob/living/carbon/human/victim in range(src, 1)) //Only for corpse right next to/on same tile - switch(victim.stat) - if(UNCONSCIOUS, HARD_CRIT) - infest(victim) - return //This will qdelete the legion. - if(DEAD) - if(can_infest_dead) - infest(victim) - return //This will qdelete the legion. - -///Create a legion at the location of a corpse. Exists so that legion subtypes can override it with their own type of legion. -/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/proc/make_legion(mob/living/carbon/human/H) - if(HAS_TRAIT(H, TRAIT_DWARF)) //dwarf legions aren't just fluff! - return new /mob/living/simple_animal/hostile/asteroid/hivelord/legion/dwarf(H.loc) - else - return new /mob/living/simple_animal/hostile/asteroid/hivelord/legion(H.loc) - -///Create a new legion using the supplied human H -/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/proc/infest(mob/living/carbon/human/H) - visible_message(span_warning("[name] burrows into the flesh of [H]!")) - var/mob/living/simple_animal/hostile/asteroid/hivelord/legion/L = make_legion(H) - visible_message(span_warning("[L] staggers to [L.p_their()] feet!")) - H.investigate_log("has been killed by hivelord infestation.", INVESTIGATE_DEATHS) - H.death() - H.adjustBruteLoss(1000) - L.stored_mob = H - H.forceMove(L) - qdel(src) - -//Advanced Legion is slightly tougher to kill and can raise corpses (revive other legions) -/mob/living/simple_animal/hostile/asteroid/hivelord/legion/advanced - stat_attack = DEAD - maxHealth = 120 - health = 120 - brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/advanced - icon_state = "dwarf_legion" - icon_living = "dwarf_legion" - icon_aggro = "dwarf_legion" - icon_dead = "dwarf_legion" - -/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/advanced - stat_attack = DEAD - can_infest_dead = TRUE - -//Legion that spawns Legions -/mob/living/simple_animal/hostile/big_legion - name = "legion" - desc = "One of many." - icon = 'icons/mob/simple/lavaland/64x64megafauna.dmi' - icon_state = "legion" - icon_living = "legion" - icon_dead = "legion" - health_doll_icon = "legion" - health = 450 - maxHealth = 450 - melee_damage_lower = 20 - melee_damage_upper = 20 - anchored = FALSE - AIStatus = AI_ON - stop_automated_movement = FALSE - wander = TRUE - maxbodytemp = INFINITY - layer = MOB_LAYER - del_on_death = TRUE - sentience_type = SENTIENCE_BOSS - loot = list(/obj/item/organ/internal/monster_core/regenerative_core/legion = 3, /obj/effect/mob_spawn/corpse/human/legioninfested = 5) - move_to_delay = 14 - vision_range = 5 - aggro_vision_range = 9 - speed = 3 - faction = list(FACTION_MINING) - weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE) - obj_damage = 30 - environment_smash = ENVIRONMENT_SMASH_STRUCTURES - // Purple, but bright cause we're gonna need to spot mobs on lavaland - lighting_cutoff_red = 35 - lighting_cutoff_green = 20 - lighting_cutoff_blue = 45 - - -/mob/living/simple_animal/hostile/big_legion/Initialize(mapload) - .=..() - AddComponent(\ - /datum/component/spawner,\ - spawn_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion),\ - spawn_time = 20 SECONDS,\ - max_spawned = 3,\ - spawn_text = "peels itself off from",\ - faction = faction,\ - ) - - -// Snow Legion -/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow - name = "snow legion" - desc = "You can still see what was once a human under the shifting snowy mass, clearly decorated by a clown." - icon = 'icons/mob/simple/icemoon/icemoon_monsters.dmi' - icon_state = "snowlegion" - icon_living = "snowlegion" - icon_aggro = "snowlegion_alive" - icon_dead = "snowlegion" - crusher_loot = /obj/item/crusher_trophy/legion_skull - loot = list(/obj/item/organ/internal/monster_core/regenerative_core/legion) - brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/snow - weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE) - snow_legion = TRUE - -/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/snow/make_legion(mob/living/carbon/human/H) - return new /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow(H.loc) - -/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/portal - from_spawner = TRUE - -// Snow Legion skull -/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/snow - name = "snow legion" - desc = "One of many." - icon = 'icons/mob/simple/icemoon/icemoon_monsters.dmi' - icon_state = "snowlegion_head" - icon_living = "snowlegion_head" - icon_aggro = "snowlegion_head" - icon_dead = "snowlegion_head" - weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/snake.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/snake.dm deleted file mode 100644 index e128349bc2e..00000000000 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/snake.dm +++ /dev/null @@ -1,76 +0,0 @@ - -/mob/living/simple_animal/hostile/retaliate/snake - name = "snake" - desc = "A slithery snake. These legless reptiles are the bane of mice and adventurers alike." - icon_state = "snake" - icon_living = "snake" - icon_dead = "snake_dead" - speak_emote = list("hisses") - health = 20 - maxHealth = 20 - attack_verb_continuous = "bites" - attack_verb_simple = "bite" - attack_sound = 'sound/weapons/bite.ogg' - attack_vis_effect = ATTACK_EFFECT_BITE - melee_damage_lower = 5 - melee_damage_upper = 6 - response_help_continuous = "pets" - response_help_simple = "pet" - response_disarm_continuous = "shoos" - response_disarm_simple = "shoo" - response_harm_continuous = "steps on" - response_harm_simple = "step on" - faction = list(FACTION_HOSTILE) - density = FALSE - pass_flags = PASSTABLE | PASSMOB - mob_size = MOB_SIZE_SMALL - mob_biotypes = MOB_ORGANIC|MOB_BEAST|MOB_REPTILE - gold_core_spawnable = FRIENDLY_SPAWN - obj_damage = 0 - environment_smash = ENVIRONMENT_SMASH_NONE - -/mob/living/simple_animal/hostile/retaliate/snake/Initialize(mapload, special_reagent) - . = ..() - add_cell_sample() - ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) - if(!special_reagent) - special_reagent = /datum/reagent/toxin - AddElement(/datum/element/venomous, special_reagent, 4) - -/mob/living/simple_animal/hostile/retaliate/snake/add_cell_sample() - AddElement(/datum/element/swabable, CELL_LINE_TABLE_SNAKE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) - -/mob/living/simple_animal/hostile/retaliate/snake/ListTargets(atom/the_target) - var/atom/target_from = GET_TARGETS_FROM(src) - . = oview(vision_range, target_from) //get list of things in vision range - var/list/living_mobs = list() - var/list/mice = list() - for (var/HM in .) - //Yum a tasty mouse - if(ismouse(HM)) - mice += HM - if(isliving(HM)) - living_mobs += HM - - // if no tasty mice to chase, lets chase any living mob enemies in our vision range - if(length(mice)) - return mice - - var/list/actual_enemies = list() - for(var/datum/weakref/enemy as anything in enemies) - var/mob/flesh_and_blood = enemy.resolve() - if(!flesh_and_blood) - enemies -= enemy - continue - actual_enemies += flesh_and_blood - - //Filter living mobs (in range mobs) by those we consider enemies (retaliate behaviour) - return living_mobs & actual_enemies - -/mob/living/simple_animal/hostile/retaliate/snake/AttackingTarget() - if(ismouse(target)) - visible_message(span_notice("[name] consumes [target] in a single gulp!"), span_notice("You consume [target] in a single gulp!")) - QDEL_NULL(target) - adjustBruteLoss(-2) - else - return ..() diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 74a27e2a014..4966ac76a8e 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -315,7 +315,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( if(parrot_state == PARROT_PERCH) parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched - parrot_interest = user + set_parrot_interest(user) parrot_state = PARROT_SWOOP //The parrot just got hit, it WILL move, now to pick a direction.. if(health > 30) //Let's get in there and squawk it up! @@ -344,7 +344,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched if(user.melee_damage_upper > 0 && !stat) - parrot_interest = user + set_parrot_interest(user) parrot_state = PARROT_SWOOP | PARROT_ATTACK //Attack other animals regardless icon_state = icon_living @@ -355,7 +355,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( if(parrot_state == PARROT_PERCH) parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched - parrot_interest = user + set_parrot_interest(user) parrot_state = PARROT_SWOOP if(health > 30) //Let's get in there and squawk it up! parrot_state |= PARROT_ATTACK @@ -380,7 +380,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( if(parrot_state == PARROT_PERCH) parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched - parrot_interest = null + set_parrot_interest(null) parrot_state = PARROT_WANDER | PARROT_FLEE //Been shot and survived! RUN LIKE HELL! //parrot_been_shot += 5 icon_state = icon_living @@ -475,7 +475,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( speak = newspeak //Search for item to steal - parrot_interest = search_for_item() + set_parrot_interest(search_for_item()) if(parrot_interest) manual_emote("looks in [parrot_interest]'s direction and takes flight.") parrot_state = PARROT_SWOOP | PARROT_STEAL @@ -486,7 +486,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( else if(parrot_state == PARROT_WANDER) //Stop movement, we'll set it later SSmove_manager.stop_looping(src) - parrot_interest = null + set_parrot_interest(null) //Wander around aimlessly. This will help keep the loops from searches down //and possibly move the mob into a new are in view of something they can use @@ -498,7 +498,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( var/atom/movable/AM = search_for_perch_and_item() //This handles checking through lists so we know it's either a perch or stealable item if(AM) if(isitem(AM) || isliving(AM)) //If stealable item - parrot_interest = AM + set_parrot_interest(AM) manual_emote("turns and flies towards [parrot_interest].") parrot_state = PARROT_SWOOP | PARROT_STEAL return @@ -543,7 +543,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( parrot_interest.forceMove(src) visible_message(span_notice("[src] grabs [held_item]!"), span_notice("You grab [held_item]!"), span_hear("You hear the sounds of wings flapping furiously.")) - parrot_interest = null + set_parrot_interest(null) parrot_state = PARROT_SWOOP | PARROT_RETURN return @@ -591,7 +591,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( //If we're attacking a nothing, an object, a turf or a ghost for some stupid reason, switch to wander if(!parrot_interest || !isliving(parrot_interest)) - parrot_interest = null + set_parrot_interest(null) parrot_state = PARROT_WANDER return @@ -605,7 +605,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( //If the mob we've been chasing/attacking dies or falls into crit, check for loot! if(L.stat) - parrot_interest = null + set_parrot_interest(null) if(!held_item) held_item = steal_from_ground() if(!held_item) @@ -629,7 +629,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( //-----STATE MISHAP else //This should not happen. If it does lets reset everything and try again SSmove_manager.stop_looping(src) - parrot_interest = null + set_parrot_interest(null) parrot_perch = null drop_held_item() parrot_state = PARROT_WANDER @@ -639,6 +639,17 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( * Procs */ +/mob/living/simple_animal/parrot/proc/set_parrot_interest(atom/movable/shiny) + if(parrot_interest) + UnregisterSignal(parrot_interest, COMSIG_QDELETING) + parrot_interest = shiny + if(parrot_interest) + RegisterSignal(parrot_interest, COMSIG_QDELETING, PROC_REF(shiny_deleted)) + +/mob/living/simple_animal/parrot/proc/shiny_deleted(datum/source) + SIGNAL_HANDLER + set_parrot_interest(null) + /mob/living/simple_animal/parrot/proc/isStuck() //Check to see if the parrot is stuck due to things like windows or doors or windowdoors if(parrot_lastmove) @@ -1038,7 +1049,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( /mob/living/simple_animal/parrot/poly/ghost/handle_automated_movement() if(isliving(parrot_interest)) if(!ishuman(parrot_interest)) - parrot_interest = null + set_parrot_interest(null) else if(parrot_state == (PARROT_SWOOP | PARROT_ATTACK) && Adjacent(parrot_interest)) SSmove_manager.move_to(src, parrot_interest, 0, parrot_speed) Possess(parrot_interest) @@ -1051,7 +1062,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( P.parrot = src forceMove(H) H.ForceContractDisease(P, FALSE) - parrot_interest = null + set_parrot_interest(null) H.visible_message(span_danger("[src] dive bombs into [H]'s chest and vanishes!"), span_userdanger("[src] dive bombs into your chest, vanishing! This can't be good!")) #undef PARROT_PERCH diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 2fdec746899..cebb747f6ba 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1405,8 +1405,11 @@ . = ..() VV_DROPDOWN_OPTION("", "---------") VV_DROPDOWN_OPTION(VV_HK_GIB, "Gib") + VV_DROPDOWN_OPTION(VV_HK_REMOVE_SPELL, "Remove Spell") VV_DROPDOWN_OPTION(VV_HK_GIVE_SPELL, "Give Spell") VV_DROPDOWN_OPTION(VV_HK_REMOVE_SPELL, "Remove Spell") + VV_DROPDOWN_OPTION(VV_HK_GIVE_MOB_ACTION, "Give Mob Ability") + VV_DROPDOWN_OPTION(VV_HK_REMOVE_MOB_ACTION, "Remove Mob Ability") VV_DROPDOWN_OPTION(VV_HK_GIVE_DISEASE, "Give Disease") VV_DROPDOWN_OPTION(VV_HK_GODMODE, "Toggle Godmode") VV_DROPDOWN_OPTION(VV_HK_DROP_ALL, "Drop Everything") @@ -1433,6 +1436,14 @@ if(!check_rights(R_ADMIN)) return usr.client.cmd_admin_godmode(src) + if(href_list[VV_HK_GIVE_MOB_ACTION]) + if(!check_rights(NONE)) + return + usr.client.give_mob_action(src) + if(href_list[VV_HK_REMOVE_MOB_ACTION]) + if(!check_rights(NONE)) + return + usr.client.remove_mob_action(src) if(href_list[VV_HK_GIVE_SPELL]) if(!check_rights(NONE)) return diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 3e561c75341..7df256d1873 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -207,20 +207,38 @@ return "" // moved out of admins.dm because things other than admin procs were calling this. -/// Returns TRUE if the game has started and we're either an AI with a 0th law, or we're someone with a special role/antag datum -/proc/is_special_character(mob/M) +/** + * Returns TRUE if the game has started and we're either an AI with a 0th law, or we're someone with a special role/antag datum + * If allow_fake_antags is set to FALSE, Valentines, ERTs, and any such roles with FLAG_FAKE_ANTAG won't pass. +*/ +/proc/is_special_character(mob/M, allow_fake_antags = FALSE) if(!SSticker.HasRoundStarted()) return FALSE if(!istype(M)) return FALSE if(iscyborg(M)) //as a borg you're now beholden to your laws rather than greentext return FALSE + + + // Returns TRUE if AI has a zeroth law *and* either has a special role *or* an antag datum. if(isAI(M)) var/mob/living/silicon/ai/A = M return (A.laws?.zeroth && (A.mind?.special_role || !isnull(M.mind?.antag_datums))) - if(M.mind?.special_role || !isnull(M.mind?.antag_datums)) //they have an antag datum! + + if(M.mind?.special_role) return TRUE - return FALSE + + // Turns 'faker' to TRUE if the antag datum is fake. If it's not fake, returns TRUE directly. + var/faker = FALSE + for(var/datum/antagonist/antag_datum as anything in M.mind?.antag_datums) + if((antag_datum.antag_flags & FLAG_FAKE_ANTAG)) + faker = TRUE + else + return TRUE + + // If 'faker' was assigned TRUE in the above loop and the argument 'allow_fake_antags' is set to TRUE, this passes. + // Else, return FALSE. + return (faker && allow_fake_antags) /** * Fancy notifications for ghosts @@ -521,3 +539,33 @@ "[key_name(src)] manually changed selected zone", data, ) + +/** + * Returns an associative list of the logs of a certain amount of lines spoken recently by this mob + * copy_amount - number of lines to return + * line_chance - chance to return a line, if you don't want just the most recent x lines + */ +/mob/proc/copy_recent_speech(copy_amount = LING_ABSORB_RECENT_SPEECH, line_chance = 100) + var/list/recent_speech = list() + var/list/say_log = list() + var/log_source = logging + for(var/log_type in log_source) + var/nlog_type = text2num(log_type) + if(nlog_type & LOG_SAY) + var/list/reversed = log_source[log_type] + if(islist(reversed)) + say_log = reverse_range(reversed.Copy()) + break + + for(var/spoken_memory in say_log) + if(recent_speech.len >= copy_amount) + break + if(!prob(line_chance)) + continue + recent_speech[spoken_memory] = splittext(say_log[spoken_memory], "\"", 1, 0, TRUE)[3] + + var/list/raw_lines = list() + for (var/key as anything in recent_speech) + raw_lines += recent_speech[key] + + return raw_lines diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index e9b0f532da5..03712663249 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -132,7 +132,7 @@ //Basically an optional override for our glide size //Sometimes you want to look like you're moving with a delay you don't actually have yet visual_delay = 0 - var/old_dir = dir + var/old_dir = mob.dir . = ..() diff --git a/code/modules/mob_spawn/corpses/mining_corpses.dm b/code/modules/mob_spawn/corpses/mining_corpses.dm index c0ea4b6af42..8b7ad474b16 100644 --- a/code/modules/mob_spawn/corpses/mining_corpses.dm +++ b/code/modules/mob_spawn/corpses/mining_corpses.dm @@ -16,18 +16,21 @@ //Legion infested mobs -//dwarf type which spawns dwarfy versions -/obj/effect/mob_spawn/corpse/human/legioninfested/dwarf - -/obj/effect/mob_spawn/corpse/human/legioninfested/dwarf/special(mob/living/carbon/human/spawned_human) - . = ..() - spawned_human.dna.add_mutation(/datum/mutation/human/dwarfism) - -//main type, rolls a pool of legion victims +/// Mob spawner used by Legion to spawn costumed bodies /obj/effect/mob_spawn/corpse/human/legioninfested brute_damage = 1000 /obj/effect/mob_spawn/corpse/human/legioninfested/Initialize(mapload) + outfit = select_outfit() + return ..() + +/obj/effect/mob_spawn/corpse/human/legioninfested/special(mob/living/carbon/human/spawned_human) + . = ..() + var/obj/item/organ/internal/legion_tumour/cancer = new() + cancer.Insert(spawned_human, special = TRUE, drop_if_replaced = FALSE) + +/// Returns the outfit worn by our corpse +/obj/effect/mob_spawn/corpse/human/legioninfested/proc/select_outfit() var/corpse_theme = pick_weight(list( "Miner" = 64, "Clown" = 5, @@ -40,26 +43,36 @@ "Shadow", )) = 4, )) + switch(corpse_theme) if("Miner") - outfit = /datum/outfit/consumed_miner + return /datum/outfit/consumed_miner if("Ashwalker") - outfit = /datum/outfit/consumed_ashwalker + return /datum/outfit/consumed_ashwalker if("Golem") - outfit = /datum/outfit/consumed_golem + return /datum/outfit/consumed_golem if("Clown") - outfit = /datum/outfit/consumed_clown + return /datum/outfit/consumed_clown if("Cultist") - outfit = /datum/outfit/consumed_cultist + return /datum/outfit/consumed_cultist if("Dame") - outfit = /datum/outfit/consumed_dame + return /datum/outfit/consumed_dame if("Operative") - outfit = /datum/outfit/syndicatecommandocorpse/lessenedgear + return /datum/outfit/syndicatecommandocorpse/lessenedgear if("Shadow") - outfit = /datum/outfit/consumed_shadowperson + return /datum/outfit/consumed_shadowperson + +/// Corpse spawner used by dwarf legions to make small corpses +/obj/effect/mob_spawn/corpse/human/legioninfested/dwarf + +/obj/effect/mob_spawn/corpse/human/legioninfested/dwarf/special(mob/living/carbon/human/spawned_human) . = ..() + spawned_human.dna.add_mutation(/datum/mutation/human/dwarfism) + +/// Corpse spawner used by snow legions with alternate costumes +/obj/effect/mob_spawn/corpse/human/legioninfested/snow -/obj/effect/mob_spawn/corpse/human/snowlegioninfested/Initialize(mapload) +/obj/effect/mob_spawn/corpse/human/legioninfested/snow/select_outfit() var/corpse_theme = pick_weight(list( "Miner" = 64, "Clown" = 5, @@ -72,24 +85,49 @@ "Shadow", )) = 4, )) + switch(corpse_theme) if("Miner") - outfit = /datum/outfit/consumed_miner + return /datum/outfit/consumed_miner if("Settler") - outfit = /datum/outfit/consumed_ice_settler + return /datum/outfit/consumed_ice_settler if("Heremoth") - outfit = /datum/outfit/consumed_heremoth + return /datum/outfit/consumed_heremoth if("Clown") - outfit = /datum/outfit/consumed_clown + return /datum/outfit/consumed_clown if("Cultist") - outfit = /datum/outfit/consumed_cultist + return /datum/outfit/consumed_cultist if("Golem") - outfit = /datum/outfit/consumed_golem + return /datum/outfit/consumed_golem if("Operative") - outfit = /datum/outfit/syndicatecommandocorpse/lessenedgear + return /datum/outfit/syndicatecommandocorpse/lessenedgear if("Shadow") - outfit = /datum/outfit/consumed_shadowperson + return /datum/outfit/consumed_shadowperson + +/// Creates a dead legion-infested skeleton +/obj/effect/mob_spawn/corpse/human/legioninfested/skeleton + name = "legion-infested skeleton" + mob_name = "skeleton" + mob_species = /datum/species/skeleton + +/obj/effect/mob_spawn/corpse/human/legioninfested/skeleton/select_outfit() + return null + +/obj/effect/mob_spawn/corpse/human/legioninfested/skeleton/special(mob/living/carbon/human/spawned_human) . = ..() + spawned_human.gender = NEUTER + +/// Creates a dead and burned legion-infested skeleton +/obj/effect/mob_spawn/corpse/human/legioninfested/skeleton/charred + name = "charred legion-infested skeleton" + mob_name = "charred skeleton" + brute_damage = 0 + burn_damage = 1000 + +/obj/effect/mob_spawn/corpse/human/legioninfested/skeleton/charred/special(mob/living/carbon/human/spawned_human) + . = ..() + spawned_human.color = "#454545" + /datum/outfit/consumed_miner name = "Legion-Consumed Miner" diff --git a/code/modules/mob_spawn/ghost_roles/drone_roles.dm b/code/modules/mob_spawn/ghost_roles/drone_roles.dm new file mode 100644 index 00000000000..b8a31a16b13 --- /dev/null +++ b/code/modules/mob_spawn/ghost_roles/drone_roles.dm @@ -0,0 +1,6 @@ +/obj/effect/mob_spawn/ghost_role/drone/name_mob(mob/living/spawned_mob, forced_name) + if(!forced_name) + var/designation = pick(GLOB.posibrain_names) + forced_name = "Drone ([designation]-[rand(100, 999)])" + + return ..() diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm index f11c6b9b4b9..f8daa9bab54 100644 --- a/code/modules/mod/mod_types.dm +++ b/code/modules/mod/mod_types.dm @@ -260,6 +260,12 @@ /obj/item/mod/module/jump_jet, ) +/obj/item/mod/control/pre_equipped/nuclear/no_jetpack + +/obj/item/mod/control/pre_equipped/nuclear/no_jetpack/Initialize(mapload, new_theme, new_skin, new_core) + applied_modules -= list(/obj/item/mod/module/jetpack/advanced, /obj/item/mod/module/jump_jet) + return ..() + /obj/item/mod/control/pre_equipped/nuclear/plasmaman /obj/item/mod/control/pre_equipped/nuclear/plasmaman/Initialize(mapload, new_theme, new_skin, new_core) diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index 21d2b8352fb..6fe91c9575b 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -150,6 +150,7 @@ close_all_programs() //Some components will actually try and interact with this, so let's do it later QDEL_NULL(soundloop) + looping_sound = FALSE // Necessary to stop a possible runtime trying to call soundloop.stop() when soundloop has been qdel'd QDEL_LIST(stored_files) if(istype(inserted_disk)) @@ -802,14 +803,8 @@ /obj/item/modular_computer/wrench_act_secondary(mob/living/user, obj/item/tool) . = ..() tool.play_tool_sound(src, user, 20, volume=20) - internal_cell?.forceMove(drop_location()) - computer_id_slot?.forceMove(drop_location()) - inserted_disk?.forceMove(drop_location()) - remove_pai() - new /obj/item/stack/sheet/iron(get_turf(loc), steel_sheet_cost) + deconstruct(TRUE) user.balloon_alert(user, "disassembled") - relay_qdel() - qdel(src) return TOOL_ACT_TOOLTYPE_SUCCESS /obj/item/modular_computer/welder_act(mob/living/user, obj/item/tool) @@ -830,15 +825,26 @@ return TOOL_ACT_TOOLTYPE_SUCCESS /obj/item/modular_computer/deconstruct(disassembled = TRUE) - break_apart() - return ..() - -/obj/item/modular_computer/proc/break_apart() + remove_pai() + eject_aicard() if(!(flags_1 & NODECONSTRUCT_1)) - physical.visible_message(span_notice("\The [src] breaks apart!")) - var/turf/newloc = get_turf(src) - new /obj/item/stack/sheet/iron(newloc, round(steel_sheet_cost / 2)) + if (disassembled) + internal_cell?.forceMove(drop_location()) + computer_id_slot?.forceMove(drop_location()) + inserted_disk?.forceMove(drop_location()) + new /obj/item/stack/sheet/iron(drop_location(), steel_sheet_cost) + else + physical.visible_message(span_notice("\The [src] breaks apart!")) + new /obj/item/stack/sheet/iron(drop_location(), round(steel_sheet_cost * 0.5)) relay_qdel() + return ..() + +// Ejects the inserted intellicard, if one exists. Used when the computer is deconstructed. +/obj/item/modular_computer/proc/eject_aicard() + var/datum/computer_file/program/ai_restorer/program = locate() in stored_files + if (program) + return program.try_eject(forced = TRUE) + return FALSE // Used by processor to relay qdel() to machinery type. /obj/item/modular_computer/proc/relay_qdel() diff --git a/code/modules/modular_computers/computers/machinery/modular_computer.dm b/code/modules/modular_computers/computers/machinery/modular_computer.dm index 33f4bc29a16..293cdd9c5f7 100644 --- a/code/modules/modular_computers/computers/machinery/modular_computer.dm +++ b/code/modules/modular_computers/computers/machinery/modular_computer.dm @@ -125,9 +125,9 @@ return cpu.screwdriver_act(user, tool) return ..() -/obj/machinery/modular_computer/wrench_act(mob/user, obj/item/tool) +/obj/machinery/modular_computer/wrench_act_secondary(mob/user, obj/item/tool) if(cpu) - return cpu.wrench_act(user, tool) + return cpu.wrench_act_secondary(user, tool) return ..() /obj/machinery/modular_computer/welder_act(mob/user, obj/item/tool) diff --git a/code/modules/modular_computers/file_system/programs/records.dm b/code/modules/modular_computers/file_system/programs/records.dm index 960702d608c..9b5617364c0 100644 --- a/code/modules/modular_computers/file_system/programs/records.dm +++ b/code/modules/modular_computers/file_system/programs/records.dm @@ -45,6 +45,7 @@ current_record["rank"] = person.rank current_record["species"] = person.species current_record["wanted"] = person.wanted_status + current_record["voice"] = person.voice all_records += list(current_record) if("medical") diff --git a/code/modules/movespeed/modifiers/mobs.dm b/code/modules/movespeed/modifiers/mobs.dm index 59b514a3d57..e5f29323223 100644 --- a/code/modules/movespeed/modifiers/mobs.dm +++ b/code/modules/movespeed/modifiers/mobs.dm @@ -84,9 +84,6 @@ /datum/movespeed_modifier/shove multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH -/datum/movespeed_modifier/borg_throw - multiplicative_slowdown = 0.9 - /datum/movespeed_modifier/human_carry multiplicative_slowdown = HUMAN_CARRY_SLOWDOWN blacklisted_movetypes = FLOATING diff --git a/code/modules/pai/pai.dm b/code/modules/pai/pai.dm index 8c3039d8c62..e1a4dfb0ae0 100644 --- a/code/modules/pai/pai.dm +++ b/code/modules/pai/pai.dm @@ -111,6 +111,7 @@ "crow" = TRUE, "duffel" = TRUE, "fox" = FALSE, + "frog" = TRUE, "hawk" = FALSE, "lizard" = FALSE, "monkey" = TRUE, diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index cb6aae768fa..ed99e7ea179 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -193,9 +193,9 @@ GLOBAL_LIST_EMPTY(employmentCabinets) /obj/structure/filingcabinet/employment/proc/fillCurrent() //This proc fills the cabinet with the current crew. for(var/datum/record/locked/target in GLOB.manifest.locked) - var/datum/mind/mind_ref = target.mind_ref - if(mind_ref && ishuman(mind_ref.current)) - addFile(mind_ref.current) + var/datum/mind/filed_mind = target.mind_ref.resolve() + if(filed_mind && ishuman(filed_mind.current)) + addFile(filed_mind.current) /obj/structure/filingcabinet/employment/proc/addFile(mob/living/carbon/human/employee) new /obj/item/paper/employment_contract(src, employee.mind.name) diff --git a/code/modules/photography/_pictures.dm b/code/modules/photography/_pictures.dm index 8c949892dbf..45fa5654ad9 100644 --- a/code/modules/photography/_pictures.dm +++ b/code/modules/photography/_pictures.dm @@ -5,6 +5,8 @@ var/list/mobs_seen = list() /// List of weakrefs pointing at dead mobs that appear in this photo var/list/dead_seen = list() + /// List of strings of face-visible humans in this photo + var/list/names_seen = list() var/caption var/icon/picture_image var/icon/picture_icon @@ -16,7 +18,7 @@ ///Was this image capable of seeing ghosts? var/see_ghosts = CAMERA_NO_GHOSTS -/datum/picture/New(name, desc, mobs_spotted, dead_spotted, image, icon, size_x, size_y, bp, caption_, autogenerate_icon, can_see_ghosts) +/datum/picture/New(name, desc, mobs_spotted, dead_spotted, names, image, icon, size_x, size_y, bp, caption_, autogenerate_icon, can_see_ghosts) if(!isnull(name)) picture_name = name if(!isnull(desc)) @@ -27,6 +29,9 @@ if(!isnull(dead_spotted)) for(var/mob/seen as anything in dead_spotted) dead_seen += WEAKREF(seen) + if(!isnull(names)) + for(var/seen in names) + names_seen += seen if(!isnull(image)) picture_image = image if(!isnull(icon)) diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm index 1c0e360ed75..b168aaf54da 100644 --- a/code/modules/photography/camera/camera.dm +++ b/code/modules/photography/camera/camera.dm @@ -188,6 +188,8 @@ var/list/mobs = list() var/blueprints = FALSE var/clone_area = SSmapping.request_turf_block_reservation(size_x * 2 + 1, size_y * 2 + 1, 1) + ///list of human names taken on picture + var/list/names = list() var/width = size_x * 2 + 1 var/height = size_y * 2 + 1 @@ -218,8 +220,11 @@ var/icon/get_icon = camera_get_icon(turfs, target_turf, psize_x, psize_y, clone_area, size_x, size_y, (size_x * 2 + 1), (size_y * 2 + 1)) qdel(clone_area) get_icon.Blend("#000", ICON_UNDERLAY) + for(var/mob/living/carbon/human/person in mobs) + if(person.is_face_visible()) + names += "[person.name]" - var/datum/picture/picture = new("picture", desc.Join(" "), mobs_spotted, dead_spotted, get_icon, null, psize_x, psize_y, blueprints, can_see_ghosts = see_ghosts) + var/datum/picture/picture = new("picture", desc.Join(" "), mobs_spotted, dead_spotted, names, get_icon, null, psize_x, psize_y, blueprints, can_see_ghosts = see_ghosts) after_picture(user, picture) SEND_SIGNAL(src, COMSIG_CAMERA_IMAGE_CAPTURED, target, user) blending = FALSE diff --git a/code/modules/photography/photos/photo.dm b/code/modules/photography/photos/photo.dm index 9be79a58266..b34ff459c00 100644 --- a/code/modules/photography/photos/photo.dm +++ b/code/modules/photography/photos/photo.dm @@ -54,11 +54,11 @@ icon = I return ..() -/obj/item/photo/suicide_act(mob/living/carbon/user) +/obj/item/photo/suicide_act(mob/living/carbon/human/user) user.visible_message(span_suicide("[user] is taking one last look at \the [src]! It looks like [user.p_theyre()] giving in to death!"))//when you wanna look at photo of waifu one last time before you die... - if (user.gender == MALE) + if (!ishuman(user) || user.physique == MALE) playsound(user, 'sound/voice/human/manlaugh1.ogg', 50, TRUE)//EVERY TIME I DO IT MAKES ME LAUGH - else if (user.gender == FEMALE) + else playsound(user, 'sound/voice/human/womanlaugh.ogg', 50, TRUE) return OXYLOSS diff --git a/code/modules/power/rtg.dm b/code/modules/power/rtg.dm index c49bc455165..974c2e66737 100644 --- a/code/modules/power/rtg.dm +++ b/code/modules/power/rtg.dm @@ -71,7 +71,7 @@ visible_message(span_danger("\The [src] lets out a shower of sparks as it starts to lose stability!"),\ span_hear("You hear a loud electrical crack!")) playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5) - tesla_zap(src, 5, power_gen * 0.05) + tesla_zap(src, 5, power_gen * 20) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(explosion), src, 2, 3, 4, null, 8), 10 SECONDS) // Not a normal explosion. /obj/machinery/power/rtg/abductor/bullet_act(obj/projectile/Proj) diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 654ea805440..8598b3cccf2 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -53,8 +53,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) var/damage_archived = 0 var/list/damage_factors - /// How much extra power does the main zap generate. - var/zap_multiplier = 1 + /// The zap power transmission over internal energy. W/MeV. + var/zap_transmission_rate = BASE_POWER_TRANSMISSION_RATE var/list/zap_factors /// The temperature at which we start taking damage @@ -95,7 +95,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) /// How much power decay is negated. Complete power decay negation at 1. var/gas_powerloss_inhibition = 0 /// Affects the amount of power the main SM zap makes. - var/gas_power_transmission = 0 + var/gas_power_transmission_rate = 0 /// Affects the power gain the SM experiances from heat. var/gas_heat_power_generation = 0 @@ -109,7 +109,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) var/external_damage_immediate = 0 ///The cutoff for a bolt jumping, grows with heat, lowers with higher mol count, - var/zap_cutoff = 1500 + var/zap_cutoff = 1.2e6 ///How much the bullets damage should be multiplied by when it is added to the internal variables var/bullet_energy = SUPERMATTER_DEFAULT_BULLET_ENERGY ///How much hallucination should we produce per unit of power? @@ -153,6 +153,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) ///Stores the time of when the last zap occurred var/last_power_zap = 0 + var/last_high_energy_zap = 0 ///Do we show this crystal in the CIMS modular program var/include_in_cims = TRUE @@ -275,7 +276,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) // PART 3: POWER PROCESSING internal_energy_factors = calculate_internal_energy() - zap_factors = calculate_zap_multiplier() + zap_factors = calculate_zap_transmission_rate() if(internal_energy && (last_power_zap + (4 - internal_energy * 0.001) SECONDS) < world.time) playsound(src, 'sound/weapons/emitter2.ogg', 70, TRUE) hue_angle_shift = clamp(903 * log(10, (internal_energy + 8000)) - 3590, -50, 240) @@ -286,9 +287,9 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) supermatter_zap( zapstart = src, range = 3, - zap_str = 1.25 * internal_energy * zap_multiplier * delta_time, + zap_str = internal_energy * zap_transmission_rate * delta_time, zap_flags = ZAP_SUPERMATTER_FLAGS, - zap_cutoff = 300 * delta_time, + zap_cutoff = 2.4e5 * delta_time, power_level = internal_energy, color = zap_color, ) @@ -374,15 +375,20 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) "name" = factor, "amount" = amount * -1 )) + var/list/internal_energy_si_derived_data = siunit_isolated(internal_energy * 1e6, "eV", 3) data["internal_energy"] = internal_energy + data["internal_energy_coefficient"] = internal_energy_si_derived_data[SI_COEFFICIENT] + data["internal_energy_unit"] = internal_energy_si_derived_data[SI_UNIT] data["internal_energy_factors"] = list() for (var/factor in internal_energy_factors) + var/list/internal_energy_factor_si_derived_data = siunit_isolated(internal_energy_factors[factor] * 1e6, "eV", 3) var/amount = round(internal_energy_factors[factor], 0.01) if(!amount) continue data["internal_energy_factors"] += list(list( "name" = factor, - "amount" = amount + "amount" = internal_energy_factor_si_derived_data[SI_COEFFICIENT], + "unit" = internal_energy_factor_si_derived_data[SI_UNIT], )) data["temp_limit"] = temp_limit data["temp_limit_factors"] = list() @@ -392,7 +398,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) continue data["temp_limit_factors"] += list(list( "name" = factor, - "amount" = amount + "amount" = amount, )) data["waste_multiplier"] = waste_multiplier data["waste_multiplier_factors"] = list() @@ -402,18 +408,42 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) continue data["waste_multiplier_factors"] += list(list( "name" = factor, - "amount" = amount + "amount" = amount, )) - data["zap_multiplier"] = zap_multiplier - data["zap_multiplier_factors"] = list() + + data["zap_transmission_factors"] = list() for (var/factor in zap_factors) - var/amount = round(zap_factors[factor], 0.01) - if(!amount) + var/list/zap_factor_si_derived_data = siunit_isolated(zap_factors[factor] * internal_energy, "W", 2) + if(!zap_factor_si_derived_data[SI_COEFFICIENT]) continue - data["zap_multiplier_factors"] += list(list( + data["zap_transmission_factors"] += list(list( "name" = factor, - "amount" = amount + "amount" = zap_factor_si_derived_data[SI_COEFFICIENT], + "unit" = zap_factor_si_derived_data[SI_UNIT], )) + + ///Add high energy bonus to the zap transmission data so we can accurately measure our power generation from zaps. + var/high_energy_bonus = 0 + var/zap_transmission = zap_transmission_rate * internal_energy + var/zap_power_multiplier = 1 + if(internal_energy > POWER_PENALTY_THRESHOLD) //Supermatter zaps multiply power internally under some conditions for some reason, so we'll snowflake this for now. + ///Power multiplier bonus applied to all zaps. Zap power generation doubles when it reaches 7GeV and 9GeV. + zap_power_multiplier *= 2 ** clamp(round((internal_energy - POWER_PENALTY_THRESHOLD) / 2000), 0, 2) + ///The supermatter releases additional zaps after 5GeV, with more at 7GeV and 9GeV. + var/additional_zap_bonus = clamp(internal_energy * 3200, 6.4e6, 3.2e7) * clamp(round(INVERSE_LERP(1000, 3000, internal_energy)), 1, 4) + high_energy_bonus = (zap_transmission + additional_zap_bonus) * zap_power_multiplier - zap_transmission + var/list/zap_factor_si_derived_data = siunit_isolated(high_energy_bonus, "W", 2) + data["zap_transmission_factors"] += list(list( + "name" = "High Energy Bonus", + "amount" = zap_factor_si_derived_data[SI_COEFFICIENT], + "unit" = zap_factor_si_derived_data[SI_UNIT], + )) + + var/list/zap_transmission_si_derived_data = siunit_isolated(zap_transmission + high_energy_bonus, "W", 2) + data["zap_transmission"] = zap_transmission + high_energy_bonus + data["zap_transmission_coefficient"] = zap_transmission_si_derived_data[SI_COEFFICIENT] + data["zap_transmission_unit"] = zap_transmission_si_derived_data[SI_UNIT] + data["absorbed_ratio"] = absorption_ratio var/list/formatted_gas_percentage = list() for (var/datum/gas/gas_path as anything in subtypesof(/datum/gas)) @@ -577,7 +607,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) * * Updates: * [/obj/machinery/power/supermatter_crystal/var/list/gas_percentage] - * [/obj/machinery/power/supermatter_crystal/var/gas_power_transmission] + * [/obj/machinery/power/supermatter_crystal/var/gas_power_transmission_rate] * [/obj/machinery/power/supermatter_crystal/var/gas_heat_modifier] * [/obj/machinery/power/supermatter_crystal/var/gas_heat_resistance] * [/obj/machinery/power/supermatter_crystal/var/gas_heat_power_generation] @@ -590,7 +620,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) return gas_percentage = list() - gas_power_transmission = 0 + gas_power_transmission_rate = 0 gas_heat_modifier = 0 gas_heat_resistance = 0 gas_heat_power_generation = 0 @@ -607,7 +637,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) var/datum/sm_gas/sm_gas = current_gas_behavior[gas_path] if(!sm_gas) continue - gas_power_transmission += sm_gas.power_transmission * gas_percentage[gas_path] + gas_power_transmission_rate += sm_gas.power_transmission * gas_percentage[gas_path] gas_heat_modifier += sm_gas.heat_modifier * gas_percentage[gas_path] gas_heat_resistance += sm_gas.heat_resistance * gas_percentage[gas_path] gas_heat_power_generation += sm_gas.heat_power_generation * gas_percentage[gas_path] @@ -637,7 +667,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) external_power_trickle -= min(additive_power[SM_POWER_EXTERNAL_TRICKLE], external_power_trickle) additive_power[SM_POWER_EXTERNAL_IMMEDIATE] = external_power_immediate external_power_immediate = 0 - additive_power[SM_POWER_HEAT] = gas_heat_power_generation * absorbed_gasmix.temperature / 6 + additive_power[SM_POWER_HEAT] = gas_heat_power_generation * absorbed_gasmix.temperature * GAS_HEAT_POWER_SCALING_COEFFICIENT additive_power[SM_POWER_HEAT] && log_activation(who = "environmental factors") // I'm sorry for this, but we need to calculate power lost immediately after power gain. @@ -660,6 +690,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) if(internal_energy && !activation_logged) stack_trace("Supermatter powered for the first time without being logged. Internal energy factors: [json_encode(internal_energy_factors)]") activation_logged = TRUE // so we dont spam the log. + else if(!internal_energy) + last_power_zap = world.time return additive_power /** Log when the supermatter is activated for the first time. @@ -685,24 +717,24 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) activation_logged = TRUE /** - * Perform calculation for the main zap power multiplier. + * Perform calculation for the main zap power transmission rate in W/MeV. * Description of each factors can be found in the defines. * * Updates: - * [/obj/machinery/power/supermatter_crystal/var/zap_multiplier] + * [/obj/machinery/power/supermatter_crystal/var/zap_transmission_rate] * * Returns: The factors that have influenced the calculation. list[FACTOR_DEFINE] = number */ -/obj/machinery/power/supermatter_crystal/proc/calculate_zap_multiplier() - var/list/additive_transmission = list() - additive_transmission[SM_ZAP_BASE] = 1 - additive_transmission[SM_ZAP_GAS] = gas_power_transmission +/obj/machinery/power/supermatter_crystal/proc/calculate_zap_transmission_rate() + var/list/additive_transmission_rate = list() + additive_transmission_rate[SM_ZAP_BASE] = BASE_POWER_TRANSMISSION_RATE + additive_transmission_rate[SM_ZAP_GAS] = BASE_POWER_TRANSMISSION_RATE * gas_power_transmission_rate - zap_multiplier = 0 - for (var/transmission_types in additive_transmission) - zap_multiplier += additive_transmission[transmission_types] - zap_multiplier = max(zap_multiplier, 0) - return additive_transmission + zap_transmission_rate = 0 + for (var/transmission_types in additive_transmission_rate) + zap_transmission_rate += additive_transmission_rate[transmission_types] + zap_transmission_rate = max(zap_transmission_rate, 0) + return additive_transmission_rate /** * Perform calculation for the waste multiplier. @@ -836,7 +868,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) delamination_strategy.on_select(src) return TRUE -/obj/machinery/proc/supermatter_zap(atom/zapstart = src, range = 5, zap_str = 4000, zap_flags = ZAP_SUPERMATTER_FLAGS, list/targets_hit = list(), zap_cutoff = 1500, power_level = 0, zap_icon = DEFAULT_ZAP_ICON_STATE, color = null) +/obj/machinery/proc/supermatter_zap(atom/zapstart = src, range = 5, zap_str = 3.2e6, zap_flags = ZAP_SUPERMATTER_FLAGS, list/targets_hit = list(), zap_cutoff = 1.2e6, power_level = 0, zap_icon = DEFAULT_ZAP_ICON_STATE, color = null) if(QDELETED(zapstart)) return . = zapstart.dir @@ -931,13 +963,13 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) //Going boom should be rareish if(prob(80)) zap_flags &= ~ZAP_MACHINE_EXPLOSIVE - if(target_type == COIL) - var/multi = 2 - switch(power_level)//Between 7k and 9k it's 4, above that it's 8 + if(target_type == COIL || target_type == ROD) + var/multi = 1 + switch(power_level)//Between 7k and 9k it's 2, above that it's 4 if(SEVERE_POWER_PENALTY_THRESHOLD to CRITICAL_POWER_PENALTY_THRESHOLD) - multi = 4 + multi = 2 if(CRITICAL_POWER_PENALTY_THRESHOLD to INFINITY) - multi = 8 + multi = 4 if(zap_flags & ZAP_SUPERMATTER_FLAGS) var/remaining_power = target.zap_act(zap_str * multi, zap_flags) zap_str = remaining_power / multi //Coils should take a lot out of the power of the zap diff --git a/code/modules/power/supermatter/supermatter_extra_effects.dm b/code/modules/power/supermatter/supermatter_extra_effects.dm index 7fe56d9c2d4..efd84c677fa 100644 --- a/code/modules/power/supermatter/supermatter_extra_effects.dm +++ b/code/modules/power/supermatter/supermatter_extra_effects.dm @@ -91,6 +91,7 @@ /obj/machinery/power/supermatter_crystal/proc/handle_high_power() if(internal_energy <= POWER_PENALTY_THRESHOLD && damage <= danger_point) //If the power is above 5000 or if the damage is above 550 + last_high_energy_zap = world.time //Prevent oddly high initial zap due to high energy zaps not getting triggered via too low energy. return var/range = 4 zap_cutoff = 1500 @@ -99,7 +100,7 @@ var/temp = absorbed_gasmix.temperature if(pressure > 0 && temp > 0) //You may be able to freeze the zapstate of the engine with good planning, we'll see - zap_cutoff = clamp(3000 - (internal_energy * total_moles / 10) / temp, 350, 3000)//If the core is cold, it's easier to jump, ditto if there are a lot of mols + zap_cutoff = clamp(1.2e6 - (internal_energy * total_moles * 40) / temp, 1.4e5, 1.2e6)//If the core is cold, it's easier to jump, ditto if there are a lot of mols //We should always be able to zap our way out of the default enclosure //See supermatter_zap() for more details range = clamp(internal_energy / pressure * 10, 2, 7) @@ -128,9 +129,10 @@ if(zap_count >= 1) playsound(loc, 'sound/weapons/emitter2.ogg', 100, TRUE, extrarange = 10) + var/delta_time = min((world.time - last_high_energy_zap) * 0.1, 16) for(var/i in 1 to zap_count) - supermatter_zap(src, range, clamp(internal_energy*2, 4000, 20000), flags, zap_cutoff = src.zap_cutoff, power_level = internal_energy, zap_icon = src.zap_icon) - + supermatter_zap(src, range, clamp(internal_energy * 3200, 6.4e6, 3.2e7) * delta_time, flags, zap_cutoff = src.zap_cutoff * delta_time, power_level = internal_energy, zap_icon = src.zap_icon) + last_high_energy_zap = world.time if(prob(5)) supermatter_anomaly_gen(src, FLUX_ANOMALY, rand(5, 10)) if(prob(5)) diff --git a/code/modules/power/supermatter/supermatter_gas.dm b/code/modules/power/supermatter/supermatter_gas.dm index 141f78a38b8..df8ef8e5b4f 100644 --- a/code/modules/power/supermatter/supermatter_gas.dm +++ b/code/modules/power/supermatter/supermatter_gas.dm @@ -17,33 +17,40 @@ // Positive is true if more of the amount is a good thing. var/list/numeric_data = list() if(sm_gas.power_transmission) + var/list/si_derived_data = siunit_isolated(sm_gas.power_transmission * BASE_POWER_TRANSMISSION_RATE, "W/MeV", 2) numeric_data += list(list( - "name" = "Power Transmission", - "amount" = sm_gas.power_transmission, + "name" = "Power Transmission Bonus", + "amount" = si_derived_data["coefficient"], + "unit" = si_derived_data["unit"], "positive" = TRUE, )) if(sm_gas.heat_modifier) numeric_data += list(list( "name" = "Waste Multiplier", - "amount" = sm_gas.heat_modifier, + "amount" = 100 * sm_gas.heat_modifier, + "unit" = "%", "positive" = FALSE, )) if(sm_gas.heat_resistance) numeric_data += list(list( "name" = "Heat Resistance", - "amount" = sm_gas.heat_resistance, + "amount" = 100 * sm_gas.heat_resistance, + "unit" = "%", "positive" = TRUE, )) if(sm_gas.heat_power_generation) + var/list/si_derived_data = siunit_isolated(sm_gas.heat_power_generation * GAS_HEAT_POWER_SCALING_COEFFICIENT * 1e7 / SSair.wait, "eV/K/s", 2) numeric_data += list(list( "name" = "Heat Power Gain", - "amount" = sm_gas.heat_power_generation, + "amount" = si_derived_data["coefficient"], + "unit" = si_derived_data["unit"], "positive" = TRUE, )) if(sm_gas.powerloss_inhibition) numeric_data += list(list( "name" = "Power Decay Negation", - "amount" = sm_gas.powerloss_inhibition, + "amount" = 100 * sm_gas.powerloss_inhibition, + "unit" = "%", "positive" = TRUE, )) singular_gas_data["numeric_data"] = numeric_data @@ -59,8 +66,7 @@ GLOBAL_LIST_INIT(sm_gas_behavior, init_sm_gas()) /datum/sm_gas /// Path of the [/datum/gas] involved with this interaction. var/gas_path - - /// Influences zap power without interfering with the crystal's own energy. + /// Influences zap power without interfering with the crystal's own energy. Gets scaled by [BASE_POWER_TRANSMISSION_RATE]. var/power_transmission = 0 /// How much more waste heat and gas the SM generates. var/heat_modifier = 0 @@ -216,7 +222,7 @@ GLOBAL_LIST_INIT(sm_gas_behavior, init_sm_gas()) sm.supermatter_zap( sm, range = 6, - zap_str = clamp(sm.internal_energy * 2, 4000, 20000), + zap_str = clamp(sm.internal_energy * 1600, 3.2e6, 1.6e7), zap_flags = ZAP_MOB_STUN, zap_cutoff = sm.zap_cutoff, power_level = sm.internal_energy, diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm index 098ff7ceaee..3cf040b76ef 100644 --- a/code/modules/power/tesla/coil.dm +++ b/code/modules/power/tesla/coil.dm @@ -1,7 +1,5 @@ // zap needs to be over this amount to get power -#define TESLA_COIL_THRESHOLD 80 -// each zap power unit produces 400 joules -#define ZAP_TO_ENERGY(p) (joules_to_energy((p) * 400)) +#define TESLA_COIL_THRESHOLD 32000 /obj/machinery/power/energy_accumulator/tesla_coil name = "tesla coil" @@ -107,7 +105,7 @@ power /= 10 zap_buckle_check(power) var/power_removed = powernet ? power * input_power_multiplier : power - stored_energy += max(ZAP_TO_ENERGY(power_removed - TESLA_COIL_THRESHOLD), 0) + stored_energy += max(joules_to_energy(power_removed - TESLA_COIL_THRESHOLD), 0) return max(power - power_removed, 0) //You get back the amount we didn't use /obj/machinery/power/energy_accumulator/tesla_coil/proc/zap() @@ -170,10 +168,9 @@ if(anchored && !panel_open) flick("grounding_rodhit", src) zap_buckle_check(power) - stored_energy += ZAP_TO_ENERGY(power) + stored_energy += joules_to_energy(power) return 0 else . = ..() #undef TESLA_COIL_THRESHOLD -#undef ZAP_TO_ENERGY diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index b21938e2608..7ee8c0085c9 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -1,5 +1,5 @@ -#define TESLA_DEFAULT_POWER 1738260 -#define TESLA_MINI_POWER 869130 +#define TESLA_DEFAULT_POWER 6.95304e8 +#define TESLA_MINI_POWER 3.47652e8 //Zap constants, speeds up targeting #define BIKE (COIL + 1) #define COIL (ROD + 1) @@ -205,7 +205,7 @@ if(!(zap_flags & ZAP_ALLOW_DUPLICATES)) LAZYSET(shocked_targets, source, TRUE) //I don't want no null refs in my list yeah? . = source.dir - if(power < 1000) + if(power < 4e5) return /* @@ -334,7 +334,7 @@ var/mob/living/closest_mob = closest_atom ADD_TRAIT(closest_mob, TRAIT_BEING_SHOCKED, WAS_SHOCKED) addtimer(TRAIT_CALLBACK_REMOVE(closest_mob, TRAIT_BEING_SHOCKED, WAS_SHOCKED), 1 SECONDS) - var/shock_damage = (zap_flags & ZAP_MOB_DAMAGE) ? (min(round(power/600), 90) + rand(-5, 5)) : 0 + var/shock_damage = (zap_flags & ZAP_MOB_DAMAGE) ? (min(round(power/2.4e5), 90) + rand(-5, 5)) : 0 closest_mob.electrocute_act(shock_damage, source, 1, SHOCK_TESLA | ((zap_flags & ZAP_MOB_STUN) ? NONE : SHOCK_NOSTUN)) if(issilicon(closest_mob)) var/mob/living/silicon/S = closest_mob diff --git a/code/modules/procedural_mapping/mapGenerators/asteroid.dm b/code/modules/procedural_mapping/mapGenerators/asteroid.dm index ab2bc6f2ca4..bf6c84ebf88 100644 --- a/code/modules/procedural_mapping/mapGenerators/asteroid.dm +++ b/code/modules/procedural_mapping/mapGenerators/asteroid.dm @@ -22,7 +22,7 @@ spawnableAtoms = list( /mob/living/basic/mining/basilisk = 10, /mob/living/basic/mining/goliath/ancient = 10, - /mob/living/simple_animal/hostile/asteroid/hivelord = 10, + /mob/living/basic/mining/hivelord = 10, ) diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index 6439b78a9bd..2b62416fe7f 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -275,10 +275,15 @@ user.visible_message(span_danger("[user.name]'s soul is captured by \the [src]!"), span_userdanger("You've lost the gamble! Your soul is forfeit!")) /obj/item/gun/ballistic/revolver/reverse //Fires directly at its user... unless the user is a clown, of course. - name = "\improper Syndicate Revolver" clumsy_check = FALSE icon_state = "revolversyndie" +/obj/item/gun/ballistic/revolver/reverse/Initialize(mapload) + . = ..() + var/obj/item/gun/ballistic/revolver/syndicate/syndie_revolver = /obj/item/gun/ballistic/revolver/syndicate + name = initial(syndie_revolver.name) + desc = initial(syndie_revolver.desc) + /obj/item/gun/ballistic/revolver/reverse/can_trigger_gun(mob/living/user, akimbo_usage) if(akimbo_usage) return FALSE diff --git a/code/modules/projectiles/guns/energy/energy_gun.dm b/code/modules/projectiles/guns/energy/energy_gun.dm index 3fd1e7c1949..cb0b5862e16 100644 --- a/code/modules/projectiles/guns/energy/energy_gun.dm +++ b/code/modules/projectiles/guns/energy/energy_gun.dm @@ -9,6 +9,18 @@ ammo_x_offset = 3 dual_wield_spread = 60 +/obj/item/gun/energy/e_gun/Initialize(mapload) + . = ..() + // Only actual eguns can be converted + if(type != /obj/item/gun/energy/e_gun) + return + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/advancedegun, /datum/crafting_recipe/tempgun, /datum/crafting_recipe/beam_rifle) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/gun/energy/e_gun/add_seclight_point() AddComponent(/datum/component/seclite_attachable, \ light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', \ diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index 8d9a29d3b80..06e82a37aae 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -16,6 +16,19 @@ var/list/modkits = list() gun_flags = NOT_A_REAL_GUN + +/obj/item/gun/energy/recharge/kinetic_accelerator/Initialize(mapload) + . = ..() + // Only actual KAs can be converted + if(type != /obj/item/gun/energy/recharge/kinetic_accelerator) + return + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/ebow) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/gun/energy/recharge/kinetic_accelerator/apply_fantasy_bonuses(bonus) . = ..() max_mod_capacity = modify_fantasy_variable("max_mod_capacity", max_mod_capacity, bonus * 10) diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index dafaaa6a7de..0409f2fe037 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -9,6 +9,18 @@ ammo_x_offset = 1 shaded_charge = 1 +/obj/item/gun/energy/laser/Initialize(mapload) + . = ..() + // Only actual lasguns can be converted + if(type != /obj/item/gun/energy/laser) + return + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/xraylaser, /datum/crafting_recipe/hellgun, /datum/crafting_recipe/ioncarbine, /datum/crafting_recipe/decloner) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/gun/energy/laser/practice name = "practice laser gun" desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice." diff --git a/code/modules/projectiles/projectile/energy/tesla.dm b/code/modules/projectiles/projectile/energy/tesla.dm index 9afb816088f..687bd1b8e73 100644 --- a/code/modules/projectiles/projectile/energy/tesla.dm +++ b/code/modules/projectiles/projectile/energy/tesla.dm @@ -5,7 +5,7 @@ damage = 10 //A worse lasergun var/zap_flags = ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_LOW_POWER_GEN var/zap_range = 3 - var/power = 10000 + var/power = 4e6 /obj/projectile/energy/tesla/on_hit(atom/target) . = ..() @@ -22,7 +22,7 @@ /obj/projectile/energy/tesla/cannon name = "tesla orb" - power = 20000 + power = 8e6 damage = 15 //Mech man big /obj/projectile/energy/tesla_cannon diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index afe59235478..c8da91b9dde 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -481,7 +481,7 @@ speed = 0.3 /// The power of the zap itself when it electrocutes someone - var/zap_power = 20000 + var/zap_power = 8e6 /// The range of the zap itself when it electrocutes someone var/zap_range = 15 /// The flags of the zap itself when it electrocutes someone @@ -503,7 +503,7 @@ return ..() /obj/projectile/magic/aoe/lightning/no_zap - zap_power = 10000 + zap_power = 4e6 zap_range = 4 zap_flags = ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_LOW_POWER_GEN diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 8de1d98cc2e..110107d103f 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -7,6 +7,10 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) if (length(initial(R.name))) .[ckey(initial(R.name))] = t +GLOBAL_LIST_INIT(blacklisted_metalgen_types, typecacheof(list( + /turf/closed/indestructible, //indestructible turfs should be indestructible, metalgen transmutation to plasma allows them to be destroyed + /turf/open/indestructible +))) //Various reagents //Toxin & acid reagents diff --git a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm index f67b813be0c..b81e1600bbf 100644 --- a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm @@ -57,6 +57,20 @@ booze_power *= 0.7 if(HAS_TRAIT(drinker, TRAIT_LIGHT_DRINKER)) booze_power *= 2 + + // water will dilute alcohol effects + var/total_water_volume = 0 + var/total_alcohol_volume = 0 + for(var/datum/reagent/water/sobriety in drinker.reagents.reagent_list) + total_water_volume += sobriety.volume + + for(var/datum/reagent/consumable/ethanol/alcohol in drinker.reagents.reagent_list) + total_alcohol_volume += alcohol.volume + + var/combined_dilute_volume = total_alcohol_volume + total_water_volume + if(combined_dilute_volume) // safety check to prevent division by zero + booze_power *= (total_alcohol_volume / combined_dilute_volume) + // Volume, power, and server alcohol rate effect how quickly one gets drunk drinker.adjust_drunk_effect(sqrt(volume) * booze_power * ALCOHOL_RATE * REM * seconds_per_tick * 0.25) // SKYRAT EDIT CHANGE - Alcohol Tolerance - Original: (sqrt(volume) * booze_power * ALCOHOL_RATE * REM * seconds_per_tick) if(boozepwr > 0) diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index 1e0559d6034..17867389c3d 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -272,9 +272,9 @@ color = "#FFFFFF" // rgb: 255, 255, 255 taste_mult = 1.5 // stop sugar drowning out other flavours nutriment_factor = 2 - metabolization_rate = 2 * REAGENTS_METABOLISM + metabolization_rate = 5 * REAGENTS_METABOLISM creation_purity = 1 // impure base reagents are a big no-no - overdose_threshold = 100 // Hyperglycaemic shock + overdose_threshold = 120 // Hyperglycaemic shock taste_description = "sweetness" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED default_container = /obj/item/reagent_containers/condiment/sugar @@ -286,11 +286,11 @@ /datum/reagent/consumable/sugar/overdose_start(mob/living/M) to_chat(M, span_userdanger("You go into hyperglycaemic shock! Lay off the twinkies!")) - M.AdjustSleeping(600) + M.AdjustSleeping(20 SECONDS) . = TRUE /datum/reagent/consumable/sugar/overdose_process(mob/living/M, seconds_per_tick, times_fired) - M.AdjustSleeping(40 * REM * seconds_per_tick) + M.adjust_drowsiness_up_to((5 SECONDS * REM * seconds_per_tick), 60 SECONDS) ..() . = TRUE diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 2a46d537233..dddf966be72 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -292,6 +292,7 @@ . = ..() if(affected_mob.blood_volume) affected_mob.blood_volume += 0.1 * REM * seconds_per_tick // water is good for you! + affected_mob.adjust_drunk_effect(-0.25 * REM * seconds_per_tick) // and even sobers you up slowly!! // For weird backwards situations where water manages to get added to trays nutrients, as opposed to being snowflaked away like usual. /datum/reagent/water/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user) @@ -2686,13 +2687,16 @@ metal_morph(exposed_turf) ///turn an object into a special material -/datum/reagent/metalgen/proc/metal_morph(atom/A) +/datum/reagent/metalgen/proc/metal_morph(atom/target) var/metal_ref = data["material"] if(!metal_ref) return + if(is_type_in_typecache(target, GLOB.blacklisted_metalgen_types)) //some stuff can lead to exploits if transmuted + return + var/metal_amount = 0 - var/list/materials_to_transmute = A.get_material_composition(BREAKDOWN_INCLUDE_ALCHEMY) + var/list/materials_to_transmute = target.get_material_composition(BREAKDOWN_INCLUDE_ALCHEMY) for(var/metal_key in materials_to_transmute) //list with what they're made of metal_amount += materials_to_transmute[metal_key] @@ -2700,9 +2704,9 @@ metal_amount = default_material_amount //some stuff doesn't have materials at all. To still give them properties, we give them a material. Basically doesn't exist var/list/metal_dat = list((metal_ref) = metal_amount) - A.material_flags = applied_material_flags - A.set_custom_materials(metal_dat) - ADD_TRAIT(A, TRAIT_MAT_TRANSMUTED, type) + target.material_flags = applied_material_flags + target.set_custom_materials(metal_dat) + ADD_TRAIT(target, TRAIT_MAT_TRANSMUTED, type) /datum/reagent/gravitum name = "Gravitum" diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index 707a1dca350..9083de70902 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -542,9 +542,9 @@ reaction_tags = REACTION_TAG_EASY | REACTION_TAG_EXPLOSIVE | REACTION_TAG_DANGEROUS /datum/chemical_reaction/reagent_explosion/teslium_lightning/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume) - var/T1 = created_volume * 20 //100 units : Zap 3 times, with powers 2000/5000/12000. Tesla revolvers have a power of 10000 for comparison. - var/T2 = created_volume * 50 - var/T3 = created_volume * 120 + var/T1 = created_volume * 8e3 //100 units : Zap 3 times, with powers 8e5/2e6/4.8e6. Tesla revolvers have a power of 10000 for comparison. + var/T2 = created_volume * 2e4 + var/T3 = created_volume * 4.8e4 var/added_delay = 0.5 SECONDS if(created_volume >= 75) addtimer(CALLBACK(src, PROC_REF(zappy_zappy), holder, T1), added_delay) diff --git a/code/modules/reagents/reagent_containers/cups/glassbottle.dm b/code/modules/reagents/reagent_containers/cups/glassbottle.dm index e2f445c6a1a..e204c6803fb 100644 --- a/code/modules/reagents/reagent_containers/cups/glassbottle.dm +++ b/code/modules/reagents/reagent_containers/cups/glassbottle.dm @@ -40,6 +40,12 @@ tool_behaviour = TOOL_ROLLINGPIN // Used to knock out the Chef. toolspeed = 1.3 //it's a little awkward to use, but it's a cylinder alright. +/obj/item/reagent_containers/cup/glass/bottle/Initialize(mapload, vol) + . = ..() + AddComponent(/datum/component/slapcrafting,\ + slapcraft_recipes = list(/datum/crafting_recipe/molotov)\ + ) + /obj/item/reagent_containers/cup/glass/bottle/small name = "small glass bottle" desc = "This blank bottle is unyieldingly anonymous, offering no clues to its contents." diff --git a/code/modules/reagents/reagent_containers/cups/soda.dm b/code/modules/reagents/reagent_containers/cups/soda.dm index 4908942b2c0..5bf0eb782c5 100644 --- a/code/modules/reagents/reagent_containers/cups/soda.dm +++ b/code/modules/reagents/reagent_containers/cups/soda.dm @@ -21,6 +21,12 @@ /// If the can hasn't been opened yet, this is the measure of how fizzed up it is from being shaken or thrown around. When opened, this is rolled as a percentage chance to burst var/fizziness = 0 +/obj/item/reagent_containers/cup/soda_cans/Initialize(mapload, vol) + . = ..() + AddComponent(/datum/component/slapcrafting,\ + slapcraft_recipes = list(/datum/crafting_recipe/improv_explosive)\ + ) + /obj/item/reagent_containers/cup/soda_cans/random/Initialize(mapload) ..() var/T = pick(subtypesof(/obj/item/reagent_containers/cup/soda_cans) - /obj/item/reagent_containers/cup/soda_cans/random) diff --git a/code/modules/religion/religion_sects.dm b/code/modules/religion/religion_sects.dm index a322303b00d..9075a656ae9 100644 --- a/code/modules/religion/religion_sects.dm +++ b/code/modules/religion/religion_sects.dm @@ -55,8 +55,8 @@ /// Activates once selected and on newjoins, oriented around people who become holy. /datum/religion_sect/proc/on_conversion(mob/living/chap) SHOULD_CALL_PARENT(TRUE) - to_chat(chap, "\"[quote]\"") - to_chat(chap, "[desc]") + to_chat(chap, span_boldnotice("\"[quote]\"")) + to_chat(chap, span_notice("[desc]")) /// Activates if religious sect is reset by admins, should clean up anything you added on conversion. /datum/religion_sect/proc/on_deconversion(mob/living/chap) @@ -66,17 +66,17 @@ to_chat(chap, span_notice("Return to an altar to reform your sect.")) /// Returns TRUE if the item can be sacrificed. Can be modified to fit item being tested as well as person offering. Returning TRUE will stop the attackby sequence and proceed to on_sacrifice. -/datum/religion_sect/proc/can_sacrifice(obj/item/I, mob/living/chap) +/datum/religion_sect/proc/can_sacrifice(obj/item/sacrifice, mob/living/chap) . = TRUE if(chap.mind.holy_role == HOLY_ROLE_DEACON) to_chat(chap, "You are merely a deacon of [GLOB.deity], and therefore cannot perform rites.") return - if(!is_type_in_typecache(I,desired_items_typecache)) + if(!is_type_in_typecache(sacrifice, desired_items_typecache)) return FALSE /// Activates when the sect sacrifices an item. This proc has NO bearing on the attackby sequence of other objects when used in conjunction with the religious_tool component. -/datum/religion_sect/proc/on_sacrifice(obj/item/I, mob/living/chap) - return adjust_favor(default_item_favor,chap) +/datum/religion_sect/proc/on_sacrifice(obj/item/sacrifice, mob/living/chap) + return adjust_favor(default_item_favor, chap) /// Returns a description for religious tools /datum/religion_sect/proc/tool_examine(mob/living/holy_creature) @@ -89,7 +89,7 @@ . = favor //if favor = 5 and we want to subtract 10, we'll only be able to subtract 5 if((favor + amount > max_favor)) . = (max_favor-favor) //if favor = 5 and we want to add 10 with a max of 10, we'll only be able to add 5 - favor = clamp(0,max_favor, favor+amount) + favor = clamp(0, max_favor, favor+amount) /// Sets favor to a specific amount. Can provide optional features based on a user. /datum/religion_sect/proc/set_favor(amount = 0, mob/living/chap) @@ -190,16 +190,17 @@ blessed.add_mood_event("blessing", /datum/mood_event/blessing) return TRUE -/datum/religion_sect/mechanical/on_sacrifice(obj/item/I, mob/living/chap) - var/obj/item/stock_parts/cell/the_cell = I - if(!istype(the_cell)) //how... +/datum/religion_sect/mechanical/on_sacrifice(obj/item/stock_parts/cell/power_cell, mob/living/chap) + if(!istype(power_cell)) return - if(the_cell.charge < 300) - to_chat(chap,span_notice("[GLOB.deity] does not accept pity amounts of power.")) + + if(power_cell.charge < 300) + to_chat(chap, span_notice("[GLOB.deity] does not accept pity amounts of power.")) return - adjust_favor(round(the_cell.charge/300), chap) - to_chat(chap, span_notice("You offer [the_cell]'s power to [GLOB.deity], pleasing them.")) - qdel(I) + + adjust_favor(round(power_cell.charge/300), chap) + to_chat(chap, span_notice("You offer [power_cell]'s power to [GLOB.deity], pleasing them.")) + qdel(power_cell) return TRUE /**** Pyre God ****/ diff --git a/code/modules/research/designs/biogenerator_designs.dm b/code/modules/research/designs/biogenerator_designs.dm index f07ef21a8e7..14d5c12eb43 100644 --- a/code/modules/research/designs/biogenerator_designs.dm +++ b/code/modules/research/designs/biogenerator_designs.dm @@ -185,3 +185,11 @@ materials = list(/datum/material/biomass = 1) build_path = /obj/item/rollingpaper category = list(RND_CATEGORY_INITIAL, RND_CATEGORY_BIO_MATERIALS) + +/datum/design/candle + name = "Candle" + id = "candle" + build_type = BIOGENERATOR + materials = list(/datum/material/biomass = 3) + build_path = /obj/item/flashlight/flare/candle + category = list(RND_CATEGORY_INITIAL, RND_CATEGORY_BIO_MATERIALS) diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 2bb779e318b..285878e7f26 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -1114,6 +1114,13 @@ surgery = /datum/surgery/advanced/wing_reconstruction research_icon_state = "surgery_chest" +/datum/design/surgery/advanced_plastic_surgery + name = "Advanced Plastic Surgery" + desc = "An advanced form of the plastic surgery, allowing oneself to remodel someone's face and voice based off a picture of someones face" + surgery = /datum/surgery/plastic_surgery/advanced + id = "surgery_advanced_plastic_surgery" + research_icon_state = "surgery_head" + /datum/design/surgery/experimental_dissection name = "Experimental Dissection" desc = "An experimental surgical procedure that dissects bodies in exchange for research points at ancient R&D consoles." diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 2ec692f0575..3f64efe851e 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -2368,3 +2368,15 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) hidden = TRUE experimental = TRUE + +/datum/techweb_node/advanced_plastic_surgery + id = "plastic_surgery" + display_name = "Advanced Plastic Surgery" + description = "A Procedure long lost due to licensing problems now once again available." + prereq_ids = list("base") + design_ids = list( + "surgery_advanced_plastic_surgery" + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + hidden = TRUE + experimental = TRUE diff --git a/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm b/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm index abb764d0689..ece96fd41e0 100644 --- a/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm +++ b/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm @@ -223,7 +223,7 @@ /datum/reagent/consumable/corn_syrup = -6, /datum/reagent/sulfur = -3) //sulfur repels snakes according to professor google. - resulting_atoms = list(/mob/living/simple_animal/hostile/retaliate/snake = 1) + resulting_atoms = list(/mob/living/basic/snake = 1) /////////////////////////////////////////// diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index aba37b37a55..44c13e39c76 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -61,17 +61,61 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list( /obj/docking_port/mobile/supply/proc/check_blacklist(areaInstances) for(var/place in areaInstances) var/area/shuttle/shuttle_area = place - for(var/turf/shuttle_turf in shuttle_area) + for(var/turf/shuttle_turf in shuttle_area.get_contained_turfs()) for(var/atom/passenger in shuttle_turf.get_all_contents()) if((is_type_in_typecache(passenger, GLOB.blacklisted_cargo_types) || HAS_TRAIT(passenger, TRAIT_BANNED_FROM_CARGO_SHUTTLE)) && !istype(passenger, /obj/docking_port)) return FALSE return TRUE +/// Returns anything on the cargo blacklist found within areas_to_check back to the turf of the home docking port via Centcom branded supply pod. +/obj/docking_port/mobile/supply/proc/return_blacklisted_things_home(list/area/areas_to_check, obj/docking_port/stationary/home) + var/list/stuff_to_send_home = list() + for(var/area/shuttle_area as anything in areas_to_check) + for(var/turf/shuttle_turf in shuttle_area.get_contained_turfs()) + for(var/atom/passenger in shuttle_turf.get_all_contents()) + if((is_type_in_typecache(passenger, GLOB.blacklisted_cargo_types) || HAS_TRAIT(passenger, TRAIT_BANNED_FROM_CARGO_SHUTTLE)) && !istype(passenger, /obj/docking_port)) + stuff_to_send_home += passenger + + if(!length(stuff_to_send_home)) + return FALSE + + var/obj/structure/closet/supplypod/centcompod/et_go_home = new() + + for(var/atom/movable/et as anything in stuff_to_send_home) + et.forceMove(et_go_home) + + new /obj/effect/pod_landingzone(get_turf(home), et_go_home) + + return stuff_to_send_home + /obj/docking_port/mobile/supply/request(obj/docking_port/stationary/S) if(mode != SHUTTLE_IDLE) return 2 return ..() +/obj/docking_port/mobile/supply/check_dock(obj/docking_port/stationary/S, silent) + . = ..() + + if(!.) + return + + // If we're not trying to dock at Centcom, we don't care. + if(S.shuttle_id != "cargo_away") + return + + // Else we are docking at Centcom, check the blacklist to make sure no contraband was put onto the shuttle mid-transit. + // If there's anything contrabandy, send these items back to the origin docking port. + // This is a sort of catch-all Centcom exploit check. + var/list/stuff_sent_home = return_blacklisted_things_home(shuttle_areas, previous) + if(!length(stuff_sent_home)) + return + + for(var/atom/thing_sent_home as anything in stuff_sent_home) + investigate_log("Blacklisted item found on in-transit Cargo Shuttle: [thing_sent_home] ([thing_sent_home.type])", INVESTIGATE_CARGO) + + message_admins("Blacklisted item found on in-transit Cargo Shuttle. See cargo logs for more details.") + SSshuttle.centcom_message = "Contraband found on Cargo Shuttle. This has been returned via drop pod." + /obj/docking_port/mobile/supply/initiate_docking() if(getDockedId() == "cargo_away") // Buy when we leave home. buy() diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm index 966f618376d..f03cd4927f8 100644 --- a/code/modules/spells/spell.dm +++ b/code/modules/spells/spell.dm @@ -180,11 +180,6 @@ to_chat(owner, span_warning("Some form of antimagic is preventing you from casting [src]!")) return FALSE - if(!(spell_requirements & SPELL_CASTABLE_WHILE_PHASED) && HAS_TRAIT(owner, TRAIT_MAGICALLY_PHASED)) - if(feedback) - to_chat(owner, span_warning("[src] cannot be cast unless you are completely manifested in the material plane!")) - return FALSE - if(!try_invoke(owner, feedback = feedback)) return FALSE diff --git a/code/modules/spells/spell_types/jaunt/_jaunt.dm b/code/modules/spells/spell_types/jaunt/_jaunt.dm index 4a94f03c041..207a7ed8b5b 100644 --- a/code/modules/spells/spell_types/jaunt/_jaunt.dm +++ b/code/modules/spells/spell_types/jaunt/_jaunt.dm @@ -62,7 +62,7 @@ var/obj/effect/dummy/phased_mob/jaunt = new jaunt_type(loc_override || get_turf(jaunter), jaunter) RegisterSignal(jaunt, COMSIG_MOB_EJECTED_FROM_JAUNT, PROC_REF(on_jaunt_exited)) - spell_requirements |= SPELL_CASTABLE_WHILE_PHASED + check_flags &= ~AB_CHECK_PHASED jaunter.add_traits(list(TRAIT_MAGICALLY_PHASED, TRAIT_RUNECHAT_HIDDEN, TRAIT_WEATHER_IMMUNE), REF(src)) // Don't do the feedback until we have runechat hidden. // Otherwise the text will follow the jaunt holder, which reveals where our caster is travelling. @@ -106,7 +106,7 @@ */ /datum/action/cooldown/spell/jaunt/proc/on_jaunt_exited(obj/effect/dummy/phased_mob/jaunt, mob/living/unjaunter) SHOULD_CALL_PARENT(TRUE) - spell_requirements &= ~SPELL_CASTABLE_WHILE_PHASED + check_flags |= AB_CHECK_PHASED unjaunter.remove_traits(list(TRAIT_MAGICALLY_PHASED, TRAIT_RUNECHAT_HIDDEN, TRAIT_WEATHER_IMMUNE), REF(src)) // This needs to happen at the end, after all the traits and stuff is handled SEND_SIGNAL(unjaunter, COMSIG_MOB_AFTER_EXIT_JAUNT, src) diff --git a/code/modules/spells/spell_types/self/splattercasting_spell.dm b/code/modules/spells/spell_types/self/splattercasting_spell.dm index 1af0cacd2aa..184a2afab7c 100644 --- a/code/modules/spells/spell_types/self/splattercasting_spell.dm +++ b/code/modules/spells/spell_types/self/splattercasting_spell.dm @@ -29,6 +29,7 @@ merely a vessel for the arcane flow. Soon, all that is left is not pain, but hunger.")) cast_on.set_species(/datum/species/vampire) + cast_on.blood_volume = BLOOD_VOLUME_NORMAL ///for predictable blood total amounts when the spell is first cast. cast_on.AddComponent(/datum/component/splattercasting) diff --git a/code/modules/surgery/bodyparts/wounds.dm b/code/modules/surgery/bodyparts/wounds.dm index 1b50dbc8fd1..94c503614a2 100644 --- a/code/modules/surgery/bodyparts/wounds.dm +++ b/code/modules/surgery/bodyparts/wounds.dm @@ -85,7 +85,7 @@ // quick re-check to see if bare_wound_bonus applies, for the benefit of log_wound(), see about getting the check from check_woundings_mods() somehow if(ishuman(owner)) var/mob/living/carbon/human/human_wearer = owner - var/list/clothing = human_wearer.clothingonpart(src) + var/list/clothing = human_wearer.get_clothing_on_part(src) for(var/obj/item/clothing/clothes_check as anything in clothing) // unlike normal armor checks, we tabluate these piece-by-piece manually so we can also pass on appropriate damage the clothing's limbs if necessary if(clothes_check.get_armor_rating(WOUND)) @@ -242,7 +242,7 @@ if(owner && ishuman(owner)) var/mob/living/carbon/human/human_owner = owner - var/list/clothing = human_owner.clothingonpart(src) + var/list/clothing = human_owner.get_clothing_on_part(src) for(var/obj/item/clothing/clothes as anything in clothing) // unlike normal armor checks, we tabluate these piece-by-piece manually so we can also pass on appropriate damage the clothing's limbs if necessary armor_ablation += clothes.get_armor_rating(WOUND) diff --git a/code/modules/surgery/organs/_organ.dm b/code/modules/surgery/organs/_organ.dm index 04103648fda..632e4c8b511 100644 --- a/code/modules/surgery/organs/_organ.dm +++ b/code/modules/surgery/organs/_organ.dm @@ -57,6 +57,8 @@ var/list/organ_traits /// Status Effects that are given to the holder of the organ. var/list/organ_effects + /// String displayed when the organ has decayed. + var/failing_desc = "has decayed for too long, and has turned a sickly color. It probably won't work without repairs." // Players can look at prefs before atoms SS init, and without this // they would not be able to see external organs, such as moth wings. @@ -242,10 +244,7 @@ INITIALIZE_IMMEDIATE(/obj/item/organ) . += span_notice("It should be inserted in the [parse_zone(zone)].") if(organ_flags & ORGAN_FAILING) - if(IS_ROBOTIC_ORGAN(src)) - . += span_warning("[src] seems to be broken.") - return - . += span_warning("[src] has decayed for too long, and has turned a sickly color. It probably won't work without repairs.") + . += span_warning("[src] [failing_desc]") return if(damage > high_threshold) @@ -424,4 +423,4 @@ INITIALIZE_IMMEDIATE(/obj/item/organ) /// Tries to replace the existing organ on the passed mob with this one, with special handling for replacing a brain without ghosting target /obj/item/organ/proc/replace_into(mob/living/carbon/new_owner) - Insert(new_owner, special = TRUE, drop_if_replaced = FALSE) + return Insert(new_owner, special = TRUE, drop_if_replaced = FALSE) diff --git a/code/modules/surgery/organs/external/_external_organ.dm b/code/modules/surgery/organs/external/_external_organ.dm index 54eb937e0ae..fd1af3d5f93 100644 --- a/code/modules/surgery/organs/external/_external_organ.dm +++ b/code/modules/surgery/organs/external/_external_organ.dm @@ -82,14 +82,13 @@ return if(bodypart_overlay.imprint_on_next_insertion) //We only want this set *once* - - // SKYRAT EDIT - Customization - ORIGINAL: bodypart_overlay.set_appearance_from_name(receiver.dna.features[bodypart_overlay.feature_key]) - if(receiver.dna.features[bodypart_overlay.feature_key]) - bodypart_overlay.set_appearance_from_name(receiver.dna.features[bodypart_overlay.feature_key]) - + var/feature_name = receiver.dna.features[bodypart_overlay.feature_key] + if (isnull(feature_name)) + bodypart_overlay.set_appearance_from_dna(receiver.dna) // SKYRAT EDIT CHANGE - ORIGINAL: feature_name = receiver.dna.species.external_organs[type] + // SKYRAT EDIT CHANGE START - Puts the following line in an else block else - bodypart_overlay.set_appearance_from_dna(receiver.dna) - // SKYRAT EDIT END + bodypart_overlay.set_appearance_from_name(feature_name) + // SKYRAT EDIT CHANGE END bodypart_overlay.imprint_on_next_insertion = FALSE ownerlimb = limb diff --git a/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm b/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm index 0a7332c0dd8..f0578832969 100644 --- a/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm +++ b/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm @@ -4,6 +4,7 @@ desc = "A state-of-the-art implant that improves a baseline's functionality." visual = FALSE organ_flags = ORGAN_ROBOTIC + failing_desc = "seems to be broken." var/implant_color = "#FFFFFF" var/implant_overlay diff --git a/code/modules/surgery/organs/internal/ears/_ears.dm b/code/modules/surgery/organs/internal/ears/_ears.dm index 52f5d740520..b77efe90c2e 100644 --- a/code/modules/surgery/organs/internal/ears/_ears.dm +++ b/code/modules/surgery/organs/internal/ears/_ears.dm @@ -109,6 +109,7 @@ desc = "A basic cybernetic organ designed to mimic the operation of ears." damage_multiplier = 0.9 organ_flags = ORGAN_ROBOTIC + failing_desc = "seems to be broken." /obj/item/organ/internal/ears/cybernetic/upgraded name = "cybernetic ears" diff --git a/code/modules/surgery/organs/internal/eyes/_eyes.dm b/code/modules/surgery/organs/internal/eyes/_eyes.dm index f2365c3988e..aca812a6186 100644 --- a/code/modules/surgery/organs/internal/eyes/_eyes.dm +++ b/code/modules/surgery/organs/internal/eyes/_eyes.dm @@ -318,6 +318,7 @@ icon_state = "cybernetic_eyeballs" desc = "Your vision is augmented." organ_flags = ORGAN_ROBOTIC + failing_desc = "seems to be broken." /obj/item/organ/internal/eyes/robotic/emp_act(severity) . = ..() @@ -656,7 +657,7 @@ if(QDELETED(eye_owner) || !ishuman(eye_owner)) //Other carbon mobs don't have eye color. return - + if(!eye.on) eye_icon_state = initial(eye_icon_state) overlay_ignore_lighting = FALSE diff --git a/code/modules/surgery/organs/internal/heart/_heart.dm b/code/modules/surgery/organs/internal/heart/_heart.dm index ce4b948c653..e553f8f1307 100644 --- a/code/modules/surgery/organs/internal/heart/_heart.dm +++ b/code/modules/surgery/organs/internal/heart/_heart.dm @@ -203,6 +203,7 @@ base_icon_state = "heart-c" organ_flags = ORGAN_ROBOTIC maxHealth = STANDARD_ORGAN_THRESHOLD*0.75 //This also hits defib timer, so a bit higher than its less important counterparts + failing_desc = "seems to be broken." var/dose_available = FALSE var/rid = /datum/reagent/medicine/epinephrine diff --git a/code/modules/surgery/organs/internal/liver/_liver.dm b/code/modules/surgery/organs/internal/liver/_liver.dm index fe5ca01df4f..7baeb04b8b6 100644 --- a/code/modules/surgery/organs/internal/liver/_liver.dm +++ b/code/modules/surgery/organs/internal/liver/_liver.dm @@ -245,6 +245,7 @@ /obj/item/organ/internal/liver/cybernetic name = "basic cybernetic liver" desc = "A very basic device designed to mimic the functions of a human liver. Handles toxins slightly worse than an organic liver." + failing_desc = "seems to be broken." icon_state = "liver-c" organ_flags = ORGAN_ROBOTIC maxHealth = STANDARD_ORGAN_THRESHOLD*0.5 diff --git a/code/modules/surgery/organs/internal/lungs/_lungs.dm b/code/modules/surgery/organs/internal/lungs/_lungs.dm index 5e4e0648067..71dc305ac5f 100644 --- a/code/modules/surgery/organs/internal/lungs/_lungs.dm +++ b/code/modules/surgery/organs/internal/lungs/_lungs.dm @@ -837,6 +837,7 @@ /obj/item/organ/internal/lungs/cybernetic name = "basic cybernetic lungs" desc = "A basic cybernetic version of the lungs found in traditional humanoid entities." + failing_desc = "seems to be broken." icon_state = "lungs-c" organ_flags = ORGAN_ROBOTIC maxHealth = STANDARD_ORGAN_THRESHOLD * 0.5 diff --git a/code/modules/surgery/organs/internal/stomach/_stomach.dm b/code/modules/surgery/organs/internal/stomach/_stomach.dm index bebeaacf110..e7d22a3ece6 100644 --- a/code/modules/surgery/organs/internal/stomach/_stomach.dm +++ b/code/modules/surgery/organs/internal/stomach/_stomach.dm @@ -289,6 +289,7 @@ /obj/item/organ/internal/stomach/cybernetic name = "basic cybernetic stomach" desc = "A basic device designed to mimic the functions of a human stomach" + failing_desc = "seems to be broken." icon_state = "stomach-c" organ_flags = ORGAN_ROBOTIC maxHealth = STANDARD_ORGAN_THRESHOLD * 0.5 diff --git a/code/modules/surgery/organs/internal/stomach/stomach_ethereal.dm b/code/modules/surgery/organs/internal/stomach/stomach_ethereal.dm index 4d43b6a3a0a..4cc8ee404c1 100644 --- a/code/modules/surgery/organs/internal/stomach/stomach_ethereal.dm +++ b/code/modules/surgery/organs/internal/stomach/stomach_ethereal.dm @@ -92,7 +92,7 @@ playsound(carbon, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5) carbon.cut_overlay(overcharge) - tesla_zap(carbon, 2, crystal_charge*2.5, ZAP_OBJ_DAMAGE | ZAP_LOW_POWER_GEN | ZAP_ALLOW_DUPLICATES) + tesla_zap(carbon, 2, crystal_charge * 1e3, ZAP_OBJ_DAMAGE | ZAP_LOW_POWER_GEN | ZAP_ALLOW_DUPLICATES) adjust_charge(ETHEREAL_CHARGE_FULL - crystal_charge) carbon.visible_message(span_danger("[carbon] violently discharges energy!"), span_warning("You violently discharge energy!")) diff --git a/code/modules/surgery/organs/internal/tongue/_tongue.dm b/code/modules/surgery/organs/internal/tongue/_tongue.dm index e9c47a0f237..08ee3d20faf 100644 --- a/code/modules/surgery/organs/internal/tongue/_tongue.dm +++ b/code/modules/surgery/organs/internal/tongue/_tongue.dm @@ -190,7 +190,7 @@ languages_native = list(/datum/language/draconic, /datum/language/ashtongue) //SKYRAT EDIT: Ashtongue for Ashwalkers liked_foodtypes = GORE | MEAT | SEAFOOD | NUTS | BUGS disliked_foodtypes = GRAIN | DAIRY | CLOTH | GROSS - + voice_filter = @{"[0:a] asplit [out0][out2]; [out0] asetrate=%SAMPLE_RATE%*0.9,aresample=%SAMPLE_RATE%,atempo=1/0.9,aformat=channel_layouts=mono,volume=0.2 [p0]; [out2] asetrate=%SAMPLE_RATE%*1.1,aresample=%SAMPLE_RATE%,atempo=1/1.1,aformat=channel_layouts=mono,volume=0.2[p2]; [p0][0][p2] amix=inputs=3"} /obj/item/organ/internal/tongue/lizard/modify_speech(datum/source, list/speech_args) var/static/regex/lizard_hiss = new("s+", "g") var/static/regex/lizard_hiSS = new("S+", "g") @@ -499,7 +499,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list()) say_mod = "hisses" taste_sensitivity = 10 // LIZARDS ARE ALIENS CONFIRMED modifies_speech = TRUE // not really, they just hiss - + voice_filter = @{"[0:a] asplit [out0][out2]; [out0] asetrate=%SAMPLE_RATE%*0.8,aresample=%SAMPLE_RATE%,atempo=1/0.8,aformat=channel_layouts=mono [p0]; [out2] asetrate=%SAMPLE_RATE%*1.2,aresample=%SAMPLE_RATE%,atempo=1/1.2,aformat=channel_layouts=mono[p2]; [p0][0][p2] amix=inputs=3"} // Aliens can only speak alien and a few other languages. /obj/item/organ/internal/tongue/alien/get_possible_languages() return list( @@ -560,6 +560,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list()) /obj/item/organ/internal/tongue/robot name = "robotic voicebox" desc = "A voice synthesizer that can interface with organic lifeforms." + failing_desc = "seems to be broken." organ_flags = ORGAN_ROBOTIC icon_state = "tonguerobot" say_mod = "states" @@ -607,6 +608,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list()) toxic_foodtypes = NONE //no food is particularly toxic to ethereals attack_verb_continuous = list("shocks", "jolts", "zaps") attack_verb_simple = list("shock", "jolt", "zap") + voice_filter = @{"[0:a] asplit [out0][out2]; [out0] asetrate=%SAMPLE_RATE%*0.99,aresample=%SAMPLE_RATE%,volume=0.3 [p0]; [p0][out2] amix=inputs=2"} // Ethereal tongues can speak all default + voltaic /obj/item/organ/internal/tongue/ethereal/get_possible_languages() diff --git a/code/modules/surgery/plastic_surgery.dm b/code/modules/surgery/plastic_surgery.dm index 440d48d1c5e..424251143c3 100644 --- a/code/modules/surgery/plastic_surgery.dm +++ b/code/modules/surgery/plastic_surgery.dm @@ -1,3 +1,9 @@ +/// Disk containing info for doing advanced plastic surgery. Spawns in maint and available as a role-restricted item in traitor uplinks. +/obj/item/disk/surgery/advanced_plastic_surgery + name = "Advanced Plastic Surgery Disk" + desc = "The disk provides instructions on how to do an Advanced Plastic Surgery, this surgery allows one-self to completely remake someone's face with that of another. Provided they have a picture of them in their offhand when reshaping the face. With the surgery long becoming obsolete with the rise of genetics technology. This item became an antique to many collectors, With only the cheaper and easier basic form of plastic surgery remaining in use in most places." + surgeries = list(/datum/surgery/plastic_surgery/advanced) + /datum/surgery/plastic_surgery name = "Plastic surgery" surgery_flags = SURGERY_REQUIRE_RESTING | SURGERY_REQUIRE_LIMB | SURGERY_REQUIRES_REAL_LIMB | SURGERY_MORBID_CURIOSITY @@ -9,6 +15,41 @@ /datum/surgery_step/close, ) +/datum/surgery/plastic_surgery/advanced + name = "advanced plastic surgery" + steps = list( + /datum/surgery_step/incise, + /datum/surgery_step/retract_skin, + /datum/surgery_step/insert_plastic, + /datum/surgery_step/reshape_face, + /datum/surgery_step/close, + ) + +//Insert plastic step, It ain't called plastic surgery for nothing! :) +/datum/surgery_step/insert_plastic + name = "insert plastic (plastic)" + implements = list( + /obj/item/stack/sheet/plastic = 100, + /obj/item/stack/sheet/meat = 100) + time = 3.2 SECONDS + preop_sound = 'sound/effects/blobattack.ogg' + success_sound = 'sound/effects/attackblob.ogg' + failure_sound = 'sound/effects/blobattack.ogg' + +/datum/surgery_step/insert_plastic/preop(mob/user, mob/living/target, target_zone, obj/item/stack/tool, datum/surgery/surgery) + display_results( + user, + target, + span_notice("You begin to insert [tool] into the incision in [target]'s [parse_zone(target_zone)]..."), + span_notice("[user] begins to insert [tool] into the incision in [target]'s [parse_zone(target_zone)]."), + span_notice("[user] begins to insert [tool] into the incision in [target]'s [parse_zone(target_zone)]."), + ) + display_pain(target, "You feel something inserting just below the skin in your [parse_zone(target_zone)].") + +/datum/surgery_step/insert_plastic/success(mob/user, mob/living/target, target_zone, obj/item/stack/tool, datum/surgery/surgery, default_display_results) + . = ..() + tool.use(1) + //reshape_face /datum/surgery_step/reshape_face name = "reshape face (scalpel)" @@ -43,8 +84,15 @@ else var/list/names = list() if(!isabductor(user)) - for(var/i in 1 to 10) - names += target.dna.species.random_name(target.gender, TRUE) + var/obj/item/offhand = user.get_inactive_held_item() + if(istype(offhand, /obj/item/photo) && istype(surgery, /datum/surgery/plastic_surgery/advanced)) + var/obj/item/photo/disguises = offhand + for(var/namelist as anything in disguises.picture?.names_seen) + names += namelist + else + user.visible_message(span_warning("You have no picture to base the appearance on, reverting to random appearances.")) + for(var/i in 1 to 10) + names += target.dna.species.random_name(target.gender, TRUE) else for(var/_i in 1 to 9) names += "Subject [target.gender == MALE ? "i" : "o"]-[pick("a", "b", "c", "d", "e")]-[rand(10000, 99999)]" diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 49fbecc2271..c5f62883b5f 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -259,6 +259,12 @@ butcher_sound = 'sound/weapons/circsawhit.ogg', \ ) //saws are very accurate and fast at butchering + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/chainsaw) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) /obj/item/circular_saw/get_surgery_tool_overlay(tray_extended) return surgical_tray_overlay diff --git a/code/modules/unit_tests/greyscale_config.dm b/code/modules/unit_tests/greyscale_config.dm index 9c5106be5b0..d3d9ce9d4fd 100644 --- a/code/modules/unit_tests/greyscale_config.dm +++ b/code/modules/unit_tests/greyscale_config.dm @@ -38,4 +38,4 @@ continue var/number_of_colors = length(colors) - 1 if(config.expected_colors != number_of_colors) - TEST_FAIL("[thing] has the wrong amount of colors configured for [config.DebugName()]. Expected [config.expected_colors] but only found [number_of_colors].") + TEST_FAIL("[thing] has the wrong amount of colors configured for [config.DebugName()]. Expected [config.expected_colors] colors but found [number_of_colors].") diff --git a/code/modules/unit_tests/simple_animal_freeze.dm b/code/modules/unit_tests/simple_animal_freeze.dm index 8de11513eaa..3c97dfe2773 100644 --- a/code/modules/unit_tests/simple_animal_freeze.dm +++ b/code/modules/unit_tests/simple_animal_freeze.dm @@ -64,22 +64,10 @@ /mob/living/simple_animal/hostile/asteroid/gutlunch/grublunch, /mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck, /mob/living/simple_animal/hostile/asteroid/gutlunch/guthen, - /mob/living/simple_animal/hostile/asteroid/hivelord, - /mob/living/simple_animal/hostile/asteroid/hivelord/legion, - /mob/living/simple_animal/hostile/asteroid/hivelord/legion/advanced, - /mob/living/simple_animal/hostile/asteroid/hivelord/legion/dwarf, - /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow, - /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/portal, - /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril, - /mob/living/simple_animal/hostile/asteroid/hivelordbrood, - /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion, - /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/advanced, - /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/snow, /mob/living/simple_animal/hostile/asteroid/ice_demon, /mob/living/simple_animal/hostile/asteroid/polarbear, /mob/living/simple_animal/hostile/asteroid/polarbear/lesser, /mob/living/simple_animal/hostile/asteroid/wolf, - /mob/living/simple_animal/hostile/big_legion, /mob/living/simple_animal/hostile/blob, /mob/living/simple_animal/hostile/blob/blobbernaut, /mob/living/simple_animal/hostile/blob/blobbernaut/independent, @@ -181,7 +169,6 @@ /mob/living/simple_animal/hostile/retaliate/goose/vomit, /mob/living/simple_animal/hostile/retaliate/nanotrasenpeace, /mob/living/simple_animal/hostile/retaliate/nanotrasenpeace/ranged, - /mob/living/simple_animal/hostile/retaliate/snake, /mob/living/simple_animal/hostile/retaliate/trader, /mob/living/simple_animal/hostile/retaliate/trader/mrbones, /mob/living/simple_animal/hostile/skeleton, @@ -215,7 +202,6 @@ /mob/living/simple_animal/pet/gondola, /mob/living/simple_animal/pet/gondola/gondolapod, /mob/living/simple_animal/revenant, - /mob/living/simple_animal/robot_customer, /mob/living/simple_animal/shade, /mob/living/simple_animal/slime, /mob/living/simple_animal/slime/pet, diff --git a/code/modules/uplink/uplink_items/implant.dm b/code/modules/uplink/uplink_items/implant.dm index 34fc9eedb0f..87c9fd6c96c 100644 --- a/code/modules/uplink/uplink_items/implant.dm +++ b/code/modules/uplink/uplink_items/implant.dm @@ -9,11 +9,14 @@ /datum/uplink_item/implants/freedom name = "Freedom Implant" - desc = "An implant injected into the body and later activated at the user's will. It will attempt to free the \ - user from common restraints such as handcuffs." + desc = "Can be activated to release common restraints such as handcuffs, legcuffs, and even bolas tethered around the legs." item = /obj/item/storage/box/syndie_kit/imp_freedom cost = 5 +/datum/uplink_item/implants/freedom/New() + . = ..() + desc += " Implant has enough energy for [FREEDOM_IMPLANT_CHARGES] uses before it becomes inert and harmlessly self-destructs." + /datum/uplink_item/implants/radio name = "Internal Syndicate Radio Implant" desc = "An implant injected into the body, allowing the use of an internal Syndicate radio. \ diff --git a/code/modules/uplink/uplink_items/job.dm b/code/modules/uplink/uplink_items/job.dm index b971e07619c..e585b07bb5f 100644 --- a/code/modules/uplink/uplink_items/job.dm +++ b/code/modules/uplink/uplink_items/job.dm @@ -173,6 +173,16 @@ cost = 5 surplus = 50 +/datum/uplink_item/role_restricted/advanced_plastic_surgery + name = "Advanced Plastic Surgery Program" + desc = "A bootleg copy of an collector item, this disk contains the procedure to perform advanced plastic surgery, allowing you to model someone's face and voice based on a picture taken by a camera on your offhand. \ + All changes are superficial and does not change ones genetic makeup. \ + Insert into an Operating Console to enable the procedure." + item = /obj/item/disk/surgery/brainwashing + restricted_roles = list(JOB_MEDICAL_DOCTOR, JOB_CHIEF_MEDICAL_OFFICER, JOB_ROBOTICIST) + cost = 1 + surplus = 50 + /datum/uplink_item/role_restricted/springlock_module name = "Heavily Modified Springlock MODsuit Module" desc = "A module that spans the entire size of the MOD unit, sitting under the outer shell. \ diff --git a/code/modules/uplink/uplink_items/stealthy.dm b/code/modules/uplink/uplink_items/stealthy.dm index 54c9bbe9adc..491f8e8e99d 100644 --- a/code/modules/uplink/uplink_items/stealthy.dm +++ b/code/modules/uplink/uplink_items/stealthy.dm @@ -90,7 +90,16 @@ slur as if inebriated. It can produce an infinite number \ of bolts, but takes time to automatically recharge after each shot." item = /obj/item/gun/energy/recharge/ebow - progression_minimum = 30 MINUTES cost = 10 surplus = 50 purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) + +/datum/uplink_item/stealthy_weapons/contrabaton + name = "Contractor Baton" + desc = "A compact, specialised baton assigned to Syndicate contractors. Applies light electrical shocks to targets. \ + These shocks are capable of affecting the inner circuitry of most robots as well, applying a short stun. \ + Has the added benefit of affecting the vocal cords of your victim, causing them to slur as if inebriated." + item = /obj/item/melee/baton/telescopic/contractor_baton + cost = 12 + surplus = 50 + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) diff --git a/code/modules/vending/wardrobes.dm b/code/modules/vending/wardrobes.dm index da2c08e04c9..2a5360c1ed2 100644 --- a/code/modules/vending/wardrobes.dm +++ b/code/modules/vending/wardrobes.dm @@ -61,6 +61,7 @@ /obj/item/clothing/head/utility/surgerycap/green = 4, /obj/item/clothing/head/beret/medical/paramedic = 4, /obj/item/clothing/head/soft/paramedic = 4, + /obj/item/clothing/head/utility/head_mirror = 4, /obj/item/clothing/mask/bandana/striped/medical = 4, /obj/item/clothing/mask/surgical = 4, /obj/item/clothing/under/rank/medical/doctor = 4, diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm index 9d3a298812e..4258dc5a304 100644 --- a/code/modules/zombie/items.dm +++ b/code/modules/zombie/items.dm @@ -11,20 +11,24 @@ bare_wound_bonus = 15 sharpness = SHARP_EDGED -/obj/item/mutant_hand/zombie/afterattack(atom/target, mob/user, proximity_flag) +/obj/item/mutant_hand/zombie/afterattack(atom/target, mob/living/user, proximity_flag) . = ..() if(!proximity_flag) return else if(isliving(target)) if(ishuman(target)) - try_to_zombie_infect(target) + try_to_zombie_infect(target, user, user.zone_selected) else . |= AFTERATTACK_PROCESSED_ITEM check_feast(target, user) -/proc/try_to_zombie_infect(mob/living/carbon/human/target) +/proc/try_to_zombie_infect(mob/living/carbon/human/target, mob/living/user, def_zone = BODY_ZONE_CHEST) CHECK_DNA_AND_SPECIES(target) + // Can't zombify with no head + if(!target.get_bodypart(BODY_ZONE_HEAD)) + return + if(HAS_TRAIT(target, TRAIT_NO_ZOMBIFY)) // cannot infect any TRAIT_NO_ZOMBIFY human return @@ -33,11 +37,31 @@ if(HAS_TRAIT(target, TRAIT_VIRUS_RESISTANCE) && prob(75)) return + var/obj/item/bodypart/actual_limb = target.get_bodypart(def_zone) + + // What you hitting bro? + if(!actual_limb) + return + + var/limb_damage = actual_limb.get_damage() + var/limb_armor = max(0, target.getarmor(actual_limb, BIO) - 25) + + // This is a pretty jank way to do this, but in short: + // if they have thick material on that bodypart it will always need at least 25 previous limb damage to trigger an infection. + // and if their bio armor isn't thick it's a bit weaker. + for(var/obj/item/clothing/iter_clothing in target.get_clothing_on_part(actual_limb)) + if(iter_clothing.clothing_flags & THICKMATERIAL) + limb_armor += 25 + + if(limb_armor > limb_damage) + return + var/obj/item/organ/internal/zombie_infection/infection infection = target.get_organ_slot(ORGAN_SLOT_ZOMBIE) if(!infection) infection = new() infection.Insert(target) + to_chat(user, span_alien("You see [target] twitch for a moment as [target.p_their()] head is covered in \a [infection] - [target.p_Theyve()] been infected.")) /obj/item/mutant_hand/zombie/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] is ripping [user.p_their()] brains out! It looks like [user.p_theyre()] trying to commit suicide!")) diff --git a/icons/mob/clothing/head/pai_head.dmi b/icons/mob/clothing/head/pai_head.dmi index 0a04e7e8ab2..e5dd4965d8b 100644 Binary files a/icons/mob/clothing/head/pai_head.dmi and b/icons/mob/clothing/head/pai_head.dmi differ diff --git a/icons/mob/clothing/head/utility.dmi b/icons/mob/clothing/head/utility.dmi index 3f3a668181c..ada1b90c4b0 100644 Binary files a/icons/mob/clothing/head/utility.dmi and b/icons/mob/clothing/head/utility.dmi differ diff --git a/icons/mob/huds/hud.dmi b/icons/mob/huds/hud.dmi index ec9be118f57..9a602eeb806 100644 Binary files a/icons/mob/huds/hud.dmi and b/icons/mob/huds/hud.dmi differ diff --git a/icons/mob/silicon/pai.dmi b/icons/mob/silicon/pai.dmi index 624ed669519..2be986d411d 100644 Binary files a/icons/mob/silicon/pai.dmi and b/icons/mob/silicon/pai.dmi differ diff --git a/icons/mob/simple/lavaland/lavaland_monsters.dmi b/icons/mob/simple/lavaland/lavaland_monsters.dmi index 13c37dca594..38b78cf468f 100644 Binary files a/icons/mob/simple/lavaland/lavaland_monsters.dmi and b/icons/mob/simple/lavaland/lavaland_monsters.dmi differ diff --git a/icons/mob/telegraphing/telegraph.dmi b/icons/mob/telegraphing/telegraph.dmi index d5e03419cd8..de525ead4ee 100644 Binary files a/icons/mob/telegraphing/telegraph.dmi and b/icons/mob/telegraphing/telegraph.dmi differ diff --git a/icons/obj/clothing/head/utility.dmi b/icons/obj/clothing/head/utility.dmi index 9571b2add78..17040f5bb8b 100644 Binary files a/icons/obj/clothing/head/utility.dmi and b/icons/obj/clothing/head/utility.dmi differ diff --git a/icons/obj/exploration.dmi b/icons/obj/exploration.dmi index 2f9d004bee2..b7224d2df84 100644 Binary files a/icons/obj/exploration.dmi and b/icons/obj/exploration.dmi differ diff --git a/icons/obj/medical/organs/mining_organs.dmi b/icons/obj/medical/organs/mining_organs.dmi index f3fc298284b..172f94001ff 100644 Binary files a/icons/obj/medical/organs/mining_organs.dmi and b/icons/obj/medical/organs/mining_organs.dmi differ diff --git a/modular_skyrat/master_files/code/datums/traits/good.dm b/modular_skyrat/master_files/code/datums/traits/good.dm index 22987f7705d..08f265145a9 100644 --- a/modular_skyrat/master_files/code/datums/traits/good.dm +++ b/modular_skyrat/master_files/code/datums/traits/good.dm @@ -68,6 +68,16 @@ right_arm.unarmed_miss_sound = initial(right_arm.unarmed_miss_sound) right_arm.unarmed_sharpness = initial(right_arm.unarmed_sharpness) +/datum/quirk/water_breathing + name = "Water breathing" + desc = "You are able to breathe underwater!" + value = 2 + mob_trait = TRAIT_WATER_BREATHING + gain_text = span_notice("You become acutely aware of the moisture in your lungs and in the air. It feels nice.") + lose_text = span_danger("You suddenly realize the moisture in your lungs feels really weird, and you almost choke on it!") + medical_record_text = "Patient possesses biology compatible with aquatic respiration." + icon = FA_ICON_FISH + // AdditionalEmotes *turf quirks /datum/quirk/water_aspect name = "Water aspect (Emotes)" diff --git a/modular_skyrat/master_files/code/modules/mob/living/human/species.dm b/modular_skyrat/master_files/code/modules/mob/living/human/species.dm index b2b9eaeecba..30df82a7f11 100644 --- a/modular_skyrat/master_files/code/modules/mob/living/human/species.dm +++ b/modular_skyrat/master_files/code/modules/mob/living/human/species.dm @@ -32,3 +32,14 @@ /datum/species/proc/apply_supplementary_body_changes(mob/living/carbon/human/target, datum/preferences/preferences, visuals_only = FALSE) return + +/datum/species/create_pref_traits_perks() + . = ..() + + if (TRAIT_WATER_BREATHING in inherent_traits) + . += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = FA_ICON_FISH, + SPECIES_PERK_NAME = "Waterbreathing", + SPECIES_PERK_DESC = "[plural_form] can breathe in water, making pools a lot safer to be in!", + )) diff --git a/modular_skyrat/modules/alerts/code/default_announcer.dm b/modular_skyrat/modules/alerts/code/default_announcer.dm index 7ae320f01f8..86add70db58 100644 --- a/modular_skyrat/modules/alerts/code/default_announcer.dm +++ b/modular_skyrat/modules/alerts/code/default_announcer.dm @@ -43,7 +43,6 @@ ANNOUNCER_KLAXON = 'modular_skyrat/modules/black_mesa/sound/siren1_long.ogg', ANNOUNCER_ICARUS = 'modular_skyrat/modules/assault_operatives/sound/icarus_alarm.ogg', ANNOUNCER_NRI_RAIDERS = 'modular_skyrat/modules/encounters/sounds/morse.ogg', - ANNOUNCER_FUNGI = 'modular_skyrat/modules/alerts/sound/alerts/fungi.ogg', ANNOUNCER_DEPARTMENTAL = 'modular_skyrat/modules/alerts/sound/alerts/alert3.ogg', ANNOUNCER_SHUTTLE = 'modular_skyrat/modules/alerts/sound/alerts/alert3.ogg', ) diff --git a/modular_skyrat/modules/alerts/sound/alerts/fungi.ogg b/modular_skyrat/modules/alerts/sound/alerts/fungi.ogg deleted file mode 100644 index 7eb45de94a2..00000000000 Binary files a/modular_skyrat/modules/alerts/sound/alerts/fungi.ogg and /dev/null differ diff --git a/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm b/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm index e34a414cf8e..ba1dd931c3a 100644 --- a/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm +++ b/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm @@ -173,7 +173,7 @@ . = ..() var/mob_type = pick( /mob/living/basic/mining/goliath, - /mob/living/simple_animal/hostile/asteroid/hivelord/legion, + /mob/living/basic/mining/legion, /mob/living/basic/mining/brimdemon, /mob/living/basic/mining/watcher, /mob/living/basic/mining/lobstrosity/lava, @@ -373,5 +373,5 @@ find_animal.faction = list(FACTION_ASHWALKER) - find_animal.revive() + find_animal.revive(HEAL_ALL) return TRUE diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/deforest_medical.dm b/modular_skyrat/modules/company_imports/code/armament_datums/deforest_medical.dm index 3f9b9b73b28..40f8ef775f7 100644 --- a/modular_skyrat/modules/company_imports/code/armament_datums/deforest_medical.dm +++ b/modular_skyrat/modules/company_imports/code/armament_datums/deforest_medical.dm @@ -121,7 +121,7 @@ cost = PAYCHECK_COMMAND /datum/armament_entry/company_import/deforest/equipment/surgical_tools - item_type = /obj/item/storage/backpack/duffelbag/med/surgery + item_type = /obj/item/surgery_tray/full cost = PAYCHECK_COMMAND /datum/armament_entry/company_import/deforest/equipment/advanced_health_analyer diff --git a/modular_skyrat/modules/customization/game/objects/items/plushes.dm b/modular_skyrat/modules/customization/game/objects/items/plushes.dm index d718d409b49..1d2992cf8ef 100644 --- a/modular_skyrat/modules/customization/game/objects/items/plushes.dm +++ b/modular_skyrat/modules/customization/game/objects/items/plushes.dm @@ -467,7 +467,7 @@ gender = FEMALE attack_verb_continuous = list("pats", "hugs", "scolds", "pets") attack_verb_simple = list("pat", "hug", "scold", "pet") - squeak_override = list('sound/effects/mousesqueek.ogg' = 1, 'modular_skyrat/modules/emotes/sound/voice/mothsqueak.ogg' = 1,) + squeak_override = list('sound/creatures/mousesqueek.ogg' = 1, 'modular_skyrat/modules/emotes/sound/voice/mothsqueak.ogg' = 1,) responses = list("Rabbits are prey animals and are therefore constantly aware of their surroundings.", "Things to jump up on (they like to be in high places)", "become a rabbit today!", "Be cunning and full of tricks...", "Subscription confirmed! Thank you for choosing RABBITFACTS +TM+!", "Holland Lops are a breed of rabbit originating in the Netherlands.", "Rabbits may need medication to keep themselves healthy, and that's ok! Make sure to take yours too!", "rabbits really liked this product", "A healthy rabbit diet includes fresh vegetables.", "Rabbits do not hibernate. Their schedules are much too busy.", "the rate of bunnies is measured by RPB (rabbits per bunny)", ) /obj/item/toy/plush/skyrat/chunko/andrew @@ -477,7 +477,7 @@ gender = MALE attack_verb_continuous = list("pats", "hugs", "scolds", "pets") attack_verb_simple = list("pat", "hug", "scold", "pet") - squeak_override = list('sound/effects/mousesqueek.ogg' = 1, 'modular_skyrat/modules/emotes/sound/voice/mothsqueak.ogg' = 1,) + squeak_override = list('sound/creatures/mousesqueek.ogg' = 1, 'modular_skyrat/modules/emotes/sound/voice/mothsqueak.ogg' = 1,) // All lowercase messages are intentional responses = list("bunny who you best pray you never encounter, lest you suffer a fate worse than death.", "this is a bunny!", "I wonder what would happen if you took bunnies, and combined them with rabbits, and merged their properties and characteristics. It's something to think about.", "If you're cold, they're cold. Give them the deed to your house.", "bunny that goes yeah! woo! yeah! woo! yeah! woo! yeah! woo! yeah! woo! yeah!", "the bunnies are beyond my comprehension", "it's a bunny thing, you wouldn't get it", "this bunny has an unfathomable power level", "%pull the string and I'll bink at you...I'm your bunny.", "Bunny (1954)", "the bunny that pulls the strings....", ) diff --git a/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm b/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm index 64a6c5c1339..746380b59cb 100644 --- a/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm +++ b/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm @@ -936,7 +936,8 @@ /obj/item/clothing/glasses/welding/steampunk_goggles/attackby(obj/item/attacking_item, mob/living/user, params) if(!istype(attacking_item, /obj/item/clothing/glasses/welding)) - ..() + return ..() + if(welding_upgraded) to_chat(user, span_warning("\The [src] was already upgraded to have welding protection!")) return diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm index 3d0aaf94db5..76ebf34b682 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm @@ -149,7 +149,7 @@ GLOBAL_LIST_EMPTY(customizable_races) var/datum/sprite_accessory/undershirt/undershirt = GLOB.undershirt_list[species_human.undershirt] if(undershirt) var/mutable_appearance/undershirt_overlay - if(species_human.dna.species.sexes && species_human.gender == FEMALE) + if(species_human.dna.species.sexes && species_human.physique == FEMALE) undershirt_overlay = wear_female_version(undershirt.icon_state, undershirt.icon, BODY_LAYER) else undershirt_overlay = mutable_appearance(undershirt.icon, undershirt.icon_state, -BODY_LAYER) diff --git a/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/other_reagents.dm b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/other_reagents.dm index fabba52db0f..1c03bbf2ca3 100644 --- a/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/modular_skyrat/modules/customization/modules/reagents/chemistry/reagents/other_reagents.dm @@ -70,3 +70,30 @@ else to_chat(M, span_notice("[pick("I feel oddly calm.", "I feel relaxed.", "Mew?")]")) ..() + +#define DERMAGEN_SCAR_FIX_AMOUNT 10 + +/datum/reagent/medicine/dermagen + name = "Dermagen" + description = "Heals scars formed by past physical trauma when applied. Minimum 10u needed, only works when applied topically." + reagent_state = LIQUID + color = "#FFEBEB" + ph = 6 + chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + +/datum/reagent/medicine/dermagen/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE) + . = ..() + if(!iscarbon(exposed_mob)) + return + if(!(methods & (PATCH|TOUCH|VAPOR))) + return + var/mob/living/carbon/scarred = exposed_mob + if(scarred.stat == DEAD) + show_message = FALSE + if(show_message) + to_chat(scarred, span_danger("The scars on your body start to fade and disappear.")) + if(reac_volume >= DERMAGEN_SCAR_FIX_AMOUNT) + for(var/i in scarred.all_scars) + qdel(i) + +#undef DERMAGEN_SCAR_FIX_AMOUNT diff --git a/modular_skyrat/modules/customization/modules/reagents/chemistry/recipes/medicine.dm b/modular_skyrat/modules/customization/modules/reagents/chemistry/recipes/medicine.dm index afcfa2da8cd..34b97214bb8 100644 --- a/modular_skyrat/modules/customization/modules/reagents/chemistry/recipes/medicine.dm +++ b/modular_skyrat/modules/customization/modules/reagents/chemistry/recipes/medicine.dm @@ -24,3 +24,8 @@ results = list(/datum/reagent/medicine/taste_suppressor = 3, /datum/reagent/chlorine = 1) // The chlorine dissociated from the sodium to allow for the synthesis of the taste suppressor required_reagents = list(/datum/reagent/consumable/salt = 2, /datum/reagent/sulfur = 1, /datum/reagent/water = 1) required_temp = 300 + +/datum/chemical_reaction/medicine/dermagen + results = list(/datum/reagent/medicine/dermagen = 5) + required_reagents = list(/datum/reagent/consumable/ethanol = 4, /datum/reagent/medicine/c2/synthflesh = 3, /datum/reagent/medicine/mine_salve = 3) + mix_message = "The slurry congeals into a thick cream." diff --git a/modular_skyrat/modules/decay_subsystem/code/nests.dm b/modular_skyrat/modules/decay_subsystem/code/nests.dm index 3a8dad43888..74424371e87 100644 --- a/modular_skyrat/modules/decay_subsystem/code/nests.dm +++ b/modular_skyrat/modules/decay_subsystem/code/nests.dm @@ -200,7 +200,7 @@ desc = "These pulsating eggs are oozing out a puss like substance..." icon_state = "nest_eggs" light_color = LIGHT_COLOR_BRIGHT_YELLOW - monster_types = list(/mob/living/simple_animal/hostile/retaliate/snake) + monster_types = list(/mob/living/basic/snake) max_mobs = 8 spawn_cooldown = 5 SECONDS diff --git a/modular_skyrat/modules/emotes/code/emotes.dm b/modular_skyrat/modules/emotes/code/emotes.dm index 5f41b22751b..16c8ecbcef6 100644 --- a/modular_skyrat/modules/emotes/code/emotes.dm +++ b/modular_skyrat/modules/emotes/code/emotes.dm @@ -143,7 +143,7 @@ message = "squeaks!" emote_type = EMOTE_AUDIBLE vary = TRUE - sound = 'sound/effects/mousesqueek.ogg' + sound = 'sound/creatures/mousesqueek.ogg' /datum/emote/living/merp key = "merp" diff --git a/modular_skyrat/modules/faction/code/outfit.dm b/modular_skyrat/modules/faction/code/outfit.dm index 4728353e4ec..a808f58c05f 100644 --- a/modular_skyrat/modules/faction/code/outfit.dm +++ b/modular_skyrat/modules/faction/code/outfit.dm @@ -43,7 +43,7 @@ back = /obj/item/storage/backpack id = /obj/item/card/id/faction_crew l_pocket = /obj/item/melee/energy/sword - l_hand = /obj/item/storage/backpack/duffelbag/med/surgery + l_hand = /obj/item/surgery_tray/full backpack_contents = list(/obj/item/storage/box/survival/engineer=1, /obj/item/storage/medkit/tactical=1,/obj/item/storage/medkit/regular=1,/obj/item/storage/medkit/toxin=1, /obj/item/ammo_box/magazine/m45=2, /obj/item/gun/ballistic/automatic/pistol/m1911=1,/obj/item/healthanalyzer=1,/obj/item/stack/spacecash/c1000=1) /datum/outfit/faction_tech diff --git a/modular_skyrat/modules/fauna_reagent/fauna_reagent.dm b/modular_skyrat/modules/fauna_reagent/fauna_reagent.dm index cee0e7efab5..796dbef0daf 100644 --- a/modular_skyrat/modules/fauna_reagent/fauna_reagent.dm +++ b/modular_skyrat/modules/fauna_reagent/fauna_reagent.dm @@ -15,14 +15,57 @@ /mob/living/simple_animal/Life(seconds_per_tick, times_fired) . = ..() - if(reagent_health && reagents) - for(var/datum/reagent/reagents_within as anything in reagents.reagent_list) - if(istype(reagents_within, /datum/reagent/toxin)) - var/datum/reagent/toxin/toxin_reagent = reagents_within - var/toxin_damage = round(toxin_reagent.toxpwr) - adjustHealth(toxin_damage + 1) - reagents.remove_reagent(toxin_reagent.type, 0.5) - continue - if(istype(reagents_within, /datum/reagent/medicine)) - adjustHealth(-1) - reagents.remove_reagent(reagents_within.type, 0.5) + + if(!reagent_health) + return + + if(!reagents) + return + + if(stat == DEAD) + return + + for(var/datum/reagent/reagents_within as anything in reagents.reagent_list) + if(istype(reagents_within, /datum/reagent/toxin)) + var/datum/reagent/toxin/toxin_reagent = reagents_within + var/toxin_damage = round(toxin_reagent.toxpwr) + adjustHealth(toxin_damage + 1) + reagents.remove_reagent(toxin_reagent.type, 0.5) + continue + + if(istype(reagents_within, /datum/reagent/medicine)) + adjustHealth(-1) + reagents.remove_reagent(reagents_within.type, 0.5) + +/mob/living/basic + /// whether the simple animal can be healed/damaged through reagents + var/reagent_health = TRUE + +/mob/living/basic/Initialize(mapload) + . = ..() + if(reagent_health) + create_reagents(1000, REAGENT_HOLDER_ALIVE) + +/mob/living/basic/Life(seconds_per_tick, times_fired) + . = ..() + + if(!reagent_health) + return + + if(!reagents) + return + + if(stat == DEAD) + return + + for(var/datum/reagent/reagents_within as anything in reagents.reagent_list) + if(istype(reagents_within, /datum/reagent/toxin)) + var/datum/reagent/toxin/toxin_reagent = reagents_within + var/toxin_damage = round(toxin_reagent.toxpwr) + adjust_health(toxin_damage + 1) + reagents.remove_reagent(toxin_reagent.type, 0.5) + continue + + if(istype(reagents_within, /datum/reagent/medicine)) + adjust_health(-1) + reagents.remove_reagent(reagents_within.type, 0.5) diff --git a/modular_skyrat/modules/ices_events/code/ICES_event_config.dm b/modular_skyrat/modules/ices_events/code/ICES_event_config.dm index bd49fc1de17..c65aafe5da5 100644 --- a/modular_skyrat/modules/ices_events/code/ICES_event_config.dm +++ b/modular_skyrat/modules/ices_events/code/ICES_event_config.dm @@ -588,12 +588,6 @@ max_occurrences = 2 weight = VERY_HIGH_EVENT_FREQ -/** - * Wall Fungus - */ -/datum/round_event_control/wall_fungus - weight = MED_EVENT_FREQ - /** * Wisdom Cow * diff --git a/modular_skyrat/modules/mapping/code/lavaland_ruin_code.dm b/modular_skyrat/modules/mapping/code/lavaland_ruin_code.dm index c66faed0810..c2e667004c2 100644 --- a/modular_skyrat/modules/mapping/code/lavaland_ruin_code.dm +++ b/modular_skyrat/modules/mapping/code/lavaland_ruin_code.dm @@ -108,3 +108,15 @@ /obj/item/radio/headset/interdyne/comms keyslot = new /obj/item/encryptionkey/headset_syndicate/interdyne keyslot2 = new /obj/item/encryptionkey/syndicate + +//MOBS + +// hivelords that stand guard where they spawn +/mob/living/basic/mining/hivelord/no_wander + ai_controller = /datum/ai_controller/basic_controller/hivelord/no_wander + +//MOB AI + +// same as a regular hivelord minus the idle walking +/datum/ai_controller/basic_controller/hivelord/no_wander + idle_behavior = null diff --git a/modular_skyrat/modules/modular_implants/code/nif_persistence.dm b/modular_skyrat/modules/modular_implants/code/nif_persistence.dm index 1dc272c434e..fd24fd3b579 100644 --- a/modular_skyrat/modules/modular_implants/code/nif_persistence.dm +++ b/modular_skyrat/modules/modular_implants/code/nif_persistence.dm @@ -15,6 +15,8 @@ var/nif_is_calibrated /// How many rewards points does the NIF have stored on it? var/stored_rewards_points + /// A string containing programs that are transfered from one round to the next. + var/persistent_nifsofts /// Saves the NIF data for a individual user. /mob/living/carbon/human/proc/save_nif_data(datum/modular_persistence/persistence, remove_nif = FALSE) @@ -51,14 +53,19 @@ persistence.stored_rewards_points = installed_nif.rewards_points var/datum/component/nif_examine/examine_component = GetComponent(/datum/component/nif_examine) - persistence.nif_examine_text = examine_component?.nif_examine_text + + var/persistent_nifsoft_paths = "" // We need to convert all of the paths in the list into a single string for(var/datum/nifsoft/nifsoft as anything in installed_nif.loaded_nifsofts) - if(!nifsoft.persistence) + if(nifsoft.persistence) + nifsoft.save_persistence_data(persistence) + + if(!nifsoft.able_to_keep || !nifsoft.keep_installed) continue - nifsoft.save_persistence_data(persistence) + persistent_nifsoft_paths += "&[(nifsoft.type)]" + persistence.persistent_nifsofts = persistent_nifsoft_paths /// Loads the NIF data for an individual user. /mob/living/carbon/human/proc/load_nif_data(datum/modular_persistence/persistence) @@ -74,6 +81,16 @@ new_nif.current_theme = persistence.nif_theme new_nif.is_calibrated = persistence.nif_is_calibrated new_nif.rewards_points = persistence.stored_rewards_points + + var/list/persistent_nifsoft_paths = list() + for(var/text as anything in splittext(persistence.persistent_nifsofts, "&")) + var/datum/nifsoft/nifsoft_to_add = text2path(text) + if(!ispath(nifsoft_to_add, /datum/nifsoft) || !initial(nifsoft_to_add.able_to_keep)) + continue + + persistent_nifsoft_paths.Add(nifsoft_to_add) + + new_nif.persistent_nifsofts = persistent_nifsoft_paths.Copy() new_nif.Insert(src) var/datum/component/nif_examine/examine_component = GetComponent(/datum/component/nif_examine) diff --git a/modular_skyrat/modules/modular_implants/code/nifs.dm b/modular_skyrat/modules/modular_implants/code/nifs.dm index 69c0a581c35..9dd1af28751 100644 --- a/modular_skyrat/modules/modular_implants/code/nifs.dm +++ b/modular_skyrat/modules/modular_implants/code/nifs.dm @@ -92,6 +92,8 @@ var/list/loaded_nifsofts = list() ///What programs come already installed on the NIF? var/list/preinstalled_nifsofts = list(/datum/nifsoft/soul_poem) + ///What programs do we want to carry between rounds? + var/list/persistent_nifsofts = list() ///This shows up in the NIF settings screen as a way to ICly display lore. var/manufacturer_notes = "There is no data currently avalible for this product." @@ -147,8 +149,8 @@ linked_mob.AddComponent(/datum/component/nif_examine) RegisterSignal(linked_mob, COMSIG_LIVING_DEATH, PROC_REF(damage_on_death)) - if(preinstalled_nifsofts) - send_message("Loading preinstalled NIFSofts, please wait...") + if(preinstalled_nifsofts || persistent_nifsofts) + send_message("Loading preinstalled and stored NIFSofts, please wait...") addtimer(CALLBACK(src, PROC_REF(install_preinstalled_nifsofts)), 3 SECONDS) /obj/item/organ/internal/cyberimp/brain/nif/Remove(mob/living/carbon/organ_owner, special = FALSE) @@ -174,6 +176,10 @@ for(var/datum/nifsoft/preinstalled_nifsoft as anything in preinstalled_nifsofts) new preinstalled_nifsoft(src) + for(var/stored_nifsoft in persistent_nifsofts) + var/datum/nifsoft/new_stored_nifsoft = new stored_nifsoft(src) + new_stored_nifsoft.keep_installed = TRUE + return TRUE /obj/item/organ/internal/cyberimp/brain/nif/process(seconds_per_tick) diff --git a/modular_skyrat/modules/modular_implants/code/nifs_tgui.dm b/modular_skyrat/modules/modular_implants/code/nifs_tgui.dm index 0423e28c830..6da74c6b89f 100644 --- a/modular_skyrat/modules/modular_implants/code/nifs_tgui.dm +++ b/modular_skyrat/modules/modular_implants/code/nifs_tgui.dm @@ -45,6 +45,8 @@ "active_cost" = nifsoft.active_cost, "reference" = REF(nifsoft), "ui_icon" = nifsoft.ui_icon, + "able_to_keep" = nifsoft.able_to_keep, + "keep_installed" = nifsoft.keep_installed, ) data["loaded_nifsofts"] += list(nifsoft_data) @@ -126,3 +128,11 @@ return FALSE activated_nifsoft.activate() + + if("toggle_keeping_nifsoft") + var/datum/nifsoft/nifsoft_to_keep = locate(params["nifsoft_to_keep"]) in loaded_nifsofts + if(!nifsoft_to_keep || !nifsoft_to_keep.able_to_keep) + return FALSE + + nifsoft_to_keep.keep_installed = !nifsoft_to_keep.keep_installed + update_static_data_for_all_viewers() diff --git a/modular_skyrat/modules/modular_implants/code/nifsoft_catalog.dm b/modular_skyrat/modules/modular_implants/code/nifsoft_catalog.dm index aac352bab4c..6a3dde80e63 100644 --- a/modular_skyrat/modules/modular_implants/code/nifsoft_catalog.dm +++ b/modular_skyrat/modules/modular_implants/code/nifsoft_catalog.dm @@ -5,6 +5,7 @@ GLOBAL_LIST_INIT(purchasable_nifsofts, list( /datum/nifsoft/summoner/dorms, /datum/nifsoft/soul_poem, /datum/nifsoft/soulcatcher, + /datum/nifsoft/summoner/book, )) /datum/computer_file/program/nifsoft_downloader @@ -79,6 +80,7 @@ GLOBAL_LIST_INIT(purchasable_nifsofts, list( "category" = initial(buyable_nifsoft.buying_category), "ui_icon" = initial(buyable_nifsoft.ui_icon), "reference" = buyable_nifsoft, + "keepable" = initial(buyable_nifsoft.able_to_keep), ) var/category = nifsoft_details["category"] if(!(category in product_list)) diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts.dm b/modular_skyrat/modules/modular_implants/code/nifsofts.dm index d7c382cfddb..1bf551866f5 100644 --- a/modular_skyrat/modules/modular_implants/code/nifsofts.dm +++ b/modular_skyrat/modules/modular_implants/code/nifsofts.dm @@ -47,6 +47,10 @@ var/rewards_points_eligible = TRUE ///Does the NIFSoft have anything that is saved cross-round? var/persistence = FALSE + /// Is the NIFSoft something that we want to allow the user to keep? + var/able_to_keep = FALSE + /// Are we keeping the NIFSoft installed between rounds? This is decided by the user + var/keep_installed = FALSE ///Is it a lewd item? var/lewd_nifsoft = FALSE diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/book_summoner.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/book_summoner.dm new file mode 100644 index 00000000000..954a56e9ff9 --- /dev/null +++ b/modular_skyrat/modules/modular_implants/code/nifsofts/book_summoner.dm @@ -0,0 +1,36 @@ +/obj/item/disk/nifsoft_uploader/summoner/book + name = "Grimoire Akasha" + loaded_nifsoft = /datum/nifsoft/summoner/book + +/datum/nifsoft/summoner/book + name = "Grimoire Akasha" + program_desc = "Grimoire Akasha is a fork of the Grimoire Caeruleam NIFSoft that is designed around giving the user access to various educational hardlight books. \ + Due to its educational nature and miniscule size, Grimoire Akasha is typically provided for free at most NIFSoft marketplaces." + summonable_items = list() + purchase_price = 0 // This is a tool intended to help out newer players. + max_summoned_items = 2 + buying_category = NIFSOFT_CATEGORY_INFORMATION + ui_icon = "book" + +/datum/nifsoft/summoner/book/New() + . = ..() + summonable_items += subtypesof(/obj/item/book/manual/wiki) //That's right! all of the manual books! + +/datum/nifsoft/summoner/book/apply_custom_properties(obj/item/book/generated_book) + if(!istype(generated_book)) + return FALSE + + generated_book.cannot_carve = TRUE + return TRUE + +// Need this code here so that we don't have people carving out the summoned books +/obj/item/book + /// Is the parent book unable to be carved? TRUE prevents carving. By default this is unset + var/cannot_carve + +/obj/item/book/try_carve(obj/item/carving_item, mob/living/user, params) + if(cannot_carve) + balloon_alert(user, "unable to be carved!") + return FALSE + + return ..() diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/prop_summoner.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/prop_summoner.dm index 5cd8a0443cb..aab1cc52b7a 100644 --- a/modular_skyrat/modules/modular_implants/code/nifsofts/prop_summoner.dm +++ b/modular_skyrat/modules/modular_implants/code/nifsofts/prop_summoner.dm @@ -16,6 +16,7 @@ activation_cost = 100 // Around 1/10th the energy of a standard NIF buying_category = NIFSOFT_CATEGORY_FUN ui_icon = "book-open" + able_to_keep = TRUE // These NIFSofts are mostly for comsetic/fun reasons anyways. /// Does the resulting object have a holographic like filter appiled to it? var/holographic_filter = TRUE @@ -88,9 +89,17 @@ refund_activation_cost() return FALSE + apply_custom_properties(new_item) summoned_items += new_item new_item.AddComponent(/datum/component/summoned_item, holographic_filter) +/// This proc is called while an item is being summoned, use this to modifiy aspects of the item that aren't modified by the component. +/datum/nifsoft/summoner/proc/apply_custom_properties(obj/item/target_item) + if(!target_item) + return FALSE + + return TRUE + /datum/nifsoft/summoner/Destroy() QDEL_LIST(summoned_items) return ..() diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/soulcatcher.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/soulcatcher.dm index 9236a49f963..019ff546edc 100644 --- a/modular_skyrat/modules/modular_implants/code/nifsofts/soulcatcher.dm +++ b/modular_skyrat/modules/modular_implants/code/nifsofts/soulcatcher.dm @@ -7,6 +7,7 @@ program_desc = "The 'Soulcatcher' coreware is a near-complete upgrade of the nanomachine systems in a NIF, meant for one purpose; supposedly, channeling the dead. This upgrade, in truth, functions as a Resonance Simulation Device; an RSD for short, an instrument capable of hosting someone's consciousness, context or otherwise. 'Resonance', a term for the specific pattern of neural activity that gives way to someone's consciousness, was discovered in the early 2500s by researchers Yun-Seo Jin and Kamakshi Padmanabhan, coining what is now called 'Jin-Padmanabhan Resonance,' or 'JP/Soul Resonance.' This 'Resonance' gives off a sophont's consciousness, their sense of continuation, and their 'I am me.' This Resonance can vary in structure and 'strength' from person to person, and even change over someone's life. When the brain of a sophont undergoes death and stops neural activity, then Resonance dissipates entirely and lingering consciousness becomes essentially an echo, rapidly fading over time.\n\nThe earliest RSDs were massive machines, drawing incredible power and utilizing bleeding-edge, clunky software to 'play' someone's Resonance at 1:1 accuracy with their original brain. However, complications arose that are still being studied. Resonance is replicable and can be re-created artificially; however, like trying to duplicate genetic code, the capture needs to be extremely accurate, and rapidly put into place. Instruments such as RSDs are capable of picking up on lingering consciousness after the end of Resonance, and resuming it through artificial neural activity can give it strength to continue once more. RSDs such as Soulcatchers can only work at such a distance, otherwise running the risk of the Resonance essentially corrupting due to poor signal.\n\nIt is currently impossible to run Resonance in two places at once, because the same Resonance over two places experiences interference; like noise canceling headphones. Slimes and other gestalt consciousnesses can modulate their harmonics to a degree, bearing a partial disconnect and bringing themselves into constructive interference with similar harmonic signatures. A deepscan of the person's brain is necessary to give their consciousness 'context;' running their Resonance and capturing their consciousness alone results in a person with their same original intelligence, but zero memories or identity. These scans rapidly become outdated due to the growth of the brain, and it is prohibitively complex to store them in their entirety.\n\nThe first portable RSD, or Soulcatcher, was developed by the Spider Clan. These were initially designed for the captive interrogation of a person's consciousness without having to worry about the struggling of their body, and for dead or aging members of the mysterious group of orbital shinobi to be able to guide field operatives. These Soulcatchers are the main instrument to play Resonance, but recent advances in medical science have been leading to more. Occasionally, it is known for unusual sources of 'wild' Resonance, called Phantoms, to end up inside of the nearest Soulcatcher, a key finding its own lock; with a wide array of theories as to how these come into existence. Much as how some people intentionally become stable Engrams to achieve digital immortality, such as the witches of the Altspace Coven, it is possible for others to forcibly enter a Soulcatcher and act as a sort of Phantom by hacking their way in." purchase_price = 150 //RP tool persistence = TRUE + able_to_keep = TRUE ui_icon = "ghost" /// What is the linked soulcatcher datum used by this NIFSoft? diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/bdsm_mask.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/bdsm_mask.dm index 81cd35398b0..6a8f8a37c58 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/bdsm_mask.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/bdsm_mask.dm @@ -27,11 +27,14 @@ actions_types = list( /datum/action/item_action/toggle_breathcontrol, /datum/action/item_action/mask_inhale, + /datum/action/item_action/toggle_gag, ) var/list/moans = list("Mmmph...", "Hmmphh", "Mmmfhg", "Gmmmh...") // Phrases to be said when the player attempts to talk when speech modification / voicebox is enabled. var/list/moans_alt = list("Mhgm...", "Hmmmp!...", "Gmmmhp!") // Power probability phrases to be said when talking. var/moans_alt_probability = 5 // Probability for alternative sounds to play. var/temp_check = TRUE //Used to check if user unconsious to prevent choking him until he wakes up + /// Does the gasmask impede the user's ability to talk? + var/speech_disabled w_class = WEIGHT_CLASS_SMALL modifies_speech = TRUE flags_cover = MASKCOVERSMOUTH @@ -53,6 +56,9 @@ update_icon() /obj/item/clothing/mask/gas/bdsm_mask/handle_speech(datum/source, list/speech_args) + if(speech_disabled) + return + speech_args[SPEECH_MESSAGE] = pick((prob(moans_alt_probability) && LAZYLEN(moans_alt)) ? moans_alt : moans) play_lewd_sound(loc, pick('modular_skyrat/modules/modular_items/lewd_items/sounds/under_moan_f1.ogg', 'modular_skyrat/modules/modular_items/lewd_items/sounds/under_moan_f2.ogg', @@ -164,6 +170,15 @@ if(istype(mask)) mask.check() +/datum/action/item_action/toggle_gag + name = "Toggle gag" + desc = "Toggles whether or not the wearer is able to speak." + +/datum/action/item_action/toggle_gag/Trigger(trigger_flags) + var/obj/item/clothing/mask/gas/bdsm_mask/mask = target + if(istype(mask)) + mask.check_gag() + /datum/action/item_action/mask_inhale name = "Inhale oxygen" desc = "You must inhale oxygen!" @@ -236,6 +251,19 @@ else STOP_PROCESSING(SSobj, src) +/obj/item/clothing/mask/gas/bdsm_mask/proc/check_gag(user) + var/mob/living/carbon/affected_carbon = user + if(src == affected_carbon.wear_mask) + to_chat(user, span_notice("You can't reach the gag switch!")) + else + toggle_gag(affected_carbon) + +/obj/item/clothing/mask/gas/bdsm_mask/proc/toggle_gag(user) + speech_disabled = !speech_disabled + to_chat(user, span_notice("You [speech_disabled ? "disable" : "enable"] the gag on the mask.")) + update_mob_action_buttonss() + update_icon() + // Mask choke processor /obj/item/clothing/mask/gas/bdsm_mask/process(seconds_per_tick) var/mob/living/affected_mob = loc diff --git a/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm b/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm index 264d9f8bedc..6e724e44dbc 100644 --- a/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm +++ b/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm @@ -254,21 +254,37 @@ SUBSYSTEM_DEF(player_ranks) * or in the legacy system. * * Arguments: - * * admin - The admin making the rank change. + * * admin - The admin making the rank change. Can be a /client or a /datum/admins. * * ckey - The ckey of the player you want to now possess that player rank. * * rank_title - The title of the group you want to add the ckey to. */ -/datum/controller/subsystem/player_ranks/proc/add_player_to_group(client/admin, ckey, rank_title) +/datum/controller/subsystem/player_ranks/proc/add_player_to_group(admin, ckey, rank_title) if(IsAdminAdvancedProcCall()) return FALSE if(!ckey || !admin || !rank_title) + stack_trace("Missing either ckey ([ckey || "*NULL*"]), admin ([admin || "*NULL*"]) or rank_title ([rank_title || "*NULL*"]) in add_player_to_group()! Fix this ASAP!") return FALSE - if(!check_rights_for(admin, R_PERMISSIONS)) - to_chat(admin, span_warning("You do not possess the permissions to do this.")) + var/is_admin_client = istype(admin, /client) + var/client/admin_client = is_admin_client ? admin : null + // If it's not a client, then it should be an admins datum. + var/datum/admins/admin_holder = null + if(is_admin_client) + admin_holder = admin_client?.holder + else if(istype(admin, /datum/admins)) + admin_holder = admin + + if(!admin_holder) + return FALSE + + if(!admin_holder.check_for_rights(R_PERMISSIONS)) + if(is_admin_client) + to_chat(admin, span_warning("You do not possess the permissions to do this.")) + return FALSE + rank_title = lowertext(rank_title) var/datum/player_rank_controller/controller = get_controller_for_group(rank_title) @@ -282,14 +298,16 @@ SUBSYSTEM_DEF(player_ranks) var/already_in_config = controller.get_ckeys_for_legacy_save() if(already_in_config[ckey]) - to_chat(admin, span_warning("\"[ckey]\" is already a [rank_title]!")) + if(is_admin_client) + to_chat(admin, span_warning("\"[ckey]\" is already a [rank_title]!")) + return FALSE if(controller.should_use_legacy_system()) controller.add_player_legacy(ckey) return TRUE - return add_player_rank_sql(controller, ckey, admin.ckey) + return add_player_rank_sql(controller, ckey, admin_holder.target) /** @@ -325,19 +343,34 @@ SUBSYSTEM_DEF(player_ranks) * or in the legacy system. * * Arguments: - * * admin - The admin making the rank change. + * * admin - The admin making the rank change. Can be a /client or a /datum/admins. * * ckey - The ckey of the player you want to no longer possess that player rank. * * rank_title - The title of the group you want to remove the ckey from. */ -/datum/controller/subsystem/player_ranks/proc/remove_player_from_group(client/admin, ckey, rank_title) +/datum/controller/subsystem/player_ranks/proc/remove_player_from_group(admin, ckey, rank_title) if(IsAdminAdvancedProcCall()) return FALSE if(!ckey || !admin || !rank_title) + stack_trace("Missing either ckey ([ckey || "*NULL*"]), admin ([admin || "*NULL*"]) or rank_title ([rank_title || "*NULL*"]) in remove_player_from_group()! Fix this ASAP!") return FALSE - if(!check_rights_for(admin, R_PERMISSIONS)) - to_chat(admin, span_warning("You do not possess the permissions to do this.")) + var/is_admin_client = istype(admin, /client) + var/client/admin_client = is_admin_client ? admin : null + // If it's not a client, then it should be an admins datum. + var/datum/admins/admin_holder = null + if(is_admin_client) + admin_holder = admin_client?.holder + else if(istype(admin, /datum/admins)) + admin_holder = admin + + if(!admin_holder) + return FALSE + + if(!admin_holder.check_for_rights(R_PERMISSIONS)) + if(is_admin_client) + to_chat(admin, span_warning("You do not possess the permissions to do this.")) + return FALSE rank_title = lowertext(rank_title) @@ -345,22 +378,16 @@ SUBSYSTEM_DEF(player_ranks) var/datum/player_rank_controller/controller = get_controller_for_group(rank_title) if(!controller) - stack_trace("Invalid player rank \"[rank_title]\" supplied in add_player_to_group()!") + stack_trace("Invalid player rank \"[rank_title]\" supplied in remove_player_from_group()!") return FALSE ckey = ckey(ckey) - var/already_in_config = controller.get_ckeys_for_legacy_save() - - if(!already_in_config[ckey]) - to_chat(admin, span_warning("\"[ckey]\" is already not a [rank_title]!")) - return FALSE - if(controller.should_use_legacy_system()) controller.remove_player_legacy(ckey) return TRUE - return remove_player_rank_sql(controller, ckey, admin.ckey) + return remove_player_rank_sql(controller, ckey, admin_holder.target) /** diff --git a/modular_skyrat/modules/player_ranks/code/world_topic.dm b/modular_skyrat/modules/player_ranks/code/world_topic.dm new file mode 100644 index 00000000000..086373fd33f --- /dev/null +++ b/modular_skyrat/modules/player_ranks/code/world_topic.dm @@ -0,0 +1,67 @@ + +/datum/world_topic/set_player_rank + keyword = "set_player_rank" + require_comms_key = TRUE + +/datum/world_topic/set_player_rank/Run(list/input) + . = list() + + var/sender_discord_id = input["sender_discord_id"] + + if(!sender_discord_id) + .["success"] = FALSE + .["message"] = "Invalid sender Discord ID, this should not be happening! Report this immediately!" + return + + var/target_ckey = ckey(input["target_ckey"]) + + if(!target_ckey) + .["success"] = FALSE + .["message"] = "Invalid target ckey provided." + return + + var/sender_ckey = ckey(SSdiscord.lookup_ckey(sender_discord_id)) + + if(!sender_ckey) + .["success"] = FALSE + .["message"] = "No ckey was found to be attached to the provided Discord account ID, **[sender_discord_id]**. Please verify your Discord account following the instructions of the in-game verb before trying this command again." + return + + var/datum/admins/linked_admin_holder = GLOB.admin_datums[sender_ckey] || GLOB.deadmins[sender_ckey] + + if(!linked_admin_holder) + .["success"] = FALSE + .["message"] = "No valid admin datum was found associated with the ckey associated to your Discord account." + return + + if(!linked_admin_holder.check_for_rights(R_PERMISSIONS)) + .["success"] = FALSE + .["message"] = "You do not possess the permissions to execute this command." + return + + var/target_rank = input["target_rank"] + + if(!target_rank) + .["success"] = FALSE + .["message"] = "Invalid target rank provided." + return + + target_rank = capitalize(target_rank) + + var/desired_rank_status = !!text2num(input["desired_rank_status"]) + + if(desired_rank_status) + var/result = SSplayer_ranks.add_player_to_group(linked_admin_holder, target_ckey, target_rank) + + .["success"] = !!result + .["message"] = result ? "**[linked_admin_holder.target]** successfully added **[target_rank]** status to **[target_ckey]**." : "**[linked_admin_holder.target]** was unable to add **[target_rank]** status to **[target_ckey]**. Please verify that you entered their ckey correctly and that they did not already possess that status before trying again. Use the in-game verb to get more information if you keep on receiving this error." + message_admins(replacetext(.["message"], "*", "")) + return + + else + var/result = SSplayer_ranks.remove_player_from_group(linked_admin_holder, target_ckey, target_rank) + + .["success"] = !!result + .["message"] = result ? "**[linked_admin_holder.target]** successfully removed **[target_rank]** status from **[target_ckey]**." : "**[linked_admin_holder.target]** was unable to remove **[target_rank]** status from **[target_ckey]**. Please verify that you entered their ckey correctly and that they did possess that status before trying again. Use the in-game verb to get more information if you keep on receiving this error." + message_admins(replacetext(.["message"], "*", "")) + return diff --git a/modular_skyrat/modules/primitive_catgirls/code/spawner.dm b/modular_skyrat/modules/primitive_catgirls/code/spawner.dm index 8cb3f3234fe..5cbe1d682c0 100644 --- a/modular_skyrat/modules/primitive_catgirls/code/spawner.dm +++ b/modular_skyrat/modules/primitive_catgirls/code/spawner.dm @@ -66,8 +66,23 @@ /datum/team/primitive_catgirls name = "Icewalkers" + member_name = "Icewalker" show_roundend_report = FALSE +/datum/team/primitive_catgirls/roundend_report() + var/list/report = list() + + report += span_header("An Ice Walker Tribe inhabited the wastes...
") + if(length(members)) + report += "The [member_name]s were:" + report += printplayerlist(members) + else + report += "But none of its members woke up!" + + return "
[report.Join("
")]
" + +// Antagonist datum + /datum/antagonist/primitive_catgirl name = "\improper Icewalker" job_rank = ROLE_LAVALAND // If you're ashwalker banned you should also not be playing this, other way around as well diff --git a/modular_skyrat/modules/primitive_catgirls/code/species.dm b/modular_skyrat/modules/primitive_catgirls/code/species.dm index 7bcaec865dd..586c7b22900 100644 --- a/modular_skyrat/modules/primitive_catgirls/code/species.dm +++ b/modular_skyrat/modules/primitive_catgirls/code/species.dm @@ -21,6 +21,7 @@ mutanttongue = /obj/item/organ/internal/tongue/cat/primitive species_language_holder = /datum/language_holder/primitive_felinid + language_prefs_whitelist = list(/datum/language/primitive_catgirl) bodytemp_normal = 270 // If a normal human gets hugged by one its gonna feel cold bodytemp_heat_damage_limit = 283 // To them normal station atmos would be sweltering diff --git a/modular_skyrat/modules/wall_fungus/code/wall_fungus_component.dm b/modular_skyrat/modules/wall_fungus/code/wall_fungus_component.dm deleted file mode 100644 index 9c66677aaed..00000000000 --- a/modular_skyrat/modules/wall_fungus/code/wall_fungus_component.dm +++ /dev/null @@ -1,159 +0,0 @@ -#define FUNGUS_STAGE_ONE 1 -#define FUNGUS_STAGE_TWO 2 -#define FUNGUS_STAGE_THREE 3 -#define FUNGUS_STAGE_FOUR 4 -#define FUNGUS_STAGE_MAX 5 - -/** - * A wall eating mushroom. - * - * This mushroom spreads to walls and eats em up! It can be removed with a welder. If left unchecked it will eat the whole wall. - */ -/datum/component/wall_fungus - /// How far has the fungus progressed on the affected wall? Percentage. - var/progression_percent = 0 - /// How many percent do we increase each subsystem fire? - var/progression_step_amount = 0.5 - /// What stage are we at? - var/progression_stage = FUNGUS_STAGE_ONE - /// Our overlay icon file - var/overlay_icon_file = 'modular_skyrat/modules/wall_fungus/icons/wall_fungus_overlay.dmi' - /// How likely are we to spread to another wall? - var/spread_chance = 1 - /// How far can we spread? - var/spread_distance = 3 // Tiles - /// How likely are we to drop a shroom upon destruction? - var/drop_chance = 30 - -/datum/component/wall_fungus/Initialize(override_progression_step_amount, override_spread_chance, override_spread_distance, override_drop_chance) - if(!iswallturf(parent)) - return COMPONENT_INCOMPATIBLE - - // This stuff enables badminery. - if(override_progression_step_amount) - progression_step_amount = override_progression_step_amount - if(override_spread_chance) - spread_chance = override_progression_step_amount - if(override_spread_distance) - spread_distance = override_spread_distance - if(override_drop_chance) - drop_chance = override_drop_chance - - var/turf/closed/wall/parent_wall = parent - - RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(apply_fungus_overlay)) // We need to do this here so that the wall shows the infection immediately. - - parent_wall.update_icon(UPDATE_OVERLAYS) - - START_PROCESSING(SSobj, src) - -/datum/component/wall_fungus/RegisterWithParent() - RegisterSignal(parent, COMSIG_ATOM_SECONDARY_TOOL_ACT(TOOL_WELDER), PROC_REF(secondary_tool_act)) - RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(examine)) - RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(on_attack_hand)) - -/datum/component/wall_fungus/Destroy(force, silent) - var/turf/closed/wall/parent_wall = parent - STOP_PROCESSING(SSobj, src) - UnregisterSignal(parent, list(COMSIG_ATOM_SECONDARY_TOOL_ACT(TOOL_WELDER), COMSIG_ATOM_EXAMINE, COMSIG_ATOM_UPDATE_OVERLAYS)) - parent_wall.update_icon(UPDATE_OVERLAYS) - return ..() - -/datum/component/wall_fungus/process(seconds_per_tick) - var/turf/closed/wall/parent_wall = parent - if(prob(spread_chance * seconds_per_tick)) - spread_to_nearby_wall() - - if(progression_stage > FUNGUS_STAGE_MAX) - collapse_parent_structure() - return - - progression_percent += progression_step_amount * seconds_per_tick - - if(progression_percent >= 100) - progression_percent = 0 - progression_stage++ - spread_to_nearby_wall() - parent_wall.update_icon(UPDATE_OVERLAYS) - -/datum/component/wall_fungus/proc/on_attack_hand(datum/source, mob/living/user) - SIGNAL_HANDLER - - if(progression_stage < FUNGUS_STAGE_THREE) - return - - collapse_parent_structure() - - -/// We kill the wall once we have progressed far enough. -/datum/component/wall_fungus/proc/collapse_parent_structure() - var/turf/closed/wall/parent_wall = parent - STOP_PROCESSING(SSobj, src) - parent_wall.balloon_alert_to_viewers("collapses!") - parent_wall.dismantle_wall() - qdel(src) - -/datum/component/wall_fungus/proc/spread_to_nearby_wall() - var/turf/closed/wall/parent_wall = parent - var/list/walls_to_pick_from = list() - for(var/turf/closed/wall/iterating_wall in RANGE_TURFS(3, parent_wall)) - if(iterating_wall.GetComponent(/datum/component/wall_fungus)) - continue - - walls_to_pick_from += iterating_wall - - if(!length(walls_to_pick_from)) - return // sad times - - var/turf/closed/wall/picked_wall = pick(walls_to_pick_from) - - picked_wall.AddComponent(/datum/component/wall_fungus, progression_step_amount, spread_chance, spread_distance, drop_chance) - -/// Gives people an idea of how badly the wall is infected. -/datum/component/wall_fungus/proc/examine(datum/source, mob/user, list/examine_list) - SIGNAL_HANDLER - var/turf/closed/wall/parent_wall = parent - switch(progression_stage) - if(FUNGUS_STAGE_ONE) - examine_list += span_green("[parent_wall] is infected with some kind of fungus!") - if(FUNGUS_STAGE_TWO) - examine_list += span_green("[parent_wall] is infected with some kind of fungus, its structure weakened!") - if(FUNGUS_STAGE_THREE) - examine_list += span_green("[parent_wall] is infected with some kind of fungus, its structure seriously weakened!") - if(FUNGUS_STAGE_THREE) - examine_list += span_green("[parent_wall] is infected with some kind of fungus, its falling apart!") - examine_list += span_green("Perhaps you could burn it off?") - -/datum/component/wall_fungus/proc/apply_fungus_overlay(atom/parent_atom, list/overlays) - SIGNAL_HANDLER - overlays += mutable_appearance(overlay_icon_file, "fungus_stage_[progression_stage]") - -/datum/component/wall_fungus/proc/secondary_tool_act(atom/source, mob/user, obj/item/item) - SIGNAL_HANDLER - INVOKE_ASYNC(src, PROC_REF(handle_tool_use), source, user, item) - return COMPONENT_BLOCK_TOOL_ATTACK - -/// Handles removal of the fungus from a wall. -/datum/component/wall_fungus/proc/handle_tool_use(atom/source, mob/user, obj/item/item) - var/turf/closed/wall/parent_wall = parent - switch(item.tool_behaviour) - if(TOOL_WELDER) - if(!item.tool_start_check(user, 1)) - return - - user.balloon_alert(user, "burning off fungus...") - - if(!item.use_tool(source, user, (1 * progression_stage) SECONDS, 1, volume = 100)) - return - - user.balloon_alert(user, "burned off fungus") - if(prob(drop_chance)) - new /obj/item/food/grown/mushroom/wall(parent_wall) - qdel(src) - - -#undef FUNGUS_STAGE_ONE -#undef FUNGUS_STAGE_TWO -#undef FUNGUS_STAGE_THREE -#undef FUNGUS_STAGE_FOUR -#undef FUNGUS_STAGE_MAX diff --git a/modular_skyrat/modules/wall_fungus/code/wall_fungus_event.dm b/modular_skyrat/modules/wall_fungus/code/wall_fungus_event.dm deleted file mode 100644 index 564b9a9424e..00000000000 --- a/modular_skyrat/modules/wall_fungus/code/wall_fungus_event.dm +++ /dev/null @@ -1,29 +0,0 @@ -/datum/round_event_control/wall_fungus - name = "Wall Fungus Outbreak" - typepath = /datum/round_event/wall_fungus - category = EVENT_CATEGORY_ENGINEERING - max_occurrences = 2 - earliest_start = 30 MINUTES - description = "A wall fungus will infest a random wall on the station, eating away at it. If left unchecked, it will spread to other walls and eventually destroy the station." - -/datum/round_event/wall_fungus/announce(fake) - priority_announce("Harmful fungi detected on the station, station structures may be contaminated. Crew are advised to provide immediate response in [get_area(starting_wall)].", "Harmful Fungi", ANNOUNCER_FUNGI) - -/datum/round_event/wall_fungus - announce_when = 180 EVENT_SECONDS - announce_chance = 100 - fakeable = FALSE - var/turf/closed/wall/starting_wall - -/datum/round_event/wall_fungus/start() - var/list/possible_start_walls = list() - var/starting_area = get_area(pick(GLOB.generic_maintenance_landmarks)) - - for(var/turf/closed/wall/iterating_wall in starting_area) - possible_start_walls += iterating_wall - - starting_wall = pick(possible_start_walls) - - starting_wall.AddComponent(/datum/component/wall_fungus) - - notify_ghosts("[starting_wall] has been infested with wall eating mushrooms!!", source = starting_wall, action = NOTIFY_JUMP, header = "Fungus Amongus!") diff --git a/modular_skyrat/modules/wall_fungus/code/wall_mushroom.dm b/modular_skyrat/modules/wall_fungus/code/wall_mushroom.dm deleted file mode 100644 index 71d99c164c6..00000000000 --- a/modular_skyrat/modules/wall_fungus/code/wall_mushroom.dm +++ /dev/null @@ -1,53 +0,0 @@ -// WALL EATING FUNGUS!!!! -/obj/item/seeds/wall_mushroom - name = "pack of wall destroying mycelium" - desc = "This mycelium grows into something devastating." - icon = 'modular_skyrat/master_files/icons/obj/hydroponics/seeds.dmi' - icon_state = "seed-wallmushroom" - species = "angel" - plantname = "Wall Mushroom" - product = /obj/item/food/grown/mushroom/wall - lifespan = 50 - endurance = 35 - maturation = 12 - production = 5 - yield = 2 - potency = 35 - growthstages = 3 - genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism) - growing_icon = 'modular_skyrat/master_files/icons/obj/hydroponics/growing.dmi' - icon_grow = "wallmushroom-grow" - icon_dead = "wallmushroom-dead" - reagents_add = list(/datum/reagent/drug/mushroomhallucinogen = 0.04, /datum/reagent/toxin/amatoxin = 0.1, /datum/reagent/consumable/nutriment = 0.1) - rarity = 30 - graft_gene = /datum/plant_gene/trait/plant_type/fungal_metabolism - -/obj/item/food/grown/mushroom/wall - seed = /obj/item/seeds/wall_mushroom - name = "wall mushroom" - desc = "Wallosia Virosa: A wall eating mushroom!" - icon = 'modular_skyrat/master_files/icons/obj/hydroponics/harvest.dmi' - icon_state = "wallmushroom" - wine_power = 60 - - - -/obj/item/food/grown/mushroom/wall/afterattack(atom/target, mob/user, proximity_flag, click_parameters) - if(!iswallturf(target)) - return ..() - var/turf/closed/wall/target_wall = target - if(target_wall.GetComponent(/datum/component/wall_fungus)) - target_wall.balloon_alert(user, "already infested!") - return ..() - target_wall.balloon_alert(user, "planting...") - if(do_after(user, 5 SECONDS, target_wall)) - target_wall.AddComponent(/datum/component/wall_fungus) - target_wall.balloon_alert(user, "planted!") - user.log_message("planted [name] on [target_wall.name].", LOG_ATTACK) - qdel(src) - return - return ..() - - - - diff --git a/modular_skyrat/modules/wall_fungus/icons/wall_fungus_overlay.dmi b/modular_skyrat/modules/wall_fungus/icons/wall_fungus_overlay.dmi deleted file mode 100644 index 822d7ea9b29..00000000000 Binary files a/modular_skyrat/modules/wall_fungus/icons/wall_fungus_overlay.dmi and /dev/null differ diff --git a/sound/creatures/attribution.txt b/sound/creatures/attribution.txt index 1d2d543aa15..06d8361868c 100644 --- a/sound/creatures/attribution.txt +++ b/sound/creatures/attribution.txt @@ -1,8 +1,14 @@ -cow.ogg sound adapted from Benboncan on Freesound +cow.ogg sound adapted from Benboncan on Freesound https://freesound.org/people/Benboncan/sounds/58277/ pig1.ogg and pig2.ogg adapted from Jofae on Freesound https://freesound.org/people/Jofae/sounds/352698/ sheep1, sheep2, and sheep3.ogg adapted from milkotz on Freesound -https://freesound.org/people/milkotz/sounds/618865/ \ No newline at end of file +https://freesound.org/people/milkotz/sounds/618865/ + +snake_hissing1.ogg adapted from schreibsel on Freesound (CC 0) +https://freesound.org/people/schreibsel/sounds/540162/ + +snake_hissing2.ogg adapted from xoiziox on Freesound (CC 0) +https://freesound.org/people/xoiziox/sounds/553374/ diff --git a/sound/creatures/bagawk.ogg b/sound/creatures/bagawk.ogg new file mode 100644 index 00000000000..bfdce2da489 Binary files /dev/null and b/sound/creatures/bagawk.ogg differ diff --git a/sound/creatures/chick_peep.ogg b/sound/creatures/chick_peep.ogg new file mode 100644 index 00000000000..1e84d1d765f Binary files /dev/null and b/sound/creatures/chick_peep.ogg differ diff --git a/sound/creatures/chitter.ogg b/sound/creatures/chitter.ogg new file mode 100644 index 00000000000..5b2a1443886 Binary files /dev/null and b/sound/creatures/chitter.ogg differ diff --git a/sound/creatures/claw_click.ogg b/sound/creatures/claw_click.ogg new file mode 100644 index 00000000000..965b4c3fa9f Binary files /dev/null and b/sound/creatures/claw_click.ogg differ diff --git a/sound/creatures/clucks.ogg b/sound/creatures/clucks.ogg new file mode 100644 index 00000000000..176f46f866f Binary files /dev/null and b/sound/creatures/clucks.ogg differ diff --git a/sound/effects/mousesqueek.ogg b/sound/creatures/mousesqueek.ogg similarity index 100% rename from sound/effects/mousesqueek.ogg rename to sound/creatures/mousesqueek.ogg diff --git a/sound/creatures/pony/snort.ogg b/sound/creatures/pony/snort.ogg index b023ddcf47c..0ea56ad957d 100644 Binary files a/sound/creatures/pony/snort.ogg and b/sound/creatures/pony/snort.ogg differ diff --git a/sound/creatures/snake_hissing1.ogg b/sound/creatures/snake_hissing1.ogg new file mode 100644 index 00000000000..52a37d764c4 Binary files /dev/null and b/sound/creatures/snake_hissing1.ogg differ diff --git a/sound/creatures/snake_hissing2.ogg b/sound/creatures/snake_hissing2.ogg new file mode 100644 index 00000000000..bd11b7fb5f0 Binary files /dev/null and b/sound/creatures/snake_hissing2.ogg differ diff --git a/tgstation.dme b/tgstation.dme index 40f533b939f..865654f09b7 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -149,6 +149,7 @@ #include "code\__DEFINES\mod.dm" #include "code\__DEFINES\modular_computer.dm" #include "code\__DEFINES\monkeys.dm" +#include "code\__DEFINES\mood.dm" #include "code\__DEFINES\move_force.dm" #include "code\__DEFINES\movement.dm" #include "code\__DEFINES\movespeed_modification.dm" @@ -889,6 +890,7 @@ #include "code\datums\ai\bane\bane_controller.dm" #include "code\datums\ai\bane\bane_subtrees.dm" #include "code\datums\ai\basic_mobs\base_basic_controller.dm" +#include "code\datums\ai\basic_mobs\generic_controllers.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\basic_attacking.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\climb_tree.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\find_mineable_wall.dm" @@ -1054,6 +1056,7 @@ #include "code\datums\components\customizable_reagent_holder.dm" #include "code\datums\components\damage_aura.dm" #include "code\datums\components\deadchat_control.dm" +#include "code\datums\components\death_linked.dm" #include "code\datums\components\dejavu.dm" #include "code\datums\components\deployable.dm" #include "code\datums\components\drift.dm" @@ -1225,6 +1228,7 @@ #include "code\datums\components\crafting\misc.dm" #include "code\datums\components\crafting\ranged_weapon.dm" #include "code\datums\components\crafting\robot.dm" +#include "code\datums\components\crafting\slapcrafting.dm" #include "code\datums\components\crafting\structures.dm" #include "code\datums\components\crafting\tailoring.dm" #include "code\datums\components\crafting\tiles.dm" @@ -1364,7 +1368,6 @@ #include "code\datums\elements\death_drops.dm" #include "code\datums\elements\death_explosion.dm" #include "code\datums\elements\death_gases.dm" -#include "code\datums\elements\death_linked.dm" #include "code\datums\elements\delete_on_drop.dm" #include "code\datums\elements\deliver_first.dm" #include "code\datums\elements\diggable.dm" @@ -1733,6 +1736,7 @@ #include "code\datums\status_effects\debuffs\choke.dm" #include "code\datums\status_effects\debuffs\confusion.dm" #include "code\datums\status_effects\debuffs\cursed.dm" +#include "code\datums\status_effects\debuffs\cyborg.dm" #include "code\datums\status_effects\debuffs\debuffs.dm" #include "code\datums\status_effects\debuffs\decloning.dm" #include "code\datums\status_effects\debuffs\dizziness.dm" @@ -2259,6 +2263,7 @@ #include "code\game\objects\items\circuitboards\machines\engine_circuitboards.dm" #include "code\game\objects\items\circuitboards\machines\machine_circuitboards.dm" #include "code\game\objects\items\devices\aicard.dm" +#include "code\game\objects\items\devices\aicard_evil.dm" #include "code\game\objects\items\devices\anomaly_neutralizer.dm" #include "code\game\objects\items\devices\anomaly_releaser.dm" #include "code\game\objects\items\devices\beacon.dm" @@ -2761,6 +2766,7 @@ #include "code\modules\admin\verbs\fps.dm" #include "code\modules\admin\verbs\getlogs.dm" #include "code\modules\admin\verbs\ghost_pool_protection.dm" +#include "code\modules\admin\verbs\grant_dna_infusion.dm" #include "code\modules\admin\verbs\hiddenprints.dm" #include "code\modules\admin\verbs\highlander_datum.dm" #include "code\modules\admin\verbs\individual_logging.dm" @@ -3249,6 +3255,7 @@ #include "code\modules\atmospherics\machinery\components\unary_devices\bluespace_sender.dm" #include "code\modules\atmospherics\machinery\components\unary_devices\cryo.dm" #include "code\modules\atmospherics\machinery\components\unary_devices\heat_exchanger.dm" +#include "code\modules\atmospherics\machinery\components\unary_devices\machine_connector.dm" #include "code\modules\atmospherics\machinery\components\unary_devices\outlet_injector.dm" #include "code\modules\atmospherics\machinery\components\unary_devices\passive_vent.dm" #include "code\modules\atmospherics\machinery\components\unary_devices\portables_connector.dm" @@ -3457,6 +3464,7 @@ #include "code\modules\client\preferences\preferred_map.dm" #include "code\modules\client\preferences\pride_pin.dm" #include "code\modules\client\preferences\prisoner_crime.dm" +#include "code\modules\client\preferences\prosthetic.dm" #include "code\modules\client\preferences\random.dm" #include "code\modules\client\preferences\runechat.dm" #include "code\modules\client\preferences\scaling_method.dm" @@ -4409,6 +4417,14 @@ #include "code\modules\mob\living\basic\lavaland\goliath\goliath_ai.dm" #include "code\modules\mob\living\basic\lavaland\goliath\goliath_trophy.dm" #include "code\modules\mob\living\basic\lavaland\goliath\tentacle.dm" +#include "code\modules\mob\living\basic\lavaland\hivelord\hivelord.dm" +#include "code\modules\mob\living\basic\lavaland\hivelord\hivelord_ai.dm" +#include "code\modules\mob\living\basic\lavaland\hivelord\spawn_hivelord_brood.dm" +#include "code\modules\mob\living\basic\lavaland\legion\legion.dm" +#include "code\modules\mob\living\basic\lavaland\legion\legion_ai.dm" +#include "code\modules\mob\living\basic\lavaland\legion\legion_brood.dm" +#include "code\modules\mob\living\basic\lavaland\legion\legion_tumour.dm" +#include "code\modules\mob\living\basic\lavaland\legion\spawn_legions.dm" #include "code\modules\mob\living\basic\lavaland\lobstrosity\lobstrosity.dm" #include "code\modules\mob\living\basic\lavaland\lobstrosity\lobstrosity_ai.dm" #include "code\modules\mob\living\basic\lavaland\lobstrosity\lobstrosity_trophy.dm" @@ -4439,6 +4455,7 @@ #include "code\modules\mob\living\basic\space_fauna\lightgeist.dm" #include "code\modules\mob\living\basic\space_fauna\morph.dm" #include "code\modules\mob\living\basic\space_fauna\mushroom.dm" +#include "code\modules\mob\living\basic\space_fauna\robot_customer.dm" #include "code\modules\mob\living\basic\space_fauna\spaceman.dm" #include "code\modules\mob\living\basic\space_fauna\bear\_bear.dm" #include "code\modules\mob\living\basic\space_fauna\bear\bear_ai_behavior.dm" @@ -4474,6 +4491,8 @@ #include "code\modules\mob\living\basic\space_fauna\regal_rat\regal_rat.dm" #include "code\modules\mob\living\basic\space_fauna\regal_rat\regal_rat_actions.dm" #include "code\modules\mob\living\basic\space_fauna\regal_rat\regal_rat_ai.dm" +#include "code\modules\mob\living\basic\space_fauna\snake\snake.dm" +#include "code\modules\mob\living\basic\space_fauna\snake\snake_ai.dm" #include "code\modules\mob\living\basic\space_fauna\spider\spider.dm" #include "code\modules\mob\living\basic\space_fauna\spider\giant_spider\giant_spider_ai.dm" #include "code\modules\mob\living\basic\space_fauna\spider\giant_spider\giant_spider_subtrees.dm" @@ -4671,7 +4690,6 @@ #include "code\modules\mob\living\simple_animal\friendly\farm_animals.dm" #include "code\modules\mob\living\simple_animal\friendly\gondola.dm" #include "code\modules\mob\living\simple_animal\friendly\pet.dm" -#include "code\modules\mob\living\simple_animal\friendly\robot_customer.dm" #include "code\modules\mob\living\simple_animal\friendly\sloth.dm" #include "code\modules\mob\living\simple_animal\friendly\drone\_drone.dm" #include "code\modules\mob\living\simple_animal\friendly\drone\drone_say.dm" @@ -4737,7 +4755,6 @@ #include "code\modules\mob\living\simple_animal\hostile\megafauna\wendigo.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\curse_blob.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\gutlunch.dm" -#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\hivelord.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\ice_demon.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\mining_mobs.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\polarbear.dm" @@ -4749,7 +4766,6 @@ #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\elites\pandora.dm" #include "code\modules\mob\living\simple_animal\hostile\retaliate\goose.dm" #include "code\modules\mob\living\simple_animal\hostile\retaliate\retaliate.dm" -#include "code\modules\mob\living\simple_animal\hostile\retaliate\snake.dm" #include "code\modules\mob\living\simple_animal\hostile\retaliate\trader.dm" #include "code\modules\mob\living\simple_animal\slime\death.dm" #include "code\modules\mob\living\simple_animal\slime\emote.dm" @@ -4766,6 +4782,7 @@ #include "code\modules\mob_spawn\corpses\nonhuman_corpses.dm" #include "code\modules\mob_spawn\corpses\species_corpses.dm" #include "code\modules\mob_spawn\ghost_roles\away_roles.dm" +#include "code\modules\mob_spawn\ghost_roles\drone_roles.dm" #include "code\modules\mob_spawn\ghost_roles\fugitive_hunter_roles.dm" #include "code\modules\mob_spawn\ghost_roles\golem_roles.dm" #include "code\modules\mob_spawn\ghost_roles\mining_roles.dm" @@ -7087,6 +7104,7 @@ #include "modular_skyrat\modules\modular_implants\code\nifs_tgui.dm" #include "modular_skyrat\modules\modular_implants\code\nifsoft_catalog.dm" #include "modular_skyrat\modules\modular_implants\code\nifsofts.dm" +#include "modular_skyrat\modules\modular_implants\code\nifsofts\book_summoner.dm" #include "modular_skyrat\modules\modular_implants\code\nifsofts\dorms.dm" #include "modular_skyrat\modules\modular_implants\code\nifsofts\hivemind.dm" #include "modular_skyrat\modules\modular_implants\code\nifsofts\huds.dm" @@ -7366,6 +7384,7 @@ #include "modular_skyrat\modules\pixel_shift\code\pixel_shift_component.dm" #include "modular_skyrat\modules\pixel_shift\code\pixel_shift_keybind.dm" #include "modular_skyrat\modules\pixel_shift\code\pixel_shift_mob.dm" +#include "modular_skyrat\modules\player_ranks\code\world_topic.dm" #include "modular_skyrat\modules\player_ranks\code\player_rank_controller\_player_rank_controller.dm" #include "modular_skyrat\modules\player_ranks\code\player_rank_controller\donator_controller.dm" #include "modular_skyrat\modules\player_ranks\code\player_rank_controller\mentor_controller.dm" @@ -7572,9 +7591,6 @@ #include "modular_skyrat\modules\vox_sprites\code\head.dm" #include "modular_skyrat\modules\vox_sprites\code\security.dm" #include "modular_skyrat\modules\vox_sprites\code\sneakers.dm" -#include "modular_skyrat\modules\wall_fungus\code\wall_fungus_component.dm" -#include "modular_skyrat\modules\wall_fungus\code\wall_fungus_event.dm" -#include "modular_skyrat\modules\wall_fungus\code\wall_mushroom.dm" #include "modular_skyrat\modules\wargame_projectors\code\game_kit.dm" #include "modular_skyrat\modules\wargame_projectors\code\holograms.dm" #include "modular_skyrat\modules\wargame_projectors\code\projectors.dm" diff --git a/tgui/packages/tgui/interfaces/CrewConsole.js b/tgui/packages/tgui/interfaces/CrewConsole.js index 0c9a927c6f4..937ff9c1baf 100644 --- a/tgui/packages/tgui/interfaces/CrewConsole.js +++ b/tgui/packages/tgui/interfaces/CrewConsole.js @@ -1,18 +1,21 @@ import { sortBy } from 'common/collections'; import { useBackend } from '../backend'; -import { Box, Button, ColorBox, Section, Table } from '../components'; +import { Box, Button, Section, Table, Icon } from '../components'; import { COLORS } from '../constants'; import { Window } from '../layouts'; const HEALTH_COLOR_BY_LEVEL = [ '#17d568', - '#2ecc71', + '#c4cf2d', '#e67e22', '#ed5100', '#e74c3c', - '#ed2814', + '#801308', ]; +const STAT_LIVING = 0; +const STAT_DEAD = 4; + const jobIsHead = (jobId) => jobId % 10 === 0; const jobToColor = (jobId) => { @@ -40,10 +43,20 @@ const jobToColor = (jobId) => { return COLORS.department.other; }; -const healthToColor = (oxy, tox, burn, brute) => { +const statToIcon = (life_status) => { + switch (life_status) { + case STAT_LIVING: + return 'heart'; + case STAT_DEAD: + return 'skull'; + } + return 'heartbeat'; +}; + +const healthToAttribute = (oxy, tox, burn, brute, attributeList) => { const healthSum = oxy + tox + burn + brute; const level = Math.min(Math.max(Math.ceil(healthSum / 25), 0), 5); - return HEALTH_COLOR_BY_LEVEL[level]; + return attributeList[level]; }; const HealthStat = (props) => { @@ -78,9 +91,11 @@ const CrewTable = (props, context) => { Vitals - Position + + Position + {!!data.link_allowed && ( - + Tracking )} @@ -116,10 +131,22 @@ const CrewTableEntry = (props, context) => { {assignment !== undefined ? ` (${assignment})` : ''} - {life_status ? ( - + {oxydam !== undefined ? ( + + ) : life_status !== STAT_DEAD ? ( + ) : ( - + )} @@ -133,13 +160,19 @@ const CrewTableEntry = (props, context) => { {'/'} - ) : life_status ? ( + ) : life_status !== STAT_DEAD ? ( 'Alive' ) : ( 'Dead' )} - {area !== undefined ? area : 'N/A'} + + {area !== undefined ? ( + area + ) : ( + + )} + {!!link_allowed && (