diff --git a/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs b/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs index adcbc3d2d3..409d1d3335 100644 --- a/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs +++ b/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs @@ -4,6 +4,7 @@ using CSNetwork; using ModelRenderer.Scripts.GameData; using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using UnityEngine; using UnityEngine.AddressableAssets; @@ -114,6 +115,10 @@ namespace BrewMonster.Network GetGameRun().Init(); InitializeStringTables(); + // Load coord_data.txt (C++: Configs/Coord_data.txt) for clickable task links auto-move. + // 加载 coord_data.txt(C++:Configs/Coord_data.txt)用于任务可点击链接的自动移动。 + LoadObjectCoord(); + return true; } public static CECConfigs GetConfigs() { return m_pConfigs; } @@ -262,6 +267,140 @@ namespace BrewMonster.Network long unixTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); return (int)unixTime + m_iTimeError; } + + //////////////////////////////////////////////////////////////////////////////// + // + // Coord_data.txt support (C++: Configs/Coord_data.txt, CECGame::LoadObjectCoord/GetObjectCoord) + // + //////////////////////////////////////////////////////////////////////////////// + + private struct OBJECT_COORD + { + public string strMap; + public Vector3 vPos; + } + + private static readonly Dictionary> m_CoordTab = + new Dictionary>(StringComparer.OrdinalIgnoreCase); + + private static bool m_bCoordLoaded = false; + + public static bool LoadObjectCoord() + { + if (m_bCoordLoaded) + { + return true; + } + + try + { + Addressables.InitializeAsync().WaitForCompletion(); + var ta = Addressables.LoadAssetAsync("Assets/Addressable/coord_data.txt").WaitForCompletion(); + if (ta == null) + { + Debug.LogError("[EC_Game] LoadObjectCoord: failed to load Addressable 'Assets/Addressable/coord_data.txt'"); + return false; + } + + ParseCoordDataText(ta.text); + m_bCoordLoaded = true; + Debug.Log($"[EC_Game] LoadObjectCoord: loaded {m_CoordTab.Count} coord keys from coord_data.txt"); + return true; + } + catch (Exception ex) + { + Debug.LogError($"[EC_Game] LoadObjectCoord exception: {ex}"); + return false; + } + } + + private static void ParseCoordDataText(string text) + { + m_CoordTab.Clear(); + if (string.IsNullOrEmpty(text)) + { + return; + } + + using var sr = new StringReader(text); + string line; + int lineNo = 0; + + while ((line = sr.ReadLine()) != null) + { + lineNo++; + if (string.IsNullOrWhiteSpace(line)) + { + continue; + } + + line = line.Trim(); + if (line.StartsWith("#", StringComparison.Ordinal) || line.StartsWith("//", StringComparison.Ordinal)) + { + continue; + } + + if (lineNo == 1 && line.StartsWith("ID", StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + string[] parts = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries); + if (parts.Length < 5) + { + continue; + } + + string key = parts[0]; + string map = parts[1]; + + if (!float.TryParse(parts[2], NumberStyles.Float, CultureInfo.InvariantCulture, out float x) || + !float.TryParse(parts[3], NumberStyles.Float, CultureInfo.InvariantCulture, out float y) || + !float.TryParse(parts[4], NumberStyles.Float, CultureInfo.InvariantCulture, out float z)) + { + continue; + } + + var coord = new OBJECT_COORD + { + strMap = map, + vPos = new Vector3(x, y, z), + }; + + if (!m_CoordTab.TryGetValue(key, out var list)) + { + list = new List(1); + m_CoordTab[key] = list; + } + + list.Add(coord); + } + } + + public static bool TryGetFirstObjectCoord(string targetId, out Vector3 pos, out string map) + { + pos = default; + map = null; + + if (string.IsNullOrWhiteSpace(targetId)) + { + return false; + } + + if (!m_bCoordLoaded) + { + LoadObjectCoord(); + } + + if (!m_CoordTab.TryGetValue(targetId, out var list) || list == null || list.Count == 0) + { + return false; + } + + pos = list[0].vPos; + map = list[0].strMap; + return true; + } #endregion } } \ No newline at end of file