ID:1372784
 
Resolved
Uncross() was not called for objects that covered a full tile.
BYOND Version:499
Operating System:Windows 7 Home Premium
Web Browser:Firefox 23.0
Applies to:Dream Daemon
Status: Resolved (500.1205)

This issue has been resolved.
Descriptive Problem Summary: Uncross() is not called when stepping off an object in my test environment.

Numbered Steps to Reproduce Problem: Apply the Cross() and Uncross() procs to an object, try walking over said object.

Code Snippet (if applicable) to Reproduce Problem: Link to topic created in Developer Help regarding problem.
obj/Cross_Test
icon='Iso64.dmi'
icon_state="density"
Cross(mob/M)
if(istype(M,/mob))
world << "Cross() Allowed"
return 1

Uncross(mob/M)
if(istype(M,/mob))
world << "Uncross() Forbidden"
return 0


Expected Results: Attempt to step onto object, recieve message "Cross() Allowed", step onto object. Attempt to step off object, recieve message "Uncross() Forbidden", can't step off object.

Actual Results: Attempt to step onto object, recieve message "Cross() Allowed", step onto object. Step off object successful with no messages.

Does the problem occur:
Every time? Or how often? Every Time
In other games? Not sure
In other user accounts? Yes
On other computers? Yes

When does the problem NOT occur? Have not been able to do this.

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked? Noticed the problem whilst using 499.1201, updated to latest version and problem still existed.

Workarounds: N/a

In your code, if M isn't a mob, Cross() will never call ..() because you've overwritten its code. The same is true for Uncross()

obj/Cross_Test
icon='Iso64.dmi'
icon_state="density"
Cross(mob/M)
if(istype(M,/mob))
world << "Cross() Allowed"
return 1
return ..()

Uncross(mob/M)
if(istype(M,/mob))
world << "Uncross() Forbidden"
return 0
return ..()


But I suspect there's something else causing your problems, judging by your icon name "iso64" you're doing something with isometric mode.
Completely forgot about that. And yes I'm running it in Isometreic mode.
I'll need more information on this one because my tests definitely do not produce this issue. Adding an Uncross() like yours to the original pixel movement demo shows no problems at all.

The only situation I can think of that could be an issue would be if pixel movement is not in play, in which case the older movement routines take over. The reference says Enter() calls Cross() by default when an obj completely covers it, but it doesn't say anything about Exit() doing the same for Uncross(), and the code confirms this. It would make sense for Exit() to behave the same way, though.
Lummox JR changed status to 'Verified'
I gave the non-pixel form a test just to confirm and yes, I do see it in that mode. I think that must be what you meant. While from all appearances this looks like this Cross/Uncross behavior without pixel movement was left asymmetrical for a reason, I honestly don't know why I did so. That tips it more into the realm of bug than missing feature so it's definitely something I'll fix for the next release.
This in a fresh project:
world
maxz = 1
maxx = 5
maxy = 1
fps = 10

obj/test
Cross(atom/m)
world << "[world.time]: Cross: [m] [m.dir]"
return ..()

Crossed(atom/m)
world << "[world.time]: Crossed: [m] [m.dir]"
..()


Uncross(atom/m)
world << "[world.time]: Uncross: [m] [m.dir]"
return ..()

Uncrossed(atom/m)
world << "[world.time]: Uncrossed: [m] [m.dir]"
..()

mob
step_size = 16

Login()
..()

loc = locate(1, 1, 1)

new /obj/test (locate(3, 1, 1))

do
world << "[world.time]: [(locate(/obj/test) in obounds()) ? "over" : "not over"]"
sleep world.tick_lag
while(step(src, EAST))

Produces this output:
0: not over
1: not over
2: not over
3: Cross: Kaiochao 4
3: Crossed: Kaiochao 4
3: over
4: over
5: over
6: Uncrossed: Kaiochao 4
6: not over
7: not over
8: not over

Using pixel movement, Uncross() isn't called. In tile movement, it's no different:
0: not over
1: not over
2: Cross: Kaiochao 4
2: Crossed: Kaiochao 4
2: over
3: Uncrossed: Kaiochao 4
3: not over
4: not over


edit: Making the /obj/test smaller than a tile fixes it. I suspect this has something to do with it, somehow:
DM Reference (Cross()):
If src completely covers the turf it is standing on, Cross() is called as part of turf.Enter(). This is to preserve the behavior of older games, which expect turf.Enter() to care about its contents.
Cross or Uncross may be ignored in certain situations, depending on the Enter/Exit of the movable atom's loc.
I can't think of any situation where Cross() would fail to be called that calling it would necessarily be desirable; that is, if something else stops a movement from happening, there's no guarantee CanCross() will be called since it would be redundant.

Likewise with the new behavior for Uncross() when pixel movement isn't in play, if a turf signals 0 in Exit(), it doesn't have to call Uncross() for its contents.
Lummox JR resolved issue with message:
Uncross() was not called for objects that covered a full tile.