121 【武将】武将系统 - 生效武将版本,同步属性计算,更改新筛选模式
25个文件已修改
2个文件已添加
1300 ■■■■■ 已修改文件
Main/Component/UI/Common/GroupButtonEx.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Common/GroupButtonExManager.cs 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/Configs/HeroQualityConfig.cs 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HappyXB/HeroCallScoreRuleWin.cs 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/HeroInfo.Properties.cs 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/HeroInfo.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/HeroManager.cs 92 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroCardLineCell.cs 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroCardLineTipCell.cs 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroCardLineTipCell.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroCollectionCardCell.cs 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroCollectionLvUpWin.cs 142 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroCollectionWin.cs 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroDeleteWin.cs 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroGiftEatSuccessWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroListWin.cs 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroPosWin.cs 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroSelectBehaviour.cs 211 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroTrainWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroUIManager.Collect.cs 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroUIManager.OnTeam.cs 67 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroUIManager.Reborn.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroUIManager.cs 107 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/FightPowerFormula.cs 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/FightPowerManager.cs 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/HeroFightingCardCell.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/UIHelper.cs 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Common/GroupButtonEx.cs
@@ -71,6 +71,15 @@
        set { this.m_Title = value; }
    }
    [SerializeField] TextEx m_TitleOutline;
    public TextEx titleOutline
    {
        get { return this.m_TitleOutline; }
        set { this.m_TitleOutline = value; }
    }
    [SerializeField] UIEffectPlayer m_SelectEffect;  //选中特效
    public UIEffectPlayer selectEffect
    {
@@ -146,6 +155,11 @@
            m_Title.color = m_Manager.GetTextColorForState(m_State);
        }
        if (m_TitleOutline != null && m_Manager != null)
        {
            m_TitleOutline.color = m_Manager.GetOutlineColorForState(m_State);
        }
        if (m_SelectEffect != null)
        {
            if (m_State == TitleBtnState.Click)
@@ -159,4 +173,4 @@
            }
        }
    }
}
}
Main/Component/UI/Common/GroupButtonExManager.cs
@@ -27,12 +27,37 @@
    }
    
    [SerializeField] Color m_NormalTextColor = UIHelper.GetUIColor(TextColType.titleUnSelectColor); // 未选中状态文字颜色
    public Color normalTextColor {
    public Color normalTextColor
    {
        get { return m_NormalTextColor; }
        set {
        set
        {
            m_NormalTextColor = value;
        }
    }
    //增加包边颜色
    [SerializeField] Color m_SelectOutlineColor = UIHelper.GetUIColor(TextColType.titleUnSelectColor);
    public Color selectedOutlineColor
    {
        get { return m_SelectOutlineColor; }
        set
        {
            m_SelectOutlineColor = value;
        }
    }
    [SerializeField] Color m_NormalOutlineColor = UIHelper.GetUIColor(TextColType.titleUnSelectColor);
    public Color normalOutlineColor
    {
        get { return m_NormalOutlineColor; }
        set
        {
            m_NormalOutlineColor = value;
        }
    }
    void OnEnable()
@@ -153,7 +178,7 @@
        m_Buttons.Sort((a, b) => { return a.transform.GetSiblingIndex() - b.transform.GetSiblingIndex(); });
        sortyet = true;
    }
    /// <summary>
    /// 获取按钮状态对应的文本颜色
    /// </summary>
@@ -163,4 +188,10 @@
    {
        return state == TitleBtnState.Click ? m_SelectedTextColor : m_NormalTextColor;
    }
    public Color GetOutlineColorForState(TitleBtnState state)
    {
        return state == TitleBtnState.Click ? m_SelectOutlineColor : m_NormalOutlineColor;
    }
}
Main/Config/Configs/HeroQualityConfig.cs
@@ -1,6 +1,6 @@
//--------------------------------------------------------
//    [Author]:           YYL
//    [  Date ]:           Thursday, August 28, 2025
//    [  Date ]:           2025年12月5日
//--------------------------------------------------------
using System.Collections.Generic;
@@ -23,9 +23,6 @@
    public int BreakLVAddPer;
    public int StarAddPer;
    public int[] BookActAwardMoney;
    public int BookInitAddPer;
    public int BookStarAddPer;
    public int BookBreakLVAddPer;
    public int[][] DismissReturnItems;
    public override int LoadKey(string _key)
@@ -64,13 +61,7 @@
                }
            }
            int.TryParse(tables[7],out BookInitAddPer);
            int.TryParse(tables[8],out BookStarAddPer);
            int.TryParse(tables[9],out BookBreakLVAddPer);
            DismissReturnItems = JsonMapper.ToObject<int[][]>(tables[10].Replace("(", "[").Replace(")", "]"));
            DismissReturnItems = JsonMapper.ToObject<int[][]>(tables[7].Replace("(", "[").Replace(")", "]"));
        }
        catch (Exception exception)
        {
Main/System/HappyXB/HeroCallScoreRuleWin.cs
@@ -10,13 +10,17 @@
{
    [SerializeField] ScrollerController scrollerController;
    [SerializeField] HeroSelectBehaviour heroSelectBehaviour;
    [SerializeField] Transform heroSelectBehaviour;
    HeroSelectBehaviour fiterManager;  //武将筛选
    protected override void InitComponent()
    {
        fiterManager = HeroSelectBehaviour.Create(heroSelectBehaviour);
    }
    protected override void OnPreOpen()
    {
        HeroUIManager.Instance.selectHeroCallListJob = 0;
        HeroUIManager.Instance.selectHeroCallListCountry = 0;
        HeroUIManager.Instance.SortHeroCallList();
        scrollerController.OnRefreshCell += OnRefreshCell;
@@ -31,13 +35,14 @@
    public override void Refresh()
    {
        heroSelectBehaviour.Display(0, HeroUIManager.Instance.selectHeroListJob, HeroUIManager.Instance.selectHeroListCountry, SelectJobCountry);
        fiterManager.Display(0, SelectJobCountry);
    }
    void SelectJobCountry(int job, int country)
    /// 回调参数: 职业,国家,伤害类型,6大战斗属性,特殊属性
    void SelectJobCountry(List<int> selects)
    {
        HeroUIManager.Instance.selectHeroCallListJob = job;
        HeroUIManager.Instance.selectHeroCallListCountry = country;
        HeroUIManager.Instance.selectHeroCallList = selects;
        HeroUIManager.Instance.SortHeroCallList();
        scrollerController.m_Scorller.RefreshActiveCellViews();
    }
Main/System/Hero/HeroInfo.Properties.cs
@@ -117,8 +117,8 @@
    }
    //上阵属性:攻防血
    public int GetOnBattleAddPer()
    //攻防血加成
    public int GetAddPer()
    {
        return qualityConfig.InitAddPer + qualityConfig.LVAddPer * (heroLevel - 1) + qualityConfig.BreakLVAddPer * breakLevel + qualityConfig.StarAddPer * heroStar;
    }
@@ -129,20 +129,20 @@
        return qualityConfig.InitAddPer + qualityConfig.LVAddPer * (1 - 1) + qualityConfig.BreakLVAddPer * breakLevel + qualityConfig.StarAddPer * heroStar;
    }
    public int GetLineupLVAddPer()
    {
        return qualityConfig.LVAddPer * (heroLevel - 1);
    }
    // public int GetLineupLVAddPer()
    // {
    //     return qualityConfig.LVAddPer * (heroLevel - 1);
    // }
    public int GetLineupBreakLVAddPer()
    {
        return qualityConfig.BreakLVAddPer * breakLevel;
    }
    // public int GetLineupBreakLVAddPer()
    // {
    //     return qualityConfig.BreakLVAddPer * breakLevel;
    // }
    public int GetLineupStarAddPer()
    {
        return qualityConfig.StarAddPer * heroStar;
    }
    // public int GetLineupStarAddPer()
    // {
    //     return qualityConfig.StarAddPer * heroStar;
    // }
    //额外配置的百分百比加成 三围对应的 百分比加成
    public int GetSelfAddPer(int attrType)
Main/System/Hero/HeroInfo.cs
@@ -43,6 +43,15 @@
        }
    }
    //生效的武将 (多武将只生效一个)
    public bool isAttrActive
    {
        get
        {
            return itemHero.GetUseDataFirstValue(80) == 1;
        }
    }
    public bool isLock
    {
Main/System/Hero/HeroManager.cs
@@ -83,29 +83,57 @@
        return heroInfoDict.Values.ToList();
    }
    public List<string> GetHeroGuidList(int job = 0, int country = 0)
    /// 参数: 职业,国家,伤害类型,6大战斗属性,特殊属性
    public List<string> GetHeroGuidList(List<int> selectList = null)
    {
        if (job == 0 && country == 0)
        if (selectList.IsNullOrEmpty())
            return heroInfoDict.Keys.ToList();
        int job = selectList[0];
        int country = selectList[1];
        int hurtType = selectList[2];
        int fightAttrType = selectList[3];
        int specialAttrType = selectList[4];
        List<string> retGuidList = new List<string>();
        foreach (string guid in heroInfoDict.Keys)
        {
            HeroInfo heroInfo = heroInfoDict[guid];
            //0代表全部
            if (job == 0 || country == 0)
            //0代表全部, 同级别是可复选,不同级别为且的关系
            bool isMatch = true;
            if (job != 0)
            {
                if (job != 0 && job == heroInfo.heroConfig.Class)
                    retGuidList.Add(guid);
                if (country != 0 && country == heroInfo.heroConfig.Country)
                    retGuidList.Add(guid);
                isMatch = isMatch && (job & (1 << heroInfo.heroConfig.Class)) > 0;
            }
            else
            if (country != 0)
            {
                if (job == heroInfo.heroConfig.Class && country == heroInfo.heroConfig.Country)
                    retGuidList.Add(guid);
                isMatch = isMatch && (country & (1 << heroInfo.heroConfig.Country)) > 0;
            }
            if (hurtType != 0)
            {
                isMatch = isMatch && (hurtType & (1 << heroInfo.heroConfig.HurtType)) > 0;
            }
            if (fightAttrType != 0)
            {
                isMatch = isMatch && (fightAttrType & (1 << heroInfo.heroConfig.Specialty)) > 0;
            }
            if (specialAttrType != 0)
            {
                bool isMatch2 = false;
                for (int i = 0; i < heroInfo.heroConfig.Specialty2.Length; i++)
                {
                    isMatch2 = (specialAttrType & (1 << heroInfo.heroConfig.Specialty2[i])) > 0;
                    if (isMatch2)
                        break;
                }
                isMatch = isMatch && isMatch2;
            }
            if (isMatch)
            {
                retGuidList.Add(guid);
            }
        }
        return retGuidList;
    }
