Useful Functions

Use the one i wrote long time ago..
pawn Код:
Float:Angle2D(Float:PointA[], Float:PointB[])
{
  new
    Float:Dist[2],
    Float:Angle
  ;

  Dist[0] = PointA[0] < PointB[0] ? PointB[0] - PointA[0] : PointA[0] - PointB[0];
  Dist[1] = PointA[1] < PointB[1] ? PointB[1] - PointA[1] : PointA[1] - PointB[1];

  Angle = atan2(Dist[1],Dist[0]);
  Angle = PointA[0] < PointB[0] ? 270.0 + Angle : 90.0 - Angle;
  Angle = PointA[1] < PointB[1] ? Angle : 180.0 - Angle;

  return Angle;
}
Reply

Just tried it in different ways, it seems that the angle always turns north there, Orb
Reply

Well, it's working perfect for me, so i think you use it wrong.

Test cases:
pawn Код:
new Float:coords[][] =
{
  { 0.0, 0.0},
  { 0.0, 1.0},
  { 0.0, -1.0},
  { 1.0, 0.0},
  { 1.0, 1.0},
  { 1.0, -1.0},
  {-1.0, 0.0},
  {-1.0, 1.0},
  {-1.0, -1.0}
};
   
for (new i = 0; i < sizeof coords; i++)
  for (new j = 0; j < sizeof coords; j++)
    if (i != j)
      printf("Angle between {%2.1f, %2.1f} and {%2.1f, %2.1f} : %4.2f", coords[i][0], coords[i][1], coords[j][0], coords[j][1], Angle2D(coords[i], coords[j]));

Edit: fix for negative angles (gta fix negative angles for us, but for displaying in messages or whatever, its better to fix them here)
pawn Код:
Float:Angle2D(Float:PointA[], Float:PointB[])
{
  new
    Float:Dist[2],
    Float:Angle
  ;

  Dist[0] = PointA[0] < PointB[0] ? PointB[0] - PointA[0] : PointA[0] - PointB[0];
  Dist[1] = PointA[1] < PointB[1] ? PointB[1] - PointA[1] : PointA[1] - PointB[1];

  Angle = atan2(Dist[1], Dist[0]);
  Angle = PointA[0] < PointB[0] ? 270.0 + Angle : 90.0 - Angle;
  Angle = PointA[1] < PointB[1] ? Angle : 180.0 - Angle;
 
  return Angle < 0.0 ? Angle + 360.0 : Angle;
}
Reply

An useful macro

pawn Код:
#define CallLoop(%1,%2) for( new %1; %1 < %2; %1++ )
It can help when you can't remember at all the formula to make some plain simple loops :P

For example, the code given below
Код:
CallLoop(i,MAX_PLAYERS)
{
if(IsPlayerConnected(i))
{
SendClientMessage(i,somecolor,"Payday! You won $-9999 >:D");
GivePlayermoney(i,-9999);
GameTextForPlayer(i,"~r~ n~b~00~y~b ~p~ pwnt",5000,4);
}
}
replaces the code give below
Код:
for(new i;i<MAX_PLAYERS;i++)
{
if(IsPlayerConnected(i))
{
SendClientMessage(i,somecolor,"Payday! You won $-9999 >:D");
GivePlayermoney(i,-9999);
GameTextForPlayer(i,"~r~ n~b~00~y~b ~p~ pwnt",5000,4);
}
}
Tested and works

You don't need a
pawn Код:
new i;
or something to define the "i" given in
pawn Код:
CallLoop(i,MAX_PLAYERS)
for example, the script creates it by himself.

- X Cutter
Reply

Quote:
Originally Posted by X Cutter
An useful macro

pawn Код:
#define CallLoop(%1,%2) for( new %1; %1 < %2; %1++ )
It can help when you can't remember at all the formula to make some plain simple loops :P

For example, the code given below
Код:
CallLoop(i,MAX_PLAYERS)
{
if(IsPlayerConnected(i))
{
SendClientMessage(i,somecolor,"Payday! You won $-9999 >:D");
GivePlayermoney(i,-9999);
GameTextForPlayer(i,"~r~ n~b~00~y~b ~p~ pwnt",5000,4);
}
}
replaces the code give below
Код:
for(new i;i<MAX_PLAYERS;i++)
{
if(IsPlayerConnected(i))
{
SendClientMessage(i,somecolor,"Payday! You won $-9999 >:D");
GivePlayermoney(i,-9999);
GameTextForPlayer(i,"~r~ n~b~00~y~b ~p~ pwnt",5000,4);
}
}
Tested and works

