Pawn Scripting




Giới thiệu

Điều đầu tiên cần biết:
1. Pawn là một ngôn ngữ lập trình. Được điều chỉnh để tạo các chức năng hoạt động trong SA-MP.
2. Để sử dụng ngôn ngữ Pawn, bạn cần có trình biên dịch Pawno.

Lưu ý: Ngôn ngữ Pawn sẽ không thể sử dụng tiếng Việt.


Mục lục

Bài 1. Mở đầu

Bài 1: Mở đầu


Nếu bạn đang tạo một bản mod, thì trước tiên bạn nên viết ra những dòng sau:

#include <a_samp>//Bao gồm trong mod của tất cả các chức năng và calbacks sa-mp.

main
(){}

a_samp.inc là một tệp chứa tất cả các chức năng và công khai của sa-mp.

Bài 2: Public

Public (công khai), đôi khi chúng được gọi là callback (gọi lại).
Callback, tạm dịch là "một hàm được gọi tự động".
Đây là các thủ tục xác định những gì sẽ được thực hiện cho một hành động nhất định, cho dù người chơi đã viết điều gì đó trong cuộc trò chuyện hay bản mod đã được khởi chạy. Mỗi cuộc gọi lại có một tên cụ thể và các thông số cụ thể.
Ví dụ:


public OnPlayerDeath(playerid,killerid,reason)//Dòng xác định loại public, các thông số của nó.
{//bắt đầu hành động

}//kết thúc hành động

Public này chịu trách nhiệm về những gì sẽ xảy ra khi người chơi chết.

playerid - ID của người đã chết
killerid - ID của người đã giết người chơi
reason - lý do (theo nghĩa vũ khí)

public OnPlayerDeath(playerid,killerid,reason) //public
{
   
//điều này mô tả điều gì sẽ xảy ra nếu người chơi chết
}

Vào cuối mỗi public nên có một sự trở lại.
Nếu public là mod, thì hãy nhập return 1;
Nếu public nằm trong tập lệnh, thì hãy nhập return 0;
Nếu bạn đặt return 1; trong script, sau đó sẽ phát ra tình huống sau:
public trong script sẽ không hoạt động!
Ngoại lệ: OnPlayerText.

Public chính.


OnGameModeInit () - các sự kiện khi một mod được tải

OnGameModeExit () - các sự kiện khi một mod dỡ bỏ

OnPlayerConnect (playerid) - các sự kiện khi một người chơi kết nối với máy chủ

OnPlayerDisconnect (playerid, lý do) - các sự kiện khi một người chơi ngắt kết nối với máy chủ. reason - lý do tắt máy.

OnPlayerDeath (playerid, killerid, reason) - các sự kiện khi một người chơi chết. reason - lý do của cái chết.

OnPlayerRequestClass (playerid, classid) - các sự kiện khi người chơi chọn một skin. classid - skin nào hiện đang được chọn.

OnPlayerCommandText (playerid, cmdtext []) - các sự kiện khi người chơi nhập một lệnh. cmdtext - lệnh được sử dụng trong strcmp.

OnPlayerPickUpPickup (playerid, pickupid) - các sự kiện khi người chơi đến pickup. pickupid - ID của pickup

OnPlayerText (playerid, text []) - các sự kiện khi người chơi nhập văn bản vào cuộc trò chuyện. trả lại các loại. Nếu return1; - văn bản người chơi được hiển thị trong trò chuyện nếu trả về 0; - văn bản trình phát không được hiển thị trong trò chuyện.

OnPlayerSpawn (playerid) - các sự kiện khi người chơi xuất hiện.

OnFilterScriptInit () - các sự kiện khi tập lệnh được tải lên máy chủ

OnFilterScriptExit () - các sự kiện khi tập lệnh được dỡ bỏ khỏi bộ nhớ của máy chủ Thực hành.

public OnPlayerDeath(playerid,killerid,reason)//Khi người chơi đã chết.
{
   
//mã được viết
   
return 1;//vì nó là mod.
}

Bài 3: Hàm

Functions - chúng cũng là chức năng ở Châu Phi. Mỗi chức năng, giống như public, có các tham số nhất định. Cú pháp hàm gốc:

GivePlayerMoney(playerid,money);

Chức năng này cung cấp cho người chơi playerid tiền.

Có thể có một hàm với một tham số, ví dụ:


GetPlayerMoney(playerid);

Chức năng này xác định số tiền mà playerid có. Vô ích bởi chính nó, được sử dụng cho các chức năng khác.

Chức năng chính.

SetPlayerHealth(playerid,health); - thiết lập máu cho người chơi

SetPlayerArmour(playerid,armour); - thiết lập giáp cho người chơi

GivePlayerMoney(playerid,money); - thiết lập tiền cho người chơi

ResetPlayerMoney(playerid); - tiền sẽ được đặt lại cho người chơi

ResetPlayerWeapons(playerid); - người chơi mất tất cả vũ khí

GivePlayerWeapon(playerid,weaponid,var1); - cung cấp vũ khí cho người chơi với weaponid và đạn là var1

CreatePickup(model,type,Float:X,Float:Y,Float:Z); - tạo ra môt pickup với model, type là loại pickup và tọa độ là X, Y, Z.
Nếu pickup được tái sinh thì hãy đặt type là 2, còn chỉ một lần thì type là 3.

AddStaticPickup(model,type,Float:X,Float:Y,Float:Z); - pickup được tạo với kiểu loại và tọa độ X, Y, Z

CreateVehicle(modelid, Float:x, Float:y,Float:z, Float:angle, color1, color2, respawn_delay); - tạo ra một phương tiện, với X, Y, Z - tọa độ, angle - góc, color1 - màu xe chính, color2 - màu xe phụ, respawn_deplay - thời gian phương tiện sẽ tải lại khi người chơi rời khỏi.

AddStaticVehicle(modelid, Float:spawn_x, Float:spawn_y,Float:spawn_z, Float:angle, color1, color2); - tạo ra một phương tiện modelid, spawn_x, spawn_y, spawn_z - tọa độ, angle - tọa độ, color1 - màu chính, color2 - màu phụ. Chỉ sử dụng trong OnGameModeInit().

SendClientMessage(playerid, 0xDEEE20FF, "Xin chao."); - gửi một tin nhắn đến người chơi - trong ví dụ sẽ gửi đến người chơi dòng "Xin chao" 

SendClientMessageToAll(0xDEEE20FF, "Xin chao."); - gửi tin nhắn đến toàn máy chủ.

Và bây giờ sẽ thực hành:

public OnPlayerDeath(playerid,killerid,reason)//Игрок умер.
{
//Khởi đầu của public
GivePlayerMoney(killerid,GetPlayerMoney(playerid));//Người chơi killerid (người đã giết) được cấp tất cả số tiền của người chơi (người đã chết).
//Kết thúc hành động
}


Bài 4: Biến số

Nói một cách chính xác, đây là những địa chỉ bộ nhớ có một giá trị nhất định.
Nói một cách đơn giản, đó là một từ có giá trị số,

có một số loại biến:
1. biến máy chủ,
2. biến trình phát,
3. biến văn bản.

1. Các biến máy chủ.

Vì vậy, chúng ta hãy gọi các biến chung.
new server_players=0;

Biến server_players đã được tạo với giá trị bằng 0.

Gán giá trị:
server_players=5;

Biến server_players được đặt thành 5.

Hàm đang thêm vào giá trị của def. số:
server_players+=5;

Chức năng của phép trừ đã trừ đi 5 giá trị của biến:
server_players-=5;

Giá trị +1:
server_players++;

-1 đến giá trị:
server_players--;

Bạn có thể gán một giá trị hàm cho một biến
server_players=GetPlayerMoney(playerid);//biến server_players được đặt vào GetPlayerMoney

Bạn cũng có thể gán một ID cho một biến, ví dụ: một phương tiện vận tải.
new vehicle;//biến được tạo có tên vehicle

vehicle= CreateVehicle (522, 1683, 785.0, 0, 6, 9, -1); // Biến 'vehicle' được đặt thành giá trị của ID xe.

DestroyVehicle (vehicle); // Phương tiện bị phá hủy.

Thực hành:
public OnPlayerDeath(playerid,killerid,reason)//Public
{//Bắt đầu thực hiện
server_players
++;//+ 1 đến giá trị server_players
}//Kết thúc quá trình thực hiện



2. Các biến số của người chơi.

Một biến được gắn với mọi người chơi trên máy chủ.

new player[MAX_PLAYERS]=0;


Một biến trình phát đã được tạo với giá trị bằng 0.

Tại thời điểm này, mỗi người chơi có giá trị là 0.

player[playerid]=5;


Biến trình phát của một playerid trình phát được gán giá trị 5.

Ngoài ra, tất cả các hành động của biến máy chủ đều được thực hiện với biến này.

Thực hành.

new kills[MAX_PLAYERS]=0;//Biến kills đã được tạo. Tất cả người chơi được đặt thành 0.
new deaths[MAX_PLAYERS]=0;//Biến deaths được tạo. Tất cả người chơi được đặt thành 0.

public OnPlayerDeath(playerid,killerid,reason)//Public
{
kills
[killerid]++;//+1 kill cho killerid
deaths
[playerid]++;//+1 deaths cho playerid
}


3. Các biến văn bản.

Biến văn bản là biến mà giá trị của nó chỉ có thể là văn bản.

new string[256];//biến string được tạo (chuỗi)


Một biến như vậy chủ yếu được sử dụng để tạo văn bản có định dạng.

format(string,256," So du kha dung cua ban: %d",GetPlayerMoney(playerid));


%d - một số giá trị số nguyên
%s - một số giá trị văn bản

Biến string đã được gán một giá trị văn bản, được đặt trong dấu ngoặc kép.

Ngoài ra còn có một biến được sử dụng cho tên:

new name[MAX_PLAYER_NAME];


Tên biến được tạo.

Thực hành.
GetPlayerName(playerid,name,256);//Tên người chơi nhận được
format
(string,256," Ten cua ban la: %s",name);//Định dạng văn bản
SendClientMessage(playerid,0xAAFF00,string);//Gửi tiên nhắn cho người chơi

 BÀI 5: Câu lệnh điều kiện

Kiểm tra - một chức năng kiểm tra xem chức năng đã cho có được thực thi hay không. Nếu một chức năng được thực thi,
thì mã cụ thể sẽ được thực thi.
if(một số chức năng)
{
// mã được thực thi khi các chức năng được thự hiện
}


Những điều sau đây có thể được sử dụng để kiểm tra:
1. so sánh các biến hoặc giá trị hàm,
2. liệu một hàm nhất định có đang được thực thi hay không.

1. So sánh các biến.

if(GetPlayerMoney(playerid) >= money)
{
thực thì mã;
}


Trong thử nghiệm này, một phép so sánh được thực hiện:
NẾU player_money >= (lớn hơn hoặc bằng) money
THÌ thực thi mã
Có các kiểu so sánh khác nhau

!= - không bằng
>= - lớn hơn hoặc bằng
<= - nhỏ hơn hoặc bằng to
> - lớn hơn
<- nhỏ hơn
== - bằng

Luyện tập.

new kills[MAX_PLAYERS]=0;//Biến kills đã được tạo. Tất cả người chơi được đặt thành 0.
new string[256];

public OnPlayerDeath(playerid,killerid,reason)//Public
{
kills
[killerid]++;//+1 kill cho killerid
if(kills[killerid] == 10)//nếu giá trị kill của killerid là 10
       
{//Bắt đầu thực thi mã
             
SendClientMessage(playerid,0x000FFF,"Ban nhan duoc $10000 khi tieu diet thanh cong.");//Tin nhắn gửi playerid
             
GivePlayerMoney(playerid,10000);//Cho playerid $10000
       
}//Kết thúc
}



2. Thực hiện một chức năng nhất định.

Kiểm tra xem chức năng đã cho có đang chạy hay không.

if(IsPlayerConnected(playerid))
{

}


Kiểm tra được thực hiện để xem liệu người chơi có được kết nối với máy chủ hay không.

Thực hành.

public OnPlayerCommandText(playerid,cmdtext[])//Public (chức năng này chỉ sử dụng khi không có thư viện cmd hỗ trợ)
{
   
if(strcmp(cmdtext,"/testmessage",true)==0)//Kiểm tra xem lệnh /testmessage được thực thi hay không
   
{//Bắt đầu thực thi lệnh
           
SendClientMessage(playerid,0xAFF00000,"Lenh da duoc thuc thi.");
           
return 1;//trả về ở đây
   
}//Kết thúc
   
return 1;
}


Tất nhiên, có một chức năng được sử dụng khi kiểm tra không thành công.

Nó được gọi là khác. Được sử dụng như thế này.

public OnPlayerCommandText(playerid,cmdtext[])
{
   
if(strcmp(cmdtext,"/testmessage",true)==0)
   
{
           
if(IsPlayerAdmin(playerid))//người chơi có phải là quản trị viên hay không (rcon)
           
{
           
SendClientMessage(playerid,0xAFF00000,"Lenh da duoc thuc thi.");//Nếu là admin, hàm này sẽ được thực thi
           
}
           
else SendClientMessage(playerid,0xAFF00000,"Ban khong phai la quan tri vien.");//Nếu không thì chức năng này sẽ thực thi thay vì cái trên.
           
return 1;
   
}
   
return 1;
}


Bài 6: Tạo ra một public mới

Một public mới được tạo như thế này:

forward SetPlayerMoney(playerid,money);


Nó được tạo ra để gọi một số chức năng cùng một lúc.

Ví dụ như chức năng đặt tiền.

forward SetPlayerMoney(playerid,money);//đã tạo public

public SetPlayerMoney(playerid,money)
{
   
ResetPlayerMoney(playerid);//Đặt lại tất cả tiền của playerid
   
GivePlayerMoney(playerid,money);//Người chơi sẽ nhận được tiền
}


Bài 7: Hẹn giờ


Hẹn giờ - một chức năng gọi một chức năng nhất định tại một thời điểm nhất định.
Hàm có thể được gọi một lần hoặc lặp lại trong các khoảng thời gian xác định.

Để treo bộ đếm thời gian trên một public cụ thể, một chức năng như vậy được tạo ra.

SetTimer("NewPublic",1000,1);


Có 1000 mili giây thì sẽ bằng 1 giây.

1000 - một khoảng thời gian được chỉ định tính bằng mili giây, sau đó public được khởi động lại.
1 - loại hẹn giờ. Nếu được đặt thành 1, thì bộ hẹn giờ sẽ được khởi động lại với số lần vô hạn. Nếu 0, thì bộ hẹn giờ
chỉ gọi công khai lần đầu tiên.

Lưu ý: bạn không nên đặt giá trị hẹn giờ <100, điều này có thể gây ra tải cho bộ xử lý.

Ví dụ sử dụng:

public OnGameModeInit()
{
   
SetTimer("AllMessage",120000,1);//Bộ đếm thời gian đã được tạo, đưa lên public NewPublic.
   
//Hẹn giờ chạy 2 phút một lần
}

forward
AllMessage();

