ID:732280
 
(See the best response by Albro1.)
OK so im playing around with AI design right now, and the first thing that came to mind was monsters walking around, lets say a forest, randomly.
but i dont really like the built-in proc for that, "walk_rand()", because it makes their movement too random and unrealistic, despite the pattern less nature of their path there should be at least a form of purpose. So i decided to make my own walk_rand proc.

oh yea and if am at it i might as well add a way to keep some npcs from wandering too far from their point of origin.

Here it is:


Code:
mob
var
org_x //this is for defining how far the mob wander from its starting point
org_y //this is for defining how far the mob wander from its starting point
random_wandering //this is for making sure mob is asked to wander randomly only once to prevent ugly jumping crap
stop_random_wander //this is for making the mob stop randomly wanderging
proc
random_wander(delay,range) // when called two arguments are passed definging speed and the range of movement
if(src.random_wandering)
return
src.random_wandering=1
spawn()
while(!src.stop_random_wander)
var/direction = src.dir
var/list/DIR = list(1,2,4,8)

//obstacle checking ... probably needs some work
for(var/turf/t in get_step(src,src.dir))
if(t.density)
DIR.Remove(src.dir)
direction=pick(DIR)
for(var/obj/t in get_step(src,src.dir))
if(t.density)
DIR.Remove(src.dir)
direction=pick(DIR)
for(var/mob/t in get_step(src,src.dir))
if(t.density)
DIR.Remove(src.dir)
direction=pick(DIR)

//this is to make sure the mobs doesnt waste time trying to walk pass the worlds edges

if(src.x==1)
DIR.Remove(8)
direction=pick(DIR)
if(src.x==world.maxx)
DIR.Remove(4)
direction=pick(DIR)
if(src.y==1)
DIR.Remove(2)
direction=pick(DIR)
if(src.y==world.maxy)
DIR.Remove(1)
direction=pick(DIR)

//here we're making sure the mob doesnt get pass its desfined area

if(src.x==src.org_x+range)
DIR.Remove(4)
direction=pick(DIR)
if(src.x==src.org_x-range)
DIR.Remove(8)
direction=pick(DIR)
if(src.y==src.org_y+range)
DIR.Remove(1)
direction=pick(DIR)
if(src.y==src.org_y-range)
DIR.Remove(2)
direction=pick(DIR)

//this part is for actually make the whole thing kinna random

if(prob(29))
DIR.Remove(src.dir)
direction=pick(DIR)

//and now we MOVE!
step(src,direction)
sleep(delay)


Problem description:
I know im no coder and what i wrote could probably use some work but hey thats what the forums are for right?
anyone?
please?
*grasshopper*
SCREW YOU MR COOL GRASSHOPPER

ok so this is what i know i could use some help on:
1)the cluster of for's i did to check for obstacles does the trick but isnt quite a home-run, because the proc can identify a tree infront of the mob and choose a different direction but if theres a rock in the new direction it wont be able to know and waste time trying to step that way.

2)creating the var's direction and DIR everytime must be wastefull and theres probably another way to do it but i couldnt find it so id love help on that one too.

and in general if you feel theres something you can contribute it'll be very much appreciated.
:)
Best response
You need to use atom instead of doing 3 different for() loops.
var/list/d = list(NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, NORTHWEST)
for(var/atom/a in view(1))
if(a.density)
if(get_dir(src, a) in d) // If the direction is still in the list, remove it.
d -= get_dir(src, a)


You can also do this for your edge checks:
for(var/v in d) // loop through the directions left
if(!(get_step(src, v)))
d -= v // If the step won't go through, then remove the direction.