hch
2025-09-06 9216ab7322fa164abaa6f9089058746b34bd690a
117 【武将】武将系统 - 洗炼
1个文件已删除
10个文件已修改
1 文件已复制
2个文件已添加
1 文件已重命名
482 ■■■■■ 已修改文件
Main/Component/UI/Effect/UISpineEffect.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Main.cs 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Hero/HeroInfo.Talent.cs 58 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroGiftEatWin.cs 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroGiftRoleListCell.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroGiftWashCell.cs 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroGiftWashCell.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroGiftWashWin.cs 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroGiftWashWin.cs.meta 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroTrainWin.cs 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroUIManager.Talent.cs 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroUIManager.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ItemTip/ItemTipUtility.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/KnapSack/Logic/ItemModel.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Tip/ConfirmCancel.cs 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Effect/UISpineEffect.cs
File was deleted
Main/Main.cs
@@ -38,8 +38,8 @@
#endif
        StageManager.Instance.ToLoginScene();
        DTC0403_tagPlayerLoginLoadOK.finishedLogin = false;
        DTC0102_tagCDBPlayer.isAfterPlayerDataInitialize = false;
        ClearGameData();
    }
    public static async UniTask InitManagers()
@@ -123,8 +123,14 @@
    /// </summary>
    private static void OpenLoginUI()
    {
    }
    //这里清理时机一定是重新登录/切换账号,而不是短暂的断线重连
    static void ClearGameData()
    {
        DTC0403_tagPlayerLoginLoadOK.finishedLogin = false;
        DTC0102_tagCDBPlayer.isAfterPlayerDataInitialize = false;
        ConfirmCancel.toggleCheckDict.Clear();
    }
}
Main/System/Hero/HeroInfo.Talent.cs
@@ -16,16 +16,14 @@
        }
    }
    // 75 # 英雄天赋洗炼锁定索引列表,对应71天赋ID索引
    // 77 # 英雄天赋洗炼随机ID列表
    // 79 # 英雄觉醒时随机天赋选项ID列表
    // 71 # 英雄天赋ID列表
    public List<int> talentIDList
    {
        get
        {
            if (itemHero == null)
                return null;
                return new List<int>();
            return itemHero.GetUseData(71);
        }
    }
@@ -36,22 +34,37 @@
        get
        {
            if (itemHero == null)
                return null;
                return new List<int>();
            return itemHero.GetUseData(73);
        }
    }
    // 75 # 英雄天赋洗炼锁定索引列表,对应71天赋ID索引
    public List<int> talentLockList
    // 洗炼锁定客户端缓存为准,重登会清除,如果需要重登显示锁定则再处理
    // 存储的是索引不是 是否锁定
    public List<int> talentLockList = new List<int>();
    // 77 # 英雄天赋洗炼随机ID列表
    public List<int> talentRandomIDList
    {
        get
        {
            if (itemHero == null)
                return null;
            return itemHero.GetUseData(75);
                return new List<int>();
            return itemHero.GetUseData(77);
        }
    }
    // 79 # 英雄觉醒时随机天赋选项ID列表
    public List<int> talentAwakeRandomIDList
    {
        get
        {
            if (itemHero == null)
                return new List<int>();
            return itemHero.GetUseData(79);
        }
    }
    Dictionary<int, int> talentAttrDic = new Dictionary<int, int>();   //属性ID : 天赋属性值
