03/10/2023 13:00
Ola, dado que o Forum SA-MP fechou decidi trazer os tutorais que tinha feito para o Forum SA-MP para aqui, com o objetivo de ver os utilizadores desta board com melhores scripts e com melhor raciocinio, isto apos ter visto muitos membros novos com codigos muito mal feitos, e se nao aprendem direito de novos, nunca ou tarde endireitam.
Problema do strtok
Mas, não sabem que ela além de ser velha é também lenta em relação a atuais comparadores de parámetros.
Bem, eu recomendo que usem sscanf criada pelo Y_Less, não só pela facilidade de uso, mas também pela velocidade desta;
Vejam a diferença do comando /kick [id]:
Em strtok;
Em sscanf;
Viram? Os comandos acima fazem exatamente o mesmo, porém como podem ver, a sua elaboração é diferente, pessoalmente acho que é sem duvida o segundo, mais fácil que o primeiro.
Problema do uso de strcmp para criar comandos
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)
Em zcmd (Processador de comandos)
Em ycmd (Processador de comandos)
Viram a diferenзa?
É 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
Em ycmd
Porque escolhi ycmd e zcmd?
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.
E se eu usar sscanf e um processador de comandos, estou a agir bem?
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 o link Github de cada processador e da SSCANF:
ZCMD: https://github.com/Southclaws/zcmd
YCMD: https://github.com/pawn-lang/YSI-Include...ommands.md
SSCANF: https://github.com/Y-Less/sscanf
Loops
A maioria tem por norma fazer os loops assim:
Não é que esteja errado, porém esquecem-se que o valor default de MAX_PLAYERS, se alterarem o valor para o valor real de slots máximo do seu servidor podem fazer com que os loops tenham um processamento (velocidade) maior, como?
Fazendo simplesmente isto:
Qual a diferença?
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 1000, ou seja, irá sempre realizar o loop de 1000, 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 1000 slots alterando o valor o loop é muito mais rápido.
Porem tem também quem insista em fazer o loop deste jeito:
Este tipo de loop é errado e mais lento.
Apenas num caso especial poderá ser mais rápido, se voce 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 versoes mais recentes esta incorporada na YSI) feita pelo Y_Less voce 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:
Tornam-se alem de mais fáceis, mais rápidos também na hora do processamento:
Fazem as duas formas exactamente o mesmo porem a segunda e muito mais rápida que a primeira na hora do processamento
Deixo abaixo o link do tópico da foreach para quem quiser saber mais sobre a mesma.
foreach: https://github.com/pawn-lang/YSI-Include...iterate.md ou se preferirem sozinha a include https://github.com/karimcambridge/samp-foreach
"Lógicas, sem lógica"
Ao ler o título é engraçado, porem o assunto é sério por vezes, ve-se os códigos assim:
Quando me deparo com um código deste, embora ja tenha visto muito piores a nivel de logica, pergunto se não seria mais fácil faze-lo assim:
Com isto vejo que muitos membros ainda não sabem os operadores lógicos, se é que ao menos sabem que eles existem, por isso decidi deixar aqui alguns links de tutoriais de operadores lógicos, e tambem a nivel de otimizacoes, para quem quiser saber mais sobre este assunto.
https://portalsamp.com/showthread.php?tid=2486
https://portalsamp.com/showthread.php?tid=3406
https://portalsamp.com/showthread.php?tid=3560
Créditos
Emmet_ - Base da ideia para criacao do tutorial
PT_Player a.k.a 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 duvida acerca de algum assunto deste tutorial, estarei á disposiзгo para responder.
Sei que o tutorial é sobre 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
P.S: Relembro que isto é um tutorial feito e postado em 2014 no Forum SA-MP.
Problema do strtok
- Bem, vejo ainda muitos membros desta board,a usar a "velhinha" strtok feita pelo DarcoBlue.
Código:
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;
}
Mas, não sabem que ela além de ser velha é também lenta em relação a atuais comparadores de parámetros.
Bem, eu recomendo que usem sscanf criada pelo Y_Less, não só pela facilidade de uso, mas também pela velocidade desta;
Vejam a diferença do comando /kick [id]:
Em strtok;
Código:
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;
}
Em sscanf;
Código:
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 duvida o segundo, mais fácil que o primeiro.
Problema do uso de strcmp para criar comandos
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)
Código:
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;
}
Em zcmd (Processador de comandos)
Código:
CMD:kick(playerid, params[])
{
new id;
if(sscanf(params, "u", id))
return SendClientMessage(playerid, 0xFFFFFFFF, "Uso: /kick [playerid]");
Kick(id);
return 1;
}
Em ycmd (Processador de comandos)
Código:
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
Código:
CMD:kick(playerid, params[])
{
if(sscanf(params, "u", params[0]))
return SendClientMessage(playerid, 0xFFFFFFFF, "Uso: /kick [playerid]");
Kick(params[0]);
return 1;
}
Código:
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 escolhi ycmd e zcmd?
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.
E se eu usar sscanf e um processador de comandos, estou a agir bem?
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 o link Github de cada processador e da SSCANF:
ZCMD: https://github.com/Southclaws/zcmd
YCMD: https://github.com/pawn-lang/YSI-Include...ommands.md
SSCANF: https://github.com/Y-Less/sscanf
Loops
A maioria tem por norma fazer os loops assim:
Código:
for(new i = 0; i < MAX_PLAYERS; i++)
Não é que esteja errado, porém esquecem-se que o valor default de MAX_PLAYERS, se alterarem o valor para o valor real de slots máximo do seu servidor podem fazer com que os loops tenham um processamento (velocidade) maior, como?
Fazendo simplesmente isto:
Código:
#include <a_samp>
#undef MAX_PLAYERS
#define MAX_PLAYERS (50) // o 50 voce muda pelo numero de slots do seu servidor
Qual a diferença?
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 1000, ou seja, irá sempre realizar o loop de 1000, 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 1000 slots alterando o valor o loop é muito mais rápido.
Porem tem também quem insista em fazer o loop deste jeito:
Código:
for(new i = 0; i < GetMaxPlayers(); i++)
Apenas num caso especial poderá ser mais rápido, se voce 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 versoes mais recentes esta incorporada na YSI) feita pelo Y_Less voce 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:
Código:
stock DarDinheiroTodos()
{
for( new i = 0; i < MAX_PLAYERS; i++)
{
if(IsPlayerConnected(i))
{
GivePlayerMoney(i, 1000);
}
}
return 1;
}
Tornam-se alem de mais fáceis, mais rápidos também na hora do processamento:
Código:
#include <foreach>
stock DarDinheiroTodos()
{
foreach(new i : Player)
{
GivePlayerMoney(i, 1000);
}
return 1;
}
Fazem as duas formas exactamente o mesmo porem a segunda e muito mais rápida que a primeira na hora do processamento
Deixo abaixo o link do tópico da foreach para quem quiser saber mais sobre a mesma.
foreach: https://github.com/pawn-lang/YSI-Include...iterate.md ou se preferirem sozinha a include https://github.com/karimcambridge/samp-foreach
"Lógicas, sem lógica"
Ao ler o título é engraçado, porem o assunto é sério por vezes, ve-se os códigos assim:
Código:
new bolacha[MAX_PLAYERS];
if(bolacha[playerid])
{
}
else
{
SendClientMessage(playerid, -1, "Nao tens bolacha");
}
Quando me deparo com um código deste, embora ja tenha visto muito piores a nivel de logica, pergunto se não seria mais fácil faze-lo assim:
Código:
new bolacha[MAX_PLAYERS];
if(!bolacha[playerid])
return SendClientMessage(playerid, -1, "Nao tens bolacha");
Com isto vejo que muitos membros ainda não sabem os operadores lógicos, se é que ao menos sabem que eles existem, por isso decidi deixar aqui alguns links de tutoriais de operadores lógicos, e tambem a nivel de otimizacoes, para quem quiser saber mais sobre este assunto.
https://portalsamp.com/showthread.php?tid=2486
https://portalsamp.com/showthread.php?tid=3406
https://portalsamp.com/showthread.php?tid=3560
Créditos
Emmet_ - Base da ideia para criacao do tutorial
PT_Player a.k.a 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 duvida acerca de algum assunto deste tutorial, estarei á disposiзгo para responder.
Sei que o tutorial é sobre 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
P.S: Relembro que isto é um tutorial feito e postado em 2014 no Forum SA-MP.