From 2e7d66b9b7d541d878b2220fa1e50552e7553708 Mon Sep 17 00:00:00 2001
From: lcy <1459594991@qq.com>
Date: 星期四, 30 四月 2026 16:28:48 +0800
Subject: [PATCH] 628 节假日活动-五一活动 任务的积分图标显示活动积分物品图标

---
 Main/System/Battle/UIComp/BattleHeroInfoBar.cs |  756 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 652 insertions(+), 104 deletions(-)

diff --git a/Main/System/Battle/UIComp/BattleHeroInfoBar.cs b/Main/System/Battle/UIComp/BattleHeroInfoBar.cs
index 766e9ab..7caf21c 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>
@@ -24,15 +22,18 @@
         public bool showBackground = false;
         public bool useBuffColor = false;  // 鏄惁浣跨敤 Buff 棰滆壊锛堜粠 FloatingConfig 璇诲彇锛�
         public bool isDebuff = false;      // 鏄惁鏄礋鍚� Buff锛堝喅瀹氱敤鍝釜棰滆壊锛�
+
+        public bool isRage = false;
     }
     
-    #endregion
-
-    #region Inspector瀛楁
     
     [Header("UI Components")]
     public Slider sliderHp;
+    public Slider sliderSlowHp;
     public Slider sliderXp;
+    public GameObject maxXpGO;
+    public Slider sliderShield1;
+    public Slider sliderShield2;
     public BasicHeroInfoContainer heroInfoContainer;
     public BattleTips textTips;
     
@@ -45,44 +46,89 @@
     public FloatingConfig followFloatingConfig;
     [Tooltip("涓嶈窡闅忚鑹茬殑椋樺瓧閰嶇疆锛堝浐瀹氬湪鎴樺満鑺傜偣锛�")]
     public FloatingConfig noFollowFloatingConfig;
-    
-    [Header("Settings")]
-    public float PopUpInterval = 0.2f;
-    
-    #endregion
 
-    #region 绉佹湁瀛楁
+    public FloatingConfig rageFloatingConfig;
     
     protected BattleObject battleObject;
-    protected float timer = 0f;
     
     protected List<TipsInfo> messages = new List<TipsInfo>();
     protected List<BattleTips> tipsList = new List<BattleTips>();
     protected List<HB428_tagSCBuffRefresh> buffList = new List<HB428_tagSCBuffRefresh>();
-    
-    protected Tween hpTween;
+    [SerializeField] ButtonEx buffInfoButton;
+    protected Sequence hpTween;
     protected Tween xpTween;
+    protected Tween shieldTween1;
+    protected Tween shieldTween2;
+    protected Sequence damageSequence;
     
-    #endregion
+    private Queue<BattleDmgInfo> damageUpdateQueue = new Queue<BattleDmgInfo>();
+    
+    // 椋樺瓧GCD鐩稿叧
+    private float tipsGCDTimer = 0f;
+    private const int TIPS_GCD_FRAMES = 5;
 
-    #region Unity鐢熷懡鍛ㄦ湡
+    // 鍏ㄥ眬琛�閲忚褰曪紙鎸夋垬鍦篻uid缁勭粐锛屼互鏈�澶ackUID涓哄噯锛岃褰曟墍鏈夊璞★細鏂芥硶鑰呭拰鍙楀嚮鑰咃級
+    public static Dictionary<string, ulong> largestPackUID = new Dictionary<string, ulong>();
+    public static Dictionary<string, Dictionary<long, long>> largestPackUIDAllObjectsToHp = new Dictionary<string, Dictionary<long, long>>();
+    public static Dictionary<string, Dictionary<long, long>> largestPackUIDAllObjectsMaxHp = new Dictionary<string, Dictionary<long, long>>();
+    public static Dictionary<string, Dictionary<long, ulong>> objectLargestPackUID = new Dictionary<string, Dictionary<long, ulong>>();
     
     protected void OnDisable()
     {
         CleanupTips();
     }
     
