최근 반짝임 효과(spell activation overlay glow)에 대한 질문을 자주 받고 있으므로 참고가 될만한 사항을 적어둡니다.

기본 인터페이스에서 일부 주문은 사용 가능해지거나 강화 효과가 적용될 때 단축버튼에 반짝이는 테두리가 표시됩니다.
이 반짝임 테두리를 적용/제거하는 기능은 간편하게 사용할 수 있도록 API로 구현되어 있어 다양한 애드온에서 기본 인터페이스의 테두리 기능을 빌려씁니다. 예를 들어 ExtraCD는 쿨이 돌아온 장신구 등에 테두리를 표시할 수 있습니다.

WA도 반짝임 효과를 액션으로 제공하나 그 용법이 매우 제한적입니다.

기본 사용법과 이를 이용한 편법을 소개하고 더 강력한 기능 구현을 위해 Lua 코드로 반짝임 효과를 적용하는 기술을 소개하겠습니다.



목차
7-1 : Lua를 사용하지 않는 반짝임 효과
    7-1-1 : 표시되는 동안에만 적용
    7-1-2 : 표시중에 반짝임 적용/숨김
7-2 : Lua를 사용한 반짝임 효과
    7-2-1 : 기본 와우 이벤트를 이용하기
    7-2-2 : WA 커스텀 이벤트를 이용하기





  Ex. 7-1-1 표시되는 동안에만 반짝임 테두리 적용

WA에서 제공하는 반짝임 효과는 '행동' 기능 중 하나로, 표시기가 나타날 때와 사라질 때에 켜거나 끌 수 있습니다.
분노 전사의 피의 갈증 크리 발동에 의해 분노의 강타가 사용 가능해지면 분노의 강타 아이콘을 표시하고 여기에 반짝임 테두리를 둘러봅시다.


아이콘을 하나 만들고 조건 탭에서 
상태 - 사용 가능 - 분노의 강타
분노의 강타가 사용 가능할 때만 표시되는 아이콘 표시기를 만듭니다.

반짝임 테두리는 '행동' 탭에서 설정합니다(최근 Actions가 행동으로 번역되어 낯섭니다).


행동에는 On Init, 보여짐, 숨겨짐의 분류가 있습니다.

