vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | --[[ |
2 | Description |
||
3 | If you have ever had a quest item you have no idea which quest it belongs to, and if it safe to destroy, this AddOn is for you. |
||
4 | |||
5 | QuestItem stores an in-game database over quest items and tell you which quest they belong to. Useful to find out if you |
||
6 | are still o n the quest, and if it safe to destroy it. The AddOn will map items to quests when you pick them up, but also |
||
7 | has a limited backward compatability. If you see tooltip for a questitem you have picked up before installing the addon, |
||
8 | QuestItem will try to find the item in your questlog, and map it to a quest. In case unsuccessful, the item will be marked |
||
9 | as unidentified. |
||
10 | |||
11 | QuestItem now has a configuration screen you can access by typing /questitem or /qi at the chat prompt. Here you can configure |
||
12 | some of the functionallity as well as do manual mapping of unidentified items. |
||
13 | |||
14 | Feature summary: |
||
15 | - Identify quest items when picked up. |
||
16 | - Show quest name and status in tooltip for quest items. |
||
17 | - Will try to identify items picked up before the AddOn was installed. |
||
18 | - Identified items are available for all your characters, and status is unique for your character. |
||
19 | - Displays how many items are needed to complete quest, and how many you currently have. |
||
20 | - Manual mapping for unidentified items. |
||
21 | - Configuration |
||
22 | |||
23 | + If you like this addon (or even if you don't), donations are always welcome to my character Shagoth on the Stormreaver server ;D |
||
24 | + If you can translate the interface to german, edit the appropriate localization.lua file, and mail it to me at shagoth@gmail.com |
||
25 | + Bug reports can be made adding a comment, or sending me a PM or email at shagoth@gmail.com |
||
26 | |||
27 | |||
28 | History: |
||
29 | New in version 1.6.0: |
||
30 | - Added configurable tooltip for item list. |
||
31 | - Added Alt + right click to open QuestLog for an item. |
||
32 | |||
33 | New in version 1.5.3: |
||
34 | - Updated french language |
||
35 | |||
36 | New in version 1.5.2: |
||
37 | - Fixed RegisterForSave in 1.10 |
||
38 | |||
39 | New in version 1.5.1: |
||
40 | - Fixed a weird graphics issue with the item list. |
||
41 | - Resized the close button to fit the rectangle its placed inside |
||
42 | - Added version information in the item list |
||
43 | - Right click for pop-up on linked items in chat should be working |
||
44 | |||
45 | New in version 1.5.0: |
||
46 | - Sorting of items in the list. |
||
47 | - Fixed the placement of the caption for the config window |
||
48 | |||
49 | New in version 1.4.0: |
||
50 | - Support for EngInventory |
||
51 | |||
52 | New in version 1.3.5: |
||
53 | - Should work in the bank, even with Emerald UI |
||
54 | |||
55 | See older history in Changelog.txt |
||
56 | |||
57 | ]]-- |
||
58 | |||
59 | -- /script arg1="Dentrium-Kraftstein: 1/1"; QuestItem_OnEvent("DELETE"); arg1="Roon's Kodo Horn: 1/1"; QuestItem_OnEvent("UI_INFO_MESSAGE"); |
||
60 | -- /script arg1="Ragefire Shaman slain: 5/8"; QuestItem_OnEvent("UI_INFO_MESSAGE"); QuestItem_OnEvent("DELETE"); |
||
61 | -- /script arg1="Sent mail"; QuestItem_OnEvent("DELETE"); QuestItem_OnEvent("DELETE"); |
||
62 | |||
63 | DEBUG = false; |
||
64 | QI_CHANNEL_NAME = "QuestItem"; |
||
65 | |||
66 | -- QuestItem array |
||
67 | QuestItems = {}; |
||
68 | -- Settings |
||
69 | QuestItem_Settings = {}; |
||
70 | |||
71 | ---------------------------------------------------- |
||
72 | -- Updates the database with item and quest mappings |
||
73 | ---------------------------------------------------- |
||
74 | ---------------------------------------------------- |
||
75 | function QuestItem_UpdateItem(item, quest, count, total, status) |
||
76 | -- If item doesn't exist, add quest name and total item count to it |
||
77 | if(not QuestItems[item]) then |
||
78 | QuestItems[item] = {}; |
||
79 | QuestItems[item].QuestName = quest; |
||
80 | end |
||
81 | |||
82 | -- If old quest name was unidentified, save new name |
||
83 | if(QuestItem_SearchString(QuestItems[item].QuestName, QUESTITEM_UNIDENTIFIED) and not QuestItem_SearchString(quest, QuestItems[item].QuestName) ) then |
||
84 | QuestItems[item].QuestName = quest; |
||
85 | end |
||
86 | |||
87 | if(not QuestItems[item][UnitName("player")]) then |
||
88 | QuestItems[item][UnitName("player")] = {}; |
||
89 | end |
||
90 | |||
91 | -- Save total count |
||
92 | if(total ~= nil and QuestItem_CheckNumeric(total) ) then |
||
93 | QuestItems[item].Total = QuestItem_MakeIntFromHexString(total); |
||
94 | else |
||
95 | QuestItems[item].Total = 0; |
||
96 | end |
||
97 | |||
98 | -- Save item count |
||
99 | if(count ~= nil and QuestItem_CheckNumeric(count) ) then |
||
100 | QuestItems[item][UnitName("player")].Count = QuestItem_MakeIntFromHexString(count); |
||
101 | else |
||
102 | QuestItems[item][UnitName("player")].Count = 0; |
||
103 | end |
||
104 | |||
105 | QuestItems[item][UnitName("player")].QuestStatus = status; |
||
106 | end |
||
107 | |||
108 | ---------------------------------------------------------------------- |
||
109 | -- Find a quest based on item name |
||
110 | -- Returns: |
||
111 | -- QuestName - the name of the Quest. |
||
112 | -- Total - Total number of items required to complete it |
||
113 | -- Count - The number of items you have |
||
114 | -- Texture - Texture of the item |
||
115 | ---------------------------------------------------------------------- |
||
116 | ---------------------------------------------------------------------- |
||
117 | function QuestItem_FindQuest(item) |
||
118 | local total = 1; |
||
119 | local count = 0; |
||
120 | local texture = nil; |
||
121 | local itemName; |
||
122 | |||
123 | -- Iterate the quest log entries |
||
124 | for y=1, GetNumQuestLogEntries(), 1 do |
||
125 | local QuestName, level, questTag, isHeader, isCollapsed, complete = GetQuestLogTitle(y); |
||
126 | -- Don't check headers |
||
127 | if(not isHeader) then |
||
128 | SelectQuestLogEntry(y); |
||
129 | local QDescription, QObjectives = GetQuestLogQuestText(); |
||
130 | |||
131 | -- Find out if this item has already been mapped to a quest. |
||
132 | -- This is to to prevent any reset of the status for manually mapped items. |
||
133 | if(QuestItems[item] and (QuestItems[item].QuestName and QuestItems[item].QuestName == QuestName) ) then |
||
134 | QuestItem_UpdateItem(item, QuestName, count, total, 0) |
||
135 | return QuestName, total, count, texture; |
||
136 | end |
||
137 | |||
138 | -- Look for the item in quest leader boards |
||
139 | if (GetNumQuestLeaderBoards() > 0) then |
||
140 | -- Look for the item in leader boards |
||
141 | for i=1, GetNumQuestLeaderBoards(), 1 do --Objectives |
||
142 | --local str = getglobal("QuestLogObjective"..i); |
||
143 | local text, itemType, finished = GetQuestLogLeaderBoard(i); |
||
144 | -- Check if type is an item, and if the item is what we are looking for |
||
145 | --QuestItem_Debug("Item type: " ..itemType); |
||
146 | if(itemType ~= nil and (itemType == "item" or itemType == "object") ) then |
||
147 | if(QuestItem_SearchString(text, item)) then |
||
148 | local count = gsub(text,"(.*): (%d+)/(%d+)","%2"); |
||
149 | local total = gsub(text,"(.*): (%d+)/(%d+)","%3"); |
||
150 | QuestItem_Debug("Count: " ..count); |
||
151 | return QuestName, total, count, texture; |
||
152 | end |
||
153 | end |
||
154 | end |
||
155 | end |
||
156 | -- Look for the item in the objectives - no count and total will be returned |
||
157 | if(QuestItem_SearchString(QObjectives, item)) then |
||
158 | return QuestName, total, count, texture; |
||
159 | end |
||
160 | end |
||
161 | end |
||
162 | return nil, total, count, texture; |
||
163 | end |
||
164 | |||
165 | -------------------------------------------------------------------------------- |
||
166 | -- Check if there is a quest for the item. If it exists; update, if not, save it. |
||
167 | -------------------------------------------------------------------------------- |
||
168 | -------------------------------------------------------------------------------- |
||
169 | function QuestItem_LocateQuest(itemText, itemCount, itemTotal) |
||
170 | local QuestName, texture; |
||
171 | |||
172 | -- Only look through the questlog if the item has not already been mapped to a quest |
||
173 | if(not QuestItems[itemText] or QuestItems[itemText].QuestName == QUESTITEM_UNIDENTIFIED) then |
||
174 | QuestName, itemTotal, itemCount, texture = QuestItem_FindQuest(itemText); |
||
175 | else |
||
176 | QuestName = QuestItems[itemText].QuestName; |
||
177 | end |
||
178 | |||
179 | -- Update the QuestItems array |
||
180 | if(QuestName ~= nil) then |
||
181 | QuestItem_Debug("Found quest for " .. itemText .. ": " .. QuestName); |
||
182 | QuestItem_UpdateItem(itemText, QuestName, itemCount, itemTotal, 0); |
||
183 | elseif(QuestItem_Settings["Alert"]) then |
||
184 | QuestItem_PrintToScreen(QUESTITEM_CANTIDENTIFY .. itemText); |
||
185 | end |
||
186 | end |
||
187 | |||
188 | --------------- |
||
189 | -- OnLoad event |
||
190 | --------------- |
||
191 | --------------- |
||
192 | function QuestItem_OnLoad() |
||
193 | -- RegisterForSave("QuestItems"); |
||
194 | -- RegisterForSave("QuestItem_Settings"); |
||
195 | |||
196 | this:RegisterEvent("VARIABLES_LOADED"); |
||
197 | |||
198 | -- Register slash commands |
||
199 | SLASH_QUESTITEM1 = "/questitem"; |
||
200 | SLASH_QUESTITEM2 = "/qi"; |
||
201 | SlashCmdList["QUESTITEM"] = QuestItem_Config_OnCommand; |
||
202 | |||
203 | QuestItem_PrintToScreen(QUESTITEM_LOADED); |
||
204 | |||
205 | --QuestItem_Sky_OnLoad(); |
||
206 | QuestItem_HookTooltip(); |
||
207 | end |
||
208 | |||
209 | |||
210 | ----------------- |
||
211 | -- OnEvent method |
||
212 | ----------------- |
||
213 | ----------------- |
||
214 | function QuestItem_OnEvent(event) |
||
215 | if(event == "VARIABLES_LOADED") then |
||
216 | QuestItem_VariablesLoaded(); |
||
217 | this:UnregisterEvent("VARIABLES_LOADED"); |
||
218 | |||
219 | if(QuestItem_Settings["version"] and QuestItem_Settings["Enabled"] == true) then |
||
220 | this:RegisterEvent("UI_INFO_MESSAGE"); |
||
221 | end |
||
222 | return; |
||
223 | end |
||
224 | |||
225 | if(not arg1) then |
||
226 | return; |
||
227 | end |
||
228 | |||
229 | local itemText = gsub(arg1,"(.*): %d+/%d+","%1",1); |
||
230 | if(event == "UI_INFO_MESSAGE") then |
||
231 | local itemCount = gsub(arg1,"(.*): (%d+)/(%d+)","%2"); |
||
232 | local itemTotal = gsub(arg1,"(.*): (%d+)/(%d+)","%3"); |
||
233 | -- Ignore trade and duel events |
||
234 | if(itemText ~= arg1 and not strfind(itemText, QUESTITEM_SLAIN)) then |
||
235 | QuestItem_Debug("Looking for quest item "..itemText); |
||
236 | QuestItem_LocateQuest(itemText, itemCount, itemTotal); |
||
237 | end |
||
238 | elseif(event == "DELETE") then |
||
239 | if(QuestItems[itemText]) then |
||
240 | QuestItems[itemText] = nil; |
||
241 | QuestItem_Debug("Deleted"); |
||
242 | end |
||
243 | end |
||
244 | end |
||
245 | |||
246 | ------------------------------------ |
||
247 | -- Initialize settings if not found. |
||
248 | ------------------------------------ |
||
249 | ------------------------------------ |
||
250 | function QuestItem_VariablesLoaded() |
||
251 | if ( QuestItem_Settings and QuestItem_Settings["version"] == QUESTITEM_VERSION ) then |
||
252 | return; |
||
253 | end |
||
254 | |||
255 | if (not QuestItem_Settings) then |
||
256 | QuestItem_Settings = { }; |
||
257 | end |
||
258 | |||
259 | -- No settings exist |
||
260 | QuestItem_Settings["version"] = QUESTITEM_VERSION; |
||
261 | |||
262 | QuestItem_Settings["Enabled"] = true; |
||
263 | QuestItem_Settings["Alert"] = true; |
||
264 | -- Check if AxuItemMenus is installed |
||
265 | if(AxuItemMenus_AddTestHook) then |
||
266 | QuestItem_Settings["DisplayRequest"] = false; |
||
267 | else |
||
268 | QuestItem_Settings["DisplayRequest"] = false; |
||
269 | end |
||
270 | QuestItem_Settings["ShiftOpen"] = false; |
||
271 | QuestItem_Settings["AltOpen"] = true; |
||
272 | end |
||
273 | |||
274 | |||
275 | --------------- |
||
276 | --------------- |
||
277 | --------------- |
||
278 | -- FUNCTIONS -- |
||
279 | --------------- |
||
280 | --------------- |
||
281 | --------------- |
||
282 | |||
283 | |||
284 | -- Print debug message to the default chatframe. |
||
285 | -- Only works if the DEBUG variable in the |
||
286 | -- beginning of QuestItem.lua is set to true. |
||
287 | ------------------------------------------------ |
||
288 | ------------------------------------------------ |
||
289 | function QuestItem_Debug(message) |
||
290 | if(DEBUG) then |
||
291 | if(not message) then |
||
292 | DEFAULT_CHAT_FRAME:AddMessage("Debug: Message was nil", 0.9, 0.5, 0.3); |
||
293 | else |
||
294 | DEFAULT_CHAT_FRAME:AddMessage("Debug: " ..message, 0.9, 0.5, 0.3); |
||
295 | end |
||
296 | end |
||
297 | end |
||
298 | |||
299 | function QuestItem_PrintToScreen(message) |
||
300 | UIErrorsFrame:AddMessage(message, 0.4, 0.5, 0.8, 1.0, 8); |
||
301 | end |
||
302 | |||
303 | --------------------------------------------------- |
||
304 | -- Find out if an item is a quest item by searching |
||
305 | -- the text in the tooltip. |
||
306 | --------------------------------------------------- |
||
307 | --------------------------------------------------- |
||
308 | function QuestItem_IsQuestItem(tooltip) |
||
309 | if(tooltip) then |
||
310 | local tooltip = getglobal(tooltip:GetName() .. "TextLeft"..2); |
||
311 | if(tooltip and tooltip:GetText()) then |
||
312 | if(QuestItem_SearchString(tooltip:GetText(), QUESTITEM_QUESTITEM)) then |
||
313 | return true; |
||
314 | end |
||
315 | end |
||
316 | end |
||
317 | return false; |
||
318 | end |
||
319 | |||
320 | -------------------------------------------- |
||
321 | -- Open the specified quest in the quest log |
||
322 | -------------------------------------------- |
||
323 | -------------------------------------------- |
||
324 | function QuestItem_OpenQuestLog(questName) |
||
325 | for y=1, GetNumQuestLogEntries(), 1 do |
||
326 | local QuestName, level, questTag, isHeader, isCollapsed, complete = GetQuestLogTitle(y); |
||
327 | if(questName == QuestName) then |
||
328 | SelectQuestLogEntry(y); |
||
329 | local logFrame = getglobal("QuestLogFrame"); |
||
330 | |||
331 | if(logFrame ~= nil) then |
||
332 | if(logFrame:IsVisible()) then |
||
333 | ToggleQuestLog(); |
||
334 | end |
||
335 | if(QuestLog_SetSelection == nil) then |
||
336 | QuestLog_SetSelection(y); |
||
337 | end |
||
338 | ToggleQuestLog(); |
||
339 | end |
||
340 | return; |
||
341 | end |
||
342 | end |
||
343 | QuestItem_PrintToScreen(QUESTITEM_NO_QUEST); |
||
344 | end |
||
345 | |||
346 | --------------------------------------- |
||
347 | -- Look for the item in the text string |
||
348 | --------------------------------------- |
||
349 | --------------------------------------- |
||
350 | function QuestItem_SearchString(text, item) |
||
351 | if(string.find(string.lower(text), string.lower(item)) ) then |
||
352 | return true; |
||
353 | end |
||
354 | return false; |
||
355 | end |
||
356 | |||
357 | -- Copied functions - don't want to depend on too many AddOns |
||
358 | |||
359 | -- From LootLink |
||
360 | function QuestItem_MakeIntFromHexString(str) |
||
361 | if(not str) then |
||
362 | return 0; |
||
363 | end |
||
364 | local remain = str; |
||
365 | local amount = 0; |
||
366 | while( remain ~= "" ) do |
||
367 | amount = amount * 10; |
||
368 | local byteVal = string.byte(strupper(strsub(remain, 1, 1))); |
||
369 | if( byteVal >= string.byte("0") and byteVal <= string.byte("9") ) then |
||
370 | amount = amount + (byteVal - string.byte("0")); |
||
371 | end |
||
372 | remain = strsub(remain, 2); |
||
373 | end |
||
374 | return amount; |
||
375 | end |
||
376 | |||
377 | function QuestItem_CheckNumeric(string) |
||
378 | local remain = string; |
||
379 | local hasNumber; |
||
380 | local hasPeriod; |
||
381 | local char; |
||
382 | |||
383 | while( remain ~= "" and remain ~= nil) do |
||
384 | --while( remain ~= "") do |
||
385 | char = strsub(remain, 1, 1); |
||
386 | if( char >= "0" and char <= "9" ) then |
||
387 | hasNumber = 1; |
||
388 | elseif( char == "." and not hasPeriod ) then |
||
389 | hasPeriod = 1; |
||
390 | else |
||
391 | return nil; |
||
392 | end |
||
393 | remain = strsub(remain, 2); |
||
394 | end |
||
395 | |||
396 | return hasNumber; |
||
397 | end |
||
398 | |||
399 | -- From Sea |
||
400 | function QuestItem_ScanTooltip() |
||
401 | local tooltipBase = "GameTooltip"; |
||
402 | local strings = {}; |
||
403 | for idx = 1, 10 do |
||
404 | local textLeft = nil; |
||
405 | local textRight = nil; |
||
406 | ttext = getglobal(tooltipBase.."TextLeft"..idx); |
||
407 | if(ttext and ttext:IsVisible() and ttext:GetText() ~= nil) |
||
408 | then |
||
409 | textLeft = ttext:GetText(); |
||
410 | end |
||
411 | ttext = getglobal(tooltipBase.."TextRight"..idx); |
||
412 | if(ttext and ttext:IsVisible() and ttext:GetText() ~= nil) |
||
413 | then |
||
414 | textRight = ttext:GetText(); |
||
415 | end |
||
416 | if (textLeft or textRight) |
||
417 | then |
||
418 | strings[idx] = {}; |
||
419 | strings[idx].left = textLeft; |
||
420 | strings[idx].right = textRight; |
||
421 | end |
||
422 | end |
||
423 | |||
424 | return strings; |
||
425 | end |