Compare commits

...

11 Commits
1.1 ... 1.2.1

Author SHA1 Message Date
1741f54321 - fix for reported error popping up 2010-10-12 12:45:33 +00:00
f93465037d - removed x-compat 2010-10-12 04:11:42 +00:00
f9971a7818 - toc bump to 4.0 2010-10-12 02:49:09 +00:00
59fd3c320d - fixed version of earlier commit that allows multiple breakable bars if the player has more than one of the supported professions.
- also added code to properly save the location of each bar independently
2010-10-07 01:04:43 +00:00
4bc72649f2 - drycode attempt at creating one bar per profession for the case where someone has some combination of inscription, enchanting, and jewelcrafting. not tested in game at all 2010-10-06 21:24:19 +00:00
4ad9afa103 - set bar to update immediately after clicking an item to break it instead of waiting the 1.5 seconds. it was making life harder for mass breaking 2010-09-27 02:51:50 +00:00
958521c6d3 - added button scale and font size options 2010-09-27 01:45:50 +00:00
1401893e2d - added localization support 2010-09-27 01:20:54 +00:00
f55cd76606 - optimized a little bit of the code that finds breakables in your bags by delaying checks on BAG_UPDATE until 1.5 seconds after the last update request has come in
- set the button font for item counts to use NumberFont_Outline_Med so that any font overrides (like tekticles) work automagically
2010-09-27 00:56:06 +00:00
6a89a7ca11 - added a tooltip to the LDB launcher 2010-09-21 03:49:35 +00:00
a5f5958c5e - added LibDataBroker support
- added option to hide the bar entirely (ticket 5) and option to hide the bar when in combat
- added short description to the config page explaining the functionality in the mod and how to get support/request features
- made all slash commands print something back to the user so they know what they changed
2010-09-12 20:25:17 +00:00
15 changed files with 545 additions and 113 deletions

View File

@ -28,6 +28,9 @@ 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

View File

