/********************************************************************************
 *	文件名:	AutoSearchAgent.cs
 *	全路径:	\Script\Player\AutoSearch\AutoSearchAgent.cs
 *	创建人:	李嘉
 *	创建时间:2014-01-02
 *
 *	功能说明:自动寻路代理,只要建立一个路径,就会自动控制主角进行自动寻路
 *	         寻路的具体路径保存在AutoSearchPath中
 *	修改记录:
*********************************************************************************/

using Games.Events;
using Games.GlobeDefine;
using Games.LogicObj;
using Games.Scene;
using GCGame.Table;
using Module.Log;
using System.Collections.Generic;
using UnityEngine;

public struct MapConnectPath
{
    //起始点
    public int SrcSceneId { get; set; }

    //结束点
    public int DstSceneId { get; set; }

    //传送点坐标X
    public float TelePosX { get; set; }

    //传送点坐标Y
    public float TelePosZ { get; set; }
}

public class AutoSearchAgent : MonoBehaviour
{
    //寻路最短距离的最大值
    private const int m_nMinDistanceMaxValue = 65535;

    // 切换场景时,寻路器锁定时间
    private const float _sceneChangeLockTime = 2f;

    //更新时间间隔
    private readonly float m_fChangeSceneInterval = 5f; //跳场景更新时间间隔,单位为秒 

    private readonly float m_fUpdateInterval = 0.50f; //更新时间间隔,单位为秒 

    //是否自动寻路中标记位
    private bool _isAutoSearching;

    // 切换场景时,锁定寻路器一段时间
    public static float unlockTime;
    private int m_AutoSearchTargetID = -1;

    private string m_AutoSearchTargetName;
    private int m_bNotEnamyNpcFlag; // 非敌对NPC标记 避免NPC多余遍历

    //场景通路图,可以在游戏开始后初始化
    private List<MapConnectPath> m_ConnectPath;

    private AutoSearchPoint m_EndPointCache;
    public AutoSearchPoint EndPointCache
    {
        get
        {
            return m_EndPointCache;
        }
    }

    private float m_fLastChangeGuildSceneUpdateTime; //上一次切换帮会场景时间
    private float m_fLastChangeSceneInstUpdateTime; //上一次更新时间
    private float m_fLastUpdateTime; //上一次更新时间

    private bool _MissionFlyChangeSceneFlag = false;

    public AutoSearchAgent()
    {
        FLastChangeSceneUpdateTime = 0;
    }

    // 自动寻路路径

    public AutoSearchPath Path { get; set; }

    public bool _IsNetAsk = false;

    public bool IsAutoSearching
    {
        get { return _isAutoSearching; }
        set
        {
            _isAutoSearching = value;
            if (!_isAutoSearching && CenterTipsLogic.Instance()!=null)
            {
                CenterTipsLogic.Instance().OnAutoMoveStateChange();
            }
        }
    }

    //场景显示路标的
    private RoadSignManager m_RoadSignManager = null;
    public RoadSignManager RoadSignManager
    {
        get
        {
            if (m_RoadSignManager == null)
                m_RoadSignManager = new RoadSignManager();
            return m_RoadSignManager;
        }
    }

    //多场景寻路
    private AutoSearchTelePort m_AutoSearchTelePort = null;
    public AutoSearchTelePort AutoSearchTelePort
    {
        get {
            if (m_AutoSearchTelePort == null)
                m_AutoSearchTelePort = new AutoSearchTelePort();
            return m_AutoSearchTelePort;
        }
    }

    public float FLastChangeSceneUpdateTime { set; get; }

    //初始化场景通路图
    public void InitMapConnectPath()
    {
        if (GameManager.gameManager.RunningScene == (int) GameDefine_Globe.SCENE_DEFINE.SCENE_LOGIN)
            return;

        //说明已经初始化过,无需再次调用Init函数,整个游戏过程中初始化一次即可
        if (null != m_ConnectPath)
            return;
        //生成完整通路图
        m_ConnectPath = new List<MapConnectPath>();

        foreach (var key in TableManager.GetMapConnection().Keys)
        {
            var tableList = TableManager.GetMapConnectionByID(key);
            if (null != tableList)
                foreach (var conect in tableList)
                {
                    var path = new MapConnectPath
                    {
                        SrcSceneId = conect.SourceSceneID,
                        DstSceneId = conect.DestSceneID,
                        TelePosX = conect.TelePosX,
                        TelePosZ = conect.TelePosZ
                    };
                    m_ConnectPath.Add(path);
                }
        }
    }

