hch
2025-09-09 e7e22b0cfafe53223b0a0f6b6189b2a8219f0740
117 【武将】武将系统 - 图鉴
17个文件已修改
2个文件已添加
686 ■■■■ 已修改文件
Main/Config/PartialConfigs/HeroBreakConfig.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB237_tagCSHeroBookUP.cs 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/DTCFile/ServerPack/HB1_Role/DTCB122_tagSCHeroInfo.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/NetworkPackage/ServerPack/HB1_Role/HB122_tagSCHeroInfo.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/HeroInfo.Properties.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroBaseWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroCardCell.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroCollectionCardCell.cs 83 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroCollectionLineCell.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroCollectionLvUpWin.cs 203 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroCollectionLvUpWin.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroCollectionWin.cs 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroTrainWin.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroUIManager.Collect.cs 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroUIManager.Talent.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroUIManager.cs 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/FightPowerManager.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Redpoint/MainRedDot.cs 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/UIHelper.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Config/PartialConfigs/HeroBreakConfig.cs
@@ -46,4 +46,14 @@
    {
        return GetHeroBreakConfig(heroID, breakLv) == null;
    }
    public static int GetMaxBreakLv(int heroID)
    {
        Dictionary<int, HeroBreakConfig> tempDic = null;
        if (!configDics.TryGetValue(heroID, out tempDic))
        {
            return 0;
        }
        return tempDic.Count;
    }
}
Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB237_tagCSHeroBookUP.cs
@@ -1,22 +1,20 @@
using UnityEngine;
using System.Collections;
// B2 37 武将图鉴激活升级 #tagCSHeroBookUP
public class CB237_tagCSHeroBookUP : GameNetPackBasic {
    public uint HeroID;    //武将ID
    public ushort ItemIndex;    //关联武将物品所在武将背包索引,激活时可不用发
    public byte BookType;    //图鉴激活类型: 0-初始激活;1-星级升级;2-突破等级升级
    public CB237_tagCSHeroBookUP () {
        combineCmd = (ushort)0x03FE;
        _cmd = (ushort)0xB237;
    }
    public override void WriteToBytes () {
        WriteBytes (HeroID, NetDataType.DWORD);
        WriteBytes (ItemIndex, NetDataType.WORD);
        WriteBytes (BookType, NetDataType.BYTE);
    }
}
// B2 37 武将图鉴激活升级 #tagCSHeroBookUP
public class CB237_tagCSHeroBookUP : GameNetPackBasic {
    public uint HeroID;    //武将ID
    public byte BookType;    //图鉴激活类型: 0-初始激活;1-星级升级;2-突破等级升级
    public CB237_tagCSHeroBookUP () {
        combineCmd = (ushort)0x03FE;
        _cmd = (ushort)0xB237;
    }
    public override void WriteToBytes () {
        WriteBytes (HeroID, NetDataType.DWORD);
        WriteBytes (BookType, NetDataType.BYTE);
    }
}
Main/Core/NetworkPackage/DTCFile/ServerPack/HB1_Role/DTCB122_tagSCHeroInfo.cs
@@ -1,7 +1,7 @@
using UnityEngine;
using System.Collections;
// B1 22 武将图鉴信息 #tagSCHeroInfo
// B1 22 武将信息 #tagSCHeroInfo
public class DTCB122_tagSCHeroInfo : DtcBasic {
    public override void Done(GameNetPackBasic vNetPack)
Main/Core/NetworkPackage/ServerPack/HB1_Role/HB122_tagSCHeroInfo.cs
@@ -1,7 +1,7 @@
using UnityEngine;
using System.Collections;
// B1 22 武将图鉴信息 #tagSCHeroInfo
// B1 22 武将信息 #tagSCHeroInfo
public class HB122_tagSCHeroInfo : GameNetPackBasic {
    public ushort HeroCnt;
@@ -21,6 +21,8 @@
            TransBytes (out HeroInfoList[i].BookInitState, vBytes, NetDataType.BYTE);
            TransBytes (out HeroInfoList[i].BookStarLV, vBytes, NetDataType.WORD);
            TransBytes (out HeroInfoList[i].BookBreakLV, vBytes, NetDataType.WORD);
            TransBytes (out HeroInfoList[i].BookStarLVH, vBytes, NetDataType.WORD);
            TransBytes (out HeroInfoList[i].BookBreakLVH, vBytes, NetDataType.WORD);
        }
    }
