ID:1312252
 
(See the best response by Danny Roe.)
Problem description: So I want to set destinations for my NPC's and I'm trying to make it so when the NPC enters a certain turf, it changes the NPC's next to target to the next turf. However i seem unable to change the target. Not sure if it's whether because I'm using ismob(). But it will walk to the first target then just step back and stop.

Note: I've also tried using /area/ to do this.

Code:
        A
icon_state = "dirt"
Entered(mob/M)
if(ismob(M))
M.target = "B"
Are your targets going to remain at a constant location (e.g. walk to 5,5,1 then walk to 10,5,1)?
Yes I believe so? I'm trying to think what you're thinking and how I would go about it. Using locate in someway I'm guessing?
Indeed, it would be easier to give an npc a list of locations, then have it move to those locations one at a time.
How would i go about defining a list of locations? Also how would i check the location to change to the next one? I'm assuming I could use get_dist, but whether that'd be efficient or not, I'm not too sure.
If you've modified the movement proc in any way, you'll find that you may have over ridden any call of the 'Entered()' proc.
In response to Xerif
Xerif wrote:
If you've modified the movement proc in any way, you'll find that you may have over ridden any call of the 'Entered()' proc.

I did modify the Move() proc but I undid that before I posted here. One of my first thought's was to check Move().
As this problem is entirely based around your NPC, it would help if you could provide the code.
        AI()
var/obj/treasure/T
var/turf/turfs/A/A
var/turf/turfs/B/B
var/turf/turfs/C/C
if(target == "A")
for(A in view(6,src))
step_to(src,A)


Also if I do this

        A
icon_state = "dirt"
Entered(mob/M)
if(ismob(M))
..()
sleep(1)
M.target ="B"


The NPC will step onto the turf but target won't become B and then he will turn around and step south.
All of it.
I just changed some stuff and this seems to work all though not perfect. Got it to move at a decent pace. But doesn't stop once it reaches A.

        A
icon_state = "dirt"
Entered(mob/M)
if(ismob(M))
M.ChangeTarget()
..()


NPC and ChangeTarget()

mob
//var npcspeed
proc
AI()

ChangeTarget()
if(target == /turf/turfs/A/)
target = /turf/turfs/B/
world << "[target]"
ai

New()
..()
spawn(10) AI()

AI()

for(target in view(6,src))
walk_to(src,target,1,5,16)

spawn(15) AI()


I also turned pixel movement on now.
It's most certainly not the best way to do things, but as long as it works, and as long as you're learning-- good luck.
Thanks, I realise this isn't the best code either and I'll probably work on it till I get something more stable. Also if I used this to change target would it be better.

if(get_dist(src, target) < 0 && target == /turf/turfs/A/) //would need multiple ifs
target = /turf/turfs/B/ //either this or the changetarget proc.

Best response
This seems to work fine when I tested it, the only issue I ran into was using step_to() when the mobs
step_size was less than the worlds icon_size.

First we store a list of X,Y,Z locations that we want our mob to walk to (as shown below). The order you enter these locations in the list is the order in which the mob will move to them.
mob/var/list/targetLocs = list("x=10;y=1;z=1","x=10;y=10;z=1","x=1;y=10;z=1","x=1;y=1;z=1")

We will extract the locations from the text format we entered them as using this proc.
proc/text2loc(params)
if(!params)
return
var/list/L = params2list(params)
if(!L)
return
if(L.len < 3)
return
return locate(text2num(L["x"]), text2num(L["y"]), text2num(L["z"]))

And here is our walk_path() proc which will walk the mob to each location one at a time until it reaches the last location in the list. As we are using step_to, the mob will walk around any dense obsticles.
mob/proc/walk_path(var/list/path)
var/stops = 1
while(stops<=length(path))
step_to(src,text2loc(path[stops]))
//Use <=1 if mob.step_size is less than the icon_size
if(get_dist(src,text2loc(path[stops]))<=0)
stops++
sleep(world.tick_lag)


Test it out.
mob/var/list/targetLocs = list("x=10;y=1;z=1","x=10;y=10;z=1","x=1;y=10;z=1","x=1;y=1;z=1")

mob/verb/WalkThePath()
src.walk_path(targetLocs)

mob/proc/walk_path(var/list/path)
var/stops = 1
while(stops<=length(path))
step_to(src,text2loc(path[stops]))
//Use <=1 if mob.step_size is less than the icon_size
if(get_dist(src,text2loc(path[stops]))<=0)
stops++
sleep(world.tick_lag)

proc/text2loc(params)
if(!params)
return
var/list/L = params2list(params)
if(!L)
return
if(L.len < 3)
return
return locate(text2num(L["x"]), text2num(L["y"]), text2num(L["z"]))
Thanks danny, really helpful. Not quite sure how everything works yet but most makes sense, gonna reference the stuff I don't understand mind. Once again thankyou.