    //初始化
    private void Awake()
    {
        Path = new AutoSearchPath();
        Path.ResetPath();

        IsAutoSearching = false;

        m_EndPointCache = new AutoSearchPoint();
        //InitMapConnectPath();
    }

    private void OnDestroy()
    {
        if (m_RoadSignManager != null)
            m_RoadSignManager.OnDestroy();
    }

    public void LockAutoSearch(float time = _sceneChangeLockTime)
    {
        unlockTime = Time.realtimeSinceStartup + time;
    }

    private void LateUpdate()
    {
        RoadSignManager.UpdateSign();
    }
    private void Update()
    {
        //未寻路,不更新
        if (!IsAutoSearching || Time.realtimeSinceStartup < unlockTime)
            return;
        //判断是否到了更新间隔
        if (Time.time - m_fLastUpdateTime < m_fUpdateInterval) return;

        m_fLastUpdateTime = Time.time;
        var mainPlayer = ObjManager.Instance.MainPlayer;
        if (null == mainPlayer)
            return;
        if (GameManager.gameManager.RunningScene != m_EndPointCache.SceneID)
        {
            // 注:传送是一个技能,因此需要满足技能使用条件
            if (mainPlayer.CheckCanCastSkill() != SkillCastableCheckResult.Success
                || !mainPlayer.SkillAllowSkill
                || Time.time - FLastChangeSceneUpdateTime < m_fChangeSceneInterval)
                return;
            if (m_EndPointCache.GuildGuid != SceneData.sceneGuildGuid)
                if (m_EndPointCache.GuildGuid != GlobeVar.INVALID_GUID)
                {
                    FLastChangeSceneUpdateTime = Time.time;
                    mainPlayer.BackGuildMap(m_EndPointCache.GuildGuid);
                    return;
                }

            FLastChangeSceneUpdateTime = Time.time;
            var sceneInfo = TableManager.GetSceneClassByID(m_EndPointCache.SceneID, 0);
            if (sceneInfo != null)
            {
                if (m_EndPointCache.ChangeMapType == AutoSearchPoint.ChangeMap_Type.WORLDMAP)
                {
                    SceneData.RequestChangeScene((int)m_EndPointCache.ChangeMapType, 0, m_EndPointCache.SceneID,
                        m_EndPointCache.SceneInstID, (int)sceneInfo.SafeX, (int)sceneInfo.SafeZ);
                }
                else
                {
                    SceneData.RequestChangeScene((int)m_EndPointCache.ChangeMapType, 0, m_EndPointCache.SceneID,
                        m_EndPointCache.SceneInstID, (int)m_EndPointCache.PosX * 100, (int)m_EndPointCache.PosZ * 100);
                }
                return;
            }
        }
        else
        {
            if (m_EndPointCache.SceneInstID != -1 && SceneData.SceneInst != m_EndPointCache.SceneInstID)
            {
                if (Time.time - FLastChangeSceneUpdateTime < m_fChangeSceneInterval)
                    return;
                FLastChangeSceneUpdateTime = Time.time;
                var packet =
                    (CG_SCENE_CHANGEINST) PacketDistributed.CreatePacket(MessageID.PACKET_CG_SCENE_CHANGEINST);
                packet.SetSceneInst(m_EndPointCache.SceneInstID);
                packet.SendPacket();
                return;
            }

            if (m_EndPointCache.ChangeMapType == AutoSearchPoint.ChangeMap_Type.MISSIONFLY)
            {
                if (!_MissionFlyChangeSceneFlag)
                {
                    UnityEngine.AI.NavMeshPath navMeshPath = new UnityEngine.AI.NavMeshPath();
                    bool needFly = false;
                    if (UnityEngine.AI.NavMesh.CalculatePath(mainPlayer.Position, new Vector3(m_EndPointCache.PosX, mainPlayer.Position.y, m_EndPointCache.PosZ), 1, navMeshPath))
                    {
                        if (navMeshPath.GetTotalDistance() < 10)
                        {
                            needFly = false;
                        }
                        else
                        {
                            needFly = true;
                        }
                    }
                    else
                    {
                        needFly = true;
                    }

                    if (needFly)
                    {
                        SceneData.RequestChangeScene((int)m_EndPointCache.ChangeMapType, 0, m_EndPointCache.SceneID,
                                m_EndPointCache.SceneInstID, (int)m_EndPointCache.PosX * 100, (int)m_EndPointCache.PosZ * 100);
                        _MissionFlyChangeSceneFlag = true;
#if UNITY_EDITOR
                        GUIData.AddNotifyData("飞鞋传送场景:" + m_EndPointCache.SceneID + "," + m_EndPointCache.PosX + "," + m_EndPointCache.PosZ);
                        Debug.Log("飞鞋传送场景:" + m_EndPointCache.SceneID + "," + m_EndPointCache.PosX + "," + m_EndPointCache.PosZ);
#endif
                        return;
                    }
                    else
                    {
                        GUIData.AddNotifyData(StrDictionary.GetClientDictionaryString("#{86104}"));
                    }
                }
            }

            if (m_EndPointCache.GuildGuid != SceneData.sceneGuildGuid)
                if (m_EndPointCache.GuildGuid != GlobeVar.INVALID_GUID)
                {
                    if (Time.time - m_fLastChangeGuildSceneUpdateTime < m_fChangeSceneInterval)
                        return;
                    m_fLastChangeGuildSceneUpdateTime = Time.time;
                    mainPlayer.BackGuildMap(m_EndPointCache.GuildGuid);
                    return;
                }
        }

        FLastChangeSceneUpdateTime = 0;
        m_fLastChangeSceneInstUpdateTime = 0;
        m_fLastChangeGuildSceneUpdateTime = 0;
        //寻路中首先判断是否结束
        if (Path.IsFinish(mainPlayer.transform.position))
            Finish();
        // 如果角色停止移动或者到达位置,则重新开始移动
        else if (Path.IsReachPoint(mainPlayer.transform.position) || mainPlayer.MovementState == MoveState.Static)
            BeginMove();
        //else if (Path.IsReachPoint(mainPlayer.transform.position))
        //    GotoNextPoint();
        ////如果此时未移动,则前往下一个点
        //else if (mainPlayer.MovementState == MoveState.Static)
        //    BeginMove();
    }

