using DG.Tweening; using FL.Battle.Actions; using FL.Battle.Components; using System; using UnityEngine; using XGame.Database; using XGame.Framework; using XGame.Framework.Interfaces; namespace FL.Battle.Skills { /// /// 普通攻击 /// internal class AttackActor : ISkillActor { public ISkillContext Context { get; set; } void ISkillActor.Play(int skillId, ITarget target, Action onCompleted) { var owner = Context.Entity; if (Context.Entity.EntityType != EEntityType.Partner) { // 玩家或者怪物 PlaySkillAtk(target, onCompleted); //Context.Spine.Play(ActionName.attack, () => //{ // OnHitFrame(); // OnAttackEnd(); // Context.Spine.Play(ActionName.idle); // onCompleted?.Invoke(); //}); return; } // 随从 PartnerType partnerType = (PartnerType)((Context.Entity.TableId / 100) % 10); //单手剑、双手剑、法杖使用法术类型攻击 var isSkill = partnerType == PartnerType.Sword || partnerType == PartnerType.Wand; if (isSkill) { PlaySkillAtk(target, onCompleted); } else { PartnerNormalAtk(target, onCompleted); } } private void PlaySkillAtk(ITarget target, Action onCompleted) { var actArgs = new AnimationPlayArgs() { aniName = EAnimationName.attack, onCompleted = () => { //Context.Animator.Play(EAnimationName.idle/* + UnityEngine.Random.Range(0, 100) % 2*/); if (target == null || target.IsDead) { //OnAttackEnd(); onCompleted.SafeInvoke(0, Context.Entity.Attr.AttackCD); return; } var to = target.Position; var actMove = ObjectPool.Acquire(); actMove.args.from = Context.Position; actMove.args.to = to; actMove.args.duration = 500; var bulletArgs = ObjectPool.Acquire(); bulletArgs.vfxName = Context.Entity.EntityType == EEntityType.Partner ? "effect_atk_bullet_20181" : "atk_007"; bulletArgs.duration = 500; bulletArgs.followType = EVfxFollowType.World; bulletArgs.action = actMove; bulletArgs.onFinish = () => { OnHitFrame(target); }; var actPosition = ObjectPool.Acquire(); actPosition.position = to; var hitArgs = ObjectPool.Acquire(); hitArgs.vfxName = Context.Entity.EntityType == EEntityType.Partner ? "effect_atk_hit_20181" : "hit_007"; hitArgs.duration = 2000; hitArgs.followType = EVfxFollowType.World; hitArgs.action = actPosition; bulletArgs.next = hitArgs; Context.Vfx.Play(bulletArgs); //var dto = new SkillEffectDto() //{ // skillEffect = "", // skillTime = 667, // from = Context.Position, // to = _targetView.Position, // hpAdd = new HpAddDto() // { // position = _targetView.Position, // hpValue = hpValue, // } //}; //if (Context.Entity.EntityType == EEntityType.Partner) //{ // dto.hitEffect = "effect_atk_hit_20181"; // dto.bulletEffect = "effect_atk_bullet_20181"; //} //else //{ // dto.hitEffect = "hit_007"; // dto.bulletEffect = "atk_007"; //} //EventSingle.Instance.Notify(EventDefine.GameMainMapSkillEffect, dto); //OnAttackEnd(); onCompleted.SafeInvoke(0, Context.Entity.Attr.AttackCD); } }; Context.Animator.Play(actArgs); } private void PartnerNormalAtk(ITarget target, Action onCompleted) { var from = Context.Position; var to = target.Position; var distance = Vector3.Distance(from, to); var atkRange = 0;// _target.Attr.Radius; if (distance > atkRange) { // 大于攻击距离 //Log.Info($"PlayAttack:Owner:{Handle.Owner.EntityId} Target:{_target.EntityId}"); var dir = (to - from).normalized; var moveDis = distance - atkRange; var atkPosition = Context.ActionRoot.localPosition + dir * moveDis; //var moveTime = 0.42f;// Mathf.Abs(moveDis) / 5; Context.ActionRoot.localPosition = atkPosition; var actArgs = new AnimationPlayArgs() { aniName = EAnimationName.attack, onCompleted = () => { //Context.Animator.Play(EAnimationName.idle/* + UnityEngine.Random.Range(0, 100) % 2*/); Context.ActionRoot.localPosition = Vector3.zero; var endArgs = ObjectPool.Acquire(); endArgs.vfxName = "effect_melee_appear"; endArgs.duration = 500; Context.Vfx.Play(endArgs); OnHitFrame(target); //OnAttackEnd(); onCompleted.SafeInvoke(0, Context.Entity.Attr.AttackCD); } }; Context.Animator.Play(actArgs); var startArgs = ObjectPool.Acquire(); startArgs.vfxName = "effect_melee_blink"; startArgs.duration = 500; Context.Vfx.Play(startArgs); //MoveTo(atkPosition, moveTime, () => //{ // OnHitFrame(); // //moveback // MoveTo(Vector3.zero, moveTime, () => // { // OnAttackEnd(); // onCompleted?.Invoke(); // }); //}); } else { OnHitFrame(target); //OnAttackEnd(); onCompleted.SafeInvoke(0, Context.Entity.Attr.AttackCD); } } public void Stop() { Context.ActionRoot.DOKill(); Context.ActionRoot.localPosition = Vector3.zero; } private void MoveTo(Vector3 to, float duration, Action callback) { var tween = Context.ActionRoot.DOLocalMove(to, duration); tween.onComplete = () => { callback.SafeInvoke(); }; } private void OnHitFrame(ITarget target) { // 攻击帧回调 //TODO 目标受击 if (target == null || target.IsDead) return; target.Calculation.Damage(-Context.Entity.Attr.Attack, EElementType.None); } void IReference.Clear() { Stop(); Context = null; } //private void OnAttackEnd() //{ // _lastAtkTime = Context.Time.GetNowTime(); // //冷却计时 // var time = _lastAtkTime + Context.Entity.Attr.AttackCD; // _cdAlarm = Context.Time.AddAlarm(() => // { // Context.EnqueueSkill(0); // }, time); //} } }