ID:2211319
 
(See the best response by FKI.)
Hey, so I made a visual effect like this:

        effect
layer = FLY_LAYER
New()
flick("effect",src)
sleep(5)
del src


The effect is created on src.loc (where the player is) everytime he uses a verb. The problem is, src.loc = locate() calculates the position in tiles, not in pixels... So sometimes the effect is created in the wrong position, because the player is not on the center of the tile, but a bit to the left/right.

How can I fix this? Does bounds have any use for this?
Best response
Check this out.

Also, [especially] for a simple object such as that, you can simply set loc to null to delete it. Avoid using del() where and whenever possible.
I'll take a look.

Also, just for the sake of learning, why should I avoid using del?
In response to DarkHitz
It's bad for performance and widespread use of it will slow your game down.

When you use del(), references to the object have to be forcefully cleansed from other potential watcher objects in the world (or something very similar to this).

When you get rid of references to the object yourself and set loc to null, there is no need to do all that processing because you handled it, so the object can just be deleted.
That's cool, I didn't know that...
The results are the same as using del() though, right?
In response to DarkHitz
Right.
In response to DarkHitz
DarkHitz wrote:
I'll take a look.

Also, just for the sake of learning, why should I avoid using del?

The del operator forcibly deletes an object.

Most objects in BYOND are reference-counted. That is, they keep track of how many other things have references to them. If an atom has a location or is on the map, its location counts as a reference. (Turfs are always self-referenced. They can only be deleted by shrinking the map or shutting down the world.) If it's referred to by a var somewhere, that's a reference. If it's in a list somewhere, that's a reference. Basically a reference means that something in the server, somewhere is holding onto this object and doesn't want to let it go yet. An object will always disappear on its own as soon as all of its references are cleared. Conversely, this also means that in certain situations an object might never disappear at all without help, like for example when you have a circular reference: A references B and B references A.

The easiest and quickest way to get rid of an object in BYOND is to let all of its references go away. With most atoms, it's very common that nothing is referencing them except for their location and any procs they might be running. So if you have a projectile and change its location to null, there's a good chance it will go away--unless something else is keeping track of it somewhere. If a projectile is using walk(), you'd want to stop the walk first, but otherwise after that you can probably set loc=null and that'll be enough to remove it once the proc ends.

When you use the del() operator, you're telling BYOND that you really, really want this object to go away now. The object knows how many references it has, but it doesn't know what those references are. (Tracking that information would be very, very bad for performance.) So the only way the server can comply with your request is to go hunting for references, and null them out, until there are none left. If you have any references you forgot about, this exhaustive search can be a performance killer--under bad circumstances, anyway, like if you put the object in a list and forgot about it.

In practice, calling del() will usually kill off the most obvious references first. With an atom (non-turf, non-area) it will change the location to null for you, and that may be enough to obviate the need for an exhaustive search. It will delete the atom's contents and vars, and that too will often be enough that it will get rid of any likely circular references. Like if you have an obj (O) in your mob's (M) contents that keeps a reference to you as its owner, that's a circular reference; but if you delete M, the act of removing O from its contents first will probably cause O to be deleted first, thereby deleting the reference O has to M. So really del() works fine in most cases--it just has a potential to be bad, if you're really lax about where you put your references.

Following a pattern in your code of removing unneeded references whenever possible will not only make the worst-case scenario less likely, but it will also make it more likely that objects will delete themselves all on their own when you don't need them anymore. Basically it's less about never using del() as being mindful of your references.
I use this to center my movables
atom/movable/proc
centerOnTile()//center a movable on its tile
step_x = (TILE_WIDTH/*your worlds tile width size in pixels*/ - bound_width)/2 - bound_x
step_y = (TILE_HEIGHT/*your worlds tile height size in pixels*/ - bound_height)/2 - bound_y
CenterOnM(atom/movable/m) // center the source step x/y onto m
step_x=m.step_x + (m.bound_width - bound_width)/2 - bound_x + m.bound_x
step_y=m.step_y + (m.bound_height - bound_height)/2 - bound_y + m.bound_y
In response to Zagros5000
I use this to center my movables (center a on b):
a.SetCenter(b)

Don't worry about the unnecessary details.
Thanks FKI and Lummox, it's worth learning that.
Zagros and Kaio, that helped (: thanks.