(feat/Encounter): Implement Encounter Trigger/Load Options via DBM, also fire ENCOUNTER_START/END and DBM Callback Events for Custom Triggers (#73)

This commit is contained in:
NoM0Re
2025-10-04 23:39:33 +02:00
committed by GitHub
parent 517f15c7bd
commit 6c6cb73fdd
10 changed files with 2143 additions and 8 deletions
+40
View File
@@ -1612,6 +1612,7 @@ function GenericTrigger.Add(data, region)
watched_trigger_events[id] = nil watched_trigger_events[id] = nil
local warnAboutCLEUEvents = false local warnAboutCLEUEvents = false
local warnEncounterEvent = false
for triggernum, triggerData in ipairs(data.triggers) do for triggernum, triggerData in ipairs(data.triggers) do
local trigger, untrigger = triggerData.trigger, triggerData.untrigger local trigger, untrigger = triggerData.trigger, triggerData.untrigger
@@ -1653,6 +1654,8 @@ function GenericTrigger.Add(data, region)
if not(Private.subevent_actual_prefix_types[trigger.subeventPrefix]) then if not(Private.subevent_actual_prefix_types[trigger.subeventPrefix]) then
trigger.subeventSuffix = ""; trigger.subeventSuffix = "";
end end
elseif (trigger.event == "Encounter Events") and not WeakAuras.IsDBMRegistered() then
warnEncounterEvent = true
end end
prototype = event_prototypes[trigger.event] prototype = event_prototypes[trigger.event]
@@ -1902,6 +1905,13 @@ function GenericTrigger.Add(data, region)
else else
Private.AuraWarnings.UpdateWarning(data.uid, "spammy_event_warning") Private.AuraWarnings.UpdateWarning(data.uid, "spammy_event_warning")
end end
if warnEncounterEvent then
Private.AuraWarnings.UpdateWarning(data.uid, "dbm_required_for_encounter_events", "error",
L["|cFFFF0000Encounter Trigger requires Deadly Boss Mods (DBM) to be installed and up to date.|r"])
else
Private.AuraWarnings.UpdateWarning(data.uid, "dbm_required_for_encounter_events")
end
end end
do do
@@ -3905,6 +3915,36 @@ Private.LibGroupTalentsWrapper.Register(function(unit)
WeakAuras.ScanEvents("UNIT_SPEC_CHANGED_" .. unit, unit) WeakAuras.ScanEvents("UNIT_SPEC_CHANGED_" .. unit, unit)
end) end)
if WeakAuras.IsDBMRegistered() then
function Private.DBMEncounterEvents(event, mod, ...)
local encounterID, encounterName, difficultyID, groupSize =
0, "", DBM:GetCurrentDifficulty(), DBM:GetGroupSize()
if type(mod) == "table" then
encounterID = mod.encounterId or encounterID
encounterName = mod.combatInfo and mod.combatInfo.name or encounterName
end
-- Fire DBM Callback Events too, because we have them anyway registered.
WeakAuras.ScanEvents(event, mod, ...)
if event == "DBM_Pull" then
-- ENCOUNTER_START: encounterID, encounterName, difficultyID, groupSize
Private.ScanForLoads(nil, "ENCOUNTER_START", encounterID, encounterName, difficultyID, groupSize)
WeakAuras.ScanEvents("ENCOUNTER_START", encounterID, encounterName, difficultyID, groupSize)
else
local success = (event == "DBM_Kill") and 1 or 0
-- ENCOUNTER_END: encounterID, encounterName, difficultyID, groupSize, success
Private.ScanForLoads(nil, "ENCOUNTER_END", encounterID, encounterName, difficultyID, groupSize, success)
WeakAuras.ScanEvents("ENCOUNTER_END", encounterID, encounterName, difficultyID, groupSize, success)
end
end
for _, event in ipairs({"DBM_Pull", "DBM_Kill", "DBM_Wipe"}) do
DBM:RegisterCallback(event, Private.DBMEncounterEvents)
end
end
do do
local scheduled_scans = {}; local scheduled_scans = {};
+5
View File
@@ -15,6 +15,7 @@ local buildTime = "2025".."09".."14".."20".."43".."00"
local isAwesomeEnabled = C_VoiceChat and C_VoiceChat.SpeakText and 2 -- TTS available local isAwesomeEnabled = C_VoiceChat and C_VoiceChat.SpeakText and 2 -- TTS available
or C_NamePlate and C_NamePlate.GetNamePlateForUnit and 1 -- Nameplates available or C_NamePlate and C_NamePlate.GetNamePlateForUnit and 1 -- Nameplates available
or false or false
local isDBMRegistered = (DBM and type(DBM.Revision) == "number" and DBM.Revision >= 20250929200404) and true or false
local flavor local flavor
if GetRealmName() == "Onyxia" or (GetRealmName() == "Blackrock [PvP only]" and GetExpansionLevel() == 1) then if GetRealmName() == "Onyxia" or (GetRealmName() == "Blackrock [PvP only]" and GetExpansionLevel() == 1) then
@@ -34,6 +35,10 @@ function WeakAuras.IsAwesomeEnabled()
return isAwesomeEnabled return isAwesomeEnabled
end end
function WeakAuras.IsDBMRegistered()
return isDBMRegistered
end
function WeakAuras.IsCorrectVersion() function WeakAuras.IsCorrectVersion()
return true return true
end end
File diff suppressed because it is too large Load Diff
+102 -1
View File
@@ -88,7 +88,8 @@ end
local constants = { local constants = {
nameRealmFilterDesc = L[" Filter formats: 'Name', 'Name-Realm', '-Realm'. \n\nSupports multiple entries, separated by commas\nCan use \\ to escape -."], nameRealmFilterDesc = L[" Filter formats: 'Name', 'Name-Realm', '-Realm'. \n\nSupports multiple entries, separated by commas\nCan use \\ to escape -."],
instanceFilterDeprecated = L["This filter has been moved to the Location trigger. Change your aura to use the new Location trigger or join the WeakAuras Discord server for help."], instanceFilterDeprecated = L["This filter has been moved to the Location trigger. Change your aura to use the new Location trigger or join the WeakAuras Discord server for help."],
guildFilterDesc = L["Supports multiple entries, separated by commas. Escape with \\. Prefix with '-' for negation."] guildFilterDesc = L["Supports multiple entries, separated by commas. Escape with \\. Prefix with '-' for negation."],
encounterDBMDesc = (WeakAuras.IsDBMRegistered() and "" or "|cFFFF0000") .. L["Requires Deadly Boss Mods (DBM) to detect encounters."] .. (WeakAuras.IsDBMRegistered() and "" or "|r")
} }
WeakAuras.UnitRaidRole = function(unit) WeakAuras.UnitRaidRole = function(unit)
@@ -969,6 +970,16 @@ Private.load_prototype = {
optional = true, optional = true,
events = {"PLAYER_DEAD", "PLAYER_ALIVE", "PLAYER_UNGHOST"} events = {"PLAYER_DEAD", "PLAYER_ALIVE", "PLAYER_UNGHOST"}
}, },
{
name = "encounter",
display = WeakAuras.newFeatureString .. L["In Encounter"],
desc = constants.encounterDBMDesc,
type = "tristate",
width = WeakAuras.normalWidth,
init = "arg",
optional = true,
events = {"ENCOUNTER_START", "ENCOUNTER_END"}
},
{ {
name = "pvpmode", name = "pvpmode",
display = L["PvP Mode Active"], display = L["PvP Mode Active"],
@@ -1304,6 +1315,17 @@ Private.load_prototype = {
end, end,
optional = true, optional = true,
}, },
{
name = "encounterid",
display = WeakAuras.newFeatureString .. L["Encounter ID(s)"],
type = "string",
init = "arg",
multiline = true,
desc = Private.get_encounters_list,
test = "WeakAuras.CheckNumericIds(%q, encounterid)",
events = {"ENCOUNTER_START", "ENCOUNTER_END"},
optional = true,
},
{ {
name = "size", name = "size",
display = L["Instance Size Type"], display = L["Instance Size Type"],
@@ -6204,6 +6226,85 @@ Private.event_prototypes = {
timedrequired = true, timedrequired = true,
progressType = "timed" progressType = "timed"
}, },
["Encounter Events"] = {
type = "event",
events = {
["events"] = {
"ENCOUNTER_START",
"ENCOUNTER_END"
}
},
name = WeakAuras.newFeatureString..L["Entering/Leaving Encounter"],
args = {
{
name = "note",
type = "description",
display = "",
text = constants.encounterDBMDesc
},
{
name = "eventtype",
required = true,
display = L["Type"],
type = "select",
values = "encounter_event_type",
test = "event == %q",
reloadOptions = true
},
{
name = "encounterId",
display = L["Id"],
type = "string",
desc = Private.get_encounters_list,
validate = WeakAuras.ValidateNumeric,
conditionType = "number",
store = true,
init = "arg"
},
{
name = "encounterName",
display = L["Name"],
type = "string",
conditionType = "string",
store = true,
init = "arg"
},
{
name = "difficulty",
display = L["Difficulty"],
type = "select",
values = "difficulty_types",
test = "%q == WeakAuras.InstanceDifficulty()",
conditionType = "select",
conditionTest = function(state, needle)
return WeakAuras.InstanceDifficulty() == needle
end,
store = true,
init = "arg"
},
{},
{
name = "success",
display = L["Success"],
type = "toggle",
conditionType = "bool",
enable = function(trigger)
return trigger.eventtype == "ENCOUNTER_END"
end,
store = true,
test = "success == 1",
conditionTest = function(state, needle)
return state and (state.success == needle)
end,
init = "arg"
}
},
statesParameter = "one",
countEvents = true,
delayEvents = true,
timedrequired = true,
progressType = "timed"
},
["Death Knight Rune"] = { ["Death Knight Rune"] = {
type = "unit", type = "unit",
events = { events = {
+5
View File
@@ -3105,6 +3105,11 @@ Private.combat_event_type = {
PLAYER_REGEN_DISABLED = L["Entering"] PLAYER_REGEN_DISABLED = L["Entering"]
} }
Private.encounter_event_type = {
ENCOUNTER_END = L["Leaving"],
ENCOUNTER_START = L["Entering"]
}
Private.bool_types = { Private.bool_types = {
[0] = L["False"], [0] = L["False"],
[1] = L["True"] [1] = L["True"]
+125
View File
@@ -7,6 +7,131 @@ if not WeakAuras.IsClassicPlus() then
return return
end end
local WeakAuras = WeakAuras;
local L = WeakAuras.L;
local encounter_list = ""
function Private.InitializeEncounterAndZoneLists()
if encounter_list ~= "" then
return
end
local raids = {
{
L["World Bosses"],
{
{ L["Onyxia"], 1084 }
}
},
{
L["Molten Core"],
{
{ L["Lucifron"], 663 },
{ L["Magmadar"], 664 },
{ L["Gehennas"], 665 },
{ L["Garr"], 666 },
{ L["Shazzrah"], 667 },
{ L["Baron Geddon"], 668 },
{ L["Sulfuron Harbinger"], 669 },
{ L["Golemagg the Incinerator"], 670 },
{ L["Majordomo Executus"], 671 },
{ L["Ragnaros"], 672 }
}
},
{
L["Black Wing Lair"],
{
{ L["Razorgore the Untamed"], 610 },
{ L["Vaelastrasz the Corrupt"], 611 },
{ L["Broodlord Lashlayer"], 612 },
{ L["Firemaw"], 613 },
{ L["Ebonroc"], 614 },
{ L["Flamegor"], 615 },
{ L["Chromaggus"], 616 },
{ L["Nefarian"], 617 }
}
},
{
L["Ahn'Qiraj"],
{
{ L["The Prophet Skeram"], 709 },
{ L["Silithid Royalty"], 710 },
{ L["Battleguard Sartura"], 711 },
{ L["Fankriss the Unyielding"], 712 },
{ L["Viscidus"], 713 },
{ L["Princess Huhuran"], 714 },
{ L["Twin Emperors"], 715 },
{ L["Ouro"], 716 },
{ L["C'thun"], 717 }
}
},
{
L["Ruins of Ahn'Qiraj"],
{
{ L["Kurinnaxx"], 718 },
{ L["General Rajaxx"], 719 },
{ L["Moam"], 720 },
{ L["Buru the Gorger"], 721 },
{ L["Ayamiss the Hunter"], 722 },
{ L["Ossirian the Unscarred"], 723 }
}
},
{
L["Zul'Gurub"],
{
{ L["High Priest Venoxis"], 784 },
{ L["High Priestess Jeklik"], 785 },
{ L["High Priestess Mar'li"], 786 },
{ L["Bloodlord Mandokir"], 787 },
{ L["Edge of Madness"], 788 },
{ L["High Priest Thekal"], 789 },
{ L["Gahz'ranka"], 790 },
{ L["High Priestess Arlokk"], 791 },
{ L["Jin'do the Hexxer"], 792 },
{ L["Hakkar"], 793 }
}
},
{
L["Naxxramas"],
{
-- The Arachnid Quarter
{ L["Anub'Rekhan"], 1107 },
{ L["Grand Widow Faerlina"], 1110 },
{ L["Maexxna"], 1116 },
-- The Plague Quarter
{ L["Noth the Plaguebringer"], 1117 },
{ L["Heigan the Unclean"], 1112 },
{ L["Loatheb"], 1115 },
-- The Military Quarter
{ L["Instructor Razuvious"], 1113 },
{ L["Gothik the Harvester"], 1109 },
{ L["The Four Horsemen"], 1121 },
-- The Construct Quarter
{ L["Patchwerk"], 1118 },
{ L["Grobbulus"], 1111 },
{ L["Gluth"], 1108 },
{ L["Thaddius"], 1120 },
-- Frostwyrm Lair
{ L["Sapphiron"], 1119 },
{ L["Kel'Thuzad"], 1114 }
}
}
}
encounter_list = (WeakAuras.IsDBMRegistered() and "" or "|cFFFF0000") .. L["Requires Deadly Boss Mods (DBM) to detect encounters."] .. (WeakAuras.IsDBMRegistered() and "" or "|r") .. "\n\n"
for _, raid in ipairs(raids) do
encounter_list = ("%s|cffffd200%s|r\n"):format(encounter_list, raid[1])
for _, boss in ipairs(raid[2]) do
encounter_list = ("%s%s: %d\n"):format(encounter_list, boss[1], boss[2])
end
encounter_list = encounter_list .. "\n"
end
encounter_list = encounter_list:sub(1, -3) .. "\n\n" .. L["Based on "] .. "https://wago.tools/db2/DungeonEncounter?build=3.4.5.63009\n" .. L["Supports multiple entries, separated by commas\n"]
end
function Private.get_encounters_list()
return encounter_list
end
Private.talentInfo = { Private.talentInfo = {
["DRUID"] = { ["DRUID"] = {
{ {
+121
View File
@@ -7,6 +7,127 @@ if not WeakAuras.IsTBC() then
return return
end end
local WeakAuras = WeakAuras;
local L = WeakAuras.L;
local encounter_list = ""
function Private.InitializeEncounterAndZoneLists()
if encounter_list ~= "" then
return
end
local raids = {
{
L["Karazhan"],
{
{ L["Attumen the Huntsman"], 652 },
{ L["Moroes"], 653 },
{ L["Maiden of Virtue"], 654 },
{ L["Opera Hall"], 655 },
{ L["The Curator"], 656 },
{ L["Terestian Illhoof"], 657 },
{ L["Shade of Aran"], 658 },
{ L["Netherspite"], 659 },
{ L["Chess Event"], 660 },
{ L["Prince Malchezaar"], 661 },
{ L["Nightbane"], 662 },
}
},
{
L["Gruul's Lair"],
{
{ L["High King Maulgar"], 649 },
{ L["Gruul the Dragonkiller"], 650 },
}
},
{
L["Magtheridon's Lair"],
{
{ L["Magtheridon"], 651 },
}
},
{
L["Coilfang: Serpentshrine Cavern"],
{
{ L["Hydross the Unstable"], 623 },
{ L["The Lurker Below"], 624 },
{ L["Leotheras the Blind"], 625 },
{ L["Fathom-Lord Karathress"], 626 },
{ L["Morogrim Tidewalker"], 627 },
{ L["Lady Vashj"], 628 },
}
},
{
L["Tempest Keep"],
{
{ L["Al'ar"], 730 },
{ L["Void Reaver"], 731 },
{ L["High Astromancer Solarian"], 732 },
{ L["Kael'thas Sunstrider"], 733 },
}
},
{
L["The Battle for Mount Hyjal"],
{
{ L["Rage Winterchill"], 618 },
{ L["Anetheron"], 619 },
{ L["Kaz'rogal"], 620 },
{ L["Azgalor"], 621 },
{ L["Archimonde"], 622 },
}
},
{
L["Black Temple"],
{
{ L["High Warlord Naj'entus"], 601 },
{ L["Supremus"], 602 },
{ L["Shade of Akama"], 603 },
{ L["Teron Gorefiend"], 604 },
{ L["Gurtogg Bloodboil"], 605 },
{ L["Reliquary of Souls"], 606 },
{ L["Mother Shahraz"], 607 },
{ L["The Illidari Council"], 608 },
{ L["Illidan Stormrage"], 609 },
}
},
{
L["Zul'Aman"],
{
{ L["Akil'zon"], 1189 },
{ L["Nalorakk"], 1190 },
{ L["Jan'alai"], 1191 },
{ L["Halazzi"], 1192 },
{ L["Hex Lord Malacrass"], 1193 },
{ L["Daakara"], 1194 },
}
},
{
L["The Sunwell Plateau"],
{
{ L["Kalecgos"], 724 },
{ L["Brutallus"], 725 },
{ L["Felmyst"], 726 },
{ L["Eredar Twins"], 727 },
{ L["M'uru"], 728 },
{ L["Kil'jaeden"], 729 },
}
}
}
encounter_list = (WeakAuras.IsDBMRegistered() and "" or "|cFFFF0000") .. L["Requires Deadly Boss Mods (DBM) to detect encounters."] .. (WeakAuras.IsDBMRegistered() and "" or "|r") .. "\n\n"
for _, raid in ipairs(raids) do
encounter_list = ("%s|cffffd200%s|r\n"):format(encounter_list, raid[1])
for _, boss in ipairs(raid[2]) do
encounter_list = ("%s%s: %d\n"):format(encounter_list, boss[1], boss[2])
end
encounter_list = encounter_list .. "\n"
end
encounter_list = encounter_list:sub(1, -3) .. "\n\n" .. L["Based on "] .. "https://wago.tools/db2/DungeonEncounter?build=3.4.5.63009\n" .. L["Supports multiple entries, separated by commas\n"]
end
function Private.get_encounters_list()
return encounter_list
end
Private.talentInfo = { Private.talentInfo = {
["HUNTER"] = { ["HUNTER"] = {
{ {
+146
View File
@@ -7,6 +7,152 @@ if not WeakAuras.IsWrath() then
return return
end end
local WeakAuras = WeakAuras;
local L = WeakAuras.L;
local encounter_list = ""
function Private.InitializeEncounterAndZoneLists()
if encounter_list ~= "" then
return
end
local raids = {
{
L["Vault of Archavon"],
{
{ L["Archavon the Stone Watcher"], 772 },
{ L["Emalon the Storm Watcher"], 774 },
{ L["Koralon the Flame Watcher"], 776 },
{ L["Toravon the Ice Watcher"], 885 },
}
},
{
L["Naxxramas"],
{
-- The Arachnid Quarter
{ L["Anub'Rekhan"], 1107 },
{ L["Grand Widow Faerlina"], 1110 },
{ L["Maexxna"], 1116 },
-- The Plague Quarter
{ L["Noth the Plaguebringer"], 1117 },
{ L["Heigan the Unclean"], 1112 },
{ L["Loatheb"], 1115 },
-- The Military Quarter
{ L["Instructor Razuvious"], 1113 },
{ L["Gothik the Harvester"], 1109 },
{ L["The Four Horsemen"], 1121 },
-- The Construct Quarter
{ L["Patchwerk"], 1118 },
{ L["Grobbulus"], 1111 },
{ L["Gluth"], 1108 },
{ L["Thaddius"], 1120 },
-- Frostwyrm Lair
{ L["Sapphiron"], 1119 },
{ L["Kel'Thuzad"], 1114 }
}
},
{
L["The Obsidian Sanctum"],
{
{ L["Tenebron"], 736 },
{ L["Shadron"], 738 },
{ L["Vesperon"], 740 },
{ L["Sartharion"], 742 },
}
},
{
L["The Eye of Eternity"],
{
{ L["Malygos"], 734 },
}
},
{
L["Ulduar"],
{
-- The Siege of Ulduar
{ L["Flame Leviathan"], 744 },
{ L["Ignis the Furnace Master"], 745 },
{ L["Razorscale"], 746 },
{ L["XT-002 Deconstructor"], 747 },
-- The Antechamber of Ulduar
{ L["Assembly of Iron"], 748 },
{ L["Kologarn"], 749 },
{ L["Auriaya"], 750 },
-- The Keepers of Ulduar
{ L["Freya"], 753 },
{ L["Hodir"], 751 },
{ L["Mimiron"], 754 },
{ L["Thorim"], 752 },
-- The Descent into Madness
{ L["General Vezax"], 755 },
{ L["Yogg-Saron"], 756 },
-- Celestial Planetarium
{ L["Algalon the Observer"], 757 },
}
},
{
L["Trial of the Crusader"],
{
{ L["Northrend Beasts"], 629 },
{ L["Lord Jaraxxus"], 633 },
{ L["Faction Champions"], 637 },
{ L["Val'kyr Twins"], 641 },
{ L["Anub'arak"], 645 },
}
},
{
L["Onyxia's Lair"],
{
{ L["Onyxia"], 1084 },
}
},
{
L["Icecrown Citadel"],
{
-- The Lower Spire
{ L["Lord Marrowgar"], 845 },
{ L["Lady Deathwhisper"], 846 },
{ L["Gunship Battle"], 847 },
{ L["Deathbringer Saurfang"], 848 },
-- The Plagueworks
{ L["Festergut"], 849 },
{ L["Rotface"], 850 },
{ L["Professor Putricide"], 851 },
-- The Crimson Hall
{ L["Blood Prince Council"], 852 },
{ L["Blood-Queen Lana'thel"], 853 },
-- The Frostwing Halls
{ L["Valithria Dreamwalker"], 854 },
{ L["Sindragosa"], 855 },
-- The Frozen Throne
{ L["The Lich King"], 856 },
}
},
{
L["The Ruby Sanctum"],
{
{ L["Baltharus the Warborn"], 890 },
{ L["General Zarithrian"], 893 },
{ L["Saviana Ragefire"], 891 },
{ L["Halion"], 887 },
}
},
}
encounter_list = (WeakAuras.IsDBMRegistered() and "" or "|cFFFF0000") .. L["Requires Deadly Boss Mods (DBM) to detect encounters."] .. (WeakAuras.IsDBMRegistered() and "" or "|r") .. "\n\n"
for _, raid in ipairs(raids) do
encounter_list = ("%s|cffffd200%s|r\n"):format(encounter_list, raid[1])
for _, boss in ipairs(raid[2]) do
encounter_list = ("%s%s: %d\n"):format(encounter_list, boss[1], boss[2])
end
encounter_list = encounter_list .. "\n"
end
encounter_list = encounter_list:sub(1, -3) .. "\n\n" .. L["Based on "] .. "https://wago.tools/db2/DungeonEncounter?build=3.4.5.63009\n" .. L["Supports multiple entries, separated by commas\n"]
end
function Private.get_encounters_list()
return encounter_list
end
Private.talentInfo = { Private.talentInfo = {
["HUNTER"] = { ["HUNTER"] = {
{ {
+98 -5
View File
@@ -25,8 +25,8 @@ local SendChatMessage, UnitInBattleground
= SendChatMessage, UnitInBattleground = SendChatMessage, UnitInBattleground
local GetTime, UpdateAddOnCPUUsage, GetFrameCPUUsage, debugprofilestop local GetTime, UpdateAddOnCPUUsage, GetFrameCPUUsage, debugprofilestop
= GetTime, UpdateAddOnCPUUsage, GetFrameCPUUsage, debugprofilestop = GetTime, UpdateAddOnCPUUsage, GetFrameCPUUsage, debugprofilestop
local GetNumTalentTabs, GetNumTalents, MAX_NUM_TALENTS local GetNumTalentTabs, GetNumTalents, MAX_NUM_TALENTS, MAX_BOSS_FRAMES
= GetNumTalentTabs, GetNumTalents, MAX_NUM_TALENTS or 40 = GetNumTalentTabs, GetNumTalents, MAX_NUM_TALENTS or 40, MAX_BOSS_FRAMES or 5
local CreateFrame, IsShiftKeyDown, GetScreenWidth, GetScreenHeight, GetCursorPosition local CreateFrame, IsShiftKeyDown, GetScreenWidth, GetScreenHeight, GetCursorPosition
= CreateFrame, IsShiftKeyDown, GetScreenWidth, GetScreenHeight, GetCursorPosition = CreateFrame, IsShiftKeyDown, GetScreenWidth, GetScreenHeight, GetCursorPosition
local debugstack, wipe, GetSpellInfo = debugstack, wipe, GetSpellInfo local debugstack, wipe, GetSpellInfo = debugstack, wipe, GetSpellInfo
@@ -1165,6 +1165,24 @@ function Private.LoginMessage()
return loginMessage return loginMessage
end end
local function CheckForPreviousEncounter()
if (UnitAffectingCombat ("player") or InCombatLockdown()) then
for i = 1, MAX_BOSS_FRAMES do
if (UnitExists ("boss" .. i)) then
local guid = UnitGUID ("boss" .. i)
if (guid and db.CurrentEncounter.boss_guids [guid]) then
-- we are in the same encounter
WeakAuras.CurrentEncounter = db.CurrentEncounter
return true
end
end
end
db.CurrentEncounter = nil
else
db.CurrentEncounter = nil
end
end
function Private.Login(takeNewSnapshots) function Private.Login(takeNewSnapshots)
local loginThread = coroutine.create(function() local loginThread = coroutine.create(function()
Private.Pause(); Private.Pause();
@@ -1201,6 +1219,10 @@ function Private.Login(takeNewSnapshots)
Private.AddMany(toAdd, takeNewSnapshots); Private.AddMany(toAdd, takeNewSnapshots);
coroutine.yield(1000); coroutine.yield(1000);
-- check in case of a disconnect during an encounter.
if (db.CurrentEncounter) then
CheckForPreviousEncounter()
end
coroutine.yield(1000); coroutine.yield(1000);
Private.RegisterLoadEvents(); Private.RegisterLoadEvents();
coroutine.yield(10000); coroutine.yield(10000);
@@ -1315,6 +1337,7 @@ loadedFrame:SetScript("OnEvent", function(self, event, ...)
if remainingSquelch > 0 then if remainingSquelch > 0 then
timer:ScheduleTimer(function() squelch_actions = false; end, remainingSquelch); -- No sounds while loading timer:ScheduleTimer(function() squelch_actions = false; end, remainingSquelch); -- No sounds while loading
end end
Private.InitializeEncounterAndZoneLists()
end end
if not isInitialLogin then if not isInitialLogin then
isInitialLogin = true isInitialLogin = true
@@ -1395,6 +1418,42 @@ function Private.ResumeAllDynamicGroups(suspended)
end end
end end
-- Encounter stuff
local function StoreBossGUIDs()
Private.StartProfileSystem("boss_guids")
if (WeakAuras.CurrentEncounter and WeakAuras.CurrentEncounter.boss_guids) then
for i = 1, MAX_BOSS_FRAMES do
if (UnitExists ("boss" .. i)) then
local guid = UnitGUID ("boss" .. i)
if (guid) then
WeakAuras.CurrentEncounter.boss_guids [guid] = true
end
end
end
db.CurrentEncounter = WeakAuras.CurrentEncounter
end
Private.StopProfileSystem("boss_guids")
end
local function DestroyEncounterTable()
if (WeakAuras.CurrentEncounter) then
wipe(WeakAuras.CurrentEncounter)
end
WeakAuras.CurrentEncounter = nil
db.CurrentEncounter = nil
end
local function CreateEncounterTable(encounter_id)
WeakAuras.CurrentEncounter = {
id = encounter_id,
zone_id = GetCurrentMapAreaID(),
boss_guids = {},
}
timer:ScheduleTimer(StoreBossGUIDs, 2)
return WeakAuras.CurrentEncounter
end
local pausedOptionsProcessing = false; local pausedOptionsProcessing = false;
function Private.pauseOptionsProcessing(enable) function Private.pauseOptionsProcessing(enable)
pausedOptionsProcessing = enable; pausedOptionsProcessing = enable;
@@ -1475,6 +1534,19 @@ local function scanForLoadsImpl(toCheck, event, arg1, ...)
playerLevel = arg1; playerLevel = arg1;
end end
-- encounter id stuff, we are holding the current combat id to further load checks.
-- there is three ways to unload: encounter_end / zone changed (hearthstone used) / reload or disconnect
-- regen_enabled isn't good due to combat drop abilities such invisibility, vanish, fake death, etc.
local encounter_id = WeakAuras.CurrentEncounter and WeakAuras.CurrentEncounter.id or 0
if (event == "ENCOUNTER_START") then
encounter_id = tonumber(arg1)
CreateEncounterTable(encounter_id)
elseif (event == "ENCOUNTER_END") then
encounter_id = 0
DestroyEncounterTable()
end
if toCheck == nil or next(toCheck) == nil then if toCheck == nil or next(toCheck) == nil then
return return
end end
@@ -1493,6 +1565,7 @@ local function scanForLoadsImpl(toCheck, event, arg1, ...)
local _, class = UnitClass("player"); local _, class = UnitClass("player");
local inCombat = UnitAffectingCombat("player") local inCombat = UnitAffectingCombat("player")
local inEncounter = encounter_id ~= 0;
local alive = not UnitIsDeadOrGhost('player') local alive = not UnitIsDeadOrGhost('player')
local pvp = UnitIsPVPFreeForAll("player") or UnitIsPVP("player") local pvp = UnitIsPVPFreeForAll("player") or UnitIsPVP("player")
local vehicle = UnitInVehicle("player") or UnitOnTaxi("player") or false local vehicle = UnitInVehicle("player") or UnitOnTaxi("player") or false
@@ -1509,6 +1582,14 @@ local function scanForLoadsImpl(toCheck, event, arg1, ...)
end end
local size, difficulty = GetInstanceTypeAndSize() local size, difficulty = GetInstanceTypeAndSize()
if (WeakAuras.CurrentEncounter) then
if (zone ~= WeakAuras.CurrentEncounter.zone_id and not inCombat) then
encounter_id = 0
DestroyEncounterTable()
end
end
local group = Private.ExecEnv.GroupType() local group = Private.ExecEnv.GroupType()
local groupSize = GetNumGroupMembers() local groupSize = GetNumGroupMembers()
@@ -1523,8 +1604,8 @@ local function scanForLoadsImpl(toCheck, event, arg1, ...)
if (data and not data.controlledChildren) then if (data and not data.controlledChildren) then
local loadFunc = loadFuncs[id]; local loadFunc = loadFuncs[id];
local loadOpt = loadFuncsForOptions[id]; local loadOpt = loadFuncsForOptions[id];
shouldBeLoaded = loadFunc and loadFunc("ScanForLoads_Auras", inCombat, alive, pvp, vehicle, vehicleUi, mounted, class, player, realm, guild, race, faction, playerLevel, role, role, raidRole, group, groupSize, raidMemberType, zone, zoneId, subzone, size, difficulty); 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, pvp, vehicle, vehicleUi, mounted, class, player, realm, guild, race, faction, playerLevel, role, role, raidRole, group, groupSize, raidMemberType, zone, zoneId, subzone, 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);
if(shouldBeLoaded and not loaded[id]) then if(shouldBeLoaded and not loaded[id]) then
changed = changed + 1; changed = changed + 1;
@@ -2386,7 +2467,7 @@ function Private.AddMany(tbl, takeSnapshots)
else else
if next(WeakAuras.LoadFromArchive("Repository", "migration").stores) ~= nil then if next(WeakAuras.LoadFromArchive("Repository", "migration").stores) ~= nil then
timer:ScheduleTimer(function() timer:ScheduleTimer(function()
prettyPrint(L["WeakAuras has detected empty settings. If this is unexpected, ask for assitance on https://discord.gg/UXSc7nt."]) prettyPrint(L["WeakAuras has detected empty settings. If this is unexpected, ask for assistance on https://discord.gg/UXSc7nt."])
end, 1) end, 1)
end end
end end
@@ -2728,6 +2809,15 @@ local oldDataStub2 = {
conditions = {}, conditions = {},
} }
function Private.WarnEncounterEvent(data)
if data.load and (data.load.use_encounter ~= nil or data.load.use_encounterid) then
Private.AuraWarnings.UpdateWarning(data.uid, "dbm_required_for_load_encounter", "error",
L["|cFFFF0000Encounter load options requires Deadly Boss Mods (DBM) to be installed and up to date.|r"])
else
Private.AuraWarnings.UpdateWarning(data.uid, "dbm_required_for_load_encounter")
end
end
function Private.UpdateSoundIcon(data) function Private.UpdateSoundIcon(data)
local function testConditions() local function testConditions()
local sound, tts local sound, tts
@@ -3026,6 +3116,9 @@ function pAdd(data, simpleChange)
end end
Private.UpdateSoundIcon(data) Private.UpdateSoundIcon(data)
if not WeakAuras.IsDBMRegistered() then
Private.WarnEncounterEvent(data)
end
Private.callbacks:Fire("Add", data.uid, data.id, data, simpleChange) Private.callbacks:Fire("Add", data.uid, data.id, data, simpleChange)
end end
end end
@@ -435,7 +435,9 @@ local tabsForWarning = {
sound_condition = "conditions", sound_condition = "conditions",
tts_action = "action", tts_action = "action",
sound_action = "action", sound_action = "action",
spammy_event_warning = "trigger" spammy_event_warning = "trigger",
dbm_required_for_load_encounter = "load",
dbm_required_for_encounter_events = "trigger"
} }
--[[----------------------------------------------------------------------------- --[[-----------------------------------------------------------------------------