    // 寻路找怪处理
    //    private void FindEnamyTick()
    //    {
    //        if (m_bNotEnamyNpcFlag != 0) return;
    //
    //        //如果有目标名字则寻找该目标,进行交互
    //        if (Path.AutoSearchTargetName != "")
    //        {
    //            var obj = Singleton<ObjManager>.GetInstance()
    //                .FindObjCharacterInSceneByName(Path.AutoSearchTargetName);
    //            if (obj && obj.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_NPC)
    //            {
    //                var objNpc = obj as Obj_NPC;
    //                //根据目标NPC的势力确认是对话还是攻击
    //                if (Reputation.IsEnemy(objNpc) || Reputation.IsNeutral(objNpc))
    //                {
    //                    Singleton<ObjManager>.GetInstance().MainPlayer.StopMove();
    //                    Path.AutoSearchPosCache.Clear();
    //                    Path.ResetPath();
    //                    IsAutoSearching = false;
    //                    m_EndPointCache.Clean();
    //
    //                    //如果是地方NPC,则开始攻击
    //                    Singleton<ObjManager>.GetInstance().MainPlayer.OnEnterCombat(objNpc);
    //                    Singleton<ObjManager>.GetInstance().MainPlayer.EnterAutoCombat();
    //                    m_bNotEnamyNpcFlag = 1;
    //                }
    //                else
    //                {
    //                    m_bNotEnamyNpcFlag = 2;
    //                }
    //            }
    //        }
    //    }

    //创建一条路径,并且在Update中判断是否抵达
    public void BuildPath(AutoSearchPoint endPoint, bool isNetAsk = false, string searchName = null, float dialogRadius = -1)
    {
        if(GameManager.gameManager.PlayerDataPool.IsInWeddingCar)
        {
            GUIData.AddNotifyData(StrDictionary.GetClientDictionaryString("#{26013}"));
            return;
        }
        //正在播放剧情
        if (SceneMovieManager.Instance._PlayingMovie)
            return;
        if (Singleton<ObjManager>.Instance.MainPlayer.IsInPaoShang() && RoadSignManager.ShowSign)
        {
            GUIData.AddNotifyData(StrDictionary.GetClientDictionaryString("{#34013}"));
            return;
        }
        //组队跟随,不响应
        if (GameManager.gameManager.PlayerDataPool.IsFollowTeam)
        {
            GUIData.AddNotifyData(StrDictionary.GetClientDictionaryString("#{5128}"));
            return;
        }

        var _mainPlayer = Singleton<ObjManager>.GetInstance().MainPlayer;
        if (null == _mainPlayer) return;

        if (GameManager.gameManager.ActiveScene.IsCopyScene() == false)
            _mainPlayer.LeveAutoCombat();

        // 同一个点,直接跳过
        if (m_EndPointCache.SceneID == endPoint.SceneID
            && m_EndPointCache.PosX == endPoint.PosX
            && m_EndPointCache.PosZ == endPoint.PosZ
            && m_EndPointCache.ChangeMapType == endPoint.ChangeMapType)
            return;

        _MissionFlyChangeSceneFlag = false;

        //停止正在进行的移动
        if (_mainPlayer.MovementState > MoveState.Static)
            _mainPlayer.StopMove();
        if (OneDragonAuto.One_DragonAuto != null && isNetAsk)
            OneDragonAuto.One_DragonAuto.NeedCheckOneDragonEnterCopy = false;

        m_EndPointCache = endPoint;
        Path.ResetPath();
        m_bNotEnamyNpcFlag = 0;
        Path.AddPathPoint(endPoint);

        _IsNetAsk = isNetAsk;
        if (searchName != null)
            Path.AutoSearchTargetName = searchName;

        if (dialogRadius != -1)
            Path.autoSearchRadius = dialogRadius;

        //设置开始自动寻路
        IsAutoSearching = true;
        // 如果是队长,让队员进入组队跟随
        if (GameManager.gameManager.PlayerDataPool.TeamInfo.IsCaptain())
            _mainPlayer.TeamLeaderEndCombat();

        //如果是当前场景,则直接生成单点路径,进行移动
        //         if (GameManager.gameManager.RunningScene == endPoint.SceneID)
        //         {
        //             m_Path.AddPathPoint(endPoint);
        //             //设置开始自动寻路
        //             m_bIsAutoSearching = true;
        //             return;
        //         }

        //根据当前点和目的地点来确定路径
        //         AutoSearchPoint startPoint = AutoSearchPoint.MakePoint(_mainPlayer.gameObject);
        //         if (true == FindPath(startPoint, endPoint))
        //         {
        //             m_bIsAutoSearching = true;
        //             return;
        //         }
    }

    //获得两个场景的通路长度
    private int GetDisBySceneID(int srcId, int dstId)
    {
        foreach (var path in m_ConnectPath)
            if (path.SrcSceneId == srcId && path.DstSceneId == dstId)
                return 1;

        return m_nMinDistanceMaxValue;
    }

