private AiData_Npc_CommonMelee GetAiData(NpcInfo npc)
        {
            AiData_Npc_CommonMelee data = npc.GetAiStateInfo().AiDatas.GetData <AiData_Npc_CommonMelee>();

            if (null == data)
            {
                data = new AiData_Npc_CommonMelee();
                npc.GetAiStateInfo().AiDatas.AddData(data);
            }
            return(data);
        }
Exemplo n.º 2
0
        private AiData_Npc_BossHulun GetAiData(NpcInfo npc)
        {
            AiData_Npc_BossHulun data = npc.GetAiStateInfo().AiDatas.GetData <AiData_Npc_BossHulun>();

            if (null == data)
            {
                data = new AiData_Npc_BossHulun();
                npc.GetAiStateInfo().AiDatas.AddData(data);
            }
            return(data);
        }
Exemplo n.º 3
0
        private AiData_Npc_BossDevilWarrior GetAiData(NpcInfo npc)
        {
            AiData_Npc_BossDevilWarrior data = npc.GetAiStateInfo().AiDatas.GetData <AiData_Npc_BossDevilWarrior>();

            if (null == data)
            {
                data = new AiData_Npc_BossDevilWarrior();
                npc.GetAiStateInfo().AiDatas.AddData(data);
            }
            return(data);
        }
Exemplo n.º 4
0
        private AiData_Npc_BossXiLie GetAiData(NpcInfo npc)
        {
            AiData_Npc_BossXiLie data = npc.GetAiStateInfo().AiDatas.GetData <AiData_Npc_BossXiLie>();

            if (null == data)
            {
                data = new AiData_Npc_BossXiLie();
                npc.GetAiStateInfo().AiDatas.AddData(data);
            }
            return(data);
        }
Exemplo n.º 5
0
        private AiData_Npc_Bluelf GetAiData(NpcInfo npc)
        {
            AiData_Npc_Bluelf data = npc.GetAiStateInfo().AiDatas.GetData <AiData_Npc_Bluelf>();

            if (null == data)
            {
                data = new AiData_Npc_Bluelf();
                npc.GetAiStateInfo().AiDatas.AddData(data);
            }
            return(data);
        }
        private AiData_Npc_ActionDrive GetAiData(NpcInfo npc)
        {
            AiData_Npc_ActionDrive data = npc.GetAiStateInfo().AiDatas.GetData <AiData_Npc_ActionDrive>();

            if (null == data)
            {
                data = new AiData_Npc_ActionDrive();
                npc.GetAiStateInfo().AiDatas.AddData(data);
            }
            return(data);
        }
