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
60 -- 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.
61 setmetatable(QuestHelper_Pref
, {__index
=QuestHelper_DefaultPref
})
63 QuestHelper_FlightInstructors
= {}
64 QuestHelper_FlightLinks
= {}
65 QuestHelper_FlightRoutes
= {}
66 QuestHelper_KnownFlightRoutes
= {}
67 QuestHelper_SeenRealms
= {}
69 QuestHelper
.tooltip
= CreateFrame("GameTooltip", "QuestHelperTooltip", nil, "GameTooltipTemplate")
70 QuestHelper
.objective_objects
= {}
71 QuestHelper
.user_objectives
= {}
72 QuestHelper
.quest_objects
= {}
73 QuestHelper
.player_level
= 1
74 QuestHelper
.locale
= QuestHelper_Locale
76 QuestHelper
.faction
= (UnitFactionGroup("player") == "Alliance" and 1) or
77 (UnitFactionGroup("player") == "Horde" and 2)
79 assert(QuestHelper
.faction
)
81 QuestHelper
.font
= {serif
=GameFontNormal
:GetFont(), sans
=ChatFontNormal
:GetFont(), fancy
=QuestTitleFont
:GetFont()}
83 function QuestHelper
:GetFontPath(list_string
, font
)
85 for name
in string.gmatch(list_string
, "[^;]+") do
86 if font
:SetFont(name
, 10) then
88 elseif font
:SetFont("Interface\\AddOns\\QuestHelper\\Fonts\\"..name
, 10) then
89 return "Interface\\AddOns\\QuestHelper\\Fonts\\"..name
95 function QuestHelper
:SetLocaleFonts()
100 local font
= self
:CreateText(self
)
102 if QuestHelper_Locale
~= QuestHelper_Pref
.locale
then
103 -- Only use alternate fonts if using a language the client wasn't intended for.
104 local replacements
= QuestHelper_SubstituteFonts
[QuestHelper_Pref
.locale
]
106 self
.font
.sans
= self
:GetFontPath(replacements
.sans
, font
)
107 self
.font
.serif
= self
:GetFontPath(replacements
.serif
, font
)
108 self
.font
.fancy
= self
:GetFontPath(replacements
.fancy
, font
)
112 self
.font
.sans
= self
.font
.sans
or self
:GetFontPath(QuestHelper_Pref
.locale
.."_sans.ttf", font
)
113 self
.font
.serif
= self
.font
.serif
or self
:GetFontPath(QuestHelper_Pref
.locale
.."_serif.ttf", font
) or self
.font
.sans
114 self
.font
.fancy
= self
.font
.fancy
or self
:GetFontPath(QuestHelper_Pref
.locale
.."_fancy.ttf", font
) or self
.font
.serif
116 self
:ReleaseText(font
)
118 self
.font
.sans
= self
.font
.sans
or ChatFontNormal
:GetFont()
119 self
.font
.serif
= self
.font
.serif
or GameFontNormal
:GetFont()
120 self
.font
.fancy
= self
.font
.fancy
or QuestTitleFont
:GetFont()
122 -- Need to change the font of the chat frame, for any messages that QuestHelper displays.
123 -- This should do nothing if not using an alternate font.
124 DEFAULT_CHAT_FRAME
:SetFont(self
.font
.sans
, select(2, DEFAULT_CHAT_FRAME
:GetFont()))
127 QuestHelper
.route
= {}
128 QuestHelper
.to_add
= {}
129 QuestHelper
.to_remove
= {}
130 QuestHelper
.quest_log
= {}
131 QuestHelper
.pos
= {nil, {}, 0, 0, 1, "You are here.", 0}
132 QuestHelper
.sharing
= false -- Will be set to true when sharing with at least one user.
134 function QuestHelper
.tooltip
:GetPrevLines() -- Just a helper to make life easier.
135 local last
= self
:NumLines()
136 local name
= self
:GetName()
137 return _G
[name
.."TextLeft"..last
], _G
[name
.."TextRight"..last
]
140 function QuestHelper
:SetTargetLocation(i
, x
, y
, toffset
)
141 -- Informs QuestHelper that you're going to be at some location in toffset seconds.
142 local c
, z
= unpack(QuestHelper_ZoneLookup
[i
])
144 self
.target
= self
:CreateTable()
145 self
.target
[2] = self
:CreateTable()
147 self
.target_time
= time()+(toffset
or 0)
149 x
, y
= self
.Astrolabe
:TranslateWorldMapPosition(c
, z
, x
, y
, c
, 0)
150 self
.target
[1] = self
.zone_nodes
[i
]
151 self
.target
[3] = x
* self
.continent_scales_x
[c
]
152 self
.target
[4] = y
* self
.continent_scales_y
[c
]
154 self
:SetTargetLocationRecalculate()
157 function QuestHelper
:SetTargetLocationRecalculate()
159 for i
, n
in ipairs(self
.target
[1]) do
160 local a
, b
= n
.x
-self
.target
[3], n
.y
-self
.target
[4]
161 self
.target
[2][i
] = math
.sqrt(a
*a
+b
*b
)
166 function QuestHelper
:UnsetTargetLocation()
167 -- Unsets the target set above.
169 self
:ReleaseTable(self
.target
[2])
170 self
:ReleaseTable(self
.target
)
172 self
.target_time
= nil
176 local interruptcount
= 0 -- counts how many "played gained control" messages we recieve, used for flight paths
177 local init_cartographer_later
= false
181 local please_submit_enabled
= true
182 local please_submit_initted
= false
184 QH_Event("ADDON_LOADED", function (addonid
)
185 if addonid
~= "QuestHelper" then return end
186 local self
= QuestHelper
-- whee hack hack hack
188 QuestHelper_Loadtime
["init_start"] = GetTime()
190 -- Use DefaultPref as fallback for unset preference keys.
191 setmetatable(QuestHelper_Pref
, {__index
=QuestHelper_DefaultPref
})
193 local file_problem_version
= false
195 local expected_version
= GetAddOnMetadata("QuestHelper", "Version")
197 local expected_files
=
199 ["bst_pre.lua"] = true,
200 ["bst_post.lua"] = true,
201 ["bst_astrolabe.lua"] = true,
202 ["bst_ctl.lua"] = true,
203 ["bst_libaboutpanel.lua"] = true,
205 ["manager_event.lua"] = true,
207 ["upgrade.lua"] = true,
209 ["recycle.lua"] = true,
210 ["objective.lua"] = true,
211 ["quest.lua"] = true,
212 ["utility.lua"] = true,
213 ["dodads.lua"] = true,
214 ["dodads_triangles.lua"] = true,
215 ["teleport.lua"] = true,
216 ["pathfinding.lua"] = true,
217 ["routing.lua"] = true,
218 ["custom.lua"] = true,
222 ["mapbutton.lua"] = true,
224 ["pattern.lua"] = true,
225 ["flightpath.lua"] = true,
226 ["tracker.lua"] = true,
227 ["objtips.lua"] = true,
228 ["cartographer.lua"] = true,
229 ["cartographer_is_terrible.lua"] = true,
230 ["tomtom.lua"] = true,
231 ["textviewer.lua"] = true,
232 ["error.lua"] = true,
233 ["timeslice.lua"] = true,
236 ["tooltip.lua"] = true,
237 ["arrow.lua"] = true,
239 ["static.lua"] = true,
240 ["static_1.lua"] = true,
241 ["static_2.lua"] = true,
242 ["static_deDE.lua"] = true,
243 ["static_deDE_1.lua"] = true,
244 ["static_deDE_2.lua"] = true,
245 ["static_enUS.lua"] = true,
246 ["static_enUS_1.lua"] = true,
247 ["static_enUS_2.lua"] = true,
248 ["static_esES.lua"] = true,
249 ["static_esES_1.lua"] = true,
250 ["static_esES_2.lua"] = true,
251 ["static_esMX.lua"] = true,
252 ["static_esMX_1.lua"] = true,
253 ["static_esMX_2.lua"] = true,
254 ["static_frFR.lua"] = true,
255 ["static_frFR_1.lua"] = true,
256 ["static_frFR_2.lua"] = true,
257 ["static_koKR.lua"] = true,
258 ["static_koKR_1.lua"] = true,
259 ["static_koKR_2.lua"] = true,
260 ["static_ruRU.lua"] = true,
261 ["static_ruRU_1.lua"] = true,
262 ["static_ruRU_2.lua"] = true,
263 ["static_zhTW.lua"] = true,
264 ["static_zhTW_1.lua"] = true,
265 ["static_zhTW_2.lua"] = true,
267 ["collect.lua"] = true,
268 ["collect_achievement.lua"] = true,
269 ["collect_lzw.lua"] = true,
270 ["collect_traveled.lua"] = true,
271 ["collect_zone.lua"] = true,
272 ["collect_location.lua"] = true,
273 ["collect_merger.lua"] = true,
274 ["collect_monster.lua"] = true,
275 ["collect_item.lua"] = true,
276 ["collect_object.lua"] = true,
277 ["collect_loot.lua"] = true,
278 ["collect_patterns.lua"] = true,
279 ["collect_flight.lua"] = true,
280 ["collect_util.lua"] = true,
281 ["collect_quest.lua"] = true,
282 ["collect_equip.lua"] = true,
283 ["collect_notifier.lua"] = true,
284 ["collect_bitstream.lua"] = true,
285 ["collect_spec.lua"] = true,
286 ["collect_upgrade.lua"] = true,
287 ["collect_merchant.lua"] = true,
288 ["collect_warp.lua"] = true,
290 ["filter_core.lua"] = true,
291 ["filter_base.lua"] = true,
293 ["routing_debug.lua"] = true,
294 ["routing_loc.lua"] = true,
295 ["routing_route.lua"] = true,
296 ["routing_core.lua"] = true,
297 ["routing_controller.lua"] = true,
298 ["routing_hidden.lua"] = true,
300 ["director_quest.lua"] = true,
301 ["director_achievement.lua"] = true,
303 ["db_get.lua"] = true,
305 ["graph_core.lua"] = true,
306 ["graph_flightpath.lua"] = true,
308 ["AstrolabeQH/Astrolabe.lua"] = true,
309 ["AstrolabeQH/AstrolabeMapMonitor.lua"] = true,
312 local uninstallederr
= ""
314 for file
, version
in pairs(QuestHelper_File
) do
315 if not expected_files
[file
] then
316 local errmsg
= "Unexpected QuestHelper file: "..file
317 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
318 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
319 file_problem_version
= true
320 elseif version
~= expected_version
then
321 local errmsg
= "Wrong version of QuestHelper file: "..file
.." (found '"..version
.."', should be '"..expected_version
.."')"
322 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
323 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
324 if version
~= "Development Version" and expected_version
~= "Development Version" then
325 -- Developers are allowed to mix dev versions with release versions
326 file_problem_version
= true
331 for file
in pairs(expected_files
) do
332 if not QuestHelper_File
[file
] then
333 local errmsg
= "Missing QuestHelper file: "..file
334 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
335 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
336 if not (expected_version
== "Development Version" and file
:match("static.*")) then file_problem_version
= true end
340 -- Don't need this table anymore.
341 QuestHelper_File
= nil
343 if QuestHelper_StaticData
and not QuestHelper_StaticData
[GetLocale()] then
344 local errmsg
= "Static data does not seem to exist"
345 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
347 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
348 file_problem_version
= true
351 if file_problem_version
then
352 QH_fixedmessage(QHText("PLEASE_RESTART"))
353 QuestHelper_ErrorCatcher_ExplicitError(false, "not-installed-properly" .. "\n" .. uninstallederr
)
354 QuestHelper
= nil -- Just in case anybody else is checking for us, we're not home
358 if not GetCategoryList
or not GetQuestLogSpecialItemInfo
or not WatchFrame_RemoveObjectiveHandler
then
359 QH_fixedmessage(QHText("PRIVATE_SERVER"))
360 QuestHelper_ErrorCatcher_ExplicitError(false, "error id cakbep ten T")
365 if not DongleStub
or not QH_Astrolabe_Ready
then
366 QH_fixedmessage(QHText("NOT_UNZIPPED_CORRECTLY"))
367 QuestHelper_ErrorCatcher_ExplicitError(false, "not-unzipped-properly")
368 QuestHelper
= nil -- Just in case anybody else is checking for us, we're not home
372 QuestHelper_ErrorCatcher_CompletelyStarted()
374 if not QuestHelper_StaticData
then
375 -- If there is no static data for some mysterious reason, create an empty table so that
376 -- other parts of the code can carry on as usual, using locally collected data if it exists.
377 QuestHelper_StaticData
= {}
380 QHFormatSetLocale(QuestHelper_Pref
.locale
or GetLocale())
382 if not QuestHelper_UID
then
383 QuestHelper_UID
= self
:CreateUID()
385 QuestHelper_SaveDate
= time()
387 QuestHelper_BuildZoneLookup()
391 if QuestHelper_Locale
~= GetLocale() then
392 self
:TextOut(QHText("LOCALE_ERROR"))
396 if not self
:ZoneSanity() then
397 self
:TextOut(QHFormat("ZONE_LAYOUT_ERROR", expected_version
))
398 QH_fixedmessage(QHFormat("ZONE_LAYOUT_ERROR", expected_version
))
403 QuestHelper_UpgradeDatabase(_G
)
404 QuestHelper_UpgradeComplete()
406 if QuestHelper_IsPolluted(_G
) then
407 self
:TextOut(QHFormat("NAG_POLLUTED"))
408 self
:Purge(nil, true, true)
411 local signature
= expected_version
.. " on " .. GetBuildInfo()
412 QuestHelper_Quests
[signature
] = QuestHelper_Quests
[signature
] or {}
413 QuestHelper_Objectives
[signature
] = QuestHelper_Objectives
[signature
] or {}
414 QuestHelper_FlightInstructors
[signature
] = QuestHelper_FlightInstructors
[signature
] or {}
415 QuestHelper_FlightRoutes
[signature
] = QuestHelper_FlightRoutes
[signature
] or {}
417 QuestHelper_Quests_Local
= QuestHelper_Quests
[signature
]
418 QuestHelper_Objectives_Local
= QuestHelper_Objectives
[signature
]
419 QuestHelper_FlightInstructors_Local
= QuestHelper_FlightInstructors
[signature
]
420 QuestHelper_FlightRoutes_Local
= QuestHelper_FlightRoutes
[signature
]
422 QuestHelper_SeenRealms
[GetRealmName()] = true -- some attempt at tracking private servers
427 self
.player_level
= UnitLevel("player")
429 self
:SetLocaleFonts()
431 if QuestHelper_Pref
.share
and not QuestHelper_Pref
.solo
then
435 if QuestHelper_Pref
.hide
then
436 self
.map_overlay
:Hide()
439 self
:HandlePartyChange()
443 for locale
in pairs(QuestHelper_StaticData
) do
444 if locale
~= self
.locale
then
445 -- Will delete references to locales you don't use.
446 QuestHelper_StaticData
[locale
] = nil
447 _G
["QuestHelper_StaticData_" .. locale
] = nil
451 local static
= QuestHelper_StaticData
[self
.locale
]
454 if static
.flight_instructors
then for faction
in pairs(static
.flight_instructors
) do
455 if faction
~= self
.faction
then
456 -- Will delete references to flight instructors that don't belong to your faction.
457 static
.flight_instructors
[faction
] = nil
461 if static
.quest
then for faction
in pairs(static
.quest
) do
462 if faction
~= self
.faction
then
463 -- Will delete references to quests that don't belong to your faction.
464 static
.quest
[faction
] = nil
469 -- Adding QuestHelper_CharVersion, so I know if I've already converted this characters saved data.
470 if not QuestHelper_CharVersion
then
471 -- Changing per-character flight routes, now only storing the flight points they have,
472 -- will attempt to guess the routes from this.
475 for i
, l
in pairs(QuestHelper_KnownFlightRoutes
) do
476 for key
in pairs(l
) do
481 QuestHelper_KnownFlightRoutes
= routes
483 -- Deleting the player's home again.
484 -- But using the new CharVersion variable I'm adding is cleaner that what I was doing, so I'll go with it.
485 QuestHelper_Home
= nil
486 QuestHelper_CharVersion
= 1
489 if not QuestHelper_Home
then
490 -- Not going to bother complaining about the player's home not being set, uncomment this when the home is used in routing.
491 -- self:TextOut(QHText("HOME_NOT_KNOWN"))
494 if QuestHelper_Pref
.map_button
then
495 QuestHelper
:InitMapButton()
498 if QuestHelper_Pref
.cart_wp_new
then
499 init_cartographer_later
= true
502 if QuestHelper_Pref
.tomtom_wp_new
then
506 self
.tracker
:SetScale(QuestHelper_Pref
.track_scale
)
508 if QuestHelper_Pref
.track
and not QuestHelper_Pref
.hide
then
512 local version
= GetAddOnMetadata("QuestHelper", "Version") or "Unknown"
514 local major
, minor
= (version_string
or ""):match("^(%d+)%.(%d+)")
515 major
, minor
= tonumber(major
), tonumber(minor
)
517 -- For versions before 0.82, we're changing the default level offset to 3.
518 if major
== 0 and minor
and minor
< 82 and QuestHelper_Pref
.level
== 2 then
519 QuestHelper_Pref
.level
= nil
522 -- For versions before 0.84...
523 if major
== 0 and minor
and minor
< 84 then
524 -- remove all keys that match their default setting.
525 for key
, val
in pairs(QuestHelper_DefaultPref
) do
526 if QuestHelper_Pref
[key
] == val
then
527 QuestHelper_Pref
[key
] = nil
532 QH_Hook(self
, "OnUpdate", self
.OnUpdate
)
534 -- Seems to do its own garbage collection pass before fully loading, so I'll just rely on that
535 --collectgarbage("collect") -- Free everything we aren't using.
538 if self.debug_objectives then
539 for name, data in pairs(self.debug_objectives) do
540 self:LoadDebugObjective(name, data)
546 QH_Arrow_SetTextScale()
549 QH_Timeslice_Add(function ()
551 self.Routing:Initialize() -- Set up the routing task
552 end, "init")]] -- FUCK YOU BOXBOT
554 --[[ -- This is just an example of how the WoW profiler biases its profiles heavily.
560 for x = 0, 130000000, 1 do
566 for x = 0, 12000000, 1 do
573 for x = 0, 1200000, 1 do
581 local ta = debugprofilestop()
583 local tb = debugprofilestop()
585 local tc = debugprofilestop()
587 QuestHelper:TextOut(string.format("%d %d %d", ta, tb - ta, tc - tb))
588 QuestHelper:TextOut(string.format("%d %d", GetFunctionCPUUsage(A), GetFunctionCPUUsage(B)))
590 --/script SetCVar("scriptProfile", value)]]
592 LibStub("LibAboutPanelQH").new(nil, "QuestHelper")
594 QuestHelper_Loadtime
["init_end"] = GetTime()
596 QuestHelper
.loading_main
= QuestHelper
.CreateLoadingCounter()
598 QuestHelper
.loading_flightpath
= QuestHelper
.loading_main
:MakeSubcategory(1)
599 QuestHelper
.loading_preroll
= QuestHelper
.loading_main
:MakeSubcategory(1)
601 QH_Event("CHAT_MSG_ADDON", function (...)
602 if arg1
== "QHpr" and arg4
~= UnitName("player") then
603 QH_Questcomm_Msg(arg2
, arg4
)
607 QH_Event({"PARTY_MEMBERS_CHANGED", "UNIT_LEVEL", "RAID_ROSTER_UPDATE"}, function ()
608 QH_Filter_Group_Sync()
609 QH_Route_Filter_Rescan("filter_quest_level")
610 QH_Route_Filter_Rescan("filter_quest_group")
613 QH_Event({"PARTY_MEMBERS_CHANGED", "RAID_ROSTER_UPDATE"}, function ()
617 QH_Event("PLAYER_LEVEL_UP", function ()
618 self
.player_level
= arg1
619 QH_Route_Filter_Rescan("filter_quest_level")
622 QH_Event("TAXIMAP_OPENED", function ()
626 QH_Event({"ZONE_CHANGED", "ZONE_CHANGED_INDOORS", "ZONE_CHANGED_NEW_AREA"}, function()
627 QH_Route_Filter_Rescan()
630 QH_Event("CHAT_MSG_CHANNEL_NOTICE", function()
631 if please_submit_enabled
and not please_submit_initted
then
632 please_submit_enabled
= QHNagInit()
633 startup_time
= GetTime()
634 please_submit_initted
= true
642 function QuestHelper
:OnEvent(event
)
643 local tstart
= GetTime()
646 if event == "GOSSIP_SHOW" then
647 local name, id = UnitName("npc"), self:GetUnitID("npc")
649 self:GetObjective("monster", name).o.id = id
650 --self:TextOut("NPC: "..name.." = "..id)
654 --[[if event == "PLAYER_TARGET_CHANGED" then
655 local name, id = UnitName("target"), self:GetUnitID("target")
657 self:GetObjective("monster", name).o.id = id
658 --self:TextOut("Target: "..name.." = "..id)
661 if UnitExists("target") and UnitIsVisible("target") and UnitCreatureType("target") ~= "Critter" and not UnitIsPlayer("target") and not UnitPlayerControlled("target") then
662 local index, x, y = self:UnitPosition("target")
664 if index then -- Might not have a position if inside an instance.
667 -- Modify the weight based on how far they are from us.
668 -- We don't know the exact location (using our own location), so the farther, the less sure we are that it's correct.
669 if CheckInteractDistance("target", 3) then w = 1
670 elseif CheckInteractDistance("target", 2) then w = 0.89
671 elseif CheckInteractDistance("target", 1) or CheckInteractDistance("target", 4) then w = 0.33 end
673 local monster_objective = self:GetObjective("monster", UnitName("target"))
674 self:AppendObjectivePosition(monster_objective, index, x, y, w)
676 monster_objective.o.faction = (UnitFactionGroup("target") == "Alliance" and 1) or
677 (UnitFactionGroup("target") == "Horde" and 2) or nil
679 local level = UnitLevel("target")
680 if level and level >= 1 then
681 local w = monster_objective.o.levelw or 0
682 monster_objective.o.level = ((monster_objective.o.level or 0)*w+level)/(w+1)
683 monster_objective.o.levelw = w+1
689 --[[if event == "LOOT_OPENED" then
690 local target = UnitName("target")
691 if target and UnitIsDead("target") and UnitCreatureType("target") ~= "Critter" and not UnitIsPlayer("target") and not UnitPlayerControlled("target") then
692 local index, x, y = self:UnitPosition("target")
694 local monster_objective = self:GetObjective("monster", target)
695 monster_objective.o.looted = (monster_objective.o.looted or 0) + 1
697 if index then -- Might not have a position if inside an instance.
698 self:AppendObjectivePosition(monster_objective, index, x, y)
701 for i = 1, GetNumLootItems() do
702 local icon, name, number, rarity = GetLootSlotInfo(i)
704 if number and number >= 1 then
705 self:AppendItemObjectiveDrop(self:GetObjective("item", name), name, target, number)
707 local total = (name:match(COPPER_AMOUNT:gsub("%%d", "%(%%d+%)")) or 0) +
708 (name:match(SILVER_AMOUNT:gsub("%%d", "%(%%d+%)")) or 0) * 100 +
709 (name:match(GOLD_AMOUNT:gsub("%%d", "%(%%d+%)")) or 0) * 10000
712 self:AppendObjectiveDrop(self:GetObjective("item", "money"), target, total)
718 local container = nil
720 -- Go through the players inventory and look for a locked item, we're probably looting it.
721 for bag = 0,NUM_BAG_SLOTS do
722 for slot = 1,GetContainerNumSlots(bag) do
723 local link = GetContainerItemLink(bag, slot)
724 if link and select(3, GetContainerItemInfo(bag, slot)) then
725 if container == nil then
726 -- Found a locked item and haven't previously assigned to container, assign its name, or false if we fail to parse it.
727 container = select(3, string.find(link, "|h%[(.+)%]|h|r")) or false
729 -- Already tried to assign to a container. If there are multiple locked items, we give up.
737 local container_objective = self:GetObjective("item", container)
738 container_objective.o.opened = (container_objective.o.opened or 0) + 1
740 for i = 1, GetNumLootItems() do
741 local icon, name, number, rarity = GetLootSlotInfo(i)
742 if name and number >= 1 then
743 self:AppendItemObjectiveContainer(self:GetObjective("item", name), container, number)
747 -- No idea where the items came from.
748 local index, x, y = self:PlayerPosition()
751 for i = 1, GetNumLootItems() do
752 local icon, name, number, rarity = GetLootSlotInfo(i)
753 if name and number >= 1 then
754 self:AppendItemObjectivePosition(self:GetObjective("item", name), name, index, x, y)
762 --[[if event == "CHAT_MSG_SYSTEM" then
763 local home_name = self:convertPattern(ERR_DEATHBIND_SUCCESS_S)(arg1)
766 self:TextOut(QHText("HOME_CHANGED"))
767 self:TextOut(QHText("WILL_RESET_PATH"))
769 local home = QuestHelper_Home
772 QuestHelper_Home = home
775 home[1], home[2], home[3], home[4] = self.i, self.x, self.y, home_name
776 self.defered_graph_reset = true
784 --[[if event == "QUEST_DETAIL" then
785 if not self.quest_giver then self.quest_giver = {} end
786 local npc = UnitName("npc")
788 -- Some NPCs aren't actually creatures, and so their positions might not be marked by PLAYER_TARGET_CHANGED.
789 local index, x, y = self:UnitPosition("npc")
791 if index then -- Might not have a position if inside an instance.
792 local npc_objective = self:GetObjective("monster", npc)
793 self:AppendObjectivePosition(npc_objective, index, x, y)
794 self.quest_giver[GetTitleText()] = npc
799 --[[if event == "QUEST_COMPLETE" or event == "QUEST_PROGRESS" then
800 local quest = GetTitleText()
802 local level, hash = self:GetQuestLevel(quest)
803 if not level or level < 1 then
804 --self:TextOut("Don't know quest level for ".. quest.."!")
807 local q = self:GetQuest(quest, level, hash)
813 local unit = UnitName("npc")
818 -- Some NPCs aren't actually creatures, and so their positions might not be marked by PLAYER_TARGET_CHANGED.
819 local index, x, y = self:UnitPosition("npc")
820 if index then -- Might not have a position if inside an instance.
821 local npc_objective = self:GetObjective("monster", unit)
822 self:AppendObjectivePosition(npc_objective, index, x, y)
824 elseif not q.o.finish then
825 local index, x, y = self:PlayerPosition()
826 if index then -- Might not have a position if inside an instance.
827 self:AppendObjectivePosition(q, index, x, y)
833 --[[if event == "MERCHANT_SHOW" then
834 local npc_name = UnitName("npc")
836 local npc_objective = self:GetObjective("monster", npc_name)
839 local item_name = GetMerchantItemInfo(index)
842 local item_objective = self:GetObjective("item", item_name)
843 if not item_objective.o.vendor then
844 item_objective.o.vendor = {npc_name}
847 for i, vendor in ipairs(item_objective.o.vendor) do
848 if npc_name == vendor then
854 table.insert(item_objective.o.vendor, npc_name)
864 if event
== "TAXIMAP_OPENED" then
868 --[[if event == "PLAYER_CONTROL_GAINED" then
869 interruptcount = interruptcount + 1
872 --[[if event == "BAG_UPDATE" then
873 for slot = 1,GetContainerNumSlots(arg1) do
874 local link = GetContainerItemLink(arg1, slot)
876 local id, name = select(3, string.find(link, "|Hitem:(%d+):.-|h%[(.-)%]|h"))
878 self:GetObjective("item", name).o.id = tonumber(id)
886 if event
== "ZONE_CHANGED" or event
== "ZONE_CHANGED_INDOORS" or event
== "ZONE_CHANGED_NEW_AREA" then
887 QH_Route_Filter_Rescan()
890 QH_Timeslice_Increment(GetTime() - tstart
, "event")
893 local map_shown_decay
= 0
894 local delayed_action
= 100
895 --local update_count = 0
899 QH_OnUpdate_High(function ()
900 local self
= QuestHelper
-- hoorj
901 local tstart
= GetTime()
904 if not QuestHelper_Loadtime
["onupdate"] then QuestHelper_Loadtime
["onupdate"] = GetTime() end
906 if false and frams
== 60 then
908 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
910 Known bugs and issues include:
912 |cff40bbffNo support for "/qh find"|r
914 |cff40bbffNo support for in-party quest synchronization|r
916 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.
918 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.
920 Thanks for testing!]], "QuestHelper " .. version_string
, 500, 20, 10)
923 --if frams == 5000 then please_submit_enabled = false end -- TOOK TOO LONG >:(
924 if please_submit_enabled
and startup_time
and startup_time
+ 10 < GetTime() then
925 QuestHelper
:TextOut(QHText("PLEASE_SUBMIT"))
927 please_submit_enabled
= false
929 QHUpdateNagTick() -- These probably shouldn't be in OnUpdate. Eventually I'll move them somewhere cleaner.
931 if init_cartographer_later
and Cartographer_Waypoints
then -- there has to be a better way to do this
932 init_cartographer_later
= false
933 if QuestHelper_Pref
.cart_wp_new
then
934 self
:EnableCartographer()
938 if not ontaxi
and UnitOnTaxi("player") then
941 elseif ontaxi
and not UnitOnTaxi("player") then
942 self
:flightEnded(interruptcount
> 1)
944 ontaxi
= UnitOnTaxi("player")
946 -- For now I'm ripping out the update_count code
947 --update_count = update_count - 1
948 --if update_count <= 0 then
950 -- Reset the update count for next time around; this will make sure the body executes every time
951 -- when perf_scale_2 >= 1, and down to 1 in 10 iterations when perf_scale_2 < 1, or when hidden.
952 --update_count = update_count + (QuestHelper_Pref.hide and 10 or 1/QuestHelper_Pref.perf_scale_2)
954 --if update_count < 0 then
955 -- Make sure the count doesn't go perpetually negative; don't know what will happen if it underflows.
959 if self
.Astrolabe
.WorldMapVisible
then
960 -- We won't trust that the zone returned by Astrolabe is correct until map_shown_decay is 0.
962 elseif map_shown_decay
> 0 then
963 map_shown_decay
= map_shown_decay
- 1
965 --SetMapToCurrentZone() -- not sure why this existed
968 --[[delayed_action = delayed_action - 1
969 if delayed_action <= 0 then
971 self:HandlePartyChange()
974 local nc
, nz
, nx
, ny
= self
.Astrolabe
:GetCurrentPlayerPosition()
977 if nc
and nc
~= -1 then -- We just want the raw data here, before we've done anything clever.
978 tc
, tx
, ty
= self
.Astrolabe
:GetAbsoluteContinentPosition(nc
, nz
, nx
, ny
)
979 QuestHelper
: Assert(tc
and tx
and ty
) -- is it true? nobody knows! :D
982 if nc
and nc
== self
.c
and map_shown_decay
> 0 and self
.z
> 0 and self
.z
~= nz
then
983 -- There's a chance Astrolable will return the wrong zone if you're messing with the world map, if you can
984 -- be seen in that zone but aren't in it.
985 local nnx
, nny
= self
.Astrolabe
:TranslateWorldMapPosition(nc
, nz
, nx
, ny
, nc
, self
.z
)
986 if nnx
> 0 and nny
> 0 and nnx
< 1 and nny
< 1 then
987 nz
, nx
, ny
= self
.z
, nnx
, nny
991 if nc
and nc
> 0 and nz
== 0 and nc
== self
.c
and self
.z
> 0 then
992 nx
, ny
= self
.Astrolabe
:TranslateWorldMapPosition(nc
, nz
, nx
, ny
, nc
, self
.z
)
993 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
996 nc
, nz
, nx
, ny
= nil, nil, nil, nil
1000 if nc
and nz
> 0 then
1001 self
.c
, self
.z
, self
.x
, self
.y
= nc
, nz
, nx
, ny
1002 local upd_zone
= false
1003 if self
.i
~= QuestHelper_IndexLookup
[nc
][nz
] then upd_zone
= true end
1004 self
.i
= QuestHelper_IndexLookup
[nc
][nz
]
1005 if upd_zone
then QH_Route_Filter_Rescan("filter_zone") end
1008 if nc
and nz
and nx
and ny
and tc
and tx
and ty
then
1009 self
.collect_rc
, self
.collect_rz
, self
.collect_rx
, self
.collect_ry
= nc
, nz
, nx
, ny
1010 self
.collect_ac
, self
.collect_ax
, self
.collect_ay
= tc
, tx
, ty
1011 self
.collect_delayed
= false
1013 local ibi
= self
.InBrokenInstance
1014 if nc
< -77 then self
.InBrokenInstance
= true else self
.InBrokenInstance
= false end
1016 if ibi
and not self
.InBrokenInstance
then self
.minimap_marker
:OnUpdate(0) end -- poke
1018 self
.collect_delayed
= true
1019 self
.InBrokenInstance
= true
1022 if not UnitOnTaxi("player") and not UnitIsDeadOrGhost("player") then
1023 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
1026 QH_Timeslice_Toggle("routing", not not self
.c
)
1028 self
:PumpCommMessages()
1032 -- 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.
1033 -- 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?
1034 function QuestHelper
:Location_RawRetrieve()
1035 return self
.collect_delayed
, self
.collect_rc
, self
.collect_rz
, self
.collect_rx
, self
.collect_ry
1037 function QuestHelper
:Location_AbsoluteRetrieve()
1038 return self
.collect_delayed
, self
.collect_ac
, self
.collect_ax
, self
.collect_ay
1041 --QH_Hook(QuestHelper, "OnEvent", QuestHelper.OnEvent)