local detailsFramework = _G ["DetailsFramework"] if (not detailsFramework or not DetailsFrameworkCanLoad) then return end local _ --lua locals local rawset = rawset local rawget = rawget local setmetatable = setmetatable local unpack = unpack ---@diagnostic disable-line local type = type local floor = math.floor local loadstring = loadstring ---@diagnostic disable-line local CreateFrame = CreateFrame ---@diagnostic disable-line local UnitIsUnit = UnitIsUnit ---@diagnostic disable-line local UnitClass = UnitClass ---@diagnostic disable-line local GetInstanceInfo = GetInstanceInfo ---@diagnostic disable-line local C_ChallengeMode = C_ChallengeMode ---@diagnostic disable-line local C_Map = C_Map ---@diagnostic disable-line local GetTalentInfoByID = GetTalentInfoByID ---@diagnostic disable-line local IS_WOW_PROJECT_MAINLINE = WOW_PROJECT_ID == WOW_PROJECT_MAINLINE ---@diagnostic disable-line local IS_WOW_PROJECT_NOT_MAINLINE = WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE ---@diagnostic disable-line local IS_WOW_PROJECT_CLASSIC_ERA = WOW_PROJECT_ID == WOW_PROJECT_CLASSIC ---@diagnostic disable-line local PixelUtil = PixelUtil or DFPixelUtil ---@diagnostic disable-line local UnitGroupRolesAssigned = detailsFramework.UnitGroupRolesAssigned local loadConditionsFrame ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ --load conditions panel --this is the table prototype to hold load conditions settings local default_load_conditions = { class = {}, spec = {}, race = {}, talent = {}, pvptalent = {}, group = {}, role = {}, affix = {}, encounter_ids = {}, map_ids = {}, } --[=[ Skittish 135994 2 Volcanic 451169 3 Necrotic 1029009 4 Teeming 136054 5 Raging 132345 6 Bolstering 132333 7 Sanguine 136124 8 Tyrannical 236401 9 Fortified 463829 10 Bursting 1035055 11 Grievous 132090 12 Explosive 2175503 13 Quaking 136025 14 Infested 2032223 16 Reaping 2446016 117 Beguiling 237565 119 Awakened 442737 120 Prideful 3528307 121 Inspiring 135946 122 Spiteful 135945 123 Storming 136018 124 Tormented 3528304 128 Infernal 1394959 129 Encrypted 4038106 130 Shrouded 136177 131 Thundering 1385910 132 [PH] 0 133 Entangling 134412 134 Afflicted 237555 135 Incorporeal 298642 136 Shielding 535593 137 --]=] local deprecatedAffixes = { [1] = true, --Overflowing [2] = true, --Skittish [3] = true, --Volcanic [4] = true, --Necrotic [5] = true, --Teeming [6] = true, --Raging [7] = true, --Bolstering [8] = true, --Sanguine --[9] = true, --Tyrannical --[10] = true, --Fortified [11] = true, --Bursting [12] = true, --Grievous [13] = true, --Explosive [14] = true, --Quaking [16] = true, --Infested [117] = true, --Reaping [119] = true, --Beguiling [120] = true, --Awakened [121] = true, --Prideful [122] = true, --Inspiring [123] = true, --Spiteful [124] = true, --Storming [128] = true, --Tormented [129] = true, --Infernal [130] = true, --Encrypted [131] = true, --Shrouded [132] = true, --Thundering [133] = true, --Focused [134] = true, --Entangling [135] = true, --Afflicted [136] = true, --Incorporeal [137] = true, --Shielding [144] = true, --Thorned [145] = true, --Reckless [146] = true, --Attuned --[147] = true, --Xal'atath's Guile --[148] = true, --Xal'atath's Bargain: Ascendant --[152] = true, --Challenger's Peril --[153] = true, --Xal'atath's Bargain: Frenzied --[158] = true, --Xal'atath's Bargain: Voidbound --[159] = true, --Xal'atath's Bargain: Oblivion --[160] = true, --Xal'atath's Bargain: Devour } local default_load_conditions_frame_options = { title = "Details! Framework: Load Conditions", name = "Object", } function detailsFramework:CreateLoadFilterParser(callback) local filterFrame = CreateFrame("frame") if IS_WOW_PROJECT_MAINLINE then filterFrame:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED") filterFrame:RegisterEvent("TRAIT_CONFIG_LIST_UPDATED") filterFrame:RegisterEvent("CHALLENGE_MODE_START") else filterFrame:RegisterEvent("PLAYER_ENTERING_WORLD") filterFrame:RegisterEvent("PLAYER_TALENT_UPDATE") end filterFrame:RegisterEvent("PLAYER_ROLES_ASSIGNED") filterFrame:RegisterEvent("ZONE_CHANGED_NEW_AREA") filterFrame:RegisterEvent("ENCOUNTER_START") filterFrame:RegisterEvent("PLAYER_REGEN_ENABLED") filterFrame:RegisterEvent("PLAYER_REGEN_DISABLED") filterFrame:RegisterEvent("CHAT_MSG_LOOT") filterFrame:SetScript("OnEvent", function(self, event, ...) if (event == "ENCOUNTER_START") then --triggers before regen_disabled local encounterID = ... filterFrame.EncounterIDCached = encounterID elseif (event == "CHAT_MSG_LOOT") then local message = ... local itemId = message:match("|Hitem:(%d+):") itemId = tonumber(itemId) if (itemId == 191140) then xpcall(callback, geterrorhandler(), "RACE_START") --monitor the player backpack each second to know when the item is removed from the bag C_Timer.After(5, function() filterFrame.FindBackpackItem = C_Timer.NewTicker(1, function() local bFoundItem = false for bagId = 0, 4 do for slotId = 1, 32 do local bagItemID = C_Container.GetContainerItemID(bagId, slotId) if (bagItemID) then if (bagItemID == itemId) then --bronze timepiece is on the player backpack return end end end end if (not bFoundItem) then filterFrame.FindBackpackItem:Cancel() xpcall(callback, geterrorhandler(), "RACE_STOP") return end end) end) end return elseif (event == "PLAYER_REGEN_DISABLED") then elseif (event == "ENCOUNTER_END") then filterFrame.EncounterIDCached = nil elseif (event == "PLAYER_REGEN_ENABLED") then --f.EncounterIDCached = nil --when the player dies during an encounter, the game is triggering regen enabled elseif (event == "PLAYER_SPECIALIZATION_CHANGED") then if (loadConditionsFrame and loadConditionsFrame:IsShown()) then loadConditionsFrame:Refresh() end local unit = ... if (not unit or not UnitIsUnit("player", unit)) then return end elseif (event == "PLAYER_ROLES_ASSIGNED") then local assignedRole = UnitGroupRolesAssigned("player") if (assignedRole == "NONE") then local spec = DetailsFramework.GetSpecialization() if (spec) then assignedRole = DetailsFramework.GetSpecializationRole(spec) end end if (detailsFramework.CurrentPlayerRole == assignedRole) then return end detailsFramework.CurrentPlayerRole = assignedRole end --problem: this xpcall won't tell where the error happened in the callback code xpcall(callback, geterrorhandler(), filterFrame.EncounterIDCached) end) end function detailsFramework:PassLoadFilters(loadTable, encounterID) --class local passLoadClass if (loadTable.class.Enabled) then local _, classFileName = UnitClass("player") if (not loadTable.class[classFileName]) then return false, _G["CLASS"] else passLoadClass = true end end --spec if (IS_WOW_PROJECT_MAINLINE and loadTable.spec.Enabled) then local canCheckTalents = true if (passLoadClass) then --if is allowed to load on this class, check if the talents isn't from another class local _, classFileName = UnitClass("player") local specsForThisClass = detailsFramework:GetClassSpecIDs(classFileName) canCheckTalents = false for _, specID in ipairs(specsForThisClass) do if (loadTable.spec[specID] or loadTable.spec[specID..""]) then --theres a talent for this class canCheckTalents = true break end end end if (canCheckTalents) then local specIndex = DetailsFramework.GetSpecialization() if (specIndex) then local specID = DetailsFramework.GetSpecializationInfo(specIndex) if not specID or(not loadTable.spec[specID] and not loadTable.spec[specID .. ""]) then return false, _G["SPECIALIZATION"] end else return false, _G["SPECIALIZATION"] end end end --race if (loadTable.race.Enabled) then local raceName, raceFileName, raceID = UnitRace("player") if (not loadTable.race [raceFileName]) then return false, _G["RACE"] end end --talents if (IS_WOW_PROJECT_MAINLINE and loadTable.talent.Enabled) then local bOnlySelected, bUseHashTable = true, true local talentsInUse = detailsFramework:GetCharacterTalents(bOnlySelected, bUseHashTable) local hasTalent for talentId in pairs(talentsInUse) do if talentId and(loadTable.talent[talentId] or loadTable.talent[talentId .. ""]) then hasTalent = true break end end if (not hasTalent) then return false, _G["TALENTS"] end end --pvptalent if (IS_WOW_PROJECT_MAINLINE and loadTable.pvptalent.Enabled) then local talentsInUse = detailsFramework:GetCharacterPvPTalents(false, true) local hasTalent for talentID, _ in pairs(talentsInUse) do if talentID and(loadTable.pvptalent [talentID] or loadTable.pvptalent [talentID .. ""]) then hasTalent = true break end end if (not hasTalent) then return false, (_G["PVP"] or "") .. " " .. (_G["TALENTS"] or "") end end --group if (loadTable.group.Enabled) then local _, zoneType = GetInstanceInfo() if (not loadTable.group[zoneType]) then return false, _G["GROUP"] end end --role if (loadTable.role.Enabled) then local assignedRole = UnitGroupRolesAssigned("player") if (assignedRole == "NONE") then local spec = DetailsFramework.GetSpecialization() if (spec) then assignedRole = DetailsFramework.GetSpecializationRole(spec) end end if (not loadTable.role [assignedRole]) then return false, _G["ROLE"] end end --affix if (IS_WOW_PROJECT_MAINLINE and loadTable.affix.Enabled) then local isInMythicDungeon = C_ChallengeMode.IsChallengeModeActive() if (not isInMythicDungeon) then return false, "M+ Affix" end local GetActiveKeystoneInfo = C_ChallengeMode.GetActiveKeystoneInfo or function() return 0, {}, false end -- ensure all three return values. local level, affixes, wasEnergized = GetActiveKeystoneInfo() local hasAffix = false for _, affixID in ipairs(affixes) do if affixID and(loadTable.affix[affixID] or loadTable.affix[affixID .. ""]) then hasAffix = true break end end if (not hasAffix) then return false, "M+ Affix" end end --encounter id if (loadTable.encounter_ids.Enabled) then if (not encounterID) then return end local bHasEncounter for _, userEnteredEncounterId in pairs(loadTable.encounter_ids) do if (userEnteredEncounterId == encounterID) then bHasEncounter = true break end end if (not bHasEncounter) then return false, _G["GUILD_NEWS_FILTER3"] --"raid encounters" end end --map id if (loadTable.map_ids.Enabled) then local _, _, _, _, _, _, _, zoneMapID = GetInstanceInfo() local uiMapID = C_Map.GetBestMapForUnit("player") local bHasMapID = false for _, userEnteredMapId in pairs(loadTable.map_ids) do if (userEnteredMapId == zoneMapID or userEnteredMapId == uiMapID) then bHasMapID = true break end end if (not bHasMapID) then return false, _G["BATTLEFIELD_MINIMAP"] --"zone map" end end return true end --this func will deploy the default values from the prototype into the config table function detailsFramework:UpdateLoadConditionsTable(configTable) configTable = configTable or {} detailsFramework.table.deploy(configTable, default_load_conditions) return configTable end --/run Plater.OpenOptionsPanel()PlaterOptionsPanelContainer:SelectIndex(Plater, 14) function detailsFramework:OpenLoadConditionsPanel(optionsTable, callback, frameOptions) frameOptions = frameOptions or {} detailsFramework.table.deploy(frameOptions, default_load_conditions_frame_options) detailsFramework:UpdateLoadConditionsTable(optionsTable) if (not loadConditionsFrame) then loadConditionsFrame = detailsFramework:CreateSimplePanel(UIParent, 1024, 620, "Load Conditions", "loadConditionsFrame") loadConditionsFrame:SetBackdropColor(0, 0, 0, 1) loadConditionsFrame.AllRadioGroups = {} loadConditionsFrame.AllTextEntries = {} loadConditionsFrame.OptionsTable = optionsTable detailsFramework:ApplyStandardBackdrop(loadConditionsFrame, false, 1.1) local xStartAt = 10 local x2StartAt = 500 local anchorPositions = { class = {xStartAt, -70}, spec = {xStartAt, -200}, race = {xStartAt, -250}, role = {xStartAt, -380}, talent = {xStartAt, -440}, pvptalent = {x2StartAt, -70}, group = {x2StartAt, -170}, affix = {x2StartAt, -240}, encounter_ids = {x2StartAt+1, -375}, map_ids = {x2StartAt + 210, -375}, } local editingLabel = detailsFramework:CreateLabel(loadConditionsFrame, "Load Conditions For:") local editingWhatLabel = detailsFramework:CreateLabel(loadConditionsFrame, "") editingLabel:SetPoint("topleft", loadConditionsFrame, "topleft", 10, -35) editingWhatLabel:SetPoint("left", editingLabel, "right", 2, 0) --this label store the name of what is being edited loadConditionsFrame.EditingLabel = editingWhatLabel --when the user click on an option, run the callback loadConditionsFrame.RunCallback = function() detailsFramework:Dispatch(loadConditionsFrame.CallbackFunc) end --when the user click on an option or when the panel is opened --check if there's an option enabled and fadein all options, fadeout otherwise loadConditionsFrame.OnRadioStateChanged = function(radioGroup, subConfigTable) subConfigTable.Enabled = nil subConfigTable.Enabled = next(subConfigTable) and true or nil radioGroup:SetFadeState(subConfigTable.Enabled) end --create the radio group for character class loadConditionsFrame.OnRadioCheckboxClick = function(self, key, value) --hierarchy: DBKey ["class"] key ["HUNTER"] value TRUE local DBKey = self:GetParent().DBKey loadConditionsFrame.OptionsTable [DBKey] [key and key .. ""] = value and true or nil if not value then -- cleanup "number" type values loadConditionsFrame.OptionsTable [DBKey] [key] = nil end loadConditionsFrame.OnRadioStateChanged(self:GetParent(), loadConditionsFrame.OptionsTable [DBKey]) loadConditionsFrame.RunCallback() end --create the radio group for classes local classes = {} for _, classTable in pairs(detailsFramework:GetClassList()) do table.insert(classes, { name = classTable.Name, set = loadConditionsFrame.OnRadioCheckboxClick, param = classTable.FileString, get = function() return loadConditionsFrame.OptionsTable.class[classTable.FileString] end, texture = classTable.Texture, texcoord = classTable.TexCoord, }) end local classGroup = detailsFramework:CreateCheckboxGroup(loadConditionsFrame, classes, nil, {width = 430, height = 200, title = "Character Class", backdrop_color = {0, 0, 0, 0}}, {offset_x = 130, amount_per_line = 3}) classGroup:SetPoint("topleft", loadConditionsFrame, "topleft", anchorPositions.class[1], anchorPositions.class[2]) classGroup.DBKey = "class" table.insert(loadConditionsFrame.AllRadioGroups, classGroup) --create the radio group for character spec if IS_WOW_PROJECT_MAINLINE then local specs = {} for _, specID in ipairs(detailsFramework:GetClassSpecIDs(select(2, UnitClass("player")))) do local specID, specName, specDescription, specIcon, specBackground, specRole, specClass = DetailsFramework.GetSpecializationInfoByID(specID) table.insert(specs, { name = specName, set = loadConditionsFrame.OnRadioCheckboxClick, param = specID, get = function() return loadConditionsFrame.OptionsTable.spec[specID] or loadConditionsFrame.OptionsTable.spec[specID..""] end, texture = specIcon, }) end local specGroup = detailsFramework:CreateCheckboxGroup(loadConditionsFrame, specs, nil, {width = 200, height = 200, title = "Character Spec", backdrop_color = {0, 0, 0, 0}}, {offset_x = 120, amount_per_line = 4}) specGroup:SetPoint("topleft", loadConditionsFrame, "topleft", anchorPositions.spec[1], anchorPositions.spec[2]) specGroup.DBKey = "spec" table.insert(loadConditionsFrame.AllRadioGroups, specGroup) end --create radio group for character races local raceList = {} for _, raceTable in ipairs(detailsFramework:GetCharacterRaceList()) do table.insert(raceList, { name = raceTable.Name:sub(1, 15), set = loadConditionsFrame.OnRadioCheckboxClick, param = raceTable.FileString, get = function() return loadConditionsFrame.OptionsTable.race [raceTable.FileString] end, }) end local raceGroup = detailsFramework:CreateCheckboxGroup(loadConditionsFrame, raceList, nil, {width = 200, height = 200, title = "Character Race", backdrop_color = {0, 0, 0, 0}}) raceGroup:SetPoint("topleft", loadConditionsFrame, "topleft", anchorPositions.race [1], anchorPositions.race [2]) raceGroup.DBKey = "race" table.insert(loadConditionsFrame.AllRadioGroups, raceGroup) --create radio group for talents if IS_WOW_PROJECT_MAINLINE then --[=[ 7.0 to 9.0 talents schema local talentList = {} for _, talentTable in ipairs(detailsFramework:GetCharacterTalents()) do if talentTable.ID then table.insert(talentList, { name = talentTable.Name:sub(1, 15), set = loadConditionsFrame.OnRadioCheckboxClick, param = talentTable.ID, get = function() return loadConditionsFrame.OptionsTable.talent[talentTable.ID] or loadConditionsFrame.OptionsTable.talent[talentTable.ID .. ""] end, texture = talentTable.Texture, }) end end --]=] --10.0 talents schema local talentList = {} local talentGroup = detailsFramework:CreateCheckboxGroup(loadConditionsFrame, talentList, nil, {width = 200, height = 200, title = "Character Talents", backdrop_color = {0, 0, 0, 0}}, {offset_x = 64, amount_per_line = 16}) talentGroup:SetPoint("topleft", loadConditionsFrame, "topleft", anchorPositions.talent[1], anchorPositions.talent[2]) talentGroup.DBKey = "talent" table.insert(loadConditionsFrame.AllRadioGroups, talentGroup) loadConditionsFrame.TalentGroup = talentGroup do if (false) then --disabled, isn't in use --create a frame to show talents selected in other specs or characters local otherTalents = CreateFrame("frame", nil, loadConditionsFrame, "BackdropTemplate") otherTalents:SetSize(26, 26) otherTalents:SetPoint("left", talentGroup.Title.widget, "right", 10, -2) otherTalents.Texture = detailsFramework:CreateImage(otherTalents, [[Interface\BUTTONS\AdventureGuideMicrobuttonAlert]], 24, 24) otherTalents.Texture:SetAllPoints() local removeTalent = function(_, _, talentID) loadConditionsFrame.OptionsTable.talent[talentID] = nil GameCooltip2:Hide() loadConditionsFrame.OnRadioStateChanged(talentGroup, loadConditionsFrame.OptionsTable[talentGroup.DBKey]) --loadConditionsFrame.CanShowTalentWarning() end local buildTalentMenu = function() local playerTalents = detailsFramework:GetCharacterTalents() local indexedTalents = {} for _, talentTable in ipairs(playerTalents) do table.insert(indexedTalents, talentTable.ID) end --talents selected to load GameCooltip2:AddLine("select a talent to remove it (added from a different spec or character)", "", 1, "orange", "orange", 9) GameCooltip2:AddLine("$div", nil, nil, -1, -1) for talentID, _ in pairs(loadConditionsFrame.OptionsTable.talent) do if (type(talentID) == "number" and not detailsFramework.table.find(indexedTalents, talentID)) then local talentID, name, texture, selected, available = GetTalentInfoByID(talentID) if (name) then GameCooltip2:AddLine(name) GameCooltip2:AddIcon(texture, 1, 1, 16, 16, .1, .9, .1, .9) GameCooltip2:AddMenu(1, removeTalent, talentID) end end end end otherTalents.CoolTip = { Type = "menu", BuildFunc = buildTalentMenu, OnEnterFunc = function(self) end, OnLeaveFunc = function(self) end, FixedValue = "none", ShowSpeed = 0.05, Options = function() GameCooltip2:SetOption("TextFont", "Friz Quadrata TT") GameCooltip2:SetOption("TextColor", "orange") GameCooltip2:SetOption("TextSize", 12) GameCooltip2:SetOption("FixedWidth", 220) GameCooltip2:SetOption("ButtonsYMod", -4) GameCooltip2:SetOption("YSpacingMod", -4) GameCooltip2:SetOption("IgnoreButtonAutoHeight", true) GameCooltip2:SetColor(1, 0.5, 0.5, 0.5, 0) local preset2_backdrop = {bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], edgeFile = [[Interface\Buttons\WHITE8X8]], tile = true, edgeSize = 1, tileSize = 16, insets = {left = 0, right = 0, top = 0, bottom = 0}} local gray_table = {0.37, 0.37, 0.37, 0.95} local black_table = {0.2, 0.2, 0.2, 1} GameCooltip2:SetBackdrop(1, preset2_backdrop, gray_table, black_table) GameCooltip2:SetBackdrop(2, preset2_backdrop, gray_table, black_table) end, } GameCooltip2:CoolTipInject(otherTalents) --[=[ function loadConditionsFrame.CanShowTalentWarning() --not in use local playerTalents = detailsFramework:GetCharacterTalents() local indexedTalents = {} for _, talentTable in ipairs(playerTalents) do table.insert(indexedTalents, talentTable.ID) end for talentID, _ in pairs(loadConditionsFrame.OptionsTable.talent) do if (type(talentID) == "number" and not detailsFramework.table.find(indexedTalents, talentID)) then otherTalents:Show() return end end otherTalents:Hide() end --]=] end end end --create radio group for pvp talents if IS_WOW_PROJECT_MAINLINE then local pvpTalentList = {} for _, talentTable in ipairs(detailsFramework:GetCharacterPvPTalents()) do table.insert(pvpTalentList, { name = talentTable.Name:sub(1, 15), set = loadConditionsFrame.OnRadioCheckboxClick, param = talentTable.ID, get = function() return loadConditionsFrame.OptionsTable.pvptalent [talentTable.ID] or loadConditionsFrame.OptionsTable.pvptalent [talentTable.ID .. ""] end, texture = talentTable.Texture, }) end local pvpTalentGroup = detailsFramework:CreateCheckboxGroup(loadConditionsFrame, pvpTalentList, nil, {width = 200, height = 200, title = "Characer PvP Talents", backdrop_color = {0, 0, 0, 0}}, {offset_x = 160, amount_per_line = 3}) pvpTalentGroup:SetPoint("topleft", loadConditionsFrame, "topleft", anchorPositions.pvptalent [1], anchorPositions.pvptalent [2]) pvpTalentGroup.DBKey = "pvptalent" table.insert(loadConditionsFrame.AllRadioGroups, pvpTalentGroup) loadConditionsFrame.PvPTalentGroup = pvpTalentGroup do if (false) then --create a frame to show talents selected in other specs or characters local otherTalents = CreateFrame("frame", nil, loadConditionsFrame, "BackdropTemplate") otherTalents:SetSize(26, 26) otherTalents:SetPoint("left", pvpTalentGroup.Title.widget, "right", 10, -2) otherTalents.Texture = detailsFramework:CreateImage(otherTalents, [[Interface\BUTTONS\AdventureGuideMicrobuttonAlert]], 24, 24) otherTalents.Texture:SetAllPoints() local removeTalent = function(_, _, talentID) loadConditionsFrame.OptionsTable.pvptalent [talentID] = nil GameCooltip2:Hide() loadConditionsFrame.OnRadioStateChanged(pvpTalentGroup, loadConditionsFrame.OptionsTable [pvpTalentGroup.DBKey]) --loadConditionsFrame.CanShowPvPTalentWarning() end local buildTalentMenu = function() local playerTalents = detailsFramework:GetCharacterPvPTalents() local indexedTalents = {} for _, talentTable in ipairs(playerTalents) do table.insert(indexedTalents, talentTable.ID) end --talents selected to load GameCooltip2:AddLine("select a talent to remove it(added from a different spec or character)", "", 1, "orange", "orange", 9) GameCooltip2:AddLine("$div", nil, nil, -1, -1) for talentID, _ in pairs(loadConditionsFrame.OptionsTable.pvptalent) do if (type(talentID) == "number" and not detailsFramework.table.find(indexedTalents, talentID)) then local _, name, texture = GetPvpTalentInfoByID(talentID) if (name) then GameCooltip2:AddLine(name) GameCooltip2:AddIcon(texture, 1, 1, 16, 16, .1, .9, .1, .9) GameCooltip2:AddMenu(1, removeTalent, talentID) end end end end otherTalents.CoolTip = { Type = "menu", BuildFunc = buildTalentMenu, OnEnterFunc = function(self) end, OnLeaveFunc = function(self) end, FixedValue = "none", ShowSpeed = 0.05, Options = function() GameCooltip2:SetOption("TextFont", "Friz Quadrata TT") GameCooltip2:SetOption("TextColor", "orange") GameCooltip2:SetOption("TextSize", 12) GameCooltip2:SetOption("FixedWidth", 220) GameCooltip2:SetOption("ButtonsYMod", -4) GameCooltip2:SetOption("YSpacingMod", -4) GameCooltip2:SetOption("IgnoreButtonAutoHeight", true) GameCooltip2:SetColor(1, 0.5, 0.5, 0.5, 0) local preset2_backdrop = {edgeFile = [[Interface\Buttons\WHITE8X8]], tile = true, edgeSize = 1, tileSize = 16, insets = {left = 0, right = 0, top = 0, bottom = 0}} local gray_table = {0.37, 0.37, 0.37, 0.95} local black_table = {0.2, 0.2, 0.2, 1} GameCooltip2:SetBackdrop(1, preset2_backdrop, gray_table, black_table) GameCooltip2:SetBackdrop(2, preset2_backdrop, gray_table, black_table) end, } GameCooltip2:CoolTipInject(otherTalents) function loadConditionsFrame.CanShowPvPTalentWarning() local playerTalents = detailsFramework:GetCharacterPvPTalents() local indexedTalents = {} for _, talentTable in ipairs(playerTalents) do table.insert(indexedTalents, talentTable.ID) end for talentID, _ in pairs(loadConditionsFrame.OptionsTable.pvptalent) do if (type(talentID) == "number" and not detailsFramework.table.find(indexedTalents, talentID)) then otherTalents:Show() return end end otherTalents:Hide() end --]=] end end end --create radio for group types local groupTypes = {} for _, groupTable in ipairs(detailsFramework:GetGroupTypes()) do table.insert(groupTypes, { name = groupTable.Name, set = loadConditionsFrame.OnRadioCheckboxClick, param = groupTable.ID, get = function() return loadConditionsFrame.OptionsTable.group [groupTable.ID] or loadConditionsFrame.OptionsTable.group [groupTable.ID .. ""] end, }) end local groupTypesGroup = detailsFramework:CreateCheckboxGroup(loadConditionsFrame, groupTypes, nil, {width = 200, height = 200, title = "Group Types", backdrop_color = {0, 0, 0, 0}}, {offset_x = 125}) groupTypesGroup:SetPoint("topleft", loadConditionsFrame, "topleft", anchorPositions.group[1], anchorPositions.group[2]) groupTypesGroup.DBKey = "group" table.insert(loadConditionsFrame.AllRadioGroups, groupTypesGroup) --create radio for character roles local roleTypes = {} for _, roleTable in ipairs(detailsFramework:GetRoleTypes()) do local texture, l, r, t, b = detailsFramework:GetRoleIconAndCoords(roleTable.ID) table.insert(roleTypes, { name = (roleTable.Texture .. " " .. roleTable.Name), name = roleTable.Name, texture = texture, texcoord = {l, r, t, b}, set = loadConditionsFrame.OnRadioCheckboxClick, param = roleTable.ID, get = function() return loadConditionsFrame.OptionsTable.role [roleTable.ID] or loadConditionsFrame.OptionsTable.role [roleTable.ID .. ""] end, }) end local roleTypesGroup = detailsFramework:CreateCheckboxGroup(loadConditionsFrame, roleTypes, nil, {width = 200, height = 200, title = "Role Types", backdrop_color = {0, 0, 0, 0}}) roleTypesGroup:SetPoint("topleft", loadConditionsFrame, "topleft", anchorPositions.role[1], anchorPositions.role[2]) roleTypesGroup.DBKey = "role" table.insert(loadConditionsFrame.AllRadioGroups, roleTypesGroup) --create radio group for mythic+ affixes if IS_WOW_PROJECT_MAINLINE then local affixes = {} local GetAffixInfo = C_ChallengeMode.GetAffixInfo or function() return nil end for i = 2, 1000 do local affixName, desc, texture = GetAffixInfo(i) if (affixName and not deprecatedAffixes[i]) then table.insert(affixes, { name = affixName, set = loadConditionsFrame.OnRadioCheckboxClick, param = i, get = function() return loadConditionsFrame.OptionsTable.affix[i] or loadConditionsFrame.OptionsTable.affix[i .. ""] end, texture = texture, }) end end local affixTypesGroup = detailsFramework:CreateCheckboxGroup(loadConditionsFrame, affixes, nil, {width = 200, height = 200, title = "M+ Affixes", backdrop_color = {0, 0, 0, 0}}, {offset_x = 230, amount_per_line = 2}) affixTypesGroup:SetPoint("topleft", loadConditionsFrame, "topleft", anchorPositions.affix [1], anchorPositions.affix [2]) affixTypesGroup.DBKey = "affix" table.insert(loadConditionsFrame.AllRadioGroups, affixTypesGroup) end --text entries functions local textEntryRefresh = function(self) local idList = loadConditionsFrame.OptionsTable [self.DBKey] self:SetText("") for _, id in pairs(idList) do if tonumber(id) then self:SetText(self:GetText() .. " " .. id) end end self:SetText(self:GetText():gsub("^ ", "")) end local textEntryOnEnterPressed = function(_, self) table.wipe(loadConditionsFrame.OptionsTable [self.DBKey]) local text = self:GetText() for _, ID in ipairs({strsplit(" ", text)}) do ID = detailsFramework:trim(ID) ID = tonumber(ID) if (ID) then table.insert(loadConditionsFrame.OptionsTable [self.DBKey], ID) loadConditionsFrame.OptionsTable [self.DBKey].Enabled = true end end end --create the text entry to type the encounter ID local encounterIDLabel = detailsFramework:CreateLabel(loadConditionsFrame, "Encounter ID", detailsFramework:GetTemplate("font", "ORANGE_FONT_TEMPLATE")) local encounterIDEditbox = detailsFramework:CreateTextEntry(loadConditionsFrame, function() loadConditionsFrame.RunCallback() end, 200, 20, "EncounterEditbox", _, _, detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")) encounterIDLabel:SetPoint("topleft", loadConditionsFrame, "topleft", anchorPositions.encounter_ids[1], anchorPositions.encounter_ids[2]) encounterIDEditbox:SetPoint("topleft", encounterIDLabel, "bottomleft", 0, -2) encounterIDEditbox.DBKey = "encounter_ids" encounterIDEditbox.Refresh = textEntryRefresh encounterIDEditbox.tooltip = "Enter multiple IDs separating with a whitespace.\nExample: 35 45 95\n\nSanctum of Domination:\n" for _, encounterTable in ipairs(detailsFramework:GetCLEncounterIDs()) do encounterIDEditbox.tooltip = encounterIDEditbox.tooltip .. encounterTable.ID .. " - " .. encounterTable.Name .. "\n" end encounterIDEditbox:SetHook("OnEnterPressed", textEntryOnEnterPressed) table.insert(loadConditionsFrame.AllTextEntries, encounterIDEditbox) --create the text entry for map ID local mapIDLabel = detailsFramework:CreateLabel(loadConditionsFrame, "Map ID", detailsFramework:GetTemplate("font", "ORANGE_FONT_TEMPLATE")) local mapIDEditbox = detailsFramework:CreateTextEntry(loadConditionsFrame, function() loadConditionsFrame.RunCallback() end, 200, 20, "MapEditbox", _, _, detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")) mapIDLabel:SetPoint("topleft", loadConditionsFrame, "topleft", anchorPositions.map_ids[1], anchorPositions.map_ids[2]) mapIDEditbox:SetPoint("topleft", mapIDLabel, "bottomleft", 0, -2) mapIDEditbox.DBKey = "map_ids" mapIDEditbox.Refresh = textEntryRefresh mapIDEditbox.tooltip = "Enter multiple IDs separating with a whitespace\nExample: 35 45 95" mapIDEditbox:SetHook("OnEnterPressed", textEntryOnEnterPressed) table.insert(loadConditionsFrame.AllTextEntries, mapIDEditbox) function loadConditionsFrame.Refresh(self) if IS_WOW_PROJECT_MAINLINE then ---@type {Name: string, ID: number, Texture: any, IsSelected: boolean}[] local allTalents = detailsFramework:GetAllTalents() local talentList = {} for _, talentTable in ipairs(allTalents) do if (talentTable.ID) then table.insert(talentList, { name = "", --talentTable.Name:sub(1, 15), set = loadConditionsFrame.OnRadioCheckboxClick, param = talentTable.ID, get = function() return loadConditionsFrame.OptionsTable.talent[talentTable.ID] or loadConditionsFrame.OptionsTable.talent[talentTable.ID .. ""] end, texture = talentTable.Texture, tooltip = talentTable.Name, }) end end --[=[]] --update the talents(might have changed if the player changed its specializationid) local talentList = {} for _, talentTable in ipairs(detailsFramework:GetCharacterTalents()) do if talentTable.ID then table.insert(talentList, { name = talentTable.Name, set = loadConditionsFrame.OnRadioCheckboxClick, param = talentTable.ID, get = function() return loadConditionsFrame.OptionsTable.talent [talentTable.ID] or loadConditionsFrame.OptionsTable.talent [talentTable.ID .. ""] end, texture = talentTable.Texture, }) end end --]=] loadConditionsFrame.TalentGroup:SetOptions(talentList) end if IS_WOW_PROJECT_MAINLINE then local pvpTalentList = {} for _, talentTable in ipairs(detailsFramework:GetCharacterPvPTalents()) do table.insert(pvpTalentList, { name = talentTable.Name:sub(1, 15), set = loadConditionsFrame.OnRadioCheckboxClick, param = talentTable.ID, get = function() return loadConditionsFrame.OptionsTable.pvptalent [talentTable.ID] or loadConditionsFrame.OptionsTable.pvptalent [talentTable.ID .. ""] end, texture = talentTable.Texture, }) end loadConditionsFrame.PvPTalentGroup:SetOptions(pvpTalentList) end --refresh the radio group for _, radioGroup in ipairs(loadConditionsFrame.AllRadioGroups) do radioGroup:Refresh() loadConditionsFrame.OnRadioStateChanged(radioGroup, loadConditionsFrame.OptionsTable [radioGroup.DBKey]) end --refresh text entries for _, textEntry in ipairs(loadConditionsFrame.AllTextEntries) do textEntry:Refresh() end if IS_WOW_PROJECT_MAINLINE then --loadConditionsFrame.CanShowTalentWarning() --loadConditionsFrame.CanShowPvPTalentWarning() end end end --set the options table loadConditionsFrame.OptionsTable = optionsTable --set the callback func loadConditionsFrame.CallbackFunc = callback loadConditionsFrame.OptionsTable = optionsTable --set title loadConditionsFrame.EditingLabel:SetText(frameOptions.name) loadConditionsFrame.Title:SetText(frameOptions.title) --show the panel to the user loadConditionsFrame:Show() loadConditionsFrame:Refresh() end