@@ -30,6 +32,8 @@
        public byte BookInitState;        // 图鉴激活状态:0-未激活;1-可激活;2-已激活
        public ushort BookStarLV;        // 图鉴星级等级
        public ushort BookBreakLV;        // 图鉴突破等级
        public ushort BookStarLVH;        // 图鉴星级历史最高等级
        public ushort BookBreakLVH;        // 图鉴突破历史最高等级
    }
}
Main/System/Hero/HeroInfo.Properties.cs
@@ -120,12 +120,12 @@
    //上阵属性:攻防血
    public int GetOnBattleAddPer()
    {
        return qualityConfig.InitAddPer + qualityConfig.LVAddPer * heroLevel + qualityConfig.BreakLVAddPer * breakLevel + qualityConfig.StarAddPer * heroStar;
        return qualityConfig.InitAddPer + qualityConfig.LVAddPer * (heroLevel - 1) + qualityConfig.BreakLVAddPer * breakLevel + qualityConfig.StarAddPer * heroStar;
    }
    public int GetLineupLVAddPer()
    {
        return qualityConfig.LVAddPer * heroLevel;
        return qualityConfig.LVAddPer * (heroLevel - 1);
    }
    public int GetLineupBreakLVAddPer()
Main/System/HeroUI/HeroBaseWin.cs
@@ -54,7 +54,7 @@
                currentSubUI = UIManager.Instance.OpenWindow<HeroListWin>();
                break;
            case 1:
                //currentSubUI = UIManager.Instance.OpenWindow<HeroCollectionsWin>();
                currentSubUI = UIManager.Instance.OpenWindow<HeroCollectionWin>();
                break;
            case 2:
                break;
Main/System/HeroUI/HeroCardCell.cs
@@ -6,7 +6,6 @@
{
    [SerializeField] Button heroCardBtn;
    [SerializeField] Image heroCardBG;
    [SerializeField] Material glowMaterial; // 流光效果材质
    [SerializeField] Text lvText;
    [SerializeField] Image countryImg;
    [SerializeField] Image jobImg;
@@ -32,10 +31,6 @@
        this.gameObject.SetActive(true);
        heroCardBG.SetSprite("herocardbg" + hero.Quality);
        if (glowMaterial != null)
        {
            heroCardBG.material = glowMaterial;
        }
        lvText.text = Language.Get("L1094") + hero.heroLevel.ToString();
        var heroConfig = hero.heroConfig;
        countryImg.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country));