@@ -152,4 +180,46 @@
    {
        return (int)PackManager.Instance.GetSinglePack(PackType.Hero).GetCountById(heroID);
    }
    //获得生效的武将数量
    public int GetAttrActiveHeroCount()
    {
        int count = 0;
        foreach (HeroInfo heroInfo in heroInfoDict.Values)
        {
            if (heroInfo.isAttrActive)
            {
                count++;
            }
        }
        return count;
    }
    //获得未生效的武将数量
    public int GetNotActiveHeroCount()
    {
        int count = 0;
        foreach (HeroInfo heroInfo in heroInfoDict.Values)
        {
            if (!heroInfo.isAttrActive)
            {
                count++;
            }
        }
        return count;
    }
    //获得指定ID且属性生效的武将
    public HeroInfo GetHeroByID(int heroID)
    {
        foreach (HeroInfo heroInfo in heroInfoDict.Values)
        {
            if (heroInfo.heroId == heroID && heroInfo.isAttrActive)
            {
                return heroInfo;
            }
        }
        return null;
    }
}
Main/System/HeroUI/HeroCardLineCell.cs
@@ -4,18 +4,41 @@
{
    [SerializeField] HeroCardCell[] cardList;
    public void Display(int index)
    {
        for (int i = 0; i < cardList.Length; i++)
    //生效和未生效共用 heroSortList,activeCount 生效数量, index大于10000 未生效
    public void Display(int index, int activeCount)
    {
        if (index < 10000)
        {
            if (i + index < HeroUIManager.Instance.heroSortList.Count)
            //生效
            for (int i = 0; i < cardList.Length; i++)
            {
                cardList[i].SetActive(true);
                cardList[i].Display(index + i);
                if (i + index < activeCount)
                {
                    cardList[i].SetActive(true);
                    cardList[i].Display(index + i);
                }
                else
                {
                    cardList[i].SetActive(false);
                }
            }
            else
        }
        else
        {
            //未生效
            index = index - 10000;
            for (int i = 0; i < cardList.Length; i++)
            {
                cardList[i].SetActive(false);
                if (i + index < HeroUIManager.Instance.heroSortList.Count)
                {
                    cardList[i].SetActive(true);
                    cardList[i].Display(index + i);
                }
                else
                {
                    cardList[i].SetActive(false);
                }
            }
        }
    }
Main/System/HeroUI/HeroCardLineTipCell.cs
New file
@@ -0,0 +1,28 @@
using UnityEngine;
using UnityEngine.UI;
public class HeroCardLineTipCell : CellView
{
    [SerializeField] Text tipText;
    [SerializeField] Image tipBG;
    //0 生效 1 未生效
    public void Display(int type)
    {
        if (type == 0)
        {
            tipText.text = Language.Get("herocard71", HeroManager.Instance.GetAttrActiveHeroCount());
            //7E4038
            tipText.color = new Color32(126, 64, 56, 255);
            tipBG.SetOrgSprite("herolineactive", "Hero");
        }
        else
        {
            tipText.text = Language.Get("herocard72", HeroManager.Instance.GetNotActiveHeroCount());
            //6E5C60
            tipText.color = new Color32(110, 92, 96, 255);
            tipBG.SetOrgSprite("herolinenoactive", "Hero");
        }
    }
}
Main/System/HeroUI/HeroCardLineTipCell.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 46a29d9aa6a41654ea999ddbb4131b97
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/HeroUI/HeroCollectionCardCell.cs
@@ -13,7 +13,7 @@
    [SerializeField] Text nameText;
    [SerializeField] Image trainStateImg;
    [SerializeField] RedpointBehaviour redpoint;
    [SerializeField] Button bookLVBtn;
    // [SerializeField] Button bookLVBtn;
    [SerializeField] GameObject unGetObj;
    [SerializeField] GameObject activeObj; // 可激活带流光效果材质
@@ -32,7 +32,7 @@
        int funcState = HeroUIManager.Instance.GetHeroBookState(heroID, quality);
        activeObj.SetActive(funcState == 1);
        bookLVBtn.SetActive(funcState > 1);
        // bookLVBtn.SetActive(funcState > 1);
        unGetObj.SetActive(funcState == 0);
        countryImg.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country));
@@ -86,11 +86,11 @@
            }
        });
        
        bookLVBtn.AddListener(() =>
        {
            HeroUIManager.Instance.selectCollectHeroID = heroID;
            UIManager.Instance.OpenWindow<HeroCollectionLvUpWin>();
        });
        // bookLVBtn.AddListener(() =>
        // {
        //     HeroUIManager.Instance.selectCollectHeroID = heroID;
        //     UIManager.Instance.OpenWindow<HeroCollectionLvUpWin>();
        // });
    }
}
Main/System/HeroUI/HeroCollectionLvUpWin.cs
@@ -18,9 +18,9 @@
    [SerializeField] HeroHeadBaseCell afterHeadCell;
    [SerializeField] Text name2;
    [SerializeField] Text[] attrNames;
    [SerializeField] Text[] beforeAttrValues;
    [SerializeField] Text[] afterAttrValues;
    // [SerializeField] Text[] attrNames;
    // [SerializeField] Text[] beforeAttrValues;
    // [SerializeField] Text[] afterAttrValues;
    [SerializeField] RichText awardInfo;
    [SerializeField] Button btn;
@@ -59,39 +59,39 @@
        HB122_tagSCHeroInfo.tagSCHero colData;
        HeroUIManager.Instance.TryGetHeroBookInfo(HeroUIManager.Instance.selectCollectHeroID, out colData);
        var bookPer = HeroUIManager.Instance.GetHeroBookPer(HeroUIManager.Instance.selectCollectHeroID);
        if (state == 5 || state == 2)
        {
            //已满级
            titleText.text = state == 5 ? Language.Get("HeroAwake13") : Language.Get("HeroAwake12");
            fullPanel.SetActive(true);
            lvupPanel.SetActive(false);
        // var bookPer = HeroUIManager.Instance.GetHeroBookPer(HeroUIManager.Instance.selectCollectHeroID);
        // if (state == 5 || state == 2)
        // {
        //     //已满级
        //     titleText.text = state == 5 ? Language.Get("HeroAwake13") : Language.Get("HeroAwake12");
        //     fullPanel.SetActive(true);
        //     lvupPanel.SetActive(false);
            fullHeadCell.Init(HeroUIManager.Instance.selectCollectHeroID, config.SkinIDList[0], colData.BookStarLV);
            name3.text = colData.BookBreakLV == 0 ? config.Name : Language.Get("herocardbreaklv", config.Name, colData.BookBreakLV);
        //     fullHeadCell.Init(HeroUIManager.Instance.selectCollectHeroID, config.SkinIDList[0], colData.BookStarLV);
        //     name3.text = colData.BookBreakLV == 0 ? config.Name : Language.Get("herocardbreaklv", config.Name, colData.BookBreakLV);
            for (int i = 0; i < fullAttrs.Length; i++)
            {
                fullAttrs[i].text = PlayerPropertyConfig.GetFullDescription(PlayerPropertyConfig.basePerAttrs[i],
                    bookPer, "{0}    " + UIHelper.AppendColor(TextColType.Green, "+{1}"));
            }
            var nextHeroID = HeroUIManager.Instance.FindHeroIDCanAddCollectAttr(HeroUIManager.Instance.selectCollectHeroID);
            if (nextHeroID != 0)
            {
                fullImg.SetActive(false);
                btn.SetActive(true);
                //下一个
                btnText.text = Language.Get("HeroAwake14");
            }
            else
            {
                fullImg.SetActive(state == 5);
                btn.SetActive(state == 2);
                btnText.text = Language.Get("L1109");
            }
        //     for (int i = 0; i < fullAttrs.Length; i++)
        //     {
        //         fullAttrs[i].text = PlayerPropertyConfig.GetFullDescription(PlayerPropertyConfig.basePerAttrs[i],
        //             bookPer, "{0}    " + UIHelper.AppendColor(TextColType.Green, "+{1}"));
        //     }
        //     var nextHeroID = HeroUIManager.Instance.FindHeroIDCanAddCollectAttr(HeroUIManager.Instance.selectCollectHeroID);
        //     if (nextHeroID != 0)
        //     {
        //         fullImg.SetActive(false);
        //         btn.SetActive(true);
        //         //下一个
        //         btnText.text = Language.Get("HeroAwake14");
        //     }
        //     else
        //     {
        //         fullImg.SetActive(state == 5);
        //         btn.SetActive(state == 2);
        //         btnText.text = Language.Get("L1109");
        //     }
        }
        else
        // }
        // else
        {
            fullPanel.SetActive(false);
            lvupPanel.SetActive(true);
@@ -100,7 +100,7 @@
            beforeHeadCell.Init(HeroUIManager.Instance.selectCollectHeroID, config.SkinIDList[0], colData.BookStarLV);
            name1.text = colData.BookBreakLV == 0 ? config.Name : Language.Get("herocardbreaklv", config.Name, colData.BookBreakLV);
            int addPer = 0;
            // int addPer = 0;
            var qualityConfig = HeroQualityConfig.Get(config.Quality);
            awardInfo.text = string.Empty;
            unActiveGo.SetActive(false);
@@ -110,27 +110,27 @@
            if (state == 1)
            {
                //激活
                addPer = qualityConfig.BookInitAddPer;
                // addPer = qualityConfig.BookInitAddPer;
                btnText.text = Language.Get("L1131");   //L1131    激活
                awardInfo.text = Language.Get("HeroAwake10", UIHelper.GetIconNameWithMoneyType(qualityConfig.BookActAwardMoney[0]),
                    qualityConfig.BookActAwardMoney[1]);
                unActiveGo.SetActive(true);
                titleText.text = Language.Get("HeroAwake11");
            }
            else if (state == 3)
            {
                //突破
                addPer = qualityConfig.BookBreakLVAddPer;
                btnText.text = Language.Get("L1109");   //升级
                afterBreakLV++;
            }
            else if (state == 4)
            {
                //升星
                addPer = qualityConfig.BookStarAddPer;
                btnText.text = Language.Get("L1109");
                afterStarLV++;
            }
            // else if (state == 3)
            // {
            //     //突破
            //     addPer = qualityConfig.BookBreakLVAddPer;
            //     btnText.text = Language.Get("L1109");   //升级
            //     afterBreakLV++;
            // }
            // else if (state == 4)
            // {
            //     //升星
            //     addPer = qualityConfig.BookStarAddPer;
            //     btnText.text = Language.Get("L1109");
            //     afterStarLV++;
            // }
            else
            {
                var nextHeroID = HeroUIManager.Instance.FindHeroIDCanAddCollectAttr(HeroUIManager.Instance.selectCollectHeroID);
@@ -141,20 +141,27 @@
                }
                else
                {
                    btnText.text = Language.Get("L1109");
                    btnText.text = Language.Get("L1001");
                }
                fullPanel.SetActive(true);
                lvupPanel.SetActive(false);
                fullHeadCell.Init(HeroUIManager.Instance.selectCollectHeroID, config.SkinIDList[0], colData.BookStarLV);
                name3.text = colData.BookBreakLV == 0 ? config.Name : Language.Get("herocardbreaklv", config.Name, colData.BookBreakLV);
            }
            afterHeadCell.Init(HeroUIManager.Instance.selectCollectHeroID, config.SkinIDList[0], afterStarLV);
            name2.text = afterBreakLV == 0 ? config.Name :Language.Get("herocardbreaklv", config.Name, afterBreakLV);
            for (int i = 0; i < beforeAttrValues.Length; i++)
            {
                beforeAttrValues[i].text = PlayerPropertyConfig.GetValueDescription(PlayerPropertyConfig.basePerAttrs[i], bookPer);
                attrNames[i].text = PlayerPropertyConfig.Get(PlayerPropertyConfig.basePerAttrs[i]).Name;
                afterAttrValues[i].text = PlayerPropertyConfig.GetValueDescription(PlayerPropertyConfig.basePerAttrs[i], bookPer + addPer);
            }
            // for (int i = 0; i < beforeAttrValues.Length; i++)
            // {
            //     beforeAttrValues[i].text = PlayerPropertyConfig.GetValueDescription(PlayerPropertyConfig.basePerAttrs[i], bookPer);
            //     attrNames[i].text = PlayerPropertyConfig.Get(PlayerPropertyConfig.basePerAttrs[i]).Name;
            //     afterAttrValues[i].text = PlayerPropertyConfig.GetValueDescription(PlayerPropertyConfig.basePerAttrs[i], bookPer + addPer);
            // }
        }
    }
@@ -167,16 +174,16 @@
            //激活
            SendPack(0);
        }
        else if (state == 3)
        {
            //突破
            SendPack(2);
        }
        else if (state == 4)
        {
            //升星
            SendPack(1);
        }
        // else if (state == 3)
        // {
        //     //突破
        //     SendPack(2);
        // }
        // else if (state == 4)
        // {
        //     //升星
        //     SendPack(1);
        // }
        else
        {
            var nextHeroID = HeroUIManager.Instance.FindHeroIDCanAddCollectAttr(HeroUIManager.Instance.selectCollectHeroID);
@@ -188,7 +195,8 @@
            }
            else
            {
                SysNotifyMgr.Instance.ShowTip("HeroGift8");
                // SysNotifyMgr.Instance.ShowTip("HeroGift8");
                CloseWindow();
            }
        }
    }
Main/System/HeroUI/HeroCollectionWin.cs
@@ -13,9 +13,10 @@
    [SerializeField] Button heroPackBtn;
    [SerializeField] Text heroPackText;
    [SerializeField] ScrollerController heroListScroller;
    [SerializeField] List<Text> totalAttrList;
    // [SerializeField] List<Text> totalAttrList;
    [SerializeField] Button attrBtn;
    [SerializeField] HeroSelectBehaviour fiterManager;  //武将筛选
    [SerializeField] Transform heroSelectBehaviour;
    HeroSelectBehaviour fiterManager;  //武将筛选
    SinglePack singlePack;
@@ -32,6 +33,8 @@
        {
            HeroUIManager.Instance.QueryUnLockHeroPack();
        });
        fiterManager = HeroSelectBehaviour.Create(heroSelectBehaviour);
    }
    protected override void OnPreOpen()
@@ -41,8 +44,6 @@
        PackManager.Instance.RefreshItemEvent += RefreshItemEvent;
        HeroUIManager.Instance.OnHeroCollectEvent += OnHeroCollectEvent;
        heroListScroller.OnRefreshCell += OnRefreshCell;
        HeroUIManager.Instance.selectHeroCollectListJob = 0;
        HeroUIManager.Instance.selectHeroCollectListCountry = 0;
        HeroUIManager.Instance.SortHeroCollectList();
        Display();
    }
@@ -59,10 +60,10 @@
    void Display()
    {
        fiterManager.Display(0, HeroUIManager.Instance.selectHeroCollectListJob, HeroUIManager.Instance.selectHeroCollectListCountry, SelectJobCountry);
        fiterManager.Display(0, SelectJobCountry);
        
        CreateScroller();
        RefreshTotalAttr();
        // CreateScroller();
        // RefreshTotalAttr();
        RefreshPackCount();
    }
@@ -94,20 +95,20 @@
    }
    void RefreshTotalAttr()
    {
        for (int i = 0; i < totalAttrList.Count; i++)
        {
            totalAttrList[i].text = PlayerPropertyConfig.GetFullDescription(PlayerPropertyConfig.basePerAttrs[i],
            HeroUIManager.Instance.allHeroBookPer);
        }
    }
    // void RefreshTotalAttr()
    // {
    //     for (int i = 0; i < totalAttrList.Count; i++)
    //     {
    //         totalAttrList[i].text = PlayerPropertyConfig.GetFullDescription(PlayerPropertyConfig.basePerAttrs[i],
    //         HeroUIManager.Instance.allHeroBookPer);
    //     }
    // }
    void SelectJobCountry(int job, int country)
    /// 回调参数: 职业,国家,伤害类型,6大战斗属性,特殊属性
    void SelectJobCountry(List<int> selects)
    {
        HeroUIManager.Instance.selectHeroCollectListJob = job;
        HeroUIManager.Instance.selectHeroCollectListCountry = country;
        HeroUIManager.Instance.selectHeroCollectList = selects;
        HeroUIManager.Instance.SortHeroCollectList();
        CreateScroller();
    }
@@ -173,7 +174,7 @@
    void OnHeroCollectEvent()
    {
        RefreshTotalAttr();
        // RefreshTotalAttr();
        heroListScroller.m_Scorller.RefreshActiveCellViews();
    }
Main/System/HeroUI/HeroDeleteWin.cs
@@ -12,7 +12,8 @@
{
    [SerializeField] Button storeBtn;
    [SerializeField] ScrollerController scroller;
    [SerializeField] HeroSelectBehaviour heroSelectBehaviour;
    [SerializeField] Transform heroSelectBehaviour;
    HeroSelectBehaviour fiterManager;  //武将筛选
    [SerializeField] GameObject noHeroObj;
    [SerializeField] Button quickSelectBtn;
    [SerializeField] Button deleteBtn;
@@ -26,6 +27,7 @@
        });
        quickSelectBtn.AddListener(QuickSelect);
        deleteBtn.AddListener(DeleteHero);
        fiterManager = HeroSelectBehaviour.Create(heroSelectBehaviour);
    }
    protected override void OnPreOpen()
@@ -35,17 +37,15 @@
        PackManager.Instance.RefreshItemLockEvent += RefreshItemLockEvent;
        ItemLogicUtility.Instance.OnGetItemShowEvent += OnGetItemShowEvent;
        HeroUIManager.Instance.selectHeroDeleteListJob = 0;
        HeroUIManager.Instance.selectHeroDeleteListCountry = 0;
        HeroUIManager.Instance.SortHeroDeleteList();
        heroSelectBehaviour.Display(0, HeroUIManager.Instance.selectHeroDeleteListJob, HeroUIManager.Instance.selectHeroDeleteListCountry, SelectJobCountry);
        fiterManager.Display(0, SelectJobCountry);
        RefreshEmptyTip();
        //外部选中
        HeroUIManager.Instance.SelectDeleteHero(HeroManager.Instance.GetHero(HeroUIManager.Instance.jumpDeleteHeroGuid));
        CreateScroller();
        // CreateScroller();
    }
    protected override void OnPreClose()
@@ -78,10 +78,10 @@
        _cell.Display(cell.index);
    }
    void SelectJobCountry(int job, int country)
    /// 回调参数: 职业,国家,伤害类型,6大战斗属性,特殊属性
    void SelectJobCountry(List<int> selects)
    {
        HeroUIManager.Instance.selectHeroDeleteListJob = job;
        HeroUIManager.Instance.selectHeroDeleteListCountry = country;
        HeroUIManager.Instance.selectHeroDeleteList = selects;
        HeroUIManager.Instance.SortHeroDeleteList();
        CreateScroller();
        RefreshEmptyTip();
Main/System/HeroUI/HeroGiftEatSuccessWin.cs
@@ -53,7 +53,7 @@
        //上阵属性
        int valuePer = hero.GetOnBattleAddPer();
        int valuePer = hero.GetAddPer();
        for (int i = 0; i < attrPerTextArr.Length; i++)
        {
            int id = PlayerPropertyConfig.basePerAttrs[i];
Main/System/HeroUI/HeroListWin.cs
@@ -12,12 +12,13 @@
    [SerializeField] Text heroPackText;
    [SerializeField] ScrollerController heroListScroller;
    [SerializeField] GameObject heroListEmpty;
    [SerializeField] List<Text> attrOnList; //上阵属性加成
    [SerializeField] List<Text> attrOnList; //全体属性加成
    [SerializeField] GameObject attrOnTip;
    [SerializeField] Button attrOnTipBtn;
    [SerializeField] Button changeHeroPosBtn; //布阵按钮
    [SerializeField] HeroSelectBehaviour fiterManager;  //武将筛选
    [SerializeField] Transform heroSelectBehaviour;
    HeroSelectBehaviour fiterManager;  //武将筛选
    SinglePack singlePack;
@@ -37,23 +38,24 @@
        {
            attrOnTip.SetActive(!attrOnTip.activeSelf);
        });
        fiterManager = HeroSelectBehaviour.Create(heroSelectBehaviour);
    }
    protected override void OnPreOpen()
    {
        HeroUIManager.Instance.selectHeroListJob = 0;
        HeroUIManager.Instance.selectHeroListCountry = 0;
        singlePack = PackManager.Instance.GetSinglePack(PackType.Hero);
        heroListScroller.OnRefreshCell += OnRefreshCell;
        PackManager.Instance.gridRefreshEvent += GridRefreshEvent;
        PackManager.Instance.RefreshItemEvent += RefreshItemEvent;
        UIManager.Instance.OnCloseWindow += OnCloseWindow;
        HeroManager.Instance.onHeroDeleteEvent += HeroDeleteEvent;
        // HeroManager.Instance.onHeroDeleteEvent += HeroDeleteEvent;
        HeroUIManager.Instance.SortHeroList();
        UIManager.Instance.OnOpenWindow += OnOpenWindow;
        CreateScroller();
        // CreateScroller();
        Refresh();
        fiterManager.Display(0, SelectJobCountry);
    }
    protected override void OnPreClose()