@@ -125,8 +138,33 @@
    public int GetTalentLockCount()
    {
        //talentLockList里的元素全部相加 1代表锁定 0代表未锁定
        return talentLockList.Sum();
        return talentLockList.Count;
    }
    //设置是否锁定,只存储锁定的索引
    public void SetTalentLockState(int lockIndex, int state)
    {
        var index = talentLockList.IndexOf(lockIndex);
        if (state == 1)
        {
            if (index < 0)
            {
                talentLockList.Add(lockIndex);
            }
            return;
        }
        if (state == 0)
        {
            if (index >= 0)
            {
                talentLockList.RemoveAt(index);
            }
            return;
        }
    }
}
Main/System/HeroUI/HeroGiftEatWin.cs
@@ -91,7 +91,21 @@
            SysNotifyMgr.Instance.ShowTip("HeroGift3");
            return;
        }
        var hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectHeroGuidForGiftFunc);
        //洗炼和觉醒的天赋未处理不可吞噬
        if (hero.talentRandomIDList.Count > 0 )
        {
            SysNotifyMgr.Instance.ShowTip("HeroGift4");
            return;
        }
        if (hero.talentAwakeRandomIDList.Count > 0)
        {
            SysNotifyMgr.Instance.ShowTip("HeroGift5");
            return;
        }
        var eatHero = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectEatHeroGuid);
        if (hero == null || eatHero == null)
            return;
@@ -104,6 +118,7 @@
        HeroUIManager.Instance.selectHeroGuidForGiftFuncForSuccessWin = HeroUIManager.Instance.selectHeroGuidForGiftFunc;
        HeroUIManager.Instance.heroBeforeGiftIDList = new List<int>(hero.talentIDList);
        HeroUIManager.Instance.heroBeforeGiftLevelList = new List<int>(hero.talentLvList);
        HeroUIManager.Instance.lastFightPower = new KeyValuePair<string, long>(hero.itemHero.guid, hero.CalculatePower(false));
        //设置个等待回复的标识 显示成功界面
        HeroUIManager.Instance.waitResponse = new WaitHeroFuncResponse()
