local parent, ns = ... local oUF = ns.oUF local _FRAMES = {} local OnRangeFrame local UnitIsConnected = UnitIsConnected local tinsert, tremove, twipe = table.insert, table.remove, table.wipe local friendlySpells, resSpells, longEnemySpells, enemySpells, petSpells = {}, {}, {}, {}, {} local function AddSpell(table, spellID) local name = GetSpellInfo(spellID) if name then local usable, nomana = IsUsableSpell(name) if usable or nomana then table[#table + 1] = name end end end local _,class = UnitClass("player") local function UpdateSpellList() twipe(friendlySpells) twipe(resSpells) twipe(longEnemySpells) twipe(enemySpells) twipe(petSpells) if class == "PRIEST" then AddSpell(enemySpells, 585) -- Smite AddSpell(longEnemySpells, 589) -- Shadow Word: Pain AddSpell(friendlySpells, 2061) -- Flash Heal AddSpell(resSpells, 2006) -- Resurrection elseif class == "DRUID" then AddSpell(enemySpells, 33786) -- Cyclone AddSpell(longEnemySpells, 5176) -- Wrath AddSpell(friendlySpells, 774) -- Rejuvenation AddSpell(resSpells, 50769) -- Revive AddSpell(resSpells, 20484) -- Rebirth elseif class == "PALADIN" then AddSpell(enemySpells, 20271) -- Judgement AddSpell(friendlySpells, 85673) -- Word of Glory AddSpell(resSpells, 7328) -- Redemption AddSpell(longEnemySpells, 114165) -- Holy Prism AddSpell(longEnemySpells, 114157) -- Execution Sentence elseif class == "SHAMAN" then AddSpell(enemySpells, 8042) -- Earth Shock AddSpell(longEnemySpells, 403) -- Lightning Bolt AddSpell(friendlySpells, 8004) -- Healing Surge AddSpell(resSpells, 2008) -- Ancestral Spirit elseif class == "WARLOCK" then AddSpell(enemySpells, 5782) -- Fear AddSpell(longEnemySpells, 172) -- Corruption AddSpell(longEnemySpells, 686) -- Shadow Bolt AddSpell(longEnemySpells, 17962) -- Conflag AddSpell(petSpells, 755) -- Health Funnel AddSpell(friendlySpells, 5697) -- Unending Breath elseif class == "MAGE" then AddSpell(enemySpells, 118) -- Polymorph AddSpell(longEnemySpells, 44614) -- Frostfire Bolt AddSpell(friendlySpells, 475) -- Remove Curse elseif class == "HUNTER" then AddSpell(petSpells, 136) -- Mend Pet AddSpell(enemySpells, 75) -- Auto Shot elseif class == "DEATHKNIGHT" then AddSpell(enemySpells, 49576) -- Death Grip AddSpell(friendlySpells, 47541) -- Death Coil AddSpell(resSpells, 61999) -- Raise Ally elseif class == "ROGUE" then AddSpell(enemySpells, 2094) -- Blind AddSpell(longEnemySpells, 1725) -- Distract AddSpell(friendlySpells, 57934) -- Tricks of the Trade elseif class == "WARRIOR" then AddSpell(enemySpells, 5246) -- Intimidating Shout AddSpell(enemySpells, 100) -- Charge AddSpell(longEnemySpells, 355) -- Taunt AddSpell(friendlySpells, 3411) -- Intervene elseif class == "MONK" then AddSpell(enemySpells, 115546) -- Provoke AddSpell(friendlySpells, 115450) -- Detox AddSpell(resSpells, 115178) -- Resuscitate end end local function getUnit(unit) if not unit:find("party") or not unit:find("raid") then for i=1, 4 do if UnitIsUnit(unit, "party"..i) then return "party"..i end end for i=1, 40 do if UnitIsUnit(unit, "raid"..i) then return "raid"..i end end else return unit end end local function friendlyIsInRange(unit) if CheckInteractDistance(unit, 1) then return true end if UnitIsDeadOrGhost(unit) and #resSpells > 0 then for _, name in ipairs(resSpells) do if IsSpellInRange(name, unit) == 1 then return true end end return false end if #friendlySpells == 0 and (UnitInRaid(unit) or UnitInParty(unit)) then unit = getUnit(unit) return unit and UnitInRange(unit) else for _, name in ipairs(friendlySpells) do if IsSpellInRange(name, unit) == 1 then return true end end end return false end local function petIsInRange(unit) if CheckInteractDistance(unit, 2) then return true end for _, name in ipairs(friendlySpells) do if IsSpellInRange(name, unit) == 1 then return true end end for _, name in ipairs(petSpells) do if IsSpellInRange(name, unit) == 1 then return true end end return false end local function enemyIsInRange(unit) for _, name in ipairs(enemySpells) do if IsSpellInRange(name, unit) == 1 then return true end end return false end local function enemyIsInLongRange(unit) for _, name in ipairs(longEnemySpells) do if IsSpellInRange(name, unit) == 1 then return true end end return false end -- updating of range. local timer = 0 local OnRangeUpdate = function(self, elapsed) timer = timer + elapsed if(timer >= .20) then for _, object in next, _FRAMES do if(object:IsShown()) then local range = object.Range local unit = object.unit if(unit) then if UnitCanAttack("player", unit) then if enemyIsInRange(unit) then object:SetAlpha(range.insideAlpha) elseif enemyIsInLongRange(unit) then object:SetAlpha(range.insideAlpha) else object:SetAlpha(range.outsideAlpha) end elseif UnitIsUnit(unit, "pet") then if petIsInRange(unit) then object:SetAlpha(range.insideAlpha) else object:SetAlpha(range.outsideAlpha) end else if friendlyIsInRange(unit) and UnitIsConnected(unit) then object:SetAlpha(range.insideAlpha) else object:SetAlpha(range.outsideAlpha) end end else object:SetAlpha(range.insideAlpha) end end end timer = 0 end end local Enable = function(self) local range = self.Range if(range and range.insideAlpha and range.outsideAlpha) then tinsert(_FRAMES, self) if(not OnRangeFrame) then OnRangeFrame = CreateFrame"Frame" OnRangeFrame:RegisterEvent("LEARNED_SPELL_IN_TAB"); OnRangeFrame:RegisterEvent("PLAYER_ENTERING_WORLD"); OnRangeFrame:SetScript("OnUpdate", OnRangeUpdate) OnRangeFrame:SetScript("OnEvent", UpdateSpellList) end OnRangeFrame:Show() return true end end local Disable = function(self) local range = self.Range if(range) then for k, frame in next, _FRAMES do if(frame == self) then tremove(_FRAMES, k) frame:SetAlpha(1) break end end if(#_FRAMES == 0) then OnRangeFrame:Hide() end end end oUF:AddElement('Range', nil, Enable, Disable)