[스크립트 강좌 - 간단한 상점부터 인던까지!] 1. 기본지식 nerguri

* 아래 내용은 script_commands.txt 파일의 내용을 한글화한 내용입니다.


형식
---------

명령어와 함수들은 기능별로 묶어 정렬되어 있으나, 대개 특별한 순서없이 나열됩니다:

*명령어의 이름과 선언형식.

설명문

    바로 사용가능 한 예제. 완성되어진 것이 아닌, 어떤 아이디어를 제공할 수 있을 정도만
   적혀있으며 어떻게 작동시키는 지에 대한 부분을 제공.

명령어를 찾고 싶다면, Ctrl+F, (또는 이 문서를 읽고있는 에디터의 찾기 기능을 호출하는 키)를 눌러 *와 같이 명령어 이름을 입력하면 손쉽게 해당 명령어를 찾을 수 있을겁니다.

또 다른 찾기의 좋은 방법이 있다면 알려주세요 :)

구문
------

이 문서에서, 해당 명령어를 사용할 때 반드시 기입해야하는 인자값을 표현하는 방법은 <꺾새>가 붙습니다. 하지만 독자가 실전에서 사용할 때에는 꺽새를 붙이지 마세요 :)
옵션으로써 사용되는(꼭 필요하진 않지만 때에 따라서 넣을 수 있는) 옵션은 {중 가로}가 붙습니다. 역시 마찬가지로 실전에서 사용할 때에는 중 가로를 붙이지 마시기 바랍니다.
옵션 인자값은 순서대로 기입되어야 하며, 여러개의 옵션 명령어가 사용될 땐 다음과 같이 문서에 기입되어 있습니다.:

명령어 <인자>{,<인자>...<인자>}

각 인자들을 구분하는 기호는 ’,’(쉼표)가 쓰입니다.

명령어에 문자열이 붙는 경우에는 “큰따옴표”를 붙이며, 이 뜻은 숫자가 아니라는 것과 같은 말입니다.
일반적인 표현인 값을 반환하는 함수나 연산자를 묶는 (둥근 괄호)를 활용할 수 있습니다.
둥근 괄호는 항상 필요치는 않지만, 쓰면 나중에 도움이 될 것입니다.

맵 이름을 기입할 때에는 ‘맵이름.gat’ 대신에 뒤에 확장자를 제외한 ‘맵이름’이라고 적어도 됩니다.


스크립트 로딩 구조
------------------------

스크립트는 맵서버의 설정파일인 ‘conf/map-server.conf’파일에서는 직접적으로 다루지 않습니다. 실질적으로 스크립트 로딩에는 ‘npc/scripts_main.conf’에 적힌 스크립트들을 불러옵니다.

스크립트가 적힌 텍스트 파일을 읽어오게 하려면 다음과 같이 적습니다.:

npc: <파일이름과 경로>

모든 줄은 위와 같은 형식으로 되어있으며, 궁극적으로 ‘map-server.conf’에서 해당 구문을 해석하여 스크립트 파일을 읽어 사용되어집니다.
똑같은 파일이 중복되어 기입되어 읽혀지면 에러가 발생하게 됩니다.

다음은 또 다른 옵션입니다.:

delnpc: <파일이름과 경로>

이 명령어는 해당 스크립트 파일을 메모리로 읽지 않게끔 합니다.
보통 쓰이진 않으나, 가끔 필요로 인해 쓰일 수가 있습니다.

‘//’이 줄의 가장 앞에 있을 경우, 해당 줄은 코멘트로 간주되어 무시합니다.
이 기능은 어느 곳에서나 사용 가능하며 같은 기능을 합니다.

// 이 줄은 스크립트를 처리함에 있어 무시됩니다.

코멘트 영역이 필요할 때가 있는데, 이럴 때에는 /*과 */사이에 텍스트를 입력하면 해당 영역은 허큘러스에서 무시됩니다.

예제:
/* 이 문서는,
 * 줄이 바뀌어도
 * 다음과 같은 기호가 발견될 때 까지
 * 무시됩니다.: */
 
별표(*)는 각 줄의 가장 앞에 붙이는게 관행일 뿐, 꼭 적으실 필요는 없습니다.

모든 파일들이 로딩 될 때, 서버는 해당 파일의 가장 ‘최상위 명령어’를 실행합니다.
다른 명령어들과는 달리, 이 명령어들은 어떤 명령어에 종속되어지지 않습니다.
(No variables exist yet at this point, no commands can be called other than those given in this section.)
이러한 명령어들은 서버 스크립트의 기초 형식입니다. - NPC오브젝트 생성, 몬스터오브젝트 스폰, 맵플레그 설정, 기타등등.
내용이 없으면 실제로 실행될 때 예외가 발생될겁니다.
‘최상위 명령어’들은 스크립트를 작성할 때 약간 헷갈릴 수 있는데, 다른 명령어들과는 다르게 이름부터 시작되지 않고 맵의 이름부터 시작합니다.

또 한가지 더 헷갈릴 수 있는 부분은 ‘최상위 명령어’들은 각 인자들을 구분할 때, 쉼표가 아닌 Tab을 이용하여 나누어 집니다.

헷갈릴 수 있는 것을 방지하기 위함으로 가독성이 조금 떨어지지만 ‘‘%TAB%’나 ‘<TAB>’으로 표기하고 있습니다. 인수를 표기하기위해 보이지 않는 기호를 쓴다는 것은 스크립트 언어의 나쁜 부분이지만.. 어쩔 수 없네요. :)

이 밑에 적혀있는 것들이 바로 ‘최상위 명령어’ 들입니다.:

** 맵플레그 설정:

<map name> mapflag%TAB%<flag>

이 명령어는 서버에서 로딩될 때, 입력한 맵 이름’<map name>’의 맵을 해당 mapflag ‘<flag>’로 설정합니다.
보통 ‘npc/mapflag’ 안에 있는 파일들이 먼저 로드되고, 그 다음에 서버가 켜지며, 모든 맵들은 각자 flag를 갖게 됩니다. 맵 flag의 문제나 좀 더 자세한 설명을 원한다면 ‘setmapflag’부분을 보세요.

** 몹 생성:

<map name>,<x>,<y>,<xs>,<ys>%TAB%monster%TAB%<monster name>%TAB%<mob id>,<amount>,<delay1>,<delay2>,<event>{,<mob size>,<mob ai>}

