WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   replacing map blips (https://www.wowinterface.com/forums/showthread.php?t=49557)

ObbleYeah 08-01-14 04:42 AM

replacing map blips
 
I have a small function that intends to bring back old cartographer-style world map blips - with embedded group #s and colour changes when the unit is in specific conditions like combat or AFK.

Lua Code:
  1. --
  2.     local blippadding = 5
  3.     --
  4.  
  5.     local frame = CreateFrame("Frame", nil, WorldMapFrame)
  6.     local frequency = .5 -- how often to update blips (while in group when map shown)
  7.     local timer = frequency
  8.     frame:Hide()
  9.  
  10.     frame:SetScript("OnUpdate", function(self, elapsed)
  11.         timer = timer + elapsed
  12.         if (timer > frequency) then
  13.             timer = 0
  14.             local groupSize = GetNumGroupMembers()
  15.             local groupUnit = IsInRaid() and "Raid" or "Party"
  16.            
  17.             if (groupSize > 0) then
  18.                 for i = 1, groupSize do
  19.                     local blip = _G["WorldMap"..groupUnit..i]
  20.                     local blipoverlay = blip:CreateTexture(nil, "OVERLAY")
  21.                     blipoverlay:SetDrawLayer("OVERLAY", 7)
  22.                     blipoverlay:SetPoint("TOPLEFT", blip.icon, -blippadding, blippadding)
  23.                     blipoverlay:SetPoint("BOTTOMRIGHT", blip.icon, blippadding, -blippadding)
  24.                    
  25.                     if blip and blip.unit and blip:IsVisible() then
  26.                         local _, class = UnitClass(blip.unit)
  27.                         local _, _, subgroup = GetRaidRosterInfo(i)
  28.                        
  29.                         if not blip.skinned then
  30.                             if (UnitInRaid(blip.unit)) then
  31.                                 blipoverlay:SetTexture(format("Interface\\AddOns\\WorldMapForModernists\\blips\\raid%d", subgroup))
  32.                             else
  33.                                 blipoverlay:SetTexture("Interface\\AddOns\\WorldMapForModernists\\blips\\party")
  34.                             end
  35.                             blip.skinned = true
  36.                        end
  37.                        
  38.                        if (blip.skinned) then
  39.                             -- color the texture
  40.                             local color = CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS[class]
  41.                             -- by class
  42.                             if color then
  43.                                 blipoverlay:SetVertexColor(color.r, color.g, color.b)
  44.                             -- fallback
  45.                             else
  46.                                 blipoverlay:SetVertexColor(103/255, 103/255, 103/255)
  47.                             end
  48.                        
  49.                             if (GetTime() % 1 < .5) then
  50.                                 -- combat (flashing)
  51.                                 if UnitAffectingCombat(blip.unit) then
  52.                                     blipoverlay:SetVertexColor(1, 0, 0)
  53.                                 -- dead (flashing)
  54.                                 elseif UnitIsDeadOrGhost(blip.unit) then
  55.                                     blipoverlay:SetVertexColor(.2, .2, .2)
  56.                                 -- AFK (flashing)
  57.                                 elseif UnitIsAFK(blip.unit) then
  58.                                     blipoverlay:SetVertexColor(255/255, 206/255, 206/255)
  59.                                 end
  60.                             end
  61.                         end
  62.                     end
  63.                 end
  64.             end
  65.         end
  66.     end)
  67.  
  68.     frame:SetScript("OnEvent",function(self,event)
  69.         timer = frequency
  70.         self:SetShown(IsInGroup())
  71.     end)
  72.    
  73.     frame:RegisterEvent("GROUP_ROSTER_UPDATE")
  74.     frame:RegisterEvent("WORLD_MAP_UPDATE")

the colour updates currently won't update like this. If I remove the blip.skinned check on line 25 then it does update as intended, but I assume that's because it's creating a new texture on every pass which is understandably a very bad thing. I recognise that this is probably written very badly, so what do I need to do to make this work?

Vlad 08-01-14 06:45 AM

There were some issues at some lines.

For instance the logic for what texture to use is a bit awkward as the texture it should use already is defined in the groupUnit variable. Meaning we only need one check at the begining and draw our custom overlay if it doesn't exist, also apply texture there. The only thing the for loop further down needs to do is make the texture change color accordingly.

I've rewritten it and tried to clean it up a bit. Take a look. Perhaps it fixes some of the issues, perhaps not. I haven't actually tested it myself. Do write what happens though, I am interested.

Also yes I hooked the Minimap UpdateBlips function so when it runs our code run, kind of more synchronized that just randomly updating hoping to update at the right time. Besides the UpdateBlips function runs at lower intervals, so it won't be each frame update either. Good for us!

Code:

local addonName = ...
local padding = 5

local groupSize, groupType, frame
local _, subgroup, class, color
local elapsed = 0

WorldMapFrame:HookScript("OnUpdate", function(self, e)
        elapsed = elapsed + e
        if elapsed > .5 then -- update frequency
                elapsed = 0
                groupSize = GetNumGroupMembers()
                if groupSize > 0 then
                        groupType = IsInRaid() and "Raid" or "Party"
                        for i = 1, groupSize do
                                frame = _G["WorldMap" .. groupType .. i]
                                if frame then
                                        if not frame.overlay then
                                                frame.overlay = frame:CreateTexture(nil, "OVERLAY")
                                                frame.overlay:SetDrawLayer("OVERLAY", 7)
                                                frame.overlay:SetPoint("TOPLEFT", frame.icon, -padding, padding)
                                                frame.overlay:SetPoint("BOTTOMRIGHT", frame.icon, padding, -padding)
                                                _, _, subgroup = GetRaidRosterInfo(i)
                                                frame.overlay:SetTexture(groupType == "Raid" and ("Interface\\AddOns\\" .. addonName .. "\\blips\\raid" .. subgroup) or "Interface\\AddOns\\" .. addonName .. "\\blips\\party")
                                        end
                                        if frame.unit and frame:IsShown() then
                                                _, class = UnitClass(frame.unit)
                                                color = (CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS)[class]
                                                if color then
                                                        frame.overlay:SetVertexColor(color.r, color.g, color.b)
                                                else
                                                        frame.overlay:SetVertexColor(103/255, 103/255, 103/255)
                                                end
                                                if GetTime() % 1 < .5 then
                                                        if UnitAffectingCombat(frame.unit) then
                                                                frame.overlay:SetVertexColor(1, 0, 0)
                                                        elseif UnitIsDeadOrGhost(frame.unit) then
                                                                frame.overlay:SetVertexColor(.2, .2, .2)
                                                        elseif UnitIsAFK(frame.unit) then
                                                                frame.overlay:SetVertexColor(255/255, 206/255, 206/255)
                                                        end
                                                end
                                        end
                                end
                        end
                end
        end
end)


ObbleYeah 08-01-14 07:42 AM

Hey, thanks for the clean up!

Not sure if the hook is the wrong choice or something but textures only appear after 30 seconds or so, presumably due to the lower intervals at which UpdateBlips runs. I also had to change the initial check for the colouring section of the function to just

Lua Code:
  1. if frame.unit then

for it to start colouring, but even then it updates only sporadically and without the intended flashing updates for dead or in combat blips.

Vlad 08-01-14 08:43 AM

*Edit* I updated my code above with the changes below. You can copy paste it instead if you like. :)

Great feedback.

The hook updates quite often when I tested, but probably not if there are no blips on the minimap to show.

For that I suggest changing:
Code:

hooksecurefunc(Minimap, "UpdateBlips", function()
to this:
Code:

local elapsed = 0
WorldMapFrame:HookScript("OnUpdate", function(self, e)
        elapsed = elapsed + e
        if elapsed < .5 then return end -- update frequency
        elapsed = 0

I thought about it and it's probably best to add a OnUpdate after all, since the blips even if not moving or updating, need to flash. :P


The "if frame.unit then" will update units that aren't visible as well. On the other hand perhaps instead of "IsVisible" maybe "IsShown" is better. Try using "if frame.unit and frame:IsShown() then" and see if it works. This will help avoid updating the hidden frames, we don't need to update those anyway. :)

ObbleYeah 08-01-14 09:15 AM

Working perfectly, thanks!


All times are GMT -6. The time now is 06:41 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI