vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 --[[
2  
3 QuestHistory -- An in-game history log of quests that have been accepted, completed, failed, or abandoned.
4  
5 Originally written by Jasters in 2004.
6 Adopted by Dsanai, after Jasters left World of Warcraft, in late 2005.
7  
8 http://ui.worldofwar.net/ui.php?id=1417
9 http://www.curse-gaming.com/mod.php?addid=2310
10 http://www.emerald-order.com/wow/QuestHistory.php
11  
12 FEATURES
13 -- Logs all quests that a player receives and records them in a sortable in-game list
14 -- The user can customize what data the addon logs. Using the default options records the following information for each quest:
15 -- -- Quest title, objectives, rewards, items as shown in the normal QuestLog
16 -- -- NPCs giving and completing the quest
17 -- -- Location of player when quest was accepted/completed
18 -- -- Level of player when quest was accepted/completed
19 -- -- Played time of player when quest was accepted/completed (displayed in days:hours:minutes:seconds format)
20 -- -- Times quest has been abandoned/failed
21 -- -- XP rewarded for quest completion
22 -- -- Money rewarded for quest completion
23 -- Notes can be added to quests
24 -- Quests can be edited and deleted
25 -- Quests can be manually added
26 -- Only records quest data from the time the addon is first used
27 -- Does not modify any of the game's original files
28  
29 VERSION HISTORY
30  
31 v10900-1
32 -- Added MetaMap support (as alternative to MapNotes).
33 -- Fixed background graphic display issues (thanks to blankstare2@Curse)
34 -- Added slash-command to enable/disable Quest Level display at NPC's. Type /qh levels to toggle.
35 -- Forced current realm's characters to sort to top of the dropdown list.
36 -- Fixed error that occurred with the dropdown list when you had a large number of characters on various servers.
37 -- Changed version structure to match other projects.
38 -- Updated for Patch 10900.
39  
40 v2.8
41 -- Added quest level display to Quest Selection window at NPC's. Only occurs when there's more than one quest available.
42  
43 v2.72
44 -- Changed the WorldMap cycler to the zoning event, so hopefully the Blizzard 0,0 bug will be killed PRIOR to any Quest activity.
45 -- Removed the circuit that was getting people stuck on quests in instances.
46 -- Increased individual quest-accept delay to 1 second. This may not be long enough. Let me know!
47  
48 v2.71
49 -- 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.
50  
51 v2.7
52 -- Changed Unknown Entity search string to a localized global (so all languages should be covered) (courtesy Asjaskan@Curse)
53 -- Now strips any third-party quest level-adding addon text from the titles (courtesy Asjaskan@Curse)
54 -- Added new trap for 0,0 coordinate bug.
55 -- Added possible 0,0 fix, using a WorldMap show/hide cycler.
56 -- Finally fixed the delay on subsequent accepted quests (speed-accept bug).
57 -- Fixed errors that occurred upon login if you weren't an existing QH user.
58 -- Updated to TOC 1800.
59  
60 v2.6
61 -- Fixed Unknown Entity bug (more like, plague).
62 -- Added Unknown Entity checks/fixes to the login procedure, and to the Repair module.
63 -- Updated for Patch 1700.
64  
65 ]]
66  
67 ----------------------------------------------------------------------------------------------------
68 -- Local QuestHistory Variables
69 ----------------------------------------------------------------------------------------------------
70  
71 local RealmName; -- Name of realm that is being played on
72 local PlayerCharacterName; -- Name of the player's character
73 local DisplayedRealmName; -- Name of realm for which quest data is displayed
74 local DisplayedPlayerCharacterName -- Name of character for which quest data is displayed
75  
76 local questHasBeenRecentlyAccepted; -- Flags if QUEST_LOG_UPDATE event occurs for accepting a quest
77 local questHasBeenRecentlyAbandoned; -- Flags if QUEST_LOG_UPDATE event occurs for abandoning a quest
78  
79 local recentlyAcceptedLocation; -- Accepted location of the most recently accepted quest
80 local recentNPCQuestGiver; -- Name of player's target when most recent quest was accepted
81  
82 local recentlyCompletedQuestID; -- ID of entry in QuestHistory_List for the most recently completed quest
83 local XPBeforeQuestCompletion = 0; -- Amount of XP before completing a quest
84 local XPMaxBeforeQuestCompletion = 0; -- Maximum XP before completing quest, needed in case player levels
85  
86 local timeText; -- Time played when a quest is accepted/completed
87 local timeEvent; -- Event (Accepted, Completed or Logged) to which timeText applies
88  
89 local SortedTable; -- Table to sort the indices of the quest list
90 local sizeSortedTable; -- Current size of SortedTable
91 local currentSortType = "accepted"; -- Keeps track of the current sort type of the quest list
92 local currentSortOrder = "inc"; -- Keeps track of the current sort order of the quest list
93  
94 local currentDetailedQuestID; -- Index of the current quest that is in the DetailFrame
95 local currentSortedID = 0; -- SortedTable index of the quest highlighted in the list frame
96 local currentTitleListID; -- Index of the currently selected TitleList button in the list frame
97  
98 local searchText; -- String to match in quest details
99  
100 timeSinceLastLog = 0; -- Keeps track of the time since the last logging of quest data
101 allowLogging = true; -- Flags whether it is okay to run QuestHistory_LogCurrentQuests()
102 QuestHistory_DelayedConfigInit = nil;
103 QuestHistory_DelayedLoginFired = nil; -- Flags after the initial login delay has fired, so we know to stop it.
104 QuestHistory_Loaded = false;
105 QuestHistory_InsideInstance = false;
106  
107 -- For Sort Dropdown list
108 local QUESTHISTORY_SORT_DROPDOWN_LIST = {
109 { name = SORT_ACCEPTED, sortType = "accepted" },
110 { name = SORT_TITLE, sortType = "t" },
111 { name = SORT_LEVEL, sortType = "l" },
112 { name = SORT_CATEGORY, sortType = "c" },
113 { name = SORT_TAG, sortType = "y" },
114 { name = SORT_COMPLETED, sortType = "co" },
115 { name = SORT_XP, sortType = "x" },
116 { name = SORT_MONEY, sortType = "m" },
117 { name = SORT_GIVER, sortType = "g" },
118 { name = SORT_COMPLETER, sortType = "w" },
119 };
120  
121 QUESTHISTORY_SORT_DROPDOWN_MENU_WIDTH = 120; -- Width of the sort dropdown menu
122 QUESTHISTORY_CHARACTER_DROPDOWN_MENU_WIDTH = 150; -- Width of the character dropdown menu
123 QUESTHISTORY_ITEMS_SHOWN = 31; -- Number of lines in the scrolling list
124  
125 -- Colors for quest status
126 local QuestHistoryStatusColor = { };
127 QuestHistoryStatusColor["completed"] = { r = 0.25, g = 0.50, b = 0.75 }; -- default color of completed quests (blue)
128 QuestHistoryStatusColor["abandoned"] = { r = 0.75, g = 0.00, b = 0.50 }; -- default color of abandoned quests (purple)
129 QuestHistoryStatusColor["failed"] = { r = 1.00, g = 0.50, b = 0.50 }; -- default color of failed quests (pink)
130  
131 -- Flags for logging/showing of quest data
132 local QuestHistoryFlags = { };
133 QuestHistoryFlags["showAbandoned"] = { index = 1, status = true, text = QUESTHISTORY_SHOW_ABANDONED, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_SHOW_ABANDONED };
134 QuestHistoryFlags["showCurrent" ] = { index = 2, status = true, text = QUESTHISTORY_SHOW_CURRENT, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_SHOW_CURRENT };
135 QuestHistoryFlags["showCompleted" ] = { index = 3, status = true, text = QUESTHISTORY_SHOW_COMPLETED, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_SHOW_COMPLETED };
136 QuestHistoryFlags["logLevel"] = { index = 4, status = true, data = "l", text = QUESTHISTORY_LOG_LEVEL, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_LEVEL };
137 QuestHistoryFlags["logCategory"] = { index = 5, status = true, data = "c", text = QUESTHISTORY_LOG_CATEGORY, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_CATEGORY };
138 QuestHistoryFlags["logTag"] = { index = 6, status = true, data = "y", text = QUESTHISTORY_LOG_TAG, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_TAG };
139 QuestHistoryFlags["logCompletedOrder"] = { index = 7, status = true, data = "co", text = QUESTHISTORY_LOG_COMPLETED_ORDER, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_COMPLETED_ORDER };
140 QuestHistoryFlags["logDescription"] = { index = 8, status = true, data = "d", text = QUESTHISTORY_LOG_DESCRIPTION, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_DESCRIPTION };
141 QuestHistoryFlags["logObjectives"] = { index = 9, status = true, data = "o", text = QUESTHISTORY_LOG_OBJECTIVES, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_OBJECTIVES };
142 QuestHistoryFlags["logObjectivesStatus"] = { index = 10, status = true, data = "os", text = QUESTHISTORY_LOG_OBJECTIVES_STATUS, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_OBJECTIVES_STATUS };
143 QuestHistoryFlags["logRewards"] = { index = 11, status = true, data = "r", text = QUESTHISTORY_LOG_REWARDS, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_REWARDS };
144 QuestHistoryFlags["logChoices"] = { index = 12, status = true, data = "i", text = QUESTHISTORY_LOG_CHOICES, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_CHOICES };
145 QuestHistoryFlags["logSpells"] = { index = 13, status = true, data = "s", text = QUESTHISTORY_LOG_SPELLS, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_SPELLS };
146 QuestHistoryFlags["logRewardMoney"] = { index = 14, status = true, data = "m", text = QUESTHISTORY_LOG_REWARD_MONEY, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_REWARD_MONEY };
147 QuestHistoryFlags["logBackgroundMaterial"] = { index = 15, status = true, data = "bg", text = QUESTHISTORY_LOG_BACKGROUND_MATERIAL, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_BACKGROUND_MATERIAL };
148 QuestHistoryFlags["logRequiredMoney"] = { index = 16, status = true, data = "rm", text = QUESTHISTORY_LOG_REQUIRED_MONEY, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_REQUIRED_MONEY };
149 QuestHistoryFlags["logXPReward"] = { index = 17, status = true, data = "x", text = QUESTHISTORY_LOG_XP_REWARD, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_XP_REWARD };
150 QuestHistoryFlags["logQuestGiver"] = { index = 18, status = true, data = "g", text = QUESTHISTORY_LOG_QUEST_GIVER, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_QUEST_GIVER };
151 QuestHistoryFlags["logQuestCompleter"] = { index = 19, status = true, data = "w", text = QUESTHISTORY_LOG_QUEST_COMPLETER, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_QUEST_COMPLETER };
152 QuestHistoryFlags["logLevelAccepted"] = { index = 20, status = true, data = "la", text = QUESTHISTORY_LOG_ACCEPTED_LEVEL, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_ACCEPTED_LEVEL };
153 QuestHistoryFlags["logLevelCompleted"] = { index = 21, status = true, data = "lc", text = QUESTHISTORY_LOG_COMPLETED_LEVEL, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_COMPLETED_LEVEL };
154 QuestHistoryFlags["logTimeAccepted"] = { index = 22, status = true, data = "ta", text = QUESTHISTORY_LOG_ACCEPTED_TIME, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_ACCEPTED_TIME };
155 QuestHistoryFlags["logTimeCompleted"] = { index = 23, status = true, data = "tc", text = QUESTHISTORY_LOG_COMPLETED_TIME, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_COMPLETED_TIME };
156 QuestHistoryFlags["logAcceptedLocation"] = { index = 24, status = true, data = "pa", text = QUESTHISTORY_LOG_ACCEPTED_LOCATION, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_ACCEPTED_LOCATION };
157 QuestHistoryFlags["logCompletedLocation"] = { index = 25, status = true, data = "pc", text = QUESTHISTORY_LOG_COMPLETED_LOCATION, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_COMPLETED_LOCATION };
158 QuestHistoryFlags["removePortQuests"] = { index = 26, status = false, text = QUESTHISTORY_REMOVE_PORT_QUESTS, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_REMOVE_PORT_QUESTS };
159 QuestHistoryFlags["removeDuplicates"] = { index = 27, status = false, text = QUESTHISTORY_REMOVE_DUPLICATES, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_REMOVE_DUPLICATES };
160 QuestHistoryFlags["allowEditing"] = { index = 28, status = false, text = QUESTHISTORY_ALLOW_EDITING, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_ALLOW_EDITING };
161 QuestHistoryFlags["allowDeleting"] = { index = 29, status = false, text = QUESTHISTORY_ALLOW_DELETING, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_ALLOW_DELETING };
162 QuestHistoryFlags["logPortQuests"] = { index = 30, status = false, text = QUESTHISTORY_LOG_PORT_QUESTS, tooltipText = QUESTHISTORY_OPTION_TOOLTIP_LOG_PORT_QUESTS };
163  
164 local QuestHistoryData = { };
165 QuestHistoryData["t"] = { old = "title", box = "Title", type = "string", tab = 22 };
166 QuestHistoryData["l"] = { old = "level", box = "Level", type = "number", tab = 6 };
167 QuestHistoryData["c"] = { old = "location", box = "Category", type = "string", tab = 8 };
168 QuestHistoryData["y"] = { old = "tag", box = "Tag", type = "string", tab = 9 };
169 QuestHistoryData["d"] = { old = "description", box = "Description", type = "string", tab = 24 };
170 QuestHistoryData["o"] = { old = "objectives", box = "Objectives", type = "string", tab = 23 };
171 QuestHistoryData["la"] = { old = "levelAccepted", box = "LevelAccepted", type = "number", tab = 1 };
172 QuestHistoryData["ll"] = { old = "levelLogged", type = "number" };
173 QuestHistoryData["lc"] = { old = "levelCompleted", box = "LevelCompleted", type = "number", tab = 2 };
174 QuestHistoryData["rm"] = { old = "requiredMoney", type = "number" };
175 QuestHistoryData["m"] = { old = "rewardMoney", box = "MoneyRewarded", type = "number", tab = 3 };
176 QuestHistoryData["bg"] = { old = "material", type = "string" };
177 QuestHistoryData["g"] = { old = "NPCGiver", box = "QuestGiver", type = "string", tab = 10 };
178 QuestHistoryData["w"] = { old = "NPCCompleter", box = "QuestCompleter", type = "string", tab = 11 };
179 QuestHistoryData["ta"] = { old = "timeAccepted", box = "TimeAccepted", type = "string", tab = 18 };
180 QuestHistoryData["tl"] = { old = "timeLogged", type = "string" };
181 QuestHistoryData["tc"] = { old = "timeCompleted", box = "TimeCompleted", type = "string", tab = 19 };
182 QuestHistoryData["co"] = { old = "completedOrder", box = "CompletedOrder", type = "number", tab = 7 };
183 QuestHistoryData["a"] = { old = "isAbandoned", type = "boolean" };
184 QuestHistoryData["f"] = { old = "isFailed", type = "boolean" };
185 QuestHistoryData["ac"] = { old = "abandonedCount", box = "TimesAbandoned", type = "number", tab = 20 };
186 QuestHistoryData["fc"] = { old = "countFailed", box = "TimesFailed", type = "number", tab = 21 };
187 QuestHistoryData["n"] = { old = "note", type = "string" };
188 QuestHistoryData["x"] = { old = "XPReward", box = "XPRewarded", type = "number", tab = 4 };
189 QuestHistoryData["ao"] = { box = "AcceptedOrder", type = "number", tab = 5 };
190 QuestHistoryData["az"] = { box = "AcceptedZone", type = "string", tab = 12 };
191 QuestHistoryData["ax"] = { box = "AcceptedX", type = "number", tab = 13 };
192 QuestHistoryData["ay"] = { box = "AcceptedY", type = "number", tab = 14 };
193 QuestHistoryData["cz"] = { box = "CompletedZone", type = "string", tab = 15 };
194 QuestHistoryData["cx"] = { box = "CompletedX", type = "number", tab = 16 };
195 QuestHistoryData["cy"] = { box = "CompletedY", type = "number", tab = 17 };
196 QuestHistoryData["r"] = { type = "item" };
197 QuestHistoryData["i"] = { type = "item" };
198 QuestHistoryData["s"] = { type = "spell" };
199 QuestHistoryData["pa"] = { type = "string" };
200 QuestHistoryData["pc"] = { type = "string" };
201 QuestHistoryData["os"] = { type = "objective" };
202  
203 QUESTHISTORY_MAX_LEVEL = 60;
204  
205 -- Function hooks
206 local originalQuestDetailAcceptButton_OnClick; -- Game functions that need to be
207 local originalQuestRewardCompleteButton_OnClick; -- hooked because some quest logging
208 local originalQuestLogFrameAbandonButton_OnClick; -- needs to be done when they are called
209 local originalChatFrame_DisplayTimePlayed; -- To prevent played time from being displayed in chat
210  
211 ----------------------------------------------------------------------------------------------------
212 -- Global QuestHistory Variables
213 ----------------------------------------------------------------------------------------------------
214  
215 QUESTHISTORY_VERSION = 2.9; -- Version of QuestHistory
216  
217 QUESTHISTORY_ITEM_HEIGHT = 14; -- Height of the item buttons in the list frame
218  
219 UIPanelWindows["QuestHistoryFrame"] = { area = "left" , pushable = 12 };
220 UIPanelWindows["QuestHistoryOptionsFrame"] = { area = "left" , pushable = 0 };
221 UIPanelWindows["QuestHistoryDetailFrame"] = { area = "left" , pushable = 0 };
222 UIPanelWindows["QuestHistoryEditFrame"] = { area = "left" , pushable = 0 };
223 UIPanelWindows["QuestHistoryConfirmFrame"] = { area = "left" , pushable = 0 };
224  
225 QuestHistory_StatusColorType = ""; -- Type of quest status when changing color
226  
227 ----------------------------------------------------------------------------------------------------
228 -- Internal Functions
229 ----------------------------------------------------------------------------------------------------
230  
231 -- Initializes the dropdown box with the available selections
232 local function QuestHistoryFrameSortDropDown_Initialize()
233 local info;
234 for i = 1, getn(QUESTHISTORY_SORT_DROPDOWN_LIST), 1 do
235 info = { };
236 info.text = QUESTHISTORY_SORT_DROPDOWN_LIST[i].name;
237 info.func = QuestHistoryFrameSortDropDownButton_OnClick;
238 UIDropDownMenu_AddButton(info);
239 end
240 end
241  
242 local function QuestHistoryOptionsFrameCharacterDropDown_Initialize()
243 local info;
244 local lineCount = 0;
245  
246 local thisRealm = GetRealmName(); -- Current realm first
247 if (QuestHistory_List[thisRealm]) then
248 info = { };
249 info.text = thisRealm;
250 info.isTitle = 1;
251 UIDropDownMenu_AddButton(info);
252 lineCount = lineCount + 1;
253 for charIndex, charValue in QuestHistory_List[thisRealm] do
254 info = { };
255 info.text = " "..charIndex;
256 info.value = thisRealm;
257 info.func = QuestHistoryOptionsFrameCharacterDropDownButton_OnClick;
258 UIDropDownMenu_AddButton(info);
259 lineCount = lineCount + 1;
260 end
261 end
262  
263 for realmIndex, realmValue in QuestHistory_List do
264 if (realmIndex ~= thisRealm and lineCount <= 25) then -- Others, up to limit
265 info = { };
266 info.text = realmIndex;
267 info.isTitle = 1;
268 UIDropDownMenu_AddButton(info);
269 lineCount = lineCount + 1;
270 for charIndex, charValue in realmValue do
271 info = { };
272 info.text = " "..charIndex;
273 info.value = realmIndex;
274 info.func = QuestHistoryOptionsFrameCharacterDropDownButton_OnClick;
275 UIDropDownMenu_AddButton(info);
276 lineCount = lineCount + 1;
277 end
278 end
279 end
280 end
281  
282 -- Comparison function to sort table
283 local function QuestHistory_SortComparison(index1, index2)
284 if ( currentSortType ~= "accepted" ) then
285 -- Get the sort values that are to be compared
286 local sort1 = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index1][currentSortType];
287 local sort2 = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index2][currentSortType];
288 if ( currentSortOrder == "dec" ) then
289 -- Swap sort values if sorting in decremented order
290 sort1, sort2 = sort2, sort1;
291 end
292 -- Make sure sort1 is not nil and is compatible with sort2
293 if ( sort1 == nil ) then
294 if ( type(sort2) == "string" ) then
295 sort1 = "";
296 else
297 sort1 = 0;
298 end
299 end
300 -- Make sure sort2 is not nil and is compatible with sort1
301 if ( sort2 == nil ) then
302 if ( type(sort1) == "string" ) then
303 sort2 = "";
304 else
305 sort2 = 0;
306 end
307 end
308 -- If sorting by completed order, make sure incomplete quests are valued more than completed quests
309 -- and that current quests are valued more than abandoned quests
310 if ( currentSortType == "co" ) then
311 if ( sort1 ~= sort2 ) then
312 if ( sort1 == 0 ) then
313 sort1 = sort2 + 1;
314 elseif ( sort2 == 0 ) then
315 sort2 = sort1 + 1;
316 end
317 else
318 if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index1].a ) then
319 sort1 = -1;
320 end
321 if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index2].a ) then
322 sort2 = -1;
323 end
324 end
325 end
326 -- If sort1 is different from sort2, return comparison of sort values
327 if ( sort1 ~= sort2 ) then
328 return sort1 < sort2;
329 end
330 else
331 if ( currentSortOrder == "dec" ) then
332 -- Swap index values if sorting in decremented order
333 index1, index2 = index2, index1;
334 end
335 end
336 -- Return comparison of index values
337 return index1 < index2;
338 end
339  
340 -- Returns true if data in value table match the current criteria, false otherwise
341 local function QuestHistory_MatchesSearch(index, value)
342 -- Check if quest is completed
343 if ( value.co ) then
344 -- If it is and not showing completed quests, return false
345 if ( not QuestHistoryFlags["showCompleted"].status ) then
346 return false;
347 end
348 -- Check if quest is abandoned
349 elseif ( value.a ) then
350 -- If it is and not showing abandoned quests, return false
351 if ( not QuestHistoryFlags["showAbandoned"].status ) then
352 return false;
353 end
354 -- Quest must be current
355 else
356 -- If not showing current quests, return false
357 if ( not QuestHistoryFlags["showCurrent"].status ) then
358 return false;
359 end
360 end
361 -- If there is no search text defined, return true
362 if ( not searchText ) then
363 return true;
364 else
365 -- Otherwise, cycle through quest details looking for search text
366 for i, v in value do
367 if ( string.find(strupper(tostring(value[i])), strupper(searchText)) ) then
368 return true;
369 end
370 end
371 end
372 -- Return false if search text is defined and not found in the quest details
373 return false;
374 end
375  
376 -- Builds the SortedTable array and populates it with the indices of QuestHistory_List that match
377 -- the current criteria. This array can then be sorted without changing the original list.
378 local function QuestHistory_BuildSortedTable()
379 local iNew = 1;
380 -- Initialize blank table
381 SortedTable = { };
382 -- Populate table with quest IDs that match current criteria
383 for index, value in QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName] do
384 if ( QuestHistory_MatchesSearch(index, value) ) then
385 SortedTable[iNew] = index;
386 iNew = iNew + 1;
387 end
388 end
389 -- Store size of sorted table
390 sizeSortedTable = iNew - 1;
391 if ( QUESTHISTORY_SORT_DROPDOWN_LIST[UIDropDownMenu_GetSelectedID(QuestHistoryFrameSortDropDown)].sortType ) then
392 -- Sort table
393 table.sort(SortedTable, QuestHistory_SortComparison);
394 end
395 -- Find sorted table ID that matches the currently selected quest
396 currentSortedID = 0;
397 for index, value in SortedTable do
398 if ( currentDetailedQuestID == SortedTable[index] ) then
399 currentSortedID = index;
400 end
401 end
402 end
403  
404 -- Refreshes the display of the QuestHistory_Frame and the scrolling list.
405 local function QuestHistory_Refresh()
406 -- Build the array that contains the indices to sort and display
407 QuestHistory_BuildSortedTable();
408 -- Check if the currently selected quest is displayed in the scrollframe or if scrolling is needed to display it
409 if ( currentSortedID and ( currentSortedID > 0 ) and ( (currentSortedID - FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame) ) <=0 or ( currentSortedID - FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame) ) >= 32 ) ) then
410 -- Calculate new offset to set scrollframe to so that currently selected quest is displayed
411 local newOffset = currentSortedID * QUESTHISTORY_ITEM_HEIGHT - (QuestHistoryListScrollFrame:GetHeight() / 2);
412 if ( newOffset < 0 ) then
413 newOffset = 0;
414 end
415 -- Scroll frame and set the new value
416 QuestHistoryListScrollFrameScrollBar:SetValue(newOffset);
417 end
418 -- Store the title list ID for the currently selected quest
419 currentTitleListID = currentSortedID - FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame);
420 QuestHistory_Update();
421 end
422  
423 -- Toggles the currently selected sorting method from increasing to decreasing or vice versa
424 local function QuestHistory_SetSortOrder()
425 -- Get selected sort type
426 local sortType = QUESTHISTORY_SORT_DROPDOWN_LIST[UIDropDownMenu_GetSelectedID(QuestHistoryFrameSortDropDown)].sortType;
427 -- If selected sort type is the same as the current sort type then toggle between incrementing and decrementing
428 if ( currentSortType == sortType and currentSortOrder == "inc" ) then
429 currentSortOrder = "dec";
430 else
431 currentSortOrder = "inc";
432 end
433 -- Set current sort type to the one selected
434 currentSortType = sortType;
435 -- Refresh the display
436 QuestHistory_Refresh();
437 end
438  
439 -- Displays and updates the reward items portion of the detail view for the quest specified by questIndex
440 -- Most of the code has been adapted from QuestFrameItems_Update() located in QuestFrame.lua
441 local function QuestHistory_Detail_Items_Update(questIndex)
442 local questItemName = "QuestHistoryDetailItem";
443 local questItemReceiveText = QuestHistoryDetailItemReceiveText;
444 local spacerFrame = QuestHistoryDetailSpacerFrame;
445 -- Get reward data for quest
446 local numQuestRewards, numQuestChoices;
447 if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["r"] ) then
448 numQuestRewards = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["r"]);
449 end
450 if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["i"] ) then
451 numQuestChoices = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["i"]);
452 end
453 if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["s"] ) then
454 numQuestSpellRewards = 1;
455 else
456 numQuestSpellRewards = 0;
457 end
458 local money = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].m;
459 local material = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].bg;
460 -- Set variables to default values if the corresponding data is not in log
461 if ( not numQuestRewards ) then
462 numQuestRewards = 0;
463 end
464 if ( not numQuestChoices ) then
465 numQuestChoices = 0;
466 end
467 if ( not money ) then
468 money = 0;
469 end
470 if ( not material ) then
471 material = "Parchment";
472 end
473 -- Calculate total number of rewards
474 local totalRewards = numQuestRewards + numQuestChoices + numQuestSpellRewards;
475 -- If there is any type of reward, show the reward frame
476 if ( totalRewards == 0 and money == 0 ) then
477 QuestHistoryDetailRewardTitleText:Hide();
478 else
479 QuestHistoryDetailRewardTitleText:Show();
480 QuestFrame_SetTitleTextColor(QuestHistoryDetailRewardTitleText, material);
481 QuestFrame_SetAsLastShown(QuestHistoryDetailRewardTitleText, spacerFrame);
482 end
483 -- If there is money rewarded, show the money frame and populate it
484 if ( money == 0 ) then
485 QuestHistoryDetailMoneyFrame:Hide();
486 else
487 QuestHistoryDetailMoneyFrame:Show();
488 QuestFrame_SetAsLastShown(QuestHistoryDetailMoneyFrame, spacerFrame);
489 MoneyFrame_Update("QuestHistoryDetailMoneyFrame", money);
490 end
491 -- Hide the unused frames
492 for i = totalRewards + 1, MAX_NUM_ITEMS, 1 do
493 getglobal(questItemName..i):Hide();
494 end
495 -- If there are items that can be chosen, show the choose items frame and populate it
496 local questItem, name, texture, numItems;
497 if ( numQuestChoices > 0 ) then
498 QuestHistoryDetailItemChooseText:Show();
499 QuestFrame_SetTextColor(QuestHistoryDetailItemChooseText, material);
500 QuestFrame_SetAsLastShown(QuestHistoryDetailItemChooseText, spacerFrame);
501 -- Cycle through the quest choices and set up the buttons with the data
502 for i = 1, numQuestChoices, 1 do
503 questItem = getglobal(questItemName..i);
504 questItem.type = "choice";
505 link = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["i"][i].l;
506 if ( link ) then
507 _, _, name = string.find(link, "|c%x+|H%w+:%d+:%d+:%d+:%d+|h%[(.-)%]|h|r");
508 end
509 texture = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["i"][i].t;
510 numItems = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["i"][i].a;
511 if ( numItems == nil or numItems == 0 ) then
512 numItems = 1;
513 end
514 -- Set the ID for the choice and show the item
515 questItem:SetID(i);
516 questItem:Show();
517 -- For the tooltip
518 questItem.rewardType = "item"
519 QuestFrame_SetAsLastShown(questItem, spacerFrame);
520 getglobal(questItemName..i.."Name"):SetText(name);
521 SetItemButtonCount(questItem, numItems);
522 SetItemButtonTexture(questItem, texture);
523 SetItemButtonTextureVertexColor(questItem, 1.0, 1.0, 1.0);
524 SetItemButtonNameFrameVertexColor(questItem, 1.0, 1.0, 1.0);
525 -- Anchor this item correctly since the items are shown two to a line
526 if ( i > 1 ) then
527 if ( mod(i, 2) == 1 ) then
528 questItem:SetPoint("TOPLEFT", questItemName..(i - 2), "BOTTOMLEFT", 0, -2);
529 else
530 questItem:SetPoint("TOPLEFT", questItemName..(i - 1), "TOPRIGHT", 1, 0);
531 end
532 else
533 questItem:SetPoint("TOPLEFT", "QuestHistoryDetailItemChooseText", "BOTTOMLEFT", -3, -5);
534 end
535 end
536 else
537 -- Hide the choose items frame if there are no choices
538 QuestHistoryDetailItemChooseText:Hide();
539 end
540 -- If there are quest rewards, show the receive items frame and populate it with reward data
541 if ( numQuestRewards > 0 or money > 0 or numQuestSpellRewards > 0 ) then
542 QuestFrame_SetTextColor(questItemReceiveText, material);
543 -- Anchor the reward text differently if there are choosable rewards
544 if ( numQuestChoices > 0 ) then
545 questItemReceiveText:SetText(TEXT(REWARD_ITEMS));
546 local index = numQuestChoices;
547 if ( mod(index, 2) == 0 ) then
548 index = index - 1;
549 end
550 questItemReceiveText:SetPoint("TOPLEFT", questItemName..index, "BOTTOMLEFT", 3, -5);
551 else
552 questItemReceiveText:SetText(TEXT(REWARD_ITEMS_ONLY));
553 questItemReceiveText:SetPoint("TOPLEFT", "QuestHistoryDetailRewardTitleText", "BOTTOMLEFT", 3, -5);
554 end
555 -- Show the receive items frame and set it as the last shown frame
556 questItemReceiveText:Show();
557 QuestFrame_SetAsLastShown(questItemReceiveText, spacerFrame);
558 -- Setup mandatory rewards
559 for i = 1, numQuestRewards, 1 do
560 questItem = getglobal(questItemName..(i + numQuestChoices));
561 questItem.type = "reward";
562 link = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["r"][i].l;
563 if ( link ) then
564 _, _, name = string.find(link, "|c%x+|H%w+:%d+:%d+:%d+:%d+|h%[(.-)%]|h|r");
565 end
566 texture = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["r"][i].t;
567 numItems = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["r"][i].a;
568 if ( numItems == nil or numItems == 0 ) then
569 numItems = 1;
570 end
571 -- Set the ID for the reward and show the item
572 questItem:SetID(i);
573 questItem:Show();
574 -- For the tooltip
575 questItem.rewardType = "item";
576 QuestFrame_SetAsLastShown(questItem, spacerFrame);
577 getglobal(questItemName..(i + numQuestChoices).."Name"):SetText(name);
578 SetItemButtonCount(questItem, numItems);
579 SetItemButtonTexture(questItem, texture);
580 SetItemButtonTextureVertexColor(questItem, 1.0, 1.0, 1.0);
581 SetItemButtonNameFrameVertexColor(questItem, 1.0, 1.0, 1.0);
582 -- Anchor this item correctly since the items are shown two to a line
583 if ( i > 1 ) then
584 if ( mod(i, 2) == 1 ) then
585 questItem:SetPoint("TOPLEFT", questItemName..((i + numQuestChoices) - 2), "BOTTOMLEFT", 0, -2);
586 else
587 questItem:SetPoint("TOPLEFT", questItemName..((i + numQuestChoices) - 1), "TOPRIGHT", 1, 0);
588 end
589 else
590 questItem:SetPoint("TOPLEFT", "QuestHistoryDetailItemReceiveText", "BOTTOMLEFT", -3, -5);
591 end
592 end
593 -- Setup spell reward
594 if ( numQuestSpellRewards > 0 ) then
595 texture = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["s"].t;
596 name = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["s"].n;
597 -- Show the spell reward button
598 questItem = getglobal(questItemName..(numQuestRewards + numQuestChoices + 1));
599 questItem.type = "spell";
600 questItem:Show();
601 -- For the tooltip
602 questItem.rewardType = "spell";
603 SetItemButtonTexture(questItem, texture);
604 getglobal(questItemName..(numQuestRewards + numQuestChoices + 1).."Name"):SetText(name);
605 -- Anchor the spell depending on whether it shares a line with a reward item or if it needs a line of its own
606 if ( numQuestRewards > 0 ) then
607 if ( mod(numQuestRewards, 2) == 0 ) then
608 questItem:SetPoint("TOPLEFT", questItemName..((numQuestRewards + numQuestChoices) - 1), "BOTTOMLEFT", 0, -2);
609 else
610 questItem:SetPoint("TOPLEFT", questItemName..((numQuestRewards + numQuestChoices)), "TOPRIGHT", 1, 0);
611 end
612 else
613 questItem:SetPoint("TOPLEFT", "QuestHistoryDetailItemReceiveText", "BOTTOMLEFT", -3, -5);
614 end
615 end
616 else
617 questItemReceiveText:Hide();
618 end
619 end
620  
621 -- Displays and updates all non-item details for the quest specified by questIndex
622 -- Most of the code adapted from QuestLog_UpdateQuestDetails() located in QuestLogFrame.lua
623 local function QuestHistory_Detail_Update(questIndex)
624 local spacerFrame = QuestHistoryDetailSpacerFrame;
625 --Hide and Show the appropriate frames
626 QuestHistoryDetailNotesScrollFrame:Hide();
627 QuestHistoryDetailSaveButton:Hide();
628 QuestHistoryDetailListScrollFrame:Show();
629 QuestHistoryDetailEditButton:Show();
630 -- Get information for frame title
631 local QuestHistoryDetailTitle = QuestHistoryDetailTitle;
632 local questTitle = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].t;
633 local tagtext = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].y;
634 local level = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].l;
635 -- Set variables to default values if the corresponding data is not in log
636 if ( not questTitle ) then
637 questTitle = "";
638 end
639 if ( tagtext and tagtext ~= "" ) then
640 tagtext = " ["..tagtext.."]";
641 else
642 tagtext = "";
643 end
644 if ( not level ) then
645 level = "";
646 end
647 -- Set the title of the frame to show quest title, level and tag
648 QuestHistoryDetailTitle:SetText(format(TEXT(QUESTHISTORY_DETAIL_TITLE_FORMAT), questTitle, level, tagtext));
649 QuestHistoryDetailTitle:Show();
650 -- Display the level of player when quest was accepted/logged
651 local levelAccepted = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].la;
652 if ( levelAccepted ) then
653 QuestHistoryDetailLevelAcceptedTitle:SetText(QUESTHISTORY_LEVEL_ACCEPTED_TITLE);
654 else
655 levelAccepted = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].ll;
656 QuestHistoryDetailLevelAcceptedTitle:SetText(QUESTHISTORY_LEVEL_LOGGED_TITLE);
657 end
658 if ( levelAccepted ) then
659 QuestHistoryDetailLevelAcceptedText:SetText(levelAccepted);
660 QuestHistoryDetailLevelAcceptedText:Show();
661 else
662 QuestHistoryDetailLevelAcceptedText:Hide();
663 end
664 -- Display the level of player when quest was completed
665 local levelCompleted = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].lc;
666 if ( levelCompleted ) then
667 QuestHistoryDetailLevelCompletedText:SetText(levelCompleted);
668 QuestHistoryDetailLevelCompletedText:Show();
669 else
670 QuestHistoryDetailLevelCompletedText:Hide();
671 end
672 -- Display the money reward for quest
673 local rewardMoney = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].m;
674 if ( rewardMoney ) then
675 QuestHistoryDetailMoneyRewardedText:SetText(rewardMoney);
676 QuestHistoryDetailMoneyRewardedText:Show();
677 else
678 QuestHistoryDetailMoneyRewardedText:Hide();
679 end
680 -- Display the XP gained for quest
681 local XPReward = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].x;
682 if ( XPReward ) then
683 QuestHistoryDetailXPRewardedText:SetText(XPReward);
684 QuestHistoryDetailXPRewardedText:Show();
685 else
686 QuestHistoryDetailXPRewardedText:Hide();
687 end
688 -- Display the name of the quest giver
689 local giver = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].g;
690 if ( giver ) then
691 QuestHistoryDetailQuestGiverText:SetText(giver);
692 QuestHistoryDetailQuestGiverText:Show();
693 else
694 QuestHistoryDetailQuestGiverText:Hide();
695 end
696 -- Display the name of the quest completer
697 local completer = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].w;
698 if ( completer ) then
699 QuestHistoryDetailQuestCompleterText:SetText(completer);
700 QuestHistoryDetailQuestCompleterText:Show();
701 else
702 QuestHistoryDetailQuestCompleterText:Hide();
703 end
704 -- Display the location where quest was accepted
705 if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].pa ) then
706 local _, _, acceptedZone, acceptedX, acceptedY = string.find(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].pa, "(.*):(.*):(.*)");
707 QuestHistoryDetailAcceptedLocationText:SetText(acceptedZone.." ("..floor(tonumber(acceptedX) * 100)..", "..floor(tonumber(acceptedY) * 100)..")");
708 QuestHistoryDetailAcceptedLocationButton:Show();
709 else
710 QuestHistoryDetailAcceptedLocationButton:Hide();
711 end
712 -- Display the location where quest was completed
713 if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].pc ) then
714 local _, _, completedZone, completedX, completedY = string.find(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].pc, "(.*):(.*):(.*)");
715 QuestHistoryDetailCompletedLocationText:SetText(completedZone.." ("..floor(tonumber(completedX) * 100)..", "..floor(tonumber(completedY) * 100)..")");
716 QuestHistoryDetailCompletedLocationButton:Show();
717 else
718 QuestHistoryDetailCompletedLocationButton:Hide();
719 end
720 -- Display the time played when quest was accepted/logged
721 local timeAccepted = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].ta;
722 if ( timeAccepted ) then
723 QuestHistoryDetailTimeAcceptedTitle:SetText(QUESTHISTORY_TIME_ACCEPTED_TITLE);
724 else
725 timeAccepted = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].tl;
726 QuestHistoryDetailTimeAcceptedTitle:SetText(QUESTHISTORY_TIME_LOGGED_TITLE);
727 end
728 if ( timeAccepted ) then
729 QuestHistoryDetailTimeAcceptedText:SetText(timeAccepted);
730 QuestHistoryDetailTimeAcceptedText:Show();
731 else
732 QuestHistoryDetailTimeAcceptedText:Hide();
733 end
734 -- Display the time played when quest was completed
735 local timeCompleted = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].tc;
736 if ( timeCompleted) then
737 QuestHistoryDetailTimeCompletedText:SetText(timeCompleted);
738 QuestHistoryDetailTimeCompletedText:Show();
739 else
740 QuestHistoryDetailTimeCompletedText:Hide();
741 end
742 -- Display the number of times quest has been abandoned
743 local abandonCount = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].ac;
744 if ( not abandonCount ) then
745 abandonCount = 0;
746 end
747 QuestHistoryDetailTimesAbandonedText:SetText(abandonCount);
748 QuestHistoryDetailTimesAbandonedText:Show();
749 -- Display the number of times quest has been failed
750 local failCount = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].fc;
751 if ( not failCount ) then
752 failCount = 0;
753 end
754 QuestHistoryDetailTimesFailedText:SetText(failCount);
755 QuestHistoryDetailTimesFailedText:Show();
756 -- Display the quest note if the player has entered one
757 local note = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].n;
758 if ( note ) then
759 QuestHistoryDetailListNotes:SetText(note);
760 QuestHistoryDetailListNotes:Show();
761 else
762 QuestHistoryDetailListNotes:Hide();
763 end
764 -- Display the quest title
765 if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].f ) then
766 questTitle = questTitle.." = ("..TEXT(FAILED)..")";
767 end
768 QuestHistoryDetailQuestTitle:SetText(questTitle);
769 -- Display the quest objective
770 local questObjectives = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].o;
771 if ( not questObjectives ) then
772 questObjectives = "";
773 end
774 QuestHistoryDetailObjectivesText:SetText(questObjectives);
775 -- If there are objectives, then set their text and display them
776 local numObjectives = 0;
777 if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["os"] ) then
778 numObjectives = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["os"]);
779 end
780 for i = 1, numObjectives, 1 do
781 local string = getglobal("QuestHistoryDetailObjective"..i);
782 local text = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["os"][i].t;
783 if ( text ) then
784 if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["os"][i].f ) then
785 string:SetTextColor(0.2, 0.2, 0.2);
786 text = text.." ("..TEXT(COMPLETE)..")";
787 else
788 string:SetTextColor(0, 0, 0);
789 end
790 string:SetText(text);
791 string:Show();
792 QuestFrame_SetAsLastShown(string, spacerFrame);
793 end
794 end
795 for i = numObjectives + 1, MAX_OBJECTIVES, 1 do
796 getglobal("QuestHistoryDetailObjective"..i):Hide();
797 end
798 -- If there's money required then anchor and display it
799 local requiredMoney = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].rm;
800 if ( not requiredMoney ) then
801 requiredMoney = 0;
802 end
803 if ( requiredMoney > 0 ) then
804 if ( numObjectives > 0 ) then
805 QuestHistoryDetailRequiredMoneyText:SetPoint("TOPLEFT", "QuestHistoryDetailObjective"..numObjectives, "BOTTOMLEFT", 0, -4);
806 else
807 QuestHistoryDetailRequiredMoneyText:SetPoint("TOPLEFT", "QuestHistoryDetailObjectivesText", "BOTTOMLEFT", 0, -10);
808 end
809 MoneyFrame_Update("QuestHistoryDetailRequiredMoneyFrame", requiredMoney);
810 if ( ( not QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].co ) and ( requiredMoney > GetMoney() ) ) then
811 -- Not enough money for a current quest
812 QuestHistoryDetailRequiredMoneyText:SetTextColor(0, 0, 0);
813 SetMoneyFrameColor("QuestHistoryDetailRequiredMoneyFrame", 1.0, 0.1, 0.1);
814 else
815 QuestHistoryDetailRequiredMoneyText:SetTextColor(0.2, 0.2, 0.2);
816 SetMoneyFrameColor("QuestHistoryDetailRequiredMoneyFrame", 1.0, 1.0, 1.0);
817 end
818 QuestHistoryDetailRequiredMoneyText:Show();
819 QuestHistoryDetailRequiredMoneyFrame:Show();
820 else
821 QuestHistoryDetailRequiredMoneyText:Hide();
822 QuestHistoryDetailRequiredMoneyFrame:Hide();
823 end
824 if ( requiredMoney > 0 ) then
825 QuestHistoryDetailDescriptionTitle:SetPoint("TOPLEFT", "QuestHistoryDetailRequiredMoneyText", "BOTTOMLEFT", 0, -10);
826 elseif ( numObjectives > 0 ) then
827 QuestHistoryDetailDescriptionTitle:SetPoint("TOPLEFT", "QuestHistoryDetailObjective"..numObjectives, "BOTTOMLEFT", 0, -10);
828 else
829 QuestHistoryDetailDescriptionTitle:SetPoint("TOPLEFT", "QuestHistoryDetailObjectivesText", "BOTTOMLEFT", 0, -10);
830 end
831 -- Display the quest description
832 local questDescription = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex].d;
833 if ( not questDescription ) then
834 questDescription = "";
835 end
836 QuestHistoryDetailQuestDescription:SetText(questDescription);
837 QuestFrame_SetAsLastShown(QuestHistoryDetailQuestDescription, spacerFrame);
838 -- If there are rewards, display the reward frame which is populated from QuestHistory_Detail_Items_Update()
839 local numRewards, numChoices;
840 if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["r"] ) then
841 numRewards = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["r"]);
842 end
843 if ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["i"] ) then
844 numChoices = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questIndex]["i"]);
845 end
846 if ( not numRewards ) then
847 numRewards = 0;
848 end
849 if ( not numChoices ) then
850 numChoices = 0;
851 end
852 if ( not rewardMoney ) then
853 rewardMoney = 0;
854 end
855 if ( (numRewards + numChoices + rewardMoney) > 0 ) then
856 QuestHistoryDetailRewardTitleText:Show();
857 QuestFrame_SetAsLastShown(QuestHistoryDetailRewardTitleText, spacerFrame);
858 else
859 QuestHistoryDetailRewardTitleText:Hide();
860 end
861 QuestHistory_Detail_Items_Update(questIndex);
862 QuestHistoryDetailListScrollFrameScrollBar:SetValue(0);
863 QuestHistoryDetailListScrollFrame:UpdateScrollChildRect();
864 QuestHistoryDetailScrollFrameScrollBar:SetValue(0);
865 QuestHistoryDetailScrollFrame:UpdateScrollChildRect();
866 end
867  
868 -- Process the stored link of an item to cut out the color and name and only return the hyperlink
869 local function QuestHistory_ProcessLinks(text)
870 if ( text ) then
871 local _, _, item = string.find(text, "|c%x+|H(%w+:%d+:%d+:%d+:%d+)|h%[.-%]|h|r");
872 return item;
873 end
874 end
875  
876 -- Upgrades the data in QuestHistory_List to the latest format
877 local function QuestHistory_UpgradeData()
878 for realmIndex, realmValue in QuestHistory_List do
879 for charIndex, charValue in realmValue do
880 for questIndex, questValue in charValue do
881 for dataIndex, dataValue in QuestHistoryData do
882 local data = questValue[dataValue.old];
883 if ( data ~= nil ) then
884 if ( data ~= 0 and data ~= false and data ~= "Parchment" ) then
885 if ( dataIndex == "ta" or dataIndex == "tl" or dataIndex == "tc" ) then
886 local _, _, days = string.find(data, "(%d+):.*");
887 local _, _, hrs = string.find(data, "%d+:(%d+):.*");
888 local _, _, mins = string.find(data, "%d+:%d+:(%d+):.*");
889 local _, _, secs = string.find(data, "%d+:%d+:%d+:(%d+)");
890 if ( days == nil ) then
891 days = 0;
892 end
893 if ( hrs == nil ) then
894 hrs = 0;
895 end
896 if ( mins == nil ) then
897 mins = 0;
898 end
899 if ( secs == nil ) then
900 secs = 0;
901 end
902 questValue[dataIndex] = format(TEXT(QUESTHISTORY_TIME_FORMAT), days, hrs, mins, secs);
903 else
904 questValue[dataIndex] = data;
905 end
906 end
907 questValue[dataValue.old] = nil;
908 end
909 end
910 -- Converts location data to new format
911 if ( questValue.acceptedZone or questValue.acceptedX or questValue.acceptedY ) then
912 if ( questValue.acceptedZone and questValue.acceptedX and questValue.acceptedY ) then
913 questValue.pa = questValue.acceptedZone..":"..questValue.acceptedX..":"..questValue.acceptedY;
914 end
915 questValue.acceptedZone = nil;
916 questValue.acceptedX = nil;
917 questValue.acceptedY = nil;
918 end
919 if ( questValue.completedZone or questValue.completedX or questValue.completedY ) then
920 if ( questValue.completedZone and questValue.completedX and questValue.completedY ) then
921 questValue.pc = questValue.completedZone..":"..questValue.completedX..":"..questValue.completedY;
922 end
923 questValue.completedZone = nil;
924 questValue.completedX = nil;
925 questValue.completedY = nil;
926 end
927 -- Converts objectives status data to new format
928 if ( questValue.numObjectives ) then
929 if ( questValue.numObjectives > 0) then
930 questValue.os = { };
931 for obIndex = 1, questValue.numObjectives, 1 do
932 questValue["os"][obIndex] = { };
933 questValue["os"][obIndex].t = questValue["objective"..obIndex.."Text"];
934 questValue["os"][obIndex].f = questValue["objective"..obIndex.."Finished"];
935 questValue["objective"..obIndex.."Text"] = nil;
936 questValue["objective"..obIndex.."Finished"] = nil;
937 end
938 end
939 questValue.numObjectives = nil;
940 end
941 -- Converts reward item data to new format
942 if ( questValue.numRewards ) then
943 if ( questValue.numRewards > 0 ) then
944 questValue.r = { };
945 for rIndex = 1, questValue.numRewards, 1 do
946 questValue["r"][rIndex] = { };
947 questValue["r"][rIndex].t = questValue["reward"..rIndex.."Texture"];
948 if ( questValue["reward"..rIndex.."NumItems"] > 1 ) then
949 questValue["r"][rIndex].a = questValue["reward"..rIndex.."NumItems"];
950 end
951 questValue["r"][rIndex].l = questValue["reward"..rIndex.."ItemLink"];
952 questValue["reward"..rIndex.."Name"] = nil;
953 questValue["reward"..rIndex.."Texture"] = nil;
954 questValue["reward"..rIndex.."NumItems"] = nil;
955 questValue["reward"..rIndex.."IsUsable"] = nil;
956 questValue["reward"..rIndex.."ItemLink"] = nil;
957 end
958 end
959 questValue.numRewards = nil;
960 end
961 -- Converts choice item data to new format
962 if ( questValue.numChoices ) then
963 if ( questValue.numChoices > 0 ) then
964 questValue.i = { };
965 for iIndex = 1, questValue.numChoices, 1 do
966 questValue["i"][iIndex] = { };
967 questValue["i"][iIndex].t = questValue["choice"..iIndex.."Texture"];
968 if ( questValue["choice"..iIndex.."NumItems"] > 1 ) then
969 questValue["i"][iIndex].a = questValue["choice"..iIndex.."NumItems"];
970 end
971 questValue["i"][iIndex].l = questValue["choice"..iIndex.."ItemLink"];
972 questValue["choice"..iIndex.."Name"] = nil;
973 questValue["choice"..iIndex.."Texture"] = nil;
974 questValue["choice"..iIndex.."NumItems"] = nil;
975 questValue["choice"..iIndex.."IsUsable"] = nil;
976 questValue["choice"..iIndex.."ItemLink"] = nil;
977 end
978 end
979 questValue.numChoices = nil;
980 end
981 -- Converts spell reward data to new format
982 if ( questValue.numSpells ) then
983 if ( questValue.numSpells > 0 ) then
984 questValue.s = { };
985 questValue["s"].t = questValue.spellTexture;
986 questValue["s"].n = questValue.spellName;
987 end
988 questValue.numSpells = nil;
989 questValue.spellTexture = nil;
990 questValue.spellName = nil;
991 questValue.spellItemLink = nil;
992 end
993 if ( questValue.backgroundMaterial ) then
994 if ( questValue.backgroundMaterial ~= "" and questValue.backgroundMaterial ~= "Parchment" ) then
995 questValue.bg = questValue.backgroundMaterial;
996 end
997 questValue.backgroundMaterial = nil;
998 end
999 if ( questValue.NPCQuestGiver ) then
1000 if ( questValue.NPCQuestGiver ~= "" ) then
1001 questValue.g = questValue.NPCQuestGiver;
1002 end
1003 questValue.NPCQuestGiver = nil;
1004 end
1005 end
1006 end
1007 end
1008 end
1009  
1010 -- Purges unwanted data from logged quests
1011 local function QuestHistory_PurgeData()
1012 for index, value in QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName] do
1013 for i, v in QuestHistoryFlags do
1014 if ( not v.status ) then
1015 if ( v.data == "la" ) then
1016 value.la = nil;
1017 value.ll = nil;
1018 elseif ( v.data == "ta" ) then
1019 value.ta = nil;
1020 value.tl = nil;
1021 elseif ( v.data ) then
1022 value[v.data] = nil;
1023 end
1024 end
1025 end
1026 end
1027 QuestHistory_Refresh();
1028 end
1029  
1030 -- Edits a quest in the player's history
1031 local function QuestHistory_EditQuest(questID)
1032 for index, value in QuestHistoryData do
1033 if ( value.box ) then
1034 local data = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questID][index];
1035 if ( data == nil ) then
1036 getglobal("QuestHistoryEdit"..value.box.."EditBox"):SetText("");
1037 else
1038 getglobal("QuestHistoryEdit"..value.box.."EditBox"):SetText(data);
1039 end
1040 end
1041 end
1042 QuestHistoryEditAcceptedOrderEditBox:SetText(questID);
1043 local location = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questID].pa;
1044 if ( location ) then
1045 local _, _, zone = string.find(location, "(.-):.*:.*");
1046 local _, _, x = string.find(location, ".-:(.-):.*");
1047 local _, _, y = string.find(location, ".-:.-:(.*)");
1048 QuestHistoryEditAcceptedZoneEditBox:SetText(zone);
1049 QuestHistoryEditAcceptedXEditBox:SetText(x * 100);
1050 QuestHistoryEditAcceptedYEditBox:SetText(y * 100);
1051 end
1052 location = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questID].pc;
1053 if ( location ) then
1054 local _, _, zone = string.find(location, "(.-):.*:.*");
1055 local _, _, x = string.find(location, ".-:(.-):.*");
1056 local _, _, y = string.find(location, ".-:.-:(.*)");
1057 QuestHistoryEditCompletedZoneEditBox:SetText(zone);
1058 QuestHistoryEditCompletedXEditBox:SetText(x * 100);
1059 QuestHistoryEditCompletedYEditBox:SetText(y * 100);
1060 end
1061 end
1062  
1063 -- Loads the text from the EditFrame and stores it in data
1064 local function QuestHistory_GetEditData()
1065 local data = { };
1066 local questID;
1067 for index, value in QuestHistoryData do
1068 if ( value.box ) then
1069 if ( value.type == "string" ) then
1070 data[index] = getglobal("QuestHistoryEdit"..value.box.."EditBox"):GetText();
1071 elseif ( value.type == "number" ) then
1072 _, _, data[index] = string.find(getglobal("QuestHistoryEdit"..value.box.."EditBox"):GetText(), "(%d+)");
1073 if ( data[index] ~= nil ) then
1074 data[index] = tonumber(data[index]);
1075 else
1076 data[index] = "";
1077 end
1078 end
1079 end
1080 end
1081 _, _, questID = string.find(QuestHistoryEditAcceptedOrderEditBox:GetText(), "(%d+)");
1082 if ( questID == nil ) then
1083 questID = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName]) + 1;
1084 elseif ( questID == "0" ) then
1085 questID = 1;
1086 else
1087 questID = tonumber( questID );
1088 end
1089 local zone, x, y;
1090 zone = QuestHistoryEditAcceptedZoneEditBox:GetText();
1091 _, _, x = string.find(QuestHistoryEditAcceptedXEditBox:GetText(), "(%d+%.?%d*)");
1092 _, _, y = string.find(QuestHistoryEditAcceptedYEditBox:GetText(), "(%d+%.?%d*)");
1093 if ( x ) then
1094 x = tonumber(x) / 100;
1095 if ( x < 0 ) then
1096 x = 0;
1097 elseif ( x > 1 ) then
1098 x = 1;
1099 end
1100 else
1101 x = nil;
1102 end
1103 if ( y ) then
1104 y = tonumber(y) / 100;
1105 if ( y < 0 ) then
1106 y = 0;
1107 elseif ( y > 1 ) then
1108 y = 1;
1109 end
1110 else
1111 y = nil;
1112 end
1113 if ( zone and x and y ) then
1114 data.pa = zone..":"..x..":"..y;
1115 end
1116 zone = QuestHistoryEditCompletedZoneEditBox:GetText();
1117 _, _, x = string.find(QuestHistoryEditCompletedXEditBox:GetText(), "(%d+%.?%d*)");
1118 _, _, y = string.find(QuestHistoryEditCompletedYEditBox:GetText(), "(%d+%.?%d*)");
1119 if ( x ) then
1120 x = tonumber(x) / 100;
1121 if ( x < 0 ) then
1122 x = 0;
1123 elseif ( x > 1 ) then
1124 x = 1;
1125 end
1126 else
1127 x = nil;
1128 end
1129 if ( y ) then
1130 y = tonumber(y) / 100;
1131 if ( y < 0 ) then
1132 y = 0;
1133 elseif ( y > 1 ) then
1134 y = 1;
1135 end
1136 else
1137 y = nil;
1138 end
1139 if ( zone and x and y ) then
1140 data.pc = zone..":"..x..":"..y;
1141 end
1142 return data, questID;
1143 end
1144  
1145 -- Removes a quest from the displayed player's history
1146 local function QuestHistory_DeleteQuest(questID, realm, character)
1147 if ( not realm ) then
1148 realm = DisplayedRealmName;
1149 end
1150 if ( not character ) then
1151 character = DisplayedPlayerCharacterName;
1152 end
1153 local completed = QuestHistory_List[realm][character][questID].co;
1154 if ( completed ) then
1155 for index, value in QuestHistory_List[realm][character] do
1156 if ( value.co and ( value.co > completed ) ) then
1157 value.co = value.co - 1;
1158 end
1159 end
1160 end
1161 table.remove(QuestHistory_List[realm][character], questID);
1162 end
1163  
1164 -- Repairs quest data
1165 local function QuestHistory_RepairData() -- BEGIN EMERALD FIX
1166  
1167 local playerName = UnitName("player");
1168 local repairCount = 0;
1169  
1170 --EMERALD: Kill bad entries before scanning for dupes
1171 for realmIndex, realmValue in QuestHistory_List do
1172 for charIndex, charValue in realmValue do
1173 for questIndex, questValue in charValue do
1174 if (string.find(questValue.d,UNKNOWNOBJECT)) then
1175 if (DEFAULT_CHAT_FRAME) then
1176 DEFAULT_CHAT_FRAME:AddMessage("Removing #"..questIndex.." \""..questValue.t.."\" (BadEntry) from "..charIndex..".");
1177 end
1178 QuestHistory_DeleteQuest(questIndex, realmIndex, charIndex);
1179 questIndex = questIndex - 1;
1180 repairCount = repairCount + 1;
1181 end
1182 end
1183 end
1184 end
1185  
1186 for realmIndex, realmValue in QuestHistory_List do
1187 for charIndex, charValue in realmValue do
1188 for questIndex, questValue in charValue do
1189 if ( QuestHistoryFlags["removePortQuests"].status and ( questValue.t == "Port to Auberdine" or questValue.t == "Port to Menethil" ) ) then
1190 if (DEFAULT_CHAT_FRAME) then
1191 DEFAULT_CHAT_FRAME:AddMessage("Removing #"..questIndex.." \""..questValue.t.."\" (Port) from "..charIndex..".");
1192 end
1193 QuestHistory_DeleteQuest(questIndex, realmIndex, charIndex);
1194 questIndex = questIndex - 1;
1195 repairCount = repairCount + 1;
1196 else
1197 if ( QuestHistoryFlags["removeDuplicates"].status ) then
1198 local offset = 0;
1199 for index = questIndex + 1, getn(charValue), 1 do
1200  
1201 -- EMERALD: Add checks here
1202 charValue[index - offset].d = string.gsub(charValue[index - offset].d,UNKNOWNOBJECT,charIndex);
1203 questValue.d = string.gsub(questValue.d,UNKNOWNOBJECT,charIndex);
1204  
1205 if ( charValue[index - offset].d == questValue.d and charValue[index - offset].t == questValue.t and index - offset ~= questIndex ) then
1206 if (DEFAULT_CHAT_FRAME) then
1207 DEFAULT_CHAT_FRAME:AddMessage("Removing #"..index.." \""..questValue.t.."\" (Duplicate) from "..charIndex..".");
1208 end
1209 QuestHistory_DeleteQuest(index - offset, realmIndex, charIndex);
1210 offset = offset + 1;
1211 repairCount = repairCount + 1;
1212 end
1213 end
1214 end -- END EMERALD FIX
1215 for dataIndex, dataValue in questValue do
1216 if ( QuestHistoryData[dataIndex] ) then
1217 local type = QuestHistoryData[dataIndex].type;
1218 if ( type == "number" ) then
1219 dataValue = tonumber(dataValue);
1220 if ( dataValue == 0 ) then
1221 dataValue = nil;
1222 end
1223 elseif ( type == "string" ) then
1224 dataValue = tostring(dataValue);
1225 if ( dataValue == "" ) then
1226 dataValue = nil;
1227 end
1228 elseif ( type == "item" ) then
1229 if ( dataValue.a == 1 ) then
1230 dataValue.a = nil;
1231 end
1232 elseif ( type == "objective" ) then
1233 if ( dataValue.f ~= 1 ) then
1234 dataValue.f = nil;
1235 end
1236 end
1237 elseif ( DEFAULT_CHAT_FRAME ) then
1238 DEFAULT_CHAT_FRAME:AddMessage("Cannot find "..dataIndex.." in QuestHistoryData.");
1239 end
1240 end
1241 end
1242 end
1243 end
1244 end
1245 QuestHistory_Refresh();
1246 DEFAULT_CHAT_FRAME:AddMessage("Repair finished. Removed "..repairCount.." entries.");
1247 end
1248  
1249 -- Reorders the quests in the displayed player's history
1250 local function QuestHistory_ReorderQuests(oldQuestID, newQuestID)
1251 local temp = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][oldQuestID];
1252 if ( oldQuestID < newQuestID ) then
1253 newQuestID = newQuestID + 1;
1254 else
1255 oldQuestID = oldQuestID + 1;
1256 end
1257 table.insert(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName], newQuestID, temp);
1258 table.remove(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName], oldQuestID);
1259 end
1260  
1261 -- Reorders the completed status in the displayed player's history
1262 local function QuestHistory_ReorderCompleted(old, new)
1263 local highest = 0;
1264 for index, value in QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName] do
1265 if ( value.co and highest < value.co ) then
1266 -- Store the highest value of the last completed quest
1267 highest = value.co;
1268 end
1269 end
1270 if ( new and new < 1 ) then
1271 new = highest + 1;
1272 end
1273 if ( old ) then
1274 if ( new ) then
1275 if ( new < old ) then
1276 -- Increment completed status of quests between new and old - 1
1277 for index, value in QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName] do
1278 if ( value.co and value.co >= new and value.co <= old - 1 ) then
1279 value.co = value.co + 1;
1280 end
1281 end
1282 else
1283 if ( new > highest ) then
1284 new = highest;
1285 end
1286 -- Decrement completed status of quests between old + 1 and new
1287 for index, value in QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName] do
1288 if ( value.co and value.co >= old + 1 and value.co <= new ) then
1289 value.co = value.co - 1;
1290 end
1291 end
1292 end
1293 else
1294 -- Decrement completed status of quests >= old + 1
1295 for index, value in QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName] do
1296 if ( value.co and value.co >= old + 1 ) then
1297 value.co = value.co - 1;
1298 end
1299 end
1300 end
1301 else
1302 if ( new ) then
1303 if ( new > highest ) then
1304 new = highest + 1;
1305 else
1306 -- Increment completed status of quests >= new
1307 for index, value in QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName] do
1308 if ( value.co and value.co >= new ) then
1309 value.co = value.co + 1;
1310 end
1311 end
1312 end
1313 else
1314 new = nil;
1315 end
1316 end
1317 return new;
1318 end
1319  
1320 -- Selects currently logged-in character as the currently displayed character
1321 local function QuestHistory_SelectCurrentCharacter()
1322 local i = 0;
1323 for realmIndex, realmValue in QuestHistory_List do
1324 i = i + 1;
1325 for charIndex, charValue in realmValue do
1326 i = i + 1;
1327 if ( ( realmIndex == RealmName ) and ( charIndex == PlayerCharacterName ) ) then
1328 UIDropDownMenu_SetSelectedID(QuestHistoryOptionsFrameCharacterDropDown, i );
1329 break;
1330 end
1331 end
1332 if ( realmIndex == RealmName ) then
1333 break;
1334 end
1335 end
1336 end
1337  
1338 -- Deletes currently displayed character's data from QuestHistory_List
1339 local function QuestHistory_DeleteCharacter()
1340 if ( RealmName ~= DisplayedRealmName or PlayerCharacterName ~= DisplayedPlayerCharacterName ) then
1341 local i = 0;
1342 QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName] = nil;
1343 for charIndex, charValue in QuestHistory_List[DisplayedRealmName] do
1344 i = i + 1;
1345 end
1346 if ( i == 0 ) then
1347 QuestHistory_List[DisplayedRealmName] = nil;
1348 end
1349 QuestHistory_SelectCurrentCharacter();
1350 UIDropDownMenu_SetText(PlayerCharacterName, QuestHistoryOptionsFrameCharacterDropDown);
1351 DisplayedRealmName = RealmName;
1352 DisplayedPlayerCharacterName = PlayerCharacterName;
1353 QuestHistory_Refresh();
1354 end
1355 end
1356  
1357 -- Loads a hexadecimal value from QuestHistory_Flags if it exists and sets the flags accordingly
1358 local function QuestHistory_LoadFlags()
1359 local sVal = QuestHistory_Flags;
1360 if ( sVal ) then
1361 local decVal = tonumber(sVal, 16);
1362 local flag;
1363 local numIndices = 0;
1364 for index, value in QuestHistoryFlags do
1365 numIndices = numIndices + 1;
1366 end
1367 for i = 1, numIndices, 1 do
1368 if ( math.mod(decVal, 2) == 0 ) then
1369 flag = false;
1370 else
1371 flag = true;
1372 end
1373 for index, value in QuestHistoryFlags do
1374 if ( value.index == i ) then
1375 value.status = flag;
1376 break;
1377 end
1378 end
1379 decVal = floor(decVal / 2);
1380 end
1381 end
1382 end
1383  
1384 -- Saves the flags as a hexadecimal value in QuestHistory_Flags
1385 local function QuestHistory_SaveFlags()
1386 local val = 0;
1387 for index, value in QuestHistoryFlags do
1388 if ( value.status ) then
1389 val = val + 2 ^ (value.index - 1);
1390 end
1391 end
1392 QuestHistory_Flags = string.format("%X", val).."";
1393 end
1394  
1395 local function QuestHistory_LogCurrentQuests() -- BEGIN EMERALD FIX
1396  
1397 local questCategory = "";
1398 local playerName = UnitName("player");
1399  
1400 -- Cycle through the quests currently in the quest log
1401 for i = 1, GetNumQuestLogEntries(), 1 do
1402 local qTitle, qLevel, qTag, isHeader = GetQuestLogTitle(i);
1403 -- Check if quest title is a header
1404 if ( qTitle ) then -- EMERALD: Thanks, Asjaskan
1405 qTitle = string.gsub(string.gsub(qTitle,'^[[].*[]]',''),'^ ','');
1406 end
1407 if ( not isHeader ) then
1408 -- Not a header, so log information for this quest
1409 local questID;
1410 -- Select the quest
1411 SelectQuestLogEntry(i);
1412 -- Get the description and objectives of quest
1413 local qDescription, qObjectives = GetQuestLogQuestText();
1414 -- Find quest in QuestHistory_List if it has been logged already
1415 for index, value in QuestHistory_List[RealmName][PlayerCharacterName] do
1416 -- Compare descriptions if one has been logged
1417 if ( value.d ) then
1418 qDescription = string.gsub(qDescription,UNKNOWNOBJECT,playerName);
1419 value.d = string.gsub(value.d,UNKNOWNOBJECT,playerName);
1420 if ( qDescription == value.d ) then
1421 questID = index;
1422 -- Break out of for loop if quest has been found
1423 break;
1424 end -- END EMERALD FIX
1425 -- Otherwise, compare titles but don't break out until all quest descriptions have been checked
1426 elseif ( value.t ) then
1427 if ( qTitle == value.t and not value.co ) then
1428 questID = index;
1429 end
1430 end
1431 end
1432 -- Check if it is a new quest that hasn't been logged yet
1433 if ( not questID ) then
1434 -- Assign questID to be 1 more than the player's current number of logged quests
1435 questID = getn(QuestHistory_List[RealmName][PlayerCharacterName]) + 1;
1436 -- Create blank table to store quest data
1437 table.insert(QuestHistory_List[RealmName][PlayerCharacterName], { });
1438 -- Record quest title
1439 QuestHistory_List[RealmName][PlayerCharacterName][questID].t = qTitle;
1440 -- Record quest level if doing so
1441 if ( QuestHistoryFlags["logLevel"].status ) then
1442 QuestHistory_List[RealmName][PlayerCharacterName][questID].l = qLevel;
1443 end
1444 -- Record quest tag if doing so
1445 if ( QuestHistoryFlags["logTag"].status ) then
1446 QuestHistory_List[RealmName][PlayerCharacterName][questID].y = qTag;
1447 end
1448 -- Record quest location if doing so
1449 if ( QuestHistoryFlags["logCategory"].status ) then
1450 QuestHistory_List[RealmName][PlayerCharacterName][questID].c = questCategory;
1451 end
1452 -- Record quest description if doing so
1453 if ( QuestHistoryFlags["logDescription"].status ) then
1454 QuestHistory_List[RealmName][PlayerCharacterName][questID].d = qDescription;
1455 end
1456 -- Record quest objectives if doing so
1457 if ( QuestHistoryFlags["logObjectives"].status ) then
1458 QuestHistory_List[RealmName][PlayerCharacterName][questID].o = qObjectives;
1459 end
1460 -- Record objectives status if doing so
1461 if ( QuestHistoryFlags["logObjectivesStatus"].status ) then
1462 local nObjectives = GetNumQuestLeaderBoards();
1463 if ( nObjectives and ( nObjectives > 0 ) ) then
1464 -- Create blank table to store quest objectives status
1465 QuestHistory_List[RealmName][PlayerCharacterName][questID].os = { };
1466 for j = 1, nObjectives, 1 do
1467 -- Create blank table for this objective
1468 QuestHistory_List[RealmName][PlayerCharacterName][questID]["os"][j] = { };
1469 end
1470 end
1471 end
1472 -- Record player's level when quest was accepted/logged if doing so
1473 if ( QuestHistoryFlags["logLevelAccepted"].status ) then
1474 if ( questHasBeenRecentlyAccepted ) then
1475 QuestHistory_List[RealmName][PlayerCharacterName][questID].la = UnitLevel("player");
1476 else
1477 QuestHistory_List[RealmName][PlayerCharacterName][questID].ll = UnitLevel("player");
1478 end
1479 end
1480 -- Record played time when quest was accepted/logged if doing so
1481 if ( QuestHistoryFlags["logTimeAccepted"].status ) then
1482 if ( questHasBeenRecentlyAccepted ) then
1483 QuestHistory_List[RealmName][PlayerCharacterName][questID].ta = timeText;
1484 else
1485 QuestHistory_List[RealmName][PlayerCharacterName][questID].tl = timeText;
1486 end
1487 end
1488 -- Record required money if doing so
1489 if ( QuestHistoryFlags["logRequiredMoney"].status ) then
1490 local reqMoney = GetQuestLogRequiredMoney();
1491 if ( reqMoney and ( reqMoney > 0 ) ) then
1492 QuestHistory_List[RealmName][PlayerCharacterName][questID].rm = reqMoney;
1493 end
1494 end
1495 -- Record quest rewards if doing so
1496 if ( QuestHistoryFlags["logRewards"].status ) then
1497 local nRewards = GetNumQuestLogRewards();
1498 if ( nRewards and ( nRewards > 0 ) ) then
1499 -- Create blank table to store reward info
1500 QuestHistory_List[RealmName][PlayerCharacterName][questID].r = { };
1501 -- Cycle through number of quest rewards
1502 for j = 1, nRewards, 1 do
1503 -- Create blank table for this reward
1504 QuestHistory_List[RealmName][PlayerCharacterName][questID]["r"][j] = { };
1505 -- Get data for quest reward
1506 local rName, rTexture, rNumItems, rQuality, rIsUsable = GetQuestLogRewardInfo(j);
1507 -- Record data for quest reward
1508 QuestHistory_List[RealmName][PlayerCharacterName][questID]["r"][j].t = rTexture;
1509 if ( rNumItems > 1 ) then
1510 QuestHistory_List[RealmName][PlayerCharacterName][questID]["r"][j].a = rNumItems;
1511 end
1512 QuestHistory_List[RealmName][PlayerCharacterName][questID]["r"][j].l = GetQuestLogItemLink("reward", j);
1513 end
1514 end
1515 end
1516 -- Record quest choices if doing so
1517 if ( QuestHistoryFlags["logChoices"].status ) then
1518 local nChoices = GetNumQuestLogChoices();
1519 if ( nChoices and ( nChoices > 0 ) ) then
1520 -- Create blank table to store choice info
1521 QuestHistory_List[RealmName][PlayerCharacterName][questID].i = { };
1522 -- Cycle through number of quest choices
1523 for j = 1, nChoices, 1 do
1524 -- Create blank table for this choice
1525 QuestHistory_List[RealmName][PlayerCharacterName][questID]["i"][j] = { };
1526 -- Get data for quest choice
1527 local cName, cTexture, cNumItems, cQuality, cIsUsable = GetQuestLogChoiceInfo(j);
1528 -- Record data for quest choice
1529 QuestHistory_List[RealmName][PlayerCharacterName][questID]["i"][j].t = cTexture;
1530 if ( cNumItems > 1 ) then
1531 QuestHistory_List[RealmName][PlayerCharacterName][questID]["i"][j].a = cNumItems;
1532 end
1533 QuestHistory_List[RealmName][PlayerCharacterName][questID]["i"][j].l = GetQuestLogItemLink("choice", j);
1534 end
1535 end
1536 end
1537 -- Record quest spells if doing so
1538 if ( QuestHistoryFlags["logSpells"].status ) then
1539 if ( GetQuestLogRewardSpell() ) then
1540 -- Create blank table to store spell info
1541 QuestHistory_List[RealmName][PlayerCharacterName][questID].s = { };
1542 -- Get data for spell reward
1543 local sTexture, sName = GetQuestLogRewardSpell();
1544 -- Record data for spell reward
1545 QuestHistory_List[RealmName][PlayerCharacterName][questID]["s"].t = sTexture;
1546 QuestHistory_List[RealmName][PlayerCharacterName][questID]["s"].n = sName;
1547 end
1548 end
1549 -- Record reward money if doing so
1550 if ( QuestHistoryFlags["logRewardMoney"].status ) then
1551 local rewMoney = GetQuestLogRewardMoney();
1552 if ( rewMoney and ( rewMoney > 0 ) ) then
1553 QuestHistory_List[RealmName][PlayerCharacterName][questID].m = rewMoney;
1554 end
1555 end
1556 -- Record background material if doing so
1557 if ( QuestHistoryFlags["logBackgroundMaterial"].status ) then
1558 local material = GetQuestBackgroundMaterial();
1559 if ( material ~= "Parchment" ) then
1560 QuestHistory_List[RealmName][PlayerCharacterName][questID].bg = material;
1561 end
1562 end
1563 -- Record accepted location if doing so
1564 if ( QuestHistoryFlags["logAcceptedLocation"].status ) then
1565 QuestHistory_List[RealmName][PlayerCharacterName][questID].pa = recentlyAcceptedLocation;
1566 recentlyAcceptedLocation = nil;
1567 end
1568 -- Record quest giver if doing so
1569 if ( QuestHistoryFlags["logQuestGiver"].status ) then
1570 QuestHistory_List[RealmName][PlayerCharacterName][questID].g = recentNPCQuestGiver;
1571 recentNPCQuestGiver = nil;
1572 end
1573 -- Check if recently accepted quest has been logged
1574 if ( questHasBeenRecentlyAccepted ) then
1575 -- Reset accepted flag
1576 questHasBeenRecentlyAccepted = nil;
1577 -- Break out of for loop since the quest most recently accepted has been logged
1578 break;
1579 end
1580 else
1581 -- Check if quest is failed
1582 if ( IsCurrentQuestFailed() ) then
1583 if ( not QuestHistory_List[RealmName][PlayerCharacterName][questID].f ) then
1584 QuestHistory_List[RealmName][PlayerCharacterName][questID].f = true;
1585 if ( not QuestHistory_List[RealmName][PlayerCharacterName][questID].fc ) then
1586 QuestHistory_List[RealmName][PlayerCharacterName][questID].fc = 1;
1587 else
1588 QuestHistory_List[RealmName][PlayerCharacterName][questID].fc = QuestHistory_List[RealmName][PlayerCharacterName][questID].fc + 1;
1589 end
1590 end
1591 else
1592 -- Mark quest as not failed
1593 QuestHistory_List[RealmName][PlayerCharacterName][questID].f = nil;
1594 end
1595 -- Make sure quest is not marked abandoned since it is currently in the quest log
1596 QuestHistory_List[RealmName][PlayerCharacterName][questID].a = nil;
1597 end
1598 -- Record quest objectives progress if doing so
1599 if ( QuestHistoryFlags["logObjectivesStatus"].status ) then
1600 if ( QuestHistory_List[RealmName][PlayerCharacterName][questID].os ) then
1601 local numObjectives = getn(QuestHistory_List[RealmName][PlayerCharacterName][questID]["os"]);
1602 for j = 1, numObjectives, 1 do
1603 local oText, oType, oFinished = GetQuestLogLeaderBoard(j);
1604 if ( not oText or strlen(oText) == 0 ) then
1605 oText = oType;
1606 end
1607 -- Check if quest objective has been finished
1608 if ( not oFinished or not QuestHistory_List[RealmName][PlayerCharacterName][questID]["os"][j].f ) then
1609 -- Update progress of objective
1610 QuestHistory_List[RealmName][PlayerCharacterName][questID]["os"][j].t = oText;
1611 QuestHistory_List[RealmName][PlayerCharacterName][questID]["os"][j].f = oFinished;
1612 end
1613 end
1614 end
1615 end
1616 else
1617 -- Store header title as the zone location for the next quest
1618 questCategory = qTitle;
1619 end
1620 end
1621 -- Reset timer to disallow this function from being run again too soon
1622 timeSinceLastLog = 0;
1623 allowLogging = false;
1624  
1625 if ( QuestHistoryFrame:IsVisible() ) then
1626 QuestHistory_Refresh();
1627 end
1628 end
1629  
1630 ----------------------------------------------------------------------------------------------------
1631 -- On_Foo Functions
1632 ----------------------------------------------------------------------------------------------------
1633  
1634 function QuestHistory_OnLoad()
1635 -- Register events for QuestHistoryFrame
1636 this:RegisterEvent("PLAYER_LOGIN");
1637 this:RegisterEvent("ADDON_LOADED");
1638 this:RegisterEvent("VARIABLES_LOADED");
1639 this:RegisterEvent("ADDON_LOADED");
1640 this:RegisterEvent("QUEST_LOG_UPDATE");
1641 this:RegisterEvent("TIME_PLAYED_MSG");
1642 this:RegisterEvent("PLAYER_ENTERING_WORLD");
1643 this:RegisterEvent("PLAYER_ALIVE");
1644 this:RegisterEvent("PLAYER_UNGHOST");
1645 -- Set up slash commands
1646 SLASH_QUESTHISTORY1 = "/questhistory";
1647 SLASH_QUESTHISTORY2 = "/qh";
1648 SlashCmdList["QUESTHISTORY"] = function(msg)
1649 QuestHistory_SlashCommandHandler(msg);
1650 end
1651 -- Hook the QuestDetailAcceptButton_OnClick function
1652 originalQuestDetailAcceptButton_OnClick = QuestDetailAcceptButton_OnClick;
1653 QuestDetailAcceptButton_OnClick = QuestHistory_QuestDetailAcceptButton_OnClick;
1654 -- Hook the QuestRewardCompleteButton_OnClick function
1655 originalQuestRewardCompleteButton_OnClick = QuestRewardCompleteButton_OnClick;
1656 QuestRewardCompleteButton_OnClick = QuestHistory_QuestRewardCompleteButton_OnClick;
1657 -- Hook the AbandonQuest function
1658 originalAbandonQuest = AbandonQuest;
1659 AbandonQuest = QuestHistory_AbandonQuest;
1660 -- Hook the ChatFrame_DisplayTimePlayed function
1661 originalChatFrame_DisplayTimePlayed = ChatFrame_DisplayTimePlayed;
1662 ChatFrame_DisplayTimePlayed = QuestHistory_ChatFrame_DisplayTimePlayed;
1663 -- Hook quest window open (v2.8)
1664 originalQuest_Save = QuestFrameGreetingPanel_OnShow;
1665 QuestFrameGreetingPanel_OnShow = QuestHistory_QuestFrameGreetingPanel_OnShow;
1666 -- Display a message in the ChatFrame indicating a successful load of this addon
1667 if ( DEFAULT_CHAT_FRAME ) then
1668 DEFAULT_CHAT_FRAME:AddMessage(format(QUESTHISTORY_LOAD_TEXT, QUESTHISTORY_VERSION));
1669 end
1670 -- Display a popup message indicating a successful load of this addon
1671 UIErrorsFrame:AddMessage(format(QUESTHISTORY_LOAD_TEXT, QUESTHISTORY_VERSION), 1.0, 1.0, 1.0, 1.0, UIERRORS_HOLD_TIME);
1672 end
1673  
1674 -- Handle quest window open (v2.8)
1675 function QuestHistory_QuestFrameGreetingPanel_OnShow()
1676 originalQuest_Save();
1677 if (QuestHistory_Options["levels"]) then -- only if enabled
1678 local actQ, availQ = GetNumActiveQuests(), GetNumAvailableQuests();
1679 if (actQ + availQ == 0) then return; end
1680 local title, level, button;
1681 local o, GetTitle, GetLevel = 0, GetActiveTitle, GetActiveLevel;
1682 for i = 1, actQ + availQ do
1683 if(i == actQ + 1) then
1684 o, GetTitle, GetLevel = actQ, GetAvailableTitle, GetAvailableLevel;
1685 end
1686 title, level = GetTitle(i-o), GetLevel(i-o);
1687 button = getglobal("QuestTitleButton"..i);
1688 button:SetText(format('[%d] %s', level, title));
1689 end
1690 end
1691 end
1692  
1693 function QuestHistory_DelayedConfigInit_OnUpdate(elapsed)
1694 if (QuestHistory_DelayedConfigInit) then
1695 QuestHistory_DelayedLoginFired = true; -- This will prevent recurring delays
1696 QuestHistory_DelayedConfigInit = QuestHistory_DelayedConfigInit - elapsed;
1697 if (QuestHistory_DelayedConfigInit <= 0) then
1698 QuestHistory_LogCurrentQuests();
1699 QuestHistory_DelayedConfigInit = nil;
1700 QuestHistoryDelayedFrame:Hide();
1701 end
1702 else -- Stop receiving OnUpdates
1703 QuestHistoryDelayedFrame:Hide();
1704 end
1705 end
1706  
1707 function QuestHistory_OnEvent(event)
1708  
1709 if ( event == "PLAYER_LOGIN" ) then
1710 if (not QuestHistory_Loaded) then
1711  
1712 if (MapNotes_Options) then -- Set to either MapNotes or MetaMapNotes
1713 QHMN_ZoneNames = MapNotes_ZoneNames;
1714 QHMN_Data = MapNotes_Data;
1715 QHMN_SetNextAsMiniNote = MapNotes_SetNextAsMiniNote;
1716 QHMN_GetNoteBySlashCommand = MapNotes_GetNoteBySlashCommand;
1717 elseif (MetaMapNotes_Options) then
1718 QHMN_ZoneNames = MetaMapNotes_ZoneNames;
1719 QHMN_Data = MetaMapNotes_Data;
1720 QHMN_SetNextAsMiniNote = MetaMapNotes_SetNextAsMiniNote;
1721 QHMN_GetNoteBySlashCommand = MetaMapNotes_GetNoteBySlashCommand;
1722 end
1723  
1724 PlayerCharacterName = UnitName("player");
1725 DisplayedPlayerCharacterName = PlayerCharacterName;
1726 RealmName = GetCVar("realmName");
1727 DisplayedRealmName = RealmName;
1728 if (not QuestHistory_List) then QuestHistory_List = {}; end
1729 if (not QuestHistory_List[RealmName]) then
1730 QuestHistory_List[RealmName] = {};
1731 end
1732 if ( not QuestHistory_List[RealmName][PlayerCharacterName] ) then
1733 QuestHistory_List[RealmName][PlayerCharacterName] = {};
1734 end
1735 -- Upgrade the data to latest format
1736 QuestHistory_UpgradeData();
1737 -- Load the logging and displaying flags
1738 QuestHistory_LoadFlags();
1739 -- Load the colors of abandoned and completed quests
1740 if ( QuestHistory_StatusColors ) then
1741 for index, value in QuestHistory_StatusColors do
1742 QuestHistoryStatusColor[index] = value;
1743 end
1744 end
1745 -- Records the played time to use for quests accepted before this addon was installed if doing so
1746 if ( QuestHistoryFlags["logTimeAccepted"].status ) then
1747 timeEvent = "Logged";
1748 RequestTimePlayed();
1749 end
1750 if ( allowLogging ) then
1751 if (not QuestHistory_DelayedLoginFired) then
1752 QuestHistory_DelayedConfigInit = 10; -- EMERALD (thanks to UberQuest)
1753 QuestHistoryDelayedFrame:Show();
1754 else -- If QuestHistory_DelayedLoginFired, then we've done the login delay. No more long delays!
1755 QuestHistory_DelayedConfigInit = 1;
1756 QuestHistoryDelayedFrame:Show();
1757 end
1758 end
1759  
1760 if (not QuestHistory_Options) then
1761 QuestHistory_Options = {
1762 ["levels"] = true, -- on by default
1763 };
1764 elseif (QuestHistory_Options["levels"]==nil) then
1765 QuestHistory_Options["levels"] = true; -- on by default
1766 end
1767  
1768 QuestHistory_Loaded = true;
1769 end
1770  
1771 elseif ( event == "PLAYER_ENTERING_WORLD" or event == "PLAYER_ALIVE" or event == "PLAYER_UNGHOST" ) then
1772 local playerX, playerY = GetPlayerMapPosition("player");
1773 -- EMERALD: New attempt to prevent the Blizzard 0,0 bug -- doing so before the quest events happen, not during
1774 if (playerX==0 and playerY==0) then
1775 ShowUIPanel(WorldMapFrame);
1776 HideUIPanel(WorldMapFrame);
1777 end
1778  
1779 elseif ( event == "QUEST_LOG_UPDATE" and QuestHistory_Loaded ) then
1780 -- Following condition needed to make sure player name has been assigned
1781 if ( PlayerCharacterName ) then
1782 -- Check if a quest has been recently completed
1783 if ( recentlyCompletedQuestID ) then
1784 -- If so and XP logging is enabled, log the XP that was gained.
1785 -- Needed here because the player's XP is not actually increased
1786 -- until some time after the CompleteQuest() function is run
1787 if ( QuestHistoryFlags["logXPReward"].status ) then
1788 local newXP = UnitXP("player") - XPBeforeQuestCompletion;
1789 -- Check if XP has been updated after quest
1790 if ( newXP ~= 0 ) then
1791 -- Check if XP now is less than XP before quest was completed
1792 if ( newXP < 0 ) then
1793 -- If so, player leveled so add the previous max XP recorded to get correct value of XP gained
1794 newXP = newXP + XPMaxBeforeQuestCompletion;
1795 end
1796 -- Log the XP Reward
1797 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].x = newXP;
1798 -- Reset variable values
1799 XPBeforeQuestCompletion = 0;
1800 XPMaxBeforeQuestCompletion = 0;
1801 recentlyCompletedQuestID = nil;
1802 end
1803 else
1804 -- If XP logging is not enabled, just reset recentlyCompletedQuestID
1805 recentlyCompletedQuestID = nil;
1806 end
1807 end
1808 -- Check if a quest has been recently abandoned
1809 if ( questHasBeenRecentlyAbandoned ) then
1810 -- Just reset the recently abandoned flag
1811 questHasBeenRecentlyAbandoned = nil;
1812 -- If a quest hasn't been recently completed or abandoned, check if
1813 -- it is okay to call LogCurrentQuests() to log new quests or update
1814 -- current ones
1815 elseif ( allowLogging ) then
1816 --QuestHistory_LogCurrentQuests();
1817 if (not QuestHistory_DelayedLoginFired) then
1818 QuestHistory_DelayedConfigInit = 10; -- EMERALD (thanks to UberQuest)
1819 QuestHistoryDelayedFrame:Show();
1820 else -- If QuestHistory_DelayedLoginFired, then we've done the login delay. No more long delays!
1821 QuestHistory_DelayedConfigInit = 0;
1822 QuestHistoryDelayedFrame:Show();
1823 end
1824 end
1825 -- Refreshes the display of the QuestHistory frame if it is visible
1826 if ( QuestHistoryFrame:IsVisible() ) then
1827 QuestHistory_Refresh();
1828 end
1829 end
1830 elseif ( event == "TIME_PLAYED_MSG" ) then
1831 if ( timeEvent == "Accepted" or timeEvent == "Completed" or timeEvent == "Logged" ) then
1832 -- Format and save current played time
1833 timeText = format(TEXT(QUESTHISTORY_TIME_FORMAT), ChatFrame_TimeBreakDown(arg1));
1834 -- Check if TIME_PLAYED_MSG event occurred when a quest was just completed
1835 if ( timeEvent == "Completed" ) then
1836 -- Record the quest completed time if doing so
1837 if ( QuestHistoryFlags["logTimeCompleted"].status ) then
1838 -- Make sure recentlyCompletedQuestID has been assigned a good value
1839 if ( recentlyCompletedQuestID ) then
1840 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].tc = timeText;
1841 if ( QuestHistoryFlags["logTimeAccepted"].status and ( not QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].ta ) and ( not QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].tl ) ) then
1842 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].ta = timeText;
1843 end
1844 end
1845 end
1846 end
1847 end
1848 end
1849 end
1850  
1851 function QuestHistory_OnShow()
1852 PlaySound("igMainMenuOpen");
1853 QuestHistory_Refresh();
1854 end
1855  
1856 function QuestHistory_OnHide()
1857 PlaySound("igMainMenuClose");
1858 HideUIPanel(QuestHistoryDetailFrame);
1859 HideUIPanel(QuestHistoryEditFrame);
1860 HideUIPanel(QuestHistoryOptionsFrame);
1861 HideUIPanel(QuestHistoryConfirmFrame);
1862 QuestHistoryFrameSearchEditBox:Hide();
1863 QuestHistoryFrameClearButton:Hide();
1864 QuestHistoryFrameSubmitButton:Hide();
1865 QuestHistoryFrameSearchButton:Show();
1866 end
1867  
1868 function QuestHistoryFrameSortDropDown_OnLoad()
1869 UIDropDownMenu_Initialize(QuestHistoryFrameSortDropDown, QuestHistoryFrameSortDropDown_Initialize);
1870 if ( not QuestHistoryFrameSortDropDown.selectedID ) then
1871 UIDropDownMenu_SetSelectedID(QuestHistoryFrameSortDropDown, 1 );
1872 end
1873 UIDropDownMenu_SetWidth(QUESTHISTORY_SORT_DROPDOWN_MENU_WIDTH);
1874 UIDropDownMenu_JustifyText("CENTER", QuestHistoryFrameSortDropDown);
1875 end
1876  
1877 function QuestHistoryFrameSortDropDownButton_OnClick()
1878 UIDropDownMenu_SetSelectedID(QuestHistoryFrameSortDropDown, this:GetID());
1879 QuestHistory_SetSortOrder();
1880 end
1881  
1882 function QuestHistory_SortButton_OnClick()
1883 UIDropDownMenu_SetSelectedID(QuestHistoryFrameSortDropDown, this:GetID());
1884 QuestHistory_SetSortOrder();
1885 end
1886  
1887 function QuestHistoryListFrame_OnClick(button)
1888 if ( button == "LeftButton" ) then
1889 if ( IsShiftKeyDown() and ChatFrameEditBox:IsVisible() ) then
1890 -- Insert quest title, level, category, tag into ChatFrame if Shift-leftclicked and chat frame is visible
1891 local frame = "QuestHistoryListFrame"..this:GetID();
1892 local title = getglobal(frame.."TitleText"):GetText();
1893 local level = getglobal(frame.."LevelText"):GetText();
1894 local category = getglobal(frame.."CategoryText"):GetText();
1895 local tag = getglobal(frame.."TagText"):GetText();
1896 if ( tag and tag ~= "" ) then
1897 tag = " ["..tag.."]";
1898 else
1899 tag = "";
1900 end
1901 local text = title.." - "..level.." - "..category..tag;
1902 ChatFrameEditBox:Insert(text);
1903 else
1904 currentTitleListID = this:GetID();
1905 local index = currentTitleListID + FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame);
1906 currentSortedID = index;
1907 currentDetailedQuestID = SortedTable[index];
1908 QuestHistory_Detail_Update(currentDetailedQuestID);
1909 ShowUIPanel(QuestHistoryDetailFrame);
1910 QuestHistoryListHighlightFrame:SetPoint("LEFT", "QuestHistoryListFrame"..currentTitleListID, "LEFT", 0, -2);
1911 QuestHistoryListHighlightFrame:Show();
1912 end
1913 elseif ( button == "RightButton" ) then
1914 if ( IsShiftKeyDown() and QuestHistoryFlags["allowDeleting"].status ) then
1915 local index = this:GetID() + FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame);
1916 QuestHistory_DeleteQuest(SortedTable[index]);
1917 if ( getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName]) and getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName]) > 0 ) then
1918 if ( index ~= 1 ) then
1919 index = index - 1;
1920 end
1921 currentSortedID = index;
1922 currentDetailedQuestID = SortedTable[index];
1923 QuestHistory_Detail_Update(currentDetailedQuestID);
1924 else
1925 currentSortedID = 0;
1926 HideUIPanel(QuestHistoryDetailFrame);
1927 end
1928 QuestHistory_Refresh();
1929 elseif ( QuestHistoryFlags["allowEditing"].status ) then
1930 currentTitleListID = this:GetID();
1931 local index = currentTitleListID + FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame);
1932 currentSortedID = index;
1933 currentDetailedQuestID = SortedTable[index];
1934 QuestHistoryEditTitle:SetText(QUESTHISTORY_EDIT_TEXT);
1935 QuestHistory_EditQuest(SortedTable[index]);
1936 QuestHistoryEditFrameSaveButton:Show();
1937 QuestHistoryEditFrameAddButton:Hide();
1938 ShowUIPanel(QuestHistoryEditFrame);
1939 QuestHistoryListHighlightFrame:SetPoint("LEFT", "QuestHistoryListFrame"..currentTitleListID, "LEFT", 0, -2);
1940 QuestHistoryListHighlightFrame:Show();
1941 end
1942 end
1943 end
1944  
1945 -- Displays quest note in a tootip-like button that appears when the mouse hovers over an item in the quest list
1946 function QuestHistoryListFrame_OnEnter()
1947 local note = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][SortedTable[this:GetID() + FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame)]].n;
1948 if ( note ~= nil and note ~= "" ) then
1949 QuestHistoryTooltip:SetPoint("TOPLEFT", "QuestHistoryListFrame"..this:GetID().."CompletedText", "TOPRIGHT", 15, 0);
1950 QuestHistoryTooltipText:SetText(note);
1951 QuestHistoryTooltip:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b);
1952 QuestHistoryTooltip:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b);
1953 QuestHistoryTooltip:Show();
1954 end
1955 end
1956  
1957 -- Hides the search button and shows the clear button and the search edit box
1958 function QuestHistoryFrameSearchButton_OnClick()
1959 QuestHistoryFrameClearButton:Show();
1960 if ( searchText ) then
1961 QuestHistoryFrameSearchEditBox:SetText(searchText);
1962 end
1963 end
1964  
1965 -- Clears the search text and refreshes the quest list
1966 function QuestHistoryFrameClearButton_OnClick()
1967 QuestHistoryFrameSearchEditBox:SetText("");
1968 searchText = nil;
1969 QuestHistory_Refresh();
1970 end
1971  
1972 -- Saves the entered search text and refreshes the quest list
1973 function QuestHistoryFrameSearchEditBox_OnEnterPressed()
1974 searchText = QuestHistoryFrameSearchEditBox:GetText();
1975 QuestHistoryFrameSearchEditBox:AddHistoryLine(searchText);
1976 QuestHistory_Refresh();
1977 QuestHistoryFrameSearchButton:Show();
1978 end
1979  
1980 -- Registers events for the detail frame
1981 function QuestHistoryDetailFrame_OnLoad()
1982 this:RegisterEvent("QUEST_LOG_UPDATE");
1983 this:RegisterEvent("UPDATE_FACTION");
1984 end
1985  
1986 -- Updates the detail frame if one of the registered events occur while the frame is visible
1987 function QuestHistoryDetailFrame_OnEvent()
1988 if ( event == "QUEST_LOG_UPDATE" or event == "UPDATE_FACTION" ) then
1989 if ( QuestHistoryDetailFrame:IsVisible() ) then
1990 QuestHistory_Detail_Update(currentDetailedQuestID);
1991 end
1992 end
1993 end
1994  
1995 -- Sets up the tooltip for the reward items in the detailed quest view
1996 function QuestHistoryDetailRewardItem_OnEnter()
1997 GameTooltip:SetOwner(this, "ANCHOR_RIGHT");
1998 local itemNumber = this:GetID();
1999 local linkText, itemLink;
2000 -- Gets the item hyperlink and processes it
2001 if ( this.type == "choice" ) then
2002 linkText = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID]["i"][itemNumber].l;
2003 itemLink = QuestHistory_ProcessLinks(linkText);
2004 elseif ( this.type == "reward" ) then
2005 linkText = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID]["r"][itemNumber].l;
2006 itemLink = QuestHistory_ProcessLinks(linkText);
2007 end
2008 -- Sets the hyperlink to the game tooltip if it exists
2009 if ( itemLink ) then
2010 GameTooltip:SetHyperlink(itemLink);
2011 end
2012 end
2013  
2014 -- Allows item to be copied to ChatFrame if Shift-leftclicked
2015 function QuestHistoryDetailRewardItem_OnClick()
2016 if ( IsShiftKeyDown() ) then
2017 local linkText;
2018 if ( ChatFrameEditBox:IsVisible() ) then
2019 local itemNumber = this:GetID();
2020 if ( this.type == "choice" ) then
2021 linkText = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID]["i"][itemNumber].l;
2022 elseif ( this.type == "reward" ) then
2023 linkText = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID]["r"][itemNumber].l;
2024 end
2025 end
2026 -- Adds the link to the chat frame
2027 if ( linkText ) then
2028 ChatFrameEditBox:Insert(linkText);
2029 end
2030 end
2031 end
2032  
2033 -- Tabs between edit boxes in QuestHistoryEditFrame
2034 function QuestHistoryEditBox_OnTabPressed()
2035 local id;
2036 local numBoxes = 0;
2037 local _, _, name = string.find(this:GetName(), "QuestHistoryEdit(.*)EditBox");
2038 for index, value in QuestHistoryData do
2039 if ( value.box ) then
2040 numBoxes = numBoxes + 1;
2041 end
2042 if ( value.box == name ) then
2043 id = value.tab;
2044 end
2045 end
2046 if ( IsShiftKeyDown() ) then
2047 id = id - 1;
2048 else
2049 id = id + 1;
2050 end
2051 if ( id < 1 ) then
2052 id = numBoxes;
2053 elseif ( id > numBoxes ) then
2054 id = 1;
2055 end
2056 local tabIndex;
2057 for index, value in QuestHistoryData do
2058 if ( value.tab == id ) then
2059 tabIndex = index;
2060 end
2061 end
2062 getglobal("QuestHistoryEdit"..QuestHistoryData[tabIndex].box.."EditBox"):SetFocus();
2063 if ( id >= 5 and id <= 10 ) then
2064 QuestHistoryEditListScrollFrameScrollBar:SetValue(0);
2065 elseif ( id >= 15 and id <= 21 ) then
2066 QuestHistoryEditListScrollFrameScrollBar:SetValue(100);
2067 end
2068 end
2069  
2070 function QuestHistoryEditFrameSaveButton_OnClick()
2071 local index = currentTitleListID + FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame);
2072 local data, questID = QuestHistory_GetEditData();
2073 if ( questID ~= SortedTable[index] ) then
2074 if ( questID > getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName]) ) then
2075 questID = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName]);
2076 end
2077 QuestHistory_ReorderQuests(SortedTable[index], questID);
2078 end
2079 for index, value in data do
2080 if ( index == "co" and value ~= QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questID].co ) then
2081 if ( value == "" ) then
2082 value = nil;
2083 end
2084 local old = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questID].co;
2085 QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questID].co = QuestHistory_ReorderCompleted(old, value);
2086 elseif ( value ~= "" ) then
2087 QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questID][index] = value;
2088 else
2089 QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][questID][index] = nil;
2090 end
2091 end
2092 currentDetailedQuestID = questID;
2093 QuestHistory_Refresh();
2094 QuestHistory_EditQuest(questID);
2095 end
2096  
2097 function QuestHistoryEditFrameAddButton_OnClick()
2098 local data, questID = QuestHistory_GetEditData();
2099 if ( questID > getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName]) + 1 ) then
2100 questID = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName]) + 1;
2101 end
2102 for index, value in data do
2103 if ( value == "" ) then
2104 data[index] = nil;
2105 elseif ( index == "co" ) then
2106 data.co = QuestHistory_ReorderCompleted(nil, value);
2107 end
2108 end
2109 table.insert(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName], questID, data);
2110 currentDetailedQuestID = questID;
2111 QuestHistory_Refresh();
2112 QuestHistory_AddQuest();
2113 end
2114  
2115 -- Sets the checkboxes to the appropriate values from QuestHistoryFlags
2116 function QuestHistoryOptionsFrame_OnShow()
2117 for index, value in QuestHistoryFlags do
2118 local button = getglobal("QuestHistoryOptionsFrameCheckButton"..value.index);
2119 local string = getglobal("QuestHistoryOptionsFrameCheckButton"..value.index.."Text");
2120 string:SetText(TEXT(value.text));
2121 button.tooltipText = value.tooltipText;
2122 if ( value.status ) then
2123 button:SetChecked(1);
2124 else
2125 button:SetChecked(0);
2126 end
2127 end
2128 end
2129  
2130 function QuestHistoryColorSwatch_OnShow(status)
2131 this.status = status;
2132 lowstatus = string.lower(status);
2133 this.swatchFunc = QuestHistory_SetColor;
2134 this.cancelFunc = QuestHistory_CancelColor;
2135 this.r = QuestHistoryStatusColor[lowstatus].r;
2136 this.g = QuestHistoryStatusColor[lowstatus].g;
2137 this.b = QuestHistoryStatusColor[lowstatus].b;
2138 getglobal(this:GetName().."NormalTexture"):SetVertexColor(this.r, this.g, this.b);
2139 end
2140  
2141 function QuestHistoryOptionsFrameCharacterDropDown_OnShow()
2142 UIDropDownMenu_Initialize(QuestHistoryOptionsFrameCharacterDropDown, QuestHistoryOptionsFrameCharacterDropDown_Initialize);
2143 if ( not QuestHistoryOptionsFrameCharacterDropDown.selectedID ) then
2144 QuestHistory_SelectCurrentCharacter();
2145 end
2146 UIDropDownMenu_SetWidth(QUESTHISTORY_CHARACTER_DROPDOWN_MENU_WIDTH);
2147 end
2148  
2149 function QuestHistoryOptionsFrameCharacterDropDownButton_OnClick()
2150 UIDropDownMenu_SetSelectedID(QuestHistoryOptionsFrameCharacterDropDown, this:GetID());
2151 button = getglobal("DropDownList"..UIDROPDOWNMENU_MENU_LEVEL.."Button"..this:GetID());
2152 _, _, DisplayedPlayerCharacterName = string.find(button:GetText(), " (.*)");
2153 DisplayedRealmName = button.value;
2154 currentDetailedListID = nil;
2155 currentSortedID = 0;
2156 currentTitleListID = nil;
2157 QuestHistory_Refresh();
2158 end
2159  
2160 function QuestHistoryOptionsFrameDeleteButton_OnClick()
2161 if ( RealmName ~= DisplayedRealmName or PlayerCharacterName ~= DisplayedPlayerCharacterName ) then
2162 PlaySound("igMainMenuOptionCheckBoxOn");
2163 QuestHistoryOptionsFrameOkayButton_OnClick();
2164 QuestHistoryConfirmFrameExplanation:SetText(QUESTHISTORY_DELETE_CONFIRM_EXPLANATION);
2165 ShowUIPanel(QuestHistoryConfirmFrame);
2166 end
2167 end
2168  
2169 function QuestHistory_AddQuest()
2170 QuestHistoryEditTitle:SetText(QUESTHISTORY_ADD_TEXT);
2171 QuestHistory_ClearQuest();
2172 QuestHistoryEditAcceptedOrderEditBox:SetText(getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName])+ 1);
2173 QuestHistoryEditFrameSaveButton:Hide();
2174 QuestHistoryEditFrameAddButton:Show();
2175 ShowUIPanel(QuestHistoryEditFrame);
2176 end
2177  
2178 -- Saves the checkbox values in QuestHistoryFlags
2179 function QuestHistoryOptionsFrameOkayButton_OnClick()
2180 for index, value in QuestHistoryFlags do
2181 value.status = getglobal("QuestHistoryOptionsFrameCheckButton"..value.index):GetChecked();
2182 end
2183 QuestHistory_SaveFlags();
2184 HideUIPanel(QuestHistoryOptionsFrame);
2185 QuestHistory_Refresh();
2186 end
2187  
2188 function QuestHistoryConfirmFrameOkayButton_OnClick()
2189 local text = QuestHistoryConfirmFrameExplanation:GetText();
2190 if ( text == QUESTHISTORY_PURGE_CONFIRM_EXPLANATION ) then
2191 QuestHistory_PurgeData();
2192 elseif ( text == QUESTHISTORY_DELETE_CONFIRM_EXPLANATION ) then
2193 QuestHistory_DeleteCharacter();
2194 elseif ( text == QUESTHISTORY_REPAIR_CONFIRM_EXPLANATION ) then
2195 QuestHistory_RepairData();
2196 end
2197 end
2198  
2199 -- Keeps track of the time since the last logging of quest data
2200 function QuestHistory_Timer_OnUpdate()
2201 -- Check if flag is set to disable logging
2202 if ( not allowLogging ) then
2203 -- Increase time since last log
2204 timeSinceLastLog = timeSinceLastLog + arg1;
2205 -- Check if it has been at least 0.1 seconds since the last logging
2206 if ( timeSinceLastLog > 0.1 ) then
2207 -- Set flag to allow logging
2208 allowLogging = true;
2209 end
2210 end
2211 end
2212  
2213 ----------------------------------------------------------------------------------------------------
2214 -- Hooked Functions
2215 ----------------------------------------------------------------------------------------------------
2216  
2217 -- Needed so that QuestHistory knows when a quest has been accepted, also to
2218 -- record the player's target, location and time when a quest is accepted
2219 function QuestHistory_QuestDetailAcceptButton_OnClick()
2220 -- Flag that a quest has just been accepted
2221 questHasBeenRecentlyAccepted = true;
2222 -- Save the name of the current target to store as the quest giver
2223 recentNPCQuestGiver = UnitName("target");
2224 -- Save the player's location where quest was accepted
2225 local playerX, playerY = GetPlayerMapPosition("player");
2226 -- EMERALD: NOTE: This is the one that fired in instances, in all reports given.
2227 --if (playerX==0 and playerY==0) then
2228 --ShowUIPanel(WorldMapFrame);
2229 --HideUIPanel(WorldMapFrame);
2230 --playerX, playerY = GetPlayerMapPosition("player");
2231 --QuestHistory_InsideInstance = true; -- set to prevent 0,0 lock
2232 --end
2233 --QuestHistory_InsideInstance = false;
2234 local zone = GetZoneText();
2235 recentlyAcceptedLocation = zone..":"..playerX..":"..playerY;
2236 -- Get the played time when the quest was accepted if doing so
2237 if ( QuestHistoryFlags["logTimeAccepted"].status ) then
2238 timeEvent = "Accepted";
2239 RequestTimePlayed();
2240 end
2241 -- Call the original QuestDetailAcceptButton_OnClick function
2242 originalQuestDetailAcceptButton_OnClick();
2243 end
2244  
2245 -- Needed to record the player's target, level, location, time and XP when a
2246 -- quest is completed -- also keeps track of the order in which quests are
2247 -- completed
2248 function QuestHistory_QuestRewardCompleteButton_OnClick()
2249 local rewardTitle = GetTitleText();
2250 local rewardDescription = GetRewardText();
2251 local skipQuest;
2252 if ( QuestHistoryFlags["logPortQuests"] or ( rewardTitle ~= "Port to Auberdine" and rewardTitle ~= "Port to Menethil" ) ) then
2253 recentlyCompletedQuestID = nil;
2254 -- Look through the currently logged quests to find the highest value of the completed quests
2255 local highestCompleted = 0;
2256  
2257 -- EMERALD DEBUG
2258 --DEFAULT_CHAT_FRAME:AddMessage("RealmName = "..RealmName);
2259 --DEFAULT_CHAT_FRAME:AddMessage("PlayerCharacterName = "..PlayerCharacterName);
2260  
2261 for index, value in QuestHistory_List[RealmName][PlayerCharacterName] do
2262 if ( value.co and highestCompleted < value.co ) then
2263 -- Store the highest value of the last completed quest
2264 highestCompleted = value.co;
2265 end
2266 end
2267 -- Look through the currently logged quests to find the one most recently completed by comparing titles
2268 for index, value in QuestHistory_List[RealmName][PlayerCharacterName] do
2269 -- Check if the quest has been marked completed
2270 if ( value.co ) then
2271 -- If so, then check if its description meets the reward description
2272 if ( rewardDescription == value.d ) then
2273 -- This quest has been logged before so skip it.
2274 skipQuest = true;
2275 end
2276 else
2277 -- If the quest has not been marked completed, check its title
2278 if ( rewardTitle == value.t ) then
2279 -- Store the index of the quest most recently completed
2280 recentlyCompletedQuestID = index;
2281 -- Don't skip this quest
2282 skipQuest = nil;
2283 -- Break out of the for loop if the quest is found
2284 break;
2285 end
2286 end
2287 end
2288 if ( not skipQuest ) then
2289 -- Check if quest is completed without ever being accepted and added to quest log
2290 if ( not recentlyCompletedQuestID ) then
2291 -- Set the last completed to 1 more than the player's current number of logged quests
2292 recentlyCompletedQuestID = getn(QuestHistory_List[RealmName][PlayerCharacterName]) + 1;
2293 -- Create a new blank quest entry
2294 table.insert(QuestHistory_List[RealmName][PlayerCharacterName], { });
2295 -- Record quest title
2296 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].t = rewardTitle;
2297 -- Record quest description if doing so
2298 if ( QuestHistoryFlags["logDescription"].status ) then
2299 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].d = rewardDescription;
2300 end
2301 -- Record quest category if doing so
2302 if ( QuestHistoryFlags["logCategory"].status ) then
2303 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].c = GetZoneText();
2304 end
2305 -- Record player's level when quest was accepted if doing so
2306 if ( QuestHistoryFlags["logLevelAccepted"].status ) then
2307 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].la = UnitLevel("player");
2308 end
2309 -- Record accepted location if doing so
2310 if ( QuestHistoryFlags["logAcceptedLocation"].status ) then
2311 local playerX, playerY = GetPlayerMapPosition("player");
2312 --if (playerX==0 and playerY==0 and not QuestHistory_InsideInstance) then
2313 --ShowUIPanel(WorldMapFrame);
2314 --HideUIPanel(WorldMapFrame);
2315 --playerX, playerY = GetPlayerMapPosition("player");
2316 --QuestHistory_InsideInstance = true; -- set to prevent 0,0 lock
2317 -- if (playerX==0 and playerY==0) then
2318 -- if ( DEFAULT_CHAT_FRAME ) then
2319 -- DEFAULT_CHAT_FRAME:AddMessage("QuestHistory: WARNING! Your coordinates are being reported as 0,0. Please give this code to Dsanai: BN2");
2320 -- end
2321 -- end
2322 --end
2323 --QuestHistory_InsideInstance = false;
2324 local zone = GetZoneText();
2325 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].pc = zone..":"..playerX..":"..playerY;
2326 end
2327 -- Record quest giver if doing so
2328 if ( QuestHistoryFlags["logQuestGiver"].status ) then
2329 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].g = UnitName("target");
2330 end
2331 -- Record required money if doing so
2332 if ( QuestHistoryFlags["logRequiredMoney"].status ) then
2333 local reqMoney = GetQuestMoneyToGet();
2334 if ( reqMoney and ( reqMoney > 0 ) ) then
2335 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].rm = reqMoney;
2336 end
2337 end
2338 -- Record quest rewards if doing so
2339 if ( QuestHistoryFlags["logRewards"].status ) then
2340 local nRewards = GetNumQuestRewards();
2341 if ( nRewards and ( nRewards > 0 ) ) then
2342 -- Create blank table to store reward info
2343 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].r = { };
2344 -- Cycle through number of quest rewards
2345 for j = 1, nRewards, 1 do
2346 -- Create blank table for this reward
2347 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID]["r"][j] = { };
2348 -- Get data for quest reward
2349 local rName, rTexture, rNumItems, rQuality, rIsUsable = GetQuestItemInfo("reward", j);
2350 -- Record data for quest reward
2351 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID]["r"][j].t = rTexture;
2352 if ( rNumItems > 1 ) then
2353 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID]["r"][j].a = rNumItems;
2354 end
2355 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID]["r"][j].l = GetQuestItemLink("reward", j);
2356 end
2357 end
2358 end
2359 -- Record quest choices if doing so
2360 if ( QuestHistoryFlags["logChoices"].status ) then
2361 local nChoices = GetNumQuestChoices();
2362 if ( nChoices and ( nChoices > 0 ) ) then
2363 -- Create blank table to store choice info
2364 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].i = { };
2365 -- Cycle through number of quest choices
2366 for j = 1, nChoices, 1 do
2367 -- Create blank table for this choice
2368 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID]["i"][j] = { };
2369 -- Get data for quest choice
2370 local cName, cTexture, cNumItems, cQuality, cIsUsable = GetQuestItemInfo("choice", j);
2371 -- Record data for quest choice
2372 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID]["i"][j].t = cTexture;
2373 if ( cNumItems > 1 ) then
2374 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID]["i"][j].a = cNumItems;
2375 end
2376 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID]["i"][j].l = GetQuestItemLink("choice", j);
2377 end
2378 end
2379 end
2380 -- Record quest spells if doing so
2381 if ( QuestHistoryFlags["logSpells"].status ) then
2382 if ( GetRewardSpell() ) then
2383 -- Create blank table to store spell info
2384 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].s = { };
2385 -- Get data for spell reward
2386 local sTexture, sName = GetRewardSpell();
2387 -- Record data for spell reward
2388 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].t = sTexture;
2389 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].n = sName;
2390 end
2391 end
2392 -- Record reward money if doing so
2393 if ( QuestHistoryFlags["logRewardMoney"].status ) then
2394 local rewMoney = GetRewardMoney();
2395 if ( rewMoney and ( rewMoney > 0 ) ) then
2396 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].m = rewMoney;
2397 end
2398 end
2399 -- Record background material if doing so
2400 if ( QuestHistoryFlags["logBackgroundMaterial"].status ) then
2401 local material = QuestFrame_GetMaterial();
2402 if ( material ~= "Parchment" ) then
2403 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].bg = material;
2404 end
2405 end
2406 end
2407 -- If logging XP reward, record the current XP and current XP max
2408 if ( QuestHistoryFlags["logXPReward"].status ) then
2409 XPBeforeQuestCompletion = UnitXP("player");
2410 XPMaxBeforeQuestCompletion = UnitXPMax("player");
2411 end
2412 -- Record player's level when quest was completed if doing so
2413 if ( QuestHistoryFlags["logLevelCompleted"].status ) then
2414 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].lc = UnitLevel("player");
2415 end
2416 -- Record order of quest completed if doing so
2417 if ( QuestHistoryFlags["logCompletedOrder"].status ) then
2418 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].co = highestCompleted + 1;
2419 end
2420 -- Record quest completer if doing so
2421 if ( QuestHistoryFlags["logQuestCompleter"].status ) then
2422 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].w = UnitName("target");
2423 end
2424 -- Record completed location if doing so
2425 if ( QuestHistoryFlags["logCompletedLocation"].status ) then
2426 local playerX, playerY = GetPlayerMapPosition("player");
2427 --if (playerX==0 and playerY==0 and not QuestHistory_InsideInstance) then
2428 --ShowUIPanel(WorldMapFrame);
2429 --HideUIPanel(WorldMapFrame);
2430 --playerX, playerY = GetPlayerMapPosition("player");
2431 --QuestHistory_InsideInstance = true; -- set to prevent 0,0 lock
2432 -- if (playerX==0 and playerY==0) then
2433 -- if ( DEFAULT_CHAT_FRAME ) then
2434 -- DEFAULT_CHAT_FRAME:AddMessage("QuestHistory: WARNING! Your coordinates are being reported as 0,0. Please give this code to Dsanai: LK6");
2435 -- end
2436 -- end
2437 --end
2438 --QuestHistory_InsideInstance = false;
2439 local zone = GetZoneText();
2440 QuestHistory_List[RealmName][PlayerCharacterName][recentlyCompletedQuestID].pc = zone..":"..playerX..":"..playerY;
2441 end
2442 -- Get the played time when quest was completed if doing so
2443 if ( QuestHistoryFlags["logTimeCompleted"].status ) then
2444 timeEvent = "Completed";
2445 RequestTimePlayed();
2446 end
2447 end
2448 end
2449 -- Call the original QuestRewardCompleteButton_OnClick function
2450 originalQuestRewardCompleteButton_OnClick();
2451 end
2452  
2453 -- Marks a quest as abandoned and updates the times abandoned count.
2454 function QuestHistory_AbandonQuest()
2455 -- Flag that a quest has just been abandoned
2456 questHasBeenRecentlyAbandoned = true;
2457 -- Store the quest title so the right quest is marked abandoned
2458 local questTitle = GetQuestLogTitle(GetQuestLogSelection());
2459 if ( questTitle ) then -- EMERALD: Thanks, Asjaskan
2460 questTitle = string.gsub(string.gsub(questTitle,'^[[].*[]]',''),'^ ','');
2461 end
2462  
2463 -- Call the original AbandonQuest function
2464 originalAbandonQuest();
2465 -- Look through the currently logged quests to mark the one abandoned
2466 for index, value in QuestHistory_List[RealmName][PlayerCharacterName] do
2467 -- Check if the quest matches the title and that it hasn't been marked completed
2468 if ( questTitle == value.t and ( not value.co ) ) then
2469 -- Mark the quest has abandoned
2470 value.a = true;
2471 -- Update the quest's count of times abandoned
2472 if ( not value.ac ) then
2473 value.ac = 1;
2474 else
2475 value.ac = value.ac + 1;
2476 end
2477 -- Break out of the for loop if the right quest was found
2478 break;
2479 end
2480 end
2481 end
2482  
2483 -- Prevents played time from being displayed in the chat frame whenever it is
2484 -- invoked for a quest being accepted/logged/completed.
2485 function QuestHistory_ChatFrame_DisplayTimePlayed(totalTime, levelTime)
2486 if ( timeEvent == "Accepted" or timeEvent == "Logged" or timeEvent == "Completed" ) then
2487 -- Clear the value of timeEvent
2488 timeEvent = "";
2489 else
2490 -- Only call the original ChatFrame_DisplayTimePlayed function if it
2491 -- wasn't invoked by the accepting/logging/completing of a quest
2492 originalChatFrame_DisplayTimePlayed(totalTime, levelTime)
2493 end
2494 end
2495  
2496 ----------------------------------------------------------------------------------------------------
2497 -- Callback Functions
2498 ----------------------------------------------------------------------------------------------------
2499  
2500 -- Toggles the showing/hiding of the QuestHistoryFrame
2501 function QuestHistory_Toggle()
2502 if ( QuestHistoryFrame:IsVisible() ) then
2503 HideUIPanel(QuestHistoryFrame);
2504 else
2505 ShowUIPanel(QuestHistoryFrame);
2506 end
2507 end
2508  
2509 -- Handles the processing of the registered slash commands
2510 function QuestHistory_SlashCommandHandler(msg)
2511 if (msg and string.lower(msg)=="levels") then -- EMERALD
2512 if (QuestHistory_Options["levels"]) then -- disable Levels
2513 QuestHistory_Options["levels"] = false;
2514 if ( DEFAULT_CHAT_FRAME ) then
2515 DEFAULT_CHAT_FRAME:AddMessage("QuestHistory: NPC Quest Level display is now disabled.");
2516 end
2517 else -- enable Levels
2518 QuestHistory_Options["levels"] = true;
2519 if ( DEFAULT_CHAT_FRAME ) then
2520 DEFAULT_CHAT_FRAME:AddMessage("QuestHistory: NPC Quest Level display is now enabled.");
2521 end
2522 end
2523 else
2524 QuestHistory_Toggle();
2525 end
2526 end
2527  
2528 -- Updates the display of the main QuestHistory frame and determines which
2529 -- quests are shown in the visible scrollframe
2530 function QuestHistory_Update()
2531 -- Get number of quests stored for current player
2532 local listSize = getn(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName]);
2533 local QuestHistoryTitle = QuestHistoryTitleText;
2534 -- Build sorted table if it hasn't been created yet
2535 if ( not SortedTable ) then
2536 QuestHistory_BuildSortedTable();
2537 end
2538 -- Highlight currently selected quest if it is visible in the scrollframe
2539 currentTitleListID = currentSortedID - FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame);
2540 if ( currentTitleListID >= 1 and currentTitleListID <= 31 ) then
2541 QuestHistoryListHighlightFrame:SetPoint("LEFT", "QuestHistoryListFrame"..currentTitleListID, "LEFT", 0, -2);
2542 QuestHistoryListHighlightFrame:Show();
2543 else
2544 -- Hide the highlight frame since selected quest is not visible in the scrollframe
2545 QuestHistoryListHighlightFrame:Hide();
2546 end
2547 -- Format QuestHistory title appropriately depending on how many quests are logged
2548 if ( listSize and ( listSize == 1 ) ) then
2549 QuestHistoryTitle:SetText(format(TEXT(QUESTHISTORY_TITLE_FORMAT_SINGULAR), DisplayedPlayerCharacterName));
2550 else
2551 QuestHistoryTitle:SetText(format(TEXT(QUESTHISTORY_TITLE_FORMAT_PLURAL), DisplayedPlayerCharacterName, listSize));
2552 end
2553 -- Update the scroll frame and add the quest data
2554 FauxScrollFrame_Update(QuestHistoryListScrollFrame, sizeSortedTable, QUESTHISTORY_ITEMS_SHOWN, QUESTHISTORY_ITEM_HEIGHT);
2555 for iQuest = 1, QUESTHISTORY_ITEMS_SHOWN, 1 do
2556 local questIndex = iQuest + FauxScrollFrame_GetOffset(QuestHistoryListScrollFrame);
2557 local listFrame = "QuestHistoryListFrame"..iQuest;
2558 if ( questIndex <= sizeSortedTable ) then
2559 local color;
2560 -- Get quest information
2561 local index = SortedTable[questIndex];
2562 local title = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index].t;
2563 local level = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index].l;
2564 local category = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index].c;
2565 local tag = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index].y;
2566 local completed = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index].co;
2567 -- Check to make sure none of the data is nil
2568 if ( not title ) then
2569 title = "";
2570 end
2571 if ( not level ) then
2572 level = "";
2573 end
2574 if ( not category ) then
2575 category = "";
2576 end
2577 if ( not tag ) then
2578 tag = "";
2579 end
2580 -- Add quest data to frame
2581 getglobal(listFrame.."AcceptedText"):SetText(index);
2582 getglobal(listFrame.."TitleText"):SetText(title);
2583 getglobal(listFrame.."LevelText"):SetText(level);
2584 getglobal(listFrame.."CategoryText"):SetText(category);
2585 getglobal(listFrame.."TagText"):SetText(tag);
2586 if ( completed ) then
2587 -- If quest has been completed, show checkmark and completed number in brackets
2588 getglobal(listFrame.."CompletedText"):SetText("["..completed.."]");
2589 getglobal(listFrame.."CheckMark"):Show();
2590 else
2591 -- Otherwise, hide checkmark and display nothing for completed
2592 getglobal(listFrame.."CompletedText"):SetText("");
2593 getglobal(listFrame.."CheckMark"):Hide();
2594 end
2595 -- Set color depending on quest status
2596 if (completed) then
2597 color = QuestHistoryStatusColor["completed"];
2598 elseif ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index].a ) then
2599 color = QuestHistoryStatusColor["abandoned"];
2600 elseif ( QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][index].f ) then
2601 color = QuestHistoryStatusColor["failed"];
2602 else
2603 if ( level == "" ) then
2604 level = 0;
2605 end
2606 color = GetDifficultyColor(level);
2607 end
2608 -- Apply color to text
2609 getglobal(listFrame.."AcceptedText"):SetTextColor(color.r, color.g, color.b);
2610 getglobal(listFrame.."TitleText"):SetTextColor(color.r, color.g, color.b);
2611 getglobal(listFrame.."LevelText"):SetTextColor(color.r, color.g, color.b);
2612 getglobal(listFrame.."CategoryText"):SetTextColor(color.r, color.g, color.b);
2613 getglobal(listFrame.."TagText"):SetTextColor(color.r, color.g, color.b);
2614 getglobal(listFrame.."CompletedText"):SetTextColor(color.r, color.g, color.b);
2615 getglobal(listFrame):Show();
2616 else
2617 -- Hide the list frame if there is no data for it
2618 getglobal(listFrame):Hide();
2619 end
2620 end
2621 end
2622  
2623 -- Opens the QuestHistory note scroll frame and populates it with the current note if there is one
2624 function QuestHistory_Edit_Note()
2625 local note = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID].n;
2626 if ( note ) then
2627 QuestHistoryDetailNotesText:SetText(note);
2628 else
2629 QuestHistoryDetailNotesText:SetText("");
2630 end
2631 -- Hide and show the appropriate frames
2632 QuestHistoryDetailListScrollFrame:Hide();
2633 QuestHistoryDetailEditButton:Hide();
2634 QuestHistoryDetailNotesScrollFrame:Show();
2635 QuestHistoryDetailSaveButton:Show();
2636 end
2637  
2638 -- Saves the player entered noted to QuestHistory_List
2639 function QuestHistory_Save_Note()
2640 local note = QuestHistoryDetailNotesText:GetText();
2641 if ( note and note ~= "" ) then
2642 QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID].n = note;
2643 end
2644 -- Refresh the detailed view display
2645 QuestHistory_Detail_Update(currentDetailedQuestID);
2646 end
2647  
2648 -- Selects the quest in the main list relative to the currently selected quest and based
2649 -- on the value of offset
2650 function QuestHistory_Change_Detailed_Quest(offset)
2651 newID = currentSortedID + offset;
2652 -- Check if newID is valid
2653 if ( newID > 0 and newID <= sizeSortedTable ) then
2654 currentTitleListID = currentTitleListID + offset;
2655 currentSortedID = newID;
2656 currentDetailedQuestID = SortedTable[newID];
2657 QuestHistory_Detail_Update(currentDetailedQuestID);
2658 ShowUIPanel(QuestHistoryDetailFrame);
2659 QuestHistory_Refresh();
2660 end
2661 end
2662  
2663 function QuestHistory_ClearQuest()
2664 for index, value in QuestHistoryData do
2665 if ( value.box ) then
2666 getglobal("QuestHistoryEdit"..value.box.."EditBox"):SetText("");
2667 end
2668 end
2669 end
2670  
2671 function QuestHistory_SetColor()
2672 local red,green,blue = ColorPickerFrame:GetColorRGB();
2673 QuestHistoryStatusColor[string.lower(QuestHistory_StatusColorType)] = { r = red, g = green, b = blue };
2674 getglobal("QuestHistoryOptionsFrame"..QuestHistory_StatusColorType.."ColorSwatchNormalTexture"):SetVertexColor(red, green, blue);
2675 getglobal("QuestHistoryOptionsFrame"..QuestHistory_StatusColorType.."ColorSwatch").r = red;
2676 getglobal("QuestHistoryOptionsFrame"..QuestHistory_StatusColorType.."ColorSwatch").g = green;
2677 getglobal("QuestHistoryOptionsFrame"..QuestHistory_StatusColorType.."ColorSwatch").b = blue;
2678 if ( not QuestHistory_StatusColors ) then
2679 QuestHistory_StatusColors = { };
2680 end
2681 QuestHistory_StatusColors[string.lower(QuestHistory_StatusColorType)] = { r = red, g = green, b = blue };
2682 QuestHistory_Refresh();
2683 end
2684  
2685 function QuestHistory_CancelColor(previousValues)
2686 if ( previousValues.r ) then
2687 ColorPickerFrame:SetColorRGB(previousValues.r, previousValues.g, previousValues.b);
2688 end
2689 end
2690  
2691 -- Converts the zone into the continent/zone numbers used by MapNotes
2692 function QuestHistory_MapNotes_GetZone(zone)
2693 for i = 1, 2, 1 do
2694 for j, value in QHMN_ZoneNames[i] do
2695 if ( value == zone ) then
2696 return i, j;
2697 end
2698 end
2699 end
2700 return 0, 0;
2701 end
2702  
2703 -- Creates the text for a new note and sends it to MapNotes
2704 function QuestHistory_SendToMapNotes(button, locationType)
2705 if ( QHMN_Data and QHMN_ZoneNames ) then
2706 local _, _, area, xPos, yPos = string.find(QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID]["p"..locationType], "(.*):(.*):(.*)");
2707 if ( area and xPos and yPos ) then
2708 if ( button == "RightButton" ) then
2709 QHMN_SetNextAsMiniNote = 2;
2710 end
2711 local continent, zone = QuestHistory_MapNotes_GetZone(area);
2712 local title;
2713 local info1 = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID].t;
2714 local info2 = "";
2715 local creator = DisplayedPlayerCharacterName;
2716 local icon;
2717 local tcolor = 0;
2718 local i1color = 2;
2719 local i2color = 0;
2720 if ( locationType == "a" ) then
2721 title = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID].g;
2722 icon = 3;
2723 else
2724 title = QuestHistory_List[DisplayedRealmName][DisplayedPlayerCharacterName][currentDetailedQuestID].w;
2725 icon = 1;
2726 end
2727 local text = "c<"..continent.."> z<"..zone.."> x<"..xPos.."> y<"..yPos..">";
2728 text = text.." t<"..title.."> i1<"..info1.."> i2<"..info2.."> cr<"..creator..">";
2729 text = text.." i<"..icon.."> tf<"..tcolor.."> i1f<"..i1color.."> i2f<"..i2color..">";
2730 QHMN_GetNoteBySlashCommand(text);
2731 end
2732 end
2733 end