You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
312 lines
13 KiB
312 lines
13 KiB
--========================================================--
|
|
-- Scorpio UnitFrame Power API --
|
|
-- --
|
|
-- Author : kurapica125@outlook.com --
|
|
-- Create Date : 2021/03/06 --
|
|
--========================================================--
|
|
|
|
--========================================================--
|
|
Scorpio "Scorpio.Secure.UnitFrame.PowerAPI""1.0.0"
|
|
--========================================================--
|
|
|
|
namespace "Scorpio.Secure.UnitFrame"
|
|
|
|
import "System.Reactive"
|
|
import "System.Toolset"
|
|
|
|
------------------------------------------------------------
|
|
-- Unit Power API --
|
|
------------------------------------------------------------
|
|
local _PlayerClass = select(2, UnitClass("player"))
|
|
local _ClassPowerType, _ClassPowerToken, _PrevClassPowerType
|
|
|
|
local _ClassPowerRefresh = Subject()
|
|
local _ClassPowerSubject = Subject()
|
|
local _ClassPowerMaxSubject = Subject()
|
|
|
|
local SPEC_DEMONHUNTER_VENGENCE = 2
|
|
local SOULFRAGMENT = 203981
|
|
local SOULFRAGMENTNAME
|
|
|
|
local STAGGER = 100 -- DIFF to other class type
|
|
|
|
local FindAuraByName = _G.AuraUtil.FindAuraByName
|
|
local PowerType = _G.Enum.PowerType
|
|
|
|
__Async__()
|
|
OnEnable = OnEnable + function ()
|
|
-- Use the custom unit event to provide the API
|
|
if _PlayerClass == "WARRIOR" then
|
|
|
|
elseif _PlayerClass == "DEATHKNIGHT" then
|
|
_ClassPowerToken = "RUNES"
|
|
_ClassPowerType = PowerType.Runes
|
|
|
|
while true do
|
|
local spec = GetSpecialization()
|
|
Continue(RefreshClassPower)
|
|
NextEvent("PLAYER_SPECIALIZATION_CHANGED")
|
|
end
|
|
|
|
elseif _PlayerClass == "PALADIN" and Scorpio.IsRetail then
|
|
_ClassPowerToken = "HOLY_POWER"
|
|
|
|
local level = UnitLevel("player")
|
|
while level < PALADINPOWERBAR_SHOW_LEVEL do
|
|
level = NextEvent("PLAYER_LEVEL_UP")
|
|
end
|
|
_ClassPowerType = PowerType.HolyPower
|
|
|
|
elseif _PlayerClass == "MONK" then
|
|
_ClassPowerToken = "CHI"
|
|
|
|
while true do
|
|
local spec = GetSpecialization()
|
|
_ClassPowerType = spec == SPEC_MONK_WINDWALKER and PowerType.Chi or spec == SPEC_MONK_BREWMASTER and STAGGER or nil
|
|
Continue(RefreshClassPower)
|
|
NextEvent("PLAYER_SPECIALIZATION_CHANGED")
|
|
end
|
|
|
|
elseif _PlayerClass == "PRIEST" and Scorpio.IsRetail then
|
|
_ClassPowerToken = "MANA"
|
|
|
|
while true do
|
|
_ClassPowerType = GetSpecialization() == SPEC_PRIEST_SHADOW and PowerType.Mana or nil
|
|
Continue(RefreshClassPower)
|
|
NextEvent("PLAYER_SPECIALIZATION_CHANGED")
|
|
end
|
|
|
|
elseif _PlayerClass == "SHAMAN" and Scorpio.IsRetail then
|
|
_ClassPowerToken = "MANA"
|
|
|
|
while true do
|
|
_ClassPowerType = GetSpecialization() ~= SPEC_SHAMAN_RESTORATION and PowerType.Mana or nil
|
|
Continue(RefreshClassPower)
|
|
NextEvent("PLAYER_SPECIALIZATION_CHANGED")
|
|
end
|
|
|
|
elseif _PlayerClass == "DRUID" then
|
|
_ClassPowerToken = "COMBO_POINTS"
|
|
|
|
while true do
|
|
_ClassPowerType = GetShapeshiftFormID() == CAT_FORM and PowerType.ComboPoints or nil
|
|
Continue(RefreshClassPower)
|
|
NextEvent("UPDATE_SHAPESHIFT_FORM")
|
|
end
|
|
|
|
elseif _PlayerClass == "ROGUE" then
|
|
_ClassPowerToken = "COMBO_POINTS"
|
|
_ClassPowerType = PowerType.ComboPoints
|
|
|
|
elseif _PlayerClass == "MAGE" and Scorpio.IsRetail then
|
|
_ClassPowerToken = "ARCANE_CHARGES"
|
|
|
|
while true do
|
|
_ClassPowerType = GetSpecialization() == SPEC_MAGE_ARCANE and PowerType.ArcaneCharges or nil
|
|
Continue(RefreshClassPower)
|
|
NextEvent("PLAYER_SPECIALIZATION_CHANGED")
|
|
end
|
|
|
|
elseif _PlayerClass == "WARLOCK" and Scorpio.IsRetail then
|
|
_ClassPowerToken = "SOUL_SHARDS"
|
|
_ClassPowerType = PowerType.SoulShards
|
|
|
|
elseif _PlayerClass == "HUNTER" then
|
|
|
|
elseif _PlayerClass == "DEMONHUNTER" then
|
|
SOULFRAGMENTNAME = GetSpellInfo(SOULFRAGMENT)
|
|
_ClassPowerToken = "DEMONHUNTER"
|
|
|
|
while true do
|
|
_ClassPowerType = GetSpecialization() == SPEC_DEMONHUNTER_VENGENCE and SOULFRAGMENT or nil
|
|
Continue(RefreshClassPower)
|
|
NextEvent("PLAYER_SPECIALIZATION_CHANGED")
|
|
end
|
|
|
|
end
|
|
|
|
return RefreshClassPower()
|
|
end
|
|
|
|
function RefreshClassPower()
|
|
if _ClassPowerType then
|
|
if _PrevClassPowerType ~= _ClassPowerType then
|
|
if _PrevClassPowerType then
|
|
_ClassPowerSubject:Unsubscribe()
|
|
_ClassPowerMaxSubject:Unsubscribe()
|
|
end
|
|
|
|
_PrevClassPowerType = _ClassPowerType
|
|
|
|
-- Binding the real event source
|
|
_ClassPowerSubject:Resubscribe()
|
|
_ClassPowerMaxSubject:Resubscribe()
|
|
|
|
if _ClassPowerType == SOULFRAGMENT then
|
|
-- Use aura to track, keep using Next() for throttling
|
|
Wow.FromEvent("UNIT_AURA"):MatchUnit("player"):Subscribe(_ClassPowerSubject)
|
|
elseif _ClassPowerType == STAGGER then
|
|
Wow.FromEvent("UNIT_HEALTH"):MatchUnit("player"):Subscribe(_ClassPowerSubject)
|
|
Wow.FromEvent("UNIT_MAXHEALTH"):MatchUnit("player"):Subscribe(_ClassPowerMaxSubject)
|
|
elseif _ClassPowerType == PowerType.Runes then
|
|
Wow.FromEvent("RUNE_POWER_UPDATE"):Map("=>'player'"):Subscribe(_ClassPowerSubject)
|
|
else
|
|
Wow.FromEvent("UNIT_POWER_FREQUENT"):MatchUnit("player"):Subscribe(_ClassPowerSubject)
|
|
Wow.FromEvent("UNIT_MAXPOWER"):MatchUnit("player"):Subscribe(_ClassPowerMaxSubject)
|
|
end
|
|
end
|
|
else
|
|
_PrevClassPowerType = false
|
|
_ClassPowerSubject:Unsubscribe()
|
|
_ClassPowerMaxSubject:Unsubscribe()
|
|
end
|
|
|
|
-- Publish the changes
|
|
_ClassPowerRefresh:OnNext("any") -- For all, but other unit's indicator will be disabled and hide
|
|
_ClassPowerSubject:OnNext("player") -- For player only
|
|
_ClassPowerMaxSubject:OnNext("player")
|
|
end
|
|
|
|
__Static__() __AutoCache__()
|
|
function Wow.ClassPower()
|
|
if _PlayerClass == "DEATHKNIGHT" then
|
|
-- A simple total rune as basic features
|
|
return Wow.FromUnitEvent(_ClassPowerSubject):Next():Map(function(unit) local count = 0 for i = 1, 6 do local _, _, ready = GetRuneCooldown(i) if ready then count = count + 1 end end return count end)
|
|
elseif _PlayerClass == "DEMONHUNTER" then
|
|
return Wow.FromUnitEvent(_ClassPowerSubject):Next():Map(function(unit) return _ClassPowerType and min((select(3, FindAuraByName(SOULFRAGMENTNAME, "player", "PLAYER|HELPFUL"))) or 0, 5) or 0 end)
|
|
elseif _PlayerClass == "MONK" then
|
|
return Wow.FromUnitEvent(_ClassPowerSubject):Next():Map(function(unit) return (_ClassPowerType == STAGGER and UnitStagger(unit) or _ClassPowerType and UnitPower(unit, _ClassPowerType)) or 0 end)
|
|
else
|
|
return Wow.FromUnitEvent(_ClassPowerSubject):Next():Map(function(unit) return _ClassPowerType and UnitPower(unit, _ClassPowerType) or 0 end)
|
|
end
|
|
end
|
|
|
|
__Static__() __AutoCache__()
|
|
function Wow.ClassPowerMax()
|
|
local minMax = { min = 0 }
|
|
if _PlayerClass == "DEATHKNIGHT" then
|
|
minMax.max = 6
|
|
return Wow.FromUnitEvent(_ClassPowerMaxSubject):Map(function(unit)
|
|
return minMax
|
|
end)
|
|
elseif _PlayerClass == "DEMONHUNTER" then
|
|
minMax.max = 5
|
|
-- Only track max 5 soul fragment
|
|
return Wow.FromUnitEvent(_ClassPowerMaxSubject):Map(function(unit)
|
|
return minMax
|
|
end)
|
|
elseif _PlayerClass == "MONK" then
|
|
return Wow.FromUnitEvent(_ClassPowerMaxSubject):Map(function(unit)
|
|
minMax.max = _ClassPowerType == STAGGER and UnitHealthMax(unit) or _ClassPowerType and UnitPowerMax(unit, _ClassPowerType) or 100
|
|
return minMax
|
|
end)
|
|
else
|
|
return Wow.FromUnitEvent(_ClassPowerMaxSubject):Map(function(unit)
|
|
minMax.max = _ClassPowerType and UnitPowerMax(unit, _ClassPowerType) or 100
|
|
return minMax
|
|
end)
|
|
end
|
|
end
|
|
|
|
__Static__() __AutoCache__()
|
|
function Wow.ClassPowerColor()
|
|
if _PlayerClass == "MONK" then
|
|
local STAGGER_YELLOW_TRANSITION = _G.STAGGER_YELLOW_TRANSITION
|
|
local STAGGER_RED_TRANSITION = _G.STAGGER_RED_TRANSITION
|
|
|
|
return Wow.FromUnitEvent(_ClassPowerSubject):Map(function(unit)
|
|
if _ClassPowerType and UnitIsUnit(unit, "player") then
|
|
if _ClassPowerType == STAGGER then
|
|
local curr = UnitStagger(unit)
|
|
local maxs = UnitHealthMax(unit)
|
|
if curr and maxs then
|
|
local pct = curr / max
|
|
|
|
if (pct >= STAGGER_RED_TRANSITION) then
|
|
return Color.RED
|
|
elseif (pct >= STAGGER_YELLOW_TRANSITION) then
|
|
return Color.YELLOW
|
|
else
|
|
return Color.GREEN
|
|
end
|
|
end
|
|
else
|
|
return Color[_ClassPowerToken]
|
|
end
|
|
end
|
|
|
|
return Color.DISABLED
|
|
end)
|
|
else
|
|
return Wow.FromUnitEvent(_ClassPowerRefresh):Map(function(unit)
|
|
return UnitIsUnit(unit, "player") and _ClassPowerType and Color[_ClassPowerToken] or Color.DISABLED
|
|
end)
|
|
end
|
|
end
|
|
|
|
__Static__() __AutoCache__()
|
|
function Wow.ClassPowerUsable()
|
|
return Wow.FromUnitEvent(_ClassPowerRefresh):Map(function(unit) return UnitIsUnit(unit, "player") and _ClassPowerType and true or false end)
|
|
end
|
|
|
|
__Static__() __AutoCache__()
|
|
function Wow.UnitPower(frequent)
|
|
return Wow.FromUnitEvent(frequent and "UNIT_POWER_FREQUENT" or "UNIT_POWER_UPDATE", "UNIT_MAXPOWER", "UNIT_DISPLAYPOWER", "UNIT_POWER_BAR_SHOW", "UNIT_POWER_BAR_HIDE")
|
|
:Next():Map(function(unit) return UnitPower(unit, (UnitPowerType(unit))) end)
|
|
end
|
|
|
|
__Static__() __AutoCache__()
|
|
function Wow.UnitPowerMax()
|
|
local minMax = { min = 0 }
|
|
return Wow.FromUnitEvent("UNIT_MAXPOWER", "UNIT_DISPLAYPOWER", "UNIT_POWER_BAR_SHOW", "UNIT_POWER_BAR_HIDE")
|
|
:Map(function(unit) minMax.max = UnitPowerMax(unit, (UnitPowerType(unit))) return minMax end)
|
|
end
|
|
|
|
__Static__() __AutoCache__()
|
|
function Wow.UnitPowerColor()
|
|
local scolor = Color(1, 1, 1)
|
|
return Wow.FromUnitEvent("UNIT_CONNECTION", "UNIT_DISPLAYPOWER", "UNIT_POWER_BAR_SHOW", "UNIT_POWER_BAR_HIDE")
|
|
:Map(function(unit)
|
|
if not UnitIsConnected(unit) then
|
|
scolor.r = 0.5
|
|
scolor.g = 0.5
|
|
scolor.b = 0.5
|
|
else
|
|
local ptype, ptoken, r, g, b = UnitPowerType(unit)
|
|
local color = ptoken and Color[ptoken]
|
|
if color then return color end
|
|
|
|
if r then
|
|
scolor.r = r
|
|
scolor.g = g
|
|
scolor.b = b
|
|
else
|
|
return Color.MANA
|
|
end
|
|
end
|
|
|
|
return scolor
|
|
end)
|
|
end
|
|
|
|
__Static__() __AutoCache__()
|
|
function Wow.UnitMana()
|
|
local MANA = _G.Enum.PowerType.Mana
|
|
return Wow.FromUnitEvent("UNIT_POWER_UPDATE", "UNIT_MAXPOWER", "UNIT_DISPLAYPOWER", "UNIT_POWER_BAR_SHOW", "UNIT_POWER_BAR_HIDE")
|
|
:Map(function(unit) return UnitPower(unit, MANA) end)
|
|
end
|
|
|
|
__Static__() __AutoCache__()
|
|
function Wow.UnitManaMax()
|
|
local MANA = _G.Enum.PowerType.Mana
|
|
local minMax = { min = 0 }
|
|
return Wow.FromUnitEvent("UNIT_MAXPOWER", "UNIT_DISPLAYPOWER", "UNIT_POWER_BAR_SHOW", "UNIT_POWER_BAR_HIDE")
|
|
:Map(function(unit) minMax.max = UnitPowerMax(unit, MANA) return minMax end)
|
|
end
|
|
|
|
__Static__() __AutoCache__()
|
|
function Wow.UnitManaVisible()
|
|
local MANA = _G.Enum.PowerType.Mana
|
|
return Wow.FromUnitEvent("UNIT_MAXPOWER", "UNIT_DISPLAYPOWER", "UNIT_POWER_BAR_SHOW", "UNIT_POWER_BAR_HIDE")
|
|
:Map(function(unit) return UnitPowerType(unit) ~= MANA and (UnitPowerMax(unit, MANA) or 0) > 0 end)
|
|
end
|
|
|