From 68869f5b4b4139958942294522471ff9f9f6c8f9 Mon Sep 17 00:00:00 2001
From: lcy <1459594991@qq.com>
Date: 星期三, 27 五月 2026 14:56:13 +0800
Subject: [PATCH] 656 布阵阵型增加混搭武将组合

---
 Main/Config/Configs/HeroLineupHaloConfig.cs        |   19 +-
 Main/System/HeroUI/HeroPosWin.cs                   |   25 ++++
 Main/System/HeroUI/HeroUIManager.OnTeam.cs         |  112 ++++++++++++++++++
 Main/System/Arena/HeroCountryComponent.cs          |   26 ++++
 Main/System/HeroUI/HeroFormationCell.cs            |   93 +++++++++++++++
 Main/Config/PartialConfigs/HeroLineupHaloConfig.cs |   37 +++++-
 Main/System/HeroUI/HeroFormationWin.cs             |   28 +++-
 7 files changed, 318 insertions(+), 22 deletions(-)

diff --git a/Main/Config/Configs/HeroLineupHaloConfig.cs b/Main/Config/Configs/HeroLineupHaloConfig.cs
index eb8fe4f..a645079 100644
--- a/Main/Config/Configs/HeroLineupHaloConfig.cs
+++ b/Main/Config/Configs/HeroLineupHaloConfig.cs
@@ -1,6 +1,6 @@
 锘�//--------------------------------------------------------
 //    [Author]:           YYL
-//    [  Date ]:           2025骞�8鏈�5鏃�
+//    [  Date ]:           Wednesday, May 27, 2026
 //--------------------------------------------------------
 
 using System.Collections.Generic;
@@ -18,6 +18,7 @@
 
     public int Id;
 	public int Country;
+	public int Countrys;
 	public int NeedHeroCount;
 	public int[] AttrIDList;
 	public int[] AttrValueList;
@@ -36,15 +37,17 @@
 
 			int.TryParse(tables[1],out Country); 
 
-			int.TryParse(tables[2],out NeedHeroCount); 
+			int.TryParse(tables[2],out Countrys); 
 
-			if (tables[3].Contains("["))
+			int.TryParse(tables[3],out NeedHeroCount); 
+
+			if (tables[4].Contains("["))
 			{
-				AttrIDList = JsonMapper.ToObject<int[]>(tables[3]);
+				AttrIDList = JsonMapper.ToObject<int[]>(tables[4]);
 			}
 			else
 			{
-				string[] AttrIDListStringArray = tables[3].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				string[] AttrIDListStringArray = tables[4].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
 				AttrIDList = new int[AttrIDListStringArray.Length];
 				for (int i=0;i<AttrIDListStringArray.Length;i++)
 				{
@@ -52,13 +55,13 @@
 				}
 			}
 
