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.

643 lines
16 KiB

local E, L = select(2, ...):unpack()
local GetNumSpecializationsForClassID = GetNumSpecializationsForClassID
local GetSpecializationInfoForClassID = GetSpecializationInfoForClassID
local GetSpecializationInfoByID = GetSpecializationInfoByID
if E.preMoP then
GetNumSpecializationsForClassID = function() return 0 end
GetSpecializationInfoForClassID = E.Noop
GetSpecializationInfoByID = E.Noop
end
local defaultBackup = {}
local classValues = {}
local specIDs = {}
for i = 1, MAX_CLASSES do
local class = CLASS_SORT_ORDER[i]
classValues[class] = format("|T%s:18|t %s", "Interface\\Icons\\ClassIcon_" .. class, LOCALIZED_CLASS_NAMES_MALE[class])
for j = 1, GetNumSpecializationsForClassID(i) do
local id = GetSpecializationInfoForClassID(i, j)
specIDs[#specIDs + 1] = id
end
end
classValues["TRINKET"] = format("|T%s:16|t %s", E.TEXTURES.TRINKET, L["Trinket, Main Hand"])
local function GetClassIndexBySpellID(id)
for class, v in pairs(E.spell_db) do
for i = 1, #v do
local t = v[i]
if t.spellID == id then
return class, i
end
end
end
end
function E:UpdateSpell(id, isInit, oldClass, oldType)
local class, i = GetClassIndexBySpellID(id)
local v = OmniCDDB.cooldowns[id]
local vclass, vtype, force
if v then
vclass, vtype = v.class, v.type
if class ~= vclass then
if class then
tremove(self.spell_db[class], i)
else
if self.spellNameToID then
local name = GetSpellInfo(id)
if name and not self.spellNameToID[name] then
self.spellNameToID[name] = id
else
return
end
end
force = true
end
self.spell_db[vclass][#self.spell_db[vclass] + 1] = v
elseif not v.custom and not defaultBackup[id] then
defaultBackup[id] = self:DeepCopy(self.spell_db[class][i])
self.spell_db[class][i] = v
if self.L_HIGHLIGHTS[vtype] then
self.Cooldowns:RegisterRemoveHighlightByCLEU(v.buff or id)
end
return
else
self.spell_db[class][i] = v
end
if self.L_HIGHLIGHTS[vtype] then
self.Cooldowns:RegisterRemoveHighlightByCLEU(v.buff or id)
end
else
v = defaultBackup[id]
if v then
vclass, vtype = v.class, v.type
self.spell_db[class][i] = self:DeepCopy(v)
else
tremove(self.spell_db[class], i)
end
end
if not isInit then
for moduleName in pairs(self.moduleOptions) do
local module = self[moduleName]
local func = module.UpdateSpellsOption
if func then
func(module, id, oldClass, oldType, vclass, vtype, force)
end
end
end
end
local GetSpellID = function(info, n)
n = n or 1
local id = info[#info - n]
return tonumber(id), id
end
local function GetSpecID(info, n)
n = n or 1
local id = info[#info - n]:gsub("spec", "")
return tonumber(id)
end
local isOthersCategory = function(info)
local id = GetSpellID(info)
return E.OTHER_SORT_ORDER[OmniCDDB.cooldowns[id].class]
end
local isClassCategory = function(info)
local id = GetSpellID(info)
return OmniCDDB.cooldowns[id].class ~= "TRINKET"
end
local getGlobalDurationCharge = function(info)
local option = info[#info]
local id = GetSpellID(info)
return OmniCDDB.cooldowns[id][option].default
end
local setGlobalDurationCharge = function(info, value)
local option = info[#info]
local id = GetSpellID(info)
OmniCDDB.cooldowns[id][option].default = value
E:UpdateSpell(id)
end
local getItem = function(info)
local option = info[#info]
local id = GetSpellID(info)
local v = OmniCDDB.cooldowns[id][option]
if v then
return tostring(v)
end
end
local setItem = function(info, v)
local option = info[#info]
local id = GetSpellID(info)
if v == "" then
if option == "icon" then
OmniCDDB.cooldowns[id][option] = OmniCDDB.cooldowns[id].item and GetItemIcon(OmniCDDB.cooldowns[id].item) or select(2, GetSpellTexture(E.iconFix[id] or id))
else
OmniCDDB.cooldowns[id][option] = nil
end
else
if strmatch(v, "[^%d]+") or strlen(v) > 9 or not C_Item.DoesItemExistByID(v) then
E.write(L["Invalid ID"], v)
return
end
OmniCDDB.cooldowns[id][option] = tonumber(v)
end
E:UpdateSpell(id)
end
local function CreateClassSpecTable(id)
local t = {}
for i = 1, #specIDs do
local class = select(6, GetSpecializationInfoByID(specIDs[i]))
if OmniCDDB.cooldowns[id].class == class then
tinsert(t, specIDs[i])
end
end
return #t > 0 and t or nil
end
local customSpellInfo = {
spellName = {
name = function(info)
local id = GetSpellID(info)
return format("|cffffd200 %s:|r %s |cff20ff20%s", L["Spell ID"], id, defaultBackup[id] and "" or L["Custom"])
end,
order = 0,
type = "description",
},
delete = {
name = DELETE,
desc = L["Default spells are reverted back to original values and removed from the list only"],
order = 1,
type = "execute",
func = function(info)
local id, sId = GetSpellID(info)
local oldClass, oldType = OmniCDDB.cooldowns[id].class, OmniCDDB.cooldowns[id].type
if not defaultBackup[id] then
for moduleName in pairs(E.moduleOptions) do
local t = E[moduleName].spell_enabled
if t then
t[id] = nil
end
end
for key in pairs(E.L_CFG_ZONE) do
E.profile.Party[key].spells[sId] = nil
E.profile.Party[key].raidCDS[sId] = nil
end
end
OmniCDDB.cooldowns[id] = nil
E.options.args.SpellEditor.args.editor.args[sId] = nil
E:UpdateSpell(id, nil, oldClass, oldType)
end,
},
hd1 = {
name = "", order = 2, type = "header",
},
class = {
disabled = function(info)
local id = GetSpellID(info)
return defaultBackup[id]
end,
name = CLASS,
order = 3,
type = "select",
values = classValues,
set = function(info, value)
local id = GetSpellID(info)
local oldClass, oldType = OmniCDDB.cooldowns[id].class, OmniCDDB.cooldowns[id].type
OmniCDDB.cooldowns[id].duration = { default = OmniCDDB.cooldowns[id].duration.default }
OmniCDDB.cooldowns[id].charges = { default = OmniCDDB.cooldowns[id].charges.default }
OmniCDDB.cooldowns[id].class = value
OmniCDDB.cooldowns[id].spec = CreateClassSpecTable(id)
E:UpdateSpell(id, nil, oldClass, oldType)
end,
},
type = {
name = TYPE,
desc = L["Set the spell type for sorting"],
order = 4,
type = "select",
values = E.L_PRIORITY,
set = function(info, value)
local id = GetSpellID(info)
local oldClass, oldType = OmniCDDB.cooldowns[id].class, OmniCDDB.cooldowns[id].type
OmniCDDB.cooldowns[id][ info[#info] ] = value
E:UpdateSpell(id, nil, oldClass, oldType)
end,
},
duration = {
name = L["Cooldown"],
desc = E.STR.MAX_RANGE_3600,
order = 5,
type = "range",
min = 1, max = 3600, softMax = 300, step = 1,
get = getGlobalDurationCharge,
set = setGlobalDurationCharge,
},
charges = {
name = function(info)
local id = GetSpellID(info)
local value = OmniCDDB.cooldowns[id].charges.default
return format(SPELL_MAX_CHARGES, value)
end,
order = 6,
type = "range",
min = 1, max = 10, step = 1,
get = getGlobalDurationCharge,
set = setGlobalDurationCharge,
},
lb1 = {
name = "\n", order = 7, type = "description",
},
talentId = {
hidden = isOthersCategory,
name = L["Talent ID"],
desc = format("%s\n\n%s", L["Enter talent ID if the spell is a talent ability in any of the class specializations. This ensures proper spell detection."],
L["Use a semi-colon(;) to seperate multiple IDs."]),
order = 10,
type = "input",
get = function(info)
local id = GetSpellID(info)
local spec = OmniCDDB.cooldowns[id].spec or CreateClassSpecTable(id)
if spec then
return table.concat(spec, ";")
end
end,
set = function(info, value)
local id = GetSpellID(info)
local t = OmniCDDB.cooldowns[id].spec
if t then
wipe(t)
else
t = {}
OmniCDDB.cooldowns[id].spec = t
end
value = gsub(value, ("[^%d;]"), "")
local s, e, v = 1
while true do
s, e, v = strfind(value, "([^;]+)", s)
if s == nil then break end
s = e + 1
if strlen(v) < 9 and (C_Spell.DoesSpellExist(v) or GetSpecializationInfoByID(v)) then
tinsert(t, tonumber(v))
end
end
E:UpdateSpell(id)
end,
},
item = {
hidden = isClassCategory,
name = format("%s: %s", L["Trinket, Main Hand"], L["Item ID (Optional)"]),
desc = L["Enter item ID to enable spell when the item is equipped only"],
order = 11,
type = "input",
get = getItem,
set = setItem,
},
item2 = {
disabled = function(info)
local id = GetSpellID(info)
return OmniCDDB.cooldowns[id].item == nil
end,
hidden = isClassCategory,
name = L["Item ID (Optional)"] .. " 2",
order = 12,
type = "input",
get = getItem,
set = setItem,
},
--[[
tt = {
hidden = isClassCategory,
name = "\n" .. L["Toggle \"Show Spell ID in Tooltips\" to retrieve item IDs"],
order = 13,
type = "description",
},
]]
lb3 = {
name = "", order = 14, type = "description",
},
buff = {
hidden = function(info)
local id = GetSpellID(info)
return not E.L_HIGHLIGHTS[OmniCDDB.cooldowns[id].type]
end,
name = L["Buff ID (Optional)"],
desc = format("%s\n\n|cffff2020%s", L["Enter buff ID if it differs from spell ID for Highlights to work"], L["0: Disable option"]),
order = 15,
type = "input",
get = function(info)
local option = info[#info]
local id = GetSpellID(info)
local v = OmniCDDB.cooldowns[id][option]
return v and tostring(v) or tostring(id)
end,
set = function(info, v)
local option = info[#info]
local id = GetSpellID(info)
if v == "" then
OmniCDDB.cooldowns[id][option] = id
else
if strmatch(v, "[^%d]+") or strlen(v) > 9 or not C_Spell.DoesSpellExist(v) then
E.write(L["Invalid ID"], v)
return
end
OmniCDDB.cooldowns[id][option] = tonumber(v)
end
E:UpdateSpell(id)
end,
},
lb4 = {
name = "\n", order = 16, type = "description",
},
icon = {
hidden = isClassCategory,
name = L["Icon ID (Optional)"],
order = 17,
type = "input",
get = getItem,
set = setItem,
},
}
if not E.preMoP then
local customSpellSpecInfo = {
enabled = {
name = ENABLE,
desc = L["Enable if the spell is a base ability for this specialization"],
order = 1,
type = "toggle",
get = function(info)
local id = GetSpellID(info, 2)
local specID = GetSpecID(info)
local spec = OmniCDDB.cooldowns[id].spec or CreateClassSpecTable(id)
for i = 1, #spec do
if spec[i] == specID then return true end
end
end,
set = function(info, value)
local id = GetSpellID(info, 2)
local specID = GetSpecID(info)
OmniCDDB.cooldowns[id].spec = OmniCDDB.cooldowns[id].spec or CreateClassSpecTable(id)
if value then
tinsert(OmniCDDB.cooldowns[id].spec, specID)
else
for i = #OmniCDDB.cooldowns[id].spec, 1, -1 do
if OmniCDDB.cooldowns[id].spec[i] == specID then
tremove(OmniCDDB.cooldowns[id].spec, i)
break
end
end
end
E:UpdateSpell(id)
end,
},
disable = {
name = L["Force Disable"],
desc = L["Only for talent abilities.\nCurrent ability for this specialization will no longer be tracked while you are in the selected zone(s)"],
order = 2,
type = "multiselect",
dialogControl = "Dropdown-OmniCD",
values = E.L_ALL_ZONE,
get = function(info, k)
local id = GetSpellID(info, 2)
local specID = GetSpecID(info)
local option = OmniCDDB.cooldowns[id].disabledSpec
return option and option[specID] and option[specID][k]
end,
set = function(info, k, value)
local id = GetSpellID(info, 2)
local specID = GetSpecID(info)
OmniCDDB.cooldowns[id].disabledSpec = OmniCDDB.cooldowns[id].disabledSpec or {}
OmniCDDB.cooldowns[id].disabledSpec[specID] = OmniCDDB.cooldowns[id].disabledSpec[specID] or {}
OmniCDDB.cooldowns[id].disabledSpec[specID][k] = value or nil
if next(OmniCDDB.cooldowns[id].disabledSpec[specID]) == nil then
OmniCDDB.cooldowns[id].disabledSpec[specID] = nil
end
if next(OmniCDDB.cooldowns[id].disabledSpec) == nil then
OmniCDDB.cooldowns[id].disabledSpec = nil
end
E:UpdateSpell(id)
end,
},
hd1 = {
name = "", order = 3, type = "header",
},
duration = {
name = L["Cooldown"],
desc = L["Set to override the global cooldown setting for this specialization"],
order = 4,
type = "range",
min = 1, max = 999, softMax = 300, step = 1,
},
charges = {
name = L["Charges"],
order = 5,
type = "range",
min = 1, max = 10, step = 1,
},
}
local customSpellSpecGroup = {
hidden = function(info)
local specID = GetSpecID(info, 0)
if not specID then return end
local id = GetSpellID(info)
local class = OmniCDDB.cooldowns[id].class
if class == "TRINKET" then return true end
if class ~= select(6, GetSpecializationInfoByID(specID)) then return true end
end,
icon = function(info)
local specID = GetSpecID(info, 0)
return select(4,GetSpecializationInfoByID(specID))
end,
iconCoords = E.BORDERLESS_TCOORDS,
name = function(info)
local specID = GetSpecID(info, 0)
return select(2,GetSpecializationInfoByID(specID))
end,
type = "group",
get = function(info)
local option = info[#info]
local id = GetSpellID(info, 2)
local specID = GetSpecID(info)
return OmniCDDB.cooldowns[id][option][specID] or OmniCDDB.cooldowns[id][option].default
end,
set = function(info, value)
local option = info[#info]
local id = GetSpellID(info, 2)
local specID = GetSpecID(info)
if value == OmniCDDB.cooldowns[id][option].default then
value = nil
end
OmniCDDB.cooldowns[id][option][specID] = value
E:UpdateSpell(id)
end,
args = customSpellSpecInfo
}
for i = 1, #specIDs do
local specID = specIDs[i]
customSpellInfo["spec" .. specID] = customSpellSpecGroup
end
end
local customSpellGroup = {
icon = function(info)
local id = GetSpellID(info,0)
return select(2,GetSpellTexture(id))
end,
iconCoords = E.BORDERLESS_TCOORDS,
name = function(info)
local id = GetSpellID(info,0)
return GetSpellInfo(id)
end,
type = "group",
args = customSpellInfo,
}
E.EditSpell = function(_, value)
if strlen(value) > 9 then
return E.write(L["Invalid ID"], value)
end
local id = tonumber(value)
local name = id and GetSpellInfo(id)
if not name then
return E.write(L["Invalid ID"], value)
end
if OmniCDDB.cooldowns[id] then
return E.Libs.ACD:SelectGroup(E.AddOn, "SpellEditor", "editor", value)
end
local class, i = GetClassIndexBySpellID(id)
local _, icon = GetSpellTexture(id)
if class and i then
OmniCDDB.cooldowns[id] = E.spell_db[class][i]
local duration = OmniCDDB.cooldowns[id].duration
if type(duration) == "number" then
OmniCDDB.cooldowns[id].duration = { default = duration }
end
local charges = OmniCDDB.cooldowns[id].charges
if type(charges) ~= "table" then
OmniCDDB.cooldowns[id].charges = { default = charges or 1 }
end
local spec = OmniCDDB.cooldowns[id].spec or CreateClassSpecTable(id)
spec = spec == true and id or (type(spec) == "number" and spec)
if spec then
OmniCDDB.cooldowns[id].spec = { spec }
end
else
OmniCDDB.cooldowns[id] = {
["spellID"] = id,
["duration"] = {default = 30},
["type"] = "trinket",
["charges"] = {default = 1},
["icon"] = icon, ["class"] = "TRINKET", ["custom"] = true,
["buff"] = id,
["name"] = name,
}
end
E.options.args.SpellEditor.args.editor.args[value] = customSpellGroup
E:UpdateSpell(id)
E.Libs.ACD:SelectGroup(E.AddOn, "SpellEditor", "editor", value)
end
local SpellEditor = {
name = L["Spell Editor"],
order = 900,
type = "group",
childGroups = "tab",
get = function(info)
local option = info[#info]
local id = GetSpellID(info)
if id then
return OmniCDDB.cooldowns[id][option]
end
end,
set = function(info, value)
local option = info[#info]
local id = GetSpellID(info)
OmniCDDB.cooldowns[id][option] = value
E:UpdateSpell(id)
end,
args = {
editor = {
name = L["Spell Editor"],
order = 10,
type = "group",
args ={
spellId = {
order = 0,
name = L["Spell ID"],
desc = L["Enter Spell ID to Add/Edit"],
type = "input",
set = E.EditSpell,
},
}
},
}
}
function E:AddSpellPickers()
for moduleName in pairs(self.moduleOptions) do
local func = self[moduleName].AddSpellPicker
if func then
func(self[moduleName])
end
end
end
function E:AddSpellEditor()
for id in pairs(OmniCDDB.cooldowns) do
if not C_Spell.DoesSpellExist(id) then
OmniCDDB.cooldowns[id] = nil
else
id = tostring(id)
SpellEditor.args.editor.args[id] = customSpellGroup
end
end
self.options.args["SpellEditor"] = SpellEditor
self:AddSpellPickers()
end
function E:UpdateSpellList(isInit)
for id in pairs(OmniCDDB.cooldowns) do
self:UpdateSpell(id, isInit)
end
end