vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 tinsert(UISpecialFrames, "CT_ExpenseHistoryFrame");
2 CT_EH_History = { };
3 CT_EH_DISPLAYTHRESHOLD = 100; -- 1 Silver
4 CT_EH_NUMCLASSPILES = 8;
5 CT_EH_Version = 1.2;
6 CT_EH_LogSort = {
7 ["curr"] = 1,
8 ["way"] = 1 -- Desc
9 };
10  
11 function CT_EH_Sort(t1, t2)
12 if ( t1 and t2 ) then
13 return t1[1] >= t2[1]
14 end
15 end
16  
17 function CT_EH_SortLogBy(id)
18 if ( CT_EH_LogSort["curr"] == id ) then
19 CT_EH_LogSort["way"] = abs(CT_EH_LogSort["way"]-1);
20 else
21 CT_EH_LogSort["curr"] = id;
22 CT_EH_LogSort["way"] = 1;
23 end
24 CT_EH_UpdateLog();
25 end
26 function CT_EH_UpdateSummary()
27 local _, _, currPlayer, currServer = string.find( CT_ExpenseHistoryFrame.currPlayer or "", "^(.+)@(.+)$");
28 if ( currPlayer ) then
29 currPlayer = currPlayer .. " @ " .. currServer;
30 end
31 UIDropDownMenu_SetSelectedName(CT_ExpenseHistoryFrameDropDown, ( currPlayer or CT_EH_ALLCHARACTERS ) );
32 UIDropDownMenu_SetWidth(200, CT_ExpenseHistoryFrameDropDown);
33 CT_ExpenseHistoryFrameDropDownText:SetText(( currPlayer or CT_EH_ALLCHARACTERS ));
34 CT_ExpenseHistoryFrameRecordingText:SetText(format(CT_EH_RECORDINGFROM, date("%m/%d/%Y", CT_EH_History["startUsage"])));
35  
36 local classCoords = {
37 ["WARRIOR"] = {0, 0.25, 0, 0.25},
38 ["MAGE"] = {0.25, 0.49609375, 0, 0.25},
39 ["ROGUE"] = {0.49609375, 0.7421875, 0, 0.25},
40 ["DRUID"] = {0.7421875, 0.98828125, 0, 0.25},
41 ["HUNTER"] = {0, 0.25, 0.25, 0.5},
42 ["SHAMAN"] = {0.25, 0.49609375, 0.25, 0.5},
43 ["PRIEST"] = {0.49609375, 0.7421875, 0.25, 0.5},
44 ["WARLOCK"] = {0.7421875, 0.98828125, 0.25, 0.5},
45 ["PALADIN"] = {0, 0.25, 0.5, 0.75}
46 };
47 local costsTable, totalRepair, numRepairs, totalFlight, totalReagent, totalAmmo, totalMail, totalCost, highCost = CT_EH_GetStats(CT_ExpenseHistoryFrame.currPlayer);
48 local allCostsTable, _, _, _, _, _, _, _, allHighCost = CT_EH_GetStats(nil);
49 table.sort(
50 allCostsTable,
51 function(a1, a2)
52 if ( a1 and a2 ) then
53 return a1[1] > a2[1];
54 end
55 end
56 );
57  
58 -- Summaries
59 local numDays = ( time() - CT_EH_History["startUsage"] ) / (24*3600);
60 MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryAverageRepairMoney", floor(totalRepair/numRepairs+0.5));
61 MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryAvgExpensesPerDayMoney", floor(totalCost/numDays+0.5) );
62 MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryTotalCostMoney", floor(totalCost+0.5));
63  
64 MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryAvgExpensesFlightsMoney", floor(totalFlight/numDays+0.5));
65 MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryAvgExpensesRepairsMoney", floor(totalRepair/numDays+0.5));
66 MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryAvgExpensesReagentsMoney", floor(totalReagent/numDays+0.5));
67 MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryAvgExpensesAmmoMoney", floor(totalAmmo/numDays+0.5));
68 MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryAvgExpensesMailMoney", floor(totalMail/numDays+0.5));
69  
70 MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryTotalCostFlightsMoney", floor(totalFlight+0.5));
71 MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryTotalCostRepairsMoney", floor(totalRepair+0.5));
72 MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryTotalCostReagentsMoney", floor(totalReagent+0.5));
73 MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryTotalCostAmmoMoney", floor(totalAmmo+0.5));
74 MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryTotalCostMailMoney", floor(totalMail+0.5));
75  
76 local i = 0;
77 CT_ExpenseHistoryFrame.numPiles = 0;
78 for playerIndex, val in allCostsTable do
79 if ( val[1] >= CT_EH_DISPLAYTHRESHOLD ) then
80 i = i + 1;
81 if ( i <= CT_EH_NUMCLASSPILES ) then
82 local v, formattedCost, class, playerName = val[1], val[2], val[3], val[4];
83 local height = 120*(v/allHighCost);
84 if ( height < 2 ) then
85 height = 2; -- So we can at least see the bar
86 end
87 CT_ExpenseHistoryFrame.numPiles = i;
88 getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i).name = playerName;
89 getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i):Show();
90 if ( not CT_ExpenseHistoryFrame.isAnimated ) then
91 getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i .. "Pile"):SetHeight(height);
92 end
93 getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i .. "Pile").goalHeight = height;
94 getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i .. "PileNumber"):SetText(formattedCost);
95 getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i .. "Texture"):SetTexCoord(classCoords[class][1], classCoords[class][2], classCoords[class][3], classCoords[class][4]);
96 getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i .. "PileBackground"):SetVertexColor(RAID_CLASS_COLORS[class].r, RAID_CLASS_COLORS[class].g, RAID_CLASS_COLORS[class].b);
97 end
98 end
99 end
100 for i = i+1, CT_EH_NUMCLASSPILES, 1 do
101 getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i):Hide();
102 end
103 end
104  
105 function CT_EH_UpdateLog()
106 local entries = { };
107 for k, v in CT_EH_History do
108 if ( type(v) == "table" ) then
109 for key, val in v do
110 if ( type(val) == "table" ) then
111 tinsert(entries, { val[3], k, val[2], val[1] });
112 end
113 end
114 end
115 end
116 table.sort(
117 entries,
118 function(a1, a2)
119 if ( a1 and a2 ) then
120 if ( CT_EH_LogSort["way"] == 1 ) then
121 if ( a1[CT_EH_LogSort["curr"]] == a2[CT_EH_LogSort["curr"]] ) then
122 return a1[1] > a2[1];
123 else
124 return a1[CT_EH_LogSort["curr"]] > a2[CT_EH_LogSort["curr"]];
125 end
126 else
127 if ( a1[CT_EH_LogSort["curr"]] == a2[CT_EH_LogSort["curr"]] ) then
128 return a1[1] < a2[1];
129 else
130 return a1[CT_EH_LogSort["curr"]] < a2[CT_EH_LogSort["curr"]];
131 end
132 end
133 end
134 end
135 );
136 local numEntries = getn(entries);
137 FauxScrollFrame_Update(CT_ExpenseHistoryFrameLogScrollFrame, numEntries, 22, 20);
138 for i=1, 22, 1 do
139 local line = getglobal("CT_ExpenseHistoryFrameLogLine" .. i);
140 local dateText = getglobal("CT_ExpenseHistoryFrameLogLine" .. i .. "Date");
141 local charText = getglobal("CT_ExpenseHistoryFrameLogLine" .. i .. "Char");
142 local typeText = getglobal("CT_ExpenseHistoryFrameLogLine" .. i .. "Type");
143 local costFrameName = "CT_ExpenseHistoryFrameLogLine" .. i .. "Cost";
144  
145 local index = i + FauxScrollFrame_GetOffset(CT_ExpenseHistoryFrameLogScrollFrame);
146 if ( index <= numEntries ) then
147 local iStart, iEnd, charName, serverName = string.find(entries[index][2], "^(.+)@(.+)$");
148 if ( strlen(charName)+strlen(serverName) > 16 ) then
149 -- We have to cut it down
150 if ( strlen(serverName) < 8 ) then
151 charName = strsub(charName, 0, 16-strlen(serverName));
152 elseif ( strlen(charName) < 8 ) then
153 serverName = strsub(serverName, 0, 16-strlen(charName));
154 else
155 charName = strsub(charName, 0, 8);
156 serverName = strsub(serverName, 0, 8);
157 end
158 end
159 line:Show();
160 dateText:SetText(date("%m/%d/%y", entries[index][1]));
161 charText:SetText(charName .. "@" .. serverName);
162 typeText:SetText(entries[index][3]);
163 MoneyFrame_Update(costFrameName, entries[index][4]);
164 else
165 line:Hide();
166 end
167 end
168 end
169  
170 function CT_EH_GetStats(player)
171 local classFileNames = {
172 [CT_EH_WARRIOR] = "WARRIOR",
173 [CT_EH_MAGE] = "MAGE",
174 [CT_EH_ROGUE] = "ROGUE",
175 [CT_EH_DRUID] = "DRUID",
176 [CT_EH_HUNTER] = "HUNTER",
177 [CT_EH_SHAMAN] = "SHAMAN",
178 [CT_EH_PRIEST] = "PRIEST",
179 [CT_EH_WARLOCK] = "WARLOCK",
180 [CT_EH_PALADIN] = "PALADIN"
181 };
182 local costs, totalRepair, numRepair, totalFlight, totalReagents, totalAmmo, totalMail, totalCost, highCost = { }, 0, 0, 0, 0, 0, 0, 0, 0;
183 for key, tbl in CT_EH_History do
184 if ( ( key == player or not player ) and type(tbl) == "table" ) then
185 local total, totalRep, numRep, totalFli, totalReg, totalAmm, totalMai = CT_EH_GetMoney(key);
186 local _, _, playerName, server = string.find(key, "^(.+)@(.+)$");
187 local formattedCost;
188 if ( total < 100 ) then
189 formattedCost = total .. "c";
190 elseif ( total < (100*100) ) then
191 formattedCost = floor(total/100) .. "s";
192 else
193 formattedCost = floor(total/(100*100)) .. "g";
194 end
195 if ( ( total or 0 ) > highCost ) then
196 highCost = total;
197 end
198 totalRepair = totalRepair + totalRep;
199 numRepair = numRepair + numRep;
200 totalFlight = totalFlight + totalFli;
201 totalReagents = totalReagents + totalReg;
202 totalAmmo = totalAmmo + totalAmm;
203 totalMail = totalMail + totalMai;
204 totalCost = totalCost + total;
205 tinsert(costs, { total, formattedCost, classFileNames[CT_EH_History[key].class], playerName .. " @ " .. server });
206 end
207 end
208 return costs, totalRepair, numRepair, totalFlight, totalReagents, totalAmmo, totalMail, totalCost, highCost;
209 end
210  
211 function CT_EH_StartAnimate()
212 for i = 1, CT_ExpenseHistoryFrame.numPiles, 1 do
213 local pile = getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i .. "Pile");
214 if ( pile:GetParent():IsVisible() ) then
215 CT_ExpenseHistoryFrame.isAnimated = 1;
216 getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i .. "Pile"):SetHeight(0);
217 end
218 end
219 end
220  
221 function CT_EH_ProcessAnimation(elapsed)
222 this.elapsed = this.elapsed - elapsed;
223 if ( this.elapsed <= 0 ) then
224 if ( this.isAnimated ) then
225 local keepAnimating = false;
226 for i = 1, CT_ExpenseHistoryFrame.numPiles, 1 do
227 local pile = getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i .. "Pile");
228 local height = pile:GetHeight();
229 if ( ( height or 0 ) < pile.goalHeight ) then
230 pile:SetHeight(height+(1*((0.017-this.elapsed)/0.017)));
231 keepAnimating = true;
232 end
233 end
234 if ( not keepAnimating ) then
235 CT_ExpenseHistoryFrame.isAnimated = nil;
236 end
237 end
238 this.elapsed = 0.017;
239 end
240 end
241  
242 function CT_EH_GetMoney(name)
243 local total, totalRep, numRep, totalFli, totalReg, totalAmm, totalMai = 0, 0, 0, 0, 0, 0, 0;
244 if ( name and CT_EH_History[name] ) then
245 for k, v in CT_EH_History[name] do
246 if ( k ~= "class" and k ~= "key" ) then
247 total = total + v[1];
248 if ( v[2] == CT_EH_REPAIR ) then
249 totalRep = totalRep + v[1];
250 numRep = numRep + 1;
251 elseif ( v[2] == CT_EH_FLIGHT ) then
252 totalFli = totalFli + v[1];
253 elseif ( v[2] == CT_EH_REAGENT ) then
254 totalReg = totalReg + v[1];
255 elseif ( v[2] == CT_EH_AMMO ) then
256 totalAmm = totalAmm + v[1];
257 elseif ( v[2] == CT_EH_MAIL ) then
258 totalMai = totalMai + v[1];
259 end
260 end
261 end
262 end
263 return total, totalRep, numRep, totalFli, totalReg, totalAmm, totalMai;
264 end
265  
266 function CT_EH_OnShow()
267 PlaySound("UChatScrollButton");
268 PanelTemplates_SetTab(CT_ExpenseHistoryFrame, 1);
269 CT_ExpenseHistoryFrameSummary:Show();
270 CT_ExpenseHistoryFrameLog:Hide();
271 CT_EH_UpdateSummary();
272 CT_EH_StartAnimate();
273 end
274  
275 function CT_EH_OnEvent(event)
276 if ( event == "PLAYER_ENTERING_WORLD" ) then
277 local player = UnitName("player") .. "@" .. GetCVar("realmName");
278 -- Initialize
279 if ( not CT_EH_History["startUsage"] ) then
280 CT_EH_History["startUsage"] = time();
281 elseif ( not CT_EH_History["version"] ) then
282 -- We used version 1.0 previously
283 CT_EH_History["startUsage"] = CT_EH_History["startUsage"] * (24*3600);
284 end
285 CT_EH_History["version"] = CT_EH_Version;
286 if ( not CT_EH_History[player] ) then
287 CT_EH_History[player] = {
288 ["class"] = UnitClass("player"),
289 ["key"] = player
290 };
291 end
292 end
293 end
294  
295 -- Data collection
296 CT_EH_oldUseContainerItem = UseContainerItem;
297 function CT_EH_newUseContainerItem(bag, slot)
298 if ( InRepairMode() ) then
299 local hasCooldown, repairCost = CT_EHTooltip:SetBagItem(bag,slot);
300 if (repairCost and repairCost > 0 and repairCost <= GetMoney() and MerchantFrame.repairCost ) then
301 MerchantFrame.repairCost = MerchantFrame.repairCost + repairCost;
302 end
303 end
304 CT_EH_oldUseContainerItem(bag, slot);
305 end
306 UseContainerItem = CT_EH_newUseContainerItem;
307 CT_EH_oldPickupContainerItem = PickupContainerItem;
308 function CT_EH_newPickupContainerItem(bag, slot)
309 if ( InRepairMode() ) then
310 local hasCooldown, repairCost = CT_EHTooltip:SetBagItem(bag,slot);
311 if (repairCost and repairCost > 0 and repairCost <= GetMoney() and MerchantFrame.repairCost ) then
312 MerchantFrame.repairCost = MerchantFrame.repairCost + repairCost;
313 end
314 end
315 CT_EH_oldPickupContainerItem(bag, slot);
316 end
317 PickupContainerItem = CT_EH_newPickupContainerItem;
318  
319 CT_EH_oldRepairAllItems = RepairAllItems;
320 function CT_EH_newRepairAllItems()
321 local repairAllCost, canRepair = GetRepairAllCost();
322 if ( canRepair and repairAllCost <= GetMoney() ) then
323 if ( MerchantFrame.repairCost ) then
324 MerchantFrame.repairCost = MerchantFrame.repairCost + repairAllCost;
325 end
326 end
327 CT_EH_oldRepairAllItems();
328 end
329 RepairAllItems = CT_EH_newRepairAllItems;
330  
331 SlashCmdList["EXPENSEHISTORY"] = function()
332 if ( CT_ExpenseHistoryFrame:IsVisible() ) then
333 HideUIPanel(CT_ExpenseHistoryFrame);
334 else
335 ShowUIPanel(CT_ExpenseHistoryFrame);
336 end
337 end
338  
339 SLASH_EXPENSEHISTORY1 = "/expensehistory";
340 SLASH_EXPENSEHISTORY2 = "/eh";
341  
342 function CT_EH_DropDown_OnLoad()
343 UIDropDownMenu_Initialize(this, CT_EH_DropDown_Initialize);
344 end
345  
346 function CT_EH_DropDown_Initialize()
347 local dropdown, info;
348 if ( UIDROPDOWNMENU_OPEN_MENU ) then
349 dropdown = getglobal(UIDROPDOWNMENU_OPEN_MENU);
350 else
351 dropdown = this;
352 end
353 info = { };
354 info.text = "All Characters";
355 info.value = nil;
356 info.checked = ( not CT_ExpenseHistoryFrame.currPlayer );
357 info.func = CT_EH_DropDown_OnClick;
358 UIDropDownMenu_AddButton(info);
359 for k, v in CT_EH_History do
360 if ( type(v) == "table" ) then
361 local total = CT_EH_GetMoney(k);
362 if ( total >= CT_EH_DISPLAYTHRESHOLD ) then
363 local _, _, playerName, server = string.find(k, "^(.+)@(.+)$");
364 info = { };
365 info.text = playerName .. " @ " .. server;
366 info.value = k;
367 info.checked = ( CT_ExpenseHistoryFrame.currPlayer == k );
368 info.func = CT_EH_DropDown_OnClick;
369 UIDropDownMenu_AddButton(info);
370 end
371 end
372 end
373 end
374  
375 function CT_EH_DropDown_OnClick()
376 if ( this:GetID() == 1 ) then
377 CT_ExpenseHistoryFrame.currPlayer = nil;
378 else
379 CT_ExpenseHistoryFrame.currPlayer = this.value;
380 end
381 CT_EH_UpdateSummary();
382 CT_EH_UpdateLog();
383 end
384  
385 function CT_EH_Tab_OnClick()
386 if ( this:GetID() == 1 ) then
387 getglobal("CT_ExpenseHistoryFrameSummary"):Show();
388 getglobal("CT_ExpenseHistoryFrameLog"):Hide();
389 CT_EH_UpdateSummary();
390 elseif ( this:GetID() == 2 ) then
391 getglobal("CT_ExpenseHistoryFrameSummary"):Hide();
392 getglobal("CT_ExpenseHistoryFrameLog"):Show();
393 CT_EH_UpdateLog();
394 end
395 PlaySound("igCharacterInfoTab");
396 PanelTemplates_SetTab(CT_ExpenseHistoryFrame, this:GetID());
397 end
398  
399 -- Find out if vendor is reagent vendor
400 function CT_EH_IsVendor(tbl)
401 for i = 1, GetMerchantNumItems(), 1 do
402 local name, texture, price, quantity, numAvailable, isUsable = GetMerchantItemInfo(i);
403 if ( name and tbl[strlower(name)] ) then
404 return true;
405 end
406 end
407 return false;
408 end
409  
410 local CT_EH_oldMerchantFrame_OnShow = MerchantFrame:GetScript("OnShow");
411 local CT_EH_oldMerchantFrame_OnHide = MerchantFrame:GetScript("OnHide");
412 MerchantFrame:SetScript("OnShow", function()
413 CT_EH_oldMerchantFrame_OnShow();
414 if ( CT_EH_IsVendor(CT_EH_SCANFORREAGENTS) ) then
415 MerchantFrame.reagentCost = 0;
416 else
417 MerchantFrame.reagentCost = nil;
418 end
419 if ( CT_EH_IsVendor(CT_EH_SCANFORAMMO) ) then
420 MerchantFrame.ammoCost = 0;
421 else
422 MerchantFrame.ammoCost = nil;
423 end
424 local repairAllCost, canRepair = GetRepairAllCost();
425 if ( canRepair ) then
426 MerchantFrame.repairCost = 0;
427 else
428 MerchantFrame.repairCost = nil;
429 end
430 end);
431 MerchantFrame:SetScript("OnHide", function()
432 CT_EH_oldMerchantFrame_OnHide();
433 if ( MerchantFrame.reagentCost and MerchantFrame.reagentCost > 0 ) then
434 tinsert(CT_EH_History[UnitName("player") .. "@" .. GetCVar("realmName")], { MerchantFrame.reagentCost, CT_EH_REAGENT, time() });
435 end
436 if ( MerchantFrame.ammoCost and MerchantFrame.ammoCost > 0 ) then
437 tinsert(CT_EH_History[UnitName("player") .. "@" .. GetCVar("realmName")], { MerchantFrame.ammoCost, CT_EH_AMMO, time() });
438 end
439 if ( MerchantFrame.repairCost and MerchantFrame.repairCost > 0 ) then
440 tinsert(CT_EH_History[UnitName("player") .. "@" .. GetCVar("realmName")], { MerchantFrame.repairCost, CT_EH_REPAIR, time() });
441 end
442 MerchantFrame.repairCost = nil;
443 MerchantFrame.reagentCost = nil;
444 MerchantFrame.ammoCost = nil;
445 CT_EH_UpdateSummary();
446 CT_EH_UpdateLog();
447 end);
448  
449 local CT_EH_oldBuyMerchantItem = BuyMerchantItem;
450 function BuyMerchantItem(id, qty)
451 local name, texture, price, quantity, numAvailable, isUsable = GetMerchantItemInfo(id);
452 local realPrice = price*(qty or 1);
453 CT_EH_oldBuyMerchantItem(id, qty);
454 if ( MerchantFrame.reagentCost and name and CT_EH_SCANFORREAGENTS[strlower(name)] and realPrice <= GetMoney() ) then
455 MerchantFrame.reagentCost = MerchantFrame.reagentCost + realPrice;
456 end
457 if ( MerchantFrame.ammoCost and name and CT_EH_SCANFORAMMO[strlower(name)] and realPrice <= GetMoney() ) then
458 MerchantFrame.ammoCost = MerchantFrame.ammoCost + realPrice;
459 end
460 end
461  
462 local CT_EH_oldSendMail = SendMail;
463 function SendMail(target, subject, body)
464 CT_EH_oldSendMail(target, subject, body);
465 local price = SendMailCostMoneyFrame.staticMoney;
466 if ( price <= GetMoney() ) then
467 tinsert(CT_EH_History[UnitName("player") .. "@" .. GetCVar("realmName")], { price, CT_EH_MAIL, time() });
468 CT_EH_UpdateSummary();
469 CT_EH_UpdateLog();
470 end
471 end
472  
473 CT_EH_oldTakeTaxiNode = TakeTaxiNode;
474 function CT_EH_newTakeTaxiNode(id)
475 if ( GetMoney() >= TaxiNodeCost(id) ) then
476 tinsert(CT_EH_History[UnitName("player") .. "@" .. GetCVar("realmName")], { TaxiNodeCost(id), CT_EH_FLIGHT, time() });
477 CT_EH_UpdateSummary();
478 CT_EH_UpdateLog();
479 end
480 CT_EH_oldTakeTaxiNode(id);
481 end
482  
483 TakeTaxiNode = CT_EH_newTakeTaxiNode;
484  
485 if ( CT_RegisterMod ) then
486 CT_RegisterMod(CT_EH_MODINFO[1], CT_EH_MODINFO[2], 5, "Interface/Icons/INV_Misc_Note_05", CT_EH_MODINFO[3], "switch", "", function() if ( CT_ExpenseHistoryFrame:IsVisible() ) then HideUIPanel(CT_ExpenseHistoryFrame) else ShowUIPanel(CT_ExpenseHistoryFrame) end end);
487 else
488 DEFAULT_CHAT_FRAME:AddMessage("<CTMod> Expense History loaded. Type /expensehistory or /eh to display the window.", 1, 1, 0);
489 end