-			if (tables[4].Contains("["))
+			if (tables[5].Contains("["))
 			{
-				AttrValueList = JsonMapper.ToObject<int[]>(tables[4]);
+				AttrValueList = JsonMapper.ToObject<int[]>(tables[5]);
 			}
 			else
 			{
-				string[] AttrValueListStringArray = tables[4].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				string[] AttrValueListStringArray = tables[5].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
 				AttrValueList = new int[AttrValueListStringArray.Length];
 				for (int i=0;i<AttrValueListStringArray.Length;i++)
 				{
diff --git a/Main/Config/PartialConfigs/HeroLineupHaloConfig.cs b/Main/Config/PartialConfigs/HeroLineupHaloConfig.cs
index 59d8155..83b5589 100644
--- a/Main/Config/PartialConfigs/HeroLineupHaloConfig.cs
+++ b/Main/Config/PartialConfigs/HeroLineupHaloConfig.cs
@@ -6,17 +6,34 @@
     // 鍥藉 鏁伴噺
     private static Dictionary<int, Dictionary<int, HeroLineupHaloConfig>> configDics = new Dictionary<int, Dictionary<int, HeroLineupHaloConfig>>();
 
+    // 娣锋惌闃靛瀷绱㈠紩锛欿ey=Countrys, Value={NeedHeroCount鈫扖onfig}
+    private static Dictionary<int, Dictionary<int, HeroLineupHaloConfig>> mixedConfigDics = new Dictionary<int, Dictionary<int, HeroLineupHaloConfig>>();
+
     protected override void OnConfigParseCompleted()
     {
-
-        Dictionary<int, HeroLineupHaloConfig> tempDic = null;
-        if (!configDics.TryGetValue(Country, out tempDic))
+        if (Country == 0 && Countrys > 0)
         {
-            tempDic = new Dictionary<int, HeroLineupHaloConfig>();
-            configDics.Add(Country, tempDic);
+            // 娣锋惌闃靛瀷閰嶇疆
+            Dictionary<int, HeroLineupHaloConfig> tempDic = null;
+            if (!mixedConfigDics.TryGetValue(Countrys, out tempDic))
+            {
+                tempDic = new Dictionary<int, HeroLineupHaloConfig>();
+                mixedConfigDics.Add(Countrys, tempDic);
+            }
+            tempDic[NeedHeroCount] = this;
         }
+        else
+        {
+            // 鍗曞浗瀹堕厤缃�
+            Dictionary<int, HeroLineupHaloConfig> tempDic = null;
+            if (!configDics.TryGetValue(Country, out tempDic))
+            {
+                tempDic = new Dictionary<int, HeroLineupHaloConfig>();
+                configDics.Add(Country, tempDic);
+            }
 
-        tempDic[NeedHeroCount] = this;
+            tempDic[NeedHeroCount] = this;
+        }
     }
 
     public static HeroLineupHaloConfig GetConfig(int country, int count)
@@ -32,6 +49,14 @@
         return configDics[country][count];
     }
 
+    /// <summary>
+    /// 鑾峰彇鎵�鏈夋贩鎼厤缃�
+    /// </summary>
+    public static Dictionary<int, Dictionary<int, HeroLineupHaloConfig>> GetAllMixedConfigs()
+    {
+        return mixedConfigDics;
+    }
+
     public static Dictionary<int, HeroLineupHaloConfig> GetAttrsByCountry(int country)
     {
         Dictionary<int, HeroLineupHaloConfig> attrs;
diff --git a/Main/System/Arena/HeroCountryComponent.cs b/Main/System/Arena/HeroCountryComponent.cs
index 10f3d5b..5d7ca47 100644
--- a/Main/System/Arena/HeroCountryComponent.cs
+++ b/Main/System/Arena/HeroCountryComponent.cs
@@ -23,6 +23,32 @@
     public void RefreshOnTeamCountry(List<TeamHero> teamHeroes, bool playEffect = false)
     {
         this.teamHeroes = teamHeroes;
+
+        // 1. 鍏堟鏌ユ贩鎼樀鍨�
+        var mixedConfig = HeroUIManager.Instance.GetMixedFormationConfig(teamHeroes);
+        if (mixedConfig != null)
+        {
+            countryOnImg.SetSprite("heroTeamCountryHe");
+            var participatingCountries = HeroUIManager.Instance.GetParticipatingCountriesByPriority(teamHeroes);
+            int totalPoints = mixedConfig.Countrys * mixedConfig.NeedHeroCount;
+            for (int i = 0; i < OnCountImgs.Count; i++)
+            {
+                if (i < totalPoints)
+                {
+                    int countryIndex = i / mixedConfig.NeedHeroCount;
+                    OnCountImgs[i].SetActive(true);
+                    OnCountImgs[i].SetSprite("heroTeamCountryPoint" + participatingCountries[countryIndex]);
+                }
+                else
+                {
+                    OnCountImgs[i].SetActive(false);
+                }
+            }
+            if (playEffect)
+                countryEffect.Play();
+            return;
+        }
+
         Int2 result = HeroUIManager.Instance.GetMaxCountHeroCountry(teamHeroes);
 
         var config = HeroLineupHaloConfig.GetConfig(result.x, result.y);
diff --git a/Main/System/HeroUI/HeroFormationCell.cs b/Main/System/HeroUI/HeroFormationCell.cs
index 2ab74ca..1fa3f1a 100644
--- a/Main/System/HeroUI/HeroFormationCell.cs
+++ b/Main/System/HeroUI/HeroFormationCell.cs
@@ -1,3 +1,4 @@
+using System.Collections.Generic;
 using System.Linq;
 using UnityEngine;
 using UnityEngine.UI;
@@ -12,6 +13,13 @@
 
     public void Display(int index)
     {
+        // 绗�5涓牸瀛愪负娣锋惌闃靛瀷
+        if (index == 4)
+        {
+            DisplayMixedFormation();
+            return;
+        }
+
         Int2 result;
         if (HeroUIManager.Instance.isCustonHeroFormation)
         {
@@ -75,5 +83,90 @@
         }
         attrText.text = text;
     }
+
+    void DisplayMixedFormation()
+    {
+        // 鑾峰彇褰撳墠婵�娲荤殑娣锋惌閰嶇疆
+        HeroLineupHaloConfig activeMixedConfig;
+        List<TeamHero> teamHeroes = null;
+        if (HeroUIManager.Instance.isCustonHeroFormation)
+            teamHeroes = HeroUIManager.Instance.custonTeamHeroes;
+
+        if (teamHeroes != null)
+            activeMixedConfig = HeroUIManager.Instance.GetMixedFormationConfig(teamHeroes);
+        else
+            activeMixedConfig = HeroUIManager.Instance.GetMixedFormationConfig(HeroUIManager.Instance.selectTeamType, true);
+
+        bool hasActive = activeMixedConfig != null;
+        activeImg.SetActive(hasActive);
+        countryOnImg.SetSprite("heroTeamCountryHe");
+
+        // 婵�娲荤偣鏄剧ず锛氫娇鐢ㄥ綋鍓嶆縺娲婚厤缃殑闃佃惀棰滆壊
+        List<int> participatingCountries = null;
+        if (teamHeroes != null)
+            participatingCountries = HeroUIManager.Instance.GetParticipatingCountriesByPriority(teamHeroes);
+        else
+            participatingCountries = HeroUIManager.Instance.GetParticipatingCountriesByPriority(HeroUIManager.Instance.selectTeamType, true);
+
+        if (activeMixedConfig != null && participatingCountries != null && participatingCountries.Count > 0)
+        {
+            int totalPoints = activeMixedConfig.Countrys * activeMixedConfig.NeedHeroCount;
+            for (int i = 0; i < OnCountImgs.Length; i++)
+            {
+                if (i < totalPoints)
+                {
+                    int countryIndex = i / activeMixedConfig.NeedHeroCount;
+                    OnCountImgs[i].SetActive(true);
+                    OnCountImgs[i].SetSprite("heroTeamCountryPoint" + participatingCountries[countryIndex]);
+                }
+                else
+                {
+                    OnCountImgs[i].SetActive(false);
+                }
+            }
+        }
+        else
+        {
+            for (int i = 0; i < OnCountImgs.Length; i++)
+                OnCountImgs[i].SetActive(false);
+        }
+
+        // 鑾峰彇鎵�鏈夋贩鎼厤缃苟灞曞钩锛屾寜 Countrys 鎺掑簭
+        var allMixedConfigs = HeroLineupHaloConfig.GetAllMixedConfigs();
+        List<HeroLineupHaloConfig> sortedConfigs = new List<HeroLineupHaloConfig>();
+        if (allMixedConfigs != null)
+        {
+            foreach (var kvp in allMixedConfigs)
+            {
+                foreach (var innerKvp in kvp.Value)
+                {
+                    sortedConfigs.Add(innerKvp.Value);
+                }
+            }
+            sortedConfigs.Sort((a, b) =>
+            {
+                if (a.Countrys != b.Countrys) return a.Countrys.CompareTo(b.Countrys);
+                return a.NeedHeroCount.CompareTo(b.NeedHeroCount);
+            });
+        }
+
+        // 灞炴�ф枃鏈細閬嶅巻鎵�鏈夋贩鎼厤缃紝婵�娲荤殑楂樹寒锛屾湭婵�娲荤殑鐏拌壊
+        string text = string.Empty;
+        for (int k = 0; k < sortedConfigs.Count; k++)
+        {
+            var config = sortedConfigs[k];
+            bool isActive = activeMixedConfig != null && activeMixedConfig.Id == config.Id;
+            string lineText = (k == 0 ? "" : "</r>") + Language.Get("herocard74", config.Countrys, config.NeedHeroCount);
+
+            for (int i = 0; i < config.AttrIDList.Length; i++)
+            {
+                string format = !isActive ? "{0}+{1}" : "{0}+" + UIHelper.AppendColor(TextColType.Green, "{1}");
+                lineText += " " + PlayerPropertyConfig.GetFullDescription(config.AttrIDList[i], config.AttrValueList[i], format);
+            }
+
+            text += UIHelper.AppendColor(isActive ? TextColType.NavyBrown : TextColType.Gray, lineText);
+        }
+        attrText.text = text;
+    }
 }
 
diff --git a/Main/System/HeroUI/HeroFormationWin.cs b/Main/System/HeroUI/HeroFormationWin.cs
index 60acf92..3ff97dd 100644
--- a/Main/System/HeroUI/HeroFormationWin.cs
+++ b/Main/System/HeroUI/HeroFormationWin.cs
@@ -23,19 +23,29 @@
     {
         scroller.OnRefreshCell += OnRefreshCell;
         CreateScroller();
-        Int2 result;
+
+        // 浼樺厛妫�鏌ユ贩鎼樀鍨�
+        HeroLineupHaloConfig activeConfig = null;
         if (HeroUIManager.Instance.isCustonHeroFormation)
         {
-            result = HeroUIManager.Instance.GetMaxCountHeroCountry(HeroUIManager.Instance.custonTeamHeroes);;
+            activeConfig = HeroUIManager.Instance.GetMixedFormationConfig(HeroUIManager.Instance.custonTeamHeroes);
+            if (activeConfig == null)
+            {
+                var result = HeroUIManager.Instance.GetMaxCountHeroCountry(HeroUIManager.Instance.custonTeamHeroes);
+                activeConfig = HeroLineupHaloConfig.GetConfig(result.x, result.y);
+            }
         }
         else
         {
-            result = HeroUIManager.Instance.GetMaxCountHeroCountry(HeroUIManager.Instance.selectTeamType, true);
+            activeConfig = HeroUIManager.Instance.GetMixedFormationConfig(HeroUIManager.Instance.selectTeamType, true);
+            if (activeConfig == null)
+            {
+                var result = HeroUIManager.Instance.GetMaxCountHeroCountry(HeroUIManager.Instance.selectTeamType, true);
+                activeConfig = HeroLineupHaloConfig.GetConfig(result.x, result.y);
+            }
         }
-        
 
-        var config = HeroLineupHaloConfig.GetConfig(result.x, result.y);
-        if (config == null)
+        if (activeConfig == null)
         {
             totalAttrText.text = "";
         }
@@ -43,10 +53,10 @@
         {
             string lineText = string.Empty;
 
-            for (int i = 0; i < config.AttrIDList.Length; i++)
+            for (int i = 0; i < activeConfig.AttrIDList.Length; i++)
             {
                 string format = "{0}+" + UIHelper.AppendColor(TextColType.Green, "{1}");
-                lineText += " " + PlayerPropertyConfig.GetFullDescription(config.AttrIDList[i], config.AttrValueList[i], format);
+                lineText += " " + PlayerPropertyConfig.GetFullDescription(activeConfig.AttrIDList[i], activeConfig.AttrValueList[i], format);
             }
             totalAttrText.text = Language.Get("herocard36") + lineText.Trim();
         }
@@ -72,6 +82,8 @@
         {
             scroller.AddCell(ScrollerDataType.Header, i);
         }
+        // 绗�5涓负娣锋惌闃靛瀷鏍煎瓙锛堟樉绀哄湪鏈�鍚庯級
+        scroller.AddCell(ScrollerDataType.Header, 4);
         scroller.Restart();
     }
 
diff --git a/Main/System/HeroUI/HeroPosWin.cs b/Main/System/HeroUI/HeroPosWin.cs
index 7ed586b..0e95cc9 100644
--- a/Main/System/HeroUI/HeroPosWin.cs
+++ b/Main/System/HeroUI/HeroPosWin.cs
@@ -238,6 +238,31 @@
     //涓婇樀姝﹀皢鍥藉鍏夌幆婵�娲�
     void RefreshOnTeamCountry(bool playEffect = false)
     {
+        // 鍏堟鏌ユ贩鎼樀鍨�
+        var mixedConfig = HeroUIManager.Instance.GetMixedFormationConfig(HeroUIManager.Instance.selectTeamType, true);
+        if (mixedConfig != null)
+        {
+            countryOnImg.SetSprite("heroTeamCountryHe");
+            var participatingCountries = HeroUIManager.Instance.GetParticipatingCountriesByPriority(HeroUIManager.Instance.selectTeamType, true);
+            int totalPoints = mixedConfig.Countrys * mixedConfig.NeedHeroCount;
+            for (int i = 0; i < OnCountImgs.Count; i++)
+            {
+                if (i < totalPoints)
+                {
+                    int countryIndex = i / mixedConfig.NeedHeroCount;
+                    OnCountImgs[i].SetActive(true);
+                    OnCountImgs[i].SetSprite("heroTeamCountryPoint" + participatingCountries[countryIndex]);
+                }
+                else
+                {
+                    OnCountImgs[i].SetActive(false);
+                }
+            }
+            if (playEffect)
+                countryEffect.Play();
+            return;
+        }
+
         Int2 result = HeroUIManager.Instance.GetMaxCountHeroCountry(HeroUIManager.Instance.selectTeamType, true);
 
         var config = HeroLineupHaloConfig.GetConfig(result.x, result.y);
diff --git a/Main/System/HeroUI/HeroUIManager.OnTeam.cs b/Main/System/HeroUI/HeroUIManager.OnTeam.cs
index 397450c..3d0b0ea 100644
--- a/Main/System/HeroUI/HeroUIManager.OnTeam.cs
+++ b/Main/System/HeroUI/HeroUIManager.OnTeam.cs
@@ -87,6 +87,105 @@
     //     return lineUPPer;
     // }
 
+    #region 娣锋惌闃靛瀷
+
+    /// <summary>
+    /// 妫�娴嬫槸鍚︽弧瓒虫贩鎼樀鍨嬫潯浠讹紙鎸夐槦浼嶇被鍨嬶級
+    /// </summary>
+    public HeroLineupHaloConfig GetMixedFormationConfig(int teamType, bool isPreview = false)
+    {
+        var countryCountDict = GetCountryHeroCountByTeamType(teamType, isPreview);
+        return GetMixedFormationConfigByCountryDict(countryCountDict);
+    }
+
+    /// <summary>
+    /// 妫�娴嬫槸鍚︽弧瓒虫贩鎼樀鍨嬫潯浠讹紙鎸夎嚜瀹氫箟闃熶紞锛�
+    /// </summary>
+    public HeroLineupHaloConfig GetMixedFormationConfig(List<TeamHero> teamHeroes)
+    {
+        var countryCountDict = GetCountryHeroCountByTeamHeroList(teamHeroes);
+        return GetMixedFormationConfigByCountryDict(countryCountDict);
+    }
+
+    /// <summary>
+    /// 鏍规嵁鍥藉鍒嗗竷妫�娴嬫贩鎼樀鍨�
+    /// </summary>
+    HeroLineupHaloConfig GetMixedFormationConfigByCountryDict(Dictionary<HeroCountry, int> countryCountDict)
+    {
+        var mixedConfigs = HeroLineupHaloConfig.GetAllMixedConfigs();
+        if (mixedConfigs == null || mixedConfigs.Count == 0)
+            return null;
+
+        // 缁熻鏈夋灏嗕笂闃电殑涓嶅悓鍥藉鏁伴噺 鍜� 鏈�灏忓浗瀹舵灏嗘暟
+        int distinctCountryCount = 0;
+        int minHeroCount = int.MaxValue;
+        foreach (var data in countryCountDict)
+        {
+            if (data.Value > 0)
+            {
+                distinctCountryCount++;
+                if (data.Value < minHeroCount)
+                    minHeroCount = data.Value;
+            }
+        }
+
+        if (distinctCountryCount == 0)
+            return null;
+
+        // 閬嶅巻娣锋惌閰嶇疆锛屾鏌ユ槸鍚﹀尮閰�
+        foreach (var kvp in mixedConfigs)
+        {
+            int countrys = kvp.Key;
+            if (countrys != distinctCountryCount)
+                continue;
+
+            foreach (var innerKvp in kvp.Value)
+            {
+                int needHeroCount = innerKvp.Key;
+                if (minHeroCount >= needHeroCount)
+                    return innerKvp.Value;
+            }
+        }
+
+        return null;
+    }
+
+    /// <summary>
+    /// 鑾峰彇涓婇樀姝﹀皢涓墍鏈夊弬涓庣殑鍥藉锛屾寜浼樺厛绾ф帓搴忥紙鎸夐槦浼嶇被鍨嬶級
+    /// 浼樺厛绾э細榄�(1) > 铚�(2) > 鍚�(3) > 缇�(4)
+    /// </summary>
+    public List<int> GetParticipatingCountriesByPriority(int teamType, bool isPreview = false)
+    {
+        var countryCountDict = GetCountryHeroCountByTeamType(teamType, isPreview);
+        return GetParticipatingCountriesByPriorityByDict(countryCountDict);
+    }
+
+    /// <summary>
+    /// 鑾峰彇涓婇樀姝﹀皢涓墍鏈夊弬涓庣殑鍥藉锛屾寜浼樺厛绾ф帓搴忥紙鎸夎嚜瀹氫箟闃熶紞锛�
+    /// </summary>
+    public List<int> GetParticipatingCountriesByPriority(List<TeamHero> teamHeroes)
+    {
+        var countryCountDict = GetCountryHeroCountByTeamHeroList(teamHeroes);
+        return GetParticipatingCountriesByPriorityByDict(countryCountDict);
+    }
+
+    /// <summary>
+    /// 鏍规嵁鍥藉鍒嗗竷鑾峰彇鎵�鏈夊弬涓庡浗瀹讹紙鎸変紭鍏堢骇鎺掑簭锛�
+    /// </summary>
+    List<int> GetParticipatingCountriesByPriorityByDict(Dictionary<HeroCountry, int> countryCountDict)
+    {
+        List<int> result = new List<int>();
+        // 浼樺厛绾э細榄�(1) > 铚�(2) > 鍚�(3) > 缇�(4)
+        for (int i = 1; i <= 4; i++)
+        {
+            if (countryCountDict.ContainsKey((HeroCountry)i) && countryCountDict[(HeroCountry)i] > 0)
+                result.Add(i);
+        }
+        return result;
+    }
+
+    #endregion
+
     /// <summary>
     /// 鎸夐槦浼嶈幏寰楅樀鍨嬶紙鍥藉鍏夌幆锛夊睘鎬�
     /// </summary>
@@ -95,6 +194,19 @@
     public Dictionary<int, int> GetCountryAttrs(int teamType, bool isPreview = false)
     {
         Dictionary<int, int> countryAttrs = new Dictionary<int, int>();
+
+        // 1. 鍏堟鏌ユ贩鎼樀鍨�
+        var mixedConfig = GetMixedFormationConfig(teamType, isPreview);
+        if (mixedConfig != null)
+        {
+            for (int i = 0; i < mixedConfig.AttrIDList.Length; i++)
+            {
+                countryAttrs[mixedConfig.AttrIDList[i]] = mixedConfig.AttrValueList[i];
+            }
+            return countryAttrs;
+        }
+
+        // 2. 娌℃湁娣锋惌鍒欒蛋鍗曞浗瀹堕�昏緫
         Int2 result = GetMaxCountHeroCountry(teamType, isPreview);
         var lineupconfig = HeroLineupHaloConfig.GetConfig(result.x, result.y);
         if (lineupconfig != null)

--
Gitblit v1.8.0