ID:264453
 
Code:
mob/Spell
verb
Accio(obj/O in world)
set category = "Spells"
var/cancast = Casting(usr)
if(cancast)
walk_to(O,usr,1,5)
gff
sleep(10)
for(var/obj/A in range(1,usr))
if(A==O)
walk(O,0)
return
goto gff


Problem description: I'm basically trying to making it so that I can summon objects and then they'll walk to me. I can achieve this with a goto (as seen above), but I know that's just asking for trouble. Could someone please help me figure this out?
I don't see why you need goto or any loop here at all. All you need to do is call walk_to() appropriately, and that's it. You don't need any of your loops (which are kinda bad and unoptimized, etc, as it is), which worry about stopping the walking once the object gets near enough - look up the actual walking proc you're using: it's got an argument for this exact purpose, that stops the walking once the object gets to the specified distance from its destination.
In response to Kaioken
Yes, and I'm sure that if you had a good look you would've noticed I'm using it =P. However, all it does is stop the obj from going any further from where I've specified. If I move at all, the obj will follow.
In response to Demon_F0rce
Demon_F0rce wrote:
Yes, and I'm sure that if you had a good look you would've noticed I'm using it =P.

Well, I did, but that didn't necessarily mean you understood it, for all I knew.

However, all it does is stop the obj from going any further from where I've specified. If I move at all, the obj will follow.

Ah, my bad, though you should've specified you didn't want that - all I saw in your description was basically that you wanted the obj to come to you, which what I said accomplishes.
In that case, you naturally have a number of options. For example, if both the obj and the mob are dense, you could set the Max argument to 0, which means the obj will try to get to the mob's loc but will fail and Bump() it, where you can halt the walking. Or, if they are not both necessarily dense then you could check whenever the obj moves if it has reached its destination.
However, IMO the above approaches aren't good enough - what you should really do is make your own custom function to use instead of the built-in walking one, which behaves and does exactly what you want. That way you don't need the extra mess involved with getting walk_to() to behave like you want (you'll need to keep an extra var, override obj/Move() or turf/Entered()....).

Just use a loop (such as while() - try and get used to never using goto) that keeps moving the obj one step (each iteration) at a time to its destination, and stops when you want it to. You still don't need to make everything on your own, you can just use the built-in stepping functions. Here's an (psuedocode, so I won't be doing all your work for you) example:
atom/movable/proc
my_walking_function(Dest,Max,Lag)
spawn(-1) /*spawn here so the function doesn't
hold up the caller, similarly to the built-in walk()s.
(the -1 delay isn't necessary, but it tries to make it
process with as little delay as possible) */

while the source isn't within Max steps of Dest
step the source closer to Dest
wait the lag time

Functions of interest: while(), get_dist(), step_to(), the rest should be common sense.
In response to Kaioken
Okay, thanks for that. Got this up and running in no time thanks to you.
In response to Demon_F0rce
You're welcome, happy to help. =) Just to make sure, what did your end result look like?
In response to Kaioken
atom/proc
my_walk_to(atom/Source,atom/Dest,MDist as num,Lag as num)
spawn(-1)
while(get_dist(Source,Dest) != MDist)
step_to(Source,Dest)
sleep(Lag)
walk(Source,0)
In response to Demon_F0rce
That works, but there is an issue with that and some extra stuff you don't need:
  • Unneeded stuff:
    • The Source argument. This is an object proc, you're meant to call it on the right object and you should use the src var to refer to it: src == the source of the proc.
    • The 'as num' definitions; they won't do harm and are nice for clarity, but do note they aren't required and the 'as' keyword in arguments is for verbs* initiated by players only - they do nothing in regular procs.
      <small>*: Or procs which are used as verbs, but let's not complicate this.</small>
    • The walk() call isn't required, but I guess it could be nice to terminate any built-in walking on the object, so you may choose to keep it in.
  • Also, for robustness you should use the > operator instead, in the distance check - that way it would stop if the distance was smaller, currently if it was then it would keep trying to get closer.
In response to Kaioken
Kaioken wrote:
The Source argument. This is an object proc, you're meant to call it on the right object and you should use the src var to refer to it: src == the source of the proc.

Yeah, I thought about this and thought that maybe I should put in the Source argument just in case.

The 'as num' definitions; they won't do harm and are nice for clarity, but do note they aren't required and the 'as' keyword in arguments is for verbs* initiated by players only - they do nothing in regular procs.

I simply put this here to prevent constant walking as this means they will always be numbers and, yes, for clarity.

The walk() call isn't required, but I guess it could be nice to terminate any built-in walking on the object, so you may choose to keep it in.

Really? My bad XD. I just thought "Okay, it's walking... Okay, it's done. Better cancel walking".

Also, for robustness you should use the > operator instead, in the distance check - that way it would stop if the distance was smaller, currently if it was then it would keep trying to get closer.

Right here, I went over it after I posted the code. I then thought "Well, Source will never get closer that MDist, so I may as well just leave it".
In response to Demon_F0rce
Demon_F0rce wrote:
Yeah, I thought about this and thought that maybe I should put in the Source argument just in case.

Well, you should use src.

I simply put this here to prevent constant walking as this means they will always be numbers

Well, no. As I pointed out to you in my previous post, those "as num" do absolutely nothing there execution-wise; read that part again. It's still possible to pass, say, a string as that argument - it doesn't really make anything sure.
This is a similar common misconception, so keep in mind the variable type definitions (e.g. var/mob/M) don't make sure the var only holds a value of that specific type - they don't affect the value at all, they're just used to pass info to the compiler. If you want to make sure a var's value was of a specific type, you need to verify it with procs such as isnum() and istype().

Really? My bad XD. I just thought "Okay, it's walking... Okay, it's done. Better cancel walking".

That would apply if we were using a 'walking function' (such as walk(), walk_to()) there, but we're not. We're using a 'stepping function' (e.g. step()), it only makes one step at a time and so doesn't need to/can't be canceled.

Right here, I went over it after I posted the code. I then thought "Well, Source will never get closer that MDist, so I may as well just leave it".

There could be scenarios when that could happen though, for example the proc could be called with the obj closer than MDist to begin with, so best do it robustly to make sure. =)
In response to Kaioken
Okay, did what you suggested and made the changes and all that jazz =P. Final product:

atom/proc
my_walk_to(atom/Dest,MDist,Lag)
if(!isnum(Lag)||!isnum(MDist)) return
spawn(-1)
while(get_dist(src,Dest) > MDist)
step_to(src,Dest)
sleep(Lag)

So yeah, thanks for your help XD.
In response to Kaioken
Alternatively: just walk_to() the player's location. Turfs don't move much.
In response to Garthor
Not really the same effect, but a worse one; if the player moves since the movement began but before it ended, the obj won't walk straight to him, but instead to the old turf destination.
In response to Kaioken
He said "where I specified". Which implies a static location, not "follow me until you tag me, then stop".
In response to Garthor
Garthor wrote:
He said "where I specified".

Hmm, where?

"follow me until you tag me, then stop".

I'm pretty sure that's essentially exactly what he wants - the obj to go to the player (and stop once it reaches him). =) Also fits it with it being a 'summoning'.

Demon_F0rce wrote:
I'm basically trying to making it so that I can summon objects and then they'll walk to me.
Etc.