using UnityEngine; using System.Collections; using System.Collections.Generic; using Snxxz.UI; using TableConfig; public class MapTransferUtility : SingletonMonobehaviour { public static UnityEngine.Events.UnityAction s_OnHeroLeaveFuncNpc; public static UnityEngine.Events.UnityAction s_OnHeroStartMoveToNPC; public enum E_MapTransferDoType { None, DaZuo, Npc, Fight, } private E_MapTransferDoType m_MapTransferType; public E_MapTransferDoType MapTransferDoType { get { return m_MapTransferType; } set { m_MapTransferType = value; #if UNITY_EDITOR // Debug.LogFormat("设置方式: {0}", m_MapTransferType); #endif } } private float m_ClosedFuncNpcDistSqrt; public float conversationDistSqrt; public void Initialize() { FuncConfigConfig _funcModel = Config.Instance.Get("ConversationDistanc"); if (_funcModel != null) { conversationDistSqrt = float.Parse(_funcModel.Numerical1); conversationDistSqrt *= conversationDistSqrt; m_ClosedFuncNpcDistSqrt = float.Parse(_funcModel.Numerical2); m_ClosedFuncNpcDistSqrt *= m_ClosedFuncNpcDistSqrt; } conversationDistSqrt = conversationDistSqrt == 0 ? 6 : conversationDistSqrt; m_ClosedFuncNpcDistSqrt = m_ClosedFuncNpcDistSqrt == 0 ? 1 : m_ClosedFuncNpcDistSqrt; } #region 打坐 public void MoveToDazuo(int mapID) { GA_Hero _hero = PlayerDatas.Instance.hero; _hero.Behaviour.StopHandupAI(); _hero.Behaviour.StopKillUntilDieAI(); if (_hero.SkillMgr.CurCastSkill != null) { if (_hero.SkillMgr.CurCastSkill.SkillCompelete == false) { return; } } if (_hero.IsRushing) { return; } MapTransferDoType = E_MapTransferDoType.DaZuo; MapModel _model = ModelCenter.Instance.GetModel(); if (mapID != PlayerDatas.Instance.baseData.MapID) { if (_model.IsMapUnLocked(mapID) == false) { SysNotifyMgr.Instance.ShowTip("Map_Delivery"); return; } _model.RequestMapTransport(mapID); } else { if (MapArea.IsInMapArea(_hero.CurMapArea, MapArea.E_Type.Dazuo)) { Debug.Log("当前已经在打坐区域内了"); return; } List _list; if (DungeonStage.s_MapAreaDict.TryGetValue(MapArea.E_Type.Dazuo, out _list) == false) { Debug.LogWarningFormat("地图没有打坐区域, 是否配置出错?"); return; } if (_list == null || _list.Count == 0) { Debug.LogWarningFormat("地图没有打坐区域, 是否配置出错?"); return; } float _x = Random.Range(_list[0].startPosition.x, _list[0].endPosition.x); float _z = Random.Range(_list[0].startPosition.z, _list[0].endPosition.z); Vector3 _destPos = new Vector3(_x, _hero.Pos.y, _z); _hero.Behaviour.StopHandupAI(); _hero.Behaviour.StopKillUntilDieAI(); _hero.MoveToPosition(_destPos); } } #endregion #region npc public int NpcID { get; private set; } #endregion bool m_DelayMoveToNPC = false; int m_TempNpcID; bool m_DelayMoveToPos = false; Vector3 m_TempPos = Vector3.zero; private void Update() { if (m_DelayMoveToNPC) { GA_Hero _hero = PlayerDatas.Instance.hero; if (_hero.IsIdle()) { _hero.Behaviour.StopHandupAI(); _hero.Behaviour.StopKillUntilDieAI(); _hero.StopRush(); _hero.LockTarget = null; MoveToNPC(m_TempNpcID); m_DelayMoveToNPC = false; } } if (m_DelayMoveToPos) { GA_Hero _hero = PlayerDatas.Instance.hero; if (_hero.IsIdle()) { _hero.Behaviour.StopHandupAI(); _hero.Behaviour.StopKillUntilDieAI(); _hero.StopRush(); _hero.LockTarget = null; _hero.MoveToPosition(new Vector3(m_TempPos.x * 0.5f, 0f, m_TempPos.y * 0.5f)); m_DelayMoveToPos = false; } } } public int lastMoveToWorldBossNpcID; public float lastMoveToWorldBossTime; private bool m_SwitchMapFinished = true; private int m_MapID; public void CheckMap(int mapID) { if (m_MapID == mapID) { m_SwitchMapFinished = true; } } public void MoveToNPC(int npcID) { NPCConfig _config = Config.Instance.Get(npcID); if (_config == null) { return; } #if UNITY_EDITOR Debug.LogFormat("想要切换至目标npc: {0}", npcID); #endif m_DelayMoveToNPC = false; m_TempNpcID = 0; GA_Hero _hero = PlayerDatas.Instance.hero; if (_hero == null) { return; } NpcID = npcID; MapTransferDoType = E_MapTransferDoType.Npc; // 获取NPC位置数据 GAStaticDefine.NPCLocation _npcLocation; var _findLocation = GAStaticDefine.TryGetMapNPCLocation(npcID, out _npcLocation); if (!_findLocation) { #if UNITY_EDITOR Debug.LogWarningFormat("需要传送至的npcid有错,无法在mapnpc表中查询到, id: {0}", npcID); #endif } if (_npcLocation.mapId != PlayerDatas.Instance.baseData.MapID) { if (PlayerDatas.Instance.extersion.pkState == 1) { SysNotifyMgr.Instance.ShowTip("PK_Leave"); return; } //if (PlayerDatas.Instance.extersion.bossState == 1) //{ // SysNotifyMgr.Instance.ShowTip("Task_Transfer1"); // return; //} } _hero.Behaviour.StopHandupAI(); _hero.Behaviour.StopKillUntilDieAI(); _hero.LockTarget = null;// 强制清空当前锁定目标 if ((_hero.SkillMgr.CurCastSkill != null && !_hero.SkillMgr.CurCastSkill.SkillCompelete) || _hero.IsRushing) { m_DelayMoveToNPC = true; m_TempNpcID = npcID; return; } MapModel _model = ModelCenter.Instance.GetModel(); GActor _npc = null; // 加入判断是否世界BOSS判断 WorldBossConfig _worldBoss = Config.Instance.Get(npcID); bool _isWorldBoss = _worldBoss != null; if (_isWorldBoss && _findLocation) { //Debug.LogFormat("目标是世界boss"); _npc = GAMgr.Instance.GetCloserNPC(_hero.Pos, npcID); if (_npc != null) { //Debug.LogFormat(" |-- 在视野内"); _hero.MoveToPosition(_npc.Pos, _npcLocation.scope); } else { //Debug.LogFormat(" |-- 不在视野内"); var _mapConfig = Config.Instance.Get(_npcLocation.mapId); // 如果不是处于相同地图, 则切图 if (_npcLocation.mapId != PlayerDatas.Instance.baseData.MapID) { if (PlayerDatas.Instance.extersion.pkState == 1) { SysNotifyMgr.Instance.ShowTip("PK_Leave"); return; } //if (PlayerDatas.Instance.extersion.bossState == 1) //{ // SysNotifyMgr.Instance.ShowTip("Task_Transfer1"); // return; //} //Debug.LogFormat(" |-- 不在本地图"); var mapId = _npcLocation.mapId; var position = new Vector3(_mapConfig.BornPoints[0].x, 0, _mapConfig.BornPoints[0].y); Send_WorldTransfer(mapId, position, MapTransferType.WorldTransport, 0, npcID); if (BossFakeLineUtility.Instance.IsShuntBoss(npcID)) { //Debug.LogFormat(" |-- BossFakeLineUtility.Instance.makeFakeLineTimes = 1"); BossFakeLineUtility.Instance.makeFakeLineTimes = 1; } m_SwitchMapFinished = false; m_MapID = _npcLocation.mapId; } else { //Debug.LogFormat(" |-- 在本地图"); if (PlayerDatas.Instance.baseData.FBID != 0) { if (BossFakeLineUtility.Instance.IsShuntBoss(npcID)) { //Debug.LogFormat(" |-- BossFakeLineUtility.Instance.makeFakeLineTimes = 1"); BossFakeLineUtility.Instance.makeFakeLineTimes = 1; } } if (((lastMoveToWorldBossNpcID == npcID && Time.realtimeSinceStartup - lastMoveToWorldBossTime < 60) && PlayerDatas.Instance.baseData.FBID == 0) || BossFakeLineUtility.Instance.showFakeLine) { //Debug.LogFormat(" |-- 非想去的boss为60秒内行为产生且为同一只boss, {0}, {1}", BossFakeLineUtility.Instance.showFakeLine, //PlayerDatas.Instance.baseData.FBID); Vector3 _destPos = new Vector3(_npcLocation.position.x, _hero.Pos.y, _npcLocation.position.y); _hero.MoveToPosition(_destPos, _npcLocation.scope); } else { // 处于相同地图 if (BossFakeLineUtility.Instance.lastBossNpcID != npcID || Time.realtimeSinceStartup - BossFakeLineUtility.Instance.inMistakeForBossAliveOverTime > 60) { //Debug.LogFormat(" |-- 非想去的boss记录,或则见到boss时差超过60秒"); Send_WorldTransfer(_npcLocation.mapId, new Vector3(_hero.Pos.x * 2, 0, _hero.Pos.z * 2), MapTransferType.WorldTransport, 0, npcID); } else { //Debug.LogFormat(" |-- 见到boss时差在60秒内 : ({0})-({1})=({2})", Time.realtimeSinceStartup, BossFakeLineUtility.Instance.inMistakeForBossAliveOverTime, (Time.realtimeSinceStartup - BossFakeLineUtility.Instance.inMistakeForBossAliveOverTime)); Vector3 _destPos = new Vector3(_npcLocation.position.x, _hero.Pos.y, _npcLocation.position.y); _hero.MoveToPosition(_destPos, _npcLocation.scope); } } } lastMoveToWorldBossTime = Time.realtimeSinceStartup; lastMoveToWorldBossNpcID = npcID; } return; } // 判断是否是在别的地图 if (_findLocation && _npcLocation.mapId != PlayerDatas.Instance.baseData.MapID) { if (_config != null) { if (_config.NPCType == (int)E_NpcType.OpenWorldMap) { if (!WindowCenter.Instance.CheckOpen()) { WindowCenter.Instance.Open(); if (_hero.State == E_ActorState.AutoRun) { _hero.StopPathFind(); } _hero.IdleImmediate(); } return; } } //if (PlayerDatas.Instance.extersion.bossState == 1) //{ // SysNotifyMgr.Instance.ShowTip("Task_Transfer1"); // return; //} if (PlayerDatas.Instance.extersion.pkState == 1) { SysNotifyMgr.Instance.ShowTip("PK_Leave"); return; } // 判断地图是否解锁 if (_model.IsMapUnLocked(_npcLocation.mapId) == false) { SysNotifyMgr.Instance.ShowTip("Map_Delivery"); return; } var _curMapConfig = Config.Instance.Get(PlayerDatas.Instance.baseData.MapID); // 副本中不可以传送 if (_curMapConfig.MapFBType != 0) { SysNotifyMgr.Instance.ShowTip("Map_Delivery"); return; } _model.RequestMapTransport(_npcLocation.mapId); m_SwitchMapFinished = false; m_MapID = _npcLocation.mapId; MapResourcesConfig _mapResConfig = DTCA127_tagMCStartChangeMap.GetMapResourcesConfig(_npcLocation.mapId, 0); if (_mapResConfig != null) { LoadingWin.targetMapResId = _mapResConfig.ID; } } // 找不到或者是本地图 // 找不到可能是客户端对象,也可能是配置不存在 else { _npc = GAMgr.Instance.GetCloserNPC(_hero.Pos, npcID); // 目标点, 默认为主角坐标, 找不到任务终点的时候不移动 Vector3 _destPos = _hero.Pos; // 计算当前坐标与目标角色的坐标差 //GActor _npc = GAMgr.Instance.GetCloserNPC(_hero.Pos, npcID); //// 如果在当前地图找得到已创建出来最近的目标 //if (_npc != null) //{ // _destPos = _npc.Pos; //} //else //{ Vector2 _calculPos = _destPos; if (_findLocation) { _calculPos = _npcLocation.position; } _destPos = new Vector3(_calculPos.x, _hero.Pos.y, _calculPos.y); //} // 判断距离 float _distSqrt = MathUtility.DistanceSqrtXZ(_hero.Pos, _destPos); // 判断是否需要骑马移动 if (_distSqrt > Mathf.Pow(7, 2)) { DTC0428_tagPlayerRideHorse.Send_tagPlayerRideHorse(true); } float _chkDist = Mathf.Max(GeneralConfig.Instance.CloseNpcDist + _config.ModelRadius - 0.3f, 0); if (_config.NPCType == (int)E_NpcType.OpenWorldMap) { _chkDist = 1; } // 针对挖洞对象保持距离为0 if (_npc != null && _config.Dig == 1) { _chkDist = 0; } // 大于配置的距离, 移动至 if (_distSqrt > Mathf.Pow(_chkDist, 2)) { if (_config.NPCType == (int)E_NpcType.Fight) { _hero.MoveToPosition(_destPos, _npcLocation.scope); } else { if (_npc != null) { _destPos = _npc.Pos; } _hero.MoveToPosition(_destPos, _chkDist); } if (s_OnHeroStartMoveToNPC != null) { s_OnHeroStartMoveToNPC(); } } // 小于距离则判断目标的类型,执行相应的逻辑 else { if (_config != null) { if (_config.NPCType == (int)E_NpcType.Fight) { _hero.Behaviour.StartHandupAI(); } else if (_config.NPCType == (int)E_NpcType.Collect) { GA_NpcCollect _collect = _npc as GA_NpcCollect; if (_collect != null) { _collect.Arrive(); } } else { // 如果目标已经在之前搜索中确定了 // 没确定其实在这里应该是异常情况 if (_npc != null) { _hero.LockTarget = _npc; _hero.SelectTarget = _npc; NPCInteractProcessor.InvokeEvent((E_NpcType)_config.NPCType, npcID, _npc.ServerInstID); Vector3 _npc2heroDir = MathUtility.ForwardXZ(_npc.Pos, _hero.Pos); if (_config.AutomaticFace == 1) { _npc.Forward = -_npc2heroDir; } _hero.Forward = _npc2heroDir; } // 会有为空的时候, 例如是小飞鞋飞的情况, 这里直接判断与配置的坐标的距离 else { } } } } } } public void MoveToLocalMapPosition(Vector3 _position) { var hero = PlayerDatas.Instance.hero; if (GA_Hero.s_MapSwitching || hero == null) { return; } MapTransferDoType = E_MapTransferDoType.None; m_DelayMoveToPos = false; m_TempPos = hero.Pos; hero.Behaviour.StopHandupAI(); hero.Behaviour.StopKillUntilDieAI(); if ((hero.SkillMgr.CurCastSkill != null && !hero.SkillMgr.CurCastSkill.SkillCompelete) || hero.IsRushing) { m_TempPos = _position; m_DelayMoveToPos = true; return; } hero.MoveToPosition(new Vector3(_position.x * 0.5f, 0f, _position.y * 0.5f)); DTC0428_tagPlayerRideHorse.Send_tagPlayerRideHorse(true); } public void MissionFlyTo(int mapId, int npcId, int extField = 0) { if (PlayerDatas.Instance.extersion.pkState == 1) { SysNotifyMgr.Instance.ShowTip("PK_Leave"); return; } GA_Hero _hero = PlayerDatas.Instance.hero; Vector3 _position = _hero.Pos; Vector3 _result = new Vector2(_position.x, _position.z); Quaternion _rot = Quaternion.identity; GAStaticDefine.NPCLocation npcLocation; var findLocation = GAStaticDefine.TryGetMapNPCLocation(npcId, out npcLocation); MapModel _model = ModelCenter.Instance.GetModel(); if (_hero.State == E_ActorState.AutoRun) { _hero.StopPathFind(); } if (findLocation) { mapId = npcLocation.mapId; _result = npcLocation.position; _rot = MathUtility.GetClientRotationFromAngle(npcLocation.face); } _position.x = _result.x; _position.y = _hero.Pos.y; _position.z = _result.y; MapTransferDoType = E_MapTransferDoType.Npc; NpcID = npcId; // 如果处于相同地图且距离小于一定的值, 则不传送 if (mapId == PlayerDatas.Instance.baseData.MapID) { FuncConfigConfig _func = Config.Instance.Get("flyMinDistance"); if (_func != null) { float _distance = float.Parse(_func.Numerical1); if (Vector3.SqrMagnitude(_hero.Pos - _position) < _distance * _distance) { MoveToNPC(npcId); SysNotifyMgr.Instance.ShowTip("NearbyHint"); return; } } } else { var _curMapConfig = Config.Instance.Get(PlayerDatas.Instance.baseData.MapID); // 副本中不可以传送(某些特定地图可以进行传送Zxw) var mainModel = ModelCenter.Instance.GetModel(); int MapId = PlayerDatas.Instance.baseData.MapID; if (_curMapConfig.MapFBType != 0 && !mainModel.OneKeyList.Contains(MapId)) { SysNotifyMgr.Instance.ShowTip("Map_Delivery"); return; } if (_model.IsMapUnLocked(npcLocation.mapId) == false) { SysNotifyMgr.Instance.ShowTip("Map_Delivery"); return; } if (PlayerDatas.Instance.extersion.bossState == 1) { SysNotifyMgr.Instance.ShowTip("Task_Transfer1"); return; } if (PlayerDatas.Instance.extersion.pkState == 1) { SysNotifyMgr.Instance.ShowTip("PK_Leave"); return; } MapResourcesConfig _config = DTCA127_tagMCStartChangeMap.GetMapResourcesConfig(npcLocation.mapId, 0); if (_config != null) { LoadingWin.targetMapResId = _config.ID; } else { LoadingWin.targetMapResId = 1; } } _hero.Behaviour.StopHandupAI(); _hero.Behaviour.StopKillUntilDieAI(); _position += _rot * Vector3.forward * 1; Send_WorldTransfer(mapId, _position * 2, MapTransferType.MissionTransport); } public void FlyTo(int mapID, Vector3 pos, byte lineID = 255) { if (PlayerDatas.Instance.extersion.pkState == 1) { SysNotifyMgr.Instance.ShowTip("PK_Leave"); return; } if (PlayerDatas.Instance.extersion.bossState == 1) { SysNotifyMgr.Instance.ShowTip("Task_Transfer1"); return; } GA_Hero _hero = PlayerDatas.Instance.hero; // 如果处于相同地图且距离小于一定的值, 则不传送 if (mapID == PlayerDatas.Instance.baseData.MapID && lineID == PlayerDatas.Instance.baseData.FBID) { FuncConfigConfig _func = Config.Instance.Get("flyMinDistance"); if (_func != null) { float _distance = float.Parse(_func.Numerical1); if (Vector3.SqrMagnitude(_hero.Pos - pos) < _distance * _distance) { _hero.MoveToPosition(pos); SysNotifyMgr.Instance.ShowTip("NearbyHint"); return; } } } else { var _curMapConfig = Config.Instance.Get(PlayerDatas.Instance.baseData.MapID); // 副本中不可以传送 if (_curMapConfig.MapFBType != 0) { SysNotifyMgr.Instance.ShowTip("Map_Delivery"); return; } MapModel _model = ModelCenter.Instance.GetModel(); if (_model.IsMapUnLocked(mapID) == false) { SysNotifyMgr.Instance.ShowTip("Map_Delivery"); return; } MapResourcesConfig _config = DTCA127_tagMCStartChangeMap.GetMapResourcesConfig(mapID, 0); if (_config != null) { LoadingWin.targetMapResId = _config.ID; } else { LoadingWin.targetMapResId = 1; } } _hero.Behaviour.StopHandupAI(); _hero.Behaviour.StopKillUntilDieAI(); Send_WorldTransfer(mapID, pos * 2, MapTransferType.MissionTransport, lineID); } public static bool Send_WorldTransfer(int mapId, Vector3 position, MapTransferType type, byte lineID = 255, int _npcId = 0) { if (!AssetSource.sceneFromEditor && VersionConfig.Get().assetAccess != InstalledAsset.IngoreDownLoad && !AssetVersionUtility.unPriorAssetDownLoadDone) { var mapResConfig = DTCA127_tagMCStartChangeMap.GetMapResourcesConfig(mapId, 0); var assetVersion = AssetVersionUtility.GetAssetVersion(StringUtility.Contact("maps/", mapResConfig.MapResources.ToLower())); if (!assetVersion.IsPriorAsset()) { InGameDownLoad.Instance.TryDownLoad(InGameDownLoad.Dominant.Whole); return false; } } var _transfer = new CB005_tagCMWorldTransfer { MapID = (uint)mapId, PosX = (ushort)(position.x), PosY = (ushort)(position.z), Type = (byte)type,// 1 世界传送; 2 大地图传送; 3 任务传送 LineID = lineID, ExData1 = (uint)_npcId }; GameNetSystem.Instance.SendInfo(_transfer); return true; } public void OnHeroPathFinding() { //if (MapTransferDoType != E_MapTransferDoType.Npc) //{ // return; //} //GA_Hero _hero = PlayerDatas.Instance.hero; //if (_hero == null) //{ // return; //} //NPCConfig _npcConfig = ConfigManager.Instance.GetTemplate(NpcID); //if (_npcConfig == null) //{ // return; //} //float _checkDistSqrt; //// 这里对战斗类型的NPC特殊处理, 如果在地图中已经出现了, 就找那个最近的那个 //if (_npcConfig.NPCType == (int)E_NpcType.Fight) //{ // // 是否要移动至的目标已经出现在地图中 // GActor _closerNpc = GAMgr.Instance.GetCloserNPC(_hero.Pos, NpcID); // if (_closerNpc != null) // { // _checkDistSqrt = MathUtility.DistanceSqrtXZ(_hero.Pos, _closerNpc.Pos); // if (_checkDistSqrt < Mathf.Pow(4, 2))// 这里的2M是暂定值 // { // _hero.StopPathFind(); // _hero.Behaviour.StartHandupAI(); // Clear(); // } // } //} } public void OnHeroStopPathFind() { // 非寻路至NPC逻辑停下, 不做后续操作 if (MapTransferDoType != E_MapTransferDoType.Npc) { return; } GA_Hero _hero = PlayerDatas.Instance.hero; if (_hero == null) { Clear(); return; } // 找不到配置, 不做后续操作 NPCConfig _npcConfig = Config.Instance.Get(NpcID); if (_npcConfig == null) { Clear(); return; } GAStaticDefine.NPCLocation _npcLocation; var _findLocation = GAStaticDefine.TryGetMapNPCLocation(NpcID, out _npcLocation); float _chkDistSqrt = 0; if (_findLocation) { _chkDistSqrt = MathUtility.DistanceSqrtXZ(_hero.Pos, new Vector3(_npcLocation.position.x, 0, _npcLocation.position.y)); } // 如果停止下来的时候并没有找到目标NPC, 则不做后续操作 GActor _npc = GAMgr.Instance.GetCloserNPC(_hero.Pos, NpcID); if (_npc != null) { _chkDistSqrt = MathUtility.DistanceSqrtXZ(_hero.Pos, _npc.Pos); } if (_npcConfig.NPCType == (int)E_NpcType.Fight) { float _fightConfigDist = _findLocation ? _npcLocation.scope : 4; if (_chkDistSqrt < Mathf.Pow(_fightConfigDist, 2) || _npc != null)// 这里的2M是暂定值 { _hero.Behaviour.StartHandupAI(); Clear(); } } else if (_npcConfig.NPCType == (int)E_NpcType.Collect) { } else { float _chkDist = GeneralConfig.Instance.CloseNpcDist + _npcConfig.ModelRadius + 0.3f; // 因为守护副本美术有挖洞, 洞太大了. 这里无法按照配置走,特殊处理 if (_npcConfig.NPCID == 32504001) { _chkDist = 2; } if (_findLocation) { Vector3 _configPos = new Vector3(_npcLocation.position.x, 0, _npcLocation.position.y); _chkDistSqrt = MathUtility.DistanceSqrtXZ(_hero.Pos, _configPos); //Debug.Log("1.....当前距离: " + Mathf.Sqrt(_chkDistSqrt) // + ".....应该保持的距离: " + _chkDist // + ".....目标在: " + _configPos); } //else //{ // Debug.Log("2.....当前距离: " + Vector3.Distance(_npc.Pos, _hero.Pos) // + ".....应该保持的距离: " + _chkDist); //} if (_npc != null) { if (_chkDistSqrt <= Mathf.Pow(_chkDist, 2)) { NPCInteractProcessor.InvokeEvent((E_NpcType)_npcConfig.NPCType, _npcConfig.NPCID, _npc.ServerInstID); _hero.LockTarget = _npc; _hero.SelectTarget = _npc; Vector3 _npc2heroDir = MathUtility.ForwardXZ(_npc.Pos, _hero.Pos); if (_npcConfig.AutomaticFace == 1) { _npc.Forward = -_npc2heroDir; } _hero.Forward = _npc2heroDir; } } } } public void Clear() { if (m_SwitchMapFinished) { NpcID = 0; MapTransferDoType = E_MapTransferDoType.None; m_DelayMoveToNPC = false; } } }