Log in

View Full Version : Useful Function Thread (Frequently updated)



Lorenc
06-26-2011, 07:48 AM
Useful Function Thread

FAQ
How do I get the compiler set?

Well, I made a re-upload of the compiler, comes with the IDE, includes and new.pwn
Works on compiling and is great to use click here (https://solidfiles.com/d/3cb71/) to obtain it.


ReturnPlayerName
Adding a player name to a formatted sentence



#if !defined MAX_PLAYER_NAME
#define MAX_PLAYER_NAME 24 // 24 Characters, I don't know the limit yet...
#endif

stock ReturnPlayerName(clientid)
{
new name[MAX_PLAYER_NAME];
GetPlayerName(clientid, name);
return name;
}


Usage:

printf("%s(%d) is cool", ReturnPlayerName(clientid), clientid);

Efficent Variable creator
Lowers the bytes of a single array created



#define MAX_PLAYERS 24 // Server slots

#define Variable:%1<%2> %1[%2 char]

new
Variable: Hey < MAX_PLAYERS >;


Full explanation by Slice, Couldn't explain it very well.. I guess lol

Explanation:


[indent]PAWN has a feature for accessing single bytes in arrays, intended for use with packed strings. Most SA-MP natives doesn't cover packed strings, though. :(
You can, however, utilize these arrays a lot for memory optimization. A normal array can store values between -2,147,483,648 and 2,147,483,647; you don't always need that capacity, do you?
With packed strings you can store values between 0-255 (yes, no negative values; -1 will wrap to 255). When you know you don't need negative values and won't ever exceed 255, why not save some memory?

new bool:g_IsPlayerSomething[ MAX_PLAYERS ]; // 500 cells * 4 bytes per cell = 2000 bytes!
new bool:g_IsPlayerSomething[ MAX_PLAYERS char ]; // 500 bytes = .. 500 bytes!

If you use "char arrays" instead of normal ones where needed 50 times you'll save 75,000 bytes (~73 kb).

Note!
When accessing these arrays, you need to use curly brackets (aka braces) as opposed to the normal square brackets.
Example:
public OnPlayerConnect( clientID)
{
g_IsPlayerSomething{ clientID} = false;
// ^ ^
}

GetPlayerPosFixed
Gathers a player position the more simple way.



stock GetPlayerPosFixed(playerid, &Float:X, &Float:Y, &Float:Z)
{
X = GetPlayerPos(playerid, X_AXIS);
Y = GetPlayerPos(playerid, Y_AXIS);
Z = GetPlayerPos(playerid, Z_AXIS);
}

Usage:



new Float: X, Float: Y, Float: Z;
GetPlayerPosFixed(clientID, X, Y, Z);
printf("Client %d is at the location X: %0.3f Y: %0.3f Z: %0.3f", clientID, X, Y, Z);


IsPlayerInRangeOfPoint
If a player is near a point from a radius set.


stock IsPlayerInRangeOfPoint(playerid, Float:radi, Float:x, Float:y, Float:z)
{
new Float:oldposx, Float:oldposy, Float:oldposz, Float:tempposx, Float:tempposy, Float:tempposz;
oldposx = GetPlayerPos(playerid, X_AXIS), oldposy = GetPlayerPos(playerid, Y_AXIS), oldposz = GetPlayerPos(playerid, Z_AXIS);
tempposx = (oldposx -x), tempposy = (oldposy -y), tempposz = (oldposz -z);
if (((tempposx < radi) && (tempposx > -radi)) && ((tempposy < radi) && (tempposy > -radi)) && ((tempposz < radi) && (tempposz > -radi))) return true;
return false;
}


Usage:



//A callback
if(IsPlayerInRangeOfPoint(clientID, 10.0, 0.0, 0.0, 0.0)) // If a player is near a point
{
//do your code..
printf("ID: %d is at the location X: 0.0 Y: 0.0 Z: 0.0 within the radius of 10.0", clientID);
}

foxtacles
06-26-2011, 05:30 PM
Which I am sorry if I am not allowed to do so.

Stickied, thanks for creating such a thread ;)


