MapLocationNaming.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. using UnityEngine;
  2. using UnityEngine.UIElements;
  3. using System.Collections.Generic;
  4. [System.Serializable]
  5. public class MapLocation
  6. {
  7. public string locationName;
  8. public LocationType locationType;
  9. public Vector2 mapPosition;
  10. public bool isDiscovered = false;
  11. public bool showName = true;
  12. }
  13. public enum LocationType
  14. {
  15. Town,
  16. Village,
  17. Forest,
  18. Mountain,
  19. River,
  20. Cave,
  21. Ruins,
  22. Dungeon,
  23. Landmark
  24. }
  25. public class MapLocationNaming : MonoBehaviour
  26. {
  27. [Header("Location Configuration")]
  28. public List<MapLocation> predefinedLocations = new List<MapLocation>();
  29. [Header("UI References")]
  30. public UIDocument mapUI;
  31. [Header("Visual Settings")]
  32. public Font locationFont;
  33. public Color townColor = Color.white;
  34. public Color villageColor = Color.cyan;
  35. public Color forestColor = Color.green;
  36. public Color mountainColor = Color.gray;
  37. public Color landmarkColor = Color.yellow;
  38. private VisualElement mapContainer;
  39. private List<Label> locationLabels = new List<Label>();
  40. // Conversion settings (adjust based on your map scale)
  41. [Header("Map Conversion")]
  42. public Vector2 mapSize = new Vector2(1920, 1080); // UI map size
  43. public Vector2 worldSize = new Vector2(100, 100); // World coordinates range
  44. public Vector2 mapOffset = Vector2.zero; // Offset for map positioning
  45. void Start()
  46. {
  47. InitializeLocationNaming();
  48. CreatePredefinedLocations();
  49. DisplayLocationNames();
  50. }
  51. private void InitializeLocationNaming()
  52. {
  53. if (mapUI == null)
  54. mapUI = GetComponent<UIDocument>();
  55. if (mapUI != null)
  56. {
  57. mapContainer = mapUI.rootVisualElement.Q<VisualElement>("map-container");
  58. if (mapContainer == null)
  59. {
  60. // Create map container if it doesn't exist
  61. mapContainer = new VisualElement();
  62. mapContainer.name = "map-container";
  63. mapContainer.style.position = Position.Absolute;
  64. mapContainer.style.width = Length.Percent(100);
  65. mapContainer.style.height = Length.Percent(100);
  66. mapUI.rootVisualElement.Add(mapContainer);
  67. }
  68. }
  69. }
  70. private void CreatePredefinedLocations()
  71. {
  72. if (predefinedLocations.Count == 0)
  73. {
  74. // Create some default locations - adjust coordinates based on your map
  75. predefinedLocations.AddRange(new MapLocation[]
  76. {
  77. // Towns
  78. new MapLocation { locationName = "Hearthhaven", locationType = LocationType.Town, mapPosition = new Vector2(50, 40), isDiscovered = true },
  79. new MapLocation { locationName = "Irongate", locationType = LocationType.Town, mapPosition = new Vector2(75, 60), isDiscovered = true },
  80. new MapLocation { locationName = "Goldmeadow", locationType = LocationType.Town, mapPosition = new Vector2(30, 70), isDiscovered = false },
  81. // Villages
  82. new MapLocation { locationName = "Millbrook", locationType = LocationType.Village, mapPosition = new Vector2(40, 50), isDiscovered = true },
  83. new MapLocation { locationName = "Stonehaven", locationType = LocationType.Village, mapPosition = new Vector2(65, 35), isDiscovered = false },
  84. new MapLocation { locationName = "Riverside", locationType = LocationType.Village, mapPosition = new Vector2(25, 55), isDiscovered = true },
  85. // Forests
  86. new MapLocation { locationName = "Whispering Woods", locationType = LocationType.Forest, mapPosition = new Vector2(35, 30), isDiscovered = true },
  87. new MapLocation { locationName = "Darkwood Forest", locationType = LocationType.Forest, mapPosition = new Vector2(80, 25), isDiscovered = false },
  88. new MapLocation { locationName = "Emerald Grove", locationType = LocationType.Forest, mapPosition = new Vector2(20, 40), isDiscovered = true },
  89. // Mountains
  90. new MapLocation { locationName = "Frostpeak Mountains", locationType = LocationType.Mountain, mapPosition = new Vector2(85, 80), isDiscovered = true },
  91. new MapLocation { locationName = "Dragon's Spine", locationType = LocationType.Mountain, mapPosition = new Vector2(90, 50), isDiscovered = false },
  92. new MapLocation { locationName = "Stormhaven Peaks", locationType = LocationType.Mountain, mapPosition = new Vector2(15, 80), isDiscovered = true },
  93. // Landmarks
  94. new MapLocation { locationName = "Ancient Ruins", locationType = LocationType.Ruins, mapPosition = new Vector2(55, 25), isDiscovered = false },
  95. new MapLocation { locationName = "Crystal Cave", locationType = LocationType.Cave, mapPosition = new Vector2(70, 75), isDiscovered = false },
  96. new MapLocation { locationName = "The Great Bridge", locationType = LocationType.Landmark, mapPosition = new Vector2(45, 65), isDiscovered = true }
  97. });
  98. }
  99. }
  100. private void DisplayLocationNames()
  101. {
  102. ClearLocationLabels();
  103. foreach (var location in predefinedLocations)
  104. {
  105. if (location.showName && (location.isDiscovered || ShouldShowUndiscovered(location)))
  106. {
  107. CreateLocationLabel(location);
  108. }
  109. }
  110. }
  111. private bool ShouldShowUndiscovered(MapLocation location)
  112. {
  113. // Show town/village names even if not discovered
  114. return location.locationType == LocationType.Town || location.locationType == LocationType.Village;
  115. }
  116. private void CreateLocationLabel(MapLocation location)
  117. {
  118. var label = new Label(location.locationName);
  119. label.AddToClassList("location-label");
  120. label.AddToClassList($"location-{location.locationType.ToString().ToLower()}");
  121. // Convert world position to UI position
  122. Vector2 uiPosition = WorldToUIPosition(location.mapPosition);
  123. // Position the label
  124. label.style.position = Position.Absolute;
  125. label.style.left = uiPosition.x;
  126. label.style.top = uiPosition.y;
  127. // Set color based on location type
  128. Color labelColor = GetLocationColor(location);
  129. label.style.color = labelColor;
  130. // Set opacity based on discovery status
  131. if (!location.isDiscovered)
  132. {
  133. label.style.opacity = 0.6f;
  134. label.AddToClassList("undiscovered");
  135. }
  136. // Add tooltip/hover effects
  137. label.RegisterCallback<MouseEnterEvent>(evt => OnLocationHover(location, label));
  138. label.RegisterCallback<MouseLeaveEvent>(evt => OnLocationHoverEnd(location, label));
  139. label.RegisterCallback<ClickEvent>(evt => OnLocationClick(location));
  140. mapContainer.Add(label);
  141. locationLabels.Add(label);
  142. }
  143. private Vector2 WorldToUIPosition(Vector2 worldPosition)
  144. {
  145. // Convert world coordinates to UI coordinates
  146. float xPercent = (worldPosition.x + mapOffset.x) / worldSize.x;
  147. float yPercent = (worldPosition.y + mapOffset.y) / worldSize.y;
  148. float uiX = xPercent * mapSize.x;
  149. float uiY = yPercent * mapSize.y;
  150. return new Vector2(uiX, uiY);
  151. }
  152. private Color GetLocationColor(MapLocation location)
  153. {
  154. switch (location.locationType)
  155. {
  156. case LocationType.Town:
  157. return townColor;
  158. case LocationType.Village:
  159. return villageColor;
  160. case LocationType.Forest:
  161. return forestColor;
  162. case LocationType.Mountain:
  163. return mountainColor;
  164. case LocationType.Landmark:
  165. case LocationType.Ruins:
  166. case LocationType.Cave:
  167. return landmarkColor;
  168. default:
  169. return Color.white;
  170. }
  171. }
  172. private void ClearLocationLabels()
  173. {
  174. foreach (var label in locationLabels)
  175. {
  176. if (label.parent != null)
  177. label.parent.Remove(label);
  178. }
  179. locationLabels.Clear();
  180. }
  181. #region Event Handlers
  182. private void OnLocationHover(MapLocation location, VisualElement label)
  183. {
  184. // Increase size slightly and add glow effect
  185. label.style.scale = new Scale(Vector3.one * 1.1f);
  186. label.AddToClassList("location-hover");
  187. // Show location info tooltip if desired
  188. ShowLocationTooltip(location, label);
  189. }
  190. private void OnLocationHoverEnd(MapLocation location, VisualElement label)
  191. {
  192. label.style.scale = new Scale(Vector3.one);
  193. label.RemoveFromClassList("location-hover");
  194. HideLocationTooltip();
  195. }
  196. private void OnLocationClick(MapLocation location)
  197. {
  198. Debug.Log($"Clicked on {location.locationName} ({location.locationType})");
  199. // Mark as discovered if not already
  200. if (!location.isDiscovered)
  201. {
  202. location.isDiscovered = true;
  203. RefreshLocationDisplay(location);
  204. }
  205. // Handle location-specific actions
  206. switch (location.locationType)
  207. {
  208. case LocationType.Town:
  209. case LocationType.Village:
  210. // Set as travel destination or open location details
  211. SetTravelDestination(location);
  212. break;
  213. case LocationType.Forest:
  214. case LocationType.Mountain:
  215. // Show exploration options
  216. ShowExplorationOptions(location);
  217. break;
  218. case LocationType.Ruins:
  219. case LocationType.Cave:
  220. case LocationType.Dungeon:
  221. // Show dungeon/exploration entry
  222. ShowDungeonEntry(location);
  223. break;
  224. }
  225. }
  226. #endregion
  227. #region Location Actions
  228. private void SetTravelDestination(MapLocation location)
  229. {
  230. Debug.Log($"Setting travel destination to {location.locationName}");
  231. // Find travel system and set destination
  232. // var travelSystem = FindFirstObjectByType<TravelSystem>();
  233. // if (travelSystem != null)
  234. // {
  235. // travelSystem.SetDestination(location.mapPosition, location.locationName);
  236. // }
  237. // Show confirmation message
  238. ShowLocationMessage($"Travel destination set to {location.locationName}", Color.green);
  239. }
  240. private void ShowExplorationOptions(MapLocation location)
  241. {
  242. Debug.Log($"Exploring {location.locationName}");
  243. ShowLocationMessage($"Exploring {location.locationName}...", Color.cyan);
  244. // Could trigger random encounters, resource gathering, etc.
  245. }
  246. private void ShowDungeonEntry(MapLocation location)
  247. {
  248. Debug.Log($"Entering {location.locationName}");
  249. ShowLocationMessage($"Entering {location.locationName}...", Color.yellow);
  250. // Could load dungeon scene or start combat encounter
  251. }
  252. #endregion
  253. #region UI Helpers
  254. private void ShowLocationTooltip(MapLocation location, VisualElement label)
  255. {
  256. // Create tooltip showing location details
  257. var tooltip = new VisualElement();
  258. tooltip.name = "location-tooltip";
  259. tooltip.AddToClassList("location-tooltip");
  260. var nameLabel = new Label(location.locationName);
  261. nameLabel.AddToClassList("tooltip-name");
  262. var typeLabel = new Label(location.locationType.ToString());
  263. typeLabel.AddToClassList("tooltip-type");
  264. var statusLabel = new Label(location.isDiscovered ? "Discovered" : "Undiscovered");
  265. statusLabel.AddToClassList("tooltip-status");
  266. tooltip.Add(nameLabel);
  267. tooltip.Add(typeLabel);
  268. tooltip.Add(statusLabel);
  269. // Position tooltip near the label
  270. tooltip.style.position = Position.Absolute;
  271. tooltip.style.left = label.style.left.value.value + 20;
  272. tooltip.style.top = label.style.top.value.value - 10;
  273. mapContainer.Add(tooltip);
  274. }
  275. private void HideLocationTooltip()
  276. {
  277. var tooltip = mapContainer.Q<VisualElement>("location-tooltip");
  278. if (tooltip != null)
  279. {
  280. mapContainer.Remove(tooltip);
  281. }
  282. }
  283. private void ShowLocationMessage(string message, Color color)
  284. {
  285. // Create temporary message display
  286. var messageLabel = new Label(message);
  287. messageLabel.AddToClassList("location-message");
  288. messageLabel.style.color = color;
  289. messageLabel.style.position = Position.Absolute;
  290. messageLabel.style.bottom = 50;
  291. messageLabel.style.left = Length.Percent(50);
  292. messageLabel.style.translate = new Translate(Length.Percent(-50), 0);
  293. mapContainer.Add(messageLabel);
  294. // Remove after delay
  295. StartCoroutine(RemoveMessageAfterDelay(messageLabel, 3f));
  296. }
  297. private System.Collections.IEnumerator RemoveMessageAfterDelay(VisualElement message, float delay)
  298. {
  299. yield return new WaitForSeconds(delay);
  300. if (message.parent != null)
  301. message.parent.Remove(message);
  302. }
  303. private void RefreshLocationDisplay(MapLocation location)
  304. {
  305. // Find and update the specific location label
  306. foreach (var label in locationLabels)
  307. {
  308. if (label.text == location.locationName)
  309. {
  310. label.style.opacity = 1f;
  311. label.RemoveFromClassList("undiscovered");
  312. break;
  313. }
  314. }
  315. }
  316. #endregion
  317. #region Public Methods
  318. public void DiscoverLocation(string locationName)
  319. {
  320. var location = predefinedLocations.Find(l => l.locationName == locationName);
  321. if (location != null && !location.isDiscovered)
  322. {
  323. location.isDiscovered = true;
  324. RefreshLocationDisplay(location);
  325. ShowLocationMessage($"Discovered: {locationName}!", new Color(1f, 0.84f, 0f)); // gold color
  326. }
  327. }
  328. public void AddCustomLocation(string name, LocationType type, Vector2 position, bool discovered = false)
  329. {
  330. var newLocation = new MapLocation
  331. {
  332. locationName = name,
  333. locationType = type,
  334. mapPosition = position,
  335. isDiscovered = discovered,
  336. showName = true
  337. };
  338. predefinedLocations.Add(newLocation);
  339. if (mapContainer != null)
  340. {
  341. CreateLocationLabel(newLocation);
  342. }
  343. }
  344. public void RefreshAllLocations()
  345. {
  346. DisplayLocationNames();
  347. }
  348. public MapLocation GetNearestLocation(Vector2 worldPosition, float maxDistance = 10f)
  349. {
  350. MapLocation nearest = null;
  351. float closestDistance = float.MaxValue;
  352. foreach (var location in predefinedLocations)
  353. {
  354. float distance = Vector2.Distance(worldPosition, location.mapPosition);
  355. if (distance < maxDistance && distance < closestDistance)
  356. {
  357. nearest = location;
  358. closestDistance = distance;
  359. }
  360. }
  361. return nearest;
  362. }
  363. #endregion
  364. }