TeamOverviewController.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. using UnityEngine;
  2. using UnityEngine.UIElements;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using UnityEngine.SceneManagement;
  6. using System.Collections;
  7. /// <summary>
  8. /// Controls the TeamOverview UI panel on the right side of the map scene.
  9. /// Displays current team information, stats, and provides navigation controls.
  10. /// Works with the main map UI document.
  11. /// </summary>
  12. public class TeamOverviewController : MonoBehaviour, IClickBlocker
  13. {
  14. [Header("Settings")]
  15. [SerializeField] public bool showDebugLogs = false;
  16. // UI Elements
  17. private VisualElement teamOverviewPanel;
  18. private ScrollView teamMembersList;
  19. private Button manageTeamButton;
  20. private Button saveGameButton;
  21. private Label memberCountLabel;
  22. private Label totalGoldLabel;
  23. private Label averageLevelLabel;
  24. private Toggle perceptionVisualizationToggle;
  25. // UI Document reference (shared with map)
  26. private UIDocument uiDocument;
  27. // Team data
  28. private List<TeamCharacter> currentTeam;
  29. void Awake()
  30. {
  31. // Get the UIDocument component from this GameObject
  32. uiDocument = GetComponent<UIDocument>();
  33. if (uiDocument == null)
  34. {
  35. Debug.LogError("❌ TeamOverviewController: No UIDocument component found on this GameObject!");
  36. }
  37. }
  38. void Start()
  39. {
  40. // Ensure GameStateManager has loaded data if it exists
  41. if (GameStateManager.Instance != null && PlayerPrefs.HasKey("GameSaved"))
  42. {
  43. GameStateManager.Instance.LoadGame();
  44. }
  45. SetupUI();
  46. LoadTeamData();
  47. ShowTeamOverview();
  48. }
  49. /// <summary>
  50. /// Sets up the UI elements and event handlers
  51. /// </summary>
  52. private void SetupUI()
  53. {
  54. if (uiDocument?.rootVisualElement == null)
  55. {
  56. Debug.LogError("❌ TeamOverviewController: UIDocument not found or has no root element!");
  57. return;
  58. }
  59. var root = uiDocument.rootVisualElement;
  60. // Find UI elements - using the correct button names from TeamOverview.uxml
  61. teamOverviewPanel = root.Q("TeamOverviewPanel");
  62. teamMembersList = root.Q<ScrollView>("TeamMembersList");
  63. manageTeamButton = root.Q<Button>("ReturnToTeamSelectButton");
  64. saveGameButton = root.Q<Button>("SaveGameButton");
  65. memberCountLabel = root.Q<Label>("MemberCountLabel");
  66. totalGoldLabel = root.Q<Label>("TotalGoldLabel");
  67. averageLevelLabel = root.Q<Label>("AverageLevelLabel");
  68. perceptionVisualizationToggle = root.Q<Toggle>("PerceptionVisualizationToggle");
  69. // Debug: Check which elements were found
  70. if (showDebugLogs)
  71. {
  72. Debug.Log($"🔍 UI Elements found:");
  73. Debug.Log($" TeamOverviewPanel: {teamOverviewPanel != null}");
  74. Debug.Log($" TeamMembersList: {teamMembersList != null}");
  75. Debug.Log($" ManageTeamButton: {manageTeamButton != null}");
  76. Debug.Log($" SaveGameButton: {saveGameButton != null}");
  77. Debug.Log($" MemberCountLabel: {memberCountLabel != null}");
  78. Debug.Log($" TotalGoldLabel: {totalGoldLabel != null}");
  79. Debug.Log($" AverageLevelLabel: {averageLevelLabel != null}");
  80. Debug.Log($" PerceptionVisualizationToggle: {perceptionVisualizationToggle != null}");
  81. }
  82. // Setup event handlers
  83. if (manageTeamButton != null)
  84. {
  85. manageTeamButton.clicked += OnManageTeamClicked;
  86. }
  87. if (saveGameButton != null)
  88. {
  89. saveGameButton.clicked += OnSaveGameClicked;
  90. }
  91. if (perceptionVisualizationToggle != null)
  92. {
  93. // Load saved toggle state
  94. bool savedState = PlayerPrefs.GetInt("ShowPerceptionVisualization", 1) == 1;
  95. perceptionVisualizationToggle.value = savedState;
  96. // Set up event handler
  97. perceptionVisualizationToggle.RegisterValueChangedCallback(OnPerceptionVisualizationToggled);
  98. // Apply initial state to visualizer
  99. UpdatePerceptionVisualizationState(savedState);
  100. }
  101. // Add mouse event blocking to prevent clicks from going through to map
  102. if (teamOverviewPanel != null)
  103. {
  104. teamOverviewPanel.RegisterCallback<MouseDownEvent>(evt =>
  105. {
  106. evt.StopPropagation();
  107. });
  108. teamOverviewPanel.RegisterCallback<MouseUpEvent>(evt =>
  109. {
  110. evt.StopPropagation();
  111. });
  112. teamOverviewPanel.RegisterCallback<ClickEvent>(evt =>
  113. {
  114. evt.StopPropagation();
  115. });
  116. if (showDebugLogs)
  117. {
  118. Debug.Log("✅ TeamOverview: Mouse event blocking added");
  119. }
  120. }
  121. if (showDebugLogs)
  122. {
  123. Debug.Log("✅ TeamOverviewController: UI setup complete");
  124. }
  125. }
  126. /// <summary>
  127. /// Loads current team data from the save system
  128. /// </summary>
  129. private void LoadTeamData()
  130. {
  131. currentTeam = new List<TeamCharacter>();
  132. // Method 1: Try to load from MainTeamSelectScript (if in TeamSelect scene)
  133. var teamSelectScript = FindFirstObjectByType<MainTeamSelectScript>();
  134. if (teamSelectScript != null)
  135. {
  136. currentTeam = teamSelectScript.GetConfiguredCharacters();
  137. if (showDebugLogs)
  138. {
  139. Debug.Log($"📋 Loaded team from MainTeamSelectScript: {currentTeam.Count} members");
  140. }
  141. return;
  142. }
  143. // Method 2: Try to load from GameStateManager
  144. if (GameStateManager.Instance != null && GameStateManager.Instance.savedTeam != null)
  145. {
  146. foreach (var character in GameStateManager.Instance.savedTeam)
  147. {
  148. if (character != null)
  149. {
  150. currentTeam.Add(character);
  151. }
  152. }
  153. if (currentTeam.Count > 0)
  154. {
  155. if (showDebugLogs)
  156. {
  157. Debug.Log($"📋 Loaded team from GameStateManager: {currentTeam.Count} members");
  158. }
  159. return;
  160. }
  161. }
  162. // Method 3: Try to load directly from PlayerPrefs (fallback)
  163. for (int i = 0; i < 4; i++)
  164. {
  165. string prefix = $"Character{i}_";
  166. if (PlayerPrefs.HasKey(prefix + "Exists") && PlayerPrefs.GetInt(prefix + "Exists") == 1)
  167. {
  168. var character = new TeamCharacter();
  169. character.name = PlayerPrefs.GetString(prefix + "Name", "");
  170. character.isMale = PlayerPrefs.GetInt(prefix + "IsMale", 1) == 1;
  171. character.strength = PlayerPrefs.GetInt(prefix + "Strength", 10);
  172. character.dexterity = PlayerPrefs.GetInt(prefix + "Dexterity", 10);
  173. character.constitution = PlayerPrefs.GetInt(prefix + "Constitution", 10);
  174. character.wisdom = PlayerPrefs.GetInt(prefix + "Wisdom", 10);
  175. character.perception = PlayerPrefs.GetInt(prefix + "Perception", 10);
  176. character.gold = PlayerPrefs.GetInt(prefix + "Gold", 25);
  177. character.silver = PlayerPrefs.GetInt(prefix + "Silver", 0);
  178. character.copper = PlayerPrefs.GetInt(prefix + "Copper", 0);
  179. if (!string.IsNullOrEmpty(character.name))
  180. {
  181. currentTeam.Add(character);
  182. }
  183. }
  184. }
  185. if (currentTeam.Count > 0)
  186. {
  187. if (showDebugLogs)
  188. {
  189. Debug.Log($"📋 Loaded team from PlayerPrefs: {currentTeam.Count} members");
  190. }
  191. }
  192. else
  193. {
  194. if (showDebugLogs)
  195. {
  196. Debug.Log("ℹ️ No team data found - this is normal for a new game");
  197. }
  198. }
  199. } /// <summary>
  200. /// Shows the team overview panel
  201. /// </summary>
  202. public void ShowTeamOverview()
  203. {
  204. if (teamOverviewPanel == null) return;
  205. teamOverviewPanel.style.display = DisplayStyle.Flex;
  206. UpdateTeamDisplay();
  207. if (showDebugLogs)
  208. {
  209. Debug.Log("👥 TeamOverviewController: Team overview panel shown");
  210. }
  211. }
  212. /// <summary>
  213. /// Hides the team overview panel
  214. /// </summary>
  215. public void HideTeamOverview()
  216. {
  217. if (teamOverviewPanel == null) return;
  218. teamOverviewPanel.style.display = DisplayStyle.None;
  219. if (showDebugLogs)
  220. {
  221. Debug.Log("👻 TeamOverviewController: Team overview panel hidden");
  222. }
  223. }
  224. /// <summary>
  225. /// Updates the team display with current data
  226. /// </summary>
  227. private void UpdateTeamDisplay()
  228. {
  229. if (currentTeam == null)
  230. {
  231. if (showDebugLogs)
  232. {
  233. Debug.Log("⚠️ UpdateTeamDisplay: currentTeam is null");
  234. }
  235. return;
  236. }
  237. if (teamMembersList == null)
  238. {
  239. if (showDebugLogs)
  240. {
  241. Debug.Log("⚠️ UpdateTeamDisplay: teamMembersList is null - UI elements not found");
  242. }
  243. return;
  244. }
  245. if (showDebugLogs)
  246. {
  247. Debug.Log($"🎨 UpdateTeamDisplay: Updating display for {currentTeam.Count} team members");
  248. }
  249. // Clear existing team member displays
  250. teamMembersList.Clear();
  251. // Add each team member
  252. foreach (var member in currentTeam)
  253. {
  254. if (member != null)
  255. {
  256. CreateTeamMemberCard(member);
  257. if (showDebugLogs)
  258. {
  259. Debug.Log($"📋 Added card for member: {member.name}");
  260. }
  261. }
  262. }
  263. // Update team stats
  264. UpdateTeamStats();
  265. if (showDebugLogs)
  266. {
  267. Debug.Log($"✅ UpdateTeamDisplay: Display updated with {currentTeam.Count} members");
  268. }
  269. }
  270. /// <summary>
  271. /// Creates a visual card for a team member
  272. /// </summary>
  273. private void CreateTeamMemberCard(TeamCharacter member)
  274. {
  275. var memberCard = new VisualElement();
  276. memberCard.style.backgroundColor = new StyleColor(new Color(0.3f, 0.3f, 0.3f, 0.8f));
  277. memberCard.style.borderTopColor = new StyleColor(new Color(0.5f, 0.5f, 0.5f));
  278. memberCard.style.borderBottomColor = new StyleColor(new Color(0.5f, 0.5f, 0.5f));
  279. memberCard.style.borderLeftColor = new StyleColor(new Color(0.5f, 0.5f, 0.5f));
  280. memberCard.style.borderRightColor = new StyleColor(new Color(0.5f, 0.5f, 0.5f));
  281. memberCard.style.borderTopWidth = 1;
  282. memberCard.style.borderBottomWidth = 1;
  283. memberCard.style.borderLeftWidth = 1;
  284. memberCard.style.borderRightWidth = 1;
  285. memberCard.style.borderTopLeftRadius = 4;
  286. memberCard.style.borderTopRightRadius = 4;
  287. memberCard.style.borderBottomLeftRadius = 4;
  288. memberCard.style.borderBottomRightRadius = 4;
  289. memberCard.style.marginBottom = 8;
  290. memberCard.style.paddingTop = 8;
  291. memberCard.style.paddingBottom = 8;
  292. memberCard.style.paddingLeft = 8;
  293. memberCard.style.paddingRight = 8;
  294. // Member header with name and level
  295. var memberHeader = new VisualElement();
  296. memberHeader.style.flexDirection = FlexDirection.Row;
  297. memberHeader.style.justifyContent = Justify.SpaceBetween;
  298. memberHeader.style.alignItems = Align.Center;
  299. memberHeader.style.marginBottom = 5;
  300. var nameLabel = new Label(member.name);
  301. nameLabel.style.color = new StyleColor(new Color(1f, 1f, 1f));
  302. nameLabel.style.fontSize = 12;
  303. nameLabel.style.unityFontStyleAndWeight = FontStyle.Bold;
  304. var hpLabel = new Label($"HP: {member.HitPoints} | AC: {member.ArmorClass}");
  305. hpLabel.style.color = new StyleColor(new Color(0.8f, 0.8f, 1f));
  306. hpLabel.style.fontSize = 10;
  307. memberHeader.Add(nameLabel);
  308. memberHeader.Add(hpLabel);
  309. memberCard.Add(memberHeader);
  310. // Stats container
  311. var statsContainer = new VisualElement();
  312. statsContainer.style.flexDirection = FlexDirection.Row;
  313. statsContainer.style.flexWrap = Wrap.Wrap;
  314. statsContainer.style.justifyContent = Justify.SpaceBetween;
  315. // Add attribute stats in a compact layout
  316. AddCompactStatLabel(statsContainer, "STR", member.strength);
  317. AddCompactStatLabel(statsContainer, "DEX", member.dexterity);
  318. AddCompactStatLabel(statsContainer, "CON", member.constitution);
  319. AddCompactStatLabel(statsContainer, "WIS", member.wisdom);
  320. AddCompactStatLabel(statsContainer, "PER", member.perception);
  321. memberCard.Add(statsContainer);
  322. teamMembersList.Add(memberCard);
  323. }
  324. /// <summary>
  325. /// Adds a compact stat label to a container
  326. /// </summary>
  327. private void AddCompactStatLabel(VisualElement container, string statName, int statValue)
  328. {
  329. var statElement = new VisualElement();
  330. statElement.style.flexDirection = FlexDirection.Row;
  331. statElement.style.width = new StyleLength(new Length(18, LengthUnit.Percent));
  332. statElement.style.marginBottom = 1;
  333. var statLabel = new Label($"{statName}:");
  334. statLabel.style.color = new StyleColor(new Color(0.8f, 0.8f, 0.8f));
  335. statLabel.style.fontSize = 9;
  336. statLabel.style.width = new StyleLength(new Length(60, LengthUnit.Percent));
  337. var valueLabel = new Label(statValue.ToString());
  338. valueLabel.style.color = new StyleColor(new Color(1f, 1f, 1f));
  339. valueLabel.style.fontSize = 9;
  340. valueLabel.style.width = new StyleLength(new Length(40, LengthUnit.Percent));
  341. statElement.Add(statLabel);
  342. statElement.Add(valueLabel);
  343. container.Add(statElement);
  344. }
  345. /// <summary>
  346. /// Updates the team summary statistics
  347. /// </summary>
  348. private void UpdateTeamStats()
  349. {
  350. if (currentTeam == null) return;
  351. // Update member count
  352. if (memberCountLabel != null)
  353. {
  354. memberCountLabel.text = currentTeam.Count.ToString();
  355. }
  356. // Update total gold (assuming team shares resources)
  357. if (totalGoldLabel != null)
  358. {
  359. var totalGold = currentTeam.Sum(member => member.gold);
  360. totalGoldLabel.text = totalGold.ToString();
  361. }
  362. // Since TeamCharacter doesn't have level property, assume level 1 for all characters
  363. if (averageLevelLabel != null)
  364. {
  365. averageLevelLabel.text = "1";
  366. }
  367. }
  368. /// <summary>
  369. /// Handle manage team button click
  370. /// </summary>
  371. private void OnManageTeamClicked()
  372. {
  373. if (showDebugLogs)
  374. {
  375. Debug.Log("🔄 TeamOverviewController: Returning to Team Select scene");
  376. }
  377. // Load the Team Select scene
  378. var sceneManager = FindFirstObjectByType<SceneNavigationManager>();
  379. if (sceneManager != null)
  380. {
  381. sceneManager.GoToTeamSelect();
  382. }
  383. else
  384. {
  385. // Fallback to direct scene loading
  386. UnityEngine.SceneManagement.SceneManager.LoadScene("TeamSelect");
  387. }
  388. }
  389. /// <summary>
  390. /// Handle save game button click
  391. /// </summary>
  392. private void OnSaveGameClicked()
  393. {
  394. if (showDebugLogs)
  395. {
  396. Debug.Log("💾 TeamOverviewController: Saving game");
  397. }
  398. try
  399. {
  400. // Use GameStateManager to save current game state
  401. var gameStateManager = FindFirstObjectByType<GameStateManager>();
  402. if (gameStateManager != null)
  403. {
  404. gameStateManager.SaveGame();
  405. Debug.Log("✅ Game saved successfully!");
  406. }
  407. else
  408. {
  409. Debug.LogWarning("⚠️ GameStateManager not found!");
  410. }
  411. }
  412. catch (System.Exception e)
  413. {
  414. Debug.LogError($"❌ Failed to save game: {e.Message}");
  415. }
  416. }
  417. /// <summary>
  418. /// Handle perception visualization toggle change
  419. /// </summary>
  420. private void OnPerceptionVisualizationToggled(ChangeEvent<bool> evt)
  421. {
  422. bool newValue = evt.newValue;
  423. if (showDebugLogs)
  424. {
  425. Debug.Log($"👁️ TeamOverviewController: Perception visualization toggled to {newValue}");
  426. }
  427. // Save the setting
  428. PlayerPrefs.SetInt("ShowPerceptionVisualization", newValue ? 1 : 0);
  429. PlayerPrefs.Save();
  430. // Update the visualizer
  431. UpdatePerceptionVisualizationState(newValue);
  432. }
  433. /// <summary>
  434. /// Updates the perception visualization state
  435. /// </summary>
  436. private void UpdatePerceptionVisualizationState(bool enabled)
  437. {
  438. var visualizer = TeamPerceptionVisualizer.Instance;
  439. if (visualizer != null)
  440. {
  441. visualizer.SetPerceptionVisualizationEnabled(enabled);
  442. }
  443. else if (showDebugLogs)
  444. {
  445. Debug.LogWarning("⚠️ TeamPerceptionVisualizer instance not found");
  446. }
  447. }
  448. /// <summary>
  449. /// Refreshes the team data and display
  450. /// </summary>
  451. public void RefreshTeamData()
  452. {
  453. LoadTeamData();
  454. UpdateTeamDisplay();
  455. if (showDebugLogs)
  456. {
  457. Debug.Log("🔄 TeamOverviewController: Team data refreshed");
  458. }
  459. }
  460. /// <summary>
  461. /// Forces a reload of team data from all sources
  462. /// </summary>
  463. public void ForceReloadTeamData()
  464. {
  465. // Force GameStateManager to reload if possible
  466. if (GameStateManager.Instance != null && PlayerPrefs.HasKey("GameSaved"))
  467. {
  468. GameStateManager.Instance.LoadGame();
  469. }
  470. LoadTeamData();
  471. UpdateTeamDisplay();
  472. if (showDebugLogs)
  473. {
  474. Debug.Log("🔄 TeamOverviewController: Team data force reloaded");
  475. }
  476. }
  477. /// <summary>
  478. /// Context menu methods for debugging
  479. /// </summary>
  480. [ContextMenu("Show Team Overview")]
  481. public void TestShowTeamOverview()
  482. {
  483. ShowTeamOverview();
  484. }
  485. [ContextMenu("Hide Team Overview")]
  486. public void TestHideTeamOverview()
  487. {
  488. HideTeamOverview();
  489. }
  490. [ContextMenu("Refresh Team Data")]
  491. public void TestRefreshTeamData()
  492. {
  493. RefreshTeamData();
  494. }
  495. [ContextMenu("Force Reload Team Data")]
  496. public void TestForceReloadTeamData()
  497. {
  498. ForceReloadTeamData();
  499. }
  500. [ContextMenu("Debug Team Data Sources")]
  501. public void DebugTeamDataSources()
  502. {
  503. Debug.Log("=== TEAM DATA DEBUG ===");
  504. // Check MainTeamSelectScript
  505. var teamSelectScript = FindFirstObjectByType<MainTeamSelectScript>();
  506. Debug.Log($"MainTeamSelectScript found: {teamSelectScript != null}");
  507. if (teamSelectScript != null)
  508. {
  509. var characters = teamSelectScript.GetConfiguredCharacters();
  510. Debug.Log($"MainTeamSelectScript characters: {characters.Count}");
  511. }
  512. // Check GameStateManager
  513. Debug.Log($"GameStateManager.Instance: {GameStateManager.Instance != null}");
  514. if (GameStateManager.Instance != null)
  515. {
  516. Debug.Log($"GameStateManager.savedTeam: {GameStateManager.Instance.savedTeam != null}");
  517. if (GameStateManager.Instance.savedTeam != null)
  518. {
  519. int count = 0;
  520. foreach (var character in GameStateManager.Instance.savedTeam)
  521. {
  522. if (character != null) count++;
  523. }
  524. Debug.Log($"GameStateManager team count: {count}");
  525. }
  526. }
  527. // Check PlayerPrefs
  528. int playerPrefsCount = 0;
  529. for (int i = 0; i < 4; i++)
  530. {
  531. if (PlayerPrefs.HasKey($"Character{i}_Exists") && PlayerPrefs.GetInt($"Character{i}_Exists") == 1)
  532. {
  533. string name = PlayerPrefs.GetString($"Character{i}_Name", "");
  534. if (!string.IsNullOrEmpty(name))
  535. {
  536. playerPrefsCount++;
  537. Debug.Log($"PlayerPrefs Character {i}: {name}");
  538. }
  539. }
  540. }
  541. Debug.Log($"PlayerPrefs character count: {playerPrefsCount}");
  542. Debug.Log($"Current team loaded: {currentTeam?.Count ?? 0}");
  543. if (currentTeam != null)
  544. {
  545. foreach (var member in currentTeam)
  546. {
  547. Debug.Log($" - {member?.name ?? "null"} (STR:{member?.strength ?? 0}, DEX:{member?.dexterity ?? 0}, CON:{member?.constitution ?? 0}, WIS:{member?.wisdom ?? 0}, PER:{member?.perception ?? 0})");
  548. }
  549. }
  550. Debug.Log("=== END DEBUG ===");
  551. }
  552. [ContextMenu("Force Update Display")]
  553. public void ForceUpdateDisplay()
  554. {
  555. if (currentTeam != null && currentTeam.Count > 0)
  556. {
  557. Debug.Log($"🔄 Force updating display with {currentTeam.Count} team members");
  558. UpdateTeamDisplay();
  559. }
  560. else
  561. {
  562. Debug.Log("⚠️ No team data to display");
  563. }
  564. }
  565. // State
  566. private ActiveQuest selectedQuest;
  567. private bool isUIVisible = false;
  568. private List<VisualElement> questEntries = new List<VisualElement>();
  569. [System.NonSerialized]
  570. private bool recentlyHandledClick = false; // Flag to prevent map clicks when UI handles them
  571. void OnEnable() => ClickBlockingHelper.RegisterWithClickManager(this);
  572. void OnDisable() => ClickBlockingHelper.UnregisterWithClickManager(this);
  573. /// <summary>
  574. /// Sets a temporary flag to block travel system clicks when UI handles a click event.
  575. /// This is much more reliable than trying to calculate coordinates manually.
  576. /// </summary>
  577. private void SetClickFlag()
  578. {
  579. ClickBlockingHelper.SetClickFlag("TeamOverviewController", this, (flag) => recentlyHandledClick = flag);
  580. }
  581. public bool IsBlockingClick(Vector2 screenPosition)
  582. {
  583. // Primary method: Check if we recently handled a UI click
  584. if (recentlyHandledClick)
  585. {
  586. Debug.Log("🚫 TeamOverviewController: Blocking click due to recent UI interaction");
  587. return true;
  588. }
  589. // Dynamic coordinate-based approach: Block clicks in the quest tracker area
  590. // This needs to account for the expanded quest panel when it shows more options
  591. float teamOverviewPanelWidth = 320f; // Approximate width of quest panel
  592. float teamOverviewPanelHeight = 250f; // Larger height to cover expanded panel (was 120f)
  593. float teamOverviewPanelX = 20f; // Left edge
  594. float teamOverviewPanelY = Screen.height - teamOverviewPanelHeight - 20f; // Top edge (converted to screen coords)
  595. // Alternative: Try to get actual bounds from the quest tracker if available
  596. if (teamOverviewPanel != null)
  597. {
  598. try
  599. {
  600. // Try to use the actual UI element bounds if possible
  601. var bounds = teamOverviewPanel.worldBound;
  602. if (bounds.width > 0 && bounds.height > 0)
  603. {
  604. // Convert UI bounds to screen coordinates
  605. teamOverviewPanelX = bounds.x;
  606. teamOverviewPanelY = Screen.height - bounds.y - bounds.height;
  607. teamOverviewPanelWidth = bounds.width;
  608. teamOverviewPanelHeight = bounds.height;
  609. Debug.Log($"🔍 Using actual UI bounds: x={teamOverviewPanelX}, y={teamOverviewPanelY}, w={teamOverviewPanelWidth}, h={teamOverviewPanelHeight}");
  610. }
  611. }
  612. catch (System.Exception e)
  613. {
  614. Debug.LogWarning($"Failed to get UI bounds, using fallback: {e.Message}");
  615. }
  616. }
  617. bool inTeamOverviewArea = screenPosition.x >= teamOverviewPanelX &&
  618. screenPosition.x <= teamOverviewPanelX + teamOverviewPanelWidth &&
  619. screenPosition.y >= teamOverviewPanelY &&
  620. screenPosition.y <= teamOverviewPanelY + teamOverviewPanelHeight;
  621. if (inTeamOverviewArea)
  622. {
  623. Debug.Log($"🛡️ TeamOverviewController: Blocking click in team overview area at {screenPosition} (team overview area: {teamOverviewPanelX}-{teamOverviewPanelX + teamOverviewPanelWidth}, {teamOverviewPanelY}-{teamOverviewPanelY + teamOverviewPanelHeight})");
  624. return true;
  625. }
  626. // Don't block clicks outside the team overview area
  627. return false;
  628. }
  629. }