// 24 Characters, I don't know the limit yet...

16 characters, but I might raise this limit later. ReturnPlayerName is indeed a nice snippet, should work without any problem ;)



#define MAX_PLAYERS 24 // Server slots

#define Variable:%1<%2> %1[%2 char]

new
Variable: Hey < MAX_PLAYERS >;


Never tried that myself, but if it works, it would in fact be very efficient. Thanks for the hint :D

ArathHunter
06-26-2011, 11:01 PM
16 player Limit? I saw the test server with 32 player limit. Though It said not to use and use the other servers... I was pretty tempted to join anyway when I saw 2 people already in xD

EDIT: Which btw, How did that work out?

Lorenc
06-26-2011, 11:10 PM
Thanks.. Updated the thread with a quote from a guy explaining CHAR arrays

foxtacles
06-27-2011, 05:25 PM
16 player Limit?

16 characters per player name ;) The max-playercount is unknown up until now.

ArathHunter
06-28-2011, 01:22 AM
Oooooooh..... heh....heheh xD

Lorenc
07-22-2011, 01:54 PM
Added a upload of the compiler set, contains pawno.exe, the main IDE of PAWN and includes new.pwn along with the includes.

Lorenc
07-25-2011, 08:51 AM
Another function added: GetPlayerPosFixed(playerid, &Float:X, &Float:Y, &Float:Z)

The design of the thread has been changed (colors) for a much neater and understandable look.

Dantiko
08-09-2011, 09:04 PM
Umm, the 32 player server is 999 ping, too laggy.Well its only test, the internet is supposed to suck because we don't have servers around the globe yet.

foxtacles
08-09-2011, 09:30 PM
999 ping usually means that the mod failed to ping the server (I have to change that 999 to something else). The only "official" servers are those named "vaultmp 0.1a testserver", you should be able to properly ping them :D

BTW, the next revision will come with the updated version of PAWN. Scripters may want to check this: https://www.compuphase.com/pawn/pawnhistory.htm

Dantiko
08-09-2011, 10:02 PM
Also something you must add before launching the next version, the 32 player server said there were 0 players, when I entered I saw a guy, and I killed him, also, the same thing happened on the 0.1 test server, the same guy, but he disappeared.IDK maybe he entered after me in the server.

Kar
08-19-2011, 08:13 AM
999 ping usually means that the mod failed to ping the server (I have to change that 999 to something else). The only "official" servers are those named "vaultmp 0.1a testserver", you should be able to properly ping them :D

BTW, the next revision will come with the updated version of PAWN. Scripters may want to check this: https://www.compuphase.com/pawn/pawnhistory.htm


it's 16 bit right? most likely. change it to 65535

Lorenc
08-19-2011, 04:38 PM
999 ping usually means that the mod failed to ping the server (I have to change that 999 to something else). The only "official" servers are those named "vaultmp 0.1a testserver", you should be able to properly ping them :D

BTW, the next revision will come with the updated version of PAWN. Scripters may want to check this: https://www.compuphase.com/pawn/pawnhistory.htm


TBH, I wouldn't even wanna move to the new PAWN they're currently on. They've removed so many great things like enumerators. Not really sure it if it's true but I'd recommend using the PAWN version that was made about 5 - 3 years ago.

Kar
08-26-2011, 10:50 PM
999 ping usually means that the mod failed to ping the server (I have to change that 999 to something else). The only "official" servers are those named "vaultmp 0.1a testserver", you should be able to properly ping them :D

BTW, the next revision will come with the updated version of PAWN. Scripters may want to check this: https://www.compuphase.com/pawn/pawnhistory.htm


