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.
712 lines
20 KiB
712 lines
20 KiB
|
5 years ago
|
-------------------------------------------------------------------------------
|
||
|
|
-- BigWigs API
|
||
|
|
-- @module BigWigs
|
||
|
|
-- @alias core
|
||
|
|
|
||
|
|
local core, bossPrototype, pluginPrototype
|
||
|
|
do
|
||
|
|
local _, tbl =...
|
||
|
|
core = tbl.core
|
||
|
|
bossPrototype = tbl.bossPrototype
|
||
|
|
pluginPrototype = tbl.pluginPrototype
|
||
|
|
|
||
|
|
core.name = "BigWigs"
|
||
|
|
|
||
|
|
local at = LibStub("AceTimer-3.0")
|
||
|
|
at:Embed(core)
|
||
|
|
at:Embed(bossPrototype)
|
||
|
|
at:Embed(pluginPrototype)
|
||
|
|
end
|
||
|
|
|
||
|
|
local adb = LibStub("AceDB-3.0")
|
||
|
|
local lds = LibStub("LibDualSpec-1.0")
|
||
|
|
|
||
|
|
local L = BigWigsAPI:GetLocale("BigWigs")
|
||
|
|
local CL = BigWigsAPI:GetLocale("BigWigs: Common")
|
||
|
|
local loader = BigWigsLoader
|
||
|
|
core.SendMessage = loader.SendMessage
|
||
|
|
|
||
|
|
local mod, bosses, plugins = {}, {}, {}
|
||
|
|
local coreEnabled = false
|
||
|
|
|
||
|
|
-- Try to grab unhooked copies of critical loading funcs (hooked by some crappy addons)
|
||
|
|
local GetBestMapForUnit = loader.GetBestMapForUnit
|
||
|
|
local SendAddonMessage = loader.SendAddonMessage
|
||
|
|
local GetInstanceInfo = loader.GetInstanceInfo
|
||
|
|
local UnitName = BigWigsLoader.UnitName
|
||
|
|
local UnitGUID = BigWigsLoader.UnitGUID
|
||
|
|
|
||
|
|
-- Upvalues
|
||
|
|
local next, type, setmetatable = next, type, setmetatable
|
||
|
|
|
||
|
|
local pName = UnitName("player")
|
||
|
|
|
||
|
|
-------------------------------------------------------------------------------
|
||
|
|
-- Event handling
|
||
|
|
--
|
||
|
|
|
||
|
|
do
|
||
|
|
local noEvent = "Module %q tried to register/unregister an event without specifying which event."
|
||
|
|
local noFunc = "Module %q tried to register an event with the function '%s' which doesn't exist in the module."
|
||
|
|
|
||
|
|
local eventMap = {}
|
||
|
|
local bwUtilityFrame = CreateFrame("Frame")
|
||
|
|
bwUtilityFrame:SetScript("OnEvent", function(_, event, ...)
|
||
|
|
for k,v in next, eventMap[event] do
|
||
|
|
if type(v) == "function" then
|
||
|
|
v(event, ...)
|
||
|
|
else
|
||
|
|
k[v](k, event, ...)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
|
||
|
|
function core:RegisterEvent(event, func)
|
||
|
|
if type(event) ~= "string" then error((noEvent):format(self.moduleName)) end
|
||
|
|
if (not func and not self[event]) or (type(func) == "string" and not self[func]) then error((noFunc):format(self.moduleName or "?", func or event)) end
|
||
|
|
if not eventMap[event] then eventMap[event] = {} end
|
||
|
|
eventMap[event][self] = func or event
|
||
|
|
bwUtilityFrame:RegisterEvent(event)
|
||
|
|
end
|
||
|
|
function core:UnregisterEvent(event)
|
||
|
|
if type(event) ~= "string" then error((noEvent):format(self.moduleName)) end
|
||
|
|
if not eventMap[event] then return end
|
||
|
|
eventMap[event][self] = nil
|
||
|
|
if not next(eventMap[event]) then
|
||
|
|
bwUtilityFrame:UnregisterEvent(event)
|
||
|
|
eventMap[event] = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function UnregisterAllEvents(_, module)
|
||
|
|
for k,v in next, eventMap do
|
||
|
|
for j in next, v do
|
||
|
|
if j == module then
|
||
|
|
module:UnregisterEvent(k)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
loader.RegisterMessage(mod, "BigWigs_OnBossDisable", UnregisterAllEvents)
|
||
|
|
loader.RegisterMessage(mod, "BigWigs_OnBossWipe", UnregisterAllEvents)
|
||
|
|
loader.RegisterMessage(mod, "BigWigs_OnPluginDisable", UnregisterAllEvents)
|
||
|
|
end
|
||
|
|
|
||
|
|
-------------------------------------------------------------------------------
|
||
|
|
-- ENCOUNTER event handler
|
||
|
|
--
|
||
|
|
|
||
|
|
function mod:ENCOUNTER_START(_, id)
|
||
|
|
for _, module in next, bosses do
|
||
|
|
if module.engageId == id then
|
||
|
|
if not module.enabled then
|
||
|
|
module:Enable()
|
||
|
|
if UnitGUID("boss1") then -- Only if _START fired after IEEU
|
||
|
|
module:Engage()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-------------------------------------------------------------------------------
|
||
|
|
-- Target monitoring
|
||
|
|
--
|
||
|
|
|
||
|
|
local enablezones, enablemobs = {}, {}
|
||
|
|
local function enableBossModule(module, sync)
|
||
|
|
if not module.enabled then
|
||
|
|
module:Enable()
|
||
|
|
if sync and not module.worldBoss then
|
||
|
|
module:Sync("Enable", module.moduleName)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function shouldReallyEnable(unit, moduleName, mobId, sync)
|
||
|
|
local module = bosses[moduleName]
|
||
|
|
if not module or module.enabled then return end
|
||
|
|
if (not module.VerifyEnable or module:VerifyEnable(unit, mobId, GetBestMapForUnit("player"))) then
|
||
|
|
enableBossModule(module, sync)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function targetSeen(unit, targetModule, mobId, sync)
|
||
|
|
if type(targetModule) == "string" then
|
||
|
|
shouldReallyEnable(unit, targetModule, mobId, sync)
|
||
|
|
else
|
||
|
|
for i = 1, #targetModule do
|
||
|
|
local module = targetModule[i]
|
||
|
|
shouldReallyEnable(unit, module, mobId, sync)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function targetCheck(unit, sync)
|
||
|
|
local name = UnitName(unit)
|
||
|
|
if not name or UnitIsCorpse(unit) or UnitIsDead(unit) or UnitPlayerControlled(unit) then return end
|
||
|
|
local guid = UnitGUID(unit)
|
||
|
|
if not guid then
|
||
|
|
core:Error(("Found unit '%s' with name '%s' but no guid, tell the BigWigs authors."):format(unit, name))
|
||
|
|
return
|
||
|
|
end
|
||
|
|
local _, _, _, _, _, mobId = strsplit("-", guid)
|
||
|
|
local id = tonumber(mobId)
|
||
|
|
if id and enablemobs[id] then
|
||
|
|
targetSeen(unit, enablemobs[id], id, sync)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function updateMouseover() targetCheck("mouseover", true) end
|
||
|
|
local function unitTargetChanged(event, target)
|
||
|
|
targetCheck(target .. "target")
|
||
|
|
end
|
||
|
|
|
||
|
|
function core:RegisterEnableMob(module, ...)
|
||
|
|
for i = 1, select("#", ...) do
|
||
|
|
local mobId = select(i, ...)
|
||
|
|
if type(mobId) ~= "number" or mobId < 1 then
|
||
|
|
core:Error(("Module %q tried to register the mobId %q, but it wasn't a valid number."):format(module.moduleName, tostring(mobId)))
|
||
|
|
else
|
||
|
|
module.enableMobs[mobId] = true -- Module specific list
|
||
|
|
-- Global list
|
||
|
|
local entryType = type(enablemobs[mobId])
|
||
|
|
if entryType == "nil" then
|
||
|
|
enablemobs[mobId] = module.moduleName
|
||
|
|
elseif entryType == "table" then
|
||
|
|
enablemobs[mobId][#enablemobs[mobId] + 1] = module.moduleName
|
||
|
|
elseif entryType == "string" then -- Converting from 1 module registered to this mobId, to multiple modules
|
||
|
|
local previousModuleEntry = enablemobs[mobId]
|
||
|
|
enablemobs[mobId] = { previousModuleEntry, module.moduleName }
|
||
|
|
else
|
||
|
|
core:Error(("Unknown type in a enable trigger table at index %d for %q."):format(i, module.moduleName))
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function core:GetEnableMobs()
|
||
|
|
local t = {}
|
||
|
|
for k,v in next, enablemobs do
|
||
|
|
t[k] = v
|
||
|
|
end
|
||
|
|
return t
|
||
|
|
end
|
||
|
|
|
||
|
|
-------------------------------------------------------------------------------
|
||
|
|
-- Testing
|
||
|
|
--
|
||
|
|
|
||
|
|
do
|
||
|
|
local callbackRegistered = false
|
||
|
|
local messages = {}
|
||
|
|
local count = 1
|
||
|
|
local colors = {"green", "red", "orange", "yellow", "cyan", "blue", "blue", "purple"}
|
||
|
|
local sounds = {"Long", "Warning", "Alert", "Alarm", "Info", "onyou", "underyou", false}
|
||
|
|
|
||
|
|
local function barStopped(event, bar)
|
||
|
|
local a = bar:Get("bigwigs:anchor")
|
||
|
|
local key = bar:GetLabel()
|
||
|
|
if a and messages[key] then
|
||
|
|
if not colors[count] then count = 1 end
|
||
|
|
local color = colors[count]
|
||
|
|
local sound = sounds[count]
|
||
|
|
local emphasized = count == 2
|
||
|
|
if count == 6 then
|
||
|
|
core:SendMessage("BigWigs_Flash", core, key)
|
||
|
|
end
|
||
|
|
core:Print(L.test .." - ".. color ..": ".. key)
|
||
|
|
core:SendMessage("BigWigs_Message", core, key, color..": "..key, color, messages[key], emphasized)
|
||
|
|
core:SendMessage("BigWigs_Sound", core, key, sound)
|
||
|
|
count = count + 1
|
||
|
|
messages[key] = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local lastNamePlateBar = 0
|
||
|
|
local lastSpell = 1
|
||
|
|
local lastTest = 1
|
||
|
|
function core:Test()
|
||
|
|
if not callbackRegistered then
|
||
|
|
LibStub("LibCandyBar-3.0").RegisterCallback(core, "LibCandyBar_Stop", barStopped)
|
||
|
|
callbackRegistered = true
|
||
|
|
end
|
||
|
|
|
||
|
|
local msg = CL.count:format(L.test, lastTest)
|
||
|
|
local icon = GetSpellTexture(lastSpell)
|
||
|
|
while not icon or icon == 136243 do -- 136243 = cogwheel
|
||
|
|
lastSpell = lastSpell + 1
|
||
|
|
icon = GetSpellTexture(lastSpell)
|
||
|
|
end
|
||
|
|
lastSpell = lastSpell + 1
|
||
|
|
lastTest = lastTest + 1
|
||
|
|
|
||
|
|
local time = random(11, 30)
|
||
|
|
messages[msg] = icon
|
||
|
|
|
||
|
|
core:SendMessage("BigWigs_StartBar", core, msg, msg, time, icon)
|
||
|
|
|
||
|
|
local guid = UnitGUID("target")
|
||
|
|
if guid and UnitCanAttack("player", "target") then
|
||
|
|
for i = 1, 40 do
|
||
|
|
local unit = ("nameplate%d"):format(i)
|
||
|
|
if UnitGUID(unit) == guid then
|
||
|
|
local t = GetTime()
|
||
|
|
if (t - lastNamePlateBar) > 25 then
|
||
|
|
lastNamePlateBar = t
|
||
|
|
core:Print(L.testNameplate)
|
||
|
|
core:SendMessage("BigWigs_StartNameplateBar", core, msg, msg, 25, icon, false, guid)
|
||
|
|
end
|
||
|
|
return
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-------------------------------------------------------------------------------
|
||
|
|
-- Communication
|
||
|
|
--
|
||
|
|
|
||
|
|
local function bossComm(_, msg, extra, sender)
|
||
|
|
if msg == "Enable" and extra then
|
||
|
|
local m = bosses[extra]
|
||
|
|
if m and not m.enabled and sender ~= pName then
|
||
|
|
enableBossModule(m)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function mod:RAID_BOSS_WHISPER(_, msg) -- Purely for Transcriptor to assist in logging purposes.
|
||
|
|
if IsInGroup() then
|
||
|
|
SendAddonMessage("Transcriptor", msg, IsInGroup(2) and "INSTANCE_CHAT" or "RAID")
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-------------------------------------------------------------------------------
|
||
|
|
-- Initialization
|
||
|
|
--
|
||
|
|
|
||
|
|
local initModules = {}
|
||
|
|
do
|
||
|
|
local function InitializeModules()
|
||
|
|
local count = #initModules
|
||
|
|
if count > 0 then
|
||
|
|
for i = 1, count do
|
||
|
|
initModules[i]:Initialize()
|
||
|
|
end
|
||
|
|
initModules = {}
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function profileUpdate()
|
||
|
|
core:SendMessage("BigWigs_ProfileUpdate")
|
||
|
|
end
|
||
|
|
|
||
|
|
local addonName = ...
|
||
|
|
function mod:ADDON_LOADED(_, name)
|
||
|
|
if name ~= addonName then return end
|
||
|
|
|
||
|
|
local defaults = {
|
||
|
|
profile = {
|
||
|
|
flash = true,
|
||
|
|
showZoneMessages = true,
|
||
|
|
fakeDBMVersion = false,
|
||
|
|
},
|
||
|
|
global = {
|
||
|
|
optionShiftIndexes = {},
|
||
|
|
watchedMovies = {},
|
||
|
|
},
|
||
|
|
}
|
||
|
|
local db = adb:New("BigWigs3DB", defaults, true)
|
||
|
|
lds:EnhanceDatabase(db, "BigWigs3DB")
|
||
|
|
|
||
|
|
db.RegisterCallback(mod, "OnProfileChanged", profileUpdate)
|
||
|
|
db.RegisterCallback(mod, "OnProfileCopied", profileUpdate)
|
||
|
|
db.RegisterCallback(mod, "OnProfileReset", profileUpdate)
|
||
|
|
core.db = db
|
||
|
|
|
||
|
|
mod.ADDON_LOADED = InitializeModules
|
||
|
|
InitializeModules()
|
||
|
|
end
|
||
|
|
core.RegisterEvent(mod, "ADDON_LOADED")
|
||
|
|
end
|
||
|
|
|
||
|
|
do
|
||
|
|
local function DisableModules()
|
||
|
|
for _, module in next, bosses do
|
||
|
|
module:Disable()
|
||
|
|
end
|
||
|
|
for _, module in next, plugins do
|
||
|
|
module:Disable()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
local function DisableCore()
|
||
|
|
if coreEnabled then
|
||
|
|
coreEnabled = false
|
||
|
|
|
||
|
|
loader.UnregisterMessage(mod, "BigWigs_BossComm")
|
||
|
|
core.UnregisterEvent(mod, "ZONE_CHANGED_NEW_AREA")
|
||
|
|
core.UnregisterEvent(mod, "PLAYER_LEAVING_WORLD")
|
||
|
|
core.UnregisterEvent(mod, "ENCOUNTER_START")
|
||
|
|
core.UnregisterEvent(mod, "RAID_BOSS_WHISPER")
|
||
|
|
core.UnregisterEvent(mod, "UPDATE_MOUSEOVER_UNIT")
|
||
|
|
core.UnregisterEvent(mod, "UNIT_TARGET")
|
||
|
|
|
||
|
|
core:CancelAllTimers()
|
||
|
|
|
||
|
|
core:SendMessage("BigWigs_StopConfigureMode")
|
||
|
|
if BigWigsOptions then
|
||
|
|
BigWigsOptions:Close()
|
||
|
|
end
|
||
|
|
DisableModules()
|
||
|
|
core:SendMessage("BigWigs_CoreDisabled")
|
||
|
|
end
|
||
|
|
end
|
||
|
|
local function zoneChanged()
|
||
|
|
-- Not if you released spirit on a world boss or if the GUI is open
|
||
|
|
if not UnitIsDeadOrGhost("player") and (not BigWigsOptions or (not BigWigsOptions:IsOpen() and not BigWigsOptions:InConfigureMode())) then
|
||
|
|
local bars = core:GetPlugin("Bars", true)
|
||
|
|
if bars and not bars:HasActiveBars() then -- Not if bars are showing
|
||
|
|
DisableCore() -- Alive in a non-enable zone, disable
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function EnablePlugins()
|
||
|
|
for _, module in next, plugins do
|
||
|
|
module:Enable()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
function core:Enable(unit)
|
||
|
|
if not coreEnabled then
|
||
|
|
coreEnabled = true
|
||
|
|
|
||
|
|
loader.RegisterMessage(mod, "BigWigs_BossComm", bossComm)
|
||
|
|
core.RegisterEvent(mod, "ENCOUNTER_START")
|
||
|
|
core.RegisterEvent(mod, "RAID_BOSS_WHISPER")
|
||
|
|
core.RegisterEvent(mod, "UPDATE_MOUSEOVER_UNIT", updateMouseover)
|
||
|
|
core.RegisterEvent(mod, "UNIT_TARGET", unitTargetChanged)
|
||
|
|
core.RegisterEvent(mod, "PLAYER_LEAVING_WORLD", DisableCore) -- Simple disable when leaving instances
|
||
|
|
local _, instanceType = GetInstanceInfo()
|
||
|
|
if instanceType == "none" then -- We don't want to be disabling in instances
|
||
|
|
core.RegisterEvent(mod, "ZONE_CHANGED_NEW_AREA", zoneChanged) -- Special checks for disabling after world bosses
|
||
|
|
end
|
||
|
|
|
||
|
|
|
||
|
|
if IsLoggedIn() then
|
||
|
|
EnablePlugins()
|
||
|
|
else
|
||
|
|
core.RegisterEvent(mod, "PLAYER_LOGIN", EnablePlugins)
|
||
|
|
end
|
||
|
|
|
||
|
|
core:SendMessage("BigWigs_CoreEnabled")
|
||
|
|
end
|
||
|
|
if type(unit) == "string" then
|
||
|
|
targetCheck(unit) -- Mainly for the Loader to tell the core to enable a world boss after loading the world boss addon
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function core:IsEnabled()
|
||
|
|
return coreEnabled
|
||
|
|
end
|
||
|
|
|
||
|
|
function core:Print(msg)
|
||
|
|
print("BigWigs: |cffffff00"..msg.."|r")
|
||
|
|
end
|
||
|
|
|
||
|
|
function core:Error(msg)
|
||
|
|
core:Print(msg)
|
||
|
|
geterrorhandler()(msg)
|
||
|
|
end
|
||
|
|
|
||
|
|
-------------------------------------------------------------------------------
|
||
|
|
-- API
|
||
|
|
--
|
||
|
|
|
||
|
|
do
|
||
|
|
local L = GetLocale()
|
||
|
|
if L == "enGB" then L = "enUS" end
|
||
|
|
function core:NewBossLocale(moduleName, locale)
|
||
|
|
local module = bosses[moduleName]
|
||
|
|
if module and L == locale then
|
||
|
|
return module:GetLocale()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-------------------------------------------------------------------------------
|
||
|
|
-- Module handling
|
||
|
|
--
|
||
|
|
|
||
|
|
do
|
||
|
|
local EJ_GetEncounterInfo = EJ_GetEncounterInfo
|
||
|
|
local errorAlreadyRegistered = "%q already exists as a module in BigWigs, but something is trying to register it again."
|
||
|
|
local errorJournalIdInvalid = "%q is using the invalid journal id of %q."
|
||
|
|
local bossMeta = { __index = bossPrototype, __metatable = false }
|
||
|
|
function core:NewBoss(moduleName, zoneId, journalId, instanceId)
|
||
|
|
if bosses[moduleName] then
|
||
|
|
core:Print(errorAlreadyRegistered:format(moduleName))
|
||
|
|
else
|
||
|
|
local m = setmetatable({
|
||
|
|
name = "BigWigs_Bosses_"..moduleName, -- XXX AceAddon/AceDB backwards compat
|
||
|
|
moduleName = moduleName,
|
||
|
|
|
||
|
|
-- Embed callback handler
|
||
|
|
RegisterMessage = loader.RegisterMessage,
|
||
|
|
UnregisterMessage = loader.UnregisterMessage,
|
||
|
|
SendMessage = loader.SendMessage,
|
||
|
|
|
||
|
|
-- Embed event handler
|
||
|
|
RegisterEvent = core.RegisterEvent,
|
||
|
|
UnregisterEvent = core.UnregisterEvent,
|
||
|
|
}, bossMeta)
|
||
|
|
bosses[moduleName] = m
|
||
|
|
initModules[#initModules+1] = m
|
||
|
|
|
||
|
|
if journalId then
|
||
|
|
local name = EJ_GetEncounterInfo(journalId)
|
||
|
|
if name then
|
||
|
|
m.journalId = journalId
|
||
|
|
m.displayName = EJ_GetEncounterInfo(journalId)
|
||
|
|
else
|
||
|
|
m.displayName = moduleName
|
||
|
|
core:Print(errorJournalIdInvalid:format(moduleName, journalId))
|
||
|
|
end
|
||
|
|
else
|
||
|
|
m.displayName = moduleName
|
||
|
|
end
|
||
|
|
|
||
|
|
if zoneId > 0 then
|
||
|
|
m.instanceId = zoneId
|
||
|
|
else
|
||
|
|
m.mapId = -zoneId
|
||
|
|
end
|
||
|
|
return m, CL
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local pluginMeta = { __index = pluginPrototype, __metatable = false }
|
||
|
|
function core:NewPlugin(moduleName)
|
||
|
|
if plugins[moduleName] then
|
||
|
|
core:Print(errorAlreadyRegistered:format(moduleName))
|
||
|
|
else
|
||
|
|
local m = setmetatable({
|
||
|
|
name = "BigWigs_Plugins_"..moduleName, -- XXX AceAddon/AceDB backwards compat
|
||
|
|
moduleName = moduleName,
|
||
|
|
|
||
|
|
-- Embed callback handler
|
||
|
|
RegisterMessage = loader.RegisterMessage,
|
||
|
|
UnregisterMessage = loader.UnregisterMessage,
|
||
|
|
SendMessage = loader.SendMessage,
|
||
|
|
|
||
|
|
-- Embed event handler
|
||
|
|
RegisterEvent = core.RegisterEvent,
|
||
|
|
UnregisterEvent = core.UnregisterEvent,
|
||
|
|
}, pluginMeta)
|
||
|
|
plugins[moduleName] = m
|
||
|
|
initModules[#initModules+1] = m
|
||
|
|
|
||
|
|
return m, CL
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function core:IterateBossModules()
|
||
|
|
return next, bosses
|
||
|
|
end
|
||
|
|
|
||
|
|
function core:GetBossModule(moduleName, silent)
|
||
|
|
if not silent and not bosses[moduleName] then
|
||
|
|
error(("No boss module named '%s' found."):format(moduleName))
|
||
|
|
else
|
||
|
|
return bosses[moduleName]
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function core:IteratePlugins()
|
||
|
|
return next, plugins
|
||
|
|
end
|
||
|
|
|
||
|
|
function core:GetPlugin(moduleName, silent)
|
||
|
|
if not silent and not plugins[moduleName] then
|
||
|
|
error(("No plugin named '%s' found."):format(moduleName))
|
||
|
|
else
|
||
|
|
return plugins[moduleName]
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
do
|
||
|
|
local GetSpellInfo, C_EncounterJournal_GetSectionInfo = GetSpellInfo, C_EncounterJournal.GetSectionInfo
|
||
|
|
local C = core.C -- Set from Constants.lua
|
||
|
|
local standardFlag = C.BAR + C.CASTBAR + C.MESSAGE + C.ICON + C.SOUND + C.SAY + C.SAY_COUNTDOWN + C.PROXIMITY + C.FLASH + C.ALTPOWER + C.VOICE + C.INFOBOX + C.NAMEPLATEBAR
|
||
|
|
local defaultToggles = setmetatable({
|
||
|
|
berserk = C.BAR + C.MESSAGE + C.SOUND,
|
||
|
|
proximity = C.PROXIMITY,
|
||
|
|
altpower = C.ALTPOWER,
|
||
|
|
infobox = C.INFOBOX,
|
||
|
|
}, {__index = function()
|
||
|
|
return standardFlag
|
||
|
|
end})
|
||
|
|
|
||
|
|
local function setupOptions(module)
|
||
|
|
if module.optionHeaders then
|
||
|
|
for k, v in next, module.optionHeaders do
|
||
|
|
if type(v) == "string" then
|
||
|
|
if CL[v] then
|
||
|
|
module.optionHeaders[k] = CL[v]
|
||
|
|
end
|
||
|
|
elseif type(v) == "number" then
|
||
|
|
if v > 0 then
|
||
|
|
local n = GetSpellInfo(v)
|
||
|
|
if not n then core:Error(("Invalid spell ID %d in the optionHeaders for module %s."):format(v, module.name)) end
|
||
|
|
module.optionHeaders[k] = n or v
|
||
|
|
else
|
||
|
|
local tbl = C_EncounterJournal_GetSectionInfo(-v)
|
||
|
|
if not tbl then core:Error(("Invalid journal ID (-)%d in the optionHeaders for module %s."):format(-v, module.name)) end
|
||
|
|
module.optionHeaders[k] = tbl and tbl.title or v
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if module.toggleOptions then
|
||
|
|
module.toggleDefaults = {}
|
||
|
|
for k, v in next, module.toggleOptions do
|
||
|
|
local bitflags = 0
|
||
|
|
local disabled = false
|
||
|
|
local t = type(v)
|
||
|
|
if t == "table" then
|
||
|
|
for i = 2, #v do
|
||
|
|
local flagName = v[i]
|
||
|
|
if C[flagName] then
|
||
|
|
bitflags = bitflags + C[flagName]
|
||
|
|
elseif flagName == "OFF" then
|
||
|
|
disabled = true
|
||
|
|
break
|
||
|
|
else
|
||
|
|
error(("%q tried to register '%q' as a bitflag for toggleoption '%q'"):format(module.moduleName, flagName, v[1]))
|
||
|
|
end
|
||
|
|
end
|
||
|
|
v = v[1]
|
||
|
|
t = type(v)
|
||
|
|
end
|
||
|
|
-- mix in default toggles for keys we know
|
||
|
|
-- this allows for mod.toggleOptions = {{1234, "bar", "message"}}
|
||
|
|
-- while option keys don't usually specify common features such as bar or message
|
||
|
|
for _, b in next, C do
|
||
|
|
if bit.band(defaultToggles[v], b) == b and bit.band(bitflags, b) ~= b then
|
||
|
|
bitflags = bitflags + b
|
||
|
|
end
|
||
|
|
end
|
||
|
|
if disabled then
|
||
|
|
if not module.toggleDisabled then
|
||
|
|
module.toggleDisabled = {}
|
||
|
|
end
|
||
|
|
module.toggleDisabled[v] = bitflags
|
||
|
|
bitflags = 0
|
||
|
|
end
|
||
|
|
if t == "string" then
|
||
|
|
local custom = v:match("^custom_(o[nf]f?)_.*")
|
||
|
|
if custom then
|
||
|
|
module.toggleDefaults[v] = custom == "on" and true or false
|
||
|
|
else
|
||
|
|
module.toggleDefaults[v] = bitflags
|
||
|
|
end
|
||
|
|
elseif t == "number" then
|
||
|
|
if v > 0 then
|
||
|
|
local n = GetSpellInfo(v)
|
||
|
|
if not n then core:Error(("Invalid spell ID %d in the toggleOptions for module %s."):format(v, module.name)) end
|
||
|
|
module.toggleDefaults[v] = bitflags
|
||
|
|
else
|
||
|
|
local tbl = C_EncounterJournal_GetSectionInfo(-v)
|
||
|
|
if not tbl then core:Error(("Invalid journal ID (-)%d in the toggleOptions for module %s."):format(-v, module.name)) end
|
||
|
|
module.toggleDefaults[v] = bitflags
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
module.db = core.db:RegisterNamespace(module.name, { profile = module.toggleDefaults })
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function moduleOptions(self)
|
||
|
|
if self.GetOptions then
|
||
|
|
local toggles, headers, altNames = self:GetOptions(CL)
|
||
|
|
if toggles then self.toggleOptions = toggles end
|
||
|
|
if headers then self.optionHeaders = headers end
|
||
|
|
if altNames then self.altNames = altNames end
|
||
|
|
self.GetOptions = nil
|
||
|
|
end
|
||
|
|
setupOptions(self)
|
||
|
|
self.SetupOptions = nil
|
||
|
|
end
|
||
|
|
|
||
|
|
function core:RegisterBossModule(module)
|
||
|
|
module.SetupOptions = moduleOptions
|
||
|
|
|
||
|
|
-- Call the module's OnRegister (which is our OnInitialize replacement)
|
||
|
|
if type(module.OnRegister) == "function" then
|
||
|
|
module:OnRegister()
|
||
|
|
module.OnRegister = nil
|
||
|
|
end
|
||
|
|
|
||
|
|
core:SendMessage("BigWigs_BossModuleRegistered", module.moduleName, module)
|
||
|
|
|
||
|
|
local id = module.instanceId or -(module.mapId)
|
||
|
|
if not enablezones[id] then
|
||
|
|
enablezones[id] = true
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function profileUpdate()
|
||
|
|
core:SendMessage("BigWigs_ProfileUpdate")
|
||
|
|
end
|
||
|
|
|
||
|
|
function core:RegisterPlugin(module)
|
||
|
|
if type(module.defaultDB) == "table" then
|
||
|
|
module.db = core.db:RegisterNamespace(module.name, { profile = module.defaultDB } )
|
||
|
|
module.db.RegisterCallback(module, "OnProfileChanged", profileUpdate)
|
||
|
|
module.db.RegisterCallback(module, "OnProfileCopied", profileUpdate)
|
||
|
|
module.db.RegisterCallback(module, "OnProfileReset", profileUpdate)
|
||
|
|
end
|
||
|
|
|
||
|
|
setupOptions(module)
|
||
|
|
|
||
|
|
-- Call the module's OnRegister (which is our OnInitialize replacement)
|
||
|
|
if type(module.OnRegister) == "function" then
|
||
|
|
module:OnRegister()
|
||
|
|
module.OnRegister = nil
|
||
|
|
end
|
||
|
|
core:SendMessage("BigWigs_PluginRegistered", module.moduleName, module)
|
||
|
|
|
||
|
|
if coreEnabled then
|
||
|
|
module:Enable() -- Support LoD plugins that load after we're enabled (e.g. zone based)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function core:AddColors(moduleName, options)
|
||
|
|
local module = bosses[moduleName]
|
||
|
|
if not module then
|
||
|
|
-- core:Error(("AddColors: Invalid module %q."):format(moduleName))
|
||
|
|
return
|
||
|
|
end
|
||
|
|
module.colorOptions = options
|
||
|
|
end
|
||
|
|
|
||
|
|
function core:AddSounds(moduleName, options)
|
||
|
|
local module = bosses[moduleName]
|
||
|
|
if not module then
|
||
|
|
-- core:Error(("AddSounds: Invalid module %q."):format(moduleName))
|
||
|
|
return
|
||
|
|
end
|
||
|
|
module.soundOptions = options
|
||
|
|
end
|
||
|
|
|
||
|
|
-------------------------------------------------------------------------------
|
||
|
|
-- Global
|
||
|
|
--
|
||
|
|
|
||
|
|
BigWigs = setmetatable({}, { __index = core, __newindex = function() end, __metatable = false })
|