Noticias:

Debes de estar registrado para poder ver el contenido indicado. Registrate o Conectate

Menú Principal

Aprendizaje en Pawn

Iniciado por Swarlog, Ene 29, 2023, 08:20 PM

Tema anterior - Siguiente tema

Swarlog

..:: Guía básica para aprender Pawn ::..

- Nivel básico/medio/avanzado -

Introducción:

Hacía rato que no creaba ningún tutorial, y tenía ganas de aportar con algo nuevo y útil, así que se me ocurrió hacer este tutorial.

Bueno en este tutorial, voy a tratar de ayudar a los más nuevos a dar sus primeros pasos con este lenguaje de programación de scripts llamado pawn. Y a aquellos que saben un poco, a que sigan aprendiendo cosas nuevas, o a recordar cosas que se habían olvidado.

Este tutorial va a ir desde lo más básico, hasta cosas un poco avanzadas. Y el objetivo no es otro que no sea aprender.
Espero que les sirva y cualquier error q cometa, háganmelo saber, ya que todos siempre estamos aprendiendo algo y nos podemos equivocar.

Forma de uso:

Primero, antes que se manden a empezar a leer, quiero aclarar, que este tutorial está dividido en 3 niveles: Nivel Básico/Nulo, Medio y Avanzado. Cada nivel consta con conocimientos acorde al nivel propuesto, pero les sugiero a aquellos que no han leído demasiado sobre pawn, que lean desde el principio, aun que tengan los conocimientos, porque lo que se dice en el nivel básico, se da por entendido en los demás niveles y así.

Segundo, lo ideal para que fijen bien los conocimientos sobre este tutorial, seria que cuando aprenden algo nuevo, lo prueben y si no lo terminan de entender o no les sale cuando lo practican, paren y piensen a ver que puede estar mal y si es necesario pregunten y luego cuando lo tengan bien claro, sigan.

Primeros pasos con pawn:

Bueno pawn es un lenguaje muy amplio, pero vamos a ir conociéndolo paso a paso.
Lo primero que vamos a aprender es como almacenar datos en variables/arrays, esto va a ser muy útil y es lo que posiblemente usen más en los scripts que vallan a programar a futuro.

Indice:

  • Introducción
       
  • Forma de uso
       
  • Primeros pasos con pawn
       
  • Indice:
       
  • Nivel Basico/Nulo
    • Variables y Arrays
      • Primeros pasos con variables y arrays
        • ¿Qué es una variable?
        • ¿Qué es un tag, y cuales de variables existen?
        • ¿Cómo definimos una variable con un tag?
        • ¿Qué es un array?
        • ¿Cuales son los tags de los arrays?
        • ¿Cómo defino un array?
      • Tipos de variables/arrays
        • Local
        • Global
    • Operadores
      • Operadores simples
        • ¿Qué es un operador?
        • ¿Cuáles son los Operadores?
    • Expreciones
      • ¿Qué es una expreción?
      • ¿Cuáles son las expreciones que existen y cómo se utilizan?
    • Caracteres Especiales
      • Script
  • Nivel Medio
    • Inicializadores
      • new
        • ¿Cómo se usa new?
        • Cuando usar new
        • Cuando no usar new
      • Enums
        • ¿Qué es un enum?
        • ¿Cómo se define un enum?
        • ¿Qué utilidad tienen los enums?
      • public
        • ¿Qué es y para que sirve public?
        • ¿Cuándo usar public?
      • forward
        • ¿Qué es y para que sirve forward?
        • ¿Cuándo usar forward?
    • Definiciones
      • Los Arrays y sus dimenciones
        • Dimenciones de un array
        • Unidimencional
        • Bidimencional
        • Tridimencional
      • Inicialización
        • ¿Cómo inicializar una variable?
        • ¿Cómo inicializar un array?
    • Operadores
      • Operadores miselaneos
        • {}
        • defined
        • sizeof
        • tagof
        • char
    • Expreciones
      • Bucles(simples) y switch
        • switch, case(simple) y default
        • for
        • do
        • while
      • Loops(infinitos)
    • Directivas
      • Directivas basicas
        • #if, #elseif, #else, #endif
        • #error
        • #assert
        • #include
        • #tryinclude
        • #define
    • Caracteres Especiales
      • Strings
    • Creacion de funciones
      • Funciones Simples
        • ¿Qué es una función?
        • ¿Cómo crear una funcion?
        • Funciones sin parametros
        • Funciones con parametros
        • Funciones con retorno de valores
  • Nivel Avanzado
    • Inicializadores (avanzado)
      • stock
        • ¿Cómo se utiliza?
        • static
                      
        • Local estatica
        • Global estatica
      • const
        • ¿Cómo se declara una variable const?
        • ¿Cuándo se declara una variable const?
      • operator
        • ¿Cómo se utiliza?
    • Operadores
      • Operadores miselaneos
                 
      • Operadores de Bits(manipulacion)
                 
      • Operadores de Bits(Asignación)
    • Expreciones
      • Loops(avanzado), saltos, sleep y state
        • break
        • continue
        • goto
        • sleep
        • state
    • Directivas
      • Directivas avanzadas
        • #define
        • #endinput
        • #pragma
        • amxlimit
        • amxram
        • codepage
        • ctrlchar
        • deprecated
        • dynamic
        • Library
        • pack
        • tabsize
        • unused
        • #undef
    • Creacion de funciones
      • Funciones Complejas
        • Pasar parametros como opcionales
        • Pasar parametros como valor y como referencia
        • Crear funciones con parametros variables
  • Final


