Pular para o conteúdo principal

Portando para open.mp

· 6 min de leitura
Y_Less

O SA:MP ficou preso no limbo por anos, sem atualizações e com várias gambiarras só para manter as coisas funcionando. O open.mp muda isso — é uma reescrita completa que corrige problemas antigos, melhora o scripting e remove limites antigos, mantendo seu código existente funcionando. Mas o que isso realmente significa para você? Vamos explicar.

aviso

O conteúdo do post a seguir está desatualizado e, em sua maioria, não tem relação com o estado atual do open.mp. O post está publicado aqui para fins de arquivo.

Já estava claro há muito tempo que Kalcor não tinha mais interesse em manter o SA:MP; o que, por si só, tudo bem, mas como ele era a única pessoa com acesso oficial ao código-fonte, isso o transformou em um gargalo para novas atualizações. Tanto YSF quanto fixes.inc foram criados para preencher esse vazio — corrigir bugs e inconsistências no servidor sem ter acesso ao código-fonte; o primeiro como plugin e o segundo como include. Apesar de esforços monumentais para tornar esses (e outros) projetos tão estáveis, abrangentes e fáceis de usar quanto possível, eles naturalmente começaram a atingir seus limites e uma nova geração de correções se tornou necessária. É aí que o open.mp entra.

Fundado nos mesmos princípios, e aproveitando todas as inúmeras melhorias desenvolvidas pela comunidade ao longo de uma década, o open.mp é uma reescrita do zero do servidor SA:MP original, com todas as correções de seus predecessores diretos e muitas outras que eram impraticáveis ou simplesmente impossíveis. É verdade que essa abordagem não veio sem controvérsia — alguns servidores desenvolveram seus próprios métodos privados para lidar com as peculiaridades do SA:MP, independentemente dos esforços da comunidade, mas essas não são técnicas que todo scripter deveria ter que desenvolver por conta própria, e este artigo ajudará na portabilidade de código existente.

Esperamos abordar os principais pontos problemáticos, mas se houver algum que deixarmos passar, fique à vontade para entrar em contato via discord ou github e teremos prazer em corrigir o guia.

A alternativa é desfazer as correções usando uma biblioteca que é a gêmea da fixes.inc: breaks.inc:

https://github.com/pawn-lang/sa-mp-fixes/blob/master/breaks.inc

Então fique à vontade para instalá-la e reverter para todos os comportamentos antigos de forma transparente por meio de hooks.

Tags​

Os includes do open.mp adicionam muitas novas tags às funções, embora ainda tentem encontrar um equilíbrio entre upgrades muito necessários e invasividade. Como essas mudanças podem ser muito amplas, escrevemos uma ferramenta para automatizar boa parte disso:

HideMenuForPlayer​

Esta função sempre recebeu um parâmetro de ID de menu, mas no SA:MP esse ID não era usado. Então, qualquer que fosse o valor fornecido, o menu atual do jogador era fechado, mesmo que ele não estivesse olhando para aquele que você disse para fechar.

Código antigo poderia ser assim:

gShopMenu = CreateMenu("text", 2, 100.0, 30.0, 7.0);

HideMenuForPlayer(gShopMenu, playerid);

Isso sempre fecharia o menu atual do jogador, independentemente de qual ele estivesse realmente vendo. Agora você precisará lembrar qual menu ele está vendo, ou simplesmente obtê-lo:

gShopMenu = CreateMenu("text", 2, 100.0, 30.0, 7.0);

HideMenuForPlayer(GetPlayerMenu(playerid), playerid);

SetPlayerAttachedObject​

Objetos anexados no SA:MP sobreviviam a uma mudança de gamemode, mas no open.mp eles não sobrevivem. Se você quiser que um jogador mantenha seus objetos após um reinício do modo, terá que adicioná-los novamente em OnPlayerConnect:

enum E_ATTACHMENT_DATA
{
E_ATTACHMENT_DATA_MODEL,
E_ATTACHMENT_DATA_BONE,
E_ATTACHMENT_DATA_OFFSET_X,
E_ATTACHMENT_DATA_OFFSET_Y,
E_ATTACHMENT_DATA_OFFSET_Z,
E_ATTACHMENT_DATA_ROT_X,
E_ATTACHMENT_DATA_ROT_Y,
E_ATTACHMENT_DATA_ROT_Z,
E_ATTACHMENT_DATA_SCALE_X,
E_ATTACHMENT_DATA_SCALE_Y,
E_ATTACHMENT_DATA_SCALE_Z,
E_ATTACHMENT_DATA_COLOUR_1,
E_ATTACHMENT_DATA_COLOUR_2,
}

