Skip to content

Commit

Permalink
TSAGE: Try to clarify more pathfinding code.
Browse files Browse the repository at this point in the history
  • Loading branch information
fuzzie committed Jun 8, 2011
1 parent 1529287 commit 89ed49d
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 85 deletions.
164 changes: 81 additions & 83 deletions engines/tsage/core.cpp
Expand Up @@ -530,10 +530,14 @@ void PlayerMover::pathfind(Common::Point *routeList, Common::Point srcPos, Commo
continue;
}

_globals->_walkRegions._field18[0]._pt1 = srcPos;
_globals->_walkRegions._field18[0]._pt2 = srcPos;
_globals->_walkRegions._field18[1]._pt1 = destPos;
_globals->_walkRegions._field18[1]._pt2 = destPos;
// field 0 holds the start, and field 1 holds the destination
WRField18 &currSrcField = _globals->_walkRegions._field18[0];
WRField18 &currDestField = _globals->_walkRegions._field18[1];

currSrcField._pt1 = srcPos;
currSrcField._pt2 = srcPos;
currDestField._pt1 = destPos;
currDestField._pt2 = destPos;

int tempList[REGION_LIST_SIZE];
tempList[0] = 0;
Expand All @@ -558,49 +562,52 @@ void PlayerMover::pathfind(Common::Point *routeList, Common::Point srcPos, Commo

tempList[idx] = 1;
for (int listIndex = 1; listIndex <= endIndex; ++listIndex) {
int var10 = tempList[listIndex];
int var12 = tempList[listIndex + 1];
int thisIdx = tempList[listIndex];
int nextIdx = tempList[listIndex + 1];

WRField18 &thisField = _globals->_walkRegions._field18[thisIdx];
WRField18 &nextField = _globals->_walkRegions._field18[nextIdx];

if (sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var12]._pt1,
_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2) &&
sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var12]._pt2,
_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2))
if (sub_F8E5_calculatePoint(currSrcField._pt1, nextField._pt1,
thisField._pt1, thisField._pt2) &&
sub_F8E5_calculatePoint(currSrcField._pt1, nextField._pt2,
thisField._pt1, thisField._pt2))
continue;

Common::Point tempPt;
if (sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[1]._pt1,
_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2, &tempPt)) {
if (sub_F8E5_calculatePoint(currSrcField._pt1, currDestField._pt1,
thisField._pt1, thisField._pt2, &tempPt)) {
// Add point to the route list
_globals->_walkRegions._field18[0]._pt1 = tempPt;
currSrcField._pt1 = tempPt;
*routeList++ = tempPt;
} else {
int v16 =
(findDistance(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var10]._pt1) << 1) +
(findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[1]._pt1) << 1) +
findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var12]._pt1) +
findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var12]._pt2);

int v1A =
(findDistance(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var10]._pt2) << 1) +
(findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[1]._pt2) << 1) +
findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[var12]._pt1) +
findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[var12]._pt2);

if (v16 < v1A) {
checkMovement2(_globals->_walkRegions._field18[var10]._pt1,
_globals->_walkRegions._field18[var10]._pt2, 1, objPos);
int dist1 =
(findDistance(currSrcField._pt1, thisField._pt1) << 1) +
(findDistance(thisField._pt1, currDestField._pt1) << 1) +
findDistance(thisField._pt1, nextField._pt1) +
findDistance(thisField._pt1, nextField._pt2);

int dist2 =
(findDistance(currSrcField._pt1, thisField._pt2) << 1) +
(findDistance(thisField._pt2, currDestField._pt2) << 1) +
findDistance(thisField._pt2, nextField._pt1) +
findDistance(thisField._pt2, nextField._pt2);

// Do 1 step of movement, storing the new position in objPos.
if (dist1 < dist2) {
doStepsOfNpcMovement(thisField._pt1, thisField._pt2, 1, objPos);
} else {
checkMovement2(_globals->_walkRegions._field18[var10]._pt2,
_globals->_walkRegions._field18[var10]._pt1, 1, objPos);
doStepsOfNpcMovement(thisField._pt2, thisField._pt1, 1, objPos);
}

_globals->_walkRegions._field18[0]._pt1 = objPos;
// Update the current position.
currSrcField._pt1 = objPos;
*routeList++ = objPos;
}
}

// Add in the route entry
*routeList++ = _globals->_walkRegions._field18[1]._pt1;
*routeList++ = currDestField._pt1;
}

// Mark the end of the path
Expand Down Expand Up @@ -748,7 +755,7 @@ int PlayerMover::checkMover(Common::Point &srcPos, const Common::Point &destPos)
return regionIndex;
}

void PlayerMover::checkMovement2(const Common::Point &srcPos, const Common::Point &destPos, int numSteps, Common::Point &ptOut) {
void PlayerMover::doStepsOfNpcMovement(const Common::Point &srcPos, const Common::Point &destPos, int numSteps, Common::Point &ptOut) {
Common::Point objPos = _sceneObject->_position;
_sceneObject->_position = srcPos;
uint32 regionBitList = _sceneObject->_regionBitList;
Expand Down Expand Up @@ -867,71 +874,62 @@ int PlayerMover::findDistance(const Common::Point &pt1, const Common::Point &pt2
return (int)sqrt(xx + yy);
}

bool PlayerMover::sub_F8E5(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3,
bool PlayerMover::sub_F8E5_calculatePoint(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3,
const Common::Point &pt4, Common::Point *ptOut) {
double diff1 = pt2.x - pt1.x;
double diff2 = pt2.y - pt1.y;
double diff3 = pt4.x - pt3.x;
double diff4 = pt4.y - pt3.y;
double var10 = 0.0, var8 = 0.0;
double var18 = 0.0, var20 = 0.0;
double diffX1 = pt2.x - pt1.x;
double diffY1 = pt2.y - pt1.y;
double diffX2 = pt4.x - pt3.x;
double diffY2 = pt4.y - pt3.y;
double ratio1 = 0.0, ratio2 = 0.0;
double adjustedY1 = 0.0, adjustedY2 = 0.0;

if (diff1 != 0.0) {
var8 = diff2 / diff1;
var18 = pt1.y - (pt1.x * var8);
// Calculate the ratios between the X and Y points.
if (diffX1 != 0.0) {
ratio1 = diffY1 / diffX1;
adjustedY1 = pt1.y - (pt1.x * ratio1);
}
if (diff3 != 0.0) {
var10 = diff4 / diff3;
var20 = pt3.y - (pt3.x * var10);
if (diffX2 != 0.0) {
ratio2 = diffY2 / diffX2;
adjustedY2 = pt3.y - (pt3.x * ratio2);
}

if (var8 == var10)
if (ratio1 == ratio2)
return false;

double var48, var50;
if (diff1 == 0) {
if (diff3 == 0)
double xPos, yPos;
if (diffX1 == 0) {
if (diffX2 == 0)
return false;

var48 = pt1.x;
var50 = var10 * var48 + var20;
xPos = pt1.x;
yPos = ratio2 * xPos + adjustedY2;
} else {
var48 = (diff3 == 0) ? pt3.x : (var20 - var18) / (var8 - var10);
var50 = var8 * var48 + var18;
xPos = (diffX2 == 0) ? pt3.x : (adjustedY2 - adjustedY1) / (ratio1 - ratio2);
yPos = ratio1 * xPos + adjustedY1;
}

bool var52 = false, var56 = false, var54 = false, var58 = false;
Common::Point tempPt((int)(var48 + 0.5), (int)(var50 + 0.5));

if ((tempPt.x >= pt3.x) && (tempPt.x <= pt4.x))
var56 = true;
else if ((tempPt.x >= pt4.x) && (tempPt.x <= pt3.x))
var56 = true;
if (var56) {
if ((tempPt.y >= pt3.y) && (tempPt.y <= pt4.y))
var58 = true;
else if ((tempPt.y >= pt4.y) && (tempPt.y <= pt3.y))
var58 = true;
}
// This is our candidate point, which we must check for validity.
Common::Point tempPt((int)(xPos + 0.5), (int)(yPos + 0.5));

if ((tempPt.x >= pt1.x) && (tempPt.x <= pt2.x))
var52 = true;
else if ((tempPt.x >= pt2.x) && (tempPt.x <= pt1.x))
var52 = true;
if (var52) {
if ((tempPt.y >= pt1.y) && (tempPt.y <= pt2.y))
var54 = true;
else if ((tempPt.y >= pt2.y) && (tempPt.y <= pt1.y))
var54 = true;
}
// Is tempPt inside the second bounds?
if (!((tempPt.x >= pt3.x) && (tempPt.x <= pt4.x)))
if (!((tempPt.x >= pt4.x) && (tempPt.x <= pt3.x)))
return false;
if (!((tempPt.y >= pt3.y) && (tempPt.y <= pt4.y)))
if (!((tempPt.y >= pt4.y) && (tempPt.y <= pt3.y)))
return false;

if (var52 && var54 && var56 && var58) {
if (ptOut)
*ptOut = tempPt;
return true;
}
// Is tempPt inside the first bounds?
if (!((tempPt.x >= pt1.x) && (tempPt.x <= pt2.x)))
if (!((tempPt.x >= pt2.x) && (tempPt.x <= pt1.x)))
return false;
if (!((tempPt.y >= pt1.y) && (tempPt.y <= pt2.y)))
if (!((tempPt.y >= pt2.y) && (tempPt.y <= pt1.y)))
return false;

return false;
if (ptOut)
*ptOut = tempPt;
return true;
}

/*--------------------------------------------------------------------------*/
Expand Down
4 changes: 2 additions & 2 deletions engines/tsage/core.h
Expand Up @@ -229,12 +229,12 @@ class PlayerMover : public NpcMover {
int regionIndexOf(int xp, int yp) { return regionIndexOf(Common::Point(xp, yp)); }
int findClosestRegion(Common::Point &pt, const Common::List<int> &indexList);
int checkMover(Common::Point &srcPos, const Common::Point &destPos);
void checkMovement2(const Common::Point &pt1, const Common::Point &pt2, int numSteps, Common::Point &ptOut);
void doStepsOfNpcMovement(const Common::Point &pt1, const Common::Point &pt2, int numSteps, Common::Point &ptOut);
int calculateRestOfRoute(int *routeList, int srcRegion, int destRegion, bool &foundRoute);

static Common::Point *findLinePoint(RouteEnds *routeEnds, Common::Point *objPos, int length, Common::Point *outPos);
static int findDistance(const Common::Point &pt1, const Common::Point &pt2);
static bool sub_F8E5(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3,
static bool sub_F8E5_calculatePoint(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3,
const Common::Point &pt4, Common::Point *ptOut = NULL);
public:
Common::Point _finalDest;
Expand Down

0 comments on commit 89ed49d

Please sign in to comment.