Grid2

Grid2

11M Downloads

Feature request: Class icon (ideally as status and not the "portrait" indicator) which turns into spec icon in arena

AlexFolland opened this issue ยท 1 comments

commented

In arena, I would like to be able to see my teammates' spec icons like other unit frame addons can show without inspecting. I think it's from C_Commentator.GetPlayerData, but I'm not sure. https://warcraft.wiki.gg/wiki/API_C_Commentator.GetPlayerData

I would also like if the class icon could be a status so I could have the class icon and spec icon side by side in separate indicators. If it was just a class icon that turned into a spec icon in arena though, that would be good.

Thanks for Grid2 and don't feel pressured to implement this. I may implement it myself and submit a pull request one day.

commented

Actually it's not C_Commentator.GetPlayerData. I see the following utility functions in SweepyBoop's PvP Helper:

addon.GetSpecForPlayerOrArena = function(unit)
    if ( unit == "player" ) then
        local currentSpec = GetSpecialization();
        if currentSpec then
            return GetSpecializationInfo(currentSpec);
        end
    else
        local arenaIndex = string.sub(unit, -1, -1);
        return GetArenaOpponentSpec(arenaIndex);
    end
end

addon.GetClassForPlayerOrArena = function (unitId)
    if ( unitId == "player" ) then
        return addon.GetUnitClass(unitId);
    else
        -- UnitClass returns nil unless unit is in range, but arena spec is available in prep phase.
        local index = string.sub(unitId, -1, -1);
        local specID = GetArenaOpponentSpec(index);
        if specID and ( specID > 0 ) then
            return select(6, GetSpecializationInfoByID(specID));
        end
    end
end

-- C_PvP.GetScoreInfoByPlayerGuid returns localized spec name
-- There are Frost Mage and Frost DK, but the spec name is "Frost" for both...
-- We need to append class info as well
local specInfoByName = {};
local specIDByTooltip = {}; -- To retrieve specID from tooltip
for _, classID in pairs(addon.CLASSID) do
    for specIndex = 1, 4 do
        local specID, specName, _, icon, role = GetSpecializationInfoForClassID(classID, specIndex);
        local classInfo = C_CreatureInfo.GetClassInfo(classID);
        if specName and classInfo and classInfo.classFile then
            local classFile = classInfo.classFile;
            specInfoByName[classFile .. "-" .. specName] = { icon = icon, role = role };
     
            local localizedClassMale = LOCALIZED_CLASS_NAMES_MALE[classFile];
            if localizedClassMale then
                specIDByTooltip[specName .. " " .. localizedClassMale] = specID;
                --print(specName .. " " .. localizedClassMale, specID); -- Debug
            end

            local localizedClassFemale = LOCALIZED_CLASS_NAMES_FEMALE[classFile];
            if localizedClassFemale and ( localizedClassFemale ~= localizedClassMale ) then
                specIDByTooltip[specName .. " " .. localizedClassFemale] = specID;
                --print(specName .. " " .. localizedClassFemale, specID); -- Debug
            end
        end
    end
end

-- Battleground enemy info parser
addon.cachedPlayerSpec = {};
local refreshFrame = CreateFrame("Frame");
refreshFrame:RegisterEvent(addon.PLAYER_ENTERING_WORLD);
refreshFrame:SetScript("OnEvent", function (self, event)
    addon.cachedPlayerSpec = {};
end)

addon.GetPlayerSpec = function (unitId)
    local guid = UnitGUID(unitId);
    if ( not addon.cachedPlayerSpec[guid] ) then
        if IsActiveBattlefieldArena() then -- in arena, we only have party1/2 and arena 1/2/3
            if ( guid == UnitGUID("party1") or guid == UnitGUID("party2") ) then
                local tooltipData = C_TooltipInfo.GetUnit(unitId);
                if tooltipData then
                    for _, line in ipairs(tooltipData.lines) do
                        if line and line.type == Enum.TooltipDataLineType.None and line.leftText and line.leftText ~= "" then
                            local specID = specIDByTooltip[line.leftText];
                            if specID then
                                local iconID, role = select(4, GetSpecializationInfoByID(specID));
                                addon.cachedPlayerSpec[guid] = { icon = iconID, role = role };
                            end
                        end
                    end
                end
            else
                for i = 1, addon.MAX_ARENA_SIZE do
                    if ( guid == UnitGUID("arena" .. i) ) then
                        local specID = GetArenaOpponentSpec(i);
                        if ( not specID ) then return end
                        local iconID, role = select(4, GetSpecializationInfoByID(specID));
                        addon.cachedPlayerSpec[guid] = { icon = iconID, role = role };
                    end
                end
            end
        else
            local scoreInfo = C_PvP.GetScoreInfoByPlayerGuid(guid);
            if scoreInfo and scoreInfo.classToken and scoreInfo.talentSpec then
                addon.cachedPlayerSpec[guid] = specInfoByName[scoreInfo.classToken .. "-" .. scoreInfo.talentSpec];
            else
                -- There are still units with unknown spec, request info
                RequestBattlefieldScoreData();
            end
        end
    end

    return addon.cachedPlayerSpec[guid];
end

Looks like that addon uses a few different ways to detect the spec for various types of units, including GetSpecialization for the player, GetArenaOpponentSpec for arena opponents (arena1, arena2, arena3), and C_TooltipInfo.GetUnit and reading the localized spec name from the tooltip for friendly arena units (party1 and party2). It also distinguishes between Frost Mage and Frost DK by appending class info. This is all very useful for showing accurate spec icons in arena.