@@ -62,7 +64,7 @@
        PackManager.Instance.RefreshItemEvent -= RefreshItemEvent;
        PackManager.Instance.gridRefreshEvent -= GridRefreshEvent;
        UIManager.Instance.OnCloseWindow -= OnCloseWindow;
        HeroManager.Instance.onHeroDeleteEvent -= HeroDeleteEvent;
        // HeroManager.Instance.onHeroDeleteEvent -= HeroDeleteEvent;
        UIManager.Instance.OnOpenWindow -= OnOpenWindow;
    }
@@ -72,6 +74,7 @@
        //其他武将功能产生数据变化,需要刷新武将列表
        if (closeUI is HeroTrainWin ||
            closeUI is HeroCallWin ||
            closeUI is HeroDeleteWin ||
            closeUI is HeroPosWin)
        {
            HeroUIManager.Instance.SortHeroList();
@@ -117,15 +120,15 @@
        RefreshPackCount();
        fiterManager.Display(0, HeroUIManager.Instance.selectHeroListJob, HeroUIManager.Instance.selectHeroListCountry, SelectJobCountry);
    }
    void HeroDeleteEvent(int heroID)
    {
        HeroUIManager.Instance.SortHeroList();
        heroListScroller.m_Scorller.RefreshActiveCellViews();
    }
    // void HeroDeleteEvent(int heroID)
    // {
    //     HeroUIManager.Instance.SortHeroList();
    //     heroListScroller.m_Scorller.RefreshActiveCellViews();
    // }
@@ -144,10 +147,10 @@
        }
    }
    void SelectJobCountry(int job, int country)
    /// 回调参数: 职业,国家,伤害类型,6大战斗属性,特殊属性
    void SelectJobCountry(List<int> selects)
    {
        HeroUIManager.Instance.selectHeroListJob = job;
        HeroUIManager.Instance.selectHeroListCountry = country;
        HeroUIManager.Instance.selectHeroList = selects;
        HeroUIManager.Instance.SortHeroList();
        RefreshEmptyTip();
        CreateScroller();
@@ -156,23 +159,23 @@
    //上阵加成
    void OnBattleTeamAttrPer()
    {
        var valuePer = 0;
        var team = TeamManager.Instance.GetTeam(TeamType.Story);
        if (team != null)
        {
            for (int i = 0; i < team.serverHeroes.Length; i++)
            {
                if (team.serverHeroes[i] == null)
                    continue;
                var hero = HeroManager.Instance.GetHero(team.serverHeroes[i].guid);
                if (hero != null)
                {
                    valuePer += hero.GetOnBattleAddPer();
                }
            }
        var valuePer = HeroUIManager.Instance.GetAllHeroPer();
        // var team = TeamManager.Instance.GetTeam(TeamType.Story);
        // if (team != null)
        // {
        //     for (int i = 0; i < team.serverHeroes.Length; i++)
        //     {
        //         if (team.serverHeroes[i] == null)
        //             continue;
        //         var hero = HeroManager.Instance.GetHero(team.serverHeroes[i].guid);
        //         if (hero != null)
        //         {
        //             valuePer += hero.GetAddPer();
        //         }
        //     }
        }
        //上阵属性
        // }
        //全体属性
        for (int i = 0; i < attrOnList.Count; i++)
        {
            attrOnList[i].text = PlayerPropertyConfig.GetFullDescription(new Int2(PlayerPropertyConfig.basePerAttrs[i], valuePer));
@@ -181,23 +184,66 @@
    void OnRefreshCell(ScrollerDataType type, CellView cell)
    {
        var _cell = cell as HeroCardLineCell;
        _cell.Display(cell.index);
        if (type == ScrollerDataType.Header)
        {
            var _cell1 = cell as HeroCardLineTipCell;
            _cell1.Display(cell.index);
        }
        else
        {
            var _cell = cell as HeroCardLineCell;
            _cell.Display(cell.index, activeCount);
        }
    }
    int activeCount;
    void CreateScroller()
    {
        heroListScroller.Refresh();
        for (int i = 0; i < HeroUIManager.Instance.heroSortList.Count; i++)
        heroListScroller.AddCell(ScrollerDataType.Header, 0);
        activeCount = GetAttrActiveHeroCount();
        for (int i = 0; i < activeCount; i++)
        {
            if (i % 4 == 0)
            {
                heroListScroller.AddCell(ScrollerDataType.Header, i);
                heroListScroller.AddCell(ScrollerDataType.Normal, i);
            }
        }
        heroListScroller.AddCell(ScrollerDataType.Header, 1);
        var unActiveCount = HeroUIManager.Instance.heroSortList.Count - activeCount;
        for (int i = 0; i < unActiveCount; i++)
        {
            if (i % 4 == 0)
            {
                //加10000 表示未生效
                heroListScroller.AddCell(ScrollerDataType.Normal, 10000 + activeCount + i);
            }
        }
        heroListScroller.Restart();
    }
    int GetAttrActiveHeroCount()
    {
        int count = 0;
        for (int i = 0; i < HeroUIManager.Instance.heroSortList.Count; i++)
        {
            var hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.heroSortList[i]);
            if (hero == null)
                continue;
            if (hero.isAttrActive)
            {
                count++;
            }
            else
            {
                break;
            }
        }
        return count;
    }
    void RefreshItemEvent(PackType type, int index, int itemID)
    {
        if (type != PackType.Hero)
Main/System/HeroUI/HeroPosWin.cs
@@ -28,7 +28,8 @@
    [SerializeField] Transform heroListEmpty;
    [SerializeField] Toggle showConnTipToggleBtn;
    [SerializeField] HeroSelectBehaviour fiterManager;  //武将筛选
    [SerializeField] Transform heroSelectBehaviour;
    HeroSelectBehaviour fiterManager;  //武将筛选
    [SerializeField] Button oneKeyOnBtn;     //一键上阵
    [SerializeField] Button saveBtn;        //保存阵型
@@ -105,20 +106,19 @@
        });
        m_IsToggleOn = LocalSave.GetBool("ShowConn" + PlayerDatas.Instance.baseData.PlayerID, false);
        fiterManager = HeroSelectBehaviour.Create(heroSelectBehaviour);
    }
    protected override void OnPreOpen()
    {
        HeroUIManager.Instance.selectTeamPosJob = 0;
        HeroUIManager.Instance.selectTeamPosCountry = 0;
        HeroUIManager.Instance.SortHeroOnTeamList();
        heroListScroller.OnRefreshCell += OnRefreshCell;
        HeroUIManager.Instance.OnTeamPosChangeEvent += TeamChangeEvent;
        TeamManager.Instance.OnTeamChange += OnTeamChange;
        ShowFuncBtn();
        SelectTiltleBtn();
        CreateScroller();
        // CreateScroller();
        Display();
    }
@@ -163,7 +163,7 @@
        showConnTipToggleBtn.isOn = isToggleOn;
        fiterManager.Display(0, HeroUIManager.Instance.selectTeamPosJob, HeroUIManager.Instance.selectTeamPosCountry, SelectJobCountry);
        fiterManager.Display(0, SelectJobCountry);
        fightPowerText.text = UIHelper.ReplaceLargeArtNum(FightPowerManager.Instance.GetTeamFightPower(HeroUIManager.Instance.selectTeamType, true));
@@ -189,10 +189,10 @@
        CancelCurrentTask();
    }
    void SelectJobCountry(int job, int country)
    /// 回调参数: 职业,国家,伤害类型,6大战斗属性,特殊属性
    void SelectJobCountry(List<int> selects)
    {
        HeroUIManager.Instance.selectTeamPosJob = job;
        HeroUIManager.Instance.selectTeamPosCountry = country;
        HeroUIManager.Instance.selectListTeamPos = selects;
        HeroUIManager.Instance.SortHeroOnTeamList();
        CreateScroller();
        RefreshEmptyTip();
@@ -245,7 +245,7 @@
                var hero = HeroManager.Instance.GetHero(team.tempHeroes[i].guid);
                if (hero != null)
                {
                    valuePer += hero.GetOnBattleAddPer();
                    valuePer += hero.GetAddPer();
                }
            }
@@ -510,8 +510,7 @@
        {
            return;
        }
        HeroUIManager.Instance.selectTeamPosJob = 0;
        HeroUIManager.Instance.selectTeamPosCountry = 0;
        HeroUIManager.Instance.selectTeamType = type;
        HeroUIManager.Instance.SortHeroOnTeamList();
        Display();
Main/System/HeroUI/HeroSelectBehaviour.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
@@ -10,17 +11,25 @@
    [SerializeField] Button foldBtn;    //收起按钮
    [SerializeField] Transform foldForm;    //收起容器
    [SerializeField] Button unFoldBtn;  //展开按钮
    [SerializeField] GroupButtonEx[] jobsBtn;
    [SerializeField] GroupButtonEx[] countrysBtn;
    [SerializeField] GroupButtonExManager jobManager;
    [SerializeField] GroupButtonExManager countryManager;
    [SerializeField] Toggle[] jobsBtn;
    [SerializeField] Toggle[] countrysBtn;
    [SerializeField] Toggle[] hurtTypeBtn;
    [SerializeField] Toggle[] specialType6Btn;
    [SerializeField] Transform specialTypeMoreRect;
    [SerializeField] ClickScreenOtherSpaceEvent clickScreenOtherSpaceEvent;
    [SerializeField] Button resetBtn;
    int m_Job = 0;
    int m_Country = 0;
    Toggle[] specialTypeMoreBtn;
    int m_Job = 0;  //职业 多选项按位存储
    int m_Country = 0;  //国家 多选项位按存储
    int m_HurtType = 0;  //伤害类型 多选项位按存储
    int m_SpecialType6 = 0;  //6大战斗属性 多选项位按存储
    int m_SpecialTypeMore = 0;  //特殊属性 多选项位按存储
    int foldState = 0;  //0 收起,1 展开
    //点击按钮需通知响应外部事件
    private Action<int, int> selectAction;
    private Action<List<int>> selectAction;
