1 QuestHelper_File
["main.lua"] = "Development Version"
2 QuestHelper_Loadtime
["main.lua"] = GetTime()
4 local version_string
= QuestHelper_File
["main.lua"] -- we pretty much save this only so we can inform the user that they're using a beta version
6 -- Just to make sure it's always 'seen' (there's nothing that can be seen, but still...), and therefore always updating.
7 QuestHelper
:SetFrameStrata("TOOLTIP")
9 QuestHelper_CharVersion
= 1
10 QuestHelper_Locale
= GetLocale() -- This variable is used only for the collected data, and has nothing to do with displayed text.
11 QuestHelper_Quests
= {}
12 QuestHelper_Objectives
= {}
17 local QuestHelper_DefaultPref
=
22 filter_blocked
=false, -- Hides blocked objectives, such as quest turn-ins for incomplete quests
23 filter_watched
=false, -- Limits to Watched objectives
26 filter_wintergrasp
=true,
27 filter_raid_accessible
=true,
30 track_minimized
=false,
46 tomtom_wp_new
= false,
51 metric
= (QuestHelper_Locale
~= "enUS" and QuestHelper_Locale
~= "esMX"),
53 locale
= GetLocale(), -- This variable is used for display purposes, and has nothing to do with the collected data.
54 perf_scale_2
= 1, -- How much background processing can the current machine handle? Higher means more load, lower means better performance.
55 perfload_scale
= 1, -- Performance scale to use on startup
61 -- 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.
62 setmetatable(QuestHelper_Pref
, {__index
=QuestHelper_DefaultPref
})
64 QuestHelper_FlightInstructors
= {}
65 QuestHelper_FlightLinks
= {}
66 QuestHelper_FlightRoutes
= {}
67 QuestHelper_KnownFlightRoutes
= {}
68 QuestHelper_SeenRealms
= {}
70 QuestHelper
.tooltip
= CreateFrame("GameTooltip", "QuestHelperTooltip", nil, "GameTooltipTemplate")
71 QuestHelper
.objective_objects
= {}
72 QuestHelper
.user_objectives
= {}
73 QuestHelper
.quest_objects
= {}
74 QuestHelper
.player_level
= 1
75 QuestHelper
.locale
= QuestHelper_Locale
77 QuestHelper
.faction
= (UnitFactionGroup("player") == "Alliance" and 1) or
78 (UnitFactionGroup("player") == "Horde" and 2)
80 assert(QuestHelper
.faction
)
82 QuestHelper
.font
= {serif
=GameFontNormal
:GetFont(), sans
=ChatFontNormal
:GetFont(), fancy
=QuestTitleFont
:GetFont()}
84 function QuestHelper
:GetFontPath(list_string
, font
)
86 for name
in string.gmatch(list_string
, "[^;]+") do
87 if font
:SetFont(name
, 10) then
89 elseif font
:SetFont("Interface\\AddOns\\QuestHelper\\Fonts\\"..name
, 10) then
90 return "Interface\\AddOns\\QuestHelper\\Fonts\\"..name
96 function QuestHelper
:SetLocaleFonts()
101 local font
= self
:CreateText(self
)
103 if QuestHelper_Locale
~= QuestHelper_Pref
.locale
then
104 -- Only use alternate fonts if using a language the client wasn't intended for.
105 local replacements
= QuestHelper_SubstituteFonts
[QuestHelper_Pref
.locale
]
107 self
.font
.sans
= self
:GetFontPath(replacements
.sans
, font
)
108 self
.font
.serif
= self
:GetFontPath(replacements
.serif
, font
)
109 self
.font
.fancy
= self
:GetFontPath(replacements
.fancy
, font
)
113 self
.font
.sans
= self
.font
.sans
or self
:GetFontPath(QuestHelper_Pref
.locale
.."_sans.ttf", font
)
114 self
.font
.serif
= self
.font
.serif
or self
:GetFontPath(QuestHelper_Pref
.locale
.."_serif.ttf", font
) or self
.font
.sans
115 self
.font
.fancy
= self
.font
.fancy
or self
:GetFontPath(QuestHelper_Pref
.locale
.."_fancy.ttf", font
) or self
.font
.serif
117 self
:ReleaseText(font
)
119 self
.font
.sans
= self
.font
.sans
or ChatFontNormal
:GetFont()
120 self
.font
.serif
= self
.font
.serif
or GameFontNormal
:GetFont()
121 self
.font
.fancy
= self
.font
.fancy
or QuestTitleFont
:GetFont()
123 -- Need to change the font of the chat frame, for any messages that QuestHelper displays.
124 -- This should do nothing if not using an alternate font.
125 --DEFAULT_CHAT_FRAME:SetFont(self.font.sans, select(2, DEFAULT_CHAT_FRAME:GetFont()))
126 -- what why did we ever do this
129 QuestHelper
.route
= {}
130 QuestHelper
.to_add
= {}
131 QuestHelper
.to_remove
= {}
132 QuestHelper
.quest_log
= {}
133 QuestHelper
.pos
= {nil, {}, 0, 0, 1, "You are here.", 0}
134 QuestHelper
.sharing
= false -- Will be set to true when sharing with at least one user.
136 function QuestHelper
.tooltip
:GetPrevLines() -- Just a helper to make life easier.
137 local last
= self
:NumLines()
138 local name
= self
:GetName()
139 return _G
[name
.."TextLeft"..last
], _G
[name
.."TextRight"..last
]
142 function QuestHelper
:SetTargetLocation(i
, x
, y
, toffset
)
143 -- Informs QuestHelper that you're going to be at some location in toffset seconds.
144 local c
, z
= unpack(QuestHelper_ZoneLookup
[i
])
146 self
.target
= self
:CreateTable()
147 self
.target
[2] = self
:CreateTable()
149 self
.target_time
= time()+(toffset
or 0)
151 x
, y
= self
.Astrolabe
:TranslateWorldMapPosition(c
, z
, x
, y
, c
, 0)
152 self
.target
[1] = self
.zone_nodes
[i
]
153 self
.target
[3] = x
* self
.continent_scales_x
[c
]
154 self
.target
[4] = y
* self
.continent_scales_y
[c
]
156 self
:SetTargetLocationRecalculate()
159 function QuestHelper
:SetTargetLocationRecalculate()
161 for i
, n
in ipairs(self
.target
[1]) do
162 local a
, b
= n
.x
-self
.target
[3], n
.y
-self
.target
[4]
163 self
.target
[2][i
] = math
.sqrt(a
*a
+b
*b
)
168 function QuestHelper
:UnsetTargetLocation()
169 -- Unsets the target set above.
171 self
:ReleaseTable(self
.target
[2])
172 self
:ReleaseTable(self
.target
)
174 self
.target_time
= nil
178 local interruptcount
= 0 -- counts how many "played gained control" messages we recieve, used for flight paths
179 local init_cartographer_later
= false
183 local please_submit_enabled
= true
184 local please_submit_initted
= false
186 local spawned
= false
187 QH_Event("ADDON_LOADED", function (addonid
)
188 if addonid
~= "QuestHelper" then return end
190 -- ONLY FAST STUFF ALLOWED IN HERE
192 -- Use DefaultPref as fallback for unset preference keys.
193 setmetatable(QuestHelper_Pref
, {__index
=QuestHelper_DefaultPref
})
194 QuestHelper
: Assert(QuestHelper_Pref
.perfload_scale
) -- if this fails, something is very botched
196 if not QuestHelper_Pref
.track
or QuestHelper_Pref
.hide
then
197 QuestHelper
:HideTracker()
199 QuestHelper
:ShowTracker() -- to respect the minimized setting
202 local self
= QuestHelper
-- whee hack hack hack
204 QuestHelper_Loadtime
["init2_start"] = GetTime()
206 local file_problem_version
= false
208 local expected_version
= GetAddOnMetadata("QuestHelper", "Version")
210 local expected_files
=
212 ["bst_pre.lua"] = true,
213 ["bst_post.lua"] = true,
214 ["bst_astrolabe.lua"] = true,
215 ["bst_ctl.lua"] = true,
216 ["bst_libaboutpanel.lua"] = true,
217 ["bst_range.lua"] = true,
219 ["manager_event.lua"] = true,
220 ["manager_achievement.lua"] = true,
221 ["manager_completed.lua"] = true,
223 ["upgrade.lua"] = true,
225 ["recycle.lua"] = true,
226 ["objective.lua"] = true,
227 ["quest.lua"] = true,
228 ["utility.lua"] = true,
229 ["dodads.lua"] = true,
230 ["dodads_triangles.lua"] = true,
231 ["teleport.lua"] = true,
232 ["pathfinding.lua"] = true,
233 ["routing.lua"] = true,
234 ["custom.lua"] = true,
238 ["mapbutton.lua"] = true,
240 ["pattern.lua"] = true,
241 ["flightpath.lua"] = true,
242 ["tracker.lua"] = true,
243 ["objtips.lua"] = true,
244 ["cartographer.lua"] = true,
245 ["cartographer_is_terrible.lua"] = true,
246 ["tomtom.lua"] = true,
247 ["textviewer.lua"] = true,
248 ["error.lua"] = true,
249 ["timeslice.lua"] = true,
252 ["tooltip.lua"] = true,
253 ["arrow.lua"] = true,
254 ["radar.lua"] = true,
256 ["config.lua"] = true,
258 ["static.lua"] = true,
259 ["static_1.lua"] = true,
260 ["static_2.lua"] = true,
261 ["static_deDE.lua"] = true,
262 ["static_deDE_1.lua"] = true,
263 ["static_deDE_2.lua"] = true,
264 ["static_enUS.lua"] = true,
265 ["static_enUS_1.lua"] = true,
266 ["static_enUS_2.lua"] = true,
267 ["static_esES.lua"] = true,
268 ["static_esES_1.lua"] = true,
269 ["static_esES_2.lua"] = true,
270 ["static_esMX.lua"] = true,
271 ["static_esMX_1.lua"] = true,
272 ["static_esMX_2.lua"] = true,
273 ["static_frFR.lua"] = true,
274 ["static_frFR_1.lua"] = true,
275 ["static_frFR_2.lua"] = true,
276 ["static_koKR.lua"] = true,
277 ["static_koKR_1.lua"] = true,
278 ["static_koKR_2.lua"] = true,
279 ["static_ruRU.lua"] = true,
280 ["static_ruRU_1.lua"] = true,
281 ["static_ruRU_2.lua"] = true,
282 ["static_zhTW.lua"] = true,
283 ["static_zhTW_1.lua"] = true,
284 ["static_zhTW_2.lua"] = true,
286 ["collect.lua"] = true,
287 ["collect_achievement.lua"] = true,
288 ["collect_lzw.lua"] = true,
289 ["collect_traveled.lua"] = true,
290 ["collect_zone.lua"] = true,
291 ["collect_location.lua"] = true,
292 ["collect_merger.lua"] = true,
293 ["collect_monster.lua"] = true,
294 ["collect_item.lua"] = true,
295 ["collect_object.lua"] = true,
296 ["collect_loot.lua"] = true,
297 ["collect_patterns.lua"] = true,
298 ["collect_flight.lua"] = true,
299 ["collect_util.lua"] = true,
300 ["collect_quest.lua"] = true,
301 ["collect_equip.lua"] = true,
302 ["collect_notifier.lua"] = true,
303 ["collect_bitstream.lua"] = true,
304 ["collect_spec.lua"] = true,
305 ["collect_upgrade.lua"] = true,
306 ["collect_merchant.lua"] = true,
307 ["collect_warp.lua"] = true,
309 ["filter_core.lua"] = true,
310 ["filter_base.lua"] = true,
312 ["routing_debug.lua"] = true,
313 ["routing_loc.lua"] = true,
314 ["routing_route.lua"] = true,
315 ["routing_core.lua"] = true,
316 ["routing_controller.lua"] = true,
317 ["routing_hidden.lua"] = true,
319 ["director_quest.lua"] = true,
320 ["director_achievement.lua"] = true,
321 ["director_find.lua"] = true,
323 ["db_get.lua"] = true,
325 ["graph_core.lua"] = true,
326 ["graph_flightpath.lua"] = true,
328 ["AstrolabeQH/Astrolabe.lua"] = true,
329 ["AstrolabeQH/AstrolabeMapMonitor.lua"] = true,
332 local uninstallederr
= ""
334 for file
, version
in pairs(QuestHelper_File
) do
335 if not expected_files
[file
] then
336 local errmsg
= "Unexpected QuestHelper file: "..file
337 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
338 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
339 file_problem_version
= true
340 elseif version
~= expected_version
then
341 local errmsg
= "Wrong version of QuestHelper file: "..file
.." (found '"..version
.."', should be '"..expected_version
.."')"
342 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
343 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
344 if version
~= "Development Version" and expected_version
~= "Development Version" then
345 -- Developers are allowed to mix dev versions with release versions
346 file_problem_version
= true
351 for file
in pairs(expected_files
) do
352 if not QuestHelper_File
[file
] then
353 local errmsg
= "Missing QuestHelper file: "..file
354 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
355 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
356 if not (expected_version
== "Development Version" and file
:match("static.*")) then file_problem_version
= true end
360 -- Don't need this table anymore.
361 QuestHelper_File
= nil
363 if QuestHelper_StaticData
and not QuestHelper_StaticData
[GetLocale()] then
364 local errmsg
= "Static data does not seem to exist"
365 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
367 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
368 file_problem_version
= true
371 if file_problem_version
then
372 QH_fixedmessage(QHText("PLEASE_RESTART"))
373 QuestHelper_ErrorCatcher_ExplicitError(false, "not-installed-properly" .. "\n" .. uninstallederr
)
374 QuestHelper
= nil -- Just in case anybody else is checking for us, we're not home
378 if not GetCategoryList
or not GetQuestLogSpecialItemInfo
or not WatchFrame_RemoveObjectiveHandler
then
379 QH_fixedmessage(QHText("PRIVATE_SERVER"))
380 QuestHelper_ErrorCatcher_ExplicitError(false, "error id cakbep ten T")
385 if not DongleStub
or not QH_Astrolabe_Ready
then
386 QH_fixedmessage(QHText("NOT_UNZIPPED_CORRECTLY"))
387 QuestHelper_ErrorCatcher_ExplicitError(false, "not-unzipped-properly")
388 QuestHelper
= nil -- Just in case anybody else is checking for us, we're not home
392 QuestHelper_ErrorCatcher_CompletelyStarted()
394 if not QuestHelper_StaticData
then
395 -- If there is no static data for some mysterious reason, create an empty table so that
396 -- other parts of the code can carry on as usual, using locally collected data if it exists.
397 QuestHelper_StaticData
= {}
400 QHFormatSetLocale(QuestHelper_Pref
.locale
or GetLocale())
402 if not QuestHelper_UID
then
403 QuestHelper_UID
= self
:CreateUID()
405 QuestHelper_SaveDate
= time()
408 QH_Timeslice_Add(function ()
409 QuestHelper_Loadtime
["init3_start"] = GetTime()
411 QuestHelper
.loading_main
= QuestHelper
.CreateLoadingCounter()
413 QuestHelper
.loading_init3
= QuestHelper
.loading_main
:MakeSubcategory(0.3)
414 QuestHelper
.loading_flightpath
= QuestHelper
.loading_main
:MakeSubcategory(1)
415 QuestHelper
.loading_preroll
= QuestHelper
.loading_main
:MakeSubcategory(1)
419 -- This is where the slow stuff goes
420 QuestHelper_BuildZoneLookup()
424 if QuestHelper_Locale
~= GetLocale() then
425 self
:TextOut(QHText("LOCALE_ERROR"))
429 if not self
:ZoneSanity() then
430 self
:TextOut(QHFormat("ZONE_LAYOUT_ERROR", expected_version
))
431 QH_fixedmessage(QHFormat("ZONE_LAYOUT_ERROR", expected_version
))
436 QuestHelper_UpgradeDatabase(_G
)
437 QuestHelper_UpgradeComplete()
439 if QuestHelper_IsPolluted(_G
) then
440 self
:TextOut(QHFormat("NAG_POLLUTED"))
441 self
:Purge(nil, true, true)
444 local signature
= expected_version
.. " on " .. GetBuildInfo()
445 QuestHelper_Quests
[signature
] = QuestHelper_Quests
[signature
] or {}
446 QuestHelper_Objectives
[signature
] = QuestHelper_Objectives
[signature
] or {}
447 QuestHelper_FlightInstructors
[signature
] = QuestHelper_FlightInstructors
[signature
] or {}
448 QuestHelper_FlightRoutes
[signature
] = QuestHelper_FlightRoutes
[signature
] or {}
450 QuestHelper_Quests_Local
= QuestHelper_Quests
[signature
]
451 QuestHelper_Objectives_Local
= QuestHelper_Objectives
[signature
]
452 QuestHelper_FlightInstructors_Local
= QuestHelper_FlightInstructors
[signature
]
453 QuestHelper_FlightRoutes_Local
= QuestHelper_FlightRoutes
[signature
]
455 QuestHelper_SeenRealms
[GetRealmName()] = true -- some attempt at tracking private servers
457 QuestHelper
.loading_init3
:SetPercentage(0.1)
459 QuestHelper
.loading_init3
:SetPercentage(0.5)
461 QuestHelper
.loading_init3
:SetPercentage(0.9)
463 self
.player_level
= UnitLevel("player")
465 self
:SetLocaleFonts()
467 if QuestHelper_Pref
.share
and not QuestHelper_Pref
.solo
then
471 if QuestHelper_Pref
.hide
then
472 self
.map_overlay
:Hide()
475 self
:HandlePartyChange()
479 for locale
in pairs(QuestHelper_StaticData
) do
480 if locale
~= self
.locale
then
481 -- Will delete references to locales you don't use.
482 QuestHelper_StaticData
[locale
] = nil
483 _G
["QuestHelper_StaticData_" .. locale
] = nil
487 local static
= QuestHelper_StaticData
[self
.locale
]
490 if static
.flight_instructors
then for faction
in pairs(static
.flight_instructors
) do
491 if faction
~= self
.faction
then
492 -- Will delete references to flight instructors that don't belong to your faction.
493 static
.flight_instructors
[faction
] = nil
497 if static
.quest
then for faction
in pairs(static
.quest
) do
498 if faction
~= self
.faction
then
499 -- Will delete references to quests that don't belong to your faction.
500 static
.quest
[faction
] = nil
505 -- Adding QuestHelper_CharVersion, so I know if I've already converted this characters saved data.
506 if not QuestHelper_CharVersion
then
507 -- Changing per-character flight routes, now only storing the flight points they have,
508 -- will attempt to guess the routes from this.
511 for i
, l
in pairs(QuestHelper_KnownFlightRoutes
) do
512 for key
in pairs(l
) do
517 QuestHelper_KnownFlightRoutes
= routes
519 -- Deleting the player's home again.
520 -- But using the new CharVersion variable I'm adding is cleaner that what I was doing, so I'll go with it.
521 QuestHelper_Home
= nil
522 QuestHelper_CharVersion
= 1
525 if not QuestHelper_Home
then
526 -- Not going to bother complaining about the player's home not being set, uncomment this when the home is used in routing.
527 -- self:TextOut(QHText("HOME_NOT_KNOWN"))
530 if QuestHelper_Pref
.map_button
then
531 QuestHelper
:InitMapButton()
534 if QuestHelper_Pref
.cart_wp_new
then
535 init_cartographer_later
= true
538 if QuestHelper_Pref
.tomtom_wp_new
then
542 self
.tracker
:SetScale(QuestHelper_Pref
.track_scale
)
544 local version
= GetAddOnMetadata("QuestHelper", "Version") or "Unknown"
546 local major
, minor
= (version_string
or ""):match("^(%d+)%.(%d+)")
547 major
, minor
= tonumber(major
), tonumber(minor
)
549 -- For versions before 0.82, we're changing the default level offset to 3.
550 if major
== 0 and minor
and minor
< 82 and QuestHelper_Pref
.level
== 2 then
551 QuestHelper_Pref
.level
= nil
554 -- For versions before 0.84...
555 if major
== 0 and minor
and minor
< 84 then
556 -- remove all keys that match their default setting.
557 for key
, val
in pairs(QuestHelper_DefaultPref
) do
558 if QuestHelper_Pref
[key
] == val
then
559 QuestHelper_Pref
[key
] = nil
564 QH_Hook(self
, "OnUpdate", self
.OnUpdate
)
566 -- Seems to do its own garbage collection pass before fully loading, so I'll just rely on that
567 --collectgarbage("collect") -- Free everything we aren't using.
570 if self.debug_objectives then
571 for name, data in pairs(self.debug_objectives) do
572 self:LoadDebugObjective(name, data)
578 QH_Arrow_SetTextScale()
581 QH_Timeslice_Add(function ()
583 self.Routing:Initialize() -- Set up the routing task
584 end, "init")]] -- FUCK YOU BOXBOT
586 --[[ -- This is just an example of how the WoW profiler biases its profiles heavily.
592 for x = 0, 130000000, 1 do
598 for x = 0, 12000000, 1 do
605 for x = 0, 1200000, 1 do
613 local ta = debugprofilestop()
615 local tb = debugprofilestop()
617 local tc = debugprofilestop()
619 QuestHelper:TextOut(string.format("%d %d %d", ta, tb - ta, tc - tb))
620 QuestHelper:TextOut(string.format("%d %d", GetFunctionCPUUsage(A), GetFunctionCPUUsage(B)))
622 --/script SetCVar("scriptProfile", value)]]
625 QH_Event("CHAT_MSG_ADDON", function (...)
626 if arg1
== "QHpr" and arg4
~= UnitName("player") then
627 QH_Questcomm_Msg(arg2
, arg4
)
631 QH_Event({"PARTY_MEMBERS_CHANGED", "UNIT_LEVEL", "RAID_ROSTER_UPDATE"}, function ()
632 QH_Filter_Group_Sync()
633 QH_Route_Filter_Rescan("filter_quest_level")
634 --QH_Route_Filter_Rescan("filter_quest_group")
635 --QH_Route_Filter_Rescan("filter_quest_raid_accessible") -- These should be in right now, but for simplicity's sake we're actually scanning everything when we get a rescan request. So they're unnecessary. PUT THEM BACK should they become necessary.
638 QH_Event({"PARTY_MEMBERS_CHANGED", "RAID_ROSTER_UPDATE"}, function ()
642 QH_Event("PLAYER_LEVEL_UP", function ()
643 self
.player_level
= arg1
644 QH_Route_Filter_Rescan("filter_quest_level")
647 QH_Event("TAXIMAP_OPENED", function ()
651 QH_Event({"ZONE_CHANGED", "ZONE_CHANGED_INDOORS", "ZONE_CHANGED_NEW_AREA"}, function()
652 QH_Route_Filter_Rescan(nil, true)
655 QH_Event("CHAT_MSG_CHANNEL_NOTICE", function()
656 if please_submit_enabled
and not please_submit_initted
then
657 please_submit_enabled
= QHNagInit()
658 startup_time
= GetTime()
659 please_submit_initted
= true
663 QuestHelper
.loading_init3
:SetPercentage(1.0) -- victory
665 QuestHelper_Loadtime
["init3_end"] = GetTime()
668 QuestHelper_Loadtime
["init2_end"] = GetTime()
673 function QuestHelper
:OnEvent(event
)
674 local tstart
= GetTime()
677 if event == "GOSSIP_SHOW" then
678 local name, id = UnitName("npc"), self:GetUnitID("npc")
680 self:GetObjective("monster", name).o.id = id
681 --self:TextOut("NPC: "..name.." = "..id)
685 --[[if event == "PLAYER_TARGET_CHANGED" then
686 local name, id = UnitName("target"), self:GetUnitID("target")
688 self:GetObjective("monster", name).o.id = id
689 --self:TextOut("Target: "..name.." = "..id)
692 if UnitExists("target") and UnitIsVisible("target") and UnitCreatureType("target") ~= "Critter" and not UnitIsPlayer("target") and not UnitPlayerControlled("target") then
693 local index, x, y = self:UnitPosition("target")
695 if index then -- Might not have a position if inside an instance.
698 -- Modify the weight based on how far they are from us.
699 -- We don't know the exact location (using our own location), so the farther, the less sure we are that it's correct.
700 if CheckInteractDistance("target", 3) then w = 1
701 elseif CheckInteractDistance("target", 2) then w = 0.89
702 elseif CheckInteractDistance("target", 1) or CheckInteractDistance("target", 4) then w = 0.33 end
704 local monster_objective = self:GetObjective("monster", UnitName("target"))
705 self:AppendObjectivePosition(monster_objective, index, x, y, w)
707 monster_objective.o.faction = (UnitFactionGroup("target") == "Alliance" and 1) or
708 (UnitFactionGroup("target") == "Horde" and 2) or nil
710 local level = UnitLevel("target")
711 if level and level >= 1 then
712 local w = monster_objective.o.levelw or 0
713 monster_objective.o.level = ((monster_objective.o.level or 0)*w+level)/(w+1)
714 monster_objective.o.levelw = w+1
720 --[[if event == "LOOT_OPENED" then
721 local target = UnitName("target")
722 if target and UnitIsDead("target") and UnitCreatureType("target") ~= "Critter" and not UnitIsPlayer("target") and not UnitPlayerControlled("target") then
723 local index, x, y = self:UnitPosition("target")
725 local monster_objective = self:GetObjective("monster", target)
726 monster_objective.o.looted = (monster_objective.o.looted or 0) + 1
728 if index then -- Might not have a position if inside an instance.
729 self:AppendObjectivePosition(monster_objective, index, x, y)
732 for i = 1, GetNumLootItems() do
733 local icon, name, number, rarity = GetLootSlotInfo(i)
735 if number and number >= 1 then
736 self:AppendItemObjectiveDrop(self:GetObjective("item", name), name, target, number)
738 local total = (name:match(COPPER_AMOUNT:gsub("%%d", "%(%%d+%)")) or 0) +
739 (name:match(SILVER_AMOUNT:gsub("%%d", "%(%%d+%)")) or 0) * 100 +
740 (name:match(GOLD_AMOUNT:gsub("%%d", "%(%%d+%)")) or 0) * 10000
743 self:AppendObjectiveDrop(self:GetObjective("item", "money"), target, total)
749 local container = nil
751 -- Go through the players inventory and look for a locked item, we're probably looting it.
752 for bag = 0,NUM_BAG_SLOTS do
753 for slot = 1,GetContainerNumSlots(bag) do
754 local link = GetContainerItemLink(bag, slot)
755 if link and select(3, GetContainerItemInfo(bag, slot)) then
756 if container == nil then
757 -- Found a locked item and haven't previously assigned to container, assign its name, or false if we fail to parse it.
758 container = select(3, string.find(link, "|h%[(.+)%]|h|r")) or false
760 -- Already tried to assign to a container. If there are multiple locked items, we give up.
768 local container_objective = self:GetObjective("item", container)
769 container_objective.o.opened = (container_objective.o.opened or 0) + 1
771 for i = 1, GetNumLootItems() do
772 local icon, name, number, rarity = GetLootSlotInfo(i)
773 if name and number >= 1 then
774 self:AppendItemObjectiveContainer(self:GetObjective("item", name), container, number)
778 -- No idea where the items came from.
779 local index, x, y = self:PlayerPosition()
782 for i = 1, GetNumLootItems() do
783 local icon, name, number, rarity = GetLootSlotInfo(i)
784 if name and number >= 1 then
785 self:AppendItemObjectivePosition(self:GetObjective("item", name), name, index, x, y)
793 --[[if event == "CHAT_MSG_SYSTEM" then
794 local home_name = self:convertPattern(ERR_DEATHBIND_SUCCESS_S)(arg1)
797 self:TextOut(QHText("HOME_CHANGED"))
798 self:TextOut(QHText("WILL_RESET_PATH"))
800 local home = QuestHelper_Home
803 QuestHelper_Home = home
806 home[1], home[2], home[3], home[4] = self.i, self.x, self.y, home_name
807 self.defered_graph_reset = true
815 --[[if event == "QUEST_DETAIL" then
816 if not self.quest_giver then self.quest_giver = {} end
817 local npc = UnitName("npc")
819 -- Some NPCs aren't actually creatures, and so their positions might not be marked by PLAYER_TARGET_CHANGED.
820 local index, x, y = self:UnitPosition("npc")
822 if index then -- Might not have a position if inside an instance.
823 local npc_objective = self:GetObjective("monster", npc)
824 self:AppendObjectivePosition(npc_objective, index, x, y)
825 self.quest_giver[GetTitleText()] = npc
830 --[[if event == "QUEST_COMPLETE" or event == "QUEST_PROGRESS" then
831 local quest = GetTitleText()
833 local level, hash = self:GetQuestLevel(quest)
834 if not level or level < 1 then
835 --self:TextOut("Don't know quest level for ".. quest.."!")
838 local q = self:GetQuest(quest, level, hash)
844 local unit = UnitName("npc")
849 -- Some NPCs aren't actually creatures, and so their positions might not be marked by PLAYER_TARGET_CHANGED.
850 local index, x, y = self:UnitPosition("npc")
851 if index then -- Might not have a position if inside an instance.
852 local npc_objective = self:GetObjective("monster", unit)
853 self:AppendObjectivePosition(npc_objective, index, x, y)
855 elseif not q.o.finish then
856 local index, x, y = self:PlayerPosition()
857 if index then -- Might not have a position if inside an instance.
858 self:AppendObjectivePosition(q, index, x, y)
864 --[[if event == "MERCHANT_SHOW" then
865 local npc_name = UnitName("npc")
867 local npc_objective = self:GetObjective("monster", npc_name)
870 local item_name = GetMerchantItemInfo(index)
873 local item_objective = self:GetObjective("item", item_name)
874 if not item_objective.o.vendor then
875 item_objective.o.vendor = {npc_name}
878 for i, vendor in ipairs(item_objective.o.vendor) do
879 if npc_name == vendor then
885 table.insert(item_objective.o.vendor, npc_name)
895 if event
== "TAXIMAP_OPENED" then
899 --[[if event == "PLAYER_CONTROL_GAINED" then
900 interruptcount = interruptcount + 1
903 --[[if event == "BAG_UPDATE" then
904 for slot = 1,GetContainerNumSlots(arg1) do
905 local link = GetContainerItemLink(arg1, slot)
907 local id, name = select(3, string.find(link, "|Hitem:(%d+):.-|h%[(.-)%]|h"))
909 self:GetObjective("item", name).o.id = tonumber(id)
917 if event
== "ZONE_CHANGED" or event
== "ZONE_CHANGED_INDOORS" or event
== "ZONE_CHANGED_NEW_AREA" then
918 QH_Route_Filter_Rescan()
921 QH_Timeslice_Increment(GetTime() - tstart
, "event")
924 local map_shown_decay
= 0
925 local delayed_action
= 100
926 --local update_count = 0
930 QH_OnUpdate_High(function ()
931 local self
= QuestHelper
-- hoorj
932 local tstart
= GetTime()
935 if not QuestHelper_Loadtime
["onupdate"] then QuestHelper_Loadtime
["onupdate"] = GetTime() end
937 if false and frams
== 60 then
939 This is a |cffff8000beta of QuestHelper|r. Be warned: It may crash. It may lock up. It may give bad advice. It may spew errors. It shouldn't spam people, delete your hard-won epics, or make your computer catch on fire, but technically I'm giving no guarantees. |cffff8000If you want a polished, functioning product, close WoW, download the official QH release from curse.com, and use that.|r
941 Known bugs and issues include:
943 |cff40bbffNo support for "/qh find"|r
945 |cff40bbffNo support for in-party quest synchronization|r
947 These may not be fixed before the official 1.0 release - I'm hoping to get them all finished up in time for 1.1.
949 If you encounter any issue besides the ones listed here, please please please report it, if you're reading this you know how to get in contact with me anyway.
951 Thanks for testing!]], "QuestHelper " .. version_string
, 500, 20, 10)
954 --if frams == 5000 then please_submit_enabled = false end -- TOOK TOO LONG >:(
955 if please_submit_enabled
and startup_time
and startup_time
+ 10 < GetTime() then
956 QuestHelper
:TextOut(QHText("PLEASE_SUBMIT"))
958 please_submit_enabled
= false
960 QHUpdateNagTick() -- These probably shouldn't be in OnUpdate. Eventually I'll move them somewhere cleaner.
962 if init_cartographer_later
and Cartographer_Waypoints
then -- there has to be a better way to do this
963 init_cartographer_later
= false
964 if QuestHelper_Pref
.cart_wp_new
then
965 self
:EnableCartographer()
969 if not ontaxi
and UnitOnTaxi("player") then
972 elseif ontaxi
and not UnitOnTaxi("player") then
973 self
:flightEnded(interruptcount
> 1)
975 ontaxi
= UnitOnTaxi("player")
977 -- For now I'm ripping out the update_count code
978 --update_count = update_count - 1
979 --if update_count <= 0 then
981 -- Reset the update count for next time around; this will make sure the body executes every time
982 -- when perf_scale_2 >= 1, and down to 1 in 10 iterations when perf_scale_2 < 1, or when hidden.
983 --update_count = update_count + (QuestHelper_Pref.hide and 10 or 1/QuestHelper_Pref.perf_scale_2)
985 --if update_count < 0 then
986 -- Make sure the count doesn't go perpetually negative; don't know what will happen if it underflows.
990 if self
.Astrolabe
.WorldMapVisible
then
991 -- We won't trust that the zone returned by Astrolabe is correct until map_shown_decay is 0.
993 elseif map_shown_decay
> 0 then
994 map_shown_decay
= map_shown_decay
- 1
996 --SetMapToCurrentZone() -- not sure why this existed
999 --[[delayed_action = delayed_action - 1
1000 if delayed_action <= 0 then
1001 delayed_action = 100
1002 self:HandlePartyChange()
1005 local nc
, nz
, nx
, ny
= self
.Astrolabe
:GetCurrentPlayerPosition()
1008 if nc
and nc
~= -1 then -- We just want the raw data here, before we've done anything clever.
1009 tc
, tx
, ty
= self
.Astrolabe
:GetAbsoluteContinentPosition(nc
, nz
, nx
, ny
)
1010 QuestHelper
: Assert(tc
and tx
and ty
) -- is it true? nobody knows! :D
1013 if nc
and nc
== self
.c
and map_shown_decay
> 0 and self
.z
> 0 and self
.z
~= nz
then
1014 -- There's a chance Astrolable will return the wrong zone if you're messing with the world map, if you can
1015 -- be seen in that zone but aren't in it.
1016 local nnx
, nny
= self
.Astrolabe
:TranslateWorldMapPosition(nc
, nz
, nx
, ny
, nc
, self
.z
)
1017 if nnx
> 0 and nny
> 0 and nnx
< 1 and nny
< 1 then
1018 nz
, nx
, ny
= self
.z
, nnx
, nny
1022 if nc
and nc
> 0 and nz
== 0 and nc
== self
.c
and self
.z
> 0 then
1023 nx
, ny
= self
.Astrolabe
:TranslateWorldMapPosition(nc
, nz
, nx
, ny
, nc
, self
.z
)
1024 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
1027 nc
, nz
, nx
, ny
= nil, nil, nil, nil
1031 if nc
and nz
> 0 and QuestHelper_IndexLookup
[nc
] then -- QuestHelper_IndexLookup is only initialized after we've finished the preinit step
1032 self
.c
, self
.z
, self
.x
, self
.y
= nc
, nz
, nx
, ny
1033 local upd_zone
= false
1034 if self
.i
~= QuestHelper_IndexLookup
[nc
][nz
] then upd_zone
= true end
1035 self
.i
= QuestHelper_IndexLookup
[nc
][nz
]
1036 if upd_zone
then QH_Route_Filter_Rescan("filter_zone") end
1039 if nc
and nz
and nx
and ny
and tc
and tx
and ty
then
1040 self
.collect_rc
, self
.collect_rz
, self
.collect_rx
, self
.collect_ry
= nc
, nz
, nx
, ny
1041 self
.collect_ac
, self
.collect_ax
, self
.collect_ay
= tc
, tx
, ty
1042 self
.collect_delayed
= false
1044 local ibi
= self
.InBrokenInstance
1045 if nc
< -77 then self
.InBrokenInstance
= true else self
.InBrokenInstance
= false end
1047 if ibi
and not self
.InBrokenInstance
then self
.minimap_marker
:OnUpdate(0) end -- poke
1049 self
.collect_delayed
= true
1050 self
.InBrokenInstance
= true
1053 if not UnitOnTaxi("player") and not UnitIsDeadOrGhost("player") then
1054 QuestHelper
.routing_ac
, QuestHelper
.routing_ax
, QuestHelper
.routing_ay
, QuestHelper
.routing_c
, QuestHelper
.routing_z
= QuestHelper
.collect_ac
, QuestHelper
.collect_ax
, QuestHelper
.collect_ay
, QuestHelper
.c
, QuestHelper
.z
1057 QH_Timeslice_Toggle("routing", not not self
.c
)
1059 self
:PumpCommMessages()
1063 -- 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, or -77 for the DK starting zone) and x,y are the coordinates within that continent.
1064 -- 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?
1065 function QuestHelper
:Location_RawRetrieve()
1066 return self
.collect_delayed
, self
.collect_rc
, self
.collect_rz
, self
.collect_rx
, self
.collect_ry
1068 function QuestHelper
:Location_AbsoluteRetrieve()
1069 return self
.collect_delayed
, self
.collect_ac
, self
.collect_ax
, self
.collect_ay
1072 --QH_Hook(QuestHelper, "OnEvent", QuestHelper.OnEvent)