ID:273937
 
If you override a turf's Enter() proc to return 0, you can't enter it but Bump won't be called (the same happens with returning 0 in the Cross proc of a non-dense mob). In this case, how can the mob detect when an object has blocked its path?

If you override the mob's Move proc you can determine that the move failed, but short of re-creating the attempt to move when it fails there doesn't seem to be an easy way to find out what object (or objects) prevented you from making that move. With tile-based movement this isn't terribly difficult, but with pixel-based movement it is.

At first I thought this was a BYOND bug - if you're not able to enter a turf because it blocks your movement then you bumped it. I never used the Bump() proc much so I'm not sure if it always worked this way or not, but I have a feeling it's always been this way.

I had expected that the default Enter proc would check if you're allowed to enter or not, then, whatever proc calls Enter() would, based on the result, either perform the move or call Bump(). Another way of asking this question is, what causes bump to be called and is there any way to customize that behavior? The reference says that it's called when movement fails due to a dense blockage, but it seems like that's what Enter() lets you do - it lets you define when an object behaves as a dense blockage.
From F1:
Areas, objs, and mobs will always permit anything to enter by default.

Turfs will return 1 (permit) or 0 (deny) based on density. In simple terms, if the atom that is entering is dense, then the turf will deny entry if the turf itself or its contents (any that take up the full tile) are dense.

What actually happens in turf.Enter() is more detailed: The turf's density is checked against the object's density first. If this check succeeds (movement is permitted), then Cross() is called for any atoms in turf.contents that cover the entire tile. If any Cross() call fails, Enter() fails too and will return 0.

If a mob is standing on a turf but its bounding box does not cover the whole tile, it is ignored by Enter(). Instead, its Cross() proc is called if there is a danger of the object overlapping it.


But also I feel I read somewhere Enter() calls Bump(), however I cannot find it now, maybe I made a mistake...
Unless you have overwritten the built-in Enter proc somewhere for whatever object you are trying to bump into, then by default, the Bump() proc would be called when movement is denied due to two dense objects colliding.
In response to Zaoshi
Zaoshi wrote:
But also I feel I read somewhere Enter() calls Bump(), however I cannot find it now, maybe I made a mistake...

I couldn't find anything that said that, but that's probably correct. It's unfortunate if this is correct...

The Enter proc should answer the question "if this mob were to try to enter this object, would it be allowed?", instead it answers the question "this mob *is* trying to enter this object, is it allowed, and what happens if it's not allowed?". Whatever default movement proc calls Enter() should be responsible for calling Bump.

This would make the Enter proc easier to use and be more useful. By overriding it to have custom logic for who is allowed to enter you're not also responsible for recreating the default behavior of what should happen if the move isn't allowed. You'd also be able to call the Enter proc in other situations. For example, if you use the Enter() proc to create one-way tiles your pathfinding routines will fail because, even though the tiles are non-dense, you can't Enter them from all directions. If you could write a pathfinding routine that calls Enter() to see what tiles you're allowed to move through, you can plan a correct path without invoking side-effects (ex: calling Bump() when you check moves that would be denied).
In response to Spunky_Girl
Spunky_Girl wrote:
Unless you have overwritten the built-in Enter proc somewhere for whatever object you are trying to bump into, then by default, the Bump() proc would be called when movement is denied due to two dense objects colliding.

The problem is that when I do override the Enter() proc, the Bump() proc isn't being called. For example:

turf
density = 0
Enter()
return 0


The turf will block your movement but Bump is never called.

It doesn't appear to be that the Bump() proc is being called from Enter(). If, in that example, you set the turf's density to 1 it still calls Bump().

It seems like whatever movement proc calls Enter() is calling Bump(), which is good (it's good that Enter isn't calling Bump directly), but it's not calling Bump() because Enter() returned zero, it's calling Bump() because the turf is dense and because Enter() returned zero. It seems like the logic to determine whether or not an atom blocks your movement exists in two places, and Enter() is only one of those places (and I have no idea what the other place is).