Thread Tools Display Modes
10-19-14, 07:55 PM   #1
Lazare
An Aku'mai Servant
 
Lazare's Avatar
AddOn Author - Click to view addons
Join Date: May 2008
Posts: 36
Over my head and drowning...

For a little background, I started programming in 1975 using COBOL and FORTRAN. I did a little Basic years later but lapsed in my programming for about 25 years. At 54 I started up with Lua about the time TOT hit to make my Lei Shen addon. That was a learning experience but it was started from scratch. Now thinking I could take over to breathe new life into QuestGuru that was programmed by two other people I am finding myself drowning. I really can't understand how Blizz broke this addon so badly. I have used it for years and has worked just great. But 6.0.2 broke it almost beyond repair. I know you folks have your addons you are trying to update but am asking for some "hand holding" so I can get this addon back into the hands of the people who use and love it like I do. I am listing the code below for the Lua, xml and bindings. Thanks in advance for your help.

QuestGuru.toc
Code:
## Interface: 60000## Title: QuestGuru
## Version: 2.3.00-60000
## Notes: Quest Log Enhancement
## Author: Lazare, current author (MrOBrian/Gregity, past authors)
## SavedVariables: QuestGuru_Items, QuestGuru_Settings
## SavedVariablesPerCharacter: 
ChatThrottleLib.lua
localization.lua
localization.DE.lua
localization.FR.lua
localization.RU.lua
localization.TW.lua
localization.CN.lua
QuestGuruComm.lua
QuestGuru_Templates.xml
QuestGuru.xml
QuestGuruOptions.lua
QuestGuruAnnounce.lua
Bindings.xml
QuestGuru.lua
lua Code:
  1. QUESTGURU_VERSION = GetAddOnMetadata("QuestGuru", "Version");
  2.  
  3.  
  4. QuestGuru_Settings = {};
  5. QuestGuru_Items = {};
  6.  
  7.  
  8. QGC_Cache = {};
  9. QGC_Active = {};
  10.  
  11.  
  12. BINDING_HEADER_QUESTGURU = "QuestGuru"
  13. BINDING_NAME_QUESTGURU_TOGGLE = "Show/Hide Quest Log"
  14.  
  15.  
  16. local QuestGuru_RealmName, QuestGuru_PlayerFaction;
  17.  
  18.  
  19. do
  20.     local qgf = CreateFrame("Frame", "qgf", UIParent);
  21.     qgf:SetScript("OnEvent",
  22.         function (self, event, arg1, arg2)
  23.             QuestGuru_OnEvent(self, event, arg1, arg2);
  24.         end);
  25.  
  26.  
  27.     qgf:RegisterEvent("QUEST_DETAIL")
  28.     qgf:RegisterEvent("QUEST_LOG_UPDATE")
  29.     qgf:RegisterEvent("QUEST_WATCH_LIST_CHANGED")
  30.     qgf:RegisterEvent("SUPER_TRACKED_QUEST_CHANGED")
  31.     qgf:RegisterEvent("GROUP_ROSTER_UPDATE")
  32.     qgf:RegisterEvent("PARTY_MEMBER_ENABLE")
  33.     qgf:RegisterEvent("PARTY_MEMBER_DISABLE")
  34.     qgf:RegisterEvent("QUEST_POI_UPDATE")
  35.     qgf:RegisterEvent("QUEST_WATCH_UPDATE")
  36.     qgf:RegisterEvent("QUEST_ACCEPTED")
  37.     qgf:RegisterEvent("UNIT_QUEST_LOG_CHANGED")
  38.  
  39.  
  40.     tinsert(UISpecialFrames, "QuestLogFrame");
  41.     QuestLogFrame:SetMovable(true)
  42.     QuestLogFrame:EnableMouse(true)
  43.     QuestLogFrame:RegisterForDrag("LeftButton")
  44.     QuestLogFrame:SetScript("OnDragStart", QuestLogFrame.StartMoving)
  45.     QuestLogFrame:SetScript("OnDragStop", QuestLogFrame.StopMovingOrSizing)
  46. end
  47.  
  48.  
  49. function QuestGuru_OnEvent(self, event, arg1, arg2)
  50.     if (event == "UI_INFO_MESSAGE") then
  51.         QuestGuru_UIInfoMessage(arg1);
  52.     elseif (event == "VARIABLES_LOADED") then
  53.         QuestLogTitleText:SetText(QuestLogTitleText:GetText().." - QuestGuru v"..QUESTGURU_VERSION);
  54.         QuestGuru_LoadVariables();
  55.         QuestGuru_HistoryShowButton:Hide();
  56.         if IsAddOnLoaded("QuestCompletist") then QuestGuru_HistoryShowButton:Show(); end
  57.     elseif (event=="QUEST_COMPLETE") then
  58.         if (QuestGuru_Settings.AutoComplete and (GetNumQuestChoices() == 0)) then
  59.             QuestRewardCompleteButton_OnClick();
  60.         end
  61.     elseif (event=="QUEST_PROGRESS") then
  62.         QuestGuru_QuestProgressShow();
  63.         if (QuestGuru_Settings.AutoComplete and IsQuestCompletable()) then
  64.             CompleteQuest();
  65.         end
  66.     elseif (event=="QUEST_LOG_UPDATE") then
  67.         wipe(QGC_Active);
  68.         local numEntries, numQuests = GetNumQuestLogEntries();
  69.         for i=1, numEntries do
  70.             local qLink = GetQuestLink(i);
  71.             if (qLink) then
  72.                 local qi, qj, questNum = string.find(qLink, (":(%d+):"));
  73.                 if (questNum) then QGC_Active[questNum]="true"; end
  74.             end
  75.         end
  76.     elseif (event=="GOSSIP_SHOW") then
  77.         QuestGuru_GossipShow();
  78.     elseif (event=="QUEST_GREETING") then
  79.         QuestGuru_QuestFrameGreetingPanel_OnShow();
  80.     elseif (event=="QUEST_DETAIL") then
  81.         QuestGuru_QuestDetailShow();
  82.     end
  83. end
  84.  
  85.  
  86. function QuestGuru_ShowHistory()
  87. -- Bring up any history addon that is installed but doesn't have it's own button
  88.   if IsAddOnLoaded("QuestCompletist") then qcQuestCompletistUI:Show(); end
  89. end
  90.  
  91.  
  92. function QuestGuru_TitleButtonCheckBox_OnClick(self, button, down)
  93.     local index = self:GetParent():GetID();
  94.     local questLogTitleText, level, questTag, suggestedGroup, isHeader, isCollapsed, isComplete, isDaily = GetQuestLogTitle(index);
  95.  
  96.  
  97.     if (self:GetChecked()) then
  98.         if (isHeader) then
  99.             QuestGuru_AddQuestWatchHeader(questLogTitleText);
  100.         else
  101.             if (not AddQuestWatch(index)) then
  102.                 self:SetChecked(0);
  103.             end
  104.         end
  105.     else
  106.         if (isHeader) then
  107.             QuestGuru_RemoveQuestWatchHeader(questLogTitleText);
  108.         else
  109.             RemoveQuestWatch(index);
  110.         end
  111.     end
  112.     WatchFrame_Update();
  113.     QuestLog_Update();
  114. end
  115.  
  116.  
  117. function QuestGuru_AddQuestWatchHeader(questHeader)
  118.     local numEntries, numQuests = GetNumQuestLogEntries();
  119.     local inHeader = false;
  120.  
  121.  
  122.     for questIndex=1, numEntries do
  123.         local questLogTitleText, level, questTag, suggestedGroup, isHeader, isCollapsed, isComplete, isDaily = GetQuestLogTitle(questIndex);
  124.         if (isHeader) then
  125.             if (questLogTitleText == questHeader) then
  126.                 inHeader = true;
  127.             else
  128.                 inHeader = false;
  129.             end
  130.         end
  131.         if (inHeader and (not isHeader)) then
  132.             AddQuestWatch(questIndex);
  133.         end
  134.     end
  135. end
  136.  
  137.  
  138. function IsHeaderWatched(questHeader)
  139.     local numEntries, numQuests = GetNumQuestLogEntries();
  140.     local inHeader = false;
  141.     local headerWatched = true;
  142.  
  143.  
  144.     for questIndex=1, numEntries do
  145.         local questLogTitleText, level, questTag, suggestedGroup, isHeader, isCollapsed, isComplete, isDaily = GetQuestLogTitle(questIndex);
  146.         if (isHeader) then
  147.             if (questLogTitleText == questHeader) then
  148.                 inHeader = true;
  149.             else
  150.                 inHeader = false;
  151.             end
  152.         end
  153.         if (inHeader and (not isHeader)) then
  154.             headerWatched = (headerWatched and IsQuestWatched(questIndex));
  155.         end
  156.     end
  157.     return headerWatched;
  158. end
  159.  
  160.  
  161. function QuestGuru_RemoveQuestWatchHeader(questHeader)
  162.     local numEntries, numQuests = GetNumQuestLogEntries();
  163.     local inHeader = false;
  164.  
  165.  
  166.     for questIndex=1, numEntries do
  167.         local questLogTitleText, level, questTag, suggestedGroup, isHeader, isCollapsed, isComplete, isDaily = GetQuestLogTitle(questIndex);
  168.         if (isHeader) then
  169.             if (questLogTitleText == questHeader) then
  170.                 inHeader = true;
  171.             else
  172.                 inHeader = false;
  173.             end
  174.         end
  175.         if (inHeader and (not isHeader)) then
  176.             RemoveQuestWatch(questIndex);
  177.         end
  178.     end
  179. end
  180.  
  181.  
  182. local prevParent;
  183. local function QuestGuru_QuestLog_HighlightQuest(questLogTitle)
  184.     if ( prevParent and prevParent ~= questLogTitle ) then
  185.         -- set prev quest's colors back to normal
  186.         prevParent.level:SetTextColor(prevParent.r, prevParent.g, prevParent.b);
  187.     end
  188.     if ( questLogTitle ) then
  189.         -- highlight the quest's colors
  190.         questLogTitle.level:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
  191.     end
  192.     prevParent = questLogTitle;
  193. end
  194.  
  195.  
  196. function QuestGuru_SetSelection(questIndex)
  197.     if ( questIndex == 0 ) then
  198.         return;
  199.     end
  200.  
  201.  
  202.     -- find and highlight the selected quest
  203.     local buttons = QuestLogScrollFrame.buttons;
  204.     local numButtons = #buttons;
  205.     local min = 1;
  206.     local max = #buttons;
  207.     local mid;
  208.     local titleButton, id;
  209.     while ( min <= max ) do
  210.         mid = bit.rshift(min + max, 1);
  211.         titleButton = buttons[mid];
  212.         id = titleButton:GetID();
  213.         if ( id == questIndex ) then
  214.             QuestGuru_QuestLog_HighlightQuest(titleButton);
  215.             break;
  216.         end
  217.         if ( id > questIndex ) then
  218.             max = mid - 1;
  219.         else
  220.             min = mid + 1;
  221.         end
  222.     end
  223.  
  224.  
  225.     -- Dridzt supplied snippet to solve some obscure framelevel issues.
  226.   local QG_qlcp = _G["QuestLogControlPanel"]
  227.   QG_qlcp:SetFrameLevel(QG_qlcp:GetParent():GetFrameLevel()+1);
  228.  
  229.  
  230. end
  231. hooksecurefunc("QuestLog_SetSelection", QuestGuru_SetSelection);
  232.  
  233.  
  234. --local QG_QuestLogUpdate = QuestLog_Update;
  235. function QG_QuestLog_Update()
  236. --    QG_QuestLogUpdate();
  237.     local buttons = QuestLogScrollFrame.buttons;
  238.     local numButtons = #buttons;
  239.     local scrollOffset = HybridScrollFrame_GetOffset(QuestLogScrollFrame);
  240.     local questLogSelection = GetQuestLogSelection();
  241.  
  242.  
  243.     local questIndex, questLogTitle, questTitleTag, questNumGroupMates, questNormalText, questCheck;
  244.     local title, level, questTag, suggestedGroup, isHeader, isCollapsed, isComplete, isDaily;
  245.     for i=1, numButtons do
  246.         questLogTitle = buttons[i];
  247.         questIndex = questLogTitle:GetID();
  248.         title, level, questTag, suggestedGroup, isHeader, isCollapsed, isComplete, isDaily = GetQuestLogTitle(questIndex);
  249.         questNumGroupMates = questLogTitle.groupMates;
  250.         questNumGroupMates:SetPoint("LEFT", 6, 0);
  251.         if (questLogTitle.level == nil) then
  252.             questLogTitle.level = questLogTitle:CreateFontString(questLogTitle:GetName().."Level", "BACKGROUND", "GameFontNormalSmall");
  253.             questLogTitle.tag:SetFontObject("GameFontNormalSmall");
  254.             questLogTitle.level:SetPoint("LEFT", 28, 0);
  255.             questLogTitle.level:SetWidth(32);
  256.             questLogTitle.level:SetJustifyH("CENTER");
  257.             questLogTitle.level.parentKey = "level";
  258.             questLogTitle:HookScript("OnEnter", function(self)
  259.                     self.level:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
  260.                 end);
  261.             questLogTitle:HookScript("OnLeave", function(self)
  262.                     if ( self:GetID() ~= QuestLogFrame.selectedIndex ) then
  263.                         self.level:SetTextColor(self.r, self.g, self.b);
  264.                     end
  265.                 end);
  266.         end
  267.         if (questLogTitle.checkBox == nil) then
  268.             questLogTitle.checkBox = CreateFrame("CheckButton", questLogTitle:GetName().."CheckBox", questLogTitle, "OptionsCheckButtonTemplate");
  269.             questLogTitle.checkBox:SetHeight(16);
  270.             questLogTitle.checkBox:SetWidth(16);
  271.             questLogTitle.checkBox:SetPoint("LEFT", 16, 0);
  272.             questLogTitle.checkBox:SetHitRectInsets(0, 0, 0, 0);
  273.             questLogTitle.checkBox:SetScript("OnClick", QuestGuru_TitleButtonCheckBox_OnClick);
  274.         end
  275.         questLogTitle.check:Hide();
  276.  
  277.  
  278.         questLevel = questLogTitle.level;
  279.         if (isHeader) then
  280.             questLevel:SetText("");
  281.             questLogTitle.normalText:SetPoint("LEFT", 32, 0);
  282.             if (IsHeaderWatched(title)) then
  283.                 questLogTitle.checkBox:SetChecked(1);
  284.             else
  285.                 questLogTitle.checkBox:SetChecked(0);
  286.             end
  287.         else
  288.             local strLvl = level
  289.             if (isDaily) then
  290.                 strLvl = strLvl.."Y";
  291.             end
  292.             if (questTag ~= nil) then
  293.                 if ((questTag == "Group") and (suggestedGroup > 0)) then
  294.                     strLvl = strLvl.."G"..suggestedGroup;
  295.                 elseif (questTag == "Dungeon") then
  296.                     strLvl = strLvl.."D";
  297.                 else
  298.                     strLvl = strLvl.."+"
  299.                 end
  300.             else
  301.                 if (suggestedGroup > 0) then
  302.                     strLvl = strLvl.."G"..suggestedGroup;
  303.                 end
  304.             end
  305.  
  306.  
  307.             if (QuestGuru_Settings.ShowLevels == nil) then
  308.                 QuestGuru_Settings.ShowLevels = {};
  309.             end
  310.             if (QuestGuru_Settings.ShowLevels.QuestLog) then
  311.                 questLevel:Show();
  312.                 textLeft = 52;
  313.             else
  314.                 questLevel:Hide();
  315.                 textLeft = 32;
  316.             end
  317.             questLevel:SetText(strLvl);
  318.             questLogTitle.normalText:SetPoint("LEFT", textLeft, 0);
  319.             local color = GetQuestDifficultyColor(level);
  320.             questLevel:SetTextColor(color.r, color.g, color.b);
  321.             if ( questLogSelection == questIndex ) then
  322.                 QuestGuru_QuestLog_HighlightQuest(questLogTitle);
  323.             end
  324.             if (IsQuestWatched(questIndex)) then
  325.                 questLogTitle.checkBox:SetChecked(1);
  326.             else
  327.                 questLogTitle.checkBox:SetChecked(0);
  328.             end
  329.         end
  330.         QuestLogTitleButton_Resize(questLogTitle);
  331.     end
  332. end
  333. hooksecurefunc("QuestLog_Update", QG_QuestLog_Update);
  334.  
  335.  
  336. QuestLogScrollFrame.update = function () QuestLog_Update(); end;
  337.  
  338.  
  339. function QuestGuru_ShowObjectives(template, parentFrame, acceptButton, material)
  340.     local i, lastObjective;
  341.     local numObjectives = GetNumQuestLeaderBoards();
  342.    
  343.     for i=1, MAX_OBJECTIVES do
  344.         _G["QuestGuru_QuestLogObjectiveItem"..i]:Hide();
  345.         _G["QuestGuru_QuestLogObjectiveItem"..i].timerEnabled = false;
  346.     end
  347.  
  348.  
  349.     if (QuestGuru_Settings.ShowObjItemIcons) then
  350.         local currObjItem = 0;
  351.         for i=1, numObjectives, 1 do
  352.             local text, type, finished = GetQuestLogLeaderBoard(i);
  353.             local count;
  354.             if (type == "item") then
  355.                 local questObj = _G["QuestInfoObjective"..i];
  356.                 if ( not text or strlen(text) == 0 ) then
  357.                     text = type;
  358.                 end
  359.                 if ( finished ) then
  360.                     questObj:SetTextColor(0.2, 0.2, 0.2);
  361.                     text = text.." ("..COMPLETE..")";
  362.                 else
  363.                     questObj:SetTextColor(0, 0, 0);
  364.                 end
  365.                 questObj:SetText(text);
  366.                 questObj:Show();
  367.                 questObj:SetAlpha(0);
  368.                 lastObjective = questObj;
  369.  
  370.  
  371.                 currObjItem = currObjItem + 1;
  372.                 local questItem = _G["QuestGuru_QuestLogObjectiveItem"..currObjItem];
  373.                 questItem.type = "required";
  374.                 local x, y, name, numItems, numNeeded = string.find(text, QG_ITEM_REQ_STR);
  375.                 local iiName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, texture = GetItemInfo(name);
  376.  
  377.  
  378.                 if ((not itemLink) and QuestGuru_Items[QuestGuru_RealmName][name]) then
  379.                     iiName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, texture = GetItemInfo(QuestGuru_Items[QuestGuru_RealmName][name]);
  380.                 end
  381.                 if (not itemLink) then
  382.                     texture = "Interface\\Icons\\INV_Misc_QuestionMark";
  383.                     count = 0;
  384.                     SetItemButtonTextureVertexColor(questItem, 0.4, 0.4, 0.4);
  385.                     QuestGuru_CommSendPGMessage("0301", name);
  386.                 else
  387.                     if (texture == nil) then
  388.                         GameTooltip:SetHyperlink(itemLink);
  389.                         GameTooltip:Show();
  390.                         GameTooltip:Hide();
  391.                         questItem.timerEnabled = true;
  392.                     end
  393.                     count = GetItemCount(itemLink);
  394.                     SetItemButtonTextureVertexColor(questItem, 0.8, 0.8, 0.8);
  395.                 end
  396.                 questItem:SetID(currObjItem)
  397.                 -- For the tooltip
  398.                 questItem.rewardType = "item"
  399.                 questItem.link = itemLink;
  400.                 _G["QuestGuru_QuestLogObjectiveItem"..currObjItem.."Name"]:SetText(name);
  401.                 _G["QuestGuru_QuestLogObjectiveItem"..currObjItem.."Count"]:SetText(count.." /"..numNeeded);
  402.                 SetItemButtonTexture(questItem, texture);
  403.                 SetItemButtonNameFrameVertexColor(questItem, 1, 1, 1);
  404.                 if ( currObjItem  > 1 ) then
  405.                     if ( mod(currObjItem ,2) == 1 ) then
  406.                         questItem:SetPoint("TOPLEFT", "QuestGuru_QuestLogObjectiveItem"..(currObjItem - 2), "BOTTOMLEFT", 0, -2);
  407.                         lastObjective = questItem;
  408.                     else
  409.                         questItem:SetPoint("TOPLEFT", "QuestGuru_QuestLogObjectiveItem"..(currObjItem - 1), "TOPRIGHT", 1, 0);
  410.                         lastObjective = _G["QuestGuru_QuestLogObjectiveItem"..(currObjItem)-1];
  411.                     end
  412.                 else
  413.                     if (i > 1) then
  414.                         questItem:SetPoint("TOPLEFT", "QuestInfoObjective"..(i - 1), "BOTTOMLEFT", 0, -5);
  415.                     else
  416.                         questItem:SetPoint("TOPLEFT");
  417.                     end
  418.                     lastObjective = questItem;
  419.                 end
  420.                 questItem:Show();
  421.             end
  422.         end
  423.         if ( lastObjective ) then
  424.             QuestInfoObjectivesFrame:SetHeight(QuestInfoObjectivesFrame:GetTop() - lastObjective:GetTop() + lastObjective:GetHeight());
  425.             QuestInfoDescriptionHeader:SetPoint("TOPLEFT", QuestInfoObjectivesFrame, "BOTTOMLEFT");
  426.         end
  427.     end
  428. end
  429. hooksecurefunc("QuestInfo_Display", QuestGuru_ShowObjectives);
  430.  
  431.  
  432. function QuestGuru_UIInfoMessage(arg1)
  433.   QuestGuru_Echo(string.format("QuestGuru_UIInfoMessage invoked, arg1=%s", tostring(arg1) ), false)
  434.     local questID=0;
  435.     local sound, announceText;
  436.     local numEntries, numQuests = GetNumQuestLogEntries();
  437.     local i, ii, jj, itemName, numDone, numNeeded;
  438.     local questLogTitleText, level, questTag, suggestedGroup, isHeader, isCollapsed, isComplete, isDaily;
  439.  
  440.  
  441.     if (arg1 == nil) then return; end
  442.  
  443.  
  444.     for questID=1, numEntries, 1 do
  445.         questLogTitleText, level, questTag, suggestedGroup, isHeader, isCollapsed, isComplete, isDaily = GetQuestLogTitle(questID);
  446.         local numObjectives = GetNumQuestLeaderBoards(questID);
  447.         local currQuest = false;
  448.         local questComplete = true;
  449.         sound = nil;
  450.         announceText = nil;
  451.  
  452.  
  453.         if (numObjectives ~= nil) then
  454.             for i=1, numObjectives, 1 do
  455.                 local text, type, finished = GetQuestLogLeaderBoard(i,questID);
  456.         if (text == nil) then
  457.           QuestGuru_Echo(string.format("Error: numEntries=%s, numQuests=%s",
  458.             tostring(numEntries), tostring(numQuests) ), false)
  459.           QuestGuru_Echo(string.format("Error: Variable text is nil. arg1=%s, questID=%s, i=%s, numObjectives=%s, questLogTitleText=%s",
  460.             tostring(arg1), tostring(questID), tostring(i), tostring(numObjectives), tostring(questLogTitleText) ), false)
  461.           QuestGuru_Echo(string.format("Error: text=%s, type=%s, finished=%s",
  462.             tostring(text), tostring(type), tostring(finished) ), false)
  463.         else
  464.                   local qi, qj, qitemName, qnumDone, qnumNeeded = string.find(text, QG_ITEM_REQ_STR);
  465.                   if ((type == "item") or (type == "monster") or (type == "object")) then
  466.                       if (type == "object") then type = "item"; end
  467.                       ii, jj, itemName, numDone, numNeeded = string.find(arg1, QG_ITEM_REQ_STR);
  468.                       if ((itemName == qitemName) and (numNeeded == qnumNeeded)) then
  469.                           if (QuestGuru_Settings.Sounds.Progress.Enabled) then sound = QuestGuru_Settings.Sounds.Progress.Sound; end
  470.                           if (QuestGuru_Settings.Announce.item.Enabled and (type == "item")) then announceText = QuestGuru_Settings.Announce.item.Text; end
  471.                            if (QuestGuru_Settings.Announce.monster.Enabled and (type == "monster")) then announceText = QuestGuru_Settings.Announce.monster.Text; end
  472.                           if (numDone == numNeeded) then
  473.                               if (QuestGuru_Settings.Sounds.ObjComplete.Enabled) then sound = QuestGuru_Settings.Sounds.ObjComplete.Sound; end
  474.                               if (announceText) then announceText = announceText.." ("..QG_ANNOUNCE_KEYWORD_COMPLETE..")"; end
  475.                               finished = true;
  476.                           end
  477.                           currQuest = true;
  478.                       end
  479.                   elseif (type == "event") then
  480.                       itemName = text;
  481.                       numDone=1;
  482.                       numNeeded=1;
  483.                       if (arg1 == text.." ("..COMPLETE..")") then
  484.                           if (QuestGuru_Settings.Sounds.ObjComplete.Enabled) then sound = QuestGuru_Settings.Sounds.ObjComplete.Sound; end
  485.                           if (QuestGuru_Settings.Announce.event.Enabled) then announceText = QuestGuru_Settings.Announce.event.Text; end
  486.                           currQuest = true;
  487.                           finished = true;
  488.                       end
  489.                   end
  490.                   if (not finished) then questComplete = false; end
  491.         end
  492.             end
  493.         end
  494.         if (currQuest) then
  495.             if (questComplete) then
  496.                 if (QuestGuru_Settings.Sounds.QuestComplete.Enabled) then sound = QuestGuru_Settings.Sounds.QuestComplete.Sound; end
  497.                 if (QuestGuru_Settings.Announce.Quest.Enabled) then announceText = QuestGuru_Settings.Announce.Quest.Text; end
  498.                 UIErrorsFrame:AddMessage(QG_QUEST_COMPLETE, 1, 1, 0, 1, 5);
  499.             end
  500.             QuestGuru_PlayExtraSound(sound);
  501.             QuestGuru_DoAnnounce(announceText, numDone, numNeeded, itemName, questLogTitleText, arg1, questID);
  502.             QuestGuru_CommAddTimer(1, 1, QuestGuru_SendQuestStatus, questID, false);
  503.         end
  504.     end
  505. end
  506.  
  507.  
  508. function QuestGuru_PlayExtraSound(sound)
  509.     if (sound == nil) then return; end
  510.    
  511.     if (QuestGuru_Settings.Sounds.Enabled) then
  512.         if ((string.sub(sound, -4) == ".wav") or (string.sub(sound, -4) == ".mp3")) then
  513.             PlaySoundFile(sound);
  514.         else
  515.             PlaySound(sound);
  516.         end
  517.     end
  518. end
  519.  
  520.  
  521. function QuestGuru_QuestProgressShow()
  522.     local questTitle = GetTitleText();
  523.    
  524.     QuestGuru_UpdateProgressFrame(questTitle, GetGossipActiveQuests());
  525.  
  526.  
  527.     local i;
  528.     for i=1, GetNumQuestItems() do
  529.         local name, texture, numItems, quality, isUsable = GetQuestItemInfo("required", i);
  530.         local link = GetQuestItemLink("required", i);
  531.         if (name and link) then
  532.             QuestGuru_Items[QuestGuru_RealmName][name] = link;
  533.             _G["QuestProgressItem"..i].link = link;
  534.             _G["QuestProgressItem"..i]:SetScript("OnEnter", function (self)
  535.                 GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
  536.                 GameTooltip:SetHyperlink(self.link);
  537.             end);
  538.         end
  539.     end
  540. end
  541.  
  542.  
  543. function QuestGuru_UpdateProgressFrame(questTitle, ...)
  544.     local i;
  545.  
  546.  
  547.     for i=1, select("#", ...), 3 do
  548.         if (select(i, ...) == questTitle) then
  549.             QuestProgressTitleText:SetText("["..select(i+1, ...).."] "..questTitle);
  550.         end
  551.     end
  552. end
  553.  
  554.  
  555. function QuestGuru_LoadVariables()
  556.         QuestGuru_Player = UnitName("player");
  557.         QuestGuru_PlayerFaction = UnitFactionGroup("player");
  558.         QuestGuru_RealmName = GetRealmName();
  559.  
  560.  
  561.         if (QuestGuru_Items == nil) then
  562.             QuestGuru_Items = {};
  563.         end
  564.         if (QuestGuru_Items[QuestGuru_RealmName] == nil) then
  565.             QuestGuru_Items[QuestGuru_RealmName] = {};
  566.         end
  567.        
  568.         if (QuestGuru_Settings == nil) then
  569.             QuestGuru_Settings = {};
  570.         end
  571.         QuestGuru_QuestAnnounceLoadSettings();
  572.         QuestGuru_OptionsSoundsLoadSettings();
  573.        
  574.         if (QuestGuru_Settings.AutoComplete ~= true) then
  575.             QuestGuru_Settings.AutoComplete = false;
  576.         end
  577.         QuestGuru_OptionsFrameAutoCompleteToggle:SetChecked(QuestGuru_Settings.AutoComplete);
  578.        
  579.         if (QuestGuru_Settings.ShowObjItemIcons ~= true) then
  580.             QuestGuru_Settings.ShowObjItemIcons = false;
  581.         end
  582.         QuestGuru_OptionsFrameShowObjItemIconsToggle:SetChecked(QuestGuru_Settings.ShowObjItemIcons);
  583.        
  584.         if (QuestGuru_Settings.DisableComm ~= true) then
  585.             QuestGuru_Settings.DisableComm = false;
  586.         end
  587.         QuestGuru_OptionsFrameDisableCommToggle:SetChecked(QuestGuru_Settings.DisableComm);
  588.  
  589.  
  590.         if (QuestGuru_Settings.HeaderQuests ~= false) then
  591.             QuestGuru_Settings.HeaderQuests = true;
  592.         end
  593.         QuestGuru_OptionsFrameShowHeaderQuestsToggle:SetChecked(QuestGuru_Settings.HeaderQuests);
  594.  
  595.  
  596.         if (QuestGuru_Settings.ShowLevels == nil) then
  597.             QuestGuru_Settings.ShowLevels = {};
  598.         end
  599.         if (QuestGuru_Settings.ShowLevels.QuestLog ~= false) then
  600.             QuestGuru_Settings.ShowLevels.QuestLog = true;
  601.         end
  602.         QuestGuru_OptionsFrameShowLevelsQuestLogToggle:SetChecked(QuestGuru_Settings.ShowLevels.QuestLog);
  603. end
  604.  
  605.  
  606. function QuestGuru_Echo(msg, always)
  607.     local info = ChatTypeInfo["SYSTEM"];
  608.     if msg == nil then msg = "<nil>"; end
  609. --    if (always) then
  610. --        DEFAULT_CHAT_FRAME:AddMessage("always " .. tostring(always), info.r, info.g, info.b, info.id);
  611. --  else
  612. --        DEFAULT_CHAT_FRAME:AddMessage("not always " .. tostring(always), info.r, info.g, info.b, info.id);
  613. --    end
  614. --    if (QuestGuru_Settings) then
  615. --        DEFAULT_CHAT_FRAME:AddMessage("QuestGuru_Settings", info.r, info.g, info.b, info.id);
  616. --    if (QuestGuru_Settings.DebugLevel) then
  617. --      DEFAULT_CHAT_FRAME:AddMessage("QuestGuru_Settings.DebugLevel = " .. QuestGuru_Settings.DebugLevel, info.r, info.g, info.b, info.id);
  618. --      DEFAULT_CHAT_FRAME:AddMessage(msg, info.r, info.g, info.b, info.id);
  619. --      end
  620. --    end
  621.     if (always or (QuestGuru_Settings and QuestGuru_Settings.DebugLevel and QuestGuru_Settings.DebugLevel > 0)) then
  622.         DEFAULT_CHAT_FRAME:AddMessage(msg, info.r, info.g, info.b, info.id);
  623.     end
  624. end
  625.  
  626.  
  627. --function QuestGuru_Dump(Var2Dump, Label)
  628. --  if ( Label ~= nil ) then
  629. --    DEFAULT_CHAT_FRAME:AddMessage("Dump " .. Label .. ":");
  630. --  end
  631. --  DevTools_Dump(Var2Dump)
  632. --end -- function
  633.  
  634.  
  635. function QuestGuru_QuestFrameGreetingPanel_OnShow()
  636.     local numActiveQuests = GetNumActiveQuests();
  637.     for i=1, numActiveQuests, 1 do
  638.         local questTitleButton = _G["QuestTitleButton"..i];
  639.         local questTitleButtonIcon = _G[questTitleButton:GetName() .. "QuestIcon"];
  640.         local level = GetActiveLevel(i);
  641.         if (level == -1) then level = "*"; end
  642.         local title = GetActiveTitle(i);
  643.         if ( IsActiveQuestTrivial(i) ) then
  644.             questTitleButton:SetFormattedText(TRIVIAL_QUEST_DISPLAY, "["..level.."] "..title);
  645.         else
  646.             questTitleButton:SetFormattedText(NORMAL_QUEST_DISPLAY, "["..level.."] "..title);
  647.         end
  648.         if (QuestGuru_IsQuestComplete(title)) then
  649.             SetDesaturation(questTitleButtonIcon, nil);
  650.         else
  651.             SetDesaturation(questTitleButtonIcon, 1);
  652.         end
  653.     end
  654.  
  655.  
  656.     local numAvailableQuests = GetNumAvailableQuests();
  657.     for i=(numActiveQuests + 1), (numActiveQuests + numAvailableQuests), 1 do
  658.         local questTitleButton = _G["QuestTitleButton"..i];
  659.         local questTitleButtonIcon = _G[questTitleButton:GetName() .. "QuestIcon"];
  660.         local level = GetAvailableLevel(i - numActiveQuests);
  661.         if (level == -1) then level = "*"; end
  662.         local title = GetAvailableTitle(i - numActiveQuests);
  663.         if ( IsAvailableQuestTrivial(i - numActiveQuests) ) then
  664.             questTitleButton:SetFormattedText(TRIVIAL_QUEST_DISPLAY, "["..level.."] "..title);
  665.             questTitleButtonIcon:SetVertexColor(0.5,0.5,0.5);
  666.         else
  667.             questTitleButton:SetFormattedText(NORMAL_QUEST_DISPLAY, "["..level.."] "..title);
  668.             questTitleButtonIcon:SetVertexColor(1,1,1);
  669.         end
  670.     end
  671. end
  672.  
  673.  
  674. function QuestGuru_QuestDetailShow()
  675.     local questTitle = GetTitleText();
  676.     QuestGuru_UpdateDetailFrame(questTitle, GetGossipAvailableQuests());
  677. end
  678.  
  679.  
  680. function QuestGuru_UpdateDetailFrame(questTitle, ...)
  681.     local i;
  682.     for i=1, select("#", ...), 5 do
  683.         if (select(i, ...) == questTitle) then
  684.             QuestInfoTitleHeader:SetText("["..select(i+1, ...).."] "..questTitle);
  685.         end
  686.     end
  687. end
  688.  
  689.  
  690. function QuestGuru_QuestProgressShow()
  691.     local questTitle = GetTitleText();
  692.    
  693.     QuestGuru_UpdateProgressFrame(questTitle, GetGossipActiveQuests());
  694.  
  695.  
  696.     local i;
  697.     for i=1, GetNumQuestItems() do
  698.         local name, texture, numItems, quality, isUsable = GetQuestItemInfo("required", i);
  699.         local link = GetQuestItemLink("required", i);
  700.         if (name and link) then
  701.             QuestGuru_Items[QuestGuru_RealmName][name] = link;
  702.         end
  703.     end
  704. end
  705.  
  706.  
  707. function QuestGuru_UpdateProgressFrame(questTitle, ...)
  708.     local i;
  709.  
  710.  
  711.     for i=1, select("#", ...), 4 do
  712.         if (select(i, ...) == questTitle) then
  713.             QuestProgressTitleText:SetText("["..select(i+1, ...).."] "..questTitle);
  714.         end
  715.     end
  716. end
  717.  
  718.  
  719. function QuestGuru_GossipShow()
  720.     local npc = UnitName("npc");
  721.     QuestGuru_UpdateGossipFrame(1, true, GetGossipAvailableQuests());
  722.     if (GetNumGossipAvailableQuests() > 0) then
  723.         QuestGuru_UpdateGossipFrame(GetNumGossipAvailableQuests() + 2, false, GetGossipActiveQuests());
  724.     else
  725.         QuestGuru_UpdateGossipFrame(1, false, GetGossipActiveQuests());
  726.     end
  727. end
  728.  
  729.  
  730. function QuestGuru_UpdateGossipFrame(currButton, availQuest, ...)
  731.     local i;
  732.    
  733.     --MoP changed this from 4&5 to 5&6.
  734.     local j = 5;
  735.     if (availQuest) then j=6; end
  736.     for i=1, select("#", ...), j do
  737.       --QuestGuru_Echo("level="..i,1)
  738.       local button = _G["GossipTitleButton"..currButton];
  739.       local buttonIcon = _G[button:GetName() .. "GossipIcon"];
  740.       local level = select(i+1, ...);
  741. --QuestGuru_Echo(level, 1)
  742.       if (level == -1) then level = "*"; end
  743.         button:SetFormattedText("[%s] %s", level, select(i, ...));
  744.       if (QuestGuru_IsQuestComplete(select(i, ...)) or availQuest) then
  745.         SetDesaturation(buttonIcon, nil);
  746.       else
  747.         SetDesaturation(buttonIcon, 1);
  748.       end
  749.       currButton = currButton + 1;
  750.     end
  751. --QuestGuru_Echo("bottom", 1)
  752. end
  753.  
  754.  
  755. function QuestGuru_IsQuestComplete(questTitle)
  756.     local numEntries, numQuests = GetNumQuestLogEntries();
  757.     local i;
  758.    
  759.     for i=1, numEntries do
  760.         local questLogTitleText, level, questTag, suggestedGroup, isHeader, isCollapsed, isComplete, isDaily = GetQuestLogTitle(i);
  761.         local numObjectives = GetNumQuestLeaderBoards(i);
  762.  
  763.  
  764.         if (questLogTitleText == questTitle) then return (isComplete or (numObjectives == 0)); end
  765.     end
  766.     return false;
  767. end
  768.  
  769.  
  770. local QuestLogFrameX, QuestLogFrameY;
  771. QuestLogFrame:HookScript("OnShow",
  772.   function(self,button)
  773.     --QuestGuru_Echo("OnShow", 1)
  774.     if (QuestLogFrameX ~= nil and QuestLogFrameY ~= nil) then
  775.       QuestLogFrame:SetPoint("TOPLEFT", QuestLogFrame:GetParent(), "BOTTOMLEFT", QuestLogFrameX, QuestLogFrameY);
  776.     end
  777.   end)
  778.  
  779.  
  780. QuestLogFrame:HookScript("OnHide",
  781.   function(self, button)
  782.     --QuestGuru_Echo("OnHide", 1)
  783.     QuestLogFrameX = QuestLogFrame:GetLeft();
  784.     QuestLogFrameY = QuestLogFrame:GetTop();
  785.   end)
  786.  
  787.  
  788. --Slash Commands are UpperCase, Global, of the form SLASH_<SlashCmdListMemberFunctionName><digit>
  789. local ADirName, A = ...                                    -- ... contains the name of the Addon Directory, which is the name of the addon and an (initially) empty table that is passed to all modules in the directory & sub-directories
  790. function A.SlashHandler(SlashText, OriginatingChatFrame)
  791.   QuestGuru_Echo(format("/qg %s", tostring(SlashText)), true)
  792.   if SlashText == "testui1" then
  793.     QuestGuru_UIInfoMessage("Test UI Info Message 1/3")
  794.   elseif SlashText == "debugon" then
  795.     QuestGuru_Settings.DebugLevel = 1
  796.     QuestGuru_Echo("Debug enabled", true)
  797.   elseif SlashText == "debugoff" then
  798.     QuestGuru_Settings.DebugLevel = 0
  799.     QuestGuru_Echo("Debug disabled", true)
  800.   end
  801. end
  802. SLASH_QG1 = "/qg"                                        -- Slash command 1
  803. SlashCmdList["QG"] = A.SlashHandler                       -- Register our SlashCmdListMemberFunction

