clcinfo and icon code

clcinfo

There is an addon for World of Warcraft called clcinfo that enables a player to compose UI elements to alert you to things that you want to be notified up, and also allows you to display an icon that shows you an ability and put some logic behind it to let you know when you should use that ability in relation to others. If you don’t like a UI cluttered with several rows of action buttons and throbbing indicators, clcinfo can help you keep a nice and tidy view of the game.

I am using some lua written by JLeeder and other examples from the clcinfo wiki but especially want to point out that Jeremy’s examples made for a great introduction.

clcinfo isn’t just useful for damage-dealing classes, you can also use it to show cooldowns or abilities for tanking or healing roles, such as letting you know that your next two Healing Wave casts are going to be great because you’ve just used Riptide.

Shadow Priest clcinfo grid I use

my grid for Shadow Priest DPS

In the course of customizing my UI even further for me, I have written up a few other icons for single cooldowns like summoning my Guardians, or trinket procs and set bonuses. I then have a large icon that I call “DPS” and that is where my priority queue comes into play.

Set bonuses and trinkets

the T11 Warlock set has a set bonus that procs a stacking buff called Fel Spark, and when you have that active, your Fel Flame casts are worth casting even when you’re not moving. Similar abilities are things like Shadow Orbs, Fulmination, anything that stacks and is consumed by an ability.

Since Fel Flame in particular is a very situational ability and not part of the standard routine for DPS, being notified that this ensemble set of gear has proc’ed and is now active and then showing an icon for Fel Flame helps me use that proc (or a trinket or some other set bonus) to my advantage.

Position that icon somewhere you want to see it without having to scan a list of buffs or have throbbing Power Auras all over the place. It’ll be faster than you can decide to use it, I swear.

example:

-- 1 Fel Spark active
local _, _, _, count, _, _, _, _, _, _, _ = UnitBuff("player", "Fel Spark")
if count ~= nil then
    fsCount=count
    else
        fsCount=0
end
if fsCount > 0 then
        return IconSpell("Fel Flame", true)
end

What the above code is doing is probably not the best way to do it, but I’m looking for a buff on the Player (me) called Fel Spark, and if it doesn’t exist, sets an internal counter for a variable called “fsCount” (Fel Spark count) to null. If it’s ever greater than 0 (because I have 1 or 2 stacks active), it will return an icon for the spell “Fel Flame”, letting me know that at this moment, casting Fel Flame is not a DPS loss, but will actually help me do more damage. How about that!

Anticipated Feedback

You can write a module for clcinfo for $class and share that. Why don’t you do it that way?

Because I don’t know how to make a module and I was quickly in over my head when I looked at the template module provided by the author. I’m not very good at this sort of thing, you probably don’t want me writing a module anyway. I may try again someday, but the other problem is that if I write a module, then I am on the hook for hearing about problems with it. By sharing the icon code instead you can see how to change priorities and make modifications for patches or new theorycraft easily without relying on a module.

Can’t you just share your SavedVariables for the classes you have worked on?

I could, but then I’d have to hear from people when it doesn’t work.

Warlock

clcinfo comes with a Destro module but there are a few things I didn’t like about it and it was being a bit flakey about Improved Soul Fire.

Destruction DPS Icon

This is my main icon that I use in my Destruction spec. It’s the largest icon I have visible in my clcinfo grid, and is what I’m usually keeping an eye on the most.

