/// <summary> /// 获生命值变动行为节点 /// </summary> /// <param name="paramsPacker"></param> /// <returns>生命值变动节点</returns> public override IFormula GetFormula(FormulaParamsPacker paramsPacker) { IFormula result = null; string errorMsg = null; if (paramsPacker == null) { errorMsg = "调用参数 paramsPacker 为空."; } else if (HealthChangeTarget != 0 && HealthChangeTarget != 1) { errorMsg = "目标标志错误, 应为0或1, 实际值:" + HealthChangeTarget; } else if ((paramsPacker.ReceiverMenber == null && HealthChangeTarget == 1) || (paramsPacker.ReleaseMember == null)) { errorMsg = "伤害/治疗目标对象为空."; } if (!string.IsNullOrEmpty(errorMsg)) { throw new Exception(errorMsg); } // 替换数据 ReplaceData(paramsPacker); // 数据本地化 var myFormulaType = FormulaType; var myHealthChageType = HealthChangeType; var myDemageOrCure = DemageOrCure; var myValue = Value.GetValue(); var myCoefficient = Coefficient.GetValue(); var myHealthChangeTarget = HealthChangeTarget; var targetDisPlayOwner = myHealthChangeTarget == 0 ? paramsPacker.ReleaseMember : paramsPacker.ReceiverMenber; var myIsNotLethal = paramsPacker.IsNotLethal; // 创建行为节点 result = new Formula((callback, scope) => { // 验证数据 if (targetDisPlayOwner.ClusterData == null) { return; } // 计算伤害/治疗量 var changeValue = 0f; // 区分伤害类型, 固定伤害, 计算伤害 changeValue = HurtResult.GetHurtForSkill(paramsPacker.ReleaseMember, targetDisPlayOwner, myDemageOrCure, myHealthChageType, CalculationType, myValue); // 伤害系数 changeValue *= myCoefficient; // 创建伤害/治疗事件 SkillManager.Single.SetTriggerData(new TriggerData() { HealthChangeValue = changeValue, ReceiveMember = paramsPacker.ReleaseMember, ReleaseMember = targetDisPlayOwner, TypeLevel1 = TriggerLevel1.Fight, TypeLevel2 = myDemageOrCure == DemageOrCure.Cure ? TriggerLevel2.BeCure : TriggerLevel2.BeAttack, IsNotLethal = myIsNotLethal, DemageType = DemageType.SkillAttackDemage }); callback(); }, myFormulaType); return result; }
public void Begin() { // 如果攻击者已死则不进行攻击 if (attacker == null) { return; } // 范围内选择单位 var memberList = ClusterManager.Single.CheckRange(graphics, attacker.AllData.MemberData.Camp, true); // 攻击者数据 var attackerDisplayOwner = DisplayerManager.Single.GetElementByPositionObject(attacker); // 所有单位扣除生命 foreach (var member in memberList) { // 被攻击者数据 var beAttackDisplayOwner = DisplayerManager.Single.GetElementByPositionObject(member); if (beAttackDisplayOwner == null || attackerDisplayOwner == null) { continue; } // 独计算是否命中, 是否伤害 var isMiss = HurtResult.AdjustIsMiss(attackerDisplayOwner, beAttackDisplayOwner); if (!isMiss) { // 计算伤害值 var hurt = HurtResult.GetHurt(attackerDisplayOwner, beAttackDisplayOwner); // 记录被击触发 记录扣血 伤害结算时结算 SkillManager.Single.SetTriggerData(new TriggerData() { HealthChangeValue = hurt, ReceiveMember = attackerDisplayOwner, ReleaseMember = beAttackDisplayOwner, TypeLevel1 = TriggerLevel1.Fight, TypeLevel2 = TriggerLevel2.BeAttack, DemageType = DemageType.NormalAttackDemage, IsCrit = HurtResult.IsCrit }); // 回调每个受击单位 if (callbackForEveryOne != null && member != null) { callbackForEveryOne(member.gameObject); } var effect = member.AllData.EffectData; var getHitEffect = effect.GetHitByBulletEffect; var getHitDurTime = 0f; // 分辨特效类型 switch (effect.BulletType) { case 1: getHitEffect = effect.GetHitByBulletEffect; getHitDurTime = effect.GetHitByBulletEffectTime; break; case 2: getHitEffect = effect.GetHitByBombEffect; getHitDurTime = effect.GetHitByBombEffectTime; break; } if (getHitDurTime > 0) { // 对每个单位播受击特效 // TODO 使用挂点 EffectsFactory.Single.CreatePointEffect(getHitEffect, ParentManager.Instance().GetParent(ParentManager.BallisticParent).transform, member.gameObject.transform.position, new Vector3(1, 1, 1), getHitDurTime, 0, null, Utils.EffectLayer).Begin(); } } else { // 闪避时事件 SkillManager.Single.SetTriggerData(new TriggerData() { ReceiveMember = attackerDisplayOwner, ReleaseMember = beAttackDisplayOwner, TypeLevel1 = TriggerLevel1.Fight, TypeLevel2 = TriggerLevel2.Dodge }); var beAttackVOBase = beAttackDisplayOwner.ClusterData.AllData.MemberData; // 抛出miss事件 FightManager.Single.DoHealthChangeAction(beAttackDisplayOwner.GameObj, beAttackVOBase.TotalHp, beAttackVOBase.CurrentHP, 0f, FightManager.HurtType.Miss, beAttackVOBase.ObjID.ObjType); } } // 播放特效 EffectsFactory.Single.CreatePointEffect(effectKey, ParentManager.Instance().GetParent(ParentManager.BallisticParent).transform, targetPos, new Vector3(1, 1, 1), durTime, 0, callback, Utils.EffectLayer).Begin(); }
/// <summary> /// /// </summary> /// <param name="attacker">攻击者数据</param> /// <param name="beAttackMember">被攻击者数据</param> /// <param name="effectKey">子弹预设key(或path)</param> /// <param name="releasePos">子弹飞行起点</param> /// <param name="targetObj">子弹目标单位</param> /// <param name="speed">子弹飞行速度</param> /// <param name="taType">子弹飞行轨迹</param> /// <param name="callback">攻击结束回调</param> public NormalGeneralAttack(PositionObject attacker, PositionObject beAttackMember, string effectKey, Vector3 releasePos, GameObject targetObj, float speed, TrajectoryAlgorithmType taType, Action <GameObject> callback) { if (attacker == null || beAttackMember == null) { //throw new Exception("被攻击者或攻击者数据为空"); return; } // 特效数据 var effectData = beAttackMember.AllData.EffectData; Action demage = () => { var attackerDisplayOwner = DisplayerManager.Single.GetElementByPositionObject(attacker); var beAttackerDisplayOwner = DisplayerManager.Single.GetElementByPositionObject(beAttackMember); if (beAttackerDisplayOwner == null || attackerDisplayOwner == null || null == beAttackerDisplayOwner.ClusterData || null == beAttackerDisplayOwner.RanderControl) { return; } // 判断是否命中 var isMiss = HurtResult.AdjustIsMiss(attackerDisplayOwner, beAttackerDisplayOwner); if (!isMiss) { // 计算伤害 // TODO 伤害计算加入Buff与技能的计算 var hurt = HurtResult.GetHurt(attackerDisplayOwner, beAttackerDisplayOwner); // 记录被击触发 记录扣血 伤害结算时结算 SkillManager.Single.SetTriggerData(new TriggerData() { HealthChangeValue = hurt, ReceiveMember = attackerDisplayOwner, ReleaseMember = beAttackerDisplayOwner, TypeLevel1 = TriggerLevel1.Fight, TypeLevel2 = TriggerLevel2.BeAttack, DemageType = DemageType.NormalAttackDemage, IsCrit = HurtResult.IsCrit }); // 命中时检测技能 SkillManager.Single.SetTriggerData(new TriggerData() { // 将造成的伤害带回 HealthChangeValue = hurt, ReceiveMember = beAttackerDisplayOwner, ReleaseMember = attackerDisplayOwner, TypeLevel1 = TriggerLevel1.Fight, TypeLevel2 = TriggerLevel2.Hit, DemageType = DemageType.NormalAttackDemage }); var getHitEffect = effectData.GetHitByBulletEffect; var getHitDurTime = 0f; // 分辨特效类型 switch (effectData.BulletType) { case 1: getHitEffect = effectData.GetHitByBulletEffect; getHitDurTime = effectData.GetHitByBulletEffectTime; break; case 2: getHitEffect = effectData.GetHitByBombEffect; getHitDurTime = effectData.GetHitByBombEffectTime; break; } if (getHitDurTime > 0) { // 对每个单位播受击特效 // 计算旋转角度 var beAttackAngle = Utils.GetAngleWithZ(attacker.gameObject.transform.forward) + 180; // TODO 使用挂点 EffectsFactory.Single.CreatePointEffect(getHitEffect, ParentManager.Instance().GetParent(ParentManager.BallisticParent).transform, beAttackMember.gameObject.transform.position, new Vector3(1, 1, 1), getHitDurTime, 0, null, Utils.EffectLayer, new Vector2(0, beAttackAngle)).Begin(); } } else { // 闪避时事件 SkillManager.Single.SetTriggerData(new TriggerData() { ReceiveMember = attackerDisplayOwner, ReleaseMember = beAttackerDisplayOwner, TypeLevel1 = TriggerLevel1.Fight, TypeLevel2 = TriggerLevel2.Dodge }); var beAttackVOBase = beAttackerDisplayOwner.ClusterData.AllData.MemberData; // 抛出miss事件 FightManager.Single.DoHealthChangeAction(beAttackerDisplayOwner.GameObj, beAttackVOBase.TotalHp, beAttackVOBase.CurrentHP, 0f, FightManager.HurtType.Miss, beAttackVOBase.ObjID.ObjType); } }; // 枪口火焰 var muzzleEffect = effectData.MuzzleFlashEffect; var muzzleDurTime = effectData.MuzzleFlashEffectTime; if (muzzleDurTime > 0) { // 对每个单位播枪口火焰特效 // 计算角度 var muzzleAngle = Utils.GetAngleWithZ(attacker.gameObject.transform.forward); // TODO 使用挂点 EffectsFactory.Single.CreatePointEffect(muzzleEffect, ParentManager.Instance().GetParent(ParentManager.BallisticParent).transform, attacker.gameObject.transform.position, new Vector3(1, 1, 1), muzzleDurTime, 0, null, Utils.EffectLayer, new Vector2(0, muzzleAngle)).Begin(); } Action action = () => { if (callback != null && beAttackMember) { callback(beAttackMember.gameObject); } }; effect = EffectsFactory.Single.CreatePointToObjEffect(effectKey, ParentManager.Instance().GetParent(ParentManager.BallisticParent).transform, releasePos, targetObj, new Vector3(1, 1, 1), speed, taType, demage + action, Utils.EffectLayer); }