ID:141690
 
Maybe I'm just tired or something, but I keep getting strange errors with some pretty straightforward code.

runtime error: Cannot read .type
proc name: MOVE (/atom/movable/proc/MOVE)
source file: Pixel Movement.dm,32
usr: Jeff8500 (/mob)
src: Jeff8500 (/mob)
call stack:
Jeff8500 (/mob): MOVE(0, 1)
Jeff8500 (/mob): UP()


var/controller/control = new

controller

var/list/move = new
var/paused

New()
..()
for()
if(!paused)
for(var/atom/movable/A in move)
var/move_container/MC = move[A]
A.pix_move(MC.x,MC.y)
move -= A
sleep(world.tick_lag)

proc/add(atom/movable/A,x,y)
move[A] = new /move_container(x,y)

Del()
world << "FOIK"
..()

atom/movable/proc/MOVE(x=0,y=0)
world << "[control.type]"
control.add(src,x,y)


The control datum does exist (it is never deleted, I checked by sending a debug message to the log and output, and got nothing). It just doesn't seem to want to read it's vars, such as type and move (and it claims it is null when I called add()).
Seems like the "invalid src" bug... try adding in if(control) and if(!control) before, and see if one of them automagically solves the issue.
spawn() off that infinite loop. New() is never returning, and it's stuffing stuff up.
atom/movable/proc/MOVE(x=0,y=0)
world << "[control.type]"
control.add(src,x,y)


Bad Things™ can happen setting x and y directly, like making src null. This is probably your issue.
In response to Xooxer
Hm? But x and y are proc arguments...?
I'm not even sure Bad Things™ are triggered by such specific causes such as not returning from New() or setting a coordinate var (which I don't think is as bad as it is unrobust)... ?
In response to Kaioken
Arguments of a proc for a movable atom, which has x, y and z variables already. BYOND is almost certainly seeing these as the x and y vars of the atom, not as local arguments of that proc. Setting these in turn directly, instead of using locate() can have undesirable effects.
In response to Jp
Thanks, that fixed the issue. I can't believe I forgot to let it return!
In response to Xooxer
Xooxer wrote:
Arguments of a proc for a movable atom, which has x, y and z variables already. BYOND is almost certainly seeing these as the x and y vars of the atom, not as local arguments of that proc. Setting these in turn directly, instead of using locate() can have undesirable effects.

The proc will use the local arguments, not the src objects'.

There is also no undesirable effects of setting x, y and z - Any more than trying to do mathematical calculations with strings, trying to add to a list that is null, etc. The reason the reference states that it is 'advised' that you use locate(), is that its a good idea to make sure you're putting them somewhere that exists.
In response to Alathon
Alathon wrote:
The proc will use the local arguments, not the src objects'.

That doesn't make any sense at all. If you try declaring a var named x in an atom/movable's anything, you get an error, so why is it an exception to be able to declare them as arguments? I don't believe it is.
In response to Xooxer
Xooxer wrote:
That doesn't make any sense at all. If you try declaring a var named x in an atom/movable's anything, you get an error, so why is it an exception to be able to declare them as arguments? I don't believe it is.

It makes perfect sense.

mob/proc/Test(x,y,z)
src.x = x
src.y = y
src.z = z


Variables declared in a procedure take precedence over variables that belong to src.


In response to Alathon
I'm still not buying it. How does the compiler know that x is x and not src's x? And how re args so special. You can't declare x in the proc, so why do you think you can in the args?
In response to Xooxer
Xooxer wrote:
I'm still not buying it. How does the compiler know that x is x and not src's x? And how re args so special. You can't declare x in the proc, so why do you think you can in the args?

I'm not debating whether this is possible or not. I'm telling you it is :s

mob/proc/Test(x=5, y=5, z=5)
world << "yee [x] [y] [z]"

mob/verb/Yee()
Test()


The above will output 'yee 5 5 5'.

As I said, variables declared as arguments to a procedure take precedence over variables that belong to src. I also don't know why you think you can't declare x in the proc, did you ever even try this?

mob/proc/Test()
var
x = 5
y = 5
z = 5
world << "yee [x] [y] [z]"

mob/verb/Yee()
Test()


The above is identical to the first snippet posted, and works as expected as well. While I don't know the exact logic involved, a good guess would be the following:

* Is any variable local to the procedure running declared, called n?
** Yes. Use that. Note that local here is either an argument, or anything declared with 'var' inside the procedure.
** No. Does src have a variable called that?
*** Yes. Use that.
*** No. Is there a global variable called that?
**** Yes. Use that.
**** No. Error!
In response to Xooxer
Variable scope, basically. I'm not 100% sure, but here's how the precedence is (I think, sorry if I'm wrong):

Local variables take precedence over global variables, which take precedence over src variables. Much in the same way that global procs take precedence over src procs.

Arguments are really not different to local variables, if you define var/x in the arguments and again in the local scope, you'll hit a duplicate definition error.
In response to Alathon
I'm not arguing with you either. I'm telling you I don't believe you. There's a difference.

Well that is madness. Even if it's true, it's crazy.
In response to Stephen001
That's nice. I think Alathon has it covered.
In response to Stephen001
Stephen001 wrote:
Local variables take precedence over global variables, which take precedence over src variables. Much in the same way that global procs take precedence over src procs.

I was in doubt about this, so I tested. src does in fact take precedence over global variables.

var/y = 2
mob/proc/Test()
var
x = 5
z = 5
world << "yee [x] [y] [z]"


Outputs 'yee 5 1 5'
In response to Alathon
Just clocked it myself, was going to trim the post but I have replies now. =P
In response to Alathon
Where'd the 1 come from?
In response to Xooxer
It's also basically the same as the scoping rules in every programming language ever invented. Java does the same thing. C++ does the same thing.
In response to Kaiochao
Kaiochao wrote:
Where'd the 1 come from?

Mobs are placed at 1,1,1 by default. Thus, 5(the x defined in the proc) 1(the y of src) 5(the z defined in the proc).