07.02.2014, 22:34
(
Последний раз редактировалось PT; 13.12.2015 в 13:51.
Причина: Atualizaзгo dos links de download das librarias
)
Boas, partindo de um tutorial do Emmet_ que vi na board Inglesa, decidi fazer um para a board portuguesa, com o objetivo de ver os utilizadores desta board com melhores scripts e com melhor raciocнnio, isto apos ter visto muitos membros novos com codes muito mal feitos, e se nao aprendem direito de novos, nunca ou tarde endireitam.
Problema do strtok
Espero que aprendam algo com este tutorial, se quiserem acrescentar algo ou melhorar o tutorial em algum aspeto, estejam б vontade.
Talvez no futuro, dependendo do vosso feedback, melhorarei ou farei mais tutoriais, deixem abaixo as suas opiniхes, tambem se tiverem em dъvida acerca de algum assunto deste tutorial, estarei б disposiзгo para responder.
Sei que o tutorial й acerca de uma matйria simples, porйm muitos ainda nunca se aperceberam ou nunca viram a vantagem de "evoluir" os seus scripts, talvez com isto aprendam algo.
Cumprimentos
Problema do strtok
- Bem, vejo ainda muitos membros desta board,a usar a "velhinha" strtok feita pelo DarcoBlue.
Funзгo strtok:
pawn Код: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;
}
Bem, eu recomendo que usem sscanf criada pelo ******, nгo sу pela facilidade de uso, mas tambйm pela velocidade desta e nгo sу;
Vejam a diferenзa do comando /kick [id]:
Em strtok
pawn Код:public OnPlayerCommandText(playerid, cmdtext[])
{
new cmd[128], idx;
cmd = strtok(cmdtext, idx);
if(strcmp(cmd, "/kick", true) == 0)
{
new tmp[128];
tmp = strtok(cmdtext, idx);
if(strlen(tmp) == 0)
return SendClientMessage(playerid, 0xFFFFFFFF, "Uso: /kick [playerid]");
Kick(strval(tmp));
return 1;
}
return 0;
}
pawn Код:public OnPlayerCommandText(playerid, cmdtext[])
{
if(strcmp(cmd, "/kick", true) == 0)
{
new id;
if(sscanf(cmdtext, "u", id))
return SendClientMessage(playerid, 0xFFFFFFFF, "Uso: /kick [playerid]");
Kick(id);
return 1;
}
return 0;
}
Viram? Os comandos acima fazem exatamente o mesmo, porйm como podem ver, a sua elaboraзгo й diferente, pessoalmente acho que й sem dъvida o segundo, mais fбcil que o primeiro.
- Bem, ainda muito usam strcmp para criar comandos. Isto atualmente normalmente diz muito sobre o programador do GM, ou й preguiзoso e nгo quer atualizar os seus comandos para processador de comandos, ou, usa um gamemode da Internet e nгo faz a mнnima ideia do que й um processador de comandos (embora atualmente tenha mais gamemodes na internet com processador de comandos). Antes de tudo strcmp tem como finalidade comparar string's e nao criar comandos.
Usar um processador de comandos tem enormes vantagens, como a maior simplicidade na criaзгo de comandos, й prбtica, cуmodo e sobretudo mais rбpido de usar do que strcmp.
Analisem o comando /kick [id] abaixo:
Em strcmp (Nгo й processador de comandos)
pawn Код:public OnPlayerCommandText(playerid, cmdtext[])
{
if(strcmp(cmd, "/kick", true) == 0)
{
new id;
if(sscanf(cmdtext, "u", id))
return SendClientMessage(playerid, 0xFFFFFFFF, "Uso: /kick [playerid]");
Kick(id);
return 1;
}
return 0;
}
pawn Код:CMD:kick(playerid, params[])
{
new id;
if(sscanf(params, "u", id))
return SendClientMessage(playerid, 0xFFFFFFFF, "Uso: /kick [playerid]");
Kick(id);
return 1;
}
pawn Код:YCMD:kick(playerid, params[], help)
{
#pragma unused help
new id;
if(sscanf(cmdtext, "u", id))
return SendClientMessage(playerid, 0xFFFFFFFF, "Uso: /kick [playerid]");
Kick(id);
return 1;
}
Й muito melhor nгo й? Eu sei que sim...
E sim criar comandos com processadores de comandos nao precisa de colocar o comando dentro de qualquer callback.
Tambem muitas vezes nao precisam criar variaveis, assim:
Em zcmd
pawn Код:CMD:kick(playerid, params[])
{
if(sscanf(params, "u", params[0]))
return SendClientMessage(playerid, 0xFFFFFFFF, "Uso: /kick [playerid]");
Kick(params[0]);
return 1;
}
pawn Код:YCMD:kick(playerid, params[], help)
{
#pragma unused help
if(sscanf(cmdtext, "u", params[0]))
return SendClientMessage(playerid, 0xFFFFFFFF, "Uso: /kick [playerid]");
Kick(params[0]);
return 1;
}
Porque sгo os mais rбpidos (apesar de ycmd ser o mais rбpido), jб criados em pawn atualmente e sгo os que a maioria dos programadores de sa-mp que usam processadores de comandos usam.
Sim, eu sei que ainda existem mais rбpidos desenvolvidos em C++, porйm sгo mais complexos o seu uso para quem ainda estб a aprender, porque mexe com plugins, etc.
- Bem isso й o ideal e sim estб a agir corretamente, porйm para quem nгo estб a usar a e quer comeзar, deixo aqui uns links de uns tutoriais para comeзarem.
- ycmd e sscanf: http://forum.sa-mp.com/showthread.ph...17#post2671917
- zcmd e sscanf: https://sampforum.blast.hk/showthread.php?tid=329507
Deixo tambйm o tуpico oficial aqui no Fуrum SA-MP de cada processador e da SSCANF:
- A maioria tem por norma fazer os loops assim:
pawn Код:for(new i = 0; i < MAX_PLAYERS; i++)
Fazendo simplesmente isto:
pawn Код:#include <a_samp>
#undef MAX_PLAYERS
#define MAX_PLAYERS (50) // o 50 voce muda pelo numero de slots do seu servidor
Se nгo alterarem o valor, MAX_PLAYERS assume um valor que para quem nгo sabe estб definido por default pela SA-MP Team na include a_samp.inc como valor padrгo 500 (a nгo ser que seja um "pacote" de 1000 players), ou seja, irб sempre realizar o loop de 500, mas se alterarem o valor de MAX_PLAYERS ira assumir o valor mбximo no loop a quantidade de slots do seu servidor, sendo que a maioria dos membros aqui na board portuguesa quase nunca tem um servidor com 500 slots alterando o valor o loop й muito mais rбpido.
Porem tem tambйm quem insista em fazer o loop deste jeito:
pawn Код:for(new i = 0; i < GetMaxPlayers(); i++)
Apenas num caso especial poderб ser mais rбpido, se vocк tiver um servidor de 50 slots e nгo alterar o valor de MAX_PLAYERS usando o loop acima torna-se mais rбpido й verdade, porem se alterarem o valor o valor de MAX_PLAYERS para o valor real dos seus slots o loop acima torna-se muito mais lento.
foreach
Com esta simples include (versгo mais antiga, nas versхes mais recentes esta incorporada na YSI) feita pelo ****** vocк pode melhorar e muito os seus loops sendo que quando sгo ligados a sistemas para players apenas corre o loop nos players conectados, mas tambйm poderб nos veнculos, entre outros.
Ou seja, cуdigos assim:
pawn Код:stock DarDinheiroTodos()
{
for( new i = 0; i < MAX_PLAYERS; i++)
{
if(IsPlayerConnected(i))
{
GivePlayerMoney(i, 1000);
}
}
return 1;
}
pawn Код:#include <foreach>
stock DarDinheiroTodos()
{
foreach(new i : Player)
{
GivePlayerMoney(i, 1000);
}
return 1;
}
Deixo abaixo o link do tуpico da foreach para quem quiser saber mais sobre a mesma.
- foreach: https://sampforum.blast.hk/showthread.php?tid=571159 ou se preferirem sozinha a include https://sampforum.blast.hk/showthread.php?tid=570868
- Ao ler o tнtulo й engraзado, porйm o assunto й sйrio por vezes, ve-se os cуdigos assim:
pawn Код:new bolacha[MAX_PLAYERS];
if(bolacha[playerid])
{
}
else
{
SendClientMessage(playerid, -1, "Nao tens bolacha");
}
pawn Код:new bolacha[MAX_PLAYERS];
if(!bolacha[playerid])
return SendClientMessage(playerid, -1, "Nao tens bolacha");
- Emmet_ - Base da ideia para criacao do tutorial
- PT - Criacao do tutorial
Espero que aprendam algo com este tutorial, se quiserem acrescentar algo ou melhorar o tutorial em algum aspeto, estejam б vontade.
Talvez no futuro, dependendo do vosso feedback, melhorarei ou farei mais tutoriais, deixem abaixo as suas opiniхes, tambem se tiverem em dъvida acerca de algum assunto deste tutorial, estarei б disposiзгo para responder.
Sei que o tutorial й acerca de uma matйria simples, porйm muitos ainda nunca se aperceberam ou nunca viram a vantagem de "evoluir" os seus scripts, talvez com isto aprendam algo.
Cumprimentos