private void GoHomeHandler(EntityInfo entity, long deltaTime)
        {
            AiStateInfo info = entity.GetAiStateInfo();

            info.Time += deltaTime;
            if (info.Time > c_IntervalTime)
            {
                info.Time = 0;
                AiData_General data = GetAiData(entity);
                if (null != data)
                {
                    Vector3 targetPos            = info.HomePos;
                    ScriptRuntime.Vector3 srcPos = entity.GetMovementStateInfo().GetPosition3D();
                    float powDistToHome          = Geometry.DistanceSquare(srcPos, info.HomePos);
                    if (powDistToHome <= 1)
                    {
                        NotifyAiStopPursue(entity);
                        ChangeToState(entity, (int)AiStateId.Idle);
                    }
                    else
                    {
                        NotifyAiPursue(entity, targetPos);
                    }
                }
            }
        }
        public void SetLockTarget(int targetId)
        {
            int oldTargetId = 0;

            if (null != m_SelectedTarget)
            {
                oldTargetId = m_SelectedTarget.TargetId;
            }
            OnSelectedTargetChange(oldTargetId, targetId);
            EntityInfo target = GetEntityById(targetId);

            if (null != target)
            {
                m_SelectedTarget = new LockTargetInfo {
                    Target = target, TargetId = targetId
                };
                EntityInfo leader = GetEntityById(LeaderId);
                if (null != leader)
                {
                    AiStateInfo aiInfo = leader.GetAiStateInfo();
                    if (null != SelectedTarget)
                    {
                        aiInfo.Target = SelectedTarget.TargetId;
                    }
                }
            }
            else
            {
                m_SelectedTarget = null;
            }
        }
        public bool CastSkill(int objId, int skillId)
        {
            bool       ret = false;
            EntityInfo obj = GetEntityById(objId);

            if (null != obj)
            {
                SkillInfo skillInfo = obj.GetSkillStateInfo().GetSkillInfoById(skillId);
                if (null != skillInfo)
                {
                    if (!skillInfo.IsInCd(TimeUtility.GetLocalMilliseconds()))
                    {
                        int targetId = 0;
                        if (null != SelectedTarget)
                        {
                            targetId = SelectedTarget.TargetId;
                        }
                        if (!IsBattleState)
                        {
                            Network.NetworkSystem.Instance.SyncPlayerSkill(obj, skillId, targetId, obj.GetMovementStateInfo().GetFaceDir());
                        }
                        else
                        {
                            AiStateInfo aiInfo = obj.GetAiStateInfo();
                            aiInfo.Target = targetId;
                            GfxSkillSystem.Instance.StartSkill(objId, skillInfo.ConfigData, 0);
                        }
                        ret = true;
                    }
                }
            }
            return(ret);
        }
        internal static void Execute(object msg, User user)
        {
            Msg_CR_OperateMode modeMsg = msg as Msg_CR_OperateMode;

            if (null == modeMsg)
            {
                return;
            }
            EntityInfo userInfo = user.Info;

            if (null == userInfo)
            {
                return;
            }

            AiStateInfo   aiInfo = userInfo.GetAiStateInfo();
            AiData_Leader data   = aiInfo.AiDatas.GetData <AiData_Leader>();

            if (null == data)
            {
                data = new AiData_Leader();
                aiInfo.AiDatas.AddData(data);
            }
            data.IsAutoOperate = modeMsg.isauto;
        }
        protected override void OnStateLogicInit(EntityInfo entity, long deltaTime)
        {
            AiStateInfo info = entity.GetAiStateInfo();

            info.Time    = 0;
            info.HomePos = entity.GetMovementStateInfo().GetPosition3D();
            info.Target  = 0;
        }
        internal static void Execute(object msg, User user)
        {
            Msg_CR_Skill use_skill = msg as Msg_CR_Skill;

            if (null == use_skill)
            {
                return;
            }
            EntityInfo userObj = user.Info;

            if (null == userObj)
            {
                LogSys.Log(LOG_TYPE.DEBUG, "UseSkillHandler, charactor {0}({1},{2},{3}) not exist", user.RoleId, user.GetKey(), user.Guid, user.Name);
                return;
            }
            Scene scene = user.OwnRoom.ActiveScene;

            if (null != scene)
            {
                EntityInfo obj = scene.GetEntityById(use_skill.role_id);
                if (null != obj)
                {
                    AiStateInfo aiInfo = obj.GetAiStateInfo();
                    if (use_skill.target_id > 0)
                    {
                        aiInfo.Target = use_skill.target_id;
                    }
                    else if (use_skill.target_dir > 0)
                    {
                        float dir = ProtoHelper.DecodeFloat(use_skill.target_dir);
                        obj.GetMovementStateInfo().SetFaceDir(dir);
                        aiInfo.Target = 0;
                    }
                    if (aiInfo.AiLogic == (int)AiStateLogicId.Entity_Leader)
                    {
                        AiData_Leader data = aiInfo.AiDatas.GetData <AiData_Leader>();
                        if (null == data)
                        {
                            data = new AiData_Leader();
                            aiInfo.AiDatas.AddData(data);
                        }
                        data.ManualSkillId = use_skill.skill_id;
                    }
                    else
                    {
                        AiData_General data = aiInfo.AiDatas.GetData <AiData_General>();
                        if (null == data)
                        {
                            data = new AiData_General();
                            aiInfo.AiDatas.AddData(data);
                        }
                        data.ManualSkillId = use_skill.skill_id;
                    }
                    aiInfo.ChangeToState((int)AiStateId.SkillCommand);
                }
            }
        }
        public bool CastSkill(int objId, int skillId)
        {
            bool       ret = false;
            EntityInfo obj = GetEntityById(objId);

            if (null != obj)
            {
                SkillInfo skillInfo = obj.GetSkillStateInfo().GetSkillInfoById(skillId);
                if (null != skillInfo)
                {
                    if (obj.Energy >= obj.GetActualProperty().EnergyMax)
                    {
                        if (!skillInfo.IsInCd(TimeUtility.GetLocalMilliseconds()))
                        {
                            int targetId = 0;
                            if (null != SelectedTarget)
                            {
                                targetId = SelectedTarget.TargetId;
                            }
                            if (IsRoomScene)
                            {
                                Network.NetworkSystem.Instance.SyncPlayerSkill(obj, skillId, targetId, obj.GetMovementStateInfo().GetFaceDir());
                            }
                            else
                            {
                                AiStateInfo aiInfo = obj.GetAiStateInfo();
                                aiInfo.Target = targetId;
                                if (aiInfo.AiLogic == (int)AiStateLogicId.Entity_Leader)
                                {
                                    AiData_Leader data = aiInfo.AiDatas.GetData <AiData_Leader>();
                                    if (null == data)
                                    {
                                        data = new AiData_Leader();
                                        aiInfo.AiDatas.AddData(data);
                                    }
                                    data.ManualSkillId = skillId;
                                }
                                else
                                {
                                    AiData_General data = aiInfo.AiDatas.GetData <AiData_General>();
                                    if (null == data)
                                    {
                                        data = new AiData_General();
                                        aiInfo.AiDatas.AddData(data);
                                    }
                                    data.ManualSkillId = skillId;
                                }
                                aiInfo.ChangeToState((int)AiStateId.SkillCommand);
                            }
                            ret = true;
                        }
                    }
                }
            }
            return(ret);
        }
        private void DslLogicHandler(EntityInfo entity, long deltaTime)
        {
            AiStateInfo info = entity.GetAiStateInfo();

            if (null != info.AiStoryInstanceInfo)
            {
                long curTime = TimeUtility.GetLocalMilliseconds();
                info.AiStoryInstanceInfo.m_StoryInstance.Tick(curTime);
            }
        }
        private void IdleHandler(EntityInfo entity, long deltaTime)
        {
            AiStateInfo info = entity.GetAiStateInfo();

            info.Time += deltaTime;
            if (info.Time > 100)
            {
                info.Time = 0;
                ChangeToState(entity, (int)AiStateId.DslLogic);
            }
        }
        private bool IsLeaderDead(EntityInfo entity)
        {
            bool           ret    = true;
            AiStateInfo    info   = entity.GetAiStateInfo();
            AiData_General data   = GetAiData(entity);
            EntityInfo     leader = AiLogicUtility.GetLivingCharacterInfoHelper(entity, info.LeaderID);

            if (null != leader)
            {
                ret = leader.IsDead();
            }
            return(ret);
        }
 static public int set_AiStoryInstanceInfo(IntPtr l)
 {
     try {
         GameFramework.AiStateInfo         self = (GameFramework.AiStateInfo)checkSelf(l);
         GameFramework.AiStoryInstanceInfo v;
         checkType(l, 2, out v);
         self.AiStoryInstanceInfo = v;
         pushValue(l, true);
         return(1);
     }
     catch (Exception e) {
         return(error(l, e));
     }
 }
 static public int PushState(IntPtr l)
 {
     try {
         GameFramework.AiStateInfo self = (GameFramework.AiStateInfo)checkSelf(l);
         System.Int32 a1;
         checkType(l, 2, out a1);
         self.PushState(a1);
         pushValue(l, true);
         return(1);
     }
     catch (Exception e) {
         return(error(l, e));
     }
 }
        public static void Execute(object msg, User user)
        {
            Msg_CR_OperateMode modeMsg = msg as Msg_CR_OperateMode;

            if (null == modeMsg)
            {
                return;
            }
            EntityInfo userInfo = user.Info;

            if (null == userInfo)
            {
                return;
            }

            AiStateInfo aiInfo = userInfo.GetAiStateInfo();
        }
        private void AttachAiLogic(EntityInfo npc)
        {
            AiStateInfo aiInfo    = npc.GetAiStateInfo();
            string      storyId   = aiInfo.AiLogic;
            string      storyFile = aiInfo.AiParam[0];

            if (!string.IsNullOrEmpty(storyId) && !string.IsNullOrEmpty(storyFile))
            {
                aiInfo.HomePos = npc.GetMovementStateInfo().GetPosition3D();
                aiInfo.ChangeToState((int)PredefinedAiStateId.Idle);
                aiInfo.AiStoryInstanceInfo = GfxStorySystem.Instance.NewAiStoryInstance(storyId, string.Empty, storyFile);
                if (null != aiInfo.AiStoryInstanceInfo)
                {
                    aiInfo.AiStoryInstanceInfo.m_StoryInstance.SetVariable("@objid", npc.GetId());
                    aiInfo.AiStoryInstanceInfo.m_StoryInstance.Start();
                }
            }
        }
        internal static void DoMoveCommandState(EntityInfo entity, long deltaTime, AbstractAiStateLogic logic)
        {
            //执行状态处理
            AiData_ForMoveCommand data = GetAiDataForMoveCommand(entity);

            if (null == data)
            {
                return;
            }

            if (!data.IsFinish)
            {
                if (WayPointArrived(entity, data))
                {
                    Vector3 targetPos = new Vector3();
                    MoveToNext(entity, data, ref targetPos);
                    if (!data.IsFinish)
                    {
                        logic.NotifyAiPursue(entity, targetPos);
                    }
                }
                else
                {
                    AiStateInfo info = entity.GetAiStateInfo();
                    info.Time += deltaTime;
                    if (info.Time > 500)
                    {
                        info.Time = 0;
                        Vector3 targetPos = data.WayPoints[data.Index];
                        logic.NotifyAiPursue(entity, targetPos);
                    }
                }
            }

            //判断是否状态结束并执行相应处理
            if (data.IsFinish)
            {
                logic.AiSendStoryMessage(entity, "npc_arrived:" + entity.GetUnitId(), entity.GetId());
                logic.AiSendStoryMessage(entity, "obj_arrived", entity.GetId());
                logic.NotifyAiStopPursue(entity);
                logic.ChangeToState(entity, (int)AiStateId.Idle);
            }
        }
        private void OnAiInitDslLogic(EntityInfo entity)
        {
            AiStateInfo aiInfo = entity.GetAiStateInfo();

            if (aiInfo.AiParam.Length >= 2)
            {
                string storyId   = aiInfo.AiParam[0];
                string storyFile = aiInfo.AiParam[1];
                if (!string.IsNullOrEmpty(storyId) && !string.IsNullOrEmpty(storyFile))
                {
                    aiInfo.AiStoryInstanceInfo = GfxStorySystem.Instance.NewAiStoryInstance(storyId, string.Empty, storyFile);
                    if (null != aiInfo.AiStoryInstanceInfo)
                    {
                        aiInfo.AiStoryInstanceInfo.m_StoryInstance.SetVariable("@objid", entity.GetId());
                        aiInfo.AiStoryInstanceInfo.m_StoryInstance.Start();
                    }
                }
            }
        }
 internal static void DoSkillCommandState(EntityInfo entity, long deltaTime, AbstractAiStateLogic logic, int skillId)
 {
     if (entity.GetMovementStateInfo().IsMoving)
     {
         logic.NotifyAiStopPursue(entity);
     }
     if (skillId > 0)
     {
         AiStateInfo aiInfo    = entity.GetAiStateInfo();
         SkillInfo   skillInfo = entity.GetSkillStateInfo().GetSkillInfoById(skillId);
         if (null != skillInfo)
         {
             if (aiInfo.Target <= 0)
             {
                 EntityInfo info;
                 if (skillInfo.ConfigData.targetType == (int)SkillTargetType.Enemy || skillInfo.ConfigData.targetType == (int)SkillTargetType.RandEnemy)
                 {
                     info = GetNearstTargetHelper(entity, CharacterRelation.RELATION_ENEMY);
                 }
                 else
                 {
                     info = GetNearstTargetHelper(entity, CharacterRelation.RELATION_FRIEND);
                 }
                 if (null != info)
                 {
                     aiInfo.Target = info.GetId();
                 }
             }
             if (aiInfo.Target > 0)
             {
                 logic.NotifyAiSkill(entity, skillId);
             }
         }
     }
     else if (!entity.GetSkillStateInfo().IsSkillActivated())
     {
         logic.AiSendStoryMessage(entity, "npc_skill_finish:" + entity.GetUnitId(), entity.GetId());
         logic.AiSendStoryMessage(entity, "obj_skill_finish", entity.GetId());
         logic.ChangeToState(entity, (int)AiStateId.Idle);
     }
 }
        internal static void DoPursuitCommandState(EntityInfo entity, long deltaTime, AbstractAiStateLogic logic)
        {
            AiStateInfo info = entity.GetAiStateInfo();

            info.Time += deltaTime;
            if (info.Time > 200)
            {
                EntityInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(entity, info.Target);
                if (null != target)
                {
                    float   minDist              = entity.GetRadius() + target.GetRadius();
                    float   dist                 = (float)entity.GetActualProperty().AttackRange + minDist;
                    float   distGoHome           = entity.GohomeRange;
                    Vector3 targetPos            = target.GetMovementStateInfo().GetPosition3D();
                    ScriptRuntime.Vector3 srcPos = entity.GetMovementStateInfo().GetPosition3D();
                    float dir = Geometry.GetYRadian(new Vector2(targetPos.X, targetPos.Z), new Vector2(srcPos.X, srcPos.Z));
                    targetPos.X += (float)(minDist * Math.Sin(dir));
                    targetPos.Z += (float)(minDist * Math.Cos(dir));
                    float powDist = Geometry.DistanceSquare(srcPos, targetPos);
                    if (powDist < dist * dist)
                    {
                        logic.AiSendStoryMessage(entity, "npc_pursuit_finish:" + entity.GetUnitId(), entity.GetId());
                        logic.AiSendStoryMessage(entity, "obj_pursuit_finish", entity.GetId());
                        logic.NotifyAiStopPursue(entity);
                        logic.ChangeToState(entity, (int)AiStateId.Idle);
                    }
                    else
                    {
                        logic.NotifyAiPursue(entity, targetPos);
                    }
                }
                else
                {
                    logic.AiSendStoryMessage(entity, "npc_pursuit_exit:" + entity.GetUnitId(), entity.GetId());
                    logic.AiSendStoryMessage(entity, "obj_pursuit_exit", entity.GetId());
                    logic.NotifyAiStopPursue(entity);
                    logic.ChangeToState(entity, (int)AiStateId.Idle);
                }
            }
        }
