From 8c724a2ea6c89b844b73da2367ca4490530229a2 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Tue, 26 Sep 2023 00:35:07 +0000 Subject: [PATCH 01/47] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-23787.yml | 4 -- html/changelogs/AutoChangeLog-pr-23887.yml | 11 ------ html/changelogs/AutoChangeLog-pr-23889.yml | 4 -- html/changelogs/AutoChangeLog-pr-23892.yml | 5 --- html/changelogs/AutoChangeLog-pr-23893.yml | 4 -- html/changelogs/AutoChangeLog-pr-23894.yml | 4 -- html/changelogs/AutoChangeLog-pr-23895.yml | 4 -- html/changelogs/AutoChangeLog-pr-23896.yml | 4 -- html/changelogs/AutoChangeLog-pr-23897.yml | 4 -- html/changelogs/AutoChangeLog-pr-23900.yml | 5 --- html/changelogs/AutoChangeLog-pr-23903.yml | 5 --- html/changelogs/AutoChangeLog-pr-23904.yml | 4 -- html/changelogs/AutoChangeLog-pr-23905.yml | 4 -- html/changelogs/AutoChangeLog-pr-23907.yml | 4 -- html/changelogs/AutoChangeLog-pr-23908.yml | 4 -- html/changelogs/AutoChangeLog-pr-23910.yml | 4 -- html/changelogs/AutoChangeLog-pr-23911.yml | 4 -- html/changelogs/archive/2023-09.yml | 46 ++++++++++++++++++++++ 18 files changed, 46 insertions(+), 78 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-23787.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23887.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23889.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23892.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23893.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23894.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23895.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23896.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23897.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23900.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23903.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23904.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23905.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23907.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23908.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23910.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23911.yml diff --git a/html/changelogs/AutoChangeLog-pr-23787.yml b/html/changelogs/AutoChangeLog-pr-23787.yml deleted file mode 100644 index e82c2d9ed56..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23787.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "sqnztb" -delete-after: True -changes: - - rscadd: "New medicine to clear up scars, made from synthflesh, ethanol, and miner's salve. Be sure to apply it via patches!" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23887.yml b/html/changelogs/AutoChangeLog-pr-23887.yml deleted file mode 100644 index ca2b73d59d5..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23887.yml +++ /dev/null @@ -1,11 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - qol: "NT CIMs shows how much power the supermatter is releasing." - - qol: "NT CIMs internal energy will adjust its prefix." - - qol: "Energy displays (such as multitooling grid) will use the full range of SI prefixes available, up to the peta prefix if you somehow managed to reach that." - - rscdel: "Removes the per cubic centimeter part of internal energy." - - bugfix: "Fix unnecessary delta time scaling on inactive supermatters." - - bugfix: "Fix high energy zaps not scaling with delta time." - - bugfix: "Fixes grounding rods lying about potential power you can generate." - - code_imp: "Convert supermatter_zap() and tesla_zap() zap_str argument unit to be in joules, and scales everything that uses that argument." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23889.yml b/html/changelogs/AutoChangeLog-pr-23889.yml deleted file mode 100644 index 8349772b109..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23889.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - admin: "First time user connections are now logged" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23892.yml b/html/changelogs/AutoChangeLog-pr-23892.yml deleted file mode 100644 index 9f953d1e0dc..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23892.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "LT3" -delete-after: True -changes: - - admin: "Successful restart votes will now restart on the current map" - - code_imp: "End round and persistence data will be saved before executing successful restart vote" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23893.yml b/html/changelogs/AutoChangeLog-pr-23893.yml deleted file mode 100644 index fa3c43a0ff7..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23893.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - image: "the security records suspected status is now teal instead of orange" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23894.yml b/html/changelogs/AutoChangeLog-pr-23894.yml deleted file mode 100644 index 6cd9fb8af03..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23894.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "Centcom now rejects contraband that somehow makes it way onto the cargo shuttle mid-transit and returns it." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23895.yml b/html/changelogs/AutoChangeLog-pr-23895.yml deleted file mode 100644 index 18d21bd4a4f..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23895.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Rhials" -delete-after: True -changes: - - bugfix: "\"Spooky\" meteors will now properly spawn during halloween." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23896.yml b/html/changelogs/AutoChangeLog-pr-23896.yml deleted file mode 100644 index 7fd773f39e1..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23896.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - image: "adds a frog holoform for pAIs" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23897.yml b/html/changelogs/AutoChangeLog-pr-23897.yml deleted file mode 100644 index 9b2249526b8..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23897.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "LT3" -delete-after: True -changes: - - spellcheck: "Improved wording in greyscale JSON error message" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23900.yml b/html/changelogs/AutoChangeLog-pr-23900.yml deleted file mode 100644 index 8f18d7f885a..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23900.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "Intellicards in computers are no longer deleted when the computer is destroyed." - - bugfix: "Modular consoles can now be deconstructed by right clicking with a wrench." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23903.yml b/html/changelogs/AutoChangeLog-pr-23903.yml deleted file mode 100644 index 1727ab4e93f..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23903.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - rscadd: "Adds an advanced plastic surgery procedure, allowing you to imitate people in pictures. Simply hold a picture in your offhand of the person you wish to imitate as while conducting the surgery! Remember, it's not foolproof, it only changes your name and voice!" - - rscadd: "You can obtain the disk containing the afromentioned surgery. as a role-restricted item to doctors and roboticists for 1TC, as a rare maint loot and BEPIS technode reward" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23904.yml b/html/changelogs/AutoChangeLog-pr-23904.yml deleted file mode 100644 index da793c3ebb6..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23904.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "Metalgen can no longer be used to transmute indestructible turfs." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23905.yml b/html/changelogs/AutoChangeLog-pr-23905.yml deleted file mode 100644 index 7ae72c0d082..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23905.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "posibrains can be inserted again" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23907.yml b/html/changelogs/AutoChangeLog-pr-23907.yml deleted file mode 100644 index 2bbe4c718ff..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23907.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "cigarettes no longer smoke themselves from inside your pockets or on your hands." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23908.yml b/html/changelogs/AutoChangeLog-pr-23908.yml deleted file mode 100644 index 4f0b4402b0e..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23908.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "you can no longer push watchers (and any other lavaland basic mob) around by running into them" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23910.yml b/html/changelogs/AutoChangeLog-pr-23910.yml deleted file mode 100644 index b40011ee2c2..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23910.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "The custom error message for when there is only one map to vote for should pop up in all cases rather than just a select few." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23911.yml b/html/changelogs/AutoChangeLog-pr-23911.yml deleted file mode 100644 index d387487e5b2..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23911.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "Stun immune people should no longer have issues with gripper gloves and other tackle gloves." \ No newline at end of file diff --git a/html/changelogs/archive/2023-09.yml b/html/changelogs/archive/2023-09.yml index e2e709c4b7c..08d6aff2784 100644 --- a/html/changelogs/archive/2023-09.yml +++ b/html/changelogs/archive/2023-09.yml @@ -1005,3 +1005,49 @@ instead of a random one. honkpocket: - rscdel: Removed wall-mushroom outbreak event +2023-09-26: + LT3: + - spellcheck: Improved wording in greyscale JSON error message + - admin: Successful restart votes will now restart on the current map + - code_imp: End round and persistence data will be saved before executing successful + restart vote + Rhials: + - bugfix: '"Spooky" meteors will now properly spawn during halloween.' + SkyratBot: + - image: the security records suspected status is now teal instead of orange + - bugfix: Intellicards in computers are no longer deleted when the computer is destroyed. + - bugfix: Modular consoles can now be deconstructed by right clicking with a wrench. + - bugfix: cigarettes no longer smoke themselves from inside your pockets or on your + hands. + - admin: First time user connections are now logged + - qol: NT CIMs shows how much power the supermatter is releasing. + - qol: NT CIMs internal energy will adjust its prefix. + - qol: Energy displays (such as multitooling grid) will use the full range of SI + prefixes available, up to the peta prefix if you somehow managed to reach that. + - rscdel: Removes the per cubic centimeter part of internal energy. + - bugfix: Fix unnecessary delta time scaling on inactive supermatters. + - bugfix: Fix high energy zaps not scaling with delta time. + - bugfix: Fixes grounding rods lying about potential power you can generate. + - code_imp: Convert supermatter_zap() and tesla_zap() zap_str argument unit to be + in joules, and scales everything that uses that argument. + - rscadd: Adds an advanced plastic surgery procedure, allowing you to imitate people + in pictures. Simply hold a picture in your offhand of the person you wish to + imitate as while conducting the surgery! Remember, it's not foolproof, it only + changes your name and voice! + - rscadd: You can obtain the disk containing the afromentioned surgery. as a role-restricted + item to doctors and roboticists for 1TC, as a rare maint loot and BEPIS technode + reward + - bugfix: Centcom now rejects contraband that somehow makes it way onto the cargo + shuttle mid-transit and returns it. + - bugfix: you can no longer push watchers (and any other lavaland basic mob) around + by running into them + - bugfix: posibrains can be inserted again + - bugfix: Metalgen can no longer be used to transmute indestructible turfs. + - image: adds a frog holoform for pAIs + - bugfix: The custom error message for when there is only one map to vote for should + pop up in all cases rather than just a select few. + - bugfix: Stun immune people should no longer have issues with gripper gloves and + other tackle gloves. + sqnztb: + - rscadd: New medicine to clear up scars, made from synthflesh, ethanol, and miner's + salve. Be sure to apply it via patches! From 997480df18fde60a22bd693b4356a4ea318409a6 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Tue, 26 Sep 2023 09:55:42 +0200 Subject: [PATCH 02/47] [MIRROR] basic mobs ranged attacks can check for friendly fire [MDB IGNORE] (#23918) * basic mobs ranged attacks can check for friendly fire (#78451) ## About The Pull Request basic mobs can check for friends in the way before firing a attack. if they find someone in the way they will try to adjust their position so their friends dont get hit by the projectiles ## Why It's Good For The Game nice optional feature people can put on the monsters they create ## Changelog :cl: add: added ranged attack friendly fire checks for basic mobs. minebots and hivebots will now try to avoid shooting their friends /:cl: * basic mobs ranged attacks can check for friendly fire --------- Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> --- .../basic_ai_behaviors/basic_attacking.dm | 55 +++++++++++++++++++ .../mob/living/basic/minebots/minebot_ai.dm | 1 + .../space_fauna/hivebot/hivebot_behavior.dm | 2 + .../space_fauna/hivebot/hivebot_subtree.dm | 2 +- 4 files changed, 59 insertions(+), 1 deletion(-) 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/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, ) From 960f164b2291922a1b84e5193e5bbf81e3cf2345 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Tue, 26 Sep 2023 09:56:08 +0200 Subject: [PATCH 03/47] Automatic changelog for PR #23918 [ci skip] --- html/changelogs/AutoChangeLog-pr-23918.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23918.yml diff --git a/html/changelogs/AutoChangeLog-pr-23918.yml b/html/changelogs/AutoChangeLog-pr-23918.yml new file mode 100644 index 00000000000..2529d2cfde0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23918.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - rscadd: "added ranged attack friendly fire checks for basic mobs. minebots and hivebots will now try to avoid shooting their friends" \ No newline at end of file From 96626708ab0a1d9dc955fdb3fbec3e56c842ede8 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Tue, 26 Sep 2023 09:57:18 +0200 Subject: [PATCH 04/47] [MIRROR] Adds tiny fan to Tramstation Mass Driver. [MDB IGNORE] (#23920) * Adds tiny fan to Tramstation Mass Driver. (#78484) ## About The Pull Request Adds tiny fan to mass driver, so you don't cause air alarms when you try to throw someone with it. ## Why It's Good For The Game Consistency. ## Changelog :cl: fix: [Tramstation] Mass Driver in chapel now has tiny fan so you don't space yourself. /:cl: * Adds tiny fan to Tramstation Mass Driver. --------- Co-authored-by: Helg2 <93882977+Helg2@users.noreply.github.com> --- _maps/map_files/tramstation/tramstation.dmm | 647 ++++++++++---------- 1 file changed, 324 insertions(+), 323 deletions(-) diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index 4ef52187a09..6fffe99a126 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, @@ -6735,6 +6716,11 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/security/interrogation) +"biE" = ( +/obj/effect/landmark/event_spawn, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/storage) "biS" = ( /obj/effect/turf_decal/trimline/neutral/filled/line{ dir = 6 @@ -10091,15 +10077,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) @@ -11140,6 +11117,20 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/commons/fitness/recreation) +"cLS" = ( +/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) "cMa" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/machinery/camera/directional/south{ @@ -11771,6 +11762,13 @@ /obj/machinery/digital_clock/directional/south, /turf/open/floor/iron/dark, /area/station/medical/break_room) +"cVx" = ( +/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) "cVz" = ( /obj/effect/landmark/start/hangover, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, @@ -13895,6 +13893,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/carpet, /area/station/service/library) +"dKz" = ( +/obj/machinery/door/poddoor/massdriver_chapel, +/obj/structure/fans/tiny, +/turf/open/floor/plating, +/area/station/service/chapel/monastery) "dKI" = ( /obj/effect/turf_decal/trimline/purple/filled/corner, /obj/machinery/atmospherics/pipe/smart/simple/cyan/visible, @@ -14143,6 +14146,15 @@ }, /turf/open/floor/iron/white, /area/station/science/research) +"dPi" = ( +/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) "dPo" = ( /obj/machinery/camera/directional/north{ c_tag = "Medical - Morgue"; @@ -15682,19 +15694,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 @@ -18003,10 +18002,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 +19671,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 +20229,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, @@ -20747,6 +20720,13 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"gqb" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/trimline/neutral/filled/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "gqc" = ( /obj/machinery/conveyor{ dir = 4; @@ -22345,11 +22325,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 +23909,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, @@ -26669,6 +26637,19 @@ /obj/machinery/light/floor, /turf/open/floor/engine/plasma, /area/station/engineering/atmos) +"iHo" = ( +/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) "iHr" = ( /obj/structure/sink{ dir = 4; @@ -27294,6 +27275,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) +"iTa" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/iron, +/area/station/cargo/storage) "iTm" = ( /obj/structure/table/glass, /obj/item/storage/pill_bottle/mannitol, @@ -28584,14 +28569,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 @@ -29081,27 +29058,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, @@ -29811,6 +29767,16 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/cargo/sorting) +"jJt" = ( +/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) "jJv" = ( /turf/open/floor/circuit, /area/station/ai_monitored/turret_protected/ai) @@ -30342,13 +30308,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 @@ -30901,6 +30860,15 @@ /obj/structure/cable, /turf/open/floor/wood, /area/station/command/heads_quarters/hop) +"kcd" = ( +/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) "kck" = ( /obj/effect/turf_decal/stripes/white/line{ dir = 1 @@ -34428,10 +34396,6 @@ }, /turf/open/floor/plating, /area/station/cargo/sorting) -"lnh" = ( -/obj/machinery/door/poddoor/massdriver_chapel, -/turf/open/floor/plating, -/area/station/service/chapel/monastery) "lnk" = ( /obj/effect/turf_decal/stripes/corner{ dir = 1 @@ -34943,20 +34907,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 +36252,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{ @@ -36637,6 +36569,13 @@ /obj/structure/cable, /turf/open/floor/wood/large, /area/station/service/library) +"lXx" = ( +/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) "lXC" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 1 @@ -36824,6 +36763,27 @@ /obj/item/clothing/glasses/meson, /turf/open/floor/iron/white, /area/station/medical/chemistry) +"mbp" = ( +/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) "mbt" = ( /obj/effect/turf_decal/trimline/neutral/filled/line{ dir = 4 @@ -37442,13 +37402,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 +37598,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, @@ -38022,6 +37966,10 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron, /area/station/hallway/secondary/command) +"mzv" = ( +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/storage) "mzD" = ( /obj/effect/turf_decal/siding/thinplating{ dir = 1 @@ -39024,20 +38972,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 +39543,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, @@ -40543,6 +40468,19 @@ }, /turf/open/space/openspace, /area/station/solars/port) +"nvn" = ( +/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) "nvo" = ( /obj/machinery/button/door/directional/west{ id = "private_b"; @@ -41838,6 +41776,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/secondary/command) +"nSY" = ( +/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) "nTa" = ( /obj/effect/landmark/start/station_engineer, /obj/structure/cable/layer1, @@ -41916,19 +41862,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 +42012,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 +43865,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 +45176,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{ @@ -47099,15 +47003,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 @@ -48277,6 +48172,19 @@ /obj/machinery/light/directional/south, /turf/open/floor/iron/dark, /area/station/hallway/secondary/exit/departure_lounge) +"qmC" = ( +/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) "qmH" = ( /obj/structure/closet/secure_closet/quartermaster, /obj/effect/turf_decal/trimline/brown/filled/line{ @@ -49225,6 +49133,19 @@ "qEH" = ( /turf/closed/wall, /area/station/solars/port) +"qEJ" = ( +/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) "qFf" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 8 @@ -50307,6 +50228,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) +"qZl" = ( +/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) "qZq" = ( /obj/structure/lattice/catwalk, /obj/structure/cable, @@ -50575,6 +50504,13 @@ /obj/machinery/airalarm/directional/north, /turf/open/floor/carpet, /area/station/medical/psychology) +"rcF" = ( +/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) "rcG" = ( /obj/machinery/camera/emp_proof/directional/east{ c_tag = "Secure - Telecomms Server Room East" @@ -50696,6 +50632,17 @@ /obj/effect/mapping_helpers/airlock/access/all/command/ai_upload, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai_upload) +"reN" = ( +/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) "reU" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/camera/directional/south{ @@ -51643,15 +51590,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{ @@ -54004,6 +53942,24 @@ /obj/structure/sign/calendar/directional/north, /turf/open/floor/carpet, /area/station/command/heads_quarters/hop) +"srh" = ( +/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) "srx" = ( /obj/structure/railing{ dir = 4 @@ -57051,10 +57007,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, @@ -59229,6 +59181,23 @@ "ufO" = ( /turf/open/floor/iron, /area/station/commons/fitness/recreation) +"ufX" = ( +/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) "ugf" = ( /obj/structure/bed{ dir = 8 @@ -60101,23 +60070,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 @@ -61622,6 +61574,15 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/tram/center) +"uQV" = ( +/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) "uRi" = ( /obj/machinery/suit_storage_unit/standard_unit, /obj/structure/window/reinforced/spawner/directional/south, @@ -61641,16 +61602,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, @@ -62815,6 +62766,15 @@ }, /turf/open/floor/iron/white, /area/station/science/lobby) +"vnA" = ( +/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) "vnD" = ( /obj/structure/reagent_dispensers/fueltank/large, /obj/effect/turf_decal/bot{ @@ -64029,6 +63989,15 @@ }, /turf/open/floor/iron, /area/station/commons/dorms) +"vHR" = ( +/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) "vIa" = ( /obj/machinery/vending/cigarette, /obj/effect/turf_decal/trimline/yellow/filled/line{ @@ -66953,6 +66922,20 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) +"wNu" = ( +/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) "wNK" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/violet/visible, /turf/open/floor/iron, @@ -67419,6 +67402,15 @@ /obj/effect/spawner/random/decoration/ornament, /turf/open/floor/carpet, /area/station/commons/vacant_room/office) +"wZK" = ( +/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) "wZL" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 6 @@ -68241,6 +68233,12 @@ }, /turf/open/floor/iron/dark, /area/station/security/interrogation) +"xrz" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "xrE" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/siding/thinplating{ @@ -68862,17 +68860,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 @@ -69011,6 +68998,20 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/station/command/meeting_room) +"xIE" = ( +/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) "xIL" = ( /obj/structure/cable, /turf/open/floor/iron, @@ -86187,7 +86188,7 @@ jWs lDo ucA wox -lvz +xIE gTv jWs aaa @@ -92394,7 +92395,7 @@ ncF ncF dFS tuU -uSl +jJt elr elr elr @@ -99829,7 +99830,7 @@ uTz hJM nAa ekB -mUc +cLS jSV uuD qjU @@ -104473,7 +104474,7 @@ qjU aaa qjU fok -uud +ufX sNq ceb pcx @@ -113437,7 +113438,7 @@ aaa aaa uGW jdU -jwP +mbp rff uGW aaa @@ -113735,7 +113736,7 @@ abM abM abM iix -giW +wNu boW iix abM @@ -116329,7 +116330,7 @@ hDT keT iEF fof -csn +vnA sXX akC hFP @@ -120936,7 +120937,7 @@ kkK jXE lwF dfz -fWK +qZl qCP urA ygC @@ -154624,7 +154625,7 @@ aRy aRE aRI aRL -lnh +dKz pMW pMW pMW @@ -179481,9 +179482,9 @@ aaa aaa aaa cTU -euR -jnL -abN +qEJ +nSY +iHo cTU cTU ohS @@ -179738,9 +179739,9 @@ aaa aaa aaa cTU -plH -jTQ -nfZ +qmC +rcF +wZK cTU exr pZA @@ -179995,9 +179996,9 @@ aac aaa aaa cTU -nUF -jTQ -mrg +nvn +rcF +uQV cTU lan pZA @@ -180253,7 +180254,7 @@ aaa cTU cTU ohS -xDW +reN ohS cTU nnb @@ -180510,10 +180511,10 @@ aaa cTU blx tAJ -lTM -axF -axF -rwo +srh +xrz +xrz +vHR dij uax uax @@ -180772,8 +180773,8 @@ uax uax uax uax -gUL -foU +biE +mzv dzw msn qza @@ -181028,9 +181029,9 @@ uax uax uax uax -tte -nXk -hDU +iTa +cVx +lXx dzw sxR skb @@ -181611,7 +181612,7 @@ eJQ bNx aSt aSt -oKn +dPi aaa aaa aaa @@ -183339,7 +183340,7 @@ cTU cTU cTU udQ -mmX +gqb pxD ayd ayt @@ -183853,7 +183854,7 @@ aaa aaa aaa udQ -pOL +kcd kXr aye rgg From 57b456f573b3e49ada073d6490f92247f1360b04 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Tue, 26 Sep 2023 09:57:44 +0200 Subject: [PATCH 05/47] Automatic changelog for PR #23920 [ci skip] --- html/changelogs/AutoChangeLog-pr-23920.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23920.yml diff --git a/html/changelogs/AutoChangeLog-pr-23920.yml b/html/changelogs/AutoChangeLog-pr-23920.yml new file mode 100644 index 00000000000..7da7c6d1af8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23920.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "[Tramstation] Mass Driver in chapel now has tiny fan so you don't space yourself." \ No newline at end of file From 91a71ea2b88ffe77242865fb52aa8d0e0033a2d2 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Tue, 26 Sep 2023 21:48:20 +0200 Subject: [PATCH 06/47] [MIRROR] Adds a candle box crate [MDB IGNORE] (#23933) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adds a candle box crate (#78593) ## About The Pull Request Adds a candle box crate that you can order. 🕯️ ## Why It's Good For The Game The chaplain only starts with a few boxes with a RNG way (scouring maintenance) to acquire any more ## Changelog :cl: add: Added a candle box crate for all your candle needs! /:cl: * Adds a candle box crate --------- Co-authored-by: admeeer --- code/modules/cargo/packs/general.dm | 7 +++++++ 1 file changed, 7 insertions(+) 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" From 724b378633adf3d9c223e9e54f18e1ac37ac491e Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Tue, 26 Sep 2023 21:48:49 +0200 Subject: [PATCH 07/47] Automatic changelog for PR #23933 [ci skip] --- html/changelogs/AutoChangeLog-pr-23933.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23933.yml diff --git a/html/changelogs/AutoChangeLog-pr-23933.yml b/html/changelogs/AutoChangeLog-pr-23933.yml new file mode 100644 index 00000000000..2fef349c7d1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23933.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - rscadd: "Added a candle box crate for all your candle needs!" \ No newline at end of file From 8dcae18a5a5469611d90e0b43dd8295fcbdf0c82 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Tue, 26 Sep 2023 21:49:21 +0200 Subject: [PATCH 08/47] [MIRROR] Refsearch Info Injection [MDB IGNORE] (#23934) * Refsearch Info Injection (#78574) ## About The Pull Request Adds a proc that types can override to inject extra information into the refsearch This'll allow us to more easily track and deal with refs held by general datums, like callbacks. I've implemented a template example FOR callbacks, to provide an example and assist in solving future issues Done to help lumipharon from TGMC, they were having trouble with this case. This isn't perfectly optimized, but this proc has a LOT of issues just in general. Need to rework it to cut down on string churn someday * Refsearch Info Injection --------- Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> --- .../admin/view_variables/reference_tracking.dm | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) 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"])" From ab501a28926cde499e4acb2292ce20f17fe46c46 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Tue, 26 Sep 2023 22:57:59 +0200 Subject: [PATCH 09/47] [MIRROR] Move felinid brain shrinkage from the species to the brain [MDB IGNORE] (#23932) * Move felinid brain shrinkage from the species to the brain (#78592) ## About The Pull Request Brain size is now a var on brains, and felinids have their own brains. This makes the feature implemented here: #77879 more modular and in line with our species goals. ## Why It's Good For The Game I didn't spend all that time moving species specific traits to bodyparts and organs for this bullshit. ## Changelog pls add code improvement tag * Move felinid brain shrinkage from the species to the brain --------- Co-authored-by: itseasytosee <55666666+itseasytosee@users.noreply.github.com> --- code/modules/mob/living/brain/brain_item.dm | 18 ++++++++++++++++++ .../carbon/human/species_types/felinid.dm | 13 +------------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 4bd275b5df1..658c7e1ac7c 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) 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) From a551f83642b5bf36531f1c5c95214ec483a2722e Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 01:16:16 +0200 Subject: [PATCH 10/47] [MIRROR] Fixes Strong Stone ruin [MDB IGNORE] (#23921) * Fixes Strong Stone ruin (#78555) ## About The Pull Request It was spawning all this time but it was overridden by mapgen! just places the rock in a lavaland/surface/outdoors area ### look at how snug he looks in there ![confy](https://github.com/tgstation/tgstation/assets/75863639/3f6e32d3-a031-4348-b004-22d49c3b2f6c) ## Changelog :cl: fix: fixed Strong Stone ruin generation /:cl: * Fixes Strong Stone ruin --------- Co-authored-by: Sealed101 --- _maps/RandomRuins/LavaRuins/lavaland_strong_rock.dmm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 6c2a62bc8b573bedc67f6ab008c25d189e67b3f6 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 01:16:43 +0200 Subject: [PATCH 11/47] Automatic changelog for PR #23921 [ci skip] --- html/changelogs/AutoChangeLog-pr-23921.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23921.yml diff --git a/html/changelogs/AutoChangeLog-pr-23921.yml b/html/changelogs/AutoChangeLog-pr-23921.yml new file mode 100644 index 00000000000..38105d750b3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23921.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "fixed Strong Stone ruin generation" \ No newline at end of file From 51af64ad9e453462ece7041f787904d0eff61201 Mon Sep 17 00:00:00 2001 From: jjpark-kb <55967837+jjpark-kb@users.noreply.github.com> Date: Tue, 26 Sep 2023 19:17:13 -0400 Subject: [PATCH 12/47] basic mob ash revival fix (#23913) --- modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm b/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm index e34a414cf8e..92a05c7e3b1 100644 --- a/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm +++ b/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm @@ -373,5 +373,5 @@ find_animal.faction = list(FACTION_ASHWALKER) - find_animal.revive() + find_animal.revive(HEAL_ALL) return TRUE From 5914f384696c757eaddcb94c2bbe68b48947529a Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 01:31:35 +0200 Subject: [PATCH 13/47] Automatic changelog for PR #23913 [ci skip] --- html/changelogs/AutoChangeLog-pr-23913.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23913.yml diff --git a/html/changelogs/AutoChangeLog-pr-23913.yml b/html/changelogs/AutoChangeLog-pr-23913.yml new file mode 100644 index 00000000000..45b231f7205 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23913.yml @@ -0,0 +1,4 @@ +author: "jjpark-kb" +delete-after: True +changes: + - bugfix: "actually fixed the ash revival ritual for basic mobs" \ No newline at end of file From a8c7671e4f8c3472b652d3031d4a82e1e9bf0bd5 Mon Sep 17 00:00:00 2001 From: jjpark-kb <55967837+jjpark-kb@users.noreply.github.com> Date: Tue, 26 Sep 2023 20:06:06 -0400 Subject: [PATCH 14/47] fixes basic fauna reagent (#23916) --- .../modules/fauna_reagent/fauna_reagent.dm | 65 +++++++++++++++---- 1 file changed, 54 insertions(+), 11 deletions(-) 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) From aca414f862d7bfa536474247ba37229122940c78 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 02:06:36 +0200 Subject: [PATCH 15/47] Automatic changelog for PR #23916 [ci skip] --- html/changelogs/AutoChangeLog-pr-23916.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23916.yml diff --git a/html/changelogs/AutoChangeLog-pr-23916.yml b/html/changelogs/AutoChangeLog-pr-23916.yml new file mode 100644 index 00000000000..a1b7163ecc7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23916.yml @@ -0,0 +1,4 @@ +author: "jjpark-kb" +delete-after: True +changes: + - bugfix: "basic animals now will have their health affected positively and negatively by medicine and toxins respectively." \ No newline at end of file From 6a2d7882ec9cda416bd10bd76c1271c6cbdc30f7 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Wed, 27 Sep 2023 00:32:04 +0000 Subject: [PATCH 16/47] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-23913.yml | 4 ---- html/changelogs/AutoChangeLog-pr-23916.yml | 4 ---- html/changelogs/AutoChangeLog-pr-23918.yml | 4 ---- html/changelogs/AutoChangeLog-pr-23920.yml | 4 ---- html/changelogs/AutoChangeLog-pr-23921.yml | 4 ---- html/changelogs/AutoChangeLog-pr-23933.yml | 4 ---- html/changelogs/archive/2023-09.yml | 12 ++++++++++++ 7 files changed, 12 insertions(+), 24 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-23913.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23916.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23918.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23920.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23921.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-23933.yml diff --git a/html/changelogs/AutoChangeLog-pr-23913.yml b/html/changelogs/AutoChangeLog-pr-23913.yml deleted file mode 100644 index 45b231f7205..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23913.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "jjpark-kb" -delete-after: True -changes: - - bugfix: "actually fixed the ash revival ritual for basic mobs" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23916.yml b/html/changelogs/AutoChangeLog-pr-23916.yml deleted file mode 100644 index a1b7163ecc7..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23916.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "jjpark-kb" -delete-after: True -changes: - - bugfix: "basic animals now will have their health affected positively and negatively by medicine and toxins respectively." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23918.yml b/html/changelogs/AutoChangeLog-pr-23918.yml deleted file mode 100644 index 2529d2cfde0..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23918.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - rscadd: "added ranged attack friendly fire checks for basic mobs. minebots and hivebots will now try to avoid shooting their friends" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23920.yml b/html/changelogs/AutoChangeLog-pr-23920.yml deleted file mode 100644 index 7da7c6d1af8..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23920.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "[Tramstation] Mass Driver in chapel now has tiny fan so you don't space yourself." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23921.yml b/html/changelogs/AutoChangeLog-pr-23921.yml deleted file mode 100644 index 38105d750b3..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23921.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "fixed Strong Stone ruin generation" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23933.yml b/html/changelogs/AutoChangeLog-pr-23933.yml deleted file mode 100644 index 2fef349c7d1..00000000000 --- a/html/changelogs/AutoChangeLog-pr-23933.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - rscadd: "Added a candle box crate for all your candle needs!" \ No newline at end of file diff --git a/html/changelogs/archive/2023-09.yml b/html/changelogs/archive/2023-09.yml index 08d6aff2784..fdba6bf3a13 100644 --- a/html/changelogs/archive/2023-09.yml +++ b/html/changelogs/archive/2023-09.yml @@ -1051,3 +1051,15 @@ sqnztb: - rscadd: New medicine to clear up scars, made from synthflesh, ethanol, and miner's salve. Be sure to apply it via patches! +2023-09-27: + SkyratBot: + - rscadd: added ranged attack friendly fire checks for basic mobs. minebots and + hivebots will now try to avoid shooting their friends + - bugfix: fixed Strong Stone ruin generation + - rscadd: Added a candle box crate for all your candle needs! + - bugfix: '[Tramstation] Mass Driver in chapel now has tiny fan so you don''t space + yourself.' + jjpark-kb: + - bugfix: actually fixed the ash revival ritual for basic mobs + - bugfix: basic animals now will have their health affected positively and negatively + by medicine and toxins respectively. From 084fbcf744f937b9ea5953b6e8e497afe9c45ae6 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 07:09:07 +0200 Subject: [PATCH 17/47] [MIRROR] Removes debug species from magic mirror [MDB IGNORE] (#23906) * Removes debug species from magic mirror * Update _external_organ.dm * Update _external_organ.dm --------- Co-authored-by: Jacquerel Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> --- .../carbon/human/species_types/abominations.dm | 5 +++++ .../surgery/organs/external/_external_organ.dm | 13 ++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) 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/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 From 978fcd3f786e9d2c58dfc9d088d86721bd5071e5 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 07:16:35 +0200 Subject: [PATCH 18/47] Automatic changelog for PR #23906 [ci skip] --- html/changelogs/AutoChangeLog-pr-23906.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23906.yml diff --git a/html/changelogs/AutoChangeLog-pr-23906.yml b/html/changelogs/AutoChangeLog-pr-23906.yml new file mode 100644 index 00000000000..772d985ddd8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23906.yml @@ -0,0 +1,5 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "Selecting \"Monkey\" on a magic mirror will now once again turn you into a Monkey rather than a disgusting freak of nature." + - bugfix: "Tall Boys have once again been barred from joining the Wizard Federation." \ No newline at end of file From faa9c208bfeabfd8d1127b0cba10fae1f52f0324 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:17:00 +0200 Subject: [PATCH 19/47] [MIRROR] Adds a holodeck to Birdshot Station [MDB IGNORE] (#23940) * Adds a holodeck to Birdshot Station (#78548) ## About The Pull Request Nanotrasen has heard your requests and dispatched a Porta-Jump Optional Holodeck Nexus (Porta-JOHN) to Birdshot Station! ![image](https://github.com/tgstation/tgstation/assets/7019927/8c028446-abc1-41ec-b6c8-ee62efdcad44) StrongDMM screenshot. ![image](https://github.com/tgstation/tgstation/assets/7019927/279ea8eb-a409-4f15-8bf0-67c73d6b4eb7) In-game screenshot Not the cleanest landing, but it's nothing you folks can't fix up. Props to zxaber for the genius idea of making it a shuttle Centcom just flew into the side of the station. This is north of Crew Facilities. I feel bad about having to take out the little cave that was there, but this was really the only place that would be publicly accessible, wouldn't require crawling through maints, and would work with how holodecks work. Tested multiple times, appears to be working just fine as far as generating holodeck tiles. ## Why It's Good For The Game Feature parity good, every map should have roughly the same things available, at least in a broad, general sense. ## Changelog :cl: Vekter add: Added a holodeck to Birdshot Station. It can be reached via the Crew Facilities hallway. /:cl: * Adds a holodeck to Birdshot Station --------- Co-authored-by: Vekter --- _maps/map_files/Birdshot/birdshot.dmm | 1440 ++++++++++++++----------- 1 file changed, 814 insertions(+), 626 deletions(-) diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index 21b1cddf818..95ecc1879fd 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -788,6 +788,12 @@ }, /turf/open/floor/iron/smooth, /area/station/engineering/supermatter/room) +"aqM" = ( +/obj/effect/turf_decal/bot_white, +/obj/structure/rack, +/obj/item/electronics/apc, +/turf/open/floor/iron/smooth_large, +/area/station/cargo/warehouse) "aqU" = ( /obj/effect/turf_decal/delivery, /obj/machinery/atmospherics/pipe/smart/simple/green/visible{ @@ -1967,6 +1973,10 @@ }, /turf/open/floor/plating, /area/station/engineering/supermatter) +"aPK" = ( +/obj/structure/window/reinforced/shuttle, +/turf/open/floor/plating, +/area/station/commons/fitness/recreation/entertainment) "aPM" = ( /obj/structure/chair/sofa/bench/right, /obj/machinery/firealarm/directional/north, @@ -3525,6 +3535,15 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/carpet/orange, /area/station/service/abandoned_gambling_den) +"buP" = ( +/obj/structure/cable, +/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) "buS" = ( /obj/structure/window/reinforced/plasma/spawner/directional/east, /obj/effect/turf_decal/stripes/white/line{ @@ -3728,6 +3747,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/engineering/atmospherics_engine) +"bzi" = ( +/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) "bzn" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/yellow/opposingcorners, @@ -3910,6 +3936,11 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/engineering/atmospherics_engine) +"bBA" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/holopad, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "bCf" = ( /obj/machinery/computer/shuttle/labor{ dir = 8 @@ -5414,14 +5445,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 +5520,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, @@ -8047,6 +8062,11 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/station/maintenance/department/engine) +"dhg" = ( +/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) "dhh" = ( /obj/structure/cable, /obj/machinery/status_display/ai/directional/north, @@ -8378,6 +8398,11 @@ /obj/effect/landmark/start/depsec/medical, /turf/open/floor/iron/smooth, /area/station/security/checkpoint/customs/auxiliary) +"dmo" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/structure/sign/poster/official/random/directional/west, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "dmw" = ( /obj/machinery/atmospherics/components/tank/plasma, /obj/structure/window/reinforced/plasma/spawner/directional/east, @@ -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"; @@ -9311,6 +9332,9 @@ /obj/machinery/camera/autoname/directional/south, /turf/open/floor/iron/smooth, /area/station/security/checkpoint/escape) +"dDV" = ( +/turf/closed/wall, +/area/station/commons/fitness/recreation/entertainment) "dEt" = ( /obj/machinery/atmospherics/pipe/smart/simple/green/visible{ dir = 6 @@ -9704,6 +9728,13 @@ /obj/effect/spawner/random/engineering/tracking_beacon, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"dMV" = ( +/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) "dMX" = ( /obj/machinery/holopad/secure, /turf/open/floor/iron/dark, @@ -10489,6 +10520,11 @@ }, /turf/open/floor/iron/small, /area/station/security/prison/shower) +"dZU" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "dZZ" = ( /obj/structure/cable/layer3, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, @@ -10952,6 +10988,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/science/ordnance/testlab) +"ejy" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/random/trash, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "ejH" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -11008,6 +11049,17 @@ /obj/structure/closet/firecloset, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) +"ekP" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/table, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) +"ekX" = ( +/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) "ekZ" = ( /obj/structure/disposalpipe/segment, /obj/effect/landmark/navigate_destination, @@ -11643,6 +11695,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/catwalk_floor/iron, /area/station/science/lobby) +"euV" = ( +/obj/effect/spawner/random/entertainment/arcade{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "euX" = ( /obj/machinery/atmospherics/pipe/layer_manifold/supply/visible{ dir = 8 @@ -12161,6 +12219,16 @@ /obj/structure/cable, /turf/open/floor/plating/rust, /area/station/maintenance/fore/lesser) +"eDT" = ( +/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) "eDX" = ( /obj/structure/table/glass, /obj/item/folder/red{ @@ -13709,6 +13777,16 @@ /obj/effect/turf_decal/sand/plating, /turf/open/floor/plating/airless, /area/space/nearstation) +"fiR" = ( +/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) "fjh" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, @@ -13891,6 +13969,10 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/station/security/prison/work) +"fmE" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/commons/fitness/recreation/entertainment) "fmH" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -14496,6 +14578,10 @@ /obj/item/kirbyplants/random, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/ce) +"fvW" = ( +/obj/machinery/vending/clothing, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "fwc" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -14573,6 +14659,11 @@ /obj/effect/turf_decal/siding/wood, /turf/open/floor/wood, /area/station/hallway/secondary/entry) +"fxk" = ( +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "fxt" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -14611,6 +14702,15 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/maintenance/hallway/abandoned_recreation) +"fyf" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) +"fyk" = ( +/obj/structure/window/reinforced/shuttle, +/obj/structure/window/reinforced/shuttle, +/turf/open/floor/plating, +/area/station/commons/fitness/recreation/entertainment) "fyo" = ( /obj/structure/table, /obj/machinery/light/small/directional/east, @@ -15566,6 +15666,10 @@ }, /turf/open/floor/engine/o2, /area/station/engineering/atmos) +"fMP" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "fMQ" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -15607,6 +15711,12 @@ }, /turf/open/floor/engine/o2, /area/station/engineering/atmos) +"fNs" = ( +/obj/machinery/light/small/directional/west, +/obj/effect/decal/cleanable/dirt, +/obj/structure/closet/firecloset, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "fNu" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -16427,6 +16537,14 @@ }, /turf/open/floor/plating, /area/station/medical/treatment_center) +"gex" = ( +/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) "geE" = ( /obj/structure/window/reinforced/spawner/directional/east, /obj/structure/window/reinforced/spawner/directional/south, @@ -18221,6 +18339,13 @@ "gLb" = ( /turf/closed/wall, /area/station/medical/virology) +"gLo" = ( +/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) "gLs" = ( /obj/effect/turf_decal/siding/thinplating{ dir = 8 @@ -18954,6 +19079,10 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/station/security/processing) +"gWG" = ( +/obj/effect/spawner/random/vending/colavend, +/turf/open/floor/plating/rust, +/area/station/maintenance/fore/greater) "gWN" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -19413,21 +19542,6 @@ }, /turf/open/floor/wood/large, /area/station/command/corporate_suite) -"hek" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/structure/closet/secure_closet/personal, -/obj/item/storage/backpack, -/obj/item/storage/backpack/satchel, -/obj/item/clothing/suit/hooded/wintercoat, -/obj/item/clothing/shoes/winterboots, -/obj/effect/landmark/start/hangover/closet, -/obj/effect/mapping_helpers/broken_floor, -/obj/structure/sign/poster/official/random/directional/north, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/commons) "hem" = ( /turf/closed/wall, /area/station/hallway/primary/fore) @@ -20241,16 +20355,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, @@ -20314,6 +20418,12 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/department/science/xenobiology) +"hue" = ( +/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) "huh" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -20689,16 +20799,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, @@ -20886,6 +20986,14 @@ /obj/machinery/light/floor, /turf/open/floor/iron/dark/small, /area/station/security/brig) +"hCa" = ( +/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) "hCn" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -20916,6 +21024,15 @@ /obj/structure/lattice/catwalk, /turf/open/space/basic, /area/station/solars/aft) +"hCV" = ( +/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) "hCX" = ( /obj/structure/chair/sofa/bench/left{ dir = 4 @@ -21023,12 +21140,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 @@ -21072,6 +21183,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/stairs, /area/station/medical/medbay/central) +"hGT" = ( +/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) "hHf" = ( /obj/structure/table/reinforced, /obj/item/paper_bin{ @@ -21174,11 +21293,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, @@ -21833,6 +21947,15 @@ /obj/effect/mapping_helpers/airlock/access/all/medical/cmo, /turf/open/floor/wood/parquet, /area/station/command/heads_quarters/cmo) +"hWF" = ( +/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) "hWJ" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -22684,11 +22807,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"; @@ -23306,11 +23424,6 @@ /obj/structure/window/spawner/directional/west, /turf/open/floor/iron/dark, /area/station/engineering/atmos) -"ivO" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/reagent_dispensers/fueltank, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "ivX" = ( /obj/structure/cable, /obj/effect/mapping_helpers/broken_floor, @@ -23364,6 +23477,10 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/hallway/primary/port) +"ixa" = ( +/obj/effect/spawner/random/structure/closet_maintenance, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "ixl" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -23729,10 +23846,6 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) -"iFi" = ( -/obj/effect/spawner/random/structure/crate, -/turf/open/floor/plating/rust, -/area/station/maintenance/fore/greater) "iFs" = ( /obj/structure/window/spawner/directional/east, /turf/open/misc/sandy_dirt, @@ -23770,6 +23883,13 @@ dir = 1 }, /area/station/engineering/atmos) +"iGi" = ( +/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) "iGl" = ( /turf/open/floor/plating, /area/station/maintenance/hallway/abandoned_command) @@ -23814,11 +23934,6 @@ /obj/effect/mapping_helpers/airlock/access/all/command/general, /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, -/area/station/maintenance/fore/greater) "iHy" = ( /obj/structure/window/reinforced/plasma/spawner/directional/east, /obj/effect/turf_decal/stripes/line{ @@ -24353,19 +24468,6 @@ /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, -/turf/open/floor/plating/rust, -/area/station/maintenance/fore/greater) "iQU" = ( /obj/structure/closet{ name = "janitorial supplies" @@ -24381,11 +24483,6 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/noslip/tram_plate, /area/station/maintenance/port/aft) -"iRv" = ( -/obj/structure/cable, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "iRz" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -24428,15 +24525,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 +24533,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, @@ -24963,6 +25044,23 @@ "jaQ" = ( /turf/open/floor/catwalk_floor/iron_dark, /area/station/security/processing) +"jaX" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/structure/closet/secure_closet/personal, +/obj/item/storage/backpack, +/obj/item/storage/backpack/satchel, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/shoes/winterboots, +/obj/effect/landmark/start/hangover/closet, +/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) "jbb" = ( /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, @@ -24990,9 +25088,6 @@ }, /turf/open/floor/plating, /area/station/command/heads_quarters/rd) -"jbm" = ( -/turf/closed/mineral/random/stationside, -/area/station/maintenance/fore/greater) "jbr" = ( /obj/structure/table/glass, /obj/item/folder/blue{ @@ -25109,16 +25204,6 @@ /obj/effect/decal/cleanable/dirt, /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) -"jez" = ( -/obj/structure/cable, -/obj/machinery/portable_atmospherics/canister/air, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "jeC" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -25146,12 +25231,6 @@ /obj/structure/sign/departments/medbay/alt/directional/west, /turf/open/floor/plating, /area/station/medical/medbay/lobby) -"jeX" = ( -/obj/structure/cable, -/obj/machinery/portable_atmospherics/canister/air, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating/rust, -/area/station/maintenance/fore/greater) "jfs" = ( /obj/effect/turf_decal/tile/yellow/half/contrasted{ dir = 4 @@ -25794,10 +25873,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 +26246,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, @@ -26223,11 +26292,6 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/construction) -"jAs" = ( -/obj/structure/cable, -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "jAw" = ( /obj/structure/cable, /obj/machinery/light/small/directional/east, @@ -27482,6 +27546,14 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron/textured_large, /area/station/cargo/office) +"jXc" = ( +/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) "jXe" = ( /obj/machinery/holopad/secure, /turf/open/floor/iron/smooth, @@ -27531,15 +27603,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; @@ -29219,11 +29282,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/smooth, /area/station/maintenance/solars/port/aft) -"kDq" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/commons) "kDV" = ( /obj/item/kirbyplants/random, /obj/effect/decal/cleanable/dirt, @@ -29369,11 +29427,6 @@ dir = 1 }, /area/station/maintenance/department/engine/atmos) -"kGz" = ( -/obj/effect/mapping_helpers/broken_floor, -/obj/structure/reagent_dispensers/plumbed, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "kGB" = ( /turf/open/floor/iron/dark, /area/station/hallway/secondary/construction) @@ -29665,11 +29718,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 @@ -30352,12 +30400,6 @@ /obj/structure/window/spawner/directional/south, /turf/open/floor/grass, /area/station/cargo/storage) -"kZf" = ( -/obj/effect/turf_decal/sand/plating, -/obj/effect/decal/cleanable/dirt, -/obj/effect/spawner/random/trash, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "kZh" = ( /obj/structure/table/glass, /obj/effect/turf_decal/siding/thinplating_new/light{ @@ -30366,14 +30408,6 @@ /obj/item/modular_computer/laptop, /turf/open/floor/iron/grimy, /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, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "kZx" = ( /obj/machinery/button/door/directional/north{ id = "main_surgery"; @@ -30552,6 +30586,11 @@ /obj/machinery/camera/directional/east, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"lcI" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/girder, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "lcN" = ( /obj/structure/flora/bush/flowers_yw/style_random, /obj/structure/flora/bush/flowers_br/style_random, @@ -31050,6 +31089,10 @@ /obj/machinery/incident_display/tram/directional/north, /turf/open/floor/iron, /area/station/maintenance/department/medical/central) +"liM" = ( +/obj/machinery/rnd/bepis, +/turf/open/floor/iron, +/area/station/cargo/storage) "liP" = ( /obj/effect/landmark/event_spawn, /turf/open/floor/iron/dark/small, @@ -31070,6 +31113,13 @@ }, /turf/open/floor/noslip/tram_platform, /area/station/maintenance/department/medical/central) +"ljf" = ( +/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) "ljk" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -31332,6 +31382,13 @@ }, /turf/open/floor/iron/dark, /area/station/cargo/office) +"lnt" = ( +/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) "lnu" = ( /obj/machinery/holopad, /turf/open/floor/iron/dark, @@ -31353,10 +31410,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, @@ -31468,9 +31521,6 @@ "lql" = ( /turf/open/floor/wood/parquet, /area/station/service/library) -"lqs" = ( -/turf/closed/wall/rust, -/area/station/maintenance/fore/greater) "lqt" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -31885,6 +31935,11 @@ }, /turf/open/floor/iron/white/small, /area/station/medical/psychology) +"lyi" = ( +/turf/open/floor/engine{ + name = "Holodeck Projector Floor" + }, +/area/station/holodeck/rec_center) "lyj" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -32173,6 +32228,11 @@ /obj/structure/falsewall, /turf/open/floor/plating, /area/station/maintenance/aft) +"lCP" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/digital_clock/directional/north, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "lCS" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -32920,12 +32980,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 @@ -33219,6 +33273,13 @@ /obj/structure/window/spawner/directional/west, /turf/open/floor/plating, /area/station/cargo/sorting) +"lVw" = ( +/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) "lVy" = ( /obj/effect/turf_decal/tile/green/anticorner/contrasted{ dir = 8 @@ -34006,6 +34067,12 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron/small, /area/station/commons/fitness/locker_room) +"miY" = ( +/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) "mjf" = ( /obj/structure/table/reinforced/rglass, /obj/machinery/door/window/left/directional/west{ @@ -34543,6 +34610,12 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) +"muD" = ( +/obj/effect/landmark/start/hangover, +/turf/open/floor/engine{ + name = "Holodeck Projector Floor" + }, +/area/station/holodeck/rec_center) "muI" = ( /obj/machinery/door/airlock{ name = "Maintenance" @@ -35037,6 +35110,14 @@ /obj/structure/sign/departments/cargo/directional/west, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"mDt" = ( +/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) "mDC" = ( /obj/structure/closet/crate{ name = "Game Supplies" @@ -35149,6 +35230,11 @@ /obj/structure/window/reinforced/spawner/directional/east, /turf/open/floor/eighties, /area/station/service/abandoned_gambling_den/gaming) +"mFo" = ( +/obj/structure/girder, +/obj/effect/decal/cleanable/glass/plastitanium, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "mFq" = ( /obj/effect/turf_decal/tile/dark_red/fourcorners, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -35543,11 +35629,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, @@ -36019,6 +36100,9 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/hallway/primary/port) +"mVg" = ( +/turf/closed/wall/mineral/titanium, +/area/station/commons/fitness/recreation/entertainment) "mVm" = ( /obj/effect/turf_decal/tile/green/anticorner/contrasted{ dir = 1 @@ -36046,6 +36130,12 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark/small, /area/station/ai_monitored/security/armory) +"mVy" = ( +/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) "mVC" = ( /obj/machinery/door/airlock/external{ name = "Departure Lounge Airlock" @@ -36254,6 +36344,16 @@ /obj/structure/alien/weeds, /turf/open/floor/wood, /area/station/maintenance/starboard/greater) +"mZQ" = ( +/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) "mZX" = ( /obj/item/kirbyplants/random, /obj/effect/decal/cleanable/dirt, @@ -36375,6 +36475,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 +36559,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, @@ -36675,6 +36781,9 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/station/hallway/primary/fore) +"niB" = ( +/turf/closed/wall/r_wall, +/area/station/commons/fitness/recreation/entertainment) "niI" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/effect/turf_decal/siding/white{ @@ -37421,6 +37530,14 @@ dir = 1 }, /area/station/hallway/secondary/dock) +"nwo" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/structure/extinguisher_cabinet/directional/north, +/turf/open/floor/iron, +/area/station/cargo/storage) "nwN" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -38305,6 +38422,11 @@ /obj/effect/spawner/random/structure/grille, /turf/open/floor/plating, /area/station/maintenance/central/greater) +"nLL" = ( +/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) "nLN" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -38694,6 +38816,12 @@ }, /turf/open/floor/iron/small, /area/station/medical/morgue) +"nTR" = ( +/obj/machinery/power/shuttle_engine/propulsion{ + dir = 1 + }, +/turf/open/floor/plating, +/area/station/commons/fitness/recreation/entertainment) "nUi" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -39115,6 +39243,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/cargo/storage) +"odY" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/random/trash/graffiti, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "oem" = ( /obj/effect/turf_decal/stripes/white/line{ dir = 8 @@ -39793,6 +39926,13 @@ /obj/machinery/duct, /turf/open/floor/iron/showroomfloor, /area/station/commons/toilet/restrooms) +"oqp" = ( +/obj/structure/cable, +/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) "oqE" = ( /obj/effect/turf_decal/siding/wood{ dir = 1 @@ -40470,10 +40610,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 @@ -40692,6 +40828,14 @@ /obj/item/circuitboard/machine/biogenerator, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) +"oJd" = ( +/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) "oJi" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -40905,6 +41049,11 @@ /obj/effect/spawner/structure/window/reinforced/plasma, /turf/open/floor/plating, /area/station/engineering/supermatter/room) +"oNs" = ( +/obj/structure/girder, +/obj/effect/decal/cleanable/glass/plastitanium, +/turf/open/floor/plating, +/area/station/commons/fitness/recreation/entertainment) "oNv" = ( /obj/effect/turf_decal/tile/dark_red/anticorner/contrasted{ dir = 1 @@ -42136,6 +42285,10 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"pjC" = ( +/obj/structure/reagent_dispensers/fueltank, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "pjL" = ( /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/trimline/blue/filled/line{ @@ -42788,11 +42941,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron/diagonal, /area/station/command/heads_quarters/hop) -"puC" = ( -/obj/effect/turf_decal/sand/plating, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "puD" = ( /obj/structure/bookcase/random/nonfiction, /obj/machinery/newscaster/directional/west, @@ -43847,11 +43995,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{ @@ -44899,6 +45042,12 @@ /obj/structure/cable, /turf/open/floor/iron/dark/side, /area/station/hallway/secondary/construction) +"qci" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/girder, +/obj/effect/decal/cleanable/glass/plastitanium, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "qcl" = ( /obj/item/radio/intercom/directional/south, /turf/open/floor/wood, @@ -45967,6 +46116,15 @@ /obj/effect/landmark/blobstart, /turf/open/floor/iron, /area/station/hallway/secondary/construction) +"qsm" = ( +/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) "qsu" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -46971,6 +47129,13 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/security/processing) +"qIu" = ( +/obj/machinery/light/small/directional/east, +/obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/broken_floor, +/obj/structure/broken_flooring/singular/directional/west, +/turf/open/floor/plating, +/area/station/commons/fitness/recreation/entertainment) "qIv" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -47370,6 +47535,10 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/starboard) +"qQE" = ( +/obj/structure/girder, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "qQK" = ( /turf/open/floor/iron/white/corner{ dir = 1 @@ -49986,14 +50155,6 @@ }, /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) "rGN" = ( /obj/effect/spawner/random/structure/crate, /turf/open/floor/plating, @@ -50109,10 +50270,6 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/engine, /area/station/engineering/gravity_generator) -"rIO" = ( -/obj/effect/spawner/random/trash, -/turf/open/misc/asteroid, -/area/station/maintenance/fore/greater) "rIS" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron/cafeteria, @@ -50395,6 +50552,10 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/catwalk_floor/iron_smooth, /area/station/command/gateway) +"rNF" = ( +/obj/effect/mob_spawn/corpse/human/miner, +/turf/open/misc/asteroid, +/area/space/nearstation) "rNJ" = ( /obj/effect/spawner/random/entertainment/arcade, /turf/open/floor/iron/cafeteria, @@ -50607,6 +50768,12 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/maintenance/starboard/greater) +"rRx" = ( +/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) "rRy" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -51766,10 +51933,10 @@ /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, +"skt" = ( +/obj/machinery/portable_atmospherics/canister/air, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/plating/rust, /area/station/maintenance/fore/greater) "skP" = ( /obj/effect/spawner/structure/window, @@ -54129,6 +54296,13 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/tech_storage, /turf/open/floor/catwalk_floor/iron, /area/station/engineering/storage/tech) +"sYv" = ( +/obj/machinery/power/shuttle_engine/heater{ + dir = 1 + }, +/obj/structure/window/spawner/directional/south, +/turf/open/floor/plating, +/area/station/commons/fitness/recreation/entertainment) "sYx" = ( /obj/machinery/atmospherics/components/unary/thermomachine/freezer, /obj/effect/turf_decal/stripes, @@ -54326,10 +54500,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, @@ -55371,13 +55541,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, @@ -55457,10 +55620,6 @@ }, /turf/open/floor/iron/small, /area/station/hallway/primary/central/fore) -"twN" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/misc/asteroid, -/area/station/maintenance/fore/greater) "twR" = ( /obj/structure/table/glass, /obj/machinery/cell_charger, @@ -55851,13 +56010,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) @@ -56037,6 +56189,11 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/port) +"tGa" = ( +/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) "tGp" = ( /obj/machinery/light/small/directional/south, /turf/open/floor/engine, @@ -56253,6 +56410,10 @@ /obj/effect/turf_decal/tile/green/diagonal_centre, /turf/open/floor/iron/diagonal, /area/station/hallway/primary/central/aft) +"tKF" = ( +/mob/living/basic/mining/basilisk, +/turf/open/misc/asteroid, +/area/space/nearstation) "tKG" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/mapping_helpers/broken_floor, @@ -57976,11 +58137,6 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) -"unK" = ( -/obj/structure/rack, -/obj/effect/spawner/random/maintenance, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "unM" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/door/airlock/public/glass{ @@ -58743,6 +58899,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/stairs, /area/station/engineering/storage/tech) +"uBJ" = ( +/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) "uBQ" = ( /obj/structure/table/bronze, /obj/machinery/microwave{ @@ -59221,6 +59386,11 @@ /obj/machinery/duct, /turf/open/floor/plating, /area/station/maintenance/port/greater) +"uJn" = ( +/obj/machinery/light/cold/directional/south, +/obj/structure/reagent_dispensers/water_cooler, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "uJD" = ( /obj/structure/chair/sofa/bench/right{ dir = 1 @@ -59459,6 +59629,10 @@ }, /turf/open/floor/iron/white/corner, /area/station/hallway/primary/aft) +"uNZ" = ( +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "uOh" = ( /obj/structure/chair{ dir = 1; @@ -60641,13 +60815,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, @@ -61150,6 +61317,11 @@ }, /turf/open/space/basic, /area/space/nearstation) +"voV" = ( +/obj/structure/rack, +/obj/effect/spawner/random/maintenance/two, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "vpb" = ( /obj/machinery/door/airlock/hatch{ name = "Tool Supply Corridor" @@ -61239,6 +61411,11 @@ "vqp" = ( /turf/open/floor/carpet/lone, /area/station/service/theater) +"vqt" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/random/structure/crate, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "vqH" = ( /obj/structure/railing{ dir = 8 @@ -61260,18 +61437,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, @@ -61902,6 +62067,10 @@ "vAD" = ( /turf/open/floor/wood/tile, /area/station/maintenance/port/lesser) +"vAE" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "vAK" = ( /obj/machinery/door/airlock{ name = "Maintenance" @@ -62638,11 +62807,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, @@ -62721,6 +62885,14 @@ /obj/effect/turf_decal/stripes/red/line, /turf/open/floor/iron/small, /area/station/hallway/secondary/spacebridge) +"vOj" = ( +/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) "vOr" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -62782,6 +62954,17 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"vPM" = ( +/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) "vPP" = ( /turf/closed/wall, /area/station/command/corporate_suite) @@ -63033,10 +63216,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) @@ -63250,6 +63429,10 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron/white/corner, /area/station/science/lobby) +"vWk" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "vWr" = ( /obj/machinery/door/airlock/security/glass{ id_tag = "permaouter"; @@ -63293,6 +63476,13 @@ "vWM" = ( /turf/open/floor/iron/smooth, /area/station/maintenance/solars/starboard/fore) +"vWN" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/chair/sofa/bench/left{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "vWQ" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/mapping_helpers/broken_floor, @@ -63917,10 +64107,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{ @@ -64046,6 +64232,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white/small, /area/station/service/janitor) +"wjU" = ( +/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) "wjY" = ( /obj/structure/window/spawner/directional/east, /obj/structure/table/wood, @@ -65258,6 +65453,12 @@ /obj/machinery/light_switch/directional/south, /turf/open/floor/iron/white, /area/station/medical/medbay/central) +"wDs" = ( +/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) "wDu" = ( /obj/effect/turf_decal/stripes/white/line, /turf/open/floor/noslip/tram_platform, @@ -66292,11 +66493,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, @@ -67328,6 +67524,12 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/port) +"xgT" = ( +/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) "xhe" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -68640,6 +68842,14 @@ }, /turf/open/floor/iron/white/textured_large, /area/station/medical/medbay/lobby) +"xyv" = ( +/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) "xyx" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 8 @@ -69163,11 +69373,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, @@ -69715,6 +69920,9 @@ /obj/effect/landmark/start/research_director, /turf/open/floor/iron/dark/small, /area/station/command/heads_quarters/rd) +"xOy" = ( +/turf/open/misc/asteroid, +/area/space/nearstation) "xOB" = ( /obj/effect/turf_decal/siding/wood{ dir = 4 @@ -70588,6 +70796,15 @@ "xYK" = ( /turf/open/floor/iron/grimy, /area/station/science/cubicle) +"xYN" = ( +/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) "xYO" = ( /turf/closed/wall/r_wall, /area/station/maintenance/department/bridge) @@ -70849,24 +71066,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) @@ -70909,9 +71108,6 @@ /obj/item/radio/intercom/directional/north, /turf/open/floor/wood/tile, /area/station/command/bridge) -"ydt" = ( -/turf/open/misc/asteroid, -/area/station/maintenance/fore/greater) "ydu" = ( /obj/structure/cable, /obj/structure/disposalpipe/sorting/mail{ @@ -71137,9 +71333,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, @@ -71437,11 +71630,6 @@ /obj/machinery/newscaster/directional/west, /turf/open/floor/iron/white/small, /area/station/science/cubicle) -"yju" = ( -/obj/effect/spawner/random/structure/closet_maintenance, -/obj/effect/spawner/random/maintenance, -/turf/open/floor/plating, -/area/station/maintenance/fore/greater) "yjD" = ( /obj/effect/turf_decal/siding/wood{ dir = 1 @@ -83003,7 +83191,7 @@ uzJ mQh nJU ppk -lnT +liM ovQ oRr poM @@ -83504,14 +83692,14 @@ gOK slY hfc slY -viR +iGi jBb kPW kwY -whS -dmz +vAE +ixa slY -hzN +mZQ lRc moz kee @@ -83761,14 +83949,14 @@ gPN gZk iNE ueX -mLx +voV kwY slY slY kwY slY slY -jXE +qsm lTv oem oem @@ -84021,10 +84209,10 @@ jCo hff jCo slY -wTn -whS +vqt +vAE kPW -tDm +ljf jkS lTN mRD @@ -84282,7 +84470,7 @@ slY slY slY slY -ciL +nwo lUz ohj ohj @@ -84532,7 +84720,7 @@ sNz hyO roi slY -hFm +aqM hAN jMb kzI @@ -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 +ejy sIA jPq kaF @@ -105344,18 +105532,18 @@ dDB dDB aJq aJq -jbm -jbm -jbm -jbm -jbm +dDV +dDV +dDV +dDV +dDV +niB +niB +niB +niB xmO xmO -xmO -xmO -xmO -xmO -jsn +oTL sIS nFW sRL @@ -105601,19 +105789,19 @@ dDB dDB aJq aJq -jbm -jbm -jbm -jbm -jbm -jbm -jbm -jbm -tbM -iFi -iQF +dDV +euV +hGT +hCa +dmo +rRx +xgT +gex +dDV +gWG jej -jAs +jej +oqp nFW pmn wZl @@ -105858,18 +106046,18 @@ dDB aJq aJq aJq -jbm -vTO -jbm -jbm -twN -jbm -jbm -lqs -xGS -yfX -twN -tDB +dDV +mVy +nLL +dhg +vWk +bBA +fxk +uJn +dDV +nFW +xyv +nFW nFW nFW tBL @@ -106111,24 +106299,24 @@ dDB dDB dDB dDB -dDB aJq aJq aJq -jbm -oEm -jbm -jbm -oEm -jbm -twN -nFW -rGL -puC -kZf -jey -nFW -hek +aJq +dDV +lCP +vWN +gLo +vWk +fMP +mDt +vWk +fmE +fNs +fxk +fvW +dDV +jaX wXt ndZ vRx @@ -106360,36 +106548,36 @@ 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 -jez -nFW -lPG -wXt -net -kDq -kDq +dDV +dZU +uBJ +ekP +fyf +tGa +xYN +dMV +eDT +dMV +dMV +ekX +wjU +wYC +wDs +wYC +hue +hue ldB bnh lPd @@ -106617,31 +106805,31 @@ aJq aJq aJq aJq -hwJ -blb -blb -blb -blb -blb -blb -blb -blb -hwJ aJq -jbm -jbm -ydt -jbm -jbm -ydt -jbm -skH -lqs -imd -rIO -pLK -jeX -nFW +dDB +dDB +dDB +dDB +dDB +dDB +dDB +dDB +mVg +aPK +oNs +aPK +fiR +fmE +fmE +vPM +fmE +fmE +fmE +fmE +odY +uNZ +qIu +dDV qhq tDq rnn @@ -106882,21 +107070,21 @@ dDB dDB dDB dDB -aJq -aJq -aJq -jbm -twN -ydt -jbm -jbm -kKN -jbm -jbm -jbm -jbm -sJR -jzl +mVg +mVg +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +mVg +nFW +xyv nFW nFW nFW @@ -107138,27 +107326,27 @@ dDB dDB dDB dDB -dDB -aJq -aJq -aJq -jbm -oEm -jbm -jbm -jbm -ydt -jbm -jbm -jbm -jbm -iHs -iQK +nTR +sYv +mVg +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +mVg +skt +lVw tDB odK tDB tDB -unK +pjC nFW cCP oow @@ -107395,22 +107583,22 @@ dDB dDB dDB dDB -dDB -aJq -aJq -jbm -jbm -twN -jbm -jbm -jbm -twN -twh -ycz -jbm -jbm -jbm -iRv +nTR +sYv +mVg +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +oNs +skt +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 +nTR +sYv +mVg +lyi +lyi +muD +lyi +lyi +lyi +lyi +lyi +lyi +lyi +oNs +lcI +lnt 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 -ivO -pLK +mVg +mVg +mVg +hWF +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +hCV +oNs +qci +lnt 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 -yju -iRv +nTR +sYv +mVg +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +mVg +miY +vOj jfP nfc jQF @@ -108423,22 +108611,22 @@ dDB dDB dDB dDB -dDB -dDB -dDB -aJq -aJq -aJq -jbm -jbm -jbm -jbm -jbm -jbm -jbm -nFW -kGz -kZo +nTR +sYv +mVg +lyi +lyi +lyi +lyi +lyi +lyi +lyi +muD +lyi +lyi +mVg +qQE +buP nFW lLv sJR @@ -108680,22 +108868,22 @@ dDB dDB dDB dDB -dDB -dDB -dDB -aJq -aJq -aJq -aJq -aJq -jbm -jbm -jbm -jbm -jbm -jbm -sJR -njm +nTR +sYv +mVg +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +oNs +mFo +jXc 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 +mVg +mVg +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +lyi +mVg +qQE +bzi +oJd dxz sJR xwy @@ -109196,18 +109384,18 @@ dDB dDB dDB dDB -dDB -dDB -dDB -aJq -aJq -aJq -aJq -aJq -jbm -jbm -jbm -jbm +mVg +aPK +aPK +aPK +fyk +aPK +oNs +oNs +aPK +aPK +aPK +mVg 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 +xOy +jJy nvS kbY imE @@ -110744,8 +110932,8 @@ aJq aJq aJq aJq -aJq -aJq +xOy +xOy weg jKf nvS @@ -110999,9 +111187,9 @@ dDB dDB aJq aJq -aJq -aJq -aJq +xOy +xOy +xOy aJq weg weg @@ -111256,8 +111444,8 @@ dDB dDB aJq aJq -aJq -aJq +xOy +rNF aJq aJq weg @@ -111513,7 +111701,7 @@ dDB dDB aJq aJq -aJq +tKF aJq aJq aJq From d47a49127f3e8199e70322fdf4e5c207a9197062 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:17:38 +0200 Subject: [PATCH 20/47] Automatic changelog for PR #23940 [ci skip] --- html/changelogs/AutoChangeLog-pr-23940.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23940.yml diff --git a/html/changelogs/AutoChangeLog-pr-23940.yml b/html/changelogs/AutoChangeLog-pr-23940.yml new file mode 100644 index 00000000000..19411fde6f2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23940.yml @@ -0,0 +1,4 @@ +author: "Vekter" +delete-after: True +changes: + - rscadd: "Added a holodeck to Birdshot Station. It can be reached via the Crew Facilities hallway." \ No newline at end of file From efa5312634579f6d7ad4b98add6a3d5f4ddab8a4 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:18:49 +0200 Subject: [PATCH 21/47] [MIRROR] Fixes a callback qdeletion during acid component deletion [MDB IGNORE] (#23937) * Fixes a callback qdeletion during acid component deletion * Update acid.dm --------- Co-authored-by: distributivgesetz Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com> --- code/datums/components/acid.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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() From f1161a6d1ec646eec79e2044f7828eebb45ac23a Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:18:59 +0200 Subject: [PATCH 22/47] [MIRROR] Fixes some more issues with job configs not being loaded by ResetOccupation [MDB IGNORE] (#23936) * Fixes some more issues with job configs not being loaded by ResetOccupation (#78596) ## About The Pull Request Job configs would get reset by ResetOccupation and not loaded afterwards. This fixes that. ## Why It's Good For The Game Bugfix ## Changelog :cl: fix: Fixed job configs not being loaded properly. /:cl: --------- Co-authored-by: Watermelon914 <3052169-Watermelon914@ users.noreply.gitlab.com> * Fixes some more issues with job configs not being loaded by ResetOccupation --------- Co-authored-by: Watermelon914 <37270891+Watermelon914@users.noreply.github.com> Co-authored-by: Watermelon914 <3052169-Watermelon914@ users.noreply.gitlab.com> --- code/controllers/configuration/entries/jobs.dm | 5 +++-- code/controllers/subsystem/job.dm | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) 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/job.dm b/code/controllers/subsystem/job.dm index 96f391b91eb..976b4bab249 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -305,8 +305,10 @@ SUBSYSTEM_DEF(job) player.mind.special_role = null SetupOccupations() unassigned = list() - if(overflow_role) - set_overflow_role(overflow_role) + 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 From 0dae04a3a272bf476b5ac7644f08e4d14027e1ac Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:23:08 +0200 Subject: [PATCH 23/47] [MIRROR] Gives maint drones random designations [MDB IGNORE] (#23944) * Gives maint drones random designations (#78573) ## About The Pull Request Right now, drone ghost spawners give all drones the name "drone." This makes it difficult to differentiate drones, both as a drone in drone chat and as a non-drone. This gives all drones a unique identifier like posibrains. Also changes a couple of 1s to TRUEs ## Why It's Good For The Game It's good to be able to identify drones, and for drones to be able to identify each other. ## Changelog :cl: Tattle qol: drones now have individual names, instead of just "drone" /:cl: Co-authored-by: tattle * Gives maint drones random designations --------- Co-authored-by: tattle <66640614+dragomagol@users.noreply.github.com> Co-authored-by: tattle --- code/modules/mob/living/simple_animal/hostile/alien.dm | 4 ++-- .../living/simple_animal/hostile/constructs/constructs.dm | 2 +- code/modules/mob_spawn/ghost_roles/drone_roles.dm | 6 ++++++ tgstation.dme | 1 + 4 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 code/modules/mob_spawn/ghost_roles/drone_roles.dm 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_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/tgstation.dme b/tgstation.dme index 2547760a8d0..a05984c12ea 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4759,6 +4759,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" From a9ae2cc4ded9dc0b6c6dbc3a02d2d2ab34f8f342 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:23:28 +0200 Subject: [PATCH 24/47] [MIRROR] [NO GBP] Fixes AI rolling so that you can't roll around if you're not on a turf, also improves AI rolling code and usage [MDB IGNORE] (#23945) * [NO GBP] Fixes AI rolling so that you can't roll around if you're not on a turf, also improves AI rolling code and usage (#78434) ## About The Pull Request Closes https://github.com/tgstation/tgstation/issues/78416 A bit of a blanket fix, but I couldnt come up with a better solution. AI rolling now doesnt require you to click on a adjacent turf, instead it just moves you in the direction of where you clicked. AI rolling cooldown is now a var, as is the roll time. * [NO GBP] Fixes AI rolling so that you can't roll around if you're not on a turf, also improves AI rolling code and usage --------- Co-authored-by: nikothedude <59709059+nikothedude@users.noreply.github.com> --- .../antagonists/malf_ai/malf_ai_modules.dm | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) 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 From 46cca542191efaea22a33863dff6f52480c690ae Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:24:02 +0200 Subject: [PATCH 25/47] [MIRROR] Planetary atmos fix [MDB IGNORE] (#23946) * Planetary atmos fix (#78602) ## About The Pull Request The code for generating random atmospheres for lavaland and icemoon has variables that define the minimum and maximum pressure that the atmosphere can be. However, due to an oversight, it was possible for the actual pressure to be below this minimum. This caused problems for the flight potion wings, as the wings will not work if the pressure is lower than the minimum lavaland/icemoon pressure. I tested this by making a quick test proc that would generate lavaland atmos 100 times, and count how often the final pressure was lower than the minimum pressure. I ran it a few times after making my changes, and it returned 0 failures every time, so I'm confident that my code works. ## Why It's Good For The Game I think its good practice for minimums and maximums variables like this to actually be hard limits. Furthermore, if there's _one_ place that mining loot should actually be useful, then its outside where you mine. ## Changelog :cl: fix: The flight potion wings will no longer fail to work on lavaland/icemoon on rare occasions. /:cl: * Planetary atmos fix --------- Co-authored-by: GPeckman <21979502+GPeckman@users.noreply.github.com> --- code/datums/atmosphere/_atmosphere.dm | 3 +++ 1 file changed, 3 insertions(+) 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 From 4300511ba518192c9c3e6ad50f8bb994ec46a384 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:24:24 +0200 Subject: [PATCH 26/47] [MIRROR] Fixes full advanced surgery trays spawning with 'nothing' [MDB IGNORE] (#23947) * Fixes full advanced surgery trays spawning with 'nothing' (#78591) ## About The Pull Request Fixes full advanced surgery trays spawning with 'nothing' They were spawning into null space ## Why It's Good For The Game I dont know ## Changelog Zepyhyr, Carlarc, Not Jacquerel :cl: fix: Fixes full advanced surgery trays spawning with 'nothing' /:cl: * Fixes full advanced surgery trays spawning with 'nothing' --------- Co-authored-by: carlarctg <53100513+carlarctg@users.noreply.github.com> --- code/game/objects/items/surgery_tray.dm | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/code/game/objects/items/surgery_tray.dm b/code/game/objects/items/surgery_tray.dm index dfe83baabdb..9d4a588ff9e 100644 --- a/code/game/objects/items/surgery_tray.dm +++ b/code/game/objects/items/surgery_tray.dm @@ -207,7 +207,7 @@ 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) @@ -227,13 +227,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) From de0894667326d794c66f88e4200fb317ff00c70a Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:25:05 +0200 Subject: [PATCH 27/47] [MIRROR] Fixed headless zambos and the oversight of no bio armor resistance [MDB IGNORE] (#23948) * Fixed headless zambos and the oversight of no bio armor resistance (#78589) ## About The Pull Request Fixed zombies being able to infect headless corpses (Including former zombies) Fixed bio armor being totally useless against zombies. Now it checks how hurt your limb is: If it's more than the bio armor value, you get infected. THICKMATERIAL clothing guarantees at least 25 damage required to infect you, non-thick clothing reduces effective defence by 25. In practice this means people with MODsuits, biosuits will resist infection unless they're pummeled into crit, and wearing a firesuit will save you from the first few slashes. Fixed the bomb hood armor not having the same bio armor value as bomb armor. Added a message to the zed when they succesfully infect someone. Turned some proc names into snake_case rather than, uh, nospacecase. ## Why It's Good For The Game > Fixed zombies being able to infect headless corpses (Including former zombies) This is pretty cool but it also means you can't actually permanently kill a zombie if they just get slashed again by another zombie. > Fixed bio armor being totally useless against zombies. Now it checks how hurt your limb is: If it's more than the bio armor value, you get infected. THICKMATERIAL clothing guarantees at least 25 damage required to infect you, non-thick clothing reduces effective defence by 25. In practice this means people with MODsuits, biosuits will resist infection unless they're pummeled into crit, and wearing a firesuit will save you from the first few slashes. Melbert told me this is an oversight, so I, uh, 'fixed' it? This also lets people have some true actual defence against zombie infections, without making them immune to it. > Fixed the bomb hood armor not having the same bio armor value as bomb armor. Bug I noticed while going over bio armors. > Added a message to the zed when they succesfully infect someone. QoL and good feedback > Turned some proc names into snake_case rather than, uh, nospacecase. what the hell do you call isuckatnamignprocs(). what case is that. cougarcase? ## Changelog :cl: fix: Fixed zombies being able to infect headless corpses (Including former zombies) fix: Fixed bio armor being totally useless against zombies. Now it checks how hurt your limb is: If it's more than the bio armor value, you get infected. THICKMATERIAL clothing guarantees at least 25 damage required to infect you, non-thick clothing reduces effective defence by 25. In practice this means people with MODsuits, biosuits will resist infection unless they're pummeled into crit, and wearing a firesuit will save you from the first few slashes. fix: Fixed the bomb hood armor not having the same bio armor value as bomb armor. qol: Added a message to the zed when they succesfully infect someone. code: Turned some proc names into snake_case rather than, uh, nospacecase. /:cl: --------- Co-authored-by: MrMelbert <51863163+MrMelbert@ users.noreply.github.com> * Fixed headless zambos and the oversight of no bio armor resistance --------- Co-authored-by: carlarctg <53100513+carlarctg@users.noreply.github.com> Co-authored-by: MrMelbert <51863163+MrMelbert@ users.noreply.github.com> --- code/controllers/subsystem/radiation.dm | 2 +- code/datums/wounds/scars/_scars.dm | 2 +- code/modules/clothing/suits/utility.dm | 1 + code/modules/mob/living/carbon/human/human.dm | 2 +- .../mob/living/carbon/human/human_defense.dm | 10 +++---- code/modules/surgery/bodyparts/wounds.dm | 4 +-- code/modules/zombie/items.dm | 30 +++++++++++++++++-- 7 files changed, 38 insertions(+), 13 deletions(-) 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/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/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/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 40e4bf095d5..b6fd8dcfacc 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 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/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/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!")) From 945e19fe58c330f781e90e4e11f0c3d50223ecac Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:25:24 +0200 Subject: [PATCH 28/47] [MIRROR] Tweaks the message that players get when not qualifying for an antagonist role. [MDB IGNORE] (#23949) * Tweaks the message that players get when not qualifying for an antagonist role. (#78563) ## About The Pull Request See title ## Why It's Good For The Game You can still end up qualifying for a role if you get lucky. The message is primarily there to tell players they weren't able to become an antagonist because their preferences are set up in a way that they're likely to return back to lobby. ## Changelog :cl: spellcheck: Tweaks the message that players get when not being able to qualify for roundstart antag to be more accurate as to what's happening. /:cl: --------- Co-authored-by: Watermelon914 <3052169-Watermelon914@ users.noreply.gitlab.com> * Tweaks the message that players get when not qualifying for an antagonist role. --------- Co-authored-by: Watermelon914 <37270891+Watermelon914@users.noreply.github.com> Co-authored-by: Watermelon914 <3052169-Watermelon914@ users.noreply.gitlab.com> --- code/game/gamemodes/dynamic/dynamic.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 26dfcb4be76..50708e0d944 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) From 66aab80c2e33813f95f242099c4b3ca3635ce1e1 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:27:46 +0200 Subject: [PATCH 29/47] [MIRROR] adds a surgery tray to surgery supplies medical order, removes surgery duffelbags entirely [MDB IGNORE] (#23941) * adds a surgery tray to surgery supplies medical order, removes surgery duffelbags entirely * Update backpack.dm * Surgery duffels are replaced by trays * Update surgery_tray.dm --------- Co-authored-by: Lamb <110322848+CoiledLamb@users.noreply.github.com> Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com> --- code/game/objects/items/storage/backpack.dm | 34 ------------------- code/game/objects/items/surgery_tray.dm | 3 ++ code/modules/cargo/packs/medical.dm | 4 +-- .../code/armament_datums/deforest_medical.dm | 2 +- modular_skyrat/modules/faction/code/outfit.dm | 2 +- 5 files changed, 7 insertions(+), 38 deletions(-) diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index c9c4815e3da..0852aeff883 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -509,46 +509,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/surgery_tray.dm b/code/game/objects/items/surgery_tray.dm index 9d4a588ff9e..99838f5d3c4 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, @@ -193,6 +194,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) @@ -214,6 +216,7 @@ 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) 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/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/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 From 32e9778c2398b2c541a479cc19cded588c0f28c6 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:27:56 +0200 Subject: [PATCH 30/47] [MIRROR] TTS: Gas Mask muffling, Hailer Mask voice effects, support for more filters that use samplerate, voice effects for lizards, ethereals, and xenomorphs. [MDB IGNORE] (#23942) * TTS: Gas Mask muffling, Hailer Mask voice effects, support for more filters that use samplerate, voice effects for lizards, ethereals, and xenomorphs. * Update RecordView.tsx * Update types.ts --------- Co-authored-by: Iamgoofball Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> --- code/__DEFINES/tts.dm | 4 ++ code/controllers/subsystem/tts.dm | 12 ++-- code/datums/records/record.dm | 3 + code/game/say.dm | 2 +- .../client/preferences/middleware/tts.dm | 2 +- code/modules/clothing/masks/_masks.dm | 4 ++ code/modules/clothing/masks/gasmask.dm | 3 +- code/modules/clothing/masks/hailer.dm | 2 + code/modules/mob/living/living_say.dm | 18 ++++- .../file_system/programs/records.dm | 1 + .../surgery/organs/internal/tongue/_tongue.dm | 5 +- .../interfaces/SecurityRecords/RecordView.tsx | 4 ++ .../tgui/interfaces/SecurityRecords/types.ts | 1 + tools/tts/tts-api/off1.wav | Bin 0 -> 3270 bytes tools/tts/tts-api/off2.wav | Bin 0 -> 19920 bytes tools/tts/tts-api/off3.wav | Bin 0 -> 21372 bytes tools/tts/tts-api/off4.wav | Bin 0 -> 3828 bytes tools/tts/tts-api/on1.wav | Bin 0 -> 3328 bytes tools/tts/tts-api/on2.wav | Bin 0 -> 10120 bytes tools/tts/tts-api/tts-api.py | 68 ++++++++++++------ 20 files changed, 96 insertions(+), 33 deletions(-) create mode 100644 tools/tts/tts-api/off1.wav create mode 100644 tools/tts/tts-api/off2.wav create mode 100644 tools/tts/tts-api/off3.wav create mode 100644 tools/tts/tts-api/off4.wav create mode 100644 tools/tts/tts-api/on1.wav create mode 100644 tools/tts/tts-api/on2.wav 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/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/records/record.dm b/code/datums/records/record.dm index 67fce2f49a4..b790c53d76c 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 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/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/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/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(",") + 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, filter.Join(","), listened, message_range = message_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_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/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/surgery/organs/internal/tongue/_tongue.dm b/code/modules/surgery/organs/internal/tongue/_tongue.dm index e767989fc05..c715d88c890 100644 --- a/code/modules/surgery/organs/internal/tongue/_tongue.dm +++ b/code/modules/surgery/organs/internal/tongue/_tongue.dm @@ -184,7 +184,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") @@ -493,7 +493,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( @@ -601,6 +601,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/tgui/packages/tgui/interfaces/SecurityRecords/RecordView.tsx b/tgui/packages/tgui/interfaces/SecurityRecords/RecordView.tsx index 5e39c743ec3..851425dadfd 100644 --- a/tgui/packages/tgui/interfaces/SecurityRecords/RecordView.tsx +++ b/tgui/packages/tgui/interfaces/SecurityRecords/RecordView.tsx @@ -56,6 +56,7 @@ const RecordInfo = (props, context) => { rank, species, wanted_status, + voice, // SKYRAT EDIT START - RP Records past_general_records, past_security_records, @@ -172,6 +173,9 @@ const RecordInfo = (props, context) => { text={fingerprint} /> + + + Ts48vqg~CB&>) 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 N{|zPkNg??L{2x%miueEk literal 0 HcmV?d00001 diff --git a/tools/tts/tts-api/off2.wav b/tools/tts/tts-api/off2.wav new file mode 100644 index 0000000000000000000000000000000000000000..e84221070a50949923738429c0893db43a058baa GIT binary patch literal 19920 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�c7uJ+fF@(YIG#BxwYbO>E^2StvAMM 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 z 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 literal 0 HcmV?d00001 diff --git a/tools/tts/tts-api/off4.wav b/tools/tts/tts-api/off4.wav new file mode 100644 index 0000000000000000000000000000000000000000..6831bc1bcdef603628491503d27809cea39cfc63 GIT binary patch literal 3828 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 U0$eZ@%m*)kDS$s&P8g8?2R#; literal 0 HcmV?d00001 diff --git a/tools/tts/tts-api/on1.wav b/tools/tts/tts-api/on1.wav new file mode 100644 index 0000000000000000000000000000000000000000..5137fa195a7692868efb72f1ed37de9f8887102a GIT binary patch literal 3328 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 KETMt`f8c+E52U96 literal 0 HcmV?d00001 diff --git a/tools/tts/tts-api/on2.wav b/tools/tts/tts-api/on2.wav new file mode 100644 index 0000000000000000000000000000000000000000..d0178cae43251e4e96166747f455042d629655db GIT binary patch literal 10120 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 literal 0 HcmV?d00001 diff --git a/tools/tts/tts-api/tts-api.py b/tools/tts/tts-api/tts-api.py index 27f56e5488b..e1a5880da5b 100644 --- a/tools/tts/tts-api/tts-api.py +++ b/tools/tts/tts-api/tts-api.py @@ -4,11 +4,18 @@ import gc import subprocess import requests import re +import pysbd +import pydub +import string +import random +import json from flask import Flask, request, send_file, abort, make_response - +tts_sample_rate = 40000 # Set to 40000 if you're using RVC, or whatever sample rate your endpoint is going to send the audio in. app = Flask(__name__) - -authorization_token = os.getenv("TTS_AUTHORIZATION_TOKEN", "coolio") +segmenter = pysbd.Segmenter(language="en", clean=True) +radio_starts = ["./on1.wav", "./on2.wav"] +radio_ends = ["./off1.wav", "./off2.wav", "./off3.wav", "./off4.wav"] +authorization_token = os.getenv("TTS_AUTHORIZATION_TOKEN", "vote_goof_2024") def hhmmss_to_seconds(string): new_time = 0 separated_times = string.split(":") @@ -17,29 +24,46 @@ def hhmmss_to_seconds(string): new_time += float(separated_times[2]) return new_time -def text_to_speech_handler(endpoint, voice, text, filter_complex, pitch, silicon = False): +def text_to_speech_handler(endpoint, voice, text, filter_complex, pitch, special_filters = []): filter_complex = filter_complex.replace("\"", "") - response = requests.get(f"http://tts-container:5003/" + endpoint, json={ 'text': text, 'voice': voice, 'pitch': pitch }) - if response.status_code != 200: - abort(500) + data_bytes = io.BytesIO() + final_audio = pydub.AudioSegment.empty() + for sentence in segmenter.segment(text): + response = requests.get(f"http://127.0.0.1:5003/" + endpoint, json={ 'text': sentence, 'voice': voice, 'pitch': pitch }) + if response.status_code != 200: + abort(500) + sentence_audio = pydub.AudioSegment.from_file(io.BytesIO(response.content), "wav") + sentence_silence = pydub.AudioSegment.silent(250, 40000) + sentence_audio += sentence_silence + final_audio += sentence_audio + # ""Goldman-Eisler (1968) determined that typical speakers paused for an average of 250 milliseconds (ms), with a range from 150 to 400 ms."" + # (https://scholarsarchive.byu.edu/cgi/viewcontent.cgi?article=10153&context=etd) + final_audio.export(data_bytes, format="wav") + filter_complex = filter_complex.replace("%SAMPLE_RATE%", str(tts_sample_rate)) ffmpeg_result = None if filter_complex != "": - ffmpeg_result = subprocess.run(["ffmpeg", "-f", "wav", "-i", "pipe:0", "-filter_complex", filter_complex, "-c:a", "libvorbis", "-b:a", "64k", "-f", "ogg", "pipe:1"], input=response.content, capture_output = True) + ffmpeg_result = subprocess.run(["ffmpeg", "-f", "wav", "-i", "pipe:0", "-filter_complex", filter_complex, "-c:a", "libvorbis", "-b:a", "64k", "-f", "ogg", "pipe:1"], input=data_bytes.read(), capture_output = True) else: - if silicon: - ffmpeg_result = subprocess.run(["ffmpeg", "-f", "wav", "-i", "pipe:0", "-i", "./SynthImpulse.wav", "-i", "./RoomImpulse.wav", "-filter_complex", "[0] aresample=44100 [re_1]; [re_1] apad=pad_dur=2 [in_1]; [in_1] asplit=2 [in_1_1] [in_1_2]; [in_1_1] [1] afir=dry=10:wet=10 [reverb_1]; [in_1_2] [reverb_1] amix=inputs=2:weights=8 1 [mix_1]; [mix_1] asplit=2 [mix_1_1] [mix_1_2]; [mix_1_1] [2] afir=dry=1:wet=1 [reverb_2]; [mix_1_2] [reverb_2] amix=inputs=2:weights=10 1 [mix_2]; [mix_2] equalizer=f=7710:t=q:w=0.6:g=-6,equalizer=f=33:t=q:w=0.44:g=-10 [out]; [out] alimiter=level_in=1:level_out=1:limit=0.5:attack=5:release=20:level=disabled", "-c:a", "libvorbis", "-b:a", "64k", "-f", "ogg", "pipe:1"], input=response.content, capture_output = True) + if "silicon" in special_filters: + ffmpeg_result = subprocess.run(["ffmpeg", "-f", "wav", "-i", "pipe:0", "-i", "./SynthImpulse.wav", "-i", "./RoomImpulse.wav", "-filter_complex", "[0] aresample=44100 [re_1]; [re_1] apad=pad_dur=2 [in_1]; [in_1] asplit=2 [in_1_1] [in_1_2]; [in_1_1] [1] afir=dry=10:wet=10 [reverb_1]; [in_1_2] [reverb_1] amix=inputs=2:weights=8 1 [mix_1]; [mix_1] asplit=2 [mix_1_1] [mix_1_2]; [mix_1_1] [2] afir=dry=1:wet=1 [reverb_2]; [mix_1_2] [reverb_2] amix=inputs=2:weights=10 1 [mix_2]; [mix_2] equalizer=f=7710:t=q:w=0.6:g=-6,equalizer=f=33:t=q:w=0.44:g=-10 [out]; [out] alimiter=level_in=1:level_out=1:limit=0.5:attack=5:release=20:level=disabled", "-c:a", "libvorbis", "-b:a", "64k", "-f", "ogg", "pipe:1"], input=data_bytes.read(), capture_output = True) else: - ffmpeg_result = subprocess.run(["ffmpeg", "-f", "wav", "-i", "pipe:0", "-c:a", "libvorbis", "-b:a", "64k", "-f", "ogg", "pipe:1"], input=response.content, capture_output = True) + ffmpeg_result = subprocess.run(["ffmpeg", "-f", "wav", "-i", "pipe:0", "-c:a", "libvorbis", "-b:a", "64k", "-f", "ogg", "pipe:1"], input= data_bytes.read(), capture_output = True) ffmpeg_metadata_output = ffmpeg_result.stderr.decode() print(f"ffmpeg result size: {len(ffmpeg_result.stdout)} stderr = \n{ffmpeg_metadata_output}") - - + export_audio = io.BytesIO(ffmpeg_result.stdout) + if "radio" in special_filters: + radio_audio = pydub.AudioSegment.from_file(random.choice(radio_starts), "wav") + radio_audio += pydub.AudioSegment.from_file(io.BytesIO(ffmpeg_result.stdout), "ogg") + radio_audio += pydub.AudioSegment.from_file(random.choice(radio_ends), "wav") + new_data_bytes = io.BytesIO() + radio_audio.export(new_data_bytes, format="ogg") + export_audio = io.BytesIO(new_data_bytes.getvalue()) matched_length = re.search(r"time=([0-9:\\.]+)", ffmpeg_metadata_output) hh_mm_ss = matched_length.group(1) length = hhmmss_to_seconds(hh_mm_ss) - response = send_file(io.BytesIO(ffmpeg_result.stdout), as_attachment=True, download_name='identifier.ogg', mimetype="audio/ogg") + response = send_file(export_audio, as_attachment=True, download_name='identifier.ogg', mimetype="audio/ogg") response.headers['audio-length'] = length return response @@ -51,12 +75,15 @@ def text_to_speech_normal(): voice = request.args.get("voice", '') text = request.json.get("text", '') pitch = request.args.get("pitch", '') - silicon = request.args.get("silicon", '') + special_filters = request.args.get("special_filters", '') if pitch == "": pitch = "0" + silicon = request.args.get("silicon", '') + if silicon: + special_filters = ["silicon"] filter_complex = request.args.get("filter", '') - return text_to_speech_handler("generate-tts", voice, text, filter_complex, pitch, bool(silicon)) + return text_to_speech_handler("generate-tts", voice, text, filter_complex, pitch, special_filters) @app.route("/tts-blips") def text_to_speech_blips(): @@ -66,12 +93,13 @@ def text_to_speech_blips(): voice = request.args.get("voice", '') text = request.json.get("text", '') pitch = request.args.get("pitch", '') - silicon = request.args.get("silicon", '') + special_filters = request.args.get("special_filters", '') if pitch == "": pitch = "0" + special_filters = special_filters.split("|") filter_complex = request.args.get("filter", '') - return text_to_speech_handler("generate-tts-blips", voice, text, filter_complex, pitch, bool(silicon)) + return text_to_speech_handler("generate-tts-blips", voice, text, filter_complex, pitch, special_filters) @@ -80,7 +108,7 @@ def voices_list(): if authorization_token != request.headers.get("Authorization", ""): abort(401) - response = requests.get(f"http://tts-container:5003/tts-voices") + response = requests.get(f"http://127.0.0.1:5003/tts-voices") return response.content @app.route("/health-check") @@ -93,7 +121,7 @@ def pitch_available(): if authorization_token != request.headers.get("Authorization", ""): abort(401) - response = requests.get(f"http://tts-container:5003/pitch-available") + response = requests.get(f"http://127.0.0.1:5003/pitch-available") if response.status_code != 200: abort(500) return make_response("Pitch available", 200) From b6c718b4ff39b4bb36a20f210ed8c532fd18457d Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:33:01 +0200 Subject: [PATCH 31/47] Automatic changelog for PR #23936 [ci skip] --- html/changelogs/AutoChangeLog-pr-23936.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23936.yml diff --git a/html/changelogs/AutoChangeLog-pr-23936.yml b/html/changelogs/AutoChangeLog-pr-23936.yml new file mode 100644 index 00000000000..b265a2cf070 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23936.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "Fixed job configs not being loaded properly." \ No newline at end of file From e34e5321df1edb3a1baa8bf52dfd9668496d097e Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:33:25 +0200 Subject: [PATCH 32/47] Automatic changelog for PR #23944 [ci skip] --- html/changelogs/AutoChangeLog-pr-23944.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23944.yml diff --git a/html/changelogs/AutoChangeLog-pr-23944.yml b/html/changelogs/AutoChangeLog-pr-23944.yml new file mode 100644 index 00000000000..ac638cd598c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23944.yml @@ -0,0 +1,4 @@ +author: "Tattle" +delete-after: True +changes: + - qol: "drones now have individual names, instead of just \"drone\"" \ No newline at end of file From 49d2a5e3654a97b779ccc9d190f3b7d70911de54 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:33:36 +0200 Subject: [PATCH 33/47] Automatic changelog for PR #23945 [ci skip] --- html/changelogs/AutoChangeLog-pr-23945.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23945.yml diff --git a/html/changelogs/AutoChangeLog-pr-23945.yml b/html/changelogs/AutoChangeLog-pr-23945.yml new file mode 100644 index 00000000000..44fb93a1aab --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23945.yml @@ -0,0 +1,6 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "You can no longer break the game by AI rolling in a card or APC" + - qol: "AI Roll now doesnt require you to click the exact turf to move you" + - qol: "AI roll cooldown and roll time is now a variable, making it possible for AIs to become terrifying catamari damacy balls" \ No newline at end of file From b881e3dff0c87679332f4909bcf5890d4634d130 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:34:00 +0200 Subject: [PATCH 34/47] Automatic changelog for PR #23946 [ci skip] --- html/changelogs/AutoChangeLog-pr-23946.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23946.yml diff --git a/html/changelogs/AutoChangeLog-pr-23946.yml b/html/changelogs/AutoChangeLog-pr-23946.yml new file mode 100644 index 00000000000..ca5b631f216 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23946.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "The flight potion wings will no longer fail to work on lavaland/icemoon on rare occasions." \ No newline at end of file From 3831f990579b1aef3865a49e82f586c201f4c1b1 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:34:17 +0200 Subject: [PATCH 35/47] Automatic changelog for PR #23947 [ci skip] --- html/changelogs/AutoChangeLog-pr-23947.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23947.yml diff --git a/html/changelogs/AutoChangeLog-pr-23947.yml b/html/changelogs/AutoChangeLog-pr-23947.yml new file mode 100644 index 00000000000..58f4e3bc782 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23947.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "Fixes full advanced surgery trays spawning with 'nothing'" \ No newline at end of file From 24a5a019a3c8ee7fd154a939325ad29699c13d1e Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:34:32 +0200 Subject: [PATCH 36/47] Automatic changelog for PR #23948 [ci skip] --- html/changelogs/AutoChangeLog-pr-23948.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23948.yml diff --git a/html/changelogs/AutoChangeLog-pr-23948.yml b/html/changelogs/AutoChangeLog-pr-23948.yml new file mode 100644 index 00000000000..952322c4f48 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23948.yml @@ -0,0 +1,8 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "Fixed zombies being able to infect headless corpses (Including former zombies)" + - bugfix: "Fixed bio armor being totally useless against zombies. Now it checks how hurt your limb is: If it's more than the bio armor value, you get infected. THICKMATERIAL clothing guarantees at least 25 damage required to infect you, non-thick clothing reduces effective defence by 25. In practice this means people with MODsuits, biosuits will resist infection unless they're pummeled into crit, and wearing a firesuit will save you from the first few slashes." + - bugfix: "Fixed the bomb hood armor not having the same bio armor value as bomb armor." + - qol: "Added a message to the zed when they succesfully infect someone." + - code_imp: "Turned some proc names into snake_case rather than, uh, nospacecase." \ No newline at end of file From 8b3ead3f4a32862d4535cdbf99e3c6e5795ba334 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:34:38 +0200 Subject: [PATCH 37/47] Automatic changelog for PR #23949 [ci skip] --- html/changelogs/AutoChangeLog-pr-23949.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23949.yml diff --git a/html/changelogs/AutoChangeLog-pr-23949.yml b/html/changelogs/AutoChangeLog-pr-23949.yml new file mode 100644 index 00000000000..1d7a5574c83 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23949.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - spellcheck: "Tweaks the message that players get when not being able to qualify for roundstart antag to be more accurate as to what's happening." \ No newline at end of file From 95118a3dad7f15c01b97ddd9c550a44ce973fa1b Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:35:03 +0200 Subject: [PATCH 38/47] Automatic changelog for PR #23941 [ci skip] --- html/changelogs/AutoChangeLog-pr-23941.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23941.yml diff --git a/html/changelogs/AutoChangeLog-pr-23941.yml b/html/changelogs/AutoChangeLog-pr-23941.yml new file mode 100644 index 00000000000..88dc26d7d6e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23941.yml @@ -0,0 +1,6 @@ +author: "SkyratBot" +delete-after: True +changes: + - rscdel: "removes surgical duffelbags" + - bugfix: "the surgery supply order now comes with a surgery tray" + - bugfix: "(skyrat) Hospital gowns will now spawn in surgery trays like they used to in the surgery duffelbags" \ No newline at end of file From 9b2ea7fd2dde0fc0a86064060314bb0fdddba4f6 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:35:05 +0200 Subject: [PATCH 39/47] Automatic changelog for PR #23942 [ci skip] --- html/changelogs/AutoChangeLog-pr-23942.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23942.yml diff --git a/html/changelogs/AutoChangeLog-pr-23942.yml b/html/changelogs/AutoChangeLog-pr-23942.yml new file mode 100644 index 00000000000..ef1193e0ee7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23942.yml @@ -0,0 +1,7 @@ +author: "SkyratBot" +delete-after: True +changes: + - qol: "Gas masks now muffle your voice with TTS." + - qol: "Security Hailer masks now disguise your voice to protect your right to brutalize greytiders." + - qol: "Lizards, Ethereals, and Xenomorphs now have a vocal effect." + - qol: "Security Records now show someone's voice name." \ No newline at end of file From f5781b2aa14903d5f54b006658a96304998bacb4 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:41:08 +0200 Subject: [PATCH 40/47] [MIRROR] Add new sounds for animals, basic animals make sound on audible emote [MDB IGNORE] (#23917) * Add new sounds for animals, basic animals make sound on audible emote (#78499) ## About The Pull Why It's Good For The Game Request More sound immersion. Also just makes sense for sounds to play when an animal is both saying something and using an audible emote. Crab click: https://freesound.org/people/JarredGibb/sounds/263882/ Chitter: https://freesound.org/people/ForSoundDesign/sounds/687302/ Chicks: https://pixabay.com/sound-effects/chicks-very-young-56075/ Chicken: https://freesound.org/people/Breviceps/sounds/456803/ https://github.com/tgstation/tgstation/assets/66640614/29cd4e8e-b9c3-4f71-be0d-8c3f3de40eba https://github.com/tgstation/tgstation/assets/66640614/9a24c1a8-0707-43ad-adec-b7ce1eddb5f6 https://github.com/tgstation/tgstation/assets/66640614/21cc37ae-c49c-461a-83c5-271f6d577fc6 ## Changelog :cl: tattle qol: Basic animals now make sounds for audible emotes sound: Added new sound effects for chicks, chickens, crabs, and insects /:cl: Co-authored-by: tattle * Add new sounds for animals, basic animals make sound on audible emote * Sound path changes --------- Co-authored-by: tattle <66640614+dragomagol@users.noreply.github.com> Co-authored-by: tattle Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com> --- .../basic_subtrees/speech_subtree.dm | 23 +++++++++++++----- code/datums/ai/generic/generic_behaviors.dm | 4 ++- .../dna_infuser/organ_sets/rat_organs.dm | 2 +- code/modules/events/mice_migration.dm | 2 +- code/modules/mob/living/basic/vermin/mouse.dm | 2 +- .../game/objects/items/plushes.dm | 4 +-- modular_skyrat/modules/emotes/code/emotes.dm | 2 +- sound/creatures/bagawk.ogg | Bin 0 -> 9230 bytes sound/creatures/chick_peep.ogg | Bin 0 -> 4870 bytes sound/creatures/chitter.ogg | Bin 0 -> 9014 bytes sound/creatures/claw_click.ogg | Bin 0 -> 10330 bytes sound/creatures/clucks.ogg | Bin 0 -> 12384 bytes sound/{effects => creatures}/mousesqueek.ogg | Bin sound/creatures/pony/snort.ogg | Bin 10443 -> 10519 bytes 14 files changed, 26 insertions(+), 13 deletions(-) create mode 100644 sound/creatures/bagawk.ogg create mode 100644 sound/creatures/chick_peep.ogg create mode 100644 sound/creatures/chitter.ogg create mode 100644 sound/creatures/claw_click.ogg create mode 100644 sound/creatures/clucks.ogg rename sound/{effects => creatures}/mousesqueek.ogg (100%) 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 8340d1da4d3..e040a566bcf 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm @@ -31,15 +31,19 @@ var/random_number_in_range = rand(1, total_choices_length) + // Sound that plays when the mob does something audible + 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)) + 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), length(sound) > 0 ? pick(sound) : null) + 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 +53,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 +98,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 +167,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.") diff --git a/code/datums/ai/generic/generic_behaviors.dm b/code/datums/ai/generic/generic_behaviors.dm index e7bfe7a7c60..fd6d848f2d6 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 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/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/mob/living/basic/vermin/mouse.dm b/code/modules/mob/living/basic/vermin/mouse.dm index 0b3645b3e0f..9e8f1b8df55 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), ) 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/emotes/code/emotes.dm b/modular_skyrat/modules/emotes/code/emotes.dm index 0d1e549037f..532373f9567 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/sound/creatures/bagawk.ogg b/sound/creatures/bagawk.ogg new file mode 100644 index 0000000000000000000000000000000000000000..bfdce2da4894b4e78df42e37972d006e999c0d68 GIT binary patch literal 9230 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
  • n7p|vC*EGKz zTmH#&=<}uSdC_4pm71YtKpw!7HX-CtU5iAQvY$Do(^X*YRA|RD`{ua$gGdEYiYY^7 z*E(y_?;&^dJ~y{)-uG$X%D(EA9iD2@SaiO^E4RPwPRVtW@4fP?h6uHF_h0V}AMuUv zhS!wjHEAcV)s(yU682KOs+Vbdsc~6UvQX93*3)ES{-o8kq>iBHsSYX!t{P%iT`dAE zuRmPdyF2#GsmX-h_l8lAaqSzCIJHIVU+C%2h0_eeO$!3&)|QnjwzG@Wth@v&s(1Q6 zp5hCCd~&PYukrd{ggpjWI8r)+} z3>Mj_eK_GzgJu|SRKH)_5GXO>4?FoT?px+DbH>K|mO&!n$XCS4jaBi~;)yd4wlsVD)raKviZtvpP3kBv8v|V5a zbK;98Eb(rqgpVsfwj6(If&js7-6`2ScM29JXIB!R(eZ0N3;!^8{~%?zaXaZP z=fxXUKiO2?zUUf^DAF!>!GxVFy7Gyv*@|@@{|NbpA8}prvouEc)s2AeIb<}6tS6YT z+1qq9Gq0xzVUZ%%slA(LHcQh~Ze8ExoA;h@E^n?My!-Xc_nY(V3Lk%zT4?dvm9a^q ndLqxhpndg2;(TsLLb2Ygq*B774aQLQkejes5+D|%#Owb6UxJ>X literal 0 HcmV?d00001 diff --git a/sound/creatures/chick_peep.ogg b/sound/creatures/chick_peep.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1e84d1d765fd8523cd1ffcde054c7cead578c40c GIT binary patch literal 4870 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 delta 7158 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 Date: Wed, 27 Sep 2023 08:41:26 +0200 Subject: [PATCH 41/47] [MIRROR] Prevent things from the feature list generating on turfs with flora [MDB IGNORE] (#23950) * Prevent things from the feature list generating on turfs with flora (#78558) ## About The Pull Request which basically means no geysers on the same turf as a plant turf. they're both structures but the for loop before this one checks for same-type structures in a radius. and bush geysers look stupid! and weird! and stupid! ## Changelog :cl: fix: fixed geysers spawning on turfs with plants /:cl: * Prevent things from the feature list generating on turfs with flora --------- Co-authored-by: Sealed101 --- code/datums/mapgen/CaveGenerator.dm | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/code/datums/mapgen/CaveGenerator.dm b/code/datums/mapgen/CaveGenerator.dm index 48df6e164fb..8cb240526a4 100644 --- a/code/datums/mapgen/CaveGenerator.dm +++ b/code/datums/mapgen/CaveGenerator.dm @@ -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 From 32715baa90a98aae248aa0cf5ec8aaceae982d4b Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:41:34 +0200 Subject: [PATCH 42/47] Automatic changelog for PR #23917 [ci skip] --- html/changelogs/AutoChangeLog-pr-23917.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23917.yml diff --git a/html/changelogs/AutoChangeLog-pr-23917.yml b/html/changelogs/AutoChangeLog-pr-23917.yml new file mode 100644 index 00000000000..84125eca8ed --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23917.yml @@ -0,0 +1,5 @@ +author: "tattle" +delete-after: True +changes: + - qol: "Basic animals now make sounds for audible emotes" + - sound: "Added new sound effects for chicks, chickens, crabs, and insects" \ No newline at end of file From 06020cbc2b2ff50d1b74c81f46c3c9332ea48098 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:42:06 +0200 Subject: [PATCH 43/47] Automatic changelog for PR #23950 [ci skip] --- html/changelogs/AutoChangeLog-pr-23950.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23950.yml diff --git a/html/changelogs/AutoChangeLog-pr-23950.yml b/html/changelogs/AutoChangeLog-pr-23950.yml new file mode 100644 index 00000000000..b4ec81b4207 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23950.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "fixed geysers spawning on turfs with plants" \ No newline at end of file From 1257fb2942448891a82ad5f93a901b4c8d1cee4d Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 10:38:41 +0200 Subject: [PATCH 44/47] [MIRROR] exodrone travel time balance, grammar, fixes and tweaks [MDB IGNORE] (#23952) * exodrone travel time balance, grammar, fixes and tweaks (#78378) Exodrones fixes and balance * exodrone travel time balance, grammar, fixes and tweaks --------- Co-authored-by: jimmyl <70376633+mc-oofert@users.noreply.github.com> --- .../modules/explorer_drone/control_console.dm | 2 +- .../Theres_a_tree_in_the_middle_of_space.json | 697 +++++++++--------- code/modules/explorer_drone/exodrone.dm | 13 +- code/modules/explorer_drone/scanner_array.dm | 41 +- icons/obj/exploration.dmi | Bin 6926 -> 7575 bytes 5 files changed, 398 insertions(+), 355 deletions(-) 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,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" - }, - { - "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,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" - }, - { - "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,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" - }, - { - "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,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" + }, + { + "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,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" + }, + { + "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/icons/obj/exploration.dmi b/icons/obj/exploration.dmi index 2f9d004bee2c398860ea376e13058c25ada4bf33..b7224d2df84d91a5603270b9f00b638615c19282 100644 GIT binary patch literal 7575 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 P3Ou;4r}0_MF8cofsC(2? literal 6926 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 From 447a087c06a25d1763642a28f5ee4861bef7ceac Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 10:39:13 +0200 Subject: [PATCH 45/47] Automatic changelog for PR #23952 [ci skip] --- html/changelogs/AutoChangeLog-pr-23952.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23952.yml diff --git a/html/changelogs/AutoChangeLog-pr-23952.yml b/html/changelogs/AutoChangeLog-pr-23952.yml new file mode 100644 index 00000000000..0e3a4edd7b7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23952.yml @@ -0,0 +1,11 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "you can now deconstruct exodrone scanner arrays" + - bugfix: "the tree in space exodrone adventure no longer softlocks you" + - qol: "the exodrone launchers now tell you on examine how to remove their fuel canister if you somehow needed to do that" + - balance: "exodrone wide scans are now capped at 10 minutes" + - balance: "exodrone travel times are 18% faster" + - balance: "you can now upgrade scanner arrays for faster wide scan" + - balance: "exodrone point scan and deep scan are faster" + - spellcheck: "fixes several typos related to exodrones and gives scanner control console a description" \ No newline at end of file From cba230cd8a8c1683e4a2f622593218f744737730 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 14:38:19 +0200 Subject: [PATCH 46/47] [MIRROR] Fixes a runtime in seed extractor when seeds do not have a product [MDB IGNORE] (#23954) * Fixes a runtime in seed extractor when seeds do not have a product * Fixing diffs --------- Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> --- code/modules/hydroponics/grown/replicapod.dm | 2 +- code/modules/hydroponics/seed_extractor.dm | 102 ++++++++++--------- 2 files changed, 56 insertions(+), 48 deletions(-) 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) From c142557087a84dfe9a94f59e40af345543b953e6 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 27 Sep 2023 14:38:47 +0200 Subject: [PATCH 47/47] Automatic changelog for PR #23954 [ci skip] --- html/changelogs/AutoChangeLog-pr-23954.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-23954.yml diff --git a/html/changelogs/AutoChangeLog-pr-23954.yml b/html/changelogs/AutoChangeLog-pr-23954.yml new file mode 100644 index 00000000000..4a5081737a9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23954.yml @@ -0,0 +1,7 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "Seeds will no longer be removed from existence after receiving the \"You can't seem to add [seed type] to the seed extractor\" message" + - bugfix: "Some seeds that were previously not able to be added to the seed extractor may now be added (starthistle for example)" + - bugfix: "fixes replica pod seeds spawning humans in nullspace" + - qol: "right clicking the seed extractor with a plant/food stores the extracted seeds in the machine." \ No newline at end of file