Main/System/HeroUI/HeroCollectionCardCell.cs
@@ -6,70 +6,61 @@
{
    [SerializeField] Button heroCardBtn;
    [SerializeField] Image heroCardBG;
    [SerializeField] Material glowMaterial; // 流光效果材质
    [SerializeField] Text lvText;
    [SerializeField] UIHeroController heroModel;
    [SerializeField] List<Image> starImgList;
    [SerializeField] Image countryImg;
    [SerializeField] Image jobImg;
    [SerializeField] UIHeroController heroModel;
    [SerializeField] Image onStateImg;
    [SerializeField] RedpointBehaviour redpoint;
    [SerializeField] Image trainStateImg;
    [SerializeField] Text nameText;
    [SerializeField] Image awakeImg;
    [SerializeField] Text awakeLVText;
    [SerializeField] List<Image> starImgList;
    [SerializeField] Image trainStateImg;
    [SerializeField] RedpointBehaviour redpoint;
    [SerializeField] Button fullBtn;
    [SerializeField] GameObject unGetObj;
    [SerializeField] GameObject activeObj; // 可激活带流光效果材质
    string guid;
    public void Display(int index)
    public void Display(int index, int quality)
    {
        guid = HeroUIManager.Instance.heroSortList[index];
        var hero = HeroManager.Instance.GetHero(guid);
        if (hero == null)
        {
            this.gameObject.SetActive(false);
            return;
        }
        var heroID = HeroUIManager.Instance.heroCollectDict[quality][index];
        var heroConfig = HeroConfig.Get(heroID);
        HB122_tagSCHeroInfo.tagSCHero colData;
        HeroUIManager.Instance.TryGetHeroBookInfo(heroID, out colData);
        heroCardBG.SetSprite("herocardbg" + heroConfig.Quality);
        this.gameObject.SetActive(true);
        heroCardBG.SetSprite("herocardbg" + hero.Quality);
        if (glowMaterial != null)
        {
            heroCardBG.material = glowMaterial;
        }
        lvText.text = Language.Get("L1094") + hero.heroLevel.ToString();
        var heroConfig = hero.heroConfig;
        //分为0未获得、1可激活、2常规、3突破升级、4、星升级、5已满级
        int funcState = HeroUIManager.Instance.GetHeroBookState(heroID, quality);
        activeObj.SetActive(funcState == 1);
        fullBtn.SetActive(funcState == 5);
        unGetObj.SetActive(funcState == 0);
        countryImg.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country));
        jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(heroConfig.Class));
        heroModel.Create(heroConfig.SkinIDList[hero.SkinIndex], heroConfig.UIScale);
        onStateImg.SetActive(hero.IsInTeamByTeamType(TeamType.Story));
        heroModel.Create(heroConfig.SkinIDList[0], heroConfig.UIScale);
        redpoint.redpointId = MainRedDot.HeroCardRedpoint * 1000 + hero.itemHero.gridIndex;
        var funcState = hero.funcState;
        if (funcState > 0)
        redpoint.redpointId = MainRedDot.HeroCardCollectRedpoint * 10000000 + heroID;
        if (funcState == 3 || funcState == 4)
        {
            trainStateImg.SetActive(true);
            trainStateImg.SetSprite("herofuncstate" + hero.funcState);
            trainStateImg.SetSprite("herofuncstate2");
        }
        else
        {
            trainStateImg.SetActive(false);
        }
        nameText.text = hero.breakLevel == 0 ? heroConfig.Name : Language.Get("herocardbreaklv", heroConfig.Name, hero.breakLevel);
        awakeImg.SetActive(hero.awakeLevel > 0);
        awakeLVText.text = hero.awakeLevel.ToString();
        nameText.text = colData.BookBreakLV == 0 ? heroConfig.Name : Language.Get("herocardbreaklv", heroConfig.Name, colData.BookBreakLV);
        for (int i = 0; i < starImgList.Count; i++)
        {
            if (hero.heroStar == 0 && i == 0)
            if (colData.BookStarLV == 0 && i == 0)
            {
                // 无星级 特殊处理
                starImgList[i].SetActive(true);
                starImgList[i].SetSprite("herostar" + hero.heroStar);
                starImgList[i].SetSprite("herostar" + colData.BookStarLV);
            }
            else if ((hero.heroStar - 1) % starImgList.Count >= i)
            else if ((colData.BookStarLV - 1) % starImgList.Count >= i)
            {
                starImgList[i].SetActive(true);
                starImgList[i].SetSprite("herostar" + (((hero.heroStar - 1) / starImgList.Count) + 1) * starImgList.Count);
                starImgList[i].SetSprite("herostar" + (((colData.BookStarLV - 1) / starImgList.Count) + 1) * starImgList.Count);
            }
            else
            {
@@ -79,8 +70,18 @@
        heroCardBtn.AddListener(() =>
        {
            HeroUIManager.Instance.selectHeroGuid = guid;
            UIManager.Instance.OpenWindow<HeroTrainWin>();
            HeroUIManager.Instance.selectCollectHeroID = heroID;
            var state = HeroUIManager.Instance.GetHeroBookState(heroID, quality);
            if (state == 1 || state == 3 || state == 4)
            {
                UIManager.Instance.OpenWindow<HeroCollectionLvUpWin>();
            }
        });
        fullBtn.AddListener(() =>
        {
            HeroUIManager.Instance.selectCollectHeroID = heroID;
            UIManager.Instance.OpenWindow<HeroCollectionLvUpWin>();
        });
    }
}
Main/System/HeroUI/HeroCollectionLineCell.cs
@@ -2,16 +2,17 @@
public class HeroCollectionLineCell : CellView
{
    [SerializeField] HeroCardCell[] cardList;
    [SerializeField] HeroCollectionCardCell[] cardList;
    public void Display(int index)
    public void Display(int index, int quality)
    { 
        var _List = HeroUIManager.Instance.heroCollectDict[quality];
        for (int i = 0; i < cardList.Length; i++)
        {
            if (i + index < HeroUIManager.Instance.heroSortList.Count)
            if (i + index < _List.Count)
            {
                cardList[i].SetActive(true);
                cardList[i].Display(index + i);
                cardList[i].Display(index + i, quality);
            }
            else
            {
Main/System/HeroUI/HeroCollectionLvUpWin.cs
New file
@@ -0,0 +1,203 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 图鉴激活升级界面
/// </summary>
public class HeroCollectionLvUpWin : UIBase
{
    [SerializeField] GameObject lvupPanel;
    [SerializeField] GameObject fullPanel;
    [SerializeField] HeroHeadBaseCell beforeHeadCell;
    [SerializeField] Text name1;
    [SerializeField] GameObject unActiveGo;
    [SerializeField] HeroHeadBaseCell afterHeadCell;
    [SerializeField] Text name2;
    [SerializeField] Text[] attrNames;
    [SerializeField] Text[] beforeAttrValues;
    [SerializeField] Text[] afterAttrValues;
    [SerializeField] RichText awardInfo;
    [SerializeField] Button btn;
    [SerializeField] Text btnText;
    [SerializeField] HeroHeadBaseCell fullHeadCell;
    [SerializeField] Text name3;
    [SerializeField] Text[] fullAttrs;
    [SerializeField] GameObject fullImg;
    [SerializeField] Text titleText;
    protected override void InitComponent()
    {
        btn.AddListener(OnBtnClick);
    }
    protected override void OnPreOpen()
    {
        HeroUIManager.Instance.OnHeroCollectEvent += Display;
        Display();
    }
    protected override void OnPreClose()
    {
        HeroUIManager.Instance.OnHeroCollectEvent -= Display;
    }
    void Display()
    {
        var state = HeroUIManager.Instance.GetHeroBookState(HeroUIManager.Instance.selectCollectHeroID, HeroConfig.Get(HeroUIManager.Instance.selectCollectHeroID).Quality);
        var config = HeroConfig.Get(HeroUIManager.Instance.selectCollectHeroID);
        HB122_tagSCHeroInfo.tagSCHero colData;
        HeroUIManager.Instance.TryGetHeroBookInfo(HeroUIManager.Instance.selectCollectHeroID, out colData);
        var bookPer = HeroUIManager.Instance.GetHeroBookPer(HeroUIManager.Instance.selectCollectHeroID);
        if (state == 5)
        {
            //已满级
            titleText.text = Language.Get("HeroAwake13");
            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);
            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(true);
                btn.SetActive(false);
            }
        }
        else
        {
            fullPanel.SetActive(false);
            lvupPanel.SetActive(true);
            btn.SetActive(true);
            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;
            var qualityConfig = HeroQualityConfig.Get(config.Quality);
            awardInfo.text = string.Empty;
            unActiveGo.SetActive(false);
            titleText.text = Language.Get("HeroAwake12");
            int afterBreakLV = colData.BookBreakLV;
            int afterStarLV = colData.BookStarLV;
            if (state == 1)
            {
                //激活
                addPer = qualityConfig.BookInitAddPer;
                btnText.text = Language.Get("L1131");   //L1131    激活
                awardInfo.text = Language.Get("HeroAwake10", UIHelper.GetIconNameWithMoneyType(HeroUIManager.Instance.bookMoneyType),
                    HeroUIManager.Instance.bookMoneyValue);
                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
            {
                var nextHeroID = HeroUIManager.Instance.FindHeroIDCanAddCollectAttr(HeroUIManager.Instance.selectCollectHeroID);
                if (nextHeroID != 0)
                {
                    //下一个
                    btnText.text = Language.Get("HeroAwake14");
                }
                else
                {
                    btnText.text = Language.Get("L1109");
                }
            }
            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);
            }
        }
    }
    void OnBtnClick()
    {
        var state = HeroUIManager.Instance.GetHeroBookState(HeroUIManager.Instance.selectCollectHeroID, HeroConfig.Get(HeroUIManager.Instance.selectCollectHeroID).Quality);
        if (state == 1)
        {
            //激活
            SendPack(0);
        }
        else if (state == 3)
        {
            //突破
            SendPack(2);
        }
        else if (state == 4)
        {
            //升星
            SendPack(1);
        }
        else
        {
            var nextHeroID = HeroUIManager.Instance.FindHeroIDCanAddCollectAttr(HeroUIManager.Instance.selectCollectHeroID);
            if (nextHeroID != 0)
            {
                //下一个
                HeroUIManager.Instance.selectCollectHeroID = nextHeroID;
                Display();
            }
            else
            {
                SysNotifyMgr.Instance.ShowTip("HeroGift8");
            }
        }
    }
    void SendPack(int type)
    {
        var pack = new CB237_tagCSHeroBookUP();
        pack.BookType = (byte)type;
        pack.HeroID = (uint)HeroUIManager.Instance.selectCollectHeroID;
        GameNetSystem.Instance.SendInfo(pack);
    }
}
Main/System/HeroUI/HeroCollectionLvUpWin.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c8604af8282af244b8ed4d2943122bf6
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/HeroUI/HeroCollectionWin.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
@@ -8,20 +9,155 @@
/// </summary>
public class HeroCollectionWin : UIBase
{
    [SerializeField] Button heroPackBtn;
    [SerializeField] Text heroPackText;
    [SerializeField] ScrollerController heroListScroller;
    [SerializeField] List<Text> totalAttrList;
    [SerializeField] Button attrBtn;
    [SerializeField] HeroSelectBehaviour fiterManager;  //武将筛选
    SinglePack singlePack;
    protected override void InitComponent()
    {
        attrBtn.AddListener(() =>
        {
            SmallTipWin.worldPos = CameraManager.uiCamera.ScreenToWorldPoint(Input.mousePosition);
            SmallTipWin.showText = Language.Get("herocard6");
            UIManager.Instance.OpenWindow<SmallTipWin>();
        });
        heroPackBtn.AddListener(() =>
        {
            HeroUIManager.Instance.QueryUnLockHeroPack();
        });
    }
    protected override void OnPreOpen()
    {
        singlePack = PackManager.Instance.GetSinglePack(PackType.Hero);
        PackManager.Instance.gridRefreshEvent += GridRefreshEvent;
        PackManager.Instance.RefreshItemEvent += RefreshItemEvent;
        HeroUIManager.Instance.OnHeroCollectEvent += OnHeroCollectEvent;
        heroListScroller.OnRefreshCell += OnRefreshCell;
        HeroUIManager.Instance.selectHeroCollectListJob = 0;
        HeroUIManager.Instance.selectHeroCollectListCountry = 0;
        HeroUIManager.Instance.SortHeroCollectList();
        Display();
    }
    protected override void OnPreClose()
    {
        PackManager.Instance.gridRefreshEvent -= GridRefreshEvent;
        PackManager.Instance.RefreshItemEvent -= RefreshItemEvent;
        HeroUIManager.Instance.OnHeroCollectEvent -= OnHeroCollectEvent;
        heroListScroller.OnRefreshCell -= OnRefreshCell;
    }
    void Display()
    {
        fiterManager.Display(0, HeroUIManager.Instance.selectHeroCollectListJob, HeroUIManager.Instance.selectHeroCollectListCountry, SelectJobCountry);
        CreateScroller();
        RefreshTotalAttr();
        RefreshPackCount();
    }
    void RefreshItemEvent(PackType type, int index, int itemID)
    {
        if (type != PackType.Hero)
            return;
        RefreshPackCount();
    }
    void RefreshPackCount()
    {
        int count = singlePack.GetAllItems().Count;
        heroPackText.text = UIHelper.AppendColor(count >= singlePack.unlockedGridCount ? TextColType.Red : TextColType.NavyBrown,
                            string.Format("{0}/{1}", count, singlePack.unlockedGridCount));
    }
    void GridRefreshEvent(PackType type)
    {
        if (type != PackType.Hero)
            return;
        RefreshPackCount();
    }
    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)
    {
        HeroUIManager.Instance.selectHeroCollectListJob = job;
        HeroUIManager.Instance.selectHeroCollectListCountry = country;
        HeroUIManager.Instance.SortHeroCollectList();
        CreateScroller();
    }
    void CreateScroller()
    {
        heroListScroller.Refresh();
        var _List = HeroUIManager.Instance.heroCollectDict.Keys.ToList();
        _List.Reverse();
        for (int i = 0; i < _List.Count; i++)
        {
            var ids = HeroUIManager.Instance.heroCollectDict[_List[i]];
            if (ids.Count == 0)
                continue;
            //品质
            heroListScroller.AddCell(ScrollerDataType.Header, _List[i]);
            //武将
            for (int j = 0; j < ids.Count; j++)
            {
                if (j % 4 == 0)
                {
                    CellInfo cellInfo = new CellInfo();
                    cellInfo.infoInt1 = _List[i];
                    heroListScroller.AddCell(ScrollerDataType.Normal, j, cellInfo);
                }
            }
        }
        heroListScroller.Restart();
    }
    void OnRefreshCell(ScrollerDataType type, CellView cell)
    {
        if (type == ScrollerDataType.Header)
        {
            var _cell = cell.GetComponent<Image>();
            _cell.SetSprite("herocoltitle" + cell.index);
        }
        else if (type == ScrollerDataType.Normal)
        {
            var _cell = cell as HeroCollectionLineCell;
            _cell?.Display(cell.index, cell.info.Value.infoInt1);
        }
    }
    void OnHeroCollectEvent()
    {
        RefreshTotalAttr();
        heroListScroller.m_Scorller.RefreshActiveCellViews();
    }
}
Main/System/HeroUI/HeroTrainWin.cs
@@ -164,7 +164,7 @@
        PackManager.Instance.RefreshItemLockEvent += RefreshItemLockEvent;
        HeroManager.Instance.onHeroChangeEvent += RefreshHeroEvent;
        UIManager.Instance.OnCloseWindow += OnCloseWindow;
        HeroUIManager.Instance.OnTeamPosChangeEvent += TeamPosChangeEvent;
        TeamManager.Instance.OnTeamChange += TeamPosChangeEvent;
        guid = HeroUIManager.Instance.selectHeroGuid;
        hero = HeroManager.Instance.GetHero(guid);
        unfoldState = false;
