Skip to content

Commit

Permalink
Breaking up AI files to integrate bot behaviors.
Browse files Browse the repository at this point in the history
  • Loading branch information
MistakeNot4892 committed Sep 24, 2024
1 parent 5c4bfec commit 3e0bf7e
Show file tree
Hide file tree
Showing 32 changed files with 392 additions and 624 deletions.
2 changes: 2 additions & 0 deletions code/__defines/ai.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#define STANCE_ATTACKING /decl/mob_controller_stance/attacking
#define STANCE_TIRED /decl/mob_controller_stance/tired
#define STANCE_CONTAINED /decl/mob_controller_stance/contained
#define STANCE_BUSY /decl/mob_controller_stance/busy

//basically 'do nothing'
#define STANCE_COMMANDED_STOP /decl/mob_controller_stance/commanded/stop
//follows a target
Expand Down
174 changes: 17 additions & 157 deletions code/datums/ai/_ai.dm
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,22 @@
/// Aggressive AI var; defined here for reference without casting.
var/try_destroy_surroundings = FALSE

/// Reference to the atom we are targetting.
var/weakref/target_ref

/// Current path for A* pathfinding.
var/list/executing_path
/// A counter for times we have failed to progress along our path.
var/path_frustration = 0
/// A list of any obstacles we should path around in future.
var/list/path_obstacles = null

/// Radius of target scan area when looking for valid targets. Set to 0 to disable target scanning.
var/target_scan_distance = 0
/// Time tracker for next target scan.
var/next_target_scan_time
/// How long minimum between scans.
var/target_scan_delay = 1 SECOND

/datum/mob_controller/New(var/mob/living/target_body)
body = target_body
Expand All @@ -72,6 +86,7 @@
/datum/mob_controller/Destroy()
LAZYCLEARLIST(_friends)
LAZYCLEARLIST(_enemies)
set_target(null)
if(is_processing)
STOP_PROCESSING(SSmob_ai, src)
if(body)
Expand All @@ -80,31 +95,6 @@
body = null
. = ..()

/datum/mob_controller/proc/get_automove_target(datum/automove_metadata/metadata)
var/turf/move_target = (islist(executing_path) && length(executing_path)) ? executing_path : null
if(istype(move_target) && QDELETED(move_target))
clear_path()

/datum/mob_controller/proc/handle_post_automoved(atom/old_loc)
if(!islist(executing_path) || length(executing_path) <= 0)
return
var/turf/body_turf = get_turf(body)
if(!istype(body_turf))
return
if(executing_path[1] != body_turf)
return
if(length(executing_path) > 1)
executing_path.Cut(1, 2)
else
clear_path()

/datum/mob_controller/proc/clear_path()
executing_path = null
body?.stop_automove()

/datum/mob_controller/proc/can_do_automated_move(variant_move_delay)
return body && !body.client

/datum/mob_controller/proc/can_process()
if(!body || !body.loc || ((body.client || body.mind) && !(body.status_flags & ENABLE_AI)))
return FALSE
Expand Down Expand Up @@ -133,6 +123,8 @@
SHOULD_CALL_PARENT(TRUE)
if(!body || QDELETED(body))
return FALSE
if(get_stance() == STANCE_BUSY)
return FALSE
if(!body.stat)
try_unbuckle()
try_wander()
Expand All @@ -150,16 +142,6 @@
else if(prob(25))
body.visible_message(SPAN_WARNING("\The [body] struggles against \the [body.buckled]!"))


/datum/mob_controller/proc/get_activity()
return current_activity

/datum/mob_controller/proc/set_activity(new_activity)
if(current_activity != new_activity)
current_activity = new_activity
return TRUE
return FALSE

// The mob will periodically sit up or step 1 tile in a random direction.
/datum/mob_controller/proc/try_wander()
//Movement
Expand Down Expand Up @@ -203,135 +185,13 @@
else if(ispath(do_emote, /decl/emote))
body.emote(do_emote)

/datum/mob_controller/proc/get_target()
return null

/datum/mob_controller/proc/set_target(atom/new_target)
return

/datum/mob_controller/proc/find_target()
return

/datum/mob_controller/proc/valid_target(var/atom/A)
return

/datum/mob_controller/proc/move_to_target(var/move_only = FALSE)
return

/datum/mob_controller/proc/stop_wandering()
stop_wander = TRUE

