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.
711 lines
25 KiB
711 lines
25 KiB
local mod = DBM:NewMod("CoSTrash", "DBM-Party-Legion", 7)
|
|
local L = mod:GetLocalizedStrings()
|
|
|
|
mod:SetRevision("20240622210644")
|
|
--mod:SetModelID(47785)
|
|
mod:SetOOCBWComms()
|
|
mod:SetMinSyncRevision(20221228000000)
|
|
mod:SetZone(1571)
|
|
|
|
mod.isTrashMod = true
|
|
|
|
--LW solution, unregister/reregister other addons/WA frames from GOSSIP_SHOW
|
|
--This is to prevent things like https://wago.io/M+Timer/114 from breaking clue helper do to advancing
|
|
--dialog before we get a chance to read gossipID
|
|
---@type Frame[]
|
|
local frames = {GetFramesRegisteredForEvent("GOSSIP_SHOW")}
|
|
for i = 1, #frames do
|
|
frames[i]:UnregisterEvent("GOSSIP_SHOW")
|
|
end
|
|
mod:RegisterEvents(
|
|
"SPELL_CAST_START 209027 212031 209485 209410 209413 211470 211464 209404 209495 225100 211299 209378 397892 397897 207979 212784 207980 212773 210261 209033 211473",
|
|
"SPELL_AURA_APPLIED 209033 209512 397907 373552",
|
|
"SPELL_AURA_REMOVED 397907",
|
|
"UNIT_DIED",
|
|
"CHAT_MSG_MONSTER_SAY",
|
|
"GOSSIP_SHOW",
|
|
"UPDATE_MOUSEOVER_UNIT"
|
|
)
|
|
for i = 1, #frames do
|
|
frames[i]:RegisterEvent("GOSSIP_SHOW")
|
|
end
|
|
|
|
--TODO, at least 1-2 more GTFOs I forgot names of
|
|
--TODO, target scan https://www.wowhead.com/beta/spell=397897/crushing-leap ?
|
|
--[[
|
|
(ability.id = 209033 or ability.id = 209027 or ability.id = 212031 or ability.id = 207979 or ability.id = 209485 or ability.id = 209410
|
|
or ability.id = 209413 or ability.id = 211470 or ability.id = 225100 or ability.id = 211299 or ability.id = 207980 or ability.id = 212773
|
|
or ability.id = 211464 or ability.id = 209404 or ability.id = 209495 or ability.id = 209378 or ability.id = 397892 or ability.id = 397897
|
|
or ability.id = 212784 or ability.id = 211473) and type = "begincast"
|
|
--]]
|
|
local warnAvailableItems = mod:NewAnnounce("warnAvailableItems", 1)
|
|
local warnImpendingDoom = mod:NewTargetAnnounce(397907, 2)
|
|
local warnSoundAlarm = mod:NewCastAnnounce(210261, 4)
|
|
local warnSubdue = mod:NewCastAnnounce(212773, 3)
|
|
local warnCrushingLeap = mod:NewCastAnnounce(397897, 3)
|
|
local warnEyeStorm = mod:NewCastAnnounce(212784, 4)
|
|
local warnShadowSlash = mod:NewCastAnnounce(211473, 4, nil, nil, "Tank|Healer")
|
|
local warnHypnosisBat = mod:NewTargetNoFilterAnnounce(373552, 3)
|
|
|
|
local specWarnFortificationDispel = mod:NewSpecialWarningDispel(209033, "MagicDispeller", nil, nil, 1, 2)
|
|
local specWarnQuellingStrike = mod:NewSpecialWarningDodge(209027, "Melee", nil, 2, 1, 2)
|
|
local specWarnChargedBlast = mod:NewSpecialWarningDodge(212031, "Tank", nil, nil, 1, 2)
|
|
local specWarnChargedSmash = mod:NewSpecialWarningDodge(209495, "Melee", nil, 2, 1, 2)
|
|
local specWarnShockwave = mod:NewSpecialWarningDodge(207979, nil, nil, nil, 2, 2)
|
|
local specWarnSubdue = mod:NewSpecialWarningInterrupt(212773, "HasInterrupt", nil, nil, 1, 2)
|
|
local specWarnFortification = mod:NewSpecialWarningInterrupt(209033, false, nil, nil, 1, 2)--Opt in. There are still higher prio interrupts in most packs with guards and this can be dispelled after the fact
|
|
local specWarnDrainMagic = mod:NewSpecialWarningInterrupt(209485, "HasInterrupt", nil, nil, 1, 2)
|
|
local specWarnNightfallOrb = mod:NewSpecialWarningInterrupt(209410, "HasInterrupt", nil, nil, 1, 2)
|
|
local specWarnSuppress = mod:NewSpecialWarningInterrupt(209413, "HasInterrupt", nil, nil, 1, 2)
|
|
local specWarnBewitch = mod:NewSpecialWarningInterrupt(211470, "HasInterrupt", nil, nil, 1, 2)
|
|
local specWarnChargingStation = mod:NewSpecialWarningInterrupt(225100, "HasInterrupt", nil, nil, 1, 2)
|
|
local specWarnSearingGlare = mod:NewSpecialWarningInterrupt(211299, "HasInterrupt", nil, nil, 1, 2)
|
|
local specWarnDisintegrationBeam = mod:NewSpecialWarningInterrupt(207980, "HasInterrupt", nil, nil, 1, 2)
|
|
local specWarnFelDetonation = mod:NewSpecialWarningMoveTo(211464, nil, nil, nil, 2, 13)
|
|
local specWarnSealMagic = mod:NewSpecialWarningRun(209404, false, nil, 2, 4, 2)
|
|
local specWarnWhirlingBlades = mod:NewSpecialWarningRun(209378, "Melee", nil, nil, 4, 2)
|
|
local specWarnScreamofPain = mod:NewSpecialWarningCast(397892, "SpellCaster", nil, nil, 1, 2)
|
|
local specWarnImpendingDoom = mod:NewSpecialWarningMoveAway(397907, nil, nil, nil, 1, 2)
|
|
local yellImpendingDoom = mod:NewYell(397907)
|
|
local yellImpendingDoomFades = mod:NewShortFadesYell(397907)
|
|
local specWarnGTFO = mod:NewSpecialWarningGTFO(209512, nil, nil, nil, 1, 8)
|
|
|
|
local timerQuellingStrikeCD = mod:NewCDNPTimer(12, 209027, nil, "Tank", nil, 3, nil, DBM_COMMON_L.TANK_ICON)--Mostly for tank to be aware of mob positioning before CD comes off
|
|
local timerFortificationCD = mod:NewCDNPTimer(18.1, 209033, nil, "HasInterrupt", nil, 4, nil, DBM_COMMON_L.INTERRUPT_ICON)
|
|
local timerSealMagicCD = mod:NewCDNPTimer(18.1, 209404, nil, "SpellCaster", nil, 3)
|
|
local timerChargingStationCD = mod:NewCDNPTimer(13.3, 225100, nil, "HasInterrupt", nil, 4, nil, DBM_COMMON_L.INTERRUPT_ICON)
|
|
local timerSuppressCD = mod:NewCDNPTimer(17, 209413, nil, "HasInterrupt", nil, 4, nil, DBM_COMMON_L.INTERRUPT_ICON)
|
|
local timerSearingGlareCD = mod:NewCDNPTimer(8.4, 211299, nil, "HasInterrupt", nil, 4, nil, DBM_COMMON_L.INTERRUPT_ICON)
|
|
local timerEyeStormCD = mod:NewCDNPTimer(20.6, 212784, nil, nil, nil, 5)--Role color cause it needs a disrupt (stun, knockback) to interrupt.
|
|
local timerBewitchCD = mod:NewCDNPTimer(17, 211470, nil, "HasInterrupt", nil, 4, nil, DBM_COMMON_L.INTERRUPT_ICON)
|
|
local timerShadowSlashCD = mod:NewCDNPTimer(18.2, 211473, nil, "Tank|Healer", nil, 5, nil, DBM_COMMON_L.TANK_ICON)
|
|
local timerFelDetonationCD = mod:NewCDNPTimer(12.1, 211464, nil, nil, nil, 2)
|
|
local timerScreamofPainCD = mod:NewCDNPTimer(14.6, 397892, nil, nil, nil, 2)
|
|
local timerWhirlingBladesCD = mod:NewCDNPTimer(18.2, 209378, nil, "Melee", nil, 2)
|
|
local timerDisintegrationBeamCD = mod:NewCDNPTimer(6.1, 207980, nil, "HasInterrupt", nil, 4, nil, DBM_COMMON_L.INTERRUPT_ICON)
|
|
local timerShockwaveCD = mod:NewCDNPTimer(8.4, 207979, nil, nil, nil, 3)
|
|
local timerCrushingLeapCD = mod:NewCDNPTimer(16.9, 397897, nil, nil, nil, 3)
|
|
|
|
mod:AddGossipOption(true, "Buff")
|
|
mod:AddGossipOption(true, "Action")
|
|
mod:AddBoolOption("SpyHelper", true)
|
|
mod:AddBoolOption("SendToChat2", true)
|
|
mod:AddBoolOption("SpyHelperClose2", false)
|
|
|
|
--Antispam IDs for this mod: 1 run away, 2 dodge, 3 dispel, 4 incoming damage, 5 you/role, 6 generalized, 7 GTFO
|
|
|
|
function mod:SPELL_CAST_START(args)
|
|
if not self.Options.Enabled then return end
|
|
if not self:IsValidWarning(args.sourceGUID) then return end
|
|
local spellId = args.spellId
|
|
if spellId == 209027 then
|
|
timerQuellingStrikeCD:Start(nil, args.sourceGUID)
|
|
if self:AntiSpam(3, 2) then
|
|
specWarnQuellingStrike:Show()
|
|
specWarnQuellingStrike:Play("shockwave")
|
|
end
|
|
elseif spellId == 212031 and self:AntiSpam(3, 2) then
|
|
specWarnChargedBlast:Show()
|
|
specWarnChargedBlast:Play("shockwave")
|
|
elseif spellId == 207979 then
|
|
timerShockwaveCD:Start(nil, args.sourceGUID)
|
|
if self:AntiSpam(3, 2) then
|
|
specWarnShockwave:Show()
|
|
specWarnShockwave:Play("shockwave")
|
|
end
|
|
elseif spellId == 209033 then
|
|
timerFortificationCD:Start(nil, args.sourceGUID)
|
|
if self:CheckInterruptFilter(args.sourceGUID, false, true) then
|
|
specWarnFortification:Show(args.sourceName)
|
|
specWarnFortification:Play("kickcast")
|
|
end
|
|
elseif spellId == 209485 and self:CheckInterruptFilter(args.sourceGUID, false, true) then
|
|
specWarnDrainMagic:Show(args.sourceName)
|
|
specWarnDrainMagic:Play("kickcast")
|
|
elseif spellId == 209410 and self:CheckInterruptFilter(args.sourceGUID, false, true) then
|
|
specWarnNightfallOrb:Show(args.sourceName)
|
|
specWarnNightfallOrb:Play("kickcast")
|
|
elseif spellId == 209413 then
|
|
timerSuppressCD:Start(nil, args.sourceGUID)
|
|
if self:CheckInterruptFilter(args.sourceGUID, false, true) then
|
|
specWarnSuppress:Show(args.sourceName)
|
|
specWarnSuppress:Play("kickcast")
|
|
end
|
|
elseif spellId == 211470 then
|
|
timerBewitchCD:Start(nil, args.sourceGUID)
|
|
if self:CheckInterruptFilter(args.sourceGUID, false, true) then
|
|
specWarnBewitch:Show(args.sourceName)
|
|
specWarnBewitch:Play("kickcast")
|
|
end
|
|
elseif spellId == 225100 then
|
|
timerChargingStationCD:Start(nil, args.sourceGUID)
|
|
if self:CheckInterruptFilter(args.sourceGUID, false, true) then
|
|
specWarnChargingStation:Show(args.sourceName)
|
|
specWarnChargingStation:Play("kickcast")
|
|
end
|
|
elseif spellId == 211299 then
|
|
timerSearingGlareCD:Start(nil, args.sourceGUID)
|
|
if self:CheckInterruptFilter(args.sourceGUID, false, true) then
|
|
specWarnSearingGlare:Show(args.sourceName)
|
|
specWarnSearingGlare:Play("kickcast")
|
|
end
|
|
elseif spellId == 207980 then
|
|
timerDisintegrationBeamCD:Start(nil, args.sourceGUID)
|
|
if self:CheckInterruptFilter(args.sourceGUID, false, true) then
|
|
specWarnDisintegrationBeam:Show(args.sourceName)
|
|
specWarnDisintegrationBeam:Play("kickcast")
|
|
end
|
|
elseif spellId == 212773 then
|
|
if self.Options.SpecWarn212773interrupt and self:CheckInterruptFilter(args.sourceGUID, false, true) then
|
|
specWarnSubdue:Show(args.sourceName)
|
|
specWarnSubdue:Play("kickcast")
|
|
elseif self:AntiSpam(3, 5) then
|
|
warnSubdue:Show()
|
|
end
|
|
elseif spellId == 211464 then
|
|
timerFelDetonationCD:Start(nil, args.sourceGUID)
|
|
if self:AntiSpam(3, 4) then
|
|
specWarnFelDetonation:Show(DBM_COMMON_L.BREAK_LOS)
|
|
specWarnFelDetonation:Play("breaklos")
|
|
end
|
|
elseif spellId == 209404 then
|
|
timerSealMagicCD:Start(nil, args.sourceGUID)
|
|
if self:AntiSpam(3, 5) then
|
|
specWarnSealMagic:Show()
|
|
specWarnSealMagic:Play("runout")
|
|
end
|
|
elseif spellId == 209495 then
|
|
specWarnChargedSmash:Show()
|
|
specWarnChargedSmash:Play("watchstep")
|
|
elseif spellId == 209378 then
|
|
timerWhirlingBladesCD:Start(nil, args.sourceGUID)
|
|
if self:AntiSpam(3, 1) then
|
|
specWarnWhirlingBlades:Show()
|
|
specWarnWhirlingBlades:Play("runout")
|
|
end
|
|
elseif spellId == 397892 then
|
|
specWarnScreamofPain:Show()
|
|
specWarnScreamofPain:Play("stopcast")
|
|
timerScreamofPainCD:Start(nil, args.sourceGUID)
|
|
elseif spellId == 397897 then
|
|
timerCrushingLeapCD:Start(nil, args.sourceGUID)
|
|
if self:AntiSpam(3, 6) then
|
|
warnCrushingLeap:Show()
|
|
end
|
|
elseif spellId == 212784 then
|
|
timerEyeStormCD:Start(nil, args.sourceGUID)
|
|
if self:AntiSpam(3, 6) then
|
|
warnEyeStorm:Show()
|
|
end
|
|
elseif spellId == 210261 then--No throttle
|
|
warnSoundAlarm:Show()
|
|
elseif spellId == 211473 then
|
|
timerShadowSlashCD:Start(nil, args.sourceGUID)
|
|
if self:AntiSpam(3, 5) then
|
|
warnShadowSlash:Show()
|
|
end
|
|
end
|
|
end
|
|
|
|
function mod:SPELL_AURA_APPLIED(args)
|
|
if not self.Options.Enabled then return end
|
|
local spellId = args.spellId
|
|
if spellId == 209033 and not args:IsDestTypePlayer() and self:CheckDispelFilter("magic") then
|
|
specWarnFortificationDispel:Show(args.destName)
|
|
specWarnFortificationDispel:Play("dispelnow")
|
|
elseif spellId == 209512 and args:IsPlayer() and self:AntiSpam(3, 7) then
|
|
specWarnGTFO:Show(args.spellName)
|
|
specWarnGTFO:Play("watchfeet")
|
|
elseif spellId == 397907 then
|
|
warnImpendingDoom:CombinedShow(0.5, args.destName)
|
|
if args:IsPlayer() then
|
|
specWarnImpendingDoom:Show()
|
|
specWarnImpendingDoom:Play("scatter")
|
|
yellImpendingDoom:Yell()
|
|
yellImpendingDoomFades:Countdown(spellId)
|
|
end
|
|
elseif spellId == 373552 then
|
|
warnHypnosisBat:Show(args.destName)
|
|
end
|
|
end
|
|
|
|
function mod:SPELL_AURA_REMOVED(args)
|
|
if not self.Options.Enabled then return end
|
|
local spellId = args.spellId
|
|
if spellId == 397907 and args:IsPlayer() then
|
|
yellImpendingDoomFades:Cancel()
|
|
end
|
|
end
|
|
|
|
function mod:UNIT_DIED(args)
|
|
local cid = self:GetCIDFromGUID(args.destGUID)
|
|
if cid == 104246 then--Duskwatch Guard
|
|
timerQuellingStrikeCD:Stop(args.destGUID)
|
|
timerFortificationCD:Stop(args.destGUID)
|
|
elseif cid == 104247 then--Duskwatch Arcanist
|
|
timerSealMagicCD:Stop(args.destGUID)
|
|
elseif cid == 104270 then--Guardian Construct
|
|
timerChargingStationCD:Stop(args.destGUID)
|
|
timerSuppressCD:Stop(args.destGUID)
|
|
elseif cid == 105715 then--Watchful Inquisitor
|
|
timerSearingGlareCD:Stop(args.destGUID)
|
|
timerEyeStormCD:Stop(args.destGUID)
|
|
elseif cid == 104300 then--Shadow Mistress
|
|
timerBewitchCD:Stop(args.destGUID)
|
|
timerShadowSlashCD:Stop(args.destGUID)
|
|
elseif cid == 104278 then--Felbound Enforcer
|
|
timerFelDetonationCD:Stop(args.destGUID)
|
|
elseif cid == 104275 then--Imacu'tya
|
|
timerScreamofPainCD:Stop(args.destGUID)
|
|
timerWhirlingBladesCD:Stop(args.destGUID)
|
|
elseif cid == 104274 then--Baalgar the Watchful
|
|
timerDisintegrationBeamCD:Stop(args.destGUID)
|
|
elseif cid == 104273 then--Jazshariu
|
|
timerShockwaveCD:Stop(args.destGUID)
|
|
timerCrushingLeapCD:Stop(args.destGUID)
|
|
end
|
|
end
|
|
|
|
do
|
|
--Court notable NPC stuff
|
|
--Old professions icon Ids/skill levels maintained in case classic ever gets up to legion
|
|
--Parts of code modified from littlewigs with permission for max intermod operability and no wheel re-inventing
|
|
local professionCache = {}
|
|
|
|
local notableBuffNPCs = {
|
|
--Buffs
|
|
[105160] = { -- Fel Orb
|
|
["name"] = DBM:GetSpellName(208275),
|
|
["buffid"] = 211081,
|
|
["class"] = {
|
|
["PALADIN"] = true,
|
|
["PRIEST"] = true,
|
|
["WARLOCK"] = true,
|
|
["DEMONHUNTER"] = true
|
|
}
|
|
},
|
|
[105249] = { -- Nightshade Refreshments
|
|
["name"] = L.Nightshade,
|
|
["buffid"] = 211102,
|
|
["raceids"] = {
|
|
[24] = true,--Pandaren (Neutral). DoubleAgent may find a way to get here?
|
|
[25] = true,--Pandaren (Alliance)
|
|
[26] = true--Pandaren (Horde)
|
|
},
|
|
["professionicons"] = {
|
|
-- [133971] = 800,--Cooking (old)
|
|
[4620671] = 1,--Cooking (DF)
|
|
-- [136246] = 800,--Herbalist (old)
|
|
[4620675] = 1--Herbalist (DF)
|
|
}
|
|
},
|
|
[105340] = { -- Umbral Bloom
|
|
["name"] = L.UmbralBloom,
|
|
["buffid"] = 211110,
|
|
["class"] = {
|
|
["DRUID"] = true
|
|
},
|
|
["professionicons"] = {
|
|
-- [133971] = 800,--Cooking (old)
|
|
[4620671] = 1,--Cooking (DF)
|
|
-- [136246] = 800,--Herbalist (old)
|
|
[4620675] = 1--Herbalist (DF)
|
|
}
|
|
},
|
|
[105831] = { -- Infernal Tome
|
|
["name"] = L.InfernalTome,
|
|
["buffid"] = 211080,
|
|
["class"] = {
|
|
["PALADIN"] = true,
|
|
["PRIEST"] = true,
|
|
["DEMONHUNTER"] = true
|
|
}
|
|
},
|
|
[106024] = { -- Magical Lantern
|
|
["name"] = L.MagicalLantern,
|
|
["buffid"] = 211093,
|
|
["class"] = {
|
|
["MAGE"] = true
|
|
},
|
|
["raceids"] = {
|
|
[4] = true,--Night Elf
|
|
[10] = true--Blood Elf
|
|
},
|
|
["professionicons"] = {
|
|
-- [136244] = 800,--Enchanting (Old)
|
|
[4620672] = 1--Enchanting (New)
|
|
}
|
|
},
|
|
[106108] = { -- Starlight Rose Brew
|
|
["name"] = L.StarlightRoseBrew,
|
|
["buffid"] = 211071,
|
|
["class"] = {
|
|
["DEATHKNIGHT"] = true,
|
|
["MONK"] = true
|
|
},
|
|
},
|
|
[106110] = { -- Waterlogged Scroll
|
|
["name"] = L.WaterloggedScroll,
|
|
["buffid"] = 211084,
|
|
["class"] = {
|
|
["SHAMAN"] = true
|
|
},
|
|
["professionicons"] = {
|
|
-- [134366] = 800,--Skinning (Old)
|
|
[4620680] = 1,--Skinning (New)
|
|
-- [237171] = 800,--Inscription (Old)
|
|
[4620676] = 1--Inscription (New)
|
|
}
|
|
},
|
|
--Debuffs
|
|
[105117] = { -- Flask of the Solemn Night
|
|
["name"] = DBM:GetSpellName(207815),
|
|
["class"] = {
|
|
["ROGUE"] = true
|
|
},
|
|
["professionicons"] = {
|
|
-- [136240] = 800, -- Alchemy (old)
|
|
[4620669] = 1 -- Alchemy (DF)
|
|
}
|
|
},
|
|
[105157] = {-- Arcane Power Conduit
|
|
["name"] = DBM:GetSpellName(210466),
|
|
["raceids"] = {
|
|
[7] = true,--Gnome
|
|
[9] = true--Goblin
|
|
},
|
|
["professionicons"] = {
|
|
-- [136243] = 800, -- Engineering (old)
|
|
[4620673] = 1 -- Engineering (DF)
|
|
}
|
|
}
|
|
}
|
|
|
|
local notableNonBuffNPCs = {
|
|
--Alerts
|
|
[105215] = { -- Discarded Junk
|
|
["name"] = L.DiscardedJunk,
|
|
["class"] = {
|
|
["HUNTER"] = true
|
|
},
|
|
["professionicons"] = {
|
|
-- [136241] = 800, -- Blacksmithing (old)
|
|
[4620670] = 1 -- Blacksmithing (DF)
|
|
},
|
|
},
|
|
[106018] = { -- Bazaar Goods
|
|
["name"] = L.BazaarGoods,
|
|
["class"] = {
|
|
["WARRIOR"] = true,
|
|
["ROGUE"] = true,
|
|
},
|
|
["professionicons"] = {
|
|
-- [136247] = 800, -- Leatherworking (old)
|
|
[4620678] = 1 -- Leatherworking (DF)
|
|
}
|
|
},
|
|
[106112] = { -- Wounded Nightborne Civilian
|
|
["name"] = L.WoundedNightborneCivilian,
|
|
["professionicons"] = {
|
|
-- [136249] = 800, -- Tailoring (old)
|
|
[4620681] = 1 -- Tailoring (DF)
|
|
},
|
|
["roles"] = {
|
|
["Healer"] = true,
|
|
}
|
|
},
|
|
[106113] = { -- Lifesized Nightborne Statue
|
|
["name"] = L.LifesizedNightborneStatue,
|
|
["professionicons"] = {
|
|
-- [134708] = 800, -- Mining (old)
|
|
[4620679] = 1, -- Mining (DF)
|
|
-- [134071] = 800, -- JC (old)
|
|
[4620677] = 1 -- JC (DF)
|
|
}
|
|
}
|
|
}
|
|
|
|
local raceIcons = {
|
|
[4] = "|T236449:0|t",
|
|
[7] = "|T236445:0|t",
|
|
[9] = "|T632354:0|t",
|
|
[10] = "|T236439:0|t",
|
|
[24] = "|T626190:0|t",
|
|
[25] = "|T626190:0|t",
|
|
[26] = "|T626190:0|t"
|
|
}
|
|
|
|
local function getClassIcon(class)
|
|
return ("|TInterface/Icons/classicon_%s:0|t"):format(strlower(class))
|
|
end
|
|
|
|
local function getIconById(id)
|
|
return ("|T%d:0|t"):format(id)
|
|
end
|
|
|
|
local roleIcons = {
|
|
["Healer"] = "|T337497:0:0:0:0:64:64:20:39:1:20|t",
|
|
}
|
|
|
|
local function alertUsable(self, cid, item)
|
|
self:SendBigWigsSync("itemAvailable", cid)
|
|
local players = {} -- who can use the item
|
|
local icons = {}
|
|
if item.professionicons then
|
|
for profIcon, requiredSkill in pairs(item.professionicons) do
|
|
if professionCache[profIcon] then
|
|
for _,v in pairs(professionCache[profIcon]) do
|
|
if v.skill >= requiredSkill then
|
|
players[v.name] = true
|
|
end
|
|
end
|
|
end
|
|
icons[#icons+1] = getIconById(profIcon)
|
|
end
|
|
end
|
|
if item.raceids then
|
|
for race, _ in pairs(item.raceids) do
|
|
for unit in DBM:GetGroupMembers() do
|
|
local _, _, unitRaceID = UnitRace(unit)
|
|
if unitRaceID == race then
|
|
players[DBM:GetUnitFullName(unit)] = true
|
|
end
|
|
end
|
|
icons[#icons+1] = raceIcons[race]
|
|
end
|
|
end
|
|
if item.class then
|
|
for class, _ in pairs(item.class) do
|
|
for unit in DBM:GetGroupMembers() do
|
|
local _, unitClass = UnitClass(unit)
|
|
if unitClass == class then
|
|
players[DBM:GetUnitFullName(unit)] = true
|
|
end
|
|
end
|
|
icons[#icons+1] = getClassIcon(class)
|
|
end
|
|
end
|
|
if item.roles then
|
|
for role, _ in pairs(item.roles) do
|
|
for unit in DBM:GetGroupMembers() do
|
|
if UnitGroupRolesAssigned(unit) == role then
|
|
players[DBM:GetUnitFullName(unit)] = true
|
|
end
|
|
end
|
|
icons[#icons+1] = roleIcons[role]
|
|
end
|
|
end
|
|
|
|
local message = (L.Available):format(table.concat(icons, ""), item.name)
|
|
|
|
if next(players) then
|
|
local list = ""
|
|
for player in pairs(players) do
|
|
if UnitInParty(player) then -- don't announce players from previous groups
|
|
list = list .. ">" .. player .. "<, "
|
|
end
|
|
end
|
|
if list:len() > 0 then
|
|
message = message .. " - ".. L.UsableBy:format(list:sub(0, list:len()-2))
|
|
end
|
|
end
|
|
warnAvailableItems:Show(message)
|
|
end
|
|
|
|
local function assessUsable(self, cid, item)
|
|
--Don't alert if buff already active
|
|
if notableBuffNPCs[cid] and notableBuffNPCs[cid].buffid and DBM:UnitBuff("player", notableBuffNPCs[cid].buffid) then return end
|
|
--Don't alert if we alerted within last 5 minutes
|
|
if self:AntiSpam(300, "CoS"..cid) then
|
|
local delayAnnouncement = false
|
|
if item.professionicons then
|
|
if self:AntiSpam(300, "CoSProf") then
|
|
self:SendBigWigsSync("getProfessions")
|
|
delayAnnouncement = true
|
|
end
|
|
end
|
|
if delayAnnouncement then
|
|
self:Schedule(0.5, alertUsable, self, cid, item)
|
|
else
|
|
alertUsable(self, cid, item)
|
|
end
|
|
end
|
|
end
|
|
|
|
function mod:UPDATE_MOUSEOVER_UNIT()
|
|
local cid = DBM:GetUnitCreatureId("mouseover")
|
|
local item = notableBuffNPCs[cid] or notableNonBuffNPCs[cid]
|
|
if item then
|
|
assessUsable(self, cid, item)
|
|
end
|
|
end
|
|
|
|
--Court Clue Stuff
|
|
local clueTotal = 0
|
|
local hintTranslations = {
|
|
[1] = L.Cape or "cape",
|
|
[2] = L.Nocape or "no cape",
|
|
[3] = L.Pouch or "pouch",
|
|
[4] = L.Potions or "potions",
|
|
[5] = L.LongSleeve or "long sleeves",
|
|
[6] = L.ShortSleeve or "short sleeves",
|
|
[7] = L.Gloves or "gloves",
|
|
[8] = L.NoGloves or "no gloves",
|
|
[9] = L.Male or "male",
|
|
[10] = L.Female or "female",
|
|
[11] = L.LightVest or "light vest",
|
|
[12] = L.DarkVest or "dark vest",
|
|
[13] = L.NoPotions or "no potions",
|
|
[14] = L.Book or "book",
|
|
}
|
|
local hints = {}
|
|
local clueIds = {
|
|
[45674] = 1,--Cape
|
|
[45675] = 2,--No Cape
|
|
[45660] = 3,--Pouch
|
|
[45666] = 4,--Potions
|
|
[45676] = 5,--Long Sleeves
|
|
[45677] = 6,--Short Sleeves
|
|
[45673] = 7,--Gloves
|
|
[45672] = 8,--No Gloves
|
|
[45657] = 9,--Male
|
|
[45658] = 10,--Female
|
|
[45636] = 11,--Light Vest
|
|
[45635] = 12,--Dark Vest
|
|
[45667] = 13,--No Potions
|
|
[45659] = 14--Book
|
|
}
|
|
|
|
local function updateInfoFrame()
|
|
local lines = {}
|
|
for hint, _ in pairs(hints) do
|
|
local text = hintTranslations[hint]
|
|
lines[text] = ""
|
|
end
|
|
return lines
|
|
end
|
|
|
|
local function callUpdate(clue)
|
|
clueTotal = clueTotal + 1
|
|
DBM.InfoFrame:SetHeader(L.CluesFound:format(clueTotal))
|
|
DBM.InfoFrame:Show(5, "function", updateInfoFrame)
|
|
local text = hintTranslations[clue]
|
|
DBM:AddMsg(L.ClueShort:format(clueTotal, text))
|
|
end
|
|
|
|
function mod:ResetGossipState()--/run DBM:GetModByName("CoSTrash"):ResetGossipState()
|
|
table.wipe(hints)
|
|
clueTotal = 0
|
|
DBM.InfoFrame:Hide()
|
|
end
|
|
|
|
function mod:CHAT_MSG_MONSTER_SAY(msg, _, _, _, target)
|
|
if msg:find(L.Found) or msg == L.Found then
|
|
self:SendSync("Finished", target)
|
|
if self.Options.SpyHelper and self.Options.SendToChat2 and target == UnitName("player") then
|
|
local text = L.SpyFoundP
|
|
if IsInGroup(LE_PARTY_CATEGORY_INSTANCE) then
|
|
SendChatMessage("DBM: "..text, "INSTANCE_CHAT")
|
|
elseif IsInGroup(LE_PARTY_CATEGORY_HOME) then
|
|
SendChatMessage("DBM: "..text, "PARTY")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function mod:GOSSIP_SHOW()
|
|
local cid = DBM:GetUnitCreatureId("npc")
|
|
if self.Options.AutoGossipBuff and notableBuffNPCs[cid] then
|
|
self:SelectGossip(1)
|
|
return
|
|
end
|
|
local gossipOptionID = self:GetGossipID()
|
|
if gossipOptionID then
|
|
if self.Options.AutoGossipAction and gossipOptionID == 45624 then -- Boat
|
|
self:SelectGossip(gossipOptionID)
|
|
elseif self.Options.AutoGossipAction and gossipOptionID == 45656 then -- Disguise
|
|
self:SelectGossip(gossipOptionID)
|
|
elseif clueIds[gossipOptionID] then -- SpyHelper
|
|
if not self.Options.SpyHelper then return end
|
|
local clue = clueIds[gossipOptionID]
|
|
if not hints[clue] then
|
|
if self.Options.SendToChat2 then
|
|
local text = hintTranslations[clue]
|
|
if IsInGroup(LE_PARTY_CATEGORY_INSTANCE) then
|
|
SendChatMessage("DBM: "..text, "INSTANCE_CHAT")
|
|
elseif IsInGroup(LE_PARTY_CATEGORY_HOME) then
|
|
SendChatMessage("DBM: "..text, "PARTY")
|
|
end
|
|
end
|
|
hints[clue] = true
|
|
self:SendSync("CoS", clue)
|
|
callUpdate(clue)
|
|
--Still required to advance dialog or demon hunters can't use spectral sight
|
|
--We try to delay it by .1 so other mods can still parse gossip ID in theory
|
|
C_Timer.After(0.1, function() self:SelectGossip(gossipOptionID) end)
|
|
end
|
|
if self.Options.SpyHelperClose2 then
|
|
--Delay used so DBM doesn't prevent other mods or WAs from parsing data
|
|
C_Timer.After(0.2, function() C_GossipInfo.CloseGossip() end)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function mod:OnSync(msg, clue)
|
|
if not self.Options.SpyHelper then return end
|
|
if msg == "CoS" and clue then
|
|
clue = tonumber(clue)
|
|
if clue and not hints[clue] then
|
|
hints[clue] = true
|
|
callUpdate(clue)
|
|
end
|
|
elseif msg == "Finished" then
|
|
self:ResetGossipState()
|
|
if clue then
|
|
local targetname = DBM:GetUnitFullName(clue) or clue
|
|
DBM:AddMsg(L.SpyFound:format(targetname))
|
|
end
|
|
end
|
|
end
|
|
function mod:OnBWSync(msg, extra, sender)
|
|
if self.Options.SpyHelper and msg == "clue" then
|
|
extra = tonumber(extra)
|
|
if extra and extra > 0 and extra < 15 and not hints[extra] then
|
|
hints[extra] = true
|
|
callUpdate(extra)
|
|
end
|
|
elseif msg == "itemAvailable" and extra then
|
|
extra = tonumber(extra)
|
|
local item = notableBuffNPCs[extra] or notableNonBuffNPCs[extra]
|
|
if item then
|
|
assessUsable(self, extra, item)
|
|
end
|
|
elseif msg == "getProfessions" then
|
|
--Answer BW profession requests using BW comms
|
|
local professions = {}
|
|
for _,id in pairs({GetProfessions()}) do
|
|
local _, icon, skill = GetProfessionInfo(id) -- name is localized, so use icon instead
|
|
professions[icon] = skill
|
|
end
|
|
local profString = ""
|
|
for k,v in pairs(professions) do
|
|
profString = profString .. k .. ":" .. v .. "#"
|
|
end
|
|
self:SendBigWigsSync("professions", profString)
|
|
elseif msg == "professions" and extra then
|
|
--DBM and BW will both just parse the bigiwgs comms for profession data
|
|
for icon, skill in extra:gmatch("(%d+):(%d+)#") do
|
|
icon = tonumber(icon)
|
|
if icon then
|
|
skill = tonumber(skill)
|
|
if not professionCache[icon] then
|
|
professionCache[icon] = {}
|
|
end
|
|
professionCache[icon][#professionCache[icon]+1] = {name=sender, skill=skill}
|
|
end
|
|
end
|
|
self:AntiSpam(300, "CoSProf")
|
|
end
|
|
end
|
|
end
|
|
|