@ -1,3 +1,4 @@
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()
@ -13,6 +14,7 @@ local CanProspect = false
local DisenchantId = 13262
local DisenchantTypes = {babbleInv["Armor"], babbleInv["Weapon"]}
local CanDisenchant = false
-- item rarity must meet or surpass this to be considered for disenchantability (is that a word?)
local RARITY_UNCOMMON = 2
@ -31,23 +33,78 @@ local BREAKABLE_HERB = 1
local BREAKABLE_ORE = 2
local BREAKABLE_DE = 3
local BagUpdateCheckDelay = 1.5
local nextCheck = {}
for i=0,NUM_BAG_SLOTS do
nextCheck[i] = -1
end
local buttonSize = 28
local _G = _G
-- can be 1 or 2
local numEligibleProfessions = 0
Breakables.optionsFrame = {}
Breakables.justClicked = false
function Breakables:OnInitialize()
self.defaults = {
profile = {
buttonFrameLeft = 100,
buttonFrameTop = -100,
buttonFrameLeft = {100, 100},
buttonFrameTop = {-100, -150},
hideIfNoBreakables = true,
maxBreakablesToShow = 5,
showSoulbound = false,
hideEqManagerItems = true,
hide = false,
hideInCombat = false,
buttonScale = 1,
fontSize = 7,
}
}
self.db = LibStub("AceDB-3.0"):New("BreakablesDB", self.defaults)
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: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()
@ -61,12 +118,44 @@ function Breakables:OnEnable()
self:RegisterEvents()
if CanMill or CanProspect or CanDisenchant then
if CanMill then
numEligibleProfessions = numEligibleProfessions + 1
end
if CanProspect then
numEligibleProfessions = numEligibleProfessions + 1
end
if CanDisenchant then
numEligibleProfessions = numEligibleProfessions + 1
end
self:CreateButtonFrame()
if self.settings.hide then
self:ToggleButtonFrameVisibility(false)
else
self:FindBreakables()
end
self.frame:SetScript("OnUpdate", function() self:CheckShouldFindBreakables() end)
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
@ -82,24 +171,49 @@ 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
@ -120,27 +234,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 +306,50 @@ 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,
},
},
}
@ -159,87 +357,142 @@ 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")
end
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", "BreakablesButtonFrame1", self.frame, "SecureActionButtonTemplate")
end
self.buttonFrame[i]:SetPoint("TOPLEFT", UIParent, "TOPLEFT", 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
self.buttonFrame[i].type = BREAKABLE_HERB
elseif CanDisenchant and (i == 1 or self.buttonFrame[1].type ~= BREAKABLE_DE) then
self.buttonFrame[i].type = BREAKABLE_DE
elseif CanProspect and (i == 1 or self.buttonFrame[1].type ~= BREAKABLE_ORE) then
self.buttonFrame[i].type = BREAKABLE_ORE
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 not self.buttonFrame[i].icon then
self.buttonFrame[i].icon = self.buttonFrame[i]:CreateTexture(nil, "BACKGROUND")
end
if self.buttonFrame[i].type then
self.buttonFrame[i]:SetWidth(buttonSize * self.settings.buttonScale)
self.buttonFrame[i]:SetHeight(buttonSize * self.settings.buttonScale)
local spellName, _, texture = GetSpellInfo((CanMill and MillingId) or (CanProspect and ProspectingId) or DisenchantId)
self.buttonFrame[i]:EnableMouse(true)
self.buttonFrame[i]:RegisterForClicks("LeftButtonUp")
self.buttonFrame:SetAttribute("type1", "spell")
self.buttonFrame:SetAttribute("spell1", spellName)
self.buttonFrame[i]:SetMovable(true)
self.buttonFrame[i]:RegisterForDrag("LeftButton")
self.buttonFrame[i]:SetScript("OnMouseDown", function(frame) self:OnMouseDown(frame) end)
self.buttonFrame[i]:SetScript("OnMouseUp", function(frame) self:OnMouseUp(frame) end)
self.buttonFrame[i]:SetClampedToScreen(true)
self.buttonFrame.icon:SetTexture(texture)
self.buttonFrame.icon:SetAllPoints(self.buttonFrame)
else
self.buttonFrame:SetTexture(nil)
local spellName, _, texture = GetSpellInfo((self.buttonFrame[i].type == BREAKABLE_HERB and MillingId) or (self.buttonFrame[i].type == BREAKABLE_ORE and ProspectingId) or DisenchantId)
self.buttonFrame[i]:SetAttribute("type1", "spell")
self.buttonFrame[i]:SetAttribute("spell1", spellName)
self.buttonFrame[i].icon:SetTexture(texture)
self.buttonFrame[i].icon:SetAllPoints(self.buttonFrame[i])
else
self.buttonFrame[i]:SetTexture(nil)
end
end
end
function Breakables:OnMouseDown()
function Breakables:ApplyScale()
if not self.buttonFrame then
return
end
for i=1,numEligibleProfessions do
-- yes, setscale exists...but it was scaling buttonFrame and breakableButtons differently for some reason. this works better.
self.buttonFrame[i]:SetWidth(buttonSize * self.settings.buttonScale)
self.buttonFrame[i]:SetHeight(buttonSize * self.settings.buttonScale)
if self.breakableButtons[i] then
for j=1,#self.breakableButtons[i] do
self.breakableButtons[i][j]:SetWidth(buttonSize * self.settings.buttonScale)
self.breakableButtons[i][j]:SetHeight(buttonSize * self.settings.buttonScale)
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
local _, _, _, xOff, yOff = frame:GetPoint(1)
self.settings.buttonFrameLeft[frameNum] = xOff
self.settings.buttonFrameTop[frameNum] = yOff
end
function Breakables:FindBreakables()
function Breakables:FindBreakables(bag)
if self.settings.hide then
return
end
if self.bCombat then
self.bPendingUpdate = true
return
@ -247,87 +500,110 @@ 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])
if (CanDisenchant and isDisenchantable) or foundBreakables[i][IDX_COUNT] >= 5 then
numBreakableStacks[j] = numBreakableStacks[j] + 1
if not btn.icon then
btn.icon = btn:CreateTexture(nil, "BACKGROUND")
end
btn.icon:SetTexture(foundBreakables[i][IDX_TEXTURE])
btn.icon:SetAllPoints(btn)
local btn = self.breakableButtons[j][numBreakableStacks[j]]
if not self.breakableButtons[j][numBreakableStacks[j]] then
self.breakableButtons[j][numBreakableStacks[j]] = CreateFrame("Button", nil, self.buttonFrame[j], "SecureActionButtonTemplate")
if numBreakableStacks >= self.settings.maxBreakablesToShow then
break
btn = self.breakableButtons[j][numBreakableStacks[j]]
btn:SetPoint("LEFT", numBreakableStacks[j] == 1 and self.buttonFrame[j] or self.breakableButtons[j][numBreakableStacks[j] - 1], "RIGHT")
btn:SetWidth(buttonSize * self.settings.buttonScale)
btn:SetHeight(buttonSize * self.settings.buttonScale)
btn:EnableMouse(true)
btn:RegisterForClicks("AnyUp")
btn:SetAttribute("type", "macro")
-- 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(NumberFont_Outline_Med:GetFont(), self.settings.fontSize, "OUTLINE")
if not btn.icon then
btn.icon = btn:CreateTexture(nil, "BACKGROUND")
end
btn.icon:SetAllPoints(btn)
end
if not isDisenchantable then
btn.text:SetText(foundBreakables[i][IDX_COUNT].." ("..(floor(foundBreakables[i][IDX_COUNT]/5))..")")
end
local BreakableAbilityName = GetSpellInfo((foundBreakables[i][IDX_BREAKABLETYPE] == BREAKABLE_HERB and MillingId) or (foundBreakables[i][IDX_BREAKABLETYPE] == BREAKABLE_ORE and ProspectingId) or DisenchantId)
btn:SetAttribute("macrotext", "/cast "..BreakableAbilityName.."\n/use "..foundBreakables[i][IDX_BAG].." "..foundBreakables[i][IDX_SLOT].."\n/script Breakables.justClicked=true")
btn.icon:SetTexture(foundBreakables[i][IDX_TEXTURE])
btn:SetScript("OnEnter", function(this) self:OnEnterBreakableButton(this, foundBreakables[i]) end)
btn:SetScript("OnLeave", function() self:OnLeaveBreakableButton(foundBreakables[i]) end)
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()
self.breakableButtons[i][j].icon:SetTexture(nil)
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

View File

@ -1,13 +1,17 @@
## Interface: 30300
## Interface: 40000
## 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
#@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
View 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

View File

@ -7,5 +7,6 @@
<Include file="libs\AceConsole-3.0\AceConsole-3.0.xml"/>
<Include file="libs\AceDB-3.0\AceDB-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"/>
</Ui>

4
loc/deDE.lua Normal file
View 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")@

13
loc/enUS.lua Normal file
View File

@ -0,0 +1,13 @@
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. 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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")@