diff --git a/WeakAuras/GenericTrigger.lua b/WeakAuras/GenericTrigger.lua index 433bd29..0e53670 100644 --- a/WeakAuras/GenericTrigger.lua +++ b/WeakAuras/GenericTrigger.lua @@ -236,7 +236,7 @@ local function singleTest(arg, trigger, name, value, operator, use_exact) return TestForMultiSelect(trigger, arg); elseif(arg.type == "toggle") then return TestForToggle(trigger, arg); - elseif (arg.type == "spell" or arg.type == "item") then + elseif (arg.type == "spell" or arg.type == "item" or arg.type == "talent" or arg.type == "mysticenchant") then if arg.test then if arg.showExactOption then return "("..arg.test:format(value, tostring(use_exact) or "false") ..")"; diff --git a/WeakAuras/Modernize.lua b/WeakAuras/Modernize.lua index 3291093..9271b0a 100644 --- a/WeakAuras/Modernize.lua +++ b/WeakAuras/Modernize.lua @@ -1930,9 +1930,6 @@ function Private.Modernize(data, oldSnapshot) if data.internalVersion < 77 then -- fix data broken by wago export local triggerFix = { - talent = { - multi = true - }, herotalent = { multi = true }, @@ -1946,15 +1943,6 @@ function Private.Modernize(data, oldSnapshot) arena_spec = true } local loadFix = { - talent = { - multi = true - }, - talent2 = { - multi = true - }, - talent3 = { - multi = true - }, herotalent = { multi = true }, diff --git a/WeakAuras/Prototypes.lua b/WeakAuras/Prototypes.lua index 997b3ec..aa87155 100644 --- a/WeakAuras/Prototypes.lua +++ b/WeakAuras/Prototypes.lua @@ -892,17 +892,41 @@ function WeakAuras.GetEffectiveRangedAttackPower() return base + pos + neg end -local function valuesForTalentFunction(trigger) - return function() - local single_class = Private.checkForSingleLoadCondition(trigger, "class") - if not single_class then - single_class = select(2, UnitClass("player")); - end - - return Private.talentInfo[single_class] +function WeakAuras.IsTalentKnownForLoad(spell, exact) + local result = WeakAuras.IsTalentKnown(spell) + if exact or result then + return result end + return false end +function WeakAuras.IsTalentKnown(spell) + if (spell) then + if tonumber(spell) then + return C_CharacterAdvancement.IsKnownSpellID(spell) and true or false; + else + -- name of talent zzz + if (GetSpellInfo(spell)) then -- maybe talent ability? + return true + end + end + end + return false +end + +function WeakAuras.IsSpecActive(specID) + specID = specID and tonumber(specID) + if not specID then return false end + return SpecializationUtil.GetActiveSpecialization() == specID +end + +function WeakAuras.IsMysticEnchantApplied(spellID) + spellID = spellID and tonumber(spellID) + if not spellID then return false end + return MysticEnchantUtil.IsEnchantApplied("player", spellID) +end + + ---helper to check if a condition is checked and have a single value, and return it function Private.checkForSingleLoadCondition(trigger, name, validateFn) local use_name = "use_"..name @@ -1036,102 +1060,39 @@ Private.load_prototype = { init = "arg" }, { - name = "class_and_spec", - display = L["Class and Specialization"], + name = "specialization", + display = L["Talent Specialization"], type = "multiselect", - values = "spec_types_all", - test = "WeakAuras.CheckClassSpec(%s)", - events = {"UNIT_SPEC_CHANGED_player", "WA_DELAYED_PLAYER_ENTERING_WORLD"}, + values = "specialization_types", + test = "WeakAuras.IsSpecActive(%s)", + preamble = "wipe(WeakAuras.specialization_types) for i = 1, SpecializationUtil.GetNumSpecializations() do WeakAuras.specialization_types[i] = i .. \". \" .. SpecializationUtil.GetSpecializationInfo(i) end", + events = {"ASCENSION_CA_SPECIALIZATION_ACTIVE_ID_CHANGED"}, + init = "arg" }, { - name = "talent", + name = "knowntalent", display = L["Talent"], - type = "multiselect", - values = valuesForTalentFunction, - test = "WeakAuras.CheckTalentByIndex(%d, %d)", - multiConvertKey = nil, - events = {"PLAYER_TALENT_UPDATE", "SPELL_UPDATE_USABLE"}, - inverse = nil, - extraOption = nil, - control = "WeakAurasMiniTalent", - multiNoSingle = true, -- no single mode - multiTristate = true, -- values can be true/false/nil - multiAll = true, -- require all tests - orConjunctionGroup = "talent", - multiUseControlWhenFalse = true, - enable = function(trigger) - return (Private.checkForSingleLoadCondition(trigger, "class") ~= nil) - end, - hidden = function(trigger) - return not (Private.checkForSingleLoadCondition(trigger, "class") ~= nil) - end, + type = "talent", + test = "WeakAuras.IsTalentKnownForLoad(%s, %s)", + events = {"ASCENSION_KNOWN_ENTRIES_UPDATED"}, + orConjunctionGroup = "knowntalent", + showExactOption = true, }, { - name = "talent2", - display = L["Or Talent"], - type = "multiselect", - values = valuesForTalentFunction, - test = "WeakAuras.CheckTalentByIndex(%d, %d)", - multiConvertKey = nil, - events = {"PLAYER_TALENT_UPDATE", "SPELL_UPDATE_USABLE"}, - inverse = nil, - extraOption = nil, - control = "WeakAurasMiniTalent", - multiNoSingle = true, -- no single mode - multiTristate = true, -- values can be true/false/nil - multiAll = true, -- require all tests - orConjunctionGroup = "talent", - multiUseControlWhenFalse = true, - enable = function(trigger) - return (trigger.use_talent ~= nil or trigger.use_talent2 ~= nil) and ( - (Private.checkForSingleLoadCondition(trigger, "class") ~= nil) - ) - end, - hidden = function(trigger) - return not((trigger.use_talent ~= nil or trigger.use_talent2 ~= nil) and ( - (Private.checkForSingleLoadCondition(trigger, "class") ~= nil)) - ) - end, + name = "mysticenchantactive", + display = L["Mystic Enchant"], + type = "mysticenchant", + test = "WeakAuras.IsMysticEnchantApplied(%s)", + events = {"MYSTIC_ENCHANT_PRESET_SET_ACTIVE_RESULT", "MYSTIC_ENCHANT_SLOT_UPDATE", "PLAYER_EQUIPMENT_CHANGED", "SPELLS_CHANGED"}, + showExactOption = true, }, { - name = "talent3", - display = L["Or Talent"], - type = "multiselect", - values = valuesForTalentFunction, - test = "WeakAuras.CheckTalentByIndex(%d, %d)", - multiConvertKey = nil, - events = {"PLAYER_TALENT_UPDATE", "SPELL_UPDATE_USABLE"}, - inverse = nil, - extraOption = nil, - control = "WeakAurasMiniTalent", - multiNoSingle = true, -- no single mode - multiTristate = true, -- values can be true/false/nil - multiAll = true, -- require all tests - orConjunctionGroup = "talent", - multiUseControlWhenFalse = true, - enable = function(trigger) - return ((trigger.use_talent ~= nil and trigger.use_talent2 ~= nil) or trigger.use_talent3 ~= nil) and ( - (Private.checkForSingleLoadCondition(trigger, "class") ~= nil) - ) - end, - hidden = function(trigger) - return not(((trigger.use_talent ~= nil and trigger.use_talent2 ~= nil) or trigger.use_talent3 ~= nil) and ( - (Private.checkForSingleLoadCondition(trigger, "class") ~= nil) - )) - end - }, - { - name = "glyph", - display = L["Glyph"], - type = "multiselect", - values = function(trigger) - Private.InitializeGlyphs(trigger and trigger.glyph) - return Private.glyph_types - end, - sorted = true, - sortOrder = Private.glyph_sorted or {}, - test = "WeakAuras.IsGlyphActive(%s)", - events = {"GLYPH_ADDED", "GLYPH_REMOVED", "GLYPH_UPDATED", "USE_GLYPH"}, + name = "not_mysticenchantactive", + display = WeakAuras.newFeatureString .. L["|cFFFF0000Not|r Mystic Enchant"], + type = "mysticenchant", + test = "not WeakAuras.IsMysticEnchantApplied(%s)", + events = {"MYSTIC_ENCHANT_PRESET_SET_ACTIVE_RESULT", "MYSTIC_ENCHANT_SLOT_UPDATE", "PLAYER_EQUIPMENT_CHANGED", "SPELLS_CHANGED"}, + showExactOption = true, }, { name = "spellknown", @@ -1146,7 +1107,7 @@ Private.load_prototype = { display = WeakAuras.newFeatureString .. L["|cFFFF0000Not|r Spell Known"], type = "spell", test = "not WeakAuras.IsSpellKnownForLoad(%s, %s)", - events = {"SPELLS_CHANGED", "UNIT_PET"}, + events = {"SPELLS_CHANGED", "UNIT_PET", "CHARACTER_ADVANCEMENT_PENDING_BUILD_UPDATED"}, showExactOption = true }, { @@ -1276,6 +1237,15 @@ Private.load_prototype = { test = "Private.ExecEnv.CheckGroupMemberType(%s, group_leader)", optional = true, }, + { + name = "ruleset", + display = "PvP Ruleset", + type = "multiselect", + width = WeakAuras.normalWidth, + init = "arg", + values = "ruleset_types", + events = {"ZONE_CHANGED_NEW_AREA", "PLAYER_FLAGS_CHANGED"} + }, { name ="locationTitle", display = L["Location"], @@ -8011,6 +7981,10 @@ Private.event_prototypes = { tinsert(events, "PARTY_MEMBERS_CHANGED") tinsert(events, "RAID_ROSTER_UPDATE") end + if trigger.use_ruleset ~= nil then + tinsert(events, "ZONE_CHANGED_NEW_AREA") + tinsert(events, "PLAYER_FLAGS_CHANGED") + end if trigger.use_instance_difficulty ~= nil or trigger.use_instance_size ~= nil then @@ -8127,9 +8101,17 @@ Private.event_prototypes = { init = "Private.ExecEnv.GroupType()", events = {"PARTY_MEMBERS_CHANGED", "RAID_ROSTER_UPDATE"} }, + { + name = "ruleset", + display = "PvP Ruleset", + type = "multiselect", + values = "ruleset_types", + init = "WeakAuras.Ruleset()", + events = {"ZONE_CHANGED_NEW_AREA", "PLAYER_FLAGS_CHANGED"} + }, { name = "instance_size", - display = L["Instance Type"].." "..L["|cffff0000deprecated|r"], + display = L["Instance Type"], desc = constants.instanceFilterDeprecated, type = "multiselect", values = "instance_types", @@ -8139,7 +8121,7 @@ Private.event_prototypes = { }, { name = "instance_difficulty", - display = L["Instance Difficulty"].." "..L["|cffff0000deprecated|r"], + display = L["Instance Difficulty"], desc = constants.instanceFilterDeprecated, type = "multiselect", values = "difficulty_types", diff --git a/WeakAuras/Types.lua b/WeakAuras/Types.lua index 4fdb6dc..3eff4be 100644 --- a/WeakAuras/Types.lua +++ b/WeakAuras/Types.lua @@ -1212,6 +1212,9 @@ do end end +WeakAuras.specialization_types = {} +for i = 1, #SPEC_SWAP_SPELLS do WeakAuras.specialization_types[i] = L["Talent Specialization"] .. " " .. i end + Private.faction_group = { Alliance = L["Alliance"], Horde = L["Horde"], @@ -2556,10 +2559,19 @@ Private.group_types = { raid = L["In Raid"] } +Private.ruleset_types = { + one = L["None"], + pve = NO_RISK_PVE, + pvp = NO_RISK_PVP, + highrisk = HIGH_RISK_PVP, +} + Private.difficulty_types = { none = L["None"], normal = PLAYER_DIFFICULTY1, - heroic = PLAYER_DIFFICULTY2 + heroic = PLAYER_DIFFICULTY2, + mythic = "Mythic", + ascended = "Ascended", } Private.raid_role_types = { @@ -3288,9 +3300,6 @@ Private.data_stub = { class = { multi = {}, }, - talent = { - multi = {}, - }, }, actions = { init = {}, diff --git a/WeakAuras/WeakAuras.lua b/WeakAuras/WeakAuras.lua index 7ea652d..082276d 100644 --- a/WeakAuras/WeakAuras.lua +++ b/WeakAuras/WeakAuras.lua @@ -747,7 +747,7 @@ local function singleTest(arg, trigger, use, name, value, operator, use_exact, c return name; end end - elseif (arg.type == "spell") then + elseif (arg.type == "spell" or arg.type == "talent" or arg.type == "mysticenchant") then if arg.showExactOption then return "("..arg.test:format(value, tostring(use_exact) or "false") ..")"; else @@ -841,6 +841,9 @@ local function ConstructFunction(prototype, trigger, skipOptional) end else local value = trigger[name] + if name == "knowntalent" then + dprint(WeakAuras.IsTalentKnownForLoad(value)) + end local operator = name and trigger[name.."_operator"] local caseInsensitive = name and trigger[name.."_caseInsensitive"] local use_exact = name and trigger["use_exact_" .. name] @@ -1473,6 +1476,20 @@ function Private.ExecEnv.GroupType() return "solo"; end +function WeakAuras.Ruleset() + local ruleset = C_Player:GetRuleset() + if ruleset == Enum.Ruleset.NoRiskPvE then + return "pve" + end + if ruleset == Enum.Ruleset.NoRiskPvP then + return "pvp" + end + if ruleset == Enum.Ruleset.HighRiskPvP then + return "highrisk" + end + return "none" +end + local function GetInstanceTypeAndSize() local size, difficulty local inInstance, Type = IsInInstance() @@ -1502,10 +1519,14 @@ local function GetInstanceTypeAndSize() difficulty = "heroic" end else - if difficultyIndex == 1 or difficultyIndex == 2 then + if difficultyIndex == 1 then difficulty = "normal" - elseif difficultyIndex == 3 or difficultyIndex == 4 then + elseif difficultyIndex == 2 then difficulty = "heroic" + elseif difficultyIndex == 3 then + difficulty = "mythic" + elseif difficultyIndex == 4 then + difficulty = "ascended" end end return size, difficulty, instanceType, ZoneMapID @@ -1593,6 +1614,9 @@ local function scanForLoadsImpl(toCheck, event, arg1, ...) local group = Private.ExecEnv.GroupType() local groupSize = GetNumGroupMembers() + local ruleset = WeakAuras.Ruleset() + local specialization = SpecializationUtil.GetActiveSpecialization() + local changed = 0; local shouldBeLoaded, couldBeLoaded; local parentsToCheck = {} @@ -1604,8 +1628,8 @@ local function scanForLoadsImpl(toCheck, event, arg1, ...) if (data and not data.controlledChildren) then local loadFunc = loadFuncs[id]; local loadOpt = loadFuncsForOptions[id]; - shouldBeLoaded = loadFunc and loadFunc("ScanForLoads_Auras", inCombat, alive, inEncounter, pvp, vehicle, vehicleUi, mounted, class, player, realm, guild, race, faction, playerLevel, role, role, raidRole, group, groupSize, raidMemberType, zone, zoneId, subzone, encounter_id, size, difficulty); - couldBeLoaded = loadOpt and loadOpt("ScanForLoads_Auras", inCombat, alive, inEncounter, pvp, vehicle, vehicleUi, mounted, class, player, realm, guild, race, faction, playerLevel, role, role, raidRole, group, groupSize, raidMemberType, zone, zoneId, subzone, encounter_id, size, difficulty); + shouldBeLoaded = loadFunc and loadFunc("ScanForLoads_Auras", inCombat, alive, inEncounter, pvp, vehicle, vehicleUi, mounted, class, specialization, player, realm, guild, race, faction, playerLevel, role, role, raidRole, group, groupSize, raidMemberType, ruleset, zone, zoneId, subzone, encounter_id, size, difficulty); + couldBeLoaded = loadOpt and loadOpt("ScanForLoads_Auras", inCombat, alive, inEncounter, pvp, vehicle, vehicleUi, mounted, class, specialization, player, realm, guild, race, faction, playerLevel, role, role, raidRole, group, groupSize, raidMemberType, ruleset, zone, zoneId, subzone, encounter_id, size, difficulty); if(shouldBeLoaded and not loaded[id]) then changed = changed + 1; @@ -1694,6 +1718,7 @@ loadFrame:RegisterEvent("PLAYER_REGEN_DISABLED"); loadFrame:RegisterEvent("PLAYER_REGEN_ENABLED"); loadFrame:RegisterEvent("PLAYER_ROLES_ASSIGNED"); loadFrame:RegisterEvent("SPELLS_CHANGED"); +loadFrame:RegisterEvent("ASCENSION_KNOWN_ENTRIES_UPDATED"); loadFrame:RegisterEvent("UNIT_INVENTORY_CHANGED") loadFrame:RegisterEvent("PLAYER_EQUIPMENT_CHANGED") loadFrame:RegisterEvent("PLAYER_DEAD") diff --git a/WeakAurasOptions/LoadOptions.lua b/WeakAurasOptions/LoadOptions.lua index e13375d..66d1016 100644 --- a/WeakAurasOptions/LoadOptions.lua +++ b/WeakAurasOptions/LoadOptions.lua @@ -45,6 +45,70 @@ local function CorrectSpellName(input) end end +local function CorrectTalentName(input) + local inputId = tonumber(input); + if(inputId) then + local name = GetSpellInfo(inputId); + if(name) then + return inputId; + else + return nil; + end + elseif type(input) == "string" and input ~= "" then + local link + if(input:sub(1,1) == "\124") then + link = input + else + link = GetSpellLink(input) + end + if(link) and link ~= "" then + local spellId = link:match("spell:(%d+)"); + return tonumber(spellId); + end + local spells = spellCache.GetSpellsMatching(input) + if type(spells) == "table" then + for id in pairs(spells) do + if tonumber(id) and id ~= 0 and C_CharacterAdvancement.IsKnownSpellID(id) then + return id + end + end + return next(spells) + end + end +end + +local function CorrectMysticEnchantName(input) + local inputId = tonumber(input); + if(inputId) then + local name = GetSpellInfo(inputId); + if(name) then + return inputId; + else + return nil; + end + elseif type(input) == "string" and input ~= "" then + local link + if(input:sub(1,1) == "\124") then + link = input + else + link = GetSpellLink(input) + end + if(link) and link ~= "" then + local spellId = link:match("spell:(%d+)"); + return tonumber(spellId); + end + local spells = spellCache.GetSpellsMatching(input) + if type(spells) == "table" then + for id in pairs(spells) do + if tonumber(id) and id ~= 0 and C_CharacterAdvancement.IsKnownSpellID(id) then + return id + end + end + return next(spells) + end + end +end + local function CorrectItemName(input) local inputId = tonumber(input); if(inputId) then @@ -355,7 +419,7 @@ function OptionsPrivate.ConstructOptions(prototype, data, startorder, triggernum if(arg.type == "toggle" or arg.type == "tristate") then options["use_"..name].width = arg.width or WeakAuras.doubleWidth; end - if(arg.type == "spell" or arg.type == "aura" or arg.type == "item") then + if(arg.type == "spell" or arg.type == "aura" or arg.type == "item" or arg.type == "talent" or arg.type == "mysticenchant") then if not arg.showExactOption then options["use_"..name].width = (arg.width or WeakAuras.normalWidth) - 0.2; end @@ -602,7 +666,7 @@ function OptionsPrivate.ConstructOptions(prototype, data, startorder, triggernum }; order = order + 1; end - elseif(arg.type == "spell" or arg.type == "aura" or arg.type == "item") then + elseif(arg.type == "spell" or arg.type == "aura" or arg.type == "item" or arg.type == "talent" or arg.type == "mysticenchant") then if entryNumber > 1 then options["spacer_"..name..suffix].width = WeakAuras.normalWidth - (arg.showExactOption and 0 or 0.2) end @@ -648,7 +712,7 @@ function OptionsPrivate.ConstructOptions(prototype, data, startorder, triggernum if(arg.type == "aura") then local icon = spellCache.GetIcon(value); return icon and tostring(icon) or "", 18, 18; - elseif(arg.type == "spell") then + elseif(arg.type == "spell" or arg.type == "talent" or arg.type == "mysticenchant") then local name, _, icon = GetSpellInfo(value); if arg.noValidation then -- GetSpellInfo and other wow apis are case insensitive, but the later matching we do @@ -672,7 +736,7 @@ function OptionsPrivate.ConstructOptions(prototype, data, startorder, triggernum if type(value) ~= "number" and type(value) ~= "string" then return true end - return not ((arg.type == "aura" and value and spellCache.GetIcon(value)) or (arg.type == "spell" and value and GetSpellInfo(value)) or (arg.type == "item" and value and GetItemIcon(value))) + return not ((arg.type == "aura" and value and spellCache.GetIcon(value)) or ((arg.type == "spell" or arg.type == "talent" or arg.type == "mysticenchant") and value and GetSpellInfo(value)) or (arg.type == "item" and value and GetItemIcon(value))) end }; order = order + 1; @@ -708,7 +772,7 @@ function OptionsPrivate.ConstructOptions(prototype, data, startorder, triggernum else return nil; end - elseif(arg.type == "spell") then + elseif(arg.type == "spell" or arg.type == "talent" or arg.type == "mysticenchant") then local useExactSpellId = (arg.showExactOption and getValue(trigger, nil, "use_exact_"..realname, multiEntry, entryNumber)) or arg.only_exact if value and value ~= "" and (type(value) == "number" or type(value) == "string") then @@ -744,6 +808,10 @@ function OptionsPrivate.ConstructOptions(prototype, data, startorder, triggernum fixedInput = WeakAuras.spellCache.CorrectAuraName(v); elseif(arg.type == "spell") then fixedInput = CorrectSpellName(v); + elseif(arg.type == "talent") then + fixedInput = CorrectTalentName(v); + elseif(arg.type == "mysticenchant") then + fixedInput = CorrectMysticEnchantName(v); elseif(arg.type == "item") then fixedInput = CorrectItemName(v); end diff --git a/WeakAurasTemplates/TriggerTemplates.lua b/WeakAurasTemplates/TriggerTemplates.lua index f624b36..0edfd14 100644 --- a/WeakAurasTemplates/TriggerTemplates.lua +++ b/WeakAurasTemplates/TriggerTemplates.lua @@ -1624,7 +1624,7 @@ function WeakAuras.CreateTemplateView(Private, frame) replaceButton:SetFullWidth(true); replaceButton:SetClick(function() replaceTriggers(newView.data, newView.chosenItem, newView.chosenSubType); - for _,v in pairs({"class", "spec", "talent", "pvptalent", "race", "covenant"}) do + for _,v in pairs({"class", "spec", "pvptalent", "race", "covenant"}) do newView.data.load[v] = nil; newView.data.load["use_"..v] = nil; end diff --git a/WeakAurasTemplates/TriggerTemplatesDataWrath.lua b/WeakAurasTemplates/TriggerTemplatesDataWrath.lua index bb20f6d..4e20b8f 100644 --- a/WeakAurasTemplates/TriggerTemplatesDataWrath.lua +++ b/WeakAurasTemplates/TriggerTemplatesDataWrath.lua @@ -1137,22 +1137,6 @@ local function handleItem(item) end end end - if (item.talent) then - item.load = item.load or {}; - if type(item.talent) == "table" then - item.load.talent = { multi = {} }; - for _,v in pairs(item.talent) do - item.load.talent.multi[v] = true; - end - item.load.use_talent = false; - else - item.load.talent = { - single = item.talent, - multi = {}, - }; - item.load.use_talent = true; - end - end if (item.pvptalent) then item.load = item.load or {}; item.load.use_pvptalent = true;