    //搜索路径算法,根据DJ算法生成最短路径
    private bool FindPath(AutoSearchPoint startPoint, AutoSearchPoint endPoint)
    {
        var path = new List<int>(); //最后生成的最短路径图

        //统计所有节点,计算srcid的逆临街表,放在nodeMap中
        var nodeMap = new Dictionary<int, PathNodeInfo>();
        foreach (var connectPath in m_ConnectPath)
        {
            if (false == nodeMap.ContainsKey(connectPath.SrcSceneId))
            {
                var info = new PathNodeInfo();
                info.sceneId = connectPath.SrcSceneId;
                info.dis = GetDisBySceneID(startPoint.SceneID, info.sceneId);
                info.prevNode = startPoint.SceneID;
                nodeMap.Add(info.sceneId, info);
            }

            if (false == nodeMap.ContainsKey(connectPath.DstSceneId))
            {
                var info = new PathNodeInfo();
                info.sceneId = connectPath.DstSceneId;
                info.dis = GetDisBySceneID(startPoint.SceneID, info.sceneId);
                info.prevNode = startPoint.SceneID;
                nodeMap.Add(info.sceneId, info);
            }
        }

        var openList = new List<int>();
        var closeList = new List<int>();

        //放入开始点
        openList.Add(startPoint.SceneID);

        while (openList.Count > 0)
        {
            var minPt = openList[0];
            var minDis = m_nMinDistanceMaxValue;

            foreach (var openPoint in openList)
            {
                if (!nodeMap.ContainsKey(openPoint)) continue;

                if (nodeMap[openPoint].dis < minDis)
                {
                    minPt = openPoint;
                    minDis = nodeMap[openPoint].dis;
                }
            }

            var minDisNode = minPt;
            openList.Remove(minDisNode);
            closeList.Add(minDisNode);

            //展开该节点,更新所有邻接表的距离,并把下一个(或几个)最短路径上的点放入openList。
            foreach (var connectPath in m_ConnectPath)
                if (connectPath.SrcSceneId == minDisNode)
                {
                    var newDis = nodeMap[minDisNode].dis + GetDisBySceneID(minDisNode, connectPath.DstSceneId);
                    if (newDis < nodeMap[connectPath.DstSceneId].dis)
                    {
                        nodeMap[connectPath.DstSceneId].dis = newDis;
                        nodeMap[connectPath.DstSceneId].prevNode = minDisNode;
                    }

                    if (!openList.Contains(connectPath.DstSceneId) && !closeList.Contains(connectPath.DstSceneId))
                        openList.Add(connectPath.DstSceneId);
                }
        }


        if (!nodeMap.ContainsKey(endPoint.SceneID)) return false;

        //这里生成最短路径和下一个场景号,这里的邻接表已经记录了最短路径信息
        if (nodeMap[endPoint.SceneID].dis < m_nMinDistanceMaxValue)
        {
            path.Insert(0, endPoint.SceneID);
            var backId = nodeMap[endPoint.SceneID].prevNode;
            while (backId != -1)
            {
                if (backId == startPoint.SceneID)
                {
                    //int nextScn = path[0];
                    path.Insert(0, backId);
                    break;
                }

                path.Insert(0, backId);
                backId = nodeMap[backId].prevNode;
            }
        }

        if (path.Count > 1)
        {
            //生成路径
            var beginScene = path[0];
            var endScene = -1;
            for (var i = 1; i < path.Count; ++i)
            {
                endScene = path[i];
                foreach (var connectPath in m_ConnectPath)
                    if (connectPath.SrcSceneId == beginScene && connectPath.DstSceneId == endScene)
                    {
                        var point = new AutoSearchPoint(connectPath.SrcSceneId, connectPath.TelePosX,
                            connectPath.TelePosZ);
                        Path.AutoSearchPosCache.Add(point);

                        beginScene = endScene;
                    }
            }

            //最后加入目标点
            Path.AutoSearchPosCache.Add(endPoint);
            return true;
        }

        return false;
    }

    //切换场景的时候判断一下是否是自动寻路,如果不是自动寻路的就清除一下自动寻路的数据
    public void OnChangeScene(int sceneId)
    {
        if(sceneId == -1)
        {
            StopAutoSerach();
            return;
        }
        if (Path == null)
            return;
        
        if (Path.GetPathPosition(sceneId) == null) StopAutoSerach();
    }