[size=+3]Nivel: Básico/Nulo[/size]

[size=+1]Variables y Arrays[/size]

Primeros pasos con variables y arrays

¿Qué es una variable?
La respuesta es muy simple:
Una variable es un pedacito de memoria que se reserva para el programa durante la ejecución del mismo, para almacenar información, que luego usara.

Para definir una variable en pawn, la forma más simple es utilizar "new" y se utiliza de la siguiente forma.

new MiVariable;
Esa sentencia define "MiVariable" como una variable de tipo entero (en ingles integer).

¿Qué es un tag, y cuáles de variables existen?
Un tag es un pedacito de código, que asignación la hora de compilar, brinda información extra sobre la variable que definimos.

Tags:

Float   =>    almacena números enteros y números con coma.
File    =>    almacena el handle de un archivo abierto. (no se preocupen de que es un handle, luego lo explicare).
Bool    =>    almacena true o false, verdadero o falso.
Integer =>    almacena números enteros.

¿Cómo definimos una variable con un tag?

Para definir una variable de tag float o file, lo vamos a hacer de la siguiente forma:
new tag:Nombre;Ejemplos:
   •float:
   new Float:MiFloat;   •file:
   new File:MiFile;   •bool:
   new bool:MyBool;   •integer:
   new MiInteger;   
Ahora, posiblemente se estén preguntando "¿Por qué no se utiliza integer:nombre?", esto es porque pawn por defecto, si no se le especifica, define las variables como integers.

¿Qué es un array?
Para simplificarlo, un array es lo mismo que una variable, pero puede contener una mayor cantidad de datos, en vez de solo 1.

¿Cuales son los tags de los arrays?
Los mismos tags que tienen las variables, y se los especifica de igual forma. "tag:nombre".

¿Cómo defino un array?
La forma de definir un array es muy sencilla, de hecho es = que definir una variable, excepto que tiene una diferencia.

new MiArray[4];
Como pueden ver, solo varia [n]; en este caso, n=4.¿Qué representa "n"? n representa el tamaño de ese array.

!Importante: A la hora de definir un array, debemos tener en cuenta, que este nunca puede tomar el valor de la definición.
Ejemplo:
new Array[5];
Array[5] = 4;//esto causara un error, dado que el índex máximo de Array es 4.
[/color]

Ahora que más o menos tenemos idea de cómo se declara una variable y un array, veremos otras formas de declararlos.

Tipos de variables/arrays:
Estos métodos se aplican tanto para variables como para arrays, así q los mezclare para variar un poco.
Existen 4 tipos, de los cuales ahora veremos los dos más fáciles de aprender.


Local
Definición:
Solo puede ser utilizada dentro del entorno en el cual es declarada(ej.: Callbacks, funciones, etc.). Para declarar una variable/array de este tipo, la declaración debe ser realizada dentro del entorno en el que se desea usar la variable/array.

Ejemplificación:
publica OnPlayerConnect(playerid)
{
new str[36+MAX_PLAYER_NAME], name[MAX_PLAYER_NAME];//declaración del array local
GetPlayerName(playerid, name, sizeof(name));
format(str, sizeof(str), ">>%s(%i) ha ingresado en el servidor", name, playerid);
SendClientMessageToAll(0xFFFF00FF, str);
return 1;
}


Global
Definición:
Puede ser utilizada en todo el proyecto. Para declarar una variable/array de este tipo, debe declararse fuera de cualquier función o callback.

Ejemplificación:
new Connected[MAX_PLAYERS];

publica OnPlayerConnect(playerid)
{
Connected[playerid] = true;
return 1;
}

publica OnPlayerDisconnect(playerid, reason)
{
Connected[playerid] = false;
return 1;
}


!Importante: Tenemos que tener en cuenta, que cuando declaramos una variable/array tanto local, la variable existe dentro de los espacios inferiores, pero no en los superiores.[/b]
ejemplo:
MyFuncion()
{
new var1;
for(new i; i<5; i++){
    //var1 todavía existe.
    new var2;
    printf("%i", var2);
    var2++;
    //var2 todavía existe
}
//var1, todavía existe, pero var2 no existe
}
//var1 no existe.
Ahora que ya sabemos que es una variable, un array y cómo definirlos. iremos con otro tema.



