SSGamers - 13 Anos online por você.

#SSGamers - A Comunidade que mais crescer no brasil!

Participe do fórum, é rápido e fácil

SSGamers - 13 Anos online por você.

#SSGamers - A Comunidade que mais crescer no brasil!

SSGamers - 13 Anos online por você.

Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.
Chegou o novo tema 6.5.5 - SSGamers - Servidores online de qualidade - Aproveite e entre para nossa comunidade, inscreva-se já! - Ouça nossa web radio - Veja nossas novidades - Participe dos nossos setores de jogos online - Parcerias aberta fale já com um administrador.

    [Tutorial] Escrevendo bibliotecas com YSI

    Weslley_Script
    Weslley_Script
    SS - Fundador
    SS - Fundador


    Steam Steam : WeslleySSGames
    Zello : WeslleySSGames
    Mensagens : 11644
    Moedas : 1032956
    Data de inscrição : 06/10/2011
    Idade : 29
    Localização : Brasil

    [Tutorial] Escrevendo bibliotecas com YSI Empty [Tutorial] Escrevendo bibliotecas com YSI

    Mensagem por Weslley_Script Qui 30 Mar 2023 - 8:39

    Introdução

    O YSI não é apenas uma biblioteca poderosa para escrever modos de jogo e scripts de filtro, mas também possui muitos recursos que podem tornar suas próprias bibliotecas muito melhores. Este tutorial apresentará quatro deles: y_hooks, y_master, y_playerarray e y_groups.

    Este tutorial seguirá o desenvolvimento de uma biblioteca muito simples que permite criar um desenho de texto e mostrá-lo apenas a determinados jogadores. Este é um exemplo artificial, mas servirá. O resultado final terá um código como:
    Código do peão:

    Código:
    novo
        Grupo : g = Group_Create ( "tds" ) ,
        Texto : t = TextDrawCreate ( 20.0 , 20.0 , "Olá" ) ;
    Group_SetTextDraw ( g, _ : t, verdadeiro ) ;
    Group_SetGlobalTextDraw ( _ : t, false ) ;
    TextDrawShow ( t ) ;


    Esse código cria um grupo YSI e um desenho de texto, em seguida, define apenas um único grupo para poder ver o desenho de texto e mostra o desenho de texto para todos com permissão para vê-lo (o único grupo).

    y_playerarray

    y_playerarray cria um array de bits de jogadores para salvar na memória. É um pouco diferente de uma matriz de bits regular, pois o primeiro slot completo é reservado. As razões para isso não são relevantes para este tutorial, mas têm a ver com futuras bibliotecas YSI não lançadas.
    Código do peão:

    Código:
    #include <a_samp>
    #include <YSI\y_playerarray>



    Código:

    new
        PlayerArray : g_players [ Texto : MAX_TEXT_DRAWS ] < MAX_PLAYERS > ;


    Isso declarará uma matriz grande o suficiente para conter dados sobre quem pode ver o que o texto desenha (ou quem tem permissão). Para adicionar um jogador faça:
    Código do peão:

    Código:
    PA + ( g_players [ td ] ,playerid ) ;


    Para remover um faça:
    Código do peão:

    Código:
    PA- ( g_players [ td ] , playerid ) ;


    y_hooks

    O que é y_hooks? É um método para conectar callbacks em sua biblioteca. Quando um novo jogador se conecta ao seu servidor, ele não pode ver nenhum desenho de texto. Isso requer conectar o OnPlayerConnect para redefinir os dados:
    Código do peão:

    Código:
    #include <a_samp>
    #include <YSI\y_playerarray>
    #include <YSI\y_hooks>




    Código:
    new
        PlayerArray : g_players [ Texto : MAX_TEXT_DRAWS ] < MAX_PLAYERS > ;

    Gancho : TextDraw_OnPlayerConnect ( playerid )
    {
        for  ( new i =  0 ; i != MAX_TEXT_DRAWS; ++ i )
        {
             PA- ( g_players [ Texto : i ] , playerid );
        }
    }


    Simples. Esse é o tipo de coisa comum às bibliotecas - redefinir um player quando ele se conecta, isso apenas torna um pouco mais fácil.

    Código extra

    Neste ponto, definirei apenas algum código extra para fazer a biblioteca fazer algo:
    Código do peão:

    Código:
    #include <a_samp>
    #include <YSI\y_playerarray>
    #include <YSI\y_hooks>
    #include <YSI\y_iterate>




    Código:
    new
        PlayerArray : g_players [ Texto : MAX_TEXT_DRAWS ] < MAX_PLAYERS > ;

    Gancho : TextDraw_OnPlayerConnect ( playerid )
    {
        for  ( new i =  0 ; i != MAX_TEXT_DRAWS; ++ i )
        {
             PA - ( g_players [ Texto : i ], id do jogador ) ;
        }
    }




    Código:
    stock  Text : TextDraw_Create ( Float : x, Float : y, str [ ] )
    {
        new
            Text : td = TextDrawCreate ( x, y, str ) ;
        PA_Init ( g_players [ td ] ,falso ) ;
        retorno td;
    }



    Código:
    #define TextDrawCreate TextDraw_Create




    Código:
    stock TextDrawShow ( Text : td)
    {
         foreach ( Jogador, id do jogador )
        {
            if  ( PA = ( g_players [ td ] , id do jogador ) )
            {
                 TextDrawShowForPlayer ( id do jogador, td ) ;
            }
        }
    }



    Código:
    stock TextDraw_SetPlayer ( td, playerid, bool : set )
    {
        if  ( set ) PA + ( g_players [ Text : td ], id do jogador ) ;
        else PA- ( g_players [ Texto : td ] , playerid ) ; }



    No código acima, "TextDraw_Create" está fora da função de criação personalizada que cria um novo desenho de texto e define todos os jogadores como falsos. Em seguida, redefine "TextDrawCreate" para chamar nossa função personalizada. A segunda função percorre todos os jogadores e exibe o desenho de texto apenas para os jogadores selecionados. A função final adiciona ou remove um jogador de um desenho de texto.

    y_master

    y_master é um sistema de distribuição. O que isso significa é que, se você incluir uma biblioteca usando o sistema mestre YSI em vários scripts, todos eles se comunicarão. Queremos poder adicionar e remover jogadores de desenhos de texto em qualquer script, então precisamos usar o sistema mestre:
    Código do peão:

    Código:
    #include <a_samp>
    #include <YSI\y_playerarray>
    #include <YSI\y_hooks>
    #include <YSI\y_iterate>

    #define MASTER 7
    #include <YSI\y_master>




    Código:
    new
        PlayerArray : g_players [ Text : MAX_TEXT_DRAWS ] < MAX_PLAYERS > ;



    Código:
    RH : TextDraw_OnPlayerConnect [ i ] ( playerid )
    {
        for  ( novo i =  0 ; i ! = MAX_TEXT_DRAWS; ++ i )
        {
             PA-( g_players [ Texto : i ] , playerid ) ;
        }
    }



    Código:
    RF @ pt : Text : TextDraw_Create [ ffs ] ( Float : x, Float : y, str [ ] ) < x, y, str >
    {
        new
            Text : td = TextDrawCreate ( x, y, str ) ;
        PA_Init ( g_players [ td ] , falso) ;
        retorno td;
    }



    Código:
    #define TextDrawCreate TextDraw_Create



    Código:
    RF : TextDrawShow [ i ] ( Text : td )
    {
         foreach ( Player, playerid )
        {
            if  ( PA = ( g_players [ td ] , playerid ) )
            {
                 TextDrawShowForPlayer ( playerid, td ) ;
            }
        }
    }




    Código:
    RF : TextDraw_SetPlayer [ iii] ( td, playerid, bool : set )
    {
        if  ( set ) PA + ( g_players [ Text : td ] , playerid ) ;
        else PA- ( g_players [ Texto : td ] , playerid ) ; }



    Deve ficar bastante claro olhando para o código acima que não mudou muito - mas muitas mudanças importantes aconteceram.
    Código do peão:

    Código:
    #define MASTER 7
    #include <YSI\y_master>


    Isso inclui o sistema mestre e define um valor mestre exclusivo para ele. Se você tiver dois scripts em execução e ambos tiverem um streamer de ponto de verificação e um streamer de objeto, você precisa de uma maneira para os streamers cp se comunicarem e os streamers de objeto se comunicarem, mas para não se confundirem entre si. É para isso que serve o ID mestre. Neste caso, estamos usando 7, portanto, todos os scripts que incluem sua biblioteca devem usar 7 para identificar exclusivamente sua biblioteca.
    Código do peão:

    Código:
    RH : TextDraw_OnPlayerConnect [ i ] ( playerid )


    Aqui "Hook:" mudou para "RH:" - essa é mais ou menos a única mudança aqui. Como vários scripts incluem sua biblioteca, vários scripts têm todo o código de sua biblioteca. Quando o servidor inicia, todos esses scripts conversam entre si e decidem quem será o responsável, para que todo o código seja feito apenas uma vez. O uso de "RH:" garante que esse gancho seja chamado apenas pelo script responsável.
    Código do peão:

    Código:
    RF @ pt : Text : TextDraw_Create [ ffs ] ( Float : x, Float : y, str [ ] ) < x, y, str >


    Esta é a parte mais complexa. "RF" define uma "Função Remota" - como acabei de dizer, vários scripts podem ter o mesmo código, mas apenas um deve ser executado. Isso significa que todos os outros scripts devem encaminhar suas chamadas para o principal e retornar o que ele disser. Um exemplo básico disso é:
    Código do peão:

    Código:
    RF : PrintNumber [ i ] ( n )
    {
        printf ( "Número: %d" , n ) ;
    }


    Se todos os seus scripts incluírem que todos podem chamar esta função, mas apenas um script irá executá-la, o que significa que os dados locais podem ser usados. O formato é "RF:FUNCTION_NAME[PARAMETER_TYPES](PARAMETERS}" - os tipos de parâmetro são as letras que apareceriam em CallRemoteFunction (pois é exatamente isso que são). Algumas funções, entretanto, são um pouco mais complicadas, especialmente aquelas com strings. Se

    você tem uma string que seus parâmetros contêm "[]" - no entanto, isso não é válido em "CallRemoteFunction", então você precisa usar a versão "parametrizada" de "RF", que é "RF@p":
    Código do peão:

    Código:
    RF @ p : PrintString [ s ] ( str [ ] ) < str >
    {
        printf ( "String: %s" , str ) ;
    }


    Isso adiciona uma parte extra ao final da definição da função com o nome da variável. Todas as outras funções não usam "RF@p", mas poderiam fazer para remover os dados da tag nas variáveis:
    Código do peão:

    Código:
    RF @ p : TextDraw_SetPlayer [ iii ] ( td, playerid, bool : set ) < td, playerid, set >


    "RF@t" é uma função que retorna uma tag, como "TextDraw_Create" faz, você também pode misturar modificadores, que é de onde vem "RF@pt" (ou "RF@tp"). O outro modificador principal é "c", que define uma versão mais curta da macro caso o código gerado seja muito longo (geralmente resulta em uma falha do compilador). Portanto, você pode acabar com "RF@pct" para nomes de função muito longos.

    y_groups

    Se você escrever uma biblioteca personalizada, poderá usar o sistema de grupos para definir os controles de acesso aos seus recursos. O sistema de grupo é, na verdade, um wrapper em torno das permissões normais do player, portanto, você deve fornecer uma função chamada "Library_SetPlayer". O seguinte é uma implementação mínima de uma biblioteca que agora pode usar o sistema de grupos. A biblioteca usa o prefixo "Custom"
    Código do peão:

    Código:
    #include <a_samp>
    #include <YSI\y_playerarray>
    #include <YSI\y_hooks>
    #include <YSI\y_iterate>




    Código:
    #define MASTER 7
    #include <YSI\y_master>



    Código:

    #define _GROUP_MAKE_NAME_INTTEST<%0...%1> % 0TextDraw%1
    #define _GROUP_MAKE_LIMIT_INTTEST MAX_TEXT_DRAWS
    #include <YSI\y_groups>




    Código:
    new
        PlayerArray : g_players [ Text : MAX_TEXT_DRAWS ] < MAX_PLAYERS > ;

    RH :


       
            for  ( new i =  0 ; i != MAX_TEXT_DRAWS; ++ i )
            {
                 PA - ( g_players [ Text : i ] , playerid ) ;
            }
        }
    }



    Código:
    RF @ pt : Text : TextDraw_Create [ ffs ] ( Float : x, Float : y, str [ ] ) < x, y, str >
    {
        novo
            Text : td = TextDrawCreate ( x, y, str ) ;
        NO_GROUPS ( _ : td )
        {
             PA_Init ( g_players [ td ] , false ) ;
        }
        return td;
    }




    Código:
    #define TextDrawCreate TextDraw_Create




    Código:
    RF : TextDrawShow [ i ] ( Text : td )
    {
         foreach ( Player, playerid )
        {
            if  ( PA= ( g_players [ td ] , playerid ) )
            {
                 TextDrawShowForPlayer ( playerid, td ) ;
            }
        }
    }




    Código:
    RF : TextDraw_SetPlayer [ iii ] ( td, playerid, bool : set )
    {
        if  ( set ) PA + ( g_players [ Text : td ] , playerid ) ;
        senão PA - (g_players [ Texto : td ] , playerid ) ;
    }



    Código:
    #undef _GROUP_MAKE_NAME_INTTEST
    #undef _GROUP_MAKE_LIMIT_INTTEST


    Realmente não mudou muito aqui:
    Código do peão:

    Código:
    #define _GROUP_MAKE_NAME_INTTEST<%0...%1> %0TextDraw%1
    #define _GROUP_MAKE_LIMIT_INTTEST MAX_TEXT_DRAWS
    #include <YSI\y_groups>


    Isso inclui a biblioteca de grupos e define o padrão que as funções devem assumir. Essas três linhas sozinhas definem as seguintes funções:
    Código do peão:

    Código:
    Group_SetTextDraw ( Grupo : grupo, elemento, bool : conjunto ) ;
    Group_SetGlobalTextDraw ( elemento, bool : conjunto ) ;
    Group_SetTextDrawDefault ( Grupo : grupo, bool : conjunto ) ;
    Group_SetGlobalTextDrawDefault ( bool : set ) ;


    Observe que não há nenhuma tag "Texto:", mas isso é outro assunto e uma limitação atual da biblioteca de grupos. Agora você pode usar todas as funções de grupo padrão para definir quem pode usar seu sistema.
    Código do peão:

    Código:
    NO_GROUPS ( )
        {
            for  ( new i =  0 ; i != MAX_TEXT_DRAWS; ++ i )
            {
                 PA - ( g_players [ Text : i ] , playerid ) ;
            }
        }


    Dentro do YSI, o sistema de grupos é totalmente opcional. Se você usar este método, o sistema de grupos será incluído inteiramente, mas o padrão "NO_GROUPS" ainda é válido. Você pode apenas remover seu próprio código de inicialização inteiramente aqui - ele só será chamado se os grupos não estiverem definidos, mas estão.
    Código do peão:

    Código:
    NO_GROUPS ( _ : td )
        {
             PA_Init ( g_players [ td ] , false ) ;
        }


    O mesmo se aplica aqui - se não houver grupos, use o código de inicialização personalizado, caso contrário, inicialize este novo desenho de texto (em "td") usando o código da biblioteca de grupos.

    Observe que o sistema y_groups usa sua função "TextDraw_SetPlayer" para chamar seu código de acesso básico por jogador - por isso é muito importante que essa função exista e tenha esses parâmetros exatos (ou seja, item, playerid, conjunto).

    Conclusões

    Esta foi uma breve introdução ao uso do YSI para escrever bibliotecas dinâmicas, e usar esses recursos fornece acesso direto a recursos como salvamento automático de grupo na biblioteca do usuário YSI, etc. Este tutorial foi principalmente um exemplo simples construído, mas mostra o básico sem considerar. Qualquer informação adicional é só perguntar aqui ou ler as inclusões relevantes (desafio você a procurar em y_groups e y_master).


    Creditos:Misiur



    [Tutorial] Escrevendo bibliotecas com YSI D07Xwqb
    [Tutorial] Escrevendo bibliotecas com YSI Yjab9HN

      Data/hora atual: Qui 28 Nov 2024 - 2:10