    //寻路到帮会场景
    public void BackGuild(ulong guildId, int roleId, float x, float z)
    {
        if (roleId == -1)
        {
            var guid = GameManager.gameManager.PlayerDataPool.GuildInfo.GuildGuid;
            var mainPlayer = ObjManager.Instance.MainPlayer;
            if (mainPlayer != null)
                mainPlayer.BackGuildMap(guid);
            else
            {
                // 保持之前玩家未创建也可以发送协议的逻辑
                var send =
                    (CG_REQ_ENTER_GUILDMAP) PacketDistributed.CreatePacket(MessageID.PACKET_CG_REQ_ENTER_GUILDMAP);
                send.SetGuildGuid(guid);
                send.SendPacket();
            }

            return;
        }

        var guildOther = TableManager.GetGuildOtherByID(0, 0);
        if (guildOther != null)
        {
            var GuildSceneId = guildOther.SceneId;
            var point = new AutoSearchPoint(GuildSceneId, x, z, -1, AutoSearchPoint.ChangeMap_Type.WORLDMAP,
                guildId);
            var RoleBase = TableManager.GetRoleBaseAttrByID(roleId, 0);
            if (null != RoleBase && null != Path)
            {
                BuildPath(point);
                Path.AutoSearchTargetName = RoleBase.Name;
                Path.autoSearchRadius = RoleBase.DialogRadius;
            }
        }
    }

    public void StopAutoSerach()
    {
        FLastChangeSceneUpdateTime = 0;
        m_fLastChangeGuildSceneUpdateTime = 0;
        m_fLastChangeSceneInstUpdateTime = 0;
        Path.ResetPath();
        IsAutoSearching = false;
        m_EndPointCache.Clean();
        m_AutoSearchTargetName = "";
        m_AutoSearchTargetID = -1;
        if(Singleton<ObjManager>.Instance.MainPlayer!=null)
            Singleton<ObjManager>.Instance.MainPlayer.StopMove();
    }

    //停止自动寻路
    public void Stop()
    {
        StopAutoSerach();
        AutoSearchTelePort.Stop();

    }

    public static UnityEngine.AI.NavMeshPath tempPath
    {
        get
        {
            if (_tempPath == null)
                _tempPath = new UnityEngine.AI.NavMeshPath();
            return _tempPath;
        }
    }

    private static UnityEngine.AI.NavMeshPath _tempPath;