[size=+1]Operadores[/size]

Operadores simples

¿Qué es un operador?
Un operador es un símbolo que se utiliza en expresiones, o bien para realizar una acción.

¿Cuáles son los Operadores?

Aritméticos:
   •A + B   =>  Retorna la suma de A y B.
   •A - B   =>   Retorna la resta de A y B.
   •A * B   =>  Retorna la multiplicación de A y B.
   •A / B   =>  Retorna la división de A y B.
   •A % B   =>  Retorna el resto de la división de A y B.

Asignación:
    •A = B      =>  Asigna a A el valor de B.
      •A ++      =>  Asigna a A el resultado de A+1.
   •A --      =>  Asigna a A el resultado de A-1.
    •A += B   =>  Asigna a A el resultado de A+B.
    •A -= B   =>   Asigna a A el resultado de A-B.
    •A *= B   =>  Asigna a A el resultado de A*B.
    •A /= B   =>  Asigna a A el resultado de A/B.
    •A %= B   =>   Asigna a A el resto de A/B.
   
Racionales(numéricos):
    •A == B   =>    Retorna "true" si A=B, de lo contrario retorna "false".
    •A != B   =>    Retorna "false" si A=B, de lo contrario retorna "true".
    •A < B      => Retorna "true" si A<B, de lo contrario retorna "false".
    •A > B      => Retorna "true" si A>B, de lo contrario retorna "false".
    •A <= B   =>   Retorna "true" si A<=B, de lo contrario retorna "false".
    •A >= B   =>    Retorna "true" si A>=B, de lo contrario retorna "false".
   
Racionales(booleanas):
    •!B      =>    Retorna "true" si B=false, de lo contrario retorna "false".
   •A || B   =>   Retorna "true" si A=true o B=true, de lo contrario retorna "false".
   •A && B   =>    Retorna "true" si A=true y B=true, de lo contrario retorna "false".

Misceláneos:
   •([])   => Se utiliza para la declaración de arrays.



[size=+1]Expresiones[/size]

¿Qué es una expresión?
Una expresión es una combinación de variables/arrays, funciones, que son evaluadas según los parámetros indicados. (si no entienden, no se preocupen, luego entenderán)

¿Cuáles son las expresiones que existen y cómo se utilizan?
Existen 16 expresiones, pero ahora solo veremos algunas. Más adelante veremos las demás.

if
Es una de las expresiones más importantes, se utiliza para comparar, y según el resultado de la comparación, se realiza o no una determinada acción.

Ejemplo1:
publica OnPlayerConnect(playerid){
new rnd = random(2);
if(rnd = 0)SendClientMessage(playerid, 0x00FF00FF, "Bienvenido al servidor");
return 1;
}
Ejemplo2:
publica OnPlayerConnect(playerid){
new rnd = random(2);
if(rnd = 0){
SendClientMessage(playerid, 0xFF0000FF, "Fuera de mi servidor");
Kick(playerid);
}
return 1;
}
!Importante: Cuando el código a ejecutar si la comparación es verdadera es de 1 línea o 1 sentencia (ejemplo1), no es necesario usar brackets, de lo contrario estos se deben colocar(ejemplo2).[/b]

else
Es al igual que if una de las expresiones más importantes, y también una de las más utilizadas. Su uso consiste en el opuesto de if o

Ejemplo:
Estado(playerid)
{
if(IsPlayerConnected(playerid)){
printf("El jugador %i está conectado", playerid);
return 1;
}
else{
printf("El jugador %i esta desconectado", playerid);
return 0;
}
}
assert
Es similar a if, pero si es falso, entonces retorna(fin del callback/función)

Ejemplo:
publica OnFilterScriptInit()
{
new num = 5;
assert(num>0);
printf("%i", num);
return 1;
}
En el ejemplo dado, si la variable num es > 0 entonces escribirá el valor de num en la consola, de lo contrario retornan.

return
Se utiliza para retornar un valor de una función/callback, o bien para salir (de la)/(del) misma/o

Ejemplo:
IsValidPlayer(playerid)
{
if(playerid==INVALID_PLAYER_ID || !IsPlayerConnected(playerid))return false;
return true;
}



[size=+1]Caracteres Especiales[/size]

Script

   •( \ )    =>   Indica que la línea actual, sigue en la de abajo.
   •( ; )   =>   Fin de sentencia.
   
   
   
[size=+3]Nivel: Medio[/size]


[size=+1]Inicializadores[/size]
Bueno ahora vamos a avanzar un poco más allá de las clásicas definiciones y vamos a comprender un poco más sobre este lenguaje de programación de scripts.
Ahora vamos a aprender un poco sobre:
new, enum,  forward y publica.

