/trunk/src/Deployment/WoWBench/BlizzardInterface/FrameXML/QuestLogFrame.lua

# · Lua · 787 lines · 663 code · 77 blank · 47 comment · 164 complexity · 7eb59ce49aff29d8b99df0bfaa8497a7 MD5 · raw file

  1. QUESTS_DISPLAYED = 6;
  2. MAX_QUESTS = 20;
  3. MAX_OBJECTIVES = 10;
  4. QUESTLOG_QUEST_HEIGHT = 16;
  5. UPDATE_DELAY = 0.1;
  6. MAX_QUESTLOG_QUESTS = 20;
  7. MAX_QUESTWATCH_LINES = 30;
  8. MAX_WATCHABLE_QUESTS = 5;
  9. MAX_NUM_PARTY_MEMBERS = 4;
  10. MAX_QUEST_WATCH_TIMER = 300;
  11. QUEST_WATCH_NO_EXPIRE = -1;
  12. QUEST_WATCH_LIST = { };
  13. QuestDifficultyColor = { };
  14. QuestDifficultyColor["impossible"] = { r = 1.00, g = 0.10, b = 0.10 };
  15. QuestDifficultyColor["verydifficult"] = { r = 1.00, g = 0.50, b = 0.25 };
  16. QuestDifficultyColor["difficult"] = { r = 1.00, g = 1.00, b = 0.00 };
  17. QuestDifficultyColor["standard"] = { r = 0.25, g = 0.75, b = 0.25 };
  18. QuestDifficultyColor["trivial"] = { r = 0.50, g = 0.50, b = 0.50 };
  19. QuestDifficultyColor["header"] = { r = 0.7, g = 0.7, b = 0.7 };
  20. function ToggleQuestLog()
  21. if ( QuestLogFrame:IsVisible() ) then
  22. HideUIPanel(QuestLogFrame);
  23. else
  24. ShowUIPanel(QuestLogFrame);
  25. end
  26. end
  27. function QuestLogTitleButton_OnLoad()
  28. this:RegisterForClicks("LeftButtonUp", "RightButtonUp");
  29. this:RegisterEvent("UNIT_QUEST_LOG_CHANGED");
  30. this:RegisterEvent("PARTY_MEMBER_ENABLE");
  31. this:RegisterEvent("PARTY_MEMBER_DISABLE");
  32. end
  33. function QuestLogTitleButton_OnEvent(event)
  34. if ( GameTooltip:IsOwned(this) ) then
  35. GameTooltip:Hide();
  36. QuestLog_UpdatePartyInfoTooltip();
  37. end
  38. end
  39. function QuestLog_OnLoad()
  40. this.selectedButtonID = 2;
  41. this:RegisterEvent("QUEST_LOG_UPDATE");
  42. this:RegisterEvent("QUEST_WATCH_UPDATE");
  43. this:RegisterEvent("UPDATE_FACTION");
  44. this:RegisterEvent("UNIT_QUEST_LOG_CHANGED");
  45. this:RegisterEvent("PARTY_MEMBERS_CHANGED");
  46. this:RegisterEvent("PARTY_MEMBER_ENABLE");
  47. this:RegisterEvent("PARTY_MEMBER_DISABLE");
  48. end
  49. function QuestLog_OnEvent(event)
  50. if ( event == "QUEST_LOG_UPDATE" or event == "UPDATE_FACTION" or (event == "UNIT_QUEST_LOG_CHANGED" and arg1 == "player") ) then
  51. QuestLog_Update();
  52. QuestWatch_Update();
  53. if ( QuestLogFrame:IsVisible() ) then
  54. QuestLog_UpdateQuestDetails(1);
  55. end
  56. if ( AUTO_QUEST_WATCH == "1" ) then
  57. AutoQuestWatch_CheckDeleted();
  58. end
  59. elseif ( event == "QUEST_WATCH_UPDATE" ) then
  60. if ( AUTO_QUEST_WATCH == "1" ) then
  61. AutoQuestWatch_Update(arg1);
  62. end
  63. else
  64. QuestLog_Update();
  65. if ( event == "PARTY_MEMBERS_CHANGED" ) then
  66. -- Determine whether the selected quest is pushable or not
  67. if ( GetQuestLogPushable() and GetNumPartyMembers() > 0 ) then
  68. QuestFramePushQuestButton:Enable();
  69. else
  70. QuestFramePushQuestButton:Disable();
  71. end
  72. end
  73. end
  74. end
  75. function QuestLog_OnShow()
  76. UpdateMicroButtons();
  77. PlaySound("igQuestLogOpen");
  78. QuestLog_SetSelection(GetQuestLogSelection());
  79. QuestLog_Update();
  80. end
  81. function QuestLog_OnHide()
  82. UpdateMicroButtons();
  83. PlaySound("igQuestLogClose");
  84. end
  85. function QuestLog_OnUpdate(elapsed)
  86. if ( QuestLogFrame.hasTimer ) then
  87. QuestLogFrame.timePassed = QuestLogFrame.timePassed + elapsed;
  88. if ( QuestLogFrame.timePassed > UPDATE_DELAY ) then
  89. QuestLogTimerText:SetText(TEXT(TIME_REMAINING).." "..SecondsToTime(GetQuestLogTimeLeft()));
  90. QuestLogFrame.timePassed = 0;
  91. end
  92. end
  93. end
  94. function QuestLog_Update()
  95. local numEntries, numQuests = GetNumQuestLogEntries();
  96. if ( numEntries == 0 ) then
  97. EmptyQuestLogFrame:Show();
  98. QuestLogFrameAbandonButton:Disable();
  99. QuestLogFrame.hasTimer = nil;
  100. QuestLogDetailScrollFrame:Hide();
  101. QuestLogExpandButtonFrame:Hide();
  102. else
  103. EmptyQuestLogFrame:Hide();
  104. QuestLogFrameAbandonButton:Enable();
  105. QuestLogDetailScrollFrame:Show();
  106. QuestLogExpandButtonFrame:Show();
  107. end
  108. -- Update Quest Count
  109. QuestLogQuestCount:SetText(format(QUEST_LOG_COUNT_TEMPLATE, numQuests, MAX_QUESTLOG_QUESTS));
  110. QuestLogCountMiddle:SetWidth(QuestLogQuestCount:GetWidth());
  111. -- ScrollFrame update
  112. FauxScrollFrame_Update(QuestLogListScrollFrame, numEntries, QUESTS_DISPLAYED, QUESTLOG_QUEST_HEIGHT, nil, nil, nil, QuestLogHighlightFrame, 293, 316 )
  113. -- Update the quest listing
  114. QuestLogHighlightFrame:Hide();
  115. local questIndex, questLogTitle, questTitleTag, questNumGroupMates, questNormalText, questHighlight, questCheck;
  116. local questLogTitleText, level, questTag, isHeader, isCollapsed, isComplete, color;
  117. local numPartyMembers, partyMembersOnQuest, tempWidth, textWidth;
  118. for i=1, QUESTS_DISPLAYED, 1 do
  119. questIndex = i + FauxScrollFrame_GetOffset(QuestLogListScrollFrame);
  120. questLogTitle = getglobal("QuestLogTitle"..i);
  121. questTitleTag = getglobal("QuestLogTitle"..i.."Tag");
  122. questNumGroupMates = getglobal("QuestLogTitle"..i.."GroupMates");
  123. questCheck = getglobal("QuestLogTitle"..i.."Check");
  124. questNormalText = getglobal("QuestLogTitle"..i.."NormalText");
  125. questHighlight = getglobal("QuestLogTitle"..i.."Highlight");
  126. if ( questIndex <= numEntries ) then
  127. questLogTitleText, level, questTag, isHeader, isCollapsed, isComplete = GetQuestLogTitle(questIndex);
  128. if ( isHeader ) then
  129. if ( questLogTitleText ) then
  130. questLogTitle:SetText(questLogTitleText);
  131. else
  132. questLogTitle:SetText("");
  133. end
  134. if ( isCollapsed ) then
  135. questLogTitle:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up");
  136. else
  137. questLogTitle:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-Up");
  138. end
  139. questHighlight:SetTexture("Interface\\Buttons\\UI-PlusButton-Hilight");
  140. questNumGroupMates:SetText("");
  141. questCheck:Hide();
  142. else
  143. questLogTitle:SetText(" "..questLogTitleText);
  144. --Set Dummy text to get text width *SUPER HACK*
  145. QuestLogDummyText:SetText(" "..questLogTitleText);
  146. questLogTitle:SetNormalTexture("");
  147. questHighlight:SetTexture("");
  148. -- If not a header see if any nearby group mates are on this quest
  149. numPartyMembers = GetNumPartyMembers();
  150. if ( numPartyMembers == 0 ) then
  151. --return;
  152. end
  153. partyMembersOnQuest = 0;
  154. for j=1, numPartyMembers do
  155. if ( IsUnitOnQuest(questIndex, "party"..j) ) then
  156. partyMembersOnQuest = partyMembersOnQuest + 1;
  157. end
  158. end
  159. if ( partyMembersOnQuest > 0 ) then
  160. questNumGroupMates:SetText("["..partyMembersOnQuest.."]");
  161. else
  162. questNumGroupMates:SetText("");
  163. end
  164. end
  165. -- Save if its a header or not
  166. questLogTitle.isHeader = isHeader;
  167. -- Set the quest tag
  168. if ( isComplete and isComplete < 0 ) then
  169. questTag = FAILED;
  170. elseif ( isComplete and isComplete > 0 ) then
  171. questTag = COMPLETE;
  172. end
  173. if ( questTag ) then
  174. questTitleTag:SetText("("..questTag..")");
  175. -- Shrink text to accomdate quest tags without wrapping
  176. tempWidth = 275 - 15 - questTitleTag:GetWidth();
  177. if ( QuestLogDummyText:GetWidth() > tempWidth ) then
  178. textWidth = tempWidth;
  179. else
  180. textWidth = QuestLogDummyText:GetWidth();
  181. end
  182. questNormalText:SetWidth(tempWidth);
  183. -- If there's quest tag position check accordingly
  184. questCheck:Hide();
  185. if ( IsQuestWatched(questIndex) ) then
  186. if ( questNormalText:GetWidth() + 24 < 275 ) then
  187. questCheck:SetPoint("LEFT", questLogTitle, "LEFT", textWidth+24, 0);
  188. else
  189. questCheck:SetPoint("LEFT", questLogTitle, "LEFT", textWidth+10, 0);
  190. end
  191. questCheck:Show();
  192. end
  193. else
  194. questTitleTag:SetText("");
  195. -- Reset to max text width
  196. if ( questNormalText:GetWidth() > 275 ) then
  197. questNormalText:SetWidth(260);
  198. end
  199. -- Show check if quest is being watched
  200. questCheck:Hide();
  201. if ( IsQuestWatched(questIndex) ) then
  202. if ( questNormalText:GetWidth() + 24 < 275 ) then
  203. questCheck:SetPoint("LEFT", questLogTitle, "LEFT", QuestLogDummyText:GetWidth()+24, 0);
  204. else
  205. questCheck:SetPoint("LEFT", questNormalText, "LEFT", questNormalText:GetWidth(), 0);
  206. end
  207. questCheck:Show();
  208. end
  209. end
  210. -- Color the quest title and highlight according to the difficulty level
  211. local playerLevel = UnitLevel("player");
  212. if ( isHeader ) then
  213. color = QuestDifficultyColor["header"];
  214. else
  215. color = GetDifficultyColor(level);
  216. end
  217. questTitleTag:SetTextColor(color.r, color.g, color.b);
  218. questLogTitle:SetTextColor(color.r, color.g, color.b);
  219. questNumGroupMates:SetTextColor(color.r, color.g, color.b);
  220. questLogTitle.r = color.r;
  221. questLogTitle.g = color.g;
  222. questLogTitle.b = color.b;
  223. questLogTitle:Show();
  224. -- Place the highlight and lock the highlight state
  225. if ( QuestLogFrame.selectedButtonID and GetQuestLogSelection() == questIndex ) then
  226. QuestLogHighlightFrame:SetPoint("TOPLEFT", "QuestLogTitle"..i, "TOPLEFT", 0, 0);
  227. QuestLogHighlightFrame:Show();
  228. questTitleTag:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
  229. questLogTitle:LockHighlight();
  230. else
  231. questLogTitle:UnlockHighlight();
  232. end
  233. else
  234. questLogTitle:Hide();
  235. end
  236. end
  237. -- Set the expand/collapse all button texture
  238. local numHeaders = 0;
  239. local notExpanded = 0;
  240. -- Somewhat redundant loop, but cleaner than the alternatives
  241. for i=1, numEntries, 1 do
  242. local index = i;
  243. local questLogTitleText, level, questTag, isHeader, isCollapsed = GetQuestLogTitle(i);
  244. if ( questLogTitleText and isHeader ) then
  245. numHeaders = numHeaders + 1;
  246. if ( isCollapsed ) then
  247. notExpanded = notExpanded + 1;
  248. end
  249. end
  250. end
  251. -- If all headers are not expanded then show collapse button, otherwise show the expand button
  252. if ( notExpanded ~= numHeaders ) then
  253. QuestLogCollapseAllButton.collapsed = nil;
  254. QuestLogCollapseAllButton:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-Up");
  255. else
  256. QuestLogCollapseAllButton.collapsed = 1;
  257. QuestLogCollapseAllButton:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up");
  258. end
  259. -- Update Quest Count
  260. QuestLogQuestCount:SetText(format(QUEST_LOG_COUNT_TEMPLATE, numQuests, MAX_QUESTLOG_QUESTS));
  261. QuestLogCountMiddle:SetWidth(QuestLogQuestCount:GetWidth());
  262. -- If no selection then set it to the first available quest
  263. if ( GetQuestLogSelection() == 0 ) then
  264. QuestLog_SetFirstValidSelection();
  265. end
  266. -- Determine whether the selected quest is pushable or not
  267. if ( numEntries == 0 ) then
  268. QuestFramePushQuestButton:Disable();
  269. elseif ( GetQuestLogPushable() and GetNumPartyMembers() > 0 ) then
  270. QuestFramePushQuestButton:Enable();
  271. else
  272. QuestFramePushQuestButton:Disable();
  273. end
  274. end
  275. function QuestLog_SetSelection(questID)
  276. local selectedQuest;
  277. if ( questID == 0 ) then
  278. QuestLogDetailScrollFrame:Hide();
  279. return;
  280. end
  281. -- Get xml id
  282. local id = questID - FauxScrollFrame_GetOffset(QuestLogListScrollFrame);
  283. SelectQuestLogEntry(questID);
  284. local titleButton = getglobal("QuestLogTitle"..id);
  285. local titleButtonTag = getglobal("QuestLogTitle"..id.."Tag");
  286. local questLogTitleText, level, questTag, isHeader, isCollapsed = GetQuestLogTitle(questID);
  287. if ( isHeader ) then
  288. if ( isCollapsed ) then
  289. ExpandQuestHeader(questID);
  290. return;
  291. else
  292. CollapseQuestHeader(questID);
  293. return;
  294. end
  295. else
  296. -- Set newly selected quest and highlight it
  297. QuestLogFrame.selectedButtonID = questID;
  298. local scrollFrameOffset = FauxScrollFrame_GetOffset(QuestLogListScrollFrame);
  299. if ( questID > scrollFrameOffset and questID <= (scrollFrameOffset + QUESTS_DISPLAYED) and questID <= GetNumQuestLogEntries() ) then
  300. titleButton:LockHighlight();
  301. titleButtonTag:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
  302. QuestLogSkillHighlight:SetVertexColor(titleButton.r, titleButton.g, titleButton.b);
  303. QuestLogHighlightFrame:SetPoint("TOPLEFT", "QuestLogTitle"..id, "TOPLEFT", 5, 0);
  304. QuestLogHighlightFrame:Show();
  305. end
  306. end
  307. if ( GetQuestLogSelection() > GetNumQuestLogEntries() ) then
  308. return;
  309. end
  310. QuestLog_UpdateQuestDetails();
  311. end
  312. function QuestLog_UpdateQuestDetails(doNotScroll)
  313. local questID = GetQuestLogSelection();
  314. local questTitle = GetQuestLogTitle(questID);
  315. if ( not questTitle ) then
  316. questTitle = "";
  317. end
  318. if ( IsCurrentQuestFailed() ) then
  319. questTitle = questTitle.." - ("..TEXT(FAILED)..")";
  320. end
  321. QuestLogQuestTitle:SetText(questTitle);
  322. local questDescription;
  323. local questObjectives;
  324. questDescription, questObjectives = GetQuestLogQuestText();
  325. QuestLogObjectivesText:SetText(questObjectives);
  326. local questTimer = GetQuestLogTimeLeft();
  327. if ( questTimer ) then
  328. QuestLogFrame.hasTimer = 1;
  329. QuestLogFrame.timePassed = 0;
  330. QuestLogTimerText:Show();
  331. QuestLogTimerText:SetText(TEXT(TIME_REMAINING).." "..SecondsToTime(questTimer));
  332. QuestLogObjective1:SetPoint("TOPLEFT", "QuestLogTimerText", "BOTTOMLEFT", 0, -10);
  333. else
  334. QuestLogFrame.hasTimer = nil;
  335. QuestLogTimerText:Hide();
  336. QuestLogObjective1:SetPoint("TOPLEFT", "QuestLogObjectivesText", "BOTTOMLEFT", 0, -10);
  337. end
  338. -- Show Quest Watch if track quest is checked
  339. local numObjectives = GetNumQuestLeaderBoards();
  340. for i=1, numObjectives, 1 do
  341. local string = getglobal("QuestLogObjective"..i);
  342. local text;
  343. local type;
  344. local finished;
  345. text, type, finished = GetQuestLogLeaderBoard(i);
  346. if ( not text or strlen(text) == 0 ) then
  347. text = type;
  348. end
  349. if ( finished ) then
  350. string:SetTextColor(0.2, 0.2, 0.2);
  351. text = text.." ("..TEXT(COMPLETE)..")";
  352. else
  353. string:SetTextColor(0, 0, 0);
  354. end
  355. string:SetText(text);
  356. string:Show();
  357. QuestFrame_SetAsLastShown(string);
  358. end
  359. for i=numObjectives + 1, MAX_OBJECTIVES, 1 do
  360. getglobal("QuestLogObjective"..i):Hide();
  361. end
  362. -- If there's money required then anchor and display it
  363. if ( GetQuestLogRequiredMoney() > 0 ) then
  364. if ( numObjectives > 0 ) then
  365. QuestLogRequiredMoneyText:SetPoint("TOPLEFT", "QuestLogObjective"..numObjectives, "BOTTOMLEFT", 0, -4);
  366. else
  367. QuestLogRequiredMoneyText:SetPoint("TOPLEFT", "QuestLogObjectivesText", "BOTTOMLEFT", 0, -10);
  368. end
  369. MoneyFrame_Update("QuestLogRequiredMoneyFrame", GetQuestLogRequiredMoney());
  370. if ( GetQuestLogRequiredMoney() > GetMoney() ) then
  371. -- Not enough money
  372. QuestLogRequiredMoneyText:SetTextColor(0, 0, 0);
  373. SetMoneyFrameColor("QuestLogRequiredMoneyFrame", 1.0, 0.1, 0.1);
  374. else
  375. QuestLogRequiredMoneyText:SetTextColor(0.2, 0.2, 0.2);
  376. SetMoneyFrameColor("QuestLogRequiredMoneyFrame", 1.0, 1.0, 1.0);
  377. end
  378. QuestLogRequiredMoneyText:Show();
  379. QuestLogRequiredMoneyFrame:Show();
  380. else
  381. QuestLogRequiredMoneyText:Hide();
  382. QuestLogRequiredMoneyFrame:Hide();
  383. end
  384. if ( GetQuestLogRequiredMoney() > 0 ) then
  385. QuestLogDescriptionTitle:SetPoint("TOPLEFT", "QuestLogRequiredMoneyText", "BOTTOMLEFT", 0, -10);
  386. elseif ( numObjectives > 0 ) then
  387. QuestLogDescriptionTitle:SetPoint("TOPLEFT", "QuestLogObjective"..numObjectives, "BOTTOMLEFT", 0, -10);
  388. else
  389. if ( questTimer ) then
  390. QuestLogDescriptionTitle:SetPoint("TOPLEFT", "QuestLogTimerText", "BOTTOMLEFT", 0, -10);
  391. else
  392. QuestLogDescriptionTitle:SetPoint("TOPLEFT", "QuestLogObjectivesText", "BOTTOMLEFT", 0, -10);
  393. end
  394. end
  395. if ( questDescription ) then
  396. QuestLogQuestDescription:SetText(questDescription);
  397. QuestFrame_SetAsLastShown(QuestLogQuestDescription);
  398. end
  399. local numRewards = GetNumQuestLogRewards();
  400. local numChoices = GetNumQuestLogChoices();
  401. local money = GetQuestLogRewardMoney();
  402. if ( (numRewards + numChoices + money) > 0 ) then
  403. QuestLogRewardTitleText:Show();
  404. QuestFrame_SetAsLastShown(QuestLogRewardTitleText);
  405. else
  406. QuestLogRewardTitleText:Hide();
  407. end
  408. QuestFrameItems_Update("QuestLog");
  409. if ( not doNotScroll ) then
  410. QuestLogDetailScrollFrameScrollBar:SetValue(0);
  411. end
  412. QuestLogDetailScrollFrame:UpdateScrollChildRect();
  413. end
  414. --Used to attach an empty spacer frame to the last shown object
  415. function QuestFrame_SetAsLastShown(frame, spacerFrame)
  416. if ( not spacerFrame ) then
  417. spacerFrame = QuestLogSpacerFrame;
  418. end
  419. spacerFrame:SetPoint("TOP", frame, "BOTTOM", 0, 0);
  420. end
  421. function QuestLogTitleButton_OnClick(button)
  422. local questName = this:GetText();
  423. local questIndex = this:GetID() + FauxScrollFrame_GetOffset(QuestLogListScrollFrame);
  424. if ( IsShiftKeyDown() ) then
  425. -- If header then return
  426. if ( this.isHeader ) then
  427. return;
  428. end
  429. -- Otherwise try to track it or put it into chat
  430. if ( ChatFrameEditBox:IsVisible() ) then
  431. -- Trim leading whitespace
  432. ChatFrameEditBox:Insert(gsub(this:GetText(), " *(.*)", "%1"));
  433. else
  434. -- Shift-click toggles quest-watch on this quest.
  435. if ( IsQuestWatched(questIndex) ) then
  436. tremove(QUEST_WATCH_LIST, questIndex);
  437. RemoveQuestWatch(questIndex);
  438. QuestWatch_Update();
  439. else
  440. -- Set error if no objectives
  441. if ( GetNumQuestLeaderBoards(questIndex) == 0 ) then
  442. UIErrorsFrame:AddMessage(QUEST_WATCH_NO_OBJECTIVES, 1.0, 0.1, 0.1, 1.0);
  443. return;
  444. end
  445. -- Set an error message if trying to show too many quests
  446. if ( GetNumQuestWatches() >= MAX_WATCHABLE_QUESTS ) then
  447. UIErrorsFrame:AddMessage(format(QUEST_WATCH_TOO_MANY, MAX_WATCHABLE_QUESTS), 1.0, 0.1, 0.1, 1.0);
  448. return;
  449. end
  450. AutoQuestWatch_Insert(questIndex, QUEST_WATCH_NO_EXPIRE);
  451. QuestWatch_Update();
  452. end
  453. end
  454. end
  455. QuestLog_SetSelection(questIndex)
  456. QuestLog_Update();
  457. end
  458. function QuestLogTitleButton_OnEnter()
  459. -- Set highlight
  460. getglobal(this:GetName().."Tag"):SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
  461. -- Set group info tooltip
  462. QuestLog_UpdatePartyInfoTooltip();
  463. end
  464. function QuestLog_UpdatePartyInfoTooltip()
  465. local index = this:GetID() + FauxScrollFrame_GetOffset(QuestLogListScrollFrame);
  466. local numPartyMembers = GetNumPartyMembers();
  467. if ( numPartyMembers == 0 or this.isHeader ) then
  468. return;
  469. end
  470. GameTooltip_SetDefaultAnchor(GameTooltip, this);
  471. local questLogTitleText = GetQuestLogTitle(index);
  472. GameTooltip:SetText(questLogTitleText);
  473. local partyMemberOnQuest;
  474. for i=1, numPartyMembers do
  475. if ( IsUnitOnQuest(index, "party"..i) ) then
  476. if ( not partyMemberOnQuest ) then
  477. GameTooltip:AddLine(HIGHLIGHT_FONT_COLOR_CODE..PARTY_QUEST_STATUS_ON..FONT_COLOR_CODE_CLOSE);
  478. partyMemberOnQuest = 1;
  479. end
  480. GameTooltip:AddLine(LIGHTYELLOW_FONT_COLOR_CODE..UnitName("party"..i)..FONT_COLOR_CODE_CLOSE);
  481. end
  482. end
  483. if ( not partyMemberOnQuest ) then
  484. GameTooltip:AddLine(HIGHLIGHT_FONT_COLOR_CODE..PARTY_QUEST_STATUS_NONE..FONT_COLOR_CODE_CLOSE);
  485. end
  486. GameTooltip:Show();
  487. end
  488. function QuestLogRewardItem_OnClick()
  489. if ( IsControlKeyDown() ) then
  490. if ( this.rewardType ~= "spell" ) then
  491. DressUpItemLink(GetQuestLogItemLink(this.type, this:GetID()));
  492. end
  493. elseif ( IsShiftKeyDown() and this.rewardType ~= "spell" ) then
  494. if ( ChatFrameEditBox:IsVisible() ) then
  495. ChatFrameEditBox:Insert(GetQuestLogItemLink(this.type, this:GetID()));
  496. end
  497. end
  498. end
  499. function QuestLogCollapseAllButton_OnClick()
  500. if (this.collapsed) then
  501. this.collapsed = nil;
  502. ExpandQuestHeader(0);
  503. else
  504. this.collapsed = 1;
  505. QuestLogListScrollFrameScrollBar:SetValue(0);
  506. CollapseQuestHeader(0);
  507. end
  508. end
  509. function QuestLog_GetFirstSelectableQuest()
  510. local numEntries = GetNumQuestLogEntries();
  511. local index = 0;
  512. local questLogTitleText, level, questTag, isHeader, isCollapsed;
  513. for i=1, numEntries, 1 do
  514. index = i;
  515. questLogTitleText, level, questTag, isHeader, isCollapsed = GetQuestLogTitle(i);
  516. if ( questLogTitleText and not isHeader ) then
  517. return index;
  518. end
  519. end
  520. return index;
  521. end
  522. function QuestLog_SetFirstValidSelection()
  523. local selectableQuest = QuestLog_GetFirstSelectableQuest();
  524. QuestLog_SetSelection(selectableQuest);
  525. end
  526. -- Used for quests and enemy coloration
  527. function GetDifficultyColor(level)
  528. local levelDiff = level - UnitLevel("player");
  529. if ( levelDiff >= 5 ) then
  530. color = QuestDifficultyColor["impossible"];
  531. elseif ( levelDiff >= 3 ) then
  532. color = QuestDifficultyColor["verydifficult"];
  533. elseif ( levelDiff >= -2 ) then
  534. color = QuestDifficultyColor["difficult"];
  535. elseif ( -levelDiff <= GetQuestGreenRange() ) then
  536. color = QuestDifficultyColor["standard"];
  537. else
  538. color = QuestDifficultyColor["trivial"];
  539. end
  540. return color;
  541. end
  542. -- QuestWatch functions
  543. function QuestWatch_Update()
  544. local numObjectives;
  545. local questWatchMaxWidth = 0;
  546. local tempWidth;
  547. local watchText;
  548. local text, type, finished;
  549. local questTitle
  550. local watchTextIndex = 1;
  551. local questIndex;
  552. local objectivesCompleted;
  553. for i=1, GetNumQuestWatches() do
  554. questIndex = GetQuestIndexForWatch(i);
  555. if ( questIndex ) then
  556. numObjectives = GetNumQuestLeaderBoards(questIndex);
  557. --If there are objectives set the title
  558. if ( numObjectives > 0 ) then
  559. -- Set title
  560. watchText = getglobal("QuestWatchLine"..watchTextIndex);
  561. watchText:SetText(GetQuestLogTitle(questIndex));
  562. tempWidth = watchText:GetWidth();
  563. -- Set the anchor of the title line a little lower
  564. if ( watchTextIndex > 1 ) then
  565. watchText:SetPoint("TOPLEFT", "QuestWatchLine"..(watchTextIndex - 1), "BOTTOMLEFT", 0, -4);
  566. end
  567. watchText:Show();
  568. if ( tempWidth > questWatchMaxWidth ) then
  569. questWatchMaxWidth = tempWidth;
  570. end
  571. watchTextIndex = watchTextIndex + 1;
  572. objectivesCompleted = 0;
  573. for j=1, numObjectives do
  574. text, type, finished = GetQuestLogLeaderBoard(j, questIndex);
  575. watchText = getglobal("QuestWatchLine"..watchTextIndex);
  576. -- Set Objective text
  577. watchText:SetText(" - "..text);
  578. -- Color the objectives
  579. if ( finished ) then
  580. watchText:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
  581. objectivesCompleted = objectivesCompleted + 1;
  582. else
  583. watchText:SetTextColor(0.8, 0.8, 0.8);
  584. end
  585. tempWidth = watchText:GetWidth();
  586. if ( tempWidth > questWatchMaxWidth ) then
  587. questWatchMaxWidth = tempWidth;
  588. end
  589. watchText:SetPoint("TOPLEFT", "QuestWatchLine"..(watchTextIndex - 1), "BOTTOMLEFT", 0, 0);
  590. watchText:Show();
  591. watchTextIndex = watchTextIndex + 1;
  592. end
  593. -- Brighten the quest title if all the quest objectives were met
  594. watchText = getglobal("QuestWatchLine"..watchTextIndex-numObjectives-1);
  595. if ( objectivesCompleted == numObjectives ) then
  596. watchText:SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b);
  597. else
  598. watchText:SetTextColor(0.75, 0.61, 0);
  599. end
  600. end
  601. end
  602. end
  603. -- Set tracking indicator
  604. if ( GetNumQuestWatches() > 0 ) then
  605. QuestLogTrackTracking:SetVertexColor(0, 1.0, 0);
  606. else
  607. QuestLogTrackTracking:SetVertexColor(1.0, 0, 0);
  608. end
  609. -- If no watch lines used then hide the frame and return
  610. if ( watchTextIndex == 1 ) then
  611. QuestWatchFrame:Hide();
  612. return;
  613. else
  614. QuestWatchFrame:Show();
  615. QuestWatchFrame:SetHeight(watchTextIndex * 13);
  616. QuestWatchFrame:SetWidth(questWatchMaxWidth + 10);
  617. end
  618. -- Hide unused watch lines
  619. for i=watchTextIndex, MAX_QUESTWATCH_LINES do
  620. getglobal("QuestWatchLine"..i):Hide();
  621. end
  622. UIParent_ManageFramePositions();
  623. end
  624. function GetQuestLogIndexByName(name)
  625. local numEntries = GetNumQuestLogEntries();
  626. local questLogTitleText;
  627. for i=1, numEntries, 1 do
  628. questLogTitleText = GetQuestLogTitle(i);
  629. if ( " "..questLogTitleText == name ) then
  630. return i;
  631. end
  632. end
  633. return nil;
  634. end
  635. function AutoQuestWatch_Insert(questIndex, watchTimer)
  636. if ( IsQuestWatched(questIndex) and watchTimer == QUEST_WATCH_NO_EXPIRE ) then
  637. return;
  638. end
  639. local lowestTimer = MAX_QUEST_WATCH_TIMER;
  640. local lowestIndex;
  641. for index, value in QUEST_WATCH_LIST do
  642. if ( ( value.timer <= lowestTimer ) and ( value.timer ~= QUEST_WATCH_NO_EXPIRE ) ) then
  643. lowestTimer = value.timer;
  644. lowestIndex = value.index;
  645. end
  646. end
  647. local watch = {};
  648. watch.index = questIndex;
  649. watch.timer = watchTimer;
  650. if ( getn(QUEST_WATCH_LIST) < MAX_WATCHABLE_QUESTS ) then
  651. tinsert(QUEST_WATCH_LIST, watch);
  652. AddQuestWatch(questIndex);
  653. else
  654. if ( lowestIndex ) then
  655. tremove(QUEST_WATCH_LIST, lowestIndex);
  656. RemoveQuestWatch(lowestIndex);
  657. tinsert(QUEST_WATCH_LIST, watch);
  658. AddQuestWatch(questIndex);
  659. end
  660. end
  661. end
  662. function AutoQuestWatch_CheckDeleted()
  663. local questLogIndex, questLogTitleText, questWatchTitleText, isInQuestLog;
  664. local numEntries = GetNumQuestLogEntries();
  665. for index, value in QUEST_WATCH_LIST do
  666. isInQuestLog = nil;
  667. questWatchTitleText = GetQuestLogTitle(value.index);
  668. for i=1, numEntries do
  669. questLogTitleText = GetQuestLogTitle(i);
  670. if ( questWatchTitleText == questLogTitleText ) then
  671. isInQuestLog = 1;
  672. end
  673. end
  674. if ( not isInQuestLog ) then
  675. tremove(QUEST_WATCH_LIST, index);
  676. end
  677. end
  678. end
  679. function AutoQuestWatch_Update(questIndex)
  680. -- Check the array for an existing matching entry. Remove if matched, then add the quest to the watch list.
  681. for index, value in QUEST_WATCH_LIST do
  682. if ( value.index == questIndex and value.timer == QUEST_WATCH_NO_EXPIRE ) then
  683. return;
  684. elseif ( not value.index and QuestIsWatched(questIndex) ) then
  685. value.index = questIndex;
  686. value.timer = QUEST_WATCH_NO_EXPIRE;
  687. tinsert(QUEST_WATCH_LIST, value)
  688. elseif ( value.index == questIndex and ( value.timer ~= QUEST_WATCH_NO_EXPIRE ) ) then
  689. tremove(QUEST_WATCH_LIST, index);
  690. value.index = questIndex;
  691. value.timer = MAX_QUEST_WATCH_TIMER;
  692. tinsert(QUEST_WATCH_LIST, value);
  693. return;
  694. end
  695. end
  696. AutoQuestWatch_Insert(questIndex, MAX_QUEST_WATCH_TIMER);
  697. end
  698. function AutoQuestWatch_OnUpdate(elapsed)
  699. for index, value in QUEST_WATCH_LIST do
  700. if ( value.timer ~= QUEST_WATCH_NO_EXPIRE ) then
  701. value.timer = value.timer - elapsed;
  702. if ( value.timer < 0 ) then
  703. RemoveQuestWatch(value.index);
  704. tremove(QUEST_WATCH_LIST, index);
  705. QuestWatch_Update();
  706. QuestLog_Update();
  707. end
  708. end
  709. end
  710. end