Dynamic number of arguments in functions

For scripting examples for learning how to use AMXX.
User avatar
Archive-Poster
Posts: 1189
Gender:
United States of America

Dynamic number of arguments in functions

Post by Archive-Poster »

Well we all know how to create a function but what about a function that uses dynamic number of parameters.
I recommend not reading if you do not have basic scripting knowledge.

Code: Select all

public function_add(num1, num2, result)
{
    result = num1 + num2
} 
But how can we create a function that uses a dynamic set of parameters?
Well the answer is simple you just need to use these functions:
numargs
getarg
setarg

For example for the function that we made above we can do something like this:

Code: Select all

public function_add( ... )
{
    // For reading the first argument you must always use getarg(0)
    // It starts with 0
    setarg(2, getarg(0)+getarg(1))
} 
As you see this function does not contain any arguments at all just dots.
That means that the number of parameters can vary.

Is this limited only to integer values?
No you can also copy vectors, strings, and Float values.
Here is a basic example

Float example:

Code: Select all

public function_mean( ... )
{
    // You need to pass the first 2 arguments as float values or else this calculation
    // Will be messed up
    // Also the third parameter is a integer (normal value)
    setarg(2, floatround((Float:getarg(1)+Float:getarg(0)) / 2.0))
} 
String example:

Code: Select all

// We think that the string is in the first argument
public function_copystring( ... )
{
    // position is the index that allows us to copy each cell of the string or array
    // len is the maximum character capacity of the string
    // string represents the array where we store text messages
    // ch is the character, the place where we will hold the value (just to avoid more calls)
    new position, ch, string[100], len
    len = charsmax(string)
    
    // We are testing to see if we reached the maximum capacity of the string, and also see if we get a value from the string that we are trying to read.
    while ( (position < len) && (ch = getarg(0, position)) )
    {
        // Store the ch value
        string[position] = ch
        // Increment the position for allowing the next cell to load
        position++;
    }
    
    // We need to do this because the string the ending character
    string[position] = '^0';
    position++;
    
    // Now that we have the string copied, print it to the server
    server_print(string)
} 
How is this useful?
Well for example I used it to create a way for sending text messages more easily.

This is what my function looks like:

Code: Select all

/* This function uses a different system of getting arguments see funcwiki for details
*  Params:
*  - id, player id
*  - print_type (ex: print_chat, print_center, etc.) 
*  - string to send to player (ex: #Alias_Not_Avail)
*  - the rest, more strings, see cstrike_english.txt to see how much strings you need in this message (you need to count the "%s" parts coresponding a tag)
* 
*  Return:
*  - None.
*/

sendTxtMsg(any: ...)
{
    new numstring = numargs() - 2
    new string[100]
    new pos, ch, totalchars = charsmax(string)
    
    message_begin(MSG_ONE, get_user_msgid("TextMsg"), _, getarg(0))
    write_byte(getarg(1))
    
    for (new i=0; i < numstring; i++)
    {
        // Here we copy the sting that we want to send to a player
        pos = 0;
        while (pos < totalchars && (ch = getarg(2 + i, pos))) 
        {
            string[pos++] = ch
        }
        
        // Add ending to the string (necessary)
        string[pos++] = '^0';
        
        //server_print("STRING %s", string)
        // Send it!
        write_string(string)
    }
    
    // End the function chain
    message_end()
} 
And now I can easily transmit every client message easily.
For example instead of writing:

Code: Select all

    message_begin(MSG_ONE, get_user_msgid("TextMsg"), _, id);
    write_byte(print_center);
    write_string("#Alias_Not_Avail");
    write_string("Item");
    message_end();


I use it like this:

Code: Select all

sendTxtMsg(id, print_center, "#Alias_Not_Avail", "Item") 
And the beauty of it is that it supports dynamic number of parameters. That means that I do not need to adapt my code for each text message type. I just need to add one more string to the function parameters. So more readable and easier.
Example:

Code: Select all

// For "Cstrike_TitlesTXT_Game_radio"        
// "%s1 (RADIO): %s2"
sendTxtMsg(id, print_center, "#Cstrike_TitlesTXT_Game_radio", "Youpii", "Having fun mate!") 
And I do not need to create another function specially for this.

Who is online

Users browsing this forum: No registered users and 0 guests