ID:170250
 
When I start the game, all the monsters start in their respective homes. They wander about in there, keeping inside their areas. But if a player attacks them, they will follow the player outside of their area. If the player moves more than 6 tiles away, the monster will start wandering around again, but this time refusing to leave its current area.

How can I get it to return to its starting areas? And how can I get it to only leave a certain number of tiles from its home area, before it returns ignoring all players until it gets there? I've made a few attempts, and they've all gone terribly wrong.

Thank you for your time.

~Ease~
you could have them teleport back to a loc after they're done chasing someone.
In response to Elchry
I want them to walk back to an area, not a loc. I don't know how to tell them to seek out an area.
In response to Ease
Ease wrote:
I want them to walk back to an area, not a loc. I don't know how to tell them to seek out an area.

You could make them have a "home" area.
mob
monster
var
area/home_area //Don't forget to set this!
//Then, use the walk_to proc to src.home_area\
in your wander code

That should work. :p
In response to Hell Ramen
And how would you set the area?

I tried this under the Monster

            New()
for(var/area/a in world)
if(a.contents.Find(src))
src.InArea = a
world<<"[src] = [src.InArea]"
break


And this just caused it to crash
In response to Ease
Don't forget that a turfs loc is an area, so make a Get_Area() proc:
proc/Get_Area(atom/a)
if(isarea(a))return a
else
if(isarea(a.loc))return a.loc
else return Get_Area(a.loc)

Then you need a decent proc for searching out areas. I think locate() returns the closest tile. I don't know if it works for areas, though.
Add a simple AI proc, with a check for distance, a check for a target, and chase procs, then finally your return proc and voila!
proc/AI()
var/area/a = Get_Area(src)
if(target && (istype(a,/area/home)||get_dist(src,home)<6))
step_towards(src,target)
attack(target)
else
var/area/a = Get_Area(src)
if(a == home)
step_rand(src) //Not sure if exists, shouldn't be too hard to make anyway
target = locate(/mob) in oview(6,src)
else if(get_dist(home)>6)
step_toward(src,home)
In response to Hazman
Hazman wrote:
Then you need a decent proc for searching out areas. I think locate() returns the closest tile. I don't know if it works for areas, though.

locate() does nothing of the sort.

Add a simple AI proc, with a check for distance, a check for a target, and chase procs, then finally your return proc and voila!
proc/AI()
var/area/a = Get_Area(src)
if(target && (istype(a,/area/home)||get_dist(src,home)<6))
step_towards(src,target)
attack(target)
else
var/area/a = Get_Area(src)
if(a == home)
step_rand(src) //Not sure if exists, shouldn't be too hard to make anyway
target = locate(/mob) in oview(6,src)
else if(get_dist(home)>6)
step_toward(src,home)


There's just way too much that won't work here. For starters, an AI proc is usually implemented as a loop, and the var/area/a=Get_Area(src) call should be saving the starting area. The type check against /area/home is bogus because it should be comparing to the monster's specific home area, not a single common home area type. The step_rand() proc actually doesn't take the area into account, so the monster may leave its area unintentionally even when not chasing a target. And finally, you've actually declared var/area/a twice, so this won't compile.

Lummox JR
In response to Lummox JR
Thank you Lummox, but I had already made my own Monster "AI" - all I couldn't do was amend it so that they returned to their own areas. The Get_Area proc from Hazman triggered my mind enough for me to make my own proc and amend my AI! =D

However, it is now very very messy, and doesn't even work!

            ai_random_wander()//random wander if no mobs are in range to attack
if(src.key)//if the source is human
return//don't call the rest
if(AI==1)
var/turf/T
var/Dir=0
do
Dir=pick(1,2,4,8,5,6,9,10)
T=get_step(src,Dir)
while(!T||T.density||T.loc!=loc.loc)
step(src,Dir)
src.ai_run_away()//checks for run away
spawn(7)//delay for one tick
if(AI==1)
ai_random_wander()//wander some more

