--[[ QuestHistory -- An in-game history log of quests that have been accepted, completed, failed, or abandoned. Originally written by Jasters in 2004. Adopted by Dsanai, after Jasters left World of Warcraft, in late 2005. http://ui.worldofwar.net/ui.php?id=1417 http://www.curse-gaming.com/mod.php?addid=2310 http://www.emerald-order.com/wow/QuestHistory.php FEATURES -- Logs all quests that a player receives and records them in a sortable in-game list -- The user can customize what data the addon logs. Using the default options records the following information for each quest: -- -- Quest title, objectives, rewards, items as shown in the normal QuestLog -- -- NPCs giving and completing the quest -- -- Location of player when quest was accepted/completed -- -- Level of player when quest was accepted/completed -- -- Played time of player when quest was accepted/completed (displayed in days:hours:minutes:seconds format) -- -- Times quest has been abandoned/failed -- -- XP rewarded for quest completion -- -- Money rewarded for quest completion -- Notes can be added to quests -- Quests can be edited and deleted -- Quests can be manually added -- Only records quest data from the time the addon is first used -- Does not modify any of the game's original files VERSION HISTORY v10900-1 -- Added MetaMap support (as alternative to MapNotes). -- Fixed background graphic display issues (thanks to blankstare2@Curse) -- Added slash-command to enable/disable Quest Level display at NPC's. Type /qh levels to toggle. -- Forced current realm's characters to sort to top of the dropdown list. -- Fixed error that occurred with the dropdown list when you had a large number of characters on various servers. -- Changed version structure to match other projects. -- Updated for Patch 10900. v2.8 -- Added quest level display to Quest Selection window at NPC's. Only occurs when there's more than one quest available. v2.72 -- Changed the WorldMap cycler to the zoning event, so hopefully the Blizzard 0,0 bug will be killed PRIOR to any Quest activity. -- Removed the circuit that was getting people stuck on quests in instances. -- Increased individual quest-accept delay to 1 second. This may not be long enough. Let me know! v2.71 -- Removed the 0,0 traps, as I've only received reports of 0,0's inside instances since adding the traps. Since instances are ALWAYS going to be 0,0, we are going to assume that things are kosher at the moment. v2.7 -- Changed Unknown Entity search string to a localized global (so all languages should be covered) (courtesy Asjaskan@Curse) -- Now strips any third-party quest level-adding addon text from the titles (courtesy Asjaskan@Curse) -- Added new trap for 0,0 coordinate bug. -- Added possible 0,0 fix, using a WorldMap show/hide cycler. -- Finally fixed the delay on subsequent accepted quests (speed-accept bug). -- Fixed errors that occurred upon login if you weren't an existing QH user. -- Updated to TOC 1800. v2.6 -- Fixed Unknown Entity bug (more like, plague). -- Added Unknown Entity checks/fixes to the login procedure, and to the Repair module. -- Updated for Patch 1700. ]] ---------------------------------------------------------------------------------------------------- -- Local QuestHistory Variables ---------------------------------------------------------------------------------------------------- local RealmName; -- Name of realm that is being played on local PlayerCharacterName; -- Name of the player's character local DisplayedRealmName; -- Name of realm for which quest data is displayed local DisplayedPlayerCharacterName -- Name of character for which quest data is displayed local questHasBeenRecentlyAccepted; -- Flags if QUEST_LOG_UPDATE event occurs for accepting a quest local questHasBeenRecentlyAbandoned; -- Flags if QUEST_LOG_UPDATE event occurs for abandoning a quest local recentlyAcceptedLocation; -- Accepted location of the most recently accepted quest local recentNPCQuestGiver; -- Name of player's target when most recent quest was accepted local recentlyCompletedQuestID; -- ID of entry in QuestHistory_List for the most recently completed quest local XPBeforeQuestCompletion = 0; -- Amount of XP before completing a quest local XPMaxBeforeQuestCompletion = 0; -- Maximum XP before completing quest, needed in case player levels local timeText; -- Time played when a quest is accepted/completed local timeEvent; -- Event (Accepted, Completed or Logged) to which timeText applies local SortedTable; -- Table to sort the indices of the quest list local sizeSortedTable; -- Current size of SortedTable local currentSortType = "accepted"; -- Keeps track of the current sort type of the quest list local currentSortOrder = "inc"; -- Keeps track of the current sort order of the quest list local currentDetailedQuestID; -- Index of the current quest that is in the DetailFrame local currentSortedID = 0; -- SortedTable index of the quest highlighted in the list frame local currentTitleListID; -- Index of the currently selected TitleList button in the list frame local searchText; -- String to match in quest details timeSinceLastLog = 0; -- Keeps track of the time since the last logging of quest data allowLogging = true; -- Flags whether it is okay to run QuestHistory_LogCurrentQuests() QuestHistory_DelayedConfigInit = nil; QuestHistory_DelayedLoginFired = nil; -- Flags after the initial login delay has fired, so we know to stop it. QuestHistory_Loaded = false; QuestHistory_InsideInstance = false; -- For Sort Dropdown list local QUESTHISTORY_SORT_DROPDOWN_LIST = { { name = SORT_ACCEPTED, sortType = "accepted" }, { name = SORT_TITLE, sortType = "t" }, { name = SORT_LEVEL, sortType = "l" }, { name = SORT_CATEGORY, sortType = "c" }, { name = SORT_TAG, sortType = "y" }, { name = SORT_COMPLETED, sortType = "co" }, { name = SORT_XP, sortType = "x" }, { name = SORT_MONEY, sortType = "m" }, { name = SORT_GIVER, sortType = "g" }, { name = SORT_COMPLETER, sortType = "w" }, }; QUESTHISTORY_SORT_DROPDOWN_MENU_WIDTH = 120; -- Width of the sort dropdown menu QUESTHISTORY_CHARACTER_DROPDOWN_MENU_WIDTH = 150; -- Width of the character dropdown menu QUESTHISTORY_ITEMS_SHOWN = 31; -- Number of lines in the scrolling list -- Colors for quest status local QuestHistoryStatusColor = { }; QuestHistoryStatusColor["completed"] = { r = 0.25, g = 0.50, b = 0.75 }; -- default color of completed quests (blue) QuestHistoryStatusColor["abandoned"] = { r = 0.75, g = 0.00, b = 0.50 }; -- default color of abandoned quests (purple) QuestHistoryStatusColor["failed"] = { r = 1.00, g = 0.50, b = 0.50 }; -- default color of failed quests (pink) -- Flags for logging/showing of quest data local QuestHistoryFlags = { }; QuestHistoryFlags["showAbandoned"] = { index = 1, status = true, text = QUESTHISTORY_SHOW_ABANDONED, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_SHOW_ABANDONED }; QuestHistoryFlags["showCurrent" ] = { index = 2, status = true, text = QUESTHISTORY_SHOW_CURRENT, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_SHOW_CURRENT }; QuestHistoryFlags["showCompleted" ] = { index = 3, status = true, text = QUESTHISTORY_SHOW_COMPLETED, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_SHOW_COMPLETED }; QuestHistoryFlags["logLevel"] = { index = 4, status = true, data = "l", text = QUESTHISTORY_LOG_LEVEL, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_LEVEL }; QuestHistoryFlags["logCategory"] = { index = 5, status = true, data = "c", text = QUESTHISTORY_LOG_CATEGORY, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_CATEGORY }; QuestHistoryFlags["logTag"] = { index = 6, status = true, data = "y", text = QUESTHISTORY_LOG_TAG, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_TAG }; QuestHistoryFlags["logCompletedOrder"] = { index = 7, status = true, data = "co", text = QUESTHISTORY_LOG_COMPLETED_ORDER, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_COMPLETED_ORDER }; QuestHistoryFlags["logDescription"] = { index = 8, status = true, data = "d", text = QUESTHISTORY_LOG_DESCRIPTION, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_DESCRIPTION }; QuestHistoryFlags["logObjectives"] = { index = 9, status = true, data = "o", text = QUESTHISTORY_LOG_OBJECTIVES, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_OBJECTIVES }; QuestHistoryFlags["logObjectivesStatus"] = { index = 10, status = true, data = "os", text = QUESTHISTORY_LOG_OBJECTIVES_STATUS, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_OBJECTIVES_STATUS }; QuestHistoryFlags["logRewards"] = { index = 11, status = true, data = "r", text = QUESTHISTORY_LOG_REWARDS, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_REWARDS }; QuestHistoryFlags["logChoices"] = { index = 12, status = true, data = "i", text = QUESTHISTORY_LOG_CHOICES, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_CHOICES }; QuestHistoryFlags["logSpells"] = { index = 13, status = true, data = "s", text = QUESTHISTORY_LOG_SPELLS, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_SPELLS }; QuestHistoryFlags["logRewardMoney"] = { index = 14, status = true, data = "m", text = QUESTHISTORY_LOG_REWARD_MONEY, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_REWARD_MONEY }; QuestHistoryFlags["logBackgroundMaterial"] = { index = 15, status = true, data = "bg", text = QUESTHISTORY_LOG_BACKGROUND_MATERIAL, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_BACKGROUND_MATERIAL }; QuestHistoryFlags["logRequiredMoney"] = { index = 16, status = true, data = "rm", text = QUESTHISTORY_LOG_REQUIRED_MONEY, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_REQUIRED_MONEY }; QuestHistoryFlags["logXPReward"] = { index = 17, status = true, data = "x", text = QUESTHISTORY_LOG_XP_REWARD, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_XP_REWARD }; QuestHistoryFlags["logQuestGiver"] = { index = 18, status = true, data = "g", text = QUESTHISTORY_LOG_QUEST_GIVER, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_QUEST_GIVER }; QuestHistoryFlags["logQuestCompleter"] = { index = 19, status = true, data = "w", text = QUESTHISTORY_LOG_QUEST_COMPLETER, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_QUEST_COMPLETER }; QuestHistoryFlags["logLevelAccepted"] = { index = 20, status = true, data = "la", text = QUESTHISTORY_LOG_ACCEPTED_LEVEL, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_ACCEPTED_LEVEL }; QuestHistoryFlags["logLevelCompleted"] = { index = 21, status = true, data = "lc", text = QUESTHISTORY_LOG_COMPLETED_LEVEL, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_COMPLETED_LEVEL }; QuestHistoryFlags["logTimeAccepted"] = { index = 22, status = true, data = "ta", text = QUESTHISTORY_LOG_ACCEPTED_TIME, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_ACCEPTED_TIME }; QuestHistoryFlags["logTimeCompleted"] = { index = 23, status = true, data = "tc", text = QUESTHISTORY_LOG_COMPLETED_TIME, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_COMPLETED_TIME }; QuestHistoryFlags["logAcceptedLocation"] = { index = 24, status = true, data = "pa", text = QUESTHISTORY_LOG_ACCEPTED_LOCATION, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_ACCEPTED_LOCATION }; QuestHistoryFlags["logCompletedLocation"] = { index = 25, status = true, data = "pc", text = QUESTHISTORY_LOG_COMPLETED_LOCATION, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_COMPLETED_LOCATION }; QuestHistoryFlags["removePortQuests"] = { index = 26, status = false, text = QUESTHISTORY_REMOVE_PORT_QUESTS, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_REMOVE_PORT_QUESTS }; QuestHistoryFlags["removeDuplicates"] = { index = 27, status = false, text = QUESTHISTORY_REMOVE_DUPLICATES, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_REMOVE_DUPLICATES }; QuestHistoryFlags["allowEditing"] = { index = 28, status = false, text = QUESTHISTORY_ALLOW_EDITING, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_ALLOW_EDITING }; QuestHistoryFlags["allowDeleting"] = { index = 29, status = false, text = QUESTHISTORY_ALLOW_DELETING, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_ALLOW_DELETING }; QuestHistoryFlags["logPortQuests"] = { index = 30, status = false, text = QUESTHISTORY_LOG_PORT_QUESTS, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_PORT_QUESTS }; local QuestHistoryData = { }; QuestHistoryData["t"] = { old = "title", box = "Title", type = "string", tab = 22 }; QuestHistoryData["l"] = { old = "level", box = "Level", type = "number", tab = 6 }; QuestHistoryData["c"] = { old = "location", box = "Category", type = "string", tab = 8 }; QuestHistoryData["y"] = { old = "tag", box = "Tag", type = "string", tab = 9 }; QuestHistoryData["d"] = { old = "description", box = "Description", type = "string", tab = 24 }; QuestHistoryData["o"] = { old = "objectives", box = "Objectives", type = "string", tab = 23 }; QuestHistoryData["la"] = { old = "levelAccepted", box = "LevelAccepted", type = "number", tab = 1 }; QuestHistoryData["ll"] = { old = "levelLogged", type = "number" }; QuestHistoryData["lc"] = { old = "levelCompleted", box = "LevelCompleted", type = "number", tab = 2 }; QuestHistoryData["rm"] = { old = "requiredMoney", type = "number" }; QuestHistoryData["m"] = { old = "rewardMoney", box = "MoneyRewarded", type = "number", tab = 3 }; QuestHistoryData["bg"] = { old = "material", type = "string" }; QuestHistoryData["g"] = { old = "NPCGiver", box = "QuestGiver", type = "string", tab = 10 }; QuestHistoryData["w"] = { old = "NPCCompleter", box = "QuestCompleter", type = "string", tab = 11 }; QuestHistoryData["ta"] = { old = "timeAccepted", box = "TimeAccepted", type = "string", tab = 18 }; QuestHistoryData["tl"] = { old = "timeLogged", type = "string" }; QuestHistoryData["tc"] = { old = "timeCompleted", box = "TimeCompleted", type = "string", tab = 19 }; QuestHistoryData["co"] = { old = "completedOrder", box = "CompletedOrder", type = "number", tab = 7 }; QuestHistoryData["a"] = { old = "isAbandoned", type = "boolean" }; QuestHistoryData["f"] = { old = "isFailed", type = "boolean" }; QuestHistoryData["ac"] = { old = "abandonedCount", box = "TimesAbandoned", type = "number", tab = 20 }; QuestHistoryData["fc"] = { old = "countFailed", box = "TimesFailed", type = "number", tab = 21 }; QuestHistoryData["n"] = { old = "note", type = "string" }; QuestHistoryData["x"] = { old = "XPReward", box = "XPRewarded", type = "number", tab = 4 }; QuestHistoryData["ao"] = { box = "AcceptedOrder", type = "number", tab = 5 }; QuestHistoryData["az"] = { box = "AcceptedZone", type = "string", tab = 12 }; QuestHistoryData["ax"] = { box = "AcceptedX", type = "number", tab = 13 }; QuestHistoryData["ay"] = { box = "AcceptedY", type = "number", tab = 14 }; QuestHistoryData["cz"] = { box = "CompletedZone", type = "string", tab = 15 }; QuestHistoryData["cx"] = { box = "CompletedX", type = "number", tab = 16 }; QuestHistoryData["cy"] = { box = "CompletedY", type = "number", tab = 17 }; QuestHistoryData["r"] = { type = "item" }; QuestHistoryData["i"] = { type = "item" }; QuestHistoryData["s"] = { type = "spell" }; QuestHistoryData["pa"] = { type = "string" }; QuestHistoryData["pc"] = { type = "string" }; QuestHistoryData["os"] = { type = "objective" }; QUESTHISTORY_MAX_LEVEL = 60; -- Function hooks local originalQuestDetailAcceptButton_OnClick; -- Game functions that need to be local originalQuestRewardCompleteButton_OnClick; -- hooked because some quest logging local originalQuestLogFrameAbandonButton_OnClick; -- needs to be done when they are called local originalChatFrame_DisplayTimePlayed; -- To prevent played time from being displayed in chat ---------------------------------------------------------------------------------------------------- -- Global QuestHistory Variables ---------------------------------------------------------------------------------------------------- QUESTHISTORY_VERSION = 2.9; -- Version of QuestHistory QUESTHISTORY_ITEM_HEIGHT = 14; -- Height of the item buttons in the list frame UIPanelWindows["QuestHistoryFrame"] = { area = "left" , pushable = 12 }; UIPanelWindows["QuestHistoryOptionsFrame"] = { area = "left" , pushable = 0 }; UIPanelWindows["QuestHistoryDetailFrame"] = { area = "left" , pushable = 0 }; UIPanelWindows["QuestHistoryEditFrame"] = { area = "left" , pushable = 0 }; UIPanelWindows["QuestHistoryConfirmFrame"] = { area = "left" , pushable = 0 }; QuestHistory_StatusColorType = ""; -- Type of quest status when changing color ---------------------------------------------------------------------------------------------------- -- Internal Functions ---------------------------------------------------------------------------------------------------- -- Initializes the dropdown box with the available selections local function QuestHistoryFrameSortDropDown_Initialize() local info; for i = 1, getn(QUESTHISTORY_SORT_DROPDOWN_LIST), 1 do info = { }; info.text = QUESTHISTORY_SORT_DROPDOWN_LIST[i].name; info.func = QuestHistoryFrameSortDropDownButton_OnClick; UIDropDownMenu_AddButton(info); end end local function QuestHistoryOptionsFrameCharacterDropDown_Initialize() local info; local lineCount = 0; local thisRealm = GetRealmName(); -- Current realm first if (QuestHistory_List[thisRealm]) then info = { }; info.text = thisRealm; info.isTitle = 1; UIDropDownMenu_AddButton(info); lineCount = lineCount + 1; for charIndex, charValue in QuestHistory_List[thisRealm] do info = { }; info.text = " "..charIndex; info.value = thisRealm; info.func = QuestHistoryOptionsFrameCharacterDropDownButton_OnClick; UIDropDownMenu_AddButton(info); lineCount = lineCount + 1; end end for realmIndex, realmValue in QuestHistory_List do if (realmIndex ~= thisRealm and lineCount <= 25) then -- Others, up to limit info = { }; info.text = realmIndex; info.isTitle = 1; UIDropDownMenu_AddButton(info); lineCount = lineCount + 1; for charIndex, charValue in realmValue do info = { }; info.text = " "..charIndex; info.value = realmIndex; info.func = QuestHistoryOptionsFrameCharacterDropDownButton_OnClick; UIDropDownMenu_AddButton(info); lineCount = lineCount + 1; end end end end -- Comparison function to sort table local function QuestHistory_SortComparison(index1, index2) if ( currentSortType ~= "accepted" ) then -- Get the sort values that are to be compared local sort1 = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index1][currentSortType]; local sort2 = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index2][currentSortType]; if ( currentSortOrder == "dec" ) then -- Swap sort values if sorting in decremented order sort1, sort2 = sort2, sort1; end -- Make sure sort1 is not nil and is compatible with sort2 if ( sort1 == nil ) then if ( type(sort2) == "string" ) then sort1 = ""; else sort1 = 0; end end -- Make sure sort2 is not nil and is compatible with sort1 if ( sort2 == nil ) then if ( type(sort1) == "string" ) then sort2 = ""; else sort2 = 0; end end -- If sorting by completed order, make sure incomplete quests are valued more than completed quests -- and that current quests are valued more than abandoned quests if ( currentSortType == "co" ) then if ( sort1 ~= sort2 ) then if ( sort1 == 0 ) then sort1 = sort2 + 1; elseif ( sort2 == 0 ) then sort2 = sort1 + 1; end else if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index1].a ) then sort1 = -1; end if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index2].a ) then sort2 = -1; end end end -- If sort1 is different from sort2, return comparison of sort values if ( sort1 ~= sort2 ) then return sort1 < sort2; end else if ( currentSortOrder == "dec" ) then -- Swap index values if sorting in decremented order index1, index2 = index2, index1; end end -- Return comparison of index values return index1 < index2; end -- Returns true if data in value table match the current criteria, false otherwise local function QuestHistory_MatchesSearch(index, value) -- Check if quest is completed if ( value.co ) then -- If it is and not showing completed quests, return false if ( not QuestHistoryFlags["showCompleted"].status ) then return false; end -- Check if quest is abandoned elseif ( value.a ) then -- If it is and not showing abandoned quests, return false if ( not QuestHistoryFlags["showAbandoned"].status ) then return false; end -- Quest must be current else -- If not showing current quests, return false if ( not QuestHistoryFlags["showCurrent"].status ) then return false; end end -- If there is no search text defined, return true if ( not searchText ) then return true; else -- Otherwise, cycle through quest details looking for search text for i, v in value do if ( string.find(strupper(tostring(value[i])), strupper(searchText)) ) then return true; end end end -- Return false if search text is defined and not found in the quest details return false; end -- Builds the SortedTable array and populates it with the indices of QuestHistory_List that match -- the current criteria. This array can then be sorted without changing the original list. local function QuestHistory_BuildSortedTable() local iNew = 1; -- Initialize blank table SortedTable = { }; -- Populate table with quest IDs that match current criteria for index, value in QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName] do if ( QuestHistory_MatchesSearch(index, value) ) then SortedTable[iNew] = index; iNew = iNew + 1; end end -- Store size of sorted table sizeSortedTable = iNew - 1; if ( QUESTHISTORY_SORT_DROPDOWN_LIST[UIDropDownMenu_GetSelectedID(QuestHistoryFrameSortDropDown)].sortType ) then -- Sort table table.sort(SortedTable, QuestHistory_SortComparison); end -- Find sorted table ID that matches the currently selected quest currentSortedID = 0; for index, value in SortedTable do if ( currentDetailedQuestID == SortedTable[index] ) then currentSortedID = index; end end end -- Refreshes the display of the QuestHistory_Frame and the scrolling list. local function QuestHistory_Refresh() -- Build the array that contains the indices to sort and display QuestHistory_BuildSortedTable(); -- Check if the currently selected quest is displayed in the scrollframe or if scrolling is needed to display it if ( currentSortedID and ( currentSortedID > 0 ) and ( (currentSortedID - FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame) ) <=0 or ( currentSortedID - FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame) ) >= 32 ) ) then -- Calculate new offset to set scrollframe to so that currently selected quest is displayed local newOffset = currentSortedID * QUESTHISTORY_ITEM_HEIGHT - (QuestHistoryListScrollFrame:GetHeight() / 2); if ( newOffset < 0 ) then newOffset = 0; end -- Scroll frame and set the new value QuestHistoryListScrollFrameScrollBar:SetValue(newOffset); end -- Store the title list ID for the currently selected quest currentTitleListID = currentSortedID - FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame); QuestHistory_Update(); end -- Toggles the currently selected sorting method from increasing to decreasing or vice versa local function QuestHistory_SetSortOrder() -- Get selected sort type local sortType = QUESTHISTORY_SORT_DROPDOWN_LIST[UIDropDownMenu_GetSelectedID(QuestHistoryFrameSortDropDown)].sortType; -- If selected sort type is the same as the current sort type then toggle between incrementing and decrementing if ( currentSortType == sortType and currentSortOrder == "inc" ) then currentSortOrder = "dec"; else currentSortOrder = "inc"; end -- Set current sort type to the one selected currentSortType = sortType; -- Refresh the display QuestHistory_Refresh(); end -- Displays and updates the reward items portion of the detail view for the quest specified by questIndex -- Most of the code has been adapted from QuestFrameItems_Update() located in QuestFrame.lua local function QuestHistory_Detail_Items_Update(questIndex) local questItemName = "QuestHistoryDetailItem"; local questItemReceiveText = QuestHistoryDetailItemReceiveText; local spacerFrame = QuestHistoryDetailSpacerFrame; -- Get reward data for quest local numQuestRewards, numQuestChoices; if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["r"] ) then numQuestRewards = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["r"]); end if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["i"] ) then numQuestChoices = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["i"]); end if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["s"] ) then numQuestSpellRewards = 1; else numQuestSpellRewards = 0; end local money = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].m; local material = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].bg; -- Set variables to default values if the corresponding data is not in log if ( not numQuestRewards ) then numQuestRewards = 0; end if ( not numQuestChoices ) then numQuestChoices = 0; end if ( not money ) then money = 0; end if ( not material ) then material = "Parchment"; end -- Calculate total number of rewards local totalRewards = numQuestRewards + numQuestChoices + numQuestSpellRewards; -- If there is any type of reward, show the reward frame if ( totalRewards == 0 and money == 0 ) then QuestHistoryDetailRewardTitleText:Hide(); else QuestHistoryDetailRewardTitleText:Show(); QuestFrame_SetTitleTextColor(QuestHistoryDetailRewardTitleText, material); QuestFrame_SetAsLastShown(QuestHistoryDetailRewardTitleText, spacerFrame); end -- If there is money rewarded, show the money frame and populate it if ( money == 0 ) then QuestHistoryDetailMoneyFrame:Hide(); else QuestHistoryDetailMoneyFrame:Show(); QuestFrame_SetAsLastShown(QuestHistoryDetailMoneyFrame, spacerFrame); MoneyFrame_Update("QuestHistoryDetailMoneyFrame", money); end -- Hide the unused frames for i = totalRewards + 1, MAX_NUM_ITEMS, 1 do getglobal(questItemName..i):Hide(); end -- If there are items that can be chosen, show the choose items frame and populate it local questItem, name, texture, numItems; if ( numQuestChoices > 0 ) then QuestHistoryDetailItemChooseText:Show(); QuestFrame_SetTextColor(QuestHistoryDetailItemChooseText, material); QuestFrame_SetAsLastShown(QuestHistoryDetailItemChooseText, spacerFrame); -- Cycle through the quest choices and set up the buttons with the data for i = 1, numQuestChoices, 1 do questItem = getglobal(questItemName..i); questItem.type = "choice"; link = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["i"][i].l; if ( link ) then _, _, name = string.find(link, "|c%x+|H%w+:%d+:%d+:%d+:%d+|h%[(.-)%]|h|r"); end texture = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["i"][i].t; numItems = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["i"][i].a; if ( numItems == nil or numItems == 0 ) then numItems = 1; end -- Set the ID for the choice and show the item questItem:SetID(i); questItem:Show(); -- For the tooltip questItem.rewardType = "item" QuestFrame_SetAsLastShown(questItem, spacerFrame); getglobal(questItemName..i.."Name"):SetText(name); SetItemButtonCount(questItem, numItems); SetItemButtonTexture(questItem, texture); SetItemButtonTextureVertexColor(questItem, 1.0, 1.0, 1.0); SetItemButtonNameFrameVertexColor(questItem, 1.0, 1.0, 1.0); -- Anchor this item correctly since the items are shown two to a line if ( i > 1 ) then if ( mod(i, 2) == 1 ) then questItem:SetPoint("TOPLEFT", questItemName..(i - 2), "BOTTOMLEFT", 0, -2); else questItem:SetPoint("TOPLEFT", questItemName..(i - 1), "TOPRIGHT", 1, 0); end else questItem:SetPoint("TOPLEFT", "QuestHistoryDetailItemChooseText", "BOTTOMLEFT", -3, -5); end end else -- Hide the choose items frame if there are no choices QuestHistoryDetailItemChooseText:Hide(); end -- If there are quest rewards, show the receive items frame and populate it with reward data if ( numQuestRewards > 0 or money > 0 or numQuestSpellRewards > 0 ) then QuestFrame_SetTextColor(questItemReceiveText, material); -- Anchor the reward text differently if there are choosable rewards if ( numQuestChoices > 0 ) then questItemReceiveText:SetText(TEXT(REWARD_ITEMS)); local index = numQuestChoices; if ( mod(index, 2) == 0 ) then index = index - 1; end questItemReceiveText:SetPoint("TOPLEFT", questItemName..index, "BOTTOMLEFT", 3, -5); else questItemReceiveText:SetText(TEXT(REWARD_ITEMS_ONLY)); questItemReceiveText:SetPoint("TOPLEFT", "QuestHistoryDetailRewardTitleText", "BOTTOMLEFT", 3, -5); end -- Show the receive items frame and set it as the last shown frame questItemReceiveText:Show(); QuestFrame_SetAsLastShown(questItemReceiveText, spacerFrame); -- Setup mandatory rewards for i = 1, numQuestRewards, 1 do questItem = getglobal(questItemName..(i + numQuestChoices)); questItem.type = "reward"; link = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["r"][i].l; if ( link ) then _, _, name = string.find(link, "|c%x+|H%w+:%d+:%d+:%d+:%d+|h%[(.-)%]|h|r"); end texture = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["r"][i].t; numItems = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["r"][i].a; if ( numItems == nil or numItems == 0 ) then numItems = 1; end -- Set the ID for the reward and show the item questItem:SetID(i); questItem:Show(); -- For the tooltip questItem.rewardType = "item"; QuestFrame_SetAsLastShown(questItem, spacerFrame); getglobal(questItemName..(i + numQuestChoices).."Name"):SetText(name); SetItemButtonCount(questItem, numItems); SetItemButtonTexture(questItem, texture); SetItemButtonTextureVertexColor(questItem, 1.0, 1.0, 1.0); SetItemButtonNameFrameVertexColor(questItem, 1.0, 1.0, 1.0); -- Anchor this item correctly since the items are shown two to a line if ( i > 1 ) then if ( mod(i, 2) == 1 ) then questItem:SetPoint("TOPLEFT", questItemName..((i + numQuestChoices) - 2), "BOTTOMLEFT", 0, -2); else questItem:SetPoint("TOPLEFT", questItemName..((i + numQuestChoices) - 1), "TOPRIGHT", 1, 0); end else questItem:SetPoint("TOPLEFT", "QuestHistoryDetailItemReceiveText", "BOTTOMLEFT", -3, -5); end end -- Setup spell reward if ( numQuestSpellRewards > 0 ) then texture = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["s"].t; name = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["s"].n; -- Show the spell reward button questItem = getglobal(questItemName..(numQuestRewards + numQuestChoices + 1)); questItem.type = "spell"; questItem:Show(); -- For the tooltip questItem.rewardType = "spell"; SetItemButtonTexture(questItem, texture); getglobal(questItemName..(numQuestRewards + numQuestChoices + 1).."Name"):SetText(name); -- Anchor the spell depending on whether it shares a line with a reward item or if it needs a line of its own if ( numQuestRewards > 0 ) then if ( mod(numQuestRewards, 2) == 0 ) then questItem:SetPoint("TOPLEFT", questItemName..((numQuestRewards + numQuestChoices) - 1), "BOTTOMLEFT", 0, -2); else questItem:SetPoint("TOPLEFT", questItemName..((numQuestRewards + numQuestChoices)), "TOPRIGHT", 1, 0); end else questItem:SetPoint("TOPLEFT", "QuestHistoryDetailItemReceiveText", "BOTTOMLEFT", -3, -5); end end else questItemReceiveText:Hide(); end end -- Displays and updates all non-item details for the quest specified by questIndex -- Most of the code adapted from QuestLog_UpdateQuestDetails() located in QuestLogFrame.lua local function QuestHistory_Detail_Update(questIndex) local spacerFrame = QuestHistoryDetailSpacerFrame; --Hide and Show the appropriate frames QuestHistoryDetailNotesScrollFrame:Hide(); QuestHistoryDetailSaveButton:Hide(); QuestHistoryDetailListScrollFrame:Show(); QuestHistoryDetailEditButton:Show(); -- Get information for frame title local QuestHistoryDetailTitle = QuestHistoryDetailTitle; local questTitle = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].t; local tagtext = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].y; local level = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].l; -- Set variables to default values if the corresponding data is not in log if ( not questTitle ) then questTitle = ""; end if ( tagtext and tagtext ~= "" ) then tagtext = " ["..tagtext.."]"; else tagtext = ""; end if ( not level ) then level = ""; end -- Set the title of the frame to show quest title, level and tag QuestHistoryDetailTitle:SetText(format(TEXT(QUESTHISTORY_DETAIL_TITLE_FORMAT), questTitle, level, tagtext)); QuestHistoryDetailTitle:Show(); -- Display the level of player when quest was accepted/logged local levelAccepted = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].la; if ( levelAccepted ) then QuestHistoryDetailLevelAcceptedTitle:SetText(QUESTHISTORY_LEVEL_ACCEPTED_TITLE); else levelAccepted = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].ll; QuestHistoryDetailLevelAcceptedTitle:SetText(QUESTHISTORY_LEVEL_LOGGED_TITLE); end if ( levelAccepted ) then QuestHistoryDetailLevelAcceptedText:SetText(levelAccepted); QuestHistoryDetailLevelAcceptedText:Show(); else QuestHistoryDetailLevelAcceptedText:Hide(); end -- Display the level of player when quest was completed local levelCompleted = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].lc; if ( levelCompleted ) then QuestHistoryDetailLevelCompletedText:SetText(levelCompleted); QuestHistoryDetailLevelCompletedText:Show(); else QuestHistoryDetailLevelCompletedText:Hide(); end -- Display the money reward for quest local rewardMoney = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].m; if ( rewardMoney ) then QuestHistoryDetailMoneyRewardedText:SetText(rewardMoney); QuestHistoryDetailMoneyRewardedText:Show(); else QuestHistoryDetailMoneyRewardedText:Hide(); end -- Display the XP gained for quest local XPReward = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].x; if ( XPReward ) then QuestHistoryDetailXPRewardedText:SetText(XPReward); QuestHistoryDetailXPRewardedText:Show(); else QuestHistoryDetailXPRewardedText:Hide(); end -- Display the name of the quest giver local giver = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].g; if ( giver ) then QuestHistoryDetailQuestGiverText:SetText(giver); QuestHistoryDetailQuestGiverText:Show(); else QuestHistoryDetailQuestGiverText:Hide(); end -- Display the name of the quest completer local completer = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].w; if ( completer ) then QuestHistoryDetailQuestCompleterText:SetText(completer); QuestHistoryDetailQuestCompleterText:Show(); else QuestHistoryDetailQuestCompleterText:Hide(); end -- Display the location where quest was accepted if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].pa ) then local _, _, acceptedZone, acceptedX, acceptedY = string.find(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].pa, "(.*):(.*):(.*)"); QuestHistoryDetailAcceptedLocationText:SetText(acceptedZone.." ("..floor(tonumber(acceptedX) * 100)..", "..floor(tonumber(acceptedY) * 100)..")"); QuestHistoryDetailAcceptedLocationButton:Show(); else QuestHistoryDetailAcceptedLocationButton:Hide(); end -- Display the location where quest was completed if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].pc ) then local _, _, completedZone, completedX, completedY = string.find(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].pc, "(.*):(.*):(.*)"); QuestHistoryDetailCompletedLocationText:SetText(completedZone.." ("..floor(tonumber(completedX) * 100)..", "..floor(tonumber(completedY) * 100)..")"); QuestHistoryDetailCompletedLocationButton:Show(); else QuestHistoryDetailCompletedLocationButton:Hide(); end -- Display the time played when quest was accepted/logged local timeAccepted = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].ta; if ( timeAccepted ) then QuestHistoryDetailTimeAcceptedTitle:SetText(QUESTHISTORY_TIME_ACCEPTED_TITLE); else timeAccepted = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].tl; QuestHistoryDetailTimeAcceptedTitle:SetText(QUESTHISTORY_TIME_LOGGED_TITLE); end if ( timeAccepted ) then QuestHistoryDetailTimeAcceptedText:SetText(timeAccepted); QuestHistoryDetailTimeAcceptedText:Show(); else QuestHistoryDetailTimeAcceptedText:Hide(); end -- Display the time played when quest was completed local timeCompleted = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].tc; if ( timeCompleted) then QuestHistoryDetailTimeCompletedText:SetText(timeCompleted); QuestHistoryDetailTimeCompletedText:Show(); else QuestHistoryDetailTimeCompletedText:Hide(); end -- Display the number of times quest has been abandoned local abandonCount = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].ac; if ( not abandonCount ) then abandonCount = 0; end QuestHistoryDetailTimesAbandonedText:SetText(abandonCount); QuestHistoryDetailTimesAbandonedText:Show(); -- Display the number of times quest has been failed local failCount = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].fc; if ( not failCount ) then failCount = 0; end QuestHistoryDetailTimesFailedText:SetText(failCount); QuestHistoryDetailTimesFailedText:Show(); -- Display the quest note if the player has entered one local note = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].n; if ( note ) then QuestHistoryDetailListNotes:SetText(note); QuestHistoryDetailListNotes:Show(); else QuestHistoryDetailListNotes:Hide(); end -- Display the quest title if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].f ) then questTitle = questTitle.." = ("..TEXT(FAILED)..")"; end QuestHistoryDetailQuestTitle:SetText(questTitle); -- Display the quest objective local questObjectives = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].o; if ( not questObjectives ) then questObjectives = ""; end QuestHistoryDetailObjectivesText:SetText(questObjectives); -- If there are objectives, then set their text and display them local numObjectives = 0; if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["os"] ) then numObjectives = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["os"]); end for i = 1, numObjectives, 1 do local string = getglobal("QuestHistoryDetailObjective"..i); local text = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["os"][i].t; if ( text ) then if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["os"][i].f ) then string:SetTextColor(0.2, 0.2, 0.2); text = text.." ("..TEXT(COMPLETE)..")"; else string:SetTextColor(0, 0, 0); end string:SetText(text); string:Show(); QuestFrame_SetAsLastShown(string, spacerFrame); end end for i = numObjectives + 1, MAX_OBJECTIVES, 1 do getglobal("QuestHistoryDetailObjective"..i):Hide(); end -- If there's money required then anchor and display it local requiredMoney = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].rm; if ( not requiredMoney ) then requiredMoney = 0; end if ( requiredMoney > 0 ) then if ( numObjectives > 0 ) then QuestHistoryDetailRequiredMoneyText:SetPoint("TOPLEFT", "QuestHistoryDetailObjective"..numObjectives, "BOTTOMLEFT", 0, -4); else QuestHistoryDetailRequiredMoneyText:SetPoint("TOPLEFT", "QuestHistoryDetailObjectivesText", "BOTTOMLEFT", 0, -10); end MoneyFrame_Update("QuestHistoryDetailRequiredMoneyFrame", requiredMoney); if ( ( not QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].co ) and ( requiredMoney > GetMoney() ) ) then -- Not enough money for a current quest QuestHistoryDetailRequiredMoneyText:SetTextColor(0, 0, 0); SetMoneyFrameColor("QuestHistoryDetailRequiredMoneyFrame", 1.0, 0.1, 0.1); else QuestHistoryDetailRequiredMoneyText:SetTextColor(0.2, 0.2, 0.2); SetMoneyFrameColor("QuestHistoryDetailRequiredMoneyFrame", 1.0, 1.0, 1.0); end QuestHistoryDetailRequiredMoneyText:Show(); QuestHistoryDetailRequiredMoneyFrame:Show(); else QuestHistoryDetailRequiredMoneyText:Hide(); QuestHistoryDetailRequiredMoneyFrame:Hide(); end if ( requiredMoney > 0 ) then QuestHistoryDetailDescriptionTitle:SetPoint("TOPLEFT", "QuestHistoryDetailRequiredMoneyText", "BOTTOMLEFT", 0, -10); elseif ( numObjectives > 0 ) then QuestHistoryDetailDescriptionTitle:SetPoint("TOPLEFT", "QuestHistoryDetailObjective"..numObjectives, "BOTTOMLEFT", 0, -10); else QuestHistoryDetailDescriptionTitle:SetPoint("TOPLEFT", "QuestHistoryDetailObjectivesText", "BOTTOMLEFT", 0, -10); end -- Display the quest description local questDescription = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].d; if ( not questDescription ) then questDescription = ""; end QuestHistoryDetailQuestDescription:SetText(questDescription); QuestFrame_SetAsLastShown(QuestHistoryDetailQuestDescription, spacerFrame); -- If there are rewards, display the reward frame which is populated from QuestHistory_Detail_Items_Update() local numRewards, numChoices; if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["r"] ) then numRewards = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["r"]); end if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["i"] ) then numChoices = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["i"]); end if ( not numRewards ) then numRewards = 0; end if ( not numChoices ) then numChoices = 0; end if ( not rewardMoney ) then rewardMoney = 0; end if ( (numRewards + numChoices + rewardMoney) > 0 ) then QuestHistoryDetailRewardTitleText:Show(); QuestFrame_SetAsLastShown(QuestHistoryDetailRewardTitleText, spacerFrame); else QuestHistoryDetailRewardTitleText:Hide(); end QuestHistory_Detail_Items_Update(questIndex); QuestHistoryDetailListScrollFrameScrollBar:SetValue(0); QuestHistoryDetailListScrollFrame:UpdateScrollChildRect(); QuestHistoryDetailScrollFrameScrollBar:SetValue(0); QuestHistoryDetailScrollFrame:UpdateScrollChildRect(); end -- Process the stored link of an item to cut out the color and name and only return the hyperlink local function QuestHistory_ProcessLinks(text) if ( text ) then local _, _, item = string.find(text, "|c%x+|H(%w+:%d+:%d+:%d+:%d+)|h%[.-%]|h|r"); return item; end end -- Upgrades the data in QuestHistory_List to the latest format local function QuestHistory_UpgradeData() for realmIndex, realmValue in QuestHistory_List do for charIndex, charValue in realmValue do for questIndex, questValue in charValue do for dataIndex, dataValue in QuestHistoryData do local data = questValue[dataValue.old]; if ( data ~= nil ) then if ( data ~= 0 and data ~= false and data ~= "Parchment" ) then if ( dataIndex == "ta" or dataIndex == "tl" or dataIndex == "tc" ) then local _, _, days = string.find(data, "(%d+):.*"); local _, _, hrs = string.find(data, "%d+:(%d+):.*"); local _, _, mins = string.find(data, "%d+:%d+:(%d+):.*"); local _, _, secs = string.find(data, "%d+:%d+:%d+:(%d+)"); if ( days == nil ) then days = 0; end if ( hrs == nil ) then hrs = 0; end if ( mins == nil ) then mins = 0; end if ( secs == nil ) then secs = 0; end questValue[dataIndex] = format(TEXT(QUESTHISTORY_TIME_FORMAT), days, hrs, mins, secs); else questValue[dataIndex] = data; end end questValue[dataValue.old] = nil; end end -- Converts location data to new format if ( questValue.acceptedZone or questValue.acceptedX or questValue.acceptedY ) then if ( questValue.acceptedZone and questValue.acceptedX and questValue.acceptedY ) then questValue.pa = questValue.acceptedZone..":"..questValue.acceptedX..":"..questValue.acceptedY; end questValue.acceptedZone = nil; questValue.acceptedX = nil; questValue.acceptedY = nil; end if ( questValue.completedZone or questValue.completedX or questValue.completedY ) then if ( questValue.completedZone and questValue.completedX and questValue.completedY ) then questValue.pc = questValue.completedZone..":"..questValue.completedX..":"..questValue.completedY; end questValue.completedZone = nil; questValue.completedX = nil; questValue.completedY = nil; end -- Converts objectives status data to new format if ( questValue.numObjectives ) then if ( questValue.numObjectives > 0) then questValue.os = { }; for obIndex = 1, questValue.numObjectives, 1 do questValue["os"][obIndex] = { }; questValue["os"][obIndex].t = questValue["objective"..obIndex.."Text"]; questValue["os"][obIndex].f = questValue["objective"..obIndex.."Finished"]; questValue["objective"..obIndex.."Text"] = nil; questValue["objective"..obIndex.."Finished"] = nil; end end questValue.numObjectives = nil; end -- Converts reward item data to new format if ( questValue.numRewards ) then if ( questValue.numRewards > 0 ) then questValue.r = { }; for rIndex = 1, questValue.numRewards, 1 do questValue["r"][rIndex] = { }; questValue["r"][rIndex].t = questValue["reward"..rIndex.."Texture"]; if ( questValue["reward"..rIndex.."NumItems"] > 1 ) then questValue["r"][rIndex].a = questValue["reward"..rIndex.."NumItems"]; end questValue["r"][rIndex].l = questValue["reward"..rIndex.."ItemLink"]; questValue["reward"..rIndex.."Name"] = nil; questValue["reward"..rIndex.."Texture"] = nil; questValue["reward"..rIndex.."NumItems"] = nil; questValue["reward"..rIndex.."IsUsable"] = nil; questValue["reward"..rIndex.."ItemLink"] = nil; end end questValue.numRewards = nil; end -- Converts choice item data to new format if ( questValue.numChoices ) then if ( questValue.numChoices > 0 ) then questValue.i = { }; for iIndex = 1, questValue.numChoices, 1 do questValue["i"][iIndex] = { }; questValue["i"][iIndex].t = questValue["choice"..iIndex.."Texture"]; if ( questValue["choice"..iIndex.."NumItems"] > 1 ) then questValue["i"][iIndex].a = questValue["choice"..iIndex.."NumItems"]; end questValue["i"][iIndex].l = questValue["choice"..iIndex.."ItemLink"]; questValue["choice"..iIndex.."Name"] = nil; questValue["choice"..iIndex.."Texture"] = nil; questValue["choice"..iIndex.."NumItems"] = nil; questValue["choice"..iIndex.."IsUsable"] = nil; questValue["choice"..iIndex.."ItemLink"] = nil; end end questValue.numChoices = nil; end -- Converts spell reward data to new format if ( questValue.numSpells ) then if ( questValue.numSpells > 0 ) then questValue.s = { }; questValue["s"].t = questValue.spellTexture; questValue["s"].n = questValue.spellName; end questValue.numSpells = nil; questValue.spellTexture = nil; questValue.spellName = nil; questValue.spellItemLink = nil; end if ( questValue.backgroundMaterial ) then if ( questValue.backgroundMaterial ~= "" and questValue.backgroundMaterial ~= "Parchment" ) then questValue.bg = questValue.backgroundMaterial; end questValue.backgroundMaterial = nil; end if ( questValue.NPCQuestGiver ) then if ( questValue.NPCQuestGiver ~= "" ) then questValue.g = questValue.NPCQuestGiver; end questValue.NPCQuestGiver = nil; end end end end end -- Purges unwanted data from logged quests local function QuestHistory_PurgeData() for index, value in QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName] do for i, v in QuestHistoryFlags do if ( not v.status ) then if ( v.data == "la" ) then value.la = nil; value.ll = nil; elseif ( v.data == "ta" ) then value.ta = nil; value.tl = nil; elseif ( v.data ) then value[v.data] = nil; end end end end QuestHistory_Refresh(); end -- Edits a quest in the player's history local function QuestHistory_EditQuest(questID) for index, value in QuestHistoryData do if ( value.box ) then local data = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questID][index]; if ( data == nil ) then getglobal("QuestHistoryEdit"..value.box.."EditBox"):SetText(""); else getglobal("QuestHistoryEdit"..value.box.."EditBox"):SetText(data); end end end QuestHistoryEditAcceptedOrderEditBox:SetText(questID); local location = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questID].pa; if ( location ) then local _, _, zone = string.find(location, "(.-):.*:.*"); local _, _, x = string.find(location, ".-:(.-):.*"); local _, _, y = string.find(location, ".-:.-:(.*)"); QuestHistoryEditAcceptedZoneEditBox:SetText(zone); QuestHistoryEditAcceptedXEditBox:SetText(x * 100); QuestHistoryEditAcceptedYEditBox:SetText(y * 100); end location = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questID].pc; if ( location ) then local _, _, zone = string.find(location, "(.-):.*:.*"); local _, _, x = string.find(location, ".-:(.-):.*"); local _, _, y = string.find(location, ".-:.-:(.*)"); QuestHistoryEditCompletedZoneEditBox:SetText(zone); QuestHistoryEditCompletedXEditBox:SetText(x * 100); QuestHistoryEditCompletedYEditBox:SetText(y * 100); end end -- Loads the text from the EditFrame and stores it in data local function QuestHistory_GetEditData() local data = { }; local questID; for index, value in QuestHistoryData do if ( value.box ) then if ( value.type == "string" ) then data[index] = getglobal("QuestHistoryEdit"..value.box.."EditBox"):GetText(); elseif ( value.type == "number" ) then _, _, data[index] = string.find(getglobal("QuestHistoryEdit"..value.box.."EditBox"):GetText(), "(%d+)"); if ( data[index] ~= nil ) then data[index] = tonumber(data[index]); else data[index] = ""; end end end end _, _, questID = string.find(QuestHistoryEditAcceptedOrderEditBox:GetText(), "(%d+)"); if ( questID == nil ) then questID = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName]) + 1; elseif ( questID == "0" ) then questID = 1; else questID = tonumber( questID ); end local zone, x, y; zone = QuestHistoryEditAcceptedZoneEditBox:GetText(); _, _, x = string.find(QuestHistoryEditAcceptedXEditBox:GetText(), "(%d+%.?%d*)"); _, _, y = string.find(QuestHistoryEditAcceptedYEditBox:GetText(), "(%d+%.?%d*)"); if ( x ) then x = tonumber(x) / 100; if ( x < 0 ) then x = 0; elseif ( x > 1 ) then x = 1; end else x = nil; end if ( y ) then y = tonumber(y) / 100; if ( y < 0 ) then y = 0; elseif ( y > 1 ) then y = 1; end else y = nil; end if ( zone and x and y ) then data.pa = zone..":"..x..":"..y; end zone = QuestHistoryEditCompletedZoneEditBox:GetText(); _, _, x = string.find(QuestHistoryEditCompletedXEditBox:GetText(), "(%d+%.?%d*)"); _, _, y = string.find(QuestHistoryEditCompletedYEditBox:GetText(), "(%d+%.?%d*)"); if ( x ) then x = tonumber(x) / 100; if ( x < 0 ) then x = 0; elseif ( x > 1 ) then x = 1; end else x = nil; end if ( y ) then y = tonumber(y) / 100; if ( y < 0 ) then y = 0; elseif ( y > 1 ) then y = 1; end else y = nil; end if ( zone and x and y ) then data.pc = zone..":"..x..":"..y; end return data, questID; end -- Removes a quest from the displayed player's history local function QuestHistory_DeleteQuest(questID, realm, character) if ( not realm ) then realm = DisplayedRealmName; end if ( not character ) then character = DisplayedPlayerCharacterName; end local completed = QuestHistory_List[realm][character][questID].co; if ( completed ) then for index, value in QuestHistory_List[realm][character] do if ( value.co and ( value.co > completed ) ) then value.co = value.co - 1; end end end table.remove(QuestHistory_List[realm][character], questID); end -- Repairs quest data local function QuestHistory_RepairData() -- BEGIN EMERALD FIX local playerName = UnitName("player"); local repairCount = 0; --EMERALD: Kill bad entries before scanning for dupes for realmIndex, realmValue in QuestHistory_List do for charIndex, charValue in realmValue do for questIndex, questValue in charValue do if (string.find(questValue.d,UNKNOWNOBJECT)) then if (DEFAULT_CHAT_FRAME) then DEFAULT_CHAT_FRAME:AddMessage("Removing #"..questIndex.." \""..questValue.t.."\" (BadEntry) from "..charIndex.."."); end QuestHistory_DeleteQuest(questIndex, realmIndex, charIndex); questIndex = questIndex - 1; repairCount = repairCount + 1; end end end end for realmIndex, realmValue in QuestHistory_List do for charIndex, charValue in realmValue do for questIndex, questValue in charValue do if ( QuestHistoryFlags["removePortQuests"].status and ( questValue.t == "Port to Auberdine" or questValue.t == "Port to Menethil" ) ) then if (DEFAULT_CHAT_FRAME) then DEFAULT_CHAT_FRAME:AddMessage("Removing #"..questIndex.." \""..questValue.t.."\" (Port) from "..charIndex.."."); end QuestHistory_DeleteQuest(questIndex, realmIndex, charIndex); questIndex = questIndex - 1; repairCount = repairCount + 1; else if ( QuestHistoryFlags["removeDuplicates"].status ) then local offset = 0; for index = questIndex + 1, getn(charValue), 1 do -- EMERALD: Add checks here charValue[index - offset].d = string.gsub(charValue[index - offset].d,UNKNOWNOBJECT,charIndex); questValue.d = string.gsub(questValue.d,UNKNOWNOBJECT,charIndex); if ( charValue[index - offset].d == questValue.d and charValue[index - offset].t == questValue.t and index - offset ~= questIndex ) then if (DEFAULT_CHAT_FRAME) then DEFAULT_CHAT_FRAME:AddMessage("Removing #"..index.." \""..questValue.t.."\" (Duplicate) from "..charIndex.."."); end QuestHistory_DeleteQuest(index - offset, realmIndex, charIndex); offset = offset + 1; repairCount = repairCount + 1; end end end -- END EMERALD FIX for dataIndex, dataValue in questValue do if ( QuestHistoryData[dataIndex] ) then local type = QuestHistoryData[dataIndex].type; if ( type == "number" ) then dataValue = tonumber(dataValue); if ( dataValue == 0 ) then dataValue = nil; end elseif ( type == "string" ) then dataValue = tostring(dataValue); if ( dataValue == "" ) then dataValue = nil; end elseif ( type == "item" ) then if ( dataValue.a == 1 ) then dataValue.a = nil; end elseif ( type == "objective" ) then if ( dataValue.f ~= 1 ) then dataValue.f = nil; end end elseif ( DEFAULT_CHAT_FRAME ) then DEFAULT_CHAT_FRAME:AddMessage("Cannot find "..dataIndex.." in QuestHistoryData."); end end end end end end QuestHistory_Refresh(); DEFAULT_CHAT_FRAME:AddMessage("Repair finished. Removed "..repairCount.." entries."); end -- Reorders the quests in the displayed player's history local function QuestHistory_ReorderQuests(oldQuestID, newQuestID) local temp = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][oldQuestID]; if ( oldQuestID < newQuestID ) then newQuestID = newQuestID + 1; else oldQuestID = oldQuestID + 1; end table.insert(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName], newQuestID, temp); table.remove(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName], oldQuestID); end -- Reorders the completed status in the displayed player's history local function QuestHistory_ReorderCompleted(old, new) local highest = 0; for index, value in QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName] do if ( value.co and highest < value.co ) then -- Store the highest value of the last completed quest highest = value.co; end end if ( new and new < 1 ) then new = highest + 1; end if ( old ) then if ( new ) then if ( new < old ) then -- Increment completed status of quests between new and old - 1 for index, value in QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName] do if ( value.co and value.co >= new and value.co <= old - 1 ) then value.co = value.co + 1; end end else if ( new > highest ) then new = highest; end -- Decrement completed status of quests between old + 1 and new for index, value in QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName] do if ( value.co and value.co >= old + 1 and value.co <= new ) then value.co = value.co - 1; end end end else -- Decrement completed status of quests >= old + 1 for index, value in QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName] do if ( value.co and value.co >= old + 1 ) then value.co = value.co - 1; end end end else if ( new ) then if ( new > highest ) then new = highest + 1; else -- Increment completed status of quests >= new for index, value in QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName] do if ( value.co and value.co >= new ) then value.co = value.co + 1; end end end else new = nil; end end return new; end -- Selects currently logged-in character as the currently displayed character local function QuestHistory_SelectCurrentCharacter() local i = 0; for realmIndex, realmValue in QuestHistory_List do i = i + 1; for charIndex, charValue in realmValue do i = i + 1; if ( ( realmIndex == RealmName ) and ( charIndex == PlayerCharacterName ) ) then UIDropDownMenu_SetSelectedID(QuestHistoryOptionsFrameCharacterDropDown, i ); break; end end if ( realmIndex == RealmName ) then break; end end end -- Deletes currently displayed character's data from QuestHistory_List local function QuestHistory_DeleteCharacter() if ( RealmName ~= DisplayedRealmName or PlayerCharacterName ~= DisplayedPlayerCharacterName ) then local i = 0; QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName] = nil; for charIndex, charValue in QuestHistory_List[DisplayedRealmName] do i = i + 1; end if ( i == 0 ) then QuestHistory_List[DisplayedRealmName] = nil; end QuestHistory_SelectCurrentCharacter(); UIDropDownMenu_SetText(PlayerCharacterName, QuestHistoryOptionsFrameCharacterDropDown); DisplayedRealmName = RealmName; DisplayedPlayerCharacterName = PlayerCharacterName; QuestHistory_Refresh(); end end -- Loads a hexadecimal value from QuestHistory_Flags if it exists and sets the flags accordingly local function QuestHistory_LoadFlags() local sVal = QuestHistory_Flags; if ( sVal ) then local decVal = tonumber(sVal, 16); local flag; local numIndices = 0; for index, value in QuestHistoryFlags do numIndices = numIndices + 1; end for i = 1, numIndices, 1 do if ( math.mod(decVal, 2) == 0 ) then flag = false; else flag = true; end for index, value in QuestHistoryFlags do if ( value.index == i ) then value.status = flag; break; end end decVal = floor(decVal / 2); end end end -- Saves the flags as a hexadecimal value in QuestHistory_Flags local function QuestHistory_SaveFlags() local val = 0; for index, value in QuestHistoryFlags do if ( value.status ) then val = val + 2 ^ (value.index - 1); end end QuestHistory_Flags = string.format("%X", val)..""; end local function QuestHistory_LogCurrentQuests() -- BEGIN EMERALD FIX local questCategory = ""; local playerName = UnitName("player"); -- Cycle through the quests currently in the quest log for i = 1, GetNumQuestLogEntries(), 1 do local qTitle, qLevel, qTag, isHeader = GetQuestLogTitle(i); -- Check if quest title is a header if ( qTitle ) then -- EMERALD: Thanks, Asjaskan qTitle = string.gsub(string.gsub(qTitle,'^[[].*[]]',''),'^ ',''); end if ( not isHeader ) then -- Not a header, so log information for this quest local questID; -- Select the quest SelectQuestLogEntry(i); -- Get the description and objectives of quest local qDescription, qObjectives = GetQuestLogQuestText(); -- Find quest in QuestHistory_List if it has been logged already for index, value in QuestHistory_List[RealmName][PlayerCharacterName] do -- Compare descriptions if one has been logged if ( value.d ) then qDescription = string.gsub(qDescription,UNKNOWNOBJECT,playerName); value.d = string.gsub(value.d,UNKNOWNOBJECT,playerName); if ( qDescription == value.d ) then questID = index; -- Break out of for loop if quest has been found break; end -- END EMERALD FIX -- Otherwise, compare titles but don't break out until all quest descriptions have been checked elseif ( value.t ) then if ( qTitle == value.t and not value.co ) then questID = index; end end end -- Check if it is a new quest that hasn't been logged yet if ( not questID ) then -- Assign questID to be 1 more than the player's current number of logged quests questID = getn(QuestHistory_List[RealmName][PlayerCharacterName]) + 1; -- Create blank table to store quest data table.insert(QuestHistory_List[RealmName][PlayerCharacterName], { }); -- Record quest title QuestHistory_List[RealmName][PlayerCharacterName][questID].t = qTitle; -- Record quest level if doing so if ( QuestHistoryFlags["logLevel"].status ) then QuestHistory_List[RealmName][PlayerCharacterName][questID].l = qLevel; end -- Record quest tag if doing so if ( QuestHistoryFlags["logTag"].status ) then QuestHistory_List[RealmName][PlayerCharacterName][questID].y = qTag; end -- Record quest location if doing so if ( QuestHistoryFlags["logCategory"].status ) then QuestHistory_List[RealmName][PlayerCharacterName][questID].c = questCategory; end -- Record quest description if doing so if ( QuestHistoryFlags["logDescription"].status ) then QuestHistory_List[RealmName][PlayerCharacterName][questID].d = qDescription; end -- Record quest objectives if doing so if ( QuestHistoryFlags["logObjectives"].status ) then QuestHistory_List[RealmName][PlayerCharacterName][questID].o = qObjectives; end -- Record objectives status if doing so if ( QuestHistoryFlags["logObjectivesStatus"].status ) then local nObjectives = GetNumQuestLeaderBoards(); if ( nObjectives and ( nObjectives > 0 ) ) then -- Create blank table to store quest objectives status QuestHistory_List[RealmName][PlayerCharacterName][questID].os = { }; for j = 1, nObjectives, 1 do -- Create blank table for this objective QuestHistory_List[RealmName][PlayerCharacterName][questID]["os"][j] = { }; end end end -- Record player's level when quest was accepted/logged if doing so if ( QuestHistoryFlags["logLevelAccepted"].status ) then if ( questHasBeenRecentlyAccepted ) then QuestHistory_List[RealmName][PlayerCharacterName][questID].la = UnitLevel("player"); else QuestHistory_List[RealmName][PlayerCharacterName][questID].ll = UnitLevel("player"); end end -- Record played time when quest was accepted/logged if doing so if ( QuestHistoryFlags["logTimeAccepted"].status ) then if ( questHasBeenRecentlyAccepted ) then QuestHistory_List[RealmName][PlayerCharacterName][questID].ta = timeText; else QuestHistory_List[RealmName][PlayerCharacterName][questID].tl = timeText; end end -- Record required money if doing so if ( QuestHistoryFlags["logRequiredMoney"].status ) then local reqMoney = GetQuestLogRequiredMoney(); if ( reqMoney and ( reqMoney > 0 ) ) then QuestHistory_List[RealmName][PlayerCharacterName][questID].rm = reqMoney; end end -- Record quest rewards if doing so if ( QuestHistoryFlags["logRewards"].status ) then local nRewards = GetNumQuestLogRewards(); if ( nRewards and ( nRewards > 0 ) ) then -- Create blank table to store reward info QuestHistory_List[RealmName][PlayerCharacterName][questID].r = { }; -- Cycle through number of quest rewards for j = 1, nRewards, 1 do -- Create blank table for this reward QuestHistory_List[RealmName][PlayerCharacterName][questID]["r"][j] = { }; -- Get data for quest reward local rName, rTexture, rNumItems, rQuality, rIsUsable = GetQuestLogRewardInfo(j); -- Record data for quest reward QuestHistory_List[RealmName][PlayerCharacterName][questID]["r"][j].t = rTexture; if ( rNumItems > 1 ) then QuestHistory_List[RealmName][PlayerCharacterName][questID]["r"][j].a = rNumItems; end QuestHistory_List[RealmName][PlayerCharacterName][questID]["r"][j].l = GetQuestLogItemLink("reward", j); end end end -- Record quest choices if doing so if ( QuestHistoryFlags["logChoices"].status ) then local nChoices = GetNumQuestLogChoices(); if ( nChoices and ( nChoices > 0 ) ) then -- Create blank table to store choice info QuestHistory_List[RealmName][PlayerCharacterName][questID].i = { }; -- Cycle through number of quest choices for j = 1, nChoices, 1 do -- Create blank table for this choice QuestHistory_List[RealmName][PlayerCharacterName][questID]["i"][j] = { }; -- Get data for quest choice local cName, cTexture, cNumItems, cQuality, cIsUsable = GetQuestLogChoiceInfo(j); -- Record data for quest choice QuestHistory_List[RealmName][PlayerCharacterName][questID]["i"][j].t = cTexture; if ( cNumItems > 1 ) then QuestHistory_List[RealmName][PlayerCharacterName][questID]["i"][j].a = cNumItems; end QuestHistory_List[RealmName][PlayerCharacterName][questID]["i"][j].l = GetQuestLogItemLink("choice", j); end end end -- Record quest spells if doing so if ( QuestHistoryFlags["logSpells"].status ) then if ( GetQuestLogRewardSpell() ) then -- Create blank table to store spell info QuestHistory_List[RealmName][PlayerCharacterName][questID].s = { }; -- Get data for spell reward local sTexture, sName = GetQuestLogRewardSpell(); -- Record data for spell reward QuestHistory_List[RealmName][PlayerCharacterName][questID]["s"].t = sTexture; QuestHistory_List[RealmName][PlayerCharacterName][questID]["s"].n = sName; end end -- Record reward money if doing so if ( QuestHistoryFlags["logRewardMoney"].status ) then local rewMoney = GetQuestLogRewardMoney(); if ( rewMoney and ( rewMoney > 0 ) ) then QuestHistory_List[RealmName][PlayerCharacterName][questID].m = rewMoney; end end -- Record background material if doing so if ( QuestHistoryFlags["logBackgroundMaterial"].status ) then local material = GetQuestBackgroundMaterial(); if ( material ~= "Parchment" ) then QuestHistory_List[RealmName][PlayerCharacterName][questID].bg = material; end end -- Record accepted location if doing so if ( QuestHistoryFlags["logAcceptedLocation"].status ) then QuestHistory_List[RealmName][PlayerCharacterName][questID].pa = recentlyAcceptedLocation; recentlyAcceptedLocation = nil; end -- Record quest giver if doing so if ( QuestHistoryFlags["logQuestGiver"].status ) then QuestHistory_List[RealmName][PlayerCharacterName][questID].g = recentNPCQuestGiver; recentNPCQuestGiver = nil; end -- Check if recently accepted quest has been logged if ( questHasBeenRecentlyAccepted ) then -- Reset accepted flag questHasBeenRecentlyAccepted = nil; -- Break out of for loop since the quest most recently accepted has been logged break; end else -- Check if quest is failed if ( IsCurrentQuestFailed() ) then if ( not QuestHistory_List[RealmName][PlayerCharacterName][questID].f ) then QuestHistory_List[RealmName][PlayerCharacterName][questID].f = true; if ( not QuestHistory_List[RealmName][PlayerCharacterName][questID].fc ) then QuestHistory_List[RealmName][PlayerCharacterName][questID].fc = 1; else QuestHistory_List[RealmName][PlayerCharacterName][questID].fc = QuestHistory_List[RealmName][PlayerCharacterName][questID].fc + 1; end end else -- Mark quest as not failed QuestHistory_List[RealmName][PlayerCharacterName][questID].f = nil; end -- Make sure quest is not marked abandoned since it is currently in the quest log QuestHistory_List[RealmName][PlayerCharacterName][questID].a = nil; end -- Record quest objectives progress if doing so if ( QuestHistoryFlags["logObjectivesStatus"].status ) then if ( QuestHistory_List[RealmName][PlayerCharacterName][questID].os ) then local numObjectives = getn(QuestHistory_List[RealmName][PlayerCharacterName][questID]["os"]); for j = 1, numObjectives, 1 do local oText, oType, oFinished = GetQuestLogLeaderBoard(j); if ( not oText or strlen(oText) == 0 ) then oText = oType; end -- Check if quest objective has been finished if ( not oFinished or not QuestHistory_List[RealmName][PlayerCharacterName][questID]["os"][j].f ) then -- Update progress of objective QuestHistory_List[RealmName][PlayerCharacterName][questID]["os"][j].t = oText; QuestHistory_List[RealmName][PlayerCharacterName][questID]["os"][j].f = oFinished; end end end end else -- Store header title as the zone location for the next quest questCategory = qTitle; end end -- Reset timer to disallow this function from being run again too soon timeSinceLastLog = 0; allowLogging = false; if ( QuestHistoryFrame:IsVisible() ) then QuestHistory_Refresh(); end end ---------------------------------------------------------------------------------------------------- -- On_Foo Functions ---------------------------------------------------------------------------------------------------- function QuestHistory_OnLoad() -- Register events for QuestHistoryFrame this:RegisterEvent("PLAYER_LOGIN"); this:RegisterEvent("ADDON_LOADED"); this:RegisterEvent("VARIABLES_LOADED"); this:RegisterEvent("ADDON_LOADED"); this:RegisterEvent("QUEST_LOG_UPDATE"); this:RegisterEvent("TIME_PLAYED_MSG"); this:RegisterEvent("PLAYER_ENTERING_WORLD"); this:RegisterEvent("PLAYER_ALIVE"); this:RegisterEvent("PLAYER_UNGHOST"); -- Set up slash commands SLASH_QUESTHISTORY1 = "/questhistory"; SLASH_QUESTHISTORY2 = "/qh"; SlashCmdList["QUESTHISTORY"] = function(msg) QuestHistory_SlashCommandHandler(msg); end -- Hook the QuestDetailAcceptButton_OnClick function originalQuestDetailAcceptButton_OnClick = QuestDetailAcceptButton_OnClick; QuestDetailAcceptButton_OnClick = QuestHistory_QuestDetailAcceptButton_OnClick; -- Hook the QuestRewardCompleteButton_OnClick function originalQuestRewardCompleteButton_OnClick = QuestRewardCompleteButton_OnClick; QuestRewardCompleteButton_OnClick = QuestHistory_QuestRewardCompleteButton_OnClick; -- Hook the AbandonQuest function originalAbandonQuest = AbandonQuest; AbandonQuest = QuestHistory_AbandonQuest; -- Hook the ChatFrame_DisplayTimePlayed function originalChatFrame_DisplayTimePlayed = ChatFrame_DisplayTimePlayed; ChatFrame_DisplayTimePlayed = QuestHistory_ChatFrame_DisplayTimePlayed; -- Hook quest window open (v2.8) originalQuest_Save = QuestFrameGreetingPanel_OnShow; QuestFrameGreetingPanel_OnShow = QuestHistory_QuestFrameGreetingPanel_OnShow; -- Display a message in the ChatFrame indicating a successful load of this addon if ( DEFAULT_CHAT_FRAME ) then DEFAULT_CHAT_FRAME:AddMessage(format(QUESTHISTORY_LOAD_TEXT, QUESTHISTORY_VERSION)); end -- Display a popup message indicating a successful load of this addon UIErrorsFrame:AddMessage(format(QUESTHISTORY_LOAD_TEXT, QUESTHISTORY_VERSION), 1.0, 1.0, 1.0, 1.0, UIERRORS_HOLD_TIME); end -- Handle quest window open (v2.8) function QuestHistory_QuestFrameGreetingPanel_OnShow() originalQuest_Save(); if (QuestHistory_Options["levels"]) then -- only if enabled local actQ, availQ = GetNumActiveQuests(), GetNumAvailableQuests(); if (actQ + availQ == 0) then return; end local title, level, button; local o, GetTitle, GetLevel = 0, GetActiveTitle, GetActiveLevel; for i = 1, actQ + availQ do if(i == actQ + 1) then o, GetTitle, GetLevel = actQ, GetAvailableTitle, GetAvailableLevel; end title, level = GetTitle(i-o), GetLevel(i-o); button = getglobal("QuestTitleButton"..i); button:SetText(format('[%d] %s', level, title)); end end end function QuestHistory_DelayedConfigInit_OnUpdate(elapsed) if (QuestHistory_DelayedConfigInit) then QuestHistory_DelayedLoginFired = true; -- This will prevent recurring delays QuestHistory_DelayedConfigInit = QuestHistory_DelayedConfigInit - elapsed; if (QuestHistory_DelayedConfigInit <= 0) then QuestHistory_LogCurrentQuests(); QuestHistory_DelayedConfigInit = nil; QuestHistoryDelayedFrame:Hide(); end else -- Stop receiving OnUpdates QuestHistoryDelayedFrame:Hide(); end end function QuestHistory_OnEvent(event) if ( event == "PLAYER_LOGIN" ) then if (not QuestHistory_Loaded) then if (MapNotes_Options) then -- Set to either MapNotes or MetaMapNotes QHMN_ZoneNames = MapNotes_ZoneNames; QHMN_Data = MapNotes_Data; QHMN_SetNextAsMiniNote = MapNotes_SetNextAsMiniNote; QHMN_GetNoteBySlashCommand = MapNotes_GetNoteBySlashCommand; elseif (MetaMapNotes_Options) then QHMN_ZoneNames = MetaMapNotes_ZoneNames; QHMN_Data = MetaMapNotes_Data; QHMN_SetNextAsMiniNote = MetaMapNotes_SetNextAsMiniNote; QHMN_GetNoteBySlashCommand = MetaMapNotes_GetNoteBySlashCommand; end PlayerCharacterName = UnitName("player"); DisplayedPlayerCharacterName = PlayerCharacterName; RealmName = GetCVar("realmName"); DisplayedRealmName = RealmName; if (not QuestHistory_List) then QuestHistory_List = {}; end if (not QuestHistory_List[RealmName]) then QuestHistory_List[RealmName] = {}; end if ( not QuestHistory_List[RealmName][PlayerCharacterName] ) then QuestHistory_List[RealmName][PlayerCharacterName] = {}; end -- Upgrade the data to latest format QuestHistory_UpgradeData(); -- Load the logging and displaying flags QuestHistory_LoadFlags(); -- Load the colors of abandoned and completed quests if ( QuestHistory_StatusColors ) then for index, value in QuestHistory_StatusColors do QuestHistoryStatusColor[index] = value; end end -- Records the played time to use for quests accepted before this addon was installed if doing so if ( QuestHistoryFlags["logTimeAccepted"].status ) then timeEvent = "Logged"; RequestTimePlayed(); end if ( allowLogging ) then if (not QuestHistory_DelayedLoginFired) then QuestHistory_DelayedConfigInit = 10; -- EMERALD (thanks to UberQuest) QuestHistoryDelayedFrame:Show(); else -- If QuestHistory_DelayedLoginFired, then we've done the login delay. No more long delays! QuestHistory_DelayedConfigInit = 1; QuestHistoryDelayedFrame:Show(); end end if (not QuestHistory_Options) then QuestHistory_Options = { ["levels"] = true, -- on by default }; elseif (QuestHistory_Options["levels"]==nil) then QuestHistory_Options["levels"] = true; -- on by default end QuestHistory_Loaded = true; end elseif ( event == "PLAYER_ENTERING_WORLD" or event == "PLAYER_ALIVE" or event == "PLAYER_UNGHOST" ) then local playerX, playerY = GetPlayerMapPosition("player"); -- EMERALD: New attempt to prevent the Blizzard 0,0 bug -- doing so before the quest events happen, not during if (playerX==0 and playerY==0) then ShowUIPanel(WorldMapFrame); HideUIPanel(WorldMapFrame); end elseif ( event == "QUEST_LOG_UPDATE" and QuestHistory_Loaded ) then -- Following condition needed to make sure player name has been assigned if ( PlayerCharacterName ) then -- Check if a quest has been recently completed if ( recentlyCompletedQuestID ) then -- If so and XP logging is enabled, log the XP that was gained. -- Needed here because the player's XP is not actually increased -- until some time after the CompleteQuest() function is run if ( QuestHistoryFlags["logXPReward"].status ) then local newXP = UnitXP("player") - XPBeforeQuestCompletion; -- Check if XP has been updated after quest if ( newXP ~= 0 ) then -- Check if XP now is less than XP before quest was completed if ( newXP < 0 ) then -- If so, player leveled so add the previous max XP recorded to get correct value of XP gained newXP = newXP + XPMaxBeforeQuestCompletion; end -- Log the XP Reward QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].x = newXP; -- Reset variable values XPBeforeQuestCompletion = 0; XPMaxBeforeQuestCompletion = 0; recentlyCompletedQuestID = nil; end else -- If XP logging is not enabled, just reset recentlyCompletedQuestID recentlyCompletedQuestID = nil; end end -- Check if a quest has been recently abandoned if ( questHasBeenRecentlyAbandoned ) then -- Just reset the recently abandoned flag questHasBeenRecentlyAbandoned = nil; -- If a quest hasn't been recently completed or abandoned, check if -- it is okay to call LogCurrentQuests() to log new quests or update -- current ones elseif ( allowLogging ) then --QuestHistory_LogCurrentQuests(); if (not QuestHistory_DelayedLoginFired) then QuestHistory_DelayedConfigInit = 10; -- EMERALD (thanks to UberQuest) QuestHistoryDelayedFrame:Show(); else -- If QuestHistory_DelayedLoginFired, then we've done the login delay. No more long delays! QuestHistory_DelayedConfigInit = 0; QuestHistoryDelayedFrame:Show(); end end -- Refreshes the display of the QuestHistory frame if it is visible if ( QuestHistoryFrame:IsVisible() ) then QuestHistory_Refresh(); end end elseif ( event == "TIME_PLAYED_MSG" ) then if ( timeEvent == "Accepted" or timeEvent == "Completed" or timeEvent == "Logged" ) then -- Format and save current played time timeText = format(TEXT(QUESTHISTORY_TIME_FORMAT), ChatFrame_TimeBreakDown(arg1)); -- Check if TIME_PLAYED_MSG event occurred when a quest was just completed if ( timeEvent == "Completed" ) then -- Record the quest completed time if doing so if ( QuestHistoryFlags["logTimeCompleted"].status ) then -- Make sure recentlyCompletedQuestID has been assigned a good value if ( recentlyCompletedQuestID ) then QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].tc = timeText; if ( QuestHistoryFlags["logTimeAccepted"].status and ( not QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].ta ) and ( not QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].tl ) ) then QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].ta = timeText; end end end end end end end function QuestHistory_OnShow() PlaySound("igMainMenuOpen"); QuestHistory_Refresh(); end function QuestHistory_OnHide() PlaySound("igMainMenuClose"); HideUIPanel(QuestHistoryDetailFrame); HideUIPanel(QuestHistoryEditFrame); HideUIPanel(QuestHistoryOptionsFrame); HideUIPanel(QuestHistoryConfirmFrame); QuestHistoryFrameSearchEditBox:Hide(); QuestHistoryFrameClearButton:Hide(); QuestHistoryFrameSubmitButton:Hide(); QuestHistoryFrameSearchButton:Show(); end function QuestHistoryFrameSortDropDown_OnLoad() UIDropDownMenu_Initialize(QuestHistoryFrameSortDropDown, QuestHistoryFrameSortDropDown_Initialize); if ( not QuestHistoryFrameSortDropDown.selectedID ) then UIDropDownMenu_SetSelectedID(QuestHistoryFrameSortDropDown, 1 ); end UIDropDownMenu_SetWidth(QUESTHISTORY_SORT_DROPDOWN_MENU_WIDTH); UIDropDownMenu_JustifyText("CENTER", QuestHistoryFrameSortDropDown); end function QuestHistoryFrameSortDropDownButton_OnClick() UIDropDownMenu_SetSelectedID(QuestHistoryFrameSortDropDown, this:GetID()); QuestHistory_SetSortOrder(); end function QuestHistory_SortButton_OnClick() UIDropDownMenu_SetSelectedID(QuestHistoryFrameSortDropDown, this:GetID()); QuestHistory_SetSortOrder(); end function QuestHistoryListFrame_OnClick(button) if ( button == "LeftButton" ) then if ( IsShiftKeyDown() and ChatFrameEditBox:IsVisible() ) then -- Insert quest title, level, category, tag into ChatFrame if Shift-leftclicked and chat frame is visible local frame = "QuestHistoryListFrame"..this:GetID(); local title = getglobal(frame.."TitleText"):GetText(); local level = getglobal(frame.."LevelText"):GetText(); local category = getglobal(frame.."CategoryText"):GetText(); local tag = getglobal(frame.."TagText"):GetText(); if ( tag and tag ~= "" ) then tag = " ["..tag.."]"; else tag = ""; end local text = title.." - "..level.." - "..category..tag; ChatFrameEditBox:Insert(text); else currentTitleListID = this:GetID(); local index = currentTitleListID + FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame); currentSortedID = index; currentDetailedQuestID = SortedTable[index]; QuestHistory_Detail_Update(currentDetailedQuestID); ShowUIPanel(QuestHistoryDetailFrame); QuestHistoryListHighlightFrame:SetPoint("LEFT", "QuestHistoryListFrame"..currentTitleListID, "LEFT", 0, -2); QuestHistoryListHighlightFrame:Show(); end elseif ( button == "RightButton" ) then if ( IsShiftKeyDown() and QuestHistoryFlags["allowDeleting"].status ) then local index = this:GetID() + FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame); QuestHistory_DeleteQuest(SortedTable[index]); if ( getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName]) and getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName]) > 0 ) then if ( index ~= 1 ) then index = index - 1; end currentSortedID = index; currentDetailedQuestID = SortedTable[index]; QuestHistory_Detail_Update(currentDetailedQuestID); else currentSortedID = 0; HideUIPanel(QuestHistoryDetailFrame); end QuestHistory_Refresh(); elseif ( QuestHistoryFlags["allowEditing"].status ) then currentTitleListID = this:GetID(); local index = currentTitleListID + FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame); currentSortedID = index; currentDetailedQuestID = SortedTable[index]; QuestHistoryEditTitle:SetText(QUESTHISTORY_EDIT_TEXT); QuestHistory_EditQuest(SortedTable[index]); QuestHistoryEditFrameSaveButton:Show(); QuestHistoryEditFrameAddButton:Hide(); ShowUIPanel(QuestHistoryEditFrame); QuestHistoryListHighlightFrame:SetPoint("LEFT", "QuestHistoryListFrame"..currentTitleListID, "LEFT", 0, -2); QuestHistoryListHighlightFrame:Show(); end end end -- Displays quest note in a tootip-like button that appears when the mouse hovers over an item in the quest list function QuestHistoryListFrame_OnEnter() local note = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][SortedTable[this:GetID() + FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame)]].n; if ( note ~= nil and note ~= "" ) then QuestHistoryTooltip:SetPoint("TOPLEFT", "QuestHistoryListFrame"..this:GetID().."CompletedText", "TOPRIGHT", 15, 0); QuestHistoryTooltipText:SetText(note); QuestHistoryTooltip:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b); QuestHistoryTooltip:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b); QuestHistoryTooltip:Show(); end end -- Hides the search button and shows the clear button and the search edit box function QuestHistoryFrameSearchButton_OnClick() QuestHistoryFrameClearButton:Show(); if ( searchText ) then QuestHistoryFrameSearchEditBox:SetText(searchText); end end -- Clears the search text and refreshes the quest list function QuestHistoryFrameClearButton_OnClick() QuestHistoryFrameSearchEditBox:SetText(""); searchText = nil; QuestHistory_Refresh(); end -- Saves the entered search text and refreshes the quest list function QuestHistoryFrameSearchEditBox_OnEnterPressed() searchText = QuestHistoryFrameSearchEditBox:GetText(); QuestHistoryFrameSearchEditBox:AddHistoryLine(searchText); QuestHistory_Refresh(); QuestHistoryFrameSearchButton:Show(); end -- Registers events for the detail frame function QuestHistoryDetailFrame_OnLoad() this:RegisterEvent("QUEST_LOG_UPDATE"); this:RegisterEvent("UPDATE_FACTION"); end -- Updates the detail frame if one of the registered events occur while the frame is visible function QuestHistoryDetailFrame_OnEvent() if ( event == "QUEST_LOG_UPDATE" or event == "UPDATE_FACTION" ) then if ( QuestHistoryDetailFrame:IsVisible() ) then QuestHistory_Detail_Update(currentDetailedQuestID); end end end -- Sets up the tooltip for the reward items in the detailed quest view function QuestHistoryDetailRewardItem_OnEnter() GameTooltip:SetOwner(this, "ANCHOR_RIGHT"); local itemNumber = this:GetID(); local linkText, itemLink; -- Gets the item hyperlink and processes it if ( this.type == "choice" ) then linkText = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID]["i"][itemNumber].l; itemLink = QuestHistory_ProcessLinks(linkText); elseif ( this.type == "reward" ) then linkText = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID]["r"][itemNumber].l; itemLink = QuestHistory_ProcessLinks(linkText); end -- Sets the hyperlink to the game tooltip if it exists if ( itemLink ) then GameTooltip:SetHyperlink(itemLink); end end -- Allows item to be copied to ChatFrame if Shift-leftclicked function QuestHistoryDetailRewardItem_OnClick() if ( IsShiftKeyDown() ) then local linkText; if ( ChatFrameEditBox:IsVisible() ) then local itemNumber = this:GetID(); if ( this.type == "choice" ) then linkText = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID]["i"][itemNumber].l; elseif ( this.type == "reward" ) then linkText = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID]["r"][itemNumber].l; end end -- Adds the link to the chat frame if ( linkText ) then ChatFrameEditBox:Insert(linkText); end end end -- Tabs between edit boxes in QuestHistoryEditFrame function QuestHistoryEditBox_OnTabPressed() local id; local numBoxes = 0; local _, _, name = string.find(this:GetName(), "QuestHistoryEdit(.*)EditBox"); for index, value in QuestHistoryData do if ( value.box ) then numBoxes = numBoxes + 1; end if ( value.box == name ) then id = value.tab; end end if ( IsShiftKeyDown() ) then id = id - 1; else id = id + 1; end if ( id < 1 ) then id = numBoxes; elseif ( id > numBoxes ) then id = 1; end local tabIndex; for index, value in QuestHistoryData do if ( value.tab == id ) then tabIndex = index; end end getglobal("QuestHistoryEdit"..QuestHistoryData[tabIndex].box.."EditBox"):SetFocus(); if ( id >= 5 and id <= 10 ) then QuestHistoryEditListScrollFrameScrollBar:SetValue(0); elseif ( id >= 15 and id <= 21 ) then QuestHistoryEditListScrollFrameScrollBar:SetValue(100); end end function QuestHistoryEditFrameSaveButton_OnClick() local index = currentTitleListID + FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame); local data, questID = QuestHistory_GetEditData(); if ( questID ~= SortedTable[index] ) then if ( questID > getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName]) ) then questID = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName]); end QuestHistory_ReorderQuests(SortedTable[index], questID); end for index, value in data do if ( index == "co" and value ~= QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questID].co ) then if ( value == "" ) then value = nil; end local old = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questID].co; QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questID].co = QuestHistory_ReorderCompleted(old, value); elseif ( value ~= "" ) then QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questID][index] = value; else QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questID][index] = nil; end end currentDetailedQuestID = questID; QuestHistory_Refresh(); QuestHistory_EditQuest(questID); end function QuestHistoryEditFrameAddButton_OnClick() local data, questID = QuestHistory_GetEditData(); if ( questID > getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName]) + 1 ) then questID = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName]) + 1; end for index, value in data do if ( value == "" ) then data[index] = nil; elseif ( index == "co" ) then data.co = QuestHistory_ReorderCompleted(nil, value); end end table.insert(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName], questID, data); currentDetailedQuestID = questID; QuestHistory_Refresh(); QuestHistory_AddQuest(); end -- Sets the checkboxes to the appropriate values from QuestHistoryFlags function QuestHistoryOptionsFrame_OnShow() for index, value in QuestHistoryFlags do local button = getglobal("QuestHistoryOptionsFrameCheckButton"..value.index); local string = getglobal("QuestHistoryOptionsFrameCheckButton"..value.index.."Text"); string:SetText(TEXT(value.text)); button.tooltipText = value.tooltipText; if ( value.status ) then button:SetChecked(1); else button:SetChecked(0); end end end function QuestHistoryColorSwatch_OnShow(status) this.status = status; lowstatus = string.lower(status); this.swatchFunc = QuestHistory_SetColor; this.cancelFunc = QuestHistory_CancelColor; this.r = QuestHistoryStatusColor[lowstatus].r; this.g = QuestHistoryStatusColor[lowstatus].g; this.b = QuestHistoryStatusColor[lowstatus].b; getglobal(this:GetName().."NormalTexture"):SetVertexColor(this.r, this.g, this.b); end function QuestHistoryOptionsFrameCharacterDropDown_OnShow() UIDropDownMenu_Initialize(QuestHistoryOptionsFrameCharacterDropDown, QuestHistoryOptionsFrameCharacterDropDown_Initialize); if ( not QuestHistoryOptionsFrameCharacterDropDown.selectedID ) then QuestHistory_SelectCurrentCharacter(); end UIDropDownMenu_SetWidth(QUESTHISTORY_CHARACTER_DROPDOWN_MENU_WIDTH); end function QuestHistoryOptionsFrameCharacterDropDownButton_OnClick() UIDropDownMenu_SetSelectedID(QuestHistoryOptionsFrameCharacterDropDown, this:GetID()); button = getglobal("DropDownList"..UIDROPDOWNMENU_MENU_LEVEL.."Button"..this:GetID()); _, _, DisplayedPlayerCharacterName = string.find(button:GetText(), " (.*)"); DisplayedRealmName = button.value; currentDetailedListID = nil; currentSortedID = 0; currentTitleListID = nil; QuestHistory_Refresh(); end function QuestHistoryOptionsFrameDeleteButton_OnClick() if ( RealmName ~= DisplayedRealmName or PlayerCharacterName ~= DisplayedPlayerCharacterName ) then PlaySound("igMainMenuOptionCheckBoxOn"); QuestHistoryOptionsFrameOkayButton_OnClick(); QuestHistoryConfirmFrameExplanation:SetText(QUESTHISTORY_DELETE_CONFIRM_EXPLANATION); ShowUIPanel(QuestHistoryConfirmFrame); end end function QuestHistory_AddQuest() QuestHistoryEditTitle:SetText(QUESTHISTORY_ADD_TEXT); QuestHistory_ClearQuest(); QuestHistoryEditAcceptedOrderEditBox:SetText(getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName])+ 1); QuestHistoryEditFrameSaveButton:Hide(); QuestHistoryEditFrameAddButton:Show(); ShowUIPanel(QuestHistoryEditFrame); end -- Saves the checkbox values in QuestHistoryFlags function QuestHistoryOptionsFrameOkayButton_OnClick() for index, value in QuestHistoryFlags do value.status = getglobal("QuestHistoryOptionsFrameCheckButton"..value.index):GetChecked(); end QuestHistory_SaveFlags(); HideUIPanel(QuestHistoryOptionsFrame); QuestHistory_Refresh(); end function QuestHistoryConfirmFrameOkayButton_OnClick() local text = QuestHistoryConfirmFrameExplanation:GetText(); if ( text == QUESTHISTORY_PURGE_CONFIRM_EXPLANATION ) then QuestHistory_PurgeData(); elseif ( text == QUESTHISTORY_DELETE_CONFIRM_EXPLANATION ) then QuestHistory_DeleteCharacter(); elseif ( text == QUESTHISTORY_REPAIR_CONFIRM_EXPLANATION ) then QuestHistory_RepairData(); end end -- Keeps track of the time since the last logging of quest data function QuestHistory_Timer_OnUpdate() -- Check if flag is set to disable logging if ( not allowLogging ) then -- Increase time since last log timeSinceLastLog = timeSinceLastLog + arg1; -- Check if it has been at least 0.1 seconds since the last logging if ( timeSinceLastLog > 0.1 ) then -- Set flag to allow logging allowLogging = true; end end end ---------------------------------------------------------------------------------------------------- -- Hooked Functions ---------------------------------------------------------------------------------------------------- -- Needed so that QuestHistory knows when a quest has been accepted, also to -- record the player's target, location and time when a quest is accepted function QuestHistory_QuestDetailAcceptButton_OnClick() -- Flag that a quest has just been accepted questHasBeenRecentlyAccepted = true; -- Save the name of the current target to store as the quest giver recentNPCQuestGiver = UnitName("target"); -- Save the player's location where quest was accepted local playerX, playerY = GetPlayerMapPosition("player"); -- EMERALD: NOTE: This is the one that fired in instances, in all reports given. --if (playerX==0 and playerY==0) then --ShowUIPanel(WorldMapFrame); --HideUIPanel(WorldMapFrame); --playerX, playerY = GetPlayerMapPosition("player"); --QuestHistory_InsideInstance = true; -- set to prevent 0,0 lock --end --QuestHistory_InsideInstance = false; local zone = GetZoneText(); recentlyAcceptedLocation = zone..":"..playerX..":"..playerY; -- Get the played time when the quest was accepted if doing so if ( QuestHistoryFlags["logTimeAccepted"].status ) then timeEvent = "Accepted"; RequestTimePlayed(); end -- Call the original QuestDetailAcceptButton_OnClick function originalQuestDetailAcceptButton_OnClick(); end -- Needed to record the player's target, level, location, time and XP when a -- quest is completed -- also keeps track of the order in which quests are -- completed function QuestHistory_QuestRewardCompleteButton_OnClick() local rewardTitle = GetTitleText(); local rewardDescription = GetRewardText(); local skipQuest; if ( QuestHistoryFlags["logPortQuests"] or ( rewardTitle ~= "Port to Auberdine" and rewardTitle ~= "Port to Menethil" ) ) then recentlyCompletedQuestID = nil; -- Look through the currently logged quests to find the highest value of the completed quests local highestCompleted = 0; -- EMERALD DEBUG --DEFAULT_CHAT_FRAME:AddMessage("RealmName = "..RealmName); --DEFAULT_CHAT_FRAME:AddMessage("PlayerCharacterName = "..PlayerCharacterName); for index, value in QuestHistory_List[RealmName][PlayerCharacterName] do if ( value.co and highestCompleted < value.co ) then -- Store the highest value of the last completed quest highestCompleted = value.co; end end -- Look through the currently logged quests to find the one most recently completed by comparing titles for index, value in QuestHistory_List[RealmName][PlayerCharacterName] do -- Check if the quest has been marked completed if ( value.co ) then -- If so, then check if its description meets the reward description if ( rewardDescription == value.d ) then -- This quest has been logged before so skip it. skipQuest = true; end else -- If the quest has not been marked completed, check its title if ( rewardTitle == value.t ) then -- Store the index of the quest most recently completed recentlyCompletedQuestID = index; -- Don't skip this quest skipQuest = nil; -- Break out of the for loop if the quest is found break; end end end if ( not skipQuest ) then -- Check if quest is completed without ever being accepted and added to quest log if ( not recentlyCompletedQuestID ) then -- Set the last completed to 1 more than the player's current number of logged quests recentlyCompletedQuestID = getn(QuestHistory_List[RealmName][PlayerCharacterName]) + 1; -- Create a new blank quest entry table.insert(QuestHistory_List[RealmName][PlayerCharacterName], { }); -- Record quest title QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].t = rewardTitle; -- Record quest description if doing so if ( QuestHistoryFlags["logDescription"].status ) then QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].d = rewardDescription; end -- Record quest category if doing so if ( QuestHistoryFlags["logCategory"].status ) then QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].c = GetZoneText(); end -- Record player's level when quest was accepted if doing so if ( QuestHistoryFlags["logLevelAccepted"].status ) then QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].la = UnitLevel("player"); end -- Record accepted location if doing so if ( QuestHistoryFlags["logAcceptedLocation"].status ) then local playerX, playerY = GetPlayerMapPosition("player"); --if (playerX==0 and playerY==0 and not QuestHistory_InsideInstance) then --ShowUIPanel(WorldMapFrame); --HideUIPanel(WorldMapFrame); --playerX, playerY = GetPlayerMapPosition("player"); --QuestHistory_InsideInstance = true; -- set to prevent 0,0 lock -- if (playerX==0 and playerY==0) then -- if ( DEFAULT_CHAT_FRAME ) then -- DEFAULT_CHAT_FRAME:AddMessage("QuestHistory: WARNING! Your coordinates are being reported as 0,0. Please give this code to Dsanai: BN2"); -- end -- end --end --QuestHistory_InsideInstance = false; local zone = GetZoneText(); QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].pc = zone..":"..playerX..":"..playerY; end -- Record quest giver if doing so if ( QuestHistoryFlags["logQuestGiver"].status ) then QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].g = UnitName("target"); end -- Record required money if doing so if ( QuestHistoryFlags["logRequiredMoney"].status ) then local reqMoney = GetQuestMoneyToGet(); if ( reqMoney and ( reqMoney > 0 ) ) then QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].rm = reqMoney; end end -- Record quest rewards if doing so if ( QuestHistoryFlags["logRewards"].status ) then local nRewards = GetNumQuestRewards(); if ( nRewards and ( nRewards > 0 ) ) then -- Create blank table to store reward info QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].r = { }; -- Cycle through number of quest rewards for j = 1, nRewards, 1 do -- Create blank table for this reward QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID]["r"][j] = { }; -- Get data for quest reward local rName, rTexture, rNumItems, rQuality, rIsUsable = GetQuestItemInfo("reward", j); -- Record data for quest reward QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID]["r"][j].t = rTexture; if ( rNumItems > 1 ) then QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID]["r"][j].a = rNumItems; end QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID]["r"][j].l = GetQuestItemLink("reward", j); end end end -- Record quest choices if doing so if ( QuestHistoryFlags["logChoices"].status ) then local nChoices = GetNumQuestChoices(); if ( nChoices and ( nChoices > 0 ) ) then -- Create blank table to store choice info QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].i = { }; -- Cycle through number of quest choices for j = 1, nChoices, 1 do -- Create blank table for this choice QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID]["i"][j] = { }; -- Get data for quest choice local cName, cTexture, cNumItems, cQuality, cIsUsable = GetQuestItemInfo("choice", j); -- Record data for quest choice QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID]["i"][j].t = cTexture; if ( cNumItems > 1 ) then QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID]["i"][j].a = cNumItems; end QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID]["i"][j].l = GetQuestItemLink("choice", j); end end end -- Record quest spells if doing so if ( QuestHistoryFlags["logSpells"].status ) then if ( GetRewardSpell() ) then -- Create blank table to store spell info QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].s = { }; -- Get data for spell reward local sTexture, sName = GetRewardSpell(); -- Record data for spell reward QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].t = sTexture; QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].n = sName; end end -- Record reward money if doing so if ( QuestHistoryFlags["logRewardMoney"].status ) then local rewMoney = GetRewardMoney(); if ( rewMoney and ( rewMoney > 0 ) ) then QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].m = rewMoney; end end -- Record background material if doing so if ( QuestHistoryFlags["logBackgroundMaterial"].status ) then local material = QuestFrame_GetMaterial(); if ( material ~= "Parchment" ) then QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].bg = material; end end end -- If logging XP reward, record the current XP and current XP max if ( QuestHistoryFlags["logXPReward"].status ) then XPBeforeQuestCompletion = UnitXP("player"); XPMaxBeforeQuestCompletion = UnitXPMax("player"); end -- Record player's level when quest was completed if doing so if ( QuestHistoryFlags["logLevelCompleted"].status ) then QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].lc = UnitLevel("player"); end -- Record order of quest completed if doing so if ( QuestHistoryFlags["logCompletedOrder"].status ) then QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].co = highestCompleted + 1; end -- Record quest completer if doing so if ( QuestHistoryFlags["logQuestCompleter"].status ) then QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].w = UnitName("target"); end -- Record completed location if doing so if ( QuestHistoryFlags["logCompletedLocation"].status ) then local playerX, playerY = GetPlayerMapPosition("player"); --if (playerX==0 and playerY==0 and not QuestHistory_InsideInstance) then --ShowUIPanel(WorldMapFrame); --HideUIPanel(WorldMapFrame); --playerX, playerY = GetPlayerMapPosition("player"); --QuestHistory_InsideInstance = true; -- set to prevent 0,0 lock -- if (playerX==0 and playerY==0) then -- if ( DEFAULT_CHAT_FRAME ) then -- DEFAULT_CHAT_FRAME:AddMessage("QuestHistory: WARNING! Your coordinates are being reported as 0,0. Please give this code to Dsanai: LK6"); -- end -- end --end --QuestHistory_InsideInstance = false; local zone = GetZoneText(); QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].pc = zone..":"..playerX..":"..playerY; end -- Get the played time when quest was completed if doing so if ( QuestHistoryFlags["logTimeCompleted"].status ) then timeEvent = "Completed"; RequestTimePlayed(); end end end -- Call the original QuestRewardCompleteButton_OnClick function originalQuestRewardCompleteButton_OnClick(); end -- Marks a quest as abandoned and updates the times abandoned count. function QuestHistory_AbandonQuest() -- Flag that a quest has just been abandoned questHasBeenRecentlyAbandoned = true; -- Store the quest title so the right quest is marked abandoned local questTitle = GetQuestLogTitle(GetQuestLogSelection()); if ( questTitle ) then -- EMERALD: Thanks, Asjaskan questTitle = string.gsub(string.gsub(questTitle,'^[[].*[]]',''),'^ ',''); end -- Call the original AbandonQuest function originalAbandonQuest(); -- Look through the currently logged quests to mark the one abandoned for index, value in QuestHistory_List[RealmName][PlayerCharacterName] do -- Check if the quest matches the title and that it hasn't been marked completed if ( questTitle == value.t and ( not value.co ) ) then -- Mark the quest has abandoned value.a = true; -- Update the quest's count of times abandoned if ( not value.ac ) then value.ac = 1; else value.ac = value.ac + 1; end -- Break out of the for loop if the right quest was found break; end end end -- Prevents played time from being displayed in the chat frame whenever it is -- invoked for a quest being accepted/logged/completed. function QuestHistory_ChatFrame_DisplayTimePlayed(totalTime, levelTime) if ( timeEvent == "Accepted" or timeEvent == "Logged" or timeEvent == "Completed" ) then -- Clear the value of timeEvent timeEvent = ""; else -- Only call the original ChatFrame_DisplayTimePlayed function if it -- wasn't invoked by the accepting/logging/completing of a quest originalChatFrame_DisplayTimePlayed(totalTime, levelTime) end end ---------------------------------------------------------------------------------------------------- -- Callback Functions ---------------------------------------------------------------------------------------------------- -- Toggles the showing/hiding of the QuestHistoryFrame function QuestHistory_Toggle() if ( QuestHistoryFrame:IsVisible() ) then HideUIPanel(QuestHistoryFrame); else ShowUIPanel(QuestHistoryFrame); end end -- Handles the processing of the registered slash commands function QuestHistory_SlashCommandHandler(msg) if (msg and string.lower(msg)=="levels") then -- EMERALD if (QuestHistory_Options["levels"]) then -- disable Levels QuestHistory_Options["levels"] = false; if ( DEFAULT_CHAT_FRAME ) then DEFAULT_CHAT_FRAME:AddMessage("QuestHistory: NPC Quest Level display is now disabled."); end else -- enable Levels QuestHistory_Options["levels"] = true; if ( DEFAULT_CHAT_FRAME ) then DEFAULT_CHAT_FRAME:AddMessage("QuestHistory: NPC Quest Level display is now enabled."); end end else QuestHistory_Toggle(); end end -- Updates the display of the main QuestHistory frame and determines which -- quests are shown in the visible scrollframe function QuestHistory_Update() -- Get number of quests stored for current player local listSize = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName]); local QuestHistoryTitle = QuestHistoryTitleText; -- Build sorted table if it hasn't been created yet if ( not SortedTable ) then QuestHistory_BuildSortedTable(); end -- Highlight currently selected quest if it is visible in the scrollframe currentTitleListID = currentSortedID - FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame); if ( currentTitleListID >= 1 and currentTitleListID <= 31 ) then QuestHistoryListHighlightFrame:SetPoint("LEFT", "QuestHistoryListFrame"..currentTitleListID, "LEFT", 0, -2); QuestHistoryListHighlightFrame:Show(); else -- Hide the highlight frame since selected quest is not visible in the scrollframe QuestHistoryListHighlightFrame:Hide(); end -- Format QuestHistory title appropriately depending on how many quests are logged if ( listSize and ( listSize == 1 ) ) then QuestHistoryTitle:SetText(format(TEXT(QUESTHISTORY_TITLE_FORMAT_SINGULAR), DisplayedPlayerCharacterName)); else QuestHistoryTitle:SetText(format(TEXT(QUESTHISTORY_TITLE_FORMAT_PLURAL), DisplayedPlayerCharacterName, listSize)); end -- Update the scroll frame and add the quest data FauxScrollFrame_Update(QuestHistoryListScrollFrame, sizeSortedTable, QUESTHISTORY_ITEMS_SHOWN, QUESTHISTORY_ITEM_HEIGHT); for iQuest = 1, QUESTHISTORY_ITEMS_SHOWN, 1 do local questIndex = iQuest + FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame); local listFrame = "QuestHistoryListFrame"..iQuest; if ( questIndex <= sizeSortedTable ) then local color; -- Get quest information local index = SortedTable[questIndex]; local title = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index].t; local level = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index].l; local category = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index].c; local tag = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index].y; local completed = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index].co; -- Check to make sure none of the data is nil if ( not title ) then title = ""; end if ( not level ) then level = ""; end if ( not category ) then category = ""; end if ( not tag ) then tag = ""; end -- Add quest data to frame getglobal(listFrame.."AcceptedText"):SetText(index); getglobal(listFrame.."TitleText"):SetText(title); getglobal(listFrame.."LevelText"):SetText(level); getglobal(listFrame.."CategoryText"):SetText(category); getglobal(listFrame.."TagText"):SetText(tag); if ( completed ) then -- If quest has been completed, show checkmark and completed number in brackets getglobal(listFrame.."CompletedText"):SetText("["..completed.."]"); getglobal(listFrame.."CheckMark"):Show(); else -- Otherwise, hide checkmark and display nothing for completed getglobal(listFrame.."CompletedText"):SetText(""); getglobal(listFrame.."CheckMark"):Hide(); end -- Set color depending on quest status if (completed) then color = QuestHistoryStatusColor["completed"]; elseif ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index].a ) then color = QuestHistoryStatusColor["abandoned"]; elseif ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index].f ) then color = QuestHistoryStatusColor["failed"]; else if ( level == "" ) then level = 0; end color = GetDifficultyColor(level); end -- Apply color to text getglobal(listFrame.."AcceptedText"):SetTextColor(color.r, color.g, color.b); getglobal(listFrame.."TitleText"):SetTextColor(color.r, color.g, color.b); getglobal(listFrame.."LevelText"):SetTextColor(color.r, color.g, color.b); getglobal(listFrame.."CategoryText"):SetTextColor(color.r, color.g, color.b); getglobal(listFrame.."TagText"):SetTextColor(color.r, color.g, color.b); getglobal(listFrame.."CompletedText"):SetTextColor(color.r, color.g, color.b); getglobal(listFrame):Show(); else -- Hide the list frame if there is no data for it getglobal(listFrame):Hide(); end end end -- Opens the QuestHistory note scroll frame and populates it with the current note if there is one function QuestHistory_Edit_Note() local note = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID].n; if ( note ) then QuestHistoryDetailNotesText:SetText(note); else QuestHistoryDetailNotesText:SetText(""); end -- Hide and show the appropriate frames QuestHistoryDetailListScrollFrame:Hide(); QuestHistoryDetailEditButton:Hide(); QuestHistoryDetailNotesScrollFrame:Show(); QuestHistoryDetailSaveButton:Show(); end -- Saves the player entered noted to QuestHistory_List function QuestHistory_Save_Note() local note = QuestHistoryDetailNotesText:GetText(); if ( note and note ~= "" ) then QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID].n = note; end -- Refresh the detailed view display QuestHistory_Detail_Update(currentDetailedQuestID); end -- Selects the quest in the main list relative to the currently selected quest and based -- on the value of offset function QuestHistory_Change_Detailed_Quest(offset) newID = currentSortedID + offset; -- Check if newID is valid if ( newID > 0 and newID <= sizeSortedTable ) then currentTitleListID = currentTitleListID + offset; currentSortedID = newID; currentDetailedQuestID = SortedTable[newID]; QuestHistory_Detail_Update(currentDetailedQuestID); ShowUIPanel(QuestHistoryDetailFrame); QuestHistory_Refresh(); end end function QuestHistory_ClearQuest() for index, value in QuestHistoryData do if ( value.box ) then getglobal("QuestHistoryEdit"..value.box.."EditBox"):SetText(""); end end end function QuestHistory_SetColor() local red,green,blue = ColorPickerFrame:GetColorRGB(); QuestHistoryStatusColor[string.lower(QuestHistory_StatusColorType)] = { r = red, g = green, b = blue }; getglobal("QuestHistoryOptionsFrame"..QuestHistory_StatusColorType.."ColorSwatchNormalTexture"):SetVertexColor(red, green, blue); getglobal("QuestHistoryOptionsFrame"..QuestHistory_StatusColorType.."ColorSwatch").r = red; getglobal("QuestHistoryOptionsFrame"..QuestHistory_StatusColorType.."ColorSwatch").g = green; getglobal("QuestHistoryOptionsFrame"..QuestHistory_StatusColorType.."ColorSwatch").b = blue; if ( not QuestHistory_StatusColors ) then QuestHistory_StatusColors = { }; end QuestHistory_StatusColors[string.lower(QuestHistory_StatusColorType)] = { r = red, g = green, b = blue }; QuestHistory_Refresh(); end function QuestHistory_CancelColor(previousValues) if ( previousValues.r ) then ColorPickerFrame:SetColorRGB(previousValues.r, previousValues.g, previousValues.b); end end -- Converts the zone into the continent/zone numbers used by MapNotes function QuestHistory_MapNotes_GetZone(zone) for i = 1, 2, 1 do for j, value in QHMN_ZoneNames[i] do if ( value == zone ) then return i, j; end end end return 0, 0; end -- Creates the text for a new note and sends it to MapNotes function QuestHistory_SendToMapNotes(button, locationType) if ( QHMN_Data and QHMN_ZoneNames ) then local _, _, area, xPos, yPos = string.find(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID]["p"..locationType], "(.*):(.*):(.*)"); if ( area and xPos and yPos ) then if ( button == "RightButton" ) then QHMN_SetNextAsMiniNote = 2; end local continent, zone = QuestHistory_MapNotes_GetZone(area); local title; local info1 = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID].t; local info2 = ""; local creator = DisplayedPlayerCharacterName; local icon; local tcolor = 0; local i1color = 2; local i2color = 0; if ( locationType == "a" ) then title = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID].g; icon = 3; else title = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID].w; icon = 1; end local text = "c<"..continent.."> z<"..zone.."> x<"..xPos.."> y<"..yPos..">"; text = text.." t<"..title.."> i1<"..info1.."> i2<"..info2.."> cr<"..creator..">"; text = text.." i<"..icon.."> tf<"..tcolor.."> i1f<"..i1color.."> i2f<"..i2color..">"; QHMN_GetNoteBySlashCommand(text); end end end