You don't need a
pawn Код:
new i;
or something to define the "i" given in
pawn Код:
CallLoop(i,MAX_PLAYERS)
for example, the script creates it by himself.

- X Cutter
Lazyness lol
Reply

IpCheck()
This functions guarantees that what they said was in fact an IP, and bans them.

Function
pawn Код:
IpCheck(playerid, text[])
{
    new var, pos, oldpos;
    oldpos = strfind(text, ".", true);
    if(strval(text[oldpos - 1]) == 0) return 1;

    while((pos = strfind(text, ".", true, pos + 1)) != -1 && pos - oldpos <= 4)
    {
        var++;

        if(strval(text[pos + 1]) == 0 || text[pos + 1] == ' ') return 1;
        oldpos = pos;

        if(var == 3 && (pos = strfind(text, ":", true, pos + 1)) != -1)
        {
            if(strval(text[pos + 1]) == 0 || text[pos + 1] == ' ') return 1;
            BanEx(playerid, "Advertising");
            return 0;
        }
    }
    return 1;
}
Usage
pawn Код:
public OnPlayerText(playerid, text[])
{
    IpCheck(playerid, text);
    return 1;
}

public OnPlayerPrivmsg(playerid, recieverid, text[])
{
    IpCheck(playerid, text);
    return 1;
}

public OnPlayerCommandText(playerid, cmdtext[])
{
    IpCheck(playerid, cmdtext);
   
    if(strcmp("/mycommand", cmdtext, true, 10) == 0)
    {
        // Do something here
        return 1;
    }
    return 0;
}
Reply

Quote:
Originally Posted by 0rb
Test cases:
pawn Код:
new Float:coords[][] =
{
};
   
for (new i = 0; i < sizeof coords; i++)
  for (new j = 0; j < sizeof coords; j++)
    if (i != j)
      printf("Angle between {%2.1f, %2.1f} and {%2.1f, %2.1f} : %4.2f", coords[i][0], coords[i][1], coords[j][0], coords[j][1], Angle2D(coords[i], coords[j]));

Edit: fix for negative angles (gta fix negative angles for us, but for displaying in messages or whatever, its better to fix them here)
pawn Код:
Float:Angle2D(Float:PointA[], Float:PointB[])
{
}
Still can't get it to work, if I use this wrong, what exactly do I have to enter in Point A en B according to you?
I want it to face another player to the place where I stand

Also, I get warning 208 (because of the Float: in functionname - breaks gamemode) so I have to slightly modify Angle2D
Reply

double post, clicked quote instead edit.
Reply

Maybe you should search for how to fix the warning 208 properly?

Quote:

When a function is “used” (invoked) before being declared, and that function returns a value with a tag name, the parser must make an extra pass over the source code, because the presence of the tag name may change the interpretation of operators (in the presence of user-defined operators). You can speed up the parsing/compilation process by declaring the relevant functions before using them.

PointA and PointB are arrays of at least 2 cells, containing coord x in cell 0 and coord y in cell 1.
Reply

Quote:
Originally Posted by 0rb
Maybe you should search for how to fix the warning 208 properly?

Quote:

When a function is “used” (invoked) before being declared, and that function returns a value with a tag name, the parser must make an extra pass over the source code, because the presence of the tag name may change the interpretation of operators (in the presence of user-defined operators). You can speed up the parsing/compilation process by declaring the relevant functions before using them.

PointA and PointB are arrays of at least 2 cells, containing coord x in cell 0 and coord y in cell 1.
that's what I did, keeps returning something in 355.<random numbers here>
Reply

Quote:
Originally Posted by dre$tA
error 033: array must be indexed (variable "model")
ya this forum, its if (model [ i ]!=0)


Код:
stock Debug()
{
	new tmpVeh;
	tmpVeh = CreateVehicle(411, 0.0, 0.0, -100.0, 0.0, 0, 0, -1);  DestroyVehicle(tmpVeh);

	new model[250], nummodel;
	for(new i=1;i<tmpVeh;i++) model[GetVehicleModel(i)-400]++;
	for(new i=0;i<250;i++) { if(model[i]!=0) { nummodel++; } }

	printf("VehicleModels:%4d",(nummodel));
}
Reply

Still not crash proved
Reply

QuatToEuler(Float:qx, Float:qy, Float:qz, Float:qw, &Float:ex, &Float:ey, &Float:ez, bool:normalize = false)

To convert from GTA quaternions to SAMP angles