new

¿Cómo se usa new?
bueno esto no lo vamos a ver, ya que es realmente algo muy básico, y lo explique anteriormente.
Lo que realmente vamos a ver es porque usar new y no otros, es decir vamos a ver el correcto uso de esta sentencia.

La verdad es que no es muy complicado el uso de esta sentencia.
Cuando usar new
   •Si necesitamos declarar una variable/array a nivel local, cuyo contenido pueda cambiar.
   •Si necesitamos declarar una variable/array a nivel global, cuyo contenido pueda cambiar.

Cuando no usar new
   •Para declarar una función.
   •Para declarar un callback.
   •Para declarar un array que no cambiara su contenido.

Enums

¿Qué es un enum?
Básicamente un enum, consiste en una lista.

¿Cómo se define un enum?
Un enum como tal, se define de la siguiente forma:
enum MiEnum{elemento_0, elemento_1, elemento_N};
llevado a la práctica y para más fácil lectura, podemos crear algo así:
enum Lista{
elemento_0,
elemento_1,
elemento_2,
elemento_n
};

¿Qué utilidad tienen los enums?
Generalmente los enums se suelen utilizar para listar datos. El más usado de ellos similar al anterior, para luego obtener los datos y asignarlos en un array

Ejemplo:
enum PD{
Dinero,
Vida,
Armadura,
Advertencias
};
new PlayerInfo[MAX_PLAYERS][PD];


publica

¿Qué es y para qué sirve publica?
Sirve para la declaración de funciones/callbacks o bien variables.

¿Cuándo usar publica?
   •Se utiliza para la declaración de funciones/callbacks que deben ser accesibles desde todos los documentos.
   •También se puede utilizar para la declaración de variables que necesitamos que el host pueda modificar, ya que el host no puede modificar variables declaradas con new.(siempre variables globales)


forward

¿Qué es y para qué sirve forward?
forward le "dice" de cierta forma que la función que se declara luego del mismo, "viene después". Esto es así ya que las funciones estándar declaradas en pawn, no son declaradas hasta su uso.
pero las funciones declaradas como publica, no son estándar y pawn exige la declaración de las mismas antes de su uso. Por eso se usa "forward función(parámetros);"

¿Cuándo usar forward?
Siempre que se declare una función/callback del tipo publica.



[size=+1]Definiciones[/size]

Los Arrays y sus dimensiones

Dimensiones de un array
new Array[5]
Ese array es unidimensional, ¿Qué quiere decir eso? Que solo tiene una dimensión.

¿Puede un array tener más de una dimensión?
Si, puede y pawn soporta hasta tres dimensiones.

Acá les dejo unos "gráficos" simples para que lo puedan entender mejor.

Unidimensional:
new ArrayUnidimencional[5];X
X
X
X
X
Cada una de esas x, puede contener un valor diferente.

Bidimensional:
new ArrayBidimencional[5][2];X X
X X
X X
X X
X X
Cada una de esas x, puede tener un valor diferente, que a su vez contiene otro valor. (Si no lo entienden no se preocupen. luego lo explicare de otra forma)

Tridimensional:
new ArrayTridimencional[5][2][2];

Ahora bien, supongamos que tengo declarado un array así:
new Array[4];
y luego le agrego un valor.
Array[2] = 6;Gráficamente:
X
X
6
X
Ahora, posiblemente, se estén preguntando por qué en la 3 posición? cuando en el índex del array(numero q indica la posición del array a utilizar) es "2".
eso es porque todos los arrays empiezan con el índex 0 y no con el 1.
Gráficamente
[color=red]índex[/color]  0 1 2 3
[color=green]valor[/color]  X X 6 X

otro ejemplo.

new Array[5][2];
Array[2][1] = 5;

Gráficamente:
X X
5 X
X X
X X
X X

Del mismo modo con un array tridimensional. dado que no se puede representar en un plano, les dejo el link a un grafico. para los 3 tipos de arrays (principalmente miren la estructura del tridimensional). Debes de estar registrado para poder ver el contenido indicado. Registrate o Conectate


Inicialización
El concepto de inicialización hace referencia al valor que se le da a una variable/array al crearlo.
por defecto en una variable su valor es "", mientras q en un array cada uno de los valores q puede contener es 0.

¿Cómo inicializar una variable?
La inicialización de una variable es realmente muy simple, consiste en setear el valor correspondiente.

Ejemplo:
new Variable = 5;La variable se inicia en 5.

¿Cómo inicializar un array?
Es un poco más complicado que una variable, pero aun así sigue siendo algo simple.

