SA-MP Forums

Go Back   SA-MP Forums > Non-English > Languages > Português/Portuguese > Lançamentos/Releases

Reply
 
Thread Tools Display Modes
Old 22/07/2012, 03:38 AM   #1871
rjjj
Guest
 
Posts: n/a
Default Re: Códigos Úteis #1

Quote:
Originally Posted by [FeK]DraKiNs View Post
Bom trabalho Ken, mas neste caso é mais rápido não usar #emit
EDIT: Passa JogadorTexto3D para uma variável global, olha o tamanho da stack carinha ..

CidadeNovaRP banido?

GetVehicleFacingAngle

pawn Code:
stock Float:GetVehicleFacingAngle(const vehid) {

    if(!GetVehicleModel(vehid))
        return Float:false;

    static
        Float:x, Float:y, Float:z
    ;

    GetVehicleVelocity(vehid, x, y, z);

    x = ((atan2(x * 100.0, y * 100.0)) + 90.0);

    return x > 360 ? x - 360 : x;

}

Se eu não tivesse usado #emit, teria que fazer com #define ou com as funções de argumentos da include core.inc .



O primeiro método faria o arquivo .amx aumentar mais de tamanho, além de poder causar problemas como este:


pawn Code:
#define DarDinheiro(%0,%1)      GivePlayerMoney(%0,%1)

DarDinheiro(0, 1000); //Compilaria.
DarDinheiro(0,
1000); //Não compilaria.


O segundo método faria a função ficar com uma definição extremamente grande para aceitar poucos argumentos.



E a variável JogadorTexto3D foi declarada com static, sendo assim ela irá para a data, não para a stack .



Sobre a sua função, saiba que o atan2 funciona da seguinte maneira :


pawn Code:
atan2(/* Seno */, /* Cosseno */);


Retornando o ângulo do qual a tangente é obtida através do seno e do cosseno que são iguais aos argumentos, por exemplo:


pawn Code:
printf("%f", atan2(floatsin(13.0, degrees), floatcos(13.0, degrees))); //Mostra o número 13.


Um ponto da circunferência trigonométrica sempre terá sua ordenada e sua abscissa iguais ao seno e cosseno de seu ângulo, respectivamente.



Então, esta linha :


pawn Code:
x = ((atan2(x * 100.0, y * 100.0)) + 90.0);


Ficaria melhor assim:


pawn Code:
x = ((atan2(y * 100.0, x * 100.0)) + 90.0);


Porque do jeito que está, essa parte resultaria em um ângulo cuja tangente é igual à cotangente do ângulo que estaria relacionado à velocidade do veículo .



E também, como a fórmula da tangente é:


Code:
tan (x) = sen (x) / cos (x)


Teoricamente, o fato de você multiplicar o seno e o cosseno por 100 não modificaria a tangente.



Porém fiz alguns testes e os resultados às vezes acabam sendo um pouco diferentes, mas acredito que isso seja um problema do arredondamento que é feito internamente .



Bem, recomendo que reforme sua função com GetVehicleZAngle.





LeiDosCossenos






A Lei dos Cossenos é uma fórmula similar ao Teorema de Pitágoras .




Créditos: rjjj ou Ken pela feitura dos códigos.




A função calcula e armazena na variável que é passada ao seu primeiro parâmetro o que seria a medida da hipotenusa em um triângulo retângulo, mas utilizando um ângulo qualquer no lugar do ângulo de 90° :


pawn Code:
stock LeiDosCossenos(&Float:a, Float:b, Float:c, Float:angulo)
{
    a = floatsqroot((b * b) + (c * c) - (2 * b * c * floatcos(angulo, degrees)));
    return true;
}


Exemplo de uso:


pawn Code:
new Float:Lado;
LeiDosCossenos(Lado, 3.0, 4.0, 90.0);
printf("%f", Lado); //Mostra o número 5.



Espero ter ajudado .

Last edited by rjjj; 22/07/2012 at 05:34 AM.
  Reply With Quote
Old 22/07/2012, 05:39 AM   #1872
ipsBruno
Godfather
 
ipsBruno's Avatar
 
Join Date: Apr 2010
Location: Brazil, Caxias RS
Posts: 6,084
Reputation: 546
Default Re : Códigos Úteis #1

A função GetVehicleZAngle não tem nada haver com isto que estou demonstrando.


- Multipliquei por 100.0 porque a velocidade é retornada em valores muito pequenos e eventualmente a angulação e o retorno dela pode avariar.

- Em relação a atan2. Isto do x antes do y foi um possível erro da função na SA:MP (não lembro em que resposta vi isto, mas é verdade) .. Por este motivo testei ambos e o atan(x,y) retornou os valores de forma correta. Sim foi testado e funcionou perfeitamente.

Quote:
Porém fiz alguns testes e os resultados às vezes acabam sendo um pouco diferentes, mas acredito que isso seja um problema do arredondamento que é feito internamente .
Não, é problema que você está invertendo a posição dos valores yx e xy, não tem mais isto na sa:mp não (eu acho)



Quote:
Porque do jeito que está, essa parte resultaria em um ângulo cuja tangente é igual à cotangente do ângulo que estaria relacionado à velocidade do veículo .
Bastante lógico e inteligente isto que fiz não é? Você pega a posição em que o veículo está indo, logo está posição tende a ser a posição frontal, depois disto só compara os valores como se fossem posições com relação a 0.0 e 0.0.

Ele retorna perfeitamente o angulo da face do carro, isto se ele não estiver de ré ou caindo de um penhasco

O valor 90.0 é questão de fixação da angulação.

Eu tentei fazer com GetVehicleRotationQuat do veículo, mas como disse, eu teria que converter de Quaternion para Método Euler de Angulação (usaria bastante condicionais e muitas regras) e depois equivaler para as rotações usadas em sa:mp, então sim fazer o atan2 para pegar a angulação referente a face do veículo. Inviável.

Exatamente isto:
http://forum.sa-mp.com/showpost.php?...22&postcount=3

Então só dar atan2 e pegar a angulação de face do carro.


A sua função LeiDosCossenos pode ser feita com #defines

Quote:
Teoricamente, o fato de você multiplicar o seno e o cosseno por 100 não modificaria a tangente.
Não mesmo. Quando passamos o valor de uma float MUITÍSSIMO PEQUENA (caso de Velocity em SA:MP) alguns valores NORMALMENTE poderam passar a serem desconsiderados. Como

0.000000005 para 0.0

E isto iria afetar no calculo final em referencia aos ângulos. Logo eu multiplico por cem, mas que os valores pequenos tenham um notoriedade maior, assim sendo considerados, pois no caso é importante.

Obviamente eu não fiz os testes de x e x e x, mas apenas multipliquei por cem, pois já presenciei casos do tipo e para evitar estes bugs chatos, multipliquei por cem.

---------------

Acho que você não entendeu a lógica da minha função. Leve em consideração que o mapa de san andreas tem 360 graus em forma de arco e que GetVehicleVelocty "retorna uma posição em tempo real" (não sei como explicar, mas ele retorna a posição que o carro pode percorrer em X tempo)

Logo se ele percorrer 13x e 13y você pega o ponto que isto gera

Note que este é o ponto:
PHP Code:
|
| -- - - - - -  (
x13 y13)
|               |
|               |
|               |
C               
|
|
|

Agora eu pego a angulação entre o centro C e x13 y13 que é a velocidade do carro. Isto retorna a angulação
PHP Code:
    /
   /
  /
 /

Essa é a angulação em que o carro está indo, ou GetVehicleFacingAngle

Acredite, não sou bom em matemática, mas está lógica de pegar a angulação com a velocidade do carro é bastante fácil de pensar.
__________________
https://github.com/ipsBruno
ipsBruno is offline   Reply With Quote
Old 22/07/2012, 03:18 PM   #1873
rjjj
Guest
 
