======================================================================

 

[목차]

1. 일부 함수가 비유저스크립트에서 작동하지 않는 문제 해결방법

2. 연속워프시 튕기는 문제의 해결조건

3. set_mobmagicstate 함수의 인자

4. mobstate란?

5. set_damagedrate 함수의 사용법

6. action 함수의 비밀

7. mob_spawn 함수의 비밀

8. magic_aether 함수의 비밀

9. showgage 함수의 비밀

10. damage 함수의 비밀

11. magic_delay 함수의 비밀

12. set_mobtarget 함수의 비밀

13. get_x, get_y 함수의 비밀

 

======================================================================

 

온전치 못한 CR의 함수들을 효과적으로 사용하는 데는 여러가지 노하우가 필요하다.

이를 사소한 것부터 복잡한 것까지 전부 나열하면 백가지도 넘겠지만

함수의 가장 기초적인 사용에 있어서 모르고 지나칠 만한 것 중 13가지만 언급을 해보겠다.

이런 것들을 잘 숙지하여 응용한다면 CR에서 쓰기 어려웠던 각종 기능을 구현하는데 도움이 될 것이다.

그 구체적 응용법은 꽤나 방대하기 때문에 여기서 다 설명하기는 어렵고, 차후 기회가 되면 정리해보겠다.

 

 

1. 일부 함수가 비유저스크립트에서 작동하지 않는 문제 해결방법

 

obj_getxy나 set_mobmagicstate 등의 몇몇 함수는 몹마법, NPCsay 등의 비유저스크립트에서 작동하지 않는다.

예를 들어 몹마법 스크립트 내에서 obj_getxy 함수를 써서 (3, 5)의 오브젝트값을 가져오고 싶다면,

계정변수, 서버변수를 임시변수처럼 다음과 같이 활용할 수 있다.

 

mob 몹마법 {

set @myid, objid();

set @target_id, get_mobtarget(@myid);

set @target_sd, id2sd(@target_id);

 

set_uservar_i @target_sd, "x", 3;

set_uservar_i @target_sd, "y", 5;

runscript @target_sd, "obj_getxy";

printf(" (3, 5) 지점의 obj_id: " + get_uservar_i(@target_sd, $obj_id));

}

script obj_getxy {

set @mysd, mysd();

set $obj_id, obj_getxy($x, $y);

}

 

즉, 몬스터가 obj_getxy 함수를 직접 쓸 수 없기 때문에

인자값들을 특정 유저의 계정변수 또는 서버변수들에 집어넣고

해당 함수를 대신 실행하게 하는 방법이다.

 

 

2. 연속워프시 튕기는 문제의 해결조건

 

warp 함수나 set_xy 함수 등을 이용해 유저가 순간적으로 워프를 2번하면 보통 튕겨버리게 되는데,

sleep 함수를 안쓰더라도 새로 읽어들이는 맵타일의 양이 충분히 적다면 이를 모면할 수 있다.

따라서, 맵크기가 1인 맵을 만들어놓고 순간이동으로 다녀온다면, 마치 ctrl+R을 누른 효과를 보는 셈이다.(모든 이펙트, 깨짐현상 제거)

 

 

3. set_mobmagicstate 함수의 인자

 

기본적으로 set_mobmagicstate에 대한 정보는 아래와 같이 알려져있다.

set_mobmagicstate @target_id, @spell_id, @aethered_time, @type, @effect, @c1, @c2, @c3;

 

MOB_GENERAL = 0, // 일반상태

MOB_POISON = 1, // 중독

MOB_COMA = 2, // 공격X, 이동X

MOB_HEAL = 3, // 이건아직 추가X

MOB_NOTATTACK = 4, // 공격 X

MOB_NOTMOVE = 5, // 이동 X

MOB_CURSE = 6, // 저주

MOB_ATTRACT = 7 // 유인

 

중요한 것은 각 인자들에 대한 구체적인 정보다.

직접 확인해본 바는 아래가 전부이며, 이외의 필요없는 인자는 0으로 놓으면 된다.

 

중독(@type == 1)의 경우 @c1: 중독량[%], @c2: -1(고정값), @c3: (0:최대체력비례, 1:현재체력비례, 2:최대체력비례+어그로, 3:현재체력비례+어그로)이며

참고로, 중독량에 음수값을 입력하면 재생량이 된다.

저주(@type == 6)의 경우 @c1: 저주량

유인(@type == 7)의 경우 @c1: 타겟id

 

덤으로 set_pcmagicstate에 대한 정보는 아래와 같다.

 

PC_GENERAL = 0, // 일반상태

PC_POISON = 1, // 중독