-    #endregion
-
-    #region 鍏叡鏂规硶 - 鍒濆鍖�
-    
     public void SetBattleObject(BattleObject _battleObject)
     {
         battleObject = _battleObject;
-        heroInfoContainer.SetHeroInfo(battleObject.teamHero);
-        RefreshBuff(battleObject.buffMgr.GetBuffList());
-        UpdateHP(battleObject.teamHero.curHp, battleObject.teamHero.curHp, battleObject.teamHero.maxHp, false);
-        UpdateXP(battleObject.teamHero.rage, battleObject.teamHero.rage, 100, false);
+        if (battleObject is HeroBattleObject heroBattleObject)
+        {
+            heroInfoContainer.SetHeroInfo(heroBattleObject.teamHero);
+        }
+        CleanupTips();
+        InitBuff();
+        
+        var buffMgr = battleObject.GetBuffMgr();
+        if (buffMgr != null) // 鍛芥牸涓嶆湁 buff
+        {
+            RefreshBuff(buffMgr.GetBuffIconList());
+        }
+
+        if (!battleObject.IsTianziBoss())
+        {
+            UpdateHP(battleObject.GetCurHp(), battleObject.GetCurHp(), battleObject.GetMaxHp(), false);
+        }
+
+        UpdateXP(battleObject.GetRage(), battleObject.GetRage(), 100, false);
+
+        long shieldValue = buffMgr != null ? buffMgr.GetShieldValue() : 0; // 鍛芥牸娌℃湁鎶ょ浘
+        long curHp = battleObject.GetCurHp();
+        long maxHp = battleObject.GetMaxHp();
+        
+        // 璁板綍璁剧疆鍓嶇殑鎶ょ浘鍊�
+        float oldShield1Value = sliderShield1.value;
+        float oldShield2Value = sliderShield2.value;
+        
+        // 鎶ょ浘1鐨勫�� = min(褰撳墠琛�閲� + 鎶ょ浘鍊�, maxHp) / maxHp
+        float shield1Value = maxHp > 0 ? Mathf.Min((float)(curHp + shieldValue), (float)maxHp) / (float)maxHp : 0;
+        // 鎶ょ浘2鐨勫�� = max(褰撳墠琛�閲� + 鎶ょ浘鍊� - maxHp, 0) / maxHp
+        float shield2Value = maxHp > 0 ? Mathf.Max((float)(curHp + shieldValue - maxHp), 0f) / (float)maxHp : 0;
+        
+        sliderShield1.value = shield1Value;
+        sliderShield2.value = shield2Value;
+        
+
+
+        // 鎵撳嵃璁剧疆鎶ょ浘鏃剁殑鐘舵��
+        // Debug.LogError($"[BattleHeroInfoBar.SetBattleObject] 璁剧疆鎶ょ浘 - curHp: {curHp}, shieldValue: {shieldValue}, maxHp: {maxHp}, shield1鍓�: {oldShield1Value}, shield1鍚�: {shield1Value}, shield2鍓�: {oldShield2Value}, shield2鍚�: {shield2Value}");
+    }
+
+    protected void InitBuff()
+    {
+        for (int i = 0; i < buffCells.Count; i++)
+        {
+            buffCells[i].SetActive(false);
+        }
     }
     
     public void SetActive(bool active)
@@ -90,58 +136,137 @@
         gameObject.SetActive(active);
     }
     
