ID:145265
 
mob
proc
walkaround()
again
if(!src.enemy in view()||src.enemy==null)
src.enemy=null
for(var/mob/M in view(src))
if(M.client)
src.enemy=M
break
if(src.enemy!=null)
if(src.enemy in view(src))
step_towards(src,src.enemy)
else
step_to(src,src.enemy)
if(src.enemy==null)
step_rand(src)
spawn(10)
goto again
The problem is, I can't get the ai to attack... They just walk around randomly... Any ideas?
It is probably because of your first if statement. You cannot do "if(!a in b)." Well, you can, but it doesn't have the effect you're looking for. You need to do if(!(a in b)) because of order of operations.

Also, the "||src.enemy==null" part in that same if statement is redundant. If enemy is null, it won't be in view and will get caught by the first check.

Inside the second if statement's code block you are checking again to see if enemy is in view. Because of your first if and its code block, if enemy is not null it should always be in your view.

While your third outer if statement (if(enemy==null)) isn't technically wrong, you could save yourself the need for another if statement by just putting it inside the first if statement, putting step_rand(src) just after the src.enemy=null line.

All that aside, the order of operations conflict in the first if statement I mentioned first is probably what is causing the problem.
In response to Loduwijk
I made this for you, but it isn't tested. All you need to do is define an Attack proc.

mob
NPC
Monster
Walk_Delay = 1
Attack_Delay = 1
Sight_Range = 5
Attack_Range = 1

New()
..()
spawn() src.Wander()
return
var
Walk_Delay // How long to wait before it attacks
Attack_Delay // How long to wait before it attacks
Sight_Range // How far it can see
Attack_Range // How close the target has to be to attack it
mob/Target // Who the target is

proc
Get_Target()
if(src.Target) return
while(1)
for(var/mob/M in view(Sight_Range,src))
if((isPC(M)))
src.Target = M
return
return

Wander()
Get_Target()
while(1)
if(Target)
if(Target in view(Attack_Range,src)) // Checks to see if it is in Attack Range
sleep(Attack_Range)
src.Attack(Target) // Make sure to define a Attack proc
spawn() src.Wander()
return
else if(Target in view(Sight_Range,src)) // Checks to see if its in their Sight Range
sleep(Walk_Delay)
step_towards(src,Target)
spawn() src.Wander()
return
else if(!(Target in view(Sight_Range,src))) // Since the Target is no where around no use looking for them anymore
src.Target = null
sleep(Walk_Delay)
step_rand(src)
spawn() src.Wander()
return
sleep(Walk_Delay)
step_rand(src)
spawn() src.Wander()
return

proc
isNPC(mob/M) // Use this to check if a mob is a Non-Player-Character
if(!ismob(M))
return 0
if(istype(M,/mob/NPC/))
return 1
else
return 0

isPC(mob/M)
if(!ismob(M)) // Use this to check if a mob is a Player-Character
return 0
if(M.client)
return 1
else if(!M.client)
return 0
In response to Y2kEric
EWWWW

Procedures to make mobs wander around aimlessly, constantly, generating lag.
In response to Y2kEric
Why do you use the following format?
proc/MyFunction()
while(1)
//do stuff
spawn() MyFunction()
return

Using a while loop does absolutely nothing there.
In response to Loduwijk
So you're telling me it makes a big difference, if so what differences does it make, they both do the exact same thing if I use while(1) or not.
In response to Y2kEric
It doesn't do the exact same thing. Using while like that is similar to doing the following.
mob/verb/attack()
var/atom/A = pick(view())
A.damage(10)
var/ThisVarWontDoAnything = "junk"
ThisVarWontDoAnything = copytext(name, 3, 5)

It's similar to doing that. Using while in that ai snippet just doesn't do anything. It won't do anything because you're returning inside the loop, so it won't end up looping, and your looping is being done by having the function recall itself.