TBH, I wouldn't even wanna move to the new PAWN they're currently on. They've removed so many great things like enumerators. Not really sure it if it's true but I'd recommend using the PAWN version that was made about 5 - 3 years ago.


to use an enum in the lastest pawn, just replace "enum ..." with "const ..."

is it so hard?


stock Times_String_Repeated( strSrc[], strWhat[], bool:casesensitive = true)
{
new Times = 0, pos = -1;
while((pos = strfind(strSrc, strWhat, casesensitive, (pos + 1))) != -1) Times ++;
return Times;
}

stock getDigits(const value, strDig[]) //by RyDeR`
{
valstr(strDig, value, true);
for(new i; strDig{i} != EOS; ++i) strDig{i} -= '0';
}

stock explode(const sSource[], aExplode[][], const sDelimiter[] = " ", iVertices = sizeof aExplode, iLength = sizeof aExplode[])//not by me
{
new iNode, iPointer, iPrevious = -1, iDelimiter = strlen(sDelimiter);
while(iNode < iVertices)
{
iPointer = strfind(sSource, sDelimiter, false, iPointer);
if(iPointer == -1)
{
strmid(aExplode[iNode], sSource, iPrevious, strlen(sSource), iLength);
break;
}
else strmid(aExplode[iNode], sSource, iPrevious, iPointer, iLength);
iPrevious = (iPointer += iDelimiter);
++iNode;
}
return iPrevious;
}
stock SplitEx(strsrc[], strdest[][], delimiter) // Credits to original author
{
new i, li, aNum, len;
while(i <= strlen(strsrc))
{
if(strsrc[i] == delimiter || i == strlen(strsrc))
{
len = strmid(strdest[aNum], strsrc, li, i, 92);
strdest[aNum][len] = 0;
li = i + 1;
aNum++;
}
i++;
}
return 1;
}
stock StripStringOfNonNumbers(string[], const ichar[] = "", const size = sizeof ichar)
{
new c, i, j, idx, length = strlen(string);
for( ; i != length; ++i) {
c = string[i];
if('0' <= c <= '9') string[idx++] = c;
else {
for(j = size - 1; j != -1; --j) {
if(c == ichar[j]) {
string[idx++] = c;
break;
}
}
}
}
string[idx] = EOS;
return false;
}

stock bool:str_in_array(const sNeedle[], const aHaystack[][], const iHaystack = sizeof aHaystack)//by westie
{
new iNode = 0;
while(iNode < iHaystack)
{
if(!strcmp(sNeedle, aHaystack[iNode], true)) return true;
++iNode;
}
return false;
}
stock PlayerInsert(text[], rchar = '%')
{
new length = strlen(text);
for(new a = 0; a < length; a++)
{
if(text[a] == rchar && IsCharNumeric(text[a+1]) && text[a+1] != EOS)
{
if(IsPlayerConnected(strval(text[a+1])))
{
strdel(text[a], 0, 2);
strins(text[a], Playername(strval(text[a+1])), 0);
}
}
}
}

Aeronix
08-27-2011, 01:52 AM
999 ping usually means that the mod failed to ping the server (I have to change that 999 to something else). The only "official" servers are those named "vaultmp 0.1a testserver", you should be able to properly ping them :D

BTW, the next revision will come with the updated version of PAWN. Scripters may want to check this: https://www.compuphase.com/pawn/pawnhistory.htm


TBH, I wouldn't even wanna move to the new PAWN they're currently on. They've removed so many great things like enumerators. Not really sure it if it's true but I'd recommend using the PAWN version that was made about 5 - 3 years ago.


to use an enum in the lastest pawn, just replace "enum ..." with "const ..."

is it so hard?


stock Times_String_Repeated( strSrc[], strWhat[], bool:casesensitive = true)
{
new Times = 0, pos = -1;
while((pos = strfind(strSrc, strWhat, casesensitive, (pos + 1))) != -1) Times ++;
return Times;
}