-    #endregion
-
-    #region 鍏叡鏂规硶 - Buff绠$悊
-    
     public void RefreshBuff(List<HB428_tagSCBuffRefresh> datas)
     {
-        if (buffCells.IsNullOrEmpty())
-            return;
+        RefreshBuffCells(buffCells, datas);
 
-        for (int i = 0; i < buffCells.Count; i++)
+        // check shield buff
+        var buffMgr = battleObject.GetBuffMgr();
+        long shieldValue = buffMgr != null ? buffMgr.GetShieldValue() : 0; // 鍛芥牸娌℃湁鎶ょ浘
+        long curHp = battleObject.GetCurHp();
+        long maxHp = battleObject.GetMaxHp();
+        
+        // 璁板綍璁剧疆鍓嶇殑鎶ょ浘鍊�
+        float oldShield1Value = sliderShield1.value;
+        float oldShield2Value = sliderShield2.value;
+    
+        // 鎶ょ浘1鐨勫�� = min(褰撳墠琛�閲� + 鎶ょ浘鍊�, maxHp) / maxHp
+        float shield1Value = maxHp > 0 ? Mathf.Min((float)(curHp + shieldValue), (float)maxHp) / (float)maxHp : 0;
+        // 鎶ょ浘2鐨勫�� = max(褰撳墠琛�閲� + 鎶ょ浘鍊� - maxHp, 0) / maxHp
+        float shield2Value = maxHp > 0 ? Mathf.Max((float)(curHp + shieldValue - maxHp), 0f) / (float)maxHp : 0;
+        
+        sliderShield1.value = shield1Value;
+        sliderShield2.value = shield2Value;
+
+        // if (!battleObject.IsTianziBoss())
+        // {
+        //     UpdateHP(curHp, curHp, maxHp, false);
+        // }
+        
+    
+        // 鎵撳嵃鍒锋柊鎶ょ浘鏃剁殑鐘舵��
+        // Debug.LogError($"[BattleHeroInfoBar.RefreshBuff] 璁剧疆鎶ょ浘 - curHp: {curHp}, shieldValue: {shieldValue}, maxHp: {maxHp}, shield1鍓�: {oldShield1Value}, shield1鍚�: {shield1Value}, shield2鍓�: {oldShield2Value}, shield2鍚�: {shield2Value}");
+    }
+    
+    protected void RefreshBuffCells(List<BattleBuffCell> cells, List<HB428_tagSCBuffRefresh> datas)
+    {
+        if (datas == null)
         {
-            if (i < datas.Count)
+            for (int i = 0; i < cells.Count; i++)
             {
-                buffCells[i].SetActive(true);
-                buffCells[i].Init(datas[i], OnBuffCellClicked);
+                cells[i].SetActive(false);
+            }
+        }
+        else
+        {
+            if (battleObject.battleField.battleSwitch.BuffIcon)
+            {
+                for (int i = 0; i < cells.Count; i++)
+                {
+                    var cell = cells[i];
+                    if (i < datas.Count)
+                    {
+                        cell.SetActive(true);
+                        HB428_tagSCBuffRefresh buffData = datas[i];
+                        SkillConfig skillConfig = SkillConfig.Get((int)buffData.SkillID);
+                        cell.Init(buffData, () =>
+                        {
+                            //  鐐瑰嚮buff鍥炬爣 鏄剧ずbuff鎻忚堪/褰撳墠韬笂鎵�鏈塨uff
+                        });
+                    }
+                    else
+                    {
+                        cell.SetActive(false);
+                    }
+                }
+
+
+                buffInfoButton.SetListener(() =>
+                {
+                    if (datas.IsNullOrEmpty()) return;
+
+                    string clickBuffBattleName = battleObject?.battleField?.ToString();
+                    if (clickBuffBattleName == BattleConst.StoryBattleField) return;
+
+                    EventBroadcast.Instance.Broadcast(EventName.BATTLE_CLICK_BUFF, new BattleClickBuffData()
+                    {
+                        isMySide = battleObject?.Camp == BattleCamp.Red,
+                        heroID = (battleObject as HeroBattleObject)?.teamHero?.heroId ?? 0,
+                        skinID = (battleObject as HeroBattleObject)?.teamHero?.SkinID ?? 0,
+                        datas = datas,
+                    });
+                });
             }
             else
             {
-                buffCells[i].SetActive(false);
+                for (int i = 0; i < cells.Count; i++)
+                {
+                    cells[i].SetActive(false);
+                }
             }
+
         }
     }
-    
-    #endregion
 
-    #region 鍏叡鏂规硶 - 椋樺瓧绠$悊
-    
     /// <summary>
-    /// 娣诲姞椋樺瓧鍒伴槦鍒�
+    /// 娣诲姞椋樺瓧鍒伴槦鍒�(闈炰激瀹抽瀛�)
     /// </summary>
     public void ShowTips(string message, bool useArtText = false, bool followCharacter = true, float scaleRatio = 1f)
     {
-        messages.Add(new TipsInfo
+        if (battleObject.battleField.battleSwitch.NonDamageTips)
         {
-            message = message,
-            useArtText = useArtText,
-            followCharacter = followCharacter,
-            scaleRatio = scaleRatio
-        });
+            messages.Add(new TipsInfo
+            {
+                message = message,
+                useArtText = useArtText,
+                followCharacter = followCharacter,
+                scaleRatio = scaleRatio
+            });
+        }
     }
 
     /// <summary>
-    /// 娣诲姞鑷畾涔夐瀛楅厤缃埌闃熷垪
+    /// 娣诲姞鑷畾涔夐瀛楅厤缃埌闃熷垪(闈炰激瀹抽瀛�)
     /// </summary>
     public void ShowTips(TipsInfo tipsInfo)
     {
-        messages.Add(tipsInfo);
+        //  BUFF椋樺瓧
+        if (tipsInfo.useBuffColor)
+        {
+            if (battleObject.battleField.battleSwitch.BuffAction)
+            {
+                messages.Add(tipsInfo);
+            }
+        }
+        else
+        {
+            //  闈炰激瀹抽瀛�
+            if (battleObject.battleField.battleSwitch.NonDamageTips)
+            {
+                messages.Add(tipsInfo);
+            }
+        }
     }
-    
-    #endregion
-
-    #region 鍏叡鏂规硶 - 鏁板�兼洿鏂�
     
     /// <summary>
     /// 鏇存柊琛�閲忔樉绀�
