Useful Functions

This function casts a ray between two points in the world, and tells you information about the point that was hit, if any.

PHP код:
processLineOfSight
//start
Floatstart_x
Floatstart_y
Floatstart_z
//finish
&Floatend_x
&
Floatend_y
&
Floatend_z
boolcheck_vehicles
boolcheck_players 
PHP код:
forward processLineOfSightFloatstart_xFloatstart_yFloatstart_z, &Floatend_x, &Floatend_y, &Floatend_zboolcheck_vehiclesboolcheck_players );
public 
processLineOfSightFloatstart_xFloatstart_yFloatstart_z, &Floatend_x, &Floatend_y, &Floatend_zboolcheck_vehiclesboolcheck_players ){//by Seregamil
     
new distance_between_points floatroundVectorSizeend_x start_xend_y start_yend_z start_z ) );
    if( 
distance_between_points == )
        return ;
    new 
Floatpack_pos_x floatdivend_x start_xfloatdistance_between_points ) ),
        
Floatpack_pos_y floatdivend_y start_yfloatdistance_between_points ) ),
        
Floatpack_pos_z floatdivend_z start_zfloatdistance_between_points ) ),
        
Floatmap_z 0.0,
        
= -1Floatpos_xFloatpos_yFloatpos_z 0;
    do{
        
start_x += pack_pos_x;
        
start_y += pack_pos_y;
        
start_z += pack_pos_z;
        if( 
check_vehicles ){
            for( 
0!= MAX_VEHICLESi++ ){
                if( !
IsValidVehicle) ) continue;
                
GetVehiclePosipos_xpos_ypos_z );
                if( 
VectorSizepos_x start_xpos_y start_ypos_z start_z ) > 3.0 ) continue;
                
end_x start_x;
                
end_y start_y;
                
end_z start_z;
                return ;
            }
        }
        
        if( 
check_players ){
            for( 
GetMaxPlayers() - 1!= -1i-- ){
                if( 
IsPlayerNPC) || !IsPlayerConnected) ) continue;
                
GetPlayerPosipos_xpos_ypos_z );
                if( !
IsPlayerInRangeOfPoint3.0pos_xpos_ypos_z ) ) continue;
                
end_x start_x;
                
end_y start_y;
                
end_z start_z;
                return ;
            }
        }
        
MapAndreas_FindZ_For2DCoordstart_xstart_ymap_z );
        if( 
map_z start_z )
            continue;
        
end_x start_x;
        
end_y start_y;
        
end_z start_z;
          break;
    }
    while( ++
distance_between_points );

Example:
PHP код:
new Float:0.0Float:0.0Float:0.0Object CreateObject2000, -10.4548,55.2839,12.16760.00.00.0 );
        
processLineOfSight( -10.4548,55.2839,12.1676x,y,zfalsetrue );
        
MoveObject(Objectx,y,z,3.0); 
Additional features:

native IsValidVehicle(vehicleid);
plugin MapAndreas: https://sampforum.blast.hk/showthread.php?tid=275492

Preview:

by Seregamil
Reply

Why use someone else's library, where a lot of unnecessary code when there is a head on your shoulders?
Reply

Just wanted to share a callback "OnPlayerVirtualWorldChange" that iFarbod asked me to do, I didn't bother denying his request as it was just easy.

basically works the same as OnPlayerInteriorChange

pawn Код:
stock pref_SetPlayerVirtualWorld(playerid, worldid)
{
    CallLocalFunction("OnPlayerVirtualWorldChange", "iii", playerid, GetPlayerVirtualWorld(playerid), worldid);
    SetPlayerVirtualWorld(playerid, worldid);  
    return 1;
}

#if defined _ALS_SetPlayerVirtualWorld
    #undef SetPlayerVirtualWorld
#else
    #define _ALS_SetPlayerVirtualWorld
#endif
 
#define SetPlayerVirtualWorld pref_SetPlayerVirtualWorld

forward OnPlayerVirtualWorldChange(playerid, oldworldid, newworldid);
Backup Source: https://gist.github.com/pds2k12/1134a1c5c9f98ae4b397
Reply

Hi!

I need a function that generates a random maze.

