hch
19 小时以前 1fdef60f2611d01bf658e8a2e4f69bfa251de95b
Merge branch 'master' of http://mobile.secondworld.net.cn:10010/r/Project_SG_scripts
6个文件已修改
301 ■■■■ 已修改文件
Main/System/Battle/BaseBattleWin.cs 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleField/BattleField.cs 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleUtility.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/Define/BattleDmgInfo.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/TianziBillboradBattleWin.cs 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/UIComp/BattleHeroInfoBar.cs 177 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BaseBattleWin.cs
@@ -192,13 +192,20 @@
    /// </summary>
    protected virtual void OnClickPass()
    {
        if (null == battleField)
        if (!IsPass())
            return;
        battleField.ForceFinish();
    }
    public bool IsPass()
    {
        if (null == battleField)
            return false;
        // 检查是否为永久特权卡玩家
        bool hasForeverPrivilege = InvestModel.Instance.IsInvested(InvestModel.foreverCardType);
        if (!hasForeverPrivilege && !FuncOpen.Instance.IsFuncOpen(BattleManager.Instance.passFuncId, true))
            return;
            return false;
        int passRound = BattleManager.Instance.defaultPassRound;
        var name = battleField.ToString();
@@ -248,13 +255,11 @@
            if (nowRound < realPassRound)
            {
                SysNotifyMgr.Instance.ShowTip("BattlePass", realPassRound - nowRound);
                return;
                return false;
            }
        }
        battleField.ForceFinish();
        return true;
    }
    /// <summary>
Main/System/Battle/BattleField/BattleField.cs
@@ -131,6 +131,20 @@
        LoadMap(MapID);
        // 清空当前战场的血量记录(防止不同战斗之间的数据混乱)
        if (BattleHeroInfoBar.largestPackUID.ContainsKey(guid))
        {
            BattleHeroInfoBar.largestPackUID.Remove(guid);
        }
        if (BattleHeroInfoBar.largestPackUIDAllObjectsToHp.ContainsKey(guid))
        {
            BattleHeroInfoBar.largestPackUIDAllObjectsToHp.Remove(guid);
        }
        if (BattleHeroInfoBar.largestPackUIDAllObjectsMaxHp.ContainsKey(guid))
        {
            BattleHeroInfoBar.largestPackUIDAllObjectsMaxHp.Remove(guid);
        }
        // battleRootNode.SetBackground(ResManager.Instance.LoadAsset<Texture>("Texture/FullScreenBg", "mainui_img_277"));
        SetBattleStartState();
@@ -259,6 +273,20 @@
        // 清理死亡处理记录
        processingDeathObjIds.Clear();
        // 清空当前战场的血量记录
        if (BattleHeroInfoBar.largestPackUID.ContainsKey(guid))
        {
            BattleHeroInfoBar.largestPackUID.Remove(guid);
        }
        if (BattleHeroInfoBar.largestPackUIDAllObjectsToHp.ContainsKey(guid))
        {
            BattleHeroInfoBar.largestPackUIDAllObjectsToHp.Remove(guid);
        }
        if (BattleHeroInfoBar.largestPackUIDAllObjectsMaxHp.ContainsKey(guid))
        {
            BattleHeroInfoBar.largestPackUIDAllObjectsMaxHp.Remove(guid);
        }
    }
    public virtual void Run()