Posts: n/a
Default Re: Re : Códigos Úteis #1

Quote:
Originally Posted by [FeK]DraKiNs View Post
A função GetVehicleZAngle não tem nada haver com isto que estou demonstrando.

A função GetVehicleZAngle é o GetPlayerFacingAngle de veículos .



Pensei que fazer isso era o foco de sua função .




Quote:
Originally Posted by [FeK]DraKiNs View Post
- Multipliquei por 100.0 porque a velocidade é retornada em valores muito pequenos e eventualmente a angulação e o retorno dela pode avariar.

- Em relação a atan2. Isto do x antes do y foi um possível erro da função na SA:MP (não lembro em que resposta vi isto, mas é verdade) .. Por este motivo testei ambos e o atan(x,y) retornou os valores de forma correta. Sim foi testado e funcionou perfeitamente.

Isso não deixaria o cálculo mais preciso ou algo do tipo. Explicarei mais abaixo.



Se você não seguir as regras para o uso de atan2 que mostrei, irá obter resultados inesperados :


pawn Code:
printf("%f", atan2(floatsin(13.0, degrees), floatcos(13.0, degrees))); //Mostra o número 13.
printf("%f", atan2(floatcos(13.0, degrees), floatsin(13.0, degrees))); //Mostra outro número.


Como você utilizou a fórmula do coeficiente angular, que é igual à tangente da inclinação da reta, você teria que fazer como eu disse para que seu cálculo ficasse correto.




Quote:
Originally Posted by [FeK]DraKiNs View Post
A sua função LeiDosCossenos pode ser feita com #defines

Funções são implementadas em linguagens de programação justamente para blocos de códigos que são executados repetidas vezes, logo, preferi as mesmas a substituição de códigos com #define .




Quote:
Originally Posted by [FeK]DraKiNs View Post
Não mesmo. Quando passamos o valor de uma float MUITÍSSIMO PEQUENA (caso de Velocity em SA:MP) alguns valores NORMALMENTE poderam passar a serem desconsiderados. Como

0.000000005 para 0.0

E isto iria afetar no calculo final em referencia aos ângulos. Logo eu multiplico por cem, mas que os valores pequenos tenham um notoriedade maior, assim sendo considerados, pois no caso é importante.

Obviamente eu não fiz os testes de x e x e x, mas apenas multipliquei por cem, pois já presenciei casos do tipo e para evitar estes bugs chatos, multipliquei por cem.

Você está enganado quanto a isso .



Essa desconsideração na verdade é um bug do format e do printf, não dos números de Pawn.



Uma prova :


pawn Code:
new Float:Var[2];
Var[0] = 0.000000005;
Var[1] = 0.000000002;
printf("Var[0]:  %f", Var[0]);
printf("Var[1]:  %f", Var[1]);
if(Var[0] == Var[1])
{
    print("Bug não é do printf !");
}
else
{
    print("Bug é do printf !");
}


O que eu quis dizer é que aquilo deve ser um problema interno da própria função atan2, por isso seria melhor você manter os valores, ou seja, não multiplicar nem nada do tipo.




Quote:
Originally Posted by [FeK]DraKiNs View Post
Acho que você não entendeu a lógica da minha função. Leve em consideração que o mapa de san andreas tem 360 graus em forma de arco e que GetVehicleVelocty "retorna uma posição em tempo real" (não sei como explicar, mas ele retorna a posição que o carro pode percorrer em X tempo)

Logo se ele percorrer 13x e 13y você pega o ponto que isto gera

Note que este é o ponto:
PHP Code:
|
| -- - - - - -  (
x13 y13)
|               |
|               |
|               |
C               
|
|
|

Agora eu pego a angulação entre o centro C e x13 y13 que é a velocidade do carro. Isto retorna a angulação
PHP Code:
    /
   /
  /
 /

