sharivan

lession3.sp

Oct 3rd, 2015
138
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  * Autor: "SHARIVAN do clã ZM Brasil (ΖмBя.™ Clan)
  3.  *
  4.  * Descrição:
  5.  *   Terceira aula de programação em sourcepawn 1.7.
  6.  *   Nesta lição serão abordados os seguintes assuntos:
  7.  *      - Strings.
  8.  *      - Listas.
  9.  *      - Vetores.
  10.  *
  11.  *   Para maiores informações sobre como programar plugins de sourcemod, recomendo ter as seguintes competências:
  12.  *
  13.  *   - Conhecimento de matemática básica, principalmente geometria euclidiana, geometria analítica e vetores.
  14.  *   - Lógica da programação
  15.  *   - Conhecimento básico e intermediário das linguagens C e C++
  16.  *   - Linguagem Pawn
  17.  *
  18.  *   Segue abaixo alguns links importantes:
  19.  *
  20.  *   Manual do sourcepawn:
  21.  *     Pré 1.7: https://wiki.alliedmods.net/Introduction_to_sourcepawn
  22.  *     Pós 1.7: https://wiki.alliedmods.net/Introduction_to_SourcePawn_1.7
  23.  *
  24.  *   API do sourcemod:
  25.  *     Pré 1.7: https://sm.alliedmods.net/api/
  26.  *     Pós 1.7: https://sm.alliedmods.net/new-api/
  27.  *
  28.  *   Realçador de sintaxe do sourcepawn para Notepad++: https://forums.alliedmods.net/showthread.php?t=120037
  29.  *
  30.  *   Pawn Studio: http://sourceforge.net/projects/pawnstudio/
  31.  *
  32.  */
  33.  
  34. #pragma semicolon 1
  35.  
  36. // Includes
  37.  
  38. #include <sourcemod>
  39. #include <sdktools>
  40. #include <zombiereloaded> // API do Zombie:Reloaded
  41. #include <smlib> // API da SMLib que pode ser obtida em https://forums.alliedmods.net/showthread.php?t=148387
  42.  
  43. // Defines
  44.  
  45. #define VERSION "1.0"
  46.  
  47. // Variáveis globais
  48.  
  49. char g_sString[16]; // Declaração de uma string com 16 caracteres. Strings em sourcepawn são como arrays, elas devem sempre ser declaradas com um tamanho fixo exceto quando são parâmetros de funções onde seu tamanho pode ser indeterminado.
  50. ArrayList g_hLista; // Uma variável do tipo ArrayList. ArrayList é uma classe (methodmap) que encapsula as operações para manipulação de uma lista.
  51.  
  52. // Info
  53.  
  54. public Plugin myinfo = {
  55.     name = "Aula 3",
  56.     author = "SHARIVAN from ΖмBя.™ Clan",
  57.     description = "Terceira aula de sourcepawn",
  58.     version = VERSION,
  59.     url = "http://www.zmbrasil.com.br/"
  60. };
  61.  
  62. // Forwards
  63.  
  64. public void OnPluginStart() {
  65.     // Atribuir um valor a uma string
  66.     g_sString = "Olá"; // Válido somente para inicializar a variável.
  67.     g_sString = "Hello"; // Não recomendável caso ela já tenha sido inicializada.
  68.     strcopy(g_sString, sizeof(g_sString), "Olá"); // Esse seria o mais recomendável.
  69.     Format(g_sString, sizeof(g_sString), "%s", "Olá"); // Uma forma alternativa de atribuir valores para strings.
  70.    
  71.     // Atribuir variável string para string
  72.     char sString2[16] = "Como vai?";
  73.     strcopy(g_sString, sizeof(g_sString), sString2);
  74.    
  75.     // Concatenar strings
  76.     char sString3[16] = "Tudo bem?";
  77.     StrCat(g_sString, sizeof(g_sString), sString3); // Isso é o mesmo que g_sString = g_sString + sString3 em Java/C#
  78.     Format(g_sString, sizeof(g_sString), "%s%s", g_sString, sString3); // Uma forma alternativa de concatenar strings;
  79.    
  80.     if (strlen(g_sString) > 10) // Para obter a quantidade de caracteres em uma string use a função strlen.
  81.         LogMessage("O tamanho da string g_sString é maior que 10."); // API do sourcemod que escreve uma mensagem nos logs do sourcemod.
  82.        
  83.     if (StrEqual(g_sString, "hehehe")) // Para comparar duas strings use a função StrEqual. Ela aceita um terceiro parâmetro opcional booleano que se for verdadeiro (padrão) compara as strings usando case sensitive, ou seja, diferencia maiúsculas de minúsculas. Caso seja falso, ele não leva em conta o case sensitive.
  84.         LogMessage("O tamanho da string g_sString é maior que 10.");
  85.        
  86.     g_hLista = new ArrayList(); // Criação de uma lista. Caso queira que os elementos tenham mais de uma célula de tamanho, deverá ser especificado o número de células passado como parâmetro neste construtor, caso contrário será assumido como apenas uma célula por elemento.
  87. }
  88.  
  89. public void OnPluginEnd() {
  90.     delete g_hLista; // Destruição de uma lista (opcional).
  91. }
  92.  
  93. public void OnClientPutInServer(int client) {
  94.     g_hLista.Push(client); // Adiciona um elemento a uma lista colocando ele no final dela.
  95. }
  96.  
  97. public void OnClientDisconnect(int client) {
  98.     int indice = g_hLista.FindValue(client); // Procura um elemento em uma lista retornando seu índice caso seja encontrado. Caso não o encontre, é retornado -1.
  99.     if (indice != -1)
  100.         g_hLista.Erase(indice); // Deleta um elemento de uma lista, sempre passando seu índice como parâmetro.
  101. }
  102.  
  103. // A forward OnPlayerRunCmd é chamada a cada frame do servidor, passando como parâmetros o estados dos botões que o jogador pressionou, do impulse, sua velocidade, angulos e arma a ser usada. Essa forward é invocada antes que o engine processe o comando enviado pelo jogador, desta forma é possível verificar por exemplo se ele pressionou determinada tecla e desativa-la antes mesmo que o engine saiba disso.
  104. public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float ang[3], int &weapon) {
  105.     if (impulse == 100) // Se ele ligou ou desligou a lanterna (impulse=100) envia uma mensagem pra ele notificando sobre isso.
  106.         PrintToChat(client, "Você acendeu/apagou a lanterna.");
  107.        
  108.     if (!IsPlayerAlive(other) || !ZR_IsClientZombie(client)) // Se ele não estiver vivo ou se ele não for um zumbi, cai fora.
  109.         return Plugin_Continue;
  110.        
  111.     float vecOrigem[3]; // Vetores tridimensionais em sourcepawn são dados sempre na forma de um array de 3 posições do tipo float. Segue abaixo o significado de cada posição deste array.
  112.     // vecOrigem[0] = coordenada x
  113.     // vecOrigem[1] = coordenada y
  114.     // vecOrigem[2] = coordenada z
  115.     GetClientAbsOrigin(client, vecOrigem); // Obtem as coordenadas da origem do jogador.
  116.        
  117.     if ((buttons & IN_ATTACK) != 0) // Se ele pressionou o botão de ataque.
  118.         for (int other = 1; other <= MaxClients; other++) { // Varre todos os demais clientes.
  119.             if (other != client // Se o outro usuário não for eu mesmo
  120.                 && Client_IsIngame(other) // Se ele for um cliente válido e estiver em jogo (aqui foi usada uma API da SMLib para este fim).
  121.                 && IsPlayerAlive(other) // Se ele estiver vivo.
  122.                 && ZR_IsClientHuman(other) // E por fim, se ele for um humano.
  123.                 ){ // Então...
  124.                 float vecOrigemDoOutro[3];
  125.                 GetClientAbsOrigin(other, vecOrigemDoOutro); // Obtém as coordenadas deste usuário.
  126.                 if (GetVectorDistance(vecOrigem, vecOrigemDoOutro) <= 200.0) // Calcula a distância entre eu e ele. Se essa distância for menor que 200.
  127.                     ZR_InfectClient(other, client); // Infecta este usuário!
  128.             }
  129.         }
  130.    
  131.     return Plugin_Continue;
  132. }
  133.  
  134. // Stocks
  135.  
  136. // Essa seria uma possível implementação do método FindValue da claase ArrayList para o caso de seus elementos forem somente números inteiros.
  137. // A palavra chave stock indica que a função é uma função de estoque. Não tem efeito nenhum durante a execução do código, é apenas uma forma de dizer pro compilador que essa função está ali e mesmo que não seja usada para ele não emitir uma warning dizendo que ela está ali de enfeite. Muito útil o uso de stocks quando se está escrevendo bibliotecas para sourcepawn, observe que todas as includes que são usadas pelos plugins usam essa palavra chave em todas as suas funções.
  138. stock int ProcuraClientNoArray(int client) {
  139.     // Varre-se todo o array em busca de um elemento que seja igual ao nosso parâmetro client. Para isso nosso índice i deve começar do zero e ser sempre menor que g_hList.Length. Length é uma propriedade da classe ArrayList que retorna o número de elementos contidos na lista.
  140.     for (int i = 0; i < g_hList.Length; i++) {
  141.         int elemento = g_hLista.Get(i); // Para obter um elemento celular de uma lista, use o método Get.
  142.         if (elemento == client)
  143.             return i; // Se o elemento for igual, retorne o seu índice na lista.
  144.     }
  145.    
  146.     return -1; // Senão retorne -1.
  147. }
  148.  
  149. // Como a classe ArrayList não provém nenhum método que permite a inserção de um elemento em um índice qualquer, segue abaio uma possível implementação de tal função.
  150. stock void InsereNoArray(int elemento, int indice) {
  151.     if (indice < 0 || indice > g_hList.Length) // Verifica se o índice é válido, ou seja, se está entre zero e o tamanho da lista.
  152.         ThrowError("O índice do array deve ser maior ou igual a zero e menor ou igual ao tamanho dele."); // Senão lança uma exceção. No sourcepawn ainda não é possível lançar exceções de tipos específicos como na maiora das linguagens, nem capturar exceções ou outras construções como por exemplo try finally.
  153.        
  154.     if (indice == g_hList.Length) // Se o índice for igual ao tamanho da lista, insere o elemento no final da lista.
  155.         g_hLista.Push(elemento);
  156.     else { // Senão...
  157.         ShiftUp(indice); // Desloca os elementos à direita (da menor para a maior posição) a partir do índice desejado para que esse índice fique livre.
  158.         g_hLista.Set(indice, elemento); // Modifica o valor da posição no índice que agora está livre, para o nosso elemento desejado.
  159.     }
  160. }
RAW Paste Data