#include "g_local.h"#include "../ghoul2/G2.h"#include "bg_saga.h"#include "../namespace_begin.h"#include "../namespace_end.h"Go to the source code of this file.
|
|
Definition at line 946 of file g_client.c. Referenced by BodySink(). |
|
|
Definition at line 256 of file g_client.c. Referenced by JMSaberThink(), and JMSaberTouch(). |
|
|
Definition at line 621 of file g_client.c. |
|
|
Definition at line 621 of file g_client.c. Referenced by SelectRandomDeathmatchSpawnPoint(). |
|
|
Definition at line 1599 of file bg_vehicleLoad.c. References BG_VehicleGetIndex(), Com_Error(), ERR_DROP, g_vehicleInfo, strcpy(), and VEHICLE_NONE. Referenced by CG_CacheG2AnimInfo(), CG_G2AnimEntModelLoad(), and SetupGameGhoul2Model().
01600 {
01601 char *vehName = &modelname[1];
01602 int vIndex = BG_VehicleGetIndex(vehName);
01603 assert(modelname[0] == '$');
01604
01605 if (vIndex == VEHICLE_NONE)
01606 {
01607 Com_Error(ERR_DROP, "BG_GetVehicleModelName: couldn't find vehicle %s", vehName);
01608 }
01609
01610 strcpy(modelname, g_vehicleInfo[vIndex].model);
01611 }
|
|
||||||||||||
|
Definition at line 2744 of file bg_misc.c. References Q_stricmp(), qboolean, qfalse, and qtrue. Referenced by BG_ValidateSkinForTeam(), and SetupGameGhoul2Model().
02745 {
02746 if (!Q_stricmp(skinName, "menu"))
02747 {
02748 return qfalse;
02749 }
02750 else if (!Q_stricmp(modelName, "kyle"))
02751 {
02752 if (!Q_stricmp(skinName, "fpls"))
02753 {
02754 return qfalse;
02755 }
02756 else if (!Q_stricmp(skinName, "fpls2"))
02757 {
02758 return qfalse;
02759 }
02760 else if (!Q_stricmp(skinName, "fpls3"))
02761 {
02762 return qfalse;
02763 }
02764 }
02765 return qtrue;
02766 }
|
|
|
Definition at line 33 of file bg_panimate.c. References BOTH_SABERDUAL_STANCE, BOTH_SABERFAST_STANCE, BOTH_SABERSLOW_STANCE, BOTH_SABERSTAFF_STANCE, BOTH_STAND1, BOTH_STAND2, qboolean, qfalse, and qtrue. Referenced by G_UpdateClientAnims().
00034 {
00035 switch ( anim )
00036 {
00037 case BOTH_STAND1://not really a saberstance anim, actually... "saber off" stance
00038 case BOTH_STAND2://single-saber, medium style
00039 case BOTH_SABERFAST_STANCE://single-saber, fast style
00040 case BOTH_SABERSLOW_STANCE://single-saber, strong style
00041 case BOTH_SABERSTAFF_STANCE://saber staff style
00042 case BOTH_SABERDUAL_STANCE://dual saber style
00043 return qtrue;
00044 break;
00045 }
00046 return qfalse;
00047 }
|
|
||||||||||||||||||||
|
Definition at line 2768 of file bg_misc.c. References BG_FileExists(), BG_IsValidCharacterModel(), MAX_QPATH, Q_strcat(), Q_stricmp(), Q_stricmpn(), Q_strncmp(), Q_strncpyz(), qboolean, qfalse, qtrue, strchr(), strlen(), TEAM_BLUE, TEAM_RED, and va(). Referenced by CG_NewClientInfo(), and SetupGameGhoul2Model().
02769 {
02770 if (!Q_stricmpn(modelName, "jedi_",5))
02771 { //argh, it's a custom player skin!
02772 if (team == TEAM_RED && colors)
02773 {
02774 colors[0] = 1.0f;
02775 colors[1] = 0.0f;
02776 colors[2] = 0.0f;
02777 }
02778 else if (team == TEAM_BLUE && colors)
02779 {
02780 colors[0] = 0.0f;
02781 colors[1] = 0.0f;
02782 colors[2] = 1.0f;
02783 }
02784 return qtrue;
02785 }
02786
02787 if (team == TEAM_RED)
02788 {
02789 if ( Q_stricmp( "red", skinName ) != 0 )
02790 {//not "red"
02791 if ( Q_stricmp( "blue", skinName ) == 0
02792 || Q_stricmp( "default", skinName ) == 0
02793 || strchr(skinName, '|')//a multi-skin playerModel
02794 || !BG_IsValidCharacterModel(modelName, skinName) )
02795 {
02796 Q_strncpyz(skinName, "red", MAX_QPATH);
02797 return qfalse;
02798 }
02799 else
02800 {//need to set it to red
02801 int len = strlen( skinName );
02802 if ( len < 3 )
02803 {//too short to be "red"
02804 Q_strcat(skinName, MAX_QPATH, "_red");
02805 }
02806 else
02807 {
02808 char *start = &skinName[len-3];
02809 if ( Q_strncmp( "red", start, 3 ) != 0 )
02810 {//doesn't already end in "red"
02811 if ( len+4 >= MAX_QPATH )
02812 {//too big to append "_red"
02813 Q_strncpyz(skinName, "red", MAX_QPATH);
02814 return qfalse;
02815 }
02816 else
02817 {
02818 Q_strcat(skinName, MAX_QPATH, "_red");
02819 }
02820 }
02821 }
02822 //if file does not exist, set to "red"
02823 if ( !BG_FileExists( va( "models/players/%s/model_%s.skin", modelName, skinName ) ) )
02824 {
02825 Q_strncpyz(skinName, "red", MAX_QPATH);
02826 }
02827 return qfalse;
02828 }
02829 }
02830
02831 }
02832 else if (team == TEAM_BLUE)
02833 {
02834 if ( Q_stricmp( "blue", skinName ) != 0 )
02835 {
02836 if ( Q_stricmp( "red", skinName ) == 0
02837 || Q_stricmp( "default", skinName ) == 0
02838 || strchr(skinName, '|')//a multi-skin playerModel
02839 || !BG_IsValidCharacterModel(modelName, skinName) )
02840 {
02841 Q_strncpyz(skinName, "blue", MAX_QPATH);
02842 return qfalse;
02843 }
02844 else
02845 {//need to set it to blue
02846 int len = strlen( skinName );
02847 if ( len < 4 )
02848 {//too short to be "blue"
02849 Q_strcat(skinName, MAX_QPATH, "_blue");
02850 }
02851 else
02852 {
02853 char *start = &skinName[len-4];
02854 if ( Q_strncmp( "blue", start, 4 ) != 0 )
02855 {//doesn't already end in "blue"
02856 if ( len+5 >= MAX_QPATH )
02857 {//too big to append "_blue"
02858 Q_strncpyz(skinName, "blue", MAX_QPATH);
02859 return qfalse;
02860 }
02861 else
02862 {
02863 Q_strcat(skinName, MAX_QPATH, "_blue");
02864 }
02865 }
02866 }
02867 //if file does not exist, set to "blue"
02868 if ( !BG_FileExists( va( "models/players/%s/model_%s.skin", modelName, skinName ) ) )
02869 {
02870 Q_strncpyz(skinName, "blue", MAX_QPATH);
02871 }
02872 return qfalse;
02873 }
02874 }
02875 }
02876 return qtrue;
02877 }
|
|
|
Definition at line 973 of file g_client.c. References BODY_SINK_TIME, EV_BODYFADE, G_AddEvent(), gentity_t, level, gentity_s::nextthink, gentity_s::physicsObject, qfalse, gentity_s::takedamage, level_locals_t::time, gentity_s::timestamp, and trap_UnlinkEntity().
00973 {
00974 if ( level.time - ent->timestamp > BODY_SINK_TIME + 2500 ) {
00975 // the body ques are never actually freed, they are just unlinked
00976 trap_UnlinkEntity( ent );
00977 ent->physicsObject = qfalse;
00978 return;
00979 }
00980 // ent->nextthink = level.time + 100;
00981 // ent->s.pos.trBase[2] -= 1;
00982
00983 G_AddEvent(ent, EV_BODYFADE, 0);
00984 ent->nextthink = level.time + 18000;
00985 ent->takedamage = qfalse;
00986 }
|
|
||||||||||||
|
Definition at line 2385 of file g_client.c. References CalculateRanks(), CHAN_VOICE, client, gentity_s::client, entityState_s::clientNum, level_locals_t::clients, ClientSpawn(), ClientUserinfoChanged(), CON_CONNECTED, clientPersistant_t::connected, clientSession_t::duelTeam, DUELTEAM_FREE, playerState_s::eFlags, clientPersistant_t::enterTime, EV_PLAYER_TELEPORT_IN, playerState_s::fd, forcedata_s::forcePowersActive, G_ClearClientLog(), g_entities, g_gametype, G_GetStringEdString(), G_InitGentity(), G_LogPrintf(), G_MuteSound(), G_ReadSessionData(), G_SetSaber(), G_TempEntity(), G_WriteClientSessionData(), gclient_t, gentity_t, gentity_s::ghoul2, gSiegeRoundBegun, gSiegeRoundEnded, GT_DUEL, GT_POWERDUEL, GT_SIEGE, GT_TEAM, playerState_s::hasDetPackPlanted, Info_SetValueForKey(), Info_ValueForKey(), vmCvar_t::integer, forcedata_s::killSoundEntIndex, renderInfo_s::lastG2, level, entityShared_t::linked, MAX_GENTITIES, MAX_INFO_STRING, MAX_INFO_VALUE, memset(), clientPersistant_t::netname, NULL, NUM_FORCE_POWERS, NUM_TRACK_CHANNELS, playerState_s::origin, gentity_s::pain, gclient_s::pers, PERS_TEAM, playerState_s::persistant, PickTeam(), gentity_s::playerState, gclient_s::ps, qfalse, gentity_s::r, rand(), gclient_s::renderInfo, gentity_s::s, S_COLOR_WHITE, gclient_s::sess, clientSession_t::sessionTeam, SetTeam(), SetTeamQuick(), SetupGameGhoul2Model(), playerTeamState_t::state, strcpy(), SVF_BOT, entityShared_t::svFlags, TEAM_BEGIN, TEAM_RED, TEAM_SPECTATOR, clientPersistant_t::teamState, level_locals_t::time, gentity_s::touch, TRACK_CHANNEL_1, trap_GetUserinfo(), trap_SendServerCommand(), trap_SetUserinfo(), trap_UnlinkEntity(), va(), WP_ForcePowerStop(), WP_InitForcePowers(), and WP_SaberInitBladeData(). Referenced by Cmd_SiegeClass_f(), G_CheckBotSpawn(), SetTeam(), SetTeamQuick(), SpectatorClientEndFrame(), and vmMain().
02385 {
02386 gentity_t *ent;
02387 gclient_t *client;
02388 gentity_t *tent;
02389 int flags, i;
02390 char userinfo[MAX_INFO_VALUE], *modelname;
02391
02392 ent = g_entities + clientNum;
02393
02394 if ((ent->r.svFlags & SVF_BOT) && g_gametype.integer >= GT_TEAM)
02395 {
02396 if (allowTeamReset)
02397 {
02398 const char *team = "Red";
02399 int preSess;
02400
02401 //SetTeam(ent, "");
02402 ent->client->sess.sessionTeam = PickTeam(-1);
02403 trap_GetUserinfo(clientNum, userinfo, MAX_INFO_STRING);
02404
02405 if (ent->client->sess.sessionTeam == TEAM_SPECTATOR)
02406 {
02407 ent->client->sess.sessionTeam = TEAM_RED;
02408 }
02409
02410 if (ent->client->sess.sessionTeam == TEAM_RED)
02411 {
02412 team = "Red";
02413 }
02414 else
02415 {
02416 team = "Blue";
02417 }
02418
02419 Info_SetValueForKey( userinfo, "team", team );
02420
02421 trap_SetUserinfo( clientNum, userinfo );
02422
02423 ent->client->ps.persistant[ PERS_TEAM ] = ent->client->sess.sessionTeam;
02424
02425 preSess = ent->client->sess.sessionTeam;
02426 G_ReadSessionData( ent->client );
02427 ent->client->sess.sessionTeam = preSess;
02428 G_WriteClientSessionData(ent->client);
02429 ClientUserinfoChanged( clientNum );
02430 ClientBegin(clientNum, qfalse);
02431 return;
02432 }
02433 }
02434
02435 client = level.clients + clientNum;
02436
02437 if ( ent->r.linked ) {
02438 trap_UnlinkEntity( ent );
02439 }
02440 G_InitGentity( ent );
02441 ent->touch = 0;
02442 ent->pain = 0;
02443 ent->client = client;
02444
02445 //assign the pointer for bg entity access
02446 ent->playerState = &ent->client->ps;
02447
02448 client->pers.connected = CON_CONNECTED;
02449 client->pers.enterTime = level.time;
02450 client->pers.teamState.state = TEAM_BEGIN;
02451
02452 // save eflags around this, because changing teams will
02453 // cause this to happen with a valid entity, and we
02454 // want to make sure the teleport bit is set right
02455 // so the viewpoint doesn't interpolate through the
02456 // world to the new position
02457 flags = client->ps.eFlags;
02458
02459 i = 0;
02460
02461 while (i < NUM_FORCE_POWERS)
02462 {
02463 if (ent->client->ps.fd.forcePowersActive & (1 << i))
02464 {
02465 WP_ForcePowerStop(ent, i);
02466 }
02467 i++;
02468 }
02469
02470 i = TRACK_CHANNEL_1;
02471
02472 while (i < NUM_TRACK_CHANNELS)
02473 {
02474 if (ent->client->ps.fd.killSoundEntIndex[i-50] && ent->client->ps.fd.killSoundEntIndex[i-50] < MAX_GENTITIES && ent->client->ps.fd.killSoundEntIndex[i-50] > 0)
02475 {
02476 G_MuteSound(ent->client->ps.fd.killSoundEntIndex[i-50], CHAN_VOICE);
02477 }
02478 i++;
02479 }
02480 i = 0;
02481
02482 memset( &client->ps, 0, sizeof( client->ps ) );
02483 client->ps.eFlags = flags;
02484
02485 client->ps.hasDetPackPlanted = qfalse;
02486
02487 //first-time force power initialization
02488 WP_InitForcePowers( ent );
02489
02490 //init saber ent
02491 WP_SaberInitBladeData( ent );
02492
02493 // First time model setup for that player.
02494 trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) );
02495 modelname = Info_ValueForKey (userinfo, "model");
02496 SetupGameGhoul2Model(ent, modelname, NULL);
02497
02498 if (ent->ghoul2 && ent->client)
02499 {
02500 ent->client->renderInfo.lastG2 = NULL; //update the renderinfo bolts next update.
02501 }
02502
02503 if (g_gametype.integer == GT_POWERDUEL && client->sess.sessionTeam != TEAM_SPECTATOR &&
02504 client->sess.duelTeam == DUELTEAM_FREE)
02505 {
02506 SetTeam(ent, "s");
02507 }
02508 else
02509 {
02510 if (g_gametype.integer == GT_SIEGE && (!gSiegeRoundBegun || gSiegeRoundEnded))
02511 {
02512 SetTeamQuick(ent, TEAM_SPECTATOR, qfalse);
02513 }
02514
02515 if ((ent->r.svFlags & SVF_BOT) &&
02516 g_gametype.integer != GT_SIEGE)
02517 {
02518 char *saberVal = Info_ValueForKey(userinfo, "saber1");
02519 char *saber2Val = Info_ValueForKey(userinfo, "saber2");
02520
02521 if (!saberVal || !saberVal[0])
02522 { //blah, set em up with a random saber
02523 int r = rand()%50;
02524 char sab1[1024];
02525 char sab2[1024];
02526
02527 if (r <= 17)
02528 {
02529 strcpy(sab1, "Katarn");
02530 strcpy(sab2, "none");
02531 }
02532 else if (r <= 34)
02533 {
02534 strcpy(sab1, "Katarn");
02535 strcpy(sab2, "Katarn");
02536 }
02537 else
02538 {
02539 strcpy(sab1, "dual_1");
02540 strcpy(sab2, "none");
02541 }
02542 G_SetSaber(ent, 0, sab1, qfalse);
02543 G_SetSaber(ent, 0, sab2, qfalse);
02544 Info_SetValueForKey( userinfo, "saber1", sab1 );
02545 Info_SetValueForKey( userinfo, "saber2", sab2 );
02546 trap_SetUserinfo( clientNum, userinfo );
02547 }
02548 else
02549 {
02550 G_SetSaber(ent, 0, saberVal, qfalse);
02551 }
02552
02553 if (saberVal && saberVal[0] &&
02554 (!saber2Val || !saber2Val[0]))
02555 {
02556 G_SetSaber(ent, 0, "none", qfalse);
02557 Info_SetValueForKey( userinfo, "saber2", "none" );
02558 trap_SetUserinfo( clientNum, userinfo );
02559 }
02560 else
02561 {
02562 G_SetSaber(ent, 0, saber2Val, qfalse);
02563 }
02564 }
02565
02566 // locate ent at a spawn point
02567 ClientSpawn( ent );
02568 }
02569
02570 if ( client->sess.sessionTeam != TEAM_SPECTATOR ) {
02571 // send event
02572 tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_IN );
02573 tent->s.clientNum = ent->s.clientNum;
02574
02575 if ( g_gametype.integer != GT_DUEL || g_gametype.integer == GT_POWERDUEL ) {
02576 trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " %s\n\"", client->pers.netname, G_GetStringEdString("MP_SVGAME", "PLENTER")) );
02577 }
02578 }
02579 G_LogPrintf( "ClientBegin: %i\n", clientNum );
02580
02581 // count current clients and rank for scoreboard
02582 CalculateRanks();
02583
02584 G_ClearClientLog(clientNum);
02585 }
|
|
||||||||||||||||
|
Definition at line 2258 of file g_client.c. References BroadcastTeamChange(), CalculateRanks(), client, gentity_s::client, level_locals_t::clients, ClientUserinfoChanged(), CON_CONNECTING, clientPersistant_t::connected, EV_CLIENTJOIN, entityState_s::eventParm, G_BotConnect(), g_entities, G_FilterPacket(), g_gametype, G_GetStringEdString(), G_InitSessionData(), G_LogPrintf(), g_needpass, g_password, G_ReadSessionData(), G_TempEntity(), gclient_t, gentity_t, GT_POWERDUEL, GT_SIEGE, GT_TEAM, Info_ValueForKey(), vmCvar_t::integer, gentity_s::inuse, level, MAX_INFO_STRING, memset(), clientPersistant_t::netname, level_locals_t::newSession, NULL, gclient_s::pers, gentity_s::playerState, gclient_s::ps, Q_stricmp(), Q_strncpyz(), qtrue, gentity_s::r, gentity_s::s, S_COLOR_WHITE, gclient_s::sess, clientSession_t::sessionTeam, clientSession_t::siegeDesiredTeam, strcmp(), vmCvar_t::string, SVF_BOT, SVF_BROADCAST, entityShared_t::svFlags, TEAM_SPECTATOR, trap_GetUserinfo(), trap_SendServerCommand(), va(), and vec3_origin. Referenced by vmMain().
02258 {
02259 char *value;
02260 // char *areabits;
02261 gclient_t *client;
02262 char userinfo[MAX_INFO_STRING];
02263 gentity_t *ent;
02264 gentity_t *te;
02265
02266 ent = &g_entities[ clientNum ];
02267
02268 trap_GetUserinfo( clientNum, userinfo, sizeof( userinfo ) );
02269
02270 // check to see if they are on the banned IP list
02271 value = Info_ValueForKey (userinfo, "ip");
02272 if ( G_FilterPacket( value ) ) {
02273 return "Banned.";
02274 }
02275
02276 if ( !( ent->r.svFlags & SVF_BOT ) && !isBot && g_needpass.integer ) {
02277 // check for a password
02278 value = Info_ValueForKey (userinfo, "password");
02279 if ( g_password.string[0] && Q_stricmp( g_password.string, "none" ) &&
02280 strcmp( g_password.string, value) != 0) {
02281 static char sTemp[1024];
02282 Q_strncpyz(sTemp, G_GetStringEdString("MP_SVGAME","INVALID_ESCAPE_TO_MAIN"), sizeof (sTemp) );
02283 return sTemp;// return "Invalid password";
02284 }
02285 }
02286
02287 // they can connect
02288 ent->client = level.clients + clientNum;
02289 client = ent->client;
02290
02291 //assign the pointer for bg entity access
02292 ent->playerState = &ent->client->ps;
02293
02294 // areabits = client->areabits;
02295
02296 memset( client, 0, sizeof(*client) );
02297
02298 client->pers.connected = CON_CONNECTING;
02299
02300 // read or initialize the session data
02301 if ( firstTime || level.newSession ) {
02302 G_InitSessionData( client, userinfo, isBot );
02303 }
02304 G_ReadSessionData( client );
02305
02306 if (g_gametype.integer == GT_SIEGE &&
02307 (firstTime || level.newSession))
02308 { //if this is the first time then auto-assign a desired siege team and show briefing for that team
02309 client->sess.siegeDesiredTeam = 0;//PickTeam(ent->s.number);
02310 /*
02311 trap_SendServerCommand(ent->s.number, va("sb %i", client->sess.siegeDesiredTeam));
02312 */
02313 //don't just show it - they'll see it if they switch to a team on purpose.
02314 }
02315
02316
02317 if (g_gametype.integer == GT_SIEGE && client->sess.sessionTeam != TEAM_SPECTATOR)
02318 {
02319 if (firstTime || level.newSession)
02320 { //start as spec
02321 client->sess.siegeDesiredTeam = client->sess.sessionTeam;
02322 client->sess.sessionTeam = TEAM_SPECTATOR;
02323 }
02324 }
02325 else if (g_gametype.integer == GT_POWERDUEL && client->sess.sessionTeam != TEAM_SPECTATOR)
02326 {
02327 client->sess.sessionTeam = TEAM_SPECTATOR;
02328 }
02329
02330 if( isBot ) {
02331 ent->r.svFlags |= SVF_BOT;
02332 ent->inuse = qtrue;
02333 if( !G_BotConnect( clientNum, !firstTime ) ) {
02334 return "BotConnectfailed";
02335 }
02336 }
02337
02338 // get and distribute relevent paramters
02339 G_LogPrintf( "ClientConnect: %i\n", clientNum );
02340 ClientUserinfoChanged( clientNum );
02341
02342 // don't do the "xxx connected" messages if they were caried over from previous level
02343 if ( firstTime ) {
02344 trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " %s\n\"", client->pers.netname, G_GetStringEdString("MP_SVGAME", "PLCONNECT")) );
02345 }
02346
02347 if ( g_gametype.integer >= GT_TEAM &&
02348 client->sess.sessionTeam != TEAM_SPECTATOR ) {
02349 BroadcastTeamChange( client, -1 );
02350 }
02351
02352 // count current clients and rank for scoreboard
02353 CalculateRanks();
02354
02355 te = G_TempEntity( vec3_origin, EV_CLIENTJOIN );
02356 te->r.svFlags |= SVF_BROADCAST;
02357 te->s.eventParm = clientNum;
02358
02359 // for statistics
02360 // client->areabits = areabits;
02361 // if ( !client->areabits )
02362 // client->areabits = G_Alloc( (trap_AAS_PointReachabilityAreaIndex( NULL ) + 7) / 8 );
02363
02364 return NULL;
02365 }
|
|
|
|
Definition at line 2930 of file g_client.c. References gclient_s::accuracy_hits, gclient_s::accuracy_shots, gclient_s::airOutTime, playerState_s::ammo, AMMO_BLASTER, AMMO_POWERCELL, ammoData, weaponData_s::ammoIndex, atoi(), BG_PlayerStateToEntityState(), bgSiegeClasses, gclient_s::bodyGrabIndex, BOTH_STAND1TO2, CFL_EXTRA_AMMO, CFL_SINGLE_ROCKET, gentity_s::classname, client, gentity_s::client, ClientEndFrame(), playerState_s::clientNum, level_locals_t::clients, ClientThink(), ClientUserinfoChanged(), gentity_s::clipmask, playerState_s::cloakFuel, clientPersistant_t::cmd, playerState_s::commandTime, CON_DISCONNECTED, clientPersistant_t::connected, entityShared_t::contents, CONTENTS_BODY, CROUCH_MAXS_2, playerState_s::crouchheight, entityShared_t::currentOrigin, playerState_s::customRGBA, DEFAULT_MAXS_2, gentity_s::die, playerState_s::duelIndex, clientSession_t::duelTeam, DUELTEAM_LONE, DUELTEAM_SINGLE, EF_DOUBLE_AMMO, EF_INVULNERABLE, EF_TELEPORT_BIT, playerState_s::eFlags, gclient_s::enemyTeam, ENTITYNUM_NONE, playerState_s::eventSequence, playerState_s::fallingToDeath, playerState_s::fd, FL_NO_BOTS, FL_NO_HUMANS, gentity_s::flags, forcedata_t, forcedata_s::forceDoInit, forcedata_s::forcePowerLevel, FP_SABER_OFFENSE, g_duel_fraglimit, g_duelWeaponDisable, g_entities, g_forcePowerDisable, g_gametype, g_inactivity, G_KillBox(), g_powerDuelEndHealth, g_powerDuelStartHealth, G_SaberModelSetup(), G_SetAnim(), G_SetOrigin(), G_SetSaber(), g_spawnInvulnerability, g_trueJedi, G_UseTargets(), g_weaponDisable, gclient_t, playerState_s::genericEnemyIndex, gentity_t, entityState_s::groundEntityNum, GT_CTF, GT_CTY, GT_DUEL, GT_HOLOCRON, GT_JEDIMASTER, GT_POWERDUEL, GT_SIEGE, GT_TEAM, HasSetSaberOnly(), gentity_s::health, HL_MAX, gclient_s::inactivityTime, Info_SetValueForKey(), Info_ValueForKey(), clientPersistant_t::initialSpawn, vmCvar_t::integer, level_locals_t::intermissiontime, gentity_s::inuse, gclient_s::invulnerableTimer, playerState_s::isJediMaster, playerState_s::jetpackFuel, gclient_s::lastkilled_client, gclient_s::latched_buttons, playerState_s::legsAnim, playerState_s::legsTimer, level, clientPersistant_t::localClient, gentity_s::locationDamage, MASK_PLAYERSOLID, MAX_INFO_STRING, MAX_PERSISTANT, MAX_SABERS, level_locals_t::maxclients, siegeClass_t::maxhealth, clientPersistant_t::maxHealth, entityShared_t::maxs, memset(), gclient_s::mGameFlags, entityShared_t::mins, saberInfo_t::model, MoveClientToIntermission(), gclient_s::noCorpse, NPCTEAM_ENEMY, NPCTEAM_PLAYER, NULL, entityState_s::number, level_locals_t::numPlayingClients, playerState_s::origin, gclient_s::pers, PERS_SPAWN_COUNT, PERS_TEAM, playerState_s::persistant, playerState_s::ping, player_die(), playerMaxs, playerMins, gentity_s::playerState, gclient_s::playerTeam, playerState_s::pm_flags, playerState_s::pm_time, PMF_RESPAWNED, PMF_TIME_KNOCKBACK, playerState_s::powerups, gclient_s::ps, PSG_TEAMVOTED, PSG_VOTED, PW_NUM_POWERUPS, Q3_INFINITE, Q_stricmp(), qboolean, qfalse, qtrue, gentity_s::r, gclient_s::respawnTime, playerState_s::rocketLockIndex, playerState_s::rocketLockTime, gentity_s::s, gclient_s::saber, clientSession_t::saber2Type, forcedata_s::saberAnimLevel, forcedata_s::saberAnimLevelBase, gclient_s::saberCycleQueue, forcedata_s::saberDrawAnimLevel, playerState_s::saberEntityNum, saberInfo_t::saberFlags, playerState_s::saberHolstered, clientSession_t::saberLevel, gclient_s::saberStoredIndex, clientSession_t::saberType, SelectCTFSpawnPoint(), SelectDuelSpawnPoint(), SelectInitialSpawnPoint(), SelectSiegeSpawnPoint(), SelectSpawnPoint(), SelectSpectatorSpawnPoint(), usercmd_s::serverTime, gclient_s::sess, clientSession_t::sessionTeam, SETANIM_BOTH, SETANIM_FLAG_HOLD, SETANIM_FLAG_HOLDLESS, SETANIM_FLAG_OVERRIDE, SETANIM_TORSO, SetClientViewAngle(), SetTeam(), SFL_TWO_HANDED, gclient_s::siegeClass, SIEGETEAM_TEAM1, SS_DUAL, SS_FAST, SS_STAFF, SS_STRONG, playerState_s::standheight, STAT_ARMOR, STAT_HEALTH, STAT_HOLDABLE_ITEM, STAT_HOLDABLE_ITEMS, STAT_MAX_HEALTH, STAT_WEAPONS, playerTeamState_t::state, playerState_s::stats, SVF_BOT, entityShared_t::svFlags, gentity_s::takedamage, TEAM_ACTIVE, TEAM_BLUE, TEAM_RED, TEAM_SPECTATOR, TeamName(), entityState_s::teamowner, clientPersistant_t::teamState, level_locals_t::time, TORSO_RAISEWEAP1, playerState_s::torsoTimer, trap_Cvar_Set(), trap_GetUsercmd(), trap_GetUserinfo(), trap_ICARUS_FreeEnt(), trap_ICARUS_InitEnt(), trap_LinkEntity(), trap_SetUserinfo(), playerState_s::trueJedi, playerState_s::trueNonJedi, va(), vec3_t, VectorCopy, gentity_s::waterlevel, gentity_s::watertype, playerState_s::weapon, WEAPON_RAISING, weaponData, gclient_s::weaponGhoul2, WeaponReadyAnim, playerState_s::weaponstate, playerState_s::weaponTime, clientSession_t::wins, WP_BLASTER, WP_BOWCASTER, WP_BRYAR_PISTOL, WP_HasForcePowers(), WP_InitForcePowers(), WP_MELEE, WP_NONE, WP_NUM_WEAPONS, WP_ROCKET_LAUNCHER, WP_SABER, WP_SaberStyleValidForSaber(), WP_SpawnInitForcePowers(), and WP_UseFirstValidSaberStyle(). Referenced by ClientBegin(), G_ResetDuelists(), respawn(), and SiegeRespawn().
02930 {
02931 int index;
02932 vec3_t spawn_origin, spawn_angles;
02933 gclient_t *client;
02934 int i;
02935 clientPersistant_t saved;
02936 clientSession_t savedSess;
02937 int persistant[MAX_PERSISTANT];
02938 gentity_t *spawnPoint;
02939 int flags, gameFlags;
02940 int savedPing;
02941 int accuracy_hits, accuracy_shots;
02942 int eventSequence;
02943 char userinfo[MAX_INFO_STRING];
02944 forcedata_t savedForce;
02945 int saveSaberNum = ENTITYNUM_NONE;
02946 int wDisable = 0;
02947 int savedSiegeIndex = 0;
02948 int maxHealth;
02949 saberInfo_t saberSaved[MAX_SABERS];
02950 int l = 0;
02951 void *g2WeaponPtrs[MAX_SABERS];
02952 char *value;
02953 char *saber;
02954 qboolean changedSaber = qfalse;
02955 qboolean inSiegeWithClass = qfalse;
02956
02957 index = ent - g_entities;
02958 client = ent->client;
02959
02960 //first we want the userinfo so we can see if we should update this client's saber -rww
02961 trap_GetUserinfo( index, userinfo, sizeof(userinfo) );
02962 while (l < MAX_SABERS)
02963 {
02964 switch (l)
02965 {
02966 case 0:
02967 saber = &ent->client->sess.saberType[0];
02968 break;
02969 case 1:
02970 saber = &ent->client->sess.saber2Type[0];
02971 break;
02972 default:
02973 saber = NULL;
02974 break;
02975 }
02976
02977 value = Info_ValueForKey (userinfo, va("saber%i", l+1));
02978 if (saber &&
02979 value &&
02980 (Q_stricmp(value, saber) || !saber[0] || !ent->client->saber[0].model[0]))
02981 { //doesn't match up (or our session saber is BS), we want to try setting it
02982 if (G_SetSaber(ent, l, value, qfalse))
02983 {
02984 changedSaber = qtrue;
02985 }
02986 else if (!saber[0] || !ent->client->saber[0].model[0])
02987 { //Well, we still want to say they changed then (it means this is siege and we have some overrides)
02988 changedSaber = qtrue;
02989 }
02990 }
02991 l++;
02992 }
02993
02994 if (changedSaber)
02995 { //make sure our new info is sent out to all the other clients, and give us a valid stance
02996 ClientUserinfoChanged( ent->s.number );
02997
02998 //make sure the saber models are updated
02999 G_SaberModelSetup(ent);
03000
03001 l = 0;
03002 while (l < MAX_SABERS)
03003 { //go through and make sure both sabers match the userinfo
03004 switch (l)
03005 {
03006 case 0:
03007 saber = &ent->client->sess.saberType[0];
03008 break;
03009 case 1:
03010 saber = &ent->client->sess.saber2Type[0];
03011 break;
03012 default:
03013 saber = NULL;
03014 break;
03015 }
03016
03017 value = Info_ValueForKey (userinfo, va("saber%i", l+1));
03018
03019 if (Q_stricmp(value, saber))
03020 { //they don't match up, force the user info
03021 Info_SetValueForKey(userinfo, va("saber%i", l+1), saber);
03022 trap_SetUserinfo( ent->s.number, userinfo );
03023 }
03024 l++;
03025 }
03026
03027 if (ent->client->saber[0].model[0] &&
03028 ent->client->saber[1].model[0])
03029 { //dual
03030 ent->client->ps.fd.saberAnimLevelBase = ent->client->ps.fd.saberAnimLevel = ent->client->ps.fd.saberDrawAnimLevel = SS_DUAL;
03031 }
03032 else if ((ent->client->saber[0].saberFlags&SFL_TWO_HANDED))
03033 { //staff
03034 ent->client->ps.fd.saberAnimLevel = ent->client->ps.fd.saberDrawAnimLevel = SS_STAFF;
03035 }
03036 else
03037 {
03038 if (ent->client->sess.saberLevel < SS_FAST)
03039 {
03040 ent->client->sess.saberLevel = SS_FAST;
03041 }
03042 else if (ent->client->sess.saberLevel > SS_STRONG)
03043 {
03044 ent->client->sess.saberLevel = SS_STRONG;
03045 }
03046 ent->client->ps.fd.saberAnimLevelBase = ent->client->ps.fd.saberAnimLevel = ent->client->ps.fd.saberDrawAnimLevel = ent->client->sess.saberLevel;
03047
03048 if (g_gametype.integer != GT_SIEGE &&
03049 ent->client->ps.fd.saberAnimLevel > ent->client->ps.fd.forcePowerLevel[FP_SABER_OFFENSE])
03050 {
03051 ent->client->ps.fd.saberAnimLevelBase = ent->client->ps.fd.saberAnimLevel = ent->client->ps.fd.saberDrawAnimLevel = ent->client->sess.saberLevel = ent->client->ps.fd.forcePowerLevel[FP_SABER_OFFENSE];
03052 }
03053 }
03054 if ( g_gametype.integer != GT_SIEGE )
03055 {
03056 //let's just make sure the styles we chose are cool
03057 if ( !WP_SaberStyleValidForSaber( &ent->client->saber[0], &ent->client->saber[1], ent->client->ps.saberHolstered, ent->client->ps.fd.saberAnimLevel ) )
03058 {
03059 WP_UseFirstValidSaberStyle( &ent->client->saber[0], &ent->client->saber[1], ent->client->ps.saberHolstered, &ent->client->ps.fd.saberAnimLevel );
03060 ent->client->ps.fd.saberAnimLevelBase = ent->client->saberCycleQueue = ent->client->ps.fd.saberAnimLevel;
03061 }
03062 }
03063 }
03064 l = 0;
03065
03066 if (client->ps.fd.forceDoInit)
03067 { //force a reread of force powers
03068 WP_InitForcePowers( ent );
03069 client->ps.fd.forceDoInit = 0;
03070 }
03071
03072 if (ent->client->ps.fd.saberAnimLevel != SS_STAFF &&
03073 ent->client->ps.fd.saberAnimLevel != SS_DUAL &&
03074 ent->client->ps.fd.saberAnimLevel == ent->client->ps.fd.saberDrawAnimLevel &&
03075 ent->client->ps.fd.saberAnimLevel == ent->client->sess.saberLevel)
03076 {
03077 if (ent->client->sess.saberLevel < SS_FAST)
03078 {
03079 ent->client->sess.saberLevel = SS_FAST;
03080 }
03081 else if (ent->client->sess.saberLevel > SS_STRONG)
03082 {
03083 ent->client->sess.saberLevel = SS_STRONG;
03084 }
03085 ent->client->ps.fd.saberAnimLevel = ent->client->ps.fd.saberDrawAnimLevel = ent->client->sess.saberLevel;
03086
03087 if (g_gametype.integer != GT_SIEGE &&
03088 ent->client->ps.fd.saberAnimLevel > ent->client->ps.fd.forcePowerLevel[FP_SABER_OFFENSE])
03089 {
03090 ent->client->ps.fd.saberAnimLevel = ent->client->ps.fd.saberDrawAnimLevel = ent->client->sess.saberLevel = ent->client->ps.fd.forcePowerLevel[FP_SABER_OFFENSE];
03091 }
03092 }
03093
03094 // find a spawn point
03095 // do it before setting health back up, so farthest
03096 // ranging doesn't count this client
03097 if ( client->sess.sessionTeam == TEAM_SPECTATOR ) {
03098 spawnPoint = SelectSpectatorSpawnPoint (
03099 spawn_origin, spawn_angles);
03100 } else if (g_gametype.integer == GT_CTF || g_gametype.integer == GT_CTY) {
03101 // all base oriented team games use the CTF spawn points
03102 spawnPoint = SelectCTFSpawnPoint (
03103 client->sess.sessionTeam,
03104 client->pers.teamState.state,
03105 spawn_origin, spawn_angles);
03106 }
03107 else if (g_gametype.integer == GT_SIEGE)
03108 {
03109 spawnPoint = SelectSiegeSpawnPoint (
03110 client->siegeClass,
03111 client->sess.sessionTeam,
03112 client->pers.teamState.state,
03113 spawn_origin, spawn_angles);
03114 }
03115 else {
03116 do {
03117 if (g_gametype.integer == GT_POWERDUEL)
03118 {
03119 spawnPoint = SelectDuelSpawnPoint(client->sess.duelTeam, client->ps.origin, spawn_origin, spawn_angles);
03120 }
03121 else if (g_gametype.integer == GT_DUEL)
03122 { // duel
03123 spawnPoint = SelectDuelSpawnPoint(DUELTEAM_SINGLE, client->ps.origin, spawn_origin, spawn_angles);
03124 }
03125 else
03126 {
03127 // the first spawn should be at a good looking spot
03128 if ( !client->pers.initialSpawn && client->pers.localClient ) {
03129 client->pers.initialSpawn = qtrue;
03130 spawnPoint = SelectInitialSpawnPoint( spawn_origin, spawn_angles, client->sess.sessionTeam );
03131 } else {
03132 // don't spawn near existing origin if possible
03133 spawnPoint = SelectSpawnPoint (
03134 client->ps.origin,
03135 spawn_origin, spawn_angles, client->sess.sessionTeam );
03136 }
03137 }
03138
03139 // Tim needs to prevent bots from spawning at the initial point
03140 // on q3dm0...
03141 if ( ( spawnPoint->flags & FL_NO_BOTS ) && ( ent->r.svFlags & SVF_BOT ) ) {
03142 continue; // try again
03143 }
03144 // just to be symetric, we have a nohumans option...
03145 if ( ( spawnPoint->flags & FL_NO_HUMANS ) && !( ent->r.svFlags & SVF_BOT ) ) {
03146 continue; // try again
03147 }
03148
03149 break;
03150
03151 } while ( 1 );
03152 }
03153 client->pers.teamState.state = TEAM_ACTIVE;
03154
03155 // toggle the teleport bit so the client knows to not lerp
03156 // and never clear the voted flag
03157 flags = ent->client->ps.eFlags & (EF_TELEPORT_BIT );
03158 flags ^= EF_TELEPORT_BIT;
03159 gameFlags = ent->client->mGameFlags & ( PSG_VOTED | PSG_TEAMVOTED);
03160
03161 // clear everything but the persistant data
03162
03163 saved = client->pers;
03164 savedSess = client->sess;
03165 savedPing = client->ps.ping;
03166 // savedAreaBits = client->areabits;
03167 accuracy_hits = client->accuracy_hits;
03168 accuracy_shots = client->accuracy_shots;
03169 for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) {
03170 persistant[i] = client->ps.persistant[i];
03171 }
03172 eventSequence = client->ps.eventSequence;
03173
03174 savedForce = client->ps.fd;
03175
03176 saveSaberNum = client->ps.saberEntityNum;
03177
03178 savedSiegeIndex = client->siegeClass;
03179
03180 l = 0;
03181 while (l < MAX_SABERS)
03182 {
03183 saberSaved[l] = client->saber[l];
03184 g2WeaponPtrs[l] = client->weaponGhoul2[l];
03185 l++;
03186 }
03187
03188 i = 0;
03189 while (i < HL_MAX)
03190 {
03191 ent->locationDamage[i] = 0;
03192 i++;
03193 }
03194
03195 memset (client, 0, sizeof(*client)); // bk FIXME: Com_Memset?
03196 client->bodyGrabIndex = ENTITYNUM_NONE;
03197
03198 //Get the skin RGB based on his userinfo
03199 value = Info_ValueForKey (userinfo, "char_color_red");
03200 if (value)
03201 {
03202 client->ps.customRGBA[0] = atoi(value);
03203 }
03204 else
03205 {
03206 client->ps.customRGBA[0] = 255;
03207 }
03208
03209 value = Info_ValueForKey (userinfo, "char_color_green");
03210 if (value)
03211 {
03212 client->ps.customRGBA[1] = atoi(value);
03213 }
03214 else
03215 {
03216 client->ps.customRGBA[1] = 255;
03217 }
03218
03219 value = Info_ValueForKey (userinfo, "char_color_blue");
03220 if (value)
03221 {
03222 client->ps.customRGBA[2] = atoi(value);
03223 }
03224 else
03225 {
03226 client->ps.customRGBA[2] = 255;
03227 }
03228
03229 if ((client->ps.customRGBA[0]+client->ps.customRGBA[1]+client->ps.customRGBA[2]) < 100)
03230 { //hmm, too dark!
03231 client->ps.customRGBA[0] = client->ps.customRGBA[1] = client->ps.customRGBA[2] = 255;
03232 }
03233
03234 client->ps.customRGBA[3]=255;
03235
03236 client->siegeClass = savedSiegeIndex;
03237
03238 l = 0;
03239 while (l < MAX_SABERS)
03240 {
03241 client->saber[l] = saberSaved[l];
03242 client->weaponGhoul2[l] = g2WeaponPtrs[l];
03243 l++;
03244 }
03245
03246 //or the saber ent num
03247 client->ps.saberEntityNum = saveSaberNum;
03248 client->saberStoredIndex = saveSaberNum;
03249
03250 client->ps.fd = savedForce;
03251
03252 client->ps.duelIndex = ENTITYNUM_NONE;
03253
03254 //spawn with 100
03255 client->ps.jetpackFuel = 100;
03256 client->ps.cloakFuel = 100;
03257
03258 client->pers = saved;
03259 client->sess = savedSess;
03260 client->ps.ping = savedPing;
03261 // client->areabits = savedAreaBits;
03262 client->accuracy_hits = accuracy_hits;
03263 client->accuracy_shots = accuracy_shots;
03264 client->lastkilled_client = -1;
03265
03266 for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) {
03267 client->ps.persistant[i] = persistant[i];
03268 }
03269 client->ps.eventSequence = eventSequence;
03270 // increment the spawncount so the client will detect the respawn
03271 client->ps.persistant[PERS_SPAWN_COUNT]++;
03272 client->ps.persistant[PERS_TEAM] = client->sess.sessionTeam;
03273
03274 client->airOutTime = level.time + 12000;
03275
03276 // set max health
03277 if (g_gametype.integer == GT_SIEGE && client->siegeClass != -1)
03278 {
03279 siegeClass_t *scl = &bgSiegeClasses[client->siegeClass];
03280 maxHealth = 100;
03281
03282 if (scl->maxhealth)
03283 {
03284 maxHealth = scl->maxhealth;
03285 }
03286 }
03287 else
03288 {
03289 maxHealth = 100;
03290 }
03291 client->pers.maxHealth = maxHealth;//atoi( Info_ValueForKey( userinfo, "handicap" ) );
03292 if ( client->pers.maxHealth < 1 || client->pers.maxHealth > maxHealth ) {
03293 client->pers.maxHealth = 100;
03294 }
03295 // clear entity values
03296 client->ps.stats[STAT_MAX_HEALTH] = client->pers.maxHealth;
03297 client->ps.eFlags = flags;
03298 client->mGameFlags = gameFlags;
03299
03300 ent->s.groundEntityNum = ENTITYNUM_NONE;
03301 ent->client = &level.clients[index];
03302 ent->playerState = &ent->client->ps;
03303 ent->takedamage = qtrue;
03304 ent->inuse = qtrue;
03305 ent->classname = "player";
03306 ent->r.contents = CONTENTS_BODY;
03307 ent->clipmask = MASK_PLAYERSOLID;
03308 ent->die = player_die;
03309 ent->waterlevel = 0;
03310 ent->watertype = 0;
03311 ent->flags = 0;
03312
03313 VectorCopy (playerMins, ent->r.mins);
03314 VectorCopy (playerMaxs, ent->r.maxs);
03315 client->ps.crouchheight = CROUCH_MAXS_2;
03316 client->ps.standheight = DEFAULT_MAXS_2;
03317
03318 client->ps.clientNum = index;
03319 //give default weapons
03320 client->ps.stats[STAT_WEAPONS] = ( 1 << WP_NONE );
03321
03322 if (g_gametype.integer == GT_DUEL || g_gametype.integer == GT_POWERDUEL)
03323 {
03324 wDisable = g_duelWeaponDisable.integer;
03325 }
03326 else
03327 {
03328 wDisable = g_weaponDisable.integer;
03329 }
03330
03331
03332
03333 if ( g_gametype.integer != GT_HOLOCRON
03334 && g_gametype.integer != GT_JEDIMASTER
03335 && !HasSetSaberOnly()
03336 && !AllForceDisabled( g_forcePowerDisable.integer )
03337 && g_trueJedi.integer )
03338 {
03339 if ( g_gametype.integer >= GT_TEAM && (client->sess.sessionTeam == TEAM_BLUE || client->sess.sessionTeam == TEAM_RED) )
03340 {//In Team games, force one side to be merc and other to be jedi
03341 if ( level.numPlayingClients > 0 )
03342 {//already someone in the game
03343 int i, forceTeam = TEAM_SPECTATOR;
03344 for ( i = 0 ; i < level.maxclients ; i++ )
03345 {
03346 if ( level.clients[i].pers.connected == CON_DISCONNECTED ) {
03347 continue;
03348 }
03349 if ( level.clients[i].sess.sessionTeam == TEAM_BLUE || level.clients[i].sess.sessionTeam == TEAM_RED )
03350 {//in-game
03351 if ( WP_HasForcePowers( &level.clients[i].ps ) )
03352 {//this side is using force
03353 forceTeam = level.clients[i].sess.sessionTeam;
03354 }
03355 else
03356 {//other team is using force
03357 if ( level.clients[i].sess.sessionTeam == TEAM_BLUE )
03358 {
03359 forceTeam = TEAM_RED;
03360 }
03361 else
03362 {
03363 forceTeam = TEAM_BLUE;
03364 }
03365 }
03366 break;
03367 }
03368 }
03369 if ( WP_HasForcePowers( &client->ps ) && client->sess.sessionTeam != forceTeam )
03370 {//using force but not on right team, switch him over
03371 const char *teamName = TeamName( forceTeam );
03372 //client->sess.sessionTeam = forceTeam;
03373 SetTeam( ent, (char *)teamName );
03374 return;
03375 }
03376 }
03377 }
03378
03379 if ( WP_HasForcePowers( &client->ps ) )
03380 {
03381 client->ps.trueNonJedi = qfalse;
03382 client->ps.trueJedi = qtrue;
03383 //make sure they only use the saber
03384 client->ps.weapon = WP_SABER;
03385 client->ps.stats[STAT_WEAPONS] = (1 << WP_SABER);
03386 }
03387 else
03388 {//no force powers set
03389 client->ps.trueNonJedi = qtrue;
03390 client->ps.trueJedi = qfalse;
03391 if (!wDisable || !(wDisable & (1 << WP_BRYAR_PISTOL)))
03392 {
03393 client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_BRYAR_PISTOL );
03394 }
03395 if (!wDisable || !(wDisable & (1 << WP_BLASTER)))
03396 {
03397 client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_BLASTER );
03398 }
03399 if (!wDisable || !(wDisable & (1 << WP_BOWCASTER)))
03400 {
03401 client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_BOWCASTER );
03402 }
03403 client->ps.stats[STAT_WEAPONS] &= ~(1 << WP_SABER);
03404 client->ps.stats[STAT_WEAPONS] |= (1 << WP_MELEE);
03405 client->ps.ammo[AMMO_POWERCELL] = ammoData[AMMO_POWERCELL].max;
03406 client->ps.weapon = WP_BRYAR_PISTOL;
03407 }
03408 }
03409 else
03410 {//jediVmerc is incompatible with this gametype, turn it off!
03411 trap_Cvar_Set( "g_jediVmerc", "0" );
03412 if (g_gametype.integer == GT_HOLOCRON)
03413 {
03414 //always get free saber level 1 in holocron
03415 client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_SABER ); //these are precached in g_items, ClearRegisteredItems()
03416 }
03417 else
03418 {
03419 if (client->ps.fd.forcePowerLevel[FP_SABER_OFFENSE])
03420 {
03421 client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_SABER ); //these are precached in g_items, ClearRegisteredItems()
03422 }
03423 else
03424 { //if you don't have saber attack rank then you don't get a saber
03425 client->ps.stats[STAT_WEAPONS] |= (1 << WP_MELEE);
03426 }
03427 }
03428
03429 if (g_gametype.integer != GT_SIEGE)
03430 {
03431 if (!wDisable || !(wDisable & (1 << WP_BRYAR_PISTOL)))
03432 {
03433 client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_BRYAR_PISTOL );
03434 }
03435 else if (g_gametype.integer == GT_JEDIMASTER)
03436 {
03437 client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_BRYAR_PISTOL );
03438 }
03439 }
03440
03441 if (g_gametype.integer == GT_JEDIMASTER)
03442 {
03443 client->ps.stats[STAT_WEAPONS] &= ~(1 << WP_SABER);
03444 client->ps.stats[STAT_WEAPONS] |= (1 << WP_MELEE);
03445 }
03446
03447 if (client->ps.stats[STAT_WEAPONS] & (1 << WP_SABER))
03448 {
03449 client->ps.weapon = WP_SABER;
03450 }
03451 else if (client->ps.stats[STAT_WEAPONS] & (1 << WP_BRYAR_PISTOL))
03452 {
03453 client->ps.weapon = WP_BRYAR_PISTOL;
03454 }
03455 else
03456 {
03457 client->ps.weapon = WP_MELEE;
03458 }
03459 }
03460
03461 /*
03462 client->ps.stats[STAT_HOLDABLE_ITEMS] |= ( 1 << HI_BINOCULARS );
03463 client->ps.stats[STAT_HOLDABLE_ITEM] = BG_GetItemIndexByTag(HI_BINOCULARS, IT_HOLDABLE);
03464 */
03465
03466 if (g_gametype.integer == GT_SIEGE && client->siegeClass != -1 &&
03467 client->sess.sessionTeam != TEAM_SPECTATOR)
03468 { //well then, we will use a custom weaponset for our class
03469 int m = 0;
03470
03471 client->ps.stats[STAT_WEAPONS] = bgSiegeClasses[client->siegeClass].weapons;
03472
03473 if (client->ps.stats[STAT_WEAPONS] & (1 << WP_SABER))
03474 {
03475 client->ps.weapon = WP_SABER;
03476 }
03477 else if (client->ps.stats[STAT_WEAPONS] & (1 << WP_BRYAR_PISTOL))
03478 {
03479 client->ps.weapon = WP_BRYAR_PISTOL;
03480 }
03481 else
03482 {
03483 client->ps.weapon = WP_MELEE;
03484 }
03485 inSiegeWithClass = qtrue;
03486
03487 while (m < WP_NUM_WEAPONS)
03488 {
03489 if (client->ps.stats[STAT_WEAPONS] & (1 << m))
03490 {
03491 if (client->ps.weapon != WP_SABER)
03492 { //try to find the highest ranking weapon we have
03493 if (m > client->ps.weapon)
03494 {
03495 client->ps.weapon = m;
03496 }
03497 }
03498
03499 if (m >= WP_BRYAR_PISTOL)
03500 { //Max his ammo out for all the weapons he has.
03501 if ( g_gametype.integer == GT_SIEGE
03502 && m == WP_ROCKET_LAUNCHER )
03503 {//don't give full ammo!
03504 //FIXME: extern this and check it when getting ammo from supplier, pickups or ammo stations!
03505 if ( client->siegeClass != -1 &&
03506 (bgSiegeClasses[client->siegeClass].classflags & (1<<CFL_SINGLE_ROCKET)) )
03507 {
03508 client->ps.ammo[weaponData[m].ammoIndex] = 1;
03509 }
03510 else
03511 {
03512 client->ps.ammo[weaponData[m].ammoIndex] = 10;
03513 }
03514 }
03515 else
03516 {
03517 if ( g_gametype.integer == GT_SIEGE
03518 && client->siegeClass != -1
03519 && (bgSiegeClasses[client->siegeClass].classflags & (1<<CFL_EXTRA_AMMO)) )
03520 {//double ammo
03521 client->ps.ammo[weaponData[m].ammoIndex] = ammoData[weaponData[m].ammoIndex].max*2;
03522 client->ps.eFlags |= EF_DOUBLE_AMMO;
03523 }
03524 else
03525 {
03526 client->ps.ammo[weaponData[m].ammoIndex] = ammoData[weaponData[m].ammoIndex].max;
03527 }
03528 }
03529 }
03530 }
03531 m++;
03532 }
03533 }
03534
03535 if (g_gametype.integer == GT_SIEGE &&
03536 client->siegeClass != -1 &&
03537 client->sess.sessionTeam != TEAM_SPECTATOR)
03538 { //use class-specified inventory
03539 client->ps.stats[STAT_HOLDABLE_ITEMS] = bgSiegeClasses[client->siegeClass].invenItems;
03540 client->ps.stats[STAT_HOLDABLE_ITEM] = 0;
03541 }
03542 else
03543 {
03544 client->ps.stats[STAT_HOLDABLE_ITEMS] = 0;
03545 client->ps.stats[STAT_HOLDABLE_ITEM] = 0;
03546 }
03547
03548 if (g_gametype.integer == GT_SIEGE &&
03549 client->siegeClass != -1 &&
03550 bgSiegeClasses[client->siegeClass].powerups &&
03551 client->sess.sessionTeam != TEAM_SPECTATOR)
03552 { //this class has some start powerups
03553 i = 0;
03554 while (i < PW_NUM_POWERUPS)
03555 {
03556 if (bgSiegeClasses[client->siegeClass].powerups & (1 << i))
03557 {
03558 client->ps.powerups[i] = Q3_INFINITE;
03559 }
03560 i++;
03561 }
03562 }
03563
03564 if ( client->sess.sessionTeam == TEAM_SPECTATOR )
03565 {
03566 client->ps.stats[STAT_WEAPONS] = 0;
03567 client->ps.stats[STAT_HOLDABLE_ITEMS] = 0;
03568 client->ps.stats[STAT_HOLDABLE_ITEM] = 0;
03569 }
03570
03571 // nmckenzie: DESERT_SIEGE... or well, siege generally. This was over-writing the max value, which was NOT good for siege.
03572 if ( inSiegeWithClass == qfalse )
03573 {
03574 client->ps.ammo[AMMO_BLASTER] = 100; //ammoData[AMMO_BLASTER].max; //100 seems fair.
03575 }
03576 // client->ps.ammo[AMMO_POWERCELL] = ammoData[AMMO_POWERCELL].max;
03577 // client->ps.ammo[AMMO_FORCE] = ammoData[AMMO_FORCE].max;
03578 // client->ps.ammo[AMMO_METAL_BOLTS] = ammoData[AMMO_METAL_BOLTS].max;
03579 // client->ps.ammo[AMMO_ROCKETS] = ammoData[AMMO_ROCKETS].max;
03580 /*
03581 client->ps.stats[STAT_WEAPONS] = ( 1 << WP_BRYAR_PISTOL);
03582 if ( g_gametype.integer == GT_TEAM ) {
03583 client->ps.ammo[WP_BRYAR_PISTOL] = 50;
03584 } else {
03585 client->ps.ammo[WP_BRYAR_PISTOL] = 100;
03586 }
03587 */
03588 client->ps.rocketLockIndex = ENTITYNUM_NONE;
03589 client->ps.rocketLockTime = 0;
03590
03591 //rww - Set here to initialize the circling seeker drone to off.
03592 //A quick note about this so I don't forget how it works again:
03593 //ps.genericEnemyIndex is kept in sync between the server and client.
03594 //When it gets set then an entitystate value of the same name gets
03595 //set along with an entitystate flag in the shared bg code. Which
03596 //is why a value needs to be both on the player state and entity state.
03597 //(it doesn't seem to just carry over the entitystate value automatically
03598 //because entity state value is derived from player state data or some
03599 //such)
03600 client->ps.genericEnemyIndex = -1;
03601
03602 client->ps.isJediMaster = qfalse;
03603
03604 if (client->ps.fallingToDeath)
03605 {
03606 client->ps.fallingToDeath = 0;
03607 client->noCorpse = qtrue;
03608 }
03609
03610 //Do per-spawn force power initialization
03611 WP_SpawnInitForcePowers( ent );
03612
03613 // health will count down towards max_health
03614 if (g_gametype.integer == GT_SIEGE &&
03615 client->siegeClass != -1 &&
03616 bgSiegeClasses[client->siegeClass].starthealth)
03617 { //class specifies a start health, so use it
03618 ent->health = client->ps.stats[STAT_HEALTH] = bgSiegeClasses[client->siegeClass].starthealth;
03619 }
03620 else if ( g_gametype.integer == GT_DUEL || g_gametype.integer == GT_POWERDUEL )
03621 {//only start with 100 health in Duel
03622 if ( g_gametype.integer == GT_POWERDUEL && client->sess.duelTeam == DUELTEAM_LONE )
03623 {
03624 if ( g_duel_fraglimit.integer )
03625 {
03626
03627 ent->health = client->ps.stats[STAT_HEALTH] = client->ps.stats[STAT_MAX_HEALTH] =
03628 g_powerDuelStartHealth.integer - ((g_powerDuelStartHealth.integer - g_powerDuelEndHealth.integer) * (float)client->sess.wins / (float)g_duel_fraglimit.integer);
03629 }
03630 else
03631 {
03632 ent->health = client->ps.stats[STAT_HEALTH] = client->ps.stats[STAT_MAX_HEALTH] = 150;
03633 }
03634 }
03635 else
03636 {
03637 ent->health = client->ps.stats[STAT_HEALTH] = client->ps.stats[STAT_MAX_HEALTH] = 100;
03638 }
03639 }
03640 else if (client->ps.stats[STAT_MAX_HEALTH] <= 100)
03641 {
03642 ent->health = client->ps.stats[STAT_HEALTH] = client->ps.stats[STAT_MAX_HEALTH] * 1.25;
03643 }
03644 else if (client->ps.stats[STAT_MAX_HEALTH] < 125)
03645 {
03646 ent->health = client->ps.stats[STAT_HEALTH] = 125;
03647 }
03648 else
03649 {
03650 ent->health = client->ps.stats[STAT_HEALTH] = client->ps.stats[STAT_MAX_HEALTH];
03651 }
03652
03653 // Start with a small amount of armor as well.
03654 if (g_gametype.integer == GT_SIEGE &&
03655 client->siegeClass != -1 /*&&
03656 bgSiegeClasses[client->siegeClass].startarmor*/)
03657 { //class specifies a start armor amount, so use it
03658 client->ps.stats[STAT_ARMOR] = bgSiegeClasses[client->siegeClass].startarmor;
03659 }
03660 else if ( g_gametype.integer == GT_DUEL || g_gametype.integer == GT_POWERDUEL )
03661 {//no armor in duel
03662 client->ps.stats[STAT_ARMOR] = 0;
03663 }
03664 else
03665 {
03666 client->ps.stats[STAT_ARMOR] = client->ps.stats[STAT_MAX_HEALTH] * 0.25;
03667 }
03668
03669 G_SetOrigin( ent, spawn_origin );
03670 VectorCopy( spawn_origin, client->ps.origin );
03671
03672 // the respawned flag will be cleared after the attack and jump keys come up
03673 client->ps.pm_flags |= PMF_RESPAWNED;
03674
03675 trap_GetUsercmd( client - level.clients, &ent->client->pers.cmd );
03676 SetClientViewAngle( ent, spawn_angles );
03677
03678 if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) {
03679
03680 } else {
03681 G_KillBox( ent );
03682 trap_LinkEntity (ent);
03683
03684 // force the base weapon up
03685 //client->ps.weapon = WP_BRYAR_PISTOL;
03686 //client->ps.weaponstate = FIRST_WEAPON;
03687 if (client->ps.weapon <= WP_NONE)
03688 {
03689 client->ps.weapon = WP_BRYAR_PISTOL;
03690 }
03691
03692 client->ps.torsoTimer = client->ps.legsTimer = 0;
03693
03694 if (client->ps.weapon == WP_SABER)
03695 {
03696 G_SetAnim(ent, NULL, SETANIM_BOTH, BOTH_STAND1TO2, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD|SETANIM_FLAG_HOLDLESS, 0);
03697 }
03698 else
03699 {
03700 G_SetAnim(ent, NULL, SETANIM_TORSO, TORSO_RAISEWEAP1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD|SETANIM_FLAG_HOLDLESS, 0);
03701 client->ps.legsAnim = WeaponReadyAnim[client->ps.weapon];
03702 }
03703 client->ps.weaponstate = WEAPON_RAISING;
03704 client->ps.weaponTime = client->ps.torsoTimer;
03705 }
03706
03707 // don't allow full run speed for a bit
03708 client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
03709 client->ps.pm_time = 100;
03710
03711 client->respawnTime = level.time;
03712 client->inactivityTime = level.time + g_inactivity.integer * 1000;
03713 client->latched_buttons = 0;
03714
03715 if ( level.intermissiontime ) {
03716 MoveClientToIntermission( ent );
03717 } else {
03718 // fire the targets of the spawn point
03719 G_UseTargets( spawnPoint, ent );
03720
03721 // select the highest weapon number available, after any
03722 // spawn given items have fired
03723 /*
03724 client->ps.weapon = 1;
03725 for ( i = WP_NUM_WEAPONS - 1 ; i > 0 ; i-- ) {
03726 if ( client->ps.stats[STAT_WEAPONS] & ( 1 << i ) ) {
03727 client->ps.weapon = i;
03728 break;
03729 }
03730 }
03731 */
03732 }
03733
03734 //set teams for NPCs to recognize
03735 if (g_gametype.integer == GT_SIEGE)
03736 { //Imperial (team1) team is allied with "enemy" NPCs in this mode
03737 if (client->sess.sessionTeam == SIEGETEAM_TEAM1)
03738 {
03739 client->playerTeam = ent->s.teamowner = NPCTEAM_ENEMY;
03740 client->enemyTeam = NPCTEAM_PLAYER;
03741 }
03742 else
03743 {
03744 client->playerTeam = ent->s.teamowner = NPCTEAM_PLAYER;
03745 client->enemyTeam = NPCTEAM_ENEMY;
03746 }
03747 }
03748 else
03749 {
03750 client->playerTeam = ent->s.teamowner = NPCTEAM_PLAYER;
03751 client->enemyTeam = NPCTEAM_ENEMY;
03752 }
03753
03754 /*
03755 //scaling for the power duel opponent
03756 if (g_gametype.integer == GT_POWERDUEL &&
03757 client->sess.duelTeam == DUELTEAM_LONE)
03758 {
03759 client->ps.iModelScale = 125;
03760 VectorSet(ent->modelScale, 1.25f, 1.25f, 1.25f);
03761 }
03762 */
03763 //Disabled. At least for now. Not sure if I'll want to do it or not eventually.
03764
03765 // run a client frame to drop exactly to the floor,
03766 // initialize animations and other things
03767 client->ps.commandTime = level.time - 100;
03768 ent->client->pers.cmd.serverTime = level.time;
03769 ClientThink( ent-g_entities, NULL );
03770
03771 // positively link the client, even if the command times are weird
03772 if ( ent->client->sess.sessionTeam != TEAM_SPECTATOR ) {
03773 BG_PlayerStateToEntityState( &client->ps, &ent->s, qtrue );
03774 VectorCopy( ent->client->ps.origin, ent->r.currentOrigin );
03775 trap_LinkEntity( ent );
03776 }
03777
03778 if (g_spawnInvulnerability.integer)
03779 {
03780 ent->client->ps.eFlags |= EF_INVULNERABLE;
03781 ent->client->invulnerableTimer = level.time + g_spawnInvulnerability.integer;
03782 }
03783
03784 // run the presend to set anything else
03785 ClientEndFrame( ent );
03786
03787 // clear entity state values
03788 BG_PlayerStateToEntityState( &client->ps, &ent->s, qtrue );
03789
03790 //rww - make sure client has a valid icarus instance
03791 trap_ICARUS_FreeEnt( ent );
03792 trap_ICARUS_InitEnt( ent );
03793 }
|
|
|
Definition at line 1888 of file g_client.c. References atoi(), BG_SiegeCheckClassLegality(), BG_SiegeFindClassIndexByName(), bgSiegeClasses, client, gentity_s::client, CON_CONNECTED, clientPersistant_t::connected, CS_PLAYERS, playerState_s::customRGBA, d_perPlayerGhoul2, clientSession_t::duelTeam, siegeClass_t::forcedModel, g_entities, g_gametype, G_GetStringEdString(), g_logClientInfo, G_LogPrintf(), G_PlayerHasCustomSkeleton(), G_SaberModelSetup(), G_SetSaber(), G_ValidateSiegeClassForTeam(), gclient_t, gentity_t, gentity_s::ghoul2, GT_SIEGE, GT_TEAM, Info_SetValueForKey(), Info_Validate(), Info_ValueForKey(), vmCvar_t::integer, renderInfo_s::lastG2, gclient_s::legsAnimExecute, gclient_s::legsLastFlip, level, gentity_s::localAnimIndex, clientPersistant_t::localClient, clientSession_t::losses, MAX_INFO_STRING, MAX_QPATH, MAX_STRING_CHARS, siegeClass_t::maxhealth, clientPersistant_t::maxHealth, gclient_s::modelname, clientPersistant_t::netname, clientPersistant_t::netnameTime, NULL, gclient_s::pers, PickTeam(), clientPersistant_t::predictItemPickup, gclient_s::ps, Q_stricmp(), Q_strncpyz(), qboolean, qfalse, qtrue, gentity_s::r, gclient_s::renderInfo, S_COLOR_WHITE, siegeClass_t::saber1, siegeClass_t::saber2, clientSession_t::saber2Type, clientSession_t::saberType, gclient_s::sess, clientSession_t::sessionTeam, SetupGameGhoul2Model(), clientSession_t::siegeClass, gclient_s::siegeClass, clientSession_t::siegeDesiredTeam, SPECTATOR_SCOREBOARD, clientSession_t::spectatorState, STAT_MAX_HEALTH, playerState_s::stats, strcmp(), strcpy(), SVF_BOT, entityShared_t::svFlags, TEAM_BLUE, TEAM_RED, TEAM_SPECTATOR, clientPersistant_t::teamInfo, clientSession_t::teamLeader, level_locals_t::time, gclient_s::torsoAnimExecute, gclient_s::torsoLastFlip, trap_GetUserinfo(), trap_SendServerCommand(), trap_SetConfigstring(), trap_SetUserinfo(), va(), and clientSession_t::wins. Referenced by AdjustTournamentScores(), ClientBegin(), ClientConnect(), ClientDisconnect(), ClientSpawn(), Cmd_DuelTeam_f(), Cmd_SiegeClass_f(), Cmd_TeamTask_f(), G_AddPowerDuelLoserScore(), G_AddPowerDuelScore(), SetLeader(), SetTeam(), SetTeamQuick(), and vmMain().
01888 {
01889 gentity_t *ent;
01890 int teamTask, teamLeader, team, health;
01891 char *s;
01892 char model[MAX_QPATH];
01893 //char headModel[MAX_QPATH];
01894 char forcePowers[MAX_QPATH];
01895 char oldname[MAX_STRING_CHARS];
01896 gclient_t *client;
01897 char c1[MAX_INFO_STRING];
01898 char c2[MAX_INFO_STRING];
01899 // char redTeam[MAX_INFO_STRING];
01900 // char blueTeam[MAX_INFO_STRING];
01901 char userinfo[MAX_INFO_STRING];
01902 char className[MAX_QPATH]; //name of class type to use in siege
01903 char saberName[MAX_QPATH];
01904 char saber2Name[MAX_QPATH];
01905 char *value;
01906 int maxHealth;
01907 qboolean modelChanged = qfalse;
01908
01909 ent = g_entities + clientNum;
01910 client = ent->client;
01911
01912 trap_GetUserinfo( clientNum, userinfo, sizeof( userinfo ) );
01913
01914 // check for malformed or illegal info strings
01915 if ( !Info_Validate(userinfo) ) {
01916 strcpy (userinfo, "\\name\\badinfo");
01917 }
01918
01919 // check for local client
01920 s = Info_ValueForKey( userinfo, "ip" );
01921 if ( !strcmp( s, "localhost" ) ) {
01922 client->pers.localClient = qtrue;
01923 }
01924
01925 // check the item prediction
01926 s = Info_ValueForKey( userinfo, "cg_predictItems" );
01927 if ( !atoi( s ) ) {
01928 client->pers.predictItemPickup = qfalse;
01929 } else {
01930 client->pers.predictItemPickup = qtrue;
01931 }
01932
01933 // set name
01934 Q_strncpyz ( oldname, client->pers.netname, sizeof( oldname ) );
01935 s = Info_ValueForKey (userinfo, "name");
01936 ClientCleanName( s, client->pers.netname, sizeof(client->pers.netname) );
01937
01938 if ( client->sess.sessionTeam == TEAM_SPECTATOR ) {
01939 if ( client->sess.spectatorState == SPECTATOR_SCOREBOARD ) {
01940 Q_strncpyz( client->pers.netname, "scoreboard", sizeof(client->pers.netname) );
01941 }
01942 }
01943
01944 if ( client->pers.connected == CON_CONNECTED ) {
01945 if ( strcmp( oldname, client->pers.netname ) )
01946 {
01947 if ( client->pers.netnameTime > level.time )
01948 {
01949 trap_SendServerCommand( clientNum, va("print \"%s\n\"", G_GetStringEdString("MP_SVGAME", "NONAMECHANGE")) );
01950
01951 Info_SetValueForKey( userinfo, "name", oldname );
01952 trap_SetUserinfo( clientNum, userinfo );
01953 strcpy ( client->pers.netname, oldname );
01954 }
01955 else
01956 {
01957 trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " %s %s\n\"", oldname, G_GetStringEdString("MP_SVGAME", "PLRENAME"), client->pers.netname) );
01958 client->pers.netnameTime = level.time + 5000;
01959 }
01960 }
01961 }
01962
01963 // set model
01964 Q_strncpyz( model, Info_ValueForKey (userinfo, "model"), sizeof( model ) );
01965
01966 if (d_perPlayerGhoul2.integer)
01967 {
01968 if (Q_stricmp(model, client->modelname))
01969 {
01970 strcpy(client->modelname, model);
01971 modelChanged = qtrue;
01972 }
01973 }
01974
01975 //Get the skin RGB based on his userinfo
01976 value = Info_ValueForKey (userinfo, "char_color_red");
01977 if (value)
01978 {
01979 client->ps.customRGBA[0] = atoi(value);
01980 }
01981 else
01982 {
01983 client->ps.customRGBA[0] = 255;
01984 }
01985
01986 value = Info_ValueForKey (userinfo, "char_color_green");
01987 if (value)
01988 {
01989 client->ps.customRGBA[1] = atoi(value);
01990 }
01991 else
01992 {
01993 client->ps.customRGBA[1] = 255;
01994 }
01995
01996 value = Info_ValueForKey (userinfo, "char_color_blue");
01997 if (value)
01998 {
01999 client->ps.customRGBA[2] = atoi(value);
02000 }
02001 else
02002 {
02003 client->ps.customRGBA[2] = 255;
02004 }
02005
02006 if ((client->ps.customRGBA[0]+client->ps.customRGBA[1]+client->ps.customRGBA[2]) < 100)
02007 { //hmm, too dark!
02008 client->ps.customRGBA[0] = client->ps.customRGBA[1] = client->ps.customRGBA[2] = 255;
02009 }
02010
02011 client->ps.customRGBA[3]=255;
02012
02013 Q_strncpyz( forcePowers, Info_ValueForKey (userinfo, "forcepowers"), sizeof( forcePowers ) );
02014
02015 // bots set their team a few frames later
02016 if (g_gametype.integer >= GT_TEAM && g_entities[clientNum].r.svFlags & SVF_BOT) {
02017 s = Info_ValueForKey( userinfo, "team" );
02018 if ( !Q_stricmp( s, "red" ) || !Q_stricmp( s, "r" ) ) {
02019 team = TEAM_RED;
02020 } else if ( !Q_stricmp( s, "blue" ) || !Q_stricmp( s, "b" ) ) {
02021 team = TEAM_BLUE;
02022 } else {
02023 // pick the team with the least number of players
02024 team = PickTeam( clientNum );
02025 }
02026 }
02027 else {
02028 team = client->sess.sessionTeam;
02029 }
02030
02031 //Set the siege class
02032 if (g_gametype.integer == GT_SIEGE)
02033 {
02034 strcpy(className, client->sess.siegeClass);
02035
02036 //This function will see if the given class is legal for the given team.
02037 //If not className will be filled in with the first legal class for this team.
02038 /* if (!BG_SiegeCheckClassLegality(team, className) &&
02039 Q_stricmp(client->sess.siegeClass, "none"))
02040 { //if it isn't legal pop up the class menu
02041 trap_SendServerCommand(ent-g_entities, "scl");
02042 }
02043 */
02044 //Now that the team is legal for sure, we'll go ahead and get an index for it.
02045 client->siegeClass = BG_SiegeFindClassIndexByName(className);
02046 if (client->siegeClass == -1)
02047 { //ok, get the first valid class for the team you're on then, I guess.
02048 BG_SiegeCheckClassLegality(team, className);
02049 strcpy(client->sess.siegeClass, className);
02050 client->siegeClass = BG_SiegeFindClassIndexByName(className);
02051 }
02052 else
02053 { //otherwise, make sure the class we are using is legal.
02054 G_ValidateSiegeClassForTeam(ent, team);
02055 strcpy(className, client->sess.siegeClass);
02056 }
02057
02058 //Set the sabers if the class dictates
02059 if (client->siegeClass != -1)
02060 {
02061 siegeClass_t *scl = &bgSiegeClasses[client->siegeClass];
02062
02063 if (scl->saber1[0])
02064 {
02065 G_SetSaber(ent, 0, scl->saber1, qtrue);
02066 }
02067 else
02068 { //default I guess
02069 G_SetSaber(ent, 0, "Kyle", qtrue);
02070 }
02071 if (scl->saber2[0])
02072 {
02073 G_SetSaber(ent, 1, scl->saber2, qtrue);
02074 }
02075 else
02076 { //no second saber then
02077 G_SetSaber(ent, 1, "none", qtrue);
02078 }
02079
02080 //make sure the saber models are updated
02081 G_SaberModelSetup(ent);
02082
02083 if (scl->forcedModel[0])
02084 { //be sure to override the model we actually use
02085 strcpy(model, scl->forcedModel);
02086 if (d_perPlayerGhoul2.integer)
02087 {
02088 if (Q_stricmp(model, client->modelname))
02089 {
02090 strcpy(client->modelname, model);
02091 modelChanged = qtrue;
02092 }
02093 }
02094 }
02095
02096 //force them to use their class model on the server, if the class dictates
02097 if (G_PlayerHasCustomSkeleton(ent))
02098 {
02099 if (Q_stricmp(model, client->modelname) || ent->localAnimIndex == 0)
02100 {
02101 strcpy(client->modelname, model);
02102 modelChanged = qtrue;
02103 }
02104 }
02105 }
02106 }
02107 else
02108 {
02109 strcpy(className, "none");
02110 }
02111
02112 //Set the saber name
02113 strcpy(saberName, client->sess.saberType);
02114 strcpy(saber2Name, client->sess.saber2Type);
02115
02116 // set max health
02117 if (g_gametype.integer == GT_SIEGE && client->siegeClass != -1)
02118 {
02119 siegeClass_t *scl = &bgSiegeClasses[client->siegeClass];
02120 maxHealth = 100;
02121
02122 if (scl->maxhealth)
02123 {
02124 maxHealth = scl->maxhealth;
02125 }
02126
02127 health = maxHealth;
02128 }
02129 else
02130 {
02131 maxHealth = 100;
02132 health = 100; //atoi( Info_ValueForKey( userinfo, "handicap" ) );
02133 }
02134 client->pers.maxHealth = health;
02135 if ( client->pers.maxHealth < 1 || client->pers.maxHealth > maxHealth ) {
02136 client->pers.maxHealth = 100;
02137 }
02138 client->ps.stats[STAT_MAX_HEALTH] = client->pers.maxHealth;
02139
02140 /* NOTE: all client side now
02141
02142 // team
02143 switch( team ) {
02144 case TEAM_RED:
02145 ForceClientSkin(client, model, "red");
02146 // ForceClientSkin(client, headModel, "red");
02147 break;
02148 case TEAM_BLUE:
02149 ForceClientSkin(client, model, "blue");
02150 // ForceClientSkin(client, headModel, "blue");
02151 break;
02152 }
02153 // don't ever use a default skin in teamplay, it would just waste memory
02154 // however bots will always join a team but they spawn in as spectator
02155 if ( g_gametype.integer >= GT_TEAM && team == TEAM_SPECTATOR) {
02156 ForceClientSkin(client, model, "red");
02157 // ForceClientSkin(client, headModel, "red");
02158 }
02159 */
02160
02161 if (g_gametype.integer >= GT_TEAM) {
02162 client->pers.teamInfo = qtrue;
02163 } else {
02164 s = Info_ValueForKey( userinfo, "teamoverlay" );
02165 if ( ! *s || atoi( s ) != 0 ) {
02166 client->pers.teamInfo = qtrue;
02167 } else {
02168 client->pers.teamInfo = qfalse;
02169 }
02170 }
02171 /*
02172 s = Info_ValueForKey( userinfo, "cg_pmove_fixed" );
02173 if ( !*s || atoi( s ) == 0 ) {
02174 client->pers.pmoveFixed = qfalse;
02175 }
02176 else {
02177 client->pers.pmoveFixed = qtrue;
02178 }
02179 */
02180
02181 // team task (0 = none, 1 = offence, 2 = defence)
02182 teamTask = atoi(Info_ValueForKey(userinfo, "teamtask"));
02183 // team Leader (1 = leader, 0 is normal player)
02184 teamLeader = client->sess.teamLeader;
02185
02186 // colors
02187 strcpy(c1, Info_ValueForKey( userinfo, "color1" ));
02188 strcpy(c2, Info_ValueForKey( userinfo, "color2" ));
02189
02190 // strcpy(redTeam, Info_ValueForKey( userinfo, "g_redteam" ));
02191 // strcpy(blueTeam, Info_ValueForKey( userinfo, "g_blueteam" ));
02192
02193 // send over a subset of the userinfo keys so other clients can
02194 // print scoreboards, display models, and play custom sounds
02195 if ( ent->r.svFlags & SVF_BOT ) {
02196 s = va("n\\%s\\t\\%i\\model\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\skill\\%s\\tt\\%d\\tl\\%d\\siegeclass\\%s\\st\\%s\\st2\\%s\\dt\\%i\\sdt\\%i",
02197 client->pers.netname, team, model, c1, c2,
02198 client->pers.maxHealth, client->sess.wins, client->sess.losses,
02199 Info_ValueForKey( userinfo, "skill" ), teamTask, teamLeader, className, saberName, saber2Name, client->sess.duelTeam, client->sess.siegeDesiredTeam );
02200 } else {
02201 if (g_gametype.integer == GT_SIEGE)
02202 { //more crap to send
02203 s = va("n\\%s\\t\\%i\\model\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\tl\\%d\\siegeclass\\%s\\st\\%s\\st2\\%s\\dt\\%i\\sdt\\%i",
02204 client->pers.netname, client->sess.sessionTeam, model, c1, c2,
02205 client->pers.maxHealth, client->sess.wins, client->sess.losses, teamTask, teamLeader, className, saberName, saber2Name, client->sess.duelTeam, client->sess.siegeDesiredTeam);
02206 }
02207 else
02208 {
02209 s = va("n\\%s\\t\\%i\\model\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\tl\\%d\\st\\%s\\st2\\%s\\dt\\%i",
02210 client->pers.netname, client->sess.sessionTeam, model, c1, c2,
02211 client->pers.maxHealth, client->sess.wins, client->sess.losses, teamTask, teamLeader, saberName, saber2Name, client->sess.duelTeam);
02212 }
02213 }
02214
02215 trap_SetConfigstring( CS_PLAYERS+clientNum, s );
02216
02217 if (modelChanged) //only going to be true for allowable server-side custom skeleton cases
02218 { //update the server g2 instance if appropriate
02219 char *modelname = Info_ValueForKey (userinfo, "model");
02220 SetupGameGhoul2Model(ent, modelname, NULL);
02221
02222 if (ent->ghoul2 && ent->client)
02223 {
02224 ent->client->renderInfo.lastG2 = NULL; //update the renderinfo bolts next update.
02225 }
02226
02227 client->torsoAnimExecute = client->legsAnimExecute = -1;
02228 client->torsoLastFlip = client->legsLastFlip = qfalse;
02229 }
02230
02231 if (g_logClientInfo.integer)
02232 {
02233 G_LogPrintf( "ClientUserinfoChanged: %i %s\n", clientNum, s );
02234 }
02235 }
|
|
||||||||||||
|
Definition at line 2608 of file g_client.c. References BOTH_PAIN2, BOTH_PAIN3, BROKENLIMB_LARM, BROKENLIMB_RARM, playerState_s::brokenLimbs, CHAN_AUTO, CHAN_VOICE, CLASS_VEHICLE, gentity_s::client, clientPersistant_t::cmd, playerState_s::fd, G_EntitySound(), G_SetAnim(), G_Sound(), G_SoundIndex(), gentity_t, gentity_s::localAnimIndex, saberInfo_t::model, entityState_s::NPC_class, gclient_s::pers, gclient_s::ps, Q_irand(), gentity_s::s, gclient_s::saber, forcedata_s::saberAnimLevel, playerState_s::saberHolstered, SETANIM_BOTH, SETANIM_FLAG_HOLD, SETANIM_FLAG_OVERRIDE, saberInfo_t::soundOff, SS_STAFF, va(), playerState_s::weapon, and WP_SABER. Referenced by ClientCommand(), G_Damage(), and player_die().
02609 {
02610 int anim = -1;
02611
02612 assert(ent && ent->client);
02613
02614 if (ent->s.NPC_class == CLASS_VEHICLE || ent->localAnimIndex > 1)
02615 { //no broken limbs for vehicles and non-humanoids
02616 return;
02617 }
02618
02619 if (!arm)
02620 { //repair him
02621 ent->client->ps.brokenLimbs = 0;
02622 return;
02623 }
02624
02625 if (ent->client->ps.fd.saberAnimLevel == SS_STAFF)
02626 { //I'm too lazy to deal with this as well for now.
02627 return;
02628 }
02629
02630 if (arm == BROKENLIMB_LARM)
02631 {
02632 if (ent->client->saber[1].model[0] &&
02633 ent->client->ps.weapon == WP_SABER &&
02634 !ent->client->ps.saberHolstered &&
02635 ent->client->saber[1].soundOff)
02636 { //the left arm shuts off its saber upon being broken
02637 G_Sound(ent, CHAN_AUTO, ent->client->saber[1].soundOff);
02638 }
02639 }
02640
02641 ent->client->ps.brokenLimbs = 0; //make sure it's cleared out
02642 ent->client->ps.brokenLimbs |= (1 << arm); //this arm is now marked as broken
02643
02644 //Do a pain anim based on the side. Since getting your arm broken does tend to hurt.
02645 if (arm == BROKENLIMB_LARM)
02646 {
02647 anim = BOTH_PAIN2;
02648 }
02649 else if (arm == BROKENLIMB_RARM)
02650 {
02651 anim = BOTH_PAIN3;
02652 }
02653
02654 if (anim == -1)
02655 {
02656 return;
02657 }
02658
02659 G_SetAnim(ent, &ent->client->pers.cmd, SETANIM_BOTH, anim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0);
02660
02661 //This could be combined into a single event. But I guess limbs don't break often enough to
02662 //worry about it.
02663 G_EntitySound( ent, CHAN_VOICE, G_SoundIndex("*pain25.wav") );
02664 //FIXME: A nice bone snapping sound instead if possible
02665 G_Sound(ent, CHAN_AUTO, G_SoundIndex( va("sound/player/bodyfall_human%i.wav", Q_irand(1, 3)) ));
02666 }
|
|
|
Definition at line 1423 of file g_client.c. References gentity_s::client, gentity_t, gentity_s::ghoul2, MAX_SABERS, saberInfo_t::model, saberInfo_t::numBlades, qboolean, qfalse, qtrue, gclient_s::saber, saberInfo_t::saberFlags, SFL_BOLT_TO_WRIST, saberInfo_t::skin, trap_G2API_AddBolt(), trap_G2API_CleanGhoul2Models(), trap_G2API_CopySpecificGhoul2Model(), trap_G2API_InitGhoul2Model(), trap_G2API_SetBoltInfo(), trap_G2API_SetSkin(), va(), and gclient_s::weaponGhoul2. Referenced by ClientSpawn(), ClientUserinfoChanged(), and SetupGameGhoul2Model().
01424 {
01425 int i = 0;
01426 qboolean fallbackForSaber = qtrue;
01427
01428 while (i < MAX_SABERS)
01429 {
01430 if (ent->client->saber[i].model[0])
01431 {
01432 //first kill it off if we've already got it
01433 if (ent->client->weaponGhoul2[i])
01434 {
01435 trap_G2API_CleanGhoul2Models(&(ent->client->weaponGhoul2[i]));
01436 }
01437 trap_G2API_InitGhoul2Model(&ent->client->weaponGhoul2[i], ent->client->saber[i].model, 0, 0, -20, 0, 0);
01438
01439 if (ent->client->weaponGhoul2[i])
01440 {
01441 int j = 0;
01442 char *tagName;
01443 int tagBolt;
01444
01445 if (ent->client->saber[i].skin)
01446 {
01447 trap_G2API_SetSkin(ent->client->weaponGhoul2[i], 0, ent->client->saber[i].skin, ent->client->saber[i].skin);
01448 }
01449
01450 if (ent->client->saber[i].saberFlags & SFL_BOLT_TO_WRIST)
01451 {
01452 trap_G2API_SetBoltInfo(ent->client->weaponGhoul2[i], 0, 3+i);
01453 }
01454 else
01455 { // bolt to right hand for 0, or left hand for 1
01456 trap_G2API_SetBoltInfo(ent->client->weaponGhoul2[i], 0, i);
01457 }
01458
01459 //Add all the bolt points
01460 while (j < ent->client->saber[i].numBlades)
01461 {
01462 tagName = va("*blade%i", j+1);
01463 tagBolt = trap_G2API_AddBolt(ent->client->weaponGhoul2[i], 0, tagName);
01464
01465 if (tagBolt == -1)
01466 {
01467 if (j == 0)
01468 { //guess this is an 0ldsk3wl saber
01469 tagBolt = trap_G2API_AddBolt(ent->client->weaponGhoul2[i], 0, "*flash");
01470 fallbackForSaber = qfalse;
01471 break;
01472 }
01473
01474 if (tagBolt == -1)
01475 {
01476 assert(0);
01477 break;
01478
01479 }
01480 }
01481 j++;
01482
01483 fallbackForSaber = qfalse; //got at least one custom saber so don't need default
01484 }
01485
01486 //Copy it into the main instance
01487 trap_G2API_CopySpecificGhoul2Model(ent->client->weaponGhoul2[i], 0, ent->ghoul2, i+1);
01488 }
01489 }
01490 else
01491 {
01492 break;
01493 }
01494
01495 i++;
01496 }
01497
01498 return fallbackForSaber;
01499 }
|
|
||||||||||||||||||||
|
Definition at line 1305 of file g_cmds.c. References bgSiegeClasses, gentity_s::client, playerState_s::fd, g_gametype, gentity_t, GT_SIEGE, vmCvar_t::integer, saberInfo_t::model, saberInfo_t::name, entityState_s::number, gclient_s::ps, Q_stricmp(), qboolean, qfalse, qtrue, gentity_s::s, gclient_s::saber, clientSession_t::saber2Type, forcedata_s::saberAnimLevel, forcedata_s::saberAnimLevelBase, gclient_s::saberCycleQueue, playerState_s::saberHolstered, clientSession_t::saberType, gclient_s::sess, gclient_s::siegeClass, strcpy(), WP_SaberStyleValidForSaber(), WP_SetSaber(), and WP_UseFirstValidSaberStyle(). Referenced by ClientBegin(), ClientSpawn(), and ClientUserinfoChanged().
01306 {
01307 char truncSaberName[64];
01308 int i = 0;
01309
01310 if (!siegeOverride &&
01311 g_gametype.integer == GT_SIEGE &&
01312 ent->client->siegeClass != -1 &&
01313 (
01314 bgSiegeClasses[ent->client->siegeClass].saberStance ||
01315 bgSiegeClasses[ent->client->siegeClass].saber1[0] ||
01316 bgSiegeClasses[ent->client->siegeClass].saber2[0]
01317 ))
01318 { //don't let it be changed if the siege class has forced any saber-related things
01319 return qfalse;
01320 }
01321
01322 while (saberName[i] && i < 64-1)
01323 {
01324 truncSaberName[i] = saberName[i];
01325 i++;
01326 }
01327 truncSaberName[i] = 0;
01328
01329 if ( saberNum == 0 && (Q_stricmp( "none", truncSaberName ) == 0 || Q_stricmp( "remove", truncSaberName ) == 0) )
01330 { //can't remove saber 0 like this
01331 strcpy(truncSaberName, "Kyle");
01332 }
01333
01334 //Set the saber with the arg given. If the arg is
01335 //not a valid sabername defaults will be used.
01336 WP_SetSaber(ent->s.number, ent->client->saber, saberNum, truncSaberName);
01337
01338 if (!ent->client->saber[0].model[0])
01339 {
01340 assert(0); //should never happen!
01341 strcpy(ent->client->sess.saberType, "none");
01342 }
01343 else
01344 {
01345 strcpy(ent->client->sess.saberType, ent->client->saber[0].name);
01346 }
01347
01348 if (!ent->client->saber[1].model[0])
01349 {
01350 strcpy(ent->client->sess.saber2Type, "none");
01351 }
01352 else
01353 {
01354 strcpy(ent->client->sess.saber2Type, ent->client->saber[1].name);
01355 }
01356
01357 if ( !WP_SaberStyleValidForSaber( &ent->client->saber[0], &ent->client->saber[1], ent->client->ps.saberHolstered, ent->client->ps.fd.saberAnimLevel ) )
01358 {
01359 WP_UseFirstValidSaberStyle( &ent->client->saber[0], &ent->client->saber[1], ent->client->ps.saberHolstered, &ent->client->ps.fd.saberAnimLevel );
01360 ent->client->ps.fd.saberAnimLevelBase = ent->client->saberCycleQueue = ent->client->ps.fd.saberAnimLevel;
01361 }
01362
01363 return qtrue;
01364 }
|
|
||||||||||||
|
Definition at line 2673 of file g_client.c. References animation_t, BG_SaberStanceAnim(), BG_SaberStartTransAnim(), bgAllAnims, BONE_ANIM_BLEND, BONE_ANIM_OVERRIDE_FREEZE, BONE_ANIM_OVERRIDE_LOOP, BOTH_ATTACK2, BOTH_DEAD21, BOTH_MELEE1, BOTH_MELEE2, BOTH_STAND2, BROKENLIMB_LARM, BROKENLIMB_RARM, playerState_s::brokenLimbs, gclient_s::brokenLimbs, CLASS_VEHICLE, gentity_s::client, playerState_s::fd, animation_s::firstFrame, animation_s::frameLerp, gentity_t, gentity_s::ghoul2, playerState_s::legsAnim, gclient_s::legsAnimExecute, playerState_s::legsFlip, gclient_s::legsLastFlip, level, gentity_s::localAnimIndex, MAX_CLIENTS, saberInfo_t::model, gentity_s::noLumbar, entityState_s::NPC_class, NULL, entityState_s::number, animation_s::numFrames, PM_RunningAnim(), gclient_s::ps, qboolean, qfalse, qtrue, gentity_s::s, gclient_s::saber, forcedata_s::saberAnimLevel, playerState_s::saberLockFrame, level_locals_t::time, TORSO_WEAPONREADY2, playerState_s::torsoAnim, gclient_s::torsoAnimExecute, playerState_s::torsoFlip, gclient_s::torsoLastFlip, trap_G2API_RemoveBone(), trap_G2API_SetBoneAnim(), playerState_s::weapon, WP_BRYAR_PISTOL, WP_MELEE, and WP_SABER. Referenced by player_die(), and WP_SaberPositionUpdate().
02674 {
02675 static int f;
02676 static int torsoAnim;
02677 static int legsAnim;
02678 static int firstFrame, lastFrame;
02679 static int aFlags;
02680 static float animSpeed, lAnimSpeedScale;
02681 qboolean setTorso = qfalse;
02682
02683 torsoAnim = (self->client->ps.torsoAnim);
02684 legsAnim = (self->client->ps.legsAnim);
02685
02686 if (self->client->ps.saberLockFrame)
02687 {
02688 trap_G2API_SetBoneAnim(self->ghoul2, 0, "model_root", self->client->ps.saberLockFrame, self->client->ps.saberLockFrame+1, BONE_ANIM_OVERRIDE_FREEZE|BONE_ANIM_BLEND, animSpeedScale, level.time, -1, 150);
02689 trap_G2API_SetBoneAnim(self->ghoul2, 0, "lower_lumbar", self->client->ps.saberLockFrame, self->client->ps.saberLockFrame+1, BONE_ANIM_OVERRIDE_FREEZE|BONE_ANIM_BLEND, animSpeedScale, level.time, -1, 150);
02690 trap_G2API_SetBoneAnim(self->ghoul2, 0, "Motion", self->client->ps.saberLockFrame, self->client->ps.saberLockFrame+1, BONE_ANIM_OVERRIDE_FREEZE|BONE_ANIM_BLEND, animSpeedScale, level.time, -1, 150);
02691 return;
02692 }
02693
02694 if (self->localAnimIndex > 1 &&
02695 bgAllAnims[self->localAnimIndex].anims[legsAnim].firstFrame == 0 &&
02696 bgAllAnims[self->localAnimIndex].anims[legsAnim].numFrames == 0)
02697 { //We'll allow this for non-humanoids.
02698 goto tryTorso;
02699 }
02700
02701 if (self->client->legsAnimExecute != legsAnim || self->client->legsLastFlip != self->client->ps.legsFlip)
02702 {
02703 animSpeed = 50.0f / bgAllAnims[self->localAnimIndex].anims[legsAnim].frameLerp;
02704 lAnimSpeedScale = (animSpeed *= animSpeedScale);
02705
02706 if (bgAllAnims[self->localAnimIndex].anims[legsAnim].loopFrames != -1)
02707 {
02708 aFlags = BONE_ANIM_OVERRIDE_LOOP;
02709 }
02710 else
02711 {
02712 aFlags = BONE_ANIM_OVERRIDE_FREEZE;
02713 }
02714
02715 if (animSpeed < 0)
02716 {
02717 lastFrame = bgAllAnims[self->localAnimIndex].anims[legsAnim].firstFrame;
02718 firstFrame = bgAllAnims[self->localAnimIndex].anims[legsAnim].firstFrame + bgAllAnims[self->localAnimIndex].anims[legsAnim].numFrames;
02719 }
02720 else
02721 {
02722 firstFrame = bgAllAnims[self->localAnimIndex].anims[legsAnim].firstFrame;
02723 lastFrame = bgAllAnims[self->localAnimIndex].anims[legsAnim].firstFrame + bgAllAnims[self->localAnimIndex].anims[legsAnim].numFrames;
02724 }
02725
02726 aFlags |= BONE_ANIM_BLEND; //since client defaults to blend. Not sure if this will make much difference if any on server position, but it's here just for the sake of matching them.
02727
02728 trap_G2API_SetBoneAnim(self->ghoul2, 0, "model_root", firstFrame, lastFrame, aFlags, lAnimSpeedScale, level.time, -1, 150);
02729 self->client->legsAnimExecute = legsAnim;
02730 self->client->legsLastFlip = self->client->ps.legsFlip;
02731 }
02732
02733 tryTorso:
02734 if (self->localAnimIndex > 1 &&
02735 bgAllAnims[self->localAnimIndex].anims[torsoAnim].firstFrame == 0 &&
02736 bgAllAnims[self->localAnimIndex].anims[torsoAnim].numFrames == 0)
02737
02738 { //If this fails as well just return.
02739 return;
02740 }
02741 else if (self->s.number >= MAX_CLIENTS &&
02742 self->s.NPC_class == CLASS_VEHICLE)
02743 { //we only want to set the root bone for vehicles
02744 return;
02745 }
02746
02747 if ((self->client->torsoAnimExecute != torsoAnim || self->client->torsoLastFlip != self->client->ps.torsoFlip) &&
02748 !self->noLumbar)
02749 {
02750 aFlags = 0;
02751 animSpeed = 0;
02752
02753 f = torsoAnim;
02754
02755 BG_SaberStartTransAnim(self->s.number, self->client->ps.fd.saberAnimLevel, self->client->ps.weapon, f, &animSpeedScale, self->client->ps.brokenLimbs);
02756
02757 animSpeed = 50.0f / bgAllAnims[self->localAnimIndex].anims[f].frameLerp;
02758 lAnimSpeedScale = (animSpeed *= animSpeedScale);
02759
02760 if (bgAllAnims[self->localAnimIndex].anims[f].loopFrames != -1)
02761 {
02762 aFlags = BONE_ANIM_OVERRIDE_LOOP;
02763 }
02764 else
02765 {
02766 aFlags = BONE_ANIM_OVERRIDE_FREEZE;
02767 }
02768
02769 aFlags |= BONE_ANIM_BLEND; //since client defaults to blend. Not sure if this will make much difference if any on client position, but it's here just for the sake of matching them.
02770
02771 if (animSpeed < 0)
02772 {
02773 lastFrame = bgAllAnims[self->localAnimIndex].anims[f].firstFrame;
02774 firstFrame = bgAllAnims[self->localAnimIndex].anims[f].firstFrame + bgAllAnims[self->localAnimIndex].anims[f].numFrames;
02775 }
02776 else
02777 {
02778 firstFrame = bgAllAnims[self->localAnimIndex].anims[f].firstFrame;
02779 lastFrame = bgAllAnims[self->localAnimIndex].anims[f].firstFrame + bgAllAnims[self->localAnimIndex].anims[f].numFrames;
02780 }
02781
02782 trap_G2API_SetBoneAnim(self->ghoul2, 0, "lower_lumbar", firstFrame, lastFrame, aFlags, lAnimSpeedScale, level.time, /*firstFrame why was it this before?*/-1, 150);
02783
02784 self->client->torsoAnimExecute = torsoAnim;
02785 self->client->torsoLastFlip = self->client->ps.torsoFlip;
02786
02787 setTorso = qtrue;
02788 }
02789
02790 if (setTorso &&
02791 self->localAnimIndex <= 1)
02792 { //only set the motion bone for humanoids.
02793 trap_G2API_SetBoneAnim(self->ghoul2, 0, "Motion", firstFrame, lastFrame, aFlags, lAnimSpeedScale, level.time, -1, 150);
02794 }
02795
02796 #if 0 //disabled for now
02797 if (self->client->ps.brokenLimbs != self->client->brokenLimbs ||
02798 setTorso)
02799 {
02800 if (self->localAnimIndex <= 1 && self->client->ps.brokenLimbs &&
02801 (self->client->ps.brokenLimbs & (1 << BROKENLIMB_LARM)))
02802 { //broken left arm
02803 char *brokenBone = "lhumerus";
02804 animation_t *armAnim;
02805 int armFirstFrame;
02806 int armLastFrame;
02807 int armFlags = 0;
02808 float armAnimSpeed;
02809
02810 armAnim = &bgAllAnims[self->localAnimIndex].anims[ BOTH_DEAD21 ];
02811 self->client->brokenLimbs = self->client->ps.brokenLimbs;
02812
02813 armFirstFrame = armAnim->firstFrame;
02814 armLastFrame = armAnim->firstFrame+armAnim->numFrames;
02815 armAnimSpeed = 50.0f / armAnim->frameLerp;
02816 armFlags = (BONE_ANIM_OVERRIDE_LOOP|BONE_ANIM_BLEND);
02817
02818 trap_G2API_SetBoneAnim(self->ghoul2, 0, brokenBone, armFirstFrame, armLastFrame, armFlags, armAnimSpeed, level.time, -1, 150);
02819 }
02820 else if (self->localAnimIndex <= 1 && self->client->ps.brokenLimbs &&
02821 (self->client->ps.brokenLimbs & (1 << BROKENLIMB_RARM)))
02822 { //broken right arm
02823 char *brokenBone = "rhumerus";
02824 char *supportBone = "lhumerus";
02825
02826 self->client->brokenLimbs = self->client->ps.brokenLimbs;
02827
02828 //Only put the arm in a broken pose if the anim is such that we
02829 //want to allow it.
02830 if ((//self->client->ps.weapon == WP_MELEE ||
02831 self->client->ps.weapon != WP_SABER ||
02832 BG_SaberStanceAnim(self->client->ps.torsoAnim) ||
02833 PM_RunningAnim(self->client->ps.torsoAnim)) &&
02834 (!self->client->saber[1].model[0] || self->client->ps.weapon != WP_SABER))
02835 {
02836 int armFirstFrame;
02837 int armLastFrame;
02838 int armFlags = 0;
02839 float armAnimSpeed;
02840 animation_t *armAnim;
02841
02842 if (self->client->ps.weapon == WP_MELEE ||
02843 self->client->ps.weapon == WP_SABER ||
02844 self->client->ps.weapon == WP_BRYAR_PISTOL)
02845 { //don't affect this arm if holding a gun, just make the other arm support it
02846 armAnim = &bgAllAnims[self->localAnimIndex].anims[ BOTH_ATTACK2 ];
02847
02848 //armFirstFrame = armAnim->firstFrame;
02849 armFirstFrame = armAnim->firstFrame+armAnim->numFrames;
02850 armLastFrame = armAnim->firstFrame+armAnim->numFrames;
02851 armAnimSpeed = 50.0f / armAnim->frameLerp;
02852 armFlags = (BONE_ANIM_OVERRIDE_LOOP|BONE_ANIM_BLEND);
02853
02854 trap_G2API_SetBoneAnim(self->ghoul2, 0, brokenBone, armFirstFrame, armLastFrame, armFlags, armAnimSpeed, level.time, -1, 150);
02855 }
02856 else
02857 { //we want to keep the broken bone updated for some cases
02858 trap_G2API_SetBoneAnim(self->ghoul2, 0, brokenBone, firstFrame, lastFrame, aFlags, lAnimSpeedScale, level.time, -1, 150);
02859 }
02860
02861 if (self->client->ps.torsoAnim != BOTH_MELEE1 &&
02862 self->client->ps.torsoAnim != BOTH_MELEE2 &&
02863 (self->client->ps.torsoAnim == TORSO_WEAPONREADY2 || self->client->ps.torsoAnim == BOTH_ATTACK2 || self->client->ps.weapon < WP_BRYAR_PISTOL))
02864 {
02865 //Now set the left arm to "support" the right one
02866 armAnim = &bgAllAnims[self->localAnimIndex].anims[ BOTH_STAND2 ];
02867 armFirstFrame = armAnim->firstFrame;
02868 armLastFrame = armAnim->firstFrame+armAnim->numFrames;
02869 armAnimSpeed = 50.0f / armAnim->frameLerp;
02870 armFlags = (BONE_ANIM_OVERRIDE_LOOP|BONE_ANIM_BLEND);
02871
02872 trap_G2API_SetBoneAnim(self->ghoul2, 0, supportBone, armFirstFrame, armLastFrame, armFlags, armAnimSpeed, level.time, -1, 150);
02873 }
02874 else
02875 { //we want to keep the support bone updated for some cases
02876 trap_G2API_SetBoneAnim(self->ghoul2, 0, supportBone, firstFrame, lastFrame, aFlags, lAnimSpeedScale, level.time, -1, 150);
02877 }
02878 }
02879 else
02880 { //otherwise, keep it set to the same as the torso
02881 trap_G2API_SetBoneAnim(self->ghoul2, 0, brokenBone, firstFrame, lastFrame, aFlags, lAnimSpeedScale, level.time, -1, 150);
02882 trap_G2API_SetBoneAnim(self->ghoul2, 0, supportBone, firstFrame, lastFrame, aFlags, lAnimSpeedScale, level.time, -1, 150);
02883 }
02884 }
02885 else if (self->client->brokenLimbs)
02886 { //remove the bone now so it can be set again
02887 char *brokenBone = NULL;
02888 int broken = 0;
02889
02890 //Warning: Don't remove bones that you've added as bolts unless you want to invalidate your bolt index
02891 //(well, in theory, I haven't actually run into the problem)
02892 if (self->client->brokenLimbs & (1<<BROKENLIMB_LARM))
02893 {
02894 brokenBone = "lhumerus";
02895 broken |= (1<<BROKENLIMB_LARM);
02896 }
02897 else if (self->client->brokenLimbs & (1<<BROKENLIMB_RARM))
02898 { //can only have one arm broken at once.
02899 brokenBone = "rhumerus";
02900 broken |= (1<<BROKENLIMB_RARM);
02901
02902 //want to remove the support bone too then
02903 trap_G2API_SetBoneAnim(self->ghoul2, 0, "lhumerus", 0, 1, 0, 0, level.time, -1, 0);
02904 trap_G2API_RemoveBone(self->ghoul2, "lhumerus", 0);
02905 }
02906
02907 assert(brokenBone);
02908
02909 //Set the flags and stuff to 0, so that the remove will succeed
02910 trap_G2API_SetBoneAnim(self->ghoul2, 0, brokenBone, 0, 1, 0, 0, level.time, -1, 0);
02911
02912 //Now remove it
02913 trap_G2API_RemoveBone(self->ghoul2, brokenBone, 0);
02914 self->client->brokenLimbs &= ~broken;
02915 }
02916 }
02917 #endif
02918 }
|
|
||||||||||||
|
Definition at line 744 of file g_saga.c. References BG_SiegeFindClassIndexByName(), BG_SiegeFindThemeForTeam(), bgSiegeClasses, siegeTeam_t::classes, gentity_s::client, gentity_t, siegeClass_t::name, siegeTeam_t::numClasses, siegeClass_t::playerClass, Q_stricmp(), gclient_s::sess, gclient_s::siegeClass, clientSession_t::siegeClass, and strcpy(). Referenced by ClientUserinfoChanged(), and SetTeamQuick().
00745 {
00746 siegeClass_t *scl;
00747 siegeTeam_t *stm;
00748 int newClassIndex = -1;
00749 if (ent->client->siegeClass == -1)
00750 { //uh.. sure.
00751 return;
00752 }
00753
00754 scl = &bgSiegeClasses[ent->client->siegeClass];
00755
00756 stm = BG_SiegeFindThemeForTeam(team);
00757 if (stm)
00758 {
00759 int i = 0;
00760
00761 while (i < stm->numClasses)
00762 { //go through the team and see its valid classes, can we find one that matches our current player class?
00763 if (stm->classes[i])
00764 {
00765 if (!Q_stricmp(scl->name, stm->classes[i]->name))
00766 { //the class we're using is already ok for this team.
00767 return;
00768 }
00769 if (stm->classes[i]->playerClass == scl->playerClass ||
00770 newClassIndex == -1)
00771 {
00772 newClassIndex = i;
00773 }
00774 }
00775 i++;
00776 }
00777
00778 if (newClassIndex != -1)
00779 { //ok, let's find it in the global class array
00780 ent->client->siegeClass = BG_SiegeFindClassIndexByName(stm->classes[newClassIndex]->name);
00781 strcpy(ent->client->sess.siegeClass, stm->classes[newClassIndex]->name);
00782 }
00783 }
00784 }
|
|
|
Definition at line 23 of file g_session.c. References client, level_locals_t::clients, clientSession_t::duelTeam, gclient_t, level, clientSession_t::losses, clientSession_t::saber2Type, clientSession_t::saberLevel, clientSession_t::saberType, clientSession_t::selectedFP, gclient_s::sess, clientSession_t::sessionTeam, clientSession_t::setForce, clientSession_t::siegeClass, clientSession_t::siegeDesiredTeam, clientSession_t::spectatorClient, clientSession_t::spectatorState, clientSession_t::spectatorTime, strcpy(), clientSession_t::teamLeader, trap_Cvar_Set(), va(), and clientSession_t::wins. Referenced by ClientBegin(), G_InitSessionData(), and G_WriteSessionData().
00023 {
00024 const char *s;
00025 const char *var;
00026 int i = 0;
00027 char siegeClass[64];
00028 char saberType[64];
00029 char saber2Type[64];
00030
00031 strcpy(siegeClass, client->sess.siegeClass);
00032
00033 while (siegeClass[i])
00034 { //sort of a hack.. we don't want spaces by siege class names have spaces so convert them all to unused chars
00035 if (siegeClass[i] == ' ')
00036 {
00037 siegeClass[i] = 1;
00038 }
00039
00040 i++;
00041 }
00042
00043 if (!siegeClass[0])
00044 { //make sure there's at least something
00045 strcpy(siegeClass, "none");
00046 }
00047
00048 //Do the same for the saber
00049 strcpy(saberType, client->sess.saberType);
00050
00051 i = 0;
00052 while (saberType[i])
00053 {
00054 if (saberType[i] == ' ')
00055 {
00056 saberType[i] = 1;
00057 }
00058
00059 i++;
00060 }
00061
00062 strcpy(saber2Type, client->sess.saber2Type);
00063
00064 i = 0;
00065 while (saber2Type[i])
00066 {
00067 if (saber2Type[i] == ' ')
00068 {
00069 saber2Type[i] = 1;
00070 }
00071
00072 i++;
00073 }
00074
00075 s = va("%i %i %i %i %i %i %i %i %i %i %i %i %s %s %s",
00076 client->sess.sessionTeam,
00077 client->sess.spectatorTime,
00078 client->sess.spectatorState,
00079 client->sess.spectatorClient,
00080 client->sess.wins,
00081 client->sess.losses,
00082 client->sess.teamLeader,
00083 client->sess.setForce,
00084 client->sess.saberLevel,
00085 client->sess.selectedFP,
00086 client->sess.duelTeam,
00087 client->sess.siegeDesiredTeam,
00088 siegeClass,
00089 saberType,
00090 saber2Type
00091 );
00092
00093 var = va( "session%i", client - level.clients );
00094
00095 trap_Cvar_Set( var, s );
00096 }
|
|
|
Definition at line 953 of file g_client.c. References BODY_QUEUE_SIZE, level_locals_t::bodyQue, level_locals_t::bodyQueIndex, gentity_s::classname, G_Spawn(), gentity_t, level, gentity_s::neverFree, and qtrue. Referenced by G_InitGame().
00953 {
00954 int i;
00955 gentity_t *ent;
00956
00957 level.bodyQueIndex = 0;
00958 for (i=0; i<BODY_QUEUE_SIZE ; i++) {
00959 ent = G_Spawn();
00960 ent->classname = "bodyque";
00961 ent->neverFree = qtrue;
00962 level.bodyQue[i] = ent;
00963 }
00964 }
|
|
|
Definition at line 346 of file g_client.c. References EF_NODRAW, ET_MISSILE, G_ModelIndex(), G_RunObject(), gentity_t, gJMSaberEnt, JMSABER_RESPAWN_TIME, level, NULL, level_locals_t::time, trap_LinkEntity(), and VectorCopy. Referenced by SP_info_jedimaster_start().
00347 {
00348 gJMSaberEnt = ent;
00349
00350 if (ent->enemy)
00351 {
00352 if (!ent->enemy->client || !ent->enemy->inuse)
00353 { //disconnected?
00354 VectorCopy(ent->enemy->s.pos.trBase, ent->s.pos.trBase);
00355 VectorCopy(ent->enemy->s.pos.trBase, ent->s.origin);
00356 VectorCopy(ent->enemy->s.pos.trBase, ent->r.currentOrigin);
00357 ent->s.modelindex = G_ModelIndex("models/weapons2/saber/saber_w.glm");
00358 ent->s.eFlags &= ~(EF_NODRAW);
00359 ent->s.modelGhoul2 = 1;
00360 ent->s.eType = ET_MISSILE;
00361 ent->enemy = NULL;
00362
00363 ent->pos2[0] = 1;
00364 ent->pos2[1] = 0; //respawn next think
00365 trap_LinkEntity(ent);
00366 }
00367 else
00368 {
00369 ent->pos2[1] = level.time + JMSABER_RESPAWN_TIME;
00370 }
00371 }
00372 else if (ent->pos2[0] && ent->pos2[1] < level.time)
00373 {
00374 VectorCopy(ent->s.origin2, ent->s.pos.trBase);
00375 VectorCopy(ent->s.origin2, ent->s.origin);
00376 VectorCopy(ent->s.origin2, ent->r.currentOrigin);
00377 ent->pos2[0] = 0;
00378 trap_LinkEntity(ent);
00379 }
00380
00381 ent->nextthink = level.time + 50;
00382 G_RunObject(ent);
00383 }
|
|
||||||||||||||||
|
Definition at line 385 of file g_client.c. References gentity_s::client, CS_CLIENT_JEDIMASTER, EF_INVULNERABLE, EF_NODRAW, entityState_s::eFlags, playerState_s::eFlags, gentity_s::enemy, ET_GENERAL, entityState_s::eType, EV_BECOME_JEDIMASTER, playerState_s::fd, FORCE_LEVEL_3, forcedata_s::forcePower, forcedata_s::forcePowerLevel, forcedata_s::forcePowersKnown, G_AddEvent(), G_GetStringEdString(), G_KillG2Queue(), g_spawnInvulnerability, gentity_t, gentity_s::health, vmCvar_t::integer, gclient_s::invulnerableTimer, playerState_s::isJediMaster, JMSABER_RESPAWN_TIME, level, entityState_s::modelGhoul2, entityState_s::modelindex, clientPersistant_t::netname, NUM_FORCE_POWERS, entityState_s::number, gclient_s::pers, gentity_s::pos2, gclient_s::ps, qtrue, gentity_s::s, playerState_s::saberIndex, STAT_HEALTH, STAT_WEAPONS, playerState_s::stats, level_locals_t::time, trap_SendServerCommand(), trap_SetConfigstring(), va(), entityState_s::weapon, playerState_s::weapon, and WP_SABER. Referenced by SP_info_jedimaster_start().
00386 {
00387 int i = 0;
00388 // gentity_t *te;
00389
00390 if (!other || !other->client || other->health < 1)
00391 {
00392 return;
00393 }
00394
00395 if (self->enemy)
00396 {
00397 return;
00398 }
00399
00400 if (!self->s.modelindex)
00401 {
00402 return;
00403 }
00404
00405 if (other->client->ps.stats[STAT_WEAPONS] & (1 << WP_SABER))
00406 {
00407 return;
00408 }
00409
00410 if (other->client->ps.isJediMaster)
00411 {
00412 return;
00413 }
00414
00415 self->enemy = other;
00416 other->client->ps.stats[STAT_WEAPONS] = (1 << WP_SABER);
00417 other->client->ps.weapon = WP_SABER;
00418 other->s.weapon = WP_SABER;
00419 G_AddEvent(other, EV_BECOME_JEDIMASTER, 0);
00420
00421 // Track the jedi master
00422 trap_SetConfigstring ( CS_CLIENT_JEDIMASTER, va("%i", other->s.number ) );
00423
00424 if (g_spawnInvulnerability.integer)
00425 {
00426 other->client->ps.eFlags |= EF_INVULNERABLE;
00427 other->client->invulnerableTimer = level.time + g_spawnInvulnerability.integer;
00428 }
00429
00430 trap_SendServerCommand( -1, va("cp \"%s %s\n\"", other->client->pers.netname, G_GetStringEdString("MP_SVGAME", "BECOMEJM")) );
00431
00432 other->client->ps.isJediMaster = qtrue;
00433 other->client->ps.saberIndex = self->s.number;
00434
00435 if (other->health < 200 && other->health > 0)
00436 { //full health when you become the Jedi Master
00437 other->client->ps.stats[STAT_HEALTH] = other->health = 200;
00438 }
00439
00440 if (other->client->ps.fd.forcePower < 100)
00441 {
00442 other->client->ps.fd.forcePower = 100;
00443 }
00444
00445 while (i < NUM_FORCE_POWERS)
00446 {
00447 other->client->ps.fd.forcePowersKnown |= (1 << i);
00448 other->client->ps.fd.forcePowerLevel[i] = FORCE_LEVEL_3;
00449
00450 i++;
00451 }
00452
00453 self->pos2[0] = 1;
00454 self->pos2[1] = level.time + JMSABER_RESPAWN_TIME;
00455
00456 self->s.modelindex = 0;
00457 self->s.eFlags |= EF_NODRAW;
00458 self->s.modelGhoul2 = 0;
00459 self->s.eType = ET_GENERAL;
00460
00461 /*
00462 te = G_TempEntity( vec3_origin, EV_DESTROY_GHOUL2_INSTANCE );
00463 te->r.svFlags |= SVF_BROADCAST;
00464 te->s.eventParm = self->s.number;
00465 */
00466 G_KillG2Queue(self->s.number);
00467
00468 return;
00469 }
|
|
|
Definition at line 1130 of file g_client.c. References gentity_s::client, entityState_s::clientNum, EF2_SHIP_DEATH, playerState_s::eFlags2, playerState_s::fallingToDeath, gentity_t, level, gclient_s::noCorpse, gclient_s::ps, qboolean, qfalse, qtrue, gentity_s::s, gclient_s::tempSpectate, level_locals_t::time, trap_SendServerCommand(), and va(). Referenced by respawn(), and SetTeam().
01131 { //do whatever should be done taking ragdoll and dismemberment states into account.
01132 qboolean doRCG = qfalse;
01133
01134 assert(ent && ent->client);
01135 if (ent->client->tempSpectate > level.time ||
01136 (ent->client->ps.eFlags2 & EF2_SHIP_DEATH))
01137 {
01138 ent->client->noCorpse = qtrue;
01139 }
01140
01141 if (!ent->client->noCorpse && !ent->client->ps.fallingToDeath)
01142 {
01143 if (!CopyToBodyQue (ent))
01144 {
01145 doRCG = qtrue;
01146 }
01147 }
01148 else
01149 {
01150 ent->client->noCorpse = qfalse; //clear it for next time
01151 ent->client->ps.fallingToDeath = qfalse;
01152 doRCG = qtrue;
01153 }
01154
01155 if (doRCG)
01156 { //bodyque func didn't manage to call ircg so call this to assure our limbs and ragdoll states are proper on the client.
01157 trap_SendServerCommand(-1, va("rcg %i", ent->s.clientNum));
01158 }
01159 }
|
|
|
Definition at line 1291 of file g_client.c. References level, TEAM_BLUE, TEAM_NUM_TEAMS, TEAM_RED, team_t, TeamCount(), and level_locals_t::teamScores. Referenced by ClientBegin(), ClientUserinfoChanged(), G_InitSessionData(), and SetTeam().
01291 {
01292 int counts[TEAM_NUM_TEAMS];
01293
01294 counts[TEAM_BLUE] = TeamCount( ignoreClientNum, TEAM_BLUE );
01295 counts[TEAM_RED] = TeamCount( ignoreClientNum, TEAM_RED );
01296
01297 if ( counts[TEAM_BLUE] > counts[TEAM_RED] ) {
01298 return TEAM_RED;
01299 }
01300 if ( counts[TEAM_RED] > counts[TEAM_BLUE] ) {
01301 return TEAM_BLUE;
01302 }
01303 // equal team count, so join the team with the lowest score
01304 if ( level.teamScores[TEAM_BLUE] > level.teamScores[TEAM_RED] ) {
01305 return TEAM_RED;
01306 }
01307 return TEAM_BLUE;
01308 }
|
|
|
Definition at line 4601 of file bg_pmove.c. References BOTH_RUN1, BOTH_RUN1START, BOTH_RUN1STOP, BOTH_RUN2, BOTH_RUN_DUAL, BOTH_RUN_STAFF, BOTH_RUNBACK1, BOTH_RUNBACK2, BOTH_RUNBACK_DUAL, BOTH_RUNBACK_STAFF, BOTH_RUNSTRAFE_LEFT1, BOTH_RUNSTRAFE_RIGHT1, qboolean, qfalse, and qtrue. Referenced by BG_SetAnimFinal(), G_UpdateClientAnims(), and PM_WeaponLightsaber().
04602 {
04603 switch ( (anim) )
04604 {
04605 case BOTH_RUN1:
04606 case BOTH_RUN2:
04607 case BOTH_RUN_STAFF:
04608 case BOTH_RUN_DUAL:
04609 case BOTH_RUNBACK1:
04610 case BOTH_RUNBACK2:
04611 case BOTH_RUNBACK_STAFF:
04612 case BOTH_RUNBACK_DUAL:
04613 case BOTH_RUN1START: //# Start into full run1
04614 case BOTH_RUN1STOP: //# Stop from full run1
04615 case BOTH_RUNSTRAFE_LEFT1: //# Sidestep left: should loop
04616 case BOTH_RUNSTRAFE_RIGHT1: //# Sidestep right: should loop
04617 return qtrue;
04618 break;
04619 }
04620 return qfalse;
04621 }
|
|
|
||||||||||||||||||||
|
Definition at line 760 of file g_client.c. References entityState_s::angles, DUELTEAM_DOUBLE, DUELTEAM_LONE, DUELTEAM_SINGLE, FOFS, G_Error(), G_Find(), gentity_t, NULL, entityState_s::origin, Q_stricmp(), random, gentity_s::s, SpotWouldTelefrag(), vec3_t, VectorCopy, and VectorSubtract. Referenced by ClientSpawn().
00761 {
00762 gentity_t *spot;
00763 vec3_t delta;
00764 float dist;
00765 float list_dist[64];
00766 gentity_t *list_spot[64];
00767 int numSpots, rnd, i, j;
00768 char *spotName;
00769
00770 if (team == DUELTEAM_LONE)
00771 {
00772 spotName = "info_player_duel1";
00773 }
00774 else if (team == DUELTEAM_DOUBLE)
00775 {
00776 spotName = "info_player_duel2";
00777 }
00778 else if (team == DUELTEAM_SINGLE)
00779 {
00780 spotName = "info_player_duel";
00781 }
00782 else
00783 {
00784 spotName = "info_player_deathmatch";
00785 }
00786 tryAgain:
00787
00788 numSpots = 0;
00789 spot = NULL;
00790
00791 while ((spot = G_Find (spot, FOFS(classname), spotName)) != NULL) {
00792 if ( SpotWouldTelefrag( spot ) ) {
00793 continue;
00794 }
00795 VectorSubtract( spot->s.origin, avoidPoint, delta );
00796 dist = VectorLength( delta );
00797 for (i = 0; i < numSpots; i++) {
00798 if ( dist > list_dist[i] ) {
00799 if ( numSpots >= 64 )
00800 numSpots = 64-1;
00801 for (j = numSpots; j > i; j--) {
00802 list_dist[j] = list_dist[j-1];
00803 list_spot[j] = list_spot[j-1];
00804 }
00805 list_dist[i] = dist;
00806 list_spot[i] = spot;
00807 numSpots++;
00808 if (numSpots > 64)
00809 numSpots = 64;
00810 break;
00811 }
00812 }
00813 if (i >= numSpots && numSpots < 64) {
00814 list_dist[numSpots] = dist;
00815 list_spot[numSpots] = spot;
00816 numSpots++;
00817 }
00818 }
00819 if (!numSpots)
00820 {
00821 if (Q_stricmp(spotName, "info_player_deathmatch"))
00822 { //try the loop again with info_player_deathmatch as the target if we couldn't find a duel spot
00823 spotName = "info_player_deathmatch";
00824 goto tryAgain;
00825 }
00826
00827 //If we got here we found no free duel or DM spots, just try the first DM spot
00828 spot = G_Find( NULL, FOFS(classname), "info_player_deathmatch");
00829 if (!spot)
00830 G_Error( "Couldn't find a spawn point" );
00831 VectorCopy (spot->s.origin, origin);
00832 origin[2] += 9;
00833 VectorCopy (spot->s.angles, angles);
00834 return spot;
00835 }
00836
00837 // select a random spot from the spawn points furthest away
00838 rnd = random() * (numSpots / 2);
00839
00840 VectorCopy (list_spot[rnd]->s.origin, origin);
00841 origin[2] += 9;
00842 VectorCopy (list_spot[rnd]->s.angles, angles);
00843
00844 return list_spot[rnd];
00845 }
|
|
||||||||||||||||
|
Definition at line 894 of file g_client.c. References entityState_s::angles, FOFS, G_Find(), gentity_t, NULL, entityState_s::origin, gentity_s::s, SelectSpawnPoint(), gentity_s::spawnflags, SpotWouldTelefrag(), team_t, vec3_origin, vec3_t, and VectorCopy. Referenced by ClientSpawn().
00894 {
00895 gentity_t *spot;
00896
00897 spot = NULL;
00898 while ((spot = G_Find (spot, FOFS(classname), "info_player_deathmatch")) != NULL) {
00899 if ( spot->spawnflags & 1 ) {
00900 break;
00901 }
00902 }
00903
00904 if ( !spot || SpotWouldTelefrag( spot ) ) {
00905 return SelectSpawnPoint( vec3_origin, origin, angles, team );
00906 }
00907
00908 VectorCopy (spot->s.origin, origin);
00909 origin[2] += 9;
00910 VectorCopy (spot->s.angles, angles);
00911
00912 return spot;
00913 }
|
|
|
Definition at line 590 of file g_client.c. References FOFS, G_Find(), gentity_t, NULL, entityState_s::origin, gentity_s::s, vec3_t, and VectorSubtract.
00590 {
00591 gentity_t *spot;
00592 vec3_t delta;
00593 float dist, nearestDist;
00594 gentity_t *nearestSpot;
00595
00596 nearestDist = 999999;
00597 nearestSpot = NULL;
00598 spot = NULL;
00599
00600 while ((spot = G_Find (spot, FOFS(classname), "info_player_deathmatch")) != NULL) {
00601
00602 VectorSubtract( spot->s.origin, from, delta );
00603 dist = VectorLength( delta );
00604 if ( dist < nearestDist ) {
00605 nearestDist = dist;
00606 nearestSpot = spot;
00607 }
00608 }
00609
00610 return nearestSpot;
00611 }
|
|
|
Definition at line 622 of file g_client.c. References FOFS, G_Find(), gentity_t, MAX_SPAWN_POINTS, NULL, rand(), and SpotWouldTelefrag().
00622 {
00623 gentity_t *spot;
00624 int count;
00625 int selection;
00626 gentity_t *spots[MAX_SPAWN_POINTS];
00627
00628 count = 0;
00629 spot = NULL;
00630
00631 while ((spot = G_Find (spot, FOFS(classname), "info_player_deathmatch")) != NULL) {
00632 if ( SpotWouldTelefrag( spot ) ) {
00633 continue;
00634 }
00635 spots[ count ] = spot;
00636 count++;
00637 }
00638
00639 if ( !count ) { // no spots that won't telefrag
00640 return G_Find( NULL, FOFS(classname), "info_player_deathmatch");
00641 }
00642
00643 selection = rand() % count;
00644 return spots[ selection ];
00645 }
|
|
||||||||||||||||||||
|
Definition at line 654 of file g_client.c. References entityState_s::angles, FOFS, G_Error(), G_Find(), g_gametype, gentity_t, GT_TEAM, vmCvar_t::integer, NULL, entityState_s::origin, random, gentity_s::s, SpotWouldTelefrag(), TEAM_FREE, TEAM_RED, TEAM_SPECTATOR, team_t, vec3_t, VectorCopy, and VectorSubtract. Referenced by SelectSpawnPoint().
00654 {
00655 gentity_t *spot;
00656 vec3_t delta;
00657 float dist;
00658 float list_dist[64];
00659 gentity_t *list_spot[64];
00660 int numSpots, rnd, i, j;
00661
00662 numSpots = 0;
00663 spot = NULL;
00664
00665 //in Team DM, look for a team start spot first, if any
00666 if ( g_gametype.integer == GT_TEAM
00667 && team != TEAM_FREE
00668 && team != TEAM_SPECTATOR )
00669 {
00670 char *classname = NULL;
00671 if ( team == TEAM_RED )
00672 {
00673 classname = "info_player_start_red";
00674 }
00675 else
00676 {
00677 classname = "info_player_start_blue";
00678 }
00679 while ((spot = G_Find (spot, FOFS(classname), classname)) != NULL) {
00680 if ( SpotWouldTelefrag( spot ) ) {
00681 continue;
00682 }
00683 VectorSubtract( spot->s.origin, avoidPoint, delta );
00684 dist = VectorLength( delta );
00685 for (i = 0; i < numSpots; i++) {
00686 if ( dist > list_dist[i] ) {
00687 if ( numSpots >= 64 )
00688 numSpots = 64-1;
00689 for (j = numSpots; j > i; j--) {
00690 list_dist[j] = list_dist[j-1];
00691 list_spot[j] = list_spot[j-1];
00692 }
00693 list_dist[i] = dist;
00694 list_spot[i] = spot;
00695 numSpots++;
00696 if (numSpots > 64)
00697 numSpots = 64;
00698 break;
00699 }
00700 }
00701 if (i >= numSpots && numSpots < 64) {
00702 list_dist[numSpots] = dist;
00703 list_spot[numSpots] = spot;
00704 numSpots++;
00705 }
00706 }
00707 }
00708
00709 if ( !numSpots )
00710 {//couldn't find any of the above
00711 while ((spot = G_Find (spot, FOFS(classname), "info_player_deathmatch")) != NULL) {
00712 if ( SpotWouldTelefrag( spot ) ) {
00713 continue;
00714 }
00715 VectorSubtract( spot->s.origin, avoidPoint, delta );
00716 dist = VectorLength( delta );
00717 for (i = 0; i < numSpots; i++) {
00718 if ( dist > list_dist[i] ) {
00719 if ( numSpots >= 64 )
00720 numSpots = 64-1;
00721 for (j = numSpots; j > i; j--) {
00722 list_dist[j] = list_dist[j-1];
00723 list_spot[j] = list_spot[j-1];
00724 }
00725 list_dist[i] = dist;
00726 list_spot[i] = spot;
00727 numSpots++;
00728 if (numSpots > 64)
00729 numSpots = 64;
00730 break;
00731 }
00732 }
00733 if (i >= numSpots && numSpots < 64) {
00734 list_dist[numSpots] = dist;
00735 list_spot[numSpots] = spot;
00736 numSpots++;
00737 }
00738 }
00739 if (!numSpots) {
00740 spot = G_Find( NULL, FOFS(classname), "info_player_deathmatch");
00741 if (!spot)
00742 G_Error( "Couldn't find a spawn point" );
00743 VectorCopy (spot->s.origin, origin);
00744 origin[2] += 9;
00745 VectorCopy (spot->s.angles, angles);
00746 return spot;
00747 }
00748 }
00749
00750 // select a random spot from the spawn points furthest away
00751 rnd = random() * (numSpots / 2);
00752
00753 VectorCopy (list_spot[rnd]->s.origin, origin);
00754 origin[2] += 9;
00755 VectorCopy (list_spot[rnd]->s.angles, angles);
00756
00757 return list_spot[rnd];
00758 }
|
|
||||||||||||||||||||
|
Definition at line 854 of file g_client.c. References gentity_t, SelectRandomFurthestSpawnPoint(), team_t, and vec3_t. Referenced by ClientSpawn(), FindIntermissionPoint(), SelectCTFSpawnPoint(), SelectInitialSpawnPoint(), and SelectSiegeSpawnPoint().
00854 {
00855 return SelectRandomFurthestSpawnPoint( avoidPoint, origin, angles, team );
00856
00857 /*
00858 gentity_t *spot;
00859 gentity_t *nearestSpot;
00860
00861 nearestSpot = SelectNearestDeathmatchSpawnPoint( avoidPoint );
00862
00863 spot = SelectRandomDeathmatchSpawnPoint ( );
00864 if ( spot == nearestSpot ) {
00865 // roll again if it would be real close to point of death
00866 spot = SelectRandomDeathmatchSpawnPoint ( );
00867 if ( spot == nearestSpot ) {
00868 // last try
00869 spot = SelectRandomDeathmatchSpawnPoint ( );
00870 }
00871 }
00872
00873 // find a single player start spot
00874 if (!spot) {
00875 G_Error( "Couldn't find a spawn point" );
00876 }
00877
00878 VectorCopy (spot->s.origin, origin);
00879 origin[2] += 9;
00880 VectorCopy (spot->s.angles, angles);
00881
00882 return spot;
00883 */
00884 }
|
|
||||||||||||
|
Definition at line 921 of file g_client.c. References FindIntermissionPoint(), gentity_t, level_locals_t::intermission_angle, level_locals_t::intermission_origin, level, NULL, vec3_t, and VectorCopy. Referenced by ClientSpawn().
00921 {
00922 FindIntermissionPoint();
00923
00924 VectorCopy( level.intermission_origin, origin );
00925 VectorCopy( level.intermission_angle, angles );
00926
00927 return NULL;
00928 }
|
|
||||||||||||
|
Definition at line 1116 of file g_client.c. References ANGLE2SHORT, usercmd_s::angles, entityState_s::angles, gentity_s::client, clientPersistant_t::cmd, playerState_s::delta_angles, gentity_t, gclient_s::pers, gclient_s::ps, gentity_s::s, vec3_t, VectorCopy, and playerState_s::viewangles. Referenced by Board(), ClientCommand(), ClientSpawn(), ClientThink_real(), Eject(), G_HeldByMonster(), misc_weapon_shooter_aim(), NPC_Begin(), NPC_Spawn_Do(), Rancor_DropVictim(), TeleportPlayer(), and WP_SaberPositionUpdate().
01116 {
01117 int i;
01118
01119 // set the delta angle
01120 for (i=0 ; i<3 ; i++) {
01121 int cmdAngle;
01122
01123 cmdAngle = ANGLE2SHORT(angle[i]);
01124 ent->client->ps.delta_angles[i] = cmdAngle - ent->client->pers.cmd.angles[i];
01125 }
01126 VectorCopy( angle, ent->s.angles );
01127 VectorCopy (ent->s.angles, ent->client->ps.viewangles);
01128 }
|
|
||||||||||||||||
|
||||||||||||||||