QuestGuru.xml
Code:
<?xml version="1.0" encoding="utf-8" ?>
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
    <Script file="QuestGuru.lua" />
    <Button name="QuestGuru_HistoryShowButton" inherits="UIPanelButtonTemplate" text="QG_SHOWHISTORY" parent="QuestLogFrame">
        <Size x="100" y="22"/>
        <Anchors>
            <Anchor point="BOTTOMRIGHT">
                <Offset x="-260" y="13"/>
            </Anchor>
        </Anchors>
        <Scripts>
            <OnClick>
                QuestGuru_ShowHistory();
            </OnClick>
        </Scripts>
    </Button>
    <Button name="QuestGuru_QuestLogObjectiveItem1" inherits="QuestLogObjectiveItemTemplate" hidden="true" parent="QuestInfoObjectivesFrame">
        <Anchors>
            <Anchor point="TOPLEFT"/>
        </Anchors>
    </Button>
    <Button name="QuestGuru_QuestLogObjectiveItem2" inherits="QuestLogObjectiveItemTemplate" hidden="true" parent="QuestInfoObjectivesFrame">
        <Anchors>
            <Anchor point="TOPLEFT"/>
        </Anchors>
    </Button>
    <Button name="QuestGuru_QuestLogObjectiveItem3" inherits="QuestLogObjectiveItemTemplate" hidden="true" parent="QuestInfoObjectivesFrame">
        <Anchors>
            <Anchor point="TOPLEFT"/>
        </Anchors>
    </Button>
    <Button name="QuestGuru_QuestLogObjectiveItem4" inherits="QuestLogObjectiveItemTemplate" hidden="true" parent="QuestInfoObjectivesFrame">
        <Anchors>
            <Anchor point="TOPLEFT"/>
        </Anchors>
    </Button>
    <Button name="QuestGuru_QuestLogObjectiveItem5" inherits="QuestLogObjectiveItemTemplate" hidden="true" parent="QuestInfoObjectivesFrame">
        <Anchors>
            <Anchor point="TOPLEFT"/>
        </Anchors>
    </Button>
    <Button name="QuestGuru_QuestLogObjectiveItem6" inherits="QuestLogObjectiveItemTemplate" hidden="true" parent="QuestInfoObjectivesFrame">
        <Anchors>
            <Anchor point="TOPLEFT"/>
        </Anchors>
    </Button>
    <Button name="QuestGuru_QuestLogObjectiveItem7" inherits="QuestLogObjectiveItemTemplate" hidden="true" parent="QuestInfoObjectivesFrame">
        <Anchors>
            <Anchor point="TOPLEFT"/>
        </Anchors>
    </Button>
    <Button name="QuestGuru_QuestLogObjectiveItem8" inherits="QuestLogObjectiveItemTemplate" hidden="true" parent="QuestInfoObjectivesFrame">
        <Anchors>
            <Anchor point="TOPLEFT"/>
        </Anchors>
    </Button>
    <Button name="QuestGuru_QuestLogObjectiveItem9" inherits="QuestLogObjectiveItemTemplate" hidden="true" parent="QuestInfoObjectivesFrame">
    <Anchors>
        <Anchor point="TOPLEFT"/>
    </Anchors>
    </Button>
    <Button name="QuestGuru_QuestLogObjectiveItem10" inherits="QuestLogObjectiveItemTemplate" hidden="true" parent="QuestInfoObjectivesFrame">
        <Anchors>
            <Anchor point="TOPLEFT"/>
        </Anchors>
    </Button>
