From 7f9ec6d10ebb5d741b10e2b4168b11ad0ebb22cd Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期二, 11 十一月 2025 17:05:01 +0800
Subject: [PATCH] 125 战斗 飘血 护盾 满怒气 吸血反伤拆分

---
 Main/System/Battle/UIComp/DamageContent.cs              |  135 ++++-
 Main/System/Battle/BattleConst.cs                       |    1 
 Main/System/Battle/BattleManager.cs                     |    9 
 Main/System/Battle/BattleObject/BattleObjectFactory.cs  |   11 
 Main/System/Battle/BattleHUDWin.cs                      |  360 ++++++++------
 Main/System/Battle/Buff/BattleObjectBuffMgr.cs          |   27 +
 Main/System/Battle/Define/BattleDmgInfo.cs              |  363 ++++++++++----
 Main/System/Battle/BattleObject/BattleObject.cs         |   17 
 Main/System/Battle/Skill/SkillBase.cs                   |  128 ++++
 Main/System/Battle/UIComp/BattleHeroInfoBar.cs          |  313 +++++++++---
 Main/System/Battle/Define/DamageType.cs                 |   22 
 Main/System/Battle/UIComp/BattleFloatingUIController.cs |    7 
 Main/System/Battle/UIComp/BattleTips.cs                 |    6 
 13 files changed, 998 insertions(+), 401 deletions(-)

diff --git a/Main/System/Battle/BattleConst.cs b/Main/System/Battle/BattleConst.cs
index 266ac7d..daf90bc 100644
--- a/Main/System/Battle/BattleConst.cs
+++ b/Main/System/Battle/BattleConst.cs
@@ -202,4 +202,5 @@
         PassiveSkillLimitGroup,
     };
 
+    public const int ShieldBuffAttackType = 1003;//鎶ょ浘鍚告敹浼ゅ绫诲瀷ID
 }
\ No newline at end of file
diff --git a/Main/System/Battle/BattleHUDWin.cs b/Main/System/Battle/BattleHUDWin.cs
index df219fd..bfbf6fc 100644
--- a/Main/System/Battle/BattleHUDWin.cs
+++ b/Main/System/Battle/BattleHUDWin.cs
@@ -10,6 +10,10 @@
 //  杩欎釜鐣岄潰鏄� persistent鐨勭晫闈�
 public class BattleHUDWin : UIBase
 {
+    private const int CASTER_DAMAGE_HEIGHT_OFFSET = 100; // 鏂芥硶鑰呬激瀹抽珮搴﹂棿闅�
+    private const int CASTER_DAMAGE_FLOAT_HEIGHT = 150;  // 椋樺瓧鍚戜笂绉诲姩楂樺害
+    private const int TARGET_DAMAGE_FLOAT_HEIGHT = 150;  // 鐩爣浼ゅ椋樺瓧鍚戜笂绉诲姩楂樺害
+
     private GameObjectPoolManager.GameObjectPool damagePrefabPool;
     private GameObjectPoolManager.GameObjectPool buffIconPrefabPool;
     private GameObjectPoolManager.GameObjectPool buffLabelPrefabPool;
@@ -29,35 +33,14 @@
     protected override void OnPreOpen()
     {
         base.OnPreOpen();
-        EventBroadcast.Instance.AddListener<BattleDmgInfo>(EventName.BATTLE_DAMAGE_TAKEN, OnDamageTaken);
-        EventBroadcast.Instance.AddListener<string, JsonData>(EventName.BATTLE_END, OnBattleEnd);
-        damagePrefabPool = GameObjectPoolManager.Instance.RequestPool(UILoader.LoadPrefab("DamageContent"));
-    }
-
-    private void OnBattleEnd(string guid, JsonData data)
-    {
-        ClearContent(guid);
-    }
-
-    private void ClearContent(string guid, bool force = false)
-    {
-        if ((battleField != null && battleField.guid == guid) || force)
-        {
-            for (int i = damageContentList.Count - 1; i >= 0; i--)
-            {
-                var content = damageContentList[i];
-                content.Stop();
-                RemoveDamageContent(content);
-            }
-            damageContentList.Clear();
-        }
+        RegisterEvents();
+        InitializePools();
     }
 
     protected override void OnPreClose()
     {
         base.OnPreClose();
-        EventBroadcast.Instance.RemoveListener<BattleDmgInfo>(EventName.BATTLE_DAMAGE_TAKEN, OnDamageTaken);
-        EventBroadcast.Instance.RemoveListener<string, JsonData>(EventName.BATTLE_END, OnBattleEnd);
+        UnregisterEvents();
     }
 
     protected override void OnOpen()
@@ -68,13 +51,7 @@
     protected override void OnClose()
     {
         base.OnClose();
-        if (battleField != null)
-        {
-            battleField.OnBattlePause -= OnBattlePause;
-            battleField.OnBattleRun -= OnBattleRun;
-            battleField.OnSpeedRatioChange -= OnSpeedRatioChange;
-            battleField = null;
-        }
+        CleanupBattleField();
     }
 
     protected override void NextFrameAfterOpen()
@@ -87,121 +64,65 @@
         base.CompleteClose();
     }
 
-    private void RemoveDamageContent(DamageContent content)
+    private void RegisterEvents()
     {
-        damageContentList.Remove(content);
-        damagePrefabPool.Release(content.gameObject);
+        EventBroadcast.Instance.AddListener<BattleDmgInfo>(EventName.BATTLE_DAMAGE_TAKEN, OnDamageTaken);
+        EventBroadcast.Instance.AddListener<string, JsonData>(EventName.BATTLE_END, OnBattleEnd);
+    }
+
+    private void UnregisterEvents()
+    {
+        EventBroadcast.Instance.RemoveListener<BattleDmgInfo>(EventName.BATTLE_DAMAGE_TAKEN, OnDamageTaken);
+        EventBroadcast.Instance.RemoveListener<string, JsonData>(EventName.BATTLE_END, OnBattleEnd);
+    }
+
+    private void InitializePools()
+    {
+        damagePrefabPool = GameObjectPoolManager.Instance.RequestPool(UILoader.LoadPrefab("DamageContent"));
+    }
+
+    public void SetBattleField(BattleField _battleField)
+    {
+        CleanupBattleField();
+        ClearContent(string.Empty, true);
+        
+        battleField = _battleField;
+        RegisterBattleFieldEvents();
+    }
+
+    private void RegisterBattleFieldEvents()
+    {
+        if (battleField == null) return;
+        
+        battleField.OnBattlePause += OnBattlePause;
+        battleField.OnBattleRun += OnBattleRun;
+        battleField.OnSpeedRatioChange += OnSpeedRatioChange;
+    }
+
+    private void UnregisterBattleFieldEvents()
+    {
+        if (battleField == null) return;
+        
+        battleField.OnBattlePause -= OnBattlePause;
+        battleField.OnBattleRun -= OnBattleRun;
+        battleField.OnSpeedRatioChange -= OnSpeedRatioChange;
+    }
+
+    private void CleanupBattleField()
+    {
+        UnregisterBattleFieldEvents();
+        battleField = null;
+    }
+
+    private void OnBattleEnd(string guid, JsonData data)
+    {
+        ClearContent(guid);
     }
 
     private void OnDamageTaken(BattleDmgInfo damageInfo)
     {
         SetTargetDamage(damageInfo);
         SetSelfDamage(damageInfo);
-    }
-
-    private void SetSelfDamage(BattleDmgInfo damageInfo)
-    {
-        if (damageInfo.casterDamageList.Count > 0)
-        {
-            GameObject damageContent = damagePrefabPool.Request();
-            DamageContent content = damageContent.GetComponent<DamageContent>();
-            damageContent.transform.SetParent(damageNode, false);
-            
-            var heroRect = damageInfo.casterObj.heroRectTrans;
-            if (heroRect == null)
-            {
-                damagePrefabPool.Release(damageContent);
-                return;
-            }
-
-            var contentRect = content.GetComponent<RectTransform>();
-            var contentParentRect = contentRect.parent as RectTransform;
-
-            // 鑾峰彇 heroRect 鐨勪笘鐣屽潗鏍囷紙閿氱偣涓轰腑蹇冿級
-            Vector3 worldTargetPos = heroRect.transform.TransformPoint(heroRect.rect.center);
-
-            // 杞崲鍒� content 鐖惰妭鐐逛笅鐨� anchoredPosition
-            Vector2 anchoredPos;
-            RectTransformUtility.ScreenPointToLocalPointInRectangle(
-                contentParentRect,
-                RectTransformUtility.WorldToScreenPoint(null, worldTargetPos),
-                null,
-                out anchoredPos);
-
-            // 璁剧疆鍔ㄦ�佷綅缃紙浼氳鐩栭厤缃腑鐨勪綅缃級
-            Vector2 beginPos = anchoredPos;
-            Vector2 endPos = anchoredPos + new Vector2(0, 150);
-            content.SetPosition(beginPos, endPos);
-
-            // 璁剧疆閫熷害姣斾緥
-            if (battleField != null)
-            {
-                content.SetRatio(battleField.speedRatio, 1f);
-            }
-            
-            content.SetDamage(damageInfo, damageInfo.casterDamageList, () => RemoveDamageContent(content));
-            damageContentList.Add(content);
-        }
-    }
-
-    private void SetTargetDamage(BattleDmgInfo damageInfo)
-    {
-        if (damageInfo.targetDamageList.Count > 0)
-        {
-            GameObject damageContent = damagePrefabPool.Request();
-            DamageContent content = damageContent.GetComponent<DamageContent>();
-            damageContent.transform.SetParent(damageNode, false);
-            
-            var heroRect = damageInfo.hurtObj.heroRectTrans;
-            if (heroRect == null)
-            {
-                damagePrefabPool.Release(damageContent);
-                return;
-            }
-
-            var contentRect = content.GetComponent<RectTransform>();
-            var contentParentRect = contentRect.parent as RectTransform;
-
-            // 鑾峰彇 heroRect 鐨勪笘鐣屽潗鏍囷紙閿氱偣涓轰腑蹇冿級
-            Vector3 worldTargetPos = heroRect.transform.TransformPoint(heroRect.rect.center);
-
-            // 杞崲鍒� content 鐖惰妭鐐逛笅鐨� anchoredPosition
-            Vector2 anchoredPos;
-            RectTransformUtility.ScreenPointToLocalPointInRectangle(
-                contentParentRect,
-                RectTransformUtility.WorldToScreenPoint(null, worldTargetPos),
-                null,
-                out anchoredPos);
-
-            // 璁剧疆鍔ㄦ�佷綅缃紙浼氳鐩栭厤缃腑鐨勪綅缃級
-            Vector2 beginPos = anchoredPos;
-            Vector2 endPos = anchoredPos + new Vector2(0, 150);
-            content.SetPosition(beginPos, endPos);
-
-            // 璁剧疆閫熷害姣斾緥
-            if (battleField != null)
-            {
-                content.SetRatio(battleField.speedRatio, 1f);
-            }
-            
-            content.SetDamage(damageInfo, damageInfo.targetDamageList, () => RemoveDamageContent(content));
-            damageContentList.Add(content);
-        }
-    }
-
-    public void SetBattleField(BattleField _battleField)
-    {
-        if (battleField != null)
-        {
-            battleField.OnBattlePause -= OnBattlePause;
-            battleField.OnBattleRun -= OnBattleRun;
-            battleField.OnSpeedRatioChange -= OnSpeedRatioChange;
-        }
-        ClearContent(string.Empty, true);
-        battleField = _battleField;
-        battleField.OnBattlePause += OnBattlePause;
-        battleField.OnBattleRun += OnBattleRun;
-        battleField.OnSpeedRatioChange += OnSpeedRatioChange;
     }
 
     private void OnSpeedRatioChange(float newSpeedRatio)
