From 3bd7f56906e31e8fe0072108c9d4652707b51de8 Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期二, 21 十月 2025 17:59:00 +0800
Subject: [PATCH] 125 战斗 战斗UI

---
 Main/System/Battle/UIComp/BossHeadCell.cs              |   21 ++
 Main/Component/UI/Common/BossLifeBar.cs                |   67 ++++--
 Main/System/Battle/UIComp/BattleBuffCell.cs            |  117 ++++++++++
 Main/System/Battle/UIComp/TotalDamageDisplayer.cs      |   78 +++++++
 Main/System/Battle/BattleField/StoryBossBattleField.cs |   49 +++-
 Main/System/MainLevel/MainBossEnterWin.cs              |    1 
 Main/ResModule/ResManager.cs                           |    6 
 Main/System/Battle/Buff/BattleObjectBuffMgr.cs         |   16 +
 Main/System/Battle/Define/BattleDmgInfo.cs             |    5 
 Main/System/Battle/BattleField/BattleField.cs          |    7 
 /dev/null                                              |   11 -
 Main/Utility/ComponentExtersion.cs                     |    1 
 Main/System/Battle/StoryBossBattleWin.cs               |  127 ++++++++++++
 Main/System/Battle/BattleObject/BattleObject.cs        |    9 
 Main/System/Battle/UIComp/BattleHeroInfoBar.cs         |   41 +--
 15 files changed, 457 insertions(+), 99 deletions(-)

diff --git a/Main/Component/UI/Common/BossLifeBar.cs b/Main/Component/UI/Common/BossLifeBar.cs
index 7634fcd..ebe96d3 100644
--- a/Main/Component/UI/Common/BossLifeBar.cs
+++ b/Main/Component/UI/Common/BossLifeBar.cs
@@ -44,8 +44,10 @@
         set {
             m_CurrentBehaviourValue = value;
             UpdateSurplusSegments(currentBehaviourValue);
-            var behaviourDecimalValue = m_CurrentBehaviourValue - (int)m_CurrentBehaviourValue;
-            var trueDecimalValue = targetValue - (int)targetValue;
+
+            float behaviourDecimalValue = GetSegmentDecimal(m_CurrentBehaviourValue);
+            float trueDecimalValue = GetSegmentDecimal(targetValue);
+
             switch (pattern)
             {
                 case Pattern.Add:
@@ -54,7 +56,7 @@
                     break;
                 case Pattern.Reduce:
                     m_SliderMiddleground.value = behaviourDecimalValue;
-                    m_SliderForeground.value = behaviourDecimalValue < trueDecimalValue ? 0 : trueDecimalValue;
+                    m_SliderForeground.value = behaviourDecimalValue < trueDecimalValue ? 0f : trueDecimalValue;
                     break;
                 case Pattern.None:
                     m_SliderMiddleground.value = behaviourDecimalValue;
@@ -64,24 +66,29 @@
         }
     }
 
-    public void SetBaseInfo(int _npcId, ulong _hp, ulong _maxHp, int _level)
+    public void SetBaseInfo(int _lifeBarCount, ulong _hp, ulong _maxHp)
     {
-        var npcConfig = NPCConfig.Get(_npcId);
-        HeroSkinConfig skinConfig = HeroSkinConfig.Get(npcConfig.SkinID);
-
         surplusSegments = -1;
-        totalSegments = npcConfig.LifeBarCount;
-        targetValue = currentBehaviourValue = ((float)_hp / _maxHp) * totalSegments - 0.0001f;
-        var behaviourDecimalValue = currentBehaviourValue - (int)currentBehaviourValue;
+        totalSegments = _lifeBarCount;
+
+        // 浣跨敤绮剧‘鍊硷紝涓嶅啀浜轰负鍑忓皬
+        float percentage = (_maxHp > 0) ? (float)_hp / (float)_maxHp : 0f;
+        targetValue = currentBehaviourValue = percentage * totalSegments;
+
+        // 浣跨敤缁熶竴鐨� GetSegmentDecimal锛岄伩鍏嶅皬鏁扮簿搴﹀鑷磋繘搴︽潯涓�0
+        var behaviourDecimalValue = GetSegmentDecimal(currentBehaviourValue);
         m_SliderForeground.value = m_SliderMiddleground.value = behaviourDecimalValue;
 
         refValue = 0f;
+
+        // 绔嬪埢鏄剧ず鍩哄噯鐧惧垎姣旓紙浣跨敤 percentage锛�
+        m_SurplusPercent.text = (percentage * 100f).ToString("F2") + "%";
     }
 
     public void Show(ulong _hp, ulong _maxHp)
     {
         var percentage = Mathf.Clamp(_hp, 0, _maxHp) / (float)_maxHp;
-        var tempValue = totalSegments * percentage - 0.00001f;
+        var tempValue = totalSegments * percentage; // 涓嶅啀鍑忓皬
         pattern = tempValue > targetValue ? Pattern.Add : tempValue < targetValue ? Pattern.Reduce : Pattern.None;
 
         behaviourStartValue = currentBehaviourValue;
@@ -89,6 +96,9 @@
 
         timer = 0f;
         refValue = 0f;
+
+        // 绔嬪嵆鏇存柊鐧惧垎姣旀樉绀猴紙鐩存帴浣跨敤 percentage锛�
+        m_SurplusPercent.text = (percentage * 100f).ToString("F2") + "%";
     }
 
     private void LateUpdate()
