// Spawn an entity and fill in all of the level fields from level.spawnVars[], then call the class specfic spawn function gentity_t *G_SpawnGEntityFromSpawnVars( qboolean inSubBSP ) { int i; gentity_t *ent; char *s, *value; const char *gametypeName; static const char *gametypeNames[] = { "ffa", "holocron", "jedimaster", "duel", "powerduel", "single", "team", "siege", "ctf", "cty" }; // get the next free entity ent = G_Spawn(); for ( i = 0; i < level.numSpawnVars; i++ ) { BG_ParseField( fields, ARRAY_LEN( fields ), level.spawnVars[i][0], level.spawnVars[i][1], (byte *)ent ); } // check for "notsingle" flag if ( level.gametype == GT_SINGLE_PLAYER ) { G_SpawnInt( "notsingle", "0", &i ); if ( i ) { G_FreeEntity( ent ); return NULL; } } // check for "notteam" flag (GT_FFA, GT_DUEL, GT_SINGLE_PLAYER) if ( level.gametype >= GT_TEAM ) { G_SpawnInt( "notteam", "0", &i ); if ( i ) { G_FreeEntity( ent ); return NULL; } } else { G_SpawnInt( "notfree", "0", &i ); if ( i ) { G_FreeEntity( ent ); return NULL; } } G_SpawnInt( "notta", "0", &i ); if ( i ) { G_FreeEntity( ent ); return NULL; } if ( G_SpawnString( "gametype", NULL, &value ) ) { if ( level.gametype >= GT_FFA && level.gametype < GT_MAX_GAME_TYPE ) { gametypeName = gametypeNames[level.gametype]; s = strstr( value, gametypeName ); if ( !s ) { G_FreeEntity( ent ); return NULL; } } } // move editor origin to pos VectorCopy( &ent->s.origin, &ent->s.pos.trBase ); VectorCopy( &ent->s.origin, &ent->r.currentOrigin ); // if we didn't get a classname, don't bother spawning anything if ( !G_CallSpawn( ent ) ) { G_FreeEntity( ent ); return NULL; } //Tag on the ICARUS scripting information only to valid recipients if ( trap->ICARUS_ValidEnt( (sharedEntity_t *)ent ) ) { trap->ICARUS_InitEnt( (sharedEntity_t *)ent ); if ( ent->classname && ent->classname[0] ) { if ( Q_strncmp( "NPC_", ent->classname, 4 ) != 0 ) {//Not an NPC_spawner (rww - probably don't even care for MP, but whatever) G_ActivateBehavior( ent, BSET_SPAWN ); } } } if ( level.manualSpawning ) { ent->jpSpawned = qtrue; } return ent; }
void G_SpawnGEntityFromSpawnVars( qboolean inSubBSP ) { int i; gentity_t *ent; char *s, *value, *gametypeName; static char *gametypeNames[] = {"ffa", "holocron", "jedimaster", "duel", "powerduel", "single", "team", "siege", "ctf", "cty"}; // get the next free entity if ( level.entCount > (MAX_GENTITIES - g_objectMargin.integer)) { G_Printf("ERROR :Run out of entities\n"); return; } ent = G_Spawn(); for ( i = 0 ; i < level.numSpawnVars ; i++ ) { BG_ParseField( fields, level.spawnVars[i][0], level.spawnVars[i][1], (byte *)ent ); } if ( level.stripping == qtrue ) { // strip out any undesirable object classes. if( Q_stricmpn( "item_", ent->classname, 5 ) == 0 || Q_stricmpn( "trigger_", ent->classname, 8 ) == 0 || Q_stricmpn( "target_", ent->classname, 7 ) == 0 || Q_stricmpn( "NPC_", ent->classname, 4 ) == 0 ) { G_FreeEntity( ent ); return; } } // check for "notsingle" flag if ( g_gametype.integer == GT_SINGLE_PLAYER ) { G_SpawnInt( "notsingle", "0", &i ); if ( i ) { G_FreeEntity( ent ); return; } } // check for "notteam" flag (GT_FFA, GT_DUEL, GT_SINGLE_PLAYER) if ( g_gametype.integer >= GT_TEAM ) { G_SpawnInt( "notteam", "0", &i ); if ( i ) { G_FreeEntity( ent ); return; } } else { G_SpawnInt( "notfree", "0", &i ); if ( i ) { G_FreeEntity( ent ); return; } } G_SpawnInt( "notta", "0", &i ); if ( i ) { G_FreeEntity( ent ); return; } if( G_SpawnString( "gametype", NULL, &value ) ) { if( g_gametype.integer >= GT_FFA && g_gametype.integer < GT_MAX_GAME_TYPE ) { gametypeName = gametypeNames[g_gametype.integer]; s = strstr( value, gametypeName ); if( !s ) { G_FreeEntity( ent ); return; } } } // move editor origin to pos VectorCopy( ent->s.origin, ent->s.pos.trBase ); VectorCopy( ent->s.origin, ent->r.currentOrigin ); // if we didn't get a classname, don't bother spawning anything if ( !G_CallSpawn( ent ) ) { G_FreeEntity( ent ); } //Tag on the ICARUS scripting information only to valid recipients if ( trap_ICARUS_ValidEnt( ent ) ) { trap_ICARUS_InitEnt( ent ); if ( ent->classname && ent->classname[0] ) { if ( Q_strncmp( "NPC_", ent->classname, 4 ) != 0 ) {//Not an NPC_spawner (rww - probably don't even care for MP, but whatever) G_ActivateBehavior( ent, BSET_SPAWN ); } } } }
void SP_worldspawn( void ) { char *text, temp[32]; int i; int lengthRed, lengthBlue, lengthGreen; //I want to "cull" entities out of net sends to clients to reduce //net traffic on our larger open maps -rww G_SpawnFloat( "distanceCull", "6000.0", &g_cullDistance ); trap->SetServerCull( g_cullDistance ); G_SpawnString( "classname", "", &text ); if ( Q_stricmp( text, "worldspawn" ) ) { trap->Error( ERR_DROP, "SP_worldspawn: The first entity isn't 'worldspawn'" ); } for ( i = 0; i < level.numSpawnVars; i++ ) { if ( Q_stricmp( "spawnscript", level.spawnVars[i][0] ) == 0 ) {//ONly let them set spawnscript, we don't want them setting an angle or something on the world. BG_ParseField( fields, ARRAY_LEN( fields ), level.spawnVars[i][0], level.spawnVars[i][1], (byte *)&g_entities[ENTITYNUM_WORLD] ); } } //The server will precache the standard model and animations, so that there is no hit //when the first client connnects. if ( !BGPAFtextLoaded ) { BG_ParseAnimationFile( "models/players/_humanoid/animation.cfg", bgHumanoidAnimations, qtrue ); } if ( !precachedKyle ) { int defSkin; trap->G2API_InitGhoul2Model( &precachedKyle, "models/players/kyle/model.glm", 0, 0, -20, 0, 0 ); if ( precachedKyle ) { defSkin = trap->R_RegisterSkin( "models/players/kyle/model_default.skin" ); trap->G2API_SetSkin( precachedKyle, 0, defSkin, defSkin ); } } if ( !g2SaberInstance ) { trap->G2API_InitGhoul2Model( &g2SaberInstance, "models/weapons2/saber/saber_w.glm", 0, 0, -20, 0, 0 ); if ( g2SaberInstance ) { // indicate we will be bolted to model 0 (ie the player) on bolt 0 (always the right hand) when we get copied trap->G2API_SetBoltInfo( g2SaberInstance, 0, 0 ); // now set up the gun bolt on it trap->G2API_AddBolt( g2SaberInstance, 0, "*blade1" ); } } if ( level.gametype == GT_SIEGE ) { //a tad bit of a hack, but.. EWebPrecache(); } // make some data visible to connecting client trap->SetConfigstring( CS_GAME_VERSION, GAME_VERSION ); trap->SetConfigstring( CS_LEVEL_START_TIME, va( "%i", level.startTime ) ); G_SpawnString( "music", "", &text ); trap->SetConfigstring( CS_MUSIC, text ); G_SpawnString( "message", "", &text ); trap->SetConfigstring( CS_MESSAGE, text ); // map specific message trap->SetConfigstring( CS_MOTD, g_motd.string ); // message of the day G_SpawnString( "gravity", "800", &text ); trap->Cvar_Set( "g_gravity", text ); G_SpawnString( "enableBreath", "0", &text ); trap->Cvar_Set( "g_enableBreath", text ); G_SpawnString( "soundSet", "default", &text ); trap->SetConfigstring( CS_GLOBAL_AMBIENT_SET, text ); g_entities[ENTITYNUM_WORLD].s.number = ENTITYNUM_WORLD; g_entities[ENTITYNUM_WORLD].classname = "worldspawn"; // see if we want a warmup time trap->SetConfigstring( CS_WARMUP, "" ); if ( g_restarted.integer ) { trap->Cvar_Set( "g_restarted", "0" ); level.warmupTime = 0; } //Raz: Fix warmup else if ( g_doWarmup.integer && level.gametype != GT_DUEL && level.gametype != GT_POWERDUEL && level.gametype != GT_SIEGE ) { // Turn it on level.warmupTime = -1; trap->SetConfigstring( CS_WARMUP, va( "%i", level.warmupTime ) ); G_LogPrintf( level.log.console, "Warmup:\n" ); } trap->SetConfigstring( CS_LIGHT_STYLES + (LS_STYLES_START * 3) + 0, defaultStyles[0][0] ); trap->SetConfigstring( CS_LIGHT_STYLES + (LS_STYLES_START * 3) + 1, defaultStyles[0][1] ); trap->SetConfigstring( CS_LIGHT_STYLES + (LS_STYLES_START * 3) + 2, defaultStyles[0][2] ); for ( i = 1; i < LS_NUM_STYLES; i++ ) { Com_sprintf( temp, sizeof(temp), "ls_%dr", i ); G_SpawnString( temp, defaultStyles[i][0], &text ); lengthRed = strlen( text ); trap->SetConfigstring( CS_LIGHT_STYLES + ((i + LS_STYLES_START) * 3) + 0, text ); Com_sprintf( temp, sizeof(temp), "ls_%dg", i ); G_SpawnString( temp, defaultStyles[i][1], &text ); lengthGreen = strlen( text ); trap->SetConfigstring( CS_LIGHT_STYLES + ((i + LS_STYLES_START) * 3) + 1, text ); Com_sprintf( temp, sizeof(temp), "ls_%db", i ); G_SpawnString( temp, defaultStyles[i][2], &text ); lengthBlue = strlen( text ); trap->SetConfigstring( CS_LIGHT_STYLES + ((i + LS_STYLES_START) * 3) + 2, text ); if ( lengthRed != lengthGreen || lengthGreen != lengthBlue ) { Com_Error( ERR_DROP, "Style %d has inconsistent lengths: R %d, G %d, B %d", i, lengthRed, lengthGreen, lengthBlue ); } } }
// For Maker Mod objects // combine the two sets of spawnVars. newVars overwrite spawnVars // we end up with level.spawnVars setup with our final values, the values applied to our ent, // and the appropriate spawn function executed. void G_ApplySpawnVars( gentity_t *ent, char *spawnVars, char *newVars ) { int i; char *token; //static char *gametypeNames[] = {"ffa", "holocron", "jedimaster", "duel", "powerduel", "single", "team", "siege", "ctf", "cty"}; char* p; char field[MAX_FIELDNAME_LENGTH + 1]; level.numSpawnVars = 0; level.numSpawnVarChars = 0; level.spawnVarChars[0] = '/0'; p = spawnVars; while ( p ) { token = ParseExt( &p, qfalse ); // TODO : make sure it's safe to use this function if ( token[0] == 0 ) break; strncpy( field, token, MAX_FIELDNAME_LENGTH ); token = ParseExt( &p, qfalse ); if ( token[0] == 0 ) break; AddSpawnField( field, token ); } p = newVars; while ( p ) { token = ParseExt( &p, qfalse ); // TODO : make sure it's safe to use this function if ( token[0] == 0 ) break; strncpy( field, token, MAX_FIELDNAME_LENGTH ); token = ParseExt( &p, qfalse ); if ( token[0] == 0 ) break; AddSpawnField( field, token ); } for ( i = 0 ; i < level.numSpawnVars ; i++ ) { BG_ParseField( fields, level.spawnVars[i][0], level.spawnVars[i][1], (byte *)ent ); } // move editor origin to pos VectorCopy( ent->s.origin, ent->s.pos.trBase ); VectorCopy( ent->s.origin, ent->r.currentOrigin ); // if we didn't get a classname, don't bother spawning anything if ( !G_CallSpawn( ent ) ) { //G_FreeEntity( ent ); } //Tag on the ICARUS scripting information only to valid recipients if ( trap_ICARUS_ValidEnt( ent ) ) { trap_ICARUS_InitEnt( ent ); if ( ent->classname && ent->classname[0] ) { if ( Q_strncmp( "NPC_", ent->classname, 4 ) != 0 ) {//Not an NPC_spawner (rww - probably don't even care for MP, but whatever) G_ActivateBehavior( ent, BSET_SPAWN ); } } } }