@@ -216,22 +137,167 @@
     {
         if (isPause)
         {
-            foreach (var content in damageContentList)
-            {
-                content.Stop();
-            }
+            PauseAllDamageContent();
         }
         else
         {
-            foreach (var content in damageContentList)
-            {
-                content.Resume();
-            }
+            ResumeAllDamageContent();
         }
     }
 
     private void OnBattleRun()
     {
+        RunAllDamageContent();
+    }
+
+    /// <summary>
+    /// 璁剧疆鐩爣鍙楀埌鐨勪激瀹虫樉绀�
+    /// </summary>
+    private void SetTargetDamage(BattleDmgInfo damageInfo)
+    {
+        if (damageInfo.targetDamageList.Count == 0) return;
+
+        RectTransform heroRect = damageInfo.hurtObj.heroRectTrans;
+        if (heroRect == null) return;
+
+        DamageContent content = CreateDamageContent();
+        if (content == null) return;
+
+        Vector2 anchoredPos = CalculateWorldToLocalPosition(heroRect, content);
+        SetupTargetDamagePosition(content, anchoredPos);
+        SetupDamageContent(content, damageInfo.targetDamageList, damageInfo);
+    }
+
+    /// <summary>
+    /// 璁剧疆鐩爣浼ゅ鐨勮捣濮嬪拰缁撴潫浣嶇疆
+    /// </summary>
+    private void SetupTargetDamagePosition(DamageContent content, Vector2 anchoredPos)
+    {
+        // 淇濇寔鑻遍泟鐨� X 鍧愭爣锛屽彧鍦� Y 杞村悜涓婇
+        Vector2 beginPos = anchoredPos;
+        Vector2 endPos = anchoredPos + new Vector2(0, TARGET_DAMAGE_FLOAT_HEIGHT);
+        content.SetPosition(beginPos, endPos);
+    }
+
+    /// <summary>
+    /// 璁剧疆鏂芥硶鑰呭彈鍒扮殑浼ゅ鏄剧ず锛堝弽浼ゃ�佸惛琛�绛夛級
+    /// </summary>
+    private void SetSelfDamage(BattleDmgInfo damageInfo)
+    {
+        if (damageInfo.casterDamageList.Count == 0) return;
+
+        RectTransform heroRect = damageInfo.casterObj.heroRectTrans;
+        if (heroRect == null) return;
+
+        // 鍒涘缓鍗曚釜DamageContent鏄剧ず鎵�鏈夋柦娉曡�呬激瀹�
+        DamageContent content = CreateDamageContent();
+        if (content == null) return;
+
+        Vector2 anchoredPos = CalculateWorldToLocalPosition(heroRect, content);
+        SetupCasterDamagePosition(content, anchoredPos);
+        SetupDamageContent(content, damageInfo.casterDamageList, damageInfo);
+    }
+
+    /// <summary>
+    /// 璁剧疆鏂芥硶鑰呬激瀹崇殑璧峰鍜岀粨鏉熶綅缃�
+    /// </summary>
+    private void SetupCasterDamagePosition(DamageContent content, Vector2 anchoredPos)
+    {
+        // 淇濇寔鑻遍泟鐨� X 鍧愭爣锛屽彧鍦� Y 杞村悜涓婇
+        Vector2 beginPos = anchoredPos;
+        Vector2 endPos = anchoredPos + new Vector2(0, CASTER_DAMAGE_FLOAT_HEIGHT);
+        content.SetPosition(beginPos, endPos);
+    }
+
+    /// <summary>
+    /// 鍒涘缓涓�涓狣amageContent瀵硅薄
+    /// </summary>
+    private DamageContent CreateDamageContent()
+    {
+        GameObject damageContentObj = damagePrefabPool.Request();
+        DamageContent content = damageContentObj.GetComponent<DamageContent>();
+        damageContentObj.transform.SetParent(damageNode, false);
+        return content;
+    }
+
+    /// <summary>
+    /// 璁$畻鑻遍泟涓栫晫鍧愭爣鍒版湰鍦板潗鏍囩殑杞崲
+    /// </summary>
+    private Vector2 CalculateWorldToLocalPosition(RectTransform heroRect, DamageContent content)
+    {
+        RectTransform contentRect = content.GetComponent<RectTransform>();
+        RectTransform contentParentRect = contentRect.parent as RectTransform;
+
+        Vector3 worldTargetPos = heroRect.transform.TransformPoint(heroRect.rect.center);
+
+        Vector2 anchoredPos;
+        RectTransformUtility.ScreenPointToLocalPointInRectangle(
+            contentParentRect,
+            RectTransformUtility.WorldToScreenPoint(null, worldTargetPos),
+            null,
+            out anchoredPos);
+
+        return anchoredPos;
+    }
+
+    /// <summary>
+    /// 閰嶇疆DamageContent鐨勯�熷害銆佷激瀹虫暟鎹拰鍥炶皟
+    /// </summary>
+    private void SetupDamageContent(DamageContent content, List<BattleDmg> damageList, BattleDmgInfo damageInfo)
+    {
+        if (battleField != null)
+        {
+            content.SetRatio(battleField.speedRatio, 1f);
+        }
+
+        content.SetDamage(damageInfo, damageList, () => RemoveDamageContent(content));
+        damageContentList.Add(content);
+    }
+
+    /// <summary>
+    /// 绉婚櫎DamageContent瀵硅薄
+    /// </summary>
+    private void RemoveDamageContent(DamageContent content)
+    {
+        damageContentList.Remove(content);
+        damagePrefabPool.Release(content.gameObject);
+    }
+
+    /// <summary>
+    /// 娓呴櫎鎵�鏈変激瀹虫樉绀哄唴瀹�
+    /// </summary>
+    private void ClearContent(string guid, bool force = false)
+    {
+        if ((battleField != null && battleField.guid == guid) || force)
+        {
+            for (int i = damageContentList.Count - 1; i >= 0; i--)
+            {
+                var content = damageContentList[i];
+                content.Stop();
+                RemoveDamageContent(content);
+            }
+            damageContentList.Clear();
+        }
+    }
+
+    private void PauseAllDamageContent()
+    {
+        foreach (var content in damageContentList)
+        {
+            content.Stop();
+        }
+    }
+
+    private void ResumeAllDamageContent()
+    {
+        foreach (var content in damageContentList)
+        {
+            content.Resume();
+        }
+    }
+
+    private void RunAllDamageContent()
+    {
         for (int i = damageContentList.Count - 1; i >= 0; i--)
         {
             if (i < damageContentList.Count)
diff --git a/Main/System/Battle/BattleManager.cs b/Main/System/Battle/BattleManager.cs
index 23bd7dc..4d0adc8 100644
--- a/Main/System/Battle/BattleManager.cs
+++ b/Main/System/Battle/BattleManager.cs
@@ -491,12 +491,19 @@
                 isCreate = false;
             }
             else
-            { 
+            {
                 BattleDebug.LogError("鎴樺満宸插瓨鍦� 鍏堣繘琛岄攢姣�");
                 battleField.Destroy();
             }
         }
 
+        var bf = GetBattleFieldByMapID(MapID);
+        if (bf != null && !string.IsNullOrEmpty(guid))
+        {
+            BattleDebug.LogError("鐩稿悓鍦板浘ID鐨勬垬鍦哄凡瀛樺湪 鍏堣繘琛岄攢姣�");
+            bf.Destroy();
+        }
+
         if (isCreate)
         {
             battleField = BattleFieldFactory.CreateBattleField(guid, MapID, FuncLineID, extendData, redTeamList, blueTeamList);
diff --git a/Main/System/Battle/BattleObject/BattleObject.cs b/Main/System/Battle/BattleObject/BattleObject.cs
index 90db068..debe190 100644
--- a/Main/System/Battle/BattleObject/BattleObject.cs
+++ b/Main/System/Battle/BattleObject/BattleObject.cs
@@ -170,12 +170,12 @@
         {
             case PlayerDataType.HP:
                 long toHp = GeneralDefine.GetFactValue(_refreshInfo.Value, _refreshInfo.ValueEx);
-                heroInfoBar.UpdateHP(teamHero.curHp, toHp, teamHero.maxHp);
+                heroInfoBar.UpdateHP(teamHero.curHp, toHp, teamHero.maxHp, false);
                 teamHero.curHp = GeneralDefine.GetFactValue(_refreshInfo.Value, _refreshInfo.ValueEx);
                 break;
             case PlayerDataType.MaxHP:
                 teamHero.maxHp = GeneralDefine.GetFactValue(_refreshInfo.Value, _refreshInfo.ValueEx);
-                heroInfoBar.UpdateHP(teamHero.curHp, teamHero.curHp, teamHero.maxHp);
+                heroInfoBar.UpdateHP(teamHero.curHp, teamHero.curHp, teamHero.maxHp, false);
                 break;
             case PlayerDataType.XP:
                 long toXp = GeneralDefine.GetFactValue(_refreshInfo.Value, _refreshInfo.ValueEx);
@@ -198,12 +198,12 @@
         {
             case PlayerDataType.HP:
                 long toHp = GeneralDefine.GetFactValue(vNetData.Value, vNetData.ValueEx);
-                heroInfoBar.UpdateHP(teamHero.curHp, toHp, teamHero.maxHp);
+                heroInfoBar.UpdateHP(teamHero.curHp, toHp, teamHero.maxHp, false);
                 teamHero.curHp = GeneralDefine.GetFactValue(vNetData.Value, vNetData.ValueEx);
                 break;
             case PlayerDataType.MaxHP:
                 teamHero.maxHp = GeneralDefine.GetFactValue(vNetData.Value, vNetData.ValueEx);
-                heroInfoBar.UpdateHP(teamHero.curHp, teamHero.curHp, teamHero.maxHp);
+                heroInfoBar.UpdateHP(teamHero.curHp, teamHero.curHp, teamHero.maxHp, false);
                 break;
             case PlayerDataType.XP:
                 long toXp = GeneralDefine.GetFactValue(vNetData.Value, vNetData.ValueEx);
@@ -365,6 +365,12 @@
 
         motionBase.ShowIllusionShadow(true);
 
+        DamageNumConfig damageNumConfig = DamageNumConfig.Get((int)DamageType.Dodge);
+
+        string dodgeStr = ((char)damageNumConfig.prefix).ToString();
+
+        heroInfoBar.ShowTips(dodgeStr, true, false);
+
         tween.onComplete += () =>
         {
             motionBase.ShowIllusionShadow(false);
@@ -428,8 +434,7 @@
         }
         else
         {
-            // 浣跨敤浼犲叆鐨� fromHp 鍜� toHp 鏇存柊琛�鏉℃樉绀�
-            heroInfoBar.UpdateHP(battleHurtParam.fromHp, battleHurtParam.toHp, teamHero.maxHp);
+            heroInfoBar.UpdateDamage(battleDmgInfo);
 
             // YYL TODO 鏄惁闇�瑕佹寕鍦ㄥ湪鑷韩鐨刦ollow鐐逛笂
             EventBroadcast.Instance.Broadcast(EventName.BATTLE_DAMAGE_TAKEN, battleDmgInfo);
diff --git a/Main/System/Battle/BattleObject/BattleObjectFactory.cs b/Main/System/Battle/BattleObject/BattleObjectFactory.cs
index d40f987..d298536 100644
--- a/Main/System/Battle/BattleObject/BattleObjectFactory.cs
+++ b/Main/System/Battle/BattleObject/BattleObjectFactory.cs
@@ -34,8 +34,6 @@
 
         GameObject battleGO = ResManager.Instance.LoadAsset<GameObject>("Hero/SpineRes", "Hero_001"/*skinCfg.SpineRes*/);
 
-
-
         GameObject goParent = posNodeList[teamHero.positionNum];
         BattleObject battleObject = new BattleObject(_battleField);
         battleObject.ObjID = teamHero.ObjID;
@@ -50,7 +48,6 @@
             return null;
         }
 
-
         float finalScaleRate = modelScaleRate * teamHero.modelScale;
 
         skeletonAnimation.skeletonDataAsset = skeletonDataAsset;
@@ -61,6 +58,14 @@
         rectTrans.anchoredPosition = Vector2.zero;
         battleObject.Init(realGO, teamHero, _Camp);
 
+#if UNITY_EDITOR
+        BattleDebug.LogError(
+            "鍒濆鍖� 鏈鍔�" +
+            (battleObject.Camp == BattleCamp.Red ? "銆愮孩鏂广��" : "銆愯摑鏂广�� ") +
+            $"姝﹀皢: {battleObject.teamHero.name}\n" +
+            $"褰撳墠琛�閲�: {battleObject.teamHero.curHp} -> 鏈�澶ц閲弡battleObject.teamHero.maxHp}\n"
+        );
+#endif
 
         return battleObject;
     }
diff --git a/Main/System/Battle/Buff/BattleObjectBuffMgr.cs b/Main/System/Battle/Buff/BattleObjectBuffMgr.cs
index de47f8b..4e34649 100644
--- a/Main/System/Battle/Buff/BattleObjectBuffMgr.cs
+++ b/Main/System/Battle/Buff/BattleObjectBuffMgr.cs
@@ -363,12 +363,37 @@
 
         return false;
     }
-    
+
     public List<HB428_tagSCBuffRefresh> GetBuffList()
     {
         return buffDataDict.Values.ToList();
     }
 
+    public long GetShieldValue()
+    {
+        // 鎵夸激鐩惧垽鏂紝褰撻噴鏀炬柟寮忎负1003鏃跺彲浠ヨ涓烘壙浼ょ浘
+        // 鍓嶇鐩墠搴旇鏄壙浼ょ浘浼氱敤鍒�
+        // Value1     褰撳墠鍓╀綑鐩惧�兼眰浣欎嚎閮ㄥ垎
+        // Value2     褰撳墠鍓╀綑鐩惧�兼暣闄や嚎閮ㄥ垎
+        return GetBuffValue(BattleConst.ShieldBuffAttackType);
+    }
+    
+    public long GetBuffValue(int buffAtkType)
+    {
+
+        long values = 0;
+        foreach (var kv in buffDataDict)
+        {
+            HB428_tagSCBuffRefresh hB428_TagSCBuffRefresh = kv.Value;
+            SkillConfig skillConfig = SkillConfig.Get((int)hB428_TagSCBuffRefresh.SkillID);
+            if (null != skillConfig && skillConfig.AtkType == buffAtkType)
+            {
+                values += GeneralDefine.GetFactValue(hB428_TagSCBuffRefresh.Value1, hB428_TagSCBuffRefresh.Value2);
+            }
+        }
+        return values;
+    }
+
     public void InsertBuff(HB428_tagSCBuffRefresh vNetData)
     {
         RefreshBuff(vNetData, true);
diff --git a/Main/System/Battle/Define/BattleDmgInfo.cs b/Main/System/Battle/Define/BattleDmgInfo.cs
index f1b8588..42ba730 100644
--- a/Main/System/Battle/Define/BattleDmgInfo.cs
+++ b/Main/System/Battle/Define/BattleDmgInfo.cs
@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using UnityEngine;
 
 public class BattleDmg
 {
@@ -11,42 +12,43 @@
     }
 }
 
-
 public class BattleDmgInfo
 {
-
     public string battleFieldGuid { get; private set; }
-
     public BattleHurtParam battleHurtParam { get; private set; }
+    
     public List<long> damageList { get { return battleHurtParam.damageList; } }
     public BattleObject hurtObj { get { return battleHurtParam.hurtObj; } }
-
     public BattleObject casterObj { get { return battleHurtParam.casterObj; } }
-
     public HB427_tagSCUseSkill.tagSCUseSkillHurt hurt { get { return battleHurtParam.hurt; } }
-
     public SkillConfig skillConfig { get { return battleHurtParam.skillConfig; } }
 
-    //  鏄惁琚牸鎸′簡
     public bool isBlocked = false;
-
     public bool isLastHit = false;
 
     public List<BattleDmg> targetDamageList = new List<BattleDmg>();
-
     public List<BattleDmg> casterDamageList = new List<BattleDmg>();
+
+    #region Initialization
 
     public BattleDmgInfo(string battleFieldGuid, BattleHurtParam battleHurtParam)
     {
         this.battleFieldGuid = battleFieldGuid;
         this.battleHurtParam = battleHurtParam;
         this.isLastHit = battleHurtParam.hitIndex >= battleHurtParam.skillConfig.DamageDivide.Length - 1;
+        
         HandleDamageType();
         HandleAttackTypeAndDamage();
     }
 
+    #endregion
+
+    #region Damage Type Processing
+
     private void HandleDamageType()
     {
+        if (hurt == null) return;
+        
         int attackTypes = 0;
         foreach (ServerDamageType serverDamageType in System.Enum.GetValues(typeof(ServerDamageType)))
         {
@@ -59,111 +61,178 @@
         hurt.AttackTypes = (uint)attackTypes;
     }
 
+    #endregion
+
+    #region Damage List Generation
+
     private void HandleAttackTypeAndDamage()
     {
         isBlocked = HaveBlockDamage();
-        int rawAttackType = (int)hurt.AttackTypes;
-        float blockRatio = GeneralDefine.blockRatio; // 鏍兼尅鍑忎激鐜�
+        int rawAttackType = hurt == null ? 0 : (int)hurt.AttackTypes;
+        
+        int maxCount = CalculateMaxDamageSegmentCount();
 
-        // 澶勭悊姣忎竴娈典激瀹冲強鍏跺搴旂殑鍙嶄激鍜屽惛琛�
-        for (int i = 0; i < damageList.Count; i++)
+        for (int i = 0; i < maxCount; i++)
         {
-            long actualDamage = damageList[i];
-
-            // ============ 1. 鍏堝鐞嗗綋鍓嶆瀵瑰簲鐨勫弽浼� ============
-            if (battleHurtParam.reflectHpList != null && i < battleHurtParam.reflectHpList.Count)
-            {
-                long reflectHp = battleHurtParam.reflectHpList[i];
-                if (reflectHp > 0)
-                {
-                    casterDamageList.Add(new BattleDmg 
-                    { 
-                        damage = reflectHp, 
-                        attackType = (int)DamageType.Reflect 
-                    });
-                }
-            }
-
-            // ============ 2. 鐒跺悗澶勭悊褰撳墠娈靛搴旂殑鍚歌 ============
-            if (battleHurtParam.suckHpList != null && i < battleHurtParam.suckHpList.Count)
-            {
-                long suckHp = battleHurtParam.suckHpList[i];
-                if (suckHp > 0)
-                {
-                    casterDamageList.Add(new BattleDmg 
-                    { 
-                        damage = suckHp, 
-                        attackType = (int)DamageType.SuckHP 
-                    });
-                }
-            }
-
-            // ============ 3. 鏈�鍚庡鐞嗕富瑕佷激瀹� ============
-            // 鏍兼尅澶勭悊
-            if (isBlocked)
-            {
-                // 鍘绘帀鏍兼尅绫诲瀷
-                int attackType = rawAttackType & (~(int)DamageType.Block);
-
-                // 璁$畻鏍兼尅浼ゅ
-                long totalDamage = (long)(actualDamage / (1 - blockRatio));
-                long blockDmg = totalDamage - actualDamage;
-                targetDamageList.Add(new BattleDmg { damage = blockDmg, attackType = (int)DamageType.Block });
-
-                // 鐪熷疄浼ゅ鐗规畩澶勭悊
-                if (IsRealdamage())
-                {
-                    int showAttackType = (int)DamageType.Realdamage + (IsCrit() ? (int)DamageType.Crit : 0);
-                    targetDamageList.Add(new BattleDmg { damage = actualDamage, attackType = showAttackType });
-                }
-                else
-                {
-                    // 鏅�氫激瀹�/娌荤枟澶勭悊
-                    if (DamageNumConfig.Get(attackType) == null)
-                    {
-                        UnityEngine.Debug.LogError($"鏈嶅姟鍣ㄧ粰鐨勪激瀹崇被鍨嬩笉瀵癸紝寮哄埗杞崲涓烘櫘閫氫激瀹�/娌荤枟, attackType: {attackType}");
-                        if ((attackType & (int)DamageType.Damage) != 0)
-                            attackType = (int)DamageType.Damage;
-                        else if ((attackType & (int)DamageType.Recovery) != 0)
-                            attackType = (int)DamageType.Recovery;
-                        else
-                            UnityEngine.Debug.LogError($"寮哄埗杞崲澶辫触锛岃绫诲瀷涓嶆槸娌荤枟涔熶笉鏄激瀹� {attackType}");
-                    }
-                    targetDamageList.Add(new BattleDmg { damage = actualDamage, attackType = attackType });
-                }
-            }
-            else
-            {
-                int attackType = rawAttackType;
-
-                // 鐪熷疄浼ゅ鐗规畩澶勭悊
-                if (IsRealdamage())
-                {
-                    int showAttackType = (int)DamageType.Realdamage + (IsCrit() ? (int)DamageType.Crit : 0);
-                    targetDamageList.Add(new BattleDmg { damage = actualDamage, attackType = showAttackType });
-                }
-                else
-                {
-                    // 鏅�氫激瀹�/娌荤枟澶勭悊
-                    if (DamageNumConfig.Get(attackType) == null)
-                    {
-                        UnityEngine.Debug.LogError($"鏈嶅姟鍣ㄧ粰鐨勪激瀹崇被鍨嬩笉瀵癸紝寮哄埗杞崲涓烘櫘閫氫激瀹�/娌荤枟, attackType: {attackType}");
-                        if ((attackType & (int)DamageType.Damage) != 0)
-                            attackType = (int)DamageType.Damage;
-                        else if ((attackType & (int)DamageType.Recovery) != 0)
-                            attackType = (int)DamageType.Recovery;
-                        else
-                            UnityEngine.Debug.LogError($"寮哄埗杞崲澶辫触锛岃绫诲瀷涓嶆槸娌荤枟涔熶笉鏄激瀹� {attackType}");
-                    }
-                    targetDamageList.Add(new BattleDmg { damage = actualDamage, attackType = attackType });
-                }
-            }
+            ProcessReflectDamage(i);
+            ProcessSuckHpDamage(i);
+            ProcessMainDamage(i, rawAttackType);
         }
     }
 
+    /// <summary>
+    /// 璁$畻鏈�澶т激瀹虫鏁�
+    /// </summary>
+    private int CalculateMaxDamageSegmentCount()
+    {
+        int maxCount = damageList != null ? damageList.Count : 0;
+        maxCount = Mathf.Max(maxCount, battleHurtParam.suckHpList != null ? battleHurtParam.suckHpList.Count : 0);
+        maxCount = Mathf.Max(maxCount, battleHurtParam.reflectHpList != null ? battleHurtParam.reflectHpList.Count : 0);
+        return maxCount;
+    }
+
+    /// <summary>
+    /// 澶勭悊鍙嶄激浼ゅ
+    /// </summary>
+    private void ProcessReflectDamage(int segmentIndex)
+    {
+        if (battleHurtParam.reflectHpList == null || segmentIndex >= battleHurtParam.reflectHpList.Count)
+            return;
+
+        long reflectHp = battleHurtParam.reflectHpList[segmentIndex];
+        if (reflectHp > 0)
+        {
+            casterDamageList.Add(new BattleDmg
+            {
+                damage = reflectHp,
+                attackType = (int)DamageType.Reflect
+            });
+        }
+    }
+
+    /// <summary>
+    /// 澶勭悊鍚歌浼ゅ
+    /// </summary>
+    private void ProcessSuckHpDamage(int segmentIndex)
+    {
+        if (battleHurtParam.suckHpList == null || segmentIndex >= battleHurtParam.suckHpList.Count)
+            return;
+
+        long suckHp = battleHurtParam.suckHpList[segmentIndex];
+        if (suckHp > 0)
+        {
+            casterDamageList.Add(new BattleDmg
+            {
+                damage = suckHp,
+                attackType = (int)DamageType.SuckHP
+            });
+        }
+    }
+
+    /// <summary>
+    /// 澶勭悊涓昏浼ゅ
+    /// </summary>
+    private void ProcessMainDamage(int segmentIndex, int rawAttackType)
+    {
+        if (damageList == null || segmentIndex >= damageList.Count)
+            return;
+
+        long actualDamage = damageList[segmentIndex];
+
+        if (isBlocked)
+        {
+            ProcessBlockedDamage(actualDamage, rawAttackType);
+        }
+        else
+        {
+            ProcessNormalDamage(actualDamage, rawAttackType);
+        }
+    }
+
+    /// <summary>
+    /// 澶勭悊琚牸鎸$殑浼ゅ
+    /// </summary>
+    private void ProcessBlockedDamage(long actualDamage, int rawAttackType)
+    {
+        float blockRatio = GeneralDefine.blockRatio;
+        int attackType = rawAttackType & (~(int)DamageType.Block);
+
+        // 娣诲姞鏍兼尅浼ゅ鏄剧ず
+        long totalDamage = (long)(actualDamage / (1 - blockRatio));
+        long blockDmg = totalDamage - actualDamage;
+        targetDamageList.Add(new BattleDmg { damage = blockDmg, attackType = (int)DamageType.Block });
+
+        // 娣诲姞瀹為檯浼ゅ鏄剧ず
+        if (IsRealdamage())
+        {
+            AddRealdamageToList(actualDamage);
+        }
+        else
+        {
+            AddNormalDamageToList(actualDamage, attackType);
+        }
+    }
+
+    /// <summary>
+    /// 澶勭悊姝e父浼ゅ锛堟湭琚牸鎸★級
+    /// </summary>
+    private void ProcessNormalDamage(long actualDamage, int rawAttackType)
+    {
+        if (IsRealdamage())
+        {
+            AddRealdamageToList(actualDamage);
+        }
+        else
+        {
+            AddNormalDamageToList(actualDamage, rawAttackType);
+        }
+    }
+
+    /// <summary>
+    /// 娣诲姞鐪熷疄浼ゅ鍒板垪琛�
+    /// </summary>
+    private void AddRealdamageToList(long damage)
+    {
+        int showAttackType = (int)DamageType.Realdamage + (IsCrit() ? (int)DamageType.Crit : 0);
+        targetDamageList.Add(new BattleDmg { damage = damage, attackType = showAttackType });
+    }
+
+    /// <summary>
+    /// 娣诲姞鏅�氫激瀹�/娌荤枟鍒板垪琛�
+    /// </summary>
+    private void AddNormalDamageToList(long damage, int attackType)
+    {
+        attackType = ValidateAndFixAttackType(attackType);
+        targetDamageList.Add(new BattleDmg { damage = damage, attackType = attackType });
+    }
+
+    /// <summary>
+    /// 楠岃瘉骞朵慨澶嶆敾鍑荤被鍨�
+    /// </summary>
+    private int ValidateAndFixAttackType(int attackType)
+    {
+        if (DamageNumConfig.Get(attackType) != null)
+            return attackType;
+
+        UnityEngine.Debug.LogError($"鏈嶅姟鍣ㄧ粰鐨勪激瀹崇被鍨嬩笉瀵癸紝寮哄埗杞崲涓烘櫘閫氫激瀹�/娌荤枟, attackType: {attackType}");
+
+        if ((attackType & (int)DamageType.Damage) != 0)
+            return (int)DamageType.Damage;
+
+        if ((attackType & (int)DamageType.Recovery) != 0)
+            return (int)DamageType.Recovery;
+
+        UnityEngine.Debug.LogError($"寮哄埗杞崲澶辫触锛岃绫诲瀷涓嶆槸娌荤枟涔熶笉鏄激瀹� {attackType}");
+        return attackType;
+    }
+
+    #endregion
+
+    #region Type Checking
+
     public bool IsType(DamageType damageType)
     {
-        return (hurt.AttackTypes & (int)damageType) == (int)damageType;
+        return hurt != null && (hurt.AttackTypes & (int)damageType) == (int)damageType;
     }
 
     public bool IsCrit()
@@ -181,6 +250,12 @@
         return skillConfig.HurtType / 10 == 1;
     }
 
+    public bool IsDamage()
+    {
+        return IsType(DamageType.Damage) || IsRealdamage() || IsType((DamageType)11) || IsType((DamageType)12);
+    }
+
+    #endregion
 }
 
 public class BattleHurtParam
@@ -191,17 +266,87 @@
     public List<long> suckHpList;
     public List<long> reflectHpList;
 
+    public long fromShieldValue;
+    public long toShieldValue;
     public long fromHp;
-
     public long toHp;
 
     public BattleDrops battleDrops;
-
     public HB427_tagSCUseSkill.tagSCUseSkillHurt hurt;
-
     public int hitIndex;
-
     public HB422_tagMCTurnFightObjDead deadPack;
-
     public SkillConfig skillConfig;
+    public long maxHp;
+
+    #region Shield Value Calculations
+
+    public long MaxSheildValue
+    {
+        get
+        {
+            return hurtObj == null ? 0 : hurtObj.teamHero.maxHp;
+        }
+    }
+
+    public long phase1FromShieldValue
+    {
+        get
+        {
+            if (fromShieldValue > 0)
+            {
+                return Mathf.Min((int)fromShieldValue, (int)MaxSheildValue);
+            }
+            else
+            {
+                return 0;
+            }
+        }
+    }
+
+    public long phase1ToShieldValue
+    {
+        get
+        {
+            if (toShieldValue > 0)
+            {
+                return Mathf.Min((int)toShieldValue, (int)MaxSheildValue);
+            }
+            else
+            {
+                return 0;
+            }
+        }
+    }
+
+    public long phase2FromShieldValue
+    {
+        get
+        {
+            if (fromShieldValue > MaxSheildValue)
+            {
+                return fromShieldValue - MaxSheildValue;
+            }
+            else
+            {
+                return 0;
+            }
+        }
+    }
+
+    public long phase2ToShieldValue
+    {
+        get
+        {
+            if (toShieldValue > MaxSheildValue)
+            {
+                return toShieldValue - MaxSheildValue;
+            }
+            else
+            {
+                return 0;
+            }
+        }
+    }
+
+    #endregion
 }
\ No newline at end of file
diff --git a/Main/System/Battle/Define/DamageType.cs b/Main/System/Battle/Define/DamageType.cs
index c0c7ffb..84ea0be 100644
--- a/Main/System/Battle/Define/DamageType.cs
+++ b/Main/System/Battle/Define/DamageType.cs
@@ -12,11 +12,23 @@
 //	鏈嶅姟鍣ㄦ嫢鏈夌殑DamageType
 public enum ServerDamageType
 {
-	Damage = 2,
-	Recovery = 4,
-	Block = 32,
-	Crit = 128,
-	Dodge = 512
+	Damage = 2,//鏅�氫激瀹�
+	Recovery = 4,//娌荤枟
+
+	Immune = 16,//鍏嶇柅
+
+	Block = 32, //鏍兼尅
+
+	Realdamage = 64, //鐪熶激
+	Crit = 128, //鏆村嚮
+
+	Dodge = 256, //闂伩
+
+	DamageReverse = 512,//浼ゅ鍙嶈浆涓烘不鐤�
+
+	SuckHpReverse = 1024,//鍚歌鍙嶈浆涓轰激瀹�
+
+	SelfHarm = 2048,//鑷畫
 }
 
 public enum DamageType
diff --git a/Main/System/Battle/Skill/SkillBase.cs b/Main/System/Battle/Skill/SkillBase.cs
index db28983..0caf1c4 100644
--- a/Main/System/Battle/Skill/SkillBase.cs
+++ b/Main/System/Battle/Skill/SkillBase.cs
@@ -390,18 +390,18 @@
         List<BattleObject> targetList = battleField.battleObjMgr.GetBattleObjList(tagUseSkillAttack);
         List<BattleObject> highlightList = new List<BattleObject>(targetList) { caster };
         List<BattleObject> allList = battleField.battleObjMgr.allBattleObjDict.Values.ToList<BattleObject>();
-        
+
         // 淇锛氫娇鐢℉ashSet浼樺寲鎬ц兘锛岄伩鍏嶉噸澶嶈缃�
         var targetSet = new HashSet<BattleObject>(targetList);
         var highlightSet = new HashSet<BattleObject>(highlightList);
-        
+
         caster.heroInfoBar.SetActive(false);
 
         foreach (BattleObject bo in allList)
         {
             bool isHighlight = highlightSet.Contains(bo);
             bool isTarget = targetSet.Contains(bo);
-            
+
             if (isHighlight)
             {
                 bo.layerMgr.SetFront();
@@ -418,14 +418,23 @@
         // battleField.battleRootNode.SetSortingOrder();
     }
 
+    protected long suckHp = 0;
+
     // 鍛戒腑鐩爣鍥炶皟锛氬鐞嗘墍鏈夎鍛戒腑鐨勭洰鏍�
     protected virtual void OnHitTargets(int _hitIndex, List<HB427_tagSCUseSkill.tagSCUseSkillHurt> hitList)
     {
         //  閫犳垚浼ゅ鍓嶅厛澶勭悊琛�閲忓埛鏂板寘
         HandleRefreshHP();
 
+        suckHp = 0;
+
         foreach (var hurt in hitList)
         {
+            suckHp += hurt.SuckHP;
+        }
+
+        foreach (var hurt in hitList)
+        { 
             BattleObject target = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
             if (target == null)
             {
@@ -436,6 +445,46 @@
             OnHitEachTarget(_hitIndex, target, hurt);
         }
     }
+
+    // protected void RecoveryHp(long suckHp, int _hitIndex)
+    // {
+    //     // long suckHp = hurt.SuckHP;
+
+    //     if (suckHp <= 0)
+    //     {
+    //         return;
+    //     }
+
+    //     List<long> suckHpList = BattleUtility.DivideDamageToList(skillConfig.DamageDivide, _hitIndex, suckHp);
+
+    //     long currentHitSuckHp = 0;
+    //     foreach (long suck in suckHpList)
+    //     {
+    //         currentHitSuckHp += suck;
+    //     }
+
+    //     long fromHp = caster.teamHero.curHp;
+    //     long toHp = caster.teamHero.curHp + currentHitSuckHp;
+
+    //             //  鍙傛暟鎵撳寘
+    //     BattleHurtParam hurtParam = new BattleHurtParam()
+    //     {
+    //         casterObj = caster,
+    //         hurtObj = null,
+    //         damageList = new List<long>(),
+    //         suckHpList = suckHpList, 
+    //         reflectHpList = new List<long>(),
+    //         fromHp = fromHp,
+    //         toHp = toHp,
+    //         battleDrops = null,
+    //         hurt = null,
+    //         hitIndex = _hitIndex,
+    //         deadPack = null,
+    //         skillConfig = skillConfig
+    //     };
+
+    //     caster.Hurt(hurtParam);
+    // }
 
     // 澶勭悊鍗曚釜鐩爣琚懡涓�:搴旂敤浼ゅ鍜屾柦娉曡�呮晥鏋�
     protected virtual void OnHitEachTarget(int _hitIndex, BattleObject target, HB427_tagSCUseSkill.tagSCUseSkillHurt hurt)
@@ -463,17 +512,20 @@
         long totalDamage = GeneralDefine.GetFactValue(hurt.HurtHP, hurt.HurtHPEx);
         List<long> damageList = BattleUtility.DivideDamageToList(skillConfig.DamageDivide, _hitIndex, totalDamage);
 
+        long totalSuckHp = suckHp;
+        List<long> suckHpList = BattleUtility.DivideDamageToList(skillConfig.DamageDivide, _hitIndex, totalSuckHp);
+
+
         // ============ 绗簩姝�:鍒锋柊瀹為檯琛�閲� ============
         long fromHp = target.teamHero.curHp;
         
 
 
-        // ============澶勭悊鍚歌璺熷弽浼� ===============
+        // ============澶勭悊鍙嶄激 ===============
         //  涔熻鎸夋瘡涓�鍑诲钩鍧囩畻 鏈�鍚庤琛ラ綈浼ゅ
-        long suckHp = hurt.SuckHP;
+
         long reflectHp = hurt.BounceHP;
 
-        List<long> suckHpList = BattleUtility.DivideDamageToList(skillConfig.DamageDivide, _hitIndex, suckHp);
 
         List<long> reflectHpList = BattleUtility.DivideDamageToList(skillConfig.DamageDivide, _hitIndex, reflectHp);
         // long currentSuckHp = suckHp / tagUseSkillAttack.HurtCount;
@@ -485,11 +537,7 @@
             currentHitDamage += dmg;
         }
 
-        long currentHitSuckHp = 0;
-        foreach (long suck in suckHpList)
-        {
-            currentHitSuckHp += suck;
-        }
+
 
         long currentHitReflectHp = 0;
         foreach (long reflect in reflectHpList)
@@ -497,7 +545,50 @@
             currentHitReflectHp += reflect;
         }
 
-        long toHp = Math.Max(0, fromHp - currentHitDamage);
+        long shieldValue = target.buffMgr.GetShieldValue();
+
+        long remainSheild = shieldValue - currentHitDamage;
+
+        long toShieldValue = Math.Max(0, shieldValue - currentHitDamage);
+
+        long shieldRecieveDamage = shieldValue - toShieldValue;
+
+        // if (shieldValue > 0 && remainSheild >= 0)
+        // {
+        //     currentHitDamage = 0;
+        //     target.buffMgr.ReduceShieldValue(currentHitDamage);
+        // }
+        // else if (shieldValue > 0 && remainSheild < 0)
+        // {
+        //     currentHitDamage = Math.Abs(remainSheild);
+        //     target.buffMgr.ClearShield();
+        // }
+
+        long toHp = fromHp; //Math.Max(0, fromHp - currentHitDamage);
+
+
+        // 鍒ゆ柇鏄不鐤楄繕鏄激瀹�
+        bool isHealing = ((hurt.AttackTypes & (int)ServerDamageType.Recovery) != 0 || 
+                          (hurt.AttackTypes & (int)ServerDamageType.DamageReverse) != 0) &&
+                         (hurt.AttackTypes & (int)ServerDamageType.Damage) == 0 &&
+                         (hurt.AttackTypes & (int)ServerDamageType.Realdamage) == 0 &&
+                         (hurt.AttackTypes & (int)ServerDamageType.SuckHpReverse) == 0 &&
+                         (hurt.AttackTypes & (int)ServerDamageType.SelfHarm) == 0;
+
+        if (isHealing)
+        {
+            // 娌荤枟閫昏緫锛氱洿鎺ュ姞琛�锛屼笉鑰冭檻鎶ょ浘
+            toHp = Math.Min(target.teamHero.maxHp, fromHp + currentHitDamage);
+        }
+        else
+        {
+            // 浼ゅ閫昏緫锛氬厛鎵f姢鐩撅紝鍐嶆墸琛�
+            if (remainSheild < 0)
+            {
+                // 鐩捐鎵撶牬
+                toHp = Math.Max(0, fromHp + remainSheild);
+            }
+        }
 
 
         // 鏇存柊鐩爣琛�閲�
@@ -505,12 +596,14 @@
 
 #if UNITY_EDITOR
         BattleDebug.LogError(
-            (caster.Camp == BattleCamp.Red ? "銆愮孩鏂硅鍔ㄣ��" : "銆愯摑鏂硅鍔ㄣ��") + "\n" +
+            (caster.Camp == BattleCamp.Red ? "銆愮孩鏂硅鍔ㄣ��" : "銆愯摑鏂硅鍔ㄣ�� ") +
             $"鏀诲嚮鑰�: {caster.teamHero.name}\n" +
             $"鐩爣: {target.teamHero.name}\n" +
             $"鎶�鑳�: {skillConfig.SkillName} (绗瑊_hitIndex}鍑�)\n" +
-            $"浼ゅ: {currentHitDamage} (鎬讳激瀹�: {totalDamage})\n" +
-            $"鍚歌: {currentHitSuckHp}\n" +
+            $"浼ゅ: {currentHitDamage} 瀹為檯鍙楀埌浼ゅ: {fromHp-toHp} (鎬讳激瀹�: {totalDamage})\n" +
+            $"鎵夸激鍓嶆姢鐩惧��: {shieldValue}\n" +
+            $"鎵夸激鍚庢姢鐩惧��: {toShieldValue}\n" +
+            $"鎶ょ浘鎵垮彈浼ゅ: {shieldRecieveDamage}\n" +
             $"鍙嶄激: {currentHitReflectHp}\n" +
             $"琛�閲忓彉鍖�: {fromHp} -> {toHp}\n" +
             $"鎶�鑳藉寘閲岀殑琛�閲忔槸: {GeneralDefine.GetFactValue(hurt.CurHP, hurt.CurHPEx)}\n"
@@ -532,10 +625,13 @@
             casterObj = caster,
             hurtObj = target,
             damageList = damageList,
-            suckHpList = suckHpList,
+            suckHpList = suckHpList, //suckHpList,
             reflectHpList = reflectHpList,
             fromHp = fromHp,
             toHp = toHp,
+            maxHp = target.teamHero.maxHp,
+            fromShieldValue = shieldValue,
+            toShieldValue = toShieldValue,
             battleDrops = battleDrops,
             hurt = hurt,
             hitIndex = _hitIndex,
diff --git a/Main/System/Battle/UIComp/BattleFloatingUIController.cs b/Main/System/Battle/UIComp/BattleFloatingUIController.cs
index 64df818..ee2ccc2 100644
--- a/Main/System/Battle/UIComp/BattleFloatingUIController.cs
+++ b/Main/System/Battle/UIComp/BattleFloatingUIController.cs
@@ -288,7 +288,7 @@
             applyColorCallback?.Invoke(GetEndColor());
         }
     }
-    
+
     /// <summary>
     /// 鍔ㄧ敾瀹屾垚鍥炶皟
     /// </summary>
@@ -299,5 +299,10 @@
         onFinishCallback = null;
     }
     
+    public bool IsValid()
+    {
+        return ValidateConfig() && rectTransform != null && gameObject != null;
+    }
+
     #endregion
 }
\ No newline at end of file
diff --git a/Main/System/Battle/UIComp/BattleHeroInfoBar.cs b/Main/System/Battle/UIComp/BattleHeroInfoBar.cs
index 766e9ab..9b60749 100644
--- a/Main/System/Battle/UIComp/BattleHeroInfoBar.cs
+++ b/Main/System/Battle/UIComp/BattleHeroInfoBar.cs
@@ -10,8 +10,6 @@
 /// </summary>
 public class BattleHeroInfoBar : MonoBehaviour
 {
-    #region 鍐呴儴绫�
-    
     /// <summary>
     /// 椋樺瓧淇℃伅閰嶇疆
     /// </summary>
@@ -26,13 +24,23 @@
         public bool isDebuff = false;      // 鏄惁鏄礋鍚� Buff锛堝喅瀹氱敤鍝釜棰滆壊锛�
     }
     
-    #endregion
-
-    #region Inspector瀛楁
+    /// <summary>
+    /// 琛�鏉℃洿鏂拌姹�
+    /// </summary>
+    private class HpUpdateRequest
+    {
+        public long fromHp;
+        public long toHp;
+        public long maxHp;
+        public bool tween;
+    }
     
     [Header("UI Components")]
     public Slider sliderHp;
     public Slider sliderXp;