‘<map name>’은 몬스터가 생성될 맵 이름을 지정합니다. x, y는 생성될 맵의 상세좌표입니다.
만약 xs와 ys가 0이 아닐 경우에는 생성이 ‘범위’화 되며  x, y좌표를 중심으로 네모 모양의 생성 area가 형성됩니다. 0을 입력할 경우에는 무작위로 몹을 생성합니다. 이 area는 몹생성 지역 초기화 이며, 몹은 랜덤하게 움직이고 생성지역에서 자유롭게 움직입니다.
‘<monster name>’은 화면에 보이는 이름뿐이므로, 원래의 이름과는 전혀 관계가 없으며 또 사용할 수 있습니다. ‘<mob id>’는 몬스터 데이터베이스인 ‘mob_db.txt’에 기록된 몬스터의 식별코드입니다. 만약 ‘<monster name>’을 “--ja--”로 적을 경우, 몬스터 데이터베이스의 ‘japanese name’ 필드의 이름(Hercules에서는 현재 영문으로 되어있음)을 가져오며, “--en--”이라고 적을 경우, ‘english name’ 필드의 이름(GM 명령어를 이용하여 몹을 생성할 때 쓰여지는 몹 이름)을 가져오게 됩니다.

‘<amount>’는 생성될 몹의 마릿수를 지정하며, ‘battle.conf’에서 생성 배율을 설정할 수 있습니다.

‘<delay1>’과 ‘<delay2>’는 몬스터가 재생성 될 때의 딜레이 - ‘<delay1>’은 고정 재생성 시간이고 ‘<delay2>’는 ‘<delay1>’에 추가되는 랜덤한 시간(편차 시간)입니다.
두 값은 밀리초(1000 = 1초) 단위입니다. 주의할 점은 서버는 재생성 시간의 최소값을 5초로 설정하고 있습니다.(너구리: 아니던데...)

‘<monster name>’ 뒤에  쉼표를 넣음으로써 mob_db.txt에 지정된 레벨 이외의 임의의 레벨로 몬스터를 생성시킬 수 있습니다. 예를들면 “포링,50” 으로 ‘<monster name>’을 설정하면 ‘포링’이라는 이름의 몬스터가 레벨 50으로 생성됩니다.

‘<event>’는 몬스터가 죽었을 때 실행되는 스크립트 이벤트입니다. 이 부분은 반드시 “NPC이름::On이벤트이름”으로 적혀야 하며, 라벨 이름은 반드시 “ON”으로 시작되는 라벨이어야 합니다. 터치 NPC인 다른 NPC들과 마찬가지로 트리거된 스크립트는 해당 플레이어를 범주 내로써 실행됩니다.

다른 두가지  ‘<mob size>’와 ‘<mob ai>’는 옵션 인자(필드)입니다. ‘<mob size>’는 0(보통), 1(작은), 2(큰)을 넣을 수 있으며, ‘<mob ai>’는 0(기본값), 1(플레이어 아군), 2(스피어), 3(플로라), 4(zanzou)를 넣을 수 있습니다.

또, 몬스터 생성에는 ‘monster’ 대신에 ‘boss_monster’를 넣으면 SC_CASH_BOSS_ALARM(아이템 12214)으로 미니맵에 표시되는 몬스터를 생성시킬 수 있습니다.

** NPC 이름

/!\ 경고: duplicates NPC와 상점들도 포함되어 적용됩니다. /!\

NPC 이름은 특수한 형태입니다.:

<Display name>{::<Unique name>}

모든 NPC들은 식별이 필요한 고유 이름을 갖습니다. NPC를 식별할 때에는 <Unique name>을 사용해야 합니다. <Unique name>을 지정하지 않으면 <Display name>이 역활을 대신하게 됩니다.

이름을 표시할 때 유저입장에서 특별한 기능이 있습니다: 만약 이름에 ‘#’ 문자가 포함되어 있다면, #부터 시작한 문자열은 보이지 않습니다.
EX: NPC이름을 ‘사냥꾼#hunter1’로 하게 되면, 유저는 해당 NPC의 이름이 ‘사냥꾼’으로만 보이게 됩니다.

<Display name>은 24자(한글은 12자?) 이하로 지정해야 합니다.
<Unique name>은 24자(한글은 12자?) 이하로 지정해야 합니다.

** 워프 포인트 정의

<from map name>,<fromX>,<fromY>{,<facing>}%TAB%warp%TAB%<warp name>%TAB%<spanx>,<spany>,<to map name>,<toX>,<toY>

플레이어를 맵간 워프를 시켜주는 NPC를 정의하며, 대부분의 인자들은 값이 있어야 하지만, 일부는 따로 언급을 해야 합니다(some deserve special mention).

‘<spanx>’와 ‘<spany>’는 캐릭터가 npc를 직접 건들지 않아도 워프시키게금 만드는 것 같지만, ‘<spanx>’로 X축과 ‘<spany>’로 Y축을 걸쳐서 만들어진 워프존에 캐릭터가 걸어 들어간 것 입니다.

워프 NPC 오브젝트도 이름을 가지며, 나중에 ‘enablenpc’나 ‘disablenpc’ 같은 기능을 사용하기 위함입니다.

워프 오브젝트의 방향(‘<facing>’)은 필요없으며(irrelevent), 기입하지 않아도 0으로 설정됩니다.

** NPC 오브젝트 정의

<map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite id>,{<code>}
<map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite id>,<triggerX>,<triggerY>,{<code>}

이 것은 지정한 맵의 지정한 위치에 NPC 오브젝트를 위치시키며, 이 ‘최상위 명령어’는 커스텀 스크립팅에 자주 사용되어집니다. NPC들은 클릭으로써 트리거되며, 정의함으로써 트리거 지역으로 걸어들어갈 경우에도 트리거됩니다. 계속해서 보시죠.

‘<facing>’은 NPC 스프라이트가 바라보는 방향입니다. 모든 NPC가 보는 위치가 다르게금 설정되어있진 않으며, 그러한 NPC에게는 무의미한 값이긴 합니다.
‘<facing>’은 시계 반대방향으로 45도씩 증가하며, 0은 맵 북쪽을 가리킵니다.
(맵의 남쪽은 4이며, 남동쪽을 가리키게 하려면 ‘<facing>’은 5입니다.)

‘<sprite id>’는 NPC를 표시하는데 사용되는 sprite 번호입니다. 모든 sprite id 번호를 보고 싶다면 http://kalen.s79.xrea.com/npc/npce.shtml 를 참조하세요.
몬스터 id를 사용하여 몬스터로 보이게금 할 수 있습니다. 직업 sprite도 물론 사용할 수 있으나, 사용하기 전에 먼저 ‘mob_avail.txt’에 몬스터 sprite로 정의해야 합니다. 이 작업에 대한 자세한 살명은 이 문서에서는 다루고 있지 않습니다.
‘<sprite id>’를 ‘-1’로 설정할 경우, NPC는 보이지 않는(클릭할 수 없는) 상태로 되어집니다.
‘111’로 설정할 경우, sprite가 없는 NPC로 만들어지지만 해당 부분을 클릭하면 NPC가 실행됩니다. 즉, 3D지형을 클릭 가능한 객체로 만들고 싶으면 이 방법을 사용하여 쓸 수 있습니다.

‘<triggerX>’와 ‘<triggerY> 옵션을 주게 되면 NPC를 중심으로 X축으로 ‘<triggerX>’셀 만큼, Y축으로 ‘<triggerY>’셀 만큼의 지역이 형성됩니다.
이 지역으로 캐릭터가 걸어들어가면 NPC가 트리거됩니다. 만약 ‘OnTouch:’가 없다면 스크립트의 가장 처음부터 순서대로 실행이 되며, 바꿔말하면 트리거가 되면 ‘OnTouch:’부터 실행이 됩니다. 걸어들어간 것이 캐릭터가 아닌 몬스터라면 ‘OnTouchNPC:’가 실행됩니다.

‘<code>’ 부분은 NPC가 트리거 되었을 때 실행되는 부분입니다. 명령어와 함수 호출로 이루어져 있으며 이 문서의 대부분이 그것들을 설명하는데 구성되어져 있습니다.
‘<code>’는 중가로로 둘러 쌓여 있으며, 앞에서 말했던 중가로의 의미(옵션으로의 의미)와는 다르게 반드시 실제로 중가로를 입력해야 합니다.

** ‘떠있는’ NPC 오브젝트 정의

-%TAB%script%TAB%<NPC Name>%TAB%-1,{<code>}

일반적인 NPC 오브젝트와는 다르게 트리거되는 것을 정의합니다.
이 오브젝트는 혼자만으로는 아무것도 할 수 없지만, 다른 스크립트가 실행되는 중에 이 스크립트를 사용하여 좀 더 많은 것을 할 수 있게 해주는 오브젝트 입니다.

** 상점/캐시상점 NPC 정의

-%TAB%shop%TAB%<NPC Name>%TAB%<sprite id>,<itemid>:<price>{,<itemid>:<price>...}
<map name>,<x>,<y>,<facing>%TAB%shop%TAB%<NPC Name>%TAB%<sprite id>,<itemid>:<price>{,<itemid>:<price>...}

상점 NPC를 정의하며, 언제 어디서든 트리거(클릭으로만 동작)될 때마다 상점 창을 띄웁니다.
다른 코드가 전혀 필요 없으며(변수고 뭐고 간에 당신을 전혀 귀찮게 하지 않습니다), 각각의 아이템을 다른 가격으로 책정할 수 있습니다.

‘<itemid>’는 ‘item_db.txt’ 데이터베이스에 기록된 아이템의 번호입니다.
만약 ‘<price>’를 ‘-1’로 지정하면, 아이템 데이터베이스에 입력된 ‘buy price’필드의 값으로 대신 책정됩니다. 바꿔 말하면, ‘<price>’에 값을 지정하면 똑같은 아이템을 다른 상점NPC에서 서로 다른 가격으로 판매하게 할 수 있습니다.

