From 8dc3fb19f2ae54478c65a6e80913ea562e28a030 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Sat, 14 Jan 2023 18:14:53 +0000 Subject: [PATCH] Some tweaks to mobs running away (#72529) ## About The Pull Request Mice running away behaviour wasn't working quite how it was supposed to due to a couple of bugs. First of all, the action was written as if it would `perform` every tick, which it doesn't. This means that the code checking if you had left line of sight didn't function, meaning mobs would continue fleeing you even when they couldn't see you any more. Secondly, mobs spent an awful lot of time pathing into walls which was especially noticeable on mice who just would _not_ stop repeatedly squeaking in a way that is kind of funny but gets old when you keep hearing it. Now the pathing stops if it hits a barrier. I'm not... totally fond of this solution because it has a few assumptions baked in (that we want to try and path through doors even if they're dense for one) but I can't for the moment think of a better "path away from" implementation that isn't way more complicated, and this doesn't really need to be complicated. For good measure I noticed a couple of other actions weren't passing a `source_atom` into `is_blocked_turf` so rats were potentially attacking "obstacles" they could simply walk over. Additionally a couple of places were setting `controller.movement_target` directly instead of using the helper method which has a minor risk of runtiming under certain conditions. ## Why It's Good For The Game Mice will stop constantly screaming if they can see someone, and should repath once they have a different escape route more quickly rather than dedicating themselves to trying to burrow through an iron wall. Rats won't bite at tables and racks they can just climb over. ## Changelog :cl: fix: Mice won't try to path through walls to escape from sight and constantly squeak. fix: Mice will stop running away from you if they can't see you any more. fix: Rats won't bite racks and tables while passing over them. /:cl: --- code/datums/ai/babies/babies_behaviors.dm | 2 +- .../run_away_from_target.dm | 22 ++++++++++++++----- .../basic_subtrees/attack_obstacle_in_path.dm | 4 ++-- .../pet_commands/pet_follow_friend.dm | 2 +- .../pet_commands/pet_use_targetted_ability.dm | 2 +- 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/code/datums/ai/babies/babies_behaviors.dm b/code/datums/ai/babies/babies_behaviors.dm index c1269001e9b..6517aebb4c1 100644 --- a/code/datums/ai/babies/babies_behaviors.dm +++ b/code/datums/ai/babies/babies_behaviors.dm @@ -53,7 +53,7 @@ var/atom/target = weak_target?.resolve() if(!target) return FALSE - controller.current_movement_target = target + set_movement_target(controller, target) return TRUE /datum/ai_behavior/make_babies/perform(delta_time, datum/ai_controller/controller, target_key, child_types_key) diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm index 2a3232e8186..ccc58d9f0a9 100644 --- a/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm +++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm @@ -2,7 +2,7 @@ /datum/ai_behavior/run_away_from_target required_distance = 0 action_cooldown = 0 - behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION + behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION /// How far do we try to run? Further makes for smoother running, but potentially weirder pathfinding var/run_distance = 9 @@ -11,8 +11,8 @@ var/atom/target = weak_target?.resolve() if(!target) return FALSE - - plot_path_away_from(controller, target) + if(!plot_path_away_from(controller, target)) + return FALSE return ..() /datum/ai_behavior/run_away_from_target/perform(delta_time, datum/ai_controller/controller, target_key, hiding_location_key) @@ -23,14 +23,24 @@ if (escaped) finish_action(controller, succeeded = TRUE, target_key = target_key, hiding_location_key = hiding_location_key) return - if (!in_range(controller.pawn, controller.current_movement_target)) + if (get_dist(controller.pawn, controller.current_movement_target) > required_distance) return - plot_path_away_from(controller, target) + if(plot_path_away_from(controller, target)) + return + finish_action(controller, succeeded = FALSE, target_key = target_key, hiding_location_key = hiding_location_key) /datum/ai_behavior/run_away_from_target/proc/plot_path_away_from(datum/ai_controller/controller, atom/target) var/run_direction = get_dir(controller.pawn, get_step_away(controller.pawn, target)) - var/turf/target_destination = get_ranged_target_turf(controller.pawn, run_direction, run_distance) + var/turf/target_destination = get_turf(controller.pawn) + for (var/i in 1 to run_distance) + var/turf/test_destination = get_ranged_target_turf(controller.pawn, run_direction, i) + if (test_destination.is_blocked_turf(exclude_mobs = TRUE, source_atom = controller.pawn, ignore_atoms = GLOB.airlocks)) + break + target_destination = test_destination + if (target_destination == get_turf(controller.pawn)) + return FALSE set_movement_target(controller, target_destination) + return TRUE /datum/ai_behavior/run_away_from_target/finish_action(datum/ai_controller/controller, succeeded, target_key, hiding_location_key) . = ..() diff --git a/code/datums/ai/basic_mobs/basic_subtrees/attack_obstacle_in_path.dm b/code/datums/ai/basic_mobs/basic_subtrees/attack_obstacle_in_path.dm index 7943e463074..b2496b15e2f 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/attack_obstacle_in_path.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/attack_obstacle_in_path.dm @@ -14,7 +14,7 @@ return var/turf/next_step = get_step_towards(controller.pawn, target) - if (!next_step.is_blocked_turf(exclude_mobs = TRUE)) + if (!next_step.is_blocked_turf(exclude_mobs = TRUE, source_atom = controller.pawn)) return controller.queue_behavior(attack_behaviour, target_key) @@ -56,7 +56,7 @@ /datum/ai_behavior/attack_obstructions/proc/attack_in_direction(datum/ai_controller/controller, mob/living/basic/basic_mob, direction) var/turf/next_step = get_step(basic_mob, direction) - if (!next_step.is_blocked_turf(exclude_mobs = TRUE)) + if (!next_step.is_blocked_turf(exclude_mobs = TRUE, source_atom = controller.pawn)) return FALSE for (var/obj/object as anything in next_step.contents) diff --git a/code/datums/ai/basic_mobs/pet_commands/pet_follow_friend.dm b/code/datums/ai/basic_mobs/pet_commands/pet_follow_friend.dm index 244a10332b0..0af3c1d3591 100644 --- a/code/datums/ai/basic_mobs/pet_commands/pet_follow_friend.dm +++ b/code/datums/ai/basic_mobs/pet_commands/pet_follow_friend.dm @@ -8,7 +8,7 @@ var/atom/target = weak_target?.resolve() if (!target) return FALSE - controller.current_movement_target = target + set_movement_target(controller, target) /datum/ai_behavior/pet_follow_friend/perform(delta_time, datum/ai_controller/controller, target_key) . = ..() diff --git a/code/datums/ai/basic_mobs/pet_commands/pet_use_targetted_ability.dm b/code/datums/ai/basic_mobs/pet_commands/pet_use_targetted_ability.dm index 3e8f1246e1c..6cd6458cc29 100644 --- a/code/datums/ai/basic_mobs/pet_commands/pet_use_targetted_ability.dm +++ b/code/datums/ai/basic_mobs/pet_commands/pet_use_targetted_ability.dm @@ -8,7 +8,7 @@ var/mob/living/target = weak_target?.resolve() if (QDELETED(target)) return FALSE - controller.current_movement_target = target + set_movement_target(controller, target) /datum/ai_behavior/pet_use_ability/perform(delta_time, datum/ai_controller/controller, ability_key, target_key) var/datum/action/cooldown/mob_cooldown/ability = controller.blackboard[ability_key]