local MAJOR, MINOR = 'LibProcessable', 19 assert(LibStub, MAJOR .. ' requires LibStub') local lib, oldMinor = LibStub:NewLibrary(MAJOR, MINOR) if(not lib) then return end local hasEnchantingBuilding local inscriptionSkill, jewelcraftingSkill, enchantingSkill, blacksmithingSkill local MILLING, MORTAR = 51005, 114942 --- API to verify if an item can be processed through the Milling skill or with the Draenic Mortar. -- @name LibProcessable:IsMillable -- @usage LibStub('LibProcessable'):IsMillable(itemID[, ignoreMortar]) -- @param itemID The itemID of the item to check against -- @param ignoreMortar Ignore the Draenic Mortar, an item to mill Draenor herbs without needing Inscription -- @return isMillable Boolean indicating if the player can process the item -- @return skillRequired Number representing the required skill to process the item -- @return skillLevel Number representing the player's skill in Inscription -- @return mortarItemID Number representing the Draenic Mortar, if used function lib:IsMillable(itemID, ignoreMortar) assert(tonumber(itemID), 'itemID needs to be a number or convertable to a number') itemID = tonumber(itemID) if(IsSpellKnown(MILLING)) then local skillRequired = lib.herbs[itemID] return skillRequired and skillRequired <= inscriptionSkill, skillRequired, inscriptionSkill elseif(not ignoreMortar and GetItemCount(MORTAR) > 0) then return itemID >= 109124 and itemID <= 109130, 1, nil, MORTAR end end local PROSPECTING = 31252 --- API to verify if an item can be processed through the Prospecting skill. -- @name LibProcessable:IsProspectable -- @usage LibStub('LibProcessable'):IsProspectable(itemID) -- @param itemID The itemID of the item to check against -- @return isProspectable Boolean indicating if the player can process the item -- @return skillRequired Number representing the required skill to process the item -- @return skillLevel Number representing the player's skill in Jewelcrafting function lib:IsProspectable(itemID) assert(tonumber(itemID), 'itemID needs to be a number or convertable to a number') itemID = tonumber(itemID) if(IsSpellKnown(PROSPECTING)) then local skillRequired = lib.ores[itemID] return skillRequired and skillRequired <= jewelcraftingSkill, skillRequired, jewelcraftingSkill end end -- https://gist.github.com/p3lim/57acb053b3efccad0275 local function GetSkillRequired(class, quality, level) if(class == 2) then -- Weapons if(quality == 2) then if(level > 449) then return 0 elseif(level > 416) then return 475 elseif(level > 403) then return 475 elseif(level > 390) then return 475 elseif(level > 377) then return 475 elseif(level > 363) then return 475 elseif(level > 312) then return 425 elseif(level > 305) then return 425 elseif(level > 289) then return 425 elseif(level > 272) then return 425 elseif(level > 200) then return 425 elseif(level > 153) then return 350 elseif(level > 120) then return 325 elseif(level > 99) then return 275 elseif(level > 79) then return 225 elseif(level > 65) then return 225 elseif(level > 60) then return 225 elseif(level > 55) then return 200 elseif(level > 50) then return 175 elseif(level > 45) then return 150 elseif(level > 40) then return 125 elseif(level > 35) then return 100 elseif(level > 30) then return 75 elseif(level > 25) then return 50 elseif(level > 20) then return 25 else return 1 end elseif(quality == 3) then if(level > 499) then return 0 elseif(level > 424) then return 550 elseif(level > 377) then return 525 elseif(level > 316) then return 450 elseif(level > 200) then return 450 elseif(level > 166) then return 325 elseif(level > 115) then return 325 elseif(level > 99) then return 275 elseif(level > 79) then return 225 elseif(level > 65) then return 225 elseif(level > 60) then return 225 elseif(level > 55) then return 200 elseif(level > 50) then return 175 elseif(level > 45) then return 150 elseif(level > 40) then return 125 elseif(level > 35) then return 100 elseif(level > 30) then return 75 elseif(level > 25) then return 50 else return 25 end elseif(quality == 4) then if(level > 599) then return 0 elseif(level > 419) then return 575 elseif(level > 299) then return 475 elseif(level > 199) then return 375 elseif(level > 99) then return 300 elseif(level > 65) then return 225 elseif(level > 60) then return 225 elseif(level > 55) then return 200 elseif(level > 50) then return 175 elseif(level > 45) then return 150 elseif(level > 40) then return 125 elseif(level > 35) then return 100 elseif(level > 30) then return 75 elseif(level > 25) then return 50 else return 25 end end elseif(class == 4) then -- Armor if(quality == 2) then if(level > 449) then return 0 elseif(level > 416) then return 475 elseif(level > 403) then return 475 elseif(level > 390) then return 475 elseif(level > 377) then return 475 elseif(level > 363) then return 475 elseif(level > 312) then return 425 elseif(level > 305) then return 425 elseif(level > 289) then return 425 elseif(level > 272) then return 425 elseif(level > 200) then return 425 elseif(level > 153) then return 350 elseif(level > 120) then return 325 elseif(level > 99) then return 275 elseif(level > 79) then return 225 elseif(level > 65) then return 225 elseif(level > 60) then return 225 elseif(level > 55) then return 200 elseif(level > 50) then return 175 elseif(level > 45) then return 150 elseif(level > 40) then return 125 elseif(level > 35) then return 100 elseif(level > 30) then return 75 elseif(level > 25) then return 50 elseif(level > 20) then return 25 else return 1 end elseif(quality == 3) then if(level > 499) then return 0 elseif(level > 424) then return 550 elseif(level > 377) then return 525 elseif(level > 316) then return 450 elseif(level > 200) then return 450 elseif(level > 166) then return 325 elseif(level > 115) then return 325 elseif(level > 99) then return 275 elseif(level > 79) then return 225 elseif(level > 65) then return 225 elseif(level > 60) then return 225 elseif(level > 55) then return 200 elseif(level > 50) then return 175 elseif(level > 45) then return 150 elseif(level > 40) then return 125 elseif(level > 35) then return 100 elseif(level > 30) then return 75 elseif(level > 25) then return 50 else return 25 end elseif(quality == 4) then if(level > 599) then return 0 elseif(level > 419) then return 575 elseif(level > 299) then return 475 elseif(level > 199) then return 375 elseif(level > 99) then return 300 elseif(level > 65) then return 225 elseif(level > 60) then return 225 elseif(level > 55) then return 200 elseif(level > 50) then return 175 elseif(level > 45) then return 150 elseif(level > 40) then return 125 elseif(level > 35) then return 100 elseif(level > 30) then return 75 elseif(level > 25) then return 50 else return 25 end end elseif(class == 3) then -- Artifact Relics -- TODO: needs refining but is good for now return 1 end end local DISENCHANTING = 13262 --- API to verify if an item can be processed through the Disenchanting skill or garrison buildings. -- @name LibProcessable:IsDisenchantable -- @usage LibStub('LibProcessable'):IsDisenchantable(itemID | itemLink[, ignoreGarrison[, ignoreGarrisonBuildingRequirement]]) -- @param itemID The itemID of the item to check against -- @param itemLink The itemLink of the item to check against -- @param ignoreGarrison Ignore the garrison enchanting buildings -- @param ignoreGarrisonBuildingRequirement Ignore the garrison enchanting building requirement -- @return isDisenchantable Boolean indicating if the player can process the item -- @return skillRequired Number representing the required skill to process the item -- @return skillLevel Number representing the player's skill in Enchanting function lib:IsDisenchantable(item, ignoreGarrison, ignoreGarrisonBuildingRequirement) if(type(item) == 'string') then if(not string.match(item, 'item:(%d+):') and not tonumber(item)) then assert(false, 'item must be an item ID or item Link') end if(tonumber(item)) then item = tonumber(item) end end if(IsSpellKnown(DISENCHANTING)) then local _, _, quality, _, _, _, _, _, _, _, _, class, subClass = GetItemInfo(item) if(class == 2 or class == 4 or (class == 3 and subClass == 11)) then local skillRequired = GetSkillRequired(class, quality, (GetDetailedItemLevelInfo(item))) return skillRequired and skillRequired <= enchantingSkill, skillRequired, enchantingSkill end elseif(not ignoreGarrison and (hasEnchantingBuilding or ignoreGarrisonBuildingRequirement)) then local _, _, quality, _, _, _, _, _, _, _, _, class, subClass = GetItemInfo(item) if(class == 2 or class == 4 or (class == 3 and subClass == 11)) then local skillRequired = GetSkillRequired(class, quality, (GetDetailedItemLevelInfo(item))) return skillRequired and skillRequired == 0, skillRequired, enchantingSkill end end end -- http://www.wowhead.com/items/name:key?filter=86;2;0 local function GetSkeletonKey(pickLevel) if(pickLevel > 425) then return 82960, 500, 450 -- Ghostly Skeleton Key elseif(pickLevel > 400) then return 55053, 475, 425 -- Obsidium Skeleton Key elseif(pickLevel > 375) then return 43853, 430, 400 -- Titanium Skeleton Key elseif(pickLevel > 300) then return 43854, 350, 375 -- Cobalt Skeleton Key elseif(pickLevel > 200) then return 15872, 275, 300 -- Arcanite Skeleton Key elseif(pickLevel > 125) then return 15871, 200, 200 -- Truesilver Skeleton Key elseif(pickLevel > 25) then return 15870, 150, 125 -- Golden Skeleton Key else return 15869, 100, 25 -- Silver Skeleton Key end end -- http://www.wowhead.com/items/name:lock?filter=86;7;0 local function GetJeweledLockpick(pickLevel) if(pickLevel <= 750) then return 130250, 1, 750 end end local LOCKPICKING = 1804 --- API to verify if an item can be opened through Rogue's Lock Pick skill -- @name LibProcessable:IsOpenable -- @usage LibStub('LibProcessable'):IsOpenable(itemID) -- @param itemID Number The itemID of the item to check against -- @return isOpenable Boolean `true` if the player can open the item, `false` otherwise -- @return pickLevel Number Represents the required lockpick level of the item -- @return skillLevel Number Represents the player's lockpicking skill level function lib:IsOpenable(itemID) assert(tonumber(itemID), 'itemID needs to be a number or convertable to a number') itemID = tonumber(itemID) local pickLevel = lib.containers[itemID] if(IsSpellKnown(LOCKPICKING)) then local skillLevel = UnitLevel('player') * 5 return pickLevel and pickLevel <= skillLevel, pickLevel, skillLevel end end local BLACKSMITHING, JEWELCRAFTING = 2018, 25229 --- API to verify if an item can be opened through the players' professions -- @name LibProcessable:IsOpenableProfession -- @usage LibStub('LibProcessable'):IsOpenableProfession(itemID) -- @param itemID Number The itemID of the item to check against -- @return isOpenable Boolean `true` if the player can open the item, `false` otherwise -- @return pickLevel Number Represents the required lockpick level of the item -- @return professionData Table Containing data relavant to the profession(s) that can open the item with a key function lib:IsOpenableProfession(itemID) assert(tonumber(itemID), 'itemID needs to be a number or convertable to a number') itemID = tonumber(itemID) local pickLevel = lib.containers[itemID] if(not pickLevel) then return false end local professionData, canOpen = {} if(GetSpellBookItemInfo(GetSpellInfo(BLACKSMITHING))) then local professionItemID, skillRequired, skillLevel = GetSkeletonKey(pickLevel) canOpen = skillRequired <= blacksmithingSkill and pickLevel <= skillLevel professionData['blacksmithing'] = { skillID = BLACKSMITHING, itemID = professionItemID, skillRequired = skillRequired, skillLevel = blacksmithingSkill, opensLevel = skillLevel } end if(GetSpellBookItemInfo(GetSpellInfo(JEWELCRAFTING))) then local professionItemID, skillRequired, skillLevel = GetJeweledLockpick(pickLevel) canOpen = skillRequired <= jewelcraftingSkill and pickLevel <= skillLevel professionData['jewelcrafting'] = { skillID = JEWELCRAFTING, itemID = professionItemID, skillRequired = skillRequired, skillLevel = jewelcraftingSkill, opensLevel = skillLevel } end return canOpen, pickLevel, professionData end local Handler = CreateFrame('Frame') Handler:RegisterEvent('SKILL_LINES_CHANGED') Handler:RegisterEvent('GARRISON_BUILDING_PLACED') Handler:RegisterEvent('GARRISON_BUILDING_REMOVED') Handler:SetScript('OnEvent', function(self, event, ...) if(event == 'SKILL_LINES_CHANGED') then inscriptionSkill, jewelcraftingSkill, enchantingSkill, blacksmithingSkill = 0, 0, 0, 0 local first, second = GetProfessions() if(first) then local _, _, skill, _, _, _, id = GetProfessionInfo(first) if(id == 773) then inscriptionSkill = skill elseif(id == 755) then jewelcraftingSkill = skill elseif(id == 333) then enchantingSkill = skill elseif(id == 164) then blacksmithingSkill = skill end end if(second) then local _, _, skill, _, _, _, id = GetProfessionInfo(second) if(id == 773) then inscriptionSkill = skill elseif(id == 755) then jewelcraftingSkill = skill elseif(id == 333) then enchantingSkill = skill elseif(id == 164) then blacksmithingSkill = skill end end elseif(event == 'GARRISON_BUILDING_PLACED') then local plotID = ... local buildingID = C_Garrison.GetOwnedBuildingInfoAbbrev(plotID) if(lib.enchantingBuildings[buildingID]) then hasEnchantingBuilding = true end elseif(event == 'GARRISON_BUILDING_REMOVED') then local _, buildingID = ... if(lib.enchantingBuildings[buildingID]) then hasEnchantingBuilding = false end end end) -- https://gist.github.com/p3lim/04e614e59c0064100c7c lib.herbs = { [765] = 1, -- Silverleaf [785] = 0, -- Mageroyal [2447] = 1, -- Peacebloom [2449] = 1, -- Earthroot [2450] = 25, -- Briarthorn [2452] = 25, -- Swiftthistle [2453] = 25, -- Bruiseweed [3355] = 75, -- Wild Steelbloom [3356] = 75, -- Kingsblood [3357] = 75, -- Liferoot [3358] = 125, -- Khadgar's Whisker [3369] = 75, -- Grave Moss [3818] = 125, -- Fadeleaf [3819] = 125, -- Dragon's Teeth [3820] = 25, -- Stranglekelp [3821] = 125, -- Goldthorn [4625] = 175, -- Firebloom [8831] = 175, -- Purple Lotus [8836] = 175, -- Arthas' Tears [8838] = 175, -- Sungrass [8839] = 175, -- Blindweed [8845] = 175, -- Ghost Mushroom [8846] = 175, -- Gromsblood [13463] = 225, -- Dreamfoil [13464] = 225, -- Golden Sansam [13465] = 225, -- Mountain Silversage [13466] = 225, -- Sorrowmoss [13467] = 200, -- Icecap [22785] = 275, -- Felweed [22786] = 275, -- Dreaming Glory [22787] = 275, -- Ragveil [22789] = 275, -- Terocone [22790] = 275, -- Ancient Lichen [22791] = 275, -- Netherbloom [22792] = 275, -- Nightmare Vine [22793] = 275, -- Mana Thistle [36901] = 325, -- Goldclover [36903] = 325, -- Adder's Tongue [36904] = 325, -- Tiger Lily [36905] = 325, -- Lichbloom [36906] = 325, -- Icethorn [36907] = 325, -- Talandra's Rose [37921] = 325, -- Deadnettle [39970] = 325, -- Fire Leaf [52983] = 425, -- Cinderbloom [52984] = 425, -- Stormvine [52985] = 450, -- Azshara's Veil [52986] = 450, -- Heartblossom [52987] = 475, -- Twilight Jasmine [52988] = 475, -- Whiptail [72234] = 500, -- Green Tea Leaf [72235] = 500, -- Silkweed [72237] = 500, -- Rain Poppy [79010] = 500, -- Snow Lily [79011] = 500, -- Fool's Cap [89639] = 500, -- Desecrated Herb [109124] = 0, -- Frostweed [109125] = 0, -- Fireweed [109126] = 0, -- Gorgrond Flytrap [109127] = 0, -- Starflower [109128] = 0, -- Nagrand Arrowbloom [109129] = 0, -- Talador Orchid [109130] = 0, -- Chameleon Lotus [124101] = 0, -- Aethril [124102] = 0, -- Dreamleaf [124103] = 0, -- Foxflower [124104] = 0, -- Fjarnskaggl [124105] = 0, -- Starlight Rose [124106] = 0, -- Felwort [128304] = 0, -- Yseralline Seed (this might be an error in the data files) } -- https://gist.github.com/p3lim/5c0363251db4a110017b lib.ores = { [2770] = 1, -- Copper Ore [2771] = 50, -- Tin Ore [2772] = 125, -- Iron Ore [3858] = 175, -- Mithril Ore [10620] = 250, -- Thorium Ore [23424] = 275, -- Fel Iron Ore [23425] = 325, -- Adamantite Ore [36909] = 350, -- Cobalt Ore [36910] = 450, -- Titanium Ore [36912] = 400, -- Saronite Ore [52183] = 500, -- Pyrite Ore [52185] = 475, -- Elementium Ore [53038] = 425, -- Obsidium Ore [72092] = 500, -- Ghost Iron Ore [72093] = 550, -- Kyparite [72094] = 600, -- Black Trillium Ore [72103] = 600, -- White Trillium Ore [123918] = 0, -- Leystone Ore [123919] = 0, -- Felslate } -- http://www.wowhead.com/items?filter=10:161:128;1:1:1;:: lib.containers = { [4632] = 1, -- Ornate Bronze Lockbox [6354] = 1, -- Small Locked Chest [16882] = 1, -- Battered Junkbox [4633] = 25, -- Heavy Bronze Lockbox [4634] = 70, -- Iron Lockbox [6355] = 70, -- Sturdy Locked Chest [16883] = 70, -- Worn Junkbox [4636] = 125, -- Strong Iron Lockbox [4637] = 175, -- Steel Lockbox [13875] = 175, -- Ironbound Locked Chest [16884] = 175, -- Sturdy Junkbox [4638] = 225, -- Reinforced Steel Lockbox [5758] = 225, -- Mithril Lockbox [5759] = 225, -- Thorium Lockbox [5760] = 225, -- Eternium Lockbox [13918] = 250, -- Reinforced Locked Chest [16885] = 250, -- Heavy Junkbox [12033] = 275, -- Thaurissan Family Jewels [29569] = 300, -- Strong Junkbox [31952] = 325, -- Khorium Lockbox [43575] = 350, -- Reinforced Junkbox [43622] = 375, -- Froststeel Lockbox [43624] = 400, -- Titanium Lockbox [45986] = 400, -- Tiny Titanium Lockbox [63349] = 400, -- Flame-Scarred Junkbox [68729] = 425, -- Elementium Lockbox [88567] = 450, -- Ghost Iron Lockbox [88165] = 450, -- Vine-Cracked Junkbox [106895] = 500, -- Iron-Bound Junkbox [116920] = 500, -- True Steel Lockbox [121331] = 550, -- Leystone Lockbox } lib.enchantingBuildings = { [93] = true, [125] = true, [126] = true, }