Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Исходник [Сурс] APB Reloaded — Алгоритм предсказания разброса

Sloppy
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
13 Фев 2026
Сообщения
347
Реакции
7
Народ, ситуация по APB классическая. Разрабы в очередной раз пофиксили (читай: сломали по-своему) механику стрельбы, вернув рандом в полный мрак, но признавать свои косяки они умеют только после пинков в дискорде.

Ковырял их движок и в свое время набросал простенькую логику для предсказания примерно 80% разброса. Сейчас это уже по большей части история и артефакты, так как после патча стало бесполезно, но для архива или изучения матчасти — пойдет.

Суть реализации:
  1. Функция APB_RecoilPredictionDirection вычисляет направление по Yaw, нормализуя значения в диапазоне от -1.0 до 1.0.
  2. Расчет ведется через полярные координаты, опираясь на текущий размер прицела из памяти (Cached.Game_HUD_CrosshairSize).
  3. Для вычисления смещения прицела используется угловое маппирование в диапазоне [-45, +45] градусов.

Код:
Expand Collapse Copy
/// <summary>
/// Calculates the value between -1.0 and 1.0 depending on camera Yaw Rotation for NSEW in world
/// </summary>
/// <param name="yaw">degrees</param>
/// <returns></returns>
float APB_RecoilPredictionDirection(float yaw)
{
    // Normalize yaw to [0, 360)
    yaw = fmodf(yaw, 360.0f);
    if (yaw < 0.0f) yaw += 360.0f;
 
    // Determine the quadrant and calculate the output
    if (yaw <= 90.0f) {
        // 0° to 90°: Constant 1.0f (right)
        return 1.0f;
    }
    else if (yaw <= 180.0f) {
        // 90° to 180°: Linearly interpolate from 1.0f to -1.0f
        return 1.0f - 2.0f * ((yaw - 90.0f) / 90.0f); // Slope: (1 - (-1)) / 90 = -2/90
    }
    else if (yaw <= 270.0f) {
        // 180° to 270°: Constant -1.0f (left)
        return -1.0f;
    }
    else {
        // 270° to 360°: Linearly interpolate from -1.0f to 1.0f
        return -1.0f + 2.0f * ((yaw - 270.0f) / 90.0f); // Slope: (1 - (-1)) / 90 = 2/90
    }
}
 
/// <summary>
/// Predicts the offset to where the bullets are supose to go (Currently Deprecated)
/// </summary>
/// <param name="x">half of the screen width</param>
/// <param name="y">half of the screen height</param>
/// <returns></returns>
SDK::Unreal::Vector2 getRecoilPredMiddleScreen(float x, float y)
{
    // Normalize the yaw direction to a value between -1 and 1
    auto cameraData = SDK::Unreal::Camera::GetCameraEntry();
    float direction = APB_RecoilPredictionDirection(URadiansToDegree(URotationToRadians(cameraData.Rotation.Yaw)));
    // Map direction to an angle between -45 and +45 degrees
    float angle_degrees = direction * 45.0f; // -1 maps to -45°, 1 maps to +45°
    float angle_radians = angle_degrees * (M_PI / 180.0f); // Convert to radians
 
    // Define the radius, scaled by crosshair_size that is read from memory
    // using 0.5f as initial crosshair_radius_scale works quite good
    float scale = Cached.Game_HUD_CrosshairSize.load(); // gets current crosshair size (1.0 is default size)
    if (scale > 3)
        scale = 3;
    float radius = 0.01f * (scale / Configuration.crosshair_radius_scale.load()) * y; // Scale radius based on y and crosshair_size
 
    // Bottom of the circle is at 90° in standard polar coordinates
    // Add 90° to start at the bottom, then adjust by angle_radians
    float total_angle_radians = (-90.0f * (M_PI / 180.0f)) + angle_radians;
 
    // Calculate offsets using polar coordinates
    float offset_x = radius * cos(total_angle_radians); // x = r * cos(θ)
    float offset_y = -radius * sin(total_angle_radians); // y = -r * sin(θ) (negative due to screen Y-axis pointing down)
    // Return the new position by adding offsets to the input x, y
    return SDK::Unreal::Vector2(x + offset_x, y + offset_y);
}

Сейчас в игре снова 100% рандомный разброс, что максимально убивает желание потеть. Если кто-то пытался на базе этого переписать под текущие оффсеты или нашел способ привязаться к новому алгоритму spread — отпишитесь, интересно глянуть, как вы это обходите.
 
Назад
Сверху Снизу