308 lines
12 KiB
Lua
308 lines
12 KiB
Lua
---@class QuestieAuto
|
|
---@field private private QuestieAutoPrivate
|
|
local QuestieAuto = QuestieLoader:CreateModule("QuestieAuto");
|
|
local _QuestieAuto = QuestieAuto.private
|
|
---@type QuestieDB
|
|
local QuestieDB = QuestieLoader:ImportModule("QuestieDB");
|
|
|
|
--- COMPATIBILITY ---
|
|
local C_Timer = QuestieCompat.C_Timer
|
|
local GetQuestID = QuestieCompat.GetQuestID
|
|
|
|
local shouldRunAuto = true
|
|
local doneTalking = false
|
|
|
|
local cameFromProgressEvent = false
|
|
local isAllowedNPC = false
|
|
local lastAmountOfAvailableQuests = 0
|
|
local lastNPCTalkedTo
|
|
local doneWithAccept = false
|
|
local lastIndexTried = 1
|
|
local lastEvent
|
|
|
|
local MOP_INDEX_AVAILABLE = 7 -- was '5' in Cataclysm
|
|
local MOP_INDEX_COMPLETE = 6 -- was '4' in Cataclysm
|
|
|
|
-- forward declarations
|
|
local _SelectAvailableQuest
|
|
|
|
|
|
local function ResetModifier()
|
|
shouldRunAuto = true
|
|
lastEvent = nil
|
|
end
|
|
|
|
function QuestieAuto:GOSSIP_SHOW(event, ...)
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto][EVENT] GOSSIP_SHOW", event, ...)
|
|
doneTalking = false
|
|
|
|
if (not shouldRunAuto) then
|
|
return
|
|
elseif _QuestieAuto:IsBindTrue(Questie.db.profile.autoModifier) then
|
|
shouldRunAuto = false
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] Modifier-Key down: Disabling QuestieAuto for now")
|
|
return
|
|
end
|
|
lastEvent = "GOSSIP_SHOW"
|
|
|
|
local availableQuests = { QuestieCompat.GetAvailableQuests() }
|
|
local currentNPC = UnitName("target")
|
|
if lastNPCTalkedTo ~= currentNPC or #availableQuests ~= lastAmountOfAvailableQuests then
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] Greeted by a new NPC")
|
|
lastNPCTalkedTo = currentNPC
|
|
isAllowedNPC = _QuestieAuto:IsAllowedNPC()
|
|
lastIndexTried = 1
|
|
lastAmountOfAvailableQuests = #availableQuests
|
|
doneWithAccept = false
|
|
end
|
|
|
|
if cameFromProgressEvent then
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] Last event was Progress")
|
|
cameFromProgressEvent = false
|
|
lastIndexTried = lastIndexTried + MOP_INDEX_AVAILABLE
|
|
end
|
|
|
|
-- Turn in complete quests
|
|
if Questie.db.profile.autocomplete and isAllowedNPC then
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] Checking active quests from gossip")
|
|
local completeQuests = { QuestieCompat.GetActiveQuests() }
|
|
|
|
for index = 1, #completeQuests, MOP_INDEX_COMPLETE do
|
|
_QuestieAuto:CompleteQuestFromGossip(index, completeQuests, MOP_INDEX_COMPLETE)
|
|
end
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] DONE. Checked all complete quests")
|
|
end
|
|
|
|
-- Accept new quests
|
|
if Questie.db.profile.autoaccept and (not doneWithAccept) and isAllowedNPC then
|
|
if lastIndexTried < #availableQuests then
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] Checking available quests from gossip")
|
|
_QuestieAuto:AcceptQuestFromGossip(lastIndexTried, availableQuests, MOP_INDEX_AVAILABLE)
|
|
return
|
|
else
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] DONE. Checked all available quests")
|
|
doneWithAccept = true
|
|
lastIndexTried = 1
|
|
end
|
|
end
|
|
end
|
|
|
|
function QuestieAuto:QUEST_PROGRESS(event, ...)
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto][EVENT] QUEST_PROGRESS", event, ...)
|
|
doneTalking = false
|
|
|
|
if (not shouldRunAuto) then
|
|
return
|
|
elseif _QuestieAuto:IsBindTrue(Questie.db.profile.autoModifier) then
|
|
shouldRunAuto = false
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] Modifier-Key down: Disabling QuestieAuto for now")
|
|
return
|
|
end
|
|
|
|
if Questie.db.profile.autocomplete then
|
|
if _QuestieAuto:IsAllowedNPC() and _QuestieAuto:IsAllowedQuest() then
|
|
if IsQuestCompletable() then
|
|
CompleteQuest()
|
|
return
|
|
else
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] Quest not completeable. Index", lastIndexTried)
|
|
end
|
|
end
|
|
|
|
-- Close the QuestFrame if no quest is completeable again
|
|
if QuestFrameGoodbyeButton and lastEvent ~= nil then
|
|
QuestFrameGoodbyeButton:Click()
|
|
end
|
|
cameFromProgressEvent = true
|
|
end
|
|
lastEvent = "QUEST_PROGRESS"
|
|
end
|
|
|
|
_SelectAvailableQuest = function(index)
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] Selecting available quest at index", index)
|
|
SelectAvailableQuest(index)
|
|
end
|
|
|
|
function QuestieAuto:QUEST_ACCEPT_CONFIRM(event, ...)
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto][EVENT] QUEST_ACCEPT_CONFIRM", event, ...)
|
|
lastEvent = "QUEST_ACCEPT_CONFIRM"
|
|
doneTalking = false
|
|
-- Escort stuff
|
|
if (Questie.db.profile.autoaccept) then
|
|
ConfirmAcceptQuest()
|
|
end
|
|
end
|
|
|
|
function QuestieAuto:QUEST_GREETING(event, ...)
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto][EVENT] QUEST_GREETING", event, GetNumActiveQuests(), ...)
|
|
lastEvent = "QUEST_GREETING"
|
|
doneTalking = false
|
|
|
|
if (not shouldRunAuto) then
|
|
return
|
|
elseif _QuestieAuto:IsBindTrue(Questie.db.profile.autoModifier) then
|
|
shouldRunAuto = false
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] Modifier-Key down: Disabling QuestieAuto for now")
|
|
return
|
|
end
|
|
|
|
if cameFromProgressEvent then
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] Last event was Progress")
|
|
cameFromProgressEvent = false
|
|
lastIndexTried = lastIndexTried + 1
|
|
end
|
|
|
|
-- Quest already taken
|
|
if (Questie.db.profile.autocomplete) then
|
|
for index = 1, GetNumActiveQuests() do
|
|
local quest, isComplete = GetActiveTitle(index)
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, quest, isComplete)
|
|
if isComplete then SelectActiveQuest(index) end
|
|
end
|
|
end
|
|
|
|
if (Questie.db.profile.autoaccept) then
|
|
local availableQuestsCount = GetNumAvailableQuests()
|
|
if lastIndexTried == 0 or lastIndexTried > availableQuestsCount then
|
|
lastIndexTried = 1
|
|
end
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] lastIndex:", lastIndexTried)
|
|
if availableQuestsCount > 0 and lastIndexTried < availableQuestsCount then
|
|
_SelectAvailableQuest(lastIndexTried)
|
|
end
|
|
end
|
|
end
|
|
|
|
function QuestieAuto:QUEST_DETAIL(event, ...)
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto][EVENT] QUEST_DETAIL", event, ...)
|
|
lastEvent = "QUEST_DETAIL"
|
|
doneTalking = false
|
|
|
|
if (not shouldRunAuto) then
|
|
return
|
|
elseif _QuestieAuto:IsBindTrue(Questie.db.profile.autoModifier) then
|
|
shouldRunAuto = false
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] Modifier-Key down: Disabling QuestieAuto for now")
|
|
return
|
|
end
|
|
|
|
-- We really want to disable this in instances, mostly to prevent retards from ruining groups.
|
|
if (Questie.db.profile.autoaccept and _QuestieAuto:IsAllowedNPC() and _QuestieAuto:IsAllowedQuest(true)) then
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] INSIDE", event, ...)
|
|
|
|
local questId = GetQuestID(true)
|
|
local questLevel
|
|
|
|
if questId and questId ~= 0 then
|
|
questLevel = QuestieDB.QueryQuestSingle(questId, "questLevel")
|
|
end
|
|
|
|
if not questLevel then
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] No quest object, retrying in 1 second")
|
|
C_Timer.After(1, function()
|
|
questId = GetQuestID(true)
|
|
if questId and questId ~= 0 then
|
|
questLevel = QuestieDB.QueryQuestSingle(questId, "questLevel")
|
|
if not questLevel then
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] retry failed. Quest", questId, "might not be in the DB!")
|
|
elseif (not QuestieDB.IsTrivial(questLevel)) or Questie.db.profile.acceptTrivial then
|
|
Questie:Debug(Questie.DEBUG_INFO, "[QuestieAuto] Questie Auto-Accepting quest:", questId)
|
|
AcceptQuest()
|
|
end
|
|
end
|
|
end)
|
|
|
|
return
|
|
end
|
|
|
|
if (not QuestieDB.IsTrivial(questLevel)) or Questie.db.profile.acceptTrivial then
|
|
Questie:Debug(Questie.DEBUG_INFO, "[QuestieAuto] Questie Auto-Accepting quest:", questId)
|
|
AcceptQuest()
|
|
end
|
|
end
|
|
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 QuestieAuto:QUEST_COMPLETE(event, ...)
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[EVENT] QUEST_COMPLETE", event, ...)
|
|
lastEvent = "QUEST_COMPLETE"
|
|
doneTalking = false
|
|
|
|
if (not shouldRunAuto) then
|
|
return
|
|
elseif _QuestieAuto:IsBindTrue(Questie.db.profile.autoModifier) then
|
|
shouldRunAuto = false
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] Modifier-Key down: Disabling QuestieAuto for now")
|
|
return
|
|
end
|
|
|
|
-- blasted Lands citadel wonderful NPC. They do not trigger any events except quest_complete.
|
|
-- if not AllowedToHandle() then
|
|
-- return
|
|
-- end
|
|
if (Questie.db.profile.autocomplete) then
|
|
local questname = GetTitleText()
|
|
local numOptions = GetNumQuestChoices()
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, event, questname, numOptions, ...)
|
|
|
|
if numOptions > 1 then
|
|
Questie:Debug(Questie.DEBUG_INFO, "[QuestieAuto] Multiple rewards (" .. numOptions .. ")! Please choose appropriate reward!")
|
|
else
|
|
_QuestieAuto:TurnInQuest(1)
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] Completed quest!")
|
|
end
|
|
end
|
|
end
|
|
|
|
local _QuestFinishedCallback = function()
|
|
if _QuestieAuto:AllQuestWindowsClosed() then
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] All quest windows closed! Resetting shouldRunAuto")
|
|
ResetModifier()
|
|
end
|
|
end
|
|
|
|
function QuestieAuto:QUEST_FINISHED()
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto][EVENT] QUEST_FINISHED")
|
|
|
|
C_Timer.After(0.5, _QuestFinishedCallback)
|
|
end
|
|
|
|
function QuestieAuto:QUEST_ACCEPTED()
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto][EVENT] QUEST_ACCEPTED")
|
|
if Questie.db.profile.bugWorkarounds == true and QuestFrameDetailPanel:IsVisible() == true then
|
|
QuestFrameCloseButton:Click()
|
|
end
|
|
end
|
|
|
|
--[[ TODO: This function already exsists in Privates.lua line 8. Does it belong here or in Privates?
|
|
function _QuestieAuto:AllQuestWindowsClosed()
|
|
if GossipFrame and (not GossipFrame:IsVisible())
|
|
and GossipFrameGreetingPanel and (not GossipFrameGreetingPanel:IsVisible())
|
|
and QuestFrameGreetingPanel and (not QuestFrameGreetingPanel:IsVisible())
|
|
and QuestFrameDetailPanel and (not QuestFrameDetailPanel:IsVisible())
|
|
and QuestFrameProgressPanel and (not QuestFrameProgressPanel:IsVisible())
|
|
and QuestFrameRewardPanel and (not QuestFrameRewardPanel:IsVisible()) then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
--]]
|
|
--- The closingCounter needs to reach 1 for QuestieAuto to reset
|
|
--- Whenever the gossip frame is closed this event is called once, HOWEVER
|
|
--- when totally stop talking to an NPC this event is called twice.
|
|
--- Another special case is: If you run away from the NPC the event is called
|
|
--- just once.
|
|
function QuestieAuto:GOSSIP_CLOSED()
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto][EVENT] GOSSIP_CLOSED")
|
|
lastEvent = "GOSSIP_CLOSED"
|
|
|
|
if doneTalking then
|
|
doneTalking = false
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAuto] We are done talking to an NPC! Resetting shouldRunAuto")
|
|
shouldRunAuto = true
|
|
lastEvent = nil
|
|
else
|
|
doneTalking = true
|
|
end
|
|
end
|