@@ -38,80 +47,190 @@
            RefreshFolState();
        });
        specialTypeMoreBtn = specialTypeMoreRect.GetComponentsInChildren<Toggle>();
        // 初始化特殊属性按钮的显示和文本
        for (int i = 0; i < specialTypeMoreBtn.Length; i++)
        {
            if (i < HeroUIManager.Instance.heroSpecialAttrsForSelect.Count)
            {
                int index = HeroUIManager.Instance.heroSpecialAttrsForSelect[i];
                specialTypeMoreBtn[i].SetActive(true);
                specialTypeMoreBtn[i].GetComponentInChildren<Text>().text = Language.Get($"HeroSpecialty2_{index}");
            }
            else
            {
                specialTypeMoreBtn[i].SetActive(false);
            }
        }
        // 添加所有Toggle监听器
        AddAllListeners();
        clickScreenOtherSpaceEvent.AddListener(() =>
        {
            if (foldState == 0)
                return;
            foldBtn.onClick.Invoke();
        });
        resetBtn.AddListener(Reset);
    }
    // 移除所有Toggle监听器
    void RemoveAllListeners()
    {
        for (int i = 0; i < jobsBtn.Length; i++)
        {
            int index = i;
            jobsBtn[i].AddListener(() =>
            jobsBtn[i].onValueChanged.RemoveAllListeners();
        }
        for (int i = 0; i < countrysBtn.Length; i++)
        {
            countrysBtn[i].onValueChanged.RemoveAllListeners();
        }
        for (int i = 0; i < hurtTypeBtn.Length; i++)
        {
            hurtTypeBtn[i].onValueChanged.RemoveAllListeners();
        }
        for (int i = 0; i < specialType6Btn.Length; i++)
        {
            specialType6Btn[i].onValueChanged.RemoveAllListeners();
        }
        for (int i = 0; i < specialTypeMoreBtn.Length; i++)
        {
            specialTypeMoreBtn[i].onValueChanged.RemoveAllListeners();
        }
    }
    // 添加所有Toggle监听器
    void AddAllListeners()
    {
        for (int i = 0; i < jobsBtn.Length; i++)
        {
            int index = i + 1;
            jobsBtn[i].onValueChanged.AddListener((bool value) =>
            {
                m_Job = index;
                RefreshJobsBtn();
                selectAction?.Invoke(m_Job, m_Country);
                m_Job = value ? m_Job | (1 << index) : m_Job & ~(1 << index);
                selectAction?.Invoke(new List<int>() { m_Job, m_Country, m_HurtType, m_SpecialType6, m_SpecialTypeMore });
            });
        }
        for (int i = 0; i < countrysBtn.Length; i++)
        {
            int index = i;
            countrysBtn[i].AddListener(() =>
            int index = i + 1;
            countrysBtn[i].onValueChanged.AddListener((bool value) =>
            {
                m_Country = index;
                RefreshCountryBtn();
                selectAction?.Invoke(m_Job, m_Country);
                m_Country = value ? m_Country | (1 << index) : m_Country & ~(1 << index);
                selectAction?.Invoke(new List<int>() { m_Job, m_Country, m_HurtType, m_SpecialType6, m_SpecialTypeMore });
            });
        }
        for (int i = 0; i < hurtTypeBtn.Length; i++)
        {
            int index = i + 1;
            hurtTypeBtn[i].onValueChanged.AddListener((bool value) =>
            {
                m_HurtType = value ? m_HurtType | (1 << index) : m_HurtType & ~(1 << index);
                selectAction?.Invoke(new List<int>() { m_Job, m_Country, m_HurtType, m_SpecialType6, m_SpecialTypeMore });
            });
        }
        for (int i = 0; i < specialType6Btn.Length; i++)
        {
            int index = i + 1;
            specialType6Btn[i].onValueChanged.AddListener((bool value) =>
            {
                m_SpecialType6 = value ? m_SpecialType6 | (1 << index) : m_SpecialType6 & ~(1 << index);
                selectAction?.Invoke(new List<int>() { m_Job, m_Country, m_HurtType, m_SpecialType6, m_SpecialTypeMore });
            });
        }
        for (int i = 0; i < specialTypeMoreBtn.Length; i++)
        {
            if (i < HeroUIManager.Instance.heroSpecialAttrsForSelect.Count)
            {
                int index = HeroUIManager.Instance.heroSpecialAttrsForSelect[i];
                specialTypeMoreBtn[i].onValueChanged.AddListener((bool value) =>
                {
                    m_SpecialTypeMore = value ? m_SpecialTypeMore | (1 << index) : m_SpecialTypeMore & ~(1 << index);
                    selectAction?.Invoke(new List<int>() { m_Job, m_Country, m_HurtType, m_SpecialType6, m_SpecialTypeMore });
                });
            }
        }
    }
    /// <summary>
    /// 国家职业筛选
    /// </summary>
    /// <param name="state"> 0收起,1展开</param>
    /// <param name="job"></param>
    /// <param name="country"></param>
    /// <param name="onRefresh"> 点击按钮需通知响应外部事件</param>
    public void Display(int state, int job, int country, Action<int, int> onRefresh)
    /// 回调参数: 职业,国家,伤害类型,6大战斗属性,特殊属性
    public void Display(int state, Action<List<int>> onRefresh)
    {
        foldState = state;
        m_Job = job;
        m_Country = country;
        RefreshFolState();
        RefreshJobsBtn();
        RefreshCountryBtn();
        selectAction = onRefresh;
        Reset();
    }
    //刷新全部分类
    void RefreshJobsBtn()
    {
        jobManager.SelectButton(jobsBtn[m_Job]);
    }
    //刷新全部分类
    void RefreshCountryBtn()
    {
        countryManager.SelectButton(countrysBtn[m_Country]);
    }
    //刷新展开收起状态
    void RefreshFolState()
    {
        unFoldForm.SetActive(foldState == 1);
        foldForm.SetActive(foldState == 0);
    }
    private void LateUpdate()
    {
        if (foldState == 0)
            return;
        if (Input.GetMouseButtonDown(0))
        if (foldState == 1)
        {
            if (!RectTransformUtility.RectangleContainsScreenPoint(this.transform as RectTransform, Input.mousePosition, CameraManager.uiCamera))
            {
                foldBtn.onClick.Invoke();
            }
            UIHelper.ForceRefreshLayout(unFoldForm).Forget();
        }
    }
    public static HeroSelectBehaviour Create(Transform heroSelectBehaviour)
    {
        var instanceGO = UIUtility.CreateWidget("HeroSelectBehaviour", "HeroSelectBehaviour");
        instanceGO.transform.SetParentEx(heroSelectBehaviour, Vector3.zero, Quaternion.identity, Vector3.one);
        return instanceGO.GetComponent<HeroSelectBehaviour>();
    }
    void Reset()
    {
        // 暂时移除所有监听器避免重置时多次触发
        RemoveAllListeners();
        m_Job = 0;
        m_Country = 0;
        m_HurtType = 0;
        m_SpecialType6 = 0;
        m_SpecialTypeMore = 0;
        for (int i = 0; i < jobsBtn.Length; i++)
        {
            jobsBtn[i].isOn = false;
        }
        for (int i = 0; i < countrysBtn.Length; i++)
        {
            countrysBtn[i].isOn = false;
        }
        for (int i = 0; i < hurtTypeBtn.Length; i++)
        {
            hurtTypeBtn[i].isOn = false;
        }
        for (int i = 0; i < specialType6Btn.Length; i++)
        {
            specialType6Btn[i].isOn = false;
        }
        for (int i = 0; i < specialTypeMoreBtn.Length; i++)
        {
            specialTypeMoreBtn[i].isOn = false;
        }
        // 重新添加监听器
        AddAllListeners();
        selectAction?.Invoke(new List<int>() { m_Job, m_Country, m_HurtType, m_SpecialType6, m_SpecialTypeMore });
    }
}
Main/System/HeroUI/HeroTrainWin.cs
@@ -440,7 +440,7 @@
        inheritAttrText[2].text = PlayerPropertyConfig.GetFullDescription(new Int2(PlayerPropertyConfig.inheritAttrs[2], hero.heroConfig.HPInheritPer));
        //上阵属性
        int valuePer = hero.GetOnBattleAddPer();
        int valuePer = hero.GetAddPer();
        for (int i = 0; i < heroAddAttrPerText.Length; i++)
        {
            heroAddAttrPerText[i].text = PlayerPropertyConfig.GetFullDescription(new Int2(PlayerPropertyConfig.basePerAttrs[i], valuePer));
Main/System/HeroUI/HeroUIManager.Collect.cs
@@ -12,8 +12,7 @@
    public Dictionary<int, List<int>> heroCollectDict { get; private set; } = new Dictionary<int, List<int>>();  //武将图鉴按品质列表
    public List<int> heroCollectList = new List<int>(); //武将图鉴列表
    public int selectHeroCollectListJob = 0;    //武将列表界面 筛选职业
    public int selectHeroCollectListCountry = 0;    //武将列表界面筛选国家
    public List<int> selectHeroCollectList = new List<int>();    //武将列表界面 筛选
    public int selectCollectHeroID; //选中的武将id 用于升级
    public int selectForPreviewHeroID; //选中的武将id 用于预览
@@ -21,7 +20,7 @@
    //图鉴和皮肤的激活情况
    Dictionary<int, HB122_tagSCHeroInfo.tagSCHero> heroCollectInfoDic = new Dictionary<int, HB122_tagSCHeroInfo.tagSCHero>();
    public int allHeroBookPer; //全体武将的图鉴激活百分比
    // public int allHeroBookPer; //全体武将的图鉴激活百分比
    public event Action OnHeroCollectEvent;
    public void UpdateHeroCollectInfo(HB122_tagSCHeroInfo netPack)
@@ -30,26 +29,26 @@
        {
            heroCollectInfoDic[(int)netPack.HeroInfoList[i].HeroID] = netPack.HeroInfoList[i];
        }
        allHeroBookPer = GetHeroCollectBookPer();
        // allHeroBookPer = GetHeroCollectBookPer();
        OnHeroCollectEvent?.Invoke();
        UpdateHeroBookRedpoint();
    }
    public int GetHeroCollectBookPer()
    {
        int per = 0;
        foreach (var kv in heroCollectInfoDic)
        {
            var config = HeroQualityConfig.Get(HeroConfig.Get(kv.Key).Quality);
            if (kv.Value.BookInitState != 2)
                continue;
            per += config.BookInitAddPer;
            per += kv.Value.BookStarLV * config.BookStarAddPer;
            per += kv.Value.BookBreakLV * config.BookBreakLVAddPer;
        }
        return per;
    }
    // public int GetHeroCollectBookPer()
    // {
    //     int per = 0;
    //     foreach (var kv in heroCollectInfoDic)
    //     {
    //         var config = HeroQualityConfig.Get(HeroConfig.Get(kv.Key).Quality);
    //         if (kv.Value.BookInitState != 2)
    //             continue;
    //         per += config.BookInitAddPer;
    //         per += kv.Value.BookStarLV * config.BookStarAddPer;
    //         per += kv.Value.BookBreakLV * config.BookBreakLVAddPer;
    //     }
    //     return per;
    // }
    public bool TryGetHeroBookInfo(int heroID, out HB122_tagSCHeroInfo.tagSCHero heroData)
    {
@@ -65,7 +64,22 @@
    public void SortHeroCollectList()
    {
        var heroIDs = HeroConfig.GetKeys().ToList();
        int job = 0;
        int country = 0;
        int hurtType = 0;
        int fightAttrType = 0;
        int specialAttrType = 0;
        if (!selectHeroCollectList.IsNullOrEmpty())
        {
            job = selectHeroCollectList[0];
            country = selectHeroCollectList[1];
            hurtType = selectHeroCollectList[2];
            fightAttrType = selectHeroCollectList[3];
            specialAttrType = selectHeroCollectList[4];
        }
        heroCollectDict.Clear();
        foreach (var heroID in heroIDs)
@@ -77,12 +91,37 @@
            {
                heroCollectDict[heroConfig.Quality] = new List<int>();
            }
            //过滤职业国家
            if (selectHeroCollectListJob != 0 && selectHeroCollectListJob != heroConfig.Class)
            //0代表全部, 同级别是可复选,不同级别为且的关系
            bool isMatch = true;
            if (job != 0)
            {
                continue;
                isMatch = isMatch && (job & (1 << heroConfig.Class)) > 0;
            }
            if (selectHeroCollectListCountry != 0 && selectHeroCollectListCountry != heroConfig.Country)
            if (country != 0)
            {
                isMatch = isMatch && (country & (1 << heroConfig.Country)) > 0;
            }
            if (hurtType != 0)
            {
                isMatch = isMatch && (hurtType & (1 << heroConfig.HurtType)) > 0;
            }
            if (fightAttrType != 0)
            {
                isMatch = isMatch && (fightAttrType & (1 << heroConfig.Specialty)) > 0;
            }
            if (specialAttrType != 0)
            {
                bool isMatch2 = false;
                for (int i = 0; i < heroConfig.Specialty2.Length; i++)
                {
                    isMatch2 = (specialAttrType & (1 << heroConfig.Specialty2[i])) > 0;
                    if (isMatch2)
                        break;
                }
                isMatch = isMatch && isMatch2;
            }
            if (!isMatch)
            {
                continue;
            }
@@ -122,8 +161,8 @@
        HB122_tagSCHeroInfo.tagSCHero colData;
        TryGetHeroBookInfo(heroID, out colData);
        int maxBreakLV = colData.BookBreakLVH; //历史最高突破等级
        int maxStarLV = colData.BookStarLVH;  //历史最高星级
        // int maxBreakLV = colData.BookBreakLVH; //历史最高突破等级
        // int maxStarLV = colData.BookStarLVH;  //历史最高星级
        if (colData.BookInitState == 0)
        {
@@ -133,30 +172,35 @@
        {
            funcState = 1;
        }
        else if (colData.BookInitState == 2)
        else
        {
            if (GetHeroBookMaxLevel(heroID, quality) == colData.BookBreakLV + colData.BookStarLV)
            {
                funcState = 5;
            }
            else if (maxBreakLV + maxStarLV == colData.BookBreakLV + colData.BookStarLV)
            {
                funcState = 2;
            }
            else
            {
                //优先突破升级
                if (colData.BookBreakLV < colData.BookBreakLVH)
                {
                    funcState = 3;
                }
                else
                {
                    funcState = 4;
                }
            }
            funcState = 2;
        }
        // else if (colData.BookInitState == 2)
        // {
        //     if (GetHeroBookMaxLevel(heroID, quality) == colData.BookBreakLV + colData.BookStarLV)
        //     {
        //         funcState = 5;
        //     }
        //     else if (maxBreakLV + maxStarLV == colData.BookBreakLV + colData.BookStarLV)
        //     {
        //         funcState = 2;
        //     }
        //     else
        //     {
        //         //优先突破升级
        //         if (colData.BookBreakLV < colData.BookBreakLVH)
        //         {
        //             funcState = 3;
        //         }
        //         else
        //         {
        //             funcState = 4;
        //         }
        //     }
        // }
        return funcState;
    }
@@ -176,16 +220,16 @@
        return 0;
    }
    public int GetHeroBookPer(int heroID)
    {
        var config = HeroQualityConfig.Get(HeroConfig.Get(heroID).Quality);
        HB122_tagSCHeroInfo.tagSCHero heroData;
        TryGetHeroBookInfo(heroID, out heroData);
        if (heroData.BookInitState < 2)
        {
            return 0;
        }
        return config.BookInitAddPer + heroData.BookStarLV * config.BookStarAddPer + heroData.BookBreakLV * config.BookBreakLVAddPer;
    }
    // public int GetHeroBookPer(int heroID)
    // {
    //     var config = HeroQualityConfig.Get(HeroConfig.Get(heroID).Quality);
    //     HB122_tagSCHeroInfo.tagSCHero heroData;
    //     TryGetHeroBookInfo(heroID, out heroData);
    //     if (heroData.BookInitState < 2)
    //     {
    //         return 0;
    //     }
    //     return config.BookInitAddPer + heroData.BookStarLV * config.BookStarAddPer + heroData.BookBreakLV * config.BookBreakLVAddPer;
    // }
}
Main/System/HeroUI/HeroUIManager.OnTeam.cs
@@ -29,8 +29,7 @@
        }
    }
    public int selectTeamPosJob = 0;    //布阵界面 筛选职业
    public int selectTeamPosCountry = 0;    //布阵界面 筛选国家
    public List<int> selectListTeamPos = new List<int>();    //布阵界面 筛选条件
    public const float clickFlyPosTime = 0.5f;  //点击列表中的武将图标时, 飞入布阵的时间
