Jump to content
The Dark Mod Forums
Sign in to follow this  
motorsep

How to find an entity in the game's world

Recommended Posts

How do I find an entity of a given class in the game's world using SDK code (C++) or/and script ?

 

For example Quake has something like find(e); a built-in that returns entity when it finds it. Does Doom 3 SDK have something similar ?

Share this post


Link to post
Share on other sites

If you're looking for a specific entity, you can use this in a script:

 

entity e = sys.getEntity("<name of entity>");

 

For example, if you want to find the entity named "John", then use:

 

entity e = sys.getEntity("John");

Share this post


Link to post
Share on other sites

No no, I am looking for any entity of a certain class. For example, I need to find any func_door entity on the level and print its name in the console.

Edited by motorsep

Share this post


Link to post
Share on other sites

I am pretty sure that this can't be achieved using the existing script events. It can easily be done in the game code. The static gameLocal object provides public members idEntity entities* (an array of pointers to map entities) and int numEntities, so code can cycle through the list of pointers and get the classname spawnarg for each entity, filtering out those that you want. There are also linked lists available for spawned entities and active entities (those that Think()).

 

I was thinking of suggesting we add a script event to the game that'll let map scripts do the same thing: cycle through the list of extant entities. This seems as good a thread as any. Would people support that script event? You could use it to do this job, plus lots of other things. I've often found situations in scripting that would be easier to set up if the map script could cycle through the list of entities during initialisation and compile a list of entities that it'll later track or act on. You can then add more affected entities to your map without having to update your script with a hard-coded list of entity names.

Share this post


Link to post
Share on other sites

Now that I am thinking about it, script would be slow. So keeping it within SDK code would be the best thing.

 

I was looking into the code last night, and it seems that what's already there is a functionality to pull entity's index. So there is no out of the box function that only polls entities of a certain class, correct?

 

If so, how would I determine what is the class of the polled entity? (entity index 0 is always a worldspawn class, but the rest?)

Share this post


Link to post
Share on other sites

Will you have to do this often? If you are only going to search the list of entities in response to something happening in game, for example, you probably don't need to worry about the time taken. If it's going to happen every frame, then yes it's worth doing it in the sdk.

 

I'm not at home so can't check the exact method names, but look for the idEntity::GetSpawnArg() method, or something very similarly named. You can GetSpawnArg("classname") to find out an entity's game class.

Share this post


Link to post
Share on other sites

Will you have to do this often? If you are only going to search the list of entities in response to something happening in game, for example, you probably don't need to worry about the time taken. If it's going to happen every frame, then yes it's worth doing it in the sdk.

 

Yeah, probably every tick. Or every so often, but often enough that performance is important.

 

I'm not at home so can't check the exact method names, but look for the idEntity::GetSpawnArg() method, or something very similarly named. You can GetSpawnArg("classname") to find out an entity's game class.

 

Me neither :) so, no rush.. I appreciate your help.

Share this post


Link to post
Share on other sites

I've done a few tests on discovering entities in the running map.

 

The world entity turns out not to be entity 0 in the gameLocal.entities list; it's indexed at a constant 8190 (MAX_GENTITIES-2). gameLocal.num_entities holds the max index +1 of entities other than the constant ones like "world" that're stored at the end of the list. There are gaps (null pointers) in the list at positions less than num_entities.

 

You have choices over which list of entities you want to look at. So far I've spotted 4 global lists that you can access during the game:

  • gameLocal.entities
  • active (thinking) entities
  • spawned entities
  • entities defined in the map file
    • ^ Not sure whether this last one is truly accessible during the game. There's at least one way to do it ( gameLocal.GetLevelMap() ) but there's a comment saying that the method "should only be used for in-game level editing"

spawned entities excludes entities defined in the map file that haven't been spawned, e.g. those that got suppressed due to difficulty spawnargs, for example. I'm not sure whether those are included in gameLocal.entities yet.

 

Two examples from my test code for finding entities by classname, (1) from the global gameLocal.entities list and (2) from the spawned entities linked list:

 

 

// find entities by classname
idStr classToFind = "atdm:player_thief";
// 1: find entities by classname in gameLocal.entities
for ( int i = 0; i < gameLocal.num_entities; ++i )
{
idEntity* ent = gameLocal.entities[i];
if (ent != NULL && idStr::Icmp(ent->spawnArgs.GetString("classname"), classToFind) == 0 )
{
	// do something with ent
	gameLocal.Printf("\n %s found, named: %s\n", classToFind.c_str(), ent->GetName());
}
}
// 2: find entities by classname within spawned entities
for ( idEntity* ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() )
{
if ( idStr::Icmp(ent->spawnArgs.GetString("classname"), classToFind) == 0 )
{
	// do something with ent
	gameLocal.Printf("\n %s found, named: %s\n", classToFind.c_str(), ent->GetName());
}
}

 

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...