View Single Post
03-05-21, 01:19 PM   #9
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
Most of the extra code is for showing friendly specs and the arena code has still not been tested:
Lua Code:
  1. local addonName = ...
  2.  
  3. local INSPECT_DELAY = 40
  4.  
  5. local iconKey = addonName .. "Icon"
  6.  
  7. local CheckInteractDistance, next = CheckInteractDistance, next
  8. local CanInspect, ClearInspectPlayer, NotifyInspect = CanInspect, ClearInspectPlayer, NotifyInspect
  9. local GetInspectSpecialization = GetInspectSpecialization
  10. local GetArenaOpponentSpec, GetNumArenaOppenents = GetArenaOpponentSpec, GetNumArenaOppenents
  11. local GetNamePlateForUnit = C_NamePlate.GetNamePlateForUnit
  12. local UnitClassBase, UnitExists, UnitGUID = UnitClassBase, UnitExists, UnitGUID
  13. local UnitIsEnemy, UnitIsFriend, UnitIsPlayer = UnitIsEnemy, UnitIsFriend, UnitIsPlayer
  14.  
  15. local iconData, inspectList, isAtlas, namePlateByGUID, reinspectList = { }, { }, { }, { }, { }
  16. local arenaSpec, numArenaOpponents = { }
  17.  
  18. local SetInspectDelay
  19.  
  20. local frame = CreateFrame("Frame")
  21.  
  22. local function InspectList_OnUpdate(self)
  23.     local namePlate, unit = next(inspectList)
  24.     if namePlate then
  25.         inspectList[namePlate], reinspectList[namePlate] = nil, unit
  26.         if CheckInteractDistance(unit, 1) then
  27.             SetInspectDelay()
  28.             NotifyInspect(unit)
  29.         end
  30.     elseif next(reinspectList) then
  31.         inspectList, reinspectList = reinspectList, inspectList
  32.     else
  33.         self:Hide()
  34.     end
  35. end
  36.  
  37. do
  38.     local delayCount = 0
  39.  
  40.     local function InspectDelay_OnUpdate(self)
  41.         delayCount = delayCount + 1
  42.         if delayCount >= INSPECT_DELAY then
  43.             delayCount = 0
  44.             self:SetScript("OnUpdate", InspectList_OnUpdate)
  45.         end
  46.     end
  47.  
  48.     function SetInspectDelay(reset)
  49.         delayCount = 0
  50.         if reset then
  51.             frame:SetScript("OnUpdate", InspectList_OnUpdate)
  52.         else
  53.             frame:SetScript("OnUpdate", InspectDelay_OnUpdate)
  54.         end
  55.     end
  56. end
  57.  
  58. local function UpdateNamePlateIcon(namePlate, unit, texture)
  59.     local icon = namePlate[iconKey]
  60.     if UnitIsPlayer(unit) then
  61.         if not texture then
  62.             local specID = GetInspectSpecialization(unit)
  63.             texture = (specID or 0) > 0 and iconData[specID]
  64.         end
  65.         local usingSpec = texture and true or nil
  66.         if not texture then
  67.             local _, classID = UnitClassBase(unit)
  68.             texture = iconData[classID]
  69.         end
  70.         if texture then
  71.             if not icon then
  72.                 icon = namePlate:CreateTexture(nil, "OVERLAY")
  73.                 namePlate[iconKey] = icon
  74.             end
  75.             local iconStyle = UnitIsFriend("player", unit) and "friend" or "enemy"
  76.             if icon.style ~= iconStyle then
  77.                 icon.style = iconStyle
  78.                 icon:ClearAllPoints()
  79.                 if iconStyle == "friend" then
  80.                     icon:SetPoint('CENTER', 0, 29.46)
  81.                     icon:SetSize(24, 24)
  82.                 else
  83.                     icon:SetPoint('RIGHT', 10, -5)
  84.                     icon:SetSize(20, 20)
  85.                 end
  86.             end
  87.             icon[isAtlas[texture] and "SetAtlas" or "SetTexture"](icon, texture)
  88.             icon:Show()
  89.             return usingSpec
  90.         end
  91.     end
  92.     if icon then
  93.         icon:Hide()
  94.     end
  95. end
  96.  
  97. frame:SetScript("OnEvent", function(self, event, arg1)
  98.     if event == "INSPECT_READY" then
  99.         local namePlate = namePlateByGUID[arg1]
  100.         if namePlate and UpdateNamePlateIcon(namePlate, namePlate.namePlateUnitToken) then
  101.             inspectList[namePlate], reinspectList[namePlate] = nil, nil
  102.         end
  103.         ClearInspectPlayer()
  104.         SetInspectDelay(true)
  105.     elseif event == "NAME_PLATE_UNIT_ADDED" or event == "PLAYER_SPECIALIZATION_CHANGED" then
  106.         local namePlate = GetNamePlateForUnit(arg1)
  107.         if namePlate then
  108.             if numArenaOpponents and UnitIsEnemy("player", arg1) then
  109.                 for index = 1, numArenaOpponents do
  110.                     if UnitIsUnit("arena" .. index, arg1) then
  111.                         UpdateNamePlateIcon(namePlate, arg1, iconData[arenaSpec[index]])
  112.                         return
  113.                     end
  114.                 end
  115.             end
  116.             if not UpdateNamePlateIcon(namePlate, arg1) and CanInspect(arg1) then
  117.                 local guid = UnitGUID(arg1)
  118.                 if guid then
  119.                     namePlateByGUID[guid], inspectList[namePlate] = namePlate, arg1
  120.                     self:Show()
  121.                 end
  122.             end
  123.         end
  124.     elseif event == "NAME_PLATE_UNIT_REMOVED" then
  125.         local namePlate = GetNamePlateForUnit(arg1)
  126.         if namePlate then
  127.             inspectList[namePlate], reinspectList[namePlate] = nil, nil
  128.             local guid = UnitGUID(arg1)
  129.             if guid then
  130.                 namePlateByGUID[guid] = nil
  131.             end
  132.             if namePlate[iconKey] then
  133.                 namePlate[iconKey]:Hide()
  134.             end
  135.         end
  136.     elseif event == "PLAYER_ENTERING_WORLD" then
  137.         wipe(arenaSpec)
  138.         wipe(inspectList)
  139.         wipe(reinspectList)
  140.         numArenaOpponents = nil
  141.     elseif event == "ARENA_PREP_OPPONENT_SPECIALIZATIONS" then
  142.         wipe(arenaSpec)
  143.         numArenaOpponents = GetNumArenaOpponents()
  144.         if numArenaOpponents > 0 then
  145.             for index = 1, numArenaOpponents do
  146.                 local specID = GetArenaOpponentSpec(index)
  147.                 arenaSpec[index] = (specID or 0) > 0 and specID or nil
  148.                 local namePlate = GetNamePlateForUnit("arena" .. index)
  149.                 if namePlate then
  150.                     inspectList[namePlate], reinspectList[namePlate] = nil, nil
  151.                     UpdateNamePlateIcon(namePlate, namePlate.namePlateUnitToken, iconData[specID])
  152.                 end
  153.             end
  154.         else
  155.             numArenaOpponents = nil
  156.         end
  157.     end
  158. end)
  159.  
  160. frame:SetScript("OnUpdate", InspectList_OnUpdate)
  161.  
  162. frame:RegisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS")
  163. frame:RegisterEvent("INSPECT_READY")
  164. frame:RegisterEvent("NAME_PLATE_UNIT_ADDED")
  165. frame:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
  166. frame:RegisterEvent("PLAYER_ENTERING_WORLD")
  167. frame:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED")
  168.  
  169. do
  170.     local GetClassAtlas, GetClassInfo = GetClassAtlas, GetClassInfo
  171.     local GetNumSpecializationsForClassID = GetNumSpecializationsForClassID
  172.     local GetSpecializationInfoForClassID = GetSpecializationInfoForClassID
  173.  
  174.     for index = 1, GetNumClasses() do
  175.         local _, class, classID = GetClassInfo(index)
  176.         local atlas = GetClassAtlas(class)
  177.         iconData[classID], isAtlas[atlas] = atlas, true
  178.         for specNum = 1, GetNumSpecializationsForClassID(classID) do
  179.             local specID, name, description, icon = GetSpecializationInfoForClassID(classID, specNum)
  180.             iconData[specID] = icon
  181.         end
  182.     end
  183. end
  Reply With Quote