ID:2240836
 
Resolved
Bump() will now be called with areas as the argument, when an area has refused entry. Because of the potential for confusion in older code, this new behavior will only apply to projects compiled in version 511 or higher.
Applies to:DM Language
Status: Resolved (511.1382)

This issue has been resolved.
When you return 0 from /area/Enter() or Exit(), /atom/movable/Bump() is never called.

This may be intended, but let's view an example why this is undesirable:

obj/missile
density = 1
New()
..()
walk(src,EAST)

Bump(atom/movable/o)
Explode()

proc
Explode()
if(loc)
walk(src,0)
loc = null


If you have an area set up like this in the path of the missile object:

area
Enter(atom/movable/o)
if(o.z)
return !(density&&o.density)
return ..()

out_of_bounds
density = 1


Your missile will never detect an obstacle. You wind up having to do an annoying hacky workaround:

obj/missile
Move()
. = ..()
if(!.)
Collision()

proc
Collision()


Also, another really obnoxious issue is that this workaround doesn't work in pixel movement mode, so it gets worse:

obj/missile
Move()
. = ..()
if(.!=step_size)
Collision()


Oh wait, that's fucked up too because Move() might not be in increments of step_size if we want to call Move() as intended to relocate a target. Sometimes Move() will return 1 rather than the number of pixels moved because the move is a jump. Since there's no easy way to detect a jump, we need to:

Calculate the distance between our current location and our destination. If it's greater than step_size, or not on the same Z layer, bail out.


But wait, there's more. step() and walk() can be called with non-step_size arguments that effectively change the step_size of a movable for that particular step.

Which... Yeah, guess what, makes it so that in order to detect this properly we have to write our own Step()/Walk() wrapper functions because we can't override the built in ones.

Oh, and it gets worse too.

I can go on at length about this problem, but suffice it to say, call Bump() for /areas that refuse entry, and leave the problem of map edge collisions up to the developer to solve.
Seems like a reasonable change.

I believe the reason this happens currently is that Enter() failure on a turf doesn't include any provision for sending back the specific bumped object, forcing Move() to query the turf for objects that might have impeded it. (That's in non-pixel code obviously.) But area bumps should be simple to detect even in legacy code, and I honestly see no reason not to Bump() the area--at least in code compiled from 511 onwards.

I think this is a good change to make in the next 511 release. I really can't imagine any modern games relying on the bumpee not being an area if the area is capable of denying entry.
Hmm, some further thoughts on this after looking at Move(): In both pixel and non-pixel modes, Bump() is called when area.Enter() fails: but the bumpee is the destination turf if dense, or a dense object on it. The only difference from your desired behavior appears to be that if the GetDenseObjectAt() or GetDenseObjectAtEx() returns null, the bumpee is null when it should be the area instead. I can definitely change that behavior, but it seems like ideally you'd prefer that the area is bumped in addition.

Exit() failure never calls Bump(), so that part of the behavior I think it makes sense to leave unchanged.
Lummox JR resolved issue with message:
Bump() will now be called with areas as the argument, when an area has refused entry. Because of the potential for confusion in older code, this new behavior will only apply to projects compiled in version 511 or higher.