// Just returns the first room of our list.
ROOM_INDEX_DATA *get_room_iterator() {
return room_index_hash[0];
}
// Returns the next iterator
ROOM_INDEX_DATA *next_room_iterator(ROOM_INDEX_DATA *it) {
ROOM_INDEX_DATA *pRoomIndex = it->next;
int i = (it->vnum % MAX_KEY_HASH); // Resume in the bucket we left off at.
if (pRoomIndex == 0)
while(++i < MAX_KEY_HASH && !pRoomIndex)
pRoomIndex = room_index_hash[i];
return pRoomIndex;
}
// Invalid random rooms are rooms that are private or safe, or can become private. All other rooms are valid.
// Other checks should be made after the get_rand_room() call to see if you need to call it more
// than once. Like things effecting a certain character. Like can_see_room(ch, room) etc.
int valid_random_room(ROOM_INDEX_DATA *pRoom) {
if (room_is_private((ROOM_INDEX_DATA*)pRoom) ||
IS_SET(pRoom->room_flags, ROOM_PRIVATE) ||
IS_SET(pRoom->room_flags, ROOM_SOLITARY) ||
IS_SET(pRoom->room_flags, ROOM_SAFE))
return 0; // false
return 1; // true
}
// Grabs a random valid room for selection.
ROOM_INDEX_DATA *get_rand_room() {
static int count;
static ROOM_INDEX_DATA **array; // Dynamically assigned after we get the count.
// If it's the same array then there's no reason to make a new one across calls.
ROOM_INDEX_DATA *it; // Iterator for later use.
if (!count) // Generators the count once.
// Let's traverse all of the rooms in the mud and get a count.
for(it = get_room_iterator(); it != 0; it = next_room_iterator(it))
if (valid_random_room(it)) // If the room is indeed meeting our criteria
count++;
if (!array) {// Generates the array once.
array = (ROOM_INDEX_DATA**) malloc(sizeof(ROOM_INDEX_DATA*) * count);
for(it = get_room_iterator(); it != 0; it = next_room_iterator(it))
if (valid_random_room(it)) // The room meets the criteria. Add it to our array.
array[(count--) - 1] = it;
}
// Now simply return a valid room.
return array[number_range(0, count-1)];
}