aboutsummaryrefslogtreecommitdiff
path: root/engines/lure
diff options
context:
space:
mode:
authorPaul Gilbert2007-05-07 12:16:05 +0000
committerPaul Gilbert2007-05-07 12:16:05 +0000
commit6a7b74d99dd97480b0fc4b95ee7cfeadb12bd0ea (patch)
treed30329e4e5d6a33623098baffff625bdeb2d9816 /engines/lure
parentd2e56f7b666f2733ca21d6f74182f8e3ce1536cb (diff)
downloadscummvm-rg350-6a7b74d99dd97480b0fc4b95ee7cfeadb12bd0ea.tar.gz
scummvm-rg350-6a7b74d99dd97480b0fc4b95ee7cfeadb12bd0ea.tar.bz2
scummvm-rg350-6a7b74d99dd97480b0fc4b95ee7cfeadb12bd0ea.zip
Reworked the pathfinder to directly return a pathfinding result, and added code to save the pathfinding state to a save game when it's in progress
svn-id: r26777
Diffstat (limited to 'engines/lure')
-rw-r--r--engines/lure/hotspots.cpp93
-rw-r--r--engines/lure/hotspots.h7
2 files changed, 55 insertions, 45 deletions
diff --git a/engines/lure/hotspots.cpp b/engines/lure/hotspots.cpp
index 3004bd3675..82ecc295cd 100644
--- a/engines/lure/hotspots.cpp
+++ b/engines/lure/hotspots.cpp
@@ -567,7 +567,7 @@ void Hotspot::setOccupied(bool occupiedFlag) {
int xp = x() >> 3;
int yp = (y() - 8 + heightCopy() - 4) >> 3;
- int widthVal = MAX(((widthCopy() - 1) >> 3), 1);
+ int widthVal = MAX(widthCopy() >> 3, 1);
// Handle cropping for screen left
if (xp < 0) {
@@ -2325,6 +2325,7 @@ void HotspotTickHandlers::standardCharacterAnimHandler(Hotspot &h) {
debugC(ERROR_DETAILED, kLureDebugAnimations, "Hotspot standard character point 6");
CurrentAction action = actions.action();
+ PathFinderResult pfResult;
switch (action) {
case NO_ACTION:
@@ -2374,14 +2375,15 @@ void HotspotTickHandlers::standardCharacterAnimHandler(Hotspot &h) {
debugC(ERROR_DETAILED, kLureDebugAnimations, "Hotspot standard character processing path");
res.pausedList().scan(h);
- if (!pathFinder.process()) break;
+ pfResult = pathFinder.process();
+ if (pfResult == PF_UNFINISHED) break;
debugC(ERROR_DETAILED, kLureDebugAnimations,
- "pathFinder done: result = %d", pathFinder.result());
+ "pathFinder done: result = %d", pfResult);
// Post-processing checks
- if ((pathFinder.result() == PF_OK) ||
- ((h.destHotspotId() == 0) && (pathFinder.result() == PF_DEST_OCCUPIED))) {
+ if ((pfResult == PF_OK) ||
+ ((h.destHotspotId() == 0) && (pfResult == PF_DEST_OCCUPIED))) {
// Standard processing
debugC(ERROR_DETAILED, kLureDebugAnimations, "Standard result handling");
@@ -2641,6 +2643,7 @@ void HotspotTickHandlers::playerAnimHandler(Hotspot &h) {
}
CurrentAction action = actions.action();
+ PathFinderResult pfResult;
switch (action) {
case NO_ACTION:
@@ -2693,16 +2696,16 @@ void HotspotTickHandlers::playerAnimHandler(Hotspot &h) {
h.setCharacterMode(CHARMODE_NONE);
res.pausedList().scan(h);
- if (!pathFinder.process()) break;
+ pfResult = pathFinder.process();
+ if (pfResult == PF_UNFINISHED) break;
// Pathfinding is now complete
pathFinder.list(buffer);
debugC(ERROR_DETAILED, kLureDebugAnimations,
"Pathfind processing done; result=%d, walkFlag=%d\n%s",
- pathFinder.result(), h.walkFlag(), buffer);
+ pfResult, h.walkFlag(), buffer);
- if ((pathFinder.result() != PF_OK) &&
- (h.walkFlag() || (pathFinder.result() != PF_DEST_OCCUPIED))) {
+ if ((pfResult != PF_OK) && (h.walkFlag() || (pfResult != PF_DEST_OCCUPIED))) {
debugC(ERROR_DETAILED, kLureDebugAnimations, "Blocked state checking");
if (h.blockedState() == BS_FINAL) {
@@ -3682,6 +3685,7 @@ int WalkingActionEntry::numSteps() {
PathFinder::PathFinder(Hotspot *h) {
_hotspot = h;
+ _inUse = false;
_list.clear();
_stepCtr = 0;
}
@@ -3696,12 +3700,13 @@ void PathFinder::clear() {
void PathFinder::reset(RoomPathsData &src) {
clear();
src.decompress(_layer, _hotspot->widthCopy());
+ _inUse = true;
}
// Does the next stage of processing to figure out a path to take to a given
// destination. Returns true if the path finding has been completed
-bool PathFinder::process() {
+PathFinderResult PathFinder::process() {
bool returnFlag = _inProgress;
// Check whether the pathfinding can be broken by the countdown counter
bool breakFlag = (PATHFIND_COUNTDOWN != 0);
@@ -3714,6 +3719,7 @@ bool PathFinder::process() {
uint16 numSteps = 0, savedSteps = 0;
bool altFlag;
uint16 *pCurrent;
+ PathFinderResult result = PF_UNFINISHED;
if (!_inProgress) {
// Following code only done during first call to method
@@ -3743,7 +3749,7 @@ bool PathFinder::process() {
// Flag starting/ending cells
*_pSrc = 1;
_destOccupied = *_pDest != 0;
- _result = _destOccupied ? PF_DEST_OCCUPIED : PF_OK;
+ result = _destOccupied ? PF_DEST_OCCUPIED : PF_OK;
*_pDest = 0;
// Set up the current pointer, adjusting away from edges if necessary
@@ -3778,7 +3784,7 @@ bool PathFinder::process() {
if (!returnFlag) {
processCell(&_layer[(_yChangeStart + _yCtr * _yChangeInc) * DECODED_PATHS_WIDTH +
(_xChangeStart + _xCtr * _xChangeInc)]);
- if (breakFlag && (_countdownCtr <= 0)) return false;
+ if (breakFlag && (_countdownCtr <= 0)) return PF_UNFINISHED;
} else {
returnFlag = false;
}
@@ -3794,7 +3800,7 @@ bool PathFinder::process() {
// At least one cell populated, so go repeat loop
_cellPopulated = false;
} else {
- _result = PF_NO_PATH;
+ result = PF_PART_PATH;
scanFlag = true;
break;
}
@@ -3819,9 +3825,8 @@ bool PathFinder::process() {
scanLine(ROOM_PATHS_HEIGHT - _destY, DECODED_PATHS_WIDTH, pTemp, v);
if (pTemp == _pDest) {
- _result = PF_NO_WALK;
clear();
- return true;
+ return PF_NO_WALK;
}
_pDest = pTemp;
@@ -3837,6 +3842,9 @@ bool PathFinder::process() {
// walking steps in reverse order until source is reached
int stageCtr;
for (stageCtr = 0; stageCtr < 3; ++stageCtr) {
+ // Clear out any previously determined directions
+ clear();
+
altFlag = stageCtr == 1;
pCurrent = _pDest;
@@ -3898,14 +3906,11 @@ bool PathFinder::process() {
if ((stageCtr == 1) && (numSteps <= savedSteps))
// Less steps were needed, so break out
break;
-
- // Clear out any previously determined directions
- clear();
}
// Add a final move if necessary
- if (_result == PF_OK) {
+ if (result == PF_OK) {
if (_xDestPos < 0)
addBack(LEFT, -_xDestPos);
else if (_xDestPos > 0)
@@ -3916,7 +3921,7 @@ final_step:
if (_xPos < 0) add(RIGHT, -_xPos);
else if (_xPos > 0) add(LEFT, _xPos);
- return true;
+ return result;
}
void PathFinder::list(char *buffer) {
@@ -4039,39 +4044,45 @@ void PathFinder::initVars() {
if (_yDestCurrent >= (FULL_SCREEN_HEIGHT - MENUBAR_Y_SIZE))
_yDestCurrent = FULL_SCREEN_HEIGHT - MENUBAR_Y_SIZE - 1;
- _result = PF_OK;
-
// Subtract an amount from the countdown counter to compensate for
// the time spent decompressing the walkable areas set for the room
_countdownCtr -= 700;
}
void PathFinder::saveToStream(Common::WriteStream *stream) {
- // Note: current saving process only handles the PathFinder correctly
- // if all pathfinding is done in one go (ie. multiple calls pathfinding
- // isn't supported)
-
- ManagedList<WalkingActionEntry *>::iterator i;
- for (i = _list.begin(); i != _list.end(); ++i) {
- WalkingActionEntry *entry = *i;
- stream->writeByte(entry->direction());
- stream->writeSint16LE(entry->rawSteps());
+ stream->writeByte(_inUse);
+
+ if (_inUse) {
+ // Save the path finding plane
+ stream->write(_layer, sizeof(RoomPathsDecompressedData));
+
+ // Save any active step sequence
+ ManagedList<WalkingActionEntry *>::iterator i;
+ for (i = _list.begin(); i != _list.end(); ++i) {
+ WalkingActionEntry *entry = *i;
+ stream->writeByte(entry->direction());
+ stream->writeSint16LE(entry->rawSteps());
+ }
+ stream->writeByte(0xff);
+ stream->writeSint16LE(_stepCtr);
}
- stream->writeByte(0xff);
- stream->writeByte(_result);
- stream->writeSint16LE(_stepCtr);
}
void PathFinder::loadFromStream(Common::ReadStream *stream) {
_inProgress = false;
- _list.clear();
- uint8 direction;
- while ((direction = stream->readByte()) != 0xff) {
- int steps = stream->readSint16LE();
- _list.push_back(new WalkingActionEntry((Direction) direction, steps));
+ _inUse = stream->readByte() != 0;
+
+ if (_inUse) {
+ stream->read(_layer, sizeof(RoomPathsDecompressedData));
+
+ _list.clear();
+ uint8 direction;
+ while ((direction = stream->readByte()) != 0xff) {
+ int steps = stream->readSint16LE();
+ _list.push_back(new WalkingActionEntry((Direction) direction, steps));
+ }
+ _stepCtr = stream->readSint16LE();
}
- _result = (PathFinderResult)stream->readByte();
- _stepCtr = stream->readSint16LE();
}
// Current action entry class methods
diff --git a/engines/lure/hotspots.h b/engines/lure/hotspots.h
index 91fa317c04..5bf7f1e310 100644
--- a/engines/lure/hotspots.h
+++ b/engines/lure/hotspots.h
@@ -172,11 +172,12 @@ public:
int numSteps();
};
-enum PathFinderResult {PF_OK, PF_DEST_OCCUPIED, PF_NO_PATH, PF_NO_WALK};
+enum PathFinderResult {PF_UNFINISHED, PF_OK, PF_DEST_OCCUPIED, PF_PART_PATH, PF_NO_WALK};
class PathFinder {
private:
Hotspot *_hotspot;
+ bool _inUse;
ManagedList<WalkingActionEntry *> _list;
RoomPathsDecompressedData _layer;
int _stepCtr;
@@ -189,7 +190,6 @@ private:
int16 _xDestCurrent, _yDestCurrent;
bool _destOccupied;
bool _cellPopulated;
- PathFinderResult _result;
uint16 *_pSrc, *_pDest;
int _xChangeInc, _xChangeStart;
int _yChangeInc, _yChangeStart;
@@ -209,7 +209,7 @@ public:
PathFinder(Hotspot *h);
void clear();
void reset(RoomPathsData &src);
- bool process();
+ PathFinderResult process();
void list(char *buffer);
void list() { list(NULL); }
@@ -217,7 +217,6 @@ public:
WalkingActionEntry &top() { return **_list.begin(); }
bool isEmpty() { return _list.empty(); }
int &stepCtr() { return _stepCtr; }
- PathFinderResult result() { return _result; }
void saveToStream(Common::WriteStream *stream);
void loadFromStream(Common::ReadStream *stream);