| | |
| | | // 飘字GCD相关 |
| | | 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() |
| | | { |
| | |
| | | // 护盾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}"); |
| | | } |
| | |
| | | // 护盾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()) |
| | | { |
| | |
| | | { |
| | | 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) |
| | | // 优先判断当前InfoBar是否为受击者(血量变化总是体现在hurter里) |
| | | BattleHurtObj hurter = dmgInfo.battleHurtParam.hurter; |
| | | if (hurter?.hurtObj != null && hurter.hurtObj.ObjID == objID) |
| | | { |
| | | // 施法者视角:使用 caster 数据 |
| | | BattleCastObj caster = dmgInfo.battleHurtParam.caster; |
| | | if (caster.casterObj != null && caster.casterObj.IsTianziBoss()) |
| | | // 当前InfoBar是受击者(包括给自己治疗、给自己造成伤害的情况) |
| | | if (hurter.hurtObj.IsTianziBoss()) |
| | | { |
| | | // 天子视角不处理护盾变化 |
| | | return; |
| | | } |
| | | maxHp = caster.maxHp; |
| | | fromHp = caster.fromHp; |
| | | toHp = caster.toHp; |
| | | fromShield = caster.fromShieldValue; |
| | | toShield = caster.toShieldValue; |
| | | } |
| | | else |
| | | { |
| | | // 目标视角:使用 hurter 数据 |
| | | BattleHurtObj hurter = dmgInfo.battleHurtParam.hurter; |
| | | if (hurter.hurtObj != null && 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) |
| | |
| | | } |
| | | } |
| | | |
| | | 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> |
| | |
| | | if (damageUpdateQueue.Count > 0) |
| | | { |
| | | BattleDmgInfo dmgInfo = damageUpdateQueue.Dequeue(); |
| | | CompareAndExchangeLargestPackUIDHp(dmgInfo); |
| | | ExecuteDamageUpdate(dmgInfo); |
| | | return; |
| | | } |