/datum/mob_controller/proc/resume_wandering()
stop_wander = FALSE

/datum/mob_controller/proc/set_stance(new_stance)
if(stance != new_stance)
stance = new_stance
return TRUE
return FALSE

/datum/mob_controller/proc/get_stance()
return stance

/datum/mob_controller/proc/list_targets(var/dist = 7)
return null

/datum/mob_controller/proc/handle_ranged_target(atom/ranged_target)
return FALSE

/datum/mob_controller/proc/startle()
if(QDELETED(body) || body.stat != UNCONSCIOUS)
return
body.set_stat(CONSCIOUS)
if(body.current_posture?.prone)
body.set_posture(/decl/posture/standing)

/datum/mob_controller/proc/retaliate(atom/source)
SHOULD_CALL_PARENT(TRUE)
if(!istype(body) || body.stat == DEAD)
return FALSE
startle()
if(isliving(source))
remove_friend(source)
return TRUE

/datum/mob_controller/proc/destroy_surroundings()
return

/datum/mob_controller/proc/lose_target()
return

/datum/mob_controller/proc/lost_target()
return

/datum/mob_controller/proc/handle_death(gibbed)
return

/datum/mob_controller/proc/pacify(mob/user)
lose_target()
add_friend(user)

// General-purpose memorise proc, used by /commanded
/datum/mob_controller/proc/memorise(mob/speaker, message)
return

// General-purpose memory checking proc, used by /faithful_hound
/datum/mob_controller/proc/check_memory(mob/speaker, message)
return FALSE

/// General-purpose scooping reaction proc, used by /passive.
/// Returns TRUE if the scoop should proceed, FALSE if it should be canceled.
/datum/mob_controller/proc/scooped_by(mob/initiator)
return TRUE

// Enemy tracking - used on /aggressive
/datum/mob_controller/proc/get_enemies()
return _enemies

/datum/mob_controller/proc/add_enemy(mob/enemy)
if(istype(enemy))
LAZYDISTINCTADD(_enemies, weakref(enemy))

/datum/mob_controller/proc/add_enemies(list/enemies)
for(var/thing in enemies)
if(ismob(thing))
add_friend(thing)
else if(istype(thing, /weakref))
LAZYDISTINCTADD(_enemies, thing)

/datum/mob_controller/proc/remove_enemy(mob/enemy)
LAZYREMOVE(_enemies, weakref(enemy))

/datum/mob_controller/proc/set_enemies(list/new_enemies)
_enemies = new_enemies

/datum/mob_controller/proc/is_enemy(mob/enemy)
. = istype(enemy) && LAZYLEN(_enemies) && (weakref(enemy) in _enemies)

/datum/mob_controller/proc/clear_enemies()
LAZYCLEARLIST(_enemies)

// Friend tracking - used on /aggressive.
/datum/mob_controller/proc/get_friends()
return _friends

/datum/mob_controller/proc/add_friend(mob/friend)
if(istype(friend))
LAZYDISTINCTADD(_friends, weakref(friend))
return TRUE
return FALSE

/datum/mob_controller/proc/remove_friend(mob/friend)
LAZYREMOVE(_friends, weakref(friend))

/datum/mob_controller/proc/set_friends(list/new_friends)
_friends = new_friends

/datum/mob_controller/proc/is_friend(mob/friend)
. = istype(friend) && LAZYLEN(_friends) && (weakref(friend) in _friends)

/datum/mob_controller/proc/clear_friends()
LAZYCLEARLIST(_friends)

/datum/mob_controller/proc/clear_paths()
return
35 changes: 35 additions & 0 deletions code/datums/ai/_ai_enemies.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Enemy tracking - used on /aggressive
/datum/mob_controller/proc/get_enemies()
return _enemies

/datum/mob_controller/proc/add_enemy(mob/enemy)
if(istype(enemy))
LAZYDISTINCTADD(_enemies, weakref(enemy))

/datum/mob_controller/proc/add_enemies(list/enemies)
for(var/thing in enemies)
if(ismob(thing))
add_friend(thing)
else if(istype(thing, /weakref))
LAZYDISTINCTADD(_enemies, thing)

/datum/mob_controller/proc/remove_enemy(mob/enemy)
LAZYREMOVE(_enemies, weakref(enemy))

/datum/mob_controller/proc/set_enemies(list/new_enemies)
_enemies = new_enemies