일반 상점NPC처럼 캐시상점을 캐시샾 인터페이스로 열 수 있으며, 이 캐시상점은 아이템을 구매하려면 특별한 포인트를 소모해야 합니다(계정 변수인 #CASHPOINTS와 #KAFRAPOINTS). 이 상점은 아이템을 상점에 판매할 수 없으며, 구매만 가능합니다. 구매개수를 정할 수 있는 부분이 따로 있으며, ‘<price>’는 아이템을 구매할 때 소진되는 포인트의 양입니다.

** 워프/상점/캐시상점/NPC duplicate(중복) 정의

워프: <map name>,<x>,<y>{,<facing>}%TAB%duplicate(<label>)%TAB%<NPC Name>%TAB%<spanx>,<spany>
상점/캐시상점/npc: -%TAB%duplicate(<label>)%TAB%<NPC Name>%TAB%<sprite id>
상점/캐시상점/npc: <map name>,<x>,<y>,<facing>%TAB%duplicate(<label>)%TAB%<NPC Name>%TAB%<sprite id>
npc: -%TAB%duplicate(<label>)%TAB%<NPC Name>%TAB%<sprite id>,<triggerX>,<triggerY>
npc: <map name>,<x>,<y>,<facing>%TAB%duplicate(<label>)%TAB%<NPC Name>%TAB%<sprite id>,<triggerX>,<triggerY>

duplicate는 워프/상점/캐시상점/NPC 객체의 ‘라벨’로써 참조합니다.
워프 duplicate는 목적 지역을 상속받습니다.
상점/캐시상점 duplicate는 아이템 목록을 상속받습니다.
NPC duplicate는 스크립트 코드를 상속받습니다.

나머지(이름, 위치, 방향, sprite id, span/트리거 area)는 duplicate를 정의할 때 입력합니다(상속되지 않음).

** 함수 오브젝트 정의

function%TAB%script%TAB%<function name>%TAB%{<code>}

함수 오브젝트를 정의하며, ‘callfunc’ 명령어(후에 나옴)로 호출할 수 있습니다. 이 오브젝트는 모든 맵 서버에서 호출할 수 있으며, 어디서든지 호출할 수 있습니다. 함수 오브젝트는 ‘callfunc’ 스크립트 명령어 이외에 다른 방법으로는 호출할 수 없습니다.

‘<code>’부분은 ‘callfunc’으로 호출되었을 때 실행되어지는 스크립트 코드입니다. 중가로로 둘러 쌓여 있으며, 앞에서 말했던 중가로의 의미(옵션으로의 의미)와는 다르게 반드시 실제로 중가로를 입력해야 합니다.

이 오브젝트에 ‘<code>’필드가 정의되어있다면, 포함된 스크립트 명령어들은 실제로 트리거되어지고 실행되어 집니다.

~ RID? GID? ~

RID가 무엇이며 왜 알아야 하는가
-----------------------------------------

스크립트 명령어와 함수들은 대개 클라이언트와 연결된 캐릭터의 데이터, 캐릭터에 저장된 변수 값을 요구합니다. 스크립트가 캐릭터에 의해 호출될 때 전달하는 소위 RID - OnTouch 영역으로 걷었거나 클릭하여 코드를 실행한 캐릭터, 또는 기타의 계정 ID번호 입니다.

기본적인 NPC를 작성할 때는 이것이 필요하다고 느껴지지 않습니다.
하지만 함수를 사용하거나, 타이머를 사용하거나, 시간 개념을 사용하여 스크립트를 작동시킨다면 RID를 attach시키지 않고 트리거시킬 수 있는 방법을 찾아야 할 것입니다.

RID없이는 캐릭터에 대한 상세정보, 클라이언트가 보낸 값, 캐릭터에 저장된 값들을 거의 모든 명령어와 함수는 알 수 없습니다.
‘attachrid’를 사용하지 않는 한, 스크립트는 캐릭터를 attach합니다. (플레이어 관련 명령어 참조)

우리가 말하는 ‘연결된 캐릭터’란, 실행중인 스크립트와 연결된 캐릭터의 RID를 말합니다.
스크립트 함수인 “playerattached”는 현재 스크립트와 연결된 캐릭터의 상태를 확인할 때 사용됩니다. (반환값이 0인 경우는 플레이어가 연결되어 있지 않거나 연결된 플레이어가 맵서버에 로그인 되어있지 않음을 의미합니다.)

그럼 GID는?
--- ---- ----- ----
GID는 Game ID의 약자로써, 몬스터 스크립트 명령어(단 하나만 생성시켰을 때)를 통해서 몬스터의 GID를 얻을 수 있으며, getnpcid 스크립트 명령어나 캐릭터(RID와 동일)의 계정 ID를 통해 GID를 얻을 수 있습니다. 또 다른 방법으로 GM sprite 캐릭터로 몹, NPC, 캐릭터들을 우측클릭하여 GID를 볼 수 있습니다.

아이템과 큐펫 스크립트
--------------------

아이템 데이터베이스의 각각의 아이템들은 3개의 특수한 필드 - Script, OnEquip_Script, OnUnequip_Script를 갖고 있습니다. 가장 처음의 Script 필드는 캐릭터가 장착했을 때 실행되어 장착된 캐릭터의 RID를 갖습니다.
아이템을 장착 해제할 때마다 보너스 옵션은 초기화 되며, 모든 스크립트는 다시 재구성되어 실행됩니다. 이 같은 일은 여러 상황(로그인 같은)에서 발생하지만 현재 전체목록은 알 수 없습니다.

OnEqup_Script는 캐릭터가 더블클릭 했을 때 실행되는 스크립트 코드 조각입니다.
OnUnequip_Script는 캐릭터가 장비를 해제할 때 실행되어집니다.

모든 스크립트 명령어가 아이템 스크립트에서 작동되진 않습니다.
Where commands and functions are known to be meant specifically for use in item scripts, 
they are described as such.

펫 데이터베이스의 모든 펫은 PetScript 필드를 갖고 있으며, 펫의 동작을 결정합니다.
펫이 생성될 때(부화, 또는 펫이 따라다닐 캐릭터가 캐릭터서버로 로드될 때) 연결됩지만 다른 상황에서도 발생할 수 있습니다.
그리고 절대로 큐펫 스크립트에서 사용가능한 명령어 이외의 다른 명령어가 정상적으로 실행될 거라고 기대하지 마세요.

숫자
-------

일반적인 10진수 숫자를 말하며, 다른 것도 아니며(이 언어에서는 모두 정수이므로 소수는 생각도 안함), 스크립트 엔진은 16진수도 마찬가지로 동일하게 처리합니다. ‘0x<16진수>’같은 수를 적으면 16진수로 인식합니다. 0x10은 16과 같습니다. 만약 ‘mes 0x10’이라고 스크립팅을 하면 결과는 ‘16’으로 나올겁니다.

숫자 값은 정수 최대치를 넘을 수 없습니다: INT_MAX(2,147,483,647) 보다 큰 수나, INT_MIN(-2.147.483.648)보다 작은 수를 입력하면 경고를 발생시킵니다.

변수
---------

모든 프로그래밍 언어에서 보는 변수 - 데이터를 저장하는 곳입니다.

Hercules 스크립팅 언어에서, 변수 이름은 대소문자를 구분합니다. 
스크립트 엔진이 캐치하지 못하고 그냥 넘어간다 하더라도 그것을 믿고 그냥 넘어가지 않는게 좋습니다.

변수는 나누어진 고유 조합에 의해 식별됩니다:
접두  - 변수의 영역 및 범위(생명주기)를 결정
이름  - ‘_’와 알파벳으로 구성된 식별자
접미  - 변수의 타입을 결정: 정수 또는 문자열

영역은 다음과 같습니다:
글로벌    - 모든 서버 공통
로컬    - 하나의 서버 내부
계정  - RID로 식별되는 캐릭터의 계정과 연결
캐릭터- RID로 식별되는 캐릭터와 연결
npc       - NPC와 연결
scope     - 인스턴스 범위에 연결

범위는 다음과 같습니다:
permanent(영구) - 서버가 리셋되도 남아있습니다.
temporary(임시) - 서버가 리셋되면 없어집니다.

접두: 영역 및 범위
명시하지 않음 - 영구적인 캐릭터 변수로써, 변수의 기본 형식입니다.
계정 데이터인 ‘global_reg_value’ 테이블에 타입 3으로 저장되어 집니다.
"@"      - 임시적인 캐릭터 변수입니다.
           캐릭터가 로그아웃할 때 사라집니다.
"$"      - 영구적인 글로벌 변수입니다.
           데이터베이스 테이블 `mapreg`에 저장됩니다.
"$@"     - 임시적인 글로벌 변수입니다.
           RID없이 호출될 수 있는 중요한 것으로, 캐릭터에게 트리거되지 않고도 사용이
           가능합니다.
"."      - NPC 변수입니다.
           NPC 안에 저장되며 서버가 재시작되거나 NPC가 다시 불러질 때(리로드) 사라집니다.
           NPC 안에서 접근할 수 있으며 ‘getvariableofnpc’로 불러들일 수 있습니다.
           함수 오브젝트에서도 .변수를 함수내에서 접근할 수 있으나, ‘getvariableofnpc’는
           함수 오브젝트에서 작동하지 않습니다.
".@"     - scope 변수 입니다.
           한정적인 변수입니다. 스크립트가 종료될 때까지만 유효한 변수입니다.
           callsub/callfunc으로 함수를 불렀을 때 시작되며, 함수가 반환될 때 종료됩니다.
           영역이 끝났을 때 변수는 값으로 변환됩니다.
"'"      - 인스턴스 변수입니다.
           인스턴스 시스템에 쓰여지며, 각 파티의 인스턴스마다 고유한 식별을 가집니다.
"#"      - 영구 로컬 계정 변수 입니다..
           'global_reg_value' 테이블의 타입 2로 저장됩니다.
"##"     - 영구 글로벌 계정 변수로 로그인서버에 저장됩니다.
           'global_reg_value' 테이블의 타입 1로 저장됩니다.
           하나의 로그인서버에 여러개의 캐릭터서버가 접속되어있는 때 제기능을 합니다.
           # 변수는 각각의 캐릭터 서버마다 틀리지만, ## 변수는 모든 캐릭터 서버가 값을
           공유합니다.

접미: 정수 또는 문자열
명시하지 않음-정수 값으로, 양수와 음수를 저장할 수 있지만, 자연수이어야 합니다.
          (수학에서의 ‘소수’는 기대도 하지 마세요).
'$'     - 문자열 변수이며, 텍스트를 저장할 수 있습니다.

예제:
  name  - 영구적인 캐릭터 정수형 변수
  name$ - 영구적인 캐릭터 문자열 변수
 @name  - 임시적인 캐릭터 정수형 변수
 @name$ - 임시적인 캐릭터 문자열 변수
 $name  - 영구적인 글로벌 정수형 변수
 $name$ - 영구적인 글로벌 문자열 변수
$@name  - 임시적인 글로벌 정수형 변수
$@name$ - 임시적인 글로벌 문자열 변수
 .name  - NPC 정수형 변수
 .name$ - NPC 문자열 변수
.@name  - scope 정수형 변수
.@name$ - scope 문자열 변수
 #name  - 영구적인 로컬 계정 정수형 변수
 #name$ - 영구적인 로컬 계정 문자열 변수
##name  - 영구적인 글로벌 계정 정수형 변수
##name$ - 영구적인 글로벌 계정 문자열 변수

변수를 설정하지 않았다면, 정수형일 경우에는 0이, 문자열일 경우엔 빈문자열(“”, 쿼터 사이에 아무것도 없는)변수가 됩니다. 한번이라도 설정을 해놓는다면 절대로 까먹지 않고 저장되며, 캐릭터나 계정 데이터에 저장되어 남겨집니다.

어떤 변수들은 특별한, 아래에 나열된 것들은 스크립팅 엔진으로부터 이미 정의되어져 있습니다. ‘db/const.txt’에서 그것들의 모든 목록을 볼 수 있습니다. 이 파일을 읽었을 경우, 이 문서의 많은 명령어 설명들을 읽는 것에 도움이 될 뿐더러 스크립팅을 할 때 숫자 대신에 넣을 수 있는 값들을 알 수 있게 됩니다.
이런 특별한 변수들은 대부분 영구적인 캐릭터 변수들로 되어져 있습니다:

Zeny        - 현재 제니의 양.
Hp          - 현재 HP의 양.
MaxHp       - 현재 최대 HP의 양.
Sp          - 현재 SP의 양.
MaxSp       - 현재 최대 SP의 양.
StatusPoint - 남아있는 스텟포인트.
SkillPoint  - 남아있는 스킬포인트.
BaseLevel   - 캐릭터 베이스 레벨.
JobLevel    - 캐릭터 직업 레벨.
BaseExp     - 베이스 경험치의 양.
JobExp      - 직업 경험치의 양.
NextBaseExp - 베이스 레벨업에 필요한 남은 경험치의 양.
NextJobExp  - 직업 레벨어벵 필요한 남은 경험치의 양.
Weight      - 현재 캐릭터가 짇고있는 무게.
MaxWeight   - 캐릭터가 짇고있을 수 있는 최대 무게.
Sex         - 남성이면 0, 여성이면 1.
Class       - 캐릭터의 직업번호.
Upper       - 노멀 직업이면 0, 1이면 확장, 2이면 베이비.
BaseClass   - 캐릭터의 1-1 ‘노멀’ 직업이며, Upper을 제외한 값입니다.
              예를들어, Job_Acolyte를 반환하면 프리스트/몽크, 
              하이프리스트/챔피언, 아크비숍/수라입니다.
              캐릭터가 1-1 클래스를 갖지 못했다면 Job_Novice를 반환합니다.
BaseJob     - 캐릭터의 ‘노멀’직업이며, Upper값을 제외한 값입니다.
              예를들어, Job_Acolyte를 반환하면, 베이비 어콜라이트와 하이 어콜라이트 입니다.
Karma       - 캐릭터의 카르마입니다. 카르마 시스템은 아직 완벽하지 않지만,
              그렇다고 동작이 안되는 것은 아닙니다. 아직 테스트가 안되었습니다.
Manner      - 캐릭터의 매너율입니다. 플레이어가 클라이언트쪽의 ‘manner.txt’파일에 적힌
              단어를 입력하여 사용하게 되면 음수로 되어집니다.

변수를 사용하면서, 언제나 항상 잘 동작한다는 기대하지 마세요.
위의 변수가 담당하는 것들을 설정하는 함수나 명령어가 있다면, 차라리 그것을 쓰는게 훨씬 좋습니다.
한가지 예로 Zeny 인데, 이 변수는 캐릭터의 ‘제니의 양’의 대한 주소(address)를 갖고 있습니다.
만약 Zeny를 음수로 설정하면 에러와 함께 스크립트가 중지될 겁니다.

변수의 할당
--------- ---------

‘set’함수를 사용하지 않고 변수에 값을 할당하거나 가져오는 것이 가능합니다.
다른 프로그래밍 언어와 마찬가지로 말입니다.

    @x = 100;
    @x = @y = 100;

변수의 값을 설정하는 ‘set’함수 역시 계속 사용할 수 있습니다.

값을 할당할 때, 모든 연산자들을 지원합니다. 예를들면:

    @x += 100;
    @x -= 100;
    @x *= 2;
    @x /= 2;
    @x %= 5;
    @x >>= 2;
    @x <<= 2;

모두 동작합니다. 연산자에 대한 더 많은 정보가 필요하다면, 아래에 설명된 연산자 부분을 참고하세요. 나열된 연산자 목록은 ‘=’ 앞에 다른 연산자들이 붙으며, 각각의 연산자들을 알맞게 사용할 수 있습니다.

Note:

 !! 현재 스크립트 엔진은 배열의 복사를 직접적으로 할 수 없습니다.
 !! 배열의 복사를 하기 위해서는 ‘copyarray’ 함수를 아직 써야 합니다.

문자열
-------

문자열 안에서 큰따옴표(“)를 사용하려면 앞에 역슬래시(\)를 넣어야 합니다.


배열
------

배열(Hercules 에서)은 여러개의 변수를 하나의 이름에 저장할 수 있습니다.
‘배열 인덱스’를 이용해 배열의 각 변수값들을 지정할 수 있습니다.

<variable name>[<array index>]

배열에 저장된 변수들을 ‘배열 요소’라고 부릅니다. 배열은 일련의 유사한 데이터(아이템 ID같은)를 저장하거나 그룹핑하는데 아주 유용합니다.
일반 변수와 마찬가지로 배열의 값을 설정할 수 있습니다:

    set @arrayofnumbers[0],1;

변수를 사용하여(또는 식, 또는 다른 배열로) 배열의 값을 쉽게 가져올 수 있습니다:

    set @x,100;
    set @arrayofnumbers[@x],10;
    
위의 스크립트는 @arrayofnumbers[100]에 10의 값을 설정합니다.
즉, @arrayofnumbers[100] == 10 입니다.

중요한 점은 인덱스의 숫자는 항상 0부터 시작합니다. 배열은 128개 이상의 길이를 갖을 수 없습니다. (최대 127개)

그리고 인덱스는 음수가 될 수 없습니다. 아직까지 아무도 음수의 배열번호를 테스트하지 않았지만, 별로 좋진 않을 듯 합니다. :)

