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.

447 lines
17 KiB

local _,L = ...
local rematch = Rematch
local toolbar = RematchToolbar
local settings
local blizzBugFixLoginTime
local templates = { {}, {}, {} }
-- potentially more templates will be added, but for now having two sets of toolbar templates
-- first template is for journal or standalone when BottomPanel is used
-- second template is for standalone when BottomPanel is not used
-- third temmplate is for minimized window only
toolbar.templates = {
["Original"] = {
{"Heal","Bandage","","SafariHat","LesserPetTreat","PetTreat","","SummonRandom"},
{"Heal","Bandage","","SafariHat","LesserPetTreat","PetTreat","","SummonRandom","","Save","SaveAs","FindBattle"},
{"Heal","Bandage","","SafariHat","LesserPetTreat","PetTreat","","SummonRandom","","FindBattle"},
},
["Import"] = {
{"Heal","Bandage","SafariHat","LesserPetTreat","PetTreat","SummonRandom","Import"}, -- [1]
{"Heal","Bandage","SafariHat","LesserPetTreat","PetTreat","SummonRandom","Import","Save","SaveAs","FindBattle"}, --[2]
{"Heal","Bandage","SafariHat","LesserPetTreat","PetTreat","SummonRandom","Import","FindBattle"}, --[3]
}
}
-- switches toolbar button templates; for now just "Original" and "Import" are possible templateNames
function toolbar:SetTemplate(templateName)
local newTemplate = toolbar.templates[templateName]
if newTemplate then
for i=1,#newTemplate do
wipe(templates[i])
for j=1,#newTemplate[i] do
tinsert(templates[i],newTemplate[i][j])
end
end
end
end
toolbar:SetTemplate("Original") -- start with original (OptionPanel will switch to Import during login if option checked)
rematch:InitModule(function()
settings = RematchSettings
rematch.Toolbar = toolbar
toolbar.PetCount.TotalLabel:SetText(L["Total Pets"])
toolbar.PetCount.UniqueLabel:SetText(L["Unique Pets"])
toolbar.FindBattle.tooltipTitle = FIND_BATTLE
toolbar.FindBattle.tooltipBody = BATTLE_PETS_FIND_BATTLE_TOOLTIP
toolbar.SaveAs.tooltipTitle = L["Save As..."]
toolbar.SaveAs.tooltipBody = L["Save the currently loaded pets to a new team."]
toolbar.Save.tooltipTitle = SAVE
toolbar.Save.tooltipBody = L["Save the currently loaded pets to the loaded team."]
local locale = GetLocale()
if locale=="zhTW" or locale=="zhCN" then
toolbar.tallLocale = true
toolbar.PetCount.UniqueLabel:Hide()
toolbar.PetCount.Unique:Hide()
toolbar.PetCount.TotalLabel:SetPoint("TOPRIGHT",toolbar.PetCount,"TOP",14,-12)
toolbar.PetCount.Total:SetPoint("TOPRIGHT",-10,-12)
end
end)
function toolbar:OnShow()
self:RegisterEvent("COMPANION_UPDATE")
self:RegisterEvent("BAG_UPDATE")
self:RegisterEvent("SPELL_UPDATE_COOLDOWN")
self:RegisterUnitEvent("UNIT_AURA","player")
self:RegisterUnitEvent("UNIT_SPELLCAST_SUCCEEDED","player")
self:RegisterEvent("BATTLE_PET_CURSOR_CLEAR")
end
function toolbar:OnHide()
self:UnregisterEvent("COMPANION_UPDATE")
self:UnregisterEvent("BAG_UPDATE")
self:UnregisterEvent("SPELL_UPDATE_COOLDOWN")
self:UnregisterEvent("UNIT_AURA")
self:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED")
self:UnregisterEvent("BATTLE_PET_CURSOR_CLEAR")
end
-- the toolbar has a separate event handler; all events are only registered while the toolbar is visible
function toolbar:OnEvent(event,...)
local update
if event=="UNIT_AURA" or event=="BAG_UPDATE" then -- can't qualify what changed on these two
update = true -- possibly bandages, treats or safari hat added/removed from inventory
elseif event=="SPELL_UPDATE_COOLDOWN" then
update = rematch:GetGCDPetID()
elseif event=="UNIT_SPELLCAST_SUCCEEDED" and select(5,...)==125439 then
update = true -- revive battle pets cast
elseif event=="COMPANION_UPDATE" and select(1,...)=="CRITTER" then
update = true -- summoned pet changed
elseif event=="BATTLE_PET_CURSOR_CLEAR" then
update = true -- a battle pet dropped, maybe on a loaded slot?
end
-- no toolbar update is critical, delaying the update to 0.1 seconds after last noteworthy event firing
if update then
rematch:StartTimer("Toolbar",0.1,toolbar.Update)
end
end
-- called during the journal or frame config: resizes and populates the toolbar
function toolbar:Resize(width)
-- choose a template based on whether toolbar is going to:
-- Minimized Frame=3; Maximized BottomToolbar Frame=2; Others=1
local templateIndex = (rematch.Frame:IsVisible() and settings.Minimized) and 3 or (rematch.Frame:IsVisible() and settings.BottomToolbar) and 2 or 1
local template = templates[templateIndex]
for _,button in pairs(toolbar.Buttons) do
button:ClearAllPoints()
button:Hide()
end
local xoff = 0
local first,last,step = #template,1,-1
if settings.ReverseToolbar then
first,last,step = 1,#template,1
end
for i=first,last,step do
local key = template[i]
if key=="" then
xoff = xoff - 10 -- for spacer just skip some space
else
toolbar[key]:SetPoint("RIGHT",xoff,0)
toolbar[key]:Show()
xoff = xoff - 32
end
end
-- set width of toolbar to passed width, or to the toolbar buttons only if we're not showing petcount
if templateIndex==3 or (templateIndex==2 and settings.SinglePanel) then
toolbar:SetWidth(-xoff) -- for single panel+bottomtoolbar or minimized adjust width to the toolbar buttons only
toolbar.PetCount:Hide()
else
toolbar:SetWidth(width-13)
toolbar.PetCount:Show()
end
if width>400 then -- if toolbar is wide enough, position and show achievement frame
toolbar.Achievement:SetPoint("TOPLEFT",112,0)
toolbar.Achievement:SetPoint("TOPRIGHT",xoff,0) -- 10 is arbitrary spacer to shift it left a bit
toolbar.Achievement:Show()
-- if we're showing all 9 buttons, shrink achievement flair textures
if templateIndex==2 then
toolbar.Achievement.LeftFlair:SetSize(23,9)
toolbar.Achievement.RightFlair:SetSize(23,9)
else
toolbar.Achievement.LeftFlair:SetSize(39,15)
toolbar.Achievement.RightFlair:SetSize(39,15)
end
else
toolbar.Achievement:Hide()
end
toolbar.width = width -- note the width in case we need to do all this again (options)
end
-- updates the toolbar's components
function toolbar:Update()
if not toolbar:IsVisible() or InCombatLockdown() then
return
end
--[[ PetCount, Achievement ]]
-- CheckForUpdate() was here -- only place it may legitimately be needed
toolbar.PetCount.Total:SetText(select(2,C_PetJournal.GetNumPets()))
toolbar.PetCount.Unique:SetText(rematch.Roster:GetNumUniquePets())
toolbar.Achievement.Text:SetText(GetCategoryAchievementPoints(15117,true))
--[[ Heal, Bandage, LesserPetTreat, PetTreat ]]
toolbar:UpdateItemButton(toolbar.Bandage,86143)
toolbar:UpdateItemButton(toolbar.PetTreat,98114,true)
toolbar:UpdateItemButton(toolbar.LesserPetTreat,98112,true)
--[[ Safari Hat ]]
toolbar:DimButton(toolbar.SafariHat,not PlayerHasToy(92738))
local safariBuff = GetItemSpell(92738)
if safariBuff and rematch:UnitBuff(safariBuff) then -- safari hat is active
toolbar.SafariHat.Cancel:Show()
toolbar.SafariHat:SetAttribute("type","macro")
toolbar.SafariHat:SetAttribute("macrotext",format("/cancelaura %s",safariBuff))
toolbar.SafariHat.Shine:Hide()
else -- safari hat is not active
toolbar.SafariHat.Cancel:Hide()
toolbar.SafariHat:SetAttribute("type","item")
toolbar.SafariHat:SetAttribute("item",(GetItemInfo(92738)))
toolbar.SafariHat.Shine:SetShown(settings.SafariHatShine and rematch:IsLowLevelPetLoaded())
end
--[[ SummonRandom ]]
local petID = C_PetJournal.GetSummonedPetGUID()
if petID then
local _,customName,_,_,_,_,_,name,icon = C_PetJournal.GetPetInfoByPetID(petID)
toolbar.SummonRandom.Icon:SetTexture(icon)
toolbar.SummonRandom.Cancel:Show()
else
local _,_,icon = GetSpellInfo(243819) -- get icon for "Summon Random Favorite Battle Pet" spell
toolbar.SummonRandom.Icon:SetTexture(icon) -- "Interface\\Icons\\Achievement_GuildPerk_MountUp")
toolbar.SummonRandom.Cancel:Hide()
end
--[[ Find Battle ]]
toolbar.FindBattle.Cancel:SetShown(C_PetBattles.GetPVPMatchmakingInfo() and true)
--[[ Save ]]
if toolbar.Save:IsVisible() then
local noTeam = not settings.loadedTeam or settings.loadedTeam==1 -- 1=imported team
toolbar.Save:SetEnabled(not noTeam)
toolbar:DimButton(toolbar.Save,noTeam,noTeam)
end
toolbar:UpdateCooldowns()
end
-- this is the OnEnter for all of the toolbar buttons
function toolbar:ButtonOnEnter(once)
if self.tooltipTitle then -- for Save, SaveAs and FindBattle whose tooltip never changes
rematch.ShowTooltip(self)
once = true -- no need to update this tooltip
elseif self==toolbar.SummonRandom then -- summon button gets its own handling
local petID = C_PetJournal.GetSummonedPetGUID()
if petID then
rematch.ShowTooltip(self,L["Dismiss Pet"],rematch:GetPetName(petID))
elseif settings.ToolbarDismiss then
rematch.ShowTooltip(self,L["Summon Pet"],L["Summons a random pet from your favorites."])
else
rematch.ShowTooltip(self,L["Summon Pet"],format("%s %s\n%s %s",rematch.LMB,L["Random Favorite"],rematch.RMB,L["Random From All"]))
end
elseif self==toolbar.Import then
rematch.ShowTooltip(self,L["Import Teams"], L["Import a single team or many teams that were exported from Rematch."])
once = true
else -- the rest are secure buttons who will use a GameTooltip based on the button attributes
GameTooltip:SetOwner(self,"ANCHOR_NONE") -- item or spells will use GameTooltip
local itemID = self:GetAttribute("item")
local spellID = self:GetAttribute("spell")
if itemID==GetItemInfo(92738) then
itemID = "item:92738" -- can't use item:id attributes for toybox, Safari Hat is named attribute
end
if itemID then
local buff = GetItemSpell(itemID)
local index, found = 1
-- using this old buff-lookup method in the OnEnter because we need a buff index for SetUnitBuff
repeat
local candidate = UnitBuff("player",index)
if candidate == buff then
found = index
end
index = index + 1
until not candidate or found
if found then
GameTooltip:SetUnitBuff("player",found) -- display buff tooltip if it's up
elseif itemID=="item:92738" then
GameTooltip:SetToyByItemID(92738) -- safari hat toybox tooltip
else
GameTooltip:SetHyperlink(itemID) -- rest of items
end
elseif spellID then
GameTooltip:SetSpellByID(tonumber(spellID))
end
rematch:SmartAnchor(GameTooltip,self)
GameTooltip:SetBackdropBorderColor(0.5,0.5,0.5)
GameTooltip:Show()
end
-- this timer calls this onenter again in half a second; the onleave stops the timer
-- this causes a bit of garbage creation but is forgivable for the effects (cooldown timers
-- count down in the tooltip and left/right click instructions update)
if not once then
self.tooltipTimer = C_Timer.NewTimer(0.5,function() toolbar.ButtonOnEnter(self) end)
end
end
function toolbar:ButtonOnLeave()
if self.tooltipTimer then
self.tooltipTimer:Cancel() -- stop tooltip updating itself
end
rematch:HideTooltip()
GameTooltip:Hide()
end
-- all toolbar buttons use this PreClick, but only heals and treats do anything for now
function toolbar:ButtonPreClick()
if InCombatLockdown() then return end
-- for heal/bandage button, check if all pets are fully healed and prevent use if so
if self==toolbar.Heal or self==toolbar.Bandage then
-- for heals or bandages, come back in a bit to load healthiest pet if options enabled
if settings.LoadHealthiest and settings.LoadHealthiestAfterBattle then
C_Timer.After(0.75,rematch.LoadHealthiestOfLoadedPets)
end
local roster = rematch.Roster
for petID in roster:AllOwnedPets() do
local health,maxHealth = C_PetJournal.GetPetStats(petID)
if health<maxHealth then
return
end
end
-- if we reached here, all pets are healed
self.backupAttribute = self:GetAttribute("type")
self:SetAttribute("type",nil)
if toolbar:IsVisible() then -- if toolbar up, notify via tooltip
if self.tooltipTimer then self.tooltipTimer:Cancel() end
toolbar.ButtonOnEnter(self,true)
GameTooltip:AddLine(format("%s%s",rematch.hexBlue,L["All pets are at full health."]))
GameTooltip:Show()
else -- if toolbar not visible, notify via print
rematch:print(format("%s%s",rematch.hexBlue,L["All pets are at full health."]))
end
-- for pet treats, check if buff is currently active and prevent use if so
elseif self==toolbar.LesserPetTreat or self==toolbar.PetTreat then
local buff = GetItemSpell(self:GetAttribute("item"))
if buff and rematch:UnitBuff(buff) then -- buff is already up
-- while treats CAN be recast, it doesn't refresh duration of buff, so we should prevent their use
self.backupAttribute = self:GetAttribute("type")
self:SetAttribute("type",nil)
if toolbar:IsVisible() then
if self.tooltipTimer then self.tooltipTimer:Cancel() end
toolbar.ButtonOnEnter(self,true)
GameTooltip:AddLine(format("%s%s",rematch.hexBlue,L["This treat's buff is already active."]),nil,nil,nil,true)
GameTooltip:Show()
else
rematch:print(format("%s%s",rematch.hexBlue,L["This treat's buff is already active."]))
end
end
end
end
-- all toolbar buttons use this PostClick
function toolbar:ButtonPostClick(button)
-- for heal, bandage and treat buttons that are turned off in their pre-click
if self.backupAttribute then
self:SetAttribute("type",self.backupAttribute)
self.backupAttribute = nil
end
-- if ToolbarDismiss enabled and right-click used, hide rematch
if button=="RightButton" and RematchSettings.ToolbarDismiss then
if rematch.Frame:IsVisible() then
rematch.Frame.Toggle()
elseif rematch.Journal:IsVisible() or (PetJournal and PetJournal:IsVisible()) then
HideUIPanel(CollectionsJournal)
end
end
end
-- only SummonRandom, Import, Save, SaveAs and FindBattle have an OnClick handler.
-- for the latter three which have a redirect keyvalue, it passes its click to the
-- BottomPanel[redirect] version of those buttons.
-- for SummonRandom it just does the summon/dismiss business.
function toolbar:ButtonOnClick(button)
if self.redirect then
rematch.BottomPanel[self.redirect]:Click()
elseif self==toolbar.SummonRandom then
local petID = C_PetJournal.GetSummonedPetGUID()
if petID then -- pet was out, dismiss it
C_PetJournal.SummonPetByGUID(petID)
else -- pet not out, as of 7.3, true=random favorites, false=random all
C_PetJournal.SummonRandomPet(button~="RightButton")
end
elseif self==toolbar.Import then
rematch:ShowImportDialog()
end
end
function toolbar:ButtonOnDragStart()
local attribType = self:GetAttribute("type")
local attribValue = attribType and self:GetAttribute(attribType)
if self==toolbar.SummonRandom then
C_PetJournal.PickupSummonRandomPet()
elseif self==toolbar.SafariHat then
C_ToyBox.PickupToyBoxItem(92738)
elseif attribType=="spell" then
PickupSpell(attribValue)
elseif attribType=="item" then
PickupItem(attribValue)
end
end
function toolbar:UpdateItemButton(button,itemID,showTimeLeft)
local count = GetItemCount(itemID)
button.Count:SetText(count)
toolbar:DimButton(button,count==0)
if showTimeLeft then
local spell = GetItemSpell(itemID)
if spell then
local _,_,_,_,duration,expiration = rematch:UnitBuff(spell)
if duration then
local start = expiration - duration
if blizzBugFixLoginTime and start<blizzBugFixLoginTime then
-- this cooldown was from a previous session, adjust times to login time
-- this means if a treat is at 30 mins remaining, the spinner's duration will be 30 mins with a start of the login time
button.Cooldown:SetCooldown(blizzBugFixLoginTime,expiration-blizzBugFixLoginTime)
else
button.Cooldown:SetCooldown(expiration-duration,duration)
end
else
button.Cooldown:Hide()
end
end
end
end
function toolbar:DimButton(button,dim,desaturate)
button.Icon:SetDesaturated(desaturate and true or false)
if dim then
button.Icon:SetVertexColor(0.5,0.5,0.5)
else
button.Icon:SetVertexColor(1,1,1)
end
end
-- fix for GetItemCooldown possibly returning nil and throwing an error in SetCooldown
local function getItemCooldown(itemID)
local start, duration, enable = GetItemCooldown(itemID)
if start then
return start, duration, enable
else
return 0, 0, 1
end
end
-- updates most cooldowns (treat cooldowns handled in the Update due to special handling for old treat buffs)
function toolbar:UpdateCooldowns()
-- update summon button's GCD (using FindGCDPetID in the SPELL_UPDATE_COOLDOWN)
local GCDPetID = rematch:GetGCDPetID()
if GCDPetID then
toolbar.SummonRandom.Cooldown:SetCooldown(C_PetJournal.GetPetCooldownByGUID(GCDPetID))
end
-- update heal, bandage and safari hat cooldowns
toolbar.Heal.Cooldown:SetCooldown(GetSpellCooldown(125439))
toolbar.Bandage.Cooldown:SetCooldown(getItemCooldown(86143))
toolbar.SafariHat.Cooldown:SetCooldown(getItemCooldown(92738))
end
function toolbar:PetCountOnEnter()
local at25=0
local missing=0
local roster = rematch.Roster
for petID in roster:AllPets() do
if type(petID)=="string" then
if select(3,C_PetJournal.GetPetInfoByPetID(petID))==25 then
at25 = at25 + 1
end
else
missing = missing + 1
end
end
rematch.ShowTooltip(self.PetCount,BATTLE_PETS_TOTAL_PETS,format(L["%s\n\nPets At Max Level: %s%d\124r\nPets Not Collected: %s%d\124r\n\n%s Click to display more about your collection."],format(BATTLE_PETS_TOTAL_PETS_TOOLTIP,C_PetJournal.GetNumMaxPets and C_PetJournal.GetNumMaxPets() or ""),rematch.hexWhite,at25,rematch.hexWhite,missing,rematch.LMB))
end