using FL.Battle.Actions;
using System;
using System.Collections.Generic;
using UnityEngine;
using XGame.Database;
using XGame.Framework;
using XGame.Framework.Components;
using XGame.Framework.Time;
namespace FL.Battle.Components.AI
{
public interface ITrapAIContext
{
long UID { get; }
long MasterId { get; }
int TableId { get; }
ITargetSelector Selector { get; }
ITimeModule Time { get; }
Vector3 Position { get; }
VfxComponent Vfx { get; }
MoveComponent Move { get; }
GameObject ParticleRoot { get; }
}
///
/// AI组件和具体的EntityView绑定,其他Component最好不要尝试获取AI组件
///
public class TrapAI : Component
{
///
/// 陷阱特效半径
///
private const float TRAP_VFX_RAIDUS = 2.56f;
private ITimer _alertTimer;
private int _loopTimes;
private EEntityType _targetType;
private SkillTable _skill;
private SkillVfxsTable _skillVfxs;
protected override void OnDispose()
{
_skill = null;
_skillVfxs = null;
_alertTimer?.Cancel();
_alertTimer = null;
}
public void Start(Vector3 targetPosition, EEntityType targetType)
{
_skill = SkillTableRepo.Get(Context.TableId);
_skillVfxs = SkillVfxsTableRepo.Get(Context.TableId);
_targetType = targetType;
Context.ParticleRoot.SetActive(true);
//Context.AlertTr.localScale = new Vector3(0.5f, 0.5f, 0.1f);
//Context.BombTr.localScale = new Vector3(0.5f, 0.5f, 0.1f);
// 飞到目标位置
var moveArgs = new MoveArgs()
{
target = targetPosition,
speed = _skillVfxs.SkillVfxSpeed,
timeScale = 1,
moveType = (EMoveType)(_skillVfxs.SkillVfxMoveType - 1),
onComplete = OnMoveCompleted
};
if (Enum.TryParse(_skillVfxs.SkillVfxMoveEase, true, out var ease))
{
moveArgs.ease = ease;
}
Context.Move.MoveTo(moveArgs);
}
private void OnMoveCompleted()
{
Context.ParticleRoot.SetActive(false);
var scaleAct = ObjectPool.Acquire();
scaleAct.localScale = Vector3.one * (_skill.Ranges[0] / TRAP_VFX_RAIDUS);
//陷阱特效包含了陷阱展开的表现,特效时长直接加500毫秒给展开表现
var vfxArgs = ObjectPool.Acquire();
vfxArgs.vfxName = _skillVfxs.CustomArgs[0];
vfxArgs.duration = _skillVfxs.SkillVfxTime + 500;
vfxArgs.action = scaleAct;
Context.Vfx.Play(vfxArgs);
{
var interval = _skillVfxs.SkillVfxInterval;
_loopTimes = _skillVfxs.SkillVfxTime == -1 ? -1 : _skillVfxs.SkillVfxTime / interval;
_alertTimer = Context.Time.AddDelayLooperTimer(500, interval, OnAlert, _loopTimes);
};
}
///
/// 警戒事件的定时回调
///
///
private void OnAlert(int times)
{
if (times != _loopTimes)
{
var target = Context.Selector.FindSync(new FinderInfo()
{
uid = Context.UID,
position = Context.Position,
radius = _skill.Ranges[0]
}, _targetType, ETargetFindType.InRangeAlive);
if (target == null)
return;
}
_alertTimer.Cancel();
_alertTimer = null;
// 达到时间上限直接爆炸,或者有目标触发爆炸
//TODO 爆炸动作
var vfxArgs = ObjectPool.Acquire();
vfxArgs.vfxName = _skillVfxs.CustomArgs[1];
vfxArgs.duration = 500;
vfxArgs.onFinish = () =>
//var explodeRange = _skill.Ranges[1] * 2;
//// 缩放倍数是查询范围的两倍
//var tween = Context.BombTr.DOScale(new Vector3(explodeRange, explodeRange, 0.1f), 0.5f);
//tween.onComplete += () =>
{
var finder = new FinderInfo()
{
uid = Context.UID,
position = Context.Position,
radius = _skill.Ranges[1]
};
var targets = new List();
if (Context.Selector.FindTargets(finder, _targetType, ETargetFindType.InRangeAlive, null, ref targets))
{
// 计算受击伤害
foreach (var target in targets)
{
target.Calculation.Damage(-_skill.Damage, Context.MasterId, _skill);
}
}
EventSingle.Instance.Notify(EventDefine.GameMainMapRemoveSimpleEntity, Context.UID);
};
Context.Vfx.Play(vfxArgs);
}
}
}