안녕하세요.
라그나로스 서버에서 게임 중인 흑마법사 유저 Apoptosis 입니다.

저 역시 흑마법사 게시판에서 좋은 정보를 많이 얻어가고 있습니다.
그래서 이번 기회에 제가 알고있는 정보를 공유해보면 어떨까 해서 흑게 여러분들의 즐거운 와우라이프를 위해
도움이 되는 몇가지 정보를 알려드리려고 미약한 지식에도 불구하고 흑게에 처음 글을 남겨봅니다.

와우는 사용자 인터페이스(UI)를 XML로 정의한 개체와 이벤트, 그에 따라 동작하는 스크립트 언어인 'Lua'로
구성해놨고, 이를 사용자의 편의를 위해 사용자가 얼마든지 수정할 수 있도록 공개해놨습니다.
이로 인해 다양한 애드온들이 나오게 되고 자신만의 UI 환경을 꾸밀 수 있는 것이 와우의 강력한 재미 요소 중
하나라고 할 수 있습니다.

여기까지는 소개글이고 본론에서 다룰 내용은 'Lua'라는 것입니다.

'Lua', 와우하면서 애드온을 이용해보셨다면 당연히 쉽게 접할 수 있는 단어 입니다.
보통 와우저에게 Lua는 애드온 파일의 확장자(xxx.lua) 또는 애드온을 구성해주는 나는 몰라도되는 신비한 거
정도가 되겠습니다. (저도 보통 와우저이므로 이렇게 생각했습니다...)

하지만 Lua는 프로그램에 'P'자도 모르는 평범한 와우저들도 몇가지 패턴만 알게 된다면 쉽게 응용하여 사용이
가능합니다. 이를 이용하여 자신이 원하는 매크로를 만들어서 게임을 더 재밌게 즐길 수 있게 되는거죠.

매크로를 하나 보겠습니다.

/run SendChatMessage("hi")

채팅창에 해당 명령어를 입력해 보면 어떨까요? 일반대화로 'hi'가 출력됩니다.
<안녕하세요?>

여기서 SendChatMessage()가 " " 안에 원하는 단어를 입력하면 일반대화로 출력되게 하는 기능이구나, 라는 것을
알 수 있습니다. 쉽게 말해서 SendChatMessage()는 Lua 내에서 우리가 사용하는 매크로와 같은 역할을 맡고 있다고 
생각하시면 됩니다.

응용해서 SendChatMessage("hi","yell") 로 쓰면 외치기로, SendChatMessage("hi","party")로 쓰면 파티말로,
"party" 대신에 "raid"를 넣으면 공격대말로, "battleground"를 넣으면 전장말로 입력한 내용을 출력합니다.

<"yell" 적용 상태. 옷이 약간 바뀐것 같지만 그건 님의 착각>

매크로를 하나 더 보겠습니다.

/run local t="target" SendChatMessage("Drain Soul "..UnitName(t)..", Health Status "..(UnitHealth(t)/UnitHealthMax(t)*100).."%")
/cast 영혼 흡수

이 매크로는 자신이 영혼 흡수를 시전한 대상의 체력 수치를 퍼센트(%) 단위로 일반 대화창에 출력합니다.

흑게 여러분들은 한번쯤 이런 경우를 겪어보신 적이 있으실 겁니다.
고흑으로 PvP나 레이드 때 상대방(또는 네임드)의 피가 마격 타임인 25%에 접어들자마자 칼같이 영흡을 꼽았는데 
이게 정말 제대로 꼽혔는지...? 너무 일찍 꼽아서 25.01%에 꼽힌거 아냐...? 다시 확실하게 꼽아야 하나...?;

이런 경우에 위의 매크로를 이용하면 자신이 영흡을 시전할 당시에 대상의 피 수치를 %로 채팅창에 출력해 주기
때문에 제대로 꼽았는지 재차 확인이 가능합니다.
<허수아비에게 매크로 사용중>

하지만! 이 매크로는 헛점 투성이의 매크로입니다. 매크로를 완벽하게 다듬어주기 전에 구문을 간단하게 분석해봅시다.

local t = "target"

t 라는 임의의 변수를 선언해서 "target"이라는 값을 대입 해준 부분입니다. 앞으로 t 라고 쓰면 "target"을 의미하는
거다, 내가 그리 정했노라... 라는 겁니다. 그 뒤에 구문을 보시면 선언해준 변수 t 가 계속 사용되고 있습니다.

아아, 앞에서 t = "target" 이라고 정의해서 전체적으로 구문 길이를 간결하게 하고 있구나, 를 알 수 있습니다.
변수로 정한 단어가 구문 전체에 많이 나올수록 더욱 구문 길이를 단축시키는 효과가 있습니다.
이는 편의성도 있지만 와우 매크로 버튼 하나당 255자 제한이기 때문에 255자 이내로 작성할 수 없는 매크로도 
변수를 이용해 축약 하므로써 원버튼 내로 쑤셔넣을 수 있다는 장점이 있습니다.

