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.

2975 lines
98 KiB

4 years ago
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster_Crafting --
-- http://www.curse.com/addons/wow/tradeskillmaster_crafting --
-- --
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
-- All Rights Reserved* - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
-- create a local reference to the TradeSkillMaster_Crafting table and register a new module
local TSM = select(2, ...)
local GUI = TSM:NewModule("CraftingGUI", "AceEvent-3.0", "AceHook-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster_Crafting") -- loads the localization table
local priceTextCache = { lastClear = 0 }
local private = {}
private.gather = {}
private.shown = {}
private.eventObj = nil
4 years ago
-- list of profession skills that do not have crafting. used by UpdateTradeSkills
local invalidTrade = {
["Herbalism"] = true,
["Skinning"] = true,
["Fishing"] = true,
["Riding"] = true
}
4 years ago
-- Helper function to find spellID associated to spellname
local function GetTradeSkillSpellID(spellName)
-- GetTradeSkillRecipeLink ONLY works when a trade skill window is open, but this should always happen
for i = 1,GetNumTradeSkills() do
local link = GetTradeSkillRecipeLink(i)
if link and link:match(spellName) then -- Not a header and spell name found
local spellID = tonumber(link:match("enchant:(%d+)"))
if spellID then
return spellID
end
end
end
return nil
end
function GUI:OnEnable()
GUI:RegisterEvent("TRADE_SKILL_SHOW", "ShowProfessionWindow")
GUI:RegisterEvent("TRADE_SKILL_CLOSE", "EventHandler")
GUI:RegisterEvent("TRADE_SKILL_UPDATE", "EventHandler")
GUI:RegisterEvent("TRADE_SKILL_FILTER_UPDATE", "EventHandler")
GUI:RegisterEvent("UPDATE_TRADESKILL_RECAST", "EventHandler")
GUI:RegisterEvent("CHAT_MSG_SKILL", "EventHandler")
GUI:RegisterEvent("UNIT_SPELLCAST_START", "EventHandler")
4 years ago
GUI:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED", "EventHandler")
GUI:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED", "EventHandler")
GUI:RegisterEvent("UNIT_SPELLCAST_FAILED", "EventHandler")
GUI:RegisterEvent("GUILDBANKFRAME_OPENED", "GatheringEventHandler")
GUI:RegisterEvent("GUILDBANKFRAME_CLOSED", "GatheringEventHandler")
GUI:RegisterEvent("GUILDBANKBAGSLOTS_CHANGED", "GatheringEventHandler")
GUI:RegisterEvent("MERCHANT_SHOW", "GatheringEventHandler")
GUI:RegisterEvent("MERCHANT_UPDATE", "GatheringEventHandler")
GUI:RegisterEvent("MERCHANT_CLOSED", "GatheringEventHandler")
GUI:RegisterEvent("MAIL_SHOW", "GatheringEventHandler")
GUI:RegisterEvent("MAIL_CLOSED", "GatheringEventHandler")
GUI:RegisterEvent("BANKFRAME_OPENED", "GatheringEventHandler")
GUI:RegisterEvent("BANKFRAME_CLOSED", "GatheringEventHandler")
GUI:RegisterEvent("UPDATE_PENDING_MAIL", "GatheringEventHandler")
GUI:RegisterEvent("AUCTION_HOUSE_SHOW", "GatheringEventHandler")
GUI:RegisterEvent("AUCTION_HOUSE_CLOSED", "GatheringEventHandler")
GUI:RegisterEvent("MAIL_INBOX_UPDATE", "QueueUpdateHandler")
4 years ago
TSMAPI:CreateTimeDelay("craftingUpdateTradeSkill", 1, function() GUI:UpdateSelectedTradeSkill() end, 0.1)
TSMAPI:RegisterForBagChange(function()
TSMAPI:CreateTimeDelay("craftingProfessionUpdateThrottle", 0.05, GUI.UpdateProfessionsTabST)
TSMAPI:CreateTimeDelay("craftingQueueUpdateThrottle", 0.1, GUI.UpdateQueue)
TSMAPI:CreateTimeDelay("gatheringUpdateThrottle", 0.3, GUI.UpdateGathering)
end)
TSMAPI:RegisterForBankChange(function()
TSMAPI:CreateTimeDelay("gatheringUpdateThrottle", 0.3, GUI.UpdateGathering)
end)
private.eventObj = private.eventObj or TSMAPI:GetEventObject()
private.eventObj:SetCallback("TSM:AUCTIONCONTROL:ITEMBOUGHT", private.OnAuctionBought)
4 years ago
GUI:UpdateTradeSkills()
GUI.gatheringFrame = GUI:CreateGatheringFrame()
if next(TSM.db.realm.gathering.neededMats) then
4 years ago
TSMAPI:CreateTimeDelay("gatheringShowThrottle", 0.3, GUI:ShowGatheringFrame())
end
end
function private.OnAuctionBought()
if not GUI.frame or not GUI.frame:IsVisible() then return end
TSMAPI:CreateTimeDelay("craftingQueueUpdateThrottle", 0.1, GUI.UpdateQueue)
TSMAPI:CreateTimeDelay("craftingProfessionUpdateThrottle", 0.2, GUI.UpdateProfessionsTabST)
end
function GUI:QueueUpdateHandler()
if not GUI.frame or not GUI.frame:IsVisible() then return end
TSMAPI:CreateTimeDelay("craftingQueueUpdateThrottle", 0.1, GUI.UpdateQueue)
TSMAPI:CreateTimeDelay("craftingProfessionUpdateThrottle", 0.2, GUI.UpdateProfessionsTabST)
end
4 years ago
function GUI:ShowGatheringFrame()
if GUI.gatheringFrame then
GUI.gatheringFrame:Show()
if AuctionFrame and AuctionFrame:IsVisible() then
GUI:GatheringEventHandler("AUCTION_HOUSE_SHOW")
elseif BankFrame and BankFrame:IsVisible() then
GUI:GatheringEventHandler("BANKFRAME_OPENED")
elseif MerchantFrame and MerchantFrame:IsVisible() then
GUI:GatheringEventHandler("MERCHANT_SHOW")
elseif GuildBankFrame and GuildBankFrame:IsVisible() then
GUI:GatheringEventHandler("GUILDBANKFRAME_OPENED")
end
GUI:UpdateGathering()
end
end
function GUI:ShowProfessionWindow()
if not TradeSkillFrame and not AscensionTradeSkillFrame then return TSMAPI:CreateTimeDelay("craftingShowProfessionDelay", 0, GUI.ShowProfessionWindow) end
4 years ago
-- if GetTradeSkillLine() == GetSpellInfo(53428) or IsTradeSkillGuild() then
if GetTradeSkillLine() == GetSpellInfo(53428) then
-- runeforging or guild profession
if GUI.frame then
GUI.noClose = true
GUI.frame:Hide()
GUI.noClose = nil
end
if GUI.switchBtn then
GUI.switchBtn:Hide()
end
return
end
TradeSkillFrame:UnregisterEvent("TRADE_SKILL_SHOW")
-- AscensionTradeSkillFrame:UnregisterEvent("TRADE_SKILL_SHOW")
-- AscensionTradeSkillFrame:OpenOldUI()
4 years ago
GUI:ShowSwitchButton()
if TSM.db.global.showingDefaultFrame then return end
GUI:UpdateTradeSkills(GetTradeSkillLine())
4 years ago
TradeSkillFrame:SetScript("OnHide", nil)
HideUIPanel(TradeSkillFrame)
TradeSkillFrame:SetScript("OnHide", function()
if not GUI.noClose and not GUI.switchingProfession then
GUI.switchBtn:Hide()
CloseTradeSkill()
end
end)
4 years ago
priceTextCache.lastClear = 0
GUI.switchBtn:Update()
if not GUI.frame then
GUI:CreateGUI()
if TSM.isSyncing then
GUI.frame:Hide()
return TSMAPI:CreateTimeDelay("craftingSyncDelay", 0.1, function() TSM.Sync:OpenTradeSkill() end)
end
elseif GUI.frame:IsVisible() then
if TSM.isSyncing then
GUI.frame:Hide()
TSMAPI:CreateTimeDelay("craftingSyncDelay", 0.1, function() TSM.Sync:OpenTradeSkill() end)
elseif not IsTradeSkillLinked() then
GUI:SaveFilters()
GUI:ClearFilters()
GUI.frame.content.professionsTab.linkBtn:Enable()
TSMAPI:CreateTimeDelay("craftingScanDelay", 0.1, TSM.Util.ScanCurrentProfession)
else
GUI.frame.content.professionsTab.linkBtn:Disable()
end
return
end
if TSM.isSyncing then
TSMAPI:CreateTimeDelay("craftingScanDelay", 0, TSM.Util.StartScanSyncedProfessionThread)
else
GUI.frame:Show()
GUI:ShowProfessionsTab()
end
if not IsTradeSkillLinked() then
GUI:SaveFilters()
GUI:ClearFilters()
GUI.frame.content.professionsTab.linkBtn:Enable()
TSMAPI:CreateTimeDelay("craftingScanDelay", 0.1, TSM.Util.ScanCurrentProfession)
elseif not TSM.isSyncing then
GUI.frame.content.professionsTab.linkBtn:Disable()
end
end
function GUI:OpenFirstProfession()
TSM.db.global.showingDefaultFrame = nil
local link
for playerName, professions in pairs(TSM.db.realm.tradeSkills) do
4 years ago
for _, data in pairs(professions) do
link = data.link
if link then break end
end
if link then break end
end
if not link then return end
local tradeString = strsub(select(3, ("|"):split(link)), 2)
SetItemRef(tradeString, link, "LeftButton", ChatFrame1)
end
function GUI:EventHandler(event, ...)
if not GUI.frame or not GUI.frame:IsVisible() then return end
local unittest = ...
4 years ago
if unittest == "player" or unittest==nil then --Changing tradeskill frames and stuff has "nil" unit, when other players cast this also triggers with nil
if event == "TRADE_SKILL_CLOSE" then
if GUI.switchingProfession then return end
4 years ago
GUI.frame:Hide()
elseif event == "TRADE_SKILL_UPDATE" or event == "TRADE_SKILL_FILTER_UPDATE" then
if GetTradeSkillLine() ~= GUI.currentTradeSkill or select(2, IsTradeSkillLinked()) ~= GUI.currentLinkedPlayer then
StopTradeSkillRepeat()
GUI.currentTradeSkill = GetTradeSkillLine()
GUI.currentLinkedPlayer = select(2, IsTradeSkillLinked())
end
GUI.frame.content.professionsTab:UpdateProfession()
if (event ~= "TRADE_SKILL_FILTER_UPDATE") and (GetTradeSkillSelectionIndex() > 1) and (GetTradeSkillSelectionIndex() <= GetNumTradeSkills()) then
TradeSkillFrame_SetSelection(GetTradeSkillSelectionIndex())
else
TradeSkillFrame_SetSelection(GetFirstTradeSkill())
end
TradeSkillFrame_Update()
TSMAPI:CreateTimeDelay("craftingProfessionUpdateThrottle", 0.2, GUI.UpdateProfessionsTabST)
TSMAPI:CreateTimeDelay("craftingQueueUpdateThrottle", 0.2, GUI.UpdateQueue)
if not private.shown[GetTradeSkillLine()] then
TSMAPI:CreateTimeDelay("firstTimeCraftingProfessionUpdateThrottle", 0.5, GUI.UpdateProfessionsTabST)
private.shown[GetTradeSkillLine()] = true
end
elseif event == "UPDATE_TRADESKILL_RECAST" then
GUI.frame.content.professionsTab.craftInfoFrame.buttonsFrame.inputBox:SetNumber(GetTradeskillRepeatCount())
elseif event == "CHAT_MSG_SKILL" and not IsTradeSkillLinked() then
local skillName, level, maxLevel = GetTradeSkillLine()
if skillName and skillName ~= "UNKNOWN" and TSM.db.realm.tradeSkills[UnitName("player")] and TSM.db.realm.tradeSkills[UnitName("player")][skillName] then
TSM.db.realm.tradeSkills[UnitName("player")][skillName].level = level
TSM.db.realm.tradeSkills[UnitName("player")][skillName].maxLevel = maxLevel
4 years ago
end
elseif event == "UNIT_SPELLCAST_START" then
local unit = ...
if unit ~= "player" then return end
TSM.currentspell = UnitCastingSpellID("player")
4 years ago
elseif event == "UNIT_SPELLCAST_SUCCEEDED" then
-- we only care about our spells
local unit = ...
if unit ~= "player" then return end
-- if spell is not related to crafting, ignore
local craft = TSM.currentspell and TSM.db.realm.crafts[TSM.currentspell]
if not craft then return end
4 years ago
-- if spellID == nil then
-- TSM:Printf("Could not find spellID for %s", spellName)
-- end
4 years ago
-- decrements the number of this craft that are queued to be crafted
craft.queued = craft.queued - 1
if GUI.isCrafting and GUI.isCrafting.quantity > 0 then
GUI.isCrafting.quantity = GUI.isCrafting.quantity - 1
if GUI.isCrafting.quantity == 0 then
--GUI:UpdateQueue()
end
end
-- no longer casting a spell so discard spellID
TSM.currentspell = nil
4 years ago
-- TSMAPI:CreateTimeDelay("craftingQueueUpdateThrottle", 0.2, GUI.UpdateQueue)
elseif event == "UNIT_SPELLCAST_INTERRUPTED" or event == "UNIT_SPELLCAST_FAILED" then
local unit = ...
if unit ~= "player" then return end
4 years ago
-- if spellID == nil then
-- TSM:Printf("Could not find spellID for %s", spellName)
-- end
if GUI.isCrafting and TSM.currentspell == GUI.isCrafting.spellID then
4 years ago
GUI.isCrafting.quantity = 0
TSMAPI:CreateTimeDelay("craftingQueueUpdateThrottle", 0.2, GUI.UpdateQueue)
end
-- no longer casting a spell so discard spellID
TSM.currentspell = nil
end
4 years ago
end
end
function GUI:UpdateTradeSkills(...)
-- Get player name
local playerName = UnitName("player")
if not playerName then return end
4 years ago
local filterTrade = ... -- only re-index the specific trade skill if told to
4 years ago
local inProfessions = false
local inSecondary = false
local old = TSM.db.realm.tradeSkills[playerName]
4 years ago
TSM.db.realm.tradeSkills[playerName] = TSM.db.realm.tradeSkills[playerName] or {} -- initialize player data if not found
4 years ago
-- for each trade skill found, add it to the db
for i = 1, GetNumSkillLines() do
local skillName, _, _, skillRank, _, _, skillMaxRank = GetSkillLineInfo(i)
if skillName == "Professions" then
inProfessions = true
elseif skillName == "Secondary Skills" then
inProfessions = false
inSecondary = true
elseif skillName == "Weapon Skills" then
inSecondary = false
elseif inProfessions == true or inSecondary == true then
if skillName ~= nil and (not filterTrade or filterTrade == skillName) and not invalidTrade[skillName] then
-- if skillName == "Mining" then skillName = "Smelting" end -- bandaid for mining as related spell is different than craft
TSM.db.realm.tradeSkills[playerName][skillName] = old[skillName] or {}
TSM.db.realm.tradeSkills[playerName][skillName].level = skillRank
TSM.db.realm.tradeSkills[playerName][skillName].maxLevel = skillMaxRank
TSM.db.realm.tradeSkills[playerName][skillName].isSecondary = inSecondary
4 years ago
-- local spellBookSlot = btns[i]:GetID() + btns[i]:GetParent().spellOffset
local _, link = GetSpellLink(skillName)
if link then
TSM.db.realm.tradeSkills[playerName][skillName].link = link
if skillName == GetTradeSkillLine() and inProfessions == true and not TSM.isSyncing then
TSM.db.realm.tradeSkills[playerName][skillName].account = nil
TSM.db.realm.tradeSkills[playerName][skillName].accountKey = TSMAPI.Sync:GetAccountKey()
4 years ago
TSM.Sync:BroadcastTradeSkillData()
end
end
end
end
4 years ago
end
4 years ago
--tidy up crafts if player unlearned a profession
for spellid, data in pairs(TSM.db.realm.crafts) do
4 years ago
for player in pairs(data.players) do
if not TSM.db.realm.tradeSkills[player] or not TSM.db.realm.tradeSkills[player][data.profession] then
TSM.db.realm.crafts[spellid].players[player] = nil
4 years ago
end
end
end
--remove craft if no players
for spellid, data in pairs(TSM.db.realm.crafts) do
4 years ago
if not next(data.players) then
TSM.db.realm.crafts[spellid] = nil
4 years ago
end
end
end
function GUI:SaveFilters()
local filters = {}
filters.search = GetTradeSkillItemNameFilter()
filters.headers = {}
local hasHeaderCollapsed
for i = 1, GetNumTradeSkills() do
local name, t, _, e = GetTradeSkillInfo(i)
if t == "header" or t == "subheader" then
filters.headers[name] = e
if not e then
hasHeaderCollapsed = true
end
end
end
if not hasHeaderCollapsed then
filters.headers = nil
end
private.professionFilters = filters
end
function GUI:RestoreFilters()
if not private.professionFilters then return end
GUI:ClearFilters()
SetTradeSkillItemNameFilter(private.professionFilters.search)
if private.professionFilters.headers then
for i = 1, GetNumTradeSkills() do
local name, t, _, e = GetTradeSkillInfo(i)
if t == "header" or t == "subheader" then
if private.professionFilters.headers[name] ~= e then
if private.professionFilters.headers[name] then
ExpandTradeSkillSubClass(i)
else
CollapseTradeSkillSubClass(i)
end
end
end
end
end
if private.professionFilters.search then
GUI.frame.content.professionsTab.searchBar:SetTextColor(1, 1, 1, 1)
GUI.frame.content.professionsTab.searchBar:SetText(private.professionFilters.search)
else
GUI.frame.content.professionsTab.searchBar:SetTextColor(1, 1, 1, 0.5)
GUI.frame.content.professionsTab.searchBar:SetText(SEARCH)
end
GUI.frame.content.professionsTab.searchBar:ClearFocus()
end
function GUI:ClearFilters()
-- close the dropdown and uncheck the buttons
CloseDropDownMenus()
-- local id = TradeSkillLinkDropDown:GetID()
-- local id = 1
-- local skillupButton = _G["DropDownList" .. id .. "Button1"]
-- local makeableButton = _G["DropDownList" .. id .. "Button2"]
-- if skillupButton and skillupButton.checked and skillupButton.value == CRAFT_IS_MAKEABLE then
-- UIDropDownMenuButton_OnClick(_G["DropDownList" .. id .. "Button1"])
-- end
-- if makeableButton and makeableButton.checked and makeableButton.value == TRADESKILL_FILTER_HAS_SKILL_UP then
-- UIDropDownMenuButton_OnClick(_G["DropDownList" .. id .. "Button2"])
-- end
-- TradeSkillOnlyShowMakeable(false)
-- TradeSkillOnlyShowSkillUps(false)
SetTradeSkillInvSlotFilter(0,1,1)
SetTradeSkillSubClassFilter(0,1,1)
GUI.frame.content.professionsTab.HaveMatsCheckBox:SetValue(false)
TradeSkillFrameAvailableFilterCheckButton:SetChecked(false)
TradeSkillOnlyShowMakeable(false)
4 years ago
TradeSkillFrame_Update()
-- TradeSkillSetFilter(-1, -1)
SetTradeSkillItemNameFilter("")
ExpandTradeSkillSubClass(0)
for i = 1, GetNumTradeSkills() do
local _, t, _, e = GetTradeSkillInfo(i)
if not e and (t == "header" or t == "subheader") then
ExpandTradeSkillSubClass(i)
end
end
GUI.frame.content.professionsTab.searchBar:SetTextColor(1, 1, 1, 0.5)
GUI.frame.content.professionsTab.searchBar:SetText(SEARCH)
GUI.frame.content.professionsTab.searchBar:ClearFocus()
end
function GUI:CastTradeSkill(index, quantity, vellum)
SelectTradeSkill(index)
quantity = vellum and 1 or quantity
DoTradeSkill(index, quantity)
GUI.isCrafting = { quantity = quantity, spellID = TSM.Util:GetSpellID(index) }
if vellum then
UseItemByName(vellum)
end
end
function GUI:ShowSwitchButton()
if not GUI.switchBtn then
local btn = TSMAPI.GUI:CreateButton(UIParent, 16)
btn:SetText(TSMAPI.Design:GetInlineColor("link") .. DEFAULT .. "|r")
btn.Update = function(self)
self:Show()
if TSM.db.global.showingDefaultFrame then
self:SetParent(TradeSkillFrame)
self:SetPoint("TOPLEFT", 55, -3)
self:SetWidth(60)
self:SetHeight(18)
self:SetText(TSMAPI.Design:GetInlineColor("link") .. "TSM|r")
else
if not GUI.frame then return TSMAPI:CreateTimeDelay("craftingSwitchBtn", 0.05, function() self:Update() end) end
self:SetParent(GUI.frame)
self:SetPoint("TOPLEFT", 4, -4)
self:SetWidth(60)
self:SetHeight(18)
self:SetText(TSMAPI.Design:GetInlineColor("advanced") .. DEFAULT .. "|r")
end
end
btn:SetScript("OnClick", function(self)
GUI.noClose = true
if TSM.db.global.showingDefaultFrame then
TSM.db.global.showingDefaultFrame = nil
GUI:ShowProfessionWindow()
else
TSM.db.global.showingDefaultFrame = true
ShowUIPanel(TradeSkillFrame)
GUI.frame:Hide()
end
GUI.noClose = nil
btn:Update()
end)
GUI.switchBtn = btn
end
GUI.switchBtn:Show()
GUI.switchBtn:Update()
end
function GUI:CreateGUI()
local frameDefaults = {
x = 100,
y = 300,
width = 520,
4 years ago
height = 500,
scale = 1,
}
local frame = TSMAPI:CreateMovableFrame("TSMCraftingTradeSkillFrame", frameDefaults)
frame:SetResizable(true)
frame:SetMinResize(520, 400)
4 years ago
TSMAPI.Design:SetFrameBackdropColor(frame)
frame:Show()
frame:SetScript("OnHide", function() if not GUI.noClose then GUI.switchBtn:Hide() TradeSkillFrame:Show() CloseTradeSkill() end end)
tinsert(UISpecialFrames, "TSMCraftingTradeSkillFrame")
GUI.frame = frame
frame.prompt = GUI:CreatePromptFrame(frame)
frame.queue = GUI:CreateQueueFrame(frame)
frame.queue:Hide()
frame.gather = GUI:CreateGatheringSelectionFrame(frame)
frame.gather:Hide()
GUI:UpdateGatherSelectionWindow()
frame.navFrame = GUI:CreateNavFrame(frame)
TSMAPI.GUI:CreateHorizontalLine(frame, -55)
local content = CreateFrame("Frame", nil, frame)
content:SetPoint("TOPLEFT", 0, -59)
content:SetPoint("BOTTOMRIGHT")
frame.content = content
local line = TSMAPI.GUI:CreateVerticalLine(frame, 0)
line:ClearAllPoints()
line:SetPoint("TOPRIGHT", -25, -1)
line:SetWidth(2)
line:SetHeight(25)
local closeBtn = TSMAPI.GUI:CreateButton(frame, 18)
closeBtn:SetPoint("TOPRIGHT", -3, -3)
closeBtn:SetWidth(19)
closeBtn:SetHeight(19)
closeBtn:SetText("X")
closeBtn:SetScript("OnClick", function() frame:Hide() end)
frame.closeBtn = closeBtn
content.professionsTab = GUI:CreateProfessionsTab(content)
content.groupsTab = GUI:CreateGroupsTab(content)
end
function GUI:CreateQueueFrame(parent)
local frame = CreateFrame("Frame", nil, parent)
frame:SetPoint("TOPLEFT", parent, "TOPRIGHT", 2, 0)
frame:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", 2, 0)
frame:SetWidth(300)
frame:EnableMouse(true)
frame:SetScript("OnMouseDown", function() parent:StartMoving() end)
frame:SetScript("OnMouseUp", function() parent:StopMovingOrSizing() end)
TSMAPI.Design:SetFrameBackdropColor(frame)
local stContainer = CreateFrame("Frame", nil, frame)
stContainer:SetPoint("TOPLEFT", 5, -5)
stContainer:SetPoint("BOTTOMRIGHT", frame, "RIGHT", -5, 5)
TSMAPI.Design:SetFrameColor(stContainer)
local stCols = {
{ name = L["Craft Queue"], width = 1, align = "Left" },
}
local function OnCraftRowEnter(self, data)
if not data.spellID then return end
local color
local totalProfit
local moneyCoinsTooltip = TSMAPI:GetMoneyCoinsTooltip()
if data.profit then
totalProfit = data.numQueued * data.profit
if data.profit < 0 then
color = "|cffff0000"
else
color = "|cff00ff00"
end
4 years ago
end
GameTooltip:SetOwner(self, "ANCHOR_NONE")
-- GameTooltip:SetPoint("LEFT", self, "RIGHT")
GameTooltip:SetPoint("LEFT", self, "LEFT")
GameTooltip:AddLine(TSM.db.realm.crafts[data.spellID].name .. " (x" .. data.numQueued .. ")")
local cost = TSM.Cost:GetCraftPrices(data.spellID)
4 years ago
if data.profit then
local profitPercent = data.profit / cost * 100
local profitPercText = format("%s%.0f%%|r", color, profitPercent)
local profitPercentM = data.profit / cost * data.numQueued * 100
local profitPercTextM = format("%s%.0f%%|r", color, profitPercentM)
if data.profit>0 then
if moneyCoinsTooltip then
GameTooltip:AddLine("Profit: " .. (TSMAPI:FormatTextMoneyIcon(data.profit, color) or "---") .. " (" .. (profitPercText or "---") .. ")")
else
GameTooltip:AddLine("Profit: " .. (TSMAPI:FormatTextMoney(data.profit, color) or "---") .. " (" .. (profitPercText or "---") .. ")")
end
if data.numQueued>1 then
if moneyCoinsTooltip then
GameTooltip:AddLine("Total Profit: " .. (TSMAPI:FormatTextMoneyIcon(totalProfit, color) or "---") .. " (" .. (profitPercTextM or "---") .. ")")
else
GameTooltip:AddLine("Total Profit: " .. (TSMAPI:FormatTextMoney(totalProfit, color) or "---") .. " (" .. (profitPercTextM or "---") .. ")")
end
end
else
if moneyCoinsTooltip then
GameTooltip:AddLine("Loss: " .. (TSMAPI:FormatTextMoneyIcon(data.profit, color) or "---") .. " (" .. (profitPercText or "---") .. ")")
else
GameTooltip:AddLine("Loss: " .. (TSMAPI:FormatTextMoney(data.profit, color) or "---") .. " (" .. (profitPercText or "---") .. ")")
end
if data.numQueued>1 then
if moneyCoinsTooltip then
GameTooltip:AddLine("Total Loss: " .. (TSMAPI:FormatTextMoneyIcon(totalProfit, color) or "---") .. " (" .. (profitPercTextM or "---") .. ")")
else
GameTooltip:AddLine("Total Loss: " .. (TSMAPI:FormatTextMoney(totalProfit, color) or "---") .. " (" .. (profitPercTextM or "---") .. ")")
end
end
end
4 years ago
end
4 years ago
GameTooltip:AddLine(" ")
if moneyCoinsTooltip then
GameTooltip:AddLine("Crafting Cost: " .. (TSMAPI:FormatTextMoneyIcon(cost, "|cffffff00") or "---"))
4 years ago
else
GameTooltip:AddLine("Crafting Cost: " .. (TSMAPI:FormatTextMoney(cost, "|cffffff00") or "---"))
4 years ago
end
if data.numQueued>1 then
local totalcost = cost and cost * data.numQueued
4 years ago
if moneyCoinsTooltip then
GameTooltip:AddLine("Total Cost: " .. (TSMAPI:FormatTextMoneyIcon(totalcost, "|cffffff00") or "---"))
4 years ago
else
GameTooltip:AddLine("Total Cost: " .. (TSMAPI:FormatTextMoney(totalcost, "|cffffff00") or "---"))
4 years ago
end
end
for itemID, matQuantity in pairs(TSM.db.realm.crafts[data.spellID].mats) do
local name = TSMAPI:GetSafeItemInfo(itemID) or (TSM.db.realm.mats[itemID] and TSM.db.realm.mats[itemID].name) or "?"
4 years ago
local itemIDx = itemID
4 years ago
-- Get Cheapest vellum, lower vellum types can be replaced by III
local velName
if strfind(name, "Vellum") then
velName = name
end
if (velName ~= nil) then
if strfind(velName, "Weapon") then
itemIDx = "item:52511:0:0:0:0:0:0"
name = TSMAPI:GetSafeItemInfo(itemIDx)
4 years ago
else
itemIDx = "item:52510:0:0:0:0:0:0"
name = TSMAPI:GetSafeItemInfo(itemIDx)
4 years ago
end
end
4 years ago
local inventory = TSM.Inventory:GetPlayerBagNum(itemIDx)
local need = matQuantity * data.numQueued
local color
if inventory >= need then color = "|cff00ff00" else color = "|cffff0000" end
name = color .. inventory .. "/" .. need .. "|r " .. name
GameTooltip:AddLine(name, 1, 1, 1)
end
GameTooltip:Show()
end
local function OnCraftRowLeave()
GameTooltip:Hide()
end
local function OnCraftRowClicked(_, data, _, button)
if button == "RightButton" and data.index then
if data.profession == GetTradeSkillLine() then
TradeSkillFrame_SetSelection(data.index)
TradeSkillFrame_Update()
GUI:UpdateSelectedTradeSkill(true)
GUI.frame.content.professionsTab.st:SetScrollOffset(max(0, data.index - 1))
end
else
if data.isTitle then
if data.stage then
TSM.db.realm.queueStatus.collapsed[data.profession .. data.stage] = not TSM.db.realm.queueStatus.collapsed[data.profession .. data.stage]
4 years ago
else
TSM.db.realm.queueStatus.collapsed[data.profession] = not TSM.db.realm.queueStatus.collapsed[data.profession]
4 years ago
end
GUI:UpdateQueue()
elseif data.index then
GUI:CastTradeSkill(data.index, min(data.canCraft, data.numQueued), data.velName)
end
end
end
frame.craftST = TSMAPI:CreateScrollingTable(stContainer, stCols, { OnClick = OnCraftRowClicked, OnEnter = OnCraftRowEnter, OnLeave = OnCraftRowLeave }, 14)
frame.craftST:SetData({})
frame.craftST:DisableSelection(true)
local line = TSMAPI.GUI:CreateHorizontalLine(frame, 0)
local height = line:GetHeight()
line:ClearAllPoints()
line:SetPoint("LEFT")
line:SetPoint("RIGHT")
line:SetHeight(height)
local stContainer2 = CreateFrame("Frame", nil, frame)
stContainer2:SetPoint("TOPLEFT", frame, "LEFT", 5, -5)
stContainer2:SetPoint("BOTTOMRIGHT", -5, 68)
TSMAPI.Design:SetFrameColor(stContainer2)
local line = TSMAPI.GUI:CreateHorizontalLine(frame, 0)
local height = line:GetHeight()
line:ClearAllPoints()
line:SetPoint("BOTTOMLEFT", 0, 63)
line:SetPoint("BOTTOMRIGHT", 0, 63)
line:SetHeight(height)
local stCols = {
{ name = L["Material Name"], width = 0.49, align = "Left" },
{ name = L["Need"], width = 0.115, align = "LEFT" },
{ name = L["Total"], width = 0.115, align = "LEFT" },
{ name = L["Cost"], width = 0.28, align = "LEFT" },
}
local function MatOnEnter(_, data, col)
GameTooltip:SetOwner(col, "ANCHOR_RIGHT")
TSMAPI:SafeTooltipLink(data.itemString)
GameTooltip:Show()
end
local function MatOnLeave(_, data)
GameTooltip:Hide()
end
4 years ago
local function MatOnClick(_, data)
if IsModifiedClick() then
local link = select(2, TSMAPI:GetSafeItemInfo(data.itemString))
HandleModifiedItemClick(link or data.itemString)
end
end
frame.matST = TSMAPI:CreateScrollingTable(stContainer2, stCols, { OnEnter = MatOnEnter, OnLeave = MatOnLeave, OnClick = MatOnClick }, 12)
frame.matST:SetData({})
frame.matST:DisableSelection(true)
local profitLabel = TSMAPI.GUI:CreateLabel(frame, "medium")
profitLabel:SetPoint("TOPLEFT", stContainer2, "BOTTOMLEFT", 0, -7)
profitLabel:SetPoint("TOPRIGHT", stContainer2, "BOTTOMRIGHT", 0, -7)
profitLabel:SetJustifyH("LEFT")
profitLabel:SetJustifyV("CENTER")
profitLabel.SetAmounts = function(self, cost, profit)
if type(cost) == "number" then
cost = TSMAPI:FormatTextMoney(cost, TSMAPI.Design:GetInlineColor("link"))
else
cost = TSMAPI.Design:GetInlineColor("link") .. "---|r"
end
if type(profit) == "number" then
if profit < 0 then
profit = "|cffff0000-|r" .. TSMAPI:FormatTextMoney(-profit, "|cffff0000")
else
profit = TSMAPI:FormatTextMoney(profit, "|cff00ff00")
end
else
profit = TSMAPI.Design:GetInlineColor("link") .. "---|r"
end
self:SetText(format(L["Estimated Cost: %s\nEstimated Profit: %s"], cost, profit))
end
profitLabel:SetAmounts("---", "---")
frame.profitLabel = profitLabel
local line = TSMAPI.GUI:CreateHorizontalLine(frame, 0)
local height = line:GetHeight()
line:ClearAllPoints()
line:SetPoint("BOTTOMLEFT", 0, 28)
line:SetPoint("BOTTOMRIGHT", 0, 28)
line:SetHeight(height)
local btn = TSMAPI.GUI:CreateButton(frame, 14)
btn:SetPoint("BOTTOMLEFT", 5, 5)
btn:SetWidth(120)
btn:SetHeight(20)
btn:SetText(L["Clear Queue"])
btn:SetScript("OnClick", function()
TSM.Queue:ClearQueue()
GUI:UpdateQueue()
if GUI.frame.gather:IsVisible() then
GUI.frame.gather:Hide()
end
private.gather = {}
GUI:UpdateGatherSelectionWindow()
if GUI.gatheringFrame:IsShown() then
GUI.gatheringFrame:Hide()
TSM.db.realm.gathering.crafter = nil
TSM.db.realm.gathering.neededMats = {}
TSM.db.realm.gathering.gatheredMats = false
TSM.db.realm.sourceStatus.collapsed = {}
4 years ago
end
end)
frame.clearBtn = btn
local btn = TSMAPI.GUI:CreateButton(frame, 18, "TSMCraftNextButton")
btn:SetPoint("BOTTOMLEFT", frame.clearBtn, "BOTTOMRIGHT", 5, 0)
btn:SetPoint("BOTTOMRIGHT", -5, 5)
btn:SetHeight(20)
btn:SetText(L["Craft Next"])
-- btn:SetScript("OnUpdate", function(self)
-- if UnitCastingInfo("player") or not GUI.craftNextInfo then
-- self:Disable()
-- elseif GUI.isCrafting and GUI.isCrafting.quantity > 0 then
-- self:Disable()
-- else
-- self:Enable()
-- end
-- end)
btn:SetScript("OnClick", function(self)
if UnitCastingInfo("player") or not GUI.craftNextInfo or not self:IsVisible() then return end
GUI:CastTradeSkill(GUI.craftNextInfo.index, GUI.craftNextInfo.quantity, GUI.craftNextInfo.velName)
self:Disable()
end)
frame.craftNextbtn = btn
return frame
end
function GUI:CreateNavFrame(frame)
local navFrame = CreateFrame("Frame", nil, frame)
navFrame:SetPoint("TOPLEFT", 0, -25)
navFrame:SetPoint("TOPRIGHT", 0, -25)
navFrame:SetHeight(30)
TSMAPI.GUI:CreateHorizontalLine(frame, -25)
local title = navFrame:CreateFontString()
title:SetFont(TSMAPI.Design:GetContentFont(), 18)
TSMAPI.Design:SetWidgetLabelColor(title)
title:SetPoint("TOP", frame, 0, -3)
local version = TSM._version
if strfind(version, "@") then version = "Dev" end
title:SetText(format("TSM_Crafting - %s", version))
local btn = TSMAPI.GUI:CreateButton(navFrame, 16)
btn:SetPoint("TOPLEFT", 5, -5)
btn:SetPoint("BOTTOMLEFT", 5, 5)
btn:SetWidth(105)
btn:SetText(L["Professions"])
btn:SetScript("OnClick", GUI.ShowProfessionsTab)
navFrame.professionsBtn = btn
local btn = TSMAPI.GUI:CreateButton(navFrame, 16)
btn:SetPoint("TOPLEFT", navFrame.professionsBtn, "TOPRIGHT", 5, 0)
btn:SetPoint("BOTTOMLEFT", navFrame.professionsBtn, "BOTTOMRIGHT", 5, 0)
btn:SetWidth(105)
btn:SetText(L["TSM Groups"])
btn:SetScript("OnClick", GUI.ShowGroupsTab)
navFrame.groupsBtn = btn
TSMAPI.GUI:CreateVerticalLine(navFrame, 224)
local btn = TSMAPI.GUI:CreateButton(navFrame, 16)
btn:SetPoint("TOPLEFT", navFrame.groupsBtn, "TOPRIGHT", 10, 0)
btn:SetPoint("BOTTOMLEFT", navFrame.groupsBtn, "BOTTOMRIGHT", 10, 0)
btn:SetWidth(60)
btn:SetText(L["Gather"])
btn:SetScript("OnClick", function(self)
local queuedCrafts = TSM.Queue:GetQueue()
if not next(queuedCrafts) then return end
if GUI.frame.queue:IsVisible() then
GUI.frame.gather:SetPoint("TOPLEFT", GUI.frame.queue, "TOPRIGHT", 2, 0)
else
GUI.frame.gather:SetPoint("TOPLEFT", frame, "TOPRIGHT", 2, 0)
end
if GUI.frame.gather:IsVisible() then
GUI.frame.gather:Hide()
else
GUI.frame.gather:Show()
GUI:UpdateGatherSelectionWindow()
end
end)
navFrame.gatherBtn = btn
TSMAPI.GUI:CreateVerticalLine(navFrame, 294)
local btn = TSMAPI.GUI:CreateButton(navFrame, 16)
btn:Hide()
btn:SetPoint("TOPLEFT", navFrame.gatherBtn, "TOPRIGHT", 10, 0)
btn:SetPoint("BOTTOMLEFT", navFrame.gatherBtn, "BOTTOMRIGHT", 10, 0)
btn:SetPoint("TOPRIGHT", -5, -5)
btn.UpdateQueueStatus = function(self)
if TSM.db.global.frameQueueOpen then
GUI.frame.queue:Show()
self:SetText(L["<< Hide Queue"])
GUI:UpdateQueue()
if GUI.frame.gather:IsVisible() then
GUI.frame.gather:SetPoint("TOPLEFT", GUI.frame.queue, "TOPRIGHT", 2, 0)
end
else
GUI.frame.queue:Hide()
self:SetText(L["Show Queue >>"])
if GUI.frame.gather:IsVisible() then
GUI.frame.gather:SetPoint("TOPLEFT", frame, "TOPRIGHT", 2, 0)
end
end
end
btn:SetScript("OnClick", function(self)
if GUI.frame.queue:IsVisible() then
TSM.db.global.frameQueueOpen = nil
else
TSM.db.global.frameQueueOpen = true
end
self:UpdateQueueStatus()
end)
btn:SetScript("OnShow", btn.UpdateQueueStatus)
btn:Show()
navFrame.queueBtn = btn
return navFrame
end
local QuickRestock = false
function GUI:CreateProfessionsTab(parent)
local frame = CreateFrame("Frame", nil, parent)
frame:SetAllPoints()
frame:Hide()
local currentSelection
local player = UnitName("player")
local function SetNoClose()
GUI.noClose = true
GUI.switchingProfession = true
TSMAPI:CreateTimeDelay("craftingNoCloseClear", 0.6, function() GUI.noClose = nil end)
TSMAPI:CreateTimeDelay("craftingSwitchingClear", 0.8, function() GUI.switchingProfession = nil end)
end
local function SelectSpellInProfession(profession, spellID)
if GetTradeSkillLine() ~= profession then
local link = TSM.db.realm.tradeSkills[player] and TSM.db.realm.tradeSkills[player][profession] and TSM.db.realm.tradeSkills[player][profession].link
if not link then return end
local tradeString = strsub(select(3, ("|"):split(link)), 2)
SetNoClose()
SetItemRef(tradeString, link, "LeftButton", ChatFrame1)
return
end
for i = 1, GetNumTradeSkills() do
if TSM.Util:GetSpellID(i) == spellID then
TradeSkillFrame_SetSelection(i)
TradeSkillFrame_Update()
GUI:UpdateSelectedTradeSkill(true)
return
end
end
end
local HaveMatsCheckBox
4 years ago
local function UpdateProfession(self)
local list = {}
list["ALL"] = L["All Professions"]
for playerName, professionData in pairs(TSM.db.realm.tradeSkills) do
4 years ago
for name, data in pairs(professionData) do
if playerName == player then -- only display current player profs until blizz fix it
4 years ago
list[playerName .. "~" .. name] = format("%s %d/%d - %s", name, data.level or "?", data.maxLevel or "?", playerName)
end
end
end
self.dropdown:SetList(list)
if TSM.db.global.showAllProfessions then
self.dropdown:SetValue("ALL")
self.dropdown:SetText(L["All Professions"])
return
end
4 years ago
local playerName = select(2, IsTradeSkillLinked()) or player
local professionName, level, maxLevel = GetTradeSkillLine()
local professionString = format("%s %d/%d - %s", professionName, level, maxLevel, playerName)
currentSelection = playerName .. "~" .. professionName
self.dropdown:SetValue(currentSelection)
if not list[playerName .. "~" .. professionName] then
self.dropdown:SetText(professionString)
end
end
frame.UpdateProfession = UpdateProfession
frame:SetScript("OnShow", UpdateProfession)
local function OnValueChanged(_, _, index)
if index == "ALL" then
TSM.db.global.showAllProfessions = true
frame:UpdateProfession()
GUI:UpdateProfessionsTabST()
return
end
if TSM.db.global.showAllProfessions then
SetNoClose()
TSM.db.global.showAllProfessions = false
end
4 years ago
local playerName, profession = ("~"):split(index)
local currentPlayer = select(2, IsTradeSkillLinked()) or player
local currentProfession = GetTradeSkillLine()
if playerName == currentPlayer and profession == currentProfession then
frame:UpdateProfession()
GUI:ShowProfessionsTab()
currentSelection = index
return
end
4 years ago
if playerName == player then
local link = TSM.db.realm.tradeSkills[playerName] and TSM.db.realm.tradeSkills[playerName][profession] and TSM.db.realm.tradeSkills[playerName][profession].link
if not link then
TSM:Printf(L["Profession data not found for %s on %s. Logging into this player and opening the profession may solve this issue."], profession, playerName)
return OnValueChanged(_, _, currentSelection)
4 years ago
end
local tradeString = strsub(select(3, ("|"):split(link)), 2)
SetNoClose()
SetItemRef(tradeString, link, "LeftButton", ChatFrame1)
4 years ago
else
local link = TSM.db.realm.tradeSkills[playerName][profession].link
4 years ago
if not link then
TSM:Printf(L["Profession data not found for %s on %s. Logging into this player and opening the profession may solve this issue."], profession, playerName)
return OnValueChanged(_, _, currentSelection)
end
local tradeString = strsub(select(3, ("|"):split(link)), 2)
SetNoClose()
SetItemRef(tradeString, link, "LeftButton", ChatFrame1)
4 years ago
end
currentSelection = index
end
local dd = TSMAPI.GUI:CreateDropdown(frame, {}, L["Select one of your characters' professions to browse."])
dd.frame:SetPoint("TOPLEFT", 3, -4)
-- dd.frame:SetPoint("TOPRIGHT", -47, -4)
dd.frame:SetWidth(256)
dd:SetCallback("OnValueChanged", OnValueChanged)
frame.dropdown = dd
HaveMatsCheckBox = TSMAPI.GUI:CreateCheckBox(frame)
4 years ago
HaveMatsCheckBox:SetLabel(" Have Mats")
HaveMatsCheckBox:SetPoint("TOPLEFT", 252, -4)
HaveMatsCheckBox:SetWidth(90)
HaveMatsCheckBox:SetHeight(26)
frame.HaveMatsCheckBox = HaveMatsCheckBox
HaveMatsCheckBox:SetCallback("OnValueChanged", function(_, _, value)
if TSM.db.global.showAllProfessions then
GUI:UpdateProfessionsTabST()
else
TradeSkillFrameAvailableFilterCheckButton:SetChecked(value)
TradeSkillOnlyShowMakeable(value)
end
4 years ago
end)
local RestockBtn = TSMAPI.GUI:CreateButton(frame, 14)
RestockBtn:SetPoint("TOPRIGHT", -50, -4)
RestockBtn:SetWidth(56)
RestockBtn:SetHeight(26)
RestockBtn:SetText("Restock")
RestockBtn:SetScript("OnClick", function(self)
QuickRestock = true
GUI.ShowGroupsTab()
end)
frame.restockBtn = RestockBtn
4 years ago
local linkBtn = TSMAPI.GUI:CreateButton(frame, 14)
linkBtn:SetPoint("TOPRIGHT", -5, -4)
linkBtn:SetWidth(40)
linkBtn:SetHeight(26)
linkBtn:SetText(L["Link"])
linkBtn:SetScript("OnClick", function(self)
local link = GetTradeSkillListLink()
if not link then return TSM:Print(L["Could not get link for profession."]) end
local activeEditBox = ChatEdit_GetActiveWindow()
if MacroFrameText and MacroFrameText:IsShown() and MacroFrameText:HasFocus() then
local text = MacroFrameText:GetText() .. link
if strlenutf8(text) <= 255 then
MacroFrameText:Insert(link)
end
elseif activeEditBox then
ChatEdit_InsertLink(link)
end
end)
frame.linkBtn = linkBtn
local function InsertLink(link)
local putIntoChat, v1, v2, v3 = GUI.hooks.ChatEdit_InsertLink(link)
local hoverButton = GetMouseFocus()
if not putIntoChat and frame:IsVisible() and not (hoverButton and hoverButton:GetName() and strfind(hoverButton:GetName(), "MerchantItem([0-9]+)ItemButton")) then
local name = TSMAPI:GetSafeItemInfo(link)
if name then
frame.searchBar:SetText(name)
frame.searchBar:SetTextColor(1, 1, 1, 1)
return true
end
end
return putIntoChat
end
GUI:RawHook("ChatEdit_InsertLink", InsertLink, true)
local searchBar = TSMAPI.GUI:CreateInputBox(frame, "TSMCraftingSearchBar")
searchBar:SetPoint("TOPLEFT", 5, -35)
searchBar:SetWidth(220) --(240)
searchBar:SetHeight(24)
searchBar:SetText(SEARCH)
searchBar:SetTextColor(1, 1, 1, 0.5)
searchBar:SetScript("OnEditFocusGained", function(self)
self:SetTextColor(1, 1, 1, 1)
if self:GetText() == SEARCH then
self:SetText("")
end
end)
searchBar:SetScript("OnEditFocusLost", function(self)
if self:GetText() == "" or self:GetText() == SEARCH then
self:SetTextColor(1, 1, 1, 0.5)
self:SetText(SEARCH)
end
end)
searchBar:SetScript("OnTextChanged", function(self)
local text = self:GetText()
if not TSM.db.global.showAllProfessions then
SetTradeSkillItemNameFilter(text == SEARCH and "" or text)
end
4 years ago
GUI:UpdateProfessionsTabST()
end)
searchBar:SetScript("OnEnterPressed", searchBar.ClearFocus)
frame.searchBar = searchBar
local btn = TSMAPI.GUI:CreateButton(frame, 14)
btn:SetPoint("TOPLEFT", searchBar, "TOPRIGHT", 5, 0)
btn:SetWidth(80)
btn:SetHeight(24)
btn:SetText(L["Clear Filters"])
btn:SetScript("OnClick", GUI.ClearFilters)
frame.clearFilterBtn = btn
-- local btn = TSMAPI.GUI:CreateButton(frame, 14, "TSMCraftingFilterButton")
-- btn:SetPoint("TOPLEFT", frame.clearFilterBtn, "TOPRIGHT", 5, 0)
-- btn:SetPoint("TOPRIGHT", -5, -35)
-- btn:SetHeight(24)
-- btn:SetText(L["Filters >>"])
-- btn:SetScript("OnClick", function(self) ToggleDropDownMenu(1, nil, TradeSkillFilterDropDown, "TSMCraftingFilterButton", btn:GetWidth(), 0) end)
-- frame.filterBtn = btn
4 years ago
local btn = TSMAPI.GUI:CreateButton(frame, 14, "TSMCraftingFilterButton")
btn:SetPoint("TOPLEFT", frame.clearFilterBtn, "TOPRIGHT", 5, 0)
btn:SetWidth(80)
btn:SetHeight(24)
btn:SetText("Subclass >>")
btn:SetScript("OnClick", function(self) ToggleDropDownMenu(1, nil, TradeSkillSubClassDropDown, "TSMCraftingFilter2Button", -84, 0) end)
frame.filterBtn = btn
local btn = TSMAPI.GUI:CreateButton(frame, 14, "TSMCraftingFilter2Button")
btn:SetPoint("TOPLEFT", frame.filterBtn, "TOPRIGHT", 5, 0)
btn:SetPoint("TOPRIGHT", -5, -35)
btn:SetHeight(24)
btn:SetText("Slot >>")
btn:SetScript("OnClick", function(self) ToggleDropDownMenu(1, nil, TradeSkillInvSlotDropDown, "TSMCraftingFilter2Button", 0, 0) end)
frame.filter2Btn = btn
TSMAPI.GUI:CreateHorizontalLine(frame, -64)
local function OnSTRowClick(_, data, _, button)
if TSM.db.global.showAllProfessions and data.spellID then
if IsModifiedClick() then
local itemID = TSM.db.realm.crafts[data.spellID] and TSM.db.realm.crafts[data.spellID].itemID
if itemID then
HandleModifiedItemClick(itemID)
end
else
SelectSpellInProfession(data.profession, data.spellID)
end
return
elseif data.isCollapseAll then
4 years ago
TradeSkillCollapseAllButton:Click()
GUI:UpdateProfessionsTabST()
elseif button == "LeftButton" then
if IsModifiedClick() then
HandleModifiedItemClick(GetTradeSkillRecipeLink(data.index))
else
TradeSkillFrame_SetSelection(data.index)
TradeSkillFrame_Update()
GUI:UpdateSelectedTradeSkill(true)
end
end
end
local function OnSTColumnClick(self)
if TSM.db.global.showAllProfessions then
local sortKey
if self.colNum == 1 then
sortKey = "available"
elseif self.colNum == 3 then
sortKey = "cost"
elseif self.colNum == 4 then
sortKey = "profit"
elseif self.colNum == 5 then
sortKey = "profitPercent"
end
if sortKey then
if TSM.db.global.showAllProfessionsSortKey ~= sortKey then
TSM.db.global.showAllProfessionsSortKey = sortKey
TSM.db.global.showAllProfessionsSortDescending = true
else
TSM.db.global.showAllProfessionsSortDescending = not TSM.db.global.showAllProfessionsSortDescending
end
GUI:UpdateProfessionsTabST()
end
4 years ago
end
end
local stContainer = CreateFrame("Frame", nil, frame)
stContainer:SetPoint("TOPLEFT", 5, -70)
stContainer:SetPoint("BOTTOMRIGHT", -5, 150) -- 177)
frame.stContainer = stContainer
TSMAPI.Design:SetFrameColor(stContainer)
local stCols = {
{ name = "#", width = 0.08, align = "LEFT", headAlign = "LEFT" },
{ name = L["Name"], width = 0.40, align = "LEFT", headAlign = "LEFT" },
{ name = L["Cost"], width = 0.16, align = "LEFT", headAlign = "LEFT" },
{ name = L["Profit"], width = 0.18, align = "LEFT", headAlign = "LEFT" },
{ name = "%", width = 0.08, align = "LEFT", headAlign = "LEFT" }
4 years ago
}
frame.st = TSMAPI:CreateScrollingTable(stContainer, stCols, { OnClick = OnSTRowClick, OnColumnClick = OnSTColumnClick })
frame.craftInfoFrame = GUI:CreateCraftInfoFrame(frame)
return frame
end
function GUI:CreateCraftInfoFrame(parent)
local frame = CreateFrame("Frame", nil, parent)
frame:SetPoint("TOPLEFT", parent.stContainer, "BOTTOMLEFT", 0, -4)
frame:SetPoint("BOTTOMRIGHT", -3, 3)
TSMAPI.Design:SetFrameColor(frame)
local function OnClick()
if not frame.index then return end
HandleModifiedItemClick(GetTradeSkillItemLink(frame.index))
end
local function OnEnter(self)
if not frame.index then return end
local spellID = TSM.Util:GetSpellID(frame.index)
local itemID = spellID and TSM.db.realm.crafts[spellID] and TSM.db.realm.crafts[spellID].itemID
4 years ago
if itemID then
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
TSMAPI:SafeTooltipLink(itemID)
else
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
GameTooltip:SetTradeSkillItem(frame.index)
end
end
local function OnLeave()
if not frame.index then return end
GameTooltip:Hide()
end
local infoFrame = CreateFrame("Frame", nil, frame)
infoFrame:SetPoint("TOPLEFT", 3, -3)
infoFrame:SetPoint("BOTTOMLEFT", 3, 53)
infoFrame:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -220, -3)
frame.infoFrame = infoFrame
local iconBtn = CreateFrame("Button", nil, infoFrame)
iconBtn:SetPoint("TOPLEFT")
iconBtn:SetWidth(32) --40
iconBtn:SetHeight(32) --40
iconBtn:SetScript("OnClick", OnClick)
iconBtn:SetScript("OnEnter", OnEnter)
iconBtn:SetScript("OnLeave", OnLeave)
infoFrame.iconBtn = iconBtn
local icon = iconBtn:CreateTexture()
icon:SetAllPoints()
infoFrame.icon = icon
local nameText = infoFrame:CreateFontString()
nameText:SetPoint("TOPLEFT", icon, "TOPRIGHT", 4, 0)
nameText:SetPoint("TOPRIGHT")
nameText:SetJustifyH("LEFT")
nameText:SetFont(TSMAPI.Design:GetContentFont("small"))
infoFrame.nameText = nameText
local toolsText = infoFrame:CreateFontString()
toolsText:SetPoint("TOPLEFT", nameText, "BOTTOMLEFT", 0, -2)
toolsText:SetPoint("TOPRIGHT", nameText, "BOTTOMRIGHT", 0, -2)
toolsText:SetJustifyH("LEFT")
toolsText:SetFont(TSMAPI.Design:GetContentFont("small"))
infoFrame.toolsText = toolsText
local cooldownText = infoFrame:CreateFontString()
cooldownText:SetPoint("TOPLEFT", toolsText, "BOTTOMLEFT", 0, -2)
cooldownText:SetPoint("TOPRIGHT", toolsText, "BOTTOMRIGHT", 0, -2)
cooldownText:SetJustifyH("LEFT")
cooldownText:SetFont(TSMAPI.Design:GetContentFont("small"))
cooldownText:SetTextColor(1, 0, 0, 1)
infoFrame.cooldownText = cooldownText
local descText = infoFrame:CreateFontString()
descText:SetPoint("TOPLEFT", iconBtn, "BOTTOMLEFT", 0, -2)
descText:SetPoint("BOTTOMRIGHT")
descText:SetFont(TSMAPI.Design:GetContentFont("small"))
descText:SetJustifyH("LEFT")
descText:SetJustifyV("TOP")
infoFrame.descText = descText
local vBar = TSMAPI.GUI:CreateVerticalLine(frame, infoFrame:GetWidth() + 3)
vBar:ClearAllPoints()
vBar:SetPoint("TOPLEFT", infoFrame, "TOPRIGHT", 3, 3)
vBar:SetPoint("BOTTOMLEFT", infoFrame, "BOTTOMRIGHT", 3, -53)
TSMAPI.GUI:CreateHorizontalLine(infoFrame, -infoFrame:GetHeight())
local matsFrame = CreateFrame("Frame", nil, frame)
matsFrame:SetPoint("TOPLEFT", infoFrame, "TOPRIGHT", 5, 0)
matsFrame:SetPoint("TOPRIGHT")
matsFrame:SetPoint("BOTTOMRIGHT")
frame.matsFrame = matsFrame
local function Sizer_OnMouseUp()
GUI.frame:StopMovingOrSizing()
end
local function Sizer_OnMouseDown()
GUI.frame:StartSizing("BOTTOMRIGHT")
end
local sizer = CreateFrame("Frame", nil, frame)
sizer:SetPoint("BOTTOMRIGHT", -2, 2)
sizer:SetWidth(16)
sizer:SetHeight(16)
sizer:EnableMouse()
sizer:SetScript("OnMouseDown", Sizer_OnMouseDown)
sizer:SetScript("OnMouseUp", Sizer_OnMouseUp)
local image = sizer:CreateTexture(nil, "BACKGROUND")
image:SetAllPoints()
image:SetTexture("Interface\\Addons\\TradeSkillMaster\\Media\\Sizer")
local castText = frame:CreateFontString()
castText:SetPoint("BOTTOMRIGHT", GUI.frame, -22, 3)
castText:SetHeight(18)
castText:SetJustifyH("RIGHT")
castText:SetJustifyV("BOTTOM")
castText:SetFont(TSMAPI.Design:GetContentFont("small"))
castText.timeout = 0
castText.endTime = 0
castText.UpdateTime = function()
local startTime, endTime, isTradeSkill = select(5, UnitCastingInfo("player"))
if isTradeSkill then
local timePerCraft = endTime - startTime
endTime = endTime + (timePerCraft * (GetTradeskillRepeatCount() - 1))
castText.endTime = ceil(endTime / 1000)
elseif not startTime then
-- not casting a tradeskill
if castText.endTime > GetTime() then
castText.timeout = castText.timeout + 1
if castText.timeout > 3 then
castText.endTime = 0
castText.timeout = 0
end
else
castText.timeout = 0
end
end
if castText.endTime > GetTime() then
castText:SetText(TSM.Util:FormatTime(castText.endTime - GetTime()))
else
castText:SetText()
end
end
TSMAPI:CreateTimeDelay("craftTimeText", 0.5, castText.UpdateTime, 0.5)
matsFrame.castText = castText
local matsText = matsFrame:CreateFontString()
matsText:SetPoint("TOPLEFT")
matsText:SetPoint("TOPRIGHT")
matsText:SetFont(TSMAPI.Design:GetContentFont(), 13)
matsText:SetJustifyH("LEFT")
matsText:SetJustifyV("TOP")
matsText:SetText(TSMAPI.Design:GetInlineColor("link") .. L["Materials:"] .. "|r")
matsFrame.matsText = matsText
local reagentButtons = {}
for i = 1, MAX_TRADE_SKILL_REAGENTS do
local btn = TSMAPI.GUI:CreateItemLinkLabel(matsFrame, 13)
if i == 1 then
btn:SetPoint("TOPLEFT", 0, -15)
btn:SetPoint("TOPRIGHT", 0, -15)
else
btn:SetPoint("TOPLEFT", reagentButtons[i - 1], "BOTTOMLEFT", 0, -3)
btn:SetPoint("TOPRIGHT", reagentButtons[i - 1], "BOTTOMRIGHT", 0, -3)
end
tinsert(reagentButtons, btn)
end
matsFrame.reagentButtons = reagentButtons
local buttonsFrame = CreateFrame("Frame", nil, frame)
buttonsFrame:SetPoint("TOPRIGHT", infoFrame, "BOTTOMRIGHT", -2, -5)
buttonsFrame:SetPoint("BOTTOMLEFT", 2, 2)
frame.buttonsFrame = buttonsFrame
local lessBtn = CreateFrame("Button", nil, buttonsFrame)
lessBtn:SetWidth(28)
lessBtn:SetHeight(28)
lessBtn:SetPoint("TOPLEFT", -4, 4)
lessBtn:SetNormalTexture("Interface\\Buttons\\UI-SpellbookIcon-PrevPage-Up")
lessBtn:SetPushedTexture("Interface\\Buttons\\UI-SpellbookIcon-PrevPage-Down")
lessBtn:SetDisabledTexture("Interface\\Buttons\\UI-SpellbookIcon-PrevPage-DisabledTexture")
lessBtn:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight")
lessBtn:SetScript("OnClick", function()
local num = buttonsFrame.inputBox:GetNumber() - 1
buttonsFrame.inputBox:SetNumber(max(num, 1))
end)
buttonsFrame.lessBtn = lessBtn
local inputBox = TSMAPI.GUI:CreateInputBox(buttonsFrame, "TSMCraftingCreateInputBox")
inputBox:SetPoint("TOPLEFT", lessBtn, "TOPRIGHT", -2, -4)
inputBox:SetPoint("BOTTOMLEFT", lessBtn, "BOTTOMRIGHT", -2, 4)
inputBox:SetWidth(40)
inputBox:SetScript("OnEditFocusGained", function(self) self:HighlightText() end)
buttonsFrame.inputBox = inputBox
local moreBtn = CreateFrame("Button", nil, buttonsFrame)
moreBtn:SetWidth(28)
moreBtn:SetHeight(28)
moreBtn:SetPoint("TOPLEFT", inputBox, "TOPRIGHT", -2, 4)
moreBtn:SetPoint("BOTTOMLEFT", inputBox, "BOTTOMRIGHT", -2, -4)
moreBtn:SetNormalTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Up")
moreBtn:SetPushedTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Down")
moreBtn:SetDisabledTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-DisabledTexture")
moreBtn:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight")
moreBtn:SetScript("OnClick", function()
local num = buttonsFrame.inputBox:GetNumber() + 1
buttonsFrame.inputBox:SetNumber(max(num, 1))
end)
buttonsFrame.moreBtn = moreBtn
local queueBtn = TSMAPI.GUI:CreateButton(buttonsFrame, 15)
queueBtn:SetText(L["Queue"])
queueBtn:SetPoint("TOPLEFT", moreBtn, "TOPRIGHT", 0, -4)
queueBtn:SetPoint("BOTTOMLEFT", moreBtn, "BOTTOMRIGHT", 0, 4)
queueBtn:SetPoint("TOPRIGHT")
queueBtn:RegisterForClicks("AnyUp")
queueBtn:SetScript("OnClick", function(_, button)
local spellID = TSM.Util:GetSpellID(frame.index)
if not spellID or not TSM.db.realm.crafts[spellID] then return end
4 years ago
TSM.db.realm.crafts[spellID].queued = max(TSM.db.realm.crafts[spellID].queued, 0)
4 years ago
if button == "LeftButton" then
if IsModifiedClick() then
TSM.db.realm.crafts[spellID].queued = select(3, GetTradeSkillInfo(frame.index)) or 0
4 years ago
else
TSM.db.realm.crafts[spellID].queued = (TSM.db.realm.crafts[spellID].queued or 0) + buttonsFrame.inputBox:GetNumber()
4 years ago
end
elseif button == "RightButton" then
if IsModifiedClick() then
TSM.db.realm.crafts[spellID].queued = 0
4 years ago
else
TSM.db.realm.crafts[spellID].queued = max((TSM.db.realm.crafts[spellID].queued or 0) - buttonsFrame.inputBox:GetNumber(), 0)
4 years ago
end
end
GUI:UpdateQueue()
end)
local color = TSMAPI.Design:GetInlineColor("link")
local tooltipLines = {
color .. L["Left-Click|r to add this craft to the queue."],
color .. L["Shift-Left-Click|r to queue all you can craft."],
color .. L["Right-Click|r to subtract this craft from the queue."],
color .. L["Shift-Right-Click|r to remove all from queue."],
}
queueBtn.tooltip = table.concat(tooltipLines, "\n")
buttonsFrame.queueBtn = queueBtn
local createBtn = TSMAPI.GUI:CreateButton(buttonsFrame, 15)
createBtn:SetText("Create")--(CREATE_PROFESSION)
createBtn:SetPoint("BOTTOMLEFT")
createBtn:SetPoint("BOTTOMRIGHT", buttonsFrame, "BOTTOM", -2, 0)
createBtn:SetHeight(20)
createBtn:SetScript("OnClick", function() GUI:CastTradeSkill(frame.index, buttonsFrame.inputBox:GetNumber()) end)
buttonsFrame.createBtn = createBtn
local createAllBtn = TSMAPI.GUI:CreateButton(buttonsFrame, 15)
createAllBtn:SetText(CREATE_ALL)
createAllBtn:SetPoint("BOTTOMLEFT", buttonsFrame, "BOTTOM", 2, 0)
createAllBtn:SetPoint("BOTTOMRIGHT")
createAllBtn:SetHeight(20)
createAllBtn:SetScript("OnClick", function(self)
local quantity = select(3, GetTradeSkillInfo(frame.index))
GUI:CastTradeSkill(frame.index, quantity, self.vellum)
GUI.frame.content.professionsTab.craftInfoFrame.buttonsFrame.inputBox:SetNumber(GetTradeskillRepeatCount())
end)
buttonsFrame.createAllBtn = createAllBtn
frame.SetTradeSkillIndex = function(self, skillIndex)
local name, _, numAvailable, _, altVerb = GetTradeSkillInfo(skillIndex)
-- Enable display of items created
local lNum, hNum = GetTradeSkillNumMade(skillIndex)
local numMade = floor(((lNum or 1) + (hNum or 1)) / 2)
if altVerb ~= nil and strfind(name,"Enchant ") then
4 years ago
numMade = 1
end
if numMade > 1 then
name = numMade .. " x " .. name
end
self.index = skillIndex
self.infoFrame.icon:SetTexture(GetTradeSkillIcon(skillIndex))
self.infoFrame.nameText:SetText(TSMAPI.Design:GetInlineColor("link") .. (name or "") .. "|r")
self.infoFrame.descText:SetText(GetTradeSkillDescription(skillIndex))
-- The code below is heavily based on the code in Blizzard_TradeSkillUI.lua.
local toolsInfo = BuildColoredListString(GetTradeSkillTools(skillIndex))
self.infoFrame.toolsText:SetText(toolsInfo and REQUIRES_LABEL .. " " .. toolsInfo or "")
local cooldown = GetTradeSkillCooldown(skillIndex)
4 years ago
if not cooldown then
self.infoFrame.cooldownText:SetText("");
elseif cooldown > 60 * 60 * 24 then --Cooldown is greater than 1 day.
self.infoFrame.cooldownText:SetText(COOLDOWN_REMAINING .. " " .. SecondsToTime(cooldown, true, false, 1, true))
else
self.infoFrame.cooldownText:SetText(COOLDOWN_REMAINING .. " " .. SecondsToTime(cooldown))
end
for i, btn in ipairs(self.matsFrame.reagentButtons) do
local name, texture, needed, player = GetTradeSkillReagentInfo(skillIndex, i)
if name then
btn:Show()
btn.link = GetTradeSkillReagentItemLink(skillIndex, i)
local linkText = (texture and "|T" .. texture .. ":0|t" or "") .. " " .. (GetTradeSkillReagentItemLink(skillIndex, i) or name)
local color = (needed > player) and "|cffff0000" or "|cff00ff00"
btn:SetText(format("%s(%d/%d) %s|r", color, player, needed, linkText))
else
btn:Hide()
btn:SetText("")
end
end
-- if altVerb == ENSCRIBE then
if altVerb ~= nil and strfind(name,"Enchant ") then
4 years ago
createAllBtn:SetText(L["Enchant Vellum"])
if strfind(name, "Weapon") or strfind(name, "Staff") then
createAllBtn.vellum = TSMAPI:GetSafeItemInfo("item:52511:0:0:0:0:0:0") -- Weapon Vellum
4 years ago
else
createAllBtn.vellum = TSMAPI:GetSafeItemInfo("item:52510:0:0:0:0:0:0") -- Armor Vellum
4 years ago
end
else
createAllBtn:SetText(CREATE_ALL)
createAllBtn.vellum = nil
end
if numAvailable > 0 and not IsTradeSkillLinked() then
local num = self.buttonsFrame.inputBox:GetNumber()
self.buttonsFrame.inputBox:SetNumber(max(min(num, numAvailable), 1))
self.buttonsFrame.createBtn:Enable()
self.buttonsFrame.createAllBtn:Enable()
else
self.buttonsFrame.inputBox:SetNumber(1)
self.buttonsFrame.createBtn:Disable()
self.buttonsFrame.createAllBtn:Disable()
end
end
return frame
end
local RestockGroups
function GUI:CreateGroupsTab(parent)
local frame = CreateFrame("Frame", nil, parent)
frame:SetAllPoints()
TSMAPI.Design:SetFrameBackdropColor(frame)
local stContainer = CreateFrame("Frame", nil, frame)
stContainer:SetPoint("TOPLEFT", 5, -5)
stContainer:SetPoint("BOTTOMRIGHT", -5, 35)
TSMAPI.Design:SetFrameColor(stContainer)
local groupTree = TSMAPI:CreateGroupTree(stContainer, "Crafting", "Crafting_Profession")
RestockGroups = groupTree
4 years ago
local function OnCreateBtnClick()
if TSM.db.realm.tradeSkills[UnitName("player")][GetTradeSkillLine()] then
TSM.db.realm.tradeSkills[UnitName("player")][GetTradeSkillLine()].prompted = nil
4 years ago
end
private.forceCreateGroups = true
TSM.Util:ScanCurrentProfession()
end
local function OnRestockBtnClick()
TSM.Queue:CreateRestockQueue(groupTree:GetSelectedGroupInfo())
GUI:UpdateQueue()
end
local btn = TSMAPI.GUI:CreateButton(frame, 13)
btn:SetPoint("BOTTOMLEFT", 5, 5)
btn:SetWidth(160)
btn:SetHeight(24)
btn:SetText(L["Create Profession Groups"])
btn:SetScript("OnClick", OnCreateBtnClick)
frame.createBtn = btn
local btn = TSMAPI.GUI:CreateButton(frame, 20)
btn:SetPoint("BOTTOMLEFT", frame.createBtn, "BOTTOMRIGHT", 5, 0)
btn:SetPoint("BOTTOMRIGHT", -5, 5)
btn:SetHeight(24)
btn:SetText(L["Restock Selected Groups"])
btn:SetScript("OnClick", OnRestockBtnClick)
frame.restockBtn = btn
return frame
end
function GUI:UpdateProfessionsTabST()
if not GUI.frame or not GUI.frame:IsVisible() then return end
4 years ago
local stData = {}
TSM:UpdateCraftReverseLookup()
local showAll = TSM.db.global.showAllProfessions
local player = UnitName("player")
4 years ago
local function RGBPercToHex(tbl)
local r = tbl.r
local g = tbl.g
local b = tbl.b
r = r <= 1 and r >= 0 and r or 0
g = g <= 1 and g >= 0 and g or 0
b = b <= 1 and b >= 0 and b or 0
return string.format("%02x%02x%02x", r * 255, g * 255, b * 255)
end
if priceTextCache.lastClear + 60 < time() then
wipe(priceTextCache)
priceTextCache.lastClear = time()
end
local function GetInventoryTotals()
local totals = {}
local bags = TSMAPI:ModuleAPI("ItemTracker", "playerbags", player)
local bank = TSMAPI:ModuleAPI("ItemTracker", "playerbank", player)
if bags or bank then
for itemString, quantity in pairs(bags or {}) do
totals[itemString] = (totals[itemString] or 0) + quantity
end
for itemString, quantity in pairs(bank or {}) do
totals[itemString] = (totals[itemString] or 0) + quantity
end
return totals
end
return select(4, TSM.Inventory:GetTotals())
end
local ts = ""
local numAvailableAllCache = {}
local inventoryTotals = GetInventoryTotals()
if showAll then
local searchText = GUI.frame and GUI.frame.content and GUI.frame.content.professionsTab and GUI.frame.content.professionsTab.searchBar and GUI.frame.content.professionsTab.searchBar:GetText() or ""
if searchText == SEARCH then
searchText = ""
end
searchText = strlower(searchText or "")
local filterHaveMats = GUI.frame and GUI.frame.content and GUI.frame.content.professionsTab and GUI.frame.content.professionsTab.HaveMatsCheckBox and GUI.frame.content.professionsTab.HaveMatsCheckBox:GetValue()
local craftList = {}
for spellID, data in pairs(TSM.db.realm.crafts) do
if data.players and data.players[UnitName("player")] then
tinsert(craftList, {
spellID = spellID,
name = data.name or "",
profession = data.profession or UNKNOWN,
numResult = data.numResult or 1,
})
end
end
for _, craft in ipairs(craftList) do
craft.cost, craft.buyout, craft.profit = TSM.Cost:GetCraftPrices(craft.spellID)
if craft.profit and craft.cost and craft.cost > 0 then
craft.profitPercent = (craft.profit / craft.cost) * 100
else
craft.profitPercent = nil
end
local available = math.huge
if TSM.db.realm.crafts[craft.spellID] then
for itemString, quantity in pairs(TSM.db.realm.crafts[craft.spellID].mats) do
available = min(available, floor((inventoryTotals[itemString] or 0) / quantity))
end
end
craft.available = available ~= math.huge and available or 0
end
if searchText ~= "" or filterHaveMats then
local filtered = {}
for _, craft in ipairs(craftList) do
if (searchText == "" or strfind(strlower(craft.name or ""), searchText, 1, true)) and (not filterHaveMats or craft.available > 0) then
tinsert(filtered, craft)
end
end
craftList = filtered
end
if TSM.db.global.showAllProfessionsSortKey == "cost" then
sort(craftList, function(a, b)
local aValue = tonumber(a.cost) or math.huge
local bValue = tonumber(b.cost) or math.huge
if aValue == bValue then
return a.name < b.name
end
if TSM.db.global.showAllProfessionsSortDescending then
return aValue > bValue
end
return aValue < bValue
end)
elseif TSM.db.global.showAllProfessionsSortKey == "profit" then
sort(craftList, function(a, b)
local aValue = tonumber(a.profit) or -math.huge
local bValue = tonumber(b.profit) or -math.huge
if aValue == bValue then
return a.name < b.name
end
if TSM.db.global.showAllProfessionsSortDescending then
return aValue > bValue
end
return aValue < bValue
end)
elseif TSM.db.global.showAllProfessionsSortKey == "available" then
sort(craftList, function(a, b)
local aValue = tonumber(a.available) or -math.huge
local bValue = tonumber(b.available) or -math.huge
if aValue == bValue then
return a.name < b.name
end
if TSM.db.global.showAllProfessionsSortDescending then
return aValue > bValue
end
return aValue < bValue
end)
elseif TSM.db.global.showAllProfessionsSortKey == "profitPercent" then
sort(craftList, function(a, b)
local aValue = tonumber(a.profitPercent) or -math.huge
local bValue = tonumber(b.profitPercent) or -math.huge
if aValue == bValue then
return a.name < b.name
end
if TSM.db.global.showAllProfessionsSortDescending then
return aValue > bValue
end
return aValue < bValue
end)
else
sort(craftList, function(a, b)
if TSM.db.global.showAllProfessionsSortDescending then
return a.name > b.name
end
return a.name < b.name
end)
end
for _, craft in ipairs(craftList) do
local spellID = craft.spellID
local craftName = craft.name
if not numAvailableAllCache[spellID] then
local numAvailableAll = math.huge
if spellID and TSM.db.realm.crafts[spellID] then
for itemString, quantity in pairs(TSM.db.realm.crafts[spellID].mats) do
numAvailableAll = min(numAvailableAll, floor((inventoryTotals[itemString] or 0) / quantity))
end
end
if numAvailableAll ~= math.huge then
numAvailableAllCache[spellID] = numAvailableAll
end
end
local available = craft.available or 0
local displayName = craftName
local costText
local profitText
local cost, _, profit = craft.cost, craft.buyout, craft.profit
if cost and cost > 0 then
costText = TSMAPI:FormatTextMoney(cost, TSMAPI.Design:GetInlineColor("link"))
else
costText = "---"
end
if profit then
if profit < 0 then
profitText = "|cffff0000-|r" .. TSMAPI:FormatTextMoney(-profit, "|cffff0000")
else
profitText = TSMAPI:FormatTextMoney(profit, "|cff00ff00")
end
else
profitText = "---"
end
local profitPercent = "---"
if profit and cost and cost > 0 then
profitPercent = craft.profitPercent
if profit < 0 then
profitPercent = format("%s%.0f%%|r", "|cffff0000", profitPercent)
else
profitPercent = format("%s%.0f%%|r", "|cff00ff00", profitPercent)
end
end
tinsert(stData, {
cols = {
{ value = available },
{ value = displayName },
{ value = costText or "" },
{ value = profitText or "" },
{ value = profitPercent or "" },
},
spellID = spellID,
profession = craft.profession,
})
end
local frame = GUI.frame.content.professionsTab
frame.st:SetData(stData)
return
end
4 years ago
local collapseAllRow = {
cols = {
{ value = "" },
4 years ago
{
value = "|cff" .. RGBPercToHex(TradeSkillTypeColor.header) .. ALL .. " [" .. (TradeSkillCollapseAllButton.collapsed and "+" or "-") .. "]|r",
},
{ value = "" },
{ value = "" },
{ value = "" },
4 years ago
},
isCollapseAll = true,
}
tinsert(stData, collapseAllRow)
for i = 1, GetNumTradeSkills() do
-- local skillName, skillType, numAvailable, isExpanded, _, numSkillUps, _, showProgressBar, currentRank, maxRank = GetTradeSkillInfo(i)
local skillName, skillType, numAvailable, isExpanded, _ = GetTradeSkillInfo(i)
if skillName then
local spellID = TSM.Util:GetSpellID(i)
local key = skillName .. i
if skillType == "header" then
ts = ""
elseif skillType == "subheader" then
ts = " "
end
if skillType == "header" or skillType == "subheader" then
-- if showProgressBar then
-- skillName = skillName .. " (" .. currentRank .. "/" .. maxRank .. ") " .. (isExpanded and " [-]" or " [+]")
-- else
skillName = skillName .. (isExpanded and " [-]" or " [+]")
-- end
end
-- if numSkillUps > 1 and skillType == "optimal" then
-- skillName = skillName .. " <" .. numSkillUps .. ">"
-- end
if not numAvailableAllCache[spellID] then
local numAvailableAll = math.huge
if spellID and TSM.db.realm.crafts[spellID] then
for itemString, quantity in pairs(TSM.db.realm.crafts[spellID].mats) do
4 years ago
numAvailableAll = min(numAvailableAll, floor((inventoryTotals[itemString] or 0) / quantity))
end
end
if numAvailableAll ~= math.huge then
numAvailableAllCache[spellID] = numAvailableAll
end
end
local available = numAvailableAllCache[spellID] or 0
skillName = ts .. "|cff" .. RGBPercToHex(TradeSkillTypeColor[skillType]) .. skillName .. "|r"
local costText
local profitText
local cost, _, profit = TSM.Cost:GetCraftPrices(spellID)
if cost and cost > 0 then
costText = TSMAPI:FormatTextMoney(cost, TSMAPI.Design:GetInlineColor("link"))
4 years ago
else
costText = "---"
4 years ago
end
if profit then
if profit < 0 then
profitText = "|cffff0000-|r" .. TSMAPI:FormatTextMoney(-profit, "|cffff0000")
4 years ago
else
profitText = TSMAPI:FormatTextMoney(profit, "|cff00ff00")
4 years ago
end
else
profitText = "---"
4 years ago
end
local profitPercent = "---"
if profit and cost and cost > 0 then
profitPercent = profit / cost * 100
4 years ago
if profit < 0 then
profitPercent = format("%s%.0f%%|r", "|cffff0000", profitPercent)
else
profitPercent = format("%s%.0f%%|r", "|cff00ff00", profitPercent)
end
4 years ago
end
4 years ago
local row = {
cols = {
{
value = spellID and available or "",
},
4 years ago
{
value = skillName,
},
{
value = spellID and costText or "",
},
{
value = spellID and profitText or "",
4 years ago
},
{
value = spellID and profitPercent or "",
},
},
index = i,
}
tinsert(stData, row)
if skillType == "header" then
ts = " "
elseif skillType == "subheader" then
ts = " "
end
end
end
local frame = GUI.frame.content.professionsTab
frame.st:SetData(stData)
GUI:UpdateSelectedTradeSkill(true)
end
function GUI:UpdateSelectedTradeSkill(forceUpdate)
if not GUI.frame or not GUI.frame.content or not GUI.frame.content.professionsTab:IsVisible() then return end
4 years ago
local frame = GUI.frame.content.professionsTab
TradeSkillFrame.selectedSkill = TradeSkillFrame.selectedSkill or 1
if TSM.db.global.showAllProfessions then
frame.craftInfoFrame:SetTradeSkillIndex(TradeSkillFrame.selectedSkill)
return
end
local selection = frame.st:GetSelection() or 0
if forceUpdate or selection - 1 ~= TradeSkillFrame.selectedSkill then
4 years ago
frame.st:SetSelection(TradeSkillFrame.selectedSkill + 1)
frame.craftInfoFrame:SetTradeSkillIndex(TradeSkillFrame.selectedSkill)
end
end
function GUI:UpdateQueue()
if not GUI.frame or not GUI.frame.queue or not GUI.frame.queue:IsVisible() then return end
TSM.Options:UpdateCraftST()
TSM:UpdateCraftReverseLookup()
GUI.craftNextInfo = nil
local skillIndexLookup = {}
for i = 1, GetNumTradeSkills() do
local spellID = TSM.Util:GetSpellID(i)
if spellID then
skillIndexLookup[spellID] = i
end
end
local queuedCrafts, queuedMats, totalCost, totalProfit = TSM.Queue:GetQueue()
GUI.frame.queue.profitLabel:SetAmounts(totalCost, totalProfit)
local currentProfession = GetTradeSkillLine()
local stData = {}
local bagTotals = TSM.Inventory:GetTotals(itemID)
4 years ago
for profession, crafts in pairs(queuedCrafts) do
local professionColor, playerColor
local players = {}
for player, data in pairs(TSM.db.realm.tradeSkills) do
4 years ago
if data[profession] then
tinsert(players, player)
end
end
if TSM.db.realm.tradeSkills[UnitName("player")][profession] then
4 years ago
playerColor = "|cffffffff"
if profession == currentProfession then
professionColor = "|cffffffff"
else
professionColor = "|cffff0000"
end
else
playerColor = "|cffff0000"
professionColor = "|cffff0000"
end
local professionCollapsed = TSM.db.realm.queueStatus.collapsed[profession]
4 years ago
local row = {
cols = {
{
value = format("%s (%s) %s%s|r", professionColor .. profession .. "|r", playerColor .. table.concat(players, ", ") .. "|r", TSMAPI.Design:GetInlineColor("link"), professionCollapsed and "[+]" or "[-]")
}
},
isTitle = true,
profession = profession,
}
tinsert(stData, row)
if not professionCollapsed then
for _, stage in ipairs(crafts) do
local stageCollapsed = TSM.db.realm.queueStatus.collapsed[profession .. stage.name]
4 years ago
local row = {
cols = {
{
value = format(" %s %s%s|r", stage.name, TSMAPI.Design:GetInlineColor("link"), stageCollapsed and "[+]" or "[-]")
}
},
isTitle = true,
stage = stage.name,
profession = profession,
}
tinsert(stData, row)
if not stageCollapsed then
local craftRows = {}
for spellID, numQueued in pairs(stage.crafts) do
local canCraft = math.huge
local velName
if TSM.VellumInfo[spellID] then
velName = GetItemInfo(TSM.VellumInfo[spellID])
end
for itemID, quantity in pairs(TSM.db.realm.crafts[spellID].mats) do
4 years ago
local MatName = GetItemInfo(itemID)
if MatName ~= nil and velName ~= nil and strfind(MatName, "Vellum") then
local NewItemString = CheapestVellum(itemID)
if itemID ~= NewItemString then
itemID = NewItemString
velName = GetItemInfo(itemID)
end
end
4 years ago
local numHave = bagTotals[itemID] or 0
canCraft = min(canCraft, floor(numHave / quantity))
end
local color
local craftIndex = skillIndexLookup[spellID]
if canCraft >= numQueued then
-- green (can craft all)
if craftIndex then
color = "|cff00ff00"
else
color = "|cff008800"
end
elseif canCraft > 0 then
-- blue (can craft some)
if craftIndex then
color = "|cff5599ff"
else
color = "|cff224488"
end
else
-- orange (can't craft any)
if craftIndex then
color = "|cffff7700"
else
color = "|cff883300"
end
end
local extra = ""
if not craftIndex then
if TSM.db.realm.crafts[spellID].players[UnitName("player")] and TSM.db.realm.crafts[spellID].profession == currentProfession then
4 years ago
extra = "|cffff0000[Filtered]|r "
end
end
local row = {
cols = {
{
value = " " .. extra .. color .. TSM.db.realm.crafts[spellID].name .. " (x" .. numQueued .. ")" .. "|r",
4 years ago
},
},
spellID = spellID,
canCraft = (canCraft > 0) and canCraft or 0,
numQueued = numQueued,
index = craftIndex,
velName = velName,
profit = select(3, TSM.Cost:GetCraftPrices(spellID)),
profession = GetTradeSkillLine(),
}
tinsert(craftRows, row)
end
sort(craftRows, function(a, b)
if (a.canCraft == 0 and b.canCraft == 0) or (a.canCraft >= a.numQueued and b.canCraft >= b.numQueued) then
if a.profit and b.profit and a.profit ~= b.profit then
return a.profit > b.profit
else
return a.spellID > b.spellID
end
elseif a.canCraft >= a.numQueued then
return true
elseif b.canCraft >= b.numQueued then
return false
else
return a.canCraft > b.canCraft
end
end)
for _, row in ipairs(craftRows) do
if not GUI.craftNextInfo and row.index and row.canCraft > 0 then
GUI.craftNextInfo = { spellID = row.spellID, index = row.index, quantity = min(row.numQueued, row.canCraft), velName = row.velName, isCrafting = 0 }
end
tinsert(stData, row)
end
end
end
end
end
GUI.frame.queue.craftST:SetData(stData)
stData = {}
local totalMats = {}
for _, data in pairs(queuedMats) do
for itemString, quantity in pairs(data) do
4 years ago
local MatName = GetItemInfo(itemString)
if MatName ~= nil and strfind(MatName, "Vellum") then
4 years ago
local NewItemString = CheapestVellum(itemString)
if itemString ~= NewItemString then
itemString = NewItemString
end
end
totalMats[itemString] = (totalMats[itemString] or 0) + quantity
4 years ago
end
end
for itemString, quantity in pairs(totalMats) do
local cost = TSM.Cost:GetMatCost(itemString)
local need = max(quantity - TSM.Inventory:GetTotalQuantity(itemString), 0)
local color, order
if need == 0 then
if TSM.Inventory:GetPlayerBagNum(itemString) >= quantity then
color = "|cff00ff00"
order = 1
else
color = "|cffffff00"
order = 2
end
else
color = "|cffff0000"
order = 3
end
local row = {
cols = {
{
value = color .. TSM.db.realm.mats[itemString].name .. "|r",
args = { TSM.db.realm.mats[itemString].name },
4 years ago
},
{
value = color .. need .. "|r",
args = { need },
},
{
value = color .. quantity .. "|r",
args = { quantity },
},
{
value = TSMAPI:FormatTextMoney(cost) or "---",
args = { cost },
},
},
itemString = itemString,
order = order,
}
tinsert(stData, row)
end
sort(stData, function(a, b) return a.order < b.order end)
GUI.frame.queue.matST:SetData(stData)
-- TSMAPI:CreateTimeDelay("gatheringUpdateThrottle", 0.3, GUI.UpdateGathering)
4 years ago
TSMAPI:CreateTimeDelay("UpdateCraftButtonThrottle", 0.2, GUI.UpdateCraftButton)
end
function GUI:UpdateCraftButton()
if UnitCastingInfo("player") or not GUI.craftNextInfo then
TSMCraftNextButton:Disable()
elseif GUI.isCrafting and GUI.isCrafting.quantity > 0 then
TSMCraftNextButton:Disable()
else
TSMCraftNextButton:Enable()
end
end
function GUI:ShowProfessionsTab()
GUI.frame.navFrame.groupsBtn:UnlockHighlight()
GUI.frame.navFrame.professionsBtn:LockHighlight()
GUI.frame.content.groupsTab:Hide()
GUI.frame.content.professionsTab:Show()
GUI:UpdateProfessionsTabST()
GUI.frame.content.professionsTab.craftInfoFrame.buttonsFrame.inputBox:SetNumber(1)
end
function GUI:ShowGroupsTab()
GUI.frame.navFrame.professionsBtn:UnlockHighlight()
GUI.frame.navFrame.groupsBtn:LockHighlight()
GUI.frame.content.professionsTab:Hide()
GUI.frame.content.groupsTab:Show()
4 years ago
if QuickRestock then
QuickRestock = false
TSM.Queue:CreateRestockQueue(RestockGroups:GetSelectedGroupInfo())
GUI:UpdateQueue()
GUI.ShowProfessionsTab()
end
end
function GUI:CreatePromptFrame(parent)
local frame = CreateFrame("Frame", nil, parent)
TSMAPI.Design:SetFrameBackdropColor(frame)
frame:SetAllPoints()
frame:SetFrameLevel(20)
frame:EnableMouse(true)
frame:Hide()
local text = frame:CreateFontString()
text:SetPoint("LEFT", 5, 50)
text:SetPoint("RIGHT", -5, 50)
text:SetHeight(100)
text:SetFont(TSMAPI.Design:GetContentFont("normal"))
text:SetText(L["Would you like to automatically create some TradeSkillMaster groups for this profession?"])
frame.text = text
frame.SetText = function(_, ...) text:SetText(...) end
local yesBtn = TSMAPI.GUI:CreateButton(frame, 16)
yesBtn:SetPoint("CENTER", -110, 0)
yesBtn:SetWidth(100)
yesBtn:SetHeight(20)
yesBtn:SetText(YES)
yesBtn:SetScript("OnClick", function()
TSM:Printf(L["Created profession group for %s."], frame.profession)
TSMAPI:CreatePresetGroups(frame.presetGroupInfo)
TSM.db.realm.tradeSkills[UnitName("player")][frame.profession].prompted = true
4 years ago
frame:Hide()
GUI:UpdateProfessionsTabST()
end)
frame.yesBtn = yesBtn
local laterBtn = TSMAPI.GUI:CreateButton(frame, 16)
laterBtn:SetPoint("CENTER")
laterBtn:SetWidth(100)
laterBtn:SetHeight(20)
laterBtn:SetText(L["Ask Later"])
laterBtn:SetScript("OnClick", function() frame:Hide() end)
frame.laterBtn = laterBtn
local noBtn = TSMAPI.GUI:CreateButton(frame, 16)
noBtn:SetPoint("CENTER", 110, 0)
noBtn:SetWidth(100)
noBtn:SetHeight(20)
noBtn:SetText(L["No Thanks"])
noBtn:SetScript("OnClick", function()
TSM.db.realm.tradeSkills[UnitName("player")][frame.profession].prompted = true
4 years ago
frame:Hide()
end)
frame.noBtn = noBtn
return frame
end
function GUI:PromptPresetGroups(currentTradeSkill, presetGroupInfo)
GUI:RestoreFilters()
if TSM.db.realm.tradeSkills[UnitName("player")][currentTradeSkill] and not TSM.db.realm.tradeSkills[UnitName("player")][currentTradeSkill].prompted then
4 years ago
GUI.frame.prompt.profession = currentTradeSkill
GUI.frame.prompt.presetGroupInfo = presetGroupInfo
GUI.frame.prompt:Show()
if private.forceCreateGroups then
private.forceCreateGroups = nil
GUI.frame.prompt.yesBtn:Click()
end
end
end
function GUI:CreateGatheringSelectionFrame(parent)
local frame = CreateFrame("Frame", nil, parent)
frame:SetFrameStrata("HIGH")
frame:SetHeight(200)
frame:SetWidth(250)
frame:SetPoint("TOPLEFT", parent, "TOPRIGHT", 2, 0)
frame:EnableMouse(true)
frame:SetScript("OnMouseDown", function() parent:StartMoving() end)
frame:SetScript("OnMouseUp", function() parent:StopMovingOrSizing() end)
TSMAPI.Design:SetFrameBackdropColor(frame)
local title = TSMAPI.GUI:CreateLabel(frame)
title:SetText("TSM_Crafting - " .. L["Gathering"])
title:SetPoint("TOPLEFT")
title:SetPoint("TOPRIGHT")
title:SetHeight(20)
TSMAPI.GUI:CreateHorizontalLine(frame, -23)
local text1 = TSMAPI.GUI:CreateLabel(frame)
text1:SetText(L["First select a crafter"])
text1:SetPoint("TOPLEFT", 5, -28)
text1:SetPoint("TOPRIGHT", -5, -28)
text1:SetHeight(20)
text1:SetJustifyH("CENTER")
text1:SetJustifyV("CENTER")
frame.text1 = text1
TSMAPI.GUI:CreateHorizontalLine(frame, -52)
local dropdown = TSMAPI.GUI:CreateDropdown(frame)
dropdown:SetPoint("TOPLEFT", 5, -55)
dropdown:SetPoint("TOPRIGHT", -5, -55)
dropdown:SetLabel(L["Crafter"])
dropdown:SetCallback("OnValueChanged", function(_, _, value)
private.gather.player = value
private.gather.professions = nil
GUI:UpdateGatherSelectionWindow()
end)
frame.playerDropdown = dropdown
local dropdown = TSMAPI.GUI:CreateDropdown(frame)
dropdown:SetPoint("TOPLEFT", 5, -100)
dropdown:SetPoint("TOPRIGHT", -5, -100)
dropdown:SetLabel(L["Professions"])
dropdown:SetMultiselect(true)
dropdown:SetCallback("OnValueChanged", function(_, _, profession, value)
private.gather.professions[profession] = value or nil
GUI:UpdateGatherSelectionWindow()
end)
frame.professionDropdown = dropdown
TSMAPI.GUI:CreateHorizontalLine(frame, -150)
local btn = TSMAPI.GUI:CreateButton(frame, 18)
btn:SetPoint("BOTTOMLEFT", 5, 5)
btn:SetPoint("BOTTOMRIGHT", -5, 5)
btn:SetHeight(24)
btn:SetText(L["Start Gathering"])
btn:SetScript("OnClick", GUI.StartGathering)
frame.gatherButton = btn
return frame
end
function GUI:UpdateGatherSelectionWindow()
-- create table of crafters
local queuedCrafts = TSM.Queue:GetQueue()
local crafters = {}
local numCrafters = 0
for profession, _ in pairs(queuedCrafts) do
for player, data in pairs(TSM.db.realm.tradeSkills) do
4 years ago
if data[profession] then
crafters[player] = player
numCrafters = numCrafters + 1
end
end
end
local frame = GUI.frame.gather
frame.playerDropdown:SetList(crafters)
if not private.gather.player then
if crafters[UnitName("player")] then
private.gather.player = UnitName("player")
elseif numCrafters == 1 then
private.gather.player = next(crafters)
end
end
if private.gather.player then
frame.playerDropdown:SetValue(private.gather.player)
-- create table of professions
local professions = {}
local numProfessions = 0
for profession, _ in pairs(queuedCrafts) do
if TSM.db.realm.tradeSkills[private.gather.player][profession] then
4 years ago
professions[profession] = profession
numProfessions = numProfessions + 1
end
end
frame.professionDropdown:SetList(professions)
if not private.gather.professions then
private.gather.professions = {}
for profession in pairs(professions) do
private.gather.professions[profession] = true
end
end
local currentProfession = GetTradeSkillLine()
if currentProfession and professions[currentProfession] then
private.gather.professions[currentProfession] = true
end
if next(private.gather.professions) then
frame.gatherButton:Enable()
else
frame.gatherButton:Disable()
end
frame.professionDropdown:SetDisabled(false)
for profession in pairs(professions) do
frame.professionDropdown:SetItemValue(profession, private.gather.professions[profession])
end
else
frame.playerDropdown:SetValue()
frame.professionDropdown:SetDisabled(true)
frame.professionDropdown:SetValue({})
frame.gatherButton:Disable()
end
end
function GUI:CreateGatheringFrame()
local frameDefaults = {
x = 850,
y = 450,
width = 325,
height = 400,
scale = 1,
}
local frame = TSMAPI:CreateMovableFrame("TSMCraftingGatherFrame", frameDefaults)
frame:SetFrameStrata("HIGH")
TSMAPI.Design:SetFrameBackdropColor(frame)
local title = TSMAPI.GUI:CreateLabel(frame)
title:SetText("TSM_Crafting - " .. L["Gathering"])
title:SetPoint("TOPLEFT")
title:SetPoint("TOPRIGHT")
title:SetHeight(20)
TSMAPI.Design:SetTitleTextColor(title)
TSMAPI.GUI:CreateHorizontalLine(frame, -21)
local label = TSMAPI.GUI:CreateLabel(frame)
label:SetText("")
label:SetPoint("TOPLEFT", 0, -22)
label:SetPoint("TOPRIGHT", 0, -22)
label:SetHeight(20)
frame.label = label
TSMAPI.GUI:CreateHorizontalLine(frame, -42)
local containersFrame = CreateFrame("Frame", nil, frame)
containersFrame:SetPoint("TOPLEFT", 2, -45)
containersFrame:SetPoint("TOPRIGHT", -2, -45)
containersFrame:SetPoint("BOTTOMLEFT", 2, 53)
local matsFrame = CreateFrame("Frame", nil, containersFrame)
matsFrame:SetPoint("TOPLEFT")
matsFrame:SetPoint("BOTTOMRIGHT", containersFrame, "CENTER", -2, 2)
local stContainer = CreateFrame("Frame", nil, matsFrame)
stContainer:SetAllPoints()
TSMAPI.Design:SetFrameColor(stContainer)
local stCols = {
{ name = L["Material Name"], width = 0.69, headAlign = "Left" },
{ name = L["Need"], width = 0.2, headAlign = "Left" },
{ name = L["Total"], width = 0.2, headAlign = "Left" },
}
local function MatOnEnter(_, data, col)
local link = select(2, TSMAPI:GetSafeItemInfo(data.itemString))
if link then
GameTooltip:SetOwner(col, "ANCHOR_RIGHT")
TSMAPI:SafeTooltipLink(link)
GameTooltip:Show()
end
end
local function MatOnLeave(_, data)
GameTooltip:Hide()
end
frame.needST = TSMAPI:CreateScrollingTable(stContainer, stCols, { OnEnter = MatOnEnter, OnLeave = MatOnLeave }, 12)
frame.needST:SetData({})
frame.needST:DisableSelection(true)
local sourcesFrame = CreateFrame("Frame", nil, containersFrame)
sourcesFrame:SetPoint("TOPLEFT", containersFrame, "TOP", 2, 0)
sourcesFrame:SetPoint("BOTTOMRIGHT")
local stContainer2 = CreateFrame("Frame", nil, sourcesFrame)
stContainer2:SetAllPoints()
TSMAPI.Design:SetFrameColor(stContainer2)
local stCols2 = {
{ name = L["Available Sources"], width = 1, align = "Left" },
}
local function OnCraftRowClicked(_, data)
if data.isTitle then
if data.task then
TSM.db.realm.sourceStatus.collapsed[data.source .. data.task] = not TSM.db.realm.sourceStatus.collapsed[data.source .. data.task]
4 years ago
else
TSM.db.realm.sourceStatus.collapsed[data.source] = not TSM.db.realm.sourceStatus.collapsed[data.source]
4 years ago
end
GUI:UpdateGathering()
end
end
4 years ago
local function AvilableOnEnter(_, data, col)
if not data.isTitle then
local link = select(2, TSMAPI:GetSafeItemInfo(data.cols[1].itemString))
if link then
GameTooltip:SetOwner(col, "ANCHOR_RIGHT")
TSMAPI:SafeTooltipLink(link)
GameTooltip:Show()
end
end
end
frame.sourcesST = TSMAPI:CreateScrollingTable(stContainer2, stCols2, { OnEnter = AvilableOnEnter, OnLeave = MatOnLeave, OnClick = OnCraftRowClicked }, 12)
frame.sourcesST:SetData({})
frame.sourcesST:DisableSelection(true)
local availFrame = CreateFrame("Frame", nil, containersFrame)
availFrame:SetPoint("TOPRIGHT", containersFrame, "CENTER", -2, -2)
availFrame:SetPoint("BOTTOMLEFT")
TSMAPI.Design:SetFrameBackdropColor(availFrame)
local stContainer3 = CreateFrame("Frame", nil, availFrame)
stContainer3:SetAllPoints()
TSMAPI.Design:SetFrameColor(stContainer3)
local stCols3 = {
{ name = L["Current Source"], width = 1, align = "Left" },
}
local function OnAvailRowClicked(_, data, _, button)
if data.name and data.taskType == L["Search for Mats"] then
if TSMAPI:AHTabIsVisible("Shopping") then
if data.need > 0 then
if button == "RightButton" then
TSM.Gather:ShoppingSearch(data.itemString, data.need, true)
else
TSM.Gather:ShoppingSearch(data.itemString, data.need)
end
end
else
TSM:Printf(L["Please switch to the Shopping Tab to perform the gathering search."])
end
end
end
4 years ago
frame.availableST = TSMAPI:CreateScrollingTable(stContainer3, stCols3, { OnEnter = MatOnEnter, OnLeave = MatOnLeave, OnClick = OnAvailRowClicked }, 12)
frame.availableST:SetData({})
frame.availableST:DisableSelection(true)
local checkboxFrame = CreateFrame("Frame", nil, frame)
checkboxFrame:SetPoint("TOPLEFT", containersFrame, "BOTTOMLEFT", 2, -2)
checkboxFrame:SetPoint("TOPRIGHT", containersFrame, "BOTTOMRIGHT", -2, 2)
checkboxFrame:SetPoint("BOTTOMLEFT", 2, 28)
local checkbox1 = TSMAPI.GUI:CreateCheckBox(checkboxFrame, L["If checked, only a normal AH search will be performed"])
checkbox1:SetPoint("LEFT", checkboxFrame, "LEFT", 0, 3)
--checkbox:SetPoint("BOTTOMRIGHT", checkboxFrame, "BOTTOMRIGHT")
checkbox1:SetHeight(18)
checkbox1:SetWidth(185)
checkbox1:SetValue(TSM.db.realm.gathering.destroyDisable)
4 years ago
checkbox1:SetLabel(L[" Disable Destroying Search"])
checkbox1:SetCallback("OnValueChanged", function(_, _, value)
TSM.db.realm.gathering.destroyDisable = value
4 years ago
end)
local checkbox2 = TSMAPI.GUI:CreateCheckBox(checkboxFrame, L["If checked, the AH destroying search will only look for even stacks"])
checkbox2:SetPoint("RIGHT", checkboxFrame, "RIGHT", 0, 3)
-- checkbox2:SetPoint("CENTER", checkboxFrame, "RIGHT")
--checkbox:SetPoint("BOTTOMRIGHT", checkboxFrame, "BOTTOMRIGHT")
checkbox2:SetHeight(18)
checkbox2:SetWidth(100)
checkbox2:SetValue(TSM.db.realm.gathering.evenStacks)
4 years ago
checkbox2:SetLabel(L["Even Stacks"])
checkbox2:SetCallback("OnValueChanged", function(_, _, value)
TSM.db.realm.gathering.evenStacks = value
4 years ago
end)
TSMAPI.Design:SetFrameColor(checkboxFrame)
local btn = TSMAPI.GUI:CreateButton(frame, 18)
btn:SetPoint("BOTTOMLEFT", frame, "BOTTOM", 2, 4)
btn:SetPoint("BOTTOMRIGHT", -4, 4)
btn:SetHeight(20)
btn:SetText(L["Stop Gathering"])
btn:SetScript("OnClick", function()
private.gather = {}
GUI.gatheringFrame:Hide()
TSM.db.realm.gathering.availableMats = {}
TSM.db.realm.gathering.crafter = nil
TSM.db.realm.gathering.neededMats = {}
TSM.db.realm.gathering.gatheredMats = false
TSM.db.realm.gathering.destroyingMats = {}
4 years ago
private.currentSource = nil
end)
local btn = TSMAPI.GUI:CreateButton(frame, 18)
btn:SetPoint("BOTTOMLEFT", 4, 4)
btn:SetPoint("BOTTOMRIGHT", frame, "BOTTOM", -2, 4)
btn:SetHeight(20)
btn:SetText(L["Gather Items"])
btn:Disable()
btn:SetScript("OnClick", function()
TSM.Gather:gatherItems(private.currentSource, private.currentTask)
end)
frame.gatherButton = btn
return frame
end
function GUI:StartGathering()
GUI.frame.gather:Hide()
TSM.db.realm.gathering.gatheredMats = false
4 years ago
local _, queuedMats = TSM.Queue:GetQueue()
local neededMats = {}
for profession, data in pairs(queuedMats) do
if private.gather.professions[profession] then
for itemString, quantity in pairs(data) do
neededMats[itemString] = (neededMats[itemString] or 0) + quantity
end
end
end
if not next(neededMats) then
TSM:Print(L["Nothing To Gather"])
else
TSM.db.realm.gathering.crafter = private.gather.player
TSM.db.realm.gathering.professions = private.gather.professions
TSM.db.realm.gathering.neededMats = neededMats
4 years ago
GUI.gatheringFrame:Show()
GUI:UpdateGathering()
end
private.gather = {}
end
function GUI:UpdateGathering()
if not GUI.gatheringFrame or not GUI.gatheringFrame:IsVisible() then return end
if not TSM.db.realm.gathering.crafter or not next(TSM.db.realm.gathering.neededMats) then return end
4 years ago
-- recheck the craft queue and update neededMats
local _, queuedMats = TSM.Queue:GetQueue()
local neededMats = {}
for profession, data in pairs(queuedMats) do
if TSM.db.realm.gathering.professions[profession] then
4 years ago
for itemString, quantity in pairs(data) do
neededMats[itemString] = (neededMats[itemString] or 0) + quantity
end
end
end
local stData = {}
local sources = {}
local crafter = TSM.db.realm.gathering.crafter
4 years ago
local professionList = {}
for profession in pairs(TSM.db.realm.gathering.professions) do
4 years ago
tinsert(professionList, profession)
end
-- double check if crafter already has all the items needed
local shortItems = {}
local crafterBags = TSMAPI:ModuleAPI("ItemTracker", "playerbags", crafter) or {}
for itemString, quantity in pairs(neededMats) do
local need = max(quantity - (crafterBags[itemString] or 0), 0)
if need > 0 then
shortItems[itemString] = need
end
end
if not next(shortItems) then
GUI.gatheringFrame:Hide()
if TSM.db.realm.gathering.gatheredMats == true then
4 years ago
TSM:Print("Finished Gathering")
TSM.db.realm.gathering.gatheredMats = false
TSM.db.realm.gathering.crafter = nil
TSM.db.realm.gathering.neededMats = {}
TSM.db.realm.gathering.gatheredMats = false
TSM.db.realm.sourceStatus.collapsed = {}
TSM.db.realm.gathering.destroyingMats = {}
4 years ago
end
return
else
TSM.db.realm.gathering.neededMats = CopyTable(neededMats)
4 years ago
end
sort(professionList)
local professionsUsed = table.concat(professionList, ", ")
GUI.gatheringFrame.label:SetText(crafter .. " (" .. professionsUsed .. ")")
for itemString, quantity in pairs(neededMats) do
local need = max(quantity - (TSM.Inventory:GetTotalQuantity(itemString) or 0), 0)
local color, order
if need == 0 then
if (crafterBags[itemString] or 0) >= quantity then
color = "|cff00ff00"
order = 1
else
color = "|cffffff00"
order = 2
end
else
color = "|cffff0000"
order = 3
end
local row = {
cols = {
{
value = color .. TSM.db.realm.mats[itemString].name .. "|r",
args = { TSM.db.realm.mats[itemString].name },
4 years ago
},
{
value = color .. need .. "|r",
args = { need },
},
{
value = color .. quantity .. "|r",
args = { quantity },
},
},
itemString = itemString,
order = order,
name = TSM.db.realm.mats[itemString].name,
4 years ago
}
tinsert(stData, row)
end
sort(stData, function(a, b)
if a.order == 3 then return false end
if b.order == 3 then return true end
if a.order == 2 then return false end
if b.order == 2 then return true end
if a.order == 1 then return false end
if b.order == 1 then return true end
return a.name < b.name
end)
GUI.gatheringFrame.needST:SetData(stData)
-- update sources
local sources = TSM.Inventory:GetItemSources(crafter, neededMats) or {}
stData = {}
if next(sources) then
for _, source in ipairs(sources) do
local color
if source.sourceName == UnitName("player") then
color = "|cff00ff00"
else
color = "|cffffff00"
end
local sourceCollapsed = TSM.db.realm.sourceStatus.collapsed[source.sourceName]
4 years ago
local row = {
cols = {
{
value = format("%s %s%s|r", color .. source.sourceName, TSMAPI.Design:GetInlineColor("link"), sourceCollapsed and "[+]" or "[-]")
}
},
isTitle = true,
source = source.sourceName,
}
tinsert(stData, row)
if not sourceCollapsed then
for _, task in ipairs(source.tasks) do
local tasksCollapsed = TSM.db.realm.sourceStatus.collapsed[source.sourceName .. task.taskType]
4 years ago
local row = {
cols = {
{
value = format(" %s %s%s|r", color .. task.taskType, TSMAPI.Design:GetInlineColor("link"), tasksCollapsed and "[+]" or "[-]")
}
},
isTitle = true,
task = task.taskType,
source = source.sourceName,
}
tinsert(stData, row)
if not tasksCollapsed then
for itemString, quantity in pairs(task.items) do
local needQty
if source.sourceName == L["Destroying"] or task.taskType == L["Collect Mail"] or task.taskType == L["Mail Items"] then
if neededMats[itemString] then
needQty = min(quantity, neededMats[itemString])
else
needQty = quantity
end
else
needQty = neededMats[itemString] - (crafterBags[itemString] or 0)
end
local name = TSMAPI:GetSafeItemInfo(itemString) or itemString
local row
-- if task.taskType == L["Search for Mats"] or task.taskType == L["Visit Vendor"] or task.taskType == L["Collect Mail"] or task.taskType == L["Mail Items"] then
row = {
cols = {
{
value = format(" %s", color .. name .. " x" .. min(needQty, quantity)),
itemString = itemString
}
},
}
-- else
-- row = {
-- cols = {
-- {
-- value = format(" %s", color .. name .. " x" .. needQty .. " (" .. quantity .. " Avail)")
-- }
-- },
-- }
-- end
tinsert(stData, row)
end
end
end
end
end
end
GUI.gatheringFrame.sourcesST:SetData(stData)
-- update available mats if at a valid source
stData = {}
local availableMats = {}
local playerBags = TSMAPI:ModuleAPI("ItemTracker", "playerbags", UnitName("player")) or {}
local crafterMail = TSMAPI:ModuleAPI("ItemTracker", "playermail", crafter) or {}
for itemString, quantity in pairs(neededMats) do
local need = quantity - (crafterBags[itemString] or 0)
if UnitName("player") ~= crafter then
need = need - (crafterMail[itemString] or 0)
end
if need > 0 then
if next(sources) then
for _, source in ipairs(sources) do
if private.currentSource and private.currentSource == source.sourceName then
for _, task in ipairs(source.tasks) do
if private.currentTask and private.currentTask == task.taskType then
for taskItemString, taskQuantity in pairs(task.items) do
if taskItemString == itemString then
if task.taskType == L["Visit Vendor"] and not TSM.Gather:MerchantSells(itemString) then
break
end
local availQty
if task.taskType == L["Search for Mats"] then
availQty = taskQuantity
end
if task.taskType == L["Mail Items"] or task.taskType == L["Collect Mail"] then
4 years ago
availQty = min(need, taskQuantity)
elseif not crafter == UnitName("player") then
availQty = min(need, taskQuantity) - (playerBags[itemString] or 0)
else
availQty = min(need, taskQuantity) -- (crafterBags[itemString] or 0)
end
availableMats[itemString] = availQty
local name = select(1, TSMAPI:GetSafeItemInfo(itemString))
if not name then
name = GetItemInfo(itemString)
end
4 years ago
local color
if need == availQty then
color = "|cff00ff00"
else
color = "|cffffff00"
end
local row = {
cols = {
{
value = color .. name .. " x" .. availQty .. "|r",
args = name,
}
},
name = name,
itemString = taskItemString,
need = availQty,
taskType = task.taskType,
}
tinsert(stData, row)
end
end
end
end
end
end
end
end
end
-- store the available mats from source
TSM.db.realm.gathering.availableMats = CopyTable(availableMats)
4 years ago
GUI.gatheringFrame.gatherButton:SetText(L["Gather Items"])
if next(stData) then
GUI.gatheringFrame.gatherButton:Enable()
if private.currentTask == L["Visit Vendor"] then
GUI.gatheringFrame.gatherButton:SetText(L["Buy Vendor Items"])
elseif private.currentTask == L["Mail Items"] then
GUI.gatheringFrame.gatherButton:SetText(L["Mail Items"])
elseif private.currentTask == L["Collect Mail"] then
GUI.gatheringFrame.gatherButton:SetText(L["Collect Mail"])
end
else
GUI.gatheringFrame.gatherButton:Disable()
4 years ago
end
sort(stData, function(a, b) return a.name < b.name end)
GUI.gatheringFrame.availableST:SetData(stData)
end
function GUI:GatheringEventHandler(event)
if not GUI.gatheringFrame or not GUI.gatheringFrame:IsShown() then return end
if event == "GUILDBANKFRAME_OPENED" then
private.currentSource = UnitName("player")
private.currentTask = L["Visit Guild Bank"]
elseif event == "GUILDBANKFRAME_CLOSED" then
private.currentSource = nil
private.currentTask = nil
GUI.gatheringFrame.gatherButton:Disable()
elseif event == "BANKFRAME_OPENED" then
private.currentSource = UnitName("player")
private.currentTask = L["Visit Bank"]
elseif event == "BANKFRAME_CLOSED" then
private.currentSource = nil
private.currentTask = nil
GUI.gatheringFrame.gatherButton:Disable()
elseif event == "MERCHANT_SHOW" then
private.currentSource = L["Vendor"]
private.currentTask = L["Visit Vendor"]
elseif event == "MERCHANT_CLOSED" then
private.currentSource = nil
private.currentTask = nil
GUI.gatheringFrame.gatherButton:Disable()
elseif event == "MAIL_SHOW" then
private.currentSource = UnitName("player")
local crafter = TSM.db.realm.gathering.crafter
if crafter and crafter == UnitName("player") then
private.currentTask = L["Collect Mail"]
else
private.currentTask = L["Mail Items"]
end
4 years ago
elseif event == "MAIL_CLOSED" then
private.currentSource = nil
private.currentTask = nil
GUI.gatheringFrame.gatherButton:Disable()
elseif event == "AUCTION_HOUSE_SHOW" then
TSM.Inventory.gatherQuantity = nil
TSM.Inventory.gatherItem = nil
private.currentSource = L["Auction House"]
private.currentTask = L["Search for Mats"]
elseif event == "AUCTION_HOUSE_CLOSED" then
TSM.Inventory.gatherQuantity = nil
TSM.Inventory.gatherItem = nil
private.currentSource = nil
private.currentTask = nil
GUI.gatheringFrame.gatherButton:Disable()
end
TSMAPI:CreateTimeDelay("gatheringUpdateThrottle", 0.3, GUI.UpdateGathering)
end
function GUI:GetStatus()
if not GUI.frame or not GUI.frame:IsVisible() then return end
return { page = (GUI.frame.content.professionsTab:IsVisible() and "profession" or "groups"), gather = GUI.frame.gather:IsVisible() and true or false, queue = GUI.frame.queue:IsVisible() and true or false }
end
function CheapestVellum(itemPassed)
-- Return one of the two vellum available
4 years ago
local MatName = GetItemInfo(itemPassed)
-- MatName is sometimes nil ???
if MatName ~= nil then
4 years ago
local velName
if strfind(MatName, "Vellum") then
velName = MatName
end
if (velName ~= nil) then
if strfind(velName, "Weapon") then
itemPassed = "item:52511:0:0:0:0:0:0"
4 years ago
else
itemPassed = "item:52510:0:0:0:0:0:0"
4 years ago
end
end
end
return itemPassed
end