@@ -394,7 +422,7 @@
        if (State == 4)
        {
            //已经结束并结算
            Debug.Log("战斗结束");
            // Debug.Log("战斗结束");
            rejectNewPackage = true;
            OnBattleEnd(turnFightStateData);
            return;
@@ -405,12 +433,12 @@
        {
            if (State == 2)
            {
                Debug.Log("战斗开始");
                // Debug.Log("战斗开始");
            }
        }
        else
        {
            Debug.Log("战斗回合 : " + turnNum + ",状态 " + State);
            // Debug.Log("战斗回合 : " + turnNum + ",状态 " + State);
        }
        DistributeNextPackage();
@@ -454,14 +482,14 @@
                // 检查是否已经在处理死亡
                if (processingDeathObjIds.Contains(objID))
                {
                    Debug.LogWarning($"OnObjsDead: 角色正在处理死亡,忽略重复死亡消息 ObjID={objID}");
                    // Debug.LogWarning($"OnObjsDead: 角色正在处理死亡,忽略重复死亡消息 ObjID={objID}");
                    continue;
                }
                
                BattleObject battleObj = battleObjMgr.GetBattleObject((int)objID);
                if (battleObj == null)
                {
                    Debug.LogWarning($"OnObjsDead: 找不到角色 ObjID={objID}");
                    Debug.LogError($"OnObjsDead: 找不到角色 ObjID={objID}");
                    continue;
                }
                
@@ -674,6 +702,20 @@
        // 清理死亡处理记录
        processingDeathObjIds.Clear();
        // 清空当前战场的血量记录
        if (BattleHeroInfoBar.largestPackUID.ContainsKey(guid))
        {
            BattleHeroInfoBar.largestPackUID.Remove(guid);
        }
        if (BattleHeroInfoBar.largestPackUIDAllObjectsToHp.ContainsKey(guid))
        {
            BattleHeroInfoBar.largestPackUIDAllObjectsToHp.Remove(guid);
        }
        if (BattleHeroInfoBar.largestPackUIDAllObjectsMaxHp.ContainsKey(guid))
        {
            BattleHeroInfoBar.largestPackUIDAllObjectsMaxHp.Remove(guid);
        }
        // ===== 新增:卸载蓝队资源 =====
        BattleResManager.Instance.UnloadBattleResources(guid);
    }
Main/System/Battle/BattleUtility.cs
@@ -369,7 +369,7 @@
        battleHurtParam.hitIndex = hitIndex;
        battleHurtParam.deadPack = deadPack;
        battleHurtParam.skillConfig = skillConfig;
        battleHurtParam.packUID = skillBase.tagUseSkillAttack.packUID;
        return battleHurtParam;
    }
Main/System/Battle/Define/BattleDmgInfo.cs
@@ -472,6 +472,13 @@
        {
            return hurtObj != null ? hurtObj.teamHero.maxHp : 0;
        }
        set
        {
            if (hurtObj != null)
            {
                hurtObj.teamHero.maxHp = value;
            }
        }
    }
    public long fromShieldValue;
@@ -512,6 +519,13 @@
        {
            return casterObj != null ? casterObj.teamHero.maxHp : 0;
        }
        set
        {
            if (casterObj != null)
            {
                casterObj.teamHero.maxHp = value;
            }
        }
    }
    public long fromShieldValue;
@@ -531,5 +545,5 @@
    public BattleDeadPack deadPack;
    public SkillConfig skillConfig;
    public ulong packUID;
}
Main/System/Battle/TianziBillboradBattleWin.cs
@@ -38,6 +38,7 @@
        {
            UIManager.Instance.CloseWindow<MainWin>();
        }
        isClickSkip = false;
    }
    private void OnPlayUiEffectAction()
@@ -73,6 +74,42 @@
            bossBattleObject = null;
        }
        if (isClickSkip)
        {
            isClickSkip = false;
            TryPass();
        }
    }
    bool isClickSkip = false;
    protected override void OnClickPass()
    {
        if (!IsPass())
            return;
        battleField.ForceFinish();
        isClickSkip = true;
        clickTime = Time.time;  // 记录点击时间
    }
    float stayTime = 2f;
    float clickTime = 0f;
    void LateUpdate()
    {
        if (isClickSkip && Time.time - clickTime >= stayTime)
        {
            isClickSkip = false;
            TryPass();
        }
    }
    private void TryPass()
    {
        if (!UIManager.Instance.IsOpened<TianziBillboradVictoryWin>())
        {
            CloseWindow();
            BattleSettlementManager.Instance.WinShowOver(BattleConst.TianziBillboradBattleField);
            TianziBillboradManager.Instance.isSweepVictory = false;
        }
    }
    private void OnUpdateBarInfoEvent(ulong loaclNowHunt, ulong loaclMaxHp, int loaclHpNum)
