ID:171447
 
Hey guys, ive searched a few demos looking for how to make monsters attack the user. they wander around randomly until they see the user. but... this is the bit i cant code >__<

can some one give me an idea or a snippet of code i can start from?

Thanks in advance,

Farkas
ok i have tried this,

            proc
walkforever(mob/M)
while(1)
var/list/dirs = list(NORTH,NORTHEAST,NORTHWEST,SOUTHEAST,SOUTHWEST,SOUTH,EAST,WEST)
var/a = pick(dirs)
Walk(rand(1,10),a,8)
sleep(rand(10,50))
if(M in view())
walk_to(src,M)
else
walkforever()
return
Walk(Steps as num, Direction, Speed as num)
while(Steps)
Steps--
step(src,Direction)
sleep(Speed)


the monster still wont walk to me, can any one tell me whats wrong?
In response to Farkas
Three problems:

  • view() should be view(src), because view() defaults to view(usr). You need this to be view(src), since src is the monster and usr is not predictable here.
  • M is never set to anything, unless you called walkforever() with a mob in mind. When this proc calls itself again it doesn't send an argument, so M will be null the second time. Instead you should search for a target in view(src), which I think is what you intended to do but didn't do correctly. if(M in view(src)) will only check if a known mob M is in that view; it will not go out and find any mob that will fit. To do that, use locate() or a for() loop. (I recommend a for() loop because you can skip over other monsters and such.)
  • When walkforever is called again, you need to use spawn() on it. If a proc calls itself, this is calle recursion. It waits for the second call to finish before finishing the first, so BYOND's stack gets full of procs waiting to finish. spawn() starts the new copy and lets the old one finish.

    Lummox JR
In response to Lummox JR
ok, i have done this based on your advice,

          proc
walkforever()
while(1)
var/list/dirs = list(NORTH,NORTHEAST,NORTHWEST,SOUTHEAST,SOUTHWEST,SOUTH,EAST,WEST)
var/a = pick(dirs)
Walk(rand(1,10),a,8)
sleep(rand(10,50))
for(var/mob/M in view(src))
if(M.race == "NPC")
spawn() src.walkforever()
else
walk_to(src,M)
break
Walk(Steps as num, Direction, Speed as num)
while(Steps)
Steps--
step(src,Direction)
sleep(Speed)


now the monsters run to me but then go CRAZY and keep runing round me, which is lagging me!!

what am i doing wrong now?
In response to Farkas
Farkas wrote:
now the monsters run to me but then go CRAZY and keep runing round me, which is lagging me!!

what am i doing wrong now?

You shouldn't be making your decision to move inside the for() loop. Instead, use that to find a mob suitable to attack. If such a mob is found, break. If the loop finishes without any player being found, then M will be null.

To change this, you need to declare var/mob/M before the for() loop.

Lummox JR
In response to Lummox JR
i have tried different ways to use the for loop, none of which seem to work for me, perhaps you could do me a small example of how to use the for loop correctly?

Farkas
In response to Farkas
i have been trying for well over 6 hours now, i am not getting any closer to achieving my goal, can some one please, lend me a hand?

Farkas
In response to Lummox JR
Lummox JR wrote:
You shouldn't be making your decision to move inside the for() loop. Instead, use that to find a mob suitable to attack. If such a mob is found, break. If the loop finishes without any player being found, then M will be null.

If the loop finishes without a player being found, M will either be an NPC or, if NO mobs are found, null.

If view(src) is being used, M will never be null, because src is always in view(src).
In response to Garthor
Garthor wrote:
Lummox JR wrote:
You shouldn't be making your decision to move inside the for() loop. Instead, use that to find a mob suitable to attack. If such a mob is found, break. If the loop finishes without any player being found, then M will be null.

If the loop finishes without a player being found, M will either be an NPC or, if NO mobs are found, null.

I'm talking about a corrected loop here. If it finishes normally, M will be null. If he breaks out when he finds a player to attack, M will be that player.

If view(src) is being used, M will never be null, because src is always in view(src).

Ah, but you can also go by the NPC test here. If looking for a player, then the mob itself will be skipped. Still oview(src) would be a better choice.

Lummox JR
In response to Lummox JR
SORTED
In response to Farkas
Not really. I won't start an argument over something as trivial as this, but, despite his statements to the contrary, he did say to do something along the lines of:
var/mob/M
for(M in view(src))
if(isplayer(M))
break
if(M)
//It's a player

Which isn't right.
In response to Garthor
Eh. That would actually work, although I didn't say it's the best method. Clearly the best method is to have a target preselected, move toward it if it's in view, and if not to find another target.

Lummox JR