Bien, como nunca vi que lo hayan posteado en alguna parte, o si lo postearon no me importa, aquí les demostrare como utilizar MACRO's para realizar cuentas matemáticas útiles para diferentes tipos de ecuaciones. En este caso el conteo de la EXP, AP, Frags, necesarios para el siguiente nivel.

Un MACRO se define de esta forma:

Código:


#include <amxmisc>
#include <amxmodx>
#include <hamsandwich>

/* Como es una constante en el tiempo, en programación se utilizan mayúsculas en el nombre del mismo */

/* Para declarar parámetros en un MACRO, se utiliza un '%' seguido de un número que lo identifique, los parametros deben ir sin separaciones luego de la coma, me ha pasado con diferentes MACRO's que el valor que retorna, a veces termina en basura */

/* Luego se pasa a declarar la ecuación, o simplemente atribuirla a una variable */

/* Como se que se van a poner a experimentar con los MACRO's (supongo o.o), alguno por ahí le va a pasar lo mismo que a mi, dentro de un macro no se pueden utilizar condicionales, no me refiero a IF o ELSE si no '?' y ':', me terminaba tirando un error de compilacion */

/* Bien les pasare una ecuación que no es muy utilizada pero es muy buena, debido a que todos se basan en una regla de superioridad al valor anterior, en este caso ustedes imaginen que yo tengo una array como esta:*/

/* new iValues[] = { 10, 30, 60, 100, 150, ... }; */

/* Como ven la EXP requerida para el siguiente nivel, aumenta tipo piramide, ya que el valor que necesita actualmente para avanzar en nivel, es el valor anterior mas el actual, lo cual me rompio demasiado las bolas, hasta que encontre cuya ecuación capaz de realizar ese conteo, se llama "Sucesión de Fibonacci, se debe trabajar con floats ya que un momento el posible resultado de una parte de la ecuacion retorna decimales necesarios para la sucesión de la ecuación */

// Experiencia para siguiente nivel.
#define NOMBRE_DEL_MACRO(%1)        floatround( ( (%1 + 1) * float(%1 / 2) ) * 10 )

// Experiencia del nivel anterior.
#define NOMBRE_DEL_MACRO2(%1)        floatround( ( %1 * float((%1-1) / 2) ) * 10 )

/* Con este MACRO, tenemos todos la EXP necesaria, sin necesidad de un Array, la cual retornara valores, si se podria decir infinitamente, lo cual no es completamente cierto, ya que todo tiene un limite */

/* Definimos las variables necesarias para el conteo del nivel y experiencia */

new g_level[33];    // Conteo de level
new g_exp[33];        // Conteo de EXP

public plugin_init()
{
    register_plugin( "NOMBRE", "VERSION", "AUTOR" ); // Registro el plugin.
   
    // Llamo a la forward de la libreria Ham Sandwich: Ham_Killed
    /* Esta función es llamada cuando una entidad de Classname "player" muere (la vida de la entidad es igual o menor a 0) */
    /* El 4to parametro indica que la función se ejecutara posterior a la muerte de la entidad y no antes, esto se debe a no interferir con ninguna función del CS Engine */
    RegisterHam( Ham_Killed, "player", "Ham_PlayerKilled", 1 );
}

public client_putinserver(id)
{
    // Reseteo valores cuando el usuario esta dentro del servidor
    g_level[id] = 1;
    g_exp[id] = 0;
}

/* Esta función devuelve los valores, tales como la victima, y el atacante cuando un usuario es asesinado */
public Ham_PlayerKilled( victim, attacker )
{
    // Si el atacante o victima no se encuentran conectados, no prosigo
    if( !is_user_connected(victim) || !is_user_connected(attacker) )
        return HAM_IGNORED;

    // Si el equipo de la victima es igual al del atacante, no prosigo
    if( get_user_team(victim) == get_user_team(attacker) )
        return HAM_IGNORED;

    // Si todo se cumple, le aumento un punto de experiencia al atacante
    update_xp(attacker, 1);
   
    // Devuelvo un valor, debido a las reglas de compilación
    return HAM_IGNORED;
}

/* Parametros:
    @id Es el index del usuario, el numero que identifica al cliente conectado al servidor
    @value Es el valor que puede diferir entre negativo y positivo, el cual segun su signo, aumenta o disminuye el valor de la EXP */
public update_xp(id, value)
{
    /* Si el valor de value es negativo, y es mayor que la EXP, no prosigo */
    if( ( g_exp[id] + value ) < 0 ) return 0;

    /* Aumento o disminuyo el valor de la EXP */
    g_exp[id] += value;

    /* Si el valor de value es positivo ... */
    if( value )
    {
        /* Mientras la experiencia que tenga sea mayor que la EXP necesaria para el
        siguiente nivel */
        while( g_exp[id] >= NOMBRE_DEL_MACRO(g_level[id]) )
        {
            /* Verifico si el usuario sigue conectado, si no devuelvo valor y no prosigo */
            if( !is_user_connected(id) ) return 0;   

            /* Le imprimo un mensaje al usuario y aumento el nivel */
            client_print(id, print_chat, "Has aumentado de nivel: %d", ++g_level[id]);
        }
    }
    else // Si el valor de value no es positivo
    {
        /* Mientras la experiencia sea menor que la EXP necesaria para el nivel anterior al actual */
        while( g_exp[id] < NOMBRE_DEL_MACRO2(g_level[id]) )
        {
            /* Verifico si el usuario sigue conectado, si no devuelvo valor y no prosigo */
            if( !is_user_connected(id) ) return 0;
            /* Le imprimo un mensaje al usuario y disminuyo el nivel */
            client_print(id, print_chat, "Has disminuido de nivel: %d", --g_level[id]);
        }
    }
   
    /* Devuelvo valor, debido a las reglas de compilación */
    return 1;
}
           
Saludos, cualquier duda, correcion estoy a disposición.

by http://forums.alliedmods.net/showthread.php?t=173940