Jump to content

Is there a client list somewhere in the SP code?


Go to solution Solved by Raz0r,

Recommended Posts

The list of clients being composed of the player (client 0) and NPCs (clients 1 and up).

 

I'm sure it's somewhere but I have not come across it. It would be helpful for debugging if you could keep tabs on a particular client throughout their lifetime in a game session.

Link to comment

Here's how I did it in the AI Workshop code.

 

If you want a helper function that writes a vector of AI, that's also possible:

 

void AIVector(std::vector<gentity_t*>& in) {
    for(int i = 1; i < globals.num_entities; i++) {
        if(!PInUse(i)) {
            continue;
        }
        gentity_t* found = &g_entities[i];
        if(!found->client) {
            continue;
        }
        in.push_back(found);
    }
}

Invoking:

 

std::vector<gentity_t*> ents;
AIVector(ents);
Link to comment

Both of you gave helpful answers, but Razor was first.

 

On a side note Eez, isn't calling to an external library (std) a bit iffy? Wouldn't it be better to internalize the vector stuff into q_shared or something like that? (But then again, any std code might be pretty complex unless you wrote your own homecooked vectors...)

Link to comment

Both of you gave helpful answers, but Razor was first.

 

On a side note Eez, isn't calling to an external library (std) a bit iffy? Wouldn't it be better to internalize the vector stuff into q_shared or something like that? (But then again, any std code might be pretty complex unless you wrote your own homecooked vectors...)

The use of vector is optional, it's just an example of iterating through it. It's not performance-optimal to do this anyway, since you'd be looking at O(n^2) worst-case performance as opposed to O(n). You want to call PInUse and use globals.num_entities though. A flag gets set on unused slots, and ent->client might be non-null on unused slots. A specific edge-case might be when a corpse is removed from bodyque.

Link to comment

^I didn't look at your code yet, so maybe you already did this... wouldn't it be best just to use an array? No new code would have to be written. It could just be a more specific version of g_entities. I'm assuming it wouldn't be very memory intensive especially if it just held pointers and not the actual entities themselves.

 

 

Quick recap to anyone reading this topic for help:

 

g_entities is an array of entities maintained by the game listing all the active entities in the current game session. The player and NPCs are entities that are also clients (therefore ent->client would be non null).

 

To figure out where your client of interest is kept in g_entities... put a breakpoint somewhere where you will have a pointer to the ent of interest (in this case our NPC). Then look at the information stored in that ent for s.number, and that number will correspond to the array index.

 

So... lets say I have a pointer to some entity called ent which I know is a stormtrooper NPC. I will look in ent->s.number (you should be able to see all this in the locals tab if you put your breakpoint in a good spot). The number I see is say... 135. Then at g_entities[135] should be that stormtrooper.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...