Example #19
0
        public static void Execute(object msg, User user)
        {
            Msg_CR_Skill use_skill = msg as Msg_CR_Skill;

            if (null == use_skill)
            {
                return;
            }
            EntityInfo userObj = user.Info;

            if (null == userObj)
            {
                LogSys.Log(LOG_TYPE.DEBUG, "UseSkillHandler, charactor {0}({1},{2},{3}) not exist", user.RoleId, user.GetKey(), user.Guid, user.Name);
                return;
            }
            Scene scene = user.OwnRoomUserManager.ActiveScene;

            if (null != scene)
            {
                EntityInfo obj = scene.GetEntityById(use_skill.role_id);
                if (null != obj)
                {
                    AiStateInfo aiInfo = obj.GetAiStateInfo();
                    if (use_skill.target_id > 0)
                    {
                        aiInfo.Target = use_skill.target_id;
                    }
                    else if (use_skill.target_dir > 0)
                    {
                        float dir = use_skill.target_dir;
                        obj.GetMovementStateInfo().SetFaceDir(dir);
                        aiInfo.Target = 0;
                    }
                    Msg_RC_NpcSkill retMsg = DataSyncUtility.BuildNpcSkillMessage(obj, use_skill.skill_id);
                    scene.NotifyAllUser(RoomMessageDefine.Msg_RC_NpcSkill, retMsg);
                }
            }
        }
        private void OnAiInitDslLogic(EntityInfo npc)
        {
            AiStateInfo aiInfo = npc.GetAiStateInfo();

            if (aiInfo.AiParam.Length >= 2)
            {
                string storyId   = aiInfo.AiLogic;
                string storyFile = aiInfo.AiParam[0];
                if (!string.IsNullOrEmpty(storyId) && !string.IsNullOrEmpty(storyFile))
                {
                    aiInfo.HomePos = npc.GetMovementStateInfo().GetPosition3D();
                    aiInfo.ChangeToState((int)PredefinedAiStateId.Idle);
                    aiInfo.AiStoryInstanceInfo = StorySystem.NewAiStoryInstance(storyId, string.Empty, storyFile);
                    if (null != aiInfo.AiStoryInstanceInfo)
                    {
                        aiInfo.AiStoryInstanceInfo.m_StoryInstance.Context = this;
                        aiInfo.AiStoryInstanceInfo.m_StoryInstance.SetVariable("@objid", npc.GetId());
                        aiInfo.AiStoryInstanceInfo.m_StoryInstance.Start();
                    }
                }
            }
            m_EntitiesForAi.Add(npc);
        }
