From e14a4f52ca87a18e11d5861f2078a73fb23cb2b3 Mon Sep 17 00:00:00 2001 From: Iajret Creature <122297233+Steals-The-PRs@users.noreply.github.com> Date: Sun, 17 Mar 2024 03:15:23 +0300 Subject: [PATCH] [MIRROR] Fix modsuit pathfinder module / JPS changes (#1461) (#2431) * Fix modsuit pathfinder module / JPS changes (#81983) ## About The Pull Request The Pathfinder module sucks cock because it doesn't work. And the reasons it doesn't work are as follows: 1. It uses the default JPS pathfinding datum, which has a hard distance limit of 30, instead of the intended 200. 2. JPS pathfinding as a whole will fail if you encounter more than 3 doors. This is because every door wastes about 5 movement opportunities, and the default pathfinder only has a limit of 20 before it considers the entire pathfinding attempt moot and bails out. Here's how I fixed it: 1. Created a new jps child that has a range of MOD_AI_RANGE 2. Instead of counting all failures during the entire pathfinding attempt, it will only consider consecutive failures. Every successful move will reset the pathfinding failure count. This should make JPS pathfinding more reliable overall? ## Changelog :cl: fix: Modsuit Pathfinder module is significantly better at finding it's destination. /:cl: * Fix modsuit pathfinder module / JPS changes --------- Co-authored-by: NovaBot <154629622+NovaBot13@users.noreply.github.com> Co-authored-by: Kapu1178 <75460809+Kapu1178@users.noreply.github.com> --- code/datums/ai/_ai_controller.dm | 2 +- code/datums/ai/movement/_ai_movement.dm | 16 ++++++++++------ code/datums/ai/movement/ai_movement_jps.dm | 3 +++ code/datums/ai/objects/mod.dm | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/code/datums/ai/_ai_controller.dm b/code/datums/ai/_ai_controller.dm index b525f66576c..91f624972ad 100644 --- a/code/datums/ai/_ai_controller.dm +++ b/code/datums/ai/_ai_controller.dm @@ -34,7 +34,7 @@ multiple modular subtrees with behaviors ///Stored arguments for behaviors given during their initial creation var/list/behavior_args = list() ///Tracks recent pathing attempts, if we fail too many in a row we fail our current plans. - var/pathing_attempts + var/consecutive_pathing_attempts ///Can the AI remain in control if there is a client? var/continue_processing_when_client = FALSE ///distance to give up on target diff --git a/code/datums/ai/movement/_ai_movement.dm b/code/datums/ai/movement/_ai_movement.dm index af29e83f1a4..3f455b2acd0 100644 --- a/code/datums/ai/movement/_ai_movement.dm +++ b/code/datums/ai/movement/_ai_movement.dm @@ -8,22 +8,25 @@ //Override this to setup the moveloop you want to use /datum/ai_movement/proc/start_moving_towards(datum/ai_controller/controller, atom/current_movement_target, min_distance) SHOULD_CALL_PARENT(TRUE) - controller.pathing_attempts = 0 + controller.consecutive_pathing_attempts = 0 controller.set_blackboard_key(BB_CURRENT_MIN_MOVE_DISTANCE, min_distance) moving_controllers[controller] = current_movement_target /datum/ai_movement/proc/stop_moving_towards(datum/ai_controller/controller) - controller.pathing_attempts = 0 + controller.consecutive_pathing_attempts = 0 moving_controllers -= controller // We got deleted as we finished an action if(!QDELETED(controller.pawn)) SSmove_manager.stop_looping(controller.pawn, SSai_movement) /datum/ai_movement/proc/increment_pathing_failures(datum/ai_controller/controller) - controller.pathing_attempts++ - if(controller.pathing_attempts >= max_pathing_attempts) + controller.consecutive_pathing_attempts++ + if(controller.consecutive_pathing_attempts >= max_pathing_attempts) controller.CancelActions() +/datum/ai_movement/proc/reset_pathing_failures(datum/ai_controller/controller) + controller.consecutive_pathing_attempts = 0 + ///Should the movement be allowed to happen? return TRUE if it can, FALSE otherwise /datum/ai_movement/proc/allowed_to_move(datum/move_loop/source) SHOULD_BE_PURE(TRUE) @@ -68,7 +71,8 @@ //Anything to do post movement /datum/ai_movement/proc/post_move(datum/move_loop/source, succeeded) SIGNAL_HANDLER - if(succeeded != FALSE) - return var/datum/ai_controller/controller = source.extra_info + if(succeeded != MOVELOOP_FAILURE) + reset_pathing_failures(controller) + return increment_pathing_failures(controller) diff --git a/code/datums/ai/movement/ai_movement_jps.dm b/code/datums/ai/movement/ai_movement_jps.dm index 6024b7e7562..825feefabfa 100644 --- a/code/datums/ai/movement/ai_movement_jps.dm +++ b/code/datums/ai/movement/ai_movement_jps.dm @@ -51,3 +51,6 @@ /datum/ai_movement/jps/bot/travel_to_beacon maximum_length = AI_BOT_PATH_LENGTH + +/datum/ai_movement/jps/modsuit + maximum_length = MOD_AI_RANGE diff --git a/code/datums/ai/objects/mod.dm b/code/datums/ai/objects/mod.dm index 2bb555d281b..67d8121a4e1 100644 --- a/code/datums/ai/objects/mod.dm +++ b/code/datums/ai/objects/mod.dm @@ -5,7 +5,7 @@ BB_MOD_IMPLANT, ) max_target_distance = MOD_AI_RANGE //a little spicy but its one specific item that summons it, and it doesn't run otherwise - ai_movement = /datum/ai_movement/jps + ai_movement = /datum/ai_movement/jps/modsuit ///ID card generated from the suit's required access. Used for pathing. var/obj/item/card/id/advanced/id_card