From 9b8b471bf890b732fdc8a278c67130b6911eab66 Mon Sep 17 00:00:00 2001 From: Interkarma Date: Sun, 27 Nov 2022 13:31:18 +1000 Subject: [PATCH] Travel map search and list localized location names Regenerates a localized map name lookup when searching or listing locations within region. Search and list then use localized lookup table instead of canonical map name table. Always using canonical region map names as fallback. --- .../DaggerfallTravelMapWindow.cs | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/Assets/Scripts/Game/UserInterfaceWindows/DaggerfallTravelMapWindow.cs b/Assets/Scripts/Game/UserInterfaceWindows/DaggerfallTravelMapWindow.cs index 6522dc31f7..cc609cb576 100644 --- a/Assets/Scripts/Game/UserInterfaceWindows/DaggerfallTravelMapWindow.cs +++ b/Assets/Scripts/Game/UserInterfaceWindows/DaggerfallTravelMapWindow.cs @@ -164,6 +164,10 @@ public class DaggerfallTravelMapWindow : DaggerfallPopupWindow protected string distanceRegionName = null; protected IDistance distance; + // Populated with localized names whenever player searches or lists inside this region + // Used to complete search and list on localized names over canonical names + protected Dictionary localizedMapNameLookup = new Dictionary(); + #endregion #region Properties @@ -418,7 +422,7 @@ public override void Update() if (!RegionSelected || currentDFRegion.LocationCount < 1) return; - string[] locations = currentDFRegion.MapNames.OrderBy(p => p).ToArray(); + string[] locations = GetCurrentRegionLocalizedMapNames().OrderBy(p => p).ToArray(); ShowLocationPicker(locations, true); } else if (DaggerfallShortcut.GetBinding(DaggerfallShortcut.Buttons.TravelMapFind).IsUpWith(keyModifiers)) @@ -1453,6 +1457,25 @@ protected virtual void HandleLocationFindEvent(DaggerfallInputMessageBox inputMe } } + // Get localized names of all locations in current region with fallback to canonical name + // Builds a new name lookup dictionary for this region on every call used to complete search + protected string[] GetCurrentRegionLocalizedMapNames() + { + localizedMapNameLookup.Clear(); + List localizedNames = new List(currentDFRegion.MapNames.Length); + for (int l = 0; l < currentDFRegion.MapNames.Length; l++) + { + // Handle duplicate names in same way as Region.MapNameLookup + string name = TextManager.Instance.GetLocalizedLocationName(currentDFRegion.MapTable[l].MapId, currentDFRegion.MapNames[l]); + if (!localizedNames.Contains(name)) + { + localizedNames.Add(name); + localizedMapNameLookup.Add(name, l); + } + } + return localizedNames.ToArray(); + } + // Find location by name protected virtual bool FindLocation(string name, out List matching) { @@ -1466,7 +1489,7 @@ protected virtual bool FindLocation(string name, out List matchin { distanceRegionName = currentDFRegion.Name; distance = DaggerfallDistance.GetDistance(); - distance.SetDictionary(currentDFRegion.MapNames); + distance.SetDictionary(GetCurrentRegionLocalizedMapNames()); } DistanceMatch[] bestMatches = distance.FindBestMatches(name, maxMatchingResults); @@ -1477,12 +1500,13 @@ protected virtual bool FindLocation(string name, out List matchin foreach (DistanceMatch match in bestMatches) { - if (!currentDFRegion.MapNameLookup.ContainsKey(match.text)) + // Must have called GetCurrentRegionLocalizedMapNames() prior to this point + if (!localizedMapNameLookup.ContainsKey(match.text)) { - DaggerfallUnity.LogMessage("Error: location name key not found in Region MapNameLookup dictionary"); + Debug.LogWarningFormat("Error: location name '{0}' key not found in localizedMapNameLookup dictionary for this region.", match.text); continue; } - int index = currentDFRegion.MapNameLookup[match.text]; + int index = localizedMapNameLookup[match.text]; DFRegion.RegionMapTable locationInfo = currentDFRegion.MapTable[index]; DFPosition pos = MapsFile.LongitudeLatitudeToMapPixel((int)locationInfo.Longitude, (int)locationInfo.Latitude); if (DaggerfallUnity.ContentReader.HasLocation(pos.X, pos.Y, out findLocationSummary)) @@ -1539,7 +1563,8 @@ private void ShowLocationPicker(string[] locations, bool applyFilters) { if (applyFilters) { - int index = currentDFRegion.MapNameLookup[locations[i]]; + // Must have called GetCurrentRegionLocalizedMapNames() prior to this point + int index = localizedMapNameLookup[locations[i]]; if (GetPixelColorIndex(currentDFRegion.MapTable[index].LocationType) == -1) continue; }