@@ -155,16 +280,28 @@
         
         if (tween)
         {
-            // 鍏抽敭淇:鍏堣缃捣濮嬪��,鍐嶆挱鏀惧姩鐢诲埌鐩爣鍊�
-            sliderHp.value = fromValue;  // 鈫� 杩欒鏄叧閿�!
-            hpTween = sliderHp.DOValue(targetValue, 0.3f).SetAutoKill(false);
+            hpTween = DOTween.Sequence();
+            // sliderHp.value = fromValue;
+            float diff = targetValue - fromValue;
+            float cost = Mathf.Lerp(0, 1f, diff);
+
+            hpTween.Append(sliderHp.DOValue(targetValue, cost).SetAutoKill(false));
+            hpTween.Join(sliderSlowHp.DOValue(targetValue, cost * 1.5f).SetAutoKill(false));
+            hpTween.onComplete += () =>
+            {
+                sliderHp.value = targetValue;
+                sliderSlowHp.value = targetValue;
+            };
+            // sliderSlowHp
             battleObject.battleField.battleTweenMgr.OnPlayTween(hpTween);
         }
         else
         {
             sliderHp.value = targetValue;
+            sliderSlowHp.value = targetValue;
         }
     }
+
 
     /// <summary>
     /// !!!涓存椂鐨勭敤浜庡ぉ瀛愭洿鏂拌閲忔樉绀�,绛夋帴鍙e畬鍠勫悗鍒犻櫎
@@ -172,6 +309,10 @@
     public void UpdateHP(float value)
     {
         sliderHp.value = value; 
+        sliderSlowHp.value = value;
+        bool IsTianziBoss = battleObject.IsTianziBoss();
+        sliderShield1.SetActive(!IsTianziBoss);
+        sliderShield2.SetActive(!IsTianziBoss);
         //Debug.Log("TianziDamageBar UpdateHP value:" + value);
     }
 
@@ -181,37 +322,269 @@
     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(() =>
+            {
+                maxXpGO.SetActive(toXp >= maxXp);
+            });
             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)