Ejemplo1:
new Array[10] = {1, 5, 5, 9, 10, 6, 7, 3, 0, 10};Ejemplo2:
new Array[2][3] = {{1, 5, 6}, {4, 2, 7}};En los ejemplos dados anteriormente se inicializan los arrays definidos ya con los valores seteados.
Ejemplo3:
new Array[10] = {1, 2, ...};Esta forma de inicializar un array es = que hacer:
new Array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};Es decir que ... llena los espacios en blanco con el valor de la sucesión que sigue.
new Array[10] = {15, 30, ...};en el ejemplo anterior el Array sería igual a {15, 30, 45, 50, 75, 90, 105, 120, 135, 150}


[size=+1]Operadores[/size]

Operadores misceláneos
   •({})      =>   Se utiliza para la declaración del contenido de arrays.
   •defined    =>  Retorna "true" si la variable indicada fue definida mediante "#define".
   •sizeof()   =>  Retorna el tamaño de un array.
   •tagof()    =>  Retorna el tag de una variable/array.
   •char       =>  Retorna el numero de cells que se necesitan para contener un string compactado.
   
[size=+1]Expresiones[/size]

Bucles(simples) y switch

switch, case(simple) y default
Estas expresiones, van siempre juntas y se utilizan para realizar comparaciones en las cuales se quiere que según el valor, se realice una acción. Puede ser reemplazada por if, else if, else if, else, pero usando if sería más lenta y menos efectiva.

Ejemplo:
switch(variable){
case 0:
print("0");
case 1:
print("1");
case 2:{
print("0");
print("1");
print("2");
}
case 3 .. 10:
print("3-10");
default:
print("variable no es ni 0, ni 1, ni 2, ni 3, ni 4, variable=otro valor");
}

!Importante: cuando luego de la expresión "case" sigue una sola línea, o un if(sin else/else if) la expresión puede ir libre de brakets, de lo contrario es necesario colocarlos.[/b]


for
Es un loop o bucle que consiste en tres pasos. El 1º consiste en la iniciación, el 2º es la comparación y el 3º es la renovación. Cada paso se separa por ";".

Ejemplo:
new playerid;
for(playerid; playerid<GetMaxPlayers(); playerid++){
if(IsPlayerConnected(playerid)){
printf("El jugador con el id %i está conectado", playerid);
print("--------------------------------------");
}
}
En el código anterior, creamos un bucle que recorre la id de todos los jugadores. luego chequea si estos están conectados, y finalmente si lo están, lo escribe en la consola.

!Importante: Funciona = que el if, respeto de los brackets y las sentencias.[/b]


do
Es otro tipo de bucle, pero a diferencia del for, solo consta de 1 paso. el chequeo.

Ejemplo:
new id;
do{
if(IsPlayerConnected(playerid)){
printf("El jugador con el id %i está conectado", playerid);
print("--------------------------------------");
}
id++;
}while(id<GetMaxPlayers());
Este ejemplo es = al ejemplo dado con el for, pero con la sentencia do.


while
Esta expresión, también es utilizada para realizar un bucle, y la forma es muy similar a la de la expresión "do".

Ejemplo:
new id;
while(id<GetMaxPlayers()){
if(IsPlayerConnected(playerid)){
printf("El jugador con el id %i está conectado", playerid);
print("--------------------------------------");
}
id++;
}

Loops(infinitos)
Bueno, en esta pequeña parte de este tutorial, explicare como crear loops infinitos de diferentes formas.

Método 1:
for(;;)print("Esto es un texto que saldrá repetidamente en la consola");
Método 2:(tira 1 warning, pero funciona perfecto)
while(true)print("Esto es un texto que saldrá repetidamente en la consola");
Método 3:(tira 1 warning, pero funciona perfecto)
do{
print("Esto es un texto que saldrá repetidamente en la consola");
}while(true);

Esas son 3 formas de hacer un loop infinito. Hay mas formas pero son todas similares, así que decidí poner solo esas.



[size=+1]Directivas[/size]

Directivas básicas

#if, #elseif, #else, #endif
Definición:
Se utiliza para comparar una sentencia.

Ejemplo:
#if USE_MENU = 1
print("Menús: Habilitados");
#elseif USE_MENU = 0
print("Menús: Deshabilitados");
#else
print("Menús: Error");
#endif


#error
Definición:
Se utiliza para enviar un error durante la compilación.

Ejemplo:
#if defined EERROR
#error Mensaje de error.
#endif


#assert
Definición:
Chequea si una comparación devuelve true o false. En caso de ser false, detiene la compilación.

Ejemplo:
#define PP 6
#assert PP<4
Ese ejemplo enviara un error fatal con el texto "assertion failed: 6<4"

#include
Definición:
Inserta el texto del archivo a incluir en la línea en la que se ubica.

Ejemplo:
#include <a_samp>//carpeta de includes
#include "../include/gl_common"//otra carpeta


#tryinclude
Definición:
Funciona igual que #include, con la diferencia de que si no puede incluir el archivo, no envía un error.

Ejemplo:
#tryinclude <a_samp>

#define
Definición:
Crea una macro.

Ejemplo:
Constante:
#define COLOR_RED 0xFF0000FF


[size=+1]Caracteres Especiales[/size]

Strings
   
   •( \a )      =>   Beep
   •( \b )      =>   Backspace
   •( \e )      =>   Escape
   •( \n )      =>   Nueva Línea
   •( \r )      =>   Retorno de Carro (se utiliza en Windows para una línea nueva "/r/n")
   •( \t )      =>   Tabulación Horizontal
   •( \v )      =>   Tabulación Vertical
   •( \\ )      =>   Inserta literalmente el símbolo '\'
   •( \'' )      =>   Inserta literalmente el símbolo "'"
   •( \" )      =>   Inserta literalmente el símbolo '"'
   •( \% )      =>   Inserta literalmente el símbolo '%'
   •( \ddd; )   =>   código de caracteres, con el código en decimal "ddd"
   •( \xhhh; )   =>   código de caracteres, con el código en hexadecimal "hhh"
   


[size=+1]Creación de funciones[/size]

Funciones Simples

¿Qué es una función?
Podemos definir a una función como un conjunto de acciones que se realizan cuando llamamos a la función.

¿Cómo crear una función?
por ahora veremos solo estas 3 formas de definir una función:
Forma 1:
MiFuncion(parámetros)
{
//acciones
}
Pero esta función si no se utiliza, nos dará 1 advertencia diciendo que no estamos usando ese símbolo.

Forma 2:
forward MiFuncion(parámetros);
publica MiFuncion(parámetros)
{
//acciones
}

Forma 3:
stock MiFuncion(parámetros)
{
//acciones
}


Funciones sin parámetros
Estas son las funciones más simples de hacer, dado que solo ejecutan el código dado. Generalmente se crean funciones así para cargar configuraciones de un sistema, o para realizar varias cosas.

Ejemplo:
stock KickAll()
{
for(new i; i<GetMaxPlayers(); i++)if(IsPlayerConnected(i))Kick(i);
}
Esa es una función muy simple que solo kickea a todos los jugadores conectados.

Funciones con parámetros
Estas funciones aun son simples de hacer, pero le agregamos una complicación más. Los parámetros de una función funcionan = que variables/arrays, y hay veces que se les debe asignar un tag en su declaración

Ejemplo:
stock SetPlayerHealthEx(playerid, Float:vida, color, const mensaje[])
{
SetPlayerHealth(playerid, vida);
SendClientMessage(playerid, color, message[]);
}

Funciones con retorno de valores
Las funciones pueden retornar valores, pero el tipo de valor retornado debe ser siempre igual.

Existen dos formas de retornar valores:

ejemplo1
stock GetConnectedPlayers()
{
new count;
for(new i; i<GetMaxPlayers(); i++)if(IsPlayerConnected(i))count++;
return count;
}

ejemplo2
stock GetConnectedPlayers()
{
new count;
for(new i; i<GetMaxPlayers(); i++)if(IsPlayerConnected(i))count++;
GetConnectedPlayers = count;
}

Ahora voy a mostrar una forma errónea de retornar valores.
stock Suma(valor1, valor2)
{
new str[128];
if(!IsNumeric(valor1) || !IsNumeric(valor2)){
str = "ERROR: Los valores deben ser numéricos";
return str;
}
return valor1+valor2;
}
La función Suma, va a generar un error a la hora de compilar, dado que el primer valor que retorna es un string o array, mientras que el segundo es un numero entero.



[size=+3]Nivel: Avanzado[/size]


[size=+1]Inicializadores (avanzado)[/size]
Ahora ya con un mayor conocimiento, vamos a ver stock, static, const y operator.

stock
Vamos a ir directo al grano, dado que entender stock es lo más fácil de esta sección.

¿Cómo se utiliza?
stock se utiliza para la declaración de variables o funciones que no estamos seguros si vamos a utilizar o no. Utilizando stock, el compilador si no se utiliza, no la define.


static
Se puede declarar una variable/array local estática o global estática.

Local estática
Definición:
Tiene la misma función que la variable/array local, pero a diferencia de la anterior, esta guarda la información.

Ejemplificación:
publica OnFilterScriptInit()
{
MyFunction();
print("!");
MyFunction();
return 1;
}

MyFunction()
{
for(new i; i<3; i++){
    static j;
    printf("%i", j);
    j++;
}
}
Ese código va a escribir en la consola:
0
1
2
!
3
4
5

Mientras que si la variable no fuera local estática, escribiría en la consola:
0
0
0
!
0
0
0

Global estática
Definición:
Tiene la misma función que la variable/array global, pero solo puede utilizarse en el archivo que se declara.

Ejemplificación:
static MyVariableEstaticaGlobal;

const
Cuando declaramos una variable como constante, significa que la misma no podrá ser modificada.

¿Cómo se declara una variable const?
eso es muy sencillo:
new const Nombre = contenidonew const Nombre[] = "contenido"
¿Cuándo se declara una variable const?
Existen 3 opciones comunes:
   •Para crear un array constante.
   •Para una variable pública(publica) que debe ser seteada obligatoriamente por el host y solo por el host.
   •En los parámetros de una función.


operator
Se utiliza para declarar un tag propio.

¿Cómo se utiliza?
Es un poco complejo.
ejemplo:
stock NewTag:operator=(a)
{
return NewTag:(a*5);
}

main()
{
new NewTag:BB = 5;
printf("%i", _:BB);
return 1;
}
este ejemplo es realmente simple y no justificaría crear un nuevo tag. Pero es para que sea más fácil de entender.

Hay otro ejemplo similar en la wiki y una explicación por ahí mejor, pero en ingles. Debes de estar registrado para poder ver el contenido indicado. Registrate o Conectate



[size=+1]Operadores[/size]

Operadores misceláneos

   •(A) ? (B) : (C) => Es muy similar a if. Si A="true" retorna B, de lo contrario retorna C.
   ejemplo:
   printf("Admin: %s", (Sinfo[Admin])?("ON"):("OFF"));   Si Sinfo[Admin] = true, entonces en la consola aparecerá "Admin: ON", de lo contrario aparecerá "Admin: OFF".

Operadores de Bits(manipulación)

   •~A      =>   Retorna el complemento de A.
   •A >> B   =>   Retorna el shift aritmético de B (hacia la izquierda) sobe A.
   •A >>> B   =>   Retorna el shift lógico de B (hacia la izquierda) sobre A.
   •A << B   =>   Retorna el shift de B (hacia la derecha) sobre A.
   •A & B      =>   Retorna A "and" B.
   •A | B      =>   Retorna A "or" B.
   •A ^ B      =>   Retorna A "exclusive or" B.
   
Operadores de Bits(Asignación)
Esos operadores son iguales a los de asignación común, y a estos se les suman los de manipulación de bits (siempre con el signo = después del signo de manipulación).

   

[size=+1]Expresiones[/size]
   
Loops(avanzado), saltos, sleep y state

break
Se utiliza para terminar con un bucle.

Ejemplo:
for(new i; i<10; i++)if(Array_N[i] == true)break;

continue
Se utiliza para saltar un valor en un bucle.
for(new i; i<10; i++){
if(i==5)continue;
printf("%i", i);
}
Este ejemplo dará como resultado en la consola:
0
1
2
3
4
5
6
7
8
9


goto
Esta expresión se utiliza para realizar un sato, para ir a x lugar del código, previamente definido.

Ejemplo:
función()
{
new bool:ThisBool;
principio:
do{
if(random(2) == 0)ThisBool = false;
else ThisBool = true;
if(ThisBool == true){
    print("SI");
goto TEnd;
}
else{
    print("No");
ThisBool = false;
goto principio;
}
}while(ThisBool == false);
TEnd:
return;
}
El ejemplo por ahí no sea muy claro, pero lo que ese código hace es:
1º definir la variable(tipo boolean).
2º empieza con el bucle, y asigna un valor a la variable según sea 0 o 1 el número obtenido en el if.
3º compara el contenido de la variable y si es false, vuelve a empezar, de lo contrario termina.


sleep
Se utiliza para parar la aplicación durante x milisegundos. Aun que esta expresión figura en el manual de pawn, dudo que funcione.

Ejemplo:
sleep(1000);En este caso, la consola quedaría detenida durante 1 segundo.

Si la función no funciona, acá dejo una para aquellos a los que les interese:
stock SleepEx(time)
{
time += GetTickCount();
while(time>GetTickCount()){}
}


state
Se utiliza para cambiar el estado de un autómata. Su uso es:
state nombredelautomata
Si quieren más información sobre esto, les recomiendo mirar Debes de estar registrado para poder ver el contenido indicado. Registrate o Conectate de y_less que está muy bien explicado este tema.



[size=+1]Directivas[/size]

Directivas avanzadas

#define
Definición:
Crea una macro. puede ser una función o solo una constante.

Ejemplo:
Constante:
#define COLOR_RED 0xFF0000FFFunción:
#define Minutes(%0) (%0)*60*1000Dado que el tema de las macros es muy amplio, y ya ha sido explicado por Y_Less les dejo el Debes de estar registrado para poder ver el contenido indicado. Registrate o Conectate


#endinput
Definición:
Deja de incluir el archivo que estaba siendo leído.

Ejemplo:
#include <nombre>
#if defined _NOMBRE_INC
#endinput
#endif
#define _NOMBRE_INC


#pragma
Definición:
Esta directiva, puede tomar muchos valores:

amxlimit (valor):
Setea el valor máximo del tamaño que puede alcanzar el archivo .amx del script.

amxram (valor):
Setea el valor máximo de memoria ram que puede utilizar el archivo .amx del script.

codepage (nombre/valor):
Setea el formato en el que deben codificarse los strings.

ctrlchar (carácter):
Setea el símbolo que indica la continuación una nueva línea (por defecto"\").

deprecated (valor):
Setea un símbolo que no se puede usar. Si el compilado lo encuentra en el script, sale un warning.

dynamic (valor):
Setea el tamaño en cells de la memoria asignada para los datos dinámicos.

Library (nombre):
Especifica el archivo (.dll o .so) del cual obtener las funciones nativas.

pack (0/1):
Cambia el modo de uso de los strings comprimidos y descomprimidos.

tabsize (value):
Setea el valor asignado a cada tabulación. (defecto: 8).

unused (symbol):
Especifica que no se usara ese símbolo.

#undef
Definición:
Elimina una macro declarada o una variable/array declarada con const.

Ejemplo:
#define COLOR_X 0xFFA4B6F9
printf("%d", COLOR_X);
#undef COLOR_X
Si luego de ese código, intentáramos usar COLOR_X, tendríamos que definirlo nuevamente, o el compilador, no compilaría.



[size=+1]Creación de funciones[/size]

Funciones Complejas

Pasar parámetros como opcionales
¿Cómo hacer esto? muy sencillo.
Debemos agregar =valordefault a la variable q queramos que sea opcional y listo.

Ejemplo:
stock Func(playerid, hora, minutos=0)
{
SetPlayerTime(playerid, hora, minutos);
printf("Un admin seteo la hora de %i a %i:%i", playerid, hora, minutos);
}

Pasar parámetros como valor y como referencia

Bueno ustedes por el momento con este tutorial solo sabían pasar archivos por valor. Ahora bien, ¿Qué significa que pasamos un archivo por valor?
Significa, que aun que nosotros editemos ese valor, el valor pasado no cambiara.

Ejemplo:
main()
{
new val, val1, val2, val3;
val = 1;
val1 = 3;
val2 = 5;
val3 = Func(val1, val2, val);
printf("%i", val3);
printf("%i %i %i", val, val1, val2);
}

stock Func(valor_I, valor_D, valor_M)
{
valor_I /= Valor_D*valor_M;
return valor_M += Valor_I-Valor_D;
}
Como pueden observar Func edita los valores que se le asignan, pero los valores iniciales (val, val2, val3), siguen siendo los mismos.

Ahora bien, existe una forma de editar los valores que se le asignan a una función. Esto es lo que se conoce como "por referencia".
¿Cómo hacer eso?
muy sencillo, solo es necesario agregar el carácter '&' delante de la variable que queremos pasar como referencia, de lo contrario (si no lo ponemos), esta variable será pasada por valor.

!Importante: por defecto, los arrays no pueden ser pasados por valor, ¿Qué quiere decir esto? que si en un archivo especificamos uno de los parámetros como array, será pasado automáticamente por referencia y no por valor.[/b]

Crear funciones con parámetros variables
Para crear una función con parámetros indefinidos, debemos hacerlo utilizando '...'.

Ejemplo:
main()
{
printf("%i", SumaTodo(5, 6, 1, 100, 8));
printf("%i", SumaTodo(1, 9, 6, 169, 17, 65, 243, 213));
}

stock SumaTodo(...)
{
new res;
for(new i; i<numargs(); i++)res += getarg(i);
return res;
}



[size=+3]Final[/size]

Creo que los que lean este tutorial en serio, van a aprender mucho, porque siempre se aprende algo o por lo menos se recuerda algo q se había olvidado.
Espero que les sirva y tengo el post abierto a ediciones si me equivoque en algo, porque cualquiera se equivoca.[/font]

By the_chaoz

Drimacus

Dioss... me acaba se rebentar la cabeza en mil trozos jajaja.
Lo bixeare estas cosas me gustan.
Pero esto se me va de las manos aver si soy capaz de hacer algo....
Un saldo y gracias por la guía.
Ami como me saques de la edición del l2, unreal o blender me pierdo pero, vamos a provar.
Siempre aprendiendo  ;D.

Swarlog

Debes de estar registrado para poder ver el contenido indicado. Registrate o ConectateDioss... me acaba se rebentar la cabeza en mil trozos jajaja.
Lo bixeare estas cosas me gustan.
Pero esto se me va de las manos aver si soy capaz de hacer algo....
Un saldo y gracias por la guía.
Ami como me saques de la edición del l2, unreal o blender me pierdo pero, vamos a provar.
Siempre aprendiendo  ;D.

Es normal, es otro lenguaje de programación. Pero sabiendo Java, más o menos te adaptas.

Yo llevo años sin tocarlo, pero igual abro un servidor test.