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.

854 lines
34 KiB

5 years ago
--========================================================--
-- Scorpio UnitFrame Indicator --
-- --
-- Author : kurapica125@outlook.com --
-- Create Date : 2020/11/25 --
--========================================================--
--========================================================--
Scorpio "Scorpio.Secure.UnitFrame.Indicator" "1.0.0"
--========================================================--
namespace "Scorpio.Secure.UnitFrame"
------------------------------------------------------------
-- Indicator --
------------------------------------------------------------
__ChildProperty__(UnitFrame, "NameLabel")
__ChildProperty__(InSecureUnitFrame, "NameLabel")
__Sealed__() class "NameLabel" { FontString }
__ChildProperty__(UnitFrame, "LevelLabel")
__ChildProperty__(InSecureUnitFrame, "LevelLabel")
__Sealed__() class "LevelLabel" { FontString }
__ChildProperty__(UnitFrame, "HealthLabel")
__ChildProperty__(InSecureUnitFrame, "HealthLabel")
__Sealed__() class "HealthLabel" { FontString }
__ChildProperty__(UnitFrame, "PowerLabel")
__ChildProperty__(InSecureUnitFrame, "PowerLabel")
__Sealed__() class "PowerLabel" { FontString }
__ChildProperty__(UnitFrame, "HealthBar")
__ChildProperty__(InSecureUnitFrame, "HealthBar")
__Sealed__() class "HealthBar" { StatusBar }
__ChildProperty__(UnitFrame, "PowerBar")
__ChildProperty__(InSecureUnitFrame, "PowerBar")
__Sealed__() class "PowerBar" { StatusBar }
__ChildProperty__(UnitFrame, "ClassPowerBar")
__ChildProperty__(InSecureUnitFrame, "ClassPowerBar")
__Sealed__() class "ClassPowerBar" { StatusBar }
__ChildProperty__(UnitFrame, "HiddenManaBar")
__ChildProperty__(InSecureUnitFrame, "HiddenManaBar")
__Sealed__() class "HiddenManaBar" { StatusBar }
__ChildProperty__(UnitFrame, "DisconnectIcon")
__ChildProperty__(InSecureUnitFrame, "DisconnectIcon")
__Sealed__() class "DisconnectIcon" { Texture }
__ChildProperty__(UnitFrame, "CombatIcon")
__ChildProperty__(InSecureUnitFrame, "CombatIcon")
__Sealed__() class "CombatIcon" { Texture }
__ChildProperty__(UnitFrame, "ResurrectIcon")
__ChildProperty__(InSecureUnitFrame, "ResurrectIcon")
__Sealed__() class "ResurrectIcon" { Texture }
__ChildProperty__(UnitFrame, "RaidTargetIcon")
__ChildProperty__(InSecureUnitFrame, "RaidTargetIcon")
__Sealed__() class "RaidTargetIcon" { Texture }
__ChildProperty__(UnitFrame, "ReadyCheckIcon")
__ChildProperty__(InSecureUnitFrame, "ReadyCheckIcon")
__Sealed__() class "ReadyCheckIcon" { Texture }
__ChildProperty__(UnitFrame, "RaidRosterIcon")
__ChildProperty__(InSecureUnitFrame, "RaidRosterIcon")
__Sealed__() class "RaidRosterIcon" { Texture }
__ChildProperty__(UnitFrame, "RoleIcon")
__ChildProperty__(InSecureUnitFrame, "RoleIcon")
__Sealed__() class "RoleIcon" { Texture }
__ChildProperty__(UnitFrame, "LeaderIcon")
__ChildProperty__(InSecureUnitFrame, "LeaderIcon")
__Sealed__() class "LeaderIcon" { Texture }
__ChildProperty__(UnitFrame, "CastBar")
__ChildProperty__(InSecureUnitFrame, "CastBar")
__Sealed__() class "CastBar" { CooldownStatusBar }
__ChildProperty__(UnitFrame, "AuraPanel")
__ChildProperty__(InSecureUnitFrame,"AuraPanel")
__Sealed__() class "AuraPanel" (function(_ENV)
inherit "ElementPanel"
import "System.Reactive"
local tconcat = table.concat
local tinsert = table.insert
local wipe = wipe
local strtrim = Toolset.trim
local validate = Enum.ValidateValue
local shareCooldown = { start = 0, duration = 0 }
local cache = {}
local function refreshAura(self, unit, filter, eleIdx, auraIdx, name, icon, count, dtype, duration, expires, caster, isStealable, nameplateShowPersonal, spellID, canApplyAura, isBossDebuff, castByPlayer, ...)
if not name or eleIdx > self.MaxCount then return eleIdx end
if not self.CustomFilter or self.CustomFilter(name, icon, count, dtype, duration, expires, caster, isStealable, nameplateShowPersonal, spellID, canApplyAura, isBossDebuff, castByPlayer, ...) then
self.Elements[eleIdx]:Show()
shareCooldown.start = expires - duration
shareCooldown.duration = duration
self.AuraIndex[eleIdx] = auraIdx
self.AuraName[eleIdx] = name
self.AuraIcon[eleIdx] = icon
self.AuraCount[eleIdx] = count
self.AuraDebuff[eleIdx] = dtype
self.AuraCooldown[eleIdx] = shareCooldown
self.AuraStealable[eleIdx] = isStealable and not UnitIsUnit(unit, "player")
self.AuraSpellID[eleIdx] = spellID
self.AuraBossDebuff[eleIdx] = isBossDebuff
self.AuraCastByPlayer[eleIdx] = castByPlayer
eleIdx = eleIdx + 1
end
auraIdx = auraIdx + 1
return refreshAura(self, unit, filter, eleIdx, auraIdx, UnitAura(unit, auraIdx, filter))
end
local function refreshAuraByPriorty(self, unit, filter, priority, auraIdx, name, icon, count, dtype, duration, expires, caster, isStealable, nameplateShowPersonal, spellID, canApplyAura, isBossDebuff, castByPlayer, ...)
if not name then return end
if not self.CustomFilter or self.CustomFilter(name, icon, count, dtype, duration, expires, caster, isStealable, nameplateShowPersonal, spellID, canApplyAura, isBossDebuff, castByPlayer, ...) then
local order = priority[name] or priority[spellID]
if order then
cache[order] = auraIdx
else
tinsert(cache, auraIdx)
end
end
auraIdx = auraIdx + 1
return refreshAuraByPriorty(self, unit, filter, priority, auraIdx, UnitAura(unit, auraIdx, filter))
end
local function OnElementCreated(self, ele)
return ele:InstantApplyStyle()
end
--- The aura filters
__Sealed__() enum "AuraFilter" { "HELPFUL", "HARMFUL", "PLAYER", "RAID", "CANCELABLE", "NOT_CANCELABLE", "INCLUDE_NAME_PLATE_ONLY" }
------------------------------------------------------
-- Property
------------------------------------------------------
--- The aura filter
property "AuraFilter" {
type = struct{ AuraFilter } + String,
field = "__AuraPanel_AuraFilter",
set = function(self, filter)
-- No more check, just keep it simple
if type(filter) == "table" then
filter = tconcat(filter, "|")
else
filter = filter and strtrim(filter) or ""
end
if filter == "" then
self.Count = 0
end
self.__AuraPanel_AuraFilter = filter
end,
}
--- The custom filter
property "CustomFilter" { type = Function }
--- The aura priority with order
property "AuraPriority" { type = struct { String + Number }, handler = function(self, val) self._AuraPriorityCache = {} if val then for i, v in ipairs(val) do self._AuraPriorityCache[v] = i end end end }
--- The property to drive the refreshing
property "Refresh" {
set = function(self, unit)
self.Unit = unit
local filter = self.AuraFilter
if not filter or filter == "" then return end
local auraPriority = self.AuraPriority
if not auraPriority or #auraPriority == 0 then
self.Count = refreshAura(self, unit, filter, 1, 1, UnitAura(unit, 1, filter)) - 1
else
wipe(cache) for i = 1, #auraPriority do cache[i] = false end
refreshAuraByPriorty(self, unit, filter, self._AuraPriorityCache, 1, UnitAura(unit, 1, filter))
local eleIdx = 1
for i = 1, #cache do
local aIdx = cache[i]
if aIdx then
local name, icon, count, dtype, duration, expires, caster, isStealable, nameplateShowPersonal, spellID, canApplyAura, isBossDebuff, castByPlayer = UnitAura(unit, aIdx, filter)
self.Elements[eleIdx]:Show()
shareCooldown.start = expires - duration
shareCooldown.duration = duration
self.AuraIndex[eleIdx] = aIdx
self.AuraName[eleIdx] = name
self.AuraIcon[eleIdx] = icon
self.AuraCount[eleIdx] = count
self.AuraDebuff[eleIdx] = dtype
self.AuraCooldown[eleIdx] = shareCooldown
self.AuraStealable[eleIdx] = isStealable and not UnitIsUnit(unit, "player")
self.AuraSpellID[eleIdx] = spellID
self.AuraBossDebuff[eleIdx] = isBossDebuff
self.AuraCastByPlayer[eleIdx] = castByPlayer
eleIdx = eleIdx + 1
if eleIdx > self.MaxCount then break end
end
end
self.Count = eleIdx - 1
end
end
}
--- The unit of the current aura
property "Unit" { type = String }
------------------------------------------------------
-- Observable Property
------------------------------------------------------
__Indexer__() __Observable__()
property "AuraIndex" { set = Toolset.fakefunc }
__Indexer__() __Observable__()
property "AuraName" { set = Toolset.fakefunc }
__Indexer__() __Observable__()
property "AuraIcon" { set = Toolset.fakefunc }
__Indexer__() __Observable__()
property "AuraCount" { set = Toolset.fakefunc }
__Indexer__() __Observable__()
property "AuraDebuff" { set = Toolset.fakefunc }
__Indexer__() __Observable__()
property "AuraCooldown" { set = Toolset.fakefunc }
__Indexer__() __Observable__()
property "AuraStealable" { set = Toolset.fakefunc }
__Indexer__() __Observable__()
property "AuraSpellID" { set = Toolset.fakefunc }
__Indexer__() __Observable__()
property "AuraBossDebuff" { set = Toolset.fakefunc }
__Indexer__() __Observable__()
property "AuraCastByPlayer" { set = Toolset.fakefunc }
------------------------------------------------------
-- Constructor
------------------------------------------------------
function __ctor(self)
self.OnElementCreated = self.OnElementCreated + OnElementCreated
end
end)
__ChildProperty__(UnitFrame, "BuffPanel")
__ChildProperty__(InSecureUnitFrame, "BuffPanel")
__Sealed__() class "BuffPanel" { AuraPanel }
__ChildProperty__(UnitFrame, "DebuffPanel")
__ChildProperty__(InSecureUnitFrame, "DebuffPanel")
__Sealed__() class "DebuffPanel" { AuraPanel }
__ChildProperty__(UnitFrame, "ClassBuffPanel")
__ChildProperty__(InSecureUnitFrame, "ClassBuffPanel")
__Sealed__() class "ClassBuffPanel" { AuraPanel }
__Sealed__() class "AuraPanelIcon" (function(_ENV)
inherit "Frame"
local isObjectType = Class.IsObjectType
local function OnEnter(self)
if self.ShowTooltip and self.AuraIndex then
local parent = self:GetParent()
if not parent then return end
GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT')
GameTooltip:SetUnitAura(parent.Unit, self.AuraIndex, parent.AuraFilter)
end
end
local function OnLeave(self)
GameTooltip:Hide()
end
property "ShowTooltip" { type = Boolean, default = true }
property "AuraIndex" { type = Number }
function __ctor(self)
self.OnEnter = self.OnEnter + OnEnter
self.OnLeave = self.OnLeave + OnLeave
end
end)
__ChildProperty__(UnitFrame, "TotemPanel")
__ChildProperty__(InSecureUnitFrame,"TotemPanel")
__Sealed__() class "TotemPanel" (function(_ENV)
inherit "ElementPanel"
import "System.Reactive"
local MAX_TOTEMS = _G.MAX_TOTEMS
local SLOT_MAP = {}
for slot, index in ipairs(select(2, UnitClass("player")) == "SHAMAN" and _G.SHAMAN_TOTEM_PRIORITIES or _G.STANDARD_TOTEM_PRIORITIES) do
SLOT_MAP[index] = slot
end
local shareCooldown = { start = 0, duration = 0 }
local function OnElementCreated(self, ele)
return ele:InstantApplyStyle()
end
------------------------------------------------------
-- Property
------------------------------------------------------
property "Refresh" {
set = function(self, unit)
local eleIdx = 1
for i = 1, MAX_TOTEMS do
local haveTotem, name, startTime, duration, icon = GetTotemInfo(SLOT_MAP[i])
if haveTotem then
local ele = self.Elements[eleIdx]
if not ele then return end
ele:Show()
ele.Slot = SLOT_MAP[i]
shareCooldown.start = startTime
shareCooldown.duration = duration
self.TotemName[eleIdx] = name
self.TotemIcon[eleIdx] = icon
self.TotemCooldown[eleIdx] = shareCooldown
eleIdx = eleIdx + 1
end
end
self.Count = eleIdx - 1
end
}
------------------------------------------------------
-- Observable Property
------------------------------------------------------
__Indexer__() __Observable__()
property "TotemName" { set = Toolset.fakefunc }
__Indexer__() __Observable__()
property "TotemIcon" { set = Toolset.fakefunc }
__Indexer__() __Observable__()
property "TotemCooldown" { set = Toolset.fakefunc }
------------------------------------------------------
-- Constructor
------------------------------------------------------
function __ctor(self)
self.OnElementCreated = self.OnElementCreated + OnElementCreated
end
end)
__Sealed__() class "TotemPanelIcon" (function(_ENV)
inherit "Frame"
local function OnEnter(self)
if self.ShowTooltip then
GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT')
GameTooltip:SetTotem(self.Slot)
end
end
local function OnLeave(self)
GameTooltip:Hide()
end
property "Slot" { type = Number }
property "ShowTooltip" { type = Boolean, default = true }
function __ctor(self)
self.OnEnter = self.OnEnter + OnEnter
self.OnLeave = self.OnLeave + OnLeave
end
end)
-- A health bar with prediction elements
__ChildProperty__(UnitFrame, "PredictionHealthBar")
__ChildProperty__(InSecureUnitFrame,"PredictionHealthBar")
__Sealed__() class "PredictionHealthBar" (function(_ENV)
inherit "StatusBar"
local function updateFillBar(self, previousTexture, bar, amount, barOffsetXPercent)
local totalWidth, totalHeight = self:GetSize()
if ( totalWidth == 0 or amount == 0 ) then
bar:Hide()
if ( bar.overlay ) then
bar.overlay:Hide()
end
return previousTexture
end
local barOffsetX = 0
if ( barOffsetXPercent ) then
barOffsetX = totalWidth * barOffsetXPercent
end
bar:ClearAllPoints()
bar:SetPoint("TOPLEFT", previousTexture, "TOPRIGHT", barOffsetX, 0)
bar:SetPoint("BOTTOMLEFT", previousTexture, "BOTTOMRIGHT", barOffsetX, 0)
local _, totalMax = self:GetMinMaxValues()
local barSize = (amount / totalMax) * totalWidth
bar:SetWidth(barSize)
bar:Show()
if ( bar.overlay ) then
bar.overlay:SetTexCoord(0, Clamp(barSize / bar.overlay.tileSize, 0, 1), 0, Clamp(totalHeight / bar.overlay.tileSize, 0, 1))
bar.overlay:Show()
end
return bar
end
property "HealPrediction" {
set = function(self, unit)
local maxHealth = unit and UnitHealthMax(unit) or 0
if maxHealth <= 0 then
self.myHealPrediction:Hide()
self.otherHealPrediction:Hide()
self.totalAbsorb:Hide()
self.totalAbsorbOverlay:Hide()
self.myHealAbsorb:Hide()
self.myHealAbsorbLeftShadow:Hide()
self.overAbsorbGlow:Hide()
self.overHealAbsorbGlow:Hide()
return
end
local health = unit and UnitHealth(unit)
local myIncomingHeal = UnitGetIncomingHeals(unit, "player") or 0
local allIncomingHeal = UnitGetIncomingHeals(unit) or 0
local totalAbsorb = UnitGetTotalAbsorbs(unit) or 0
local totalHealAbsorb = UnitGetTotalHealAbsorbs(unit) or 0
local otherIncomingHeal = 0
local overHealAbsorb = false
local overAbsorb = false
if health < totalHealAbsorb then
totalHealAbsorb = health
overHealAbsorb = true
end
if health - totalHealAbsorb + allIncomingHeal > maxHealth * self.MaxHealOverflowRatio then
allIncomingHeal = maxHealth * self.MaxHealOverflowRatio - health + totalHealAbsorb
end
--Split up incoming heals.
if allIncomingHeal >= myIncomingHeal then
otherIncomingHeal = allIncomingHeal - myIncomingHeal
else
myIncomingHeal = allIncomingHeal
end
if health - totalHealAbsorb + allIncomingHeal + totalAbsorb >= maxHealth or health + totalAbsorb >= maxHealth then
overAbsorb = totalAbsorb > 0
if allIncomingHeal > totalHealAbsorb then
totalAbsorb = max(0, maxHealth - (health - totalHealAbsorb + allIncomingHeal))
else
totalAbsorb = max(0, maxHealth - health)
end
end
self.overHealAbsorbGlow:SetShown(overHealAbsorb)
self.overAbsorbGlow:SetShown(overAbsorb)
local healthTexture = self:GetStatusBarTexture()
local totalHealAbsorbPct = totalHealAbsorb / maxHealth
local healAbsorbTexture = nil
if totalHealAbsorb > allIncomingHeal then
local shownHealAbsorb = totalHealAbsorb - allIncomingHeal
local shownHealAbsorbPercent= shownHealAbsorb / maxHealth
healAbsorbTexture = updateFillBar(self, healthTexture, self.myHealAbsorb, shownHealAbsorb, -shownHealAbsorbPercent)
--If there are incoming heals the left shadow would be overlayed by the incoming heals
--so it isn't shown.
if ( allIncomingHeal > 0 ) then
self.myHealAbsorbLeftShadow:Hide()
else
self.myHealAbsorbLeftShadow:ClearAllPoints()
self.myHealAbsorbLeftShadow:SetPoint("TOPLEFT", healAbsorbTexture, "TOPLEFT", 0, 0)
self.myHealAbsorbLeftShadow:SetPoint("BOTTOMLEFT", healAbsorbTexture, "BOTTOMLEFT", 0, 0)
self.myHealAbsorbLeftShadow:Show()
end
-- The right shadow is only shown if there are absorbs on the health bar.
if ( totalAbsorb > 0 ) then
self.myHealAbsorbRightShadow:ClearAllPoints()
self.myHealAbsorbRightShadow:SetPoint("TOPLEFT", healAbsorbTexture, "TOPRIGHT", -8, 0)
self.myHealAbsorbRightShadow:SetPoint("BOTTOMLEFT", healAbsorbTexture, "BOTTOMRIGHT", -8, 0)
self.myHealAbsorbRightShadow:Show()
else
self.myHealAbsorbRightShadow:Hide()
end
else
self.myHealAbsorb:Hide()
self.myHealAbsorbRightShadow:Hide()
self.myHealAbsorbLeftShadow:Hide()
end
--Show myIncomingHeal on the health bar.
local incomingHealsTexture = updateFillBar(self, healthTexture, self.myHealPrediction, myIncomingHeal, -totalHealAbsorbPct)
--Append otherIncomingHeal on the health bar.
incomingHealsTexture = updateFillBar(self, incomingHealsTexture, self.otherHealPrediction, otherIncomingHeal)
--Appen absorbs to the correct section of the health bar.
local appendTexture = nil
if ( healAbsorbTexture ) then
--If there is a healAbsorb part shown, append the absorb to the end of that.
appendTexture = healAbsorbTexture
else
--Otherwise, append the absorb to the end of the the incomingHeals part
appendTexture = incomingHealsTexture
end
updateFillBar(self, appendTexture, self.totalAbsorb, totalAbsorb)
end
}
property "MaxHealOverflowRatio" { type = Number, default = 1.00 }
__Template__{
MyHealPrediction = Texture,
OtherHealPrediction = Texture,
TotalAbsorb = Texture,
TotalAbsorbOverlay = Texture,
MyHealAbsorb = Texture,
MyHealAbsorbLeftShadow = Texture,
MyHealAbsorbRightShadow = Texture,
OverAbsorbGlow = Texture,
OverHealAbsorbGlow = Texture,
}
function __ctor(self)
self.myHealPrediction = self:GetChild("MyHealPrediction")
self.otherHealPrediction= self:GetChild("OtherHealPrediction")
self.totalAbsorb = self:GetChild("TotalAbsorb")
self.totalAbsorbOverlay = self:GetChild("TotalAbsorbOverlay")
self.myHealAbsorb = self:GetChild("MyHealAbsorb")
self.myHealAbsorbLeftShadow = self:GetChild("MyHealAbsorbLeftShadow")
self.myHealAbsorbRightShadow= self:GetChild("MyHealAbsorbRightShadow")
self.overAbsorbGlow = self:GetChild("OverAbsorbGlow")
self.overHealAbsorbGlow = self:GetChild("OverHealAbsorbGlow")
self.totalAbsorb.overlay = self.totalAbsorbOverlay
self.totalAbsorbOverlay.tileSize = 32
end
end)
------------------------------------------------------------
-- Default Style --
------------------------------------------------------------
local shareRect = RectType()
Style.UpdateSkin("Default", {
[NameLabel] = {
drawLayer = "BORDER",
fontObject = GameFontNormalSmall,
text = Wow.UnitName(true),
textColor = Wow.UnitColor(),
},
[LevelLabel] = {
drawLayer = "BORDER",
fontObject = GameFontNormalSmall,
text = Wow.UnitLevel(),
vertexColor = Wow.UnitLevelColor(),
},
[HealthLabel] = {
drawLayer = "BORDER",
fontObject = GameFontNormalSmall,
text = Wow.UnitHealth(),
},
[PowerLabel] = {
drawLayer = "BORDER",
fontObject = GameFontNormalSmall,
text = Wow.UnitPower(),
},
[HealthBar] = {
frameStrata = "LOW",
enableMouse = false,
statusBarTexture = {
file = [[Interface\TargetingFrame\UI-StatusBar]],
},
value = Wow.UnitHealth(),
minMaxValues = Wow.UnitHealthMax(),
statusBarColor = Color.GREEN,
},
[PowerBar] = {
frameStrata = "LOW",
enableMouse = false,
statusBarTexture = {
file = [[Interface\TargetingFrame\UI-StatusBar]],
},
value = Wow.UnitPower(),
minMaxValues = Wow.UnitPowerMax(),
statusBarColor = Wow.UnitPowerColor(),
},
[HiddenManaBar] = {
frameStrata = "LOW",
enableMouse = false,
statusBarTexture = {
file = [[Interface\TargetingFrame\UI-StatusBar]],
},
value = Wow.UnitMana(),
minMaxValues = Wow.UnitManaMax(),
visible = Wow.UnitManaVisible(),
statusBarColor = Color.MANA,
},
[ClassPowerBar] = {
frameStrata = "LOW",
enableMouse = false,
statusBarTexture = {
file = [[Interface\TargetingFrame\UI-StatusBar]],
},
value = Wow.ClassPower(),
minMaxValues = Wow.ClassPowerMax(),
statusBarColor = Wow.ClassPowerColor(),
visible = Wow.ClassPowerUsable(),
},
[DisconnectIcon] = {
file = [[Interface\CharacterFrame\Disconnect-Icon]],
size = Size(16, 16),
visible = Wow.UnitIsDisconnected(),
},
[CombatIcon] = {
file = [[Interface\CharacterFrame\UI-StateIcon]],
texCoords = RectType(.5, 1, 0, .49),
size = Size(24, 24),
visible = Wow.PlayerInCombat(),
},
[ResurrectIcon] = {
file = [[Interface\RaidFrame\Raid-Icon-Rez]],
size = Size(16, 16),
visible = Wow.UnitIsResurrect(),
},
[RaidTargetIcon] = {
file = [[Interface\TargetingFrame\UI-RaidTargetingIcons]],
size = Size(16, 16),
texCoords = Wow.UnitRaidTargetIndex():Map(function(index)
if index then
index = index - 1
local left, right, top, bottom
local cIncr = RAID_TARGET_ICON_DIMENSION / RAID_TARGET_TEXTURE_DIMENSION
left = mod(index , RAID_TARGET_TEXTURE_COLUMNS) * cIncr
right = left + cIncr
top = floor(index / RAID_TARGET_TEXTURE_ROWS) * cIncr
bottom = top + cIncr
shareRect.left = left
shareRect.right = right
shareRect.top = top
shareRect.bottom= bottom
end
return shareRect
end),
visible = Wow.UnitRaidTargetIndex():Map(function(val) return val and true or false end),
},
[ReadyCheckIcon] = {
file = Wow.UnitReadyCheck():Map(function(state)
return state == "ready" and READY_CHECK_READY_TEXTURE
or state == "notready" and READY_CHECK_NOT_READY_TEXTURE
or state == "waiting" and READY_CHECK_WAITING_TEXTURE
or nil
end),
visible = Wow.UnitReadyCheckVisible(),
size = Size(16, 16),
},
[RaidRosterIcon] = {
file = Wow.UnitGroupRoster():Map(function(assign)
return assign == "MAINTANK" and [[Interface\GROUPFRAME\UI-GROUP-MAINTANKICON]]
or assign == "MAINASSIST" and [[Interface\GROUPFRAME\UI-GROUP-MAINASSISTICON]]
or nil
end),
size = Size(16, 16),
},
[RoleIcon] = {
file = [[Interface\LFGFrame\UI-LFG-ICON-PORTRAITROLES]],
texCoords = Wow.UnitRole():Map(function(role)
if role and role ~= "NONE" then
local left, right, top, bottom = GetTexCoordsForRoleSmallCircle(role)
shareRect.left = left
shareRect.right = right
shareRect.top = top
shareRect.bottom= bottom
else
shareRect.left = 0
shareRect.right = 0
shareRect.top = 0
shareRect.bottom= 0
end
return shareRect
end),
size = Size(16, 16),
},
[LeaderIcon] = {
file = [[Interface\GroupFrame\UI-Group-LeaderIcon]],
size = Size(16, 16),
visible = Wow.UnitIsLeader(),
},
[CastBar] = {
cooldown = Wow.UnitCastCooldown(),
reverse = Wow.UnitCastChannel(),
showSafeZone = Wow.UnitIsPlayer(),
},
[AuraPanel] = {
refresh = Wow.UnitAura(),
elementType = AuraPanelIcon,
frameStrata = "MEDIUM",
columnCount = 6,
rowCount = 6,
elementWidth = 16,
elementHeight = 16,
hSpacing = 2,
vSpacing = 2,
enableMouse = false,
},
[BuffPanel] = {
auraFilter = "HELPFUL",
},
[DebuffPanel] = {
auraFilter = "HARMFUL",
},
[ClassBuffPanel] = {
auraFilter = "PLAYER",
},
[AuraPanelIcon] = {
enableMouse = true,
auraIndex = Wow.FromPanelProperty("AuraIndex"),
},
[TotemPanel] = {
refresh = Wow.UnitTotem(),
visible = Wow.UnitIsPlayer(),
elementType = TotemPanelIcon,
frameStrata = "MEDIUM",
columnCount = _G.MAX_TOTEMS,
rowCount = 1,
elementWidth = 16,
elementHeight = 16,
hSpacing = 2,
vSpacing = 2,
enableMouse = false,
},
[TotemPanelIcon] = {
enableMouse = true,
},
[PredictionHealthBar] = {
frameStrata = "LOW",
enableMouse = false,
statusBarColor = Wow.UnitConditionColor(true, Color.RED),
statusBarTexture = {
file = [[Interface\TargetingFrame\UI-StatusBar]],
},
value = Wow.UnitHealthFrequent(),
minMaxValues = Wow.UnitHealthMax(),
healPrediction = Wow.UnitHealPrediction(),
MyHealPrediction = {
drawLayer = "BORDER",
subLevel = 5,
color = Color.WHITE,
gradient = GradientType("VERTICAL", Color(8/255, 93/255, 72/255), Color(11/255, 136/255, 105/255)),
},
OtherHealPrediction = {
drawLayer = "BORDER",
subLevel = 5,
color = Color.WHITE,
gradient = GradientType("VERTICAL", Color(11/255, 53/255, 43/255), Color(21/255, 89/255, 72/255)),
},
TotalAbsorb = {
file = [[Interface\RaidFrame\Shield-Fill]],
drawLayer = "BORDER",
subLevel = 5,
},
TotalAbsorbOverlay = {
file = [[Interface\RaidFrame\Shield-Overlay]],
hWrapMode = "REPEAT",
vWrapMode = "REPEAT",
drawLayer = "BORDER",
subLevel = 6,
},
MyHealAbsorb = {
file = [[Interface\RaidFrame\Absorb-Fill]],
hWrapMode = "REPEAT",
vWrapMode = "REPEAT",
drawLayer = "ARTWORK",
subLevel = 1,
},
MyHealAbsorbLeftShadow = {
file = [[Interface\RaidFrame\Absorb-Edge]],
drawLayer = "ARTWORK",
subLevel = 1,
},
MyHealAbsorbRightShadow = {
file = [[Interface\RaidFrame\Absorb-Edge]],
drawLayer = "ARTWORK",
subLevel = 1,
texCoords = RectType(1, 0, 0, 1),
},
OverAbsorbGlow = {
file = [[Interface\RaidFrame\Shield-Overshield]],
alphaMode = "ADD",
drawLayer = "ARTWORK",
subLevel = 2,
location = { Anchor("BOTTOMLEFT", -7, 0, nil, "BOTTOMRIGHT"), Anchor("TOPLEFT", -7, 0, nil, "TOPRIGHT") },
width = 16,
},
OverHealAbsorbGlow = {
file = [[Interface\RaidFrame\Absorb-Overabsorb]],
alphaMode = "ADD",
drawLayer = "ARTWORK",
subLevel = 2,
location = { Anchor("BOTTOMRIGHT", 7, 0, nil, "BOTTOMLEFT"), Anchor("TOPRIGHT", 7, 0, nil, "TOPLEFT") },
width = 16,
},
},
})