+    {
+        // 楠岃瘉鏁版嵁鏈夋晥鎬э紝闃叉绌哄紩鐢�
+        if (dmgInfo?.battleHurtParam == null)
+            return;
+            
+        // 妫�鏌ュ彈鍑昏�呭璞℃湁鏁堟��
+        if (dmgInfo.battleHurtParam.hurter?.hurtObj != null)
+        {
+            var hurtObj = dmgInfo.battleHurtParam.hurter.hurtObj;
+            // 妫�鏌ュ璞℃槸鍚﹀凡琚攢姣�
+            if (hurtObj == null || hurtObj.Equals(null))
+            {
+                Debug.LogWarning($"[UpdateDamage] 鍙楀嚮鑰呭璞″凡琚攢姣侊紝璺宠繃浼ゅ鏇存柊");
+                return;
+            }
+            
+            // 楠岃瘉鏄惁鑳藉畨鍏ㄨ幏鍙� maxHp锛堥棿鎺ユ鏌� HeroBattleObject 鍐呴儴鐘舵�侊級
+            if (hurtObj is HeroBattleObject && hurtObj.GetMaxHp() <= 0)
+            {
+                Debug.LogWarning($"[UpdateDamage] 鍙楀嚮鑰� maxHp 鏃犳晥锛岃烦杩囦激瀹虫洿鏂�");
+                return;
+            }
+        }
+        
+        // 妫�鏌ユ柦娉曡�呭璞℃湁鏁堟��
+        if (dmgInfo.battleHurtParam.caster?.casterObj != null)
+        {
+            var casterObj = dmgInfo.battleHurtParam.caster.casterObj;
+            // 妫�鏌ュ璞℃槸鍚﹀凡琚攢姣�
+            if (casterObj == null || casterObj.Equals(null))
+            {
+                Debug.LogWarning($"[UpdateDamage] 鏂芥硶鑰呭璞″凡琚攢姣侊紝璺宠繃浼ゅ鏇存柊");
+                return;
+            }
+            
+            // 楠岃瘉鏄惁鑳藉畨鍏ㄨ幏鍙� maxHp
+            if (casterObj is HeroBattleObject && casterObj.GetMaxHp() <= 0)
+            {
+                Debug.LogWarning($"[UpdateDamage] 鏂芥硶鑰� maxHp 鏃犳晥锛岃烦杩囦激瀹虫洿鏂�");
+                return;
+            }
+        }
+        
+        // 鏁版嵁楠岃瘉閫氳繃锛屽姞鍏ラ槦鍒�
+        damageUpdateQueue.Enqueue(dmgInfo);
+    }
+
+    /// <summary>
+    /// 瀹為檯鎵ц浼ゅ鏇存柊锛堢粺涓�澶勭悊鐩爣鍜屾柦娉曡�咃級
+    /// </summary>
+    private void ExecuteDamageUpdate(BattleDmgInfo dmgInfo)
+    {
+        KillTween(ref damageSequence);
+
+        string guid = battleObject.battleField.guid;
+        long objID = battleObject.ObjID;
+        ulong currentPackUID = dmgInfo.battleHurtParam.packUID;
+        
+        // 鑾峰彇璇ユ垬鍦虹殑瀵硅薄PackUID瀛楀吀锛堢敤浜庢寜瑙掕壊+瑙掕壊韬唤绮掑害鍒ゆ柇锛�
+        Dictionary<long, ulong> objPackUIDDict = null;
+        if (objectLargestPackUID.ContainsKey(guid))
+        {
+            objPackUIDDict = objectLargestPackUID[guid];
+        }
+        
+        long maxHp, fromHp, toHp, fromShield, toShield;
+        
+        // 浼樺厛鍒ゆ柇褰撳墠InfoBar鏄惁涓哄彈鍑昏�咃紙琛�閲忓彉鍖栨�绘槸浣撶幇鍦╤urter閲岋級
+        BattleHurtObj hurter = dmgInfo.battleHurtParam.hurter;
+        if (hurter?.hurtObj != null && hurter.hurtObj.ObjID == objID)
+        {
+            // 鎸夊璞�+鍙楀嚮鑰呰韩浠芥鏌ackUID锛岄伩鍏嶄笉鍚岃韩浠斤紙hurter/caster锛夌殑鍖呬簰鐩搁樆鎷�
+            long hurterKey = objID * 2; // hurter鐢ㄥ伓鏁発ey
+            if (objPackUIDDict != null 
+                && objPackUIDDict.ContainsKey(hurterKey) 
+                && currentPackUID < objPackUIDDict[hurterKey])
+            {
+                // Debug.LogWarning($"[ExecuteDamageUpdate] 蹇界暐鏃у寘(鍙楀嚮鑰�) - ObjID:{objID}, 褰撳墠PackUID:{currentPackUID} < 瀵硅薄鍙楀嚮鏈�澶ackUID:{objPackUIDDict[hurterKey]}");
+                return;
+            }
+            
+            // 褰撳墠InfoBar鏄彈鍑昏�咃紙鍖呮嫭缁欒嚜宸辨不鐤椼�佺粰鑷繁閫犳垚浼ゅ鐨勬儏鍐碉級
+            if (hurter.hurtObj.IsTianziBoss())
+            {
+                return;
+            }
+            
+            // 鐩存帴浣跨敤 dmgInfo 涓殑鏁版嵁锛堝凡缁忚 CompareAndExchangeLargestPackUIDHp 楠岃瘉杩囷級
+            maxHp = hurter.maxHp;
+            fromHp = hurter.fromHp;
+            toHp = hurter.toHp;
+            fromShield = hurter.fromShieldValue;
+            toShield = hurter.toShieldValue;
+            
+            // 鏇存柊璇ュ璞′綔涓哄彈鍑昏�呯殑鏈�澶ackUID
+            if (objPackUIDDict != null)
+            {
+                objPackUIDDict[hurterKey] = currentPackUID;
+            }
+            
+            // Debug.LogError($"[ExecuteDamageUpdate] 鍙楀嚮鑰� - ObjID:{objID}, fromHp:{fromHp}, toHp:{toHp}, maxHp:{maxHp} (PackUID:{currentPackUID})");
+        }
+        // 鍏舵鍒ゆ柇鏄惁涓烘柦娉曡�咃紙鏂芥硶娑堣�楃敓鍛界瓑鎯呭喌锛�
+        else
+        {
+            BattleCastObj caster = dmgInfo.battleHurtParam.caster;
+            if (caster?.casterObj == null || caster.casterObj.ObjID != objID)
+            {
+                // Debug.LogWarning($"[ExecuteDamageUpdate] 褰撳墠瀵硅薄 {objID} 鏃笉鏄柦娉曡�呬篃涓嶆槸鍙楀嚮鑰�");
+                return;
+            }
+            
+            // 鎸夊璞�+鏂芥硶鑰呰韩浠芥鏌ackUID
+            long casterKey = objID * 2 + 1; // caster鐢ㄥ鏁発ey
+            if (objPackUIDDict != null 
+                && objPackUIDDict.ContainsKey(casterKey) 
+                && currentPackUID < objPackUIDDict[casterKey])
+            {
+                // Debug.LogWarning($"[ExecuteDamageUpdate] 蹇界暐鏃у寘(鏂芥硶鑰�) - ObjID:{objID}, 褰撳墠PackUID:{currentPackUID} < 瀵硅薄鏂芥硶鏈�澶ackUID:{objPackUIDDict[casterKey]}");
+                return;
+            }
+            
+            if (caster.casterObj.IsTianziBoss())
+            {
+                return;
+            }
+            
+            // 鐩存帴浣跨敤 dmgInfo 涓殑鏁版嵁锛堝凡缁忚 CompareAndExchangeLargestPackUIDHp 楠岃瘉杩囷級
+            maxHp = caster.maxHp;
+            fromHp = caster.fromHp;
+            toHp = caster.toHp;
+            fromShield = caster.fromShieldValue;
+            toShield = caster.toShieldValue;
+            
+            // 鏇存柊璇ュ璞′綔涓烘柦娉曡�呯殑鏈�澶ackUID
+            if (objPackUIDDict != null)
+            {
+                objPackUIDDict[casterKey] = currentPackUID;
+            }
+            
+            // Debug.LogError($"[ExecuteDamageUpdate] 鏂芥硶鑰� - ObjID:{objID}, fromHp:{fromHp}, toHp:{toHp}, maxHp:{maxHp} (PackUID:{currentPackUID})");
+        }
+
+        if (maxHp <= 0)
+        {
+            sliderShield1.value = 0;
+            sliderShield2.value = 0;
+            return;
+        }
+
+        damageSequence = DOTween.Sequence();
+
+        bool IsTianziBoss = battleObject.IsTianziBoss();
+
+        // 鎶ょ浘鍔ㄧ敾
+        if (fromShield > 0 && !IsTianziBoss)
+        {
+            float fromShield1Value = Mathf.Min((float)(fromHp + fromShield), (float)maxHp) / (float)maxHp;
+            float fromShield2Value = Mathf.Max((float)(fromHp + fromShield - maxHp), 0f) / (float)maxHp;
+            
+            sliderShield1.value = fromShield1Value;
+            sliderShield2.value = fromShield2Value;
+
+            // 鎶ょ浘2鍔ㄧ敾
+            if (fromShield2Value > 0)
+            {
+                float toShield2Value = Mathf.Max((float)(toHp + toShield - maxHp), 0f) / (float)maxHp;
+
+                if (Mathf.Abs(fromShield2Value - toShield2Value) > 0.001f)
+                {
+                    damageSequence.Append(sliderShield2.DOValue(toShield2Value, 0.2f));
+                }
+            }
+
+            // 鎶ょ浘1鍔ㄧ敾
+            if (fromShield1Value > 0)
+            {
+                float toShield1Value = Mathf.Min((float)(toHp + toShield), (float)maxHp) / (float)maxHp;
+
+                if (Mathf.Abs(fromShield1Value - toShield1Value) > 0.001f)
+                {
+                    damageSequence.Append(sliderShield1.DOValue(toShield1Value, 0.2f));
+                }
+            }
+        }
+        else
+        {
+            sliderShield1.value = 0f;
+            sliderShield2.value = 0f;
+        }
+
+        // 琛�閲忓姩鐢�
+        float fromHpValue = (float)fromHp / (float)maxHp;
+        float toHpValue = (float)toHp / (float)maxHp;
+        
+        // sliderHp.value = fromHpValue;
+        // sliderSlowHp.value = fromHpValue;
+        float diff = Mathf.Abs(toHpValue - fromHpValue);
+        float cost = Mathf.Lerp(0, 1f, diff);
+
+        if (Mathf.Abs(fromHpValue - toHpValue) > 0.001f)
+        {
+            damageSequence.Append(sliderHp.DOValue(toHpValue, cost));
+            damageSequence.Join(sliderSlowHp.DOValue(toHpValue, cost * 1.5f));
+        }
+
+        damageSequence.onComplete += () =>
+        {
+            sliderHp.value = toHpValue;
+            sliderSlowHp.value = toHpValue;
+        };
+
+        damageSequence.Play();
+        battleObject.battleField.battleTweenMgr.OnPlayTween(damageSequence);
+    }
     
     /// <summary>
     /// 姣忓抚鏇存柊
     /// </summary>
     public void Run()
     {
+        // 澶勭悊琛�鏉″拰浼ゅ闃熷垪
+        UpdateHpAndDamageQueue();
+        
+        // 鏇存柊椋樺瓧GCD骞跺鐞嗛槦鍒�
+        UpdateTipsGCDAndQueue();
+        
         // 鏇存柊鎵�鏈夐瀛�
         UpdateActiveTips();
-        
-        // 澶勭悊椋樺瓧闃熷垪
-        ProcessTipsQueue();
     }
 
     /// <summary>
