-- ------------------------------------------------------------------------------ -- -- 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. -- -- ------------------------------------------------------------------------------ -- -- load the parent file (TSM) into a local variable and register this file as a module local TSM = select(2, ...) local Util = TSM:NewModule("Util") -- local VELLUM_ID = "item:38682:0:0:0:0:0:0" local scanTooltip function GetTradeSkillReagentItemLink(skillIndex, reagentLink) if not scanTooltip then scanTooltip = CreateFrame("GameTooltip", "TSMCraftingScanTooltip", UIParent, "GameTooltipTemplate") scanTooltip:SetOwner(UIParent, "ANCHOR_NONE") end scanTooltip:ClearLines() scanTooltip:SetTradeSkillItem(skillIndex, reagentLink) return select(2, scanTooltip:GetItem()) end function Util:IsProfessionReady() if GetTradeSkillLine() == "UNKNOWN" or not GetNumTradeSkills() or GetNumTradeSkills() <= 0 or InCombatLockdown() then return end for index=1, GetNumTradeSkills() do local itemLink = GetTradeSkillItemLink(index) local spellLink = GetTradeSkillRecipeLink(index) if itemLink and spellLink and strfind(spellLink, "enchant:") then local spellID, itemID, craftName if strfind(itemLink, "enchant:") then -- result of craft is enchant spellID = Util:GetSpellID(index) itemID = TSM.enchantingItemIDs[spellID] and "item:"..TSM.enchantingItemIDs[spellID]..":0:0:0:0:0:0" elseif strfind(itemLink, "item:") then -- result of craft is item itemID = TSMAPI:GetItemString(itemLink) spellID = Util:GetSpellID(index) else return end if itemID and spellID then for i=1, GetTradeSkillNumReagents(index) do local link = GetTradeSkillReagentItemLink(index, i) local name, _, quantity = GetTradeSkillReagentInfo(index, i) if not name or not link then return end end end end end return true end function Util:ScanCurrentProfession() if not Util:IsProfessionReady() then return TSMAPI:CreateTimeDelay("craftingScanDelay", 0.1, Util.ScanCurrentProfession) end local newCrafts = {} local playerName = UnitName("player") local currentTradeSkill = GetTradeSkillLine() local subClasses = {GetTradeSkillSubClasses()} local currentSubClass = 0 local usedItems = {} local presetGroupInfo = {} local reagentLinkCache = {} for index=1, GetNumTradeSkills() do local itemLink = GetTradeSkillItemLink(index) local spellLink = GetTradeSkillRecipeLink(index) if not itemLink then local skillName, skillType = GetTradeSkillInfo(index) if skillType == "header" then for j=1, #subClasses do if skillName == subClasses[j] then currentSubClass = j break end end end elseif spellLink and strfind(spellLink, "enchant:") then local spellID, itemID, craftName if strfind(itemLink, "enchant:") then -- result of craft is enchant spellID = Util:GetSpellID(index) itemID = TSM.enchantingItemIDs[spellID] and "item:"..TSM.enchantingItemIDs[spellID]..":0:0:0:0:0:0" craftName = GetSpellInfo(spellID) elseif strfind(itemLink, "item:") then -- result of craft is item itemID = TSMAPI:GetItemString(itemLink) craftName = TSMAPI:GetSafeItemInfo(itemLink) spellID = Util:GetSpellID(index) end if itemID and spellID then local lNum, hNum = GetTradeSkillNumMade(index) local numMade = floor(((lNum or 1) + (hNum or 1))/2) local hasCD = GetTradeSkillCooldown(index) and true or nil local mats = {} if currentTradeSkill == TSM.enchantingName and strfind(itemLink, "enchant:") then local VellumString = "item:"..TSM.VellumInfo[spellID]..":0:0:0:0:0:0" mats[VellumString] = 1 local name = TSMAPI:GetSafeItemInfo(VellumString) or nil TSM.db.realm.mats[VellumString] = TSM.db.realm.mats[VellumString] or {} TSM.db.realm.mats[VellumString].name = TSM.db.realm.mats[VellumString].name or name numMade = 1 end local isValid = true for i=1, GetTradeSkillNumReagents(index) do local name, texture, quantity = GetTradeSkillReagentInfo(index, i) if not name then isValid = false break end if not reagentLinkCache[name.."\001"..texture] then reagentLinkCache[name.."\001"..texture] = GetTradeSkillReagentItemLink(index, i) end local matID = TSMAPI:GetItemString(reagentLinkCache[name.."\001"..texture]) if not matID then isValid = false break end mats[matID] = quantity TSM.db.realm.mats[matID] = TSM.db.realm.mats[matID] or {} TSM.db.realm.mats[matID].name = TSM.db.realm.mats[matID].name or name end if isValid then local players = TSM.db.realm.crafts[spellID] and TSM.db.realm.crafts[spellID].players or {} players[playerName] = true local queued = TSM.db.realm.crafts[spellID] and TSM.db.realm.crafts[spellID].queued or 0 local intermediateQueued = TSM.db.realm.crafts[spellID] and TSM.db.realm.crafts[spellID].intermediateQueued or nil newCrafts[spellID] = {name=craftName, itemID=itemID, mats=mats, hasCD=hasCD, numResult=numMade, queued=queued, intermediateQueued=intermediateQueued, players=players, profession=currentTradeSkill} if not usedItems[itemID] then usedItems[itemID] = true local itemString = TSMAPI:GetItemString(itemID) if itemString then for matItemString in pairs(mats) do if not presetGroupInfo[matItemString] then presetGroupInfo[matItemString] = TSMAPI:JoinGroupPath("Professions", currentTradeSkill, "Materials") end end presetGroupInfo[itemString] = TSMAPI:JoinGroupPath("Professions", currentTradeSkill, "Crafts") end end end end end end -- search for and remove any spells that we can't craft anymore for spellID, data in pairs(TSM.db.realm.crafts) do if data.profession == currentTradeSkill then local hasCrafters = false for player in pairs(data.players) do if player ~= playerName or newCrafts[spellID] then hasCrafters = true break end end if not hasCrafters then TSM.db.realm.crafts[spellID] = nil end end end -- save the new craft info for spellID, data in pairs(newCrafts) do TSM.db.realm.crafts[spellID] = data end TSM.CraftingGUI:PromptPresetGroups(currentTradeSkill, presetGroupInfo) --Bugged, asks after every login. Not saving prompt result between sessions. Either saving or loading bug (works fine on /reload though). end function Util:StartScanSyncedProfessionThread() local function callback() TradeSkillFrame:Show() CloseTradeSkill() TSM.isSyncing = nil end TSMAPI.Threading:Start(Util.ScanSyncedProfessionThread, 0.5, callback) end function Util.ScanSyncedProfessionThread(self) local ready for i=1, 10 do if Util:IsProfessionReady() then ready = true break end self:Sleep(0.1) end if not ready then return end local newCrafts = {} local reagentLinkCache = {} local _, playerName = IsTradeSkillLinked() local currentTradeSkill = GetTradeSkillLine() if playerName ~= TSM.isSyncing.player then return end for index=1, GetNumTradeSkills() do local itemLink = GetTradeSkillItemLink(index) local spellLink = GetTradeSkillRecipeLink(index) if itemLink and spellLink and strfind(spellLink, "enchant:") then local spellID, itemID, craftName if strfind(itemLink, "enchant:") then -- result of craft is enchant spellID = Util:GetSpellID(index) itemID = TSM.enchantingItemIDs[spellID] and "item:"..TSM.enchantingItemIDs[spellID]..":0:0:0:0:0:0" craftName = GetSpellInfo(spellID) elseif strfind(itemLink, "item:") then -- result of craft is item itemID = TSMAPI:GetItemString(itemLink) craftName = TSMAPI:GetSafeItemInfo(itemLink) spellID = Util:GetSpellID(index) end if itemID and spellID then local lNum, hNum = GetTradeSkillNumMade(index) local numMade = floor(((lNum or 1) + (hNum or 1))/2) local hasCD = GetTradeSkillCooldown(index) and true or nil local mats = {} if currentTradeSkill == TSM.enchantingName and strfind(itemLink, "enchant:") then local VellumString = "item:"..TSM.VellumInfo[spellID]..":0:0:0:0:0:0" mats[VellumString] = 1 local name = TSMAPI:GetSafeItemInfo(VellumString) or nil TSM.db.realm.mats[VellumString] = TSM.db.realm.mats[VellumString] or {} TSM.db.realm.mats[VellumString].name = TSM.db.realm.mats[VellumString].name or name numMade = 1 end local isValid = true for i=1, GetTradeSkillNumReagents(index) do local name, texture, quantity = GetTradeSkillReagentInfo(index, i) if not name then isValid = false break end if not reagentLinkCache[name.."\001"..texture] then reagentLinkCache[name.."\001"..texture] = GetTradeSkillReagentItemLink(index, i) end local matID = TSMAPI:GetItemString(reagentLinkCache[name.."\001"..texture]) if not matID then isValid = false break end mats[matID] = quantity TSM.db.realm.mats[matID] = TSM.db.realm.mats[matID] or {} TSM.db.realm.mats[matID].name = TSM.db.realm.mats[matID].name or name end if isValid then local players = TSM.db.realm.crafts[spellID] and TSM.db.realm.crafts[spellID].players or {} players[playerName] = true local queued = TSM.db.realm.crafts[spellID] and TSM.db.realm.crafts[spellID].queued or 0 local intermediateQueued = TSM.db.realm.crafts[spellID] and TSM.db.realm.crafts[spellID].intermediateQueued or nil newCrafts[spellID] = {name=craftName, itemID=itemID, mats=mats, hasCD=hasCD, numResult=numMade, queued=queued, intermediateQueued=intermediateQueued, players=players, profession=currentTradeSkill} end end end self:Yield() if currentTradeSkill ~= GetTradeSkillLine() or select(2, IsTradeSkillLinked()) ~= TSM.isSyncing.player then return end end -- search for and remove any spells that we can't craft anymore for spellID, data in pairs(TSM.db.realm.crafts) do if data.profession == currentTradeSkill then local hasCrafters = false for player in pairs(data.players) do if player ~= playerName or newCrafts[spellID] then hasCrafters = true break end end if not hasCrafters then TSM.db.realm.crafts[spellID] = nil end end end -- save the new craft info for spellID, data in pairs(newCrafts) do TSM.db.realm.crafts[spellID] = data end local playerName = select(2, IsTradeSkillLinked()) local skillName, level, maxLevel = GetTradeSkillLine() TSM.db.realm.tradeSkills[playerName] = TSM.db.realm.tradeSkills[playerName] or {} TSM.db.realm.tradeSkills[playerName][skillName] = TSM.db.realm.tradeSkills[playerName][skillName] or {} TSM.db.realm.tradeSkills[playerName][skillName].link = TSM.isSyncing.link TSM.db.realm.tradeSkills[playerName][skillName].accountKey = TSM.isSyncing.accountKey TSM.db.realm.tradeSkills[playerName][skillName].level = level TSM.db.realm.tradeSkills[playerName][skillName].maxLevel = maxLevel end function Util:GetSpellID(index) local spellLink = GetTradeSkillRecipeLink(index) if not spellLink then return end return TSMAPI:GetItemID(spellLink) end function Util:FormatTime(seconds) if seconds == 0 then return end local hours = floor(seconds/3600) local mins = floor((seconds%3600)/60) local secs = seconds % 60 local str = "" if hours > 0 then str = str..format("%dh", hours) end if mins > 0 then str = str..format("%dm", mins) end if secs > 0 then str = str..format("%ds", secs) end return str end