diff --git a/MAIN/configs/defaultcomp.config b/MAIN/configs/defaultcomp.config index 5fbfc0d7..4ab11103 100644 --- a/MAIN/configs/defaultcomp.config +++ b/MAIN/configs/defaultcomp.config @@ -1,82 +1,83 @@ -// -// RTCWPro Default Competition -// -// !!! IMPORTANT NOTE !!! -// Ensure all values are surrounded by quotes, the parser can't properly deal with negative values otherwise. - -configname "^1RTCWPro ^7Competition" - -init -{ -setl g_tournament "1" -setl g_altStopwatchMode "0" -setl g_complaintlimit "999" -setl g_inactivity "0" -setl g_forcerespawn "0" -setl g_doWarmup "1" -setl g_inactivity "0" -setl g_maxlives "0" -setl g_teamforcebalance "0" -setl g_voicechatsallowed "50" -setl g_warmup "10" -setl g_antiWarp "1" -setl g_antilag "1" -setl g_noTeamSwitching "0" -setl g_minGameClients "2" -setl match_minplayers "2" -setl match_latejoin "0" -setl match_mutespecs "0" -setl match_timeoutcount "3" -setl match_warmupDamage "4" -setl team_maxplayers "10" -setl team_nocontrols "0" -setl team_commands "1" -setl sv_allowDownload "1" -setl sv_floodProtect "0" -setl sv_fps "20" -setl vote_limit "10" -setl g_lifeStats "0" -setl g_crouchRate "5" -setl g_fastStabSound "3" // 1 = osp goat, 2 = humiliation, 3 = random -setl g_maxTeamPF "1" -setl g_dropWeapons "9" -setl g_stats_curl_submit "1" - -command sv_cvarempty 0 0 "0" -command sv_cvar cg_bobup IN "0 0.005" -command sv_cvar cg_bobpitch IN "0 0.002" -command sv_cvar cg_bobroll IN "0 0.002" -command sv_cvar cg_fov IN "90 120" -command sv_cvar cg_shadows EQ "0" -command sv_cvar cg_thirdperson EQ "0" -command sv_cvar cg_zoomDefaultSniper IN "0 125" -command sv_cvar cl_avidemo EQ "0" -command sv_cvar cl_maxpackets EQ "100" -command sv_cvar cl_pitchspeed IN "0 180" -command sv_cvar cl_timenudge IN "-20 0" -command sv_cvar cl_yawspeed IN "0 180" -command sv_cvar com_maxfps IN "60 125" -command sv_cvar m_pitch OUT "-0.01 0.01" -command sv_cvar m_yaw EQ "0.022" -command sv_cvar r_ati_fsaa_samples EQ "0" -command sv_cvar r_ati_truform_tess EQ "0" -command sv_cvar r_colorbits EQ "32" -command sv_cvar r_ext_ATI_pntriangles EQ "0" -command sv_cvar r_ext_NV_fog_dist EQ "0" -command sv_cvar r_ext_texture_filter_anisotropic EQ "0" -command sv_cvar r_gamma IN "0 3" -command sv_cvar r_flares IN "0 1" -command sv_cvar r_ignorehwgamma EQ "1" -command sv_cvar r_intensity IN "0 3" -command sv_cvar r_mapoverbrightbits IN "0 4" -command sv_cvar r_overbrightbits IN "0 4" -command sv_cvar r_picmip IN "0 3" -command sv_cvar r_primitives IN "0 2" -command sv_cvar r_rmse EQ "0" -command sv_cvar r_texturemode INCLUDE "GL_LINEAR" -command sv_cvar r_uifullscreen IN "0 1" -command sv_cvar r_vertexlight IN "0 1" -command sv_cvar rate EQ "25000" -command sv_cvar snaps EQ "40" -command sv_cvarload 0 0 "0" -} +// +// RTCWPro Default Competition +// +// !!! IMPORTANT NOTE !!! +// Ensure all values are surrounded by quotes, the parser can't properly deal with negative values otherwise. + +configname "^1RTCWPro ^7Competition" + +init +{ +setl g_tournament "1" +setl g_altStopwatchMode "0" +setl g_complaintlimit "999" +setl g_inactivity "0" +setl g_forcerespawn "0" +setl g_doWarmup "1" +setl g_inactivity "0" +setl g_maxlives "0" +setl g_teamforcebalance "0" +setl g_voicechatsallowed "50" +setl g_warmup "10" +setl g_antiWarp "1" +setl g_antilag "1" +setl g_noTeamSwitching "0" +setl g_minGameClients "2" +setl match_minplayers "2" +setl match_latejoin "0" +setl match_mutespecs "0" +setl match_timeoutcount "3" +setl match_warmupDamage "4" +setl team_maxplayers "10" +setl team_nocontrols "0" +setl team_commands "1" +setl sv_allowDownload "1" +setl sv_floodProtect "0" +setl sv_fps "20" +setl vote_limit "10" +setl g_lifeStats "0" +setl g_crouchRate "5" +setl g_fastStabSound "3" // 1 = osp goat, 2 = humiliation, 3 = random +setl g_maxTeamPF "1" +setl g_dropWeapons "9" +setl g_customSpawns "0" +setl g_stats_curl_submit "1" + +command sv_cvarempty 0 0 "0" +command sv_cvar cg_bobup IN "0 0.005" +command sv_cvar cg_bobpitch IN "0 0.002" +command sv_cvar cg_bobroll IN "0 0.002" +command sv_cvar cg_fov IN "90 120" +command sv_cvar cg_shadows EQ "0" +command sv_cvar cg_thirdperson EQ "0" +command sv_cvar cg_zoomDefaultSniper IN "0 125" +command sv_cvar cl_avidemo EQ "0" +command sv_cvar cl_maxpackets EQ "100" +command sv_cvar cl_pitchspeed IN "0 180" +command sv_cvar cl_timenudge IN "-20 0" +command sv_cvar cl_yawspeed IN "0 180" +command sv_cvar com_maxfps IN "60 125" +command sv_cvar m_pitch OUT "-0.01 0.01" +command sv_cvar m_yaw EQ "0.022" +command sv_cvar r_ati_fsaa_samples EQ "0" +command sv_cvar r_ati_truform_tess EQ "0" +command sv_cvar r_colorbits EQ "32" +command sv_cvar r_ext_ATI_pntriangles EQ "0" +command sv_cvar r_ext_NV_fog_dist EQ "0" +command sv_cvar r_ext_texture_filter_anisotropic EQ "0" +command sv_cvar r_gamma IN "0 3" +command sv_cvar r_flares IN "0 1" +command sv_cvar r_ignorehwgamma EQ "1" +command sv_cvar r_intensity IN "0 3" +command sv_cvar r_mapoverbrightbits IN "0 4" +command sv_cvar r_overbrightbits IN "0 4" +command sv_cvar r_picmip IN "0 3" +command sv_cvar r_primitives IN "0 2" +command sv_cvar r_rmse EQ "0" +command sv_cvar r_texturemode INCLUDE "GL_LINEAR" +command sv_cvar r_uifullscreen IN "0 1" +command sv_cvar r_vertexlight IN "0 1" +command sv_cvar rate EQ "25000" +command sv_cvar snaps EQ "40" +command sv_cvarload 0 0 "0" +} diff --git a/MAIN/configs/defaultpublic.config b/MAIN/configs/defaultpublic.config index 5b951187..480cacac 100644 --- a/MAIN/configs/defaultpublic.config +++ b/MAIN/configs/defaultpublic.config @@ -41,6 +41,7 @@ setl g_fastStabSound "3" // 1 = osp goat, 2 = humiliation, 3 = random setl g_hitsounds "0" setl g_maxTeamPF "1" setl g_dropWeapons "9" +setl g_customSpawns "0" // reset cvars which might be set (but no changed) when switching from public to comp configs set g_userTimeLimit "0" diff --git a/MAIN/configs/pug.config b/MAIN/configs/pug.config index 72c7dc45..4b03433b 100644 --- a/MAIN/configs/pug.config +++ b/MAIN/configs/pug.config @@ -43,6 +43,7 @@ setl g_maxTeamFlamer "1" setl g_maxTeamSniper "2" setl g_maxTeamVenom "1" setl g_dropWeapons "9" +setl g_customSpawns "0" command sv_cvarempty 0 0 "0" command sv_cvar cg_bobup IN "0 0.005" diff --git a/src/game/g_local.h b/src/game/g_local.h index 55638b3e..8e2d0453 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -1688,7 +1688,7 @@ extern vmCvar_t vote_percent; extern vmCvar_t g_antiWarp; // antiwarp port extern vmCvar_t P; // player teams in server info extern vmCvar_t g_hsDamage; - +extern vmCvar_t g_customSpawns; void trap_Printf( const char *fmt ); void trap_Error( const char *fmt ); int trap_Milliseconds( void ); @@ -1738,6 +1738,10 @@ void trap_BotFreeClient( int clientNum ); void trap_GetUsercmd( int clientNum, usercmd_t *cmd ); qboolean trap_GetEntityToken( char *buffer, int bufferSize ); qboolean trap_GetTag(gentity_t* ent, clientAnimationInfo_t* animInfo, char* tagName, orientation_t* or ); +// sswolf - custom spawns +void trap_AppendEntityString(char* fileName); +void trap_FreeEntityString(void); +// custom spawns end int trap_DebugPolygonCreate( int color, int numPoints, vec3_t *points ); void trap_DebugPolygonDelete( int id ); diff --git a/src/game/g_main.c b/src/game/g_main.c index 0bb1d1f9..9cadada9 100644 --- a/src/game/g_main.c +++ b/src/game/g_main.c @@ -314,6 +314,7 @@ vmCvar_t g_dropWeapons; // allow drop weapon for each class, bitflag value: 1 vmCvar_t P; // ET Port Players server info vmCvar_t g_hsDamage; +vmCvar_t g_customSpawns; cvarTable_t gameCvarTable[] = { // don't override the cheat state set by the system @@ -580,6 +581,7 @@ cvarTable_t gameCvarTable[] = { { &g_dbgRevive, "g_dbgRevive", "0", 0, 0, qfalse }, { &g_dropWeapons, "g_dropWeapons", "9", CVAR_ARCHIVE, 0, qtrue, qtrue }, { &g_hsDamage, "g_hsDamage", "50", CVAR_ARCHIVE, 0, qfalse, qtrue }, + { &g_customSpawns, "g_customSpawns", "0", CVAR_ARCHIVE, 0, qfalse }, // sswolf - custom spawns, source: Nobo { &g_pauseLimit, "g_pauseLimit", "3", CVAR_ARCHIVE, 0, qfalse, qfalse }, { &P, "P", "", CVAR_SERVERINFO | CVAR_ARCHIVE, 0, qfalse } // ET Port Players server info }; @@ -1473,6 +1475,7 @@ G_InitGame void G_InitGame( int levelTime, int randomSeed, int restart ) { int i; char cs[MAX_INFO_STRING]; + char mapName[MAX_QPATH]; if ( trap_Cvar_VariableIntegerValue( "g_gametype" ) != GT_SINGLE_PLAYER ) { G_Printf( "------- Game Initialization -------\n" ); @@ -1644,6 +1647,20 @@ void G_InitGame( int levelTime, int randomSeed, int restart ) { ClearRegisteredItems(); + if (g_customSpawns.integer) + { + trap_Cvar_VariableStringBuffer("mapname", mapName, sizeof(mapName)); + } + + if (!restart) + { + // NOTE(nobo): Append to entity string before it's parsed by G_SpawnEntitiesFromString + if (g_customSpawns.integer) + { + trap_AppendEntityString(va("maps/%s.spawns", mapName)); + } + } + // parse the key/value pairs and spawn gentities G_SpawnEntitiesFromString(); @@ -1670,7 +1687,7 @@ void G_InitGame( int levelTime, int randomSeed, int restart ) { // L0 - auto cfg for each map if (g_mapConfigs.integer){ - char mapName[64]; + //char mapName[64]; trap_Cvar_VariableStringBuffer( "mapname", mapName, sizeof(mapName) ); trap_SendConsoleCommand(EXEC_APPEND, va("exec mapConfigs/%s.cfg \n", mapName)); diff --git a/src/game/g_public.h b/src/game/g_public.h index feb3a853..928d12e4 100644 --- a/src/game/g_public.h +++ b/src/game/g_public.h @@ -246,6 +246,11 @@ typedef enum { G_GETTAG, + // sswolf - custom spawns + G_APPEND_ENTITY_STRING, + G_FREE_ENTITY_STRING, + // custom spawns end + BOTLIB_SETUP = 200, // ( void ); BOTLIB_SHUTDOWN, // ( void ); BOTLIB_LIBVAR_SET, diff --git a/src/game/g_syscalls.c b/src/game/g_syscalls.c index 9758df5e..2ae68d21 100644 --- a/src/game/g_syscalls.c +++ b/src/game/g_syscalls.c @@ -255,6 +255,16 @@ qboolean trap_GetTag(gentity_t* ent, clientAnimationInfo_t* animInfo, char* tagN return syscall(G_GETTAG, ent, animInfo, tagName, or ); } +// sswolf - custom spawns +void trap_AppendEntityString(char* fileName) { + syscall(G_APPEND_ENTITY_STRING, fileName); +} + +void trap_FreeEntityString() { + syscall(G_FREE_ENTITY_STRING); +} +// custom spawns end + int trap_PC_LoadSource(const char* filename) { return syscall(BOTLIB_PC_LOAD_SOURCE, filename); } diff --git a/src/qcommon/cm_load.c b/src/qcommon/cm_load.c index 9db5a2a8..51528493 100644 --- a/src/qcommon/cm_load.c +++ b/src/qcommon/cm_load.c @@ -458,7 +458,11 @@ CMod_LoadEntityString ================= */ void CMod_LoadEntityString( lump_t *l ) { - cm.entityString = Hunk_Alloc( l->filelen, h_high ); + + // sswolf - custom spawns + //cm.entityString = Hunk_Alloc( l->filelen, h_high ); + cm.entityString = Z_Malloc(l->filelen); + // custom spawns end cm.numEntityChars = l->filelen; memcpy( cm.entityString, cmod_base + l->fileofs, l->filelen ); } @@ -751,6 +755,28 @@ char *CM_EntityString( void ) { return cm.entityString; } +/* +============= +sswolf - custom spawns + +CM_AppendToEntityString +============= +*/ +void CM_AppendToEntityString(char* data, int dataLength) { + int newSize = cm.numEntityChars + dataLength; + char* newEntityString = Z_Malloc(newSize); + + if (cm.entityString) + { + Q_strncpyz(newEntityString, cm.entityString, newSize); + Z_Free(cm.entityString); + } + + Q_strcat(newEntityString, newSize, data); + cm.entityString = newEntityString; + cm.numEntityChars = newSize; +} + int CM_LeafCluster( int leafnum ) { if ( leafnum < 0 || leafnum >= cm.numLeafs ) { Com_Error( ERR_DROP, "CM_LeafCluster: bad number" ); diff --git a/src/qcommon/cm_public.h b/src/qcommon/cm_public.h index 0d0dfcb8..a23f1e57 100644 --- a/src/qcommon/cm_public.h +++ b/src/qcommon/cm_public.h @@ -43,6 +43,7 @@ void CM_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs ); int CM_NumClusters( void ); int CM_NumInlineModels( void ); char *CM_EntityString( void ); +void CM_AppendToEntityString(char* data, int dataLength); // sswolf - custom spawns // returns an ORed contents mask int CM_PointContents( const vec3_t p, clipHandle_t model ); diff --git a/src/server/server.h b/src/server/server.h index cee39690..122e2bcc 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -466,7 +466,11 @@ void SV_InitGameProgs( void ); void SV_ShutdownGameProgs( void ); void SV_RestartGameProgs( void ); qboolean SV_inPVS( const vec3_t p1, const vec3_t p2 ); -qboolean SV_GetTag(sharedEntity_t* ent, clientAnimationInfo_t* animInfo, char* tagname, orientation_t* or ); +qboolean SV_GetTag(sharedEntity_t* ent, clientAnimationInfo_t* animInfo, char* tagname, orientation_t* or ); +// sswolf - custom spawns +void SV_AppendEntityString(char* fileName); +void SV_FreeEntityString(); +// custom spawns end // sv_animation.c int SV_LerpTag(orientation_t* tag, clientAnimationInfo_t* animInfo, char* tagname); diff --git a/src/server/sv_game.c b/src/server/sv_game.c index 77954f0d..36582cd1 100644 --- a/src/server/sv_game.c +++ b/src/server/sv_game.c @@ -474,6 +474,15 @@ int SV_GameSystemCalls( int *args ) { case G_GETTAG: return SV_GetTag(VMA(1), VMA(2), VMA(3), VMA(4)); + // sswolf - custom spawns + case G_APPEND_ENTITY_STRING: + SV_AppendEntityString(VMA(1)); + return 0; + case G_FREE_ENTITY_STRING: + SV_FreeEntityString(); + return 0; + // custom spawns end + //==================================== case BOTLIB_SETUP: @@ -955,6 +964,9 @@ void SV_ShutdownGameProgs( void ) { return; } VM_Call( gvm, GAME_SHUTDOWN, qfalse ); + // sswolf - custom spawns + SV_FreeEntityString(); + // custom spawns end VM_Free( gvm ); gvm = NULL; } @@ -1098,3 +1110,42 @@ qboolean SV_GetTag(sharedEntity_t* ent, clientAnimationInfo_t* animInfo, char* t return qtrue; #endif } + +// sswolf - custom spawns +/* +==================== +SV_AppendEntityString + +Reads in entity string from file and appends it to the current entity string +==================== +*/ +void SV_AppendEntityString(char* fileName) +{ + int* buf = NULL; + int length = FS_ReadFile(fileName, (void**)&buf); + + if (buf) + { + CM_AppendToEntityString((char*)buf, length); + sv.entityParsePoint = CM_EntityString(); + FS_FreeFile(buf); + } +} + +/* +=============== +SV_FreeEntityString + +Z_Frees entity string on map unload +=============== +*/ +void SV_FreeEntityString() +{ + char* entityString = CM_EntityString(); + if (entityString) + { + Z_Free(entityString); + } +} +// custom spawns end +