Essa é a angulação em que o carro está indo, ou GetVehicleFacingAngle

Acredite, não sou bom em matemática, mas está lógica de pegar a angulação com a velocidade do carro é bastante fácil de pensar.

Eu tinha entendido a lógica, porém agora ficou claro que você aplicou a fórmula do coeficiente angular .



Bem, você teria que consertar a parte do atan2 de qualquer jeito, como eu disse antes.



E a parte de aumentar em 90°, isso é feito para a conversão :


Code:
ângulos do SA-MP  ->  ângulos da Matemática


Então, você teria que fazer o contrário, pois o objetivo final no caso da sua função é um ângulo do SA-MP.



Você também teria que dar alguns ajustes para o caso do ângulo ser negativo, como você fez com ângulos maiores que 360° .



Em suma, esta seria uma versão bem mais correta de sua função:


pawn Code:
stock Float:GetVehicleFacingAngle(const vehid) {

    if(!GetVehicleModel(vehid))
        return Float:false;

    static
        Float:x, Float:y, Float:z
    ;

    GetVehicleVelocity(vehid, x, y, z);

    x = (atan2(y, x) - 90.0);

    if(x < 0)
        x += 360;

    else if(x > 360)
        x -= 360;

    return x;

}


Tanto que o retorno dela seria bem próximo do de GetVehicleZAngle.



Espero ter ajudado .
  Reply With Quote
Old 22/07/2012, 08:07 PM   #1874
ipsBruno
Godfather
 
ipsBruno's Avatar
 
Join Date: Apr 2010
Location: Brazil, Caxias RS
Posts: 6,084
Reputation: 546
Default Re : Códigos Úteis #1

Você não precisa essas condicionais Ken. O valor NUNCA VAI SER menor que zero. Porque sempre será acrescido +90 e atan2 não irá retornar valores menores de -90 nessa ocasião.

Você está tirando 90, mas como estou usando atan2 x y seu sistema irá retornar ao contrário (haha) em vez de norte vai ser sul, em vez de leste vai ser oeste. É mais 90, eu fiz os testes

pawn Code:
return x > 360 ? x - 360 : x;

Em relação aos valores digo quando eles passam a função para C++ via parâmetro as floats, não em pawn, criatura

--
GetVehicleZAngle não é um GetVehicleFaceAngle.

Tente dar:
pawn Code:
// uso da funcao em outra funcao

stock const
        Float:direita   =   090.0,
        Float:esquerda  =   270.0,
        Float:frente    =   000.0,
        Float:atras     =   180.0;

stock empinarCarro(carro, Float:lado) {
    return SetVehicleAngleVelocity(carro, lado, 0.08);
}

// exemplo comando

// "/empinar"
cmd(empinar, playerid, params[]) {
    return empinarCarro(GetPlayerVehicleID(playerid), frente);
}

Note que somente a versão da minha função fará isto certo.
__________________
https://github.com/ipsBruno

Last edited by ipsBruno; 22/07/2012 at 08:58 PM.
ipsBruno is offline   Reply With Quote
Old 24/07/2012, 12:28 PM   #1875
RebeloX
High-roller
 
RebeloX's Avatar
 
Join Date: Jul 2011
Location: Portugal
Posts: 2,172
Reputation: 442
Default Re: Códigos Úteis #1

Coordenadas polares

Vi um video sobre coordenadas polares e deu-me vontade de fazer em pawn.

A sua função é muito simples, você necessita de saber 2 coisas:
r: a distância entre esse ponto e a origem O.
angle: o ângulo formado entre o segmento de recta que une esse ponto à origem e o eixo x, também chamado ângulo azimutal, que em matemática é representado por θ .

Função

marco:
pawn Code:
#define cpolar(%0,%1,%2,%3)\
    %0=%2*floatcos(%3,degrees);%1=%2*floatsin(%3,degrees)

stock:
pawn Code:
stock cpolar(&Float:x,&Float:y,r,Float:angle){
    x = r*floatcos(angle,degrees);
    y = r*floatsin(angle,degrees);
    return true;
}