/datum/mob_controller/proc/is_enemy(mob/enemy)
. = istype(enemy) && LAZYLEN(_enemies) && (weakref(enemy) in _enemies)

/datum/mob_controller/proc/clear_enemies()
LAZYCLEARLIST(_enemies)

/datum/mob_controller/proc/retaliate(atom/source)
SHOULD_CALL_PARENT(TRUE)
if(!istype(body) || body.stat == DEAD)
return FALSE
startle()
if(isliving(source))
remove_friend(source)
return TRUE
25 changes: 25 additions & 0 deletions code/datums/ai/_ai_friends.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/datum/mob_controller/proc/pacify(mob/user)
lose_target()
add_friend(user)

// Friend tracking - used on /aggressive.
/datum/mob_controller/proc/get_friends()
return _friends

/datum/mob_controller/proc/add_friend(mob/friend)
if(istype(friend))
LAZYDISTINCTADD(_friends, weakref(friend))
return TRUE
return FALSE

/datum/mob_controller/proc/remove_friend(mob/friend)
LAZYREMOVE(_friends, weakref(friend))

/datum/mob_controller/proc/set_friends(list/new_friends)
_friends = new_friends

/datum/mob_controller/proc/is_friend(mob/friend)
. = istype(friend) && LAZYLEN(_friends) && (weakref(friend) in _friends)

/datum/mob_controller/proc/clear_friends()
LAZYCLEARLIST(_friends)
7 changes: 7 additions & 0 deletions code/datums/ai/_ai_memory.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// General-purpose memorise proc, used by /commanded
/datum/mob_controller/proc/memorise(mob/speaker, message)
return

// General-purpose memory checking proc, used by /faithful_hound
/datum/mob_controller/proc/check_memory(mob/speaker, message)
return FALSE
27 changes: 27 additions & 0 deletions code/datums/ai/_ai_pathfinding.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/datum/mob_controller/proc/can_do_automated_move(variant_move_delay)
return body && !body.client

/datum/mob_controller/proc/clear_paths()
clear_path()

/datum/mob_controller/proc/clear_path()
executing_path = null
body?.stop_automove()

/datum/mob_controller/proc/get_automove_target(datum/automove_metadata/metadata)
var/turf/move_target = (islist(executing_path) && length(executing_path)) ? executing_path : null
if(istype(move_target) && QDELETED(move_target))
clear_path()

/datum/mob_controller/proc/handle_post_automoved(atom/old_loc)
if(!islist(executing_path) || length(executing_path) <= 0)
return
var/turf/body_turf = get_turf(body)
if(!istype(body_turf))
return
if(executing_path[1] != body_turf)
return
if(length(executing_path) > 1)
executing_path.Cut(1, 2)
else
clear_path()
39 changes: 26 additions & 13 deletions code/datums/ai/_ai_stance.dm
Original file line number Diff line number Diff line change
@@ -1,30 +1,43 @@
// Stub type for future expansion/logic encapsulation.
/decl/mob_controller_stance
abstract_type = /decl/mob_controller_stance

/decl/mob_controller_stance/none

/decl/mob_controller_stance/idle

/decl/mob_controller_stance/alert

/decl/mob_controller_stance/attack

/decl/mob_controller_stance/attacking

/decl/mob_controller_stance/tired

/decl/mob_controller_stance/contained

/decl/mob_controller_stance/commanded
abstract_type = /decl/mob_controller_stance/commanded

/decl/mob_controller_stance/commanded/stop

/decl/mob_controller_stance/commanded/follow

/decl/mob_controller_stance/commanded/misc

/decl/mob_controller_stance/commanded/heal

/decl/mob_controller_stance/commanded/healing
/decl/mob_controller_stance/busy

/datum/mob_controller/proc/get_activity()
return current_activity

/datum/mob_controller/proc/set_activity(new_activity)
if(current_activity != new_activity)
current_activity = new_activity
return TRUE
return FALSE

/datum/mob_controller/proc/set_stance(new_stance)
if(stance != new_stance)
stance = new_stance
return TRUE
return FALSE

/datum/mob_controller/proc/get_stance()
return stance

/datum/mob_controller/proc/startle()
if(QDELETED(body) || body.stat != UNCONSCIOUS)
return
body.set_stat(CONSCIOUS)
if(body.current_posture?.prone)
body.set_posture(/decl/posture/standing)
Loading

0 comments on commit 3e0bf7e

Please sign in to comment.