AdventurersGuildUI.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690
  1. using UnityEngine;
  2. using UnityEngine.UIElements;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. /// <summary>
  6. /// UI controller for the Adventurer's Guild interface
  7. /// </summary>
  8. public class AdventurersGuildUI : MonoBehaviour
  9. {
  10. [Header("UI References")]
  11. [SerializeField] private UIDocument uiDocument;
  12. [Header("Guild Reference")]
  13. [SerializeField] private AdventurersGuild guild;
  14. private VisualElement root;
  15. private VisualElement questBoardPanel;
  16. private VisualElement activeQuestsPanel;
  17. private VisualElement questHistoryPanel;
  18. private VisualElement questDetailsPanel;
  19. private ScrollView questBoardList;
  20. private ScrollView activeQuestsList;
  21. private ScrollView questHistoryList;
  22. private Button questBoardTab;
  23. private Button activeQuestsTab;
  24. private Button questHistoryTab;
  25. private Label renownLabel;
  26. private Label questCountLabel;
  27. private Label historyStatsLabel;
  28. private Quest selectedQuest;
  29. private ActiveQuest selectedActiveQuest;
  30. private void Start()
  31. {
  32. InitializeUI();
  33. SetupEventListeners();
  34. ShowQuestBoard();
  35. }
  36. private void OnEnable()
  37. {
  38. if (QuestManager.Instance != null)
  39. {
  40. QuestManager.Instance.OnQuestAccepted += OnQuestAccepted;
  41. QuestManager.Instance.OnQuestCompleted += OnQuestCompleted;
  42. QuestManager.Instance.OnQuestFailed += OnQuestFailed;
  43. QuestManager.Instance.OnRenownChanged += OnRenownChanged;
  44. }
  45. }
  46. private void OnDisable()
  47. {
  48. if (QuestManager.Instance != null)
  49. {
  50. QuestManager.Instance.OnQuestAccepted -= OnQuestAccepted;
  51. QuestManager.Instance.OnQuestCompleted -= OnQuestCompleted;
  52. QuestManager.Instance.OnQuestFailed -= OnQuestFailed;
  53. QuestManager.Instance.OnRenownChanged -= OnRenownChanged;
  54. }
  55. }
  56. private void InitializeUI()
  57. {
  58. if (uiDocument == null)
  59. uiDocument = GetComponent<UIDocument>();
  60. root = uiDocument.rootVisualElement;
  61. // Get panel references
  62. questBoardPanel = root.Q("QuestBoardPanel");
  63. activeQuestsPanel = root.Q("ActiveQuestsPanel");
  64. questHistoryPanel = root.Q("QuestHistoryPanel");
  65. questDetailsPanel = root.Q("QuestDetailsPanel");
  66. // Get list references
  67. questBoardList = root.Q<ScrollView>("QuestBoardList");
  68. activeQuestsList = root.Q<ScrollView>("ActiveQuestsList");
  69. questHistoryList = root.Q<ScrollView>("QuestHistoryList");
  70. // Get tab references
  71. questBoardTab = root.Q<Button>("QuestBoardTab");
  72. activeQuestsTab = root.Q<Button>("ActiveQuestsTab");
  73. questHistoryTab = root.Q<Button>("QuestHistoryTab");
  74. // Get label references
  75. renownLabel = root.Q<Label>("RenownLabel");
  76. questCountLabel = root.Q<Label>("QuestCountLabel");
  77. historyStatsLabel = root.Q<Label>("HistoryStatsLabel");
  78. // Find guild if not assigned
  79. if (guild == null)
  80. guild = FindFirstObjectByType<AdventurersGuild>();
  81. UpdateRenownDisplay();
  82. }
  83. private void SetupEventListeners()
  84. {
  85. // Tab navigation
  86. questBoardTab?.RegisterCallback<ClickEvent>(evt => ShowTab("QuestBoard"));
  87. activeQuestsTab?.RegisterCallback<ClickEvent>(evt => ShowTab("ActiveQuests"));
  88. questHistoryTab?.RegisterCallback<ClickEvent>(evt => ShowTab("QuestHistory"));
  89. // Close button
  90. var closeButton = root.Q<Button>("CloseButton");
  91. closeButton?.RegisterCallback<ClickEvent>(evt => CloseGuild());
  92. // Action buttons
  93. var refreshButton = root.Q<Button>("RefreshBoardButton");
  94. refreshButton?.RegisterCallback<ClickEvent>(evt =>
  95. {
  96. // Refresh the guild board first, then the UI
  97. if (guild != null)
  98. {
  99. guild.RefreshQuestBoard();
  100. }
  101. RefreshQuestBoard();
  102. });
  103. var acceptButton = root.Q<Button>("AcceptQuestButton");
  104. acceptButton?.RegisterCallback<ClickEvent>(evt => AcceptSelectedQuest());
  105. var abandonButton = root.Q<Button>("AbandonQuestButton");
  106. abandonButton?.RegisterCallback<ClickEvent>(evt => AbandonSelectedQuest());
  107. }
  108. private void ShowTab(string tabName)
  109. {
  110. // Hide all panels
  111. questBoardPanel.AddToClassList("hidden");
  112. activeQuestsPanel.AddToClassList("hidden");
  113. questHistoryPanel.AddToClassList("hidden");
  114. // Remove active class from all tabs
  115. questBoardTab.RemoveFromClassList("active-tab");
  116. activeQuestsTab.RemoveFromClassList("active-tab");
  117. questHistoryTab.RemoveFromClassList("active-tab");
  118. // Show selected panel and mark tab as active
  119. switch (tabName)
  120. {
  121. case "QuestBoard":
  122. questBoardPanel.RemoveFromClassList("hidden");
  123. questBoardTab.AddToClassList("active-tab");
  124. RefreshQuestBoard();
  125. break;
  126. case "ActiveQuests":
  127. activeQuestsPanel.RemoveFromClassList("hidden");
  128. activeQuestsTab.AddToClassList("active-tab");
  129. RefreshActiveQuests();
  130. break;
  131. case "QuestHistory":
  132. questHistoryPanel.RemoveFromClassList("hidden");
  133. questHistoryTab.AddToClassList("active-tab");
  134. RefreshQuestHistory();
  135. break;
  136. }
  137. CloseQuestDetails();
  138. }
  139. private void RefreshQuestBoard()
  140. {
  141. if (guild == null || questBoardList == null) return;
  142. questBoardList.Clear();
  143. var questBoard = guild.GetQuestBoard();
  144. if (questBoard.Count == 0)
  145. {
  146. // Try to refresh the board first
  147. guild.RefreshQuestBoard();
  148. questBoard = guild.GetQuestBoard();
  149. if (questBoard.Count == 0)
  150. {
  151. var placeholder = new Label("No quests available. Check back later!");
  152. placeholder.AddToClassList("placeholder-text");
  153. questBoardList.Add(placeholder);
  154. // Add a button to create a test quest for debugging
  155. var debugButton = new Button(() => CreateDebugQuest()) { text = "🔧 Create Test Quest (Debug)" };
  156. debugButton.AddToClassList("debug-button");
  157. questBoardList.Add(debugButton);
  158. return;
  159. }
  160. }
  161. // Add helpful instructions at the top
  162. if (questBoard.Count > 0)
  163. {
  164. var instructions = new Label("💡 Click on any quest below to view details and accept it!");
  165. instructions.AddToClassList("instructions-text");
  166. questBoardList.Add(instructions);
  167. }
  168. foreach (var quest in questBoard)
  169. {
  170. var questEntry = CreateQuestEntry(quest);
  171. questBoardList.Add(questEntry);
  172. }
  173. } private void CreateDebugQuest()
  174. {
  175. if (guild == null) return;
  176. var debugQuest = ScriptableObject.CreateInstance<Quest>();
  177. debugQuest.questTitle = "Test Quest - Goblin Patrol";
  178. debugQuest.questDescription = "A group of goblins has been spotted near the village. Clear them out to protect the trade routes.";
  179. debugQuest.questType = QuestType.Combat;
  180. debugQuest.difficulty = QuestDifficulty.Easy;
  181. debugQuest.timeLimitDays = 7;
  182. debugQuest.targetAreaName = "Forest Edge";
  183. debugQuest.targetMapPosition = new Vector2Int(45, 55);
  184. debugQuest.goldReward = 75;
  185. debugQuest.renownReward = 10;
  186. debugQuest.minimumRenown = 0; // No requirements for testing
  187. debugQuest.goals.Add(new QuestGoal
  188. {
  189. description = "Defeat 5 Goblins",
  190. goalType = QuestGoalType.KillEnemies,
  191. targetName = "Goblin",
  192. targetCount = 5
  193. });
  194. // Add to guild's available quests and refresh
  195. var availableQuests = new System.Collections.Generic.List<Quest>();
  196. var currentBoard = guild.GetQuestBoard();
  197. availableQuests.AddRange(currentBoard);
  198. availableQuests.Add(debugQuest);
  199. // Use reflection or a public method to add the quest
  200. // For now, just force it into the board via the guild's debug method
  201. Debug.Log("✅ Created debug quest. Use the guild's 'Create Simple Test Quest' context menu to add it properly.");
  202. // Refresh the UI
  203. RefreshQuestBoard();
  204. }
  205. private void RefreshActiveQuests()
  206. {
  207. if (QuestManager.Instance == null || activeQuestsList == null) return;
  208. activeQuestsList.Clear();
  209. var activeQuests = QuestManager.Instance.GetActiveQuests();
  210. questCountLabel.text = $"{activeQuests.Count}/{QuestManager.Instance.maxActiveQuests} Quests";
  211. if (activeQuests.Count == 0)
  212. {
  213. var placeholder = new Label("No active quests.");
  214. placeholder.AddToClassList("placeholder-text");
  215. activeQuestsList.Add(placeholder);
  216. return;
  217. }
  218. foreach (var activeQuest in activeQuests)
  219. {
  220. var questEntry = CreateActiveQuestEntry(activeQuest);
  221. activeQuestsList.Add(questEntry);
  222. }
  223. }
  224. private void RefreshQuestHistory()
  225. {
  226. // TODO: Implement quest history display
  227. questHistoryList.Clear();
  228. var placeholder = new Label("Quest history not yet implemented.");
  229. placeholder.AddToClassList("placeholder-text");
  230. questHistoryList.Add(placeholder);
  231. historyStatsLabel.text = "Completed: 0 | Failed: 0";
  232. }
  233. private VisualElement CreateQuestEntry(Quest quest)
  234. {
  235. var entry = new VisualElement();
  236. entry.AddToClassList("quest-list-item");
  237. entry.AddToClassList("clickable-quest"); // New class for better styling
  238. // Add a hover effect to make it clear it's clickable
  239. entry.RegisterCallback<MouseEnterEvent>(evt => entry.AddToClassList("quest-hover"));
  240. entry.RegisterCallback<MouseLeaveEvent>(evt => entry.RemoveFromClassList("quest-hover"));
  241. // Header with title and difficulty badge
  242. var header = new VisualElement();
  243. header.AddToClassList("quest-item-header");
  244. var titleContainer = new VisualElement();
  245. titleContainer.AddToClassList("quest-title-container");
  246. var title = new Label(quest.questTitle);
  247. title.AddToClassList("quest-item-title");
  248. var clickHint = new Label("📋 Click to view details");
  249. clickHint.AddToClassList("quest-click-hint");
  250. titleContainer.Add(title);
  251. titleContainer.Add(clickHint);
  252. var difficulty = new Label(quest.difficulty.ToString().ToUpper());
  253. difficulty.AddToClassList("quest-item-difficulty");
  254. difficulty.AddToClassList($"difficulty-{quest.difficulty.ToString().ToLower()}");
  255. header.Add(titleContainer);
  256. header.Add(difficulty);
  257. // Description (truncated)
  258. var description = new Label(TruncateText(quest.questDescription, 100));
  259. description.AddToClassList("quest-item-description");
  260. // Key info row
  261. var infoRow = new VisualElement();
  262. infoRow.AddToClassList("quest-info-row");
  263. var location = new Label($"📍 {quest.targetAreaName}");
  264. location.AddToClassList("quest-info-item");
  265. var timeLimit = new Label($"⏰ {quest.timeLimitDays}d {quest.timeLimitHours}h");
  266. timeLimit.AddToClassList("quest-info-item");
  267. infoRow.Add(location);
  268. infoRow.Add(timeLimit);
  269. // Rewards container - made more prominent
  270. var rewardsContainer = new VisualElement();
  271. rewardsContainer.AddToClassList("quest-item-rewards");
  272. var rewardsLabel = new Label("Rewards:");
  273. rewardsLabel.AddToClassList("rewards-label");
  274. rewardsContainer.Add(rewardsLabel);
  275. var rewardsContent = new VisualElement();
  276. rewardsContent.AddToClassList("rewards-content");
  277. if (quest.goldReward > 0)
  278. {
  279. var goldReward = new Label($"💰 {quest.goldReward} Gold");
  280. goldReward.AddToClassList("quest-item-reward");
  281. goldReward.AddToClassList("reward-gold");
  282. rewardsContent.Add(goldReward);
  283. }
  284. if (quest.renownReward > 0)
  285. {
  286. var renownReward = new Label($"⭐ +{quest.renownReward} Renown");
  287. renownReward.AddToClassList("quest-item-reward");
  288. renownReward.AddToClassList("reward-renown");
  289. rewardsContent.Add(renownReward);
  290. }
  291. rewardsContainer.Add(rewardsContent);
  292. // Requirements
  293. if (quest.minimumRenown > 0)
  294. {
  295. var requirements = new Label($"⚡ Requires {quest.minimumRenown} Renown");
  296. requirements.AddToClassList("quest-requirements");
  297. rewardsContainer.Add(requirements);
  298. }
  299. // Assemble the entry
  300. entry.Add(header);
  301. entry.Add(description);
  302. entry.Add(infoRow);
  303. entry.Add(rewardsContainer);
  304. // Click handler to select quest and show details
  305. entry.RegisterCallback<ClickEvent>(evt =>
  306. {
  307. // Remove selection from all quest items
  308. foreach (var child in questBoardList.Children())
  309. {
  310. child.RemoveFromClassList("selected");
  311. }
  312. // Select this item
  313. entry.AddToClassList("selected");
  314. ShowQuestDetails(quest);
  315. });
  316. return entry;
  317. }
  318. private string TruncateText(string text, int maxLength)
  319. {
  320. if (string.IsNullOrEmpty(text) || text.Length <= maxLength)
  321. return text;
  322. return text.Substring(0, maxLength - 3) + "...";
  323. }
  324. private VisualElement CreateActiveQuestEntry(ActiveQuest activeQuest)
  325. {
  326. var entry = CreateQuestEntry(activeQuest.questData);
  327. // Add urgency indicator
  328. var urgency = activeQuest.GetUrgency();
  329. entry.AddToClassList($"urgency-{urgency.ToString().ToLower()}");
  330. // Update time display to show remaining time
  331. var timeLabel = entry.Q<Label>(className: "quest-entry-time");
  332. if (timeLabel != null)
  333. {
  334. timeLabel.text = $"⏰ {activeQuest.GetTimeRemainingString()}";
  335. }
  336. // Add progress info
  337. var progressLabel = new Label($"Progress: {activeQuest.GetOverallProgress() * 100:F0}%");
  338. progressLabel.style.color = Color.cyan;
  339. progressLabel.style.fontSize = 12;
  340. entry.Add(progressLabel);
  341. // Click handler for active quest
  342. entry.RegisterCallback<ClickEvent>(evt => ShowActiveQuestDetails(activeQuest));
  343. return entry;
  344. }
  345. private void ShowQuestDetails(Quest quest)
  346. {
  347. selectedQuest = quest;
  348. selectedActiveQuest = null;
  349. // Show quest info container and hide placeholder
  350. var questInfoContainer = root.Q("QuestInfoContainer");
  351. var placeholder = root.Q("QuestDetailsText");
  352. questInfoContainer?.RemoveFromClassList("hidden");
  353. placeholder?.AddToClassList("hidden");
  354. // Populate the details with null checks
  355. try
  356. {
  357. PopulateQuestDetails(quest);
  358. }
  359. catch (System.Exception ex)
  360. {
  361. Debug.LogError($"Error populating quest details: {ex.Message}");
  362. // Fallback - show basic info
  363. var title = root.Q<Label>("QuestTitle");
  364. if (title != null) title.text = quest?.questTitle ?? "Unknown Quest";
  365. var description = root.Q<Label>("QuestDescription");
  366. if (description != null) description.text = quest?.questDescription ?? "Quest details unavailable.";
  367. }
  368. // Show/hide appropriate buttons
  369. var acceptButton = root.Q<Button>("AcceptQuestButton");
  370. var abandonButton = root.Q<Button>("AbandonQuestButton");
  371. if (acceptButton != null)
  372. {
  373. acceptButton.RemoveFromClassList("hidden");
  374. acceptButton.AddToClassList("accept-button");
  375. acceptButton.AddToClassList("action-button");
  376. }
  377. if (abandonButton != null)
  378. {
  379. abandonButton.AddToClassList("hidden");
  380. }
  381. }
  382. private void CloseGuild()
  383. {
  384. // Destroy the guild UI GameObject
  385. if (gameObject != null)
  386. {
  387. Destroy(gameObject);
  388. }
  389. }
  390. private void ShowActiveQuestDetails(ActiveQuest activeQuest)
  391. {
  392. selectedQuest = null;
  393. selectedActiveQuest = activeQuest;
  394. questDetailsPanel.RemoveFromClassList("hidden");
  395. PopulateQuestDetails(activeQuest.questData, activeQuest);
  396. // Show/hide appropriate buttons
  397. root.Q<Button>("AcceptQuestButton").AddToClassList("hidden");
  398. root.Q<Button>("AbandonQuestButton").RemoveFromClassList("hidden");
  399. root.Q<Button>("TrackQuestButton").RemoveFromClassList("hidden");
  400. }
  401. private void PopulateQuestDetails(Quest quest, ActiveQuest activeQuest = null)
  402. {
  403. if (quest == null) return;
  404. // Basic info - with null checks
  405. var questTitle = root.Q<Label>("QuestTitle");
  406. if (questTitle != null) questTitle.text = quest.questTitle;
  407. var questDifficulty = root.Q<Label>("QuestDifficulty");
  408. if (questDifficulty != null) questDifficulty.text = $"Difficulty: {quest.difficulty}";
  409. var questTimeLimit = root.Q<Label>("QuestTimeLimit");
  410. if (questTimeLimit != null)
  411. {
  412. if (activeQuest != null)
  413. {
  414. questTimeLimit.text = $"Time Remaining: {activeQuest.GetTimeRemainingString()}";
  415. }
  416. else
  417. {
  418. questTimeLimit.text = $"Time Limit: {quest.timeLimitDays}d {quest.timeLimitHours}h";
  419. }
  420. }
  421. // Description
  422. var questDescription = root.Q<Label>("QuestDescription");
  423. if (questDescription != null) questDescription.text = quest.questDescription;
  424. // Objectives
  425. var objectivesList = root.Q("ObjectivesList");
  426. if (objectivesList != null)
  427. {
  428. objectivesList.Clear();
  429. var goalsToShow = activeQuest?.activeGoals ?? quest.goals;
  430. foreach (var goal in goalsToShow)
  431. {
  432. if (goal.isHidden && activeQuest == null) continue;
  433. var objectiveItem = new VisualElement();
  434. objectiveItem.AddToClassList("objective-item");
  435. var status = new VisualElement();
  436. status.AddToClassList("objective-status");
  437. if (goal.IsCompleted)
  438. status.AddToClassList("objective-completed");
  439. var text = new Label(goal.description);
  440. text.AddToClassList("objective-text");
  441. if (activeQuest != null)
  442. {
  443. text.text += $" ({goal.currentProgress}/{goal.targetCount})";
  444. }
  445. objectiveItem.Add(status);
  446. objectiveItem.Add(text);
  447. objectivesList.Add(objectiveItem);
  448. }
  449. }
  450. // Location
  451. var questLocation = root.Q<Label>("QuestLocation");
  452. if (questLocation != null) questLocation.text = $"Target Area: {quest.targetAreaName}";
  453. // Calculate travel time if we have current position
  454. var travelTime = quest.CalculateTravelTime(new Vector2Int(50, 50)); // Placeholder position
  455. var travelTimeLabel = root.Q<Label>("TravelTime");
  456. if (travelTimeLabel != null) travelTimeLabel.text = $"Travel Time: ~{travelTime:F1} hours";
  457. // Rewards
  458. var goldReward = root.Q<Label>("GoldReward");
  459. if (goldReward != null) goldReward.text = $"💰 Gold: {quest.goldReward}";
  460. var renownReward = root.Q<Label>("RenownReward");
  461. if (renownReward != null) renownReward.text = $"⭐ Renown: +{quest.renownReward}";
  462. var itemRewardsList = root.Q("ItemRewardsList");
  463. if (itemRewardsList != null)
  464. {
  465. itemRewardsList.Clear();
  466. foreach (var itemName in quest.itemRewards)
  467. {
  468. var itemLabel = new Label($"🎁 {itemName}");
  469. itemLabel.AddToClassList("reward-item");
  470. itemRewardsList.Add(itemLabel);
  471. }
  472. }
  473. }
  474. private void CloseQuestDetails()
  475. {
  476. questDetailsPanel.AddToClassList("hidden");
  477. selectedQuest = null;
  478. selectedActiveQuest = null;
  479. }
  480. private void AcceptSelectedQuest()
  481. {
  482. if (selectedQuest == null || guild == null) return;
  483. bool accepted = guild.AcceptQuest(selectedQuest);
  484. if (accepted)
  485. {
  486. CloseQuestDetails();
  487. RefreshQuestBoard();
  488. ShowTab("ActiveQuests");
  489. }
  490. }
  491. private void AbandonSelectedQuest()
  492. {
  493. if (selectedActiveQuest == null || QuestManager.Instance == null) return;
  494. bool abandoned = QuestManager.Instance.AbandonQuest(selectedActiveQuest.questId);
  495. if (abandoned)
  496. {
  497. CloseQuestDetails();
  498. RefreshActiveQuests();
  499. }
  500. }
  501. private void TrackSelectedQuest()
  502. {
  503. if (selectedActiveQuest == null) return;
  504. // TODO: Implement quest tracking on map
  505. Debug.Log($"Tracking quest: {selectedActiveQuest.questData.questTitle}");
  506. CloseQuestDetails();
  507. }
  508. private void UpdateRenownDisplay()
  509. {
  510. if (renownLabel != null && QuestManager.Instance != null)
  511. {
  512. renownLabel.text = $"Renown: {QuestManager.Instance.GetRenown()}";
  513. }
  514. }
  515. private void ShowQuestBoard()
  516. {
  517. ShowTab("QuestBoard");
  518. }
  519. // Event handlers
  520. private void OnQuestAccepted(ActiveQuest quest)
  521. {
  522. RefreshQuestBoard();
  523. RefreshActiveQuests();
  524. }
  525. private void OnQuestCompleted(ActiveQuest quest, List<QuestReward> rewards)
  526. {
  527. RefreshActiveQuests();
  528. RefreshQuestHistory();
  529. }
  530. private void OnQuestFailed(ActiveQuest quest)
  531. {
  532. RefreshActiveQuests();
  533. RefreshQuestHistory();
  534. }
  535. private void OnRenownChanged(int newRenown)
  536. {
  537. UpdateRenownDisplay();
  538. }
  539. // Debug methods
  540. [ContextMenu("Force Refresh UI")]
  541. private void DebugForceRefreshUI()
  542. {
  543. if (guild != null)
  544. {
  545. guild.RefreshQuestBoard();
  546. }
  547. RefreshQuestBoard();
  548. RefreshActiveQuests();
  549. RefreshQuestHistory();
  550. Debug.Log("🔄 Forced UI refresh complete");
  551. }
  552. [ContextMenu("Debug Guild Connection")]
  553. private void DebugGuildConnection()
  554. {
  555. Debug.Log($"Guild reference: {(guild != null ? "✅ Found" : "❌ NULL")}");
  556. Debug.Log($"QuestManager: {(QuestManager.Instance != null ? "✅ Found" : "❌ NULL")}");
  557. if (guild != null)
  558. {
  559. var questBoard = guild.GetQuestBoard();
  560. Debug.Log($"Quest Board: {questBoard.Count} quests");
  561. }
  562. }
  563. }