Created
July 27, 2021 15:46
-
-
Save arcadepro/b82f28fdc0fcac0af9a05928a422671c to your computer and use it in GitHub Desktop.
MythicDungeonTools.lua
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Made by Nnoggie, 2017-2020 | |
local AddonName, MDT = ... | |
local L = MDT.L | |
local mainFrameStrata = "HIGH" | |
local canvasDrawLayer = "BORDER" | |
local 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 | |
local SetPortraitTextureFromCreatureDisplayID,MouseIsOver = SetPortraitTextureFromCreatureDisplayID,MouseIsOver | |
local sizex = 840 | |
local sizey = 555 | |
local mythicColor = "|cFFFFFFFF" | |
MDT.BackdropColor = { 0.058823399245739, 0.058823399245739, 0.058823399245739, 0.9} | |
local AceGUI = LibStub("AceGUI-3.0") | |
local db | |
local icon = LibStub("LibDBIcon-1.0") | |
local LibDD = LibStub:GetLibrary("LibUIDropDownMenu-4.0") | |
local LDB = LibStub("LibDataBroker-1.1"):NewDataObject("MythicDungeonTools", { | |
type = "data source", | |
text = "Mythic Dungeon Tools", | |
icon = "Interface\\AddOns\\"..AddonName.."\\Textures\\NnoggieMinimap", | |
OnClick = function(button,buttonPressed) | |
if buttonPressed == "RightButton" then | |
if db.minimap.lock then | |
icon:Unlock("MythicDungeonTools") | |
else | |
icon:Lock("MythicDungeonTools") | |
end | |
else | |
MDT:ShowInterface() | |
end | |
end, | |
OnTooltipShow = function(tooltip) | |
if not tooltip or not tooltip.AddLine then return end | |
tooltip:AddLine(mythicColor .."Mythic Dungeon Tools|r") | |
tooltip:AddLine(L["Click to toggle AddOn Window"]) | |
tooltip:AddLine(L["Right-click to lock Minimap Button"]) | |
end, | |
}) | |
SLASH_MYTHICDUNGEONTOOLS1 = "/mplus" | |
SLASH_MYTHICDUNGEONTOOLS2 = "/mdt" | |
SLASH_MYTHICDUNGEONTOOLS3 = "/mythicdungeontools" | |
BINDING_NAME_MDTTOGGLE = L["Toggle Window"] | |
BINDING_NAME_MDTNPC = L["New NPC at Cursor Position"] | |
BINDING_NAME_MDTWAYPOINT = L["New Patrol Waypoint at Cursor Position"] | |
function SlashCmdList.MYTHICDUNGEONTOOLS(cmd, editbox) | |
local rqst, arg = strsplit(' ', cmd) | |
if rqst == "devmode" then | |
MDT:ToggleDevMode() | |
elseif rqst == "reset" then | |
MDT:ResetMainFramePos() | |
elseif rqst == "dc" then | |
MDT:ToggleDataCollection() | |
elseif rqst == "hptrack" then | |
MDT:ToggleHealthTrack() | |
else | |
MDT:ShowInterface() | |
end | |
end | |
function MDT:GetLocaleIndex() | |
local localeToIndex = { | |
["enUS"] = 1, | |
["deDE"] = 2, | |
["esES"] = 3, | |
["esMX"] = 4, | |
["frFR"] = 5, | |
["itIT"] = 6, | |
["ptBR"] = 7, | |
["ruRU"] = 8, | |
["koKR"] = 9, | |
["zhCN"] = 10, | |
["zhTW"] = 11, | |
} | |
return localeToIndex[GetLocale()] or 1 | |
end | |
local initFrames | |
------------------------- | |
--- Saved Variables ---- | |
------------------------- | |
local defaultSavedVars = { | |
global = { | |
toolbarExpanded = true, | |
currentSeason = 6, | |
currentExpansion = 3, | |
scale = 1, | |
enemyForcesFormat = 2, | |
enemyStyle = 1, | |
currentDungeonIdx = 29, | |
currentDifficulty = 10, | |
xoffset = 0, | |
yoffset = -150, | |
defaultColor = "228b22", | |
anchorFrom = "TOP", | |
anchorTo = "TOP", | |
tooltipInCorner = false, | |
minimap = { | |
hide = false, | |
}, | |
toolbar ={ | |
color = {r=1,g=1,b=1,a=1}, | |
brushSize = 3, | |
}, | |
presets = {}, | |
currentPreset = {}, | |
dataCollectionActive = false, | |
colorPaletteInfo = { | |
autoColoring = true, | |
forceColorBlindMode = false, | |
colorPaletteIdx = 4, | |
customPaletteValues = {}, | |
numberCustomColors = 12, | |
}, | |
language = MDT:GetLocaleIndex(), | |
dungeonImport = {}, | |
}, | |
} | |
do | |
for i=1,37 do | |
defaultSavedVars.global.presets[i] = { | |
[1] = {text="Default",value={},colorPaletteInfo={autoColoring=true,colorPaletteIdx=4}}, | |
[2] = {text="<New Preset>",value=0}, | |
} | |
defaultSavedVars.global.currentPreset[i] = 1 | |
end | |
end | |
-- Init db | |
do | |
local frame = CreateFrame("Frame") | |
frame:RegisterEvent("ADDON_LOADED") | |
frame:RegisterEvent("GROUP_ROSTER_UPDATE") | |
frame:RegisterEvent("PLAYER_ENTERING_WORLD") | |
--TODO Register Affix Changed event | |
frame:SetScript("OnEvent", function(self, event, ...) | |
return MDT[event](self,...) | |
end) | |
function MDT.ADDON_LOADED(self, addon) | |
if addon == "MythicDungeonTools" then | |
db = LibStub("AceDB-3.0"):New("MythicDungeonToolsDB", defaultSavedVars).global | |
icon:Register("MythicDungeonTools", LDB, db.minimap) | |
if not db.minimap.hide then | |
icon:Show("MythicDungeonTools") | |
end | |
--if db.dataCollectionActive then MDT.DataCollection:Init() end | |
--fix db corruption | |
do | |
for _,presets in pairs(db.presets) do | |
for presetIdx,preset in pairs(presets) do | |
if presetIdx == 1 then | |
if preset.text ~= "Default" then | |
preset.text = "Default" | |
preset.value = {} | |
end | |
end | |
end | |
end | |
for k,v in pairs(db.currentPreset) do | |
if v <= 0 then db.currentPreset[k] = 1 end | |
end | |
end | |
--register AddOn Options | |
MDT:RegisterOptions() | |
self:UnregisterEvent("ADDON_LOADED") | |
end | |
end | |
local last = 0 | |
function MDT.GROUP_ROSTER_UPDATE(self, addon) | |
--check not more than once per second (blizzard event spam) | |
local now = GetTime() | |
if last < now - 1 then | |
if not MDT.main_frame then return end | |
local inGroup = UnitInRaid("player") or IsInGroup() | |
MDT.main_frame.LinkToChatButton:SetDisabled(not inGroup) | |
MDT.main_frame.LiveSessionButton:SetDisabled(not inGroup) | |
if inGroup then | |
MDT.main_frame.LinkToChatButton.text:SetTextColor(1,0.8196,0) | |
if MDT.liveSessionActive then | |
MDT.main_frame.LiveSessionButton:SetText(L["*Live*"]) | |
MDT.main_frame.LiveSessionButton.text:SetTextColor(0,1,0) | |
else | |
MDT.main_frame.LiveSessionButton:SetText(L["Live"]) | |
MDT.main_frame.LiveSessionButton.text:SetTextColor(1,0.8196,0) | |
end | |
else | |
MDT.main_frame.LinkToChatButton.text:SetTextColor(0.5,0.5,0.5) | |
MDT.main_frame.LiveSessionButton.text:SetTextColor(0.5,0.5,0.5) | |
end | |
last = now | |
--MDT:RequestDataCollectionUpdate() | |
end | |
end | |
function MDT.PLAYER_ENTERING_WORLD(self, addon) | |
--initialize Blizzard_ChallengesUI | |
C_Timer.After(1,function() | |
LoadAddOn("Blizzard_ChallengesUI") | |
C_MythicPlus.RequestCurrentAffixes() | |
C_MythicPlus.RequestMapInfo() | |
C_MythicPlus.RequestRewards() | |
end) | |
self:UnregisterEvent("PLAYER_ENTERING_WORLD") | |
end | |
end | |
MDT.mapInfo = {} | |
MDT.dungeonTotalCount = {} | |
MDT.scaleMultiplier = {} | |
--affixID as used in C_ChallengeMode.GetAffixInfo(affixID) | |
--https://www.wowhead.com/affixes | |
--lvl 4 affix, lvl 7 affix, tyrannical/fortified, seasonal affix | |
local affixWeeks = { | |
[1] = {11,124,10,128}, --bursting storming fortified tormented | |
[2] = {6,3,9,128}, --raging volcanic tyrannical tormented | |
[3] = {122,12,10,128}, -- insp grev | |
[4] = {123,4,9,128}, -- spite necro | |
[5] = {7,14,10,128}, -- bolster quaking | |
[6] = {0,0,9,128}, | |
[7] = {0,0,10,128}, | |
[8] = {0,0,9,128}, | |
[9] = {0,0,10,128}, | |
[10] = {0,0,9,128}, | |
[11] = {0,0,10,128}, | |
[12] = {0,0,9,128}, | |
} | |
local dungeonList = { | |
[1] = L["Black Rook Hold"], | |
[2] = L["Cathedral of Eternal Night"], | |
[3] = L["Court of Stars"], | |
[4] = L["Darkheart Thicket"], | |
[5] = L["Eye of Azshara"], | |
[6] = L["Halls of Valor"], | |
[7] = L["Maw of Souls"], | |
[8] = L["Neltharion's Lair"], | |
[9] = L["Return to Karazhan Lower"], | |
[10] = L["Return to Karazhan Upper"], | |
[11] = L["Seat of the Triumvirate"], | |
[12] = L["The Arcway"], | |
[13] = L["Vault of the Wardens"], | |
[14] = " >"..L["Battle for Azeroth"], | |
[15] = L["Atal'Dazar"], | |
[16] = L["Freehold"], | |
[17] = L["Kings' Rest"], | |
[18] = L["Shrine of the Storm"], | |
[19] = L["Siege of Boralus"], | |
[20] = L["Temple of Sethraliss"], | |
[21] = L["The MOTHERLODE!!"], | |
[22] = L["The Underrot"], | |
[23] = L["Tol Dagor"], | |
[24] = L["Waycrest Manor"], | |
[25] = L["Mechagon - Junkyard"], | |
[26] = L["Mechagon - Workshop"], | |
[27] = " <"..L["Legion"], | |
[28] = " >"..L["Shadowlands"], | |
[29] = L["De Other Side"], | |
[30] = L["Halls of Atonement"], | |
[31] = L["Mists of Tirna Scithe"], | |
[32] = L["Plaguefall"], | |
[33] = L["Sanguine Depths"], | |
[34] = L["Spires of Ascension"], | |
[35] = L["The Necrotic Wake"], | |
[36] = L["Theater of Pain"], | |
[37] = " <"..L["Battle for Azeroth"], | |
} | |
function MDT:GetNumDungeons() return #dungeonList-1 end | |
function MDT:GetDungeonName(idx) return dungeonList[idx] end | |
local dungeonSubLevels = { | |
[1] = { | |
[1] = L["The Ravenscrypt"], | |
[2] = L["The Grand Hall"], | |
[3] = L["Ravenshold"], | |
[4] = L["The Rook's Host"], | |
[5] = L["Lord Ravencrest's Chamber"], | |
[6] = L["The Raven's Crown"], | |
}, | |
[2] = { | |
[1] = L["Hall of the Moon"], | |
[2] = L["Twilight Grove"], | |
[3] = L["The Emerald Archives"], | |
[4] = L["Path of Illumination"], | |
[5] = L["Sacristy of Elune"], | |
}, | |
[3] = { | |
[1] = L["Court of Stars Sublevel"], | |
[2] = L["The Jeweled Estate"], | |
[3] = L["The Balconies"], | |
}, | |
[4] = { | |
[1] = L["Darkheart Thicket Sublevel"], | |
}, | |
[5] = { | |
[1] = L["Eye of Azshara Sublevel"], | |
}, | |
[6] = { | |
[1] = L["The High Gate"], | |
[2] = L["Field of the Eternal Hunt"], | |
[3] = L["Halls of Valor Sublevel"], | |
}, | |
[7] = { | |
[1] = L["Helmouth Cliffs"], | |
[2] = L["The Hold"], | |
[3] = L["The Naglfar"], | |
}, | |
[8] = { | |
[1] = L["Neltharion's Lair Sublevel"], | |
}, | |
[9] = { | |
[1] = L["Master's Terrace"], | |
[2] = L["Opera Hall Balcony"], | |
[3] = L["The Guest Chambers"], | |
[4] = L["The Banquet Hall"], | |
[5] = L["Upper Livery Stables"], | |
[6] = L["The Servant's Quarters"], | |
}, | |
[10] = { | |
[1] = L["Lower Broken Stair"], | |
[2] = L["Upper Broken Stair"], | |
[3] = L["The Menagerie"], | |
[4] = L["Guardian's Library"], | |
[5] = L["Library Floor"], | |
[6] = L["Upper Library"], | |
[7] = L["Gamesman's Hall"], | |
[8] = L["Netherspace"], | |
}, | |
[11] = { | |
[1] = L["Seat of the Triumvirate Sublevel"], | |
}, | |
[12] = { | |
[1] = L["The Arcway Sublevel"], | |
}, | |
[13] = { | |
[1] = L["The Warden's Court"], | |
[2] = L["Vault of the Wardens Sublevel"], | |
[3] = L["Vault of the Betrayer"], | |
}, | |
[15] = { | |
[1] = L["Atal'Dazar Sublevel"], | |
[2] = L["Sacrificial Pits"], | |
}, | |
[16] = { | |
[1] = L["Freehold Sublevel"], | |
}, | |
[17] = { | |
[1] = L["Kings' Rest Sublevel"], | |
}, | |
[18] = { | |
[1] = L["Shrine of the Storm Sublevel"], | |
[2] = L["Storm's End"], | |
}, | |
[19] = { | |
[1] = L["Siege of Boralus Sublevel"], | |
[2] = L["Siege of Boralus (Upstairs)"], | |
}, | |
[20] = { | |
[1] = L["Temple of Sethraliss Sublevel"], | |
[2] = L["Atrium of Sethraliss"], | |
}, | |
[21] = { | |
[1] = L["The MOTHERLODE!! Sublevel"], | |
}, | |
[22] = { | |
[1] = L["The Underrot Sublevel"], | |
[2] = L["Ruin's Descent"], | |
}, | |
[23] = { | |
[1] = L["Tol Dagor Sublevel1"], | |
[2] = L["The Drain"], | |
[3] = L["The Brig"], | |
[4] = L["Detention Block"], | |
[5] = L["Officer Quarters"], | |
[6] = L["Overseer's Redoubt"], | |
[7] = L["Overseer's Summit"], | |
}, | |
[24] = { | |
[1] = L["The Grand Foyer"], | |
[2] = L["Upstairs"], | |
[3] = L["The Cellar"], | |
[4] = L["Catacombs"], | |
[5] = L["The Rupture"], | |
}, | |
[25] = { | |
[1] = L["Mechagon Island"], | |
[2] = L["Mechagon Island (Tunnels)"], | |
}, | |
[26] = { | |
[1] = L["The Robodrome"], | |
[2] = L["Waste Pipes"], | |
[3] = L["The Under Junk"], | |
[4] = L["Mechagon City"], | |
}, | |
[29] = { | |
[1] = L["De Other Side"], | |
[2] = L["Mechagon"], | |
[3] = L["Zul'Gurub"], | |
[4] = L["Ardenweald"], | |
}, | |
[30] = { | |
[1] = L["HallsOfAtonementFloor1"], | |
[2] = L["HallsOfAtonementFloor2"], | |
[3] = L["HallsOfAtonementFloor3"], | |
}, | |
[31] = { | |
[1] = L["Mists of Tirna Scithe"], | |
}, | |
[32] = { | |
[1] = L["Plaguefall"], | |
[2] = L["The Festering Sanctum"], | |
}, | |
[33] = { | |
[1] = L["Sanguine DepthsFloor1"], | |
[2] = L["Sanguine DepthsFloor2"], | |
}, | |
[34] = { | |
[1] = L["Honor's Ascent"], | |
[2] = L["Gardens of Repose"], | |
[3] = L["Font of Fealty"], | |
[4] = L["Seat of the Archon"], | |
}, | |
[35] = { | |
[1] = L["TheNecroticWakeFloor1"], | |
[2] = L["TheNecroticWakeFloor2"], | |
[3] = L["TheNecroticWakeFloor3"], | |
}, | |
[36] = { | |
[1] = L["TheaterOfPainFloor1"], | |
[2] = L["TheaterOfPainFloor2"], | |
[3] = L["TheaterOfPainFloor3"], | |
[4] = L["TheaterOfPainFloor4"], | |
[5] = L["TheaterOfPainFloor5"], | |
}, | |
} | |
function MDT:GetDungeonSublevels() | |
return dungeonSubLevels | |
end | |
function MDT:GetSublevelName(dungeonIdx, sublevelIdx) | |
if not dungeonIdx then dungeonIdx = db.currentDungeonIdx end | |
return dungeonSubLevels[dungeonIdx][sublevelIdx] | |
end | |
MDT.dungeonMaps = { | |
[1] = { | |
[0]= "BlackRookHoldDungeon", | |
[1]= "BlackRookHoldDungeon1_", | |
[2]= "BlackRookHoldDungeon2_", | |
[3]= "BlackRookHoldDungeon3_", | |
[4]= "BlackRookHoldDungeon4_", | |
[5]= "BlackRookHoldDungeon5_", | |
[6]= "BlackRookHoldDungeon6_", | |
}, | |
[2] = { | |
[0]= "TombofSargerasDungeon", | |
[1]= "TombofSargerasDungeon1_", | |
[2]= "TombofSargerasDungeon2_", | |
[3]= "TombofSargerasDungeon3_", | |
[4]= "TombofSargerasDungeon4_", | |
[5]= "TombofSargerasDungeon5_", | |
}, | |
[3] = { | |
[0] = "SuramarNoblesDistrict", | |
[1] = "SuramarNoblesDistrict", | |
[2] = "SuramarNoblesDistrict1_", | |
[3] = "SuramarNoblesDistrict2_", | |
}, | |
[4] = { | |
[0] = "DarkheartThicket", | |
[1] = "DarkheartThicket", | |
}, | |
[5] = { | |
[0]= "AszunaDungeon", | |
[1]= "AszunaDungeon", | |
}, | |
[6] = { | |
[0]= "Hallsofvalor", | |
[1]= "Hallsofvalor1_", | |
[2]= "Hallsofvalor", | |
[3]= "Hallsofvalor2_", | |
}, | |
[7] = { | |
[0] = "HelheimDungeonDock", | |
[1] = "HelheimDungeonDock", | |
[2] = "HelheimDungeonDock1_", | |
[3] = "HelheimDungeonDock2_", | |
}, | |
[8] = { | |
[0] = "NeltharionsLair", | |
[1] = "NeltharionsLair", | |
}, | |
[9] = { | |
[0] = "LegionKarazhanDungeon", | |
[1] = "LegionKarazhanDungeon6_", | |
[2] = "LegionKarazhanDungeon5_", | |
[3] = "LegionKarazhanDungeon4_", | |
[4] = "LegionKarazhanDungeon3_", | |
[5] = "LegionKarazhanDungeon2_", | |
[6] = "LegionKarazhanDungeon1_", | |
}, | |
[10] = { | |
[0] = "LegionKarazhanDungeon", | |
[1] = "LegionKarazhanDungeon7_", | |
[2] = "LegionKarazhanDungeon8_", | |
[3] = "LegionKarazhanDungeon9_", | |
[4] = "LegionKarazhanDungeon10_", | |
[5] = "LegionKarazhanDungeon11_", | |
[6] = "LegionKarazhanDungeon12_", | |
[7] = "LegionKarazhanDungeon13_", | |
[8] = "LegionKarazhanDungeon14_", | |
}, | |
[11] = { | |
[0] = "ArgusDungeon", | |
[1] = "ArgusDungeon", | |
}, | |
[12] = { | |
[0]= "SuamarCatacombsDungeon", | |
[1]= "SuamarCatacombsDungeon1_", | |
}, | |
[13] = { | |
[0]= "VaultOfTheWardens", | |
[1]= "VaultOfTheWardens1_", | |
[2]= "VaultOfTheWardens2_", | |
[3]= "VaultOfTheWardens3_", | |
}, | |
[15] = { | |
[0]= "CityOfGold", | |
[1]= "CityOfGold1_", | |
[2]= "CityOfGold2_", | |
}, | |
[16] = { | |
[0]= "KulTirasPirateTownDungeon", | |
[1]= "KulTirasPirateTownDungeon", | |
}, | |
[17] = { | |
[0] = "KingsRest", | |
[1] = "KingsRest1_" | |
}, | |
[18] = { | |
[0] = "ShrineOfTheStorm", | |
[1] = "ShrineOfTheStorm", | |
[2] = "ShrineOfTheStorm1_", | |
}, | |
[19] = { | |
[0] = "SiegeOfBoralus", | |
[1] = "SiegeOfBoralus", | |
[2] = "SiegeOfBoralus", | |
}, | |
[20] = { | |
[0] = "TempleOfSethralissA", | |
[1] = "TempleOfSethralissA", | |
[2] = "TempleOfSethralissB", | |
}, | |
[21] = { | |
[0] = "KezanDungeon", | |
[1] = "KezanDungeon", | |
}, | |
[22] = { | |
[0] = "UnderrotExterior", | |
[1] = "UnderrotExterior", | |
[2] = "UnderrotInterior", | |
}, | |
[23] = { | |
[0] = "PrisonDungeon", | |
[1] = "PrisonDungeon", | |
[2] = "PrisonDungeon1_", | |
[3] = "PrisonDungeon2_", | |
[4] = "PrisonDungeon3_", | |
[5] = "PrisonDungeon4_", | |
[6] = "PrisonDungeon5_", | |
[7] = "PrisonDungeon6_", | |
}, | |
[24] = { | |
[0] = "Waycrest", | |
[1] = "Waycrest1_", | |
[2] = "Waycrest2_", | |
[3] = "Waycrest3_", | |
[4] = "Waycrest4_", | |
[5] = "Waycrest5_", | |
}, | |
[25] = { | |
[0] = "MechagonDungeon", | |
[1] = "MechagonDungeonExterior", | |
[2] = "MechagonDungeonExterior", | |
}, | |
[26] = { | |
[0] = "MechagonDungeon", | |
[1] = "MechagonDungeon1_", | |
[2] = "MechagonDungeon2_", | |
[3] = "MechagonDungeon3_", | |
[4] = "MechagonDungeon4_", | |
}, | |
[29] = { | |
[0] = "DeOtherSide_Ardenweald", | |
[1] = "DeOtherSide_Main", | |
[2] = "DeOtherSide_Gnome", | |
[3] = "DeOtherSide_Hakkar", | |
[4] = "DeOtherSide_Ardenweald", | |
}, | |
[30] = { | |
[0] = "HallsOfAtonement_A", | |
[1] = "HallsOfAttonementExterior", | |
[2] = "HallsOfAtonement_A", | |
[3] = "HallsOfAtonement_B", | |
}, | |
[31] = { | |
[0] = "MistsOfTirneScithe", | |
[1] = "MistsOfTirneScithe", | |
}, | |
[32] = { | |
[0] = "Plaguefall", | |
[1] = "Plaguefall", | |
[2] = "Plaguefall_B", | |
}, | |
[33] = { | |
[0] = "SanguineDepths_A", | |
[1] = "SanguineDepths_A", | |
[2] = "SanguineDepths_B", | |
}, | |
[34] = { | |
[0] = "SpiresOfAscension_A", | |
[1] = "SpiresOfAscension_A", | |
[2] = "SpiresOfAscension_B", | |
[3] = "SpiresOfAscension_C", | |
[4] = "SpiresOfAscension_D", | |
}, | |
[35] = { | |
[0] = "NecroticWake_A", | |
[1] = "NecroticWake_Exterior", | |
[2] = "NecroticWake_A", | |
[3] = "NecroticWake_B", | |
}, | |
[36] = { | |
[0] = "TheaterOfPain", | |
[1] = "TheaterOfPain", | |
[2] = "TheaterOfPain_Warlord", | |
[3] = "TheaterOfPain_Lich", | |
[4] = "TheaterOfPain_AbomTop", | |
[5] = "TheaterOfPain_AbomBot", | |
}, | |
} | |
MDT.dungeonBosses = {} | |
MDT.dungeonEnemies = {} | |
MDT.mapPOIs = {} | |
function MDT:GetDB() | |
return db | |
end | |
local framesInitialized | |
function MDT:ShowInterface(force) | |
if not framesInitialized then initFrames() end | |
if self.main_frame:IsShown() and not force then | |
MDT:HideInterface() | |
else | |
self.main_frame:Show() | |
self.main_frame.HelpButton:Show() | |
self:CheckCurrentZone() | |
--edge case if user closed MDT window while in the process of dragging a corrupted blip | |
if self.draggedBlip then | |
if MDT.liveSessionActive then | |
MDT:LiveSession_SendCorruptedPositions(MDT:GetRiftOffsets()) | |
end | |
self:UpdateMap() | |
self.draggedBlip = nil | |
end | |
MDT:UpdateBottomText() | |
end | |
end | |
function MDT:HideInterface() | |
self.main_frame:Hide() | |
self.main_frame.HelpButton:Hide() | |
end | |
function MDT:ToggleDevMode() | |
db.devMode = not db.devMode | |
ReloadUI() | |
end | |
function MDT:ToggleDataCollection() | |
db.dataCollectionActive = not db.dataCollectionActive | |
print(string.format("%sMDT|r: DataCollection %s. Reload Interface!", mythicColor,db.dataCollectionActive and "|cFF00FF00Enabled|r" or "|cFFFF0000Disabled|r")) | |
end | |
function MDT:ToggleHealthTrack() | |
MDT.DataCollection:InitHealthTrack() | |
print(string.format("%sMDT|r: HealthTrack %s.", mythicColor,"|cFF00FF00Enabled|r")) | |
end | |
function MDT:CreateMenu() | |
-- Close button | |
self.main_frame.closeButton = CreateFrame("Button", "MDTCloseButton", self.main_frame, "UIPanelCloseButton") | |
self.main_frame.closeButton:ClearAllPoints() | |
self.main_frame.closeButton:SetPoint("TOPRIGHT", self.main_frame.sidePanel, "TOPRIGHT", 0, 0) | |
self.main_frame.closeButton:SetScript("OnClick", function() self:HideInterface() end) | |
self.main_frame.closeButton:SetFrameLevel(4) | |
--Maximize Button | |
self.main_frame.maximizeButton = CreateFrame("Button", "MDTMaximizeButton", self.main_frame, "MaximizeMinimizeButtonFrameTemplate") | |
self.main_frame.maximizeButton:ClearAllPoints() | |
self.main_frame.maximizeButton:SetPoint("RIGHT", self.main_frame.closeButton, "LEFT", 0, 0) | |
self.main_frame.maximizeButton:SetFrameLevel(4) | |
db.maximized = db.maximized or false | |
if not db.maximized then self.main_frame.maximizeButton:Minimize() end | |
self.main_frame.maximizeButton:SetOnMaximizedCallback(self.Maximize) | |
self.main_frame.maximizeButton:SetOnMinimizedCallback(self.Minimize) | |
--return to live preset | |
self.main_frame.liveReturnButton = CreateFrame("Button", "MDTLiveReturnButton", self.main_frame, "UIPanelCloseButton") | |
local liveReturnButton = self.main_frame.liveReturnButton | |
liveReturnButton:ClearAllPoints() | |
liveReturnButton:SetPoint("RIGHT", self.main_frame.topPanel, "RIGHT", 0, 0) | |
liveReturnButton.Icon = liveReturnButton:CreateTexture(nil, "OVERLAY") | |
liveReturnButton.Icon:SetTexture("Interface\\Buttons\\UI-RefreshButton") | |
liveReturnButton.Icon:SetSize(16,16) | |
liveReturnButton.Icon:SetTexCoord(1, 0, 0, 1) --flipped image | |
liveReturnButton.Icon:SetPoint("CENTER",liveReturnButton,"CENTER") | |
liveReturnButton:SetScript("OnClick", function() self:ReturnToLivePreset() end) | |
liveReturnButton:SetFrameLevel(4) | |
liveReturnButton.tooltip = L["Return to the live preset"] | |
--set preset as new live preset | |
self.main_frame.setLivePresetButton = CreateFrame("Button", "MDTSetLivePresetButton", self.main_frame, "UIPanelCloseButton") | |
local setLivePresetButton = self.main_frame.setLivePresetButton | |
setLivePresetButton:ClearAllPoints() | |
setLivePresetButton:SetPoint("RIGHT", liveReturnButton, "LEFT", 0, 0) | |
setLivePresetButton.Icon = setLivePresetButton:CreateTexture(nil, "OVERLAY") | |
setLivePresetButton.Icon:SetTexture("Interface\\ChatFrame\\ChatFrameExpandArrow") | |
setLivePresetButton.Icon:SetSize(16,16) | |
setLivePresetButton.Icon:SetPoint("CENTER",setLivePresetButton,"CENTER") | |
setLivePresetButton:SetScript("OnClick", function() self:SetLivePreset() end) | |
setLivePresetButton:SetFrameLevel(4) | |
setLivePresetButton.tooltip = L["Make this preset the live preset"] | |
self:SkinMenuButtons() | |
--Resize Handle | |
self.main_frame.resizer = CreateFrame("BUTTON", nil, self.main_frame.sidePanel) | |
local resizer = self.main_frame.resizer | |
resizer:SetPoint("BOTTOMRIGHT", self.main_frame.sidePanel,"BOTTOMRIGHT",7,-7) | |
resizer:SetSize(25, 25) | |
resizer:EnableMouse() | |
resizer:SetScript("OnMouseDown", function() | |
self.main_frame:StartSizing("BOTTOMRIGHT") | |
self:StartScaling() | |
self:HideAllPresetObjects() | |
self:ReleaseHullTextures() | |
self.main_frame:SetScript("OnSizeChanged", function() | |
local height = self.main_frame:GetHeight() | |
self:SetScale(height/sizey) | |
end) | |
end) | |
resizer:SetScript("OnMouseUp", function() | |
self.main_frame:StopMovingOrSizing() | |
self:UpdateEnemyInfoFrame() | |
self:UpdateMap() | |
self:CreateTutorialButton(self.main_frame) | |
self.main_frame:SetScript("OnSizeChanged", function() end) | |
end) | |
local normal = resizer:CreateTexture(nil, "OVERLAY") | |
normal:SetTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Up") | |
normal:SetTexCoord(0, 1, 0, 1) | |
normal:SetPoint("BOTTOMLEFT", resizer, 0, 6) | |
normal:SetPoint("TOPRIGHT", resizer, -6, 0) | |
resizer:SetNormalTexture(normal) | |
local pushed = resizer:CreateTexture(nil, "OVERLAY") | |
pushed:SetTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Down") | |
pushed:SetTexCoord(0, 1, 0, 1) | |
pushed:SetPoint("BOTTOMLEFT", resizer, 0, 6) | |
pushed:SetPoint("TOPRIGHT", resizer, -6, 0) | |
resizer:SetPushedTexture(pushed) | |
local highlight = resizer:CreateTexture(nil, "OVERLAY") | |
highlight:SetTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Highlight") | |
highlight:SetTexCoord(0, 1, 0, 1) | |
highlight:SetPoint("BOTTOMLEFT", resizer, 0, 6) | |
highlight:SetPoint("TOPRIGHT", resizer, -6, 0) | |
resizer:SetHighlightTexture(highlight) | |
end | |
function MDT:SkinMenuButtons() | |
--attempt to skin close button for ElvUI | |
if IsAddOnLoaded("ElvUI") then | |
local E, L, V, P, G = unpack(ElvUI) | |
local S | |
if E then S = E:GetModule("Skins") end | |
if S then | |
S:HandleCloseButton(self.main_frame.closeButton) | |
S:HandleMaxMinFrame(self.main_frame.maximizeButton) | |
S:HandleButton(self.main_frame.liveReturnButton) | |
self.main_frame.liveReturnButton:Size(26) | |
--self.main_frame.liveReturnButton.Icon:SetVertexColor(0,1,1,1) | |
S:HandleButton(self.main_frame.setLivePresetButton) | |
self.main_frame.setLivePresetButton:Size(26) | |
self.main_frame.setLivePresetButton.Icon:SetVertexColor(1, .82, 0, 0.8) | |
end | |
end | |
end | |
---GetDefaultMapPanelSize | |
function MDT:GetDefaultMapPanelSize() | |
return sizex,sizey | |
end | |
---GetScale | |
---Returns scale factor stored in db | |
function MDT:GetScale() | |
if not db.scale then db.scale = 1 end | |
return db.scale | |
end | |
local oldScrollValues = {} | |
---StartScaling | |
---Stores values when we start scaling the frame | |
function MDT:StartScaling() | |
local f = self.main_frame | |
oldScrollValues.oldScrollH = f.scrollFrame:GetHorizontalScroll() | |
oldScrollValues.oldScrollV = f.scrollFrame:GetVerticalScroll() | |
oldScrollValues.oldSizeX = f.scrollFrame:GetWidth() | |
oldScrollValues.oldSizeY = f.scrollFrame:GetHeight() | |
HelpPlate_Hide(true) | |
self:DungeonEnemies_HideAllBlips() | |
self:POI_HideAllPoints() | |
self:KillAllAnimatedLines() | |
end | |
---SetScale | |
---Scales the map frame and it's sub frames to a factor and stores the scale in db | |
function MDT:SetScale(scale) | |
local f = self.main_frame | |
local newSizex = sizex*scale | |
local newSizey = sizey*scale | |
f:SetSize(newSizex,newSizey) | |
f.scrollFrame:SetSize(newSizex, newSizey) | |
f.mapPanelFrame:SetSize(newSizex, newSizey) | |
for i=1,12 do | |
f["mapPanelTile"..i]:SetSize((newSizex/4+5*scale),(newSizex/4+5*scale)) | |
end | |
for i=1,10 do | |
for j=1,15 do | |
f["largeMapPanelTile"..i..j]:SetSize(newSizex/15,newSizex/15) | |
end | |
end | |
f.scrollFrame:SetVerticalScroll(oldScrollValues.oldScrollV * (newSizey / oldScrollValues.oldSizeY)) | |
f.scrollFrame:SetHorizontalScroll(oldScrollValues.oldScrollH * (newSizex / oldScrollValues.oldSizeX)) | |
f.scrollFrame.cursorY = f.scrollFrame.cursorY * (newSizey / oldScrollValues.oldSizeY) | |
f.scrollFrame.cursorX = f.scrollFrame.cursorX * (newSizex / oldScrollValues.oldSizeX) | |
self:ZoomMap(0) | |
db.scale = scale | |
db.nonFullscreenScale = scale | |
end | |
function MDT:GetFullScreenSizes() | |
local newSizey = GetScreenHeight()-60 --top and bottom panel 30 each | |
local newSizex = newSizey*(sizex/sizey) | |
local isNarrow | |
if newSizex+251>GetScreenWidth() then --251 sidebar | |
newSizex = GetScreenWidth()-251 | |
newSizey = newSizex*(sizey/sizex) | |
isNarrow = true | |
end | |
local scale = newSizey/sizey --use this for adjusting NPC / POI positions later | |
return newSizex, newSizey, scale, isNarrow | |
end | |
---Maximize | |
---FULLSCREEN the UI | |
function MDT:Maximize() | |
local f = MDT.main_frame | |
local oldScrollH = f.scrollFrame:GetHorizontalScroll() | |
local oldScrollV = f.scrollFrame:GetVerticalScroll() | |
local oldSizeX = f.scrollFrame:GetWidth() | |
local oldSizeY = f.scrollFrame:GetHeight() | |
if not f.blackoutFrame then | |
f.blackoutFrame = CreateFrame("Frame", "MDTBlackoutFrame", f) | |
f.blackoutFrame:EnableMouse(true) | |
f.blackoutFrameTex = f.blackoutFrame:CreateTexture(nil, "BACKGROUND") | |
f.blackoutFrameTex:SetAllPoints() | |
f.blackoutFrameTex:SetDrawLayer(canvasDrawLayer, -6) | |
f.blackoutFrameTex:SetColorTexture(0.058823399245739,0.058823399245739,0.058823399245739,1) | |
f.blackoutFrame:ClearAllPoints() | |
f.blackoutFrame:SetAllPoints(UIParent) | |
end | |
f.blackoutFrame:Show() | |
f.topPanel:RegisterForDrag(nil) | |
f.bottomPanel:RegisterForDrag(nil) | |
local newSizex, newSizey, scale, isNarrow = MDT:GetFullScreenSizes() | |
db.scale = scale | |
f:ClearAllPoints() | |
if not isNarrow then | |
f:SetPoint("TOP", UIParent,"TOP", -(f.sidePanel:GetWidth()/2), -30) | |
else | |
f:SetPoint("LEFT", UIParent,"LEFT") | |
end | |
f:SetSize(newSizex,newSizey) | |
f.scrollFrame:SetSize(newSizex, newSizey) | |
f.mapPanelFrame:SetSize(newSizex, newSizey) | |
for i=1,12 do | |
f["mapPanelTile"..i]:SetSize((newSizex/4+5*db.scale),(newSizex/4+5*db.scale)) | |
end | |
for i=1,10 do | |
for j=1,15 do | |
f["largeMapPanelTile"..i..j]:SetSize(newSizex/15,newSizex/15) | |
end | |
end | |
f.scrollFrame:SetVerticalScroll(oldScrollV * (newSizey / oldSizeY)) | |
f.scrollFrame:SetHorizontalScroll(oldScrollH * (newSizex / oldSizeX)) | |
f.scrollFrame.cursorY = f.scrollFrame.cursorY * (newSizey / oldSizeY) | |
f.scrollFrame.cursorX = f.scrollFrame.cursorX * (newSizex / oldSizeX) | |
MDT:ZoomMap(0) | |
MDT:UpdateEnemyInfoFrame() | |
MDT:UpdateMap() | |
if db.devMode then | |
f.devPanel:ClearAllPoints() | |
f.devPanel:SetPoint("TOPLEFT",f,"TOPLEFT",0,-45) | |
end | |
f.resizer:Hide() | |
MDT:CreateTutorialButton(MDT.main_frame) | |
db.maximized = true | |
end | |
---Minimize | |
---Restore normal UI | |
function MDT:Minimize() | |
local f = MDT.main_frame | |
local oldScrollH = f.scrollFrame:GetHorizontalScroll() | |
local oldScrollV = f.scrollFrame:GetVerticalScroll() | |
local oldSizeX = f.scrollFrame:GetWidth() | |
local oldSizeY = f.scrollFrame:GetHeight() | |
if f.blackoutFrame then f.blackoutFrame:Hide() end | |
f.topPanel:RegisterForDrag("LeftButton") | |
f.bottomPanel:RegisterForDrag("LeftButton") | |
db.scale = db.nonFullscreenScale | |
local newSizex = sizex*db.scale | |
local newSizey = sizey*db.scale | |
f:ClearAllPoints() | |
f:SetPoint(db.anchorTo, UIParent,db.anchorFrom, db.xoffset, db.yoffset) | |
f:SetSize(newSizex,newSizey) | |
f.scrollFrame:SetSize(newSizex, newSizey) | |
f.mapPanelFrame:SetSize(newSizex, newSizey) | |
for i=1,12 do | |
f["mapPanelTile"..i]:SetSize(newSizex/4+(5*db.scale),newSizex/4+(5*db.scale)) | |
end | |
for i=1,10 do | |
for j=1,15 do | |
f["largeMapPanelTile"..i..j]:SetSize(newSizex/15,newSizex/15) | |
end | |
end | |
f.scrollFrame:SetVerticalScroll(oldScrollV * (newSizey / oldSizeY)) | |
f.scrollFrame:SetHorizontalScroll(oldScrollH * (newSizex / oldSizeX)) | |
f.scrollFrame.cursorY = f.scrollFrame.cursorY * (newSizey / oldSizeY) | |
f.scrollFrame.cursorX = f.scrollFrame.cursorX * (newSizex / oldSizeX) | |
MDT:ZoomMap(0) | |
MDT:UpdateEnemyInfoFrame() | |
MDT:UpdateMap() | |
if db.devMode then | |
f.devPanel:ClearAllPoints() | |
f.devPanel:SetPoint("TOPRIGHT",f.topPanel,"TOPLEFT",0,0) | |
end | |
f.resizer:Show() | |
MDT:CreateTutorialButton(MDT.main_frame) | |
db.maximized = false | |
end | |
function MDT:SkinProgressBar(progressBar) | |
local bar = progressBar and progressBar.Bar | |
if not bar then return end | |
bar.Icon:Hide() | |
bar.IconBG:Hide() | |
if IsAddOnLoaded("ElvUI") then | |
local E, L, V, P, G = unpack(ElvUI) | |
if bar.BarFrame then bar.BarFrame:Hide() end | |
if bar.BarFrame2 then bar.BarFrame2:Hide() end | |
if bar.BarFrame3 then bar.BarFrame3:Hide() end | |
if bar.BarGlow then bar.BarGlow:Hide() end | |
if bar.Sheen then bar.Sheen:Hide() end | |
if bar.IconBG then bar.IconBG:SetAlpha(0) end | |
if bar.BorderLeft then bar.BorderLeft:SetAlpha(0) end | |
if bar.BorderRight then bar.BorderRight:SetAlpha(0) end | |
if bar.BorderMid then bar.BorderMid:SetAlpha(0) end | |
bar:Height(18) | |
bar:StripTextures() | |
bar:CreateBackdrop("Transparent") | |
bar:SetStatusBarTexture(E.media.normTex) | |
local label = bar.Label | |
if not label then return end | |
label:ClearAllPoints() | |
label:SetPoint("CENTER",bar,"CENTER") | |
end | |
end | |
function MDT:IsFrameOffScreen() | |
local topPanel = MDT.main_frame.topPanel | |
local bottomPanel = MDT.main_frame.bottomPanel | |
local width = GetScreenWidth() | |
local height = GetScreenHeight() | |
local left = topPanel:GetLeft()-->width | |
local right = topPanel:GetRight()--<0 | |
local bottom = topPanel:GetBottom()--<0 | |
local top = bottomPanel:GetTop()-->height | |
return left>width or right<0 or bottom<0 or top>height | |
end | |
local bottomTips = { | |
[1] = L["Please report any bugs on https://github.com/Nnoggie/MythicDungeonTools/issues"], | |
[2] = L["Hold CTRL to single-select enemies."], | |
[3] = L["Hold SHIFT to create a new pull while selecting enemies."], | |
[4] = L["Hold SHIFT to delete all presets with the delete preset button."], | |
[5] = L["Right click a pull for more options."], | |
[6] = L["Right click an enemy to open the enemy info window."], | |
[7] = L["Drag the bottom right edge to resize MDT."], | |
[8] = L["Click the fullscreen button for a maximized view of MDT."], | |
[9] = L["Use /mdt reset to restore the default position and scale of MDT."], | |
[10] = L["Mouseover the Live button while in a group to learn more about Live mode."], | |
[11] = L["You are using MDT. You rock!"], | |
[12] = L["You can choose from different color palettes in the automatic pull coloring settings menu."], | |
[13] = L["You can cycle through different floors by holding CTRL and using the mousewheel."], | |
[14] = L["You can cycle through dungeons by holding ALT and using the mousewheel."], | |
[15] = L["Mouseover a patrolling enemy with a blue border to view the patrol path."], | |
[16] = L["Expand the top toolbar to gain access to drawing and note features."], | |
[17] = L["ConnectedTip"], | |
} | |
function MDT:UpdateBottomText() | |
local f = self.main_frame.bottomPanelString | |
f:SetText(bottomTips[math.random(#bottomTips)]) | |
end | |
function MDT:MakeTopBottomTextures(frame) | |
frame:SetMovable(true) | |
if frame.topPanel == nil then | |
frame.topPanel = CreateFrame("Frame", "MDTTopPanel", frame) | |
frame.topPanelTex = frame.topPanel:CreateTexture(nil, "BACKGROUND") | |
frame.topPanelTex:SetAllPoints() | |
frame.topPanelTex:SetDrawLayer(canvasDrawLayer, -5) | |
frame.topPanelTex:SetColorTexture(unpack(MDT.BackdropColor)) | |
frame.topPanelString = frame.topPanel:CreateFontString("MDT name") | |
--use default font if ElvUI is enabled | |
--if IsAddOnLoaded("ElvUI") then | |
frame.topPanelString:SetFontObject("GameFontNormalMed3") | |
frame.topPanelString:SetTextColor(1, 1, 1, 1) | |
frame.topPanelString:SetJustifyH("CENTER") | |
frame.topPanelString:SetJustifyV("CENTER") | |
--frame.topPanelString:SetWidth(600) | |
frame.topPanelString:SetHeight(20) | |
frame.topPanelString:SetText("Mythic Dungeon Tools") | |
frame.topPanelString:ClearAllPoints() | |
frame.topPanelString:SetPoint("CENTER", frame.topPanel, "CENTER", 10, 0) | |
frame.topPanelString:Show() | |
--frame.topPanelString:SetFont(frame.topPanelString:GetFont(), 20) | |
frame.topPanelLogo = frame.topPanel:CreateTexture(nil, "HIGH", nil, 7) | |
frame.topPanelLogo:SetTexture("Interface\\AddOns\\"..AddonName.."\\Textures\\Nnoggie") | |
frame.topPanelLogo:SetWidth(24) | |
frame.topPanelLogo:SetHeight(24) | |
frame.topPanelLogo:SetPoint("RIGHT",frame.topPanelString,"LEFT",-5,0) | |
frame.topPanelLogo:Show() | |
end | |
frame.topPanel:ClearAllPoints() | |
frame.topPanel:SetHeight(30) | |
frame.topPanel:SetPoint("BOTTOMLEFT", frame, "TOPLEFT") | |
frame.topPanel:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT") | |
frame.topPanel:EnableMouse(true) | |
frame.topPanel:RegisterForDrag("LeftButton") | |
frame.topPanel:SetScript("OnDragStart", function(self,button) | |
frame:SetMovable(true) | |
frame:StartMoving() | |
end) | |
frame.topPanel:SetScript("OnDragStop", function(self,button) | |
frame:StopMovingOrSizing() | |
frame:SetMovable(false) | |
if MDT:IsFrameOffScreen() then | |
MDT:ResetMainFramePos(true) | |
else | |
local from,_,to,x,y = MDT.main_frame:GetPoint() | |
db.anchorFrom = from | |
db.anchorTo = to | |
db.xoffset,db.yoffset = x,y | |
end | |
end) | |
if frame.bottomPanel == nil then | |
frame.bottomPanel = CreateFrame("Frame", "MDTBottomPanel", frame) | |
frame.bottomPanelTex = frame.bottomPanel:CreateTexture(nil, "BACKGROUND") | |
frame.bottomPanelTex:SetAllPoints() | |
frame.bottomPanelTex:SetDrawLayer(canvasDrawLayer, -5) | |
frame.bottomPanelTex:SetColorTexture(unpack(MDT.BackdropColor)) | |
end | |
frame.bottomPanel:ClearAllPoints() | |
frame.bottomPanel:SetHeight(30) | |
frame.bottomPanel:SetPoint("TOPLEFT", frame, "BOTTOMLEFT") | |
frame.bottomPanel:SetPoint("TOPRIGHT", frame, "BOTTOMRIGHT") | |
frame.bottomPanelString = frame.bottomPanel:CreateFontString("MDTMid") | |
frame.bottomPanelString:SetFontObject("GameFontNormalSmall") | |
frame.bottomPanelString:SetJustifyH("CENTER") | |
frame.bottomPanelString:SetJustifyV("CENTER") | |
frame.bottomPanelString:SetPoint("CENTER", frame.bottomPanel, "CENTER", 0, 0) | |
frame.bottomPanelString:SetTextColor(1, 1, 1, 1) | |
frame.bottomPanelString:Show() | |
frame.bottomLeftPanelString = frame.bottomPanel:CreateFontString("MDTVersion") | |
frame.bottomLeftPanelString:SetFontObject("GameFontNormalSmall") | |
frame.bottomLeftPanelString:SetJustifyH("LEFT") | |
frame.bottomLeftPanelString:SetJustifyV("CENTER") | |
frame.bottomLeftPanelString:SetPoint("LEFT", frame.bottomPanel, "LEFT", 0, 0) | |
frame.bottomLeftPanelString:SetTextColor(1, 1, 1, 1) | |
frame.bottomLeftPanelString:SetText(" v"..GetAddOnMetadata(AddonName, "Version")) | |
frame.bottomLeftPanelString:Show() | |
frame.bottomPanel:EnableMouse(true) | |
frame.bottomPanel:RegisterForDrag("LeftButton") | |
frame.bottomPanel:SetScript("OnDragStart", function(self,button) | |
frame:SetMovable(true) | |
frame:StartMoving() | |
end) | |
frame.bottomPanel:SetScript("OnDragStop", function(self,button) | |
frame:StopMovingOrSizing() | |
frame:SetMovable(false) | |
if MDT:IsFrameOffScreen() then | |
MDT:ResetMainFramePos(true) | |
else | |
local from,_,to,x,y = MDT.main_frame:GetPoint() | |
db.anchorFrom = from | |
db.anchorTo = to | |
db.xoffset,db.yoffset = x,y | |
end | |
end) | |
end | |
function MDT:MakeSidePanel(frame) | |
if frame.sidePanel == nil then | |
frame.sidePanel = CreateFrame("Frame", "MDTSidePanel", frame) | |
frame.sidePanelTex = frame.sidePanel:CreateTexture(nil, "BACKGROUND") | |
frame.sidePanelTex:SetAllPoints() | |
frame.sidePanelTex:SetDrawLayer(canvasDrawLayer, -5) | |
frame.sidePanelTex:SetColorTexture(unpack(MDT.BackdropColor)) | |
frame.sidePanelTex:Show() | |
end | |
frame.sidePanel:EnableMouse(true) | |
frame.sidePanel:ClearAllPoints() | |
frame.sidePanel:SetWidth(251) | |
frame.sidePanel:SetPoint("TOPLEFT", frame, "TOPRIGHT", 0, 30) | |
frame.sidePanel:SetPoint("BOTTOMLEFT", frame, "BOTTOMRIGHT", 0, -30) | |
frame.sidePanelString = frame.sidePanel:CreateFontString("MDTSidePanelText") | |
frame.sidePanelString:SetFont("Fonts\\FRIZQT__.TTF", 10) | |
frame.sidePanelString:SetTextColor(1, 1, 1, 1) | |
frame.sidePanelString:SetJustifyH("LEFT") | |
frame.sidePanelString:SetJustifyV("TOP") | |
frame.sidePanelString:SetWidth(200) | |
frame.sidePanelString:SetHeight(500) | |
frame.sidePanelString:SetText("") | |
frame.sidePanelString:ClearAllPoints() | |
frame.sidePanelString:SetPoint("TOPLEFT", frame.sidePanel, "TOPLEFT", 33, -120-30-25) | |
frame.sidePanelString:Hide() | |
frame.sidePanel.WidgetGroup = AceGUI:Create("SimpleGroup") | |
frame.sidePanel.WidgetGroup:SetWidth(245) | |
frame.sidePanel.WidgetGroup:SetHeight(frame:GetHeight()+(frame.topPanel:GetHeight()*2)-31) | |
frame.sidePanel.WidgetGroup:SetPoint("TOP",frame.sidePanel,"TOP",3,-1) | |
frame.sidePanel.WidgetGroup:SetLayout("Flow") | |
frame.sidePanel.WidgetGroup.frame:SetFrameStrata(mainFrameStrata) | |
if not frame.sidePanel.WidgetGroup.frame.SetBackdrop then | |
Mixin(frame.sidePanel.WidgetGroup.frame, BackdropTemplateMixin) | |
end | |
frame.sidePanel.WidgetGroup.frame:SetBackdropColor(1,1,1,0) | |
frame.sidePanel.WidgetGroup.frame:Hide() | |
--dirty hook to make widgetgroup show/hide | |
local originalShow,originalHide = frame.Show,frame.Hide | |
function frame:Show(...) | |
frame.sidePanel.WidgetGroup.frame:Show() | |
return originalShow(self, ...) | |
end | |
function frame:Hide(...) | |
frame.sidePanel.WidgetGroup.frame:Hide() | |
MDT.pullTooltip:Hide() | |
return originalHide(self, ...) | |
end | |
--preset selection | |
frame.sidePanel.WidgetGroup.PresetDropDown = AceGUI:Create("Dropdown") | |
local dropdown = frame.sidePanel.WidgetGroup.PresetDropDown | |
dropdown.frame:SetWidth(170) | |
dropdown.text:SetJustifyH("LEFT") | |
dropdown:SetCallback("OnValueChanged",function(widget,callbackName,key) | |
if db.presets[db.currentDungeonIdx][key].value==0 then | |
MDT:OpenNewPresetDialog() | |
MDT.main_frame.sidePanelDeleteButton:SetDisabled(true) | |
MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(0.5,0.5,0.5) | |
else | |
if key == 1 then | |
MDT.main_frame.sidePanelDeleteButton:SetDisabled(true) | |
MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(0.5,0.5,0.5) | |
else | |
if not MDT.liveSessionActive then | |
MDT.main_frame.sidePanelDeleteButton:SetDisabled(false) | |
MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(1,0.8196,0) | |
else | |
MDT.main_frame.sidePanelDeleteButton:SetDisabled(true) | |
MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(0.5,0.5,0.5) | |
end | |
end | |
db.currentPreset[db.currentDungeonIdx] = key | |
--Set affix dropdown to preset week | |
--frame.sidePanel.affixDropdown:SetAffixWeek(MDT:GetCurrentPreset().week or MDT:GetCurrentAffixWeek()) | |
--UpdateMap is called in SetAffixWeek, no need to call twice | |
MDT:UpdateMap() | |
frame.sidePanel.affixDropdown:SetAffixWeek(MDT:GetCurrentPreset().week or MDT:GetCurrentAffixWeek() or 1) | |
end | |
end) | |
MDT:UpdatePresetDropDown() | |
frame.sidePanel.WidgetGroup:AddChild(dropdown) | |
---new profile,rename,export,delete | |
local buttonWidth = 80 | |
frame.sidePanelNewButton = AceGUI:Create("Button") | |
frame.sidePanelNewButton:SetText(L["New"]) | |
frame.sidePanelNewButton:SetWidth(buttonWidth) | |
--button fontInstance | |
local fontInstance = CreateFont("MDTButtonFont") | |
fontInstance:CopyFontObject(frame.sidePanelNewButton.frame:GetNormalFontObject()) | |
local fontName,height = fontInstance:GetFont() | |
fontInstance:SetFont(fontName,10) | |
frame.sidePanelNewButton.frame:SetNormalFontObject(fontInstance) | |
frame.sidePanelNewButton.frame:SetHighlightFontObject(fontInstance) | |
frame.sidePanelNewButton.frame:SetDisabledFontObject(fontInstance) | |
frame.sidePanelNewButton:SetCallback("OnClick",function(widget,callbackName,value) | |
MDT:OpenNewPresetDialog() | |
end) | |
frame.sidePanelNewButton.frame:SetScript("OnEnter",function() | |
GameTooltip:SetOwner(frame.sidePanelNewButton.frame, "ANCHOR_BOTTOMLEFT",frame.sidePanelNewButton.frame:GetWidth()*(-0),frame.sidePanelNewButton.frame:GetHeight()) | |
GameTooltip:AddLine(L["Create a new preset"],1,1,1) | |
GameTooltip:Show() | |
end) | |
frame.sidePanelNewButton.frame:SetScript("OnLeave",function() | |
GameTooltip:Hide() | |
end) | |
frame.sidePanelRenameButton = AceGUI:Create("Button") | |
frame.sidePanelRenameButton:SetWidth(buttonWidth) | |
frame.sidePanelRenameButton:SetText(L["Rename"]) | |
frame.sidePanelRenameButton.frame:SetNormalFontObject(fontInstance) | |
frame.sidePanelRenameButton.frame:SetHighlightFontObject(fontInstance) | |
frame.sidePanelRenameButton.frame:SetDisabledFontObject(fontInstance) | |
frame.sidePanelRenameButton:SetCallback("OnClick",function(widget,callbackName,value) | |
MDT:HideAllDialogs() | |
local currentPresetName = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].text | |
MDT.main_frame.RenameFrame:Show() | |
MDT.main_frame.RenameFrame.RenameButton:SetDisabled(true) | |
MDT.main_frame.RenameFrame.RenameButton.text:SetTextColor(0.5,0.5,0.5) | |
MDT.main_frame.RenameFrame:ClearAllPoints() | |
MDT.main_frame.RenameFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50) | |
MDT.main_frame.RenameFrame.Editbox:SetText(currentPresetName) | |
MDT.main_frame.RenameFrame.Editbox:HighlightText(0, string.len(currentPresetName)) | |
MDT.main_frame.RenameFrame.Editbox:SetFocus() | |
end) | |
frame.sidePanelRenameButton.frame:SetScript("OnEnter",function() | |
GameTooltip:SetOwner(frame.sidePanelRenameButton.frame, "ANCHOR_BOTTOMLEFT",frame.sidePanelRenameButton.frame:GetWidth()*(-1),frame.sidePanelRenameButton.frame:GetHeight()) | |
GameTooltip:AddLine(L["Rename the preset"],1,1,1) | |
GameTooltip:Show() | |
end) | |
frame.sidePanelRenameButton.frame:SetScript("OnLeave",function() | |
GameTooltip:Hide() | |
end) | |
frame.sidePanelImportButton = AceGUI:Create("Button") | |
frame.sidePanelImportButton:SetText(L["Import"]) | |
frame.sidePanelImportButton:SetWidth(buttonWidth) | |
frame.sidePanelImportButton.frame:SetNormalFontObject(fontInstance) | |
frame.sidePanelImportButton.frame:SetHighlightFontObject(fontInstance) | |
frame.sidePanelImportButton.frame:SetDisabledFontObject(fontInstance) | |
frame.sidePanelImportButton:SetCallback("OnClick",function(widget,callbackName,value) | |
MDT:OpenImportPresetDialog() | |
end) | |
frame.sidePanelImportButton.frame:SetScript("OnEnter",function() | |
GameTooltip:SetOwner(frame.sidePanelImportButton.frame, "ANCHOR_BOTTOMLEFT",frame.sidePanelImportButton.frame:GetWidth()*(-1),frame.sidePanelImportButton.frame:GetHeight()) | |
GameTooltip:AddLine(L["Import a preset from a text string"],1,1,1) | |
GameTooltip:AddLine(L["You can find MDT exports from other users on the wago.io website"],1,1,1,1) | |
GameTooltip:Show() | |
end) | |
frame.sidePanelImportButton.frame:SetScript("OnLeave",function() | |
GameTooltip:Hide() | |
end) | |
frame.sidePanelExportButton = AceGUI:Create("Button") | |
frame.sidePanelExportButton:SetText(L["Export"]) | |
frame.sidePanelExportButton:SetWidth(buttonWidth) | |
frame.sidePanelExportButton.frame:SetNormalFontObject(fontInstance) | |
frame.sidePanelExportButton.frame:SetHighlightFontObject(fontInstance) | |
frame.sidePanelExportButton.frame:SetDisabledFontObject(fontInstance) | |
frame.sidePanelExportButton:SetCallback("OnClick",function(widget,callbackName,value) | |
if db.colorPaletteInfo.forceColorBlindMode then MDT:ColorAllPulls(_,_,_,true) end | |
local preset = MDT:GetCurrentPreset() | |
MDT:SetUniqueID(preset) | |
preset.mdiEnabled = db.MDI.enabled | |
preset.difficulty = db.currentDifficulty | |
local export = MDT:TableToString(preset,true,5) | |
MDT:HideAllDialogs() | |
MDT.main_frame.ExportFrame:Show() | |
MDT.main_frame.ExportFrame:ClearAllPoints() | |
MDT.main_frame.ExportFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50) | |
MDT.main_frame.ExportFrameEditbox:SetText(export) | |
MDT.main_frame.ExportFrameEditbox:HighlightText(0, string.len(export)) | |
MDT.main_frame.ExportFrameEditbox:SetFocus() | |
MDT.main_frame.ExportFrameEditbox:SetLabel(preset.text.." "..string.len(export)) | |
if db.colorPaletteInfo.forceColorBlindMode then MDT:ColorAllPulls() end | |
end) | |
frame.sidePanelExportButton.frame:SetScript("OnEnter",function() | |
GameTooltip:SetOwner(frame.sidePanelExportButton.frame, "ANCHOR_BOTTOMLEFT",frame.sidePanelExportButton.frame:GetWidth()*(-2),frame.sidePanelExportButton.frame:GetHeight()) | |
GameTooltip:AddLine(L["Export the preset as a text string"],1,1,1) | |
GameTooltip:AddLine(L["You can share MDT exports on the wago.io website"],1,1,1,1) | |
GameTooltip:Show() | |
end) | |
frame.sidePanelExportButton.frame:SetScript("OnLeave",function() | |
GameTooltip:Hide() | |
end) | |
frame.sidePanelDeleteButton = AceGUI:Create("Button") | |
frame.sidePanelDeleteButton:SetText(L["Delete"]) | |
frame.sidePanelDeleteButton:SetWidth(buttonWidth) | |
frame.sidePanelDeleteButton.frame:SetScript("OnEnter",function() | |
GameTooltip:SetOwner(frame.sidePanelDeleteButton.frame, "ANCHOR_BOTTOMLEFT",frame.sidePanelDeleteButton.frame:GetWidth()*(-2),frame.sidePanelDeleteButton.frame:GetHeight()) | |
GameTooltip:AddLine(L["Delete this preset"],1,1,1) | |
GameTooltip:AddLine(L["Shift-Click to delete all presets for this dungeon"],1,1,1) | |
GameTooltip:Show() | |
end) | |
frame.sidePanelDeleteButton.frame:SetScript("OnLeave",function() | |
GameTooltip:Hide() | |
end) | |
frame.sidePanelDeleteButton.frame:SetNormalFontObject(fontInstance) | |
frame.sidePanelDeleteButton.frame:SetHighlightFontObject(fontInstance) | |
frame.sidePanelDeleteButton.frame:SetDisabledFontObject(fontInstance) | |
frame.sidePanelDeleteButton:SetCallback("OnClick",function(widget,callbackName,value) | |
if IsShiftKeyDown() then | |
--delete all profiles | |
local numPresets = self:CountPresets() | |
local prompt = string.format(L["deleteAllWarning"],"\n","\n",numPresets,"\n") | |
MDT:OpenConfirmationFrame(450,150,L["Delete ALL presets"],L["Delete"],prompt, MDT.DeleteAllPresets) | |
else | |
MDT:HideAllDialogs() | |
frame.DeleteConfirmationFrame:ClearAllPoints() | |
frame.DeleteConfirmationFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50) | |
local currentPresetName = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].text | |
frame.DeleteConfirmationFrame.label:SetText(string.format(L["Delete %s?"],currentPresetName)) | |
frame.DeleteConfirmationFrame:Show() | |
end | |
end) | |
frame.LinkToChatButton = AceGUI:Create("Button") | |
frame.LinkToChatButton:SetText(L["Share"]) | |
frame.LinkToChatButton:SetWidth(buttonWidth) | |
frame.LinkToChatButton.frame:SetNormalFontObject(fontInstance) | |
frame.LinkToChatButton.frame:SetHighlightFontObject(fontInstance) | |
frame.LinkToChatButton.frame:SetDisabledFontObject(fontInstance) | |
frame.LinkToChatButton:SetCallback("OnClick",function(widget,callbackName,value) | |
local distribution = MDT:IsPlayerInGroup() | |
if not distribution then return end | |
local callback = function() | |
frame.LinkToChatButton:SetDisabled(true) | |
frame.LinkToChatButton.text:SetTextColor(0.5,0.5,0.5) | |
frame.LiveSessionButton:SetDisabled(true) | |
frame.LiveSessionButton.text:SetTextColor(0.5,0.5,0.5) | |
frame.LinkToChatButton:SetText("...") | |
frame.LiveSessionButton:SetText("...") | |
MDT:SendToGroup(distribution) | |
end | |
local presetSize = self:GetPresetSize(false,5) | |
if presetSize>25000 then | |
local prompt = string.format(L["LargePresetWarning"],presetSize,"\n","\n","\n") | |
MDT:OpenConfirmationFrame(450,150,L["Sharing large preset"],"Share",prompt, callback) | |
else | |
callback() | |
end | |
end) | |
frame.LinkToChatButton.frame:SetScript("OnEnter",function() | |
GameTooltip:SetOwner(frame.sidePanelDeleteButton.frame, "ANCHOR_BOTTOMLEFT",frame.LinkToChatButton.frame:GetWidth()*(-2),-frame.LinkToChatButton.frame:GetHeight()) | |
GameTooltip:AddLine(L["Share the preset with your party members"],1,1,1) | |
GameTooltip:Show() | |
end) | |
frame.LinkToChatButton.frame:SetScript("OnLeave",function() | |
GameTooltip:Hide() | |
end) | |
local inGroup = UnitInRaid("player") or IsInGroup() | |
MDT.main_frame.LinkToChatButton:SetDisabled(not inGroup) | |
if inGroup then | |
MDT.main_frame.LinkToChatButton.text:SetTextColor(1,0.8196,0) | |
else | |
MDT.main_frame.LinkToChatButton.text:SetTextColor(0.5,0.5,0.5) | |
end | |
frame.ClearPresetButton = AceGUI:Create("Button") | |
frame.ClearPresetButton:SetText(L["Reset"]) | |
frame.ClearPresetButton:SetWidth(buttonWidth) | |
frame.ClearPresetButton.frame:SetNormalFontObject(fontInstance) | |
frame.ClearPresetButton.frame:SetHighlightFontObject(fontInstance) | |
frame.ClearPresetButton.frame:SetDisabledFontObject(fontInstance) | |
frame.ClearPresetButton:SetCallback("OnClick",function(widget,callbackName,value) | |
MDT:OpenClearPresetDialog() | |
end) | |
frame.ClearPresetButton.frame:SetScript("OnEnter",function() | |
GameTooltip:SetOwner(frame.ClearPresetButton.frame, "ANCHOR_BOTTOMLEFT",frame.ClearPresetButton.frame:GetWidth()*(-0),frame.ClearPresetButton.frame:GetHeight()) | |
GameTooltip:AddLine(L["Reset the preset to the default state"],1,1,1) | |
GameTooltip:AddLine(L["Does not delete your drawings"],1,1,1) | |
GameTooltip:Show() | |
end) | |
frame.ClearPresetButton.frame:SetScript("OnLeave",function() | |
GameTooltip:Hide() | |
end) | |
frame.LiveSessionButton = AceGUI:Create("Button") | |
frame.LiveSessionButton:SetText(L["Live"]) | |
frame.LiveSessionButton:SetWidth(buttonWidth) | |
frame.LiveSessionButton.frame:SetNormalFontObject(fontInstance) | |
frame.LiveSessionButton.frame:SetHighlightFontObject(fontInstance) | |
frame.LiveSessionButton.frame:SetDisabledFontObject(fontInstance) | |
local c1,c2,c3 = frame.LiveSessionButton.text:GetTextColor() | |
frame.LiveSessionButton.normalTextColor = {r = c1,g = c2,b = c3,} | |
frame.LiveSessionButton:SetCallback("OnClick",function(widget,callbackName,value) | |
if MDT.liveSessionActive then | |
MDT:LiveSession_Disable() | |
else | |
MDT:LiveSession_Enable() | |
end | |
end) | |
frame.LiveSessionButton.frame:SetScript("OnEnter",function() | |
GameTooltip:SetOwner(frame.LiveSessionButton.frame, "ANCHOR_BOTTOMLEFT",frame.LiveSessionButton.frame:GetWidth()*(-1),frame.LiveSessionButton.frame:GetHeight()) | |
GameTooltip:AddLine(L["Start or join the current |cFF00FF00Live Session|r"],1,1,1) | |
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) | |
GameTooltip:AddLine(L["The preset will continuously synchronize between all party members participating in the Live Session"],1,1,1,1) | |
GameTooltip:AddLine(L["Players can join the live session by either clicking this button or the Live Session chat link"],1,1,1,1) | |
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) | |
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) | |
GameTooltip:Show() | |
end) | |
frame.LiveSessionButton.frame:SetScript("OnLeave",function() | |
GameTooltip:Hide() | |
end) | |
MDT.main_frame.LiveSessionButton:SetDisabled(not inGroup) | |
if inGroup then | |
MDT.main_frame.LiveSessionButton.text:SetTextColor(1,0.8196,0) | |
else | |
MDT.main_frame.LiveSessionButton.text:SetTextColor(0.5,0.5,0.5) | |
end | |
--MDI | |
frame.MDIButton = AceGUI:Create("Button") | |
frame.MDIButton:SetText("MDI") | |
frame.MDIButton:SetWidth(buttonWidth) | |
frame.MDIButton.frame:SetNormalFontObject(fontInstance) | |
frame.MDIButton.frame:SetHighlightFontObject(fontInstance) | |
frame.MDIButton.frame:SetDisabledFontObject(fontInstance) | |
frame.MDIButton:SetCallback("OnClick",function(widget,callbackName,value) | |
MDT:ToggleMDIMode() | |
end) | |
frame.MDIButton.frame:SetScript("OnEnter",function() | |
GameTooltip:SetOwner(frame.MDIButton.frame, "ANCHOR_BOTTOMLEFT",frame.MDIButton.frame:GetWidth()*(-2),frame.MDIButton.frame:GetHeight()) | |
GameTooltip:AddLine(L["Open MDI override options"],1,1,1) | |
GameTooltip:Show() | |
end) | |
frame.MDIButton.frame:SetScript("OnLeave",function() | |
end) | |
--AutomaticColorsCheckbox | |
frame.AutomaticColorsCheckSidePanel = AceGUI:Create("CheckBox") | |
frame.AutomaticColorsCheckSidePanel:SetLabel(L["Automatically color pulls"]) | |
frame.AutomaticColorsCheckSidePanel:SetValue(db.colorPaletteInfo.autoColoring) | |
frame.AutomaticColorsCheckSidePanel:SetCallback("OnValueChanged",function(widget,callbackName,value) | |
db.colorPaletteInfo.autoColoring = value | |
MDT:SetPresetColorPaletteInfo() | |
frame.AutomaticColorsCheck:SetValue(db.colorPaletteInfo.autoColoring) | |
if value == true then | |
frame.toggleForceColorBlindMode:SetDisabled(false) | |
MDT:ColorAllPulls() | |
MDT.main_frame.AutomaticColorsCogwheel:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\helpIconRnbw") | |
else | |
frame.toggleForceColorBlindMode:SetDisabled(true) | |
MDT.main_frame.AutomaticColorsCogwheel:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\helpIconGrey") | |
end | |
end) | |
--AutomaticColorsCogwheel | |
frame.AutomaticColorsCogwheel = AceGUI:Create("Icon") | |
local colorCogwheel = frame.AutomaticColorsCogwheel | |
colorCogwheel:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\helpIconRnbw") | |
colorCogwheel:SetImageSize(25,25) | |
colorCogwheel:SetWidth(35) | |
colorCogwheel:SetCallback("OnEnter",function(...) | |
GameTooltip:SetOwner(colorCogwheel.frame, "ANCHOR_CURSOR") | |
GameTooltip:AddLine(L["Click to adjust color settings"],1,1,1) | |
GameTooltip:Show() | |
end) | |
colorCogwheel:SetCallback("OnLeave",function(...) | |
GameTooltip:Hide() | |
end) | |
colorCogwheel:SetCallback("OnClick",function(...) | |
self:OpenAutomaticColorsDialog() | |
end) | |
frame.sidePanel.WidgetGroup:AddChild(frame.sidePanelNewButton) | |
frame.sidePanel.WidgetGroup:AddChild(frame.sidePanelRenameButton) | |
frame.sidePanel.WidgetGroup:AddChild(frame.sidePanelDeleteButton) | |
frame.sidePanel.WidgetGroup:AddChild(frame.ClearPresetButton) | |
frame.sidePanel.WidgetGroup:AddChild(frame.sidePanelImportButton) | |
frame.sidePanel.WidgetGroup:AddChild(frame.sidePanelExportButton) | |
frame.sidePanel.WidgetGroup:AddChild(frame.LinkToChatButton) | |
frame.sidePanel.WidgetGroup:AddChild(frame.LiveSessionButton) | |
frame.sidePanel.WidgetGroup:AddChild(frame.MDIButton) | |
frame.sidePanel.WidgetGroup:AddChild(frame.AutomaticColorsCheckSidePanel) | |
frame.sidePanel.WidgetGroup:AddChild(frame.AutomaticColorsCogwheel) | |
--Week Dropdown (Infested / Affixes) | |
local function makeAffixString(week,affixes,longText) | |
local ret | |
local sep = "" | |
for _,affixID in ipairs(affixes) do | |
local name, _, filedataid = C_ChallengeMode.GetAffixInfo(affixID) | |
name = name or "Unknown" | |
filedataid = filedataid or 134400 --questionmark | |
if longText then | |
ret = ret or "" | |
ret = ret..sep..name | |
sep = ", " | |
else | |
ret = ret or week..(week>9 and ". " or ". ") | |
if week == MDT:GetCurrentAffixWeek() then | |
ret = WrapTextInColorCode(ret, "FF00FF00") | |
end | |
ret = ret..CreateTextureMarkup(filedataid, 64, 64, 20, 20, 0.1, 0.9, 0.1, 0.9,0,0).." " | |
end | |
end | |
return ret | |
end | |
frame.sidePanel.affixDropdown = AceGUI:Create("Dropdown") | |
local affixDropdown = frame.sidePanel.affixDropdown | |
affixDropdown.text:SetJustifyH("LEFT") | |
affixDropdown:SetLabel(L["Affixes"]) | |
function affixDropdown:UpdateAffixList() | |
local affixWeekMarkups = {} | |
for week,affixes in ipairs(affixWeeks) do | |
tinsert(affixWeekMarkups,makeAffixString(week,affixes)) | |
end | |
local order = {1,2,3,4,5,6,7,8,9,10,11,12} | |
affixDropdown:SetList(affixWeekMarkups,order) | |
--mouseover list items | |
for itemIdx,item in ipairs(affixDropdown.pullout.items) do | |
item:SetOnEnter(function() | |
GameTooltip:SetOwner(item.frame, "ANCHOR_LEFT",-11,-25) | |
local v = affixWeeks[itemIdx] | |
GameTooltip:SetText(makeAffixString(itemIdx,v,true),1,1,1,1) | |
GameTooltip:Show() | |
end) | |
item:SetOnLeave(function() | |
GameTooltip:Hide() | |
end) | |
end | |
end | |
function affixDropdown:SetAffixWeek(key,ignoreReloadPullButtons,ignoreUpdateProgressBar) | |
affixDropdown:SetValue(key) | |
if not MDT:GetCurrentAffixWeek() then | |
frame.sidePanel.affixWeekWarning.image:Hide() | |
frame.sidePanel.affixWeekWarning:SetDisabled(true) | |
elseif MDT:GetCurrentAffixWeek() == key then | |
frame.sidePanel.affixWeekWarning.image:Hide() | |
frame.sidePanel.affixWeekWarning:SetDisabled(true) | |
else | |
frame.sidePanel.affixWeekWarning.image:Show() | |
frame.sidePanel.affixWeekWarning:SetDisabled(false) | |
end | |
MDT:GetCurrentPreset().week = key | |
local teeming = MDT:IsPresetTeeming(MDT:GetCurrentPreset()) | |
MDT:GetCurrentPreset().value.teeming = teeming | |
if MDT.EnemyInfoFrame and MDT.EnemyInfoFrame.frame:IsShown() then MDT:UpdateEnemyInfoData() end | |
MDT:UpdateMap(nil,ignoreReloadPullButtons,ignoreUpdateProgressBar) | |
end | |
affixDropdown:SetCallback("OnValueChanged",function(widget,callbackName,key) | |
affixDropdown:SetAffixWeek(key) | |
if MDT.liveSessionActive and MDT:GetCurrentPreset().uid == MDT.livePresetUID then | |
MDT:LiveSession_SendAffixWeek(key) | |
end | |
end) | |
affixDropdown:SetCallback("OnEnter",function(...) | |
local selectedWeek = affixDropdown:GetValue() | |
if not selectedWeek then return end | |
GameTooltip:SetOwner(affixDropdown.frame, "ANCHOR_LEFT",-6,-41) | |
local v = affixWeeks[selectedWeek] | |
GameTooltip:SetText(makeAffixString(selectedWeek,v,true),1,1,1,1) | |
GameTooltip:Show() | |
end) | |
affixDropdown:SetCallback("OnLeave",function(...) | |
GameTooltip:Hide() | |
end) | |
frame.sidePanel.WidgetGroup:AddChild(affixDropdown) | |
--affix not current week warning | |
frame.sidePanel.affixWeekWarning = AceGUI:Create("Icon") | |
local affixWeekWarning = frame.sidePanel.affixWeekWarning | |
affixWeekWarning:SetImage("Interface\\DialogFrame\\UI-Dialog-Icon-AlertNew") | |
affixWeekWarning:SetImageSize(25,25) | |
affixWeekWarning:SetWidth(35) | |
affixWeekWarning:SetCallback("OnEnter",function(...) | |
GameTooltip:SetOwner(affixDropdown.frame, "ANCHOR_CURSOR") | |
GameTooltip:AddLine(L["The selected affixes are not the ones of the current week"],1,1,1) | |
GameTooltip:AddLine(L["Click to switch to current week"],1,1,1) | |
GameTooltip:Show() | |
end) | |
affixWeekWarning:SetCallback("OnLeave",function(...) | |
GameTooltip:Hide() | |
end) | |
affixWeekWarning:SetCallback("OnClick",function(...) | |
if not MDT:GetCurrentAffixWeek() then return end | |
affixDropdown:SetAffixWeek(MDT:GetCurrentAffixWeek()) | |
if MDT.liveSessionActive and MDT:GetCurrentPreset().uid == MDT.livePresetUID then | |
MDT:LiveSession_SendAffixWeek(MDT:GetCurrentAffixWeek()) | |
end | |
end) | |
affixWeekWarning.image:Hide() | |
affixWeekWarning:SetDisabled(true) | |
frame.sidePanel.WidgetGroup:AddChild(affixWeekWarning) | |
--difficulty slider | |
frame.sidePanel.DifficultySlider = AceGUI:Create("Slider") | |
frame.sidePanel.DifficultySlider:SetSliderValues(1,35,1) | |
frame.sidePanel.DifficultySlider:SetLabel(L["Dungeon Level"]) | |
frame.sidePanel.DifficultySlider.label:SetJustifyH("LEFT") | |
frame.sidePanel.DifficultySlider.label:SetFontObject("GameFontNormalSmall") | |
frame.sidePanel.DifficultySlider:SetWidth(200) | |
frame.sidePanel.DifficultySlider:SetValue(db.currentDifficulty) | |
local timer | |
frame.sidePanel.DifficultySlider:SetCallback("OnValueChanged",function(widget,callbackName,value) | |
local difficulty = tonumber(value) | |
if (difficulty>=10 and db.currentDifficulty<10) or (difficulty<10 and db.currentDifficulty>=10) then | |
db.currentDifficulty = difficulty or db.currentDifficulty | |
MDT:DungeonEnemies_UpdateSeasonalAffix() | |
frame.sidePanel.difficultyWarning:Toggle(difficulty) | |
MDT:POI_UpdateAll() | |
MDT:KillAllAnimatedLines() | |
MDT:DrawAllAnimatedLines() | |
else | |
db.currentDifficulty = difficulty or db.currentDifficulty | |
end | |
MDT:GetCurrentPreset().difficulty = db.currentDifficulty | |
MDT:UpdateProgressbar() | |
if MDT.EnemyInfoFrame and MDT.EnemyInfoFrame.frame:IsShown() then MDT:UpdateEnemyInfoData() end | |
if timer then timer:Cancel() end | |
timer = C_Timer.NewTimer(2, function() | |
MDT:ReloadPullButtons() | |
if MDT.liveSessionActive then | |
local livePreset = MDT:GetCurrentLivePreset() | |
local shouldUpdate = livePreset == MDT:GetCurrentPreset() | |
if shouldUpdate then MDT:LiveSession_SendDifficulty() end | |
end | |
end) | |
end) | |
frame.sidePanel.DifficultySlider:SetCallback("OnMouseUp",function() | |
if timer then timer:Cancel() end | |
MDT:ReloadPullButtons() | |
if MDT.liveSessionActive then | |
local livePreset = MDT:GetCurrentLivePreset() | |
local shouldUpdate = livePreset == MDT:GetCurrentPreset() | |
if shouldUpdate then MDT:LiveSession_SendDifficulty() end | |
end | |
end) | |
frame.sidePanel.DifficultySlider:SetCallback("OnEnter",function() | |
GameTooltip:SetOwner(frame.sidePanel.DifficultySlider.frame, "ANCHOR_BOTTOMLEFT",0,40) | |
GameTooltip:AddLine(L["Select the dungeon level"],1,1,1) | |
GameTooltip:AddLine(L["The selected level will affect displayed npc health"],1,1,1) | |
GameTooltip:AddLine(L["Levels below 10 will hide enemies related to seasonal affixes"],1,1,1) | |
GameTooltip:Show() | |
end) | |
frame.sidePanel.DifficultySlider:SetCallback("OnLeave",function() | |
GameTooltip:Hide() | |
end) | |
frame.sidePanel.WidgetGroup:AddChild(frame.sidePanel.DifficultySlider) | |
--dungeon level below 10 warning | |
frame.sidePanel.difficultyWarning = AceGUI:Create("Icon") | |
local difficultyWarning = frame.sidePanel.difficultyWarning | |
difficultyWarning:SetImage("Interface\\DialogFrame\\UI-Dialog-Icon-AlertNew") | |
difficultyWarning:SetImageSize(25,25) | |
difficultyWarning:SetWidth(35) | |
difficultyWarning:SetCallback("OnEnter",function(...) | |
GameTooltip:SetOwner(frame.sidePanel.DifficultySlider.frame, "ANCHOR_CURSOR") | |
GameTooltip:AddLine(L["The selected dungeon level is below 10"],1,1,1) | |
GameTooltip:AddLine(L["Enemies related to seasonal affixes are currently hidden"],1,1,1) | |
GameTooltip:AddLine(L["Click to set dungeon level to 10"],1,1,1) | |
GameTooltip:Show() | |
end) | |
difficultyWarning:SetCallback("OnLeave",function(...) | |
GameTooltip:Hide() | |
end) | |
difficultyWarning:SetCallback("OnClick",function(...) | |
frame.sidePanel.DifficultySlider:SetValue(10) | |
db.currentDifficulty = 10 | |
MDT:GetCurrentPreset().difficulty = db.currentDifficulty | |
MDT:DungeonEnemies_UpdateSeasonalAffix() | |
MDT:POI_UpdateAll() | |
MDT:UpdateProgressbar() | |
MDT:ReloadPullButtons() | |
difficultyWarning:Toggle(db.currentDifficulty) | |
if MDT.liveSessionActive then | |
local livePreset = MDT:GetCurrentLivePreset() | |
local shouldUpdate = livePreset == MDT:GetCurrentPreset() | |
if shouldUpdate then MDT:LiveSession_SendDifficulty() end | |
end | |
MDT:KillAllAnimatedLines() | |
MDT:DrawAllAnimatedLines() | |
end) | |
function difficultyWarning:Toggle(difficulty) | |
if difficulty<10 then | |
self.image:Show() | |
self:SetDisabled(false) | |
else | |
self.image:Hide() | |
self:SetDisabled(true) | |
end | |
end | |
difficultyWarning:Toggle(db.currentDifficulty) | |
frame.sidePanel.WidgetGroup:AddChild(difficultyWarning) | |
frame.sidePanel.middleLine = AceGUI:Create("Heading") | |
frame.sidePanel.middleLine:SetWidth(240) | |
frame.sidePanel.WidgetGroup:AddChild(frame.sidePanel.middleLine) | |
frame.sidePanel.WidgetGroup.frame:SetFrameLevel(3) | |
--progress bar | |
frame.sidePanel.ProgressBar = CreateFrame("Frame", nil, frame.sidePanel, "ScenarioTrackerProgressBarTemplate") | |
frame.sidePanel.ProgressBar:Show() | |
frame.sidePanel.ProgressBar:ClearAllPoints() | |
frame.sidePanel.ProgressBar:SetPoint("TOP",frame.sidePanel.WidgetGroup.frame,"BOTTOM",-10,5) | |
MDT:SkinProgressBar(frame.sidePanel.ProgressBar) | |
end | |
---ToggleMDIMode | |
---Enables display to override beguiling+freehold week | |
function MDT:ToggleMDIMode() | |
db.MDI.enabled = not db.MDI.enabled | |
self:DisplayMDISelector() | |
if self.liveSessionActive then self:LiveSession_SendMDI("toggle",db.MDI.enabled and "1" or "0") end | |
end | |
function MDT:DisplayMDISelector() | |
local show = db.MDI.enabled | |
db = MDT:GetDB() | |
if not MDT.MDISelector then | |
MDT.MDISelector = AceGUI:Create("SimpleGroup") | |
MDT.MDISelector.frame:SetFrameStrata("HIGH") | |
MDT.MDISelector.frame:SetFrameLevel(50) | |
if not MDT.MDISelector.frame.SetBackdrop then | |
Mixin(MDT.MDISelector.frame, BackdropTemplateMixin) | |
end | |
MDT.MDISelector.frame:SetBackdropColor(unpack(MDT.BackdropColor)) | |
--fix show hide | |
local frame = MDT.main_frame | |
local originalShow,originalHide = frame.Show,frame.Hide | |
local widget = MDT.MDISelector.frame | |
function frame:Hide(...) | |
widget:Hide() | |
return originalHide(self, ...) | |
end | |
function frame:Show(...) | |
if db.MDI.enabled then widget:Show() end | |
return originalShow(self, ...) | |
end | |
MDT.MDISelector:SetLayout("Flow") | |
MDT.MDISelector.frame.bg = MDT.MDISelector.frame:CreateTexture(nil, "BACKGROUND") | |
MDT.MDISelector.frame.bg:SetAllPoints(MDT.MDISelector.frame) | |
MDT.MDISelector.frame.bg:SetColorTexture(unpack(MDT.BackdropColor)) | |
MDT.MDISelector:SetWidth(145) | |
MDT.MDISelector:SetHeight(90) | |
MDT.MDISelector.frame:ClearAllPoints() | |
MDT.MDISelector.frame:SetPoint("BOTTOMRIGHT", MDT.main_frame,"BOTTOMRIGHT",0,0) | |
local label = AceGUI:Create("Label") | |
label:SetText(L["MDI Mode"]) | |
MDT.MDISelector:AddChild(label) | |
--beguiling | |
MDT.MDISelector.BeguilingDropDown = AceGUI:Create("Dropdown") | |
MDT.MDISelector.BeguilingDropDown:SetLabel(L["Seasonal Affix:"]) | |
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"]} | |
MDT.MDISelector.BeguilingDropDown:SetList(beguilingList) | |
MDT.MDISelector.BeguilingDropDown:SetCallback("OnValueChanged",function(widget, callbackName, key) | |
local preset = self:GetCurrentPreset() | |
preset.mdi.beguiling = key | |
db.currentSeason = self:GetEffectivePresetSeason(preset) | |
self:UpdateMap() | |
if self.liveSessionActive and preset.uid == self.livePresetUID then | |
self:LiveSession_SendMDI("beguiling",key) | |
end | |
end) | |
MDT.MDISelector:AddChild(MDT.MDISelector.BeguilingDropDown) | |
--freehold | |
MDT.MDISelector.FreeholdDropDown = AceGUI:Create("Dropdown") | |
MDT.MDISelector.FreeholdDropDown:SetLabel(L["Freehold:"]) | |
local freeholdList = {string.format("1. %s",L["Cutwater"]),string.format("2. %s",L["Blacktooth"]),string.format("3. %s",L["Bilge Rats"])} | |
MDT.MDISelector.FreeholdDropDown:SetList(freeholdList) | |
MDT.MDISelector.FreeholdDropDown:SetCallback("OnValueChanged",function(widget, callbackName, key) | |
local preset = MDT:GetCurrentPreset() | |
preset.mdi.freehold = key | |
if preset.mdi.freeholdJoined then | |
MDT:DungeonEnemies_UpdateFreeholdCrew(preset.mdi.freehold) | |
end | |
MDT:DungeonEnemies_UpdateBlacktoothEvent() | |
MDT:UpdateProgressbar() | |
MDT:ReloadPullButtons() | |
if self.liveSessionActive and self:GetCurrentPreset().uid == self.livePresetUID then | |
self:LiveSession_SendMDI("freehold",key) | |
end | |
end) | |
MDT.MDISelector:AddChild(MDT.MDISelector.FreeholdDropDown) | |
MDT.MDISelector.FreeholdCheck = AceGUI:Create("CheckBox") | |
MDT.MDISelector.FreeholdCheck:SetLabel(L["Join Crew"]) | |
MDT.MDISelector.FreeholdCheck:SetCallback("OnValueChanged",function(widget, callbackName, value) | |
local preset = MDT:GetCurrentPreset() | |
preset.mdi.freeholdJoined = value | |
MDT:DungeonEnemies_UpdateFreeholdCrew() | |
MDT:ReloadPullButtons() | |
MDT:UpdateProgressbar() | |
if self.liveSessionActive and self:GetCurrentPreset().uid == self.livePresetUID then | |
self:LiveSession_SendMDI("join",value and "1" or "0") | |
end | |
end) | |
MDT.MDISelector:AddChild(MDT.MDISelector.FreeholdCheck) | |
end | |
if show then | |
local preset = MDT:GetCurrentPreset() | |
preset.mdi = preset.mdi or {} | |
--beguiling | |
preset.mdi.beguiling = preset.mdi.beguiling or 1 | |
MDT.MDISelector.BeguilingDropDown:SetValue(preset.mdi.beguiling) | |
db.currentSeason = MDT:GetEffectivePresetSeason(preset) | |
MDT:DungeonEnemies_UpdateSeasonalAffix() | |
MDT:DungeonEnemies_UpdateBoralusFaction(MDT:GetCurrentPreset().faction) | |
--freehold | |
preset.mdi.freehold = preset.mdi.freehold or 1 | |
MDT.MDISelector.FreeholdDropDown:SetValue(preset.mdi.freehold) | |
preset.mdi.freeholdJoined = preset.mdi.freeholdJoined or false | |
MDT.MDISelector.FreeholdCheck:SetValue(preset.mdi.freeholdJoined) | |
MDT:DungeonEnemies_UpdateFreeholdCrew() | |
MDT:DungeonEnemies_UpdateBlacktoothEvent() | |
MDT:UpdateProgressbar() | |
MDT:ReloadPullButtons() | |
MDT.MDISelector.frame:Show() | |
MDT:ToggleFreeholdSelector(false) | |
else | |
db.currentSeason = defaultSavedVars.global.currentSeason | |
MDT:DungeonEnemies_UpdateSeasonalAffix() | |
MDT:DungeonEnemies_UpdateBoralusFaction(MDT:GetCurrentPreset().faction) | |
MDT:UpdateFreeholdSelector(MDT:GetCurrentPreset().week) | |
MDT:DungeonEnemies_UpdateBlacktoothEvent() | |
MDT:UpdateProgressbar() | |
MDT:ReloadPullButtons() | |
MDT.MDISelector.frame:Hide() | |
MDT:ToggleFreeholdSelector(db.currentDungeonIdx == 16) | |
end | |
MDT:POI_UpdateAll() | |
MDT:KillAllAnimatedLines() | |
MDT:DrawAllAnimatedLines() | |
end | |
function MDT:UpdatePresetDropDown() | |
local dropdown = MDT.main_frame.sidePanel.WidgetGroup.PresetDropDown | |
local presetList = {} | |
for k,v in pairs(db.presets[db.currentDungeonIdx]) do | |
table.insert(presetList,k,v.text) | |
end | |
dropdown:SetList(presetList) | |
dropdown:SetValue(db.currentPreset[db.currentDungeonIdx]) | |
dropdown:ClearFocus() | |
end | |
function MDT:UpdatePresetDropdownTextColor(forceReset) | |
local preset = self:GetCurrentPreset() | |
local livePreset = self:GetCurrentLivePreset() | |
if self.liveSessionActive and preset == livePreset and (not forceReset) then | |
local dropdown = MDT.main_frame.sidePanel.WidgetGroup.PresetDropDown | |
dropdown.text:SetTextColor(0,1,0,1) | |
else | |
local dropdown = MDT.main_frame.sidePanel.WidgetGroup.PresetDropDown | |
dropdown.text:SetTextColor(1,1,1,1) | |
end | |
end | |
---FormatEnemyForces | |
function MDT:FormatEnemyForces(forces, forcesmax, progressbar) | |
if not forcesmax then forcesmax = MDT:IsCurrentPresetTeeming() and MDT.dungeonTotalCount[db.currentDungeonIdx].teeming or MDT.dungeonTotalCount[db.currentDungeonIdx].normal end | |
if db.enemyForcesFormat == 1 then | |
if progressbar then return forces.."/"..forcesmax end | |
return forces | |
elseif db.enemyForcesFormat == 2 then | |
if progressbar then return string.format((forces.."/"..forcesmax.." (%.2f%%)"),(forces/forcesmax)*100) end | |
return string.format(forces.." (%.2f%%)",(forces/forcesmax)*100) | |
end | |
end | |
---Progressbar_SetValue | |
---Sets the value/progress/color of the count progressbar to the apropriate data | |
function MDT:Progressbar_SetValue(self, totalCurrent, totalMax) | |
local percent = (totalCurrent/totalMax)*100 | |
if percent >= 102 then | |
if totalCurrent-totalMax > 8 then | |
self.Bar:SetStatusBarColor(1,0,0,1) | |
else | |
self.Bar:SetStatusBarColor(0,1,0,1) | |
end | |
elseif percent >= 100 then | |
self.Bar:SetStatusBarColor(0,1,0,1) | |
else | |
self.Bar:SetStatusBarColor(0.26,0.42,1) | |
end | |
self.Bar:SetValue(percent) | |
self.Bar.Label:SetText(MDT:FormatEnemyForces(totalCurrent,totalMax,true)) | |
self.AnimValue = percent | |
end | |
---UpdateProgressbar | |
---Update the progressbar on the sidepanel with the correct values | |
function MDT:UpdateProgressbar() | |
local teeming = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.teeming | |
MDT:EnsureDBTables() | |
local grandTotal = MDT:CountForces() | |
MDT:Progressbar_SetValue(MDT.main_frame.sidePanel.ProgressBar,grandTotal,teeming==true and MDT.dungeonTotalCount[db.currentDungeonIdx].teeming or MDT.dungeonTotalCount[db.currentDungeonIdx].normal) | |
end | |
function MDT:OnPan(cursorX, cursorY) | |
local scrollFrame = MDTScrollFrame | |
local scale = MDTMapPanelFrame:GetScale()/1.5 | |
local deltaX = (scrollFrame.cursorX - cursorX)/scale | |
local deltaY = (cursorY - scrollFrame.cursorY)/scale | |
if(scrollFrame.panning)then | |
local newHorizontalPosition = max(0, deltaX + scrollFrame:GetHorizontalScroll()) | |
newHorizontalPosition = min(newHorizontalPosition, scrollFrame.maxX) | |
local newVerticalPosition = max(0, deltaY + scrollFrame:GetVerticalScroll()) | |
newVerticalPosition = min(newVerticalPosition, scrollFrame.maxY) | |
scrollFrame:SetHorizontalScroll(newHorizontalPosition) | |
scrollFrame:SetVerticalScroll(newVerticalPosition) | |
scrollFrame.cursorX = cursorX | |
scrollFrame.cursorY = cursorY | |
scrollFrame.wasPanningLastFrame = true; | |
scrollFrame.lastDeltaX = deltaX; | |
scrollFrame.lastDeltaY = deltaY; | |
else | |
if(scrollFrame.wasPanningLastFrame)then | |
scrollFrame.isFadeOutPanning = true | |
scrollFrame.fadeOutXStart = scrollFrame.lastDeltaX | |
scrollFrame.fadeOutYStart = scrollFrame.lastDeltaY | |
scrollFrame.panDuration = 0 | |
scrollFrame.wasPanningLastFrame = false; | |
end | |
end | |
end | |
function MDT:OnPanFadeOut(deltaTime) | |
local scrollFrame = MDTScrollFrame | |
local panDuration = 0.5 | |
local panAtenuation = 7 | |
if(scrollFrame.isFadeOutPanning)then | |
scrollFrame.panDuration = scrollFrame.panDuration + deltaTime | |
local phase = scrollFrame.panDuration / panDuration | |
local phaseLog = -math.log(phase) | |
local stepX = (scrollFrame.fadeOutXStart * phaseLog) / panAtenuation | |
local stepY = (scrollFrame.fadeOutYStart * phaseLog) / panAtenuation | |
local newHorizontalPosition = max(0, stepX + scrollFrame:GetHorizontalScroll()) | |
newHorizontalPosition = min(newHorizontalPosition, scrollFrame.maxX) | |
local newVerticalPosition = max(0, stepY + scrollFrame:GetVerticalScroll()) | |
newVerticalPosition = min(newVerticalPosition, scrollFrame.maxY) | |
scrollFrame:SetHorizontalScroll(newHorizontalPosition) | |
scrollFrame:SetVerticalScroll(newVerticalPosition) | |
if(scrollFrame.panDuration > panDuration)then | |
scrollFrame.isFadeOutPanning = false | |
end | |
end | |
end | |
function MDT:ExportCurrentZoomPanSettings() | |
local mainFrame = MDTMapPanelFrame | |
local scrollFrame = MDTScrollFrame | |
local zoom = MDTMapPanelFrame:GetScale() | |
local panH = MDTScrollFrame:GetHorizontalScroll() / MDT:GetScale() | |
local panV = MDTScrollFrame:GetVerticalScroll() / MDT:GetScale() | |
local output = " ["..db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel.."] = {\n" | |
output = output.." zoomScale = "..zoom..";\n" | |
output = output.." horizontalPan = "..panH..";\n" | |
output = output.." verticalPan = "..panV..";\n" | |
output = output.." };\n" | |
MDT:HideAllDialogs() | |
MDT.main_frame.ExportFrame:Show() | |
MDT.main_frame.ExportFrame:ClearAllPoints() | |
MDT.main_frame.ExportFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50) | |
MDT.main_frame.ExportFrameEditbox:SetText(output) | |
MDT.main_frame.ExportFrameEditbox:HighlightText(0, string.len(output)) | |
MDT.main_frame.ExportFrameEditbox:SetFocus() | |
MDT.main_frame.ExportFrameEditbox:SetLabel("Current pan/zoom settings"); | |
end | |
function MDT:ZoomMapToDefault() | |
local currentMap = db.presets[db.currentDungeonIdx] | |
local currentSublevel = currentMap[db.currentPreset[db.currentDungeonIdx]].value.currentSublevel | |
local mainFrame = MDTMapPanelFrame | |
local scrollFrame = MDTScrollFrame | |
local currentMapInfo = MDT.mapInfo[db.currentDungeonIdx] | |
if(currentMapInfo and currentMapInfo.viewportPositionOverrides and currentMapInfo.viewportPositionOverrides[currentSublevel])then | |
local data = currentMapInfo.viewportPositionOverrides[currentSublevel]; | |
local scaledSizeX = mainFrame:GetWidth() * data.zoomScale | |
local scaledSizeY = mainFrame:GetHeight() * data.zoomScale | |
scrollFrame.maxX = (scaledSizeX - mainFrame:GetWidth()) / data.zoomScale | |
scrollFrame.maxY = (scaledSizeY - mainFrame:GetHeight()) / data.zoomScale | |
scrollFrame.zoomedIn = abs(data.zoomScale - 1) > 0.02 | |
mainFrame:SetScale(data.zoomScale) | |
scrollFrame:SetHorizontalScroll(data.horizontalPan * MDT:GetScale()) | |
scrollFrame:SetVerticalScroll(data.verticalPan * MDT:GetScale()) | |
else | |
scrollFrame.maxX = 1 | |
scrollFrame.maxY = 1 | |
scrollFrame.zoomedIn = false | |
mainFrame:SetScale(1); | |
scrollFrame:SetHorizontalScroll(0) | |
scrollFrame:SetVerticalScroll(0) | |
end | |
end | |
function MDT:ZoomMap(delta) | |
local scrollFrame = MDTScrollFrame | |
if not scrollFrame:GetLeft() then return end | |
local oldScrollH = scrollFrame:GetHorizontalScroll() | |
local oldScrollV = scrollFrame:GetVerticalScroll() | |
local mainFrame = MDTMapPanelFrame | |
local oldScale = mainFrame:GetScale() | |
local newScale = oldScale + delta * 0.3 | |
newScale = max(1, newScale) | |
newScale = min(15, newScale) | |
mainFrame:SetScale(newScale) | |
local scaledSizeX = mainFrame:GetWidth() * newScale | |
local scaledSizeY = mainFrame:GetHeight() * newScale | |
scrollFrame.maxX = (scaledSizeX - mainFrame:GetWidth()) / newScale | |
scrollFrame.maxY = (scaledSizeY - mainFrame:GetHeight()) / newScale | |
scrollFrame.zoomedIn = abs(newScale - 1) > 0.02 | |
local cursorX,cursorY = GetCursorPosition() | |
local frameX = (cursorX / UIParent:GetScale()) - scrollFrame:GetLeft() | |
local frameY = scrollFrame:GetTop() - (cursorY / UIParent:GetScale()) | |
local scaleChange = newScale / oldScale | |
local newScrollH = (scaleChange * frameX - frameX) / newScale + oldScrollH | |
local newScrollV = (scaleChange * frameY - frameY) / newScale + oldScrollV | |
newScrollH = min(newScrollH, scrollFrame.maxX) | |
newScrollH = max(0, newScrollH) | |
newScrollV = min(newScrollV, scrollFrame.maxY) | |
newScrollV = max(0, newScrollV) | |
scrollFrame:SetHorizontalScroll(newScrollH) | |
scrollFrame:SetVerticalScroll(newScrollV) | |
MDT:SetPingOffsets(newScale) | |
end | |
---ActivatePullTooltip | |
--- | |
function MDT:ActivatePullTooltip(pull) | |
local pullTooltip = MDT.pullTooltip | |
--[[ | |
if not pullTooltip.ranOnce then | |
--fix elvui skinning | |
pullTooltip:SetPoint("TOPRIGHT",UIParent,"BOTTOMRIGHT") | |
pullTooltip:SetPoint("BOTTOMRIGHT",UIParent,"BOTTOMRIGHT") | |
pullTooltip:Show() | |
pullTooltip.ranOnce = true | |
end | |
]] | |
pullTooltip.currentPull = pull | |
pullTooltip:Show() | |
end | |
---UpdatePullTooltip | |
---Updates the tooltip which is being displayed when a pull is mouseovered | |
function MDT:UpdatePullTooltip(tooltip) | |
local frame = MDT.main_frame | |
if not MouseIsOver(frame.sidePanel.pullButtonsScrollFrame.frame) then | |
tooltip:Hide() | |
elseif MouseIsOver(frame.sidePanel.newPullButton.frame) then | |
tooltip:Hide() | |
else | |
if frame.sidePanel.newPullButtons and tooltip.currentPull and frame.sidePanel.newPullButtons[tooltip.currentPull] then | |
--enemy portraits | |
local showData | |
for k,v in pairs(frame.sidePanel.newPullButtons[tooltip.currentPull].enemyPortraits) do | |
if MouseIsOver(v) then | |
if v:IsShown() then | |
--model | |
if v.enemyData.displayId and (not tooltip.modelNpcId or (tooltip.modelNpcId ~= v.enemyData.displayId)) then | |
tooltip.Model:SetDisplayInfo(v.enemyData.displayId) | |
tooltip.modelNpcId = v.enemyData.displayId | |
end | |
--topString | |
local newLine = "\n" | |
local text = newLine..newLine..newLine..L[v.enemyData.name].." x"..v.enemyData.quantity..newLine | |
text = text..string.format(L["Level %d %s"],v.enemyData.level,L[v.enemyData.creatureType])..newLine | |
local boss = v.enemyData.isBoss or false | |
local health = MDT:CalculateEnemyHealth(boss,v.enemyData.baseHealth,db.currentDifficulty,v.enemyData.ignoreFortified) | |
text = text.. string.format(L["%s HP"],MDT:FormatEnemyHealth(health))..newLine | |
local totalForcesMax = MDT:IsCurrentPresetTeeming() and MDT.dungeonTotalCount[db.currentDungeonIdx].teeming or MDT.dungeonTotalCount[db.currentDungeonIdx].normal | |
local count = MDT:IsCurrentPresetTeeming() and v.enemyData.teemingCount or v.enemyData.count | |
text = text..L["Forces"]..": ".. MDT:FormatEnemyForces(count,totalForcesMax,false) | |
tooltip.topString:SetText(text) | |
showData = true | |
end | |
break | |
end | |
end | |
if showData then | |
tooltip.topString:Show() | |
tooltip.Model:Show() | |
else | |
tooltip.topString:Hide() | |
tooltip.Model:Hide() | |
end | |
local countEnemies = 0 | |
for k,v in pairs(frame.sidePanel.newPullButtons[tooltip.currentPull].enemyPortraits) do | |
if v:IsShown() then countEnemies = countEnemies + 1 end | |
end | |
if countEnemies == 0 then | |
tooltip:Hide() | |
return | |
end | |
local pullForces = MDT:CountForces(tooltip.currentPull,true) | |
local totalForces = MDT:CountForces(tooltip.currentPull,false) | |
local totalForcesMax = MDT:IsCurrentPresetTeeming() and MDT.dungeonTotalCount[db.currentDungeonIdx].teeming or MDT.dungeonTotalCount[db.currentDungeonIdx].normal | |
local text = L["Forces"]..": ".. MDT:FormatEnemyForces(pullForces,totalForcesMax,false) | |
text = text.. "\n"..L["Total"]..": ".. MDT:FormatEnemyForces(totalForces,totalForcesMax,true) | |
tooltip.botString:SetText(text) | |
tooltip.botString:Show() | |
end | |
end | |
end | |
---CountForces | |
---Counts total selected enemy forces in the current preset up to pull | |
function MDT:CountForces(currentPull, currentOnly) | |
--count up to and including the currently selected pull | |
currentPull = currentPull or 1000 | |
local preset = self:GetCurrentPreset() | |
local teeming = self:IsCurrentPresetTeeming() | |
local pullCurrent = 0 | |
for pullIdx,pull in pairs(preset.value.pulls) do | |
if not currentOnly or (currentOnly and pullIdx == currentPull) then | |
if pullIdx <= currentPull then | |
for enemyIdx,clones in pairs(pull) do | |
if tonumber(enemyIdx) then | |
for k,v in pairs(clones) do | |
if MDT:IsCloneIncluded(enemyIdx,v) then | |
local count = teeming | |
and self.dungeonEnemies[db.currentDungeonIdx][enemyIdx].teemingCount | |
or self.dungeonEnemies[db.currentDungeonIdx][enemyIdx].count | |
pullCurrent = pullCurrent + count | |
end | |
end | |
end | |
end | |
else | |
break | |
end | |
end | |
end | |
return pullCurrent | |
end | |
local emissaryIds = {[155432]=true,[155433]=true,[155434]=true} | |
---Checks if the specified clone is part of the current map configuration | |
function MDT:IsCloneIncluded(enemyIdx, cloneIdx) | |
local preset = MDT:GetCurrentPreset() | |
local isCloneBlacktoothEvent = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][cloneIdx].blacktoothEvent | |
local cloneFaction = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][cloneIdx].faction | |
local week = self:GetEffectivePresetWeek() | |
if db.currentSeason ~= 3 then | |
if emissaryIds[MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx].id] then return false end | |
elseif db.currentSeason ~= 4 then | |
if MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx].corrupted then return false end | |
end | |
--beguiling weekly configuration | |
local weekData = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][cloneIdx].week | |
if weekData then | |
if weekData[week] and not (cloneFaction and cloneFaction~= preset.faction) and db.currentDifficulty >= 10 then | |
return true | |
else | |
return false | |
end | |
end | |
week = week%3 | |
if week == 0 then week = 3 end | |
local isBlacktoothWeek = week == 2 | |
if not isCloneBlacktoothEvent or isBlacktoothWeek then | |
if not (cloneFaction and cloneFaction~= preset.faction) then | |
local isCloneTeeming = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][cloneIdx].teeming | |
local isCloneNegativeTeeming = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][cloneIdx].negativeTeeming | |
if MDT:IsCurrentPresetTeeming() or ((isCloneTeeming and isCloneTeeming == false) or (not isCloneTeeming)) then | |
if not(MDT:IsCurrentPresetTeeming() and isCloneNegativeTeeming) then | |
return true | |
end | |
end | |
end | |
end | |
end | |
---IsCurrentPresetTeeming | |
---Returns true if the current preset has teeming turned on, false otherwise | |
function MDT:IsCurrentPresetTeeming() | |
--return self:GetCurrentPreset().week | |
return db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.teeming | |
end | |
---IsCurrentPresetFortified | |
function MDT:IsCurrentPresetFortified() | |
return self:GetCurrentPreset().week%2 == 1 | |
end | |
---IsCurrentPresetTyrannical | |
function MDT:IsCurrentPresetTyrannical() | |
return not MDT:IsCurrentPresetFortified() | |
end | |
---MouseDownHook | |
function MDT:MouseDownHook() | |
return | |
end | |
---Handles mouse-down events on the map scrollframe | |
MDT.OnMouseDown = function(self, button) | |
local scrollFrame = MDT.main_frame.scrollFrame | |
if scrollFrame.zoomedIn then | |
scrollFrame.panning = true | |
scrollFrame.cursorX,scrollFrame.cursorY = GetCursorPosition() | |
end | |
scrollFrame.oldX = scrollFrame.cursorX | |
scrollFrame.oldY = scrollFrame.cursorY | |
MDT:MouseDownHook() | |
end | |
---handles mouse-up events on the map scrollframe | |
MDT.OnMouseUp = function(self, button) | |
local scrollFrame = MDT.main_frame.scrollFrame | |
if scrollFrame.panning then scrollFrame.panning = false end | |
--play minimap ping on right click at cursor position | |
--only ping if we didnt pan | |
if scrollFrame.oldX==scrollFrame.cursorX or scrollFrame.oldY==scrollFrame.cursorY then | |
if button == "RightButton" then | |
local x,y = MDT:GetCursorPosition() | |
MDT:PingMap(x,y) | |
local sublevel = MDT:GetCurrentSubLevel() | |
if MDT.liveSessionActive then MDT:LiveSession_SendPing(x,y,sublevel) end | |
end | |
end | |
end | |
---Pings the map | |
function MDT:PingMap(x, y) | |
self.ping:ClearAllPoints() | |
self.ping:SetPoint("CENTER",self.main_frame.mapPanelTile1,"TOPLEFT",x,y) | |
self.ping:SetModel("interface/minimap/ping/minimapping.m2") | |
local mainFrame = MDTMapPanelFrame | |
local mapScale = mainFrame:GetScale() | |
self:SetPingOffsets(mapScale) | |
self.ping:Show() | |
UIFrameFadeOut(self.ping, 2, 1, 0) | |
self.ping:SetSequence(0) | |
end | |
function MDT:SetPingOffsets(mapScale) | |
local scale = 0.35 | |
local offset = (10.25/1000)*mapScale | |
MDT.ping:SetTransform(offset,offset,0,0,0,0,scale) | |
end | |
---SetCurrentSubLevel | |
---Sets the sublevel of the currently active preset, need to UpdateMap to reflect the change in UI | |
function MDT:SetCurrentSubLevel(sublevel) | |
MDT:GetCurrentPreset().value.currentSublevel = sublevel | |
end | |
---GetCurrentPull | |
---Returns the current pull of the currently active preset | |
function MDT:GetCurrentPull() | |
local selection = MDT:GetSelection() | |
return selection[#selection] | |
end | |
---GetCurrentSubLevel | |
---Returns the sublevel of the currently active preset | |
function MDT:GetCurrentSubLevel() | |
return MDT:GetCurrentPreset().value.currentSublevel | |
end | |
---GetCurrentPreset | |
---Returns the current preset | |
function MDT:GetCurrentPreset() | |
return db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]] | |
end | |
---GetCurrentLivePreset | |
function MDT:GetCurrentLivePreset() | |
if not self.livePresetUID then return end | |
if self.liveUpdateFrameOpen then | |
for fullName,cachedPreset in pairs(self.transmissionCache) do | |
if cachedPreset.uid == self.livePresetUID then | |
return cachedPreset | |
end | |
end | |
end | |
for dungeonIdx,presets in pairs(db.presets) do | |
for presetIdx,preset in pairs(presets) do | |
if preset.uid and preset.uid == self.livePresetUID then | |
return preset,presetIdx | |
end | |
end | |
end | |
end | |
---GetEffectivePresetWeek | |
function MDT:GetEffectivePresetWeek(preset) | |
preset = preset or self:GetCurrentPreset() | |
local week | |
if db.MDI.enabled then | |
week = preset.mdi.beguiling or 1 | |
if week == 14 then week = 1 end | |
if week == 15 then week = 3 end | |
else | |
week = preset.week | |
end | |
return week | |
end | |
---GetEffectivePresetSeason | |
function MDT:GetEffectivePresetSeason(preset) | |
local season = db.currentSeason | |
if db.MDI.enabled then | |
local mdiWeek = preset.mdi.beguiling | |
season = (mdiWeek == 1 or mdiWeek == 2 or mdiWeek == 3) and 3 or mdiWeek == 13 and 2 or (mdiWeek == 14 or mdiWeek == 15) and 4 | |
end | |
return season | |
end | |
---ReturnToLivePreset | |
function MDT:ReturnToLivePreset() | |
local preset,presetIdx = self:GetCurrentLivePreset() | |
self:UpdateToDungeon(preset.value.currentDungeonIdx,true) | |
db.currentPreset[db.currentDungeonIdx] = presetIdx | |
self:UpdatePresetDropDown() | |
self:UpdateMap() | |
end | |
---SetLivePreset | |
function MDT:SetLivePreset() | |
local preset = self:GetCurrentPreset() | |
self:SetUniqueID(preset) | |
self.livePresetUID = preset.uid | |
self:LiveSession_SendPreset(preset) | |
self:UpdatePresetDropdownTextColor() | |
self.main_frame.setLivePresetButton:Hide() | |
self.main_frame.liveReturnButton:Hide() | |
end | |
---IsWeekTeeming | |
---Returns if the current week has an affix week set that includes the teeming affix | |
function MDT:IsWeekTeeming(week) | |
if not week then week = MDT:GetCurrentAffixWeek() or 1 end | |
return affixWeeks[week][1] == 5 | |
end | |
---Returns if the current week has an affix weeks set that includes the inspiring affix | |
function MDT:IsWeekInspiring(week) | |
if not week then week = MDT:GetCurrentAffixWeek() or 1 end | |
return affixWeeks[week][1] == 122 or affixWeeks[week][2] == 122 | |
end | |
---IsPresetTeeming | |
---Returns if the preset is set to a week which contains the teeming affix | |
function MDT:IsPresetTeeming(preset) | |
return MDT:IsWeekTeeming(preset.week) | |
end | |
function MDT:GetRiftOffsets() | |
local week = self:GetEffectivePresetWeek() | |
local preset = self:GetCurrentPreset() | |
preset.value.riftOffsets = preset.value.riftOffsets or {} | |
local riftOffsets = preset.value.riftOffsets | |
riftOffsets[week] = riftOffsets[week] or {} | |
return riftOffsets[week] | |
end | |
function MDT:MakeMapTexture(frame) | |
MDT.contextMenuList = {} | |
tinsert(MDT.contextMenuList, { | |
text = "Close", | |
notCheckable = 1, | |
func = frame.contextDropdown:Hide() | |
}) | |
-- Scroll Frame | |
if frame.scrollFrame == nil then | |
frame.scrollFrame = CreateFrame("ScrollFrame", "MDTScrollFrame",frame) | |
frame.scrollFrame:ClearAllPoints() | |
frame.scrollFrame:SetSize(sizex*db.scale, sizey*db.scale) | |
--frame.scrollFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, 0) | |
frame.scrollFrame:SetAllPoints(frame) | |
-- Enable mousewheel scrolling | |
frame.scrollFrame:EnableMouseWheel(true) | |
local lastModifiedScroll | |
local ignoredTargets = {--ignore alt scroll if expansion would be changed | |
[14] = true, | |
[27] = true, | |
[28] = true, | |
[37] = true, | |
} | |
frame.scrollFrame:SetScript("OnMouseWheel", function(self, delta) | |
if IsControlKeyDown() then | |
if not lastModifiedScroll or lastModifiedScroll < GetTime() - 0.1 then | |
lastModifiedScroll = GetTime() | |
delta = delta*-1 | |
local target = MDT:GetCurrentSubLevel()+delta | |
if dungeonSubLevels[db.currentDungeonIdx][target] then | |
MDT:SetCurrentSubLevel(target) | |
MDT:UpdateMap() | |
MDT:ZoomMapToDefault() | |
end | |
end | |
elseif IsAltKeyDown() then | |
if not lastModifiedScroll or lastModifiedScroll < GetTime() - 0.3 then | |
lastModifiedScroll = GetTime() | |
delta = delta*-1 | |
local target = db.currentDungeonIdx+delta | |
if dungeonList[target] and not ignoredTargets[target] then | |
local group = MDT.main_frame.DungeonSelectionGroup | |
group.DungeonDropdown:Fire("OnValueChanged", target) | |
end | |
end | |
else | |
MDT:ZoomMap(delta) | |
end | |
end) | |
--PAN | |
frame.scrollFrame:EnableMouse(true) | |
frame.scrollFrame:SetScript("OnMouseDown", MDT.OnMouseDown) | |
frame.scrollFrame:SetScript("OnMouseUp", MDT.OnMouseUp) | |
frame.scrollFrame:SetScript("OnUpdate", function(self,elapsed) | |
local x, y = GetCursorPosition() | |
MDT:OnPan(x, y) | |
MDT:OnPanFadeOut(elapsed) | |
end) | |
if frame.mapPanelFrame == nil then | |
frame.mapPanelFrame = CreateFrame("frame","MDTMapPanelFrame",nil) | |
frame.mapPanelFrame:ClearAllPoints() | |
frame.mapPanelFrame:SetSize(sizex*db.scale, sizey*db.scale) | |
--frame.mapPanelFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, 0) | |
frame.mapPanelFrame:SetAllPoints(frame) | |
end | |
--create the 12 tiles and set the scrollchild | |
for i=1,12 do | |
frame["mapPanelTile"..i] = frame.mapPanelFrame:CreateTexture("MDTmapPanelTile"..i, "BACKGROUND") | |
frame["mapPanelTile"..i]:SetDrawLayer(canvasDrawLayer, 0) | |
--frame["mapPanelTile"..i]:SetAlpha(0.3) | |
frame["mapPanelTile"..i]:SetSize(frame:GetWidth()/4+(5*db.scale),frame:GetWidth()/4+(5*db.scale)) | |
end | |
frame.mapPanelTile1:SetPoint("TOPLEFT",frame.mapPanelFrame,"TOPLEFT",0,0) | |
frame.mapPanelTile2:SetPoint("TOPLEFT",frame.mapPanelTile1,"TOPRIGHT") | |
frame.mapPanelTile3:SetPoint("TOPLEFT",frame.mapPanelTile2,"TOPRIGHT") | |
frame.mapPanelTile4:SetPoint("TOPLEFT",frame.mapPanelTile3,"TOPRIGHT") | |
frame.mapPanelTile5:SetPoint("TOPLEFT",frame.mapPanelTile1,"BOTTOMLEFT") | |
frame.mapPanelTile6:SetPoint("TOPLEFT",frame.mapPanelTile5,"TOPRIGHT") | |
frame.mapPanelTile7:SetPoint("TOPLEFT",frame.mapPanelTile6,"TOPRIGHT") | |
frame.mapPanelTile8:SetPoint("TOPLEFT",frame.mapPanelTile7,"TOPRIGHT") | |
frame.mapPanelTile9:SetPoint("TOPLEFT",frame.mapPanelTile5,"BOTTOMLEFT") | |
frame.mapPanelTile10:SetPoint("TOPLEFT",frame.mapPanelTile9,"TOPRIGHT") | |
frame.mapPanelTile11:SetPoint("TOPLEFT",frame.mapPanelTile10,"TOPRIGHT") | |
frame.mapPanelTile12:SetPoint("TOPLEFT",frame.mapPanelTile11,"TOPRIGHT") | |
--create the 150 large map tiles | |
for i=1,10 do | |
for j=1,15 do | |
frame["largeMapPanelTile"..i..j] = frame.mapPanelFrame:CreateTexture("MDTLargeMapPanelTile"..i..j, "BACKGROUND") | |
local tile = frame["largeMapPanelTile"..i..j] | |
tile:SetDrawLayer(canvasDrawLayer, 5) | |
tile:SetSize(frame:GetWidth()/15,frame:GetWidth()/15) | |
if i==1 and j==1 then | |
--to mapPanel | |
tile:SetPoint("TOPLEFT",frame.mapPanelFrame,"TOPLEFT",0,0) | |
elseif j==1 then | |
--to tile above | |
tile:SetPoint("TOPLEFT",frame["largeMapPanelTile"..(i-1)..j],"BOTTOMLEFT",0,0) | |
else | |
--to tile to the left | |
tile:SetPoint("TOPLEFT",frame["largeMapPanelTile"..i..(j-1)],"TOPRIGHT",0,0) | |
end | |
tile:SetColorTexture(i/10,j/10,0,1) | |
tile:Hide() | |
end | |
end | |
frame.scrollFrame:SetScrollChild(frame.mapPanelFrame) | |
frame.scrollFrame.cursorX = 0 | |
frame.scrollFrame.cursorY = 0 | |
frame.scrollFrame.queuedDeltaX = 0; | |
frame.scrollFrame.queuedDeltaY = 0; | |
end | |
end | |
local function round(number, decimals) | |
return (("%%.%df"):format(decimals)):format(number) | |
end | |
function MDT:CalculateEnemyHealth(boss, baseHealth, level, ignoreFortified) | |
local fortified = MDT:IsCurrentPresetFortified() | |
local tyrannical = MDT:IsCurrentPresetTyrannical() | |
local mult = 1 | |
if boss == false and fortified == true and (not ignoreFortified) then mult = 1.2 end | |
if boss == true and tyrannical == true then mult = 1.3 end | |
mult = round((1.08^math.max(level-2,0))*mult,2) | |
return round(mult*baseHealth,0) | |
end | |
function MDT:ReverseCalcEnemyHealth(unit, level, boss) | |
local health = UnitHealthMax(unit) | |
local fortified = MDT:IsCurrentPresetFortified() | |
local tyrannical = MDT:IsCurrentPresetTyrannical() | |
local mult = 1 | |
if boss == false and fortified == true then mult = 1.2 end | |
if boss == true and tyrannical == true then mult = 1.3 end | |
mult = round((1.08^math.max(level-2,0))*mult,2) | |
local baseHealth = health/mult | |
return baseHealth | |
end | |
function MDT:FormatEnemyHealth(amount) | |
amount = tonumber(amount) | |
if not amount then return "" end | |
if self:GetLocaleIndex() == 9 then | |
if amount < 1e3 then | |
return 0 | |
elseif amount >= 1e16 then | |
return string.format("%.3f경", amount/1e16) | |
elseif amount >= 1e12 then | |
return string.format("%.3f조", amount/1e12) | |
elseif amount >= 1e8 then | |
return string.format("%.2f억", amount/1e8) | |
elseif amount >= 1e4 then | |
return string.format("%.1f만", amount/1e4) | |
end | |
else | |
if amount < 1e3 then | |
return 0 | |
elseif amount >= 1e12 then | |
return string.format("%.3ft", amount/1e12) | |
elseif amount >= 1e9 then | |
return string.format("%.3fb", amount/1e9) | |
elseif amount >= 1e6 then | |
return string.format("%.2fm", amount/1e6) | |
elseif amount >= 1e3 then | |
return string.format("%.1fk", amount/1e3) | |
end | |
end | |
end | |
function MDT:UpdateDungeonEnemies() | |
MDT:DungeonEnemies_UpdateEnemies() | |
end | |
function MDT:HideAllDialogs() | |
MDT.main_frame.presetCreationFrame:Hide() | |
MDT.main_frame.presetImportFrame:Hide() | |
MDT.main_frame.ExportFrame:Hide() | |
MDT.main_frame.RenameFrame:Hide() | |
MDT.main_frame.ClearConfirmationFrame:Hide() | |
MDT.main_frame.DeleteConfirmationFrame:Hide() | |
MDT.main_frame.automaticColorsFrame.CustomColorFrame:Hide() | |
MDT.main_frame.automaticColorsFrame:Hide() | |
if MDT.main_frame.ConfirmationFrame then MDT.main_frame.ConfirmationFrame:Hide() end | |
end | |
function MDT:OpenImportPresetDialog() | |
MDT:HideAllDialogs() | |
MDT.main_frame.presetImportFrame:ClearAllPoints() | |
MDT.main_frame.presetImportFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50) | |
MDT.main_frame.presetImportFrame:Show() | |
MDT.main_frame.presetImportBox:SetText("") | |
MDT.main_frame.presetImportBox:SetFocus() | |
MDT.main_frame.presetImportLabel:SetText(nil) | |
end | |
function MDT:OpenNewPresetDialog() | |
MDT:HideAllDialogs() | |
local presetList = {} | |
local countPresets = 0 | |
for k,v in pairs(db.presets[db.currentDungeonIdx]) do | |
if v.text ~= "<New Preset>" then | |
table.insert(presetList,k,v.text) | |
countPresets=countPresets+1 | |
end | |
end | |
table.insert(presetList,1,"Empty") | |
MDT.main_frame.PresetCreationDropDown:SetList(presetList) | |
MDT.main_frame.PresetCreationDropDown:SetValue(1) | |
MDT.main_frame.PresetCreationEditbox:SetText(L["defaultPresetName"].." "..countPresets+1) | |
MDT.main_frame.presetCreationFrame:ClearAllPoints() | |
MDT.main_frame.presetCreationFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50) | |
MDT.main_frame.presetCreationFrame:SetStatusText("") | |
MDT.main_frame.presetCreationFrame:Show() | |
MDT.main_frame.presetCreationCreateButton:SetDisabled(false) | |
MDT.main_frame.presetCreationCreateButton.text:SetTextColor(1,0.8196,0) | |
MDT.main_frame.PresetCreationEditbox:SetFocus() | |
MDT.main_frame.PresetCreationEditbox:HighlightText(0,50) | |
MDT.main_frame.presetImportBox:SetText("") | |
end | |
function MDT:OpenClearPresetDialog() | |
MDT:HideAllDialogs() | |
MDT.main_frame.ClearConfirmationFrame:ClearAllPoints() | |
MDT.main_frame.ClearConfirmationFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50) | |
local currentPresetName = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].text | |
MDT.main_frame.ClearConfirmationFrame.label:SetText(string.format(L["Reset %s?"],currentPresetName)) | |
MDT.main_frame.ClearConfirmationFrame:Show() | |
end | |
function MDT:OpenAutomaticColorsDialog() | |
MDT:HideAllDialogs() | |
MDT.main_frame.automaticColorsFrame:ClearAllPoints() | |
MDT.main_frame.automaticColorsFrame:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50) | |
MDT.main_frame.automaticColorsFrame:SetStatusText("") | |
MDT.main_frame.automaticColorsFrame:Show() | |
MDT.main_frame.automaticColorsFrame.CustomColorFrame:Hide() | |
if db.colorPaletteInfo.colorPaletteIdx == 6 then | |
MDT:OpenCustomColorsDialog() | |
end | |
end | |
function MDT:OpenCustomColorsDialog(frame) | |
MDT:HideAllDialogs() | |
MDT.main_frame.automaticColorsFrame:Show() --Not the prettiest way to handle this, but it works. | |
MDT.main_frame.automaticColorsFrame.CustomColorFrame:ClearAllPoints() | |
MDT.main_frame.automaticColorsFrame.CustomColorFrame:SetPoint("CENTER",264,-7) | |
MDT.main_frame.automaticColorsFrame.CustomColorFrame:SetStatusText("") | |
MDT.main_frame.automaticColorsFrame.CustomColorFrame:Show() | |
end | |
function MDT:UpdateDungeonDropDown() | |
local group = MDT.main_frame.DungeonSelectionGroup | |
group.DungeonDropdown:SetList({}) | |
if db.currentExpansion == 1 then | |
for i=1,14 do | |
group.DungeonDropdown:AddItem(i,dungeonList[i]) | |
end | |
elseif db.currentExpansion == 2 then | |
for i=15,28 do | |
group.DungeonDropdown:AddItem(i,dungeonList[i]) | |
end | |
elseif db.currentExpansion == 3 then | |
for i = 29,37 do | |
group.DungeonDropdown:AddItem(i,dungeonList[i]) | |
end | |
end | |
group.DungeonDropdown:SetValue(db.currentDungeonIdx) | |
group.SublevelDropdown:SetList(dungeonSubLevels[db.currentDungeonIdx]) | |
group.SublevelDropdown:SetValue(db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel) | |
group.DungeonDropdown:ClearFocus() | |
group.SublevelDropdown:ClearFocus() | |
end | |
---CreateDungeonSelectDropdown | |
---Creates both dungeon and sublevel dropdowns | |
function MDT:CreateDungeonSelectDropdown(frame) | |
--Simple Group to hold both dropdowns | |
frame.DungeonSelectionGroup = AceGUI:Create("SimpleGroup") | |
local group = frame.DungeonSelectionGroup | |
group.frame:SetFrameStrata("HIGH") | |
group.frame:SetFrameLevel(50) | |
group:SetWidth(200) | |
group:SetHeight(50) | |
group:SetPoint("TOPLEFT",frame.topPanel,"BOTTOMLEFT",0,2) | |
group:SetLayout("List") | |
MDT:FixAceGUIShowHide(group) | |
--dungeon select | |
group.DungeonDropdown = AceGUI:Create("Dropdown") | |
group.DungeonDropdown.text:SetJustifyH("LEFT") | |
group.DungeonDropdown:SetCallback("OnValueChanged",function(widget,callbackName,key) | |
if key == 14 then | |
db.currentExpansion = 2 | |
db.currentDungeonIdx = 15 | |
MDT:UpdateDungeonDropDown() | |
MDT:UpdateToDungeon(db.currentDungeonIdx) | |
elseif key == 27 then | |
db.currentExpansion = 1 | |
db.currentDungeonIdx = 1 | |
MDT:UpdateDungeonDropDown() | |
MDT:UpdateToDungeon(db.currentDungeonIdx) | |
elseif key == 28 then | |
db.currentExpansion = 3 | |
db.currentDungeonIdx = 29 | |
MDT:UpdateDungeonDropDown() | |
MDT:UpdateToDungeon(db.currentDungeonIdx) | |
elseif key == 37 then | |
db.currentExpansion = 2 | |
db.currentDungeonIdx = 15 | |
MDT:UpdateDungeonDropDown() | |
MDT:UpdateToDungeon(db.currentDungeonIdx) | |
else | |
MDT:UpdateToDungeon(key) | |
end | |
end) | |
group:AddChild(group.DungeonDropdown) | |
--sublevel select | |
group.SublevelDropdown = AceGUI:Create("Dropdown") | |
group.SublevelDropdown.text:SetJustifyH("LEFT") | |
group.SublevelDropdown:SetCallback("OnValueChanged",function(widget,callbackName,key) | |
db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel = key | |
MDT:UpdateMap() | |
MDT:ZoomMapToDefault() | |
end) | |
group:AddChild(group.SublevelDropdown) | |
MDT:UpdateDungeonDropDown() | |
end | |
---EnsureDBTables | |
---Makes sure profiles are valid and have their fields set | |
function MDT:EnsureDBTables() | |
--dungeonIdx doesnt exist | |
if not dungeonList[db.currentDungeonIdx] or string.find(dungeonList[db.currentDungeonIdx],">") then | |
db.currentDungeonIdx = db.currentExpansion == 1 and 1 or db.currentExpansion == 2 and 15 | |
end | |
local preset = MDT:GetCurrentPreset() | |
preset.week = preset.week or MDT:GetCurrentAffixWeek() | |
db.currentPreset[db.currentDungeonIdx] = db.currentPreset[db.currentDungeonIdx] or 1 | |
db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentDungeonIdx = db.currentDungeonIdx | |
db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel or 1 | |
db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentPull = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentPull or 1 | |
db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls or {} | |
-- make sure, that at least 1 pull exists | |
if #db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls == 0 then | |
db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls[1] = {} | |
end | |
--detect gaps in pull list and delete invalid pulls | |
for k,v in pairs(preset.value.pulls) do | |
if k == 0 or k>#preset.value.pulls then | |
preset.value.pulls[k] = nil | |
end | |
end | |
-- Set current pull to last pull, if the actual current pull does not exists anymore | |
if not db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls[db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentPull] then | |
db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentPull = #db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls | |
end | |
for k,v in pairs(db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls) do | |
if k ==0 then | |
db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls[0] = nil | |
break | |
end | |
end | |
--removed clones: remove data from presets | |
for pullIdx,pull in pairs(preset.value.pulls) do | |
for enemyIdx,clones in pairs(pull) do | |
if tonumber(enemyIdx) then | |
--enemy does not exist at all anymore | |
if not MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx] then | |
pull[enemyIdx] = nil | |
else | |
--only clones | |
for k,v in pairs(clones) do | |
if not MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][v] then | |
clones[k] = nil | |
end | |
end | |
end | |
end | |
end | |
pull["color"] = pull["color"] or db.defaultColor | |
end | |
MDT:GetCurrentPreset().week = MDT:GetCurrentPreset().week or MDT:GetCurrentAffixWeek() | |
if db.currentDungeonIdx == 19 then | |
local englishFaction = UnitFactionGroup("player") | |
preset.faction = preset.faction or (englishFaction and englishFaction=="Alliance") and 2 or 1 | |
end | |
if db.currentDungeonIdx == 16 and (not preset.freeholdCrewSelected) then | |
local week = preset.week | |
week = week%3 | |
if week == 0 then week = 3 end | |
preset.freeholdCrew = week | |
preset.freeholdCrewSelected = true | |
end | |
db.MDI = db.MDI or {} | |
preset.mdi = preset.mdi or {} | |
preset.mdi.freehold = preset.mdi.freehold or 1 | |
preset.mdi.freeholdJoined = preset.mdi.freeholdJoined or false | |
preset.mdi.beguiling = preset.mdi.beguiling or 1 | |
preset.difficulty = preset.difficulty or db.currentDifficulty | |
preset.mdiEnabled = preset.mdiEnabled or db.MDI.enabled | |
--make sure sublevel actually exists for the dungeon | |
--this might have been caused by bugged dropdowns in the past | |
local maxSublevel = -1 | |
for _,_ in pairs(MDT.dungeonMaps[db.currentDungeonIdx]) do | |
maxSublevel = maxSublevel + 1 | |
end | |
if preset.value.currentSublevel > maxSublevel then preset.value.currentSublevel = maxSublevel end | |
--make sure teeeming flag is set | |
preset.value.teeming = MDT:IsWeekTeeming(preset.week) | |
end | |
function MDT:GetTileFormat(dungeonIdx) | |
local mapInfo = MDT.mapInfo[dungeonIdx] | |
return mapInfo and mapInfo.tileFormat or 4 | |
end | |
function MDT:UpdateMap(ignoreSetSelection, ignoreReloadPullButtons, ignoreUpdateProgressBar) | |
local mapName | |
local frame = MDT.main_frame | |
mapName = MDT.dungeonMaps[db.currentDungeonIdx][0] | |
MDT:EnsureDBTables() | |
local preset = MDT:GetCurrentPreset() | |
if preset.difficulty then | |
db.currentDifficulty = preset.difficulty | |
frame.sidePanel.DifficultySlider:SetValue(db.currentDifficulty) | |
frame.sidePanel.difficultyWarning:Toggle(db.currentDifficulty) | |
end | |
local fileName = MDT.dungeonMaps[db.currentDungeonIdx][preset.value.currentSublevel] | |
local path = "Interface\\WorldMap\\"..mapName.."\\" | |
local tileFormat = MDT:GetTileFormat(db.currentDungeonIdx) | |
for i=1,12 do | |
if tileFormat == 4 then | |
local texName = path..fileName..i | |
if frame["mapPanelTile"..i] then | |
frame["mapPanelTile"..i]:SetTexture(texName) | |
frame["mapPanelTile"..i]:Show() | |
end | |
else | |
if frame["mapPanelTile"..i] then | |
frame["mapPanelTile"..i]:Hide() | |
end | |
end | |
end | |
for i=1,10 do | |
for j=1,15 do | |
if tileFormat == 15 then | |
local texName= path..fileName..((i - 1) * 15 + j) | |
frame["largeMapPanelTile"..i..j]:SetTexture(texName) | |
frame["largeMapPanelTile"..i..j]:Show() | |
else | |
frame["largeMapPanelTile"..i..j]:Hide() | |
end | |
end | |
end | |
MDT:UpdateDungeonEnemies() | |
MDT:DungeonEnemies_UpdateTeeming() | |
MDT:DungeonEnemies_UpdateSeasonalAffix() | |
MDT:DungeonEnemies_UpdateInspiring() | |
if not ignoreReloadPullButtons then | |
MDT:ReloadPullButtons() | |
end | |
--handle delete button disable/enable | |
local presetCount = 0 | |
for k,v in pairs(db.presets[db.currentDungeonIdx]) do | |
presetCount = presetCount + 1 | |
end | |
if (db.currentPreset[db.currentDungeonIdx] == 1 or db.currentPreset[db.currentDungeonIdx] == presetCount) or MDT.liveSessionActive then | |
MDT.main_frame.sidePanelDeleteButton:SetDisabled(true) | |
MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(0.5,0.5,0.5) | |
else | |
MDT.main_frame.sidePanelDeleteButton:SetDisabled(false) | |
MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(1,0.8196,0) | |
end | |
--live mode | |
local livePreset = MDT:GetCurrentLivePreset() | |
if MDT.liveSessionActive and preset ~= livePreset then | |
MDT.main_frame.liveReturnButton:Show() | |
MDT.main_frame.setLivePresetButton:Show() | |
else | |
MDT.main_frame.liveReturnButton:Hide() | |
MDT.main_frame.setLivePresetButton:Hide() | |
end | |
MDT:UpdatePresetDropdownTextColor() | |
if not ignoreSetSelection then MDT:SetSelectionToPull(preset.value.currentPull) end | |
MDT:UpdateDungeonDropDown() | |
--frame.sidePanel.affixDropdown:SetAffixWeek(MDT:GetCurrentPreset().week,ignoreReloadPullButtons,ignoreUpdateProgressBar) | |
frame.sidePanel.affixDropdown:SetValue(MDT:GetCurrentPreset().week) | |
MDT:ToggleFreeholdSelector(db.currentDungeonIdx == 16) | |
MDT:ToggleBoralusSelector(db.currentDungeonIdx == 19) | |
MDT:DisplayMDISelector() | |
MDT:DrawAllPresetObjects() | |
MDT:KillAllAnimatedLines() | |
MDT:DrawAllAnimatedLines() | |
end | |
---UpdateToDungeon | |
---Updates the map to the specified dungeon | |
function MDT:UpdateToDungeon(dungeonIdx, ignoreUpdateMap, init) | |
db.currentExpansion = 1 | |
if dungeonIdx>=15 then db.currentExpansion = 2 end | |
if dungeonIdx>=29 then db.currentExpansion = 3 end | |
db.currentDungeonIdx = dungeonIdx | |
if not db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel then | |
db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel=1 | |
end | |
if init then return end | |
MDT:UpdatePresetDropDown() | |
if not ignoreUpdateMap then MDT:UpdateMap() end | |
MDT:ZoomMapToDefault() | |
--Colors the first pull in "Default" presets | |
if db.currentPreset[db.currentDungeonIdx] == 1 then MDT:ColorPull() end | |
end | |
function MDT:DeletePreset(index) | |
tremove(db.presets[db.currentDungeonIdx],index) | |
db.currentPreset[db.currentDungeonIdx] = index-1 | |
MDT:UpdatePresetDropDown() | |
MDT:UpdateMap() | |
MDT:ZoomMapToDefault() | |
end | |
MDT.zoneIdToDungeonIdx = { | |
[934] = 15,--atal | |
[935] = 15,--atal | |
[936] = 16,--fh | |
[1004] = 17,--kr | |
[1039] = 18,--shrine | |
[1040] = 18,--shrine | |
[1162] = 19,--siege | |
[1038] = 20,--temple | |
[1043] = 20,--temple | |
[1010] = 21,--motherlode | |
[1041] = 22,--underrot | |
[1042] = 22,--underrot | |
[974] = 23,--toldagor | |
[975] = 23,--toldagor | |
[976] = 23,--toldagor | |
[977] = 23,--toldagor | |
[978] = 23,--toldagor | |
[979] = 23,--toldagor | |
[980] = 23,--toldagor | |
[1015] = 24,--wcm | |
[1016] = 24,--wcm | |
[1017] = 24,--wcm | |
[1018] = 24,--wcm | |
[1029] = 24,--wcm | |
[1490] = 25,--lower mecha | |
[1491] = 26,--upper mecha | |
[1493] = 26,--upper mecha | |
[1494] = 26,--upper mecha | |
[1497] = 26,--upper mecha | |
[1663] = 30, | |
[1664] = 30, | |
[1665] = 30, | |
[1666] = 35, | |
[1667] = 35, | |
[1668] = 35, | |
[1669] = 31, | |
[1674] = 32, | |
[1675] = 33, | |
[1676] = 33, | |
[1677] = 29, | |
[1678] = 29, | |
[1679] = 29, | |
[1680] = 29, | |
[1683] = 36, | |
[1684] = 36, | |
[1685] = 36, | |
[1686] = 36, | |
[1687] = 36, | |
[1692] = 34, | |
[1693] = 34, | |
[1694] = 34, | |
[1695] = 34, | |
[1697] = 32, | |
} | |
local lastUpdatedDungeonIdx | |
function MDT:CheckCurrentZone(init) | |
local zoneId = C_Map.GetBestMapForUnit("player") | |
local dungeonIdx = MDT.zoneIdToDungeonIdx[zoneId] | |
if dungeonIdx and (not lastUpdatedDungeonIdx or dungeonIdx ~= lastUpdatedDungeonIdx) then | |
lastUpdatedDungeonIdx = dungeonIdx | |
MDT:UpdateToDungeon(dungeonIdx,nil,init) | |
end | |
end | |
---CountPresets | |
---Counts the number of presets of the current dungeon | |
function MDT:CountPresets() | |
return #db.presets[db.currentDungeonIdx]-2 | |
end | |
---DeleteAllPresets | |
---Deletes all presets from the current dungeon | |
function MDT:DeleteAllPresets() | |
local countPresets = #db.presets[db.currentDungeonIdx]-1 | |
for i=countPresets,2,-1 do | |
tremove(db.presets[db.currentDungeonIdx],i) | |
db.currentPreset[db.currentDungeonIdx] = i-1 | |
end | |
MDT:UpdatePresetDropDown() | |
MDT:UpdateMap() | |
end | |
function MDT:ClearPreset(preset, silent) | |
if preset == self:GetCurrentPreset() then silent = false end | |
table.wipe(preset.value.pulls) | |
preset.value.currentPull = 1 | |
table.wipe(preset.value.riftOffsets) | |
--MDT:DeleteAllPresetObjects() | |
self:EnsureDBTables() | |
if not silent then | |
self:UpdateMap() | |
self:ReloadPullButtons() | |
end | |
MDT:ColorPull() | |
end | |
function MDT:CreateNewPreset(name) | |
if name == "<New Preset>" then | |
MDT.main_frame.presetCreationLabel:SetText(string.format(L["Cannot create preset '%s'"],name)) | |
MDT.main_frame.presetCreationCreateButton:SetDisabled(true) | |
MDT.main_frame.presetCreationCreateButton.text:SetTextColor(0.5,0.5,0.5) | |
MDT.main_frame.presetCreationFrame:DoLayout() | |
return | |
end | |
local duplicate = false | |
local countPresets = 0 | |
for k,v in pairs(db.presets[db.currentDungeonIdx]) do | |
countPresets = countPresets + 1 | |
if v.text == name then duplicate = true end | |
end | |
if duplicate == false then | |
db.presets[db.currentDungeonIdx][countPresets+1] = db.presets[db.currentDungeonIdx][countPresets] --put <New Preset> at the end of the list | |
local startingPointPresetIdx = MDT.main_frame.PresetCreationDropDown:GetValue()-1 | |
if startingPointPresetIdx>0 then | |
db.presets[db.currentDungeonIdx][countPresets] = MDT:CopyObject(db.presets[db.currentDungeonIdx][startingPointPresetIdx]) | |
db.presets[db.currentDungeonIdx][countPresets].text = name | |
db.presets[db.currentDungeonIdx][countPresets].uid = nil | |
else | |
db.presets[db.currentDungeonIdx][countPresets] = {text=name,value={}} | |
end | |
db.currentPreset[db.currentDungeonIdx] = countPresets | |
MDT.main_frame.presetCreationFrame:Hide() | |
MDT:UpdatePresetDropDown() | |
MDT:UpdateMap() | |
MDT:ZoomMapToDefault() | |
MDT:SetPresetColorPaletteInfo() | |
MDT:ColorAllPulls() | |
else | |
MDT.main_frame.presetCreationLabel:SetText(string.format(L["Preset '%s' already exists"],name)) | |
MDT.main_frame.presetCreationCreateButton:SetDisabled(true) | |
MDT.main_frame.presetCreationCreateButton.text:SetTextColor(0.5,0.5,0.5) | |
MDT.main_frame.presetCreationFrame:DoLayout() | |
end | |
end | |
function MDT:SanitizePresetName(text) | |
--check if name is valid, block button if so, unblock if valid | |
if text == "<New Preset>" then | |
return false | |
else | |
local duplicate = false | |
local countPresets = 0 | |
for k,v in pairs(db.presets[db.currentDungeonIdx]) do | |
countPresets = countPresets + 1 | |
if v.text == text then duplicate = true end | |
end | |
return not duplicate and text or false | |
end | |
end | |
function MDT:MakeChatPresetImportFrame(frame) | |
frame.chatPresetImportFrame = AceGUI:Create("Frame") | |
local chatImport = frame.chatPresetImportFrame | |
chatImport:SetTitle(L["Import Preset"]) | |
chatImport:SetWidth(400) | |
chatImport:SetHeight(100) | |
chatImport:EnableResize(false) | |
chatImport:SetLayout("Flow") | |
chatImport:SetCallback("OnClose", function(widget) | |
MDT:UpdatePresetDropDown() | |
if db.currentPreset[db.currentDungeonIdx] ~= 1 then | |
MDT.main_frame.sidePanelDeleteButton:SetDisabled(false) | |
MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(1,0.8196,0) | |
end | |
end) | |
chatImport.defaultText = L["Import Preset"]..":\n" | |
chatImport.importLabel = AceGUI:Create("Label") | |
chatImport.importLabel:SetText(chatImport.defaultText) | |
chatImport.importLabel:SetWidth(250) | |
--chatImport.importLabel:SetColor(1,0,0) | |
chatImport.importButton = AceGUI:Create("Button") | |
local importButton = chatImport.importButton | |
importButton:SetText(L["Import"]) | |
importButton:SetWidth(100) | |
importButton:SetCallback("OnClick", function() | |
local newPreset = chatImport.currentPreset | |
if MDT:ValidateImportPreset(newPreset) then | |
chatImport:Hide() | |
MDT:ImportPreset(MDT:DeepCopy(newPreset)) | |
else | |
print(L["MDT: Error importing preset"]) | |
end | |
end) | |
chatImport:AddChild(chatImport.importLabel) | |
chatImport:AddChild(importButton) | |
chatImport:Hide() | |
end | |
function MDT:OpenChatImportPresetDialog(sender, preset, live) | |
MDT:HideAllDialogs() | |
local chatImport = MDT.main_frame.chatPresetImportFrame | |
chatImport:ClearAllPoints() | |
chatImport:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50) | |
chatImport.currentPreset = preset | |
local dungeon = MDT:GetDungeonName(preset.value.currentDungeonIdx) | |
local name = preset.text | |
chatImport:Show() | |
chatImport.importLabel:SetText(chatImport.defaultText..sender.. ": "..dungeon.." - "..name) | |
chatImport:SetTitle(L["Import Preset"]) | |
chatImport.importButton:SetText(L["Import"]) | |
chatImport.live = nil | |
if live then | |
chatImport.importLabel:SetText(string.format(L["Join Live Session"],"\n",sender,dungeon,name)) | |
chatImport:SetTitle(L["Live Session"]) | |
chatImport.importButton:SetText(L["Join"]) | |
chatImport.live = true | |
end | |
end | |
function MDT:MakePresetImportFrame(frame) | |
frame.presetImportFrame = AceGUI:Create("Frame") | |
frame.presetImportFrame:SetTitle(L["Import Preset"]) | |
frame.presetImportFrame:SetWidth(400) | |
frame.presetImportFrame:SetHeight(200) | |
frame.presetImportFrame:EnableResize(false) | |
frame.presetImportFrame:SetLayout("Flow") | |
frame.presetImportFrame:SetCallback("OnClose", function(widget) | |
MDT:UpdatePresetDropDown() | |
if db.currentPreset[db.currentDungeonIdx] ~= 1 then | |
MDT.main_frame.sidePanelDeleteButton:SetDisabled(false) | |
MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(1,0.8196,0) | |
end | |
end) | |
frame.presetImportLabel = AceGUI:Create("Label") | |
frame.presetImportLabel:SetText(nil) | |
frame.presetImportLabel:SetWidth(390) | |
frame.presetImportLabel:SetColor(1,0,0) | |
local importString = "" | |
frame.presetImportBox = AceGUI:Create("EditBox") | |
frame.presetImportBox:SetLabel(L["Import Preset"]..":") | |
frame.presetImportBox:SetWidth(255) | |
frame.presetImportBox:SetCallback("OnEnterPressed", function(widget, event, text) importString = text end) | |
frame.presetImportFrame:AddChild(frame.presetImportBox) | |
local importButton = AceGUI:Create("Button") | |
importButton:SetText(L["Import"]) | |
importButton:SetWidth(100) | |
importButton:SetCallback("OnClick", function() | |
local newPreset = MDT:StringToTable(importString, true) | |
if MDT:ValidateImportPreset(newPreset) then | |
MDT.main_frame.presetImportFrame:Hide() | |
MDT:ImportPreset(newPreset) | |
if db.colorPaletteInfo.forceColorBlindMode then | |
MDT:ColorAllPulls() | |
end | |
else | |
frame.presetImportLabel:SetText(L["Invalid import string"]) | |
end | |
end) | |
frame.presetImportFrame:AddChild(importButton) | |
frame.presetImportFrame:AddChild(frame.presetImportLabel) | |
frame.presetImportFrame:Hide() | |
end | |
function MDT:MakePresetCreationFrame(frame) | |
frame.presetCreationFrame = AceGUI:Create("Frame") | |
frame.presetCreationFrame:SetTitle(L["New Preset"]) | |
frame.presetCreationFrame:SetWidth(400) | |
frame.presetCreationFrame:SetHeight(200) | |
frame.presetCreationFrame:EnableResize(false) | |
--frame.presetCreationFrame:SetCallback("OnClose", function(widget) AceGUI:Release(widget) end) | |
frame.presetCreationFrame:SetLayout("Flow") | |
frame.presetCreationFrame:SetCallback("OnClose", function(widget) | |
MDT:UpdatePresetDropDown() | |
if db.currentPreset[db.currentDungeonIdx] ~= 1 then | |
MDT.main_frame.sidePanelDeleteButton:SetDisabled(false) | |
MDT.main_frame.sidePanelDeleteButton.text:SetTextColor(1,0.8196,0) | |
end | |
end) | |
frame.PresetCreationEditbox = AceGUI:Create("EditBox") | |
frame.PresetCreationEditbox:SetLabel(L["Preset Name"]..":") | |
frame.PresetCreationEditbox:SetWidth(255) | |
frame.PresetCreationEditbox:SetCallback("OnEnterPressed", function(widget, event, text) | |
--check if name is valid, block button if so, unblock if valid | |
if MDT:SanitizePresetName(text) then | |
frame.presetCreationLabel:SetText(nil) | |
frame.presetCreationCreateButton:SetDisabled(false) | |
frame.presetCreationCreateButton.text:SetTextColor(1,0.8196,0) | |
else | |
frame.presetCreationLabel:SetText(string.format(L["Cannot create preset '%s'"],text)) | |
frame.presetCreationCreateButton:SetDisabled(true) | |
frame.presetCreationCreateButton.text:SetTextColor(0.5,0.5,0.5) | |
end | |
frame.presetCreationFrame:DoLayout() | |
end) | |
frame.presetCreationFrame:AddChild(frame.PresetCreationEditbox) | |
frame.presetCreationCreateButton = AceGUI:Create("Button") | |
frame.presetCreationCreateButton:SetText(L["Create"]) | |
frame.presetCreationCreateButton:SetWidth(100) | |
frame.presetCreationCreateButton:SetCallback("OnClick", function() | |
local name = frame.PresetCreationEditbox:GetText() | |
MDT:CreateNewPreset(name) | |
end) | |
frame.presetCreationFrame:AddChild(frame.presetCreationCreateButton) | |
frame.presetCreationLabel = AceGUI:Create("Label") | |
frame.presetCreationLabel:SetText(nil) | |
frame.presetCreationLabel:SetWidth(390) | |
frame.presetCreationLabel:SetColor(1,0,0) | |
frame.presetCreationFrame:AddChild(frame.presetCreationLabel) | |
frame.PresetCreationDropDown = AceGUI:Create("Dropdown") | |
frame.PresetCreationDropDown:SetLabel(L["Use as a starting point:"]) | |
frame.PresetCreationDropDown.text:SetJustifyH("LEFT") | |
frame.presetCreationFrame:AddChild(frame.PresetCreationDropDown) | |
frame.presetCreationFrame:Hide() | |
end | |
function MDT:ValidateImportPreset(preset) | |
if type(preset) ~= "table" then return false end | |
if not preset.text then return false end | |
if not preset.value then return false end | |
if type(preset.text) ~= "string" then return false end | |
if type(preset.value) ~= "table" then return false end | |
if not preset.value.currentDungeonIdx then return false end | |
if not preset.value.currentPull then return false end | |
if not preset.value.currentSublevel then return false end | |
if not preset.value.pulls then return false end | |
if type(preset.value.pulls) ~= "table" then return false end | |
return true | |
end | |
function MDT:ImportPreset(preset, fromLiveSession) | |
--change dungeon to dungeon of the new preset | |
self:UpdateToDungeon(preset.value.currentDungeonIdx,true) | |
local mdiEnabled = preset.mdiEnabled | |
--search for uid | |
local updateIndex | |
local duplicatePreset | |
for k,v in pairs(db.presets[db.currentDungeonIdx]) do | |
if v.uid and v.uid == preset.uid then | |
updateIndex = k | |
duplicatePreset = v | |
break | |
end | |
end | |
local updateCallback = function() | |
if self.main_frame.ConfirmationFrame then | |
self.main_frame.ConfirmationFrame:SetCallback("OnClose", function() end) | |
end | |
db.MDI.enabled = mdiEnabled | |
db.presets[db.currentDungeonIdx][updateIndex] = preset | |
db.currentPreset[db.currentDungeonIdx] = updateIndex | |
self.liveUpdateFrameOpen = nil | |
self:UpdatePresetDropDown() | |
self:UpdateMap() | |
if fromLiveSession then | |
self.main_frame.SendingStatusBar:Hide() | |
if self.main_frame.LoadingSpinner then | |
self.main_frame.LoadingSpinner:Hide() | |
self.main_frame.LoadingSpinner.Anim:Stop() | |
end | |
end | |
end | |
local copyCallback = function() | |
if self.main_frame.ConfirmationFrame then | |
self.main_frame.ConfirmationFrame:SetCallback("OnClose", function() end) | |
end | |
db.MDI.enabled = mdiEnabled | |
local name = preset.text | |
local num = 2 | |
for k,v in pairs(db.presets[db.currentDungeonIdx]) do | |
if name == v.text then | |
name = preset.text.." "..num | |
num = num + 1 | |
end | |
end | |
preset.text = name | |
if fromLiveSession then | |
if duplicatePreset then duplicatePreset.uid = nil end | |
else | |
preset.uid = nil | |
end | |
local countPresets = 0 | |
for k,v in pairs(db.presets[db.currentDungeonIdx]) do | |
countPresets = countPresets + 1 | |
end | |
db.presets[db.currentDungeonIdx][countPresets+1] = db.presets[db.currentDungeonIdx][countPresets] --put <New Preset> at the end of the list | |
db.presets[db.currentDungeonIdx][countPresets] = preset | |
db.currentPreset[db.currentDungeonIdx] = countPresets | |
self.liveUpdateFrameOpen = nil | |
self:UpdatePresetDropDown() | |
self:UpdateMap() | |
if fromLiveSession then | |
self.main_frame.SendingStatusBar:Hide() | |
if self.main_frame.LoadingSpinner then | |
self.main_frame.LoadingSpinner:Hide() | |
self.main_frame.LoadingSpinner.Anim:Stop() | |
end | |
end | |
end | |
local closeCallback = function() | |
self.liveUpdateFrameOpen = nil | |
self:LiveSession_Disable() | |
self.main_frame.ConfirmationFrame:SetCallback("OnClose", function() end) | |
if fromLiveSession then | |
self.main_frame.SendingStatusBar:Hide() | |
if self.main_frame.LoadingSpinner then | |
self.main_frame.LoadingSpinner:Hide() | |
self.main_frame.LoadingSpinner.Anim:Stop() | |
end | |
end | |
end | |
--open dialog to ask for replacing | |
if updateIndex then | |
local prompt = string.format(L["Earlier Version"],duplicatePreset.text,"\n","\n","\n","\n") | |
self:OpenConfirmationFrame(450,150,L["Import Preset"],L["Update"],prompt, updateCallback,L["Copy"],copyCallback) | |
if fromLiveSession then | |
self.liveUpdateFrameOpen = true | |
self.main_frame.ConfirmationFrame:SetCallback("OnClose", function()closeCallback() end) | |
end | |
else | |
copyCallback() | |
end | |
end | |
---Stores r g b values for coloring pulls with MDT:ColorPull() | |
local colorPaletteValues = { | |
[1] = { --Rainbow values | |
[1] = {[1]=0.2446, [2]=1, [3]=0.2446}, | |
[2] = {[1]=0.2446, [2]=1, [3]=0.6223}, | |
[3] = {[1]=0.2446, [2]=1, [3]=1}, | |
[4] = {[1]=0.2446, [2]=0.6223, [3]=1}, | |
[5] = {[1]=0.2446, [2]=0.2446, [3]=1}, | |
[6] = {[1]=0.6223, [2]=0.6223, [3]=1}, | |
[7] = {[1]=1, [2]=0.2446, [3]=1}, | |
[8] = {[1]=1, [2]=0.2446, [3]=0.6223}, | |
[9] = {[1]=1, [2]=0.2446, [3]=0.2446}, | |
[10] = {[1]=1, [2]=0.60971, [3]=0.2446}, | |
[11] = {[1]=1, [2]=0.98741, [3]=0.2446}, | |
[12] = {[1]=0.63489, [2]=1, [3]=0.2446}, | |
--[13] = {[1]=1, [2]=0.2446, [3]=0.54676}, | |
--[14] = {[1]=1, [2]=0.2446, [3]=0.32014}, | |
--[15] = {[1]=1, [2]=0.38309, [3]=0.2446}, | |
--[16] = {[1]=1, [2]=0.60971, [3]=0.2446}, | |
--[17] = {[1]=1, [2]=0.83633, [3]=0.2446}, | |
--[18] = {[1]=0.93705, [2]=1, [3]=0.2446}, | |
--[19] = {[1]=0.71043, [2]=1, [3]=0.2446}, | |
--[20] = {[1]=0.48381, [2]=1, [3]=0.2446}, | |
}, | |
[2] = { --Black and Yellow values | |
[1] = {[1]=0.4, [2]=0.4, [3]=0.4}, | |
[2] = {[1]=1, [2]=1, [3]=0.0}, | |
}, | |
[3] = { --Red, Green and Blue values | |
[1] = {[1]=0.85882, [2]=0.058824, [3]=0.15294}, | |
[2] = {[1]=0.49804, [2]=1.0, [3]=0.0}, | |
[3] = {[1]=0.0, [2]=0.50196, [3]=1.0}, | |
}, | |
[4] = { --High Contrast values | |
[1] = {[1]=1, [2]=0.2446, [3]=1}, | |
[2] = {[1]=0.2446, [2]=1, [3]=0.6223}, | |
[3] = {[1]=1, [2]=0.2446, [3]=0.2446}, | |
[4] = {[1]=0.2446, [2]=0.6223, [3]=1}, | |
[5] = {[1]=1, [2]=0.98741, [3]=0.2446}, | |
[6] = {[1]=0.2446, [2]=1, [3]=0.2446}, | |
[7] = {[1]=1, [2]=0.2446, [3]=0.6223}, | |
[8] = {[1]=0.2446, [2]=1, [3]=1}, | |
[9] = {[1]=1, [2]=0.60971, [3]=0.2446}, | |
[10] = {[1]=0.2446, [2]=0.2446, [3]=1}, | |
[11] = {[1]=0.63489, [2]=1, [3]=0.2446}, | |
}, | |
[5] = { --Color Blind Friendly values (Based on IBM's color library "Color blind safe" | |
[1] = {[1]=0.39215686274509803, [2]=0.5607843137254902, [3]=1.0}, | |
--[2] = {[1]=0.47058823529411764, [2]=0.3686274509803922, [3]=0.9411764705882353}, | |
[2] = {[1]=0.8627450980392157, [2]=0.14901960784313725, [3]=0.4980392156862745}, | |
[3] = {[1]=0.996078431372549, [2]=0.3803921568627451, [3]=0.0}, | |
[4] = {[1]=1.0, [2]=0.6901960784313725, [3]=0.0}, | |
}, | |
} | |
---Dropdown menu items for color settings frame | |
local colorPaletteNames = { | |
[1] = L["Rainbow"], | |
[2] = L["Black and Yellow"], | |
[3] = L["Red, Green and Blue"], | |
[4] = L["High Contrast"], | |
[5] = L["Color Blind Friendly"], | |
[6] = L["Custom"], | |
} | |
---SetPresetColorPaletteInfo | |
---Saves currently selected automatic coloring settings to the current | |
---This can be achieved easier, but it will increase the export text length significantly for non custom palettes. | |
function MDT:SetPresetColorPaletteInfo() | |
local preset = MDT:GetCurrentPreset() | |
preset.colorPaletteInfo = {} | |
preset.colorPaletteInfo.autoColoring = db.colorPaletteInfo.autoColoring | |
if preset.colorPaletteInfo.autoColoring then | |
preset.colorPaletteInfo.colorPaletteIdx = db.colorPaletteInfo.colorPaletteIdx | |
if preset.colorPaletteInfo.colorPaletteIdx == 6 then | |
preset.colorPaletteInfo.customPaletteValues = db.colorPaletteInfo.customPaletteValues | |
preset.colorPaletteInfo.numberCustomColors = db.colorPaletteInfo.numberCustomColors | |
end | |
end | |
--Code below works, but in most cases it saves more data to the preset and thereby significantly increases the export string length | |
--MDT:GetCurrentPreset().colorPaletteInfo = db.colorPaletteInfo | |
end | |
---GetPresetColorPaletteInfo | |
function MDT:GetPresetColorPaletteInfo(preset) | |
preset = preset or MDT:GetCurrentPreset() | |
return preset.colorPaletteInfo | |
end | |
---ColorPull | |
---Function executes full coloring of a pull and it's blips | |
function MDT:ColorPull(colorValues, pullIdx, preset, bypass, exportColorBlind) -- bypass can be passed as true to color even when automatic coloring is toggled off | |
local colorPaletteInfo = MDT:GetPresetColorPaletteInfo(preset) | |
local pullIdx = pullIdx or MDT:GetCurrentPull() | |
if(pullIdx) then | |
local colorValues | |
local numberColors | |
local r,g,b | |
if colorPaletteInfo.autoColoring or bypass == true then | |
--Force color blind mode locally, will not alter the color values saved to a preset | |
if db.colorPaletteInfo.forceColorBlindMode == true and not exportColorBlind then | |
--Local color blind mode, will not alter the colorPaletteInfo saved to a preset | |
colorValues = colorValues or colorPaletteValues[colorValues] or colorPaletteValues[5] | |
numberColors = #colorValues | |
else | |
--Regular coloring | |
colorValues = colorValues or colorPaletteValues[colorValues] or colorPaletteInfo.colorPaletteIdx == 6 and colorPaletteInfo.customPaletteValues or colorPaletteValues[colorPaletteInfo.colorPaletteIdx] | |
numberColors = colorPaletteInfo.colorPaletteIdx == 6 and colorPaletteInfo.numberCustomColors or #colorValues -- tables must start from 1 and have no blank rows | |
end | |
local colorIdx = (pullIdx-1)%numberColors+1 | |
r,g,b = colorValues[colorIdx][1],colorValues[colorIdx][2],colorValues[colorIdx][3] | |
MDT:DungeonEnemies_SetPullColor(pullIdx,r,g,b) | |
MDT:UpdatePullButtonColor(pullIdx,r,g,b) | |
MDT:DungeonEnemies_UpdateBlipColors(pullIdx,r,g,b) | |
end | |
end | |
end | |
---ColorAllPulls | |
---Loops over all pulls in a preset and colors them | |
function MDT:ColorAllPulls(colorValues, startFrom, bypass, exportColorBlind) | |
local preset = self:GetCurrentPreset() | |
local startFrom = startFrom or 0 | |
for pullIdx,_ in pairs(preset.value.pulls) do | |
if pullIdx >= startFrom then | |
MDT:ColorPull(colorValues, pullIdx, preset, bypass, exportColorBlind) | |
end | |
end | |
end | |
---MakeCustomColorFrame | |
---creates frame housing settings for user customized color palette | |
function MDT:MakeCustomColorFrame(frame) | |
--Base frame for custom palette setup | |
frame.CustomColorFrame = AceGUI:Create("Frame") | |
frame.CustomColorFrame:SetTitle(L["Custom Color Palette"]) | |
frame.CustomColorFrame:SetWidth(290) | |
frame.CustomColorFrame:SetHeight(220) | |
frame.CustomColorFrame:EnableResize(false) | |
frame.CustomColorFrame:SetLayout("Flow") | |
frame:AddChild(frame.CustomColorFrame) | |
--Slider to adjust number of different colors and remake the frame OnMouseUp | |
frame.CustomColorFrame.ColorSlider = AceGUI:Create("Slider") | |
frame.CustomColorFrame.ColorSlider:SetSliderValues(2,20,1) | |
frame.CustomColorFrame.ColorSlider:SetValue(db.colorPaletteInfo.numberCustomColors) | |
frame.CustomColorFrame.ColorSlider:SetLabel(L["Choose number of colors"]) | |
frame.CustomColorFrame.ColorSlider:SetRelativeWidth(1) | |
frame.CustomColorFrame.ColorSlider:SetCallback("OnMouseUp", function(event, callbackName, value) | |
if value>20 then | |
db.colorPaletteInfo.numberCustomColors = 20 | |
elseif value<2 then | |
db.colorPaletteInfo.numberCustomColors = 2 | |
else | |
db.colorPaletteInfo.numberCustomColors = value | |
end | |
MDT:SetPresetColorPaletteInfo() | |
MDT:ColorAllPulls() | |
MDT:DrawAllHulls() | |
frame.CustomColorFrame:ReleaseChildren() | |
frame.CustomColorFrame:Release() | |
MDT:MakeCustomColorFrame(frame) | |
MDT:OpenCustomColorsDialog() | |
end) | |
frame.CustomColorFrame:AddChild(frame.CustomColorFrame.ColorSlider) | |
--Loop to create as many colorpickers as requested limited by db.colorPaletteInfo.numberCustomColors | |
local ColorPicker = {} | |
for i= 1,db.colorPaletteInfo.numberCustomColors do | |
ColorPicker[i] = AceGUI:Create("ColorPicker") | |
if db.colorPaletteInfo.customPaletteValues[i] then | |
ColorPicker[i]:SetColor(db.colorPaletteInfo.customPaletteValues[i][1], db.colorPaletteInfo.customPaletteValues[i][2], db.colorPaletteInfo.customPaletteValues[i][3]) | |
else | |
db.colorPaletteInfo.customPaletteValues[i] = {1,1,1} | |
ColorPicker[i]:SetColor(db.colorPaletteInfo.customPaletteValues[i][1], db.colorPaletteInfo.customPaletteValues[i][2], db.colorPaletteInfo.customPaletteValues[i][3]) | |
end | |
ColorPicker[i]:SetLabel(" "..i) | |
ColorPicker[i]:SetRelativeWidth(0.25) | |
ColorPicker[i]:SetHeight(15) | |
ColorPicker[i]:SetCallback("OnValueConfirmed", function(widget, event, r, g, b) | |
db.colorPaletteInfo.customPaletteValues[i] = {r,g,b} | |
MDT:SetPresetColorPaletteInfo() | |
MDT:ColorAllPulls() | |
MDT:DrawAllHulls() | |
end) | |
frame.CustomColorFrame:AddChild(ColorPicker[i]) | |
end | |
frame.CustomColorFrame:Hide() | |
end | |
function MDT:MakeAutomaticColorsFrame(frame) | |
frame.automaticColorsFrame = AceGUI:Create("Frame") | |
frame.automaticColorsFrame:SetTitle(L["Automatic Coloring"]) | |
frame.automaticColorsFrame:SetWidth(240) | |
frame.automaticColorsFrame:SetHeight(220) | |
frame.automaticColorsFrame:EnableResize(false) | |
frame.automaticColorsFrame:SetLayout("Flow") | |
frame.AutomaticColorsCheck = AceGUI:Create("CheckBox") | |
frame.AutomaticColorsCheck:SetLabel(L["Automatically color pulls"]) | |
frame.AutomaticColorsCheck:SetValue(db.colorPaletteInfo.autoColoring) | |
frame.AutomaticColorsCheck:SetCallback("OnValueChanged",function(widget,callbackName,value) | |
db.colorPaletteInfo.autoColoring = value | |
MDT:SetPresetColorPaletteInfo() | |
frame.AutomaticColorsCheckSidePanel:SetValue(db.colorPaletteInfo.autoColoring) | |
if value == true then | |
frame.toggleForceColorBlindMode:SetDisabled(false) | |
MDT:ColorAllPulls() | |
MDT:DrawAllHulls() | |
MDT.main_frame.AutomaticColorsCogwheel:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\helpIconRnbw") | |
else | |
frame.toggleForceColorBlindMode:SetDisabled(true) | |
MDT.main_frame.AutomaticColorsCogwheel:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\helpIconGrey") | |
end | |
end) | |
frame.automaticColorsFrame:AddChild(frame.AutomaticColorsCheck) | |
--Toggle local color blind mode | |
frame.toggleForceColorBlindMode = AceGUI:Create("CheckBox") | |
frame.toggleForceColorBlindMode:SetLabel(L["Local color blind mode"]) | |
frame.toggleForceColorBlindMode:SetValue(db.colorPaletteInfo.forceColorBlindMode) | |
frame.toggleForceColorBlindMode:SetCallback("OnValueChanged",function(widget,callbackName,value) | |
db.colorPaletteInfo.forceColorBlindMode = value | |
MDT:SetPresetColorPaletteInfo() | |
MDT:ColorAllPulls() | |
MDT:DrawAllHulls() | |
end) | |
frame.automaticColorsFrame:AddChild(frame.toggleForceColorBlindMode) | |
frame.PaletteSelectDropdown = AceGUI:Create("Dropdown") | |
frame.PaletteSelectDropdown:SetList(colorPaletteNames) | |
frame.PaletteSelectDropdown:SetLabel(L["Choose preferred color palette"]) | |
frame.PaletteSelectDropdown:SetValue(db.colorPaletteInfo.colorPaletteIdx) | |
frame.PaletteSelectDropdown:SetCallback("OnValueChanged", function(widget,callbackName,value) | |
if value == 6 then | |
db.colorPaletteInfo.colorPaletteIdx = value | |
MDT:OpenCustomColorsDialog() | |
else | |
MDT.main_frame.automaticColorsFrame.CustomColorFrame:Hide() | |
db.colorPaletteInfo.colorPaletteIdx = value | |
end | |
MDT:SetPresetColorPaletteInfo() | |
MDT:ColorAllPulls() | |
MDT:DrawAllHulls() | |
end) | |
frame.automaticColorsFrame:AddChild(frame.PaletteSelectDropdown) | |
-- The reason this button exists is to allow altering colorPaletteInfo of an imported preset | |
-- Without the need to untoggle/toggle or swap back and forth in the PaletteSelectDropdown | |
frame.button = AceGUI:Create("Button") | |
frame.button:SetText(L["Apply to preset"]) | |
frame.button:SetCallback("OnClick", function(widget, callbackName) | |
if not db.colorPaletteInfo.autoColoring then | |
db.colorPaletteInfo.autoColoring = true | |
frame.AutomaticColorsCheck:SetValue(db.colorPaletteInfo.autoColoring) | |
frame.AutomaticColorsCheckSidePanel:SetValue(db.colorPaletteInfo.autoColoring) | |
MDT.main_frame.AutomaticColorsCogwheel:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\helpIconRnbw") | |
frame.toggleForceColorBlindMode:SetDisabled(false) | |
end | |
MDT:SetPresetColorPaletteInfo() | |
MDT:ColorAllPulls() | |
MDT:DrawAllHulls() | |
end) | |
frame.automaticColorsFrame:AddChild(frame.button) | |
frame.automaticColorsFrame:Hide() | |
end | |
function MDT:MakePullSelectionButtons(frame) | |
frame.PullButtonScrollGroup = AceGUI:Create("SimpleGroup") | |
frame.PullButtonScrollGroup:SetWidth(248) | |
frame.PullButtonScrollGroup:SetHeight(410) | |
frame.PullButtonScrollGroup:SetPoint("TOPLEFT",frame.WidgetGroup.frame,"BOTTOMLEFT",-4,-32) | |
frame.PullButtonScrollGroup:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,30) | |
frame.PullButtonScrollGroup:SetLayout("Fill") | |
frame.PullButtonScrollGroup.frame:SetFrameStrata(mainFrameStrata) | |
if not frame.PullButtonScrollGroup.frame.SetBackdrop then | |
Mixin(frame.PullButtonScrollGroup.frame, BackdropTemplateMixin) | |
end | |
frame.PullButtonScrollGroup.frame:SetBackdropColor(1,1,1,0) | |
frame.PullButtonScrollGroup.frame:Show() | |
self:FixAceGUIShowHide(frame.PullButtonScrollGroup) | |
frame.pullButtonsScrollFrame = AceGUI:Create("ScrollFrame") | |
frame.pullButtonsScrollFrame:SetLayout("Flow") | |
frame.PullButtonScrollGroup:AddChild(frame.pullButtonsScrollFrame) | |
frame.newPullButtons = {} | |
--rightclick context menu | |
frame.optionsDropDown = LibDD:Create_UIDropDownMenu("PullButtonsOptionsDropDown", nil) | |
end | |
function MDT:PresetsAddPull(index, data, preset) | |
preset = preset or self:GetCurrentPreset() | |
if not data then data = {} end | |
if index then | |
tinsert(preset.value.pulls,index,data) | |
else | |
tinsert(preset.value.pulls,data) | |
end | |
self:EnsureDBTables() | |
end | |
---Merges a list of pulls and inserts them at a specified destination. | |
--- | |
---@param pulls table List of all pull indices, that shall be merged (and deleted). If pulls | |
--- is a number, then the pull list is automatically generated from pulls | |
--- and destination. | |
---@param destination number The pull index, where the merged pull shall be inserted. | |
--- | |
---@author Dradux | |
function MDT:PresetsMergePulls(pulls, destination) | |
if type(pulls) == "number" then | |
pulls = {pulls, destination} | |
end | |
if not destination then | |
destination = pulls[#pulls] | |
end | |
local count_if = self.U.count_if | |
local newPull = {} | |
local removed_pulls = {} | |
for _, pullIdx in ipairs(pulls) do | |
local offset = count_if(removed_pulls, function(entry) | |
return entry < pullIdx | |
end) | |
local index = pullIdx - offset | |
local pull = self:GetCurrentPreset().value.pulls[index] | |
for enemyIdx,clones in pairs(pull) do | |
if string.match(enemyIdx, "^%d+$") then | |
-- it's really an enemy index | |
if tonumber(enemyIdx) then | |
if not newPull[enemyIdx] then | |
newPull[enemyIdx] = clones | |
else | |
for k,v in pairs(clones) do | |
if newPull[enemyIdx][k] ~= nil then | |
local newIndex = #newPull[enemyIdx] + 1 | |
newPull[enemyIdx][newIndex] = v | |
else | |
newPull[enemyIdx][k] = v | |
end | |
end | |
end | |
end | |
else | |
-- it's another pull option like color | |
local optionName = enemyIdx | |
local optionValue = clones | |
newPull[optionName] = optionValue | |
end | |
end | |
self:PresetsDeletePull(index) | |
tinsert(removed_pulls, pullIdx) | |
end | |
local offset = count_if(removed_pulls, function(entry) | |
return entry < destination | |
end) | |
local index = destination - offset | |
self:PresetsAddPull(index, newPull) | |
return index | |
end | |
function MDT:PresetsDeletePull(p, preset) | |
preset = preset or self:GetCurrentPreset() | |
if p == preset.value.currentPull then | |
preset.value.currentPull = math.max(p - 1, 1) | |
end | |
tremove(preset.value.pulls,p) | |
end | |
function MDT:GetPulls(preset) | |
preset = preset or self:GetCurrentPreset() | |
return preset.value.pulls | |
end | |
function MDT:GetPullsNum(preset) | |
preset = preset or self:GetCurrentPreset() | |
return table.getn(preset.value.pulls) | |
end | |
function MDT:CopyObject(obj, seen) | |
if type(obj) ~= 'table' then return obj end | |
if seen and seen[obj] then return seen[obj] end | |
local s = seen or {} | |
local res = setmetatable({}, getmetatable(obj)) | |
s[obj] = res | |
for k, v in pairs(obj) do res[self:CopyObject(k, s)] = self:CopyObject(v, s) end | |
return res | |
end | |
function MDT:PresetsSwapPulls(p1, p2) | |
local p1copy = self:CopyObject(self:GetCurrentPreset().value.pulls[p1]) | |
local p2copy = self:CopyObject(self:GetCurrentPreset().value.pulls[p2]) | |
self:GetCurrentPreset().value.pulls[p1] = p2copy | |
self:GetCurrentPreset().value.pulls[p2] = p1copy | |
end | |
function MDT:SetMapSublevel(pull) | |
--set map sublevel | |
local shouldResetZoom = false | |
local lastSubLevel | |
for enemyIdx,clones in pairs(db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls[pull]) do | |
if tonumber(enemyIdx) then | |
for idx,cloneIdx in pairs(clones) do | |
if MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][cloneIdx] then | |
lastSubLevel = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][cloneIdx].sublevel | |
end | |
end | |
end | |
end | |
if lastSubLevel then | |
shouldResetZoom = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel ~= lastSubLevel | |
db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.currentSublevel = lastSubLevel | |
if shouldResetZoom then | |
MDT:UpdateMap(true,true,true) | |
end | |
end | |
MDT:UpdateDungeonDropDown() | |
if shouldResetZoom then MDT:ZoomMapToDefault() end | |
end | |
function MDT:SetSelectionToPull(pull) | |
--if pull is not specified set pull to last pull in preset (for adding new pulls) | |
if not pull then | |
local count = 0 | |
for k,v in pairs(MDT:GetCurrentPreset().value.pulls) do | |
count = count + 1 | |
end | |
pull = count | |
end | |
--SaveCurrentPresetPull | |
if type(pull) == "number" and pull > 0 then | |
MDT:GetCurrentPreset().value.currentPull = pull | |
MDT:GetCurrentPreset().value.selection = { pull } | |
MDT:PickPullButton(pull) | |
MDT:DungeonEnemies_UpdateSelected(pull) | |
elseif type(pull) == "table" then | |
MDT:GetCurrentPreset().value.currentPull = pull[#pull] | |
MDT:GetCurrentPreset().value.selection = pull | |
MDT:ClearPullButtonPicks() | |
for _, pullIdx in ipairs(MDT:GetSelection()) do | |
MDT:PickPullButton(pullIdx, true) | |
MDT:DungeonEnemies_UpdateSelected(pullIdx) | |
end | |
end | |
end | |
---UpdatePullButtonNPCData | |
---Updates the portraits display of a button to show which and how many npcs are selected | |
function MDT:UpdatePullButtonNPCData(idx) | |
if db.devMode then return end | |
local preset = MDT:GetCurrentPreset() | |
local frame = MDT.main_frame.sidePanel | |
local enemyTable = {} | |
if preset.value.pulls[idx] then | |
local enemyTableIdx = 0 | |
for enemyIdx,clones in pairs(preset.value.pulls[idx]) do | |
if tonumber(enemyIdx) then | |
--check if enemy exists, remove if not | |
if MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx] then | |
local incremented = false | |
local npcId = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["id"] | |
local name = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["name"] | |
local creatureType = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["creatureType"] | |
local level = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["level"] | |
local baseHealth = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["health"] | |
for k,cloneIdx in pairs(clones) do | |
--check if clone exists, remove if not | |
if MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["clones"][cloneIdx] then | |
if self:IsCloneIncluded(enemyIdx,cloneIdx) then | |
if not incremented then enemyTableIdx = enemyTableIdx + 1 incremented = true end | |
if not enemyTable[enemyTableIdx] then enemyTable[enemyTableIdx] = {} end | |
enemyTable[enemyTableIdx].quantity = enemyTable[enemyTableIdx].quantity or 0 | |
enemyTable[enemyTableIdx].npcId = npcId | |
enemyTable[enemyTableIdx].count = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["count"] | |
enemyTable[enemyTableIdx].teemingCount = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["teemingCount"] | |
enemyTable[enemyTableIdx].displayId = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["displayId"] | |
enemyTable[enemyTableIdx].quantity = enemyTable[enemyTableIdx].quantity + 1 | |
enemyTable[enemyTableIdx].name = name | |
enemyTable[enemyTableIdx].level = level | |
enemyTable[enemyTableIdx].creatureType = creatureType | |
enemyTable[enemyTableIdx].baseHealth = baseHealth | |
enemyTable[enemyTableIdx].ignoreFortified = MDT.dungeonEnemies[db.currentDungeonIdx][enemyIdx]["ignoreFortified"] | |
end | |
end | |
end | |
end | |
end | |
end | |
end | |
frame.newPullButtons[idx]:SetNPCData(enemyTable) | |
if db.MDI.enabled and preset.mdi.beguiling == 13 then end | |
--display reaping icon | |
local pullForces = MDT:CountForces(idx,false) | |
local totalForcesMax = MDT:IsCurrentPresetTeeming() and MDT.dungeonTotalCount[db.currentDungeonIdx].teeming or MDT.dungeonTotalCount[db.currentDungeonIdx].normal | |
local currentPercent = pullForces/totalForcesMax | |
local oldPullForces | |
if idx == 1 then | |
oldPullForces = 0 | |
else | |
oldPullForces = MDT:CountForces(idx-1,false) | |
end | |
local oldPercent = oldPullForces/totalForcesMax | |
if (math.floor(currentPercent/0.2)>math.floor(oldPercent/0.2)) and oldPercent<1 and db.MDI.enabled and preset.mdi.beguiling == 13 then | |
frame.newPullButtons[idx]:ShowReapingIcon(true,currentPercent,oldPercent) | |
else | |
frame.newPullButtons[idx]:ShowReapingIcon(false,currentPercent,oldPercent) | |
end | |
--prideful icon | |
if (math.floor(currentPercent/0.2)>math.floor(oldPercent/0.2)) and oldPercent<1 and db.currentSeason == 5 then | |
frame.newPullButtons[idx]:ShowPridefulIcon(true,currentPercent,oldPercent) | |
else | |
frame.newPullButtons[idx]:ShowPridefulIcon(false,currentPercent,oldPercent) | |
end | |
--count per health | |
if pullForces>0 then | |
frame.newPullButtons[idx]:ShowCountPerHealth(true,pullForces,totalForcesMax) | |
else | |
frame.newPullButtons[idx]:ShowCountPerHealth(true,pullForces,totalForcesMax) | |
end | |
end | |
---ReloadPullButtons | |
---Reloads all pull buttons in the scroll frame | |
function MDT:ReloadPullButtons() | |
local frame = MDT.main_frame.sidePanel | |
if not frame.pullButtonsScrollFrame then return end | |
local preset = db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]] | |
--store scroll value | |
local oldScrollValue = frame.pullButtonsScrollFrame.localstatus.scrollvalue | |
--first release all children of the scroll frame | |
frame.pullButtonsScrollFrame:ReleaseChildren() | |
local maxPulls = 0 | |
for k,v in pairs(preset.value.pulls) do | |
maxPulls = maxPulls + 1 | |
end | |
--add new children to the scrollFrame, the frames are from the widget pool so no memory is wasted | |
local idx = 0 | |
for k,pull in ipairs(preset.value.pulls) do | |
idx = idx+1 | |
frame.newPullButtons[idx] = AceGUI:Create("MDTPullButton") | |
frame.newPullButtons[idx]:SetMaxPulls(maxPulls) | |
frame.newPullButtons[idx]:SetIndex(idx) | |
MDT:UpdatePullButtonNPCData(idx) | |
frame.newPullButtons[idx]:Initialize() | |
frame.newPullButtons[idx]:Enable() | |
frame.pullButtonsScrollFrame:AddChild(frame.newPullButtons[idx]) | |
end | |
--add the "new pull" button | |
frame.newPullButton = AceGUI:Create("MDTNewPullButton") | |
frame.newPullButton:Initialize() | |
frame.newPullButton:Enable() | |
frame.pullButtonsScrollFrame:AddChild(frame.newPullButton) | |
--set the scroll value back to the old value | |
frame.pullButtonsScrollFrame.scrollframe.obj:SetScroll(oldScrollValue) | |
frame.pullButtonsScrollFrame.scrollframe.obj:FixScroll() | |
if self:GetCurrentPreset().value.currentPull then | |
self:PickPullButton(self:GetCurrentPreset().value.currentPull) | |
end | |
end | |
---ClearPullButtonPicks | |
---Deselects all pull buttons | |
function MDT:ClearPullButtonPicks() | |
local frame = MDT.main_frame.sidePanel | |
for k,v in pairs(frame.newPullButtons) do | |
v:ClearPick() | |
end | |
end | |
---PickPullButton | |
---Selects the current pull button and deselects all other buttons | |
function MDT:PickPullButton(idx, keepPicked) | |
if db.devMode then return end | |
if not keepPicked then | |
MDT:ClearPullButtonPicks() | |
end | |
local frame = MDT.main_frame.sidePanel | |
frame.newPullButtons[idx]:Pick() | |
end | |
---AddPull | |
---Creates a new pull in the current preset and calls ReloadPullButtons to reflect the change in the scrollframe | |
function MDT:AddPull(index) | |
MDT:PresetsAddPull(index) | |
MDT:ReloadPullButtons() | |
MDT:SetSelectionToPull(index) | |
MDT:ColorPull() | |
MDT:DrawAllHulls() | |
end | |
function MDT:SetAutomaticColor(index) | |
--if not db.colorPaletteInfo.autoColoring then return end | |
local H = (index - 1) * 360 / 12 + 120 --db.automaticColorsNum | |
--if db.alternatingColors and index % 2 == 0 then | |
-- H = H + 180 | |
--end | |
local V = 1--0.5451 | |
--if db.brightColors then V = 1 end | |
local r, g, b = self:HSVtoRGB(H, 0.7554, V) | |
--self:DungeonEnemies_SetPullColor(index, r, g, b) | |
--self:UpdatePullButtonColor(index, r, g, b) | |
--self:DungeonEnemies_UpdateBlipColors(index, r, g, b) | |
--if self.liveSessionActive and self:GetCurrentPreset().uid == self.livePresetUID then | |
-- self:LiveSession_QueueColorUpdate() | |
--end | |
end | |
function MDT:UpdateAutomaticColors(index) | |
if not db.colorPaletteInfo.autoColoring then return end | |
for i = index or 1, self:GetPullsNum() do | |
self:SetAutomaticColor(i) | |
end | |
end | |
---Clears all the npcs out of a pull | |
function MDT:ClearPull(index) | |
table.wipe(db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].value.pulls[index]) | |
MDT:EnsureDBTables() | |
MDT:ReloadPullButtons() | |
MDT:SetSelectionToPull(index) | |
MDT:ColorPull() | |
MDT:DrawAllHulls() | |
--MDT:SetAutomaticColor(index) | |
end | |
---Moves the selected pull up | |
function MDT:MovePullUp(index) | |
MDT:PresetsSwapPulls(index,index-1) | |
MDT:ReloadPullButtons() | |
MDT:SetSelectionToPull(index-1) | |
MDT:ColorAllPulls(_, index-1) | |
MDT:DrawAllHulls() | |
--MDT:UpdateAutomaticColors(index - 1) | |
end | |
---Moves the selected pull down | |
function MDT:MovePullDown(index) | |
MDT:PresetsSwapPulls(index,index+1) | |
MDT:ReloadPullButtons() | |
MDT:SetSelectionToPull(index+1) | |
MDT:ColorAllPulls(_, index) | |
MDT:DrawAllHulls() | |
--MDT:UpdateAutomaticColors(index) | |
end | |
---Deletes the selected pull and makes sure that a pull will be selected afterwards | |
function MDT:DeletePull(index) | |
local pulls = self:GetPulls() | |
if #pulls == 1 then return end | |
self:PresetsDeletePull(index) | |
self:ReloadPullButtons() | |
local pullCount = 0 | |
for k,v in pairs(pulls) do | |
pullCount = pullCount + 1 | |
end | |
if index>pullCount then index = pullCount end | |
self:SetSelectionToPull(index) | |
--self:UpdateAutomaticColors(index) | |
self:ColorAllPulls(_, index-1) | |
MDT:DrawAllHulls() | |
end | |
---RenamePreset | |
function MDT:RenamePreset(renameText) | |
db.presets[db.currentDungeonIdx][db.currentPreset[db.currentDungeonIdx]].text = renameText | |
MDT.main_frame.RenameFrame:Hide() | |
MDT:UpdatePresetDropDown() | |
end | |
---GetFirstNotSelectedPullButton | |
function MDT:GetFirstNotSelectedPullButton(start, direction) | |
if not direction then | |
direction = -1 | |
elseif direction == "UP" then | |
direction = -1 | |
elseif direction == "DOWN" then | |
direction = 1 | |
end | |
local pullIdx = start | |
while MDT.U.contains(MDT:GetCurrentPreset().value.selection, pullIdx) | |
and MDT.U.isInRange(pullIdx, 1, #MDT:GetCurrentPreset().value.pulls) do | |
pullIdx = pullIdx + direction | |
end | |
if not MDT.U.isInRange(pullIdx, 1, #MDT:GetCurrentPreset().value.pulls) then | |
return | |
end | |
return pullIdx | |
end | |
function MDT:MakeRenameFrame(frame) | |
frame.RenameFrame = AceGUI:Create("Frame") | |
frame.RenameFrame:SetTitle(L["Rename Preset"]) | |
frame.RenameFrame:SetWidth(350) | |
frame.RenameFrame:SetHeight(150) | |
frame.RenameFrame:EnableResize(false) | |
frame.RenameFrame:SetLayout("Flow") | |
frame.RenameFrame:SetCallback("OnClose", function(widget) | |
end) | |
frame.RenameFrame:Hide() | |
local renameText | |
frame.RenameFrame.Editbox = AceGUI:Create("EditBox") | |
frame.RenameFrame.Editbox:SetLabel(L["Preset Name"]..":") | |
frame.RenameFrame.Editbox:SetWidth(200) | |
frame.RenameFrame.Editbox:SetCallback("OnEnterPressed", function(...) | |
local widget, event, text = ... | |
--check if name is valid, block button if so, unblock if valid | |
if MDT:SanitizePresetName(text) then | |
frame.RenameFrame.PresetRenameLabel:SetText(nil) | |
frame.RenameFrame.RenameButton:SetDisabled(false) | |
frame.RenameFrame.RenameButton.text:SetTextColor(1,0.8196,0) | |
renameText = text | |
else | |
frame.RenameFrame.PresetRenameLabel:SetText(string.format(L["Cannot rename preset to '%s'"],text)) | |
frame.RenameFrame.RenameButton:SetDisabled(true) | |
frame.RenameFrame.RenameButton.text:SetTextColor(0.5,0.5,0.5) | |
renameText = nil | |
end | |
frame.presetCreationFrame:DoLayout() | |
end) | |
frame.RenameFrame:AddChild(frame.RenameFrame.Editbox) | |
frame.RenameFrame.RenameButton = AceGUI:Create("Button") | |
frame.RenameFrame.RenameButton:SetText(L["Rename"]) | |
frame.RenameFrame.RenameButton:SetWidth(100) | |
frame.RenameFrame.RenameButton:SetCallback("OnClick",function() MDT:RenamePreset(renameText) end) | |
frame.RenameFrame:AddChild(frame.RenameFrame.RenameButton) | |
frame.RenameFrame.PresetRenameLabel = AceGUI:Create("Label") | |
frame.RenameFrame.PresetRenameLabel:SetText(nil) | |
frame.RenameFrame.PresetRenameLabel:SetWidth(390) | |
frame.RenameFrame.PresetRenameLabel:SetColor(1,0,0) | |
frame.RenameFrame:AddChild(frame.RenameFrame.PresetRenameLabel) | |
end | |
---MakeExportFrame | |
---Creates the frame used to export presets to a string which can be uploaded to text sharing websites like pastebin | |
function MDT:MakeExportFrame(frame) | |
frame.ExportFrame = AceGUI:Create("Frame") | |
frame.ExportFrame:SetTitle(L["Preset Export"]) | |
frame.ExportFrame:SetWidth(600) | |
frame.ExportFrame:SetHeight(400) | |
frame.ExportFrame:EnableResize(false) | |
frame.ExportFrame:SetLayout("Flow") | |
frame.ExportFrame:SetCallback("OnClose", function(widget) | |
end) | |
frame.ExportFrameEditbox = AceGUI:Create("MultiLineEditBox") | |
frame.ExportFrameEditbox:SetWidth(600) | |
frame.ExportFrameEditbox:DisableButton(true) | |
frame.ExportFrameEditbox:SetNumLines(20) | |
frame.ExportFrameEditbox:SetCallback("OnEnterPressed", function(widget, event, text) | |
end) | |
frame.ExportFrame:AddChild(frame.ExportFrameEditbox) | |
--frame.presetCreationFrame:SetStatusText("AceGUI-3.0 Example Container Frame") | |
frame.ExportFrame:Hide() | |
end | |
---MakeDeleteConfirmationFrame | |
---Creates the delete confirmation dialog that pops up when a user wants to delete a preset | |
function MDT:MakeDeleteConfirmationFrame(frame) | |
frame.DeleteConfirmationFrame = AceGUI:Create("Frame") | |
frame.DeleteConfirmationFrame:SetTitle(L["Delete Preset"]) | |
frame.DeleteConfirmationFrame:SetWidth(250) | |
frame.DeleteConfirmationFrame:SetHeight(120) | |
frame.DeleteConfirmationFrame:EnableResize(false) | |
frame.DeleteConfirmationFrame:SetLayout("Flow") | |
frame.DeleteConfirmationFrame:SetCallback("OnClose", function(widget) | |
end) | |
frame.DeleteConfirmationFrame.label = AceGUI:Create("Label") | |
frame.DeleteConfirmationFrame.label:SetWidth(390) | |
frame.DeleteConfirmationFrame.label:SetHeight(10) | |
--frame.DeleteConfirmationFrame.label:SetColor(1,0,0) | |
frame.DeleteConfirmationFrame:AddChild(frame.DeleteConfirmationFrame.label) | |
frame.DeleteConfirmationFrame.OkayButton = AceGUI:Create("Button") | |
frame.DeleteConfirmationFrame.OkayButton:SetText(L["Delete"]) | |
frame.DeleteConfirmationFrame.OkayButton:SetWidth(100) | |
frame.DeleteConfirmationFrame.OkayButton:SetCallback("OnClick",function() | |
MDT:DeletePreset(db.currentPreset[db.currentDungeonIdx]) | |
frame.DeleteConfirmationFrame:Hide() | |
end) | |
frame.DeleteConfirmationFrame.CancelButton = AceGUI:Create("Button") | |
frame.DeleteConfirmationFrame.CancelButton:SetText(L["Cancel"]) | |
frame.DeleteConfirmationFrame.CancelButton:SetWidth(100) | |
frame.DeleteConfirmationFrame.CancelButton:SetCallback("OnClick",function() | |
frame.DeleteConfirmationFrame:Hide() | |
end) | |
frame.DeleteConfirmationFrame:AddChild(frame.DeleteConfirmationFrame.OkayButton) | |
frame.DeleteConfirmationFrame:AddChild(frame.DeleteConfirmationFrame.CancelButton) | |
frame.DeleteConfirmationFrame:Hide() | |
end | |
---MakeClearConfirmationFrame | |
---Creates the clear confirmation dialog that pops up when a user wants to clear a preset | |
function MDT:MakeClearConfirmationFrame(frame) | |
frame.ClearConfirmationFrame = AceGUI:Create("Frame") | |
frame.ClearConfirmationFrame:SetTitle(L["Reset Preset"]) | |
frame.ClearConfirmationFrame:SetWidth(250) | |
frame.ClearConfirmationFrame:SetHeight(120) | |
frame.ClearConfirmationFrame:EnableResize(false) | |
frame.ClearConfirmationFrame:SetLayout("Flow") | |
frame.ClearConfirmationFrame:SetCallback("OnClose", function(widget) | |
end) | |
frame.ClearConfirmationFrame.label = AceGUI:Create("Label") | |
frame.ClearConfirmationFrame.label:SetWidth(390) | |
frame.ClearConfirmationFrame.label:SetHeight(10) | |
--frame.DeleteConfirmationFrame.label:SetColor(1,0,0) | |
frame.ClearConfirmationFrame:AddChild(frame.ClearConfirmationFrame.label) | |
frame.ClearConfirmationFrame.OkayButton = AceGUI:Create("Button") | |
frame.ClearConfirmationFrame.OkayButton:SetText(L["Reset"]) | |
frame.ClearConfirmationFrame.OkayButton:SetWidth(100) | |
frame.ClearConfirmationFrame.OkayButton:SetCallback("OnClick",function() | |
self:ClearPreset(self:GetCurrentPreset()) | |
if self.liveSessionActive and self:GetCurrentPreset().uid == self.livePresetUID then MDT:LiveSession_SendCommand("clear") end | |
frame.ClearConfirmationFrame:Hide() | |
end) | |
frame.ClearConfirmationFrame.CancelButton = AceGUI:Create("Button") | |
frame.ClearConfirmationFrame.CancelButton:SetText(L["Cancel"]) | |
frame.ClearConfirmationFrame.CancelButton:SetWidth(100) | |
frame.ClearConfirmationFrame.CancelButton:SetCallback("OnClick",function() | |
frame.ClearConfirmationFrame:Hide() | |
end) | |
frame.ClearConfirmationFrame:AddChild(frame.ClearConfirmationFrame.OkayButton) | |
frame.ClearConfirmationFrame:AddChild(frame.ClearConfirmationFrame.CancelButton) | |
frame.ClearConfirmationFrame:Hide() | |
end | |
---OpenConfirmationFrame | |
---Creates a generic dialog that pops up when a user wants needs confirmation for an action | |
function MDT:OpenConfirmationFrame(width, height, title, buttonText, prompt, callback, buttonText2, callback2) | |
local f = MDT.main_frame.ConfirmationFrame | |
if not f then | |
MDT.main_frame.ConfirmationFrame = AceGUI:Create("Frame") | |
f = MDT.main_frame.ConfirmationFrame | |
f:EnableResize(false) | |
f:SetLayout("Flow") | |
f:SetCallback("OnClose", function(widget) end) | |
f.label = AceGUI:Create("Label") | |
f.label:SetWidth(390) | |
f.label:SetHeight(height-20) | |
f:AddChild(f.label) | |
f.OkayButton = AceGUI:Create("Button") | |
f.OkayButton:SetWidth(100) | |
f:AddChild(f.OkayButton) | |
f.CancelButton = AceGUI:Create("Button") | |
f.CancelButton:SetText(L["Cancel"]) | |
f.CancelButton:SetWidth(100) | |
f.CancelButton:SetCallback("OnClick",function() | |
MDT:HideAllDialogs() | |
end) | |
f:AddChild(f.CancelButton) | |
end | |
f:SetWidth(width or 250) | |
f:SetHeight(height or 120) | |
f:SetTitle(title) | |
f.OkayButton:SetText(buttonText) | |
f.OkayButton:SetCallback("OnClick",function()callback() | |
MDT:HideAllDialogs() end) | |
if buttonText2 then | |
f.CancelButton:SetText(buttonText2) else | |
f.CancelButton:SetText(L["Cancel"]) | |
end | |
if callback2 then | |
f.CancelButton:SetCallback("OnClick",function()callback2() | |
MDT:HideAllDialogs() end) | |
else | |
f.CancelButton:SetCallback("OnClick",function() | |
MDT:HideAllDialogs() end) | |
end | |
MDT:HideAllDialogs() | |
f:ClearAllPoints() | |
f:SetPoint("CENTER", MDT.main_frame,"CENTER",0,50) | |
f.label:SetText(prompt) | |
f:Show() | |
end | |
---CreateTutorialButton | |
---Creates the tutorial button and sets up the help plate frames | |
function MDT:CreateTutorialButton(parent) | |
local scale = self:GetScale() | |
local sidePanelHeight = MDT.main_frame.sidePanel.PullButtonScrollGroup.frame:GetHeight() | |
local helpPlate = { | |
FramePos = { x = 0, y = 0 }, | |
FrameSize = { width = sizex, height = sizey }, | |
[1] = { ButtonPos = { x = 205, y = 0 }, HighLightBox = { x = 0, y = 0, width = 200, height = 56 }, ToolTipDir = "RIGHT", ToolTipText = L["helpPlateDungeonSelect"] }, | |
[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") }, | |
[3] = { ButtonPos = { x = 900*scale, y = 0*scale }, HighLightBox = { x = 838*scale, y = 30, width = 251, height = 115 }, ToolTipDir = "LEFT", ToolTipText = L["helpPlatePresets"] }, | |
[4] = { ButtonPos = { x = 900*scale, y = -87*scale }, HighLightBox = { x = 838*scale, y = 30-115, width = 251, height = 102 }, ToolTipDir = "LEFT", ToolTipText = L["helpPlateDungeon"] }, | |
[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") }, | |
} | |
if not parent.HelpButton then | |
parent.HelpButton = CreateFrame("Button","MDTMainHelpPlateButton",parent,"MainHelpPlateButton") | |
parent.HelpButton:ClearAllPoints() | |
parent.HelpButton:SetPoint("TOPLEFT",parent,"TOPLEFT",0,48) | |
parent.HelpButton:SetScale(0.8) | |
parent.HelpButton:SetFrameStrata(mainFrameStrata) | |
parent.HelpButton:SetFrameLevel(6) | |
parent.HelpButton:Hide() | |
--hook to make button hide | |
local originalHide = parent.Hide | |
function parent:Hide(...) | |
parent.HelpButton:Hide() | |
return originalHide(self, ...) | |
end | |
local function TutorialButtonOnHide(self) | |
HelpPlate_Hide(true) | |
end | |
parent.HelpButton:SetScript("OnHide",TutorialButtonOnHide) | |
end | |
local function TutorialButtonOnClick(self) | |
if not HelpPlate_IsShowing(helpPlate) then | |
HelpPlate_Show(helpPlate, MDT.main_frame, self) | |
else | |
HelpPlate_Hide(true) | |
end | |
end | |
parent.HelpButton:SetScript("OnClick",TutorialButtonOnClick) | |
end | |
---RegisterOptions | |
---Register the options of the addon to the blizzard options | |
function MDT:RegisterOptions() | |
MDT.blizzardOptionsMenuTable = { | |
name = "Mythic Dungeon Tools", | |
type = 'group', | |
args = { | |
--[[ | |
language = { | |
type = 'select', | |
style = 'dropdown', | |
name = "Language", | |
desc = "Sets the Language of the AddOn. Requires Reload to take effect", | |
values = { | |
[1] = "English", | |
[2] = "Deutsch", | |
[3] = "Español (esES)", | |
[4] = "Español (esMX)", | |
[5] = "Français", | |
[6] = "Italiano", | |
[7] = "Português Brasileiro", | |
[8] = "Русский", | |
[9] = "한국어", | |
[10] = "简体中文 (zhCN)", | |
[11] = "國語 (zhTW)", | |
}, | |
get = function() return db.language end, | |
set = function(_, newValue) | |
db.language = newValue | |
end, | |
}, | |
]] | |
enable = { | |
type = 'toggle', | |
name = L["Enable Minimap Button"], | |
desc = L["If the Minimap Button is enabled"], | |
get = function() return not db.minimap.hide end, | |
set = function(_, newValue) | |
db.minimap.hide = not newValue | |
if not db.minimap.hide then | |
icon:Show("MythicDungeonTools") | |
else | |
icon:Hide("MythicDungeonTools") | |
end | |
end, | |
order = 1, | |
width = "full", | |
}, | |
tooltipSelect ={ | |
type = 'select', | |
name = L["Choose NPC tooltip position"], | |
values = { | |
[1] = L["Next to the NPC"], | |
[2] = L["In the bottom right corner"], | |
}, | |
get = function() return db.tooltipInCorner and 2 or 1 end, | |
set = function(_,newValue) | |
if newValue == 1 then db.tooltipInCorner = false end | |
if newValue == 2 then db.tooltipInCorner = true end | |
end, | |
style = 'dropdown', | |
}, | |
enemyForcesFormat = { | |
type = "select", | |
name = L["Choose Enemy Forces Format"], | |
values = { | |
[1] = L["Forces only: 5/200"], | |
[2] = L["Forces+%: 5/200 (2.5%)"], | |
}, | |
get = function() return db.enemyForcesFormat end, | |
set = function(_,newValue) db.enemyForcesFormat = newValue end, | |
style = "dropdown", | |
}, | |
enemyStyle = { | |
type = "select", | |
name = L["Choose Enemy Style. Requires Reload"], | |
values = { | |
[1] = L["Portrait"], | |
[2] = L["Plain Texture"], | |
}, | |
get = function() return db.enemyStyle end, | |
set = function(_,newValue) db.enemyStyle = newValue end, | |
style = "dropdown", | |
}, | |
} | |
} | |
LibStub("AceConfigRegistry-3.0"):RegisterOptionsTable("MythicDungeonTools", MDT.blizzardOptionsMenuTable) | |
self.blizzardOptionsMenu = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("MythicDungeonTools", "MythicDungeonTools") | |
end | |
function MDT:Round(number, decimals) | |
return (("%%.%df"):format(decimals)):format(number) | |
end | |
function MDT:RGBToHex(r, g, b) | |
r = r*255 | |
g = g*255 | |
b = b*255 | |
return ("%.2x%.2x%.2x"):format(r, g, b) | |
end | |
function MDT:HexToRGB(rgb) | |
if string.len(rgb) == 6 then | |
local r, g, b | |
r, g, b = tonumber('0x'..strsub(rgb, 0, 2)), tonumber('0x'..strsub(rgb, 3, 4)), tonumber('0x'..strsub(rgb, 5, 6)) | |
if not r then r = 0 else r = r/255 end | |
if not g then g = 0 else g = g/255 end | |
if not b then b = 0 else b = b/255 end | |
return r,g,b | |
else | |
return | |
end | |
end | |
---https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB_alternative | |
function MDT:HSVtoRGB(H, S, V) | |
H = H % 361 | |
local function f(n) | |
k = (n + H/60) % 6 | |
return V - V * S * math.max(math.min(k, 4 - k, 1), 0) | |
end | |
return f(5), f(3), f(1) | |
end | |
function MDT:DeepCopy(orig) | |
local orig_type = type(orig) | |
local copy | |
if orig_type == 'table' then | |
copy = {} | |
for orig_key, orig_value in next, orig, nil do | |
copy[MDT:DeepCopy(orig_key)] = MDT:DeepCopy(orig_value) | |
end | |
setmetatable(copy, MDT:DeepCopy(getmetatable(orig))) | |
else -- number, string, boolean, etc | |
copy = orig | |
end | |
return copy | |
end | |
---scale if preset comes from live session | |
function MDT:StorePresetObject(obj, ignoreScale, preset) | |
--adjust scale | |
if not ignoreScale then | |
local scale = self:GetScale() | |
if obj.n then | |
obj.d[1] = obj.d[1]*(1/scale) | |
obj.d[2] = obj.d[2]*(1/scale) | |
else | |
for idx,coord in pairs(obj.l) do | |
obj.l[idx] = self:Round(obj.l[idx]*(1/scale),1) | |
end | |
end | |
end | |
preset = preset or self:GetCurrentPreset() | |
preset.objects = preset.objects or {} | |
--we insert the object infront of the first hidden oject | |
local pos = 1 | |
for k,v in ipairs(preset.objects) do | |
pos = pos + 1 | |
if v.d[4]==false then | |
pos = pos - 1 | |
end | |
end | |
if pos>1 then | |
tinsert(preset.objects,pos,self:DeepCopy(obj)) | |
else | |
tinsert(preset.objects,self:DeepCopy(obj)) | |
end | |
end | |
---excluding notes, these are handled in OverrideScrollFrameScripts | |
function MDT:UpdatePresetObjectOffsets(idx, x, y, preset, silent) | |
--adjust coords to scale | |
local scale = self:GetScale() | |
x = self:Round(x*(1/scale),1) | |
y = self:Round(y*(1/scale),1) | |
preset = preset or self:GetCurrentPreset() | |
for objectIndex,obj in pairs(preset.objects) do | |
if objectIndex == idx then | |
for coordIdx,coord in pairs(obj.l) do | |
if coordIdx%2==1 then | |
obj.l[coordIdx] = coord-x | |
else | |
obj.l[coordIdx] = coord-y | |
end | |
end | |
end | |
end | |
--redraw everything | |
if not silent then self:DrawAllPresetObjects() end | |
end | |
---Draws all Preset objects on the map canvas/sublevel | |
function MDT:DrawAllPresetObjects() | |
self:ReleaseAllActiveTextures() | |
local scale = self:GetScale() | |
local currentPreset = self:GetCurrentPreset() | |
local currentSublevel = self:GetCurrentSubLevel() | |
currentPreset.objects = currentPreset.objects or {} | |
for objectIndex,obj in pairs(currentPreset.objects) do | |
self:DrawPresetObject(obj,objectIndex,scale,currentPreset,currentSublevel) | |
end | |
end | |
---Draws specific preset object | |
function MDT:DrawPresetObject(obj, objectIndex, scale, currentPreset, currentSublevel) | |
if not objectIndex then | |
for oIndex,o in pairs(currentPreset.objects) do | |
if o == obj then | |
objectIndex = oIndex | |
break | |
end | |
end | |
end | |
--d: size,lineFactor,sublevel,shown,colorstring,drawLayer,[smooth] | |
--l: x1,y1,x2,y2,... | |
local color = {} | |
if obj.d[3] == currentSublevel and obj.d[4] then | |
if obj.n then | |
local x = obj.d[1]*scale | |
local y = obj.d[2]*scale | |
local text = obj.d[5] | |
self:DrawNote(x,y,text,objectIndex) | |
else | |
obj.d[1] = obj.d[1] or 5 | |
color.r,color.g,color.b = self:HexToRGB(obj.d[5]) | |
--lines | |
local x1,y1,x2,y2 | |
local lastx,lasty | |
for _,coord in pairs(obj.l) do | |
if not x1 then x1 = coord | |
elseif not y1 then y1 = coord | |
elseif not x2 then | |
x2 = coord | |
lastx = coord | |
elseif not y2 then | |
y2 = coord | |
lasty = coord | |
end | |
if x1 and y1 and x2 and y2 then | |
x1 = x1*scale | |
x2 = x2*scale | |
y1 = y1*scale | |
y2 = y2*scale | |
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) | |
--circles if smooth | |
if obj.d[7] then | |
self:DrawCircle(x1,y1,obj.d[1]*0.3*scale,color,nil,obj.d[6],nil,objectIndex) | |
self:DrawCircle(x2,y2,obj.d[1]*0.3*scale,color,nil,obj.d[6],nil,objectIndex) | |
end | |
x1,y1,x2,y2 = nil,nil,nil,nil | |
end | |
end | |
--triangle | |
if obj.t and lastx and lasty then | |
lastx = lastx*scale | |
lasty = lasty*scale | |
self:DrawTriangle(lastx,lasty,obj.t[1],obj.d[1]*scale,color,nil,obj.d[6],nil,objectIndex) | |
end | |
--remove empty objects leftover from erasing | |
if obj.l then | |
local lineCount = 0 | |
for _,_ in pairs(obj.l) do | |
lineCount = lineCount +1 | |
end | |
if lineCount == 0 then | |
currentPreset.objects[objectIndex] = nil | |
end | |
end | |
end | |
end | |
end | |
---DeletePresetObjects | |
---Deletes objects from the current preset in the current sublevel | |
function MDT:DeletePresetObjects(preset, silent) | |
preset = preset or self:GetCurrentPreset() | |
if preset == self:GetCurrentPreset() then silent = false end | |
local currentSublevel = self:GetCurrentSubLevel() | |
for objectIndex,obj in pairs(preset.objects) do | |
if obj.d[3] == currentSublevel then | |
preset.objects[objectIndex] = nil | |
end | |
end | |
if not silent then self:DrawAllPresetObjects() end | |
end | |
---StepBack | |
---Undo the latest drawing | |
function MDT:PresetObjectStepBack(preset, silent) | |
preset = preset or self:GetCurrentPreset() | |
if preset == self:GetCurrentPreset() then silent = false end | |
preset.objects = preset.objects or {} | |
local length = 0 | |
for k,v in pairs(preset.objects) do | |
length = length + 1 | |
end | |
if length>0 then | |
for i = length,1,-1 do | |
if preset.objects[i] and preset.objects[i].d[4] then | |
preset.objects[i].d[4] = false | |
if not silent then self:DrawAllPresetObjects() end | |
break | |
end | |
end | |
end | |
end | |
---StepForward | |
---Redo the latest drawing | |
function MDT:PresetObjectStepForward(preset, silent) | |
preset = preset or MDT:GetCurrentPreset() | |
if preset == self:GetCurrentPreset() then silent = false end | |
preset.objects = preset.objects or {} | |
local length = 0 | |
for k,v in ipairs(preset.objects) do | |
length = length + 1 | |
end | |
if length>0 then | |
for i = 1,length do | |
if preset.objects[i] and not preset.objects[i].d[4] then | |
preset.objects[i].d[4] = true | |
if not silent then self:DrawAllPresetObjects() end | |
break | |
end | |
end | |
end | |
end | |
function MDT:FixAceGUIShowHide(widget, frame, isFrame, hideOnly) | |
frame = frame or MDT.main_frame | |
local originalShow,originalHide = frame.Show,frame.Hide | |
if not isFrame then | |
widget = widget.frame | |
end | |
function frame:Hide(...) | |
widget:Hide() | |
return originalHide(self, ...) | |
end | |
if hideOnly then return end | |
function frame:Show(...) | |
widget:Show() | |
return originalShow(self, ...) | |
end | |
end | |
function MDT:GetCurrentAffixWeek() | |
if not IsAddOnLoaded("Blizzard_ChallengesUI") then | |
LoadAddOn("Blizzard_ChallengesUI") | |
end | |
C_MythicPlus.RequestCurrentAffixes() | |
C_MythicPlus.RequestMapInfo() | |
C_MythicPlus.RequestRewards() | |
local affixIds = C_MythicPlus.GetCurrentAffixes() --table | |
if not affixIds then return end | |
if not affixIds[1] then return 1 end | |
for week,affixes in ipairs(affixWeeks) do | |
if affixes[1] == affixIds[2].id and affixes[2] == affixIds[3].id and affixes[3] == affixIds[1].id then | |
return week | |
end | |
end | |
return 1 | |
end | |
---PrintCurrentAffixes | |
---Helper function to print out current affixes with their ids and their names | |
function MDT:PrintCurrentAffixes() | |
--run this once so blizz stuff is loaded | |
MDT:GetCurrentAffixWeek() | |
--https://www.wowhead.com/affixes | |
local affixNames = { | |
[1] =L["Overflowing"], | |
[2] =L["Skittish"], | |
[3] =L["Volcanic"], | |
[4] =L["Necrotic"], | |
[5] =L["Teeming"], | |
[6] =L["Raging"], | |
[7] =L["Bolstering"], | |
[8] =L["Sanguine"], | |
[9] =L["Tyrannical"], | |
[10] =L["Fortified"], | |
[11] =L["Bursting"], | |
[12] =L["Grievous"], | |
[13] =L["Explosive"], | |
[14] =L["Quaking"], | |
[15] =L["Relentless"], | |
[16] =L["Infested"], | |
[117] =L["Reaping"], | |
[119] =L["Beguiling"], | |
[120] =L["Awakened"], | |
[121] =L["Prideful"], | |
[122] =L["Inspiring"], | |
[123] =L["Spiteful"], | |
[124] =L["Storming"], | |
[128] =L["Tormented"], | |
} | |
local affixIds = C_MythicPlus.GetCurrentAffixes() | |
for idx,data in ipairs(affixIds) do | |
print(data.id,affixNames[data.id]) | |
end | |
end | |
---IsPlayerInGroup | |
---Checks if the players is in a group/raid and returns the type | |
function MDT:IsPlayerInGroup() | |
local inGroup = (UnitInRaid("player") and "RAID") or (IsInGroup() and "PARTY") | |
return inGroup | |
end | |
function MDT:ResetMainFramePos(soft) | |
--soft reset just redraws the window with existing coordinates from db | |
local f = self.main_frame | |
if not soft then | |
db.nonFullscreenScale = 1 | |
db.maximized = false | |
if not framesInitialized then initFrames() end | |
f.maximizeButton:Minimize() | |
db.xoffset = 0 | |
db.yoffset = -150 | |
db.anchorFrom = "TOP" | |
db.anchorTo = "TOP" | |
end | |
f:ClearAllPoints() | |
f:SetPoint(db.anchorTo, UIParent,db.anchorFrom, db.xoffset, db.yoffset) | |
end | |
function MDT:DropIndicator() | |
local indicator = MDT.main_frame.drop_indicator | |
if not indicator then | |
indicator = CreateFrame("Frame", "MDT_DropIndicator") | |
indicator:SetHeight(4) | |
indicator:SetFrameStrata("FULLSCREEN") | |
local texture = indicator:CreateTexture(nil, "FULLSCREEN") | |
texture:SetBlendMode("ADD") | |
texture:SetAllPoints(indicator) | |
texture:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight") | |
local icon = indicator:CreateTexture(nil, "OVERLAY") | |
icon:ClearAllPoints() | |
icon:SetSize(16, 16) | |
icon:SetPoint("CENTER", indicator) | |
indicator.icon = icon | |
indicator.texture = texture | |
MDT.main_frame.drop_indicator = indicator | |
indicator:Hide() | |
end | |
return indicator | |
end | |
function MDT:IsShown_DropIndicator() | |
local indicator = MDT:DropIndicator() | |
return indicator:IsShown() | |
end | |
function MDT:Show_DropIndicator(target, pos) | |
local indicator = MDT:DropIndicator() | |
indicator:ClearAllPoints() | |
if pos == "TOP" then | |
indicator:SetPoint("BOTTOMLEFT", target.frame, "TOPLEFT", 0, -1) | |
indicator:SetPoint("BOTTOMRIGHT", target.frame, "TOPRIGHT", 0, -1) | |
indicator:Show() | |
elseif pos == "BOTTOM" then | |
indicator:SetPoint("TOPLEFT", target.frame, "BOTTOMLEFT", 0, 1) | |
indicator:SetPoint("TOPRIGHT", target.frame, "BOTTOMRIGHT", 0, 1) | |
indicator:Show() | |
end | |
end | |
function MDT:Hide_DropIndicator() | |
local indicator = MDT:DropIndicator() | |
indicator:Hide() | |
end | |
function MDT:GetSelection() | |
if not MDT:GetCurrentPreset().value.selection or #MDT:GetCurrentPreset().value.selection == 0 then | |
MDT:GetCurrentPreset().value.selection = { MDT:GetCurrentPreset().value.currentPull } | |
end | |
return MDT:GetCurrentPreset().value.selection | |
end | |
function MDT:GetScrollingAmount(scrollFrame, pixelPerSecond) | |
local viewheight = scrollFrame.frame.obj.content:GetHeight() | |
return (pixelPerSecond / viewheight) * 1000 | |
end | |
function MDT:ScrollToPull(pullIdx) | |
-- Get scroll frame | |
local scrollFrame = MDT.main_frame.sidePanel.pullButtonsScrollFrame | |
-- Get amount of total pulls plus the extra button "+ Add Pull" | |
local pulls = #MDT:GetCurrentPreset().value.pulls + 1 or 1 | |
local percentage = pullIdx / pulls | |
local value = percentage * 1000 | |
scrollFrame:SetScroll(value) | |
scrollFrame:FixScroll() | |
end | |
function MDT:CopyPullOptions(sourceIdx, destinationIdx) | |
local preset = MDT:GetCurrentPreset() | |
local pulls = preset.value.pulls | |
local source = pulls[sourceIdx] | |
local destination = pulls[destinationIdx] | |
if source and destination then | |
for optionName, optionValue in pairs(source) do | |
-- Assure, that it is an option and not an enemy index | |
if not string.match(optionName, "^%d+$") then | |
destination[optionName] = optionValue | |
end | |
end | |
end | |
end | |
function MDT:GetPullButton(pullIdx) | |
local frame = MDT.main_frame.sidePanel | |
return frame.newPullButtons[pullIdx] | |
end | |
function MDT:UpdatePullButtonColor(pullIdx, r, g, b) | |
local button = MDT:GetPullButton(pullIdx) | |
local function updateSwatch(t) | |
for k,v in pairs(t) do | |
if v.hasColorSwatch then | |
v.r,v.g,v.b = r,g,b | |
return | |
end | |
end | |
end | |
button.color.r, button.color.g, button.color.b = r, g, b | |
updateSwatch(button.menu) | |
updateSwatch(button.multiselectMenu) | |
button:UpdateColor() | |
end | |
--/run MDT:ResetDataCache(); | |
function MDT:ResetDataCache() | |
db.dungeonEnemies = nil | |
db.mapPOIs = nil | |
ReloadUI() | |
end | |
function MDT:HardReset() | |
MythicDungeonToolsDB = nil | |
ReloadUI() | |
end | |
function initFrames() | |
local main_frame = CreateFrame("frame", "MDTFrame", UIParent) | |
tinsert(UISpecialFrames,"MDTFrame") | |
--cache dungeon data to not lose data during reloads | |
if db.devMode then | |
if db.dungeonEnemies then | |
MDT.dungeonEnemies = db.dungeonEnemies | |
else | |
db.dungeonEnemies = MDT.dungeonEnemies | |
end | |
if db.mapPOIs then | |
MDT.mapPOIs = db.mapPOIs | |
else | |
db.mapPOIs = MDT.mapPOIs | |
end | |
end | |
db.nonFullscreenScale = db.nonFullscreenScale or 1 | |
if not db.maximized then db.scale = db.nonFullscreenScale end | |
main_frame:SetFrameStrata(mainFrameStrata) | |
main_frame:SetFrameLevel(1) | |
main_frame.background = main_frame:CreateTexture(nil, "BACKGROUND") | |
main_frame.background:SetAllPoints() | |
main_frame.background:SetDrawLayer(canvasDrawLayer, 1) | |
main_frame.background:SetColorTexture(unpack(MDT.BackdropColor)) | |
main_frame.background:SetAlpha(0.2) | |
main_frame:SetSize(sizex*db.scale, sizey*db.scale) | |
main_frame:SetResizable(true) | |
main_frame:SetMinResize(sizex*0.75,sizey*0.75) | |
local _,_,fullscreenScale = MDT:GetFullScreenSizes() | |
main_frame:SetMaxResize(sizex*fullscreenScale,sizey*fullscreenScale) | |
MDT.main_frame = main_frame | |
main_frame.mainFrametex = main_frame:CreateTexture(nil, "BACKGROUND") | |
main_frame.mainFrametex:SetAllPoints() | |
main_frame.mainFrametex:SetDrawLayer(canvasDrawLayer, -5) | |
main_frame.mainFrametex:SetColorTexture(unpack(MDT.BackdropColor)) | |
local version = GetAddOnMetadata(AddonName, "Version"):gsub("%.","") | |
db.version = tonumber(version) | |
-- Set frame position | |
main_frame:ClearAllPoints() | |
main_frame:SetPoint(db.anchorTo, UIParent,db.anchorFrom, db.xoffset, db.yoffset) | |
main_frame.contextDropdown = LibDD:Create_UIDropDownMenu("MDTContextDropDown", nil) | |
MDT:CheckCurrentZone(true) | |
MDT:EnsureDBTables() | |
MDT:MakeTopBottomTextures(main_frame) | |
MDT:MakeMapTexture(main_frame) | |
MDT:MakeSidePanel(main_frame) | |
MDT:CreateMenu() | |
MDT:MakePresetCreationFrame(main_frame) | |
MDT:MakePresetImportFrame(main_frame) | |
MDT:DungeonEnemies_CreateFramePools() | |
--MDT:UpdateDungeonEnemies(main_frame) | |
MDT:CreateDungeonSelectDropdown(main_frame) | |
MDT:MakePullSelectionButtons(main_frame.sidePanel) | |
MDT:MakeExportFrame(main_frame) | |
MDT:MakeRenameFrame(main_frame) | |
MDT:MakeDeleteConfirmationFrame(main_frame) | |
MDT:MakeClearConfirmationFrame(main_frame) | |
MDT:CreateTutorialButton(main_frame) | |
MDT:POI_CreateFramePools() | |
MDT:MakeChatPresetImportFrame(main_frame) | |
MDT:MakeSendingStatusBar(main_frame) | |
MDT:MakeAutomaticColorsFrame(main_frame) | |
MDT:MakeCustomColorFrame(main_frame.automaticColorsFrame) | |
--devMode | |
if db.devMode and MDT.CreateDevPanel then | |
MDT:CreateDevPanel(MDT.main_frame) | |
end | |
if not db.MDI.enabled then | |
db.currentSeason = defaultSavedVars.global.currentSeason | |
end | |
--ElvUI skinning | |
local skinTooltip = function(tooltip) | |
if IsAddOnLoaded("ElvUI") and ElvUI[1].Tooltip then | |
local borderTextures = {"BorderBottom","BorderBottomLeft","BorderBottomRight","BorderLeft","BorderRight","BorderTop","BorderTopLeft","BorderTopRight"} | |
for k,v in pairs(borderTextures) do | |
tooltip[v]:Kill() | |
end | |
tooltip.Background:Kill() | |
if not tooltip.SetBackdrop then | |
Mixin(tooltip, BackdropTemplateMixin) | |
end | |
tooltip:HookScript("OnShow",function(self) | |
if self:IsForbidden() then return end | |
self:SetTemplate("Transparent", nil, true) --ignore updates | |
local r, g, b = self:GetBackdropColor() | |
self:SetBackdropColor(r, g, b, ElvUI[1].Tooltip.db.colorAlpha) | |
end) | |
if tooltip.String then tooltip.String:SetFont(tooltip.String:GetFont(),11) end | |
if tooltip.topString then tooltip.topString:SetFont(tooltip.topString:GetFont(),11) end | |
if tooltip.botString then tooltip.botString:SetFont(tooltip.botString:GetFont(),11) end | |
end | |
end | |
--tooltip new | |
do | |
MDT.tooltip = CreateFrame("Frame", "MDTModelTooltip", UIParent, "TooltipBorderedFrameTemplate") | |
local tooltip = MDT.tooltip | |
tooltip:SetClampedToScreen(true) | |
tooltip:SetFrameStrata("TOOLTIP") | |
tooltip.mySizes ={x=290,y=120} | |
tooltip:SetSize(tooltip.mySizes.x, tooltip.mySizes.y) | |
tooltip.Model = CreateFrame("PlayerModel", nil, tooltip) | |
tooltip.Model:SetFrameLevel(1) | |
tooltip.Model:SetSize(100,100) | |
tooltip.Model.fac = 0 | |
tooltip.Model:SetScript("OnUpdate",function (self,elapsed) | |
self.fac = self.fac + 0.5 | |
if self.fac >= 360 then | |
self.fac = 0 | |
end | |
self:SetFacing(PI*2 / 360 * self.fac) | |
end) | |
tooltip.Model:SetPoint("TOPLEFT", tooltip, "TOPLEFT",7,-7) | |
tooltip.String = tooltip:CreateFontString("MDTToolTipString") | |
tooltip.String:SetFontObject("GameFontNormalSmall") | |
tooltip.String:SetFont(tooltip.String:GetFont(),10) | |
tooltip.String:SetTextColor(1, 1, 1, 1) | |
tooltip.String:SetJustifyH("LEFT") | |
--tooltip.String:SetJustifyV("CENTER") | |
tooltip.String:SetWidth(tooltip:GetWidth()) | |
tooltip.String:SetHeight(90) | |
tooltip.String:SetWidth(175) | |
tooltip.String:SetText(" ") | |
tooltip.String:SetPoint("TOPLEFT", tooltip, "TOPLEFT", 110, -10) | |
tooltip.String:Show() | |
skinTooltip(tooltip) | |
end | |
--pullTooltip | |
do | |
MDT.pullTooltip = CreateFrame("Frame", "MDTPullTooltip", UIParent, "TooltipBorderedFrameTemplate") | |
--MDT.pullTooltip:SetOwner(UIParent, "ANCHOR_NONE") | |
local pullTT = MDT.pullTooltip | |
MDT.pullTooltip:SetClampedToScreen(true) | |
MDT.pullTooltip:SetFrameStrata("TOOLTIP") | |
MDT.pullTooltip.myHeight = 160 | |
MDT.pullTooltip:SetSize(250, MDT.pullTooltip.myHeight) | |
MDT.pullTooltip.Model = CreateFrame("PlayerModel", nil, MDT.pullTooltip) | |
MDT.pullTooltip.Model:SetFrameLevel(1) | |
MDT.pullTooltip.Model.fac = 0 | |
if true then | |
MDT.pullTooltip.Model:SetScript("OnUpdate",function (self, elapsed) | |
self.fac = self.fac + 0.5 | |
if self.fac >= 360 then | |
self.fac = 0 | |
end | |
self:SetFacing(PI*2 / 360 * self.fac) | |
end) | |
else | |
MDT.pullTooltip.Model:SetPortraitZoom(1) | |
MDT.pullTooltip.Model:SetFacing(PI*2 / 360 * 2) | |
end | |
MDT.pullTooltip.Model:SetSize(110,110) | |
MDT.pullTooltip.Model:SetPoint("TOPLEFT", MDT.pullTooltip, "TOPLEFT",7,-7) | |
MDT.pullTooltip.topString = MDT.pullTooltip:CreateFontString("MDTToolTipString") | |
MDT.pullTooltip.topString:SetFontObject("GameFontNormalSmall") | |
MDT.pullTooltip.topString:SetFont(MDT.pullTooltip.topString:GetFont(),10) | |
MDT.pullTooltip.topString:SetTextColor(1, 1, 1, 1) | |
MDT.pullTooltip.topString:SetJustifyH("LEFT") | |
MDT.pullTooltip.topString:SetJustifyV("TOP") | |
MDT.pullTooltip.topString:SetHeight(110) | |
MDT.pullTooltip.topString:SetWidth(130) | |
MDT.pullTooltip.topString:SetPoint("TOPLEFT", MDT.pullTooltip, "TOPLEFT", 110, -7) | |
MDT.pullTooltip.topString:Hide() | |
local heading = MDT.pullTooltip:CreateTexture(nil, "TOOLTIP") | |
heading:SetHeight(8) | |
heading:SetPoint("LEFT", 12, -30) | |
heading:SetPoint("RIGHT", MDT.pullTooltip, "RIGHT", -12, -30) | |
heading:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border") | |
heading:SetTexCoord(0.81, 0.94, 0.5, 1) | |
heading:Show() | |
MDT.pullTooltip.botString = MDT.pullTooltip:CreateFontString("MDTToolTipString") | |
local botString = MDT.pullTooltip.botString | |
botString:SetFontObject("GameFontNormalSmall") | |
botString:SetFont(MDT.pullTooltip.topString:GetFont(),10) | |
botString:SetTextColor(1, 1, 1, 1) | |
botString:SetJustifyH("TOP") | |
botString:SetJustifyV("TOP") | |
botString:SetHeight(23) | |
botString:SetWidth(250) | |
botString:SetPoint("TOPLEFT", heading, "LEFT", -12, -7) | |
botString:Hide() | |
skinTooltip(pullTT) | |
end | |
MDT:initToolbar(main_frame) | |
if db.toolbarExpanded then | |
main_frame.toolbar.toggleButton:Click() | |
end | |
--ping | |
MDT.ping = CreateFrame("PlayerModel", nil, MDT.main_frame.mapPanelFrame) | |
local ping = MDT.ping | |
--ping:SetModel("interface/minimap/ping/minimapping.m2") | |
ping:SetModel(120590) | |
ping:SetPortraitZoom(1) | |
ping:SetCamera(1) | |
ping:SetFrameLevel(50) | |
ping:SetFrameStrata("DIALOG") | |
ping.mySize = 45 | |
ping:SetSize(ping.mySize,ping.mySize) | |
ping:Hide() | |
--Set affix dropdown to preset week | |
--gotta set the list here, as affixes are not ready to be retrieved yet on login | |
main_frame.sidePanel.affixDropdown:UpdateAffixList() | |
main_frame.sidePanel.affixDropdown:SetAffixWeek(MDT:GetCurrentPreset().week or (MDT:GetCurrentAffixWeek() or 1)) | |
MDT:UpdateToDungeon(db.currentDungeonIdx) | |
main_frame:Hide() | |
--Maximize if needed | |
if db.maximized then MDT:Maximize() end | |
if MDT:IsFrameOffScreen() then | |
MDT:ResetMainFramePos() | |
end | |
framesInitialized = true | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment