본문 바로가기
프로그래밍/Pawn

Pawn 기초문법

by 알용 2012. 4. 11.
반응형

머리말

Pawn 카테고리 제일 첫번째 글을 보면 Pawn을 소개하는 내용 중에 C언어와 문법이 비슷하다고 되어 있는데
몇가지를 제외하고는 C언어와 문법이 정말 많이 비슷하다.
고로, C언어를 학습한 분들이라면 낯설지 않게 Pawn을 익힐 수 있다.
Pawn의 가장 기초문법만을 간단하게 설명하고 이번 장은 마치도록 하겠다.
이 글 이후로는 모드메이커들을 위한 스크립트들을 포스팅할 것이다.



1. main 함수

pawn에도 main 함수가 있을까? 물론, 있다.
서버 구동 파일인 samp-server.exe 를 실행시키면 main 함수가 실행되고 나서 OnGameModeInit 콜백이 호출된다.
print 함수나 printf 함수로 콘솔(도스)창에 텍스트 출력이 가능하다.

2. 연산자

프로그래밍 언어의 연산자는 거의 대부분 비슷하다.
대입연산자, 산술연산자, 비트연산자, 관계연산자, 논리연산자 모두 C언어와 동일하다.

3. 변수

Pawn은 변수의 자료형(Data Type)이 조금 특이하다.
C/C++언어를 예로 들면 정수형은 int, 문자형은 char, 실수형은 double, 논리형은 bool을 사용한다.
하지만 Pawn에서는 변수 선언의 키워드가 모두 new 이다.
아래 표를 참고하길 바란다.

 C/C++

Pawn 

 int num;

 new num;

 char str[64];

 new str[64]; 

 double radius;

 new Float:radius; 

 bool remain; 

 new bool:remain; 


4. 제어문

제어문(if, switch, break, continue)은 switch문만 제외하고 C언어와 동일하다.
C언어에서는 case 구문마다 break 제어문을 넣어주어야
해당 case 구문이 참일 때 아래 거짓인 case 구문을 실행하지 않고 switch문을 종료하는데
Pawn에서는 break 제어문을 넣어주지 않아도 case 구문마다 break가 걸린다.
오히려 break문을 넣어주면 에러가 나게 된다.

그리고 또 한가지, Pawn에서는 다음과 같은 문법 사용이 가능하다.

switch( num )
{
case 1..5:
    명령문;
case 6..10:
    명령문;
}

최소값..최대값 식으로 case 구문의 값을 설정해주어 사용할 수 있다.

5. 반복문

C언어와 완전하게 동일하므로 자세한 설명은 생략하겠다.
while, do~while, for 사용이 가능하다.

6. 함수

C언어에서는 함수의 반환형(Return Type)이라고 해서 void, int, char 등등
함수가 반환할 데이터의 자료형을 지정해주었는데
Pawn에서는 "이건 함수의 본체다" 라고 알려줄 키워드 하나만 필요하다.

stock 함수명(파라미터)
{
    명령문;
}

이것이 Pawn에서의 사용자정의 함수 구현이다.
C언어에서는 void형을 제외한 다른 자료형으로 함수를 구현하면 반환값을 꼭 지정해주어야 했다.
하지만 Pawn에서는 함수의 반환형을 적어주지 않기 때문에 값의 리턴이 필요하면 적고, 그렇지 않으면 적지 않는다.

7. 배열

배열도 C언어와 동일하지만 변수 설명과 마찬가지로 자료형은 new 밖에 없다.

cell이 5개인 정수형 배열을 선언하려면 new arr[5];
cell이 5개인 문자형 배열을 선언하려면 new str[5];
cell이 5개인 실수형 배열을 선언하려면 new Float:dbl[5];

변수 선언과 동일하다고 보면 된다.
 

8. 포인터

없다, 고로 동적 메모리 할당도 불가능하다.

9. 구조체
    
    C언어에서는 구조체를 사용하기 위해 struct 키워드를 사용하지만
    Pawn에서는 C언어에서 열거형으로 사용하던 enum을 구조체화하여 사용한다.
    다음은 플레이어의 정보를 담고 있는 Pawn형 구조체이다.

    enum pInfo
    {
        pPassword[64],
        pLevel,
        pMoney
    };
    new PlayerInfo[MAX_PLAYER][pInfo];

    이런식으로 구현한 뒤에 3번 플레이어의 레벨을 5로 조정하려면
    PlayerInfo[3][pLevel] = 3;
    이런 식으로 명령문을 구현하면 된다.

10. 파일 입출력

가능하다.
fopen, fclose 등의 함수가 구현되어 있고 파일입출력이 어려운 분들은 dini 헤더파일을 참고 및 사용하면 된다.
다만, RP 모드와 같이 저장할 데이터가 많은 모드에는 dini 사용을 비추천한다.
dini 구조상 한줄 한줄 데이터를 읽을 때마다 파일을 열고닫고 반복 수행하기 때문에 속도가 굉장히 느리기 때문이다.
본인의 환경에 맞게 잘 선택하길 바란다.

11. 전처리기

    #include, #define, #pragma, #error 등 전처리기 사용이 가능하며
    물론 전처리기를 이용한 조건부 컴파일도 가능하다.

