diff --git a/src/xrGame/HudItem.h b/src/xrGame/HudItem.h index 76a5fc26ba4..4291f1dbb22 100644 --- a/src/xrGame/HudItem.h +++ b/src/xrGame/HudItem.h @@ -140,6 +140,8 @@ class CHudItem : public CHUDState virtual void on_b_hud_detach(); IC BOOL HudInertionEnabled() const { return m_huditem_flags.test(fl_inertion_enable); } IC BOOL HudInertionAllowed() const { return m_huditem_flags.test(fl_inertion_allow); } + virtual float GetInertionFactor() { return 1.f; }; //--#SM+#-- + virtual float GetInertionPowerFactor() { return 1.f; }; //--#SM+#-- virtual void render_hud_mode(){}; virtual bool need_renderable() { return true; }; virtual void render_item_3d_ui() {} diff --git a/src/xrGame/PHCommander.cpp b/src/xrGame/PHCommander.cpp index 289aa929cf3..2dfd33cbf09 100644 --- a/src/xrGame/PHCommander.cpp +++ b/src/xrGame/PHCommander.cpp @@ -22,7 +22,7 @@ CPHCall::~CPHCall() bool CPHCall::obsolete() { return m_action->obsolete() || m_condition->obsolete(); } void CPHCall::check() { - if (m_condition->is_true() && m_action) + if (m_condition && m_condition->is_true() && m_action) m_action->run(); } diff --git a/src/xrGame/Weapon.cpp b/src/xrGame/Weapon.cpp index 8a1a2503ed4..2f8d40f187f 100644 --- a/src/xrGame/Weapon.cpp +++ b/src/xrGame/Weapon.cpp @@ -1342,7 +1342,8 @@ void CWeapon::OnZoomIn() else m_zoom_params.m_fCurrentZoomFactor = CurrentZoomFactor(); - EnableHudInertion(FALSE); + // Отключаем инерцию (Заменено GetInertionFactor()) + // EnableHudInertion(FALSE); if (m_zoom_params.m_bZoomDofEnabled && !IsScopeAttached()) GamePersistent().SetEffectorDOF(m_zoom_params.m_ZoomDof); @@ -1372,7 +1373,9 @@ void CWeapon::OnZoomOut() m_zoom_params.m_bIsZoomModeNow = false; m_fRTZoomFactor = GetZoomFactor(); // store current m_zoom_params.m_fCurrentZoomFactor = g_fov; - EnableHudInertion(TRUE); + + // Включаем инерцию (также заменено GetInertionFactor()) + // EnableHudInertion (TRUE); GamePersistent().RestoreEffectorDOF(); diff --git a/src/xrGame/player_hud.cpp b/src/xrGame/player_hud.cpp index d02aeb83c77..608c13e2a9e 100644 --- a/src/xrGame/player_hud.cpp +++ b/src/xrGame/player_hud.cpp @@ -1,4 +1,4 @@ -#include "stdafx.h" +#include "stdafx.h" #include "player_hud.h" #include "HudItem.h" #include "ui_base.h" @@ -14,6 +14,17 @@ player_hud* g_player_hud = nullptr; Fvector _ancor_pos; Fvector _wpn_root_pos; +// clang-format off +static const float PITCH_OFFSET_R = 0.017f; // Насколько сильно ствол смещается вбок (влево) при вертикальных поворотах камеры --#SM+#-- +static const float PITCH_OFFSET_N = 0.012f; // Насколько сильно ствол поднимается\опускается при вертикальных поворотах камеры --#SM+#-- +static const float PITCH_OFFSET_D = 0.02f; // Насколько сильно ствол приближается\отдаляется при вертикальных поворотах камеры --#SM+#-- +static const float PITCH_LOW_LIMIT = -PI; // Минимальное значение pitch при использовании совместно с PITCH_OFFSET_N --#SM+#-- +static const float ORIGIN_OFFSET = -0.05f; // Фактор влияния инерции на положение ствола (чем меньше, тем маштабней инерция) --#SM+#-- +static const float ORIGIN_OFFSET_AIM = -0.03f; // (Для прицеливания) --#SM+#-- +static const float TENDTO_SPEED = 5.f; // Скорость нормализации положения ствола --#SM+#-- +static const float TENDTO_SPEED_AIM = 8.f; // (Для прицеливания) --#SM+#-- +// clang-format on + float CalcMotionSpeed(const shared_str& anim_name) { if (!IsGameTypeSingle() && (anim_name == "anm_show" || anim_name == "anm_hide")) @@ -281,6 +292,19 @@ void hud_item_measures::load(const shared_str& sect_name, IKinematics* K) sect_name.c_str()); m_prop_flags.set(e_16x9_mode_now, is_16x9); + + //Загрузка параметров инерции --#SM+# Begin-- + m_inertion_params.m_pitch_offset_r = READ_IF_EXISTS(pSettings, r_float, sect_name, "pitch_offset_right", PITCH_OFFSET_R); + m_inertion_params.m_pitch_offset_n = READ_IF_EXISTS(pSettings, r_float, sect_name, "pitch_offset_up", PITCH_OFFSET_N); + m_inertion_params.m_pitch_offset_d = READ_IF_EXISTS(pSettings, r_float, sect_name, "pitch_offset_forward", PITCH_OFFSET_D); + m_inertion_params.m_pitch_low_limit = READ_IF_EXISTS(pSettings, r_float, sect_name, "pitch_offset_up_low_limit", PITCH_LOW_LIMIT); + + m_inertion_params.m_origin_offset = READ_IF_EXISTS(pSettings, r_float, sect_name, "inertion_origin_offset", ORIGIN_OFFSET); + m_inertion_params.m_origin_offset_aim = READ_IF_EXISTS(pSettings, r_float, sect_name, "inertion_origin_aim_offset", ORIGIN_OFFSET_AIM); + m_inertion_params.m_tendto_speed = READ_IF_EXISTS(pSettings, r_float, sect_name, "inertion_tendto_speed", TENDTO_SPEED); + m_inertion_params.m_tendto_speed_aim = READ_IF_EXISTS(pSettings, r_float, sect_name, "inertion_tendto_aim_speed", TENDTO_SPEED_AIM); + //--#SM+# End-- + } attachable_hud_item::~attachable_hud_item() @@ -598,22 +622,43 @@ void player_hud::update_additional(Fmatrix& trans) m_attached_items[1]->update_hud_additional(trans); } -static const float PITCH_OFFSET_R = 0.017f; -static const float PITCH_OFFSET_N = 0.012f; -static const float PITCH_OFFSET_D = 0.02f; -static const float ORIGIN_OFFSET = -0.05f; -static const float TENDTO_SPEED = 5.f; - void player_hud::update_inertion(Fmatrix& trans) { if (inertion_allowed()) { + attachable_hud_item* pMainHud = m_attached_items[0]; + Fmatrix xform; Fvector& origin = trans.c; xform = trans; static Fvector st_last_dir = {0, 0, 0}; + // load params + hud_item_measures::inertion_params inertion_data; + if (pMainHud != NULL) + { // Загружаем параметры инерции из основного худа + inertion_data.m_pitch_offset_r = pMainHud->m_measures.m_inertion_params.m_pitch_offset_r; + inertion_data.m_pitch_offset_n = pMainHud->m_measures.m_inertion_params.m_pitch_offset_n; + inertion_data.m_pitch_offset_d = pMainHud->m_measures.m_inertion_params.m_pitch_offset_d; + inertion_data.m_pitch_low_limit = pMainHud->m_measures.m_inertion_params.m_pitch_low_limit; + inertion_data.m_origin_offset = pMainHud->m_measures.m_inertion_params.m_origin_offset; + inertion_data.m_origin_offset_aim = pMainHud->m_measures.m_inertion_params.m_origin_offset_aim; + inertion_data.m_tendto_speed = pMainHud->m_measures.m_inertion_params.m_tendto_speed; + inertion_data.m_tendto_speed_aim = pMainHud->m_measures.m_inertion_params.m_tendto_speed_aim; + } + else + { // Загружаем дефолтные параметры инерции + inertion_data.m_pitch_offset_r = PITCH_OFFSET_R; + inertion_data.m_pitch_offset_n = PITCH_OFFSET_N; + inertion_data.m_pitch_offset_d = PITCH_OFFSET_D; + inertion_data.m_pitch_low_limit = PITCH_LOW_LIMIT; + inertion_data.m_origin_offset = ORIGIN_OFFSET; + inertion_data.m_origin_offset_aim = ORIGIN_OFFSET_AIM; + inertion_data.m_tendto_speed = TENDTO_SPEED; + inertion_data.m_tendto_speed_aim = TENDTO_SPEED_AIM; + } + // calc difference Fvector diff_dir; diff_dir.sub(xform.k, st_last_dir); @@ -631,14 +676,46 @@ void player_hud::update_inertion(Fmatrix& trans) } // tend to forward - st_last_dir.mad(diff_dir, TENDTO_SPEED * Device.fTimeDelta); - origin.mad(diff_dir, ORIGIN_OFFSET); + float _tendto_speed, _origin_offset; + if (pMainHud != NULL && pMainHud->m_parent_hud_item->GetCurrentHudOffsetIdx() > 0) + { // Худ в режиме "Прицеливание" + float factor = pMainHud->m_parent_hud_item->GetInertionFactor(); + _tendto_speed = inertion_data.m_tendto_speed_aim - (inertion_data.m_tendto_speed_aim - inertion_data.m_tendto_speed) * factor; + _origin_offset = + inertion_data.m_origin_offset_aim - (inertion_data.m_origin_offset_aim - inertion_data.m_origin_offset) * factor; + } + else + { // Худ в режиме "От бедра" + _tendto_speed = inertion_data.m_tendto_speed; + _origin_offset = inertion_data.m_origin_offset; + } + + // Фактор силы инерции + if (pMainHud != NULL) + { + float power_factor = pMainHud->m_parent_hud_item->GetInertionPowerFactor(); + _tendto_speed *= power_factor; + _origin_offset *= power_factor; + } + + st_last_dir.mad(diff_dir, _tendto_speed * Device.fTimeDelta); + origin.mad(diff_dir, _origin_offset); // pitch compensation float pitch = angle_normalize_signed(xform.k.getP()); - origin.mad(xform.k, -pitch * PITCH_OFFSET_D); - origin.mad(xform.i, -pitch * PITCH_OFFSET_R); - origin.mad(xform.j, -pitch * PITCH_OFFSET_N); + + if (pMainHud != NULL) + pitch *= pMainHud->m_parent_hud_item->GetInertionFactor(); + + // Отдаление\приближение + origin.mad(xform.k, -pitch * inertion_data.m_pitch_offset_d); + + // Сдвиг в противоположную часть экрана + origin.mad(xform.i, -pitch * inertion_data.m_pitch_offset_r); + + // Подьём\опускание + clamp(pitch, inertion_data.m_pitch_low_limit, PI); + origin.mad(xform.j, -pitch * inertion_data.m_pitch_offset_n); } } diff --git a/src/xrGame/player_hud.h b/src/xrGame/player_hud.h index ab39077b576..0e040de4807 100644 --- a/src/xrGame/player_hud.h +++ b/src/xrGame/player_hud.h @@ -55,6 +55,19 @@ struct hud_item_measures Fvector m_hands_attach[2]; // pos,rot void load(const shared_str& sect_name, IKinematics* K); + + struct inertion_params + { + float m_pitch_offset_r; + float m_pitch_offset_n; + float m_pitch_offset_d; + float m_pitch_low_limit; + float m_origin_offset; + float m_origin_offset_aim; + float m_tendto_speed; + float m_tendto_speed_aim; + }; + inertion_params m_inertion_params; //--#SM+#-- }; struct attachable_hud_item