Main/System/Battle/UIComp/BattleHeroInfoBar.cs
@@ -77,6 +77,11 @@
    private float tipsGCDTimer = 0f;
    private const int TIPS_GCD_FRAMES = 5;
    
    // 全局血量记录(按战场guid组织,以最大PackUID为准,记录所有对象:施法者和受击者)
    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>>();
    protected void OnDisable()
    {
        CleanupTips();
@@ -108,8 +113,10 @@
        // 护盾2的值 = max(当前血量 + 护盾值 - maxHp, 0) / maxHp
        float shield2Value = maxHp > 0 ? Mathf.Max((float)(curHp + shieldValue - maxHp), 0f) / (float)maxHp : 0;
        
        sliderShield1.value = shieldValue > 0 ? shield1Value : 0;
        sliderShield2.value = shieldValue > maxHp ? shield2Value : 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}");
@@ -152,8 +159,8 @@
        // 护盾2的值 = max(当前血量 + 护盾值 - maxHp, 0) / maxHp
        float shield2Value = maxHp > 0 ? Mathf.Max((float)(curHp + shieldValue - maxHp), 0f) / (float)maxHp : 0;
        
        sliderShield1.value = shieldValue > 0 ? shield1Value : 0;
        sliderShield2.value = shieldValue > maxHp ? shield2Value : 0;
        sliderShield1.value = shield1Value;
        sliderShield2.value = shield2Value;
        if (!battleObject.IsTianziBoss())
        {
@@ -293,40 +300,61 @@
    {
        KillTween(ref damageSequence);
        // 判断是目标视角还是施法者视角,使用对应的数据
        bool isCasterView = dmgInfo.hurtObj == dmgInfo.casterObj;
        string guid = battleObject.battleField.guid;
        long objID = battleObject.ObjID;
        ulong currentPackUID = dmgInfo.battleHurtParam.packUID;
        // 检查是否是最新的 PackUID,如果不是则忽略
        if (!largestPackUID.ContainsKey(guid) || currentPackUID < largestPackUID[guid])
        {
            // Debug.LogWarning($"[ExecuteDamageUpdate] 忽略旧包 - ObjID:{objID}, 当前PackUID:{currentPackUID} < 最大PackUID:{largestPackUID[guid]}");
            return;
        }
        
        long maxHp, fromHp, toHp, fromShield, toShield;
        
        if (isCasterView)
        {
            // 施法者视角:使用 caster 数据
            BattleCastObj caster = dmgInfo.battleHurtParam.caster;
            if (caster.casterObj != null && caster.casterObj.IsTianziBoss())
            {
                // 天子视角不处理护盾变化
                return;
            }
            maxHp = caster.maxHp;
            fromHp = caster.fromHp;
            toHp = caster.toHp;
            fromShield = caster.fromShieldValue;
            toShield = caster.toShieldValue;
        }
        else
        {
            // 目标视角:使用 hurter 数据
        // 优先判断当前InfoBar是否为受击者(血量变化总是体现在hurter里)
            BattleHurtObj hurter = dmgInfo.battleHurtParam.hurter;
            if (hurter.hurtObj != null && hurter.hurtObj.IsTianziBoss())
        if (hurter?.hurtObj != null && hurter.hurtObj.ObjID == objID)
            {
                // 天子视角不处理护盾变化
            // 当前InfoBar是受击者(包括给自己治疗、给自己造成伤害的情况)
            if (hurter.hurtObj.IsTianziBoss())
            {
                return;
            }
            // 直接使用 dmgInfo 中的数据(已经被 CompareAndExchangeLargestPackUIDHp 验证过)
            maxHp = hurter.maxHp;
            fromHp = hurter.fromHp;
            toHp = hurter.toHp;
            fromShield = hurter.fromShieldValue;
            toShield = hurter.toShieldValue;
            // 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;
            }
            if (caster.casterObj.IsTianziBoss())
            {
                return;
            }
            // 直接使用 dmgInfo 中的数据(已经被 CompareAndExchangeLargestPackUIDHp 验证过)
            maxHp = caster.maxHp;
            fromHp = caster.fromHp;
            toHp = caster.toHp;
            fromShield = caster.fromShieldValue;
            toShield = caster.toShieldValue;
            // Debug.LogError($"[ExecuteDamageUpdate] 施法者 - ObjID:{objID}, fromHp:{fromHp}, toHp:{toHp}, maxHp:{maxHp} (PackUID:{currentPackUID})");
        }
        if (maxHp <= 0)
@@ -418,6 +446,102 @@
        }
    }
    
    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>();
        }
        ulong currentLargestPackUID = largestPackUID[guid];
        Dictionary<long, long> hpDict = largestPackUIDAllObjectsToHp[guid];
        Dictionary<long, long> maxHpDict = largestPackUIDAllObjectsMaxHp[guid];
        // 如果遇到更大的packUID,更新标记(不清空数据,保留所有证据)
        if (currentPackUID > currentLargestPackUID)
        {
            // Debug.LogError($"[血量记录] 检测到新批次PackUID: {currentPackUID} > {currentLargestPackUID},保留所有历史数据");
            largestPackUID[guid] = currentPackUID;
            currentLargestPackUID = currentPackUID;
        }
        // 记录所有packUID的数据(包括早触发的包),但只采用最大packUID的数据
        // 记录施法者的血量变化
        if (dmgInfo.battleHurtParam.caster?.casterObj != null)
        {
            BattleCastObj caster = dmgInfo.battleHurtParam.caster;
            long casterID = caster.casterObj.ObjID;
            // 获取旧血量用于计算变化
            long oldHp = hpDict.ContainsKey(casterID) ? hpDict[casterID] : caster.fromHp;
            long newHp = caster.toHp;
            long maxHp = caster.maxHp;
            long hpChange = newHp - oldHp;
            // 只有当前packUID等于最大packUID时才更新记录
            if (currentPackUID == currentLargestPackUID)
            {
                hpDict[casterID] = newHp;
                maxHpDict[casterID] = maxHp;
                // 打印血量变化日志(施法者通常是恢复生命)
                // 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} < 最大PackUID:{currentLargestPackUID}");
            }
        }
        // 记录受击者的血量变化
        if (dmgInfo.battleHurtParam.hurter?.hurtObj != null)
        {
            BattleHurtObj hurter = dmgInfo.battleHurtParam.hurter;
            long hurterID = hurter.hurtObj.ObjID;
            // 获取旧血量用于计算伤害
            long oldHp = hpDict.ContainsKey(hurterID) ? hpDict[hurterID] : hurter.fromHp;
            long newHp = hurter.toHp;
            long maxHp = hurter.maxHp;
            long damage = oldHp - newHp;
            // 只有当前packUID等于最大packUID时才更新记录
            if (currentPackUID == currentLargestPackUID)
            {
                hpDict[hurterID] = newHp;
                maxHpDict[hurterID] = maxHp;
                // 打印血量变化日志
                // 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} < 最大PackUID:{currentLargestPackUID}");
            }
        }
    }
    /// <summary>
    /// 处理血条和伤害更新队列
    /// </summary>
@@ -427,6 +551,7 @@
        if (damageUpdateQueue.Count > 0)
        {
            BattleDmgInfo dmgInfo = damageUpdateQueue.Dequeue();
            CompareAndExchangeLargestPackUIDHp(dmgInfo);
            ExecuteDamageUpdate(dmgInfo);
            return;
        }