update changes
[QuestHelper.git] / help.lua
blob7e4f9126e7f0e99bae96cdcb5bf33412cc265926
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 self:TextOut("Objective sharing is currently broken. Zorba will make it work again once he can.")
100 do return end
102 QuestHelper_Pref.share = not QuestHelper_Pref.share
103 if QuestHelper_Pref.share then
104 if QuestHelper_Pref.solo then
105 self:TextOut("Objective sharing will been |cff00ff00enabled|r when you disable solo mode.")
106 else
107 self:TextOut("Objective sharing has been |cff00ff00enabled|r.")
108 self:EnableSharing()
110 else
111 self:TextOut("Objective sharing has been |cffff0000disabled|r.")
112 if QuestHelper_Pref.solo then
113 self:TextOut("Objective sharing won't be reenabled when you disable solo mode.")
114 else
115 self:DisableSharing()
120 function QuestHelper:ToggleFlightTimes()
121 QuestHelper_Pref.flight_time = not QuestHelper_Pref.flight_time
122 if QuestHelper_Pref.flight_time then
123 self:TextOut("The flight timer has been |cff00ff00enabled|r.")
124 else
125 self:TextOut("The flight timer has been |cffff0000disabled|r.")
129 function QuestHelper:ToggleTrack()
130 QuestHelper_Pref.track = not QuestHelper_Pref.track
131 if QuestHelper_Pref.track then
132 self:ShowTracker()
133 self:TextOut("The quest tracker has been |cff00ff00enabled|r.")
134 else
135 self:HideTracker()
136 self:TextOut("The quest tracker has been |cffff0000disabled|r.")
140 function QuestHelper:ToggleTrackLevel()
141 QuestHelper_Pref.track_level = not QuestHelper_Pref.track_level
142 if QuestHelper_Pref.track_level then
143 self:TextOut("Display of levels in the quest tracker has been |cff00ff00enabled|r.")
144 else
145 self:TextOut("Display of levels in the quest tracker has been |cffff0000disabled|r.")
147 QH_UpdateQuests(true)
148 QH_Tracker_Rescan()
151 function QuestHelper:ToggleTrackQColour()
152 QuestHelper_Pref.track_qcolour = not QuestHelper_Pref.track_qcolour
153 if QuestHelper_Pref.track_qcolour then
154 self:TextOut("Colour for quest difficulty in quest tracker has been |cff00ff00enabled|r.")
155 else
156 self:TextOut("Colour for quest difficulty in quest tracker has been |cffff0000disabled|r.")
158 QH_UpdateQuests(true)
159 QH_Tracker_Rescan()
162 function QuestHelper:ToggleTrackOColour()
163 QuestHelper_Pref.track_ocolour = not QuestHelper_Pref.track_ocolour
164 if QuestHelper_Pref.track_ocolour then
165 self:TextOut("Colour for objective progress in quest tracker has been |cff00ff00enabled|r.")
166 else
167 self:TextOut("Colour for objective progress in quest tracker has been |cffff0000disabled|r.")
169 QH_UpdateQuests(true)
170 QH_Tracker_Rescan()
173 function QuestHelper:ToggleTooltip()
174 QuestHelper_Pref.tooltip = not QuestHelper_Pref.tooltip
175 if QuestHelper_Pref.tooltip then
176 self:TextOut("Objective tooltip information has been |cff00ff00enabled|r.")
177 else
178 self:TextOut("Objective tooltip information has been |cffff0000disabled|r.")
182 function QuestHelper:Purgewarning()
183 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.")
184 QuestHelper:TextOut("Enter "..self:HighlightText("/qh nag verbose").." to check and see if you're destroying anything important.")
185 QuestHelper:TextOut("Enter "..self:HighlightText("/qh submit").." for instructions on how to submit your collected data.")
186 QuestHelper:TextOut("See the "..self:HighlightText("How You Can Help").." section on the project website for instructions.")
189 function QuestHelper:Purge(code, force, noreload)
190 if code == self.purge_code or force then
191 QuestHelper_Quests = nil
192 QuestHelper_Objectives = nil
193 QuestHelper_FlightInstructors = nil
194 QuestHelper_FlightRoutes = nil
195 QuestHelper_Locale = nil
196 QuestHelper_UID = nil
197 QuestHelper_Version = nil
198 QuestHelper_SaveVersion = nil
200 QuestHelper_SaveDate = nil
201 QuestHelper_SeenRealms = nil
203 QuestHelper_Collector = nil
204 QuestHelper_Collector_Version = nil
206 if not noreload then ReloadUI() end
207 else
208 if not self.purge_code then self.purge_code = self:CreateUID(8) end
209 QuestHelper:TextOut("THIS COMMAND WILL DELETE ALL YOUR COLLECTED DATA")
210 QuestHelper:Purgewarning()
211 QuestHelper:TextOut("If you're sure you want to go through with this, enter: "..self:HighlightText("/qh purge "..self.purge_code))
215 function QuestHelper:HardReset(code)
216 if code == self.purge_code then
217 self:ResetTrackerPosition() -- do this before we kill off the prefs, since it touches a pref
218 QH_Arrow_Reset()
219 QuestHelper_Pref = nil
220 QuestHelper_ErrorList = nil -- BIZAM
221 QuestHelper_KnownFlightRoutes = nil
222 QuestHelper_Home = nil
223 QuestHelper_CharVersion = nil
224 self:Purge(nil, true)
225 else
226 if not self.purge_code then self.purge_code = self:CreateUID(8) end
227 QuestHelper:TextOut("THIS COMMAND WILL DELETE ALL YOUR COLLECTED DATA AND RESET ALL YOUR PREFERENCES")
228 QuestHelper:Purgewarning()
229 QuestHelper:TextOut("If you're sure you want to go through with this, enter: "..self:HighlightText("/qh hardreset "..self.purge_code))
233 function QuestHelper:ToggleSolo()
234 QuestHelper_Pref.solo = not QuestHelper_Pref.solo
235 if QuestHelper_Pref.solo then
236 if QuestHelper_Pref.share then
237 self:DisableSharing()
238 self:TextOut("Objective sharing has been temporarly |cffff0000disabled|r.")
240 self:TextOut("Solo mode has been |cff00ff00enabled|r.")
241 else
242 self:TextOut("Solo mode has been |cffff0000disabled|r.")
243 if QuestHelper_Pref.share then
244 self:EnableSharing()
245 self:TextOut("Objective sharing has been re|cff00ff00enabled|r.")
250 function QuestHelper:ToggleComm()
251 if QuestHelper_Pref.comm then
252 QuestHelper_Pref.comm = false
253 self:TextOut("Communication display has been |cffff0000disabled|r.")
254 else
255 QuestHelper_Pref.comm = true
256 self:TextOut("Communication display has been |cff00ff00enabled|r.")
260 function QuestHelper:ToggleAnts()
261 if QuestHelper_Pref.show_ants then
262 QuestHelper_Pref.show_ants = false
263 self:TextOut("Ant trails have been |cffff0000disabled|r.")
264 else
265 QuestHelper_Pref.show_ants = true
266 self:TextOut("Ant trails have been |cff00ff00enabled|r.")
270 function QuestHelper:LevelOffset(offset)
271 local level = tonumber(offset)
272 if level then
273 if level > 0 then
274 self:TextOut("Allowing quests up to "..self:HighlightText(level).." level"..(level==1 and " " or "s ")..self:HighlightText("above").." you.")
275 elseif level < 0 then
276 self:TextOut("Only allowing quests "..self:HighlightText(-level).." level"..(level==-1 and " " or "s ")..self:HighlightText("below").." you.")
277 else
278 self:TextOut("Only allowing quests "..self:HighlightText("at or below").." your current level.")
281 if not QuestHelper_Pref.filter_level then
282 self:TextOut("Note: This won't have any effect until you turn the level filter on.")
285 if QuestHelper_Pref.level ~= level then
286 QuestHelper_Pref.level = level
287 QH_Route_Filter_Rescan("filter_quest_level")
289 elseif offset == "" then
290 if QuestHelper_Pref.level <= 0 then
291 self:TextOut("Level offset is currently set to "..self:HighlightText(QuestHelper_Pref.level)..".")
292 else
293 self:TextOut("Level offset is currently set to "..self:HighlightText("+"..QuestHelper_Pref.level)..".")
296 if self.party_levels then for n, l in ipairs(self.party_levels) do
297 self:TextOut("Your effective level in a "..self:HighlightText(n).." player quest is "..self:HighlightText(string.format("%.1f", l))..".")
298 end end
300 if QuestHelper_Pref.solo then
301 self:TextOut("Peers aren't considered in your effective level, because you're playing solo.")
303 else
304 self:TextOut("Expected a level offset.")
308 function QuestHelper:Filter(input)
309 input = string.upper(input)
310 if input == "ZONE" then
311 QuestHelper_Pref.filter_zone = not QuestHelper_Pref.filter_zone
312 self:TextOut("Filter "..self:HighlightText("zone").." set to "..self:HighlightText(QuestHelper_Pref.filter_zone and "active" or "inactive")..".")
313 QH_Route_Filter_Rescan("filter_zone")
314 elseif input == "DONE" then
315 QuestHelper_Pref.filter_done = not QuestHelper_Pref.filter_done
316 self:TextOut("Filter "..self:HighlightText("done").." set to "..self:HighlightText(QuestHelper_Pref.filter_done and "active" or "inactive")..".")
317 QH_Route_Filter_Rescan("filter_quest_done")
318 elseif input == "LEVEL" then
319 QuestHelper_Pref.filter_level = not QuestHelper_Pref.filter_level
320 self:TextOut("Filter "..self:HighlightText("level").." set to "..self:HighlightText(QuestHelper_Pref.filter_level and "active" or "inactive")..".")
321 QH_Route_Filter_Rescan("filter_quest_level")
322 elseif input == "BLOCKED" or input == "BLOCK" then
323 QuestHelper_Pref.filter_blocked = not QuestHelper_Pref.filter_blocked
324 self:TextOut("Filter "..self:HighlightText("blocked").." set to "..self:HighlightText(QuestHelper_Pref.filter_blocked and "active" or "inactive")..".")
325 QH_Route_Filter_Rescan("filter_blocked")
326 elseif input == "WATCHED" or input == "WATCH" then
327 QuestHelper_Pref.filter_watched = not QuestHelper_Pref.filter_watched
328 self:TextOut("Filter "..self:HighlightText("watched").." set to "..self:HighlightText(QuestHelper_Pref.filter_watched and "active" or "inactive")..".")
329 QH_Route_Filter_Rescan("filter_quest_watched")
330 elseif input == "" then
331 self:TextOut("Filter "..self:HighlightText("zone")..": "..self:HighlightText(QuestHelper_Pref.filter_zone and "active" or "inactive"))
332 self:TextOut("Filter "..self:HighlightText("level")..": "..self:HighlightText(QuestHelper_Pref.filter_level and "active" or "inactive"))
333 self:TextOut("Filter "..self:HighlightText("done")..": "..self:HighlightText(QuestHelper_Pref.filter_done and "active" or "inactive"))
334 self:TextOut("Filter "..self:HighlightText("blocked")..": "..self:HighlightText(QuestHelper_Pref.filter_blocked and "active" or "inactive"))
335 self:TextOut("Filter "..self:HighlightText("watched")..": "..self:HighlightText(QuestHelper_Pref.filter_watched and "active" or "inactive"))
336 else
337 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")..".")
341 function QuestHelper:ToggleArrow(text)
342 if text == "reset" then QH_Arrow_Reset() return end
344 QuestHelper_Pref.arrow = not QuestHelper_Pref.arrow
345 if QuestHelper_Pref.arrow then
346 QH_Arrow_Show()
347 self:TextOut(QHFormat("SETTINGS_ARROWLINK_ON", QHText("SETTINGS_ARROWLINK_ARROW")))
348 else
349 self:TextOut(QHFormat("SETTINGS_ARROWLINK_OFF", QHText("SETTINGS_ARROWLINK_ARROW")))
353 function QuestHelper:ToggleCartWP()
354 QuestHelper_Pref.cart_wp_new = not QuestHelper_Pref.cart_wp_new
355 if QuestHelper_Pref.cart_wp_new then
356 self:EnableCartographer()
357 if Cartographer_Waypoints then
358 if Waypoint and Waypoint.prototype then
359 self:TextOut("Would use "..self:HighlightText("Cartographer Waypoints").." to show objectives, but another mod is interfering with it.")
360 else
361 self:TextOut(QHFormat("SETTINGS_ARROWLINK_ON", QHText("SETTINGS_ARROWLINK_CART")))
363 else
364 self:TextOut("Would use "..self:HighlightText("Cartographer Waypoints").." to show objectives, except it doesn't seem to be present.")
366 else
367 self:DisableCartographer()
368 self:TextOut(QHFormat("SETTINGS_ARROWLINK_OFF", QHText("SETTINGS_ARROWLINK_CART")))
372 function QuestHelper:ToggleTomTomWP()
373 QuestHelper_Pref.tomtom_wp_new = not QuestHelper_Pref.tomtom_wp_new
374 if QuestHelper_Pref.tomtom_wp_new then
375 self:EnableTomTom()
376 if TomTom then
377 self:TextOut(QHFormat("SETTINGS_ARROWLINK_ON", QHText("SETTINGS_ARROWLINK_TOMTOM")))
378 else
379 self:TextOut("Would use "..self:HighlightText("TomTom").." to show objectives, except it doesn't seem to be present.")
381 else
382 self:DisableTomTom()
383 self:TextOut(QHFormat("SETTINGS_ARROWLINK_OFF", QHText("SETTINGS_ARROWLINK_TOMTOM")))
387 function QuestHelper:WantPathingReset()
388 self:TextOut("Will reset world graph.")
389 self.defered_graph_reset = true
392 function QuestHelper:PrintVersion()
393 self:TextOut("Version: "..self:HighlightText(GetAddOnMetadata("QuestHelper", "Version") or "Unknown"))
396 local function RecycleStatusString(fmt, usedcount, freetable, usedtable)
397 local freetablecount = QuestHelper:TableSize(freetable)
398 if usedtable then
399 local usedtablecount = QuestHelper:TableSize(usedtable)
400 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)
401 else
402 return string.format(fmt, QuestHelper:ProgressString(string.format("%d/%d", usedcount, usedcount+freetablecount), ((usedcount+freetablecount == 0) and 1) or (1-usedcount/(usedcount+freetablecount))))
406 function QuestHelper:Top(cmd)
407 if cmd and string.find(cmd, "all") then
408 cmd = cmd .. " collected recycle clear boot usage"
411 if cmd and string.find(cmd, "boot") then
412 local bootv = {}
413 for k, v in pairs(QuestHelper_Loadtime) do
414 table.insert(bootv, {time = v, file = k})
416 table.sort(bootv, function (a, b) return a.time < b.time end)
418 if string.find(cmd, "sort") then
419 local boott = {}
420 for i = 1, #bootv - 1 do
421 table.insert(boott, {time = bootv[i + 1].time - bootv[i].time, file = bootv[i].file})
423 table.sort(boott, function(a, b) return a.time < b.time end)
425 for _, v in pairs(boott) do
426 QuestHelper:TextOut(string.format("%s: %f", v.file, v.time))
428 QuestHelper:TextOut(string.format("%s: shrug", bootv[#bootv].file))
429 else
430 for i = 1, #bootv do
431 QuestHelper:TextOut(string.format("%f: %s", bootv[i].time - bootv[1].time, bootv[i].file))
436 local pre_ttf
437 local pre_db
438 if cmd and string.find(cmd, "collected") then
439 pre_ttf = self:DumpTableTypeFrequencies(true)
440 pre_db = DB_DumpItems()
443 if cmd and string.find(cmd, "recycle") then
444 self:DumpTableTypeFrequencies()
445 self:TextOut(RecycleStatusString("Using %s lua tables.", self.used_tables, self.free_tables, self.recycle_tabletyping))
446 self:TextOut(RecycleStatusString("Using %s texture objects.", self.used_textures, self.free_textures))
447 self:TextOut(RecycleStatusString("Using %s font objects.", self.used_text, self.free_text))
448 self:TextOut(RecycleStatusString("Using %s frame objects.", self.used_frames, self.free_frames))
451 if cmd and string.find(cmd, "usage") then
452 self:DumpTableTypeFrequencies()
455 if cmd and string.find(cmd, "cache") then
456 self:DumpCacheData()
459 if cmd and string.find(cmd, "perf") then
460 QH_Timeslice_DumpPerf()
463 local uncd = 0
464 for k, v in pairs(QuestHelper_Collector) do
465 if not v.compressed then uncd = uncd + 1 end
467 uncd = uncd - 1
468 local uncs = ""
469 if uncd > 0 then
470 uncs = string.format(" (%d uncompressed IDs)", uncd)
473 UpdateAddOnMemoryUsage()
474 local pre_gc = GetAddOnMemoryUsage("QuestHelper")
476 collectgarbage("collect")
478 UpdateAddOnMemoryUsage()
479 local post_gc = GetAddOnMemoryUsage("QuestHelper")
481 if cmd and string.find(cmd, "collected") then
482 local post_ttf = self:DumpTableTypeFrequencies(true)
484 local union = {}
485 for k, v in pairs(pre_ttf) do union[k] = (pre_ttf[k] or 0) - (post_ttf[k] or 0) end
486 for k, v in pairs(post_ttf) do union[k] = (pre_ttf[k] or 0) - (post_ttf[k] or 0) end
488 local sorted = {}
489 for k, v in pairs(union) do
490 table.insert(sorted, {k = k, d = v})
493 table.sort(sorted, function(a, b) return a.d < b.d end)
494 for _, v in pairs(sorted) do
495 if v.d > 0 then
496 QuestHelper:TextOut(string.format("%d: %s", v.d, v.k))
500 local post_db = DB_DumpItems()
502 local st = {}
503 for k, v in pairs(pre_db) do
504 if not post_db[k] then
505 table.insert(st, k)
508 table.sort(st)
510 for _, v in ipairs(st) do
511 QuestHelper:TextOut("DB: " .. v)
515 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))
517 if cmd and string.find(cmd, "clear") then
518 local cleared = QH_ClearPathcache()
520 collectgarbage("collect")
521 UpdateAddOnMemoryUsage()
522 local new_post_gc = GetAddOnMemoryUsage("QuestHelper")
523 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))
525 local cleared = QuestHelper:RecycleClear()
527 collectgarbage("collect")
528 UpdateAddOnMemoryUsage()
529 local new_post_gc_2 = GetAddOnMemoryUsage("QuestHelper")
530 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))
534 function QuestHelper:ToggleMapButton()
535 QuestHelper_Pref.map_button = not QuestHelper_Pref.map_button
537 if QuestHelper_Pref.map_button then
538 QuestHelper:InitMapButton()
539 self:TextOut("Map button has been |cff00ff00enabled|r.")
540 else
541 QuestHelper:HideMapButton()
542 self:TextOut("Map button has been |cffff0000disabled|r. Use '/qh button' to restore it.")
546 function QuestHelper:ChangeLog()
547 self:ShowText(QuestHelper_ChangeLog, string.format("QuestHelper %s ChangeLog", QuestHelper_Version))
550 function QuestHelper:Submit()
551 self:ShowText([[
552 |TInterface\AddOns\QuestHelper\Art\Upload.tga:100:300|t
553 Your data can't be submitted automatically, since AddOns can't interact with anything outside of World of Warcraft.
555 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.
557 World of Warcraft stores QuestHelper's data in a file named |cff40bbffQuestHelper.lua|r.
559 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.
561 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.
563 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.
565 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.
567 After you find |cff40bbffQuestHelper.lua|r, you can email it to me here: |cff40bbffqhaddon@gmail.com|r
568 ]], "How To Submit Your Data")
571 function QuestHelper:ShowError(params)
572 if params and params == "full" then
573 QuestHelper_ErrorCatcher_GenerateReport()
575 QuestHelper_ErrorCatcher_ReportError()
578 local commands
580 function QuestHelper:Help(argument)
581 local text = ""
582 local argument = argument and argument:upper() or ""
584 for i1, cat in ipairs(commands) do
585 text = string.format("%s|cffffff00%s|r\n\n", text, cat[1])
586 for i, data in ipairs(cat[2]) do
587 if data[1]:find(argument, 1, true) then
588 text = string.format("%s |cffff8000%s|r %s\n", text, data[1], data[2])
590 if #data[3] > 0 then
591 text = string.format("%s\n %s\n", text, #data[3] == 1 and "Example:" or "Examples:")
592 for i, pair in ipairs(data[3]) do
593 text = string.format("%s |cff40bbff%s|r\n %s\n", text, pair[1], pair[2])
597 text = text .. "\n"
600 text = text .. "\n\n"
603 self:ShowText(text == "" and ("No commands containing '"..argument.."'") or text, "QuestHelper Slash Commands")
606 function QuestHelper:Donate(argument)
607 local text = ""
608 local argument = argument and argument:upper() or ""
610 for i1, cat in ipairs(commands) do
611 text = string.format("%s|cffffff00%s|r\n\n", text, cat[1])
612 for i, data in ipairs(cat[2]) do
613 if data[1]:find(argument, 1, true) then
614 text = string.format("%s |cffff8000%s|r %s\n", text, data[1], data[2])
616 if #data[3] > 0 then
617 text = string.format("%s\n %s\n", text, #data[3] == 1 and "Example:" or "Examples:")
618 for i, pair in ipairs(data[3]) do
619 text = string.format("%s |cff40bbff%s|r\n %s\n", text, pair[1], pair[2])
623 text = text .. "\n"
626 text = text .. "\n\n"
629 self:ShowText([[
630 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.
632 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:
634 |cff40bbffReduced memory and CPU usage for smoother gameplay|r
636 |cff40bbffFlying mount support for both Northrend and Outland|r
638 |cff40bbffBetter support for Northrend "phased" quests|r
640 |cff40bbffAchievementHelper, built right into QuestHelper|r
642 |cff40bbffPaths that lead you around obstacles instead of through them|r
644 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!
646 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.
648 Thanks!]], "Please Donate!", 500, 20, 10)
651 commands =
653 { "Common commands", {
654 {"HIDDEN",
655 "Compiles a list of objectives that QuestHelper is hiding from you. Depending on the reason, you can also unhide the objective.",
656 {}, QH_Hidden_Menu},
658 {"HIDE",
659 "Hides QuestHelper's modifications to the minimap and world map, and pauses routing calculations.",
660 {}, QuestHelper.ToggleHide, QuestHelper},
662 {"ARROW",
663 "Toggles Questhelper's built-in directional arrow.",
664 {{"/qh arrow reset", "Reset location to the center of the screen."}},
665 QuestHelper.ToggleArrow, QuestHelper},
667 {"CARTWP",
668 "Toggles displaying the current objective using Cartographer Waypoints (must be installed separately).",
669 {}, QuestHelper.ToggleCartWP, QuestHelper},
671 {"TOMTOM",
672 "Toggles displaying the current objective using TomTom (must be installed separately).",
673 {}, QuestHelper.ToggleTomTomWP, QuestHelper},
675 {"FIND",
676 "Search for an item, location, or npc.",
677 {{"/qh find item rune of teleport", "Finds a reagent vendor."},
678 {"/qh find npc bragok", "Finds the Ratchet flight point."},
679 {"/qh find loc stormwind 50 60", "Finds the Stormwind auction house."},
680 {"/qh find loc 50 50", "Finds the center of the zone you're in."},
681 {"/qh find something", "Searches for something in all categories."},
682 {"/qh find", "Lists objectives you manually created so that you can remove them."}}, QuestHelper.PerformSearch, QuestHelper},
684 {"SOLO",
685 "Toggles solo mode. When enabled, assumes your party members don't exist. Objective sharing with party members will also be disabled.",
686 {}, QuestHelper.ToggleSolo, QuestHelper},
689 { "Objective filtering", {
690 {"FILTER",
691 "Automatically ignores/unignores objectives based on criteria.",
692 {{"/qh filter zone", "Toggle showing objectives outside the current zone"},
693 {"/qh filter done", "Toggle showing objectives for uncompleted quests."},
694 {"/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."},
695 {"/qh filter blocked", "Toggle showing blocked objectives, such as quest turn-ins for incomplete quests."},
696 {"/qh filter watched", "Toggle limiting to objectives watched in the Quest Log"}
697 }, QuestHelper.Filter, QuestHelper},
699 {"LEVEL",
700 "Adjusts the level offset used by the level filter. Naturally, the level filter must be turned on to have an effect.",
701 {{"/qh level", "See information related to the level filter."},
702 {"/qh level 0", "Only allow objectives at or below your current level."},
703 {"/qh level +2", "Allow objectives up to two levels above your current level."},
704 {"/qh level -1", "Only allow objectives below your current level."}}, QuestHelper.LevelOffset, QuestHelper},
706 {"SCALE",
707 "Scales the map icons used by QuestHelper. Will accept values between 50% and 300%.",
708 {{"/qh scale 1", "Uses the default icon size."},
709 {"/qh scale 2", "Makes icons twice their default size."},
710 {"/qh scale 80%", "Makes icons slightly smaller than their default size."}},
711 QuestHelper.genericSetScale, QuestHelper, "scale", "icon scale", .5, 3},
713 {"SHARE",
714 "Toggles objective sharing between QuestHelper users.",
715 {}, QuestHelper.ToggleShare, QuestHelper},
718 { "Interface", {
719 {"TRACK",
720 "Toggles the visibility of the QuestHelper's replacement quest tracker.",
721 {}, QuestHelper.ToggleTrack, QuestHelper},
723 {"TSCALE",
724 "Scales the quest tracker provided by QuestHelper. Will accept values between 50% and 300%.",
726 QuestHelper.TrackerScale, QuestHelper},
728 {"TRESET",
729 "Reset's the position of the quest tracker provided by QuestHelper, in cause you move it somewhere inaccessable.",
730 {{"/qh treset center", "Resets to the center of the screen, instead of a more normal quest tracker location."}}, QuestHelper.ResetTrackerPosition, QuestHelper},
732 {"TLEVEL",
733 "Toggles display of levels in the quest tracker provided by QuestHelper.",
734 {}, QuestHelper.ToggleTrackLevel, QuestHelper},
736 {"TQCOL",
737 "Toggles display of colours for the difficulty level of quests in the quest tracker provided by QuestHelper.",
738 {}, QuestHelper.ToggleTrackQColour, QuestHelper},
740 {"TOCOL",
741 "Toggles display of colours for objective progress in the quest tracker provided by QuestHelper.",
742 {}, QuestHelper.ToggleTrackOColour, QuestHelper},
744 {"TOOLTIP",
745 "Toggles appending information about tracked items and NPCs to their tooltips.",
746 {}, QuestHelper.ToggleTooltip, QuestHelper},
748 {"FTIME",
749 "Toggles display of flight time estimates.", {}, QuestHelper.ToggleFlightTimes, QuestHelper},
751 {"ANTS",
752 "Toggles the display of trails on the world map on and off.",
753 {}, QuestHelper.ToggleAnts, QuestHelper},
755 {"LOCALE",
756 "Select the locale to use for displayed messages.",
757 {}, QuestHelper.SetLocale, QuestHelper},
759 {"BUTTON",
760 "Toggles the display of QuestHelper's button on the world map.",
761 {}, QuestHelper.ToggleMapButton, QuestHelper},
763 {"SETTINGS",
764 "Opens the Settings menu at the current cursor location. Note that not all settings can be changed through the menu.",
765 {}, QuestHelper.DoSettingsMenu, QuestHelper},
768 { "Data collection", {
769 {"SUBMIT",
770 "Displays instructions for submitting your collected data.",
771 {}, QuestHelper.Submit, QuestHelper},
773 {"NAG",
774 "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.",
775 {{"/qh nag verbose", "Prints the specific changes that were found."}}, QuestHelper.Nag, QuestHelper},
777 {"PURGE",
778 "Deletes all QuestHelper's collected data.", {}, QuestHelper.Purge, QuestHelper},
780 {"HARDRESET",
781 "Deletes all QuestHelper's collected data and resets QuestHelper preferences.", {}, QuestHelper.HardReset, QuestHelper},
784 { "Performance and debug", {
785 {"PERF",
786 "Sets or shows the route workload. Higher means more agressive route updating, lower means better performance Accepts numbers between 10% and 500%.",
787 {{"/qh perf", "Show current Performance Factor"},
788 {"/qh perf 1", "Sets standard performance"},
789 {"/qh perf 50%", "Does half as much background processing"},
790 {"/qh perf 3", "Computes routes 3 times more aggressively. Better have some good horsepower!"}},
791 QuestHelper.genericSetScale, QuestHelper, "perf_scale", "performance factor", .1, 5},
793 {"PERFLOAD",
794 "Sets or shows the initialization workload. Higher numbers will make QuestHelper load faster, lower numbers will result in better framerate while it's loading.",
795 {{"/qh perfload", "Show current Performance Factor"},
796 {"/qh perfload 1", "Sets standard performance"},
797 {"/qh perfload 50%", "Does half as much background processing"},
798 {"/qh perfload 3", "Loads 3 times as quickly."}},
799 QuestHelper.genericSetScale, QuestHelper, "perfload_scale", "boot performance factor", .2, 5},
801 {"TOP",
802 "Displays various performance stats on QuestHelper.",
804 {"/qh top recycle", "Displays detailed information on QuestHelper's recycled item pools"},
805 {"/qh top usage", "Displays detailed information on which table types are most common"},
806 {"/qh top cache", "Displays detailed information on the internal distance cache"},
807 {"/qh top perf", "Displays detailed information on coroutine CPU usage"},
808 }, QuestHelper.Top, QuestHelper},
810 {"ERROR",
811 "Displays the first QuestHelper error that has been generated this session in a form which can be copied out of WoW.",
812 {}, QuestHelper.ShowError, QuestHelper},
814 {"POS",
815 "Prints the player's current position. Exists mainly for my own personal convenience.",
816 {}, 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},
818 {"COMM",
819 "Toggles showing of the communication between QuestHelper users. Exists mainly for my own personal convenience.",
820 {}, QuestHelper.ToggleComm, QuestHelper},
822 {"RECALC",
823 "Recalculates the world graph and locations for any active objectives. Should not be necessary.", {}, QuestHelper.WantPathingReset, QuestHelper},
826 { "Help", {
827 {"HELP",
828 "Displays a list of help commands. Listed commands are filtered by the passed string.",
829 {}, QuestHelper.Help, QuestHelper},
831 {"VERSION",
832 "Displays QuestHelper's version.", {}, QuestHelper.PrintVersion, QuestHelper},
834 {"CHANGES",
835 "Displays a summary of changes recently made to QuestHelper.",
836 {}, QuestHelper.ChangeLog, QuestHelper},
838 --[[{"DONATE",
839 "Displays some instructions and a link for donating.",
840 {}, QuestHelper.Donate, QuestHelper},]]
844 function QuestHelper_SlashCommand(input)
845 local _, _, command, argument = string.find(input, "^%s*([^%s]-)%s+(.-)%s*$")
846 if not command then
847 command, argument = input, ""
850 command = string.upper(command)
852 for i1, cat in ipairs(commands) do
853 for i, data in ipairs(cat[2]) do
854 if data[1] == command then
855 local st = {}
857 for i = 5,#data do table.insert(st, data[i]) end
858 table.insert(st, argument)
860 if type(data[4]) == "function" then
861 data[4](unpack(st))
862 else
863 QuestHelper:TextOut(data[1].." is not yet implemented.")
866 return
871 QuestHelper:Help()
874 SLASH_QuestHelper1 = "/qh"
875 SLASH_QuestHelper2 = "/questhelper"
876 SlashCmdList["QuestHelper"] = function (text) QuestHelper_SlashCommand(text) end