@@ -225,9 +598,181 @@
         }
     }
     
-    #endregion
+    private void CompareAndExchangeLargestPackUIDHp(BattleDmgInfo dmgInfo)
+    {
+        string guid = battleObject.battleField.guid;
+        ulong currentPackUID = dmgInfo.battleHurtParam.packUID;
+        
+        // 鑾峰彇鎴栧垵濮嬪寲褰撳墠鎴樺満鐨勬暟鎹�
+        if (!largestPackUID.ContainsKey(guid))
+        {
+            largestPackUID[guid] = 0ul;
+        }
+        if (!largestPackUIDAllObjectsToHp.ContainsKey(guid))
+        {
+            largestPackUIDAllObjectsToHp[guid] = new Dictionary<long, long>();
+        }
+        if (!largestPackUIDAllObjectsMaxHp.ContainsKey(guid))
+        {
+            largestPackUIDAllObjectsMaxHp[guid] = new Dictionary<long, long>();
+        }
+        if (!objectLargestPackUID.ContainsKey(guid))
+        {
+            objectLargestPackUID[guid] = new Dictionary<long, ulong>();
+        }
+        
+        ulong currentLargestPackUID = largestPackUID[guid];
+        Dictionary<long, long> hpDict = largestPackUIDAllObjectsToHp[guid];
+        Dictionary<long, long> maxHpDict = largestPackUIDAllObjectsMaxHp[guid];
+        Dictionary<long, ulong> objPackUIDDict = objectLargestPackUID[guid];
+        
+        // 濡傛灉閬囧埌鏇村ぇ鐨刾ackUID锛屾洿鏂版爣璁帮紙涓嶆竻绌烘暟鎹紝淇濈暀鎵�鏈夎瘉鎹級
+        if (currentPackUID > currentLargestPackUID)
+        {
+            // Debug.LogError($"[琛�閲忚褰昡 妫�娴嬪埌鏂版壒娆ackUID: {currentPackUID} > {currentLargestPackUID}锛屼繚鐣欐墍鏈夊巻鍙叉暟鎹�");
+            largestPackUID[guid] = currentPackUID;
+            currentLargestPackUID = currentPackUID;
+        }
+        
+        // 璁板綍鎵�鏈塸ackUID鐨勬暟鎹紙鍖呮嫭鏃╄Е鍙戠殑鍖咃級锛屼絾鍙噰鐢ㄦ渶澶ackUID鐨勬暟鎹�
+        // 璁板綍鏂芥硶鑰呯殑琛�閲忓彉鍖�
+        BattleCastObj battleCastObj = dmgInfo.battleHurtParam.caster;
+        if (battleCastObj != null && battleCastObj.casterObj != null)
+        {
+            long casterID = battleCastObj.casterObj.ObjID;
+            
+            // 鑾峰彇鏃ц閲忕敤浜庤绠楀彉鍖�
+            long oldHp = hpDict.ContainsKey(casterID) ? hpDict[casterID] : battleCastObj.fromHp;
+            long newHp = battleCastObj.toHp;
+            long maxHp = battleCastObj.maxHp;
+            long hpChange = newHp - oldHp;
+            
+            // 鍙湁褰撳墠packUID涓嶅皬浜庤瀵硅薄鐨勬渶澶ackUID鏃舵墠鏇存柊璁板綍
+            ulong casterLastPackUID = objPackUIDDict.ContainsKey(casterID) ? objPackUIDDict[casterID] : 0ul;
+            if (currentPackUID >= casterLastPackUID)
+            {
+                hpDict[casterID] = newHp;
+                maxHpDict[casterID] = maxHp;
+                objPackUIDDict[casterID] = currentPackUID;
+                
+                // 鎵撳嵃琛�閲忓彉鍖栨棩蹇楋紙鏂芥硶鑰呴�氬父鏄仮澶嶇敓鍛斤級
+                // string casterName = caster.casterObj.teamHero?.heroConfig.Name ?? "鏈煡姝﹀皢";
+                if (hpChange != 0)
+                {
+                    // string changeType = hpChange > 0 ? "鎭㈠" : "鎹熷け";
+                    // Debug.LogError($"[琛�閲忓彉鍖朷 {casterName}(ID:{casterID}) {changeType} {Math.Abs(hpChange)} 鐢熷懡锛岃閲忎粠 {oldHp}/{maxHp} 鍙樹负 {newHp}/{maxHp} (PackUID:{currentPackUID})");
+                }
+            }
+            else
+            {
+                // Debug.LogWarning($"[琛�閲忚褰昡 蹇界暐鏃у寘鏁版嵁 - 鏂芥硶鑰厈casterID}, 褰撳墠PackUID:{currentPackUID} < 瀵硅薄鏈�澶ackUID:{casterLastPackUID}");
+            }
+        }
+        
+        // 璁板綍鍙楀嚮鑰呯殑琛�閲忓彉鍖�
+        BattleHurtObj battleHurtObj = dmgInfo.battleHurtParam.hurter;
+        if (battleHurtObj != null && battleHurtObj.hurtObj != null)
+        {
+            BattleObject hurter = battleHurtObj.hurtObj;
+            long hurterID = hurter.ObjID;
+            
+            // 鑾峰彇鏃ц閲忕敤浜庤绠椾激瀹�
+            long oldHp = hpDict.ContainsKey(hurterID) ? hpDict[hurterID] : battleHurtObj.fromHp;
+            long newHp = battleHurtObj.toHp;
+            long maxHp = battleHurtObj.maxHp;
+            long damage = oldHp - newHp;
+            
+            // 鍙湁褰撳墠packUID涓嶅皬浜庤瀵硅薄鐨勬渶澶ackUID鏃舵墠鏇存柊璁板綍
+            ulong hurterLastPackUID = objPackUIDDict.ContainsKey(hurterID) ? objPackUIDDict[hurterID] : 0ul;
+            if (currentPackUID >= hurterLastPackUID)
+            {
+                hpDict[hurterID] = newHp;
+                maxHpDict[hurterID] = maxHp;
+                objPackUIDDict[hurterID] = currentPackUID;
+                
+                // 鎵撳嵃琛�閲忓彉鍖栨棩蹇�
+                // string hurterName = hurter.hurtObj.teamHero?.heroConfig.Name ?? "鏈煡姝﹀皢";
+                if (damage != 0)
+                {
+                    // Debug.LogError($"[琛�閲忓彉鍖朷 {hurterName}(ID:{hurterID}) 鍙楀埌 {damage} 浼ゅ锛岃閲忎粠 {oldHp}/{maxHp} 鍙樹负 {newHp}/{maxHp} (PackUID:{currentPackUID})");
+                }
+            }
+            else
+            {
+                // Debug.LogWarning($"[琛�閲忚褰昡 蹇界暐鏃у寘鏁版嵁 - 鍙楀嚮鑰厈hurterID}, 褰撳墠PackUID:{currentPackUID} < 瀵硅薄鏈�澶ackUID:{hurterLastPackUID}");
+            }
+        }
+    }
 
