diff --git a/code/__HELPERS/paths/path.dm b/code/__HELPERS/paths/path.dm index 14241ef8e706..3b674fdc7afb 100644 --- a/code/__HELPERS/paths/path.dm +++ b/code/__HELPERS/paths/path.dm @@ -297,6 +297,8 @@ var/incapacitated = FALSE /// Is our mob incorporeal var/incorporeal_move = FALSE + /// is our mob a xenofauna or slime + var/xenofauna_or_slime = FALSE /// If our mob has a rider, what does it look like var/datum/can_pass_info/rider_info = null /// If our mob is buckled to something, what's it like @@ -346,6 +348,9 @@ src.can_ventcrawl = HAS_TRAIT(living_construct, TRAIT_VENTCRAWLER_ALWAYS) || HAS_TRAIT(living_construct, TRAIT_VENTCRAWLER_NUDE) src.mob_size = living_construct.mob_size src.incorporeal_move = living_construct.incorporeal_move + if(istype(living_construct, /mob/living/basic/slime) || istype(living_construct, /mob/living/basic/xenofauna)) + src.xenofauna_or_slime = TRUE + if(iscameramob(construct_from)) src.camera_type = construct_from.type src.is_bot = isbot(construct_from) diff --git a/code/datums/ai/_ai_controller.dm b/code/datums/ai/_ai_controller.dm index 0a63e31edc9c..b1b44d50ec78 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 2b734ca24a92..0be133279f7e 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? As of writing this, MOVELOOP_SKIP_STEP is defined as (1<<0) so be careful on using (return TRUE) or (can_move = TRUE; return can_move) /datum/ai_movement/proc/allowed_to_move(datum/move_loop/source) var/atom/movable/pawn = source.moving @@ -58,7 +61,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/monkestation/code/modules/slimecore/corral/machines/corral_corner.dm b/monkestation/code/modules/slimecore/corral/machines/corral_corner.dm index 2dc9a024df3b..28dc28702176 100644 --- a/monkestation/code/modules/slimecore/corral/machines/corral_corner.dm +++ b/monkestation/code/modules/slimecore/corral/machines/corral_corner.dm @@ -170,6 +170,7 @@ icon = 'monkestation/code/modules/slimecore/icons/machinery.dmi' icon_state = "corral_fence" can_atmos_pass = ATMOS_PASS_NO + can_astar_pass = CANASTARPASS_ALWAYS_PROC /obj/effect/corral_fence/CanPass(atom/movable/mover, border_dir) . = ..() @@ -178,3 +179,9 @@ if((istype(mover, /mob/living/basic/slime) || ismonkey(mover) || istype(mover, /mob/living/basic/xenofauna)) && !HAS_TRAIT(mover, VACPACK_THROW)) return FALSE return TRUE + + +/obj/effect/corral_fence/CanAStarPass(to_dir, datum/can_pass_info/pass_info) + if(pass_info.xenofauna_or_slime) + return FALSE + return TRUE //anything expect slimes can astar pass diff --git a/monkestation/code/modules/slimecore/mobs/ai_controller/controller.dm b/monkestation/code/modules/slimecore/mobs/ai_controller/controller.dm index 4b7a9631d226..c171a1eaf482 100644 --- a/monkestation/code/modules/slimecore/mobs/ai_controller/controller.dm +++ b/monkestation/code/modules/slimecore/mobs/ai_controller/controller.dm @@ -7,7 +7,7 @@ BB_WONT_TARGET_CLIENTS = FALSE, //specifically to stop targetting clients ) - ai_movement = /datum/ai_movement/basic_avoidance + ai_movement = /datum/ai_movement/jps_slime idle_behavior = /datum/idle_behavior/idle_slime_playful planning_subtrees = list( //we try to flee first these flip flop based on flee state which is controlled by a componenet on the mob @@ -17,3 +17,34 @@ /datum/ai_planning_subtree/simple_find_target_no_trait/slime, /datum/ai_planning_subtree/basic_melee_attack_subtree/slime, ) + + +/datum/ai_movement/jps_slime + max_pathing_attempts = 20 + +/datum/ai_movement/jps_slime/start_moving_towards(datum/ai_controller/controller, atom/current_movement_target, min_distance) + . = ..() + var/atom/movable/moving = controller.pawn + var/delay = controller.movement_delay + + var/datum/move_loop/loop = SSmove_manager.jps_move(moving, + current_movement_target, + delay, + repath_delay = 0.1 SECONDS, + max_path_length = AI_MAX_PATH_LENGTH * 3, + minimum_distance = controller.get_minimum_distance(), + access = controller.get_access(), + subsystem = SSai_movement, + extra_info = controller, + ) + + RegisterSignal(loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move)) + RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_move)) + RegisterSignal(loop, COMSIG_MOVELOOP_JPS_REPATH, PROC_REF(repath_incoming)) + +/datum/ai_movement/jps_slime/proc/repath_incoming(datum/move_loop/has_target/jps/source) + SIGNAL_HANDLER + var/datum/ai_controller/controller = source.extra_info + + source.access = controller.get_access() + source.minimum_distance = controller.get_minimum_distance()