stock getDigits(const value, strDig[]) //by RyDeR`
{
valstr(strDig, value, true);
for(new i; strDig{i} != EOS; ++i) strDig{i} -= '0';
}

stock explode(const sSource[], aExplode[][], const sDelimiter[] = " ", iVertices = sizeof aExplode, iLength = sizeof aExplode[])//not by me
{
new iNode, iPointer, iPrevious = -1, iDelimiter = strlen(sDelimiter);
while(iNode < iVertices)
{
iPointer = strfind(sSource, sDelimiter, false, iPointer);
if(iPointer == -1)
{
strmid(aExplode[iNode], sSource, iPrevious, strlen(sSource), iLength);
break;
}
else strmid(aExplode[iNode], sSource, iPrevious, iPointer, iLength);
iPrevious = (iPointer += iDelimiter);
++iNode;
}
return iPrevious;
}
stock SplitEx(strsrc[], strdest[][], delimiter) // Credits to original author
{
new i, li, aNum, len;
while(i <= strlen(strsrc))
{
if(strsrc[i] == delimiter || i == strlen(strsrc))
{
len = strmid(strdest[aNum], strsrc, li, i, 92);
strdest[aNum][len] = 0;
li = i + 1;
aNum++;
}
i++;
}
return 1;
}
stock StripStringOfNonNumbers(string[], const ichar[] = "", const size = sizeof ichar)
{
new c, i, j, idx, length = strlen(string);
for( ; i != length; ++i) {
c = string[i];
if('0' <= c <= '9') string[idx++] = c;
else {
for(j = size - 1; j != -1; --j) {
if(c == ichar[j]) {
string[idx++] = c;
break;
}
}
}
}
string[idx] = EOS;
return false;
}

stock bool:str_in_array(const sNeedle[], const aHaystack[][], const iHaystack = sizeof aHaystack)//by westie
{
new iNode = 0;
while(iNode < iHaystack)
{
if(!strcmp(sNeedle, aHaystack[iNode], true)) return true;
++iNode;
}
return false;
}
stock PlayerInsert(text[], rchar = '%')
{
new length = strlen(text);
for(new a = 0; a < length; a++)
{
if(text[a] == rchar && IsCharNumeric(text[a+1]) && text[a+1] != EOS)
{
if(IsPlayerConnected(strval(text[a+1])))
{
strdel(text[a], 0, 2);
strins(text[a], Playername(strval(text[a+1])), 0);
}
}
}
}

The syntax is quite different, it is going to be hard to get used to it for him I guess..

Lorenc
08-27-2011, 03:55 PM
999 ping usually means that the mod failed to ping the server (I have to change that 999 to something else). The only "official" servers are those named "vaultmp 0.1a testserver", you should be able to properly ping them :D

BTW, the next revision will come with the updated version of PAWN. Scripters may want to check this: https://www.compuphase.com/pawn/pawnhistory.htm


TBH, I wouldn't even wanna move to the new PAWN they're currently on. They've removed so many great things like enumerators. Not really sure it if it's true but I'd recommend using the PAWN version that was made about 5 - 3 years ago.


to use an enum in the lastest pawn, just replace "enum ..." with "const ..."

is it so hard?


stock Times_String_Repeated( strSrc[], strWhat[], bool:casesensitive = true)
{
new Times = 0, pos = -1;
while((pos = strfind(strSrc, strWhat, casesensitive, (pos + 1))) != -1) Times ++;
return Times;
}

stock getDigits(const value, strDig[]) //by RyDeR`
{
valstr(strDig, value, true);
for(new i; strDig{i} != EOS; ++i) strDig{i} -= '0';
}

