1 QuestHelper_File
["main.lua"] = "Development Version"
2 QuestHelper_Loadtime
["main.lua"] = GetTime()
4 local QuestHelper_Version
= QuestHelper_File
["main.lua"]
6 QuestHelper
= CreateFrame("Frame", "QuestHelper", nil)
8 -- Just to make sure it's always 'seen' (there's nothing that can be seen, but still...), and therefore always updating.
9 QuestHelper
:SetFrameStrata("TOOLTIP")
11 QuestHelper_SaveVersion
= 10
12 QuestHelper_CharVersion
= 1
13 QuestHelper_Locale
= GetLocale() -- This variable is used only for the collected data, and has nothing to do with displayed text.
14 QuestHelper_Quests
= {}
15 QuestHelper_Objectives
= {}
20 QuestHelper_DefaultPref
=
25 filter_blocked
=false, -- Hides blocked objectives, such as quest turn-ins for incomplete quests
26 filter_watched
=false, -- Limits to Watched objectives
28 track_minimized
=false,
43 tomtom_wp_new
= false,
49 locale
= GetLocale(), -- This variable is used for display purposes, and has nothing to do with the collected data.
50 perf_scale
= 1, -- How much background processing can the current machine handle? Higher means more load, lower means better performance.
51 perfload_scale
= 1, -- Performance scale to use on startup
55 -- We do it here also in case things decide they care about preferences before the init function is called. Shouldn't happen, but maybe does.
56 setmetatable(QuestHelper_Pref
, {__index
=QuestHelper_DefaultPref
})
58 QuestHelper_FlightInstructors
= {}
59 QuestHelper_FlightLinks
= {}
60 QuestHelper_FlightRoutes
= {}
61 QuestHelper_KnownFlightRoutes
= {}
62 QuestHelper_SeenRealms
= {}
64 QuestHelper
.tooltip
= CreateFrame("GameTooltip", "QuestHelperTooltip", nil, "GameTooltipTemplate")
65 QuestHelper
.objective_objects
= {}
66 QuestHelper
.user_objectives
= {}
67 QuestHelper
.quest_objects
= {}
68 QuestHelper
.player_level
= 1
69 QuestHelper
.locale
= QuestHelper_Locale
71 QuestHelper
.faction
= (UnitFactionGroup("player") == "Alliance" and 1) or
72 (UnitFactionGroup("player") == "Horde" and 2)
74 assert(QuestHelper
.faction
)
76 QuestHelper
.font
= {serif
=GameFontNormal
:GetFont(), sans
=ChatFontNormal
:GetFont(), fancy
=QuestTitleFont
:GetFont()}
78 function QuestHelper
:GetFontPath(list_string
, font
)
80 for name
in string.gmatch(list_string
, "[^;]+") do
81 if font
:SetFont(name
, 10) then
83 elseif font
:SetFont("Interface\\AddOns\\QuestHelper\\Fonts\\"..name
, 10) then
84 return "Interface\\AddOns\\QuestHelper\\Fonts\\"..name
90 function QuestHelper
:SetLocaleFonts()
95 local font
= self
:CreateText(self
)
97 if QuestHelper_Locale
~= QuestHelper_Pref
.locale
then
98 -- Only use alternate fonts if using a language the client wasn't intended for.
99 local replacements
= QuestHelper_SubstituteFonts
[QuestHelper_Pref
.locale
]
101 self
.font
.sans
= self
:GetFontPath(replacements
.sans
, font
)
102 self
.font
.serif
= self
:GetFontPath(replacements
.serif
, font
)
103 self
.font
.fancy
= self
:GetFontPath(replacements
.fancy
, font
)
107 self
.font
.sans
= self
.font
.sans
or self
:GetFontPath(QuestHelper_Pref
.locale
.."_sans.ttf", font
)
108 self
.font
.serif
= self
.font
.serif
or self
:GetFontPath(QuestHelper_Pref
.locale
.."_serif.ttf", font
) or self
.font
.sans
109 self
.font
.fancy
= self
.font
.fancy
or self
:GetFontPath(QuestHelper_Pref
.locale
.."_fancy.ttf", font
) or self
.font
.serif
111 self
:ReleaseText(font
)
113 self
.font
.sans
= self
.font
.sans
or ChatFontNormal
:GetFont()
114 self
.font
.serif
= self
.font
.serif
or GameFontNormal
:GetFont()
115 self
.font
.fancy
= self
.font
.fancy
or QuestTitleFont
:GetFont()
117 -- Need to change the font of the chat frame, for any messages that QuestHelper displays.
118 -- This should do nothing if not using an alternate font.
119 DEFAULT_CHAT_FRAME
:SetFont(self
.font
.sans
, select(2, DEFAULT_CHAT_FRAME
:GetFont()))
122 QuestHelper
.route
= {}
123 QuestHelper
.to_add
= {}
124 QuestHelper
.to_remove
= {}
125 QuestHelper
.quest_log
= {}
126 QuestHelper
.pos
= {nil, {}, 0, 0, 1, "You are here.", 0}
127 QuestHelper
.sharing
= false -- Will be set to true when sharing with at least one user.
129 function QuestHelper
.tooltip
:GetPrevLines() -- Just a helper to make life easier.
130 local last
= self
:NumLines()
131 local name
= self
:GetName()
132 return _G
[name
.."TextLeft"..last
], _G
[name
.."TextRight"..last
]
135 function QuestHelper
:SetTargetLocation(i
, x
, y
, toffset
)
136 -- Informs QuestHelper that you're going to be at some location in toffset seconds.
137 local c
, z
= unpack(QuestHelper_ZoneLookup
[i
])
139 self
.target
= self
:CreateTable()
140 self
.target
[2] = self
:CreateTable()
142 self
.target_time
= time()+(toffset
or 0)
144 x
, y
= self
.Astrolabe
:TranslateWorldMapPosition(c
, z
, x
, y
, c
, 0)
145 self
.target
[1] = self
.zone_nodes
[i
]
146 self
.target
[3] = x
* self
.continent_scales_x
[c
]
147 self
.target
[4] = y
* self
.continent_scales_y
[c
]
149 self
:SetTargetLocationRecalculate()
152 function QuestHelper
:SetTargetLocationRecalculate()
154 for i
, n
in ipairs(self
.target
[1]) do
155 local a
, b
= n
.x
-self
.target
[3], n
.y
-self
.target
[4]
156 self
.target
[2][i
] = math
.sqrt(a
*a
+b
*b
)
161 function QuestHelper
:UnsetTargetLocation()
162 -- Unsets the target set above.
164 self
:ReleaseTable(self
.target
[2])
165 self
:ReleaseTable(self
.target
)
167 self
.target_time
= nil
171 local interruptcount
= 0 -- counts how many "played gained control" messages we recieve, used for flight paths
172 local init_cartographer_later
= false
174 function QuestHelper
:Initialize()
175 QuestHelper_Loadtime
["init_start"] = GetTime()
177 -- Use DefaultPref as fallback for unset preference keys.
178 setmetatable(QuestHelper_Pref
, {__index
=QuestHelper_DefaultPref
})
180 local file_problem
= false
181 local expected_version
= GetAddOnMetadata("QuestHelper", "Version")
183 local expected_files
=
185 ["bst_pre.lua"] = true,
186 ["bst_post.lua"] = true,
187 ["bst_astrolabe.lua"] = true,
188 ["bst_ctl.lua"] = true,
189 ["bst_libaboutpanel.lua"] = true,
191 ["upgrade.lua"] = true,
193 ["recycle.lua"] = true,
194 ["objective.lua"] = true,
195 ["quest.lua"] = true,
196 ["questlog.lua"] = true,
197 ["utility.lua"] = true,
198 ["dodads.lua"] = true,
199 ["graph.lua"] = true,
200 ["teleport.lua"] = true,
201 ["pathfinding.lua"] = true,
202 ["routing.lua"] = true,
203 ["custom.lua"] = true,
205 ["hidden.lua"] = true,
208 ["mapbutton.lua"] = true,
210 ["pattern.lua"] = true,
211 ["flightpath.lua"] = true,
212 ["tracker.lua"] = true,
213 ["objtips.lua"] = true,
214 ["cartographer.lua"] = true,
215 ["tomtom.lua"] = true,
216 ["textviewer.lua"] = true,
217 ["error.lua"] = true,
218 ["timeslice.lua"] = true,
220 ["arrow.lua"] = true,
222 ["static.lua"] = true,
223 ["static_deDE.lua"] = true,
224 ["static_enUS.lua"] = true,
225 ["static_esES.lua"] = true,
226 ["static_esMX.lua"] = true,
227 ["static_frFR.lua"] = true,
228 ["static_koKR.lua"] = true,
229 ["static_ruRU.lua"] = true,
230 ["static_zhCN.lua"] = true,
231 ["static_zhTW.lua"] = true,
233 ["collect.lua"] = true,
234 ["collect_achievement.lua"] = true,
235 ["collect_lzw.lua"] = true,
236 ["collect_traveled.lua"] = true,
237 ["collect_zone.lua"] = true,
238 ["collect_location.lua"] = true,
239 ["collect_merger.lua"] = true,
240 ["collect_monster.lua"] = true,
241 ["collect_item.lua"] = true,
242 ["collect_object.lua"] = true,
243 ["collect_loot.lua"] = true,
244 ["collect_patterns.lua"] = true,
245 ["collect_flight.lua"] = true,
246 ["collect_util.lua"] = true,
247 ["collect_quest.lua"] = true,
248 ["collect_equip.lua"] = true,
249 ["collect_notifier.lua"] = true,
250 ["collect_bitstream.lua"] = true,
251 ["collect_spec.lua"] = true,
252 ["collect_upgrade.lua"] = true,
253 ["collect_merchant.lua"] = true,
254 ["collect_warp.lua"] = true,
257 local uninstallederr
= ""
259 for file
, version
in pairs(QuestHelper_File
) do
260 if not expected_files
[file
] then
261 local errmsg
= "Unexpected QuestHelper file: "..file
262 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
263 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
265 elseif version
~= expected_version
then
266 local errmsg
= "Wrong version of QuestHelper file: "..file
.." (found '"..version
.."', should be '"..expected_version
.."')"
267 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
268 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
269 if version
~= "Development Version" and expected_version
~= "Development Version" then
270 -- Developers are allowed to mix dev versions with release versions
276 for file
in pairs(expected_files
) do
277 if not QuestHelper_File
[file
] then
278 local errmsg
= "Missing QuestHelper file: "..file
279 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
280 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
285 -- Don't need this table anymore.
286 QuestHelper_File
= nil
288 if QuestHelper_StaticData
and not QuestHelper_StaticData
[GetLocale()] then
289 local errmsg
= "Static data does not seem to exist"
290 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
292 -- TODO: Are you sure this should be an error? Shouldn't we let people we don't have data for collect their own?
293 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
298 message(QHText("PLEASE_RESTART"))
299 QuestHelper_ErrorCatcher_ExplicitError(true, "not-installed-properly" .. "\n" .. uninstallederr
)
300 QuestHelper
= nil -- Just in case anybody else is checking for us, we're not home
304 if not GetCategoryList
or not GetQuestLogSpecialItemInfo
or not WatchFrame_RemoveObjectiveHandler
then
305 message(QHText("PRIVATE_SERVER"))
306 QuestHelper_ErrorCatcher_ExplicitError(true, "error id cakbep ten T")
311 if not DongleStub
then
312 message(QHText("NOT_UNZIPPED_CORRECTLY"))
313 QuestHelper_ErrorCatcher_ExplicitError(true, "not-unzipped-properly")
314 QuestHelper
= nil -- Just in case anybody else is checking for us, we're not home
318 QuestHelper_ErrorCatcher_CompletelyStarted()
320 if not QuestHelper_StaticData
then
321 -- If there is no static data for some mysterious reason, create an empty table so that
322 -- other parts of the code can carry on as usual, using locally collected data if it exists.
323 QuestHelper_StaticData
= {}
326 QHFormatSetLocale(QuestHelper_Pref
.locale
or GetLocale())
328 if not QuestHelper_UID
then
329 QuestHelper_UID
= self
:CreateUID()
331 QuestHelper_SaveDate
= time()
333 self
.Astrolabe
= DongleStub("Astrolabe-0.4-QuestHelper")
334 QuestHelper_BuildZoneLookup()
336 if QuestHelper_Locale
~= GetLocale() then
337 self
:TextOut(QHText("LOCALE_ERROR"))
341 if not self
:ZoneSanity() then
342 self
:TextOut(QHText("ZONE_LAYOUT_ERROR"))
343 message("QuestHelper: "..QHText("ZONE_LAYOUT_ERROR"))
347 QuestHelper_UpgradeDatabase(_G
)
348 QuestHelper_UpgradeComplete()
350 if QuestHelper_SaveVersion
~= 10 then
351 self
:TextOut(QHText("DOWNGRADE_ERROR"))
355 if QuestHelper_IsPolluted(_G
) then
356 self
:TextOut(QHFormat("NAG_POLLUTED"))
357 self
:Purge(nil, true, true)
360 local signature
= expected_version
.. " on " .. GetBuildInfo()
361 QuestHelper_Quests
[signature
] = QuestHelper_Quests
[signature
] or {}
362 QuestHelper_Objectives
[signature
] = QuestHelper_Objectives
[signature
] or {}
363 QuestHelper_FlightInstructors
[signature
] = QuestHelper_FlightInstructors
[signature
] or {}
364 QuestHelper_FlightRoutes
[signature
] = QuestHelper_FlightRoutes
[signature
] or {}
366 QuestHelper_Quests_Local
= QuestHelper_Quests
[signature
]
367 QuestHelper_Objectives_Local
= QuestHelper_Objectives
[signature
]
368 QuestHelper_FlightInstructors_Local
= QuestHelper_FlightInstructors
[signature
]
369 QuestHelper_FlightRoutes_Local
= QuestHelper_FlightRoutes
[signature
]
371 QuestHelper_SeenRealms
[GetRealmName()] = true -- some attempt at tracking private servers
375 self
.player_level
= UnitLevel("player")
377 self
:UnregisterEvent("VARIABLES_LOADED")
378 self
:RegisterEvent("PLAYER_TARGET_CHANGED")
379 self
:RegisterEvent("LOOT_OPENED")
380 self
:RegisterEvent("QUEST_COMPLETE")
381 self
:RegisterEvent("QUEST_LOG_UPDATE")
382 self
:RegisterEvent("QUEST_PROGRESS")
383 self
:RegisterEvent("MERCHANT_SHOW")
384 self
:RegisterEvent("QUEST_DETAIL")
385 self
:RegisterEvent("TAXIMAP_OPENED")
386 self
:RegisterEvent("PLAYER_CONTROL_GAINED")
387 self
:RegisterEvent("PLAYER_LEVEL_UP")
388 self
:RegisterEvent("PARTY_MEMBERS_CHANGED")
389 self
:RegisterEvent("CHAT_MSG_ADDON")
390 self
:RegisterEvent("CHAT_MSG_SYSTEM")
391 self
:RegisterEvent("BAG_UPDATE")
392 self
:RegisterEvent("GOSSIP_SHOW")
393 self
:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE")
395 self
:SetLocaleFonts()
397 if QuestHelper_Pref
.share
and not QuestHelper_Pref
.solo
then
401 if QuestHelper_Pref
.hide
then
402 self
.map_overlay
:Hide()
405 self
:HandlePartyChange()
409 for locale
in pairs(QuestHelper_StaticData
) do
410 if locale
~= self
.locale
then
411 -- Will delete references to locales you don't use.
412 QuestHelper_StaticData
[locale
] = nil
413 _G
["QuestHelper_StaticData_" .. locale
] = nil
417 local static
= QuestHelper_StaticData
[self
.locale
]
420 if static
.flight_instructors
then for faction
in pairs(static
.flight_instructors
) do
421 if faction
~= self
.faction
then
422 -- Will delete references to flight instructors that don't belong to your faction.
423 static
.flight_instructors
[faction
] = nil
427 if static
.quest
then for faction
in pairs(static
.quest
) do
428 if faction
~= self
.faction
then
429 -- Will delete references to quests that don't belong to your faction.
430 static
.quest
[faction
] = nil
435 -- Adding QuestHelper_CharVersion, so I know if I've already converted this characters saved data.
436 if not QuestHelper_CharVersion
then
437 -- Changing per-character flight routes, now only storing the flight points they have,
438 -- will attempt to guess the routes from this.
441 for i
, l
in pairs(QuestHelper_KnownFlightRoutes
) do
442 for key
in pairs(l
) do
447 QuestHelper_KnownFlightRoutes
= routes
449 -- Deleting the player's home again.
450 -- But using the new CharVersion variable I'm adding is cleaner that what I was doing, so I'll go with it.
451 QuestHelper_Home
= nil
452 QuestHelper_CharVersion
= 1
455 if not QuestHelper_Home
then
456 -- Not going to bother complaining about the player's home not being set, uncomment this when the home is used in routing.
457 -- self:TextOut(QHText("HOME_NOT_KNOWN"))
460 self
.minimap_dodad
= self
:CreateMipmapDodad()
461 QuestHelper
: Assert(self
.minimap_dodad
)
463 if QuestHelper_Pref
.map_button
then
464 QuestHelper
:InitMapButton()
467 if QuestHelper_Pref
.cart_wp_new
then
468 init_cartographer_later
= true
471 if QuestHelper_Pref
.tomtom_wp_new
then
475 self
.tracker
:SetScale(QuestHelper_Pref
.track_scale
)
477 if QuestHelper_Pref
.track
and not QuestHelper_Pref
.hide
then
481 local version
= GetAddOnMetadata("QuestHelper", "Version") or "Unknown"
483 local major
, minor
= (QuestHelper_Version
or ""):match("^(%d+)%.(%d+)")
484 major
, minor
= tonumber(major
), tonumber(minor
)
486 -- For versions before 0.82, we're changing the default level offset to 3.
487 if major
== 0 and minor
and minor
< 82 and QuestHelper_Pref
.level
== 2 then
488 QuestHelper_Pref
.level
= nil
491 -- For versions before 0.84...
492 if major
== 0 and minor
and minor
< 84 then
493 -- remove all keys that match their default setting.
494 for key
, val
in pairs(QuestHelper_DefaultPref
) do
495 if QuestHelper_Pref
[key
] == val
then
496 QuestHelper_Pref
[key
] = nil
501 self
:SetScript("OnUpdate", self
.OnUpdate
)
503 -- Seems to do its own garbage collection pass before fully loading, so I'll just rely on that
504 --collectgarbage("collect") -- Free everything we aren't using.
506 if self
.debug_objectives
then
507 for name
, data
in pairs(self
.debug_objectives
) do
508 self
:LoadDebugObjective(name
, data
)
512 QH_Timeslice_Add(function ()
514 self
.Routing
:Initialize() -- Set up the routing task
517 --[[ -- This is just an example of how the WoW profiler biases its profiles heavily.
523 for x = 0, 130000000, 1 do
529 for x = 0, 12000000, 1 do
536 for x = 0, 1200000, 1 do
544 local ta = debugprofilestop()
546 local tb = debugprofilestop()
548 local tc = debugprofilestop()
550 QuestHelper:TextOut(string.format("%d %d %d", ta, tb - ta, tc - tb))
551 QuestHelper:TextOut(string.format("%d %d", GetFunctionCPUUsage(A), GetFunctionCPUUsage(B)))
553 --/script SetCVar("scriptProfile", value)]]
555 LibStub("LibAboutPanelQH").new(nil, "QuestHelper")
557 QuestHelper_Loadtime
["init_end"] = GetTime()
561 local please_donate_enabled
= false
562 local please_donate_initted
= false
564 function QuestHelper
:OnEvent(event
)
565 if event
== "VARIABLES_LOADED" then
566 local tstart
= GetTime()
568 QH_Timeslice_Increment(GetTime() - tstart
, "init")
571 local tstart
= GetTime()
573 if event
== "GOSSIP_SHOW" then
574 local name
, id
= UnitName("npc"), self
:GetUnitID("npc")
576 self
:GetObjective("monster", name
).o
.id
= id
577 --self:TextOut("NPC: "..name.." = "..id)
581 if event
== "PLAYER_TARGET_CHANGED" then
582 local name
, id
= UnitName("target"), self
:GetUnitID("target")
584 self
:GetObjective("monster", name
).o
.id
= id
585 --self:TextOut("Target: "..name.." = "..id)
588 if UnitExists("target") and UnitIsVisible("target") and UnitCreatureType("target") ~= "Critter" and not UnitIsPlayer("target") and not UnitPlayerControlled("target") then
589 local index
, x
, y
= self
:UnitPosition("target")
591 if index
then -- Might not have a position if inside an instance.
594 -- Modify the weight based on how far they are from us.
595 -- We don't know the exact location (using our own location), so the farther, the less sure we are that it's correct.
596 if CheckInteractDistance("target", 3) then w
= 1
597 elseif CheckInteractDistance("target", 2) then w
= 0.89
598 elseif CheckInteractDistance("target", 1) or CheckInteractDistance("target", 4) then w
= 0.33 end
600 local monster_objective
= self
:GetObjective("monster", UnitName("target"))
601 self
:AppendObjectivePosition(monster_objective
, index
, x
, y
, w
)
603 monster_objective
.o
.faction
= (UnitFactionGroup("target") == "Alliance" and 1) or
604 (UnitFactionGroup("target") == "Horde" and 2) or nil
606 local level
= UnitLevel("target")
607 if level
and level
>= 1 then
608 local w
= monster_objective
.o
.levelw
or 0
609 monster_objective
.o
.level
= ((monster_objective
.o
.level
or 0)*w
+level
)/(w
+1)
610 monster_objective
.o
.levelw
= w
+1
616 if event
== "LOOT_OPENED" then
617 local target
= UnitName("target")
618 if target
and UnitIsDead("target") and UnitCreatureType("target") ~= "Critter" and not UnitIsPlayer("target") and not UnitPlayerControlled("target") then
619 local index
, x
, y
= self
:UnitPosition("target")
621 local monster_objective
= self
:GetObjective("monster", target
)
622 monster_objective
.o
.looted
= (monster_objective
.o
.looted
or 0) + 1
624 if index
then -- Might not have a position if inside an instance.
625 self
:AppendObjectivePosition(monster_objective
, index
, x
, y
)
628 for i
= 1, GetNumLootItems() do
629 local icon
, name
, number, rarity
= GetLootSlotInfo(i
)
631 if number and number >= 1 then
632 self
:AppendItemObjectiveDrop(self
:GetObjective("item", name
), name
, target
, number)
634 local total
= (name
:match(COPPER_AMOUNT
:gsub("%%d", "%(%%d+%)")) or 0) +
635 (name
:match(SILVER_AMOUNT
:gsub("%%d", "%(%%d+%)")) or 0) * 100 +
636 (name
:match(GOLD_AMOUNT
:gsub("%%d", "%(%%d+%)")) or 0) * 10000
639 self
:AppendObjectiveDrop(self
:GetObjective("item", "money"), target
, total
)
645 local container
= nil
647 -- Go through the players inventory and look for a locked item, we're probably looting it.
648 for bag
= 0,NUM_BAG_SLOTS
do
649 for slot
= 1,GetContainerNumSlots(bag
) do
650 local link
= GetContainerItemLink(bag
, slot
)
651 if link
and select(3, GetContainerItemInfo(bag
, slot
)) then
652 if container
== nil then
653 -- Found a locked item and haven't previously assigned to container, assign its name, or false if we fail to parse it.
654 container
= select(3, string.find(link
, "|h%[(.+)%]|h|r")) or false
656 -- Already tried to assign to a container. If there are multiple locked items, we give up.
664 local container_objective
= self
:GetObjective("item", container
)
665 container_objective
.o
.opened
= (container_objective
.o
.opened
or 0) + 1
667 for i
= 1, GetNumLootItems() do
668 local icon
, name
, number, rarity
= GetLootSlotInfo(i
)
669 if name
and number >= 1 then
670 self
:AppendItemObjectiveContainer(self
:GetObjective("item", name
), container
, number)
674 -- No idea where the items came from.
675 local index
, x
, y
= self
:PlayerPosition()
678 for i
= 1, GetNumLootItems() do
679 local icon
, name
, number, rarity
= GetLootSlotInfo(i
)
680 if name
and number >= 1 then
681 self
:AppendItemObjectivePosition(self
:GetObjective("item", name
), name
, index
, x
, y
)
689 if event
== "CHAT_MSG_SYSTEM" then
690 local home_name
= self
:convertPattern(ERR_DEATHBIND_SUCCESS_S
)(arg1
)
693 self
:TextOut(QHText("HOME_CHANGED"))
694 self
:TextOut(QHText("WILL_RESET_PATH"))
696 local home
= QuestHelper_Home
699 QuestHelper_Home
= home
702 home
[1], home
[2], home
[3], home
[4] = self
.i
, self
.x
, self
.y
, home_name
703 self
.defered_graph_reset
= true
708 if event
== "CHAT_MSG_ADDON" then
709 if arg1
== "QHpr" and (arg3
== "PARTY" or arg3
== "WHISPER") and arg4
~= UnitName("player") then
710 self
:HandleRemoteData(arg2
, arg4
)
714 if event
== "PARTY_MEMBERS_CHANGED" then
715 self
:HandlePartyChange()
718 if event
== "QUEST_LOG_UPDATE" or
719 event
== "PLAYER_LEVEL_UP" or
720 event
== "PARTY_MEMBERS_CHANGED" then
721 self
.defered_quest_scan
= true
724 if event
== "QUEST_DETAIL" then
725 if not self
.quest_giver
then self
.quest_giver
= {} end
726 local npc
= UnitName("npc")
728 -- Some NPCs aren't actually creatures, and so their positions might not be marked by PLAYER_TARGET_CHANGED.
729 local index
, x
, y
= self
:UnitPosition("npc")
731 if index
then -- Might not have a position if inside an instance.
732 local npc_objective
= self
:GetObjective("monster", npc
)
733 self
:AppendObjectivePosition(npc_objective
, index
, x
, y
)
734 self
.quest_giver
[GetTitleText()] = npc
739 if event
== "QUEST_COMPLETE" or event
== "QUEST_PROGRESS" then
740 local quest
= GetTitleText()
742 local level
, hash
= self
:GetQuestLevel(quest
)
743 if not level
or level
< 1 then
744 --self:TextOut("Don't know quest level for ".. quest.."!")
747 local q
= self
:GetQuest(quest
, level
, hash
)
753 local unit
= UnitName("npc")
758 -- Some NPCs aren't actually creatures, and so their positions might not be marked by PLAYER_TARGET_CHANGED.
759 local index
, x
, y
= self
:UnitPosition("npc")
760 if index
then -- Might not have a position if inside an instance.
761 local npc_objective
= self
:GetObjective("monster", unit
)
762 self
:AppendObjectivePosition(npc_objective
, index
, x
, y
)
764 elseif not q
.o
.finish
then
765 local index
, x
, y
= self
:PlayerPosition()
766 if index
then -- Might not have a position if inside an instance.
767 self
:AppendObjectivePosition(q
, index
, x
, y
)
773 if event
== "MERCHANT_SHOW" then
774 local npc_name
= UnitName("npc")
776 local npc_objective
= self
:GetObjective("monster", npc_name
)
779 local item_name
= GetMerchantItemInfo(index
)
782 local item_objective
= self
:GetObjective("item", item_name
)
783 if not item_objective
.o
.vendor
then
784 item_objective
.o
.vendor
= {npc_name
}
787 for i
, vendor
in ipairs(item_objective
.o
.vendor
) do
788 if npc_name
== vendor
then
794 table.insert(item_objective
.o
.vendor
, npc_name
)
804 if event
== "TAXIMAP_OPENED" then
808 if event
== "PLAYER_CONTROL_GAINED" then
809 interruptcount
= interruptcount
+ 1
812 if event
== "BAG_UPDATE" then
813 for slot
= 1,GetContainerNumSlots(arg1
) do
814 local link
= GetContainerItemLink(arg1
, slot
)
816 local id
, name
= select(3, string.find(link
, "|Hitem:(%d+):.-|h%[(.-)%]|h"))
818 self
:GetObjective("item", name
).o
.id
= tonumber(id
)
824 if event
== "CHAT_MSG_CHANNEL_NOTICE" and please_donate_enabled
and not please_donate_initted
then
825 please_donate_enabled
= QHNagInit()
826 startup_time
= GetTime()
827 please_donate_initted
= true
832 QH_Timeslice_Increment(GetTime() - tstart
, "event")
835 local map_shown_decay
= 0
836 local delayed_action
= 100
837 --local update_count = 0
841 function QuestHelper
:OnUpdate()
842 local tstart
= GetTime()
845 if not QuestHelper_Loadtime
["onupdate"] then QuestHelper_Loadtime
["onupdate"] = GetTime() end
847 if frams
== 250 then please_donate_enabled
= false end -- TOOK TOO LONG >:(
848 if please_donate_enabled
and startup_time
and startup_time
+ 1 < GetTime() then
849 QuestHelper
:TextOut(QHText("PLEASE_DONATE"))
851 please_donate_enabled
= false
853 QHUpdateNagTick() -- These probably shouldn't be in OnUpdate. Eventually I'll move them somewhere cleaner.
855 if init_cartographer_later
and Cartographer_Waypoints
then -- there has to be a better way to do this
856 init_cartographer_later
= false
857 if QuestHelper_Pref
.cart_wp_new
then
858 self
:EnableCartographer()
862 if not ontaxi
and UnitOnTaxi("player") then
865 elseif ontaxi
and not UnitOnTaxi("player") then
866 self
:flightEnded(interruptcount
> 1)
868 ontaxi
= UnitOnTaxi("player")
870 -- For now I'm ripping out the update_count code
871 --update_count = update_count - 1
872 --if update_count <= 0 then
874 -- Reset the update count for next time around; this will make sure the body executes every time
875 -- when perf_scale >= 1, and down to 1 in 10 iterations when perf_scale < 1, or when hidden.
876 --update_count = update_count + (QuestHelper_Pref.hide and 10 or 1/QuestHelper_Pref.perf_scale)
878 --if update_count < 0 then
879 -- Make sure the count doesn't go perpetually negative; don't know what will happen if it underflows.
883 if self
.Astrolabe
.WorldMapVisible
then
884 -- We won't trust that the zone returned by Astrolabe is correct until map_shown_decay is 0.
886 elseif map_shown_decay
> 0 then
887 map_shown_decay
= map_shown_decay
- 1
889 --SetMapToCurrentZone() -- not sure why this existed
892 delayed_action
= delayed_action
- 1
893 if delayed_action
<= 0 then
895 self
:HandlePartyChange()
898 local nc
, nz
, nx
, ny
= self
.Astrolabe
:GetCurrentPlayerPosition()
901 if nc
and nc
~= -1 then -- We just want the raw data here, before we've done anything clever.
902 tc
, tx
, ty
= self
.Astrolabe
:GetAbsoluteContinentPosition(nc
, nz
, nx
, ny
)
903 QuestHelper
: Assert(tc
and tx
and ty
) -- is it true? nobody knows! :D
906 if nc
and nc
== self
.c
and map_shown_decay
> 0 and self
.z
> 0 and self
.z
~= nz
then
907 -- There's a chance Astrolable will return the wrong zone if you're messing with the world map, if you can
908 -- be seen in that zone but aren't in it.
909 local nnx
, nny
= self
.Astrolabe
:TranslateWorldMapPosition(nc
, nz
, nx
, ny
, nc
, self
.z
)
910 if nnx
> 0 and nny
> 0 and nnx
< 1 and nny
< 1 then
911 nz
, nx
, ny
= self
.z
, nnx
, nny
915 if nc
and nc
> 0 and nz
== 0 and nc
== self
.c
and self
.z
> 0 then
916 nx
, ny
= self
.Astrolabe
:TranslateWorldMapPosition(nc
, nz
, nx
, ny
, nc
, self
.z
)
917 if nx
and ny
--[[and nx > -0.1 and ny > -0.1 and nx < 1.1 and ny < 1.1]] then -- removing the conditional because I think I can use the data even when it's a little wonky
920 nc
, nz
, nx
, ny
= nil, nil, nil, nil
924 if nc
and nz
> 0 then
925 self
.c
, self
.z
, self
.x
, self
.y
= nc
, nz
, nx
, ny
926 self
.i
= QuestHelper_IndexLookup
[nc
][nz
]
929 if nc
and nz
and nx
and ny
and tc
and tx
and ty
then
930 self
.collect_rc
, self
.collect_rz
, self
.collect_rx
, self
.collect_ry
= nc
, nz
, nx
, ny
931 self
.collect_ac
, self
.collect_ax
, self
.collect_ay
= tc
, tx
, ty
932 self
.collect_delayed
= false
934 local ibi
= self
.InBrokenInstance
935 if nc
< -77 then self
.InBrokenInstance
= true else self
.InBrokenInstance
= false end
937 if ibi
and not self
.InBrokenInstance
then self
.minimap_dodad
:OnUpdate(0) end -- poke
939 self
.collect_delayed
= true
940 self
.InBrokenInstance
= true
943 local level
= UnitLevel("player")
944 if level
>= 58 and self
.player_level
< 58 then
945 self
.defered_graph_reset
= true
947 if level
~= self
.player_level
then
948 self
.defered_quest_scan
= true
950 self
.player_level
= level
952 if self
.defered_quest_scan
and not self
.graph_in_limbo
then
953 self
.defered_quest_scan
= false
957 QH_Timeslice_Toggle("routing", not not self
.c
)
959 self
:PumpCommMessages()
962 QH_Collector_OnUpdate()
964 QH_Timeslice_Increment(GetTime() - tstart
, "onupdate")
969 -- Some or all of these may be nil. c,x,y should be enough for a location - c is the pure continent (currently either 0 or 3 for Azeroth or Outland) and x,y are the coordinates within that continent.
970 -- rc and rz are the continent and zone that Questhelper thinks it's within. For various reasons, this isn't perfect. TODO: Base it off the map zone name identifiers instead of the map itself?
971 function QuestHelper
:Location_RawRetrieve()
972 return self
.collect_delayed
, self
.collect_rc
, self
.collect_rz
, self
.collect_rx
, self
.collect_ry
974 function QuestHelper
:Location_AbsoluteRetrieve()
975 return self
.collect_delayed
, self
.collect_ac
, self
.collect_ax
, self
.collect_ay
978 QuestHelper
:RegisterEvent("VARIABLES_LOADED")
979 QuestHelper
:SetScript("OnEvent", QuestHelper
.OnEvent
)