Исходник Corrected StartPrediction for 2018 hvh

Участник
Статус
Оффлайн
Регистрация
6 Апр 2021
Сообщения
338
Реакции[?]
207
Поинты[?]
113K
C++:
bool LagCompensation::StartPrediction( AimPlayer* data ) {
    // Check if data and player are valid
    if ( data->m_records.empty( ) || data->m_player->dormant( ) ) {
        return false;
    }

    // Count number of non-dormant records
    size_t size = 0;
    for ( const auto& it : data->m_records ) {
        if ( it->dormant( ) ) {
            break;
        }
        size++;
    }

    // Get first record
    LagRecord* record = data->m_records[ 0 ].get( );

    // Check if record is valid
    if ( record == nullptr ) {
        return false;
    }

    // Reset prediction related variables
    record->predict( );

    // Check if LC (Lag Compensation) is broken
    if ( size > 1 && ( ( record->m_origin - data->m_records[ 1 ]->m_origin ).length_sqr( ) > 4096.f ||
        ( size > 2 && ( data->m_records[ 1 ]->m_origin - data->m_records[ 2 ]->m_origin ).length_sqr( ) > 4096.f ) ) ) {
        record->m_broke_lc = true;
    }

    if ( !record->m_broke_lc )
        return false;

    int simulation = game::TIME_TO_TICKS( record->m_sim_time );

    if ( std::abs( g_cl.m_arrival_tick - simulation ) >= 128 )
        return true;

    int lag;
    if ( size <= 2 )
        lag = game::TIME_TO_TICKS( record->m_sim_time - data->m_records[ 1 ]->m_sim_time );
    else
        lag = game::TIME_TO_TICKS( data->m_records[ 1 ]->m_sim_time - data->m_records[ 2 ]->m_sim_time );

    // Clamp lag to ensure that it is within a reasonable range.
    lag = std::clamp( lag, 1, 15 );

    int updatedelta = g_cl.m_server_tick - record->m_tick;
    if ( g_cl.m_latency_ticks <= lag - updatedelta )
        return true;

    int next = record->m_tick + 1;
    if ( next + lag >= g_cl.m_arrival_tick )
        return true;

    float change = 0.f, dir = 0.f;
    if ( record->m_velocity.y != 0.f || record->m_velocity.x != 0.f )
        dir = std::atan2( record->m_velocity.y, record->m_velocity.x );

    // Convert the direction to degrees.
    dir = math::rad_to_deg( dir );

    if ( size > 1 ) {
        // get the delta time between the 2 most recent records.
        float dt = record->m_sim_time - data->m_records[ 1 ]->m_sim_time;

        // check for division by zero
        if ( dt <= 0.f )
            return false;

        float prevdir = 0.f;

        // get the direction of the previous velocity.
        if ( data->m_records[ 1 ]->m_velocity.y != 0.f || data->m_records[ 1 ]->m_velocity.x != 0.f )
            prevdir = math::rad_to_deg( std::atan2( data->m_records[ 1 ]->m_velocity.y, data->m_records[ 1 ]->m_velocity.x ) );

        // compute the direction change per tick.
        change = ( math::NormalizedAngle( prevdir - dir ) / dt ) * g_csgo.m_globals->m_interval;

        // clamp the change to a valid range
        change = std::clamp( change, -6.f, 6.f );
    }

    // get the pointer to the players animation state.
    CCSGOPlayerAnimState* state = data->m_player->m_PlayerAnimState( );

    // backup the animation state.
    CCSGOPlayerAnimState backup{};
    if( state )
        std::memcpy( &backup, state, sizeof( CCSGOPlayerAnimState ) );

    // add in the shot prediction here.
    int shot = 0;
    int pred = 0;

    // start our predicton loop.
    while( true ) {
        // see if by predicting this amount of lag
        // we do not break stuff.
        next += lag;
        if( next >= g_cl.m_arrival_tick )
            break;

        // predict lag.
        for( int sim{}; sim < lag; ++sim ) {
            const int numberOfRecords = data->m_records.size( );

            if ( numberOfRecords > 1 ) {
                const float deltaTime = record->m_sim_time - data->m_records[ 1 ]->m_sim_time;

                float previousDirection = math::rad_to_deg( std::atan2( data->m_records[ 1 ]->m_velocity.y, data->m_records[ 1 ]->m_velocity.x ) );

                change = ( math::NormalizedAngle( dir - previousDirection ) / deltaTime ) * g_csgo.m_globals->m_interval;
            }

            if ( std::abs( change ) > 6.f ) {
                change = 0.f;
            }

            dir = math::NormalizedAngle( dir + change );

            const float hyp = record->m_pred_velocity.length_2d( );

            record->m_pred_velocity.x = std::cos( math::deg_to_rad( dir ) ) * hyp;
            record->m_pred_velocity.y = std::sin( math::deg_to_rad( dir ) ) * hyp;

            if ( record->m_pred_flags & FL_ONGROUND ) {
                const int bunnyhoppingEnabled = g_csgo.sv_enablebunnyhopping->GetInt( );
                if ( !bunnyhoppingEnabled ) {
                    const float max = data->m_player->m_flMaxspeed( ) * 1.1f;
                    const float speed = record->m_pred_velocity.length( );
                    if ( max > 0.f && speed > max ) {
                        record->m_pred_velocity *= ( max / speed );
                    }
                }
                record->m_pred_velocity.z = g_csgo.sv_jump_impulse->GetFloat( );
            }

            // we are not on the ground
            // apply gravity and airaccel.
            else {
                // apply one tick of gravity.
                record->m_pred_velocity.z -= g_csgo.sv_gravity->GetFloat( ) * g_csgo.m_globals->m_interval;

                // compute the ideal strafe angle for this velocity.
                float speed2d = record->m_pred_velocity.length_2d( );
                float ideal   = ( speed2d > 0.f ) ? math::rad_to_deg( std::asin( 15.f / speed2d ) ) : 90.f;
                math::clamp( ideal, 0.f, 90.f );

                float smove = 0.f;
                float abschange = std::abs( change );

                if( abschange <= ideal || abschange >= 30.f ) {
                    static float mod{ 1.f };

                    dir += ( ideal * mod );
                    move = 450.f * mod;
                    mod *= -1.f;
                }

                else if( change > 0.f )
                    move = -450.f;

                else
                    move = 450.f;

                // apply air accel.
                AirAccelerate( record, ang_t{ 0.f, dir, 0.f }, 0.f, smove );
            }

            // predict player.
            // convert newly computed velocity
            // to origin and flags.
            PlayerMove(record);

            // move time forward by one.
            record->m_pred_time += g_csgo.m_globals->m_interval;

            // increment total amt of predicted ticks.
            ++pred;

            // the server animates every first choked command.
            // therefore we should do that too.
            if( sim == 0 && state )
                PredictAnimations( state, record );
        }
    }

    // restore state.
    if(state)
        std::memcpy( state, &backup, sizeof( CCSGOPlayerAnimState ) );

    if( predict <= 0 )
        return true;

    // lagcomp broken, invalidate bones.
    record->invalidate( );

    // re-setup bones for this record.
    g_bones.setup( data->m_player, nullptr, record );

    return true;
}
 
Пользователь
Статус
Оффлайн
Регистрация
7 Май 2020
Сообщения
92
Реакции[?]
41
Поинты[?]
2K
C++:
   // Check if LC (Lag Compensation) is broken
    if ( size > 1 && ( ( record->m_origin - data->m_records[ 1 ]->m_origin ).length_sqr( ) > 4096.f ||
        ( size > 2 && ( data->m_records[ 1 ]->m_origin - data->m_records[ 2 ]->m_origin ).length_sqr( ) > 4096.f ) ) ) {
        record->m_broke_lc = true;
    }
???? n1
C++:
   int lag;
    if ( size <= 2 )
        lag = game::TIME_TO_TICKS( record->m_sim_time - data->m_records[ 1 ]->m_sim_time );
    else
        lag = game::TIME_TO_TICKS( data->m_records[ 1 ]->m_sim_time - data->m_records[ 2 ]->m_sim_time );
you should've left this as a ternary operator imo. only because it still looks cleaner...
 
Сверху Снизу