+    public GameObject maxXpGO;
+    public Slider sliderShield1;
+    public Slider sliderShield2;
     public BasicHeroInfoContainer heroInfoContainer;
     public BattleTips textTips;
     
@@ -46,15 +54,7 @@
     [Tooltip("涓嶈窡闅忚鑹茬殑椋樺瓧閰嶇疆锛堝浐瀹氬湪鎴樺満鑺傜偣锛�")]
     public FloatingConfig noFollowFloatingConfig;
     
-    [Header("Settings")]
-    public float PopUpInterval = 0.2f;
-    
-    #endregion
-
-    #region 绉佹湁瀛楁
-    
     protected BattleObject battleObject;
-    protected float timer = 0f;
     
     protected List<TipsInfo> messages = new List<TipsInfo>();
     protected List<BattleTips> tipsList = new List<BattleTips>();
@@ -62,19 +62,21 @@
     
     protected Tween hpTween;
     protected Tween xpTween;
+    protected Tween shieldTween1;
+    protected Tween shieldTween2;
+    protected Sequence damageSequence;
     
-    #endregion
-
-    #region Unity鐢熷懡鍛ㄦ湡
+    private Queue<HpUpdateRequest> hpUpdateQueue = new Queue<HpUpdateRequest>();
+    private Queue<BattleDmgInfo> damageUpdateQueue = new Queue<BattleDmgInfo>();
+    
+    // 椋樺瓧GCD鐩稿叧
+    private float tipsGCDTimer = 0f;
+    private const int TIPS_GCD_FRAMES = 5;
     
     protected void OnDisable()
     {
         CleanupTips();
     }
