aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2007-05-05 01:00:01 +0000
committerPaul Gilbert2007-05-05 01:00:01 +0000
commit643735e8a46e3a1d992cb0f98579b2598c348101 (patch)
tree3c5fe4df0291a2238ed95c3eeb2a5a66ffc3a75b /engines
parentecf8417d01783e65ceaa0bf42b3869ce8f5ec43b (diff)
downloadscummvm-rg350-643735e8a46e3a1d992cb0f98579b2598c348101.tar.gz
scummvm-rg350-643735e8a46e3a1d992cb0f98579b2598c348101.tar.bz2
scummvm-rg350-643735e8a46e3a1d992cb0f98579b2598c348101.zip
Bugfix for random destination setting so NPCs don't walk outside the valid walkable areas of a room
svn-id: r26747
Diffstat (limited to 'engines')
-rw-r--r--engines/lure/hotspots.cpp9
-rw-r--r--engines/lure/res_struct.cpp11
-rw-r--r--engines/lure/res_struct.h1
3 files changed, 17 insertions, 4 deletions
diff --git a/engines/lure/hotspots.cpp b/engines/lure/hotspots.cpp
index 1bbcfe5dcb..3004bd3675 100644
--- a/engines/lure/hotspots.cpp
+++ b/engines/lure/hotspots.cpp
@@ -536,7 +536,6 @@ void Hotspot::setRandomDest() {
RoomData *roomData = res.getRoom(roomNumber());
Common::Rect &rect = roomData->walkBounds;
Common::RandomSource rnd;
- int tryCtr = 0;
int16 xp, yp;
if (_currentActions.isEmpty())
@@ -545,13 +544,15 @@ void Hotspot::setRandomDest() {
_currentActions.top().setAction(START_WALKING);
_walkFlag = true;
- while (tryCtr ++ <= 20) {
+ // Try up to 20 times to find an unoccupied destination
+ for (int tryCtr = 0; tryCtr < 20; ++tryCtr) {
xp = rect.left + rnd.getRandomNumber(rect.right - rect.left);
- yp = rect.left + rnd.getRandomNumber(rect.right - rect.left);
+ yp = rect.left + rnd.getRandomNumber(rect.bottom - rect.top);
setDestPosition(xp, yp);
setDestHotspot(0);
- if (!roomData->paths.isOccupied(xp, yp) && !roomData->paths.isOccupied(xp, yp))
+ // Check if three sequential blocks at chosen destination are unoccupied
+ if (!roomData->paths.isOccupied(xp, yp, 3))
break;
}
}
diff --git a/engines/lure/res_struct.cpp b/engines/lure/res_struct.cpp
index aa6f4b2782..e1cf32811a 100644
--- a/engines/lure/res_struct.cpp
+++ b/engines/lure/res_struct.cpp
@@ -158,6 +158,15 @@ bool RoomPathsData::isOccupied(int x, int y) {
return (_data[y * 5 + (x >> 3)] & (0x80 >> (x % 8))) != 0;
}
+bool RoomPathsData::isOccupied(int x, int y, int width) {
+ for (int blockCtr = 0; blockCtr < width; ++blockCtr) {
+ if (isOccupied(x + 8 * blockCtr, y))
+ return true;
+ }
+
+ return false;
+}
+
void RoomPathsData::setOccupied(int x, int y, int width) {
if ((x < 0) || (y < 0) || (x >= ROOM_PATHS_WIDTH) || (y >= ROOM_PATHS_HEIGHT))
return;
@@ -212,6 +221,8 @@ void RoomPathsData::decompress(RoomPathsDecompressedData &dataOut, int character
*pOut-- = 0;
for (int y = 0; y < ROOM_PATHS_HEIGHT; ++y) {
+ charState = false;
+
for (int x = 0; x < (ROOM_PATHS_WIDTH / 8); ++x) {
// Get next byte, which containing bits for 8 blocks
v = *pIn--;
diff --git a/engines/lure/res_struct.h b/engines/lure/res_struct.h
index e1d11d6d5b..c49de0fee2 100644
--- a/engines/lure/res_struct.h
+++ b/engines/lure/res_struct.h
@@ -311,6 +311,7 @@ public:
memcpy(_data, srcData, ROOM_PATHS_SIZE);
}
bool isOccupied(int x, int y);
+ bool isOccupied(int x, int y, int width);
void setOccupied(int x, int y, int width);
void clearOccupied(int x, int y, int width);
void decompress(RoomPathsDecompressedData &dataOut, int characterWidth);