You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

943 lines
36 KiB

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