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 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);
                }
            }
        }
        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 bool IsAiActionSatify(NpcInfo npc, CharacterInfo target, AiActionInfo aiActionInfo)
        {
            Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D();
            Vector3 srcPos    = npc.GetMovementStateInfo().GetPosition3D();
            float   dist      = Geometry.Distance(srcPos, targetPos);

            if (aiActionInfo.IsSatifyCD(TimeUtility.GetServerMilliseconds()) &&
                aiActionInfo.IsSatifyDis(dist) &&
                aiActionInfo.IsSatisfySelfHp(npc.Hp, npc.GetActualProperty().HpMax) &&
                aiActionInfo.IsSatisfyTargetHp(target.Hp, target.GetActualProperty().HpMax) &&
                aiActionInfo.IsSatifyUser(npc) &&
                aiActionInfo.IsLuckyEnough())
            {
                return(true);
            }
            return(false);
        }
        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();
                }
            }
        }
        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 AiActionInfo CreateAiAction(int id)
        {
            AiActionInfo   result = null;
            AiActionConfig config = AiActionConfigProvider.Instance.GetDataById(id);

            if (null != config)
            {
                if (config.AiActionType == (int)AiActionType.SKILL)
                {
                    result = new AiSkillActionInfo(config);
                }
                else
                {
                    result = new AiActionInfo(config);
                }
            }
            else
            {
                LogSystem.Warn("CreateAiAction:: can't find AiActionConfig {0}", id);
            }
            return(result);
        }
        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);
                        }
                    }
                }
            }
        }
        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();
                    }
                }
            }
        }
        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;
            if (!string.IsNullOrEmpty(info.AiParam[0]))
            {
                if (int.Parse(info.AiParam[0]) == 1)
                {
                    AiLogicUtility.InitPatrolData(npc, this);
                }
            }
            AiData_Npc_ActionDrive data = GetAiData(npc);

            if (null != data && !string.IsNullOrEmpty(info.AiParam[2]))
            {
                int      aiConfigId = int.Parse(info.AiParam[2]);
                AiConfig aiConfig   = AiConfigProvider.Instance.GetDataById(aiConfigId);
                if (null != aiConfig)
                {
                    for (int i = 0; i < aiConfig.ActionList.Count; i++)
                    {
                        AiActionInfo aiActionInfo = CreateAiAction(aiConfig.ActionList[i]);
                        if (null != aiActionInfo)
                        {
                            data.Actions.Add(aiActionInfo);
                        }
                    }
                    for (int i = 0; i < aiConfig.MaxControlEvent.Count; i++)
                    {
                        AiActionInfo aiActionInfo = CreateAiAction(aiConfig.MaxControlEvent[i]);
                        if (null != aiActionInfo)
                        {
                            data.MaxControlEventActions.Add(aiActionInfo);
                        }
                    }
                    for (int i = 0; i < aiConfig.MaxControlEventPlus.Count; i++)
                    {
                        AiActionInfo aiActionInfo = CreateAiAction(aiConfig.MaxControlEventPlus[i]);
                        if (null != aiActionInfo)
                        {
                            data.MaxControlEventPlusActions.Add(aiActionInfo);
                        }
                    }
                    for (int i = 0; i < aiConfig.GetUpEvent.Count; ++i)
                    {
                        AiActionInfo aiActionInfo = CreateAiAction(aiConfig.GetUpEvent[i]);
                        if (null != aiActionInfo)
                        {
                            data.GetUpEventActions.Add(aiActionInfo);
                        }
                    }

                    /*
                     * foreach (int id in aiConfig.ActionList) {
                     * AiActionInfo aiActionInfo = CreateAiAction(id);
                     * if (null != aiActionInfo) {
                     *  data.Actions.Add(aiActionInfo);
                     * }
                     * }
                     * foreach (int id in aiConfig.MaxControlEvent) {
                     * AiActionInfo aiActionInfo = CreateAiAction(id);
                     * if (null != aiActionInfo) {
                     *  data.MaxControlEventActions.Add(aiActionInfo);
                     * }
                     * }*/
                    data.MaxControlTime = aiConfig.MaxControlTime;
                }
            }
        }
        private void HandleSkillAction(NpcInfo npc, CharacterInfo target, long deltaTime)
        {
            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.GetSkillStateInfo().IsSkillActivated())
                {
                    AiSkillActionInfo skillActionInfo = aiActionInfo as AiSkillActionInfo;
                    if (null != skillActionInfo && skillActionInfo.CurSkillIndex < skillActionInfo.CurSkillCombo.Count)
                    {
                        int skillId = skillActionInfo.CurSkillCombo[skillActionInfo.CurSkillIndex];
                        if (AiLogicUtility.CanCastSkill(npc, skillId, target))
                        {
                            npc.GetMovementStateInfo().IsMoving = false;
                            NotifyNpcMove(npc);
                            if (TryCastSkill(npc, skillId, target))
                            {
                                skillActionInfo.CurSkillIndex++;
                            }
                        }
                        else
                        {
                            info.Time += deltaTime;
                            if (info.Time > m_IntervalTime)
                            {
                                info.Time = 0;
                                if (AiLogicUtility.IsTooCloseToCastSkill(npc, target))
                                {
                                    Vector3 escapePos = Vector3.Zero;
                                    if (AiLogicUtility.GetEscapeTargetPos(npc, target, 3.0f, ref escapePos))
                                    {
                                        NotifyNpcRun(npc);
                                        AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, escapePos, m_IntervalTime, true, this);
                                    }
                                }
                                else
                                {
                                    NotifyNpcRun(npc);
                                    AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                                }
                            }
                        }
                    }
                    else
                    {
                        skillActionInfo.CurSkillIndex = 0;
                        data.ActiveAction             = null;
                        aiActionInfo.LastStartTime    = TimeUtility.GetServerMilliseconds();
                    }
                }
                if ((!IsAiActionSatifyWithOutProbability(npc, target, aiActionInfo) && aiActionInfo.Config.CanInterrupt) || (aiActionInfo.IsTimeOut(TimeUtility.GetServerMilliseconds()) && !npc.GetSkillStateInfo().IsSkillActivated()))
                {
                    data.ActiveAction          = null;
                    aiActionInfo.LastStartTime = TimeUtility.GetServerMilliseconds();
                    NotifyNpcStopSkill(npc);
                }
            }
        }