Exemplo n.º 7
0
 public void Execute(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
 {
     if (npc.GetAIEnable())
     {
         NpcAiStateInfo npcAi = npc.GetAiStateInfo();
         if (npcAi.CommandQueue.Count <= 0)
         {
             int curState = npcAi.CurState;
             if (curState > (int)AiStateId.Invalid && curState < (int)AiStateId.MaxNum)
             {
                 NpcAiStateHandler handler;
                 if (m_Handlers.TryGetValue(curState, out handler))
                 {
                     if (null != handler)
                     {
                         handler(npc, aiCmdDispatcher, deltaTime);
                     }
                 }
                 else
                 {
                     LogSystem.Error("Illegal ai state: " + curState + " npc:" + npc.GetId());
                 }
             }
             else
             {
                 OnStateLogicInit(npc, aiCmdDispatcher, deltaTime);
                 ChangeToState(npc, (int)AiStateId.Idle);
             }
         }
         ExecuteCommandQueue(npc, deltaTime);
     }
 }
        private void HandleTauntAction(NpcInfo npc, CharacterInfo target, long deltaTime)
        {
            if (npc.GetSkillStateInfo().IsSkillActivated())
            {
                return;
            }
            NpcAiStateInfo         info = npc.GetAiStateInfo();
            AiData_Npc_ActionDrive data = GetAiData(npc);

            if (null != data && null != target)
            {
                Vector3      targetPos    = target.GetMovementStateInfo().GetPosition3D();
                AiActionInfo aiActionInfo = data.ActiveAction;
                if (null != aiActionInfo)
                {
                    npc.GetMovementStateInfo().IsMoving = false;
                    npc.IsTaunt = true;
                    TrySeeTarget(npc, target);
                }
                if ((!IsAiActionSatify(npc, target, aiActionInfo) && aiActionInfo.Config.CanInterrupt) || aiActionInfo.IsTimeOut(TimeUtility.GetServerMilliseconds()))
                {
                    npc.IsTaunt                = false;
                    data.ActiveAction          = null;
                    aiActionInfo.LastStartTime = TimeUtility.GetServerMilliseconds();
                }
            }
        }
        private void HandleRunAction(NpcInfo npc, CharacterInfo target, long deltaTime)
        {
            if (npc.GetSkillStateInfo().IsSkillActivated())
            {
                return;
            }
            NpcAiStateInfo         info = npc.GetAiStateInfo();
            AiData_Npc_ActionDrive data = GetAiData(npc);

            if (null != data && null != target)
            {
                Vector3      targetPos    = target.GetMovementStateInfo().GetPosition3D();
                AiActionInfo aiActionInfo = data.ActiveAction;
                if (null != aiActionInfo)
                {
                    info.Time += deltaTime;
                    if (info.Time > m_IntervalTime)
                    {
                        info.Time = 0;
                        NotifyNpcRun(npc);
                        AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                    }
                }
                if ((!IsAiActionSatify(npc, target, aiActionInfo) && aiActionInfo.Config.CanInterrupt) || aiActionInfo.IsTimeOut(TimeUtility.GetServerMilliseconds()))
                {
                    data.ActiveAction          = null;
                    aiActionInfo.LastStartTime = TimeUtility.GetServerMilliseconds();
                }
            }
        }
        private AiActionInfo GetFitAiAction(NpcInfo npc)
        {
            NpcAiStateInfo         info = npc.GetAiStateInfo();
            AiData_Npc_ActionDrive data = GetAiData(npc);

            if (null != data)
            {
                CharacterInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(npc, info.Target);
                if (null != target)
                {
                    Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D();
                    Vector3 srcPos    = npc.GetMovementStateInfo().GetPosition3D();
                    float   dist      = Geometry.Distance(srcPos, targetPos);

                    for (int i = 0; i < data.Actions.Count; i++)
                    {
                        if (IsAiActionSatify(npc, target, data.Actions[i]))
                        {
                            return(data.Actions[i]);
                        }
                    }

                    /*
                     * foreach(AiActionInfo aiActionInfo in data.Actions){
                     * if(IsAiActionSatify(npc, target, aiActionInfo)){
                     * return aiActionInfo;
                     * }
                     * }*/
                }
            }
            return(null);
        }
Exemplo n.º 11
0
        private void GoHomeHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (!CanAiControl(npc))
            {
                npc.GetMovementStateInfo().IsMoving = false;
                return;
            }
            ChangeToState(npc, (int)AiStateId.Idle);
            NpcAiStateInfo info = npc.GetAiStateInfo();

            info.Time += deltaTime;
            if (info.Time > m_IntervalTime)
            {
                info.Time = 0;
                AiData_Demo_Melee data = GetAiData(npc);
                if (null != data)
                {
                    Vector3 targetPos     = info.HomePos;
                    Vector3 srcPos        = npc.GetMovementStateInfo().GetPosition3D();
                    float   powDistToHome = Geometry.DistanceSquare(srcPos, info.HomePos);
                    if (powDistToHome <= 1)
                    {
                        npc.GetMovementStateInfo().IsMoving = false;
                        info.Time = 0;
                        ChangeToState(npc, (int)AiStateId.Idle);
                    }
                    else
                    {
                        AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, 100, true, this);
                    }
                }
            }
        }
        private void ActionDriveHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (npc.IsDead())
            {
                npc.GetMovementStateInfo().IsMoving = false;
                return;
            }
            NpcAiStateInfo         info = npc.GetAiStateInfo();
            AiData_Npc_ActionDrive data = GetAiData(npc);

            if (null != data)
            {
                CharacterInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(npc, info.Target);
                if (null != target)
                {
                    Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D();
                    Vector3 srcPos    = npc.GetMovementStateInfo().GetPosition3D();
                    float   dist      = Geometry.Distance(srcPos, targetPos);
                    if (data.LastGfxState != npc.GfxStateFlag)
                    {
                        if (data.LastGfxState == (int)GfxCharacterState_Type.KnockDown && npc.GfxStateFlag == (int)GfxCharacterState_Type.GetUp)
                        {
                            // 起身
                            OnEvent(npc, (int)AiEventEnum.GET_UP, target, deltaTime);
                        }
                        data.LastGfxState = npc.GfxStateFlag;
                    }
                    if (npc.IsUnderControl())
                    {
                        data.ControlTime += deltaTime;
                        if (data.ControlTime > data.MaxControlTime && npc.CanDisControl())
                        {
                            data.ControlTime = 0;
                            OnEvent(npc, (int)AiEventEnum.CONTROL_TIME_OVERFLOW, target, deltaTime);
                        }
                        return;
                    }
                    ExecAiAction(npc, target, deltaTime);
                }
                else
                {
                    if (null != data.ActiveAction)
                    {
                        AiActionInfo aiActionInfo         = data.ActiveAction;
                        AiActionForceStopDelegate handler = GetAiActionForceStopHandler(aiActionInfo.Config.AiActionType);
                        if (null != handler)
                        {
                            handler(npc, target);
                        }
                    }
                    else
                    {
                        npc.GetMovementStateInfo().IsMoving = false;
                    }
                    ChangeToState(npc, (int)AiStateId.Pursuit);
                }
            }
        }
Exemplo n.º 13
0
        protected override void OnStateLogicInit(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            NpcAiStateInfo info = npc.GetAiStateInfo();

            info.Time = 0;
            npc.GetMovementStateInfo().IsMoving = false;
            info.HomePos = npc.GetMovementStateInfo().GetPosition3D();
            info.Target  = 0;
        }
Exemplo n.º 14
0
        private void TickNpc(NpcInfo npc, long delta)
        {
            INpcStateLogic logic = AiLogicManager.Instance.GetNpcStateLogic(npc.GetAiStateInfo().AiLogic);

            if (null != logic)
            {
                logic.Execute(npc, m_AiCommandDispatcher, delta);
                logic.UpdateTarget(npc);
            }
        }
        protected override void OnStateLogicInit(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            NpcAiStateInfo info = npc.GetAiStateInfo();

            info.Time = 0;
            npc.GetMovementStateInfo().IsMoving = false;
            info.Target = 0;
            BlackBoard_SmallMouse blackBoradInfo = GetBlackBorad(npc);

            blackBoradInfo.AddAliveNpc(npc.GetId());
        }
        private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (!CanAiControl(npc))
            {
                npc.GetMovementStateInfo().IsMoving = false;
                return;
            }
            NpcAiStateInfo         info = npc.GetAiStateInfo();
            AiData_Npc_ActionDrive data = GetAiData(npc);

            if (null != data)
            {
                CharacterInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(npc, info.Target);
                if (null != target)
                {
                    float   dist          = (float)npc.GetActualProperty().AttackRange;
                    float   distGoHome    = (float)npc.GohomeRange;
                    Vector3 targetPos     = target.GetMovementStateInfo().GetPosition3D();
                    Vector3 srcPos        = npc.GetMovementStateInfo().GetPosition3D();
                    float   powDist       = Geometry.DistanceSquare(srcPos, targetPos);
                    float   powDistToHome = Geometry.DistanceSquare(srcPos, info.HomePos);
                    // 遇敌是播放特效, 逗留两秒。
                    if (data.WaitTime <= npc.MeetEnemyStayTime)
                    {
                        if (!data.HasMeetEnemy)
                        {
                            NotifyNpcMeetEnemy(npc, Animation_Type.AT_Attack);
                            data.HasMeetEnemy = true;
                        }
                        TrySeeTarget(npc, target);
                        data.WaitTime += deltaTime;
                        return;
                    }
                    // 走向目标1.5秒
                    if (data.MeetEnemyWalkTime < npc.MeetEnemyWalkTime)
                    {
                        data.MeetEnemyWalkTime += deltaTime;
                        NotifyNpcWalk(npc);
                        info.Time += deltaTime;
                        if (info.Time > m_IntervalTime)
                        {
                            info.Time = 0;
                            AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                        }
                        return;
                    }
                    ChangeToState(npc, (int)AiStateId.ActionDrive);
                }
                else
                {
                    ChangeToState(npc, (int)AiStateId.Idle);
                }
            }
        }
