port ai controller target handling improvements (#29525)

This commit is contained in:
warriorstar-orion
2025-06-04 11:09:52 +00:00
committed by GitHub
parent a4895a9865
commit b8ec569d4f
+32 -18
View File
@@ -99,8 +99,17 @@ RESTRICT_TYPE(/datum/ai_controller)
/// Sets the current movement target, with an optional param to override the movement behavior
/datum/ai_controller/proc/set_movement_target(source, atom/target, datum/ai_movement/new_movement)
if(current_movement_target)
UnregisterSignal(current_movement_target, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_PREQDELETED))
if(!isnull(target) && !isatom(target))
stack_trace("[pawn]'s current movement target is [target.type], not an atom")
cancel_actions()
return
movement_target_source = source
current_movement_target = target
if(!isnull(current_movement_target))
RegisterSignal(current_movement_target, COMSIG_MOVABLE_MOVED, PROC_REF(on_movement_target_move))
RegisterSignal(current_movement_target, COMSIG_PARENT_PREQDELETED, PROC_REF(on_movement_target_delete))
if(new_movement)
change_ai_movement_type(new_movement)
@@ -158,6 +167,18 @@ RESTRICT_TYPE(/datum/ai_controller)
RegisterSignal(pawn, COMSIG_MOB_LOGIN, PROC_REF(on_sentience_gained))
RegisterSignal(pawn, COMSIG_PARENT_QDELETING, PROC_REF(on_pawn_qdeleted))
/datum/ai_controller/proc/on_movement_target_move(datum/source)
SIGNAL_HANDLER // COMSIG_MOVABLE_MOVED
check_target_max_distance()
/datum/ai_controller/proc/on_movement_target_delete(atom/source)
SIGNAL_HANDLER // COMSIG_PARENT_PREQDELETED
set_movement_target(source = type, target = null)
/datum/ai_controller/proc/check_target_max_distance()
if(get_dist(current_movement_target, pawn) > max_target_distance)
cancel_actions()
/// Sets the AI on or off based on current conditions, call to reset after you've manually disabled it somewhere
/datum/ai_controller/proc/reset_ai_status()
set_ai_status(get_expected_ai_status())
@@ -282,16 +303,6 @@ RESTRICT_TYPE(/datum/ai_controller)
idle_behavior.perform_idle_behavior(seconds_per_tick, src) //Do some stupid shit while we have nothing to do
return
if(current_movement_target)
if(!isatom(current_movement_target))
stack_trace("[pawn]'s current movement target is [current_movement_target], not an atom!")
cancel_actions()
return
if(get_dist(pawn, current_movement_target) > max_target_distance) //The distance is out of range
cancel_actions()
return
for(var/datum/ai_behavior/current_behavior as anything in current_behaviors)
// Convert the current behaviour action cooldown to realtime seconds from deciseconds.current_behavior
// Then pick the max of this and the seconds_per_tick passed to ai_controller.process()
@@ -299,9 +310,9 @@ RESTRICT_TYPE(/datum/ai_controller)
var/action_seconds_per_tick = max(current_behavior.get_cooldown(src) * 0.1, seconds_per_tick)
if(current_behavior.behavior_flags & AI_BEHAVIOR_REQUIRE_MOVEMENT) //Might need to move closer
if(!current_movement_target)
stack_trace("[pawn] wants to perform action type [current_behavior.type] which requires movement, but has no current movement target!")
return // This can cause issues, so don't let these slide.
if(isnull(current_movement_target))
fail_behavior(current_behavior)
return
// Stops pawns from performing such actions that should require the target to be adjacent.
var/atom/movable/moving_pawn = pawn
@@ -432,11 +443,14 @@ RESTRICT_TYPE(/datum/ai_controller)
if(!LAZYLEN(current_behaviors))
return
for(var/datum/ai_behavior/current_behavior as anything in current_behaviors)
var/list/arguments = list(src, FALSE)
var/list/stored_arguments = behavior_args[current_behavior.type]
if(stored_arguments)
arguments += stored_arguments
current_behavior.finish_action(arglist(arguments))
fail_behavior(current_behavior)
/datum/ai_controller/proc/fail_behavior(datum/ai_behavior/current_behavior)
var/list/arguments = list(src, FALSE)
var/list/stored_arguments = behavior_args[current_behavior.type]
if(stored_arguments)
arguments += stored_arguments
current_behavior.finish_action(arglist(arguments))
/// Turn the controller on or off based on if you're alive.
/// We only register to this if the flag is present so don't need to check again.