vanilla-wow-addons – Rev 1
?pathlinks?
tinsert(UISpecialFrames, "CT_ExpenseHistoryFrame");
CT_EH_History = { };
CT_EH_DISPLAYTHRESHOLD = 100; -- 1 Silver
CT_EH_NUMCLASSPILES = 8;
CT_EH_Version = 1.2;
CT_EH_LogSort = {
["curr"] = 1,
["way"] = 1 -- Desc
};
function CT_EH_Sort(t1, t2)
if ( t1 and t2 ) then
return t1[1] >= t2[1]
end
end
function CT_EH_SortLogBy(id)
if ( CT_EH_LogSort["curr"] == id ) then
CT_EH_LogSort["way"] = abs(CT_EH_LogSort["way"]-1);
else
CT_EH_LogSort["curr"] = id;
CT_EH_LogSort["way"] = 1;
end
CT_EH_UpdateLog();
end
function CT_EH_UpdateSummary()
local _, _, currPlayer, currServer = string.find( CT_ExpenseHistoryFrame.currPlayer or "", "^(.+)@(.+)$");
if ( currPlayer ) then
currPlayer = currPlayer .. " @ " .. currServer;
end
UIDropDownMenu_SetSelectedName(CT_ExpenseHistoryFrameDropDown, ( currPlayer or CT_EH_ALLCHARACTERS ) );
UIDropDownMenu_SetWidth(200, CT_ExpenseHistoryFrameDropDown);
CT_ExpenseHistoryFrameDropDownText:SetText(( currPlayer or CT_EH_ALLCHARACTERS ));
CT_ExpenseHistoryFrameRecordingText:SetText(format(CT_EH_RECORDINGFROM, date("%m/%d/%Y", CT_EH_History["startUsage"])));
local classCoords = {
["WARRIOR"] = {0, 0.25, 0, 0.25},
["MAGE"] = {0.25, 0.49609375, 0, 0.25},
["ROGUE"] = {0.49609375, 0.7421875, 0, 0.25},
["DRUID"] = {0.7421875, 0.98828125, 0, 0.25},
["HUNTER"] = {0, 0.25, 0.25, 0.5},
["SHAMAN"] = {0.25, 0.49609375, 0.25, 0.5},
["PRIEST"] = {0.49609375, 0.7421875, 0.25, 0.5},
["WARLOCK"] = {0.7421875, 0.98828125, 0.25, 0.5},
["PALADIN"] = {0, 0.25, 0.5, 0.75}
};
local costsTable, totalRepair, numRepairs, totalFlight, totalReagent, totalAmmo, totalMail, totalCost, highCost = CT_EH_GetStats(CT_ExpenseHistoryFrame.currPlayer);
local allCostsTable, _, _, _, _, _, _, _, allHighCost = CT_EH_GetStats(nil);
table.sort(
allCostsTable,
function(a1, a2)
if ( a1 and a2 ) then
return a1[1] > a2[1];
end
end
);
-- Summaries
local numDays = ( time() - CT_EH_History["startUsage"] ) / (24*3600);
MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryAverageRepairMoney", floor(totalRepair/numRepairs+0.5));
MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryAvgExpensesPerDayMoney", floor(totalCost/numDays+0.5) );
MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryTotalCostMoney", floor(totalCost+0.5));
MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryAvgExpensesFlightsMoney", floor(totalFlight/numDays+0.5));
MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryAvgExpensesRepairsMoney", floor(totalRepair/numDays+0.5));
MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryAvgExpensesReagentsMoney", floor(totalReagent/numDays+0.5));
MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryAvgExpensesAmmoMoney", floor(totalAmmo/numDays+0.5));
MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryAvgExpensesMailMoney", floor(totalMail/numDays+0.5));
MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryTotalCostFlightsMoney", floor(totalFlight+0.5));
MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryTotalCostRepairsMoney", floor(totalRepair+0.5));
MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryTotalCostReagentsMoney", floor(totalReagent+0.5));
MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryTotalCostAmmoMoney", floor(totalAmmo+0.5));
MoneyFrame_Update("CT_ExpenseHistoryFrameSummaryTotalCostMailMoney", floor(totalMail+0.5));
local i = 0;
CT_ExpenseHistoryFrame.numPiles = 0;
for playerIndex, val in allCostsTable do
if ( val[1] >= CT_EH_DISPLAYTHRESHOLD ) then
i = i + 1;
if ( i <= CT_EH_NUMCLASSPILES ) then
local v, formattedCost, class, playerName = val[1], val[2], val[3], val[4];
local height = 120*(v/allHighCost);
if ( height < 2 ) then
height = 2; -- So we can at least see the bar
end
CT_ExpenseHistoryFrame.numPiles = i;
getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i).name = playerName;
getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i):Show();
if ( not CT_ExpenseHistoryFrame.isAnimated ) then
getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i .. "Pile"):SetHeight(height);
end
getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i .. "Pile").goalHeight = height;
getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i .. "PileNumber"):SetText(formattedCost);
getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i .. "Texture"):SetTexCoord(classCoords[class][1], classCoords[class][2], classCoords[class][3], classCoords[class][4]);
getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i .. "PileBackground"):SetVertexColor(RAID_CLASS_COLORS[class].r, RAID_CLASS_COLORS[class].g, RAID_CLASS_COLORS[class].b);
end
end
end
for i = i+1, CT_EH_NUMCLASSPILES, 1 do
getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i):Hide();
end
end
function CT_EH_UpdateLog()
local entries = { };
for k, v in CT_EH_History do
if ( type(v) == "table" ) then
for key, val in v do
if ( type(val) == "table" ) then
tinsert(entries, { val[3], k, val[2], val[1] });
end
end
end
end
table.sort(
entries,
function(a1, a2)
if ( a1 and a2 ) then
if ( CT_EH_LogSort["way"] == 1 ) then
if ( a1[CT_EH_LogSort["curr"]] == a2[CT_EH_LogSort["curr"]] ) then
return a1[1] > a2[1];
else
return a1[CT_EH_LogSort["curr"]] > a2[CT_EH_LogSort["curr"]];
end
else
if ( a1[CT_EH_LogSort["curr"]] == a2[CT_EH_LogSort["curr"]] ) then
return a1[1] < a2[1];
else
return a1[CT_EH_LogSort["curr"]] < a2[CT_EH_LogSort["curr"]];
end
end
end
end
);
local numEntries = getn(entries);
FauxScrollFrame_Update(CT_ExpenseHistoryFrameLogScrollFrame, numEntries, 22, 20);
for i=1, 22, 1 do
local line = getglobal("CT_ExpenseHistoryFrameLogLine" .. i);
local dateText = getglobal("CT_ExpenseHistoryFrameLogLine" .. i .. "Date");
local charText = getglobal("CT_ExpenseHistoryFrameLogLine" .. i .. "Char");
local typeText = getglobal("CT_ExpenseHistoryFrameLogLine" .. i .. "Type");
local costFrameName = "CT_ExpenseHistoryFrameLogLine" .. i .. "Cost";
local index = i + FauxScrollFrame_GetOffset(CT_ExpenseHistoryFrameLogScrollFrame);
if ( index <= numEntries ) then
local iStart, iEnd, charName, serverName = string.find(entries[index][2], "^(.+)@(.+)$");
if ( strlen(charName)+strlen(serverName) > 16 ) then
-- We have to cut it down
if ( strlen(serverName) < 8 ) then
charName = strsub(charName, 0, 16-strlen(serverName));
elseif ( strlen(charName) < 8 ) then
serverName = strsub(serverName, 0, 16-strlen(charName));
else
charName = strsub(charName, 0, 8);
serverName = strsub(serverName, 0, 8);
end
end
line:Show();
dateText:SetText(date("%m/%d/%y", entries[index][1]));
charText:SetText(charName .. "@" .. serverName);
typeText:SetText(entries[index][3]);
MoneyFrame_Update(costFrameName, entries[index][4]);
else
line:Hide();
end
end
end
function CT_EH_GetStats(player)
local classFileNames = {
[CT_EH_WARRIOR] = "WARRIOR",
[CT_EH_MAGE] = "MAGE",
[CT_EH_ROGUE] = "ROGUE",
[CT_EH_DRUID] = "DRUID",
[CT_EH_HUNTER] = "HUNTER",
[CT_EH_SHAMAN] = "SHAMAN",
[CT_EH_PRIEST] = "PRIEST",
[CT_EH_WARLOCK] = "WARLOCK",
[CT_EH_PALADIN] = "PALADIN"
};
local costs, totalRepair, numRepair, totalFlight, totalReagents, totalAmmo, totalMail, totalCost, highCost = { }, 0, 0, 0, 0, 0, 0, 0, 0;
for key, tbl in CT_EH_History do
if ( ( key == player or not player ) and type(tbl) == "table" ) then
local total, totalRep, numRep, totalFli, totalReg, totalAmm, totalMai = CT_EH_GetMoney(key);
local _, _, playerName, server = string.find(key, "^(.+)@(.+)$");
local formattedCost;
if ( total < 100 ) then
formattedCost = total .. "c";
elseif ( total < (100*100) ) then
formattedCost = floor(total/100) .. "s";
else
formattedCost = floor(total/(100*100)) .. "g";
end
if ( ( total or 0 ) > highCost ) then
highCost = total;
end
totalRepair = totalRepair + totalRep;
numRepair = numRepair + numRep;
totalFlight = totalFlight + totalFli;
totalReagents = totalReagents + totalReg;
totalAmmo = totalAmmo + totalAmm;
totalMail = totalMail + totalMai;
totalCost = totalCost + total;
tinsert(costs, { total, formattedCost, classFileNames[CT_EH_History[key].class], playerName .. " @ " .. server });
end
end
return costs, totalRepair, numRepair, totalFlight, totalReagents, totalAmmo, totalMail, totalCost, highCost;
end
function CT_EH_StartAnimate()
for i = 1, CT_ExpenseHistoryFrame.numPiles, 1 do
local pile = getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i .. "Pile");
if ( pile:GetParent():IsVisible() ) then
CT_ExpenseHistoryFrame.isAnimated = 1;
getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i .. "Pile"):SetHeight(0);
end
end
end
function CT_EH_ProcessAnimation(elapsed)
this.elapsed = this.elapsed - elapsed;
if ( this.elapsed <= 0 ) then
if ( this.isAnimated ) then
local keepAnimating = false;
for i = 1, CT_ExpenseHistoryFrame.numPiles, 1 do
local pile = getglobal("CT_ExpenseHistoryFrameSummaryDiagramClass" .. i .. "Pile");
local height = pile:GetHeight();
if ( ( height or 0 ) < pile.goalHeight ) then
pile:SetHeight(height+(1*((0.017-this.elapsed)/0.017)));
keepAnimating = true;
end
end
if ( not keepAnimating ) then
CT_ExpenseHistoryFrame.isAnimated = nil;
end
end
this.elapsed = 0.017;
end
end
function CT_EH_GetMoney(name)
local total, totalRep, numRep, totalFli, totalReg, totalAmm, totalMai = 0, 0, 0, 0, 0, 0, 0;
if ( name and CT_EH_History[name] ) then
for k, v in CT_EH_History[name] do
if ( k ~= "class" and k ~= "key" ) then
total = total + v[1];
if ( v[2] == CT_EH_REPAIR ) then
totalRep = totalRep + v[1];
numRep = numRep + 1;
elseif ( v[2] == CT_EH_FLIGHT ) then
totalFli = totalFli + v[1];
elseif ( v[2] == CT_EH_REAGENT ) then
totalReg = totalReg + v[1];
elseif ( v[2] == CT_EH_AMMO ) then
totalAmm = totalAmm + v[1];
elseif ( v[2] == CT_EH_MAIL ) then
totalMai = totalMai + v[1];
end
end
end
end
return total, totalRep, numRep, totalFli, totalReg, totalAmm, totalMai;
end
function CT_EH_OnShow()
PlaySound("UChatScrollButton");
PanelTemplates_SetTab(CT_ExpenseHistoryFrame, 1);
CT_ExpenseHistoryFrameSummary:Show();
CT_ExpenseHistoryFrameLog:Hide();
CT_EH_UpdateSummary();
CT_EH_StartAnimate();
end
function CT_EH_OnEvent(event)
if ( event == "PLAYER_ENTERING_WORLD" ) then
local player = UnitName("player") .. "@" .. GetCVar("realmName");
-- Initialize
if ( not CT_EH_History["startUsage"] ) then
CT_EH_History["startUsage"] = time();
elseif ( not CT_EH_History["version"] ) then
-- We used version 1.0 previously
CT_EH_History["startUsage"] = CT_EH_History["startUsage"] * (24*3600);
end
CT_EH_History["version"] = CT_EH_Version;
if ( not CT_EH_History[player] ) then
CT_EH_History[player] = {
["class"] = UnitClass("player"),
["key"] = player
};
end
end
end
-- Data collection
CT_EH_oldUseContainerItem = UseContainerItem;
function CT_EH_newUseContainerItem(bag, slot)
if ( InRepairMode() ) then
local hasCooldown, repairCost = CT_EHTooltip:SetBagItem(bag,slot);
if (repairCost and repairCost > 0 and repairCost <= GetMoney() and MerchantFrame.repairCost ) then
MerchantFrame.repairCost = MerchantFrame.repairCost + repairCost;
end
end
CT_EH_oldUseContainerItem(bag, slot);
end
UseContainerItem = CT_EH_newUseContainerItem;
CT_EH_oldPickupContainerItem = PickupContainerItem;
function CT_EH_newPickupContainerItem(bag, slot)
if ( InRepairMode() ) then
local hasCooldown, repairCost = CT_EHTooltip:SetBagItem(bag,slot);
if (repairCost and repairCost > 0 and repairCost <= GetMoney() and MerchantFrame.repairCost ) then
MerchantFrame.repairCost = MerchantFrame.repairCost + repairCost;
end
end
CT_EH_oldPickupContainerItem(bag, slot);
end
PickupContainerItem = CT_EH_newPickupContainerItem;
CT_EH_oldRepairAllItems = RepairAllItems;
function CT_EH_newRepairAllItems()
local repairAllCost, canRepair = GetRepairAllCost();
if ( canRepair and repairAllCost <= GetMoney() ) then
if ( MerchantFrame.repairCost ) then
MerchantFrame.repairCost = MerchantFrame.repairCost + repairAllCost;
end
end
CT_EH_oldRepairAllItems();
end
RepairAllItems = CT_EH_newRepairAllItems;
SlashCmdList["EXPENSEHISTORY"] = function()
if ( CT_ExpenseHistoryFrame:IsVisible() ) then
HideUIPanel(CT_ExpenseHistoryFrame);
else
ShowUIPanel(CT_ExpenseHistoryFrame);
end
end
SLASH_EXPENSEHISTORY1 = "/expensehistory";
SLASH_EXPENSEHISTORY2 = "/eh";
function CT_EH_DropDown_OnLoad()
UIDropDownMenu_Initialize(this, CT_EH_DropDown_Initialize);
end
function CT_EH_DropDown_Initialize()
local dropdown, info;
if ( UIDROPDOWNMENU_OPEN_MENU ) then
dropdown = getglobal(UIDROPDOWNMENU_OPEN_MENU);
else
dropdown = this;
end
info = { };
info.text = "All Characters";
info.value = nil;
info.checked = ( not CT_ExpenseHistoryFrame.currPlayer );
info.func = CT_EH_DropDown_OnClick;
UIDropDownMenu_AddButton(info);
for k, v in CT_EH_History do
if ( type(v) == "table" ) then
local total = CT_EH_GetMoney(k);
if ( total >= CT_EH_DISPLAYTHRESHOLD ) then
local _, _, playerName, server = string.find(k, "^(.+)@(.+)$");
info = { };
info.text = playerName .. " @ " .. server;
info.value = k;
info.checked = ( CT_ExpenseHistoryFrame.currPlayer == k );
info.func = CT_EH_DropDown_OnClick;
UIDropDownMenu_AddButton(info);
end
end
end
end
function CT_EH_DropDown_OnClick()
if ( this:GetID() == 1 ) then
CT_ExpenseHistoryFrame.currPlayer = nil;
else
CT_ExpenseHistoryFrame.currPlayer = this.value;
end
CT_EH_UpdateSummary();
CT_EH_UpdateLog();
end
function CT_EH_Tab_OnClick()
if ( this:GetID() == 1 ) then
getglobal("CT_ExpenseHistoryFrameSummary"):Show();
getglobal("CT_ExpenseHistoryFrameLog"):Hide();
CT_EH_UpdateSummary();
elseif ( this:GetID() == 2 ) then
getglobal("CT_ExpenseHistoryFrameSummary"):Hide();
getglobal("CT_ExpenseHistoryFrameLog"):Show();
CT_EH_UpdateLog();
end
PlaySound("igCharacterInfoTab");
PanelTemplates_SetTab(CT_ExpenseHistoryFrame, this:GetID());
end
-- Find out if vendor is reagent vendor
function CT_EH_IsVendor(tbl)
for i = 1, GetMerchantNumItems(), 1 do
local name, texture, price, quantity, numAvailable, isUsable = GetMerchantItemInfo(i);
if ( name and tbl[strlower(name)] ) then
return true;
end
end
return false;
end
local CT_EH_oldMerchantFrame_OnShow = MerchantFrame:GetScript("OnShow");
local CT_EH_oldMerchantFrame_OnHide = MerchantFrame:GetScript("OnHide");
MerchantFrame:SetScript("OnShow", function()
CT_EH_oldMerchantFrame_OnShow();
if ( CT_EH_IsVendor(CT_EH_SCANFORREAGENTS) ) then
MerchantFrame.reagentCost = 0;
else
MerchantFrame.reagentCost = nil;
end
if ( CT_EH_IsVendor(CT_EH_SCANFORAMMO) ) then
MerchantFrame.ammoCost = 0;
else
MerchantFrame.ammoCost = nil;
end
local repairAllCost, canRepair = GetRepairAllCost();
if ( canRepair ) then
MerchantFrame.repairCost = 0;
else
MerchantFrame.repairCost = nil;
end
end);
MerchantFrame:SetScript("OnHide", function()
CT_EH_oldMerchantFrame_OnHide();
if ( MerchantFrame.reagentCost and MerchantFrame.reagentCost > 0 ) then
tinsert(CT_EH_History[UnitName("player") .. "@" .. GetCVar("realmName")], { MerchantFrame.reagentCost, CT_EH_REAGENT, time() });
end
if ( MerchantFrame.ammoCost and MerchantFrame.ammoCost > 0 ) then
tinsert(CT_EH_History[UnitName("player") .. "@" .. GetCVar("realmName")], { MerchantFrame.ammoCost, CT_EH_AMMO, time() });
end
if ( MerchantFrame.repairCost and MerchantFrame.repairCost > 0 ) then
tinsert(CT_EH_History[UnitName("player") .. "@" .. GetCVar("realmName")], { MerchantFrame.repairCost, CT_EH_REPAIR, time() });
end
MerchantFrame.repairCost = nil;
MerchantFrame.reagentCost = nil;
MerchantFrame.ammoCost = nil;
CT_EH_UpdateSummary();
CT_EH_UpdateLog();
end);
local CT_EH_oldBuyMerchantItem = BuyMerchantItem;
function BuyMerchantItem(id, qty)
local name, texture, price, quantity, numAvailable, isUsable = GetMerchantItemInfo(id);
local realPrice = price*(qty or 1);
CT_EH_oldBuyMerchantItem(id, qty);
if ( MerchantFrame.reagentCost and name and CT_EH_SCANFORREAGENTS[strlower(name)] and realPrice <= GetMoney() ) then
MerchantFrame.reagentCost = MerchantFrame.reagentCost + realPrice;
end
if ( MerchantFrame.ammoCost and name and CT_EH_SCANFORAMMO[strlower(name)] and realPrice <= GetMoney() ) then
MerchantFrame.ammoCost = MerchantFrame.ammoCost + realPrice;
end
end
local CT_EH_oldSendMail = SendMail;
function SendMail(target, subject, body)
CT_EH_oldSendMail(target, subject, body);
local price = SendMailCostMoneyFrame.staticMoney;
if ( price <= GetMoney() ) then
tinsert(CT_EH_History[UnitName("player") .. "@" .. GetCVar("realmName")], { price, CT_EH_MAIL, time() });
CT_EH_UpdateSummary();
CT_EH_UpdateLog();
end
end
CT_EH_oldTakeTaxiNode = TakeTaxiNode;
function CT_EH_newTakeTaxiNode(id)
if ( GetMoney() >= TaxiNodeCost(id) ) then
tinsert(CT_EH_History[UnitName("player") .. "@" .. GetCVar("realmName")], { TaxiNodeCost(id), CT_EH_FLIGHT, time() });
CT_EH_UpdateSummary();
CT_EH_UpdateLog();
end
CT_EH_oldTakeTaxiNode(id);
end
TakeTaxiNode = CT_EH_newTakeTaxiNode;
if ( CT_RegisterMod ) then
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);
else
DEFAULT_CHAT_FRAME:AddMessage("<CTMod> Expense History loaded. Type /expensehistory or /eh to display the window.", 1, 1, 0);
end
Generated by GNU Enscript 1.6.5.90.