Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "prediction.h"
- #include "utils.h"
- #include "clienthook.h"
- #include "HAPI.h"
- Prediction gPrediction;
- Prediction::Prediction( ) : UpdateContext( )
- {
- }
- Prediction::~Prediction( )
- {
- }
- float flSpeed = 1100.0f;
- float Prediction::GetProjectileSpeed( )
- {
- switch( m_weaponID )
- {
- case Demoman_Grenade_Launcher:
- return 910.0f;
- case Demoman_Sticky_Launcher:
- return 805.0f + ( m_charge * 261.63 );
- case Soldier_Direct_Hit:
- return 1850.0f;
- case Soldier_Rocket_Launcher:
- return 1100.0f;
- case Pyro_Flaregun:
- return 1450.0f;
- default:
- return 1000.0f;
- }
- }
- bool Prediction::PredictEntityLocation( CBaseEntity * ent, Vector in, Vector & out )
- {
- Vector vVelocity, vPosition;
- if( !ent )
- return false;
- if( !Util::GetAbsVelocity( ent, vVelocity ) )
- return false;
- float flCurrentTime = *( float* )( ( DWORD_PTR )ent + 0x68 );
- float flOldTime = *( float* )( ( DWORD_PTR )ent + 0x6C );
- float flDelta = flCurrentTime - flOldTime;
- out = in + vVelocity * g_pGlobalVars->frametime;
- return true;
- }
- void Prediction::Reset( )
- {
- /* Update the local player context */
- ResetFrameData( );
- }
- float Dist2D( Vector from, Vector to )
- {
- float x = to.x - from.x;
- float y = to.y - from.y;
- return sqrt( x*x + y*y );
- }
- /* How long is it going to take the projectile to reach the position at 'to'? */
- float Prediction::TimeToImpact( Vector from, Vector to )
- {
- float flSpeed = gPrediction.GetProjectileSpeed( );
- float flTime = 1.0f;
- float flDistance = 1.0f;
- /* Some weapons ignore gravity...*/
- if( m_weaponID == Soldier_Rocket_Launcher || m_weaponID == Soldier_Direct_Hit )
- {
- flDistance = from.DistTo( to );
- }
- else /* others you have to take into account the arc required to hit the target given the known gravity */
- {
- float v = flSpeed;
- float v2 = v*v;
- float v4 = v2*v2;
- float g = -800.0f;
- float x = from.DistTo( to );
- float x2 = x*x;
- float y = to.z - from.z;
- float anglep = 0.0f;
- //if( to.z < from.z )
- // anglep = atan2( v2 - sqrt( v4 - g * ( g * x2 + ( 2 * y ) * v2 ) ), g * x ) ;
- //else
- anglep = atan2( v2 + sqrt( v4 - g * ( g * x2 + ( 2 * y ) * v2 ) ), g * x ) ;
- float vca = v * cos( anglep );
- float vsa = v * sin( anglep );
- flDistance = ( vca / g ) * ( vsa + sqrt( vsa*vsa + ( 2 * g * from.z ) ) );
- }
- flTime = flDistance / flSpeed;
- return flTime;
- }
- Vector PredictedPos( CBaseEntity * target, Vector pos, float time )
- {
- Vector vel, vpos;
- Util::GetAbsVelocity( target, vel );
- vpos.x = pos.x + vel.x * time;
- vpos.y = pos.y + vel.y * time;
- vpos.z = pos.z + vel.z * time;
- int nFlags = Util::GetFlags( target );
- /* FIX: this flag is based on CURRENT position, not the predicted position, so they could actually be on the floor when they aren't */
- if( !( nFlags & FL_ONGROUND ) )
- vpos.z += ( -800.0f * 0.5f * time * time );
- return vpos;
- }
- bool Prediction::PredictProjectiles( /*CUserCmd * cmd, */CBaseEntity * target, Vector in, Vector & out )
- {
- Vector vNextFrame, f, r, u, vShootPos;
- QAngle vAngles;
- CBaseEntity * pLocal = NULL;
- CBaseCombatWeapon * pWeapon = NULL;
- if( !target )
- return false;
- Reset( );
- if( !Util::HasProjectileLauncher( m_weaponID ) )
- return true;
- if( !Util::GetLocalPlayer( &pLocal ) )
- return false;
- if( !Util::GetBaseCombatWeapon( pLocal, &pWeapon ) )
- return false;
- Vector vTargetVelocity;
- //g_pEngine->GetViewAngles( vAngles );
- //Util::Math::_AngleVectors( vAngles, &f, &r, &u );
- //Util::GetLocalEyePos( vShootPos );
- //vShootPos = vShootPos + f + 3 * r + -18.0f * u;
- vShootPos = Util::GetWeaponShootPosition( pLocal );
- //PredictEntityLocation( pLocal, vShootPos, vShootPos );
- float flProjTime = 0.1f;
- Vector pos = in;
- float flProjectileSpeed = GetProjectileSpeed( );
- if( !Util::GetAbsVelocity( target, vTargetVelocity ) )
- return false;
- float flTargetSpeed = vTargetVelocity.Length( );
- /* This could cause a crash! */
- if( flTargetSpeed == 0.0f )
- return true;
- float flCurrentTime = *( float* )( ( DWORD_PTR )target + 0x68 );
- float flOldTime = *( float* )( ( DWORD_PTR )target + 0x6C );
- float flDelta = 0.00001f;//flCurrentTime - flOldTime;
- if( !flDelta )
- return true;
- Ray_t ray;
- trace_t tr;
- float flDeltaOfTimes = 1.0f;
- /* Keep going until we find a point in space that it takes the same time for the projectile to reach as it does for the player, THAT will be the most probable hit location */
- while( flDeltaOfTimes > 0.0f )
- {
- pos = PredictedPos( target, in, flDelta ); // the position at guestimated time x
- flProjTime = TimeToImpact( vShootPos, pos ); // the time it takes for our projectile to reach position predicted in space
- float flTimeFromPlayerToNewPos = in.DistTo( pos ) / flTargetSpeed; //the time it takes to get from the current position to the predicted position in space
- flDeltaOfTimes = flProjTime - flTimeFromPlayerToNewPos;
- flDelta *= 1.001f;
- }
- ray.Init( in, pos );
- g_pEngineTrace->TraceRay( ray, 0x4600400B, NULL, &tr );
- /* If the predicted position intersected with an object, stop the prediction there */
- if( tr.fraction != 1.0f )
- {
- pos = tr.endpos;
- }
- out = pos;// + f + -3 * r + 18.0f * u;
- return true;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement