[Tutorial] Descomplicando o ZCMD e SSCANF

12 de jan. de 2013.
O meu objetivo neste tutorial é ensinar do modo mais fácil para quem ainda não é familiarizado com o uso do ZCMD e SSCANF, que para muita gente é um bixo de sete cabeças. Antes de começar, certifique-se de obter as duas includes.

ZCMD - Download.
SSCANF - Download.

Para instalar é fácil, vá até a pasta onde o seu pawno está e coloque-os na pasta include.
Ex: C:\Program Files (x86)\Rockstar Games\GTA San Andreas\pawno\include

No caso do SSCANF, ele irá vir em um .rar já com as pastas definidas, então basta extrair na pasta onde o seu servidor está instalado, no meu caso, a pasta principal do jogo.
Ex: C:\Program Files (x86)\Rockstar Games\GTA San Andreas\

Como ele é um plugin, você tambem deverá abrir o seu server.cfg e adicionar a seguinte linha:

Código:
echo Executing Server Config...
lanmode 0
rcon_password xxx
maxplayers 32
port 7777
hostname Test server
gamemode0 grandlarc 1
filterscripts gl_actions gl_property gl_realtime gl_mapicon ls_elevator test_cmds ls_mall attachments
plugins sscanf
announce 0
query 1
weburl www.sa-mp.com
onfoot_rate 40
incar_rate 40
weapon_rate 40
stream_distance 300.0
stream_rate 1000
maxnpc 10
logtimeformat [%H:%M:%S]
Então adicione as includes no topo do gamemode:
pawn Código:
#include <zcmd> #include <sscanf2>
Após feito isso, tudo iniciará sem problemas.
Estrutura

Estamos prontos para fazer o nosso primeiro comando! Lembre-se de se certificar que seguiu todos os passos anteriores. Mas antes vamos dar uma olhada na estrutura básica dos comandos.