    //向最新点移动
    private void BeginMove()
    {
        var mainPlayer = ObjManager.Instance.MainPlayer;
        if (null == mainPlayer)
            return;

        if (Path.AutoSearchPosCache.Count > 0)
        {
            //首先检测场景是否对应,如果不对则直接返回
            if (GameManager.gameManager.RunningScene != m_EndPointCache.SceneID)
            {
                if (m_EndPointCache.GuildGuid != SceneData.sceneGuildGuid)
                    if (m_EndPointCache.GuildGuid != GlobeVar.INVALID_GUID)
                    {
                        FLastChangeSceneUpdateTime = Time.time;
                        Singleton<ObjManager>.Instance.MainPlayer.BackGuildMap(m_EndPointCache.GuildGuid);
                        return;
                    }

                var sceneInfo = TableManager.GetSceneClassByID(m_EndPointCache.SceneID, 0);
                if (sceneInfo != null)
                {
                    if (m_EndPointCache.ChangeMapType == AutoSearchPoint.ChangeMap_Type.WORLDMAP)
                    {
                        SceneData.RequestChangeScene((int)m_EndPointCache.ChangeMapType, 0, m_EndPointCache.SceneID,
                            m_EndPointCache.SceneInstID, (int)sceneInfo.SafeX, (int)sceneInfo.SafeZ);
                    }
                    else
                    {
                        SceneData.RequestChangeScene((int)m_EndPointCache.ChangeMapType, 0, m_EndPointCache.SceneID,
                            m_EndPointCache.SceneInstID, (int)m_EndPointCache.PosX * 100, (int)m_EndPointCache.PosZ * 100);
                    }
                    return;
                }
            }
            else
            {
                if (m_EndPointCache.SceneInstID != -1 && SceneData.SceneInst != m_EndPointCache.SceneInstID)
                {
                    var packet =
                        (CG_SCENE_CHANGEINST)PacketDistributed.CreatePacket(MessageID.PACKET_CG_SCENE_CHANGEINST);
                    packet.SetSceneInst(m_EndPointCache.SceneInstID);
                    packet.SendPacket();
                    return;
                }

                if (m_EndPointCache.ChangeMapType == AutoSearchPoint.ChangeMap_Type.MISSIONFLY)
                {
                    if (!_MissionFlyChangeSceneFlag)
                    {
                        UnityEngine.AI.NavMeshPath navMeshPath = new UnityEngine.AI.NavMeshPath();
                        bool needFly = false;
                        if (UnityEngine.AI.NavMesh.CalculatePath(mainPlayer.Position, new Vector3(m_EndPointCache.PosX, mainPlayer.Position.y, m_EndPointCache.PosZ), 1, navMeshPath))
                        {
                            if (navMeshPath.GetTotalDistance() < 10)
                            {
                                needFly = false;
                            }
                            else
                            {
                                needFly = true;
                            }
                        }
                        else
                        {
                            needFly = true;
                        }

                        if (needFly)
                        {
                            SceneData.RequestChangeScene((int)m_EndPointCache.ChangeMapType, 0, m_EndPointCache.SceneID,
                                    m_EndPointCache.SceneInstID, (int)m_EndPointCache.PosX * 100, (int)m_EndPointCache.PosZ * 100);
                            _MissionFlyChangeSceneFlag = true;
#if UNITY_EDITOR
                            GUIData.AddNotifyData("飞鞋传送场景:" + m_EndPointCache.SceneID + "," + m_EndPointCache.PosX + "," + m_EndPointCache.PosZ);
                            Debug.Log("飞鞋传送场景:" + m_EndPointCache.SceneID + "," + m_EndPointCache.PosX + "," + m_EndPointCache.PosZ);
#endif
                            return;
                        }
                    }
                }

                if (m_EndPointCache.GuildGuid != SceneData.sceneGuildGuid)
                    if (m_EndPointCache.GuildGuid != GlobeVar.INVALID_GUID)
                    {
                        Singleton<ObjManager>.Instance.MainPlayer.BackGuildMap(m_EndPointCache.GuildGuid);
                        return;
                    }
            }

            //todo 武场特殊处理一下,后续一定要完善高度图误差
            //             if (GameManager.gameManager.RunningScene == (int)GameDefine_Globe.SCENE_DEFINE.SCENE_WUCHANG)
            //             {
            //                 pos.y = 18.5f;
            //             }
            if (mainPlayer.IsCanAcceptMoveOrder(true))
            {
                var pos = new Vector3(m_EndPointCache.PosX, 0, m_EndPointCache.PosZ);
                pos = ActiveScene.GetTerrainPosition(pos);

                if (CenterTipsLogic.Instance() != null)
                {
                    CenterTipsLogic.Instance().OnAutoMoveStateChange();
                }
                var stopRange = Mathf.Max(0f, Path.autoSearchRadius);
                mainPlayer.MainPlayMoveToPos(pos, stopRange, bIsAutoSearch: true);
                if (IsAutoSearching &&
                    null != GameManager.gameManager.AutoSearch &&
                    GameManager.gameManager.AutoSearch.IsAutoSearching
                    && GameManager.gameManager.PlayerDataPool.m_objMountParam.AdvanceMountId < 1 //当前有坐骑但是你没有骑乘 
                    && GameManager.gameManager.PlayerDataPool.m_objMountParam.AutoFlagMountID > 0)
                {
                    if (mainPlayer.NavAgent != null && mainPlayer.NavAgent.isActiveAndEnabled &&
                        mainPlayer.NavAgent.hasPath)
                    {
                        var distance = mainPlayer.NavAgent.path.GetTotalDistance();
                        if ( /*distance > 50f &&*/ distance >= 10f)
                            mainPlayer.AskRideMount(false);
                    }
                }
            }
        }
    }