-    
-    #endregion
-
-    #region 鍏叡鏂规硶 - 鍒濆鍖�
     
     public void SetBattleObject(BattleObject _battleObject)
     {
@@ -83,16 +85,19 @@
         RefreshBuff(battleObject.buffMgr.GetBuffList());
         UpdateHP(battleObject.teamHero.curHp, battleObject.teamHero.curHp, battleObject.teamHero.maxHp, false);
         UpdateXP(battleObject.teamHero.rage, battleObject.teamHero.rage, 100, false);
+
+        long shieldValue = battleObject.buffMgr.GetShieldValue();
+        long maxHp = battleObject.teamHero.maxHp;
+        //  绗竴鏉℃姢鐩剧殑鍊兼渶澶у�兼槸褰撳墠鐨凪axHp 绗簩鏉℃姢鐩剧殑鏈�澶у�煎叾瀹炰篃鏄疢axHp 澶氫綑鐨勪笉鍋氭樉绀�
+
+        sliderShield1.value = maxHp > 0 ? Mathf.Min((float)shieldValue, (float)maxHp) / (float)maxHp : 0;
+        sliderShield2.value = maxHp > 0 ? Mathf.Max((float)(shieldValue - maxHp), 0f) / (float)maxHp : 0;
     }
     
     public void SetActive(bool active)
     {
         gameObject.SetActive(active);
     }