On Init은 설정 중에 Lua 코드가 포함된 표시기에서, 로드 후에 처음으로 코드 중 하나가 수행될 때 이에 앞서서 한 번만 시행됩니다(연재글 #5에서 다룬 적이 있습니다).

보여짐 행동은 조건이 만족돼서 표시기가 화면에 표시되는 순간에 수행되며 숨겨짐 행동은 반대로 사라질 때 수행됩니다.

보여짐 행동에는 '버튼 반짝임 - 보이기'를 선택하고 아래의 '선택'이라는 버튼을 누른 다음 게임 화면에 떠있는, 지금 편집중인 분노의 강타 아이콘을 누릅니다. 옆의 텍스트 입력창에는 WeakAuras: 라는 식별부호 뒤에 이 아이콘 표시기의 이름인 Raging Blow가 자동으로 입력됩니다.

숨겨짐 행동에는 '버튼 반짝임 - 숨기기'를 선택하고 역시 편집중인 표시기의 아이콘을 선택합니다.

보시다시피 보여짐/숨겨짐 행동 각각에서 테두리를 표시한 다음 숨기는데 어떤 개체에 반짝임 테두리를 두를 것인지를 선택하도록 되어있습니다. 즉, A라는 표시기에서 B라는 표시기에 테두리를 두를 수도 있고 미니맵이나 채팅창에 테두리를 두르는 것도 가능합니다.

'어짜피 아이콘이 숨겨지면 테두리도 같이 숨겨질 것인데 꼭 숨겨짐 행동을 지정할 필요가 있는가' 의문이 들 수도 있습니다만 보여짐 행동에서 테두리를 두르는 것만 계속 반복하면 아이콘에 하나 이상의 테두리가 덧붙여질 수가 있습니다.
바람직하지 않으므로 매번 끕시다.




  Ex. 7-1-2 표시 중에 반짝임 적용 / 숨김

예제 7-1-1의 방법은 표시기가 나타나 있는 동안은 테두리 효과가 계속 적용되는 방식입니다.
그런데 아이콘 자체는 계속 떠 있으나 특정한 조건에서만 테두리 효과가 적용되도록 설정하고 싶을 때가 많습니다.

예를 들어 쿨다운 추적용으로 '상태 - 쿨다운 진행상황(주문)' 조건을 만든 다음 보이기 조건을 Always로 설정하면 아이콘 자체는 계속 표시되고 디스플레이 탭에서 쿨다운을 체크하면 쿨다운이 진행중일 때에만 시계방향 쿨다운 애니메이션이 표시됩니다.

이런 상황에서는 이 표시기 자체의 행동 기능으로는 쿨이 있을 때만 테두리를 표시하는 기능을 구현할 수 없습니다.


간단한 편법 중 한 가지는 표시기를 두 개 만들어서 Always가 아니라 On Cooldown 과 Not on Cooldown 조건으로 분리하는 것입니다.
두 개 아이콘을 한 자리에 겹쳐 표시하고 이 중 Not on Cooldown 아이콘에는 테두리를 덧붙이면 됩니다.


그런데 이런 방식으로 구현하기 곤란할 때도 있습니다

마무리 일격의 사용 가능 여부에 따라 마격 아이콘이 표시되며 '급살' 효과가 발동되어 공짜 마격이 가능해질 때는 테두리까지 표시하는 기능을 만들어봅시다.



Execute는 '상태 - 사용 가능 - 마무리 일격'으로 만든 아이콘입니다. 마격이 사용 가능할 때 표시됩니다.
이제 여기에, 급살 효과가 발동되면 반짝임 테두리를 두르게 하겠습니다.


Execute Glow라는 텍스트 표시기를 만듭니다. 이 표시기는 조건이 만족되어도 화면에 아무것도 나오지 않게 만들 것입니다. 
이를 위해서는 흔히 텍스트 표시기를 만들고 디스플레이 탭에서 표시할 텍스트 부분에 New를 지우고 스페이스 바를 하나 입력합니다. 표시되어도 빈 칸이 하나 나오겠지요.

조건에서는 '오라 - 급살'로 설정해서 급살 버프가 있을 때만 (빈 칸이) 표시되게 만듭니다.

행동 탭으로 갑니다.


보여짐 / 숨겨짐 행동에 버튼 반짝임 효과를 설정하는데 대상 프레임을 이 텍스트 표시기가 아니라 마격 아이콘으로 지정해야 합니다.
설정창이 열려있을 때에 현재 편집중이 아닌 WA 개체들은 숨겨지므로 텍스트로 입력해야합니다.

위에서 보셨듯 아이콘 표시기의 이름은 'Execute'이므로
WeakAuras:Execute 라고 입력합니다.

대상 생명력이 20% 밑이라 사용 가능하면 그냥 아이콘이 표시되고 급살이 발동하면 두 번째 표시기가 표시되면서 첫 표시기에 테두리까지 표시됩니다.




  Ex. 7-2-1 Lua 코드 + 기본 와우 이벤트 이용

와우 기본 인터페이스에서 행동 단축 버튼에 반짝임 효과가 적용되고 사라지는 것은
"SPELL_ACTIVATION_OVERLAY_GLOW_SHOW"
"SPELL_ACTIVATION_OVERLAY_GLOW_HIDE"
라는 이벤트에 기반해서 동작합니다.

이 이벤트에는 주문 id가 인수로 전달되는데 이 이벤트가 발생하면 와우의 60개 단축 아이콘은 모두 각자 자기 위치에 있는 주문의 주문 id가 이벤트 인수와 일치하는지 체크해서 일치하면 테두리를 두르거나 끕니다.

테두리를 두르거나 끄는 데에는
ActionButton_ShowOverlayGlow(region)
ActionButton_HideOverlayGlow(region)
이라는 API 명령어가 사용됩니다. 괄호 안에 테두리를 적용 / 제거할 프레임 개체를 지정하면 됩니다.


이걸 이용해서 퇴마술 쿨다운 표시기를 만들고 공짜 퇴마술이 발동되어서 기본 행동 버튼에 반짝임이 적용되면 WA 아이콘에도 반짝임 테두리가 적용되게 만들겠습니다.
(공짜 퇴마술이 발동할 때는 아무 버프도 표시되지 않으므로 예제 7-1-2에서 마격에 급살 버프를 추적하는 방식이 불가능합니다. 오직 이 이벤트만 사용할 수 있습니다.)



아이콘을 만들고
'조건 - 쿨다운 진행상황(주문) - 퇴마술 - 보이기(Always)'
로 설정해서 계속 표시되는 퇴마술 쿨다운 추적 아이콘을 세팅합니다.

이제 여기에 반짝임 테두리를 적용하는 코드를 덧붙일 것인데 표시기를 두 개 만들기 귀찮으므로 그냥 조건을 하나 추가합니다.



'아무 조건'으로 설정하고 2번 조건에서는 true를 반환하지 않으면 그냥 '조건 1'만이 표시 여부를 결정하게 됩니다(논리값   P or never = P  이므로).

두 번째 조건은 '개인추가 - 이벤트'로 설정하고 체크할 이벤트로는
SPELL_ACTIVATION_OVERLAY_GLOW_SHOW, SPELL_ACTIVATION_OVERLAY_GLOW_HIDE
두 가지를 넣습니다. 둘 이상의 이벤트를 넣을 때는 중간에 콤마를 넣어도 되고 그냥 띄어쓰기로도 구분됩니다.

개인추가 조건은 다음과 같이 입력합니다.


function(event, spellid)
    if spellid ~= 879 then
        return
    end
    
    local region = WeakAuras.regions[aura_env.id].region

    if event == "SPELL_ACTIVATION_OVERLAY_GLOW_SHOW" then
        ActionButton_ShowOverlayGlow(region)
    else
        ActionButton_HideOverlayGlow(region)
    end
end

위에 말씀드렸듯 SPELL_ACTIVATION_OVERLAY_GLOW_SHOW, SPELL_ACTIVATION_OVERLAY_GLOW_HIDE 이벤트들은 주문 id가 메시지로 전달됩니다.
퇴마술 주문id는 879이며 그 외 이벤트들은 퇴마술과 관련 없으니 무시합니다.

테두리를 두를 아이콘 개체의 프레임을 지정해야 하는데 현재 편집중인 개체의 region은 다음 경로로 접근할 수 있습니다.

WeakAuras.regions[aura_env.id].region

여기에서 aura_env는 현재 개체에 제공되는 고유 데이터 공간(스크래치 테이블이라고들 하던데 저는 프로그래머가 아니라 잘 모르겠습니다)이며 여기에 아무 정보도 저장하지 않아도 id라는 키로 표시기의 이름이 원래부터 들어있습니다.
저는 이 아이콘 표시기 이름을 Execute라고 설정했기 때문에 aura_env.id는 "Execute" 라는 스트링입니다.
위 경로는 WeakAuras.regions.Execute.region 이라고 써서 접근할 수도 있지만 이렇게 하면 표시기 이름을 다른 것으로 바꾸면 에러가 발생하므로 첫 방식을 추천합니다.

프레임 개체의 경로를 획득했으니
- 이벤트가 SHOW 라면 테두리 표시 :: ActionButton_ShowOverlayGlow(region)
- 아니라면 HIDE가 확실하므로 테두리 숨김 :: ActionButton_HideOverlayGlow(region)

이런 식으로, 조건 2는 아이콘의 표시 여부에는 전혀 영향을 주지 않고 단축버튼의 테두리 표시/숨김만을 감지해서 WA 아이콘에도 테두리를 적용하는 코드를 수행하게 됩니다.




  Ex. 7-2-2 Lua 코드 + WA 전용 이벤트 이용

예제 7-2-1의 방식은 기본 인터페이스의 행동 버튼 반짝임 효과를 그대로 복제할 뿐입니다.
다만 ActionButton_ShowOverlayGlow, ActionButton_HideOverlayGlow 명령을 이용하면 언제든 원할 때 테두리 효과를 적용할 수는 있습니다.

그런데, 주문의 쿨다운을 추적하는 것은 의외로 어려운 일이고 여러개 주문의 쿨다운을 추적할 때 각기 이 기능을 따로 구현하려면 상당히 자원이 낭비됩니다.

다행스럽게 WA는 자연히 주문의 쿨다운을 추적할 것인데 이 정보를 빌려쓰는 방식을 하나 더 소개하겠습니다.


WA는 CallbackHandler-1.0 라이브러리 기반으로(CBH가 아니라 자체적으로 코드를 짰네요) 자체적인 이벤트들을 사용하는데 이는 예제 #4의 끄트머리에 소개한 바가 있습니다.
이런 이벤트들은 WeakAuras.ScanEvents("EVENT"[, arg1 [,arg2 ...]]) 형태로 fire 되고 완전히 내부적으로도 사용되지만 개인추가 조건에서 이벤트로 등록해서 내가 원하는 이벤트를 발생 / 추적할 수도 있고 WA가 기존에 사용하는 이벤트를 개인추가 조건에 사용할 수도 있습니다.

WA로 쿨다운 추적 표시기를 사용하는 주문에 대해서는 다음의 이벤트들이 발생합니다.
"SPELL_COOLDOWN_READY", id
"SPELL_COOLDOWN_STARTED", id
"SPELL_COOLDOWN_CHANGED", id

다시 말씀드리지만 위 이벤트들은 WA가 쿨다운을 추적하는 주문에 한해서 발생합니다.
쿨다운 추적용 아이콘을 사용하고 여기에 반짝임 테두리 효과를 덧붙이고 싶다면 물론 이 제약조건은 자연히 해결됩니다.

여러개의 쿨다운 추적 아이콘을 사용할 때, 통합 관제 센터 역할을 하는 한 개의 가짜 표시기로 각각의 아이콘들에 번쩍임 효과를 적용하는 예제를 소개합니다.




각종 쿨다운 기술들의 쿨다운을 추적하는 아이콘을 만들어서 유동적 그룹에 넣어두었습니다.
각각은 모두 '쿨다운 진행상황(주문) - Always'로 설정되어 있습니다.

아이콘들의 이름이 'CD:주문 이름' 형식으로 통일되어 있는 것에 유의하세요.



이제 번쩍임 효과를 관제할 가짜 표시기를 하나 만듭니다. 텍스트 표시기로 만들었습니다.

조건 탭에서
개인추가 - 이벤트 - SPELL_COOLDOWN_READY
로 설정합니다.

개인추가 조건 창에는 다음과 같이 씁니다.

function(event, spellid)
    local name = GetSpellInfo(spellid)
    if not name then return end
    
    local regionName = "CD:" .. name
    local region = WeakAuras.regions[regionName] and WeakAuras.regions[regionName].region
    if region then
        ActionButton_ShowOverlayGlow(region)
        C_Timer.After(2, function()
                ActionButton_HideOverlayGlow(region)
        end)
    end
end

쿨다운 추적 아이콘을 사용하는 여러 가지 주문 중에 하나의 쿨다운이 돌아오면 WA에서 "SPELL_COOLDOWN_READY" 이벤트가 발생하고 첫 메시지로 주문id가 전달될 것입니다.



local name = GetSpellInfo(spellid)
if not name then return end

쿨다운이 돌아온 주문의 주문명을 GetSpellInfo로 얻습니다. 가끔 실제 주문ID가 아닌 메시지가 전달되기도 하므로 주문명이 없다면 트리거를 종료합니다.



local regionName = "CD:" .. name
local region = WeakAuras.regions[regionName] and WeakAuras.regions[regionName].region

테두리를 표시해야할 개체의 id는 'CD:주문명'으로 통일해둔 상태입니다.
스트링 축약을 이용해 "CD:주문명" 형식의 스트링을 만들고 WA 개체 중에 이 이름을 가진 것이 있다면 region이라는 변수에 그 개체를 지정합니다. ( a = b and c 형식에 의해 b가 true라면 a에 c가 지정됩니다. b가 false이면 아무 일도 없고요 )




if region then
    ActionButton_ShowOverlayGlow(region)
    C_Timer.After(2, function()
            ActionButton_HideOverlayGlow(region)
    end)
end

개체가 존재한다면 ActionButton_ShowOverlayGlow(region) 명령으로 해당 개체에 번쩍임 효과를 적용합니다.
그리고 C_Timer.After 명령을 이용해 2초 후에 번쩍임을 제거합니다.

(C_Timer.After는 AceTimer 라이브러리를 안써도 되도록 드군에서 블리자드가 추가한 API입니다. 사용법은
C_Timer.After(delay, callback)
delay는 초 단위 숫자
callback은 함수)


쿨이 돌아온 아이콘에는 2초간 번쩍임 테두리가 표시됩니다.

저는 2초 후에 번쩍임이 사라지게 했으나 원하신다면 트리거 이벤트로 SPELL_COOLDOWN_STARTED까지 두 가지를 등록해서 쿨다운이 돌아오는 이벤트에서 번쩍임이 표시되고 쿨다운이 시작되는 이벤트일 때는 번쩍임이 사라지게 만들 수도 있을 것입니다.


이상.