forked from p3lim-wow/QuickQuest
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaddon.lua
385 lines (338 loc) · 11 KB
/
addon.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
local _, addon = ...
local paused
local ignoredQuests = {}
local cashRewards = {
[45724] = 1e5, -- Champion's Purse, 10 gold
[64491] = 2e6, -- Royal Reward, 200 gold
-- items from the Sixtrigger brothers quest chain in Stormheim
[138127] = 15, -- Mysterious Coin, 15 copper
[138129] = 11, -- Swatch of Priceless Silk, 11 copper
[138131] = 24, -- Magical Sprouting Beans, 24 copper
[138123] = 15, -- Shiny Gold Nugget, 15 copper
[138125] = 16, -- Crystal Clear Gemstone, 16 copper
[138133] = 27, -- Elixir of Endless Wonder, 27 copper
}
local darkmoonFaireOptions = {
[40563] = true, -- whack
[28701] = true, -- cannon
[31202] = true, -- shoot
[39245] = true, -- tonk
[40224] = true, -- ring toss
[43060] = true, -- firebird
[52651] = true, -- dance
[41759] = true, -- pet battle 1
[42668] = true, -- pet battle 2
[40872] = true, -- cannon return (Teleportologist Fozlebub)
[40007] = true, -- Darkmoon Faire Mystic Mage (Horde)
[40457] = true, -- Darkmoon Faire Mystic Mage (Alliance)
}
local skipGossip = {
[109275] = true, -- Soridormi - begin time rift
[120619] = true, -- Big Dig task
[120620] = true, -- Big Dig task
}
local ignoreGossip = {
[122442] = true, -- leave the dungeon in remix
}
local function isQuestIgnored(questID)
if ignoredQuests[questID] then
return true
end
local questTitle = tonumber(questID) and C_QuestLog.GetTitleForQuestID(questID) or ''
for key, value in next, addon.db.profile.blocklist.quests do
if key == questID or questTitle:lower():find(tostring(key):lower()) then
return value
end
end
return false
end
local function isTrackingTrivialQuests()
for index = 1, C_Minimap.GetNumTrackingTypes() do
local name, _, isActive = C_Minimap.GetTrackingInfo(index)
if name == MINIMAP_TRACKING_TRIVIAL_QUESTS then
return isActive
end
end
end
function addon:GOSSIP_SHOW()
-- triggered when the player interacts with an NPC that presents dialogue
if paused then
return
end
if C_PlayerInteractionManager.IsInteractingWithNpcOfType(Enum.PlayerInteractionType.TaxiNode) then
-- don't annoy taxi addons
return
end
local npcID = addon:GetNPCID('npc')
if addon.db.profile.blocklist.npcs[npcID] then
return
end
-- we want to auto-accept the dialogues from Darkmoon Faire NPCs
for _, info in next, C_GossipInfo.GetOptions() do
if darkmoonFaireOptions[info.gossipOptionID] and addon.db.profile.general.paydarkmoonfaire then
C_GossipInfo.SelectOption(info.gossipOptionID, '', true)
return
elseif skipGossip[info.gossipOptionID] then
C_GossipInfo.SelectOption(info.gossipOptionID)
elseif FlagsUtil.IsSet(info.flags, Enum.GossipOptionRecFlags.QuestLabelPrepend) and addon.db.profile.general.autoquestgossip then
C_GossipInfo.SelectOption(info.gossipOptionID)
end
end
if C_GossipInfo.GetNumActiveQuests() > 0 or C_GossipInfo.GetNumAvailableQuests() > 0 then
-- bail if there is more than just dialogue
return
end
local gossipOptions = C_GossipInfo.GetOptions()
if #gossipOptions == 1 and addon.db.profile.general.skipgossip and gossipOptions[1].gossipOptionID and not ignoreGossip[gossipOptions[1].gossipOptionID] then
-- automatically skip single dialogue under certain conditions
local _, instanceType = GetInstanceInfo()
if instanceType == 'raid' and addon.db.profile.general.skipgossipwhen > 0 then
if GetNumGroupMembers() <= 1 or addon.db.profile.general.skipgossipwhen == 2 then
-- select dialogue if alone or when configured to "Always" while in a raid
C_GossipInfo.SelectOption(gossipOptions[1].gossipOptionID)
return
end
elseif instanceType ~= 'raid' then
-- always select single dialogue while outside a raid
C_GossipInfo.SelectOption(gossipOptions[1].gossipOptionID)
return
end
end
end
function addon:GOSSIP_SHOW()
-- triggered when the player interacts with an NPC that presents dialogue
if paused then
return
end
if addon.db.profile.blocklist.npcs[addon:GetNPCID('npc')] then
return
end
-- turn in all completed quests
if addon.db.profile.general.complete then
for _, info in next, C_GossipInfo.GetActiveQuests() do
if not isQuestIgnored(info.questID) then
if info.isComplete and not C_QuestLog.IsWorldQuest(info.questID) then
C_GossipInfo.SelectActiveQuest(info.questID)
end
end
end
end
-- accept all available quests
if addon.db.profile.general.accept then
for _, info in next, C_GossipInfo.GetAvailableQuests() do
if not isQuestIgnored(info.questID) then
if (not info.isTrivial or isTrackingTrivialQuests()) and (not info.repeatable or addon.db.profile.general.acceptRepeatables) then
C_GossipInfo.SelectAvailableQuest(info.questID)
end
end
end
end
end
function addon:QUEST_GREETING()
-- triggered when the player interacts with an NPC that hands in/out quests
if paused then
return
end
if addon.db.profile.blocklist.npcs[addon:GetNPCID('npc')] then
return
end
-- turn in all completed quests
if addon.db.profile.general.complete then
for index = 1, GetNumActiveQuests() do
if not isQuestIgnored(GetActiveQuestID(index)) then
local _, isComplete = GetActiveTitle(index)
if isComplete and not C_QuestLog.IsWorldQuest(GetActiveQuestID(index)) then
SelectActiveQuest(index)
end
end
end
end
-- accept all available quests
if addon.db.profile.general.accept then
for index = 1, GetNumAvailableQuests() do
local isTrivial, _, isRepeatable, _, questID = GetAvailableQuestInfo(index)
if not isQuestIgnored(questID) then
if (not isTrivial or isTrackingTrivialQuests()) and (not isRepeatable or addon.db.profile.general.acceptRepeatables) then
SelectAvailableQuest(index)
end
end
end
end
end
function addon:QUEST_DETAIL()
-- triggered when the information about an available quest is available
if paused then
return
end
if addon.db.profile.general.accept then
if QuestIsFromAreaTrigger() then
-- this type of quest is automatically accepted, but the dialogue is presented in a way that
-- the player seems to have a choice to decline it, which they don't, so just accept it
AcceptQuest()
elseif QuestGetAutoAccept() then
-- this type of quest is automatically accepted, but the dialogue persists
AcknowledgeAutoAcceptQuest()
elseif not C_QuestLog.IsQuestTrivial(GetQuestID()) or isTrackingTrivialQuests() then
if isQuestIgnored(GetQuestID()) then
CloseQuest()
else
AcceptQuest()
end
end
end
end
local itemCacheQueue = {}
function addon:QUEST_ITEM_UPDATE()
local i, event = next(itemCacheQueue)
if i then
table.remove(itemCacheQueue, i)
addon[event]()
end
end
function addon:QUEST_PROGRESS()
-- triggered when an active quest is selected during turn-in
if paused then
return
end
if addon.db.profile.blocklist.npcs[addon:GetNPCID('npc')] then
return
end
if not IsQuestCompletable() then
return
end
-- iterate through the items part of the quest
for index = 1, GetNumQuestItems() do
local itemLink = GetQuestItemLink('required', index)
if itemLink then
-- check to see if the item is blocked
local questItemID = GetItemInfoFromHyperlink(itemLink)
if addon.db.profile.blocklist.items[questItemID] then
-- item is blocked, prevent this quest from opening again and close it
ignoredQuests[GetQuestID()] = true
CloseQuest()
return
end
else
-- item is not cached yet, trigger the item and wait for the cache to populate
table.insert(itemCacheQueue, 'QUEST_PROGRESS')
GetQuestItemInfo('required', index)
return
end
end
if addon.db.profile.general.complete then
CompleteQuest()
end
end
function addon:QUEST_COMPLETE()
-- triggered when an active quest is ready to be completed
if paused then
return
end
if addon.db.profile.general.complete then
if GetNumQuestChoices() <= 1 then
-- complete the quest by accepting the first item
GetQuestReward(1)
end
end
end
function addon:QUEST_COMPLETE()
if not addon.db.profile.general.selectreward then
return
end
-- triggered when an active quest is ready to be completed
local numItemRewards = GetNumQuestChoices()
if numItemRewards <= 1 then
-- no point iterating over a single item or none at all
return
end
local highestItemValue, highestItemValueIndex = 0
-- iterate through the item rewards and automatically select the one worth the most
for index = 1, numItemRewards do
local itemLink = GetQuestItemLink('choice', index)
if itemLink then
-- check the value on the item and compare it to the others
local _, _, _, _, _, _, _, _, _, _, itemValue = C_Item.GetItemInfo(itemLink)
local itemID = GetItemInfoFromHyperlink(itemLink)
-- some items are containers that contains currencies of worth
itemValue = cashRewards[itemID] or itemValue
-- compare the values
if itemValue > highestItemValue then
highestItemValue = itemValue
highestItemValueIndex = index
end
else
-- item is not cached yet, trigger the item and wait for the cache to populate
table.insert(itemCacheQueue, 'QUEST_COMPLETE')
GetQuestItemInfo('choice', index)
return
end
end
if highestItemValueIndex then
-- this is considered an intrusive action, as we're modifying the UI
QuestInfoItem_OnClick(QuestInfoRewardsFrame.RewardButtons[highestItemValueIndex])
end
end
function addon:QUEST_LOG_UPDATE()
-- triggered when the player's quest log has been altered
if paused or WorldMapFrame:IsShown() then -- see #45
return
end
-- check for quest popups whenever the quest log is updated, which also happens on login, and
-- when the player loots an item that starts a quest
if GetNumAutoQuestPopUps() > 0 then
if UnitIsDeadOrGhost('player') then
-- can't accept quests while we're dead
addon:Defer(addon, 'QUEST_LOG_UPDATE', addon)
return
end
-- this is considered an intrusive action, as we're modifying the UI
local questID, questType = GetAutoQuestPopUp(1)
if questType == 'OFFER' then
if addon.db.profile.general.accept then
ShowQuestOffer(questID)
end
elseif questType == 'COMPLETE' then
if addon.db.profile.general.complete then
ShowQuestComplete(questID)
end
end
-- remove the popup once accepted/completed, the game logic doesn't handle this
RemoveAutoQuestPopUp(questID)
end
end
function addon:QUEST_ACCEPT_CONFIRM()
-- triggered when a quest is shared in the party, but requires confirmation (like escorts)
if paused then
return
end
if addon.db.profile.general.accept then
AcceptQuest()
end
end
function addon:QUEST_ACCEPTED(questID)
-- triggered when a quest has been accepted by the player
if addon.db.profile.general.share then
local questLogIndex = C_QuestLog.GetLogIndexForQuestID(questID)
if questLogIndex then
QuestLogPushQuest(questLogIndex)
end
end
end
function addon:MODIFIER_STATE_CHANGED(key, state)
-- triggered when the player clicks any modifier keys on the keyboard
if string.sub(key, 2) == addon.db.profile.general.pausekey then
-- change the paused state
if addon.db.profile.general.pausekeyreverse then
paused = state ~= 1
else
paused = state == 1
end
end
end
function addon:PLAYER_LOGIN()
-- triggered when the game has completed the login process
if addon.db.profile.general.pausekeyreverse then
-- default to a paused state
paused = true
end
end