Entities File for Quake3
Je le sais, mais je ne connais pas le code: ni C, ni C+, ni C++, ni C#, ni d'autres. Je sais qu'on peut compiler de nouveaux fichiers *.qvm d'après les sources à l'aide des fichiers *.bat, mais je ne sais pas quels fichiers j'ai à modifier.
Tout ce que je veux, c'est d'avoir un mode qui se base sur le "baseq3", mais avec les armes et les bonus (power-ups) de Team Arena, et avec les armures verte (25 points - cela existe au mode ExcessvePlus) et bleue (200 points - cela existe, si je ne me trompe pas, à Quake Live).
Excessiveplus v2.1, fragment of g_spawn.c
( xp_noCustomEnts and g_mapname must be defined as cvars, g_mapname depends on currently loaded map )
/*QUAKED worldspawn (0 0 0) ? Every map should have exactly one worldspawn. "music" music wav file "gravity" 800 is default gravity "message" Text to print during connection process */ void SP_worldspawn( void ) { char *s; G_SpawnString( "classname", "", &s ); if ( Q_stricmp( s, "worldspawn" ) ) { G_Error( "SP_worldspawn: The first entity isn't 'worldspawn'" ); } // 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", "", &s ); trap_SetConfigstring( CS_MUSIC, s ); G_SpawnString( "message", "", &s ); trap_SetConfigstring( CS_MESSAGE, s ); // map specific message trap_SetConfigstring( CS_MOTD, g_motd.string ); // message of the day G_SpawnString( "gravity", "800", &s ); trap_Cvar_Set( "g_gravity", s ); G_SpawnString( "enableDust", "0", &s ); trap_Cvar_Set( "g_enableDust", s ); G_SpawnString( "enableBreath", "0", &s ); trap_Cvar_Set( "g_enableBreath", s ); #ifdef EXCESSIVEPLUS G_SpawnString( "atmosphere", "", &s ); if ( g_gametype.integer == GT_FTAG ) { trap_Cvar_Set( "g_enableBreath", "1" ); s = "T=SNOW"; } trap_SetConfigstring( 31, s ); #endif 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, "" ); #ifdef EXCESSIVEPLUS if ( trap_Cvar_VariableIntegerValue( "g_restarted" ) ) { trap_Cvar_Set( "g_restarted", "0" ); level.warmupTime = 0; } else { if ( g_gametype.integer != GT_SINGLE_PLAYER ) { trap_SetConfigstring( CS_WARMUP, "-1" ); level.warmupTime = -1; G_LogPrintf( "Warmup:\n" ); } } #else if ( g_restarted.integer ) { trap_Cvar_Set( "g_restarted", "0" ); level.warmupTime = 0; } else if ( g_doWarmup.integer ) { // Turn it on level.warmupTime = -1; trap_SetConfigstring( CS_WARMUP, va("%i", level.warmupTime) ); G_LogPrintf( "Warmup:\n" ); } #endif } #ifdef EXCESSIVEPLUS qboolean G_ParseSpawnVarsFromFile( char **data ) { char keyname[MAX_TOKEN_CHARS]; char com_token[MAX_TOKEN_CHARS]; level.numSpawnVars = 0; level.numSpawnVarChars = 0; Com_sprintf( com_token, sizeof( com_token ), "%s", COM_Parse( data ) ); if ( com_token[0] ) { if ( com_token[0] != '{' ) COM_ParseError( "found '%s' when expecting {", com_token ); while ( 1 ) { Com_sprintf( keyname, sizeof( keyname ), "%s", COM_Parse( data ) ); if ( !keyname[0] ) COM_ParseError( "EOF without closing brace" ); if ( keyname[0] == '}' ) break; Com_sprintf( com_token, sizeof( com_token ), "%s", COM_Parse( data ) ); if ( !com_token[0] ) COM_ParseError( "EOF without closing brace" ); if ( com_token[0] == '}' ) COM_ParseError( "closing brace without data" ); if ( level.numSpawnVars == MAX_SPAWN_VARS ) COM_ParseError( "MAX_SPAWN_VARS" ); level.spawnVars[ level.numSpawnVars ][0] = G_AddSpawnVarToken( keyname ); level.spawnVars[ level.numSpawnVars ][1] = G_AddSpawnVarToken( com_token ); level.numSpawnVars++; } return qtrue; } else return qfalse; } qboolean G_SpawnEntitiesFromFile( const char *filename, qboolean isents ) { fileHandle_t f; int len; char *buf; len = trap_FS_FOpenFile( filename, &f, FS_READ ); if ( !f ) return qfalse; if ( len <= 0 ) { trap_FS_FCloseFile( f ); return qfalse; } COM_BeginParseSession( filename ); buf = ( char * )malloc( len + 1 ); if ( buf ) { trap_FS_Read( buf, len, f ); buf[len] = 0; if ( isents ) { if ( !G_ParseSpawnVarsFromFile( &buf ) ) COM_ParseError( "SpawnEntities: no entities" ); SP_worldspawn(); } while ( G_ParseSpawnVarsFromFile( &buf ) ) G_SpawnGEntityFromSpawnVars(); trap_FS_FCloseFile( f ); free( buf ); return qtrue; } else { trap_FS_FCloseFile( f ); COM_ParseError( "Not enough memory to load file" ); return qfalse; } } #endif /* ============== G_SpawnEntitiesFromString Parses textual entity definitions out of an entstring and spawns gentities. ============== */ void G_SpawnEntitiesFromString( void ) { #ifdef EXCESSIVEPLUS /*char string[MAX_CVAR_VALUE_STRING]; char *ptr;*/ #endif // allow calls to G_Spawn*() level.spawning = qtrue; level.numSpawnVars = 0; #ifdef EXCESSIVEPLUS if ( xp_noCustomEnts.integer || !G_SpawnEntitiesFromFile( va( "maps/%s.ents", g_mapname.string ), qtrue ) ) { #endif // the worldspawn is not an actual entity, but it still // has a "spawn" function to perform any global setup // needed by a level (setting configstrings or cvars, etc) if ( !G_ParseSpawnVars() ) { G_Error( "SpawnEntities: no entities" ); } SP_worldspawn(); // parse ents while( G_ParseSpawnVars() ) { G_SpawnGEntityFromSpawnVars(); } #ifdef EXCESSIVEPLUS } if ( !xp_noCustomEnts.integer ) { G_SpawnEntitiesFromFile( va( "maps/%s.add", g_mapname.string ), qfalse ); } /*trap_Cvar_VariableStringBuffer( "xp_config", string, sizeof( string ) ); if ( !string ) ptr = "default"; else ptr = string; if ( !ParseConfig( ptr, 3 ) ) ParseConfig( "default", 2 );*/ #endif level.spawning = qfalse; // any future calls to G_Spawn*() will be errors }
This code fragment is small part of reverse-engineered qagamex86.dll(xp2.1).
P.S. I think excessiveplus source code is here.
From program(IDA Pro with Hex-Rays) I can get only this files.
On ne peux "normalement" pas modifier les fichiers .qvm.. Mais tu peux quand même faire ton propre mod grace au source de quake 3. Après c'est a toi d'apprendre, c'est du C simplement