-    #region 绉佹湁鏂规硶 - 椋樺瓧澶勭悊
+    /// <summary>
+    /// 澶勭悊琛�鏉″拰浼ゅ鏇存柊闃熷垪
+    /// </summary>
+    private void UpdateHpAndDamageQueue()
+    {
+        // 浼樺厛澶勭悊UpdateDamage
+        if (damageUpdateQueue.Count > 0)
+        {
+            BattleDmgInfo dmgInfo = damageUpdateQueue.Dequeue();
+            CompareAndExchangeLargestPackUIDHp(dmgInfo);
+            ExecuteDamageUpdate(dmgInfo);
+            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();
+        }
+    }
+
+    /// <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 +781,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);
     }
@@ -265,7 +809,7 @@
     {
         Transform parent = tipsInfo.followCharacter 
             ? transform 
-            : battleObject.battleField.battleRootNode.transform;
+            : battleObject.battleField.battleRootNode.notFollowTipsAdjuster.transform;
             
         GameObject go = GameObject.Instantiate(textTips.gameObject, parent);
         return go.GetComponent<BattleTips>();
@@ -276,7 +820,7 @@
     /// </summary>
     private void ConfigureTips(BattleTips tips, TipsInfo tipsInfo)
     {
-        FloatingConfig targetConfig = tipsInfo.followCharacter 
+        FloatingConfig targetConfig = tipsInfo.isRage ? rageFloatingConfig : tipsInfo.followCharacter 
             ? followFloatingConfig 
             : noFollowFloatingConfig;
         
@@ -327,6 +871,7 @@
     private void RemoveTips(BattleTips tips)
     {
         tipsList.Remove(tips);
+        tips.controller = null;
         GameObject.DestroyImmediate(tips.gameObject);
     }
     
@@ -337,25 +882,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;
         }
     }
     
