MapLocationNaming.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  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. // Mark as discovered if not already
  199. if (!location.isDiscovered)
  200. {
  201. location.isDiscovered = true;
  202. RefreshLocationDisplay(location);
  203. }
  204. // Handle location-specific actions
  205. switch (location.locationType)
  206. {
  207. case LocationType.Town:
  208. case LocationType.Village:
  209. // Set as travel destination or open location details
  210. SetTravelDestination(location);
  211. break;
  212. case LocationType.Forest:
  213. case LocationType.Mountain:
  214. // Show exploration options
  215. ShowExplorationOptions(location);
  216. break;
  217. case LocationType.Ruins:
  218. case LocationType.Cave:
  219. case LocationType.Dungeon:
  220. // Show dungeon/exploration entry
  221. ShowDungeonEntry(location);
  222. break;
  223. }
  224. }
  225. #endregion
  226. #region Location Actions
  227. private void SetTravelDestination(MapLocation location)
  228. {
  229. // Find travel system and set destination
  230. // var travelSystem = FindFirstObjectByType<TravelSystem>();
  231. // if (travelSystem != null)
  232. // {
  233. // travelSystem.SetDestination(location.mapPosition, location.locationName);
  234. // }
  235. // Show confirmation message
  236. ShowLocationMessage($"Travel destination set to {location.locationName}", Color.green);
  237. }
  238. private void ShowExplorationOptions(MapLocation location)
  239. {
  240. ShowLocationMessage($"Exploring {location.locationName}...", Color.cyan);
  241. // Could trigger random encounters, resource gathering, etc.
  242. }
  243. private void ShowDungeonEntry(MapLocation location)
  244. {
  245. ShowLocationMessage($"Entering {location.locationName}...", Color.yellow);
  246. // Could load dungeon scene or start combat encounter
  247. }
  248. #endregion
  249. #region UI Helpers
  250. private void ShowLocationTooltip(MapLocation location, VisualElement label)
  251. {
  252. // Create tooltip showing location details
  253. var tooltip = new VisualElement();
  254. tooltip.name = "location-tooltip";
  255. tooltip.AddToClassList("location-tooltip");
  256. var nameLabel = new Label(location.locationName);
  257. nameLabel.AddToClassList("tooltip-name");
  258. var typeLabel = new Label(location.locationType.ToString());
  259. typeLabel.AddToClassList("tooltip-type");
  260. var statusLabel = new Label(location.isDiscovered ? "Discovered" : "Undiscovered");
  261. statusLabel.AddToClassList("tooltip-status");
  262. tooltip.Add(nameLabel);
  263. tooltip.Add(typeLabel);
  264. tooltip.Add(statusLabel);
  265. // Position tooltip near the label
  266. tooltip.style.position = Position.Absolute;
  267. tooltip.style.left = label.style.left.value.value + 20;
  268. tooltip.style.top = label.style.top.value.value - 10;
  269. mapContainer.Add(tooltip);
  270. }
  271. private void HideLocationTooltip()
  272. {
  273. var tooltip = mapContainer.Q<VisualElement>("location-tooltip");
  274. if (tooltip != null)
  275. {
  276. mapContainer.Remove(tooltip);
  277. }
  278. }
  279. private void ShowLocationMessage(string message, Color color)
  280. {
  281. // Create temporary message display
  282. var messageLabel = new Label(message);
  283. messageLabel.AddToClassList("location-message");
  284. messageLabel.style.color = color;
  285. messageLabel.style.position = Position.Absolute;
  286. messageLabel.style.bottom = 50;
  287. messageLabel.style.left = Length.Percent(50);
  288. messageLabel.style.translate = new Translate(Length.Percent(-50), 0);
  289. mapContainer.Add(messageLabel);
  290. // Remove after delay
  291. StartCoroutine(RemoveMessageAfterDelay(messageLabel, 3f));
  292. }
  293. private System.Collections.IEnumerator RemoveMessageAfterDelay(VisualElement message, float delay)
  294. {
  295. yield return new WaitForSeconds(delay);
  296. if (message.parent != null)
  297. message.parent.Remove(message);
  298. }
  299. private void RefreshLocationDisplay(MapLocation location)
  300. {
  301. // Find and update the specific location label
  302. foreach (var label in locationLabels)
  303. {
  304. if (label.text == location.locationName)
  305. {
  306. label.style.opacity = 1f;
  307. label.RemoveFromClassList("undiscovered");
  308. break;
  309. }
  310. }
  311. }
  312. #endregion
  313. #region Public Methods
  314. public void DiscoverLocation(string locationName)
  315. {
  316. var location = predefinedLocations.Find(l => l.locationName == locationName);
  317. if (location != null && !location.isDiscovered)
  318. {
  319. location.isDiscovered = true;
  320. RefreshLocationDisplay(location);
  321. ShowLocationMessage($"Discovered: {locationName}!", new Color(1f, 0.84f, 0f)); // gold color
  322. }
  323. }
  324. public void AddCustomLocation(string name, LocationType type, Vector2 position, bool discovered = false)
  325. {
  326. var newLocation = new MapLocation
  327. {
  328. locationName = name,
  329. locationType = type,
  330. mapPosition = position,
  331. isDiscovered = discovered,
  332. showName = true
  333. };
  334. predefinedLocations.Add(newLocation);
  335. if (mapContainer != null)
  336. {
  337. CreateLocationLabel(newLocation);
  338. }
  339. }
  340. public void RefreshAllLocations()
  341. {
  342. DisplayLocationNames();
  343. }
  344. public MapLocation GetNearestLocation(Vector2 worldPosition, float maxDistance = 10f)
  345. {
  346. MapLocation nearest = null;
  347. float closestDistance = float.MaxValue;
  348. foreach (var location in predefinedLocations)
  349. {
  350. float distance = Vector2.Distance(worldPosition, location.mapPosition);
  351. if (distance < maxDistance && distance < closestDistance)
  352. {
  353. nearest = location;
  354. closestDistance = distance;
  355. }
  356. }
  357. return nearest;
  358. }
  359. #endregion
  360. }