· 4 years ago · Jan 06, 2021, 07:44 PM
1-- Made by Nnoggie, 2017-2020
2local AddonName, MDT = ...
3local L = MDT.L
4local mainFrameStrata = "HIGH"
5local canvasDrawLayer = "BORDER"
6
7
8local twipe,tinsert,tremove,tgetn,CreateFrame,tonumber,pi,max,min,atan2,abs,pairs,ipairs,GetCursorPosition,GameTooltip = table.wipe,table.insert,table.remove,table.getn,CreateFrame,tonumber,math.pi,math.max,math.min,math.atan2,math.abs,pairs,ipairs,GetCursorPosition,GameTooltip
9local SetPortraitTextureFromCreatureDisplayID,MouseIsOver = SetPortraitTextureFromCreatureDisplayID,MouseIsOver
10
11local sizex = 840
12local sizey = 555
13
14local mythicColor = "|cFFFFFFFF"
15MDT.BackdropColor = { 0.058823399245739, 0.058823399245739, 0.058823399245739, 0.9}
16
17local AceGUI = LibStub("AceGUI-3.0")
18local db
19local icon = LibStub("LibDBIcon-1.0")
20local LDB = LibStub("LibDataBroker-1.1"):NewDataObject("MythicDungeonTools", {
21 type = "data source",
22 text = "Mythic Dungeon Tools",
23 icon = "Interface\\ICONS\\inv_relics_hourglass",
24 OnClick = function(button,buttonPressed)
25 if buttonPressed == "RightButton" then
26 if db.minimap.lock then
27 icon:Unlock("MythicDungeonTools")
28 else
29 icon:Lock("MythicDungeonTools")
30 end
31 else
32 MDT:ShowInterface()
33 end
34 end,
35 OnTooltipShow = function(tooltip)
36 if not tooltip or not tooltip.AddLine then return end
37 tooltip:AddLine(mythicColor .."Mythic Dungeon Tools|r")
38 tooltip:AddLine(L["Click to toggle AddOn Window"])
39 tooltip:AddLine(L["Right-click to lock Minimap Button"])
40 end,
41})
42
43SLASH_MYTHICDUNGEONTOOLS1 = "/mplus"
44SLASH_MYTHICDUNGEONTOOLS2 = "/mdt"
45SLASH_MYTHICDUNGEONTOOLS3 = "/mythicdungeontools"
46
47BINDING_NAME_MDTTOGGLE = L["Toggle Window"]
48BINDING_NAME_MDTNPC = L["New NPC at Cursor Position"]
49BINDING_NAME_MDTWAYPOINT = L["New Patrol Waypoint at Cursor Position"]
50
51function SlashCmdList.MYTHICDUNGEONTOOLS(cmd, editbox)
52 local rqst, arg = strsplit(' ', cmd)
53 if rqst == "devmode" then
54 MDT:ToggleDevMode()
55 elseif rqst == "reset" then
56 MDT:ResetMainFramePos()
57 elseif rqst == "dc" then
58 MDT:ToggleDataCollection()
59 elseif rqst == "hptrack" then
60 MDT:ToggleHealthTrack()
61 else
62 MDT:ShowInterface()
63 end
64end
65
66function MDT:GetLocaleIndex()
67 local localeToIndex = {
68 ["enUS"] = 1,
69 ["deDE"] = 2,
70 ["esES"] = 3,
71 ["esMX"] = 4,
72 ["frFR"] = 5,
73 ["itIT"] = 6,
74 ["ptBR"] = 7,
75 ["ruRU"] = 8,
76 ["koKR"] = 9,
77 ["zhCN"] = 10,
78 ["zhTW"] = 11,
79 }
80 return localeToIndex[GetLocale()] or 1
81end
82
83local initFrames
84-------------------------
85--- Saved Variables ----
86-------------------------
87local defaultSavedVars = {
88 global = {
89 toolbarExpanded = true,
90 currentSeason = 5,
91 currentExpansion = 3,
92 scale = 1,
93 enemyForcesFormat = 2,
94 enemyStyle = 1,
95 currentDungeonIdx = 15,
96 currentDifficulty = 10,
97 xoffset = 0,
98 yoffset = -150,
99 defaultColor = "228b22",
100 anchorFrom = "TOP",
101 anchorTo = "TOP",
102 tooltipInCorner = false,
103 minimap = {
104 hide = false,
105 },
106 toolbar ={
107 color = {r=1,g=1,b=1,a=1},
108 brushSize = 3,
109 },
110 presets = {},
111 currentPreset = {},
112 dataCollectionActive = false,
113 colorPaletteInfo = {
114 autoColoring = true,
115 forceColorBlindMode = false,
116 colorPaletteIdx = 4,
117 customPaletteValues = {},
118 numberCustomColors = 12,
119 },
120 language = MDT:GetLocaleIndex(),
121 },
122}
123do
124 for i=1,37 do
125 defaultSavedVars.global.presets[i] = {
126 [1] = {text="Default",value={},colorPaletteInfo={autoColoring=true,colorPaletteIdx=4}},
127 [2] = {text="<New Preset>",value=0},
128 }
129 defaultSavedVars.global.currentPreset[i] = 1
130 end
131end
132
133-- Init db
134do
135 local frame = CreateFrame("Frame")
136 frame:RegisterEvent("ADDON_LOADED")
137 frame:RegisterEvent("GROUP_ROSTER_UPDATE")
138 frame:RegisterEvent("PLAYER_ENTERING_WORLD")
139 --TODO Register Affix Changed event
140 frame:SetScript("OnEvent", function(self, event, ...)
141 return MDT[event](self,...)
142 end)
143
144 function MDT.ADDON_LOADED(self, addon)
145 if addon == "MythicDungeonTools" then
146 db = LibStub("AceDB-3.0"):New("MythicDungeonToolsDB", defaultSavedVars).global
147 icon:Register("MythicDungeonTools", LDB, db.minimap)
148 if not db.minimap.hide then
149 icon:Show("MythicDungeonTools")
150 end
151
152 --if db.dataCollectionActive then MDT.DataCollection:Init() end
153 --fix db corruption
154 do
155 for _,presets in pairs(db.presets) do
156 for presetIdx,preset in pairs(presets) do
157 if presetIdx == 1 then
158 if preset.text ~= "Default" then
159 preset.text = "Default"
160 preset.value = {}
161 end
162 end
163 end
164 end
165 for k,v in pairs(db.currentPreset) do
166 if v <= 0 then db.currentPreset[k] = 1 end
167 end
168 end
169 --register AddOn Options
170 MDT:RegisterOptions()
171 self:UnregisterEvent("ADDON_LOADED")
172 end
173 end
174 local last = 0
175 function MDT.GROUP_ROSTER_UPDATE(self, addon)
176 --check not more than once per second (blizzard event spam)
177 local now = GetTime()
178 if last < now - 1 then
179 if not MDT.main_frame then return end
180 local inGroup = UnitInRaid("player") or IsInGroup()
181 MDT.main_frame.LinkToChatButton:SetDisabled(not inGroup)
182 MDT.main_frame.LiveSessionButton:SetDisabled(not inGroup)
183 if inGroup then
184 MDT.main_frame.LinkToChatButton.text:SetTextColor(1,0.8196,0)
185 if MDT.liveSessionActive then
186 MDT.main_frame.LiveSessionButton:SetText(L["*Live*"])
187 MDT.main_frame.LiveSessionButton.text:SetTextColor(0,1,0)
188 else
189 MDT.main_frame.LiveSessionButton:SetText(L["Live"])
190 MDT.main_frame.LiveSessionButton.text:SetTextColor(1,0.8196,0)
191 end
192 else
193 MDT.main_frame.LinkToChatButton.text:SetTextColor(0.5,0.5,0.5)
194 MDT.main_frame.LiveSessionButton.text:SetTextColor(0.5,0.5,0.5)
195 end
196 last = now
197 --MDT:RequestDataCollectionUpdate()
198 end
199 end
200 function MDT.PLAYER_ENTERING_WORLD(self, addon)
201 --initialize Blizzard_ChallengesUI
202 C_Timer.After(1,function()
203 LoadAddOn("Blizzard_ChallengesUI")
204 C_MythicPlus.RequestCurrentAffixes()
205 C_MythicPlus.RequestMapInfo()
206 C_MythicPlus.RequestRewards()
207 end)
208 self:UnregisterEvent("PLAYER_ENTERING_WORLD")
209 end
210
211end
212
213
214MDT.mapInfo = {}
215MDT.dungeonTotalCount = {}
216MDT.scaleMultiplier = {}
217--affixID as used in C_ChallengeMode.GetAffixInfo(affixID)
218--https://www.wowhead.com/affixes
219--lvl 4 affix, lvl 7 affix, tyrannical/fortified, seasonal affix
220local affixWeeks = {
221 [1] = {[1]=11,[2]=3,[3]=10,[4]=121}, -->>Bursting, Volcanic, Fortified
222 [2] = {[1]=0,[2]=0,[3]=0,[4]=0},
223 [3] = {[1]=0,[2]=0,[3]=0,[4]=0},
224 [4] = {[1]=0,[2]=0,[3]=0,[4]=0},
225 [5] = {[1]=0,[2]=0,[3]=0,[4]=0},
226 [6] = {[1]=0,[2]=0,[3]=0,[4]=0},
227 [7] = {[1]=0,[2]=0,[3]=0,[4]=0},
228 [8] = {[1]=7,[2]=4,[3]=9,[4]=121}, -->>Bolstering, Necrotic, Tyrannical
229 [9] = {[1]=124,[2]=122,[3]=10,[4]=121}, -->>Storming, Inspiring, Fortified
230 [10] = {[1]=11,[2]=13,[3]=9,[4]=121}, -->>Bursting, Explosive, Tyrannical
231 [11] = {[1]=4,[2]=7,[3]=10,[4]=121}, -->>Sanguine, Grievous, Fortified
232 [12] = {[1]=6,[2]=14,[3]=9,[4]=121}, -->>Raging, Quaking, Tyrannical
233}
234
235local dungeonList = {
236 [1] = L["Black Rook Hold"],
237 [2] = L["Cathedral of Eternal Night"],
238 [3] = L["Court of Stars"],
239 [4] = L["Darkheart Thicket"],
240 [5] = L["Eye of Azshara"],
241 [6] = L["Halls of Valor"],
242 [7] = L["Maw of Souls"],
243 [8] = L["Neltharion's Lair"],
244 [9] = L["Return to Karazhan Lower"],
245 [10] = L["Return to Karazhan Upper"],
246 [11] = L["Seat of the Triumvirate"],
247 [12] = L["The Arcway"],
248 [13] = L["Vault of the Wardens"],
249 [14] = " >"..L["Battle for Azeroth"],
250 [15] = L["Atal'Dazar"],
251 [16] = L["Freehold"],
252 [17] = L["Kings' Rest"],
253 [18] = L["Shrine of the Storm"],
254 [19] = L["Siege of Boralus"],
255 [20] = L["Temple of Sethraliss"],
256 [21] = L["The MOTHERLODE!!"],
257 [22] = L["The Underrot"],
258 [23] = L["Tol Dagor"],
259 [24] = L["Waycrest Manor"],
260 [25] = L["Mechagon - Junkyard"],
261 [26] = L["Mechagon - Workshop"],
262 [27] = " <"..L["Legion"],
263 [28] = " >"..L["Shadowlands"],
264 [29] = L["De Other Side"],
265 [30] = L["Halls of Atonement"],
266 [31] = L["Mists of Tirna Scithe"],
267 [32] = L["Plaguefall"],
268 [33] = L["Sanguine Depths"],
269 [34] = L["Spires of Ascension"],
270 [35] = L["The Necrotic Wake"],
271 [36] = L["Theater of Pain"],
272 [37] = " <"..L["Battle for Azeroth"],
273}
274function MDT:GetNumDungeons() return #dungeonList-1 end
275function MDT:GetDungeonName(idx) return dungeonList[idx] end
276
277local dungeonSubLevels = {
278 [1] = {
279 [1] = L["The Ravenscrypt"],
280 [2] = L["The Grand Hall"],
281 [3] = L["Ravenshold"],
282 [4] = L["The Rook's Host"],
283 [5] = L["Lord Ravencrest's Chamber"],
284 [6] = L["The Raven's Crown"],
285 },
286 [2] = {
287 [1] = L["Hall of the Moon"],
288 [2] = L["Twilight Grove"],
289 [3] = L["The Emerald Archives"],
290 [4] = L["Path of Illumination"],
291 [5] = L["Sacristy of Elune"],
292 },
293 [3] = {
294 [1] = L["Court of Stars Sublevel"],
295 [2] = L["The Jeweled Estate"],
296 [3] = L["The Balconies"],
297 },
298 [4] = {
299 [1] = L["Darkheart Thicket Sublevel"],
300 },
301 [5] = {
302 [1] = L["Eye of Azshara Sublevel"],
303 },
304 [6] = {
305 [1] = L["The High Gate"],
306 [2] = L["Field of the Eternal Hunt"],
307 [3] = L["Halls of Valor Sublevel"],
308 },
309 [7] = {
310 [1] = L["Helmouth Cliffs"],
311 [2] = L["The Hold"],
312 [3] = L["The Naglfar"],
313 },
314 [8] = {
315 [1] = L["Neltharion's Lair Sublevel"],
316 },
317 [9] = {
318 [1] = L["Master's Terrace"],
319 [2] = L["Opera Hall Balcony"],
320 [3] = L["The Guest Chambers"],
321 [4] = L["The Banquet Hall"],
322 [5] = L["Upper Livery Stables"],
323 [6] = L["The Servant's Quarters"],
324 },
325 [10] = {
326 [1] = L["Lower Broken Stair"],
327 [2] = L["Upper Broken Stair"],
328 [3] = L["The Menagerie"],
329 [4] = L["Guardian's Library"],
330 [5] = L["Library Floor"],
331 [6] = L["Upper Library"],
332 [7] = L["Gamesman's Hall"],
333 [8] = L["Netherspace"],
334 },
335 [11] = {
336 [1] = L["Seat of the Triumvirate Sublevel"],
337 },
338 [12] = {
339 [1] = L["The Arcway Sublevel"],
340 },
341 [13] = {
342 [1] = L["The Warden's Court"],
343 [2] = L["Vault of the Wardens Sublevel"],
344 [3] = L["Vault of the Betrayer"],
345 },
346 [15] = {
347 [1] = L["Atal'Dazar Sublevel"],
348 [2] = L["Sacrificial Pits"],
349 },
350 [16] = {
351 [1] = L["Freehold Sublevel"],
352 },
353 [17] = {
354 [1] = L["Kings' Rest Sublevel"],
355 },
356 [18] = {
357 [1] = L["Shrine of the Storm Sublevel"],
358 [2] = L["Storm's End"],
359 },
360 [19] = {
361 [1] = L["Siege of Boralus Sublevel"],
362 [2] = L["Siege of Boralus (Upstairs)"],
363 },
364 [20] = {
365 [1] = L["Temple of Sethraliss Sublevel"],
366 [2] = L["Atrium of Sethraliss"],
367 },
368 [21] = {
369 [1] = L["The MOTHERLODE!! Sublevel"],
370 },
371 [22] = {
372 [1] = L["The Underrot Sublevel"],
373 [2] = L["Ruin's Descent"],
374 },
375 [23] = {
376 [1] = L["Tol Dagor Sublevel1"],
377 [2] = L["The Drain"],
378 [3] = L["The Brig"],
379 [4] = L["Detention Block"],
380 [5] = L["Officer Quarters"],
381 [6] = L["Overseer's Redoubt"],
382 [7] = L["Overseer's Summit"],
383 },
384 [24] = {
385 [1] = L["The Grand Foyer"],
386 [2] = L["Upstairs"],
387 [3] = L["The Cellar"],
388 [4] = L["Catacombs"],
389 [5] = L["The Rupture"],
390 },
391 [25] = {
392 [1] = L["Mechagon Island"],
393 [2] = L["Mechagon Island (Tunnels)"],
394 },
395 [26] = {
396 [1] = L["The Robodrome"],
397 [2] = L["Waste Pipes"],
398 [3] = L["The Under Junk"],
399 [4] = L["Mechagon City"],
400 },
401 [29] = {
402 [1] = L["De Other Side"],
403 [2] = L["Mechagon"],
404 [3] = L["Zul'Gurub"],
405 [4] = L["Ardenweald"],
406 },
407 [30] = {
408 [1] = L["HallsOfAtonementFloor1"],
409 [2] = L["HallsOfAtonementFloor2"],
410 [3] = L["HallsOfAtonementFloor3"],
411 },
412 [31] = {
413 [1] = L["Mists of Tirna Scithe"],
414 },
415 [32] = {
416 [1] = L["Plaguefall"],
417 [2] = L["The Festering Sanctum"],
418 },
419 [33] = {
420 [1] = L["Sanguine DepthsFloor1"],
421 [2] = L["Sanguine DepthsFloor2"],
422 },
423 [34] = {
424 [1] = L["Honor's Ascent"],
425 [2] = L["Gardens of Repose"],
426 [3] = L["Font of Fealty"],
427 [4] = L["Seat of the Archon"],
428 },
429 [35] = {
430 [1] = L["TheNecroticWakeFloor1"],
431 [2] = L["TheNecroticWakeFloor2"],
432 [3] = L["TheNecroticWakeFloor3"],
433 },
434 [36] = {
435 [1] = L["TheaterOfPainFloor1"],
436 [2] = L["TheaterOfPainFloor2"],
437 [3] = L["TheaterOfPainFloor3"],
438 [4] = L["TheaterOfPainFloor4"],
439 [5] = L["TheaterOfPainFloor5"],
440 },
441}
442function MDT:GetDungeonSublevels()
443 return dungeonSubLevels
444end
445
446function MDT:GetSublevelName(dungeonIdx, sublevelIdx)
447 if not dungeonIdx then dungeonIdx = db.currentDungeonIdx end
448 return dungeonSubLevels[dungeonIdx][sublevelIdx]
449end
450
451MDT.dungeonMaps = {
452 [1] = {
453 [0]= "BlackRookHoldDungeon",
454 [1]= "BlackRookHoldDungeon1_",
455 [2]= "BlackRookHoldDungeon2_",
456 [3]= "BlackRookHoldDungeon3_",
457 [4]= "BlackRookHoldDungeon4_",
458 [5]= "BlackRookHoldDungeon5_",
459 [6]= "BlackRookHoldDungeon6_",
460 },
461 [2] = {
462 [0]= "TombofSargerasDungeon",
463 [1]= "TombofSargerasDungeon1_",
464 [2]= "TombofSargerasDungeon2_",
465 [3]= "TombofSargerasDungeon3_",
466 [4]= "TombofSargerasDungeon4_",
467 [5]= "TombofSargerasDungeon5_",
468 },
469 [3] = {
470 [0] = "SuramarNoblesDistrict",
471 [1] = "SuramarNoblesDistrict",
472 [2] = "SuramarNoblesDistrict1_",
473 [3] = "SuramarNoblesDistrict2_",
474 },
475 [4] = {
476 [0] = "DarkheartThicket",
477 [1] = "DarkheartThicket",
478 },
479 [5] = {
480 [0]= "AszunaDungeon",
481 [1]= "AszunaDungeon",
482 },
483 [6] = {
484 [0]= "Hallsofvalor",
485 [1]= "Hallsofvalor1_",
486 [2]= "Hallsofvalor",
487 [3]= "Hallsofvalor2_",
488 },
489
490 [7] = {
491 [0] = "HelheimDungeonDock",
492 [1] = "HelheimDungeonDock",
493 [2] = "HelheimDungeonDock1_",
494 [3] = "HelheimDungeonDock2_",
495 },
496 [8] = {
497 [0] = "NeltharionsLair",
498 [1] = "NeltharionsLair",
499 },
500 [9] = {
501 [0] = "LegionKarazhanDungeon",
502 [1] = "LegionKarazhanDungeon6_",
503 [2] = "LegionKarazhanDungeon5_",
504 [3] = "LegionKarazhanDungeon4_",
505 [4] = "LegionKarazhanDungeon3_",
506 [5] = "LegionKarazhanDungeon2_",
507 [6] = "LegionKarazhanDungeon1_",
508 },
509 [10] = {
510 [0] = "LegionKarazhanDungeon",
511 [1] = "LegionKarazhanDungeon7_",
512 [2] = "LegionKarazhanDungeon8_",
513 [3] = "LegionKarazhanDungeon9_",
514 [4] = "LegionKarazhanDungeon10_",
515 [5] = "LegionKarazhanDungeon11_",
516 [6] = "LegionKarazhanDungeon12_",
517 [7] = "LegionKarazhanDungeon13_",
518 [8] = "LegionKarazhanDungeon14_",
519 },
520 [11] = {
521 [0] = "ArgusDungeon",
522 [1] = "ArgusDungeon",
523 },
524 [12] = {
525 [0]= "SuamarCatacombsDungeon",
526 [1]= "SuamarCatacombsDungeon1_",
527 },
528 [13] = {
529 [0]= "VaultOfTheWardens",
530 [1]= "VaultOfTheWardens1_",
531 [2]= "VaultOfTheWardens2_",
532 [3]= "VaultOfTheWardens3_",
533 },
534 [15] = {
535 [0]= "CityOfGold",
536 [1]= "CityOfGold1_",
537 [2]= "CityOfGold2_",
538 },
539 [16] = {
540 [0]= "KulTirasPirateTownDungeon",
541 [1]= "KulTirasPirateTownDungeon",
542 },
543 [17] = {
544 [0] = "KingsRest",
545 [1] = "KingsRest1_"
546 },
547 [18] = {
548 [0] = "ShrineOfTheStorm",
549 [1] = "ShrineOfTheStorm",
550 [2] = "ShrineOfTheStorm1_",
551 },
552 [19] = {
553 [0] = "SiegeOfBoralus",
554 [1] = "SiegeOfBoralus",
555 [2] = "SiegeOfBoralus",
556 },
557 [20] = {
558 [0] = "TempleOfSethralissA",
559 [1] = "TempleOfSethralissA",
560 [2] = "TempleOfSethralissB",
561 },
562 [21] = {
563 [0] = "KezanDungeon",
564 [1] = "KezanDungeon",
565 },
566 [22] = {
567 [0] = "UnderrotExterior",
568 [1] = "UnderrotExterior",
569 [2] = "UnderrotInterior",
570 },
571 [23] = {
572 [0] = "PrisonDungeon",
573 [1] = "PrisonDungeon",
574 [2] = "PrisonDungeon1_",
575 [3] = "PrisonDungeon2_",
576 [4] = "PrisonDungeon3_",
577 [5] = "PrisonDungeon4_",
578 [6] = "PrisonDungeon5_",
579 [7] = "PrisonDungeon6_",
580 },
581 [24] = {
582 [0] = "Waycrest",
583 [1] = "Waycrest1_",
584 [2] = "Waycrest2_",
585 [3] = "Waycrest3_",
586 [4] = "Waycrest4_",
587 [5] = "Waycrest5_",
588 },
589 [25] = {
590 [0] = "MechagonDungeon",
591 [1] = "MechagonDungeonExterior",
592 [2] = "MechagonDungeonExterior",
593 },
594 [26] = {
595 [0] = "MechagonDungeon",
596 [1] = "MechagonDungeon1_",
597 [2] = "MechagonDungeon2_",
598 [3] = "MechagonDungeon3_",
599 [4] = "MechagonDungeon4_",
600 },
601 [29] = {
602 [0] = "DeOtherSide_Ardenweald",
603 [1] = "DeOtherSide_Main",
604 [2] = "DeOtherSide_Gnome",
605 [3] = "DeOtherSide_Hakkar",
606 [4] = "DeOtherSide_Ardenweald",
607 },
608 [30] = {
609 [0] = "HallsOfAtonement_A",
610 [1] = "HallsOfAttonementExterior",
611 [2] = "HallsOfAtonement_A",
612 [3] = "HallsOfAtonement_B",
613 },
614 [31] = {
615 [0] = "MistsOfTirneScithe",
616 [1] = "MistsOfTirneScithe",
617 },
618 [32] = {
619 [0] = "Plaguefall",
620 [1] = "Plaguefall",
621 [2] = "Plaguefall_B",
622 },
623 [33] = {
624 [0] = "SanguineDepths_A",
625 [1] = "SanguineDepths_A",
626 [2] = "SanguineDepths_B",
627 },
628 [34] = {
629 [0] = "SpiresOfAscension_A",
630 [1] = "SpiresOfAscension_A",
631 [2] = "SpiresOfAscension_B",
632 [3] = "SpiresOfAscension_C",
633 [4] = "SpiresOfAscension_D",
634 },
635 [35] = {
636 [0] = "NecroticWake_A",
637 [1] = "NecroticWake_Exterior",
638 [2] = "NecroticWake_A",
639 [3] = "NecroticWake_B",
640 },
641 [36] = {
642 [0] = "TheaterOfPain",
643 [1] = "TheaterOfPain",
644 [2] = "TheaterOfPain_Warlord",
645 [3] = "TheaterOfPain_Lich",
646 [4] = "TheaterOfPain_AbomTop",
647 [5] = "TheaterOfPain_AbomBot",
648 },
649
650}
651MDT.dungeonBosses = {}
652MDT.dungeonEnemies = {}
653MDT.mapPOIs = {}
654
655function MDT:GetDB()
656 return db
657end
658
659local framesInitialized
660function MDT:ShowInterface(force)
661 if not framesInitialized then initFrames() end
662 if self.main_frame:IsShown() and not force then
663 MDT:HideInterface()
664 else
665 self.main_frame:Show()
666 self.main_frame.HelpButton:Show()
667 self:CheckCurrentZone()
668 --edge case if user closed MDT window while in the process of dragging a corrupted blip
669 if self.draggedBlip then
670 if MDT.liveSessionActive then
671 MDT:LiveSession_SendCorruptedPositions(MDT:GetRiftOffsets())
672 end
673 self:UpdateMap()
674 self.draggedBlip = nil
675 end
676 MDT:UpdateBottomText()
677 end
678end
679
680function MDT:HideInterface()
681 self.main_frame:Hide()
682 self.main_frame.HelpButton:Hide()
683end
684
685function MDT:ToggleDevMode()
686 db.devMode = not db.devMode
687 ReloadUI()
688end
689
690function MDT:ToggleDataCollection()
691 db.dataCollectionActive = not db.dataCollectionActive
692 print(string.format("%sMDT|r: DataCollection %s. Reload Interface!", mythicColor,db.dataCollectionActive and "|cFF00FF00Enabled|r" or "|cFFFF0000Disabled|r"))
693end
694
695function MDT:ToggleHealthTrack()
696 MDT.DataCollection:InitHealthTrack()
697 print(string.format("%sMDT|r: HealthTrack %s.", mythicColor,"|cFF00FF00Enabled|r"))
698end
699
700
701function MDT:CreateMenu()
702 -- Close button
703 self.main_frame.closeButton = CreateFrame("Button", "MDTCloseButton", self.main_frame, "UIPanelCloseButton")
704 self.main_frame.closeButton:ClearAllPoints()
705 self.main_frame.closeButton:SetPoint("TOPRIGHT", self.main_frame.sidePanel, "TOPRIGHT", 0, 0)
706 self.main_frame.closeButton:SetScript("OnClick", function() self:HideInterface() end)
707 self.main_frame.closeButton:SetFrameLevel(4)
708
709 --Maximize Button
710 self.main_frame.maximizeButton = CreateFrame("Button", "MDTMaximizeButton", self.main_frame, "MaximizeMinimizeButtonFrameTemplate")
711 self.main_frame.maximizeButton:ClearAllPoints()
712 self.main_frame.maximizeButton:SetPoint("RIGHT", self.main_frame.closeButton, "LEFT", 0, 0)
713 self.main_frame.maximizeButton:SetFrameLevel(4)
714 db.maximized = db.maximized or false
715 if not db.maximized then self.main_frame.maximizeButton:Minimize() end
716 self.main_frame.maximizeButton:SetOnMaximizedCallback(self.Maximize)
717 self.main_frame.maximizeButton:SetOnMinimizedCallback(self.Minimize)
718
719 --return to live preset
720 self.main_frame.liveReturnButton = CreateFrame("Button", "MDTLiveReturnButton", self.main_frame, "UIPanelCloseButton")
721 local liveReturnButton = self.main_frame.liveReturnButton
722 liveReturnButton:ClearAllPoints()
723 liveReturnButton:SetPoint("RIGHT", self.main_frame.topPanel, "RIGHT", 0, 0)
724 liveReturnButton.Icon = liveReturnButton:CreateTexture(nil, "OVERLAY")
725 liveReturnButton.Icon:SetTexture("Interface\\Buttons\\UI-RefreshButton")
726 liveReturnButton.Icon:SetSize(16,16)
727 liveReturnButton.Icon:SetTexCoord(1, 0, 0, 1) --flipped image
728 liveReturnButton.Icon:SetPoint("CENTER",liveReturnButton,"CENTER")
729 liveReturnButton:SetScript("OnClick", function() self:ReturnToLivePreset() end)
730 liveReturnButton:SetFrameLevel(4)
731 liveReturnButton.tooltip = L["Return to the live preset"]
732
733 --set preset as new live preset
734 self.main_frame.setLivePresetButton = CreateFrame("Button", "MDTSetLivePresetButton", self.main_frame, "UIPanelCloseButton")
735 local setLivePresetButton = self.main_frame.setLivePresetButton
736 setLivePresetButton:ClearAllPoints()
737 setLivePresetButton:SetPoint("RIGHT", liveReturnButton, "LEFT", 0, 0)
738 setLivePresetButton.Icon = setLivePresetButton:CreateTexture(nil, "OVERLAY")
739 setLivePresetButton.Icon:SetTexture("Interface\\ChatFrame\\ChatFrameExpandArrow")
740 setLivePresetButton.Icon:SetSize(16,16)
741 setLivePresetButton.Icon:SetPoint("CENTER",setLivePresetButton,"CENTER")
742 setLivePresetButton:SetScript("OnClick", function() self:SetLivePreset() end)
743 setLivePresetButton:SetFrameLevel(4)
744 setLivePresetButton.tooltip = L["Make this preset the live preset"]
745
746 self:SkinMenuButtons()
747
748 --Resize Handle
749 self.main_frame.resizer = CreateFrame("BUTTON", nil, self.main_frame.sidePanel)
750 local resizer = self.main_frame.resizer
751 resizer:SetPoint("BOTTOMRIGHT", self.main_frame.sidePanel,"BOTTOMRIGHT",7,-7)
752 resizer:SetSize(25, 25)
753 resizer:EnableMouse()
754 resizer:SetScript("OnMouseDown", function()
755 self.main_frame:StartSizing("BOTTOMRIGHT")
756 self:StartScaling()
757 self:HideAllPresetObjects()
758 self:ReleaseHullTextures()
759 self.main_frame:SetScript("OnSizeChanged", function()
760 local height = self.main_frame:GetHeight()
761 self:SetScale(height/sizey)
762 end)
763 end)
764 resizer:SetScript("OnMouseUp", function()
765 self.main_frame:StopMovingOrSizing()
766 self:UpdateEnemyInfoFrame()
767 self:UpdateMap()
768 self:CreateTutorialButton(self.main_frame)
769 self.main_frame:SetScript("OnSizeChanged", function() end)
770 end)
771 local normal = resizer:CreateTexture(nil, "OVERLAY")
772 normal:SetTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Up")
773 normal:SetTexCoord(0, 1, 0, 1)
774 normal:SetPoint("BOTTOMLEFT", resizer, 0, 6)
775 normal:SetPoint("TOPRIGHT", resizer, -6, 0)
776 resizer:SetNormalTexture(normal)
777 local pushed = resizer:CreateTexture(nil, "OVERLAY")
778 pushed:SetTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Down")
779 pushed:SetTexCoord(0, 1, 0, 1)
780 pushed:SetPoint("BOTTOMLEFT", resizer, 0, 6)
781 pushed:SetPoint("TOPRIGHT", resizer, -6, 0)
782 resizer:SetPushedTexture(pushed)
783 local highlight = resizer:CreateTexture(nil, "OVERLAY")
784 highlight:SetTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Highlight")
785 highlight:SetTexCoord(0, 1, 0, 1)
786 highlight:SetPoint("BOTTOMLEFT", resizer, 0, 6)
787 highlight:SetPoint("TOPRIGHT", resizer, -6, 0)
788 resizer:SetHighlightTexture(highlight)
789
790end
791
792function MDT:SkinMenuButtons()
793 --attempt to skin close button for ElvUI
794 if IsAddOnLoaded("ElvUI") then
795 local E, L, V, P, G = unpack(ElvUI)
796 local S
797 if E then S = E:GetModule("Skins") end
798 if S then
799 S:HandleCloseButton(self.main_frame.closeButton)
800 S:HandleMaxMinFrame(self.main_frame.maximizeButton)
801 S:HandleButton(self.main_frame.liveReturnButton)
802 self.main_frame.liveReturnButton:Size(26)
803 --self.main_frame.liveReturnButton.Icon:SetVertexColor(0,1,1,1)
804 S:HandleButton(self.main_frame.setLivePresetButton)
805 self.main_frame.setLivePresetButton:Size(26)
806 self.main_frame.setLivePresetButton.Icon:SetVertexColor(1, .82, 0, 0.8)
807 end
808 end
809end
810
811---GetDefaultMapPanelSize
812function MDT:GetDefaultMapPanelSize()
813 return sizex,sizey
814end
815
816---GetScale
817---Returns scale factor stored in db
818function MDT:GetScale()
819 if not db.scale then db.scale = 1 end
820 return db.scale
821end
822
823
824local oldScrollValues = {}
825---StartScaling
826---Stores values when we start scaling the frame
827function MDT:StartScaling()
828 local f = self.main_frame
829 oldScrollValues.oldScrollH = f.scrollFrame:GetHorizontalScroll()
830 oldScrollValues.oldScrollV = f.scrollFrame:GetVerticalScroll()
831 oldScrollValues.oldSizeX = f.scrollFrame:GetWidth()
832 oldScrollValues.oldSizeY = f.scrollFrame:GetHeight()
833 HelpPlate_Hide(true)
834 self:DungeonEnemies_HideAllBlips()
835 self:POI_HideAllPoints()
836 self:KillAllAnimatedLines()
837end
838
839
840---SetScale
841---Scales the map frame and it's sub frames to a factor and stores the scale in db
842function MDT:SetScale(scale)
843 local f = self.main_frame
844 local newSizex = sizex*scale
845 local newSizey = sizey*scale
846 f:SetSize(newSizex,newSizey)
847 f.scrollFrame:SetSize(newSizex, newSizey)
848 f.mapPanelFrame:SetSize(newSizex, newSizey)
849 for i=1,12 do
850 f["mapPanelTile"..i]:SetSize((newSizex/4+5*scale),(newSizex/4+5*scale))
851 end
852 for i=1,10 do
853 for j=1,15 do
854 f["largeMapPanelTile"..i..j]:SetSize(newSizex/15,newSizex/15)
855 end
856 end
857 f.scrollFrame:SetVerticalScroll(oldScrollValues.oldScrollV * (newSizey / oldScrollValues.oldSizeY))
858 f.scrollFrame:SetHorizontalScroll(oldScrollValues.oldScrollH * (newSizex / oldScrollValues.oldSizeX))
859 f.scrollFrame.cursorY = f.scrollFrame.cursorY * (newSizey / oldScrollValues.oldSizeY)
860 f.scrollFrame.cursorX = f.scrollFrame.cursorX * (newSizex / oldScrollValues.oldSizeX)
861 self:ZoomMap(0)
862 db.scale = scale
863 db.nonFullscreenScale = scale
864end
865
866function MDT:GetFullScreenSizes()
867 local newSizey = GetScreenHeight()-60 --top and bottom panel 30 each
868 local newSizex = newSizey*(sizex/sizey)
869 local isNarrow
870 if newSizex+251>GetScreenWidth() then --251 sidebar
871 newSizex = GetScreenWidth()-251
872 newSizey = newSizex*(sizey/sizex)
873 isNarrow = true
874 end
875 local scale = newSizey/sizey --use this for adjusting NPC / POI positions later
876 return newSizex, newSizey, scale, isNarrow
877end
878
879---Maximize
880---FULLSCREEN the UI
881function MDT:Maximize()
882 local f = MDT.main_frame
883
884 local oldScrollH = f.scrollFrame:GetHorizontalScroll()
885 local oldScrollV = f.scrollFrame:GetVerticalScroll()
886 local oldSizeX = f.scrollFrame:GetWidth()
887 local oldSizeY = f.scrollFrame:GetHeight()
888 if not f.blackoutFrame then
889 f.blackoutFrame = CreateFrame("Frame", "MDTBlackoutFrame", f)
890 f.blackoutFrame:EnableMouse(true)
891 f.blackoutFrameTex = f.blackoutFrame:CreateTexture(nil, "BACKGROUND")
892 f.blackoutFrameTex:SetAllPoints()
893 f.blackoutFrameTex:SetDrawLayer(canvasDrawLayer, -6)
894 f.blackoutFrameTex:SetColorTexture(0.058823399245739,0.058823399245739,0.058823399245739,1)
895 f.blackoutFrame:ClearAllPoints()
896 f.blackoutFrame:SetAllPoints(UIParent)
897 end
898 f.blackoutFrame:Show()
899 f.topPanel:RegisterForDrag(nil)
900 f.bottomPanel:RegisterForDrag(nil)
901 local newSizex, newSizey, scale, isNarrow = MDT:GetFullScreenSizes()
902 db.scale = scale
903 f:ClearAllPoints()
904 if not isNarrow then
905 f:SetPoint("TOP", UIParent,"TOP", -(f.sidePanel:GetWidth()/2), -30)
906 else
907 f:SetPoint("LEFT", UIParent,"LEFT")
908 end
909 f:SetSize(newSizex,newSizey)
910 f.scrollFrame:SetSize(newSizex, newSizey)
911 f.mapPanelFrame:SetSize(newSizex, newSizey)
912 for i=1,12 do
913 f["mapPanelTile"..i]:SetSize((newSizex/4+5*db.scale),(newSizex/4+5*db.scale))
914 end
915 for i=1,10 do
916 for j=1,15 do
917 f["largeMapPanelTile"..i..j]:SetSize(newSizex/15,newSizex/15)
918 end
919 end
920 f.scrollFrame:SetVerticalScroll(oldScrollV * (newSizey / oldSizeY))
921 f.scrollFrame:SetHorizontalScroll(oldScrollH * (newSizex / oldSizeX))
922 f.scrollFrame.cursorY = f.scrollFrame.cursorY * (newSizey / oldSizeY)
923 f.scrollFrame.cursorX = f.scrollFrame.cursorX * (newSizex / oldSizeX)
924 MDT:ZoomMap(0)
925 MDT:UpdateEnemyInfoFrame()
926 MDT:UpdateMap()
927 if db.devMode then
928 f.devPanel:ClearAllPoints()
929 f.devPanel:SetPoint("TOPLEFT",f,"TOPLEFT",0,-45)
930 end
931 f.resizer:Hide()
932 MDT:CreateTutorialButton(MDT.main_frame)
933 db.maximized = true
934end
935
936---Minimize
937---Restore normal UI
938function MDT:Minimize()
939 local f = MDT.main_frame
940
941 local oldScrollH = f.scrollFrame:GetHorizontalScroll()
942 local oldScrollV = f.scrollFrame:GetVerticalScroll()
943 local oldSizeX = f.scrollFrame:GetWidth()
944 local oldSizeY = f.scrollFrame:GetHeight()
945 if f.blackoutFrame then f.blackoutFrame:Hide() end
946 f.topPanel:RegisterForDrag("LeftButton")
947 f.bottomPanel:RegisterForDrag("LeftButton")
948 db.scale = db.nonFullscreenScale
949 local newSizex = sizex*db.scale
950 local newSizey = sizey*db.scale
951 f:ClearAllPoints()
952 f:SetPoint(db.anchorTo, UIParent,db.anchorFrom, db.xoffset, db.yoffset)
953 f:SetSize(newSizex,newSizey)
954 f.scrollFrame:SetSize(newSizex, newSizey)
955 f.mapPanelFrame:SetSize(newSizex, newSizey)
956 for i=1,12 do
957 f["mapPanelTile"..i]:SetSize(newSizex/4+(5*db.scale),newSizex/4+(5*db.scale))
958 end
959 for i=1,10 do
960 for j=1,15 do
961 f["largeMapPanelTile"..i..j]:SetSize(newSizex/15,newSizex/15)
962 end
963 end
964 f.scrollFrame:SetVerticalScroll(oldScrollV * (newSizey / oldSizeY))
965 f.scrollFrame:SetHorizontalScroll(oldScrollH * (newSizex / oldSizeX))
966 f.scrollFrame.cursorY = f.scrollFrame.cursorY * (newSizey / oldSizeY)
967 f.scrollFrame.cursorX = f.scrollFrame.cursorX * (newSizex / oldSizeX)
968 MDT:ZoomMap(0)
969 MDT:UpdateEnemyInfoFrame()
970 MDT:UpdateMap()
971 if db.devMode then
972 f.devPanel:ClearAllPoints()
973 f.devPanel:SetPoint("TOPRIGHT",f.topPanel,"TOPLEFT",0,0)
974 end
975 f.resizer:Show()
976 MDT:CreateTutorialButton(MDT.main_frame)
977
978 db.maximized = false
979end
980
981function MDT:SkinProgressBar(progressBar)
982 local bar = progressBar and progressBar.Bar
983 if not bar then return end
984 bar.Icon:Hide()
985 bar.IconBG:Hide()
986 if IsAddOnLoaded("ElvUI") then
987 local E, L, V, P, G = unpack(ElvUI)
988 if bar.BarFrame then bar.BarFrame:Hide() end
989 if bar.BarFrame2 then bar.BarFrame2:Hide() end
990 if bar.BarFrame3 then bar.BarFrame3:Hide() end
991 if bar.BarGlow then bar.BarGlow:Hide() end
992 if bar.Sheen then bar.Sheen:Hide() end
993 if bar.IconBG then bar.IconBG:SetAlpha(0) end
994 if bar.BorderLeft then bar.BorderLeft:SetAlpha(0) end
995 if bar.BorderRight then bar.BorderRight:SetAlpha(0) end
996 if bar.BorderMid then bar.BorderMid:SetAlpha(0) end
997 bar:Height(18)
998 bar:StripTextures()
999 bar:CreateBackdrop("Transparent")
1000 bar:SetStatusBarTexture(E.media.normTex)
1001 local label = bar.Label
1002 if not label then return end
1003 label:ClearAllPoints()
1004 label:SetPoint("CENTER",bar,"CENTER")
1005 end
1006end
1007
1008function MDT:IsFrameOffScreen()
1009 local topPanel = MDT.main_frame.topPanel
1010 local bottomPanel = MDT.main_frame.bottomPanel
1011 local width = GetScreenWidth()
1012 local height = GetScreenHeight()
1013 local left = topPanel:GetLeft()-->width
1014 local right = topPanel:GetRight()--<0
1015 local bottom = topPanel:GetBottom()--<0
1016 local top = bottomPanel:GetTop()-->height
1017 return left>width or right<0 or bottom<0 or top>height
1018end
1019
1020local bottomTips = {
1021 [1] = L["Please report any bugs on https://github.com/Nnoggie/MythicDungeonTools/issues"],
1022 [2] = L["Hold CTRL to single-select enemies."],
1023 [3] = L["Hold SHIFT to create a new pull while selecting enemies."],
1024 [4] = L["Hold SHIFT to delete all presets with the delete preset button."],
1025 [5] = L["Right click a pull for more options."],
1026 [6] = L["Right click an enemy to open the enemy info window."],
1027 [7] = L["Drag the bottom right edge to resize MDT."],
1028 [8] = L["Click the fullscreen button for a maximized view of MDT."],
1029 [9] = L["Use /mdt reset to restore the default position and scale of MDT."],
1030 [10] = L["Mouseover the Live button while in a group to learn more about Live mode."],
1031 [11] = L["You are using MDT. You rock!"],
1032 [12] = L["You can choose from different color palettes in the automatic pull coloring settings menu."],
1033 [13] = L["You can cycle through different floors by holding CTRL and using the mousewheel."],
1034 [14] = L["You can cycle through dungeons by holding ALT and using the mousewheel."],
1035 [15] = L["Mouseover a patrolling enemy with a blue border to view the patrol path."],
1036 [16] = L["Expand the top toolbar to gain access to drawing and note features."],
1037 [17] = L["ConnectedTip"],
1038}
1039
1040function MDT:UpdateBottomText()
1041 local f = self.main_frame.bottomPanelString
1042 f:SetText(bottomTips[math.random(#bottomTips)])
1043end
1044
1045function MDT:MakeTopBottomTextures(frame)
1046 frame:SetMovable(true)
1047 if frame.topPanel == nil then
1048 frame.topPanel = CreateFrame("Frame", "MDTTopPanel", frame)
1049 frame.topPanelTex = frame.topPanel:CreateTexture(nil, "BACKGROUND")
1050 frame.topPanelTex:SetAllPoints()
1051 frame.topPanelTex:SetDrawLayer(canvasDrawLayer, -5)
1052 frame.topPanelTex:SetColorTexture(unpack(MDT.BackdropColor))
1053 frame.topPanelString = frame.topPanel:CreateFontString("MDT name")
1054 --use default font if ElvUI is enabled
1055 --if IsAddOnLoaded("ElvUI") then
1056 frame.topPanelString:SetFontObject("GameFontNormalMed3")
1057 frame.topPanelString:SetTextColor(1, 1, 1, 1)
1058 frame.topPanelString:SetJustifyH("CENTER")
1059 frame.topPanelString:SetJustifyV("CENTER")
1060 --frame.topPanelString:SetWidth(600)
1061 frame.topPanelString:SetHeight(20)
1062 frame.topPanelString:SetText("Mythic Dungeon Tools")
1063 frame.topPanelString:ClearAllPoints()
1064 frame.topPanelString:SetPoint("CENTER", frame.topPanel, "CENTER", 10, 0)
1065 frame.topPanelString:Show()
1066 --frame.topPanelString:SetFont(frame.topPanelString:GetFont(), 20)
1067 end
1068
1069 frame.topPanel:ClearAllPoints()
1070 frame.topPanel:SetHeight(30)
1071 frame.topPanel:SetPoint("BOTTOMLEFT", frame, "TOPLEFT")
1072 frame.topPanel:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT")
1073
1074 frame.topPanel:EnableMouse(true)
1075 frame.topPanel:RegisterForDrag("LeftButton")
1076 frame.topPanel:SetScript("OnDragStart", function(self,button)
1077 frame:SetMovable(true)
1078 frame:StartMoving()
1079 end)
1080 frame.topPanel:SetScript("OnDragStop", function(self,button)
1081 frame:StopMovingOrSizing()
1082 frame:SetMovable(false)
1083 if MDT:IsFrameOffScreen() then
1084 MDT:ResetMainFramePos(true)
1085 else
1086 local from,_,to,x,y = MDT.main_frame:GetPoint()
1087 db.anchorFrom = from
1088 db.anchorTo = to
1089 db.xoffset,db.yoffset = x,y
1090 end
1091 end)
1092
1093 if frame.bottomPanel == nil then
1094 frame.bottomPanel = CreateFrame("Frame", "MDTBottomPanel", frame)
1095 frame.bottomPanelTex = frame.bottomPanel:CreateTexture(nil, "BACKGROUND")
1096 frame.bottomPanelTex:SetAllPoints()
1097 frame.bottomPanelTex:SetDrawLayer(canvasDrawLayer, -5)
1098 frame.bottomPanelTex:SetColorTexture(unpack(MDT.BackdropColor))
1099 end
1100
1101 frame.bottomPanel:ClearAllPoints()
1102 frame.bottomPanel:SetHeight(30)
1103 frame.bottomPanel:SetPoint("TOPLEFT", frame, "BOTTOMLEFT")
1104 frame.bottomPanel:SetPoint("TOPRIGHT", frame, "BOTTOMRIGHT")
1105
1106 frame.bottomPanelString = frame.bottomPanel:CreateFontString("MDTMid")
1107 frame.bottomPanelString:SetFontObject("GameFontNormalSmall")
1108 frame.bottomPanelString:SetJustifyH("CENTER")
1109 frame.bottomPanelString:SetJustifyV("CENTER")
1110 frame.bottomPanelString:SetPoint("CENTER", frame.bottomPanel, "CENTER", 0, 0)
1111 frame.bottomPanelString:SetTextColor(1, 1, 1, 1)
1112 frame.bottomPanelString:Show()
1113
1114 frame.bottomLeftPanelString = frame.bottomPanel:CreateFontString("MDTVersion")
1115 frame.bottomLeftPanelString:SetFontObject("GameFontNormalSmall")
1116 frame.bottomLeftPanelString:SetJustifyH("LEFT")
1117 frame.bottomLeftPanelString:SetJustifyV("CENTER")
1118 frame.bottomLeftPanelString:SetPoint("LEFT", frame.bottomPanel, "LEFT", 0, 0)
1119 frame.bottomLeftPanelString:SetTextColor(1, 1, 1, 1)
1120 frame.bottomLeftPanelString:SetText(" v"..GetAddOnMetadata(AddonName, "Version"))
1121 frame.bottomLeftPanelString:Show()
1122
1123 frame.bottomPanel:EnableMouse(true)
1124 frame.bottomPanel:RegisterForDrag("LeftButton")
1125 frame.bottomPanel:SetScript("OnDragStart", function(self,button)
1126 frame:SetMovable(true)
1127 frame:StartMoving()
1128 end)
1129 frame.bottomPanel:SetScript("OnDragStop", function(self,button)
1130 frame:StopMovingOrSizing()
1131 frame:SetMovable(false)
1132 if MDT:IsFrameOffScreen() then
1133 MDT:ResetMainFramePos(true)
1134 else
1135 local from,_,to,x,y = MDT.main_frame:GetPoint()
1136 db.anchorFrom = from
1137 db.anchorTo = to
1138 db.xoffset,db.yoffset = x,y
1139 end
1140 end)
1141end
1142
1143function MDT:MakeSidePanel(frame)
1144
1145 if frame.sidePanel == nil then
1146 frame.sidePanel = CreateFrame("Frame", "MDTSidePanel", frame)
1147 frame.sidePanelTex = frame.sidePanel:CreateTexture(nil, "BACKGROUND")
1148 frame.sidePanelTex:SetAllPoints()
1149 frame.sidePanelTex:SetDrawLayer(canvasDrawLayer, -5)
1150 frame.sidePanelTex:SetColorTexture(unpack(MDT.BackdropColor))
1151 frame.sidePanelTex:Show()
1152 end
1153 frame.sidePanel:EnableMouse(true)
1154
1155 frame.sidePanel:ClearAllPoints()
1156 frame.sidePanel:SetWidth(251)
1157 frame.sidePanel:SetPoint("TOPLEFT", frame, "TOPRIGHT", 0, 30)
1158 frame.sidePanel:SetPoint("BOTTOMLEFT", frame, "BOTTOMRIGHT", 0, -30)
1159
1160 frame.sidePanelString = frame.sidePanel:CreateFontString("MDTSidePanelText")
1161 frame.sidePanelString:SetFont("Fonts\\FRIZQT__.TTF", 10)
1162 frame.sidePanelString:SetTextColor(1, 1, 1, 1)
1163 frame.sidePanelString:SetJustifyH("LEFT")
1164 frame.sidePanelString:SetJustifyV("TOP")
1165 frame.sidePanelString:SetWidth(200)
1166 frame.sidePanelString:SetHeight(500)
1167 frame.sidePanelString:SetText("")
1168 frame.sidePanelString:ClearAllPoints()
1169 frame.sidePanelString:SetPoint("TOPLEFT", frame.sidePanel, "TOPLEFT", 33, -120-30-25)
1170 frame.sidePanelString:Hide()
1171
1172 frame.sidePanel.WidgetGroup = AceGUI:Create("SimpleGroup")
1173 frame.sidePanel.WidgetGroup:SetWidth(245)
1174 frame.sidePanel.WidgetGroup:SetHeight(frame:GetHeight()+(frame.topPanel:GetHeight()*2)-31)
1175 frame.sidePanel.WidgetGroup:SetPoint("TOP",frame.sidePanel,"TOP",3,-1)
1176 frame.sidePanel.WidgetGroup:SetLayout("Flow")
1177
1178 frame.sidePanel.WidgetGroup.frame:SetFrameStrata(mainFrameStrata)
1179 if not frame.sidePanel.WidgetGroup.frame.SetBackdrop then
1180 Mixin(frame.sidePanel.WidgetGroup.frame, BackdropTemplateMixin)
1181 end
1182 frame.sidePanel.WidgetGroup.frame:SetBackdropColor(1,1,1,0)
1183 frame.sidePanel.WidgetGroup.frame:Hide()
1184
1185 --dirty hook to make widgetgroup show/hide
1186 local originalShow,originalHide = frame.Show,frame.Hide
1187 function frame:Show(...)
1188 frame.sidePanel.WidgetGroup.frame:Show()
1189 return originalShow(self, ...)
1190 end
1191 function frame:Hide(...)
1192 frame.sidePanel.WidgetGroup.frame:Hide()
1193 MDT.pullTooltip:Hide()
1194 return originalHide(self, ...)
1195 end
1196
1197 --preset selection
1198 frame.sidePanel.WidgetGroup.PresetDropDown = AceGUI:Create("Dropdown")
1199 local dropdown = frame.sidePanel.WidgetGroup.PresetDropDown
1200 dropdown.frame:SetWidth(170)
1201 dropdown.text:SetJustifyH("LEFT")
1202 dropdown:SetCallback("OnValueChanged",function(widget,callbackName,key)
1203 if db.presets[db.currentDungeonIdx][key].value==0 then
1204 MDT:OpenNewPresetDialog()
1205 MDT.main_frame.sidePanelDeleteButton:SetDisabled(true)
1206 MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(0.5,0.5,0.5)
1207 else
1208 if key == 1 then
1209 MDT.main_frame.sidePanelDeleteButton:SetDisabled(true)
1210 MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(0.5,0.5,0.5)
1211 else
1212 if not MDT.liveSessionActive then
1213 MDT.main_frame.sidePanelDeleteButton:SetDisabled(false)
1214 MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(1,0.8196,0)
1215 else
1216 MDT.main_frame.sidePanelDeleteButton:SetDisabled(true)
1217 MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(0.5,0.5,0.5)
1218 end
1219 end
1220 db.currentPreset[db.currentDungeonIdx] = key
1221 --Set affix dropdown to preset week
1222 --frame.sidePanel.affixDropdown:SetAffixWeek(MDT:GetCurrentPreset().week or MDT:GetCurrentAffixWeek())
1223 --UpdateMap is called in SetAffixWeek, no need to call twice
1224 MDT:UpdateMap()
1225 frame.sidePanel.affixDropdown:SetAffixWeek(MDT:GetCurrentPreset().week or MDT:GetCurrentAffixWeek() or 1)
1226 end
1227 end)
1228 MDT:UpdatePresetDropDown()
1229 frame.sidePanel.WidgetGroup:AddChild(dropdown)
1230
1231 ---new profile,rename,export,delete
1232 local buttonWidth = 80
1233 frame.sidePanelNewButton = AceGUI:Create("Button")
1234 frame.sidePanelNewButton:SetText(L["New"])
1235 frame.sidePanelNewButton:SetWidth(buttonWidth)
1236 --button fontInstance
1237 local fontInstance = CreateFont("MDTButtonFont")
1238 fontInstance:CopyFontObject(frame.sidePanelNewButton.frame:GetNormalFontObject())
1239 local fontName,height = fontInstance:GetFont()
1240 fontInstance:SetFont(fontName,10)
1241 frame.sidePanelNewButton.frame:SetNormalFontObject(fontInstance)
1242 frame.sidePanelNewButton.frame:SetHighlightFontObject(fontInstance)
1243 frame.sidePanelNewButton.frame:SetDisabledFontObject(fontInstance)
1244 frame.sidePanelNewButton:SetCallback("OnClick",function(widget,callbackName,value)
1245 MDT:OpenNewPresetDialog()
1246 end)
1247 frame.sidePanelNewButton.frame:SetScript("OnEnter",function()
1248 GameTooltip:SetOwner(frame.sidePanelNewButton.frame, "ANCHOR_BOTTOMLEFT",frame.sidePanelNewButton.frame:GetWidth()*(-0),frame.sidePanelNewButton.frame:GetHeight())
1249 GameTooltip:AddLine(L["Create a new preset"],1,1,1)
1250 GameTooltip:Show()
1251 end)
1252 frame.sidePanelNewButton.frame:SetScript("OnLeave",function()
1253 GameTooltip:Hide()
1254 end)
1255
1256 frame.sidePanelRenameButton = AceGUI:Create("Button")
1257 frame.sidePanelRenameButton:SetWidth(buttonWidth)
1258 frame.sidePanelRenameButton:SetText(L["Rename"])
1259 frame.sidePanelRenameButton.frame:SetNormalFontObject(fontInstance)
1260 frame.sidePanelRenameButton.frame:SetHighlightFontObject(fontInstance)
1261 frame.sidePanelRenameButton.frame:SetDisabledFontObject(fontInstance)
1262 frame.sidePanelRenameButton:SetCallback("OnClick",function(widget,callbackName,value)
1263 MDT:HideAllDialogs()
1264 local currentPresetName = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].text
1265 MDT.main_frame.RenameFrame:Show()
1266 MDT.main_frame.RenameFrame.RenameButton:SetDisabled(true)
1267 MDT.main_frame.RenameFrame.RenameButton.text:SetTextColor(0.5,0.5,0.5)
1268 MDT.main_frame.RenameFrame:ClearAllPoints()
1269 MDT.main_frame.RenameFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50)
1270 MDT.main_frame.RenameFrame.Editbox:SetText(currentPresetName)
1271 MDT.main_frame.RenameFrame.Editbox:HighlightText(0, string.len(currentPresetName))
1272 MDT.main_frame.RenameFrame.Editbox:SetFocus()
1273 end)
1274 frame.sidePanelRenameButton.frame:SetScript("OnEnter",function()
1275 GameTooltip:SetOwner(frame.sidePanelRenameButton.frame, "ANCHOR_BOTTOMLEFT",frame.sidePanelRenameButton.frame:GetWidth()*(-1),frame.sidePanelRenameButton.frame:GetHeight())
1276 GameTooltip:AddLine(L["Rename the preset"],1,1,1)
1277 GameTooltip:Show()
1278 end)
1279 frame.sidePanelRenameButton.frame:SetScript("OnLeave",function()
1280 GameTooltip:Hide()
1281 end)
1282
1283 frame.sidePanelImportButton = AceGUI:Create("Button")
1284 frame.sidePanelImportButton:SetText(L["Import"])
1285 frame.sidePanelImportButton:SetWidth(buttonWidth)
1286 frame.sidePanelImportButton.frame:SetNormalFontObject(fontInstance)
1287 frame.sidePanelImportButton.frame:SetHighlightFontObject(fontInstance)
1288 frame.sidePanelImportButton.frame:SetDisabledFontObject(fontInstance)
1289 frame.sidePanelImportButton:SetCallback("OnClick",function(widget,callbackName,value)
1290 MDT:OpenImportPresetDialog()
1291 end)
1292 frame.sidePanelImportButton.frame:SetScript("OnEnter",function()
1293 GameTooltip:SetOwner(frame.sidePanelImportButton.frame, "ANCHOR_BOTTOMLEFT",frame.sidePanelImportButton.frame:GetWidth()*(-1),frame.sidePanelImportButton.frame:GetHeight())
1294 GameTooltip:AddLine(L["Import a preset from a text string"],1,1,1)
1295 GameTooltip:AddLine(L["You can find MDT exports from other users on the wago.io website"],1,1,1,1)
1296 GameTooltip:Show()
1297 end)
1298 frame.sidePanelImportButton.frame:SetScript("OnLeave",function()
1299 GameTooltip:Hide()
1300 end)
1301
1302 frame.sidePanelExportButton = AceGUI:Create("Button")
1303 frame.sidePanelExportButton:SetText(L["Export"])
1304 frame.sidePanelExportButton:SetWidth(buttonWidth)
1305 frame.sidePanelExportButton.frame:SetNormalFontObject(fontInstance)
1306 frame.sidePanelExportButton.frame:SetHighlightFontObject(fontInstance)
1307 frame.sidePanelExportButton.frame:SetDisabledFontObject(fontInstance)
1308 frame.sidePanelExportButton:SetCallback("OnClick",function(widget,callbackName,value)
1309 if db.colorPaletteInfo.forceColorBlindMode then MDT:ColorAllPulls(_,_,_,true) end
1310 local preset = MDT:GetCurrentPreset()
1311 MDT:SetUniqueID(preset)
1312 preset.mdiEnabled = db.MDI.enabled
1313 preset.difficulty = db.currentDifficulty
1314 local export = MDT:TableToString(preset,true,5)
1315 MDT:HideAllDialogs()
1316 MDT.main_frame.ExportFrame:Show()
1317 MDT.main_frame.ExportFrame:ClearAllPoints()
1318 MDT.main_frame.ExportFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50)
1319 MDT.main_frame.ExportFrameEditbox:SetText(export)
1320 MDT.main_frame.ExportFrameEditbox:HighlightText(0, string.len(export))
1321 MDT.main_frame.ExportFrameEditbox:SetFocus()
1322 MDT.main_frame.ExportFrameEditbox:SetLabel(preset.text.." "..string.len(export))
1323 if db.colorPaletteInfo.forceColorBlindMode then MDT:ColorAllPulls() end
1324 end)
1325 frame.sidePanelExportButton.frame:SetScript("OnEnter",function()
1326 GameTooltip:SetOwner(frame.sidePanelExportButton.frame, "ANCHOR_BOTTOMLEFT",frame.sidePanelExportButton.frame:GetWidth()*(-2),frame.sidePanelExportButton.frame:GetHeight())
1327 GameTooltip:AddLine(L["Export the preset as a text string"],1,1,1)
1328 GameTooltip:AddLine(L["You can share MDT exports on the wago.io website"],1,1,1,1)
1329 GameTooltip:Show()
1330 end)
1331 frame.sidePanelExportButton.frame:SetScript("OnLeave",function()
1332 GameTooltip:Hide()
1333 end)
1334
1335 frame.sidePanelDeleteButton = AceGUI:Create("Button")
1336 frame.sidePanelDeleteButton:SetText(L["Delete"])
1337 frame.sidePanelDeleteButton:SetWidth(buttonWidth)
1338 frame.sidePanelDeleteButton.frame:SetScript("OnEnter",function()
1339 GameTooltip:SetOwner(frame.sidePanelDeleteButton.frame, "ANCHOR_BOTTOMLEFT",frame.sidePanelDeleteButton.frame:GetWidth()*(-2),frame.sidePanelDeleteButton.frame:GetHeight())
1340 GameTooltip:AddLine(L["Delete this preset"],1,1,1)
1341 GameTooltip:AddLine(L["Shift-Click to delete all presets for this dungeon"],1,1,1)
1342 GameTooltip:Show()
1343 end)
1344 frame.sidePanelDeleteButton.frame:SetScript("OnLeave",function()
1345 GameTooltip:Hide()
1346 end)
1347 frame.sidePanelDeleteButton.frame:SetNormalFontObject(fontInstance)
1348 frame.sidePanelDeleteButton.frame:SetHighlightFontObject(fontInstance)
1349 frame.sidePanelDeleteButton.frame:SetDisabledFontObject(fontInstance)
1350 frame.sidePanelDeleteButton:SetCallback("OnClick",function(widget,callbackName,value)
1351 if IsShiftKeyDown() then
1352 --delete all profiles
1353 local numPresets = self:CountPresets()
1354 local prompt = string.format(L["deleteAllWarning"],"\n","\n",numPresets,"\n")
1355 MDT:OpenConfirmationFrame(450,150,L["Delete ALL presets"],L["Delete"],prompt, MDT.DeleteAllPresets)
1356 else
1357 MDT:HideAllDialogs()
1358 frame.DeleteConfirmationFrame:ClearAllPoints()
1359 frame.DeleteConfirmationFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50)
1360 local currentPresetName = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].text
1361 frame.DeleteConfirmationFrame.label:SetText(string.format(L["Delete %s?"],currentPresetName))
1362 frame.DeleteConfirmationFrame:Show()
1363 end
1364 end)
1365
1366 frame.LinkToChatButton = AceGUI:Create("Button")
1367 frame.LinkToChatButton:SetText(L["Share"])
1368 frame.LinkToChatButton:SetWidth(buttonWidth)
1369 frame.LinkToChatButton.frame:SetNormalFontObject(fontInstance)
1370 frame.LinkToChatButton.frame:SetHighlightFontObject(fontInstance)
1371 frame.LinkToChatButton.frame:SetDisabledFontObject(fontInstance)
1372 frame.LinkToChatButton:SetCallback("OnClick",function(widget,callbackName,value)
1373 local distribution = MDT:IsPlayerInGroup()
1374 if not distribution then return end
1375 local callback = function()
1376 frame.LinkToChatButton:SetDisabled(true)
1377 frame.LinkToChatButton.text:SetTextColor(0.5,0.5,0.5)
1378 frame.LiveSessionButton:SetDisabled(true)
1379 frame.LiveSessionButton.text:SetTextColor(0.5,0.5,0.5)
1380 frame.LinkToChatButton:SetText("...")
1381 frame.LiveSessionButton:SetText("...")
1382 MDT:SendToGroup(distribution)
1383 end
1384 local presetSize = self:GetPresetSize(false,5)
1385 if presetSize>25000 then
1386 local prompt = string.format(L["LargePresetWarning"],presetSize,"\n","\n","\n")
1387 MDT:OpenConfirmationFrame(450,150,L["Sharing large preset"],"Share",prompt, callback)
1388 else
1389 callback()
1390 end
1391 end)
1392 frame.LinkToChatButton.frame:SetScript("OnEnter",function()
1393 GameTooltip:SetOwner(frame.sidePanelDeleteButton.frame, "ANCHOR_BOTTOMLEFT",frame.LinkToChatButton.frame:GetWidth()*(-2),-frame.LinkToChatButton.frame:GetHeight())
1394 GameTooltip:AddLine(L["Share the preset with your party members"],1,1,1)
1395 GameTooltip:Show()
1396 end)
1397 frame.LinkToChatButton.frame:SetScript("OnLeave",function()
1398 GameTooltip:Hide()
1399 end)
1400 local inGroup = UnitInRaid("player") or IsInGroup()
1401 MDT.main_frame.LinkToChatButton:SetDisabled(not inGroup)
1402 if inGroup then
1403 MDT.main_frame.LinkToChatButton.text:SetTextColor(1,0.8196,0)
1404 else
1405 MDT.main_frame.LinkToChatButton.text:SetTextColor(0.5,0.5,0.5)
1406 end
1407
1408 frame.ClearPresetButton = AceGUI:Create("Button")
1409 frame.ClearPresetButton:SetText(L["Reset"])
1410 frame.ClearPresetButton:SetWidth(buttonWidth)
1411 frame.ClearPresetButton.frame:SetNormalFontObject(fontInstance)
1412 frame.ClearPresetButton.frame:SetHighlightFontObject(fontInstance)
1413 frame.ClearPresetButton.frame:SetDisabledFontObject(fontInstance)
1414 frame.ClearPresetButton:SetCallback("OnClick",function(widget,callbackName,value)
1415 MDT:OpenClearPresetDialog()
1416 end)
1417 frame.ClearPresetButton.frame:SetScript("OnEnter",function()
1418 GameTooltip:SetOwner(frame.ClearPresetButton.frame, "ANCHOR_BOTTOMLEFT",frame.ClearPresetButton.frame:GetWidth()*(-0),frame.ClearPresetButton.frame:GetHeight())
1419 GameTooltip:AddLine(L["Reset the preset to the default state"],1,1,1)
1420 GameTooltip:AddLine(L["Does not delete your drawings"],1,1,1)
1421 GameTooltip:Show()
1422 end)
1423 frame.ClearPresetButton.frame:SetScript("OnLeave",function()
1424 GameTooltip:Hide()
1425 end)
1426
1427 frame.LiveSessionButton = AceGUI:Create("Button")
1428 frame.LiveSessionButton:SetText(L["Live"])
1429 frame.LiveSessionButton:SetWidth(buttonWidth)
1430 frame.LiveSessionButton.frame:SetNormalFontObject(fontInstance)
1431 frame.LiveSessionButton.frame:SetHighlightFontObject(fontInstance)
1432 frame.LiveSessionButton.frame:SetDisabledFontObject(fontInstance)
1433 local c1,c2,c3 = frame.LiveSessionButton.text:GetTextColor()
1434 frame.LiveSessionButton.normalTextColor = {r = c1,g = c2,b = c3,}
1435 frame.LiveSessionButton:SetCallback("OnClick",function(widget,callbackName,value)
1436 if MDT.liveSessionActive then
1437 MDT:LiveSession_Disable()
1438 else
1439 MDT:LiveSession_Enable()
1440 end
1441 end)
1442 frame.LiveSessionButton.frame:SetScript("OnEnter",function()
1443 GameTooltip:SetOwner(frame.LiveSessionButton.frame, "ANCHOR_BOTTOMLEFT",frame.LiveSessionButton.frame:GetWidth()*(-1),frame.LiveSessionButton.frame:GetHeight())
1444 GameTooltip:AddLine(L["Start or join the current |cFF00FF00Live Session|r"],1,1,1)
1445 GameTooltip:AddLine(L["Clicking this button will attempt to join the ongoing Live Session of your group or create a new one if none is found"],1,1,1,1)
1446 GameTooltip:AddLine(L["The preset will continuously synchronize between all party members participating in the Live Session"],1,1,1,1)
1447 GameTooltip:AddLine(L["Players can join the live session by either clicking this button or the Live Session chat link"],1,1,1,1)
1448 GameTooltip:AddLine(L["To share a different preset while the live session is active simply navigate to the preferred preset and click the new 'Set to Live' Button next to the preset-dropdown"],1,1,1,1)
1449 GameTooltip:AddLine(L["You can always return to the current Live Session preset by clicking the 'Return to Live' button next to the preset-dropdown"],1,1,1,1)
1450 GameTooltip:Show()
1451 end)
1452 frame.LiveSessionButton.frame:SetScript("OnLeave",function()
1453 GameTooltip:Hide()
1454 end)
1455 MDT.main_frame.LiveSessionButton:SetDisabled(not inGroup)
1456 if inGroup then
1457 MDT.main_frame.LiveSessionButton.text:SetTextColor(1,0.8196,0)
1458 else
1459 MDT.main_frame.LiveSessionButton.text:SetTextColor(0.5,0.5,0.5)
1460 end
1461
1462 --MDI
1463 frame.MDIButton = AceGUI:Create("Button")
1464 frame.MDIButton:SetText("MDI")
1465 frame.MDIButton:SetWidth(buttonWidth)
1466 frame.MDIButton.frame:SetNormalFontObject(fontInstance)
1467 frame.MDIButton.frame:SetHighlightFontObject(fontInstance)
1468 frame.MDIButton.frame:SetDisabledFontObject(fontInstance)
1469 frame.MDIButton:SetCallback("OnClick",function(widget,callbackName,value)
1470 MDT:ToggleMDIMode()
1471 end)
1472 frame.MDIButton.frame:SetScript("OnEnter",function()
1473 GameTooltip:SetOwner(frame.MDIButton.frame, "ANCHOR_BOTTOMLEFT",frame.MDIButton.frame:GetWidth()*(-2),frame.MDIButton.frame:GetHeight())
1474 GameTooltip:AddLine(L["Open MDI override options"],1,1,1)
1475 GameTooltip:Show()
1476 end)
1477 frame.MDIButton.frame:SetScript("OnLeave",function()
1478 GameTooltip:Hide()
1479 end)
1480
1481 --AutomaticColorsCheckbox
1482 frame.AutomaticColorsCheckSidePanel = AceGUI:Create("CheckBox")
1483 frame.AutomaticColorsCheckSidePanel:SetLabel(L["Automatically color pulls"])
1484 frame.AutomaticColorsCheckSidePanel:SetValue(db.colorPaletteInfo.autoColoring)
1485 frame.AutomaticColorsCheckSidePanel:SetCallback("OnValueChanged",function(widget,callbackName,value)
1486 db.colorPaletteInfo.autoColoring = value
1487 MDT:SetPresetColorPaletteInfo()
1488 frame.AutomaticColorsCheck:SetValue(db.colorPaletteInfo.autoColoring)
1489 if value == true then
1490 frame.toggleForceColorBlindMode:SetDisabled(false)
1491 MDT:ColorAllPulls()
1492 MDT.main_frame.AutomaticColorsCogwheel:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\helpIconRnbw")
1493 else
1494 frame.toggleForceColorBlindMode:SetDisabled(true)
1495 MDT.main_frame.AutomaticColorsCogwheel:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\helpIconGrey")
1496 end
1497 end)
1498 --AutomaticColorsCogwheel
1499 frame.AutomaticColorsCogwheel = AceGUI:Create("Icon")
1500 local colorCogwheel = frame.AutomaticColorsCogwheel
1501 colorCogwheel:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\helpIconRnbw")
1502 colorCogwheel:SetImageSize(25,25)
1503 colorCogwheel:SetWidth(35)
1504 colorCogwheel:SetCallback("OnEnter",function(...)
1505 GameTooltip:SetOwner(colorCogwheel.frame, "ANCHOR_CURSOR")
1506 GameTooltip:AddLine(L["Click to adjust color settings"],1,1,1)
1507 GameTooltip:Show()
1508 end)
1509 colorCogwheel:SetCallback("OnLeave",function(...)
1510 GameTooltip:Hide()
1511 end)
1512 colorCogwheel:SetCallback("OnClick",function(...)
1513 self:OpenAutomaticColorsDialog()
1514 end)
1515
1516
1517
1518 frame.sidePanel.WidgetGroup:AddChild(frame.sidePanelNewButton)
1519 frame.sidePanel.WidgetGroup:AddChild(frame.sidePanelRenameButton)
1520 frame.sidePanel.WidgetGroup:AddChild(frame.sidePanelDeleteButton)
1521 frame.sidePanel.WidgetGroup:AddChild(frame.ClearPresetButton)
1522 frame.sidePanel.WidgetGroup:AddChild(frame.sidePanelImportButton)
1523 frame.sidePanel.WidgetGroup:AddChild(frame.sidePanelExportButton)
1524 frame.sidePanel.WidgetGroup:AddChild(frame.LinkToChatButton)
1525 frame.sidePanel.WidgetGroup:AddChild(frame.LiveSessionButton)
1526 frame.sidePanel.WidgetGroup:AddChild(frame.MDIButton)
1527 frame.sidePanel.WidgetGroup:AddChild(frame.AutomaticColorsCheckSidePanel)
1528 frame.sidePanel.WidgetGroup:AddChild(frame.AutomaticColorsCogwheel)
1529
1530 --Week Dropdown (Infested / Affixes)
1531 local function makeAffixString(week,affixes,longText)
1532 local ret
1533 local sep = ""
1534 for _,affixID in ipairs(affixes) do
1535 local name, _, filedataid = C_ChallengeMode.GetAffixInfo(affixID)
1536 name = name or "Unknown"
1537 filedataid = filedataid or 134400 --questionmark
1538 if longText then
1539 ret = ret or ""
1540 ret = ret..sep..name
1541 sep = ", "
1542 else
1543 ret = ret or week..(week>9 and ". " or ". ")
1544 if week == MDT:GetCurrentAffixWeek() then
1545 ret = WrapTextInColorCode(ret, "FF00FF00")
1546 end
1547 ret = ret..CreateTextureMarkup(filedataid, 64, 64, 20, 20, 0.1, 0.9, 0.1, 0.9,0,0).." "
1548 end
1549 end
1550 return ret
1551 end
1552 frame.sidePanel.affixDropdown = AceGUI:Create("Dropdown")
1553 local affixDropdown = frame.sidePanel.affixDropdown
1554 affixDropdown.text:SetJustifyH("LEFT")
1555 affixDropdown:SetLabel(L["Affixes"])
1556
1557 function affixDropdown:UpdateAffixList()
1558 local affixWeekMarkups = {}
1559 for week,affixes in ipairs(affixWeeks) do
1560 tinsert(affixWeekMarkups,makeAffixString(week,affixes))
1561 end
1562 local order = {1,2,3,4,5,6,7,8,9,10,11,12}
1563 affixDropdown:SetList(affixWeekMarkups,order)
1564 --mouseover list items
1565 for itemIdx,item in ipairs(affixDropdown.pullout.items) do
1566 item:SetOnEnter(function()
1567 GameTooltip:SetOwner(item.frame, "ANCHOR_LEFT",-11,-25)
1568 local v = affixWeeks[itemIdx]
1569 GameTooltip:SetText(makeAffixString(itemIdx,v,true),1,1,1,1)
1570 GameTooltip:Show()
1571 end)
1572 item:SetOnLeave(function()
1573 GameTooltip:Hide()
1574 end)
1575 end
1576 end
1577 function affixDropdown:SetAffixWeek(key,ignoreReloadPullButtons,ignoreUpdateProgressBar)
1578 affixDropdown:SetValue(key)
1579 if not MDT:GetCurrentAffixWeek() then
1580 frame.sidePanel.affixWeekWarning.image:Hide()
1581 frame.sidePanel.affixWeekWarning:SetDisabled(true)
1582 elseif MDT:GetCurrentAffixWeek() == key then
1583 frame.sidePanel.affixWeekWarning.image:Hide()
1584 frame.sidePanel.affixWeekWarning:SetDisabled(true)
1585 else
1586 frame.sidePanel.affixWeekWarning.image:Show()
1587 frame.sidePanel.affixWeekWarning:SetDisabled(false)
1588 end
1589 MDT:GetCurrentPreset().week = key
1590 local teeming = MDT:IsPresetTeeming(MDT:GetCurrentPreset())
1591 MDT:GetCurrentPreset().value.teeming = teeming
1592
1593 if MDT.EnemyInfoFrame and MDT.EnemyInfoFrame.frame:IsShown() then MDT:UpdateEnemyInfoData() end
1594 MDT:UpdateMap(nil,ignoreReloadPullButtons,ignoreUpdateProgressBar)
1595 end
1596 affixDropdown:SetCallback("OnValueChanged",function(widget,callbackName,key)
1597 affixDropdown:SetAffixWeek(key)
1598 if MDT.liveSessionActive and MDT:GetCurrentPreset().uid == MDT.livePresetUID then
1599 MDT:LiveSession_SendAffixWeek(key)
1600 end
1601 end)
1602 affixDropdown:SetCallback("OnEnter",function(...)
1603 local selectedWeek = affixDropdown:GetValue()
1604 if not selectedWeek then return end
1605 GameTooltip:SetOwner(affixDropdown.frame, "ANCHOR_LEFT",-6,-41)
1606 local v = affixWeeks[selectedWeek]
1607 GameTooltip:SetText(makeAffixString(selectedWeek,v,true),1,1,1,1)
1608 GameTooltip:Show()
1609 end)
1610 affixDropdown:SetCallback("OnLeave",function(...)
1611 GameTooltip:Hide()
1612 end)
1613
1614 frame.sidePanel.WidgetGroup:AddChild(affixDropdown)
1615
1616 --affix not current week warning
1617 frame.sidePanel.affixWeekWarning = AceGUI:Create("Icon")
1618 local affixWeekWarning = frame.sidePanel.affixWeekWarning
1619 affixWeekWarning:SetImage("Interface\\DialogFrame\\UI-Dialog-Icon-AlertNew")
1620 affixWeekWarning:SetImageSize(25,25)
1621 affixWeekWarning:SetWidth(35)
1622 affixWeekWarning:SetCallback("OnEnter",function(...)
1623 GameTooltip:SetOwner(affixDropdown.frame, "ANCHOR_CURSOR")
1624 GameTooltip:AddLine(L["The selected affixes are not the ones of the current week"],1,1,1)
1625 GameTooltip:AddLine(L["Click to switch to current week"],1,1,1)
1626 GameTooltip:Show()
1627 end)
1628 affixWeekWarning:SetCallback("OnLeave",function(...)
1629 GameTooltip:Hide()
1630 end)
1631 affixWeekWarning:SetCallback("OnClick",function(...)
1632 if not MDT:GetCurrentAffixWeek() then return end
1633 affixDropdown:SetAffixWeek(MDT:GetCurrentAffixWeek())
1634 if MDT.liveSessionActive and MDT:GetCurrentPreset().uid == MDT.livePresetUID then
1635 MDT:LiveSession_SendAffixWeek(MDT:GetCurrentAffixWeek())
1636 end
1637 end)
1638 affixWeekWarning.image:Hide()
1639 affixWeekWarning:SetDisabled(true)
1640 frame.sidePanel.WidgetGroup:AddChild(affixWeekWarning)
1641
1642 --difficulty slider
1643 frame.sidePanel.DifficultySlider = AceGUI:Create("Slider")
1644 frame.sidePanel.DifficultySlider:SetSliderValues(1,35,1)
1645 frame.sidePanel.DifficultySlider:SetLabel(L["Dungeon Level"])
1646 frame.sidePanel.DifficultySlider.label:SetJustifyH("LEFT")
1647 frame.sidePanel.DifficultySlider.label:SetFontObject("GameFontNormalSmall")
1648 frame.sidePanel.DifficultySlider:SetWidth(200)
1649 frame.sidePanel.DifficultySlider:SetValue(db.currentDifficulty)
1650 local timer
1651 frame.sidePanel.DifficultySlider:SetCallback("OnValueChanged",function(widget,callbackName,value)
1652 local difficulty = tonumber(value)
1653 if (difficulty>=10 and db.currentDifficulty<10) or (difficulty<10 and db.currentDifficulty>=10) then
1654 db.currentDifficulty = difficulty or db.currentDifficulty
1655 MDT:DungeonEnemies_UpdateSeasonalAffix()
1656 frame.sidePanel.difficultyWarning:Toggle(difficulty)
1657 MDT:POI_UpdateAll()
1658 MDT:KillAllAnimatedLines()
1659 MDT:DrawAllAnimatedLines()
1660 else
1661 db.currentDifficulty = difficulty or db.currentDifficulty
1662 end
1663 MDT:GetCurrentPreset().difficulty = db.currentDifficulty
1664 MDT:UpdateProgressbar()
1665 if MDT.EnemyInfoFrame and MDT.EnemyInfoFrame.frame:IsShown() then MDT:UpdateEnemyInfoData() end
1666 if timer then timer:Cancel() end
1667 timer = C_Timer.NewTimer(2, function()
1668 MDT:ReloadPullButtons()
1669 if MDT.liveSessionActive then
1670 local livePreset = MDT:GetCurrentLivePreset()
1671 local shouldUpdate = livePreset == MDT:GetCurrentPreset()
1672 if shouldUpdate then MDT:LiveSession_SendDifficulty() end
1673 end
1674 end)
1675 end)
1676 frame.sidePanel.DifficultySlider:SetCallback("OnMouseUp",function()
1677 if timer then timer:Cancel() end
1678 MDT:ReloadPullButtons()
1679 if MDT.liveSessionActive then
1680 local livePreset = MDT:GetCurrentLivePreset()
1681 local shouldUpdate = livePreset == MDT:GetCurrentPreset()
1682 if shouldUpdate then MDT:LiveSession_SendDifficulty() end
1683 end
1684 end)
1685 frame.sidePanel.DifficultySlider:SetCallback("OnEnter",function()
1686 GameTooltip:SetOwner(frame.sidePanel.DifficultySlider.frame, "ANCHOR_BOTTOMLEFT",0,40)
1687 GameTooltip:AddLine(L["Select the dungeon level"],1,1,1)
1688 GameTooltip:AddLine(L["The selected level will affect displayed npc health"],1,1,1)
1689 GameTooltip:AddLine(L["Levels below 10 will hide enemies related to seasonal affixes"],1,1,1)
1690 GameTooltip:Show()
1691 end)
1692 frame.sidePanel.DifficultySlider:SetCallback("OnLeave",function()
1693 GameTooltip:Hide()
1694 end)
1695 frame.sidePanel.WidgetGroup:AddChild(frame.sidePanel.DifficultySlider)
1696
1697 --dungeon level below 10 warning
1698 frame.sidePanel.difficultyWarning = AceGUI:Create("Icon")
1699 local difficultyWarning = frame.sidePanel.difficultyWarning
1700 difficultyWarning:SetImage("Interface\\DialogFrame\\UI-Dialog-Icon-AlertNew")
1701 difficultyWarning:SetImageSize(25,25)
1702 difficultyWarning:SetWidth(35)
1703 difficultyWarning:SetCallback("OnEnter",function(...)
1704 GameTooltip:SetOwner(frame.sidePanel.DifficultySlider.frame, "ANCHOR_CURSOR")
1705 GameTooltip:AddLine(L["The selected dungeon level is below 10"],1,1,1)
1706 GameTooltip:AddLine(L["Enemies related to seasonal affixes are currently hidden"],1,1,1)
1707 GameTooltip:AddLine(L["Click to set dungeon level to 10"],1,1,1)
1708 GameTooltip:Show()
1709 end)
1710 difficultyWarning:SetCallback("OnLeave",function(...)
1711 GameTooltip:Hide()
1712 end)
1713 difficultyWarning:SetCallback("OnClick",function(...)
1714 frame.sidePanel.DifficultySlider:SetValue(10)
1715 db.currentDifficulty = 10
1716 MDT:GetCurrentPreset().difficulty = db.currentDifficulty
1717 MDT:DungeonEnemies_UpdateSeasonalAffix()
1718 MDT:POI_UpdateAll()
1719 MDT:UpdateProgressbar()
1720 MDT:ReloadPullButtons()
1721 difficultyWarning:Toggle(db.currentDifficulty)
1722 if MDT.liveSessionActive then
1723 local livePreset = MDT:GetCurrentLivePreset()
1724 local shouldUpdate = livePreset == MDT:GetCurrentPreset()
1725 if shouldUpdate then MDT:LiveSession_SendDifficulty() end
1726 end
1727 MDT:KillAllAnimatedLines()
1728 MDT:DrawAllAnimatedLines()
1729 end)
1730 function difficultyWarning:Toggle(difficulty)
1731 if difficulty<10 then
1732 self.image:Show()
1733 self:SetDisabled(false)
1734 else
1735 self.image:Hide()
1736 self:SetDisabled(true)
1737 end
1738 end
1739 difficultyWarning:Toggle(db.currentDifficulty)
1740 frame.sidePanel.WidgetGroup:AddChild(difficultyWarning)
1741
1742 frame.sidePanel.middleLine = AceGUI:Create("Heading")
1743 frame.sidePanel.middleLine:SetWidth(240)
1744 frame.sidePanel.WidgetGroup:AddChild(frame.sidePanel.middleLine)
1745 frame.sidePanel.WidgetGroup.frame:SetFrameLevel(3)
1746
1747 --progress bar
1748 frame.sidePanel.ProgressBar = CreateFrame("Frame", nil, frame.sidePanel, "ScenarioTrackerProgressBarTemplate")
1749 frame.sidePanel.ProgressBar:Show()
1750 frame.sidePanel.ProgressBar:ClearAllPoints()
1751 frame.sidePanel.ProgressBar:SetPoint("TOP",frame.sidePanel.WidgetGroup.frame,"BOTTOM",-10,5)
1752 MDT:SkinProgressBar(frame.sidePanel.ProgressBar)
1753end
1754
1755---ToggleMDIMode
1756---Enables display to override beguiling+freehold week
1757function MDT:ToggleMDIMode()
1758 db.MDI.enabled = not db.MDI.enabled
1759 self:DisplayMDISelector()
1760 if self.liveSessionActive then self:LiveSession_SendMDI("toggle",db.MDI.enabled and "1" or "0") end
1761end
1762
1763function MDT:DisplayMDISelector()
1764 local show = db.MDI.enabled
1765 db = MDT:GetDB()
1766 if not MDT.MDISelector then
1767 MDT.MDISelector = AceGUI:Create("SimpleGroup")
1768 MDT.MDISelector.frame:SetFrameStrata("HIGH")
1769 MDT.MDISelector.frame:SetFrameLevel(50)
1770 if not MDT.MDISelector.frame.SetBackdrop then
1771 Mixin(MDT.MDISelector.frame, BackdropTemplateMixin)
1772 end
1773 MDT.MDISelector.frame:SetBackdropColor(unpack(MDT.BackdropColor))
1774 --fix show hide
1775 local frame = MDT.main_frame
1776 local originalShow,originalHide = frame.Show,frame.Hide
1777 local widget = MDT.MDISelector.frame
1778 function frame:Hide(...)
1779 widget:Hide()
1780 return originalHide(self, ...)
1781 end
1782 function frame:Show(...)
1783 if db.MDI.enabled then widget:Show() end
1784 return originalShow(self, ...)
1785 end
1786
1787 MDT.MDISelector:SetLayout("Flow")
1788 MDT.MDISelector.frame.bg = MDT.MDISelector.frame:CreateTexture(nil, "BACKGROUND")
1789 MDT.MDISelector.frame.bg:SetAllPoints(MDT.MDISelector.frame)
1790 MDT.MDISelector.frame.bg:SetColorTexture(unpack(MDT.BackdropColor))
1791 MDT.MDISelector:SetWidth(145)
1792 MDT.MDISelector:SetHeight(90)
1793 MDT.MDISelector.frame:ClearAllPoints()
1794 MDT.MDISelector.frame:SetPoint("BOTTOMRIGHT", MDT.main_frame,"BOTTOMRIGHT",0,0)
1795
1796 local label = AceGUI:Create("Label")
1797 label:SetText(L["MDI Mode"])
1798 MDT.MDISelector:AddChild(label)
1799
1800 --beguiling
1801 MDT.MDISelector.BeguilingDropDown = AceGUI:Create("Dropdown")
1802 MDT.MDISelector.BeguilingDropDown:SetLabel(L["Seasonal Affix:"])
1803 local beguilingList = {[1]=L["Beguiling 1 Void"],[2]=L["Beguiling 2 Tides"],[3]=L["Beguiling 3 Ench."],[13]=L["Reaping"],[14]=L["Awakened A"],[15]=L["Awakened B"]}
1804 MDT.MDISelector.BeguilingDropDown:SetList(beguilingList)
1805 MDT.MDISelector.BeguilingDropDown:SetCallback("OnValueChanged",function(widget, callbackName, key)
1806 local preset = self:GetCurrentPreset()
1807 preset.mdi.beguiling = key
1808 db.currentSeason = self:GetEffectivePresetSeason(preset)
1809 self:UpdateMap()
1810 if self.liveSessionActive and preset.uid == self.livePresetUID then
1811 self:LiveSession_SendMDI("beguiling",key)
1812 end
1813 end)
1814 MDT.MDISelector:AddChild(MDT.MDISelector.BeguilingDropDown)
1815
1816 --freehold
1817 MDT.MDISelector.FreeholdDropDown = AceGUI:Create("Dropdown")
1818 MDT.MDISelector.FreeholdDropDown:SetLabel(L["Freehold:"])
1819 local freeholdList = {string.format("1. %s",L["Cutwater"]),string.format("2. %s",L["Blacktooth"]),string.format("3. %s",L["Bilge Rats"])}
1820 MDT.MDISelector.FreeholdDropDown:SetList(freeholdList)
1821 MDT.MDISelector.FreeholdDropDown:SetCallback("OnValueChanged",function(widget, callbackName, key)
1822 local preset = MDT:GetCurrentPreset()
1823 preset.mdi.freehold = key
1824 if preset.mdi.freeholdJoined then
1825 MDT:DungeonEnemies_UpdateFreeholdCrew(preset.mdi.freehold)
1826 end
1827 MDT:DungeonEnemies_UpdateBlacktoothEvent()
1828 MDT:UpdateProgressbar()
1829 MDT:ReloadPullButtons()
1830 if self.liveSessionActive and self:GetCurrentPreset().uid == self.livePresetUID then
1831 self:LiveSession_SendMDI("freehold",key)
1832 end
1833 end)
1834 MDT.MDISelector:AddChild(MDT.MDISelector.FreeholdDropDown)
1835
1836 MDT.MDISelector.FreeholdCheck = AceGUI:Create("CheckBox")
1837 MDT.MDISelector.FreeholdCheck:SetLabel(L["Join Crew"])
1838 MDT.MDISelector.FreeholdCheck:SetCallback("OnValueChanged",function(widget, callbackName, value)
1839 local preset = MDT:GetCurrentPreset()
1840 preset.mdi.freeholdJoined = value
1841 MDT:DungeonEnemies_UpdateFreeholdCrew()
1842 MDT:ReloadPullButtons()
1843 MDT:UpdateProgressbar()
1844 if self.liveSessionActive and self:GetCurrentPreset().uid == self.livePresetUID then
1845 self:LiveSession_SendMDI("join",value and "1" or "0")
1846 end
1847 end)
1848 MDT.MDISelector:AddChild(MDT.MDISelector.FreeholdCheck)
1849
1850 end
1851 if show then
1852 local preset = MDT:GetCurrentPreset()
1853 preset.mdi = preset.mdi or {}
1854 --beguiling
1855 preset.mdi.beguiling = preset.mdi.beguiling or 1
1856 MDT.MDISelector.BeguilingDropDown:SetValue(preset.mdi.beguiling)
1857 db.currentSeason = MDT:GetEffectivePresetSeason(preset)
1858 MDT:DungeonEnemies_UpdateSeasonalAffix()
1859 MDT:DungeonEnemies_UpdateBoralusFaction(MDT:GetCurrentPreset().faction)
1860 --freehold
1861 preset.mdi.freehold = preset.mdi.freehold or 1
1862 MDT.MDISelector.FreeholdDropDown:SetValue(preset.mdi.freehold)
1863 preset.mdi.freeholdJoined = preset.mdi.freeholdJoined or false
1864 MDT.MDISelector.FreeholdCheck:SetValue(preset.mdi.freeholdJoined)
1865 MDT:DungeonEnemies_UpdateFreeholdCrew()
1866 MDT:DungeonEnemies_UpdateBlacktoothEvent()
1867 MDT:UpdateProgressbar()
1868 MDT:ReloadPullButtons()
1869 MDT.MDISelector.frame:Show()
1870 MDT:ToggleFreeholdSelector(false)
1871 else
1872 db.currentSeason = defaultSavedVars.global.currentSeason
1873 MDT:DungeonEnemies_UpdateSeasonalAffix()
1874 MDT:DungeonEnemies_UpdateBoralusFaction(MDT:GetCurrentPreset().faction)
1875 MDT:UpdateFreeholdSelector(MDT:GetCurrentPreset().week)
1876 MDT:DungeonEnemies_UpdateBlacktoothEvent()
1877 MDT:UpdateProgressbar()
1878 MDT:ReloadPullButtons()
1879 MDT.MDISelector.frame:Hide()
1880 MDT:ToggleFreeholdSelector(db.currentDungeonIdx == 16)
1881 end
1882 MDT:POI_UpdateAll()
1883 MDT:KillAllAnimatedLines()
1884 MDT:DrawAllAnimatedLines()
1885end
1886
1887
1888function MDT:UpdatePresetDropDown()
1889 local dropdown = MDT.main_frame.sidePanel.WidgetGroup.PresetDropDown
1890 local presetList = {}
1891 for k,v in pairs(db.presets[db.currentDungeonIdx]) do
1892 table.insert(presetList,k,v.text)
1893 end
1894 dropdown:SetList(presetList)
1895 dropdown:SetValue(db.currentPreset[db.currentDungeonIdx])
1896 dropdown:ClearFocus()
1897end
1898
1899function MDT:UpdatePresetDropdownTextColor(forceReset)
1900 local preset = self:GetCurrentPreset()
1901 local livePreset = self:GetCurrentLivePreset()
1902 if self.liveSessionActive and preset == livePreset and (not forceReset) then
1903 local dropdown = MDT.main_frame.sidePanel.WidgetGroup.PresetDropDown
1904 dropdown.text:SetTextColor(0,1,0,1)
1905 else
1906 local dropdown = MDT.main_frame.sidePanel.WidgetGroup.PresetDropDown
1907 dropdown.text:SetTextColor(1,1,1,1)
1908 end
1909end
1910
1911---FormatEnemyForces
1912function MDT:FormatEnemyForces(forces, forcesmax, progressbar)
1913 if not forcesmax then forcesmax = MDT:IsCurrentPresetTeeming() and MDT.dungeonTotalCount[db.currentDungeonIdx].teeming or MDT.dungeonTotalCount[db.currentDungeonIdx].normal end
1914 if db.enemyForcesFormat == 1 then
1915 if progressbar then return forces.."/"..forcesmax end
1916 return forces
1917 elseif db.enemyForcesFormat == 2 then
1918 if progressbar then return string.format((forces.."/"..forcesmax.." (%.2f%%)"),(forces/forcesmax)*100) end
1919 return string.format(forces.." (%.2f%%)",(forces/forcesmax)*100)
1920 end
1921end
1922
1923---Progressbar_SetValue
1924---Sets the value/progress/color of the count progressbar to the apropriate data
1925function MDT:Progressbar_SetValue(self, totalCurrent, totalMax)
1926 local percent = (totalCurrent/totalMax)*100
1927 if percent >= 102 then
1928 if totalCurrent-totalMax > 8 then
1929 self.Bar:SetStatusBarColor(1,0,0,1)
1930 else
1931 self.Bar:SetStatusBarColor(0,1,0,1)
1932 end
1933 elseif percent >= 100 then
1934 self.Bar:SetStatusBarColor(0,1,0,1)
1935 else
1936 self.Bar:SetStatusBarColor(0.26,0.42,1)
1937 end
1938 self.Bar:SetValue(percent)
1939 self.Bar.Label:SetText(MDT:FormatEnemyForces(totalCurrent,totalMax,true))
1940 self.AnimValue = percent
1941end
1942
1943---UpdateProgressbar
1944---Update the progressbar on the sidepanel with the correct values
1945function MDT:UpdateProgressbar()
1946 local teeming = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.teeming
1947 MDT:EnsureDBTables()
1948 local grandTotal = MDT:CountForces()
1949 MDT:Progressbar_SetValue(MDT.main_frame.sidePanel.ProgressBar,grandTotal,teeming==true and MDT.dungeonTotalCount[db.currentDungeonIdx].teeming or MDT.dungeonTotalCount[db.currentDungeonIdx].normal)
1950end
1951
1952function MDT:OnPan(cursorX, cursorY)
1953 local scrollFrame = MDTScrollFrame
1954 local scale = MDTMapPanelFrame:GetScale()/1.5
1955 local deltaX = (scrollFrame.cursorX - cursorX)/scale
1956 local deltaY = (cursorY - scrollFrame.cursorY)/scale
1957
1958 if(scrollFrame.panning)then
1959 local newHorizontalPosition = max(0, deltaX + scrollFrame:GetHorizontalScroll())
1960 newHorizontalPosition = min(newHorizontalPosition, scrollFrame.maxX)
1961 local newVerticalPosition = max(0, deltaY + scrollFrame:GetVerticalScroll())
1962 newVerticalPosition = min(newVerticalPosition, scrollFrame.maxY)
1963 scrollFrame:SetHorizontalScroll(newHorizontalPosition)
1964 scrollFrame:SetVerticalScroll(newVerticalPosition)
1965 scrollFrame.cursorX = cursorX
1966 scrollFrame.cursorY = cursorY
1967
1968 scrollFrame.wasPanningLastFrame = true;
1969 scrollFrame.lastDeltaX = deltaX;
1970 scrollFrame.lastDeltaY = deltaY;
1971
1972 else
1973 if(scrollFrame.wasPanningLastFrame)then
1974
1975 scrollFrame.isFadeOutPanning = true
1976 scrollFrame.fadeOutXStart = scrollFrame.lastDeltaX
1977 scrollFrame.fadeOutYStart = scrollFrame.lastDeltaY
1978 scrollFrame.panDuration = 0
1979
1980 scrollFrame.wasPanningLastFrame = false;
1981 end
1982 end
1983end
1984
1985function MDT:OnPanFadeOut(deltaTime)
1986 local scrollFrame = MDTScrollFrame
1987 local panDuration = 0.5
1988 local panAtenuation = 7
1989 if(scrollFrame.isFadeOutPanning)then
1990 scrollFrame.panDuration = scrollFrame.panDuration + deltaTime
1991
1992 local phase = scrollFrame.panDuration / panDuration
1993 local phaseLog = -math.log(phase)
1994 local stepX = (scrollFrame.fadeOutXStart * phaseLog) / panAtenuation
1995 local stepY = (scrollFrame.fadeOutYStart * phaseLog) / panAtenuation
1996
1997 local newHorizontalPosition = max(0, stepX + scrollFrame:GetHorizontalScroll())
1998 newHorizontalPosition = min(newHorizontalPosition, scrollFrame.maxX)
1999 local newVerticalPosition = max(0, stepY + scrollFrame:GetVerticalScroll())
2000 newVerticalPosition = min(newVerticalPosition, scrollFrame.maxY)
2001 scrollFrame:SetHorizontalScroll(newHorizontalPosition)
2002 scrollFrame:SetVerticalScroll(newVerticalPosition)
2003
2004 if(scrollFrame.panDuration > panDuration)then
2005 scrollFrame.isFadeOutPanning = false
2006 end
2007 end
2008end
2009
2010function MDT:ExportCurrentZoomPanSettings()
2011 local mainFrame = MDTMapPanelFrame
2012 local scrollFrame = MDTScrollFrame
2013
2014 local zoom = MDTMapPanelFrame:GetScale()
2015 local panH = MDTScrollFrame:GetHorizontalScroll() / MDT:GetScale()
2016 local panV = MDTScrollFrame:GetVerticalScroll() / MDT:GetScale()
2017
2018 local output = " ["..db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel.."] = {\n"
2019 output = output.." zoomScale = "..zoom..";\n"
2020 output = output.." horizontalPan = "..panH..";\n"
2021 output = output.." verticalPan = "..panV..";\n"
2022 output = output.." };\n"
2023
2024 MDT:HideAllDialogs()
2025 MDT.main_frame.ExportFrame:Show()
2026 MDT.main_frame.ExportFrame:ClearAllPoints()
2027 MDT.main_frame.ExportFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50)
2028 MDT.main_frame.ExportFrameEditbox:SetText(output)
2029 MDT.main_frame.ExportFrameEditbox:HighlightText(0, string.len(output))
2030 MDT.main_frame.ExportFrameEditbox:SetFocus()
2031 MDT.main_frame.ExportFrameEditbox:SetLabel("Current pan/zoom settings");
2032end
2033
2034
2035function MDT:ZoomMapToDefault()
2036 local currentMap = db.presets[db.currentDungeonIdx]
2037 local currentSublevel = currentMap[db.currentPreset[db.currentDungeonIdx]].value.currentSublevel
2038 local mainFrame = MDTMapPanelFrame
2039 local scrollFrame = MDTScrollFrame
2040
2041 local currentMapInfo = MDT.mapInfo[db.currentDungeonIdx]
2042 if(currentMapInfo and currentMapInfo.viewportPositionOverrides and currentMapInfo.viewportPositionOverrides[currentSublevel])then
2043 local data = currentMapInfo.viewportPositionOverrides[currentSublevel];
2044
2045 local scaledSizeX = mainFrame:GetWidth() * data.zoomScale
2046 local scaledSizeY = mainFrame:GetHeight() * data.zoomScale
2047
2048 scrollFrame.maxX = (scaledSizeX - mainFrame:GetWidth()) / data.zoomScale
2049 scrollFrame.maxY = (scaledSizeY - mainFrame:GetHeight()) / data.zoomScale
2050 scrollFrame.zoomedIn = abs(data.zoomScale - 1) > 0.02
2051
2052 mainFrame:SetScale(data.zoomScale)
2053
2054 scrollFrame:SetHorizontalScroll(data.horizontalPan * MDT:GetScale())
2055 scrollFrame:SetVerticalScroll(data.verticalPan * MDT:GetScale())
2056
2057 else
2058 scrollFrame.maxX = 1
2059 scrollFrame.maxY = 1
2060 scrollFrame.zoomedIn = false
2061
2062 mainFrame:SetScale(1);
2063
2064 scrollFrame:SetHorizontalScroll(0)
2065 scrollFrame:SetVerticalScroll(0)
2066 end
2067
2068end
2069
2070function MDT:ZoomMap(delta)
2071 local scrollFrame = MDTScrollFrame
2072 if not scrollFrame:GetLeft() then return end
2073 local oldScrollH = scrollFrame:GetHorizontalScroll()
2074 local oldScrollV = scrollFrame:GetVerticalScroll()
2075
2076 local mainFrame = MDTMapPanelFrame
2077
2078 local oldScale = mainFrame:GetScale()
2079 local newScale = oldScale + delta * 0.3
2080
2081 newScale = max(1, newScale)
2082 newScale = min(15, newScale)
2083
2084 mainFrame:SetScale(newScale)
2085
2086 local scaledSizeX = mainFrame:GetWidth() * newScale
2087 local scaledSizeY = mainFrame:GetHeight() * newScale
2088
2089 scrollFrame.maxX = (scaledSizeX - mainFrame:GetWidth()) / newScale
2090 scrollFrame.maxY = (scaledSizeY - mainFrame:GetHeight()) / newScale
2091 scrollFrame.zoomedIn = abs(newScale - 1) > 0.02
2092
2093 local cursorX,cursorY = GetCursorPosition()
2094 local frameX = (cursorX / UIParent:GetScale()) - scrollFrame:GetLeft()
2095 local frameY = scrollFrame:GetTop() - (cursorY / UIParent:GetScale())
2096 local scaleChange = newScale / oldScale
2097 local newScrollH = (scaleChange * frameX - frameX) / newScale + oldScrollH
2098 local newScrollV = (scaleChange * frameY - frameY) / newScale + oldScrollV
2099
2100 newScrollH = min(newScrollH, scrollFrame.maxX)
2101 newScrollH = max(0, newScrollH)
2102 newScrollV = min(newScrollV, scrollFrame.maxY)
2103 newScrollV = max(0, newScrollV)
2104
2105 scrollFrame:SetHorizontalScroll(newScrollH)
2106 scrollFrame:SetVerticalScroll(newScrollV)
2107
2108 MDT:SetPingOffsets(newScale)
2109end
2110
2111---ActivatePullTooltip
2112---
2113function MDT:ActivatePullTooltip(pull)
2114 local pullTooltip = MDT.pullTooltip
2115 --[[
2116 if not pullTooltip.ranOnce then
2117 --fix elvui skinning
2118 pullTooltip:SetPoint("TOPRIGHT",UIParent,"BOTTOMRIGHT")
2119 pullTooltip:SetPoint("BOTTOMRIGHT",UIParent,"BOTTOMRIGHT")
2120 pullTooltip:Show()
2121 pullTooltip.ranOnce = true
2122 end
2123 ]]
2124 pullTooltip.currentPull = pull
2125 pullTooltip:Show()
2126end
2127
2128---UpdatePullTooltip
2129---Updates the tooltip which is being displayed when a pull is mouseovered
2130function MDT:UpdatePullTooltip(tooltip)
2131 local frame = MDT.main_frame
2132 if not MouseIsOver(frame.sidePanel.pullButtonsScrollFrame.frame) then
2133 tooltip:Hide()
2134 elseif MouseIsOver(frame.sidePanel.newPullButton.frame) then
2135 tooltip:Hide()
2136 else
2137 if frame.sidePanel.newPullButtons and tooltip.currentPull and frame.sidePanel.newPullButtons[tooltip.currentPull] then
2138 --enemy portraits
2139 local showData
2140 for k,v in pairs(frame.sidePanel.newPullButtons[tooltip.currentPull].enemyPortraits) do
2141 if MouseIsOver(v) then
2142 if v:IsShown() then
2143 --model
2144 if v.enemyData.displayId and (not tooltip.modelNpcId or (tooltip.modelNpcId ~= v.enemyData.displayId)) then
2145 tooltip.Model:SetDisplayInfo(v.enemyData.displayId)
2146 tooltip.modelNpcId = v.enemyData.displayId
2147 end
2148 --topString
2149 local newLine = "\n"
2150 local text = newLine..newLine..newLine..v.enemyData.name.." x"..v.enemyData.quantity..newLine
2151 text = text..string.format(L["Level %d %s"],v.enemyData.level,v.enemyData.creatureType)..newLine
2152 local boss = v.enemyData.isBoss or false
2153 local health = MDT:CalculateEnemyHealth(boss,v.enemyData.baseHealth,db.currentDifficulty,v.enemyData.ignoreFortified)
2154 text = text.. string.format(L["%s HP"],MDT:FormatEnemyHealth(health))..newLine
2155
2156 local totalForcesMax = MDT:IsCurrentPresetTeeming() and MDT.dungeonTotalCount[db.currentDungeonIdx].teeming or MDT.dungeonTotalCount[db.currentDungeonIdx].normal
2157 local count = MDT:IsCurrentPresetTeeming() and v.enemyData.teemingCount or v.enemyData.count
2158 text = text..L["Forces"]..": ".. MDT:FormatEnemyForces(count,totalForcesMax,false)
2159
2160 tooltip.topString:SetText(text)
2161 showData = true
2162 end
2163 break
2164 end
2165 end
2166 if showData then
2167 tooltip.topString:Show()
2168 tooltip.Model:Show()
2169 else
2170 tooltip.topString:Hide()
2171 tooltip.Model:Hide()
2172 end
2173
2174 local countEnemies = 0
2175 for k,v in pairs(frame.sidePanel.newPullButtons[tooltip.currentPull].enemyPortraits) do
2176 if v:IsShown() then countEnemies = countEnemies + 1 end
2177 end
2178 if countEnemies == 0 then
2179 tooltip:Hide()
2180 return
2181 end
2182 local pullForces = MDT:CountForces(tooltip.currentPull,true)
2183 local totalForces = MDT:CountForces(tooltip.currentPull,false)
2184 local totalForcesMax = MDT:IsCurrentPresetTeeming() and MDT.dungeonTotalCount[db.currentDungeonIdx].teeming or MDT.dungeonTotalCount[db.currentDungeonIdx].normal
2185
2186 local text = L["Forces"]..": ".. MDT:FormatEnemyForces(pullForces,totalForcesMax,false)
2187 text = text.. "\n"..L["Total"]..": ".. MDT:FormatEnemyForces(totalForces,totalForcesMax,true)
2188
2189 tooltip.botString:SetText(text)
2190 tooltip.botString:Show()
2191 end
2192 end
2193end
2194
2195---CountForces
2196---Counts total selected enemy forces in the current preset up to pull
2197function MDT:CountForces(currentPull, currentOnly)
2198 --count up to and including the currently selected pull
2199 currentPull = currentPull or 1000
2200 local preset = self:GetCurrentPreset()
2201 local teeming = self:IsCurrentPresetTeeming()
2202 local pullCurrent = 0
2203 for pullIdx,pull in pairs(preset.value.pulls) do
2204 if not currentOnly or (currentOnly and pullIdx == currentPull) then
2205 if pullIdx <= currentPull then
2206 for enemyIdx,clones in pairs(pull) do
2207 if tonumber(enemyIdx) then
2208 for k,v in pairs(clones) do
2209 if MDT:IsCloneIncluded(enemyIdx,v) then
2210 local count = teeming
2211 and self.dungeonEnemies[db.currentDungeonIdx][enemyIdx].teemingCount
2212 or self.dungeonEnemies[db.currentDungeonIdx][enemyIdx].count
2213 pullCurrent = pullCurrent + count
2214 end
2215 end
2216 end
2217 end
2218 else
2219 break
2220 end
2221 end
2222 end
2223 return pullCurrent
2224end
2225
2226local emissaryIds = {[155432]=true,[155433]=true,[155434]=true}
2227
2228---Checks if the specified clone is part of the current map configuration
2229function MDT:IsCloneIncluded(enemyIdx, cloneIdx)
2230 local preset = MDT:GetCurrentPreset()
2231 local isCloneBlacktoothEvent = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][cloneIdx].blacktoothEvent
2232 local cloneFaction = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][cloneIdx].faction
2233
2234 local week = self:GetEffectivePresetWeek()
2235
2236 if db.currentSeason ~= 3 then
2237 if emissaryIds[MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx].id] then return false end
2238 elseif db.currentSeason ~= 4 then
2239 if MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx].corrupted then return false end
2240 end
2241
2242 --beguiling weekly configuration
2243 local weekData = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][cloneIdx].week
2244 if weekData then
2245 if weekData[week] and not (cloneFaction and cloneFaction~= preset.faction) and db.currentDifficulty >= 10 then
2246 return true
2247 else
2248 return false
2249 end
2250 end
2251
2252 week = week%3
2253 if week == 0 then week = 3 end
2254 local isBlacktoothWeek = week == 2
2255
2256 if not isCloneBlacktoothEvent or isBlacktoothWeek then
2257 if not (cloneFaction and cloneFaction~= preset.faction) then
2258 local isCloneTeeming = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][cloneIdx].teeming
2259 local isCloneNegativeTeeming = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][cloneIdx].negativeTeeming
2260 if MDT:IsCurrentPresetTeeming() or ((isCloneTeeming and isCloneTeeming == false) or (not isCloneTeeming)) then
2261 if not(MDT:IsCurrentPresetTeeming() and isCloneNegativeTeeming) then
2262 return true
2263 end
2264 end
2265 end
2266 end
2267end
2268
2269---IsCurrentPresetTeeming
2270---Returns true if the current preset has teeming turned on, false otherwise
2271function MDT:IsCurrentPresetTeeming()
2272 --return self:GetCurrentPreset().week
2273 return db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.teeming
2274end
2275
2276---IsCurrentPresetFortified
2277function MDT:IsCurrentPresetFortified()
2278 return self:GetCurrentPreset().week%2 == 0
2279end
2280
2281---IsCurrentPresetTyrannical
2282function MDT:IsCurrentPresetTyrannical()
2283 return self:GetCurrentPreset().week%2 == 1
2284end
2285
2286---MouseDownHook
2287function MDT:MouseDownHook()
2288 return
2289end
2290
2291---Handles mouse-down events on the map scrollframe
2292MDT.OnMouseDown = function(self, button)
2293 local scrollFrame = MDT.main_frame.scrollFrame
2294 if scrollFrame.zoomedIn then
2295 scrollFrame.panning = true
2296 scrollFrame.cursorX,scrollFrame.cursorY = GetCursorPosition()
2297 end
2298 scrollFrame.oldX = scrollFrame.cursorX
2299 scrollFrame.oldY = scrollFrame.cursorY
2300 MDT:MouseDownHook()
2301end
2302
2303---handles mouse-up events on the map scrollframe
2304MDT.OnMouseUp = function(self, button)
2305 local scrollFrame = MDT.main_frame.scrollFrame
2306 if scrollFrame.panning then scrollFrame.panning = false end
2307
2308 --play minimap ping on right click at cursor position
2309 --only ping if we didnt pan
2310 if scrollFrame.oldX==scrollFrame.cursorX or scrollFrame.oldY==scrollFrame.cursorY then
2311 if button == "RightButton" then
2312 local x,y = MDT:GetCursorPosition()
2313 MDT:PingMap(x,y)
2314 local sublevel = MDT:GetCurrentSubLevel()
2315 if MDT.liveSessionActive then MDT:LiveSession_SendPing(x,y,sublevel) end
2316 end
2317 end
2318end
2319
2320---Pings the map
2321function MDT:PingMap(x, y)
2322 self.ping:ClearAllPoints()
2323 self.ping:SetPoint("CENTER",self.main_frame.mapPanelTile1,"TOPLEFT",x,y)
2324 self.ping:SetModel("interface/minimap/ping/minimapping.m2")
2325 local mainFrame = MDTMapPanelFrame
2326 local mapScale = mainFrame:GetScale()
2327 self:SetPingOffsets(mapScale)
2328 self.ping:Show()
2329 UIFrameFadeOut(self.ping, 2, 1, 0)
2330 self.ping:SetSequence(0)
2331end
2332
2333function MDT:SetPingOffsets(mapScale)
2334 local scale = 0.35
2335 local offset = (10.25/1000)*mapScale
2336 MDT.ping:SetTransform(offset,offset,0,0,0,0,scale)
2337end
2338
2339---SetCurrentSubLevel
2340---Sets the sublevel of the currently active preset, need to UpdateMap to reflect the change in UI
2341function MDT:SetCurrentSubLevel(sublevel)
2342 MDT:GetCurrentPreset().value.currentSublevel = sublevel
2343end
2344
2345---GetCurrentPull
2346---Returns the current pull of the currently active preset
2347function MDT:GetCurrentPull()
2348 local selection = MDT:GetSelection()
2349 return selection[#selection]
2350end
2351
2352---GetCurrentSubLevel
2353---Returns the sublevel of the currently active preset
2354function MDT:GetCurrentSubLevel()
2355 return MDT:GetCurrentPreset().value.currentSublevel
2356end
2357
2358---GetCurrentPreset
2359---Returns the current preset
2360function MDT:GetCurrentPreset()
2361 return db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]]
2362end
2363
2364---GetCurrentLivePreset
2365function MDT:GetCurrentLivePreset()
2366 if not self.livePresetUID then return end
2367 if self.liveUpdateFrameOpen then
2368 for fullName,cachedPreset in pairs(self.transmissionCache) do
2369 if cachedPreset.uid == self.livePresetUID then
2370 return cachedPreset
2371 end
2372 end
2373 end
2374 for dungeonIdx,presets in pairs(db.presets) do
2375 for presetIdx,preset in pairs(presets) do
2376 if preset.uid and preset.uid == self.livePresetUID then
2377 return preset,presetIdx
2378 end
2379 end
2380 end
2381end
2382
2383---GetEffectivePresetWeek
2384function MDT:GetEffectivePresetWeek(preset)
2385 preset = preset or self:GetCurrentPreset()
2386 local week
2387 if db.MDI.enabled then
2388 week = preset.mdi.beguiling or 1
2389 if week == 14 then week = 1 end
2390 if week == 15 then week = 3 end
2391 else
2392 week = preset.week
2393 end
2394 return week
2395end
2396
2397---GetEffectivePresetSeason
2398function MDT:GetEffectivePresetSeason(preset)
2399 local season = db.currentSeason
2400 if db.MDI.enabled then
2401 local mdiWeek = preset.mdi.beguiling
2402 season = (mdiWeek == 1 or mdiWeek == 2 or mdiWeek == 3) and 3 or mdiWeek == 13 and 2 or (mdiWeek == 14 or mdiWeek == 15) and 4
2403 end
2404 return season
2405end
2406
2407---ReturnToLivePreset
2408function MDT:ReturnToLivePreset()
2409 local preset,presetIdx = self:GetCurrentLivePreset()
2410 self:UpdateToDungeon(preset.value.currentDungeonIdx,true)
2411 db.currentPreset[db.currentDungeonIdx] = presetIdx
2412 self:UpdatePresetDropDown()
2413 self:UpdateMap()
2414end
2415
2416---SetLivePreset
2417function MDT:SetLivePreset()
2418 local preset = self:GetCurrentPreset()
2419 self:SetUniqueID(preset)
2420 self.livePresetUID = preset.uid
2421 self:LiveSession_SendPreset(preset)
2422 self:UpdatePresetDropdownTextColor()
2423 self.main_frame.setLivePresetButton:Hide()
2424 self.main_frame.liveReturnButton:Hide()
2425end
2426
2427---IsWeekTeeming
2428---Returns if the current week has an affix week set that includes the teeming affix
2429function MDT:IsWeekTeeming(week)
2430 if not week then week = MDT:GetCurrentAffixWeek() or 1 end
2431 return affixWeeks[week][1] == 5
2432end
2433
2434---Returns if the current week has an affix weeks set that includes the inspiring affix
2435function MDT:IsWeekInspiring(week)
2436 if not week then week = MDT:GetCurrentAffixWeek() or 1 end
2437 return affixWeeks[week][1] == 122 or affixWeeks[week][2] == 122
2438end
2439
2440---IsPresetTeeming
2441---Returns if the preset is set to a week which contains the teeming affix
2442function MDT:IsPresetTeeming(preset)
2443 return MDT:IsWeekTeeming(preset.week)
2444end
2445
2446function MDT:GetRiftOffsets()
2447 local week = self:GetEffectivePresetWeek()
2448 local preset = self:GetCurrentPreset()
2449 preset.value.riftOffsets = preset.value.riftOffsets or {}
2450 local riftOffsets = preset.value.riftOffsets
2451 riftOffsets[week] = riftOffsets[week] or {}
2452 return riftOffsets[week]
2453end
2454
2455
2456function MDT:MakeMapTexture(frame)
2457 MDT.contextMenuList = {}
2458
2459 tinsert(MDT.contextMenuList, {
2460 text = "Close",
2461 notCheckable = 1,
2462 func = frame.contextDropdown:Hide()
2463 })
2464
2465 -- Scroll Frame
2466 if frame.scrollFrame == nil then
2467 frame.scrollFrame = CreateFrame("ScrollFrame", "MDTScrollFrame",frame)
2468 frame.scrollFrame:ClearAllPoints()
2469 frame.scrollFrame:SetSize(sizex*db.scale, sizey*db.scale)
2470 --frame.scrollFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, 0)
2471 frame.scrollFrame:SetAllPoints(frame)
2472
2473 -- Enable mousewheel scrolling
2474 frame.scrollFrame:EnableMouseWheel(true)
2475 local lastModifiedScroll
2476 local ignoredTargets = {--ignore alt scroll if expansion would be changed
2477 [14] = true,
2478 [27] = true,
2479 [28] = true,
2480 [37] = true,
2481 }
2482 frame.scrollFrame:SetScript("OnMouseWheel", function(self, delta)
2483 if IsControlKeyDown() then
2484 if not lastModifiedScroll or lastModifiedScroll < GetTime() - 0.1 then
2485 lastModifiedScroll = GetTime()
2486 delta = delta*-1
2487 local target = MDT:GetCurrentSubLevel()+delta
2488 if dungeonSubLevels[db.currentDungeonIdx][target] then
2489 MDT:SetCurrentSubLevel(target)
2490 MDT:UpdateMap()
2491 MDT:ZoomMapToDefault()
2492 end
2493 end
2494 elseif IsAltKeyDown() then
2495 if not lastModifiedScroll or lastModifiedScroll < GetTime() - 0.3 then
2496 lastModifiedScroll = GetTime()
2497 delta = delta*-1
2498 local target = db.currentDungeonIdx+delta
2499 if dungeonList[target] and not ignoredTargets[target] then
2500 local group = MDT.main_frame.DungeonSelectionGroup
2501 group.DungeonDropdown:Fire("OnValueChanged", target)
2502 end
2503 end
2504 else
2505 MDT:ZoomMap(delta)
2506 end
2507 end)
2508
2509 --PAN
2510 frame.scrollFrame:EnableMouse(true)
2511 frame.scrollFrame:SetScript("OnMouseDown", MDT.OnMouseDown)
2512 frame.scrollFrame:SetScript("OnMouseUp", MDT.OnMouseUp)
2513
2514
2515 frame.scrollFrame:SetScript("OnUpdate", function(self,elapsed)
2516 local x, y = GetCursorPosition()
2517 MDT:OnPan(x, y)
2518 MDT:OnPanFadeOut(elapsed)
2519 end)
2520
2521 if frame.mapPanelFrame == nil then
2522 frame.mapPanelFrame = CreateFrame("frame","MDTMapPanelFrame",nil)
2523 frame.mapPanelFrame:ClearAllPoints()
2524 frame.mapPanelFrame:SetSize(sizex*db.scale, sizey*db.scale)
2525 --frame.mapPanelFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, 0)
2526 frame.mapPanelFrame:SetAllPoints(frame)
2527 end
2528
2529 --create the 12 tiles and set the scrollchild
2530 for i=1,12 do
2531 frame["mapPanelTile"..i] = frame.mapPanelFrame:CreateTexture("MDTmapPanelTile"..i, "BACKGROUND")
2532 frame["mapPanelTile"..i]:SetDrawLayer(canvasDrawLayer, 0)
2533 --frame["mapPanelTile"..i]:SetAlpha(0.3)
2534 frame["mapPanelTile"..i]:SetSize(frame:GetWidth()/4+(5*db.scale),frame:GetWidth()/4+(5*db.scale))
2535 end
2536 frame.mapPanelTile1:SetPoint("TOPLEFT",frame.mapPanelFrame,"TOPLEFT",0,0)
2537 frame.mapPanelTile2:SetPoint("TOPLEFT",frame.mapPanelTile1,"TOPRIGHT")
2538 frame.mapPanelTile3:SetPoint("TOPLEFT",frame.mapPanelTile2,"TOPRIGHT")
2539 frame.mapPanelTile4:SetPoint("TOPLEFT",frame.mapPanelTile3,"TOPRIGHT")
2540 frame.mapPanelTile5:SetPoint("TOPLEFT",frame.mapPanelTile1,"BOTTOMLEFT")
2541 frame.mapPanelTile6:SetPoint("TOPLEFT",frame.mapPanelTile5,"TOPRIGHT")
2542 frame.mapPanelTile7:SetPoint("TOPLEFT",frame.mapPanelTile6,"TOPRIGHT")
2543 frame.mapPanelTile8:SetPoint("TOPLEFT",frame.mapPanelTile7,"TOPRIGHT")
2544 frame.mapPanelTile9:SetPoint("TOPLEFT",frame.mapPanelTile5,"BOTTOMLEFT")
2545 frame.mapPanelTile10:SetPoint("TOPLEFT",frame.mapPanelTile9,"TOPRIGHT")
2546 frame.mapPanelTile11:SetPoint("TOPLEFT",frame.mapPanelTile10,"TOPRIGHT")
2547 frame.mapPanelTile12:SetPoint("TOPLEFT",frame.mapPanelTile11,"TOPRIGHT")
2548
2549 --create the 150 large map tiles
2550 for i=1,10 do
2551 for j=1,15 do
2552 frame["largeMapPanelTile"..i..j] = frame.mapPanelFrame:CreateTexture("MDTLargeMapPanelTile"..i..j, "BACKGROUND")
2553 local tile = frame["largeMapPanelTile"..i..j]
2554 tile:SetDrawLayer(canvasDrawLayer, 5)
2555 tile:SetSize(frame:GetWidth()/15,frame:GetWidth()/15)
2556 if i==1 and j==1 then
2557 --to mapPanel
2558 tile:SetPoint("TOPLEFT",frame.mapPanelFrame,"TOPLEFT",0,0)
2559 elseif j==1 then
2560 --to tile above
2561 tile:SetPoint("TOPLEFT",frame["largeMapPanelTile"..(i-1)..j],"BOTTOMLEFT",0,0)
2562 else
2563 --to tile to the left
2564 tile:SetPoint("TOPLEFT",frame["largeMapPanelTile"..i..(j-1)],"TOPRIGHT",0,0)
2565 end
2566 tile:SetColorTexture(i/10,j/10,0,1)
2567 tile:Hide()
2568 end
2569 end
2570
2571
2572 frame.scrollFrame:SetScrollChild(frame.mapPanelFrame)
2573
2574 frame.scrollFrame.cursorX = 0
2575 frame.scrollFrame.cursorY = 0
2576
2577 frame.scrollFrame.queuedDeltaX = 0;
2578 frame.scrollFrame.queuedDeltaY = 0;
2579 end
2580
2581end
2582
2583local function round(number, decimals)
2584 return (("%%.%df"):format(decimals)):format(number)
2585end
2586function MDT:CalculateEnemyHealth(boss, baseHealth, level, ignoreFortified)
2587 local fortified = MDT:IsCurrentPresetFortified()
2588 local tyrannical = MDT:IsCurrentPresetTyrannical()
2589 local mult = 1
2590 if boss == false and fortified == true and (not ignoreFortified) then mult = 1.2 end
2591 if boss == true and tyrannical == true then mult = 1.4 end
2592 mult = round((1.10^math.max(level-2,0))*mult,2)
2593 return round(mult*baseHealth,0)
2594end
2595
2596function MDT:ReverseCalcEnemyHealth(unit, level, boss)
2597 local health = UnitHealthMax(unit)
2598 local fortified = MDT:IsCurrentPresetFortified()
2599 local tyrannical = MDT:IsCurrentPresetTyrannical()
2600 local mult = 1
2601 if boss == false and fortified == true then mult = 1.2 end
2602 if boss == true and tyrannical == true then mult = 1.4 end
2603 mult = round((1.10^math.max(level-2,0))*mult,2)
2604 local baseHealth = health/mult
2605 return baseHealth
2606end
2607
2608function MDT:FormatEnemyHealth(amount)
2609 amount = tonumber(amount)
2610 if not amount then return "" end
2611 if amount < 1e3 then
2612 return 0
2613 elseif amount >= 1e12 then
2614 return string.format("%.3ft", amount/1e12)
2615 elseif amount >= 1e9 then
2616 return string.format("%.3fb", amount/1e9)
2617 elseif amount >= 1e6 then
2618 return string.format("%.2fm", amount/1e6)
2619 elseif amount >= 1e3 then
2620 return string.format("%.1fk", amount/1e3)
2621 end
2622end
2623
2624function MDT:UpdateDungeonEnemies()
2625 MDT:DungeonEnemies_UpdateEnemies()
2626end
2627
2628function MDT:HideAllDialogs()
2629 MDT.main_frame.presetCreationFrame:Hide()
2630 MDT.main_frame.presetImportFrame:Hide()
2631 MDT.main_frame.ExportFrame:Hide()
2632 MDT.main_frame.RenameFrame:Hide()
2633 MDT.main_frame.ClearConfirmationFrame:Hide()
2634 MDT.main_frame.DeleteConfirmationFrame:Hide()
2635 MDT.main_frame.automaticColorsFrame.CustomColorFrame:Hide()
2636 MDT.main_frame.automaticColorsFrame:Hide()
2637 if MDT.main_frame.ConfirmationFrame then MDT.main_frame.ConfirmationFrame:Hide() end
2638end
2639
2640function MDT:OpenImportPresetDialog()
2641 MDT:HideAllDialogs()
2642 MDT.main_frame.presetImportFrame:ClearAllPoints()
2643 MDT.main_frame.presetImportFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50)
2644 MDT.main_frame.presetImportFrame:Show()
2645 MDT.main_frame.presetImportBox:SetText("")
2646 MDT.main_frame.presetImportBox:SetFocus()
2647 MDT.main_frame.presetImportLabel:SetText(nil)
2648end
2649
2650function MDT:OpenNewPresetDialog()
2651 MDT:HideAllDialogs()
2652 local presetList = {}
2653 local countPresets = 0
2654 for k,v in pairs(db.presets[db.currentDungeonIdx]) do
2655 if v.text ~= "<New Preset>" then
2656 table.insert(presetList,k,v.text)
2657 countPresets=countPresets+1
2658 end
2659 end
2660 table.insert(presetList,1,"Empty")
2661 MDT.main_frame.PresetCreationDropDown:SetList(presetList)
2662 MDT.main_frame.PresetCreationDropDown:SetValue(1)
2663 MDT.main_frame.PresetCreationEditbox:SetText(L["defaultPresetName"].." "..countPresets+1)
2664 MDT.main_frame.presetCreationFrame:ClearAllPoints()
2665 MDT.main_frame.presetCreationFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50)
2666 MDT.main_frame.presetCreationFrame:SetStatusText("")
2667 MDT.main_frame.presetCreationFrame:Show()
2668 MDT.main_frame.presetCreationCreateButton:SetDisabled(false)
2669 MDT.main_frame.presetCreationCreateButton.text:SetTextColor(1,0.8196,0)
2670 MDT.main_frame.PresetCreationEditbox:SetFocus()
2671 MDT.main_frame.PresetCreationEditbox:HighlightText(0,50)
2672 MDT.main_frame.presetImportBox:SetText("")
2673end
2674
2675function MDT:OpenClearPresetDialog()
2676 MDT:HideAllDialogs()
2677 MDT.main_frame.ClearConfirmationFrame:ClearAllPoints()
2678 MDT.main_frame.ClearConfirmationFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50)
2679 local currentPresetName = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].text
2680 MDT.main_frame.ClearConfirmationFrame.label:SetText(string.format(L["Reset %s?"],currentPresetName))
2681 MDT.main_frame.ClearConfirmationFrame:Show()
2682end
2683
2684function MDT:OpenAutomaticColorsDialog()
2685 MDT:HideAllDialogs()
2686 MDT.main_frame.automaticColorsFrame:ClearAllPoints()
2687 MDT.main_frame.automaticColorsFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50)
2688 MDT.main_frame.automaticColorsFrame:SetStatusText("")
2689 MDT.main_frame.automaticColorsFrame:Show()
2690 MDT.main_frame.automaticColorsFrame.CustomColorFrame:Hide()
2691 if db.colorPaletteInfo.colorPaletteIdx == 6 then
2692 MDT:OpenCustomColorsDialog()
2693 end
2694end
2695
2696function MDT:OpenCustomColorsDialog(frame)
2697 MDT:HideAllDialogs()
2698 MDT.main_frame.automaticColorsFrame:Show() --Not the prettiest way to handle this, but it works.
2699 MDT.main_frame.automaticColorsFrame.CustomColorFrame:ClearAllPoints()
2700 MDT.main_frame.automaticColorsFrame.CustomColorFrame:SetPoint("CENTER",264,-7)
2701 MDT.main_frame.automaticColorsFrame.CustomColorFrame:SetStatusText("")
2702 MDT.main_frame.automaticColorsFrame.CustomColorFrame:Show()
2703end
2704
2705function MDT:UpdateDungeonDropDown()
2706 local group = MDT.main_frame.DungeonSelectionGroup
2707 group.DungeonDropdown:SetList({})
2708 if db.currentExpansion == 1 then
2709 for i=1,14 do
2710 group.DungeonDropdown:AddItem(i,dungeonList[i])
2711 end
2712 elseif db.currentExpansion == 2 then
2713 for i=15,28 do
2714 group.DungeonDropdown:AddItem(i,dungeonList[i])
2715 end
2716 elseif db.currentExpansion == 3 then
2717 for i = 29,37 do
2718 group.DungeonDropdown:AddItem(i,dungeonList[i])
2719 end
2720 end
2721 group.DungeonDropdown:SetValue(db.currentDungeonIdx)
2722 group.SublevelDropdown:SetList(dungeonSubLevels[db.currentDungeonIdx])
2723 group.SublevelDropdown:SetValue(db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel)
2724 group.DungeonDropdown:ClearFocus()
2725 group.SublevelDropdown:ClearFocus()
2726end
2727
2728---CreateDungeonSelectDropdown
2729---Creates both dungeon and sublevel dropdowns
2730function MDT:CreateDungeonSelectDropdown(frame)
2731 --Simple Group to hold both dropdowns
2732 frame.DungeonSelectionGroup = AceGUI:Create("SimpleGroup")
2733 local group = frame.DungeonSelectionGroup
2734 group.frame:SetFrameStrata("HIGH")
2735 group.frame:SetFrameLevel(50)
2736 group:SetWidth(200)
2737 group:SetHeight(50)
2738 group:SetPoint("TOPLEFT",frame.topPanel,"BOTTOMLEFT",0,2)
2739 group:SetLayout("List")
2740
2741 MDT:FixAceGUIShowHide(group)
2742
2743 --dungeon select
2744 group.DungeonDropdown = AceGUI:Create("Dropdown")
2745 group.DungeonDropdown.text:SetJustifyH("LEFT")
2746 group.DungeonDropdown:SetCallback("OnValueChanged",function(widget,callbackName,key)
2747 if key == 14 then
2748 db.currentExpansion = 2
2749 db.currentDungeonIdx = 15
2750 MDT:UpdateDungeonDropDown()
2751 MDT:UpdateToDungeon(db.currentDungeonIdx)
2752 elseif key == 27 then
2753 db.currentExpansion = 1
2754 db.currentDungeonIdx = 1
2755 MDT:UpdateDungeonDropDown()
2756 MDT:UpdateToDungeon(db.currentDungeonIdx)
2757 elseif key == 28 then
2758 db.currentExpansion = 3
2759 db.currentDungeonIdx = 29
2760 MDT:UpdateDungeonDropDown()
2761 MDT:UpdateToDungeon(db.currentDungeonIdx)
2762 elseif key == 37 then
2763 db.currentExpansion = 2
2764 db.currentDungeonIdx = 15
2765 MDT:UpdateDungeonDropDown()
2766 MDT:UpdateToDungeon(db.currentDungeonIdx)
2767 else
2768 MDT:UpdateToDungeon(key)
2769 end
2770 end)
2771 group:AddChild(group.DungeonDropdown)
2772
2773 --sublevel select
2774 group.SublevelDropdown = AceGUI:Create("Dropdown")
2775 group.SublevelDropdown.text:SetJustifyH("LEFT")
2776 group.SublevelDropdown:SetCallback("OnValueChanged",function(widget,callbackName,key)
2777 db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel = key
2778 MDT:UpdateMap()
2779 MDT:ZoomMapToDefault()
2780 end)
2781 group:AddChild(group.SublevelDropdown)
2782
2783 MDT:UpdateDungeonDropDown()
2784end
2785
2786---EnsureDBTables
2787---Makes sure profiles are valid and have their fields set
2788function MDT:EnsureDBTables()
2789 --dungeonIdx doesnt exist
2790 if not dungeonList[db.currentDungeonIdx] or string.find(dungeonList[db.currentDungeonIdx],">") then
2791 db.currentDungeonIdx = db.currentExpansion == 1 and 1 or db.currentExpansion == 2 and 15
2792 end
2793 local preset = MDT:GetCurrentPreset()
2794 preset.week = preset.week or MDT:GetCurrentAffixWeek()
2795 db.currentPreset[db.currentDungeonIdx] = db.currentPreset[db.currentDungeonIdx] or 1
2796 db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentDungeonIdx = db.currentDungeonIdx
2797 db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel or 1
2798 db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentPull = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentPull or 1
2799 db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls or {}
2800 -- make sure, that at least 1 pull exists
2801 if #db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls == 0 then
2802 db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls[1] = {}
2803 end
2804
2805 --detect gaps in pull list and delete invalid pulls
2806 for k,v in pairs(preset.value.pulls) do
2807 if k == 0 or k>#preset.value.pulls then
2808 preset.value.pulls[k] = nil
2809 end
2810 end
2811
2812 -- Set current pull to last pull, if the actual current pull does not exists anymore
2813 if not db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls[db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentPull] then
2814 db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentPull = #db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls
2815 end
2816
2817 for k,v in pairs(db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls) do
2818 if k ==0 then
2819 db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls[0] = nil
2820 break
2821 end
2822 end
2823
2824 --removed clones: remove data from presets
2825 for pullIdx,pull in pairs(preset.value.pulls) do
2826 for enemyIdx,clones in pairs(pull) do
2827
2828 if tonumber(enemyIdx) then
2829 --enemy does not exist at all anymore
2830 if not MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx] then
2831 pull[enemyIdx] = nil
2832 else
2833 --only clones
2834 for k,v in pairs(clones) do
2835 if not MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][v] then
2836 clones[k] = nil
2837 end
2838 end
2839 end
2840 end
2841 end
2842 pull["color"] = pull["color"] or db.defaultColor
2843 end
2844
2845 MDT:GetCurrentPreset().week = MDT:GetCurrentPreset().week or MDT:GetCurrentAffixWeek()
2846
2847 if db.currentDungeonIdx == 19 then
2848 local englishFaction = UnitFactionGroup("player")
2849 preset.faction = preset.faction or (englishFaction and englishFaction=="Alliance") and 2 or 1
2850 end
2851
2852 if db.currentDungeonIdx == 16 and (not preset.freeholdCrewSelected) then
2853 local week = preset.week
2854 week = week%3
2855 if week == 0 then week = 3 end
2856 preset.freeholdCrew = week
2857 preset.freeholdCrewSelected = true
2858 end
2859
2860 db.MDI = db.MDI or {}
2861 preset.mdi = preset.mdi or {}
2862 preset.mdi.freehold = preset.mdi.freehold or 1
2863 preset.mdi.freeholdJoined = preset.mdi.freeholdJoined or false
2864 preset.mdi.beguiling = preset.mdi.beguiling or 1
2865 preset.difficulty = preset.difficulty or db.currentDifficulty
2866 preset.mdiEnabled = preset.mdiEnabled or db.MDI.enabled
2867
2868 --make sure sublevel actually exists for the dungeon
2869 --this might have been caused by bugged dropdowns in the past
2870 local maxSublevel = -1
2871 for _,_ in pairs(MDT.dungeonMaps[db.currentDungeonIdx]) do
2872 maxSublevel = maxSublevel + 1
2873 end
2874 if preset.value.currentSublevel > maxSublevel then preset.value.currentSublevel = maxSublevel end
2875 --make sure teeeming flag is set
2876 preset.value.teeming = MDT:IsWeekTeeming(preset.week)
2877end
2878
2879function MDT:GetTileFormat(dungeonIdx)
2880 local mapInfo = MDT.mapInfo[dungeonIdx]
2881 return mapInfo and mapInfo.tileFormat or 4
2882end
2883
2884function MDT:UpdateMap(ignoreSetSelection, ignoreReloadPullButtons, ignoreUpdateProgressBar)
2885 local mapName
2886 local frame = MDT.main_frame
2887 mapName = MDT.dungeonMaps[db.currentDungeonIdx][0]
2888 MDT:EnsureDBTables()
2889 local preset = MDT:GetCurrentPreset()
2890 if preset.difficulty then
2891 db.currentDifficulty = preset.difficulty
2892 frame.sidePanel.DifficultySlider:SetValue(db.currentDifficulty)
2893 frame.sidePanel.difficultyWarning:Toggle(db.currentDifficulty)
2894 end
2895 local fileName = MDT.dungeonMaps[db.currentDungeonIdx][preset.value.currentSublevel]
2896 local path = "Interface\\WorldMap\\"..mapName.."\\"
2897 local tileFormat = MDT:GetTileFormat(db.currentDungeonIdx)
2898 for i=1,12 do
2899 if tileFormat == 4 then
2900 local texName = path..fileName..i
2901 if frame["mapPanelTile"..i] then
2902 frame["mapPanelTile"..i]:SetTexture(texName)
2903 frame["mapPanelTile"..i]:Show()
2904 end
2905 else
2906 if frame["mapPanelTile"..i] then
2907 frame["mapPanelTile"..i]:Hide()
2908 end
2909 end
2910 end
2911 for i=1,10 do
2912 for j=1,15 do
2913 if tileFormat == 15 then
2914 local texName= path..fileName..((i - 1) * 15 + j)
2915 frame["largeMapPanelTile"..i..j]:SetTexture(texName)
2916 frame["largeMapPanelTile"..i..j]:Show()
2917 else
2918 frame["largeMapPanelTile"..i..j]:Hide()
2919 end
2920 end
2921 end
2922 MDT:UpdateDungeonEnemies()
2923 MDT:DungeonEnemies_UpdateTeeming()
2924 MDT:DungeonEnemies_UpdateSeasonalAffix()
2925 MDT:DungeonEnemies_UpdateInspiring()
2926
2927 if not ignoreReloadPullButtons then
2928 MDT:ReloadPullButtons()
2929 end
2930 --handle delete button disable/enable
2931 local presetCount = 0
2932 for k,v in pairs(db.presets[db.currentDungeonIdx]) do
2933 presetCount = presetCount + 1
2934 end
2935 if (db.currentPreset[db.currentDungeonIdx] == 1 or db.currentPreset[db.currentDungeonIdx] == presetCount) or MDT.liveSessionActive then
2936 MDT.main_frame.sidePanelDeleteButton:SetDisabled(true)
2937 MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(0.5,0.5,0.5)
2938 else
2939 MDT.main_frame.sidePanelDeleteButton:SetDisabled(false)
2940 MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(1,0.8196,0)
2941 end
2942 --live mode
2943 local livePreset = MDT:GetCurrentLivePreset()
2944 if MDT.liveSessionActive and preset ~= livePreset then
2945 MDT.main_frame.liveReturnButton:Show()
2946 MDT.main_frame.setLivePresetButton:Show()
2947 else
2948 MDT.main_frame.liveReturnButton:Hide()
2949 MDT.main_frame.setLivePresetButton:Hide()
2950 end
2951 MDT:UpdatePresetDropdownTextColor()
2952
2953 if not ignoreSetSelection then MDT:SetSelectionToPull(preset.value.currentPull) end
2954 MDT:UpdateDungeonDropDown()
2955 --frame.sidePanel.affixDropdown:SetAffixWeek(MDT:GetCurrentPreset().week,ignoreReloadPullButtons,ignoreUpdateProgressBar)
2956 frame.sidePanel.affixDropdown:SetValue(MDT:GetCurrentPreset().week)
2957 MDT:ToggleFreeholdSelector(db.currentDungeonIdx == 16)
2958 MDT:ToggleBoralusSelector(db.currentDungeonIdx == 19)
2959 MDT:DisplayMDISelector()
2960 MDT:DrawAllPresetObjects()
2961 MDT:KillAllAnimatedLines()
2962 MDT:DrawAllAnimatedLines()
2963end
2964
2965---UpdateToDungeon
2966---Updates the map to the specified dungeon
2967function MDT:UpdateToDungeon(dungeonIdx, ignoreUpdateMap, init)
2968 db.currentExpansion = 1
2969 if dungeonIdx>=15 then db.currentExpansion = 2 end
2970 if dungeonIdx>=29 then db.currentExpansion = 3 end
2971 db.currentDungeonIdx = dungeonIdx
2972 if not db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel then
2973 db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel=1
2974 end
2975 if init then return end
2976 MDT:UpdatePresetDropDown()
2977 if not ignoreUpdateMap then MDT:UpdateMap() end
2978 MDT:ZoomMapToDefault()
2979 --Colors the first pull in "Default" presets
2980 if db.currentPreset[db.currentDungeonIdx] == 1 then MDT:ColorPull() end
2981end
2982
2983function MDT:DeletePreset(index)
2984 tremove(db.presets[db.currentDungeonIdx],index)
2985 db.currentPreset[db.currentDungeonIdx] = index-1
2986 MDT:UpdatePresetDropDown()
2987 MDT:UpdateMap()
2988 MDT:ZoomMapToDefault()
2989end
2990
2991MDT.zoneIdToDungeonIdx = {
2992 [934] = 15,--atal
2993 [935] = 15,--atal
2994 [936] = 16,--fh
2995 [1004] = 17,--kr
2996 [1039] = 18,--shrine
2997 [1040] = 18,--shrine
2998 [1162] = 19,--siege
2999 [1038] = 20,--temple
3000 [1043] = 20,--temple
3001 [1010] = 21,--motherlode
3002 [1041] = 22,--underrot
3003 [1042] = 22,--underrot
3004 [974] = 23,--toldagor
3005 [975] = 23,--toldagor
3006 [976] = 23,--toldagor
3007 [977] = 23,--toldagor
3008 [978] = 23,--toldagor
3009 [979] = 23,--toldagor
3010 [980] = 23,--toldagor
3011 [1015] = 24,--wcm
3012 [1016] = 24,--wcm
3013 [1017] = 24,--wcm
3014 [1018] = 24,--wcm
3015 [1029] = 24,--wcm
3016 [1490] = 25,--lower mecha
3017 [1491] = 26,--upper mecha
3018 [1493] = 26,--upper mecha
3019 [1494] = 26,--upper mecha
3020 [1497] = 26,--upper mecha
3021}
3022local lastUpdatedDungeonIdx
3023function MDT:CheckCurrentZone(init)
3024 local zoneId = C_Map.GetBestMapForUnit("player")
3025 local dungeonIdx = MDT.zoneIdToDungeonIdx[zoneId]
3026 if dungeonIdx and (not lastUpdatedDungeonIdx or dungeonIdx ~= lastUpdatedDungeonIdx) then
3027 lastUpdatedDungeonIdx = dungeonIdx
3028 MDT:UpdateToDungeon(dungeonIdx,nil,init)
3029 end
3030end
3031
3032---CountPresets
3033---Counts the number of presets of the current dungeon
3034function MDT:CountPresets()
3035 return #db.presets[db.currentDungeonIdx]-2
3036end
3037
3038---DeleteAllPresets
3039---Deletes all presets from the current dungeon
3040function MDT:DeleteAllPresets()
3041 local countPresets = #db.presets[db.currentDungeonIdx]-1
3042 for i=countPresets,2,-1 do
3043 tremove(db.presets[db.currentDungeonIdx],i)
3044 db.currentPreset[db.currentDungeonIdx] = i-1
3045 end
3046 MDT:UpdatePresetDropDown()
3047 MDT:UpdateMap()
3048end
3049
3050function MDT:ClearPreset(preset, silent)
3051 if preset == self:GetCurrentPreset() then silent = false end
3052 table.wipe(preset.value.pulls)
3053 preset.value.currentPull = 1
3054 table.wipe(preset.value.riftOffsets)
3055 --MDT:DeleteAllPresetObjects()
3056 self:EnsureDBTables()
3057 if not silent then
3058 self:UpdateMap()
3059 self:ReloadPullButtons()
3060 end
3061 MDT:ColorPull()
3062end
3063
3064function MDT:CreateNewPreset(name)
3065 if name == "<New Preset>" then
3066 MDT.main_frame.presetCreationLabel:SetText(string.format(L["Cannot create preset '%s'"],name))
3067 MDT.main_frame.presetCreationCreateButton:SetDisabled(true)
3068 MDT.main_frame.presetCreationCreateButton.text:SetTextColor(0.5,0.5,0.5)
3069 MDT.main_frame.presetCreationFrame:DoLayout()
3070 return
3071 end
3072 local duplicate = false
3073 local countPresets = 0
3074 for k,v in pairs(db.presets[db.currentDungeonIdx]) do
3075 countPresets = countPresets + 1
3076 if v.text == name then duplicate = true end
3077 end
3078 if duplicate == false then
3079 db.presets[db.currentDungeonIdx][countPresets+1] = db.presets[db.currentDungeonIdx][countPresets] --put <New Preset> at the end of the list
3080
3081 local startingPointPresetIdx = MDT.main_frame.PresetCreationDropDown:GetValue()-1
3082 if startingPointPresetIdx>0 then
3083 db.presets[db.currentDungeonIdx][countPresets] = MDT:CopyObject(db.presets[db.currentDungeonIdx][startingPointPresetIdx])
3084 db.presets[db.currentDungeonIdx][countPresets].text = name
3085 db.presets[db.currentDungeonIdx][countPresets].uid = nil
3086 else
3087 db.presets[db.currentDungeonIdx][countPresets] = {text=name,value={}}
3088 end
3089
3090 db.currentPreset[db.currentDungeonIdx] = countPresets
3091 MDT.main_frame.presetCreationFrame:Hide()
3092 MDT:UpdatePresetDropDown()
3093 MDT:UpdateMap()
3094 MDT:ZoomMapToDefault()
3095 MDT:SetPresetColorPaletteInfo()
3096 MDT:ColorAllPulls()
3097 else
3098 MDT.main_frame.presetCreationLabel:SetText(string.format(L["Preset '%s' already exists"],name))
3099 MDT.main_frame.presetCreationCreateButton:SetDisabled(true)
3100 MDT.main_frame.presetCreationCreateButton.text:SetTextColor(0.5,0.5,0.5)
3101 MDT.main_frame.presetCreationFrame:DoLayout()
3102 end
3103end
3104
3105
3106
3107function MDT:SanitizePresetName(text)
3108 --check if name is valid, block button if so, unblock if valid
3109 if text == "<New Preset>" then
3110 return false
3111 else
3112 local duplicate = false
3113 local countPresets = 0
3114 for k,v in pairs(db.presets[db.currentDungeonIdx]) do
3115 countPresets = countPresets + 1
3116 if v.text == text then duplicate = true end
3117 end
3118 return not duplicate and text or false
3119 end
3120end
3121
3122
3123function MDT:MakeChatPresetImportFrame(frame)
3124 frame.chatPresetImportFrame = AceGUI:Create("Frame")
3125 local chatImport = frame.chatPresetImportFrame
3126 chatImport:SetTitle(L["Import Preset"])
3127 chatImport:SetWidth(400)
3128 chatImport:SetHeight(100)
3129 chatImport:EnableResize(false)
3130 chatImport:SetLayout("Flow")
3131 chatImport:SetCallback("OnClose", function(widget)
3132 MDT:UpdatePresetDropDown()
3133 if db.currentPreset[db.currentDungeonIdx] ~= 1 then
3134 MDT.main_frame.sidePanelDeleteButton:SetDisabled(false)
3135 MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(1,0.8196,0)
3136 end
3137 end)
3138 chatImport.defaultText = L["Import Preset"]..":\n"
3139 chatImport.importLabel = AceGUI:Create("Label")
3140 chatImport.importLabel:SetText(chatImport.defaultText)
3141 chatImport.importLabel:SetWidth(250)
3142 --chatImport.importLabel:SetColor(1,0,0)
3143
3144 chatImport.importButton = AceGUI:Create("Button")
3145 local importButton = chatImport.importButton
3146 importButton:SetText(L["Import"])
3147 importButton:SetWidth(100)
3148 importButton:SetCallback("OnClick", function()
3149 local newPreset = chatImport.currentPreset
3150 if MDT:ValidateImportPreset(newPreset) then
3151 chatImport:Hide()
3152 MDT:ImportPreset(MDT:DeepCopy(newPreset))
3153 else
3154 print(L["MDT: Error importing preset"])
3155 end
3156 end)
3157 chatImport:AddChild(chatImport.importLabel)
3158 chatImport:AddChild(importButton)
3159 chatImport:Hide()
3160
3161end
3162
3163function MDT:OpenChatImportPresetDialog(sender, preset, live)
3164 MDT:HideAllDialogs()
3165 local chatImport = MDT.main_frame.chatPresetImportFrame
3166 chatImport:ClearAllPoints()
3167 chatImport:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50)
3168 chatImport.currentPreset = preset
3169 local dungeon = MDT:GetDungeonName(preset.value.currentDungeonIdx)
3170 local name = preset.text
3171 chatImport:Show()
3172 chatImport.importLabel:SetText(chatImport.defaultText..sender.. ": "..dungeon.." - "..name)
3173 chatImport:SetTitle(L["Import Preset"])
3174 chatImport.importButton:SetText(L["Import"])
3175 chatImport.live = nil
3176 if live then
3177 chatImport.importLabel:SetText(string.format(L["Join Live Session"],"\n",sender,dungeon,name))
3178 chatImport:SetTitle(L["Live Session"])
3179 chatImport.importButton:SetText(L["Join"])
3180 chatImport.live = true
3181 end
3182end
3183
3184function MDT:MakePresetImportFrame(frame)
3185 frame.presetImportFrame = AceGUI:Create("Frame")
3186 frame.presetImportFrame:SetTitle(L["Import Preset"])
3187 frame.presetImportFrame:SetWidth(400)
3188 frame.presetImportFrame:SetHeight(200)
3189 frame.presetImportFrame:EnableResize(false)
3190 frame.presetImportFrame:SetLayout("Flow")
3191 frame.presetImportFrame:SetCallback("OnClose", function(widget)
3192 MDT:UpdatePresetDropDown()
3193 if db.currentPreset[db.currentDungeonIdx] ~= 1 then
3194 MDT.main_frame.sidePanelDeleteButton:SetDisabled(false)
3195 MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(1,0.8196,0)
3196 end
3197 end)
3198
3199 frame.presetImportLabel = AceGUI:Create("Label")
3200 frame.presetImportLabel:SetText(nil)
3201 frame.presetImportLabel:SetWidth(390)
3202 frame.presetImportLabel:SetColor(1,0,0)
3203
3204 local importString = ""
3205 frame.presetImportBox = AceGUI:Create("EditBox")
3206 frame.presetImportBox:SetLabel(L["Import Preset"]..":")
3207 frame.presetImportBox:SetWidth(255)
3208 frame.presetImportBox:SetCallback("OnEnterPressed", function(widget, event, text) importString = text end)
3209 frame.presetImportFrame:AddChild(frame.presetImportBox)
3210
3211 local importButton = AceGUI:Create("Button")
3212 importButton:SetText(L["Import"])
3213 importButton:SetWidth(100)
3214 importButton:SetCallback("OnClick", function()
3215 local newPreset = MDT:StringToTable(importString, true)
3216 if MDT:ValidateImportPreset(newPreset) then
3217 MDT.main_frame.presetImportFrame:Hide()
3218 MDT:ImportPreset(newPreset)
3219 if db.colorPaletteInfo.forceColorBlindMode then
3220 MDT:ColorAllPulls()
3221 end
3222
3223 else
3224 frame.presetImportLabel:SetText(L["Invalid import string"])
3225 end
3226 end)
3227 frame.presetImportFrame:AddChild(importButton)
3228 frame.presetImportFrame:AddChild(frame.presetImportLabel)
3229 frame.presetImportFrame:Hide()
3230
3231end
3232
3233function MDT:MakePresetCreationFrame(frame)
3234 frame.presetCreationFrame = AceGUI:Create("Frame")
3235 frame.presetCreationFrame:SetTitle(L["New Preset"])
3236 frame.presetCreationFrame:SetWidth(400)
3237 frame.presetCreationFrame:SetHeight(200)
3238 frame.presetCreationFrame:EnableResize(false)
3239 --frame.presetCreationFrame:SetCallback("OnClose", function(widget) AceGUI:Release(widget) end)
3240 frame.presetCreationFrame:SetLayout("Flow")
3241 frame.presetCreationFrame:SetCallback("OnClose", function(widget)
3242 MDT:UpdatePresetDropDown()
3243 if db.currentPreset[db.currentDungeonIdx] ~= 1 then
3244 MDT.main_frame.sidePanelDeleteButton:SetDisabled(false)
3245 MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(1,0.8196,0)
3246 end
3247 end)
3248
3249
3250 frame.PresetCreationEditbox = AceGUI:Create("EditBox")
3251 frame.PresetCreationEditbox:SetLabel(L["Preset Name"]..":")
3252 frame.PresetCreationEditbox:SetWidth(255)
3253 frame.PresetCreationEditbox:SetCallback("OnEnterPressed", function(widget, event, text)
3254 --check if name is valid, block button if so, unblock if valid
3255 if MDT:SanitizePresetName(text) then
3256 frame.presetCreationLabel:SetText(nil)
3257 frame.presetCreationCreateButton:SetDisabled(false)
3258 frame.presetCreationCreateButton.text:SetTextColor(1,0.8196,0)
3259 else
3260 frame.presetCreationLabel:SetText(string.format(L["Cannot create preset '%s'"],text))
3261 frame.presetCreationCreateButton:SetDisabled(true)
3262 frame.presetCreationCreateButton.text:SetTextColor(0.5,0.5,0.5)
3263 end
3264 frame.presetCreationFrame:DoLayout()
3265 end)
3266 frame.presetCreationFrame:AddChild(frame.PresetCreationEditbox)
3267
3268 frame.presetCreationCreateButton = AceGUI:Create("Button")
3269 frame.presetCreationCreateButton:SetText(L["Create"])
3270 frame.presetCreationCreateButton:SetWidth(100)
3271 frame.presetCreationCreateButton:SetCallback("OnClick", function()
3272 local name = frame.PresetCreationEditbox:GetText()
3273 MDT:CreateNewPreset(name)
3274 end)
3275 frame.presetCreationFrame:AddChild(frame.presetCreationCreateButton)
3276
3277 frame.presetCreationLabel = AceGUI:Create("Label")
3278 frame.presetCreationLabel:SetText(nil)
3279 frame.presetCreationLabel:SetWidth(390)
3280 frame.presetCreationLabel:SetColor(1,0,0)
3281 frame.presetCreationFrame:AddChild(frame.presetCreationLabel)
3282
3283
3284 frame.PresetCreationDropDown = AceGUI:Create("Dropdown")
3285 frame.PresetCreationDropDown:SetLabel(L["Use as a starting point:"])
3286 frame.PresetCreationDropDown.text:SetJustifyH("LEFT")
3287 frame.presetCreationFrame:AddChild(frame.PresetCreationDropDown)
3288
3289 frame.presetCreationFrame:Hide()
3290end
3291
3292function MDT:ValidateImportPreset(preset)
3293 if type(preset) ~= "table" then return false end
3294 if not preset.text then return false end
3295 if not preset.value then return false end
3296 if type(preset.text) ~= "string" then return false end
3297 if type(preset.value) ~= "table" then return false end
3298 if not preset.value.currentDungeonIdx then return false end
3299 if not preset.value.currentPull then return false end
3300 if not preset.value.currentSublevel then return false end
3301 if not preset.value.pulls then return false end
3302 if type(preset.value.pulls) ~= "table" then return false end
3303 return true
3304end
3305
3306function MDT:ImportPreset(preset, fromLiveSession)
3307 --change dungeon to dungeon of the new preset
3308 self:UpdateToDungeon(preset.value.currentDungeonIdx,true)
3309 local mdiEnabled = preset.mdiEnabled
3310 --search for uid
3311 local updateIndex
3312 local duplicatePreset
3313 for k,v in pairs(db.presets[db.currentDungeonIdx]) do
3314 if v.uid and v.uid == preset.uid then
3315 updateIndex = k
3316 duplicatePreset = v
3317 break
3318 end
3319 end
3320
3321 local updateCallback = function()
3322 if self.main_frame.ConfirmationFrame then
3323 self.main_frame.ConfirmationFrame:SetCallback("OnClose", function() end)
3324 end
3325 db.MDI.enabled = mdiEnabled
3326 db.presets[db.currentDungeonIdx][updateIndex] = preset
3327 db.currentPreset[db.currentDungeonIdx] = updateIndex
3328 self.liveUpdateFrameOpen = nil
3329 self:UpdatePresetDropDown()
3330 self:UpdateMap()
3331 if fromLiveSession then
3332 self.main_frame.SendingStatusBar:Hide()
3333 if self.main_frame.LoadingSpinner then
3334 self.main_frame.LoadingSpinner:Hide()
3335 self.main_frame.LoadingSpinner.Anim:Stop()
3336 end
3337 end
3338 end
3339 local copyCallback = function()
3340 if self.main_frame.ConfirmationFrame then
3341 self.main_frame.ConfirmationFrame:SetCallback("OnClose", function() end)
3342 end
3343 db.MDI.enabled = mdiEnabled
3344 local name = preset.text
3345 local num = 2
3346 for k,v in pairs(db.presets[db.currentDungeonIdx]) do
3347 if name == v.text then
3348 name = preset.text.." "..num
3349 num = num + 1
3350 end
3351 end
3352 preset.text = name
3353 if fromLiveSession then
3354 if duplicatePreset then duplicatePreset.uid = nil end
3355 else
3356 preset.uid = nil
3357 end
3358 local countPresets = 0
3359 for k,v in pairs(db.presets[db.currentDungeonIdx]) do
3360 countPresets = countPresets + 1
3361 end
3362 db.presets[db.currentDungeonIdx][countPresets+1] = db.presets[db.currentDungeonIdx][countPresets] --put <New Preset> at the end of the list
3363 db.presets[db.currentDungeonIdx][countPresets] = preset
3364 db.currentPreset[db.currentDungeonIdx] = countPresets
3365 self.liveUpdateFrameOpen = nil
3366 self:UpdatePresetDropDown()
3367 self:UpdateMap()
3368 if fromLiveSession then
3369 self.main_frame.SendingStatusBar:Hide()
3370 if self.main_frame.LoadingSpinner then
3371 self.main_frame.LoadingSpinner:Hide()
3372 self.main_frame.LoadingSpinner.Anim:Stop()
3373 end
3374 end
3375 end
3376 local closeCallback = function()
3377 self.liveUpdateFrameOpen = nil
3378 self:LiveSession_Disable()
3379 self.main_frame.ConfirmationFrame:SetCallback("OnClose", function() end)
3380 if fromLiveSession then
3381 self.main_frame.SendingStatusBar:Hide()
3382 if self.main_frame.LoadingSpinner then
3383 self.main_frame.LoadingSpinner:Hide()
3384 self.main_frame.LoadingSpinner.Anim:Stop()
3385 end
3386 end
3387 end
3388
3389 --open dialog to ask for replacing
3390 if updateIndex then
3391 local prompt = string.format(L["Earlier Version"],duplicatePreset.text,"\n","\n","\n","\n")
3392 self:OpenConfirmationFrame(450,150,L["Import Preset"],L["Update"],prompt, updateCallback,L["Copy"],copyCallback)
3393 if fromLiveSession then
3394 self.liveUpdateFrameOpen = true
3395 self.main_frame.ConfirmationFrame:SetCallback("OnClose", function()closeCallback() end)
3396 end
3397 else
3398 copyCallback()
3399 end
3400end
3401
3402---Stores r g b values for coloring pulls with MDT:ColorPull()
3403local colorPaletteValues = {
3404 [1] = { --Rainbow values
3405 [1] = {[1]=0.2446, [2]=1, [3]=0.2446},
3406 [2] = {[1]=0.2446, [2]=1, [3]=0.6223},
3407 [3] = {[1]=0.2446, [2]=1, [3]=1},
3408 [4] = {[1]=0.2446, [2]=0.6223, [3]=1},
3409 [5] = {[1]=0.2446, [2]=0.2446, [3]=1},
3410 [6] = {[1]=0.6223, [2]=0.6223, [3]=1},
3411 [7] = {[1]=1, [2]=0.2446, [3]=1},
3412 [8] = {[1]=1, [2]=0.2446, [3]=0.6223},
3413 [9] = {[1]=1, [2]=0.2446, [3]=0.2446},
3414 [10] = {[1]=1, [2]=0.60971, [3]=0.2446},
3415 [11] = {[1]=1, [2]=0.98741, [3]=0.2446},
3416 [12] = {[1]=0.63489, [2]=1, [3]=0.2446},
3417 --[13] = {[1]=1, [2]=0.2446, [3]=0.54676},
3418 --[14] = {[1]=1, [2]=0.2446, [3]=0.32014},
3419 --[15] = {[1]=1, [2]=0.38309, [3]=0.2446},
3420 --[16] = {[1]=1, [2]=0.60971, [3]=0.2446},
3421 --[17] = {[1]=1, [2]=0.83633, [3]=0.2446},
3422 --[18] = {[1]=0.93705, [2]=1, [3]=0.2446},
3423 --[19] = {[1]=0.71043, [2]=1, [3]=0.2446},
3424 --[20] = {[1]=0.48381, [2]=1, [3]=0.2446},
3425 },
3426 [2] = { --Black and Yellow values
3427 [1] = {[1]=0.4, [2]=0.4, [3]=0.4},
3428 [2] = {[1]=1, [2]=1, [3]=0.0},
3429 },
3430 [3] = { --Red, Green and Blue values
3431 [1] = {[1]=0.85882, [2]=0.058824, [3]=0.15294},
3432 [2] = {[1]=0.49804, [2]=1.0, [3]=0.0},
3433 [3] = {[1]=0.0, [2]=0.50196, [3]=1.0},
3434 },
3435 [4] = { --High Contrast values
3436 [1] = {[1]=1, [2]=0.2446, [3]=1},
3437 [2] = {[1]=0.2446, [2]=1, [3]=0.6223},
3438 [3] = {[1]=1, [2]=0.2446, [3]=0.2446},
3439 [4] = {[1]=0.2446, [2]=0.6223, [3]=1},
3440 [5] = {[1]=1, [2]=0.98741, [3]=0.2446},
3441 [6] = {[1]=0.2446, [2]=1, [3]=0.2446},
3442 [7] = {[1]=1, [2]=0.2446, [3]=0.6223},
3443 [8] = {[1]=0.2446, [2]=1, [3]=1},
3444 [9] = {[1]=1, [2]=0.60971, [3]=0.2446},
3445 [10] = {[1]=0.2446, [2]=0.2446, [3]=1},
3446 [11] = {[1]=0.63489, [2]=1, [3]=0.2446},
3447 },
3448 [5] = { --Color Blind Friendly values (Based on IBM's color library "Color blind safe"
3449 [1] = {[1]=0.39215686274509803, [2]=0.5607843137254902, [3]=1.0},
3450 --[2] = {[1]=0.47058823529411764, [2]=0.3686274509803922, [3]=0.9411764705882353},
3451 [2] = {[1]=0.8627450980392157, [2]=0.14901960784313725, [3]=0.4980392156862745},
3452 [3] = {[1]=0.996078431372549, [2]=0.3803921568627451, [3]=0.0},
3453 [4] = {[1]=1.0, [2]=0.6901960784313725, [3]=0.0},
3454 },
3455
3456}
3457
3458---Dropdown menu items for color settings frame
3459local colorPaletteNames = {
3460 [1] = L["Rainbow"],
3461 [2] = L["Black and Yellow"],
3462 [3] = L["Red, Green and Blue"],
3463 [4] = L["High Contrast"],
3464 [5] = L["Color Blind Friendly"],
3465 [6] = L["Custom"],
3466}
3467
3468---SetPresetColorPaletteInfo
3469---Saves currently selected automatic coloring settings to the current
3470---This can be achieved easier, but it will increase the export text length significantly for non custom palettes.
3471function MDT:SetPresetColorPaletteInfo()
3472 local preset = MDT:GetCurrentPreset()
3473 preset.colorPaletteInfo = {}
3474 preset.colorPaletteInfo.autoColoring = db.colorPaletteInfo.autoColoring
3475 if preset.colorPaletteInfo.autoColoring then
3476 preset.colorPaletteInfo.colorPaletteIdx = db.colorPaletteInfo.colorPaletteIdx
3477 if preset.colorPaletteInfo.colorPaletteIdx == 6 then
3478 preset.colorPaletteInfo.customPaletteValues = db.colorPaletteInfo.customPaletteValues
3479 preset.colorPaletteInfo.numberCustomColors = db.colorPaletteInfo.numberCustomColors
3480 end
3481 end
3482 --Code below works, but in most cases it saves more data to the preset and thereby significantly increases the export string length
3483 --MDT:GetCurrentPreset().colorPaletteInfo = db.colorPaletteInfo
3484end
3485
3486---GetPresetColorPaletteInfo
3487function MDT:GetPresetColorPaletteInfo(preset)
3488 preset = preset or MDT:GetCurrentPreset()
3489 return preset.colorPaletteInfo
3490end
3491
3492---ColorPull
3493---Function executes full coloring of a pull and it's blips
3494function MDT:ColorPull(colorValues, pullIdx, preset, bypass, exportColorBlind) -- bypass can be passed as true to color even when automatic coloring is toggled off
3495 local colorPaletteInfo = MDT:GetPresetColorPaletteInfo(preset)
3496 local pullIdx = pullIdx or MDT:GetCurrentPull()
3497 if(pullIdx) then
3498 local colorValues
3499 local numberColors
3500 local r,g,b
3501 if colorPaletteInfo.autoColoring or bypass == true then
3502 --Force color blind mode locally, will not alter the color values saved to a preset
3503 if db.colorPaletteInfo.forceColorBlindMode == true and not exportColorBlind then
3504 --Local color blind mode, will not alter the colorPaletteInfo saved to a preset
3505 colorValues = colorValues or colorPaletteValues[colorValues] or colorPaletteValues[5]
3506 numberColors = #colorValues
3507 else
3508 --Regular coloring
3509 colorValues = colorValues or colorPaletteValues[colorValues] or colorPaletteInfo.colorPaletteIdx == 6 and colorPaletteInfo.customPaletteValues or colorPaletteValues[colorPaletteInfo.colorPaletteIdx]
3510 numberColors = colorPaletteInfo.colorPaletteIdx == 6 and colorPaletteInfo.numberCustomColors or #colorValues -- tables must start from 1 and have no blank rows
3511 end
3512 local colorIdx = (pullIdx-1)%numberColors+1
3513 r,g,b = colorValues[colorIdx][1],colorValues[colorIdx][2],colorValues[colorIdx][3]
3514
3515 MDT:DungeonEnemies_SetPullColor(pullIdx,r,g,b)
3516 MDT:UpdatePullButtonColor(pullIdx,r,g,b)
3517 MDT:DungeonEnemies_UpdateBlipColors(pullIdx,r,g,b)
3518 end
3519 end
3520end
3521
3522---ColorAllPulls
3523---Loops over all pulls in a preset and colors them
3524function MDT:ColorAllPulls(colorValues, startFrom, bypass, exportColorBlind)
3525 local preset = self:GetCurrentPreset()
3526 local startFrom = startFrom or 0
3527 for pullIdx,_ in pairs(preset.value.pulls) do
3528 if pullIdx >= startFrom then
3529 MDT:ColorPull(colorValues, pullIdx, preset, bypass, exportColorBlind)
3530 end
3531 end
3532end
3533
3534---MakeCustomColorFrame
3535---creates frame housing settings for user customized color palette
3536function MDT:MakeCustomColorFrame(frame)
3537 --Base frame for custom palette setup
3538 frame.CustomColorFrame = AceGUI:Create("Frame")
3539 frame.CustomColorFrame:SetTitle(L["Custom Color Palette"])
3540 frame.CustomColorFrame:SetWidth(290)
3541 frame.CustomColorFrame:SetHeight(220)
3542 frame.CustomColorFrame:EnableResize(false)
3543 frame.CustomColorFrame:SetLayout("Flow")
3544 frame:AddChild(frame.CustomColorFrame)
3545
3546 --Slider to adjust number of different colors and remake the frame OnMouseUp
3547 frame.CustomColorFrame.ColorSlider = AceGUI:Create("Slider")
3548 frame.CustomColorFrame.ColorSlider:SetSliderValues(2,20,1)
3549 frame.CustomColorFrame.ColorSlider:SetValue(db.colorPaletteInfo.numberCustomColors)
3550 frame.CustomColorFrame.ColorSlider:SetLabel(L["Choose number of colors"])
3551 frame.CustomColorFrame.ColorSlider:SetRelativeWidth(1)
3552 frame.CustomColorFrame.ColorSlider:SetCallback("OnMouseUp", function(event, callbackName, value)
3553 if value>20 then
3554 db.colorPaletteInfo.numberCustomColors = 20
3555 elseif value<2 then
3556 db.colorPaletteInfo.numberCustomColors = 2
3557 else
3558 db.colorPaletteInfo.numberCustomColors = value
3559 end
3560 MDT:SetPresetColorPaletteInfo()
3561 MDT:ColorAllPulls()
3562 MDT:DrawAllHulls()
3563 frame.CustomColorFrame:ReleaseChildren()
3564 frame.CustomColorFrame:Release()
3565 MDT:MakeCustomColorFrame(frame)
3566 MDT:OpenCustomColorsDialog()
3567 end)
3568 frame.CustomColorFrame:AddChild(frame.CustomColorFrame.ColorSlider)
3569
3570 --Loop to create as many colorpickers as requested limited by db.colorPaletteInfo.numberCustomColors
3571 local ColorPicker = {}
3572 for i= 1,db.colorPaletteInfo.numberCustomColors do
3573 ColorPicker[i] = AceGUI:Create("ColorPicker")
3574 if db.colorPaletteInfo.customPaletteValues[i] then
3575 ColorPicker[i]:SetColor(db.colorPaletteInfo.customPaletteValues[i][1], db.colorPaletteInfo.customPaletteValues[i][2], db.colorPaletteInfo.customPaletteValues[i][3])
3576 else
3577 db.colorPaletteInfo.customPaletteValues[i] = {1,1,1}
3578 ColorPicker[i]:SetColor(db.colorPaletteInfo.customPaletteValues[i][1], db.colorPaletteInfo.customPaletteValues[i][2], db.colorPaletteInfo.customPaletteValues[i][3])
3579 end
3580 ColorPicker[i]:SetLabel(" "..i)
3581 ColorPicker[i]:SetRelativeWidth(0.25)
3582 ColorPicker[i]:SetHeight(15)
3583 ColorPicker[i]:SetCallback("OnValueConfirmed", function(widget, event, r, g, b)
3584 db.colorPaletteInfo.customPaletteValues[i] = {r,g,b}
3585 MDT:SetPresetColorPaletteInfo()
3586 MDT:ColorAllPulls()
3587 MDT:DrawAllHulls()
3588 end)
3589 frame.CustomColorFrame:AddChild(ColorPicker[i])
3590 end
3591 frame.CustomColorFrame:Hide()
3592end
3593
3594function MDT:MakeAutomaticColorsFrame(frame)
3595 frame.automaticColorsFrame = AceGUI:Create("Frame")
3596 frame.automaticColorsFrame:SetTitle(L["Automatic Coloring"])
3597 frame.automaticColorsFrame:SetWidth(240)
3598 frame.automaticColorsFrame:SetHeight(220)
3599 frame.automaticColorsFrame:EnableResize(false)
3600 frame.automaticColorsFrame:SetLayout("Flow")
3601
3602 frame.AutomaticColorsCheck = AceGUI:Create("CheckBox")
3603 frame.AutomaticColorsCheck:SetLabel(L["Automatically color pulls"])
3604 frame.AutomaticColorsCheck:SetValue(db.colorPaletteInfo.autoColoring)
3605 frame.AutomaticColorsCheck:SetCallback("OnValueChanged",function(widget,callbackName,value)
3606 db.colorPaletteInfo.autoColoring = value
3607 MDT:SetPresetColorPaletteInfo()
3608 frame.AutomaticColorsCheckSidePanel:SetValue(db.colorPaletteInfo.autoColoring)
3609 if value == true then
3610 frame.toggleForceColorBlindMode:SetDisabled(false)
3611 MDT:ColorAllPulls()
3612 MDT:DrawAllHulls()
3613 MDT.main_frame.AutomaticColorsCogwheel:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\helpIconRnbw")
3614 else
3615 frame.toggleForceColorBlindMode:SetDisabled(true)
3616 MDT.main_frame.AutomaticColorsCogwheel:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\helpIconGrey")
3617 end
3618 end)
3619 frame.automaticColorsFrame:AddChild(frame.AutomaticColorsCheck)
3620
3621 --Toggle local color blind mode
3622 frame.toggleForceColorBlindMode = AceGUI:Create("CheckBox")
3623 frame.toggleForceColorBlindMode:SetLabel(L["Local color blind mode"])
3624 frame.toggleForceColorBlindMode:SetValue(db.colorPaletteInfo.forceColorBlindMode)
3625 frame.toggleForceColorBlindMode:SetCallback("OnValueChanged",function(widget,callbackName,value)
3626 db.colorPaletteInfo.forceColorBlindMode = value
3627 MDT:SetPresetColorPaletteInfo()
3628 MDT:ColorAllPulls()
3629 MDT:DrawAllHulls()
3630 end)
3631 frame.automaticColorsFrame:AddChild(frame.toggleForceColorBlindMode)
3632
3633 frame.PaletteSelectDropdown = AceGUI:Create("Dropdown")
3634 frame.PaletteSelectDropdown:SetList(colorPaletteNames)
3635 frame.PaletteSelectDropdown:SetLabel(L["Choose preferred color palette"])
3636 frame.PaletteSelectDropdown:SetValue(db.colorPaletteInfo.colorPaletteIdx)
3637 frame.PaletteSelectDropdown:SetCallback("OnValueChanged", function(widget,callbackName,value)
3638 if value == 6 then
3639 db.colorPaletteInfo.colorPaletteIdx = value
3640 MDT:OpenCustomColorsDialog()
3641 else
3642 MDT.main_frame.automaticColorsFrame.CustomColorFrame:Hide()
3643 db.colorPaletteInfo.colorPaletteIdx = value
3644 end
3645 MDT:SetPresetColorPaletteInfo()
3646 MDT:ColorAllPulls()
3647 MDT:DrawAllHulls()
3648 end)
3649 frame.automaticColorsFrame:AddChild(frame.PaletteSelectDropdown)
3650
3651 -- The reason this button exists is to allow altering colorPaletteInfo of an imported preset
3652 -- Without the need to untoggle/toggle or swap back and forth in the PaletteSelectDropdown
3653 frame.button = AceGUI:Create("Button")
3654 frame.button:SetText(L["Apply to preset"])
3655 frame.button:SetCallback("OnClick", function(widget, callbackName)
3656 if not db.colorPaletteInfo.autoColoring then
3657 db.colorPaletteInfo.autoColoring = true
3658 frame.AutomaticColorsCheck:SetValue(db.colorPaletteInfo.autoColoring)
3659 frame.AutomaticColorsCheckSidePanel:SetValue(db.colorPaletteInfo.autoColoring)
3660 MDT.main_frame.AutomaticColorsCogwheel:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\helpIconRnbw")
3661 frame.toggleForceColorBlindMode:SetDisabled(false)
3662 end
3663 MDT:SetPresetColorPaletteInfo()
3664 MDT:ColorAllPulls()
3665 MDT:DrawAllHulls()
3666 end)
3667 frame.automaticColorsFrame:AddChild(frame.button)
3668
3669 frame.automaticColorsFrame:Hide()
3670end
3671
3672function MDT:MakePullSelectionButtons(frame)
3673 frame.PullButtonScrollGroup = AceGUI:Create("SimpleGroup")
3674 frame.PullButtonScrollGroup:SetWidth(248)
3675 frame.PullButtonScrollGroup:SetHeight(410)
3676 frame.PullButtonScrollGroup:SetPoint("TOPLEFT",frame.WidgetGroup.frame,"BOTTOMLEFT",-4,-32)
3677 frame.PullButtonScrollGroup:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,30)
3678 frame.PullButtonScrollGroup:SetLayout("Fill")
3679 frame.PullButtonScrollGroup.frame:SetFrameStrata(mainFrameStrata)
3680 if not frame.PullButtonScrollGroup.frame.SetBackdrop then
3681 Mixin(frame.PullButtonScrollGroup.frame, BackdropTemplateMixin)
3682 end
3683 frame.PullButtonScrollGroup.frame:SetBackdropColor(1,1,1,0)
3684 frame.PullButtonScrollGroup.frame:Show()
3685
3686 self:FixAceGUIShowHide(frame.PullButtonScrollGroup)
3687
3688 frame.pullButtonsScrollFrame = AceGUI:Create("ScrollFrame")
3689 frame.pullButtonsScrollFrame:SetLayout("Flow")
3690
3691 frame.PullButtonScrollGroup:AddChild(frame.pullButtonsScrollFrame)
3692
3693 frame.newPullButtons = {}
3694 --rightclick context menu
3695 frame.optionsDropDown = L_Create_UIDropDownMenu("PullButtonsOptionsDropDown", nil)
3696end
3697
3698
3699function MDT:PresetsAddPull(index, data, preset)
3700 preset = preset or self:GetCurrentPreset()
3701 if not data then data = {} end
3702 if index then
3703 tinsert(preset.value.pulls,index,data)
3704 else
3705 tinsert(preset.value.pulls,data)
3706 end
3707 self:EnsureDBTables()
3708end
3709
3710
3711---Merges a list of pulls and inserts them at a specified destination.
3712---
3713---@param pulls table List of all pull indices, that shall be merged (and deleted). If pulls
3714--- is a number, then the pull list is automatically generated from pulls
3715--- and destination.
3716---@param destination number The pull index, where the merged pull shall be inserted.
3717---
3718---@author Dradux
3719function MDT:PresetsMergePulls(pulls, destination)
3720 if type(pulls) == "number" then
3721 pulls = {pulls, destination}
3722 end
3723
3724 if not destination then
3725 destination = pulls[#pulls]
3726 end
3727
3728 local count_if = self.U.count_if
3729
3730 local newPull = {}
3731 local removed_pulls = {}
3732
3733 for _, pullIdx in ipairs(pulls) do
3734 local offset = count_if(removed_pulls, function(entry)
3735 return entry < pullIdx
3736 end)
3737
3738 local index = pullIdx - offset
3739 local pull = self:GetCurrentPreset().value.pulls[index]
3740
3741 for enemyIdx,clones in pairs(pull) do
3742 if string.match(enemyIdx, "^%d+$") then
3743 -- it's really an enemy index
3744 if tonumber(enemyIdx) then
3745 if not newPull[enemyIdx] then
3746 newPull[enemyIdx] = clones
3747 else
3748 for k,v in pairs(clones) do
3749 if newPull[enemyIdx][k] ~= nil then
3750 local newIndex = #newPull[enemyIdx] + 1
3751 newPull[enemyIdx][newIndex] = v
3752 else
3753 newPull[enemyIdx][k] = v
3754 end
3755
3756 end
3757 end
3758 end
3759 else
3760 -- it's another pull option like color
3761 local optionName = enemyIdx
3762 local optionValue = clones
3763 newPull[optionName] = optionValue
3764 end
3765 end
3766
3767 self:PresetsDeletePull(index)
3768 tinsert(removed_pulls, pullIdx)
3769 end
3770
3771 local offset = count_if(removed_pulls, function(entry)
3772 return entry < destination
3773 end)
3774
3775 local index = destination - offset
3776 self:PresetsAddPull(index, newPull)
3777 return index
3778end
3779
3780function MDT:PresetsDeletePull(p, preset)
3781 preset = preset or self:GetCurrentPreset()
3782 if p == preset.value.currentPull then
3783 preset.value.currentPull = math.max(p - 1, 1)
3784 end
3785 tremove(preset.value.pulls,p)
3786end
3787
3788function MDT:GetPulls(preset)
3789 preset = preset or self:GetCurrentPreset()
3790 return preset.value.pulls
3791end
3792
3793function MDT:GetPullsNum(preset)
3794 preset = preset or self:GetCurrentPreset()
3795 return table.getn(preset.value.pulls)
3796end
3797
3798function MDT:CopyObject(obj, seen)
3799 if type(obj) ~= 'table' then return obj end
3800 if seen and seen[obj] then return seen[obj] end
3801 local s = seen or {}
3802 local res = setmetatable({}, getmetatable(obj))
3803 s[obj] = res
3804 for k, v in pairs(obj) do res[self:CopyObject(k, s)] = self:CopyObject(v, s) end
3805 return res
3806end
3807
3808function MDT:PresetsSwapPulls(p1, p2)
3809 local p1copy = self:CopyObject(self:GetCurrentPreset().value.pulls[p1])
3810 local p2copy = self:CopyObject(self:GetCurrentPreset().value.pulls[p2])
3811 self:GetCurrentPreset().value.pulls[p1] = p2copy
3812 self:GetCurrentPreset().value.pulls[p2] = p1copy
3813end
3814
3815function MDT:SetMapSublevel(pull)
3816 --set map sublevel
3817 local shouldResetZoom = false
3818 local lastSubLevel
3819 for enemyIdx,clones in pairs(db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls[pull]) do
3820 if tonumber(enemyIdx) then
3821 for idx,cloneIdx in pairs(clones) do
3822 if MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][cloneIdx] then
3823 lastSubLevel = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][cloneIdx].sublevel
3824 end
3825 end
3826 end
3827 end
3828 if lastSubLevel then
3829 shouldResetZoom = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel ~= lastSubLevel
3830 db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel = lastSubLevel
3831 if shouldResetZoom then
3832 MDT:UpdateMap(true,true,true)
3833 end
3834 end
3835
3836 MDT:UpdateDungeonDropDown()
3837 if shouldResetZoom then MDT:ZoomMapToDefault() end
3838end
3839
3840function MDT:SetSelectionToPull(pull)
3841 --if pull is not specified set pull to last pull in preset (for adding new pulls)
3842 if not pull then
3843 local count = 0
3844 for k,v in pairs(MDT:GetCurrentPreset().value.pulls) do
3845 count = count + 1
3846 end
3847 pull = count
3848 end
3849
3850 --SaveCurrentPresetPull
3851 if type(pull) == "number" and pull > 0 then
3852 MDT:GetCurrentPreset().value.currentPull = pull
3853 MDT:GetCurrentPreset().value.selection = { pull }
3854 MDT:PickPullButton(pull)
3855
3856 MDT:DungeonEnemies_UpdateSelected(pull)
3857 elseif type(pull) == "table" then
3858 MDT:GetCurrentPreset().value.currentPull = pull[#pull]
3859 MDT:GetCurrentPreset().value.selection = pull
3860
3861 MDT:ClearPullButtonPicks()
3862 for _, pullIdx in ipairs(MDT:GetSelection()) do
3863 MDT:PickPullButton(pullIdx, true)
3864 MDT:DungeonEnemies_UpdateSelected(pullIdx)
3865 end
3866 end
3867end
3868
3869---UpdatePullButtonNPCData
3870---Updates the portraits display of a button to show which and how many npcs are selected
3871function MDT:UpdatePullButtonNPCData(idx)
3872 if db.devMode then return end
3873 local preset = MDT:GetCurrentPreset()
3874 local frame = MDT.main_frame.sidePanel
3875 local enemyTable = {}
3876 if preset.value.pulls[idx] then
3877 local enemyTableIdx = 0
3878 for enemyIdx,clones in pairs(preset.value.pulls[idx]) do
3879 if tonumber(enemyIdx) then
3880 --check if enemy exists, remove if not
3881 if MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx] then
3882 local incremented = false
3883 local npcId = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["id"]
3884 local name = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["name"]
3885 local creatureType = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["creatureType"]
3886 local level = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["level"]
3887 local baseHealth = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["health"]
3888 for k,cloneIdx in pairs(clones) do
3889 --check if clone exists, remove if not
3890 if MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][cloneIdx] then
3891 if self:IsCloneIncluded(enemyIdx,cloneIdx) then
3892 if not incremented then enemyTableIdx = enemyTableIdx + 1 incremented = true end
3893 if not enemyTable[enemyTableIdx] then enemyTable[enemyTableIdx] = {} end
3894 enemyTable[enemyTableIdx].quantity = enemyTable[enemyTableIdx].quantity or 0
3895 enemyTable[enemyTableIdx].npcId = npcId
3896 enemyTable[enemyTableIdx].count = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["count"]
3897 enemyTable[enemyTableIdx].teemingCount = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["teemingCount"]
3898 enemyTable[enemyTableIdx].displayId = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["displayId"]
3899 enemyTable[enemyTableIdx].quantity = enemyTable[enemyTableIdx].quantity + 1
3900 enemyTable[enemyTableIdx].name = name
3901 enemyTable[enemyTableIdx].level = level
3902 enemyTable[enemyTableIdx].creatureType = creatureType
3903 enemyTable[enemyTableIdx].baseHealth = baseHealth
3904 enemyTable[enemyTableIdx].ignoreFortified = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["ignoreFortified"]
3905 end
3906 end
3907 end
3908 end
3909 end
3910 end
3911 end
3912 frame.newPullButtons[idx]:SetNPCData(enemyTable)
3913
3914 if db.MDI.enabled and preset.mdi.beguiling == 13 then end
3915 --display reaping icon
3916 local pullForces = MDT:CountForces(idx,false)
3917 local totalForcesMax = MDT:IsCurrentPresetTeeming() and MDT.dungeonTotalCount[db.currentDungeonIdx].teeming or MDT.dungeonTotalCount[db.currentDungeonIdx].normal
3918 local currentPercent = pullForces/totalForcesMax
3919 local oldPullForces
3920 if idx == 1 then
3921 oldPullForces = 0
3922 else
3923 oldPullForces = MDT:CountForces(idx-1,false)
3924 end
3925 local oldPercent = oldPullForces/totalForcesMax
3926 if (math.floor(currentPercent/0.2)>math.floor(oldPercent/0.2)) and oldPercent<1 and db.MDI.enabled and preset.mdi.beguiling == 13 then
3927 frame.newPullButtons[idx]:ShowReapingIcon(true,currentPercent,oldPercent)
3928 else
3929 frame.newPullButtons[idx]:ShowReapingIcon(false,currentPercent,oldPercent)
3930 end
3931 --prideful icon
3932 if (math.floor(currentPercent/0.2)>math.floor(oldPercent/0.2)) and oldPercent<1 and db.currentSeason == 5 then
3933 frame.newPullButtons[idx]:ShowPridefulIcon(true,currentPercent,oldPercent)
3934 else
3935 frame.newPullButtons[idx]:ShowPridefulIcon(false,currentPercent,oldPercent)
3936 end
3937end
3938
3939---ReloadPullButtons
3940---Reloads all pull buttons in the scroll frame
3941function MDT:ReloadPullButtons()
3942 local frame = MDT.main_frame.sidePanel
3943 if not frame.pullButtonsScrollFrame then return end
3944 local preset = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]]
3945 --store scroll value
3946 local oldScrollValue = frame.pullButtonsScrollFrame.localstatus.scrollvalue
3947 --first release all children of the scroll frame
3948 frame.pullButtonsScrollFrame:ReleaseChildren()
3949 local maxPulls = 0
3950 for k,v in pairs(preset.value.pulls) do
3951 maxPulls = maxPulls + 1
3952 end
3953 --add new children to the scrollFrame, the frames are from the widget pool so no memory is wasted
3954 local idx = 0
3955 for k,pull in ipairs(preset.value.pulls) do
3956 idx = idx+1
3957 frame.newPullButtons[idx] = AceGUI:Create("MDTPullButton")
3958 frame.newPullButtons[idx]:SetMaxPulls(maxPulls)
3959 frame.newPullButtons[idx]:SetIndex(idx)
3960 MDT:UpdatePullButtonNPCData(idx)
3961 frame.newPullButtons[idx]:Initialize()
3962 frame.newPullButtons[idx]:Enable()
3963 frame.pullButtonsScrollFrame:AddChild(frame.newPullButtons[idx])
3964 end
3965 --add the "new pull" button
3966 frame.newPullButton = AceGUI:Create("MDTNewPullButton")
3967 frame.newPullButton:Initialize()
3968 frame.newPullButton:Enable()
3969 frame.pullButtonsScrollFrame:AddChild(frame.newPullButton)
3970 --set the scroll value back to the old value
3971 frame.pullButtonsScrollFrame.scrollframe.obj:SetScroll(oldScrollValue)
3972 frame.pullButtonsScrollFrame.scrollframe.obj:FixScroll()
3973 if self:GetCurrentPreset().value.currentPull then
3974 self:PickPullButton(self:GetCurrentPreset().value.currentPull)
3975 end
3976end
3977
3978---ClearPullButtonPicks
3979---Deselects all pull buttons
3980function MDT:ClearPullButtonPicks()
3981 local frame = MDT.main_frame.sidePanel
3982 for k,v in pairs(frame.newPullButtons) do
3983 v:ClearPick()
3984 end
3985end
3986
3987---PickPullButton
3988---Selects the current pull button and deselects all other buttons
3989function MDT:PickPullButton(idx, keepPicked)
3990 if db.devMode then return end
3991
3992 if not keepPicked then
3993 MDT:ClearPullButtonPicks()
3994 end
3995 local frame = MDT.main_frame.sidePanel
3996 frame.newPullButtons[idx]:Pick()
3997end
3998
3999---AddPull
4000---Creates a new pull in the current preset and calls ReloadPullButtons to reflect the change in the scrollframe
4001function MDT:AddPull(index)
4002 MDT:PresetsAddPull(index)
4003 MDT:ReloadPullButtons()
4004 MDT:SetSelectionToPull(index)
4005 MDT:ColorPull()
4006 MDT:DrawAllHulls()
4007end
4008
4009function MDT:SetAutomaticColor(index)
4010 --if not db.colorPaletteInfo.autoColoring then return end
4011
4012 local H = (index - 1) * 360 / 12 + 120 --db.automaticColorsNum
4013 --if db.alternatingColors and index % 2 == 0 then
4014 -- H = H + 180
4015 --end
4016
4017 local V = 1--0.5451
4018 --if db.brightColors then V = 1 end
4019
4020 local r, g, b = self:HSVtoRGB(H, 0.7554, V)
4021
4022 --self:DungeonEnemies_SetPullColor(index, r, g, b)
4023 --self:UpdatePullButtonColor(index, r, g, b)
4024 --self:DungeonEnemies_UpdateBlipColors(index, r, g, b)
4025 --if self.liveSessionActive and self:GetCurrentPreset().uid == self.livePresetUID then
4026 -- self:LiveSession_QueueColorUpdate()
4027 --end
4028end
4029
4030function MDT:UpdateAutomaticColors(index)
4031 if not db.colorPaletteInfo.autoColoring then return end
4032 for i = index or 1, self:GetPullsNum() do
4033 self:SetAutomaticColor(i)
4034 end
4035end
4036
4037---Clears all the npcs out of a pull
4038function MDT:ClearPull(index)
4039 table.wipe(db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls[index])
4040 MDT:EnsureDBTables()
4041 MDT:ReloadPullButtons()
4042 MDT:SetSelectionToPull(index)
4043 MDT:ColorPull()
4044 MDT:DrawAllHulls()
4045 --MDT:SetAutomaticColor(index)
4046end
4047
4048---Moves the selected pull up
4049function MDT:MovePullUp(index)
4050 MDT:PresetsSwapPulls(index,index-1)
4051 MDT:ReloadPullButtons()
4052 MDT:SetSelectionToPull(index-1)
4053 MDT:ColorAllPulls(_, index-1)
4054 MDT:DrawAllHulls()
4055 --MDT:UpdateAutomaticColors(index - 1)
4056end
4057
4058---Moves the selected pull down
4059function MDT:MovePullDown(index)
4060 MDT:PresetsSwapPulls(index,index+1)
4061 MDT:ReloadPullButtons()
4062 MDT:SetSelectionToPull(index+1)
4063 MDT:ColorAllPulls(_, index)
4064 MDT:DrawAllHulls()
4065 --MDT:UpdateAutomaticColors(index)
4066end
4067
4068---Deletes the selected pull and makes sure that a pull will be selected afterwards
4069function MDT:DeletePull(index)
4070 local pulls = self:GetPulls()
4071 if #pulls == 1 then return end
4072 self:PresetsDeletePull(index)
4073 self:ReloadPullButtons()
4074 local pullCount = 0
4075 for k,v in pairs(pulls) do
4076 pullCount = pullCount + 1
4077 end
4078 if index>pullCount then index = pullCount end
4079 self:SetSelectionToPull(index)
4080 --self:UpdateAutomaticColors(index)
4081 self:ColorAllPulls(_, index-1)
4082 MDT:DrawAllHulls()
4083end
4084
4085---RenamePreset
4086function MDT:RenamePreset(renameText)
4087 db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].text = renameText
4088 MDT.main_frame.RenameFrame:Hide()
4089 MDT:UpdatePresetDropDown()
4090end
4091
4092---GetFirstNotSelectedPullButton
4093function MDT:GetFirstNotSelectedPullButton(start, direction)
4094 if not direction then
4095 direction = -1
4096 elseif direction == "UP" then
4097 direction = -1
4098 elseif direction == "DOWN" then
4099 direction = 1
4100 end
4101
4102 local pullIdx = start
4103 while MDT.U.contains(MDT:GetCurrentPreset().value.selection, pullIdx)
4104 and MDT.U.isInRange(pullIdx, 1, #MDT:GetCurrentPreset().value.pulls) do
4105 pullIdx = pullIdx + direction
4106 end
4107
4108 if not MDT.U.isInRange(pullIdx, 1, #MDT:GetCurrentPreset().value.pulls) then
4109 return
4110 end
4111
4112 return pullIdx
4113end
4114
4115function MDT:MakeRenameFrame(frame)
4116 frame.RenameFrame = AceGUI:Create("Frame")
4117 frame.RenameFrame:SetTitle(L["Rename Preset"])
4118 frame.RenameFrame:SetWidth(350)
4119 frame.RenameFrame:SetHeight(150)
4120 frame.RenameFrame:EnableResize(false)
4121 frame.RenameFrame:SetLayout("Flow")
4122 frame.RenameFrame:SetCallback("OnClose", function(widget)
4123
4124 end)
4125 frame.RenameFrame:Hide()
4126
4127 local renameText
4128 frame.RenameFrame.Editbox = AceGUI:Create("EditBox")
4129 frame.RenameFrame.Editbox:SetLabel(L["Preset Name"]..":")
4130 frame.RenameFrame.Editbox:SetWidth(200)
4131 frame.RenameFrame.Editbox:SetCallback("OnEnterPressed", function(...)
4132 local widget, event, text = ...
4133 --check if name is valid, block button if so, unblock if valid
4134 if MDT:SanitizePresetName(text) then
4135 frame.RenameFrame.PresetRenameLabel:SetText(nil)
4136 frame.RenameFrame.RenameButton:SetDisabled(false)
4137 frame.RenameFrame.RenameButton.text:SetTextColor(1,0.8196,0)
4138 renameText = text
4139 else
4140 frame.RenameFrame.PresetRenameLabel:SetText(string.format(L["Cannot rename preset to '%s'"],text))
4141 frame.RenameFrame.RenameButton:SetDisabled(true)
4142 frame.RenameFrame.RenameButton.text:SetTextColor(0.5,0.5,0.5)
4143 renameText = nil
4144 end
4145 frame.presetCreationFrame:DoLayout()
4146 end)
4147
4148 frame.RenameFrame:AddChild(frame.RenameFrame.Editbox)
4149
4150 frame.RenameFrame.RenameButton = AceGUI:Create("Button")
4151 frame.RenameFrame.RenameButton:SetText(L["Rename"])
4152 frame.RenameFrame.RenameButton:SetWidth(100)
4153 frame.RenameFrame.RenameButton:SetCallback("OnClick",function() MDT:RenamePreset(renameText) end)
4154 frame.RenameFrame:AddChild(frame.RenameFrame.RenameButton)
4155
4156 frame.RenameFrame.PresetRenameLabel = AceGUI:Create("Label")
4157 frame.RenameFrame.PresetRenameLabel:SetText(nil)
4158 frame.RenameFrame.PresetRenameLabel:SetWidth(390)
4159 frame.RenameFrame.PresetRenameLabel:SetColor(1,0,0)
4160 frame.RenameFrame:AddChild(frame.RenameFrame.PresetRenameLabel)
4161
4162end
4163
4164
4165---MakeExportFrame
4166---Creates the frame used to export presets to a string which can be uploaded to text sharing websites like pastebin
4167function MDT:MakeExportFrame(frame)
4168 frame.ExportFrame = AceGUI:Create("Frame")
4169 frame.ExportFrame:SetTitle(L["Preset Export"])
4170 frame.ExportFrame:SetWidth(600)
4171 frame.ExportFrame:SetHeight(400)
4172 frame.ExportFrame:EnableResize(false)
4173 frame.ExportFrame:SetLayout("Flow")
4174 frame.ExportFrame:SetCallback("OnClose", function(widget)
4175
4176 end)
4177
4178 frame.ExportFrameEditbox = AceGUI:Create("MultiLineEditBox")
4179 frame.ExportFrameEditbox:SetWidth(600)
4180 frame.ExportFrameEditbox:DisableButton(true)
4181 frame.ExportFrameEditbox:SetNumLines(20)
4182 frame.ExportFrameEditbox:SetCallback("OnEnterPressed", function(widget, event, text)
4183
4184 end)
4185 frame.ExportFrame:AddChild(frame.ExportFrameEditbox)
4186 --frame.presetCreationFrame:SetStatusText("AceGUI-3.0 Example Container Frame")
4187 frame.ExportFrame:Hide()
4188end
4189
4190
4191---MakeDeleteConfirmationFrame
4192---Creates the delete confirmation dialog that pops up when a user wants to delete a preset
4193function MDT:MakeDeleteConfirmationFrame(frame)
4194 frame.DeleteConfirmationFrame = AceGUI:Create("Frame")
4195 frame.DeleteConfirmationFrame:SetTitle(L["Delete Preset"])
4196 frame.DeleteConfirmationFrame:SetWidth(250)
4197 frame.DeleteConfirmationFrame:SetHeight(120)
4198 frame.DeleteConfirmationFrame:EnableResize(false)
4199 frame.DeleteConfirmationFrame:SetLayout("Flow")
4200 frame.DeleteConfirmationFrame:SetCallback("OnClose", function(widget)
4201
4202 end)
4203
4204 frame.DeleteConfirmationFrame.label = AceGUI:Create("Label")
4205 frame.DeleteConfirmationFrame.label:SetWidth(390)
4206 frame.DeleteConfirmationFrame.label:SetHeight(10)
4207 --frame.DeleteConfirmationFrame.label:SetColor(1,0,0)
4208 frame.DeleteConfirmationFrame:AddChild(frame.DeleteConfirmationFrame.label)
4209
4210 frame.DeleteConfirmationFrame.OkayButton = AceGUI:Create("Button")
4211 frame.DeleteConfirmationFrame.OkayButton:SetText(L["Delete"])
4212 frame.DeleteConfirmationFrame.OkayButton:SetWidth(100)
4213 frame.DeleteConfirmationFrame.OkayButton:SetCallback("OnClick",function()
4214 MDT:DeletePreset(db.currentPreset[db.currentDungeonIdx])
4215 frame.DeleteConfirmationFrame:Hide()
4216 end)
4217 frame.DeleteConfirmationFrame.CancelButton = AceGUI:Create("Button")
4218 frame.DeleteConfirmationFrame.CancelButton:SetText(L["Cancel"])
4219 frame.DeleteConfirmationFrame.CancelButton:SetWidth(100)
4220 frame.DeleteConfirmationFrame.CancelButton:SetCallback("OnClick",function()
4221 frame.DeleteConfirmationFrame:Hide()
4222 end)
4223
4224 frame.DeleteConfirmationFrame:AddChild(frame.DeleteConfirmationFrame.OkayButton)
4225 frame.DeleteConfirmationFrame:AddChild(frame.DeleteConfirmationFrame.CancelButton)
4226 frame.DeleteConfirmationFrame:Hide()
4227
4228end
4229
4230
4231---MakeClearConfirmationFrame
4232---Creates the clear confirmation dialog that pops up when a user wants to clear a preset
4233function MDT:MakeClearConfirmationFrame(frame)
4234 frame.ClearConfirmationFrame = AceGUI:Create("Frame")
4235 frame.ClearConfirmationFrame:SetTitle(L["Reset Preset"])
4236 frame.ClearConfirmationFrame:SetWidth(250)
4237 frame.ClearConfirmationFrame:SetHeight(120)
4238 frame.ClearConfirmationFrame:EnableResize(false)
4239 frame.ClearConfirmationFrame:SetLayout("Flow")
4240 frame.ClearConfirmationFrame:SetCallback("OnClose", function(widget)
4241
4242 end)
4243
4244 frame.ClearConfirmationFrame.label = AceGUI:Create("Label")
4245 frame.ClearConfirmationFrame.label:SetWidth(390)
4246 frame.ClearConfirmationFrame.label:SetHeight(10)
4247 --frame.DeleteConfirmationFrame.label:SetColor(1,0,0)
4248 frame.ClearConfirmationFrame:AddChild(frame.ClearConfirmationFrame.label)
4249
4250 frame.ClearConfirmationFrame.OkayButton = AceGUI:Create("Button")
4251 frame.ClearConfirmationFrame.OkayButton:SetText(L["Reset"])
4252 frame.ClearConfirmationFrame.OkayButton:SetWidth(100)
4253 frame.ClearConfirmationFrame.OkayButton:SetCallback("OnClick",function()
4254 self:ClearPreset(self:GetCurrentPreset())
4255 if self.liveSessionActive and self:GetCurrentPreset().uid == self.livePresetUID then MDT:LiveSession_SendCommand("clear") end
4256 frame.ClearConfirmationFrame:Hide()
4257 end)
4258 frame.ClearConfirmationFrame.CancelButton = AceGUI:Create("Button")
4259 frame.ClearConfirmationFrame.CancelButton:SetText(L["Cancel"])
4260 frame.ClearConfirmationFrame.CancelButton:SetWidth(100)
4261 frame.ClearConfirmationFrame.CancelButton:SetCallback("OnClick",function()
4262 frame.ClearConfirmationFrame:Hide()
4263 end)
4264
4265 frame.ClearConfirmationFrame:AddChild(frame.ClearConfirmationFrame.OkayButton)
4266 frame.ClearConfirmationFrame:AddChild(frame.ClearConfirmationFrame.CancelButton)
4267 frame.ClearConfirmationFrame:Hide()
4268
4269end
4270
4271---OpenConfirmationFrame
4272---Creates a generic dialog that pops up when a user wants needs confirmation for an action
4273function MDT:OpenConfirmationFrame(width, height, title, buttonText, prompt, callback, buttonText2, callback2)
4274 local f = MDT.main_frame.ConfirmationFrame
4275 if not f then
4276 MDT.main_frame.ConfirmationFrame = AceGUI:Create("Frame")
4277 f = MDT.main_frame.ConfirmationFrame
4278 f:EnableResize(false)
4279 f:SetLayout("Flow")
4280 f:SetCallback("OnClose", function(widget) end)
4281
4282 f.label = AceGUI:Create("Label")
4283 f.label:SetWidth(390)
4284 f.label:SetHeight(height-20)
4285 f:AddChild(f.label)
4286
4287 f.OkayButton = AceGUI:Create("Button")
4288 f.OkayButton:SetWidth(100)
4289 f:AddChild(f.OkayButton)
4290
4291 f.CancelButton = AceGUI:Create("Button")
4292 f.CancelButton:SetText(L["Cancel"])
4293 f.CancelButton:SetWidth(100)
4294 f.CancelButton:SetCallback("OnClick",function()
4295 MDT:HideAllDialogs()
4296 end)
4297 f:AddChild(f.CancelButton)
4298 end
4299 f:SetWidth(width or 250)
4300 f:SetHeight(height or 120)
4301 f:SetTitle(title)
4302 f.OkayButton:SetText(buttonText)
4303 f.OkayButton:SetCallback("OnClick",function()callback()
4304 MDT:HideAllDialogs() end)
4305 if buttonText2 then
4306 f.CancelButton:SetText(buttonText2) else
4307 f.CancelButton:SetText(L["Cancel"])
4308 end
4309 if callback2 then
4310 f.CancelButton:SetCallback("OnClick",function()callback2()
4311 MDT:HideAllDialogs() end)
4312 else
4313 f.CancelButton:SetCallback("OnClick",function()
4314 MDT:HideAllDialogs() end)
4315 end
4316 MDT:HideAllDialogs()
4317 f:ClearAllPoints()
4318 f:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50)
4319 f.label:SetText(prompt)
4320 f:Show()
4321end
4322
4323---CreateTutorialButton
4324---Creates the tutorial button and sets up the help plate frames
4325function MDT:CreateTutorialButton(parent)
4326 local scale = self:GetScale()
4327 local sidePanelHeight = MDT.main_frame.sidePanel.PullButtonScrollGroup.frame:GetHeight()
4328 local helpPlate = {
4329 FramePos = { x = 0, y = 0 },
4330 FrameSize = { width = sizex, height = sizey },
4331 [1] = { ButtonPos = { x = 205, y = 0 }, HighLightBox = { x = 0, y = 0, width = 200, height = 56 }, ToolTipDir = "RIGHT", ToolTipText = L["helpPlateDungeonSelect"] },
4332 [2] = { ButtonPos = { x = 205, y = -210*scale }, HighLightBox = { x = 0, y = -58, width = (sizex-6)*scale, height = (sizey*scale)-58 }, ToolTipDir = "RIGHT", ToolTipText = string.format(L["helpPlateNPC"],"\n","\n") },
4333 [3] = { ButtonPos = { x = 900*scale, y = 0*scale }, HighLightBox = { x = 838*scale, y = 30, width = 251, height = 115 }, ToolTipDir = "LEFT", ToolTipText = L["helpPlatePresets"] },
4334 [4] = { ButtonPos = { x = 900*scale, y = -87*scale }, HighLightBox = { x = 838*scale, y = 30-115, width = 251, height = 102 }, ToolTipDir = "LEFT", ToolTipText = L["helpPlateDungeon"] },
4335 [5] = { ButtonPos = { x = 900*scale, y = -(115+102*scale) }, HighLightBox = { x = 838*scale, y = (30-(115+102)), width = 251, height = (sidePanelHeight)+43 }, ToolTipDir = "LEFT", ToolTipText = string.format(L["helpPlatePulls"],"\n") },
4336 }
4337 if not parent.HelpButton then
4338 parent.HelpButton = CreateFrame("Button","MDTMainHelpPlateButton",parent,"MainHelpPlateButton")
4339 parent.HelpButton:ClearAllPoints()
4340 parent.HelpButton:SetPoint("TOPLEFT",parent,"TOPLEFT",0,48)
4341 parent.HelpButton:SetScale(0.8)
4342 parent.HelpButton:SetFrameStrata(mainFrameStrata)
4343 parent.HelpButton:SetFrameLevel(6)
4344 parent.HelpButton:Hide()
4345 --hook to make button hide
4346 local originalHide = parent.Hide
4347 function parent:Hide(...)
4348 parent.HelpButton:Hide()
4349 return originalHide(self, ...)
4350 end
4351 local function TutorialButtonOnHide(self)
4352 HelpPlate_Hide(true)
4353 end
4354 parent.HelpButton:SetScript("OnHide",TutorialButtonOnHide)
4355 end
4356 local function TutorialButtonOnClick(self)
4357 if not HelpPlate_IsShowing(helpPlate) then
4358 HelpPlate_Show(helpPlate, MDT.main_frame, self)
4359 else
4360 HelpPlate_Hide(true)
4361 end
4362 end
4363 parent.HelpButton:SetScript("OnClick",TutorialButtonOnClick)
4364end
4365
4366---RegisterOptions
4367---Register the options of the addon to the blizzard options
4368function MDT:RegisterOptions()
4369 MDT.blizzardOptionsMenuTable = {
4370 name = "Mythic Dungeon Tools",
4371 type = 'group',
4372 args = {
4373 --[[
4374 language = {
4375 type = 'select',
4376 style = 'dropdown',
4377 name = "Language",
4378 desc = "Sets the Language of the AddOn. Requires Reload to take effect",
4379 values = {
4380 [1] = "English",
4381 [2] = "Deutsch",
4382 [3] = "Español (esES)",
4383 [4] = "Español (esMX)",
4384 [5] = "Français",
4385 [6] = "Italiano",
4386 [7] = "Português Brasileiro",
4387 [8] = "Русский",
4388 [9] = "한국어",
4389 [10] = "简体中文 (zhCN)",
4390 [11] = "國語 (zhTW)",
4391 },
4392 get = function() return db.language end,
4393 set = function(_, newValue)
4394 db.language = newValue
4395 end,
4396 },
4397 ]]
4398 enable = {
4399 type = 'toggle',
4400 name = L["Enable Minimap Button"],
4401 desc = L["If the Minimap Button is enabled"],
4402 get = function() return not db.minimap.hide end,
4403 set = function(_, newValue)
4404 db.minimap.hide = not newValue
4405 if not db.minimap.hide then
4406 icon:Show("MythicDungeonTools")
4407 else
4408 icon:Hide("MythicDungeonTools")
4409 end
4410 end,
4411 order = 1,
4412 width = "full",
4413 },
4414 tooltipSelect ={
4415 type = 'select',
4416 name = L["Choose NPC tooltip position"],
4417 values = {
4418 [1] = L["Next to the NPC"],
4419 [2] = L["In the bottom right corner"],
4420 },
4421 get = function() return db.tooltipInCorner and 2 or 1 end,
4422 set = function(_,newValue)
4423 if newValue == 1 then db.tooltipInCorner = false end
4424 if newValue == 2 then db.tooltipInCorner = true end
4425 end,
4426 style = 'dropdown',
4427 },
4428 enemyForcesFormat = {
4429 type = "select",
4430 name = L["Choose Enemy Forces Format"],
4431 values = {
4432 [1] = L["Forces only: 5/200"],
4433 [2] = L["Forces+%: 5/200 (2.5%)"],
4434 },
4435 get = function() return db.enemyForcesFormat end,
4436 set = function(_,newValue) db.enemyForcesFormat = newValue end,
4437 style = "dropdown",
4438 },
4439 enemyStyle = {
4440 type = "select",
4441 name = L["Choose Enemy Style. Requires Reload"],
4442 values = {
4443 [1] = L["Portrait"],
4444 [2] = L["Plain Texture"],
4445 },
4446 get = function() return db.enemyStyle end,
4447 set = function(_,newValue) db.enemyStyle = newValue end,
4448 style = "dropdown",
4449 },
4450 }
4451 }
4452 LibStub("AceConfigRegistry-3.0"):RegisterOptionsTable("MythicDungeonTools", MDT.blizzardOptionsMenuTable)
4453 self.blizzardOptionsMenu = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("MythicDungeonTools", "MythicDungeonTools")
4454end
4455
4456function MDT:Round(number, decimals)
4457 return (("%%.%df"):format(decimals)):format(number)
4458end
4459
4460function MDT:RGBToHex(r, g, b)
4461 r = r*255
4462 g = g*255
4463 b = b*255
4464 return ("%.2x%.2x%.2x"):format(r, g, b)
4465end
4466
4467
4468function MDT:HexToRGB(rgb)
4469 if string.len(rgb) == 6 then
4470 local r, g, b
4471 r, g, b = tonumber('0x'..strsub(rgb, 0, 2)), tonumber('0x'..strsub(rgb, 3, 4)), tonumber('0x'..strsub(rgb, 5, 6))
4472 if not r then r = 0 else r = r/255 end
4473 if not g then g = 0 else g = g/255 end
4474 if not b then b = 0 else b = b/255 end
4475 return r,g,b
4476 else
4477 return
4478 end
4479end
4480
4481---https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB_alternative
4482function MDT:HSVtoRGB(H, S, V)
4483 H = H % 361
4484
4485 local function f(n)
4486 k = (n + H/60) % 6
4487 return V - V * S * math.max(math.min(k, 4 - k, 1), 0)
4488 end
4489
4490 return f(5), f(3), f(1)
4491end
4492
4493function MDT:DeepCopy(orig)
4494 local orig_type = type(orig)
4495 local copy
4496 if orig_type == 'table' then
4497 copy = {}
4498 for orig_key, orig_value in next, orig, nil do
4499 copy[MDT:DeepCopy(orig_key)] = MDT:DeepCopy(orig_value)
4500 end
4501 setmetatable(copy, MDT:DeepCopy(getmetatable(orig)))
4502 else -- number, string, boolean, etc
4503 copy = orig
4504 end
4505 return copy
4506end
4507
4508---scale if preset comes from live session
4509function MDT:StorePresetObject(obj, ignoreScale, preset)
4510 --adjust scale
4511 if not ignoreScale then
4512 local scale = self:GetScale()
4513 if obj.n then
4514 obj.d[1] = obj.d[1]*(1/scale)
4515 obj.d[2] = obj.d[2]*(1/scale)
4516 else
4517 for idx,coord in pairs(obj.l) do
4518 obj.l[idx] = self:Round(obj.l[idx]*(1/scale),1)
4519 end
4520 end
4521 end
4522 preset = preset or self:GetCurrentPreset()
4523 preset.objects = preset.objects or {}
4524 --we insert the object infront of the first hidden oject
4525 local pos = 1
4526 for k,v in ipairs(preset.objects) do
4527 pos = pos + 1
4528 if v.d[4]==false then
4529 pos = pos - 1
4530 end
4531 end
4532 if pos>1 then
4533 tinsert(preset.objects,pos,self:DeepCopy(obj))
4534 else
4535 tinsert(preset.objects,self:DeepCopy(obj))
4536 end
4537end
4538
4539---excluding notes, these are handled in OverrideScrollFrameScripts
4540function MDT:UpdatePresetObjectOffsets(idx, x, y, preset, silent)
4541 --adjust coords to scale
4542 local scale = self:GetScale()
4543 x = self:Round(x*(1/scale),1)
4544 y = self:Round(y*(1/scale),1)
4545 preset = preset or self:GetCurrentPreset()
4546 for objectIndex,obj in pairs(preset.objects) do
4547 if objectIndex == idx then
4548 for coordIdx,coord in pairs(obj.l) do
4549 if coordIdx%2==1 then
4550 obj.l[coordIdx] = coord-x
4551 else
4552 obj.l[coordIdx] = coord-y
4553 end
4554 end
4555 end
4556 end
4557 --redraw everything
4558 if not silent then self:DrawAllPresetObjects() end
4559end
4560
4561---Draws all Preset objects on the map canvas/sublevel
4562function MDT:DrawAllPresetObjects()
4563 self:ReleaseAllActiveTextures()
4564 local scale = self:GetScale()
4565 local currentPreset = self:GetCurrentPreset()
4566 local currentSublevel = self:GetCurrentSubLevel()
4567 currentPreset.objects = currentPreset.objects or {}
4568 for objectIndex,obj in pairs(currentPreset.objects) do
4569 self:DrawPresetObject(obj,objectIndex,scale,currentPreset,currentSublevel)
4570 end
4571end
4572
4573---Draws specific preset object
4574function MDT:DrawPresetObject(obj, objectIndex, scale, currentPreset, currentSublevel)
4575 if not objectIndex then
4576 for oIndex,o in pairs(currentPreset.objects) do
4577 if o == obj then
4578 objectIndex = oIndex
4579 break
4580 end
4581 end
4582 end
4583 --d: size,lineFactor,sublevel,shown,colorstring,drawLayer,[smooth]
4584 --l: x1,y1,x2,y2,...
4585 local color = {}
4586 if obj.d[3] == currentSublevel and obj.d[4] then
4587 if obj.n then
4588 local x = obj.d[1]*scale
4589 local y = obj.d[2]*scale
4590 local text = obj.d[5]
4591 self:DrawNote(x,y,text,objectIndex)
4592 else
4593 obj.d[1] = obj.d[1] or 5
4594 color.r,color.g,color.b = self:HexToRGB(obj.d[5])
4595 --lines
4596 local x1,y1,x2,y2
4597 local lastx,lasty
4598 for _,coord in pairs(obj.l) do
4599 if not x1 then x1 = coord
4600 elseif not y1 then y1 = coord
4601 elseif not x2 then
4602 x2 = coord
4603 lastx = coord
4604 elseif not y2 then
4605 y2 = coord
4606 lasty = coord
4607 end
4608 if x1 and y1 and x2 and y2 then
4609 x1 = x1*scale
4610 x2 = x2*scale
4611 y1 = y1*scale
4612 y2 = y2*scale
4613 self:DrawLine(x1,y1,x2,y2,obj.d[1]*0.3*scale,color,obj.d[7],nil,obj.d[6],obj.d[2],nil,objectIndex)
4614 --circles if smooth
4615 if obj.d[7] then
4616 self:DrawCircle(x1,y1,obj.d[1]*0.3*scale,color,nil,obj.d[6],nil,objectIndex)
4617 self:DrawCircle(x2,y2,obj.d[1]*0.3*scale,color,nil,obj.d[6],nil,objectIndex)
4618
4619 end
4620 x1,y1,x2,y2 = nil,nil,nil,nil
4621 end
4622 end
4623 --triangle
4624 if obj.t and lastx and lasty then
4625 lastx = lastx*scale
4626 lasty = lasty*scale
4627 self:DrawTriangle(lastx,lasty,obj.t[1],obj.d[1]*scale,color,nil,obj.d[6],nil,objectIndex)
4628 end
4629 --remove empty objects leftover from erasing
4630 if obj.l then
4631 local lineCount = 0
4632 for _,_ in pairs(obj.l) do
4633 lineCount = lineCount +1
4634 end
4635 if lineCount == 0 then
4636 currentPreset.objects[objectIndex] = nil
4637 end
4638 end
4639 end
4640 end
4641end
4642
4643---DeletePresetObjects
4644---Deletes objects from the current preset in the current sublevel
4645function MDT:DeletePresetObjects(preset, silent)
4646 preset = preset or self:GetCurrentPreset()
4647 if preset == self:GetCurrentPreset() then silent = false end
4648 local currentSublevel = self:GetCurrentSubLevel()
4649 for objectIndex,obj in pairs(preset.objects) do
4650 if obj.d[3] == currentSublevel then
4651 preset.objects[objectIndex] = nil
4652 end
4653 end
4654 if not silent then self:DrawAllPresetObjects() end
4655end
4656
4657---StepBack
4658---Undo the latest drawing
4659function MDT:PresetObjectStepBack(preset, silent)
4660 preset = preset or self:GetCurrentPreset()
4661 if preset == self:GetCurrentPreset() then silent = false end
4662 preset.objects = preset.objects or {}
4663 local length = 0
4664 for k,v in pairs(preset.objects) do
4665 length = length + 1
4666 end
4667 if length>0 then
4668 for i = length,1,-1 do
4669 if preset.objects[i] and preset.objects[i].d[4] then
4670 preset.objects[i].d[4] = false
4671 if not silent then self:DrawAllPresetObjects() end
4672 break
4673 end
4674 end
4675 end
4676end
4677
4678---StepForward
4679---Redo the latest drawing
4680function MDT:PresetObjectStepForward(preset, silent)
4681 preset = preset or MDT:GetCurrentPreset()
4682 if preset == self:GetCurrentPreset() then silent = false end
4683 preset.objects = preset.objects or {}
4684 local length = 0
4685 for k,v in ipairs(preset.objects) do
4686 length = length + 1
4687 end
4688 if length>0 then
4689 for i = 1,length do
4690 if preset.objects[i] and not preset.objects[i].d[4] then
4691 preset.objects[i].d[4] = true
4692 if not silent then self:DrawAllPresetObjects() end
4693 break
4694 end
4695 end
4696 end
4697end
4698
4699function MDT:FixAceGUIShowHide(widget, frame, isFrame, hideOnly)
4700 frame = frame or MDT.main_frame
4701 local originalShow,originalHide = frame.Show,frame.Hide
4702 if not isFrame then
4703 widget = widget.frame
4704 end
4705 function frame:Hide(...)
4706 widget:Hide()
4707 return originalHide(self, ...)
4708 end
4709 if hideOnly then return end
4710 function frame:Show(...)
4711 widget:Show()
4712 return originalShow(self, ...)
4713 end
4714end
4715
4716function MDT:GetCurrentAffixWeek()
4717 if not IsAddOnLoaded("Blizzard_ChallengesUI") then
4718 LoadAddOn("Blizzard_ChallengesUI")
4719 end
4720 C_MythicPlus.RequestCurrentAffixes()
4721 C_MythicPlus.RequestMapInfo()
4722 C_MythicPlus.RequestRewards()
4723 local affixIds = C_MythicPlus.GetCurrentAffixes() --table
4724 if not affixIds then return end
4725 if not affixIds[1] then return 1 end
4726 for week,affixes in ipairs(affixWeeks) do
4727 if affixes[1] == affixIds[2].id and affixes[2] == affixIds[3].id and affixes[3] == affixIds[1].id then
4728 return week
4729 end
4730 end
4731 return 1
4732end
4733
4734---PrintCurrentAffixes
4735---Helper function to print out current affixes with their ids and their names
4736function MDT:PrintCurrentAffixes()
4737 --run this once so blizz stuff is loaded
4738 MDT:GetCurrentAffixWeek()
4739 --https://www.wowhead.com/affixes
4740 local affixNames = {
4741 [1] =L["Overflowing"],
4742 [2] =L["Skittish"],
4743 [3] =L["Volcanic"],
4744 [4] =L["Necrotic"],
4745 [5] =L["Teeming"],
4746 [6] =L["Raging"],
4747 [7] =L["Bolstering"],
4748 [8] =L["Sanguine"],
4749 [9] =L["Tyrannical"],
4750 [10] =L["Fortified"],
4751 [11] =L["Bursting"],
4752 [12] =L["Grievous"],
4753 [13] =L["Explosive"],
4754 [14] =L["Quaking"],
4755 [15] =L["Relentless"],
4756 [16] =L["Infested"],
4757 [117] =L["Reaping"],
4758 [119] =L["Beguiling"],
4759 [120] =L["Awakened"],
4760 [121] =L["Prideful"],
4761 [122] =L["Inspiring"],
4762 [123] =L["Spiteful"],
4763 [124] =L["Storming"],
4764 }
4765 local affixIds = C_MythicPlus.GetCurrentAffixes()
4766 for idx,data in ipairs(affixIds) do
4767 print(data.id,affixNames[data.id])
4768 end
4769end
4770
4771---IsPlayerInGroup
4772---Checks if the players is in a group/raid and returns the type
4773function MDT:IsPlayerInGroup()
4774 local inGroup = (UnitInRaid("player") and "RAID") or (IsInGroup() and "PARTY")
4775 return inGroup
4776end
4777
4778function MDT:ResetMainFramePos(soft)
4779 --soft reset just redraws the window with existing coordinates from db
4780 local f = self.main_frame
4781 if not soft then
4782 db.nonFullscreenScale = 1
4783 db.maximized = false
4784 if not framesInitialized then initFrames() end
4785 f.maximizeButton:Minimize()
4786 db.xoffset = 0
4787 db.yoffset = -150
4788 db.anchorFrom = "TOP"
4789 db.anchorTo = "TOP"
4790 end
4791 f:ClearAllPoints()
4792 f:SetPoint(db.anchorTo, UIParent,db.anchorFrom, db.xoffset, db.yoffset)
4793end
4794
4795function MDT:DropIndicator()
4796 local indicator = MDT.main_frame.drop_indicator
4797 if not indicator then
4798 indicator = CreateFrame("Frame", "MDT_DropIndicator")
4799 indicator:SetHeight(4)
4800 indicator:SetFrameStrata("FULLSCREEN")
4801
4802 local texture = indicator:CreateTexture(nil, "FULLSCREEN")
4803 texture:SetBlendMode("ADD")
4804 texture:SetAllPoints(indicator)
4805 texture:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight")
4806
4807 local icon = indicator:CreateTexture(nil, "OVERLAY")
4808 icon:ClearAllPoints()
4809 icon:SetSize(16, 16)
4810 icon:SetPoint("CENTER", indicator)
4811
4812 indicator.icon = icon
4813 indicator.texture = texture
4814 MDT.main_frame.drop_indicator = indicator
4815
4816 indicator:Hide()
4817 end
4818
4819 return indicator
4820end
4821
4822function MDT:IsShown_DropIndicator()
4823 local indicator = MDT:DropIndicator()
4824 return indicator:IsShown()
4825end
4826
4827function MDT:Show_DropIndicator(target, pos)
4828 local indicator = MDT:DropIndicator()
4829 indicator:ClearAllPoints()
4830 if pos == "TOP" then
4831 indicator:SetPoint("BOTTOMLEFT", target.frame, "TOPLEFT", 0, -1)
4832 indicator:SetPoint("BOTTOMRIGHT", target.frame, "TOPRIGHT", 0, -1)
4833 indicator:Show()
4834 elseif pos == "BOTTOM" then
4835 indicator:SetPoint("TOPLEFT", target.frame, "BOTTOMLEFT", 0, 1)
4836 indicator:SetPoint("TOPRIGHT", target.frame, "BOTTOMRIGHT", 0, 1)
4837 indicator:Show()
4838 end
4839end
4840
4841function MDT:Hide_DropIndicator()
4842 local indicator = MDT:DropIndicator()
4843 indicator:Hide()
4844end
4845
4846function MDT:GetSelection()
4847 if not MDT:GetCurrentPreset().value.selection or #MDT:GetCurrentPreset().value.selection == 0 then
4848 MDT:GetCurrentPreset().value.selection = { MDT:GetCurrentPreset().value.currentPull }
4849 end
4850
4851 return MDT:GetCurrentPreset().value.selection
4852end
4853
4854function MDT:GetScrollingAmount(scrollFrame, pixelPerSecond)
4855 local viewheight = scrollFrame.frame.obj.content:GetHeight()
4856 return (pixelPerSecond / viewheight) * 1000
4857end
4858
4859function MDT:ScrollToPull(pullIdx)
4860 -- Get scroll frame
4861 local scrollFrame = MDT.main_frame.sidePanel.pullButtonsScrollFrame
4862 -- Get amount of total pulls plus the extra button "+ Add Pull"
4863 local pulls = #MDT:GetCurrentPreset().value.pulls + 1 or 1
4864 local percentage = pullIdx / pulls
4865 local value = percentage * 1000
4866 scrollFrame:SetScroll(value)
4867 scrollFrame:FixScroll()
4868end
4869
4870function MDT:CopyPullOptions(sourceIdx, destinationIdx)
4871 local preset = MDT:GetCurrentPreset()
4872 local pulls = preset.value.pulls
4873 local source = pulls[sourceIdx]
4874 local destination = pulls[destinationIdx]
4875
4876 if source and destination then
4877 for optionName, optionValue in pairs(source) do
4878 -- Assure, that it is an option and not an enemy index
4879 if not string.match(optionName, "^%d+$") then
4880 destination[optionName] = optionValue
4881 end
4882 end
4883 end
4884end
4885
4886function MDT:GetPullButton(pullIdx)
4887 local frame = MDT.main_frame.sidePanel
4888 return frame.newPullButtons[pullIdx]
4889end
4890
4891function MDT:UpdatePullButtonColor(pullIdx, r, g, b)
4892 local button = MDT:GetPullButton(pullIdx)
4893
4894 local function updateSwatch(t)
4895 for k,v in pairs(t) do
4896 if v.hasColorSwatch then
4897 v.r,v.g,v.b = r,g,b
4898 return
4899 end
4900 end
4901 end
4902
4903 button.color.r, button.color.g, button.color.b = r, g, b
4904 updateSwatch(button.menu)
4905 updateSwatch(button.multiselectMenu)
4906 button:UpdateColor()
4907end
4908
4909--/run MDT:ResetDataCache();
4910function MDT:ResetDataCache()
4911 db.dungeonEnemies = nil
4912 db.mapPOIs = nil
4913 ReloadUI()
4914end
4915
4916function MDT:HardReset()
4917 MythicDungeonToolsDB = nil
4918 ReloadUI()
4919end
4920
4921function initFrames()
4922 local main_frame = CreateFrame("frame", "MDTFrame", UIParent)
4923 tinsert(UISpecialFrames,"MDTFrame")
4924
4925 --cache dungeon data to not lose data during reloads
4926 if db.devMode then
4927 if db.dungeonEnemies then
4928 MDT.dungeonEnemies = db.dungeonEnemies
4929 else
4930 db.dungeonEnemies = MDT.dungeonEnemies
4931 end
4932 if db.mapPOIs then
4933 MDT.mapPOIs = db.mapPOIs
4934 else
4935 db.mapPOIs = MDT.mapPOIs
4936 end
4937 end
4938
4939 db.nonFullscreenScale = db.nonFullscreenScale or 1
4940 if not db.maximized then db.scale = db.nonFullscreenScale end
4941 main_frame:SetFrameStrata(mainFrameStrata)
4942 main_frame:SetFrameLevel(1)
4943 main_frame.background = main_frame:CreateTexture(nil, "BACKGROUND")
4944 main_frame.background:SetAllPoints()
4945 main_frame.background:SetDrawLayer(canvasDrawLayer, 1)
4946 main_frame.background:SetColorTexture(unpack(MDT.BackdropColor))
4947 main_frame.background:SetAlpha(0.2)
4948 main_frame:SetSize(sizex*db.scale, sizey*db.scale)
4949 main_frame:SetResizable(true)
4950 main_frame:SetMinResize(sizex*0.75,sizey*0.75)
4951 local _,_,fullscreenScale = MDT:GetFullScreenSizes()
4952 main_frame:SetMaxResize(sizex*fullscreenScale,sizey*fullscreenScale)
4953 MDT.main_frame = main_frame
4954
4955 main_frame.mainFrametex = main_frame:CreateTexture(nil, "BACKGROUND")
4956 main_frame.mainFrametex:SetAllPoints()
4957 main_frame.mainFrametex:SetDrawLayer(canvasDrawLayer, -5)
4958 main_frame.mainFrametex:SetColorTexture(unpack(MDT.BackdropColor))
4959
4960
4961 local version = GetAddOnMetadata(AddonName, "Version"):gsub("%.","")
4962 db.version = tonumber(version)
4963 -- Set frame position
4964 main_frame:ClearAllPoints()
4965 main_frame:SetPoint(db.anchorTo, UIParent,db.anchorFrom, db.xoffset, db.yoffset)
4966 main_frame.contextDropdown = L_Create_UIDropDownMenu("MDTContextDropDown", nil)
4967
4968 MDT:CheckCurrentZone(true)
4969 MDT:EnsureDBTables()
4970 MDT:MakeTopBottomTextures(main_frame)
4971 MDT:MakeMapTexture(main_frame)
4972 MDT:MakeSidePanel(main_frame)
4973 MDT:CreateMenu()
4974 MDT:MakePresetCreationFrame(main_frame)
4975 MDT:MakePresetImportFrame(main_frame)
4976 MDT:DungeonEnemies_CreateFramePools()
4977 --MDT:UpdateDungeonEnemies(main_frame)
4978 MDT:CreateDungeonSelectDropdown(main_frame)
4979 MDT:MakePullSelectionButtons(main_frame.sidePanel)
4980 MDT:MakeExportFrame(main_frame)
4981 MDT:MakeRenameFrame(main_frame)
4982 MDT:MakeDeleteConfirmationFrame(main_frame)
4983 MDT:MakeClearConfirmationFrame(main_frame)
4984 MDT:CreateTutorialButton(main_frame)
4985 MDT:POI_CreateFramePools()
4986 MDT:MakeChatPresetImportFrame(main_frame)
4987 MDT:MakeSendingStatusBar(main_frame)
4988 MDT:MakeAutomaticColorsFrame(main_frame)
4989 MDT:MakeCustomColorFrame(main_frame.automaticColorsFrame)
4990
4991 --devMode
4992 if db.devMode and MDT.CreateDevPanel then
4993 MDT:CreateDevPanel(MDT.main_frame)
4994 end
4995
4996 if not db.MDI.enabled then
4997 db.currentSeason = defaultSavedVars.global.currentSeason
4998 end
4999
5000 --ElvUI skinning
5001 local skinTooltip = function(tooltip)
5002 if IsAddOnLoaded("ElvUI") and ElvUI[1].Tooltip then
5003 local borderTextures = {"BorderBottom","BorderBottomLeft","BorderBottomRight","BorderLeft","BorderRight","BorderTop","BorderTopLeft","BorderTopRight"}
5004 for k,v in pairs(borderTextures) do
5005 tooltip[v]:Kill()
5006 end
5007 tooltip.Background:Kill()
5008 if not tooltip.SetBackdrop then
5009 Mixin(tooltip, BackdropTemplateMixin)
5010 end
5011 tooltip:HookScript("OnShow",function(self)
5012 if self:IsForbidden() then return end
5013 self:SetTemplate("Transparent", nil, true) --ignore updates
5014 local r, g, b = self:GetBackdropColor()
5015 self:SetBackdropColor(r, g, b, ElvUI[1].Tooltip.db.colorAlpha)
5016 end)
5017 if tooltip.String then tooltip.String:SetFont(tooltip.String:GetFont(),11) end
5018 if tooltip.topString then tooltip.topString:SetFont(tooltip.topString:GetFont(),11) end
5019 if tooltip.botString then tooltip.botString:SetFont(tooltip.botString:GetFont(),11) end
5020 end
5021 end
5022 --tooltip new
5023 do
5024 MDT.tooltip = CreateFrame("Frame", "MDTModelTooltip", UIParent, "TooltipBorderedFrameTemplate")
5025 local tooltip = MDT.tooltip
5026 tooltip:SetClampedToScreen(true)
5027 tooltip:SetFrameStrata("TOOLTIP")
5028 tooltip.mySizes ={x=290,y=120}
5029 tooltip:SetSize(tooltip.mySizes.x, tooltip.mySizes.y)
5030 tooltip.Model = CreateFrame("PlayerModel", nil, tooltip)
5031 tooltip.Model:SetFrameLevel(1)
5032 tooltip.Model:SetSize(100,100)
5033 tooltip.Model.fac = 0
5034 tooltip.Model:SetScript("OnUpdate",function (self,elapsed)
5035 self.fac = self.fac + 0.5
5036 if self.fac >= 360 then
5037 self.fac = 0
5038 end
5039 self:SetFacing(PI*2 / 360 * self.fac)
5040 end)
5041 tooltip.Model:SetPoint("TOPLEFT", tooltip, "TOPLEFT",7,-7)
5042 tooltip.String = tooltip:CreateFontString("MDTToolTipString")
5043 tooltip.String:SetFontObject("GameFontNormalSmall")
5044 tooltip.String:SetFont(tooltip.String:GetFont(),10)
5045 tooltip.String:SetTextColor(1, 1, 1, 1)
5046 tooltip.String:SetJustifyH("LEFT")
5047 --tooltip.String:SetJustifyV("CENTER")
5048 tooltip.String:SetWidth(tooltip:GetWidth())
5049 tooltip.String:SetHeight(90)
5050 tooltip.String:SetWidth(175)
5051 tooltip.String:SetText(" ")
5052 tooltip.String:SetPoint("TOPLEFT", tooltip, "TOPLEFT", 110, -10)
5053 tooltip.String:Show()
5054 skinTooltip(tooltip)
5055 end
5056
5057 --pullTooltip
5058 do
5059 MDT.pullTooltip = CreateFrame("Frame", "MDTPullTooltip", UIParent, "TooltipBorderedFrameTemplate")
5060 --MDT.pullTooltip:SetOwner(UIParent, "ANCHOR_NONE")
5061 local pullTT = MDT.pullTooltip
5062 MDT.pullTooltip:SetClampedToScreen(true)
5063 MDT.pullTooltip:SetFrameStrata("TOOLTIP")
5064 MDT.pullTooltip.myHeight = 160
5065 MDT.pullTooltip:SetSize(250, MDT.pullTooltip.myHeight)
5066 MDT.pullTooltip.Model = CreateFrame("PlayerModel", nil, MDT.pullTooltip)
5067 MDT.pullTooltip.Model:SetFrameLevel(1)
5068 MDT.pullTooltip.Model.fac = 0
5069 if true then
5070 MDT.pullTooltip.Model:SetScript("OnUpdate",function (self, elapsed)
5071 self.fac = self.fac + 0.5
5072 if self.fac >= 360 then
5073 self.fac = 0
5074 end
5075 self:SetFacing(PI*2 / 360 * self.fac)
5076 end)
5077 else
5078 MDT.pullTooltip.Model:SetPortraitZoom(1)
5079 MDT.pullTooltip.Model:SetFacing(PI*2 / 360 * 2)
5080 end
5081
5082 MDT.pullTooltip.Model:SetSize(110,110)
5083 MDT.pullTooltip.Model:SetPoint("TOPLEFT", MDT.pullTooltip, "TOPLEFT",7,-7)
5084
5085 MDT.pullTooltip.topString = MDT.pullTooltip:CreateFontString("MDTToolTipString")
5086 MDT.pullTooltip.topString:SetFontObject("GameFontNormalSmall")
5087 MDT.pullTooltip.topString:SetFont(MDT.pullTooltip.topString:GetFont(),10)
5088 MDT.pullTooltip.topString:SetTextColor(1, 1, 1, 1)
5089 MDT.pullTooltip.topString:SetJustifyH("LEFT")
5090 MDT.pullTooltip.topString:SetJustifyV("TOP")
5091 MDT.pullTooltip.topString:SetHeight(110)
5092 MDT.pullTooltip.topString:SetWidth(130)
5093 MDT.pullTooltip.topString:SetPoint("TOPLEFT", MDT.pullTooltip, "TOPLEFT", 110, -7)
5094 MDT.pullTooltip.topString:Hide()
5095
5096 local heading = MDT.pullTooltip:CreateTexture(nil, "TOOLTIP")
5097 heading:SetHeight(8)
5098 heading:SetPoint("LEFT", 12, -30)
5099 heading:SetPoint("RIGHT", MDT.pullTooltip, "RIGHT", -12, -30)
5100 heading:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
5101 heading:SetTexCoord(0.81, 0.94, 0.5, 1)
5102 heading:Show()
5103
5104 MDT.pullTooltip.botString = MDT.pullTooltip:CreateFontString("MDTToolTipString")
5105 local botString = MDT.pullTooltip.botString
5106 botString:SetFontObject("GameFontNormalSmall")
5107 botString:SetFont(MDT.pullTooltip.topString:GetFont(),10)
5108 botString:SetTextColor(1, 1, 1, 1)
5109 botString:SetJustifyH("TOP")
5110 botString:SetJustifyV("TOP")
5111 botString:SetHeight(23)
5112 botString:SetWidth(250)
5113 botString:SetPoint("TOPLEFT", heading, "LEFT", -12, -7)
5114 botString:Hide()
5115 skinTooltip(pullTT)
5116 end
5117
5118 MDT:initToolbar(main_frame)
5119 if db.toolbarExpanded then
5120 main_frame.toolbar.toggleButton:Click()
5121 end
5122
5123 --ping
5124 MDT.ping = CreateFrame("PlayerModel", nil, MDT.main_frame.mapPanelFrame)
5125 local ping = MDT.ping
5126 --ping:SetModel("interface/minimap/ping/minimapping.m2")
5127 ping:SetModel(120590)
5128 ping:SetPortraitZoom(1)
5129 ping:SetCamera(1)
5130 ping:SetFrameLevel(50)
5131 ping:SetFrameStrata("DIALOG")
5132 ping.mySize = 45
5133 ping:SetSize(ping.mySize,ping.mySize)
5134 ping:Hide()
5135
5136 --Set affix dropdown to preset week
5137 --gotta set the list here, as affixes are not ready to be retrieved yet on login
5138 main_frame.sidePanel.affixDropdown:UpdateAffixList()
5139 main_frame.sidePanel.affixDropdown:SetAffixWeek(MDT:GetCurrentPreset().week or (MDT:GetCurrentAffixWeek() or 1))
5140 MDT:UpdateToDungeon(db.currentDungeonIdx)
5141 main_frame:Hide()
5142
5143 --Maximize if needed
5144 if db.maximized then MDT:Maximize() end
5145
5146 if MDT:IsFrameOffScreen() then
5147 MDT:ResetMainFramePos()
5148 end
5149
5150 framesInitialized = true
5151end
5152
5153