12. 모듈화 프로그래밍

    불가능하다, 어떤 실력 있는 모드메이커가 필터스크립트를 모드에 장착하는 식으로
    모듈화 프로그래밍을 시도해보았었는데 결과는 실패였다.
    어쩔 수 없이 소스파일 하나에 모든 내용을 집어넣어야 한다.
    고로 헤더파일을 적절히 분리해야 하고 코드 정리도 유지,보수가 쉽게 해놓아야 한다.


Pawn이 C언어 문법과 비슷하다 보니 C언어와 비교해가면서 어떤 점이 같고 어떤 점이 다른지 적어보았고
이제 SAMP 모드가 서버에서 어떤 식으로 구동되는지 설명하겠다. 

SAMP에는 수많은 멀티 서버들이 존재하고 유저들이 서버 리스트에서 원하는 서버에 들어가 플레이하게 된다.

서버에 들어가게 되면 각각 플레이어 번호(playerid)를 부여받게 되는데

모드메이커는 이 플레이어 번호를 이용해 모드를 구현해야 한다.

플레이어가 서버에서 특정한 행동을 할 때마다(이벤트 발생) 모드에 있는 기본 내장 콜백함수가 호출되는데

Windows Programming을 할 때 운영체제에서 받아온 Message에 따라 알맞은 처리를 하는 것과 같다.

비슷한 예로 VB 에서 이벤트가 발생했을 때 호출되는 프로시저와 비슷하다.

예를 들어, 플레이어가 서버에 접속한다면 모드 내에서 OnPlayerConnect 콜백함수가 호출이 되는데

플레이어가 서버에 접속했을 때 "안녕하세요" 라는 메시지를 보내주고 싶거든

public OnPlayerConnect(playerid)
{
    SendClientMessage(playerid, 0xFFFFFFAA, "안녕하세요");
    return 1;


라고 구현하면 된다.

이벤트가 발생하면 이벤트 정보를 담은 콜백 함수가 실행되고 매개변수 정보를 이용해 그에 맞는 처리를 해주는 것이다.

SAMP Mode가 전부 기본 내장 콜백함수에 의존해서 프로그래밍을 하게 된다.

콜백함수 몇가지를 소개하겠다.

OnGameModeInit()                                            서버 구동기에 의해 모드가 서버에 Load 되었을 때 호출
OnGameModeExit()                                           서버 구동기에 의해 모드가 서버에 Exit 되었을 때 호출
OnPlayerRequestClass(playerid, classid)            플레이어가 서버에 접속하고 캐릭터 Class를 고를 때 호출
OnPlayerConnect(playerid)                                플레이어가 서버에 접속했을 때 호출
OnPlayerDisconnect(playerid, reason)                플레이어가 서버에서 나갔을 때 호출
OnPlayerSpawn(playerid)                                  플레이어가 태어났을 때 호출
OnPlayerDeath(playerid, killerid, reason)             플레이어가 사망했을 때 호출
OnVehicleSpawn(vehicleid)                               차량이 Spawn 되었을 때 호출
OnVehicleDeath(vehicleid, killerid)                     차량이 파괴 되었을 때 호출
OnPlayerText(playerid, text[])                            플레이어가 채팅을 입력했을 때 호출
OnPlayerCommandText(playerid, cmdtext[])        플레이어가 명령어를 입력했을 때 호출
OnPlayerEnterVehicle(playerid, vehicleid, ispassenger) 플레이어가 차량에 탑승할 때 호출
OnPlayerExitVehicle(playerid, vehicleid)            플레이어가 차량에서 내릴 때 호출
OnPlayerStateChange(playerid, newstate, oldstate) 플레이어의 상태가 변경될 때 호출
OnPlayerEnterCheckpoint(playerid)                    플레이어가 체크포인트에 들어갔을 때 호출
OnPlayerLeaveCheckpoint(playerid)                   플레이어가 체크포인트에서 나갔을 때 호출
OnPlayerEnterRaceCheckpoint(playerid)            플레이어가 레이스 체크포인트에 들어갔을 때 호출
OnPlayerLeaveRaceCheckpoint(playerid)          플레이어가 레이스 체크포인트에서 나갔을 때 호출
OnRconCommand(cmd[])                                플레이어가 관리자 명령어를 입력했을 때 호출
OnPlayerRequestSpawn(playerid)                    플레이어가 캐릭터 Class를 고르고 Spawn 됐을 때 호출
OnObjectMoved(objectid)                                오브젝트가 움직일 때 호출
OnPlayerPickUpPickup(playerid, pickupid)        플레이어가 Pickup 아이콘을 주웠을 때 호출
OnPlayerKeyStateChange(playerid, newkeys, oldkeys) 플레이어가 SAMP에서 지원하는 이벤트 키를 눌렀을 때 호출
OnRconLoginAttempt(ip[], password[], success) 플레이어가 Rcon Login 을 시도할 때 호출
OnPlayerUpdate(playerid)                                플레이어가 잠수가 아닐 경우 계속 호출
OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) 다이얼로그가 띄워졌을 때


몇가지 더 있지만 다 적자니 너무 많고, 비교적 자주 쓰이는 것들로만 구성해서 적었다.

이와 같이 SAMP Mode 에서는 다양한 콜백 함수를 지원하고 모드메이커는 이를 이용해 시스템을 제작하면 된다.


 


반응형