mob
Enemies
var
aggro_dist = 7
keep_dist = 1
chase_speed = 2
turf/aggro_loc
turf/home_loc
next_attack = 0
//helper functions
proc
foundTarget(var/mob/player/c)
if(!src.target)
src.target = c
aggro_loc = src.loc
src.chaseState()
lostTarget()
var
rng = range(aggro_loc,aggro_dist)
mob/player/trg
mdist = aggro_dist+1
d
//search for combatants within range
for(var/mob/player/c in rng)
d = get_dist(src,c)
if(d<mdist||(d==mdist&&rand(1)))
mdist = d
trg = c
//if we found anything, chase, if not, reset
if(trg)
src.target = trg
chaseState()
else
resetState()
fight()
//You can put whatever you want in here.
//just make sure you set next_attack when you have made an attack.
next_attack = world.time + 10
//state functions
proc
chaseState()
set waitfor=0
var/d = get_dist(src,target)
while(d>keep_dist)
//if the target is out of range of dead, bail out.
if(get_dist(aggro_loc,src)>aggro_dist||src.target.health.current<=0)
src.lostTarget()
return 0
//if the path is blocked, take a random step
. = step(src,get_dir(src,target))
if(!.)
step_rand(src)
sleep(chase_speed)
d = get_dist(src,target)
attackState()
return 1
attackState()
set waitfor=0
var/d
while(src.target.health.current>0)
d = get_dist(src,target)
//if the target is too far away, chase
if(d>src.keep_dist)
chaseState()
return
//if the target is too close, avoid
if(d<src.keep_dist)
//if the path is blocked, take a random step
. = step_away(src,target)
if(!.)
step_rand(src)
//if we are eligible to attack, do it.
if(world.time>=next_attack) attack()
sleep(chase_speed)
//when the loop is done, we've lost the target
src.lostTarget()
resetState()
set waitfor=0
var
//allow us longer than it should take to get home via distance
returntime = world.time + get_dist(src,home_loc) * (3 + chase_speed)
while(world.time<returntime&&src.loc!=home_loc)
//if the path is blocked, take a random step
. = step(src,get_dir(src,home_loc))
if(!.)
step_rand(src)
sleep(chase_speed)
//teleport if we can't get home
if(src.loc!=home_loc)
src.loc = home_loc
src.target = null
src.aggro_loc = null
src.dir = 2
Problem description: Greetings, after tempering with the snippet, no matter how many tiny changes I make, I can't seem to solve this issue.
runtime error: Maximum recursion level reached (perhaps there is an infinite loop)
To avoid this safety check, set world.loop_checks=0.
proc name: lostTarget (/mob/Enemies/proc/lostTarget)
usr: Luchasi (/mob/player)
src: (83)Dummy (/mob/Enemies)
call stack:
(83)Dummy (/mob/Enemies): lostTarget()
(83)Dummy (/mob/Enemies): attackState()
(83)Dummy (/mob/Enemies): chaseState()
This usually occurs after one the following arguments return a false:
//from the chaseState()
if(get_dist(aggro_loc,src)>aggro_dist||src.target.health.current<=0)
In addition I would like to know:
-How can I allow the ai to continue chasing until the player exists its view.
The critical problem in this code appears to be lostTarget(), which is looping through potential targets but does not check their health to see if they're valid. So your mob is detecting a target in lostTarget() that happens to be dead; that calls chaseState(). Because the distance appears to be within keep_dist, chaseState() is immediately calling attackState(). Then attackState() sees that your target is dead, and calls lostTarget().
The recursion likely wouldn't be much of an issue here if not for the fact that lostTarget() is allowing the infinite loop to happen. In fact I think that with setting waitfor=0 as you are, the recursion stops being an issue as soon as any of the procs sleeps. The problem is, the procs are never sleeping because lostTarget() is repeatedly picking a bad target.