stock explode(const sSource[], aExplode[][], const sDelimiter[] = " ", iVertices = sizeof aExplode, iLength = sizeof aExplode[])//not by me
{
new iNode, iPointer, iPrevious = -1, iDelimiter = strlen(sDelimiter);
while(iNode < iVertices)
{
iPointer = strfind(sSource, sDelimiter, false, iPointer);
if(iPointer == -1)
{
strmid(aExplode[iNode], sSource, iPrevious, strlen(sSource), iLength);
break;
}
else strmid(aExplode[iNode], sSource, iPrevious, iPointer, iLength);
iPrevious = (iPointer += iDelimiter);
++iNode;
}
return iPrevious;
}
stock SplitEx(strsrc[], strdest[][], delimiter) // Credits to original author
{
new i, li, aNum, len;
while(i <= strlen(strsrc))
{
if(strsrc[i] == delimiter || i == strlen(strsrc))
{
len = strmid(strdest[aNum], strsrc, li, i, 92);
strdest[aNum][len] = 0;
li = i + 1;
aNum++;
}
i++;
}
return 1;
}
stock StripStringOfNonNumbers(string[], const ichar[] = "", const size = sizeof ichar)
{
new c, i, j, idx, length = strlen(string);
for( ; i != length; ++i) {
c = string[i];
if('0' <= c <= '9') string[idx++] = c;
else {
for(j = size - 1; j != -1; --j) {
if(c == ichar[j]) {
string[idx++] = c;
break;
}
}
}
}
string[idx] = EOS;
return false;
}

stock bool:str_in_array(const sNeedle[], const aHaystack[][], const iHaystack = sizeof aHaystack)//by westie
{
new iNode = 0;
while(iNode < iHaystack)
{
if(!strcmp(sNeedle, aHaystack[iNode], true)) return true;
++iNode;
}
return false;
}
stock PlayerInsert(text[], rchar = '%')
{
new length = strlen(text);
for(new a = 0; a < length; a++)
{
if(text[a] == rchar && IsCharNumeric(text[a+1]) && text[a+1] != EOS)
{
if(IsPlayerConnected(strval(text[a+1])))
{
strdel(text[a], 0, 2);
strins(text[a], Playername(strval(text[a+1])), 0);
}
}
}
}


hahaha Didn't relise. I'll add those functions soon though

Kar
08-31-2011, 04:55 AM
999 ping usually means that the mod failed to ping the server (I have to change that 999 to something else). The only "official" servers are those named "vaultmp 0.1a testserver", you should be able to properly ping them :D

BTW, the next revision will come with the updated version of PAWN. Scripters may want to check this: https://www.compuphase.com/pawn/pawnhistory.htm


TBH, I wouldn't even wanna move to the new PAWN they're currently on. They've removed so many great things like enumerators. Not really sure it if it's true but I'd recommend using the PAWN version that was made about 5 - 3 years ago.


to use an enum in the lastest pawn, just replace "enum ..." with "const ..."

is it so hard?


stock Times_String_Repeated( strSrc[], strWhat[], bool:casesensitive = true)
{
new Times = 0, pos = -1;
while((pos = strfind(strSrc, strWhat, casesensitive, (pos + 1))) != -1) Times ++;
return Times;
}

stock getDigits(const value, strDig[]) //by RyDeR`
{
valstr(strDig, value, true);
for(new i; strDig{i} != EOS; ++i) strDig{i} -= '0';
}

stock explode(const sSource[], aExplode[][], const sDelimiter[] = " ", iVertices = sizeof aExplode, iLength = sizeof aExplode[])//not by me
{
new iNode, iPointer, iPrevious = -1, iDelimiter = strlen(sDelimiter);
while(iNode < iVertices)
{
iPointer = strfind(sSource, sDelimiter, false, iPointer);
if(iPointer == -1)
{
strmid(aExplode[iNode], sSource, iPrevious, strlen(sSource), iLength);
break;
}
else strmid(aExplode[iNode], sSource, iPrevious, iPointer, iLength);
iPrevious = (iPointer += iDelimiter);
++iNode;
}
return iPrevious;
}
stock SplitEx(strsrc[], strdest[][], delimiter) // Credits to original author
{
new i, li, aNum, len;
while(i <= strlen(strsrc))
{
if(strsrc[i] == delimiter || i == strlen(strsrc))
{
len = strmid(strdest[aNum], strsrc, li, i, 92);
strdest[aNum][len] = 0;
li = i + 1;
aNum++;
}
i++;
}
return 1;
}
stock StripStringOfNonNumbers(string[], const ichar[] = "", const size = sizeof ichar)
{
new c, i, j, idx, length = strlen(string);
for( ; i != length; ++i) {
c = string[i];
if('0' <= c <= '9') string[idx++] = c;
else {
for(j = size - 1; j != -1; --j) {
if(c == ichar[j]) {
string[idx++] = c;
break;
}
}
}
}
string[idx] = EOS;
return false;
}