<변수 선언이 없었다면 255자 이내로 완성할 수 없었을 것이다.>

변수 t 앞에 'local'은 변수의 적용 범위를 이 실행문 내에서만 사용가능하게 지정해주는 역할입니다.
지역 변수라고 하는데, 매크로 여러개를 순서대로 눌러야 적용되는 매크로를 본적이 있을 겁니다. 이런 매크로에는
변수를 선언해 줄 때 변수 앞에 local 을 붙이지 않아서 전체 매크로가 변수를 공유할 수 있도록 합니다.

<고대인님의 상대방 급장 체크 매크로, 총 5개의 버튼을 다 눌러줘야 제대로 매크로가 작동하며 앞매크로에서
  설정한 변수를 뒷매크로도 가져가 사용하고 있다.>

UnitName(t)

UnitName("target")은 " "안에 넣은 대상의 이름을 출력하는 기능을 합니다. "%t" 도 같은 기능을 하는데,
~("Drain Soul "...UnitName(t).."~ 대신에 ~("Drain Soul %t"~ 이렇게 써도 같은 결과가 출력됩니다.

(UnitHealth(t)/UnitHealthMax(t)*100)

UnitHealth(t) 는 대상의 현재 체력을 출력해주는 기능
UnitHealthMax(t) 는 대상의 체력의 최대치를 출력해 주는 기능입니다.

현재 체력 / 최대 체력 * 100 이니까 결국에는 대상의 현재 체력을 Percent(%)로 출력하는 기능을 하게됩니다.

간단하게 구문을 살펴봤습니다. 생각보다 간단하죠?
자, 이제 이 매크로가 헛점 투성이라고 아까 말했는데 그부분에 대해서 살펴보겠습니다.

이 매크로를 마구 눌러봅시다. 결과는 어떤가요?
네, 그렇습니다. 매크로를 누른만큼 마구 출력되어 채팅창을 도배하게 됩니다.

<마구 누르시면, 마구 출력됩니다.>

심지어 아군, 적군, 시전이 가능한 대상인지 따지지도 않고 범위에 상관없이 대상만 클릭하고 있으면 작동합니다.

<강제적으로 실험에 참가한 가로쉬, 아군인데도 작동한다. 사실 적군인가?>

<스킬 시전범위와 전혀상관없이 대상만 잡혀있으면 무조건 작동한다.>

딱 봐도 매크로의 문제가 몇가지 보입니다. 하나씩 조건을 추가해서 다듬어 보겠습니다.

1. 영혼 흡수 스킬이 '전역 재사용 대기시간(일명 글쿨)' 일 때 매크로도 같이 작동되지 않게 하기

영혼 흡수는 따로 쿨이 없기 때문에 글쿨만 아니면 사용이 가능합니다. 글쿨 때 영흡이 시전 안되는 것과 같이
동시에 매크로도 작동하지 않게 조건을 주는 것입니다.

/run local t="target" if GetSpellCooldown("영혼 흡수")==0 then SendChatMessage("Drain Soul "..UnitName(t)..", Health Status "..(UnitHealth(t)/UnitHealthMax(t)*100).."%!");end
/cast 영혼 흡수

GetSpellCooldown() : 입력한 기술의 현재 쿨을 가져오는 기능입니다.

if 문을 써서 ~ 조건이면 then ~ 을 한다. end 가 됩니다. 구문을 이해하기 쉽도록 나눠보겠습니다.


local t = "target" -- 변수 t를 선언하여 "target"을 대입

if GetSpellCooldown("영혼 흡수")==0 then -- 영혼 흡수의 쿨이 0초 이면,

SendChatMessage("Drain ~ %"); -- 대화창에 "Drain ~ %" 출력한다.

end


당연히 if 조건에 맞지 않으면 (기술이 쿨다운 상태일때) then 이하는 실행되지 않습니다. 문제점 한가지가 쉽게
해결이 되었습니다. 참 쉽죠? 그럼 계속 다듬어 보겠습니다.

2. 영혼 흡수 스킬의 시전 범위내에서만 매크로 작동되게 하기

앞서 말했듯이 영흡은 따로 쿨이 없기 때문에 글쿨이 안돌면 매크로는 실행됩니다. 그럼 타겟과의 거리를 40미터
밖으로 벗어나서 영흡이 시전되지 않아 글쿨이 돌지 않는 경우 매크로는 누른만큼 착실하게 실행되서 채팅창을 또
도배하게 됩니다.

그러므로 해결법은 매크로를 영혼 흡수 시전범위 내에서만 작동하도록 조건을 주는 것입니다.

/run local t="target" ds="영혼 흡수" if GetSpellCooldown(ds)==0 and IsSpellInRange(ds,t)==1 then SendChatMessage("Drain Soul "..UnitName(t)..", Health Status "..(UnitHealth(t)/UnitHealthMax(t)*100).."%!");end
/cast 영혼 흡수

"영혼 흡수" 라는 말이 두번 반복되기 때문에 깔끔하게 변수 ds를 선언해서 "영혼 흡수"를 대입해주고 if문 뒤에 and
를 쓰고 IsSpellInRange(ds,t) 조건을 추가 해줬습니다.

IsSpellInRange(ds,t) : t(target)가 ds(영혼 흡수)의 시전 범위에 포함되어 있는지 판단하는 기능을 합니다.
'1'을 주면 시전 범위안에 있을 때 조건을 만족하게 되고 '0'을 주면 시전 범위 밖에 있을 때 조건에 만족하게 됩니다.

지금 까지 다듬은 매크로의 기능을 풀어 얘기하자면,

영혼 흡수의 글쿨이 돌지 않고 시전 범위(40미터)내에 대상이 존재하면 "Drain Soul (대상), Health Status XX %!"
라고 대화창에 출력하며 영혼 흡수 시전

여기서 영혼 흡수는 오직 적대적 대상에게만 시전되는 스킬라서 상관 없지만 사제의 '회개' 기술처럼 아군/적군 
모두에게 시전되는 스킬인데 아군/적군 둘중 특정집단에게만 실행되는 매크로를 만들고 싶다면

지금 했던 방법처럼 조건절에 UnitIsEnemy() (적인지 판단) 이나 UnitIsFriend() (아군인지 판단) 조건을 따로 추가
해주시면 되겠습니다.

자, 여기까지 했지만 아직 매크로가 다 완성된 것은 아닙니다. 마무리를 해줘야 합니다. 뭐냐구요? 이 매크로를
허수아비 말고 실전에서 써봅시다.

<야호! 뜨거운 바위 정령의 현재 체력은 69.19647184259% 네!>

네, 뭔가 굉장합니다. UnitHealth(t)/UnitHealthMax(t)*100 계산이 딱 떨어지지않아 소수점 밑으로 굉장하게 나갑니다.
이런 경우에 직접 출력될 형태를 format 해줘야 합니다.

format( "%.2f", (UnitHealth(t)/UnitHealthMax(t)*100) )

체력계산 부분을 format()으로 감싸주고 출력형태를 %.2f 로 지정해줬습니다. %.2f 는 소수점 두번째 자리까지 출력
한다는 뜻입니다. %.0f 로 해주면 소수점을 없이 정수부분만 출력하게 됩니다.

/run local t="target" ds="영혼 흡수" if GetSpellCooldown(ds)==0 and IsSpellInRange(ds,t)==1 then SendChatMessage("Drain Soul "..UnitName(t)..", Health Status "..format("%.2f", (UnitHealth(t)/UnitHealthMax(t)*100)).."%!");end
/cast 영혼 흡수

<제대로 소수점 두번째 자리까지 깔끔하게 표시된다!>

매크로 하나를 완성해봤습니다. 어떠신가요? 참 쉽죠? ...ㅋ?

Lua를 이용한 매크로 하나 분석해보았더니 Lua, 그거 별거 아니라는 결론이 나왔습니다. (...는 구라)
자, 그럼 본격적으로 제목에서 언급했듯이 Lua를 이용한 매크로로 기본 UI를 강화시켜보겠습니다.

저는 기본 UI를 선호하는 사람 중 한명으로 애드온을 하나도 사용하고 있지 않습니다.
애드온을 사용하지 않고 기본 UI를 사용하면 오는 장점으로는 어디서든 애드온에 구애받지 않고 접속해서 와우를
즐길 수 있다는 점과 대규모 패치로 인한 애드온 대란은 남얘기라는 겁니다. 훗.

주위 아는 지인분들 중에는 애드온에 너무 의존하게되서 사용하고 있는 애드온이 작동하지 않거나 없으면 와우를
즐기는 것 자체에 크게 영향을 받는 분들이 종종 계시곤 합니다.
물론 애드온을 사용하는 것의 옳고 그름을 논하려는 것은 아닙니다. 서두에서 말씀드렸듯이 애드온은 와우의 재미를
한층 더 높여주는 자랑거리 중 하나입니다.

말씀드리고 싶은 것은 불편해도 남이 해줄 때 까지 기다리는 의존적인 앤드 유저가 되기 보다는, 가려운 곳이 있으면
자신이 바로 긁었을 때 오는 시원함을 느낄 수 있는 능동적인 와우저가 되었으면 좋겠습니다. 그것이 와우를 한층 더
진정으로 재밌게 하는 요소 중 하나라고 저는 굳게 믿습니다. 물론 정말 가려운데 긁지 못하는 등짝 가운데는
전문의의 도움을 받는게 현명합니다.

제가 기본 UI를 사용한다고 했는데 기본 UI는 그대로 쓰기엔 불편한게 한두가지가 아닙니다. 그대로 꾹 참고 쓰기엔
제 몸이 너무 근질 거립니다. 마치 3년동안 샤워안한 것처럼요. 그래서 너무 가려워서 한번 긁어보기로 했습니다.

<우선 제일 마음에 안드는 부분은 이겁니다. 체력만 따로 % 로 표시해주는 설정은 자네가 먹었능가?>

영혼 흡수가 마격 스킬이긴 하지만 25%가 된다고 자동으로 스킬에 불이 들어오거나 하진 않습니다. 유저가 신경을
써줘서 알아서 대상의 체력이 25% 이하로 내려가면 영흡을 꽂아줘야 합니다. 그렇다면 대상의 체력만 따로 %로 하는
설정이 필요합니다. 하지만 그런 설정은 없고 모든 화면의 나타나는 수치를 전부 싸잡아서 모두 백분율로 표시하는
옵션만이 존재합니다.

<체력만 백분율로 표시하고 싶은 남자의 심정을 매도하지마.>

그래서 가려운 곳을 긁으니까 바로 해결법이 나왔습니다.

/run TF=CreateFrame("Frame")TFHB=TargetFrameHealthBar.TextString;
/run TF:SetScript("OnUpdate", function(target)TFHB:SetText(format("%.0f", ((UnitHealth("target")/UnitHealthMax("target"))*100)).."%")end)

<매크로를 적용한 상태>

네, 어때요? 참 쉽죠?
원래 프로그램의 세계란 1+1을 알려주고나서 다음 단계는 바로 미분/적분입니다.
그런것 치고는 위에서 함께 분석한 간단한 매크로에서 쓰였던 부분들이 많이 보입니다. 매크로를 이해하는게 어려움은
없어보이네요. 요 부분은 무슨 기능이지? 라고 궁금한 부분은 와우위키(www.wowwiki.com/API)를 참고하시면 되겠습니다.

그럼 더 나아가 체력수치는 그대로 보여주고 그옆에 백분율을 추가로 표시해주는건 어떻게 할까요?

1번 매크로
/run TF=CreateFrame("Frame")TFHB=TargetFrameHealthBar.TextString;TTSB=TextStatusBar_CapDisplayOfNumericValue
2번 매크로
/run TF:SetScript("OnUpdate", function(target)TFHB:SetText(TTSB(UnitHealth("target")).."/"..TTSB(UnitHealthMax("target")).." ("..format("%.0f", ((UnitHealth("target")/UnitHealthMax("target"))*100)).."%)") end)

네, 고민하려는 찰나에 매크로가 어디서 뚝딱 하고 튀어나와버렸습니다. 매크로가 길어져서 1번 매크로, 2번 매크로
로 나누어 졌습니다. 차례대로 눌러주시면 제대로 동작합니다.

<현재 체력 / 최대 체력 (백분율 %)>

처음 매크로와 차이점은 TextStatusBar_CapDisplayOfNumericValue 를 이용해서 출력부분에 
TTSB(UnitHealth("target")).."/"..TTSB(UnitHealthMax("target")).." 현재 체력과 최대 체력을 처리해준 부분이 추가
되었습니다. 여기서 최대 체력을 없애고 싶으신 분들은 TTSB(UnitHealthMax(... 부분을 지워 주시면 되겠죠?


추가 요청 사항

"체력 표시 13455/13455(100%) 이렇게 되는거 쓰고 싶긴한데 너무 길어져서 체력바 전체를 가려버리는 느낌
 이 있어서요. 어느 영상에선가 13000을 1.3K 이런식으로 표현하는 것을 본적이 있는데 이건 불가능 할까요?"

13000을 1.3K로 바꾸는 것처럼 자신이 원하는 형태로 출력하고 싶은 경우에는 format()을 이용합니다.

format() : 값을 임의의 정해진 형태대로 출력하는 기능을 합니다.

format()의 자세한 기능을 알고 싶으신 분들은 와우위키 : API format (http://www.wowwiki.com/API_format)
참고하시고 본문에서는 format()을 간단하게 알아보겠습니다.

기본적으로 쓰이는 형태는

format("표현", "")

입니다.

13000을 13K로 바꾸고 싶다면 format("%.0fK", 13000/1000) 이런식으로 쓰면 되겠습니다.

(여기서 잠깐, 질문에는 13000을 1.3k로 표현해놓으셨는데 이는 잘못된 표현입니다. k는 1000(kilo)를 의미하는
 단위로 13k가 정확한 표현입니다. 13000을 1.3k로 표현되는경우가 종종있는데 이는 숫자를 셀때 만 단위로 끊어
 쓰는 한국사람들만의 잘못된 습관입니다. 13000을 1.3으로 표현하고 싶다면 '1.3만'이라고 한국어로 표현하는게
 맞습니다.)

표현의 종류에는 여러가지가 있지만 와우에서 주로사용되는 것만 살펴보면 다음과 같습니다.

%d : 'Decimal' 10진 정수로 출력한다.

%s : 'String' 문자열을 출력한다.

%f : 'float' 실수형으로 출력한다. %.nf (소수점 n번째 자리까지 출력한다는 의미)

%% : % 문자 출력 방법

또한 여러 값을 차례차례 받아서 순서대로 원하는 표현으로 출력가능합니다.

format("표현1, 표현2", "1", "값2")

자, 말로는 설명해놨지만 구체적으로 어떤식으로 이용하는지 알고싶습니다.
와우 내에서 실제로 format이 어떻게 이루어지는지 확인하기 위해서 /run SendChatMessage()를 이용해서 채팅창
에 출력해 보겠습니다.

/run SendChatMessage(format("%.0f", 12.345))

<%.0f로 표현식을 정해준 매크로 실행화면>

표현식을 %.0f 로 했기때문에 값을 받아 소수점 0번째 자리까지 출력해서 12가 출력되었습니다. 그럼 표현식을
%d로 바꿔보면 어떨까요?

/run SendChatMessage(format("%d", 12.345))

<%d로 표현식을 정해준 매크로 실행화면>

%d는 10진 정수로 출력하므로 같은 결과값 12가 출력됩니다. 와우 매크로는 축약할수록 좋다고 했는데
그럼 %.0f 보다 약간더 길이가 짧은 %d를 표현식으로 사용하면 전체적인 문장길이를 줄일 수 있지 않나요? 라고
생각하실껍니다.

%.0f%d의 차이점을 살펴보겠습니다.

/run SendChatMessage(format("%.0f, %d", 1.99999, 1.99999))

<%f.0f와 %d의 각각 값의 표현 결과>

값 1.99999 는 거의 2와 같은 숫자크기인데 %.0f는 결과값 2로 반올림으로 받아줬고, %d는 결과값이 1
소수점 이하값을 절사합니다. 와우 캐릭터의 체력수치와 같은 민감한 값은 %f로 받아주는게 더 좋은방법이겠죠?

계속해서 매크로를 써보겠습니다.

/run SendChatMessage(format("%.0f", UnitHealth("player")/1000))

<매크로가 실행된 채팅창>

이 매크로는 플레이어 자신의 현재 체력수치를 1000으로 나눈 값을 %.0f 형태로 받아서 출력하는 매크로입니다.
표현식 뒤에 k를 붙여서 1000 단위 표현을 붙여봅시다.

/run SendChatMessage(format("%.0fk", UnitHealth("player")/1000))


어느정도 점점 원하는 형태로 접근이 되고있습니다. 이번엔 자신의 최대 체력수치까지 표시해서
"현재 체력 / 최대 체력" 형태로 표현해봅시다.

/run SendChatMessage(format("%.0fk/%.0fk", UnitHealth("player")/1000, UnitHealthMax("player")/1000))

<"현재 체력 / 최대 체력" 형태로 출력된 화면>

결과적으로 질문했던 부분에 완전히 접근했습니다. 이제 "현재 체력 / 최대 체력 (%표시)" 매크로에서
현재 체력 / 최대 체력 출력을 담당하는 부분을 fomat()으로 감싸주면 끝입니다.

기존 1번 매크로
/run TF=CreateFrame("Frame")TFHB=TargetFrameHealthBar.TextString;TTSB=TextStatusBar_CapDisplayOfNumericValue
기존 2번 매크로
/run TF:SetScript("OnUpdate", function(target)TFHB:SetText(TTSB(UnitHealth("target")).."/"..TTSB(UnitHealthMax("target")).." ("..format("%.0f", ((UnitHealth("target")/UnitHealthMax("target"))*100)).."%)") end)

2번 매크로에서 굵은 글씨로 표시한 곳이 "현재 체력 / 최대 체력" 출력을 담당하는 부분입니다.
이 부분을 format()으로 감싸주시면 되겠습니다.

변경된 1번 매크로
/run t="target";TF=CreateFrame("Frame");TFHB=TargetFrameHealthBar.TextString;TTSB=TextStatusBar_CapDisplayOfNumericValue
변경된 2번 매크로
/run TF:SetScript("OnUpdate",function(target)TFHB:SetText(TTSB(format("%.0fk",UnitHealth(t)/1000)).."/"..TTSB(format("%.0fk",UnitHealthMax(t)/1000)).." ("..format("%.0f",(UnitHealth(t)/UnitHealthMax(t))*100).."%)")end)

<변경된 매크로를 실행한 화면>

2번 매크로에서 굵게 처리된 부분이 format()을 이용해서 변경한 부분입니다. 매크로의 길이가 좀더 길어
졌으므로 2번 매크로에서 반복되는 "target"을 1번 매크로에서 변수 t로 선언해서 전체적인 매크로 길이를 축약
시켰습니다.

제대로 잘 되시죠? 차근차근 알아보니 금방 원하는 매크로가 나왔습니다.

주의! 소스에 Lua 오류가 있음을 제보받고 "변경된 2번 매크로"의 소스를 임시 변경해 놓았습니다. 제대로 정상적으로 오류없이 동작을 하므로 사용하시는 데에는 지장이 없지만 정확한 소스를 위해 수정 중이오니 사용하는 분들은 글상자의 임시 소스를 일단 사용해 주세요.


<고대인님의 '현재 체력 (% 퍼센트)' 관련 원버튼 매크로 소스를 본문에 게재하였습니다. (2011-12-12)>

/run TBC=TextStatusBar_CapDisplayOfNumericValue;hooksecurefunc("TextStatusBar_UpdateTextString",function(tsb)if(tsb.TextString)then local v={tsb:GetValue(),tsb:GetMinMaxValues()}tsb.TextString:SetText(TBC(v[1]).."  ("..ceil(v[1]/v[3]*100).."%)")end end)

또한 흑마 고통 특성 중에는 '죽음의 은총'이라는 특성이 있습니다.

<플레이어의 생명력이 25% 이하일 때는 생흡량이 +3% 더!>

자신의 체력도 백분율로 표시해 줄 필요성이 있는데 이럴 경우는 위에 있는 매크로들의 "target" 부분을 모두 "player"
로 바꿔 주시면 됩니다.

/run TF=CreateFrame("Frame")PFHB=PlayerFrameHealthBar.TextString;
/run TF:SetScript("OnUpdate", function(player)PFHB:SetText(format("%.0f", ((UnitHealth("player")/UnitHealthMax("player"))*100)).."%")end)

<내 체력도 백분율로 변경 완료>

저는 제 마나량 수치가 얼마인지 별로 궁금하지 않기 때문에 [인터페이스 설정] > [상태 숫자] > [플레이어] 체크
박스를 해제한 후

/run ShowTextStatusBarText(PlayerFrameHealthBar)

매크로를 이용하여 체력만 보이도록 설정하였습니다.

<체력 수치만 퍼센트로>

ShowTextStatusBarText(PlayerFrameHealthBar) 는 Show <-> Hide , Player <-> Target 또는 Focus,
Health <-> Mana 로 변경해서 자신이 원하는 부분만을 화면 상에 나타내고 지울 수가 있습니다.

<이처럼 체력바를 깔끔하게 다 지우고 전장에서 상대방이 징기인지 신기인지만 (힐특인지 아닌지)
  빠르게 판단하는 용도로 쓰기도 합니다.>

다음 불편한 점은 고흑을 할때 나타나는 성가신 초록색 글씨들 입니다.

<이겁니다! 이 간에 기별도 안차는 회복량 표시 덕분에 제 캐릭이 안보입니다...
  화면을 초록색 글씨로 도배해주는 고마운 기술들>

전 제가 입은 피해량은 화면에 표시하되 초록색으로 표시되는 치유량은 따로 없애고 싶었습니다. 하지만
[인터페이스 설정] -> [전투 상황 알림]에는 모든 전투메시지를 끄는 기능은 있지만 치유 메시지만 선택적으로
끄는 옵션은 아쉽게도 없었습니다. 

그래서 나온 해결법입니다.

/run COMBAT_TEXT_TYPE_INFO["HEAL"].show=false
/run COMBAT_TEXT_TYPE_INFO["PERIODIC_HEAL"].show=false

이 매크로를 이용하면 직접적인 치유량과 주기적인 치유량을 화면에서 안보이게 할 수 있습니다.
흑마법사의 기술 중 치유량을 크리내는 기술은 없기 때문에 ["HEAL_CRIT"]는 건드리지 않았습니다.
따라서 아군 힐러들에게 힐을 받을 시에 크리가 터지면 화면에 표시가 됩니다. 모든 힐량이 표시되지 않는 것보다
힐을 받고있다는 상황을 알 수 있기 때문에 이부분은 남겨두었습니다.

<풀딜을 해도 화면이 더러워지지 않는다!>

'COMBAT_TEXT_TYPE_INFO'로 인터넷에 검색해보시면 전투 메시지의 종류도 참으로 다양합니다.
그중에 /run COMBAT_TEXT_TYPE_INFO["SPELL_CAST"]를 이용해 스킬 발동 메시지인 <어둠의 무아지경>도 지워버렸습니다.

/run COMBAT_TEXT_TYPE_INFO["SPELL_CAST"].show=false

<주문 발동 시 뜨는 <어둠의 무아지경> 도 선택적으로 없애는 옵션이 없기 때문에 매크로로 깔끔하게 처리>


지금까지 기본적으로 UI를 자신에게 맞게끔 조절하는 방법을 알아보았습니다.
이러한 매크로를 한개 두개 모으고 만들어서 쓰다보니 매크로 칸이 점점 부족해집니다.

그렇다면 이번에는 넘쳐나는 매크로들을 .lua 파일로 묶어서 애드온화 시키는 법을 알아보겠습니다.

우선 사나이로님이 쓰신 글, '나만의 애드온 만들기(기본)' 입니다.

정말 좋은 글입니다. 이 글을 참고해서 나만의 애드온을 하나 만들어 보겠습니다.

<일단 새폴더를 만들어서 이름을 임의로 하고싶은걸로 정해줍니다.>

<그 다음 메모장을 열어서 저장을 누릅니다.>

<저장할 위치는 아까 만든 그 폴더로 지정하고 파일 형식을 '모든 파일'로 선택하고 파일 이름을
  저장 폴더와 같은 이름으로 쓰고 확장자를 '.lua' 로 해줍니다. -> '저장'>

<새 메모장을 하나 더 열어서 이런식으로 작성해줍니다.>

<같은 폴더 내에 같은 이름으로 하고 확장자를 .toc 로 저장한다.>

<자 끝났습니다! 나만의 애드온이 완성되었습니다!>

<이제 남은일은 lua 파일만 나만의 소스로 채워주면 끝!>

<새 메모장을 열어서 [파일]->[열기]를 누릅니다.>

<파일 형식을 '모든 파일' 선택으로 하면 목록에 .lua 파일과 .toc 파일이 보입니다.
  lua 파일을 선택하고 -> '열기'>


일단 forbidden 님의 '빗나감, 저항함 등의 전투메시지를 영어로 표시해봅시다.'

COMBAT_TEXT_ABSORB = "Absorb"
COMBAT_TEXT_IMMUNE = "Immune"

를 추가해보겠습니다. COMBAT_TEXT_ABSORB = "Absorb" 는 와우 전투 메시지 중 화면에 "흡수"라고 뜨는 메시지를
-> "Absorb"로 영어로 바꿔줍니다. COMBAT_TEXT_IMMUNE = "Immune" 는 메시지 "면역" 을 "Immune" 로 바꿔줍니다.

<'-- (하이픈을 두번 눌러주면) 그줄은 주석처리로 Lua 코드에 아무런 영향을 주지 않는다.'>

<그외에도 forbidden 님의 글에선 다루지 않았지만 COMBAT_TEXT 에 관한건 찾아보면 얼마든지 나온다.
  몇개 더 추가해보자.>

-- 양쪽 끝 독수리 모양 없애는 소스

MainMenuBarLeftEndCap:Hide()MainMenuBarRightEndCap:Hide();

그리고 사나이로님의 글에서 '초상화 체력바에 클래스 컬러 입히기', '거리에 따른 액션바 색상변화' 소스를
추가하고 본문에서 사용해보았던 '대상의 체력을 퍼센트로 표시', '플레이어의 체력을 퍼센트로 표시'를
추가해보았습니다.

<매크로 소스를 lua 파일에 적을 때는 /run 만 빼고 적어주시면 됩니다.>

--초상화 체력바에 클래스 컬러 입히기

local UnitIsPlayer, UnitIsConnected, UnitClass, RAID_CLASS_COLORS =
UnitIsPlayer, UnitIsConnected, UnitClass, RAID_CLASS_COLORS
local _, class, c
 
local function colour(statusbar, unit)
if UnitIsPlayer(unit) and UnitIsConnected(unit) and unit == statusbar.unit and UnitClass(unit) then
_, class = UnitClass(unit)
c = CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS[class] or RAID_CLASS_COLORS[class]
statusbar:SetStatusBarColor(c.r, c.g, c.b)
end
end
 
hooksecurefunc("UnitFrameHealthBar_Update", colour)
hooksecurefunc("HealthBar_OnValueChanged", function(self)
colour(self, self.unit)
end)
 
local sb = _G.GameTooltipStatusBar
local addon = CreateFrame("Frame", "StatusColour")
addon:RegisterEvent("UPDATE_MOUSEOVER_UNIT")
addon:SetScript("OnEvent", function()
colour(sb, "mouseover")
end)


--거리에 따른 액션바 색상변화

hooksecurefunc("ActionButton_OnEvent",function(self, event, ...) 
        if ( event == "PLAYER_TARGET_CHANGED" ) then 
                self.newTimer = self.rangeTimer 
        end 
end) 
 
hooksecurefunc("ActionButton_UpdateUsable",function(self) 
        local icon = _G[self:GetName().."Icon"] 
        local valid = IsActionInRange(self.action) 
 
        if ( valid == 0 ) then 
                icon:SetVertexColor(1.0, 0.1, 0.1) 
        end 
end) 
 
hooksecurefunc("ActionButton_OnUpdate",function(self, elapsed) 
        local rangeTimer = self.newTimer 
 
        if ( rangeTimer ) then 
                rangeTimer = rangeTimer - elapsed 
  
                if ( rangeTimer <= 0 ) then 
                        ActionButton_UpdateUsable(self) 
                        rangeTimer = TOOLTIP_UPDATE_TIME 
                end 
 
                self.newTimer = rangeTimer 
        end 
end)


--대상의 체력을 퍼센트로 표시

TF=CreateFrame("Frame")
TFHB=TargetFrameHealthBar.TextString;

TF:SetScript("OnUpdate", function(target)
TFHB:SetText(format("%.0f", ((UnitHealth("target")/UnitHealthMax("target"))*100)).."%")
end)


--플레이어의 체력을 퍼센트로 표시

TF=CreateFrame("Frame")
PFHB=PlayerFrameHealthBar.TextString;

TF:SetScript("OnUpdate", function(player)
PFHB:SetText(format("%.0f", ((UnitHealth("player")/UnitHealthMax("player"))*100)).."%")
end)

<추가가 다 되었으면 저장을 누릅니다.>

lua 파일에 소스도 채웠고 이제 테스트를 해볼 차례입니다.

<만들어진 애드온 폴더를 '와우가 설치된 폴더\Interface\AddOns 에 넣어줍니다.>

<와우를 실행해 봅니다. 캐릭터 대기화면 좌측 하단에 '외부 인터페이스' 버튼을 클릭>

<제작한 애드온이 제대로 목록에 뜨는군요. 접속해봅시다.>

<접속화면과 소스 구현 부분>

기본적으로 몇가지 시험해 봤습니다. 잘 적용되는군요. 이밖에도 여러분들이 자신이 필요하다고 생각하는 소스를
lua 폴더에 추가하시면 되겠습니다. 유닛프레임을 크게 한다던지, 자신에게 걸린 디버프를 2배로 크게 표시한다던지..

미약한 지식으로 쓴 부족한 글을, 스압도 상당한데 읽어주셔서 감사합니다.
마지막으로, 몇가지 매크로를 소개해드리고 이상 마치도록 하겠습니다.

/run f=CreateFrame("Frame") f:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED") f:SetScript("OnEvent", function(self,event,...) if UnitName(select(1,...))==UnitName("target") and select(5,...)==19647 then Stopwatch_StartCountdown(0,0,24) Stopwatch_Play() end end)

클릭하고 있는 대상이 자신에게 주문잠금을 시전하면 자동으로 초시계가 24초부터 돌아갑니다.
한마디로 상대방 마반 쿨보는 매크로인데, 많은 분들이 이와 같은 매크로를 게시판에 물어봤었던 걸로 기억합니다.
구문에 "target" 을 "focus"로 바꿔주면 자신이 주시잡고 있는 대상의 마반을 감지합니다.

중간에 19647 숫자는 흑마 똥개의 주문잠금의 스펠ID 입니다. 매크로를 한번 작동시킨 뒤 스펠아이디를 법사 마반으로
수정해서 한번 더 눌러주시면 주잠/마차에 모두 초시계가 자동으로 반응합니다. 같은 매크로를 스펠아이디만 바꿔서
2개 만들어놔도 좋구요.

그리고 모든 와우 DB 정보는 와우헤드(www.wowhead.com)를 참조하시면 되겠습니다.

<와우헤드 메인에서 흑마법사 카테고리를 찾아 들어간다.>

<주문잠금을 찾아서 클릭하면 주문잠금 마법에 대한 페이지가 뜨는데 주소가 곧 스펠 아이디이다.>

살타라하르님의 '한줄 매크로를 이용해 mp3 파일 재생하기!' 글입니다.

살타라하르님의 글에서 소개된 매크로를 응용하는 방법입니다.

/Script PlaySoundFile("Sound\\snd001.mp3")

<제 글에 있는 첨부 파일(snd001.zip)을 받아서 압축을 풀어줍니다. snd001.mp3 파일이 나옵니다.>

<와우 폴더로 가셔서 Sound 폴더를 하나 만들어 줍니다.>


<와우를 실행키고 /Script PlaySoundFile("Sound\\snd001.mp3")를 매크로로 만들어줍니다.>

자 매크로가 완성되었습니다. 연속 5번 빠르게 눌러봅시다. 굉장한 일이 벌어집니다.

<이런 천상의 하모니 같으니...!>

낚이신 분들이 계시다면 죄송합니다. 정말 굉장한 소리가 나옵니다. 그럼 어떻게 하면 좋을까요?

본문에서 사용되었던 GetSpellCooldown을 이용해서 흑마법사의 기술 '악마의 영혼'과 묶어보겠습니다.

#showtooltip
/cast 악마의 영혼
/use 13
/run if GetSpellCooldown("악마의 영혼")==0 then PlaySoundFile("Sound\\snd001.mp3"); end

악영과 사효장신구 그리고 신나는 음악매크로를 한번에 묶었습니다.
이렇게 사용하면 악영 딜타임 때만 매크로가 발동되겠죠?