-    
-    #endregion
-
-    #region 鍏叡鏂规硶 - Buff绠$悊
     
     public void RefreshBuff(List<HB428_tagSCBuffRefresh> datas)
     {
@@ -111,11 +116,14 @@
                 buffCells[i].SetActive(false);
             }
         }
-    }
-    
-    #endregion
 
-    #region 鍏叡鏂规硶 - 椋樺瓧绠$悊
+        //  check shield buff
+        long shieldValue = battleObject.buffMgr.GetShieldValue();
+        long maxHp = battleObject.teamHero.maxHp;
+        //  绗竴鏉℃姢鐩剧殑鍊兼渶澶у�兼槸褰撳墠鐨凪axHp 绗簩鏉℃姢鐩剧殑鏈�澶у�煎叾瀹炰篃鏄疢axHp 澶氫綑鐨勪笉鍋氭樉绀�
+        sliderShield1.value = maxHp > 0 ? Mathf.Min((float)shieldValue, (float)maxHp) / (float)maxHp : 0;
+        sliderShield2.value = maxHp > 0 ? Mathf.Max((float)(shieldValue - maxHp), 0f) / (float)maxHp : 0;
+    }
     
     /// <summary>
     /// 娣诲姞椋樺瓧鍒伴槦鍒�
@@ -139,24 +147,34 @@
         messages.Add(tipsInfo);
     }
     
