// 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)]; }