motorsep Posted May 29, 2014 Report Posted May 29, 2014 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 ? Quote
grayman Posted May 29, 2014 Report Posted May 29, 2014 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"); Quote
motorsep Posted May 29, 2014 Author Report Posted May 29, 2014 (edited) 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 May 29, 2014 by motorsep Quote
SteveL Posted May 29, 2014 Report Posted May 29, 2014 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. Quote
motorsep Posted May 29, 2014 Author Report Posted May 29, 2014 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?) Quote
SteveL Posted May 29, 2014 Report Posted May 29, 2014 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. Quote
motorsep Posted May 29, 2014 Author Report Posted May 29, 2014 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. Quote
SteveL Posted May 29, 2014 Report Posted May 29, 2014 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.entitiesactive (thinking) entitiesspawned entitiesentities 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()); } } Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.