-    #endregion
-
-    #region 鍏叡鏂规硶 - 鏁板�兼洿鏂�
-    
     /// <summary>
     /// 鏇存柊琛�閲忔樉绀�
     /// </summary>
     public void UpdateHP(long fromHp, long toHp, long maxHp, bool tween = true)
     {
+        // 鍔犲叆闃熷垪
+        hpUpdateQueue.Enqueue(new HpUpdateRequest
+        {
+            fromHp = fromHp,
+            toHp = toHp,
+            maxHp = maxHp,
+            tween = tween
+        });
+    }
+
+    /// <summary>
+    /// 瀹為檯鎵ц琛�閲忔洿鏂�
+    /// </summary>
+    private void ExecuteHpUpdate(HpUpdateRequest request)
+    {
         KillTween(ref hpTween);
         
-        float fromValue = (float)fromHp / (float)maxHp;
-        float targetValue = (float)toHp / (float)maxHp;
+        float fromValue = (float)request.fromHp / (float)request.maxHp;
+        float targetValue = (float)request.toHp / (float)request.maxHp;
         
-        if (tween)
+        if (request.tween)
         {
-            // 鍏抽敭淇:鍏堣缃捣濮嬪��,鍐嶆挱鏀惧姩鐢诲埌鐩爣鍊�
-            sliderHp.value = fromValue;  // 鈫� 杩欒鏄叧閿�!
+            sliderHp.value = fromValue;
             hpTween = sliderHp.DOValue(targetValue, 0.3f).SetAutoKill(false);
             battleObject.battleField.battleTweenMgr.OnPlayTween(hpTween);
         }
@@ -181,37 +199,116 @@
     public void UpdateXP(long fromXp, long toXp, long maxXp, bool tween = true)
     {
         KillTween(ref xpTween);
-        
+
         float fromValue = (float)fromXp / (float)maxXp;
         float targetValue = (float)toXp / (float)maxXp;
-        
+
         if (tween)
         {
-            // 鍚屾牱鐨勪慨澶�
             sliderXp.value = fromValue;
             xpTween = sliderXp.DOValue(targetValue, 0.2f).SetAutoKill(false);
+            xpTween.OnComplete(() =>
+            {
+                if (toXp >= maxXp)
+                {
+                    maxXpGO.SetActive(true);
+                }
+                else
+                {
+                    maxXpGO.SetActive(false);
+                }
+            });
             battleObject.battleField.battleTweenMgr.OnPlayTween(xpTween);
         }
         else
         {
+            if (toXp >= maxXp)
+            {
+                maxXpGO.SetActive(true);
+            }
+            else
+            {
+                maxXpGO.SetActive(false);
+            }
             sliderXp.value = targetValue;
         }
     }
-    
-    #endregion
 
-    #region 鍏叡鏂规硶 - 杩愯鏃舵洿鏂�
+    /// <summary>
+    /// 鎾斁琛�鏉� 鎶ょ浘鐨勫彉鍖�
+    /// </summary>
+    public void UpdateDamage(BattleDmgInfo dmgInfo)
+    {
+        // 鍔犲叆闃熷垪
+        damageUpdateQueue.Enqueue(dmgInfo);
+    }
+
+    /// <summary>
+    /// 瀹為檯鎵ц浼ゅ鏇存柊
+    /// </summary>
+    private void ExecuteDamageUpdate(BattleDmgInfo dmgInfo)
+    {
+        KillTween(ref damageSequence);
+
+        long maxHp = dmgInfo.battleHurtParam.maxHp;
+        long fromShield = dmgInfo.battleHurtParam.fromShieldValue;
+        long toShield = dmgInfo.battleHurtParam.toShieldValue;
+
+        if (maxHp <= 0)
+        {
+            sliderShield1.value = 0;
+            sliderShield2.value = 0;
+            return;
+        }
+
+        //  绗竴鏉℃姢鐩剧殑鍊兼渶澶у�兼槸褰撳墠鐨凪axHp 绗簩鏉℃姢鐩剧殑鏈�澶у�煎叾瀹炰篃鏄疢axHp 澶氫綑鐨勪笉鍋氭樉绀�
+        float fromValue1 = (float)dmgInfo.battleHurtParam.phase1FromShieldValue / (float)maxHp;
+        float targetValue1 = (float)dmgInfo.battleHurtParam.phase1ToShieldValue / (float)maxHp;
+
+        float fromValue2 = (float)dmgInfo.battleHurtParam.phase2FromShieldValue / (float)maxHp;
+        float targetValue2 = (float)dmgInfo.battleHurtParam.phase2ToShieldValue / (float)maxHp;
+
+        damageSequence = DOTween.Sequence();
+
+        sliderShield2.value = fromValue2;
+        if (fromValue2 > 0  && fromValue2 != targetValue2)
+        {
+            damageSequence.Append(sliderShield2.DOValue(targetValue2, 0.2f));
+        }
+
+        sliderShield1.value = fromValue1;
+        if (fromValue1 > 0 && fromValue1 != targetValue1)
+        {
+            damageSequence.Append(sliderShield1.DOValue(targetValue1, 0.2f));
+        }
+
+        if (dmgInfo.battleHurtParam.fromHp != dmgInfo.battleHurtParam.toHp)
+        {
+            float fromHpValue = (float)dmgInfo.battleHurtParam.fromHp / (float)maxHp;
+            float toHpValue = (float)dmgInfo.battleHurtParam.toHp / (float)maxHp;
+
+            sliderHp.value = fromHpValue;
+            damageSequence.Append(sliderHp.DOValue(toHpValue, 0.2f));
+        }
+
+        damageSequence.Play();
+
+        battleObject.battleField.battleTweenMgr.OnPlayTween(damageSequence);
+    }
     
     /// <summary>
     /// 姣忓抚鏇存柊
     /// </summary>
     public void Run()
     {
+        // 澶勭悊琛�鏉″拰浼ゅ闃熷垪
+        UpdateHpAndDamageQueue();
+        
+        // 鏇存柊椋樺瓧GCD骞跺鐞嗛槦鍒�
+        UpdateTipsGCDAndQueue();
+        
         // 鏇存柊鎵�鏈夐瀛�
         UpdateActiveTips();
-        
-        // 澶勭悊椋樺瓧闃熷垪
-        ProcessTipsQueue();
     }
 
     /// <summary>
@@ -225,9 +322,81 @@
         }
     }
     
-    #endregion
+    /// <summary>
+    /// 澶勭悊琛�鏉″拰浼ゅ鏇存柊闃熷垪
+    /// </summary>
+    private void UpdateHpAndDamageQueue()
+    {
+        // 浼樺厛澶勭悊UpdateDamage
+        if (damageUpdateQueue.Count > 0)
+        {
+            BattleDmgInfo dmgInfo = damageUpdateQueue.Dequeue();
+            ExecuteDamageUpdate(dmgInfo);
+            return;
+        }
+        // 鍏舵澶勭悊UpdateHP
+        else if (hpUpdateQueue.Count > 0)
+        {
+            HpUpdateRequest request = hpUpdateQueue.Dequeue();
+            ExecuteHpUpdate(request);
+            return;
+        }
+    }
+    
+    /// <summary>
+    /// 鏇存柊椋樺瓧GCD骞跺鐞嗛槦鍒�
+    /// </summary>
+    private void UpdateTipsGCDAndQueue()
+    {
+        // 鏇存柊GCD璁℃椂鍣�
+        if (tipsGCDTimer > 0f)
+        {
+            float speedRatio = GetCurrentSpeedRatio();
+            float deltaTime = 1f / (float)BattleConst.skillMotionFps * speedRatio;
+            tipsGCDTimer -= deltaTime;
+            
+            if (tipsGCDTimer < 0f)
+            {
+                tipsGCDTimer = 0f;
+            }
+        }
+        
+        // 濡傛灉GCD缁撴潫涓旀湁寰呭鐞嗙殑椋樺瓧锛屽脊鍑轰竴涓�
+        if (tipsGCDTimer <= 0f && messages.Count > 0)
+        {
+            TipsInfo tipsInfo = messages[0];
+            messages.RemoveAt(0);
+            
+            PopUpTipsDirectly(tipsInfo);
+            
+            // 閲嶇疆GCD
+            ResetTipsGCD();
+        }
+    }
 
-    #region 绉佹湁鏂规硶 - 椋樺瓧澶勭悊
+    /// <summary>
+    /// 閲嶇疆椋樺瓧GCD璁℃椂鍣�
+    /// </summary>
+    private void ResetTipsGCD()
+    {
+        float speedRatio = GetCurrentSpeedRatio();
+        float frameTime = 1f / (float)BattleConst.skillMotionFps;
+        tipsGCDTimer = frameTime * TIPS_GCD_FRAMES / speedRatio;
+    }
+    
+    /// <summary>
+    /// 鑾峰彇褰撳墠閫熷害鍊嶇巼
+    /// </summary>
+    private float GetCurrentSpeedRatio()
+    {
+        // 鍥為��鍒版垬鍦洪�熷害
+        if (battleObject != null && battleObject.battleField != null)
+        {
+            return battleObject.battleField.speedRatio;
+        }
+        
+        return 1f;
+    }
     
     /// <summary>
     /// 绔嬪嵆寮瑰嚭椋樺瓧