@@ -117,19 +127,11 @@
 
             m_BackGround.SetActive(surplusSegments > 1);
 
-            // var chars = surplusSegments.ToString();
-            // stringBuild.Remove(0, stringBuild.Length);
-            // for (var i = 0; i < chars.Length; i++)
-            // {
-            //     var numChar = GetNumKey(chars[i]);
-            //     if (numChar > 0)
-            //     {
-            //         stringBuild.Append((char)numChar);
-            //     }
-            // }
-
-            m_Surplus.text = surplusSegments.ToString();
-            m_SurplusPercent.text = Mathf.CeilToInt((_targetValue / totalSegments) * 100f).ToString() + "%";
+            m_Surplus.text = "x" + surplusSegments.ToString();
+            float pct = totalSegments > 0 ? Mathf.Clamp01(_targetValue / totalSegments) : 0f;
+            // 淇鏍煎紡骞跺鐞嗘帴杩� 100% 鐨勬儏鍐�
+            if (1f - pct < 0.00005f) pct = 1f;
+            m_SurplusPercent.text = (pct * 100f).ToString("F2") + "%";
         }
     }
 
@@ -147,6 +149,23 @@
         Reduce,
     }
 
+    // helper: 杩斿洖娈靛唴灏忔暟閮ㄥ垎锛涘綋鎭板ソ涓烘暣鏁颁笖澶т簬0鏃讹紝杩斿洖1浠ヨ〃绀烘弧鏍硷紙閬垮厤0瀵艰嚧杩涘害鏉″彉绌猴級
+    private float GetSegmentDecimal(float value)
+    {
+        if (value <= 0f) return 0f;
+
+        // 浣跨敤涓�涓皬鐨勫蹇嶅�兼潵澶勭悊娴偣璇樊锛岄伩鍏� near-integer 瀵艰嚧 0
+        const float eps = 1e-5f;
+
+        // 鍏堝仛涓�涓悜涓嬬ǔ瀹氱殑 floor锛岄伩鍏� 2.999999 鍙樻垚 2 鐨勯棶棰�
+        float stableFloor = Mathf.Floor(value + eps);
+        float frac = value - stableFloor;
+
+        if (frac <= eps)
+            return 1f; // 瑙嗕负鏁存锛屾樉绀烘弧鏍�
+        return Mathf.Clamp01(frac);
+    }
+
 }
 
 