@@ -178,7 +178,7 @@
        PackManager.Instance.RefreshItemLockEvent -= RefreshItemLockEvent;
        HeroManager.Instance.onHeroChangeEvent -= RefreshHeroEvent;
        UIManager.Instance.OnCloseWindow -= OnCloseWindow;
        HeroUIManager.Instance.OnTeamPosChangeEvent -= TeamPosChangeEvent;
        TeamManager.Instance.OnTeamChange -= TeamPosChangeEvent;
    }
    private void OnCloseWindow(UIBase closeUI)
@@ -726,8 +726,10 @@
        }
    }
    void TeamPosChangeEvent(List<int> posList, int flyFrom, Vector3 startPos)
    {
    void TeamPosChangeEvent(TeamType teamType)
    {
        if (teamType != TeamType.Story)
            return;
        fightPowerText.text = UIHelper.ReplaceLargeArtNum(hero.CalculatePower());
    }
}
Main/System/HeroUI/HeroUIManager.Collect.cs
@@ -1,18 +1,28 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
//图鉴和皮肤
public partial class HeroUIManager : GameSystemManager<HeroUIManager>
{
    #region 图鉴和皮肤
    public Dictionary<int, List<int>> heroCollectDict { get; private set; } = new Dictionary<int, List<int>>();  //武将图鉴按品质列表
    public int selectHeroCollectListJob = 0;    //武将列表界面 筛选职业
    public int selectHeroCollectListCountry = 0;    //武将列表界面筛选国家
    public int selectCollectHeroID; //选中的武将id
    public int bookMoneyType; //图鉴奖励货币类型
    public int bookMoneyValue;//图鉴奖励货币数量
    //图鉴和皮肤的激活情况
    public Dictionary<int, HB122_tagSCHeroInfo.tagSCHero> heroCollectInfoDic { get; private set; } = new Dictionary<int, HB122_tagSCHeroInfo.tagSCHero>();
    Dictionary<int, HB122_tagSCHeroInfo.tagSCHero> heroCollectInfoDic = new Dictionary<int, HB122_tagSCHeroInfo.tagSCHero>();
    public int bookPer;
    public int allHeroBookPer; //全体武将的图鉴激活百分比
    public event Action OnHeroCollectEvent;
    public void UpdateHeroCollectInfo(HB122_tagSCHeroInfo netPack)
@@ -21,7 +31,7 @@
        {
            heroCollectInfoDic[(int)netPack.HeroInfoList[i].HeroID] = netPack.HeroInfoList[i];
        }
        bookPer = GetHeroCollectBookPer();
        allHeroBookPer = GetHeroCollectBookPer();
        OnHeroCollectEvent?.Invoke();
    }