Exemplo n.º 17
0
        private void IdleHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (!CanAiControl(npc))
            {
                npc.GetMovementStateInfo().IsMoving = false;
                return;
            }
            NpcAiStateInfo info = npc.GetAiStateInfo();

            info.Time += deltaTime;
            if (info.Time > 100)
            {
                info.Time = 0;
                if (GetAiData(npc).HasPatrolData)
                {
                    npc.GetMovementStateInfo().IsMoving = false;
                    ChangeToState(npc, (int)AiStateId.PatrolCommand);
                }
                else
                {
                    CharacterInfo target = null;
                    if (info.IsExternalTarget)
                    {
                        target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(npc, info.Target);
                        if (null == target)
                        {
                            target = AiLogicUtility.GetNearstTargetHelper(npc, CharacterRelation.RELATION_ENEMY);
                            if (null != target)
                            {
                                info.Target = target.GetId();
                            }
                        }
                    }
                    else
                    {
                        target = AiLogicUtility.GetNearstTargetHelper(npc, CharacterRelation.RELATION_ENEMY);
                        if (null != target)
                        {
                            info.Target = target.GetId();
                        }
                    }
                    if (null != target)
                    {
                        NotifyNpcTargetChange(npc);
                        npc.GetMovementStateInfo().IsMoving = false;
                        NotifyNpcMove(npc);
                        info.Time = 0;
                        ChangeToState(npc, (int)AiStateId.Pursuit);
                    }
                }
            }
        }
        private void NormalActionStartHandler(NpcInfo npc, CharacterInfo target)
        {
            NpcAiStateInfo         info = npc.GetAiStateInfo();
            AiData_Npc_ActionDrive data = GetAiData(npc);

            if (null != data && null != target)
            {
                AiActionInfo aiActionInfo = data.ActiveAction;
                if (null != aiActionInfo)
                {
                    //aiActionInfo.LastStartTime = TimeUtility.GetServerMilliseconds();
                    aiActionInfo.StartTime = TimeUtility.GetServerMilliseconds();
                }
            }
        }
        private void PathFindingCommandHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            // Path has found.
            if (!npc.UnityPathFinding)
            {
                return;
            }

            if (npc.PathFindingFinished)
            {
                // npc.PathFindingFinished = false;
                NpcAiStateInfo info = npc.GetAiStateInfo();
                ChangeToState(npc, info.PreviousState);
            }
        }
Exemplo n.º 20
0
        protected virtual void OnStateLogicInit(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            NpcAiStateInfo info = npc.GetAiStateInfo();

            info.Time = 0;
            npc.GetMovementStateInfo().IsMoving = false;
            info.HomePos = npc.GetMovementStateInfo().GetPosition3D();
            info.Target  = 0;
            if (!string.IsNullOrEmpty(info.AiParam[0]))
            {
                if (int.Parse(info.AiParam[0]) == 1)
                {
                    AiLogicUtility.InitPatrolData(npc, this);
                }
            }
        }
Exemplo n.º 21
0
        private void ExecuteCommandQueue(NpcInfo npc, long deltaTime)
        {
            NpcAiStateInfo npcAi = npc.GetAiStateInfo();

            while (npcAi.CommandQueue.Count > 0)
            {
                IAiCommand cmd = npcAi.CommandQueue.Peek();
                if (cmd.Execute(deltaTime))
                {
                    npcAi.CommandQueue.Dequeue();
                }
                else
                {
                    break;
                }
            }
        }
        private void NormalForceStopHandler(NpcInfo npc)
        {
            NpcAiStateInfo         info = npc.GetAiStateInfo();
            AiData_Npc_ActionDrive data = GetAiData(npc);

            if (null != data)
            {
                npc.GetMovementStateInfo().IsMoving = false;
                npc.IsTaunt = false;
                NotifyNpcRun(npc);
                AiActionInfo aiActionInfo = data.ActiveAction;
                if (null != aiActionInfo)
                {
                    data.ActiveAction          = null;
                    aiActionInfo.LastStartTime = TimeUtility.GetServerMilliseconds();
                }
            }
        }
Exemplo n.º 23
0
 public void UpdateTarget(NpcInfo npc)
 {
     if (npc.GetAIEnable())
     {
         NpcAiStateInfo npcAi   = npc.GetAiStateInfo();
         long           curTime = TimeUtility.GetServerMilliseconds();
         if (npcAi.Target > 0)
         {
             if (curTime > npcAi.LastChangeTargetTime + m_ChangeTargetCD && curTime > npc.GetCombatStatisticInfo().LastHitTime + m_MaxChaseTime)
             {
                 npcAi.Target = 0;
                 NotifyNpcTargetChange(npc);
                 npcAi.LastChangeTargetTime = curTime;
                 LogSystem.Debug("Npc {0} changed target", npc.GetId());
             }
         }
     }
 }