stock bool:str_in_array(const sNeedle[], const aHaystack[][], const iHaystack = sizeof aHaystack)//by westie
{
new iNode = 0;
while(iNode < iHaystack)
{
if(!strcmp(sNeedle, aHaystack[iNode], true)) return true;
++iNode;
}
return false;
}
stock PlayerInsert(text[], rchar = '%')
{
new length = strlen(text);
for(new a = 0; a < length; a++)
{
if(text[a] == rchar && IsCharNumeric(text[a+1]) && text[a+1] != EOS)
{
if(IsPlayerConnected(strval(text[a+1])))
{
strdel(text[a], 0, 2);
strins(text[a], Playername(strval(text[a+1])), 0);
}
}
}
}

The syntax is quite different, it is going to be hard to get used to it for him I guess..


It's not that much updated, you can really make a enum using 2 (3?) different ways now, all you have to do is get the enum finished, the easiest way would be to just replace enum with const and there you go, no need to change the main variable

Dantiko
08-31-2011, 05:10 PM
Hm, will there be save data(server side)?

Lorenc
09-01-2011, 02:06 PM
Hm, will there be save data(server side)?


No, you will need to script that using the file functions. I hope to release a simple file writer soon.

NeoPhoenix
10-03-2011, 11:35 AM
#if !defined MAX_PLAYER_NAME
#define MAX_PLAYER_NAME 24 // 24 Characters, I don't know the limit yet...
#endif
stock ReturnPlayerName(clientid)
{
new name[MAX_PLAYER_NAME];
GetPlayerName(clientid, name);
return name;
}

Would be better so store it in a global variable and check the name while connecting

Lorenc
10-03-2011, 06:05 PM
#if !defined MAX_PLAYER_NAME
#define MAX_PLAYER_NAME 24 // 24 Characters, I don't know the limit yet...
#endif
stock ReturnPlayerName(clientid)
{
new name[MAX_PLAYER_NAME];
GetPlayerName(clientid, name);
return name;
}

Would be better so store it in a global variable and check the name while connecting


That function hasn't been updated in days!



#if !defined MAX_PLAYER_NAME
#define MAX_PLAYER_NAME 24 // 24 Characters, I don't know the limit yet...
#endif
new name{MAX_PLAYER_NAME};

stock ReturnPlayerName(clientid)
{
GetPlayerName(clientid, name);
return name;
}



Uses packed strings however, my laziness bumps me out of my I'm going to update the thread :/


Post your functions in the thread as well ;D

foxtacles
10-03-2011, 06:18 PM
GetPlayerName is now

https://wiki.vaultmp.com/index.php/GetName

MAX_PLAYER_NAME is

https://wiki.vaultmp.com/index.php/MAX_PLAYER_NAME

:D

Lorenc
10-06-2011, 05:46 AM
GetPlayerName is now

https://wiki.vaultmp.com/index.php/GetName

MAX_PLAYER_NAME is

https://wiki.vaultmp.com/index.php/MAX_PLAYER_NAME

:D


Yay! Can you soon bring some functions that set a certain index?

Like for example:

SetPlayerPos(playerid, Float: X, Float: Y, Float: Z);