ScummVM version:
ScummVM 1.9.0git1868-gd35cdf5 (May 19 2016 09:14:40)
Features compiled in: TAINTED Vorbis FLAC MP3 RGB zLib MPEG2 FluidSynth Theora AAC FreeType2 JPEG PNG
Details:
In QFG3 (anthology version, English, no patches), room 750, when standing in the middle of the upper bridge, moving the character via the keyboard behaves incorrectly:
Pressing the LEFT key moves the hero to the right.
In SSCI, the LEFT key moves the hero to the left, as expected.
Attaching save games for ScummVM and SSCI.
Plaftorm: Windows 10
Maybe this could help:
When enabling Pathfinding debugflag, we get this output upon pressing the LEFT key:
The same problem also occurs when standing in the middle of the bottom plane (with the grass) and pressing the RIGHT key (the hero goes left):
I have a suspicion the problem has to with polygons of type
POLY_CONTAINED_ACCESS
(3).I managed to reproduce this behavior also in room 380, when pressing LEFT (hero goes upper-left):
I found that
fixup_end_point()
changes the endpoint from(-31782, 27)
to(284, 30
) which flips the direction from the hero's left to the hero's right side (the hero is at(233, 30)
).After this change it's clear why the pathfinding algorithm finds a path that moves the hero to the right.
Still need to figure what goes wrong in
fixup_end_point()
.Last edit: Omer Mor 2016-05-27
Further analysis:
I've got this backtrace:
The end point is very far the to west (-31,782). // explain why
fixup_end_point()
tries to fix it to the closest point in the containingPOLY_CONTAINED_ACCESS
polygon. It does that inPathfindingState::findNearPoint()
by iterating on the polygon's points and calculating comparing distances viaPoint::sqrDist()
.The problem is that
Point::sqrDist()
only supports distance in each axis up to 4,096 (0x1000
), When the distance is longer, it returns a constant0xFFFFFF
.As a consequence, the iteration in
PathfindingState::findNearPoint()
always calculates the same sqrDist from the end point, so the point it chooses is not the one with the minimal distance, but the ones that it happened to compare first with.I don't know why
Point::sqrDist()
has these limits, but I'll try to find out.Following a discussion with waltervn, here's what we concluded:
1. Calling
kAvoidPath
due to keyboard event should not result in real pathfinding: it is called with optimizing level of 0, which means it should simply return a direct path until an obstacle is hit. This meansfixup_end_point
probaly should not be called in this case. Assuming this is correct - then this is the root cause of the bug.2.
Point::sqrDist()
is capping the distance, and it's hard to tell why. This function goes back to the initial scummvm commit by Ludvig Strigeus from 2001. However since it's not the root cause - its not clear whether it should be fixed.