local thp = ((UnitHealth("target") / UnitHealthMax("target")) * 100)
local plvl = UnitLevel("player")
local currentTime = GetTime()
-- Get gcd
local gCD=1.5
-- True if (within 9.9 yards
local inRnge = CheckInteractDistance("target", 3)
--1 Fel Armor but accept Demon Armor too
local _, _, _, _, _, durFA, _, _, _, _, _ = UnitBuff("player", "Fel Armor")
local _, _, _, _, _, durDA, _, _, _, _, _ = UnitBuff("player", "Demon Armor")
if (durFA == nil and durDA == nil) then
		return IconSpell("Fel Armor")
end
-- Dark Intent applied
local _, _, _, _, _, duration, _, _, _, _, _ = UnitBuff("player", "Dark Intent")
if (duration == nil and plvl >= 83) then
		return IconSpell("Dark Intent")
end
-- ISF
	local x,x,x,x,x, durISF, expTISF, uCISF,x,x,x  = UnitBuff("player", "Improved Soul Fire")
	if (durISF ~= nil and uCISF == "player") then
		sfire = expTISF - currentTime
	else
			return IconSpell("Soul Fire", true)
	end
-- Immolate
local name, _, _, _, _, _, expirationTime, unitCaster, _, _, _ = UnitDebuff("target", "Immolate")
if (name ~= nil and unitCaster == "player") then
		Immo = expirationTime - currentTime
else
		Immo = 0.0
end
if (Immo <= 2) then
		return IconSpell("Immolate", true)
end
-- Conflag
local start, cdFlag = GetSpellCooldown("Conflagrate")
if (cdFlag < gCD) then
		return IconSpell("Conflagrate", true)
end
-- Empowered Imp proc
local _, _, _, _, _, duration, _, _, _, _, _ = UnitBuff("player", "Empowered Imp")
if (duration ~= nil) then
		return IconSpell("Soul Fire", true)
end
-- Bane of Doom but accept Agony or Havoc
local nBoA,x,x,x,x, durBoA, exTBoA, uCBoA,x,x,x	 = UnitDebuff("target", "Bane of Agony")
local nBoD,x,x,x,x, durBoD, exTBoD, uCBoD,x,x,x	 = UnitDebuff("target", "Bane of Doom")
local nBoH,x,x,x,x, durBoH, exTBoH, uCBoH,x,x,x	 = UnitDebuff("target", "Bane of Havoc")
if (nBoD ~= nil and uCBoD == "player") then
	bod = exTBoD - currentTime
	if (bod <= 1.0) then
		return IconSpell("Bane of Doom", true)
	end
elseif (nBoA ~= nil and uCBoA == "player") then
	boa = exTBoA - currentTime
	if (boa <= 1.0) then
		return IconSpell("Bane of Agony", true)
	end
else
		return IconSpell("Bane of Doom", true)
end
-- Corruption
local name, _, _, _, _, _, expirationTime, unitCaster, _, _, _ = UnitDebuff("target", "Corruption")
if (name ~= nil and unitCaster == "player") then
		corrup = expirationTime - currentTime
else
		corrup = 0.0
end
if (corrup <= 2.0) then
		return IconSpell("Corruption", true)
end
-- Shadowflame
local start, cdSfl = GetSpellCooldown("Shadowflame")
if (inRnge and cdSfl < gCD) then
		return IconSpell("Shadowflame", true)
end
-- Chaos Bolt
local start, cdCBolt = GetSpellCooldown("Chaos Bolt")
if (cdCBolt < gCD) then
		return IconSpell("Chaos Bolt", true)
end
-- Spam incinerate
return IconSpell("Incinerate", true)

Cooldowns

Guardian available

Show an icon to remind you that your Guardian is available. I use a Doomguard most of the time, use your judgement. Remember that Infernal will also put Doomguard on cooldown, so you can use either one and it will no longer show you can cast the other unless your shared cooldown expires.

-- Summon a Guardian
return IconSpell("Summon Doomguard",nil,"ready")

Lifetap

When mana is low, make a suggestion to Life Tap visible by creating an icon.

-- Life Tap
local mana = UnitPower("player")
local maxpower = UnitPowerMax("player")
tm = (mana/maxpower) *100
if tm <= 35 then
    return IconSpell("Life Tap")
end

Shadowburn

An icon to show me that a target is able to be Shadowburn’ed (it can be cast since the ability can be used due to the target health being low) and that Shadowburn is off cooldown.

-- Shadowburn
return IconSpell("Shadowburn",nil,"ready")

Metamorphosis

For Demonology specs, this lets you show that your Meta cooldown is available.

-- Metamorphosis 
return IconSpell("Metamorphosis",nil,"ready")

Now you can easily see how to create an icon for a simple cooldown like this, and can make your own for Teleport, Soul Shatter, or Death Coil, or anything else you would want.

Priest

I have a Disc clcinfo grid for tracking evangelism and penance and letting me know that Grace is off my target. I haven’t cleaned it up enough to share.

Shadow DPS priority icon

This icon for my Shadow Priest ensures I have Vampiric Embrace up, keeps track of Shadow Orbs, ensures I have SWP, DP and Vampiric Touch ticking on my current target, and then juggles cooldowns, target health for SW:D, prompts you to blow Archangel when Evangelism is stacked.

I keep my Shadowfiend on it’s own cooldown icon, along with Dispersion.

 -- moar dots
 local thp = ((UnitHealth("target") / UnitHealthMax("target")) * 100)
 local plvl = UnitLevel("player")
 currentTime = GetTime()
 -- Get gcd
 local gCD=1.5
 -- VE
 local _, _, _, _, _, durVE, _, _, _, _, _ = UnitBuff("player", "Vampiric Embrace")
 if durVE == nil then
         return IconSpell("Vampiric Embrace")
 end
 -- Shadow Orb Counts
 local _, _, _, count, _, _, _, _, _, _, _ = UnitBuff("player", "Shadow Orb")
 if count ~= nil then
     orbCount=count
 else
     orbCount=0
 end
 -- start DPS
 -- SWP
 local name, _, _, _, _, _, expirationTime, unitCaster, _, _, _ = UnitDebuff("target", "Shadow Word: Pain")
 if name ~= nil and unitCaster == "player" then
         swPain = expirationTime - currentTime
 else
         swPain = 0
 end
 if (swPain <= 1.5) then
         return IconSpell("Shadow Word: Pain")
 end
 -- MB if Charged
 local start, cdBlast = GetSpellCooldown("Mind Blast")
 if (cdBlast <= gCD and orbCount > 2) then
     return IconSpell("Mind Blast", true)
 end
 -- Vampiric Touch
 local name, _, _, _, _, _, expirationTime, unitCaster, _, _, _ = UnitDebuff("target", "Vampiric Touch")
 if name ~= nil and unitCaster == "player" then
         vTouch = expirationTime - currentTime
 else
         vTouch = 0.0
 end
 if (vTouch <= 2.5) then
         return IconSpell("Vampiric Touch")
 end
 -- Devouring Plague
 local name, _, _, _, _, _, expirationTime, unitCaster, _, _, _ = UnitDebuff("target", "Devouring Plague")
 if name ~= nil and unitCaster == "player" then
         dPlague = expirationTime - currentTime
 else
         dPlague = 0.0
 end
 if (dPlague <= 2) then
         return IconSpell("Devouring Plague")
 end
 -- Mind Blast
 local start, cdMB = GetSpellCooldown("Mind Blast")
 if cdMB < gCD then
         return IconSpell("Mind Blast", true)
 end
 -- SW:D
 if (thp <= 20) then
         local start, cdSWD = GetSpellCooldown("Shadow Word: Death")
 				if cdSWD < gCD then
         			return IconSpell("Shadow Word: Death", true)
 				end
 end
 -- Archangel when you've got it
 local start, cdArch = GetSpellCooldown("Archangel")
 if (cdArch <= gCD and evaCount > 4) then
     return IconSpell("Archangel", true)
 end
 -- Mind Flay
 return IconSpell("Mind Flay", true)

Shaman

My shaman is Elemental and Resto and I’ve done some icons for those two specs too.

Resto priority icon

local currentTime = GetTime()
-- Get gcd
local gcd=1.5
-- Water Shield active
local _, _, _, count, _, _, _, _, _, _, _ = UnitBuff("player", "Water Shield")
if count ~= nil then
    wsCount=count
else
   wsCount=0
end
if wsCount == 0 then
    return IconSpell("Water Shield")
end
-- Tidal Waves active?  Healing Wave is extra good right now.
local _, _, _, _, _, duration, _, _, _, _, _ = UnitBuff("player", "Tidal Waves")
if duration ~= nil then
        return IconSpell("Healing Wave")
end
-- Nature's Swiftness can be used 
local start, cdswift = GetSpellCooldown("Nature's Swiftness")
if (cdswift < gcd) then
        return IconSpell("Nature's Swiftness", true)
end

Elemental DPS priority icon

Pew pew, keep LS up, Flame Shock on your target, Lava Burst when you can, and turret LB to greatness.

Elemental Shaman

my grid for Elemental DPS

Use CL at your discretion, and I use another icon to show Nova cooldowns.

-- shocking
local currentTime = GetTime()
-- Get gcd
local gcd=1.5
-- Lightning Shield
local _, _, _, count, _, _, _, _, _, _, _ = UnitBuff("player", "Lightning Shield")
if count ~= nil then
	lsCount=count
else
lsCount=0
end
if lsCount == 0 then
	return IconSpell("Lightning Shield")
end
-- Flame Shock timer (this used to also juggle Unleashed Elements)
local start, cdFlame = GetSpellCooldown("Flame Shock")
local start, cdUE = GetSpellCooldown("Unleash Elements")
local name, _, _, _, _, _, expirationTime, unitCaster, _, _, _ = UnitDebuff("target", "Flame Shock")
if (name ~= nil and unitCaster == "player") then
    fsTime = expirationTime - currentTime
else
fsTime = 0.0
end	
-- Flame Shock 
if (fsTime < 1.0 and cdFlame < gcd ) then
    return IconSpell("Flame Shock", true)
end
-- Lava Burst
local start, cdLava = GetSpellCooldown("Lava Burst")
	if (cdLava < gcd) then
  	  return IconSpell("Lava Burst", true)
end
-- Earth Shock if 7-9 Charges
local start, cdEarth = GetSpellCooldown("Earth Shock")
	if (cdEarth <= gcd and lsCount >= 7) then
	return IconSpell("Earth Shock", true)
end
-- LB Spam
return IconSpell("Lightning Bolt", true)

Cooldowns

Thunderstorm

If I’m below 90% mana and Thunderstorm is available, I should cast it.

-- Cue the AC/DC, you've just been Thunderstruck
local mana = UnitPower("player")
local maxpower = UnitPowerMax("player")
tm = (mana/maxpower) *100
if tm <= 90 then
	return IconSpell("Thunderstorm",nil,"ready")
end

Searing Totem

This will tell me when Searing Totem needs to be down, and not cry at me about it when a Fire Elemental or other Fire totem is active.

-- So hot
haveTotem, totemName, startTime, duration = GetTotemInfo(1)
if duration ~= nil then
    if  duration <= 3 then
        return IconSpell("Searing Totem")    
    end
end

Fire Elemental Totem available

-- The roof is on fire
return IconSpell("Fire Elemental Totem",nil,"ready")

Mana Tide Totem available

-- get more spirit
return IconSpell("Mana Tide Totem",nil,"ready")

Published: December 10 2011