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_SaveVersion
= 10
10 QuestHelper_CharVersion
= 1
11 QuestHelper_Locale
= GetLocale() -- This variable is used only for the collected data, and has nothing to do with displayed text.
12 QuestHelper_Quests
= {}
13 QuestHelper_Objectives
= {}
18 QuestHelper_DefaultPref
=
23 filter_blocked
=false, -- Hides blocked objectives, such as quest turn-ins for incomplete quests
24 filter_watched
=false, -- Limits to Watched objectives
27 filter_wintergrasp
=true,
29 track_minimized
=false,
44 tomtom_wp_new
= false,
49 metric
= (QuestHelper_Locale
~= "enUS" and QuestHelper_Locale
~= "esMX"),
51 locale
= GetLocale(), -- This variable is used for display purposes, and has nothing to do with the collected data.
52 perf_scale_2
= 1, -- How much background processing can the current machine handle? Higher means more load, lower means better performance.
53 perfload_scale
= 1, -- Performance scale to use on startup
57 -- 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.
58 setmetatable(QuestHelper_Pref
, {__index
=QuestHelper_DefaultPref
})
60 QuestHelper_FlightInstructors
= {}
61 QuestHelper_FlightLinks
= {}
62 QuestHelper_FlightRoutes
= {}
63 QuestHelper_KnownFlightRoutes
= {}
64 QuestHelper_SeenRealms
= {}
66 QuestHelper
.tooltip
= CreateFrame("GameTooltip", "QuestHelperTooltip", nil, "GameTooltipTemplate")
67 QuestHelper
.objective_objects
= {}
68 QuestHelper
.user_objectives
= {}
69 QuestHelper
.quest_objects
= {}
70 QuestHelper
.player_level
= 1
71 QuestHelper
.locale
= QuestHelper_Locale
73 QuestHelper
.faction
= (UnitFactionGroup("player") == "Alliance" and 1) or
74 (UnitFactionGroup("player") == "Horde" and 2)
76 assert(QuestHelper
.faction
)
78 QuestHelper
.font
= {serif
=GameFontNormal
:GetFont(), sans
=ChatFontNormal
:GetFont(), fancy
=QuestTitleFont
:GetFont()}
80 function QuestHelper
:GetFontPath(list_string
, font
)
82 for name
in string.gmatch(list_string
, "[^;]+") do
83 if font
:SetFont(name
, 10) then
85 elseif font
:SetFont("Interface\\AddOns\\QuestHelper\\Fonts\\"..name
, 10) then
86 return "Interface\\AddOns\\QuestHelper\\Fonts\\"..name
92 function QuestHelper
:SetLocaleFonts()
97 local font
= self
:CreateText(self
)
99 if QuestHelper_Locale
~= QuestHelper_Pref
.locale
then
100 -- Only use alternate fonts if using a language the client wasn't intended for.
101 local replacements
= QuestHelper_SubstituteFonts
[QuestHelper_Pref
.locale
]
103 self
.font
.sans
= self
:GetFontPath(replacements
.sans
, font
)
104 self
.font
.serif
= self
:GetFontPath(replacements
.serif
, font
)
105 self
.font
.fancy
= self
:GetFontPath(replacements
.fancy
, font
)
109 self
.font
.sans
= self
.font
.sans
or self
:GetFontPath(QuestHelper_Pref
.locale
.."_sans.ttf", font
)
110 self
.font
.serif
= self
.font
.serif
or self
:GetFontPath(QuestHelper_Pref
.locale
.."_serif.ttf", font
) or self
.font
.sans
111 self
.font
.fancy
= self
.font
.fancy
or self
:GetFontPath(QuestHelper_Pref
.locale
.."_fancy.ttf", font
) or self
.font
.serif
113 self
:ReleaseText(font
)
115 self
.font
.sans
= self
.font
.sans
or ChatFontNormal
:GetFont()
116 self
.font
.serif
= self
.font
.serif
or GameFontNormal
:GetFont()
117 self
.font
.fancy
= self
.font
.fancy
or QuestTitleFont
:GetFont()
119 -- Need to change the font of the chat frame, for any messages that QuestHelper displays.
120 -- This should do nothing if not using an alternate font.
121 DEFAULT_CHAT_FRAME
:SetFont(self
.font
.sans
, select(2, DEFAULT_CHAT_FRAME
:GetFont()))
124 QuestHelper
.route
= {}
125 QuestHelper
.to_add
= {}
126 QuestHelper
.to_remove
= {}
127 QuestHelper
.quest_log
= {}
128 QuestHelper
.pos
= {nil, {}, 0, 0, 1, "You are here.", 0}
129 QuestHelper
.sharing
= false -- Will be set to true when sharing with at least one user.
131 function QuestHelper
.tooltip
:GetPrevLines() -- Just a helper to make life easier.
132 local last
= self
:NumLines()
133 local name
= self
:GetName()
134 return _G
[name
.."TextLeft"..last
], _G
[name
.."TextRight"..last
]
137 function QuestHelper
:SetTargetLocation(i
, x
, y
, toffset
)
138 -- Informs QuestHelper that you're going to be at some location in toffset seconds.
139 local c
, z
= unpack(QuestHelper_ZoneLookup
[i
])
141 self
.target
= self
:CreateTable()
142 self
.target
[2] = self
:CreateTable()
144 self
.target_time
= time()+(toffset
or 0)
146 x
, y
= self
.Astrolabe
:TranslateWorldMapPosition(c
, z
, x
, y
, c
, 0)
147 self
.target
[1] = self
.zone_nodes
[i
]
148 self
.target
[3] = x
* self
.continent_scales_x
[c
]
149 self
.target
[4] = y
* self
.continent_scales_y
[c
]
151 self
:SetTargetLocationRecalculate()
154 function QuestHelper
:SetTargetLocationRecalculate()
156 for i
, n
in ipairs(self
.target
[1]) do
157 local a
, b
= n
.x
-self
.target
[3], n
.y
-self
.target
[4]
158 self
.target
[2][i
] = math
.sqrt(a
*a
+b
*b
)
163 function QuestHelper
:UnsetTargetLocation()
164 -- Unsets the target set above.
166 self
:ReleaseTable(self
.target
[2])
167 self
:ReleaseTable(self
.target
)
169 self
.target_time
= nil
173 local interruptcount
= 0 -- counts how many "played gained control" messages we recieve, used for flight paths
174 local init_cartographer_later
= false
176 QH_Event("ADDON_LOADED", function (addonid
)
177 if addonid
~= "QuestHelper" then return end
178 local self
= QuestHelper
-- whee hack hack hack
180 QuestHelper_Loadtime
["init_start"] = GetTime()
182 -- Use DefaultPref as fallback for unset preference keys.
183 setmetatable(QuestHelper_Pref
, {__index
=QuestHelper_DefaultPref
})
185 local file_problem
= false
186 local expected_version
= GetAddOnMetadata("QuestHelper", "Version")
188 local expected_files
=
190 ["bst_pre.lua"] = true,
191 ["bst_post.lua"] = true,
192 ["bst_astrolabe.lua"] = true,
193 ["bst_ctl.lua"] = true,
194 ["bst_libaboutpanel.lua"] = true,
196 ["manager_event.lua"] = true,
198 ["upgrade.lua"] = true,
200 ["recycle.lua"] = true,
201 ["objective.lua"] = true,
202 ["quest.lua"] = true,
203 ["utility.lua"] = true,
204 ["dodads.lua"] = true,
205 ["teleport.lua"] = true,
206 ["pathfinding.lua"] = true,
207 ["routing.lua"] = true,
208 ["custom.lua"] = true,
212 ["mapbutton.lua"] = true,
214 ["pattern.lua"] = true,
215 ["flightpath.lua"] = true,
216 ["tracker.lua"] = true,
217 ["objtips.lua"] = true,
218 ["cartographer.lua"] = true,
219 ["cartographer_is_terrible.lua"] = true,
220 ["tomtom.lua"] = true,
221 ["textviewer.lua"] = true,
222 ["error.lua"] = true,
223 ["timeslice.lua"] = true,
226 ["tooltip.lua"] = true,
227 ["arrow.lua"] = true,
229 ["static.lua"] = true,
230 ["static_1.lua"] = true,
231 ["static_2.lua"] = true,
232 ["static_deDE.lua"] = true,
233 ["static_deDE_1.lua"] = true,
234 ["static_deDE_2.lua"] = true,
235 ["static_enUS.lua"] = true,
236 ["static_enUS_1.lua"] = true,
237 ["static_enUS_2.lua"] = true,
238 ["static_esES.lua"] = true,
239 ["static_esES_1.lua"] = true,
240 ["static_esES_2.lua"] = true,
241 ["static_esMX.lua"] = true,
242 ["static_esMX_1.lua"] = true,
243 ["static_esMX_2.lua"] = true,
244 ["static_frFR.lua"] = true,
245 ["static_frFR_1.lua"] = true,
246 ["static_frFR_2.lua"] = true,
247 ["static_koKR.lua"] = true,
248 ["static_koKR_1.lua"] = true,
249 ["static_koKR_2.lua"] = true,
250 ["static_ruRU.lua"] = true,
251 ["static_ruRU_1.lua"] = true,
252 ["static_ruRU_2.lua"] = true,
253 ["static_zhTW.lua"] = true,
254 ["static_zhTW_1.lua"] = true,
255 ["static_zhTW_2.lua"] = true,
257 ["collect.lua"] = true,
258 ["collect_achievement.lua"] = true,
259 ["collect_lzw.lua"] = true,
260 ["collect_traveled.lua"] = true,
261 ["collect_zone.lua"] = true,
262 ["collect_location.lua"] = true,
263 ["collect_merger.lua"] = true,
264 ["collect_monster.lua"] = true,
265 ["collect_item.lua"] = true,
266 ["collect_object.lua"] = true,
267 ["collect_loot.lua"] = true,
268 ["collect_patterns.lua"] = true,
269 ["collect_flight.lua"] = true,
270 ["collect_util.lua"] = true,
271 ["collect_quest.lua"] = true,
272 ["collect_equip.lua"] = true,
273 ["collect_notifier.lua"] = true,
274 ["collect_bitstream.lua"] = true,
275 ["collect_spec.lua"] = true,
276 ["collect_upgrade.lua"] = true,
277 ["collect_merchant.lua"] = true,
278 ["collect_warp.lua"] = true,
280 ["filter_core.lua"] = true,
281 ["filter_base.lua"] = true,
283 ["routing_debug.lua"] = true,
284 ["routing_loc.lua"] = true,
285 ["routing_route.lua"] = true,
286 ["routing_core.lua"] = true,
287 ["routing_controller.lua"] = true,
288 ["routing_hidden.lua"] = true,
290 ["director_quest.lua"] = true,
291 ["director_achievement.lua"] = true,
293 ["db_get.lua"] = true,
295 ["graph_core.lua"] = true,
296 ["graph_flightpath.lua"] = true,
299 local uninstallederr
= ""
301 for file
, version
in pairs(QuestHelper_File
) do
302 if not expected_files
[file
] then
303 local errmsg
= "Unexpected QuestHelper file: "..file
304 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
305 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
307 elseif version
~= expected_version
then
308 local errmsg
= "Wrong version of QuestHelper file: "..file
.." (found '"..version
.."', should be '"..expected_version
.."')"
309 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
310 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
311 if version
~= "Development Version" and expected_version
~= "Development Version" then
312 -- Developers are allowed to mix dev versions with release versions
318 for file
in pairs(expected_files
) do
319 if not QuestHelper_File
[file
] then
320 local errmsg
= "Missing QuestHelper file: "..file
321 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
322 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
323 if not (expected_version
== "Development Version" and file
:match("static.*")) then file_problem
= true end
327 -- Don't need this table anymore.
328 QuestHelper_File
= nil
330 if QuestHelper_StaticData
and not QuestHelper_StaticData
[GetLocale()] then
331 local errmsg
= "Static data does not seem to exist"
332 DEFAULT_CHAT_FRAME
:AddMessage(errmsg
)
334 -- TODO: Are you sure this should be an error? Shouldn't we let people we don't have data for collect their own?
335 uninstallederr
= uninstallederr
.. " " .. errmsg
.. "\n"
340 message(QHText("PLEASE_RESTART"))
341 QuestHelper_ErrorCatcher_ExplicitError(true, "not-installed-properly" .. "\n" .. uninstallederr
)
342 QuestHelper
= nil -- Just in case anybody else is checking for us, we're not home
346 if not GetCategoryList
or not GetQuestLogSpecialItemInfo
or not WatchFrame_RemoveObjectiveHandler
then
347 message(QHText("PRIVATE_SERVER"))
348 QuestHelper_ErrorCatcher_ExplicitError(true, "error id cakbep ten T")
353 if not DongleStub
then
354 message(QHText("NOT_UNZIPPED_CORRECTLY"))
355 QuestHelper_ErrorCatcher_ExplicitError(true, "not-unzipped-properly")
356 QuestHelper
= nil -- Just in case anybody else is checking for us, we're not home
360 QuestHelper_ErrorCatcher_CompletelyStarted()
362 if not QuestHelper_StaticData
then
363 -- If there is no static data for some mysterious reason, create an empty table so that
364 -- other parts of the code can carry on as usual, using locally collected data if it exists.
365 QuestHelper_StaticData
= {}
368 QHFormatSetLocale(QuestHelper_Pref
.locale
or GetLocale())
370 if not QuestHelper_UID
then
371 QuestHelper_UID
= self
:CreateUID()
373 QuestHelper_SaveDate
= time()
375 QuestHelper_BuildZoneLookup()
379 if QuestHelper_Locale
~= GetLocale() then
380 self
:TextOut(QHText("LOCALE_ERROR"))
384 if not self
:ZoneSanity() then
385 self
:TextOut(QHText("ZONE_LAYOUT_ERROR"))
386 message("QuestHelper: "..QHText("ZONE_LAYOUT_ERROR"))
390 QuestHelper_UpgradeDatabase(_G
)
391 QuestHelper_UpgradeComplete()
393 if QuestHelper_SaveVersion
~= 10 then
394 self
:TextOut(QHText("DOWNGRADE_ERROR"))
398 if QuestHelper_IsPolluted(_G
) then
399 self
:TextOut(QHFormat("NAG_POLLUTED"))
400 self
:Purge(nil, true, true)
403 local signature
= expected_version
.. " on " .. GetBuildInfo()
404 QuestHelper_Quests
[signature
] = QuestHelper_Quests
[signature
] or {}
405 QuestHelper_Objectives
[signature
] = QuestHelper_Objectives
[signature
] or {}
406 QuestHelper_FlightInstructors
[signature
] = QuestHelper_FlightInstructors
[signature
] or {}
407 QuestHelper_FlightRoutes
[signature
] = QuestHelper_FlightRoutes
[signature
] or {}
409 QuestHelper_Quests_Local
= QuestHelper_Quests
[signature
]
410 QuestHelper_Objectives_Local
= QuestHelper_Objectives
[signature
]
411 QuestHelper_FlightInstructors_Local
= QuestHelper_FlightInstructors
[signature
]
412 QuestHelper_FlightRoutes_Local
= QuestHelper_FlightRoutes
[signature
]
414 QuestHelper_SeenRealms
[GetRealmName()] = true -- some attempt at tracking private servers
419 self
.player_level
= UnitLevel("player")
421 self
:SetLocaleFonts()
423 if QuestHelper_Pref
.share
and not QuestHelper_Pref
.solo
then
427 if QuestHelper_Pref
.hide
then
428 self
.map_overlay
:Hide()
431 self
:HandlePartyChange()
435 for locale
in pairs(QuestHelper_StaticData
) do
436 if locale
~= self
.locale
then
437 -- Will delete references to locales you don't use.
438 QuestHelper_StaticData
[locale
] = nil
439 _G
["QuestHelper_StaticData_" .. locale
] = nil
443 local static
= QuestHelper_StaticData
[self
.locale
]
446 if static
.flight_instructors
then for faction
in pairs(static
.flight_instructors
) do
447 if faction
~= self
.faction
then
448 -- Will delete references to flight instructors that don't belong to your faction.
449 static
.flight_instructors
[faction
] = nil
453 if static
.quest
then for faction
in pairs(static
.quest
) do
454 if faction
~= self
.faction
then
455 -- Will delete references to quests that don't belong to your faction.
456 static
.quest
[faction
] = nil
461 -- Adding QuestHelper_CharVersion, so I know if I've already converted this characters saved data.
462 if not QuestHelper_CharVersion
then
463 -- Changing per-character flight routes, now only storing the flight points they have,
464 -- will attempt to guess the routes from this.
467 for i
, l
in pairs(QuestHelper_KnownFlightRoutes
) do
468 for key
in pairs(l
) do
473 QuestHelper_KnownFlightRoutes
= routes
475 -- Deleting the player's home again.
476 -- But using the new CharVersion variable I'm adding is cleaner that what I was doing, so I'll go with it.
477 QuestHelper_Home
= nil
478 QuestHelper_CharVersion
= 1
481 if not QuestHelper_Home
then
482 -- Not going to bother complaining about the player's home not being set, uncomment this when the home is used in routing.
483 -- self:TextOut(QHText("HOME_NOT_KNOWN"))
486 if QuestHelper_Pref
.map_button
then
487 QuestHelper
:InitMapButton()
490 if QuestHelper_Pref
.cart_wp_new
then
491 init_cartographer_later
= true
494 if QuestHelper_Pref
.tomtom_wp_new
then
498 self
.tracker
:SetScale(QuestHelper_Pref
.track_scale
)
500 if QuestHelper_Pref
.track
and not QuestHelper_Pref
.hide
then
504 local version
= GetAddOnMetadata("QuestHelper", "Version") or "Unknown"
506 local major
, minor
= (version_string
or ""):match("^(%d+)%.(%d+)")
507 major
, minor
= tonumber(major
), tonumber(minor
)
509 -- For versions before 0.82, we're changing the default level offset to 3.
510 if major
== 0 and minor
and minor
< 82 and QuestHelper_Pref
.level
== 2 then
511 QuestHelper_Pref
.level
= nil
514 -- For versions before 0.84...
515 if major
== 0 and minor
and minor
< 84 then
516 -- remove all keys that match their default setting.
517 for key
, val
in pairs(QuestHelper_DefaultPref
) do
518 if QuestHelper_Pref
[key
] == val
then
519 QuestHelper_Pref
[key
] = nil
524 QH_Hook(self
, "OnUpdate", self
.OnUpdate
)
526 -- Seems to do its own garbage collection pass before fully loading, so I'll just rely on that
527 --collectgarbage("collect") -- Free everything we aren't using.
530 if self.debug_objectives then
531 for name, data in pairs(self.debug_objectives) do
532 self:LoadDebugObjective(name, data)
538 QH_Arrow_SetTextScale()
541 QH_Timeslice_Add(function ()
543 self.Routing:Initialize() -- Set up the routing task
544 end, "init")]] -- FUCK YOU BOXBOT
546 --[[ -- This is just an example of how the WoW profiler biases its profiles heavily.
552 for x = 0, 130000000, 1 do
558 for x = 0, 12000000, 1 do
565 for x = 0, 1200000, 1 do
573 local ta = debugprofilestop()
575 local tb = debugprofilestop()
577 local tc = debugprofilestop()
579 QuestHelper:TextOut(string.format("%d %d %d", ta, tb - ta, tc - tb))
580 QuestHelper:TextOut(string.format("%d %d", GetFunctionCPUUsage(A), GetFunctionCPUUsage(B)))
582 --/script SetCVar("scriptProfile", value)]]
584 LibStub("LibAboutPanelQH").new(nil, "QuestHelper")
586 QuestHelper_Loadtime
["init_end"] = GetTime()
588 QuestHelper
.loading_main
= QuestHelper
.CreateLoadingCounter()
590 QuestHelper
.loading_flightpath
= QuestHelper
.loading_main
:MakeSubcategory(1)
591 QuestHelper
.loading_preroll
= QuestHelper
.loading_main
:MakeSubcategory(1)
593 QH_Event("CHAT_MSG_ADDON", function (...)
594 if arg1
== "QHpr" and arg4
~= UnitName("player") then
595 QH_Questcomm_Msg(arg2
, arg4
)
599 QH_Event({"PARTY_MEMBERS_CHANGED", "UNIT_LEVEL", "RAID_ROSTER_UPDATE"}, function ()
600 QH_Filter_Group_Sync()
601 QH_Route_Filter_Rescan("filter_quest_level")
602 QH_Route_Filter_Rescan("filter_quest_group")
605 QH_Event({"PARTY_MEMBERS_CHANGED", "RAID_ROSTER_UPDATE"}, function ()
609 QH_Event("PLAYER_LEVEL_UP", function ()
610 self
.player_level
= arg1
611 QH_Route_Filter_Rescan("filter_quest_level")
614 QH_Event("TAXIMAP_OPENED", function ()
618 QH_Event({"ZONE_CHANGED", "ZONE_CHANGED_INDOORS", "ZONE_CHANGED_NEW_AREA"}, function()
619 QH_Route_Filter_Rescan()
625 local please_donate_enabled
= false
626 local please_donate_initted
= false
629 function QuestHelper
:OnEvent(event
)
630 local tstart
= GetTime()
633 if event == "GOSSIP_SHOW" then
634 local name, id = UnitName("npc"), self:GetUnitID("npc")
636 self:GetObjective("monster", name).o.id = id
637 --self:TextOut("NPC: "..name.." = "..id)
641 --[[if event == "PLAYER_TARGET_CHANGED" then
642 local name, id = UnitName("target"), self:GetUnitID("target")
644 self:GetObjective("monster", name).o.id = id
645 --self:TextOut("Target: "..name.." = "..id)
648 if UnitExists("target") and UnitIsVisible("target") and UnitCreatureType("target") ~= "Critter" and not UnitIsPlayer("target") and not UnitPlayerControlled("target") then
649 local index, x, y = self:UnitPosition("target")
651 if index then -- Might not have a position if inside an instance.
654 -- Modify the weight based on how far they are from us.
655 -- We don't know the exact location (using our own location), so the farther, the less sure we are that it's correct.
656 if CheckInteractDistance("target", 3) then w = 1
657 elseif CheckInteractDistance("target", 2) then w = 0.89
658 elseif CheckInteractDistance("target", 1) or CheckInteractDistance("target", 4) then w = 0.33 end
660 local monster_objective = self:GetObjective("monster", UnitName("target"))
661 self:AppendObjectivePosition(monster_objective, index, x, y, w)
663 monster_objective.o.faction = (UnitFactionGroup("target") == "Alliance" and 1) or
664 (UnitFactionGroup("target") == "Horde" and 2) or nil
666 local level = UnitLevel("target")
667 if level and level >= 1 then
668 local w = monster_objective.o.levelw or 0
669 monster_objective.o.level = ((monster_objective.o.level or 0)*w+level)/(w+1)
670 monster_objective.o.levelw = w+1
676 --[[if event == "LOOT_OPENED" then
677 local target = UnitName("target")
678 if target and UnitIsDead("target") and UnitCreatureType("target") ~= "Critter" and not UnitIsPlayer("target") and not UnitPlayerControlled("target") then
679 local index, x, y = self:UnitPosition("target")
681 local monster_objective = self:GetObjective("monster", target)
682 monster_objective.o.looted = (monster_objective.o.looted or 0) + 1
684 if index then -- Might not have a position if inside an instance.
685 self:AppendObjectivePosition(monster_objective, index, x, y)
688 for i = 1, GetNumLootItems() do
689 local icon, name, number, rarity = GetLootSlotInfo(i)
691 if number and number >= 1 then
692 self:AppendItemObjectiveDrop(self:GetObjective("item", name), name, target, number)
694 local total = (name:match(COPPER_AMOUNT:gsub("%%d", "%(%%d+%)")) or 0) +
695 (name:match(SILVER_AMOUNT:gsub("%%d", "%(%%d+%)")) or 0) * 100 +
696 (name:match(GOLD_AMOUNT:gsub("%%d", "%(%%d+%)")) or 0) * 10000
699 self:AppendObjectiveDrop(self:GetObjective("item", "money"), target, total)
705 local container = nil
707 -- Go through the players inventory and look for a locked item, we're probably looting it.
708 for bag = 0,NUM_BAG_SLOTS do
709 for slot = 1,GetContainerNumSlots(bag) do
710 local link = GetContainerItemLink(bag, slot)
711 if link and select(3, GetContainerItemInfo(bag, slot)) then
712 if container == nil then
713 -- Found a locked item and haven't previously assigned to container, assign its name, or false if we fail to parse it.
714 container = select(3, string.find(link, "|h%[(.+)%]|h|r")) or false
716 -- Already tried to assign to a container. If there are multiple locked items, we give up.
724 local container_objective = self:GetObjective("item", container)
725 container_objective.o.opened = (container_objective.o.opened or 0) + 1
727 for i = 1, GetNumLootItems() do
728 local icon, name, number, rarity = GetLootSlotInfo(i)
729 if name and number >= 1 then
730 self:AppendItemObjectiveContainer(self:GetObjective("item", name), container, number)
734 -- No idea where the items came from.
735 local index, x, y = self:PlayerPosition()
738 for i = 1, GetNumLootItems() do
739 local icon, name, number, rarity = GetLootSlotInfo(i)
740 if name and number >= 1 then
741 self:AppendItemObjectivePosition(self:GetObjective("item", name), name, index, x, y)
749 --[[if event == "CHAT_MSG_SYSTEM" then
750 local home_name = self:convertPattern(ERR_DEATHBIND_SUCCESS_S)(arg1)
753 self:TextOut(QHText("HOME_CHANGED"))
754 self:TextOut(QHText("WILL_RESET_PATH"))
756 local home = QuestHelper_Home
759 QuestHelper_Home = home
762 home[1], home[2], home[3], home[4] = self.i, self.x, self.y, home_name
763 self.defered_graph_reset = true
771 --[[if event == "QUEST_DETAIL" then
772 if not self.quest_giver then self.quest_giver = {} end
773 local npc = UnitName("npc")
775 -- Some NPCs aren't actually creatures, and so their positions might not be marked by PLAYER_TARGET_CHANGED.
776 local index, x, y = self:UnitPosition("npc")
778 if index then -- Might not have a position if inside an instance.
779 local npc_objective = self:GetObjective("monster", npc)
780 self:AppendObjectivePosition(npc_objective, index, x, y)
781 self.quest_giver[GetTitleText()] = npc
786 --[[if event == "QUEST_COMPLETE" or event == "QUEST_PROGRESS" then
787 local quest = GetTitleText()
789 local level, hash = self:GetQuestLevel(quest)
790 if not level or level < 1 then
791 --self:TextOut("Don't know quest level for ".. quest.."!")
794 local q = self:GetQuest(quest, level, hash)
800 local unit = UnitName("npc")
805 -- Some NPCs aren't actually creatures, and so their positions might not be marked by PLAYER_TARGET_CHANGED.
806 local index, x, y = self:UnitPosition("npc")
807 if index then -- Might not have a position if inside an instance.
808 local npc_objective = self:GetObjective("monster", unit)
809 self:AppendObjectivePosition(npc_objective, index, x, y)
811 elseif not q.o.finish then
812 local index, x, y = self:PlayerPosition()
813 if index then -- Might not have a position if inside an instance.
814 self:AppendObjectivePosition(q, index, x, y)
820 --[[if event == "MERCHANT_SHOW" then
821 local npc_name = UnitName("npc")
823 local npc_objective = self:GetObjective("monster", npc_name)
826 local item_name = GetMerchantItemInfo(index)
829 local item_objective = self:GetObjective("item", item_name)
830 if not item_objective.o.vendor then
831 item_objective.o.vendor = {npc_name}
834 for i, vendor in ipairs(item_objective.o.vendor) do
835 if npc_name == vendor then
841 table.insert(item_objective.o.vendor, npc_name)
851 if event
== "TAXIMAP_OPENED" then
855 --[[if event == "PLAYER_CONTROL_GAINED" then
856 interruptcount = interruptcount + 1
859 --[[if event == "BAG_UPDATE" then
860 for slot = 1,GetContainerNumSlots(arg1) do
861 local link = GetContainerItemLink(arg1, slot)
863 local id, name = select(3, string.find(link, "|Hitem:(%d+):.-|h%[(.-)%]|h"))
865 self:GetObjective("item", name).o.id = tonumber(id)
871 if event
== "CHAT_MSG_CHANNEL_NOTICE" and please_donate_enabled
and not please_donate_initted
then
872 please_donate_enabled
= QHNagInit()
873 startup_time
= GetTime()
874 please_donate_initted
= true
879 if event
== "ZONE_CHANGED" or event
== "ZONE_CHANGED_INDOORS" or event
== "ZONE_CHANGED_NEW_AREA" then
880 QH_Route_Filter_Rescan()
883 QH_Timeslice_Increment(GetTime() - tstart
, "event")
886 local map_shown_decay
= 0
887 local delayed_action
= 100
888 --local update_count = 0
892 QH_OnUpdate_High(function ()
893 local self
= QuestHelper
-- hoorj
894 local tstart
= GetTime()
897 if not QuestHelper_Loadtime
["onupdate"] then QuestHelper_Loadtime
["onupdate"] = GetTime() end
899 if false and frams
== 60 then
901 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
903 Known bugs and issues include:
905 |cff40bbffNo support for "/qh find"|r
907 |cff40bbffNo support for in-party quest synchronization|r
909 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.
911 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.
913 Thanks for testing!]], "QuestHelper " .. version_string
, 500, 20, 10)
916 if frams
== 250 then please_donate_enabled
= false end -- TOOK TOO LONG >:(
917 if please_donate_enabled
and startup_time
and startup_time
+ 1 < GetTime() then
918 QuestHelper
:TextOut(QHText("PLEASE_DONATE"))
920 please_donate_enabled
= false
922 QHUpdateNagTick() -- These probably shouldn't be in OnUpdate. Eventually I'll move them somewhere cleaner.
924 if init_cartographer_later
and Cartographer_Waypoints
then -- there has to be a better way to do this
925 init_cartographer_later
= false
926 if QuestHelper_Pref
.cart_wp_new
then
927 self
:EnableCartographer()
931 if not ontaxi
and UnitOnTaxi("player") then
934 elseif ontaxi
and not UnitOnTaxi("player") then
935 self
:flightEnded(interruptcount
> 1)
937 ontaxi
= UnitOnTaxi("player")
939 -- For now I'm ripping out the update_count code
940 --update_count = update_count - 1
941 --if update_count <= 0 then
943 -- Reset the update count for next time around; this will make sure the body executes every time
944 -- when perf_scale_2 >= 1, and down to 1 in 10 iterations when perf_scale_2 < 1, or when hidden.
945 --update_count = update_count + (QuestHelper_Pref.hide and 10 or 1/QuestHelper_Pref.perf_scale_2)
947 --if update_count < 0 then
948 -- Make sure the count doesn't go perpetually negative; don't know what will happen if it underflows.
952 if self
.Astrolabe
.WorldMapVisible
then
953 -- We won't trust that the zone returned by Astrolabe is correct until map_shown_decay is 0.
955 elseif map_shown_decay
> 0 then
956 map_shown_decay
= map_shown_decay
- 1
958 --SetMapToCurrentZone() -- not sure why this existed
961 --[[delayed_action = delayed_action - 1
962 if delayed_action <= 0 then
964 self:HandlePartyChange()
967 local nc
, nz
, nx
, ny
= self
.Astrolabe
:GetCurrentPlayerPosition()
970 if nc
and nc
~= -1 then -- We just want the raw data here, before we've done anything clever.
971 tc
, tx
, ty
= self
.Astrolabe
:GetAbsoluteContinentPosition(nc
, nz
, nx
, ny
)
972 QuestHelper
: Assert(tc
and tx
and ty
) -- is it true? nobody knows! :D
975 if nc
and nc
== self
.c
and map_shown_decay
> 0 and self
.z
> 0 and self
.z
~= nz
then
976 -- There's a chance Astrolable will return the wrong zone if you're messing with the world map, if you can
977 -- be seen in that zone but aren't in it.
978 local nnx
, nny
= self
.Astrolabe
:TranslateWorldMapPosition(nc
, nz
, nx
, ny
, nc
, self
.z
)
979 if nnx
> 0 and nny
> 0 and nnx
< 1 and nny
< 1 then
980 nz
, nx
, ny
= self
.z
, nnx
, nny
984 if nc
and nc
> 0 and nz
== 0 and nc
== self
.c
and self
.z
> 0 then
985 nx
, ny
= self
.Astrolabe
:TranslateWorldMapPosition(nc
, nz
, nx
, ny
, nc
, self
.z
)
986 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
989 nc
, nz
, nx
, ny
= nil, nil, nil, nil
993 if nc
and nz
> 0 then
994 self
.c
, self
.z
, self
.x
, self
.y
= nc
, nz
, nx
, ny
995 local upd_zone
= false
996 if self
.i
~= QuestHelper_IndexLookup
[nc
][nz
] then upd_zone
= true end
997 self
.i
= QuestHelper_IndexLookup
[nc
][nz
]
998 if upd_zone
then QH_Route_Filter_Rescan("filter_zone") end
1001 if nc
and nz
and nx
and ny
and tc
and tx
and ty
then
1002 self
.collect_rc
, self
.collect_rz
, self
.collect_rx
, self
.collect_ry
= nc
, nz
, nx
, ny
1003 self
.collect_ac
, self
.collect_ax
, self
.collect_ay
= tc
, tx
, ty
1004 self
.collect_delayed
= false
1006 local ibi
= self
.InBrokenInstance
1007 if nc
< -77 then self
.InBrokenInstance
= true else self
.InBrokenInstance
= false end
1009 if ibi
and not self
.InBrokenInstance
then self
.minimap_marker
:OnUpdate(0) end -- poke
1011 self
.collect_delayed
= true
1012 self
.InBrokenInstance
= true
1015 if not UnitOnTaxi("player") and not UnitIsDeadOrGhost("player") then
1016 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
1019 QH_Timeslice_Toggle("routing", not not self
.c
)
1021 self
:PumpCommMessages()
1025 -- 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.
1026 -- 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?
1027 function QuestHelper
:Location_RawRetrieve()
1028 return self
.collect_delayed
, self
.collect_rc
, self
.collect_rz
, self
.collect_rx
, self
.collect_ry
1030 function QuestHelper
:Location_AbsoluteRetrieve()
1031 return self
.collect_delayed
, self
.collect_ac
, self
.collect_ax
, self
.collect_ay
1034 --QH_Hook(QuestHelper, "OnEvent", QuestHelper.OnEvent)