Bugfix for random destination setting so NPCs don't walk outside the valid walkable areas of a room

svn-id: r26747
This commit is contained in:
Paul Gilbert 2007-05-05 01:00:01 +00:00
parent ecf8417d01
commit 643735e8a4
3 changed files with 17 additions and 4 deletions

View File

@ -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;
}
}

View File

@ -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--;

View File

@ -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);