Main/System/HeroUI/HeroGiftRoleListCell.cs
@@ -24,7 +24,7 @@
    {
        var hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.heroEatList[index]);
        //上阵 锁定 觉醒 的情况
        if (hero.awakeLevel > 0)
        if (hero.awakeLevel > 0 || hero.breakLevel > 0)
        {
            SysNotifyMgr.Instance.ShowTip("HeroReborn1");
            return;
Main/System/HeroUI/HeroGiftWashCell.cs
New file
@@ -0,0 +1,78 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 武将洗炼当前的天赋
/// </summary>
public class HeroGiftWashCell : MonoBehaviour
{
    [SerializeField] GiftBaseCell giftCell;
    [SerializeField] Button lockBtn;
    [SerializeField] Image lockImg;
    [SerializeField] UIEffectPlayer effectPlayer;
    public void Display(HeroInfo hero, int index)
    {
        int giftID = hero.talentIDList[index];
        int giftLV = hero.talentLvList[index];
        giftCell.Init(giftID, giftLV);
        if (hero.talentLockList.IndexOf(index) != -1)
        {
            lockImg.SetSprite("lockImage");
        }
        else
        {
            lockImg.SetSprite("unlockImage");
        }
        lockBtn.AddListener(() =>
        {
            var hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectWashHeroGUID);
            if (hero == null)
            {
                return;
            }
            //没有发锁定包,客户端自己保存
            var state = hero.talentLockList.IndexOf(index) == -1 ? 0 : 1;
            if (state == 0 && hero.GetTalentLockCount() >= hero.talentIDList.Count - 1)
            {
                //至少要保留一个天赋未锁定
                SysNotifyMgr.Instance.ShowTip("HeroGift6");
                return;
            }
            hero.SetTalentLockState(index, state == 1 ? 0 : 1);
            if (hero.talentLockList.IndexOf(index) != -1)
            {
                lockImg.SetSprite("lockImage");
            }
            else
            {
                lockImg.SetSprite("unlockImage");
            }
            HeroUIManager.Instance.changeLockEvent?.Invoke();
        });
    }
    public void ShowEffect(HeroInfo hero, int index)
    {
        if (hero.talentLockList.IndexOf(index) != -1)
        {
            return;
        }
        effectPlayer.Play(true, true);
    }
}
Main/System/HeroUI/HeroGiftWashCell.cs.meta
File was renamed from Main/Component/UI/Effect/UISpineEffect.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: fdbe400d15c065042a16a05cd09dd322
guid: e4bda7ee080f4a04fb1c9fd7b6c1d399
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/HeroUI/HeroGiftWashWin.cs
New file
@@ -0,0 +1,235 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 武将洗炼界面
/// </summary>
public class HeroGiftWashWin : UIBase
{
    [SerializeField] HeroShowBaseCell heroShow;
    [SerializeField] GameObject currentGo;
    [SerializeField] GameObject changeGo;
    [SerializeField] HeroGiftWashCell[] currentGiftCells;
    [SerializeField] Button washBtn;
    [SerializeField] Image itemIcon;
    [SerializeField] Text itemCountText;
    [SerializeField] GiftBaseCell[] beforeGiftCells;
    [SerializeField] GiftBaseCell[] afterGiftCells;
    [SerializeField] Button cancelBtn;
    [SerializeField] Button saveBtn;
    HeroInfo hero;
    protected override void InitComponent()
    {
        washBtn.AddListener(WashGift);
        cancelBtn.AddListener(CancelWash);
        saveBtn.AddListener(SaveWash);
        btnClickEmptyCloseEvent = OnCloseWin;
    }
    protected override void OnPreOpen()
    {
        hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectWashHeroGUID);
        if (hero == null)
        {
            return;
        }
        HeroManager.Instance.onHeroChangeEvent += OnHeroChangeEvent;
        HeroUIManager.Instance.changeLockEvent += ChangeLockEvent;
        Display();
    }
    protected override void OnPreClose()
    {
        hero = null;
        HeroManager.Instance.onHeroChangeEvent -= OnHeroChangeEvent;
        HeroUIManager.Instance.changeLockEvent -= ChangeLockEvent;
    }
    void OnHeroChangeEvent(HeroInfo hero)
    {
        if (hero.itemHero.guid != HeroUIManager.Instance.selectWashHeroGUID)
        {
            return;
        }
        Display();
    }
    public void Display()
    {
        heroShow.Init(hero.heroId, hero.SkinID, hero.breakLevel, hero.heroStar, hero.awakeLevel, hero.heroLevel);
        if (hero.talentRandomIDList.Count == 0)
        {
            currentGo.SetActive(true);
            changeGo.SetActive(false);
            for (int i = 0; i < currentGiftCells.Length; i++)
            {
                if (i < hero.talentIDList.Count)
                {
                    currentGiftCells[i].SetActive(true);
                    currentGiftCells[i].Display(hero, i);
                }
                else
                {
                    currentGiftCells[i].SetActive(false);
                }
            }
            itemIcon.SetItemSprite(HeroUIManager.Instance.washItemID);
            int useCount = HeroUIManager.Instance.GetTalentLockUseWashCount(hero);
            var itemCount = PackManager.Instance.GetItemCountByID(PackType.Item, HeroUIManager.Instance.washItemID);
            itemCountText.text = UIHelper.AppendColor(itemCount >= useCount ? TextColType.Green : TextColType.Red,
                itemCount + "/" + useCount);
        }
        else
        {
            currentGo.SetActive(false);
            changeGo.SetActive(true);
            HeroUIManager.Instance.RefreshGiftCell(beforeGiftCells, hero);  //当前天赋
            ShowChangeGift(hero);   //随机未保存的天赋
        }
    }
    void WashGift()
    {
        var hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectWashHeroGUID);
        if (hero == null)
        {
            return;
        }
        //根据锁状态判断材料是否足够
        if (!ItemLogicUtility.CheckItemCount(PackType.Item, HeroUIManager.Instance.washItemID,
        HeroUIManager.Instance.GetTalentLockUseWashCount(hero), 2))
        {
            return;
        }
        for (int i = 0; i < currentGiftCells.Length; i++)
        {
            if (i < hero.talentIDList.Count)
            {
                currentGiftCells[i].ShowEffect(hero, i);
            }
        }
        closeTime = Time.time;
        //做特效表现
        SendPack().Forget();
    }
    float closeTime;
    async UniTask SendPack()
    {
        //延迟0.5秒发包
        await UniTask.Delay(500);
        var hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectWashHeroGUID);
        if (hero == null)
        {
            return;
        }
        HeroUIManager.Instance.SendWash(hero, 0);
    }
    void ShowChangeGift(HeroInfo hero)
    {
        for (int i = 0; i < afterGiftCells.Length; i++)
        {
            if (i >= hero.talentRandomIDList.Count)
            {
                afterGiftCells[i].SetActive(false);
                continue;
            }
            afterGiftCells[i].SetActive(true);
            afterGiftCells[i].Init(hero.talentRandomIDList[i], hero.talentLvList[i]);
            //对比变化的天赋显示特效
            if (hero.talentRandomIDList[i] != hero.talentIDList[i])
            {
                afterGiftCells[i].GetComponentInChildren<UIEffectPlayer>().Play();
            }
            else
            {
                afterGiftCells[i].GetComponentInChildren<UIEffectPlayer>().Stop();
            }
        }
    }
    void CancelWash()
    {
        //取消洗炼
        ConfirmCancel.ToggleConfirmCancelByType(ToggleCheckType.WashCancel, Language.Get("HeroGift20"), () =>
        {
            var hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectWashHeroGUID);
            if (hero == null)
            {
                return;
            }
            HeroUIManager.Instance.SendWash(hero, 2);
        });
    }
    void SaveWash()
    {
        var hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectWashHeroGUID);
        if (hero == null)
        {
            return;
        }
        HeroUIManager.Instance.SendWash(hero, 1);
    }
    void OnCloseWin()
    {
        if (Time.time - closeTime < 1f)
        {
            return;
        }
        //洗炼结果未处理
        var hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectWashHeroGUID);
        if (hero == null)
        {
            return;
        }
        if (hero.talentRandomIDList.Count > 0)
        {
            return;
        }
        else
        {
            CloseWindow();
        }
    }
    void ChangeLockEvent()
    {
        int useCount = HeroUIManager.Instance.GetTalentLockUseWashCount(hero);
        var itemCount = PackManager.Instance.GetItemCountByID(PackType.Item, HeroUIManager.Instance.washItemID);
        itemCountText.text = UIHelper.AppendColor(itemCount >= useCount ? TextColType.Green : TextColType.Red,
            itemCount + "/" + useCount);
    }
}
Main/System/HeroUI/HeroGiftWashWin.cs.meta
copy from Main/Component/UI/Effect/UISpineEffect.cs.meta copy to Main/System/HeroUI/HeroGiftWashWin.cs.meta
File was copied from Main/Component/UI/Effect/UISpineEffect.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: fdbe400d15c065042a16a05cd09dd322
guid: e98a167ec42aa6541b0854a73c6c727b
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
Main/System/HeroUI/HeroTrainWin.cs
@@ -622,17 +622,12 @@
        }
        else if (hero.IsFullStar())
        {
            starUPBtn.interactable = true;
            starUPBtn.SetColorful(null, false);
            starUPBtnText.text = Language.Get("HeroGift3");
            SysNotifyMgr.Instance.ShowTip("HeroGift1");
            return;
        }
        else
        {
            starUPBtn.interactable = true;
            starUPBtn.SetColorful(null, true);
            HeroUIManager.Instance.selectHeroGuidForGiftFunc = hero.itemHero.guid;
            UIManager.Instance.OpenWindow<HeroGiftEatWin>();
        }
    }
    void Wash()