@@ -50,41 +49,41 @@
    /// <param name="type"></param>
    /// <param name="isPreview">true 客户端预览阵容,默认false 服务器阵容</param>
    /// <returns></returns>
    public Dictionary<string, int> GetLineupPer(TeamType type, bool isPreview = false)
    {
        Dictionary<string, int> lineUPPer = new Dictionary<string, int>()
        {
            {"lineupInitAddPer", 0},
            {"lineupLVAddPer", 0},
            {"lineupBreakLVAddPer", 0},
            {"lineupStarAddPer", 0},
        };
    // public Dictionary<string, int> GetLineupPer(TeamType type, bool isPreview = false)
    // {
    //     Dictionary<string, int> lineUPPer = new Dictionary<string, int>()
    //     {
    //         {"lineupInitAddPer", 0},
    //         {"lineupLVAddPer", 0},
    //         {"lineupBreakLVAddPer", 0},
    //         {"lineupStarAddPer", 0},
    //     };
        var team = TeamManager.Instance.GetTeam(type);
        if (team == null)
        {
            return lineUPPer;
        }
        TeamHero[] teamHeroes = isPreview ? team.tempHeroes : team.serverHeroes;
    //     var team = TeamManager.Instance.GetTeam(type);
    //     if (team == null)
    //     {
    //         return lineUPPer;
    //     }
    //     TeamHero[] teamHeroes = isPreview ? team.tempHeroes : team.serverHeroes;
        foreach (var teamHero in teamHeroes)
        {
            if (teamHero == null)
            {
                continue;
            }
            var config = HeroQualityConfig.Get(HeroConfig.Get(teamHero.heroId).Quality);
            lineUPPer["lineupInitAddPer"] += config.InitAddPer;
    //     foreach (var teamHero in teamHeroes)
    //     {
    //         if (teamHero == null)
    //         {
    //             continue;
    //         }
    //         var config = HeroQualityConfig.Get(HeroConfig.Get(teamHero.heroId).Quality);
    //         lineUPPer["lineupInitAddPer"] += config.InitAddPer;
            HeroInfo hero = HeroManager.Instance.GetHero(teamHero.guid);
            if (hero == null) continue;
            lineUPPer["lineupLVAddPer"] += hero.GetLineupLVAddPer();
            lineUPPer["lineupBreakLVAddPer"] += hero.GetLineupBreakLVAddPer();
            lineUPPer["lineupStarAddPer"] += hero.GetLineupStarAddPer();
    //         HeroInfo hero = HeroManager.Instance.GetHero(teamHero.guid);
    //         if (hero == null) continue;
    //         lineUPPer["lineupLVAddPer"] += hero.GetLineupLVAddPer();
    //         lineUPPer["lineupBreakLVAddPer"] += hero.GetLineupBreakLVAddPer();
    //         lineUPPer["lineupStarAddPer"] += hero.GetLineupStarAddPer();
        }
        return lineUPPer;
    }
    //     }
    //     return lineUPPer;
    // }
    /// <summary>
    /// 按队伍获得阵型(国家光环)属性
@@ -110,7 +109,7 @@
    public void SortHeroOnTeamList()
    {
        heroOnTeamSortList = HeroManager.Instance.GetHeroGuidList(selectTeamPosJob, selectTeamPosCountry);
        heroOnTeamSortList = HeroManager.Instance.GetHeroGuidList(selectListTeamPos);
        heroOnTeamSortList.Sort(CmpHeroByTeamType);
    }
Main/System/HeroUI/HeroUIManager.Reborn.cs
@@ -17,9 +17,7 @@
    public int deletePayBackPer;    //遣散返还的百分比
    public List<string> heroDeleteSortList { get; private set; } = new List<string>();
    public int selectHeroDeleteListJob = 0;    //筛选职业
    public int selectHeroDeleteListCountry = 0;    //筛选国家
    public List<int> selectHeroDeleteList = new List<int>();    //筛选
    public List<string> selectDeleteHeroList { get; private set; } = new List<string>();
    public string jumpDeleteHeroGuid;
@@ -104,7 +102,7 @@
    public void SortHeroDeleteList()
    {
        heroDeleteSortList = HeroManager.Instance.GetHeroGuidList(selectHeroDeleteListJob, selectHeroDeleteListCountry);
        heroDeleteSortList = HeroManager.Instance.GetHeroGuidList(selectHeroDeleteList);
        heroDeleteSortList.Sort(CmpDeleteHero);
    }
