Thread Tools Display Modes
08-01-14, 04:42 AM   #1
ObbleYeah
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Sep 2008
Posts: 210
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?
  Reply With Quote
08-01-14, 06:45 AM   #2
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
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)
__________________
Profile: Curse | Wowhead

Last edited by Vlad : 08-01-14 at 08:45 AM.
  Reply With Quote
08-01-14, 07:42 AM   #3
ObbleYeah
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Sep 2008
Posts: 210
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.
  Reply With Quote
08-01-14, 08:43 AM   #4
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
*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.
__________________
Profile: Curse | Wowhead

Last edited by Vlad : 08-01-14 at 08:45 AM.
  Reply With Quote
08-01-14, 09:15 AM   #5
ObbleYeah
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Sep 2008
Posts: 210
Working perfectly, thanks!
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » replacing map blips

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off