--A very special thanks to P3lim (Molinari) for the inspiration behind the AutoShine and Blightdavid for his work on Prospect Easy.
local spells = {}
local setInCombat = 0
local lastItem
local colors = {
[51005] = {r=181/255, g=230/255, b=29/255}, --milling
[31252] = {r=1, g=127/255, b=138/255}, --prospecting
[13262] = {r=128/255, g=128/255, b=1}, --disenchant
[1804] = {r=200/255, g=75/255, b=75/255}, --lock picking (Thanks to kaisoul)
}
--[[------------------------
LOCALIZATION
--------------------------]]
local locale = GetLocale()
local L = setmetatable(locale == "deDE" and {
Weapon = "Waffe",
} or {}, {__index=function(t,i) return i end})
--[[------------------------
CREATE BUTTON
--------------------------]]
--this will assist us in checking if we are in combat or not
local function checkCombat(btn, force)
if setInCombat == 0 and InCombatLockdown() then
setInCombat = 1
btn:SetAlpha(0)
btn:RegisterEvent('PLAYER_REGEN_ENABLED')
elseif force or (setInCombat == 1 and not InCombatLockdown()) then
setInCombat = 0
btn:UnregisterEvent('PLAYER_REGEN_ENABLED')
btn:ClearAllPoints()
btn:SetAlpha(1)
btn:Hide()
end
end
local button = CreateFrame("Button", "xMP_ButtonFrame", UIParent, "SecureActionButtonTemplate,SecureHandlerEnterLeaveTemplate,AutoCastShineTemplate")
button:SetScript("OnEvent", function(self, event, ...) if self[event] then return self[event](self, event, ...) end end)
button:RegisterEvent('MODIFIER_STATE_CHANGED')
button:SetAttribute('alt-type1', 'macro')
button:RegisterForClicks("LeftButtonUp")
button:RegisterForDrag("LeftButton")
button:SetFrameStrata("DIALOG")
--secured on leave function to hide the frame when we are in combat
button:SetAttribute("_onleave", "self:ClearAllPoints() self:SetAlpha(0) self:Hide()")
button:HookScript("OnLeave", function(self)
AutoCastShine_AutoCastStop(self)
if InCombatLockdown() then checkCombat(self) else self:ClearAllPoints() self:Hide() end --prevent combat errors
end)
button:HookScript("OnReceiveDrag", function(self)
AutoCastShine_AutoCastStop(self)
if InCombatLockdown() then checkCombat(self) else self:ClearAllPoints() self:Hide() end --prevent combat errors
end)
button:HookScript("OnDragStop", function(self, button)
AutoCastShine_AutoCastStop(self)
if InCombatLockdown() then checkCombat(self) else self:ClearAllPoints() self:Hide() end --prevent combat errors
end)
button:Hide()
function button:MODIFIER_STATE_CHANGED(event, modi)
if not modi then return end
if modi ~= "LALT" or modi ~= "RALT" then return end
if not self:IsShown() then return end
--clear the auto shine if alt key has been released
if not IsAltKeyDown() and not InCombatLockdown() then
AutoCastShine_AutoCastStop(self)
self:ClearAllPoints()
self:Hide()
elseif InCombatLockdown() then
checkCombat(self)
end
end
function button:PLAYER_REGEN_ENABLED()
--player left combat
checkCombat(self, true)
end
--AutoCastShineTemplate
--set the sparkles otherwise it will throw an error
--increase the sparkles a bit for clarity
for _, sparks in pairs(button.sparkles) do
sparks:SetHeight(sparks:GetHeight() * 3)
sparks:SetWidth(sparks:GetWidth() * 3)
end
--if the lootframe is showing then disable everything
LootFrame:HookScript("OnShow", function(self)
if button:IsShown() and not InCombatLockdown() then
AutoCastShine_AutoCastStop(button)
button:ClearAllPoints()
button:Hide()
end
end)
--[[------------------------
CORE
--------------------------]]
local frm = CreateFrame("frame", "xanMortarPestle_Frame", UIParent)
frm:SetScript("OnEvent", function(self, event, ...) if self[event] then return self[event](self, event, ...) end end)
function frm:PLAYER_LOGIN()
--check for DB
if not XMP_DB then XMP_DB = {} end
--milling
if(IsSpellKnown(51005)) then
spells[51005] = GetSpellInfo(51005)
end
--prospecting
if(IsSpellKnown(31252)) then
spells[31252] = GetSpellInfo(31252)
end
--disenchanting
if(IsSpellKnown(13262)) then
spells[13262] = GetSpellInfo(13262)
end
--lock picking (thanks to Kaisoul)
if(IsSpellKnown(1804)) then
spells[1804] = GetSpellInfo(1804)
end
GameTooltip:HookScript('OnTooltipSetItem', function(self)
--do some checks before we do anything
if InCombatLockdown() then return end --if were in combat then exit
if not IsAltKeyDown() then return end --if the modifier is not down then exit
if CursorHasItem() then return end --if the mouse has an item then exit
local item, link = self:GetItem()
--make sure we have an item to work with
if not item and not link then return end
local owner = self:GetOwner() --get the owner of the tooltip
--if it's the character frames <alt> equipment switch then ignore it
if owner and owner:GetName() and strfind(string.lower(owner:GetName()), "character") and strfind(string.lower(owner:GetName()), "slot") then return end
if owner and owner:GetParent() and owner:GetParent():GetName() and strfind(string.lower(owner:GetParent():GetName()), "paperdoll") then return end
--reset if no item (link will be nil)
lastItem = link
--make sure we have an item, it's not an equipped one, and the darn lootframe isn't showing
if item and link and not IsEquippedItem(link) and not LootFrame:IsShown() then
--get the bag slot info
local bag = owner:GetParent():GetID()
local slot = owner:GetID()
local id = type(link) == "number" and link or select(3, link:find("item:(%d+):"))
id = tonumber(id)
if not id then return end
if not xMPDB then return end
local _, _, qual, itemLevel, _, itemType = GetItemInfo(link)
local spellID = processCheck(id, itemType, qual, link)
--check to show or hide the button
if spellID then
--set the item for disenchant check
lastItem = link
button:SetAttribute('macrotext', string.format('/cast %s\n/use %s %s', spells[spellID], bag, slot))
button:SetAllPoints(owner)
button:SetAlpha(1)
button:Show()
AutoCastShine_AutoCastStart(button, colors[spellID].r, colors[spellID].g, colors[spellID].b)
else
button:ClearAllPoints()
button:Hide()
end
end
end)
self:UnregisterEvent("PLAYER_LOGIN")
self.PLAYER_LOGIN = nil
end
function processCheck(id, itemType, qual, link)
if not spells then return nil end
--first check milling
if xMPDB.herbs[id] and spells[51005] then
return 51005
end
--second checking prospecting
if xMPDB.ore[id] and spells[31252] then
return 31252
end
--third checking lock picking (thanks to Kailsoul)
if xMPDB.lock[id] and spells[1804] then
return 1804
end
--otherwise check disenchat
if itemType and qual and XMP_DB and spells[13262] then
--only allow if the type of item is a weapon or armor, and it's a specific quality
if (itemType == ARMOR or itemType == L.Weapon) and qual > 1 and qual < 5 and IsEquippableItem(link) and not XMP_DB[id] then
return 13262
end
end
return nil
end
--instead of having a large array with all the possible non-disenchant items
--I decided to go another way around this. Whenever a user tries to disenchant an item that can't be disenchanted
--it learns the item into a database. That way in the future the user will not be able to disenchant it.
--A one time warning will be displayed for the user ;)
local originalOnEvent = UIErrorsFrame:GetScript("OnEvent")
UIErrorsFrame:SetScript("OnEvent", function(self, event, msg, r, g, b, ...)
if event ~= "SYSMSG" then
--it's not a system message so lets grab it and compare with non-disenchant
if msg == SPELL_FAILED_CANT_BE_DISENCHANTED and XMP_DB and button:IsShown() and lastItem then
--get the id from the previously stored link
local id = type(lastItem) == "number" and lastItem or select(3, lastItem:find("item:(%d+):"))
id = tonumber(id)
--check to see if it's already in the database, if it isn't then add it to the DE list.
if id and not XMP_DB[id] then
XMP_DB[id] = true
DEFAULT_CHAT_FRAME:AddMessage(string.format("|cFF99CC33xanMortarPestle|r: %s added to database. %s", lastItem, SPELL_FAILED_CANT_BE_DISENCHANTED))
end
end
end
return originalOnEvent(self, event, msg, r, g, b, ...)
end)
if IsLoggedIn() then frm:PLAYER_LOGIN() else frm:RegisterEvent("PLAYER_LOGIN") end