diff options
Diffstat (limited to 'src/cgame')
-rw-r--r-- | src/cgame/cg_buildable.c | 7 | ||||
-rw-r--r-- | src/cgame/cg_consolecmds.c | 8 | ||||
-rw-r--r-- | src/cgame/cg_draw.c | 11 | ||||
-rw-r--r-- | src/cgame/cg_ents.c | 104 | ||||
-rw-r--r-- | src/cgame/cg_event.c | 100 | ||||
-rw-r--r-- | src/cgame/cg_local.h | 3 | ||||
-rw-r--r-- | src/cgame/cg_main.c | 9 | ||||
-rw-r--r-- | src/cgame/cg_public.h | 6 | ||||
-rw-r--r-- | src/cgame/cg_tutorial.c | 38 | ||||
-rw-r--r-- | src/cgame/cg_view.c | 19 | ||||
-rw-r--r-- | src/cgame/cg_weapons.c | 23 |
11 files changed, 206 insertions, 122 deletions
diff --git a/src/cgame/cg_buildable.c b/src/cgame/cg_buildable.c index b8d03a48..0a1f3877 100644 --- a/src/cgame/cg_buildable.c +++ b/src/cgame/cg_buildable.c @@ -904,6 +904,7 @@ static void CG_BuildableStatusDisplay( centity_t *cent ) qboolean visible = qfalse; vec3_t mins, maxs; entityState_t *hit; + int anim; if( BG_FindTeamForBuildable( es->modelindex ) == BIT_ALIENS ) bs = &cgs.alienBuildStat; @@ -922,6 +923,12 @@ static void CG_BuildableStatusDisplay( centity_t *cent ) // trace for center point BG_FindBBoxForBuildable( es->modelindex, mins, maxs ); + // hack for shrunken barricades + anim = es->torsoAnim & ~( ANIM_FORCEBIT | ANIM_TOGGLEBIT ); + if( es->modelindex == BA_A_BARRICADE && + ( anim == BANIM_DESTROYED || !( es->generic1 & B_SPAWNED_TOGGLEBIT ) ) ) + maxs[ 2 ] = (int)( maxs[ 2 ] * BARRICADE_SHRINKPROP ); + VectorCopy( cent->lerpOrigin, origin ); // center point diff --git a/src/cgame/cg_consolecmds.c b/src/cgame/cg_consolecmds.c index a44a5497..697b0e98 100644 --- a/src/cgame/cg_consolecmds.c +++ b/src/cgame/cg_consolecmds.c @@ -279,10 +279,10 @@ void CG_InitConsoleCommands( void ) // forwarded to the server after they are not recognized locally // trap_AddCommand( "kill" ); - trap_AddCommand( "messagemode" ); - trap_AddCommand( "messagemode2" ); - trap_AddCommand( "messagemode3" ); - trap_AddCommand( "messagemode4" ); + trap_AddCommand( "ui_messagemode" ); + trap_AddCommand( "ui_messagemode2" ); + trap_AddCommand( "ui_messagemode3" ); + trap_AddCommand( "ui_messagemode4" ); trap_AddCommand( "say" ); trap_AddCommand( "say_team" ); trap_AddCommand( "tell" ); diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c index 47e7d477..c8f75da0 100644 --- a/src/cgame/cg_draw.c +++ b/src/cgame/cg_draw.c @@ -593,14 +593,15 @@ CG_DrawPlayerBoosterBolt static void CG_DrawPlayerBoosterBolt( rectDef_t *rect, vec4_t color, qhandle_t shader ) { vec4_t localColor; + playerState_t *ps = &cg.snap->ps; Vector4Copy( color, localColor ); - if( cg.boostedTime >= 0 ) + if( ps->stats[ STAT_STATE ] & SS_BOOSTED ) { - if( ( cg.time - cg.boostedTime ) > BOOST_TIME - 3000 ) + if( ps->stats[ STAT_MISC2 ] < 3000 ) { - qboolean flash = ( cg.time / 500 ) % 2; + qboolean flash = ( ps->stats[ STAT_MISC2 ] / 500 ) % 2; if( flash ) localColor[ 3 ] = 1.0f; @@ -1986,7 +1987,7 @@ static void CG_DrawCrosshair( void ) wi = &cg_weapons[ cg.snap->ps.weapon ]; - w = h = wi->crossHairSize; + w = h = wi->crossHairSize * cg_crosshairSize.value; w *= cgDC.aspectScale; @@ -3017,5 +3018,3 @@ void CG_DrawActive( stereoFrame_t stereoView ) CG_Draw2D( ); } - - diff --git a/src/cgame/cg_ents.c b/src/cgame/cg_ents.c index 17f1a7d3..c6597b6b 100644 --- a/src/cgame/cg_ents.c +++ b/src/cgame/cg_ents.c @@ -216,6 +216,8 @@ Add continuous entity effects, like local entity emission and lighting */ static void CG_EntityEffects( centity_t *cent ) { + int i; + // update sound origins CG_SetEntitySoundPosition( cent ); @@ -251,7 +253,7 @@ static void CG_EntityEffects( centity_t *cent ) if( CG_IsTrailSystemValid( ¢->muzzleTS ) ) { - //FIXME hack to prevent tesla trails reaching too far + //FIXME hack to prevent tesla trails reaching too far if( cent->currentState.eType == ET_BUILDABLE ) { vec3_t front, back; @@ -266,6 +268,33 @@ static void CG_EntityEffects( centity_t *cent ) if( cg.time > cent->muzzleTSDeathTime && CG_IsTrailSystemValid( ¢->muzzleTS ) ) CG_DestroyTrailSystem( ¢->muzzleTS ); } + + + if( cent->currentState.eType == ET_PLAYER ) + { + centity_t *pcent = cent;; + + // predicted entity doesn't have local cgame vars + if( cent == &cg.predictedPlayerEntity ) + pcent = &cg_entities[ cg.clientNum ]; + + for( i = 0; i <= 2; i++ ) + { + if( CG_IsTrailSystemValid( &pcent->level2ZapTS[ i ] ) ) + { + vec3_t front, back; + + CG_AttachmentPoint( &pcent->level2ZapTS[ i ]->frontAttachment, front ); + CG_AttachmentPoint( &pcent->level2ZapTS[ i ]->backAttachment, back ); + + if( cg.time - pcent->level2ZapTime > 100 || + Distance( front, back ) > LEVEL2_AREAZAP_CUTOFF ) + { + CG_DestroyTrailSystem( &pcent->level2ZapTS[ i ] ); + } + } + } + } } @@ -780,61 +809,6 @@ static void CG_LightFlare( centity_t *cent ) /* ========================= -CG_Lev2ZapChain -========================= -*/ -static void CG_Lev2ZapChain( centity_t *cent ) -{ - int i; - entityState_t *es; - centity_t *source = NULL, *target = NULL; - - es = ¢->currentState; - - for( i = 0; i <= 2; i++ ) - { - switch( i ) - { - case 0: - if( es->time <= 0 ) - continue; - - source = &cg_entities[ es->misc ]; - target = &cg_entities[ es->time ]; - break; - - case 1: - if( es->time2 <= 0 ) - continue; - - source = &cg_entities[ es->time ]; - target = &cg_entities[ es->time2 ]; - break; - - case 2: - if( es->constantLight <= 0 ) - continue; - - source = &cg_entities[ es->time2 ]; - target = &cg_entities[ es->constantLight ]; - break; - } - - if( !CG_IsTrailSystemValid( ¢->level2ZapTS[ i ] ) ) - cent->level2ZapTS[ i ] = CG_SpawnNewTrailSystem( cgs.media.level2ZapTS ); - - if( CG_IsTrailSystemValid( ¢->level2ZapTS[ i ] ) ) - { - CG_SetAttachmentCent( ¢->level2ZapTS[ i ]->frontAttachment, source ); - CG_SetAttachmentCent( ¢->level2ZapTS[ i ]->backAttachment, target ); - CG_AttachToCent( ¢->level2ZapTS[ i ]->frontAttachment ); - CG_AttachToCent( ¢->level2ZapTS[ i ]->backAttachment ); - } - } -} - -/* -========================= CG_AdjustPositionForMover Also called by client movement prediction code @@ -1029,22 +1003,8 @@ CG_CEntityPVSLeave */ static void CG_CEntityPVSLeave( centity_t *cent ) { - int i; - entityState_t *es = ¢->currentState; - if( cg_debugPVS.integer ) CG_Printf( "Entity %d left PVS\n", cent->currentState.number ); - - switch( es->eType ) - { - case ET_LEV2_ZAP_CHAIN: - for( i = 0; i <= 2; i++ ) - { - if( CG_IsTrailSystemValid( ¢->level2ZapTS[ i ] ) ) - CG_DestroyTrailSystem( ¢->level2ZapTS[ i ] ); - } - break; - } } @@ -1128,10 +1088,6 @@ static void CG_AddCEntity( centity_t *cent ) case ET_LIGHTFLARE: CG_LightFlare( cent ); break; - - case ET_LEV2_ZAP_CHAIN: - CG_Lev2ZapChain( cent ); - break; } } diff --git a/src/cgame/cg_event.c b/src/cgame/cg_event.c index 454f843e..1caba1f5 100644 --- a/src/cgame/cg_event.c +++ b/src/cgame/cg_event.c @@ -168,6 +168,24 @@ static void CG_Obituary( entityState_t *ent ) message = "blew himself up"; break; + case MOD_LEVEL3_BOUNCEBALL: + if( gender == GENDER_FEMALE ) + message = "sniped herself"; + else if( gender == GENDER_NEUTER ) + message = "sniped itself"; + else + message = "sniped himself"; + break; + + case MOD_PRIFLE: + if( gender == GENDER_FEMALE ) + message = "pulse rifled herself"; + else if( gender == GENDER_NEUTER ) + message = "pulse rifled itself"; + else + message = "pulse rifled himself"; + break; + default: if( gender == GENDER_FEMALE ) message = "killed herself"; @@ -181,7 +199,7 @@ static void CG_Obituary( entityState_t *ent ) if( message ) { - CG_Printf( "%s" S_COLOR_WHITE " %s.\n", targetName, message ); + CG_Printf( "%s" S_COLOR_WHITE " %s\n", targetName, message ); return; } @@ -297,12 +315,16 @@ static void CG_Obituary( entityState_t *ent ) BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL4 ) ); message2 = className; break; - case MOD_LEVEL4_CHARGE: + case MOD_LEVEL4_TRAMPLE: message = "should have gotten out of the way of"; Com_sprintf( className, 64, "'s %s", BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL4 ) ); message2 = className; break; + case MOD_LEVEL4_CRUSH: + message = "was crushed under"; + message2 = "'s weight"; + break; case MOD_POISON: message = "should have used a medkit against"; @@ -342,7 +364,7 @@ static void CG_Obituary( entityState_t *ent ) } // we don't know what it was - CG_Printf( "%s died.\n", targetName ); + CG_Printf( "%s died\n", targetName ); } //========================================================================== @@ -380,6 +402,60 @@ void CG_PainEvent( centity_t *cent, int health ) } /* +========================= +CG_Level2Zap +========================= +*/ +static void CG_Level2Zap( entityState_t *es ) +{ + int i; + centity_t *source = NULL, *target = NULL; + + if( es->misc < 0 || es->misc >= MAX_CLIENTS ) + return; + + source = &cg_entities[ es->misc ]; + for( i = 0; i <= 2; i++ ) + { + switch( i ) + { + case 0: + if( es->time <= 0 ) + continue; + + target = &cg_entities[ es->time ]; + break; + + case 1: + if( es->time2 <= 0 ) + continue; + + target = &cg_entities[ es->time2 ]; + break; + + case 2: + if( es->constantLight <= 0 ) + continue; + + target = &cg_entities[ es->constantLight ]; + break; + } + + if( !CG_IsTrailSystemValid( &source->level2ZapTS[ i ] ) ) + source->level2ZapTS[ i ] = CG_SpawnNewTrailSystem( cgs.media.level2ZapTS ); + + if( CG_IsTrailSystemValid( &source->level2ZapTS[ i ] ) ) + { + CG_SetAttachmentCent( &source->level2ZapTS[ i ]->frontAttachment, source ); + CG_SetAttachmentCent( &source->level2ZapTS[ i ]->backAttachment, target ); + CG_AttachToCent( &source->level2ZapTS[ i ]->frontAttachment ); + CG_AttachToCent( &source->level2ZapTS[ i ]->backAttachment ); + } + } + source->level2ZapTime = cg.time; +} + +/* ============== CG_EntityEvent @@ -619,13 +695,13 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL1Grab ); break; - case EV_LEV4_CHARGE_PREPARE: - DEBUGNAME( "EV_LEV4_CHARGE_PREPARE" ); + case EV_LEV4_TRAMPLE_PREPARE: + DEBUGNAME( "EV_LEV4_TRAMPLE_PREPARE" ); trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL4ChargePrepare ); break; - case EV_LEV4_CHARGE_START: - DEBUGNAME( "EV_LEV4_CHARGE_START" ); + case EV_LEV4_TRAMPLE_START: + DEBUGNAME( "EV_LEV4_TRAMPLE_START" ); //FIXME: stop cgs.media.alienL4ChargePrepare playing here trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL4ChargeStart ); break; @@ -903,6 +979,11 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) } break; + case EV_MGTURRET_SPINUP: + DEBUGNAME( "EV_MGTURRET_SPINUP" ); + trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.turretSpinupSound ); + break; + case EV_OVERMIND_SPAWNS: DEBUGNAME( "EV_OVERMIND_SPAWNS" ); if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS ) @@ -968,6 +1049,11 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) cg.spawnTime = cg.time; break; + case EV_LEV2_ZAP: + DEBUGNAME( "EV_LEV2_ZAP" ); + CG_Level2Zap( es ); + break; + default: DEBUGNAME( "UNKNOWN" ); CG_Error( "Unknown event: %i", event ); diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h index f70afc85..50381ff2 100644 --- a/src/cgame/cg_local.h +++ b/src/cgame/cg_local.h @@ -655,6 +655,7 @@ typedef struct centity_s qboolean entityPSMissing; trailSystem_t *level2ZapTS[ 3 ]; + int level2ZapTime; trailSystem_t *muzzleTS; //used for the tesla and reactor int muzzleTSDeathTime; @@ -1177,6 +1178,7 @@ typedef struct sfxHandle_t humanTalkSound; sfxHandle_t landSound; sfxHandle_t fallSound; + sfxHandle_t turretSpinupSound; sfxHandle_t hardBounceSound1; sfxHandle_t hardBounceSound2; @@ -1408,6 +1410,7 @@ extern vmCvar_t cg_drawTeamOverlay; extern vmCvar_t cg_teamOverlayUserinfo; extern vmCvar_t cg_crosshairX; extern vmCvar_t cg_crosshairY; +extern vmCvar_t cg_crosshairSize; extern vmCvar_t cg_drawStatus; extern vmCvar_t cg_draw2D; extern vmCvar_t cg_animSpeed; diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c index bbaf914f..01234d1d 100644 --- a/src/cgame/cg_main.c +++ b/src/cgame/cg_main.c @@ -68,6 +68,12 @@ intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, CG_DrawActiveFrame( arg0, arg1, arg2 ); return 0; + case CG_CROSSHAIR_PLAYER: + return CG_CrosshairPlayer( ); + + case CG_LAST_ATTACKER: + return CG_LastAttacker( ); + case CG_KEY_EVENT: CG_KeyEvent( arg0, arg1 ); return 0; @@ -124,6 +130,7 @@ vmCvar_t cg_drawCrosshairNames; vmCvar_t cg_drawRewards; vmCvar_t cg_crosshairX; vmCvar_t cg_crosshairY; +vmCvar_t cg_crosshairSize; vmCvar_t cg_draw2D; vmCvar_t cg_drawStatus; vmCvar_t cg_animSpeed; @@ -263,6 +270,7 @@ static cvarTable_t cvarTable[ ] = { &cg_drawRewards, "cg_drawRewards", "1", CVAR_ARCHIVE }, { &cg_crosshairX, "cg_crosshairX", "0", CVAR_ARCHIVE }, { &cg_crosshairY, "cg_crosshairY", "0", CVAR_ARCHIVE }, + { &cg_crosshairSize, "cg_crosshairSize", "1", CVAR_ARCHIVE }, { &cg_brassTime, "cg_brassTime", "2500", CVAR_ARCHIVE }, { &cg_simpleItems, "cg_simpleItems", "0", CVAR_ARCHIVE }, { &cg_addMarks, "cg_marks", "1", CVAR_ARCHIVE }, @@ -667,6 +675,7 @@ static void CG_RegisterSounds( void ) cgs.media.tracerSound = trap_S_RegisterSound( "sound/weapons/tracer.wav", qfalse ); cgs.media.selectSound = trap_S_RegisterSound( "sound/weapons/change.wav", qfalse ); + cgs.media.turretSpinupSound = trap_S_RegisterSound( "sound/buildables/mgturret/spinup.wav", qfalse ); cgs.media.talkSound = trap_S_RegisterSound( "sound/misc/talk.wav", qfalse ); cgs.media.alienTalkSound = trap_S_RegisterSound( "sound/misc/alien_talk.wav", qfalse ); diff --git a/src/cgame/cg_public.h b/src/cgame/cg_public.h index 905b1db2..4d9e965a 100644 --- a/src/cgame/cg_public.h +++ b/src/cgame/cg_public.h @@ -232,6 +232,12 @@ typedef enum // Generates and draws a game scene and status information at the given time. // If demoPlayback is set, local movement prediction will not be enabled + CG_CROSSHAIR_PLAYER, + // int (*CG_CrosshairPlayer)( void ); + + CG_LAST_ATTACKER, + // int (*CG_LastAttacker)( void ); + CG_KEY_EVENT, // void (*CG_KeyEvent)( int key, qboolean down ); diff --git a/src/cgame/cg_tutorial.c b/src/cgame/cg_tutorial.c index 21242a75..bfcd03ac 100644 --- a/src/cgame/cg_tutorial.c +++ b/src/cgame/cg_tutorial.c @@ -36,6 +36,7 @@ static bind_t bindings[ ] = { "+button2", "Activate Upgrade", { -1, -1 } }, { "+speed", "Run/Walk", { -1, -1 } }, { "boost", "Sprint", { -1, -1 } }, + { "+button6", "Dodge", { -1, -1 } }, { "+moveup", "Jump", { -1, -1 } }, { "+movedown", "Crouch", { -1, -1 } }, { "+attack", "Primary Attack", { -1, -1 } }, @@ -340,7 +341,7 @@ static void CG_AlienLevel4Text( char *text, playerState_t *ps ) CG_KeyNameForCommand( "+attack" ) ) ); Q_strcat( text, MAX_TUTORIAL_TEXT, - va( "Hold down and release %s to charge\n", + va( "Hold down and release %s to trample\n", CG_KeyNameForCommand( "+button5" ) ) ); } @@ -552,14 +553,25 @@ CG_SpectatorText */ static void CG_SpectatorText( char *text, playerState_t *ps ) { + if( cgs.clientinfo[ cg.clientNum ].team != PTE_NONE ) + { + Q_strcat( text, MAX_TUTORIAL_TEXT, + va( "Press %s to spawn\n", + CG_KeyNameForCommand( "+attack" ) ) ); + } + else + { + Q_strcat( text, MAX_TUTORIAL_TEXT, + va( "Press %s to join a team\n", + CG_KeyNameForCommand( "+attack" ) ) ); + } + if( ps->pm_flags & PMF_FOLLOW ) { Q_strcat( text, MAX_TUTORIAL_TEXT, - va( "Press %s to return to free spectator mode\n", + va( "Press %s to stop following\n", CG_KeyNameForCommand( "+button2" ) ) ); - if( CG_PlayerCount( ) > 1 ) - { Q_strcat( text, MAX_TUTORIAL_TEXT, va( "Press %s or ", CG_KeyNameForCommand( "weapprev" ) ) ); @@ -567,27 +579,13 @@ static void CG_SpectatorText( char *text, playerState_t *ps ) va( "%s to change player\n", CG_KeyNameForCommand( "weapnext" ) ) ); } - } - else if( ps->pm_type == PM_SPECTATOR ) + else { Q_strcat( text, MAX_TUTORIAL_TEXT, - va( "Press %s to join a team\n", - CG_KeyNameForCommand( "+attack" ) ) ); - - if( CG_PlayerCount( ) > 0 ) - { - Q_strcat( text, MAX_TUTORIAL_TEXT, - va( "Press %s to enter spectator follow mode\n", + va( "Press %s to follow a player\n", CG_KeyNameForCommand( "+button2" ) ) ); } } - else - { - Q_strcat( text, MAX_TUTORIAL_TEXT, - va( "Press %s to spawn\n", - CG_KeyNameForCommand( "+attack" ) ) ); - } -} /* =============== diff --git a/src/cgame/cg_view.c b/src/cgame/cg_view.c index 781e068a..ae7cf7bb 100644 --- a/src/cgame/cg_view.c +++ b/src/cgame/cg_view.c @@ -470,7 +470,8 @@ static void CG_OffsetFirstPersonView( void ) { if( ps->stats[ STAT_MISC ] > 0 ) { - float fraction = (float)ps->stats[ STAT_MISC ] / (float)LEVEL4_CHARGE_TIME; + float fraction = (float)ps->stats[ STAT_MISC ] / + (float)LEVEL4_TRAMPLE_CHARGE_MAX; if( fraction > 1.0f ) fraction = 1.0f; @@ -593,17 +594,17 @@ static void CG_OffsetFirstPersonView( void ) } // this *feels* more realisitic for humans - if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_HUMANS ) + if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_HUMANS && + ( cg.predictedPlayerState.pm_type == PM_NORMAL || + cg.predictedPlayerState.pm_type == PM_JETPACK ) ) { angles[PITCH] += cg.bobfracsin * bob2 * 0.5; // heavy breathing effects //FIXME: sound - if( cg.predictedPlayerState.stats[ STAT_STAMINA ] < 0 ) + if( cg.predictedPlayerState.stats[ STAT_STAMINA ] < STAMINA_BREATHING_LEVEL ) { - float deltaBreath = (float)( - cg.predictedPlayerState.stats[ STAT_STAMINA ] < 0 ? - -cg.predictedPlayerState.stats[ STAT_STAMINA ] : - cg.predictedPlayerState.stats[ STAT_STAMINA ] ) / 200.0; + float deltaBreath = ( cg.predictedPlayerState.stats[ STAT_STAMINA ] - + STAMINA_BREATHING_LEVEL ) / -250.0; float deltaAngle = cos( (float)cg.time/150.0 ) * deltaBreath; deltaAngle += ( deltaAngle < 0 ? -deltaAngle : deltaAngle ) * 0.5; @@ -1067,6 +1068,10 @@ static int CG_CalcViewValues( void ) cg.xyspeed = sqrt( ps->velocity[ 0 ] * ps->velocity[ 0 ] + ps->velocity[ 1 ] * ps->velocity[ 1 ] ); + // the bob velocity should't get too fast to avoid jerking + if( cg.xyspeed > 300.f ) + cg.xyspeed = 300.f; + VectorCopy( ps->origin, cg.refdef.vieworg ); if( BG_ClassHasAbility( ps->stats[ STAT_PCLASS ], SCA_WALLCLIMBER ) ) diff --git a/src/cgame/cg_weapons.c b/src/cgame/cg_weapons.c index fc8dc058..a74a15f4 100644 --- a/src/cgame/cg_weapons.c +++ b/src/cgame/cg_weapons.c @@ -1061,12 +1061,27 @@ void CG_AddViewWeapon( playerState_t *ps ) VectorMA( hand.origin, cg_gun_y.value, cg.refdef.viewaxis[ 1 ], hand.origin ); VectorMA( hand.origin, ( cg_gun_z.value + fovOffset ), cg.refdef.viewaxis[ 2 ], hand.origin ); - if( weapon == WP_LUCIFER_CANNON && ps->stats[ STAT_MISC ] > 0 ) + if( weapon == WP_LUCIFER_CANNON ) { - float fraction = (float)ps->stats[ STAT_MISC ] / (float)LCANNON_TOTAL_CHARGE; + float fraction; - VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 0 ], hand.origin ); - VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 1 ], hand.origin ); + if( ps->stats[ STAT_MISC ] > 0 ) + { + // vibration effect + fraction = (float)ps->stats[ STAT_MISC ] / (float)LCANNON_TOTAL_CHARGE; + VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 0 ], + hand.origin ); + VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 1 ], + hand.origin ); + } + else if( ps->stats[ STAT_MISC2 ] > 0 ) + { + // reloading effect + fraction = (float)ps->stats[ STAT_MISC2 ] / 250.0f; + fraction = ( fraction > 1.0f ) ? 1.0f : fraction; + VectorMA( hand.origin, fraction * -3.0f, cg.refdef.viewaxis[ 2 ], + hand.origin ); + } } AnglesToAxis( angles, hand.axis ); |