Main/System/HeroUI/HeroUIManager.cs
@@ -12,8 +12,7 @@
{
    #region 武将列表界面
    public List<string> heroSortList { get; private set; } = new List<string>();  //上阵为主线的 GUID列表 
    public int selectHeroListJob = 0;    //武将列表界面 筛选职业
    public int selectHeroListCountry = 0;    //武将列表界面筛选国家
    public List<int> selectHeroList = new List<int>();   //武将列表界面 筛选职业
    public string selectHeroGuid; //选中的武将id
    public int[] heroRedpointItemList;  //有影响红点的道具
    #endregion
@@ -31,6 +30,7 @@
    public int firstHeroIDBookUpdate = 0;    //图鉴中第一个可以升级或者升星的武将,引导用
    public List<int> heroSpecialAttrsForSelect = new List<int>();  //筛选用的特殊属性汇总
    public override void Init()
    {
@@ -43,7 +43,7 @@
        QuickSetting.Instance.onQuickSettingUpdate += OnQuickSettingUpdate;
        ParseConfig();
        InitHeroOnTeamRedpointList();
        InitHeroBookRedpointList();
        InitHerosData();
    }
    public override void Release()
@@ -208,6 +208,20 @@
        return hero.heroLevel == GetMaxLVByBreakLV(hero.Quality, hero.breakLevel);
    }
    public int GetAllHeroPer()
    {
        var list = HeroManager.Instance.GetHeroList();
        int per = 0;
        foreach (var hero in list)
        {
            if (hero.isAttrActive)
            {
                per += hero.GetAddPer();
            }
        }
        return per;
    }
    #endregion
@@ -240,7 +254,7 @@
    //刷新时机, 打开武将界面 或者 关闭功能界面
    public void SortHeroList()
    {
        heroSortList = HeroManager.Instance.GetHeroGuidList(selectHeroListJob, selectHeroListCountry);
        heroSortList = HeroManager.Instance.GetHeroGuidList(selectHeroList);
        heroSortList.Sort(CmpHero);
    }
@@ -252,6 +266,13 @@
        if (heroA == null || heroB == null)
        {
            return 0;
        }
        bool isActiveA = heroA.isAttrActive;
        bool isActiveB = heroB.isAttrActive;
        if (isActiveA != isActiveB)
        {
            return isActiveA ? -1 : 1;
        }
        // 排序规则:上阵>武将等级>突破等级>武将觉醒阶级>武将品质>武将吞噬星级>武将ID
@@ -286,7 +307,6 @@
    }
    #region 招募
    public HappXBTitle selectCallType;  //寻宝枚举类型
@@ -295,8 +315,7 @@
    //积分招募预览
    public List<int> heroCallSortList { get; private set; } = new List<int>();  //积分招募列表 
    public int selectHeroCallListJob = 0;    //筛选职业
    public int selectHeroCallListCountry = 0;    //筛选国家
    public List<int> selectHeroCallList = new List<int>();    //筛选
    public List<int> newHeroIDList = new List<int>();  //新武将列表
    public bool IsNewHero(int heroID)
@@ -356,12 +375,28 @@
            allHeroCallScoreList = HappyXBModel.Instance.GetAllGridLibItemIDByType((int)HappXBTitle.HeroCallScore);
        }
        heroCallSortList = new List<int>();
        if (selectHeroCallListJob == 0 && selectHeroCallListCountry == 0)
        if (selectHeroCallList.IsNullOrEmpty())
        {
            heroCallSortList = allHeroCallScoreList;
        }
        else
        {
            int job = 0;
            int country = 0;
            int hurtType = 0;
            int fightAttrType = 0;
            int specialAttrType = 0;
            if (!selectHeroCallList.IsNullOrEmpty())
            {
                job = selectHeroCallList[0];
                country = selectHeroCallList[1];
                hurtType = selectHeroCallList[2];
                fightAttrType = selectHeroCallList[3];
                specialAttrType = selectHeroCallList[4];
            }
            foreach (var item in allHeroCallScoreList)
            {
                HeroConfig heroConfig = HeroConfig.Get(item);
@@ -369,14 +404,41 @@
                {
                    continue;
                }
                if (selectHeroCallListJob != 0 && selectHeroCallListJob != heroConfig.Class)
                //0代表全部, 同级别是可复选,不同级别为且的关系
                bool isMatch = true;
                if (job != 0)
                {
                    isMatch = isMatch && (job & (1 << heroConfig.Class)) > 0;
                }
                if (country != 0)
                {
                    isMatch = isMatch && (country & (1 << heroConfig.Country)) > 0;
                }
                if (hurtType != 0)
                {
                    isMatch = isMatch && (hurtType & (1 << heroConfig.HurtType)) > 0;
                }
                if (fightAttrType != 0)
                {
                    isMatch = isMatch && (fightAttrType & (1 << heroConfig.Specialty)) > 0;
                }
                if (specialAttrType != 0)
                {
                    bool isMatch2 = false;
                    for (int i = 0; i < heroConfig.Specialty2.Length; i++)
                    {
                        isMatch2 = (specialAttrType & (1 << heroConfig.Specialty2[i])) > 0;
                        if (isMatch2)
                            break;
                    }
                    isMatch = isMatch && isMatch2;
                }
                if (!isMatch)
                {
                    continue;
                }
                if (selectHeroCallListCountry != 0 && selectHeroCallListCountry != heroConfig.Country)
                {
                    continue;
                }
                heroCallSortList.Add(item);
            }
        }
@@ -507,16 +569,33 @@
    }
    void InitHeroBookRedpointList()
    void InitHerosData()
    {
        heroBookRedpointList.Clear();
        foreach (var key in HeroConfig.GetKeys())
        {
            var config = HeroConfig.Get(key);
            //汇总特殊属性
            if (!config.Specialty2.IsNullOrEmpty())
            {
                foreach (var num in config.Specialty2)
                {
                    if (!heroSpecialAttrsForSelect.Contains(num))
                    {
                        heroSpecialAttrsForSelect.Add(num);
                    }
                }
            }
            if (config.PlayerCanUse == 0)
                continue;
            //图鉴红点
            heroBookRedpointList.Add(new Redpoint(MainRedDot.HeroCardCollectRedpoint, MainRedDot.HeroCardCollectRedpoint * 10000000 + key));
        }
        heroSpecialAttrsForSelect.Sort();
    }
Main/System/Main/FightPowerFormula.cs
@@ -5,23 +5,18 @@
    // 变量名常量定义
    private const string LVVALUE_VALUE = "lvValue";
    private const string EQUIPVALUE_VALUE = "equipValue";
    private const string BOOKVALUE_VALUE = "bookValue";
    private const string REALMVALUE_VALUE = "realmValue";
    private const string GUBAOVALUE_VALUE = "gubaoValue";
    private const string HJGVALUE_VALUE = "hjgValue";
    private const string HORSEVALUE_VALUE = "horseValue";
    private const string BEAUTYVALUE_VALUE = "beautyValue";
    private const string LINEUPHALOPER_VALUE = "lineupHaloPer";
    private const string BOOKPER_VALUE = "bookPer";
    private const string REALMPER_VALUE = "realmPer";
    private const string GUBAOPER_VALUE = "gubaoPer";
    private const string HJGPER_VALUE = "hjgPer";
    private const string HORSEPER_VALUE = "horsePer";
    private const string BEAUTYPER_VALUE = "beautyPer";
    private const string LINEUPINITADDPER_VALUE = "lineupInitAddPer";
    private const string LINEUPLVADDPER_VALUE = "lineupLVAddPer";
    private const string LINEUPBREAKLVADDPER_VALUE = "lineupBreakLVAddPer";
    private const string LINEUPSTARADDPER_VALUE = "lineupStarAddPer";
    private const string CARDPER_VALUE = "cardPer";
    private const string INHERITPER_VALUE = "inheritPer";
    private const string FETTERPER_VALUE = "fetterPer";
    private const string STARTALENTPER_VALUE = "starTalentPer";
@@ -124,9 +119,9 @@
    private const string OFFICIALLV_VALUE = "OfficialLV";
    // 基础属性公式
    // (lvValue+equipValue+bookValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue)*(1+lineupHaloPer+bookPer+realmPer+gubaoPer+hjgPer+horsePer+beautyPer+lineupInitAddPer+lineupLVAddPer+lineupBreakLVAddPer+lineupStarAddPer)*(inheritPer+fetterPer+starTalentPer+breakLVPer+awakeTalentPer)+heroSelfValue+heroLVValue
    // (lvValue+equipValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue)*(1+lineupHaloPer+realmPer+gubaoPer+hjgPer+horsePer+beautyPer+cardPer)*(inheritPer+fetterPer+starTalentPer+breakLVPer+awakeTalentPer)+heroSelfValue+heroLVValue
    // 战斗属性公式
    // (lvValue+equipValue+bookValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue)+(heroSelfValue+lineupHaloValue+starTalentValue+breakLVValue+awakeTalentValue)+fetterValue
    // (lvValue+equipValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue)+(heroSelfValue+lineupHaloValue+starTalentValue+breakLVValue+awakeTalentValue)+fetterValue
    // 战斗力公式
    // long(Atk*AtkRatio+MaxHP*MaxHPRatio+Def*DefRatio+(StunRate*StunRateRatio+SuperHitRate*SuperHitRateRatio+ComboRate*ComboRateRatio+MissRate*MissRateRatio+ParryRate*ParryRateRatio+SuckHPPer*SuckHPPerRatio+StunRateDef*StunRateDefRatio+SuperHitRateDef*SuperHitRateDefRatio+ComboRateDef*ComboRateDefRatio+MissRateDef*MissRateDefRatio+ParryRateDef*ParryRateDefRatio+SuckHPPerDef*SuckHPPerDefRatio+FinalDamPer*FinalDamPerRatio+FinalDamPerDef*FinalDamPerDefRatio+PhyDamPer*PhyDamPerRatio+PhyDamPerDef*PhyDamPerDefRatio+MagDamPer*MagDamPerRatio+MagDamPerDef*MagDamPerDefRatio+NormalSkillPer*NormalSkillPerRatio+NormalSkillPerDef*NormalSkillPerDefRatio+AngerSkillPer*AngerSkillPerRatio+AngerSkillPerDef*AngerSkillPerDefRatio+SuperDamPer*SuperDamPerRatio+SuperDamPerDef*SuperDamPerDefRatio+CurePer*CurePerRatio+CurePerDef*CurePerDefRatio+ShieldPer*ShieldPerRatio+ShieldPerDef*ShieldPerDefRatio+DOTPer*DOTPerRatio+DOTPerDef*DOTPerDefRatio+WeiFinalDamPer*WeiFinalDamPerRatio+WeiFinalDamPerDef*WeiFinalDamPerDefRatio+ShuFinalDamPer*ShuFinalDamPerRatio+ShuFinalDamPerDef*ShuFinalDamPerDefRatio+WuFinalDamPer*WuFinalDamPerRatio+WuFinalDamPerDef*WuFinalDamPerDefRatio+QunFinalDamPer*QunFinalDamPerRatio+QunFinalDamPerDef*QunFinalDamPerDefRatio+PVPDamPer*PVPDamPerRatio+PVPDamPerDef*PVPDamPerDefRatio)/100.0-55000)
    // 技能战斗力公式