    //自动寻路结束
    private void Finish()
    {
        //如果有结束后的回调事件则回调
        if (null != Path.FinishCallBackEvent &&
            GameDefine_Globe.EVENT_DEFINE.EVENT_INVALID != Path.FinishCallBackEvent.EventID)
            Singleton<EventSystem>.GetInstance().PushEvent(Path.FinishCallBackEvent);

        if (Path.finishCallBack != null) Path.finishCallBack(Path.callBackParam);

        m_AutoSearchTargetName = Path.AutoSearchTargetName;
        m_AutoSearchTargetID = Path.AutoSearchTargetID;
        AgentToNPC();

        m_EndPointCache.Clean();
        Path.ResetPath();
        IsAutoSearching = false;
        m_fLastUpdateTime = 0;
    }

    public void AgentToNPC(Obj_NPC npc = null)
    {
        if (npc != null && IsAutoSearching && Path.AutoSearchTargetRoleID != -1 && Path.AutoSearchTargetRoleID == npc.BaseAttr.RoleBaseID)
        {
            Stop();
            Path.AutoSearchTargetRoleID = -1;
            AutoSearchPoint point = new AutoSearchPoint(GameManager.gameManager.RunningScene, npc.Position.x, npc.Position.z, SceneData.SceneInst, AutoSearchPoint.ChangeMap_Type.WORLDMAP, SceneData.sceneGuildGuid);
            if (GameManager.gameManager && GameManager.gameManager.AutoSearch)
            {
                GameManager.gameManager.AutoSearch.BuildPath(point);
                GameManager.gameManager.AutoSearch.Path.AutoSearchTargetID = npc.ServerID;
                GameManager.gameManager.AutoSearch.Path.autoSearchRadius = 1.5f;
            }
            return;
        }


        //如果有目标名字则寻找该目标,进行交互
        if (m_AutoSearchTargetName != "" || m_AutoSearchTargetID != -1)
        {
            var obj = ObjManager.Instance.FindObjCharacterInScene(m_AutoSearchTargetID);
            if (obj == null)
                obj = ObjManager.Instance.FindObjCharacterInSceneByName(m_AutoSearchTargetName);
            var mainPlayer = ObjManager.Instance.MainPlayer;
            if (mainPlayer && obj && obj.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_NPC)
            {
                m_AutoSearchTargetName = "";
                m_AutoSearchTargetID = -1;
                var objNpc = (Obj_NPC)obj;
                //根据目标NPC的势力确认是对话还是攻击
                if (Reputation.CanAttack(objNpc))
                {
                    //如果是地方NPC,则开始攻击
                    if (!mainPlayer.isAutoCombat)
                        mainPlayer.OnEnterCombat(objNpc);
                    mainPlayer.EnterAutoCombat();
                }
                else
                {
                    mainPlayer.SetClientTargetByClick(objNpc);
                }
            }
            return;
        }
    }

    //当自动寻路过程中遇到传送点
    public void ProcessTelepoint(Obj_TeleportPoint telePoint)
    {
        //传送点数据异常,返回
        if (null == telePoint || null == telePoint.gameObject) return;

        //非自动寻路状态,返回
        if (!IsAutoSearching) return;

        //自动寻路状态,并且路径中有数值
        if (Path.AutoSearchPosCache.Count > 0)
        {
            //判断是不是本次跨场景寻路所需传送点
            var autoSearchPoint = new Vector2(Path.AutoSearchPosCache[0].PosX, Path.AutoSearchPosCache[0].PosZ);
            var telePortPoint = new Vector2(telePoint.gameObject.transform.position.x,
                telePoint.gameObject.transform.position.z);
            //距离校验,因为自动寻路点为2D,所以转化为2D坐标验证
            if (Vector2.Distance(autoSearchPoint, telePortPoint) <= 3.0f)
            {
                Path.AutoSearchPosCache.RemoveAt(0);

                //如果此时路径点中无数据,则结束自动寻路
                if (Path.AutoSearchPosCache.Count == 0) Finish();
            }
        }
    }

    private class PathNodeInfo
    {
        public int dis;
        public int prevNode;

        public int sceneId;

        public PathNodeInfo()
        {
            sceneId = -1;
            dis = m_nMinDistanceMaxValue;
            prevNode = -1;
        }
    }
}