@@ -642,15 +637,9 @@
            SysNotifyMgr.Instance.ShowTip("HeroGift2", HeroUIManager.Instance.canWashStarLevel);
            return;
        }
        // //根据锁状态判断材料是否足够
        // if (!ItemLogicUtility.CheckItemCount(PackType.Item, HeroUIManager.Instance.washItemID,
        // HeroUIManager.Instance.GetTalentLockUseWashCount(hero), 2))
        // {
        //     return;
        // }
        // UIManager.Instance.OpenWindow<HeroGiftWashWin>();
        HeroUIManager.Instance.selectWashHeroGUID = hero.itemHero.guid;
        UIManager.Instance.OpenWindow<HeroGiftWashWin>();
    }
}
Main/System/HeroUI/HeroUIManager.Talent.cs
@@ -38,7 +38,11 @@
        }
    }
    #region 洗炼
    public string selectWashHeroGUID; //被洗练武将GUID
    public Action changeLockEvent;
    #endregion
    public List<string> heroEatList = new List<string>();
@@ -60,7 +64,13 @@
    //根据天赋锁状态获取消耗的材料数量
    public int GetTalentLockUseWashCount(HeroInfo hero)
    {
        return washByLockUseCounts[hero.GetTalentLockCount()];
        int heroTalentLockCount = hero.GetTalentLockCount();
        //不够取最后一个
        if (heroTalentLockCount >= washByLockUseCounts.Length)
        {
            heroTalentLockCount = washByLockUseCounts.Length - 1;
        }
        return washByLockUseCounts[heroTalentLockCount];
    }