@@ -136,23 +131,18 @@
    {
        double lvValue = variables[LVVALUE_VALUE];
        double equipValue = variables[EQUIPVALUE_VALUE];
        double bookValue = variables[BOOKVALUE_VALUE];
        double realmValue = variables[REALMVALUE_VALUE];
        double gubaoValue = variables[GUBAOVALUE_VALUE];
        double hjgValue = variables[HJGVALUE_VALUE];
        double horseValue = variables[HORSEVALUE_VALUE];
        double beautyValue = variables[BEAUTYVALUE_VALUE];
        double lineupHaloPer = variables[LINEUPHALOPER_VALUE];
        double bookPer = variables[BOOKPER_VALUE];
        double realmPer = variables[REALMPER_VALUE];
        double gubaoPer = variables[GUBAOPER_VALUE];
        double hjgPer = variables[HJGPER_VALUE];
        double horsePer = variables[HORSEPER_VALUE];
        double beautyPer = variables[BEAUTYPER_VALUE];
        double lineupInitAddPer = variables[LINEUPINITADDPER_VALUE];
        double lineupLVAddPer = variables[LINEUPLVADDPER_VALUE];
        double lineupBreakLVAddPer = variables[LINEUPBREAKLVADDPER_VALUE];
        double lineupStarAddPer = variables[LINEUPSTARADDPER_VALUE];
        double cardPer = variables[CARDPER_VALUE];
        double inheritPer = variables[INHERITPER_VALUE];
        double fetterPer = variables[FETTERPER_VALUE];
        double starTalentPer = variables[STARTALENTPER_VALUE];
@@ -161,14 +151,13 @@
        double heroSelfValue = variables[HEROSELFVALUE_VALUE];
        double heroLVValue = variables[HEROLVVALUE_VALUE];
        return (lvValue+equipValue+bookValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue)*(1+lineupHaloPer+bookPer+realmPer+gubaoPer+hjgPer+horsePer+beautyPer+lineupInitAddPer+lineupLVAddPer+lineupBreakLVAddPer+lineupStarAddPer)*(inheritPer+fetterPer+starTalentPer+breakLVPer+awakeTalentPer)+heroSelfValue+heroLVValue;
        return (lvValue+equipValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue)*(1+lineupHaloPer+realmPer+gubaoPer+hjgPer+horsePer+beautyPer+cardPer)*(inheritPer+fetterPer+starTalentPer+breakLVPer+awakeTalentPer)+heroSelfValue+heroLVValue;
    }
    public static double GetFightAttr(Dictionary<string, double> variables)
    {
        double lvValue = variables[LVVALUE_VALUE];
        double equipValue = variables[EQUIPVALUE_VALUE];
        double bookValue = variables[BOOKVALUE_VALUE];
        double realmValue = variables[REALMVALUE_VALUE];
        double gubaoValue = variables[GUBAOVALUE_VALUE];
        double hjgValue = variables[HJGVALUE_VALUE];
@@ -181,7 +170,7 @@
        double awakeTalentValue = variables[AWAKETALENTVALUE_VALUE];
        double fetterValue = variables[FETTERVALUE_VALUE];
        return (lvValue+equipValue+bookValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue)+(heroSelfValue+lineupHaloValue+starTalentValue+breakLVValue+awakeTalentValue)+fetterValue;
        return (lvValue+equipValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue)+(heroSelfValue+lineupHaloValue+starTalentValue+breakLVValue+awakeTalentValue)+fetterValue;
    }
    public static double GetFightPower(Dictionary<string, double> variables)
Main/System/Main/FightPowerManager.cs
@@ -46,6 +46,7 @@
    private const string FETTER_PER = "fetterPer";
    private const string HERO_LV_VALUE = "heroLVValue";
    private const string HERO_LV_PER = "heroLVPer";
    private const string HERO_CARDPER = "cardPer";
    // 战力变量常量
    private const string ATK_RATIO = "AtkRatio";
@@ -143,8 +144,10 @@
    //分开存储预览和 真实属性
    public Dictionary<int, int> equipAttrs = new Dictionary<int, int>();   //装备属性
    public Dictionary<string, int> lineUpPerDict = new Dictionary<string, int>();  //阵容属性加成
    // public Dictionary<string, int> lineUpPerDict = new Dictionary<string, int>();  //阵容属性加成
    public Dictionary<int, int> countryAttrs = new Dictionary<int, int>();   //阵容国家(光环)属性
    float allHeroAddPer = 0;  //所有武将加成
    //等级属性
    void RefreshLVAttrs()
@@ -259,8 +262,8 @@
    {
        //阵容属性
        // 阵容:所有武将上阵属性
        lineUpPerDict = HeroUIManager.Instance.GetLineupPer(teamTypeCalc, isPreviewTeamPower);
        // lineUpPerDict = HeroUIManager.Instance.GetLineupPer(teamTypeCalc, isPreviewTeamPower);
        allHeroAddPer = HeroUIManager.Instance.GetAllHeroPer() / 10000.0f;
#if UNITY_EDITOR
        // Debug.Log("战力:上阵属性 " + JsonMapper.ToJson(lineUpPerDict));
#endif
@@ -302,10 +305,10 @@
        
        propertyVariables[LV_VALUE] = lvAttrs.ContainsKey(attrType) ? lvAttrs[attrType] : 0;
        propertyVariables[EQUIP_VALUE] = equipAttrs.ContainsKey(attrType) ? equipAttrs[attrType] : 0;
        propertyVariables[BOOK_VALUE] = 0;
        // propertyVariables[BOOK_VALUE] = 0;
        propertyVariables[REALM_VALUE] = officialAttrs.ContainsKey(attrType) ? officialAttrs[attrType] : 0;
        propertyVariables[REALM_PER] = GetOfficialPer(attrType) / 10000.0f;
        propertyVariables[BOOK_PER] = GetBookPer(attrType) / 10000.0f;
        // propertyVariables[BOOK_PER] = GetBookPer(attrType) / 10000.0f;
        propertyVariables[GUBAO_VALUE] = 0;
        propertyVariables[GUBAO_PER] = 0;
        propertyVariables[HJG_VALUE] = PhantasmPavilionManager.Instance.GetAttrValue(attrType);
@@ -315,11 +318,13 @@
        propertyVariables[BEAUTY_VALUE] = 0;
        propertyVariables[BEAUTY_PER] = 0;
        //全体卡牌加成
        propertyVariables[HERO_CARDPER] = allHeroAddPer;
        //!!!单武将战力预览的话需要排除队伍影响战力,只算武将自身的上阵属性
        propertyVariables[LINEUP_INIT_ADD_PER] = GetLineUpPer(attrType, LINEUP_INIT_ADD_PER) / 10000.0f;
        propertyVariables[LINEUP_LV_ADD_PER] = GetLineUpPer(attrType, LINEUP_LV_ADD_PER) / 10000.0f;
        propertyVariables[LINEUP_BREAK_LV_ADD_PER] = GetLineUpPer(attrType, LINEUP_BREAK_LV_ADD_PER) / 10000.0f;
        propertyVariables[LINEUP_STAR_ADD_PER] = GetLineUpPer(attrType, LINEUP_STAR_ADD_PER) / 10000.0f;
        // propertyVariables[LINEUP_INIT_ADD_PER] = GetLineUpPer(attrType, LINEUP_INIT_ADD_PER) / 10000.0f;
        // propertyVariables[LINEUP_LV_ADD_PER] = GetLineUpPer(attrType, LINEUP_LV_ADD_PER) / 10000.0f;
        // propertyVariables[LINEUP_BREAK_LV_ADD_PER] = GetLineUpPer(attrType, LINEUP_BREAK_LV_ADD_PER) / 10000.0f;
        // propertyVariables[LINEUP_STAR_ADD_PER] = GetLineUpPer(attrType, LINEUP_STAR_ADD_PER) / 10000.0f;
        //阵容光环 三围百分比加成
        propertyVariables[LINEUP_HALO_VALUE] = countryAttrs.ContainsKey(attrType) ? countryAttrs[attrType] : 0;
@@ -354,24 +359,24 @@
    int GetLineUpPer(int attrType, string key)
    {
        if (!PlayerPropertyConfig.baseAttrs.Contains(attrType))
        {
            return 0;
        }
    // int GetLineUpPer(int attrType, string key)
    // {
    //     if (!PlayerPropertyConfig.baseAttrs.Contains(attrType))
    //     {
    //         return 0;
    //     }
        return lineUpPerDict[key];
    }
    //     return lineUpPerDict[key];
    // }
    int GetBookPer(int attrType)
    {
        if (!PlayerPropertyConfig.baseAttrs.Contains(attrType))
        {
            return 0;
        }
        return HeroUIManager.Instance.allHeroBookPer;
    }
    // int GetBookPer(int attrType)
    // {
    //     if (!PlayerPropertyConfig.baseAttrs.Contains(attrType))
    //     {
    //         return 0;
    //     }
    //     return HeroUIManager.Instance.allHeroBookPer;
    // }
    int GetOfficialPer(int attrType)
    {
Main/System/Main/HeroFightingCardCell.cs
@@ -118,8 +118,6 @@
    void ClickHero()
    {
        HeroUIManager.Instance.selectHeroListJob = 0;
        HeroUIManager.Instance.selectHeroListCountry = 0;
        HeroUIManager.Instance.SortHeroList();
        HeroUIManager.Instance.selectHeroGuid = guid;
        UIManager.Instance.OpenWindow<HeroTrainWin>();
Main/Utility/UIHelper.cs
@@ -8,6 +8,7 @@
using System.Text.RegularExpressions;
using System.IO;
using LitJson;
using Cysharp.Threading.Tasks;
/// <summary>
/// UI辅助类
@@ -1423,11 +1424,33 @@
        GUIUtility.systemCopyBuffer = text;
        Debug.Log("文字已复制到剪贴板: " + text);
    }
    //获取剪切板内容
    public static string GetClipboardText()
    {
        return GUIUtility.systemCopyBuffer;
    }
    
    /// <summary>
    /// 强制刷新Layout,解决嵌套Layout和ContentSizeFitter的重叠问题
    /// </summary>
    public static async UniTask ForceRefreshLayout(Transform transform)
    {
        await UniTask.DelayFrame(2);
        // 刷新所有Layout组件
        var layouts = transform.GetComponentsInChildren<LayoutGroup>(true);
        foreach (var layout in layouts)
        {
            LayoutRebuilder.ForceRebuildLayoutImmediate(layout.GetComponent<RectTransform>());
        }
        await UniTask.DelayFrame(2);
        // 刷新所有Layout组件
        foreach (var layout in layouts)
        {
            LayoutRebuilder.ForceRebuildLayoutImmediate(layout.GetComponent<RectTransform>());
        }
    }
}