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.

213 lines
7.4 KiB

local _, T = ...
if select(4,GetBuildInfo()) < 8e4 then return end
local EV, L = T.Evie, T.L
local AB = assert(T.ActionBook:compatible(2,23), "A compatible version of ActionBook is required.")
local RW = assert(AB:compatible("Rewire", 1,7), "A compatible version of Rewire is required")
local CHARNAME = UnitName("player") .. "@" .. GetRealmName()
do -- RW/opiespecset
local f = CreateFrame("Frame", nil, nil, "SecureFrameTemplate")
f:SetAttribute("RunSlashCmd", [[self:CallMethod("SwitchSpec", ...)]])
local esSpec, esSet, esDeadline
function EV:PLAYER_SPECIALIZATION_CHANGED(unit)
if esDeadline and unit == "player" and GetSpecialization() == esSpec and not InCombatLockdown() and esDeadline > GetTime() then
local sid = C_EquipmentSet.GetEquipmentSetID(esSet)
esDeadline, esSpec, esSet = sid and C_EquipmentSet.UseEquipmentSet(sid) and nil
end
end
function f:SwitchSpec(_cmd, args)
local sid, sname = args:match("(%d+) {(.*)}")
sid = tonumber(sid)
if GetSpecialization() ~= sid and not InCombatLockdown() then
SetSpecialization(sid)
if sname ~= "" then
esSpec, esSet, esDeadline = sid, sname, GetTime()+9
end
end
end
RW:RegisterCommand("/opiespecset", false, false, f)
end
do -- AB/specset
local slot, tspec, tset = {}, {}, {}
local function SetSpecializationTooltip(self, id, set)
local _, name, desc = GetSpecializationInfo(id)
if name then
self:SetText(name, 1,1,1)
self:AddLine(desc, nil, nil, nil, 1)
if (set or "") ~= "" then
local _, ico, _, _isCur, total, eq, bags, miss = C_EquipmentSet.GetEquipmentSetInfo(C_EquipmentSet.GetEquipmentSetID(set) or -1)
if ico then
local eql
if total == eq then
eql = GREEN_FONT_COLOR_CODE .. ITEMS_EQUIPPED:format(eq)
elseif miss > 0 then
eql = RED_FONT_COLOR_CODE .. ITEMS_NOT_IN_INVENTORY:format(miss)
else
eql = NORMAL_FONT_COLOR_CODE .. ITEMS_IN_INVENTORY:format(bags)
end
self:AddLine(" ")
self:AddLine("|T" .. ico .. ":0|t " .. set .. ": " .. eql, 1,1,1)
end
end
else
self:Hide()
end
end
local function SetSpecSetTooltip(self, tok)
local spec, set = tspec[tok], tset[tok]
if spec == nil then
spec, set = 0+tok:sub(1,1), tok:sub(3)
tspec[tok], tset[tok] = spec, set
end
SetSpecializationTooltip(self, spec, set)
end
local function hintSpecSet(tok)
local cs, spec, set = GetSpecialization(), tspec[tok], tset[tok]
if spec == nil then
spec, set = 0+tok:sub(1,1), tok:sub(3)
tspec[tok], tset[tok] = spec, set
end
local _, name, _, ico = GetSpecializationInfo(spec)
local state = (cs == spec and 1 or 0)
return (HasFullControl() and not InCombatLockdown()), state, ico, name, 0, 0, 0, SetSpecSetTooltip, tok
end
local function createSpecSet(idx, sets)
local _, specName = GetSpecializationInfo(idx)
local setName = sets and sets[CHARNAME]
setName = setName ~= false and (setName or specName) or ""
local tk = idx .. "#" .. setName
local ret = slot[tk]
if specName and UnitLevel("player") >= 10 and GetNumSpecializations() >= idx and not ret then
ret = AB:GetActionSlot("macrotext", ("/cancelform [nospec:%d,form:travel,flyable,noflying,nocombat]\n/opiespecset %d {%s}\n%s [spec:%d] %s"):format(idx, idx, setName, SLASH_EQUIP_SET1, setName ~= "" and idx or 5, setName))
ret = AB:CreateActionSlot(hintSpecSet, tk, "clone", ret)
slot[tk] = ret
end
return ret
end
local function describeSpecSet(idx, _sets)
local _, name, _, ico = GetSpecializationInfo(idx)
return SPECIALIZATION, name or idx, ico or "Interface/Icons/Temp", nil, SetSpecializationTooltip, idx
end
AB:RegisterActionType("specset", createSpecSet, describeSpecSet, 2)
AB:AugmentCategory("Miscellaneous", function(_, add)
for i=1,GetNumSpecializations() do
add("specset", i)
end
end)
end
do -- EditorUI
local bg = CreateFrame("Frame")
local drop = CreateFrame("Frame", "OPie_SSDrop", bg, "UIDropDownMenuTemplate")
local lab = drop:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
local myPlayerMap, mySpecID, mySpecName
lab:SetPoint("LEFT", bg, "TOPLEFT", 0, -18)
lab:SetText(L"Equip set:")
drop:SetPoint("TOPRIGHT", -3, -2)
UIDropDownMenu_SetWidth(drop, 250)
local function getCurrentValue()
local value = nil
if myPlayerMap and myPlayerMap[CHARNAME] ~= nil then
value = myPlayerMap[CHARNAME]
end
if value == nil then
value = mySpecName
end
return value
end
function drop:text()
local name = getCurrentValue()
local _, ico = C_EquipmentSet.GetEquipmentSetInfo(name and C_EquipmentSet.GetEquipmentSetID(name) or -1)
UIDropDownMenu_SetText(drop, name == false and NONE or ((ico and "|T" .. ico .. ":0|t " or "|cffb0b0b0") .. name))
end
function drop:set(name)
if name == mySpecName then
name = nil
end
if myPlayerMap or name ~= nil then
myPlayerMap = myPlayerMap or {}
myPlayerMap[CHARNAME] = name
if name == nil and next(myPlayerMap) == nil then
myPlayerMap = nil
end
end
drop:text()
local p = bg:GetParent()
if p and type(p.OnActionChanged) == "function" then
p:OnActionChanged(bg)
elseif p and type(p.SaveAction) == "function" then -- DEPRECATED [2303/Y8]
p:SaveAction()
end
end
function drop:initialize()
local value = getCurrentValue()
local inf, hadSpec = {func=self.set, minWidth=self:GetWidth()-40}, false
inf.text, inf.arg1, inf.checked = NONE, false, value == false
UIDropDownMenu_AddButton(inf)
for _, id in pairs(C_EquipmentSet.GetEquipmentSetIDs()) do
local n, ico = C_EquipmentSet.GetEquipmentSetInfo(id)
inf.text, inf.arg1, inf.checked = "|T" .. (ico or "Interface/Icons/Temp") .. ":0|t " .. n, n, value == n
hadSpec = hadSpec or n == mySpecName
UIDropDownMenu_AddButton(inf)
end
if not hadSpec and mySpecName then
inf.text, inf.arg1, inf.checked = mySpecName, mySpecName, value == nil or value == mySpecName
UIDropDownMenu_AddButton(inf)
end
end
--[[ The action format is: "specset", specIndex, {CHARNAME => equipSetName}
The map in [3] is needed to allow different characters to use the
"same" specset action to equip different sets. This editor only shows
and edits the equipment set used for the current character.
Note that this editor will happily hand out the *original map reference*
to anyone who asks. The caller is responsible for mitigating this,
e.g. via ActionBook:CreateEditorHost.
--]]
function bg:SetAction(owner, action)
local op = self:GetParent()
if op and op ~= owner and type(op.OnEditorRelease) == "function" then
securecall(op.OnEditorRelease, op, self)
end
bg:SetParent(nil)
bg:ClearAllPoints()
bg:SetAllPoints(owner)
bg:SetParent(owner)
drop:ClearAllPoints()
if bg:GetWidth() < 400 then
drop:SetPoint("TOPLEFT", -16, -32)
else
local ofsX = owner.optionsColumnOffset
ofsX = type(ofsX) == "number" and ofsX or 256
drop:SetPoint("TOPLEFT", ofsX-16, 0)
end
bg:Show()
mySpecID, myPlayerMap = action[2], action[3]
if type(myPlayerMap) ~= "table" then
myPlayerMap = nil
end
mySpecName = select(2, GetSpecializationInfo(mySpecID))
drop:SetShown(not not mySpecName)
if mySpecName then
drop:text()
end
end
function bg:GetAction(into)
into[1], into[2], into[3] = "specset", mySpecID, myPlayerMap
end
function bg:Release(owner)
if bg:IsOwned(owner) then
bg:SetParent(nil)
bg:ClearAllPoints()
bg:Hide()
myPlayerMap, mySpecID, mySpecName = nil
end
end
function bg:IsOwned(owner)
return bg:GetParent() == owner
end
AB:RegisterEditorPanel("specset", bg)
end