Descomplicando o ZCMD e SSCANF -
Linow - 10.01.2013
Introduзгo
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:
Код:
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 Код:
#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 Код:
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:
Код:
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 Код:
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...
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 Код:
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 Код:
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.
* ESSE TUTORIAL Й DIRECIONADO AOS INICIANTES EM PAWN.
Re: Descomplicando o ZCMD e SSCANF -
.FuneraL. - 10.01.2013
Duas observaзхes bбsicas, vocк poderia comentar em seu tutorial que o uso disso:
й apenas sу mais um peso ao seu GM, quando vocк nгo estб utilizando, й mais recomendбvel por apenas:
e o Segundo Comentбrio a ser fй eito, й em questгo do if e else if para valores, й muito mais facil utilizar:
pawn Код:
if(Var < 1 || Var > 1) ...
do que utilizar o prуprio if e else if. Mas creio que em restante, ficou legal.
Re: Descomplicando o ZCMD e SSCANF -
Abravanel - 10.01.2013
O que hб de complicado em zcmd e sscanf? Creio que vocк escolheu mau o tнtulo do tуpico.
Sobre o nгo uso de parвmetros, nгo й necessбrio usar
pragma unused.
pawn Код:
CMD:comando(playerid) {
SendClientMessage(playerid,-1,"Hello");
return 1;
}
A respeito dos especificadores, vocк esqueceu de citar muitos.
Sobre o comando
/setarvida, nгo era necessбrio o uso de sscanf pois o comando sу possui um parвmetro.
[]s.
Re: Descomplicando o ZCMD e SSCANF -
Gii - 10.01.2013
Na minha mera opiniгo ZCMD e Sscanf nгo sгo coisas complicadas, o que acontece й que muitos baixam GM prontos (a maioria em strcmp) e preferem nгo perder tempo (na opiniгo deles) em atualizar o algoritmo.
Good Joob!
Re: Descomplicando o ZCMD e SSCANF -
RebeloX - 10.01.2013
Jб tem muitos tutoriais de zcmd, mas й sempre bem vindo outro, atй porque muitos membros tem perguiзa de usar search, mas vou fazer uma observaзгo.
pawn Код:
CMD:meucomando(playerid, params[])
{
#pragma unused params // <- Й utilizado em comandos que nгo vгo usar os parametros
return 1;
}
Em vez de #pragma unused params basta fazer
pawn Код:
CMD:meucomando(playerid)
{
return 1;
}
Outra coisa
pawn Код:
CMD:pm(playerid, params[])
{
new playerdestino, playerNome[MAX_PLAYER_NAME], pdestinoNome[MAX_PLAYER_NAME], mensagem[128], string[128], stringsender[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);
format(stringsender, sizeof(stringsender), "* PM para %s(%d): %s", pdestinoNome, playerdestino, mensagem);
SendClientMessage(playerdestino, 0xFFFF80AA, string);
SendClientMessage(playerid, 0x6F6F00AA, stringsender);
return 1;
}
pawn Код:
if(sscanf(params, "ds", playerdestino, mensagem)) return SendClientMessage(playerid, -1, "Use /pm [ID] [mensagem].");
lembre-se sempre de definir o tamanho mбximo de caracteres, ou seja.
pawn Код:
if(sscanf(params, "ds[128]", playerdestino, mensagem))
Assim o sscanf irб funcionar corretamente.
Deu para ver que vocк usou 2 strings, eu no inicio do sa-mp tinha uma confusгo porque pensava que cada string ficava com os dados ocupados lб para sempre entгo fazia o que vocк fez.
pawn Код:
format(string, sizeof(string), "* PM de %s (%d): %s", playerNome, playerid, mensagem);
format(stringsender, sizeof(stringsender), "* PM para %s(%d): %s", pdestinoNome, playerdestino, mensagem);
SendClientMessage(playerdestino, 0xFFFF80AA, string);
SendClientMessage(playerid, 0x6F6F00AA, stringsender);
Em vez disso faзa
pawn Код:
format(string, sizeof(string), "* PM de %s (%d): %s", playerNome, playerid, mensagem);
SendClientMessage(playerdestino, 0xFFFF80AA, string);
format(stringsender, sizeof(string), "* PM para %s(%d): %s", pdestinoNome, playerdestino, mensagem);
SendClientMessage(playerid, 0x6F6F00AA, string);
Assim vocк nгo irб usar variaveis desnecessбrias obviamente.
Mais uma coisa
pawn Код:
if(playerdestino == INVALID_PLAYER_ID) return SendClientMessage(playerid, -1, "ID invбlida ou inexistente.");
Covem vocк juntar outra verificaзгo, ou seja, verificar se o jogador estб conectado.
pawn Код:
if(playerdestino == INVALID_PLAYER_ID && !IsPlayerConnected(playerid)) return SendClientMessage(playerid, -1, "ID invбlida ou inexistente.");
Bem, por agora й sу isto.
Todos nуs cometemos erros, esses erros nгo sгo erros de sintaxe em si, sгo outro tipos de erros que nem sempre vemos mas que tambйm contam muito, espero que isto o ajude
Fora isso bom tutorial
Re: Descomplicando o ZCMD e SSCANF -
zSuYaNw - 10.01.2013
Belo Tutorial!
Acredito que jб tenha 3473575 tutoriais do mesmo assunto na бrea BR ;/
Re: Descomplicando o ZCMD e SSCANF -
MegaStyle157 - 10.01.2013
o tutorial esta leganzin mais desde quando zcmd e sscanf й complicado ?quer complicaзгo usa strcmp+strtok isso sim й chato de usar e lembrar a sintaxe.jб zcmd e sscanf nunca vi jeito mais facil de criar seus comandos de forma rapida e facil edite o titulo do tуpico e tente explicar um pouco mais.
Nota: 6/10
Re: Descomplicando o ZCMD e SSCANF -
Schocc - 10.01.2013
Quote:
Originally Posted by [Full]Garfield[XDB]
Belo Tutorial!
Acredito que jб tenha 3473575 tutoriais do mesmo assunto na бrea BR ;/
|
І ...
7/10
Re: Descomplicando o ZCMD e SSCANF -
DrTHE - 10.01.2013
Ficou bom, mas poderia adicionar esses detalhes que eles falaram.
Re: Descomplicando o ZCMD e SSCANF -
Maklister - 10.01.2013
Outra coisa
Com apenas 1 paramкtro pode ser usado,
pawn Код:
if(isnull(params)) return SendClientMessage(playerid, -1, "Digite uma mensagem.");