Java rewrite of something tried this, but did not agree to Java. (Tremaux's Algorithm)
Reply

@RCON1: Are you trying to make the code hard to read on purpose?
Reply

If your computer doesn't allow SA-MP to use file permissions, which can result in /save not working, here's a command that will save your position, or camera into a file (scriptfiles/debug.txt). This can also be helpful to get positions for SetPlayerCameraPos and SetPlayerCameraLookAt.

pawn Код:
CMD:dsave(playerid, params[])
{
    new swhat[12], string[126], desc[126], Float:X, Float:Y, Float:Z, Float:A, vw = GetPlayerVirtualWorld(playerid), interior = GetPlayerInterior(playerid);
    if(sscanf(params, "s[12]s[126]", swhat, desc)) return SendClientMessage(playerid, -1, "DEBUG: /dsave [position / camera] [description]");
   
    if(strcmp(swhat, "position", true) == 0)
    {
        if(GetPlayerState(playerid) == PLAYER_STATE_DRIVER || GetPlayerState(playerid) == PLAYER_STATE_PASSENGER)
        {
            new File:fdebug = fopen("debug.txt", io_append);
            new vehicleid = GetPlayerVehicleID(playerid);
            GetVehiclePos(vehicleid, X, Y, Z);
            GetVehicleZAngle(vehicleid, A);
            format(string, sizeof(string), "VEHICLE POSITION: %f, %f, %f, %f // %s\r\n", X, Y, Z, A, desc);
            fwrite(fdebug, string);
            fclose(fdebug);
            SendClientMessage(playerid, -1, "DEBUG: Your vehicles position has been saved to debug.txt");
            return 1;
        }
        else if(GetPlayerState(playerid) == PLAYER_STATE_ONFOOT)
        {
            new File:fdebug = fopen("debug.txt", io_append);
            GetPlayerPos(playerid, X, Y, Z);
            GetPlayerFacingAngle(playerid, A);
            format(string, sizeof(string), "ON FOOT POSITION: %f, %f, %f, %f, %d, %d // %s\r\n", X, Y, Z, A, vw, interior, desc);
            fwrite(fdebug, string);
            fclose(fdebug);
            SendClientMessage(playerid, -1, "DEBUG: Your on-foot position has been saved to debug.txt");
            return 1;
        }
        else
        {
            SendClientMessage(playerid, -1, "DEBUG: You are not on-foot or in any vehicle.");
            return 1;
        }
    }
    else if(strcmp(swhat, "camera", true) == 0)
    {
        new File:fdebug = fopen("debug.txt", io_append);
        new Float: x2, Float: y2, Float: z2, Float:x3, Float: y3, Float:z3;
        GetPlayerCameraPos(playerid, X, Y, Z);
        GetPlayerCameraFrontVector(playerid, x2, y2, z2);
        format(string, sizeof(string), "CAMERA POSITION: %f, %f, %f // %s\r\n", X, Y, Z, desc);
        fwrite(fdebug, string);
        const Float:fScale = 1.0;
        x3 = X + floatmul(x2, fScale);
        y3 = Y + floatmul(y2, fScale);
        z3 = Z + floatmul(z2, fScale);
        format(string, sizeof(string), "CAMERA LOOKAT: %f, %f, %f // %s\r\n", x3, y3, z3, desc);
        fwrite(fdebug, string);
        fclose(fdebug);
        SendClientMessage(playerid, -1, "DEBUG: Your camera position and lookat has been saved.");
        return 1;
    }
    else
    {
        SendClientMessage(playerid, -1, "DEBUG: /dsave [position / camera] [description]");
    }
    return 1;
}
Reply

haha nice find.
should be either: #define isUpper(%0) (!isLower(%0))
or
#define isUpper(%0) (!((%0>=97)&&(%0<=122)))
Reply

That would not work though, ASCII characters aren't entirelly upper & lower case characters. 65-90 are the uppercase letters and 97 through 122 are the lower cars ones.
Reply

That is cool, but the case bit doesn't work properly, only when converting from upper to lower, or vice versa. The number 1 (ASCII: 49) does have a "case bit" even though it is a number. If, however, you know the character IS a letter, then you can do an easy check with AND'ing 32.
Reply

This is a deeply recursive function:
pawn Код:
stock ack(m, n) {return (m == 0)?(n+1):((n == 0)?ack(m-1, 1):ack(m-1, ack(m, n-1)));}
Documentation:
http://en.wikipedia.org/wiki/Ackermann_function

Test script:
pawn Код:
#include <a_samp>

stock ack(m, n) {return (m == 0)?(n+1):((n == 0)?ack(m-1, 1):ack(m-1, ack(m, n-1)));}

main()
{
    for(new i = 0; i < 5; i++) for(new j = 0; j < 5; j++) printf("ack(%d, %d) equals %d.", i, j, ack(i, j));
}
Don't do "ack(4, 1)"
Код:
ack(0, 0) equals 1.
ack(0, 1) equals 2.
ack(0, 2) equals 3.
ack(0, 3) equals 4.
ack(0, 4) equals 5.
ack(1, 0) equals 2.
ack(1, 1) equals 3.
ack(1, 2) equals 4.
ack(1, 3) equals 5.
ack(1, 4) equals 6.
ack(2, 0) equals 3.
ack(2, 1) equals 5.
ack(2, 2) equals 7.
ack(2, 3) equals 9.
ack(2, 4) equals 11.
ack(3, 0) equals 5.
ack(3, 1) equals 13.
ack(3, 2) equals 29.
ack(3, 3) equals 61.
ack(3, 4) equals 125.
ack(4, 0) equals 13.
[debug] Run time error 3: "Stack/heap collision (insufficient stack size)"
ouch!

Tested at http://slice-vps.nl:7070/
Reply

Quote:
Originally Posted by BigETI
Посмотреть сообщение
This is a deeply recursive function:
pawn Код:
stock ack(m, n) {return (m == 0)?(n+1):((n == 0)?ack(m-1, 1):ack(m-1, ack(m, n-1)));}
Documentation:
http://en.wikipedia.org/wiki/Ackermann_function

Test script:
pawn Код:
#include <a_samp>

stock ack(m, n) {return (m == 0)?(n+1):((n == 0)?ack(m-1, 1):ack(m-1, ack(m, n-1)));}

main()
{
    for(new i = 0; i < 5; i++) for(new j = 0; j < 5; j++) printf("ack(%d, %d) equals %d.", i, j, ack(i, j));
}
Don't do "ack(4, 1)"
Код:
ack(0, 0) equals 1.
ack(0, 1) equals 2.
ack(0, 2) equals 3.
ack(0, 3) equals 4.
ack(0, 4) equals 5.
ack(1, 0) equals 2.
ack(1, 1) equals 3.
ack(1, 2) equals 4.
ack(1, 3) equals 5.
ack(1, 4) equals 6.
ack(2, 0) equals 3.
ack(2, 1) equals 5.
ack(2, 2) equals 7.
ack(2, 3) equals 9.
ack(2, 4) equals 11.
ack(3, 0) equals 5.
ack(3, 1) equals 13.
ack(3, 2) equals 29.
ack(3, 3) equals 61.
ack(3, 4) equals 125.
ack(4, 0) equals 13.
[debug] Run time error 3: "Stack/heap collision (insufficient stack size)"
ouch!

Tested at http://slice-vps.nl:7070/
That's quite interesting, but how is that recursive mess useful for SA-MP?
Reply

Removed.
Reply

Removed
Reply

Removed
Reply

pawn Код:
stock Hash(string[])
{
    new const len = strlen(string);
    new s[2] = {2, 5};
    s[1] *= len;
    new str1[40];
    new str2[3];

    for(new i = 0; i < len; i++)
    {
        s[0] += (string[i] & ((i+2) ^ len));
        format(str2, sizeof(str2), "%x", s[1] += (s[0] * 4));
        strcat(str1, str2);
    }
    return str1;
}

Works something similar as Whirlpool.
Reply

Anti-skinbot (a.k.a Pro-Aim.cs - not 100% accurate, could fail at high pings):


pawn Код:
public OnPlayerTakeDamage(playerid, issuerid, Float:amount, weaponid)
{
    if(weaponid == 22 || weaponid == 23 || weaponid == 24 || weaponid == 25 || weaponid == 26 || weaponid == 27 || weaponid == 28 || weaponid == 29 || weaponid == 30 || weaponid == 31 ||
       weaponid == 33 || weaponid == 34 || weaponid == 35 || weaponid == 36 || // I'm not sure if it returns sniper Z coord correctly because I haven't tried it, just remove this line if it doesn't work
       weaponid == 38)
    {
        //if playerid is 1.1 units away from issuerid and deals damage on playerid with a gun, player uses skinbot
        new Float:x, Float:y, Float:z;
        GetPlayerPos(playerid, x, y, z);
        if(!IsPlayerAimingAt(issuerid, x, y, z, 1.1)) //1.1 is the shot radius, modify it if it's not accurate enough
        {
            SendClientMessageToAll(-1, "Skinbot");
            //maybe send a warning to an admin
        }
    }
}
Required functions:

pawn Код:
Float:DistanceCameraTargetToLocation(Float:CamX, Float:CamY, Float:CamZ, Float:ObjX, Float:ObjY, Float:ObjZ, Float:FrX, Float:FrY, Float:FrZ)
{
    new Float:TGTDistance;

    TGTDistance = floatsqroot((CamX - ObjX) * (CamX - ObjX) + (CamY - ObjY) * (CamY - ObjY) + (CamZ - ObjZ) * (CamZ - ObjZ));

    new Float:tmpX, Float:tmpY, Float:tmpZ;

    tmpX = FrX * TGTDistance + CamX;
    tmpY = FrY * TGTDistance + CamY;
    tmpZ = FrZ * TGTDistance + CamZ;

    return floatsqroot((tmpX - ObjX) * (tmpX - ObjX) + (tmpY - ObjY) * (tmpY - ObjY) + (tmpZ - ObjZ) * (tmpZ - ObjZ));
}

stock Float:GetPointAngleToPoint(Float:x2, Float:y2, Float:X, Float:Y)
{
    new Float:DX, Float:DY;
    new Float:angle;

    DX = floatabs(floatsub(x2,X));
    DY = floatabs(floatsub(y2,Y));

    if (DY == 0.0 || DX == 0.0) {
    if(DY == 0 && DX > 0) angle = 0.0;
    else if(DY == 0 && DX < 0) angle = 180.0;
    else if(DY > 0 && DX == 0) angle = 90.0;
    else if(DY < 0 && DX == 0) angle = 270.0;
    else if(DY == 0 && DX == 0) angle = 0.0;
    }
    else {
    angle = atan(DX/DY);

    if(X > x2 && Y <= y2) angle += 90.0;
    else if(X <= x2 && Y < y2) angle = floatsub(90.0, angle);
    else if(X < x2 && Y >= y2) angle -= 90.0;
    else if(X >= x2 && Y > y2) angle = floatsub(270.0, angle);
    }

    return floatadd(angle, 90.0);
}

stock GetXYInFrontOfPoint(&Float:x, &Float:y, Float:angle, Float:distance)
{
    x += (distance * floatsin(-angle, degrees));
    y += (distance * floatcos(-angle, degrees));
}

stock IsPlayerAimingAt(playerid, Float:x, Float:y, Float:z, Float:radius)
{
    new Float:camera_x,Float:camera_y,Float:camera_z,Float:vector_x,Float:vector_y,Float:vector_z;
    GetPlayerCameraPos(playerid, camera_x, camera_y, camera_z);
    GetPlayerCameraFrontVector(playerid, vector_x, vector_y, vector_z);

    new Float:vertical, Float:horizontal;

    switch (GetPlayerWeapon(playerid)) {
      case 34,35,36: {
      if (DistanceCameraTargetToLocation(camera_x, camera_y, camera_z, x, y, z, vector_x, vector_y, vector_z) < radius) return true;
      return false;
      }
      case 30,31: {vertical = 4.0; horizontal = -1.6;}
      case 33: {vertical = 2.7; horizontal = -1.0;}
      default: {vertical = 6.0; horizontal = -2.2;}
    }

    new Float:angle = GetPointAngleToPoint(0, 0, floatsqroot(vector_x*vector_x+vector_y*vector_y), vector_z) - 270.0;
    new Float:resize_x, Float:resize_y, Float:resize_z = floatsin(angle+vertical, degrees);
    GetXYInFrontOfPoint(resize_x, resize_y, GetPointAngleToPoint(0, 0, vector_x, vector_y)+horizontal, floatcos(angle+vertical, degrees));

    if (DistanceCameraTargetToLocation(camera_x, camera_y, camera_z, x, y, z, resize_x, resize_y, resize_z) < radius) return true;
    return false;
}
Functions from this topic.

Could probably be improved by using this.


Reply

Scrambles a string.

Areas of use:
  • Word contests
  • RCON security (e.g. scramble the RCON password every few days).
  • Scramble games (e.g. players get a few minutes to descramble and guess the word).
Code:

pawn Код:
stock strscramble(src[])
{
    new
        dest[128],
        idx,
        j;

    for (new l = strlen(src); idx != l; j ++) if (src[(j = random(l))]) {
        dest[idx++] = src[j];

        src[j] = 0;
    }
    return dest;
}
This is as efficient as I could make it, without heavy use of arrays or similar.
Reply

Quote:
Originally Posted by Emmet_
Посмотреть сообщение
This is as efficient as I could make it, without heavy use of arrays or similar.
It could still result in an infinity loop
I suggest that you never return a string with unknown length, what happens if src is bigger than 128 ?
pawn Код:
swap(& var1, & var2) {
    #emit lref.s.pri var1
    #emit lref.s.alt var2
    #emit sref.s.pri var2
    #emit sref.s.alt var1
}

strscramble(src[], dest[], ssize = sizeof src, dsize = sizeof dest) {
    if(dsize < ssize) {
        return false;
    }
    strcat(dest, src, dsize);
    ssize = strlen(src);
    dsize = 0;

    while(dsize != ssize) {
        swap(dest[dsize], dest[dsize + random(ssize - dsize)]);
        dsize++;
    }
    return true;
}
Reply

Quote:
Originally Posted by EnzoMetlc
Посмотреть сообщение
pawn Код:
stock Hash(string[])
{
    new const len = strlen(string);
    new s[2] = {2, 5};
    s[1] *= len;
    new str1[40];
    new str2[3];

    for(new i = 0; i < len; i++)
    {
        s[0] += (string[i] & ((i+2) ^ len));
        format(str2, sizeof(str2), "%x", s[1] += (s[0] * 4));
        strcat(str1, str2);
    }
    return str1;
}

Works something similar as Whirlpool.
I have a hash(slightly better than previous one) function too, but ****** disallowed me to post it.
Reply

Quote:
Originally Posted by RyDeR`
Посмотреть сообщение
Info
Just a simple piece of code which you can to detect IP adresses.
It returns true/1 if it detects a ip otherwise false/0.

Code
pawn Код:
stock stringContainsIP(const szStr[])
{
    new
        iDots,
        i
    ;
    while(szStr[i] != EOS)
    {
        if('0' <= szStr[i] <= '9')
        {
            do
            {
                if(szStr[i] == '.')
                    iDots++;
               
                i++;
            }
            while(('0' <= szStr[i] <= '9') || szStr[i] == '.' || szStr[i] == ':');
        }
        if(iDots > 2)
            return 1;
        else
            iDots = 0;
       
        i++;
    }
    return 0;
}
Usage
Block advertisements:
Under OnPlayerText:
pawn Код:
if(stringContainsIP(text))
{
    new
        szMsg[128]
    ;
    GetPlayerName(playerid, szMsg, MAX_PLAYER_NAME);
   
    format(szMsg, sizeof(szMsg), "%s has been banned due advertising!", szMsg);
    SendClientMessageToAll(0xFF0000FF, szMsg);
    Ban(playerid);
   
    return 0;
}
This will ban the player if he writes an IP adress like 78.22.66.22:7777 (doesn't matter which IP)
This is pretty old, but just want to point out that using that stock under OnPlayerText has a minor bug.

Try typing three words, the first word with 1 character, the second word with 3 characters, and the last word with 1 character and a number. If you are sending texts with the playerid, the ID of the player won't be sent. Also if you try printing those 3 words in the console they won't print neither.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)