@@ -205,5 +215,24 @@
            }
        }
    }
    // public ushort ItemIndex;    //武将物品所在武将背包位置索引
    // public byte LockCnt;
    // public  byte[] LockTalentIndexs;    //锁定天赋索引列表
    // public byte OPType;    // 操作类型:0-执行洗炼;1-替换原天赋;2-保留原天赋
    public void SendWash(HeroInfo hero, byte opType)
    {
        var pack = new CB235_tagCSHeroWash();
        pack.ItemIndex = (ushort)hero.itemHero.gridIndex;
        pack.LockCnt = (byte)hero.talentLockList.Count;
        pack.LockTalentIndexs = new byte[pack.LockCnt];
        for (int i = 0; i < pack.LockCnt; i++)
        {
            pack.LockTalentIndexs[i] = (byte)hero.talentLockList[i];
        }
        pack.OPType = opType;
        GameNetSystem.Instance.SendInfo(pack);
    }
}
Main/System/HeroUI/HeroUIManager.cs
@@ -17,6 +17,7 @@
    public WaitHeroFuncResponse waitResponse;    //请求武将功能,与服务端交互
    //用于非上阵武将战力变化时 武将ID:上次战力
    //使用方法:其他功能界面设置该值即可
    public KeyValuePair<string, long> lastFightPower = new KeyValuePair<string, long>(); 
    public override void Init()
Main/System/ItemTip/ItemTipUtility.cs
@@ -237,6 +237,7 @@
    }
    //showGetWay 是否获取途径界面
    public static void Show(int itemId, bool showGetWay = false)
    {
        if (!ItemConfig.HasKey(itemId))
Main/System/KnapSack/Logic/ItemModel.cs
@@ -121,7 +121,7 @@
            useDataDict.TryGetValue(key, out list);
        }
        return list;
        return list == null ? new List<int>() : list;
    }
    public int GetUseDataFirstValue(int key)
Main/System/Tip/ConfirmCancel.cs
@@ -192,13 +192,10 @@
    }
    //本次登陆不再提示, toggle的确认类型,方便外部调用
    static Dictionary<int, bool> toggleCheckDict = new Dictionary<int, bool>();
    public enum ToggleCheckType
    {
        Auction = 0, //拍卖行
    }
    public static Dictionary<ToggleCheckType, bool> toggleCheckDict = new Dictionary<ToggleCheckType, bool>();
    public static void ToggleConfirmCancelByType(int type, string fullTip, Action func)
    public static void ToggleConfirmCancelByType(ToggleCheckType type, string fullTip, Action func)
    {
        if (toggleCheckDict.ContainsKey(type) && toggleCheckDict[type])
        {
@@ -323,4 +320,10 @@
}
public enum ToggleCheckType
{
    Auction = 0, //拍卖行
    WashCancel = 1, //洗练取消
}