</Ui>
QuestGuru_Templates.xml
Code:
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
    <Button name="QuestLogObjectiveItemTemplate" inherits="QuestItemTemplate" virtual="true">
        <Scripts>
            <OnEnter>
                if (( self:GetAlpha() > 0 ) and self.link) then
                    GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
                    GameTooltip:SetHyperlink(self.link);
                    GameTooltip_ShowCompareItem();
                end
                CursorUpdate();
            </OnEnter>
            <OnUpdate>
                if (( self:GetAlpha() > 0 ) and self.link) then
                    if (self.timerEnabled) then
                        local name, link, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, texture = GetItemInfo(self.link);
                        if (texture) then
                            self.timerEnabled = nil;
                            SetItemButtonTexture(self, texture);
                            _G[self:GetName().."Name"]:SetText(name);
                            self:Show();
                        end
                    end
                end
            </OnUpdate>
        </Scripts>
    </Button>


    <Button name="QuestGuru_ColorPickerButtonTemplate" virtual="true">
        <Size x="16" y="16"/>
        <Layers>
            <Layer level="ARTWORK">
                <Texture name="$parentSwatch">
                    <Size x="12" y="12"/>
                    <Anchors>
                        <Anchor point="CENTER">
                            <Offset x="0" y="0"/>
                        </Anchor>
                    </Anchors>
                    <Color r="1.0" g="1.0" b="1.0" a="1.0"/>
                </Texture>
            </Layer>
        </Layers>
        <Scripts>
            <OnEnter>
                if ( self.tooltipText ) then
                    GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
                    GameTooltip:SetText(self.tooltipText, nil, nil, nil, nil, 1);
                end
                if ( self.tooltipRequirement ) then
                    GameTooltip:AddLine(self.tooltipRequirement, "", 1.0, 1.0, 1.0);
                    GameTooltip:Show();
                end
            </OnEnter>
            <OnLeave function="GameTooltip_Hide" />
        </Scripts>
    </Button>


    <Button name="QuestGuru_QuestLogStartFinishTemplate" virtual="true">
        <Size x="285" y="14"/>
        <Layers>
            <Layer level="BACKGROUND">
                <FontString name="$parentLabel" inherits="QuestFont" justifyH="LEFT">
                    <Size x="0" y="0"/>
                    <Anchors>
                        <Anchor point="LEFT">
                            <Offset x="0" y="0"/>
                        </Anchor>
                    </Anchors>
                </FontString>
                <FontString name="$parentPos" inherits="QuestFontNormalSmall" justifyH="LEFT">
                    <Size x="0" y="0"/>
                    <Anchors>
                        <Anchor point="RIGHT">
                            <Offset x="0" y="0"/>
                        </Anchor>
                    </Anchors>
                </FontString>
            </Layer>
        </Layers>
        <Scripts>
            <OnLeave>
                QuestGuru_QuestStartInfoFrame:Hide();
            </OnLeave>
        </Scripts>
        <ButtonText name="$parentNPCName" nonspacewrap="true">
            <Size x="0" y="10"/>
            <Anchors>
                <Anchor point="LEFT" relativeTo="$parentLabel" relativePoint="RIGHT">
                    <Offset x="2" y="0"/>
                </Anchor>
            </Anchors> 
        </ButtonText>
        <NormalFont style="QuestFontLeft" />
        <HighlightFont style="QuestFontLeft" />
        <DisabledFont style="QuestFontLeft" />
    </Button>
    
    <CheckButton name="QuestGuru_InterfaceOptionsBaseCheckButtonTemplate" virtual="true">
        <Size x="26" y="26"/>
        <HitRectInsets>
            <AbsInset left="0" right="-100" top="0" bottom="0"/>
        </HitRectInsets>
        <Scripts>
            <OnShow>
                self:SetHitRectInsets(0, -_G[self:GetName().."Text"]:GetWidth(), 0, 0);
            </OnShow>
            <OnMouseUp>
                if ( self:GetChecked() ) then
                    PlaySound("igMainMenuOptionCheckBoxOn");
                else
                    PlaySound("igMainMenuOptionCheckBoxOff");
                end
            </OnMouseUp>
            <OnEnter>
                if ( self.tooltipText ) then
                    GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
                    GameTooltip:SetText(self.tooltipText, nil, nil, nil, nil, 1);
                end
                if ( self.tooltipRequirement ) then
                    GameTooltip:AddLine(self.tooltipRequirement, "", 1.0, 1.0, 1.0);
                    GameTooltip:Show();
                end
            </OnEnter>
            <OnLeave function="GameTooltip_Hide" />
        </Scripts>
        <NormalTexture file="Interface\Buttons\UI-CheckBox-Up"/>
        <PushedTexture file="Interface\Buttons\UI-CheckBox-Down"/>
         <HighlightTexture file="Interface\Buttons\UI-CheckBox-Highlight" alphaMode="ADD"/>
        <CheckedTexture file="Interface\Buttons\UI-CheckBox-Check"/>
        <DisabledCheckedTexture file="Interface\Buttons\UI-CheckBox-Check-Disabled"/>        
    </CheckButton>
    <CheckButton name="QuestGuru_InterfaceOptionsCheckButtonTemplate" virtual="true" inherits="QuestGuru_InterfaceOptionsBaseCheckButtonTemplate">
        <Layers>
            <Layer level="ARTWORK">
                <FontString name="$parentText" inherits="GameFontHighlight">
                    <Anchors>
                        <Anchor point="LEFT" relativePoint="RIGHT">
                            <Offset x="0" y="1" />
                        </Anchor>
                    </Anchors>
                </FontString>
            </Layer>
        </Layers>
    </CheckButton>
    <CheckButton name="QuestGuru_InterfaceOptionsSmallCheckButtonTemplate" virtual="true" inherits="QuestGuru_InterfaceOptionsBaseCheckButtonTemplate">
        <Layers>
            <Layer level="ARTWORK">
                <FontString name="$parentText" inherits="GameFontNormalSmall">
                    <Anchors>
                        <Anchor point="LEFT" relativePoint="RIGHT">
                            <Offset x="0" y="1" />
                        </Anchor>
                    </Anchors>
                </FontString>
            </Layer>
        </Layers>
    </CheckButton>