배열에 문자열을 저장할 수 있습니다:

@menulines$[0]은 문자열 변수 @menulines$의 0번째 배열요소입니다.
주의할 점은 ‘$’기호가 대가로가 인덱스 앞에 붙어있어야 한다는 것입니다.

계속해서 변수와 배열로 사용가능한 범위를 알아보죠.
------ -- --- ------- -------- --- ----- ------

+==========+======+=======+
|변수타입   | 일반 | 배열|
+==========+======+=======+
|$Str$     | OK!  | OK!   |
+----------+------+-------+
|$@Str$    | OK!  | OK!   |
+----------+------+-------+
|@Str$     | OK!  | OK!   |
+----------+------+-------+
|#Str$     | OK!  | FAIL! |
+----------+------+-------+
|Str$      | OK!  | FAIL! |
+----------+------+-------+
|$Int      | OK!  | OK!   |
+----------+------+-------+
|$@Int     | OK!  | OK!   |
+----------+------+-------+
|@Int      | OK!  | OK!   |
+----------+------+-------+
|#Int      | OK!  | FAIL! |
+----------+------+-------+
|Int       | OK!  | FAIL! |
+----------+------+-------+
|.Str$     | OK!  | OK!   |
+----------+------+-------+
|.Int      | OK!  | OK!   |
+----------+------+-------+
|.@Str$    | OK!  | OK!   |
+----------+------+-------+
|.@Int     | OK!  | OK!   |
+----------+------+-------+