Exemplo n.º 24
0
        private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (!CanAiControl(npc))
            {
                npc.GetMovementStateInfo().IsMoving = false;
                return;
            }
            NpcAiStateInfo    info = npc.GetAiStateInfo();
            AiData_Demo_Melee data = GetAiData(npc);

            if (null != data)
            {
                CharacterInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(npc, info.Target);
                if (null != target)
                {
                    float   dist          = (float)npc.GetActualProperty().AttackRange;
                    float   distGoHome    = (float)npc.GohomeRange;
                    Vector3 targetPos     = target.GetMovementStateInfo().GetPosition3D();
                    Vector3 srcPos        = npc.GetMovementStateInfo().GetPosition3D();
                    float   powDist       = Geometry.DistanceSquare(srcPos, targetPos);
                    float   powDistToHome = Geometry.DistanceSquare(srcPos, info.HomePos);
                    if (powDist < dist * dist)
                    {
                        npc.GetMovementStateInfo().IsMoving = false;
                        info.Time = 0;
                        data.Time = 0;
                        ChangeToState(npc, (int)AiStateId.Combat);
                        NotifyNpcMove(npc);
                    }
                    else
                    {
                        info.Time += deltaTime;
                        if (info.Time > m_IntervalTime)
                        {
                            info.Time = 0;
                            AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                        }
                    }
                }
            }
        }
        private void HandleSelfImpactAction(NpcInfo npc, CharacterInfo target, long deltaTime)
        {
            if (npc.GetSkillStateInfo().IsSkillActivated())
            {
                return;
            }
            NpcAiStateInfo         info = npc.GetAiStateInfo();
            AiData_Npc_ActionDrive data = GetAiData(npc);

            if (null != data && null != target)
            {
                Vector3      targetPos    = target.GetMovementStateInfo().GetPosition3D();
                AiActionInfo aiActionInfo = data.ActiveAction;
                if (null != aiActionInfo && !String.IsNullOrEmpty(aiActionInfo.Config.ActionParam))
                {
                    NotifyNpcAddImpact(npc, int.Parse(aiActionInfo.Config.ActionParam));
                }
                data.ActiveAction          = null;
                aiActionInfo.LastStartTime = TimeUtility.GetServerMilliseconds();
            }
        }
        private void ExecAiAction(NpcInfo npc, CharacterInfo target, long deltaTime)
        {
            NpcAiStateInfo         info = npc.GetAiStateInfo();
            AiData_Npc_ActionDrive data = GetAiData(npc);

            if (null != info && null != data)
            {
                if (null != data.ActiveAction)
                {
                    AiActionInfo            aiActionInfo = data.ActiveAction;
                    AiActionExcueteDelegate handler      = GetAiActionExcuteHandler(aiActionInfo.Config.AiActionType);
                    if (null != handler)
                    {
                        handler(npc, target, deltaTime);
                    }
                }
                else
                {
                    if (data.ActionStack.Count > 0)
                    {
                        data.ActiveAction = data.ActionStack.Pop();
                    }
                    else
                    {
                        data.ActiveAction = GetFitAiAction(npc);
                    }
                    if (null != data.ActiveAction)
                    {
                        AiActionInfo          aiActionInfo = data.ActiveAction;
                        AiActionStartDelegate handler      = GetAiActionStartHandler(aiActionInfo.Config.AiActionType);
                        if (null != handler)
                        {
                            handler(npc, target);
                        }
                    }
                }
            }
        }
