mirror of
https://github.com/parnic/breakables.git
synced 2025-06-17 01:41:51 -05:00
Compare commits
30 Commits
Author | SHA1 | Date | |
---|---|---|---|
1e45bfe622 | |||
26d83c425b | |||
8e6867ed44 | |||
a9f1b24563 | |||
a20c5fe54f | |||
e22f4ef334 | |||
c20dabea47 | |||
fa59e6137d | |||
c3ee55d04c | |||
f22c064472 | |||
5628e8d289 | |||
cf128a6a87 | |||
dbd7d69459 | |||
ef4fc31fa6 | |||
b6556dc98d | |||
64a7e73ec0 | |||
30e6b021dd | |||
a701b935b0 | |||
4158971161 | |||
1741f54321 | |||
f93465037d | |||
f9971a7818 | |||
59fd3c320d | |||
4bc72649f2 | |||
4ad9afa103 | |||
958521c6d3 | |||
1401893e2d | |||
f55cd76606 | |||
6a89a7ca11 | |||
a5f5958c5e |
4
.pkgmeta
4
.pkgmeta
@ -28,6 +28,10 @@ externals:
|
||||
libs/AceEvent-3.0:
|
||||
url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceEvent-3.0
|
||||
tag: latest
|
||||
libs/AceLocale-3.0:
|
||||
url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceLocale-3.0
|
||||
tag: latest
|
||||
libs/LibBabble-Inventory-3.0:
|
||||
url: svn://svn.wowace.com/wow/libbabble-inventory-3-0/mainline/trunk
|
||||
tag: latest
|
||||
libs/LibButtonFacade: svn://svn.wowace.com/wow/buttonfacade/mainline/trunk/Libs/LibButtonFacade
|
||||
|
759
Breakables.lua
759
Breakables.lua
@ -1,5 +1,9 @@
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Breakables", false)
|
||||
Breakables = LibStub("AceAddon-3.0"):NewAddon("Breakables", "AceConsole-3.0", "AceEvent-3.0")
|
||||
local babbleInv = LibStub("LibBabble-Inventory-3.0"):GetLookupTable()
|
||||
local LBF = LibStub("LibButtonFacade", true)
|
||||
|
||||
local lbfGroup
|
||||
|
||||
local MillingId = 51005
|
||||
local MillingItemSubType = babbleInv["Herb"]
|
||||
@ -13,8 +17,22 @@ local CanProspect = false
|
||||
local DisenchantId = 13262
|
||||
local DisenchantTypes = {babbleInv["Armor"], babbleInv["Weapon"]}
|
||||
local CanDisenchant = false
|
||||
|
||||
local PickLockId = 1804
|
||||
local PickableItems = {
|
||||
16882, -- battered junkbox
|
||||
16883, -- worn junkbox
|
||||
16884, -- sturdy junkbox
|
||||
16885, -- heavy junkbox
|
||||
29569, -- strong junkbox
|
||||
43575, -- reinforced junkbox
|
||||
63349, -- flame-scarred junkbox
|
||||
}
|
||||
local CanPickLock = false
|
||||
|
||||
-- item rarity must meet or surpass this to be considered for disenchantability (is that a word?)
|
||||
local RARITY_UNCOMMON = 2
|
||||
local RARITY_HEIRLOOM = 7
|
||||
|
||||
local IDX_LINK = 1
|
||||
local IDX_COUNT = 2
|
||||
@ -26,47 +44,167 @@ local IDX_SUBTYPE = 7
|
||||
local IDX_LEVEL = 8
|
||||
local IDX_BREAKABLETYPE = 9
|
||||
local IDX_SOULBOUND = 10
|
||||
local IDX_NAME = 11
|
||||
|
||||
local BREAKABLE_HERB = 1
|
||||
local BREAKABLE_ORE = 2
|
||||
local BREAKABLE_DE = 3
|
||||
local BREAKABLE_PICK = 4
|
||||
|
||||
local BagUpdateCheckDelay = 1.0
|
||||
local nextCheck = {}
|
||||
for i=0,NUM_BAG_SLOTS do
|
||||
nextCheck[i] = -1
|
||||
end
|
||||
|
||||
local buttonSize = 45
|
||||
|
||||
local _G = _G
|
||||
|
||||
local validGrowDirections = {L["Left"], L["Right"], L["Up"], L["Down"]}
|
||||
|
||||
-- can be 1, 2, or 3 (in the case of a rogue with pick lock)
|
||||
local numEligibleProfessions = 0
|
||||
|
||||
Breakables.optionsFrame = {}
|
||||
Breakables.justClicked = false
|
||||
|
||||
function Breakables:OnInitialize()
|
||||
self.defaults = {
|
||||
profile = {
|
||||
buttonFrameLeft = 100,
|
||||
buttonFrameTop = -100,
|
||||
buttonFrameLeft = {100, 100},
|
||||
buttonFrameTop = {700, 650},
|
||||
hideIfNoBreakables = true,
|
||||
maxBreakablesToShow = 5,
|
||||
showSoulbound = false,
|
||||
hideEqManagerItems = true,
|
||||
hide = false,
|
||||
hideInCombat = false,
|
||||
buttonScale = 1,
|
||||
fontSize = 11,
|
||||
growDirection = 2,
|
||||
}
|
||||
}
|
||||
self.db = LibStub("AceDB-3.0"):New("BreakablesDB", self.defaults)
|
||||
self.db = LibStub("AceDB-3.0"):New("BreakablesDB", self.defaults, true)
|
||||
self.settings = self.db.profile
|
||||
|
||||
self:RegisterChatCommand("brk", "OnSlashCommand")
|
||||
|
||||
if type(self.settings.buttonFrameLeft) ~= "table" then
|
||||
local old = self.settings.buttonFrameLeft
|
||||
self.settings.buttonFrameLeft = {}
|
||||
self.settings.buttonFrameLeft[1] = old
|
||||
self.settings.buttonFrameLeft[2] = self.defaults.profile.buttonFrameLeft[2]
|
||||
end
|
||||
if type(self.settings.buttonFrameTop) ~= "table" then
|
||||
local old = self.settings.buttonFrameTop
|
||||
self.settings.buttonFrameTop = {}
|
||||
self.settings.buttonFrameTop[1] = old
|
||||
self.settings.buttonFrameTop[2] = self.defaults.profile.buttonFrameTop[2]
|
||||
end
|
||||
|
||||
self:InitLDB()
|
||||
end
|
||||
|
||||
function Breakables:ButtonFacadeCallback(SkinID, Gloss, Backdrop, Group, Button, Colors)
|
||||
if not Group then
|
||||
self.settings.SkinID = SkinID
|
||||
self.settings.Gloss = Gloss
|
||||
self.settings.Backdrop = Backdrop
|
||||
self.settings.Colors = Colors
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:InitLDB()
|
||||
local LDB = LibStub and LibStub("LibDataBroker-1.1", true)
|
||||
|
||||
if (LDB) then
|
||||
local ldbButton = LDB:NewDataObject("Breakables", {
|
||||
type = "launcher",
|
||||
text = L["Breakables"],
|
||||
icon = "Interface\\Icons\\ability_warrior_sunder",
|
||||
OnClick = function(button, msg)
|
||||
self:OnSlashCommand()
|
||||
end,
|
||||
})
|
||||
|
||||
if ldbButton then
|
||||
function ldbButton:OnTooltipShow()
|
||||
self:AddLine(L["Breakables"] .. " @project-version@")
|
||||
self:AddLine(L["Click to open Breakables options."], 1, 1, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:OnEnable()
|
||||
CanMill = IsUsableSpell(GetSpellInfo(MillingId))
|
||||
CanProspect = IsUsableSpell(GetSpellInfo(ProspectingId))
|
||||
CanDisenchant = IsUsableSpell(GetSpellInfo(DisenchantId))
|
||||
CanPickLock = IsUsableSpell(GetSpellInfo(PickLockId))
|
||||
|
||||
LibStub("AceConfig-3.0"):RegisterOptionsTable("Breakables", self:GetOptions(), "breakables")
|
||||
self.optionsFrame = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("Breakables")
|
||||
|
||||
if LBF then
|
||||
LBF:RegisterSkinCallback("Breakables", self.ButtonFacadeCallback, self)
|
||||
|
||||
lbfGroup = LBF:Group("Breakables")
|
||||
if lbfGroup then
|
||||
lbfGroup:Skin(self.settings.SkinID,
|
||||
self.settings.Gloss,
|
||||
self.settings.Backdrop,
|
||||
self.settings.Colors)
|
||||
end
|
||||
end
|
||||
|
||||
self:RegisterEvents()
|
||||
|
||||
if CanMill or CanProspect or CanDisenchant then
|
||||
if CanMill or CanProspect or CanDisenchant or CanPickLock then
|
||||
if CanMill then
|
||||
numEligibleProfessions = numEligibleProfessions + 1
|
||||
end
|
||||
if CanProspect then
|
||||
numEligibleProfessions = numEligibleProfessions + 1
|
||||
end
|
||||
if CanDisenchant then
|
||||
numEligibleProfessions = numEligibleProfessions + 1
|
||||
end
|
||||
if CanPickLock then
|
||||
numEligibleProfessions = numEligibleProfessions + 1
|
||||
end
|
||||
|
||||
self:CreateButtonFrame()
|
||||
if self.settings.hide then
|
||||
self:ToggleButtonFrameVisibility(false)
|
||||
else
|
||||
self:FindBreakables()
|
||||
end
|
||||
if not self.frame.OnUpdateFunc then
|
||||
self.frame.OnUpdateFunc = function() self:CheckShouldFindBreakables() end
|
||||
end
|
||||
self.frame:SetScript("OnUpdate", self.frame.OnUpdateFunc)
|
||||
else
|
||||
self:UnregisterAllEvents()
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:ToggleButtonFrameVisibility(show)
|
||||
for i=1,numEligibleProfessions do
|
||||
if self.buttonFrame[i] then
|
||||
if show == nil then
|
||||
show = not self.buttonFrame[i]:IsVisible()
|
||||
end
|
||||
|
||||
if not show then
|
||||
self.buttonFrame[i]:Hide()
|
||||
else
|
||||
self.buttonFrame[i]:Show()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:RegisterEvents()
|
||||
-- would have used ITEM_PUSH here, but that seems to fire after looting and before the bag actually gets the item
|
||||
-- another alternative is to parse the chat msg, but that seems lame...however, that should only fire once as opposed to BAG_UPDATE's potential double-fire
|
||||
@ -78,28 +216,57 @@ function Breakables:RegisterEvents()
|
||||
if CanDisenchant then
|
||||
self:RegisterEvent("TRADE_SKILL_UPDATE", "OnTradeSkillUpdate")
|
||||
end
|
||||
|
||||
if CanPickLock then
|
||||
self:RegisterEvent("CHAT_MSG_OPENING", "OnBagItemLockPicked")
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:OnDisable()
|
||||
self:UnregisterAllEvents()
|
||||
self.frame:SetScript("OnUpdate", nil)
|
||||
end
|
||||
|
||||
function Breakables:OnSlashCommand(input)
|
||||
InterfaceOptionsFrame_OpenToCategory(self.optionsFrame)
|
||||
end
|
||||
|
||||
function Breakables:OnItemReceived(bag)
|
||||
self:FindBreakables()
|
||||
function Breakables:OnItemReceived(event, bag)
|
||||
if self.justClicked then
|
||||
self:FindBreakables()
|
||||
self.justClicked = false
|
||||
elseif not bag or bag >= 0 then
|
||||
nextCheck[bag] = GetTime() + BagUpdateCheckDelay
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:CheckShouldFindBreakables()
|
||||
local latestTime = -1
|
||||
for i=0,#nextCheck do
|
||||
if nextCheck[i] and nextCheck[i] > latestTime then
|
||||
latestTime = nextCheck[i]
|
||||
end
|
||||
end
|
||||
|
||||
if latestTime > 0 and latestTime <= GetTime() then
|
||||
self:FindBreakables()
|
||||
for i=0,#nextCheck do
|
||||
nextCheck[i] = -1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:OnEnterCombat()
|
||||
self.bCombat = true
|
||||
if self.settings.hideInCombat then
|
||||
self:ToggleButtonFrameVisibility(false)
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:OnLeaveCombat()
|
||||
self.bCombat = false
|
||||
|
||||
if self.bPendingUpdate then
|
||||
if self.bPendingUpdate or self.settings.hideInCombat then
|
||||
self.bPendingUpdate = false
|
||||
self:FindBreakables()
|
||||
end
|
||||
@ -109,6 +276,10 @@ function Breakables:OnTradeSkillUpdate()
|
||||
self:GetEnchantingLevel()
|
||||
end
|
||||
|
||||
function Breakables:OnBagItemLockPicked()
|
||||
nextCheck[1] = GetTime() + BagUpdateCheckDelay
|
||||
end
|
||||
|
||||
function Breakables:GetEnchantingLevel()
|
||||
local skillName, skillType, numAvailable, isExpanded = GetTradeSkillInfo(1)
|
||||
|
||||
@ -120,27 +291,70 @@ end
|
||||
|
||||
function Breakables:GetOptions()
|
||||
local opts = {
|
||||
name = "Breakables",
|
||||
name = L["Breakables"],
|
||||
handler = Breakables,
|
||||
type = "group",
|
||||
args = {
|
||||
intro = {
|
||||
type = "description",
|
||||
fontSize = "small",
|
||||
name = L["Welcome"],
|
||||
order = 0,
|
||||
},
|
||||
hideAlways = {
|
||||
type = "toggle",
|
||||
name = L["Hide bar"],
|
||||
desc = L["This will completely hide the breakables bar whether you have anything to break down or not. Note that you can toggle this in a macro using the /breakables command as well."],
|
||||
get = function(info)
|
||||
return self.settings.hide
|
||||
end,
|
||||
set = function(info, v)
|
||||
self.settings.hide = v
|
||||
if info.uiType == "cmd" then
|
||||
print("|cff33ff99Breakables|r: set |cffffff78maxBreakables|r to " .. tostring(self.settings.hide))
|
||||
end
|
||||
self:ToggleButtonFrameVisibility(not v)
|
||||
if not v then
|
||||
self:FindBreakables()
|
||||
end
|
||||
end,
|
||||
order = 1
|
||||
},
|
||||
hideNoBreakables = {
|
||||
type = "toggle",
|
||||
name = "Hide if no breakables",
|
||||
desc = "Whether or not to hide the action bar if no breakables are present in your bags",
|
||||
name = L["Hide if no breakables"],
|
||||
desc = L["Whether or not to hide the action bar if no breakables are present in your bags"],
|
||||
get = function(info)
|
||||
return self.settings.hideIfNoBreakables
|
||||
end,
|
||||
set = function(info, v)
|
||||
self.settings.hideIfNoBreakables = v
|
||||
if info.uiType == "cmd" then
|
||||
print("|cff33ff99Breakables|r: set |cffffff78hideIfNoBreakables|r to " .. tostring(self.settings.hideIfNoBreakables))
|
||||
end
|
||||
self:FindBreakables()
|
||||
end,
|
||||
order = 1,
|
||||
order = 2,
|
||||
},
|
||||
hideInCombat = {
|
||||
type = "toggle",
|
||||
name = L["Hide during combat"],
|
||||
desc = L["Whether or not to hide the breakables bar when you enter combat and show it again when leaving combat."],
|
||||
get = function(info)
|
||||
return self.settings.hideInCombat
|
||||
end,
|
||||
set = function(info, v)
|
||||
self.settings.hideInCombat = v
|
||||
if info.uiType == "cmd" then
|
||||
print("|cff33ff99Breakables|r: set |cffffff78hideInCombat|r to " .. tostring(self.settings.hideInCombat))
|
||||
end
|
||||
end,
|
||||
order = 3,
|
||||
},
|
||||
maxBreakables = {
|
||||
type = 'range',
|
||||
name = 'Max number to display',
|
||||
desc = 'How many breakable buttons to display next to the profession button at maximum',
|
||||
name = L["Max number to display"],
|
||||
desc = L["How many breakable buttons to display next to the profession button at maximum"],
|
||||
min = 1,
|
||||
max = 50,
|
||||
step = 1,
|
||||
@ -149,9 +363,64 @@ function Breakables:GetOptions()
|
||||
end,
|
||||
set = function(info, v)
|
||||
self.settings.maxBreakablesToShow = v
|
||||
if info.uiType == "cmd" then
|
||||
print("|cff33ff99Breakables|r: set |cffffff78maxBreakables|r to " .. tostring(self.settings.maxBreakablesToShow))
|
||||
end
|
||||
self:FindBreakables()
|
||||
end,
|
||||
order = 2,
|
||||
order = 4,
|
||||
},
|
||||
buttonScale = {
|
||||
type = 'range',
|
||||
name = L["Button scale"],
|
||||
desc = L["This will scale the size of each button up or down."],
|
||||
min = 0.1,
|
||||
max = 2,
|
||||
step = 0.01,
|
||||
get = function(info)
|
||||
return self.settings.buttonScale
|
||||
end,
|
||||
set = function(info, v)
|
||||
self.settings.buttonScale = v
|
||||
Breakables:ApplyScale()
|
||||
if info.uiType == "cmd" then
|
||||
print("|cff33ff99Breakables|r: set |cffffff78buttonScale|r to " .. tostring(self.settings.buttonScale))
|
||||
end
|
||||
end,
|
||||
order = 5,
|
||||
},
|
||||
fontSize = {
|
||||
type = 'range',
|
||||
name = L["Font size"],
|
||||
desc = L["This sets the size of the text that shows how many items you have to break."],
|
||||
min = 4,
|
||||
max = 90,
|
||||
step = 1,
|
||||
get = function(info)
|
||||
return self.settings.fontSize
|
||||
end,
|
||||
set = function(info, v)
|
||||
self.settings.fontSize = v
|
||||
Breakables:ApplyScale()
|
||||
if info.uiType == "cmd" then
|
||||
print("|cff33ff99Breakables|r: set |cffffff78fontSize|r to " .. tostring(self.settings.fontSize))
|
||||
end
|
||||
end,
|
||||
order = 6,
|
||||
},
|
||||
growDirection = {
|
||||
type = 'select',
|
||||
name = L["Button grow direction"],
|
||||
desc = L["This controls which direction the breakable buttons grow toward."],
|
||||
values = validGrowDirections,
|
||||
get = function()
|
||||
return self.settings.growDirection
|
||||
end,
|
||||
set = function(info, v)
|
||||
self.settings.growDirection = v
|
||||
self:FindBreakables()
|
||||
end,
|
||||
order = 7,
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -159,87 +428,165 @@ function Breakables:GetOptions()
|
||||
if CanDisenchant then
|
||||
opts.args.showSoulbound = {
|
||||
type = "toggle",
|
||||
name = "Show soulbound items",
|
||||
desc = "Whether or not to display soulbound items as breakables.",
|
||||
name = L["Show soulbound items"],
|
||||
desc = L["Whether or not to display soulbound items as breakables."],
|
||||
get = function(info)
|
||||
return self.settings.showSoulbound
|
||||
end,
|
||||
set = function(info, v)
|
||||
self.settings.showSoulbound = v
|
||||
if info.uiType == "cmd" then
|
||||
print("|cff33ff99Breakables|r: set |cffffff78showSoulbound|r to " .. tostring(self.settings.showSoulbound))
|
||||
end
|
||||
self:FindBreakables()
|
||||
end,
|
||||
order = 3,
|
||||
order = 20,
|
||||
}
|
||||
opts.args.hideSoulboundIfInEquipmentManager = {
|
||||
opts.args.hideEqManagerItems = {
|
||||
type = "toggle",
|
||||
name = "Hide Eq. Mgr items",
|
||||
desc = "Whether or not to hide items that are part of an equipment set in the game's equipment manager.",
|
||||
name = L["Hide Eq. Mgr items"],
|
||||
desc = L["Whether or not to hide items that are part of an equipment set in the game's equipment manager."],
|
||||
get = function(info)
|
||||
return self.settings.hideEqManagerItems
|
||||
end,
|
||||
set = function(info, v)
|
||||
self.settings.hideEqManagerItems = v
|
||||
if info.uiType == "cmd" then
|
||||
print("|cff33ff99Breakables|r: set |cffffff78hideEqManagerItems|r to " .. tostring(self.settings.hideEqManagerItems))
|
||||
end
|
||||
self:FindBreakables()
|
||||
end,
|
||||
hidden = function()
|
||||
return not self.settings.showSoulbound
|
||||
end,
|
||||
order = 4,
|
||||
order = 21,
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
return opts
|
||||
end
|
||||
|
||||
function Breakables:CreateButtonFrame()
|
||||
if not self.frame then
|
||||
self.frame = CreateFrame("Frame", nil, UIParent)
|
||||
end
|
||||
self.frame:SetScale(self.settings.buttonScale)
|
||||
if not self.buttonFrame then
|
||||
self.buttonFrame = CreateFrame("Button", "BreakablesButtonFrame1", UIParent, "SecureActionButtonTemplate")
|
||||
self.buttonFrame = {}
|
||||
end
|
||||
self.buttonFrame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", self.settings.buttonFrameLeft, self.settings.buttonFrameTop)
|
||||
|
||||
if not self.buttonFrame.icon then
|
||||
self.buttonFrame.icon = self.buttonFrame:CreateTexture(nil, "BACKGROUND")
|
||||
end
|
||||
if CanMill or CanProspect or CanDisenchant then
|
||||
self.buttonFrame:SetWidth(40)
|
||||
self.buttonFrame:SetHeight(40)
|
||||
for i=1,numEligibleProfessions do
|
||||
if not self.buttonFrame[i] then
|
||||
self.buttonFrame[i] = CreateFrame("Button", "BREAKABLES_BUTTON_FRAME"..i, self.frame, "SecureActionButtonTemplate")
|
||||
end
|
||||
local frame = self.buttonFrame[i]
|
||||
frame:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", self.settings.buttonFrameLeft[i], self.settings.buttonFrameTop[i])
|
||||
|
||||
self.buttonFrame:EnableMouse(true)
|
||||
self.buttonFrame:RegisterForClicks("LeftButtonUp")
|
||||
if CanMill and (i == 1 or self.buttonFrame[1].type ~= BREAKABLE_HERB) then
|
||||
frame.type = BREAKABLE_HERB
|
||||
elseif CanDisenchant and (i == 1 or self.buttonFrame[1].type ~= BREAKABLE_DE) then
|
||||
frame.type = BREAKABLE_DE
|
||||
elseif CanProspect and (i == 1 or self.buttonFrame[1].type ~= BREAKABLE_ORE) then
|
||||
frame.type = BREAKABLE_ORE
|
||||
elseif CanPickLock and (i == 1 or self.buttonFrame[1].type ~= BREAKABLE_PICK) then
|
||||
frame.type = BREAKABLE_PICK
|
||||
end
|
||||
|
||||
self.buttonFrame:SetMovable(true)
|
||||
self.buttonFrame:RegisterForDrag("LeftButton")
|
||||
self.buttonFrame:SetScript("OnMouseDown", function() self:OnMouseDown() end)
|
||||
self.buttonFrame:SetScript("OnMouseUp", function() self:OnMouseUp() end)
|
||||
self.buttonFrame:SetClampedToScreen(true)
|
||||
if frame.type then
|
||||
frame:SetWidth(buttonSize)
|
||||
frame:SetHeight(buttonSize)
|
||||
|
||||
local spellName, _, texture = GetSpellInfo((CanMill and MillingId) or (CanProspect and ProspectingId) or DisenchantId)
|
||||
frame:EnableMouse(true)
|
||||
frame:RegisterForClicks("LeftButtonUp")
|
||||
|
||||
self.buttonFrame:SetAttribute("type1", "spell")
|
||||
self.buttonFrame:SetAttribute("spell1", spellName)
|
||||
if not frame.OnMouseDownFunc then
|
||||
frame.OnMouseDownFunc = function(frame) self:OnMouseDown(frame) end
|
||||
end
|
||||
if not frame.OnMouseUpFunc then
|
||||
frame.OnMouseUpFunc = function(frame) self:OnMouseUp(frame) end
|
||||
end
|
||||
|
||||
self.buttonFrame.icon:SetTexture(texture)
|
||||
self.buttonFrame.icon:SetAllPoints(self.buttonFrame)
|
||||
else
|
||||
self.buttonFrame:SetTexture(nil)
|
||||
frame:SetMovable(true)
|
||||
frame:RegisterForDrag("LeftButton")
|
||||
frame:SetScript("OnMouseDown", frame.OnMouseDownFunc)
|
||||
frame:SetScript("OnMouseUp", frame.OnMouseUpFunc)
|
||||
frame:SetClampedToScreen(true)
|
||||
|
||||
local spellName, _, texture = GetSpellInfo(self:GetSpellIdFromProfessionButton(frame))
|
||||
|
||||
frame:SetAttribute("type1", "spell")
|
||||
frame:SetAttribute("spell1", spellName)
|
||||
|
||||
if not lbfGroup then
|
||||
frame:SetNormalTexture(texture)
|
||||
else
|
||||
frame.icon = frame:CreateTexture(frame:GetName().."Icon", "BACKGROUND")
|
||||
frame.icon:SetTexture(texture)
|
||||
|
||||
lbfGroup:AddButton(frame)
|
||||
end
|
||||
|
||||
if not frame.OnEnterFunc then
|
||||
frame.OnEnterFunc = function(this) self:OnEnterProfessionButton(this) end
|
||||
end
|
||||
if not frame.OnLeaveFunc then
|
||||
frame.OnLeaveFunc = function() self:OnLeaveProfessionButton() end
|
||||
end
|
||||
|
||||
frame:SetScript("OnEnter", frame.OnEnterFunc)
|
||||
frame:SetScript("OnLeave", frame.OnLeaveFunc)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:OnMouseDown()
|
||||
function Breakables:GetSpellIdFromProfessionButton(btn)
|
||||
return (btn.type == BREAKABLE_HERB and MillingId)
|
||||
or (btn.type == BREAKABLE_ORE and ProspectingId)
|
||||
or (btn.type == BREAKABLE_DE and DisenchantId)
|
||||
or PickLockId
|
||||
end
|
||||
|
||||
function Breakables:ApplyScale()
|
||||
if not self.buttonFrame then
|
||||
return
|
||||
end
|
||||
self.frame:SetScale(self.settings.buttonScale)
|
||||
|
||||
for i=1,numEligibleProfessions do
|
||||
if self.breakableButtons[i] then
|
||||
for j=1,#self.breakableButtons[i] do
|
||||
self.breakableButtons[i][j].text:SetFont(NumberFont_Outline_Med:GetFont(), self.settings.fontSize, "OUTLINE")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:OnMouseDown(frame)
|
||||
if IsShiftKeyDown() then
|
||||
self.buttonFrame:StartMoving()
|
||||
frame:StartMoving()
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:OnMouseUp()
|
||||
self.buttonFrame:StopMovingOrSizing()
|
||||
function Breakables:OnMouseUp(frame)
|
||||
frame:StopMovingOrSizing()
|
||||
|
||||
local _, _, _, xOff, yOff = self.buttonFrame:GetPoint(1)
|
||||
self.settings.buttonFrameLeft = xOff
|
||||
self.settings.buttonFrameTop = yOff
|
||||
local frameNum = 1
|
||||
for i=1,numEligibleProfessions do
|
||||
if self.buttonFrame[i] == frame then
|
||||
frameNum = i
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
self.settings.buttonFrameLeft[frameNum] = frame:GetLeft()
|
||||
self.settings.buttonFrameTop[frameNum] = frame:GetTop()
|
||||
end
|
||||
|
||||
function Breakables:FindBreakables()
|
||||
function Breakables:FindBreakables(bag)
|
||||
if self.settings.hide then
|
||||
return
|
||||
end
|
||||
|
||||
if self.bCombat then
|
||||
self.bPendingUpdate = true
|
||||
return
|
||||
@ -247,100 +594,201 @@ function Breakables:FindBreakables()
|
||||
|
||||
local foundBreakables = {}
|
||||
local i=1
|
||||
local numBreakableStacks = 0
|
||||
local numBreakableStacks = {}
|
||||
|
||||
for bagId=0,NUM_BAG_SLOTS do
|
||||
local found = self:FindBreakablesInBag(bagId)
|
||||
for n=1,#found do
|
||||
local addedToExisting = self:MergeBreakables(found[n], foundBreakables)
|
||||
-- this is where i tried to throttle updates...can't just yet since the full breakables list is rebuilt every time this function is called
|
||||
-- consider ways of caching off the last-known state of all breakables
|
||||
--if bag == nil or bag == bagId then
|
||||
local found = self:FindBreakablesInBag(bagId)
|
||||
for n=1,#found do
|
||||
local addedToExisting = self:MergeBreakables(found[n], foundBreakables)
|
||||
|
||||
if not addedToExisting then
|
||||
foundBreakables[i] = found[n]
|
||||
i = i + 1
|
||||
if not addedToExisting then
|
||||
foundBreakables[i] = found[n]
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
--end
|
||||
end
|
||||
|
||||
self:SortBreakables(foundBreakables)
|
||||
|
||||
if not self.breakableButtons then
|
||||
self.breakableButtons = {}
|
||||
end
|
||||
|
||||
for i=1,#foundBreakables do
|
||||
local isDisenchantable = self:BreakableIsDisenchantable(foundBreakables[i][IDX_TYPE], foundBreakables[i][IDX_LEVEL])
|
||||
if (CanDisenchant and isDisenchantable) or foundBreakables[i][IDX_COUNT] >= 5 then
|
||||
if not self.breakableButtons then
|
||||
self.breakableButtons = {}
|
||||
for j=1,numEligibleProfessions do
|
||||
if not self.breakableButtons[j] then
|
||||
self.breakableButtons[j] = {}
|
||||
end
|
||||
|
||||
numBreakableStacks = numBreakableStacks + 1
|
||||
|
||||
if not self.breakableButtons[numBreakableStacks] then
|
||||
self.breakableButtons[numBreakableStacks] = CreateFrame("Button", "BreakablesButtonStackFrame"..numBreakableStacks, self.buttonFrame, "SecureActionButtonTemplate")
|
||||
end
|
||||
local btn = self.breakableButtons[numBreakableStacks]
|
||||
btn:SetPoint("LEFT", numBreakableStacks == 1 and self.buttonFrame or self.breakableButtons[numBreakableStacks - 1], "RIGHT")
|
||||
btn:SetWidth(40)
|
||||
btn:SetHeight(40)
|
||||
btn:EnableMouse(true)
|
||||
btn:RegisterForClicks("AnyUp")
|
||||
|
||||
local BreakableAbilityName = GetSpellInfo((foundBreakables[i][IDX_BREAKABLETYPE] == BREAKABLE_HERB and MillingId) or (foundBreakables[i][IDX_BREAKABLETYPE] == BREAKABLE_ORE and ProspectingId) or DisenchantId)
|
||||
btn:SetAttribute("type", "macro")
|
||||
btn:SetAttribute("macrotext", "/cast "..BreakableAbilityName.."\n/use "..foundBreakables[i][IDX_BAG].." "..foundBreakables[i][IDX_SLOT])
|
||||
|
||||
-- btn:SetAttribute("type1", "item")
|
||||
-- btn:SetAttribute("bag1", foundBreakables[i][IDX_BAG])
|
||||
-- btn:SetAttribute("slot1", foundBreakables[i][IDX_SLOT])
|
||||
|
||||
if not btn.text then
|
||||
btn.text = btn:CreateFontString()
|
||||
btn.text:SetPoint("BOTTOM", btn, "BOTTOM", 0, 2)
|
||||
end
|
||||
btn.text:SetFont("Fonts\\FRIZQT__.TTF", 11, "OUTLINE")
|
||||
|
||||
if not isDisenchantable then
|
||||
btn.text:SetText(foundBreakables[i][IDX_COUNT].." ("..(floor(foundBreakables[i][IDX_COUNT]/5))..")")
|
||||
if not numBreakableStacks[j] then
|
||||
numBreakableStacks[j] = 0
|
||||
end
|
||||
|
||||
btn:SetScript("OnEnter", function(this) self:OnEnterBreakableButton(this, foundBreakables[i]) end)
|
||||
btn:SetScript("OnLeave", function() self:OnLeaveBreakableButton(foundBreakables[i]) end)
|
||||
if foundBreakables[i][IDX_BREAKABLETYPE] == self.buttonFrame[j].type and numBreakableStacks[j] < self.settings.maxBreakablesToShow then
|
||||
local isDisenchantable = self:BreakableIsDisenchantable(foundBreakables[i][IDX_TYPE], foundBreakables[i][IDX_LEVEL])
|
||||
local isLockedItem = foundBreakables[i][IDX_BREAKABLETYPE] == BREAKABLE_PICK
|
||||
|
||||
if not btn.icon then
|
||||
btn.icon = btn:CreateTexture(nil, "BACKGROUND")
|
||||
end
|
||||
btn.icon:SetTexture(foundBreakables[i][IDX_TEXTURE])
|
||||
btn.icon:SetAllPoints(btn)
|
||||
if (CanDisenchant and isDisenchantable) or (CanPickLock and isLockedItem) or (foundBreakables[i][IDX_COUNT] >= 5) then
|
||||
numBreakableStacks[j] = numBreakableStacks[j] + 1
|
||||
local btnIdx = numBreakableStacks[j]
|
||||
|
||||
if numBreakableStacks >= self.settings.maxBreakablesToShow then
|
||||
break
|
||||
local btn = self.breakableButtons[j][btnIdx]
|
||||
if not self.breakableButtons[j][btnIdx] then
|
||||
self.breakableButtons[j][btnIdx] = CreateFrame("Button", "BREAKABLES_BUTTON"..j.."-"..btnIdx, self.buttonFrame[j], "SecureActionButtonTemplate")
|
||||
|
||||
btn = self.breakableButtons[j][btnIdx]
|
||||
|
||||
if lbfGroup then
|
||||
btn.icon = btn:CreateTexture(btn:GetName().."Icon", "BACKGROUND")
|
||||
end
|
||||
|
||||
btn:SetWidth(buttonSize)
|
||||
btn:SetHeight(buttonSize)
|
||||
btn:EnableMouse(true)
|
||||
btn:RegisterForClicks("AnyUp")
|
||||
|
||||
btn:SetAttribute("type", "spell")
|
||||
|
||||
if not btn.text then
|
||||
btn.text = btn:CreateFontString()
|
||||
btn.text:SetPoint("BOTTOM", btn, "BOTTOM", 0, 2)
|
||||
end
|
||||
btn.text:SetFont(NumberFont_Outline_Med:GetFont(), self.settings.fontSize, "OUTLINE")
|
||||
|
||||
if lbfGroup then
|
||||
lbfGroup:AddButton(btn)
|
||||
end
|
||||
end
|
||||
|
||||
local attachFrom = "LEFT"
|
||||
local attachTo = "RIGHT"
|
||||
if self.settings.growDirection then
|
||||
if self.settings.growDirection == 1 then -- left
|
||||
attachFrom = "RIGHT"
|
||||
attachTo = "LEFT"
|
||||
--elseif self.settings.growDirection == 2 then -- right
|
||||
elseif self.settings.growDirection == 3 then -- up
|
||||
attachFrom = "BOTTOM"
|
||||
attachTo = "TOP"
|
||||
elseif self.settings.growDirection == 4 then -- down
|
||||
attachFrom = "TOP"
|
||||
attachTo = "BOTTOM"
|
||||
end
|
||||
end
|
||||
|
||||
btn:ClearAllPoints()
|
||||
btn:SetPoint(attachFrom, btnIdx == 1 and self.buttonFrame[j] or self.breakableButtons[j][btnIdx - 1], attachTo)
|
||||
|
||||
if not isDisenchantable then
|
||||
local appendText = ""
|
||||
if not isLockedItem then
|
||||
appendText = " ("..(floor(foundBreakables[i][IDX_COUNT]/5))..")"
|
||||
end
|
||||
|
||||
btn.text:SetText(foundBreakables[i][IDX_COUNT] .. appendText)
|
||||
end
|
||||
|
||||
local BreakableAbilityName = GetSpellInfo((foundBreakables[i][IDX_BREAKABLETYPE] == BREAKABLE_HERB and MillingId)
|
||||
or (foundBreakables[i][IDX_BREAKABLETYPE] == BREAKABLE_ORE and ProspectingId)
|
||||
or (foundBreakables[i][IDX_BREAKABLETYPE] == BREAKABLE_DE and DisenchantId)
|
||||
or PickLockId)
|
||||
btn:SetAttribute("spell", BreakableAbilityName)
|
||||
|
||||
if isLockedItem then
|
||||
btn:SetAttribute("target-item")
|
||||
btn:SetAttribute("target-bag", foundBreakables[i][IDX_BAG])
|
||||
btn:SetAttribute("target-slot", foundBreakables[i][IDX_SLOT])
|
||||
else
|
||||
btn:SetAttribute("target-item", foundBreakables[i][IDX_NAME])
|
||||
btn:SetAttribute("target-bag")
|
||||
btn:SetAttribute("target-slot")
|
||||
end
|
||||
|
||||
if lbfGroup then
|
||||
btn.icon:SetTexture(foundBreakables[i][IDX_TEXTURE])
|
||||
else
|
||||
btn:SetNormalTexture(foundBreakables[i][IDX_TEXTURE])
|
||||
end
|
||||
btn.bag = foundBreakables[i][IDX_BAG]
|
||||
btn.slot = foundBreakables[i][IDX_SLOT]
|
||||
|
||||
if not btn.OnEnterFunc then
|
||||
btn.OnEnterFunc = function(this) self:OnEnterBreakableButton(this) end
|
||||
end
|
||||
if not btn.OnLeaveFunc then
|
||||
btn.OnLeaveFunc = function() self:OnLeaveBreakableButton() end
|
||||
end
|
||||
if not btn.PostClickedFunc then
|
||||
btn.PostClickedFunc = function(this) self:PostClickedBreakableButton(this) end
|
||||
end
|
||||
|
||||
btn:SetScript("OnEnter", btn.OnEnterFunc)
|
||||
btn:SetScript("OnLeave", btn.OnLeaveFunc)
|
||||
btn:SetScript("PostClick", btn.PostClickedFunc)
|
||||
|
||||
btn:Show()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self.breakableButtons and numBreakableStacks < #self.breakableButtons then
|
||||
for i=numBreakableStacks+1,#self.breakableButtons do
|
||||
self.breakableButtons[i].icon:SetTexture(nil)
|
||||
self.breakableButtons[i].text:SetText()
|
||||
self.breakableButtons[i]:EnableMouse(false)
|
||||
for i=1,numEligibleProfessions do
|
||||
if not numBreakableStacks[i] then
|
||||
numBreakableStacks[i] = 0
|
||||
end
|
||||
end
|
||||
|
||||
if self.buttonFrame then
|
||||
if numBreakableStacks == 0 and self.settings.hideIfNoBreakables then
|
||||
self.buttonFrame:Hide()
|
||||
else
|
||||
self.buttonFrame:Show()
|
||||
if self.breakableButtons[i] and numBreakableStacks[i] < #self.breakableButtons[i] then
|
||||
for j=numBreakableStacks[i]+1,#self.breakableButtons[i] do
|
||||
self.breakableButtons[i][j]:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
if self.buttonFrame[i] then
|
||||
if numBreakableStacks[i] == 0 and self.settings.hideIfNoBreakables then
|
||||
self.buttonFrame[i]:Hide()
|
||||
else
|
||||
self.buttonFrame[i]:Show()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:OnEnterBreakableButton(this, breakable)
|
||||
GameTooltip:SetOwner(this, "ANCHOR_BOTTOMLEFT")
|
||||
GameTooltip:SetBagItem(breakable[IDX_BAG], breakable[IDX_SLOT])
|
||||
function Breakables:OnEnterProfessionButton(btn)
|
||||
GameTooltip:SetOwner(btn, "ANCHOR_BOTTOMLEFT")
|
||||
GameTooltip:SetSpellByID(self:GetSpellIdFromProfessionButton(btn))
|
||||
|
||||
GameTooltip:AddLine(" ")
|
||||
GameTooltip:AddLine(L["Hold shift and left-click to drag the Breakables bar around."], 1, 1, 1, 1)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
|
||||
function Breakables:OnLeaveBreakableButton(breakable)
|
||||
function Breakables:OnLeaveProfessionButton()
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
function Breakables:OnEnterBreakableButton(this)
|
||||
GameTooltip:SetOwner(this, "ANCHOR_BOTTOMLEFT")
|
||||
GameTooltip:SetBagItem(this.bag, this.slot)
|
||||
|
||||
GameTooltip:AddLine(" ")
|
||||
GameTooltip:AddLine(L["You can click on this button to break this item without having to click on the profession button first."], 1, 1, 1, 1)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
|
||||
function Breakables:OnLeaveBreakableButton()
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
function Breakables:PostClickedBreakableButton(this)
|
||||
if this.type == BREAKABLE_HERB or this.type == BREAKABLE_ORE or this.type == BREAKABLE_DE then
|
||||
self.justClicked = true
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:FindBreakablesInBag(bagId)
|
||||
local foundBreakables = {}
|
||||
local i=1
|
||||
@ -371,11 +819,12 @@ function Breakables:FindBreakablesInSlot(bagId, slotId)
|
||||
local texture, itemCount, locked, quality, readable = GetContainerItemInfo(bagId, slotId)
|
||||
if texture then
|
||||
local itemLink = GetContainerItemLink(bagId, slotId)
|
||||
local _, _, itemRarity, itemLevel, _, itemType, itemSubType, _, _, itemTexture = GetItemInfo(itemLink)
|
||||
local itemName, _, itemRarity, itemLevel, _, itemType, itemSubType, _, _, itemTexture = GetItemInfo(itemLink)
|
||||
|
||||
self.myTooltip:SetBagItem(bagId, slotId)
|
||||
|
||||
if CanDisenchant and itemRarity and itemRarity >= RARITY_UNCOMMON and self:BreakableIsDisenchantable(itemType, itemLevel) then
|
||||
if CanDisenchant and itemRarity and itemRarity >= RARITY_UNCOMMON and itemRarity < RARITY_HEIRLOOM
|
||||
and self:BreakableIsDisenchantable(itemType, itemLevel) then
|
||||
local i = 1
|
||||
local soulbound = false
|
||||
for i=1,5 do
|
||||
@ -392,26 +841,86 @@ function Breakables:FindBreakablesInSlot(bagId, slotId)
|
||||
local shouldHideThisItem = self.settings.hideEqManagerItems and isInEquipmentSet
|
||||
|
||||
if (not soulbound or self.settings.showSoulbound) and not shouldHideThisItem then
|
||||
return {itemLink, itemCount, itemType, itemTexture, bagId, slotId, itemSubType, itemLevel, BREAKABLE_DE, soulbound}
|
||||
return {itemLink, itemCount, itemType, itemTexture, bagId, slotId, itemSubType, itemLevel, BREAKABLE_DE, soulbound, itemName}
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
local extraInfo = BreakablesTooltipTextLeft2:GetText()
|
||||
|
||||
if CanMill and (itemSubType == MillingItemSubType or itemSubType == MillingItemSecondarySubType) and extraInfo == ITEM_MILLABLE then
|
||||
return {itemLink, itemCount, itemType, itemTexture, bagId, slotId, itemSubType, itemLevel, BREAKABLE_HERB, false}
|
||||
local idx = 1
|
||||
local millable = false
|
||||
local prospectable = false
|
||||
for idx=1,5 do
|
||||
if _G["BreakablesTooltipTextLeft"..idx] then
|
||||
if _G["BreakablesTooltipTextLeft"..idx]:GetText() == ITEM_MILLABLE then
|
||||
millable = true
|
||||
break
|
||||
elseif _G["BreakablesTooltipTextLeft"..idx]:GetText() == ITEM_PROSPECTABLE then
|
||||
prospectable = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if CanProspect and itemSubType == ProspectingItemSubType and extraInfo == ITEM_PROSPECTABLE then
|
||||
return {itemLink, itemCount, itemType, itemTexture, bagId, slotId, itemSubType, itemLevel, BREAKABLE_ORE, false}
|
||||
if CanMill and (itemSubType == MillingItemSubType or itemSubType == MillingItemSecondarySubType) and millable then
|
||||
return {itemLink, itemCount, itemType, itemTexture, bagId, slotId, itemSubType, itemLevel, BREAKABLE_HERB, false, itemName}
|
||||
end
|
||||
|
||||
if CanProspect and itemSubType == ProspectingItemSubType and prospectable then
|
||||
return {itemLink, itemCount, itemType, itemTexture, bagId, slotId, itemSubType, itemLevel, BREAKABLE_ORE, false, itemName}
|
||||
end
|
||||
|
||||
if CanPickLock and self:ItemIsPickable(self:GetItemIdFromLink(itemLink)) and self:ItemIsLocked(bagId, slotId) then
|
||||
return {itemLink, itemCount, itemType, itemTexture, bagId, slotId, itemSubType, itemLevel, BREAKABLE_PICK, false, itemName}
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function Breakables:ItemIsPickable(itemId)
|
||||
for i=1,#PickableItems do
|
||||
if PickableItems[i] == itemId then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
do
|
||||
local regions = {}
|
||||
local tooltipBuffer = CreateFrame("GameTooltip","tooltipBuffer",nil,"GameTooltipTemplate")
|
||||
tooltipBuffer:SetOwner(WorldFrame, "ANCHOR_NONE")
|
||||
|
||||
local function makeTable(t, ...)
|
||||
wipe(t)
|
||||
for i = 1, select("#", ...) do
|
||||
t[i] = select(i, ...)
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:ItemIsLocked(bagId, slotId)
|
||||
tooltipBuffer:ClearLines()
|
||||
tooltipBuffer:SetBagItem(bagId, slotId)
|
||||
|
||||
-- Grab all regions, stuff em into our table
|
||||
makeTable(regions, tooltipBuffer:GetRegions())
|
||||
|
||||
-- Convert FontStrings to strings, replace anything else with ""
|
||||
for i=1, #regions do
|
||||
local region = regions[i]
|
||||
if region:GetObjectType() == "FontString" then
|
||||
if region:GetText() == LOCKED then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:IsInEquipmentSet(itemId)
|
||||
for setIdx=1, GetNumEquipmentSets() do
|
||||
local set = GetEquipmentSetInfo(setIdx)
|
||||
|
@ -1,13 +1,17 @@
|
||||
## Interface: 30300
|
||||
## Interface: 40300
|
||||
## Author: Parnic
|
||||
## Name: Breakables
|
||||
## Title: Breakables |cff7fff7f -Ace3-|r
|
||||
## Title: Breakables |cff7fff7f-Ace3-|r
|
||||
## Notes: Tracks herbs/ore/items that can be broken into component pieces
|
||||
## Version: @project-version@ (Revision: @project-revision@)
|
||||
## SavedVariables: BreakablesDB
|
||||
## OptionalDeps: Ace3, LibBabble-Inventory-3.0
|
||||
## X-Compatible-With: 40000
|
||||
## OptionalDeps: Ace3, LibBabble-Inventory-3.0, ButtonFacade
|
||||
|
||||
#@no-lib-strip@
|
||||
embeds.xml
|
||||
#@end-no-lib-strip@
|
||||
# LDB is hard-embedded so don't skip it if packaging no-lib
|
||||
LibDataBroker-1.1.lua
|
||||
loc\loc.xml
|
||||
|
||||
Breakables.lua
|
90
LibDataBroker-1.1.lua
Normal file
90
LibDataBroker-1.1.lua
Normal file
@ -0,0 +1,90 @@
|
||||
|
||||
assert(LibStub, "LibDataBroker-1.1 requires LibStub")
|
||||
assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0")
|
||||
|
||||
local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4)
|
||||
if not lib then return end
|
||||
oldminor = oldminor or 0
|
||||
|
||||
|
||||
lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib)
|
||||
lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {}
|
||||
local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks
|
||||
|
||||
if oldminor < 2 then
|
||||
lib.domt = {
|
||||
__metatable = "access denied",
|
||||
__index = function(self, key) return attributestorage[self] and attributestorage[self][key] end,
|
||||
}
|
||||
end
|
||||
|
||||
if oldminor < 3 then
|
||||
lib.domt.__newindex = function(self, key, value)
|
||||
if not attributestorage[self] then attributestorage[self] = {} end
|
||||
if attributestorage[self][key] == value then return end
|
||||
attributestorage[self][key] = value
|
||||
local name = namestorage[self]
|
||||
if not name then return end
|
||||
callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self)
|
||||
callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self)
|
||||
callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self)
|
||||
callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self)
|
||||
end
|
||||
end
|
||||
|
||||
if oldminor < 2 then
|
||||
function lib:NewDataObject(name, dataobj)
|
||||
if self.proxystorage[name] then return end
|
||||
|
||||
if dataobj then
|
||||
assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table")
|
||||
self.attributestorage[dataobj] = {}
|
||||
for i,v in pairs(dataobj) do
|
||||
self.attributestorage[dataobj][i] = v
|
||||
dataobj[i] = nil
|
||||
end
|
||||
end
|
||||
dataobj = setmetatable(dataobj or {}, self.domt)
|
||||
self.proxystorage[name], self.namestorage[dataobj] = dataobj, name
|
||||
self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj)
|
||||
return dataobj
|
||||
end
|
||||
end
|
||||
|
||||
if oldminor < 1 then
|
||||
function lib:DataObjectIterator()
|
||||
return pairs(self.proxystorage)
|
||||
end
|
||||
|
||||
function lib:GetDataObjectByName(dataobjectname)
|
||||
return self.proxystorage[dataobjectname]
|
||||
end
|
||||
|
||||
function lib:GetNameByDataObject(dataobject)
|
||||
return self.namestorage[dataobject]
|
||||
end
|
||||
end
|
||||
|
||||
if oldminor < 4 then
|
||||
local next = pairs(attributestorage)
|
||||
function lib:pairs(dataobject_or_name)
|
||||
local t = type(dataobject_or_name)
|
||||
assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)")
|
||||
|
||||
local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
|
||||
assert(attributestorage[dataobj], "Data object not found")
|
||||
|
||||
return next, attributestorage[dataobj], nil
|
||||
end
|
||||
|
||||
local ipairs_iter = ipairs(attributestorage)
|
||||
function lib:ipairs(dataobject_or_name)
|
||||
local t = type(dataobject_or_name)
|
||||
assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)")
|
||||
|
||||
local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
|
||||
assert(attributestorage[dataobj], "Data object not found")
|
||||
|
||||
return ipairs_iter, attributestorage[dataobj], 0
|
||||
end
|
||||
end
|
@ -6,6 +6,9 @@
|
||||
<Include file="libs\AceConfig-3.0\AceConfig-3.0.xml"/>
|
||||
<Include file="libs\AceConsole-3.0\AceConsole-3.0.xml"/>
|
||||
<Include file="libs\AceDB-3.0\AceDB-3.0.xml"/>
|
||||
<Include file="libs\AceDBOptions-3.0\AceDBOptions-3.0.xml"/>
|
||||
<Include file="libs\AceEvent-3.0\AceEvent-3.0.xml"/>
|
||||
<Include file="libs\AceLocale-3.0\AceLocale-3.0.xml"/>
|
||||
<Include file="libs\LibBabble-Inventory-3.0\lib.xml"/>
|
||||
<Include file="libs\LibButtonFacade\LibButtonFacade.xml"/>
|
||||
</Ui>
|
4
loc/deDE.lua
Normal file
4
loc/deDE.lua
Normal file
@ -0,0 +1,4 @@
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale("Breakables", "deDE")
|
||||
if not L then return end
|
||||
|
||||
--@localization(locale="deDE", format="lua_additive_table", handle-subnamespaces="concat", handle-unlocalized="english")@
|
15
loc/enUS.lua
Normal file
15
loc/enUS.lua
Normal file
@ -0,0 +1,15 @@
|
||||
local debug = false
|
||||
--@debug@
|
||||
debug = true
|
||||
--@end-debug@
|
||||
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale("Breakables", "enUS", true, debug)
|
||||
|
||||
--@localization(locale="enUS", format="lua_additive_table", same-key-is-true=true, handle-subnamespaces="concat")@
|
||||
--@debug@
|
||||
L["Welcome"] = [[Thanks for using |cff33ff99Breakables|r! Use |cffffff78/brk|r to open this menu or |cffffff78/breakables|r to access the same options on the command line.
|
||||
|
||||
Hold shift and drag the profession button to move the breakables bar around. You can also click directly on any breakable item button to break it without having to click the profession button first.
|
||||
|
||||
If you have any feature requests or problems, please email |cff33ff99breakables@parnic.com|r or visit the |cffffff78curse.com|r or |cffffff78wowinterface.com|r page and leave a comment.]]
|
||||
--@end-debug@
|
4
loc/esES.lua
Normal file
4
loc/esES.lua
Normal file
@ -0,0 +1,4 @@
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale("Breakables", "esES")
|
||||
if not L then return end
|
||||
|
||||
--@localization(locale="esES", format="lua_additive_table", handle-subnamespaces="concat", handle-unlocalized="english")@
|
4
loc/esMX.lua
Normal file
4
loc/esMX.lua
Normal file
@ -0,0 +1,4 @@
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale("Breakables", "esMX")
|
||||
if not L then return end
|
||||
|
||||
--@localization(locale="esMX", format="lua_additive_table", handle-subnamespaces="concat", handle-unlocalized="english")@
|
4
loc/frFR.lua
Normal file
4
loc/frFR.lua
Normal file
@ -0,0 +1,4 @@
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale("Breakables", "frFR")
|
||||
if not L then return end
|
||||
|
||||
--@localization(locale="frFR", format="lua_additive_table", handle-subnamespaces="concat", handle-unlocalized="english")@
|
4
loc/koKR.lua
Normal file
4
loc/koKR.lua
Normal file
@ -0,0 +1,4 @@
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale("Breakables", "koKR")
|
||||
if not L then return end
|
||||
|
||||
--@localization(locale="koKR", format="lua_additive_table", handle-subnamespaces="concat", handle-unlocalized="english")@
|
13
loc/loc.xml
Normal file
13
loc/loc.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd">
|
||||
|
||||
<Script file="enUS.lua"/>
|
||||
<Script file="deDE.lua"/>
|
||||
<Script file="esES.lua"/>
|
||||
<Script file="esMX.lua"/>
|
||||
<Script file="frFR.lua"/>
|
||||
<Script file="koKR.lua"/>
|
||||
<Script file="ruRU.lua"/>
|
||||
<Script file="zhCN.lua"/>
|
||||
<Script file="zhTW.lua"/>
|
||||
|
||||
</Ui>
|
4
loc/ruRU.lua
Normal file
4
loc/ruRU.lua
Normal file
@ -0,0 +1,4 @@
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale("Breakables", "ruRU")
|
||||
if not L then return end
|
||||
|
||||
--@localization(locale="ruRU", format="lua_additive_table", handle-subnamespaces="concat", handle-unlocalized="english")@
|
4
loc/zhCN.lua
Normal file
4
loc/zhCN.lua
Normal file
@ -0,0 +1,4 @@
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale("Breakables", "zhCN")
|
||||
if not L then return end
|
||||
|
||||
--@localization(locale="zhCN", format="lua_additive_table", handle-subnamespaces="concat", handle-unlocalized="english")@
|
4
loc/zhTW.lua
Normal file
4
loc/zhTW.lua
Normal file
@ -0,0 +1,4 @@
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale("Breakables", "zhTW")
|
||||
if not L then return end
|
||||
|
||||
--@localization(locale="zhTW", format="lua_additive_table", handle-subnamespaces="concat", handle-unlocalized="english")@
|
Reference in New Issue
Block a user