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.

728 lines
26 KiB

local myname, ns = ...
local core = LibStub("AceAddon-3.0"):GetAddon("SilverDragon")
local module = core:NewModule("Announce", "AceTimer-3.0", "LibSink-2.0")
local Debug = core.Debug
local LSM = LibStub("LibSharedMedia-3.0")
-- Register some media
LSM:Register("sound", "Rubber Ducky", 566121)
LSM:Register("sound", "Cartoon FX", 566543)
LSM:Register("sound", "Explosion", 566982)
LSM:Register("sound", "Shing!", 566240)
LSM:Register("sound", "Wham!", 566946)
LSM:Register("sound", "Simon Chime", 566076)
LSM:Register("sound", "War Drums", 567275)--NPC Scan default
LSM:Register("sound", "Scourge Horn", 567386)--NPC Scan default
4 years ago
LSM:Register("sound", "Dwarf Horn", 566064)
LSM:Register("sound", "Pygmy Drums", 566508)
LSM:Register("sound", "Cheer", 567283)
LSM:Register("sound", "Humm", 569518)
LSM:Register("sound", "Short Circuit", 568975)
LSM:Register("sound", "Fel Portal", 569215)
LSM:Register("sound", "Fel Nova", 568582)
LSM:Register("sound", "PVP Flag", 569200)
4 years ago
LSM:Register("sound", "PvP Flag Horde", 568165) -- PVPFlagTakenHorde
LSM:Register("sound", "Thunder crack", 566202) -- doodad/fx_thundercrack04.ogg
LSM:Register("sound", "Algalon: Beware!", 543587)
LSM:Register("sound", "Yogg Saron: Laugh", 564859)
LSM:Register("sound", "Illidan: Not Prepared", 552503)
LSM:Register("sound", "Magtheridon: I am Unleashed", 554554)
LSM:Register("sound", "Loatheb: I see you", 554236)
LSM:Register("sound", "Ikiss: Trinkets", 561403)
LSM:Register("sound", "NPCScan", 567275)--Sound file is actually bogus, this just forces the option NPCScan into menu. We hack it later.
4 years ago
LSM:Register("sound", "PvP Alliance", 568320) -- PVPWarningAllianceLong
LSM:Register("sound", "PvP Horde", 569112) -- PVPWarningHordeLong
LSM:Register("sound", "Grimrail Train Horn", 1023633)
LSM:Register("sound", "Squire Horn", 598079)
LSM:Register("sound", "Gruntling Horn", 598196)
function module:OnInitialize()
self.db = core.db:RegisterNamespace("Announce", {
profile = {
sink = true,
drums = true,
sound = true,
soundgroup = true,
soundguild = false,
sound_mount = true,
sound_boss = true,
sound_loot = true,
soundfile = "Loatheb: I see you",
soundfile_mount = "Illidan: Not Prepared",
soundfile_boss = "Magtheridon: I am Unleashed",
soundfile_loot = "Ikiss: Trinkets",
sound_loop = 1,
sound_mount_loop = 1,
sound_boss_loop = 1,
sound_loot_loop = 1,
flash = true,
flash_texture = "Blizzard Low Health",
flash_color = {r=1,g=0,b=1,a=1,},
flash_mount = true,
flash_texture_mount = "Blizzard Low Health",
flash_color_mount = {r=0,g=1,b=0,a=1,},
flash_boss = false,
flash_texture_boss = "Blizzard Low Health",
flash_color_boss = {r=1,g=0,b=1,a=1,},
vibrate = true,
vibrate_type = "High",
vibrate_intensity = 1,
vibrate_mount = true,
vibrate_type_mount = "Low",
vibrate_intensity_mount = 1,
vibrate_boss = true,
vibrate_type_boss = "High",
vibrate_intensity_boss = 1,
vibrate_loot = true,
vibrate_type_loot = "High",
vibrate_intensity_loot = 0.8,
instances = false,
dead = true,
already = false,
already_drop = true,
already_transmog = false,
already_alt = true,
sink_opts = {},
channel = "Master",
unmute = false,
background = false,
loot = true,
known_mounts = true,
},
})
self:SetSinkStorage(self.db.profile.sink_opts)
if self.db.profile.sink_opts.sink20OutputSink == "Channel" then
-- 8.2.5 / Classic removed the ability to output to channels, outside of hardware-driven events
self.db.profile.sink_opts.sink20OutputSink = "Default"
end
core.RegisterCallback(self, "Seen")
core.RegisterCallback(self, "SeenLoot")
local config = core:GetModule("Config", true)
if config then
local toggle = config.toggle
local get = function(info) return self.db.profile[info[#info]] end
local set = function(info, v) self.db.profile[info[#info]] = v end
local sink_config = self:GetSinkAce3OptionsDataTable()
local sink_args = {}
for k,v in pairs(sink_config.args) do
if k ~= "Channel" then
sink_args[k] = v
end
end
sink_config.args = sink_args
sink_config.inline = true
sink_config.order = 15
sink_config.args.Channel = nil
local faker = function(id, name, zone, x, y)
return {
type = "execute", name = name,
desc = "Fake seeing " .. name,
func = function()
-- id, zone, x, y, is_dead, source, unit
core.events:Fire("Seen", id, zone, x, y, false, "fake", false)
end,
}
end
local soundfile = function(enabled_key, order)
return {
type = "select", dialogControl = "LSM30_Sound",
name = "Sound to Play", desc = "Choose a sound file to play",
values = AceGUIWidgetLSMlists.sound,
disabled = function() return not self.db.profile[enabled_key] end,
order = order,
}
end
local soundrange = function(order)
return {
type = "range",
name = "Repeat...",
desc = "How many times to repeat the sound",
min = 1, max = 10, step = 1,
order = order,
}
end
local colorget = function(info)
local color = self.db.profile[info[#info]]
return color.r, color.g, color.b, color.a
end
local colorset = function(info, r, g, b, a)
local color = self.db.profile[info[#info]]
color.r, color.g, color.b, color.a = r, g, b, a
end
local options = {
general = {
type = "group", name = "Announcements", inline = true,
order = 10,
get = get, set = set,
args = {
already = toggle("Already found", "Announce when we see rares we've already killed / achieved (if known)", 0),
already_drop = toggle("Got the loot", "Still announce when we see rares which drop a mount / toy / pet you already have", 10),
already_transmog = toggle("...include transmog as loot", "Count transmog appearances as knowable loot", 11),
already_alt = toggle("Completed by an alt", "Announce when we see rares for an achievement that the current character doesn't have, but an alt has completed already", 20),
known_mounts = toggle("Known mounts are boring", "Treat mount-dropping rares whose mount you already know as if they're regular rares (unless the mount is BoE)", 25),
dead = toggle("Dead rares", "Announce when we see dead rares, if known. Not all scanning methods know whether a rare is dead or not", 30),
instances = toggle("Instances", "Show announcements while in an instance", 50),
loot = toggle("Treasures", "Show announcements when treasure appears on the minimap", 60),
},
},
message = {
type = "group", name = "Messages",
order = 20,
get = get, set = set,
args = {
sink = toggle("Enabled", "Send a message to whatever scrolling text addon you're using.", 10),
output = sink_config,
},
},
test = {
type = "group", name = "Test it!",
inline = true,
args = {
-- id, name, zone, x, y, is_dead, is_new_location, source, unit
time = faker(32491, "Time-Lost Proto Drake (Mount!)", 120, 0.490, 0.362),
-- ishak = faker(157134, "Ishak of the Four Winds (Mount!)", 1527, 0.73, 0.83),
anger = faker(60491, "Sha of Anger (Boss!)", 809, 0.5, 0.5),
vyragosa = faker(32630, "Vyragosa (Boring)", 120, 0.5, 0.5),
deathmaw = faker(10077, "Deathmaw (Tame!)", 29, 0.5, 0.5),
-- haakun = faker(83008, "Haakun", 946, 0.5, 0.5),
yiphrim = faker(157473, "Yiphrim the Will Ravager (Toy!)", 1527, 0.5, 0.786),
amalgamation = faker(157593, "Amalgamation of Flesh (Pet!)", 1527, 0.598, 0.724),
-- alash = faker(148787, "Alash'anir", 62, 0.598, 0.724),
-- burninator = faker(149141, "Burninator Mk V (Pet!)", 62, 0.414, 0.764),
worldedge = faker(160821, "Worldedge Gorger (mount)", 1525, 0.5, 0.5),
tarahna = faker(126900, "Instructor Tarahna (multi-toy)", 882, 0.5, 0.5),
nerissa = faker(162690, "Nerissa Heartless (mount)", 1536, 0.5, 0.5),
-- faeflayer = faker(171688, "Faeflayer", 1536, 0.5, 0.5),
scrapking = faker(151625, "Scrap King (loot)", 1462, 0.5, 0.5),
kash = faker(159105, "Collector Kash (lots of loot)", 1536, 0.5, 0.5),
4 years ago
-- worldcracker = faker(180032, "Wild Worldcracker", 1961, 0.5, 0.5),
-- blanchy = faker(173468, "Dead Blanchy", 1525, 0.5, 0.5),
chest = {
type = "execute", name = "Waterlogged Chest",
desc = "Fake seeing a Waterlogged Chest",
func = function()
-- id, zone, x, y, is_dead, source, unit
core.events:Fire("SeenLoot", "Waterlogged Chest", 3341, 37, 0.318, 0.628)
end,
},
},
},
sound = {
type = "group", name = "Sounds",
get = get, set = set,
order = 10,
args = {
about = config.desc("Play sounds to announce rare mobs? Can do special things for special mobs. You *really* don't want to miss, say, the Time-Lost Proto Drake, after all...", 0),
channel = {
type = "select",
name = _G.SOUND_CHANNELS,
descStyle = "inline",
values = {
Ambience = _G.AMBIENCE_VOLUME,
Master = _G.MASTER,
Music = _G.MUSIC_VOLUME,
SFX = _G.SOUND_VOLUME,
Dialog = _G.DIALOG_VOLUME,
},
order = 11,
},
unmute = toggle("Ignore mute", "Play sounds even when muted", 12),
background = toggle(_G.ENABLE_BGSOUND, _G.OPTION_TOOLTIP_ENABLE_BGSOUND, 13),
drums = toggle("The Sound of Drums", "Underneath it all, the constant drumming", 14),
soundgroup = toggle("Group Sync Sounds", "Play sounds from synced mobs from party/raid members", 15),
soundguild = toggle("Guild Sync Sounds", "Play sounds from synced mobs from guild members not in group", 16),
regular = {type="header", name="", order=20,},
sound = toggle("Sounds", "Play sounds for regular mobs", 21),
soundfile = soundfile("sound", 22),
sound_loop = soundrange(23),
mount = {type="header", name="", order=25,},
sound_mount = toggle("Mount sounds", "Play a sound for mobs that drop a mount", 26),
soundfile_mount = soundfile("sound_mount", 27),
sound_mount_loop = soundrange(28),
boss = {type="header", name="", order=30,},
sound_boss = toggle("Boss sounds", "Play a sound for mobs that require a group", 31),
soundfile_boss = soundfile("sound_boss", 35),
sound_boss_loop = soundrange(37),
loot = {type="header", name="", order=40,},
sound_loot = toggle("Loot sounds", "Play a sound for treasures", 41),
soundfile_loot = soundfile("sound_loot", 45),
sound_loot_loop = soundrange(47),
},
},
flash = {
type = "group", name = "Flash",
get = get, set = set,
order = 15,
args = {
about = config.desc("Flash the screen when a rare is seen.", 0),
flash = toggle("Enabled", "Flash the screen?", 1),
flash_color = {
name = COLOR,
type = "color",
hasAlpha = true,
descStyle = "inline",
get = colorget,
set = colorset,
order = 2,
},
flash_texture = {
name = TEXTURES_SUBHEADER,
type = "select",
descStyle = "inline",
dialogControl = "LSM30_Background",
values = AceGUIWidgetLSMlists.background,
order = 3,
},
preview = {
name = PREVIEW,
type = "execute",
func = function()
module:Flash(50065) -- Armagedillo
end,
order = 4,
},
mount = {type="header", name="", order=10,},
flash_mount = toggle("Mount flash", "Flash the screen differently when we see a mob with a mount?", 11),
flash_color_mount = {
name = COLOR,
type = "color",
hasAlpha = true,
descStyle = "inline",
get = colorget,
set = colorset,
order = 12,
},
flash_texture_mount = {
name = TEXTURES_SUBHEADER,
type = "select",
descStyle = "inline",
dialogControl = "LSM30_Background",
values = AceGUIWidgetLSMlists.background,
order = 13,
},
preview_mount = {
name = PREVIEW,
type = "execute",
func = function()
module:Flash(32491) -- time lost
end,
order = 14,
},
boss = {type="header", name="", order=20,},
flash_boss = toggle("Boss flash", "Flash the screen differently when we see a boss rare?", 21),
flash_color_boss = {
name = COLOR,
type = "color",
hasAlpha = true,
descStyle = "inline",
get = colorget,
set = colorset,
order = 22,
},
flash_texture_boss = {
name = TEXTURES_SUBHEADER,
type = "select",
descStyle = "inline",
dialogControl = "LSM30_Background",
values = AceGUIWidgetLSMlists.background,
order = 23,
},
preview_boss = {
name = PREVIEW,
type = "execute",
func = function()
module:Flash(70096) -- War-God Dokah
end,
order = 24,
},
},
},
controller = {
type = "group", name = "Controller",
get = get, set = set,
disabled = function(info) return info[#info] ~= "controller" and not C_GamePad.IsEnabled() end,
order = 15,
args = {
about = config.desc("Vibrate a connected controller when a rare is seen. Only works if controller support is enabled. You can turn it on by typing `/console GamePadEnable 1` in the chat box.", 0),
},
},
}
local function vibrate_section(t, key, order, heading)
key = key and ("_"..key) or ""
if heading then
t["vibrate_heading" .. key] = {type="header", name="", order=order,}
end
t["vibrate" .. key] = toggle(heading or "Vibrate", "Vibrate the controller?", order + 1)
t["vibrate_type" .. key] = {
type = "select", name = "Type",
desc = "What type of vibration to use",
values = {
Low = "Low",
High = "High",
LTrigger = "LTrigger (PS5 only)",
RTrigger = "RTrigger (PS5 only)",
},
order = order + 2,
}
t["vibrate_intensity" .. key] = {
type = "range", name = "Intensity",
desc = "How strong the vibration should be",
min = 0, max = 1, step = 0.1,
order = order + 3,
}
t["preview" .. key] = {
type = "execute", name = PREVIEW,
func = function(info)
C_GamePad.SetVibration(self.db.profile["vibrate_type" .. key], self.db.profile["vibrate_intensity" .. key])
end,
order = order + 4,
}
return order + 5
end
local order = 1
order = vibrate_section(options.controller.args, nil, 1)
order = vibrate_section(options.controller.args, "mount", order, "Vibrate for mounts")
order = vibrate_section(options.controller.args, "boss", order, "Vibrate for bosses")
order = vibrate_section(options.controller.args, "loot", order, "Vibrate for loot")
config.options.args.general.plugins.announce = options
end
end
function module:HasInterestingMounts(id)
if not module.db.profile.known_mounts then
return ns.Loot.HasMounts(id)
end
return ns.Loot.HasInterestingMounts(id)
end
function module:Seen(callback, id, zone, x, y, is_dead, source, ...)
Debug("Announce:Seen", id, zone, x, y, is_dead, ...)
if not self.db.profile.instances and IsInInstance() then
return
end
if not self:ShouldAnnounce(id, zone, x, y, is_dead, source, ...) then
return
end
core.events:Fire("Announce", id, zone, x, y, is_dead, source, ...)
end
function module:SeenLoot(callback, name, id, zone, x, y, ...)
Debug("Announce:SeenLoot", name, id, zone, x, y, ...)
if not self.db.profile.instances and IsInInstance() then
return
end
if not self.db.profile.loot then
return
end
core.events:Fire("AnnounceLoot", name, id, zone, x, y, ...)
end
function module:ShouldAnnounce(id, zone, x, y, is_dead, source, ...)
if is_dead and not self.db.profile.dead then
Debug("ShouldAnnounce", false, "dead")
return false
end
if core.db.global.always[id] then
-- If you've manually added a mob, bypass any other checks
Debug("ShouldAnnounce", true, "always")
return true
end
if not self.db.profile.already_drop and ns.Loot.Status(id, self.db.profile.already_transmog) == true and not ns.Loot.HasMounts(id, true, true) then
-- hide mobs which have a mount/pet/toy which you already own... apart from BoE mounts
-- this means there's knowable loot, and it's all known
Debug("ShouldAnnounce", false, "already got loot")
return false
end
4 years ago
if ns.mobdb[id] and ns.mobdb[id].requires and not ns.conditions.check(ns.mobdb[id].requires) then
Debug("ShouldAnnounce", false, "requirements not met")
return false
end
if not self.db.profile.already then
-- hide already-completed mobs
local quest, achievement, by_alt = ns:CompletionStatus(id)
if by_alt and not self.db.profile.already_alt then
-- an alt has completed the achievement, and we don't want to know about that
Debug("ShouldAnnounce", false, "alt got achievement")
return false
end
if source == "vignette" or source == "point-of-interest" then
-- The vignette's presence implies no quest completion
Debug("ShouldAnnounce", true, "vignette implies quest")
return true
end
if quest ~= nil then
Debug("ShouldAnnounce", not quest, "quest")
return not quest
end
if achievement ~= nil then
-- can just fall back on achievement
Debug("ShouldAnnounce", not achievement, "achievement")
return not achievement
end
end
Debug("ShouldAnnounce", true, "fallback")
return true
end
core.RegisterCallback("SD Announce Sink", "Announce", function(callback, id, zone, x, y, dead, source)
if not module.db.profile.sink then
return
end
Debug("Pouring")
if source:match("^sync") then
local channel, player = source:match("sync:(.+):(.+)")
if channel and player then
local localized_zone = core.zone_names[zone] or UNKNOWN
source = "by " .. player .. " in your " .. strlower(channel) .. "; " .. localized_zone
end
end
local pin = ""
if x and y then
if x == 0 and y == 0 then
source = source .. " @ unknown location"
else
source = source .. (" @ %.1f, %.1f"):format(x * 100, y * 100)
if module.db.profile.sink_opts.sink20OutputSink == "ChatFrame" then
pin = (" |cffffff00|Hworldmap:%d:%d:%d|h[%s]|h|r"):format(
zone, x * 10000, y * 10000, MAP_PIN_HYPERLINK
)
end
end
end
module:Pour(("Rare seen: %s%s (%s)%s"):format(core:GetMobLabel(id), dead and "... but it's dead" or '', source or '', pin))
end)
core.RegisterCallback("SD AnnounceLoot Sink", "AnnounceLoot", function(callback, name, id, zone, x, y)
if not module.db.profile.sink then
return
end
Debug("Pouring")
local pin = ""
local location = UNKNOWN
if x and y and x > 0 and y > 0 then
location = ("%.1f, %.1f"):format(x * 100, y * 100)
if module.db.profile.sink_opts.sink20OutputSink == "ChatFrame" then
pin = (" |cffffff00|Hworldmap:%d:%d:%d|h[%s]|h|r"):format(
zone, x * 10000, y * 10000, MAP_PIN_HYPERLINK
)
end
end
module:Pour(("Treasure seen: %s (%s)%s"):format(name, location, pin))
end)
local cvar_overrides
local channel_cvars = {
Ambience = "Sound_EnableAmbience",
Master = "Sound_EnableAllSound",
Music = "Sound_EnableMusic",
SFX = "Sound_EnableSFX",
Dialog = "Sound_EnableDialog",
}
local delays = {
["Ikiss: Trinkets"] = 5.7,
}
local nowplaying
function module:PlaySound(s)
-- Arg is a table, to make scheduling the loops easier. I am lazy.
Debug("Playing sound", s.soundfile, s.loops)
-- boring check:
if s and s.handle then
StopSound(s.handle)
if s.drumshandle then
StopSound(s.drumshandle)
end
s.handle = nil
s.drumshandle = nil
end
if not s.loops or s.loops == 0 then
if cvar_overrides and s.cvars then
for cvar, value in pairs(s.cvars) do
SetCVar(cvar, value)
end
cvar_overrides = false
end
nowplaying = false
return
end
if not cvar_overrides then
if self.db.profile.background and GetCVar("Sound_EnableSoundWhenGameIsInBG") == "0" then
cvar_overrides = true
s.cvars = s.cvars or {}
s.cvars["Sound_EnableSoundWhenGameIsInBG"] = GetCVar("Sound_EnableSoundWhenGameIsInBG")
SetCVar("Sound_EnableSoundWhenGameIsInBG", "1")
end
if self.db.profile.unmute and GetCVar(channel_cvars[self.db.profile.channel]) == "0" then
cvar_overrides = true
s.cvars = s.cvars or {}
s.cvars[channel_cvars[self.db.profile.channel]] = GetCVar(channel_cvars[self.db.profile.channel])
SetCVar(channel_cvars[self.db.profile.channel], "1")
end
end
-- now, noise!
local drums = self.db.profile.drums
if s.soundfile == "NPCScan" then
--Override default behavior and force npcscan behavior of two sounds at once
drums = true
local _, handle = PlaySoundFile(LSM:Fetch("sound", "Scourge Horn"), self.db.profile.channel)
s.handle = handle
else
--Play whatever sound is set
local _, handle = PlaySoundFile(LSM:Fetch("sound", s.soundfile), self.db.profile.channel)
s.handle = handle
end
if drums then
local _, handle = PlaySoundFile(LSM:Fetch("sound", "War Drums"), self.db.profile.channel)
s.drumshandle = handle
end
s.loops = s.loops - 1
-- we guarantee one callback, in case we need to do cleanup
self:ScheduleTimer("PlaySound", delays[s.soundfile] or 4.5, s)
nowplaying = true
end
core.RegisterCallback("SD Announce Sound", "Announce", function(callback, id, zone, x, y, dead, source)
if not LSM then return end
if nowplaying then return end
if source:match("^sync") then
local channel, player = source:match("sync:(.+):(.+)")
if channel == "GUILD" and not module.db.profile.soundguild or (channel == "PARTY" or channel == "RAID") and not module.db.profile.soundgroup then return end
end
local soundfile, loops
if module:HasInterestingMounts(id) then
if not module.db.profile.sound_mount then return end
soundfile = module.db.profile.soundfile_mount
loops = module.db.profile.sound_mount_loop
elseif ns.mobdb[id] and ns.mobdb[id].boss then
if not module.db.profile.sound_boss then return end
soundfile = module.db.profile.soundfile_boss
loops = module.db.profile.sound_boss_loop
else
if not module.db.profile.sound then return end
soundfile = module.db.profile.soundfile
loops = module.db.profile.sound_loop
end
module:PlaySound{soundfile = soundfile, loops = loops}
end)
core.RegisterCallback("SD AnnounceLoot Sound", "AnnounceLoot", function(callback, id, zone, x, y, dead, source)
if not (module.db.profile.sound_loot and LSM) then
return
end
if nowplaying then return end
module:PlaySound{soundfile = module.db.profile.soundfile_loot, loops = module.db.profile.sound_loot_loop}
end)
do
local flashframe
function module:Flash(id)
if not module.db.profile.flash then
return
end
if not flashframe then
flashframe = CreateFrame("Frame", nil, WorldFrame)
flashframe:SetClampedToScreen(true)
flashframe:SetFrameStrata("FULLSCREEN_DIALOG")
flashframe:SetToplevel(true)
flashframe:SetAllPoints(UIParent)
flashframe:Hide()
-- Use the OutOfControl (blue) and LowHealth (red) textures to get a purple flash
local texture = flashframe:CreateTexture(nil, "BACKGROUND")
texture:SetBlendMode("ADD")
texture:SetDesaturated(true)
texture:SetAllPoints()
local group = flashframe:CreateAnimationGroup()
group:SetLooping("BOUNCE")
local pulse = group:CreateAnimation("Alpha")
pulse:SetFromAlpha(0.3)
pulse:SetToAlpha(0.75)
pulse:SetDuration(0.5236)
local loops = 0
group:SetScript("OnLoop", function(frame, state)
loops = loops + 1
if loops == 9 then
group:Finish()
end
end)
group:SetScript("OnFinished", function(self)
loops = 0
flashframe:Hide()
end)
flashframe:SetScript("OnShow", function(self)
local background = module.db.profile.flash_texture
local color = module.db.profile.flash_color
if self.id and ns.mobdb[self.id] then
if module.db.profile.flash_mount and module:HasInterestingMounts(id) then
background = module.db.profile.flash_texture_mount
color = module.db.profile.flash_color_mount
elseif ns.mobdb[self.id].boss and module.db.profile.flash_boss then
background = module.db.profile.flash_texture_boss
color = module.db.profile.flash_color_boss
end
end
texture:SetTexture(LSM:Fetch("background", background))
texture:SetVertexColor(color.r, color.g, color.b, color.a)
group:Play()
end)
end
Debug("Flashing")
flashframe.id = id
flashframe:Hide()
flashframe:Show()
end
core.RegisterCallback("SD Announce Flash", "Announce", function(callback, id)
module:Flash(id)
end)
core.RegisterCallback("SD AnnounceLoot Flash", "AnnounceLoot", function(callback, id)
module:Flash(id)
end)
end
core.RegisterCallback("SD Announce Controller", "Announce", function(callback, id, zone, x, y, dead, source)
local vibrate_type, vibrate_intensity
if module:HasInterestingMounts(id) then
if not module.db.profile.vibrate_mount then return end
vibrate_type = module.db.profile.vibrate_type_mount
vibrate_intensity = module.db.profile.vibrate_intensity_mount
elseif ns.mobdb[id] and ns.mobdb[id].boss then
if not module.db.profile.vibrate_boss then return end
vibrate_type = module.db.profile.vibrate_type_boss
vibrate_intensity = module.db.profile.vibrate_intensity_boss
else
if not module.db.profile.vibrate then return end
vibrate_type = module.db.profile.vibrate_type
vibrate_intensity = module.db.profile.vibrate_intensity
end
C_GamePad.SetVibration(vibrate_type, vibrate_intensity)
end)
core.RegisterCallback("SD AnnounceLoot Controller", "AnnounceLoot", function(callback, id, zone, x, y, dead, source)
if not module.db.profile.vibrate_loot then
return
end
C_GamePad.SetVibration(module.db.profile.vibrate_type_loot, module.db.profile.vibrate_intensity_loot)
end)