void CBaseViewModel::CalcIronsights( Vector &pos, QAngle &ang ) { CBaseCombatWeapon *pWeapon = GetOwningWeapon(); if (!pWeapon) return; //get delta time for interpolation float delta = (gpGlobals->curtime - pWeapon->m_flIronsightedTime) * 2.5f; //modify this value to adjust how fast the interpolation is float exp = (pWeapon->IsIronsighted()) ? (delta > 1.0f) ? 1.0f : delta : //normal blending (delta > 1.0f) ? 0.0f : 1.0f - delta; //reverse interpolation if (exp <= 0.001f) //fully not ironsighted; save performance return; Vector newPos = pos; QAngle newAng = ang; Vector vForward, vRight, vUp, vOffset; AngleVectors(newAng, &vForward, &vRight, &vUp); vOffset = pWeapon->GetIronsightPositionOffset(); newPos += vForward * vOffset.x; newPos += vRight * vOffset.y; newPos += vUp * vOffset.z; newAng += pWeapon->GetIronsightAngleOffset(); //fov is handled by CBaseCombatWeapon pos += (newPos - pos) * exp; ang += (newAng - ang) * exp; }
//BG2 -Added for Iron Sights Testing. Credits to Jorg for the code. -HairyPotter void CBaseViewModel::CalcIronsights( Vector &pos, QAngle &ang ) { //CBaseCombatWeapon *pWeapon = GetOwningWeapon(); CBaseCombatWeapon *pWeapon = m_hWeapon.Get(); if ( !pWeapon ) return; //get delta time for interpolation float time = pWeapon->IsIronsighted() ? IRONSIGHTS_ANGLE_IN_TIME : IRONSIGHTS_ANGLE_OUT_TIME; float delta( ( gpGlobals->curtime - pWeapon->m_flIronsightedTime ) / time ); float exp = ( pWeapon->IsIronsighted() ) ? ( delta > 1.0f ) ? 1.0f : delta : //normal blending ( delta > 1.0f ) ? 0.0f : 1.0f - delta; //reverse interpolation if( exp <= 0.0f ) //fully not ironsighted; save performance return; if( exp > 1.0f ) exp = 1.0f; Vector newPos = pos; QAngle newAng = ang; Vector vForward, vRight, vUp, vOffset; AngleVectors( newAng, &vForward, &vRight, &vUp ); vOffset = pWeapon->GetIronsightPositionOffset(); newPos += vForward * vOffset.x; newPos += vRight * vOffset.y; newPos += vUp * vOffset.z; newAng += pWeapon->GetIronsightAngleOffset(); //This also handles the pitch... //fov is handled by CBaseCombatWeapon pos += ( newPos - pos ) * exp; ang += ( newAng - ang ) * exp; }
void CBaseViewModel::CalcViewModelView( CBasePlayer *owner, const Vector& eyePosition, const QAngle& eyeAngles ) { // UNDONE: Calc this on the server? Disabled for now as it seems unnecessary to have this info on the server #if defined( CLIENT_DLL ) QAngle vmangoriginal = eyeAngles; QAngle vmangles = eyeAngles; Vector vmorigin = eyePosition; CBaseCombatWeapon *pWeapon = m_hWeapon.Get(); //Allow weapon lagging //if ( pWeapon != NULL ) if( pWeapon != NULL && !pWeapon->IsIronsighted() ) // { #if defined( CLIENT_DLL ) if ( !prediction->InPrediction() ) #endif { // add weapon-specific bob pWeapon->AddViewmodelBob( this, vmorigin, vmangles ); } } // Add model-specific bob even if no weapon associated (for head bob for off hand models) AddViewModelBob( owner, vmorigin, vmangles ); //So this is the function that does the model movement when you move around. // Add lag CalcViewModelLag( vmorigin, vmangles, vmangoriginal ); #if defined( CLIENT_DLL ) if ( !prediction->InPrediction() ) { // Let the viewmodel shake at about 10% of the amplitude of the player's view vieweffects->ApplyShake( vmorigin, vmangles, 0.1 ); } #endif CalcIronsights( vmorigin, vmangles ); //BG2 -Added for Iron Sights Testing. Credits to Jorg for the code. -HairyPotter SetLocalOrigin( Vector( vmorigin.x, vmorigin.y, vmorigin.z ) ); SetLocalAngles( vmangles ); #endif }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHLMachineGun::DoMachineGunKick( CBasePlayer *pPlayer, float dampEasy, float maxVerticleKickAngle, float fireDurationTime, float slideLimitTime ) { #define KICK_MIN_X 0.2f //Degrees #define KICK_MIN_Y 0.2f //Degrees #define KICK_MIN_Z 0.1f //Degrees QAngle vecScratch; //Find how far into our accuracy degradation we are float duration = ( fireDurationTime > slideLimitTime ) ? slideLimitTime : fireDurationTime; float kickPerc = duration / slideLimitTime; // do this to get a hard discontinuity, clear out anything under 10 degrees punch pPlayer->ViewPunchReset( 10 ); //Apply this to the view angles as well vecScratch.x = -( KICK_MIN_X + ( maxVerticleKickAngle * kickPerc ) ); vecScratch.y = -( KICK_MIN_Y + ( maxVerticleKickAngle * kickPerc ) ) / 3; vecScratch.z = KICK_MIN_Z + ( maxVerticleKickAngle * kickPerc ) / 8; //Wibble left and right if ( random->RandomInt( -1, 1 ) >= 0 ) vecScratch.y *= -1; //Wobble up and down if ( random->RandomInt( -1, 1 ) >= 0 ) vecScratch.z *= -1; //If we're in easy, dampen the effect a bit if ( g_pGameRules->IsSkillLevel( SKILL_EASY ) ) { for ( int i = 0; i < 3; i++ ) { vecScratch[i] *= dampEasy; } } //Clip this to our desired min/max UTIL_ClipPunchAngleOffset( vecScratch, pPlayer->m_Local.m_vecPunchAngle, QAngle( 24.0f, 3.0f, 1.0f ) ); //Add it to the view punch // NOTE: 0.5 is just tuned to match the old effect before the punch became simulated // FAKEFACTORY IRONSIGHT // old // pPlayer->ViewPunch( vecScratch * 0.5 ); // new if ( ff_weapons_recoil.GetInt() == 1 ) { CBaseCombatWeapon *pWeapon = pPlayer->GetActiveWeapon(); if ( pWeapon == NULL ) return; if ( pWeapon->IsIronsighted() ) { QAngle angle = pPlayer->GetPunchAngle(); angle.x -= random->RandomInt( 2.75, 3.25) + ( angle.x / 4 ); angle.y += random->RandomInt( -0.75, 0.75); pPlayer->SetPunchAngle( angle ); } else { QAngle angle = pPlayer->GetPunchAngle(); angle.x -= random->RandomInt( 2.75, 3.25) + ( angle.x / 4 ); angle.y += random->RandomInt( -1.25, 1.5); pPlayer->SetPunchAngle( angle ); } } else { pPlayer->ViewPunch( vecScratch * 0.5 ); } // FAKEFACTORY IRONSIGHT }
void CBaseViewModel::CalcViewModelLag( Vector& origin, QAngle& angles, QAngle& original_angles ) { Vector vOriginalOrigin = origin; QAngle vOriginalAngles = angles; CBaseCombatWeapon *pWeapon = GetOwningWeapon(); if ( !pWeapon ) return; if ( pWeapon->IsIronsighted() ) { origin = vOriginalOrigin; angles = vOriginalAngles; } else { // Calculate our drift Vector forward; AngleVectors( angles, &forward, NULL, NULL ); if ( gpGlobals->frametime != 0.0f ) { Vector vDifference; VectorSubtract( forward, m_vecLastFacing, vDifference ); float flSpeed = 5.0f; // If we start to lag too far behind, we'll increase the "catch up" speed. Solves the problem with fast cl_yawspeed, m_yaw or joysticks // rotating quickly. The old code would slam lastfacing with origin causing the viewmodel to pop to a new position float flDiff = vDifference.Length(); if ( (flDiff > g_fMaxViewModelLag) && (g_fMaxViewModelLag > 0.0f) ) { float flScale = flDiff / g_fMaxViewModelLag; flSpeed *= flScale; } // FIXME: Needs to be predictable? VectorMA( m_vecLastFacing, flSpeed * gpGlobals->frametime, vDifference, m_vecLastFacing ); // Make sure it doesn't grow out of control!!! VectorNormalize( m_vecLastFacing ); VectorMA( origin, 5.0f, vDifference * -1.0f, origin ); Assert( m_vecLastFacing.IsValid() ); } Vector right, up; AngleVectors( original_angles, &forward, &right, &up ); float pitch = original_angles[ PITCH ]; if ( pitch > 180.0f ) pitch -= 360.0f; else if ( pitch < -180.0f ) pitch += 360.0f; if ( g_fMaxViewModelLag == 0.0f ) { origin = vOriginalOrigin; angles = vOriginalAngles; } //FIXME: These are the old settings that caused too many exposed polys on some models VectorMA( origin, -pitch * 0.035f, forward, origin ); VectorMA( origin, -pitch * 0.03f, right, origin ); VectorMA( origin, -pitch * 0.02f, up, origin); } }