@@ -41,15 +51,130 @@
        return per;
    }
    public HB122_tagSCHeroInfo.tagSCHero GetHeroBookInfo(int heroID)
    {
    public bool TryGetHeroBookInfo(int heroID, out HB122_tagSCHeroInfo.tagSCHero heroData)
    {
        if (heroCollectInfoDic.ContainsKey(heroID))
        {
            return heroCollectInfoDic[heroID];
            heroData = heroCollectInfoDic[heroID];
            return true;
        }
        return null;
        heroData = new HB122_tagSCHeroInfo.tagSCHero();
        return false;
    }
    #endregion
    public void SortHeroCollectList()
    {
        var heroIDs = HeroConfig.GetKeys().ToList();
        heroCollectDict.Clear();
        foreach (var heroID in heroIDs)
        {
            HeroConfig heroConfig = HeroConfig.Get(heroID);
            if (!heroCollectDict.ContainsKey(heroConfig.Quality))
            {
                heroCollectDict[heroConfig.Quality] = new List<int>();
            }
            //过滤职业国家
            if (selectHeroCollectListJob != 0 && selectHeroCollectListJob != heroConfig.Class)
            {
                continue;
            }
            if (selectHeroCollectListCountry != 0 && selectHeroCollectListCountry != heroConfig.Country)
            {
                continue;
            }
            heroCollectDict[heroConfig.Quality].Add(heroID);
        }
    }
    //图鉴总上限等级 = 图鉴星级上限 + 图鉴突破上限
    public int GetHeroBookMaxLevel(int heroID, int quality)
    {
        return GetMaxStarCount(heroID, quality) + HeroBreakConfig.GetMaxBreakLv(heroID);
    }
    public int GetHeroBookLevel(int heroID)
    {
        if (heroCollectInfoDic.ContainsKey(heroID))
        {
            return heroCollectInfoDic[heroID].BookStarLV + heroCollectInfoDic[heroID].BookBreakLV;
        }
        return 0;
    }
    //分为0未获得、1可激活、2常规、3突破升级、4、星升级、5已满级
    public int GetHeroBookState(int heroID, int quality)
    {
        int funcState = 0;
        HB122_tagSCHeroInfo.tagSCHero colData;
        TryGetHeroBookInfo(heroID, out colData);
        int maxBreakLV = colData.BookBreakLVH; //历史最高突破等级
        int maxStarLV = colData.BookStarLVH;  //历史最高星级
        if (colData.BookInitState == 0)
        {
            funcState = 0;
        }
        else if (colData.BookInitState == 1)
        {
            funcState = 1;
        }
        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;
    }
    //找到可以操作的图鉴武将
    public int FindHeroIDCanAddCollectAttr(int excludeHeroID = 0)
    {
        foreach (var kv in heroCollectInfoDic)
        {
            if (kv.Key == excludeHeroID)
                continue;
            var state = GetHeroBookState(kv.Key, HeroConfig.Get(kv.Key).Quality);
            if (state == 1 || state == 3 || state == 4)
            {
                return kv.Key;
            }
        }
        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;
    }
}
Main/System/HeroUI/HeroUIManager.Talent.cs
@@ -167,7 +167,7 @@
                else
                {
                    int index = i;
                    giftBaseCells[i].Init(-1, 0, null, hero.heroId, index);
                    giftBaseCells[i].Init(-1, 0, null, 0, hero.heroId, index);
                }
            }