변수 참조
-------------------

//##TODO



연산자
---------

연산자는 변수와 숫자로 할 수 있습니다(?).
우리가 다룰 연산자는 일반적인 수학 연산자나 조건 연산자입니다.


+ - 두 개의 숫자를 덧셈합니다. 만약 두 개의 문자열일 경우, 두 개의 문자열이 합쳐져서
    하나의 문자열이 만들어집니다. 숫자와 문자열을 더할 경우엔 결과는 문자열입니다.
    +기호 이외의 다른 연산자들은 문자열과 작동하지 않습니다.
- - 두 개의 숫자를 뺄셈합니다.
* - 두 개의 숫자를 곱셈합니다.
/ - 두 개의 숫자를 나눗셈합니다. 주의해야 할 점은 정수형의 나눗셈이며,
    7/2 의 결과는 3.5가 아니라 3입니다.
% - 두 개의 숫자의 나머지계산을 합니다. 7%2 는 1입니다.

조건 연산자도 있습니다. 이 조건 연산자들은 참이면 1, 거짓이면 0을 결과물로 냅니다.
보통 ‘boolean’이라고 부릅니다. 0은 ‘거짓(False)’를 의미합니다. 0이 아닌 값은 모두 ‘참(True)’ 입니다(홀수, -1, -5, 0 이하의 음수값도 모두 참입니다).

숫자끼리 또는 문자끼리를 비교할 수 있지만, 숫자와 문자는 비교할 수 없습니다.

 ==  - 양쪽이 같으면 참입니다. 문자열일 경우, ‘두 개의 문자열이 완전히 일치한다’
       라는 뜻입니다.
 >=  - 왼쪽의 값이 오른쪽의 값보다 크거나 같을 경우에만 참입니다.
 <=  - 왼쪽의 값이 오른쪽의 값보다 작거나 같을 경우에만 참입니다.
 >   - 왼쪽의 값이 오른쪽의 값보다 클 경우에만 참입니다.
 <   - 왼쪽의 값이 오른쪽의 값보다 작을 경우에만 참입니다.
 !=  - 왼쪽의 값과 오른쪽의 값이 다를 경우에만 참입니다.

예제:

 1==1 는 참입니다.
 1<2 는 참이지만 1>2 는 거짓입니다.
 @x>2 만약 @x 가 3이면 참입니다. 하지면 2일 경우엔 거짓입니다.

‘==’와 ‘!=’만 문자열 비교를 위해 테스트 되었습니다. 이 언어를 이용하여 복잡한 구조의 코딩을 할 수 없기 때문에 알파벳 순으로 문자열을 정렬하는 것은 무의미합니다(?).

동일한 상태도 비교할 수 있습니다:

 && - 양쪽의 비교가 모두 같아야만 ‘참(True)’입니다.
      ('1==1 && 2==2' 는 참입니다. '2==1 && 1==1' 는 거짓입니다.)
 || - 양쪽의 비교 중, 어느 하나만이라도 참이면 ‘참(True)’입니다.

 1==1 && 2==2 는 참입니다.
 1==1 && 2==1 는 거짓입니다.
 1==1 || 2==1 는 참입니다.

논리 비트연산자는 숫자에만 쓰일 수 있으며, 아래와 같습니다:

 << - 좌측 시프트 연산.
 >> - 우측 시프트 연산.
좌측 시프트 연산은 왼쪽에 있는 값을 2진수로 좌측으로 오른쪽의 값만큼 
    이동시킨 값을 말하며, 이 값은 ‘왼쪽 값’ * ‘오른쪽 값’을 한 것과 같습니다.
반면에, 우측 시프트 연산은 왼쪽에 있는 값을 2진수로 우측으로 오른쪽의 값만큼
    이동시킨 값을 말하며, 이 값은 ‘왼쪽 값’ / ‘오른쪽 값’을 한 것과 같습니다.
