diff --git a/code/__DEFINES/ai/ai.dm b/code/__DEFINES/ai/ai.dm index 73a8f2d1900..c91f7eb0659 100644 --- a/code/__DEFINES/ai/ai.dm +++ b/code/__DEFINES/ai/ai.dm @@ -11,6 +11,12 @@ ///The AI is currently in idle mode. #define AI_STATUS_IDLE "ai_idle" +//Flags returned by get_able_to_run() +///pauses AI processing +#define AI_UNABLE_TO_RUN (1<<1) +///bypass canceling our actions on set_ai_status() +#define AI_PREVENT_CANCEL_ACTIONS (1<<2) + ///For JPS pathing, the maximum length of a path we'll try to generate. Should be modularized depending on what we're doing later on #define AI_MAX_PATH_LENGTH 30 // 30 is possibly overkill since by default we lose interest after 14 tiles of distance, but this gives wiggle room for weaving around obstacles #define AI_BOT_PATH_LENGTH 75 diff --git a/code/datums/ai/_ai_controller.dm b/code/datums/ai/_ai_controller.dm index 65e3acf5f6f..07e3851a1ae 100644 --- a/code/datums/ai/_ai_controller.dm +++ b/code/datums/ai/_ai_controller.dm @@ -317,18 +317,21 @@ multiple modular subtrees with behaviors /datum/ai_controller/proc/update_able_to_run() SIGNAL_HANDLER - able_to_run = get_able_to_run() - if(!able_to_run) + var/run_flags = get_able_to_run() + if(run_flags & AI_UNABLE_TO_RUN) + able_to_run = FALSE GLOB.move_manager.stop_looping(pawn) //stop moving - set_ai_status(get_expected_ai_status()) + else + able_to_run = TRUE + set_ai_status(get_expected_ai_status(), run_flags) ///Returns TRUE if the ai controller can actually run at the moment, FALSE otherwise /datum/ai_controller/proc/get_able_to_run() if(HAS_TRAIT(pawn, TRAIT_AI_PAUSED)) - return FALSE + return AI_UNABLE_TO_RUN if(world.time < paused_until) - return FALSE - return TRUE + return AI_UNABLE_TO_RUN + return NONE ///Can this pawn interact with objects? /datum/ai_controller/proc/ai_can_interact() @@ -415,7 +418,7 @@ multiple modular subtrees with behaviors forgotten_behavior.finish_action(arglist(arguments)) ///This proc handles changing ai status, and starts/stops processing if required. -/datum/ai_controller/proc/set_ai_status(new_ai_status) +/datum/ai_controller/proc/set_ai_status(new_ai_status, additional_flags = NONE) if(ai_status == new_ai_status) return FALSE //no change @@ -427,7 +430,8 @@ multiple modular subtrees with behaviors ai_status = new_ai_status GLOB.ai_controllers_by_status[new_ai_status] += src if(ai_status == AI_STATUS_OFF) - CancelActions() + if(!(additional_flags & AI_PREVENT_CANCEL_ACTIONS)) + CancelActions() return if(!length(current_behaviors)) add_to_unplanned_controllers() diff --git a/code/datums/ai/bane/bane_controller.dm b/code/datums/ai/bane/bane_controller.dm index 64e1dcf31af..580e80440a4 100644 --- a/code/datums/ai/bane/bane_controller.dm +++ b/code/datums/ai/bane/bane_controller.dm @@ -27,5 +27,5 @@ And the only victory you achieved was a lie. Now you understand Gotham is beyond /datum/ai_controller/bane/get_able_to_run() var/mob/living/living_pawn = pawn if(IS_DEAD_OR_INCAP(living_pawn)) - return FALSE + return AI_UNABLE_TO_RUN return ..() diff --git a/code/datums/ai/basic_mobs/base_basic_controller.dm b/code/datums/ai/basic_mobs/base_basic_controller.dm index 7ab15437f7d..eb1c38437e3 100644 --- a/code/datums/ai/basic_mobs/base_basic_controller.dm +++ b/code/datums/ai/basic_mobs/base_basic_controller.dm @@ -30,17 +30,17 @@ /datum/ai_controller/basic_controller/get_able_to_run() . = ..() - if(!.) - return FALSE + if(. & AI_UNABLE_TO_RUN) + return . var/mob/living/living_pawn = pawn if(!(ai_traits & CAN_ACT_WHILE_DEAD)) // Unroll for flags here if (ai_traits & CAN_ACT_IN_STASIS && (living_pawn.stat || INCAPACITATED_IGNORING(living_pawn, INCAPABLE_STASIS))) - return FALSE - else if(IS_DEAD_OR_INCAP(living_pawn)) - return FALSE + return AI_UNABLE_TO_RUN + if(IS_DEAD_OR_INCAP(living_pawn)) + return AI_UNABLE_TO_RUN if(ai_traits & PAUSE_DURING_DO_AFTER && LAZYLEN(living_pawn.do_afters)) - return FALSE + return AI_UNABLE_TO_RUN | AI_PREVENT_CANCEL_ACTIONS //dont erase targets post a do_after /datum/ai_controller/basic_controller/proc/update_speed(mob/living/basic/basic_mob) SIGNAL_HANDLER diff --git a/code/datums/ai/monkey/monkey_controller.dm b/code/datums/ai/monkey/monkey_controller.dm index e92ec519b20..71e3d5f3981 100644 --- a/code/datums/ai/monkey/monkey_controller.dm +++ b/code/datums/ai/monkey/monkey_controller.dm @@ -120,7 +120,7 @@ have ways of interacting with a specific mob and control it. var/mob/living/living_pawn = pawn if(INCAPACITATED_IGNORING(living_pawn, INCAPABLE_RESTRAINTS|INCAPABLE_STASIS|INCAPABLE_GRAB) || living_pawn.stat > CONSCIOUS) - return FALSE + return AI_UNABLE_TO_RUN return ..() /datum/ai_controller/monkey/proc/set_trip_mode(mode = TRUE) diff --git a/code/datums/ai/oldhostile/hostile_tameable.dm b/code/datums/ai/oldhostile/hostile_tameable.dm index 907ab955a8d..92e300d939b 100644 --- a/code/datums/ai/oldhostile/hostile_tameable.dm +++ b/code/datums/ai/oldhostile/hostile_tameable.dm @@ -66,7 +66,7 @@ var/mob/living/living_pawn = pawn if(IS_DEAD_OR_INCAP(living_pawn)) - return FALSE + return AI_UNABLE_TO_RUN return ..() /datum/ai_controller/hostile_friend/get_access() diff --git a/code/modules/mob/living/basic/bots/bot_ai.dm b/code/modules/mob/living/basic/bots/bot_ai.dm index fd89168ddf4..d777614d743 100644 --- a/code/modules/mob/living/basic/bots/bot_ai.dm +++ b/code/modules/mob/living/basic/bots/bot_ai.dm @@ -72,7 +72,7 @@ /datum/ai_controller/basic_controller/bot/get_able_to_run() var/mob/living/basic/bot/bot_pawn = pawn if(!(bot_pawn.bot_mode_flags & BOT_MODE_ON)) - return FALSE + return AI_UNABLE_TO_RUN return ..() /datum/ai_controller/basic_controller/bot/get_access()