public AllMessage()
{
   
SendClientMessageToAll(0xAFDAFD00," >> Ma da duoc thuc thi.");
   
//Tin nhắn. Gửi đến tất cả người chơi 2 phút một lần.

Bài 8: Chu kỳ


Vòng lặp là một hàm lặp trên tất cả các giá trị của một
biến nhất định, trong các giới hạn được chỉ định.

Mã chu kỳ:

for(new i=0;i<50;i++)//chu kỳ
{//thực thi chu kỳ

   
GivePlayerMoney(i,1000);//tiền được cho (playerid = i)
   
GameTextForPlayer(i,"~r~Nhan tien!",1000,1);//Tin nhắn trên màn hình
   
//Tôi lặp lại tất cả các giá trị của i, hóa ra là hàm được thực thi cho tất cả người chơi có ID<50

//kết thúc
}

Lưu ý: không đặt giới hạn vòng lặp trên MAX_PLAYERS (500). Điều này gây ra
tải nặng cho bộ xử lý.

Một ví dụ về việc sử dụng một vòng lặp.

public OnGameModeInit()
{
   
SetTimer("TTimer",120000,1);//Bộ đếm thời gian được tạo.
}

forward
TTimer();//public được tạo

public TTimer()
{
   
for(new i=0;i<50;i++)//Lặp qua tất cả các giá trị của i lên đến 50.
   
{
       
SendClientMessage(i,0xAFAFAF," >> Lenh nay da duoc thuc thi.");//Một thông báo được gửi đến tất cả người chơi có ID <50.
   
}
}

Bài 9: Define


Tính năng này hiếm khi được sử dụng. Cho phép một từ để "đặt" một từ khác.

#define COLOR_ZEL 0x00FF00AA


Từ COLOR_ZEL hiện được trình biên dịch hiểu là một mã màu cụ thể.

Bài 10: enum


enum là thứ cho phép bạn tạo nhiều địa chỉ của một biến.

Ví dụ:

enum PVar
{
   
PHealth,
   
PArmour
}

Tại đây, các tiểu mục PHealth, PAmour được tạo tại địa chỉ PVar.

new PlayerVar[MAX_PLAYERS][PVar];


Bây giờ người chơi có thể đặt một số địa chỉ trên một biến trình phát.
PVar có nghĩa là PHealth hoặc PArmour.

Tất nhiên, enum cũng có thể được sử dụng trong biến chia sẻ (máy chủ).

enum SVar//Đã tạo địa chỉ SVar với các tiểu mục Players và AllPlayers
{
   
Players,
   
AllPlayers
}

new PlayerServer[SVar];


Ví dụ về cách sử dụng.

enum Var1//Đã tạo địa chỉ Var1 với các tiểu mục PBank, PKills và PDeaths.
{
   
PBank,
   
PKills,
   
PDeaths
}

new PlayerVar[MAX_PLAYERS][Var1];//Đã tạo biến với các địa chỉ đã cho

public OnPlayerDeath(playerid,killerid,reason)
{
   
PlayerVar[playerid][PDeaths]+=1;//+1 tới địa chỉ của PDeaths biến người chơi
   
PlayerVar[killerid][PKills]+=1;//Thêm +1 vào địa chỉ PKill biến người chơi
}


Bổ sung 1. Làm việc với zcmd.

zcmd là bộ xử lý lệnh giúp tạo lệnh với biến dễ dàng hơn (bỏ qua strtok), nó được sử dụng rộng rãi tại Việt Nam.

Nói chung, bản thân thư viện zcmd được tạo bằng cách sử dụng định nghĩa. Mật mã:

#define COMMAND:%1(%2)          \
			forward cmd_%1(%2); \
			public cmd_%1(%2)

#define CMD:%1(%2) \
			COMMAND:%1(%2)

#define command(%1,%2,%3) \
			COMMAND:%1(%2, %3)

#define cmd(%1,%2,%3) \
			COMMAND:%1(%2, %3)

Bản thân lệnh được tạo như thế này:

CMD:testcmd(playerid, params[])
{
   
new player1;//biến player1
    player1
= strval(params[0]);//player1 được gán một tham số giá trị số [0]
   
if(IsPlayerConnected(player1))//Kiểm tra xem người chơi đã được kết nối với máy chủ chưa
   
{
       
if(IsPlayerAdmin(playerid))//Nếu là quản trị viên
       
{
             S
etPlayerHealth(player1,100);//Chỉnh máu cho người chơi
       
}
   
} return 1; }


Phụ lục 2. Làm việc với strtok.

strtok là một hàm tương tự như zcmd. Cho phép bạn tạo các lệnh với các biến.

Chính hàm strtok.

strtok(const string[], &index)
{
   
new length = strlen(string);
   
while ((index < length) && (string[index] <= ' '))
   
{
        index
++;
   
}

   
new offset = index;
   
new result[20];
   
while ((index < length) && (string[index] > ' ') && ((index - offset) < (sizeof(result) - 1)))
   
{
        result
[index - offset] = string[index];
        index
++;
   
}
    result
[index - offset] = EOS;
   
return result;
}


Chúng tôi chuyển cho OnPlayerCommandText công khai. Đầu tiên, chúng tôi viết mã ở đó:

new cmd[256],idx;
cmd
= strtok(cmdtext,idx);

Hãy tạo lệnh:

if(strcmp(cmd,"/healplayer",true)==0)//Kiểm tra lệnh đã nhập
{
   
new tmp[256];//Tạo 1 biến tmp[256]. Bắt buộc đối với strtok
   
new splayer;//Tạo một biến được chia sẻ

   
//Dưới đây là mã cho biến trong lệnh. splayer có thể được thay thế bằng bất kỳ biến thích hợp nào khác
    tmp
= strtok(cmdtext,idx);
   
if(!strlen(tmp))
   
{
       
SendClientMessage(playerid,0xFFFFF00,"Su dung: /healplayer [playerid]");
   
}
    splayer
= strval(tmp);

   
if(IsPlayerConnected(splayer))//Người chơi có trên máy chủ không?
   
{
       
if(IsPlayerAdmin(playerid))//Bạn có phải là quản trị viên rcon?
       
{
           
SetPlayerHealth(splayer,100);//Người chơi được nhận 100 máu.
       
}
       
else SendClientMessage(playerid,0xFFFFF00,"Ban khong phai la quan tri vien!");//Nếu không đủ điều kiện
   
}
   
else SendClientMessage(playerid,0xFFFFF00,"Nguoi choi chua ket noi.");//Nếu chua kết nối
   
return 1;
}


Vậy là xong, nhóm đã được tạo ra.

- Toàn bộ bài học đã được hoàn thành ngắn gọn -
- Tác giả: Không xác định -