예제:
set b,2;
set a, b << 3;
mes a;
set a, a >> 2;
mes a;
첫번째 mes 명령어는 16을 표기하며, 2 x (2 x 2 x 2) = 16 라고 보시면 됩니다.
두번째 mes 명령어는 4를 표기하며, 16 / 2 = 8; 8 / 2 = 4 라고 보시면 됩니다.
 &  - And(앤드) 연산.
 |  - Or(오어) 연산.
비트 연산자 AND(&)는 두 개의 데이터를 비교하여, 활성화된 비트들의 대한 결과를 냅니다.
    이것으로 여러가지 것들을 할 수 있지만, 허큘러스에서는 스크립트에서 비트마스크를 만드는데 사용됩니다.

비트 연산자 OR(|)는 2진수 값이 하나라도 1인 값을 해당 2진수 위치를 1로 설정합니다.
    이 것을 사용하여 비트마스크로 사용된 값을 변수에 저장할 수 있습니다. 변수에는 32 비트까지 설정할 수 있습니다. 이것을 사용하여 플레이어의 여러가지 검사를 저장하는 배열 변수 대신, 쉽고 간단하게 쓸 수 있습니다.

비트마스크는 기본적으로 하나의 변수에 다영한 옵션 값을 설정하여 사용됩니다. 현재는 32개의 다른 옵션을 하나의 변수에 설정할 수 있습니다(0부터 31).

예제:
- 기본적인 & 연산자의 비트 예제:
10 & 2 = 2
왜그런가? :
10 = 2^1 + 2^3 (2 + 8), 비트로 하면 1010 입니다.
2 = 2^1 (2), 비트로 하면 (같은 크기) 0010 입니다.
연산자 & (AND)는 활성화된(1) 비트들을 취합한 값을 내므로, 
        예제의 비트들을 &연산한 식이 1010 & 0010으로써, 오직 2^1 자리만 둘 다 1이므로
        2가 됩니다.
- 기본적인 비트마스크 생성 예제:
set @options,2|4|16; // (note: 2+4+16 이나 22와 동일한 값)
if (@options & 1) mes "옵션 1은 활성화되어있습니다";
if (@options & 2) mes "옵션 2는 활성화되어있습니다";
if (@options & 4) mes "옵션 3은 활성화되어있습니다";
if (@options & 8) mes "옵션 4는 활성화되어있습니다";
if (@options & 16) mes "옵션 5는 활성화되어있습니다";
이 스크립트를 실행하면 2, 3, 5번 옵션에 대한 메세지만 보일겁니다
    (우리는 2, 4, 16의 비트만 1로 설정하였죠).
 ^  - Xor.
비트연산자 XOR(eXclusive OR)는 2진수 부분의 두개의 값이 같을 경우
    0으로 설정합니다. 반면에 값이 다르면 1로 설정합니다. 비트마스크를 설정하는
    방법 중에 하나입니다.

예제:
- 첫번재로 퀘스트 현재 진행을 설정합니다:
set inProgress,1|8|16; // 퀘스트 진행인 1,8,16을 설정
- 플레이어가 다른 퀘스트를 시작할 때 비트를 설정합니다:
if( inProgress&2 == 0 ){
// 퀘스트 2를 비트로 설정 (inProgress의 진행중인 비트가
// 현재 0으로 되어 있습니다)
set inProgress,inProgress^2;
mes “퀘스트 2: 뉴비를 찾아서 1시간 동안 도와주세요.”;
close;
}
- XOR로 인해 플레이어는 퀘스트 1이 완료됨:
if( inProgress&1 && isComplete ){
// 퀘스트 1의 비트를 0으로 설정 (inProgress의 진행중인 비트가
// 현재 1로 설정되어있습니다)
set inProgress,inProgress^1;
mes “퀘스트 1 완료!! 훌륭한 연산처리로 Xor 왕조의 비밀을 밝혔습니다.”;
close;
}

오직 숫자만 단항 연산자를 사용할 수 있으며, 다음과 같은 것들이 있습니다:

 -  - 부정.
숫자의 부호를 전환시킵니다. 값이 양수면, 그 반대로 음수가 됩니다.

예제:
set .@myvar,10;
mes "10의 음수는 "+(-.@myvar)+”입니다.”;

 !  - 논리적 부정.
Boolean 값을 반전시켜 표현합니다. 참이면 거짓으로, 거짓이면 참으로
    바꿉니다.

예제:
if(!callfunc("F_dosomething"))
{
mes "뭔가 실패하였다.";
close;
}

 ~  - 비트 부정.
1의 보수로 알려준 것들의 비트를 반전시킵니다. 해제비트를 설정시켜서,
    해당 비트를 소거 시킵니다(0으로 바꿉니다).

예제:
- 퀘스트 2를 비활성화 시키고, 다른 값으르 전부 활성화 시킵니다.
set inProgress,inProgress&(~2);  
        // 이 것은 set inProgress,inProgress&0xfffffffd 와 같은 기능을 합니다.

3항 연산자는 3개의 형태(숫자, 문자열, 불 대수(Boolean))에 사용할 수 있으며,
다음과 같은 것들이 있습니다:

 ?: - 조건 연산자
매우 유용한 예제로써 아래에 있는 식을
Very useful e.g. to replace

if(Sex) mes "..."; else mes "...";

다음과 같이 매우 간단한 표현으로 바꿀 수 있으며,

mes "Welcome, " + (Sex?"Mr.":"Mrs.") + " " + strcharinfo(0);

이외에 다른 if-else 형식 대신에 사용할 수 있습니다. ?:는 우선순위가
굉장히 낮으므로 (항상은 아니지만)괄호로 묶어서 사용하는 것이
좋습니다.

라벨 들
------

스크립트 코드 안에서 사용할 수 있는 라벨들 입니다:

<라벨 이름>:

라벨은 스크립트의 참조부분을 가르키는 것으로, ‘goto’, ‘menu’, ‘jump_zero’ 명령어
사용하여 갈 수 있으며, ‘doevent’와 ‘donpcevent’ 명령어로인해 호출되며, 다른 방식
으로도 사용됩니다. 라벨의 이름은 최대 22자(23번째는 ‘:’)입니다. 22,23,24 것처럼
다른 것들과 혼동되기 쉬운데, 그럴 필요 없이 최소 값인 22자 이하로 사용하면
편합니다. 22자에는 숫자,알파벳,언더바 만으로만 사용할 수 있습니다.
라벨의 이름을 추가하여 사용할 수 있으며, 다음과 같은 몇몇의 특별한
라벨들은 스크립트 엔진이 특수한 상황이 발생되면 실행시킵니다:

OnClock<시간><분>:
OnMinute<분>:
OnHour<시간>:
On<요일><시간><분>:
OnDay<월><일>:

