ID:1192438
 
(See the best response by Orange55.)
Code:
        proc
/******************/
/**COMBAT AI PROC**/
/******************/
CombatAI(/**/)
while(src)
if(!src.aggressive && src.maxpowerlevel > src.powerlevel)
src.aggressive=1
for(var/mob/player/M)
if(M in oview(/**/))
if(src.aggressive && M && get_dist(src,M)<=7)
if(get_dist(src,M)<=1)
src.dir=get_dir(src,M)
var/next_dir = get_dir(src,M)
switch(next_dir)
if(NORTHEAST){step(src,NORTH);sleep(5);step(src,EAST)}
if(NORTHWEST){step(src,NORTH);sleep(5);step(src,WEST)}
if(SOUTHEAST){step(src,SOUTH);sleep(5);step(src,EAST)}
if(SOUTHWEST){step(src,SOUTH);sleep(5);step(src,WEST)}
src.AIAttack(/**/)
else
step_towards(src,M)
break
else
step(src,pick(NORTH,SOUTH,EAST,WEST))
sleep(rand(9,12))
else

sleep(rand(4,6))


Problem description:
When there are 2 or more players oround can get buggy .. i want that monster attack the nearest player ...

Best response
(I think) The problem is that it cycles through each mob and executes the instructions you said, exactly as you said them. The solution is to give it a target variable and assign it the nearest mob for its value. Then have it walk towards and attack that mob until its dead.


Try out this simple AI I made

What it does : walks towards a mob, when around 2 mobs it will first target the closest one, then try attacking(moving towards), if it gets out of range it will target any other mobs in the area if there is none around, it will wander and continue to check to see if a new mob came around.

I like to build my AI in different blocks, thinking about what it does in segments of a total loop. In this case it does 3 things at different times, 1 target the closest mob, 2 attack only the target mob 3 wander around. You might try it when you make another AI?

Hopefully this helps.
mob
NPC
var/mob/target
New()
..()
spawn(10)
AI()
proc
AI()
wander_phase
step_rand(src)
sleep(10)
goto target_phase
target_phase
for(var/mob/M in oview(3,src))
target=M
goto attack_phase
goto attack_phase
attack_phase
if(target)
step_towards(src,target)
sleep(10)
if(get_dist(src,target)>4)
target=null
else
goto attack_phase
sleep(5)
target=null
goto wander_phase

If you want it to sometimes switch when there is multiple mobs around you may add something like this under the attack phase

if(prob(chance of switching to a new mob))
for(var/mob/M in oview(3,src)) //cycle through near mobs
if(!target==M) //if its not the current target
target==M //target that one instead
goto attack_phase //start attacking the new mob

^it stops cycling at attack_phase so it should target the nearest mob assuming you did something like this.

Good luck on your project

-Orange55