using System.Collections.Generic;
|
using System.Linq;
|
using UnityEngine;
|
|
// SkillBase(Hit 部分):命中阶段——OnHit 分发到主目标 / 溅射目标 / 命中提示。
|
public partial class SkillBase
|
{
|
// 命中目标回调:处理所有被命中的目标(包括主目标、弹射目标、溅射目标)
|
protected virtual void OnHitTargets(int _hitIndex, List<HB427_tagSCUseSkill.tagSCUseSkillHurt> hitList)
|
{
|
// Debug.LogError($"Skill {skillConfig.SkillID} hit targets _hitIndex: {_hitIndex} hit {string.Join(", ", hitList.Select(h => h.ObjID + ":" + battleField.battleObjMgr.GetBattleObject((int)h.ObjID)?.GetName()))}");
|
|
// 造成伤害前先处理血量刷新包
|
HandleRefreshHP();
|
|
bool suckHp = true;
|
|
// 处理主目标列表
|
foreach (var hurt in hitList)
|
{
|
BattleObject target = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
|
if (target == null)
|
{
|
Debug.LogError("目标为空 target == null ObjId : " + hurt.ObjID);
|
continue;
|
}
|
|
OnHitEachTarget(_hitIndex, target, hurt, suckHp);
|
|
suckHp = false;
|
|
// 处理该目标的额外目标列表(如弹射伤害的平摊目标)
|
if (hurt.HurtListEx != null && hurt.HurtListEx.Length > 0)
|
{
|
foreach (var hurtEx in hurt.HurtListEx)
|
{
|
BattleObject exTarget = caster.battleField.battleObjMgr.GetBattleObject((int)hurtEx.ObjID);
|
if (exTarget == null)
|
{
|
Debug.LogError($"额外目标为空 HurtListEx target == null ObjId : {hurtEx.ObjID}");
|
continue;
|
}
|
|
OnHitEachTargetEx(_hitIndex, exTarget, hurtEx);
|
}
|
}
|
}
|
|
// 处理技能包顶层的额外目标列表(如溅射伤害、平摊伤害)
|
if (tagUseSkillAttack.HurtListEx != null && tagUseSkillAttack.HurtListEx.Length > 0)
|
{
|
foreach (var hurtEx in tagUseSkillAttack.HurtListEx)
|
{
|
BattleObject exTarget = caster.battleField.battleObjMgr.GetBattleObject((int)hurtEx.ObjID);
|
if (exTarget == null)
|
{
|
Debug.LogError($"顶层额外目标为空 tagUseSkillAttack.HurtListEx target == null ObjId : {hurtEx.ObjID}");
|
continue;
|
}
|
|
OnHitEachTargetEx(_hitIndex, exTarget, hurtEx);
|
}
|
}
|
|
HandleHint(_hitIndex, hitList);
|
}
|
|
protected void HandleHint(int _hitIndex, List<HB427_tagSCUseSkill.tagSCUseSkillHurt> hitList)
|
{
|
if (0 == _hitIndex)
|
{
|
bool needhint = false;
|
|
for (int i = 0; i < hitList.Count; i++)
|
{
|
var hurt = hitList[i];
|
|
//8-击晕
|
if ((hurt.AttackTypes & (int)DamageType.Stunned) == (int)DamageType.Stunned)
|
{
|
needhint = true;
|
break;
|
}
|
|
for (int j = 0; j < hurt.HurtListEx?.Length; j++)
|
{
|
var hurtex = hurt.HurtListEx[j];
|
//8-击晕
|
if ((hurtex.AttackTypes & (int)ServerDamageType.Stunned) == (int)ServerDamageType.Stunned)
|
{
|
needhint = true;
|
break;
|
}
|
}
|
|
if (needhint)
|
break;
|
}
|
|
if (needhint)
|
{
|
DamageNumConfig hintConfig = DamageNumConfig.Get(BattleConst.BattleStun);
|
Hint(caster, hintConfig);
|
}
|
|
for (int i = 0; i < hitList.Count; i++)
|
{
|
var hurt = hitList[i];
|
|
if ((hurt.AttackTypes & (int)DamageType.BreakArmor) == (int)DamageType.BreakArmor)
|
{
|
BattleObject battleObject = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
|
if (battleObject != null)
|
{
|
DamageNumConfig hintConfig = DamageNumConfig.Get(BattleConst.BreakArmor);
|
Hint(battleObject, hintConfig);
|
battleField.battleEffectMgr.PlayEffect(battleObject,
|
BattleConst.BreakArmorEffectID, battleObject.GetRectTransform(), battleObject.Camp,
|
battleObject.GetModelScale());
|
}
|
}
|
else if ((hurt.AttackTypes & (int)DamageType.Parry) == (int)DamageType.Parry)
|
{
|
BattleObject battleObject = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
|
if (battleObject != null)
|
{
|
DamageNumConfig hintConfig = DamageNumConfig.Get(BattleConst.Parry);
|
Hint(battleObject, hintConfig);
|
battleField.battleEffectMgr.PlayEffect(battleObject,
|
BattleConst.ParryEffectID, battleObject.GetRectTransform(), battleObject.Camp,
|
battleObject.GetModelScale());
|
}
|
}
|
}
|
}
|
}
|
|
// 处理单个目标被命中:应用伤害和施法者效果
|
protected virtual void OnHitEachTarget(int _hitIndex, BattleObject target, HB427_tagSCUseSkill.tagSCUseSkillHurt hurt, bool suckHp)
|
{
|
// ============ 获取临时数据(掉落、死亡等) ============
|
int objID = (int)target.ObjID;
|
tempDropList.TryGetValue(objID, out BattleDrops battleDrops);
|
tempDeadPackList.TryGetValue(objID, out BattleDeadPack deadPack);
|
|
// 如果目标正在释放技能,跳过死亡处理(延迟到技能结束)
|
if (battleField != null && battleField.IsCastingSkill(target.ObjID))
|
{
|
deadPack = null;
|
}
|
|
// ============ 参数打包 ============
|
BattleHurtParam hurtParam = BattleUtility.CalcBattleHurtParam(this, _hitIndex, target, hurt, battleDrops, deadPack, suckHp);
|
#if UNITY_EDITOR
|
PrintHurtParamDebugInfo(hurtParam);
|
#endif
|
|
// 先调用目标受伤
|
DeathRecordAction recordAc = target.Hurt(hurtParam, ownRecordAction);
|
|
if (null != recordAc)
|
{
|
tempDeadPackList.Remove(hurtParam.hurter.hurtObj.ObjID);
|
ownRecordAction.GetInnerRecordPlayer().ImmediatelyPlay(recordAc, ownRecordAction, true);
|
currentWaitingSkill.Add(recordAc);
|
}
|
|
// 再调用施法者吸血/反伤
|
caster.OnHurtTarget(hurtParam);
|
}
|
|
// 处理额外目标被命中(HurtListEx):溅射、弹射、平摊伤害等
|
protected virtual void OnHitEachTargetEx(int _hitIndex, BattleObject target, HB427_tagSCUseSkill.tagSCUseSkillHurtEx hurtEx)
|
{
|
// ============ 获取临时数据(掉落、死亡等) ============
|
int objID = (int)target.ObjID;
|
tempDropList.TryGetValue(objID, out BattleDrops battleDrops);
|
|
tempDeadPackList.TryGetValue(objID, out BattleDeadPack deadPack);
|
|
// 如果目标正在释放技能,跳过死亡处理(延迟到技能结束)
|
if (battleField != null && battleField.IsCastingSkill(target.ObjID))
|
{
|
deadPack = null;
|
}
|
// ============ 参数打包(将 tagSCUseSkillHurtEx 转换为 tagSCUseSkillHurt)============
|
HB427_tagSCUseSkill.tagSCUseSkillHurt hurt = new HB427_tagSCUseSkill.tagSCUseSkillHurt
|
{
|
ObjID = hurtEx.ObjID,
|
AttackTypes = hurtEx.AttackTypes,
|
HurtHP = hurtEx.HurtHP,
|
HurtHPEx = hurtEx.HurtHPEx,
|
CurHP = hurtEx.CurHP,
|
CurHPEx = hurtEx.CurHPEx,
|
SuckHP = 0,//hurtEx.SuckHP, 获取全部吸血时已经计算过 这里就不再计算
|
BounceHP = 0, // HurtEx 没有反伤字段
|
HurtCountEx = 0,
|
HurtListEx = null
|
};
|
|
OnHitEachTarget(_hitIndex, target, hurt, false);//获取全部吸血时已经计算过 这里就不再计算
|
}
|
|
#if UNITY_EDITOR
|
private void PrintHurtParamDebugInfo(BattleHurtParam hurtParam)
|
{
|
bool isLastHit = hurtParam.hitIndex >= hurtParam.skillSkinConfig.DamageDivide.Length - 1;
|
|
long currentHitDamage = hurtParam.hurter.damageList != null ? hurtParam.hurter.damageList.Sum() : 0;
|
long currentHitSuckHp = hurtParam.caster.suckHpList != null ? hurtParam.caster.suckHpList.Sum() : 0;
|
long currentHitReflectHp = hurtParam.caster.reflectHpList != null ? hurtParam.caster.reflectHpList.Sum() : 0;
|
|
long totalDamage = GeneralDefine.GetFactValue(hurtParam.hurt.HurtHP, hurtParam.hurt.HurtHPEx);
|
long totalSuckHp = BattleUtility.GetSuckHp(tagUseSkillAttack);
|
long totalReflectHp = hurtParam.hurt.BounceHP;
|
|
BattleDebug.LogError(
|
(hurtParam.caster.casterObj.Camp == BattleCamp.Red ? "【红方行动】" : "【蓝方行动】 ") +
|
$"攻击者: {hurtParam.caster.casterObj.GetName()} (ObjID:{hurtParam.caster.casterObj.ObjID})\n" +
|
$"目标: {hurtParam.hurter.hurtObj.GetName()} (ObjID:{hurtParam.hurter.hurtObj.ObjID})\n" +
|
$"技能: {hurtParam.skillConfig.SkillName} (ID:{hurtParam.skillConfig.SkillID})\n" +
|
$"击数: 第{hurtParam.hitIndex + 1}击 / 共{hurtParam.skillSkinConfig.DamageDivide.Length}击" + (isLastHit ? " [最后一击]" : " [中间击]") + "\n" +
|
$"\n" +
|
$"========== 目标受伤数据 ==========\n" +
|
$"伤害: {currentHitDamage} / 总伤害: {totalDamage}\n" +
|
$"伤害分段: [{string.Join(", ", hurtParam.hurter.damageList ?? new System.Collections.Generic.List<long>())}]\n" +
|
$"目标血量: {hurtParam.hurter.fromHp} -> {hurtParam.hurter.toHp} (最大:{hurtParam.hurter.maxHp})\n" +
|
$"目标护盾: {hurtParam.hurter.fromShieldValue} -> {hurtParam.hurter.toShieldValue}\n" +
|
$"攻击类型: {hurtParam.hurt.AttackTypes}\n" +
|
$"\n" +
|
$"========== 施法者数据 ==========\n" +
|
$"吸血: {currentHitSuckHp} / 总吸血: {totalSuckHp}\n" +
|
$"吸血分段: [{string.Join(", ", hurtParam.caster.suckHpList ?? new System.Collections.Generic.List<long>())}]\n" +
|
$"反伤: {currentHitReflectHp} / 总反伤: {totalReflectHp}\n" +
|
$"反伤分段: [{string.Join(", ", hurtParam.caster.reflectHpList ?? new System.Collections.Generic.List<long>())}]\n" +
|
$"施法者血量: {hurtParam.caster.fromHp} -> {hurtParam.caster.toHp} (最大:{hurtParam.caster.maxHp})\n" +
|
$"施法者护盾: {hurtParam.caster.fromShieldValue} -> {hurtParam.caster.toShieldValue}\n"
|
);
|
}
|
#endif
|
}
|