서버시간이 설정된 날짜나 시간이 될 경우 실행되는 라벨들입니다.
<시간>과 <분>은 군용시간(‘0105’는 AM 01:05 입니다)을 기입해야합니다.
<요일>은 Sun,Mon,Tue,Wed,Thu,Fri,Sat 입니다. <월>은 01부터 12이며,
<일>은 01부터 31입니다. 한자릿수 일 경우에 꼭 0을 넣으세요. :)

OnInit:
OnInterIfInit:
OnInterIfInitOnce:

OnInit은 스크립트의 로딩이 완료되어지거나 @reloadscript 명령어를
사용하였을 때마다 항상 실행됩니다.OnInterIfInit은 캐릭터서버와
맵서버가 연결 되었을 때 실행되며, OnInterIfInitOnce는 맵서버와
캐릭터 서버가 다시 한번 연결 되었을 때 실행됩니다.

OnAgitStart:
OnAgitEnd:
OnAgitInit:
OnAgitStart2:
OnAgitEnd2:
OnAgitInit2:

OnAgitStart는 서버가 WoE모드가 되었을 때 실행되며, @agitstart 운영자
명령어나 ‘AgitStart’ 스크립트 명령어가 사용되었는지도 확인합니다.
OnAgitEnd는 WoE모드가 종료되었을 때 비슷하게 동작합니다.

OnAgitinit은 캐릭터서버로부터 연결 초기화 후에 맵서버가 모든 성(castle)
정보, 모든 길드정보를 받았을 때 실행됩니다.

위에 언급된 라벨들은 RID를 필요하지 않으므로, 캐릭터나 계정의 대한
변수들에 접근할 수 없으며, ‘attachrid’(나중에 나옴)를 통해 RID를 받아
사용할 수 있습니다.

위의 6개 중, 3개(OnAgitStart2, OnAgitEnd2, OnAgitInit2)는 WoE SE에서만
동작되며, 이 3개는 다른 3개와는 독립적으로 호출됩니다.

OnTouch:

이 라벨은 NPC 오브젝트에 정의된 트리거 지역에 들어갈 경우 실행됩니다.
라벨이 없으면 스크립트는 NPC의 가장 처음의 코드부터 실행됩니다.
라벨은 트리거된 캐릭터의 RID를 참조(attach)합니다.

OnTouch_:

OnTouch와 같지만, 단 하나의 인스턴스로 실행됩니다. 다른 캐릭터는
기존의 트리거된 캐릭터가 트리거 지역을 빠져나가야지만 실행이 됩니다.

OnPCLoginEvent:
OnPCLogoutEvent:
OnPCBaseLvUpEvent:
OnPCJobLvUpEvent:


이 4개의 라벨들은 각각의 이름처럼 동작합니다.

OnPCDieEvent:

캐릭터가 죽었을 때 동작하는 특수한 라벨입니다. 변수 ‘killerrid’는
캐릭터를 죽인 자의 ID로 설정됩니다.

OnPCKillEvent:

플레이어가 다른 플레이어를 죽였을 때 동작하는 특수한 라벨입니다.
변수 ‘killedrid’는 죽은 캐릭터의 ID로 설정됩니다.

OnNPCKillEvent:

캐릭터가 몬스터를 죽였을 때 동작하는 특수한 라벨입니다.
변수 ‘killedrid’는 몬스터의 클레스로 설정됩니다.

OnPCLoadMapEvent:

캐릭터가 ‘loadevent’로 mapflag가 설정된 맵에 들어올 경우에 동작하는
특수한 라벨이며, 들어온 캐릭터의 RID를 참조(attach)합니다.
이 라벨은 mapflag가 있는 맵에서만 동작을 하는데, 그 이유는 서버 전체
의 모든 캐릭터가 맵을 바꿀 때 마다 트리거되기 때문입니다.
1,000에 플레이어가 있다고 생각해보세요(어휴…)

다른 스크립트 명령어와 연관되지 않는 특별한 라벨은 다음과 같습니다.
다른 종류의 라벨처럼 유사한 방식으로 트리거되며, 연관된 명령어와
함께 설명되어 있습니다.

On<라벨 이름>:

이 특별한 라벨은 주로 Mob 스크립트와 함께 사용되며, 몹이나 다른 NPC를
지칭/링크하는 명령을 요구하는 스크립트 명령어에 시작지점 라벨이름을
줍니다. 라벨이름은 좋을대로 쓸 수 있으나, 반드시 앞에 On이 붙어야 합니다.

예제:

monster "prontera",123,42,"포링0호기",2341,23,"마스터::OnThisMobDeath";

amatsu,13,152,4 script 마스터 767,{
mes "안녕하시오.";
close;

OnThisMobDeath:
announce "어이, 포링0호기를 죽였구만 "+strcharinfo(0)+"여.",bc_blue|bc_all;
end;
}

포링0호기를 죽이면 모두에게 파란색글씨로 해당 메세지가 공지로 뜹니다.

"글로벌" 라벨

라벨과 doevent와 함께 포함됩니다. 라벨을 콜했을 경우(doevent를 사용하여)와
NPC의 트리거 지역에서 라벨을 콜했을 경우, 라벨은 “글로벌”하게 공용으로
종료되어야 합니다(i.e 만약 rid가 트리거 지역 밖에 있으면 doevent로 호출하여도
아무런 소용이 없으며, 이유는 OnTouch가 작동하기 때문입니다). npc.c 파일의
npc_event를 참조하세요.

스크립팅 명령어와 함수들
--------------------------------

명령어와 함수는 특별한 순서없이 나열됩니다. 다른 명령어와 함수와는 차이가
있는 - 명령어에 반환값이 없기 때문에 조건문을 사용하려면 명령어의 인자로,
또는 저장되어지는 변수로 사용해야 합니다.
Calling commands as if they were functions will sometimes work,
but is not advised, as this can lead to some hard to track errors.
Calling functions as if they were commands will mess up the stack,
so 'return' command will not return correctly after this happens in
a particular script.

모든 명령어는 마지막에 ‘;’로 끝나야 합니다. 
사실 ‘;’로 여러개의 명령으로 된 하나의 줄을 끊을 수 있을 것 같지만.
안하는게 지만, 당신이 그것을 잘 할 수만 있다면 스크립트엔진은
잘 처리할 겁니다.

명령과 함수의 이름의 대소문자 구분을 꼭 하시기 바랍니다. 스크립트 엔진이
잘 처리는 해주겠지만 추천하지 않는 부분이며, 결국엔 대소문자 구분을 다시
해야할 겁니다.

덧글

댓글 입력 영역