PC_HEAL = 2, // 재생

PC_? = 3, // ?

PC_INVULNERABLE = 4, // 무적

 

중독 또는 재생(@type == 1 || @type == 2)의 경우 @c1: 중독량/재생량, @c2:중독량/재생량[%], @c3:-1(%댐이면 고정값, 수치댐이면 0:방어무시, 1:방어적용)이나 @c1과 @c2 중 하나는 반드시 -1이어야 한다.

 

 

4. mobstate란?

 

아직 set_mobstate 함수의 기능이 정확히 알려져있지 않은데,

사실 set_mobmagicstate 함수가 주던 효과들을 수동으로 조정할 수 있게 해준다.

 

기본적으로 set @state_prev, get_mobstate(@target_id);는 대상 몹의 기존 상태값을 가져오며,

set_mobstate @target_id, @state;는 대상 몹을 @state_prev+@state에 '해당하는' 상태로 설정해준다.

이 설명만으로는 굉장히 어렵게 다가올 수 밖에 없으니 예시를 통해 이해해보자.

 

먼저 현재까지 확인한 각 효과의 상태값은 다음과 같다.

1:중독, 2:?, 4:이동불가, 8:공격불가, 16:유인, ...

예를들어 기본 상태(상태값 0)에서 set_mobstate @target_id, 4;하면 상태값이 4로 바뀌면서 이동불가상태가 된다.

마찬가지로 한번 더 +4를 해주면 상태값이 8로 바뀌면서 공격불가상태가 된다.

그런데 만약 여기서 또다시 +4를 해주면 어떻게 될까?

물론 상태값은 12가 된다. 그런데 12=8+4이므로 이동불가상태이면서 공격불가상태가 된다.

만약 상태값이 20이라면? 20=16+4이므로 유인상태이면서 이동불가상태가 된다.

 

이제 감이 좀 오는가? 이는 결국 하나의 상태값을 가지고 모든 상태 여부를 표시하기 위한 이진법적 표기법이라는 정도로 해두겠다.

즉, 몇개의 상태가 걸려있든 그 전체가 고유한 하나의 상태값으로 나타내어진다는 것이다.

 

또한, set_mobmagicstate 함수를 걸어놓고 get_mobstate나 mob_isstate로 그 상태를 확인할 수 있다.

예를들어 이동불가(@type == 5) 효과를 주는 set_mobmagicstate 함수와, 이동 및 공격불가(@type == 2) 효과를 주는 set_mamagicstate 함수를

걸어놓고 get_mobstate를 찍어본다면 결국 이동불가와 공격불가라는 두 종류의 상태가 걸려있는 셈이므로 4+8=12라는 상태값을 나타낼 것이다.

 

마지막으로, set_mobmagicstate 함수에 의한 상태는 절대적(취소되더라도 즉시 갱신됨)이다.

무슨 말이냐 하면, set_mobmagicstate로 이동불가(@type == 5)를 걸어서 상태값이 4가 되어있는 상태라면,

set_mobstate -4를 해줘서 0이 되었다가 걸려있는 set_mobmagicstate 함수에 의해 즉시 4로 돌아간다는 것이다.

더 신기한 건, set_mobmagicstate로 공격불가(@type == 4)가 걸려 상태값이 8인 경우를 생각해보자.

이때 set_mobstate -4를 해주면, 순간적으로 상태값 4가 되었다가 즉시 공격불가 상태값 8이 추가되므로 상태값 12가 된다.

한편, set_mobmagicstate가 풀리면 제거된 효과에 상당하는 만큼의 상태값이 감소하게 된다.

 

즉 정리하자면, set_mobmagicstate에 의해 걸린 효과는 상응하는 set_mobstate로 제거할 수 '없으나',

set_mobstate에 의해 걸린 효과는 상응하는 set_mobmagicstate가 풀리면서 제거될 수 있다.

따라서 그 원리를 잘 이해한다면, 그리고 이해해야만 유용하게 쓸 수 있는 것이 바로 mobstate 개념이다.

 

 

5. set_damagedrate 함수의 사용법

 

set_damagedrate는 참 이상한 함수다. set은 있는데 get이 없다.

사용법도 굉장히 특이하다. 일련의 테스트 끝에 다음의 룰에 의해 작동함을 알 수 있었다.

1. damagedrate 값 @a는 항상 0 이상의 값을 갖는다.

2. damagedrate 값 @a가 만약 0 이상 1 미만이면 (1-@a)*100%의 대미지를 받는다.

3. 그렇지 않으면 100%의 대미지를 받는다.

4. set_damagedrate @sd, @b를 해주면 damagedrate 값이 기존값 * @b로 바뀐다.

