UIPanelWindows["CT_RaidTrackerFrame"] = { area = "left", pushable = 1 }; CT_RAIDTRACKER_RAIDS = "Raids: %d"; CT_RaidTracker_Online = { }; CT_RaidTracker_Version = "v1.2"; CT_RaidTracker_Events = { }; CT_RaidTracker_LastPage = { }; CT_RaidTracker_SortOptions = { ["method"] = "name", ["way"] = "asc", ["itemmethod"] = "looted", ["itemway"] = "asc", ["itemfilter"] = 1, ["playerraidway"] = "desc", ["playeritemfilter"] = 1, ["playeritemmethod"] = "name", ["playeritemway"] = "asc", ["itemhistorymethod"] = "name", ["itemhistoryway"] = "asc" }; CT_RaidTracker_ItemTextures = { ["Head"] = "INV_Helmet_22", ["Neck"] = "INV_Jewelry_Necklace_11", ["Shoulder"] = "INV_Shoulder_23", ["Back"] = "INV_Misc_Cape_16", ["Chest"] = "INV_Chest_Chain_05", ["Shirt"] = "INV_Shirt_Black_01", ["Shield"] = "INV_Shield_05", ["Tabard"] = "INV_Misc_TabardPVP_04", ["Wrist"] = "INV_Bracer_07", ["Two-Hand-Other"] = "INV_Sword_39", ["Two-Hand-Sword"] = "INV_Sword_39", ["Two-Hand-Staff"] = "INV_Staff_30", ["Two-Hand-Polearm"] = "INV_Spear_06", ["Two-Hand-Axe"] = "INV_Axe_09", ["Two-Hand-Mace"] = "INV_Hammer_04", ["Back"] = "INV_Misc_Cape_16", ["Off Hand"] = "INV_Misc_Book_06", ["Held In Off-hand"] = "INV_Misc_Book_06", ["Off Hand-Other"] = "INV_Misc_Wrench_01", ["Gun"] = "INV_Weapon_Rifle_01", ["Bow"] = "INV_Weapon_Bow_01", ["Wand"] = "INV_Wand_02", ["Projectile"] = "INV_Ammo_Arrow_01", ["Thrown"] = "INV_Spear_07", ["Hands"] = "INV_Gauntlets_16", ["Waist"] = "INV_Belt_02", ["Legs"] = "INV_Pants_11", ["Feet"] = "INV_Boots_05", ["Finger"] = "INV_Jewelry_Ring_30", ["Trinket"] = "INV_Jewelry_Talisman_10", ["Other"] = "INV_Misc_Gear_08", ["Special-Sword"] = "INV_Sword_18", ["Special-Dagger"] = "INV_Weapon_ShortBlade_11", ["Special-Mace"] = "INV_Hammer_17", ["Special-Axe"] = "INV_Axe_09", ["Special-Fist Weapon"] = "INV_Misc_MonsterClaw_04", ["Special-Shield"] = "INV_Shield_05", }; CT_RaidTracker_RarityTable = { ["ff9d9d9d"] = -1, ["ffffffff"] = 0, ["ff1eff00"] = 1, ["ff0070dd"] = 2, ["ffa335ee"] = 3, ["ffff8000"] = 4 }; function CT_RaidTracker_GetTime(dDate) if ( not dDate ) then return nil; end local _, _, mon, day, year, hr, min, sec = string.find(dDate, "(%d+)/(%d+)/(%d+) (%d+):(%d+):(%d+)"); local table = date("*t"); table["month"] = tonumber(mon); table["year"] = tonumber("20" .. year); table["day"] = tonumber(day); table["hour"] = tonumber(hr); table["min"] = tonumber(min); table["sec"] = tonumber(sec); return time(table); end function CT_RaidTracker_SortRaidTable() table.sort( CT_RaidTracker_RaidLog, function(a1, a2) if ( a1 and a2 ) then return CT_RaidTracker_GetTime(a1.key) > CT_RaidTracker_GetTime(a2.key); end end ); end function CT_RaidTracker_GetRaidTitle(id, hideid) if ( CT_RaidTracker_RaidLog[id] and CT_RaidTracker_RaidLog[id].key ) then local _, _, mon, day, year, hr, min, sec = string.find(CT_RaidTracker_RaidLog[id].key, "(%d+)/(%d+)/(%d+) (%d+):(%d+):(%d+)"); if ( mon ) then local months = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; if ( hideid ) then return months[tonumber(mon)] .. " " .. day .. " '" .. year .. ", " .. hr .. ":" .. min; else return "[" .. (getn(CT_RaidTracker_RaidLog)-id+1) .. "] " .. months[tonumber(mon)] .. " " .. day .. " '" .. year .. ", " .. hr .. ":" .. min; end else return ""; end end return ""; end function CT_RaidTracker_SaveNote(id) local text = CT_RaidTrackerEditNoteFrameNoteEB:GetText(); if ( strlen(text) == 0 ) then text = nil; end if ( CT_RaidTrackerEditNoteFrame.type == "item" ) then CT_RaidTracker_RaidLog[id]["Loot"][CT_RaidTrackerEditNoteFrame.itemid]["note"] = text; elseif ( CT_RaidTrackerEditNoteFrame.type == "raid" ) then CT_RaidTracker_RaidLog[id]["note"] = text; else CT_RaidTracker_RaidLog[id]["Notes"][CT_RaidTrackerEditNoteFrame.playerid] = text; end CT_RaidTracker_Update(); CT_RaidTracker_UpdateView(); end function CT_RaidTracker_EditNote_OnShow() local text; if ( this.type == "raid" ) then text = CT_RaidTracker_RaidLog[this.id]["note"]; elseif ( this.type == "item" ) then text = CT_RaidTracker_RaidLog[this.id]["Loot"][this.itemid]["note"]; else text = CT_RaidTracker_RaidLog[this.id]["Notes"][this.playerid]; end if ( text ) then getglobal(this:GetName() .. "NoteEB"):SetText(text); getglobal(this:GetName() .. "NoteEB"):HighlightText(); else getglobal(this:GetName() .. "NoteEB"):SetText(""); end getglobal(this:GetName() .. "Editing"):SetText("Editing note for " .. this.type .. " \"|c" .. this.color .. "" .. this.text .. "|r\""); end function CT_RaidTracker_Update() if ( getn(CT_RaidTracker_LastPage) > 0 ) then CT_RaidTrackerFrameBackButton:Enable(); else CT_RaidTrackerFrameBackButton:Disable(); end if ( getn(CT_RaidTracker_RaidLog) > 0 ) then if ( CT_RaidTrackerFrame.selected ) then local selected; if ( not CT_RaidTracker_RaidLog[CT_RaidTrackerFrame.selected] ) then while ( not selected ) do if ( CT_RaidTrackerFrame.selected < 1 ) then selected = 1; CT_RaidTrackerFrame.selected = nil; else CT_RaidTrackerFrame.selected = CT_RaidTrackerFrame.selected - 1; if ( CT_RaidTracker_RaidLog[CT_RaidTrackerFrame.selected] ) then selected = 2; end end end end if ( not selected or selected == 2 ) then if ( not CT_RaidTracker_RaidLog[CT_RaidTrackerFrame.selected] or getn(CT_RaidTracker_RaidLog[CT_RaidTrackerFrame.selected]["Loot"]) == 0 ) then CT_RaidTrackerFrame.type = "raids"; CT_RaidTrackerFrameViewButton:Disable(); else CT_RaidTrackerFrameViewButton:Enable(); end end end CT_EmptyRaidTrackerFrame:Hide(); CT_RaidTrackerFrameNoteButton:Enable(); CT_RaidTrackerFrameDeleteButton:Enable(); local hasItem; for k, v in CT_RaidTracker_RaidLog do for key, val in v["Loot"] do if ( val["player"] == CT_RaidTrackerFrame.player ) then hasItem = 1; break; end end if ( hasItem ) then break; end end if ( CT_RaidTrackerFrame.type == "raids" or not CT_RaidTrackerFrame.type ) then CT_RaidTrackerFrameViewButton:SetText("View Items"); elseif ( CT_RaidTrackerFrame.type == "items" ) then CT_RaidTrackerFrameViewButton:SetText("View Players"); elseif ( CT_RaidTrackerFrame.type == "player" ) then if ( not hasItem ) then CT_RaidTrackerFrameViewButton:Disable(); else CT_RaidTrackerFrameViewButton:Enable(); end CT_RaidTrackerFrameViewButton:SetText("View Loot"); CT_RaidTrackerFrameNoteButton:Disable(); CT_RaidTrackerFrameDeleteButton:Disable(); elseif ( CT_RaidTrackerFrame.type == "playeritems" ) then CT_RaidTrackerFrameViewButton:SetText("View Raids"); CT_RaidTrackerFrameNoteButton:Disable(); CT_RaidTrackerFrameDeleteButton:Disable(); if ( not hasItem ) then CT_RaidTrackerFrame.type = "player"; CT_RaidTracker_Update(); CT_RaidTracker_UpdateView(); end elseif ( CT_RaidTrackerFrame.type == "itemhistory" ) then CT_RaidTrackerFrameNoteButton:Disable(); CT_RaidTrackerFrameDeleteButton:Disable(); CT_RaidTrackerFrameViewButton:Disable(); end else CT_EmptyRaidTrackerFrame:Show(); CT_RaidTrackerDetailScrollFramePlayers:Hide(); CT_RaidTrackerDetailScrollFrameItems:Hide(); CT_RaidTrackerDetailScrollFramePlayer:Hide(); CT_RaidTrackerFrameNoteButton:Disable(); CT_RaidTrackerFrameDeleteButton:Disable(); CT_RaidTrackerFrameViewButton:Disable(); end local numRaids = getn(CT_RaidTracker_RaidLog); local numEntries = numRaids; -- Update Quest Count CT_RaidTrackerQuestCount:SetText(format(CT_RAIDTRACKER_RAIDS, numRaids)); -- ScrollFrame update FauxScrollFrame_Update(CT_RaidTrackerListScrollFrame, numEntries, 6, 16, nil, nil, nil, CT_RaidTrackerHighlightFrame, 293, 316 ); -- Update the quest listing CT_RaidTrackerHighlightFrame:Hide(); for i=1, 6, 1 do local title = getglobal("CT_RaidTrackerTitle" .. i); local normaltext = getglobal("CT_RaidTrackerTitle" .. i .. "NormalText"); local highlighttext = getglobal("CT_RaidTrackerTitle" .. i .. "HighlightText"); local disabledtext = getglobal("CT_RaidTrackerTitle" .. i .. "DisabledText"); local highlight = getglobal("CT_RaidTrackerTitle" .. i .. "Highlight"); local index = i + FauxScrollFrame_GetOffset(CT_RaidTrackerListScrollFrame); if ( index <= numEntries ) then local raidTitle = CT_RaidTracker_GetRaidTitle(index); local raidTag = CT_RaidTracker_RaidLog[index]["note"]; if ( not raidTag ) then raidTag = ""; else raidTag = " (" .. raidTag .. ")"; end if ( raidTitle ) then title:SetText(raidTitle .. raidTag); else title:SetText(""); end title:Show(); -- Place the highlight and lock the highlight state if ( CT_RaidTrackerFrame.selected and CT_RaidTrackerFrame.selected == index ) then CT_RaidTrackerSkillHighlight:SetVertexColor(1, 1, 0); CT_RaidTrackerHighlightFrame:SetPoint("TOPLEFT", "CT_RaidTrackerTitle"..i, "TOPLEFT", 0, 0); CT_RaidTrackerHighlightFrame:Show(); title:LockHighlight(); else title:UnlockHighlight(); end else title:Hide(); end end end function CT_RaidTracker_SelectRaid(id) local raidid = id + FauxScrollFrame_GetOffset(CT_RaidTrackerListScrollFrame); CT_RaidTracker_GetPage(); CT_RaidTrackerFrame.selected = raidid; if ( getn(CT_RaidTracker_RaidLog[raidid]["Loot"]) == 0 or ( CT_RaidTrackerFrame.type and CT_RaidTrackerFrame.type ~= "items" ) ) then CT_RaidTrackerFrame.type = "raids"; end CT_RaidTracker_UpdateView(); CT_RaidTracker_Update(); end function CT_RaidTracker_ShowInfo(player) CT_RaidTracker_GetPage(); CT_RaidTrackerFrame.type = "player"; CT_RaidTrackerFrame.player = player; CT_RaidTrackerFrame.selected = nil; CT_RaidTracker_Update(); CT_RaidTracker_UpdateView(); end function CT_RaidTracker_GetItemType(link) local types = { ["Head"] = 1, ["Neck"] = 1, ["Shoulder"] = 1, ["Back"] = 1, ["Chest"] = 1, ["Shirt"] = 1, ["Tabard"] = 1, ["Wrist"] = 1, ["Two-Hand"] = 1, ["One-Hand"] = 1, ["Main Hand"] = 1, ["Off Hand"] = 1, ["Held In Off-hand"] = 1, ["Gun"] = 1, ["Bow"] = 1, ["Wand"] = 1, ["Projectile"] = 1, ["Thrown"] = 1, ["Hands"] = 1, ["Waist"] = 1, ["Legs"] = 1, ["Feet"] = 1, ["Finger"] = 1, ["Trinket"] = 1 }; local special = { ["Fist Weapon"] = 1, ["Dagger"] = 1, ["Shield"] = 1, ["Sword"] = 1, ["Axe"] = 1, ["Polearm"] = 1, ["Mace"] = 1, ["Staff"] = 1 }; for i = 1, 30, 1 do getglobal("CT_RTTooltipTextLeft" .. i):SetText(""); getglobal("CT_RTTooltipTextLeft" .. i):Hide(); getglobal("CT_RTTooltipTextRight" .. i):SetText(""); getglobal("CT_RTTooltipTextRight" .. i):Hide(); end CT_RTTooltip:SetHyperlink(link); for i = 2, min(CT_RTTooltip:NumLines(), 5), 1 do local textleft = getglobal("CT_RTTooltipTextLeft" .. i); local textright = getglobal("CT_RTTooltipTextRight" .. i); if ( textleft and types[textleft:GetText()] ) then if ( ( textleft:GetText() == "Off Hand" or textleft:GetText() == "Main Hand" or textleft:GetText() == "One-Hand" or textleft:GetText() == "Two-Hand" ) and strlen(textright:GetText()) > 0 ) then if ( special[textright:GetText()] ) then if ( textleft:GetText() == "Two-Hand" ) then return "Two-Hand-" .. textright:GetText(); else return "Special-" .. textright:GetText(); end else return textleft:GetText().."-Other"; end else return textleft:GetText(); end elseif ( textright and types[textright:GetText()] ) then return textright:GetText(); end end return "Other"; end function CT_RaidTracker_Delete(id, type, typeid) if ( type == "raid" ) then table.remove(CT_RaidTracker_RaidLog, id); if ( id == CT_RaidTracker_GetCurrentRaid ) then CT_RaidTracker_GetCurrentRaid = nil; end if ( CT_RaidTrackerFrame.selected == id ) then CT_RaidTrackerFrame.selected = CT_RaidTrackerFrame.selected - 1; if ( CT_RaidTrackerFrame.selected < 1 ) then CT_RaidTrackerFrame.selected = 1; end CT_RaidTrackerFrame.type = "raids"; end elseif ( type == "item" ) then table.remove(CT_RaidTracker_RaidLog[id]["Loot"], typeid); elseif ( type == "player" ) then for key, val in CT_RaidTracker_RaidLog[id]["Join"] do if ( val["player"] == typeid ) then CT_RaidTracker_RaidLog[id]["Join"][key] = nil; end end for key, val in CT_RaidTracker_RaidLog[id]["Leave"] do if ( val["player"] == typeid ) then CT_RaidTracker_RaidLog[id]["Leave"][key] = nil; end end end CT_RaidTracker_Update(); CT_RaidTracker_UpdateView(); end function CT_RaidTracker_Sort(tbl, method, way) if ( way == "asc" ) then table.sort( tbl, function(a1, a2) return a1[method] < a2[method]; end ); else table.sort( tbl, function(a1, a2) return a1[method] > a2[method]; end ); end return tbl; end function CT_RaidTracker_SortPlayerRaids(id) if ( CT_RaidTrackerFrame.type == "itemhistory" ) then local table = { "name", "looter" }; if ( CT_RaidTracker_SortOptions["itemhistorymethod"] == table[id] ) then if ( CT_RaidTracker_SortOptions["itemhistoryway"] == "asc" ) then CT_RaidTracker_SortOptions["itemhistoryway"] = "desc"; else CT_RaidTracker_SortOptions["itemhistoryway"] = "asc"; end else CT_RaidTracker_SortOptions["itemhistoryway"] = "asc"; CT_RaidTracker_SortOptions["itemhistorymethod"] = table[id]; end else if ( CT_RaidTracker_SortOptions["playerraidway"] == "asc" ) then CT_RaidTracker_SortOptions["playerraidway"] = "desc"; else CT_RaidTracker_SortOptions["playerraidway"] = "asc"; end end CT_RaidTracker_UpdateView(); end function CT_RaidTracker_CompareItems(a1, a2) -- This function could probably be better, but I can't think of any better way while still maintaining functionality local filter, method, way = CT_RaidTracker_SortOptions["itemfilter"], CT_RaidTracker_SortOptions["itemmethod"], CT_RaidTracker_SortOptions["itemway"]; if ( CT_RaidTrackerFrame.type == "playeritems" ) then filter, method, way = CT_RaidTracker_SortOptions["playeritemfilter"], CT_RaidTracker_SortOptions["playeritemmethod"], CT_RaidTracker_SortOptions["playeritemway"]; end -- Check to see if it matches the rarity requirements if ( not CT_RaidTracker_RarityTable[a1["item"]["c"]] or CT_RaidTracker_RarityTable[a1["item"]["c"]] < filter ) then return false; elseif ( CT_RaidTracker_RarityTable[a2["item"]["c"]] < filter ) then return true; end if ( method == "name" ) then local c1, c2 = a1["item"]["name"], a2["item"]["name"]; if ( c1 == c2 ) then c1, c2 = a1["player"], a2["player"]; end if ( way == "asc" ) then return c1 < c2; else return c1 > c2; end elseif ( method == "looter" ) then local c1, c2 = a1["player"], a2["player"]; if ( c1 == c2 ) then c1, c2 = CT_RaidTracker_RarityTable[a2["item"]["c"]], CT_RaidTracker_RarityTable[a1["item"]["c"]]; if ( c1 == c2 ) then c1, c2 = a1["item"]["name"], a2["item"]["name"]; end end if ( way == "asc" ) then return c1 < c2; else return c1 > c2; end elseif ( method == "looted" ) then if ( way == "asc" ) then return CT_RaidTracker_GetTime(a1["time"]) < CT_RaidTracker_GetTime(a2["time"]); else return CT_RaidTracker_GetTime(a1["time"]) > CT_RaidTracker_GetTime(a2["time"]); end else local c1, c2 = CT_RaidTracker_RarityTable[a1["item"]["c"]], CT_RaidTracker_RarityTable[a2["item"]["c"]]; if ( c1 == c2 ) then c1, c2 = a1["item"]["name"], a2["item"]["name"]; if ( c1 == c2 ) then c1, c2 = a1["player"], a2["player"]; else return c1 < c2; end end if ( way == "asc" ) then return c1 < c2; else return c1 > c2; end end end function CT_RaidTracker_SortItem(tbl, method, way) table.sort( tbl, CT_RaidTracker_CompareItems ); return tbl; end function CT_RaidTracker_SortItemBy(id) local table = { "name", "looted", "looter", "rarity" }; local prefix = ""; if ( CT_RaidTrackerFrame.type == "playeritems" ) then prefix = "player"; end if ( CT_RaidTracker_SortOptions[prefix.."itemmethod"] == table[id] ) then if ( CT_RaidTracker_SortOptions[prefix.."itemway"] == "asc" ) then CT_RaidTracker_SortOptions[prefix.."itemway"] = "desc"; else CT_RaidTracker_SortOptions[prefix.."itemway"] = "asc"; end else CT_RaidTracker_SortOptions[prefix.."itemmethod"] = table[id]; CT_RaidTracker_SortOptions[prefix.."itemway"] = "asc"; end CT_RaidTracker_UpdateView(); end function CT_RaidTracker_SortBy(id) local table = { "name", "join", "leave" }; if ( CT_RaidTracker_SortOptions["method"] == table[id] ) then if ( CT_RaidTracker_SortOptions["way"] == "asc" ) then CT_RaidTracker_SortOptions["way"] = "desc"; else CT_RaidTracker_SortOptions["way"] = "asc"; end else CT_RaidTracker_SortOptions["method"] = table[id]; if ( table[id] ~= "leave" ) then CT_RaidTracker_SortOptions["way"] = "asc"; else CT_RaidTracker_SortOptions["way"] = "desc"; end end CT_RaidTracker_UpdateView(); end function CT_RaidTracker_UpdateView() if ( CT_EmptyRaidTrackerFrame:IsVisible() ) then return; end local raidid = CT_RaidTrackerFrame.selected; local num = 1; while ( getglobal("CT_RaidTrackerItem" .. num) ) do getglobal("CT_RaidTrackerItem" .. num):Hide(); num = num + 1; end if ( CT_RaidTrackerFrame.type == "raids" or not CT_RaidTrackerFrame.type ) then CT_RaidTrackerDetailScrollFramePlayers:Show(); CT_RaidTrackerDetailScrollFramePlayer:Hide(); CT_RaidTrackerDetailScrollFrameItems:Hide(); local players, str, num = { }, "", 0; if ( CT_RaidTracker_RaidLog[raidid] ) then local playerIndexes = { }; for key, val in CT_RaidTracker_RaidLog[raidid]["Join"] do if ( val["player"] ) then local id = playerIndexes[val["player"]]; local time = CT_RaidTracker_GetTime(val["time"]); if ( not id or time < players[id]["join"] ) then if ( playerIndexes[val["player"]] ) then players[id] = { ["join"] = time, ["name"] = val["player"] }; else tinsert(players, { ["join"] = time, ["name"] = val["player"] }); playerIndexes[val["player"]] = getn(players); end end id = playerIndexes[val["player"]]; if ( not players[id]["lastjoin"] or players[id]["lastjoin"] < time ) then players[id]["lastjoin"] = time; end end end for key, val in CT_RaidTracker_RaidLog[raidid]["Leave"] do local id = playerIndexes[val["player"]]; local time = CT_RaidTracker_GetTime(val["time"]); if ( id ) then if ( ( not players[id]["leave"] or time > players[id]["leave"] ) and time >= players[id]["lastjoin"] ) then players[id]["leave"] = time; end end end for k, v in players do if ( not v["leave"] ) then -- Very ugly hack, I know :( players[k]["leave"] = 99999999999; end end players = CT_RaidTracker_Sort(players, CT_RaidTracker_SortOptions["method"], CT_RaidTracker_SortOptions["way"]); num = 0; for key, val in players do num = num + 1; local name = getglobal("CT_RaidTrackerPlayerLine" .. num .. "Name"); local number = getglobal("CT_RaidTrackerPlayerLine" .. num .. "Number"); local join = getglobal("CT_RaidTrackerPlayerLine" .. num .. "Join"); local leave = getglobal("CT_RaidTrackerPlayerLine" .. num .. "Leave"); if ( name ) then getglobal("CT_RaidTrackerPlayerLine" .. num):Show(); name:SetText(val["name"]); local iNumber = num; if ( iNumber < 10 ) then iNumber = " " .. iNumber; end number:SetText(iNumber); join:SetText(date("%I:%M%p", val["join"])); if ( val["leave"] == 99999999999 ) then leave:SetText(""); else leave:SetText(date("%I:%M%p", val["leave"])); end end end for i = num+1, 100, 1 do getglobal("CT_RaidTrackerPlayerLine" .. i):Hide(); end end CT_RaidTrackerRaidText:SetText(str); CT_RaidTrackerParticipantsText:SetText("Participants (" .. num .. "):"); CT_RaidTrackerDetailScrollFramePlayers:UpdateScrollChildRect(); elseif ( CT_RaidTrackerFrame.type == "items" ) then CT_RaidTrackerDetailScrollFramePlayers:Hide(); CT_RaidTrackerDetailScrollFramePlayer:Hide(); CT_RaidTrackerDetailScrollFrameItems:Show(); local numItems, numHidden = 0, 0; if ( CT_RaidTracker_RaidLog[raidid] ) then local loot = CT_RaidTracker_SortItem(CT_RaidTracker_RaidLog[raidid]["Loot"], CT_RaidTracker_SortOptions["itemmethod"], CT_RaidTracker_SortOptions["itemway"]); for key, val in loot do local _, _, lootTime = string.find(val["time"], " (%d+:%d+:%d+)$"); if ( lootTime ) then local found; local i = 1; if ( not found ) then if ( CT_RaidTracker_RarityTable[val["item"]["c"]] >= CT_RaidTracker_SortOptions["itemfilter"] ) then numItems = numItems + 1; if ( getglobal("CT_RaidTrackerItem" .. numItems) ) then getglobal("CT_RaidTrackerItem" .. numItems).raidid = CT_RaidTrackerFrame.selected; getglobal("CT_RaidTrackerItem" .. numItems).itemid = numItems; getglobal("CT_RaidTrackerItem" .. numItems).itemname = val["item"]["name"]; getglobal("CT_RaidTrackerItem" .. numItems):Show(); if ( val["item"]["count"] and val["item"]["count"] > 1 ) then getglobal("CT_RaidTrackerItem" .. numItems .. "Count"):Show(); getglobal("CT_RaidTrackerItem" .. numItems .. "Count"):SetText(val["item"]["count"]); else getglobal("CT_RaidTrackerItem" .. numItems .. "Count"):Hide(); end if ( val["item"]["type"] and CT_RaidTracker_ItemTextures[val["item"]["type"]] ) then getglobal("CT_RaidTrackerItem" .. numItems .. "IconTexture"):SetTexture("Interface\\Icons\\" .. CT_RaidTracker_ItemTextures[val["item"]["type"]]); else getglobal("CT_RaidTrackerItem" .. numItems .. "IconTexture"):SetTexture("Interface\\Icons\\" .. CT_RaidTracker_ItemTextures["Other"]); end local color = val["item"]["c"]; if ( color == "ff1eff00" ) then color = "11009900"; end getglobal("CT_RaidTrackerItem" .. numItems .. "Description"):SetText("|c" .. color .. val["item"]["name"] .. "|r\nLooted by: " .. val["player"]); if ( val["note"] ) then getglobal("CT_RaidTrackerItem" .. numItems .. "NoteNormalTexture"):SetVertexColor(1, 1, 1); else getglobal("CT_RaidTrackerItem" .. numItems .. "NoteNormalTexture"):SetVertexColor(0.5, 0.5, 0.5); end end else numHidden = numHidden + 1; end end end end end for i = numItems+1, 255, 1 do getglobal("CT_RaidTrackerItem" .. i):Hide(); end if ( numHidden == 0 ) then CT_RaidTrackerItemsText:SetText("Items (" .. numItems .. "):"); else CT_RaidTrackerItemsText:SetText("Items (" .. numItems .. "/" .. numHidden + numItems .. ")"); end UIDropDownMenu_SetSelectedID(CT_RaidTrackerRarityDropDown, CT_RaidTracker_SortOptions["itemfilter"]); local colors = { "|c001eff00Uncommon|r", "|c000070ddRare|r", "|c00a335eeEpic|r", "|c00ff8000Legendary" }; CT_RaidTrackerRarityDropDownText:SetText(colors[CT_RaidTracker_SortOptions["itemfilter"]]); CT_RaidTrackerDetailScrollFrameItems:UpdateScrollChildRect(); elseif ( CT_RaidTrackerFrame.type == "player" ) then CT_RaidTrackerDetailScrollFramePlayers:Hide(); CT_RaidTrackerDetailScrollFramePlayer:Show(); CT_RaidTrackerDetailScrollFrameItems:Hide(); CT_RaidTrackerPlayerRaidTabLooter:Hide(); CT_RaidTrackerPlayerRaidTab1:SetWidth(300); CT_RaidTrackerPlayerRaidTab1Middle:SetWidth(290); local name = CT_RaidTrackerFrame.player; local raids = { }; for k, v in CT_RaidTracker_RaidLog do local isInRaid; for key, val in v["Join"] do if ( val["player"] == name ) then tinsert(raids, { k, v }); break; end end end table.sort( raids, function(a1, a2) if ( CT_RaidTracker_SortOptions["playerraidway"] == "asc" ) then return CT_RaidTracker_GetTime(a1[2]["key"]) < CT_RaidTracker_GetTime(a2[2]["key"]); else return CT_RaidTracker_GetTime(a1[2]["key"]) > CT_RaidTracker_GetTime(a2[2]["key"]); end end ); for k, v in raids do local raid = getglobal("CT_RaidTrackerPlayerRaid" .. k); raid.raidid = v[1]; raid.playername = name; raid.raidtitle = CT_RaidTracker_GetRaidTitle(v[1], 1); local iNumber = getn(CT_RaidTracker_RaidLog)-v[1]+1; if ( iNumber < 10 ) then iNumber = " " .. iNumber; end getglobal(raid:GetName() .. "MouseOverLeft"):Hide(); getglobal(raid:GetName() .. "MouseOverRight"):Hide(); getglobal(raid:GetName() .. "HitAreaLeft"):Hide(); getglobal(raid:GetName() .. "HitAreaRight"):Hide(); getglobal(raid:GetName() .. "HitArea"):Show(); getglobal(raid:GetName() .. "Note"):Hide(); getglobal(raid:GetName() .. "NoteButton"):Show(); getglobal(raid:GetName() .. "DeleteButton"):Show(); getglobal(raid:GetName() .. "DeleteText"):Show(); getglobal(raid:GetName() .. "Number"):SetText(iNumber); getglobal(raid:GetName() .. "Name"):SetWidth(200); getglobal(raid:GetName() .. "Name"):SetText(CT_RaidTracker_GetRaidTitle(v[1], 1)); if ( v[2]["Notes"][name] ) then getglobal(raid:GetName() .. "NoteButtonNormalTexture"):SetVertexColor(1, 1, 1); else getglobal(raid:GetName() .. "NoteButtonNormalTexture"):SetVertexColor(0.5, 0.5, 0.5); end raid:Show(); end for i = getn(raids)+1, 255, 1 do getglobal("CT_RaidTrackerPlayerRaid" .. i):Hide(); end CT_RaidTrackerPlayerText:SetText(name .. "'s Raids (" .. getn(raids) .. "):"); CT_RaidTrackerDetailScrollFramePlayer:UpdateScrollChildRect(); elseif ( CT_RaidTrackerFrame.type == "itemhistory" ) then CT_RaidTrackerDetailScrollFramePlayers:Hide(); CT_RaidTrackerDetailScrollFramePlayer:Show(); CT_RaidTrackerDetailScrollFrameItems:Hide(); CT_RaidTrackerPlayerRaidTabLooter:Show(); CT_RaidTrackerPlayerRaidTab1:SetWidth(163); CT_RaidTrackerPlayerRaidTab1Middle:SetWidth(155); local name, totalItems = CT_RaidTrackerFrame.itemname, 0; local items = { }; for k, v in CT_RaidTracker_RaidLog do for key, val in v["Loot"] do if ( val["item"]["name"] == name ) then tinsert(items, { k, v, val }); if ( val["item"]["count"] ) then totalItems = totalItems + val["item"]["count"]; else totalItems = totalItems + 1; end end end end table.sort( items, function(a1, a2) if ( CT_RaidTracker_SortOptions["itemhistorymethod"] == "looter" ) then if ( CT_RaidTracker_SortOptions["itemhistoryway"] == "asc" ) then return a1[3]["player"] < a2[3]["player"]; else return a1[3]["player"] > a2[3]["player"]; end else if ( CT_RaidTracker_SortOptions["itemhistoryway"] == "asc" ) then return CT_RaidTracker_GetTime(a1[2]["key"]) < CT_RaidTracker_GetTime(a2[2]["key"]); else return CT_RaidTracker_GetTime(a1[2]["key"]) > CT_RaidTracker_GetTime(a2[2]["key"]); end end end ); for k, v in items do local raid = getglobal("CT_RaidTrackerPlayerRaid" .. k); raid.raidid = v[1]; local iNumber = getn(CT_RaidTracker_RaidLog)-v[1]+1; if ( iNumber < 10 ) then iNumber = " " .. iNumber; end getglobal(raid:GetName() .. "MouseOver"):Hide(); getglobal(raid:GetName() .. "HitAreaLeft"):Show(); getglobal(raid:GetName() .. "HitAreaRight"):Show(); getglobal(raid:GetName() .. "HitArea"):Hide(); getglobal(raid:GetName() .. "NoteButton"):Hide(); getglobal(raid:GetName() .. "Note"):Show(); getglobal(raid:GetName() .. "DeleteButton"):Hide(); getglobal(raid:GetName() .. "DeleteText"):Hide(); getglobal(raid:GetName() .. "Number"):SetText(iNumber); getglobal(raid:GetName() .. "Name"):SetWidth(130); getglobal(raid:GetName() .. "Name"):SetText(CT_RaidTracker_GetRaidTitle(v[1], 1)); getglobal(raid:GetName() .. "Note"):SetText(v[3]["player"]); raid:Show(); end for i = getn(items)+1, 255, 1 do getglobal("CT_RaidTrackerPlayerRaid" .. i):Hide(); end CT_RaidTrackerPlayerText:SetText(name .. " (" .. getn(items) .. "/" .. totalItems .. "):"); CT_RaidTrackerDetailScrollFramePlayer:UpdateScrollChildRect(); elseif ( CT_RaidTrackerFrame.type == "playeritems" ) then CT_RaidTrackerDetailScrollFramePlayers:Hide(); CT_RaidTrackerDetailScrollFramePlayer:Hide(); CT_RaidTrackerDetailScrollFrameItems:Show(); local name = CT_RaidTrackerFrame.player; local loot = { }; for k, v in CT_RaidTracker_RaidLog do for key, val in v["Loot"] do if ( val["player"] == name ) then tinsert( loot, { ["note"] = val["note"], ["player"] = val["player"], ["time"] = val["time"], ["item"] = val["item"], ["ids"] = { k, key } } ); end end end local numItems, numHidden = 0, 0; loot = CT_RaidTracker_SortItem(loot, CT_RaidTracker_SortOptions["playeritemmethod"], CT_RaidTracker_SortOptions["playeritemway"]); for key, val in loot do local _, _, lootTime = string.find(val["time"], " (%d+:%d+:%d+)$"); if ( lootTime ) then local found; local i = 1; if ( not found ) then if ( CT_RaidTracker_RarityTable[val["item"]["c"]] >= CT_RaidTracker_SortOptions["playeritemfilter"] ) then numItems = numItems + 1; if ( getglobal("CT_RaidTrackerItem" .. numItems) ) then getglobal("CT_RaidTrackerItem" .. numItems).raidid = val["ids"][1]; getglobal("CT_RaidTrackerItem" .. numItems).itemid = val["ids"][2]; getglobal("CT_RaidTrackerItem" .. numItems).itemname = val["item"]["name"]; getglobal("CT_RaidTrackerItem" .. numItems):Show(); if ( val["item"]["count"] and val["item"]["count"] > 1 ) then getglobal("CT_RaidTrackerItem" .. numItems .. "Count"):Show(); getglobal("CT_RaidTrackerItem" .. numItems .. "Count"):SetText(val["item"]["count"]); else getglobal("CT_RaidTrackerItem" .. numItems .. "Count"):Hide(); end if ( val["item"]["type"] and CT_RaidTracker_ItemTextures[val["item"]["type"]] ) then getglobal("CT_RaidTrackerItem" .. numItems .. "IconTexture"):SetTexture("Interface\\Icons\\" .. CT_RaidTracker_ItemTextures[val["item"]["type"]]); else getglobal("CT_RaidTrackerItem" .. numItems .. "IconTexture"):SetTexture("Interface\\Icons\\" .. CT_RaidTracker_ItemTextures["Other"]); end local color = val["item"]["c"]; if ( color == "ff1eff00" ) then color = "11009900"; end getglobal("CT_RaidTrackerItem" .. numItems .. "Description"):SetText("|c" .. color .. val["item"]["name"] .. "|r\nLooted " .. CT_RaidTracker_GetRaidTitle(val["ids"][1], 1)); if ( val["note"] ) then getglobal("CT_RaidTrackerItem" .. numItems .. "NoteNormalTexture"):SetVertexColor(1, 1, 1); else getglobal("CT_RaidTrackerItem" .. numItems .. "NoteNormalTexture"):SetVertexColor(0.5, 0.5, 0.5); end end else numHidden = numHidden + 1; end end end end for i = numItems+1, 255, 1 do getglobal("CT_RaidTrackerItem" .. i):Hide(); end if ( numHidden == 0 ) then CT_RaidTrackerItemsText:SetText(name .. "'s Loot (" .. numItems .. "):"); else CT_RaidTrackerItemsText:SetText(name .. "'s Loot (" .. numItems .. "/" .. numHidden + numItems .. "):"); end UIDropDownMenu_SetSelectedID(CT_RaidTrackerRarityDropDown, CT_RaidTracker_SortOptions["playeritemfilter"]); local colors = { "|c001eff00Uncommon|r", "|c000070ddRare|r", "|c00a335eeEpic|r", "|c00ff8000Legendary" }; CT_RaidTrackerRarityDropDownText:SetText(colors[CT_RaidTracker_SortOptions["playeritemfilter"]]); CT_RaidTrackerDetailScrollFrameItems:UpdateScrollChildRect(); end end function CT_RaidTracker_ColorToRGB(str) str = strlower(strsub(str, 3)); local tbl = { }; tbl[1], tbl[2], tbl[3], tbl[4], tbl[5], tbl[6] = strsub(str, 1, 1), strsub(str, 2, 2), strsub(str, 3, 3), strsub(str, 4, 4), strsub(str, 5, 5), strsub(str, 6, 6); local highvals = { ["a"] = 10, ["b"] = 11, ["c"] = 12, ["d"] = 13, ["e"] = 14, ["f"] = 15 }; for k, v in tbl do if ( highvals[v] ) then tbl[k] = highvals[v]; elseif ( tonumber(v) ) then tbl[k] = tonumber(v); end end local r, g, b = (tbl[1]*16+tbl[2])/255, (tbl[3]*16+tbl[4])/255, (tbl[5]*16+tbl[6])/255; if ( not r or r > 1 or r < 0 ) then r = 1; end if ( not g or g > 1 or g < 0 ) then g = 1; end if ( not b or b > 1 or b < 0 ) then b = 1; end return r, g, b; end function CT_RaidTracker_GetColorString(str) if ( not str ) then return 1, 1, 1; end local playerClass = UnitClass("player"); local playerLevel = UnitLevel("player"); local classArmor = { ["Warrior"] = { ["Cloth"] = 1, ["Leather"] = 1, ["Mail"] = 1, ["Plate"] = 40 }, ["Paladin"] = { ["Cloth"] = 1, ["Leather"] = 1, ["Mail"] = 1, ["Plate"] = 40 }, ["Shaman"] = { ["Cloth"] = 1, ["Leather"] = 1, ["Mail"] = 40, ["Plate"] = 61 }, ["Hunter"] = { ["Cloth"] = 1, ["Leather"] = 1, ["Mail"] = 40, ["Plate"] = 61 }, ["Rogue"] = { ["Cloth"] = 1, ["Leather"] = 1, ["Mail"] = 61, ["Plate"] = 61 }, ["Druid"] = { ["Cloth"] = 1, ["Leather"] = 1, ["Mail"] = 61, ["Plate"] = 61 }, ["Warlock"] = { ["Cloth"] = 1, ["Leather"] = 61, ["Mail"] = 61, ["Plate"] = 61 }, ["Mage"] = { ["Cloth"] = 1, ["Leather"] = 61, ["Mail"] = 61, ["Plate"] = 61 }, ["Priest"] = { ["Cloth"] = 1, ["Leather"] = 61, ["Mail"] = 61, ["Plate"] = 61 }, ["Warlock"] = { ["Cloth"] = 1, ["Leather"] = 61, ["Mail"] = 61, ["Plate"] = 61 } }; -- Equip: if ( string.find(str, "^Equip: ") ) then return 0, 1, 0; -- Use: elseif ( string.find(str, "^Use: ") ) then return 0, 1, 0; -- Chance on hit: elseif ( string.find(str, "^Chance on hit:") ) then return 0, 1, 0; -- Sets elseif ( string.find(str, "^.+ %(%d+/%d+%)$") ) then return 1, 0.82, 0, 1; -- Durability 0/X elseif ( string.find(str, "^Durability 0 / %d+$") ) then return 1, 0.15, 0.15; -- Wrong class elseif ( string.find(str, "^Classes: ") and not string.find(str, "^Classes: .*" .. playerClass) ) then return 1, 0.15, 0.15; -- Made by elseif ( string.find(str, "^$") ) then return 0, 1, 0; end -- Armor type if ( classArmor[playerClass][str] and classArmor[playerClass][str] > playerLevel ) then return 1, 0.15, 0.15; end -- Low level local iStart, iEnd, level = string.find(str, "^Requires Level (%d+)$"); if ( level and tonumber(level) > playerLevel ) then return 1, 0.15, 0.15; end return 1, 1, 1; end function CT_RaidTrackerItem_SetHyperlink() local raidid = this.raidid; local lootid = this.itemid; if ( CT_RaidTracker_RaidLog[raidid] and CT_RaidTracker_RaidLog[raidid]["Loot"][lootid] ) then local item = CT_RaidTracker_RaidLog[raidid]["Loot"][lootid]["item"]; for i = 1, 30, 1 do getglobal("CT_RTTooltipTextLeft" .. i):SetText(""); getglobal("CT_RTTooltipTextLeft" .. i):Hide(); getglobal("CT_RTTooltipTextRight" .. i):SetText(""); getglobal("CT_RTTooltipTextRight" .. i):Hide(); end if ( not item["tooltip"] ) then local tTooltip = { }; CT_RTTooltip:SetHyperlink("item:" .. item["id"]); for i = 1, CT_RTTooltip:NumLines(), 1 do local tl, tr; if ( getglobal("CT_RTTooltipTextLeft" .. i):IsVisible() ) then tl = getglobal("CT_RTTooltipTextLeft" .. i):GetText(); end if ( getglobal("CT_RTTooltipTextRight" .. i):IsVisible() ) then tr = getglobal("CT_RTTooltipTextRight" .. i):GetText(); end tinsert(tTooltip, { ["left"] = tl, ["right"] = tr }); end CT_RaidTracker_RaidLog[raidid]["Loot"][lootid]["item"]["tooltip"] = tTooltip; item["tooltip"] = tTooltip; end for i = 1, 30, 1 do getglobal("CT_RTTooltipTextLeft" .. i):SetText(""); getglobal("CT_RTTooltipTextLeft" .. i):Hide(); getglobal("CT_RTTooltipTextRight" .. i):SetText(""); getglobal("CT_RTTooltipTextRight" .. i):Hide(); end CT_RTTooltip:SetOwner(this, "ANCHOR_RIGHT"); local hasShownSet; for k, v in item["tooltip"] do local rl, gl, bl, rr, gr, br; if ( k == 1 ) then rl, gl, bl = CT_RaidTracker_ColorToRGB(item["c"]); end if ( v["right"] ) then rl, gl, bl, hasShownSet = CT_RaidTracker_GetColorString(v["left"]); rr, gr, br = CT_RaidTracker_GetColorString(v["right"]); CT_RTTooltip:AddDoubleLine(v["left"], v["right"], rl, gl, bl, rr, gr, br); else if ( hasShownSet ) then CT_RTTooltip:AddLine(v["left"], 0.5, 0.5, 0.5); else if ( not rl and not gl and not bl ) then rl, gl, bl, hasShownSet = CT_RaidTracker_GetColorString(v["left"]); end CT_RTTooltip:AddLine(v["left"], rl, gl, bl); end end end CT_RTTooltip:Show(); return; end end function CT_RaidTrackerItem_GetChatHyperlink() local raidid = this.raidid; local lootid = this.itemid; if ( IsShiftKeyDown() and ChatFrameEditBox:IsVisible() and CT_RaidTracker_RaidLog[raidid] and CT_RaidTracker_RaidLog[raidid]["Loot"][lootid] ) then local item = CT_RaidTracker_RaidLog[raidid]["Loot"][lootid]["item"]; ChatFrameEditBox:Insert("|c" .. item.c .. "|Hitem:" .. item.id .. "|h[" .. item.name .. "]|h|r"); end end CT_RaidTracker_RaidLog = { }; CT_RaidTracker_GetCurrentRaid = nil; -- Debug flag CT_RaidTracker_DebugFlag = nil; -- Debug function(s) function CT_RaidTracker_Debug(...) if ( CT_RaidTracker_DebugFlag ) then local sDebug = "#"; for i = 1, arg.n, 1 do if ( arg[i] ) then sDebug = sDebug .. arg[i] .. "#"; end end DEFAULT_CHAT_FRAME:AddMessage(sDebug, 1, 0.5, 0); end end -- OnFoo functions function CT_RaidTracker_OnLoad() CT_RaidTrackerTitleText:SetText("CT_RaidTracker " .. CT_RaidTracker_Version); -- Register events this:RegisterEvent("CHAT_MSG_LOOT"); this:RegisterEvent("CHAT_MSG_SYSTEM"); this:RegisterEvent("RAID_ROSTER_UPDATE"); this:RegisterEvent("PLAYER_ENTERING_WORLD"); this:RegisterEvent("VARIABLES_LOADED"); end function CT_RaidTracker_OnEvent(event) if ( CT_RaidTracker_UpdateFrame.time and CT_RaidTracker_UpdateFrame.time <= 2 ) then tinsert(CT_RaidTracker_Events, event); return; end if ( event == "RAID_ROSTER_UPDATE" or event == "PLAYER_ENTERING_WORLD" ) then if ( GetNumRaidMembers() == 0 and event == "RAID_ROSTER_UPDATE" ) then if ( CT_RaidTracker_GetCurrentRaid ) then CT_RaidTracker_RaidLog[CT_RaidTracker_GetCurrentRaid]["raidEnd"] = CT_RaidTracker_Date(); end CT_RaidTracker_GetCurrentRaid = nil; CT_RaidTracker_Debug("Left raid."); CT_RaidTracker_Offline = { }; elseif ( not CT_RaidTracker_GetCurrentRaid and GetNumRaidMembers() > 0 and event == "RAID_ROSTER_UPDATE" ) then local sDate = CT_RaidTracker_Date(); tinsert(CT_RaidTracker_RaidLog, 1, { ["Loot"] = { }, ["Join"] = { }, ["Leave"] = { }, ["Notes"] = { }, ["key"] = sDate }); CT_RaidTracker_SortRaidTable(); CT_RaidTracker_GetCurrentRaid = 1; for i = 1, GetNumRaidMembers(), 1 do tinsert(CT_RaidTracker_RaidLog[CT_RaidTracker_GetCurrentRaid]["Join"], { ["player"] = UnitName("raid" .. i), ["time"] = sDate } ); local name, rank, subgroup, level, class, fileName, zone, online = GetRaidRosterInfo(i); if ( not online ) then tinsert(CT_RaidTracker_RaidLog[CT_RaidTracker_GetCurrentRaid]["Leave"], { ["player"] = UnitName("raid" .. i), ["time"] = sDate } ); end end CT_RaidTracker_Debug("Joined new raid at " .. sDate); CT_RaidTracker_Update(); CT_RaidTracker_UpdateView(); end if ( not CT_RaidTracker_GetCurrentRaid ) then return; end local updated; for i = 1, GetNumRaidMembers(), 1 do local name, online = UnitName("raid" .. i), UnitIsConnected("raid" .. i); if ( name ) then if ( online ~= CT_RaidTracker_Online[name] ) then -- Status isn't updated if ( not CT_RaidTracker_RaidLog[CT_RaidTracker_GetCurrentRaid] ) then CT_RaidTracker_RaidLog[CT_RaidTracker_GetCurrentRaid] = { ["Loot"] = { }, ["Join"] = { }, ["Leave"] = { }, ["Notes"] = { } }; end if ( not online ) then tinsert(CT_RaidTracker_RaidLog[CT_RaidTracker_GetCurrentRaid]["Leave"], { ["player"] = name, ["time"] = CT_RaidTracker_Date() } ); CT_RaidTracker_Debug("OFFLINE", name); else tinsert(CT_RaidTracker_RaidLog[CT_RaidTracker_GetCurrentRaid]["Join"], { ["player"] = name, ["time"] = CT_RaidTracker_Date() } ); CT_RaidTracker_Debug("ONLINE", name); end updated = 1; end CT_RaidTracker_Online[name] = online; end end if ( updated ) then CT_RaidTracker_Update(); CT_RaidTracker_UpdateView(); end elseif ( event == "CHAT_MSG_LOOT" and CT_RaidTracker_GetCurrentRaid ) then local sPlayer, sLink; local iStart, iEnd, sPlayerName, sItem = string.find(arg1, "([^%s]+) receives loot: (.+)%."); if ( sPlayerName ) then sPlayer = sPlayerName; sLink = sItem; else local iStart, iEnd, sItem = string.find(arg1, "You receive loot: (.+)%."); if ( sItem ) then sPlayer = UnitName("player"); sLink = sItem; end end -- Make sure there is a link if ( sLink and sPlayer ) then local sColor, sItem, sName, tTooltip = CT_RaidTracker_GetItemInfo(sLink); if ( sColor and sItem and sName and tTooltip and CT_RaidTracker_RarityTable[sColor] ) then -- Insert into table if ( not CT_RaidTracker_RaidLog[CT_RaidTracker_GetCurrentRaid] ) then CT_RaidTracker_RaidLog[CT_RaidTracker_GetCurrentRaid] = { ["Loot"] = { }, ["Join"] = { }, ["Leave"] = { }, ["Notes"] = { } }; end local found; for k, v in CT_RaidTracker_RaidLog[CT_RaidTracker_GetCurrentRaid]["Loot"] do if ( v["item"]["name"] == sName and v["player"] == sPlayer ) then if ( v["item"]["count"] ) then CT_RaidTracker_RaidLog[CT_RaidTracker_GetCurrentRaid]["Loot"][k]["item"]["count"] = v["item"]["count"]+1; else CT_RaidTracker_RaidLog[CT_RaidTracker_GetCurrentRaid]["Loot"][k]["item"]["count"] = 1; end found = 1; break; end end if ( not found ) then tinsert(CT_RaidTracker_RaidLog[CT_RaidTracker_GetCurrentRaid]["Loot"], { ["player"] = sPlayer, ["item"] = { ["c"] = sColor, ["id"] = sItem, ["tooltip"] = tTooltip, ["name"] = sName, ["count"] = 1, ["type"] = CT_RaidTracker_GetItemType("item:"..sItem) }, ["time"] = CT_RaidTracker_Date() } ); end CT_RaidTracker_Debug(sPlayer, sColor, sItem, sName); CT_RaidTracker_Update(); CT_RaidTracker_UpdateView(); end end elseif ( event == "CHAT_MSG_SYSTEM" and UnitName("player") and UnitName("player") ~= "Unknown Being" and CT_RaidTracker_GetCurrentRaid ) then local sDate = CT_RaidTracker_Date(); local iStart, iEnd, sPlayer = string.find(arg1, "([^%s]+) has left the raid group"); if ( sPlayer and sPlayer ~= UnitName("player") and UnitName("player") and UnitName("player") ~= "Unknown Entity" ) then tinsert(CT_RaidTracker_RaidLog[CT_RaidTracker_GetCurrentRaid]["Leave"], { ["player"] = sPlayer, ["time"] = sDate } ); CT_RaidTracker_Debug(sPlayer, "LEFT"); end local iStart, iEnd, sPlayer = string.find(arg1, "([^%s]+) has joined the raid group"); if ( sPlayer and sPlayer ~= UnitName("player") ) then tinsert(CT_RaidTracker_RaidLog[CT_RaidTracker_GetCurrentRaid]["Join"], { ["player"] = sPlayer, ["time"] = sDate } ); CT_RaidTracker_Debug(sPlayer, "JOIN"); end CT_RaidTracker_UpdateView(); CT_RaidTracker_Update(); elseif ( event == "VARIABLES_LOADED" ) then CT_RaidTracker_ConvertFormat(); end end -- Item functions function CT_RaidTracker_GetItemInfo(sItem) -- Thanks to Telo for the following regular expression local iStart, iEnd, sColor, sItemName, sName = string.find(sItem, "|c(%x+)|Hitem:(%d+:%d+:%d+:%d+)|h%[(.-)%]|h|r"); if ( sColor and sItemName and sName ) then local tTooltip = { }; for i = 1, 30, 1 do getglobal("CT_RTTooltipTextLeft" .. i):SetText(""); getglobal("CT_RTTooltipTextLeft" .. i):Hide(); getglobal("CT_RTTooltipTextRight" .. i):SetText(""); getglobal("CT_RTTooltipTextRight" .. i):Hide(); end CT_RTTooltip:SetHyperlink("item:" .. sItemName); for i = 1, CT_RTTooltip:NumLines(), 1 do local tl, tr; if ( getglobal("CT_RTTooltipTextLeft" .. i):IsVisible() ) then tl = getglobal("CT_RTTooltipTextLeft" .. i):GetText(); end if ( getglobal("CT_RTTooltipTextRight" .. i):IsVisible() ) then tr = getglobal("CT_RTTooltipTextRight" .. i):GetText(); end tinsert(tTooltip, { ["left"] = tl, ["right"] = tr }); end return sColor, sItemName, sName, tTooltip; end end SlashCmdList["RAIDTRACKER"] = function(msg) ShowUIPanel(CT_RaidTrackerFrame); end SLASH_RAIDTRACKER1 = "/raidtracker"; SLASH_RAIDTRACKER2 = "/rt"; function CT_RaidTracker_Print(msg, r, g, b) if ( CT_Print ) then CT_Print(msg, r, g, b); else DEFAULT_CHAT_FRAME:AddMessage(msg, r, g, b); end end function CT_RaidTracker_RarityDropDown_OnLoad() UIDropDownMenu_Initialize(this, CT_RaidTracker_RarityDropDown_Initialize); --UIDropDownMenu_SetWidth(130); UIDropDownMenu_SetSelectedID(CT_RaidTrackerRarityDropDown, 1); end -- Green = 1eff00 -- Blue = 0070dd -- Purple = a335ee -- Orange = ff8000 function CT_RaidTracker_RarityDropDown_Initialize() local info = {}; info.text = "|c001eff00Uncommon|r"; info.func = CT_RaidTracker_RarityDropDown_OnClick; UIDropDownMenu_AddButton(info); info = {}; info.text = "|c000070ddRare|r"; info.func = CT_RaidTracker_RarityDropDown_OnClick; UIDropDownMenu_AddButton(info); info = {}; info.text = "|c00a335eeEpic|r"; info.func = CT_RaidTracker_RarityDropDown_OnClick; UIDropDownMenu_AddButton(info); info = {}; info.text = "|c00ff8000Legendary|r"; info.func = CT_RaidTracker_RarityDropDown_OnClick; UIDropDownMenu_AddButton(info); end function CT_RaidTracker_RarityDropDown_OnClick() UIDropDownMenu_SetSelectedID(CT_RaidTrackerRarityDropDown, this:GetID()); if ( CT_RaidTrackerFrame.type == "items" ) then CT_RaidTracker_SortOptions["itemfilter"] = this:GetID(); else CT_RaidTracker_SortOptions["playeritemfilter"] = this:GetID(); end CT_RaidTracker_UpdateView(); end function CT_RaidTracker_SelectItem(name) CT_RaidTracker_GetPage(); CT_RaidTrackerFrame.type = "itemhistory"; CT_RaidTrackerFrame.itemname = name; CT_RaidTrackerFrame.selected = nil; CT_RaidTracker_Update(); CT_RaidTracker_UpdateView(); end function CT_RaidTracker_GetPage() if ( CT_RaidTrackerFrame.type or CT_RaidTrackerFrame.itemname or CT_RaidTrackerFrame.selected or CT_RaidTrackerFrame.player ) then tinsert(CT_RaidTracker_LastPage, { ["type"] = CT_RaidTrackerFrame.type, ["itemname"] = CT_RaidTrackerFrame.itemname, ["selected"] = CT_RaidTrackerFrame.selected, ["player"] = CT_RaidTrackerFrame.player } ); end if ( getn(CT_RaidTracker_LastPage) > 0 ) then CT_RaidTrackerFrameBackButton:Enable(); else CT_RaidTrackerFrameBackButton:Disable(); end end function CT_RaidTracker_GoBack() local t = table.remove(CT_RaidTracker_LastPage); if ( t ) then CT_RaidTrackerFrame.type = t["type"]; CT_RaidTrackerFrame.itemname = t["itemname"]; CT_RaidTrackerFrame.selected = t["selected"]; CT_RaidTrackerFrame.player = t["player"]; CT_RaidTracker_Update(); CT_RaidTracker_UpdateView(); end if ( getn(CT_RaidTracker_LastPage) > 0 ) then CT_RaidTrackerFrameBackButton:Enable(); else CT_RaidTrackerFrameBackButton:Disable(); end end function CT_RaidTracker_ConvertFormat() -- Called because of old format used during development for k, v in CT_RaidTracker_RaidLog do if ( not v["Notes"] ) then CT_RaidTracker_RaidLog[k]["Notes"] = { }; end end end if ( CT_RegisterMod ) then CT_RaidTracker_DisplayWindow = function() ShowUIPanel(CT_RaidTrackerFrame); end CT_RegisterMod("Raid Tracker", "Display window", 5, "Interface\\Icons\\INV_Chest_Chain_05", "Displays the Raid Tracker window, which tracks raid loot & attendance.", "switch", "", CT_RaidTracker_DisplayWindow); else CT_RaidTracker_Print(" CT_RaidTracker loaded. Type /rt to show the RaidTracker window.", 1, 1, 0); end function CT_RaidTracker_FixZero(num) if ( num < 10 ) then return "0" .. num; else return num; end end function CT_RaidTracker_Date() local t = date("*t"); return CT_RaidTracker_FixZero(t.month) .. "/" .. CT_RaidTracker_FixZero(t.day) .. "/" .. strsub(t.year, 3) .. " " .. CT_RaidTracker_FixZero(t.hour) .. ":" .. CT_RaidTracker_FixZero(t.min) .. ":" .. CT_RaidTracker_FixZero(t.sec); end function CT_RaidTrackerUpdateFrame_OnUpdate(elapsed) if ( this.time ) then this.time = this.time + elapsed; if ( this.time > 2 ) then this.time = nil; for k, v in CT_RaidTracker_Events do CT_RaidTracker_OnEvent(v); end end end end function CT_RaidTracker_SelectRaidUpdate() local numEntries = getn(CT_RaidTracker_RaidLog); FauxScrollFrame_Update(CT_RaidTracker_SelectRaidFrameScrollFrame, numEntries, 20, 20); for i = 1, 20, 1 do local button = getglobal("CT_RaidTracker_SelectRaidFrameRaid" .. i); local index = i + FauxScrollFrame_GetOffset(CT_RaidTracker_SelectRaidFrameScrollFrame); if ( index <= numEntries ) then if ( numEntries <= 20 ) then button:SetWidth(260); else button:SetWidth(245); end button:Show(); getglobal(button:GetName() .. "Name"):SetText(CT_RaidTracker_RaidLog[index].key); --getglobal(button:GetName() .. "Info"):SetText(CT_RADurability_Shown[index][2]); else button:Hide(); end end end