Exemplo n.º 27
0
 public virtual void StartImpact(CharacterInfo obj, int impactId)
 {
     if (null != obj)
     {
         ImpactInfo impactInfo = obj.GetSkillStateInfo().GetImpactInfoById(impactId);
         if (null != impactInfo)
         {
             if (impactInfo.ConfigData.BreakSuperArmor)
             {
                 obj.SuperArmor = false;
             }
         }
         if (obj is NpcInfo)
         {
             NpcInfo        npcObj = obj as NpcInfo;
             NpcAiStateInfo aiInfo = npcObj.GetAiStateInfo();
             if (null != aiInfo && 0 == aiInfo.HateTarget)
             {
                 aiInfo.HateTarget = impactInfo.m_ImpactSenderId;
             }
         }
     }
 }
        private void HandleFleeAction(NpcInfo npc, CharacterInfo target, long deltaTime)
        {
            if (npc.GetSkillStateInfo().IsSkillActivated())
            {
                return;
            }
            NpcAiStateInfo         info = npc.GetAiStateInfo();
            AiData_Npc_ActionDrive data = GetAiData(npc);

            if (null != data && null != target)
            {
                Vector3      targetPos    = Vector3.Zero;
                AiActionInfo aiActionInfo = data.ActiveAction;
                if (null != aiActionInfo)
                {
                    float anglePlus = 0.0f;
                    float.TryParse(aiActionInfo.Config.ActionParam, out anglePlus);
                    if (GetEscapeTargetPos(npc, target, 3.0f, anglePlus, ref targetPos))
                    {
                        info.Time += deltaTime;
                        if (info.Time > m_IntervalTime)
                        {
                            info.Time = 0;
                            NotifyNpcRun(npc);
                            AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                        }
                    }
                }
                if ((!IsAiActionSatify(npc, target, aiActionInfo) && aiActionInfo.Config.CanInterrupt) || aiActionInfo.IsTimeOut(TimeUtility.GetServerMilliseconds()))
                {
                    data.ActiveAction = null;
                    npc.GetMovementStateInfo().IsMoving = false;
                    NotifyNpcMove(npc);
                    aiActionInfo.LastStartTime = TimeUtility.GetServerMilliseconds();
                }
            }
        }
        private void HandleStandAction(NpcInfo npc, CharacterInfo target, long delatTime)
        {
            if (npc.GetSkillStateInfo().IsSkillActivated())
            {
                return;
            }
            NpcAiStateInfo         info = npc.GetAiStateInfo();
            AiData_Npc_ActionDrive data = GetAiData(npc);

            if (null != data && null != target)
            {
                npc.GetMovementStateInfo().IsMoving = false;
                NotifyNpcMove(npc);
                AiActionInfo aiActionInfo = data.ActiveAction;
                if (null != aiActionInfo)
                {
                    if ((!IsAiActionSatify(npc, target, aiActionInfo) && aiActionInfo.Config.CanInterrupt) || aiActionInfo.IsTimeOut(TimeUtility.GetServerMilliseconds()))
                    {
                        data.ActiveAction          = null;
                        aiActionInfo.LastStartTime = TimeUtility.GetServerMilliseconds();
                    }
                }
            }
        }
        private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (!CanAiControl(npc))
            {
                npc.GetMovementStateInfo().IsMoving = false;
                return;
            }
            NpcAiStateInfo         info = npc.GetAiStateInfo();
            AiData_Npc_CommonMelee data = GetAiData(npc);

            if (null != data)
            {
                CharacterInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(npc, info.Target);
                if (null != target)
                {
                    float   dist          = (float)npc.GetActualProperty().AttackRange;
                    float   distGoHome    = (float)npc.GohomeRange;
                    Vector3 targetPos     = target.GetMovementStateInfo().GetPosition3D();
                    Vector3 srcPos        = npc.GetMovementStateInfo().GetPosition3D();
                    float   powDist       = Geometry.DistanceSquare(srcPos, targetPos);
                    float   powDistToHome = Geometry.DistanceSquare(srcPos, info.HomePos);
                    // 遇敌是播放特效, 逗留两秒。
                    if (data.WaitTime <= npc.MeetEnemyStayTime)
                    {
                        if (!data.HasMeetEnemy)
                        {
                            NotifyNpcMeetEnemy(npc, Animation_Type.AT_Attack);
                            data.HasMeetEnemy = true;
                        }
                        TrySeeTarget(npc, target);
                        data.WaitTime += deltaTime;
                        return;
                    }
                    // 走向目标1.5秒
                    if (data.MeetEnemyWalkTime < npc.MeetEnemyWalkTime)
                    {
                        data.MeetEnemyWalkTime += deltaTime;
                        NotifyNpcWalk(npc);
                        info.Time += deltaTime;
                        if (info.Time > m_IntervalTime)
                        {
                            info.Time = 0;
                            if (!npc.UnityPathFinding)
                            {
                                AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                            }
                            else
                            {
                                if (!npc.PathFindingFinished)
                                {
                                    GfxSystem.NpcCommonMeleePathToTarget(npc, targetPos);
                                    ChangeToState(npc, (int)AiStateId.PathFinding);
                                }
                                else
                                {
                                    npc.PathFindingFinished = false;
                                    AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                                }
                            }
                        }
                        return;
                    }

                    // 大于攻击距离 跑向目标
                    if (powDist > m_AttackRange * m_AttackRange && 0 == data.CurAiAction)
                    {
                        npc.IsTaunt = false;
                        NotifyNpcRun(npc);
                        info.Time += deltaTime;
                        if (info.Time > m_IntervalTime)
                        {
                            info.Time = 0;
                            if (!npc.UnityPathFinding)
                            {
                                AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                            }
                            else
                            {
                                if (!npc.PathFindingFinished)
                                {
                                    GfxSystem.NpcCommonMeleePathToTarget(npc, targetPos);
                                    ChangeToState(npc, (int)AiStateId.PathFinding);
                                }
                                else
                                {
                                    npc.PathFindingFinished = false;
                                    AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                                }
                            }
                        }
                    }
                    else
                    {
                        //小于攻击距离
                        if (data.CurAiAction == (int)AiAction.NONE)
                        {
                            npc.GetMovementStateInfo().IsMoving = false;
                            NotifyNpcMove(npc);
                            data.CurAiAction = (int)GetNextAction();
                        }
                        switch (data.CurAiAction)
                        {
                        case (int)AiAction.SKILL:
                            if (0 >= data.SkillToCast)
                            {
                                data.SkillToCast = GetCanCastSkillId(npc, (float)Math.Sqrt(powDist));
                            }
                            if (0 >= data.SkillToCast || !AiLogicUtility.CanCastSkill(npc, data.SkillToCast, target))
                            {
                                info.Time += deltaTime;
                                if (info.Time > m_IntervalTime)
                                {
                                    info.Time = 0;
                                    NotifyNpcRun(npc);
                                    if (!npc.UnityPathFinding)
                                    {
                                        AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                                    }
                                    else
                                    {
                                        if (!npc.PathFindingFinished)
                                        {
                                            GfxSystem.NpcCommonMeleePathToTarget(npc, targetPos);
                                            ChangeToState(npc, (int)AiStateId.PathFinding);
                                        }
                                        else
                                        {
                                            npc.PathFindingFinished = false;
                                            AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                npc.GetMovementStateInfo().IsMoving = false;
                                NotifyNpcMove(npc);
                                if (TryCastSkill(npc, data.SkillToCast, target))
                                {
                                    data.CurAiAction = 0;
                                    data.SkillToCast = -1;
                                }
                            }
                            break;

                        case (int)AiAction.STAND:
                            data.ChaseStandTime += deltaTime;
                            TrySeeTarget(npc, target);
                            if (data.ChaseStandTime > m_ChaseWalkMaxTime)
                            {
                                data.ChaseStandTime = 0;
                                data.CurAiAction    = 0;
                            }
                            break;

                        case (int)AiAction.TAUNT:
                            npc.GetMovementStateInfo().IsMoving = false;
                            NotifyNpcMove(npc);
                            npc.IsTaunt     = true;
                            data.TauntTime += deltaTime;
                            TrySeeTarget(npc, target);
                            if (data.TauntTime > m_TauntTime)
                            {
                                npc.IsTaunt      = false;
                                data.TauntTime   = 0;
                                data.CurAiAction = 0;
                            }
                            break;

                        case (int)AiAction.WALK:
                            data.ChaseWalkTime += deltaTime;
                            info.Time          += deltaTime;
                            if (info.Time > m_IntervalTime)
                            {
                                info.Time = 0;
                                NotifyNpcWalk(npc);
                                if (!npc.UnityPathFinding)
                                {
                                    AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                                }
                                else
                                {
                                    if (!npc.PathFindingFinished)
                                    {
                                        GfxSystem.NpcCommonMeleePathToTarget(npc, targetPos);
                                        ChangeToState(npc, (int)AiStateId.PathFinding);
                                    }
                                    else
                                    {
                                        npc.PathFindingFinished = false;
                                        AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                                    }
                                }
                            }
                            if (data.ChaseWalkTime > m_ChaseStandMaxTime)
                            {
                                data.ChaseWalkTime = 0;
                                data.CurAiAction   = 0;
                            }
                            break;
                        }
                    }
                }
                else
                {
                    NotifyNpcTargetChange(npc);
                    npc.GetMovementStateInfo().IsMoving = false;
                    NotifyNpcMove(npc);
                    info.Time = 0;
                    ChangeToState(npc, (int)AiStateId.Idle);
                }
            }
        }