pawn Код:
#define q2e(%0) QuatToEuler(%0)

QuatToEuler(Float:qx, Float:qy, Float:qz, Float:qw, &Float:ex, &Float:ey, &Float:ez, bool:normalize = false)
{
  new
    Float:sqx = qx * qx,
    Float:sqy = qy * qy,
    Float:sqz = qz * qz,
    Float:sqw = qw * qw
  ;

  ex = atan2(-sqy - sqx + sqz + sqw, 2.0 * (qy * qz + qx * qw)) - 90.0;
  ey = asin(-2.0 * (qx * qz - qy * qw));
  ez = atan2(sqy - sqx - sqz + sqw, 2.0 * (qx * qy + qz * qw)) - 90.0;

  if (normalize)
  {
    if (ex < 0.0) ex += 360.0;
    if (ey < 0.0) ey += 360.0;
    if (ez < 0.0) ez += 360.0;

    if (ex == 360.0) ex = 0.0;
    if (ey == 360.0) ey = 0.0;
    if (ez == 360.0) ez = 0.0;
  }
}
Reply

Quote:
Originally Posted by Nubotron
QuatToEuler(Float:qx, Float:qy, Float:qz, Float:qw, &Float:ex, &Float:ey, &Float:ez, bool:normalize = false)
What can you use this for?

Leopard
Reply

Quote:
Originally Posted by ♣ ⓐⓢⓢ
pawn Код:
stock GetVehicleCount()
{
    new count,
        v = 1;
    while(v <= MAX_VEHICLES)
        if(GetVehicleModel(v))
            count++;
    return count;
}
That's going to create an infinite loop dude and it has no protection against invalid models, for example:

pawn Код:
AddStaticVehicle( 3, 0, 0, 0, 0, 0, 0 );
Would be counted as a valid model when it's not actually valid so IMO it would be better to do this to get an accurate count:

pawn Код:
stock GetVehicleCount()
{
  new
    count,
    model;
       
  for ( new v; v < MAX_VEHICLES; v ++ )
  {
    model = GetVehicleModel( v );
    if ( model > 399 && model < 612 ) count ++;
  }
  return count;
}
Reply

Quote:
Originally Posted by Donny
pawn Код:
AddStaticVehicle( 3, 0, 0, 0, 0, 0, 0 );
Would be counted as a valid model when it's not actually valid so IMO it would be better to do this to get an accurate count:
But I am sure this will crash your server, doesnt it ?
Or crash the players on it

< liked the "no-protection" from 0.1 XD
Reply

Quote:
Originally Posted by ♣ ⓐⓢⓢ
Quote:
Originally Posted by Donny
pawn Код:
AddStaticVehicle( 3, 0, 0, 0, 0, 0, 0 );
Would be counted as a valid model when it's not actually valid so IMO it would be better to do this to get an accurate count:
But I am sure this will crash your server, doesnt it ?
Or crash the players on it

< liked the "no-protection" from 0.1 XD
Yes when the first person connects it should crash (I think) but what if you are just doing a print in Init() to check how many vehicles your script currently has ? In this case your code would return an invalid count if the user had indeed made a typo and passed an invalid model like the example I showed (3).

Anyway this doesn't matter because your code will of already killed the server by running the loop as 'v' isn't increased at any time so it's never going to be equal to MAX_VEHICLES.
Reply

Quote:
Originally Posted by Donny
Yes when the first person connects it should crash (I think) but what if you are just doing a print in Init() to check how many vehicles your script currently has ? In this case your code would return an invalid count if the user had indeed made a typo and passed an invalid model like the example I showed (3).

Anyway this doesn't matter because your code will of already killed the server by running the loop as 'v' isn't increased at any time so it's never going to be equal to MAX_VEHICLES.
oh didnt noticed, miss that part, but I like when the server stops XD
Reply

hey...

i was using is playerinarea for some stuff, and was finding it was being annoying - i wanted to see if someone was in an elevator, but people not in the elevator BUT below it were being counted... so i made a modification to isplayerinarea:


stock IsPlayerInBox(playerid, Float:max_x, Float:min_x, Float:max_y, Float:min_y, Float:max_z, Float:min_z){
new Float:X, Float:Y, Float:Z;
GetPlayerPos(playerid, X, Y, Z);
if(X <= max_x && X >= min_x && Y <= max_y && Y >= min_y && Z <= max_z && Z >= min_z) return 1;
return 0;}


idk if its been done before, but meh
Reply

yh, it's done before
Reply


Forum Jump:


Users browsing this thread: 26 Guest(s)