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 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,
29 track_minimized
=false,
45 tomtom_wp_new
= false,
50 metric
= (QuestHelper_Locale
~= "enUS" and QuestHelper_Locale
~= "esMX"),
52 locale
= GetLocale(), -- This variable is used for display purposes, and has nothing to do with the collected data.
53 perf_scale_2
= 1, -- How much background processing can the current machine handle? Higher means more load, lower means better performance.
54 perfload_scale
= 1, -- Performance scale to use on startup
59 -- 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.
60 setmetatable(QuestHelper_Pref
, {__index
=QuestHelper_DefaultPref
})
62 QuestHelper_FlightInstructors
= {}
63 QuestHelper_FlightLinks
= {}
64 QuestHelper_FlightRoutes
= {}
65 QuestHelper_KnownFlightRoutes
= {}
66 QuestHelper_SeenRealms
= {}
68 QuestHelper
.tooltip
= CreateFrame("GameTooltip", "QuestHelperTooltip", nil, "GameTooltipTemplate")
69 QuestHelper
.objective_objects
= {}
70 QuestHelper
.user_objectives
= {}
71 QuestHelper
.quest_objects
= {}
72 QuestHelper
.player_level
= 1
73 QuestHelper
.locale
= QuestHelper_Locale
75 QuestHelper
.faction
= (UnitFactionGroup("player") == "Alliance" and 1) or
76 (UnitFactionGroup("player") == "Horde" and 2)
78 assert(QuestHelper
.faction
)
80 QuestHelper
.font
= {serif
=GameFontNormal
:GetFont(), sans
=ChatFontNormal
:GetFont(), fancy
=QuestTitleFont
:GetFont()}
82 function QuestHelper
:GetFontPath(list_string
, font
)
84 for name
in string.gmatch(list_string
, "[^;]+") do
85 if font
:SetFont(name
, 10) then
87 elseif font
:SetFont("Interface\\AddOns\\QuestHelper\\Fonts\\"..name
, 10) then
88 return "Interface\\AddOns\\QuestHelper\\Fonts\\"..name
94 function QuestHelper
:SetLocaleFonts()
99 local font
= self
:CreateText(self
)
101 if QuestHelper_Locale
~= QuestHelper_Pref
.locale
then
102 -- Only use alternate fonts if using a language the client wasn't intended for.
103 local replacements
= QuestHelper_SubstituteFonts
[QuestHelper_Pref
.locale
]
105 self
.font
.sans
= self
:GetFontPath(replacements
.sans
, font
)
106 self
.font
.serif
= self
:GetFontPath(replacements
.serif
, font
)
107 self
.font
.fancy
= self
:GetFontPath(replacements
.fancy
, font
)
111 self
.font
.sans
= self
.font
.sans
or self
:GetFontPath(QuestHelper_Pref
.locale
.."_sans.ttf", font
)
112 self
.font
.serif
= self
.font
.serif
or self
:GetFontPath(QuestHelper_Pref
.locale
.."_serif.ttf", font
) or self
.font
.sans
113 self
.font
.fancy
= self
.font
.fancy
or self
:GetFontPath(QuestHelper_Pref
.locale
.."_fancy.ttf", font
) or self
.font
.serif
115 self
:ReleaseText(font
)
117 self
.font
.sans
= self
.font
.sans
or ChatFontNormal
:GetFont()
118 self
.font
.serif
= self
.font
.serif
or GameFontNormal
:GetFont()
119 self
.font
.fancy
= self
.font
.fancy
or QuestTitleFont
:GetFont()
121 -- Need to change the font of the chat frame, for any messages that QuestHelper displays.
122 -- This should do nothing if not using an alternate font.
123 DEFAULT_CHAT_FRAME
:SetFont(self
.font
.sans
, select(2, DEFAULT_CHAT_FRAME
:GetFont()))
126 QuestHelper
.route
= {}
127 QuestHelper
.to_add
= {}
128 QuestHelper
.to_remove
= {}
129 QuestHelper
.quest_log
= {}
130 QuestHelper
.pos
= {nil, {}, 0, 0, 1, "You are here.", 0}
131 QuestHelper
.sharing
= false -- Will be set to true when sharing with at least one user.
133 function QuestHelper
.tooltip
:GetPrevLines() -- Just a helper to make life easier.
134 local last
= self
:NumLines()
135 local name
= self
:GetName()
136 return _G
[name
.."TextLeft"..last
], _G
[name
.."TextRight"..last
]
139 function QuestHelper
:SetTargetLocation(i
, x
, y
, toffset
)
140 -- Informs QuestHelper that you're going to be at some location in toffset seconds.
141 local c
, z
= unpack(QuestHelper_ZoneLookup
[i
])
143 self
.target
= self
:CreateTable()
144 self
.target
[2] = self
:CreateTable()
146 self
.target_time
= time()+(toffset
or 0)
148 x
, y
= self
.Astrolabe
:TranslateWorldMapPosition(c
, z
, x
, y
, c
, 0)
149 self
.target
[1] = self
.zone_nodes
[i
]
150 self
.target
[3] = x
* self
.continent_scales_x
[c
]
151 self
.target
[4] = y
* self
.continent_scales_y
[c
]
153 self
:SetTargetLocationRecalculate()
156 function QuestHelper
:SetTargetLocationRecalculate()
158 for i
, n
in ipairs(self
.target
[1]) do
159 local a
, b
= n
.x
-self
.target
[3], n
.y
-self
.target
[4]
160 self
.target
[2][i
] = math
.sqrt(a
*a
+b
*b
)
165 function QuestHelper
:UnsetTargetLocation()
166 -- Unsets the target set above.
168 self
:ReleaseTable(self
.target
[2])
169 self
:ReleaseTable(self
.target
)
171 self
.target_time
= nil
175 local interruptcount
= 0 -- counts how many "played gained control" messages we recieve, used for flight paths
176 local init_cartographer_later
= false
180 local please_submit_enabled
= true
181 local please_submit_initted
= false
183 QH_Event("ADDON_LOADED", function (addonid
)
184 if addonid
~= "QuestHelper" then return end
185 local self
= QuestHelper
-- whee hack hack hack
187 QuestHelper_Loadtime
["init_start"] = GetTime()
189 -- Use DefaultPref as fallback for unset preference keys.
190 setmetatable(QuestHelper_Pref
, {__index
=QuestHelper_DefaultPref
})
192 local file_problem_version
= false
194 local expected_version
= GetAddOnMetadata("QuestHelper", "Version")
196 local expected_files
=
198 ["bst_pre.lua"] = true,
199 ["bst_post.lua"] = true,
200 ["bst_astrolabe.lua"] = true,
201 ["bst_ctl.lua"] = true,
202 ["bst_libaboutpanel.lua"] = true,
204 ["manager_event.lua"] = true,
206 ["upgrade.lua"] = true,
208 ["recycle.lua"] = true,
209 ["objective.lua"] = true,
210 ["quest.lua"] = true,
211 ["utility.lua"] = true,
212 ["dodads.lua"] = true,
213 ["dodads_triangles.lua"] = true,
214 ["teleport.lua"] = true,
215 ["pathfinding.lua"] = true,
216 ["routing.lua"] = true,
217 ["custom.lua"] = true,
221 ["mapbutton.lua"] = true,
223 ["pattern.lua"] = true,
224 ["flightpath.lua"] = true,
225 ["tracker.lua"] = true,
226 ["objtips.lua"] = true,
227 ["cartographer.lua"] = true,
228 ["cartographer_is_terrible.lua"] = true,
229 ["tomtom.lua"] = true,
230 ["textviewer.lua"] = true,
231 ["error.lua"] = true,
232 ["timeslice.lua"] = true,
235 ["tooltip.lua"] = true,
236 ["arrow.lua"] = true,
238 ["static.lua"] = true,
239 ["static_1.lua"] = true,
240 ["static_2.lua"] = true,
241 ["static_deDE.lua"] = true,
242 ["static_deDE_1.lua"] = true,
243 ["static_deDE_2.lua"] = true,
244 ["static_enUS.lua"] = true,
245 ["static_enUS_1.lua"] = true,
246 ["static_enUS_2.lua"] = true,
247 ["static_esES.lua"] = true,
248 ["static_esES_1.lua"] = true,
249 ["static_esES_2.lua"] = true,
250 ["static_esMX.lua"] = true,
251 ["static_esMX_1.lua"] = true,
252 ["static_esMX_2.lua"] = true,
253 ["static_frFR.lua"] = true,
254 ["static_frFR_1.lua"] = true,
255 ["static_frFR_2.lua"] = true,
256 ["static_koKR.lua"] = true,
257 ["static_koKR_1.lua"] = true,
258 ["static_koKR_2.lua"] = true,
259 ["static_ruRU.lua"] = true,
260 ["static_ruRU_1.lua"] = true,
261 ["static_ruRU_2.lua"] = true,
262 ["static_zhTW.lua"] = true,
263 ["static_zhTW_1.lua"] = true,
264 ["static_zhTW_2.lua"] = true,
266 ["collect.lua"] = true,
267 ["collect_achievement.lua"] = true,
268 ["collect_lzw.lua"] = true,
269 ["collect_traveled.lua"] = true,
270 ["collect_zone.lua"] = true,
271 ["collect_location.lua"] = true,
272 ["collect_merger.lua"] = true,
273 ["collect_monster.lua"] = true,
274 ["collect_item.lua"] = true,
275 ["collect_object.lua"] = true,
276 ["collect_loot.lua"] = true,
277 ["collect_patterns.lua"] = true,
278 ["collect_flight.lua"] = true,
279 ["collect_util.lua"] = true,
280 ["collect_quest.lua"] = true,
281 ["collect_equip.lua"] = true,
282 ["collect_notifier.lua"] = true,
283 ["collect_bitstream.lua"] = true,
284 ["collect_spec.lua"] = true,
285 ["collect_upgrade.lua"] = true,
286 ["collect_merchant.lua"] = true,
287 ["collect_warp.lua"] = true,
289 ["filter_core.lua"] = true,
290 ["filter_base.lua"] = true,
292 ["routing_debug.lua"] = true,
293 ["routing_loc.lua"] = true,
294 ["routing_route.lua"] = true,
295 ["routing_core.lua"] = true,
296 ["routing_controller.lua"] = true,
297 ["routing_hidden.lua"] = true,
299 ["director_quest.lua"] = true,
300 ["director_achievement.lua"] = true,
302 ["db_get.lua"] = true,
304 ["graph_core.lua"] = true,
305 ["graph_flightpath.lua"] = true,
307 ["AstrolabeQH/Astrolabe.lua"] = true,
308 ["AstrolabeQH/AstrolabeMapMonitor.lua"] = true,
311 local uninstallederr
= ""
313 for file
, version
in pairs(QuestHelper_File
) do
314 if not expected_files
[file
] then
315 local errmsg
= "Unexpected QuestHelper file: "..file
316 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
317 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
318 file_problem_version
= true
319 elseif version
~= expected_version
then
320 local errmsg
= "Wrong version of QuestHelper file: "..file
.." (found '"..version
.."', should be '"..expected_version
.."')"
321 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
322 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
323 if version
~= "Development Version" and expected_version
~= "Development Version" then
324 -- Developers are allowed to mix dev versions with release versions
325 file_problem_version
= true
330 for file
in pairs(expected_files
) do
331 if not QuestHelper_File
[file
] then
332 local errmsg
= "Missing QuestHelper file: "..file
333 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
334 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
335 if not (expected_version
== "Development Version" and file
:match("static.*")) then file_problem_version
= true end
339 -- Don't need this table anymore.
340 QuestHelper_File
= nil
342 if QuestHelper_StaticData
and not QuestHelper_StaticData
[GetLocale()] then
343 local errmsg
= "Static data does not seem to exist"
344 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
346 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
347 file_problem_version
= true
350 if file_problem_version
then
351 QH_fixedmessage(QHText("PLEASE_RESTART"))
352 QuestHelper_ErrorCatcher_ExplicitError(false, "not-installed-properly" .. "\n" .. uninstallederr
)
353 QuestHelper
= nil -- Just in case anybody else is checking for us, we're not home
357 if not GetCategoryList
or not GetQuestLogSpecialItemInfo
or not WatchFrame_RemoveObjectiveHandler
then
358 QH_fixedmessage(QHText("PRIVATE_SERVER"))
359 QuestHelper_ErrorCatcher_ExplicitError(false, "error id cakbep ten T")
364 if not DongleStub
or not QH_Astrolabe_Ready
then
365 QH_fixedmessage(QHText("NOT_UNZIPPED_CORRECTLY"))
366 QuestHelper_ErrorCatcher_ExplicitError(false, "not-unzipped-properly")
367 QuestHelper
= nil -- Just in case anybody else is checking for us, we're not home
371 QuestHelper_ErrorCatcher_CompletelyStarted()
373 if not QuestHelper_StaticData
then
374 -- If there is no static data for some mysterious reason, create an empty table so that
375 -- other parts of the code can carry on as usual, using locally collected data if it exists.
376 QuestHelper_StaticData
= {}
379 QHFormatSetLocale(QuestHelper_Pref
.locale
or GetLocale())
381 if not QuestHelper_UID
then
382 QuestHelper_UID
= self
:CreateUID()
384 QuestHelper_SaveDate
= time()
386 QuestHelper_BuildZoneLookup()
390 if QuestHelper_Locale
~= GetLocale() then
391 self
:TextOut(QHText("LOCALE_ERROR"))
395 if not self
:ZoneSanity() then
396 self
:TextOut(QHFormat("ZONE_LAYOUT_ERROR", expected_version
))
397 QH_fixedmessage(QHFormat("ZONE_LAYOUT_ERROR", expected_version
))
402 QuestHelper_UpgradeDatabase(_G
)
403 QuestHelper_UpgradeComplete()
405 if QuestHelper_IsPolluted(_G
) then
406 self
:TextOut(QHFormat("NAG_POLLUTED"))
407 self
:Purge(nil, true, true)
410 local signature
= expected_version
.. " on " .. GetBuildInfo()
411 QuestHelper_Quests
[signature
] = QuestHelper_Quests
[signature
] or {}
412 QuestHelper_Objectives
[signature
] = QuestHelper_Objectives
[signature
] or {}
413 QuestHelper_FlightInstructors
[signature
] = QuestHelper_FlightInstructors
[signature
] or {}
414 QuestHelper_FlightRoutes
[signature
] = QuestHelper_FlightRoutes
[signature
] or {}
416 QuestHelper_Quests_Local
= QuestHelper_Quests
[signature
]
417 QuestHelper_Objectives_Local
= QuestHelper_Objectives
[signature
]
418 QuestHelper_FlightInstructors_Local
= QuestHelper_FlightInstructors
[signature
]
419 QuestHelper_FlightRoutes_Local
= QuestHelper_FlightRoutes
[signature
]
421 QuestHelper_SeenRealms
[GetRealmName()] = true -- some attempt at tracking private servers
426 self
.player_level
= UnitLevel("player")
428 self
:SetLocaleFonts()
430 if QuestHelper_Pref
.share
and not QuestHelper_Pref
.solo
then
434 if QuestHelper_Pref
.hide
then
435 self
.map_overlay
:Hide()
438 self
:HandlePartyChange()
442 for locale
in pairs(QuestHelper_StaticData
) do
443 if locale
~= self
.locale
then
444 -- Will delete references to locales you don't use.
445 QuestHelper_StaticData
[locale
] = nil
446 _G
["QuestHelper_StaticData_" .. locale
] = nil
450 local static
= QuestHelper_StaticData
[self
.locale
]
453 if static
.flight_instructors
then for faction
in pairs(static
.flight_instructors
) do
454 if faction
~= self
.faction
then
455 -- Will delete references to flight instructors that don't belong to your faction.
456 static
.flight_instructors
[faction
] = nil
460 if static
.quest
then for faction
in pairs(static
.quest
) do
461 if faction
~= self
.faction
then
462 -- Will delete references to quests that don't belong to your faction.
463 static
.quest
[faction
] = nil
468 -- Adding QuestHelper_CharVersion, so I know if I've already converted this characters saved data.
469 if not QuestHelper_CharVersion
then
470 -- Changing per-character flight routes, now only storing the flight points they have,
471 -- will attempt to guess the routes from this.
474 for i
, l
in pairs(QuestHelper_KnownFlightRoutes
) do
475 for key
in pairs(l
) do
480 QuestHelper_KnownFlightRoutes
= routes
482 -- Deleting the player's home again.
483 -- But using the new CharVersion variable I'm adding is cleaner that what I was doing, so I'll go with it.
484 QuestHelper_Home
= nil
485 QuestHelper_CharVersion
= 1
488 if not QuestHelper_Home
then
489 -- Not going to bother complaining about the player's home not being set, uncomment this when the home is used in routing.
490 -- self:TextOut(QHText("HOME_NOT_KNOWN"))
493 if QuestHelper_Pref
.map_button
then
494 QuestHelper
:InitMapButton()
497 if QuestHelper_Pref
.cart_wp_new
then
498 init_cartographer_later
= true
501 if QuestHelper_Pref
.tomtom_wp_new
then
505 self
.tracker
:SetScale(QuestHelper_Pref
.track_scale
)
507 if QuestHelper_Pref
.track
and not QuestHelper_Pref
.hide
then
511 local version
= GetAddOnMetadata("QuestHelper", "Version") or "Unknown"
513 local major
, minor
= (version_string
or ""):match("^(%d+)%.(%d+)")
514 major
, minor
= tonumber(major
), tonumber(minor
)
516 -- For versions before 0.82, we're changing the default level offset to 3.
517 if major
== 0 and minor
and minor
< 82 and QuestHelper_Pref
.level
== 2 then
518 QuestHelper_Pref
.level
= nil
521 -- For versions before 0.84...
522 if major
== 0 and minor
and minor
< 84 then
523 -- remove all keys that match their default setting.
524 for key
, val
in pairs(QuestHelper_DefaultPref
) do
525 if QuestHelper_Pref
[key
] == val
then
526 QuestHelper_Pref
[key
] = nil
531 QH_Hook(self
, "OnUpdate", self
.OnUpdate
)
533 -- Seems to do its own garbage collection pass before fully loading, so I'll just rely on that
534 --collectgarbage("collect") -- Free everything we aren't using.
537 if self.debug_objectives then
538 for name, data in pairs(self.debug_objectives) do
539 self:LoadDebugObjective(name, data)
545 QH_Arrow_SetTextScale()
548 QH_Timeslice_Add(function ()
550 self.Routing:Initialize() -- Set up the routing task
551 end, "init")]] -- FUCK YOU BOXBOT
553 --[[ -- This is just an example of how the WoW profiler biases its profiles heavily.
559 for x = 0, 130000000, 1 do
565 for x = 0, 12000000, 1 do
572 for x = 0, 1200000, 1 do
580 local ta = debugprofilestop()
582 local tb = debugprofilestop()
584 local tc = debugprofilestop()
586 QuestHelper:TextOut(string.format("%d %d %d", ta, tb - ta, tc - tb))
587 QuestHelper:TextOut(string.format("%d %d", GetFunctionCPUUsage(A), GetFunctionCPUUsage(B)))
589 --/script SetCVar("scriptProfile", value)]]
591 LibStub("LibAboutPanelQH").new(nil, "QuestHelper")
593 QuestHelper_Loadtime
["init_end"] = GetTime()
595 QuestHelper
.loading_main
= QuestHelper
.CreateLoadingCounter()
597 QuestHelper
.loading_flightpath
= QuestHelper
.loading_main
:MakeSubcategory(1)
598 QuestHelper
.loading_preroll
= QuestHelper
.loading_main
:MakeSubcategory(1)
600 QH_Event("CHAT_MSG_ADDON", function (...)
601 if arg1
== "QHpr" and arg4
~= UnitName("player") then
602 QH_Questcomm_Msg(arg2
, arg4
)
606 QH_Event({"PARTY_MEMBERS_CHANGED", "UNIT_LEVEL", "RAID_ROSTER_UPDATE"}, function ()
607 QH_Filter_Group_Sync()
608 QH_Route_Filter_Rescan("filter_quest_level")
609 QH_Route_Filter_Rescan("filter_quest_group")
612 QH_Event({"PARTY_MEMBERS_CHANGED", "RAID_ROSTER_UPDATE"}, function ()
616 QH_Event("PLAYER_LEVEL_UP", function ()
617 self
.player_level
= arg1
618 QH_Route_Filter_Rescan("filter_quest_level")
621 QH_Event("TAXIMAP_OPENED", function ()
625 QH_Event({"ZONE_CHANGED", "ZONE_CHANGED_INDOORS", "ZONE_CHANGED_NEW_AREA"}, function()
626 QH_Route_Filter_Rescan()
629 QH_Event("CHAT_MSG_CHANNEL_NOTICE", function()
630 if please_submit_enabled
and not please_submit_initted
then
631 please_submit_enabled
= QHNagInit()
632 startup_time
= GetTime()
633 please_submit_initted
= true
641 function QuestHelper
:OnEvent(event
)
642 local tstart
= GetTime()
645 if event == "GOSSIP_SHOW" then
646 local name, id = UnitName("npc"), self:GetUnitID("npc")
648 self:GetObjective("monster", name).o.id = id
649 --self:TextOut("NPC: "..name.." = "..id)
653 --[[if event == "PLAYER_TARGET_CHANGED" then
654 local name, id = UnitName("target"), self:GetUnitID("target")
656 self:GetObjective("monster", name).o.id = id
657 --self:TextOut("Target: "..name.." = "..id)
660 if UnitExists("target") and UnitIsVisible("target") and UnitCreatureType("target") ~= "Critter" and not UnitIsPlayer("target") and not UnitPlayerControlled("target") then
661 local index, x, y = self:UnitPosition("target")
663 if index then -- Might not have a position if inside an instance.
666 -- Modify the weight based on how far they are from us.
667 -- We don't know the exact location (using our own location), so the farther, the less sure we are that it's correct.
668 if CheckInteractDistance("target", 3) then w = 1
669 elseif CheckInteractDistance("target", 2) then w = 0.89
670 elseif CheckInteractDistance("target", 1) or CheckInteractDistance("target", 4) then w = 0.33 end
672 local monster_objective = self:GetObjective("monster", UnitName("target"))
673 self:AppendObjectivePosition(monster_objective, index, x, y, w)
675 monster_objective.o.faction = (UnitFactionGroup("target") == "Alliance" and 1) or
676 (UnitFactionGroup("target") == "Horde" and 2) or nil
678 local level = UnitLevel("target")
679 if level and level >= 1 then
680 local w = monster_objective.o.levelw or 0
681 monster_objective.o.level = ((monster_objective.o.level or 0)*w+level)/(w+1)
682 monster_objective.o.levelw = w+1
688 --[[if event == "LOOT_OPENED" then
689 local target = UnitName("target")
690 if target and UnitIsDead("target") and UnitCreatureType("target") ~= "Critter" and not UnitIsPlayer("target") and not UnitPlayerControlled("target") then
691 local index, x, y = self:UnitPosition("target")
693 local monster_objective = self:GetObjective("monster", target)
694 monster_objective.o.looted = (monster_objective.o.looted or 0) + 1
696 if index then -- Might not have a position if inside an instance.
697 self:AppendObjectivePosition(monster_objective, index, x, y)
700 for i = 1, GetNumLootItems() do
701 local icon, name, number, rarity = GetLootSlotInfo(i)
703 if number and number >= 1 then
704 self:AppendItemObjectiveDrop(self:GetObjective("item", name), name, target, number)
706 local total = (name:match(COPPER_AMOUNT:gsub("%%d", "%(%%d+%)")) or 0) +
707 (name:match(SILVER_AMOUNT:gsub("%%d", "%(%%d+%)")) or 0) * 100 +
708 (name:match(GOLD_AMOUNT:gsub("%%d", "%(%%d+%)")) or 0) * 10000
711 self:AppendObjectiveDrop(self:GetObjective("item", "money"), target, total)
717 local container = nil
719 -- Go through the players inventory and look for a locked item, we're probably looting it.
720 for bag = 0,NUM_BAG_SLOTS do
721 for slot = 1,GetContainerNumSlots(bag) do
722 local link = GetContainerItemLink(bag, slot)
723 if link and select(3, GetContainerItemInfo(bag, slot)) then
724 if container == nil then
725 -- Found a locked item and haven't previously assigned to container, assign its name, or false if we fail to parse it.
726 container = select(3, string.find(link, "|h%[(.+)%]|h|r")) or false
728 -- Already tried to assign to a container. If there are multiple locked items, we give up.
736 local container_objective = self:GetObjective("item", container)
737 container_objective.o.opened = (container_objective.o.opened or 0) + 1
739 for i = 1, GetNumLootItems() do
740 local icon, name, number, rarity = GetLootSlotInfo(i)
741 if name and number >= 1 then
742 self:AppendItemObjectiveContainer(self:GetObjective("item", name), container, number)
746 -- No idea where the items came from.
747 local index, x, y = self:PlayerPosition()
750 for i = 1, GetNumLootItems() do
751 local icon, name, number, rarity = GetLootSlotInfo(i)
752 if name and number >= 1 then
753 self:AppendItemObjectivePosition(self:GetObjective("item", name), name, index, x, y)
761 --[[if event == "CHAT_MSG_SYSTEM" then
762 local home_name = self:convertPattern(ERR_DEATHBIND_SUCCESS_S)(arg1)
765 self:TextOut(QHText("HOME_CHANGED"))
766 self:TextOut(QHText("WILL_RESET_PATH"))
768 local home = QuestHelper_Home
771 QuestHelper_Home = home
774 home[1], home[2], home[3], home[4] = self.i, self.x, self.y, home_name
775 self.defered_graph_reset = true
783 --[[if event == "QUEST_DETAIL" then
784 if not self.quest_giver then self.quest_giver = {} end
785 local npc = UnitName("npc")
787 -- Some NPCs aren't actually creatures, and so their positions might not be marked by PLAYER_TARGET_CHANGED.
788 local index, x, y = self:UnitPosition("npc")
790 if index then -- Might not have a position if inside an instance.
791 local npc_objective = self:GetObjective("monster", npc)
792 self:AppendObjectivePosition(npc_objective, index, x, y)
793 self.quest_giver[GetTitleText()] = npc
798 --[[if event == "QUEST_COMPLETE" or event == "QUEST_PROGRESS" then
799 local quest = GetTitleText()
801 local level, hash = self:GetQuestLevel(quest)
802 if not level or level < 1 then
803 --self:TextOut("Don't know quest level for ".. quest.."!")
806 local q = self:GetQuest(quest, level, hash)
812 local unit = UnitName("npc")
817 -- Some NPCs aren't actually creatures, and so their positions might not be marked by PLAYER_TARGET_CHANGED.
818 local index, x, y = self:UnitPosition("npc")
819 if index then -- Might not have a position if inside an instance.
820 local npc_objective = self:GetObjective("monster", unit)
821 self:AppendObjectivePosition(npc_objective, index, x, y)
823 elseif not q.o.finish then
824 local index, x, y = self:PlayerPosition()
825 if index then -- Might not have a position if inside an instance.
826 self:AppendObjectivePosition(q, index, x, y)
832 --[[if event == "MERCHANT_SHOW" then
833 local npc_name = UnitName("npc")
835 local npc_objective = self:GetObjective("monster", npc_name)
838 local item_name = GetMerchantItemInfo(index)
841 local item_objective = self:GetObjective("item", item_name)
842 if not item_objective.o.vendor then
843 item_objective.o.vendor = {npc_name}
846 for i, vendor in ipairs(item_objective.o.vendor) do
847 if npc_name == vendor then
853 table.insert(item_objective.o.vendor, npc_name)
863 if event
== "TAXIMAP_OPENED" then
867 --[[if event == "PLAYER_CONTROL_GAINED" then
868 interruptcount = interruptcount + 1
871 --[[if event == "BAG_UPDATE" then
872 for slot = 1,GetContainerNumSlots(arg1) do
873 local link = GetContainerItemLink(arg1, slot)
875 local id, name = select(3, string.find(link, "|Hitem:(%d+):.-|h%[(.-)%]|h"))
877 self:GetObjective("item", name).o.id = tonumber(id)
885 if event
== "ZONE_CHANGED" or event
== "ZONE_CHANGED_INDOORS" or event
== "ZONE_CHANGED_NEW_AREA" then
886 QH_Route_Filter_Rescan()
889 QH_Timeslice_Increment(GetTime() - tstart
, "event")
892 local map_shown_decay
= 0
893 local delayed_action
= 100
894 --local update_count = 0
898 QH_OnUpdate_High(function ()
899 local self
= QuestHelper
-- hoorj
900 local tstart
= GetTime()
903 if not QuestHelper_Loadtime
["onupdate"] then QuestHelper_Loadtime
["onupdate"] = GetTime() end
905 if false and frams
== 60 then
907 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
909 Known bugs and issues include:
911 |cff40bbffNo support for "/qh find"|r
913 |cff40bbffNo support for in-party quest synchronization|r
915 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.
917 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.
919 Thanks for testing!]], "QuestHelper " .. version_string
, 500, 20, 10)
922 --if frams == 5000 then please_submit_enabled = false end -- TOOK TOO LONG >:(
923 if please_submit_enabled
and startup_time
and startup_time
+ 10 < GetTime() then
924 QuestHelper
:TextOut(QHText("PLEASE_SUBMIT"))
926 please_submit_enabled
= false
928 QHUpdateNagTick() -- These probably shouldn't be in OnUpdate. Eventually I'll move them somewhere cleaner.
930 if init_cartographer_later
and Cartographer_Waypoints
then -- there has to be a better way to do this
931 init_cartographer_later
= false
932 if QuestHelper_Pref
.cart_wp_new
then
933 self
:EnableCartographer()
937 if not ontaxi
and UnitOnTaxi("player") then
940 elseif ontaxi
and not UnitOnTaxi("player") then
941 self
:flightEnded(interruptcount
> 1)
943 ontaxi
= UnitOnTaxi("player")
945 -- For now I'm ripping out the update_count code
946 --update_count = update_count - 1
947 --if update_count <= 0 then
949 -- Reset the update count for next time around; this will make sure the body executes every time
950 -- when perf_scale_2 >= 1, and down to 1 in 10 iterations when perf_scale_2 < 1, or when hidden.
951 --update_count = update_count + (QuestHelper_Pref.hide and 10 or 1/QuestHelper_Pref.perf_scale_2)
953 --if update_count < 0 then
954 -- Make sure the count doesn't go perpetually negative; don't know what will happen if it underflows.
958 if self
.Astrolabe
.WorldMapVisible
then
959 -- We won't trust that the zone returned by Astrolabe is correct until map_shown_decay is 0.
961 elseif map_shown_decay
> 0 then
962 map_shown_decay
= map_shown_decay
- 1
964 --SetMapToCurrentZone() -- not sure why this existed
967 --[[delayed_action = delayed_action - 1
968 if delayed_action <= 0 then
970 self:HandlePartyChange()
973 local nc
, nz
, nx
, ny
= self
.Astrolabe
:GetCurrentPlayerPosition()
976 if nc
and nc
~= -1 then -- We just want the raw data here, before we've done anything clever.
977 tc
, tx
, ty
= self
.Astrolabe
:GetAbsoluteContinentPosition(nc
, nz
, nx
, ny
)
978 QuestHelper
: Assert(tc
and tx
and ty
) -- is it true? nobody knows! :D
981 if nc
and nc
== self
.c
and map_shown_decay
> 0 and self
.z
> 0 and self
.z
~= nz
then
982 -- There's a chance Astrolable will return the wrong zone if you're messing with the world map, if you can
983 -- be seen in that zone but aren't in it.
984 local nnx
, nny
= self
.Astrolabe
:TranslateWorldMapPosition(nc
, nz
, nx
, ny
, nc
, self
.z
)
985 if nnx
> 0 and nny
> 0 and nnx
< 1 and nny
< 1 then
986 nz
, nx
, ny
= self
.z
, nnx
, nny
990 if nc
and nc
> 0 and nz
== 0 and nc
== self
.c
and self
.z
> 0 then
991 nx
, ny
= self
.Astrolabe
:TranslateWorldMapPosition(nc
, nz
, nx
, ny
, nc
, self
.z
)
992 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
995 nc
, nz
, nx
, ny
= nil, nil, nil, nil
999 if nc
and nz
> 0 then
1000 self
.c
, self
.z
, self
.x
, self
.y
= nc
, nz
, nx
, ny
1001 local upd_zone
= false
1002 if self
.i
~= QuestHelper_IndexLookup
[nc
][nz
] then upd_zone
= true end
1003 self
.i
= QuestHelper_IndexLookup
[nc
][nz
]
1004 if upd_zone
then QH_Route_Filter_Rescan("filter_zone") end
1007 if nc
and nz
and nx
and ny
and tc
and tx
and ty
then
1008 self
.collect_rc
, self
.collect_rz
, self
.collect_rx
, self
.collect_ry
= nc
, nz
, nx
, ny
1009 self
.collect_ac
, self
.collect_ax
, self
.collect_ay
= tc
, tx
, ty
1010 self
.collect_delayed
= false
1012 local ibi
= self
.InBrokenInstance
1013 if nc
< -77 then self
.InBrokenInstance
= true else self
.InBrokenInstance
= false end
1015 if ibi
and not self
.InBrokenInstance
then self
.minimap_marker
:OnUpdate(0) end -- poke
1017 self
.collect_delayed
= true
1018 self
.InBrokenInstance
= true
1021 if not UnitOnTaxi("player") and not UnitIsDeadOrGhost("player") then
1022 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
1025 QH_Timeslice_Toggle("routing", not not self
.c
)
1027 self
:PumpCommMessages()
1031 -- 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.
1032 -- 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?
1033 function QuestHelper
:Location_RawRetrieve()
1034 return self
.collect_delayed
, self
.collect_rc
, self
.collect_rz
, self
.collect_rx
, self
.collect_ry
1036 function QuestHelper
:Location_AbsoluteRetrieve()
1037 return self
.collect_delayed
, self
.collect_ac
, self
.collect_ax
, self
.collect_ay
1040 --QH_Hook(QuestHelper, "OnEvent", QuestHelper.OnEvent)