#include "cg_local.h"Go to the source code of this file.
Functions | |
| void | CG_CheckAmmo (void) |
| void | CG_DamageFeedback (int yawByte, int pitchByte, int damage) |
| void | CG_Respawn (void) |
| void | CG_CheckPlayerstateEvents (playerState_t *ps, playerState_t *ops) |
| void | CG_CheckChangedPredictableEvents (playerState_t *ps) |
| void | CG_CheckLocalSounds (playerState_t *ps, playerState_t *ops) |
| void | CG_TransitionPlayerState (playerState_t *ps, playerState_t *ops) |
Variables | |
| char * | eventnames [] |
| int | cgAnnouncerTime = 0 |
|
|
Definition at line 17 of file cg_playerstate.c. References playerState_s::ammo, weaponData_s::ammoIndex, cg, cgs, CHAN_LOCAL_SOUND, cg_t::lowAmmoWarning, cgs_t::media, cgMedia_t::noAmmoSound, snapshot_t::ps, cg_t::snap, STAT_WEAPONS, playerState_s::stats, trap_S_StartLocalSound(), playerState_s::weapon, weaponData, WP_BLASTER, WP_BOWCASTER, WP_BRYAR_OLD, WP_BRYAR_PISTOL, WP_CONCUSSION, WP_DEMP2, WP_DET_PACK, WP_DISRUPTOR, WP_EMPLACED_GUN, WP_FLECHETTE, WP_NUM_WEAPONS, WP_REPEATER, WP_ROCKET_LAUNCHER, WP_SABER, WP_THERMAL, and WP_TRIP_MINE. Referenced by CG_TransitionPlayerState().
00017 {
00018 #if 0
00019 int i;
00020 int total;
00021 int previous;
00022 int weapons;
00023
00024 // see about how many seconds of ammo we have remaining
00025 weapons = cg.snap->ps.stats[ STAT_WEAPONS ];
00026 total = 0;
00027 for ( i = WP_BRYAR_PISTOL; i < WP_NUM_WEAPONS ; i++ ) {
00028 if ( ! ( weapons & ( 1 << i ) ) ) {
00029 continue;
00030 }
00031 switch ( i )
00032 {
00033 case WP_BRYAR_PISTOL:
00034 case WP_CONCUSSION:
00035 case WP_BRYAR_OLD:
00036 case WP_BLASTER:
00037 case WP_DISRUPTOR:
00038 case WP_BOWCASTER:
00039 case WP_REPEATER:
00040 case WP_DEMP2:
00041 case WP_FLECHETTE:
00042 case WP_ROCKET_LAUNCHER:
00043 case WP_THERMAL:
00044 case WP_TRIP_MINE:
00045 case WP_DET_PACK:
00046 case WP_EMPLACED_GUN:
00047 total += cg.snap->ps.ammo[weaponData[i].ammoIndex] * 1000;
00048 break;
00049 default:
00050 total += cg.snap->ps.ammo[weaponData[i].ammoIndex] * 200;
00051 break;
00052 }
00053 if ( total >= 5000 ) {
00054 cg.lowAmmoWarning = 0;
00055 return;
00056 }
00057 }
00058
00059 previous = cg.lowAmmoWarning;
00060
00061 if ( total == 0 ) {
00062 cg.lowAmmoWarning = 2;
00063 } else {
00064 cg.lowAmmoWarning = 1;
00065 }
00066
00067 if (cg.snap->ps.weapon == WP_SABER)
00068 {
00069 cg.lowAmmoWarning = 0;
00070 }
00071
00072 // play a sound on transitions
00073 if ( cg.lowAmmoWarning != previous ) {
00074 trap_S_StartLocalSound( cgs.media.noAmmoSound, CHAN_LOCAL_SOUND );
00075 }
00076 #endif
00077 //disabled silly ammo warning stuff for now
00078 }
|
|
|
Definition at line 257 of file cg_playerstate.c. References centity_t, cg, cg_entities, CG_EntityEvent(), CG_Printf(), cg_showmiss, playerState_s::clientNum, centity_s::currentState, entityState_s::event, entityState_s::eventParm, playerState_s::eventParms, playerState_s::events, cg_t::eventSequence, playerState_s::eventSequence, vmCvar_t::integer, centity_s::lerpOrigin, MAX_PREDICTED_EVENTS, MAX_PS_EVENTS, playerState_t, and cg_t::predictableEvents.
00257 {
00258 int i;
00259 int event;
00260 centity_t *cent;
00261
00262 cent = &cg_entities[ps->clientNum];
00263 for ( i = ps->eventSequence - MAX_PS_EVENTS ; i < ps->eventSequence ; i++ ) {
00264 //
00265 if (i >= cg.eventSequence) {
00266 continue;
00267 }
00268 // if this event is not further back in than the maximum predictable events we remember
00269 if (i > cg.eventSequence - MAX_PREDICTED_EVENTS) {
00270 // if the new playerstate event is different from a previously predicted one
00271 if ( ps->events[i & (MAX_PS_EVENTS-1)] != cg.predictableEvents[i & (MAX_PREDICTED_EVENTS-1) ] ) {
00272
00273 event = ps->events[ i & (MAX_PS_EVENTS-1) ];
00274 cent->currentState.event = event;
00275 cent->currentState.eventParm = ps->eventParms[ i & (MAX_PS_EVENTS-1) ];
00276 CG_EntityEvent( cent, cent->lerpOrigin );
00277
00278 cg.predictableEvents[ i & (MAX_PREDICTED_EVENTS-1) ] = event;
00279
00280 if ( cg_showmiss.integer ) {
00281 CG_Printf("WARNING: changed predicted event\n");
00282 }
00283 }
00284 }
00285 }
00286 }
|
|
||||||||||||
|
Definition at line 311 of file cg_playerstate.c. References cg, CG_AddBufferedSound(), cg_entities, cg_oldPainSounds, CG_PainEvent(), cgAnnouncerTime, cgs, CHAN_ANNOUNCER, playerState_s::clientNum, cgMedia_t::fiveMinuteSound, cgs_t::fraglimit, cg_t::fraglimitWarnings, cgs_t::gametype, GT_CTF, GT_DUEL, GT_POWERDUEL, GT_SIEGE, GT_TEAM, vmCvar_t::integer, cg_t::intermissionStarted, cgs_t::levelStartTime, cgs_t::media, cgMedia_t::oneFragSound, cgMedia_t::oneMinuteSound, PERS_ASSIST_COUNT, PERS_ATTACKEE_ARMOR, PERS_CAPTURES, PERS_DEFEND_COUNT, PERS_EXCELLENT_COUNT, PERS_GAUNTLET_FRAG_COUNT, PERS_HITS, PERS_IMPRESSIVE_COUNT, PERS_PLAYEREVENTS, PERS_RANK, PERS_TEAM, playerState_s::persistant, PLAYEREVENT_DENIEDREWARD, PLAYEREVENT_GAUNTLETREWARD, playerState_t, cg_t::predictedPlayerState, qfalse, qtrue, cgs_t::scores1, sfxHandle_t, STAT_HEALTH, playerState_s::stats, cgMedia_t::threeFragSound, cg_t::time, cgs_t::timelimit, cg_t::timelimitWarnings, trap_S_StartLocalSound(), cgMedia_t::twoFragSound, and cg_t::warmup. Referenced by CG_TransitionPlayerState().
00311 {
00312 int highScore, health, armor, reward;
00313 #ifdef JK2AWARDS
00314 sfxHandle_t sfx;
00315 #endif
00316
00317 // don't play the sounds if the player just changed teams
00318 if ( ps->persistant[PERS_TEAM] != ops->persistant[PERS_TEAM] ) {
00319 return;
00320 }
00321
00322 // hit changes
00323 if ( ps->persistant[PERS_HITS] > ops->persistant[PERS_HITS] ) {
00324 armor = ps->persistant[PERS_ATTACKEE_ARMOR] & 0xff;
00325 health = ps->persistant[PERS_ATTACKEE_ARMOR] >> 8;
00326
00327 if (armor > health/2)
00328 { // We also hit shields along the way, so consider them "pierced".
00329 // trap_S_StartLocalSound( cgs.media.shieldPierceSound, CHAN_LOCAL_SOUND );
00330 }
00331 else
00332 { // Shields didn't really stand in our way.
00333 // trap_S_StartLocalSound( cgs.media.hitSound, CHAN_LOCAL_SOUND );
00334 }
00335
00336 //FIXME: Hit sounds?
00337 /*
00338 if (armor > 50 ) {
00339 trap_S_StartLocalSound( cgs.media.hitSoundHighArmor, CHAN_LOCAL_SOUND );
00340 } else if (armor || health > 100) {
00341 trap_S_StartLocalSound( cgs.media.hitSoundLowArmor, CHAN_LOCAL_SOUND );
00342 } else {
00343 trap_S_StartLocalSound( cgs.media.hitSound, CHAN_LOCAL_SOUND );
00344 }
00345 */
00346 } else if ( ps->persistant[PERS_HITS] < ops->persistant[PERS_HITS] ) {
00347 //trap_S_StartLocalSound( cgs.media.hitTeamSound, CHAN_LOCAL_SOUND );
00348 }
00349
00350 // health changes of more than -3 should make pain sounds
00351 if (cg_oldPainSounds.integer)
00352 {
00353 if ( ps->stats[STAT_HEALTH] < (ops->stats[STAT_HEALTH] - 3))
00354 {
00355 if ( ps->stats[STAT_HEALTH] > 0 )
00356 {
00357 CG_PainEvent( &cg_entities[cg.predictedPlayerState.clientNum], ps->stats[STAT_HEALTH] );
00358 }
00359 }
00360 }
00361
00362 // if we are going into the intermission, don't start any voices
00363 if ( cg.intermissionStarted ) {
00364 return;
00365 }
00366
00367 #ifdef JK2AWARDS
00368 // reward sounds
00369 reward = qfalse;
00370 if (ps->persistant[PERS_CAPTURES] != ops->persistant[PERS_CAPTURES]) {
00371 pushReward(cgs.media.captureAwardSound, cgs.media.medalCapture, ps->persistant[PERS_CAPTURES]);
00372 reward = qtrue;
00373 //Com_Printf("capture\n");
00374 }
00375 if (ps->persistant[PERS_IMPRESSIVE_COUNT] != ops->persistant[PERS_IMPRESSIVE_COUNT]) {
00376 sfx = cgs.media.impressiveSound;
00377
00378 pushReward(sfx, cgs.media.medalImpressive, ps->persistant[PERS_IMPRESSIVE_COUNT]);
00379 reward = qtrue;
00380 //Com_Printf("impressive\n");
00381 }
00382 if (ps->persistant[PERS_EXCELLENT_COUNT] != ops->persistant[PERS_EXCELLENT_COUNT]) {
00383 sfx = cgs.media.excellentSound;
00384 pushReward(sfx, cgs.media.medalExcellent, ps->persistant[PERS_EXCELLENT_COUNT]);
00385 reward = qtrue;
00386 //Com_Printf("excellent\n");
00387 }
00388 if (ps->persistant[PERS_GAUNTLET_FRAG_COUNT] != ops->persistant[PERS_GAUNTLET_FRAG_COUNT]) {
00389 sfx = cgs.media.humiliationSound;
00390 pushReward(sfx, cgs.media.medalGauntlet, ps->persistant[PERS_GAUNTLET_FRAG_COUNT]);
00391 reward = qtrue;
00392 //Com_Printf("guantlet frag\n");
00393 }
00394 if (ps->persistant[PERS_DEFEND_COUNT] != ops->persistant[PERS_DEFEND_COUNT]) {
00395 pushReward(cgs.media.defendSound, cgs.media.medalDefend, ps->persistant[PERS_DEFEND_COUNT]);
00396 reward = qtrue;
00397 //Com_Printf("defend\n");
00398 }
00399 if (ps->persistant[PERS_ASSIST_COUNT] != ops->persistant[PERS_ASSIST_COUNT]) {
00400 //pushReward(cgs.media.assistSound, cgs.media.medalAssist, ps->persistant[PERS_ASSIST_COUNT]);
00401 //reward = qtrue;
00402 //Com_Printf("assist\n");
00403 }
00404 // if any of the player event bits changed
00405 if (ps->persistant[PERS_PLAYEREVENTS] != ops->persistant[PERS_PLAYEREVENTS]) {
00406 if ((ps->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_DENIEDREWARD) !=
00407 (ops->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_DENIEDREWARD)) {
00408 trap_S_StartLocalSound( cgs.media.deniedSound, CHAN_ANNOUNCER );
00409 }
00410 else if ((ps->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_GAUNTLETREWARD) !=
00411 (ops->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_GAUNTLETREWARD)) {
00412 trap_S_StartLocalSound( cgs.media.humiliationSound, CHAN_ANNOUNCER );
00413 }
00414 reward = qtrue;
00415 }
00416 #else
00417 reward = qfalse;
00418 #endif
00419 // lead changes
00420 if (!reward && cgAnnouncerTime < cg.time) {
00421 //
00422 if ( !cg.warmup && cgs.gametype != GT_POWERDUEL ) {
00423 // never play lead changes during warmup and powerduel
00424 if ( ps->persistant[PERS_RANK] != ops->persistant[PERS_RANK] ) {
00425 if ( cgs.gametype < GT_TEAM) {
00426 /*
00427 if ( ps->persistant[PERS_RANK] == 0 ) {
00428 CG_AddBufferedSound(cgs.media.takenLeadSound);
00429 cgAnnouncerTime = cg.time + 3000;
00430 } else if ( ps->persistant[PERS_RANK] == RANK_TIED_FLAG ) {
00431 //CG_AddBufferedSound(cgs.media.tiedLeadSound);
00432 } else if ( ( ops->persistant[PERS_RANK] & ~RANK_TIED_FLAG ) == 0 ) {
00433 //rww - only bother saying this if you have more than 1 kill already.
00434 //joining the server and hearing "the force is not with you" is silly.
00435 if (ps->persistant[PERS_SCORE] > 0)
00436 {
00437 CG_AddBufferedSound(cgs.media.lostLeadSound);
00438 cgAnnouncerTime = cg.time + 3000;
00439 }
00440 }
00441 */
00442 }
00443 }
00444 }
00445 }
00446
00447 // timelimit warnings
00448 if ( cgs.timelimit > 0 && cgAnnouncerTime < cg.time ) {
00449 int msec;
00450
00451 msec = cg.time - cgs.levelStartTime;
00452 if ( !( cg.timelimitWarnings & 4 ) && msec > ( cgs.timelimit * 60 + 2 ) * 1000 ) {
00453 cg.timelimitWarnings |= 1 | 2 | 4;
00454 //trap_S_StartLocalSound( cgs.media.suddenDeathSound, CHAN_ANNOUNCER );
00455 }
00456 else if ( !( cg.timelimitWarnings & 2 ) && msec > (cgs.timelimit - 1) * 60 * 1000 ) {
00457 cg.timelimitWarnings |= 1 | 2;
00458 trap_S_StartLocalSound( cgs.media.oneMinuteSound, CHAN_ANNOUNCER );
00459 cgAnnouncerTime = cg.time + 3000;
00460 }
00461 else if ( cgs.timelimit > 5 && !( cg.timelimitWarnings & 1 ) && msec > (cgs.timelimit - 5) * 60 * 1000 ) {
00462 cg.timelimitWarnings |= 1;
00463 trap_S_StartLocalSound( cgs.media.fiveMinuteSound, CHAN_ANNOUNCER );
00464 cgAnnouncerTime = cg.time + 3000;
00465 }
00466 }
00467
00468 // fraglimit warnings
00469 if ( cgs.fraglimit > 0 && cgs.gametype < GT_CTF && cgs.gametype != GT_DUEL && cgs.gametype != GT_POWERDUEL && cgs.gametype != GT_SIEGE && cgAnnouncerTime < cg.time) {
00470 highScore = cgs.scores1;
00471 if ( !( cg.fraglimitWarnings & 4 ) && highScore == (cgs.fraglimit - 1) ) {
00472 cg.fraglimitWarnings |= 1 | 2 | 4;
00473 CG_AddBufferedSound(cgs.media.oneFragSound);
00474 cgAnnouncerTime = cg.time + 3000;
00475 }
00476 else if ( cgs.fraglimit > 2 && !( cg.fraglimitWarnings & 2 ) && highScore == (cgs.fraglimit - 2) ) {
00477 cg.fraglimitWarnings |= 1 | 2;
00478 CG_AddBufferedSound(cgs.media.twoFragSound);
00479 cgAnnouncerTime = cg.time + 3000;
00480 }
00481 else if ( cgs.fraglimit > 3 && !( cg.fraglimitWarnings & 1 ) && highScore == (cgs.fraglimit - 3) ) {
00482 cg.fraglimitWarnings |= 1;
00483 CG_AddBufferedSound(cgs.media.threeFragSound);
00484 cgAnnouncerTime = cg.time + 3000;
00485 }
00486 }
00487 }
|
|
||||||||||||
|
Definition at line 217 of file cg_playerstate.c. References centity_t, cg, cg_entities, CG_EntityEvent(), playerState_s::clientNum, centity_s::currentState, entityState_s::event, entityState_s::eventParm, playerState_s::eventParms, playerState_s::events, cg_t::eventSequence, playerState_s::eventSequence, playerState_s::externalEvent, playerState_s::externalEventParm, centity_s::lerpOrigin, MAX_PREDICTED_EVENTS, MAX_PS_EVENTS, centity_s::playerState, playerState_t, and cg_t::predictableEvents. Referenced by CG_TransitionPlayerState().
00217 {
00218 int i;
00219 int event;
00220 centity_t *cent;
00221
00222 if ( ps->externalEvent && ps->externalEvent != ops->externalEvent ) {
00223 cent = &cg_entities[ ps->clientNum ];
00224 cent->currentState.event = ps->externalEvent;
00225 cent->currentState.eventParm = ps->externalEventParm;
00226 CG_EntityEvent( cent, cent->lerpOrigin );
00227 }
00228
00229 cent = &cg_entities[ ps->clientNum ];
00230 // go through the predictable events buffer
00231 for ( i = ps->eventSequence - MAX_PS_EVENTS ; i < ps->eventSequence ; i++ ) {
00232 // if we have a new predictable event
00233 if ( i >= ops->eventSequence
00234 // or the server told us to play another event instead of a predicted event we already issued
00235 // or something the server told us changed our prediction causing a different event
00236 || (i > ops->eventSequence - MAX_PS_EVENTS && ps->events[i & (MAX_PS_EVENTS-1)] != ops->events[i & (MAX_PS_EVENTS-1)]) ) {
00237
00238 event = ps->events[ i & (MAX_PS_EVENTS-1) ];
00239 cent->currentState.event = event;
00240 cent->currentState.eventParm = ps->eventParms[ i & (MAX_PS_EVENTS-1) ];
00241 //JLF ADDED to hopefully mark events as player event
00242 cent->playerState = ps;
00243 CG_EntityEvent( cent, cent->lerpOrigin );
00244
00245 cg.predictableEvents[ i & (MAX_PREDICTED_EVENTS-1) ] = event;
00246
00247 cg.eventSequence++;
00248 }
00249 }
00250 }
|
|
||||||||||||||||
|
Definition at line 85 of file cg_playerstate.c. References AngleVectors(), cg_t::attackerTime, cg, DAMAGE_TIME, cg_t::damageTime, cg_t::damageValue, cg_t::damageX, cg_t::damageY, DotProduct, NULL, PITCH, snapshot_t::ps, cg_t::refdef, ROLL, snapshot_t::serverTime, cg_t::snap, STAT_HEALTH, playerState_s::stats, cg_t::time, cg_t::v_dmg_pitch, cg_t::v_dmg_roll, cg_t::v_dmg_time, vec3_origin, vec3_t, VectorSubtract, refdef_t::viewaxis, and YAW. Referenced by CG_TransitionPlayerState().
00085 {
00086 float left, front, up;
00087 float kick;
00088 int health;
00089 float scale;
00090 vec3_t dir;
00091 vec3_t angles;
00092 float dist;
00093 float yaw, pitch;
00094
00095 // show the attacking player's head and name in corner
00096 cg.attackerTime = cg.time;
00097
00098 // the lower on health you are, the greater the view kick will be
00099 health = cg.snap->ps.stats[STAT_HEALTH];
00100 if ( health < 40 ) {
00101 scale = 1;
00102 } else {
00103 scale = 40.0 / health;
00104 }
00105 kick = damage * scale;
00106
00107 if (kick < 5)
00108 kick = 5;
00109 if (kick > 10)
00110 kick = 10;
00111
00112 // if yaw and pitch are both 255, make the damage always centered (falling, etc)
00113 if ( yawByte == 255 && pitchByte == 255 ) {
00114 cg.damageX = 0;
00115 cg.damageY = 0;
00116 cg.v_dmg_roll = 0;
00117 cg.v_dmg_pitch = -kick;
00118 } else {
00119 // positional
00120 pitch = pitchByte / 255.0 * 360;
00121 yaw = yawByte / 255.0 * 360;
00122
00123 angles[PITCH] = pitch;
00124 angles[YAW] = yaw;
00125 angles[ROLL] = 0;
00126
00127 AngleVectors( angles, dir, NULL, NULL );
00128 VectorSubtract( vec3_origin, dir, dir );
00129
00130 front = DotProduct (dir, cg.refdef.viewaxis[0] );
00131 left = DotProduct (dir, cg.refdef.viewaxis[1] );
00132 up = DotProduct (dir, cg.refdef.viewaxis[2] );
00133
00134 dir[0] = front;
00135 dir[1] = left;
00136 dir[2] = 0;
00137 dist = VectorLength( dir );
00138 if ( dist < 0.1 ) {
00139 dist = 0.1f;
00140 }
00141
00142 cg.v_dmg_roll = kick * left;
00143
00144 cg.v_dmg_pitch = -kick * front;
00145
00146 if ( front <= 0.1 ) {
00147 front = 0.1f;
00148 }
00149 cg.damageX = -left / front;
00150 cg.damageY = up / dist;
00151 }
00152
00153 // clamp the position
00154 if ( cg.damageX > 1.0 ) {
00155 cg.damageX = 1.0;
00156 }
00157 if ( cg.damageX < - 1.0 ) {
00158 cg.damageX = -1.0;
00159 }
00160
00161 if ( cg.damageY > 1.0 ) {
00162 cg.damageY = 1.0;
00163 }
00164 if ( cg.damageY < - 1.0 ) {
00165 cg.damageY = -1.0;
00166 }
00167
00168 // don't let the screen flashes vary as much
00169 if ( kick > 10 ) {
00170 kick = 10;
00171 }
00172 cg.damageValue = kick;
00173 cg.v_dmg_time = cg.time + DAMAGE_TIME;
00174 cg.damageTime = cg.snap->serverTime;
00175
00176 //JLFRUMBLE
00177 #ifdef _XBOX
00178 extern void FF_XboxShake(float intensity, int duration);
00179 extern void FF_XboxDamage(int damage, float xpos);
00180
00181 //FF_XboxShake(kick, 500);
00182 FF_XboxDamage(damage, -left);
00183
00184
00185 #endif
00186
00187 }
|
|
|
Definition at line 199 of file cg_playerstate.c. References cg, snapshot_t::ps, qtrue, cg_t::snap, cg_t::thisFrameTeleport, cg_t::time, playerState_s::weapon, cg_t::weaponSelect, and cg_t::weaponSelectTime. Referenced by CG_SetInitialSnapshot(), and CG_TransitionPlayerState().
00199 {
00200 // no error decay on player movement
00201 cg.thisFrameTeleport = qtrue;
00202
00203 // display weapons available
00204 cg.weaponSelectTime = cg.time;
00205
00206 // select the weapon the server says we are using
00207 cg.weaponSelect = cg.snap->ps.weapon;
00208 }
|
|
||||||||||||
|
|
Definition at line 304 of file cg_playerstate.c. Referenced by CG_CheckLocalSounds(). |
|
|
Definition at line 210 of file cg_playerstate.c. Referenced by BG_AddPredictableEventToPlayerstate(). |