Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- List of talent spec displays
- local displays = {
- ["DEATHKNIGHT"] = {
- ["Blood"] = "Blood DK",
- ["Frost"] = "Frost DK",
- ["Unholy"] = "Unholy DK",
- },
- ["DRUID"] = {
- ["Balance"] = "Moonkin",
- ["Feral"] = "Cat Druid",
- ["Guardian"] = "Bear Druid",
- ["Restoration"] = "Resto Druid",
- },
- ["HUNTER"] = {
- ["Beast Mastery"] = "BM Hunter",
- ["Marksmanship"] = "MM Hunter",
- ["Survival"] = "Surv Hunter",
- },
- ["MAGE"] = {
- ["Arcane"] = "Arcane Mage",
- ["Fire"] = "Fire Mage",
- ["Frost"] = "Frost Mage",
- },
- ["MONK"] = {
- ["Brewmaster"] = "Brew Monk",
- ["Mistweaver"] = "Mist Monk",
- ["Windwalker"] = "Wind Monk",
- },
- ["PALADIN"] = {
- ["Holy"] = "Holy Pally",
- ["Protection"] = "Prot Pally",
- ["Retribution"] = "Ret Pally",
- },
- ["PRIEST"] = {
- ["Discipline"] = "Disc Priest",
- ["Holy"] = "Holy Priest",
- ["Shadow"] = "Shadow Priest",
- },
- ["ROGUE"] = {
- ["Assassination"] = "Mute Rogue",
- ["Combat"] = "Combat Rogue",
- ["Subtlety"] = "Sub Rogue",
- },
- ["SHAMAN"] = {
- ["Elemental"] = "Ele Shaman",
- ["Enhancement"] = "Enhance Shaman",
- ["Restoration"] = "Resto Shaman",
- },
- ["WARLOCK"] = {
- ["Affliction"] = "Aff Lock",
- ["Demonology"] = "Demo Lock",
- ["Destruction"] = "Destro Lock",
- },
- ["WARRIOR"] = {
- ["Arms"] = "Arms Warr",
- ["Fury"] = "Fury Warr",
- ["Protection"] = "Prot Warr",
- },
- ["AMBIGUOUS"] = {
- ["Frost"] = "Frost Something",
- ["Holy"] = "Holy Something",
- ["Protection"] = "Prot Something",
- ["Restoration"] = "Resto Something",
- },
- }
- -- List of talent spec roles
- local roles = {
- ["DEATHKNIGHT"] = {
- ["Blood"] = "Tank",
- ["Frost"] = "Melee",
- ["Unholy"] = "Melee",
- },
- ["DRUID"] = {
- ["Balance"] = "Knockback",
- ["Feral"] = "Melee",
- ["Guardian"] = "Tank",
- ["Restoration"] = "Healer",
- },
- ["HUNTER"] = {
- ["Beast Mastery"] = "Knockback",
- ["Marksmanship"] = "Ranged",
- ["Survival"] = "Ranged",
- },
- ["MAGE"] = {
- ["Arcane"] = "Knockback",
- ["Fire"] = "Ranged",
- ["Frost"] = "Ranged",
- },
- ["MONK"] = {
- ["Brewmaster"] = "Tank",
- ["Mistweaver"] = "Healer",
- ["Windwalker"] = "Melee",
- },
- ["PALADIN"] = {
- ["Holy"] = "Healer",
- ["Protection"] = "Tank",
- ["Retribution"] = "Melee",
- },
- ["PRIEST"] = {
- ["Discipline"] = "Healer",
- ["Holy"] = "Healer",
- ["Shadow"] = "Ranged",
- },
- ["ROGUE"] = {
- ["Assassination"] = "Melee",
- ["Combat"] = "Melee",
- ["Subtlety"] = "Melee",
- },
- ["SHAMAN"] = {
- ["Elemental"] = "Knockback",
- ["Enhancement"] = "Melee",
- ["Restoration"] = "Healer",
- },
- ["WARLOCK"] = {
- ["Affliction"] = "Knockback",
- ["Demonology"] = "Knockback",
- ["Destruction"] = "Knockback",
- },
- ["WARRIOR"] = {
- ["Arms"] = "Melee",
- ["Fury"] = "Melee",
- ["Protection"] = "Tank",
- },
- ["AMBIGUOUS"] = {
- ["Frost"] = "Ranged", -- Ranged Frost DKs?
- ["Holy"] = "Healer",
- ["Protection"] = "Tank",
- ["Restoration"] = "Healer",
- },
- }
- -- List of talent spec classes
- local classes = {
- ["Blood"] = "DEATHKNIGHT",
- ["Unholy"] = "DEATHKNIGHT",
- ["Balance"] = "DRUID",
- ["Feral"] = "DRUID",
- ["Guardian"] = "DRUID",
- ["Beast Mastery"] = "HUNTER",
- ["Marksmanship"] = "HUNTER",
- ["Survival"] = "HUNTER",
- ["Arcane"] = "MAGE",
- ["Fire"] = "MAGE",
- ["Brewmaster"] = "MONK",
- ["Mistweaver"] = "MONK",
- ["Windwalker"] = "MONK",
- ["Retribution"] = "PALADIN",
- ["Discipline"] = "PRIEST",
- ["Shadow"] = "PRIEST",
- ["Assassination"] = "ROGUE",
- ["Combat"] = "ROGUE",
- ["Subtlety"] = "ROGUE",
- ["Elemental"] = "SHAMAN",
- ["Enhancement"] = "SHAMAN",
- ["Affliction"] = "WARLOCK",
- ["Demonology"] = "WARLOCK",
- ["Destruction"] = "WARLOCK",
- ["Arms"] = "WARRIOR",
- ["Fury"] = "WARRIOR",
- ["Frost"] = "AMBIGUOUS",
- ["Holy"] = "AMBIGUOUS",
- ["Protection"] = "AMBIGUOUS",
- ["Restoration"] = "AMBIGUOUS",
- }
- -- List of class colours
- local colours = {
- ["DEATHKNIGHT"] = "|cFFC41F3B",
- ["DRUID"] = "|cFFFF7D0A",
- ["HUNTER"] = "|cFFABD473",
- ["MAGE"] = "|cFF69CCF0",
- ["MONK"] = "|cFF00FF96",
- ["PALADIN"] = "|cFFF58CBA",
- ["PRIEST"] = "|cFFFFFFFF",
- ["ROGUE"] = "|cFFFFF569",
- ["SHAMAN"] = "|cFF0070DE",
- ["WARLOCK"] = "|cFF9482C9",
- ["WARRIOR"] = "|cFFC79C6E",
- ["AMBIGUOUS"] = "|cFF7F7F7F",
- }
- local function charcount(s, c)
- local _, n = gsub(s, c, c)
- return n
- end
- local function charselect(s, i)
- -- Returns false on no character
- local c = strsub(s, i, i)
- return c ~= "" and c
- end
- local realm = GetRealmName()
- local function ParseName(identifier)
- -- Pattern assumes identifier is formatted as "name" or "name-server"
- -- Name is composed of every character except for '-'
- -- Server is any characters after an optional '-' character
- -- When no '-' character is present, the player is from the local realm
- local name, server = strmatch(identifier, "^([^%-]+)-?(.*)")
- return name, server == "" and realm or server
- end
- local function DisplayMessage(report, message, ...)
- if report then
- SendChatMessage(gsub(message, "%%s", ""), "INSTANCE_CHAT")
- else
- print(format(message, ...))
- end
- end
- local function BuildList(side)
- -- Show scores for players of both factions
- SetBattlefieldScoreFaction()
- -- Build list of players
- local players, specless = {}, 0
- for i = 1, GetNumBattlefieldScores() do
- local identifier, _, _, _, _, faction, race, _, classToken, _, _, _, _, _, _, talentSpec = GetBattlefieldScore(i)
- if faction == side then
- if talentSpec then
- local name, server = ParseName(identifier)
- local player = {
- ["name"] = name,
- ["server"] = server,
- ["spec"] = talentSpec,
- }
- -- GetBattlefieldScore occasionally returns nil for race, class, and classToken
- -- Assume all three are absent together
- if race then
- player["race"] = race
- player["class"] = classToken
- player["colour"] = colours[classToken]
- player["display"] = displays[classToken][talentSpec]
- player["role"] = roles[classToken][talentSpec]
- else
- player["race"] = "Unknown"
- player["class"] = classes[talentSpec]
- player["colour"] = colours[classes[talentSpec]]
- player["display"] = displays[classes[talentSpec]][talentSpec]
- player["role"] = roles[classes[talentSpec]][talentSpec]
- end
- tinsert(players, player)
- else
- specless = specless+1
- end
- end
- end
- -- Check for any talented players on the team
- local n = #players
- if n == 0 then
- print(format("%s have 0 players with talents and %d players with no talents.", side == 0 and "Horde" or "Alliance", specless))
- return
- end
- -- Sort by class then spec then name
- sort(players, function(a, b) return a.class == b.class and ( a.spec == b.spec and a.name < b.name or a.spec < b.spec ) or a.class < b.class end)
- return players, n, specless
- end
- local function DisplaySummary(report)
- DisplayMessage(report, "BG Spy: Team Summary")
- for side = 0, 1 do
- local players, n, specless = BuildList(side)
- if not players then
- return
- end
- -- Role totals
- local total = {
- Tank = 0,
- Healer = 0,
- Melee = 0,
- Ranged = 0,
- Knockback = 0,
- }
- -- Calculate the role totals
- for i = 1, n do
- total[players[i].role] = total[players[i].role]+1
- end
- -- Display role totals
- DisplayMessage(report, format("%s: %d melee, %d ranged, %d healer%s.%s", side == 0 and "Horde" or "Alliance", total.Tank+total.Melee, total.Ranged+total.Knockback, total.Healer, total.Healer == 1 and "" or "s", specless > 0 and format(" (%d with no talents)", specless) or ""))
- end
- end
- local function DisplaySpecs(side, report)
- local players, n, specless = BuildList(side)
- if not players then
- return
- end
- -- Role totals
- local total = {
- Tank = 0,
- Healer = 0,
- Melee = 0,
- Ranged = 0,
- Knockback = 0,
- }
- -- Display list
- local x, last, names = 1, players[1].display, players[1].name
- total[players[1].role] = 1
- local function out(i)
- DisplayMessage(report, format("%dx %%s%s (%s)", x, last, names), players[i].colour)
- end
- for i = 2, n do
- local current = players[i].display
- if current ~= last then
- out(i-1)
- x = 1
- last = current
- names = players[i].name
- else
- x = x+1
- names = format("%s, %s", names, players[i].name)
- end
- total[players[i].role] = total[players[i].role]+1
- end
- out(n)
- -- Display role totals
- DisplayMessage(report, format("%s: %d melee, %d ranged, %d healer%s.%s", side == 0 and "Horde" or "Alliance", total.Tank+total.Melee, total.Ranged+total.Knockback, total.Healer, total.Healer == 1 and "" or "s", specless > 0 and format(" (%d with no talents)", specless) or ""))
- end
- -- Role listing tables
- local member = {
- t = function(role)
- return role == "Tank"
- end,
- h = function(role)
- return role == "Healer"
- end,
- d = function(role)
- return role == "Melee" or role == "Ranged" or role == "Knockback"
- end,
- k = function(role)
- return role == "Knockback"
- end,
- }
- local listname = {
- t = "tank",
- h = "healer",
- d = "DPS",
- k = "knockback",
- }
- local function DisplayRole(side, report, list)
- local players, n = BuildList(side)
- if not players then
- return
- end
- -- Display list
- local total = 0
- for i = 1, n do
- if member[list](players[i].role) then
- DisplayMessage(report, format("%s - %s %%s%s", players[i].name, players[i].race, players[i].display), players[i].colour)
- total = total+1
- end
- end
- DisplayMessage(report, format("%s have %d %s%s.", side == 0 and "Horde" or "Alliance", total, listname[list], list ~= "d" and total ~= 1 and "s" or ""))
- end
- local function printHelp()
- print("BG Spy 1.2.6 commands:")
- print("/bgs - Include any additional commands.")
- print("help - Display this help.")
- print("r - Report list to Battleground chat.")
- print("f - List players of friendly team.")
- print("s - List talent spec numbers on team.")
- print("t - List tanks on team.")
- print("h - List healers on team.")
- print("d - List DPS on team.")
- print("k - List players possible of knockback effects on team.")
- print("Example - /bgs rfh - Report friendly healers.")
- end
- local function printCommand(nr, nf, list)
- local r = nr == 1 and "Report" or "List"
- local f = nf == 1 and "friendly" or "enemy"
- if list == "s" then
- print(format("BG Spy: %s %s talent specs.", r, f))
- elseif list then
- local listType = listname[list] .. (list ~= "d" and "s" or "")
- print(format("BG Spy: %s %s %s.", r, f, listType))
- else
- print(format("BG Spy: %s team summaries.", r))
- end
- end
- local inBattleground
- local scoresInvalid
- local reportOnUpdate
- local nextReport = {}
- local function DisplayReport()
- local list = nextReport.list
- -- Set the arguments for the list functions
- local side = nextReport.nf == GetBattlefieldArenaFaction() and 1 or 0
- local report = nextReport.nr == 1
- -- Run a list function
- if list == "s" then
- DisplaySpecs(side, report)
- elseif list then
- DisplayRole(side, report, list)
- else
- DisplaySummary(report)
- end
- end
- SLASH_BGSPY1, SLASH_BGSPY2 = "/bgspy", "/bgs"
- SlashCmdList.BGSPY = function(msg)
- -- Normalize case
- msg = strlower(msg)
- -- Check for help
- if msg == "help" then
- printHelp()
- return
- end
- -- Check for any invalid characters
- if not strfind(msg, "[^rfsthdk ]") then
- -- Check for invalid combinations of list types
- local ilist = strfind(msg, "[sthdk]") or 0
- if not strfind(msg, "[sthdk]", ilist+1) then
- -- Check for repetitions of control characters
- local nf = charcount(msg, "f")
- local nr = charcount(msg, "r")
- if nf <= 1 and nr <= 1 then
- -- Get the list character
- local list = charselect(msg, ilist)
- -- Set next report if in a Battlegound
- if inBattleground then
- nextReport.nr = nr
- nextReport.nf = nf
- nextReport.list = list
- if scoresInvalid > GetTime() or GetBattlefieldWinner() then
- DisplayReport()
- else
- reportOnUpdate = true
- RequestBattlefieldScoreData()
- end
- -- Print command explanation if not in a Battlegound
- else
- printCommand(nr, nf, list)
- end
- return
- end
- end
- end
- print("BG Spy: Invalid command. Type \'/bgs help\' to list possible options.")
- end
- local events = {}
- function events:PLAYER_ENTERING_WORLD()
- inBattleground = false
- end
- function events:PLAYER_ENTERING_BATTLEGROUND()
- reportOnUpdate = false
- scoresInvalid = GetTime()
- inBattleground = true
- end
- function events:UPDATE_BATTLEFIELD_SCORE()
- if GetNumBattlefieldScores() > 0 then
- scoresInvalid = GetTime()+5
- end
- if reportOnUpdate then
- reportOnUpdate = false
- DisplayReport()
- end
- end
- local frame = CreateFrame("frame")
- frame:SetScript("OnEvent", function(self, event, ...)
- events[event](self, ...)
- end)
- for k in pairs(events) do
- frame:RegisterEvent(k)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement