diff --git a/res/gamedata/configs/ui/maingame.xml b/res/gamedata/configs/ui/maingame.xml
new file mode 100644
index 00000000000..48f638506f8
--- /dev/null
+++ b/res/gamedata/configs/ui/maingame.xml
@@ -0,0 +1,195 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ui_hud_icon_weapon
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ui_inGame2_shield_Psy
+
+
+ ui_inGame2_shield_Radiation
+
+
+ ui_inGame2_shield_biological
+
+
+ ui_inGame2_shield_blood
+
+
+ ui_inGame2_shield_force
+
+
+ ui_inGame2_shield_health
+
+
+ ui_inGame2_shield_stamina
+
+
+ ui_inGame2_shield_radiation_cleanup
+
+
+
+
+ ui_hud_icon_goodmode
+
+
+
+ ui_hud_icon_artefact
+
+
+
+
+
+
+
+
+ ui_hud_icon_PDA
+
+
+
+
+
+ detectors\contact_1
+
+
+
+ counter
+ ui_item_count_back
+
+
+
+ ui_inGame2_Patroni_HUD_active_items_icon
+
+
+
+
+ counter
+ ui_item_count_back
+
+
+
+ ui_inGame2_Patroni_HUD_active_items_icon
+
+
+
+
+ counter
+ ui_item_count_back
+
+
+
+ ui_inGame2_Patroni_HUD_active_items_icon
+
+
+
+
+ counter
+ ui_item_count_back
+
+
+
+ ui_inGame2_Patroni_HUD_active_items_icon
+
+
+
+ quick_use_str_1
+
+
+ quick_use_str_2
+
+
+ quick_use_str_3
+
+
+ quick_use_str_4
+
+
+
+
+
+
+
+
+
+
+
+ ui_inGame2_Patroni_HUD_main_window
+
+
+
+
+
+
+
+
+
+
+ ammo
+
+
+
+ fmj
+
+
+
+ ap
+
+
+
+ gr
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/gamedata/configs/ui/maingame_16.xml b/res/gamedata/configs/ui/maingame_16.xml
new file mode 100644
index 00000000000..fd37c9b1117
--- /dev/null
+++ b/res/gamedata/configs/ui/maingame_16.xml
@@ -0,0 +1,199 @@
+
+
+ <_auto_static x="512" y="384" width="115" height="115" alignment="c" stretch="1" heading="1" xform_anim="xfrom_rotate_3sec" xform_anim_cyclic="1">
+ ui_icons_newPDA_Crclbig_h
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ui_hud_icon_weapon
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ui_inGame2_shield_Psy
+
+
+ ui_inGame2_shield_Radiation
+
+
+ ui_inGame2_shield_biological
+
+
+ ui_inGame2_shield_blood
+
+
+ ui_inGame2_shield_force
+
+
+ ui_inGame2_shield_health
+
+
+ ui_inGame2_shield_stamina
+
+
+ ui_inGame2_shield_radiation_cleanup
+
+
+
+
+ ui_hud_icon_goodmode
+
+
+
+ ui_hud_icon_artefact
+
+
+
+
+
+
+
+
+ ui_hud_icon_PDA
+
+
+
+
+
+ detectors\contact_1
+
+
+
+ counter
+ ui_item_count_back
+
+
+
+ ui_inGame2_Patroni_HUD_active_items_icon
+
+
+
+
+ counter
+ ui_item_count_back
+
+
+
+ ui_inGame2_Patroni_HUD_active_items_icon
+
+
+
+
+ counter
+ ui_item_count_back
+
+
+
+ ui_inGame2_Patroni_HUD_active_items_icon
+
+
+
+
+ counter
+ ui_item_count_back
+
+
+
+ ui_inGame2_Patroni_HUD_active_items_icon
+
+
+
+ quick_use_str_1
+
+
+ quick_use_str_2
+
+
+ quick_use_str_3
+
+
+ quick_use_str_4
+
+
+
+
+
+
+
+
+
+
+ ui_inGame2_Patroni_HUD_main_window
+
+
+
+
+
+
+
+
+
+
+
+ ammo
+
+
+
+ fmj
+
+
+
+ ap
+
+
+
+ gr
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/xrGame/ui/UIBoostStatesWnd.cpp b/src/xrGame/ui/UIBoostStatesWnd.cpp
new file mode 100644
index 00000000000..711199acd2a
--- /dev/null
+++ b/src/xrGame/ui/UIBoostStatesWnd.cpp
@@ -0,0 +1,176 @@
+#include "StdAfx.h"
+#include "UIBoostStatesWnd.h"
+#include "UIHelper.h"
+
+CUIBoostStatesWnd::CUIBoostStatesWnd()
+ : CUIWindow(CUIBoostStatesWnd::GetDebugType()),
+ bHorizontal(true),
+ bInverse(false),
+ dx(0.f),
+ dy(0.f),
+ maxItem(8)
+{
+}
+
+void CUIBoostStatesWnd::InitFromXml(CUIXml& xml, LPCSTR path)
+{
+ ZoneScoped;
+
+ CUIXmlInit::InitWindow(xml, path, 0, this);
+ XML_NODE stored_root = xml.GetLocalRoot();
+
+ XML_NODE new_root = xml.NavigateToNode(path, 0);
+ xml.SetLocalRoot(new_root);
+
+ dx = xml.ReadAttribFlt("settings", 0, "dx", GetWidth());
+ dy = xml.ReadAttribFlt("settings", 0, "dy", GetHeight());
+ bHorizontal = (xml.ReadAttribInt("settings", 0, "horz_align", 1) == 1);
+ bInverse = (xml.ReadAttribInt("settings", 0, "inverse", 0) == 1);
+ maxItem = xml.ReadAttribInt("settings", 0, "max_item", 8);
+ constexpr std::tuple booster_list[] = {
+ {eBoostHpRestore, "indicator_booster_health"},
+ {eBoostPowerRestore, "indicator_booster_power"},
+ {eBoostRadiationRestore, "indicator_booster_rad"},
+ {eBoostBleedingRestore, "indicator_booster_wound"},
+ {eBoostMaxWeight, "indicator_booster_weight"},
+ {eBoostRadiationProtection, "indicator_booster_radia"},
+ {eBoostTelepaticProtection, "indicator_booster_psy"},
+ {eBoostChemicalBurnProtection, "indicator_booster_chem"}
+ };
+ for (auto [type, tpath] : booster_list)
+ {
+ CUIStatic* booster;
+ booster = UIHelper::CreateStatic(xml, tpath, this, false);
+ indBoostState.emplace(type, booster);
+ }
+ xml.SetLocalRoot(stored_root);
+}
+
+void CUIBoostStatesWnd::DrawBoosterIndicators()
+{
+ if (indBoostPos.empty())
+ return;
+ for (const auto& [type, item] : indBoostState)
+ {
+ if (item && item->IsShown())
+ {
+ item->Update();
+ item->Draw();
+ }
+ }
+}
+
+void CUIBoostStatesWnd::UpdateBoosterIndicators(const CEntityCondition::BOOSTER_MAP& influences)
+{
+ LPCSTR str_flag = "ui_slow_blinking_alpha";
+ u8 flags = 0;
+ flags |= LA_CYCLIC;
+ flags |= LA_ONLYALPHA;
+ flags |= LA_TEXTURECOLOR;
+
+ for (const auto& [type, item] : indBoostState)
+ {
+ if (influences.empty())
+ {
+ item->Show(false);
+ continue;
+ }
+ CEntityCondition::BOOSTER_MAP::const_iterator it = influences.find(type);
+ if (it != influences.end())
+ {
+ if (!item->IsShown())
+ {
+ indBoostPos.push_back(type);
+ item->Show(true);
+ }
+ if (it->second.fBoostTime <= 3.0f)
+ {
+ item->SetColorAnimation(str_flag, flags);
+ }
+ else
+ {
+ item->ResetColorAnimation();
+ }
+ }
+ else
+ {
+ item->Show(false);
+ }
+ }
+ if (!influences.empty() || !indBoostPos.empty())
+ {
+ UpdateBoosterPosition(influences);
+ }
+}
+
+void CUIBoostStatesWnd::UpdateBoosterPosition(const CEntityCondition::BOOSTER_MAP& influences)
+{
+ if (indBoostPos.empty() && !influences.empty())
+ {
+ for (const auto& [type, item] : indBoostState)
+ {
+ if (item && item->IsShown())
+ {
+ item->Show(false);
+ }
+ }
+ }
+ if (indBoostPos.empty())
+ return;
+ u8 i = 0, j = 0, max = maxItem - 1;
+ if (bInverse)
+ {
+ for (auto it = indBoostPos.end() - 1; it >= indBoostPos.begin(); it--)
+ {
+ xr_map::const_iterator item = indBoostState.find(*it);
+ if (item->second->IsShown())
+ {
+ (bHorizontal ? item->second->SetWndPos({dx * i, dy * j}) :
+ item->second->SetWndPos({dx * j, dy * i}));
+ if (i >= maxItem)
+ {
+ i = 0;
+ j++;
+ }
+ else
+ {
+ i++;
+ }
+ item->second->Update();
+ item->second->Draw();
+ }
+ else
+ {
+ indBoostPos.erase(it);
+ }
+ }
+ }
+ else
+ {
+ for (auto it = indBoostPos.begin(); it != indBoostPos.end(); it++)
+ {
+ xr_map::const_iterator item = indBoostState.find(*it);
+ if (item->second->IsShown())
+ {
+ (bHorizontal ? item->second->SetWndPos({dx * i, dy * j}) :
+ item->second->SetWndPos({dx * j, dy * i}));
+ if (i >= max)
+ {
+ i = 0;
+ j++;
+ }
+ else
+ {
+ i++;
+ }
+ item->second->Update();
+ item->second->Draw();
+ }
+ else
+ {
+ indBoostPos.erase(it);
+ it--;
+ }
+ }
+ }
+}
diff --git a/src/xrGame/ui/UIBoostStatesWnd.h b/src/xrGame/ui/UIBoostStatesWnd.h
new file mode 100644
index 00000000000..cc8f18abeb9
--- /dev/null
+++ b/src/xrGame/ui/UIBoostStatesWnd.h
@@ -0,0 +1,24 @@
+#pragma once
+#include "xrUICore/Windows/UIWindow.h"
+#include "EntityCondition.h"
+
+
+class CUIStatic;
+class CUIXml;
+
+class CUIBoostStatesWnd final : public CUIWindow
+{
+public:
+ CUIBoostStatesWnd();
+ void InitFromXml(CUIXml& xml, LPCSTR path);
+ void DrawBoosterIndicators();
+ void UpdateBoosterIndicators(const CEntityCondition::BOOSTER_MAP& influences);
+ void UpdateBoosterPosition(const CEntityCondition::BOOSTER_MAP& influences);
+
+private:
+ bool bHorizontal, bInverse;
+ float dx, dy;
+ u8 maxItem;
+ xr_vector indBoostPos;
+ xr_map indBoostState;
+};
diff --git a/src/xrGame/ui/UIMainIngameWnd.cpp b/src/xrGame/ui/UIMainIngameWnd.cpp
index ce485230f4d..85c15baf03c 100644
--- a/src/xrGame/ui/UIMainIngameWnd.cpp
+++ b/src/xrGame/ui/UIMainIngameWnd.cpp
@@ -43,6 +43,7 @@
#include "UIActorMenu.h"
#include "xrUICore/ProgressBar/UIProgressShape.h"
#include "UIArtefactPanel.h"
+#include "UIBoostStatesWnd.h"
#include "Include/xrRender/Kinematics.h"
@@ -120,29 +121,6 @@ void CUIMainIngameWnd::Init()
m_ind_outfit_broken = UIHelper::CreateStatic(uiXml, "indicator_outfit_broken", this, false);
m_ind_overweight = UIHelper::CreateStatic(uiXml, "indicator_overweight", this, false);
- if ((m_ind_boost_psy = UIHelper::CreateStatic(uiXml, "indicator_booster_psy", this, false)))
- m_ind_boost_psy->Show(false);
-
- if ((m_ind_boost_radia = UIHelper::CreateStatic(uiXml, "indicator_booster_radia", this, false)))
- m_ind_boost_radia->Show(false);
-
- if ((m_ind_boost_chem = UIHelper::CreateStatic(uiXml, "indicator_booster_chem", this, false)))
- m_ind_boost_chem->Show(false);
-
- if ((m_ind_boost_wound = UIHelper::CreateStatic(uiXml, "indicator_booster_wound", this, false)))
- m_ind_boost_wound->Show(false);
-
- if ((m_ind_boost_weight = UIHelper::CreateStatic(uiXml, "indicator_booster_weight", this, false)))
- m_ind_boost_weight->Show(false);
-
- if ((m_ind_boost_health = UIHelper::CreateStatic(uiXml, "indicator_booster_health", this, false)))
- m_ind_boost_health->Show(false);
-
- if ((m_ind_boost_power = UIHelper::CreateStatic(uiXml, "indicator_booster_power", this, false)))
- m_ind_boost_power->Show(false);
-
- if ((m_ind_boost_rad = UIHelper::CreateStatic(uiXml, "indicator_booster_rad", this, false)))
- m_ind_boost_rad->Show(false);
// Загружаем иконки
/* if ( IsGameTypeSingle() )
@@ -255,6 +233,11 @@ void CUIMainIngameWnd::Init()
i++;
}
+ m_ui_boost_states = xr_new();
+ m_ui_boost_states->SetAutoDelete(true);
+ AttachChild(m_ui_boost_states);
+ m_ui_boost_states->InitFromXml(uiXml, "booster_states");
+
HUD_SOUND_ITEM::LoadSound("maingame_ui", "snd_new_contact", m_contactSnd, SOUND_TYPE_IDLE);
}
@@ -891,193 +874,17 @@ void CUIMainIngameWnd::DrawMainIndicatorsForInventory()
return;
UpdateQuickSlots();
- UpdateBoosterIndicators(pActor->conditions().GetCurBoosterInfluences());
+ m_ui_boost_states->UpdateBoosterIndicators(pActor->conditions().GetCurBoosterInfluences());
for (const auto& slot : m_quick_slots_icons)
slot->Draw();
for (const auto& slot : m_quick_slots_texts)
slot->Draw();
-
- if (m_ind_boost_psy && m_ind_boost_psy->IsShown())
- {
- m_ind_boost_psy->Update();
- m_ind_boost_psy->Draw();
- }
-
- if (m_ind_boost_radia && m_ind_boost_radia->IsShown())
- {
- m_ind_boost_radia->Update();
- m_ind_boost_radia->Draw();
- }
-
- if (m_ind_boost_chem && m_ind_boost_chem->IsShown())
- {
- m_ind_boost_chem->Update();
- m_ind_boost_chem->Draw();
- }
-
- if (m_ind_boost_wound && m_ind_boost_wound->IsShown())
- {
- m_ind_boost_wound->Update();
- m_ind_boost_wound->Draw();
- }
-
- if (m_ind_boost_weight && m_ind_boost_weight->IsShown())
- {
- m_ind_boost_weight->Update();
- m_ind_boost_weight->Draw();
- }
-
- if (m_ind_boost_health && m_ind_boost_health->IsShown())
- {
- m_ind_boost_health->Update();
- m_ind_boost_health->Draw();
- }
-
- if (m_ind_boost_power && m_ind_boost_power->IsShown())
- {
- m_ind_boost_power->Update();
- m_ind_boost_power->Draw();
- }
-
- if (m_ind_boost_rad && m_ind_boost_rad->IsShown())
- {
- m_ind_boost_rad->Update();
- m_ind_boost_rad->Draw();
- }
-
+ m_ui_boost_states->DrawBoosterIndicators();
m_ui_hud_states->DrawZoneIndicators();
}
-
-void CUIMainIngameWnd::UpdateBoosterIndicators(const CEntityCondition::BOOSTER_MAP& influences)
+void CUIMainIngameWnd::UpdateBoosterIndicators(const CEntityCondition::BOOSTER_MAP& influences)
{
- if (m_ind_boost_psy)
- m_ind_boost_psy->Show(false);
- if (m_ind_boost_radia)
- m_ind_boost_radia->Show(false);
- if (m_ind_boost_chem)
- m_ind_boost_chem->Show(false);
- if (m_ind_boost_wound)
- m_ind_boost_wound->Show(false);
- if (m_ind_boost_weight)
- m_ind_boost_weight->Show(false);
- if (m_ind_boost_health)
- m_ind_boost_health->Show(false);
- if (m_ind_boost_power)
- m_ind_boost_power->Show(false);
- if (m_ind_boost_rad)
- m_ind_boost_rad->Show(false);
-
- LPCSTR str_flag = "ui_slow_blinking_alpha";
- u8 flags = 0;
- flags |= LA_CYCLIC;
- flags |= LA_ONLYALPHA;
- flags |= LA_TEXTURECOLOR;
-
- for(const auto& [_, booster] : influences)
- {
- switch (booster.m_type)
- {
- case eBoostHpRestore:
- {
- if (m_ind_boost_health)
- {
- m_ind_boost_health->Show(true);
- if (booster.fBoostTime <= 3.0f)
- m_ind_boost_health->SetColorAnimation(str_flag, flags);
- else
- m_ind_boost_health->ResetColorAnimation();
- }
- break;
- }
- case eBoostPowerRestore:
- {
- if (m_ind_boost_power)
- {
- m_ind_boost_power->Show(true);
- if (booster.fBoostTime <= 3.0f)
- m_ind_boost_power->SetColorAnimation(str_flag, flags);
- else
- m_ind_boost_power->ResetColorAnimation();
- }
- break;
- }
- case eBoostRadiationRestore:
- {
- if (m_ind_boost_rad)
- {
- m_ind_boost_rad->Show(true);
- if (booster.fBoostTime <= 3.0f)
- m_ind_boost_rad->SetColorAnimation(str_flag, flags);
- else
- m_ind_boost_rad->ResetColorAnimation();
- }
- break;
- }
- case eBoostBleedingRestore:
- {
- if (m_ind_boost_wound)
- {
- m_ind_boost_wound->Show(true);
- if (booster.fBoostTime <= 3.0f)
- m_ind_boost_wound->SetColorAnimation(str_flag, flags);
- else
- m_ind_boost_wound->ResetColorAnimation();
- }
- break;
- }
- case eBoostMaxWeight:
- {
- if (m_ind_boost_weight)
- {
- m_ind_boost_weight->Show(true);
- if (booster.fBoostTime <= 3.0f)
- m_ind_boost_weight->SetColorAnimation(str_flag, flags);
- else
- m_ind_boost_weight->ResetColorAnimation();
- }
- break;
- }
- case eBoostRadiationImmunity:
- case eBoostRadiationProtection:
- {
- if (m_ind_boost_radia)
- {
- m_ind_boost_radia->Show(true);
- if (booster.fBoostTime <= 3.0f)
- m_ind_boost_radia->SetColorAnimation(str_flag, flags);
- else
- m_ind_boost_radia->ResetColorAnimation();
- }
- break;
- }
- case eBoostTelepaticImmunity:
- case eBoostTelepaticProtection:
- {
- if (m_ind_boost_psy)
- {
- m_ind_boost_psy->Show(true);
- if (booster.fBoostTime <= 3.0f)
- m_ind_boost_psy->SetColorAnimation(str_flag, flags);
- else
- m_ind_boost_psy->ResetColorAnimation();
- }
- break;
- }
- case eBoostChemicalBurnImmunity:
- case eBoostChemicalBurnProtection:
- {
- if (m_ind_boost_chem)
- {
- m_ind_boost_chem->Show(true);
- if (booster.fBoostTime <= 3.0f)
- m_ind_boost_chem->SetColorAnimation(str_flag, flags);
- else
- m_ind_boost_chem->ResetColorAnimation();
- }
- break;
- }
- }
- }
+ m_ui_boost_states->UpdateBoosterIndicators(influences);
}
diff --git a/src/xrGame/ui/UIMainIngameWnd.h b/src/xrGame/ui/UIMainIngameWnd.h
index ee25106e5c9..325f38993a3 100644
--- a/src/xrGame/ui/UIMainIngameWnd.h
+++ b/src/xrGame/ui/UIMainIngameWnd.h
@@ -14,7 +14,7 @@ class CInventoryItem;
class CUIHudStatesWnd;
class CUIMotionIcon;
class CUIArtefactPanel;
-
+class CUIBoostStatesWnd;
class CUIMainIngameWnd final : public CUIWindow
{
public:
@@ -34,6 +34,7 @@ class CUIMainIngameWnd final : public CUIWindow
CUIZoneMap* UIZoneMap{};
CUIHudStatesWnd* m_ui_hud_states{};
+ CUIBoostStatesWnd* m_ui_boost_states{};
CUIStatic* m_ind_bleeding{};
CUIStatic* m_ind_radiation{};
@@ -44,15 +45,6 @@ class CUIMainIngameWnd final : public CUIWindow
CUIStatic* m_ind_overweight{};
public:
- CUIStatic* m_ind_boost_psy{};
- CUIStatic* m_ind_boost_radia{};
- CUIStatic* m_ind_boost_chem{};
- CUIStatic* m_ind_boost_wound{};
- CUIStatic* m_ind_boost_weight{};
- CUIStatic* m_ind_boost_health{};
- CUIStatic* m_ind_boost_power{};
- CUIStatic* m_ind_boost_rad{};
-
CUIArtefactPanel* UIArtefactPanel{};
void ShowZoneMap(bool status);
diff --git a/src/xrGame/xrGame.vcxproj b/src/xrGame/xrGame.vcxproj
index 762c7b46e36..fb3520cbd77 100644
--- a/src/xrGame/xrGame.vcxproj
+++ b/src/xrGame/xrGame.vcxproj
@@ -1307,6 +1307,7 @@
+
@@ -3227,6 +3228,7 @@
+
diff --git a/src/xrGame/xrGame.vcxproj.filters b/src/xrGame/xrGame.vcxproj.filters
index ba820c81759..a973f949968 100644
--- a/src/xrGame/xrGame.vcxproj.filters
+++ b/src/xrGame/xrGame.vcxproj.filters
@@ -6495,6 +6495,9 @@
Core\Client\Objects\items & weapons\HudItem
+
+ UI\Common\MainIngame
+
@@ -9854,6 +9857,9 @@
UI\Common\PDA\Tasks
+
+ UI\Common\MainIngame
+