well it appears to function
[QuestHelper.git] / help.lua
blobbf0485433824c13013bcccf6b04f59880d62fb8a
1 QuestHelper_File["help.lua"] = "Development Version"
2 QuestHelper_Loadtime["help.lua"] = GetTime()
4 local QuestHelper_Version = QuestHelper_File["help.lua"]
6 function QuestHelper:scaleString(val)
7 return self:HighlightText(math.floor(val*100+0.5).."%")
8 end
10 function QuestHelper:genericSetScale(varname, name, mn, mx, input, onchange, ...)
11 if input == "" then
12 self:TextOut(string.format("Current %s scale is %s.", name, self:scaleString(QuestHelper_Pref[varname])))
13 else
14 local scale = tonumber(input)
16 if not scale then
17 local x = string.match(input or "", "^%s*([%d%.]+)%s*%%%s*$")
18 scale = tonumber(x) or 0
19 if not scale then
20 self:TextOut("I don't know how to interpret your input.")
21 return
22 end
23 scale = scale * 0.01
24 end
26 if scale < mn then
27 self:TextOut(string.format("I won't accept a scale less than %s.", self:scaleString(mn)))
28 elseif scale > mx then
29 self:TextOut(string.format("I won't accept a scale more than %s.", self:scaleString(mx)))
30 else
31 QuestHelper_Pref[varname] = scale
32 self:TextOut(string.format("Set %s scale set to %s.", name, self:scaleString(scale)))
33 if onchange then
34 onchange(...)
35 end
36 end
37 end
38 end
40 function QuestHelper:TrackerScale(scale)
41 QuestHelper:genericSetScale("track_scale", "tracker scale", .5, 2, scale,
42 function() QuestHelper.tracker:SetScale(QuestHelper_Pref.track_scale) end)
43 end
45 function QuestHelper:SetLocale(loc)
46 if not loc or loc == "" then
47 self:TextOut(QHText("LOCALE_LIST_BEGIN"))
48 for loc, tbl in pairs(QuestHelper_Translations) do
49 self:TextOut(string.format(" %s%s %s", self:HighlightText(loc),
50 loc == QuestHelper_Pref.locale and " *" or " ",
51 tbl.LOCALE_NAME or "???"))
52 end
53 else
54 for l, tbl in pairs(QuestHelper_Translations) do
55 if string.find(string.lower(l), "^"..string.lower(loc)) or
56 string.find(string.lower(tbl.LOCALE_NAME or ""), "^"..string.lower(loc)) then
57 QuestHelper_Pref.locale = l
58 QHFormatSetLocale(l)
59 self:SetLocaleFonts()
60 self:TextOut(QHFormat("LOCALE_CHANGED", l))
61 return
62 end
63 end
65 self:TextOut(QHFormat("LOCALE_UNKNOWN", tostring(loc) or "UNKNOWN"))
66 end
67 end
69 function QuestHelper:ToggleHide()
70 QuestHelper_Pref.hide = not QuestHelper_Pref.hide
72 -- Desaturate the button texture if QuestHelper is disabled.
73 if self.MapButton then
74 -- This should always be true, but just in case...
75 self.MapButton:GetNormalTexture():SetDesaturated(QuestHelper_Pref.hide)
76 end
78 if QuestHelper_Pref.hide then
79 if QuestHelper_Pref.track then
80 self:HideTracker()
81 end
83 self.map_overlay:Hide()
84 self:TextOut("QuestHelper is now |cffff0000hidden|r.")
85 else
86 if QuestHelper_Pref.track then
87 self:ShowTracker()
88 end
90 self.map_overlay:Show()
91 self.minimap_marker:Show()
92 self:TextOut("QuestHelper is now |cff00ff00shown|r.")
94 QH_Timeslice_Bonus(20) -- Let the corutine do some overtime...
95 end
96 end
98 function QuestHelper:ToggleShare()
99 QuestHelper_Pref.share = not QuestHelper_Pref.share
100 if QuestHelper_Pref.share then
101 if QuestHelper_Pref.solo then
102 self:TextOut("Objective sharing will been |cff00ff00enabled|r when you disable solo mode.")
103 else
104 self:TextOut("Objective sharing has been |cff00ff00enabled|r.")
105 self:SetShare(true)
107 else
108 self:TextOut("Objective sharing has been |cffff0000disabled|r.")
109 if QuestHelper_Pref.solo then
110 self:TextOut("Objective sharing won't be reenabled when you disable solo mode.")
111 else
112 self:SetShare(false)
117 function QuestHelper:ToggleFlightTimes()
118 QuestHelper_Pref.flight_time = not QuestHelper_Pref.flight_time
119 if QuestHelper_Pref.flight_time then
120 self:TextOut("The flight timer has been |cff00ff00enabled|r.")
121 else
122 self:TextOut("The flight timer has been |cffff0000disabled|r.")
126 function QuestHelper:ToggleTrack()
127 QuestHelper_Pref.track = not QuestHelper_Pref.track
128 if QuestHelper_Pref.track then
129 self:ShowTracker()
130 self:TextOut("The quest tracker has been |cff00ff00enabled|r.")
131 else
132 self:HideTracker()
133 self:TextOut("The quest tracker has been |cffff0000disabled|r.")
137 function QuestHelper:ToggleTrackLevel()
138 QuestHelper_Pref.track_level = not QuestHelper_Pref.track_level
139 if QuestHelper_Pref.track_level then
140 self:TextOut("Display of levels in the quest tracker has been |cff00ff00enabled|r.")
141 else
142 self:TextOut("Display of levels in the quest tracker has been |cffff0000disabled|r.")
144 QH_UpdateQuests(true)
145 QH_Tracker_Rescan()
148 function QuestHelper:ToggleTrackQColour()
149 QuestHelper_Pref.track_qcolour = not QuestHelper_Pref.track_qcolour
150 if QuestHelper_Pref.track_qcolour then
151 self:TextOut("Colour for quest difficulty in quest tracker has been |cff00ff00enabled|r.")
152 else
153 self:TextOut("Colour for quest difficulty in quest tracker has been |cffff0000disabled|r.")
155 QH_UpdateQuests(true)
156 QH_Tracker_Rescan()
159 function QuestHelper:ToggleTrackOColour()
160 QuestHelper_Pref.track_ocolour = not QuestHelper_Pref.track_ocolour
161 if QuestHelper_Pref.track_ocolour then
162 self:TextOut("Colour for objective progress in quest tracker has been |cff00ff00enabled|r.")
163 else
164 self:TextOut("Colour for objective progress in quest tracker has been |cffff0000disabled|r.")
166 QH_UpdateQuests(true)
167 QH_Tracker_Rescan()
170 function QuestHelper:ToggleTooltip()
171 QuestHelper_Pref.tooltip = not QuestHelper_Pref.tooltip
172 if QuestHelper_Pref.tooltip then
173 self:TextOut("Objective tooltip information has been |cff00ff00enabled|r.")
174 else
175 self:TextOut("Objective tooltip information has been |cffff0000disabled|r.")
179 function QuestHelper:Purgewarning()
180 QuestHelper:TextOut("I would consider this a tragic loss, and would appreciate it if you sent me your saved data before going through with it.")
181 QuestHelper:TextOut("Enter "..self:HighlightText("/qh nag verbose").." to check and see if you're destroying anything important.")
182 QuestHelper:TextOut("Enter "..self:HighlightText("/qh submit").." for instructions on how to submit your collected data.")
183 QuestHelper:TextOut("See the "..self:HighlightText("How You Can Help").." section on the project website for instructions.")
186 function QuestHelper:Purge(code, force, noreload)
187 if code == self.purge_code or force then
188 QuestHelper_Quests = nil
189 QuestHelper_Objectives = nil
190 QuestHelper_FlightInstructors = nil
191 QuestHelper_FlightRoutes = nil
192 QuestHelper_Locale = nil
193 QuestHelper_UID = nil
194 QuestHelper_Version = nil
195 QuestHelper_SaveVersion = nil
197 QuestHelper_SaveDate = nil
198 QuestHelper_SeenRealms = nil
200 QuestHelper_Collector = nil
201 QuestHelper_Collector_Version = nil
203 if not noreload then ReloadUI() end
204 else
205 if not self.purge_code then self.purge_code = self:CreateUID(8) end
206 QuestHelper:TextOut("THIS COMMAND WILL DELETE ALL YOUR COLLECTED DATA")
207 QuestHelper:Purgewarning()
208 QuestHelper:TextOut("If you're sure you want to go through with this, enter: "..self:HighlightText("/qh purge "..self.purge_code))
212 function QuestHelper:HardReset(code)
213 if code == self.purge_code then
214 self:ResetTrackerPosition() -- do this before we kill off the prefs, since it touches a pref
215 QH_Arrow_Reset()
216 QuestHelper_Pref = nil
217 QuestHelper_ErrorList = nil -- BIZAM
218 QuestHelper_KnownFlightRoutes = nil
219 QuestHelper_Home = nil
220 QuestHelper_CharVersion = nil
221 self:Purge(nil, true)
222 else
223 if not self.purge_code then self.purge_code = self:CreateUID(8) end
224 QuestHelper:TextOut("THIS COMMAND WILL DELETE ALL YOUR COLLECTED DATA AND RESET ALL YOUR PREFERENCES")
225 QuestHelper:Purgewarning()
226 QuestHelper:TextOut("If you're sure you want to go through with this, enter: "..self:HighlightText("/qh hardreset "..self.purge_code))
230 function QuestHelper:ToggleSolo()
231 QuestHelper_Pref.solo = not QuestHelper_Pref.solo
232 if QuestHelper_Pref.solo then
233 if QuestHelper_Pref.share then
234 self:SetShare(false)
235 self:TextOut("Objective sharing has been temporarly |cffff0000disabled|r.")
237 self:TextOut("Solo mode has been |cff00ff00enabled|r.")
238 else
239 self:TextOut("Solo mode has been |cffff0000disabled|r.")
240 if QuestHelper_Pref.share then
241 self:SetShare(true)
242 self:TextOut("Objective sharing has been re|cff00ff00enabled|r.")
247 function QuestHelper:ToggleComm()
248 if QuestHelper_Pref.comm then
249 QuestHelper_Pref.comm = false
250 self:TextOut("Communication display has been |cffff0000disabled|r.")
251 else
252 QuestHelper_Pref.comm = true
253 self:TextOut("Communication display has been |cff00ff00enabled|r.")
257 function QuestHelper:ToggleAnts()
258 if QuestHelper_Pref.show_ants then
259 QuestHelper_Pref.show_ants = false
260 self:TextOut("Ant trails have been |cffff0000disabled|r.")
261 else
262 QuestHelper_Pref.show_ants = true
263 self:TextOut("Ant trails have been |cff00ff00enabled|r.")
267 function QuestHelper:LevelOffset(offset)
268 local level = tonumber(offset)
269 if level then
270 if level > 0 then
271 self:TextOut("Allowing quests up to "..self:HighlightText(level).." level"..(level==1 and " " or "s ")..self:HighlightText("above").." you.")
272 elseif level < 0 then
273 self:TextOut("Only allowing quests "..self:HighlightText(-level).." level"..(level==-1 and " " or "s ")..self:HighlightText("below").." you.")
274 else
275 self:TextOut("Only allowing quests "..self:HighlightText("at or below").." your current level.")
278 if not QuestHelper_Pref.filter_level then
279 self:TextOut("Note: This won't have any effect until you turn the level filter on.")
282 if QuestHelper_Pref.level ~= level then
283 QuestHelper_Pref.level = level
284 QH_Route_Filter_Rescan("filter_quest_level")
286 elseif offset == "" then
287 if QuestHelper_Pref.level <= 0 then
288 self:TextOut("Level offset is currently set to "..self:HighlightText(QuestHelper_Pref.level)..".")
289 else
290 self:TextOut("Level offset is currently set to "..self:HighlightText("+"..QuestHelper_Pref.level)..".")
293 if self.party_levels then for n, l in ipairs(self.party_levels) do
294 self:TextOut("Your effective level in a "..self:HighlightText(n).." player quest is "..self:HighlightText(string.format("%.1f", l))..".")
295 end end
297 if QuestHelper_Pref.solo then
298 self:TextOut("Peers aren't considered in your effective level, because you're playing solo.")
300 else
301 self:TextOut("Expected a level offset.")
305 function QuestHelper:Filter(input)
306 input = string.upper(input)
307 if input == "ZONE" then
308 QuestHelper_Pref.filter_zone = not QuestHelper_Pref.filter_zone
309 self:TextOut("Filter "..self:HighlightText("zone").." set to "..self:HighlightText(QuestHelper_Pref.filter_zone and "active" or "inactive")..".")
310 QH_Route_Filter_Rescan("filter_zone")
311 elseif input == "DONE" then
312 QuestHelper_Pref.filter_done = not QuestHelper_Pref.filter_done
313 self:TextOut("Filter "..self:HighlightText("done").." set to "..self:HighlightText(QuestHelper_Pref.filter_done and "active" or "inactive")..".")
314 QH_Route_Filter_Rescan("filter_quest_done")
315 elseif input == "LEVEL" then
316 QuestHelper_Pref.filter_level = not QuestHelper_Pref.filter_level
317 self:TextOut("Filter "..self:HighlightText("level").." set to "..self:HighlightText(QuestHelper_Pref.filter_level and "active" or "inactive")..".")
318 QH_Route_Filter_Rescan("filter_quest_level")
319 elseif input == "BLOCKED" or input == "BLOCK" then
320 QuestHelper_Pref.filter_blocked = not QuestHelper_Pref.filter_blocked
321 self:TextOut("Filter "..self:HighlightText("blocked").." set to "..self:HighlightText(QuestHelper_Pref.filter_blocked and "active" or "inactive")..".")
322 QH_Route_Filter_Rescan("filter_blocked")
323 elseif input == "WATCHED" or input == "WATCH" then
324 QuestHelper_Pref.filter_watched = not QuestHelper_Pref.filter_watched
325 self:TextOut("Filter "..self:HighlightText("watched").." set to "..self:HighlightText(QuestHelper_Pref.filter_watched and "active" or "inactive")..".")
326 QH_Route_Filter_Rescan("filter_quest_watched")
327 elseif input == "" then
328 self:TextOut("Filter "..self:HighlightText("zone")..": "..self:HighlightText(QuestHelper_Pref.filter_zone and "active" or "inactive"))
329 self:TextOut("Filter "..self:HighlightText("level")..": "..self:HighlightText(QuestHelper_Pref.filter_level and "active" or "inactive"))
330 self:TextOut("Filter "..self:HighlightText("done")..": "..self:HighlightText(QuestHelper_Pref.filter_done and "active" or "inactive"))
331 self:TextOut("Filter "..self:HighlightText("blocked")..": "..self:HighlightText(QuestHelper_Pref.filter_blocked and "active" or "inactive"))
332 self:TextOut("Filter "..self:HighlightText("watched")..": "..self:HighlightText(QuestHelper_Pref.filter_watched and "active" or "inactive"))
333 else
334 self:TextOut("Don't know what you want filtered, expect "..self:HighlightText("zone")..", "..self:HighlightText("done")..", "..self:HighlightText("level")..", "..self:HighlightText("blocked")..", or "..self:HighlightText("watched")..".")
338 function QuestHelper:ToggleArrow(text)
339 if text == "reset" then QH_Arrow_Reset() return end
341 QuestHelper_Pref.arrow = not QuestHelper_Pref.arrow
342 if QuestHelper_Pref.arrow then
343 QH_Arrow_Show()
344 self:TextOut(QHFormat("SETTINGS_ARROWLINK_ON", QHText("SETTINGS_ARROWLINK_ARROW")))
345 else
346 self:TextOut(QHFormat("SETTINGS_ARROWLINK_OFF", QHText("SETTINGS_ARROWLINK_ARROW")))
350 function QuestHelper:ToggleCartWP()
351 QuestHelper_Pref.cart_wp_new = not QuestHelper_Pref.cart_wp_new
352 if QuestHelper_Pref.cart_wp_new then
353 self:EnableCartographer()
354 if Cartographer_Waypoints then
355 if Waypoint and Waypoint.prototype then
356 self:TextOut("Would use "..self:HighlightText("Cartographer Waypoints").." to show objectives, but another mod is interfering with it.")
357 else
358 self:TextOut(QHFormat("SETTINGS_ARROWLINK_ON", QHText("SETTINGS_ARROWLINK_CART")))
360 else
361 self:TextOut("Would use "..self:HighlightText("Cartographer Waypoints").." to show objectives, except it doesn't seem to be present.")
363 else
364 self:DisableCartographer()
365 self:TextOut(QHFormat("SETTINGS_ARROWLINK_OFF", QHText("SETTINGS_ARROWLINK_CART")))
369 function QuestHelper:ToggleTomTomWP()
370 QuestHelper_Pref.tomtom_wp_new = not QuestHelper_Pref.tomtom_wp_new
371 if QuestHelper_Pref.tomtom_wp_new then
372 self:EnableTomTom()
373 if TomTom then
374 self:TextOut(QHFormat("SETTINGS_ARROWLINK_ON", QHText("SETTINGS_ARROWLINK_TOMTOM")))
375 else
376 self:TextOut("Would use "..self:HighlightText("TomTom").." to show objectives, except it doesn't seem to be present.")
378 else
379 self:DisableTomTom()
380 self:TextOut(QHFormat("SETTINGS_ARROWLINK_OFF", QHText("SETTINGS_ARROWLINK_TOMTOM")))
384 function QuestHelper:WantPathingReset()
385 self:TextOut("Will reset world graph.")
386 self.defered_graph_reset = true
389 function QuestHelper:PrintVersion()
390 self:TextOut("Version: "..self:HighlightText(GetAddOnMetadata("QuestHelper", "Version") or "Unknown"))
393 local function RecycleStatusString(fmt, usedcount, freetable, usedtable)
394 local freetablecount = QuestHelper:TableSize(freetable)
395 if usedtable then
396 local usedtablecount = QuestHelper:TableSize(usedtable)
397 return string.format(fmt, QuestHelper:ProgressString(string.format("%d/%d", usedtablecount, usedtablecount+freetablecount), ((usedtablecount+freetablecount == 0) and 1) or (1-usedtablecount/(usedtablecount+freetablecount)))) .. string.format(" (%d \"leaked\")", usedcount - usedtablecount)
398 else
399 return string.format(fmt, QuestHelper:ProgressString(string.format("%d/%d", usedcount, usedcount+freetablecount), ((usedcount+freetablecount == 0) and 1) or (1-usedcount/(usedcount+freetablecount))))
403 function QuestHelper:Top(cmd)
404 if cmd and string.find(cmd, "all") then
405 cmd = cmd .. " collected recycle clear boot usage"
408 if cmd and string.find(cmd, "boot") then
409 local bootv = {}
410 for k, v in pairs(QuestHelper_Loadtime) do
411 table.insert(bootv, {time = v, file = k})
413 table.sort(bootv, function (a, b) return a.time < b.time end)
415 if string.find(cmd, "sort") then
416 local boott = {}
417 for i = 1, #bootv - 1 do
418 table.insert(boott, {time = bootv[i + 1].time - bootv[i].time, file = bootv[i].file})
420 table.sort(boott, function(a, b) return a.time < b.time end)
422 for _, v in pairs(boott) do
423 QuestHelper:TextOut(string.format("%s: %f", v.file, v.time))
425 QuestHelper:TextOut(string.format("%s: shrug", bootv[#bootv].file))
426 else
427 for i = 1, #bootv do
428 QuestHelper:TextOut(string.format("%f: %s", bootv[i].time - bootv[1].time, bootv[i].file))
433 local pre_ttf
434 local pre_db
435 if cmd and string.find(cmd, "collected") then
436 pre_ttf = self:DumpTableTypeFrequencies(true)
437 pre_db = DB_DumpItems()
440 if cmd and string.find(cmd, "recycle") then
441 self:DumpTableTypeFrequencies()
442 self:TextOut(RecycleStatusString("Using %s lua tables.", self.used_tables, self.free_tables, self.recycle_tabletyping))
443 self:TextOut(RecycleStatusString("Using %s texture objects.", self.used_textures, self.free_textures))
444 self:TextOut(RecycleStatusString("Using %s font objects.", self.used_text, self.free_text))
445 self:TextOut(RecycleStatusString("Using %s frame objects.", self.used_frames, self.free_frames))
448 if cmd and string.find(cmd, "usage") then
449 self:DumpTableTypeFrequencies()
452 if cmd and string.find(cmd, "cache") then
453 self:DumpCacheData()
456 if cmd and string.find(cmd, "perf") then
457 QH_Timeslice_DumpPerf()
460 local uncd = 0
461 for k, v in pairs(QuestHelper_Collector) do
462 if not v.compressed then uncd = uncd + 1 end
464 uncd = uncd - 1
465 local uncs = ""
466 if uncd > 0 then
467 uncs = string.format(" (%d uncompressed IDs)", uncd)
470 UpdateAddOnMemoryUsage()
471 local pre_gc = GetAddOnMemoryUsage("QuestHelper")
473 collectgarbage("collect")
475 UpdateAddOnMemoryUsage()
476 local post_gc = GetAddOnMemoryUsage("QuestHelper")
478 if cmd and string.find(cmd, "collected") then
479 local post_ttf = self:DumpTableTypeFrequencies(true)
481 local union = {}
482 for k, v in pairs(pre_ttf) do union[k] = (pre_ttf[k] or 0) - (post_ttf[k] or 0) end
483 for k, v in pairs(post_ttf) do union[k] = (pre_ttf[k] or 0) - (post_ttf[k] or 0) end
485 local sorted = {}
486 for k, v in pairs(union) do
487 table.insert(sorted, {k = k, d = v})
490 table.sort(sorted, function(a, b) return a.d < b.d end)
491 for _, v in pairs(sorted) do
492 if v.d > 0 then
493 QuestHelper:TextOut(string.format("%d: %s", v.d, v.k))
497 local post_db = DB_DumpItems()
499 local st = {}
500 for k, v in pairs(pre_db) do
501 if not post_db[k] then
502 table.insert(st, k)
505 table.sort(st)
507 for _, v in ipairs(st) do
508 QuestHelper:TextOut("DB: " .. v)
512 self:TextOut(string.format("QuestHelper is using %dkb (pre-collect %dkb) of RAM (%s/%s/%s/%s)%s", post_gc, pre_gc, QuestHelper_local_version, QuestHelper_toc_version, GetBuildInfo(), GetLocale(), uncs))
514 if cmd and string.find(cmd, "clear") then
515 local cleared = QH_ClearPathcache()
517 collectgarbage("collect")
518 UpdateAddOnMemoryUsage()
519 local new_post_gc = GetAddOnMemoryUsage("QuestHelper")
520 self:TextOut(string.format("QuestHelper is using %dkb/%dkb/%dkb (%d pathcache cleared) of RAM (%s/%s/%s/%s)%s", pre_gc, post_gc, new_post_gc, cleared, QuestHelper_local_version, QuestHelper_toc_version, GetBuildInfo(), GetLocale(), uncs))
522 local cleared = QuestHelper:RecycleClear()
524 collectgarbage("collect")
525 UpdateAddOnMemoryUsage()
526 local new_post_gc_2 = GetAddOnMemoryUsage("QuestHelper")
527 self:TextOut(string.format("QuestHelper is using %dkb/%dkb/%dkb/%dkb (%d recycle cleared) of RAM (%s/%s/%s/%s)%s", pre_gc, post_gc, new_post_gc, new_post_gc_2, cleared, QuestHelper_local_version, QuestHelper_toc_version, GetBuildInfo(), GetLocale(), uncs))
531 function QuestHelper:ToggleMapButton()
532 QuestHelper_Pref.map_button = not QuestHelper_Pref.map_button
534 if QuestHelper_Pref.map_button then
535 QuestHelper:InitMapButton()
536 self:TextOut("Map button has been |cff00ff00enabled|r.")
537 else
538 QuestHelper:HideMapButton()
539 self:TextOut("Map button has been |cffff0000disabled|r. Use '/qh button' to restore it.")
543 function QuestHelper:ChangeLog()
544 self:ShowText(QuestHelper_ChangeLog, string.format("QuestHelper %s ChangeLog", QuestHelper_Version))
547 function QuestHelper:Submit()
548 self:ShowText([[
549 |TInterface\AddOns\QuestHelper\Art\Upload.tga:100:300|t
550 Your data can't be submitted automatically, since AddOns can't interact with anything outside of World of Warcraft.
552 To do this would require me to create some third party software, and I don't want to include such software with QuestHelper, because that's the kind of thing that ill intended people are likely to tamper with.
554 World of Warcraft stores QuestHelper's data in a file named |cff40bbffQuestHelper.lua|r.
556 To find this file, first find the the directory you installed World of Warcraft to. In Windows, this defaults to |cff40bbffC:\Program Files\World of Warcraft|r, and on Mac, I believe this is |cff40bbff/Applications/World of Warcraft|r.
558 If you're using Windows Vista, Windows might protect the Program Files directory from changes, and redirect Warcraft's saved data to |cff40bbffC:\Users\|cffff8000USER|cff40bbff\AppData\Local\VirtualStore\Program Files\World of Warcraft|r, or possibly |cff40bbffC:\Users\Public\Games\World of Warcraft|r.
560 In that directory, the needed file is in |cff40bbffWTF/Account/|cffff8000ACCOUNT|cff40bbff/SavedVariables|r, replacing ACCOUNT with the name of your account, and in that directory, you should find |cff40bbffQuestHelper.lua|r.
562 There are other directories with the names of the realms where your characters are stored, |cffffff00but don't enter them|r. They contain information specific to your characters, such as the flight points they know about, and don't contain the quest information I want.
564 After you find |cff40bbffQuestHelper.lua|r, you can email it to me here: |cff40bbffqhaddon@gmail.com|r
565 ]], "How To Submit Your Data")
568 function QuestHelper:ShowError(params)
569 if params and params == "full" then
570 QuestHelper_ErrorCatcher_GenerateReport()
572 QuestHelper_ErrorCatcher_ReportError()
575 local commands
577 function QuestHelper:Help(argument)
578 local text = ""
579 local argument = argument and argument:upper() or ""
581 for i1, cat in ipairs(commands) do
582 text = string.format("%s|cffffff00%s|r\n\n", text, cat[1])
583 for i, data in ipairs(cat[2]) do
584 if data[1]:find(argument, 1, true) then
585 text = string.format("%s |cffff8000%s|r %s\n", text, data[1], data[2])
587 if #data[3] > 0 then
588 text = string.format("%s\n %s\n", text, #data[3] == 1 and "Example:" or "Examples:")
589 for i, pair in ipairs(data[3]) do
590 text = string.format("%s |cff40bbff%s|r\n %s\n", text, pair[1], pair[2])
594 text = text .. "\n"
597 text = text .. "\n\n"
600 self:ShowText(text == "" and ("No commands containing '"..argument.."'") or text, "QuestHelper Slash Commands")
603 function QuestHelper:Donate(argument)
604 local text = ""
605 local argument = argument and argument:upper() or ""
607 for i1, cat in ipairs(commands) do
608 text = string.format("%s|cffffff00%s|r\n\n", text, cat[1])
609 for i, data in ipairs(cat[2]) do
610 if data[1]:find(argument, 1, true) then
611 text = string.format("%s |cffff8000%s|r %s\n", text, data[1], data[2])
613 if #data[3] > 0 then
614 text = string.format("%s\n %s\n", text, #data[3] == 1 and "Example:" or "Examples:")
615 for i, pair in ipairs(data[3]) do
616 text = string.format("%s |cff40bbff%s|r\n %s\n", text, pair[1], pair[2])
620 text = text .. "\n"
623 text = text .. "\n\n"
626 self:ShowText([[
627 QuestHelper currently survives on |cffff8000your donations|r. I'm trying to make this into a full-time job so I can add more features and fix bugs, and I can't do that without paying the bills.
629 There's a lot of stuff I plan to add if I can get enough donations to live off. Some of the most-requested features include:
631 |cff40bbffReduced memory and CPU usage for smoother gameplay|r
633 |cff40bbffFlying mount support for both Northrend and Outland|r
635 |cff40bbffBetter support for Northrend "phased" quests|r
637 |cff40bbffAchievementHelper, built right into QuestHelper|r
639 |cff40bbffPaths that lead you around obstacles instead of through them|r
641 I can't guarantee these will show up soon, as there's a lot of work involved in them, but every donation - no matter how small - helps!
643 To donate, open up your web browser and go to |cffff8000http://www.quest-helper.com/donate|r. Enter however much you feel comfortable donating, then bask in the knowledge that you're supporting QuestHelper.
645 Thanks!]], "Please Donate!", 500, 20, 10)
648 commands =
650 { "Common commands", {
651 {"HIDDEN",
652 "Compiles a list of objectives that QuestHelper is hiding from you. Depending on the reason, you can also unhide the objective.",
653 {}, QH_Hidden_Menu},
655 {"HIDE",
656 "Hides QuestHelper's modifications to the minimap and world map, and pauses routing calculations.",
657 {}, QuestHelper.ToggleHide, QuestHelper},
659 {"ARROW",
660 "Toggles Questhelper's built-in directional arrow.",
661 {{"/qh arrow reset", "Reset location to the center of the screen."}},
662 QuestHelper.ToggleArrow, QuestHelper},
664 {"CARTWP",
665 "Toggles displaying the current objective using Cartographer Waypoints (must be installed separately).",
666 {}, QuestHelper.ToggleCartWP, QuestHelper},
668 {"TOMTOM",
669 "Toggles displaying the current objective using TomTom (must be installed separately).",
670 {}, QuestHelper.ToggleTomTomWP, QuestHelper},
672 {"FIND",
673 "Search for an item, location, or npc.",
674 {{"/qh find item rune of teleport", "Finds a reagent vendor."},
675 {"/qh find npc bragok", "Finds the Ratchet flight point."},
676 {"/qh find loc stormwind 50 60", "Finds the Stormwind auction house."},
677 {"/qh find loc 50 50", "Finds the center of the zone you're in."},
678 {"/qh find something", "Searches for something in all categories."},
679 {"/qh find", "Lists objectives you manually created so that you can remove them."}}, QuestHelper.PerformSearch, QuestHelper},
681 {"SOLO",
682 "Toggles solo mode. When enabled, assumes your party members don't exist. Objective sharing with party members will also be disabled.",
683 {}, QuestHelper.ToggleSolo, QuestHelper},
686 { "Objective filtering", {
687 {"FILTER",
688 "Automatically ignores/unignores objectives based on criteria.",
689 {{"/qh filter zone", "Toggle showing objectives outside the current zone"},
690 {"/qh filter done", "Toggle showing objectives for uncompleted quests."},
691 {"/qh filter level", "Toggle showing objectives that are probably too hard, by considering the levels of you and your party members, and the offset set by the level command."},
692 {"/qh filter blocked", "Toggle showing blocked objectives, such as quest turn-ins for incomplete quests."},
693 {"/qh filter watched", "Toggle limiting to objectives watched in the Quest Log"}
694 }, QuestHelper.Filter, QuestHelper},
696 {"LEVEL",
697 "Adjusts the level offset used by the level filter. Naturally, the level filter must be turned on to have an effect.",
698 {{"/qh level", "See information related to the level filter."},
699 {"/qh level 0", "Only allow objectives at or below your current level."},
700 {"/qh level +2", "Allow objectives up to two levels above your current level."},
701 {"/qh level -1", "Only allow objectives below your current level."}}, QuestHelper.LevelOffset, QuestHelper},
703 {"SCALE",
704 "Scales the map icons used by QuestHelper. Will accept values between 50% and 300%.",
705 {{"/qh scale 1", "Uses the default icon size."},
706 {"/qh scale 2", "Makes icons twice their default size."},
707 {"/qh scale 80%", "Makes icons slightly smaller than their default size."}},
708 QuestHelper.genericSetScale, QuestHelper, "scale", "icon scale", .5, 3},
710 {"SHARE",
711 "Toggles objective sharing between QuestHelper users.",
712 {}, QuestHelper.ToggleShare, QuestHelper},
715 { "Interface", {
716 {"TRACK",
717 "Toggles the visibility of the QuestHelper's replacement quest tracker.",
718 {}, QuestHelper.ToggleTrack, QuestHelper},
720 {"TSCALE",
721 "Scales the quest tracker provided by QuestHelper. Will accept values between 50% and 300%.",
723 QuestHelper.TrackerScale, QuestHelper},
725 {"TRESET",
726 "Reset's the position of the quest tracker provided by QuestHelper, in cause you move it somewhere inaccessable.",
727 {{"/qh treset center", "Resets to the center of the screen, instead of a more normal quest tracker location."}}, QuestHelper.ResetTrackerPosition, QuestHelper},
729 {"TLEVEL",
730 "Toggles display of levels in the quest tracker provided by QuestHelper.",
731 {}, QuestHelper.ToggleTrackLevel, QuestHelper},
733 {"TQCOL",
734 "Toggles display of colours for the difficulty level of quests in the quest tracker provided by QuestHelper.",
735 {}, QuestHelper.ToggleTrackQColour, QuestHelper},
737 {"TOCOL",
738 "Toggles display of colours for objective progress in the quest tracker provided by QuestHelper.",
739 {}, QuestHelper.ToggleTrackOColour, QuestHelper},
741 {"TOOLTIP",
742 "Toggles appending information about tracked items and NPCs to their tooltips.",
743 {}, QuestHelper.ToggleTooltip, QuestHelper},
745 {"FTIME",
746 "Toggles display of flight time estimates.", {}, QuestHelper.ToggleFlightTimes, QuestHelper},
748 {"ANTS",
749 "Toggles the display of trails on the world map on and off.",
750 {}, QuestHelper.ToggleAnts, QuestHelper},
752 {"LOCALE",
753 "Select the locale to use for displayed messages.",
754 {}, QuestHelper.SetLocale, QuestHelper},
756 {"BUTTON",
757 "Toggles the display of QuestHelper's button on the world map.",
758 {}, QuestHelper.ToggleMapButton, QuestHelper},
760 {"SETTINGS",
761 "Opens the Settings menu at the current cursor location. Note that not all settings can be changed through the menu.",
762 {}, QuestHelper.DoSettingsMenu, QuestHelper},
765 { "Data collection", {
766 {"SUBMIT",
767 "Displays instructions for submitting your collected data.",
768 {}, QuestHelper.Submit, QuestHelper},
770 {"NAG",
771 "Tells you if you have anything that's missing from the static database. It can only check quests from your own faction, as the quests of your opposing faction are ommitted to save memory.",
772 {{"/qh nag verbose", "Prints the specific changes that were found."}}, QuestHelper.Nag, QuestHelper},
774 {"PURGE",
775 "Deletes all QuestHelper's collected data.", {}, QuestHelper.Purge, QuestHelper},
777 {"HARDRESET",
778 "Deletes all QuestHelper's collected data and resets QuestHelper preferences.", {}, QuestHelper.HardReset, QuestHelper},
781 { "Performance and debug", {
782 {"PERF",
783 "Sets or shows the route workload. Higher means more agressive route updating, lower means better performance Accepts numbers between 10% and 500%.",
784 {{"/qh perf", "Show current Performance Factor"},
785 {"/qh perf 1", "Sets standard performance"},
786 {"/qh perf 50%", "Does half as much background processing"},
787 {"/qh perf 3", "Computes routes 3 times more aggressively. Better have some good horsepower!"}},
788 QuestHelper.genericSetScale, QuestHelper, "perf_scale", "performance factor", .1, 5},
790 {"PERFLOAD",
791 "Sets or shows the initialization workload. Higher numbers will make QuestHelper load faster, lower numbers will result in better framerate while it's loading.",
792 {{"/qh perfload", "Show current Performance Factor"},
793 {"/qh perfload 1", "Sets standard performance"},
794 {"/qh perfload 50%", "Does half as much background processing"},
795 {"/qh perfload 3", "Loads 3 times as quickly."}},
796 QuestHelper.genericSetScale, QuestHelper, "perfload_scale", "boot performance factor", .2, 5},
798 {"TOP",
799 "Displays various performance stats on QuestHelper.",
801 {"/qh top recycle", "Displays detailed information on QuestHelper's recycled item pools"},
802 {"/qh top usage", "Displays detailed information on which table types are most common"},
803 {"/qh top cache", "Displays detailed information on the internal distance cache"},
804 {"/qh top perf", "Displays detailed information on coroutine CPU usage"},
805 }, QuestHelper.Top, QuestHelper},
807 {"ERROR",
808 "Displays the first QuestHelper error that has been generated this session in a form which can be copied out of WoW.",
809 {}, QuestHelper.ShowError, QuestHelper},
811 {"POS",
812 "Prints the player's current position. Exists mainly for my own personal convenience.",
813 {}, function (qh) qh:TextOut(qh:LocationString(qh.i, qh.x, qh.y) .. " " .. qh:Location_RawString(qh:Location_RawRetrieve()) .. " " .. qh:Location_AbsoluteString(qh:Location_AbsoluteRetrieve())) end, QuestHelper},
815 {"COMM",
816 "Toggles showing of the communication between QuestHelper users. Exists mainly for my own personal convenience.",
817 {}, QuestHelper.ToggleComm, QuestHelper},
819 {"RECALC",
820 "Recalculates the world graph and locations for any active objectives. Should not be necessary.", {}, QuestHelper.WantPathingReset, QuestHelper},
823 { "Help", {
824 {"HELP",
825 "Displays a list of help commands. Listed commands are filtered by the passed string.",
826 {}, QuestHelper.Help, QuestHelper},
828 {"VERSION",
829 "Displays QuestHelper's version.", {}, QuestHelper.PrintVersion, QuestHelper},
831 {"CHANGES",
832 "Displays a summary of changes recently made to QuestHelper.",
833 {}, QuestHelper.ChangeLog, QuestHelper},
835 --[[{"DONATE",
836 "Displays some instructions and a link for donating.",
837 {}, QuestHelper.Donate, QuestHelper},]]
841 function QuestHelper_SlashCommand(input)
842 local _, _, command, argument = string.find(input, "^%s*([^%s]-)%s+(.-)%s*$")
843 if not command then
844 command, argument = input, ""
847 command = string.upper(command)
849 for i1, cat in ipairs(commands) do
850 for i, data in ipairs(cat[2]) do
851 if data[1] == command then
852 local st = {}
854 for i = 5,#data do table.insert(st, data[i]) end
855 table.insert(st, argument)
857 if type(data[4]) == "function" then
858 data[4](unpack(st))
859 else
860 QuestHelper:TextOut(data[1].." is not yet implemented.")
863 return
868 QuestHelper:Help()
871 SLASH_QuestHelper1 = "/qh"
872 SLASH_QuestHelper2 = "/questhelper"
873 SlashCmdList["QuestHelper"] = function (text) QuestHelper_SlashCommand(text) end