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