@@ -366,23 +899,18 @@
     {
         messages.Clear();
         
-        foreach (var tip in tipsList)
+        for (int i = tipsList.Count - 1; i >= 0; i--)
         {
-            tip.OnFinish = null;
-            GameObject.DestroyImmediate(tip.gameObject);
+            RemoveTips(tipsList[i]);
         }
         
         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 +934,26 @@
     {
         // TODO: 鏄剧ずbuff鎻忚堪/褰撳墠韬笂鎵�鏈塨uff
     }
-    
-    #endregion
+
+    /// <summary>
+    /// 娓呯悊鎸囧畾鎴樺満鐨勯潤鎬丳ackUID鍜岃閲忚褰�
+    /// </summary>
+    public static void ClearStaticBattleData(string guid)
+    {
+        largestPackUID.Remove(guid);
+        largestPackUIDAllObjectsToHp.Remove(guid);
+        largestPackUIDAllObjectsMaxHp.Remove(guid);
+        objectLargestPackUID.Remove(guid);
+    }
+
+    public void HaveRest()
+    {
+        CleanupTips();
+        SetActive(false);
+
+        //  鍏虫帀鎵�鏈夌殑tween
+        KillTween(ref hpTween);
+        KillTween(ref xpTween);
+        KillTween(ref damageSequence);
+    }
 }
\ No newline at end of file

--
Gitblit v1.8.0