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);
//}
}
}