Example #21
0
 public void Execute(EntityInfo entity, long deltaTime)
 {
     if (entity.IsUnderControl())
     {
         return;
     }
     if (entity.GetAIEnable())
     {
         AiStateInfo npcAi = entity.GetAiStateInfo();
         if (!npcAi.IsInited)
         {
             OnStateLogicInit(entity, deltaTime);
             npcAi.IsInited = true;
         }
         int curState = npcAi.CurState;
         if (curState > (int)AiStateId.Invalid && curState < (int)AiStateId.MaxNum)
         {
             AiStateHandler handler;
             if (m_Handlers.TryGetValue(curState, out handler))
             {
                 if (OnStateLogicCheck(entity, deltaTime) && null != handler)
                 {
                     handler(entity, deltaTime);
                 }
             }
             else
             {
                 LogSystem.Error("Illegal ai state: " + curState + " entity:" + entity.GetId());
             }
         }
         else
         {
             ChangeToState(entity, (int)AiStateId.Idle);
         }
     }
 }
        public void SetOperateType(bool bAuto)
        {
            int        leaderID = ClientModule.Instance.LeaderID;
            EntityInfo obj      = GetEntityById(leaderID);

            if (null != obj)
            {
                if (IsRoomScene)
                {
                    Network.NetworkSystem.Instance.SyncOperateMode(bAuto);
                }
                else
                {
                    AiStateInfo   aiInfo = obj.GetAiStateInfo();
                    AiData_Leader data   = aiInfo.AiDatas.GetData <AiData_Leader>();
                    if (null == data)
                    {
                        data = new AiData_Leader();
                        aiInfo.AiDatas.AddData(data);
                    }
                    data.IsAutoOperate = bAuto;
                }
            }
        }
        private void GoHomeHandler(EntityInfo entity, long deltaTime)
        {
            AiStateInfo info = entity.GetAiStateInfo();

            info.Time += deltaTime;
            if (info.Time > c_IntervalTime)
            {
                info.Time = 0;
                AiData_General data = GetAiData(entity);
                if (null != data)
                {
                    EntityInfo leader = AiLogicUtility.GetLivingCharacterInfoHelper(entity, info.LeaderID);
                    if (null != leader)
                    {
                        float   minDist              = entity.GetRadius() + leader.GetRadius();
                        Vector3 targetPos            = GetHomePos(entity.GetMovementStateInfo().FormationIndex, leader);
                        ScriptRuntime.Vector3 srcPos = entity.GetMovementStateInfo().GetPosition3D();
                        float powDistToHome          = Geometry.DistanceSquare(srcPos, targetPos);
                        if (powDistToHome <= (minDist + 1) * (minDist + 1))
                        {
                            NotifyAiStopPursue(entity);
                            ChangeToState(entity, (int)AiStateId.Idle);
                        }
                        else
                        {
                            NotifyAiPursue(entity, targetPos);
                        }
                    }
                    else
                    {
                        NotifyAiStopPursue(entity);
                        ChangeToState(entity, (int)AiStateId.Idle);
                    }
                }
            }
        }
        private void CombatHandler(EntityInfo npc, long deltaTime)
        {
            if (npc.GetSkillStateInfo().IsSkillActivated())
            {
                return;
            }

            AiStateInfo info          = npc.GetAiStateInfo();
            EntityInfo  leader        = AiLogicUtility.GetLivingCharacterInfoHelper(npc, info.LeaderID);
            bool        isAutoOperate = IsAutoOperate(leader);

            ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D();
            Vector3 homePos = Vector3.Zero;

            if (null != leader)
            {
                GetHomePos(npc.GetMovementStateInfo().FormationIndex, leader);
            }
            float distSqrToHome = Geometry.DistanceSquare(srcPos, homePos);

            if (distSqrToHome > npc.GohomeRange * npc.GohomeRange)
            {
                NotifyAiStopPursue(npc);
                ChangeToState(npc, (int)AiStateId.GoHome);
                return;
            }

            ///
            EntityInfo     attackTarget = null;
            SkillStateInfo currSkInfo   = npc.GetSkillStateInfo();
            ///找到可以使用的技能
            SkillInfo skInfo = AiLogicUtility.NpcFindCanUseSkill(npc, this.GetAiData(npc), isAutoOperate);

            NotifyAiSelectSkill(npc, skInfo);
            if (skInfo == null)
            {
                //没有可以使用的技能就切换到Idle状态
                ChangeToState(npc, (int)AiStateId.Idle);
                return;
            }

            CharacterRelation relation =
                (skInfo.TargetType == SkillTargetType.Friend ||
                 skInfo.TargetType == SkillTargetType.RandFriend) ?
                CharacterRelation.RELATION_FRIEND :
                CharacterRelation.RELATION_ENEMY;

            attackTarget = AiLogicUtility.GetNearstTargetHelper(
                npc, skInfo.Distance, relation);

            if (attackTarget != null && null != skInfo) //攻击范围内找到可攻击目标
            {
                info.Target = attackTarget.GetId();
                NotifyAiStopPursue(npc);
                NotifyAiSkill(npc, skInfo.SkillId); //攻击目标
                return;
            }
            attackTarget = AiLogicUtility.GetNearstTargetHelper(
                npc, npc.ViewRange, relation);
            if (attackTarget != null && isAutoOperate)                                    //视野范围内找到可攻击目标
            {
                NotifyAiPursue(npc, attackTarget.GetMovementStateInfo().GetPosition3D()); // 追赶目标
                return;
            }

            currSkInfo.SetCurSkillInfo(0);
            NotifyAiStopPursue(npc);
            ChangeToState(npc, (int)AiStateId.GoHome);
        }
        internal static void DoPatrolCommandState(EntityInfo entity, long deltaTime, AbstractAiStateLogic logic)
        {
            AiStateInfo info = entity.GetAiStateInfo();

            info.Time += deltaTime;
            if (info.Time > 100)
            {
                info.Time = 0;
                EntityInfo target = null;
                if (info.IsExternalTarget)
                {
                    target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(entity, info.Target);
                    if (null == target)
                    {
                        target = AiLogicUtility.GetNearstTargetHelper(entity, CharacterRelation.RELATION_ENEMY);
                        if (null != target)
                        {
                            info.Target = target.GetId();
                        }
                    }
                }
                else
                {
                    target = AiLogicUtility.GetNearstTargetHelper(entity, CharacterRelation.RELATION_ENEMY);
                    if (null != target)
                    {
                        info.Target = target.GetId();
                    }
                }
                if (null != target)
                {
                    logic.AiSendStoryMessage(entity, "obj_patrol_exit", entity.GetId());
                    logic.AiSendStoryMessage(entity, string.Format("npc_patrol_exit:{0}", entity.GetUnitId()), entity.GetId());
                    logic.ChangeToState(entity, (int)AiStateId.Idle);
                }
                else
                {
                    AiData_ForPatrolCommand data = GetAiDataForPatrolCommand(entity);
                    if (null != data)
                    {
                        ScriptRuntime.Vector3 srcPos = entity.GetMovementStateInfo().GetPosition3D();
                        if (data.PatrolPath.HavePathPoint && !data.PatrolPath.IsReached(srcPos))
                        {
                            logic.NotifyAiPursue(entity, data.PatrolPath.CurPathPoint);
                        }
                        else
                        {
                            data.PatrolPath.UseNextPathPoint();
                            if (data.PatrolPath.HavePathPoint)
                            {
                                logic.NotifyAiPursue(entity, data.PatrolPath.CurPathPoint);
                            }
                            else
                            {
                                if (data.IsLoopPatrol)
                                {
                                    logic.AiSendStoryMessage(entity, "obj_patrol_restart", entity.GetId());
                                    logic.AiSendStoryMessage(entity, string.Format("npc_patrol_restart:{0}", entity.GetUnitId()), entity.GetId());
                                    data.PatrolPath.Restart();
                                }
                                else
                                {
                                    logic.AiSendStoryMessage(entity, "obj_patrol_finish", entity.GetId());
                                    logic.AiSendStoryMessage(entity, string.Format("npc_patrol_finish:{0}", entity.GetUnitId()), entity.GetId());
                                    logic.NotifyAiStopPursue(entity);
                                    logic.ChangeToState(entity, (int)AiStateId.Idle);
                                }
                            }
                        }
                        info.HomePos = entity.GetMovementStateInfo().GetPosition3D();
                    }
                    else
                    {
                        logic.NotifyAiStopPursue(entity);
                        logic.ChangeToState(entity, (int)AiStateId.Idle);
                    }
                }
            }
        }
        private void CombatHandler(EntityInfo npc, long deltaTime)
        {
            AiStateInfo   aiInfo = npc.GetAiStateInfo();
            AiData_Leader aiData = GetAiData(npc);

            if (npc.GetSkillStateInfo().IsSkillActivated())
            {
                return;
            }
            ///
            SkillStateInfo currSkInfo = npc.GetSkillStateInfo();
            ///找到可以使用的技能
            SkillInfo skInfo = AiLogicUtility.NpcFindCanUseSkill(npc, this.GetAiData(npc), aiData.IsAutoOperate);

            NotifyAiSelectSkill(npc, skInfo);
            if (skInfo == null)
            {
                //没有可以使用的技能就切换到Idle状态
                ChangeToState(npc, (int)AiStateId.Idle);
                return;
            }

            CharacterRelation relation =
                (skInfo.TargetType == SkillTargetType.Friend ||
                 skInfo.TargetType == SkillTargetType.RandFriend) ?
                CharacterRelation.RELATION_FRIEND :
                CharacterRelation.RELATION_ENEMY;
            EntityInfo attackTarget = AiLogicUtility.GetNearstAttackerHelper(npc, relation, aiData);

            if (null != attackTarget)
            {
                NotifyAiTarget(npc, attackTarget);
                if (Geometry.DistanceSquare(npc.GetMovementStateInfo().GetPosition3D(), attackTarget.GetMovementStateInfo().GetPosition3D()) < skInfo.Distance * skInfo.Distance)
                {
                    aiInfo.Target = attackTarget.GetId();
                    NotifyAiStopPursue(npc);
                    NotifyAiSkill(npc, skInfo.SkillId);
                    return;
                }
            }
            attackTarget = AiLogicUtility.GetNearstTargetHelper(npc, skInfo.Distance, relation);
            if (attackTarget != null && null != skInfo)   //攻击范围内找到可攻击目标
            {
                NotifyAiTarget(npc, attackTarget);
                aiInfo.Target = attackTarget.GetId();
                NotifyAiStopPursue(npc);
                NotifyAiSkill(npc, skInfo.SkillId); //攻击目标
                return;
            }
            if (aiData.IsAutoOperate)
            {
                attackTarget = AiLogicUtility.GetNearstTargetHelper(npc, npc.ViewRange, relation);
                if (attackTarget != null && null != skInfo)   //视野内找到可攻击目标
                {
                    NotifyAiPursue(npc, attackTarget.GetMovementStateInfo().GetPosition3D());
                    return;
                }
            }

            ///退出战斗模式清理一下手动技能
            currSkInfo.SetCurSkillInfo(0);
            aiData.ManualSkillId = 0;
            NotifyAiStopPursue(npc);
            ChangeToState(npc, (int)AiStateId.Idle);
        }