Added machine translated descriptions in the TOC file.
[QuestHelper.git] / nag.lua
blob5d10936c533cad740689ffedf5cbcd3441cfb630
1 local function FindStaticQuest(faction, level, name, hash)
2 local data = QuestHelper_StaticData[QuestHelper.locale]
3 data = data and data.quest
4 data = data and data[faction]
5 data = data and data[level]
6 data = data and data[name]
7 if data and data.hash and data.hash ~= hash then
8 data = data.alt and data.alt[hash]
9 end
10 return data
11 end
13 local function FindStaticObjective(cat, name)
14 local data = QuestHelper_StaticData[QuestHelper.locale]
15 data = data and data.objective
16 data = data and data[cat]
17 return data and data[name]
18 end
20 local function ListUpdated(list, static, compare, weight)
21 if not list then return false end
22 if not static then return true end
24 local high = 0
26 for _, b in ipairs(static) do
27 high = math.max(high, weight(b))
28 end
30 for _, a in ipairs(list) do
31 local found = false
33 for _, b in ipairs(static) do
34 if weight(a) < high*0.2 or compare(a, b) then
35 found = true
36 break
37 end
38 end
40 if not found then return true end
41 end
42 return false
43 end
45 local function PositionWeight(a)
46 return a[4]
47 end
49 local function PositionCompare(a, b)
50 return a[1] == b[1] and
51 (a[2]-b[2])*(a[2]-b[2])+(a[3]-b[3])*(a[3]-b[3]) < 0.05*0.05
52 end
54 local function VendorCompare(a, b)
55 return a == b
56 end
58 local function VendorWeight(a)
59 return 1
60 end
62 local function PositionListUpdated(list, static)
63 return ListUpdated(list, static, PositionCompare, PositionWeight)
64 end
66 local function VendorListUpdated(list, static)
67 return ListUpdated(list, static, VendorCompare, VendorWeight)
68 end
70 local function DropListUpdated(list, static)
71 if not list then return false end
72 if not static then return next(list, nil) ~= nil end
73 local high = 0
75 for name in pairs(list) do
76 local monster_obj = FindStaticObjective("monster", name)
77 if monster_obj and monster_obj.looted and monster_obj.looted > 0 then
78 high = math.max(high, (static[name] or 0)/monster_obj.looted)
79 end
80 end
82 for name, v in pairs(list) do
83 local monster_obj1 = QuestHelper:GetObjective("monster", name)
84 local monster_obj2 = FindStaticObjective("monster", name)
86 local looted = math.ceil((monster_obj1.looted or 0)+((monster_obj2 and monster_obj2.looted) or 0))
87 if looted > 0 then
88 v = math.max(1, math.floor(v))/looted
89 if v > high*0.2 and not static[name] then return true end
90 end
91 end
92 return false
93 end
95 local function DropListMass(list)
96 if not list then return 0 end
97 local mass = 0
98 for item, count in pairs(list) do
99 mass = mass + count
101 return mass
104 local function PositionListMass(list)
105 if not list then return 0 end
106 local mass = 0
107 for _, pos in ipairs(list) do
108 mass = mass + pos[4]
110 return mass
113 local function CompareStaticQuest(info, faction, level, name, hash, data, verbose)
114 local static = FindStaticQuest(faction, level, name, hash)
116 if not static then
117 if data.finish or data.pos then
118 if verbose then QuestHelper:TextOut("Quest "..QuestHelper:HighlightText(name).." was missing.") end
119 info.new.quest = (info.new.quest or 0) + 1
121 return
124 local updated = false
126 if data.finish and data.finish ~= static.finish then
127 if verbose then QuestHelper:TextOut("Quest "..QuestHelper:HighlightText(name).." was missing finish NPC "..QuestHelper:HighlightText(data.finish)..".") end
128 updated = true
129 elseif not static.finish and PositionListUpdated(data.pos, static.pos) then
130 if verbose then QuestHelper:TextOut("Quest "..QuestHelper:HighlightText(name).." was missing finish location.") end
131 updated = true
132 elseif data.item then
133 for item_name, item in pairs(data.item) do
134 local static_item = (static.item and static.item[item_name]) or FindStaticObjective("item", item_name)
136 if not static_item then
137 if verbose then QuestHelper:TextOut("Quest "..QuestHelper:HighlightText(name).." was missing item "..QuestHelper:HighlightText(item_name)..".") end
138 updated = true
139 break
140 elseif item.drop then
141 if DropListUpdated(item.drop, static_item.drop) then
142 if DropListMass(item.drop) > PositionListMass(static_item.pos) then
143 if verbose then QuestHelper:TextOut("Quest "..QuestHelper:HighlightText(name).." was missing drop for item "..QuestHelper:HighlightText(item_name)..".") end
144 updated = true
145 break
148 elseif item.pos and not static_item.drop and PositionListUpdated(item.pos, static_item.pos) then
149 if verbose then QuestHelper:TextOut("Quest "..QuestHelper:HighlightText(name).." was missing position for item "..QuestHelper:HighlightText(item_name)..".") end
150 updated = true
151 break
156 if updated then
157 info.update.quest = (info.update.quest or 0)+1
161 local function CompareStaticObjective(info, cat, name, data, verbose)
162 if info.quest then
163 local static = FindStaticObjective(cat, name)
164 if not static then
165 if data.pos or data.drop or data.vendor then
166 if verbose then QuestHelper:TextOut(string.gsub(cat, "^(.)", string.upper).." "..QuestHelper:HighlightText(name).." was missing.") end
167 info.new[cat.."_obj"] = (info.new[cat.."_obj"] or 0)+1
169 return
172 local updated = false
174 if data.vendor then
175 updated = VendorListUpdated(data.vendor, static.vendor)
176 if updated and verbose then QuestHelper:TextOut(string.gsub(cat, "^(.)", string.upper).." "..QuestHelper:HighlightText(name).." was missing vendor.") end
177 elseif data.drop and not static.vendor then
178 updated = DropListUpdated(data.drop, static.drop) and DropListMass(data.drop) > PositionListMass(static.pos)
179 if updated and verbose then QuestHelper:TextOut(string.gsub(cat, "^(.)", string.upper).." "..QuestHelper:HighlightText(name).." was missing monster drop.") end
180 elseif data.pos and not static.vendor and not static.drop then
181 if updated and verbose then QuestHelper:TextOut(Qstring.gsub(cat, "^(.)", string.upper).." "..QuestHelper:HighlightText(name).." was missing position.") end
182 updated = PositionListUpdated(data.pos, static.pos)
185 if updated then
186 info.update[cat.."_obj"] = (info.update[cat.."_obj"] or 0)+1
191 function QuestHelper:Nag(cmd)
192 local verbose, local_only = false, true
194 if cmd then
195 if string.find(cmd, "verbose") then verbose = true end
196 if string.find(cmd, "all") then local_only = false end
199 local info =
201 new = {},
202 update = {}
205 for faction, level_list in pairs(QuestHelper_Quests) do
206 if not local_only or faction == self.faction then
207 for level, name_list in pairs(level_list) do
208 for name, data in pairs(name_list) do
209 CompareStaticQuest(info, faction, level, name, data.hash, data, verbose)
210 if data.alt then
211 for hash, data in pairs(data.alt) do
212 CompareStaticQuest(info, faction, level, name, hash, data, verbose)
220 for cat, name_list in pairs(QuestHelper_Objectives) do
221 for name, obj in pairs(name_list) do
222 CompareStaticObjective(info, cat, name, obj, verbose)
226 for faction, location_list in pairs(QuestHelper_FlightInstructors) do
227 if not local_only or faction == self.faction then
228 for location, npc in pairs(location_list) do
229 local data = QuestHelper_StaticData[self.locale]
230 data = data and data.flight_instructors
231 data = data and data[faction]
232 data = data and data[location]
234 if not data or data ~= npc then
235 if verbose then self:TextOut(QuestHelper:HighlightText(faction).." flight master "..QuestHelper:HighlightText(npc).." was missing.") end
236 info.new["fp"] = (info.new["fp"] or 0)+1
242 for faction, start_list in pairs(QuestHelper_FlightRoutes) do
243 if not local_only or faction == self.faction then
244 for start, dest_list in pairs(start_list) do
245 for dest, hash_list in pairs(dest_list) do
246 for hash, data in pairs(hash_list) do
247 local static = QuestHelper_StaticData[self.locale]
248 static = static and static.flight_routes
249 static = static and static[faction]
250 static = static and static[start]
251 static = static and static[dest]
252 static = static and static[hash]
254 if not static or static == true and type(data) == "number" then
255 if verbose then self:TextOut("Flight time from "..QuestHelper:HighlightText((select(3, string.find(start, "^(.*),")) or start)).." to "..QuestHelper:HighlightText((select(3, string.find(dest, "^(.*),")) or dest)).." was missing.") end
256 info.new["route"] = (info.new["route"] or 0)+1
264 local total = 0
266 for what, count in pairs(info.new) do
267 total = total + count
268 local count2 = info.update[what]
269 if count2 then
270 total = total + count2
271 self:TextOut(QHFormat("NAG_MULTIPLE_NEW", count, count2, QHText("NAG_"..string.upper(what))))
272 else
273 self:TextOut(QHFormat("NAG_SINGLE_NEW", QHFormat(count==1 and "NAG_SINGLE" or "NAG_PLURAL", count, QHText("NAG_"..string.upper(what)))))
277 for what, count in pairs(info.update) do
278 if not info.new[what] then
279 total = total + count
280 self:TextOut(QHFormat("NAG_ADDITIONAL", QHFormat(count==1 and "NAG_SINGLE" or "NAG_PLURAL", count, QHText("NAG_"..string.upper(what)))))
284 if total == 0 then
285 self:TextOut(QHText("NAG_NOT_NEW"))
286 else
287 self:TextOut(QHText("NAG_NEW"))
289 if total > 20 then
290 DEFAULT_CHAT_FRAME:AddMessage("|TInterface\\AddOns\\QuestHelper\\Art\\Upload.tga:300:90|t")