From 643735e8a46e3a1d992cb0f98579b2598c348101 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 5 May 2007 01:00:01 +0000 Subject: Bugfix for random destination setting so NPCs don't walk outside the valid walkable areas of a room svn-id: r26747 --- engines/lure/hotspots.cpp | 9 +++++---- engines/lure/res_struct.cpp | 11 +++++++++++ engines/lure/res_struct.h | 1 + 3 files changed, 17 insertions(+), 4 deletions(-) (limited to 'engines') 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); -- cgit v1.2.3