ai_run_away()//used for checking to see if it should run or attack
if(src.client)
return
else
for(var/mob/chars/M in oview(4,src))//loops over all mobs within 4 tiles of the monster
if(M.client)//if the mob is human
var/area/a = Get_Area(src)
var/area/T = src.InArea
if(get_dist(src,M) <= 5 && src.HP < src.HP/3)//if the player is close, and the monster is weaker
AI = 2
walk_away(src,M,5,6)//run away
else if(istype(a,T)||get_dist(src,T)<6)
AI = 2
src.ai_walk_to()//calls the walk_to (for attacking) proc
else if(get_dist(src,T)>6)
AI = 2
walk_towards(src,T,7)

else
continue//if it's a monster keep looping


ai_walk_to()//someone came into view
if(src.client)
return 0
else
for(var/mob/chars/M in oview(5,src))
if(M.client&&M.loc.loc==loc.loc)
if(get_dist(src,M) <= 5&&checktrg(M))//within 5 tiles
do
step_to(src,M,1)//walk to the player
if(get_dist(src,M) <= 1)
Attackproc(M)
sleep(9)
sleep(11)

while(checktrg(M)&&get_dist(src,M) <= 5)
break//stops the loop
else
continue
AI = 1
ai_random_wander()
ai_walk_to2(var/mob/M)//someone shot src
if(src.client)
return 0
else
var/e = 1
do
step_to(src,M,1)//walk to the player
if(get_dist(src,M) <= 5)
ai_walk_to()
sleep(11)
while(e)
AI = 1
ai_random_wander()

checktrg(atom/target)
if(target.loc.loc==loc.loc)
return 1
else
return 0


ai_random_wander() is the main proc, called when all monsters are made anew. To make them walk randomly. ai_run_away() is not just for running away, it actually chooses which action to take: run away, run home (to "InArea" area) or run at an enemy. ai_walk_to() is to get it to walk at an enemy, and attack if near enough. ai_walk_to2() is to walk at an enemy shooting you from outside your area.

Unfortunately, now they walk very erratically when a player nears, and they never, ever walk back home. Any help would be greatly appreciated!

~Ease~
In response to Ease
hmmm u could set the Mob's Move delay so it runs away slower. I don't know if that helps *Becasue i'm not sure on the code myself. If some1 could post it, it could realy help Ease
In response to Ease
I'm still stuck on this. Monsters jump erratically, and never return home. I've changed the code a little, but to no avail:

            ai_random_wander()//random wander if no mobs are in range to attack
if(src.key)//if the source is human
return//don't call the rest
else
var/turf/T
var/Dir=0
do
Dir=pick(1,2,4,8,5,6,9,10)
T=get_step(src,Dir)
while(!T||T.density||T.loc!=loc.loc)
step(src,Dir)
src.ai_run_away()//checks for run away
spawn(7)//delay for one tick
src.ai_random_wander()

ai_run_away()//used for checking to see if it should run or attack
if(src.client)
return
else
for(var/mob/chars/M in oview(4,src))//loops over all mobs within 4 tiles of the monster
if(M.client)//if the mob is human
var/area/a = Get_Area(src)
var/area/T = src.InArea
if(get_dist(src,M) <= 5 && src.HP < src.HP/3)//if the player is close, and the monster is weaker
walk_away(src,M,5,6)//run away
else if(istype(a,T)||get_dist(src,T)<6)
src.ai_walk_to()//calls the walk_to (for attacking) proc
else if(get_dist(src,T)>6)
walk_towards(src,T,7)
else
ai_random_wander()//if it's a monster keep looping


ai_walk_to()//someone came into view
if(src.client)
return 0
else
for(var/mob/chars/M in oview(5,src))
if(M.client&&M.loc.loc==loc.loc)
if(get_dist(src,M) <= 5&&checktrg(M))//within 5 tiles
do
step_to(src,M,1)//walk to the player
if(get_dist(src,M) <= 1)
Attackproc(M)
sleep(9)
sleep(11)

while(checktrg(M)&&get_dist(src,M) <= 5)
break//stops the loop
else
continue
ai_walk_to2(var/mob/M)//someone shot src
if(src.client)
return 0
else
var/e = 1
do
step_to(src,M,1)//walk to the player
if(get_dist(src,M) <= 5)
ai_walk_to()
sleep(11)
while(e)
ai_random_wander()

checktrg(atom/target)
if(target.loc.loc==loc.loc)
return 1
else
return 0


Any help?

~Ease~
In response to ElderKain
Nope, movement delay did not affect it in the slightest. =( Thanks though!
In response to Ease
Fixed