Modo de uso:

pawn Code:
public OnFilterScriptInit()
{
    new Float:a,Float:b;
    cpolar(a,b,3,120.0);
    printf("x = %f | y = %f",a,b);
    return 1;
}

Também pode ser usado para setar as coordenadas do jogador, ex:

pawn Code:
public SuaCallBack(playerid){
    new Float:a,Float:b;
    cpolar(a,b,3,120.0);
    SetPlayerPos(playerid,a,b,10);
    return 1;
}
__________________
RebeloX is offline   Reply With Quote
Old 24/07/2012, 06:36 PM   #1876
leonardo1434
High-roller
 
leonardo1434's Avatar
 
Join Date: Mar 2012
Posts: 1,667
Reputation: 179
Default Re: Códigos Úteis #1

Bluex, sua intenção foi boa, porém já existe algo como isto, e ainda mais eficiente já que usa a própria altura do jogador para funcionar de acordo.


http://wiki.sa-mp.com/wiki/GetPlayerCameraFrontVector
__________________
c++
leonardo1434 is offline   Reply With Quote
Old 24/07/2012, 07:00 PM   #1877
paulor
High-roller
 
Join Date: Nov 2011
Location: Brasil
Posts: 3,116
Reputation: 222
Default Re: Códigos Úteis #1