</Ui>
ChatThrottleLib.lua
lua Code:
  1. --
  2. -- ChatThrottleLib by Mikk
  3. --
  4. -- Manages AddOn chat output to keep player from getting kicked off.
  5. --
  6. -- ChatThrottleLib:SendChatMessage/:SendAddonMessage functions that accept
  7. -- a Priority ("BULK", "NORMAL", "ALERT") as well as prefix for SendChatMessage.
  8. --
  9. -- Priorities get an equal share of available bandwidth when fully loaded.
  10. -- Communication channels are separated on extension+chattype+destination and
  11. -- get round-robinned. (Destination only matters for whispers and channels,
  12. -- obviously)
  13. --
  14. -- Will install hooks for SendChatMessage and SendAddonMessage to measure
  15. -- bandwidth bypassing the library and use less bandwidth itself.
  16. --
  17. --
  18. -- Fully embeddable library. Just copy this file into your addon directory,
  19. -- add it to the .toc, and it's done.
  20. --
  21. -- Can run as a standalone addon also, but, really, just embed it! :-)
  22. --
  23.  
  24.  
  25. local CTL_VERSION = 21
  26.  
  27.  
  28. local _G = _G
  29.  
  30.  
  31. if _G.ChatThrottleLib then
  32.     if _G.ChatThrottleLib.version >= CTL_VERSION then
  33.         -- There's already a newer (or same) version loaded. Buh-bye.
  34.         return
  35.     elseif not _G.ChatThrottleLib.securelyHooked then
  36.         print("ChatThrottleLib: Warning: There's an ANCIENT ChatThrottleLib.lua (pre-wow 2.0, <v16) in an addon somewhere. Get the addon updated or copy in a newer ChatThrottleLib.lua (>=v16) in it!")
  37.         -- ATTEMPT to unhook; this'll behave badly if someone else has hooked...
  38.         -- ... and if someone has securehooked, they can kiss that goodbye too... >.<
  39.         _G.SendChatMessage = _G.ChatThrottleLib.ORIG_SendChatMessage
  40.         if _G.ChatThrottleLib.ORIG_SendAddonMessage then
  41.             _G.SendAddonMessage = _G.ChatThrottleLib.ORIG_SendAddonMessage
  42.         end
  43.     end
  44.     _G.ChatThrottleLib.ORIG_SendChatMessage = nil
  45.     _G.ChatThrottleLib.ORIG_SendAddonMessage = nil
  46. end
  47.  
  48.  
  49. if not _G.ChatThrottleLib then
  50.     _G.ChatThrottleLib = {}
  51. end
  52.  
  53.  
  54. ChatThrottleLib = _G.ChatThrottleLib  -- in case some addon does "local ChatThrottleLib" above us and we're copypasted (AceComm-2, sigh)
  55. local ChatThrottleLib = _G.ChatThrottleLib
  56.  
  57.  
  58. ChatThrottleLib.version = CTL_VERSION
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65. ------------------ TWEAKABLES -----------------
  66.  
  67.  
  68. ChatThrottleLib.MAX_CPS = 800              -- 2000 seems to be safe if NOTHING ELSE is happening. let's call it 800.
  69. ChatThrottleLib.MSG_OVERHEAD = 40        -- Guesstimate overhead for sending a message; source+dest+chattype+protocolstuff
  70.  
  71.  
  72. ChatThrottleLib.BURST = 4000                -- WoW's server buffer seems to be about 32KB. 8KB should be safe, but seen disconnects on _some_ servers. Using 4KB now.
  73.  
  74.  
  75. ChatThrottleLib.MIN_FPS = 20                -- Reduce output CPS to half (and don't burst) if FPS drops below this value
  76.  
  77.  
  78.  
  79.  
  80. local setmetatable = setmetatable
  81. local table_remove = table.remove
  82. local tostring = tostring
  83. local GetTime = GetTime
  84. local math_min = math.min
  85. local math_max = math.max
  86. local next = next
  87. local strlen = string.len
  88. local GetFrameRate = GetFrameRate
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95. -----------------------------------------------------------------------
  96. -- Double-linked ring implementation
  97.  
  98.  
  99. local Ring = {}
  100. local RingMeta = { __index = Ring }
  101.  
  102.  
  103. function Ring:New()
  104.     local ret = {}
  105.     setmetatable(ret, RingMeta)
  106.     return ret
  107. end
  108.  
  109.  
  110. function Ring:Add(obj)    -- Append at the "far end" of the ring (aka just before the current position)
  111.     if self.pos then
  112.         obj.prev = self.pos.prev
  113.         obj.prev.next = obj
  114.         obj.next = self.pos
  115.         obj.next.prev = obj
  116.     else
  117.         obj.next = obj
  118.         obj.prev = obj
  119.         self.pos = obj
  120.     end
  121. end
  122.  
  123.  
  124. function Ring:Remove(obj)
  125.     obj.next.prev = obj.prev
  126.     obj.prev.next = obj.next
  127.     if self.pos == obj then
  128.         self.pos = obj.next
  129.         if self.pos == obj then
  130.             self.pos = nil
  131.         end
  132.     end
  133. end
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140. -----------------------------------------------------------------------
  141. -- Recycling bin for pipes
  142. -- A pipe is a plain integer-indexed queue, which also happens to be a ring member
  143.  
  144.  
  145. ChatThrottleLib.PipeBin = nil -- pre-v19, drastically different
  146. local PipeBin = setmetatable({}, {__mode="k"})
  147.  
  148.  
  149. local function DelPipe(pipe)
  150.     for i = #pipe, 1, -1 do
  151.         pipe[i] = nil
  152.     end
  153.     pipe.prev = nil
  154.     pipe.next = nil
  155.  
  156.  
  157.     PipeBin[pipe] = true
  158. end
  159.  
  160.  
  161. local function NewPipe()
  162.     local pipe = next(PipeBin)
  163.     if pipe then
  164.         PipeBin[pipe] = nil
  165.         return pipe
  166.     end
  167.     return {}
  168. end
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177. -----------------------------------------------------------------------
  178. -- Recycling bin for messages
  179.  
  180.  
  181. ChatThrottleLib.MsgBin = nil -- pre-v19, drastically different
  182. local MsgBin = setmetatable({}, {__mode="k"})
  183.  
  184.  
  185. local function DelMsg(msg)
  186.     msg[1] = nil
  187.     -- there's more parameters, but they're very repetetive so the string pool doesn't suffer really, and it's faster to just not delete them.
  188.     MsgBin[msg] = true
  189. end
  190.  
  191.  
  192. local function NewMsg()
  193.     local msg = next(MsgBin)
  194.     if msg then
  195.         MsgBin[msg] = nil
  196.         return msg
  197.     end
  198.     return {}
  199. end
  200.  
  201.  
  202.  
  203.  
  204. -----------------------------------------------------------------------
  205. -- ChatThrottleLib:Init
  206. -- Initialize queues, set up frame for OnUpdate, etc
  207.  
  208.  
  209.  
  210.  
  211. function ChatThrottleLib:Init()    
  212.  
  213.  
  214.     -- Set up queues
  215.     if not self.Prio then
  216.         self.Prio = {}
  217.         self.Prio["ALERT"] = { ByName = {}, Ring = Ring:New(), avail = 0 }
  218.         self.Prio["NORMAL"] = { ByName = {}, Ring = Ring:New(), avail = 0 }
  219.         self.Prio["BULK"] = { ByName = {}, Ring = Ring:New(), avail = 0 }
  220.     end
  221.  
  222.  
  223.     -- v4: total send counters per priority
  224.     for _, Prio in pairs(self.Prio) do
  225.         Prio.nTotalSent = Prio.nTotalSent or 0
  226.     end
  227.  
  228.  
  229.     if not self.avail then
  230.         self.avail = 0 -- v5
  231.     end
  232.     if not self.nTotalSent then
  233.         self.nTotalSent = 0 -- v5
  234.     end
  235.  
  236.  
  237.  
  238.  
  239.     -- Set up a frame to get OnUpdate events
  240.     if not self.Frame then
  241.         self.Frame = CreateFrame("Frame")
  242.         self.Frame:Hide()
  243.     end
  244.     self.Frame:SetScript("OnUpdate", self.OnUpdate)
  245.     self.Frame:SetScript("OnEvent", self.OnEvent)    -- v11: Monitor P_E_W so we can throttle hard for a few seconds
  246.     self.Frame:RegisterEvent("PLAYER_ENTERING_WORLD")
  247.     self.OnUpdateDelay = 0
  248.     self.LastAvailUpdate = GetTime()
  249.     self.HardThrottlingBeginTime = GetTime()    -- v11: Throttle hard for a few seconds after startup
  250.  
  251.  
  252.     -- Hook SendChatMessage and SendAddonMessage so we can measure unpiped traffic and avoid overloads (v7)
  253.     if not self.securelyHooked then
  254.         -- Use secure hooks as of v16. Old regular hook support yanked out in v21.
  255.         self.securelyHooked = true
  256.         --SendChatMessage
  257.         hooksecurefunc("SendChatMessage", function(...)
  258.             return ChatThrottleLib.Hook_SendChatMessage(...)
  259.         end)
  260.         --SendAddonMessage
  261.         hooksecurefunc("SendAddonMessage", function(...)
  262.             return ChatThrottleLib.Hook_SendAddonMessage(...)
  263.         end)
  264.     end
  265.     self.nBypass = 0
  266. end
  267.  
  268.  
  269.  
  270.  
  271. -----------------------------------------------------------------------
  272. -- ChatThrottleLib.Hook_SendChatMessage / .Hook_SendAddonMessage
  273.  
  274.  
  275. local bMyTraffic = false
  276.  
  277.  
  278. function ChatThrottleLib.Hook_SendChatMessage(text, chattype, language, destination, ...)
  279.     if bMyTraffic then
  280.         return
  281.     end
  282.     local self = ChatThrottleLib
  283.     local size = strlen(tostring(text or "")) + strlen(tostring(destination or "")) + self.MSG_OVERHEAD
  284.     self.avail = self.avail - size
  285.     self.nBypass = self.nBypass + size    -- just a statistic
  286. end
  287. function ChatThrottleLib.Hook_SendAddonMessage(prefix, text, chattype, destination, ...)
  288.     if bMyTraffic then
  289.         return
  290.     end
  291.     local self = ChatThrottleLib
  292.     local size = tostring(text or ""):len() + tostring(prefix or ""):len();
  293.     size = size + tostring(destination or ""):len() + self.MSG_OVERHEAD
  294.     self.avail = self.avail - size
  295.     self.nBypass = self.nBypass + size    -- just a statistic
  296. end
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303. -----------------------------------------------------------------------
  304. -- ChatThrottleLib:UpdateAvail
  305. -- Update self.avail with how much bandwidth is currently available
  306.  
  307.  
  308. function ChatThrottleLib:UpdateAvail()
  309.     local now = GetTime()
  310.     local MAX_CPS = self.MAX_CPS;
  311.     local newavail = MAX_CPS * (now - self.LastAvailUpdate)
  312.     local avail = self.avail
  313.  
  314.  
  315.     if now - self.HardThrottlingBeginTime < 5 then
  316.         -- First 5 seconds after startup/zoning: VERY hard clamping to avoid irritating the server rate limiter, it seems very cranky then
  317.         avail = math_min(avail + (newavail*0.1), MAX_CPS*0.5)
  318.         self.bChoking = true
  319.     elseif GetFramerate() < self.MIN_FPS then        -- GetFrameRate call takes ~0.002 secs
  320.         avail = math_min(MAX_CPS, avail + newavail*0.5)
  321.         self.bChoking = true        -- just a statistic
  322.     else
  323.         avail = math_min(self.BURST, avail + newavail)
  324.         self.bChoking = false
  325.     end
  326.  
  327.  
  328.     avail = math_max(avail, 0-(MAX_CPS*2))    -- Can go negative when someone is eating bandwidth past the lib. but we refuse to stay silent for more than 2 seconds; if they can do it, we can.
  329.  
  330.  
  331.     self.avail = avail
  332.     self.LastAvailUpdate = now
  333.  
  334.  
  335.     return avail
  336. end
  337.  
  338.  
  339.  
  340.  
  341. -----------------------------------------------------------------------
  342. -- Despooling logic
  343.  
  344.  
  345. function ChatThrottleLib:Despool(Prio)
  346.     local ring = Prio.Ring
  347.     while ring.pos and Prio.avail > ring.pos[1].nSize do
  348.         local msg = table_remove(Prio.Ring.pos, 1)
  349.         if not Prio.Ring.pos[1] then
  350.             local pipe = Prio.Ring.pos
  351.             Prio.Ring:Remove(pipe)
  352.             Prio.ByName[pipe.name] = nil
  353.             DelPipe(pipe)
  354.         else
  355.             Prio.Ring.pos = Prio.Ring.pos.next
  356.         end
  357.         Prio.avail = Prio.avail - msg.nSize
  358.         bMyTraffic = true
  359.         msg.f(unpack(msg, 1, msg.n))
  360.         bMyTraffic = false
  361.         Prio.nTotalSent = Prio.nTotalSent + msg.nSize
  362.         DelMsg(msg)
  363.         if msg.callbackFn then
  364.             msg.callbackFn (msg.callbackArg)
  365.         end
  366.     end
  367. end
  368.  
  369.  
  370.  
  371.  
  372. function ChatThrottleLib.OnEvent(this,event)
  373.     -- v11: We know that the rate limiter is touchy after login. Assume that it's touchy after zoning, too.
  374.     local self = ChatThrottleLib
  375.     if event == "PLAYER_ENTERING_WORLD" then
  376.         self.HardThrottlingBeginTime = GetTime()    -- Throttle hard for a few seconds after zoning
  377.         self.avail = 0
  378.     end
  379. end
  380.  
  381.  
  382.  
  383.  
  384. function ChatThrottleLib.OnUpdate(this,delay)
  385.     local self = ChatThrottleLib
  386.  
  387.  
  388.     self.OnUpdateDelay = self.OnUpdateDelay + delay
  389.     if self.OnUpdateDelay < 0.08 then
  390.         return
  391.     end
  392.     self.OnUpdateDelay = 0
  393.  
  394.  
  395.     self:UpdateAvail()
  396.  
  397.  
  398.     if self.avail < 0  then
  399.         return -- argh. some bastard is spewing stuff past the lib. just bail early to save cpu.
  400.     end
  401.  
  402.  
  403.     -- See how many of our priorities have queued messages (we only have 3, don't worry about the loop)
  404.     local n = 0
  405.     for prioname,Prio in pairs(self.Prio) do
  406.         if Prio.Ring.pos or Prio.avail < 0 then
  407.             n = n + 1
  408.         end
  409.     end
  410.  
  411.  
  412.     -- Anything queued still?
  413.     if n<1 then
  414.         -- Nope. Move spillover bandwidth to global availability gauge and clear self.bQueueing
  415.         for prioname, Prio in pairs(self.Prio) do
  416.             self.avail = self.avail + Prio.avail
  417.             Prio.avail = 0
  418.         end
  419.         self.bQueueing = false
  420.         self.Frame:Hide()
  421.         return
  422.     end
  423.  
  424.  
  425.     -- There's stuff queued. Hand out available bandwidth to priorities as needed and despool their queues
  426.     local avail = self.avail/n
  427.     self.avail = 0
  428.  
  429.  
  430.     for prioname, Prio in pairs(self.Prio) do
  431.         if Prio.Ring.pos or Prio.avail < 0 then
  432.             Prio.avail = Prio.avail + avail
  433.             if Prio.Ring.pos and Prio.avail > Prio.Ring.pos[1].nSize then
  434.                 self:Despool(Prio)
  435.                 -- Note: We might not get here if the user-supplied callback function errors out! Take care!
  436.             end
  437.         end
  438.     end
  439.  
  440.  
  441. end
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450. -----------------------------------------------------------------------
  451. -- Spooling logic
  452.  
  453.  
  454.  
  455.  
  456. function ChatThrottleLib:Enqueue(prioname, pipename, msg)
  457.     local Prio = self.Prio[prioname]
  458.     local pipe = Prio.ByName[pipename]
  459.     if not pipe then
  460.         self.Frame:Show()
  461.         pipe = NewPipe()
  462.         pipe.name = pipename
  463.         Prio.ByName[pipename] = pipe
  464.         Prio.Ring:Add(pipe)
  465.     end
  466.  
  467.  
  468.     pipe[#pipe + 1] = msg
  469.  
  470.  
  471.     self.bQueueing = true
  472. end
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479. function ChatThrottleLib:SendChatMessage(prio, prefix,   text, chattype, language, destination, queueName, callbackFn, callbackArg)
  480.     if not self or not prio or not prefix or not text or not self.Prio[prio] then
  481.         error('Usage: ChatThrottleLib:SendChatMessage("{BULK||NORMAL||ALERT}", "prefix", "text"[, "chattype"[, "language"[, "destination"]]]', 2)
  482.     end
  483.     if callbackFn and type(callbackFn)~="function" then
  484.         error('ChatThrottleLib:ChatMessage(): callbackFn: expected function, got '..type(callbackFn), 2)
  485.     end
  486.  
  487.  
  488.     local nSize = text:len()
  489.  
  490.  
  491.     if nSize>255 then
  492.         error("ChatThrottleLib:SendChatMessage(): message length cannot exceed 255 bytes", 2)
  493.     end
  494.  
  495.  
  496.     nSize = nSize + self.MSG_OVERHEAD
  497.  
  498.  
  499.     -- Check if there's room in the global available bandwidth gauge to send directly
  500.     if not self.bQueueing and nSize < self:UpdateAvail() then
  501.         self.avail = self.avail - nSize
  502.         bMyTraffic = true
  503.         _G.SendChatMessage(text, chattype, language, destination)
  504.         bMyTraffic = false
  505.         self.Prio[prio].nTotalSent = self.Prio[prio].nTotalSent + nSize
  506.         if callbackFn then
  507.             callbackFn (callbackArg)
  508.         end
  509.         return
  510.     end
  511.  
  512.  
  513.     -- Message needs to be queued
  514.     local msg = NewMsg()
  515.     msg.f = _G.SendChatMessage
  516.     msg[1] = text
  517.     msg[2] = chattype or "SAY"
  518.     msg[3] = language
  519.     msg[4] = destination
  520.     msg.n = 4
  521.     msg.nSize = nSize
  522.     msg.callbackFn = callbackFn
  523.     msg.callbackArg = callbackArg
  524.  
  525.  
  526.     self:Enqueue(prio, queueName or (prefix..(chattype or "SAY")..(destination or "")), msg)
  527. end
  528.  
  529.  
  530.  
  531.  
  532. function ChatThrottleLib:SendAddonMessage(prio, prefix, text, chattype, target, queueName, callbackFn, callbackArg)
  533.     if not self or not prio or not prefix or not text or not chattype or not self.Prio[prio] then
  534.         error('Usage: ChatThrottleLib:SendAddonMessage("{BULK||NORMAL||ALERT}", "prefix", "text", "chattype"[, "target"])', 2)
  535.     end
  536.     if callbackFn and type(callbackFn)~="function" then
  537.         error('ChatThrottleLib:SendAddonMessage(): callbackFn: expected function, got '..type(callbackFn), 2)
  538.     end
  539.  
  540.  
  541.     local nSize = prefix:len() + 1 + text:len();
  542.  
  543.  
  544.     if nSize>255 then
  545.         error("ChatThrottleLib:SendAddonMessage(): prefix + message length cannot exceed 254 bytes", 2)
  546.     end
  547.  
  548.  
  549.     nSize = nSize + self.MSG_OVERHEAD;
  550.  
  551.  
  552.     -- Check if there's room in the global available bandwidth gauge to send directly
  553.     if not self.bQueueing and nSize < self:UpdateAvail() then
  554.         self.avail = self.avail - nSize
  555.         bMyTraffic = true
  556.         _G.SendAddonMessage(prefix, text, chattype, target)
  557.         bMyTraffic = false
  558.         self.Prio[prio].nTotalSent = self.Prio[prio].nTotalSent + nSize
  559.         if callbackFn then
  560.             callbackFn (callbackArg)
  561.         end
  562.         return
  563.     end
  564.  
  565.  
  566.     -- Message needs to be queued
  567.     local msg = NewMsg()
  568.     msg.f = _G.SendAddonMessage
  569.     msg[1] = prefix
  570.     msg[2] = text
  571.     msg[3] = chattype
  572.     msg[4] = target
  573.     msg.n = (target~=nil) and 4 or 3;
  574.     msg.nSize = nSize
  575.     msg.callbackFn = callbackFn
  576.     msg.callbackArg = callbackArg
  577.  
  578.  
  579.     self:Enqueue(prio, queueName or (prefix..chattype..(target or "")), msg)
  580. end
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589. -----------------------------------------------------------------------
  590. -- Get the ball rolling!
  591.  
  592.  
  593. ChatThrottleLib:Init()
  594.  
  595.  
  596. --[[ WoWBench debugging snippet
  597. if(WOWB_VER) then
  598.     local function SayTimer()
  599.         print("SAY: "..GetTime().." "..arg1)
  600.     end
  601.     ChatThrottleLib.Frame:SetScript("OnEvent", SayTimer)
  602.     ChatThrottleLib.Frame:RegisterEvent("CHAT_MSG_SAY")
  603. end
  604. ]]


QuestGuruOptions.lua (I do know that I have to change the one mp3 sound file to ogg)
lua Code:
  1. local lastColorPick;
  2.  
  3.  
  4. QuestGuru_Sounds = {"PVPENTERQUEUE","PVPTHROUGHQUEUE","GLUECREATECHARACTERBUTTON","GLUEENTERWORLDBUTTON","QUESTCOMPLETED","INTERFACESOUND_MONEYFRAMEOPEN",
  5. "igPlayerInvite","LEVELUP","QUESTADDED","gsCharacterCreationCreateChar","TalentScreenOpen","ReadyCheck","RaidWarning","AuctionWindowOpen","AuctionWindowClose",
  6. "Sound\\Creature\\Peon\\PeonBuildingComplete1.wav", "Sound\\Creature\\Peon\\PeonReady1.wav", "Sound\\Creature\\Peasant\\PeasantReady1.wav", "Sound\\Interface\\igPlayerBind.wav",
  7. "Sound\\Creature\\MillhouseManastorm\\TEMPEST_Millhouse_Ready01.wav", "Sound\\Creature\\MillhouseManastorm\\TEMPEST_Millhouse_Slay01.wav", "Sound\\Creature\\Cow\\CowDeath.wav",
  8. "Sound\\interface\\HumanExploration.wav","Sound\\Creature\\Peasant\\PeasantWhat3.wav", "Sound\\Creature\\Peon\\PeonYes3.wav", "Sound\\Creature\\Peon\\PeonWhat4.wav",
  9. "Interface\\AddOns\\QuestGuru\\Peasant_job_done.mp3"};
  10.  
  11.  
  12. function QuestGuru_OptionsFrameSoundProgressDropDown_Initialize()
  13.     if (QuestGuru_Settings.Sounds == nil) then return; end
  14.     local info = UIDropDownMenu_CreateInfo();
  15.     info.func = QuestGuru_OptionsFrameSoundProgress_OnClick;
  16.     info.owner = QuestGuru_OptionsFrameSoundProgressButton;
  17.     info.checked = nil;
  18.     info.icon = nil;
  19.  
  20.  
  21.     for i,v in ipairs(QuestGuru_Sounds) do
  22.         info.text = v;
  23.         info.value = i;
  24.         if (v == QuestGuru_Settings.Sounds.Progress.Sound) then
  25.             info.checked = 1;
  26.         else
  27.             info.checked = nil;
  28.         end
  29.         UIDropDownMenu_AddButton(info, 1);
  30.     end
  31.     UIDropDownMenu_SetText(QuestGuru_OptionsFrameSoundProgressButton, QuestGuru_Settings.Sounds.Progress.Sound);
  32. end
  33.  
  34.  
  35. function QuestGuru_OptionsFrameSoundProgress_OnClick(self, button, down)
  36.     if (QuestGuru_Settings.Sounds == nil) then return; end
  37.     local sound = QuestGuru_Sounds[self.value];
  38.     if ((string.sub(sound, -4) == ".wav") or (string.sub(sound, -4) == ".mp3")) then
  39.         PlaySoundFile(sound);
  40.     else
  41.         PlaySound(sound);
  42.     end
  43.     UIDropDownMenu_SetText(QuestGuru_OptionsFrameSoundProgressButton, sound);
  44.     QuestGuru_Settings.Sounds.Progress.Sound = sound;
  45. end
  46.  
  47.  
  48. function QuestGuru_OptionsFrameSoundObjCompleteDropDown_Initialize()
  49.     if (QuestGuru_Settings.Sounds == nil) then return; end
  50.     local info = UIDropDownMenu_CreateInfo();
  51.     info.func = QuestGuru_OptionsFrameSoundObjComplete_OnClick;
  52.     info.owner = QuestGuru_OptionsFrameSoundObjCompleteButton;
  53.     info.checked = nil;
  54.     info.icon = nil;
  55.  
  56.  
  57.     for i,v in ipairs(QuestGuru_Sounds) do
  58.         info.text = v;
  59.         info.value = i;
  60.         if (v == QuestGuru_Settings.Sounds.ObjComplete.Sound) then
  61.             info.checked = 1;
  62.         else
  63.             info.checked = nil;
  64.         end
  65.         UIDropDownMenu_AddButton(info, 1);
  66.     end
  67.     UIDropDownMenu_SetText(QuestGuru_OptionsFrameSoundObjCompleteButton, QuestGuru_Settings.Sounds.ObjComplete.Sound);
  68. end
  69.  
  70.  
  71. function QuestGuru_OptionsFrameSoundObjComplete_OnClick(self, button, down)
  72.     if (QuestGuru_Settings.Sounds == nil) then return; end
  73.     local sound = QuestGuru_Sounds[self.value];
  74.     if ((string.sub(sound, -4) == ".wav") or (string.sub(sound, -4) == ".mp3")) then
  75.         PlaySoundFile(sound);
  76.     else
  77.         PlaySound(sound);
  78.     end
  79.     UIDropDownMenu_SetText(QuestGuru_OptionsFrameSoundObjCompleteButton, sound);
  80.     QuestGuru_Settings.Sounds.ObjComplete.Sound = sound;
  81. end
  82.  
  83.  
  84. function QuestGuru_OptionsFrameSoundQuestCompleteDropDown_Initialize()
  85.     if (QuestGuru_Settings.Sounds == nil) then return; end
  86.     local info = UIDropDownMenu_CreateInfo();
  87.     info.func = QuestGuru_OptionsFrameSoundQuestComplete_OnClick;
  88.     info.owner = QuestGuru_OptionsFrameSoundQuestCompleteButton;
  89.     info.checked = nil;
  90.     info.icon = nil;
  91.  
  92.  
  93.     for i,v in ipairs(QuestGuru_Sounds) do
  94.         info.text = v;
  95.         info.value = i;
  96.         if (v == QuestGuru_Settings.Sounds.QuestComplete.Sound) then
  97.             info.checked = 1;
  98.         else
  99.             info.checked = nil;
  100.         end
  101.         UIDropDownMenu_AddButton(info, 1);
  102.     end
  103.     UIDropDownMenu_SetText(QuestGuru_OptionsFrameSoundQuestCompleteButton, QuestGuru_Settings.Sounds.QuestComplete.Sound);
  104. end
  105.  
  106.  
  107. function QuestGuru_OptionsFrameSoundQuestComplete_OnClick(self, button, down)
  108.     if (QuestGuru_Settings.Sounds == nil) then return; end
  109.     local sound = QuestGuru_Sounds[self.value];
  110.     if ((string.sub(sound, -4) == ".wav") or (string.sub(sound, -4) == ".mp3")) then
  111.         PlaySoundFile(sound);
  112.     else
  113.         PlaySound(sound);
  114.     end
  115.     UIDropDownMenu_SetText(QuestGuru_OptionsFrameSoundQuestCompleteButton, sound);
  116.     QuestGuru_Settings.Sounds.QuestComplete.Sound = sound;
  117. end
  118.  
  119.  
  120. do
  121.     local temp, i;
  122.  
  123.  
  124. ---------------------
  125. -- General Options --
  126. ---------------------
  127.     QuestGuru_OptionsFrameGeneral = CreateFrame("FRAME", "QuestGuru_OptionsFrameGeneral", QuestGuru_OptionsFrame);
  128.     QuestGuru_OptionsFrameGeneral.name = "QuestGuru";
  129.     QuestGuru_OptionsFrameGeneral.default = function () QuestGuru_SetGeneralDefaults(); end;
  130.     InterfaceOptions_AddCategory(QuestGuru_OptionsFrameGeneral);
  131.  
  132.  
  133.     QuestGuru_OptionsFrameGeneralTitle = QuestGuru_OptionsFrameGeneral:CreateFontString("QuestGuru_OptionsFrameGeneralTitle", "ARTWORK", "GameFontNormalLarge");
  134.     QuestGuru_OptionsFrameGeneralTitle:SetPoint("TOPLEFT", 16, -16);
  135.     QuestGuru_OptionsFrameGeneralTitle:SetJustifyH("LEFT");
  136.     QuestGuru_OptionsFrameGeneralTitle:SetJustifyV("TOP");
  137.     QuestGuru_OptionsFrameGeneralTitle:SetText("QuestGuru "..QG_OPTIONS);
  138.  
  139.  
  140.     QuestGuru_OptionsFrameGeneralSubText = QuestGuru_OptionsFrameGeneral:CreateFontString("QuestGuru_OptionsFrameGeneralSubText", "ARTWORK", "GameFontHighlightSmall");
  141.     QuestGuru_OptionsFrameGeneralSubText:SetPoint("TOPLEFT", "QuestGuru_OptionsFrameGeneralTitle", "BOTTOMLEFT", 0, -8);
  142.     QuestGuru_OptionsFrameGeneralSubText:SetPoint("RIGHT", -32, 0);
  143.     QuestGuru_OptionsFrameGeneralSubText:SetJustifyH("LEFT");
  144.     QuestGuru_OptionsFrameGeneralSubText:SetJustifyV("TOP");
  145.     QuestGuru_OptionsFrameGeneralSubText:SetHeight(24);
  146.     QuestGuru_OptionsFrameGeneralSubText:SetText(QG_OPT_OPTIONS_DESC);
  147.  
  148.  
  149.     QuestGuru_OptionsFrameGeneralShowLevels = QuestGuru_OptionsFrameGeneral:CreateFontString("QuestGuru_OptionsFrameGeneralShowLevels", "OVERLAY", "GameFontHighlight");
  150.     QuestGuru_OptionsFrameGeneralShowLevels:SetPoint("TOPLEFT", "QuestGuru_OptionsFrameGeneralSubText", "BOTTOMLEFT", -2, -8);
  151.     QuestGuru_OptionsFrameGeneralShowLevels:SetText(QG_OPT_LEVELS_HEAD);
  152.  
  153.  
  154.     QuestGuru_OptionsFrameShowLevelsQuestLogToggle = CreateFrame("CheckButton", "QuestGuru_OptionsFrameShowLevelsQuestLogToggle", QuestGuru_OptionsFrameGeneral, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  155.     QuestGuru_OptionsFrameShowLevelsQuestLogToggle:SetPoint("TOPLEFT", QuestGuru_OptionsFrameGeneralShowLevels, "BOTTOMLEFT", 0, -2);
  156.     QuestGuru_OptionsFrameShowLevelsQuestLogToggleText:SetText(QG_OPT_LEVELS_QUESTLOG);
  157.     QuestGuru_OptionsFrameShowLevelsQuestLogToggle:SetScript("OnClick",
  158.         function ()
  159.             if (QuestGuru_OptionsFrameShowLevelsQuestLogToggle:GetChecked()) then
  160.                 QuestGuru_Settings.ShowLevels.QuestLog = true;
  161.             else
  162.                 QuestGuru_Settings.ShowLevels.QuestLog = false;
  163.             end
  164.             QuestLog_Update();
  165.         end);
  166.  
  167.  
  168.     QuestGuru_OptionsFrameAutoCompleteToggle = CreateFrame("CheckButton", "QuestGuru_OptionsFrameAutoCompleteToggle", QuestGuru_OptionsFrameGeneral, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  169.     QuestGuru_OptionsFrameAutoCompleteToggle:SetPoint("TOPLEFT", QuestGuru_OptionsFrameShowLevelsQuestLogToggle, "BOTTOMLEFT", 0, -6);
  170.     QuestGuru_OptionsFrameAutoCompleteToggleText:SetText(QG_OPT_AUTOCOMPLETE);
  171.     QuestGuru_OptionsFrameAutoCompleteToggle:SetScript("OnClick",
  172.         function ()
  173.             if (QuestGuru_OptionsFrameAutoCompleteToggle:GetChecked()) then
  174.                 QuestGuru_Settings.AutoComplete = true;
  175.             else
  176.                 QuestGuru_Settings.AutoComplete = false;
  177.             end
  178.         end);
  179.  
  180.  
  181.     QuestGuru_OptionsFrameShowObjItemIconsToggle = CreateFrame("CheckButton", "QuestGuru_OptionsFrameShowObjItemIconsToggle", QuestGuru_OptionsFrameGeneral, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  182.     QuestGuru_OptionsFrameShowObjItemIconsToggle:SetPoint("TOPLEFT", QuestGuru_OptionsFrameAutoCompleteToggle, "BOTTOMLEFT", 0, -4);
  183.     QuestGuru_OptionsFrameShowObjItemIconsToggleText:SetText(QG_OPT_OBJ_ICON);
  184.     QuestGuru_OptionsFrameShowObjItemIconsToggle:SetScript("OnClick",
  185.         function ()
  186.             if (QuestGuru_OptionsFrameShowObjItemIconsToggle:GetChecked()) then
  187.                 QuestGuru_Settings.ShowObjItemIcons = true;
  188.             else
  189.                 QuestGuru_Settings.ShowObjItemIcons = false;
  190.             end
  191.             QuestLog_UpdateQuestDetails();
  192.         end);
  193.  
  194.  
  195.     QuestGuru_OptionsFrameShowHeaderQuestsToggle = CreateFrame("CheckButton", "QuestGuru_OptionsFrameShowHeaderQuestsToggle", QuestGuru_OptionsFrameGeneral, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  196.     QuestGuru_OptionsFrameShowHeaderQuestsToggle:SetPoint("TOPLEFT", QuestGuru_OptionsFrameShowObjItemIconsToggle, "BOTTOMLEFT", 0, -4);
  197.     QuestGuru_OptionsFrameShowHeaderQuestsToggleText:SetText(QG_OPT_HEADER_QUEST_NUM);
  198.     QuestGuru_OptionsFrameShowHeaderQuestsToggle:SetScript("OnClick",
  199.         function ()
  200.             if (QuestGuru_OptionsFrameShowHeaderQuestsToggle:GetChecked()) then
  201.                 QuestGuru_Settings.HeaderQuests = true;
  202.             else
  203.                 QuestGuru_Settings.HeaderQuests = false;
  204.             end
  205.             QuestLog_Update();
  206.         end);
  207.  
  208.  
  209.     QuestGuru_OptionsFrameDisableCommToggle = CreateFrame("CheckButton", "QuestGuru_OptionsFrameDisableCommToggle", QuestGuru_OptionsFrameGeneral, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  210.     QuestGuru_OptionsFrameDisableCommToggle:SetPoint("TOPLEFT", QuestGuru_OptionsFrameShowHeaderQuestsToggle, "BOTTOMLEFT", 0, -4);
  211.     QuestGuru_OptionsFrameDisableCommToggleText:SetText(QG_OPT_DISABLE_COMM);
  212.     QuestGuru_OptionsFrameDisableCommToggle:SetScript("OnClick",
  213.         function ()
  214.             if (QuestGuru_OptionsFrameDisableCommToggle:GetChecked()) then
  215.                 QuestGuru_Settings.DisableComm = true;
  216.             else
  217.                 QuestGuru_Settings.DisableComm = false;
  218.                 QuestGuru_CommSendPGMessage("0001", QUESTGURU_VERSION);
  219.                 QuestGuru_SendCurrentQuestStatus(true);
  220.             end
  221.         end);
  222.        
  223.  
  224.  
  225. ---------------------
  226. -- Sound Options --
  227. ---------------------
  228.     QuestGuru_OptionsFrameSound = CreateFrame("FRAME", "QuestGuru_OptionsFrameSound", QuestGuru_OptionsFrame);
  229.     QuestGuru_OptionsFrameSound.name = "QG Sounds";
  230.     QuestGuru_OptionsFrameSound.parent = "QuestGuru";
  231.     QuestGuru_OptionsFrameSound.default = function () QuestGuru_SetSoundDefaults(); end;
  232.     InterfaceOptions_AddCategory(QuestGuru_OptionsFrameSound)
  233.  
  234.  
  235.     QuestGuru_OptionsFrameSoundTitle = QuestGuru_OptionsFrameSound:CreateFontString("QuestGuru_OptionsFrameSoundTitle", "ARTWORK", "GameFontNormalLarge");
  236.     QuestGuru_OptionsFrameSoundTitle:SetPoint("TOPLEFT", 16, -16);
  237.     QuestGuru_OptionsFrameSoundTitle:SetJustifyH("LEFT");
  238.     QuestGuru_OptionsFrameSoundTitle:SetJustifyV("TOP");
  239.     QuestGuru_OptionsFrameSoundTitle:SetText("QuestGuru "..QG_OPT_SOUND_HEAD);
  240.  
  241.  
  242.     QuestGuru_OptionsFrameSoundSubText = QuestGuru_OptionsFrameSound:CreateFontString("QuestGuru_OptionsFrameSoundSubText", "ARTWORK", "GameFontHighlightSmall");
  243.     QuestGuru_OptionsFrameSoundSubText:SetPoint("TOPLEFT", "QuestGuru_OptionsFrameSoundTitle", "BOTTOMLEFT", 0, -8);
  244.     QuestGuru_OptionsFrameSoundSubText:SetPoint("RIGHT", -32, 0);
  245.     QuestGuru_OptionsFrameSoundSubText:SetJustifyH("LEFT");
  246.     QuestGuru_OptionsFrameSoundSubText:SetJustifyV("TOP");
  247.     QuestGuru_OptionsFrameSoundSubText:SetHeight(24);
  248.     QuestGuru_OptionsFrameSoundSubText:SetText(QG_OPT_SOUND_DESC);
  249.  
  250.  
  251.     QuestGuru_OptionsFrameSoundToggle = CreateFrame("CheckButton", "QuestGuru_OptionsFrameSoundToggle", QuestGuru_OptionsFrameSound, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  252.     QuestGuru_OptionsFrameSoundToggle:SetPoint("TOPLEFT", "QuestGuru_OptionsFrameSoundSubText", "BOTTOMLEFT", -2, -8);
  253.     QuestGuru_OptionsFrameSoundToggleText:SetText(QG_OPT_SOUND_ENABLE);
  254.     QuestGuru_OptionsFrameSoundToggle:SetScript("OnClick",
  255.         function ()
  256.             if (QuestGuru_OptionsFrameSoundToggle:GetChecked()) then
  257.                 QuestGuru_Settings.Sounds.Enabled = true;
  258.             else
  259.                 QuestGuru_Settings.Sounds.Enabled = false;
  260.             end
  261.         end);
  262.  
  263.  
  264.     QuestGuru_OptionsFrameSoundProgressToggle = CreateFrame("CheckButton", "QuestGuru_OptionsFrameSoundProgressToggle", QuestGuru_OptionsFrameSound, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  265.     QuestGuru_OptionsFrameSoundProgressToggle:SetPoint("TOPLEFT", "QuestGuru_OptionsFrameSoundToggle", "BOTTOMLEFT", 0, -12);
  266.     QuestGuru_OptionsFrameSoundProgressToggleText:SetText(QG_OPT_SOUND_OBJ);
  267.     QuestGuru_OptionsFrameSoundProgressToggle:SetScript("OnClick",
  268.         function ()
  269.             if (QuestGuru_OptionsFrameSoundProgressToggle:GetChecked()) then
  270.                 QuestGuru_Settings.Sounds.Progress.Enabled = true;
  271.             else
  272.                 QuestGuru_Settings.Sounds.Progress.Enabled = false;
  273.             end
  274.         end);
  275.  
  276.  
  277.     QuestGuru_OptionsFrameSoundProgressButton = CreateFrame("Frame", "QuestGuru_OptionsFrameSoundProgressButton", QuestGuru_OptionsFrameSound, "UIDropDownMenuTemplate");
  278.     QuestGuru_OptionsFrameSoundProgressButton:SetPoint("TOPLEFT", "QuestGuru_OptionsFrameSoundProgressToggle", "BOTTOMLEFT");
  279.     QuestGuru_OptionsFrameSoundProgressButton:SetWidth(200);
  280.     QuestGuru_OptionsFrameSoundProgressButtonText:SetJustifyH("LEFT");
  281.     UIDropDownMenu_SetWidth(QuestGuru_OptionsFrameSoundProgressButton, 200);
  282.     UIDropDownMenu_Initialize(QuestGuru_OptionsFrameSoundProgressButton, QuestGuru_OptionsFrameSoundProgressDropDown_Initialize);
  283.  
  284.  
  285.     QuestGuru_OptionsFrameSoundObjCompleteToggle = CreateFrame("CheckButton", "QuestGuru_OptionsFrameSoundObjCompleteToggle", QuestGuru_OptionsFrameSound, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  286.     QuestGuru_OptionsFrameSoundObjCompleteToggle:SetPoint("TOPLEFT", "QuestGuru_OptionsFrameSoundProgressToggle", "BOTTOMLEFT", 0, -48);
  287.     QuestGuru_OptionsFrameSoundObjCompleteToggleText:SetText(QG_OPT_SOUND_OBJ_DONE);
  288.     QuestGuru_OptionsFrameSoundObjCompleteToggle:SetScript("OnClick",
  289.         function ()
  290.             if (QuestGuru_OptionsFrameSoundObjCompleteToggle:GetChecked()) then
  291.                 QuestGuru_Settings.Sounds.ObjComplete.Enabled = true;
  292.             else
  293.                 QuestGuru_Settings.Sounds.ObjComplete.Enabled = false;
  294.             end
  295.         end);
  296.  
  297.  
  298.     QuestGuru_OptionsFrameSoundObjCompleteButton = CreateFrame("Frame", "QuestGuru_OptionsFrameSoundObjCompleteButton", QuestGuru_OptionsFrameSound, "UIDropDownMenuTemplate");
  299.     QuestGuru_OptionsFrameSoundObjCompleteButton:SetPoint("TOPLEFT", "QuestGuru_OptionsFrameSoundObjCompleteToggle", "BOTTOMLEFT");
  300.     QuestGuru_OptionsFrameSoundObjCompleteButton:SetWidth(200);
  301.     QuestGuru_OptionsFrameSoundObjCompleteButtonText:SetJustifyH("LEFT");
  302.     UIDropDownMenu_SetWidth(QuestGuru_OptionsFrameSoundObjCompleteButton, 200);
  303.     UIDropDownMenu_Initialize(QuestGuru_OptionsFrameSoundObjCompleteButton, QuestGuru_OptionsFrameSoundObjCompleteDropDown_Initialize);
  304.  
  305.  
  306.     QuestGuru_OptionsFrameSoundQuestCompleteToggle = CreateFrame("CheckButton", "QuestGuru_OptionsFrameSoundQuestCompleteToggle", QuestGuru_OptionsFrameSound, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  307.     QuestGuru_OptionsFrameSoundQuestCompleteToggle:SetPoint("TOPLEFT", "QuestGuru_OptionsFrameSoundObjCompleteToggle", "BOTTOMLEFT", 0, -48);
  308.     QuestGuru_OptionsFrameSoundQuestCompleteToggleText:SetText(QG_SOUND_QUEST_DONE);
  309.     QuestGuru_OptionsFrameSoundQuestCompleteToggle:SetScript("OnClick",
  310.         function ()
  311.             if (QuestGuru_OptionsFrameSoundQuestCompleteToggle:GetChecked()) then
  312.                 QuestGuru_Settings.Sounds.QuestComplete.Enabled = true;
  313.             else
  314.                 QuestGuru_Settings.Sounds.QuestComplete.Enabled = false;
  315.             end
  316.         end);
  317.  
  318.  
  319.     QuestGuru_OptionsFrameSoundQuestCompleteButton = CreateFrame("Frame", "QuestGuru_OptionsFrameSoundQuestCompleteButton", QuestGuru_OptionsFrameSound, "UIDropDownMenuTemplate");
  320.     QuestGuru_OptionsFrameSoundQuestCompleteButton:SetPoint("TOPLEFT", "QuestGuru_OptionsFrameSoundQuestCompleteToggle", "BOTTOMLEFT");
  321.     QuestGuru_OptionsFrameSoundQuestCompleteButton:SetWidth(200);
  322.     QuestGuru_OptionsFrameSoundQuestCompleteButtonText:SetJustifyH("LEFT");
  323.     UIDropDownMenu_SetWidth(QuestGuru_OptionsFrameSoundQuestCompleteButton, 200);
  324.     UIDropDownMenu_Initialize(QuestGuru_OptionsFrameSoundQuestCompleteButton, QuestGuru_OptionsFrameSoundQuestCompleteDropDown_Initialize);
  325. end
  326.  
  327.  
  328. function QuestGuru_OptionsSaveColor()
  329.     local r,g,b = ColorPickerFrame:GetColorRGB();
  330.  
  331.  
  332.     QuestGuru_Settings.Colorize[lastColorPick].Color.r = r;
  333.     QuestGuru_Settings.Colorize[lastColorPick].Color.g = g;
  334.     QuestGuru_Settings.Colorize[lastColorPick].Color.b = b;
  335.     QuestGuru_OptionsFrameColorizePlayerNameColorSwatch:SetTexture(QuestGuru_Settings.Colorize.PlayerName.Color.r, QuestGuru_Settings.Colorize.PlayerName.Color.g, QuestGuru_Settings.Colorize.PlayerName.Color.b, 1.0);
  336.     QuestGuru_OptionsFrameColorizeAreaNamesColorSwatch:SetTexture(QuestGuru_Settings.Colorize.AreaNames.Color.r, QuestGuru_Settings.Colorize.AreaNames.Color.g, QuestGuru_Settings.Colorize.AreaNames.Color.b, 1.0);
  337.     QuestGuru_OptionsFrameColorizeNPCNamesColorSwatch:SetTexture(QuestGuru_Settings.Colorize.NPCNames.Color.r, QuestGuru_Settings.Colorize.NPCNames.Color.g, QuestGuru_Settings.Colorize.NPCNames.Color.b, 1.0);
  338. end
  339.  
  340.  
  341. function QuestGuru_OptionsSoundsLoadSettings()
  342.     if (QuestGuru_Settings.Sounds == nil) then
  343.         QuestGuru_Settings.Sounds = {};
  344.     end
  345.     if (QuestGuru_Settings.Sounds.Enabled ~= false) then
  346.         QuestGuru_Settings.Sounds.Enabled = true;
  347.     end
  348.     QuestGuru_OptionsFrameSoundToggle:SetChecked(QuestGuru_Settings.Sounds.Enabled);
  349.    
  350.     if (QuestGuru_Settings.Sounds.Progress == nil) then
  351.         QuestGuru_Settings.Sounds.Progress = {};
  352.     end
  353.     if (QuestGuru_Settings.Sounds.Progress.Enabled ~= false) then
  354.         QuestGuru_Settings.Sounds.Progress.Enabled = true;
  355.     end
  356.     QuestGuru_OptionsFrameSoundProgressToggle:SetChecked(QuestGuru_Settings.Sounds.Progress.Enabled);
  357.     if (QuestGuru_Settings.Sounds.Progress.Sound == nil) then
  358.         QuestGuru_Settings.Sounds.Progress.Sound = "AuctionWindowOpen";
  359.     end
  360.     UIDropDownMenu_SetText(QuestGuru_OptionsFrameSoundProgressButton, QuestGuru_Settings.Sounds.Progress.Sound);
  361.  
  362.  
  363.     if (QuestGuru_Settings.Sounds.ObjComplete == nil) then
  364.         QuestGuru_Settings.Sounds.ObjComplete = {};
  365.     end
  366.     if (QuestGuru_Settings.Sounds.ObjComplete.Enabled ~= false) then
  367.         QuestGuru_Settings.Sounds.ObjComplete.Enabled = true;
  368.     end
  369.     QuestGuru_OptionsFrameSoundObjCompleteToggle:SetChecked(QuestGuru_Settings.Sounds.ObjComplete.Enabled);
  370.     if (QuestGuru_Settings.Sounds.ObjComplete.Sound == nil) then
  371.         QuestGuru_Settings.Sounds.ObjComplete.Sound = "AuctionWindowClose";
  372.     end
  373.     UIDropDownMenu_SetText(QuestGuru_OptionsFrameSoundObjCompleteButton, QuestGuru_Settings.Sounds.ObjComplete.Sound);
  374.  
  375.  
  376.     if (QuestGuru_Settings.Sounds.QuestComplete == nil) then
  377.         QuestGuru_Settings.Sounds.QuestComplete = {};
  378.     end
  379.     if (QuestGuru_Settings.Sounds.QuestComplete.Enabled ~= false) then
  380.         QuestGuru_Settings.Sounds.QuestComplete.Enabled = true;
  381.     end
  382.     QuestGuru_OptionsFrameSoundQuestCompleteToggle:SetChecked(QuestGuru_Settings.Sounds.QuestComplete.Enabled);
  383.     if (QuestGuru_Settings.Sounds.QuestComplete.Sound == nil) then
  384.         QuestGuru_Settings.Sounds.QuestComplete.Sound = "ReadyCheck";
  385.     end
  386.     UIDropDownMenu_SetText(QuestGuru_OptionsFrameSoundQuestCompleteButton, QuestGuru_Settings.Sounds.QuestComplete.Sound);
  387. end
  388.  
  389.  
  390. function QuestGuru_SetGeneralDefaults()
  391.     QuestGuru_Echo("Resetting General settings to defaults.");
  392.     QuestGuru_Settings.AutoComplete = false;
  393.     QuestGuru_OptionsFrameAutoCompleteToggle:SetChecked(QuestGuru_Settings.AutoComplete);
  394.     QuestGuru_Settings.ShowObjItemIcons = false;
  395.     QuestGuru_OptionsFrameShowObjItemIconsToggle:SetChecked(QuestGuru_Settings.ShowObjItemIcons);
  396.     QuestGuru_Settings.DisableComm = false;
  397.     QuestGuru_OptionsFrameDisableCommToggle:SetChecked(QuestGuru_Settings.DisableComm);
  398.     QuestGuru_Settings.HeaderQuests = true;
  399.     QuestGuru_OptionsFrameShowHeaderQuestsToggle:SetChecked(QuestGuru_Settings.HeaderQuests);
  400.     QuestGuru_Settings.ShowLevels = {};
  401.     QuestGuru_Settings.ShowLevels.QuestLog = true;
  402.     QuestGuru_OptionsFrameShowLevelsQuestLogToggle:SetChecked(QuestGuru_Settings.ShowLevels.QuestLog);
  403. end
  404.  
  405.  
  406. function QuestGuru_SetSoundDefaults()
  407.     QuestGuru_Echo("Resetting Sound settings to defaults.");
  408.     QuestGuru_Settings.Sounds.Progress.Enabled = true;
  409.     QuestGuru_Settings.Sounds.QuestComplete.Sound = "ReadyCheck";
  410.     QuestGuru_Settings.Sounds.ObjComplete.Sound = "AuctionWindowClose";
  411.     QuestGuru_Settings.Sounds.Progress.Sound = "AuctionWindowOpen";
  412. end
QuestGuruAnnounce.lua
lua Code:
  1. do
  2.     local temp, i;
  3.  
  4.  
  5.     QuestGuru_AnnounceFrame = CreateFrame("FRAME", "QuestGuru_AnnounceFrame", QuestGuru_OptionsFrame);
  6.     QuestGuru_AnnounceFrame.name = "QG Announcer";
  7.     QuestGuru_AnnounceFrame.parent = "QuestGuru";
  8.     QuestGuru_AnnounceFrame.default = function () QuestGuru_SetAnnounceDefaults(); end;
  9.     QuestGuru_AnnounceFrame.okay = function () QuestGuru_SaveAnnounceSettings(); end;
  10.     QuestGuru_AnnounceFrame.cancel = function () QuestGuru_CancelAnnounceChanges(); end;
  11.     InterfaceOptions_AddCategory(QuestGuru_AnnounceFrame);
  12.  
  13.  
  14.     QuestGuru_OptionsFrameAnnounceTitle = QuestGuru_AnnounceFrame:CreateFontString("QuestGuru_OptionsFrameAnnounceTitle", "ARTWORK", "GameFontNormalLarge");
  15.     QuestGuru_OptionsFrameAnnounceTitle:SetPoint("TOPLEFT", 16, -16);
  16.     QuestGuru_OptionsFrameAnnounceTitle:SetJustifyH("LEFT");
  17.     QuestGuru_OptionsFrameAnnounceTitle:SetJustifyV("TOP");
  18.     QuestGuru_OptionsFrameAnnounceTitle:SetText(QG_OPT_ANNOUNCE_HEAD);
  19.  
  20.  
  21.     QuestGuru_OptionsFrameAnnounceSubText = QuestGuru_AnnounceFrame:CreateFontString("QuestGuru_OptionsFrameAnnounceSubText", "ARTWORK", "GameFontHighlightSmall");
  22.     QuestGuru_OptionsFrameAnnounceSubText:SetPoint("TOPLEFT", "QuestGuru_OptionsFrameAnnounceTitle", "BOTTOMLEFT", 0, -8);
  23.     QuestGuru_OptionsFrameAnnounceSubText:SetPoint("RIGHT", -32, 0);
  24.     QuestGuru_OptionsFrameAnnounceSubText:SetJustifyH("LEFT");
  25.     QuestGuru_OptionsFrameAnnounceSubText:SetJustifyV("TOP");
  26.     QuestGuru_OptionsFrameAnnounceSubText:SetHeight(24);
  27.     QuestGuru_OptionsFrameAnnounceSubText:SetText(QG_OPT_ANNOUNCE_DESC);
  28.  
  29.  
  30.     QuestGuru_AnnounceFrameAnnounceToggle = CreateFrame("CheckButton", "QuestGuru_AnnounceFrameAnnounceToggle", QuestGuru_AnnounceFrame, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  31.     QuestGuru_AnnounceFrameAnnounceToggle:SetPoint("TOPLEFT", "QuestGuru_OptionsFrameAnnounceSubText", "BOTTOMLEFT", -2, -8);
  32.     QuestGuru_AnnounceFrameAnnounceToggleText:SetText(QG_OPT_ANNOUNCE_PROGRESS);
  33.  
  34.  
  35.     temp = QuestGuru_AnnounceFrame:CreateFontString("QuestGuru_AnnounceFrameChannelsLabel", "ARTWORK", "GameFontNormal");
  36.     temp:SetText(QG_OPT_ANNOUNCE_CHANNEL_HEAD);
  37.     temp:SetPoint("TOPLEFT", "QuestGuru_AnnounceFrameAnnounceToggle", "BOTTOMLEFT", 0, -6);
  38.    
  39.     QuestGuru_AnnounceFrameChannelSayToggle = CreateFrame("CheckButton", "QuestGuru_AnnounceFrameChannelSayToggle", QuestGuru_AnnounceFrame, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  40.     QuestGuru_AnnounceFrameChannelSayToggle:SetPoint("TOPLEFT", "QuestGuru_AnnounceFrameChannelsLabel", "BOTTOMLEFT", 0, -2);
  41.     QuestGuru_AnnounceFrameChannelSayToggleText:SetText(QG_OPT_ANNOUNCE_CHANNEL_SAY);
  42.     QuestGuru_AnnounceFrameChannelSayToggle.tooltipText = QG_OPT_ANNOUNCE_CHANNEL_SAY_DESC;
  43.    
  44.     QuestGuru_AnnounceFrameChannelPartyToggle = CreateFrame("CheckButton", "QuestGuru_AnnounceFrameChannelPartyToggle", QuestGuru_AnnounceFrame, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  45.     QuestGuru_AnnounceFrameChannelPartyToggle:SetPoint("LEFT", "QuestGuru_AnnounceFrameChannelSayToggle", "RIGHT", 24, 0);
  46.     QuestGuru_AnnounceFrameChannelPartyToggleText:SetText(QG_OPT_ANNOUNCE_CHANNEL_PARTY);
  47.     QuestGuru_AnnounceFrameChannelPartyToggle.tooltipText = QG_OPT_ANNOUNCE_CHANNEL_PARTY_DESC;
  48.    
  49.     QuestGuru_AnnounceFrameChannelGuildToggle = CreateFrame("CheckButton", "QuestGuru_AnnounceFrameChannelGuildToggle", QuestGuru_AnnounceFrame, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  50.     QuestGuru_AnnounceFrameChannelGuildToggle:SetPoint("LEFT", "QuestGuru_AnnounceFrameChannelPartyToggle", "RIGHT", 24, 0);
  51.     QuestGuru_AnnounceFrameChannelGuildToggleText:SetText(QG_OPT_ANNOUNCE_CHANNEL_GUILD);
  52.     QuestGuru_AnnounceFrameChannelGuildToggle.tooltipText = QG_OPT_ANNOUNCE_CHANNEL_GUILD_DESC;
  53.    
  54.     QuestGuru_AnnounceFrameChannelWhisperToggle = CreateFrame("CheckButton", "QuestGuru_AnnounceFrameChannelWhisperToggle", QuestGuru_AnnounceFrame, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  55.     QuestGuru_AnnounceFrameChannelWhisperToggle:SetPoint("LEFT", "QuestGuru_AnnounceFrameChannelGuildToggle", "RIGHT", 24, 0);
  56.     QuestGuru_AnnounceFrameChannelWhisperToggleText:SetText(QG_OPT_ANNOUNCE_CHANNEL_WHISPER);
  57.     QuestGuru_AnnounceFrameChannelWhisperToggle.tooltipText = QG_OPT_ANNOUNCE_CHANNEL_WHISPER_DESC;
  58.  
  59.  
  60.     temp = QuestGuru_AnnounceFrame:CreateFontString("QuestGuru_AnnounceFrameChannelWhisperToText", "ARTWORK", "GameFontNormal");
  61.     temp:SetText(QG_OPT_ANNOUNCE_CHANNEL_WHISPER_TO);
  62.     temp:SetPoint("LEFT", "QuestGuru_AnnounceFrameChannelWhisperToggle", "RIGHT", 24, 0);
  63.    
  64.     QuestGuru_AnnounceFrameChannelWhisperTo = CreateFrame("EditBox", "QuestGuru_AnnounceFrameChannelWhisperTo", QuestGuru_AnnounceFrame, "InputBoxTemplate");
  65.     QuestGuru_AnnounceFrameChannelWhisperTo:SetPoint("LEFT", "QuestGuru_AnnounceFrameChannelWhisperToText", "RIGHT", 8, 0);
  66.     QuestGuru_AnnounceFrameChannelWhisperTo:SetHeight(20);
  67.     QuestGuru_AnnounceFrameChannelWhisperTo:SetWidth(72);
  68.     QuestGuru_AnnounceFrameChannelWhisperTo:SetAutoFocus(false);
  69.     QuestGuru_AnnounceFrameChannelWhisperTo:SetScript("OnShow",
  70.         function ()
  71.             QuestGuru_AnnounceFrameChannelWhisperTo:SetCursorPosition(1);
  72.         end);
  73.     QuestGuru_AnnounceFrameChannelWhisperTo:SetScript("OnEscapePressed",
  74.         function (self)
  75.             self:ClearFocus();
  76.         end);
  77.  
  78.  
  79.     QuestGuru_AnnounceFrameChannelEchoToggle = CreateFrame("CheckButton", "QuestGuru_AnnounceFrameChannelEchoToggle", QuestGuru_AnnounceFrame, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  80.     QuestGuru_AnnounceFrameChannelEchoToggle:SetPoint("LEFT", "QuestGuru_AnnounceFrameChannelWhisperTo", "RIGHT", 24, 2);
  81.     QuestGuru_AnnounceFrameChannelEchoToggleText:SetText(QG_OPT_ANNOUNCE_ECHO);
  82.     QuestGuru_AnnounceFrameChannelEchoToggle.tooltipText = QG_OPT_ANNOUNCE_ECHO_DESC;
  83.  
  84.  
  85.     temp = QuestGuru_AnnounceFrame:CreateFontString("QuestGuru_AnnounceFrameMessageLabel", "ARTWORK", "GameFontNormal");
  86.     temp:SetText(QG_OPT_ANNOUNCE_MESSAGES);
  87.     temp:SetPoint("TOPLEFT", "QuestGuru_AnnounceFrameChannelSayToggle", "BOTTOMLEFT", 0, -8);
  88.    
  89.     QuestGuru_AnnounceFrameMessageHelpButton = CreateFrame("BUTTON", "QuestGuru_AnnounceFrameMessageHelpButton", QuestGuru_AnnounceFrame, "UIPanelButtonTemplate");
  90.     QuestGuru_AnnounceFrameMessageHelpButton:SetHeight(24);
  91.     QuestGuru_AnnounceFrameMessageHelpButton:SetWidth(24);
  92.     QuestGuru_AnnounceFrameMessageHelpButton:SetText("?");
  93.     QuestGuru_AnnounceFrameMessageHelpButton:SetPoint("TOP", "QuestGuru_AnnounceFrameChannelSayToggle", "BOTTOM", 0, -24);
  94.     QuestGuru_AnnounceFrameMessageHelpButton:SetPoint("RIGHT", -8, 0);
  95.     QuestGuru_AnnounceFrameMessageHelpButton:SetScript("OnEnter",
  96.         function (self)
  97.             GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
  98.             GameTooltip:ClearLines();
  99.             GameTooltip:AddLine(QG_OPT_ANNOUNCE_MSG_VARS);
  100.             GameTooltip:AddDoubleLine(QG_ANNOUNCE_KEYWORD_DONE,QG_OPT_ANNOUNCE_HELP_DONE);
  101.             GameTooltip:AddDoubleLine(QG_ANNOUNCE_KEYWORD_NEEDED,QG_OPT_ANNOUNCE_HELP_NEEDED);
  102.             GameTooltip:AddDoubleLine(QG_ANNOUNCE_KEYWORD_NUMLEFT,QG_OPT_ANNOUNCE_HELP_NUMLEFT);
  103.             GameTooltip:AddDoubleLine(QG_ANNOUNCE_KEYWORD_ITEMNAME,QG_OPT_ANNOUNCE_HELP_NAME);
  104.             GameTooltip:AddDoubleLine(QG_ANNOUNCE_KEYWORD_QUESTTITLE,QG_OPT_ANNOUNCE_HELP_TITLE);
  105.             GameTooltip:AddDoubleLine(QG_ANNOUNCE_KEYWORD_UITEXT,QG_OPT_ANNOUNCE_HELP_UITEXT);
  106.             GameTooltip:AddDoubleLine(QG_ANNOUNCE_KEYWORD_COMPLETE,QG_OPT_ANNOUNCE_HELP_COMPLETE);
  107.             GameTooltip:AddDoubleLine(QG_ANNOUNCE_KEYWORD_QLINK,QG_OPT_ANNOUNCE_HELP_QLINK);
  108.             GameTooltip:Show();
  109.         end);
  110.     QuestGuru_AnnounceFrameMessageHelpButton:SetScript("OnLeave",
  111.         function ()
  112.             GameTooltip:Hide();
  113.         end);
  114.  
  115.  
  116.     QuestGuru_AnnounceFrameMessageItemToggle = CreateFrame("CheckButton", "QuestGuru_AnnounceFrameMessageItemToggle", QuestGuru_AnnounceFrame, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  117.     QuestGuru_AnnounceFrameMessageItemToggle:SetPoint("TOPLEFT", "QuestGuru_AnnounceFrameMessageLabel", "BOTTOMLEFT", 0, -2);
  118.     QuestGuru_AnnounceFrameMessageItemToggleText:SetText(QG_OPT_ANNOUNCE_ITEM_MSG);
  119.    
  120.     QuestGuru_AnnounceFrameMessageItem = CreateFrame("EditBox", "QuestGuru_AnnounceFrameMessageItem", QuestGuru_AnnounceFrame, "InputBoxTemplate");
  121.     QuestGuru_AnnounceFrameMessageItem:SetPoint("TOPLEFT", "QuestGuru_AnnounceFrameMessageItemToggle", "BOTTOMLEFT", 2, 0);
  122.     QuestGuru_AnnounceFrameMessageItem:SetHeight(20);
  123.     QuestGuru_AnnounceFrameMessageItem:SetWidth(352);
  124.     QuestGuru_AnnounceFrameMessageItem:SetAutoFocus(false);
  125.     QuestGuru_AnnounceFrameMessageItem:SetScript("OnShow",
  126.         function ()
  127.             QuestGuru_AnnounceFrameMessageItem:SetCursorPosition(1);
  128.         end);
  129.     QuestGuru_AnnounceFrameMessageItem:SetScript("OnEscapePressed",
  130.         function (self)
  131.             self:ClearFocus();
  132.         end);
  133.  
  134.  
  135.     QuestGuru_AnnounceFrameMessageMonsterToggle = CreateFrame("CheckButton", "QuestGuru_AnnounceFrameMessageMonsterToggle", QuestGuru_AnnounceFrame, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  136.     QuestGuru_AnnounceFrameMessageMonsterToggle:SetPoint("TOPLEFT", "QuestGuru_AnnounceFrameMessageItem", "BOTTOMLEFT", -2, -6);
  137.     QuestGuru_AnnounceFrameMessageMonsterToggleText:SetText(QG_OPT_ANNOUNCE_MOB_MSG);
  138.    
  139.     QuestGuru_AnnounceFrameMessageMonster = CreateFrame("EditBox", "QuestGuru_AnnounceFrameMessageMonster", QuestGuru_AnnounceFrame, "InputBoxTemplate");
  140.     QuestGuru_AnnounceFrameMessageMonster:SetPoint("TOPLEFT", "QuestGuru_AnnounceFrameMessageMonsterToggle", "BOTTOMLEFT", 2, 0);
  141.     QuestGuru_AnnounceFrameMessageMonster:SetHeight(20);
  142.     QuestGuru_AnnounceFrameMessageMonster:SetWidth(352);
  143.     QuestGuru_AnnounceFrameMessageMonster:SetAutoFocus(false);
  144.     QuestGuru_AnnounceFrameMessageMonster:SetScript("OnShow",
  145.         function ()
  146.             QuestGuru_AnnounceFrameMessageMonster:SetCursorPosition(1);
  147.         end);
  148.     QuestGuru_AnnounceFrameMessageMonster:SetScript("OnEscapePressed",
  149.         function (self)
  150.             self:ClearFocus();
  151.         end);
  152.  
  153.  
  154.     QuestGuru_AnnounceFrameMessageEventToggle = CreateFrame("CheckButton", "QuestGuru_AnnounceFrameMessageEventToggle", QuestGuru_AnnounceFrame, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  155.     QuestGuru_AnnounceFrameMessageEventToggle:SetPoint("TOPLEFT", "QuestGuru_AnnounceFrameMessageMonster", "BOTTOMLEFT", -2, -6);
  156.     QuestGuru_AnnounceFrameMessageEventToggleText:SetText(QG_OPT_ANNOUNCE_EVENT_MSG);
  157.    
  158.     QuestGuru_AnnounceFrameMessageEvent = CreateFrame("EditBox", "QuestGuru_AnnounceFrameMessageEvent", QuestGuru_AnnounceFrame, "InputBoxTemplate");
  159.     QuestGuru_AnnounceFrameMessageEvent:SetPoint("TOPLEFT", "QuestGuru_AnnounceFrameMessageEventToggle", "BOTTOMLEFT", 2, 0);
  160.     QuestGuru_AnnounceFrameMessageEvent:SetHeight(20);
  161.     QuestGuru_AnnounceFrameMessageEvent:SetWidth(352);
  162.     QuestGuru_AnnounceFrameMessageEvent:SetAutoFocus(false);
  163.     QuestGuru_AnnounceFrameMessageEvent:SetScript("OnShow",
  164.         function ()
  165.             QuestGuru_AnnounceFrameMessageEvent:SetCursorPosition(1);
  166.         end);
  167.     QuestGuru_AnnounceFrameMessageEvent:SetScript("OnEscapePressed",
  168.         function (self)
  169.             self:ClearFocus();
  170.         end);
  171.  
  172.  
  173.     QuestGuru_AnnounceFrameMessageQuestToggle = CreateFrame("CheckButton", "QuestGuru_AnnounceFrameMessageQuestToggle", QuestGuru_AnnounceFrame, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  174.     QuestGuru_AnnounceFrameMessageQuestToggle:SetPoint("TOPLEFT", "QuestGuru_AnnounceFrameMessageEvent", "BOTTOMLEFT", -2, -6);
  175.     QuestGuru_AnnounceFrameMessageQuestToggleText:SetText(QG_OPT_ANNOUNCE_COMPLETE_MSG);
  176.    
  177.     QuestGuru_AnnounceFrameMessageQuest = CreateFrame("EditBox", "QuestGuru_AnnounceFrameMessageQuest", QuestGuru_AnnounceFrame, "InputBoxTemplate");
  178.     QuestGuru_AnnounceFrameMessageQuest:SetPoint("TOPLEFT", "QuestGuru_AnnounceFrameMessageQuestToggle", "BOTTOMLEFT", 2, 0);
  179.     QuestGuru_AnnounceFrameMessageQuest:SetHeight(20);
  180.     QuestGuru_AnnounceFrameMessageQuest:SetWidth(352);
  181.     QuestGuru_AnnounceFrameMessageQuest:SetAutoFocus(false);
  182.     QuestGuru_AnnounceFrameMessageQuest:SetScript("OnShow",
  183.         function ()
  184.             QuestGuru_AnnounceFrameMessageQuest:SetCursorPosition(1);
  185.         end);
  186.     QuestGuru_AnnounceFrameMessageQuest:SetScript("OnEscapePressed",
  187.         function (self)
  188.             self:ClearFocus();
  189.         end);
  190.  
  191.  
  192.     QuestGuru_AnnounceFrameMessageQuestAcceptToggle = CreateFrame("CheckButton", "QuestGuru_AnnounceFrameMessageQuestAcceptToggle", QuestGuru_AnnounceFrame, "QuestGuru_InterfaceOptionsCheckButtonTemplate");
  193.     QuestGuru_AnnounceFrameMessageQuestAcceptToggle:SetPoint("TOPLEFT", "QuestGuru_AnnounceFrameMessageQuest", "BOTTOMLEFT", -2, -6);
  194.     QuestGuru_AnnounceFrameMessageQuestAcceptToggleText:SetText(QG_OPT_ANNOUNCE_QUESTACCEPT_MSG);
  195.    
  196.     QuestGuru_AnnounceFrameMessageQuestAccept = CreateFrame("EditBox", "QuestGuru_AnnounceFrameMessageQuestAccept", QuestGuru_AnnounceFrame, "InputBoxTemplate");
  197.     QuestGuru_AnnounceFrameMessageQuestAccept:SetPoint("TOPLEFT", "QuestGuru_AnnounceFrameMessageQuestAcceptToggle", "BOTTOMLEFT", 2, 0);
  198.     QuestGuru_AnnounceFrameMessageQuestAccept:SetHeight(20);
  199.     QuestGuru_AnnounceFrameMessageQuestAccept:SetWidth(352);
  200.     QuestGuru_AnnounceFrameMessageQuestAccept:SetAutoFocus(false);
  201.     QuestGuru_AnnounceFrameMessageQuestAccept:SetScript("OnShow",
  202.         function ()
  203.             QuestGuru_AnnounceFrameMessageQuestAccept:SetCursorPosition(1);
  204.         end);
  205.     QuestGuru_AnnounceFrameMessageQuestAccept:SetScript("OnEscapePressed",
  206.         function (self)
  207.             self:ClearFocus();
  208.         end);
  209. end
  210.  
  211.  
  212. function QuestGuru_QuestAnnounceLoadSettings()
  213.     if (QuestGuru_Settings.Announce == nil) then
  214.         QuestGuru_Settings.Announce={};
  215.     end
  216.    
  217.     if (QuestGuru_Settings.Announce.Enabled ~= true) then
  218.         QuestGuru_Settings.Announce.Enabled = false;
  219.     end
  220.     QuestGuru_AnnounceFrameAnnounceToggle:SetChecked(QuestGuru_Settings.Announce.Enabled);
  221.  
  222.  
  223.     if (QuestGuru_Settings.Announce.item == nil) then
  224.         QuestGuru_Settings.Announce.item = {};
  225.     end
  226.     if (QuestGuru_Settings.Announce.item.Enabled ~= false) then
  227.         QuestGuru_Settings.Announce.item.Enabled = true;
  228.     end
  229.     QuestGuru_AnnounceFrameMessageItemToggle:SetChecked(QuestGuru_Settings.Announce.item.Enabled);
  230.     if (QuestGuru_Settings.Announce.item.Text == nil) then
  231.         QuestGuru_Settings.Announce.item.Text = QG_ANNOUNCE_ITEM_DEFAULT;
  232.     end
  233.     QuestGuru_AnnounceFrameMessageItem:SetText(QuestGuru_Settings.Announce.item.Text);
  234.  
  235.  
  236.     if (QuestGuru_Settings.Announce.monster == nil) then
  237.         QuestGuru_Settings.Announce.monster = {};
  238.     end
  239.     if (QuestGuru_Settings.Announce.monster.Enabled ~= false) then
  240.         QuestGuru_Settings.Announce.monster.Enabled = true;
  241.     end
  242.     QuestGuru_AnnounceFrameMessageMonsterToggle:SetChecked(QuestGuru_Settings.Announce.monster.Enabled);
  243.     if (QuestGuru_Settings.Announce.monster.Text == nil) then
  244.         QuestGuru_Settings.Announce.monster.Text = QG_ANNOUNCE_MOB_DEFAULT;
  245.     end
  246.     QuestGuru_AnnounceFrameMessageMonster:SetText(QuestGuru_Settings.Announce.monster.Text);
  247.  
  248.  
  249.     if (QuestGuru_Settings.Announce.QuestAccept == nil) then
  250.         QuestGuru_Settings.Announce.QuestAccept = {};
  251.     end
  252.     if (QuestGuru_Settings.Announce.QuestAccept.Enabled ~= false) then
  253.         QuestGuru_Settings.Announce.QuestAccept.Enabled = true;
  254.     end
  255.     QuestGuru_AnnounceFrameMessageQuestAcceptToggle:SetChecked(QuestGuru_Settings.Announce.QuestAccept.Enabled);
  256.     if (QuestGuru_Settings.Announce.QuestAccept.Text == nil) then
  257.         QuestGuru_Settings.Announce.QuestAccept.Text = QG_ANNOUNCE_QUESTACCEPT_DEFAULT;
  258.     end
  259.     QuestGuru_AnnounceFrameMessageQuestAccept:SetText(QuestGuru_Settings.Announce.QuestAccept.Text);
  260.  
  261.  
  262.     if (QuestGuru_Settings.Announce.event == nil) then
  263.         QuestGuru_Settings.Announce.event = {};
  264.     end
  265.     if (QuestGuru_Settings.Announce.event.Enabled ~= false) then
  266.         QuestGuru_Settings.Announce.event.Enabled = true;
  267.     end
  268.     QuestGuru_AnnounceFrameMessageEventToggle:SetChecked(QuestGuru_Settings.Announce.event.Enabled);
  269.     if (QuestGuru_Settings.Announce.event.Text == nil) then
  270.         QuestGuru_Settings.Announce.event.Text = QG_ANNOUNCE_KEYWORD_UITEXT;
  271.     end
  272.     QuestGuru_AnnounceFrameMessageEvent:SetText(QuestGuru_Settings.Announce.event.Text);
  273.  
  274.  
  275.     if (QuestGuru_Settings.Announce.Quest == nil) then
  276.         QuestGuru_Settings.Announce.Quest = {};
  277.     end
  278.     if (QuestGuru_Settings.Announce.Quest.Enabled ~= false) then
  279.         QuestGuru_Settings.Announce.Quest.Enabled = true;
  280.     end
  281.     QuestGuru_AnnounceFrameMessageQuestToggle:SetChecked(QuestGuru_Settings.Announce.Quest.Enabled);
  282.     if (QuestGuru_Settings.Announce.Quest.Text == nil) then
  283.         QuestGuru_Settings.Announce.Quest.Text = QG_ANNOUNCE_QUEST_TEXT;
  284.     end
  285.     QuestGuru_AnnounceFrameMessageQuest:SetText(QuestGuru_Settings.Announce.Quest.Text);
  286.    
  287.     if (QuestGuru_Settings.Announce.say ~= true) then
  288.         QuestGuru_Settings.Announce.say = false;
  289.     end
  290.     QuestGuru_AnnounceFrameChannelSayToggle:SetChecked(QuestGuru_Settings.Announce.say);
  291.     if (QuestGuru_Settings.Announce.party ~= false) then
  292.         QuestGuru_Settings.Announce.party = true;
  293.     end
  294.     QuestGuru_AnnounceFrameChannelPartyToggle:SetChecked(QuestGuru_Settings.Announce.party);
  295.     if (QuestGuru_Settings.Announce.guild ~= true) then
  296.         QuestGuru_Settings.Announce.guild = false;
  297.     end
  298.     QuestGuru_AnnounceFrameChannelGuildToggle:SetChecked(QuestGuru_Settings.Announce.guild);
  299.     if (QuestGuru_Settings.Announce.whisper == nil) then
  300.         QuestGuru_Settings.Announce.whisper = {};
  301.     end
  302.     if (QuestGuru_Settings.Announce.whisper.Enabled ~= true) then
  303.         QuestGuru_Settings.Announce.whisper.Enabled = false;
  304.     end
  305.     QuestGuru_AnnounceFrameChannelWhisperToggle:SetChecked(QuestGuru_Settings.Announce.whisper.Enabled);
  306.     if (QuestGuru_Settings.Announce.whisper.To == nil) then
  307.         QuestGuru_Settings.Announce.whisper.To = "";
  308.     end
  309.     QuestGuru_AnnounceFrameChannelWhisperTo:SetText(QuestGuru_Settings.Announce.whisper.To);
  310.     if (QuestGuru_Settings.Announce.Echo ~= true) then
  311.         QuestGuru_Settings.Announce.Echo = false;
  312.     end
  313.     QuestGuru_AnnounceFrameChannelEchoToggle:SetChecked(QuestGuru_Settings.Announce.Echo);
  314. end
  315.  
  316.  
  317. function QuestGuru_SetAnnounceDefaults()
  318.     QuestGuru_Echo(QG_ANNOUNCE_RESET);
  319.     QuestGuru_Settings.Announce.Enabled = false;
  320.     QuestGuru_AnnounceFrameAnnounceToggle:SetChecked(QuestGuru_Settings.Announce.Enabled);
  321.     QuestGuru_Settings.Announce.item = {};
  322.     QuestGuru_Settings.Announce.item.Enabled = true;
  323.     QuestGuru_AnnounceFrameMessageItemToggle:SetChecked(QuestGuru_Settings.Announce.item.Enabled);
  324.     QuestGuru_Settings.Announce.item.Text = QG_ANNOUNCE_ITEM_DEFAULT;
  325.     QuestGuru_AnnounceFrameMessageItem:SetText(QuestGuru_Settings.Announce.item.Text);
  326.     QuestGuru_Settings.Announce.monster = {};
  327.     QuestGuru_Settings.Announce.monster.Enabled = true;
  328.     QuestGuru_AnnounceFrameMessageMonsterToggle:SetChecked(QuestGuru_Settings.Announce.monster.Enabled);
  329.     QuestGuru_Settings.Announce.monster.Text = QG_ANNOUNCE_MOB_DEFAULT;
  330.     QuestGuru_AnnounceFrameMessageMonster:SetText(QuestGuru_Settings.Announce.monster.Text);
  331.     QuestGuru_Settings.Announce.QuestAccept = {};
  332.     QuestGuru_Settings.Announce.QuestAccept.Enabled = true;
  333.     QuestGuru_AnnounceFrameMessageQuestAcceptToggle:SetChecked(QuestGuru_Settings.Announce.QuestAccept.Enabled);
  334.     QuestGuru_Settings.Announce.QuestAccept.Text = QG_ANNOUNCE_QUESTACCEPT_DEFAULT;
  335.     QuestGuru_AnnounceFrameMessageQuestAccept:SetText(QuestGuru_Settings.Announce.QuestAccept.Text);
  336.     QuestGuru_Settings.Announce.event = {};
  337.     QuestGuru_Settings.Announce.event.Enabled = true;
  338.     QuestGuru_AnnounceFrameMessageEventToggle:SetChecked(QuestGuru_Settings.Announce.event.Enabled);
  339.     QuestGuru_Settings.Announce.event.Text = QG_ANNOUNCE_KEYWORD_UITEXT;
  340.     QuestGuru_AnnounceFrameMessageEvent:SetText(QuestGuru_Settings.Announce.event.Text);
  341.     QuestGuru_Settings.Announce.Quest = {};
  342.     QuestGuru_Settings.Announce.Quest.Enabled = true;
  343.     QuestGuru_AnnounceFrameMessageQuestToggle:SetChecked(QuestGuru_Settings.Announce.Quest.Enabled);
  344.     QuestGuru_Settings.Announce.Quest.Text = QG_ANNOUNCE_QUEST_TEXT;
  345.     QuestGuru_AnnounceFrameMessageQuest:SetText(QuestGuru_Settings.Announce.Quest.Text);
  346.  
  347.  
  348.     QuestGuru_Settings.Announce.say = false;
  349.     QuestGuru_AnnounceFrameChannelSayToggle:SetChecked(QuestGuru_Settings.Announce.say);
  350.     QuestGuru_Settings.Announce.party = true;
  351.     QuestGuru_AnnounceFrameChannelPartyToggle:SetChecked(QuestGuru_Settings.Announce.party);
  352.     QuestGuru_Settings.Announce.guild = false;
  353.     QuestGuru_AnnounceFrameChannelGuildToggle:SetChecked(QuestGuru_Settings.Announce.guild);
  354.     QuestGuru_Settings.Announce.whisper = {};
  355.     QuestGuru_Settings.Announce.whisper.Enabled = false;
  356.     QuestGuru_AnnounceFrameChannelWhisperToggle:SetChecked(QuestGuru_Settings.Announce.whisper.Enabled);
  357.     QuestGuru_Settings.Announce.whisper.To = "";
  358.     QuestGuru_AnnounceFrameChannelWhisperTo:SetText(QuestGuru_Settings.Announce.whisper.To);
  359.     QuestGuru_Settings.Announce.Echo = false;
  360.     QuestGuru_AnnounceFrameChannelEchoToggle:SetChecked(QuestGuru_Settings.Announce.Echo);
  361. end
  362.  
  363.  
  364. function QuestGuru_SaveAnnounceSettings()
  365.     if (QuestGuru_AnnounceFrameAnnounceToggle:GetChecked()) then
  366.         QuestGuru_Settings.Announce.Enabled = true;
  367.     else
  368.         QuestGuru_Settings.Announce.Enabled = false;
  369.     end
  370.     if (QuestGuru_AnnounceFrameChannelSayToggle:GetChecked()) then
  371.         QuestGuru_Settings.Announce.say = true;
  372.     else
  373.         QuestGuru_Settings.Announce.say = false;
  374.     end
  375.     if (QuestGuru_AnnounceFrameChannelPartyToggle:GetChecked()) then
  376.         QuestGuru_Settings.Announce.party = true;
  377.     else
  378.         QuestGuru_Settings.Announce.party = false;
  379.     end
  380.     if (QuestGuru_AnnounceFrameChannelGuildToggle:GetChecked()) then
  381.         QuestGuru_Settings.Announce.guild = true;
  382.     else
  383.         QuestGuru_Settings.Announce.guild = false;    
  384.     end
  385.     if (QuestGuru_AnnounceFrameChannelWhisperToggle:GetChecked()) then
  386.         QuestGuru_Settings.Announce.whisper.Enabled = true;
  387.     else
  388.         QuestGuru_Settings.Announce.whisper.Enabled = false;
  389.     end
  390.     QuestGuru_Settings.Announce.whisper.To = QuestGuru_AnnounceFrameChannelWhisperTo:GetText();
  391.     if (QuestGuru_AnnounceFrameChannelEchoToggle:GetChecked()) then
  392.         QuestGuru_Settings.Announce.Echo = true;
  393.     else
  394.         QuestGuru_Settings.Announce.Echo = false;
  395.     end
  396.     if (QuestGuru_AnnounceFrameMessageItemToggle:GetChecked()) then
  397.         QuestGuru_Settings.Announce.item.Enabled = true;
  398.     else
  399.         QuestGuru_Settings.Announce.item.Enabled = false;
  400.     end
  401.     QuestGuru_Settings.Announce.item.Text = QuestGuru_AnnounceFrameMessageItem:GetText();
  402.     if (QuestGuru_AnnounceFrameMessageMonsterToggle:GetChecked()) then
  403.         QuestGuru_Settings.Announce.monster.Enabled = true;
  404.     else
  405.         QuestGuru_Settings.Announce.monster.Enabled = false;
  406.     end
  407.     QuestGuru_Settings.Announce.monster.Text = QuestGuru_AnnounceFrameMessageMonster:GetText();
  408.     if (QuestGuru_AnnounceFrameMessageQuestAcceptToggle:GetChecked()) then
  409.         QuestGuru_Settings.Announce.QuestAccept.Enabled = true;
  410.     else
  411.         QuestGuru_Settings.Announce.QuestAccept.Enabled = false;
  412.     end
  413.     QuestGuru_Settings.Announce.QuestAccept.Text = QuestGuru_AnnounceFrameMessageQuestAccept:GetText();
  414.     if (QuestGuru_AnnounceFrameMessageEventToggle:GetChecked()) then
  415.         QuestGuru_Settings.Announce.event.Enabled = true;
  416.     else
  417.         QuestGuru_Settings.Announce.event.Enabled = false;
  418.     end
  419.     QuestGuru_Settings.Announce.event.Text = QuestGuru_AnnounceFrameMessageEvent:GetText();
  420.     if (QuestGuru_AnnounceFrameMessageQuestToggle:GetChecked()) then
  421.         QuestGuru_Settings.Announce.Quest.Enabled = true;
  422.     else
  423.         QuestGuru_Settings.Announce.Quest.Enabled = false;
  424.     end
  425.     QuestGuru_Settings.Announce.Quest.Text = QuestGuru_AnnounceFrameMessageQuest:GetText();
  426. end
  427.  
  428.  
  429. function QuestGuru_CancelAnnounceChanges()
  430.     QuestGuru_AnnounceFrameAnnounceToggle:SetChecked(QuestGuru_Settings.Announce.Enabled);
  431.     QuestGuru_AnnounceFrameChannelSayToggle:SetChecked(QuestGuru_Settings.Announce.say);
  432.     QuestGuru_AnnounceFrameChannelPartyToggle:SetChecked(QuestGuru_Settings.Announce.party);
  433.     QuestGuru_AnnounceFrameChannelGuildToggle:GetChecked(QuestGuru_Settings.Announce.guild);
  434.     QuestGuru_AnnounceFrameChannelWhisperToggle:GetChecked(QuestGuru_Settings.Announce.whisper.Enabled);
  435.     QuestGuru_AnnounceFrameChannelWhisperTo:SetText(QuestGuru_Settings.Announce.whisper.To);
  436.     QuestGuru_AnnounceFrameChannelEchoToggle:SetChecked(QuestGuru_Settings.Announce.Echo);
  437.     QuestGuru_AnnounceFrameMessageItemToggle:SetChecked(QuestGuru_Settings.Announce.item.Enabled);
  438.     QuestGuru_AnnounceFrameMessageItem:SetText(QuestGuru_Settings.Announce.item.Text);
  439.     QuestGuru_AnnounceFrameMessageMonsterToggle:SetChecked(QuestGuru_Settings.Announce.monster.Enabled);
  440.     QuestGuru_AnnounceFrameMessageMonster:SetText(QuestGuru_Settings.Announce.monster.Text);
  441.     QuestGuru_AnnounceFrameMessageQuestAcceptToggle:SetChecked(QuestGuru_Settings.Announce.QuestAccept.Enabled);
  442.     QuestGuru_AnnounceFrameMessageQuestAccept:SetText(QuestGuru_Settings.Announce.QuestAccept.Text);
  443.     QuestGuru_AnnounceFrameMessageEventToggle:SetChecked(QuestGuru_Settings.Announce.event.Enabled);
  444.     QuestGuru_AnnounceFrameMessageEvent:SetText(QuestGuru_Settings.Announce.event.Text);
  445.     QuestGuru_AnnounceFrameMessageQuestToggle:SetChecked(QuestGuru_Settings.Announce.Quest.Enabled);
  446.     QuestGuru_AnnounceFrameMessageQuest:SetText(QuestGuru_Settings.Announce.Quest.Text);
  447. end
  448.  
  449.  
  450. function QuestGuru_DoAnnounce(announceText, numDone, numNeeded, itemName, questTitle, arg1, questID)
  451.     if (not QuestGuru_Settings.Announce.Enabled) then return; end
  452.  
  453.  
  454.     if (announceText ~= nil) then
  455.         if (numDone == nil) then numDone = 0; end
  456.         if (numNeeded == nil) then numNeeded = 0; end
  457.         announceText = string.gsub(announceText,QG_ANNOUNCE_KEYWORD_DONE,numDone);
  458.         announceText = string.gsub(announceText,QG_ANNOUNCE_KEYWORD_NEEDED,numNeeded);
  459.         announceText = string.gsub(announceText,QG_ANNOUNCE_KEYWORD_NUMLEFT,numNeeded-numDone);
  460.         announceText = string.gsub(announceText,QG_ANNOUNCE_KEYWORD_ITEMNAME,itemName);
  461.         announceText = string.gsub(announceText,QG_ANNOUNCE_KEYWORD_QUESTTITLE,questTitle);
  462.         announceText = string.gsub(announceText,QG_ANNOUNCE_KEYWORD_UITEXT,arg1);
  463.         announceText = string.gsub(announceText,QG_ANNOUNCE_KEYWORD_COMPLETE,COMPLETE);
  464.         announceText = string.gsub(announceText,QG_ANNOUNCE_KEYWORD_QLINK,GetQuestLink(questID));
  465.        
  466.         if (QuestGuru_Settings.Announce.say) then
  467.             SendChatMessage(announceText, "SAY");
  468.         end
  469.         if (QuestGuru_Settings.Announce.party and (IsInGroup() and GetNumSubgroupMembers(LE_PARTY_CATEGORY_HOME) > 0 and IsInRaid() == false)) then
  470.             SendChatMessage(announceText, "PARTY");
  471.         end
  472.         if ((QuestGuru_Settings.Announce.guild) and IsInGuild()) then
  473.             SendChatMessage(announceText, "GUILD");
  474.         end
  475.         if (QuestGuru_Settings.Announce.whisper.Enabled) then
  476.             SendChatMessage(announceText, "WHISPER", nil, QuestGuru_Settings.Announce.whisper.To);
  477.         end
  478.         if (QuestGuru_Settings.Announce.Echo) then
  479.             QuestGuru_Echo(announceText, true);
  480.         end
  481.     end
  482. end
  483.  
  484.  
  485. function QuestGuru_DoAnnounceByTitle(questTitle, announceText, numDone, numNeeded, itemName, arg1)
  486.     local i;
  487.     local numEntries, numQuests = GetNumQuestLogEntries();
  488.  
  489.  
  490.     for i=1, numEntries do
  491.         local qTitle, _, _, _, isHeader = GetQuestLogTitle(i);
  492.         if not isHeader and (qTitle == questTitle) then
  493.             QuestGuru_DoAnnounce(announceText, numDone, numNeeded, itemName, questTitle, arg1, i);
  494.         end
  495.     end
  496. end


QuestGuruComm.lua
lua Code:
  1. QuestGuru_CommFrame = CreateFrame("FRAME", "QuestGuru_CommFrame", UIParent);
  2. QuestGuru_CommFrame:SetPoint("TOPLEFT");
  3. QuestGuru_CommFrame:SetHeight(0);
  4. QuestGuru_CommFrame:SetWidth(0);
  5. QuestGuru_CommFrame:SetScript("OnUpdate",
  6.     function (self, elapsed)
  7.         QuestGuru_CommOnUpdate(elapsed);
  8.     end);
  9. QuestGuru_CommFrame:Show();
  10.  
  11.  
  12. QuestGuru_CommGuild = {};
  13. QuestGuru_CommParty = {};
  14. -- [PlayerName].QGver = version of QuestGuru other player is using
  15. --              quietTime = number of seconds since last message from player
  16. --              [quest number].Title
  17. --            .Status = status of player on that quest
  18. --             .Objectives = objectives text
  19. --                            .Description = description text
  20. --                            .[Obj#].type = objective type
  21. --            .text = objective text
  22. --            .finished = objective finished?
  23. --                            .[Reward#].type = reward type (choice, spell, reward)
  24. --                            .link = reward link
  25. --              MPmsg = storage for multi-part messages
  26.  
  27.  
  28. QuestGuru_CommTimer = {};
  29. -- .interval = number of seconds to wait
  30. -- .currTime = number of seconds remaining
  31. -- .func = function to call after interval
  32. -- .count = number of times to repeat (-1 for infinite)
  33. -- .args = options arguments to pass
  34.  
  35.  
  36. QuestGuru_CommLastPartyNum = 0;
  37. QuestGuru_CommPendingPartyUpdate = false;
  38.  
  39.  
  40. function QuestGuru_CommOnUpdate(elapsed)
  41.     local i, timer;
  42.    
  43.     for i, timer in ipairs(QuestGuru_CommTimer) do
  44.         timer.currTime = timer.currTime - elapsed;
  45.         if (timer.currTime <= 0) then
  46.             timer.func(timer.arg1, timer.arg2, timer.arg3, timer.arg4);
  47.             timer.currTime = timer.interval;
  48.             timer.count = timer.count - 1;
  49.             if (timer.count < 0) then
  50.                 timer.count = -1;
  51.             elseif (timer.count == 0) then
  52.                 tremove(QuestGuru_CommTimer, i);
  53.                 i = i - 1;
  54.             end
  55.         end
  56.     end
  57. end
  58.  
  59.  
  60. function QuestGuru_CommAddTimer(interval, count, func, arg1, arg2, arg3, arg4)
  61.     local tempTimer = {}
  62.     tempTimer.interval = interval;
  63.     tempTimer.currTime = interval;
  64.     tempTimer.count = count;
  65.     tempTimer.func = func;
  66.     tempTimer.arg1 = arg1;
  67.     tempTimer.arg2 = arg2;
  68.     tempTimer.arg3 = arg3;
  69.     tempTimer.arg4 = arg4;
  70.     tinsert(QuestGuru_CommTimer, tempTimer);
  71. end
  72.  
  73.  
  74. function QuestGuru_CommSendMessage(channel, code, ...)
  75.     local i = 1;
  76.     local recipient;
  77.    
  78.     if (channel == "WHISPER") then
  79.         i = 2;
  80.         recipient = select(1, ...);
  81.     end
  82.     if ((not QuestGuru_Settings.DisableComm) and not ((UnitInBattleground("player") ~= nil) and (channel == "PARTY"))) then
  83.         ChatThrottleLib:SendAddonMessage("NORMAL", "QuGu", strjoin(string.char(2), code, ...), channel, recipient);
  84.     end
  85. end
  86.  
  87.  
  88. function QuestGuru_CommSendPGMessage(...)
  89.     if ((IsInGroup() and GetNumSubgroupMembers(LE_PARTY_CATEGORY_HOME) > 0) and (table.getn(QuestGuru_CommParty) > 0)) then
  90.         QuestGuru_CommSendMessage("PARTY", ...);
  91.     end
  92.     if (IsInGuild()) then
  93.         QuestGuru_CommSendMessage("GUILD", ...);
  94.     end
  95. end
  96.  
  97.  
  98. function QuestGuru_CommSendMPMessage(channel, code, recipient, qNum, msg)
  99. -- Sends a MultiPart message (for quest objective and description since they can exceed the per-message size limit)
  100. -- These should always be WHISPER. Part "0" is last part, ready to process
  101. -- MP messages use char(3) to not conflict with SendMessage
  102.  
  103.  
  104.     local i=1;
  105.     msg = qNum..string.char(3)..msg;
  106.     while (strlen(msg) > 200) do
  107.         local t = string.sub(msg, 1, 200);
  108.         msg = string.sub(msg, 201);
  109.         QuestGuru_CommSendMessage(channel, code, recipient, i, t)
  110.         i = i + 1;
  111.     end
  112.     QuestGuru_CommSendMessage(channel, code, recipient, "0", msg)
  113. end
  114.  
  115.  
  116. function QuestGuru_CommProcessMsg(sender, channel, message)
  117.     local msg = { strsplit(string.char(2), message) };
  118.     if (msg == nil) then return; end
  119.     local code = msg[1];
  120.     local currSender;
  121.  
  122.  
  123.     if (channel == "GUILD") then
  124.         if (QuestGuru_CommGuild[sender] == nil) then
  125.             QuestGuru_CommGuild[sender] = {};
  126.         end
  127.         currSender = QuestGuru_CommGuild[sender];
  128.     elseif (channel == "PARTY") then
  129.         if (QuestGuru_CommParty[sender] == nil) then
  130.             QuestGuru_CommParty[sender] = {};
  131.         end
  132.         currSender = QuestGuru_CommParty[sender];
  133.     else
  134.         if (QuestGuru_CommGuild[sender]) then QuestGuru_CommGuild[sender].quietTime = 0; end
  135.         if (QuestGuru_CommParty[sender]) then QuestGuru_CommParty[sender].quietTime = 0; end
  136.         currSender = {};
  137.     end
  138.     currSender.quietTime = 0;
  139.  
  140.  
  141.     if (code == "0000") then -- Player is sending their QG info
  142.         -- store it
  143.         currSender.QGver = msg[2];
  144. QuestGuru_Echo(sender.." is using QuestGuru v"..msg[2]);
  145.     elseif (code == "0001") then -- Player is sending QG info and requesting yours
  146.         -- store their info and send ours
  147.         currSender.QGver = msg[2];
  148. QuestGuru_Echo(sender.." is using QuestGuru v"..msg[2]);
  149.         if (sender ~= QuestGuru_Player) then QuestGuru_CommSendMessage(channel, "0000", QUESTGURU_VERSION); end
  150.     elseif (code == "0008") then -- Pong
  151.         -- not really necessary to do anything
  152.     elseif (code == "0009") then -- Ping
  153.         -- send a Pong
  154.         QuestGuru_CommSendMessage("WHISPER", "0008", sender);
  155.     elseif (code == "000F") then -- Player logged out
  156.         currSender = nil;
  157. QuestGuru_Echo(sender.." logged off");
  158.     elseif (code == "0020") then -- Discovered NPC Name
  159.         QuestGuru_MoreNPCNames[msg[2]] = 1;
  160.     elseif (code == "0024") then -- Discovered Area Name
  161.         QuestGuru_MoreAreaNames[msg[2]] = 1;
  162.     elseif (code == "0108") then -- Player is on quest (linkNum, objStatus)
  163.         if ((not msg[2]) or (not msg[3])) then return; end
  164.         local qIDi, qIDj, qNum = string.find(msg[2], (":(%d+):"));
  165.         if (qNum) then
  166.             if (not currSender[qNum]) then currSender[qNum] = {}; end
  167.             currSender[qNum].Status = msg[3];
  168.         end
  169.         QuestLog_Update();
  170.     elseif (code == "0109") then -- Player is on quest, requesting who else is too
  171.         if ((not msg[2]) or (not msg[3])) then return; end
  172.         local qIDi, qIDj, qNum = string.find(msg[2], (":(%d+):"));
  173.         if (qNum) then
  174.             if (not currSender[qNum]) then currSender[qNum] = {}; end
  175.             currSender[qNum].Status = msg[3];
  176.         end
  177.         local numEntries, numQuests = GetNumQuestLogEntries();
  178.         local i, j;
  179.         local qStatus = "";
  180.         for i=1, numEntries do
  181.             local qLink = GetQuestLink(i);
  182.             if (qLink) then
  183.                 local qli, qlj, qlNum = string.find(qLink, (":(%d+):"));
  184.                 if (qlNum == qNum) then
  185.                     QuestGuru_SendQuestStatus(i, false);
  186.                 end
  187.             end
  188.         end
  189.         QuestLog_Update();
  190.     elseif (code == "010A") then -- Player completed quest
  191.         currSender[msg[2]] = nil;
  192.         QuestLog_Update();
  193.     elseif (code == "010B") then -- Player completed quest, requesting who else has it
  194.         -- not used at this time
  195.     elseif (code == "010C") then -- Player abandoned quest
  196.         currSender[msg[2]] = nil;
  197.         QuestLog_Update();
  198.     elseif (code == "010D") then -- Player abandoned quest, requesting who else has it
  199.         -- not used at this time
  200.     elseif (code == "0200") then -- qID = quest link
  201.         QuestGuru_UpdateqID(msg[2], msg[3]);
  202.     elseif (code == "0201") then -- Request quest link by qID
  203.         if (QuestGuru_Quests[QuestGuru_RealmName][msg[2]] ~= nil) then
  204.             if (QuestGuru_Quests[QuestGuru_RealmName][msg[2]]["_link"] ~= nil) then
  205.                 QuestGuru_CommSendMessage(channel, "0200", msg[2], QuestGuru_Quests[QuestGuru_RealmName][msg[2]]["_link"]);
  206.             end
  207.         end
  208.     elseif (code == "0202") then -- Quest Title (qNum, Title)
  209.         if (not currSender[msg[2]]) then currSender[msg[2]] = {}; end
  210.         currSender[msg[2]].Title = msg[3];
  211.     elseif (code == "0203") then -- Request quest title (qNum)
  212.         if (not msg[2]) then return; end
  213.         local qNum = msg[2];
  214.         local numEntries, numQuests = GetNumQuestLogEntries();
  215.         local i, j;
  216.         local qStatus = "";
  217.         for i=1, numEntries do
  218.             local qLink = GetQuestLink(i);
  219.             if (qLink) then
  220.                 local qli, qlj, qlNum = string.find(qLink, (":(%d+):"));
  221.                 if (qlNum == qNum) then
  222.                     local qTitle = GetQuestLogTitle(i);
  223.                     QuestGuru_CommSendMessage(channel, "0202", sender, qNum, qTitle);
  224.                 end
  225.             end
  226.         end
  227.     elseif (code == "0204") then -- Objectives text (msg[2] = part, msg[3] = qNum..char(3)..text)
  228.         if (tonumber(msg[2]) == 1) then currSender.MPmsg = nil; end
  229.         currSender.MPmsg = currSender.MPmsg..msg[3];
  230.         if (msg[2] == "0") then -- end of multi-part
  231.             local qDesc = { strsplit(string.char(3), currSender.MPmsg) }; -- qDesc[1] = qNum, qDesc[2] = text
  232.             if (not currSender[qDesc[1]]) then currSender[qDesc[1]] = {}; end
  233.             currSender[qDesc[1]].Objectives = qDesc[2];
  234.             currSender.MPmsg = nil;
  235.         end
  236.     elseif (code == "0205") then -- Request objectives text (qNum)
  237.         if (not msg[2]) then return; end
  238.         local qNum = msg[2];
  239.         local numEntries, numQuests = GetNumQuestLogEntries();
  240.         local i, j;
  241.         local qStatus = "";
  242.         for i=1, numEntries do
  243.             local qLink = GetQuestLink(i);
  244.             if (qLink) then
  245.                 local qli, qlj, qlNum = string.find(qLink, (":(%d+):"));
  246.                 if (qlNum == qNum) then
  247.                     QuestGuru_SendQuestObjectivesText(i, sender, qNum);
  248.                 end
  249.             end
  250.         end
  251.     elseif (code == "0206") then -- Description text (msg[2] = part, msg[3] = qNum..char(3)..text)
  252.         if (tonumber(msg[2]) < 2) then currSender.MPmsg = nil; end
  253.         currSender.MPmsg = currSender.MPmsg..msg[3];
  254.         if (msg[2] == "0") then -- end of multi-part
  255.             local qDesc = { strsplit(string.char(3), currSender.MPmsg) }; -- qDesc[1] = qNum, qDesc[2] = text
  256.             if (not currSender[qDesc[1]]) then currSender[qDesc[1]] = {}; end
  257.             currSender[qDesc[1]].Description = qDesc[2];
  258.         end
  259.     elseif (code == "0207") then -- Request description text (qNum)
  260.         if (not msg[2]) then return; end
  261.         local qNum = msg[2];
  262.         local numEntries, numQuests = GetNumQuestLogEntries();
  263.         local i, j;
  264.         local qStatus = "";
  265.         for i=1, numEntries do
  266.             local qLink = GetQuestLink(i);
  267.             if (qLink) then
  268.                 local qli, qlj, qlNum = string.find(qLink, (":(%d+):"));
  269.                 if (qlNum == qNum) then
  270.                     QuestGuru_SendQuestDescription(i, sender, qNum);
  271.                 end
  272.             end
  273.         end
  274.     elseif (code == "0208") then -- Quest starter info (qNum, info)
  275.         if (QuestGuru_Quests[QuestGuru_RealmName][msg[2]] == nil) then
  276.             QuestGuru_Quests[QuestGuru_RealmName][msg[2]] = {};
  277.         end
  278.         if ((QuestGuru_Quests[QuestGuru_RealmName][msg[2]].StartInfo == nil) or (string.find(QuestGuru_Quests[QuestGuru_RealmName][msg[2]].StartInfo, QG_UNKNOWN))) then
  279.             QuestGuru_Quests[QuestGuru_RealmName][msg[2]].StartInfo = msg[3];
  280.         end
  281.     elseif (code == "0209") then -- Requesting quest starter info (qNum)
  282.         if (QuestGuru_Quests[QuestGuru_RealmName][msg[2]] ~= nil) then
  283.             if ((QuestGuru_Quests[QuestGuru_RealmName][msg[2]].StartInfo ~= nil) and (not string.find(QuestGuru_Quests[QuestGuru_RealmName][msg[2]].StartInfo, QG_UNKNOWN))) then
  284.                 QuestGuru_CommSendMessage(channel, "020A", msg[2], QuestGuru_Quests[QuestGuru_RealmName][msg[2]].StartInfo);
  285.             end
  286.         end
  287.     elseif (code == "020A") then -- Quest finisher info (qNum, info)
  288.         if (QuestGuru_Quests[QuestGuru_RealmName][msg[2]] == nil) then
  289.             QuestGuru_Quests[QuestGuru_RealmName][msg[2]] = {};
  290.         end
  291.         if ((QuestGuru_Quests[QuestGuru_RealmName][msg[2]].FinishInfo == nil) or (string.find(QuestGuru_Quests[QuestGuru_RealmName][msg[2]].FinishInfo, QG_UNKNOWN))) then
  292.             QuestGuru_Quests[QuestGuru_RealmName][msg[2]].FinishInfo = msg[3];
  293.         end
  294.     elseif (code == "020B") then -- Requesting quest finisher info (qNum)
  295.         if (QuestGuru_Quests[QuestGuru_RealmName][msg[2]] ~= nil) then
  296.             if ((QuestGuru_Quests[QuestGuru_RealmName][msg[2]].FinishInfo ~= nil) and (not string.find(QuestGuru_Quests[QuestGuru_RealmName][msg[2]].FinishInfo, QG_UNKNOWN))) then
  297.                 QuestGuru_CommSendMessage(channel, "020A", msg[2], QuestGuru_Quests[QuestGuru_RealmName][msg[2]].FinishInfo);
  298.             end
  299.         end
  300.     elseif (code == "020C") then -- Quest objective (qNum, type, text)
  301.     elseif (code == "020D") then -- Request quest objectives (qNum)
  302.     elseif (code == "020E") then -- Quest reward (qNum, type, link)
  303.     elseif (code == "020F") then -- Request quest rewards (qNum)
  304.     elseif (code == "0300") then -- Item link by name
  305.         if (QuestGuru_Items[QuestGuru_RealmName]) then
  306.             QuestGuru_Items[QuestGuru_RealmName][msg[2]] = msg[3];
  307.         end
  308.     elseif (code == "0301") then -- Request item link by name
  309.         if (QuestGuru_Items[QuestGuru_RealmName] and QuestGuru_Items[QuestGuru_RealmName][msg[2]]) then
  310.             QuestGuru_CommSendMessage(channel, "0300", msg[2], QuestGuru_Items[QuestGuru_RealmName][msg[2]]);
  311.         end
  312.     end
  313. end
  314.  
  315.  
  316. function QuestGuru_UpdateqID(qID, link)
  317.     if (QuestGuru_Quests[QuestGuru_RealmName][qID] == nil) then
  318.         QuestGuru_Quests[QuestGuru_RealmName][qID] = {};
  319.     end
  320.     if (QuestGuru_Quests[QuestGuru_RealmName][qID]["_link"] == nil) then
  321.         QuestGuru_Quests[QuestGuru_RealmName][qID]["_link"] = link;
  322.     end
  323.  
  324.  
  325.     local qIDi, qIDj, qNum, qLevel = string.find(link, (":(%d+):(%d+)|"));
  326.     if (qLevel and (QuestGuru_Quests[QuestGuru_RealmName][qID].level == nil)) then
  327.         QuestGuru_Quests[QuestGuru_RealmName][qID].level = qLevel;
  328.     end
  329.     if (qNum and (QuestGuru_Quests[QuestGuru_RealmName][qNum] == nil)) then
  330.         QuestGuru_Quests[QuestGuru_RealmName][qNum] = {};
  331.     end
  332.     if (qNum and (QuestGuru_Quests[QuestGuru_RealmName][qNum][qID] == nil)) then
  333.         QuestGuru_Quests[QuestGuru_RealmName][qNum][qID] = 1;
  334.     end
  335. end
  336.  
  337.  
  338. function QuestGuru_SendCurrentQuestStatus(req, channel)
  339.     local numEntries, numQuests = GetNumQuestLogEntries();
  340.     local i;
  341.     for i=1, numEntries do
  342.         QuestGuru_SendQuestStatus(i, req, channel);
  343.     end
  344. end
  345.  
  346.  
  347. function QuestGuru_SendQuestStatusByName(name, req, channel)
  348.     local i;
  349.     local numEntries, numQuests = GetNumQuestLogEntries();
  350.    
  351.     for i=1, numEntries do
  352.         local qTitle = GetQuestLogTitle(i);
  353.         if (qTitle == name) then
  354.             QuestGuru_SendQuestStatus(i, req, channel);
  355.         end
  356.     end
  357. end
  358.  
  359.  
  360. function QuestGuru_SendQuestStatus(index, req, channel)
  361.     local j;
  362.     local qStatus = "";
  363.     if (req ~= false) then req = true; end
  364.    
  365.     local qLink = GetQuestLink(index);
  366.     if (qLink) then
  367.         local numObjectives = GetNumQuestLeaderBoards(index);
  368.         for j=1, numObjectives do
  369.             local text, type, finished = GetQuestLogLeaderBoard(j, index);
  370.             if ((type == "item") or (type == "monster") or (type == "object")) then
  371.                 local x, y, name, numItems, numNeeded = string.find(text, QG_ITEM_REQ_STR);
  372.                 if (name ~= nil) then
  373.                     qStatus = qStatus..numItems..";";
  374.                 end
  375.             else
  376.                 if (finished) then
  377.                     qStatus = qStatus.."1;";
  378.                 else
  379.                     qStatus = qStatus.."0;";
  380.                 end
  381.             end
  382.         end
  383.  
  384.  
  385.         local code = "0108";
  386.         if (req == true) then code = "0109"; end
  387.         if (channel == nil) then
  388.             QuestGuru_CommSendPGMessage(code, qLink, qStatus);
  389.         else
  390.             QuestGuru_CommSendMessage(channel, code, qLink, qStatus);
  391.         end
  392.     end
  393. end
  394.  
  395.  
  396. function QuestGuru_SendQuestDescription(index, recipient, qNum)
  397.     local questSelected = GetQuestLogSelection();
  398.  
  399.  
  400.     SelectQuestLogEntry(index);
  401.     local questDescription, questObjectives = GetQuestLogQuestText();
  402.     QuestGuru_CommSendMPMessage("WHISPER", "0206", recipient, qNum, questDescription);
  403.     SelectQuestLogEntry(questSelected);
  404. end
  405.  
  406.  
  407. function QuestGuru_SendQuestObjectivesText(index, recipient, qNum)
  408.     local questSelected = GetQuestLogSelection();
  409.  
  410.  
  411.     SelectQuestLogEntry(index);
  412.     local questDescription, questObjectives = GetQuestLogQuestText();
  413.     QuestGuru_CommSendMPMessage("WHISPER", "0204", recipient, qNum, questObjectives);
  414.     SelectQuestLogEntry(questSelected);
  415. end
  416.  
  417.  
  418. function QuestGuru_FindLink(lastqID)
  419.     local qID, record;
  420.     for qID, record in pairs(QuestGuru_Quests) do
  421.         if (record["_link"] == nil) then
  422.             if (lastqID == nil) then
  423.                 lastqID = qID;
  424.                 QuestGuru_CommSendPGMessage("0201", qID);
  425.                 QuestGuru_CommAddTimer(60, 1, QuestGuru_FindLink, lastqID);
  426.                 return;
  427.             elseif (lastqID == qID) then
  428.                 lastqID = nil;
  429.             end
  430.         end
  431.     end
  432. end
  433.  
  434.  
  435. function QuestGuru_CommUpdateParty()
  436.     local i, v;
  437.     local c = 0;
  438.  
  439.  
  440.     for i, v in pairs(QuestGuru_CommParty) do
  441.         if (not UnitInParty(i)) then
  442.             QuestGuru_CommParty[i] = nil;
  443.         else
  444.             c = c + 1;
  445.         end
  446.     end
  447.  
  448.  
  449.     if ((QuestGuru_CommLastPartyNum == 0) and (IsInGroup() and GetNumSubgroupMembers(LE_PARTY_CATEGORY_HOME) > 0)) then
  450.         QuestGuru_CommSendMessage("PARTY", "0001", QUESTGURU_VERSION);
  451.         QuestGuru_SendCurrentQuestStatus(true, "PARTY");
  452.     end
  453.     QuestGuru_CommLastPartyNum = GetNumSubgroupMembers(LE_PARTY_CATEGORY_HOME);
  454.     QuestGuru_CommPendingPartyUpdate = false;
  455. end
  456.  
  457.  
  458. function QuestGuru_CommUpdateGuild()
  459.     local i;
  460.     local c = 0;
  461.     local guildNum = GetNumGuildMembers();
  462.     local showOffline = GetGuildRosterShowOffline();
  463.     if (QuestGuru_CommGuild == nil) then QuestGuru_CommGuild = {}; end
  464.  
  465.  
  466.     SetGuildRosterShowOffline(true);
  467.     for i=1, guildNum do
  468.         local name, rank, rankIndex, level, class, zone, note, officernote, online, status = GetGuildRosterInfo(i);
  469.         if (not online) then
  470.             if (name) then QuestGuru_CommGuild[name] = nil; end
  471.         else
  472.             if (name and QuestGuru_CommGuild[name]) then
  473.                 c = c + 1;
  474.             end
  475.         end
  476.     end
  477.     SetGuildRosterShowOffline(showOffline);
  478. end
  479.  
  480.  
  481. function QuestGuru_CommListGuild()
  482.     local i, v;
  483.    
  484.     for i, v in pairs(QuestGuru_CommGuild) do
  485.         QuestGuru_Echo(i.." is using QuestGuru v"..v.QGver, true);
  486.     end
  487. end


Bindings.xml
Code:
<Bindings>
    <Binding name="QUESTGURU_TOGGLE" description="Toggle Quest Log" header="QUESTGURU" default="L" category="ADDONS">
        ToggleQuestLog();
    </Binding>
</Bindings>
I didn't add the localization files as they are still ok (I hope). I really do appreciate any and all help getting this addon back on the road and will include acknowledgements for all those that do help because without you I would sink. I do hope that once I do understand what you are helping me with that I can get the QuestGuru Tracker up and going also. I just thought it would be way too much to ask help on both parts here. Not used to asking for too much help. I have asked a couple of small things in the past, but mainly rely on searching the net for the knowledge to help myself. Its just now seeing myself get overwhelmed with this and the emails I have been getting from the people that rely on this addon that I must ask for help. Thanks again in advance.(Also, the full QuestGuru addon is attached as a zip file)
Attached Files
File Type: zip QuestGuru.zip (44.6 KB, 125 views)
__________________
"There's no such thing as too many addons."
Lothaer

My Authored Addons
HOME OF THE FREE, BECAUSE OF THE BRAVE
  Reply With Quote
10-19-14, 08:21 PM   #2
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Well, based on the description and screenshots on the addon's download page, there's just no way to continue this addon in 6.0 in its current form. It looks like its primary function was adding stuff to the quest log, but the quest log no longer exists in the default UI; quests are only shown on the world map now unless you install an addon like LegacyQuest to mimic the original quest log frame. he objectives tracker has also undergone significant changes. There's just not going to be an easy way to move all of the additions and modifications over to the new map-based quest display and new tracker. You'll just have to remove everything, and start porting features over one at a time.

Looking at other quest addons that have already been updated for 6.0 may be helpful. The one I linked above is the only one I'm using, though, so I can't really point you to any specific examples.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
10-19-14, 09:03 PM   #3
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
The returns for GetQuestLogTitle have changed so that will impact some stuff too.
  Reply With Quote
10-19-14, 09:16 PM   #4
JDoubleU00
A Firelord
 
JDoubleU00's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2008
Posts: 463
How much has changed in the Quest Tracker now know as Objectives Window?
  Reply With Quote
10-19-14, 09:28 PM   #5
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
I haven't even gotten started updating my private quest tracker modification yet, but at the very least, all of the object and function names have changed, and I'd guess quite a bit of the internal hierarchy of objects has also changed. The quest item buttons no longer have global names, etc.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
10-19-14, 10:40 PM   #6
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
Pretty much everything has changed. I'm rewriting WFWW.
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Over my head and drowning...

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off