diff --git a/Main/ResModule/ResManager.cs b/Main/ResModule/ResManager.cs
index 7445d6b..27e2bac 100644
--- a/Main/ResModule/ResManager.cs
+++ b/Main/ResModule/ResManager.cs
@@ -216,8 +216,12 @@
     private Sprite LoadSprite(string atlasName, string spriteName)
     {
         if (!AssetSource.isUseAssetBundle)
-        { 
+        {
             SpriteAtlas atlas = LoadAsset<SpriteAtlas>("Sprite", atlasName.Replace("Sprite/", ""));
+            if (null == atlas)
+            {
+                return null;
+            }
             return atlas.GetSprite(spriteName);
         }
         else
diff --git a/Main/System/Battle/BattleField/BattleField.cs b/Main/System/Battle/BattleField/BattleField.cs
index aea3df5..c89cd53 100644
--- a/Main/System/Battle/BattleField/BattleField.cs
+++ b/Main/System/Battle/BattleField/BattleField.cs
@@ -586,6 +586,11 @@
 
     public virtual void ShowWindow(HB424_tagSCTurnFightInit vNetData)
     {
-        
+
+    }
+
+    public virtual BattleObject FindBoss()
+    {
+        return null;
     }
 }
diff --git a/Main/System/Battle/BattleField/StoryBossBattleField.cs b/Main/System/Battle/BattleField/StoryBossBattleField.cs
index c85ff80..fb71a62 100644
--- a/Main/System/Battle/BattleField/StoryBossBattleField.cs
+++ b/Main/System/Battle/BattleField/StoryBossBattleField.cs
@@ -2,19 +2,14 @@
 using LitJson;
 using UnityEngine;
 using System.Collections.Generic;
+using System.Linq;
 
 
 public class StoryBossBattleField : BattleField
 {
-    protected int chapter;//   绔犺妭
-    protected int wave;//  娉㈡暟
-    protected int level;// 鍏冲崱
     protected JsonData extendData;
 
-    protected MainChapterConfig chapterConfig;
-
     protected MainLevelConfig levelConfig;
-
 
     public StoryBossBattleField(string _guid) : base(_guid)
     {
@@ -26,12 +21,8 @@
     {
         base.Init(MapID, FuncLineID, extendData, _redTeamList, _blueTeamList, turnMax);
 
-        chapter = FuncLineID / 10000;
-        wave = MapID == 1 ? FuncLineID % 100 : 1;//绗嚑娉㈡��
-        level = (FuncLineID % 10000) / 100;
-
+        int level = FuncLineID;// 鍏冲崱
         extendData = _extendData;
-        chapterConfig = MainChapterConfig.Get(chapter);
         levelConfig = MainLevelConfig.Get(level);
 
         SetBattleMode(BattleMode.Record);
@@ -128,4 +119,40 @@
         }
         fsBattleWin.SetBattleField(this);
     }
+
+    public NPCLineupConfig GetBossLineupConfig()
+    {
+        if (null == levelConfig)
+            return null;
+
+        int[] bossLineup = levelConfig.BossLineupIDList;
+
+        if (bossLineup.IsNullOrEmpty())
+            return null;
+
+        var lineupID = bossLineup[0];
+
+        if (lineupID > 0)
+        {
+            NPCLineupConfig lineupConfig = NPCLineupConfig.Get(lineupID);
+            return lineupConfig;
+        }
+
+        return null;
+    }
+
+    public override BattleObject FindBoss()
+    {
+        NPCLineupConfig lineupConfig = GetBossLineupConfig();
+        if (lineupConfig != null)
+        {
+            int bossId = lineupConfig.BossID;
+
+            BattleObject bo = battleObjMgr.allBattleObjDict.Values.FirstOrDefault(bo => bo.teamHero.NPCID == bossId);
+
+            return bo;
+        }
+
+        return null;
+    }
 }
\ No newline at end of file
diff --git a/Main/System/Battle/BattleObject/BattleObject.cs b/Main/System/Battle/BattleObject/BattleObject.cs
index 8457d59..89714c3 100644
--- a/Main/System/Battle/BattleObject/BattleObject.cs
+++ b/Main/System/Battle/BattleObject/BattleObject.cs
@@ -272,9 +272,10 @@
         HB427_tagSCUseSkill.tagSCUseSkillHurt hurt, SkillConfig skillConfig, int hitIndex,
         BattleDrops battleDrops, HB422_tagMCTurnFightObjDead deadPack)
     {
-        BattleDmgInfo dmgInfo = PopDamage(damageValues, _totalDamage, hurt, skillConfig);
         bool isLastHit = hitIndex >= skillConfig.DamageDivide.Length - 1;
         bool firstHit = hitIndex == 0;
+        BattleDmgInfo dmgInfo = PopDamage(damageValues, _totalDamage, hurt, skillConfig, isLastHit);
+
 
         //  杩欓噷
         if (dmgInfo.IsType(DamageType.Dodge))
@@ -385,11 +386,9 @@
     }
 
     // 浼ゅ杩樿鐪� 鏄惁闂伩 鏆村嚮 and so on 闇�瑕佹湁涓�涓狣amageType 鏈嶅姟鍣ㄥ簲璇ヤ細缁�
