vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | --------------------------------------------------------------------------------------------------- |
2 | -- Name: QuestieNotes |
||
3 | -- Description: Handles all the quest map notes |
||
4 | --------------------------------------------------------------------------------------------------- |
||
5 | --///////////////////////////////////////////////////////////////////////////////////////////////-- |
||
6 | --------------------------------------------------------------------------------------------------- |
||
7 | -- Local Vars |
||
8 | --------------------------------------------------------------------------------------------------- |
||
9 | local AllFrames = {}; |
||
10 | local FramePool = {}; |
||
11 | local Cluster = {}; |
||
12 | local LastContinent = nil; |
||
13 | local LastZone = nil; |
||
14 | local Dewdrop = AceLibrary("Dewdrop-2.0"); |
||
15 | local specialSources = { ["openedby"] = 1, }; |
||
16 | local QGet_QuestLogTitle = GetQuestLogTitle; |
||
17 | local QGet_NumQuestLeaderBoards = GetNumQuestLeaderBoards; |
||
18 | local QSelect_QuestLogEntry = SelectQuestLogEntry; |
||
19 | local QGet_QuestLogLeaderBoard = GetQuestLogLeaderBoard; |
||
20 | local QGet_QuestLogQuestText = GetQuestLogQuestText; |
||
21 | local QGet_TitleText = GetTitleText; |
||
22 | local QGet_QuestLogSelection = GetQuestLogSelection; |
||
23 | --------------------------------------------------------------------------------------------------- |
||
24 | -- Global Vars |
||
25 | --------------------------------------------------------------------------------------------------- |
||
26 | QUESTIE_NOTES_MAP_ICON_SCALE = 1.2; |
||
27 | QUESTIE_NOTES_WORLD_MAP_ICON_SCALE = 0.75; |
||
28 | QUESTIE_NOTES_CONTINENT_ICON_SCALE = 1; |
||
29 | QUESTIE_NOTES_MINIMAP_ICON_SCALE = 1.0; |
||
30 | QuestieMapNotes = {}; |
||
31 | QuestieUsedNoteFrames = {}; |
||
32 | QuestieHandledQuests = {}; |
||
33 | QuestieAvailableMapNotes = {}; |
||
34 | QuestieCachedMonstersAndObjects = {}; |
||
35 | Questie_LastTooltip = GetTime(); |
||
36 | QUESTIE_DEBUG_TOOLTIP = nil; |
||
37 | Questie_TooltipCache = {}; |
||
38 | CREATED_NOTE_FRAMES = 1; |
||
39 | INIT_POOL_SIZE = 11; |
||
40 | Cluster.__index = Cluster; |
||
41 | __TT_LineCache = {}; |
||
42 | UIOpen = false; |
||
43 | QuestieNotes = AceLibrary("AceAddon-2.0"):new("AceHook-2.1") |
||
44 | --------------------------------------------------------------------------------------------------- |
||
45 | --Setup Hooks |
||
46 | --------------------------------------------------------------------------------------------------- |
||
47 | function QuestieNotes:OnInitialize() |
||
48 | self:Hook(WorldMapFrame, "Show", "WorldMapFrame_Show", true) |
||
49 | self:Hook(WorldMapFrame, "SetAlpha", "WorldMapFrame_SetAlpha", true) |
||
50 | end |
||
51 | --------------------------------------------------------------------------------------------------- |
||
52 | -- Refreshes Quest Notes |
||
53 | --------------------------------------------------------------------------------------------------- |
||
54 | function Questie:RefreshQuestNotes() |
||
55 | QUESTIE_UPDATE_EVENT = 1; |
||
56 | if (GetTime() - QUESTIE_LAST_SYNCLOG > 0.1) then |
||
57 | Questie:AddEvent("SYNCLOG", 0); |
||
58 | QUESTIE_LAST_SYNCLOG = GetTime(); |
||
59 | else |
||
60 | QUESTIE_LAST_SYNCLOG = GetTime(); |
||
61 | end |
||
62 | if (GetTime() - QUESTIE_LAST_DRAWNOTES > 0.1) then |
||
63 | Questie:AddEvent("DRAWNOTES", 0.2); |
||
64 | QUESTIE_LAST_DRAWNOTES = GetTime(); |
||
65 | else |
||
66 | QUESTIE_LAST_DRAWNOTES = GetTime(); |
||
67 | end |
||
68 | if (GetTime() - QUESTIE_LAST_TRACKER > 0.1) then |
||
69 | Questie:AddEvent("TRACKER", 0.4); |
||
70 | QUESTIE_LAST_TRACKER = GetTime(); |
||
71 | else |
||
72 | QUESTIE_LAST_TRACKER = GetTime(); |
||
73 | end |
||
74 | end |
||
75 | --------------------------------------------------------------------------------------------------- |
||
76 | -- Adds quest notes to map |
||
77 | --------------------------------------------------------------------------------------------------- |
||
78 | function Questie:AddQuestToMap(questHash, redraw) |
||
79 | if(IsQuestieActive == false) then return; end |
||
80 | if questHash == -1 then return; end |
||
81 | --Questie:debug_Print("Notes:AddQuestToMap --> Adding Quest to Map [Hash: "..questHash.."]"); |
||
82 | local c, z = GetCurrentMapContinent(), GetCurrentMapZone(); |
||
83 | Questie:RemoveQuestFromMap(questHash); |
||
84 | local objectives = Questie:GetQuestObjectivePaths(questHash) |
||
85 | --Cache code |
||
86 | local ques = {}; |
||
87 | ques["noteHandles"] = {}; |
||
88 | UsedContinents = {}; |
||
89 | UsedZones = {}; |
||
90 | local Quest = Questie:IsQuestFinished(questHash); |
||
91 | if not (Quest) then |
||
92 | Questie:debug_Print("Notes:AddQuestToMap --> Display Objective Icons: [Hash: "..questHash.."]"); |
||
93 | for objectiveid, objective in pairs(objectives) do |
||
94 | if not objective.done then |
||
95 | local typeToIcon = { |
||
96 | ["item"] = "loot", |
||
97 | ["event"] = "event", |
||
98 | ["monster"] = "slay", |
||
99 | ["object"] = "object", |
||
100 | }; |
||
101 | local defaultIcon = typeToIcon[objective.type]; |
||
102 | local iconMeta = { |
||
103 | ["defaultIcon"] = defaultIcon |
||
104 | }; |
||
105 | Questie:RecursiveCreateNotes(c, z, questHash, objective.path, iconMeta, objectiveid); |
||
106 | end |
||
107 | end |
||
108 | else |
||
109 | --Questie:debug_Print("Notes:AddQuestToMap --> Display Finished Quest Icon: [Hash: "..questHash.."]"); |
||
110 | local addedNote = false |
||
111 | local questInfo = QuestieHashMap[Quest.questHash]; |
||
112 | if questInfo ~= nil then |
||
113 | local typeFunctions = { |
||
114 | ['monster'] = GetMonsterLocations, |
||
115 | ['object'] = GetObjectLocations, |
||
116 | ['unknown'] = function() return nil; end |
||
117 | }; |
||
118 | local typeFunction = typeFunctions[questInfo.finishedType]; |
||
119 | local finishPath = typeFunction(questInfo.finishedBy); |
||
120 | if finishPath == nil or (not next(finishPath)) then |
||
121 | finishPath = typeFunction(QuestieFinishers[Quest.name]); |
||
122 | end |
||
123 | if(finishPath) then |
||
124 | local locations = Questie:RecursiveGetPathLocations(finishPath); |
||
125 | if next(locations) then |
||
126 | for i, location in pairs(locations) do |
||
127 | local c, z, x, y = location[1], location[2], location[3], location[4]; |
||
128 | Questie:AddNoteToMap(c, z, x, y, "complete", questHash, 0); |
||
129 | addedNote = true |
||
130 | end |
||
131 | end |
||
132 | end |
||
133 | end |
||
134 | if addedNote == false then |
||
135 | Questie:debug_Print("AddQuestToMap: ERROR Quest broken! ", Quest["name"], questHash, "report on github!") |
||
136 | end |
||
137 | end |
||
138 | --Cache code |
||
139 | ques["objectives"] = objectives; |
||
140 | QuestieHandledQuests[questHash] = ques; |
||
141 | if (redraw) then |
||
142 | Questie:debug_Print("Notes:AddQuestToMap: redraw VAR true --> Questie:RefreshQuestStatus();"); |
||
143 | Questie:RefreshQuestNotes(); |
||
144 | end |
||
145 | end |
||
146 | --------------------------------------------------------------------------------------------------- |
||
147 | -- Checks for a quest note in QuestieMapNotes |
||
148 | --------------------------------------------------------------------------------------------------- |
||
149 | function Questie:CheckQuestNote(questHash) |
||
150 | for continent, zoneTable in pairs(QuestieMapNotes) do |
||
151 | for index, zone in pairs(zoneTable) do |
||
152 | for i, note in pairs(zone) do |
||
153 | if (note.questHash == questHash) then |
||
154 | return true |
||
155 | end |
||
156 | end |
||
157 | end |
||
158 | end |
||
159 | return false |
||
160 | end |
||
161 | --------------------------------------------------------------------------------------------------- |
||
162 | -- Updates quest notes on map |
||
163 | --------------------------------------------------------------------------------------------------- |
||
164 | function Questie:UpdateQuestNotes(questHash, redraw) |
||
165 | if not QuestieHandledQuests[questHash] then |
||
166 | --Questie:debug_Print("UpdateQuestNotes: ERROR! Tried updating a quest not handled. Hash: ", questHash); |
||
167 | return; |
||
168 | end |
||
169 | local prevQuestLogSelection = QGet_QuestLogSelection() |
||
170 | local QuestLogID = Questie:GetQuestIdFromHash(questHash); |
||
171 | QSelect_QuestLogEntry(QuestLogID); |
||
172 | local q, level, questTag, isHeader, isCollapsed, isComplete = QGet_QuestLogTitle(QuestLogID); |
||
173 | local count = QGet_NumQuestLeaderBoards(); |
||
174 | local questText, objectiveText = QGet_QuestLogQuestText(); |
||
175 | for k, noteInfo in pairs(QuestieHandledQuests[questHash]["noteHandles"]) do |
||
176 | for id, note in pairs(QuestieMapNotes[noteInfo.c][noteInfo.z]) do |
||
177 | if(note.questHash == questHash) then |
||
178 | local desc, typ, done = QGet_QuestLogLeaderBoard(note.objectiveid); |
||
179 | --Questie:debug_Print("UpdateQuestNotes: Desc: "..tostring(desc).." Type: "..tostring(typ).." Done: "..tostring(done)); |
||
180 | end |
||
181 | end |
||
182 | end |
||
183 | QSelect_QuestLogEntry(prevQuestLogSelection) |
||
184 | if(redraw) then |
||
185 | Questie:debug_Print("Notes:UpdateQuestNotes: redraw VAR true --> Questie:RefreshQuestStatus();"); |
||
186 | Questie:RefreshQuestNotes(); |
||
187 | end |
||
188 | end |
||
189 | --------------------------------------------------------------------------------------------------- |
||
190 | -- Remove quest note from map |
||
191 | --------------------------------------------------------------------------------------------------- |
||
192 | function Questie:RemoveQuestFromMap(questHash, redraw) |
||
193 | local removed = false; |
||
194 | for continent, zoneTable in pairs(QuestieMapNotes) do |
||
195 | for index, zone in pairs(zoneTable) do |
||
196 | for i, note in pairs(zone) do |
||
197 | if(note.questHash == questHash) then |
||
198 | QuestieMapNotes[continent][index][i] = nil; |
||
199 | removed = true; |
||
200 | end |
||
201 | end |
||
202 | end |
||
203 | end |
||
204 | if(redraw) then |
||
205 | Questie:debug_Print("Notes:RemoveQuestFromMap: redraw VAR true --> Questie:RefreshQuestStatus();"); |
||
206 | Questie:RefreshQuestNotes(); |
||
207 | end |
||
208 | if(QuestieHandledQuests[questHash]) then |
||
209 | QuestieHandledQuests[questHash] = nil; |
||
210 | end |
||
211 | end |
||
212 | --------------------------------------------------------------------------------------------------- |
||
213 | function Questie:GetMapInfoFromID(id) |
||
214 | return QuestieZoneIDLookup[id]; |
||
215 | end |
||
216 | --------------------------------------------------------------------------------------------------- |
||
217 | -- Add quest note to map |
||
218 | --------------------------------------------------------------------------------------------------- |
||
219 | function Questie:AddNoteToMap(continent, zoneid, posx, posy, type, questHash, objectiveid, path) |
||
220 | if (not type == "complete") then |
||
221 | return; |
||
222 | end |
||
223 | if(QuestieMapNotes[continent] == nil) then |
||
224 | QuestieMapNotes[continent] = {}; |
||
225 | end |
||
226 | if(QuestieMapNotes[continent][zoneid] == nil) then |
||
227 | QuestieMapNotes[continent][zoneid] = {}; |
||
228 | end |
||
229 | Note = {}; |
||
230 | Note.x = posx; |
||
231 | Note.y = posy; |
||
232 | Note.zoneid = zoneid; |
||
233 | Note.continent = continent; |
||
234 | Note.icontype = type; |
||
235 | Note.questHash = questHash; |
||
236 | Note.objectiveid = objectiveid; |
||
237 | Note.path = path |
||
238 | table.insert(QuestieMapNotes[continent][zoneid], Note); |
||
239 | end |
||
240 | --------------------------------------------------------------------------------------------------- |
||
241 | -- Add available quest note to map |
||
242 | --------------------------------------------------------------------------------------------------- |
||
243 | function Questie:AddAvailableNoteToMap(continent, zoneid, posx, posy, type, questHash, objectiveid, path) |
||
244 | --This is to set up the variables |
||
245 | if(QuestieAvailableMapNotes[continent] == nil) then |
||
246 | QuestieAvailableMapNotes[continent] = {}; |
||
247 | end |
||
248 | if(QuestieAvailableMapNotes[continent][zoneid] == nil) then |
||
249 | QuestieAvailableMapNotes[continent][zoneid] = {}; |
||
250 | end |
||
251 | --Sets values that i want to use for the notes THIS IS WIP MORE INFO MAY BE NEDED BOTH IN PARAMETERS AND NOTES!!! |
||
252 | Note = {}; |
||
253 | Note.x = posx; |
||
254 | Note.y = posy; |
||
255 | Note.zoneid = zoneid; |
||
256 | Note.continent = continent; |
||
257 | Note.icontype = type; |
||
258 | Note.questHash = questHash; |
||
259 | Note.objectiveid = objectiveid; |
||
260 | Note.path = path |
||
261 | --Inserts it into the right zone and continent for later use. |
||
262 | table.insert(QuestieAvailableMapNotes[continent][zoneid], Note); |
||
263 | end |
||
264 | --------------------------------------------------------------------------------------------------- |
||
265 | -- Gets a blank frame either from Pool or creates a new one! |
||
266 | --------------------------------------------------------------------------------------------------- |
||
267 | function Questie:GetBlankNoteFrame(frame) |
||
268 | if(table.getn(FramePool)==0) then |
||
269 | Questie:CreateBlankFrameNote(frame); |
||
270 | end |
||
271 | f = FramePool[1]; |
||
272 | table.remove(FramePool, 1); |
||
273 | return f; |
||
274 | end |
||
275 | --------------------------------------------------------------------------------------------------- |
||
276 | -- Hook World Map Events |
||
277 | --------------------------------------------------------------------------------------------------- |
||
278 | function QuestieNotes:SetAllNoteFramesAlpha() |
||
279 | for i,v in ipairs({WorldMapFrame:GetChildren()}) do |
||
280 | if v:GetName() and string.find(v:GetName(), "^QuestieNoteFrame") then |
||
281 | v:SetAlpha(1) |
||
282 | end |
||
283 | end |
||
284 | end |
||
285 | |||
286 | function QuestieNotes:WorldMapFrame_Show(this) |
||
287 | self.hooks[this].Show(this) |
||
288 | QuestieNotes:SetAllNoteFramesAlpha() |
||
289 | end |
||
290 | |||
291 | function QuestieNotes:WorldMapFrame_SetAlpha(this, alpha) |
||
292 | self.hooks[this].SetAlpha(this, alpha) |
||
293 | QuestieNotes:SetAllNoteFramesAlpha() |
||
294 | end |
||
295 | --------------------------------------------------------------------------------------------------- |
||
296 | -- Hook Tooltip |
||
297 | --------------------------------------------------------------------------------------------------- |
||
298 | function Questie:hookTooltip() |
||
299 | local f = GameTooltip:GetScript("OnShow"); |
||
300 | --Proper tooltip hooking! |
||
301 | if not f then |
||
302 | GameTooltip:SetScript("OnShow", function(self) |
||
303 | Questie:Tooltip(self, true); |
||
304 | end) |
||
305 | end |
||
306 | local Blizz_GameTooltip_Show = GameTooltip.Show; |
||
307 | GameTooltip.Show = function(self) |
||
308 | Questie:Tooltip(self); |
||
309 | Blizz_GameTooltip_Show(self); |
||
310 | end |
||
311 | local Bliz_GameTooltip_SetLootItem = GameTooltip.SetLootItem; |
||
312 | GameTooltip.SetLootItem = function(self, slot) |
||
313 | Bliz_GameTooltip_SetLootItem(self, slot); |
||
314 | Questie:Tooltip(self, true); |
||
315 | end |
||
316 | local index = self:GetID(); |
||
317 | local Bliz_GameTooltip_SetQuestLogItem = GameTooltip.SetQuestLogItem; |
||
318 | GameTooltip.SetQuestLogItem = function(self, type, index) |
||
319 | local link = GetQuestLogItemLink(type, index); |
||
320 | if link then |
||
321 | Bliz_GameTooltip_SetQuestLogItem(self, type, index); |
||
322 | end |
||
323 | end |
||
324 | end |
||
325 | --------------------------------------------------------------------------------------------------- |
||
326 | -- Tooltip code for quest objects |
||
327 | --------------------------------------------------------------------------------------------------- |
||
328 | function Questie:hookTooltipLineCheck() |
||
329 | local oh = GameTooltip:GetScript("OnHide"); |
||
330 | GameTooltip:SetScript("OnHide", function(self, arg) |
||
331 | if oh then |
||
332 | oh(self, arg); |
||
333 | end |
||
334 | __TT_LineCache = {}; |
||
335 | end) |
||
336 | GameTooltip.AddLine_orig = GameTooltip.AddLine; |
||
337 | GameTooltip.AddLine = function(self, line, r, g, b, wrap, lineNumber) |
||
338 | GameTooltip:AddLine_orig(line, r, g, b, wrap); |
||
339 | if (line) then |
||
340 | if lineNumber == nil then lineNumber = 1; end |
||
341 | __TT_LineCache[lineNumber] = {}; |
||
342 | __TT_LineCache[lineNumber][line] = true; |
||
343 | end |
||
344 | end |
||
345 | end |
||
346 | --------------------------------------------------------------------------------------------------- |
||
347 | function Questie:Tooltip(this, forceShow, bag, slot) |
||
348 | if (QuestieConfig.showToolTips == false) then return end |
||
349 | |||
350 | -- Don't show detailed tooltip for questie minimap icons |
||
351 | local owner = GameTooltip.owner |
||
352 | if owner and owner.type == "MiniMapNote" then return end |
||
353 | |||
354 | local monster = UnitName("mouseover") |
||
355 | local objective = GameTooltipTextLeft1:GetText() |
||
356 | local cacheKey = ""-- .. monster .. objective |
||
357 | local validKey = false |
||
358 | if(monster) then |
||
359 | cacheKey = cacheKey .. monster |
||
360 | validKey = true |
||
361 | end |
||
362 | if(objective) then |
||
363 | cacheKey = cacheKey .. objective |
||
364 | validKey = true |
||
365 | end |
||
366 | if not validKey then |
||
367 | return |
||
368 | end |
||
369 | local reaction = UnitReaction("mouseover", "player") |
||
370 | local unitColorRGB = Questie:GetReactionColor(reaction) |
||
371 | local unitColor = "ff"..fRGBToHex(unitColorRGB.r, unitColorRGB.g, unitColorRGB.b) |
||
372 | if (Questie_TooltipCache[cacheKey] == nil) or (QUESTIE_LAST_UPDATE_FINISHED - Questie_TooltipCache[cacheKey]['updateTime']) > 0 then |
||
373 | -- Create or Update Tooltip Cache |
||
374 | Questie_TooltipCache[cacheKey] = {} |
||
375 | Questie_TooltipCache[cacheKey]['lines'] = {} |
||
376 | Questie_TooltipCache[cacheKey]['lineCount'] = 1 |
||
377 | Questie_TooltipCache[cacheKey]['updateTime'] = GetTime() |
||
378 | local prevQuestLogSelection = QGet_QuestLogSelection() |
||
379 | for questHash, quest in pairs(QuestieHandledQuests) do |
||
380 | local QuestLogID = Questie:GetQuestIdFromHash(questHash) |
||
381 | QSelect_QuestLogEntry(QuestLogID) |
||
382 | local drawnQuestTitle = false |
||
383 | for objectiveid, objectiveInfo in pairs(quest.objectives) do |
||
384 | local highlightInfo = { |
||
385 | ["text"] = objective, |
||
386 | ["color"] = unitColor |
||
387 | } |
||
388 | local sourceNames = Questie:RecursiveGetSourceNamesFromRawPath(objectiveInfo.path) |
||
389 | if objectiveInfo.name == objective or sourceNames[objective] then |
||
390 | local lineIndex = Questie_TooltipCache[cacheKey]['lineCount'] |
||
391 | if drawnQuestTitle == false then |
||
392 | local questInfo = QuestieHashMap[questHash] |
||
393 | local colorString = "|c" .. QuestieTracker:GetDifficultyColor(questInfo.questLevel) |
||
394 | local title = colorString |
||
395 | title = title .. "[" .. questInfo.questLevel .. "] " |
||
396 | title = title .. questInfo.name .. "|r" |
||
397 | Questie_TooltipCache[cacheKey]['lines'][lineIndex] = { |
||
398 | ['color'] = {1,1,1}, |
||
399 | ['data'] = " " |
||
400 | } |
||
401 | lineIndex = lineIndex + 1 |
||
402 | Questie_TooltipCache[cacheKey]['lines'][lineIndex] = { |
||
403 | ['color'] = {1,1,1}, |
||
404 | ['data'] = title, |
||
405 | ['wrap'] = false |
||
406 | } |
||
407 | lineIndex = lineIndex + 1 |
||
408 | drawnQuestTitle = true |
||
409 | end |
||
410 | local desc, type, done = QGet_QuestLogLeaderBoard(objectiveid) |
||
411 | if done then |
||
412 | Questie_TooltipCache[cacheKey]['lines'][lineIndex] = { |
||
413 | ['color'] = {0.2,1,0.3}, |
||
414 | ['data'] = desc, |
||
415 | ['wrap'] = false |
||
416 | } |
||
417 | lineIndex = lineIndex + 1 |
||
418 | Questie_TooltipCache[cacheKey]['lineCount'] = lineIndex |
||
419 | else |
||
420 | local objectivePath = deepcopy(objectiveInfo.path) |
||
421 | Questie:PostProcessIconPath(objectivePath) |
||
422 | local lines = Questie:GetTooltipLines(objectivePath, 1, highlightInfo) |
||
423 | desc = string.gsub(desc, objective, "|c"..unitColor..objective.."|r") |
||
424 | Questie_TooltipCache[cacheKey]['lines'][lineIndex] = { |
||
425 | ['color'] = {1,1,1}, |
||
426 | ['data'] = desc, |
||
427 | ['wrap'] = false |
||
428 | } |
||
429 | lineIndex = lineIndex + 1 |
||
430 | for i, line in pairs(lines) do |
||
431 | Questie_TooltipCache[cacheKey]['lines'][lineIndex] = { |
||
432 | ['color'] = {1,1,1}, |
||
433 | ['data'] = line |
||
434 | } |
||
435 | lineIndex = lineIndex + 1 |
||
436 | end |
||
437 | Questie_TooltipCache[cacheKey]['lineCount'] = lineIndex |
||
438 | end |
||
439 | end |
||
440 | end |
||
441 | end |
||
442 | QSelect_QuestLogEntry(prevQuestLogSelection) |
||
443 | end |
||
444 | for k, v in pairs(Questie_TooltipCache[cacheKey]['lines']) do |
||
445 | if (not __TT_LineCache[k]) or (not __TT_LineCache[k][v['data']]) then |
||
446 | local wrap = v['wrap'] |
||
447 | if wrap == nil then wrap = true end |
||
448 | GameTooltip:AddLine(v['data'], v['color'][1], v['color'][2], v['color'][3], wrap, k) |
||
449 | end |
||
450 | end |
||
451 | if(QUESTIE_DEBUG_TOOLTIP) then |
||
452 | GameTooltip:AddLine("--Questie hook--") |
||
453 | end |
||
454 | if(forceShow) then |
||
455 | GameTooltip:Show() |
||
456 | end |
||
457 | GameTooltip.QuestieDone = true |
||
458 | Questie_LastTooltip = GetTime() |
||
459 | --Questie_TooltipCache = {} |
||
460 | mi = nil |
||
461 | end |
||
462 | --------------------------------------------------------------------------------------------------- |
||
463 | -- Tooltip code for quest starters and finishers |
||
464 | --------------------------------------------------------------------------------------------------- |
||
465 | function Questie:GetTooltipLines(path, indent, highlightInfo, lines) |
||
466 | if lines == nil then lines = {} end |
||
467 | local indentString = ""; |
||
468 | for i=1,indent,1 do |
||
469 | indentString = indentString.." "; |
||
470 | end |
||
471 | if path["contained_id"] then path["contained"] = nil; end |
||
472 | for sourceType, sources in pairs(path) do |
||
473 | local prefix; |
||
474 | if sourceType == "drop" then |
||
475 | prefix = "Dropped by"; |
||
476 | elseif sourceType == "rewardedby" then |
||
477 | prefix = "Awarded by"; |
||
478 | elseif sourceType == "contained" then |
||
479 | prefix = "Contained in"; |
||
480 | elseif sourceType == "contained_id" then |
||
481 | prefix = "Contained in"; |
||
482 | elseif sourceType == "containedi" then |
||
483 | prefix = "Opened in"; |
||
484 | elseif sourceType == "created" then |
||
485 | prefix = "Created by"; |
||
486 | elseif sourceType == "openedby" then |
||
487 | prefix = "Opened by"; |
||
488 | elseif sourceType == "transforms" then |
||
489 | prefix = "Used on"; |
||
490 | elseif sourceType == "transformedby" then |
||
491 | prefix = "Created by"; |
||
492 | end |
||
493 | if prefix then |
||
494 | for sourceName, sourcePath in pairs(sources) do |
||
495 | local splitNames = Questie:SplitString(sourceName, ", "); |
||
496 | local combinedNames = ""; |
||
497 | local countDown = table.getn(splitNames); |
||
498 | for i, name in pairs(splitNames) do |
||
499 | if i <= 5 or (highlightInfo ~= nil and name == highlightInfo.text) then |
||
500 | if i > 1 then combinedNames = combinedNames..", "; end |
||
501 | if highlightInfo ~= nil and name == highlightInfo.text then |
||
502 | combinedNames = combinedNames.."|r|c"..highlightInfo.color..name.."|r|cFFa6a6a6"; |
||
503 | else |
||
504 | combinedNames = combinedNames..name; |
||
505 | end |
||
506 | countDown = countDown - 1; |
||
507 | end |
||
508 | end |
||
509 | if countDown > 0 then |
||
510 | combinedNames = combinedNames.." and "..countDown.." more..."; |
||
511 | end |
||
512 | table.insert(lines, indentString..prefix..": |cFFa6a6a6"..combinedNames.."|r"); |
||
513 | Questie:GetTooltipLines(sourcePath, indent+1, highlightInfo, lines, sourceNames); |
||
514 | end |
||
515 | end |
||
516 | end |
||
517 | return lines |
||
518 | end |
||
519 | --------------------------------------------------------------------------------------------------- |
||
520 | function Questie:AddPathToTooltip(Tooltip, path, indent) |
||
521 | local lines = Questie:GetTooltipLines(path, indent); |
||
522 | for i, line in pairs(lines) do |
||
523 | Tooltip:AddLine(line,1,1,1,true); |
||
524 | end |
||
525 | end |
||
526 | --------------------------------------------------------------------------------------------------- |
||
527 | function Questie_Tooltip_OnEnter() |
||
528 | if(this.data.questHash) then |
||
529 | local Tooltip = GameTooltip; |
||
530 | if(this.type == "WorldMapNote") then |
||
531 | Tooltip = WorldMapTooltip; |
||
532 | else |
||
533 | Tooltip = GameTooltip; |
||
534 | end |
||
535 | Tooltip:SetOwner(this, this); |
||
536 | Tooltip.owner = this |
||
537 | local count = 0; |
||
538 | local canManualComplete = 0; |
||
539 | local orderedQuests = {}; |
||
540 | for questHash, questMeta in pairs(this.quests) do |
||
541 | orderedQuests[questMeta['sortOrder']] = questMeta; |
||
542 | end |
||
543 | local prevQuestLogSelection = QGet_QuestLogSelection(); |
||
544 | for i, questMeta in pairs(orderedQuests) do |
||
545 | local data = questMeta['quest']; |
||
546 | count = count + 1; |
||
547 | if (count > 1) then |
||
548 | Tooltip:AddLine(" "); |
||
549 | end |
||
550 | if(data.icontype ~= "available" and data.icontype ~= "availablesoon") then |
||
551 | local Quest = Questie:IsQuestFinished(data.questHash); |
||
552 | if not Quest then |
||
553 | local QuestLogID = Questie:GetQuestIdFromHash(data.questHash); |
||
554 | if QuestLogID then |
||
555 | QSelect_QuestLogEntry(QuestLogID); |
||
556 | local q, level, questTag, isHeader, isCollapsed, isComplete = QGet_QuestLogTitle(QuestLogID); |
||
557 | Tooltip:AddLine(q); |
||
558 | for objectiveid, objectivePath in pairs(questMeta['objectives']) do |
||
559 | local objectiveName; |
||
560 | if type(objectiveid) == "string" then |
||
561 | objectiveName = objectiveid; |
||
562 | else |
||
563 | local desc, typ, done = QGet_QuestLogLeaderBoard(objectiveid); |
||
564 | objectiveName = desc; |
||
565 | end |
||
566 | Tooltip:AddLine(objectiveName,1,1,1); |
||
567 | Questie:AddPathToTooltip(Tooltip, objectivePath, 1); |
||
568 | end |
||
569 | end |
||
570 | else |
||
571 | Tooltip:AddLine("["..QuestieHashMap[data.questHash].questLevel.."] "..Quest["name"].." |cFF33FF00(complete)|r"); |
||
572 | Tooltip:AddLine("Finished by: |cFFa6a6a6"..QuestieHashMap[data.questHash].finishedBy.."|r",1,1,1); |
||
573 | end |
||
574 | else |
||
575 | questOb = nil; |
||
576 | local QuestName = tostring(QuestieHashMap[data.questHash].name); |
||
577 | if QuestName then |
||
578 | local index = 0; |
||
579 | for k,v in pairs(Questie:SanitisedQuestLookup(QuestName)) do |
||
580 | index = index + 1; |
||
581 | if (index == 1) and (v[2] == data.questHash) and (k ~= "") then |
||
582 | questOb = k; |
||
583 | elseif (index > 0) and(v[2] == data.questHash) and (k ~= "") then |
||
584 | questOb = k; |
||
585 | elseif (index == 1) and (v[2] ~= data.questHash) and (k ~= "") then |
||
586 | questOb = k; |
||
587 | end |
||
588 | end |
||
589 | end |
||
590 | local questLine = "["..QuestieHashMap[data.questHash].questLevel.."] "..QuestieHashMap[data.questHash].name; |
||
591 | if data.icontype == "available" then |
||
592 | questLine = questLine.." |cFF33FF00(available)|r"; |
||
593 | elseif data.icontype == "availablesoon" then |
||
594 | questLine = questLine.." |cFFa6a6a6(not available)|r"; |
||
595 | end |
||
596 | Tooltip:AddLine(questLine); |
||
597 | Tooltip:AddLine("Min Level: |cFFa6a6a6"..QuestieHashMap[data.questHash].level.."|r",1,1,1); |
||
598 | Tooltip:AddLine("Started by: |cFFa6a6a6"..Questie:RemoveUniqueSuffix(QuestieHashMap[data.questHash].startedBy).."|r",1,1,1); |
||
599 | Questie:AddPathToTooltip(Tooltip, questMeta['path'], 1); |
||
600 | if questOb ~= nil then |
||
601 | Tooltip:AddLine("Description: |cFFa6a6a6"..Questie:RemoveUniqueSuffix(questOb).."|r",1,1,1,true); |
||
602 | end |
||
603 | canManualComplete = 1; |
||
604 | end |
||
605 | end |
||
606 | QSelect_QuestLogEntry(prevQuestLogSelection); |
||
607 | if canManualComplete > 0 then |
||
608 | if count > 1 then |
||
609 | Tooltip:AddLine(" "); |
||
610 | end |
||
611 | Tooltip:AddLine("Shift+Click: |cFFa6a6a6Manually complete quest!|r",1,1,1); |
||
612 | end |
||
613 | if(NOTES_DEBUG and IsAltKeyDown()) then |
||
614 | Tooltip:AddLine("!DEBUG!", 1, 0, 0); |
||
615 | Tooltip:AddLine("QuestID: "..this.data.questHash, 1, 0, 0); |
||
616 | end |
||
617 | Tooltip:SetFrameStrata("TOOLTIP"); |
||
618 | Tooltip:Show(); |
||
619 | end |
||
620 | end |
||
621 | --------------------------------------------------------------------------------------------------- |
||
622 | -- Force a quest to be finished via the Minimap or Worldmap (Shift-Click icon - NO confirmation) |
||
623 | --------------------------------------------------------------------------------------------------- |
||
624 | function Questie_AvailableQuestClick() |
||
625 | if this.type == "WorldMapNote" then |
||
626 | local c, z = GetCurrentMapContinent(), GetCurrentMapZone(); |
||
627 | local newC, newZ = c, z; |
||
628 | if arg1 == "LeftButton" then |
||
629 | if c == 0 then |
||
630 | newC = this.data.continent; |
||
631 | else |
||
632 | newZ = this.data.zoneid; |
||
633 | end |
||
634 | end |
||
635 | if arg1 == "RightButton" or arg1 == "MiddleButton" then |
||
636 | if z == 0 then |
||
637 | newC = 0; |
||
638 | else |
||
639 | newZ = 0; |
||
640 | end |
||
641 | end |
||
642 | if newC ~= c or newZ ~= z then |
||
643 | SetMapZoom(newC, newZ); |
||
644 | return; |
||
645 | end |
||
646 | end |
||
647 | local Tooltip = GameTooltip; |
||
648 | if(this.type == "WorldMapNote") then |
||
649 | Tooltip = WorldMapTooltip; |
||
650 | else |
||
651 | Tooltip = GameTooltip; |
||
652 | end |
||
653 | if (QuestieConfig.arrowEnabled == true) and (arg1 == "LeftButton") and (not IsControlKeyDown()) and (not IsShiftKeyDown()) then |
||
654 | SetArrowFromIcon(this); |
||
655 | end |
||
656 | if ((this.data.icontype == "available" or this.data.icontype == "availablesoon" or this.data.icontype == "complete") and IsShiftKeyDown() and Tooltip ) then |
||
657 | local finishQuest = function(quest) |
||
658 | if (quest.icontype == "available" or quest.icontype == "availablesoon") then |
||
659 | local hash = quest.questHash; |
||
660 | local questName = "["..QuestieHashMap[hash].questLevel.."] "..QuestieHashMap[hash]['name']; |
||
661 | Questie:finishAndRecurse(hash); |
||
662 | DEFAULT_CHAT_FRAME:AddMessage("Completing quest |cFF00FF00\"" .. questName .. "\"|r ("..hash..") and parent quests."); |
||
663 | --Questie:debug_Print("Notes:Questie_AvailableQuestClick --> Refreshing QuestNPC Icons: [AddEvent:DRAWNOTES]"); |
||
664 | Questie:AddEvent("DRAWNOTES", 0.1); |
||
665 | end |
||
666 | end |
||
667 | local count = 0; |
||
668 | local firstQuest; |
||
669 | for questHash, questMeta in pairs(this.quests) do |
||
670 | count = count + 1; |
||
671 | if not firstQuest then |
||
672 | firstQuest = questMeta['quest']; |
||
673 | end |
||
674 | end |
||
675 | if (count < 2) then |
||
676 | -- Finish first quest in list |
||
677 | finishQuest(firstQuest); |
||
678 | else |
||
679 | -- Open Dewdrop to select which quest to finish |
||
680 | local closeFunc = function() |
||
681 | Dewdrop:Close(); |
||
682 | end |
||
683 | local registerDewdrop = function(frame, quests, k1, v1, k2, v2) |
||
684 | Dewdrop:Register(frame, |
||
685 | 'children', function() |
||
686 | for questHash, questMeta in pairs(quests) do |
||
687 | local quest = questMeta.quest; |
||
688 | local hash = questHash; |
||
689 | local questName = "["..QuestieHashMap[hash].questLevel.."] "..QuestieHashMap[hash]['name'] |
||
690 | local finishFunc = function(quest) |
||
691 | finishQuest(quest); |
||
692 | Dewdrop:Close(); |
||
693 | end |
||
694 | Dewdrop:AddLine( |
||
695 | 'text', questName, |
||
696 | 'notClickable', quest.icontype ~= "available" and quest.icontype ~= "availablesoon", |
||
697 | 'icon', QuestieIcons[quest.icontype].path, |
||
698 | 'iconCoordLeft', 0, |
||
699 | 'iconCoordRight', 1, |
||
700 | 'iconCoordTop', 0, |
||
701 | 'iconCoordBottom', 1, |
||
702 | 'func', finishFunc, |
||
703 | 'arg1', quest |
||
704 | ); |
||
705 | end |
||
706 | Dewdrop:AddLine( |
||
707 | 'text', "", |
||
708 | 'notClickable', true |
||
709 | ); |
||
710 | Dewdrop:AddLine( |
||
711 | 'text', "Cancel", |
||
712 | 'func', closeFunc |
||
713 | ); |
||
714 | end, |
||
715 | 'dontHook', true, |
||
716 | k1, v1, |
||
717 | k2, v2 |
||
718 | ); |
||
719 | Dewdrop:Open(frame); |
||
720 | Dewdrop:Unregister(frame); |
||
721 | end |
||
722 | if (IsAddOnLoaded("Cartographer")) or (IsAddOnLoaded("MetaMap")) or (QuestieConfig.resizeWorldmap == true) then |
||
723 | registerDewdrop(WorldMapFrame, this.quests, 'cursorX', true, 'cursorY', true); |
||
724 | elseif (not IsAddOnLoaded("Cartographer")) or (not IsAddOnLoaded("MetaMap")) and (QuestieConfig.resizeWorldmap == false) then |
||
725 | registerDewdrop(this, this.quests, 'point', "TOPLEFT", 'relativePoint', "BOTTOMRIGHT"); |
||
726 | elseif (IsAddOnLoaded("Cartographer")) and (CartographerDB["disabledModules"]["Default"]["Look 'n' Feel"] == true) then |
||
727 | registerDewdrop(this, this.quests, 'point', "TOPLEFT", 'relativePoint', "BOTTOMRIGHT"); |
||
728 | end |
||
729 | end |
||
730 | end |
||
731 | end |
||
732 | --------------------------------------------------------------------------------------------------- |
||
733 | -- Creates a blank frame for use within the map system |
||
734 | --------------------------------------------------------------------------------------------------- |
||
735 | function Questie:CreateBlankFrameNote(frame) |
||
736 | local f = CreateFrame("Button","QuestieNoteFrame"..CREATED_NOTE_FRAMES,frame); |
||
737 | local t = f:CreateTexture(nil,"BACKGROUND"); |
||
738 | f.texture = t; |
||
739 | f:SetScript("OnEnter", Questie_Tooltip_OnEnter); |
||
740 | f:SetScript("OnLeave", function() |
||
741 | if(WorldMapTooltip) then |
||
742 | WorldMapTooltip:Hide(); |
||
743 | end |
||
744 | if(GameTooltip) then |
||
745 | GameTooltip:Hide(); |
||
746 | GameTooltip.owner = nil |
||
747 | end |
||
748 | end) |
||
749 | f:SetScript("OnClick", Questie_AvailableQuestClick); |
||
750 | f:RegisterForClicks("LeftButtonDown", "RightButtonDown", "MiddleButtonDown"); |
||
751 | CREATED_NOTE_FRAMES = CREATED_NOTE_FRAMES+1; |
||
752 | table.insert(FramePool, f); |
||
753 | table.insert(AllFrames, f); |
||
754 | end |
||
755 | --------------------------------------------------------------------------------------------------- |
||
756 | function Questie:GetFrameNote(data, parentFrame, frameLevel, type, scale) |
||
757 | if(table.getn(FramePool)==0) then |
||
758 | Questie:CreateFrameNote(data, parentFrame, frameLevel, type, scale); |
||
759 | end |
||
760 | f = FramePool[1]; |
||
761 | table.remove(FramePool, 1); |
||
762 | return f; |
||
763 | end |
||
764 | --------------------------------------------------------------------------------------------------- |
||
765 | function Questie:SetFrameNoteData(f, data, parentFrame, frameLevel, type, scale) |
||
766 | f.data = data; |
||
767 | f.quests = {}; |
||
768 | Questie:AddFrameNoteData(f, data); |
||
769 | f:SetParent(parentFrame); |
||
770 | f:SetFrameLevel(frameLevel); |
||
771 | f:SetPoint("CENTER",0,0); |
||
772 | f.type = type; |
||
773 | f:SetWidth(16*scale); |
||
774 | f:SetHeight(16*scale); |
||
775 | f.texture:SetTexture(QuestieIcons[data.icontype].path); |
||
776 | f.texture:SetAllPoints(f); |
||
777 | end |
||
778 | --------------------------------------------------------------------------------------------------- |
||
779 | function Questie:AddFrameNoteData(icon, data) |
||
780 | if icon then |
||
781 | if (icon.averageX == nil or icon.averageY == nil or icon.countForAverage == nil) then |
||
782 | icon.averageX = 0; |
||
783 | icon.averageY = 0; |
||
784 | icon.countForAverage = 0; |
||
785 | end |
||
786 | local numQuests = 0; |
||
787 | for k, v in pairs(icon.quests) do |
||
788 | numQuests = numQuests + 1; |
||
789 | end |
||
790 | local newAverageX = (icon.averageX * icon.countForAverage + data.x) / (icon.countForAverage + 1); |
||
791 | local newAverageY = (icon.averageY * icon.countForAverage + data.y) / (icon.countForAverage + 1); |
||
792 | icon.averageX = newAverageX; |
||
793 | icon.averageY = newAverageY; |
||
794 | icon.countForAverage = icon.countForAverage + 1; |
||
795 | if icon.quests[data.questHash] then |
||
796 | -- Add cumulative quest data |
||
797 | if icon.quests[data.questHash]['objectives'][data.objectiveid] == nil then |
||
798 | icon.quests[data.questHash]['objectives'][data.objectiveid] = {}; |
||
799 | end |
||
800 | if data.path then |
||
801 | Questie:JoinPathTables(icon.quests[data.questHash]['path'], data.path); |
||
802 | end |
||
803 | if data.objectiveid and data.path then |
||
804 | Questie:JoinPathTables(icon.quests[data.questHash]['objectives'][data.objectiveid], data.path); |
||
805 | end |
||
806 | else |
||
807 | icon.quests[data.questHash] = {}; |
||
808 | icon.quests[data.questHash]['quest'] = data; |
||
809 | icon.quests[data.questHash]['sortOrder'] = numQuests + 1; |
||
810 | icon.quests[data.questHash]['objectives'] = {}; |
||
811 | icon.quests[data.questHash]['path'] = {}; |
||
812 | if data.objectiveid then |
||
813 | icon.quests[data.questHash]['objectives'][data.objectiveid] = {}; |
||
814 | if data.path then |
||
815 | icon.quests[data.questHash]['objectives'][data.objectiveid] = deepcopy(data.path); |
||
816 | end |
||
817 | end |
||
818 | if data.path then |
||
819 | icon.quests[data.questHash]['path'] = deepcopy(data.path); |
||
820 | end |
||
821 | end |
||
822 | end |
||
823 | end |
||
824 | --------------------------------------------------------------------------------------------------- |
||
825 | function Questie:JoinPathTables(path1, path2) |
||
826 | for k, v in pairs(path2) do |
||
827 | if path1[k] then |
||
828 | --Questie:debug_Print("Joining values for "..k) |
||
829 | Questie:JoinPathTables(path1[k], path2[k]); |
||
830 | else |
||
831 | --Questie:debug_Print("Setting value for "..k) |
||
832 | path1[k] = path2[k]; |
||
833 | end |
||
834 | end |
||
835 | end |
||
836 | --------------------------------------------------------------------------------------------------- |
||
837 | function Questie:PathsAreIdentical(path1, path2) |
||
838 | if not next(path1) and not next(path2) then |
||
839 | return true; |
||
840 | end |
||
841 | for sourceType1, sources1 in pairs(path1) do |
||
842 | for sourceType2, sources2 in pairs(path2) do |
||
843 | if path1[sourceType2] == nil or path2[sourceType1] == nil then |
||
844 | return false; |
||
845 | end |
||
846 | end |
||
847 | for sourceName, sourcePath in pairs(path1[sourceType1]) do |
||
848 | for otherSourceName, otherSourcePath in pairs(path2[sourceType1]) do |
||
849 | if path1[sourceType1][otherSourceName] == nil or path2[sourceType1][sourceName] == nil then |
||
850 | return false; |
||
851 | end |
||
852 | end |
||
853 | end |
||
854 | end |
||
855 | return true; |
||
856 | end |
||
857 | --------------------------------------------------------------------------------------------------- |
||
858 | function Questie:PostProcessIconPath(path) |
||
859 | if path["locations"] then path["locations"] = nil; end |
||
860 | if path["name"] then path["name"] = nil; end |
||
861 | for sourceType, sources in pairs(path) do |
||
862 | for sourceName, sourcePath in pairs(sources) do |
||
863 | Questie:PostProcessIconPath(sourcePath); |
||
864 | end |
||
865 | local newSources = {}; |
||
866 | for sourceName, sourcePath in pairs(sources) do |
||
867 | for otherSourceName, otherSourcePath in pairs(sources) do |
||
868 | if sourceName ~= otherSourceName and (newSources[sourceName] == nil or newSources[otherSourceName] == nil) then |
||
869 | if Questie:PathsAreIdentical(sourcePath, otherSourcePath) then |
||
870 | local newSource = newSources[sourceName]; |
||
871 | if newSource == nil then |
||
872 | newSource = newSources[otherSourceName]; |
||
873 | end |
||
874 | if newSource ~= nil then |
||
875 | newSource.name = newSource.name..", "..otherSourceName; |
||
876 | table.insert(newSource.names, otherSourceName); |
||
877 | else |
||
878 | newSource = { |
||
879 | ['name'] = sourceName..", "..otherSourceName, |
||
880 | ['names'] = {sourceName, otherSourceName}, |
||
881 | ['sourcePath'] = sourcePath |
||
882 | }; |
||
883 | end |
||
884 | for i, name in ipairs(newSource.names) do |
||
885 | newSources[name] = newSource; |
||
886 | end |
||
887 | end |
||
888 | end |
||
889 | end |
||
890 | end |
||
891 | for sourceName, sourcePath in pairs(sources) do |
||
892 | if newSources[sourceName] == nil then |
||
893 | newSources[sourceName] = { |
||
894 | ['name'] = sourceName, |
||
895 | ['sourcePath'] = sourcePath, |
||
896 | ['names'] = {sourceName} |
||
897 | }; |
||
898 | end |
||
899 | end |
||
900 | local processedSources = {}; |
||
901 | for sourceName, data in pairs(newSources) do |
||
902 | processedSources[data.name] = data.sourcePath; |
||
903 | end |
||
904 | path[sourceType] = processedSources; |
||
905 | end |
||
906 | end |
||
907 | --------------------------------------------------------------------------------------------------- |
||
908 | function Questie:RecursiveGetSourceNamesFromRawPath(path, sourceNames) |
||
909 | if sourceNames == nil then sourceNames = {} end |
||
910 | for sourceType, sources in pairs(path) do |
||
911 | if sourceType ~= "locations" and sourceType ~= "name" then |
||
912 | for sourceName, sourcePath in pairs(sources) do |
||
913 | sourceNames[sourceName] = true |
||
914 | Questie:RecursiveGetSourceNamesFromRawPath(sourcePath, sourceNames) |
||
915 | end |
||
916 | end |
||
917 | end |
||
918 | return sourceNames |
||
919 | end |
||
920 | --------------------------------------------------------------------------------------------------- |
||
921 | function Questie:RecursiveFindAndCombineObjectiveName(pathToSearch, objectiveName, pathToAdd) |
||
922 | local found = false; |
||
923 | for sourceType, sources in pairs(pathToSearch) do |
||
924 | for sourceName, sourcePath in pairs(sources) do |
||
925 | if sourceName == objectiveName then |
||
926 | sources[sourceName] = pathToAdd; |
||
927 | found = true; |
||
928 | else |
||
929 | if Questie:RecursiveFindAndCombineObjectiveName(sourcePath, objectiveName, pathToAdd) then |
||
930 | found = true; |
||
931 | end |
||
932 | end |
||
933 | end |
||
934 | end |
||
935 | return found; |
||
936 | end |
||
937 | --------------------------------------------------------------------------------------------------- |
||
938 | function Questie:FindAndCombineObjectiveName(objectives, objectiveName, pathToAdd) |
||
939 | for objectiveid, objectivePath in pairs(objectives) do |
||
940 | if type(objectiveid) ~= "string" then |
||
941 | if Questie:RecursiveFindAndCombineObjectiveName(objectivePath, objectiveName, pathToAdd) then |
||
942 | objectives[objectiveName] = nil; |
||
943 | end |
||
944 | end |
||
945 | end |
||
946 | end |
||
947 | --------------------------------------------------------------------------------------------------- |
||
948 | function Questie:PostProcessIconPaths(icon) |
||
949 | for questHash, questMeta in pairs(icon.quests) do |
||
950 | Questie:PostProcessIconPath(questMeta.path); |
||
951 | for objectiveid, objectivePath in pairs(questMeta.objectives) do |
||
952 | if type(objectiveid) == "string" then |
||
953 | Questie:FindAndCombineObjectiveName(questMeta.objectives, objectiveid, objectivePath); |
||
954 | end |
||
955 | Questie:PostProcessIconPath(objectivePath); |
||
956 | end |
||
957 | end |
||
958 | end |
||
959 | --------------------------------------------------------------------------------------------------- |
||
960 | -- Updates notes for current zone only |
||
961 | --------------------------------------------------------------------------------------------------- |
||
962 | function Questie:NOTES_ON_UPDATE(elapsed) |
||
963 | if GameLoadingComplete == false then return; end |
||
964 | local c, z = GetCurrentMapContinent(), GetCurrentMapZone(); |
||
965 | if(c ~= LastContinent or LastZone ~= z) then |
||
966 | --Questie:debug_Print("Notes:NOTES_ON_UPDATE: [AddEvent:DRAWNOTES]"); |
||
967 | Questie:SetAvailableQuests(); |
||
968 | Questie:RedrawNotes(); |
||
969 | LastContinent = c; |
||
970 | LastZone = z; |
||
971 | end |
||
972 | if(WorldMapFrame:IsVisible() and UIOpen == false) then |
||
973 | --Questie:debug_Print("NOTES_ON_UPDATE: Created Frames: "..CREATED_NOTE_FRAMES, "Used Frames: "..table.getn(QuestieUsedNoteFrames), "Free Frames: "..table.getn(FramePool)); |
||
974 | UIOpen = true; |
||
975 | elseif(WorldMapFrame:IsVisible() == nil and UIOpen == true) then |
||
976 | UIOpen = false; |
||
977 | end |
||
978 | end |
||
979 | --------------------------------------------------------------------------------------------------- |
||
980 | -- Inital pool size (Not tested how much you can do before it lags like shit, from experiance 11 |
||
981 | -- is good) |
||
982 | --------------------------------------------------------------------------------------------------- |
||
983 | function Questie:NOTES_LOADED() |
||
984 | --Questie:debug_Print("NOTES_LOADED: Loading QuestieNotes"); |
||
985 | if(table.getn(FramePool) < 10) then |
||
986 | for i = 1, INIT_POOL_SIZE do |
||
987 | Questie:CreateBlankFrameNote(); |
||
988 | end |
||
989 | end |
||
990 | --Questie:debug_Print("NOTES_LOADED: Done Loading QuestieNotes"); |
||
991 | end |
||
992 | --------------------------------------------------------------------------------------------------- |
||
993 | function Questie:RecursiveGetPathLocations(path, locations) |
||
994 | if locations == nil then locations = {}; end |
||
995 | for sourceType, sources in pairs(path) do |
||
996 | if sourceType == "locations" and next(sources) then |
||
997 | for i, location in pairs(sources) do |
||
998 | table.insert(locations, location); |
||
999 | end |
||
1000 | elseif sourceType == "drop" or sourceType == "rewardedby" or sourceType == "contained" or sourceType == "contained_id" or sourceType == "created" or sourceType == "containedi" or sourceType == "transforms" or sourceType == "transformedby" then |
||
1001 | for sourceName, sourcePath in pairs(sources) do |
||
1002 | Questie:RecursiveGetPathLocations(sourcePath, locations); |
||
1003 | end |
||
1004 | end |
||
1005 | end |
||
1006 | return locations; |
||
1007 | end |
||
1008 | --------------------------------------------------------------------------------------------------- |
||
1009 | function Questie:RecursiveCreateNotes(c, z, v, locationMeta, iconMeta, objectiveid, path, pathKeys) |
||
1010 | if path == nil then path = {}; end |
||
1011 | if pathKeys == nil then pathKeys = {}; end |
||
1012 | for sourceType, sources in pairs(locationMeta) do |
||
1013 | if sourceType == "locations" and next(sources) then |
||
1014 | for specialSource, b in pairs(specialSources) do |
||
1015 | if locationMeta[specialSource] ~= nil and next(locationMeta[specialSource]) then |
||
1016 | local pathToAppend = path; |
||
1017 | for i, pathKey in pairs(pathKeys) do |
||
1018 | pathToAppend = pathToAppend[pathKey]; |
||
1019 | end |
||
1020 | pathToAppend[specialSource] = {}; |
||
1021 | for sourceName, sourcePath in pairs(locationMeta[specialSource]) do |
||
1022 | pathToAppend[specialSource][sourceName] = {}; |
||
1023 | end |
||
1024 | end |
||
1025 | end |
||
1026 | for i, location in pairs(sources) do |
||
1027 | local MapInfo = QuestieZoneIDLookup[location[1]]; |
||
1028 | if MapInfo ~= nil then |
||
1029 | c = MapInfo[4]; |
||
1030 | z = MapInfo[5]; |
||
1031 | local icontype = iconMeta.selectedIcon; |
||
1032 | if icontype == nil then icontype = iconMeta.defaultIcon; end |
||
1033 | if icontype == "available" or icontype == "availablesoon" then |
||
1034 | Questie:AddAvailableNoteToMap(location[1],location[2],location[3],location[4],icontype,v,-1,deepcopy(path)); |
||
1035 | else |
||
1036 | Questie:AddNoteToMap(location[1],location[2],location[3],location[4],icontype,v,objectiveid,deepcopy(path)); |
||
1037 | end |
||
1038 | end |
||
1039 | end |
||
1040 | elseif sourceType == "drop" or sourceType == "rewardedby" or sourceType == "contained" or sourceType == "contained_id" or sourceType == "created" or sourceType == "containedi" or sourceType == "openedby" or sourceType == "transforms" or sourceType == "transformedby" then |
||
1041 | for sourceName, sourceLocationMeta in pairs(sources) do |
||
1042 | local newPath = deepcopy(path); |
||
1043 | local editPath = newPath; |
||
1044 | for i, pathKey in pairs(pathKeys) do |
||
1045 | editPath = editPath[pathKey]; |
||
1046 | end |
||
1047 | editPath[sourceType] = {}; |
||
1048 | editPath[sourceType][sourceName] = {}; |
||
1049 | local newPathKeys = deepcopy(pathKeys); |
||
1050 | table.insert(newPathKeys, sourceType); |
||
1051 | table.insert(newPathKeys, sourceName); |
||
1052 | local newIconMeta = deepcopy(iconMeta); |
||
1053 | if newIconMeta.selectedIcon == nil then |
||
1054 | local typeToIcon = { |
||
1055 | ["drop"] = "loot", |
||
1056 | ["rewardedby"] = "slay", |
||
1057 | ["contained"] = "object", |
||
1058 | ["contained_id"] = "object", |
||
1059 | ["created"] = "event", |
||
1060 | ["containedi"] = "object", |
||
1061 | ["openedby"] = "object", |
||
1062 | ["transforms"] = "event", |
||
1063 | ["transformedby"] = "loot", |
||
1064 | }; |
||
1065 | newIconMeta.selectedIcon = typeToIcon[sourceType]; |
||
1066 | end |
||
1067 | local newObjectiveId = objectiveid; |
||
1068 | if specialSources[sourceType] then |
||
1069 | newPath = {}; |
||
1070 | newPathKeys = {}; |
||
1071 | newObjectiveId = sourceName; |
||
1072 | newIconMeta.selectedIcon = nil; |
||
1073 | end |
||
1074 | Questie:RecursiveCreateNotes(c, z, v, sourceLocationMeta, newIconMeta, newObjectiveId, newPath, newPathKeys); |
||
1075 | end |
||
1076 | end |
||
1077 | end |
||
1078 | end |
||
1079 | --------------------------------------------------------------------------------------------------- |
||
1080 | -- Sets up all available quests |
||
1081 | --------------------------------------------------------------------------------------------------- |
||
1082 | function Questie:SetAvailableQuests(customLevel) |
||
1083 | QuestieAvailableMapNotes = {}; |
||
1084 | local saqtime = GetTime(); |
||
1085 | local level = customLevel or UnitLevel("player"); |
||
1086 | local c, z = GetCurrentMapContinent(), GetCurrentMapZone(); |
||
1087 | local mapFileName = GetMapInfo(); |
||
1088 | local quests = nil; |
||
1089 | local minLevel = 0; |
||
1090 | local maxLevel = 100; |
||
1091 | if QuestieConfig.minLevelFilter then |
||
1092 | minLevel = level - QuestieConfig.minShowLevel; |
||
1093 | end |
||
1094 | if QuestieConfig.maxLevelFilter then |
||
1095 | maxLevel = level + QuestieConfig.maxShowLevel; |
||
1096 | end |
||
1097 | quests = Questie:GetAvailableQuestHashes(mapFileName, minLevel, maxLevel); |
||
1098 | if quests then |
||
1099 | local count = 0; |
||
1100 | for k, v in pairs(quests) do |
||
1101 | count = count + 1; |
||
1102 | local icontype = "available"; |
||
1103 | if QuestieHashMap[k].level > level then icontype = "availablesoon"; end |
||
1104 | Questie:RecursiveCreateNotes(c, z, k, v, {["selectedIcon"] = icontype}); |
||
1105 | end |
||
1106 | --Questie:debug_Print("SetAvailableQuests: Adding "..count.." available quests took "..tostring((GetTime()- saqtime)*1000).."ms"); |
||
1107 | saqtime = nil; |
||
1108 | end |
||
1109 | end |
||
1110 | --------------------------------------------------------------------------------------------------- |
||
1111 | -- Reason this exists is to be able to call both clearnotes and drawnotes without doing 2 function |
||
1112 | -- calls, and to be able to force a redraw |
||
1113 | --------------------------------------------------------------------------------------------------- |
||
1114 | function Questie:RedrawNotes() |
||
1115 | Questie:CLEAR_ALL_NOTES(); |
||
1116 | Questie:DRAW_NOTES(); |
||
1117 | end |
||
1118 | --------------------------------------------------------------------------------------------------- |
||
1119 | function Questie:Clear_Note(v) |
||
1120 | v:SetParent(nil); |
||
1121 | v:Hide(); |
||
1122 | v:SetAlpha(1); |
||
1123 | v:SetFrameLevel(9); |
||
1124 | v:SetHighlightTexture(nil, "ADD"); |
||
1125 | v.questHash = nil; |
||
1126 | v.objId = nil; |
||
1127 | v.data = nil; |
||
1128 | v.quests = nil; |
||
1129 | v.averageX = nil; |
||
1130 | v.averageY = nil; |
||
1131 | v.countForAverage = nil; |
||
1132 | table.insert(FramePool, v); |
||
1133 | end |
||
1134 | --------------------------------------------------------------------------------------------------- |
||
1135 | -- Clears the notes, goes through the usednoteframes and clears them. Then sets the |
||
1136 | -- QuestieUsedNotesFrame to new table; |
||
1137 | --------------------------------------------------------------------------------------------------- |
||
1138 | function Questie:CLEAR_ALL_NOTES() |
||
1139 | --Questie:debug_Print("CLEAR_ALL_NOTES"); |
||
1140 | Astrolabe:RemoveAllMinimapIcons(); |
||
1141 | clustersByFrame = nil; |
||
1142 | for k, v in pairs(QuestieUsedNoteFrames) do |
||
1143 | Questie:Clear_Note(v); |
||
1144 | end |
||
1145 | QuestieUsedNoteFrames = {}; |
||
1146 | end |
||
1147 | --------------------------------------------------------------------------------------------------- |
||
1148 | -- Logic for clusters |
||
1149 | --------------------------------------------------------------------------------------------------- |
||
1150 | function Cluster.new(points) |
||
1151 | local self = setmetatable({}, Cluster); |
||
1152 | self.points = points; |
||
1153 | return self; |
||
1154 | end |
||
1155 | --------------------------------------------------------------------------------------------------- |
||
1156 | function Cluster:CountPoints() |
||
1157 | local count = 0; |
||
1158 | local counted = {}; |
||
1159 | for i, q in pairs(self.points) do |
||
1160 | if not counted[q.questHash] then |
||
1161 | count = count + 1; |
||
1162 | counted[q.questHash] = true; |
||
1163 | end |
||
1164 | end |
||
1165 | return count; |
||
1166 | end |
||
1167 | --------------------------------------------------------------------------------------------------- |
||
1168 | function Cluster.CalculateDistance(x1, y1, x2, y2) |
||
1169 | local deltaX = x1 - x2; |
||
1170 | local deltaY = y1 - y2; |
||
1171 | return sqrt(deltaX*deltaX + deltaY*deltaY); |
||
1172 | end |
||
1173 | --------------------------------------------------------------------------------------------------- |
||
1174 | function Cluster.CalculateLinkageDistance(cluster1, cluster2) |
||
1175 | local total = 0; |
||
1176 | for i, pi in cluster1 do |
||
1177 | for j, pj in cluster2 do |
||
1178 | if pi.zoneid ~= pj.zoneid then return -1; end |
||
1179 | local distance = Cluster.CalculateDistance(pi.x, pi.y, pj.x, pj.y); |
||
1180 | total = total + distance; |
||
1181 | end |
||
1182 | end |
||
1183 | return total / (table.getn(cluster1) * table.getn(cluster2)); |
||
1184 | end |
||
1185 | --------------------------------------------------------------------------------------------------- |
||
1186 | function Cluster:CalculateClusters(clusters, distanceThreshold, maxClusterSize) |
||
1187 | while table.getn(clusters) > 1 do |
||
1188 | local nearest1; |
||
1189 | local nearest2; |
||
1190 | local nearestDistance; |
||
1191 | for i, cluster in pairs(clusters) do |
||
1192 | for j, otherCluster in pairs(clusters) do |
||
1193 | if cluster ~= otherCluster then |
||
1194 | local distance = Cluster.CalculateLinkageDistance(cluster.points, otherCluster.points); |
||
1195 | if distance >= 0 and (distance == 0 or ((nearestDistance == nil or distance < nearestDistance) and (cluster:CountPoints() + otherCluster:CountPoints() <= maxClusterSize))) then |
||
1196 | nearestDistance = distance; |
||
1197 | nearest1 = cluster; |
||
1198 | nearest2 = otherCluster; |
||
1199 | end |
||
1200 | end |
||
1201 | if nearestDistance == 0 then break; end |
||
1202 | end |
||
1203 | if nearestDistance == 0 then break; end |
||
1204 | end |
||
1205 | if nearestDistance == nil or nearestDistance > distanceThreshold then break; end |
||
1206 | local index1 = indexOf(clusters, nearest1); |
||
1207 | table.remove(clusters, index1); |
||
1208 | local index2 = indexOf(clusters, nearest2); |
||
1209 | table.remove(clusters, index2); |
||
1210 | local points = nearest1.points; |
||
1211 | for i, point in pairs(nearest2.points) do |
||
1212 | table.insert(points, point); |
||
1213 | end |
||
1214 | local newCluster = Cluster.new(points); |
||
1215 | table.insert(clusters, newCluster); |
||
1216 | end |
||
1217 | end |
||
1218 | --------------------------------------------------------------------------------------------------- |
||
1219 | -- splits the specified text into an array on the specified separator |
||
1220 | -- todo make a QuestieUtils.lua file for things like this |
||
1221 | --------------------------------------------------------------------------------------------------- |
||
1222 | function Questie:SplitString( text, separator, limit ) |
||
1223 | local parts, position, length, last, jump, count = {}, 1, string.len( text ), nil, string.len( separator ), 0; |
||
1224 | while true do |
||
1225 | last = string.find( text, separator, position, true ); |
||
1226 | if last and ( not limit or count < limit ) then |
||
1227 | table.insert( parts, string.sub( text, position, last - 1 ) ); |
||
1228 | position, count = last + jump, count + 1; |
||
1229 | else |
||
1230 | table.insert( parts, string.sub( text, position ) ); |
||
1231 | break; |
||
1232 | end |
||
1233 | end |
||
1234 | return parts; |
||
1235 | end |
||
1236 | --------------------------------------------------------------------------------------------------- |
||
1237 | function Questie:RoundCoordinate(coord, factor) |
||
1238 | if factor == nil then factor = 1; end |
||
1239 | return tonumber(string.format("%.2f", coord/factor)) * factor; |
||
1240 | end |
||
1241 | --------------------------------------------------------------------------------------------------- |
||
1242 | function Questie:GetReactionColor(reaction) |
||
1243 | if reaction == nil or reaction < 1 or reaction > 8 then reaction = 4; end |
||
1244 | return FACTION_BAR_COLORS[reaction]; |
||
1245 | end |
||
1246 | --------------------------------------------------------------------------------------------------- |
||
1247 | function Questie:AddClusterFromNote(frame, identifier, v) |
||
1248 | if clustersByFrame == nil then |
||
1249 | clustersByFrame = {}; |
||
1250 | end |
||
1251 | if clustersByFrame[frame] == nil then |
||
1252 | clustersByFrame[frame] = {}; |
||
1253 | end |
||
1254 | if clustersByFrame[frame][identifier] == nil then |
||
1255 | clustersByFrame[frame][identifier] = {}; |
||
1256 | end |
||
1257 | if clustersByFrame[frame][identifier][v.continent] == nil then |
||
1258 | clustersByFrame[frame][identifier][v.continent] = {}; |
||
1259 | end |
||
1260 | if clustersByFrame[frame][identifier][v.continent][v.zoneid] == nil then |
||
1261 | clustersByFrame[frame][identifier][v.continent][v.zoneid] = {}; |
||
1262 | end |
||
1263 | local roundedX = v.x; |
||
1264 | local roundedY = v.y; |
||
1265 | if QuestieConfig.clusterQuests and frame == "WorldMapNote" and identifier == "Objectives" then |
||
1266 | roundedX = Questie:RoundCoordinate(v.x, 5); |
||
1267 | roundedY = Questie:RoundCoordinate(v.y, 5); |
||
1268 | end |
||
1269 | if clustersByFrame[frame][identifier][v.continent][v.zoneid][roundedX] == nil then |
||
1270 | clustersByFrame[frame][identifier][v.continent][v.zoneid][roundedX] = {}; |
||
1271 | end |
||
1272 | if clustersByFrame[frame][identifier][v.continent][v.zoneid][roundedX][roundedY] == nil then |
||
1273 | local points = { v }; |
||
1274 | local cluster = Cluster.new(points); |
||
1275 | clustersByFrame[frame][identifier][v.continent][v.zoneid][roundedX][roundedY] = cluster; |
||
1276 | else |
||
1277 | table.insert(clustersByFrame[frame][identifier][v.continent][v.zoneid][roundedX][roundedY].points, v); |
||
1278 | end |
||
1279 | end |
||
1280 | --------------------------------------------------------------------------------------------------- |
||
1281 | function Questie:GetClustersByFrame(frame, identifier) |
||
1282 | if clustersByFrame == nil then |
||
1283 | clustersByFrame = {}; |
||
1284 | end |
||
1285 | if clustersByFrame[frame] == nil then |
||
1286 | clustersByFrame[frame] = {}; |
||
1287 | end |
||
1288 | if clustersByFrame[frame][identifier] == nil then |
||
1289 | clustersByFrame[frame][identifier] = {}; |
||
1290 | end |
||
1291 | local clusters = {}; |
||
1292 | for c, v in pairs(clustersByFrame[frame][identifier]) do |
||
1293 | for z, v in pairs(clustersByFrame[frame][identifier][c]) do |
||
1294 | for x, v in pairs(clustersByFrame[frame][identifier][c][z]) do |
||
1295 | for y, v in pairs(clustersByFrame[frame][identifier][c][z][x]) do |
||
1296 | table.insert(clusters, clustersByFrame[frame][identifier][c][z][x][y]); |
||
1297 | end |
||
1298 | end |
||
1299 | end |
||
1300 | end |
||
1301 | return clusters; |
||
1302 | end |
||
1303 | --------------------------------------------------------------------------------------------------- |
||
1304 | -- Finds the index of an item in a table. Not sure if a function already exists somewhere. |
||
1305 | --------------------------------------------------------------------------------------------------- |
||
1306 | function indexOf(table, item) |
||
1307 | for k, v in pairs(table) do |
||
1308 | if v == item then return k; end |
||
1309 | end |
||
1310 | return nil; |
||
1311 | end |
||
1312 | --------------------------------------------------------------------------------------------------- |
||
1313 | -- Checks first if there are any notes for the current zone, then draws the desired icon |
||
1314 | --------------------------------------------------------------------------------------------------- |
||
1315 | function Questie:DRAW_NOTES() |
||
1316 | --Questie:debug_Print("DRAW_NOTES"); |
||
1317 | local c, z = GetCurrentMapContinent(), GetCurrentMapZone(); |
||
1318 | if (not QuestieConfig.hideMinimapIcons) then |
||
1319 | -- Draw minimap objective markers |
||
1320 | if (QuestieMapNotes[c] and QuestieMapNotes[c][z]) then |
||
1321 | for k, v in pairs(QuestieMapNotes[c][z]) do |
||
1322 | --If an available quest isn't in the zone or we aren't tracking a quest on the QuestTracker or the user wants to hide all objectives then hide the objectives from the minimap |
||
1323 | local show = QuestieConfig.alwaysShowObjectives or ((MMLastX ~= 0) and (MMLastY ~= 0)) and (QuestieCachedQuests[v.questHash] ~= nil) and (QuestieCachedQuests[v.questHash]["tracked"] ~= false); |
||
1324 | if show then |
||
1325 | if (v.icontype == "complete") then |
||
1326 | Questie:AddClusterFromNote("MiniMapNote", "Quests", v); |
||
1327 | else |
||
1328 | if QuestieConfig.hideObjectives == false then |
||
1329 | Questie:AddClusterFromNote("MiniMapNote", "Objectives", v); |
||
1330 | end |
||
1331 | end |
||
1332 | end |
||
1333 | end |
||
1334 | end |
||
1335 | end |
||
1336 | -- Draw world map objective markers |
||
1337 | for k, Continent in pairs(QuestieMapNotes) do |
||
1338 | for zone, noteHeap in pairs(Continent) do |
||
1339 | for k, v in pairs(noteHeap) do |
||
1340 | if true then |
||
1341 | --If we aren't tracking a quest on the QuestTracker or the user wants to hide all objectives then hide the objectives from the worldmap |
||
1342 | if (((QuestieCachedQuests[v.questHash] ~= nil) and (QuestieCachedQuests[v.questHash]["tracked"] ~= false)) or (v.icontype == "complete")) and (QuestieConfig.alwaysShowObjectives == false) then |
||
1343 | if (v.icontype == "complete") then |
||
1344 | Questie:AddClusterFromNote("WorldMapNote", "Quests", v); |
||
1345 | else |
||
1346 | if QuestieConfig.hideObjectives == false then |
||
1347 | Questie:AddClusterFromNote("WorldMapNote", "Objectives", v); |
||
1348 | end |
||
1349 | end |
||
1350 | elseif (QuestieConfig.alwaysShowObjectives == true) then |
||
1351 | if (v.icontype == "complete") then |
||
1352 | Questie:AddClusterFromNote("WorldMapNote", "Quests", v); |
||
1353 | else |
||
1354 | if QuestieConfig.hideObjectives == false then |
||
1355 | Questie:AddClusterFromNote("WorldMapNote", "Objectives", v); |
||
1356 | end |
||
1357 | end |
||
1358 | end |
||
1359 | end |
||
1360 | end |
||
1361 | end |
||
1362 | end |
||
1363 | -- Draw available quest markers. |
||
1364 | if (QuestieAvailableMapNotes[c] and QuestieAvailableMapNotes[c][z]) then |
||
1365 | if (IsQuestieActive == true) then |
||
1366 | local con,zon,x,y = Astrolabe:GetCurrentPlayerPosition(); |
||
1367 | for k, v in pairs(QuestieAvailableMapNotes[c][z]) do |
||
1368 | Questie:AddClusterFromNote("WorldMapNote", "Quests", v); |
||
1369 | if (not QuestieConfig.hideMinimapIcons) then |
||
1370 | Questie:AddClusterFromNote("MiniMapNote", "Quests", v); |
||
1371 | end |
||
1372 | end |
||
1373 | end |
||
1374 | end |
||
1375 | local minimapObjectiveClusters = Questie:GetClustersByFrame("MiniMapNote", "Objectives"); |
||
1376 | local worldMapObjectiveClusters = Questie:GetClustersByFrame("WorldMapNote", "Objectives"); |
||
1377 | local minimapClusters = Questie:GetClustersByFrame("MiniMapNote", "Quests"); |
||
1378 | local worldMapClusters = Questie:GetClustersByFrame("WorldMapNote", "Quests"); |
||
1379 | if QuestieConfig.clusterQuests then |
||
1380 | Cluster:CalculateClusters(worldMapClusters, 0.025, 5); |
||
1381 | end |
||
1382 | local scale = QUESTIE_NOTES_MAP_ICON_SCALE; |
||
1383 | if (z == 0 and c == 0) then--Both continents |
||
1384 | scale = QUESTIE_NOTES_WORLD_MAP_ICON_SCALE; |
||
1385 | elseif (z == 0) then--Single continent |
||
1386 | scale = QUESTIE_NOTES_CONTINENT_ICON_SCALE; |
||
1387 | end |
||
1388 | Questie:DrawClusters(worldMapObjectiveClusters, "WorldMapNote", scale, WorldMapFrame, WorldMapButton); |
||
1389 | Questie:DrawClusters(worldMapClusters, "WorldMapNote", scale, WorldMapFrame, WorldMapButton); |
||
1390 | Questie:DrawClusters(minimapObjectiveClusters, "MiniMapNote", QUESTIE_NOTES_MINIMAP_ICON_SCALE, Minimap); |
||
1391 | Questie:DrawClusters(minimapClusters, "MiniMapNote", QUESTIE_NOTES_MINIMAP_ICON_SCALE, Minimap); |
||
1392 | end |
||
1393 | --------------------------------------------------------------------------------------------------- |
||
1394 | function Questie:DrawClusters(clusters, frameName, scale, frame, button) |
||
1395 | local frameLevel = 9; |
||
1396 | if frameName == "MiniMapNote" then |
||
1397 | frameLevel = 7; |
||
1398 | end |
||
1399 | for i, cluster in pairs(clusters) do |
||
1400 | table.sort(cluster.points, function(a, b) |
||
1401 | if QuestieIcons[a.icontype].priority ~= QuestieIcons[b.icontype].priority then return QuestieIcons[a.icontype].priority < QuestieIcons[b.icontype].priority end |
||
1402 | if a.questHash == b.questHash then return tostring(a) < tostring(b) end |
||
1403 | local questA = QuestieHashMap[a.questHash] |
||
1404 | local questB = QuestieHashMap[b.questHash] |
||
1405 | if not questA or not questB then return questA ~= nil end |
||
1406 | if questA and questB then |
||
1407 | if questA.level ~= questB.level then return questA.level < questB.level end |
||
1408 | local questLevelA = GetNumberFromString(questA.questLevel) |
||
1409 | local questLevelB = GetNumberFromString(questB.questLevel) |
||
1410 | if questLevelA ~= questLevelB then return questLevelA < questLevelB end |
||
1411 | end |
||
1412 | return a.questHash < b.questHash |
||
1413 | end) |
||
1414 | local Icon = Questie:GetBlankNoteFrame(frame); |
||
1415 | for j, v in pairs(cluster.points) do |
||
1416 | if j == 1 then |
||
1417 | local finalFrameLevel = frameLevel; |
||
1418 | if v.icontype == "complete" then finalFrameLevel = finalFrameLevel + 1; end |
||
1419 | Questie:SetFrameNoteData(Icon, v, frame, finalFrameLevel, frameName, scale); |
||
1420 | else |
||
1421 | Questie:AddFrameNoteData(Icon, v); |
||
1422 | end |
||
1423 | end |
||
1424 | Questie:PostProcessIconPaths(Icon); |
||
1425 | if frameName == "MiniMapNote" then |
||
1426 | Icon:SetHighlightTexture(QuestieIcons[Icon.data.icontype].path, "ADD"); |
||
1427 | Astrolabe:PlaceIconOnMinimap(Icon, Icon.data.continent, Icon.data.zoneid, Icon.averageX, Icon.averageY); |
||
1428 | table.insert(QuestieUsedNoteFrames, Icon); |
||
1429 | else |
||
1430 | Icon:Show(); |
||
1431 | xx, yy = Astrolabe:PlaceIconOnWorldMap(button, Icon, Icon.data.continent, Icon.data.zoneid, Icon.averageX, Icon.averageY); |
||
1432 | if(xx and yy and xx > 0 and xx < 1 and yy > 0 and yy < 1) then |
||
1433 | table.insert(QuestieUsedNoteFrames, Icon); |
||
1434 | else |
||
1435 | Questie:Clear_Note(Icon); |
||
1436 | end |
||
1437 | end |
||
1438 | end |
||
1439 | end |
||
1440 | --------------------------------------------------------------------------------------------------- |
||
1441 | -- Debug print function |
||
1442 | --------------------------------------------------------------------------------------------------- |
||
1443 | function Questie:debug_Print(...) |
||
1444 | local debugWin = 0; |
||
1445 | local name, shown; |
||
1446 | for i=1, NUM_CHAT_WINDOWS do |
||
1447 | name,_,_,_,_,_,shown = GetChatWindowInfo(i); |
||
1448 | if (string.lower(name) == "questiedebug") then debugWin = i; break; end |
||
1449 | end |
||
1450 | if (debugWin == 0) then return; end |
||
1451 | local out = ""; |
||
1452 | for i = 1, arg.n, 1 do |
||
1453 | if (i > 1) then out = out .. ", "; end |
||
1454 | local t = type(arg[i]); |
||
1455 | if (t == "string") then |
||
1456 | out = out .. '"'..arg[i]..'"'; |
||
1457 | elseif (t == "number") then |
||
1458 | out = out .. arg[i]; |
||
1459 | else |
||
1460 | out = out .. dump(arg[i]); |
||
1461 | end |
||
1462 | end |
||
1463 | getglobal("ChatFrame"..debugWin):AddMessage(out, 1.0, 1.0, 0.3); |
||
1464 | end |
||
1465 | --------------------------------------------------------------------------------------------------- |
||
1466 | -- Sets the icon type |
||
1467 | --------------------------------------------------------------------------------------------------- |
||
1468 | QuestieIcons = { |
||
1469 | ["complete"] = { |
||
1470 | text = "Complete", |
||
1471 | path = "Interface\\AddOns\\!Questie\\Icons\\complete", |
||
1472 | priority = 1 |
||
1473 | }, |
||
1474 | ["available"] = { |
||
1475 | text = "Complete", |
||
1476 | path = "Interface\\AddOns\\!Questie\\Icons\\available", |
||
1477 | priority = 2 |
||
1478 | }, |
||
1479 | ["availablesoon"] = { |
||
1480 | text = "Complete", |
||
1481 | path = "Interface\\AddOns\\!Questie\\Icons\\availablesoon", |
||
1482 | priority = 2 |
||
1483 | }, |
||
1484 | ["loot"] = { |
||
1485 | text = "Complete", |
||
1486 | path = "Interface\\AddOns\\!Questie\\Icons\\loot", |
||
1487 | priority = 3 |
||
1488 | }, |
||
1489 | ["item"] = { |
||
1490 | text = "Complete", |
||
1491 | path = "Interface\\AddOns\\!Questie\\Icons\\loot", |
||
1492 | priority = 3 |
||
1493 | }, |
||
1494 | ["event"] = { |
||
1495 | text = "Complete", |
||
1496 | path = "Interface\\AddOns\\!Questie\\Icons\\event", |
||
1497 | priority = 3 |
||
1498 | }, |
||
1499 | ["object"] = { |
||
1500 | text = "Complete", |
||
1501 | path = "Interface\\AddOns\\!Questie\\Icons\\object", |
||
1502 | priority = 3 |
||
1503 | }, |
||
1504 | ["slay"] = { |
||
1505 | text = "Complete", |
||
1506 | path = "Interface\\AddOns\\!Questie\\Icons\\slay", |
||
1507 | priority = 3 |
||
1508 | } |
||
1509 | }; |