5. set_damagedrate @sd, -1를 해주면 damagedrate 기본값(1)으로 설정된다.

 

이건 뭐 그냥 엿먹으라는 것처럼 보일 수도 있지만..

뭐든지 쓰기 나름이니 허접한 무장체계를 보완하는 유용한 함수로 활용해보자!

 

 

6. action 함수의 비밀

 

action 함수는 몹에게도 적용될 수 있다.

특히 청의태자의 청룡마령참은 청의태자 3번액션에 해당한다.

청의태자 몹이 2번액션을 쓰도록 했더니 본적도 없는 주술액션이 나가는 것을 보고 깜짝 놀랐었다.

그러나 대부분은 0번액션 걷기와 5번액션 죽음, 그리고 25번액션 맞기 이외에는 없다.

가끔 버그에 의해서 어떤 액션번호를 쓰면 이미지순서에 따라 다른 몬스터 이미지로 변했다가 돌아오는 경우도 있다.

그리고 어떤 몹이 쓰는 액션과, 유저가 해당 몹 이미지로 변신하여 쓰는 액션과는 다소 차이가 있다.

마지막으로, action의 세번째 인자는 action의 지속시간을 의미하는데 최대값은 255이다.

 

 

7. mob_spawn 함수의 비밀

 

mob_spawn 함수의 5번째 인자인 @side에는 0~3보다 큰 값이 들어갈 수 있다.

각 방향에 대해 걷거나 때리거나 맞을 때, 죽을 때의 스냅샷이 나타난다.

이를 잘 활용하면 제공되지 않는다고 생각했던 다양한 이미지의 페이크를 만드는 데 도움이 된다.

 

 

8. magic_aether 함수의 비밀

 

magic_aether의 3번째 인자인 @aethered_time에 -1를 입력하면 지속시간이 무한으로 설정된다.

온오프 형태의 버프마법을 표시할 때 9999초처럼 지저분하게 쓰지 않아도 되는 것이 장점이다.

 

 

9. showgage 함수의 비밀

 

이 함수는 두가지 용도로 사용되는데, 하나는 대미지를 임의로 표시하는 것이고,

또 하나는 의도하지 않은 대미지 표시를 취소하는 것이다.

예를 들어 순간적으로 대미지를 2번 주면 표시되는 대미지는 실제와 달라지게 된다.

이럴 경우 참값을 수동으로 표시하기 위해 실제 대미지를 계산해서

showgage의 2번째 인자인 @damage에 입력하면 표시대미지를 참값으로 덮어씌울 수 있다.

한편, 대미지를 계산하기가 어려운 경우 0을 입력하면 힛게이지만 표시가 되고,

바로 전 순간의 쓸모없는 대미지는 표시되지 않는다.

 

 

10. damage 함수의 비밀

 

damage @myid, @target_id, @damage, @option;인 것이 잘 알려져있으나, 한가지 주의할 사항이 있다.

몹이 몹에게 대미지를 가하는 경우는 1번째와 2번째 인자의 순서가 뒤바뀐다는 것이다.

즉, 이런 경우 damage @target_id, @myid, @damage, @option이 된다.

또 한가지, 몹이 스폰되자마자 자살하면 튕김현상을 초래하니 이런 경우 최소 100ms의 딜레이라도 넣도록 하자.

 

 

11. magic_delay 함수의 비밀

 

CR에서의 magic_delay는 해당 마법스크립트에 적용되는 것이 아니라, 최근에 사용한 마법에 적용된다.

따라서 magic_delay 함수는 항상 sleep 함수 이전에 사용되어야 딜레이가 꼬이는 일이 없다.

 

 

12. set_mobtarget 함수의 비밀

 

몹이 맵의 가장자리에 있어서 몹이 유저를 볼 수 있지만 유저는 몹을 볼 수 없는 경우가 있다.

이런 상태의 몹들 여러마리에게 몹타겟을 지정해주게 되면 유저가 읽어들여야하는 맵 정보가 과다해져 서버에 튕김현상을 초래한다.

 

 

13. get_x, get_y 함수의 비밀

 

get_mob_x, get_mob_y 함수가 따로 있음에도 불구하고

get_x, get_y가 유저나 엔피시 뿐만 아니라 몹의 위치도 가져올 수 있다.

현재까지는 굳이 get_mob_x, get_mob_y를 써야할 이유를 찾은 바 없다.

또 비슷한 사례로, myid()도 objid()로 대체하여 써도 아무 문제 없었다.

이런 경우 유저와 몹에게 사용하는 함수를 하나로 통일하는 쪽을 택하는 편이 낫지 싶다.

+ Recent posts