-    protected virtual BattleDmgInfo PopDamage(List<long> damageValues, long _totalDamage, HB427_tagSCUseSkill.tagSCUseSkillHurt hurt, SkillConfig skillConfig)
+    protected virtual BattleDmgInfo PopDamage(List<long> damageValues, long _totalDamage, HB427_tagSCUseSkill.tagSCUseSkillHurt hurt, SkillConfig skillConfig, bool isLastHit)
     {
-        BattleDmgInfo battleDmgInfo = new BattleDmgInfo(battleField.guid, damageValues, this, hurt, skillConfig);
-
-
+        BattleDmgInfo battleDmgInfo = new BattleDmgInfo(battleField.guid, damageValues, this, hurt, skillConfig, isLastHit);
 
         int currentHurtHp = 0;
         for (int i = 0; i < damageValues.Count; i++)
diff --git a/Main/System/Battle/Buff/BattleObjectBuffMgr.cs b/Main/System/Battle/Buff/BattleObjectBuffMgr.cs
index 104fbcf..a3225a6 100644
--- a/Main/System/Battle/Buff/BattleObjectBuffMgr.cs
+++ b/Main/System/Battle/Buff/BattleObjectBuffMgr.cs
@@ -110,6 +110,13 @@
     //  鍒锋柊buff
     public void RefreshBuff(HB428_tagSCBuffRefresh vNetData, bool insert = false)
     {
+        if (battleObject.IsDead())
+        {
+            Debug.LogError("缁欐浜″璞″埛鏂癰uff 妫�鏌ユ湇鍔″櫒浠g爜");
+            RemoveAllBuff();
+            return;
+        }
+
         SkillConfig skillConfig = SkillConfig.Get((int)vNetData.SkillID);
 
         if (null == skillConfig)
@@ -131,7 +138,7 @@
 
         if (vNetData.IsAdd != 0)
         {
-            BuffMountAction buffMountAction = new BuffMountAction(battleObject.battleField, new List<HB428_tagSCBuffRefresh>(){ vNetData}, () =>
+            BuffMountAction buffMountAction = new BuffMountAction(battleObject.battleField, new List<HB428_tagSCBuffRefresh>() { vNetData }, () =>
             {
                 if (null != skillConfig && skillConfig.BuffEffect > 0)
                 {
@@ -147,7 +154,7 @@
                         BoneFollower boneFollower = effect.AddMissingComponent<BoneFollower>();
 
                         effect.BindBone(battleObject.motionBase.skeletonAnim, "hit");
-                        
+
                         HashSet<uint> buffIdSet = new HashSet<uint>();
                         buffIdSet.Add(vNetData.BuffID);
                         buffEffectDict.Add(skillConfig.BuffEffect, new KeyValuePair<BattleEffectPlayer, HashSet<uint>>(effect, buffIdSet));
@@ -170,6 +177,11 @@
             battleObject.heroInfoBar.RefreshBuff(buffDataDict.Values.ToList());
         }
     }
+    
+    public List<HB428_tagSCBuffRefresh> GetBuffList()
+    {
+        return buffDataDict.Values.ToList();
+    }
 
     public void InsertBuff(HB428_tagSCBuffRefresh vNetData)
     {
diff --git a/Main/System/Battle/Define/BattleDmgInfo.cs b/Main/System/Battle/Define/BattleDmgInfo.cs
index c68f1c1..f6e0492 100644
--- a/Main/System/Battle/Define/BattleDmgInfo.cs
+++ b/Main/System/Battle/Define/BattleDmgInfo.cs
@@ -26,15 +26,18 @@
     //  鏄惁琚牸鎸′簡
     public bool isBlocked = false;
 
+    public bool isLastHit = false;
+
     public List<BattleDmg> battleDamageList = new List<BattleDmg>();
 
-    public BattleDmgInfo(string battleFieldGuid, List<long> damageList, BattleObject hurtObj, HB427_tagSCUseSkill.tagSCUseSkillHurt hurt, SkillConfig skillConfig)
+    public BattleDmgInfo(string battleFieldGuid, List<long> damageList, BattleObject hurtObj, HB427_tagSCUseSkill.tagSCUseSkillHurt hurt, SkillConfig skillConfig, bool isLastHit)
     {
         this.battleFieldGuid = battleFieldGuid;
         this.damageList = damageList;
         this.hurtObj = hurtObj;
         this.hurt = hurt;
         this.skillConfig = skillConfig;
+        this.isLastHit = isLastHit;
         HandleDamageType();
         HandleAttackTypeAndDamage();
     }
diff --git a/Main/System/Battle/StoryBossBattleWin.cs b/Main/System/Battle/StoryBossBattleWin.cs
index 1c3db8a..6e54f4b 100644
--- a/Main/System/Battle/StoryBossBattleWin.cs
+++ b/Main/System/Battle/StoryBossBattleWin.cs
@@ -1,4 +1,5 @@
 锘縰sing System;
+using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
 
@@ -11,7 +12,7 @@
     private BattleRootNode battleRootNode = null;
 
 
-    private BattleField battleField;
+    private StoryBossBattleField battleField;
 
     [SerializeField]
     private Button btnSpeed;
@@ -39,6 +40,10 @@
     public Text txtBattleRound;
 
     public TotalDamageDisplayer totalDamageDisplayer;
+
+    private BattleObject bossBattleObject = null;
+
+    [SerializeField] public List<BattleBuffCell> buffCells;
 
     // 鐢熷懡鍛ㄦ湡
     protected override void InitComponent()
@@ -84,15 +89,20 @@
         base.OnPreOpen();
         // SetBattleField(BattleManager.Instance.storyBattleField);
         BattleManager.Instance.onBattleFieldCreate += OnCreateBattleField;
+        EventBroadcast.Instance.AddListener<BattleDmgInfo>(EventName.BATTLE_DAMAGE_TAKEN, OnDamageTaken);
 
         UIManager.Instance.CloseWindow<MainWin>();
     }
 
+
+
     protected override void OnPreClose()
     {
         base.OnPreClose();
-        UIManager.Instance.CloseWindow<BattleHUDWin>();
         BattleManager.Instance.onBattleFieldCreate -= OnCreateBattleField;
+        EventBroadcast.Instance.RemoveListener<BattleDmgInfo>(EventName.BATTLE_DAMAGE_TAKEN, OnDamageTaken);
+
+        UIManager.Instance.CloseWindow<BattleHUDWin>();
 
         if (!UIManager.Instance.IsOpened<MainWin>())
             UIManager.Instance.OpenWindow<MainWin>();
@@ -102,13 +112,67 @@
     {
         if (field.GetType() == battleField.GetType())
         {
-            SetBattleField(field);
+            SetBattleField(field as StoryBossBattleField);
         }
     }
 
     protected override void OnOpen()
     {
         base.OnOpen();
+    }
+
+    public override void Refresh()
+    {
+        base.Refresh();
+
+        // bossLifeBar.SetBaseInfo(battleField);
+
+        // skillWordCells;
+
+        NPCLineupConfig lineupConfig = battleField.GetBossLineupConfig();
+
+        bossBattleObject = battleField.FindBoss();
+
+        DisplaySkillWordsList(lineupConfig);
+
+        if (null != bossBattleObject)
+        {
+            TeamHero teamHero = bossBattleObject.teamHero;
+            bossHeadCell.SetTeamHero(teamHero);
+            txtBossName.text = teamHero.name;
+            NPCConfig npcConfig = NPCConfig.Get(teamHero.NPCID);
+            bossLifeBar.SetBaseInfo(Mathf.Max(1, npcConfig.LifeBarCount), (ulong)teamHero.curHp, (ulong)teamHero.maxHp);
+        }
+        else
+        {
+            bossHeadCell.SetTeamHero(null);
+            txtBossName.text = string.Empty;
+            bossLifeBar.SetBaseInfo(2, 2, 2);
+            Debug.LogError("鎵句笉鍒癰oss");
+        }
+
+        txtBattleRound.text = string.Format("{0}/{1}", battleField.round, battleField.turnMax);
+    }
+
+    private void RefreshHP()
+    {
+        if (null != bossBattleObject)
+        {
+            TeamHero teamHero = bossBattleObject.teamHero;
+            bossLifeBar.Show((ulong)teamHero.curHp, (ulong)teamHero.maxHp);
+        }
+    }
+
+
+    private void OnDamageTaken(BattleDmgInfo info)
+    {
+        if (info.hurtObj.ObjID == bossBattleObject.ObjID)
+        {
+            // Update the boss's health bar
+            RefreshHP();
+        }
+
+        totalDamageDisplayer.SetDamage(info);
     }
 
     protected override void OnClose()
@@ -134,7 +198,7 @@
         base.CompleteClose();
     }
 
-    public void SetBattleField(BattleField _battleField)
+    public void SetBattleField(StoryBossBattleField _battleField)
     {
         battleField = _battleField;
         if (battleRootNode != null)
@@ -160,6 +224,61 @@
         battleField.UpdateCanvas(canvas);
         buttonsAdjuster.SetSortingOrder(BattleConst.ActiveHeroActionSortingOrder);
 
+        Refresh();
+
         textSpeed.text = (BattleManager.Instance.speedIndex + 1).ToString();
     }
+
+    public void DisplaySkillWordsList(NPCLineupConfig lineUPConfig)
+    {
+        if (skillWordCells.IsNullOrEmpty())
+            return;
+
+        if (null == lineUPConfig)
+            return;
+
+        for (int i = 0; i < skillWordCells.Length; i++)
+        {
+            if (i < lineUPConfig.SkillIDExList.Length)
+            {
+                skillWordCells[i].SetActive(true);
+                int skillID = lineUPConfig.SkillIDExList[i];
+                skillWordCells[i].Init(skillID, () =>
+                {
+                    SmallTipWin.showText = Language.Get("SmallTipFomat", SkillConfig.Get(skillID)?.SkillName, SkillConfig.Get(skillID)?.Description);
+                    SmallTipWin.worldPos = CameraManager.uiCamera.ScreenToWorldPoint(Input.mousePosition);
+                    SmallTipWin.isDownShow = true;
+                    UIManager.Instance.OpenWindow<SmallTipWin>();
+                });
+            }
+            else
+            {
+                skillWordCells[i].SetActive(false);
+            }
+        }
+    }
+
+    public void RefreshBuff(List<HB428_tagSCBuffRefresh> datas)
+    {
+        if (buffCells.IsNullOrEmpty())
+            return;
+
+
+        for (int i = 0; i < buffCells.Count; i++)
+        {
+            if (i < datas.Count)
+            {
+                buffCells[i].SetActive(true);
+                HB428_tagSCBuffRefresh buffData = datas[i];
+                buffCells[i].Init(buffData, () =>
+                {
+                    //  鐐瑰嚮buff鍥炬爣 鏄剧ずbuff鎻忚堪/褰撳墠韬笂鎵�鏈塨uff
+                });
+            }
+            else
+            {
+                buffCells[i].SetActive(false);
+            }
+        }
+    }
 }
diff --git a/Main/System/Battle/UIComp/BattleBuffCell.cs b/Main/System/Battle/UIComp/BattleBuffCell.cs
index d3e5e57..c5052ca 100644
--- a/Main/System/Battle/UIComp/BattleBuffCell.cs
+++ b/Main/System/Battle/UIComp/BattleBuffCell.cs
@@ -1,17 +1,118 @@
 using UnityEngine;
 using UnityEngine.UI;
+using System;
 
-public class BattleBuffCell : CellView
+public class BattleBuffCell : MonoBehaviour
 {
-    public Image imageIcon;
-    public Text textLevel;
-
-    public void Display(HB428_tagSCBuffRefresh hB428_TagSCBuffRefresh)
+    ImageEx m_buffIcon;
+    ImageEx buffIcon
     {
-        SkillConfig skillConfig = SkillConfig.Get((int)hB428_TagSCBuffRefresh.SkillID);
+        get
+        {
+            if (m_buffIcon == null)
+            {
+                m_buffIcon = this.transform.GetComponent<ImageEx>("Container_BuffCell/Img_Icon");
+            }
+            return m_buffIcon;
+        }
+    }
 
-        imageIcon.sprite = ResManager.Instance.LoadAsset<Sprite>("", skillConfig.IconName);
-        textLevel.text = hB428_TagSCBuffRefresh.Layer.ToString();
+    Button m_buffButton;
+    Button buffButton
+    {
+        get
+        {
+            if (m_buffButton == null)
+            {
+                m_buffButton = gameObject.GetComponent<Button>();
+            }
+            return m_buffButton;
+        }
+    }
+
+    TextEx m_BuffLayer;
+
+    TextEx buffLayer
+    {
+        get
+        {
+            if (m_BuffLayer == null)
+            {
+                m_BuffLayer = this.transform.GetComponent<TextEx>("Container_BuffCell/Text_Layer");
+            }
+            return m_BuffLayer;
+        }
+    }
+
+    void Awake()
+    {
+        LoadPrefab();
+    }
+
+    GameObject cellContainer;
+
+    private void LoadPrefab()
+    {
+        if (cellContainer != null)
+            return;
+
+        var tmp = transform.Find("Container_BuffCell");
+        if (tmp != null)
+        {
+            cellContainer = tmp.gameObject;
+            return;
+        }
+
+        if (cellContainer == null)
+        {
+            cellContainer = UIUtility.CreateWidget("BattleBuffCell", "Container_BuffCell");
+            if (cellContainer != null)
+            {
+                cellContainer.transform.SetParentEx(this.transform, Vector3.zero, Quaternion.identity, Vector3.one);
+                cellContainer.transform.SetAsFirstSibling();
+            }
+        }
+
+        //缂╂斁鍒板拰鐖秗ect涓�鏍峰ぇ
+        // var scale = 1f;
+        // var rect = cellContainer.GetComponent<RectTransform>();
+        // var parentRect = transform.GetComponent<RectTransform>();
+        // float width = parentRect.sizeDelta.x;
+        // if (width <= 0f)
+        // {
+        //     //澶栭儴鎺у埗浜嗗昂瀵歌幏鍙栦负0
+        //     GridLayoutGroup grid = GetComponentInParent<GridLayoutGroup>();
+        //     if (grid != null)
+        //     {
+        //         width = grid.cellSize.x;
+        //     }
+
+        // }
+        // scale = width / rect.sizeDelta.x;
+        // cellContainer.transform.localScale = cellContainer.transform.localScale * scale;
+    }
+
+    public void Init(HB428_tagSCBuffRefresh buffData, Action onclick = null, bool showType = false)
+    {
+        if (null == buffData || gameObject == null)
+        {
+            return;
+        }
+        LoadPrefab();   //瀛樺湪琚嵏杞界殑鍙兘锛岄噸鏂板姞杞�
+        var config = SkillConfig.Get((int)buffData.SkillID);
+        if (config == null)
+        {
+            Debug.LogErrorFormat("鎶�鑳芥湭閰嶇疆 : {0}", buffData.SkillID);
+            return;
+        }
+        buffIcon.SetOrgSprite(config.BuffIconName, "BuffIcon");
+
+        buffButton.AddListener(() =>
+        {
+            onclick?.Invoke();
+        });
+
+        buffLayer.text = buffData.Layer == 0 ? "" : buffData.Layer.ToString();
     }
 }
 
diff --git a/Main/System/Battle/UIComp/BattleBuffLineCell.cs b/Main/System/Battle/UIComp/BattleBuffLineCell.cs
deleted file mode 100644
index e8e4519..0000000
--- a/Main/System/Battle/UIComp/BattleBuffLineCell.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System.Collections.Generic;
-using UnityEngine;
-
-
-public class BattleBuffLineCell : CellView
-{
-    [SerializeField] BattleBuffCell[] buffCellList;
-
-    public void Display(List<HB428_tagSCBuffRefresh> buffList, int index)
-    { 
-        for (int i = 0; i < buffCellList.Length; i++)
-        {
-            if (i + index < buffList.Count)
-            {
-                buffCellList[i].SetActive(true);
-                buffCellList[i].Display(buffList[i + index]);
-            }
-            else
-            {
-                buffCellList[i].SetActive(false);
-            }
-        }
-    }
-}
-
diff --git a/Main/System/Battle/UIComp/BattleBuffLineCell.cs.meta b/Main/System/Battle/UIComp/BattleBuffLineCell.cs.meta
deleted file mode 100644
index eef39d7..0000000
--- a/Main/System/Battle/UIComp/BattleBuffLineCell.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: ed7bc7d61144495468403b4152a0150f
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/System/Battle/UIComp/BattleHeroInfoBar.cs b/Main/System/Battle/UIComp/BattleHeroInfoBar.cs
index eebee91..87e73fe 100644
--- a/Main/System/Battle/UIComp/BattleHeroInfoBar.cs
+++ b/Main/System/Battle/UIComp/BattleHeroInfoBar.cs
@@ -18,7 +18,7 @@
     public float PopUpInterval = 0.2f;
 
 
-    // public List<BattleBuffCell> buffCells = new List<BattleBuffCell>();
+    [SerializeField] public List<BattleBuffCell> buffCells = new List<BattleBuffCell>();
 
     protected List<string> messages = new List<string>();
 
@@ -34,40 +34,42 @@
 
     protected List<HB428_tagSCBuffRefresh> buffList = new List<HB428_tagSCBuffRefresh>();
 
-    public ScrollerController scroller;
 
     public void SetBattleObject(BattleObject _battleObject)
     {
         battleObject = _battleObject;
         heroInfoContainer.SetHeroInfo(battleObject.teamHero);
-        RefreshBuff(buffList);
+        RefreshBuff(battleObject.buffMgr.GetBuffList());
         UpdateHP(battleObject.teamHero.curHp, battleObject.teamHero.curHp, battleObject.teamHero.maxHp, false);
         UpdateXP(battleObject.teamHero.rage, battleObject.teamHero.rage, 100, false);
     }
 
     public void RefreshBuff(List<HB428_tagSCBuffRefresh> datas)
     {
-        buffList = datas;
-        //  鏇存柊buff鍥炬爣 or 鍒涘缓鏂扮殑buff鍥炬爣
-        scroller.Refresh();
-        for (int i = 0; i < buffList.Count; i++)
+        if (buffCells.IsNullOrEmpty())
+            return;
+
+
+        for (int i = 0; i < buffCells.Count; i++)
         {
-            if (i % 5 == 0)
+            if (i < datas.Count)
             {
-                scroller.AddCell(ScrollerDataType.Header, i);
+                buffCells[i].SetActive(true);
+                HB428_tagSCBuffRefresh buffData = datas[i];
+                buffCells[i].Init(buffData, () =>
+                {
+                    //  鐐瑰嚮buff鍥炬爣 鏄剧ずbuff鎻忚堪/褰撳墠韬笂鎵�鏈塨uff
+                });
+            }
+            else
+            {
+                buffCells[i].SetActive(false);
             }
         }
-        scroller.Restart();
-    }
-
-    protected void OnEnable()
-    {
-        scroller.OnRefreshCell += OnRefreshCell;        
     }
 
     protected void OnDisable()
     {
-        scroller.OnRefreshCell -= OnRefreshCell;     
         //  TODO YYL 鑰冭檻姹犲寲
         messages.Clear();
         for (int i = 0; i < tipsList.Count; i++)
@@ -78,13 +80,6 @@
         }
         tipsList.Clear();
     }
-
-    protected void OnRefreshCell(ScrollerDataType type, CellView cell)
-    {
-        var _cell = cell as BattleBuffLineCell;
-        _cell.Display(buffList, cell.index);
-    }
-
     public void ShowTips(string message)
     {
         messages.Add(message);
diff --git a/Main/System/Battle/UIComp/BossHeadCell.cs b/Main/System/Battle/UIComp/BossHeadCell.cs
index fc9d14a..6041171 100644
--- a/Main/System/Battle/UIComp/BossHeadCell.cs
+++ b/Main/System/Battle/UIComp/BossHeadCell.cs
@@ -15,6 +15,25 @@
 
     public void SetTeamHero(TeamHero teamHero)
     {
-        
+        if (null == teamHero)
+        {
+            SetDefault();
+            return;
+        }
+
+        HeroSkinConfig heroSkinConfig = teamHero.skinConfig;
+        imgIcon.sprite = UILoader.LoadSprite("HeroHead", heroSkinConfig.SquareIcon);
+        txtLv.text = Language.Get("Arena22", teamHero.level);
+
+        // TODO YYL
+        // imgFrame璺焛mgDecoration绛夊够澧冮榿瀹屾垚涔嬪悗鍐嶆潵鍋�
+    }
+    
+    public void SetDefault()
+    {
+        imgFrame.sprite = null;
+        imgIcon.sprite = null;
+        imgDecoration.sprite = null;
+        txtLv.text = "";
     }
 }
diff --git a/Main/System/Battle/UIComp/TotalDamageDisplayer.cs b/Main/System/Battle/UIComp/TotalDamageDisplayer.cs
index 41df9e1..1ed0fe3 100644
--- a/Main/System/Battle/UIComp/TotalDamageDisplayer.cs
+++ b/Main/System/Battle/UIComp/TotalDamageDisplayer.cs
@@ -1,32 +1,96 @@
 using System.Collections;
-using System.Collections.Generic;
+using Cysharp.Threading.Tasks;
 using UnityEngine;
 using UnityEngine.UI;
+using System.Threading;
 
 public class TotalDamageDisplayer : MonoBehaviour
 {
     public Image damageBackground;
-
     public Text textDamage;
-
     public Text textTotalDesc; //鎬讳激瀹虫垨鑰呮�绘不鐤�
 
-    public void SetDamage(bool isEnd, BattleDmgInfo dmgInfo)
+    public UniTask task = default;
+
+    private Coroutine hideCoroutine;
+    private int hideVersion = 0;
+
+    public void SetDamage(BattleDmgInfo dmgInfo)
     {
+        // 鍏堢粺涓�鍋滄骞舵竻鐞嗘鍓嶇殑闅愯棌鍗忕▼锛堝鏋滄湁锛�
+        ClearHideCoroutine();
+
+        if (!gameObject.activeInHierarchy)
+            gameObject.SetActive(true);
+
         if (dmgInfo == null)
-        {
             return;
-        }
 
         if (dmgInfo.IsType(DamageType.Recovery))
         {
-
+            // 淇濇寔鍘熸湁澶勭悊閫昏緫浣嶇疆
         }
         else if (dmgInfo.IsType(DamageType.Damage) || dmgInfo.IsType(DamageType.Realdamage))
         {
+            // 淇濇寔鍘熸湁澶勭悊閫昏緫浣嶇疆
+        }
 
+        if (dmgInfo.isLastHit)
+        {
+            // 鍚姩鏂扮殑闅愯棌鍗忕▼锛屽厛鐢熸垚鏂扮殑鐗堟湰鍙蜂互鐢ㄤ簬鍗忕▼鏈夋晥鎬ф牎楠�
+            hideVersion++;
+            int myVersion = hideVersion;
+
+
+            var battleField = BattleManager.Instance.GetBattleField(dmgInfo.battleFieldGuid);
+
+            float ms = 1000f / battleField.speedRatio;
+
+            hideCoroutine = StartCoroutine(HideAfterDelayCoroutine(ms, myVersion));
+
+            task = default;
         }
     }
 
+    protected void OnDisable()
+    {
+        ClearHideCoroutine();
+        hideVersion++;
+    }
 
+    protected void OnDestroy()
+    {
+        ClearHideCoroutine();
+        hideVersion++;
+    }
+
+    public void CancelHide()
+    {
+        ClearHideCoroutine();
+        hideVersion++;
+    }
+
+    private void ClearHideCoroutine()
+    {
+        if (hideCoroutine != null)
+        {
+            try { StopCoroutine(hideCoroutine); } catch { }
+            hideCoroutine = null;
+        }
+    }
+
+    private IEnumerator HideAfterDelayCoroutine(float secondsDelay, int version = 0)
+    {
+        yield return new WaitForSeconds(secondsDelay);
+
+        if (version != 0 && version != hideVersion)
+            yield break;
+
+        if (this == null) yield break;
+        if (gameObject != null)
+            gameObject.SetActive(false);
+
+        if (hideCoroutine != null)
+            hideCoroutine = null;
+    }
 }
diff --git a/Main/System/MainLevel/MainBossEnterWin.cs b/Main/System/MainLevel/MainBossEnterWin.cs
index 9c23ddf..212b555 100644
--- a/Main/System/MainLevel/MainBossEnterWin.cs
+++ b/Main/System/MainLevel/MainBossEnterWin.cs
@@ -138,6 +138,7 @@
         {
             var pack = new CB410_tagCMTurnFight();
             pack.MapID = 2;
+            // pack.FuncLineID = (uint)PlayerDatas.Instance.baseData.ExAttr1 + 1;
             GameNetSystem.Instance.SendInfo(pack);
 
             AutoFightModel.Instance.isPause = true;
diff --git a/Main/Utility/ComponentExtersion.cs b/Main/Utility/ComponentExtersion.cs
index 46de825..17601fc 100644
--- a/Main/Utility/ComponentExtersion.cs
+++ b/Main/Utility/ComponentExtersion.cs
@@ -315,6 +315,7 @@
         }
 
         var sprite = UILoader.LoadSprite(folderName, iconName);
+        if (null == sprite) return;
         _image.overrideSprite = sprite;
     }
 

--
Gitblit v1.8.0