Merge branch 'master' into translations
[QuestHelper.git] / tooltip.lua
blobdd6ab4e01fcef36df5e017f5f3eb256e302aabc3
1 QuestHelper_File["tooltip.lua"] = "Development Version"
2 QuestHelper_Loadtime["tooltip.lua"] = GetTime()
4 if QuestHelper_File["tooltip.lua"] == "Development Version" then
5 qh_hackery_nosuppress = true
6 end
8 local function DoTooltip(self, data, lines, prefix)
9 local indent = 1
11 if prefix then
12 self:AddLine((" "):rep(indent) .. prefix, 1, 1, 1)
13 indent = indent + 1
14 end
16 --QuestHelper:TextOut(QuestHelper:StringizeTable(data))
17 --QuestHelper:TextOut(QuestHelper:StringizeTable(lines))
18 for _, v in ipairs(lines) do
19 self:AddLine((" "):rep(indent) .. v, 1, 1, 1)
20 indent = indent + 1
21 end
22 self:AddLine((" "):rep(indent) .. data.desc, 1, 1, 1)
23 QuestHelper:AppendObjectiveProgressToTooltip(data, self, nil, indent + 1)
24 end
26 local function DoTooltipDefault(self, qname, text)
27 self:AddLine(" " .. QHFormat("TOOLTIP_SLAY", text), 1, 1, 1)
28 self:AddLine(" " .. QHFormat("TOOLTIP_QUEST", qname), 1, 1, 1)
29 end
31 local ctts = {}
33 -- Format:
34 -- { ["monster@@1234"] = {{"Slay for blah blah blah"}, (Objective)} }
35 -- ("Slay for" is frequently an empty table)
36 function QH_Tooltip_Canned_Add(tooltips)
37 for k, v in pairs(tooltips) do
38 local typ, id = k:match("([^@]+)@@([^@]+)")
39 --[[print(k)
40 for tk, tv in pairs(v[1]) do
41 print(" ", 1, tk, tv)
42 end
43 for tk, tv in pairs(v[2]) do
44 print(" ", 2, tk, tv)
45 end]]
46 QuestHelper: Assert(typ and id, k)
47 if not ctts[typ] then ctts[typ] = {} end
48 if not ctts[typ][id] then ctts[typ][id] = {} end
49 QuestHelper: Assert(not ctts[typ][id][v[2]])
50 ctts[typ][id][v[2]] = v[1]
51 end
52 end
53 function QH_Tooltip_Canned_Remove(tooltips)
54 for k, v in pairs(tooltips) do
55 local typ, id = k:match("([^@]+)@@([^@]+)")
56 QuestHelper: Assert(typ and id, k)
57 QuestHelper: Assert(ctts[typ][id][v[2]])
58 ctts[typ][id][v[2]] = nil
60 local cleanup = true
61 for _, _ in pairs(ctts[typ][id]) do
62 cleanup = false
63 end
65 if cleanup then
66 ctts[typ][id] = nil
67 end
68 end
69 end
71 local deferences = {}
72 local deference_default = {} -- this is just a unique value that we can use to lookup
74 -- think about what we want out of this
75 -- If it matches quest/objective, we suppress it and show our canned text
76 -- If it matches quest, but has unknown objectives, we suppress it and show some synthesized "Canned thing, for Quest Blahblahblah"
78 -- tooltips is the same slay/objective pair in the above thing
79 function QH_Tooltip_Defer_Add(questname, objective, tooltips)
80 --print("defer add", questname, objective)
81 local objo = objective
82 if not objective then objective = deference_default end
84 if not deferences[questname] then deferences[questname] = {} end
85 if not deferences[questname][objective] then deferences[questname][objective] = {} end
87 for k, v in pairs(deferences[questname][objective]) do
88 QuestHelper: Assert(v ~= tooltips)
89 end
90 table.insert(deferences[questname][objective], tooltips)
92 --print("adding", questname, objective)
93 end
94 function QH_Tooltip_Defer_Remove(questname, objective, tooltips)
95 local objo = objective
96 if not objective then objective = deference_default end
98 --print("remove", questname, objective)
99 --print("removing", questname, objective, deferences[questname][objective])
100 QuestHelper: Assert(deferences[questname][objective], string.format("%s %s %s", tostring(questname), tostring(objective), tostring(objo)))
102 local remmed = false
103 for k, v in pairs(deferences[questname][objective]) do
104 if v == tooltips then
105 table.remove(deferences[questname][objective], k)
106 remmed = true
107 break
110 QuestHelper: Assert(remmed)
112 if #deferences[questname][objective] == 0 then
113 deferences[questname][objective] = nil
116 local cleanup = true
117 for _ in pairs(deferences[questname]) do
118 cleanup = false
121 if cleanup then
122 deferences[questname] = nil
125 function QH_Tooltip_Defer_Dump()
126 for k, v in pairs(deferences) do
127 print(k)
128 for t, m in pairs(v) do
129 print(" ", t, #m)
134 -- TODO: move this into some common file, I hate that I'm duplicating them but I just want this to work. entire codebase will need a going-over soon
135 local function IsMonsterGUID(guid)
136 QuestHelper: Assert(#guid == 18, "guid len " .. guid) -- 64 bits, plus the 0x prefix
137 QuestHelper: Assert(guid:sub(1, 2) == "0x", "guid 0x-prefix " .. guid)
138 return guid:sub(5, 5) == "3" or guid:sub(5, 5) == "5"
141 local function GetMonsterType(guid)
142 QuestHelper: Assert(#guid == 18, "guid len " .. guid) -- 64 bits, plus the 0x prefix
143 QuestHelper: Assert(guid:sub(1, 2) == "0x", "guid 0x-prefix " .. guid)
144 QuestHelper: Assert(guid:sub(5, 5) == "3" or guid:sub(5, 5) == "5", "guid 3-prefix " .. guid) -- It *shouldn't* be a player or a pet by the time we've gotten here. If so, something's gone wrong.
145 return tonumber(guid:sub(9, 12), 16) -- here's our actual identifier
148 local function GetItemType(link, vague)
149 return tonumber(string.match(link,
150 (vague and "" or "^") .. "|cff%x%x%x%x%x%x|Hitem:(%d+):[%d:-]+|h%[[^%]]*%]|h|r".. (vague and "" or "$")
154 local function CopyOver(to, from)
155 to:SetFont(from:GetFont())
156 to:SetFontObject(from:GetFontObject())
157 to:SetText(from:GetText())
158 to:SetTextColor(from:GetTextColor())
159 to:SetSpacing(from:GetSpacing())
160 to:SetShadowOffset(from:GetShadowOffset())
161 to:SetShadowColor(from:GetShadowColor())
162 to:Show()
165 local function StripBlizzQHTooltipClone(ttp)
166 --do return end
167 if not UnitExists("mouseover") then return end
170 local changed = false
171 local removed = 0
173 local qobj = nil
174 local qobj_name = nil
176 local linemax
178 local line = 2
179 while _G["GameTooltipTextLeft" .. line] and _G["GameTooltipTextLeft" .. line]:IsShown() do
180 linemax = line
181 line = line + 1
185 for line = 2, linemax do
186 local r, g, b, a = _G["GameTooltipTextLeft" .. line]:GetTextColor()
187 r, g, b, a = math.floor(r * 255 + 0.5), math.floor(g * 255 + 0.5), math.floor(b * 255 + 0.5), math.floor(a * 255 + 0.5)
189 if qh_tooltip_print_a_lot then print(thistext, r, g, b, a, qobj) end
191 local thistext = _G["GameTooltipTextLeft" .. line]:GetText()
192 local hideme
193 local thistextm = thistext:match(" %- (.*)")
195 --print(thistext, thistextm)
197 if r == 255 and g == 210 and b == 0 and a == 255 and deferences[thistext] then
198 qobj = deferences[thistext]
199 qobj_name = thistext
200 hideme = true
201 elseif r == 255 and g == 255 and b == 255 and a == 255 and qobj and thistextm and qobj[thistextm] then
202 local ite = qobj[thistextm][1]
203 QuestHelper: Assert(ite)
205 local ttsplat = thistextm:match("(.*): ([0-9]+)/([0-9]+)")
206 if ttsplat == ttp:GetUnit() then
207 ttsplat = nil
209 DoTooltip(ttp, ite[2], ite[1], ttsplat and QHFormat("TOOLTIP_SLAY", ttsplat))
210 hideme = true
211 elseif r == 255 and g == 255 and b == 255 and a == 255 and qobj and thistextm and not qobj[thistextm] and thistextm:find(":") then
212 hideme = true -- it parses as an objective, but we don't know about it, so it's probably a completed objective. todo: actually store completed objectives.
213 elseif r == 255 and g == 255 and b == 255 and a == 255 and qobj and thistextm and not thistextm:find(":") then -- Blizzard cleverly does not suppress tooltips when the user has finished getting certain items, so we do instead
214 DoTooltipDefault(ttp, qobj_name, thistextm)
215 hideme = true
218 if hideme and not qh_hackery_nosuppress then
219 _G["GameTooltipTextLeft" .. line]:SetText(nil)
220 _G["GameTooltipTextLeft" .. line]:SetHeight(0)
221 _G["GameTooltipTextLeft" .. line]:ClearAllPoints()
222 _G["GameTooltipTextLeft" .. line]:SetPoint("TOPLEFT", _G["GameTooltipTextLeft" .. (line - 1)], "BOTTOMLEFT", 0, 1)
223 changed = true
224 removed = removed + 1
228 if changed then
229 ttp:Show()
232 return removed
235 local glob_strip = 0
236 function CreateTooltip(self)
237 glob_strip = 0
239 if QuestHelper_Pref.tooltip then
240 local inu, ilink = self:GetItem()
241 local un, ulink = self:GetUnit()
242 if ulink then ulink = UnitGUID(ulink) end
244 --[[
245 if ilink then
246 local ite = tostring(GetItemType(ilink))
248 if ctts["item"] and ctts["item"][ite] then
249 DoTooltip(self, ctts["item"][ite])
252 self:Show()
253 end]]
255 if qh_tooltip_print_a_lot then print("wut", ulink, IsMonsterGUID(ulink)) print(ulink) print(IsMonsterGUID(ulink)) end
256 if ulink and IsMonsterGUID(ulink) then
257 if qh_tooltip_print_a_lot then print("huhwuzat") print(QH_filter_hints) end
259 glob_strip = StripBlizzQHTooltipClone(self)
261 local ite = tostring(GetMonsterType(ulink))
263 if ctts["monster"] and ctts["monster"][ite] then
264 for data, lines in pairs(ctts["monster"][ite]) do
265 DoTooltip(self, data, lines)
269 self:Show()
274 local unit_to_adjust = nil
276 -- SmoothQuest and possibly others
277 QH_AddNotifier(GetTime() + 5, function ()
278 local ottsu = GameTooltip:GetScript("OnTooltipSetUnit")
279 QH_Hook(GameTooltip, "OnTooltipSetUnit", function (self, ...)
280 if qh_tooltip_print_a_lot then print("lol") end
281 CreateTooltip(self)
282 if ottsu then return QH_Hook_NotMyFault(ottsu, self, ...) end
283 unit_to_adjust = self:GetUnit()
284 end, "tooltip OnTooltipSetUnit")
286 local ottsi = GameTooltip:GetScript("OnTooltipSetItem")
287 QH_Hook(GameTooltip, "OnTooltipSetItem", function (self, ...)
288 QH_Hook_NotMyFault(CreateTooltip, self)
289 if ottsi then return QH_Hook_NotMyFault(ottsi, self, ...) end
290 end, "tooltip OnTooltipSetItem")
292 local ttsx = GameTooltip:GetScript("OnUpdate")
293 QH_Hook(GameTooltip, "OnUpdate", function (self, ...)
294 if ttsx then return QH_Hook_NotMyFault(ttsx, self, ...) end
295 if glob_strip and unit_to_adjust and unit_to_adjust == self:GetUnit() then
296 self:SetHeight(self:GetHeight() - glob_strip * 3) -- maaaaaagic
297 unit_to_adjust = nil
299 end, "tooltip OnUpdate")
300 end)