@@ -236,24 +405,23 @@
     {
         // 鍒涘缓椋樺瓧瀹炰緥
         BattleTips tips = CreateTipsInstance(tipsInfo);
-        
+
         // 閰嶇疆椋樺瓧
         ConfigureTips(tips, tipsInfo);
-        
+
         // 璁剧疆浣嶇疆锛堝鏋滀笉璺熼殢锛�
         if (!tipsInfo.followCharacter)
         {
             SetNonFollowPosition(tips);
         }
-        
+
         // 璁剧疆鍙傛暟骞舵樉绀�
-        tips.SetRatio(battleObject.battleField.speedRatio, tipsInfo.scaleRatio);
-        tips.SetText(tipsInfo.message, tipsInfo.useArtText, false); // 绉婚櫎 textColor 鍙傛暟
-        tips.ShowBackground(tipsInfo.showBackground);
-        
         // 娉ㄥ唽瀹屾垚鍥炶皟
         tips.OnFinish = () => RemoveTips(tips);
-        
+        tips.SetRatio(battleObject.battleField.speedRatio, tipsInfo.scaleRatio);
+        tips.ShowBackground(tipsInfo.showBackground);
+        tips.SetText(tipsInfo.message, tipsInfo.useArtText, false);
+
         // 娣诲姞鍒板垪琛�
         tipsList.Add(tips);
     }
@@ -327,6 +495,7 @@
     private void RemoveTips(BattleTips tips)
     {
         tipsList.Remove(tips);
+        tips.controller = null;
         GameObject.DestroyImmediate(tips.gameObject);
     }
     
@@ -337,25 +506,13 @@
     {
         for (int i = tipsList.Count - 1; i >= 0; i--)
         {
+            if (tipsList[i].gameObject == null)
+            {
+                var instanceid = tipsList[i].gameObject.GetInstanceID();
+                tipsList.RemoveAt(i);
+                continue;
+            }
             tipsList[i].Run();
-        }
-    }
-    
-    /// <summary>
-    /// 澶勭悊椋樺瓧闃熷垪
-    /// </summary>
-    private void ProcessTipsQueue()
-    {
-        timer += GetDeltaTime();
-
-        if (messages.Count > 0 && timer >= PopUpInterval)
-        {
-            TipsInfo tipsInfo = messages[0];
-            messages.RemoveAt(0);
-            
-            PopUpTipsDirectly(tipsInfo);
-            
-            timer = 0f;
         }
     }
     
@@ -375,14 +532,10 @@
         tipsList.Clear();
     }
     
-    #endregion
-
-    #region 绉佹湁鏂规硶 - 杈呭姪鏂规硶
-    
     /// <summary>
     /// 鍋滄骞舵竻鐞員ween
     /// </summary>
-    private void KillTween(ref Tween tween)
+    private void KillTween<T>(ref T tween) where T : Tween
     {
         if (tween != null && battleObject != null)
         {
@@ -406,6 +559,4 @@
     {
         // TODO: 鏄剧ずbuff鎻忚堪/褰撳墠韬笂鎵�鏈塨uff
     }
-    
-    #endregion
 }
\ No newline at end of file
diff --git a/Main/System/Battle/UIComp/BattleTips.cs b/Main/System/Battle/UIComp/BattleTips.cs
index ca50cd7..736d889 100644
--- a/Main/System/Battle/UIComp/BattleTips.cs
+++ b/Main/System/Battle/UIComp/BattleTips.cs
@@ -35,7 +35,7 @@
     #region 绉佹湁瀛楁
     
     // 绉婚櫎 [SerializeField]锛宑ontroller 涓嶅簲璇ヨ搴忓垪鍖�
-    private BattleFloatingUIController controller;
+    public BattleFloatingUIController controller;
     
     #endregion
 
@@ -165,8 +165,6 @@
     /// </summary>
     private void InitController()
     {
-        if (controller != null) return;
-
         if (floatingConfig == null)
         {
             Debug.LogError($"[BattleTips] FloatingConfig 鏈厤缃�! GameObject: {gameObject.name}");
@@ -186,7 +184,7 @@
     /// </summary>
     private void EnsureControllerInitialized()
     {
-        if (controller == null)
+        if (controller == null || !controller.IsValid())
             InitController();
     }
     
diff --git a/Main/System/Battle/UIComp/DamageContent.cs b/Main/System/Battle/UIComp/DamageContent.cs
index 80be128..fddadfa 100644
--- a/Main/System/Battle/UIComp/DamageContent.cs
+++ b/Main/System/Battle/UIComp/DamageContent.cs
@@ -3,6 +3,7 @@
 using UnityEngine;
 using System;
 using Cysharp.Threading.Tasks;
+using DG.Tweening;
 
 public class DamageContent : MonoBehaviour, IBattleFloatingUI
 {
@@ -17,10 +18,16 @@
     private BattleDmgInfo battleDmgInfo;
     private BattleFloatingUIController controller;
 
+    #region Unity Lifecycle
+
     void Awake()
     {
         line.SetActive(false);
     }
+
+    #endregion
+
+    #region Controller Management
 
     private void InitController()
     {
@@ -42,6 +49,19 @@
         controller?.SetRatio(speed, scale);
     }
 
+    public void SetFloatingConfig(FloatingConfig config)
+    {
+        floatingConfig = config;
+        if (controller != null)
+        {
+            controller.SetConfig(config);
+        }
+    }
+
+    #endregion
+
+    #region Position Management
+
     /// <summary>
     /// 璁剧疆椋樺瓧鐨勮捣鐐瑰拰缁堢偣浣嶇疆锛堣繍琛屾椂鍔ㄦ�佽缃級
     /// </summary>
@@ -51,30 +71,95 @@
         controller?.SetRuntimePosition(beginPos, endPos);
     }
 
-    public async void SetDamage(BattleDmgInfo _battleDmgInfo, List<BattleDmg> damages, Action _onComplete)
+    #endregion
+
+    #region Damage Display
+
+    public void SetDamage(BattleDmgInfo _battleDmgInfo, List<BattleDmg> damages, Action _onComplete)
     {
         battleDmgInfo = _battleDmgInfo;
-        for (int i = damages.Count; i < damageLineList.Count; i++)
+        
+        EnsureDamageLineCapacity(damages.Count);
+        DisplayDamageLines(damages);
+        HideExcessDamageLines(damages.Count);
+        
+        bool isCrit = battleDmgInfo.IsCrit();
+        Play(isCrit, _onComplete);
+    }
+
+    /// <summary>
+    /// 纭繚鏈夎冻澶熺殑DamageLine瀵硅薄
+    /// </summary>
+    private void EnsureDamageLineCapacity(int requiredCount)
+    {
+        RectTransform lineTemplate = line.GetComponent<RectTransform>();
+        Vector2 templateAnchorMin = lineTemplate.anchorMin;
+        Vector2 templateAnchorMax = lineTemplate.anchorMax;
+        Vector2 templatePivot = lineTemplate.pivot;
+        
+        for (int i = damageLineList.Count; i < requiredCount; i++)
+        {
+            GameObject newLine = GameObject.Instantiate(line, parent);
+            DamageLine damageLine = newLine.GetComponent<DamageLine>();
+            
+            RectTransform newLineRect = newLine.GetComponent<RectTransform>();
+            if (newLineRect != null)
+            {
+                newLineRect.anchorMin = templateAnchorMin;
+                newLineRect.anchorMax = templateAnchorMax;
+                newLineRect.pivot = templatePivot;
+                newLineRect.anchoredPosition = Vector2.zero;
+                newLineRect.localScale = Vector3.one;
+            }
+            
+            damageLineList.Add(damageLine);
+        }
+    }
+
+    /// <summary>
+    /// 鏄剧ず浼ゅ琛屽苟璁剧疆浣嶇疆
+    /// </summary>
+    private void DisplayDamageLines(List<BattleDmg> damages)
+    {
+        for (int i = 0; i < damages.Count; i++)
+        {
+            DamageLine damageLine = damageLineList[i];
+            SetDamageLinePosition(damageLine, i);
+            damageLine.SetActive(true);
+            damageLine.SetDamage(damages[i]);
+        }
+    }
+
+    /// <summary>
+    /// 璁剧疆鍗曚釜浼ゅ琛岀殑浣嶇疆锛堜娇鐢╕杞村亸绉伙級
+    /// </summary>
+    private void SetDamageLinePosition(DamageLine damageLine, int index)
+    {
+        RectTransform lineRect = damageLine.GetComponent<RectTransform>();
+        if (lineRect == null) return;
+
+        RectTransform lineTemplate = line.GetComponent<RectTransform>();
+        Vector2 basePos = lineTemplate.anchoredPosition;
+        
+        Vector2 pos = basePos;
+        pos.y += 60f * index;
+        lineRect.anchoredPosition = pos;
+    }
+
+    /// <summary>
+    /// 闅愯棌澶氫綑鐨勪激瀹宠
+    /// </summary>
+    private void HideExcessDamageLines(int displayCount)
+    {
+        for (int i = displayCount; i < damageLineList.Count; i++)
         {
             damageLineList[i].SetActive(false);
         }
-
-        // 浣跨敤鎺у埗鍣ㄧ殑Play鏂规硶
-        bool isCrit = battleDmgInfo.IsCrit();
-        Play(isCrit, _onComplete);
-
-        for (int i = 0; i < damages.Count; i++)
-        {
-            if (i >= damageLineList.Count)
-            {
-                GameObject newLine = GameObject.Instantiate(line, parent);
-                damageLineList.Add(newLine.GetComponent<DamageLine>());
-            }
-            damageLineList[i].SetActive(true);
-            damageLineList[i].SetDamage(damages[i]);
-            await UniTask.Delay(100);
-        }
     }
+
+    #endregion
+
+    #region Animation Control
 
     public void Play(bool isCrit, Action onComplete = null)
     {
@@ -100,6 +185,10 @@
         controller.Resume();
     }
 
+    #endregion
+
+    #region Visual Effects
+
     private void ApplyColor(Color color)
     {
         for (int i = 0; i < damageLineList.Count; i++)
@@ -111,13 +200,5 @@
         }
     }
 
-    // 杩愯鏃舵洿鏂伴厤缃�
-    public void SetFloatingConfig(FloatingConfig config)
-    {
-        floatingConfig = config;
-        if (controller != null)
-        {
-            controller.SetConfig(config);
-        }
-    }
+    #endregion
 }

--
Gitblit v1.8.0