diff --git a/reaction/cgame/cg_players.c b/reaction/cgame/cg_players.c index 0b362c2f..5a5a74f3 100644 --- a/reaction/cgame/cg_players.c +++ b/reaction/cgame/cg_players.c @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.22 2002/04/22 02:27:57 jbravo +// Dynamic model recognition +// // Revision 1.21 2002/03/31 03:31:24 jbravo // Compiler warning cleanups // @@ -359,7 +362,9 @@ static qboolean CG_FindClientModelFile( char *filename, int length, clientInfo_t if ( CG_FileExists( filename ) ) { return qtrue; } - if ( cgs.gametype >= GT_TEAM ) { + if (cgs.gametype == GT_TEAMPLAY) { + Com_sprintf( filename, length, "models/players/%s/%s_%s.%s", modelName, base, skinName, ext); + } else if ( cgs.gametype >= GT_TEAM ) { if ( i == 0 && teamName && *teamName ) { // "models/players/characters/james/stroggs/lower_red.skin" Com_sprintf( filename, length, "models/players/%s%s/%s%s_%s.%s", charactersFolder, modelName, teamName, base, team, ext ); @@ -439,7 +444,9 @@ static qboolean CG_FindClientHeadFile( char *filename, int length, clientInfo_t if ( CG_FileExists( filename ) ) { return qtrue; } - if ( cgs.gametype >= GT_TEAM ) { + if (cgs.gametype == GT_TEAMPLAY) { + Com_sprintf( filename, length, "models/players/%s/%s_%s.%s", headModelName, base, headSkinName, ext); + } else if ( cgs.gametype >= GT_TEAM ) { if ( i == 0 && teamName && *teamName ) { Com_sprintf( filename, length, "models/players/%s%s/%s%s_%s.%s", headsFolder, headModelName, teamName, base, team, ext ); } @@ -480,6 +487,7 @@ CG_RegisterClientSkin static qboolean CG_RegisterClientSkin( clientInfo_t *ci, const char *teamName, const char *modelName, const char *skinName, const char *headModelName, const char *headSkinName ) { char filename[MAX_QPATH]; + CG_Printf("debug: modelName = %s, skinName = %s, headModelName = %s, headSkinName = %s\n", modelName, skinName, headModelName, headSkinName); /* Com_sprintf( filename, sizeof( filename ), "models/players/%s/%slower_%s.skin", modelName, teamName, skinName ); ci->legsSkin = trap_R_RegisterSkin( filename ); diff --git a/reaction/game/g_client.c b/reaction/game/g_client.c index 9444c343..757bc3af 100644 --- a/reaction/game/g_client.c +++ b/reaction/game/g_client.c @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.67 2002/04/22 02:27:57 jbravo +// Dynamic model recognition +// // Revision 1.66 2002/04/18 16:13:23 jbravo // Scoreboard now shows green for live players and white for dead. // Time should not get reset on deaths any more. @@ -153,6 +156,9 @@ char rq3_breakables[RQ3_MAX_BREAKABLES][80]; #define RQ3_NONAMEPLAYER "Nameless" +// JBravo: for models +extern legitmodel_t legitmodels[MAXMODELS]; + // g_client.c -- client functions that don't happen every frame static vec3_t playerMins = {-15, -15, -24}; @@ -863,6 +869,7 @@ void ClientUserinfoChanged( int clientNum ) { int teamTask, teamLeader, team, health; char *s; char model[MAX_QPATH]; + char skin[MAX_QPATH]; char headModel[MAX_QPATH]; char oldname[MAX_STRING_CHARS]; gclient_t *client; @@ -945,23 +952,32 @@ void ClientUserinfoChanged( int clientNum ) { Q_strncpyz( headModel, Info_ValueForKey (userinfo, "headmodel"), sizeof( headModel ) ); } - // NiceAss: temporary hack to prevent non-grunt models: - Q_strncpyz(model2, model, sizeof(model)); - skin2 = Q_strrchr( model2, '/' ); - if ( skin2 ) { - *skin2++ = '\0'; + if (g_gametype.integer == GT_TEAMPLAY) { + if (client->sess.sessionTeam == TEAM_RED) { + Com_sprintf (model, sizeof (model) , "%s/%s", g_RQ3_team1model.string, g_RQ3_team1skin.string); + Com_sprintf (headModel, sizeof (headModel) , "%s/%s", g_RQ3_team1model.string, g_RQ3_team1skin.string); + } else { + Com_sprintf (model, sizeof (model) , "%s/%s", g_RQ3_team2model.string, g_RQ3_team2skin.string); + Com_sprintf (headModel, sizeof (headModel) , "%s/%s", g_RQ3_team2model.string, g_RQ3_team2skin.string); + } } else { - skin2 = "default"; - } + // NiceAss: temporary hack to prevent non-grunt models: + Q_strncpyz(model2, model, sizeof(model)); + skin2 = Q_strrchr( model2, '/' ); + if ( skin2 ) { + *skin2++ = '\0'; + } else { + skin2 = "default"; + } - // Makro - adding abbey - if ( Q_stricmpn(model2, "grunt", sizeof(model2)) && Q_stricmpn(model2, "abbey", sizeof(model2))) { - trap_SendServerCommand( ent-g_entities, va("print \"Illegal player model (%s). Forcing change on server.\n\"", model2)); - Q_strncpyz(model, "grunt/resdog", sizeof("grunt/resdog")); - Q_strncpyz(headModel, "grunt/resdog", sizeof("grunt/resdog")); + // Makro - adding abbey + if ( Q_stricmpn(model2, "grunt", sizeof(model2)) && Q_stricmpn(model2, "abbey", sizeof(model2))) { + trap_SendServerCommand( ent-g_entities, va("print \"Illegal player model (%s). Forcing change on server.\n\"", model2)); + Q_strncpyz(model, "grunt/resdog", sizeof("grunt/resdog")); + Q_strncpyz(headModel, "grunt/resdog", sizeof("grunt/resdog")); + } + // End of temporary hack. } - // End of temporary hack. - // bots set their team a few frames later if (g_gametype.integer >= GT_TEAM && g_entities[clientNum].r.svFlags & SVF_BOT) { s = Info_ValueForKey( userinfo, "team" ); diff --git a/reaction/game/g_local.h b/reaction/game/g_local.h index a786d5f4..9b7dca28 100644 --- a/reaction/game/g_local.h +++ b/reaction/game/g_local.h @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.68 2002/04/22 02:27:57 jbravo +// Dynamic model recognition +// // Revision 1.67 2002/04/15 00:54:26 assimon // Simple ini file parser that reads a ini configuration file and suports rotations. // @@ -536,6 +539,17 @@ struct gclient_s { int team_kills; }; +// JBravo: for model loading +#define MAXMODELS 64 +#define MAXMODELLEN 100 + +typedef struct legitmodel { + char name[MAXMODELLEN]; + vec3_t team1color; + vec3_t team2color; + int gender; +} legitmodel_t; + // Begin Duffman int G_LocationDamage(vec3_t point, gentity_t* targ, gentity_t* attacker, int take); @@ -1091,6 +1105,10 @@ extern vmCvar_t g_RQ3_limchasecam; // JBravo: 0 = no chasecam limit, 1 = limite extern vmCvar_t g_RQ3_sniperup; // JBravo: 0 = snipers begin with pistol, 1 = begin with sniper extern vmCvar_t g_RQ3_team1name; // JBravo: cvar for the name of team 1 extern vmCvar_t g_RQ3_team2name; // JBravo: cvar for the name of team 2 +extern vmCvar_t g_RQ3_team1model; // JBravo: team 1 model +extern vmCvar_t g_RQ3_team2model; // JBravo: team 2 model +extern vmCvar_t g_RQ3_team1skin; // JBravo: team 1 skin +extern vmCvar_t g_RQ3_team2skin; // JBravo: team 2 skin extern vmCvar_t g_RQ3_lca; // JBravo: cvar to signal cgame that LCA is in progress extern vmCvar_t g_RQ3_teamCount1; // JBravo: cvar for the UI join menus extern vmCvar_t g_RQ3_teamCount2; // JBravo: cvar for the UI join menus diff --git a/reaction/game/g_main.c b/reaction/game/g_main.c index 9cbe2975..8639b2f0 100644 --- a/reaction/game/g_main.c +++ b/reaction/game/g_main.c @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.46 2002/04/22 02:27:57 jbravo +// Dynamic model recognition +// // Revision 1.45 2002/04/15 00:54:26 assimon // Simple ini file parser that reads a ini configuration file and suports rotations. // @@ -197,6 +200,10 @@ vmCvar_t g_RQ3_sniperup; vmCvar_t g_RQ3_lca; vmCvar_t g_RQ3_team1name; vmCvar_t g_RQ3_team2name; +vmCvar_t g_RQ3_team1model; +vmCvar_t g_RQ3_team2model; +vmCvar_t g_RQ3_team1skin; +vmCvar_t g_RQ3_team2skin; vmCvar_t g_RQ3_teamCount1; vmCvar_t g_RQ3_teamCount2; vmCvar_t g_RQ3_numSpectators; @@ -343,6 +350,10 @@ static cvarTable_t gameCvarTable[] = { { &g_RQ3_sniperup, "g_RQ3_sniperup", "0", CVAR_ARCHIVE, 0, qtrue}, { &g_RQ3_team1name, "g_RQ3_team1name", "Robbers", CVAR_SYSTEMINFO | CVAR_SERVERINFO , 0, qfalse }, { &g_RQ3_team2name, "g_RQ3_team2name", "Swat", CVAR_SYSTEMINFO | CVAR_SERVERINFO , 0, qfalse }, + { &g_RQ3_team1model, "g_RQ3_team1model", "grunt", CVAR_SERVERINFO, 0, qfalse }, + { &g_RQ3_team2model, "g_RQ3_team2model", "grunt", CVAR_SERVERINFO, 0, qfalse }, + { &g_RQ3_team1skin, "g_RQ3_team1skin", "robber", CVAR_SERVERINFO, 0, qfalse }, + { &g_RQ3_team2skin, "g_RQ3_team2skin", "police", CVAR_SERVERINFO, 0, qfalse }, { &g_RQ3_teamCount1, "g_RQ3_teamCount1", "0", CVAR_ROM, 0, qfalse }, { &g_RQ3_teamCount2, "g_RQ3_teamCount2", "0", CVAR_ROM, 0, qfalse }, { &g_RQ3_numSpectators, "g_RQ3_numSpectators", "0", CVAR_ROM, 0, qfalse }, @@ -587,8 +598,14 @@ G_InitGame ============ */ + +legitmodel_t legitmodels[MAXMODELS]; + void G_InitGame( int levelTime, int randomSeed, int restart ) { - int i; + int i, j, numdirs, dirlen, len, modelcount; + char *dirptr, *text_p, *token; + char dirlist[2048], buf[2048]; + fileHandle_t file; G_Printf ("------- Game Initialization -------\n"); G_Printf ("gamename: %s\n", GAMEVERSION); @@ -727,6 +744,80 @@ void G_InitGame( int levelTime, int randomSeed, int restart ) { BotAILoadMap( restart ); G_InitBots( restart ); } +// JBravo: Load legit model names. + if (g_gametype.integer == GT_TEAMPLAY) { + for (i=0; i < MAXMODELS; i++) { + memset (&legitmodels[i], 0, sizeof (legitmodels[i])); + } + numdirs = trap_FS_GetFileList("models/players", "/", dirlist, sizeof(dirlist)); + dirptr = dirlist; + modelcount = 0; + for (i=0; i < numdirs; i++, dirptr += dirlen+1) { + dirlen = strlen(dirptr); + if (dirlen && dirptr[dirlen-1]=='/') dirptr[dirlen-1]='\0'; + if (!strcmp(dirptr, ".") || !strcmp(dirptr, "..")) + continue; + len = trap_FS_FOpenFile(va("models/players/%s/rq3model.cfg", dirptr), &file, FS_READ); + if (file) { + trap_FS_Read(buf, len, file); + buf[len] = 0; + text_p = buf; + trap_FS_FCloseFile (file); + Com_sprintf(legitmodels[modelcount].name, sizeof(legitmodels[modelcount].name), "%s", dirptr); + for (j=0; j < 3; j++) { + token = COM_Parse(&text_p); + if (!token) break; + if (Q_stricmp (token, "team1color") == 0) { + token = COM_Parse(&text_p); + if (token) + legitmodels[modelcount].team1color[0] = atof (token); + else + break; + token = COM_Parse(&text_p); + if (token) + legitmodels[modelcount].team1color[1] = atof (token); + else + break; + token = COM_Parse(&text_p); + if (token) + legitmodels[modelcount].team1color[2] = atof (token); + else + break; + } else if (Q_stricmp (token, "team2color") == 0) { + token = COM_Parse(&text_p); + if (token) + legitmodels[modelcount].team2color[0] = atof (token); + else + break; + token = COM_Parse(&text_p); + if (token) + legitmodels[modelcount].team2color[1] = atof (token); + else + break; + token = COM_Parse(&text_p); + if (token) + legitmodels[modelcount].team2color[2] = atof (token); + else + break; + } else if (Q_stricmp (token, "gender") == 0) { + token = COM_Parse(&text_p); + if (token) + if (!Q_stricmp(token, "male")) + legitmodels[modelcount].gender = GENDER_MALE; + else if (!Q_stricmp(token, "female")) + legitmodels[modelcount].gender = GENDER_FEMALE; + else if (!Q_stricmp(token, "neuter")) + legitmodels[modelcount].gender = GENDER_NEUTER; + else + break; + else + break; + } + } + modelcount++; + } + } + } G_RemapTeamShaders();