Main/System/HeroUI/HeroUIManager.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using LitJson;
using UnityEngine;
@@ -39,6 +40,11 @@
        payBackMoneyType = int.Parse(config.Numerical1);
        rebornAwakeHeroMaxCount = int.Parse(config.Numerical2);
        ParseGiftConfig();
        config = FuncConfigConfig.Get("HeroBook");
        var arr = JsonMapper.ToObject<int[]>(config.Numerical1);
        bookMoneyType = arr[0];
        bookMoneyValue = arr[1];
    }
    public void OnBeforePlayerDataInitialize()
@@ -235,8 +241,8 @@
    public bool IsNewHero(int heroID)
    {
        var bookInfo = GetHeroBookInfo(heroID);
        if (bookInfo != null)
        HB122_tagSCHeroInfo.tagSCHero bookInfo;
        if (TryGetHeroBookInfo(heroID, out bookInfo))
        {
            if (bookInfo.BookInitState < 2)
            {
Main/System/Main/FightPowerManager.cs
@@ -261,7 +261,7 @@
        {
            return 0;
        }
        return HeroUIManager.Instance.bookPer;
        return HeroUIManager.Instance.allHeroBookPer;
    }
    int GetCountryPer(int attrType)
@@ -348,11 +348,11 @@
            }
            if (config.showType == 1)
            {
                fightPowerVariables[config.Parameter] = (ulong)GetPropertyVaule(config.ID, hero, propertyFormula);
                fightPowerVariables[config.Parameter] = GetPropertyVaule(config.ID, hero, propertyFormula);
            }
            else
            {
                fightPowerVariables[config.Parameter] = (ulong)GetPropertyVaule(config.ID, hero, fightPropertyFormula);
                fightPowerVariables[config.Parameter] = GetPropertyVaule(config.ID, hero, fightPropertyFormula);
            }
        }
Main/System/Redpoint/MainRedDot.cs
@@ -24,7 +24,9 @@
    //武将卡
    public const int HeroCardRedpoint = 200;
    public Redpoint HeroCardRedpoint1 = new Redpoint(MainHerosRedpoint, HeroCardRedpoint);
    public Redpoint HeroListRedpoint = new Redpoint(MainHerosRedpoint, HeroCardRedpoint);
    public const int HeroCardCollectRedpoint = 201;
    public Redpoint HeroCollectRedpoint = new Redpoint(MainHerosRedpoint, HeroCardCollectRedpoint);
    #region 邮件红点
Main/Utility/UIHelper.cs
@@ -88,7 +88,7 @@
        }
        else
        {
            Debug.LogError("MoneyDisplayModel 为配置货币类型:" + moneyType);
            Debug.LogError("MoneyDisplayModel 未配置货币类型:" + moneyType);
            return "";
        }
    }