--[[
Feel free to use this source code for any purpose ( except developing nuclear weapon! :)
Please keep original author statement.
@author Alex Shubert (alex.shubert@gmail.com)
]]--
local _G = _G --Rumors say that global _G is called by lookup in a super-global table. Have no idea whether it is true.
local _ --Sometimes blizzard exposes "_" variable as a global.
local addonName, ptable = ...
local L = ptable.L
local IGNORED_NPC = ptable.IGNORED_NPC
local C = ptable.CONST
local TOCVersion = GetAddOnMetadata(addonName, "Version")
local Q_ALL, Q_DAILY, Q_EXCEPTDAILY = 1, 2, 3
AutoTurnIn = LibStub("AceAddon-3.0"):NewAddon("AutoTurnIn", "AceEvent-3.0", "AceConsole-3.0")
AutoTurnIn.TOC = select(4, GetBuildInfo())
AutoTurnIn.defaults = {enabled = true, all = 2, trivial = false, completeonly = false,
lootreward = 1, tournament = 2,
darkmoonteleport=true, todarkmoon=true, togglekey=4, darkmoonautostart=true, showrewardtext=true,
version=TOCVersion, autoequip = false, debug=false,
questlevel=true, watchlevel=true, questshare=false,
armor = {}, weapon = {}, stat = {}, secondary = {}}
AutoTurnIn.ldb, AutoTurnIn.allowed = nil, nil
AutoTurnIn.caption = addonName ..' [%s]'
AutoTurnIn.funcList = {[1] = function() return false end, [2]=IsAltKeyDown, [3]=IsControlKeyDown, [4]=IsShiftKeyDown}
AutoTurnIn.OptionsPanel, AutoTurnIn.RewardPanel = nil, nil
AutoTurnIn.autoEquipList={}
AutoTurnIn.questCache={} -- daily quest cache. Initially is built from player's quest log
AutoTurnIn.ERRORVALUE = nil
AutoTurnIn.ldbstruct = {
type = "data source",
icon = "Interface\\QUESTFRAME\\UI-QuestLog-BookIcon",
label = addonName,
text = addonName,
OnClick = function(clickedframe, button)
if InterfaceOptionsFrame:IsVisible() then
if (InterfaceOptionsFrameAddOns.selection:GetName() == AutoTurnIn.OptionsPanel:GetName()) then --"AutoTurnInOptionsPanel"
InterfaceOptionsFrame_OpenToCategory(AutoTurnIn.RewardPanel)
elseif (InterfaceOptionsFrameAddOns.selection:GetName() == AutoTurnIn.RewardPanel:GetName() ) then --"AutoTurnInRewardPanel"
InterfaceOptionsFrameCancel:Click()
end
else
InterfaceOptionsFrame_OpenToCategory(AutoTurnIn.OptionsPanel)
end
end,
}
function AutoTurnIn:OnInitialize()
self:RegisterChatCommand("au", "ConsoleComand")
end
function AutoTurnIn:SetEnabled(enabled)
AutoTurnInCharacterDB.enabled = not not enabled
if self.ldb then
self.ldb.text = self.caption:format((AutoTurnInCharacterDB.enabled) and 'on' or 'off' )
self.ldb.label = self.ldb.text
end
end
-- quest autocomplete handlers and functions
function AutoTurnIn:OnEnable()
if (not AutoTurnInCharacterDB) or (not AutoTurnInCharacterDB.version or (AutoTurnInCharacterDB.version < TOCVersion)) then
AutoTurnInCharacterDB = nil
self:Print(L["reset"])
end
if not AutoTurnInCharacterDB then
_G.AutoTurnInCharacterDB = CopyTable(self.defaults)
end
local DB = AutoTurnInCharacterDB
if (tonumber(DB.lootreward) == nil) then
DB.lootreward = 1
end
if (tonumber(DB.togglekey) == nil) then
DB.togglekey = 1
end
DB.armor = DB.armor and DB.armor or {}
DB.weapon = DB.weapon and DB.weapon or {}
DB.stat = DB.stat and DB.stat or {}
DB.secondary = DB.secondary and DB.secondary or {}
DB.trivial = DB.trivial ~= nil and DB.trivial or false
DB.questlevel = DB.questlevel == nil and true or DB.questlevel
DB.watchlevel = DB.watchlevel == nil and true or DB.watchlevel
DB.questshare = DB.questshare == nil and false or DB.questshare
local LDB = LibStub:GetLibrary("LibDataBroker-1.1", true)
if LDB then
self.ldb = LDB:NewDataObject("AutoTurnIn", self.ldbstruct)
end
self:SetEnabled(DB.enabled)
self:RegisterGossipEvents()
-- See no way tp fix taint issues with quest special items.
-- hooksecurefunc("ObjectiveTracker_Update", AutoTurnIn.ShowQuestLevelInWatchFrame)
hooksecurefunc("QuestLogQuests_Update", AutoTurnIn.ShowQuestLevelInLog)
end
function AutoTurnIn:OnDisable()
self:UnregisterAllEvents()
end
function AutoTurnIn:RegisterGossipEvents()
self:RegisterEvent("QUEST_GREETING")
self:RegisterEvent("GOSSIP_SHOW")
self:RegisterEvent("QUEST_DETAIL")
self:RegisterEvent("QUEST_PROGRESS")
self:RegisterEvent("QUEST_COMPLETE")
self:RegisterEvent("QUEST_LOG_UPDATE")
self:RegisterEvent("QUEST_ACCEPTED")
end
function AutoTurnIn:QUEST_LOG_UPDATE()
if ( GetNumQuestLogEntries() > 0 ) then
for index=1, GetNumQuestLogEntries() do
local title, _, _, _, isHeader , _, _, isDaily = GetQuestLogTitle(index)
if not isHeader and isDaily then
self.questCache[title] = true
end
end
self:UnregisterEvent("QUEST_LOG_UPDATE")
end
end
-- Available check requires cache
-- Active check query API function Returns true if quest matches options
function AutoTurnIn:isAppropriate(questname, byCache)
local daily
if byCache then
daily = (not not self.questCache[questname])
else
daily = (QuestIsDaily() or QuestIsWeekly())
end
return self:_isAppropriate(daily)
end
-- 'private' function
function AutoTurnIn:_isAppropriate(daily)
if daily then
return (AutoTurnInCharacterDB.all ~= Q_EXCEPTDAILY)
else
return (AutoTurnInCharacterDB.all ~= Q_DAILY)
end
end
-- caches offered by gossip quest as daily
function AutoTurnIn:CacheAsDaily(questname)
self.questCache[questname] = true
end
function AutoTurnIn:IsIgnoredQuest(quest)
local function startsWith(str,template)
return (string.len(str) >= string.len(template)) and (string.sub(str,1,string.len(template))==template)
end
for q in pairs(L.ignoreList) do
if (startsWith(quest, q)) then
return true
end
end
return false
end
function AutoTurnIn:ConsoleComand(arg)
arg = strlower(arg)
if (#arg == 0) then
-- http://wowpedia.org/Patch_5.3.0/API_changes double call is a workaround
InterfaceOptionsFrame_OpenToCategory(AutoTurnIn.OptionsPanel)
InterfaceOptionsFrame_OpenToCategory(AutoTurnIn.OptionsPanel)
elseif arg == "on" then
self:SetEnabled(true)
self:Print(L["enabled"])
elseif arg == "off" then
self:SetEnabled(false)
self:Print(L["disabled"])
end
end
-- returns specified item count on player character. It may be some sort of currency or present in inventory as real items.
function AutoTurnIn:GetItemAmount(isCurrency, item)
local amount = isCurrency and select(2, GetCurrencyInfo(item)) or GetItemCount(item, nil, true)
return amount and amount or 0
end
-- returns set 'self.allowed' to true if addon is allowed to handle current gossip conversation
-- Cases when it may not : (addon is enabled and toggle key was pressed) or (addon is disabled and toggle key is not pressed)
-- 'forcecheck' does what it name says: forces check
function AutoTurnIn:AllowedToHandle(forcecheck)
if ( self.allowed == nil or forcecheck ) then
-- Double 'not' converts possible 'nil' to boolean representation
local IsModifiedClick = not not self.funcList[AutoTurnInCharacterDB.togglekey]()
-- it's a simple xor implementation (a ~= b)
self.allowed = (not not AutoTurnInCharacterDB.enabled) ~= (IsModifiedClick)
end
return self.allowed and (not IGNORED_NPC[AutoTurnIn:GetNPCGUID()]) and (not QuestGetAutoAccept())
end
-- Old 'Quest NPC' interaction system. See http://wowprogramming.com/docs/events/QUEST_GREETING
function AutoTurnIn:QUEST_GREETING()
if (not self:AllowedToHandle(true)) then
return
end
for index=1, GetNumActiveQuests() do
local quest, isComplete = GetActiveTitle(index)
if isComplete and (self:isAppropriate(quest, true)) then
SelectActiveQuest(index)
end
end
if not AutoTurnInCharacterDB.completeonly then
for index=1, GetNumAvailableQuests() do
local isTrivial, isDaily, isRepeatable = GetAvailableQuestInfo(index)
local triviaAndAllowedOrNotTrivia = (not isTrivial) or AutoTurnInCharacterDB.trivial
local title = GetAvailableTitle(index)
local quest = L.quests[title]
local notBlackListed = not (quest and (quest.donotaccept or AutoTurnIn:IsIgnoredQuest(title)))
if isDaily then
self:CacheAsDaily(GetAvailableTitle(index))
end
if (triviaAndAllowedOrNotTrivia and notBlackListed and self:_isAppropriate(isDaily)) then
if quest and quest.amount then
if self:GetItemAmount(quest.currency, quest.item) >= quest.amount then
SelectAvailableQuest(index)
end
else
SelectAvailableQuest(index)
end
end
end
end
end
-- (gaq[i+3]) equals "1" if quest is complete, "nil" otherwise
-- why not gaq={GetGossipAvailableQuests()}? Well, tables in lua are truncated for values
-- with ending `nil`. So: '#' for {1,nil, "b", nil} returns 1
function AutoTurnIn:VarArgForActiveQuests(...)
local MOP_INDEX_CONST = 5 -- was '4' in Cataclysm
for i=1, select("#", ...), MOP_INDEX_CONST do
local isComplete = select(i+3, ...) -- complete status
if ( isComplete ) then
local questname = select(i, ...)
if self:isAppropriate(questname, true) then
local quest = L.quests[questname]
if quest and quest.amount then
if self:GetItemAmount(quest.currency, quest.item) >= quest.amount then
SelectGossipActiveQuest(math.floor(i/MOP_INDEX_CONST)+1)
self.DarkmoonAllowToProceed = false
end
else
SelectGossipActiveQuest(math.floor(i/MOP_INDEX_CONST)+1)
self.DarkmoonAllowToProceed = false
end
end
end
end
end
-- like previous function this one works around `nil` values in a list.
function AutoTurnIn:VarArgForAvailableQuests(...)
local MOP_INDEX_CONST = 6 -- was '5' in Cataclysm
for i=1, select("#", ...), MOP_INDEX_CONST do
local title = select(i, ...)
local isTrivial = select(i+2, ...)
local isDaily = select(i+3, ...)
local triviaAndAllowedOrNotTrivia = (not isTrivial) or AutoTurnInCharacterDB.trivial
local quest = L.quests[title] -- this quest exists in addons quest DB. There are mostly daily quests
local notBlackListed = not (quest and (quest.donotaccept or AutoTurnIn:IsIgnoredQuest(title)))
-- Quest is appropriate if: (it is trivial and trivial are accepted) and (any quest accepted or (it is daily quest that is not in ignore list))
if (triviaAndAllowedOrNotTrivia and notBlackListed and self:_isAppropriate(isDaily)) then
if quest and quest.amount then
if self:GetItemAmount(quest.currency, quest.item) >= quest.amount then
SelectGossipAvailableQuest(math.floor(i/MOP_INDEX_CONST)+1)
end
else
SelectGossipAvailableQuest(math.floor(i/MOP_INDEX_CONST)+1)
end
end
end
end
-- Extracts GUID from the NPC which dialog window is currenty displayed
function AutoTurnIn:GetNPCGUID()
local a = UnitGUID("npc")
return a and select(3, a:find("Creature%-%d+%-%d+%-%d+%-%d+%-(%d+)%-")) or nil
end
function AutoTurnIn:isDarkmoonAndAllowed(questCount)
return (self.DarkmoonAllowToProceed and questCount) and
AutoTurnInCharacterDB.darkmoonautostart and
(GetZoneText() == L["Darkmoon Island"])
end
function AutoTurnIn:isYoungPandaren()
return (AutoTurnIn:GetNPCGUID() == "55267")
end
function AutoTurnIn:isDarkmoonFaireMysticMage()
local guid = AutoTurnIn:GetNPCGUID()
local isMage = (guid == "54334") or (guid == "55382")
return AutoTurnInCharacterDB.todarkmoon and
(isMage and GetRealZoneText() ~= L["Darkmoon Island"])
end
function AutoTurnIn:isDarkmoonFaireTeleportologist()
return AutoTurnInCharacterDB.darkmoonteleport and (AutoTurnIn:GetNPCGUID() == "57850")
end
function AutoTurnIn:GOSSIP_SHOW()
if (not self:AllowedToHandle(true)) then
return
end
-- darkmoon fairy gossip sometime turns in quest too fast so I can't relay only on quest number count. It often lie.
-- this flag is set in VarArgForActiveQuests if any quest may be turned in
self.DarkmoonAllowToProceed = true
local questCount = GetNumGossipActiveQuests() > 0
self:VarArgForActiveQuests(GetGossipActiveQuests())
if not AutoTurnInCharacterDB.completeonly then
self:VarArgForAvailableQuests(GetGossipAvailableQuests())
end
if self:isDarkmoonAndAllowed(questCount) then
local options = {GetGossipOptions()}
for k, v in pairs(options) do
if ((v ~= "gossip") and strfind(v, "|cFF0008E8%(")) then
local opcount = GetNumGossipOptions()
SelectGossipOption((opcount == 1) and 1 or math.floor(k / GetNumGossipOptions()) + 1)
end
end
end
if self:isYoungPandaren() then
SelectGossipOption(1)
end
if self:isDarkmoonFaireMysticMage() or self:isDarkmoonFaireTeleportologist() then
SelectGossipOption(1)
StaticPopup1Button1:Click()
end
end
function AutoTurnIn:QUEST_DETAIL()
if (QuestIsDaily() or QuestIsWeekly()) then
self:CacheAsDaily(GetTitleText())
end
if self:AllowedToHandle() and self:isAppropriate() and (not AutoTurnInCharacterDB.completeonly)then
QuestInfoDescriptionText:SetAlphaGradient(0, -1)
QuestInfoDescriptionText:SetAlpha(1)
AcceptQuest()
end
end
function AutoTurnIn:QUEST_ACCEPTED(event, index)
if AutoTurnInCharacterDB.questshare and GetQuestLogPushable() and GetNumGroupMembers() >= 1 then
SelectQuestLogEntry(index);
QuestLogPushQuest();
end
end
function AutoTurnIn:QUEST_PROGRESS()
if self:AllowedToHandle() and IsQuestCompletable() and self:isAppropriate() then
CompleteQuest()
end
end
-- return true if an item is of `ranged` type and is suitable with current options
function AutoTurnIn:IsRangedAndRequired(subclass)
return (AutoTurnInCharacterDB.weapon['Ranged'] and
(C.ITEMS['Crossbows'] == subclass or C.ITEMS['Guns'] == subclass or C.ITEMS['Bows'] == subclass))
end
-- return true if an item is of `Jewelry` type and is suitable with current options
function AutoTurnIn:IsJewelryAndRequired(equipSlot)
return AutoTurnInCharacterDB.armor['Jewelry'] and (C.JEWELRY[equipSlot])
end
-- initiated in AutoTurnIn:TurnInQuest PLAYER_LEAVE_COMBAT ? PLAYER_REGEN_ENABLED ?
AutoTurnIn.delayFrame = CreateFrame('Frame')
AutoTurnIn.delayFrame:Hide()
AutoTurnIn.delayFrame:SetScript('OnUpdate', function()
if not next(AutoTurnIn.autoEquipList) then
AutoTurnIn.delayFrame:Hide()
return
end
if (InCombatLockdown()) then
return
end
if (time() < AutoTurnIn.delayFrame.delay) then
return
end
for bag=0, NUM_BAG_SLOTS do
for slot=1, GetContainerNumSlots(bag), 1 do
local link = GetContainerItemLink (bag, slot)
if ( link ) then
local name = GetItemInfo(link)
if ( name and AutoTurnIn.autoEquipList[name] ) then
AutoTurnIn:Print(L["equipping reward"], link)
EquipItemByName(name, AutoTurnIn.autoEquipList[name])
AutoTurnIn.autoEquipList[name]=nil
end
end
end
end
end)
-- return 0 if itemlink is null, item level is math.huge if the item is heirloom
function AutoTurnIn:ItemLevel(itemLink)
if (not itemLink) then
return 0
end
-- 7 for heirloom http://wowprogramming.com/docs/api_types#itemQuality
local invQuality, invLevel = select(3, GetItemInfo(itemLink))
return (invQuality == 7) and math.huge or invLevel
end
-- turns quest in printing reward text if `showrewardtext` option is set.
-- prints appropriate message if item is taken by greed
-- equips received reward if such option selected
function AutoTurnIn:TurnInQuest(rewardIndex)
if (AutoTurnInCharacterDB.showrewardtext) then
self:Print((UnitName("target") and UnitName("target") or '')..'\n', GetRewardText())
end
if (self.forceGreed) then
if (GetNumQuestChoices() > 1) then
self:Print(L["gogreedy"])
end
else
local name = GetQuestItemInfo("choice", (GetNumQuestChoices() == 1) and 1 or rewardIndex)
if (AutoTurnInCharacterDB.autoequip and (strlen(name) > 0)) then
local lootLevel, _, _, _, _, equipSlot = select(4, GetItemInfo(GetQuestItemLink("choice", rewardIndex)))
-- Compares reward and already equipped item levels. If reward level is greater than equipped item, auto equip reward
local slot = C.SLOTS[equipSlot]
if (slot) then
local firstSlot = GetInventorySlotInfo(slot[1])
local invLink = GetInventoryItemLink("player", firstSlot)
local eqLevel = self:ItemLevel(invLink)
-- If reward is a ring trinket or one-handed weapons all slots must be checked in order to swap one with a lesser item-level
if (#slot > 1) then
local secondSlot = GetInventorySlotInfo(slot[2])
invLink = GetInventoryItemLink("player", secondSlot)
if (invLink) then
local eq2Level = self:ItemLevel(invLink)
firstSlot = (eqLevel > eq2Level) and secondSlot or firstSlot
eqLevel = (eqLevel > eq2Level) and eq2Level or eqLevel
end
end
-- comparing lowest equipped item level with reward's item level
if (lootLevel > eqLevel) then
self.autoEquipList[name] = firstSlot
self.delayFrame.delay = time() + 2
self.delayFrame:Show()
end
end
end
end
if (AutoTurnInCharacterDB.debug) then
local link = GetQuestItemLink("choice", rewardIndex)
if (link) then
self:Print("Debug: item to loot=", link)
elseif (GetNumQuestChoices() == 0) then
self:Print("Debug: turning quest in, no choice required")
end
else
GetQuestReward(rewardIndex)
end
end
function AutoTurnIn:Greed()
local index, money = 0, 0;
for i=1, GetNumQuestChoices() do
local link = GetQuestItemLink("choice", i)
if ( link == nil ) then
return
end
local m = select(11, GetItemInfo(link))
if m > money then
money = m
index = i
end
end
if money > 0 then -- some quests, like tournament ones, offer reputation rewards and they have no cost.
self.forceGreed = true
self:TurnInQuest(index)
end
end
--[[
iterates all rewards and compares with chosen stats and types. If only one appropriate item found then it accepted and quest is turned in.
if more than one suitable item found then item list is shown in a chat window and addons return control to player.
@returns 'true' if one or more suitable reward is found, 'false' otherwise ]]--
-- tables are declared here to optimize memory model. Said that in current implementation it's cheaper to wipe than to create.
AutoTurnIn.found, AutoTurnIn.stattable = {}, {}
function AutoTurnIn:Need()
wipe(self.found)
for i=1, GetNumQuestChoices() do
local link = GetQuestItemLink("choice", i)
if ( link == nil ) then
self:Print(L["rewardlag"])
return true
end
local class, subclass, _, equipSlot = select(6, GetItemInfo(link))
--[[trinkets are out of autoloot]]--
if ( 'INVTYPE_TRINKET' == equipSlot )then
self:Print(L["stopitemfound"]:format(_G[equipSlot]))
return true
end
local itemCandidate = {index=i, points=0, type="", stat="", secondary={}} --DEBUG structure
-- TYPE: item is suitable if there are no type specified at all or item type is chosen
local OkByType = false
if class == C.WEAPONLABEL then
OkByType = (not next(AutoTurnInCharacterDB.weapon)) or (AutoTurnInCharacterDB.weapon[subclass] or
self:IsRangedAndRequired(subclass))
else
OkByType = ( not next(AutoTurnInCharacterDB.armor) ) or ( AutoTurnInCharacterDB.armor[subclass] or
AutoTurnInCharacterDB.armor[equipSlot] or self:IsJewelryAndRequired(equipSlot) )
end
itemCandidate.type=subclass .. ((not not OkByType) and "=>OK" or "=>FAIL")
--STAT+SECONDARY: Same here: if no stat specified or item stat is chosen then item is wanted
local OkByStat = not next(AutoTurnInCharacterDB.stat) -- true if table is empty
local OkBySecondary = not next(AutoTurnInCharacterDB.secondary) -- true if table is empty
if (not (OkByStat and OkBySecondaryStat)) then
wipe(self.stattable)
GetItemStats(link, self.stattable)
local count = 0
for stat, value in pairs(self.stattable) do
count = count + 1
if ( AutoTurnInCharacterDB.stat[stat] ) then
OkByStat = true
itemCandidate.stat = _G[stat].. "=>OK"
end
if ( AutoTurnInCharacterDB.secondary[stat] ) then
OkBySecondary = true
itemCandidate.points = itemCandidate.points + 1
tinsert(itemCandidate.secondary, _G[stat])
end
end
if (count == 1) then -- Common quality items have only 1 attribute. This 'if' makes them suitable loot candidates.
OkByStat, OkBySecondary = true, true
end
else
itemCandidate.stat = "NO_STAT_SETTINGS"
end
-- User may not choose any options hence any item became 'ok'. That situation is undoubtly incorrect.
local SettingsExists = (class == C.WEAPONLABEL and next(AutoTurnInCharacterDB.weapon) or next(AutoTurnInCharacterDB.armor))
or next(AutoTurnInCharacterDB.stat)
-- OK means that particular options section is empty or item meets requirements
if (OkByType and OkByStat and OkBySecondary and SettingsExists) then
tinsert(self.found, itemCandidate)
end
if (AutoTurnInCharacterDB.debug) then
local secondaryDebug = ""
for _, sec in pairs(itemCandidate.secondary) do
secondaryDebug = sec..","..secondaryDebug
end
self:Print("Debug:", GetQuestItemLink("choice", itemCandidate.index), " type:", itemCandidate.type,
" stat:", itemCandidate.stat, " secondary:[", secondaryDebug, "]=>", itemCandidate.points)
end
end
-- HANDLE RESULT
local foundCount = #self.found
if foundCount > 1 then
-- sorting found items by relevance (count of attributes that concidence)
table.sort(self.found, function(a,b) return a.points > b.points end)
if (self.found[1].points == self.found[2].points) then
self:Print(L["multiplefound"])
for _, reward in pairs(self.found) do
self:Print(GetQuestItemLink("choice", reward.index))
end
else
self:TurnInQuest(self.found[1].index)
end
elseif(foundCount == 1) then
self:TurnInQuest(self.found[1].index)
elseif ( foundCount == 0 and GetNumQuestChoices() > 0 ) and ( not AutoTurnInCharacterDB.greedifnothingfound ) then
self:Print(L["nosuitablefound"])
end
return ( foundCount ~= 0 )
end
-- I was forced to make decision on offhand, cloak and shields separate from armor but I can't pick up my mind about the reason...
function AutoTurnIn:QUEST_COMPLETE()
-- blasted Lands citadel wonderful NPC. They do not trigger any events except quest_complete.
if not self:AllowedToHandle() then
return
end
--/script faction = (GameTooltip:NumLines() > 2 and not UnitIsPlayer(select(2,GameTooltip:GetUnit()))) and
-- getglobal("GameTooltipTextLeft"..GameTooltip:NumLines()):GetText() DEFAULT_CHAT_FRAME:AddMessage(faction or "NIL")
if self:isAppropriate() then
local questname = GetTitleText()
local quest = L.quests[questname]
if GetNumQuestChoices() > 1 then
local function getItemId(typeStr)
local link = GetQuestItemLink(typeStr, 1) --first item is enough
return link and link:match("%b::"):gsub(":", "") or self.ERRORVALUE
end
local itemID = getItemId("choice")
if (not itemID) then
self:Print("Can't read reward link from server. Close NPC dialog and open it again.");
return
end
-- Tournament quest found
if (itemID == "46114" or itemID == "45724") then
self:TurnInQuest(AutoTurnInCharacterDB.tournament)
return
end
if (AutoTurnInCharacterDB.lootreward > 1) then -- Auto Loot enabled!
self.forceGreed = false
if (AutoTurnInCharacterDB.lootreward == 3) then -- 3 == Need
self.forceGreed = (not self:Need() ) and AutoTurnInCharacterDB.greedifnothingfound
end
if (AutoTurnInCharacterDB.lootreward == 2 or self.forceGreed) then -- 2 == Greed
self:Greed()
end
end
else
self:TurnInQuest(1) -- for autoequip to work index must be greater that 0. That's required by Blizzard API
end
end
end
-- gossip and quest interaction goes through a sequence of windows: gossip [shows a list of available quests] - quest[describes specified quest]
-- sometimes some parts of this chain is skipped. For example, priest in Honor Hold show quest window directly. This is a trick to handle 'toggle key'
hooksecurefunc(QuestFrame, "Hide", function() AutoTurnIn.allowed = nil end)
-- if (GetItemCount(45724, false) > 0) then
-- UseItemByName(45724)
-- end
-- /run local a=UnitGUID("npc"); for word in a:gmatch("Creature%-%d+%-%d+%-%d+%-%d+%-(%d+)%-") do print(word) end