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.
232 lines
6.9 KiB
232 lines
6.9 KiB
|
|
local LS = LibStub:NewLibrary("LibSpecialization", 2)
|
|
if not LS then return end -- No upgrade needed
|
|
|
|
-- Throttle times for separate channels
|
|
LS.throttleTable = LS.throttleTable or {
|
|
["RAID"] = 0,
|
|
["PARTY"] = 0,
|
|
["INSTANCE_CHAT"] = 0,
|
|
}
|
|
LS.throttleSendTable = LS.throttleSendTable or {
|
|
["RAID"] = 0,
|
|
["PARTY"] = 0,
|
|
["INSTANCE_CHAT"] = 0,
|
|
}
|
|
-- Positions of roles
|
|
LS.positionTable = LS.positionTable or {
|
|
-- Death Knight
|
|
[250] = "MELEE", -- Blood (Tank)
|
|
[251] = "MELEE", -- Frost (DPS)
|
|
[252] = "MELEE", -- Unholy (DPS)
|
|
-- Demon Hunter
|
|
[577] = "MELEE", -- Havoc (DPS)
|
|
[581] = "MELEE", -- Vengeance (Tank)
|
|
-- Druid
|
|
[102] = "RANGED", -- Balance (DPS Owl)
|
|
[103] = "MELEE", -- Feral (DPS Cat)
|
|
[104] = "MELEE", -- Guardian (Tank Bear)
|
|
[105] = "RANGED", -- Restoration (Heal)
|
|
-- Hunter
|
|
[253] = "RANGED", -- Beast Mastery
|
|
[254] = "RANGED", -- Marksmanship
|
|
[255] = "MELEE", -- Survival
|
|
-- Mage
|
|
[62] = "RANGED", -- Arcane
|
|
[63] = "RANGED", -- Fire
|
|
[64] = "RANGED", -- Frost
|
|
-- Monk
|
|
[268] = "MELEE", -- Brewmaster (Tank)
|
|
[269] = "MELEE", -- Windwalker (DPS)
|
|
[270] = "MELEE", -- Mistweaver (Heal)
|
|
-- Paladin
|
|
[65] = "MELEE", -- Holy (Heal)
|
|
[66] = "MELEE", -- Protection (Tank)
|
|
[70] = "MELEE", -- Retribution (DPS)
|
|
-- Priest
|
|
[256] = "RANGED", -- Discipline (Heal)
|
|
[257] = "RANGED", -- Holy (Heal)
|
|
[258] = "RANGED", -- Shadow (DPS)
|
|
-- Rogue
|
|
[259] = "MELEE", -- Assassination
|
|
[260] = "MELEE", -- Outlaw
|
|
[261] = "MELEE", -- Subtlety
|
|
-- Shaman
|
|
[262] = "RANGED", -- Elemental (DPS)
|
|
[263] = "MELEE", -- Enhancement (DPS)
|
|
[264] = "RANGED", -- Restoration (Heal)
|
|
-- Warlock
|
|
[265] = "RANGED", -- Affliction
|
|
[266] = "RANGED", -- Demonology
|
|
[267] = "RANGED", -- Destruction
|
|
-- Warrior
|
|
[71] = "MELEE", -- Arms (DPS)
|
|
[72] = "MELEE", -- Fury (DPS)
|
|
[73] = "MELEE", -- Protection (Tank)
|
|
}
|
|
-- Player roles
|
|
LS.roleTable = LS.roleTable or {
|
|
-- Death Knight
|
|
[250] = "TANK", -- Blood (Tank)
|
|
[251] = "DAMAGER", -- Frost (DPS)
|
|
[252] = "DAMAGER", -- Unholy (DPS)
|
|
-- Demon Hunter
|
|
[577] = "DAMAGER", -- Havoc (DPS)
|
|
[581] = "TANK", -- Vengeance (Tank)
|
|
-- Druid
|
|
[102] = "DAMAGER", -- Balance (DPS Owl)
|
|
[103] = "DAMAGER", -- Feral (DPS Cat)
|
|
[104] = "TANK", -- Guardian (Tank Bear)
|
|
[105] = "HEALER", -- Restoration (Heal)
|
|
-- Hunter
|
|
[253] = "DAMAGER", -- Beast Mastery
|
|
[254] = "DAMAGER", -- Marksmanship
|
|
[255] = "DAMAGER", -- Survival
|
|
-- Mage
|
|
[62] = "DAMAGER", -- Arcane
|
|
[63] = "DAMAGER", -- Fire
|
|
[64] = "DAMAGER", -- Frost
|
|
-- Monk
|
|
[268] = "TANK", -- Brewmaster (Tank)
|
|
[269] = "DAMAGER", -- Windwalker (DPS)
|
|
[270] = "HEALER", -- Mistweaver (Heal)
|
|
-- Paladin
|
|
[65] = "HEALER", -- Holy (Heal)
|
|
[66] = "TANK", -- Protection (Tank)
|
|
[70] = "DAMAGER", -- Retribution (DPS)
|
|
-- Priest
|
|
[256] = "HEALER", -- Discipline (Heal)
|
|
[257] = "HEALER", -- Holy (Heal)
|
|
[258] = "DAMAGER", -- Shadow (DPS)
|
|
-- Rogue
|
|
[259] = "DAMAGER", -- Assassination
|
|
[260] = "DAMAGER", -- Outlaw
|
|
[261] = "DAMAGER", -- Subtlety
|
|
-- Shaman
|
|
[262] = "DAMAGER", -- Elemental (DPS)
|
|
[263] = "DAMAGER", -- Enhancement (DPS)
|
|
[264] = "HEALER", -- Restoration (Heal)
|
|
-- Warlock
|
|
[265] = "DAMAGER", -- Affliction
|
|
[266] = "DAMAGER", -- Demonology
|
|
[267] = "DAMAGER", -- Destruction
|
|
-- Warrior
|
|
[71] = "DAMAGER", -- Arms (DPS)
|
|
[72] = "DAMAGER", -- Fury (DPS)
|
|
[73] = "TANK", -- Protection (Tank)
|
|
}
|
|
LS.callbackMap = LS.callbackMap or {}
|
|
LS.frame = LS.frame or CreateFrame("Frame")
|
|
|
|
local throttleTable = LS.throttleTable
|
|
local throttleSendTable = LS.throttleSendTable
|
|
local callbackMap = LS.callbackMap
|
|
local positionTable = LS.positionTable
|
|
local roleTable = LS.roleTable
|
|
local frame = LS.frame
|
|
|
|
local next, type, error, tonumber, format = next, type, error, tonumber, string.format
|
|
local Ambiguate, GetTime, IsInGroup, IsInRaid = Ambiguate, GetTime, IsInGroup, IsInRaid
|
|
local GetSpecialization, GetSpecializationInfo = GetSpecialization, GetSpecializationInfo
|
|
local SendAddonMessage = C_ChatInfo.SendAddonMessage
|
|
local pName = UnitName("player")
|
|
|
|
if not C_ChatInfo.RegisterAddonMessagePrefix("LibSpec") then
|
|
error("LibSpecialization: Failed to register the addon prefix.")
|
|
end
|
|
frame:SetScript("OnEvent", function(_, _, prefix, msg, channel, sender)
|
|
if prefix == "LibSpec" and throttleTable[channel] then
|
|
if msg == "R" then
|
|
local t = GetTime()
|
|
if t - throttleTable[channel] > 4 then
|
|
throttleTable[channel] = t
|
|
local spec = GetSpecialization()
|
|
if type(spec) == "number" and spec > 0 then
|
|
local id = GetSpecializationInfo(spec)
|
|
|
|
if id then
|
|
if positionTable[id] then
|
|
SendAddonMessage("LibSpec", format("%d", id), channel)
|
|
else
|
|
error(format("LibSpecialization: Unknown ID %q", id))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return
|
|
end
|
|
|
|
local specId = tonumber(msg)
|
|
local role, position = roleTable[specId], positionTable[specId]
|
|
if role and position then
|
|
for _,func in next, callbackMap do
|
|
func(specId, role, position, Ambiguate(sender, "none"), channel)
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
frame:RegisterEvent("CHAT_MSG_ADDON")
|
|
|
|
-- Allow requesting only your specialization
|
|
function LS:MySpecialization()
|
|
local spec = GetSpecialization()
|
|
if type(spec) == "number" and spec > 0 then
|
|
local specId, _, _, _, role = GetSpecializationInfo(spec)
|
|
|
|
if specId and role then
|
|
local position = positionTable[specId]
|
|
if position then
|
|
return specId, role, position
|
|
else
|
|
error(format("LibSpecialization: Unknown specId %q", specId))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- For automatic group handling, don't pass a channel. The order is INSTANCE_CHAT > RAID > GROUP.
|
|
function LS:RequestSpecialization(channel)
|
|
if channel and not throttleSendTable[channel] then
|
|
error("LibSpecialization: Incorrect channel type for :RequestSpecialization.")
|
|
else
|
|
if not channel and IsInGroup() then
|
|
channel = IsInGroup(2) and "INSTANCE_CHAT" or IsInRaid() and "RAID" or "PARTY"
|
|
end
|
|
|
|
local specId, role, position = LS:MySpecialization()
|
|
for _,func in next, callbackMap do
|
|
func(specId, role, position, pName, channel) -- This allows us to show our own spec info when not grouped
|
|
end
|
|
|
|
if channel then
|
|
local t = GetTime()
|
|
if t - throttleSendTable[channel] > 4 then
|
|
throttleSendTable[channel] = t
|
|
SendAddonMessage("LibSpec", "R", channel)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function LS:Register(addon, func)
|
|
if not addon or addon == LS then
|
|
error("LibSpecialization: You must pass your own addon name or object to :Register.")
|
|
end
|
|
|
|
local t = type(func)
|
|
if t == "string" then
|
|
callbackMap[addon] = function(...) addon[func](addon, ...) end
|
|
elseif t == "function" then
|
|
callbackMap[addon] = func
|
|
else
|
|
error("LibSpecialization: Incorrect function type for :Register.")
|
|
end
|
|
end
|
|
|
|
function LS:Unregister(addon)
|
|
if not addon or addon == LS then
|
|
error("LibSpecialization: You must pass your own addon name or object to :Unregister.")
|
|
end
|
|
callbackMap[addon] = nil
|
|
end
|
|
|
|
|