Relembrando que o ZCMD NÃO utiliza a callback OnPlayerCommandText, logo você poderá criar seus comandos abaixo, exemplo:
pawn Código:
public OnPlayerCommandText(playerid, cmdtext[]) {     return 0; } CMD:meucomando(playerid, params[]) {     #pragma unused params // <- É utilizado em comandos que não vão usar os parametros, ou retire o params[]     return 1; }
Se você pretende criar um filterscript/gamemode completamente baseado no ZCMD, você deverá fazer com que a OnPlayerCommandText retorne false, ou uma mensagem de comando inexistente. Vamos a explicação:
Código:
CMD:meucomando(playerid, params[])
{
    #pragma unused params
    return 1;
}
CMD: ou COMMAND: - Função que irá criar nosso comando em ZCMD.
meucomando - nome do comando, no nosso caso seria /meucomando.
playerid, params[] - playerid irá retornar a id do player que executou o comando, params[] são os parâmetros, que nós vamos analizar com o sscanf mais tarde.
O primeiro comando

Vamos começar criando um comando simples de setar a sua própria vida.
pawn Código:
CMD:setarvida(playerid, params[]) {     new Float:vida, string[60];     if(sscanf(params, "f", vida)) return SendClientMessage(playerid, -1, "Use /setarvida [1-100].");         if(vida < 1 || vida > 100) return SendClientMessage(playerid, -1, "Escolha apenas valores entre 1 e 100.");     format(string, sizeof(string), "Você setou sua vida para %.f", vida);     SendClientMessage(playerid, -1, string);         SetPlayerHealth(playerid, vida);     return 1; }
Agora vamos explicar todas as partes do comando:

new Float:vida, string[60]; - Criamos uma variável float para salvarmos a vida que o jogador colocará no comando, e uma string para mandar uma mensagem para o mesmo.

Agora vamos entender como funciona o sscanf, com ele você poderá separar os termos do comando individualmente, por exemplo, se eu utilizar /criarveiculo 411 0 0, com o sscanf você poderá pegar os três numeros e os separar. Tudo bem até agora? Então vamos ver as definições básicas utilizadas no sscanf:

As definições são os tipos de dados que iremos armazenar, ela fica presente entre as aspas, no campo central da função:

if(sscanf(params,"ds", id, mensagem))

i ou d - Integer
Sâo utilizados para numeros INTEIROS, exemplo: 1, 2, 18791...

f - Float
É utilizados para numeros DECIMAIS, exemplo: 0.1, 5.7, 249.998890220110...

s - String
Utilizado para letras, palavras, frases...

l - Logical
Valores boolean, exemplos: true, false.

Então vamos entender o que utilizamos:
if(sscanf(params"f"vida))

params - Definimos que a string/variável que queremos analizar, são os parâmetros do comando.

"f" - Como mostrei na tabela acima, por se tratar de valores relacionados a vida, nós usaremos Float considerando que o valor poderá ser decimal.

vida - string que iremos armazenar o resultado.

Quando nós utilizarmos /setarvida 95.5 por exemplo, o sscanf irá analizar os parâmetros (params) e armazenará o primeiro valor (95.5) float na variável vida.

* Lembrando que o SSCANF irá retornar 1 se o comando não estiver com todos os parâmetros necessários. Por isso fizemos isso:
if(sscanf(params, "f", vida)) return SendClientMessage(playerid, -1, "Use /setarvida [1-100].");

As outras partes do comando são auto-explicativas.
Mais exemplos
pawn Código:
CMD:pm(playerid, params[]) {     new playerdestino, playerNome[MAX_PLAYER_NAME], pdestinoNome[MAX_PLAYER_NAME], mensagem[128], string[128];     if(sscanf(params, "ds", playerdestino, mensagem)) return SendClientMessage(playerid, -1, "Use /pm [ID] [mensagem].");         if(playerdestino == INVALID_PLAYER_ID) return SendClientMessage(playerid, -1, "ID inválida ou inexistente.");         if(!strlen(mensagem)) return SendClientMessage(playerid, -1, "Digite uma mensagem.");     GetPlayerName(playerid, playerNome, MAX_PLAYER_NAME);     GetPlayerName(playerdestino, pdestinoNome, MAX_PLAYER_NAME);         format(string, sizeof(string), "* PM de %s (%d): %s", playerNome, playerid, mensagem);     SendClientMessage(playerdestino, 0xFFFF80AA, string);     format(string, sizeof(string), "* PM para %s(%d): %s", pdestinoNome, playerdestino, mensagem);     SendClientMessage(playerid, 0x6F6F00AA, string);         return 1; }
if(sscanf(params, "ds", playerdestino, mensagem))

Salvamos a ID (número inteiro, então é integer, por isso utilizamos "d") na variável playerdestino, e a mensagem (string, então colocamos o "s"). O sscanf irá seguir a ordem que colocamos, como coloquei [id] [mensagem], o d vem antes do s.

if(playerdestino == INVALID_PLAYER_ID)

Verificamos se a ID que o player digitou existe.

if(!strlen(mensagem))

Verificamos se algo foi digitado na mensagem, e então logo depois, criamos as strings e mandamos a mensagem para ambos os jogadores.
pawn Código:
CMD:criarveiculo(playerid,params[]) {     new id,cor1,cor2,veh, Float:x, Float:y, Float:z, Float:a;     if(sscanf(params,"ddd",id,cor1,cor2)) return SendClientMessage(playerid,-1,"Use /criarveiculo [ID] [COR1] [COR2]");     if(id < 400 || id > 611) return SendClientMessage(playerid, -1, "A ID do veiculo deve ser entre 400 e 611.");     if(c1 > 128 || c2 > 128) return SendClientMessage(playerid, -1, "A ID das cores devem ser até 128.");     if(IsPlayerInAnyVehicle(playerid)) DestroyVehicle(GetPlayerVehicleID(playerid));     GetPlayerPos(playerid,x,y,z);     GetPlayerFacingAngle(playerid,a);     veh = CreateVehicle(id,x,y,z,a,c1,c2,-1);     PutPlayerInVehicle(playerid, veh, 0);     return 1; }
if(sscanf(params,"ddd",id,cor1,cor2))

/criarveiculo 411 1 0

Iremos armazenar a id do veiculo (411 - Infernus) na variável id, a cor primária na variável cor1 e a cor secundária na variável cor2. Verificamos se o jogador está em um veiculo, se estiver o destruimos, então pegamos a posição dele e o ângulo no qual o corpo está virado, criamos o carro e o colocamos dentro do mesmo.
Conclusão:
Espero que este tutorial tenha ajudado você a compreender mais sobre como eles funcionam, e como é mais fácil criar comandos com vários parâmetros. Se ainda restar alguma duvida sinta-se a vontade para postar no tópico, e irei responder assim que possível. Se eu esqueci de algo, sinta-se à vontade para comentar.

Creditos: Linow

0 comentários:

Postar um comentário