00001
00002
00003
00004
00005
00006
00007 #include "cg_local.h"
00008 #include "../../ui/menudef.h"
00009 #if !defined(CL_LIGHT_H_INC)
00010 #include "cg_lights.h"
00011 #endif
00012 #include "..\ghoul2\g2.h"
00013 #include "../ui/ui_public.h"
00014
00015
00016
00017
00018
00019
00020
00021 static void CG_ParseScores( void ) {
00022 int i, powerups, readScores;
00023
00024 cg.numScores = atoi( CG_Argv( 1 ) );
00025
00026 readScores = cg.numScores;
00027
00028 if (readScores > MAX_CLIENT_SCORE_SEND)
00029 {
00030 readScores = MAX_CLIENT_SCORE_SEND;
00031 }
00032
00033 if ( cg.numScores > MAX_CLIENTS ) {
00034 cg.numScores = MAX_CLIENTS;
00035 }
00036
00037 cg.numScores = readScores;
00038
00039 cg.teamScores[0] = atoi( CG_Argv( 2 ) );
00040 cg.teamScores[1] = atoi( CG_Argv( 3 ) );
00041
00042 memset( cg.scores, 0, sizeof( cg.scores ) );
00043 for ( i = 0 ; i < readScores ; i++ ) {
00044
00045 cg.scores[i].client = atoi( CG_Argv( i * 14 + 4 ) );
00046 cg.scores[i].score = atoi( CG_Argv( i * 14 + 5 ) );
00047 cg.scores[i].ping = atoi( CG_Argv( i * 14 + 6 ) );
00048 cg.scores[i].time = atoi( CG_Argv( i * 14 + 7 ) );
00049 cg.scores[i].scoreFlags = atoi( CG_Argv( i * 14 + 8 ) );
00050 powerups = atoi( CG_Argv( i * 14 + 9 ) );
00051 cg.scores[i].accuracy = atoi(CG_Argv(i * 14 + 10));
00052 cg.scores[i].impressiveCount = atoi(CG_Argv(i * 14 + 11));
00053 cg.scores[i].excellentCount = atoi(CG_Argv(i * 14 + 12));
00054 cg.scores[i].guantletCount = atoi(CG_Argv(i * 14 + 13));
00055 cg.scores[i].defendCount = atoi(CG_Argv(i * 14 + 14));
00056 cg.scores[i].assistCount = atoi(CG_Argv(i * 14 + 15));
00057 cg.scores[i].perfect = atoi(CG_Argv(i * 14 + 16));
00058 cg.scores[i].captures = atoi(CG_Argv(i * 14 + 17));
00059
00060 if ( cg.scores[i].client < 0 || cg.scores[i].client >= MAX_CLIENTS ) {
00061 cg.scores[i].client = 0;
00062 }
00063 cgs.clientinfo[ cg.scores[i].client ].score = cg.scores[i].score;
00064 cgs.clientinfo[ cg.scores[i].client ].powerups = powerups;
00065
00066 cg.scores[i].team = cgs.clientinfo[cg.scores[i].client].team;
00067 }
00068 CG_SetScoreSelection(NULL);
00069 }
00070
00071
00072
00073
00074
00075
00076
00077 static void CG_ParseTeamInfo( void ) {
00078 int i;
00079 int client;
00080
00081 numSortedTeamPlayers = atoi( CG_Argv( 1 ) );
00082
00083 for ( i = 0 ; i < numSortedTeamPlayers ; i++ ) {
00084 client = atoi( CG_Argv( i * 6 + 2 ) );
00085
00086 sortedTeamPlayers[i] = client;
00087
00088 cgs.clientinfo[ client ].location = atoi( CG_Argv( i * 6 + 3 ) );
00089 cgs.clientinfo[ client ].health = atoi( CG_Argv( i * 6 + 4 ) );
00090 cgs.clientinfo[ client ].armor = atoi( CG_Argv( i * 6 + 5 ) );
00091 cgs.clientinfo[ client ].curWeapon = atoi( CG_Argv( i * 6 + 6 ) );
00092 cgs.clientinfo[ client ].powerups = atoi( CG_Argv( i * 6 + 7 ) );
00093 }
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 void CG_ParseServerinfo( void ) {
00106 const char *info;
00107 const char *tinfo;
00108 char *mapname;
00109
00110 info = CG_ConfigString( CS_SERVERINFO );
00111
00112 cgs.debugMelee = atoi( Info_ValueForKey( info, "g_debugMelee" ) );
00113 cgs.stepSlideFix = atoi( Info_ValueForKey( info, "g_stepSlideFix" ) );
00114
00115 cgs.noSpecMove = atoi( Info_ValueForKey( info, "g_noSpecMove" ) );
00116
00117 trap_Cvar_Set("bg_fighterAltControl", Info_ValueForKey( info, "bg_fighterAltControl" ));
00118
00119 cgs.siegeTeamSwitch = atoi( Info_ValueForKey( info, "g_siegeTeamSwitch" ) );
00120
00121 cgs.showDuelHealths = atoi( Info_ValueForKey( info, "g_showDuelHealths" ) );
00122
00123 cgs.gametype = atoi( Info_ValueForKey( info, "g_gametype" ) );
00124 trap_Cvar_Set("g_gametype", va("%i", cgs.gametype));
00125 cgs.needpass = atoi( Info_ValueForKey( info, "needpass" ) );
00126 cgs.jediVmerc = atoi( Info_ValueForKey( info, "g_jediVmerc" ) );
00127 cgs.wDisable = atoi( Info_ValueForKey( info, "wdisable" ) );
00128 cgs.fDisable = atoi( Info_ValueForKey( info, "fdisable" ) );
00129 cgs.dmflags = atoi( Info_ValueForKey( info, "dmflags" ) );
00130 cgs.teamflags = atoi( Info_ValueForKey( info, "teamflags" ) );
00131 cgs.fraglimit = atoi( Info_ValueForKey( info, "fraglimit" ) );
00132 cgs.duel_fraglimit = atoi( Info_ValueForKey( info, "duel_fraglimit" ) );
00133 cgs.capturelimit = atoi( Info_ValueForKey( info, "capturelimit" ) );
00134 cgs.timelimit = atoi( Info_ValueForKey( info, "timelimit" ) );
00135 cgs.maxclients = atoi( Info_ValueForKey( info, "sv_maxclients" ) );
00136 mapname = Info_ValueForKey( info, "mapname" );
00137
00138
00139 trap_Cvar_Set ( "ui_about_mapname", mapname );
00140
00141 Com_sprintf( cgs.mapname, sizeof( cgs.mapname ), "maps/%s.bsp", mapname );
00142
00143
00144
00145
00146
00147 trap_Cvar_Set ( "ui_about_gametype", va("%i", cgs.gametype ) );
00148 trap_Cvar_Set ( "ui_about_fraglimit", va("%i", cgs.fraglimit ) );
00149 trap_Cvar_Set ( "ui_about_duellimit", va("%i", cgs.duel_fraglimit ) );
00150 trap_Cvar_Set ( "ui_about_capturelimit", va("%i", cgs.capturelimit ) );
00151 trap_Cvar_Set ( "ui_about_timelimit", va("%i", cgs.timelimit ) );
00152 trap_Cvar_Set ( "ui_about_maxclients", va("%i", cgs.maxclients ) );
00153 trap_Cvar_Set ( "ui_about_dmflags", va("%i", cgs.dmflags ) );
00154 trap_Cvar_Set ( "ui_about_hostname", Info_ValueForKey( info, "sv_hostname" ) );
00155 trap_Cvar_Set ( "ui_about_needpass", Info_ValueForKey( info, "g_needpass" ) );
00156 trap_Cvar_Set ( "ui_about_botminplayers", Info_ValueForKey ( info, "bot_minplayers" ) );
00157
00158
00159 trap_Cvar_Set("cg_siegeTeam1", Info_ValueForKey(info, "g_siegeTeam1"));
00160 trap_Cvar_Set("cg_siegeTeam2", Info_ValueForKey(info, "g_siegeTeam2"));
00161
00162 tinfo = CG_ConfigString( CS_TERRAINS + 1 );
00163 if ( !tinfo || !*tinfo )
00164 {
00165 cg.mInRMG = qfalse;
00166 }
00167 else
00168 {
00169 int weather = 0;
00170
00171 cg.mInRMG = qtrue;
00172 trap_Cvar_Set("RMG", "1");
00173
00174 weather = atoi( Info_ValueForKey( info, "RMG_weather" ) );
00175
00176 trap_Cvar_Set("RMG_weather", va("%i", weather));
00177
00178 if (weather == 1 || weather == 2)
00179 {
00180 cg.mRMGWeather = qtrue;
00181 }
00182 else
00183 {
00184 cg.mRMGWeather = qfalse;
00185 }
00186 }
00187 }
00188
00189
00190
00191
00192
00193
00194 static void CG_ParseWarmup( void ) {
00195 const char *info;
00196 int warmup;
00197
00198 info = CG_ConfigString( CS_WARMUP );
00199
00200 warmup = atoi( info );
00201 cg.warmupCount = -1;
00202
00203 cg.warmup = warmup;
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213 void CG_SetConfigValues( void )
00214 {
00215 const char *s;
00216 const char *str;
00217
00218 cgs.scores1 = atoi( CG_ConfigString( CS_SCORES1 ) );
00219 cgs.scores2 = atoi( CG_ConfigString( CS_SCORES2 ) );
00220 cgs.levelStartTime = atoi( CG_ConfigString( CS_LEVEL_START_TIME ) );
00221 if( cgs.gametype == GT_CTF || cgs.gametype == GT_CTY ) {
00222 s = CG_ConfigString( CS_FLAGSTATUS );
00223 cgs.redflag = s[0] - '0';
00224 cgs.blueflag = s[1] - '0';
00225 }
00226 cg.warmup = atoi( CG_ConfigString( CS_WARMUP ) );
00227
00228
00229 cgs.jediMaster = atoi ( CG_ConfigString ( CS_CLIENT_JEDIMASTER ) );
00230 cgs.duelWinner = atoi ( CG_ConfigString ( CS_CLIENT_DUELWINNER ) );
00231
00232 str = CG_ConfigString(CS_CLIENT_DUELISTS);
00233
00234 if (str && str[0])
00235 {
00236 char buf[64];
00237 int c = 0;
00238 int i = 0;
00239
00240 while (str[i] && str[i] != '|')
00241 {
00242 buf[c] = str[i];
00243 c++;
00244 i++;
00245 }
00246 buf[c] = 0;
00247
00248 cgs.duelist1 = atoi ( buf );
00249 c = 0;
00250
00251 i++;
00252 while (str[i])
00253 {
00254 buf[c] = str[i];
00255 c++;
00256 i++;
00257 }
00258 buf[c] = 0;
00259
00260 cgs.duelist2 = atoi ( buf );
00261 }
00262 }
00263
00264
00265
00266
00267
00268
00269 void CG_ShaderStateChanged(void) {
00270 char originalShader[MAX_QPATH];
00271 char newShader[MAX_QPATH];
00272 char timeOffset[16];
00273 const char *o;
00274 char *n,*t;
00275
00276 o = CG_ConfigString( CS_SHADERSTATE );
00277 while (o && *o) {
00278 n = strstr(o, "=");
00279 if (n && *n) {
00280 strncpy(originalShader, o, n-o);
00281 originalShader[n-o] = 0;
00282 n++;
00283 t = strstr(n, ":");
00284 if (t && *t) {
00285 strncpy(newShader, n, t-n);
00286 newShader[t-n] = 0;
00287 } else {
00288 break;
00289 }
00290 t++;
00291 o = strstr(t, "@");
if (o) {
strncpy(timeOffset, t, o-t);
timeOffset[o-t] = 0;
o++;
trap_R_RemapShader( originalShader, newShader, timeOffset );
}
} else {
break;
}
}
}
extern char *cg_customSoundNames[MAX_CUSTOM_SOUNDS];
extern const char *cg_customCombatSoundNames[MAX_CUSTOM_COMBAT_SOUNDS];
extern const char *cg_customExtraSoundNames[MAX_CUSTOM_EXTRA_SOUNDS];
extern const char *cg_customJediSoundNames[MAX_CUSTOM_JEDI_SOUNDS];
extern const char *cg_customDuelSoundNames[MAX_CUSTOM_DUEL_SOUNDS];
static const char *GetCustomSoundForType(int setType, int index)
{
switch (setType)
{
case 1:
return cg_customSoundNames[index];
case 2:
return cg_customCombatSoundNames[index];
case 3:
return cg_customExtraSoundNames[index];
case 4:
return cg_customJediSoundNames[index];
case 5:
return bg_customSiegeSoundNames[index];
case 6:
return cg_customDuelSoundNames[index];
default:
assert(0);
return NULL;
}
}
void SetCustomSoundForType(clientInfo_t *ci, int setType, int index, sfxHandle_t sfx)
{
switch (setType)
{
case 1:
ci->sounds[index] = sfx;
break;
case 2:
ci->combatSounds[index] = sfx;
break;
case 3:
ci->extraSounds[index] = sfx;
break;
case 4:
ci->jediSounds[index] = sfx;
break;
case 5:
ci->siegeSounds[index] = sfx;
break;
case 6:
ci->duelSounds[index] = sfx;
break;
default:
assert(0);
break;
}
}
static void CG_RegisterCustomSounds(clientInfo_t *ci, int setType, const char *psDir)
{
int iTableEntries = 0;
int i;
switch (setType)
{
case 1:
iTableEntries = MAX_CUSTOM_SOUNDS;
break;
case 2:
iTableEntries = MAX_CUSTOM_COMBAT_SOUNDS;
break;
case 3:
iTableEntries = MAX_CUSTOM_EXTRA_SOUNDS;
break;
case 4:
iTableEntries = MAX_CUSTOM_JEDI_SOUNDS;
break;
case 5:
iTableEntries = MAX_CUSTOM_SIEGE_SOUNDS;
default:
assert(0);
return;
}
for ( i = 0 ; i<iTableEntries; i++ )
{
sfxHandle_t hSFX;
const char *s = GetCustomSoundForType(setType, i);
if ( !s )
{
break;
}
s++;
hSFX = trap_S_RegisterSound( va("sound/chars/%s/misc/%s", psDir, s) );
00292
00293 if (hSFX == 0)
00294 {
00295 char modifiedSound[MAX_QPATH];
00296 char *p;
00297
00298 strcpy(modifiedSound, s);
00299 p = strchr(modifiedSound,'.');
00300
00301 if (p)
00302 {
00303 char testNumber[2];
00304 p--;
00305
00306
00307
00308
00309 testNumber[0] = *p;
00310 testNumber[1] = 0;
00311 if (atoi(testNumber))
00312 {
00313 *p = 0;
00314
00315 strcat(modifiedSound, "1.wav");
00316
00317 hSFX = trap_S_RegisterSound( va("sound/chars/%s/misc/%s", psDir, modifiedSound) );
00318 }
00319 }
00320 }
00321
00322 SetCustomSoundForType(ci, setType, i, hSFX);
00323 }
00324 }
00325
00326 void CG_PrecacheNPCSounds(const char *str)
00327 {
00328 char sEnd[MAX_QPATH];
00329 char pEnd[MAX_QPATH];
00330 int i = 0;
00331 int j = 0;
00332 int k = 0;
00333
00334 k = 2;
00335
00336 while (str[k])
00337 {
00338 pEnd[k-2] = str[k];
00339 k++;
00340 }
00341 pEnd[k-2] = 0;
00342
00343 while (i < 4)
00344 {
00345
00346
00347 while (j < MAX_CUSTOM_SOUNDS)
00348 {
00349 const char *s = GetCustomSoundForType(i+1, j);
00350
00351 if (s && s[0])
00352 {
00353 k = 1;
00354 while (s[k])
00355 {
00356 sEnd[k-1] = s[k];
00357 k++;
00358 }
00359 sEnd[k-1] = 0;
00360
00361 trap_S_ShutUp(qtrue);
00362 trap_S_RegisterSound( va("sound/chars/%s/misc/%s", pEnd, sEnd) );
00363 trap_S_ShutUp(qfalse);
00364 }
00365 else
00366 {
00367 break;
00368 }
00369
00370 j++;
00371 }
00372
00373 j = 0;
00374 i++;
00375 }
00376 }
00377
00378 void CG_HandleNPCSounds(centity_t *cent)
00379 {
00380 if (!cent->npcClient)
00381 {
00382 return;
00383 }
00384
00385
00386 if (cent->currentState.csSounds_Std)
00387 {
00388 const char *s = CG_ConfigString( CS_SOUNDS + cent->currentState.csSounds_Std );
00389
00390 if (s && s[0])
00391 {
00392 char sEnd[MAX_QPATH];
00393 int i = 2;
00394 int j = 0;
00395
00396
00397
00398 while (s[i])
00399 {
00400 sEnd[j] = s[i];
00401 j++;
00402 i++;
00403 }
00404 sEnd[j] = 0;
00405
00406 CG_RegisterCustomSounds(cent->npcClient, 1, sEnd);
00407 }
00408 }
00409 else
00410 {
00411 memset(¢->npcClient->sounds, 0, sizeof(cent->npcClient->sounds));
00412 }
00413
00414
00415 if (cent->currentState.csSounds_Combat)
00416 {
00417 const char *s = CG_ConfigString( CS_SOUNDS + cent->currentState.csSounds_Combat );
00418
00419 if (s && s[0])
00420 {
00421 char sEnd[MAX_QPATH];
00422 int i = 2;
00423 int j = 0;
00424
00425
00426
00427 while (s[i])
00428 {
00429 sEnd[j] = s[i];
00430 j++;
00431 i++;
00432 }
00433 sEnd[j] = 0;
00434
00435 CG_RegisterCustomSounds(cent->npcClient, 2, sEnd);
00436 }
00437 }
00438 else
00439 {
00440 memset(¢->npcClient->combatSounds, 0, sizeof(cent->npcClient->combatSounds));
00441 }
00442
00443
00444 if (cent->currentState.csSounds_Extra)
00445 {
00446 const char *s = CG_ConfigString( CS_SOUNDS + cent->currentState.csSounds_Extra );
00447
00448 if (s && s[0])
00449 {
00450 char sEnd[MAX_QPATH];
00451 int i = 2;
00452 int j = 0;
00453
00454
00455
00456 while (s[i])
00457 {
00458 sEnd[j] = s[i];
00459 j++;
00460 i++;
00461 }
00462 sEnd[j] = 0;
00463
00464 CG_RegisterCustomSounds(cent->npcClient, 3, sEnd);
00465 }
00466 }
00467 else
00468 {
00469 memset(¢->npcClient->extraSounds, 0, sizeof(cent->npcClient->extraSounds));
00470 }
00471
00472
00473 if (cent->currentState.csSounds_Jedi)
00474 {
00475 const char *s = CG_ConfigString( CS_SOUNDS + cent->currentState.csSounds_Jedi );
00476
00477 if (s && s[0])
00478 {
00479 char sEnd[MAX_QPATH];
00480 int i = 2;
00481 int j = 0;
00482
00483
00484
00485 while (s[i])
00486 {
00487 sEnd[j] = s[i];
00488 j++;
00489 i++;
00490 }
00491 sEnd[j] = 0;
00492
00493 CG_RegisterCustomSounds(cent->npcClient, 4, sEnd);
00494 }
00495 }
00496 else
00497 {
00498 memset(¢->npcClient->jediSounds, 0, sizeof(cent->npcClient->jediSounds));
00499 }
00500 }
00501
00502 int CG_HandleAppendedSkin(char *modelName);
00503 void CG_CacheG2AnimInfo(char *modelName);
00504
00505
00506 void SetDuelistHealthsFromConfigString ( const char *str ) {
00507 char buf[64];
00508 int c = 0;
00509 int i = 0;
00510
00511 while (str[i] && str[i] != '|')
00512 {
00513 buf[c] = str[i];
00514 c++;
00515 i++;
00516 }
00517 buf[c] = 0;
00518
00519 cgs.duelist1health = atoi ( buf );
00520
00521 c = 0;
00522 i++;
00523 while (str[i] && str[i] != '|')
00524 {
00525 buf[c] = str[i];
00526 c++;
00527 i++;
00528 }
00529 buf[c] = 0;
00530
00531 cgs.duelist2health = atoi ( buf );
00532
00533 c = 0;
00534 i++;
00535 if ( str[i] == '!' )
00536 {
00537 cgs.duelist3health = -1;
00538 return;
00539 }
00540
00541 while (str[i] && str[i] != '|')
00542 {
00543 buf[c] = str[i];
00544 c++;
00545 i++;
00546 }
00547 buf[c] = 0;
00548
00549 cgs.duelist3health = atoi ( buf );
00550 }
00551
00552
00553
00554
00555
00556
00557
00558 extern int cgSiegeRoundState;
00559 extern int cgSiegeRoundTime;
00560 void CG_ParseSiegeObjectiveStatus(const char *str);
00561 void CG_ParseWeatherEffect(const char *str);
00562 extern void CG_ParseSiegeState(const char *str);
00563 extern int cg_beatingSiegeTime;
00564 extern int cg_siegeWinTeam;
00565 static void CG_ConfigStringModified( void ) {
00566 const char *str;
00567 int num;
00568
00569 num = atoi( CG_Argv( 1 ) );
00570
00571
00572
00573 trap_GetGameState( &cgs.gameState );
00574
00575
00576 str = CG_ConfigString( num );
00577
00578
00579 if ( num == CS_MUSIC ) {
00580 CG_StartMusic( qtrue );
00581 } else if ( num == CS_SERVERINFO ) {
00582 CG_ParseServerinfo();
00583 } else if ( num == CS_WARMUP ) {
00584 CG_ParseWarmup();
00585 } else if ( num == CS_SCORES1 ) {
00586 cgs.scores1 = atoi( str );
00587 } else if ( num == CS_SCORES2 ) {
00588 cgs.scores2 = atoi( str );
00589 } else if ( num == CS_CLIENT_JEDIMASTER ) {
00590 cgs.jediMaster = atoi ( str );
00591 }
00592 else if ( num == CS_CLIENT_DUELWINNER )
00593 {
00594 cgs.duelWinner = atoi ( str );
00595 }
00596 else if ( num == CS_CLIENT_DUELISTS )
00597 {
00598 char buf[64];
00599 int c = 0;
00600 int i = 0;
00601
00602 while (str[i] && str[i] != '|')
00603 {
00604 buf[c] = str[i];
00605 c++;
00606 i++;
00607 }
00608 buf[c] = 0;
00609
00610 cgs.duelist1 = atoi ( buf );
00611 c = 0;
00612
00613 i++;
00614 while (str[i] && str[i] != '|')
00615 {
00616 buf[c] = str[i];
00617 c++;
00618 i++;
00619 }
00620 buf[c] = 0;
00621
00622 cgs.duelist2 = atoi ( buf );
00623
00624 if (str[i])
00625 {
00626 c = 0;
00627 i++;
00628
00629 while (str[i])
00630 {
00631 buf[c] = str[i];
00632 c++;
00633 i++;
00634 }
00635 buf[c] = 0;
00636
00637 cgs.duelist3 = atoi(buf);
00638 }
00639 }
00640 else if ( num == CS_CLIENT_DUELHEALTHS ) {
00641 SetDuelistHealthsFromConfigString(str);
00642 }
00643 else if ( num == CS_LEVEL_START_TIME ) {
00644 cgs.levelStartTime = atoi( str );
00645 } else if ( num == CS_VOTE_TIME ) {
00646 cgs.voteTime = atoi( str );
00647 cgs.voteModified = qtrue;
00648 } else if ( num == CS_VOTE_YES ) {
00649 cgs.voteYes = atoi( str );
00650 cgs.voteModified = qtrue;
00651 } else if ( num == CS_VOTE_NO ) {
00652 cgs.voteNo = atoi( str );
00653 cgs.voteModified = qtrue;
00654 } else if ( num == CS_VOTE_STRING ) {
00655 Q_strncpyz( cgs.voteString, str, sizeof( cgs.voteString ) );
00656 } else if ( num >= CS_TEAMVOTE_TIME && num <= CS_TEAMVOTE_TIME + 1) {
00657 cgs.teamVoteTime[num-CS_TEAMVOTE_TIME] = atoi( str );
00658 cgs.teamVoteModified[num-CS_TEAMVOTE_TIME] = qtrue;
00659 } else if ( num >= CS_TEAMVOTE_YES && num <= CS_TEAMVOTE_YES + 1) {
00660 cgs.teamVoteYes[num-CS_TEAMVOTE_YES] = atoi( str );
00661 cgs.teamVoteModified[num-CS_TEAMVOTE_YES] = qtrue;
00662 } else if ( num >= CS_TEAMVOTE_NO && num <= CS_TEAMVOTE_NO + 1) {
00663 cgs.teamVoteNo[num-CS_TEAMVOTE_NO] = atoi( str );
00664 cgs.teamVoteModified[num-CS_TEAMVOTE_NO] = qtrue;
00665 } else if ( num >= CS_TEAMVOTE_STRING && num <= CS_TEAMVOTE_STRING + 1) {
00666 Q_strncpyz( cgs.teamVoteString[num-CS_TEAMVOTE_STRING], str, sizeof( cgs.teamVoteString ) );
00667 } else if ( num == CS_INTERMISSION ) {
00668 cg.intermissionStarted = atoi( str );
00669 } else if ( num >= CS_MODELS && num < CS_MODELS+MAX_MODELS ) {
00670 char modelName[MAX_QPATH];
00671 strcpy(modelName, str);
00672 if (strstr(modelName, ".glm") || modelName[0] == '$')
00673 {
00674 CG_HandleAppendedSkin(modelName);
00675 CG_CacheG2AnimInfo(modelName);
00676 }
00677
00678 if (modelName[0] != '$' && modelName[0] != '@')
00679 {
00680 cgs.gameModels[ num-CS_MODELS ] = trap_R_RegisterModel( modelName );
00681 }
00682 else
00683 {
00684 cgs.gameModels[ num-CS_MODELS ] = 0;
00685 }
00686
00687
00688
00689
00690
00691
00692
00693 } else if ( num >= CS_SOUNDS && num < CS_SOUNDS+MAX_SOUNDS ) {
00694 if ( str[0] != '*' ) {
00695 cgs.gameSounds[ num-CS_SOUNDS] = trap_S_RegisterSound( str );
00696 }
00697 else if (str[1] == '$')
00698 {
00699 CG_PrecacheNPCSounds(str);
00700 }
00701 } else if ( num >= CS_EFFECTS && num < CS_EFFECTS+MAX_FX ) {
00702 if (str[0] == '*')
00703 {
00704 CG_ParseWeatherEffect(str);
00705 cgs.gameEffects[ num-CS_EFFECTS] = 0;
00706 }
00707 else
00708 {
00709 cgs.gameEffects[ num-CS_EFFECTS] = trap_FX_RegisterEffect( str );
00710 }
00711 }
00712 else if ( num >= CS_SIEGE_STATE && num < CS_SIEGE_STATE+1 )
00713 {
00714 if (str[0])
00715 {
00716 CG_ParseSiegeState(str);
00717 }
00718 }
00719 else if ( num >= CS_SIEGE_WINTEAM && num < CS_SIEGE_WINTEAM+1 )
00720 {
00721 if (str[0])
00722 {
00723 cg_siegeWinTeam = atoi(str);
00724 }
00725 }
00726 else if ( num >= CS_SIEGE_OBJECTIVES && num < CS_SIEGE_OBJECTIVES+1 )
00727 {
00728 CG_ParseSiegeObjectiveStatus(str);
00729 }
00730 else if (num >= CS_SIEGE_TIMEOVERRIDE && num < CS_SIEGE_TIMEOVERRIDE+1)
00731 {
00732 cg_beatingSiegeTime = atoi(str);
00733 CG_SetSiegeTimerCvar ( cg_beatingSiegeTime );
00734 }
00735 else if ( num >= CS_PLAYERS && num < CS_PLAYERS+MAX_CLIENTS )
00736 {
00737 CG_NewClientInfo( num - CS_PLAYERS, qtrue);
00738 CG_BuildSpectatorString();
00739 } else if ( num == CS_FLAGSTATUS ) {
00740 if( cgs.gametype == GT_CTF || cgs.gametype == GT_CTY ) {
00741
00742 cgs.redflag = str[0] - '0';
00743 cgs.blueflag = str[1] - '0';
00744 }
00745 }
00746 else if ( num == CS_SHADERSTATE ) {
00747 CG_ShaderStateChanged();
00748 }
00749 else if ( num >= CS_LIGHT_STYLES && num < CS_LIGHT_STYLES + (MAX_LIGHT_STYLES * 3))
00750 {
00751 CG_SetLightstyle(num - CS_LIGHT_STYLES);
00752 }
00753
00754 }
00755
00756
00757 void CG_KillCEntityG2(int entNum)
00758 {
00759 int j;
00760 clientInfo_t *ci = NULL;
00761 centity_t *cent = &cg_entities[entNum];
00762
00763 if (entNum < MAX_CLIENTS)
00764 {
00765 ci = &cgs.clientinfo[entNum];
00766 }
00767 else
00768 {
00769 ci = cent->npcClient;
00770 }
00771
00772 if (ci)
00773 {
00774 if (ci == cent->npcClient)
00775 {
00776 ci->ghoul2Model = NULL;
00777 }
00778 else if (ci->ghoul2Model == cent->ghoul2)
00779 {
00780 ci->ghoul2Model = NULL;
00781 }
00782 else if (ci->ghoul2Model && trap_G2_HaveWeGhoul2Models(ci->ghoul2Model))
00783 {
00784 trap_G2API_CleanGhoul2Models(&ci->ghoul2Model);
00785 ci->ghoul2Model = NULL;
00786 }
00787
00788
00789 j = 0;
00790 while (j < MAX_SABERS)
00791 {
00792 if (ci->ghoul2Weapons[j] && trap_G2_HaveWeGhoul2Models(ci->ghoul2Weapons[j]))
00793 {
00794 trap_G2API_CleanGhoul2Models(&ci->ghoul2Weapons[j]);
00795 ci->ghoul2Weapons[j] = NULL;
00796 }
00797
00798 j++;
00799 }
00800 }
00801
00802 if (cent->ghoul2 && trap_G2_HaveWeGhoul2Models(cent->ghoul2))
00803 {
00804 trap_G2API_CleanGhoul2Models(¢->ghoul2);
00805 cent->ghoul2 = NULL;
00806 }
00807
00808 if (cent->grip_arm && trap_G2_HaveWeGhoul2Models(cent->grip_arm))
00809 {
00810 trap_G2API_CleanGhoul2Models(¢->grip_arm);
00811 cent->grip_arm = NULL;
00812 }
00813
00814 if (cent->frame_hold && trap_G2_HaveWeGhoul2Models(cent->frame_hold))
00815 {
00816 trap_G2API_CleanGhoul2Models(¢->frame_hold);
00817 cent->frame_hold = NULL;
00818 }
00819
00820 if (cent->npcClient)
00821 {
00822 CG_DestroyNPCClient(¢->npcClient);
00823 }
00824
00825 cent->isRagging = qfalse;
00826 cent->ikStatus = qfalse;
00827
00828 cent->localAnimIndex = 0;
00829 }
00830
00831 void CG_KillCEntityInstances(void)
00832 {
00833 int i = 0;
00834 centity_t *cent;
00835
00836 while (i < MAX_GENTITIES)
00837 {
00838 cent = &cg_entities[i];
00839
00840 if (i >= MAX_CLIENTS && cent->currentState.number == i)
00841 {
00842 CG_KillCEntityG2(i);
00843 }
00844
00845 cent->bolt1 = 0;
00846 cent->bolt2 = 0;
00847 cent->bolt3 = 0;
00848 cent->bolt4 = 0;
00849
00850 cent->bodyHeight = 0;
00851
00852
00853 cent->boltInfo = 0;
00854
00855 cent->frame_minus1_refreshed = 0;
00856 cent->frame_minus2_refreshed = 0;
00857 cent->dustTrailTime = 0;
00858 cent->ghoul2weapon = NULL;
00859
00860 cent->trailTime = 0;
00861 cent->frame_hold_time = 0;
00862 cent->frame_hold_refreshed = 0;
00863 cent->trickAlpha = 0;
00864 cent->trickAlphaTime = 0;
00865 VectorClear(cent->turAngles);
00866 cent->weapon = 0;
00867 cent->teamPowerEffectTime = 0;
00868 cent->teamPowerType = 0;
00869 cent->numLoopingSounds = 0;
00870
00871 cent->localAnimIndex = 0;
00872
00873 i++;
00874 }
00875 }
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888 static void CG_MapRestart( void ) {
00889 if ( cg_showmiss.integer ) {
00890 CG_Printf( "CG_MapRestart\n" );
00891 }
00892
00893 trap_R_ClearDecals ( );
00894
00895
00896 CG_InitLocalEntities();
00897 CG_InitMarkPolys();
00898 CG_ClearParticles ();
00899 CG_KillCEntityInstances();
00900
00901
00902 cg.fraglimitWarnings = 0;
00903
00904 cg.timelimitWarnings = 0;
00905
00906 cg.intermissionStarted = qfalse;
00907
00908 cgs.voteTime = 0;
00909
00910 cg.mapRestart = qtrue;
00911
00912 CG_StartMusic(qtrue);
00913
00914 trap_S_ClearLoopingSounds();
00915
00916
00917
00918
00919 if ( cg.warmup == 0 && cgs.gametype != GT_SIEGE && cgs.gametype != GT_POWERDUEL) {
00920 trap_S_StartLocalSound( cgs.media.countFightSound, CHAN_ANNOUNCER );
00921 CG_CenterPrint( CG_GetStringEdString("MP_SVGAME", "BEGIN_DUEL"), 120, GIANTCHAR_WIDTH*2 );
00922 }
00923
00924
00925
00926
00927
00928
00929
00930
00931 trap_Cvar_Set("cg_thirdPerson", "0");
00932 }
00933
00934
00935
00936
00937
00938
00939 static void CG_RemoveChatEscapeChar( char *text ) {
00940 int i, l;
00941
00942 l = 0;
00943 for ( i = 0; text[i]; i++ ) {
00944 if (text[i] == '\x19')
00945 continue;
00946 text[l++] = text[i];
00947 }
00948 text[l] = '\0';
00949 }
00950
00951 #define MAX_STRINGED_SV_STRING 1024 // this is an quake-engine limit, not a StringEd limit
00952
00953 void CG_CheckSVStringEdRef(char *buf, const char *str)
00954 {
00955 int i = 0;
00956 int b = 0;
00957 int strLen = 0;
00958 qboolean gotStrip = qfalse;
00959
00960 if (!str || !str[0])
00961 {
00962 if (str)
00963 {
00964 strcpy(buf, str);
00965 }
00966 return;
00967 }
00968
00969 strcpy(buf, str);
00970
00971 strLen = strlen(str);
00972
00973 if (strLen >= MAX_STRINGED_SV_STRING)
00974 {
00975 return;
00976 }
00977
00978 while (i < strLen && str[i])
00979 {
00980 gotStrip = qfalse;
00981
00982 if (str[i] == '@' && (i+1) < strLen)
00983 {
00984 if (str[i+1] == '@' && (i+2) < strLen)
00985 {
00986 if (str[i+2] == '@' && (i+3) < strLen)
00987 {
00988 char stringRef[MAX_STRINGED_SV_STRING];
00989 int r = 0;
00990
00991 while (i < strLen && str[i] == '@')
00992 {
00993 i++;
00994 }
00995
00996 while (i < strLen && str[i] && str[i] != ' ' && str[i] != ':' && str[i] != '.' && str[i] != '\n')
00997 {
00998 stringRef[r] = str[i];
00999 r++;
01000 i++;
01001 }
01002 stringRef[r] = 0;
01003
01004 buf[b] = 0;
01005 Q_strcat(buf, MAX_STRINGED_SV_STRING, CG_GetStringEdString("MP_SVGAME", stringRef));
01006 b = strlen(buf);
01007 }
01008 }
01009 }
01010
01011 if (!gotStrip)
01012 {
01013 buf[b] = str[i];
01014 b++;
01015 }
01016 i++;
01017 }
01018
01019 buf[b] = 0;
01020 }
01021
01022 static void CG_BodyQueueCopy(centity_t *cent, int clientNum, int knownWeapon)
01023 {
01024 centity_t *source;
01025 animation_t *anim;
01026 float animSpeed;
01027 int flags=BONE_ANIM_OVERRIDE_FREEZE;
01028 clientInfo_t *ci;
01029
01030 if (cent->ghoul2)
01031 {
01032 trap_G2API_CleanGhoul2Models(¢->ghoul2);
01033 }
01034
01035 if (clientNum < 0 || clientNum >= MAX_CLIENTS)
01036 {
01037 return;
01038 }
01039
01040 source = &cg_entities[ clientNum ];
01041 ci = &cgs.clientinfo[ clientNum ];
01042
01043 if (!source)
01044 {
01045 return;
01046 }
01047
01048 if (!source->ghoul2)
01049 {
01050 return;
01051 }
01052
01053 cent->isRagging = qfalse;
01054 cent->ownerRagging = source->isRagging;
01055
01056 #if 0
01057 VectorCopy(source->lerpOriginOffset, cent->lerpOriginOffset);
01058 #endif
01059
01060 cent->bodyFadeTime = 0;
01061 cent->bodyHeight = 0;
01062
01063 cent->dustTrailTime = source->dustTrailTime;
01064
01065 trap_G2API_DuplicateGhoul2Instance(source->ghoul2, ¢->ghoul2);
01066
01067 if (source->isRagging)
01068 {
01069 source->isRagging = qfalse;
01070 trap_G2API_SetRagDoll(source->ghoul2, NULL);
01071 }
01072
01073
01074 if (knownWeapon > WP_BRYAR_PISTOL && trap_G2API_HasGhoul2ModelOnIndex(&(cent->ghoul2), 1))
01075 {
01076 trap_G2API_RemoveGhoul2Model(&(cent->ghoul2), 1);
01077 }
01078 else if (trap_G2API_HasGhoul2ModelOnIndex(&(cent->ghoul2), 1))
01079 {
01080 trap_G2API_CopySpecificGhoul2Model(CG_G2WeaponInstance(cent, knownWeapon), 0, cent->ghoul2, 1);
01081 }
01082
01083 if (!cent->ownerRagging)
01084 {
01085 int aNum;
01086 int eFrame;
01087 qboolean fallBack = qfalse;
01088
01089
01090 if (!BG_InDeathAnim(source->currentState.torsoAnim))
01091 {
01092 anim = &bgAllAnims[source->localAnimIndex].anims[ BOTH_DEAD1 ];
01093 fallBack = qtrue;
01094 }
01095 else
01096 {
01097 anim = &bgAllAnims[source->localAnimIndex].anims[ source->currentState.torsoAnim ];
01098 }
01099 animSpeed = 50.0f / anim->frameLerp;
01100
01101 if (!fallBack)
01102 {
01103
01104 aNum = cgs.clientinfo[source->currentState.number].frame+1;
01105
01106 while (aNum >= anim->firstFrame+anim->numFrames)
01107 {
01108 aNum--;
01109 }
01110
01111 if (aNum < anim->firstFrame-1)
01112 {
01113 aNum = (anim->firstFrame+anim->numFrames)-1;
01114 }
01115 }
01116 else
01117 {
01118 aNum = anim->firstFrame;
01119 }
01120
01121 eFrame = anim->firstFrame + anim->numFrames;
01122
01123
01124
01125
01126
01127
01128 trap_G2API_SetBoneAnim(cent->ghoul2, 0, "upper_lumbar", aNum, eFrame, flags, animSpeed, cg.time, -1, 150);
01129 trap_G2API_SetBoneAnim(cent->ghoul2, 0, "model_root", aNum, eFrame, flags, animSpeed, cg.time, -1, 150);
01130 trap_G2API_SetBoneAnim(cent->ghoul2, 0, "Motion", aNum, eFrame, flags, animSpeed, cg.time, -1, 150);
01131 }
01132
01133
01134 if (source->torsoBolt)
01135 {
01136 CG_ReattachLimb(source);
01137 }
01138 }
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148 void CG_SiegeBriefingDisplay(int team, int dontshow);
01149 void CG_ParseSiegeExtendedData(void);
01150 extern void CG_ChatBox_AddString(char *chatStr);
01151 static void CG_ServerCommand( void ) {
01152 const char *cmd;
01153 char text[MAX_SAY_TEXT];
01154 qboolean IRCG = qfalse;
01155
01156 cmd = CG_Argv(0);
01157
01158 if ( !cmd[0] ) {
01159
01160 return;
01161 }
01162
01163 #if 0
01164
01165 if ( !strcmp( cmd, "spd" ) )
01166 {
01167 const char *ID;
01168 int holdInt,count,i;
01169 char string[1204];
01170
01171 count = trap_Argc();
01172
01173 ID = CG_Argv(1);
01174 holdInt = atoi(ID);
01175
01176 memset( &string, 0, sizeof( string ) );
01177
01178 Com_sprintf( string,sizeof(string)," \"%s\"", (const char *) CG_Argv(2));
01179
01180 for (i=3;i<count;i++)
01181 {
01182 Com_sprintf( string,sizeof(string)," %s \"%s\"", string, (const char *) CG_Argv(i));
01183 }
01184
01185 trap_SP_Print(holdInt, (byte *)string);
01186 return;
01187 }
01188 #endif
01189
01190 if (!strcmp(cmd, "sxd"))
01191 {
01192 CG_ParseSiegeExtendedData();
01193 return;
01194 }
01195
01196 if (!strcmp(cmd, "sb"))
01197 {
01198 CG_SiegeBriefingDisplay(atoi(CG_Argv(1)), 0);
01199 return;
01200 }
01201
01202 if ( !strcmp( cmd, "scl" ) )
01203 {
01204
01205
01206 {
01207 trap_OpenUIMenu(UIMENU_CLASSSEL);
01208 }
01209 return;
01210 }
01211
01212 if ( !strcmp( cmd, "spc" ) )
01213 {
01214 trap_Cvar_Set("ui_myteam", "3");
01215 trap_OpenUIMenu(UIMENU_PLAYERCONFIG);
01216 return;
01217 }
01218
01219 if ( !strcmp( cmd, "nfr" ) )
01220 {
01221 int doMenu = 0;
01222 int setTeam = 0;
01223 int newRank = 0;
01224
01225 if (trap_Argc() < 3)
01226 {
01227 #ifdef _DEBUG
01228 Com_Printf("WARNING: Invalid newForceRank string\n");
01229 #endif
01230 return;
01231 }
01232
01233 newRank = atoi(CG_Argv(1));
01234 doMenu = atoi(CG_Argv(2));
01235 setTeam = atoi(CG_Argv(3));
01236
01237 trap_Cvar_Set("ui_rankChange", va("%i", newRank));
01238
01239 trap_Cvar_Set("ui_myteam", va("%i", setTeam));
01240
01241 if (!( trap_Key_GetCatcher() & KEYCATCH_UI ) && doMenu)
01242 {
01243 trap_OpenUIMenu(UIMENU_PLAYERCONFIG);
01244 }
01245
01246 return;
01247 }
01248
01249 if ( !strcmp( cmd, "kg2" ) )
01250 {
01251
01252
01253 int indexNum = 0;
01254 int argNum = trap_Argc();
01255 int i = 1;
01256
01257 if (argNum < 1)
01258 {
01259 return;
01260 }
01261
01262 while (i < argNum)
01263 {
01264 indexNum = atoi(CG_Argv(i));
01265
01266 if (cg_entities[indexNum].ghoul2 && trap_G2_HaveWeGhoul2Models(cg_entities[indexNum].ghoul2))
01267 {
01268 if (indexNum < MAX_CLIENTS)
01269 {
01270 #ifdef _DEBUG
01271 Com_Printf("WARNING: Tried to kill a client ghoul2 instance with a kg2 command!\n");
01272 #endif
01273 return;
01274 }
01275
01276 CG_KillCEntityG2(indexNum);
01277 }
01278
01279 i++;
01280 }
01281
01282 return;
01283 }
01284
01285 if (!strcmp(cmd, "kls"))
01286 {
01287 int indexNum = 0;
01288 int argNum = trap_Argc();
01289 centity_t *clent = NULL;
01290 centity_t *trackerent = NULL;
01291
01292 if (argNum < 1)
01293 {
01294 assert(0);
01295 return;
01296 }
01297
01298 indexNum = atoi(CG_Argv(1));
01299
01300 if (indexNum != -1)
01301 {
01302 clent = &cg_entities[indexNum];
01303 }
01304
01305 if (argNum >= 2)
01306 {
01307 indexNum = atoi(CG_Argv(2));
01308
01309 if (indexNum != -1)
01310 {
01311 trackerent = &cg_entities[indexNum];
01312 }
01313 }
01314
01315 if (clent)
01316 {
01317 CG_S_StopLoopingSound(clent->currentState.number, -1);
01318 }
01319 if (trackerent)
01320 {
01321 CG_S_StopLoopingSound(trackerent->currentState.number, -1);
01322 }
01323
01324 return;
01325 }
01326
01327 if (!strcmp(cmd, "ircg"))
01328 {
01329 IRCG = qtrue;
01330 }
01331
01332 if (!strcmp(cmd, "rcg") || IRCG)
01333 {
01334 int indexNum = 0;
01335 int argNum = trap_Argc();
01336 centity_t *clent;
01337
01338 if (argNum < 1)
01339 {
01340 assert(0);
01341 return;
01342 }
01343
01344 indexNum = atoi(CG_Argv(1));
01345 if (indexNum < 0 || indexNum >= MAX_CLIENTS)
01346 {
01347 assert(0);
01348 return;
01349 }
01350
01351 clent = &cg_entities[indexNum];
01352
01353
01354 if (!clent->ghoul2)
01355 {
01356 return;
01357 }
01358
01359 #ifdef _DEBUG
01360 if (!