From 45556710f40322e003434a2aa385775cb49b80ca Mon Sep 17 00:00:00 2001 From: Crazy_ArKzX Date: Mon, 17 Nov 2025 14:15:41 -0300 Subject: [PATCH 1/3] Translation | PT-BR - All File of "server" archive --- .../current/server/CommonServerIssues.md | 83 ++++ .../current/server/Installation.md | 395 +++++++++++++++ .../current/server/LinuxServerInstallation.md | 207 ++++++++ .../current/server/config.json.md | 249 ++++++++++ .../current/server/omp-functions.md | 453 ++++++++++++++++++ .../current/server/server.cfg.md | 126 +++++ 6 files changed, 1513 insertions(+) create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/CommonServerIssues.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/Installation.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/LinuxServerInstallation.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/config.json.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/omp-functions.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/server.cfg.md diff --git a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/CommonServerIssues.md b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/CommonServerIssues.md new file mode 100644 index 00000000000..d529e11c913 --- /dev/null +++ b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/CommonServerIssues.md @@ -0,0 +1,83 @@ +--- +title: Problemas Comuns do Servidor +sidebar_label: Problemas Comuns do Servidor +--- + +## Servidor trava instantaneamente ao ser iniciado + +Na maioria das vezes é um erro no seu arquivo server.cfg ou seu gamemode está faltando. Verifique o arquivo server_log.txt e a razão deve estar localizada no final. Se não estiver, verifique o arquivo crashinfo.txt. A melhor solução para descobrir o que está causando a falha é usar o plugin Crash detect por Zeex/0x5A656578 ([clique para o link](https://github.com/Zeex/samp-plugin-crashdetect)) que fornecerá mais informações como números de linha, nomes de funções, valores de parâmetros, etc. Se o script for compilado em modo debug (flag -d3) para fazer o compilador colocar informações extras sobre tudo isso no arquivo .amx de saída. + +## Servidor não está funcionando - firewall está desativado + +Você precisará redirecionar suas portas para permitir que os jogadores entrem no seu servidor. Você pode redirecionar suas portas usando o PF Port Checker. Baixe em: www.portforward.com Se as portas não estiverem redirecionadas, significa que você precisa abri-las no seu roteador. Você pode verificar a lista de roteadores em [http://portforward.com/english/routers/port_forwarding/routerindex.htm](http://portforward.com/english/routers/port_forwarding/routerindex.htm "http://portforward.com/english/routers/port_forwarding/routerindex.htm") + +Tem todas as informações sobre como redirecionar portas. + +## 'Packet was modified' + +O erro comumente mostrado como: + +``` +[hh:mm:ss] Packet was modified, sent by id: , ip: : +``` + +acontece quando um jogador sofre timeout ou está tendo problemas de conexão no momento. + +## 'Warning: client exceeded messageslimit' + +O erro comumente mostrado como: + +``` +Warning: client exceeded 'messageslimit' (1) : () Limit: x/sec +``` + +acontece quando o número de mensagens por segundo que um cliente envia ao servidor excede o limite. + +## 'Warning: client exceeded ackslimit' + +O erro comumente mostrado como: + +``` +Warning: client exceeded 'ackslimit' : () Limit: x/sec +``` + +acontece quando o limite de acks é excedido. + +## 'Warning: client exceeded messageholelimit' + +O erro comumente mostrado como: + +``` +Warning: client exceeded 'messageholelimit' () : () Limit: x +``` + +acontece quando o limite de lacunas de mensagens é excedido. + +## 'Warning: Too many out-of-order messages' + +O erro comumente mostrado como: + +``` +Warning: Too many out-of-order messages from player : () Limit: x (messageholelimit) +``` + +Acontece quando 'mensagens fora de ordem' reutiliza a configuração messageholelimit. + +Para mais informações sobre isso, consulte [isto](ControllingServer#RCON_Commands) + +## Jogadores constantemente recebendo erro "Unacceptable NickName" mas o nome é válido + +Se você tem certeza de que está usando um nome aceitável e o servidor está rodando no Windows, tente alterar a opção de compatibilidade do samp-server.exe para Windows 98 e isso deve ser corrigido após reiniciar o servidor. + +Servidores Windows com alto tempo de atividade também podem causar esse problema. Isso foi observado em torno de 50 dias de tempo de atividade do servidor. Para resolver, é necessária uma reinicialização. + +## `MSVCR___.dll`/`MSVCP___.dll` não encontrado + +Este problema ocorre regularmente em servidores Windows ao tentar carregar um plugin que foi desenvolvido usando uma versão superior do runtime Visual C++ do que a atualmente instalada no seu computador. Para corrigir isso, baixe as bibliotecas de runtime apropriadas do Microsoft Visual C++. Note que o servidor SA-MP é de 32 bits, portanto você também precisará baixar a versão 32 bits (x86) do runtime, independentemente da arquitetura. A versão do runtime que você precisa especificamente é indicada pelos números no nome do arquivo (veja a tabela abaixo), embora não faça mal instalar todos eles. Essas bibliotecas não se empilham, ou em outras palavras: você não terá os runtimes para as versões 2013 e anteriores se instalar apenas a versão 2015. + +| Número da versão | Runtime | +| ---------------- | --------------------------------------------- | +| 10.0 | Microsoft Visual C++ 2010 x86 Redistributable | +| 11.0 | Microsoft Visual C++ 2012 x86 Redistributable | +| 12.0 | Microsoft Visual C++ 2013 x86 Redistributable | +| 14.0 | Microsoft Visual C++ 2015 x86 Redistributable | diff --git a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/Installation.md b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/Installation.md new file mode 100644 index 00000000000..ed7df9e7e1c --- /dev/null +++ b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/Installation.md @@ -0,0 +1,395 @@ +**Este tutorial é para aqueles que desejam transferir seu gamemode de servidor SA:MP para servidor open.mp.** + +:::note + +Se você está usando o plugin FCNPC, por favor pare por enquanto porque este plugin não funciona para open.mp atualmente. + +::: + +## Passo 1 + +Baixe a versão mais recente dos arquivos do servidor open.mp em [https://github.com/openmultiplayer/open.mp/releases](https://github.com/openmultiplayer/open.mp/releases/latest) + +![]() + +- `open.mp-win-x86.zip` Servidor **Windows** +- `open.mp-linux-x86.tar.gz` Servidor **Linux** +- `open.mp-linux-x86-dynssl.tar.gz` Servidor **Linux** (SSL Dinâmico) + +## Passo 2 + +Extraia o conteúdo do arquivo `.zip` ou `.tar.gz` no seu disco + +![]() + +:::note + +- **components:** componentes do open.mp +- **filterscripts:** Arquivos de filter script do seu servidor (scripts secundários) +- **gamemodes:** Arquivos de game mode do seu servidor (scripts principais) +- **models:** Modelos personalizados do seu servidor (texturas .txd .dff) +- **plugins:** Arquivos de plugin do seu servidor (plugins legados) +- **qawno:** Programa editor Pawn e includes do seu servidor +- **scriptfiles:** Arquivos INI ou outras coisas. +- **bans.json:** Arquivo de lista de banimentos +- **config.json:** Arquivo de configuração do servidor +- **omp-server.exe:** Programa do servidor open.mp +- **omp-server.pdb:** Arquivo de depuração do servidor open.mp + +::: + +## Passo 3 + +Coloque seu arquivo `.pwn` do gamemode na pasta **gamemodes** + +## Passo 4 + +Coloque os includes necessários (por exemplo, `sscanf2.inc`, `streamer.inc`) na pasta **qawno/include** + +:::note + +Se você está usando os includes YSI-4 no seu game mode, atualize para [YSI-5.x](https://github.com/pawn-lang/YSI-Includes/releases) + +::: + +## Passo 5 + +Coloque os plugins necessários (por exemplo, `sscanf.dll`, `streamer.dll`) na pasta **plugins** + +
+ +:::warning + +Se você usa os seguintes plugins da tabela, você deve colocar uma versão do plugin que seja compatível com omp! + +Coloque os seguintes plugins na pasta **../components**, não na pasta **../plugins**! + +::: + +| Plugin | OMP | +| ----------------- | ---------------------------------------------------------------------------- | +| Pawn.CMD | https://github.com/katursis/Pawn.CMD/releases/tag/3.4.0-omp | +| Pawn.RakNet | https://github.com/katursis/Pawn.RakNet/releases/tag/1.6.0-omp | +| sampvoice | https://github.com/AmyrAhmady/sampvoice/releases/tag/v3.1.5-omp | +| discord-connector | https://github.com/maddinat0r/samp-discord-connector/releases/tag/v0.3.6-pre | +| SKY | Use Pawn.RakNet em vez disso | +| YSF | Você não precisa do YSF porque o open.mp já declarou a maioria das mesmas natives | +| FCNPC | Atualmente não suportado | + +## Passo 6 + +Abra o programa qawno IDE localizado em **Server/qawno/qawno.exe** + +![]() + +## Passo 7 + +Pressione **CTRL + O** e vá para a pasta **../gamemodes** e abra seu arquivo `.pwn` do gamemode + +## Passo 8 + +Encontre + +```pawn +#include +``` + +substitua por + +```pawn +#include +``` + +depois pressione **F5** para compilar. + +## Passo 9 + +Abra o arquivo **[config.json](https://www.open.mp/docs/server/config.json)** com o Bloco de Notas ou outras IDEs + +![]() + +## Passo 10 + +Edite o **config.json** + +![]() + +Encontre + +```json +"main_scripts": [ + "gungame 1" +], +``` + +substitua por + +```json +"main_scripts": [ + "nome_do_arquivo_amx_do_seu_gamemode 1" +], +``` + +
+ +Encontre + +```json +"legacy_plugins": [], +``` + +Especifique os plugins necessários + +```json +"legacy_plugins": [ + "crashdetect", + "mysql", + "sscanf", + "streamer", + "PawnPlus", + "pawn-memory" +], +``` + +
+ +Encontre + +```json +"side_scripts": [] +``` + +Especifique seus filterscripts + +```json +"side_scripts": [ + "filterscripts/nome_do_arquivo" +] +``` + +
+ +Encontre + +```json +"rcon": { + "allow_teleport": false, + "enable": false, + "password": "changeme1" +}, +``` + +Digite uma senha forte para a senha do rcon: + +```json +"rcon": { + "allow_teleport": false, + "enable": false, + "password": "151sd80hgse32q1oi0v8dsge166" +}, +``` + +Pressione **CTRL + S** para salvar as alterações. + +:::tip + +Há um guia sobre como converter `server.cfg` para `config.json` em https://www.open.mp/docs/server/config.json + +::: + +## Passo 11 + +Execute o servidor + +- **Windows** + +Abra o programa `omp-server.exe` + +![]() + +- **Linux** + +```bash +./omp-server +``` + +## Erros e avisos do compilador + +- **warning 213: tag mismatch: expected tag "?", but found none ("\_")**: + +Por exemplo: + +```pawn +TogglePlayerControllable(playerid, 1); +// -> +TogglePlayerControllable(playerid, true); +``` + +
+ +```pawn +TextDrawFont(textid, 1); +// -> +TextDrawFont(textid, TEXT_DRAW_FONT_1); +``` + +
+ +```pawn +GivePlayerWeapon(playerid, 4, 1); +// -> +GivePlayerWeapon(playerid, WEAPON_KNIFE, 1); +``` + +Mas você pode ignorar por enquanto: + +```pawn +#define NO_TAGS +#include + +// Se o aviso ainda ocorrer +// Use #pragma warning disable 213 +``` + +
+ +
+ +- **warning 234: function is deprecated (symbol "TextDrawColor") Use `TextDrawColour** + +Pressione **CTRL + F** no qawno e substitua todos os `TextDrawColor` por `TextDrawColour` + +![]() + +
+ +Ou se você preferir, pode usar as grafias mistas: + +```pawn +#define MIXED_SPELLINGS +#include +``` + +
+ +
+ +- **warning 234: function is deprecated (symbol "GetPlayerPoolSize") This function is fundamentally broken.** +- **warning 234: function is deprecated (symbol "GetVehiclePoolSize") This function is fundamentally broken.** +- **warning 234: function is deprecated (symbol "GetActorPoolSize") This function is fundamentally broken.** + +Substitua `GetPlayerPoolSize()` por `MAX_PLAYERS` + +Substitua `GetVehiclePoolSize()` por `MAX_VEHICLES` + +Substitua `GetActorPoolSize()` por `MAX_ACTORS` + +
+ +- **warning 234: function is deprecated (symbol "SHA256_PassHash") Use BCrypt for hashing passwords** + +Use o plugin [samp-bcrypt](https://github.com/Sreyas-Sreelal/samp-bcrypt) para hash de senhas. SHA-256 não é seguro. + +
+ +- **warning 214: possibly a "const" array argument was intended: "?"** +- **warning 239: literal array/string passed to a non-const parameter** + +Por exemplo: + +```pawn +public MyFunction(string[]) +// -> +public MyFunction(const string[]) +``` + +
+ +
+ +- **error 025: function heading differs from prototype** + +Por exemplo: + +```pawn +public OnPlayerDeath(playerid, killerid, reason) +// -> +public OnPlayerDeath(playerid, killerid, WEAPON:reason) +``` + +
+ +```pawn +public OnPlayerEditAttachedObject(playerid, response, index, modelid, boneid, Float:fOffsetX, Float:fOffsetY, Float:fOffsetZ, Float:fRotX, Float:fRotY, Float:fRotZ, Float:fScaleX, Float:fScaleY, Float:fScaleZ) +// -> +public OnPlayerEditAttachedObject(playerid, EDIT_RESPONSE:response, index, modelid, boneid, Float:fOffsetX, Float:fOffsetY, Float:fOffsetZ, Float:fRotX, Float:fRotY, Float:fRotZ, Float:fScaleX, Float:fScaleY, Float:fScaleZ) +``` + +
+ +
+ +:::note + +Também existe uma ferramenta de atualização que tenta encontrar código antigo sem tags e com const incorreto e atualizá-lo. + +https://github.com/openmultiplayer/upgrade + +Já incluída na pasta `/qawno/upgrader`. + +::: + +## Erros e avisos em tempo de execução + +``` +[Info] Couldn't announce legacy network to open.mp list. +[Info] [Server Error] Status: 406 +[Info] [Server Error] Message: {"error":"failed to query server: socket read timed out"} +[Info] This won't affect the server's behaviour. +``` + +- Seu servidor não está acessível a partir do site open.mp. +- Você provavelmente está executando o servidor localmente. +- O firewall bloqueou a conexão. + +**Este aviso não afetará o comportamento do servidor.** + +
+ +
+ +``` +[Warning] Insufficient specifiers given to `format`: "?" < 1 +``` + +Os especificadores são menores que os argumentos que você passa no format. Por exemplo: + +```pawn +new string[32]; +new mp[32] = ".MP"; + +format(string, sizeof(string), "OPEN", mp); +// [Warning] Insufficient specifiers given to `format`: "OPEN" < 1 + +// Deveria ser: +format(string, sizeof(string), "OPEN%s", mp); +// ^^ +``` + +## Documentos úteis + +Confira as novas funções e callbacks de script: https://www.open.mp/docs/server/omp-functions + +Se você é completamente novo na programação Pawn: [readme-beginner](https://github.com/openmultiplayer/omp-stdlib/blob/master/documentation/readme-beginner.md) + +Se você é intermediário na programação Pawn: [readme-intermediate](https://github.com/openmultiplayer/omp-stdlib/blob/master/documentation/readme-intermediate.md) + +Se você é especialista na programação Pawn: [readme-expert](https://github.com/openmultiplayer/omp-stdlib/blob/master/documentation/readme-expert.md) + +Postagem no blog: [Portando para open.mp](https://www.open.mp/blog/porting) + +## Ajuda + +Se você ainda tiver problemas ao executar o servidor, junte-se ao servidor Discord oficial do open.mp: https://discord.gg/samp + +Pergunte no canal [#openmp-support](https://discord.com/channels/231799104731217931/966398440051445790). diff --git a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/LinuxServerInstallation.md b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/LinuxServerInstallation.md new file mode 100644 index 00000000000..b08bdf92a00 --- /dev/null +++ b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/LinuxServerInstallation.md @@ -0,0 +1,207 @@ +**Este guia contém um guia abrangente sobre como instalar um servidor open.mp no Ubuntu ou em outro Linux baseado em Debian. +Seja você um iniciante ou apenas queira atualizar seus conhecimentos, este guia pode ter algo útil para você!** + +:::warning + +Se você está usando o servidor SA:MP e ainda não converteu para open.mp, **[por favor pare aqui e leia este guia primeiro.](https://www.open.mp/docs/server/Installation)** + +::: + +:::note + +Se você está usando o plugin FCNPC, por favor pare por enquanto porque este plugin não funciona para open.mp atualmente. + +::: + +## Pré-requisitos + +Antes de começar, você deve ter: + +- Uma máquina executando Ubuntu (20.04 ou posterior recomendado) ou outro Linux baseado em Debian; +- WinSCP ou Filezilla para transferências de arquivos; +- PuTTY ou sua solução SSH de hospedagem; + +:::note + +Se você instalar o WinSCP, o instalador solicitará que você instale o PuTTY! +Depende de você se deseja instalá-lo ou não, mas você sempre pode baixá-lo mais tarde! + +::: + +## Fase 1: Preparando o Ambiente + +1. Conectando via SSH: + - Use o PuTTY ou sua solução SSH de hospedagem para se conectar à sua instância. + +:::note + +Procure guias online ou a documentação do seu provedor de hospedagem se não tiver certeza de como se conectar à sua Instância Linux. + +::: + +2. Atualizando sua Instância Linux: + + - Antes de prosseguir, vamos garantir que seu sistema esteja atualizado executando: + + ``` + sudo apt update + ``` + + ``` + sudo apt upgrade + ``` + +3. Criando uma conta de serviço segura: + + - Por razões de segurança, devemos criar uma conta de serviço dedicada sem um diretório home: + + ``` + sudo useradd -M svc-omp-server + ``` + +4. Bloqueando a conta de serviço: + + - Vamos impedir que a conta de serviço seja usada para login: + + ``` + sudo usermod -L svc-omp-server + ``` + +5. Criando um diretório para os arquivos do servidor: + + - Usaremos o diretório /opt, este é o local padrão para aplicações de terceiros: + + ``` + sudo mkdir /opt/omp-server + ``` + +6. Definindo permissões para o diretório: + + - Alterando o grupo do diretório para corresponder à conta de serviço: + + ``` + sudo chgrp svc-omp-server /opt/omp-server + ``` + + - Definindo a flag g+s para que novos arquivos herdem o grupo correto e removendo o acesso para outros: + + ``` + sudo chmod g+s /opt/omp-server + ``` + + ``` + sudo chmod o-rwx /opt/omp-server + ``` + +
+ +## Fase 2: Instalando os Arquivos do Servidor open.mp + +7. Vamos navegar para o diretório do servidor: + + - Precisamos ir para o diretório /opt/omp-server onde o servidor será armazenado: + + ``` + cd /opt/omp-server + ``` + +8. Baixando os arquivos do servidor open.mp: + + - Baixe a versão mais recente do servidor open.mp: + + ``` + sudo -u svc-omp-server wget https://github.com/openmultiplayer/open.mp/releases/download/vX.X.X.XXXX/open.mp-linux-x86.tar.gz + ``` + +:::warning + +**Você deve SEMPRE verificar a versão mais recente na página de Releases do GitHub do open.mp!** +[https://github.com/openmultiplayer/open.mp/releases](https://github.com/openmultiplayer/open.mp/releases) + +::: + +9. Extraindo os arquivos do servidor: + + - Uma vez baixado, extraia os arquivos: + + ``` + sudo -u svc-omp-server tar -xzf open.mp-linux-x86.tar.gz + ``` + +
+ +## Fase 3: Configurando e Iniciando o Servidor + +10. Instalando as bibliotecas x86 necessárias: + + - Como o servidor roda como uma aplicação de 32 bits, você precisa habilitar o suporte para arquitetura de 32 bits: + + ``` + sudo dpkg --add-architecture i386 + ``` + + ``` + sudo apt update + ``` + + ``` + sudo apt install libc6:i386 + ``` + +11. Tornando o servidor executável: + + - Altere as permissões para que o servidor possa ser executado (necessário apenas uma vez!): + + ``` + cd /opt/omp-server/Server/ + ``` + + ``` + sudo chmod +x omp-server + ``` + +12. Iniciando o servidor: + + - Use o seguinte comando para iniciar o servidor em segundo plano: + + ``` + nohup ./omp-server & + ``` + + - O terminal exibirá um ID de processo (PID). Anote este número para referência futura. + +
+ +## Fase 4: Gerenciando o Servidor + +13. Parando o servidor: + + - Para parar o servidor, use o PID do passo 12 e execute: + + ``` + sudo kill + ``` + +14. Encontrando o ID do Processo (se esquecido): + + - Se você esquecer o ID do processo, execute: + + ``` + top + ``` + + - Procure pelo processo omp-server na lista, anote o PID, pressione 'Q' para sair e então finalize o processo conforme mostrado no passo 13. + +
+ +## Fase 5: Enviando Seu Gamemode e Arquivos + +15. Envie seus gamemodes e scripts personalizados: + - Use o WinSCP ou Filezilla para transferir seus gamemodes e scripts para o diretório /opt/omp-server. + Importante: Certifique-se de usar arquivos .so para plugins Linux, pois arquivos .dll são suportados apenas no Windows. + +## Ajuda + +Se você ainda estiver enfrentando problemas para configurar o servidor, junte-se ao servidor Discord oficial do open.mp: [https://discord.gg/samp](https://discord.gg/samp) + +Poste sua pergunta no canal [#openmp-support](https://discord.com/channels/231799104731217931/966398440051445790) e mencione este guia para que possamos melhorá-lo. diff --git a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/config.json.md b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/config.json.md new file mode 100644 index 00000000000..40f7e89f79d --- /dev/null +++ b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/config.json.md @@ -0,0 +1,249 @@ +--- +title: config.json +sidebar_label: config.json +description: Arquivo de configuração do servidor open.mp. +--- + +## Descrição + +- `config.json` é um arquivo de configuração do servidor que permite alterar todos os tipos de configurações do seu servidor open.mp. +- Você ainda pode usar o arquivo [server.cfg](server.cfg) no seu servidor open.mp, mas é recomendado usar config.json porque há mais configurações disponíveis! + +
+ +
+ +
+ +:::tip + +Você pode simplesmente converter seu server.cfg para config.json. + +Abra um prompt de comando no diretório do seu servidor e digite o seguinte comando, depois pressione Enter: + +```bash +# Windows +omp-server --dump-config + +# Linux +./omp-server --dump-config +``` + +**Nota:** Se você já tem um arquivo config.json no diretório, pode ser necessário deletá-lo antes de executar o comando acima. + +::: + +
+ +:::tip + +Para gerar um config.json padrão, digite o seguinte comando: + +```bash +# Windows +omp-server --default-config + +# Linux +./omp-server --default-config +``` + +::: + +
+ +## Anunciar + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| -------- | ---- | ------------ | --------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| announce | bool | true | ❌ | ❌ | Define se o servidor deve ser anunciado na lista principal do open.mp. Defina como '**true**' para ativar ou '**false**' para desativar. | + +## Modelos Personalizados (Artwork) + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ----------------------- | ------ | ------------ | --------------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| artwork.cdn | string | | ✅ | ❌ | Um endereço http para um servidor de modelos remoto. | +| artwork.enable | bool | true | ✅ | ✅ | Define se o servidor usa modelos personalizados da pasta /models. Defina como '**true**' para ativar ou '**false**' para desativar. | +| artwork.models_path | string | models | ✅ | ❌ | O caminho onde os modelos personalizados estão localizados. | +| artwork.port | int | 7777 | ✅ | ❌ | | +| artwork.web_server_bind | string | | ✅ | ❌ | | + +## Filtro de Chat + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ----------------- | ---- | ------------ | --------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| chat_input_filter | bool | true | ❌ | ❌ | Ativa/desativa o filtro de entrada do chat. Desative para usar caracteres como % no chat. Você também pode usar a função [ToggleChatTextReplacement](../scripting/functions/ToggleChatTextReplacement). | + +## Informações do Servidor de Consulta + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ------------ | ---- | ------------ | --------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| enable_query | bool | true | ❌ | ❌ | Define se as informações do servidor devem ser exibidas no navegador de servidores. Defina como '**true**' para ativar ou '**false**' para desativar. Os jogadores ainda podem entrar em um servidor que desabilitou a consulta, mas o navegador não exibirá nenhuma informação. | + +## Jogo + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ---------------------------------- | ------ | ------------ | --------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| game.allow_interior_weapons | bool | true | ❌ | ❌ | Define se o uso de armas em interiores é permitido ou não. '**true**' para ativar armas em interiores, '**false**' para desativar. | +| game.chat_radius | float | 200.0 | ❌ | ❌ | Define uma limitação de raio para o chat. Apenas jogadores a uma certa distância do jogador verão sua mensagem no chat. Também altera a distância na qual um jogador pode ver outros jogadores no mapa na mesma distância. | +| game.death_drop_amount | int | 0 | ❌ | ❌ | | +| game.gravity | float | 0.008 | ❌ | ✅ | A gravidade global que o servidor usa. | +| game.group_player_objects | bool | false | ❌ | ❌ | Objetos por jogador e objetos globais compartilham um pool de IDs no SA:MP. Se um ID foi "atribuído" aos jogadores, cada jogador poderia ter um objeto único com esse ID, mas se você criasse o máximo de objetos globais, não poderia criar nenhum objeto por jogador.
Se o agrupamento de objetos de jogador estiver ativado, o servidor tentará encontrar um slot de objeto de jogador já usado por outro jogador. | +| game.lag_compensation_mode | int | 1 | ✅ | ✅ | **0**: Desativa completamente a compensação de lag.

**1**: Ativa completamente a compensação de lag.

**2**: Ativa apenas a compensação de lag de posição. Isso significa que a rotação do jogador não terá compensação de lag. | +| game.map | string | | ❌ | ✅ | O nome do mapa que aparece no navegador de servidores. Pode ser qualquer coisa, por exemplo, Meu Mapa de Manobras. | +| game.mode | string | | ❌ | ❌ | O modo que será mostrado no navegador de servidores. Usar [SetGameModeText](../scripting/functions/SetGameModeText) tem o mesmo efeito e substitui o valor usado no config.json. Se você tem múltiplos gamemodes que requerem textos diferentes, use essa função. | +| game.nametag_draw_radius | float | 70.0 | ❌ | ❌ | Define a distância máxima para exibir os nomes dos jogadores. | +| game.player_marker_draw_radius | float | 250.0 | ❌ | ❌ | Define o raio do marcador para todos os jogadores. | +| game.player_marker_mode | int | 1 | ❌ | ❌ | **0**: Modo de marcador desligado

**1**: Modo de marcador global

**2**: Modo de marcador em streaming

[Modos de Marcador](../scripting/resources/markermodes) | +| game.time | int | 12 | ❌ | ✅ | O horário global que o servidor usa e que será mostrado no navegador de servidores. | +| game.use_all_animations | bool | false | ✅ | ❌ | Permite o uso das animações ausentes em algumas versões. '**true**' para ativar todas as animações, '**false**' para desativar. | +| game.use_chat_radius | bool | false | ❌ | ❌ | Ativa/Desativa o raio do chat. | +| game.use_entry_exit_markers | bool | true | ✅ | ❌ | Ativa/Desativa todas as entradas e saídas de interiores no jogo (as setas amarelas nas portas). | +| game.use_instagib | bool | false | ❌ | ❌ | instagib é uma variável configurável antiga que não está mais disponível no cliente sa-mp, o nome provavelmente foi tirado do jogo Quake, instagib é basicamente morte instantânea, ativa o recurso de um tiro e morte no jogo (não está disponível no momento porque o sa-mp removeu isso no lado do cliente) | +| game.use_manual_engine_and_lights | bool | false | ❌ | ❌ | Controla motores e luzes de veículos. **false**: impede que o jogo ligue/desligue automaticamente o motor quando os jogadores entram/saem de veículos e que os faróis acendam automaticamente quando está escuro. | +| game.use_nametag_los | bool | true | ❌ | ❌ | Ativa/desativa a Linha de Visão das nametags, barras de vida e armadura acima dos jogadores. | +| game.use_nametags | bool | true | ❌ | ❌ | Ativa/desativa o desenho de nametags, barras de vida e armadura acima dos jogadores. | +| game.use_player_marker_draw_radius | bool | false | ❌ | ❌ | Ativa/desativa os marcadores de jogadores (pontos no radar). | +| game.use_player_ped_anims | bool | false | ❌ | ❌ | Usa animação de caminhada padrão do jogador (animação da skin do CJ) em vez de animações personalizadas para cada skin (por exemplo, skate para skins de skatistas). | +| game.use_stunt_bonuses | bool | true | ❌ | ❌ | Ativa ou desativa bônus de manobras para todos os jogadores. Se ativado, os jogadores receberão recompensas em dinheiro ao realizar uma manobra em um veículo (por exemplo, empinar). | +| game.use_vehicle_friendly_fire | bool | false | ❌ | ❌ | Ativa fogo amigo para veículos de equipe. Os jogadores não poderão danificar veículos de companheiros de equipe. | +| game.use_zone_names | bool | false | ❌ | ❌ | Permite ativar nomes de zonas/áreas como o texto "Vinewood" ou "Doherty" no canto inferior direito da tela quando entram na área. | +| game.validate_animations | bool | true | ❌ | ❌ | Valida animações para os jogadores. | +| game.vehicle_respawn_time | int | 10000 | ❌ | ❌ | Define o tempo de respawn dos veículos em milissegundos. (Padrão 10 segundos) | +| game.weather | int | 10 | ❌ | ✅ | O clima global que o servidor usa e que será mostrado no navegador de servidores. | + +## Idioma + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| -------- | ------ | ------------ | --------------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------- | +| language | string | | ❌ | ❌ | O idioma que aparece no navegador de servidores. Os jogadores podem usar isso para filtrar servidores por idioma no navegador de servidores. | + +## Registro de Logs + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ------------------------------- | ------ | --------------------- | --------------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| logging.enable | bool | true | ❌ | ❌ | Ativa/Desativa o registro de logs. | +| logging.file | string | log.txt | ✅ | ❌ | O caminho e nome do arquivo para salvar o log do servidor. | +| logging.log_chat | bool | true | ❌ | ❌ | Define se o chat dos jogadores deve ser mostrado no console do servidor. Útil para evitar que o log fique sobrecarregado, ou se você tiver outra solução de registro de chat por script. Defina como '**true**' para ativar ou '**false**' para desativar. | +| logging.log_connection_messages | bool | true | ❌ | ❌ | Ativa/Desativa mensagens de entrada de jogadores e NPCs. | +| logging.log_cookies | bool | false | ❌ | ❌ | Ativa/desativa o registro de cookies de conexão solicitados por jogadores recém-conectados. Defina como '**true**' para ativar ou '**false**' para desativar. | +| logging.log_deaths | bool | true | ❌ | ❌ | Define se as mortes dos jogadores devem ser mostradas no console do servidor. Defina como '**true**' para ativar ou '**false**' para desativar. | +| logging.log_queries | bool | false | ❌ | ❌ | Define se todas as consultas enviadas ao servidor pelos jogadores devem ser registradas. Defina como '**true**' para ativar ou '**false**' para desativar. É consideravelmente útil durante um ataque DDoS. | +| logging.log_sqlite | bool | false | ❌ | ❌ | Registra erros de funções DB\_\* do sqlite no console do servidor. | +| logging.log_sqlite_queries | bool | false | ❌ | ❌ | Registra todas as chamadas DB_Query do sqlite, incluindo a string de consulta. | +| logging.timestamp_format | string | [%Y-%m-%dT%H:%M:%S%z] | ✅ | ❌ | O formato de timestamp que deve ser usado. O formato é baseado no formato [strftime](http://cplusplus.com/reference/clibrary/ctime/strftime/) de C/C++. Aqui estão alguns exemplos:

**[%H:%M:%S]** Exibe apenas o horário.

**[%d/%m/%Y %H:%M:%S]** Exibiria a data no formato dd/mm/aaaa seguido pelo horário no formato hora:minuto:segundo. | +| logging.use_prefix | bool | true | ❌ | ❌ | Define se prefixos como `[Info]` devem ser impressos com cada mensagem do console. Defina como '**true**' para ativar ou '**false**' para desativar. | +| logging.use_timestamp | bool | true | ❌ | ❌ | Define se um timestamp deve ser impresso com cada mensagem do console. Defina como '**true**' para ativar ou '**false**' para desativar. | + +## NPCs e Jogadores + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ----------- | ---- | ------------ | --------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| max_bots | int | 0 | ❌ | ❌ | A quantidade máxima de NPCs que seu servidor pode conter. Ao alterar este número, você pode modificar quantos dos slots de jogadores podem ser usados por NPCs. | +| max_players | int | 50 | ✅ | ❌ | A quantidade máxima de jogadores que seu servidor pode conter. Ao alterar este número, você pode modificar quantos jogadores podem entrar no servidor. O máximo é 1000 e o mínimo é 1. | + +## Nome do Servidor + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ----- | ------ | -------------- | --------------- | ----- | ---------------------------------------------------------------------------------------------------- | +| name | string | open.mp server | ❌ | ❌ | O nome que será mostrado no navegador de servidores e quando o jogador se conectar ao servidor. | + +## Rede + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ------------------------------- | ------ | ------------ | --------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| network.acks_limit | int | 3000 | ❌ | ❌ | | +| network.aiming_sync_rate\* | int | 30 | ✅ | ❌ | O tempo em milissegundos que um cliente deve atualizar o servidor com novos dados enquanto dispara uma arma. | +| network.allow_037_clients | bool | true | ❌ | ❌ | Define se jogadores com cliente 0.3.7 podem entrar no servidor. | +| network.use_omp_encryption | bool | false | ❌ | ❌ | Ativa/desativa a criptografia de pacotes open.mp para proteção extra (o protocolo padrão ainda funciona junto com ela). | +| network.bind | string | | ✅ | ❌ | O endereço IP que o servidor deve usar. O servidor será forçado a usar este endereço IP em vez de escolher automaticamente um IP livre. Este IP deve corresponder a um atribuído a uma placa de rede no servidor. Isso é útil para executar múltiplos servidores na mesma porta na mesma máquina. | +| network.cookie_reseed_time | int | 300000 | ❌ | ❌ | O tempo em milissegundos que o valor de seed do cookie de conexão é atualizado. | +| network.grace_period | int | 5000 | ❌ | ❌ | Este é um período de tolerância para permitir conexões ilimitadas do mesmo IP após iniciar o servidor, principalmente usado para NPCs.
Por padrão: 5 Segundos | +| network.http_threads | int | 50 | ❌ | ❌ | | +| network.in_vehicle_sync_rate\* | int | 30 | ✅ | ❌ | O tempo em milissegundos que um cliente deve atualizar o servidor com novos dados enquanto está em um veículo. | +| network.limits_ban_time | int | 60000 | ❌ | ❌ | Define o tempo de banimento do raknet para pacotes de conexão ruins em milissegundos. (Quando o limite de acks/mensagens é atingido.) | +| network.message_hole_limit | int | 3000 | ❌ | ❌ | Uma configuração de nível de rede para lidar com ataques DoS. | +| network.messages_limit | int | 500 | ❌ | ❌ | O número máximo de mensagens que um usuário pode enviar por segundo. | +| network.minimum_connection_time | int | 0 | ❌ | ❌ | O tempo em milissegundos que o servidor aguardará antes de aceitar outra conexão de entrada. Não é recomendado usar esta variável a menos que seu servidor esteja sob um ataque de flood de conexão. | +| network.mtu | int | 576 | ✅ | ❌ | Mantenha o valor padrão, você realmente não precisa ou deve alterar isso se não souber o que é, porque se você não sabe, então não tem nada no seu servidor que requer MTU mais alto, mas se ainda estiver interessado: https://en.wikipedia.org/wiki/Maximum_transmission_unit | +| network.multiplier | int | 10 | ❌ | ❌ | | +| network.on_foot_sync_rate\* | int | 30 | ✅ | ❌ | O tempo em milissegundos que um cliente deve atualizar o servidor com novos dados enquanto está a pé. | +| network.player_marker_sync_rate | int | 2500 | ✅ | ❌ | O tempo em milissegundos que um cliente deve atualizar o servidor com novos dados enquanto está se movendo. | +| network.player_timeout | int | 10000 | ❌ | ❌ | O tempo em milissegundos após o qual um jogador sofrerá timeout quando não enviar dados ao servidor. | +| network.port | int | 7777 | ✅ | ❌ | A porta que o servidor deve usar. Você precisará fazer [Redirecionamento de Porta](http://www.portforward.com/) para que os jogadores possam entrar no seu servidor de fora da sua LAN. | +| network.public_addr | string | | ✅ | ❌ | Algumas máquinas em que você executa seu servidor podem ter IPs diferentes, isso é usado para que, se o endereço que você definiu na configuração `bind` for diferente, você defina um novo. esta variável de configuração é usada apenas para servidores DL, porque no open.mp, ele hospedará um servidor web para download de modelos | +| network.stream_radius | float | 200.0 | ❌ | ❌ | A distância no plano X,Y em que os jogadores farão streaming das entidades do servidor. O máximo é **400.0** e o mínimo é **50.0**. Valores mais altos fazem os jogadores verem entidades do servidor a uma distância maior, mas requerem mais processamento do cliente e potencialmente mais largura de banda. | +| network.stream_rate | int | 1000 | ❌ | ❌ | O tempo em milissegundos antes que o streaming das entidades do servidor seja retestado para cada jogador. O máximo é **5000** e o mínimo é **500**. Valores mais baixos aumentam o processamento do servidor, pois ele precisa reverificar as condições de streaming com mais frequência para cada jogador. | +| network.time_sync_rate | int | 30000 | ❌ | ❌ | A taxa na qual o horário do jogo de um jogador é atualizado em milissegundos. | +| network.use_lan_mode | bool | false | ❌ | ❌ | Variável obsoleta, não tem efeito. | + +> [*] Valores mais baixos de `aiming_sync_rate`, `in_vehicle_sync_rate` e `on_foot_sync_rate` aumentam o desempenho de sincronização, mas usam mais largura de banda. + +## Bloqueio do Servidor + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| -------- | ------ | ------------ | --------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| password | string | | ❌ | ❌ | A senha usada para bloquear o servidor. Ao usar isso, apenas jogadores que conhecem esta senha poderão entrar no servidor. | + +## Pawn + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ------------------- | ------------ | ------------ | --------------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| pawn.legacy_plugins | list, string | [] | ✅ | ❌ | O arquivo .dll ou .so na pasta /plugins que o servidor deve usar para executar como plugin. Plugins são scripts que são projetados para aprimorar gamemodes e filterscripts.
Exemplo: `["mysql", "streamer"]` | +| pawn.main_scripts | list, string | ["test 1"] | ✅ | ❌ | O arquivo .amx na pasta /gamemodes que o servidor deve usar para executar como gamemode. | +| pawn.side_scripts | list, string | [] | ✅ | ❌ | O arquivo .amx na pasta /filterscripts que o servidor deve usar para executar como filterscript. Filterscripts são scripts que rodam em segundo plano do seu gamemode. Eles servem para adicionar extras ao servidor sem editar o gamemode. É muito útil se você quiser carregar uma propriedade específica para mais de um gamemode.
Exemplo: `["filterscripts/Race_System"]` | + +## RCON + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ------------------- | ------ | ------------ | --------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| rcon.allow_teleport | bool | false | ✅ | ❌ | Determina se os administradores RCON serão teleportados para seu waypoint quando definirem um. Defina como '**true**' para ativar ou '**false**' para desativar. | +| rcon.enable | bool | false | ✅ | ❌ | Define se o recurso de [Console Remoto](RemoteConsole) deve ser usado. Defina como '**true**' para ativar ou '**false**' para desativar. | +| rcon.password | string | changeme | ❌ | ❌ | A senha usada para administrar o servidor e usar o console remoto (rcon). Você deve certificar-se de alterar isso para algo difícil de decifrar para que outros não possam assumir o controle do seu servidor. Seu servidor NÃO iniciará se changeme for a senha RCON! | + +## Sleep e Ticks + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ------------- | ----- | ------------ | --------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| sleep | float | 5.0 | ❌ | ❌ | O tempo em milissegundos que a thread principal do open.mp e da rede raknet "dormirá" ociosamente durante cada ciclo de sincronização. Valores mais altos diminuem o processamento do servidor, mas reduzem a qualidade da sincronização. Valores mais baixos aumentam o processamento do servidor, mas melhoram a qualidade da sincronização. Não é aconselhável alterar este valor a menos que sua contagem de jogadores seja muito alta e você tenha problemas de estabilidade de fps do servidor. | +| use_dyn_ticks | bool | true | ✅ | ❌ | A configuração dynticks serve basicamente para manter a taxa de ticks do seu servidor em uma contagem constante usando mais CPU para cobrir a lacuna se houver alguma queda.
É calculada usando o valor de sleep fornecido, então se sleep for 5, a contagem constante de ticks seria 1000 / 5 = 200 ticks por segundo.
O open.mp modifica o valor interno de sleep em tempo real com base no tempo de execução do código de cada tick, apenas para mantê-lo estável em 200 ticks, e sleep menor significa mais uso de CPU (que não é uma diferença massiva se o código do servidor for bem escrito) | + +## URL Web + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ------- | ------ | ------------ | --------------- | ----- | ----------------------------------------------------------------------------------- | +| website | string | open.mp | ❌ | ✅ | O site que as pessoas podem visitar para obter mais informações sobre o servidor. | + +## Discord + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| -------------- | ------ | ----------------------- | --------------- | ----- | ------------------------------------------------------------------------------------ | +| discord.invite | string | https://discord.gg/samp | ❌ | ❌ | O endereço do discord do seu servidor que aparece no launcher do omp. | + +![](https://i.ibb.co/cTRq5pr/294345382-54d77460-da32-458e-bcfa-10ebec90fbfa.png) + +## Banners + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ------------- | ------ | ------------ | --------------- | ----- | ---------------------------------------------------------------------------------------- | +| banners.light | string | | ❌ | ❌ | O endereço url do banner claro do seu servidor que aparece no launcher do omp. | +| banners.dark | string | | ❌ | ❌ | O endereço url do banner escuro do seu servidor que aparece no launcher do omp. | + +![](https://i.ibb.co/86T8wYG/image.png) + +## Logo do Servidor + +| Chave | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ----- | ------ | ------------ | --------------- | ----- | ------------------------------------------------------------------------------------------------------- | +| logo | string | | ❌ | ❌ | O endereço url do logo do seu servidor que aparece no launcher do omp e no status do discord. | + +![](https://i.ibb.co/VQZch1Y/image-1.png) + +
+ +:::note + +- Valores marcados como "Somente leitura" não podem ser alterados durante a execução. Todos os outros valores podem ser (temporariamente) alterados passando-os para [SendRconCommand](../scripting/functions/SendRconCommand) ou via console do servidor. + +- Valores marcados como "Regra" são exibidos no navegador de servidores na seção Regras. + +::: \ No newline at end of file diff --git a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/omp-functions.md b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/omp-functions.md new file mode 100644 index 00000000000..026208a677a --- /dev/null +++ b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/omp-functions.md @@ -0,0 +1,453 @@ +--- +title: Funções do open.mp +sidebar_label: Funções do open.mp +description: Novas funções e callbacks. +--- + +Esta página contém todas as funções e callbacks que foram adicionadas no open.mp + +## Jogador + +| Nome | +| ----------------------------------------------------------------------------------- | +| [TogglePlayerWidescreen](../scripting/functions/TogglePlayerWidescreen) | +| [IsPlayerWidescreenToggled](../scripting/functions/IsPlayerWidescreenToggled) | +| [SetPlayerGravity](../scripting/functions/SetPlayerGravity) | +| [GetPlayerGravity](../scripting/functions/GetPlayerGravity) | +| [ClearPlayerWorldBounds](../scripting/functions/ClearPlayerWorldBounds) | +| [GetPlayerRotationQuat](../scripting/functions/GetPlayerRotationQuat) | +| [GetPlayerSpectateID](../scripting/functions/GetPlayerSpectateID) | +| [GetPlayerSpectateType](../scripting/functions/GetPlayerSpectateType) | +| [GetPlayerSurfingOffsets](../scripting/functions/GetPlayerSurfingOffsets) | +| [GetPlayerWorldBounds](../scripting/functions/GetPlayerWorldBounds) | +| [GetPlayerZAim](../scripting/functions/GetPlayerZAim) | +| [IsPlayerSpawned](../scripting/functions/IsPlayerSpawned) | +| [GetPlayerHydraReactorAngle](../scripting/functions/GetPlayerHydraReactorAngle) | +| [GetPlayerLandingGearState](../scripting/functions/GetPlayerLandingGearState) | +| [GetPlayerLastSyncedTrailerID](../scripting/functions/GetPlayerLastSyncedTrailerID) | +| [GetPlayerSirenState](../scripting/functions/GetPlayerSirenState) | +| [GetPlayerTrainSpeed](../scripting/functions/GetPlayerTrainSpeed) | +| [IsPlayerInModShop](../scripting/functions/IsPlayerInModShop) | +| [GetPlayerDialogData](../scripting/functions/GetPlayerDialogData) | +| [GetPlayerDialogID](../scripting/functions/GetPlayerDialogID) | +| [HidePlayerDialog](../scripting/functions/HidePlayerDialog) | +| [GetPlayerWeather](../scripting/functions/GetPlayerWeather) | +| [GetPlayerSkillLevel](../scripting/functions/GetPlayerSkillLevel) | +| [GetPlayerRawIp](../scripting/functions/GetPlayerRawIp) | +| [GetPlayerAttachedObject](../scripting/functions/GetPlayerAttachedObject) | +| [GetSpawnInfo](../scripting/functions/GetSpawnInfo) | +| [GetPlayerBuildingsRemoved](../scripting/functions/GetPlayerBuildingsRemoved) | +| [RemovePlayerWeapon](../scripting/functions/RemovePlayerWeapon) | +| [AllowPlayerWeapons](../scripting/functions/AllowPlayerWeapons) | +| [IsPlayerControllable](../scripting/functions/IsPlayerControllable) | +| [IsPlayerCameraTargetEnabled](../scripting/functions/IsPlayerCameraTargetEnabled) | +| [TogglePlayerGhostMode](../scripting/functions/TogglePlayerGhostMode) | +| [GetPlayerGhostMode](../scripting/functions/GetPlayerGhostMode) | +| [GetPlayerAnimationFlags](../scripting/functions/GetPlayerAnimationFlags) | +| [GetDefaultPlayerColour](../scripting/functions/GetDefaultPlayerColour) | +| [PlayerHasClockEnabled](../scripting/functions/PlayerHasClockEnabled) | +| [IsPlayerUsingOfficialClient](../scripting/functions/IsPlayerUsingOfficialClient) | +| [IsPlayerUsingOmp](../scripting/functions/IsPlayerUsingOmp) | +| [IsPlayerInDriveByMode](../scripting/functions/IsPlayerInDriveByMode) | +| [IsPlayerCuffed](../scripting/functions/IsPlayerCuffed) | +| [SetPlayerAdmin](../scripting/functions/SetPlayerAdmin) | +| [GetPlayers](../scripting/functions/GetPlayers) | +| [OnScriptLoadPlayer](../scripting/callbacks/OnScriptLoadPlayer) | +| [OnScriptUnloadPlayer](../scripting/callbacks/OnScriptUnloadPlayer) | + +## Objeto + +| Nome | +| --------------------------------------------------------------------------------------------- | +| [SetObjectNoCameraCollision](../scripting/functions/SetObjectNoCameraCollision) | +| [SetPlayerObjectNoCameraCollision](../scripting/functions/SetPlayerObjectNoCameraCollision) | +| [AttachPlayerObjectToObject](../scripting/functions/AttachPlayerObjectToObject) | +| [BeginObjectEditing](../scripting/functions/BeginObjectEditing) | +| [BeginObjectSelecting](../scripting/functions/BeginObjectSelecting) | +| [BeginPlayerObjectEditing](../scripting/functions/BeginPlayerObjectEditing) | +| [EndObjectEditing](../scripting/functions/EndObjectEditing) | +| [GetObjectAttachedData](../scripting/functions/GetObjectAttachedData) | +| [GetObjectAttachedOffset](../scripting/functions/GetObjectAttachedOffset) | +| [GetObjectDrawDistance](../scripting/functions/GetObjectDrawDistance) | +| [GetObjectMaterial](../scripting/functions/GetObjectMaterial) | +| [GetObjectMaterialText](../scripting/functions/GetObjectMaterialText) | +| [GetObjectMoveSpeed](../scripting/functions/GetObjectMoveSpeed) | +| [GetObjectMovingTargetPos](../scripting/functions/GetObjectMovingTargetPos) | +| [GetObjectMovingTargetRot](../scripting/functions/GetObjectMovingTargetRot) | +| [GetObjectSyncRotation](../scripting/functions/GetObjectSyncRotation) | +| [GetObjectType](../scripting/functions/GetObjectType) | +| [GetPlayerCameraTargetPlayerObject](../scripting/functions/GetPlayerCameraTargetPlayerObject) | +| [GetPlayerObjectAttachedData](../scripting/functions/GetPlayerObjectAttachedData) | +| [GetPlayerObjectAttachedOffset](../scripting/functions/GetPlayerObjectAttachedOffset) | +| [GetPlayerObjectDrawDistance](../scripting/functions/GetPlayerObjectDrawDistance) | +| [GetPlayerObjectMaterial](../scripting/functions/GetPlayerObjectMaterial) | +| [GetPlayerObjectMaterialText](../scripting/functions/GetPlayerObjectMaterialText) | +| [GetPlayerObjectMoveSpeed](../scripting/functions/GetPlayerObjectMoveSpeed) | +| [GetPlayerObjectMovingTargetPos](../scripting/functions/GetPlayerObjectMovingTargetPos) | +| [GetPlayerObjectMovingTargetRot](../scripting/functions/GetPlayerObjectMovingTargetRot) | +| [GetPlayerObjectSyncRotation](../scripting/functions/GetPlayerObjectSyncRotation) | +| [GetPlayerSurfingPlayerObjectID](../scripting/functions/GetPlayerSurfingPlayerObjectID) | +| [HasObjectCameraCollision](../scripting/functions/HasObjectCameraCollision) | +| [HasPlayerObjectCameraCollision](../scripting/functions/HasPlayerObjectCameraCollision) | +| [IsObjectHiddenForPlayer](../scripting/functions/IsObjectHiddenForPlayer) | +| [IsObjectMaterialSlotUsed](../scripting/functions/IsObjectMaterialSlotUsed) | +| [IsPlayerObjectMaterialSlotUsed](../scripting/functions/IsPlayerObjectMaterialSlotUsed) | +| [SetObjectMoveSpeed](../scripting/functions/SetObjectMoveSpeed) | +| [SetObjectsDefaultCameraCollision](../scripting/functions/SetObjectsDefaultCameraCollision) | +| [SetPlayerObjectMoveSpeed](../scripting/functions/SetPlayerObjectMoveSpeed) | +| [HideObjectForPlayer](../scripting/functions/HideObjectForPlayer) | +| [ShowObjectForPlayer](../scripting/functions/ShowObjectForPlayer) | + +## Pickup + +| Nome | +| --------------------------------------------------------------------------------- | +| [CreatePlayerPickup](../scripting/functions/CreatePlayerPickup) | +| [DestroyPlayerPickup](../scripting/functions/DestroyPlayerPickup) | +| [GetPickupModel](../scripting/functions/GetPickupModel) | +| [GetPickupPos](../scripting/functions/GetPickupPos) | +| [GetPickupType](../scripting/functions/GetPickupType) | +| [GetPickupVirtualWorld](../scripting/functions/GetPickupVirtualWorld) | +| [GetPlayerPickupModel](../scripting/functions/GetPlayerPickupModel) | +| [GetPlayerPickupPos](../scripting/functions/GetPlayerPickupPos) | +| [GetPlayerPickupType](../scripting/functions/GetPlayerPickupType) | +| [GetPlayerPickupVirtualWorld](../scripting/functions/GetPlayerPickupVirtualWorld) | +| [IsPickupHiddenForPlayer](../scripting/functions/IsPickupHiddenForPlayer) | +| [IsPickupStreamedIn](../scripting/functions/IsPickupStreamedIn) | +| [IsPlayerPickupStreamedIn](../scripting/functions/IsPlayerPickupStreamedIn) | +| [IsValidPickup](../scripting/functions/IsValidPickup) | +| [IsValidPlayerPickup](../scripting/functions/IsValidPlayerPickup) | +| [SetPickupForPlayer](../scripting/functions/SetPickupForPlayer) | +| [SetPickupModel](../scripting/functions/SetPickupModel) | +| [SetPickupPos](../scripting/functions/SetPickupPos) | +| [SetPickupType](../scripting/functions/SetPickupType) | +| [SetPickupVirtualWorld](../scripting/functions/SetPickupVirtualWorld) | +| [SetPlayerPickupModel](../scripting/functions/SetPlayerPickupModel) | +| [SetPlayerPickupPos](../scripting/functions/SetPlayerPickupPos) | +| [SetPlayerPickupType](../scripting/functions/SetPlayerPickupType) | +| [SetPlayerPickupVirtualWorld](../scripting/functions/SetPlayerPickupVirtualWorld) | +| [HidePickupForPlayer](../scripting/functions/HidePickupForPlayer) | +| [ShowPickupForPlayer](../scripting/functions/ShowPickupForPlayer) | +| [OnPickupStreamIn](../scripting/callbacks/OnPickupStreamIn) | +| [OnPickupStreamOut](../scripting/callbacks/OnPickupStreamOut) | +| [OnPlayerPickUpPlayerPickup](../scripting/callbacks/OnPlayerPickUpPlayerPickup) | +| [OnPlayerPickupStreamIn](../scripting/callbacks/OnPlayerPickupStreamIn) | +| [OnPlayerPickupStreamOut](../scripting/callbacks/OnPlayerPickupStreamOut) | + +## Veículo + +| Nome | +| ----------------------------------------------------------------------------------- | +| [ChangeVehicleColours](../scripting/functions/ChangeVehicleColours) | +| [GetPlayerLastSyncedVehicleID](../scripting/functions/GetPlayerLastSyncedVehicleID) | +| [GetRandomVehicleColourPair](../scripting/functions/GetRandomVehicleColourPair) | +| [GetVehicleCab](../scripting/functions/GetVehicleCab) | +| [GetVehicleTower](../scripting/functions/GetVehicleTower) | +| [GetVehicleColours](../scripting/functions/GetVehicleColours) | +| [GetVehicleHydraReactorAngle](../scripting/functions/GetVehicleHydraReactorAngle) | +| [GetVehicleInterior](../scripting/functions/GetVehicleInterior) | +| [GetVehicleLandingGearState](../scripting/functions/GetVehicleLandingGearState) | +| [GetVehicleDriver](../scripting/functions/GetVehicleDriver) | +| [GetVehicleLastDriver](../scripting/functions/GetVehicleLastDriver) | +| [GetVehicleMatrix](../scripting/functions/GetVehicleMatrix) | +| [GetVehicleModelCount](../scripting/functions/GetVehicleModelCount) | +| [GetVehicleModelsUsed](../scripting/functions/GetVehicleModelsUsed) | +| [GetVehicleNumberPlate](../scripting/functions/GetVehicleNumberPlate) | +| [GetVehicleOccupiedTick](../scripting/functions/GetVehicleOccupiedTick) | +| [GetVehiclePaintjob](../scripting/functions/GetVehiclePaintjob) | +| [GetVehicleRespawnDelay](../scripting/functions/GetVehicleRespawnDelay) | +| [GetVehicleRespawnTick](../scripting/functions/GetVehicleRespawnTick) | +| [GetVehicleSirenState](../scripting/functions/GetVehicleSirenState) | +| [GetVehicleSpawnInfo](../scripting/functions/GetVehicleSpawnInfo) | +| [GetVehicleTrainSpeed](../scripting/functions/GetVehicleTrainSpeed) | +| [SetVehicleBeenOccupied](../scripting/functions/SetVehicleBeenOccupied) | +| [HasVehicleBeenOccupied](../scripting/functions/HasVehicleBeenOccupied) | +| [IsVehicleOccupied](../scripting/functions/IsVehicleOccupied) | +| [HideVehicle](../scripting/functions/HideVehicle) | +| [ShowVehicle](../scripting/functions/ShowVehicle) | +| [IsVehicleHidden](../scripting/functions/IsVehicleHidden) | +| [SetVehicleDead](../scripting/functions/SetVehicleDead) | +| [IsVehicleDead](../scripting/functions/IsVehicleDead) | +| [IsVehicleSirenEnabled](../scripting/functions/IsVehicleSirenEnabled) | +| [SetVehicleOccupiedTick](../scripting/functions/SetVehicleOccupiedTick) | +| [SetVehicleParamsSirenState](../scripting/functions/SetVehicleParamsSirenState) | +| [SetVehicleRespawnDelay](../scripting/functions/SetVehicleRespawnDelay) | +| [SetVehicleRespawnTick](../scripting/functions/SetVehicleRespawnTick) | +| [SetVehicleSpawnInfo](../scripting/functions/SetVehicleSpawnInfo) | +| [ToggleVehicleSirenEnabled](../scripting/functions/ToggleVehicleSirenEnabled) | +| [VehicleColourIndexToColour](../scripting/functions/VehicleColourIndexToColour) | +| [GetVehicleSeats](../scripting/functions/GetVehicleSeats) | +| [VehicleCanHaveComponent](../scripting/functions/VehicleCanHaveComponent) | +| [GetVehicles](../scripting/functions/GetVehicles) | + +## TextDraw + +| Nome | +| ------------------------------------------------------------------------------------------------------- | +| [TextDrawColour](../scripting/functions/TextDrawColour) | +| [TextDrawBoxColour](../scripting/functions/TextDrawBoxColour) | +| [TextDrawBackgroundColour](../scripting/functions/TextDrawBackgroundColour) | +| [TextDrawGetAlignment](../scripting/functions/TextDrawGetAlignment) | +| [TextDrawGetBackgroundColor](../scripting/functions/TextDrawGetBackgroundColor) | +| [TextDrawGetBackgroundColour](../scripting/functions/TextDrawGetBackgroundColour) | +| [TextDrawGetBoxColor](../scripting/functions/TextDrawGetBoxColor) | +| [TextDrawGetBoxColour](../scripting/functions/TextDrawGetBoxColour) | +| [TextDrawGetColor](../scripting/functions/TextDrawGetColor) | +| [TextDrawGetColour](../scripting/functions/TextDrawGetColour) | +| [TextDrawGetFont](../scripting/functions/TextDrawGetFont) | +| [TextDrawGetLetterSize](../scripting/functions/TextDrawGetLetterSize) | +| [TextDrawGetOutline](../scripting/functions/TextDrawGetOutline) | +| [TextDrawGetPos](../scripting/functions/TextDrawGetPos) | +| [TextDrawGetPreviewModel](../scripting/functions/TextDrawGetPreviewModel) | +| [TextDrawGetPreviewRot](../scripting/functions/TextDrawGetPreviewRot) | +| [TextDrawGetPreviewVehicleColours](../scripting/functions/TextDrawGetPreviewVehicleColours) | +| [TextDrawGetShadow](../scripting/functions/TextDrawGetShadow) | +| [TextDrawGetString](../scripting/functions/TextDrawGetString) | +| [TextDrawGetTextSize](../scripting/functions/TextDrawGetTextSize) | +| [TextDrawIsBox](../scripting/functions/TextDrawIsBox) | +| [TextDrawIsProportional](../scripting/functions/TextDrawIsProportional) | +| [TextDrawIsSelectable](../scripting/functions/TextDrawIsSelectable) | +| [TextDrawSetPos](../scripting/functions/TextDrawSetPos) | +| [TextDrawSetPreviewVehicleColours](../scripting/functions/TextDrawSetPreviewVehicleColours) | +| [TextDrawSetStringForPlayer](../scripting/functions/TextDrawSetStringForPlayer) | +| [IsValidTextDraw](../scripting/functions/IsValidTextDraw) | +| [IsTextDrawVisibleForPlayer](../scripting/functions/IsTextDrawVisibleForPlayer) | +| [PlayerTextDrawBackgroundColour](../scripting/functions/PlayerTextDrawBackgroundColour) | +| [PlayerTextDrawBoxColour](../scripting/functions/PlayerTextDrawBoxColour) | +| [PlayerTextDrawColour](../scripting/functions/PlayerTextDrawColour) | +| [PlayerTextDrawGetAlignment](../scripting/functions/PlayerTextDrawGetAlignment) | +| [PlayerTextDrawGetBackgroundCol](../scripting/functions/PlayerTextDrawGetBackgroundCol) | +| [PlayerTextDrawGetBackgroundColour](../scripting/functions/PlayerTextDrawGetBackgroundColour) | +| [PlayerTextDrawGetBoxColor](../scripting/functions/PlayerTextDrawGetBoxColor) | +| [PlayerTextDrawGetBoxColour](../scripting/functions/PlayerTextDrawGetBoxColour) | +| [PlayerTextDrawGetColor](../scripting/functions/PlayerTextDrawGetColor) | +| [PlayerTextDrawGetColour](../scripting/functions/PlayerTextDrawGetColour) | +| [PlayerTextDrawGetFont](../scripting/functions/PlayerTextDrawGetFont) | +| [PlayerTextDrawGetLetterSize](../scripting/functions/PlayerTextDrawGetLetterSize) | +| [PlayerTextDrawGetOutline](../scripting/functions/PlayerTextDrawGetOutline) | +| [PlayerTextDrawGetPos](../scripting/functions/PlayerTextDrawGetPos) | +| [PlayerTextDrawGetPreviewModel](../scripting/functions/PlayerTextDrawGetPreviewModel) | +| [PlayerTextDrawGetPreviewRot](../scripting/functions/PlayerTextDrawGetPreviewRot) | +| [PlayerTextDrawGetPreviewVehicleColours](../scripting/functions/PlayerTextDrawGetPreviewVehicleColours) | +| [PlayerTextDrawGetShadow](../scripting/functions/PlayerTextDrawGetShadow) | +| [PlayerTextDrawGetString](../scripting/functions/PlayerTextDrawGetString) | +| [PlayerTextDrawGetTextSize](../scripting/functions/PlayerTextDrawGetTextSize) | +| [PlayerTextDrawIsBox](../scripting/functions/PlayerTextDrawIsBox) | +| [PlayerTextDrawIsProportional](../scripting/functions/PlayerTextDrawIsProportional) | +| [PlayerTextDrawIsSelectable](../scripting/functions/PlayerTextDrawIsSelectable) | +| [PlayerTextDrawSetPos](../scripting/functions/PlayerTextDrawSetPos) | +| [PlayerTextDrawSetPreviewVehicleColours](../scripting/functions/PlayerTextDrawSetPreviewVehicleColours) | +| [IsValidPlayerTextDraw](../scripting/functions/IsValidPlayerTextDraw) | +| [IsPlayerTextDrawVisible](../scripting/functions/IsPlayerTextDrawVisible) | + +## GameText + +| Nome | +| --------------------------------------------------------------------- | +| [GetGameText](../scripting/functions/GetGameText) | +| [HasGameText](../scripting/functions/HasGameText) | +| [HideGameTextForAll](../scripting/functions/HideGameTextForAll) | +| [HideGameTextForPlayer](../scripting/functions/HideGameTextForPlayer) | + +## GangZone + +| Nome | +| ----------------------------------------------------------------------------------------- | +| [IsValidGangZone](../scripting/functions/IsValidGangZone) | +| [IsPlayerInGangZone](../scripting/functions/IsPlayerInGangZone) | +| [IsGangZoneVisibleForPlayer](../scripting/functions/IsGangZoneVisibleForPlayer) | +| [GangZoneGetColourForPlayer](../scripting/functions/GangZoneGetColourForPlayer) | +| [GangZoneGetFlashColourForPlayer](../scripting/functions/GangZoneGetFlashColourForPlayer) | +| [IsGangZoneFlashingForPlayer](../scripting/functions/IsGangZoneFlashingForPlayer) | +| [GangZoneGetPos](../scripting/functions/GangZoneGetPos) | +| [UseGangZoneCheck](../scripting/functions/UseGangZoneCheck) | +| [CreatePlayerGangZone](../scripting/functions/CreatePlayerGangZone) | +| [PlayerGangZoneDestroy](../scripting/functions/PlayerGangZoneDestroy) | +| [PlayerGangZoneShow](../scripting/functions/PlayerGangZoneShow) | +| [PlayerGangZoneHide](../scripting/functions/PlayerGangZoneHide) | +| [PlayerGangZoneFlash](../scripting/functions/PlayerGangZoneFlash) | +| [PlayerGangZoneStopFlash](../scripting/functions/PlayerGangZoneStopFlash) | +| [PlayerGangZoneGetColour](../scripting/functions/PlayerGangZoneGetColour) | +| [PlayerGangZoneGetFlashColour](../scripting/functions/PlayerGangZoneGetFlashColour) | +| [PlayerGangZoneGetPos](../scripting/functions/PlayerGangZoneGetPos) | +| [IsValidPlayerGangZone](../scripting/functions/IsValidPlayerGangZone) | +| [IsPlayerInPlayerGangZone](../scripting/functions/IsPlayerInPlayerGangZone) | +| [IsPlayerGangZoneVisible](../scripting/functions/IsPlayerGangZoneVisible) | +| [IsPlayerGangZoneFlashing](../scripting/functions/IsPlayerGangZoneFlashing) | +| [UsePlayerGangZoneCheck](../scripting/functions/UsePlayerGangZoneCheck) | +| [OnPlayerEnterGangZone](../scripting/callbacks/OnPlayerEnterGangZone) | +| [OnPlayerLeaveGangZone](../scripting/callbacks/OnPlayerLeaveGangZone) | +| [OnPlayerEnterPlayerGangZone](../scripting/callbacks/OnPlayerEnterPlayerGangZone) | +| [OnPlayerLeavePlayerGangZone](../scripting/callbacks/OnPlayerLeavePlayerGangZone) | +| [OnPlayerClickGangZone](../scripting/callbacks/OnPlayerClickGangZone) | +| [OnPlayerClickPlayerGangZone](../scripting/callbacks/OnPlayerClickPlayerGangZone) | + +## Checkpoint + +| Nome | +| ----------------------------------------------------------------------------------- | +| [IsPlayerCheckpointActive](../scripting/functions/IsPlayerCheckpointActive) | +| [GetPlayerCheckpoint](../scripting/functions/GetPlayerCheckpoint) | +| [IsPlayerRaceCheckpointActive](../scripting/functions/IsPlayerRaceCheckpointActive) | +| [GetPlayerRaceCheckpoint](../scripting/functions/GetPlayerRaceCheckpoint) | + +## Ator + +| Nome | +| ------------------------------------------------------------- | +| [SetActorSkin](../scripting/functions/SetActorSkin) | +| [GetActorSkin](../scripting/functions/GetActorSkin) | +| [GetActorAnimation](../scripting/functions/GetActorAnimation) | +| [GetActorSpawnInfo](../scripting/functions/GetActorSpawnInfo) | +| [GetActors](../scripting/functions/GetActors) | + +## TextLabel 3D + +| Nome | +| ------------------------------------------------------------------------------------------- | +| [Is3DTextLabelStreamedIn](../scripting/functions/Is3DTextLabelStreamedIn) | +| [Get3DTextLabelText](../scripting/functions/Get3DTextLabelText) | +| [Get3DTextLabelColor](../scripting/functions/Get3DTextLabelColor) | +| [Get3DTextLabelColour](../scripting/functions/Get3DTextLabelColour) | +| [Get3DTextLabelPos](../scripting/functions/Get3DTextLabelPos) | +| [Set3DTextLabelDrawDistance](../scripting/functions/Set3DTextLabelDrawDistance) | +| [Get3DTextLabelDrawDistance](../scripting/functions/Get3DTextLabelDrawDistance) | +| [Get3DTextLabelLOS](../scripting/functions/Get3DTextLabelLOS) | +| [Set3DTextLabelLOS](../scripting/functions/Set3DTextLabelLOS) | +| [Get3DTextLabelVirtualWorld](../scripting/functions/Get3DTextLabelVirtualWorld) | +| [Set3DTextLabelVirtualWorld](../scripting/functions/Set3DTextLabelVirtualWorld) | +| [Get3DTextLabelAttachedData](../scripting/functions/Get3DTextLabelAttachedData) | +| [IsValid3DTextLabel](../scripting/functions/IsValid3DTextLabel) | +| [IsValidPlayer3DTextLabel](../scripting/functions/IsValidPlayer3DTextLabel) | +| [GetPlayer3DTextLabelText](../scripting/functions/GetPlayer3DTextLabelText) | +| [GetPlayer3DTextLabelColor](../scripting/functions/GetPlayer3DTextLabelColor) | +| [GetPlayer3DTextLabelColour](../scripting/functions/GetPlayer3DTextLabelColour) | +| [GetPlayer3DTextLabelPos](../scripting/functions/GetPlayer3DTextLabelPos) | +| [SetPlayer3DTextLabelDrawDistance](../scripting/functions/SetPlayer3DTextLabelDrawDistance) | +| [GetPlayer3DTextLabelDrawDistance](../scripting/functions/GetPlayer3DTextLabelDrawDistance) | +| [GetPlayer3DTextLabelLOS](../scripting/functions/GetPlayer3DTextLabelLOS) | +| [GetPlayer3DTextLabelVirtualWorld](../scripting/functions/GetPlayer3DTextLabelVirtualWorld) | +| [SetPlayer3DTextLabelVirtualWorld](../scripting/functions/SetPlayer3DTextLabelVirtualWorld) | +| [GetPlayer3DTextLabelAttached](../scripting/functions/GetPlayer3DTextLabelAttached) | +| [GetPlayer3DTextLabelAttachedData](../scripting/functions/GetPlayer3DTextLabelAttachedData) | + +## Classe + +| Nome | +| ----------------------------------------------------------------- | +| [GetAvailableClasses](../scripting/functions/GetAvailableClasses) | +| [EditPlayerClass](../scripting/functions/EditPlayerClass) | +| [GetPlayerClass](../scripting/functions/GetPlayerClass) | + +## Menu + +| Nome | +| ----------------------------------------------------------------- | +| [GetMenuItem](../scripting/functions/GetMenuItem) | +| [GetMenuItems](../scripting/functions/GetMenuItems) | +| [GetMenuColumns](../scripting/functions/GetMenuColumns) | +| [GetMenuColumnHeader](../scripting/functions/GetMenuColumnHeader) | +| [GetMenuPos](../scripting/functions/GetMenuPos) | +| [GetMenuColumnWidth](../scripting/functions/GetMenuColumnWidth) | +| [IsMenuDisabled](../scripting/functions/IsMenuDisabled) | +| [IsMenuRowDisabled](../scripting/functions/IsMenuRowDisabled) | + +## Banco de Dados + +| Nome | +| ------------------------------------------------------------------------------------- | +| [DB_ExecuteQuery](../scripting/functions/DB_ExecuteQuery) | +| [DB_FreeResultSet](../scripting/functions/DB_FreeResultSet) | +| [DB_GetDatabaseConnectionCount](../scripting/functions/DB_GetDatabaseConnectionCount) | +| [DB_GetDatabaseResultSetCount](../scripting/functions/DB_GetDatabaseResultSetCount) | +| [DB_GetFieldCount](../scripting/functions/DB_GetFieldCount) | +| [DB_GetFieldFloat](../scripting/functions/DB_GetFieldFloat) | +| [DB_GetFieldFloatByName](../scripting/functions/DB_GetFieldFloatByName) | +| [DB_GetFieldInt](../scripting/functions/DB_GetFieldInt) | +| [DB_GetFieldIntByName](../scripting/functions/DB_GetFieldIntByName) | +| [DB_GetFieldName](../scripting/functions/DB_GetFieldName) | +| [DB_GetFieldString](../scripting/functions/DB_GetFieldString) | +| [DB_GetFieldStringByName](../scripting/functions/DB_GetFieldStringByName) | +| [DB_GetLegacyDBResult](../scripting/functions/DB_GetLegacyDBResult) | +| [DB_GetMemHandle](../scripting/functions/DB_GetMemHandle) | +| [DB_GetRowCount](../scripting/functions/DB_GetRowCount) | +| [DB_SelectNextRow](../scripting/functions/DB_SelectNextRow) | + +## Núcleo + +| Nome | +| ------------------------------------------------------------------------------- | +| [SetModeRestartTime](../scripting/functions/SetModeRestartTime) | +| [GetModeRestartTime](../scripting/functions/GetModeRestartTime) | +| [IsAdminTeleportAllowed](../scripting/functions/IsAdminTeleportAllowed) | +| [AreAllAnimationsEnabled](../scripting/functions/AreAllAnimationsEnabled) | +| [EnableAllAnimations](../scripting/functions/EnableAllAnimations) | +| [IsValidAnimationLibrary](../scripting/functions/IsValidAnimationLibrary) | +| [ArePlayerWeaponsAllowed](../scripting/functions/ArePlayerWeaponsAllowed) | +| [AreInteriorWeaponsAllowed](../scripting/functions/AreInteriorWeaponsAllowed) | +| [GetWeaponSlot](../scripting/functions/GetWeaponSlot) | +| [GetWeather](../scripting/functions/GetWeather) | +| [GetWorldTime](../scripting/functions/GetWorldTime) | +| [ToggleChatTextReplacement](../scripting/functions/ToggleChatTextReplacement) | +| [ChatTextReplacementToggled](../scripting/functions/ChatTextReplacementToggled) | +| [AllowNickNameCharacter](../scripting/functions/AllowNickNameCharacter) | +| [IsNickNameCharacterAllowed](../scripting/functions/IsNickNameCharacterAllowed) | +| [IsValidNickName](../scripting/functions/IsValidNickName) | +| [ClearBanList](../scripting/functions/ClearBanList) | +| [IsBanned](../scripting/functions/IsBanned) | + +## Regra do Servidor + +| Nome | +| --------------------------------------------------------------- | +| [AddServerRule](../scripting/functions/AddServerRule) | +| [RemoveServerRule](../scripting/functions/RemoveServerRule) | +| [IsValidServerRule](../scripting/functions/IsValidServerRule) | +| [SetServerRule](../scripting/functions/SetServerRule) | +| [SetServerRuleFlags](../scripting/functions/SetServerRuleFlags) | +| [GetServerRuleFlags](../scripting/functions/GetServerRuleFlags) | + +## Timer + +| Nome | +| --------------------------------------------------------------- | +| [IsValidTimer](../scripting/functions/IsValidTimer) | +| [IsRepeatingTimer](../scripting/functions/IsRepeatingTimer) | +| [GetTimerInterval](../scripting/functions/GetTimerInterval) | +| [GetTimerRemaining](../scripting/functions/GetTimerRemaining) | +| [CountRunningTimers](../scripting/functions/CountRunningTimers) | +| [GetRunningTimers](../scripting/functions/GetRunningTimers) | + +## Modelo Personalizado + +| Nome | +| --------------------------------------------------------------- | +| [IsValidCustomModel](../scripting/functions/IsValidCustomModel) | +| [GetCustomModelPath](../scripting/functions/GetCustomModelPath) | + +## String + +| Nome | +| ------------------------------------------- | +| [strcopy](../scripting/functions/strcopy) | +| [strequal](../scripting/functions/strequal) | + +## Float + +| Nome | +| ------------------------------------------- | +| [strfloat](../scripting/functions/strfloat) | + +## Arquivo + +| Nome | +| ----------------------------------------------- | +| [ftell](../scripting/functions/ftell) | +| [fstat](../scripting/functions/fstat) | +| [frename](../scripting/functions/frename) | +| [filecrc](../scripting/functions/filecrc) | +| [fflush](../scripting/functions/fflush) | +| [fcreatedir](../scripting/functions/fcreatedir) | +| [fcopy](../scripting/functions/fcopy) | +| [fattrib](../scripting/functions/fattrib) | +| [diskfree](../scripting/functions/diskfree) | diff --git a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/server.cfg.md b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/server.cfg.md new file mode 100644 index 00000000000..19c7df68b2f --- /dev/null +++ b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/server/server.cfg.md @@ -0,0 +1,126 @@ +--- +title: "server.cfg" +sidebar_label: "server.cfg" +description: Arquivo de configuração do servidor. +--- + +## Descrição + +- `server.cfg` é um arquivo de configuração do servidor que permite alterar todos os tipos de configurações do seu servidor sa-mp. +- Este arquivo é necessário para cada servidor e deve estar localizado no diretório do servidor ao lado do aplicativo do servidor (samp-server.exe). + +## Console + +| Configuração | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ------------- | ------ | -------------------------- | --------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| echo | string | Executing Server Config... | Sim | Não | O que o samp-server.exe imprime no console do servidor ao executar o server.cfg. Não há necessidade de alterar isso, pois você será o único que verá o console. | +| rcon_password | string | changeme | Não | Não | A senha usada para administrar o servidor e usar o console remoto (rcon). Você deve certificar-se de alterar isso para algo difícil de decifrar para que outros não possam assumir o controle do seu servidor. Seu servidor NÃO iniciará se changeme for a senha RCON! | +| rcon | bool | 1 | Não | Não | Define se o recurso de [Console Remoto](RemoteConsole) deve ser usado. Defina como 1 para ativar ou 0 para desativar. | + +## Scripts + +| Configuração | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ------------------- | ------ | --------------------- | --------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| gamemode(n) (N) (t) | string | gamemode0 grandlarc 1 | Não | Não | O arquivo .amx na pasta gamemodes que o servidor deve usar para executar como gamemode. (n) é o número do gamemode, (N) é o nome do gamemode sem a extensão .amx, e (t) é a quantidade de vezes que o gamemode deve ser jogado antes de mudar para o próximo gamemode. | +| filterscripts (N) | string | | Sim | Não | O arquivo .amx na pasta filterscripts que o servidor deve usar para executar como filterscript. (N) é o nome do filterscript sem a extensão .amx. Filterscripts são scripts que rodam em segundo plano do seu gamemode. Eles servem para adicionar extras ao servidor sem editar o gamemode. É muito útil se você quiser carregar uma propriedade específica para mais de um gamemode. Se você tem múltiplos filterscripts que deseja carregar, coloque todos em sequência separados por "espaço", ex: filterscripts script1 script2. | +| plugins (N) | string | | Sim | Não | O arquivo .dll ou .so na pasta plugins que o servidor deve usar para executar como plugin. No Windows, (N) é o nome do plugin sem a extensão .dll. No entanto, no Linux a extensão .so é necessária! Plugins são scripts projetados para aprimorar gamemodes e filterscripts. Se você tem múltiplos plugins que deseja carregar, coloque todos em sequência separados por "espaço", ex: plugins plugin1 plugin2. | + +## Navegador de servidores + +| Configuração | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ------------ | -------- | ------------ | --------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| announce | bool | 1 | Não | Não | Define se o servidor deve ser anunciado na lista principal do SA-MP. Defina como 1 para ativar ou 0 para desativar. | +| query | bool | 1 | Não | Não | Define se as informações do servidor devem ser exibidas no navegador de servidores. Defina como 1 para ativar ou 0 para desativar. Os jogadores ainda podem entrar em um servidor que desabilitou a consulta, mas o navegador de servidores não exibirá nenhuma informação. | +| hostname | string | SA-MP Server | Não | Não | O nome que será mostrado no navegador de servidores e quando o jogador se conectar ao servidor. | +| language | string | | Não | Não | O idioma que aparece no navegador de servidores. Os jogadores podem usar isso para filtrar servidores por idioma no navegador de servidores.

**NOTA:** Esta variável do servidor foi adicionada na versão 0.3.7 e não terá efeito em versões anteriores. | +| mapname | string | San Andreas | Não | Sim | O nome do mapa que aparece no navegador de servidores. Pode ser qualquer coisa, por exemplo, Meu Mapa de Manobras. | +| gamemodetext | string | Unknown | Não | Não | O modo que será mostrado no navegador de servidores. Usar [SetGameModeText](../scripting/functions/SetGameModeText) tem o mesmo efeito e substitui o valor usado no server.cfg. Se você tem múltiplos gamemodes que requerem textos diferentes, use essa função. | +| weather | string\* | 10 | Não | Sim | O clima global que o servidor usa e que será mostrado no navegador de servidores. Usar esta configuração no arquivo server.cfg fará com que o aplicativo do servidor trave na inicialização. Use [SetWeather](../scripting/functions/SetWeather) em vez disso para alterar esta configuração. | +| worldtime | string\* | 12:00 | Não | Sim | O horário global que o servidor usa e que será mostrado no navegador de servidores. Usar esta configuração no arquivo server.cfg não tem efeito. Use [SetWorldTime](../scripting/functions/SetWorldTime) em vez disso para alterar esta configuração. | +| gravity | string\* | 0.008 | Não | Não | A gravidade global que o servidor usa. Usar esta configuração no arquivo server.cfg fará com que o aplicativo do servidor trave na inicialização. Use [SetGravity](../scripting/functions/SetGravity) em vez disso para alterar esta configuração. | +| weburl | string | www.open.mp | Não | Sim | O site que as pessoas podem visitar para obter mais informações sobre o servidor. | +| version | string | | Sim | Sim | A versão do SA-MP que o servidor usa e que será mostrada no navegador de servidores. Usar esta configuração no arquivo server.cfg não tem efeito. | +| maxplayers | int | 50 | Sim | Não | A quantidade máxima de jogadores que seu servidor pode conter. Ao alterar este número, você pode modificar quantos jogadores podem entrar no servidor. O máximo é 1000 e o mínimo é 1. | +| password | string | | Não | Não | A senha usada para bloquear o servidor. Ao usar isso, apenas jogadores que conhecem esta senha poderão entrar no servidor. | + +> [*] Algumas configurações são de um tipo diferente do que você pode pensar. + +## Rede + +| Configuração | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ----------------- | ------ | -------------------------------- | --------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| sleep | int | 5 | Não | Não | O tempo em milissegundos que a thread principal do sa-mp e da rede raknet "dormirá" ociosamente durante cada ciclo de sincronização. Valores mais altos diminuem o processamento do servidor, mas reduzem a qualidade da sincronização. Valores mais baixos aumentam o processamento do servidor, mas melhoram a qualidade da sincronização. Não é aconselhável alterar este valor a menos que sua contagem de jogadores seja muito alta e você tenha problemas de estabilidade de fps do servidor. | +| lanmode | bool | 0 | Não | Não | Variável obsoleta, não tem efeito. | +| bind | string | | Sim | Não | O endereço IP que o servidor deve usar. O servidor será forçado a usar este endereço IP em vez de escolher automaticamente um endereço IP livre. Este endereço IP deve corresponder a um atribuído a uma placa de rede no servidor. Isso é útil para executar múltiplos servidores na mesma porta na mesma máquina. | +| port | int | 8192 (7777 também é comum) | Sim | Não | A porta que o servidor deve usar. Você precisará fazer [Redirecionamento de Porta](http://www.portforward.com/) para que os jogadores possam entrar no seu servidor de fora da sua LAN. | +| conncookies | int\* | 1 | Não | Não | Ativa/desativa o sistema de cookies de conexão da versão 0.3.7. Defina como 1 para ativar ou 0 para desativar.

**NOTA:** Esta variável do servidor foi adicionada na versão 0.3.7 R2 e não terá efeito em versões anteriores. | +| cookielogging | int\* | 0 | Não | Não | Ativa/desativa o registro de cookies de conexão solicitados por jogadores recém-conectados. Defina como 1 para ativar ou 0 para desativar.

**NOTA:** Esta variável do servidor foi adicionada na versão 0.3.7 R2 e não terá efeito em versões anteriores. | +| connseedtime | int | 300000 | Não | Não | O tempo em milissegundos que o valor de seed do cookie de conexão é atualizado.

**NOTA:** Esta variável do servidor foi adicionada na versão 0.3.7 e não terá efeito em versões anteriores. | +| minconnectiontime | int | 0 | Não | Não | O tempo em milissegundos que o servidor aguardará antes de aceitar outra conexão de entrada. Não é recomendado usar esta variável a menos que seu servidor esteja sob um ataque de flood de conexão. | +| messageslimit | int | 500 | Não | Não | O número máximo de mensagens que um usuário pode enviar por segundo. | +| messageholelimit | int | 3000 | Não | Não | Uma configuração de nível de rede para lidar com ataques DoS. | +| ackslimit | int | 3000 | Não | Não | | +| playertimeout | int | 10000 | Não | Não | O tempo em milissegundos após o qual um jogador sofrerá timeout quando não enviar dados ao servidor. | +| mtu | int | 576 | Sim | Não | [Veja aqui](https://en.wikipedia.org/wiki/Maximum_transmission_unit).

**NOTA:** Esta variável do servidor foi adicionada na versão 0.3.8 e não terá efeito em versões anteriores. | + +> [*] Algumas configurações são de um tipo diferente do que você pode pensar. + +## Registro de Logs + +| Configuração | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| -------------- | ------ | ------------ | --------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| output | bool | 0 | Não | Não | Define se as mensagens de log (por exemplo, print/printf de scripts ou logprintf de plugins) devem ser duplicadas no console do servidor. Defina como 1 para ativar ou 0 para desativar. Esta opção tem efeito apenas em servidores Linux. | +| timestamp | bool | 1 | Não | Não | Define se um timestamp deve ser impresso com cada mensagem do console. Defina como 1 para ativar ou 0 para desativar. | +| logtimeformat | string | [%H:%M:%S] | Sim | Não | O formato de timestamp que deve ser usado. O formato é baseado no formato [strftime](http://cplusplus.com/reference/clibrary/ctime/strftime/) de C/C++. Aqui estão alguns exemplos:

**[%H:%M:%S]** Exibe apenas o horário e é o formato padrão para todas as versões anteriores do servidor SA-MP.

**[%d/%m/%Y %H:%M:%S]** Exibiria a data no formato dd/mm/aaaa seguido pelo horário no formato hora:minuto:segundo. | +| logqueries | bool | 0 | Não | Não | Define se todas as consultas enviadas ao servidor pelos jogadores devem ser registradas. Defina como 1 para ativar ou 0 para desativar. É consideravelmente útil durante um ataque DDoS. | +| chatlogging | int\* | 1 | Não | Não | Define se o chat dos jogadores deve ser mostrado no console do servidor. Útil para evitar que o log fique sobrecarregado, ou se você tiver outra solução de registro de chat por script. Defina como 1 para ativar ou 0 para desativar. | +| db_logging | int\* | 0 | Não | Não | Registra erros de funções db\_\* do sqlite no console do servidor.

**NOTA:** Esta variável do servidor foi adicionada na versão 0.3.7 R2 e não terá efeito em versões anteriores. | +| db_log_queries | int\* | 0 | Não | Não | Registra todas as chamadas db_query do sqlite, incluindo a string de consulta.

**NOTA:** Esta variável do servidor foi adicionada na versão 0.3.7 R2 e não terá efeito em versões anteriores. | + +> [*] Algumas configurações são de um tipo diferente do que você pode pensar. + +## Cliente + +| Configuração | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ----------------- | ----- | ------------ | --------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| onfoot_rate\* | int | 30 | Sim | Não | O tempo em milissegundos que um cliente deve atualizar o servidor com novos dados enquanto está a pé. | +| incar_rate | int | 30 | Sim | Não | O tempo em milissegundos que um cliente deve atualizar o servidor com novos dados enquanto está em um veículo. | +| weapon_rate | int | 30 | Sim | Não | O tempo em milissegundos que um cliente deve atualizar o servidor com novos dados enquanto dispara uma arma. | +| stream_distance\* | float | 200.0 | Não | Não | A distância no plano X,Y em que os jogadores farão streaming das entidades do servidor. O máximo é **400.0** e o mínimo é **50.0**. Valores mais altos fazem os jogadores verem entidades do servidor a uma distância maior, mas requerem mais processamento do cliente e potencialmente mais largura de banda. | +| stream_rate\* | int | 1000 | Não | Não | O tempo em milissegundos antes que o streaming das entidades do servidor seja retestado para cada jogador. O máximo é **5000** e o mínimo é **500**. Valores mais baixos aumentam o processamento do servidor, pois ele precisa reverificar as condições de streaming com mais frequência para cada jogador. | + +> [*] Valores mais baixos de onfoot_rate, incar_rate e weapon_rate aumentam o desempenho de sincronização, mas usam mais largura de banda. + +## NPCs + +| Configuração | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ------------ | ---- | ------------ | --------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| maxnpc | int | 0 | Não | Não | A quantidade máxima de NPCs que seu servidor pode conter. Ao alterar este número, você pode modificar quantos dos slots de jogadores podem ser usados por NPCs. | + +## Compensação de lag + +| Configuração | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ------------ | ------ | ------------ | --------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| lagcompmode | int | 1 | Sim | Não | 0: Desativa completamente a compensação de lag.

1: Ativa completamente a compensação de lag.

2: Ativa apenas a compensação de lag de posição. Isso significa que a rotação do jogador não terá compensação de lag. | +| lagcomp | string | On | Sim | Sim | Provavelmente definido automaticamente como **On** ou **Off** dependendo da configuração **lagcompmode**. | + +## Modelos personalizados + +| Configuração | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ------------ | ------ | ------------ | --------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| useartwork | bool | 0 | Sim | Não | Define se o servidor usa modelos personalizados da pasta models. Defina como 1 para ativar ou 0 para desativar.

**NOTA:** Esta variável do servidor foi adicionada na versão 0.3.8 e não terá efeito em versões anteriores. | +| artwork | string | No | Sim | Sim | Provavelmente definido automaticamente como **No** ou **Yes** dependendo da configuração **useartwork**.

**NOTA:** Esta variável do servidor foi adicionada na versão 0.3.8 e não terá efeito em versões anteriores. | +| artpath | string | models | Sim | Não | O caminho onde os modelos personalizados estão localizados.

**NOTA:** Esta variável do servidor foi adicionada na versão 0.3.8 e não terá efeito em versões anteriores. | + +## Outros + +| Configuração | Tipo | Valor padrão | Somente leitura | Regra | Efeito | +| ------------ | ------ | ------------ | --------------- | ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| myriad | bool | 0 | Não | Não | Não utilizada. Provavelmente habilitava alguma compatibilidade com um antigo mod do GTA San Andreas chamado "Myriad Islands" anos atrás, provavelmente antes do ano 2008. | +| nosign | string | | Sim | Não | Não utilizada. | + +## Notas + +- Valores marcados como "Somente leitura" (conforme mostrado por `/rcon varlist`) não podem ser alterados durante a execução. Todos os outros valores podem ser (temporariamente) alterados passando-os para SendRconCommand. +- Valores marcados como "Regra" (conforme mostrado por `/rcon varlist`) são exibidos no navegador de servidores na seção Regras. +- Scripts não precisam estar nas pastas gamemodes ou filterscripts. A informação no server.cfg é um caminho e, portanto, pode usar "..". From 39de6e59221e6e85579056ac5bf34f09b79eae3d Mon Sep 17 00:00:00 2001 From: itsneufox <156133096+itsneufox@users.noreply.github.com> Date: Mon, 1 Dec 2025 23:49:44 +0000 Subject: [PATCH 2/3] fix animation pages issues --- frontend/src/pages/animations.tsx | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/frontend/src/pages/animations.tsx b/frontend/src/pages/animations.tsx index 680349a7749..c952a01e4e6 100644 --- a/frontend/src/pages/animations.tsx +++ b/frontend/src/pages/animations.tsx @@ -44,10 +44,35 @@ const AnimationsPage = () => { const handleLibraryChange = (library: string) => { setSelectedLibrary(library); setSelectedAnimation(""); + + // Update URL + if (typeof window !== "undefined") { + const url = new URL(window.location.href); + if (library) { + url.searchParams.set("library", library); + url.searchParams.delete("animation"); + } else { + url.searchParams.delete("library"); + url.searchParams.delete("animation"); + } + window.history.pushState({}, "", url); + } }; const handleAnimationChange = (animationName: string) => { setSelectedAnimation(animationName); + + // Update URL + if (typeof window !== "undefined" && selectedLibrary) { + const url = new URL(window.location.href); + url.searchParams.set("library", selectedLibrary); + if (animationName) { + url.searchParams.set("animation", animationName); + } else { + url.searchParams.delete("animation"); + } + window.history.pushState({}, "", url); + } }; return ( @@ -95,6 +120,7 @@ const AnimationsPage = () => { onChange={(e) => handleAnimationChange(e.target.value)} className={styles.select} disabled={!selectedLibrary} + key={selectedLibrary} > {availableAnimations.map((animation) => ( From 995be796e0f6b1873ee606ed4930a0eb0f17993e Mon Sep 17 00:00:00 2001 From: itsneufox <156133096+itsneufox@users.noreply.github.com> Date: Tue, 2 Dec 2025 00:04:38 +0000 Subject: [PATCH 3/3] patch1 --- .../scripting/language/ControlStructures.md | 4 +- .../current/scripting/language/Directives.md | 237 +- .../scripting/language/Initialisers.md | 340 +++ .../current/scripting/language/Operators.md | 107 + .../current/scripting/language/Style.md | 261 ++ .../current/scripting/language/Tags.md | 181 ++ .../current/scripting/language/Variables.md | 218 ++ .../language/reference/00-Contents.md | 78 + .../language/reference/01-Foreword.md | 29 + .../reference/02-A-tutorial-introduction.md | 2265 +++++++++++++++++ .../reference/03-Data-and-declarations.md | 338 +++ .../language/reference/04-Functions.md | 1197 +++++++++ .../language/reference/05-The-preprocessor.md | 150 ++ .../scripting/resources/callbacks-sequence.md | 79 + .../scripting/resources/connectionstatus.md | 23 + .../current/scripting/resources/constants.md | 408 +++ .../current/scripting/resources/crimelist.md | 33 + .../scripting/resources/damagestatus.md | 86 + .../current/scripting/resources/doorstates.md | 163 ++ .../scripting/resources/download-requests.md | 18 + .../scripting/resources/escapecodes.md | 31 + .../scripting/resources/explosionlist.md | 33 + .../scripting/resources/fightingstyles.md | 19 + .../current/tutorials/AdvancedStructures.md | 321 +++ .../current/tutorials/Binary.md | 411 +++ .../current/tutorials/_.md | 7 + .../current/tutorials/colorfix.md | 112 + 27 files changed, 7012 insertions(+), 137 deletions(-) create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Initialisers.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Operators.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Style.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Tags.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Variables.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/reference/00-Contents.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/reference/01-Foreword.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/reference/02-A-tutorial-introduction.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/reference/03-Data-and-declarations.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/reference/04-Functions.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/reference/05-The-preprocessor.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/resources/callbacks-sequence.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/resources/connectionstatus.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/resources/constants.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/resources/crimelist.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/resources/damagestatus.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/resources/doorstates.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/resources/download-requests.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/resources/escapecodes.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/resources/explosionlist.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/resources/fightingstyles.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/tutorials/AdvancedStructures.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/tutorials/Binary.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/tutorials/_.md create mode 100644 frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/tutorials/colorfix.md diff --git a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/ControlStructures.md b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/ControlStructures.md index f06e2a07a6d..a6457cb4aac 100644 --- a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/ControlStructures.md +++ b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/ControlStructures.md @@ -569,9 +569,7 @@ Um "default" (padrão) é equivalente a um "else", ele realiza algo caso todos o ### goto -goto is essentially a jump, it goes to a label without question (i.e. there's no condition to need to be true). You can see an example above in the if-goto loop. - -Um "goto" (vá até) é essencialmente um pulo, ele vai até determinada "label" sem a necessidade de uma condição. Você pode ver em um exemplo acima um if-goto loop. +Um `goto` é essencialmente um salto: ele leva a execução diretamente para um rótulo, sem verificar condições (como no exemplo do loop `if-goto` mostrado acima). ```c goto my_label; diff --git a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Directives.md b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Directives.md index 766a37f2e39..fa4015f5766 100644 --- a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Directives.md +++ b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Directives.md @@ -1,24 +1,28 @@ --- -title: "Diretivas" -sidebar_label: "Diretivas" +title: "Palavras-chave: diretivas" +sidebar_label: "Palavras-chave: diretivas" --- -As diretivas são instruções passadas ao compilador para controlar como ele interpreta seu código fonte. +Diretivas são instruções passadas ao compilador para controlar como ele interpreta o código-fonte. + ## `#assert` -Isto verifica se a expressão constante é verdadeira e se não aborta a compilação. +Verifica se uma expressão constante é verdadeira; caso contrário interrompe a compilação. + ```c #define MOO 10 #assert MOO > 5 ``` -Isso irá compilar corretamente. +Compila normalmente. + ```c #define MOO 1 #assert MOO > 5 ``` -Isso não vai dar e dará um erro fatal. Isto é semelhante a: +Provoca um erro fatal. É semelhante a: + ```c #define MOO 1 #if MOO <= 5 @@ -26,234 +30,196 @@ Isso não vai dar e dará um erro fatal. Isto é semelhante a: #endif ``` -No entanto, a afirmação dará um erro: +A diferença é que `#assert` mostra a mensagem: + ``` Assertation failed: 1 > 5 ``` -Onde o segundo dará um erro: +enquanto o segundo exibe: + ``` User error: Moo check failed ``` -O que pode ou não ser útil. ## `#define` -`#define` é uma diretiva de substituição de texto, onde quer que o primeiro símbolo da definição seja encontrado, o resto será colocado. +`#define` substitui texto: onde o símbolo declarado aparece, ele é trocado pelo conteúdo definido. ```c #define MOO 7 printf("%d", MOO); ``` -Será mudado para: +Vira: ```c printf("%d", 7); ``` -É por isso que todas as definições se perdem na descompilação, pois não existem quando o código é compilado (todas as diretivas são pré-processadas). As definições não têm que conter números: +Por isso `#define`s não existem no código compilado; o pré-processador resolve tudo antes. Eles não precisam conter números: + ```c #define PL new i = 0; i < MAX_PLAYERS; i++) if (IsPlayerConnected(i) -for(PL) printf("%d connected", i); +for (PL) printf("%d connected", i); ``` -Compilará para o loop de 1000, mais conhecido como Player Loop que todos nós conhecemos e amamos(e desprezamos). Observe como os parênteses são usados aqui, alguns do loop 'for' e outros do macro definido (o substituto). +O código acima gera o clássico player loop. Note como parte dos parênteses vem do `for` e parte do macro. + +Pouca gente sabe que você pode criar definições multilinha escapando a quebra de linha: -Outro fato pouco conhecido sobre as definições é que elas podem ser multi-linhas se você pular da nova linha. Geralmente uma nova linha termina a definição, no entanto, o seguinte é válido: ```c #define PL \ new i = 0; i < MAX_PLAYERS; i++) \ if (IsPlayerConnected(i) - -printf("%d", MOO(6)); -``` - -Isso resultará em 42 (não, não é escolhido aleatoriamente). Notou os parênteses excessivos na definição? Isto porque as definições são substituições de texto reto, de modo que serão compiladas como: -```c -printf("%d", ((6) * 7)); ``` -Está bem assim, mas olhe este exemplo: -```c -printf("%d", MOO(5 + 6)); -``` - -Você esperaria que compilasse para produzir 77 ((5 + 6) \* 7) e com os parênteses, porém sem os parênteses que você tem: +Macros também podem receber parâmetros: ```c #define MOO(%0) \ - %0 * 7 + ((%0) * 7) -printf("%d", MOO(5 + 6)); +printf("%d", MOO(6)); // imprime 42 +printf("%d", MOO(5 + 6)); // imprime 77 ``` -O que converte para: - -```c -printf("%d", MOO(5 + 6 * 7)); -``` +Os parênteses extras são importantes. Sem eles `MOO(5 + 6)` se expandiria para `5 + 6 * 7`, que resulta em 47 devido à ordem das operações. -Que, devido à ordem de operações, compila como (5 + (6 \* 7)), o que se for 47 e é muito errado. +Se o número de argumentos fornecido for maior que o declarado, o último parâmetro recebe todos os valores restantes: -Um fato interessante sobre os parâmetros é que, se você tem muitos, o último será todos os parâmetros extras. Assim formando: ```c #define PP(%0,%1) \ printf(%0, %1) -PP(%s %s %s, "hi", "hello", "hi"); +PP(%s %s %s, "hi", "hello", "hi"); // imprime "hi hello hi" ``` -Irá imprimir de fato: - -``` -hi hello hi -``` - -Como `%1` contém "hi", "hello", "hi". Você também deve ter notado o uso de `#` para converter um literal em uma string. Esta é uma característica apenas do SA-MP e pode ser útil. Foi apenas adicionado aqui para dar uma distinta distinção entre os parâmetros. +O operador `#` transforma um literal em string; esse recurso é específico do SA-MP. ## `#else` -`#else` É igual ao `else` comum, só que na diretiva #else. +Equivalente a `else`, mas usado em blocos condicionais do pré-processador (`#if`). ## `#elseif` -`#elseif` É igual elseif comum, só que na diretiva #if. +Versão de `else if` para `#if`: ```c #define MOO 10 #if MOO == 9 - printf("if"); + printf("if"); #elseif MOO == 8 - printf("else if"); + printf("else if"); #else - printf("else"); + printf("else"); #endif ``` ## `#emit` -Esta diretiva não está listada na tabela pawn-lang.pdf, entretanto, ela existe. Ela é basicamente um compilador em linha. Se você conhece AMX, você pode usar isto para colocar os opcodes AMX diretamente em seu código. A única limitação é que isso permite apenas um argumento. Sintaxe: `#emita >argumento>`. `` pode ser um número racional, inteiro ou símbolo (local ou global) (variáveis, funções e rótulos). A lista de opcodes e seu significado pode ser encontrada em Pawn Toolkit ver. 3664. + +Não aparece na tabela do `pawn-lang.pdf`, mas existe. É basicamente um compilador inline: se você conhece AMX, pode inserir opcodes diretamente no código. Sintaxe: `#emit `. O argumento pode ser um número (inteiro ou racional) ou um símbolo local/global (variáveis, funções ou rótulos). Consulte o Pawn Toolkit v3664 para a lista de opcodes. + ## `#endif` -`#endif` É como se um aparelho para-se. #if não usar aparelho, tudo é somado condicionalmente até o correspondente #endif. +Funciona como a chave de fechamento de um `if`. Tudo o que estiver entre `#if` e `#endif` é incluído condicionalmente. -## `#endinput, #endscript` +## `#endinput`, `#endscript` -Isto impede a inclusão de um único arquivo. +Interrompem a inclusão do arquivo atual. ## `#error` -Isto serve para o compilador instantaneamente imprimir mensagem de erro personalizada. Veja #assert para um exemplo. +Interrompe a compilação imediatamente exibindo uma mensagem customizada. Veja `#assert` para um exemplo. ## `#if` -`#if` Indica para o pré-processador e se é para compilar aquele trecho de código. Pode escolher exatamente o que compilar e o que não compilar a partir daqui. Por exemplo, considere o seguinte código: +Faz para o pré-processador o que `if` faz para o código: permite escolher o que será compilado. Considere: ```c -#define LIMITE 10 +#define LIMIT 10 -if (LIMITE < 10) +if (LIMIT < 10) { - printf("Limite muito baixo"); + printf("Limit too low"); } ``` -That will compile as: +Isso vira: ```c if (10 < 10) { - printf("Limite muito baixo"); + printf("Limit too low"); } ``` -O que claramente nunca retornará verdadeiro e o compilador sabe disso - portanto retornará um aviso de "expressão constante". A questão é, se nunca será verdade, de que vale a pena incluí-lo de todo? Poderá simplesmente remover o código, mas depois não haverá verificações se alguém alterar o macro LIMITE e recompilar. É para isto que serve a diretiva #if. Ao contrário do normal, que dá um aviso se a expressão for constante, as expressões #if devem ser constantes. Portanto: +O compilador sabe que a condição é constante e avisa. Se o resultado nunca muda, por que manter o código? Remover o trecho impediria validações futuras caso `LIMIT` fosse alterado. É aí que `#if` ajuda: diferente de `if`, ele *espera* expressões constantes. + ```c -#define LIMITE 10 +#define LIMIT 10 -#if LIMITE < 10 - #error Limite muito baixo +#if LIMIT < 10 + #error Limit too low #endif ``` -Isso irá verificar que o limite não é demasiado pequeno quando se compila e se é, dará um erro de tempo de compilação, em vez de se ter de testar o modo para ver se há algo de errado. Isto também significa que não é gerado um excesso de código. Note também a falta de parênteses, pode utilizá-los, e pode precisar deles em expressões mais complexas, mas não são necessários. - -Aqui está outro exemplo: - -```c -#define LIMITE 10 +Assim a checagem ocorre na compilação e evita código morto. Note que os parênteses são opcionais. -if (LIMITE < 10) -{ - printf("Limite menor que 10"); -} -else -{ - printf("Limite igual ou menor do que 10"); -} -``` +Outro exemplo: -Mais uma vez, esta é uma verificação constante, que dará um aviso, mas ambas as impressões serão compiladas quando sabermos que apenas uma será executada. Usando #if isto se tornar: ```c -#define LIMITE 10 +#define LIMIT 10 -#if LIMITE < 10 - printf("Limite menor que 10"); +#if LIMIT < 10 + printf("Limit less than 10"); #else - printf("Limite igual ou menor que 10"); + printf("Limit equal to or above 10"); #endif ``` -Dessa forma, apenas a impressão que é necessária será compilada e a outra ainda estará no seu código-fonte, caso alterem o valor do macro LIMITE e recompilem, mas não será incluída no código, uma vez que não é necessária. Esta forma também significa o inútil se não for executado sempre que o seu código for executado, o que é sempre bom. +Somente o ramo válido é compilado, mas o código redundante permanece no arquivo para futuras mudanças. ## `#include` -Isto retira todo o código de um arquivo especificado e insere-o no seu código no ponto em que a linha include se encontra. Há dois tipos de include: relativo e sistema (termos inventados pelo autor para simplificar o que está sendo feito). Relativo inclui usar aspas duplas em torno do nome do arquivo e estão localizados em relação ao arquivo atual, portanto: +Insere o conteúdo de outro arquivo no ponto onde a diretiva aparece. Existem dois formatos: -```c -#include "include.pwn" -``` +- **Relativo** (`"arquivo.pwn"`): o caminho é resolvido relativo ao arquivo atual. +- **Sistema** (``): o arquivo é buscado no diretório `include` ao lado (ou um nível acima) do compilador Pawn, como `pawno/include`. -incluiria o arquivo "include.pwn" do mesmo diretório que o arquivo incluindo esse arquivo. O outro tipo, sistema, inclui o arquivo do diretório "include" que está localizado ou no mesmo diretório que o compilador Pawn ou diretório pai (caminhos: "include",".../include"): -```c -#include "" -``` - -Incluiria o arquivo "include.inc" (note a falta de extensão, pode especificar se um arquivo não for .p (não .pwn ou .inc) do diretório pawno/include (supondo que você esteja utilizando Pawno). - -Ambos os tipos podem conter diretórios: - -```#include +#include "folder/me.pwn" +#include ``` -Ambos incluirão um arquivo de um diretório abaixo dos respectivos directórios por defeito. Se o arquivo não existir, a compilação falhará. +Se o arquivo não existir, a compilação falha. ## `#pragma` -Esta é uma das diretivas mais complexas. Ela tem uma série de opções para controlar como seu roteiro funciona. Um exemplo de configuração pareceria: +Diretiva para ajustar o comportamento do compilador. Exemplo: + ```c #pragma ctrlchar '$' ``` -Mais uma vez, esta é uma verificação constante, que dará um aviso, mas ambas as impressões serão compiladas quando sabermos que apenas uma será executada. Usando #if isto se tornar: +Isso altera o caractere de escape de `\` para `$`. Algumas opções úteis no contexto SA:MP: + | Nome | Valores | Descrição | -| ---------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| codepage | nome/valor | Define a página de codificação Unicode a utilizar para cordas. | -| comprimir | 1/0 | Sem suporte no SA-MP - não tente usá-lo. | -| depreciado | símbolo | gerou um aviso se o símbolo dado for utilizado para dizer às pessoas que há uma versão melhor disponível. | -| dinâmico | valor (geralmente uma potência de 2) | Define o tamanho da memória (em células) atribuída à pilha e à pilha. Necessário se receber um aviso de utilização de memória em excesso após a compilação. (Uma tabela estranha após a linha de copyright do compilador) | -| biblioteca | nome dll | Widley incorrectamente utilizado no SA-MP. Isto especifica a dll para obter as funções nativas definidas no ficheiro de onde é proveniente. Não define um ficheiro **como** uma biblioteca. | -| pack | 1/0 | Troque os significados de !"" e """. Ver penhor-lang.pdf para mais informações sobre cordas embaladas. | -| tamanho do separador | valor | Outra configuração largamente mal utilizada. Isto deve ser utilizado para definir o tamanho de um separador para evitar avisos de compilação que estejam errados devido a espaços e separadores serem utilizados alternadamente. Isto é definido para 4 em SA:MP, pois é o tamanho de uma tabulação em pawno. Definindo este valor como 0 irá suprimir todos os seus avisos de indentação, mas é altamente desaconselhável uma vez que permite um código totalmente ilegível. | -| não utilizado | símbolo | como depreciado isto aparece após o símbolo para o qual se deseja suprimir o aviso "símbolo nunca é utilizado". Geralmente, o método preferido para o fazer é a utilização de stock, no entanto, isto nem sempre é aplicável (por exemplo, os parâmetros da função não podem ser compilados). - -### Descontinuado +| --- | --- | --- | +| `codepage` | nome/valor | Define a página de código Unicode usada para strings. | +| `compress` | `1`/`0` | Não suportado no SA-MP. | +| `deprecated` | símbolo | Gera um aviso ao usar o símbolo indicado, sinalizando que existe versão melhor. | +| `dynamic` | valor (geralmente potência de 2) | Define o tamanho (em células) da pilha e do heap; use ao receber avisos de memória insuficiente. | +| `library` | nome da DLL | Indica a DLL da qual funções nativas serão importadas; não transforma o arquivo atual em biblioteca. | +| `pack` | `1`/`0` | Inverte o significado de `!""` e `""`. Veja `pawn-lang.pdf` para detalhes sobre strings compactadas. | +| `tabsize` | valor | Define o tamanho do tab para evitar avisos errados de indentação; em SA:MP o padrão é 4. Não use 0, pois oculta avisos úteis. | +| `unused` | símbolo | Suprime o aviso “symbol is never used” para o símbolo indicado. Útil quando `stock` não se aplica (por exemplo, parâmetros). | + +### Depreciado ```c new @@ -261,13 +227,14 @@ new #pragma deprecated gOldVariable -main() {printf("%d", gOldVariable);} +main() { printf("%d", gOldVariable); } ``` -Isso dará um aviso de que a gOldVariable não deve mais ser usada. Isto é útil principalmente para funções que preservam a compatibilidade com o passado enquanto atualizam o API. -### `#tryinclude` +Gera um aviso indicando que `gOldVariable` não deve mais ser usada. Útil para manter compatibilidade enquanto a API evolui. + +## `#tryinclude` -Isso é semelhante a #include, mas se o arquivo não existir, a compilação não falhará. Isso é útil apenas para incluir recursos em seu script se uma pessoa tiver o plugin correto instalado(Ou pelo menos o plugin incluído) +Semelhante a `#include`, mas não falha se o arquivo não existir. Serve para incluir recursos opcionais quando o desenvolvedor possui o plugin apropriado. **myinc.inc** @@ -277,41 +244,43 @@ Isso é semelhante a #include, mas se o arquivo não existir, a compilação nã #endif #define _MY_INC_INC -stock MinhaIncludeFunc() {printf("Olá!");} +stock MyIncFunc() { printf("Hello"); } ``` -**Gamemode:** +**Gamemode** ```c -#tryinclude +#tryinclude main() { - #if defined _MINHA_INC_INC - MinhaIncludeFunc(); + #if defined _MY_INC_INC + MyIncFunc(); #endif } ``` -Isso só chamará a função MinhaIncludeFunc se o arquivo com ele for encontrado na pasta includes e compilado com sucesso. Isso, como afirmado anteriormente, é bom para plugins padrões (Por exemplo a_samp.inc ou a_actors.inc) para verificar se o desenvolvedor realmente tem o plugin instalado. -### `#undef` +`MyIncFunc` só será chamada se `myinc.inc` estiver disponível e compilar sem erros. + +## `#undef` -Remove um macro ou simbolo constante anteriormente definido. +Remove um macro ou símbolo constante previamente definido. ```c #define MOO 10 printf("%d", MOO); #undef MOO -printf("%d", MOO); +printf("%d", MOO); // erro: MOO não existe mais ``` -Irá falhar ao compilar, pois o macro MOO não existe. +Também funciona com enumeradores: + ```c enum { - e_example = 300 + E_EXAMPLE = 300 }; -printf("%d", e_example); -#undef e_example -printf("%d", e_example); // fatal error +printf("%d", E_EXAMPLE); +#undef E_EXAMPLE +printf("%d", E_EXAMPLE); // erro fatal ``` diff --git a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Initialisers.md b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Initialisers.md new file mode 100644 index 00000000000..2eadae0e8ef --- /dev/null +++ b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Initialisers.md @@ -0,0 +1,340 @@ +--- +title: "Palavras-chave: inicializadores" +sidebar_label: "Palavras-chave: inicializadores" +--- + +## `const` + +```c +new const + MY_CONSTANT[] = {1, 2, 3}; +``` + +`const` não é muito usado, mas serve para declarar variáveis que não podem ser alteradas em tempo de execução. Em funções, parâmetros de array marcados como `const` podem ser otimizados, e você pode criar algo parecido com um `#define`, só que baseado em arrays. Como `const` é um modificador, ele deve acompanhar `new` ou outro declarador de variável. Se tentar modificar uma variável constante, o compilador reclamará. + +## `enum` + +Enums são úteis para agrupar dados relacionados, substituir longas listas de `#define`s e criar novas tags. Também facilitam o controle de índices de arrays. + +Definição mais comum: + +```c +enum E_MY_ARRAY +{ + E_MY_ARRAY_MONEY, + E_MY_ARRAY_GUN +} + +new + gPlayerData[MAX_PLAYERS][E_MY_ARRAY]; + +public OnPlayerConnect(playerid) +{ + gPlayerData[playerid][E_MY_ARRAY_MONEY] = 0; + gPlayerData[playerid][E_MY_ARRAY_GUN] = 5; +} +``` + +Isso cria dois slots por jogador. Sem enum, ficaria: + +```c +new + gPlayerData[MAX_PLAYERS][2]; + +public OnPlayerConnect(playerid) +{ + gPlayerData[playerid][0] = 0; + gPlayerData[playerid][1] = 5; +} +``` + +Funciona, mas é menos legível. Se quiser inserir um slot entre 0 e 1, teria de renumerar tudo. Com enum basta adicionar o novo campo: + +```c +enum E_MY_ARRAY +{ + E_MY_ARRAY_MONEY, + E_MY_ARRAY_AMMO, + E_MY_ARRAY_GUN +} +``` + +Ao recompilar, o compilador ajusta todos os índices. + +A forma completa de um enum é: + +```c +enum NAME (modificador) +{ + NAME_ENTRY_1 = valor, + ... +} +``` + +Se você não definir um modificador, o padrão é `+= 1`. Ou seja, cada item vale o item anterior + 1. Exemplo: + +```c +enum E_EXAMPLE +{ + E_EXAMPLE_0, + E_EXAMPLE_1, + E_EXAMPLE_2 +} +``` + +Aqui temos 0, 1, 2 e o valor do enum (`E_EXAMPLE`) é 3. Mudando o modificador para `+= 5` os valores passam a ser 0, 5, 10 e 15. Declarar um array com `gEnumArray[E_EXAMPLE]` reservá 15 células, mas os índices simbólicos atingem apenas 0, 5 e 10. + +Também é possível usar outro modificador, como `*= 2`. Nesse caso, se não definir o primeiro valor manualmente, todos continuam 0. Para corrigir, basta atribuir um valor inicial: + +```c +enum E_EXAMPLE (*= 2) +{ + E_EXAMPLE_0 = 1, + E_EXAMPLE_1, + E_EXAMPLE_2 +} +``` + +Resultado: 1, 2, 4 e 8. Você pode definir quantos valores quiser: + +```c +enum E_EXAMPLE (*= 2) +{ + E_EXAMPLE_0, + E_EXAMPLE_1 = 1, + E_EXAMPLE_2 +} // 0, 1, 2, 4 +``` + +Arrays também são suportados: + +```c +enum E_EXAMPLE +{ + E_EXAMPLE_0[10], + E_EXAMPLE_1, + E_EXAMPLE_2 +} // produz 0, 10, 11 e 12 +``` + +Itens podem ter tags. No exemplo inicial: + +```c +enum E_MY_ARRAY +{ + E_MY_ARRAY_MONEY, + E_MY_ARRAY_AMMO, + Float:E_MY_ARRAY_HEALTH, + E_MY_ARRAY_GUN +} +``` + +Assim evitamos `tag mismatch` ao armazenar floats. + +Enums também podem servir como tags: + +```c +enum E_MY_TAG (<<= 1) +{ + E_MY_TAG_NONE, + E_MY_TAG_VAL_1 = 1, + E_MY_TAG_VAL_2, + E_MY_TAG_VAL_3, + E_MY_TAG_VAL_4 +} + +new + E_MY_TAG:gMyTagVar = E_MY_TAG_VAL_2 | E_MY_TAG_VAL_3; +``` + +`gMyTagVar` terá valor 6 e tag personalizada. Atribuir um número puro gera aviso: + +```c +gMyTagVar = 7; // warning +gMyTagVar = E_MY_TAG:7; // válido +``` + +Muito útil para flags ou dados combinados: + +```c +enum E_MY_TAG (<<= 1) +{ + E_MY_TAG_NONE, + E_MY_TAG_MASK = 0xFF, + E_MY_TAG_VAL_1 = 0x100, + E_MY_TAG_VAL_2, + E_MY_TAG_VAL_3, + E_MY_TAG_VAL_4 +} + +new + E_MY_TAG:gMyTagVar = E_MY_TAG_VAL_2 | E_MY_TAG_VAL_3 | (E_MY_TAG:7 & E_MY_TAG_MASK); +``` + +Valor final: 0x0607 (1543). + +Enums também podem substituir blocos de `#define`: + +```c +enum +{ + TEAM_NONE, + TEAM_COP, + TEAM_ROBBER, + TEAM_CIV, + TEAM_CLERK, + TEAM_DRIVER +} +``` + +Os valores continuam 0–5 e o uso é idêntico. Você pode ainda transformá-los em bitmasks para permitir múltiplos times: + +```c +enum (<<= 1) +{ + TEAM_NONE, + TEAM_COP = 1, + TEAM_ROBBER, + TEAM_CIV, + TEAM_CLERK, + TEAM_DRIVER, + TEAM_ADMIN +} +``` + +Operações básicas: + +- Adicionar: `gPlayerTeam[playerid] |= TEAM_COP` +- Remover: `gPlayerTeam[playerid] &= ~TEAM_COP` +- Verificar: `if (gPlayerTeam[playerid] & TEAM_COP)` + +## `forward` + +Informa ao compilador que uma função será declarada depois. Obrigatório para todas as `public`, mas útil em outros casos, como funções que retornam tags. + +```c +forward MyPublicFunction(playerid, const string[]); + +public MyPublicFunction(playerid, const string[]) +{ +} +``` + +Sem o `forward`, o compilador precisa “reprocessar” quando encontra uma função que retorna, por exemplo, `Float:` antes da definição. Outra alternativa é declarar a função antes do uso, mas o `forward` evita reorganizar o arquivo. + +## `native` + +Nativas são funções implementadas fora do script (no servidor ou em plugins). Você só pode declará-las se já existir uma implementação; porém, pode criar “falsas” nativas para listar funções no painel do Pawno. + +```c +native printf(const format[], {Float,_}:...); +``` + +Para exibir uma função personalizada na lista sem declará-la de fato: + +```c +/* +native MyFunction(playerid); +*/ +``` + +O Pawno não interpreta comentários e adiciona o símbolo na lista, enquanto o compilador ignora a linha. + +Também é possível renomear ou encapsular nativas: + +```c +native my_print(const string[]) = print; + +print(const string[]) +{ + my_print("Someone called print()"); + my_print(string); +} +``` + +Agora toda chamada a `print` passa pelo wrapper. + +## `new` + +Declara variáveis; por padrão começam em 0. + +```c +new + myVar = 5; +``` + +O escopo depende das chaves onde é declarado. Variáveis globais (`new` fora de funções) podem ser usadas em qualquer ponto após a declaração. Se o arquivo incluir outros, eles também terão acesso, a menos que você use `static`. + +## `operator` + +Permite sobrecarregar operadores para tags personalizadas. Exemplo para armazenar números em big endian: + +```c +stock BigEndian:operator=(value) +{ + return BigEndian:(((value >>> 24) & 0x000000FF) | + ((value >>> 8) & 0x0000FF00) | + ((value << 8) & 0x00FF0000) | + ((value << 24) & 0xFF000000)); +} +``` + +Operadores suportados: `+`, `-`, `*`, `/`, `%`, `++`, `--`, `==`, `!=`, `<`, `>`, `<=`, `>=`, `!` e `=`. + +Eles podem executar qualquer lógica, inclusive ignorar o comportamento padrão. + +## `public` + +Transforma funções (ou variáveis) em símbolos acessíveis pelo servidor. Todas as callbacks do SA:MP são `public`. O nome textual da função é armazenado no AMX, o que permite chamá-la por `CallLocalFunction`, `SetTimerEx`, etc. Para isso é obrigatório declarar um `forward`. + +```c +forward MyPublicFunc(); + +main() +{ + CallLocalFunction("MyPublicFunc", ""); +} + +public MyPublicFunc() +{ + printf("Hello"); +} +``` + +Funções públicas também podem ser chamadas normalmente dentro do script (`MyPublicFunc();`), o que é bem mais rápido do que invoques por string. + +## `static` + +`static` aplicado globalmente cria variáveis visíveis apenas no arquivo (ou `#section`) onde foram declaradas. Diferente de `new`, a visibilidade não se estende a arquivos incluídos. + +Localmente, `static` mantém o valor entre chamadas: + +```c +MyFunc() +{ + static + counter = 0; + printf("%d", counter); + counter++; +} +``` + +A primeira chamada imprime 0, a segunda 1 e assim por diante. Com `new`, o valor seria reiniciado em cada execução. Também é possível declarar funções `static` para “privatizá-las”. + +## `stock` + +`stock` serve para declarar funções ou variáveis opcionais, sem gerar avisos de “unused”. Se o símbolo for usado, o compilador o inclui; caso contrário, ele é descartado. + +```c +stock Func1() +{ + printf("Hello"); +} + +stock Func2() +{ + printf("Hi"); +} +``` + +Útil para bibliotecas, onde você não sabe quais funções o usuário vai chamar. Diferentemente de `#pragma unused`, o código nem chega a ser emitido se não houver uso. diff --git a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Operators.md b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Operators.md new file mode 100644 index 00000000000..2ee89fa5ec6 --- /dev/null +++ b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Operators.md @@ -0,0 +1,107 @@ +--- +title: "Palavras-chave: operadores" +sidebar_label: "Palavras-chave: operadores" +--- + +## `char` + +Retorna quantas células (de 4 bytes) são necessárias para armazenar determinado número de caracteres em uma string compactada. + +```c +4 char // 1 +3 char // 1 (não existe ¾ de célula) +256 char // 64 (256 ÷ 4) +``` + +Utilize principalmente em declarações de arrays: + +```c +new + buffer[40 char]; // 10 células +``` + +Consulte o `pawn-lang.pdf` para saber mais sobre strings compactadas. + +## `defined` + +Verifica se um símbolo existe, geralmente dentro de `#if`: + +```c +new + someVar = 5; +#if defined someVar + printf("%d", someVar); +#else + #error The variable 'someVar' isn't defined +#endif +``` + +Uso típico: habilitar trechos de código dependendo de um `#define`. + +```c +#define FILTERSCRIPT + +#if defined FILTERSCRIPT + +public OnFilterScriptInit() +{ + return 1; +} + +#else + +public OnGameModeInit() +{ + return 1; +} + +#endif +``` + +## `sizeof` + +Retorna o tamanho de um array em **elementos**: + +```c +new + someVar[10]; +printf("%d", sizeof (someVar)); // 10 +``` + +Para arrays multidimensionais: + +```c +new + someVar[2][10]; +printf("%d %d", sizeof (someVar), sizeof (someVar[])); // 2 10 +``` + +## `state` + +Relacionado ao sistema de autômatos da linguagem Pawn; não é abordado aqui. + +## `tagof` + +Retorna o identificador numérico da tag de uma variável: + +```c +new + someVar, + Float:someFloat; +printf("%d %d", tagof (someVar), tagof (someFloat)); +``` + +Os valores exibidos correspondem aos códigos internos das tags. Para verificar se uma variável possui determinada tag: + +```c +new Float:fValue = 6.9; + +if (tagof (fValue) == tagof (Float:)) +{ + print("float"); +} +else +{ + print("not a float"); +} +``` diff --git a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Style.md b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Style.md new file mode 100644 index 00000000000..4d2ca98ae48 --- /dev/null +++ b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Style.md @@ -0,0 +1,261 @@ +--- +title: "Guia de estilo Pawn" +sidebar_label: "Guia de estilo Pawn" +description: Um guia breve sobre a convenção de nomes e outros aspectos do código Pawn para facilitar a comunicação de intenção e agilizar depuração e compartilhamento. +--- + +Este documento resume as convenções geralmente aceitas para nomeação e demais aspectos do código-fonte Pawn a fim de facilitar a comunicação de intenções e tornar a depuração e o compartilhamento de código mais simples. + +Veja também: + +- [Modern Pawn](https://github.com/Southclaws/sampctl/wiki/Modern-Pawn) +- [Pawn Package](https://github.com/Southclaws/sampctl/wiki/Packages) + +## Terminologia + +### Statement (instrução) + +Uma instrução é um trecho de código que ordena imperativamente que o programa faça algo. Ela é um pedaço válido de código que produz algum resultado. + +```c +a = b + c; +``` + +Esta é uma instrução composta por uma variável recebendo o resultado de uma [#Expression]. + +```c +SetPlayerColor(playerid, 0xFF4700FF); +``` + +Esta é uma instrução que manda o programa chamar uma função com determinados argumentos. + +```c +x + 8 +``` + +Isto _não_ é uma instrução porque o resultado não é usado em lugar nenhum; é apenas uma [#Expression]. + +### Compound Statement + +Uma instrução composta é um conjunto de instruções delimitadas por chaves. + +```c +{ + new message[] = "hi!"; + print(message); +} +``` + +Este é um bloco composto por duas instruções. + +```c +if (a == b) +{ + print("hello!"); +} +``` + +Este é um bloco composto com uma condição `if`, normalmente chamado de “if statement”. + +```c +return Function1(), Function2(), Function3(); +``` + +Isto _não_ é um bloco composto, e sim uma cadeia de instruções separadas por vírgulas. Esse encadeamento é considerado má prática. + +### Expression (expressão) + +Uma expressão é uma construção sintática que produz um valor; ela não é uma instrução válida a menos que o valor seja usado de alguma forma. + +Expressões normalmente são combinadas para formar instruções. + +```c +a + b +``` + +Esta é uma expressão de soma simples que recebe dois valores e aplica o operador de adição. + +## Diretrizes + +### Chaves + +Prefira o estilo Allman: + +```pawn +function() +{ + // +} +``` + +Porém, se você não consegue evitar, o estilo K&R também é válido em Pawn: + +```pawn +function() { + // +} +``` + +### Switches + +`switch` deve usar dois níveis de indentação, um para o bloco `switch` e outro para cada `case` ou bloco composto. + +```pawn +switch (variable) +{ + case 0: + return 0; + case 1: + return 1; + case 2: + return 2; + default: + return -1; +} +``` + +```pawn +switch (variable) +{ + case 0: + { + // code... + return 0; + } + case 1: + { + // code... + return 1; + } + case 2: + { + // code... + return 2; + } + default: + { + // code... + return -1; + } +} +``` + +### Blocos + +Blocos sempre devem usar chaves, mesmo que contenham apenas uma linha de código. Isso vale para todas as estruturas, inclusive funções. + +```pawn +func() +{ + singleLineExpr(); +} +``` + +```pawn +func() +{ + if () + { + singleLineExpr(); + } +} +``` + +```pawn +func() +{ + if () + { + singleLineExpr(); + } + else if () + { + // + } + else + { + // + } +} +``` + +### Nomeação + +#### Funções + +Funções devem usar `PascalCase`. + +#### Variáveis globais + +Variáveis globais declaradas com `new` devem usar `g_` seguido de `PascalCase` (por exemplo `g_VariableName`). Se forem declaradas com `static`, use `s_` com `PascalCase` (por exemplo `s_VariableName`). + +Globais constantes devem usar `SCREAMING_SNAKE_CASE`. + +#### Variáveis locais + +Variáveis locais devem sempre usar `camelCase` e nunca nomes de uma única letra, exceto: + +- `i`, `j`, `k` etc. em laços `for` +- `x`, `y`, `z` etc. em contextos matemáticos + +#### Enumeradores + +Enumeradores nomeados devem ser prefixados com `E_` (tag forte) ou `e_` (tag fraca). + +Os campos do enumerador também devem usar `SCREAMING_SNAKE_CASE` e o nome do enumerador como prefixo. + +```pawn +static enum E_PLAYER_DATA { + E_PLAYER_CASH, + Float:E_PLAYER_HEALTH, +} +``` + +Usando uma tag fraca: + +```pawn +static enum e_PLAYER_DATA { + E_PLAYER_CASH, + Float:E_PLAYER_HEALTH, +} +``` + +Enumeradores não nomeados também devem usar `SCREAMING_SNAKE_CASE` e o nome do enumerador como prefixo. + +```pawn +static enum { + ENUMATOR_INTEGER, + Float:ENUMATOR_FLOAT, +} +``` + +Enumeradores devem ser declarados como `static`, a menos que sejam usados fora do módulo. + +#### Macros e definições do pré-processador + +Macros devem sempre usar `SCREAMING_SNAKE_CASE`, não importa o uso. + +Definições do pré-processador (constantes) também devem usar `SCREAMING_SNAKE_CASE`. + +Isso ajuda a diferenciar variáveis de constantes e funções de macros. + +De forma geral, evite inventar novas construções sintáticas para não confundir quem está começando sobre o que faz parte da linguagem e o que vem de bibliotecas. + +Algumas bibliotecas antigas fazem isso e não podem ser alteradas por questões de compatibilidade. + +### Documentação + +Documente funções exportadas com um comentário de linha no formato `// FunctionName faz X, Y e Z e retorna A`, em que a primeira palavra é o nome da função seguido de uma breve descrição. Não há necessidade de citar cada parâmetro. Exemplo: + +```pawn +// LoadPlayerAccount é chamada para iniciar o processo de carregamento da conta. +// Esta função dispara chamadas HTTP para obter dados do jogador, exibe diálogos +// e, quando o processo termina com sucesso, o evento `OnPlayerLogin` é emitido. +// Em caso de falha, o jogador é desconectado. +stock Error:LoadPlayerAccount(playerid) +{ + // code... +} +``` + +Cada pacote deve ter um `README` e, se necessário, cada módulo deve ter um comentário logo na primeira linha descrevendo o que ele oferece. diff --git a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Tags.md b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Tags.md new file mode 100644 index 00000000000..3f7a658f5df --- /dev/null +++ b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Tags.md @@ -0,0 +1,181 @@ +--- +title: "Scripting: Tags" +sidebar_label: "Scripting: Tags" +description: Um guia sobre Tags, o recurso semelhante a tipos da linguagem Pawn que oferece segurança ao trabalhar com valores de diferentes propósitos. +--- + +## Introdução + +Uma tag é um prefixo aplicado a uma variável para indicar ao compilador que ela deve ser tratada de forma especial em determinadas situações. Por exemplo, você pode usar tags para determinar onde uma variável pode ou não ser usada, ou ainda definir uma forma específica de somar duas variáveis. + +Existem dois tipos de tags: tags fortes (usam letra maiúscula) e tags fracas (usam letra minúscula). Em geral elas funcionam igual, mas em algumas situações as tags fracas podem ser convertidas silenciosamente para “sem tag” pelo compilador (ou seja, você não verá um aviso). Na maioria das vezes, com tags fracas, e sempre com tags fortes, mudar a tag implicitamente gera um aviso indicando que os dados podem estar sendo usados de forma incorreta. + +Um exemplo simples: + +```c +new + File:myfile = fopen("file.txt", io_read); +myFile += 4; +``` + +A função `fopen` retorna um valor com tag `File:`; não há problema porque esse valor é armazenado em uma variável também marcada com `File:` (observe que as letras maiúsculas/minúsculas são idênticas). Contudo, na linha seguinte o valor `4` é somado ao handle do arquivo. O `4` não possui tag (na verdade tem o tipo `_:` por padrão, mas não é algo com que você precise se preocupar normalmente) e `myFile` tem a tag `File:`. Como nada e algo não podem ser iguais, o compilador emitirá um aviso; isso é bom, pois um handle de arquivo não faz sentido em termos de valor numérico, então modificá-lo apenas corromperia o handle e impediria o fechamento do arquivo, já que não haveria mais um handle válido para passar ao fechamento. + +### Tags fortes + +Como dito, uma tag forte começa com letra maiúscula. Exemplos em SA:MP: + +```c +Float: +File: +Text: +``` + +Elas não podem ser misturadas com outros tipos e sempre geram aviso quando você tenta fazer isso: + +```c +new + Float:myFloat, + File:myFile, + myBlank; + +myFile = fopen("file.txt", io_read); // File: = File:, sem aviso + +myFloat = myFile; // Float: = File:, aviso "tag mismatch" + +myFloat = 4; // Float: = _: (nenhuma), aviso "tag mismatch" + +myBlank = myFloat; // _: (nenhuma) = Float:, aviso "tag mismatch" +``` + +### Tags fracas + +Uma tag fraca se comporta quase como uma tag forte, mas o compilador não gera aviso quando o destino não tem tag e a origem é uma tag fraca. Compare o código com tag forte e com tag fraca: o primeiro gera aviso, o segundo não. + +```c +new + Strong:myStrong, + weak:myWeak, + myNone; + +myNone = myStrong; // Aviso +myNone = myWeak; // Sem aviso +``` + +O inverso não é verdadeiro: + +```c +myWeak = myNone; // Aviso +``` + +Isso também vale para funções: chamar uma função cujo parâmetro é sem tag passando uma variável com tag fraca não gera aviso: + +```c +new + weak:myWeak; +MyFunction(myWeak); + + + +MyFunction(myVar) +{ + ... +} +``` + +Mas chamar uma função que espera um parâmetro etiquetado (fraco ou forte) com um valor sem tag gera aviso. Exemplos de tags fracas usados em SA:MP, ainda que pouco conhecidos, incluem: + +```c +bool: +filemode: +floatround_method: +``` + +## Uso + +### Declaração + +Declarar uma variável com tag é simples: basta escrever a tag; não é necessário defini-la antes, embora isso seja possível e útil em alguns casos (veremos mais à frente): + +```c +new + Mytag:myVariable; +``` + +Declarar com uma tag existente permite usar essa variável com as funções e operadores já definidos para o tipo. + +### Funções + +Criar uma função que recebe ou retorna uma tag também é simples: prefixe a parte relevante com o tipo desejado, por exemplo: + +```c +Float:GetValue(File:fHnd, const name[]) +{ + ... +} +``` + +Essa função recebe o handle de um arquivo e retorna um float (presumivelmente um valor lido desse arquivo e correspondente ao nome informado em `name[]`). Ela provavelmente usará `floatstr`, que também retorna um `Float:` (é possível conferir na barra de status do Pawno ao clicar na função). A implementação em si não importa, mas ela converte a string em um float IEEE, armazenado como um cell (na prática é um inteiro com o mesmo padrão de bits do número IEEE, já que Pawn não tem tipagem; tags existem justamente para amenizar isso). + +### Operadores + +Operadores como `+`, `==`, `>` etc. podem ser sobrecarregados para tags diferentes, ou seja, fazer `+` em dois `Float:` executa algo distinto de somar duas variáveis sem tag. Isso é especialmente útil para floats porque, como mencionado, eles são apenas inteiros com um padrão de bits específico; se os operadores não fossem sobrecarregados, as operações ocorreriam sobre os inteiros e o resultado, interpretado como float, seria lixo. Por isso a tag `Float:` tem versões sobrecarregadas da maioria dos operadores para chamar funções especiais no servidor em vez de confiar em Pawn. + +Um operador é igual a uma função normal, mas com o nome `operator(**símbolo**)`, onde (**símbolo**) é o operador que você quer sobrescrever. Os operadores válidos são: + +```c ++ +- += +++ +-- +== +* +/ +!= +> +< +>= +<= +! +% +``` + +Operadores como `\`, `*`, `=` etc. já são tratados automaticamente. Operadores como `&` não podem ser sobrecarregados. Você também pode sobrescrever o mesmo operador várias vezes com combinações diferentes de tags. Exemplo: + +```c +stock Float:operator=(Mytag:oper) +{ + return float(_:oper); +} +``` + +Se adicionar isso ao código e fizer: + +```c +new + Float:myFloat, + Mytag:myTag; + +myFloat = myTag; +``` + +Você não verá mais o aviso do compilador porque agora o operador `=` para o caso `Float: = Mytag:` está implementado e o compilador sabe como tratar a conversão. + +### Sobrescrita + +No exemplo de sobrecarga acima, a linha funcional foi: + +```c +return float(_:oper); +``` + +Esse é um exemplo de sobrescrita de tag: o `_:` antes de `oper` indica ao compilador que ignore o fato de a variável ter tag `Mytag:` e a trate como `_:` (sem tag). A função `float()` aplica a tag a um número comum, então precisa receber um número sem tag. No exemplo consideramos que `Mytag` armazena um inteiro comum, mas é necessário cuidado com a sobrescrita; o código a seguir gera resultados estranhos: + +```c +new + Float:f1, + Float:f2 = 4.0; +f1 = float(_:f2); +``` + +Seria lógico imaginar que `f1` viraria `4.0`, mas isso não acontece. Como mencionado, `f2` guarda a representação de `4.0`, e não apenas o valor inteiro `4`; isso significa que o valor bruto contido na variável é um número bem incomum. Ao mandar o compilador tratá-la como inteiro, ele simplesmente interpreta o padrão de bits como um inteiro, sem converter o float, então o resultado será praticamente aleatório (há um padrão nos floats IEEE, mas certamente não se parecerá com `4.0`). diff --git a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Variables.md b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Variables.md new file mode 100644 index 00000000000..8fddf8a92e8 --- /dev/null +++ b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/Variables.md @@ -0,0 +1,218 @@ +--- +title: "Noções básicas: Variáveis" +sidebar_label: "Noções básicas: Variáveis" +description: Um guia introdutório sobre variáveis em Pawn +--- + +## Variáveis + +Um dos conceitos mais importantes em programação é o de “variáveis”. Em programação, uma variável é uma entidade mutável, mas em que sentido? Em Pawn, uma variável guarda um “valor” a qualquer momento e esse valor — como o próprio nome sugere — é “variável” ou “mutável”. + +Variáveis são importantes porque são unidades pequenas de memória que podem guardar ou “lembrar” valores diferentes enquanto o programa está em execução, e essa propriedade é extremamente útil. Por exemplo, se você quiser acompanhar a pontuação de 100 jogadores em um jogo, basta programar o computador para armazenar (lembrar) e atualizar esses valores. Depois, se quiser calcular a média dessas pontuações ou montar um placar, os valores guardados nas variáveis podem ser acessados facilmente e usados para esse fim. + +### Declarando variáveis + +O seguinte é o formato básico de declaração: + +```c +// Criando (mais precisamente, declarando) uma variável chamada 'myVariable' + +new myVariable; + +// A palavra-chave 'new' é usada para declarar uma variável +// Na linha acima, declaramos uma variável com o nome 'myVariable' +// O ponto e vírgula fecha a instrução de declaração. +``` + +O formato fica mais claro com alguns exemplos: + +```c +new var; +new ammo; +new score; +new vehicles; +new topScore; +``` + +Cada variável acima tem o valor zero por padrão. Há diferentes maneiras de atribuir valores a uma variável; uma delas é definir o valor no momento da declaração: + +```c +new letters = 25; +``` + +No exemplo acima, declaramos a variável `letters` com o valor 25. Note o sinal de igualdade, que é um operador de atribuição simples usado para definir valores. Ele avalia a expressão do lado direito e envia o resultado para a variável referenciada do lado esquerdo. Além de atribuir valores diretamente na declaração, você pode fazer isso em outra parte do código: + +```c +new letters; + +letters = 25; +``` + +### Escopos + +Só é possível modificar o valor de uma variável se a parte do código onde ela é usada estiver dentro do escopo dessa variável. O escopo depende do bloco ou da posição em que ela foi declarada. Por exemplo, uma variável declarada fora de qualquer bloco — geralmente no início do script — tem escopo global e pode ser acessada de qualquer parte do script: + +```c +#include + +new g_var = 5; + +public OnFilterScriptInit() +{ + g_var = 10; + + printf("The value is %i", g_var); + + return 1; +} + +public OnPlayerConnect(playerid) +{ + g_var = 100; + + printf("The value is %i", g_var); + + return 1; +} + +// Saída : +// The value is 10 +// The value is 100 + +// Observação: a segunda linha aparece apenas quando um jogador se conecta. +``` + +Além das variáveis globais, existem variáveis “locais” ou “privadas” que só podem ser acessadas dentro do bloco onde foram declaradas. + +```c +#include + +public OnFilterScriptInit() +{ + new localVar; + + localVar = 5; + + return 1; +} + +public OnPlayerConnect(playerid) +{ + localVar = 10; // Esta linha causará um erro na compilação + + return 1; +} +``` + +Se você compilar o código acima, o compilador exibirá um erro porque a variável local está sendo referenciada em outro bloco totalmente diferente. Observação: se for um bloco interno (aninhado), a variável pode ser acessada a partir dele. + +Outro ponto importante é que não é possível declarar variáveis com o mesmo nome se seus escopos se interceptam. Por exemplo, se já existir uma variável `score` em escopo global, você não pode criar outra `score` também global nem uma local com esse nome, e o inverso também vale (se já existir uma variável local, evite declarar uma global com o mesmo nome). + +```c +#include + +new g_score; + +public OnFilterScriptInit() +{ + new g_score = 5; // Esta linha causará um erro. + return 1; +} +``` + +### Regras de nomenclatura + +Agora que você sabe declarar variáveis, precisa conhecer as regras de nomes: + +- Todo nome deve começar com uma letra ou sublinhado (`_`). +- Depois do primeiro caractere, nomes podem conter letras e números, mas não espaços nem caracteres especiais. +- Os nomes diferenciam maiúsculas de minúsculas. +- Usar uma palavra reservada (keyword) como nome gera erro. + +#### Exemplos: + +```c +new new; // Incorreto: palavra reservada +new _new; // Correto + +new 10letters; // Incorreto: começa com número +new letters10; // Correto +new letters_10; // Correto + +new my name; // Incorreto: espaço no nome +new my_name; // Correto + +new !nternet; // Incorreto +new Internet; // Correto +``` + +### Armazenando diferentes tipos de dados + +Agora vejamos exemplos dos tipos de dados que podem ser armazenados e como fazer isso: + +```c +new letter = 'M'; + + +new value = 100; + + +new decimalValue = 1.0; +// Funciona, mas mostrará um aviso do compilador +// warning 213: tag mismatch + + +new engineOn = true; +// Funciona sem aviso, mas é recomendado usar uma Tag + + +new sentence = "This is a sentence"; +// Mostrará um erro. +// error 006: must be assigned to an array +``` + +Uma variável pode guardar um caractere, um inteiro, um booleano (true ou false) e um valor decimal (float). Os comentários acima mostram que tentar armazenar uma string em uma variável comum resulta em erro (strings só podem ser armazenadas em _arrays_). Além disso, atribuir um valor float sem tag gera um aviso do compilador, que pode ser evitado usando “tags”. Sem as tags corretas o script ainda compila, mas o aviso aparece. As tags dizem ao compilador qual tipo de dado deve ser guardado e, assim, ele consegue nos alertar com avisos ou erros quando fazemos algo que pode quebrar o programa. Exemplos: + +```c +new decimalValue = 1.0; // Incorreto +new bool:decimalValue = 1.0 // Incorreto +new Float:decimalValue = 1.0; // Correto + +new switchOn = 1.0; // Incorreto +new switchOn = true; // Incorreto, não mostra aviso +new bool:switchOn = true; // Correto +``` + +Usar as tags corretas é essencial para evitar bugs ou erros durante a execução. + +Como Pawn é uma linguagem sem tipos fixos, ele permite guardar tipos de dados diferentes na mesma variável. Isso pode ser útil em alguns casos e problemático em outros, portanto não é recomendado. + +```c +#include + +public OnFilterScriptInit() +{ + + new var; + + var = 'a'; + printf("%c", var); + + var = 1; + printf("%d", var); + + var = 1.0; + printf("%f", var); + + var = true; + printf("%d", var); // imprime 0 ou 1 + + return 1; +} + +// Saída : +a +1 +1.000000 +1 +``` diff --git a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/reference/00-Contents.md b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/reference/00-Contents.md new file mode 100644 index 00000000000..055eeea8d7e --- /dev/null +++ b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/reference/00-Contents.md @@ -0,0 +1,78 @@ +# PAWN + +![Pawn](https://i.ibb.co/SRbRt3C/pawn-icon-daddy-DOT-small.png) + +### linguagem de script embarcada + +##### Fevereiro de 2006 + +--- + +##### ITB CompuPhase + +##### ii + +--- + +“Java” é marca registrada da Sun Microsystems, Inc. + +“Microsoft” e “Microsoft Windows” são marcas registradas da Microsoft Corporation. + +“Linux” é marca registrada de Linus Torvalds. + +“CompuPhase” é marca registrada da ITB CompuPhase. + +“Unicode” é marca registrada da Unicode, Inc. + +Copyright © 1997–2006, ITB CompuPhase + +Eerste Industriestraat 19–21, 1401VL Bussum, Países Baixos +telefone: (+31)-(0)35 6939 261 + +e-mail: info@compuphase.com, http://www.compuphase.com + +As informações deste manual e o software associado são fornecidos “como estão”. Não há garantias, explícitas ou implícitas, sobre a exatidão do software e da documentação. + +Pedidos de correções e complementos ao manual ou ao software podem ser enviados para o endereço acima. + +Diagramado com TeX usando as fontes “Computer Modern” e “Palatino”, tamanho base de 11 pontos. + +--- + +# Sumário + +--- + +[Prefácio](01-Foreword) — páginas 3–5 + +[Introdução guiada](02-A-tutorial-introduction) — páginas 5–62 + +[Dados e declarações](03-Data-and-declarations) — páginas 62–70 + +[Funções](04-Functions) — páginas 70–93 + +[O pré-processador](05-The-preprocessor) — páginas 93–97 + +[Sintaxe geral](06-General-syntax) — páginas 97–104 + +[Operadores e expressões](07-Operators-and-expressions) — páginas 104–112 + +[Instruções](08-Statements) — páginas 112–117 + +[Diretivas](09-Directives) — páginas 117–124 + +[Biblioteca de funções proposta](10-Proposed-function-library) — páginas 124–134 + +[Armadilhas: diferenças em relação ao C](11-Pitfalls-differences-from-C) — páginas 134–137 + +[Dicas variadas](12-Assorted-tips) — páginas 137–148 + +[Apêndices](13-Appendices) — páginas 148–183 + +∟ [Mensagens de erro e aviso](13-Appendices#error-and-warning-messages) — páginas 148–168 + +∟ [O compilador](13-Appendices#the-compiler) — páginas 168–174 + +∟ [Justificativa](13-Appendices#rationale) — páginas 174–181 + +∟ [Licença](13-Appendices#license) — páginas 181–183 diff --git a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/reference/01-Foreword.md b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/reference/01-Foreword.md new file mode 100644 index 00000000000..30109b316b9 --- /dev/null +++ b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/reference/01-Foreword.md @@ -0,0 +1,29 @@ +# Prefácio + +--- + +“pawn” é uma linguagem de script simples, sem tipos e de 32 bits, com sintaxe parecida com C. Velocidade de execução, estabilidade, simplicidade e baixo consumo de recursos foram critérios essenciais tanto para a linguagem quanto para o interpretador/máquina abstrata que executa um programa pawn. + +Nenhuma aplicação ou ferramenta consegue fazer tudo para todos os usuários. Isso não apenas impulsiona novos sistemas, como explica a presença de opções extensas de configuração e linguagens de macro/script dentro de softwares. Nas minhas próprias aplicações sempre existiram “mini linguagens”: algumas extremamente simples, outras bem abrangentes... e, na maioria dos casos, as necessidades poderiam ser atendidas por uma linguagem de propósito geral acompanhada de uma biblioteca específica. Assim surgiu o pawn. + +A linguagem pawn foi desenhada para manipular objetos dentro de uma aplicação hospedeira. O conjunto de ferramentas (compilador e máquina abstrata) foi escrito para ser facilmente extensível e capaz de rodar em diferentes arquiteturas de software e hardware. + +## ♦ + +pawn descende do Small C original, de Ron Cain e James Hendrix, que por sua vez era um subconjunto de C. Algumas das modificações que fiz no Small C —como remover o sistema de tipos e substituir ponteiros por referências— foram tão profundas que já não era apropriado chamar minha linguagem de “subconjunto de C” ou “dialeto de C”. Por isso tirei o “C” do título e passei a publicar sobre a linguagem com o nome “Small” na revista Dr. Dobb’s Journal e nos anos seguintes. Durante o desenvolvimento e manutenção do produto recebi inúmeros pedidos de mudança; um dos mais frequentes era adotar outro nome, pois procurar por “small scripting language” na Internet era dificultado pelo termo “small” ser comum demais. A mudança de nome coincidiu com outra alteração importante da linguagem: o suporte a “estados” (e máquinas de estados). + +Sou grato a Ron Cain e James Hendrix (e, mais recentemente, Andy Yuen) e à revista Dr. Dobb’s Journal por terem colocado esse projeto em movimento. Embora eu tenha revisado praticamente todas as linhas do código original algumas vezes, as origens em Small C ainda são visíveis. + +## ♦ + +--- + +Um panorama detalhado dos objetivos de design e dos compromissos assumidos está no apêndice C; aqui faço um resumo de alguns pontos-chave. Como dito anteriormente, pawn serve para customizar aplicações (escrevendo scripts), não para escrever aplicações completas. Ele é modesto em termos de estrutura de dados porque os programas pawn existem para manipular objetos (texto, sprites, fluxos, consultas etc.) dentro da aplicação hospedeira, e esse programa, por design, não tem acesso direto a dados fora da sua máquina abstrata. A única forma de interagir com objetos na aplicação host é chamando sub-rotinas —as “funções nativas” expostas por ela. + +Pawn é flexível justamente nessa área crucial: a chamada de funções. Ele suporta valores padrão para **qualquer** argumento (não apenas o último), chamada por referência e por valor, e argumentos nomeados ou posicionais. Como é uma linguagem sem tipos, não possui verificação de tipos tradicional; em vez disso, oferece um mecanismo de “classificação” chamado “tags”. Esse sistema é especialmente útil em parâmetros de funções, pois cada argumento pode aceitar múltiplas tags. + +Creio que o ponto forte do pawn não está em um recurso isolado, e sim na combinação deles. Argumentos nomeados permitem especificar parâmetros em qualquer ordem; valores padrão possibilitam omitir os que não importam para o contexto. Juntos, criam uma forma prática e “descritiva” de chamar (funções nativas) para manipular objetos na aplicação hospedeira. + +--- + +[Voltar ao sumário](00-Contents) diff --git a/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/reference/02-A-tutorial-introduction.md b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/reference/02-A-tutorial-introduction.md new file mode 100644 index 00000000000..2917edaba9d --- /dev/null +++ b/frontend/i18n/pt-BR/docusaurus-plugin-content-docs/current/scripting/language/reference/02-A-tutorial-introduction.md @@ -0,0 +1,2265 @@ +# Introdução guiada + +--- + +Pawn é uma linguagem de programação simples cuja sintaxe lembra a da linguagem C. Um programa pawn é formado por um conjunto de funções e um conjunto de variáveis. As variáveis representam objetos de dados e as funções agrupam instruções (chamadas de _statements_) que operam sobre esses dados ou executam tarefas específicas. + +O primeiro programa demonstrado em praticamente qualquer linguagem costuma imprimir uma mensagem simples; o clássico é “Hello world”. Em pawn o programa fica assim: + +Listagem: hello.p + +```c + +main() + printf "Hello world\n" + +``` + +Este manual parte do princípio de que você já sabe executar um programa pawn; caso contrário, consulte o manual da aplicação (há mais dicas na página 168). + +A execução de um programa pawn começa em uma função de “entrada”∗ —neste manual, quase todos os exemplos usam a função `main` para esse papel. No exemplo acima, `main` contém apenas uma instrução, logo abaixo do cabeçalho da função. Quebras de linha e indentação não são significativas; poderíamos invocar `printf` na mesma linha do cabeçalho de `main`. + +A definição de uma função exige que o nome seja seguido por um par de parênteses. Se a função receber parâmetros, eles são declarados entre os parênteses. `main` não recebe nenhum parâmetro. Já as regras mudam quando chamamos uma função: os parênteses são opcionais na chamada de `printf`. + +O único argumento passado a `printf` é uma string, delimitada por aspas duplas. Os caracteres `\n` perto do final formam uma sequência de escape —nesse caso, representam a quebra de linha. Ao encontrar a sequência `\n`, `printf` move o cursor para a primeira coluna da próxima linha. +the next line. One has to use the \n escape sequence to insert a “newline” into +the string, because a string may not wrap over multiple lines. + +--- + +###### ∗ This should not be confused with the “state” entry functions, which are called entry, but serve a different purpose — see page 42. + +`Compiling and running scripts: see page 168` + +`String literals: 99 Escape sequence: 99` + +--- + +pawn is a “case sensitive” language: upper and lower case letters are considered +to be different letters. It would be an error to spell the function printf in the +acima como “PrintF”. Palavras-chave e símbolos pré-definidos, como o nome +da função `main`, devem ser escritos em minúsculas. + +Se você conhece C, talvez ache que o exemplo anterior não se parece muito +com o tradicional “Hello world” de C/C++. No entanto, pawn também pode +lembrar bastante C. O próximo exemplo é sintaxe válida em pawn (e tem a +mesma lógica do anterior): + +Listing: hello.p — C style + +```c + +#include + +main() +{ + printf("Hello world\n"); +} + +``` + +Esses primeiros exemplos já revelam algumas diferenças entre pawn e C: + +- normalmente não é necessário incluir arquivos de cabeçalho fornecidos pelo sistema; +- pontos e vírgulas são opcionais (exceto ao escrever várias instruções na mesma linha); +- quando o corpo de uma função tem apenas uma instrução, as chaves (que transformam em instrução composta) também são opcionais; +- se você não usa o resultado de uma função em uma expressão ou atribuição, os parênteses ao redor dos argumentos são opcionais. + +Esses itens referem-se a sintaxes opcionais —use o estilo que preferir; nenhum deles é “desaconselhado” ou “nocivo”. Os exemplos deste manual posicionam as chaves e usam uma indentação conhecida como “estilo Whitesmith”, mas pawn é uma linguagem de formato livre e qualquer estilo de recuo funciona. + +Como pawn foi projetado como linguagem de extensão de aplicações, o conjunto de funções disponível em um programa depende da aplicação hospedeira. Consequentemente, a linguagem não conhece nenhuma função intrinsecamente. A função `print`, usada nos primeiros exemplos, precisa ser fornecida pelo aplicativo host e “declarada” ao analisador de pawn. + +--- + +###### ∗ In the language specification, the term “parser” refers to any implementation that processes and runs on conforming Pawn programs —either interpreters or compilers. + +`More function descriptions at page 124` + +--- + +Pressupõe-se, porém, que toda aplicação hospedeira disponibilize um conjunto mínimo de funções comuns, como `print` e `printf`. + +Em alguns ambientes é necessário “habilitar” o display ou terminal antes de enviar texto. Se for o caso, chame a função `console` antes da primeira chamada a `print` ou `printf`. A função `console` também permite configurar características do dispositivo, como quantidade de linhas e colunas. Os programas deste manual não a utilizam porque muitas plataformas não exigem nem oferecem esse recurso. + +### • Arithmetic + +Os elementos fundamentais de grande parte dos programas são cálculos, decisões (execuções condicionais), iterações (loops) e variáveis para armazenar dados de entrada, saída e resultados intermediários. O próximo exemplo ilustra vários desses conceitos: ele calcula o máximo divisor comum de dois valores usando o algoritmo de Euclides. + +Listing: gcd.p + +```c + +/* the greatest common divisor of two values, using Euclides’ +algorithm */ + +main() +{ + print "Input two values\n" + new a = getvalue() + new b = getvalue() + while (a != b) + if (a > b) + a = a - b + else + b = b - a + printf "The greatest common divisor is %d\n", a +} + +``` + +Agora `main` contém mais do que uma única instrução `print`. Quando o corpo de uma função possui várias instruções, elas devem ficar dentro de chaves (`{` e `}`), formando uma instrução composta. O mesmo vale para os blocos de `if/else` e para os corpos de loops. + +A palavra-chave `new` cria uma variável; seu nome vem logo em seguida. É comum (mas não obrigatório) atribuir um valor inicial ao declarar a variável. + +`Compound statement: 112` + +`Data declarations are covered in detail starting at page 62` + +--- + +Variáveis devem ser declaradas antes de serem usadas em qualquer expressão. A função `getvalue` (também comum entre as funções pré-definidas) lê um valor do teclado e o retorna. Lembre-se de que pawn é uma linguagem sem tipos: toda variável é uma célula numérica capaz de armazenar um inteiro com sinal. + +O nome `getvalue` é seguido por parênteses porque o valor retornado é armazenado em uma variável. Normalmente os argumentos da função apareceriam entre os parênteses, mas `getvalue` (neste programa) não recebe parâmetros explícitos. Se você não atribuir o resultado de uma função a uma variável nem o usar em outra expressão, os parênteses são opcionais —como acontece com `print` e `printf`. Você pode mantê-los se preferir, mas não é necessário. + +Loop instructions, like “while”, repeat a single instruction as long as the loop +condition (the expression between parentheses) is “true”. One can +execute multiple instructions in a loop by grouping them in a compound statement. +The if–else instruction has one instruction for the “true” clause and one for the “false”. + +Observe that some statements, like while and if–else, contain (or +“fold around”) another instruction —in the case of if–else even two other instructions. +The complete bundle is, again, a single instruction. That is: + +- the assignment statements “a = a - b” below the if and “b = b - a” below the else are statements; + +- the if–else statement folds around these two assignment statements and forms a single statement of itself; + +- the while statement folds around the if–else statement and forms, again, a single statement. + +It is common to make the nesting of the statements explicit by indenting any +sub-statements below a statement in the source text. In the “Greatest Com- +mon Divisor” example, the left margin indent increases by four space characters +after the while statement, and again after the if and else keywords. State- +ments that belong to the same level, such as both printf invocations and the +while loop, have the same indentation. + +The loop condition for the while loop is “(a != b)”; the symbol != is the +“not equal to” operator. That is, the if–else instruction is repeated +until “a” equals “b”. It is good practice to indent the instructions that run under +control of another statement, as is done in the preceding example. + +--- + +The call to printf, near the bottom of the example, differs from the print call +right below the opening brace (“\{”). The “f” in printf stands for “formatted”, +which means that the function can format and print numeric values and other +data (in a user-specified format), as well as literal text. The %d symbol in the +string is a token that indicates the position and the format that the subsequent +argument to function printf should be printed. At run time, the token %d is +replaced by the value of variable “a” (the second argument of printf). + +A função `print` imprime apenas texto e é mais rápida do que `printf`. Se quiser exibir um caractere “%” literal, use `print` ou duplique o símbolo ao usar `printf`. Ou seja: + +`print "20% of the personnel accounts for 80% of the costs\n"` + +e + +`printf "20%% of the personnel accounts for 80%% of the costs\n"` + +produzem a mesma string. + +--- + +`"while" loop: 116` + +`"if else": 114` + +`Relational operators: 107` + +--- + +### • Arrays e constantes + +Além das variáveis simples de uma célula, pawn oferece “variáveis array” que armazenam diversos valores. O exemplo a seguir lista números primos usando o famoso “crivo de Eratóstenes”. Ele também apresenta outro conceito: constantes simbólicas, que se parecem com variáveis, mas não podem ser alteradas. + +Listing: sieve.p + +```c + +/* Print all primes below 100, using the "Sieve of Eratosthenes" */ + +main() +{ + const max_primes = 100 + new series[max_primes] = { true, ... } + for (new i = 2; i < max_primes; ++i) + if (series[i]) + { + printf "%d ", i + /* filter all multiples of this "prime" from the list */ + for (new j = 2 * i; j < max_primes; j += i) + series[j] = false + } +} + +``` + +--- + +Sempre que um programa (ou subprograma) tiver limites fixos, é boa prática criar constantes simbólicas para eles. No exemplo, `max_primes` vale 100 e é usada três vezes após a definição: na declaração do array `series` e nas duas estruturas `for`. Se quisermos adaptar o código para listar primos menores que 500, basta alterar uma linha. + +Assim como variáveis simples, arrays podem ser inicializados na criação. Pawn fornece um atalho para inicializar todos os elementos com o mesmo valor: os cem elementos de `series` recebem `true` —sem que seja necessário digitar a palavra cem vezes. Os símbolos `true` e `false` são constantes pré-definidas. + +Quando uma variável simples (como `i` e `j` na implementação do crivo) é declarada na primeira expressão de um laço `for`, ela existe apenas dentro do loop. Declaração de variável segue suas próprias regras; apesar da aparência, não é uma instrução comum. Uma dessas regras permite declarar uma variável na primeira expressão do `for`. + +Os dois `for` também apresentam novos operadores na terceira expressão: `++` incrementa seu operando em um; ou seja, `++i` equivale a `i = i + 1`. Já `+=` soma a expressão da direita ao valor da esquerda; `j += i` equivale a `j = j + i`. + +Trabalhando com arrays é preciso ficar atento ao problema clássico de “um a mais”: o primeiro elemento de `series` é `series[0]`, logo, se o array tem `max_primes` elementos, o último índice é `series[max_primes - 1]`. Se `max_primes` vale 100, o último elemento é `series[99]`; acessar `series[100]` é inválido. + +`Constant declaration: 101` + +`Progressive initiallers: 65` + +`"for" loop: 113` + +`An overview of all operators: 104` + +### • Funções + +Programas maiores costumam separar tarefas e operações em funções. Isso aumenta a modularidade e, quando bem escritas, elas podem ser reaproveitadas em outros projetos. O exemplo a seguir implementa uma função para calcular a sequência de Fibonacci. + +Essa série foi descrita por Leonardo “Fibonacci”, de Pisa, matemático italiano do século XIII famoso por popularizar os algarismos indo-arábicos no Ocidente. A sequência tinha como objetivo modelar o crescimento de uma população de coelhos idealizados, e segue 1, 1, 2, 3, 5, 8, 13, 21... —cada termo é a soma dos dois anteriores. + +Listing: fib.p + +```c + +/* Calculation of Fibonacci numbers by iteration */ + +main() +{ + print "Enter a value: " + new v = getvalue() + if (v > 0) + printf "The value of Fibonacci number %d is %d\n", v, fibonacci(v) + else + printf "The Fibonacci number %d does not exist\n", v +} +fibonacci(n) +{ + assert n > 0 + new a = 0, b = 1 + (new i = 2; i < n; i++) + { + new c = a + b + a = b + b = c + } + return a + b +} + +``` + +A instrução `assert` no início de `fibonacci` merece destaque: ela protege contra condições “impossíveis” ou inválidas. Números de Fibonacci negativos são inválidos, e `assert` sinaliza isso como erro de programação caso ocorra. Use `assert` apenas para erros do programador, nunca para erros de entrada do usuário. + +Implementar uma função definida pelo usuário se parece bastante com a função `main`. Em `fibonacci` vemos dois conceitos novos: ela recebe um valor por parâmetro e retorna um resultado. + +Os parâmetros são declarados no cabeçalho da função; aqui, há apenas `n`. Dentro da função, o parâmetro se comporta como uma variável local cujo valor foi passado do lado externo no momento da chamada. + +A instrução `return` encerra a função e estabelece o valor retornado. Ela não precisa aparecer apenas ao final; saídas antecipadas são permitidas. + +`"assert" statement: 112` + +`Funcitons: properties & features: 70` + +--- + +The main function of the Fibonacci example calls predefined “native” functions, +like getvalue and printf, as well as the user-defined function fibonacci. +From the perspective of calling a function (as in function main), there is no +difference between user-defined and native functions. + +The Fibonacci numbers sequence describes a surprising variety of natural phe- +nomena. For example, the two or three sets of spirals in pineapples, pine cones +and sunflowers usually have consecutive Fibonacci numbers between 5 and 89 +as their number of spirals. The numbers that occur naturally in branching +patterns (e.g. that of plants) are indeed Fibonacci numbers. Finally, although +the Fibonacci sequence is not a geometric sequence, the further the sequence +is extended, the more closely the ratio between successive terms approaches +the Golden Ratio, of 1.618. . . ∗ that appears so often in art and architecture. + +### • Call-by-reference & call-by-value + +Dates are a particularly rich source of algorithms and conversion routines, +because the calenders that a date refers to have known such a diversity, +through time and around the world. + +The “Julian Day Number” is attributed to Josephus Scaliger† and it counts +the number of days since November 24, 4714 BC (proleptic Gregorian cal- +endar‡). Scaliger chose that date because it marked the coincidence of three +well-established cycles: the 28-year Solar Cycle (of the old Julian calendar), +the 19-year Metonic Cycle and the 15-year Indiction Cycle (periodic taxes or gov- +ernmental requisitions in ancient Rome), and because no literature or recorded +history was known to predate that particular date in the remote past. Scaliger +used this concept to reconcile dates in historic documents, later astronomers +embraced it to calculate intervals between two events more easily. + +--- + +###### ∗ The exact value for the Golden Ratio is 1/2(√5 + 1). The relation between Fibonacci numbers and the Golden Ratio also allows for a “direct” calculation of any sequence number, instead of the iterative method described here. + +###### ∗ There is some debate on exactly what Josephus Scaliger invented and who or what he called it after. + +###### ∗ The Gregorian calendar was decreed to start on 15 October 1582 by pope Gregory XIII, which means that earlier dates do not really exist in the Gregorian calendar. When extending the Gregorian calendar to days before 15 October 1582, we refer to it as the proleptic Gregorian calendar. + +`Native function interface: 85` + +--- + +Julian Day numbers (sometimes denoted with unit “jd”) should not be con- +Aqui estamos falando de “Julian Day Numbers” (JDN), que não devem ser confundidos com “Julian Dates” (número de dias desde o início do ano) nem com o calendário juliano criado por Júlio César. + +O programa abaixo calcula o número de dias julianos a partir de uma data do calendário gregoriano (próleptico) e também faz o caminho inverso. Nesse calendário, o primeiro ano é 1 d.C. e o anterior é 1 a.C.; o ano zero **não** existe. Por isso, o programa considera anos negativos para datas a.C. e positivos (não zero) para anos d.C. + +Listing: julian.p + +```c + +/* calculate Julian Day number from a date, and vice versa */ + +main() +{ + new d, m, y, jdn + print "Give a date (dd-mm-yyyy): " + + d = getvalue(_, ’-’, ’/’) + m = getvalue(_, ’-’, ’/’) + y = getvalue() + jdn = DateToJulian(d, m, y) + + printf("Date %d/%d/%d = %d JD\n", d, m, y, jdn) + print "Give a Julian Day Number: " + + jdn = getvalue() + JulianToDate jdn, d, m, y + + printf "%d JD = %d/%d/%d\n", jdn, d, m, y +} + +DateToJulian(day, month, year) +{ + /* The first year is 1. Year 0 does not exist: it is 1 BC (or -1) */ + + assert year != 0 + if (year < 0) + year++ + + /* move January and February to the end of the previous year */ + + if (month <= 2) + year--, month += 12 + new jdn = 365*year + year/4 - year/100 + year/400 + + (153*month - 457) / 5 + + day + 1721119 + + return jdn +} + +JulianToDate(jdn, &day, &month, &year) +{ + jdn -= 1721119 + + /* approximate year, then adjust in a loop */ + + year = (400 * jdn) / 146097 + while (365*year + year/4 - year/100 + year/400 < jdn) + year++ + year-- + /* determine month */ + + jdn -= 365*year + year/4 - year/100 + year/400 + month = (5*jdn + 457) / 153 + + /* determine day */ + + day = jdn - (153*month - 457) / 5 + + /* move January and February to start of the year */ + + if (month > 12) + month -= 12, year++ + + /* adjust negative years (year 0 must become 1 BC, or -1) */ + + if (year <= 0) + year-- +} + +``` + +--- + +`main` começa criando variáveis para armazenar dia, mês, ano e o JDN calculado. Em seguida lê a data (três chamadas a `getvalue`) e chama `DateToJulian` para obter o número. Depois de calcular, imprime a data digitada e o JDN correspondente. Foquemos agora em `DateToJulian`. + +Logo no início, a função incrementa o ano caso ele seja negativo —isso serve para lidar com a ausência do ano zero no calendário gregoriano próleptico. Em outras palavras, `DateToJulian` modifica os argumentos recebidos (mais tarde, altera também `month`). Dentro da função, o argumento se comporta como variável local e pode ser alterado; contudo, essas mudanças são locais a `DateToJulian`. A função `main` passa `d`, `m` e `y`, que são mapeados para `day`, `month` e `year`. Embora `DateToJulian` modifique `year` e `month`, ela não altera `y` e `m` em `main`, apenas suas cópias locais. Esse conceito é conhecido como “passagem por valor”. + +O exemplo usa nomes diferentes para as variáveis locais de `main` e `DateToJulian` justamente para tornar a explicação mais clara. Se renomearmos `d`, `m` e `y` para `day`, `month` e `year`, a situação continua a mesma: haverá dois conjuntos de variáveis com esses nomes —algo perfeitamente válido em pawn. + +`"Call by value" versus "Call by reference": 71` + +--- + +O restante de `DateToJulian` é aritmética pura, sem novidades para a linguagem. + +Voltando ao segundo trecho de `main`, vemos que agora ele solicita um número juliano e chama `JulianToDate` para encontrar a data correspondente. Essa função é interessante porque recebe um único argumento (o JDN) e precisa produzir três valores: dia, mês e ano. Mas uma função só pode retornar um valor —um `return` contém apenas uma expressão. Para resolver isso, `JulianToDate` pede explicitamente que as alterações feitas em alguns argumentos sejam copiadas de volta para as variáveis do chamador. Assim, em `main`, as variáveis que devem receber o resultado são passadas como argumentos. + +`JulianToDate` marca os argumentos que devem ser “copiados de volta” com o prefixo `&`. Argumentos com `&` são tratados de forma especial: em vez de passar apenas o valor, a função recebe acesso direto à variável original. Isso se chama “passagem por referência”, e o argumento se torna uma “referência”. + +Em outras palavras, se `main` passa `y` e `JulianToDate` o mapeia para `year`, qualquer alteração feita em `year` refletirá em `y`. Somente por meio de argumentos por referência uma função pode modificar diretamente uma variável declarada em outra função. + +Resumindo: se uma função retorna apenas um valor, use o `return`; se precisa retornar vários, use argumentos por referência. Ambos podem coexistir na mesma função —por exemplo, retornar o resultado principal via referência e um código de erro no `return`. + +Observação: muitas aplicações desktop usam conversões para e a partir de números julianos (ou variantes) para calcular intervalos entre datas ou descobrir a data exata daqui a 90 dias, por exemplo. + +### • Números racionais + +Até aqui lidamos apenas com números inteiros. Pawn também pode trabalhar com valores fracionários, chamados de “números racionais”, mas o suporte depende da aplicação hospedeira. + +Os racionais podem ser implementados como números de ponto flutuante ou de ponto fixo. Ponto flutuante é comum em cálculos gerais e científicos; ponto fixo é indicado para aplicações financeiras ou quando os erros de arredondamento devem ser inexistentes (ou, ao menos, previsíveis). O kit de ferramentas do pawn inclui módulos para ambos, com detalhes e compromissos explicados na documentação específica. Entretanto, o aplicativo host pode oferecer apenas um dos formatos, os dois ou nenhum∗. O programa abaixo exige que haja suporte a pelo menos um tipo de racional; caso contrário, ele não executa. + +Listing: c2f.p + +```c + +main() +{ + new Rational: Celsius + new Rational: Fahrenheit + print "Celsius\t Fahrenheit\n" + for (Celsius = 5; Celsius <= 25; Celsius++) + { + Fahrenheit = (Celsius * 1.8) + 32 + printf "%r \t %r\n", Celsius, Fahrenheit + } +} + +``` + +O programa converte uma tabela de graus Celsius para Fahrenheit. A primeira diretiva importa as definições necessárias para trabalhar com racionais. O arquivo `rational` carrega suporte a ponto flutuante ou ponto fixo, conforme o disponível. + +As variáveis `Celsius` e `Fahrenheit` são declaradas com a tag `Rational:` entre `new` e o nome da variável. Tags indicam a finalidade da variável, o uso permitido e, no caso específico de racionais, sua representação em memória. + +--- + +###### ∗ Actually, this is already true of all native functions, including all native functions that the examples in this manual use. + +`Tag names: 68` + +--- + +The Rational: tag tells the pawn parser that the variables Celsius and Fahrenheit +contain fractional values, rather than whole numbers. + +The equation for obtaining degrees Fahrenheit from degrees Celsius is + +°F = ⁹⁄₅ + 32 °C + +The program uses the value 1.8 for the quotient 9/₅. When rational number +support is enabled, pawn supports values with a fractional part behind +the decimal point. + +The only other non-trivial change from earlier programs is that the format +string for the printf function now has variable placeholders denoted with +“%r” instead of “%d”. The placeholder %r prints a rational number at +the position; %d is only for integers (“whole numbers”). + +I used the include file “rational” rather than “float” or “fixed” in an +attempt to make the example program portable. If you know that the host +application supports floating point arithmetic, it may be more convenient to +“#include” the definitions from the file float and use the tag Float: instead +of Rational —when doing so, you should also replace %r by %f in the call to +printf. For details on fixed point and floating point support, please see the +application notes “Fixed Point Support Library” and “Floating Point Support +Library” that are available separately. + +### • Strings + +pawn has no intrinsic “string” type; character strings are stored in arrays, with +the convention that the array element behind the last valid character is zero. +Working with strings is therefore equivalent with working with arrays. + +Among the simplest of encryption schemes is the one called “ROT13” — +actually the algorithm is quite “weak” from a cryptographical point of view. It +is most widely used in public electronic forums (BBSes, Usenet) to hide texts +from casual reading, such as the solution to puzzles or riddles. ROT13 simply +“rotates” the alphabet by half its length, i.e. 13 characters. It is a symmetric +operation: applying it twice on the same text reveals the original. + +--- + +Listing: rot13.p + +```c + +/* Simple encryption, using ROT13 */ + +main() +{ + printf "Please type the string to mangle: " + + new str[100] + getstring str, sizeof str + rot13 str + + printf "After mangling, the string is: \"%s\"\n", str +} + +rot13(string[]) +{ + for (new index = 0; string[index]; index++) + if (’a’ <= string[index] <= ’z’) + string[index] = (string[index] - ’a’ + 13) % 26 + ’a’ + else if (’A’ <= string[index] <= ’Z’) + string[index] = (string[index] - ’A’ + 13) % 26 + ’A’ +} + +``` + +No cabeçalho de `rot13`, o parâmetro `string` é declarado como array, mas sem tamanho —não há valor entre colchetes. Quando um tamanho é especificado no cabeçalho, ele precisa coincidir com o tamanho do argumento passado na chamada. Ao omitir, removemos essa restrição e permitimos que a função opere sobre arrays de qualquer comprimento. É preciso, então, ter outra forma de descobrir o tamanho (máximo). Para strings, basta procurar pelo terminador zero. + +O `for` que percorre a string é típico em rotinas de processamento de texto. Repare que a condição é `string[index]`. Em pawn, qualquer valor diferente de zero é considerado “true”; valores iguais a zero são “false”. Assim, quando `string[index]` chega a zero, o loop termina. + +O algoritmo ROT13 rotaciona apenas letras; dígitos, pontuação e caracteres especiais permanecem intactos. Além disso, maiúsculas e minúsculas são tratados separadamente. Dentro do loop, dois `if` filtram os caracteres relevantes. O encadeamento do segundo `if` no `else` do primeiro é um padrão comum para testar várias condições mutuamente exclusivas. + +No início deste capítulo falamos sobre passagem por valor e por referência. No caso de strings (ou arrays em geral), lembre-se de que pawn sempre passa arrays por referência. Isso economiza memória e melhora o desempenho, já que copiar uma estrutura grande apenas para passá-la por valor consumiria tempo e memória adicionais. + +--- + +`A function that takes an array as an argument and that does not change it, may mark the argument as “const”; see page 72` + +Por causa dessa regra, `rot13` pode modificar o parâmetro `string` sem precisar declará-lo explicitamente como argumento por referência. + +Outro ponto interessante são as condições dos `if`. A primeira usa `’a’ <= string[index] <= ’z’`, expressão verdadeira se, e somente se, `’a’ <= string[index]` **e** `string[index] <= ’z’`. Esse encadeamento de operadores relacionais é comum para expressar múltiplas comparações em uma única condição. + +Por fim, repare como o último `printf` em `main` usa `\"` para imprimir aspas duplas. Normalmente esse caractere encerraria a string literal; a sequência de escape insere a aspa no texto. + +Ainda falando de strings e arrays, o próximo programa divide uma frase em palavras e contabiliza quantas são. É um exemplo simples que apresenta alguns recursos novos da linguagem. + +Listing: wcount.p + +```c + +/* word count: count words on a string that the user types */ + +main() +{ + print "Please type a string: " + new string[100] + getstring string, sizeof string + + new count = 0 + + new word[20] + new index + for ( ;; ) + { + word = strtok(string, index) + if (strlen(word) == 0) + break + count++ + printf "Word %d: ’%s’\n", count, word + } + printf "\nNumber of words: %d\n", count +} + +strtok(const string[], &index) +{ + new length = strlen(string) + + /* skip leading white space */ + while (index < length && string[index] <= ’ ’) + index++ + /* store the word letter for letter */ + new offset = index /* save start position of token */ + new result[20] /* string to store the word in */ + while (index < length + && string[index] > ’ ’ + && index - offset < sizeof result - 1) + { + result[index - offset] = string[index] + index++ + } + result[index - offset] = EOS /* zero-terminate the string */ + return result +} + +``` + +--- + +`Relational operators: 107` + +`Escape sequence: 99` + +`main` primeiro mostra uma mensagem e lê a string digitada. Depois entra em um loop: escrever `for (;;)` cria um laço sem inicialização, incremento ou teste —um loop infinito, equivalente a `while (true)`. A diferença é que o analisador de pawn gera um aviso para `while (true)` (“expressão redundante; sempre verdadeira”), mas `for (;;)` passa sem alertas. + +Loops infinitos são úteis quando precisamos de um teste no meio —um híbrido entre `while` e `do...while`. Pawn não tem essa construção diretamente, mas podemos simulá-la com um loop infinito e um `break` condicional. No exemplo: + +- a palavra é extraída da string (código antes do teste); +- verificamos se há uma nova palavra; se não houver, saímos do loop (teste no meio); +- imprimimos a palavra e sua posição (código depois do teste). + +A linha `word = strtok(string, index)` (junto com a declaração de `word`) mostra que pawn permite atribuir arrays e retornar arrays de funções. O analisador verifica se o array retornado por `strtok` tem o mesmo tamanho/dimensão da variável que o recebe. + +`strlen` é uma função nativa; `strtok` não e precisa ser implementada. Ela foi inspirada na homônima de C/C++, mas não modifica a string original: em vez disso, copia palavra por palavra para um array local, que é retornado no final. + +--- + +### • Arrays e enumerações (dados estruturados) + +Em uma linguagem sem tipos, podemos atribuir funções diferentes a elementos específicos de um mesmo array. Pawn suporta constantes enumeradas com uma extensão que simula parte da funcionalidade das “structs” ou “records” de outras linguagens. + +O exemplo a seguir é maior do que os anteriores e demonstra outros recursos, como variáveis globais e parâmetros nomeados. + +```c + +/* Priority queue (for simple text strings) */ + +enum message +{ + text[40 char], + priority +} + +main() +{ + new msg[message] + + /* insert a few items (read from console input) */ + + printf "Please insert a few messages and their priorities; \ + end with an empty string\n" + for ( ;; ) + { + printf "Message: " + getstring .string = msg[text], .maxlength = 40, .pack = true + if (strlen(msg[text]) == 0) + break + printf "Priority: " + msg[priority] = getvalue() + if (!insert(msg)) + { + printf "Queue is full, cannot insert more items\n" + break + } + } + /* now print the messages extracted from the queue */ + printf "\nContents of the queue:\n" + while (extract(msg)) + printf "[%d] %s\n", msg[priority], msg[text] +} + +const queuesize = 10 +new queue[queuesize][message] +new queueitems = 0 +insert(const item[message]) +{ + /* check if the queue can hold one more message */ + if (queueitems == queuesize) + return false /* queue is full */ + + /* find the position to insert it to */ + new pos = queueitems /* start at the bottom */ + while (pos > 0 && item[priority] > queue[pos-1][priority]) + --pos /* higher priority: move one position up */ + + /* make place for the item at the insertion spot */ + for (new i = queueitems; i > pos; --i) + queue[i] = queue[i-1] + + /* add the message to the correct slot */ + queue[pos] = item + queueitems++ + + return true +} + +extract(item[message]) +{ + /* check whether the queue has one more message */ + if (queueitems == 0) + return false /* queue is empty */ + + /* copy the topmost item */ + item = queue[0] + --queueitems + + /* move the queue one position up */ + for (new i = 0; i < queueitems; ++i) + queue[i] = queue[i+1] + + return true +} + +``` + +--- + +`"for" loop: 113` + +`"enum" statement: 101` + +`"char" operator: 110` + +Near the top of the program listing is the declaration of the enumeration mes- +sage. This enumeration defines two constants: text, which is zero, and pri- +ority, which is 11 (assuming a 32-bit cell). The idea behind an enumeration +is to quickly define a list of symbolic constants without duplicates. By +default, every constant in the list is 1 higher than its predecessor and the very +first constant in the list is zero. However, you may give an extra increment for a +constant so that the successor has a value of 1 plus that extra increment. The + +text constant specifies an extra increment of 40 char. In pawn, char is an +operator, it returns the number of cells needed to +hold a packed string of the + +specified number of characters. Assuming a 32-bit cell and a 8-bit character, +10 cells can hold 40 packed characters. + +Immediately at the top of function main, a new array variable is declared with +the size of message. The symbol message is the name of the enumeration. It +is also a constant with the value of the last constant in the enumeration list +plus the optional extra increment for that last element. So in this example, +message is 12. That is to say, array msg is declared to hold 12 cells. + +Further in main are two loops. The for loop reads strings and priority values +from the console and inserts them in a queue. The while loop below +that +extracts element by element from the queue and prints the information on the +screen. The point to note, is that the for loop stores both the string and the +priority number (an integer) in the same variable msg; indeed, function main +declares only a single variable. Function getstring stores the message text +that you type starting at array msg[text] while the priority value is stored +(by an assignment a few lines lower) in msg[priority]. The printf function +in the while loop reads the string and the value from those positions as well. + +At the same time, the msg array is an entity on itself: it is passed in its +entirety +to function insert. That function, near the end, says “queue[queueitems] + += item”, where item is an array with size message and queue is a +two- +dimensional array that holds queuesize elements of size message. The decla- +ration of queue and queuesize are just above function insert. + +The example implements a “priority queue”. You can insert a number +of +messages into the queue and when these messages all have the same priority, +they are extracted from the queue in the same order. However, when +the +messages have different priorities, the one with the highest priority comes out +first. The “intelligence” for this operation is inside function insert: it +first +determines the position of the new message to add, then moves a few messages +one position upward to make space for the new message. Function extract +simply always retrieves the first element of the queue and shifts all remaining +elements down by one position. + +Note that both functions insert and extract work on two shared variables, +queue and queueitems. A variable that is declared inside a function, +like +variable msg in function main can only be accessed from within that function. +A “global variable” is accessible by all functions, and that variable is +declared +outside the scope of any function. Variables must still be declared before they +are used, so main cannot access variables queue and queueitems, but both +insert and extract can. + +--- + +Function extract returns the messages with the highest priority via its func- +tion argument item. That is, it changes its function argument by copying the +first element of the queue array into item. Function insert copies in the other +direction and it does not change its function argument item. In such a case, +it is advised to mark the function argument as “const”. This helps the pawn +parser to both check for errors and to generate better (more compact, quicker) code. + +A final remark on this latest sample is the call to getstring in function main: +note how the parameters are attributed with a description. The first param- +eter is labeled “.string”, the second “.maxlength” and the third “.pack”. +Function getstring receives “named parameters” rather than positional pa- +rameters. The order in which named parameters are listed is not important. +Named parameters are convenient in specifying —and deciphering— long pa- +rameter lists. + +--- + +`Named parameters: 74` + +### • Bit operations to manipulate ‘‘sets’’ + +A few algorithms are most easily solved with “set operations”, like +intersection, +union and inversion. In the figure below, for example, we want to design an +algorithm that returns us the points that can be reached from some other point +in a specified maximum number of steps. For example, if we ask it to +return the points that can be reached in two steps starting from B, the algorithm has +to return C, D, E and F, but not G because G takes three steps from B. + +Our approach is to keep, for each point in the graph, the set of other points +that it can reach in one step —this is the “next_step” set. We +also have a “result” set that keeps all points that we have found so far. We start by +setting the result set equal to the next_step set for the departure point. Now +we have in the result set all points that one can reach in one step. Then, for +every point in our result set, we create a union of the result set and the +next_step set for that point. This process is iterated for a specified number of loops. + +--- + +An example may clarify the procedure outlined above. When the departure +point is B, we start by setting the result set to D and E —these are the +points that one can reach from B in one step. Then, we walk through +the result set. The first point that we encounter in the set is D, and we check +what points can be reached from D in one step: these are C and F. So we add +C and F to the result set. We knew that the points that can be reached from +D in one step are C and F, because C and F are in the next_step set for + +D. So what we do is to merge the next_step set for point D into the result +set. The merge is called a “union” in set theory. That handles D. The original +result set also contained point E, but the next_step set for E is empty, so +no more point is added. The new result set therefore now contains C, D, E and F. + +![img](https://i.ibb.co/m9Dq7x2/image.png) + +A set is a general purpose container for elements. The only information that +a set holds of an element is whether it is present in the set or not. The order +of elements in a set is insignificant and a set cannot contain the same element + +multiple times. The pawn language does not provide a “set” data type or +operators that work on sets. However, sets with up to 32 elements can be +simulated by bit operations. It takes just one bit to store a “present/absent” +status and a 32-bit cell can therefore maintain the status for 32 set elements +—provided that each element is assigned a unique bit position. + +The relation between set operations and bitwise operations is summarized in +the following table. In the table, an upper case letter stands for a set and a +lower case letter for an element from that set. + +| concept | mathematical notation | pawn expression | +| ------------ | --------------------- | --------------- | +| intersection | A ∩ B | A & B | +| union | A ∪ B | A I B | +| complement | A | ~A | +| empty set | ε | 0 | +| membership | x ∈ A | (1 \<< x ) & A | + +--- + +To test for membership —that is, to query whether a set holds a particular +element, create a set with just one element and take the intersection. If the +result is 0 (the empty set) the element is not in the set. Bit numbering starts +typically at zero; the lowest bit is bit 0 and the highest bit in a 32-bit cell +is bit 31. To make a cell with only bit 7 set, shift the value 1 left by seven +—or in a pawn expression: “1 \<< 7”. + +Below is the program that implements the algorithm described earlier to find +all points that can be reached from a specific departure in a given number of +steps. The algorithm is completely in the findtargets function. + +Listing: set.p + +```c + +/* Set operations, using bit arithmetic */ + +main() +{ + enum (<<= 1) { A = 1, B, C, D, E, F, G } + new nextstep[] = + + { C | E, /* A can reach C and E */ + D | E, /* B " " D and E */ + G, /* C " " G */ + C | F, /* D " " C and F */ + 0, /* E " " none */ + 0, /* F " " none */ + E | F, /* G " " E and F */ + } + #pragma unused A, B + + print "The departure point: " + new source = clamp( .value = toupper(getchar()) - ’A’, + .min = 0, + .max = sizeof nextstep - 1 + ) + print "\nThe number of steps: " + new steps = getvalue() + + /* make the set */ + new result = findtargets(source, steps, nextstep) + printf "The points reachable from %c in %d steps: ", source+’A’, + steps + for (new i = 0; i < sizeof nextstep; i++) + if (result & 1 << i) + printf "%c ", i + ’A’ +} + +findtargets(source, steps, nextstep[], numpoints = sizeof nextstep) +{ + new result = 0 + new addedpoints = nextstep[source] + while (steps-- > 0 && result != addedpoints) + { + result = addedpoints + for (new i = 0; i < numpoints; i++) + if (result & 1 << i) + addedpoints |= nextstep[i] + } + return result +} + +``` + +--- + +The enum statement just below the header of the main function declares the +constants for the nodes A to G, but with a twist. Usually, the enum starts +counting from zero; here, the value of the first constant, A, is explicitly set to + +1. More noteworthy is the expression “(\<\<= 1)” between the enum keyword + and the opening brace that starts the constant list: it specifies a “bit + shifting” increment. By default, every constant in an enum list gets a value that is + 1 above its predecessor, but you can specify every successive constant + in an enumeration to have a value that is: + +_its predecessor incremented by any value (not just 1) —e.g., “(+= 5)”;_ + +_its predecessor multiplied by any value —e.g., “(_= 3)”;\_ + +_its predecessor bit-shifted to the left by any value —e.g., “(\<\<= 1)”;_ + +Note that, in binary arithmetic, shifting left by one bit amounts to the same +as multiplying by two, meaning that `(/*= 2)` and `(<<= 1)` do the same thing. + +When working with sets, a typical task that pops up is to determine the number +of elements in the set. A straightforward function that does this is below: + +Listing: simple bitcount function + +```c + +bitcount(set) +{ + new count = 0 + for (new i = 0; i < cellbits; i++) + if (set & (1 << i)) + count++ + return count +} + +``` + +With a cell size of 32 bits, this function’s loop iterates 32 times to check for +a single bit at each iteration. With a bit of binary arithmetic magic, we can +reduce it to loop only for the number of bits that are “set”. +That is, the following function iterates only once if the input value has only one bit set: + +Listing: improved bitcount function + +```c + +bitcount(set) +{ + new count = 0 + if (set) + do + count++ + while ((set = set & (set - 1))) + return count +} + +``` + +--- + +`“enum” statement: 101` + +`“cellbits” constant: 102` + +--- + +### • A simple RPN calculator + +The common mathematical notation, with expressions like “26 3 (5 + 2)”, +is known as the algebraic notation. It is a compact notation and +we have +grown accustomed to it. pawn and by far most other programming languages +use the algebraic notation for their programming expressions. The algebraic + +notation does have a few disadvantages, though. For instance, it occasionally +exige que deixemos explícita a ordem das operações com parênteses. A expressão no início desta seção poderia ser reescrita sem parênteses, mas à custa de quase dobrar o tamanho. Na prática, complementamos a notação algébrica com regras de precedência que dizem, por exemplo, que multiplicação vem antes de adição e subtração.∗ Essas regras reduzem muito a necessidade de parênteses, mas não a eliminam. Pior: quando o número de operadores cresce, lembrar a hierarquia de precedência e o nível de cada operador torna-se difícil —motivo pelo qual linguagens ricas em operadores, como APL, abandonam precedência e usam outra abordagem. + +Por volta de 1920, o matemático polonês Jan Łukasiewicz demonstrou que, colocando os operadores antes dos operandos em vez de entre eles, a precedência se tornava redundante e parênteses deixavam de ser necessários. Essa notação ficou conhecida como “notação polonesa”.† Mais tarde, Charles Hamblin sugeriu posicionar os operadores **após** os operandos, resultando na “notação polonesa reversa” (RPN). + +--- + +###### ∗ These rules are often summarized in a mnemonic like “Please Excuse My Dear Aunt Sally” (Parentheses, Exponentiation, Multiplication, Division, Addition, Subtraction) + +###### \* Polish Notation is completely unrelated to “Hungarian Notation” —which is just the habit of adding “type” or “purpose” identification warts to names of variables or functions + +--- + +`Algebraic notation is also called “infix” notation` + +`Reverse Polish Notation is also called “postfix” notation` + +--- + +O benefício dessa inversão é que os operadores aparecem na mesma ordem em que devem ser executados: ao lê-los da esquerda para a direita, realizamos as operações na mesma sequência. A expressão algébrica desta seção ficaria, em RPN: + +`26 3 5 2 + × −` + +Observando apenas os operadores, temos: primeiro uma soma, depois uma multiplicação e, por fim, uma subtração. Os operandos de cada operador são lidos da direita para a esquerda: os operandos de `+` são 5 e 2; os de `×` são o resultado da soma anterior e o valor 3; e assim por diante. + +É útil imaginar os valores sendo empilhados, com os operadores removendo um ou mais elementos do topo, efetuando a operação e devolvendo o resultado no topo. Ao percorrer a expressão em RPN, empilhamos 26, 3, 5 e 2 nessa ordem. O operador `+` remove 5 e 2 e empilha a soma, resultando em “26 3 7”. O operador `×` remove 3 e 7 e empilha o produto, deixando “26 21”. Por fim, o operador `−` subtrai 21 de 26 e empilha o valor único 5 —resultado final da expressão. + +RPN se popularizou porque é fácil de entender e de implementar (especialmente em calculadoras antigas). Ela também abre espaço para operadores com mais de dois operandos (como integrações) ou com mais de um resultado (como conversões entre coordenadas polares e cartesianas). + +Segue o programa principal de uma calculadora em notação polonesa reversa: + +Listing: rpn.p + +```c + +/* a simple RPN calculator */ +#include strtok +#include stack +#include rpnparse + +main() +{ + print "Type an expression in Reverse Polish Notation: " + new string[100] + getstring string, sizeof string + rpncalc string +} + +``` + +--- + +O programa principal em si é bem curto; ele apenas inclui o código de três arquivos auxiliares, cada um responsável por algumas funções que, combinadas, implementam a calculadora. Em programas maiores é comum distribuir a lógica em vários arquivos para facilitar a manutenção. + +`main` mostra um prompt e chama a nativa `getstring` para ler a expressão. Em seguida, invoca `rpncalc`, que faz o trabalho pesado. A implementação de `rpncalc` está em `rpnparse.inc`, reproduzida abaixo: + +Listing: rpnparse.inc + +````c + +/* main rpn parser and lexical analysis, part of the RPN calculator */ +#include +#include + +enum token +{ + t_type, /* operator or token type */ + Rational: t_value, /* value, if t_type is "Number" */ + t_word[20], /* raw string */ + +} + +const Number = ’0’ +const EndOfExpr = ’#’ + +rpncalc(const string[]) +{ + new index + new field[token] + for ( ;; ) + { + field = gettoken(string, index) + switch (field[t_type]) + { + case Number: + push field[t_value] + case ’+’: + push pop() + pop() + case ’-’: + push - pop() + pop() + case ’*’: + push pop() * pop() + case ’/’, ’:’: + push 1.0 / pop() * pop() + case EndOfExpr: + break /* exit "for" loop */ + default: + printf "Unknown operator ’%s’\n", field[t_word] + } + } + printf "Result = %r\n", pop() + if (clearstack()) + print "Stack not empty\n", red +} + +gettoken(const string[], &index) +{ + /* first get the next "word" from the string */ + new word[20] + word = strtok(string, index) + + /* then parse it */ + new field[token] + field[t_word] = word + if (strlen(word) == 0) + { + field[t_type] = EndOfExpr /* special "stop" symbol */ + field[t_value] = 0 + } + else if (’0’ <= word[0] <= ’9’) + { + field[t_type] = Number + field[t_value] = rationalstr(word) + } + else + { + field[t_type] = word[0] + field[t_value] = 0 + } + return field + +} + +```*** + +Essa calculadora usa suporte a números racionais, por isso `rpnparse.inc` inclui o arquivo `rational`. Quase todas as operações envolvendo racionais ficam escondidas na aritmética; as únicas referências diretas são o especificador de formato `%r` no `printf` ao final de `rpncalc` e a chamada `rationalstr` dentro de `gettoken`. + +O primeiro ponto curioso em `rpnparse.inc` é a declaração `enum`, na qual um elemento recebe uma tag (`t_value`) e outro define um tamanho (`t_word`). A função `rpncalc` declara a variável `field` como um array cujo tamanho é o símbolo dessa enumeração. Na prática, isso faz mais do que criar um array de 22 células: + +- O “índice” do array passa a ter a tag `token:`. Isso permite indexá-lo usando qualquer elemento da enumeração, mas impede o uso de valores com outras tags. Em outras palavras, `field[t_type]` é válido, enquanto `field[1]` gera diagnóstico. +- A tag da enumeração prevalece sobre a eventual tag do array. `field` em si não tem tag, mas `field[t_value]` recebe `Rational:`, já que o elemento `t_value` foi declarado assim. Isso permite criar arrays cujos elementos têm tags diferentes entre si. +- Quando um elemento da enumeração define um tamanho, a posição correspondente no array passa a ser tratada como um subarray. Em `rpncalc`, `field[t_type]` é uma célula, `field[t_value]` é outra, mas `field[t_word]` é um array unidimensional com 20 células. É por isso que a linha + + printf "Unknown operator ’%s’\n", field[t_word] + +where the format code %s expects a string —a zero-terminated array. + + + + + +`Rational numbers, see also the “Celsius to Fahrenheit” example on page page 16` + +`“enum” statement: 101` + +`Another example of an index tag: page 68` + + + +// came to here + + + + +*** + +If you know C/C⁺⁺ or Java, you may want to look at the switch statement. +The switch statement differs in a number of ways from the other languages +that provide it. The cases are not fall-through, for example, which in +turn means that the break statement for the case EndOfExpr breaks out of the +enclosing loop, instead of out of the switch. + +On the top of the for loop in function rpncalc, you will find the +instruction “field = gettoken(string, index)”. As already exemplified in the +wcount.p (“word count”) program on page 19, functions may return arrays. +It gets more interesting for a similar line in function gettoken: + +field[t_word] = word + +where word is an array of 20 cells and field is an array of 22 cells. +However, as the t_word enumeration field is declared as having a size of 20 cells, +“field[t_word]” is considered a sub-array of 20 cells, precisely matching the +array size of word. + +Listing: strtok.inc + +```c + +/* extract words from a string (words must be separated by white space) */ +#include + +strtok(const string[], &index) +{ + new length = strlen(string) + + /* skip leading white space */ + while (index < length && string[index] <= ’ ’) + index++ + + /* store the word letter for letter */ + new offset = index /* save start position of token */ + new result[20] /* string to store the word in */ + while (index < length + && string[index] > ’ ’ + && index - offset < sizeof result - 1) + { + result[index - offset] = string[index] + index++ + } + result[index - offset] = EOS /* zero-terminate the string */ + + return result +} + +```` + +--- + +`“switch” statement: page 115` + +--- + +Function strtok is the same as the one used in the wcount.p example. It is +implemented in a separate file for the rpn calculator program. Note that the +strtok function as it is implemented here can only handle words with up to 19 + +characters —the 20th character is the zero terminator. A truly general purpose +re-usable implementation of an strtok function would pass the destination +array as a parameter, so that it could handle words of any size. Supporting +both packed and unpack strings would also be a useful feature of a +general purpose function. + +When discussing the merits of Reverse Polish Notation, I mentioned that a +stack is both an aid in “visualizing” the algorithm as well as a +convenient method to implement an rpn parser. This example rpn calculator, uses +a stack with the ubiquitous functions push and pop. For error checking +and resetting the stack, there is a third function that clears the stack. + +Listing: stack.inc + +```c + +/* stack functions, part of the RPN calculator */ +#include + +static Rational: stack[50] +static stackidx = 0 + +push(Rational: value) +{ + assert stackidx < sizeof stack + stack[stackidx++] = value +} + +Rational: pop() +{ + assert stackidx > 0 + return stack[--stackidx] +} + +clearstack() +{ + assert stackidx >= 0 + if (stackidx == 0) + return false + stackidx = 0 + return true +} + +``` + +--- + +`wcount.p: page 19` + +--- + +The file stack.inc includes the file rational again. This is technically not +necessary (rpnparse.inc already included the definitions for rational number +support), but it does not do any harm either and, for the sake of code re-use, +it is better to make any file include the definitions of the libraries that it +depends on. + +Notice how the two global variables stack and stackidx are declared +as “static” variables; using the keyword static instead of new. Doing this makes +the global variables “visible” in that file only. For all other files in a +larger project, the symbols stack and stackidx are invisible and they cannot (ac- +cidentally) modify the variables. It also allows the other modules to declare +their own private variables with these names, so it avoids name clashing. + +Embora a calculadora RPN continue sendo um programa pequeno, estruturamos o código como se fosse maior para demonstrar vários elementos da linguagem. Em um cenário real, poderíamos implementá-la de maneira mais compacta. + +### • Event-driven programming + +Todos os exemplos deste capítulo até aqui seguiram um modelo “linear”: começam em `main` e o código decide o que fazer e quando pedir entrada. Esse modelo é fácil de entender e se encaixa bem na maioria das linguagens, mas não atende a muitas situações do mundo real. Frequentemente, o programa não pode simplesmente processar dados e solicitar entrada apenas quando for conveniente; é o usuário quem escolhe quando interagir, e o aplicativo deve estar pronto para responder rapidamente, independentemente do que estiver fazendo. + +Isso sugere que o programa deveria ser capaz de interromper o trabalho atual, realizar outra atividade e depois retomar a tarefa original. Nas primeiras implementações, isso era feito com sistemas multitarefa: uma thread cuidava das tarefas em segundo plano e outra ficava em loop aguardando entrada do usuário. Porém, essa solução é pesada. Um modelo mais leve para obter responsividade é o chamado “programação dirigida a eventos”. + +--- + +Nesse modelo, o programa divide tarefas longas em blocos curtos e, entre eles, fica disponível para processar eventos. Em vez de ficar “pollando” entradas, a aplicação hospedeira (ou outro subsistema) chama uma função associada ao evento —mas apenas quando ele ocorre. + +O evento mais comum é “entrada”. Porém, entradas não vêm apenas de usuários: podem chegar pacotes por cabos seriais, redes, temporizadores internos e outros dispositivos conectados. Muitos desses dispositivos simplesmente enviam dados; o recebimento é um evento, como uma tecla pressionada. Se você não tratar o evento, talvez alguns fiquem em uma fila interna, mas, quando ela enche, os demais são descartados. + +Pawn oferece suporte direto a esse modelo porque permite vários pontos de entrada. Em um programa linear, apenas `main` é o ponto inicial; em um programa dirigido a eventos, há uma função de entrada para cada evento capturado. Comparado ao modelo linear, esse estilo parece “de baixo para cima”: em vez de o programa chamar a aplicação hospedeira para decidir o próximo passo, é o host que invoca o script quando necessário, exigindo respostas rápidas. + +Como pawn não especifica uma biblioteca padrão, não há garantia de que determinada implementação forneça funções como `printf` ou `getvalue`. Embora se recomende que todas ofereçam ao menos uma interface mínima de console/terminal com essas funções, a disponibilidade depende da implementação. + +dependent. The same holds for the public functions —the entry points for a +script. It is implementation-dependent which public functions a host applica- +tion supports. The script in this section may therefore not run on your platform +(even if all previous scripts ran fine). The tools in the standard +distribution of +the pawn system support all scripts developed in this manual, provided that + +your operating system or environment supports standard terminal functions + +such as setting the cursor position. + +An early programming language that was developed solely for teaching the +concepts of programming to children was “Logo”. This dialect of LISP made +programming visual by having a small robot, the “turtle”, drive over the floor +under control of a simple program. This concept was then copied to moving +a (usually triangular) cursor of the computer display, again under control of a +program. A novelty was that the turtle now left a trail behind it, allowing you +to create drawings by properly programming the turtle —it became known as turtle graphics. + +--- + +`Public functions: 83` + +--- + +The term “turtle graphics” was also used for drawing inter- +actively with the arrow keys on the keyboard and a “turtle” for the current +position. This method of drawing pictures on the computer was briefly popular +before the advent of the mouse. + +Listing: turtle.p + +```c + +@keypressed(key) +{ + /_ get current position */ + new x, y + wherexy x, y + + /_ determine how the update the current position */ + switch (key) + { + case ’u’: y-- /_ up */ + case ’d’: y++ /_ down */ + case ’l’: x-- /_ left */ + case ’r’: x++ /_ right */ + case ’\e’: exit /_ Escape = exit */ + } + + /_ adjust the cursor position and draw something */ + moveturtle x, y +} + +moveturtle(x, y) +{ + gotoxy x, y + print ’/*’ + gotoxy x, y +} + +``` + +The entry point of the above program is @keypressed —it is called on a +key press. If you run the program and do not type any key, the +function @keypressed never runs; if you type ten keys, @keypressed runs ten times. +Contrast this behaviour with main: function main runs immediately after you +start the script and it runs only once. + +It is still allowed to add a main function to an event-driven program: the main +function will then serve for one-time initialization. A simple addition to this +example program is to add a main function, in order to clear the +console/ +terminal window on entry and perhaps set the initial position of the “turtle” +to the centre. + +Support for function keys and other special keys (e.g. the arrow keys) is highly +system-dependent. On ANSI terminals, these keys produce different codes +than in a Windows “DOS box”. + +--- + +In the spirit of keeping the example program +portable, I have used common letters (“u” for up, “l” for left, etc.). This +does not mean, however, that special keys are beyond pawn’s capabilities. + +In the “turtle” script, the “Escape” key terminates the host application through +the instruction exit. For a simple pawn run-time host, this will indeed work. +With host applications where the script is an add-on, or +host-applications + +that are embedded in a device, the script usually cannot terminate the host application. + +### • Múltiplos eventos + +As vantagens do modelo dirigido a eventos para construir programas reativos ficam claras quando há diversos eventos. Na prática, ele só faz sentido se houver mais de um ponto de entrada; se seu script lida com apenas um evento, um loop de polling seria suficiente. Quanto mais eventos precisamos tratar, mais difícil fica usar o modelo linear. O script a seguir implementa um chat bem simples com dois eventos: envio e recebimento. Ele permite que usuários em rede (ou outro meio) troquem mensagens de uma linha. + +O script depende de a aplicação hospedeira fornecer funções nativas/públicas para enviar e receber datagramas e reagir a teclas digitadas. O método de envio (serial, TCP/IP etc.) fica a cargo do host. As ferramentas da distribuição padrão do pawn usam TCP/IP e permitem um modo de “broadcast” para que mais de duas pessoas conversem. + +--- + +Listing: chat.p + +```c + +#include + +@receivestring(const message[], const source[]) +printf "[%s] says: %s\n", source, message + +@keypressed(key) +{ + static string[100 char] + static index + + if (key == ’\e’) + exit /* quit on ’Esc’ key */ + + echo key + + if (key == ’\r’ || key == ’\n’ || index char == sizeof string) + { + string{index} = ’\0’ /* terminate string */ + sendstring string + + index = 0 + string[index] = ’\0’ + } + else + string{index++} = key +} + +echo(key) +{ + new string[2 char] = { 0 } + string{0} = key == ’\r’ ? ’\n’ : key + printf string +} + +``` + +Grande parte do script se ocupa de juntar os caracteres digitados em uma string e enviá-la quando o usuário pressiona Enter. A tecla Escape encerra o programa. A função `echo` gera um feedback visual do que é digitado: monta uma string com terminador zero a partir da tecla e a imprime. + +Apesar da simplicidade, o script demonstra uma característica interessante: não há ordem rígida para enviar ou receber mensagens —não existe o esquema pergunta–resposta em que cada host “espera a vez”. Uma mensagem pode chegar enquanto o usuário ainda está digitando.∗ + +### • Programação com estados + +Em um programa dirigido a eventos, cada evento chega isoladamente e recebe uma resposta isolada. Às vezes, porém, um evento faz parte de um fluxo sequencial que deve ser tratado na ordem correta. Protocolos de transferência de dados em linhas seriais são um exemplo: cada evento pode carregar um comando, um pedaço de arquivo, um reconhecimento ou outro sinal do protocolo. + +--- + +###### ∗ As this script makes no attempt to separate received messages from typed messages (for example, in two different scrollable regions), the terminal/console will look confusing when this happens. With an improved user-interface, this simple script could indeed be a nice message-base chat program + +--- + +Para que esse fluxo faça sentido, o programa precisa seguir um protocolo rigoroso de “handshake”. Isso significa que ele deve reagir a cada evento considerando o histórico recente de eventos anteriores e as respostas enviadas. Ou seja, o tratamento de um evento pode definir a “condição” ou “contexto” em que os próximos serão processados. + +Uma abstração simples e eficaz para construir sistemas reativos que seguem protocolos parcialmente sequenciais é o autômato ou máquina de estados. Como o número de estados costuma ser finito, falamos em Máquinas de Estados Finitos (MEF). No autômato, o contexto do evento é o estado atual. Um mesmo evento pode ser tratado de maneiras diferentes dependendo desse estado e, em resposta, o autômato pode mudar para outro estado —essa mudança é chamada transição. + +Autômatos são comuns tanto em software quanto em dispositivos mecânicos (o tear de Jacquard é um exemplo clássico). Com um número finito de estados, são determinísticos (comportamento previsível) e fáceis de implementar a partir de um diagrama de estados. + +![State diagram](https://i.ibb.co/k3kWVvy/image.png) + +In a state diagram, the states are usually represented as circles or +rounded rectangles and the arrows represent the transitions. As transitions are +the response of the automaton to events, an arrow may also be seen as an event “that does something”. + +--- + +An event/transition that is not defined in a particular +state is assumed to have no effect —it is silently ignored. A filled dot +represents the entry state, which your program (or the host application) must set in start- +up. It is common to omit in a state diagram all event arrows that drop back +into the same state, but here I have chosen to make the response to all events explicit. + +O diagrama acima corresponde à análise de comentários iniciados por `/*` e terminados em `*/`. Há estados para texto normal, para texto dentro do comentário e dois estados intermediários para entrada e saída. O autômato foi pensado para processar caracteres digitados pelo usuário, então reage apenas a eventos de tecla. Na prática há um único evento (“tecla pressionada”); as transições dependem do parâmetro (a própria tecla). + +Pawn oferece suporte nativo a autômatos e estados. Cada função∗ pode ter um ou mais estados associados. A linguagem também permite múltiplos autômatos, e cada estado pertence a um autômato específico. + +O script abaixo implementa o diagrama descrito (usando um autômato anônimo). Para destacar o texto normal dos comentários, cada tipo recebe uma cor diferente. + +Listing: comment.p + +```c + +/* parse C comments interactively, using events and a state machine */ + +main() + state plain + +@keypressed(key) +{ + state (key == ’/’) slash + if (key != ’/’) + echo key +} + +@keypressed(key) +{ + state (key != ’/’) plain + state (key == ’/*’) comment + echo ’/’ /* print ’/’ held back from previous state */ + if (key != ’/’) + echo key +} + +@keypressed(key) +{ + echo key + state (key == ’/*’) star +} + +@keypressed(key) +{ + echo key + state (key != ’/*’) comment + state (key == ’/’) plain +} + +echo(key) + printchar key, yellow + +echo(key) + printchar key, green + +printchar(ch, colour) +{ + setattr .foreground = colour + printf "%c", ch +} + +``` + +--- + +###### ∗ With the exception of “native functions” and user-defined operators. + +--- + +`main` define o estado inicial como `plain` e termina; toda a lógica é dirigida a eventos. Quando uma tecla chega no estado `plain`, verificamos se é uma barra e, dependendo disso, imprimimos ou não o caractere. A interação entre os estados `plain` e `slash` mostra uma característica típica dos autômatos: é preciso decidir como reagir no momento em que o evento acontece, sem “olhar à frente” nem desfazer respostas anteriores. Em sistemas dirigidos a eventos, geralmente não sabemos qual será o próximo evento nem quando virá, e o que fizermos agora dificilmente poderá ser anulado depois. + +Neste caso, quando uma barra chega, ela **pode** indicar o início de um comentário (`/*`), mas não necessariamente. Não dá para decidir de imediato em que cor imprimir o caractere, então o mantemos “em espera”. Note que não declaramos nenhuma variável global para isso; na verdade, além dos parâmetros, não há variáveis declaradas. A informação de que há um caractere pendente está implícita no estado do autômato. + +Como mostra o script, mudanças de estado podem ser condicionais. A condição é opcional, e também podemos usar `if/else` tradicionais para alterá-los. + +A dependência de estado não se restringe às funções de evento. Outras funções podem declarar estados, como `echo` faz. Quando várias situações compartilham a mesma implementação, basta escrever uma função e listar todos os estados aplicáveis. Em `echo` existem duas versões para cobrir os quatro estados.† + +Um autômato deve estar preparado para tratar todos os eventos em qualquer estado. Normalmente ele não controla quais eventos chegam nem quando, portanto ignorá-los em certo estado pode levar a falhas. Muitas vezes alguns eventos fazem sentido somente em poucos estados e, nos demais, deveriam disparar erros ou uma rotina de “reset”. Para evitar listar manualmente todos os estados inválidos, podemos omitir o conteúdo entre os colchetes angulares: assim, a função atende a todos os estados que não têm implementação específica. Por exemplo, poderíamos declarar `echo(key) <>` em vez de listar explicitamente cada estado (mas apenas em uma das implementações). + +Existe um autômato anônimo predefinido. Se o programa contiver mais de um, precisamos mencionar seu nome tanto no qualificador quanto no comando `state`. Basta colocar o nome do autômato antes do estado, separados por `:` —por exemplo, `parser:slash` refere-se ao estado `slash` do autômato `parser`. Uma função só pode pertencer a um autômato; podemos reutilizar a mesma implementação em vários estados desse autômato, mas não em estados de autômatos diferentes. + +### • Funções `entry` e teoria de autômatos + +As máquinas de estados e a própria teoria dos autômatos têm origem no design mecânico e em circuitos elétricos/pneumáticos de comutação (com relés, não transistores). Exemplos típicos são aceitadores de moedas, semáforos e centrais de comunicação. Nesses sistemas, robustez e previsibilidade são fundamentais, e descobriu-se que esses objetivos são alcançados com mais facilidade quando as ações (saídas) estão ligadas aos estados em vez dos eventos (entradas). + +--- + +###### \* A function that has the same implementation for all states, does not need a state classifierat all —see printchar. + +--- + +![pcl](https://i.ibb.co/PYnBGS9/image.png) + +###### Figure 1: Pedestrian crossing lights + +--- + +Ao entrar em um estado, opcionalmente realizamos alguma ação; os eventos apenas provocam a mudança de estado, mas não executam operações por conta própria. + +Em um semáforo para pedestres, as luzes dos veículos e dos pedestres precisam ficar sincronizadas. Certamente, exibir verde para os carros e “andar” para os pedestres seria desastroso —o mesmo vale para amarelo/andar. Restam quatro combinações possíveis. O diagrama a seguir descreve o processo: tudo começa com um botão e é controlado por temporizadores. + +![pcl](https://i.ibb.co/9wNR3ry/image.png) + +When the state red/walk times out, the state cannot immediately go back to +green/wait, because the pedestrians that are busy crossing the road at +that moment need some time to clear the road —the state red/wait +allows for this. + +--- + +Para fins de demonstração, este semáforo tem um extra: se o pedestre aperta o botão enquanto a luz já está vermelha para os carros, o tempo de travessia é prolongado. Ou seja, se estamos em `red/wait` e alguém pressiona o botão, voltamos para `red/walk`. A caixa que envolve esses estados no diagrama é apenas uma convenção visual; poderíamos ter desenhado duas setas voltando a `red/walk`. O código abaixo segue a mesma convenção. + +Na implementação em pawn, as funções de evento sempre têm uma única instrução: ou mudam de estado ou não fazem nada. Os eventos que não provocam mudanças não aparecem no diagrama, mas precisam ser tratados no script —daí as funções “fallback” vazias. + +A saída (neste caso, apenas mensagens no console) é feita nas funções especiais `entry`. Podemos vê-las como “main” de cada estado: são chamadas automaticamente quando o estado correspondente é ativado. Note que elas também são executadas em reentradas, ou seja, quando mudamos para o mesmo estado em que já estávamos. + +Listing: traffic.p + +```c + +/* traffic light synchronizer, using states in an event-driven model */ +#include