Hey Cohsty, I'd do it this way.
I'd create a list of clients that are pickable from and store them in an array such as:
I'd go through the list of the entities from 0 to < MAX_CLIENTS and then check if they are:
ent && ent->client,
g_entities[i].client->pers.connected == CON_CONNECTED,
g_entities[i].client->sess.sessionTeam != TEAM_SPECTATOR,
(and if you don't want it to be a bot)
!(g_entities[i].r.svFlags & SVF_BOT)
What is intermission, is that the time between siege defense/attack mode, between maps, or between cutscenes?
Ok, then as I go through the g_entities list I select the ones that meet all the criteria above and select their client nums with g_entities[i]->client.ps.clientNum and store it in selectableClients all the while incrementing the numSelectableClients counter or something.
Then I'd use q_irand to select a number from 0 to numSelectableClients, and select the client that's stored in that slot. Something sort of like.
int chosen = q_irand(0, numSelectableClients);
gentity_t *chosenClient = &g_entities[selectableClients[chosen]];
I think that might be the optimal way of doing it, not sure though. As to your other question, I don't think replacements go on. A lot of server and client code stores relations code with the ent's num:
ent->grappleIndex = bob's client num;
Meaning that Bob put ent in one of those strangle hold melee anims that the Kyle boss does or you can do with g_debugmelee. If replacements took place, these sorts of stored values would become useless. Which brings up the question, what happens if there are 32 clients connected, and someone drops and another person takes their place? I think that's how it works but I'm not sure, I'm not sure how it gets rid of relations when a client does get replaced though. So I believe you can have client numbers that are non consecutive.