[Tutorial] Melhorando seus script's e seus gamemodes
#1

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
  • 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;
    }
    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 ******, 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;
    }
    Em sscanf
    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.
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)
    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;
    }
    Em zcmd (Processador de comandos)
    pawn Код:
    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)
    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;
    }
    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
    pawn Код:
    CMD:kick(playerid, params[])
    {
        if(sscanf(params, "u", params[0]))
            return SendClientMessage(playerid, 0xFFFFFFFF, "Uso: /kick [playerid]");
        Kick(params[0]);
        return 1;
    }
    Em ycmd
    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 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?
Loops
  • A maioria tem por norma fazer os loops assim:

    pawn Код:
    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:

    pawn Код:
    #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 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++)
    Este tipo de loop й errado e mais lento.

    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;
    }
    Tornam-se alem de mais fбceis, mais rбpidos tambйm na hora do processamento:


    pawn Код:
    #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.
"Lуgicas, sem lуgica"
Crйditos
    • 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
Reply
#2

dei uma lida rбpida, nada mal, pode ajudar muitos iniciantes...
Reply
#3

Valeu PT, me ajudou muito sinceramente, antes eu fazia

pawn Код:
if(tembolacha = 1) {

 dasdasfasfasfas

}
else {

nao tem bolacha dasdsadsadsa

}
Nunca tinha pensado que podia fazer usando o sinal '!', vlw! me ajudou!
Vocк nгo й spammers, nгo sei pq dizem isso de vocк, sу pq comenta em todos os tуpicos!


+REP
Reply
#4

Bom o tutorial, pena que grande parte das pessoas nгo estгo nem aн para otimizaзгo pois o seu interesse й sim editar um gm da net para botar num host e criar um servidor sem qualquer conhecimento.

Sugestгo, poderia colocar comparaзхes de velocidade entre todos processadores de comandos e tal.
Reply
#5

Vocк poderia ter colocado outras maneiras de otimizaзхes para GameMod ai PT.
Reply
#6

Quote:
Originally Posted by BieeelEvolution
Посмотреть сообщение
Vocк poderia ter colocado outras maneiras de otimizaзхes para GameMod ai PT.
ve os links que deixei no fim, acho que vc nao viu tudo.

mesmo assim obrigado pelo apoio.

@ Todos

muito obrigado pelo feedback positivo.
Reply
#7

devias apresentar os operadores logicos especificar pelo menos cada um o que faz na parte final do tutorial e bastante util para os iniciantes. caso nao faзas vou deixar ja aqui
! negaзao penso que esta claro
&& iquer dizer "e" exemplo Eu && tu que lesse eu e tu
|| quer dizer ou por exemplo eu || tu que lesse eu ou tu.
estes 3 sao os essenciais
== isto usasse para igualar por exemplo if( 1 == 1)
depois temos o >= e o <= que e maior ou igual e menor ou igual respetivamente lembrem-se sempre que o igual e sempre a frente dos <>.
<> menor e maior como e obvo.
penso que fui claro fiz so isto para complementar o teu tuto pt eu nao sei explicar muito bem e por isso que nem faco tutoriais
Reply
#8

Quote:
Originally Posted by caoraivoso3
Посмотреть сообщение
devias apresentar os operadores logicos especificar pelo menos cada um o que faz na parte final do tutorial e bastante util para os iniciantes. caso nao faзas vou deixar ja aqui
! negaзao penso que esta claro
&& iquer dizer "e" exemplo Eu && tu que lesse eu e tu
|| quer dizer ou por exemplo eu || tu que lesse eu ou tu.
estes 3 sao os essenciais
== isto usasse para igualar por exemplo if( 1 == 1)
depois temos o >= e o <= que e maior ou igual e menor ou igual respetivamente lembrem-se sempre que o igual e sempre a frente dos <>.
<> menor e maior como e obvo.
penso que fui claro fiz so isto para complementar o teu tuto pt eu nao sei explicar muito bem e por isso que nem faco tutoriais
para isso deixei links de outros tutoriais como este: https://sampforum.blast.hk/showthread.php?tid=240266

tem membros que ja falaram sobre isso e achei mais interessante "linkar" para os tutos deles.
Reply
#9

Muito bom PT, isso pode ajudar muitos os iniciantes porque eu vejo muitos scripts aqui com comandos em strcmp.

Parabйns pelo tutorial, +REP.
Reply
#10

Legal para comeзo, se vocк aprimorar-lo de acordo com o tempo seria muito ъtil para novatos.
Reply
#11

Bom tutorial

Unica coisa que nгo gosto dos processadores de comando й que nгo tem como usar um parвmetro dentro do outro... xD
Reply
#12

Bom trabalho !!! Agora sim eu percebi q fui ignorante esse tempo todo em nao querer deixar o famoso strtok em nao procurar a saber do processadores de comandos.


+REP
Reply
#13

Isso nгo й bom para iniciantes. Atй porque eles pegam um gamemode na internet e nгo sabem nem oque й uma variбvel, logo isso aн sу vai colocar a sujeira de baixo do tapete, mas eles poderгo nгo aprender isso.

Anyway, parabйns pelo tutorial. Creio que vai ajudar aqueles novatos-avanзados em pawn.
Reply
#14

Sу pra constar a funзгo "strtok" foi feita originalmente pela compuphase que o fez inspirada na implementaзгo do mesmo em c/c++. O resto do thread, й a mesma coisa que outros jб fizeram.
Reply
#15

pawn Код:
if(PTisGay == 1){
Rep ++; }
Bom tuto!
Reply
#16

Minha vida foi uma mentira (), legal sua publicaзгo mas prefiro dizer que cada um tem seu jeito e suas crenзas, ninguйm tem direito de os mudar (minha opiniгo), cada um faz script do jeito que lhe couber na cabeзa.

Nгo estou procurando briga e nem te criticando, tenho muito respeito por vocк, como sempre vocк fez um grande trabalho.
+Rep
Reply
#17

Bom!

й certo dizer que ainda faltou alguns raciocнnios bбsicos, porйm nгo altera a qualidade com que foi explicado ..

pawn Код:
if(0 < var && var > 10) :::::  if( 0 < var < 10)
var = 2
var1 = 2
var = var1 = 2


e tambйm que da para construir Loops ainda mais rapidas partindo da contagem de players On nгo pela quantidade de Slots ..
pois muitas vezes os servidores tem 300 slots e 20 pessoas Connected .. contando apenas os onlines a loop fica ainda mais Rapida .. Lуgica ^^
Reply
#18

Grande tutorial!
Reply
#19

Not bad, bom tutorial.
Reply
#20

esta um bom tutorial.
bom trabalho!
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)