diff --git a/gamedata/configs/text/eng/ui_mm_modded_exes.xml b/gamedata/configs/text/eng/ui_mm_modded_exes.xml index a9f36b699..19faf9ce7 100644 --- a/gamedata/configs/text/eng/ui_mm_modded_exes.xml +++ b/gamedata/configs/text/eng/ui_mm_modded_exes.xml @@ -954,6 +954,18 @@ If enabled, NPCs will run instead of walk when taking cover during combat. This makes firefights more dynamic and prevents NPCs from slowly walking while under fire. + + AI Dispersion Scale at Rank 0 (ai_dispersion_novice_k) + + + Multiplier applied on top of the vanilla rank-dispersion curve at rank 0 (novice).\n \nDefault: 1.0 (no change from vanilla).\n \nLower values reduce low-rank NPC dispersion; higher values increase it. Applies on every NPC's next shot. + + + AI Dispersion Scale at Rank 100 (ai_dispersion_experienced_k) + + + Multiplier applied on top of the vanilla rank-dispersion curve at rank 100 (legend tier; cvar name follows the vanilla LTX naming convention).\n \nDefault: 1.0 (no change from vanilla).\n \nLower values reduce high-rank NPC dispersion; higher values increase it. Applies on every NPC's next shot. + diff --git a/gamedata/configs/text/rus/ui_mm_modded_exes.xml b/gamedata/configs/text/rus/ui_mm_modded_exes.xml index 9ea6705f9..3bd8c700c 100644 --- a/gamedata/configs/text/rus/ui_mm_modded_exes.xml +++ b/gamedata/configs/text/rus/ui_mm_modded_exes.xml @@ -953,6 +953,18 @@ Если включено, NPC будут бежать, а не идти шагом при поиске укрытия во время боя. Это делает перестрелки более динамичными и не дает NPC медленно прогуливаться под огнем. + + Множитель разброса ИИ при ранге 0 (ai_dispersion_novice_k) + + + Множитель, применяемый поверх стандартной кривой разброса по рангу при ранге 0 (новичок).\n \nПо умолчанию: 1.0 (без изменений относительно оригинала).\n \nБолее низкие значения уменьшают разброс у NPC низкого ранга, а более высокие увеличивают его. Применяется при следующем выстреле каждого NPC. + + + Множитель разброса ИИ при ранге 100 (ai_dispersion_experienced_k) + + + Множитель, применяемый поверх стандартной кривой разброса по рангу при ранге 100 (легенда; имя cvar соответствует названию переменной в стандартном LTX).\n \nПо умолчанию: 1.0 (без изменений относительно оригинала).\n \nБолее низкие значения уменьшают разброс у NPC высокого ранга, а более высокие увеличивают его. Применяется при следующем выстреле каждого NPC. + diff --git a/gamedata/scripts/lua_help_ex.script b/gamedata/scripts/lua_help_ex.script index 77e26af8f..88dbbd4df 100644 --- a/gamedata/scripts/lua_help_ex.script +++ b/gamedata/scripts/lua_help_ex.script @@ -65,6 +65,9 @@ g_decouple_horz_recoil // calculate horz recoil independently of vert recoil g_use_non_linear_inertia // enable non linear weapon inertia movement + ai_dispersion_novice_k [0; 10] // Stalker NPC weapon-dispersion scale on top of vanilla rank curve, at rank 0; live per shot. Default 1.0 (identity). + ai_dispersion_experienced_k [0; 10] // Stalker NPC weapon-dispersion scale on top of vanilla rank curve, at rank 100; live per shot. Default 1.0 (identity). + } lua extensions { diff --git a/gamedata/scripts/options_modded_exes_stalkers.script b/gamedata/scripts/options_modded_exes_stalkers.script index a337620b5..d96e983ee 100644 --- a/gamedata/scripts/options_modded_exes_stalkers.script +++ b/gamedata/scripts/options_modded_exes_stalkers.script @@ -135,4 +135,21 @@ PAGE = page { def = false, cmd = "ai_move_to_cover_run", }, + line {}, + track { + id = "ai_dispersion_novice_k", + def = 1.0, + min = 0.0, + max = 10.0, + step = 0.1, + cmd = "ai_dispersion_novice_k", + }, + track { + id = "ai_dispersion_experienced_k", + def = 1.0, + min = 0.0, + max = 10.0, + step = 0.1, + cmd = "ai_dispersion_experienced_k", + }, } \ No newline at end of file diff --git a/src/xrGame/ai/stalker/ai_stalker_fire.cpp b/src/xrGame/ai/stalker/ai_stalker_fire.cpp index 6abbd831e..d6c7711c5 100644 --- a/src/xrGame/ai/stalker/ai_stalker_fire.cpp +++ b/src/xrGame/ai/stalker/ai_stalker_fire.cpp @@ -71,11 +71,18 @@ static float const min_throw_distance = 10.f; float g_dispersion_base = 1.0f; float g_dispersion_factor = 1.0f; +float g_ai_dispersion_novice_k = 1.0f; +float g_ai_dispersion_experienced_k = 1.0f; float CAI_Stalker::GetWeaponAccuracy() const { float base = PI / 180.f; base *= m_fRankDisperison; + // cvar-driven rank-curve scale on top of vanilla, identity at defaults (1.0 / 1.0) + CHARACTER_RANK_VALUE rank = Rank(); + clamp(rank, 0, 100); + float rank_k = float(rank) / 100.f; + base *= g_ai_dispersion_experienced_k * rank_k + g_ai_dispersion_novice_k * (1.f - rank_k); CWeapon* W = smart_cast(inventory().ActiveItem()); if (!movement().path_completed()) diff --git a/src/xrGame/console_commands.cpp b/src/xrGame/console_commands.cpp index a90f58d04..03e12fa34 100644 --- a/src/xrGame/console_commands.cpp +++ b/src/xrGame/console_commands.cpp @@ -3025,6 +3025,12 @@ void CCC_RegisterCommands() extern float g_ai_aim_max_angle; CMD4(CCC_Float, "ai_aim_max_angle", &g_ai_aim_max_angle, 0.f, 10.f*PI); + extern float g_ai_dispersion_novice_k; + CMD4(CCC_Float, "ai_dispersion_novice_k", &g_ai_dispersion_novice_k, 0.f, 10.f); + + extern float g_ai_dispersion_experienced_k; + CMD4(CCC_Float, "ai_dispersion_experienced_k", &g_ai_dispersion_experienced_k, 0.f, 10.f); + #ifdef DEBUG extern BOOL g_debug_doors; CMD4(CCC_Integer, "ai_debug_doors", &g_debug_doors, 0, 1);