/* =============== G_CallSpawnFunction Finds the spawn function for the entity and calls it, returning qfalse if not found =============== */ qboolean G_CallSpawnFunction( gentity_t *spawnedEntity ) { entityClassDescriptor_t *spawnedClass; buildable_t buildable; if ( !spawnedEntity->classname ) { //don't even warn about spawning-errors with -2 (maps might still work at least partly if we ignore these willingly) if ( g_debugEntities.integer > -2 ) G_Printf( S_ERROR "Entity " S_COLOR_CYAN "#%i" S_COLOR_WHITE " is missing classname – we are unable to spawn it.\n", spawnedEntity->s.number ); return qfalse; } //check buildable spawn functions buildable = BG_BuildableByEntityName( spawnedEntity->classname )->number; if ( buildable != BA_NONE ) { // don't spawn built-in buildings if we are using a custom layout if ( level.layout[ 0 ] && Q_stricmp( level.layout, S_BUILTIN_LAYOUT ) ) { return qfalse; } if ( buildable == BA_A_SPAWN || buildable == BA_H_SPAWN ) { spawnedEntity->s.angles[ YAW ] += 180.0f; AngleNormalize360( spawnedEntity->s.angles[ YAW ] ); } G_SpawnBuildable( spawnedEntity, buildable ); return qtrue; } // check the spawn functions for other classes spawnedClass = bsearch( spawnedEntity->classname, entityClassDescriptions, ARRAY_LEN( entityClassDescriptions ), sizeof( entityClassDescriptor_t ), cmdcmp ); if ( spawnedClass ) { // found it spawnedEntity->eclass = &entityClasses[(int) (spawnedClass-entityClassDescriptions)]; spawnedEntity->eclass->instanceCounter++; if(!G_ValidateEntity( spawnedClass, spawnedEntity )) return qfalse; // results in freeing the entity spawnedClass->spawn( spawnedEntity ); spawnedEntity->spawned = qtrue; if ( g_debugEntities.integer > 2 ) G_Printf( S_DEBUG "Successfully spawned entity " S_COLOR_CYAN "#%i" S_COLOR_WHITE " as " S_COLOR_YELLOW "%i" S_COLOR_WHITE "th instance of " S_COLOR_CYAN "%s\n", spawnedEntity->s.number, spawnedEntity->eclass->instanceCounter, spawnedClass->name); /* * to allow each spawn function to test and handle for itself, * we handle it automatically *after* the spawn (but before it's use/reset) */ if(!G_HandleEntityVersions( spawnedClass, spawnedEntity )) return qfalse; return qtrue; } //don't even warn about spawning-errors with -2 (maps might still work at least partly if we ignore these willingly) if ( g_debugEntities.integer > -2 ) { if (!Q_stricmp(S_WORLDSPAWN, spawnedEntity->classname)) { G_Printf( S_ERROR "a " S_COLOR_CYAN S_WORLDSPAWN S_COLOR_WHITE " class was misplaced into position " S_COLOR_CYAN "#%i" S_COLOR_WHITE " of the spawn string – Ignoring\n", spawnedEntity->s.number ); } else { G_Printf( S_ERROR "Unknown entity class \"" S_COLOR_CYAN "%s" S_COLOR_WHITE "\".\n", spawnedEntity->classname ); } } return qfalse; }
/* =============== G_CallSpawnFunction Finds the spawn function for the entity and calls it, returning false if not found =============== */ bool G_CallSpawnFunction( gentity_t *spawnedEntity ) { entityClassDescriptor_t *spawnedClass; buildable_t buildable; if ( !spawnedEntity->classname ) { //don't even warn about spawning-errors with -2 (maps might still work at least partly if we ignore these willingly) if ( g_debugEntities.integer > -2 ) Log::Warn("Entity ^5#%i^* is missing classname – we are unable to spawn it.", spawnedEntity->s.number ); return false; } //check buildable spawn functions buildable = BG_BuildableByEntityName( spawnedEntity->classname )->number; if ( buildable != BA_NONE ) { const buildableAttributes_t *attr = BG_Buildable( buildable ); // don't spawn built-in buildings if we are using a custom layout if ( level.layout[ 0 ] && Q_stricmp( level.layout, S_BUILTIN_LAYOUT ) ) { return false; } if ( buildable == BA_A_SPAWN || buildable == BA_H_SPAWN ) { spawnedEntity->s.angles[ YAW ] += 180.0f; AngleNormalize360( spawnedEntity->s.angles[ YAW ] ); } G_SpawnBuildable( spawnedEntity, buildable ); level.team[ attr->team ].layoutBuildPoints += attr->buildPoints; return true; } // check the spawn functions for other classes spawnedClass = (entityClassDescriptor_t*) bsearch( spawnedEntity->classname, entityClassDescriptions, ARRAY_LEN( entityClassDescriptions ), sizeof( entityClassDescriptor_t ), cmdcmp ); if ( spawnedClass ) { // found it spawnedEntity->eclass = &entityClasses[(int) (spawnedClass-entityClassDescriptions)]; spawnedEntity->eclass->instanceCounter++; if(!G_ValidateEntity( spawnedClass, spawnedEntity )) return false; // results in freeing the entity spawnedClass->spawn( spawnedEntity ); spawnedEntity->spawned = true; if ( g_debugEntities.integer > 2 ) Log::Warn("Successfully spawned entity ^5#%i^* as ^3#%i^*th instance of ^5%s", spawnedEntity->s.number, spawnedEntity->eclass->instanceCounter, spawnedClass->name); /* * to allow each spawn function to test and handle for itself, * we handle it automatically *after* the spawn (but before it's use/reset) */ if(!G_HandleEntityVersions( spawnedClass, spawnedEntity )) return false; return true; } //don't even warn about spawning-errors with -2 (maps might still work at least partly if we ignore these willingly) if ( g_debugEntities.integer > -2 ) { if (!Q_stricmp(S_WORLDSPAWN, spawnedEntity->classname)) { Log::Warn("a ^5" S_WORLDSPAWN "^7 class was misplaced into position ^5#%i^* of the spawn string – Ignoring", spawnedEntity->s.number ); } else { Log::Warn("Unknown entity class \"^5%s^*\".", spawnedEntity->classname ); } } return false; }