public OnPlayerConnect(playerid)
{
for (new i = 0; i != MAX_OBJECT_ATTACHMENT_SLOTS; ++i)
{
SetPlayerAttachedObject(
playerid,
i,
gAttachementData[playerid][E_ATTACHMENT_DATA_MODEL],
gAttachementData[playerid][E_ATTACHMENT_DATA_BONE],
gAttachementData[playerid][E_ATTACHMENT_DATA_OFFSET_X],
gAttachementData[playerid][E_ATTACHMENT_DATA_OFFSET_Y],
gAttachementData[playerid][E_ATTACHMENT_DATA_OFFSET_Z],
gAttachementData[playerid][E_ATTACHMENT_DATA_ROT_X],
gAttachementData[playerid][E_ATTACHMENT_DATA_ROT_Y],
gAttachementData[playerid][E_ATTACHMENT_DATA_ROT_Z],
gAttachementData[playerid][E_ATTACHMENT_DATA_SCALE_X],
gAttachementData[playerid][E_ATTACHMENT_DATA_SCALE_Y],
gAttachementData[playerid][E_ATTACHMENT_DATA_SCALE_Z],
gAttachementData[playerid][E_ATTACHMENT_DATA_COLOUR_1],
gAttachementData[playerid][E_ATTACHMENT_DATA_COLOUR_2]
);
}
}

Dinheiro ao morrer​

Quando um jogador morre em San Andreas, $100 são deduzidos dele automaticamente para cobrir as contas do hospital. Esse recurso permanece no SA:MP, mas foi removido do open.mp para permitir que scripts gerenciem todo o próprio dinheiro. Vários scripts já tentam corrigir isso adicionando $100 a um jogador depois da morte, ou ao nascer. Se esse for o seu script, simplesmente remova a correção adicional, embora o código no open.mp tente levar em conta scripts que fazem isso. Se seu script dependia desse recurso, basta adicionar o seguinte código em OnPlayerDeath:

GivePlayerMoney(playerid, -100);

Game texts​

O SA:MP tem seis estilos diferentes de game text, mas vários deles são basicamente inutilizáveis. Um fica aparecendo e desaparecendo constantemente, um desaparece após um tempo definido independentemente do tempo que você colocou, e um nunca desaparece independentemente do tempo selecionado. No entanto, descobriu-se que todos esses estilos de game text podem ser reproduzidos com precisão1 usando text draws. Assim, fixes.inc e, posteriormente, open.mp fizeram isso. A aparência dos game texts é a mesma de antes, com a vantagem de que todos os estilos são utilizáveis, e a desvantagem de que eles não fazem mais fade in e fade out.

FadingGameTextForPlayer(playerid, const format[], time, style)
{
if (style > 6)
{
// Não há versão com fade desses estilos.
GameTextForPlayer(playerid, format, time, style)
}
else
{
// Envia uma mensagem bruta via Pawn.RakNet
}
}

Tamanhos dos pools​

GetPlayerPoolSize, GetActorPoolSize e GetVehiclePoolSize eram um tanto sem sentido quando foram introduzidas pela primeira vez; retornavam o maior ID conectado, que não tem relação com o número de jogadores conectados, e chegaram muito depois de métodos de loop muito melhores já existirem. Ser meio bobo não é, por si só, motivo para remover as funções, mas infelizmente elas também estão quebradas e retornam dados incorretos quando não há jogadores conectados. Não há como corrigir esses valores de retorno de uma forma que seja ao mesmo tempo retrocompatível e correta daqui para frente (acredite, tentamos). Diante desses fatos, optamos por simplesmente remover as funções. Use apenas um loop normal ou foreach:

foreach (new i : Player)
{
}

Alguns scripts travaram quando essa mudança foi introduzida, mas apenas ao usar a seguinte forma de loop:

for (new i = 0; i != GetPlayerPoolSize(); ++i)
{
}

Embora, como o maior valor é um jogador real quando há pessoas online, esse código esteja errado de qualquer forma — ele deixa uma pessoa de fora.

Grafias​

O SA:MP é muito inconsistente nas grafias usadas no código — algumas coisas usam inglês britânico, outras usam americano:

  • Bumper - Britânico
  • Hood - Americano
  • Armour - Britânico
  • Stereo - Americano

Unificamos isso e adotamos as grafias britânicas. Então, por exemplo:

TextDrawBoxColor(Text:textid, boxColor);

Agora é:

TextDrawBoxColour(Text:textid, boxColour);

A ferramenta de upgrade cuidará automaticamente da maioria desses casos.

Footnotes​

  1. Com uma exceção notável: o novo estilo de game text de relógio. Por algum motivo desconhecido, a cor do relógio é diferente para pessoas diferentes, o que levou a muita discussão sobre a melhor forma de replicar esse estilo até que a discrepância fosse encontrada. Tivemos que escolher uma das duas por consistência. ↩