Veiculo em Primeira Pessoa.
pawn Code:
public OnPlayerStateChange(playerid, newstate, oldstate) {
    if(newstate == PLAYER_STATE_DRIVER) {
        SetPVarInt(playerid, #Object, CreateObject(19351, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
        AttachObjectToPlayer(GetPVarInt(playerid, #Object), playerid, 0.0194, 0.1061, 0.5559, 90.0, 0.0, 90.0);
        AttachCameraToObject(playerid, GetPVarInt(playerid, #Object));
    } else if(oldstate == PLAYER_STATE_DRIVER) {
        DestroyObject(GetPVarInt(playerid, #Object));
        DeletePVar(playerid, #Object);
        SetCameraBehindPlayer(playerid);
    }
    return 1;
}
__________________
Meus Projetos - contato@paulorwd.com.br
[IMG]https://sites.******.com/site/facesbypaulo/MetropoleGames.png[/IMG]
paulor is offline   Reply With Quote
Old 24/07/2012, 07:17 PM   #1878
RebeloX
High-roller
 
RebeloX's Avatar
 
Join Date: Jul 2011
Location: Portugal
Posts: 2,172
Reputation: 442
Default Re: Códigos Úteis #1

Quote:
Originally Posted by leonardo1434 View Post
Bluex, sua intenção foi boa, porém já existe algo como isto, e ainda mais eficiente já que usa a própria altura do jogador para funcionar de acordo.


http://wiki.sa-mp.com/wiki/GetPlayerCameraFrontVector
Coordenadas polares servem para você obter o x e o z, eu não coloquei o y porque nas coordenadas polares é só x e z, mesmo que eu tentasse fazer os cálculos com z iria dar errado.

Veja esse video

[ame]http://www.youtube.com/watch?v=I-ING7l7Wbk&feature=relmfu[/ame]


Checar se o jogador esta com health hack.

OnPlayerConnect
pawn Code:
RemoveBuildingForPlayer(playerid, 1302, 0.0, 0.0, 0.0, 6000.0);
    RemoveBuildingForPlayer(playerid, 1209, 0.0, 0.0, 0.0, 6000.0);
    RemoveBuildingForPlayer(playerid, 955, 0.0, 0.0, 0.0, 6000.0);
    RemoveBuildingForPlayer(playerid, 956, 0.0, 0.0, 0.0, 6000.0);
    RemoveBuildingForPlayer(playerid, 1775, 0.0, 0.0, 0.0, 6000.0);
    RemoveBuildingForPlayer(playerid, 1776, 0.0, 0.0, 0.0, 6000.0);
    RemoveBuildingForPlayer(playerid, 1977, 0.0, 0.0, 0.0, 6000.0);

OnPlayerSpawn
pawn Code:
SetPlayerHealth(playerid,99.0);
SetPVarFloat(playerid,"Health",99.0);

OnPlayerUpdate
pawn Code:
new Float:nHealth;
    GetPlayerHealth(playerid,nHealth);
    if(nHealth > GetPVarFloat(playerid,"Health"))
        Kick(playerid);
    return 1;

Depois quando for setar a vida do jogador coloque sempre 99.0, caso coloque mais ele vai ser kickado...
__________________

Last edited by RebeloX; 25/07/2012 at 05:01 AM.
RebeloX is offline   Reply With Quote
Old 25/07/2012, 01:37 AM   #1879
ipsBruno
Godfather
 
ipsBruno's Avatar
 
Join Date: Apr 2010
Location: Brazil, Caxias RS
Posts: 6,084
Reputation: 546
Default Re : Códigos Úteis #1

Gonçalo faltou um ')' if(nHealth > GetPVarFloat(playerid,"Health") em seu código.

Teste antes de postar



fsize
Essa função retorna o número de bytes de um determinado arquivo:

pawn Code:
static
    File: gLengthFile [2]
;

#define fsize(%0) \
                (fclose((gLengthFile[1] = File: flength ( (gLengthFile[0] = fopen( %0, io_read ), gLengthFile[0]) ), gLengthFile[0])), _: gLengthFile[1] )

Uso:
PHP Code:
printf("%d size"fsize("sa.pos")); 
--

Se o arquivo não existir, como padrão, é crash. Caso existir, retorna o número de bytes dele.

Terceira edição ._. Gonçalo, o que você está fazendo chama-se coordenadas cilíndricas (parte especifica as polares) Mas isto não é útil em SA:MP. Use com relação as coordenadas cartesianas x-y, então sim fica útil. Parabéns pelo código

GetPlayerCameraFrontVector retorna a relação tridimensional com GetCameraPos. Não muito haver com isto não.
__________________
https://github.com/ipsBruno
ipsBruno is offline   Reply With Quote
Old 25/07/2012, 01:47 AM   #1880
FireCat
High-roller
 
FireCat's Avatar
 
Join Date: Jul 2010
Posts: 2,322
Reputation: 609
Default Re: Códigos Úteis #1

IsPlayerInArea e IsPlayerInArea3D

pawn Code:
public IsPlayerInArea(playerid,Float:fXMax,Float:fYMax,Float:fXMin,Float:fYMin) //By: Firecat
{
    new
        Float:fX,Float:fY,Float:fZ;
       
    GetPlayerPos(playerid,fX,fY,fZ);
    if(((fX >= fXMin) && (fX <= fXMax)) && ((fY >= fYMin) &&(fY <= fYMax)))
        return 1;
    return 0;
}


public IsPlayerInArea3D(playerid,Float:fXMax,Float:fYMax,Float:fZMax,Float:fXMin,Float:fYMin,Float:fZMin) //By: Firecat
{
    static
        Float:fX,Float:fY,Float:fZ;

    GetPlayerPos(playerid,fX,fY,fZ);
    if(((fX >= fXMin) && (fX <= fXMax)) && ((fY >= fYMin) && (fY <= fYMax)) && ((fZ >= fZMin) && (fZ <= fZMax)))
        return 1;
    return 0;
}
FireCat is online now   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[FilterScript] Menus Úteis [SKIN|CARROS|ARMAS] SlashPT Lançamentos/Releases 25 02/05/2014 03:56 PM
[Include] [INC]Várias e Uteis Funções andmeida10 Lançamentos/Releases 28 14/12/2012 01:49 PM
[PEDIDO] Codigos Hashtag Português/Portuguese 7 16/11/2011 10:09 PM


All times are GMT. The time now is 06:19 AM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.