ID:1801275
 
(See the best response by Lummox JR.)
Code:
            action()

if(dead)
slow_down()
return

move(dir)

if(at_edge())
turn_around()

if(!target)
get_target()

if(target)
if(shooting || target:dead) return

if(bounds_dist(src,target) > 90)
target = null
return

var/turn_to = get_dir(target, src)

if(dir == turn_to)
turn_around()

shoot(dir)

..()

get_target()
for(var/mob/m in oview(5, src))
if(m.dead)
return

src.target = m


Problem description: How would I set about improving this piece of code? The turn_to variable I couldn't figure out another way for the NPC to face the player.

Bounds_dist is the only way I could figure to clear the target and stop the NPC from shooting.

Please note I'm using the forum_account sidescroller library, the code works I just want to learn to improve. A bit of this I just made from the reference.

Also you'd have probably laughed when you seen my first attempt at this, it used to 3 bullets rapidly then a copy of my character in a random direction.

Best response
Going over some of the trouble spots:

                if(target)
if(shooting || target:dead) return

Is target defined as a mob var? If so, then you shouldn't need the : operator; you should be using the . operator instead which can check var safety at compile time. If you've only defined the dead var under a subtype such as /mob/player, then this would point to a design flaw.

                    var/turn_to = get_dir(target, src)
if(dir == turn_to)
turn_around()

This does not look right. If you want to face the target, then the call should be get_dir(src, target), and you want to change directions if dir does not match turn_to. At the moment, it appears your mob will only turn around if they're facing exactly the other way.

            get_target()
for(var/mob/m in oview(5, src))
if(m.dead)
return
src.target = m

You want continue, not return. Return will bail out of this loop as soon as it finds a dead mob, instead of skipping on to the next one.
Thanks for the information Lummox, dead is a mob var. But when I try using the . operator it comes up as an undefined var? Is this down to how I'm handling the target var?

Also when i first wrote the turn_to I did it that way first but still had dir == turn_to. Misinterpretation on my part.

I also never knew continue worked like that. Again thank you for the information.
Could this be the reason why the . operator is an undefined variable? My NPC's are setup up like this.

mob
enemy
enemy1
//rest of code


Edit: Never mind I tested as just under mob and it still won't let me use the . operator.

P.s sorry for the double post.
How did you define the target var?
mob
var
target
There's your problem. As I said, you have to define target as a mob. That should be var/mob/target, not var/target. Unless you have any reason that your target might not be a mob (if it's not null, that is), define it as a mob.
I see what you mean now, thank you once again Lummox.

This is what I have now. I also realized i never needed the turn_to var.

            action()
var/mob/target

if(dead)
slow_down()
return

move(dir)

if(at_edge())
turn_around()

if(!target)
target = get_target()

if(target)

if(shooting || target.dead) return

if(bounds_dist(src,target) > 90)
target = null
return

//var/turn_to = get_dir(src, target)

if(dir == target.dir)
turn_around()

shoot(dir)

..()

get_target()
for(var/mob/m in oview(5, src))
if(m.dead)
continue

return m
target.dir is the direction the target is facing. Your code now says: If I'm facing the same way the target is facing, turn around.

You're not thinking it through. Your first code was closer to correct as it used get_dir(), which tells you the direction from the first object to the second; you merely had the order wrong, and you should not be calling turn_around()--you should just set src.dir to whatever you need to.
I'm sorry if I'm annoying you but more like this?

                    var/turn_to = get_dir(src, target)

if(dir != turn_to)
dir = turn(dir, 180)


This works till the player jumps and the npc turns the opposite way. Think that's down to the library more than anything.
You don't need to call turn(). You don't need to do anything here except set src.dir to match turn_to.

// face the target
dir = get_dir(src, target)

That's all you need.

If you need to face only in one of four directions, or get an approximate dir (so something mostly north doesn't count as northeast, for instance), there's an old forum thread with a snippet I posted a while back. I'll see if I can find it.
Found the link to get_approx_dir().
Well now I feel pretty stupid. Thanks for your help and being patient with me Lummox. I understand people who aren't getting the point can be frustrating.