WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   AddOn Help/Support (https://www.wowinterface.com/forums/forumdisplay.php?f=3)
-   -   Latest patch broke a small addon from Arenajunkies (author quit the game.) (https://www.wowinterface.com/forums/showthread.php?t=52688)

Lesteryoung 09-02-15 08:26 PM

Latest patch broke a small addon from Arenajunkies (author quit the game.)
 
It's a nameplate addon so I assume what broke it is the same thing that broke every other nameplate addon, something about hp values.

It just modifies the default nameplates when in an arena. Don't think the author is gonna be fixing this any time soon, otherwise I would just wait patiently.

Oh, and if anyone cares to take a look, would you mind getting rid of the totem filtering aspect of the addon? The guy who made it said he would remove it eventually but that was like 6 months ago.

Code:

--<< Configuration >>--

-- Font size for the ArenaID numbers (default 14)
local FontSize = 14

-- Shows the arena numbers always 100% opaque, for improved visibility. If false, they will inherit the nameplate opacity (50% non-target / 100% target)
local OpaqueMode = true

-- Replaces the font default shadow with an outline (looks better). If false, the number will look exactly as the default level number
local Outline = true

-- Hides the unitname of nameplates of arena enemy players, to make them more simple
local HideNames = false

-- Change the color of nameplates based on its combat status
local CombatColoring = true
-- Check the combat status every this seconds. The lower the number the higher the precision (but also the CPU use)
local CheckPrecision = 0.2
-- Color for nameplates of units out of combat
local NoCombatColor  = {}
      NoCombatColor.R = 0
      NoCombatColor.G = 1
      NoCombatColor.B = 0

-- Totem filter. Show only the nameplate of specific totems
local TotemFilter = false
-- List of totems to show/hide
local Totems = {
  [2062]  = false, -- Earth Elemental Totem
  [2484]  = false, -- Earthbind Totem
  [2894]  = false, -- Fire Elemental Totem
  [3599]  = false, -- Searing Totem
  [5394]  = true,  -- Healing Stream Totem
  [8143]  = true,  -- Tremor Totem
  [8177]  = true,  -- Grounding Totem
  [8190]  = true,  -- Magma Totem
  [51485]  = false, -- Earthgrab Totem
  [16190]  = true,  -- Mana Tide Totem
  [98008]  = true,  -- Spirit Link Totem
  [108269] = true,  -- Capacitor Totem
  [108270] = false, -- Stone Bulwark Totem
  [108273] = false, -- Windwalk Totem
  [108280] = true,  -- Healing Tide Totem
  [120668] = true,  -- Stormlash Totem
}

--<< End of Configuration >>--

-- Upvalues
local pairs, unpack, select, hooksecurefunc, CreateFrame, WorldFrame, IsInInstance, UnitExists, UnitHealthMax, GetUnitName, UnitAffectingCombat, GetNumArenaOpponents =
      pairs, unpack, select, hooksecurefunc, CreateFrame, WorldFrame, IsInInstance, UnitExists, UnitHealthMax, GetUnitName, UnitAffectingCombat, GetNumArenaOpponents

-- Namespace local vars
local _ -- Declaring this name as local to avoid any possible taint with Blizzard's global declaration of _
local NumChildren = -1 -- WorldFrame child counter
local Number = {} -- Stores the FontStrings with the ArenaID numbers
local VisiblePlates = {} -- Stores references to the visible nameplates that we want to check its combat status (indexed by UnitID)
local NumVisiblePlates = 0 -- Counter for the number of elements on the table VisiblePlates
local TotemsToHide = {} -- List of the totem names (in the current locale) that we want to hide their nameplates
local CombatChecker = CreateFrame("Frame") -- Frame whose OnUpdate will check the combat status of the nameplates on VisiblePlates
      CombatChecker.LastUpdate = 0
local AP = CreateFrame("Frame") -- Addon main frame
      AP:SetFrameStrata("LOW")

-- Event registration
AP:SetScript("OnEvent", function(self, event, ...) return self[event](self, ...) end)
AP:RegisterEvent("PLAYER_LOGIN")
AP:RegisterEvent("PLAYER_ENTERING_WORLD")

-- CreateNumber()
-- Creates an ArenaID number, to be anchored to nameplates.
-- > i:          Number digit.
-- > FontSource: Nameplate level FontString to clone it.
-- < Number:    FontString of the created number.
local function CreateNumber(i, FontSource)
  local Number = AP:CreateFontString()

  -- Cloning the level FontString
  Number:SetDrawLayer(FontSource:GetDrawLayer())
  Number:SetFontObject(FontSource:GetFontObject())
  Number:SetFont(FontSource:GetFont())
  Number:SetTextColor(FontSource:GetTextColor())
  Number:SetShadowColor(FontSource:GetShadowColor())
  Number:SetShadowOffset(FontSource:GetShadowOffset())
  Number:SetText(i)

  -- Setting font size
  local FontData = { Number:GetFont() }
  FontData[2] = FontSize

  -- If outline wanted, creating it and removing the default shadow
  if Outline then
    FontData[3] = "OUTLINE"
    Number:SetShadowColor(0, 0, 0, 0)
    Number:SetShadowOffset(0, 0)
  end

  Number:SetFont(unpack(FontData))
  return Number
end

-- PutNumber()
-- Replace the level number of a nameplate for an ArenaID number.
-- > i:    Number digit
-- > Plate: Nameplate reference
local function PutNumber(i, Plate)
  if not Number[i] then Number[i] = CreateNumber(i, Plate.AP.Level) end
  local N = Number[i] -- ArenaID FontString reference

  if HideNames then Plate.AP.Name:Hide() end -- Option for hiding the unitname
  Plate.AP.Level:Hide() -- Hiding the level text, coz the ArenaID number will be here
  Plate.AP.ArenaID = N -- Storing a reference in the nameplate to the ArenaID number FontString, for later use in NAMEPLATE_HIDE

  -- Anchoring the number to the nameplate
  local AnchorData = { Plate.AP.Level:GetPoint() } -- Getting the anchor point of the default level FontString
  if Outline then AnchorData[5] = AnchorData[5] - 1 end -- If outlined, move it 1 pixel down
  N:SetPoint(unpack(AnchorData)) -- Anchoring the ArenaID number on the same place of the default level FontString

  -- If "always 100% opacity" is not wanted, configuring the number to inherit the nameplate opacity
  if not OpaqueMode then
    N:SetParent(Plate.AP.Level:GetParent())
    N:SetDrawLayer(Plate.AP.Level:GetDrawLayer())
  end

  N:Show()
end

-- CombatCheckerFunc()
-- OnUpdate function for the CombatChecker frame.
-- Checks the combat status of visible nameplates that pertain to arena enemies, and changes the border color based on it.
-- > self:    Reference to the CombatChecker frame
-- > Elapsed: Time since the last OnUpdate cycle
local function CombatCheckerFunc(self, Elapsed)
  -- OnUpdate time check
  self.LastUpdate = self.LastUpdate + Elapsed
  if self.LastUpdate < CheckPrecision then return end
  self.LastUpdate = 0

  -- The time has passed, checking combat status on visible nameplates
  for UnitID, Plate in pairs(VisiblePlates) do
    if UnitAffectingCombat(UnitID) then Plate.AP.Border:SetVertexColor(1, 1, 1)
    else Plate.AP.Border:SetVertexColor(NoCombatColor.R, NoCombatColor.G, NoCombatColor.B) end
  end
end

-- IsUnitPlate()
-- Checks if a nameplate is the nameplate of a given UnitID.
-- > Plate:  Nameplate reference
-- > UnitID: UnitID
-- < Boolean result
local function IsUnitPlate(Plate, UnitID)
  if not UnitExists(UnitID) then return false end

  local p_HPmax = select(2, Plate.AP.Healthbar:GetMinMaxValues())
  local p_Name  = Plate.AP:GetUnitName()

  local u_HPmax = UnitHealthMax(UnitID)      -- Maximum health
  local u_Name  = GetUnitName(UnitID, false) -- Unit name

  if p_HPmax == u_HPmax and p_Name == u_Name then return true end
  return false
end

-- GetArenaUnitID()
-- Returns the Arena UnitID of a nameplate.
-- > Plate: Nameplate reference.
-- < UnitID (nil if not found)
local function GetArenaUnitID(Plate)
  -- Iterating thru all the arena enemies and their pets
  for i = 1, GetNumArenaOpponents() do
    for _, UnitID in pairs({"arena"..i, "arenapet"..i}) do
      if IsUnitPlate(Plate, UnitID) then return UnitID end
    end
  end

  return nil
end

-- Event NAMEPLATE_SHOW
-- Fires when a nameplate appears on screen.
-- > Plate: Nameplate reference
local function NAMEPLATE_SHOW(Plate)
  -- If it's a totem we don't want to see, hide it
  if TotemsToHide[Plate.AP:GetUnitName()] then
    Plate.AP:SetShown(false)
    return
  end

  local UnitID = GetArenaUnitID(Plate) -- UnitID of the owner of this nameplate
  if not UnitID then return end -- Doesn't have an UnitID
  Plate.AP.UnitID = UnitID -- Storing nameplate's UnitID (for future use in NAMEPLATE_HIDE)

  -- If it's an enemy player, put his ArenaID number on his nameplate
  if UnitID:sub(1, 5) == "arena" and UnitID:len() == 6 then PutNumber(UnitID:sub(6), Plate) end

  -- If we want to color by combat status, add this nameplate to the combat checker process
  if CombatColoring then
    if NumVisiblePlates == 0 then CombatChecker:SetScript("OnUpdate", CombatCheckerFunc) end -- Enabling combat tracker
    VisiblePlates[UnitID] = Plate
    NumVisiblePlates = NumVisiblePlates + 1
  end
end

-- Event NAMEPLATE_HIDE
-- Fires when a nameplate disappears from screen.
-- > Plate: Nameplate reference
local function NAMEPLATE_HIDE(Plate)
  -- If it's a hidden totem, show again all frames and regions that were hidden
  if TotemsToHide[Plate.AP:GetUnitName()] then
    Plate.AP:SetShown(true)
    return
  end

  if not Plate.AP.UnitID then return end -- Doesn't have an UnitID

  -- Removing from the combat tracker
  if CombatColoring then
    VisiblePlates[Plate.AP.UnitID] = nil
    NumVisiblePlates = NumVisiblePlates - 1
    if NumVisiblePlates == 0 then CombatChecker:SetScript("OnUpdate", nil) end -- Disabling combat tracker coz there isn't any nameplates
    Plate.AP.Border:SetVertexColor(1, 1, 1)
  end
  Plate.AP.UnitID = nil

  -- If it has an ArenaID number attached, free it
  if Plate.AP.ArenaID then
    Plate.AP.ArenaID:Hide()
    Plate.AP.ArenaID:ClearAllPoints()
    Plate.AP.ArenaID:SetParent(AP)
    Plate.AP.ArenaID = nil
    -- Showing again the regions that were hidden
    Plate.AP.Name:Show() -- Unit name (hidden if HideNames option is used)
    Plate.AP.Level:Show() -- Level number
  end
end

-- SetScriptHook()
-- This function is used in the secure hook of SetScript() on nameplate frames, to detect selfish addons which use
-- that instead of HookScript() (destroying the hooks of every other nameplate addon running), to re-apply our hooks.
-- > Plate: Nameplate reference
-- > Handler: Script handler used on the SetScript() call
-- > Func: Hooked function
local function SetScriptHook(Plate, Handler, Func)
  if Handler == "OnShow" then Plate:HookScript("OnShow", NAMEPLATE_SHOW)
  elseif Handler == "OnHide" then Plate:HookScript("OnHide", NAMEPLATE_HIDE) end
end

-- StructurePlate()
-- Creates references to the frames and regions of a nameplate used by the addon, and adds events/methods/hooks.
-- Every new property is created under the table "AP", to avoid using the same names as other addons.
-- > Plate: Nameplate reference
local function StructurePlate(Plate)
  local Child = { Plate:GetChildren() }
  Child[1].Region = { Child[1]:GetRegions() }
  Plate.AP = {}

  -- Creating references to frames and regions we need to access
  Plate.AP.Border    = Child[1].Region[2]
  Plate.AP.Level    = Child[1].Region[4]
  Plate.AP.Healthbar = Child[1]:GetChildren()
  Plate.AP.Name      = Child[2]:GetRegions()

  -- SetShown(): Shows/Hides the nameplate without tainting it
  Plate.AP.SetShown = function(self, ShowFlag)
    local Alpha = 0
    if ShowFlag then Alpha = 1 end
    -- Bar frame. Can't be hidden directly, hidding all regions and children
    for K, V in pairs({ Child[1]:GetRegions() }) do V:SetShown(ShowFlag); V:SetAlpha(Alpha) end
    for K, V in pairs({ Child[1]:GetChildren() }) do V:SetShown(ShowFlag); V:SetAlpha(Alpha) end
    -- Name frame
    Child[2]:SetShown(ShowFlag)
  end

  -- GetUnitName(): Returns the nameplate unit name
  Plate.AP.GetUnitName = function()
    return Plate.AP.Name:GetText()
  end

  -- Scripts
  Plate:HookScript("OnShow", NAMEPLATE_SHOW) -- Event to trigger when the nameplate appears on screen
  Plate:HookScript("OnHide", NAMEPLATE_HIDE) -- Event to trigger when the nameplate disappears from screen
  if Plate:IsVisible() then NAMEPLATE_SHOW(Plate) end -- If it's already visible trigger for the first time

  -- Hooking the use of SetScript() on nameplates by other addons, so they don't fuck our hooks
  hooksecurefunc(Plate, "SetScript", SetScriptHook)
end

-- PlateProcess()
-- Process the WorldFrame children whenever a new children it's created, to catch nameplates.
local function PlateProcess()
  if WorldFrame:GetNumChildren() == NumChildren then return end
  NumChildren = WorldFrame:GetNumChildren()

  for _, Plate in pairs({WorldFrame:GetChildren()}) do
    if not Plate.ArenaPlates and Plate:GetName() and Plate:GetName():find("NamePlate") then
      Plate.ArenaPlates = true -- Mark as seen to ignore it in future iterations
      StructurePlate(Plate)
    end
  end
end

-- Evento PLAYER_LOGIN
-- Fires after PLAYER_ENTERING_WORLD after logging in and after /reloadui.
function AP:PLAYER_LOGIN()
  -- If we want to use the totem filter, populating totem table
  if TotemFilter then
    for TotemID, Visible in pairs(Totems) do
      local TotemName = GetSpellInfo(TotemID) -- 1st argument is the name
      if not TotemName then print("[ArenaPlates] Totem with ID "..TotemID.." does not exists.") end
      if not Visible and TotemName then TotemsToHide[TotemName] = true end
    end
  end

  -- Checking if we are in arena after logging in to enable nameplate processing
  -- This is useful when relogging after getting disconnected from arena, because PLAYER_ENTERING_WORLD does not trigger always in this case
  if select(2, IsInInstance()) == "arena" then AP:SetScript("OnUpdate", PlateProcess) end
end

-- Event PLAYER_ENTERING_WORLD
-- Fires after a loading screen.
function AP:PLAYER_ENTERING_WORLD()
  -- If it's an arena, enabling nameplate processing, disabling it otherwise
  if select(2, IsInInstance()) == "arena" then AP:SetScript("OnUpdate", PlateProcess)
  else AP:SetScript("OnUpdate", nil) end
end


wardz 09-03-15 09:27 AM

http://pastebin.com/1Akzz4AA
Haven't tested it properly, but seems to be working again.


All times are GMT -6. The time now is 11:20 AM.

vBulletin © 2020, Jelsoft Enterprises Ltd
© 2004 - 2020 MMOUI