[ZP][RESUELTO] Problema con zombie xp redonim
#1
12345
No hay mejor maestro que la experiencia más amarga de uno mismo, todo parece imposible hasta que se hace.
Responder
#2
(13/10/2013, 02:42 PM)Tig escribió: Creo que el plugin de redonim8 esta creado solo para 7 clases de zombies máximas, porque si pongo mas de 7 clases me salta un bug y que ya no restringe las clases nuevas por niveles, es decir pongo 7 clases pero si pongo 8 o 9 ...etc... de 7 para arriba ya no están restringida por su correspondiente nivel, las puedes escoger teniendo el nivel que tengas, pero en las clases humanas no pasa lo mismo de momento, revise todo y veo todo normal, excepto esto que no se lo que hace:



Código PHP:
if (ZCLASSES_STARTID->= 0ZCLASSES_STARTID -= 



Alguna ayuda? gracias

Lo que dice esa línea que mostrás es esto:

"Si la cantidad de clases zombies menos 7 es mayor o igual a 0, entonces borro las últimas 7 clases."
Responder
#3
Neel entonces que solucion tendrai tener mas de 7 clases ,, este es el mismo sma de mi amigo Tig ,, que le estoy ayudando un poco mas rreglado pero no encotnramos ninguna solucion a eso puedes epxlicarme alguna o ayudarnos a solucionarlo



Aqui te dejo el pastebin : http://pastebin.com/e4BTrj7t



(Tiene un fallo en la linea 401 , pero lo estoy intentando fixear ) si nos puedes ayudar a qeu no de ningun warning seria de agradecimiento



SALUDOS !!!
Responder
#4
En vez de subirlo a pastebin, adjuntá el sma acá en el foro.

El error de la línea 401 te está diciendo que no se puede tener nada abajo de un return. Ya que el return frena la ejecución de la función, todo lo que esté abajo nunca se ejecutará.

Vos tenés esto:
Código PHP:
public handle_say_level(id)
{
        
//return level
        
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"SAY_LEVEL"userLevel[id])
        return 
PLUGIN_HANDLED
       
        zp_colored_print
(id"[Clan nK]^x03 %s^x01 tiene^x04 %s^x01 niveles "userNameID[id], userLevel[id])
        return 
PLUGIN_HANDLED
       

Cambiandolo por esto compilará.
Código PHP:
public handle_say_level(id)
{
        
//return level
        
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"SAY_LEVEL"userLevel[id])
        
zp_colored_print(id"[Clan nK]^x03 %s^x01 tiene^x04 %s^x01 niveles "userNameID[id], userLevel[id])
        return 
PLUGIN_HANDLED


Con respecto a lo del máximo de clases, simplemente borrá la condición esa que mostró tig.
Responder
#5
neeel i love you .Gran sonrisa

Neel si quiero adaptar este code para que ponga una public nueva aparte debajo y que cuand oescriba level f0 , level f0r , level asd y su nobmre es (asdafasdfas) no tengo ni idea de como adaptarlo una explicacion ?

xd.... perdon por agobiar...
Responder
#6
deberíais empezar a aprender un poco de pawn antes de meteros con zp, porque eso es muy simple



y si tenéis ese error no me quiero imaginar que vendrá después, es una recomendación.
(17/04/2015, 03:36 PM)Neeeeeeeeeel.- escribió: No se va a volver a conectar a internet en toda su puta vida... nadie sube porno a mi foro y vive para contarlo.
Responder
#7
(13/10/2013, 06:34 PM)RauliTop escribió: deberíais empezar a aprender un poco de pawn antes de meteros con zp, porque eso es muy simple

y si tenéis ese error no me quiero imaginar que vendrá después, es una recomendación.

ya... solo son esos .. pero a la respuesta a neell

ay mucahs condiciones :
Código PHP:
// Zombie Class Menu
public menu_zclass(idkey)
{
    
// Special keys / items list exceeded
    
if (key >= MENU_KEY_BACK || ZCLASSES_SELECTION >= g_zclass_i)
    {
        switch (
key)
        {
            case 
MENU_KEY_BACK// back
            
{
            if (
ZCLASSES_STARTID->= 0ZCLASSES_STARTID -= 
            
}
            case 
MENU_KEY_NEXT// next
            
{
                if (
ZCLASSES_STARTID+g_zclass_iZCLASSES_STARTID += 7
            
}
            case 
MENU_KEY_EXIT// exit
            
{
                return 
PLUGIN_HANDLED;
            }
        }
        
        
// Show extra items menu again
        
show_menu_zclass(id)
        return 
PLUGIN_HANDLED;
    } 

cual borro ? n
Responder
#8
(13/10/2013, 06:37 PM)tiomaster escribió:
(13/10/2013, 06:34 PM)RauliTop escribió: deberíais empezar a aprender un poco de pawn antes de meteros con zp, porque eso es muy simple



y si tenéis ese error no me quiero imaginar que vendrá después, es una recomendación.



ya... solo son esos .. pero a la respuesta a neell



ay mucahs condiciones :

Código PHP:
// Zombie Class Menu

public menu_zclass(idkey)

{

    
// Special keys / items list exceeded

    
if (key >= MENU_KEY_BACK || ZCLASSES_SELECTION >= g_zclass_i)

    {

        switch (
key)

        {

            case 
MENU_KEY_BACK// back

            
{

            if (
ZCLASSES_STARTID->= 0ZCLASSES_STARTID -= 

            
}

            case 
MENU_KEY_NEXT// next

            
{

                if (
ZCLASSES_STARTID+g_zclass_iZCLASSES_STARTID += 7

            
}

            case 
MENU_KEY_EXIT// exit

            
{

                return 
PLUGIN_HANDLED;

            }

        }

        

        
// Show extra items menu again

        
show_menu_zclass(id)

        return 
PLUGIN_HANDLED;

    } 



cual borro ? n
Ah no... dentro de ese contexto eso está bien.... debes tener algún problema con la paginación...
Responder
#9
(13/10/2013, 06:45 PM)Neeeeeeeeeel.- escribió:
(13/10/2013, 06:37 PM)tiomaster escribió:
(13/10/2013, 06:34 PM)RauliTop escribió: deberíais empezar a aprender un poco de pawn antes de meteros con zp, porque eso es muy simple



y si tenéis ese error no me quiero imaginar que vendrá después, es una recomendación.



ya... solo son esos .. pero a la respuesta a neell



ay mucahs condiciones :

Código PHP:
// Zombie Class Menu

public menu_zclass(idkey)

{

    
// Special keys / items list exceeded

    
if (key >= MENU_KEY_BACK || ZCLASSES_SELECTION >= g_zclass_i)

    {

        switch (
key)

        {

            case 
MENU_KEY_BACK// back

            
{

            if (
ZCLASSES_STARTID->= 0ZCLASSES_STARTID -= 

            
}

            case 
MENU_KEY_NEXT// next

            
{

                if (
ZCLASSES_STARTID+g_zclass_iZCLASSES_STARTID += 7

            
}

            case 
MENU_KEY_EXIT// exit

            
{

                return 
PLUGIN_HANDLED;

            }

        }

        

        
// Show extra items menu again

        
show_menu_zclass(id)

        return 
PLUGIN_HANDLED;

    } 



cual borro ? n
Ah no... dentro de ese contexto eso está bien.... debes tener algún problema con la paginación...



Lo siento nel por tratarte asi ,,, pero necesito aque te refieres con la compaginacion , a las acciones del menu ? o aque
Responder
#10
Paginación es el código que hace la simulación para que parezca que un menú tiene varias páginas.
Responder
#11
es muy grande pero aqui esta el fallo no lo se exacatmente lo e ledio masd e 50 veces ....
miralo porfavor nell

Código PHP:
/* ----------------------- Menu Handlers -------------------------*/

// Game Menu
public menu_game(idkey)
{
    if(
get_pcvar_num(cvar_removexp) == 1key++;
    
    switch (
key)
    {
        case 
0// Buy a level up
        
{
            if(
getAmmoPacks(id) >= getNeededPacks(id))
            {
                
setAmmoPacks(idgetAmmoPacks(id) - getNeededPacks(id))
                
userLevel[id] += 1
                save_data
(id)
                
                
// Inform the user they leveled up
                
zp_colored_print(id"^x04%s^x01 %L %d"textHeaderid ,"MENU_BUY_LEVEL"userLevel[id])
                
ShowHUD(id)
            } else {
                
zp_colored_print(id"^x04%s^x01 %L"textHeaderid ,"ERR_NOTENOUGHPACKS")
            }
            
            
// Return to the main xp menu
            
show_menu_game(id);
            
        }
        
        case 
1// Human Classes
        
{
            
// Restrict it here if we wanted to
            
show_menu_hclass(id)
        }
        
        case 
2// Zombie Classes
        
{
            if (
get_pcvar_num(cvar_removezombie) == 0)
            {
                
// Restrict it here if we wanted to
                
show_menu_zclass(id)
            }
        }
    }
    
    return 
PLUGIN_HANDLED;
}

// Zombie Class Menu
public menu_zclass(idkey)
{
    
// Special keys / items list exceeded
    
if (key >= MENU_KEY_BACK || ZCLASSES_SELECTION >= g_zclass_i)
    {
        switch (
key)
        {
            case 
MENU_KEY_BACK// back
            
{
            if (
ZCLASSES_STARTID->= 0ZCLASSES_STARTID -= 
            
}
            case 
MENU_KEY_NEXT// next
            
{
                if (
ZCLASSES_STARTID+g_zclass_iZCLASSES_STARTID += 7
            
}
            case 
MENU_KEY_EXIT// exit
            
{
                return 
PLUGIN_HANDLED;
            }
        }
        
        
// Show extra items menu again
        
show_menu_zclass(id)
        return 
PLUGIN_HANDLED;
    } 
    
// They selected their own class
    
if (ZCLASSES_SELECTION == g_zombieclassnext[id])
    {
        
//Plugin continues if this is false (sets class info on connect)
        
if( g_zclass_showmenu[id] == false//when a client first connects, the menu shows all zombies as a choice even the one the client defaults to (index of 0)
        
{
            
// Alert them they already have chosen a zombie
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_ALREADYSELECTED")
            
show_menu_zclass(id)
            
            
// They had already chosen this zombie, dont rerun the command
            
return PLUGIN_HANDLED;
        }
    }
    
    if (
get_pcvar_num(cvar_removexp) == 0)
    {
        if (
g_zclass_lvl[HCLASSES_SELECTION] > userLevel[id])
        {
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_NOTLEVEL")
            
show_menu_zclass(id)
            return 
PLUGIN_HANDLED;
        }
    }
    
    
// Store selection for the next infection
    
g_zombieclassnext[id] = ZCLASSES_SELECTION;
    
    
// Disable showing menu since theyve chosen
    
g_zclass_showmenu[id] = false;
        
    
// Show selected zombie class info and stats
    
zp_colored_print(id"^x04%s^x01 %L: %s"textHeaderid"ZOMBIE_SELECT_XP"g_zclass_name[g_zombieclassnext[id]])
    
zp_colored_print(id"^x04%s^x01 %L: %d %L: %d %L: %d %L: %d%%"textHeaderid"ZOMBIE_ATTRIB1_XP"g_zclass_hp[g_zombieclassnext[id]], id"ZOMBIE_ATTRIB2_XP"g_zclass_spd[g_zombieclassnext[id]],
    
id"ZOMBIE_ATTRIB3_XP"floatround(g_zclass_grav[g_zombieclassnext[id]]*800), id"ZOMBIE_ATTRIB4_XP"floatround(g_zclass_kb[g_zombieclassnext[id]]*100))
    
    
// Set the class for zombie plague
    
zp_set_user_zombie_class(idg_zombieclassnext[id])
    
    return 
PLUGIN_HANDLED;
}

// Human Class Menu
public menu_hclass(idkey)
{
    
// Special keys / items list exceeded
    
if (key >= MENU_KEY_BACK || HCLASSES_SELECTION >= g_hclass_i)
    {
        switch (
key)
        {
            case 
MENU_KEY_BACK// back
            
{
                if (
HCLASSES_STARTID->= 0HCLASSES_STARTID -= 7
            
}
            case 
MENU_KEY_NEXT// next
            
{
                if (
HCLASSES_STARTID+g_hclass_iHCLASSES_STARTID += 7
            
}
            case 
MENU_KEY_EXIT// exit
            
{
                return 
PLUGIN_HANDLED;
            }
        }
        
        
// Show human list again
        
show_menu_hclass(id)
        return 
PLUGIN_HANDLED;
    }
    
    if (
HCLASSES_SELECTION == g_humanclassnext[id])
    {
        
// When a client first connects, the menu shows all zombies as a choice even the one the client defaults to (index of 0)
        
if( g_hclass_showmenu[id] == false)
        {
            
// Alert them they alaerdy have chosen a zombie
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_ALREADYSELECTED")
            
show_menu_hclass(id)
            return 
PLUGIN_HANDLED//they had already chosen this zombie, dont rerun the command
        
}
    }
    
    if (
get_pcvar_num(cvar_removexp) == 0)
    {
        if (
g_hclass_lvl[HCLASSES_SELECTION] > userLevel[id])
        {
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_NOTLEVEL")
            
show_menu_hclass(id)
            return 
PLUGIN_HANDLED;
        }
    }

    
// Store selection for the next infection
    
g_humanclassnext[id] = HCLASSES_SELECTION;
    
    
// Disable showing menu since theyve chosen
    
g_hclass_showmenu[id] = false;
    
    
// Show selected human class info and stats
    
zp_colored_print(id"^x04%s^x01 %L: %s"textHeaderid"HUMAN_SELECT_XP"g_hclass_name[g_humanclassnext[id]])
    
zp_colored_print(id"^x04%s^x01 %L: %d %L: %d %L: %d"textHeaderid"HUMAN_ATTRIB1_XP"g_hclass_hp[g_humanclassnext[id]], id"HUMAN_ATTRIB2_XP"g_hclass_spd[g_humanclassnext[id]],
    
id"HUMAN_ATTRIB3_XP"floatround(g_hclass_grav[g_humanclassnext[id]]*800), id)
    
    return 
PLUGIN_HANDLED;
}

public 
ShowHUD(taskid)
{
    
//if (get_pcvar_num(cvar_removexp) == 1 ) return;
    
    
static id;
    
    
// Our ID
    
id ID_SHOWHUD;
    
    
// Player died?
    
if (!is_user_alive(id))
    {
        
// Get spectating target
        
id pev(idPEV_SPEC_TARGET//other persons ID
        
        // Target not alive
        
if (!is_user_alive(id)) return;
    }
    
    
// Format the classname
    
static redgreenblueg_name[sizeof g_hclass_name]; // Hopefully g_zclass_name and g_zclass_name will be left the same array size 
    
    
if ( g_human[id] == false // zombies
    
{
        
red 0
        green 
255
        blue 
0
        
        formatex
(g_namesizeof g_name 1"%L"id"HUD_ZOMBIE");        
    }
    else 
// humans
    
{
        
red 0
        green 
255
        blue 
0
        
        copy
(g_namesizeof g_name 1g_hclass_name[g_humanclass[id]]);
    }
    
    if (
id != ID_SHOWHUD)
    {
        if (
get_pcvar_num(cvar_removexp) == 
        {
            
// Set our HUD in position for spectating
            
set_hudmessage(255255255HUD_SPECT_XHUD_SPECT_Y06.01.10.00.0, -1);
            
ShowSyncHudMsg(ID_SHOWHUDg_MsgSync2"%L: %s - %L: %d"ID_SHOWHUD"HUD_CLASS"g_nameID_SHOWHUD"HUD_LEVEL"userLevel[id]);
        } else {
            
// Just show the class information
            
set_hudmessage(255255255HUD_SPECT_XHUD_SPECT_Y06.01.10.00.0, -1);
            
ShowSyncHudMsg(ID_SHOWHUDg_MsgSync2"%L: %s"ID_SHOWHUD"HUD_CLASS"g_name);
        }
    } else {
        if (
get_pcvar_num(cvar_removexp) == 
        {
            
// Set our HUD in position for the player
            
set_hudmessage(redgreenblueHUD_STATS_XHUD_STATS_Y06.01.10.00.0, -1);
            
ShowSyncHudMsg(idg_MsgSync2"%L: %s - %L: %d^t^t^t"id"HUD_CLASS"g_nameid"HUD_LEVEL"userLevel[id]);
        } else {
            
// Just show the class information
            
set_hudmessage(redgreenblueHUD_STATS_XHUD_STATS_Y06.01.10.00.0, -1);
            
ShowSyncHudMsg(idg_MsgSync2"%L: %s^t^t^t"id"HUD_CLASS"g_name);    
        }
    }
}

// Native: native_get_user_human_class
public native_get_user_human_class(id)
{
    return 
g_humanclass[id];
}

// Native: zpxp_register_human_class
public native_register_human_class(const name[], const info[], const model[], const weapons[], hpspeedFloat:gravitylevel)
{
    
// Reached human classes limit
    
if (g_hclass_i >= sizeof g_hclass_name)
        return -
1;
    
    
// Strings passed byref
    
param_convert(1)
    
param_convert(2)
    
param_convert(3)
    
param_convert(4)
    
    
// Add the class
    
copy(g_hclass_name[g_hclass_i], sizeof g_hclass_name[] - 1name)
    
copy(g_hclass_info[g_hclass_i], sizeof g_hclass_info[] - 1info)
    
copy(g_hclass_model[g_hclass_i], sizeof g_hclass_model[] - 1model)
    
copy(g_hclass_weapons[g_hclass_i], sizeof g_hclass_weapons[] - 1weapons)
    
g_hclass_hp[g_hclass_i] = hp
    g_hclass_spd
[g_hclass_i] = speed
    g_hclass_grav
[g_hclass_i] = gravity
    g_hclass_lvl
[g_hclass_i] = level
    
    
    
// For the load_data and save_data
    
new tSave[40]
    
formatex(tSavesizeof tSave 1"%s%s"nameinfo);
    
replace_all(tSavesizeof tSave 1";""")
    
replace_all(tSavesizeof tSave 1" """)
    
g_hclass_load[g_hclass_i] =  tSave;
        
    
// Increase registered classes counter
    
g_hclass_i++
    
    
// Return id under which we registered the class
    
return g_hclass_i-1;
}

// Native: zpxp_register_zombie_class
public native_register_zombie_class(const name[], const info[], const model[], const clawmodel[], hpspeedFloat:gravityFloat:knockbacklevel)
{    
    
// Dont return -1, we wil get lots of server window print errors from the plugins
    
if( get_pcvar_num(cvar_removezombie) == 2) return 0;
    
    
//Bugfix for loading zombies
    
loadedZombies true;
    
    
// Strings passed byref
    
param_convert(1)
    
param_convert(2)
    
param_convert(3)
    
param_convert(4)
    
    
// Save the name, level required, and classid
    
copy(g_zclass_name[g_zclass_i], sizeof g_zclass_name[] - 1name)
    
copy(g_zclass_info[g_zclass_i], sizeof g_zclass_info[] - 1info)
    
copy(g_zclass_model[g_zclass_i], sizeof g_zclass_model[] - 1model)
    
copy(g_zclass_clawmodel[g_zclass_i], sizeof g_zclass_clawmodel[] - 1clawmodel)
    
    
g_zclass_hp[g_zclass_i] = hp
    g_zclass_spd
[g_zclass_i] = speed
    g_zclass_grav
[g_zclass_i] = gravity
    g_zclass_kb
[g_zclass_i] = knockback
    g_zclass_lvl
[g_zclass_i] = level
    
    
// For the load_data and save_data
    
new tSave[40]
    
formatex(tSavesizeof tSave 1"%s%s"nameinfo);
    
replace_all(tSavesizeof tSave 1";""")
    
replace_all(tSavesizeof tSave 1" """)
    
g_zclass_load[g_zclass_i] =  tSave;
    
    
// Get the classid from zombie plague
    
new g_returnclass_id;
    
g_returnclass_id zp_register_zombie_class(g_zclass_name[g_zclass_i], g_zclass_info[g_zclass_i], g_zclass_model[g_zclass_i], g_zclass_clawmodel[g_zclass_i], g_zclass_hp[g_zclass_i] / 2g_zclass_spd[g_zclass_i], g_zclass_grav[g_zclass_i], g_zclass_kb[g_zclass_i]);
    
    
// Make sure there was no error
    
if( g_returnclass_id == -)
    {
        
server_print("%s %L"textHeaderLANG_PLAYER"ERR_BADRETURN");
        return -
1
    
}
    
    
// Increase registered classes counter
    
g_zclass_i++
    
    
// Return id under which we registered the class
    
return g_zclass_i-1;
}

public 
native_register_extra_item(const name[], costteam)
{
    
//TO DO 
    


es solo el de zombie ... solo falta eso por fixear .. lo demas esta medio medio
Responder
#12
Si no podés encontrar el error quizás lo más fácil sea mudar los menúes al sistema nuevo. Ya que estos tienen paginación automática.
Responder
#13
(13/10/2013, 07:16 PM)Neeeeeeeeeel.- escribió: Si no podés encontrar el error quizás lo más fácil sea mudar los menúes al sistema nuevo. Ya que estos tienen paginación automática.

Nadie puede echarle un vistazo ? e.e ?
Y como los mudo ? esque no tengo ni idea ? puedes acerme un ejemplo

te paso el sma por si tu puedes echar un vistazo -..- porfa Gran sonrisa

Código PHP:
#include <amxmodx>
#include <amxmisc>
#include <nvault>
#include <fakemeta>
#include <zombieplague>
#include <hamsandwich>
#include <fun>
#include <cstrike>

/*================================================================================
    Info
==================================================================================

Zombie XP Mode by redomin8
MeRcyLeZZ coded a huuuuge portion of the code, and I learned
from his genius and maybe made some changes (some was perfect)

Also, I'd very much like to thank G-Dog for all the help with creating
ZP Bank, I used his code to learn nvault. Good job guys!

Thanks to AssKicR and xeroblood for making ExplodeString.

Enjoy it, take it apart, make a better one. Have fun!

================================================================================
    Editable Section follows
================================================================================*/

// Uncomment to have an item added to zp's extra menu
#define TRIGGER_ZP_ITEM

// Uncomment to use say commands like "xp", "levels", "class", etc
#define TRIGGER_SAYMENU

// Uncomment if you have redomin8's [ZP] Bank - With Autosave installed (fixes spending spree bug)
//#define ZP_BANK_AUTOSAVE

// Uncomment to allow experimental menu alignment
//#define ZP_ALIGN_TEXT

//Uncomment to give levels to people
//#define ZP_GAMERUINER

//Uncomment to automatically bind a letter to show our menu
#define ZP_BINDMENU "j"

/*================================================================================
    End Editable Section
================================================================================*/

#if defined TRIGGER_ZP_ITEM
new g_TriggerItem
#endif
#if defined ZP_BANK_AUTOSAVE
//compatibility with zp_banks spending spree mode
native zp_bank_get_packs(id)
native zp_bank_set_packs(idvalue)
#endif

// Plugin info
static const PLUGIN_NAME[] = "ZP XP by redomin8"
static const PLUGIN_VERSION[] = ""

// Forwards for our zombie plugins
new g_fwRoundStartg_fwDummyResult

// nVault parameters
new gvault;
#define VAULT_LEVEL 0
#define VAULT_HCLASS 1
#define VAULT_ZCLASS 2

// Internal variables
enum pcvar
{
    
enable 0,
    
packslevelup //(current level) * packslevelup = price to level up
}
new 
pcvars[pcvar];
new 
userLevel[33], userNameID[33][32], userNeededPacks[33]
new 
g_modname[32// for formating the mod name
new g_maxplayers // max players counter


/*================================================================================
    Required Code from zombie_plague (modified to suite the plugin)
================================================================================*/

const MAX_CLASSSES 200

// Note: keep g_zclass_name and g_hclass_name the same array size!
// Zombie Classes vars
new g_zclass_name[MAX_CLASSSES][32// name
new g_zclass_info[MAX_CLASSSES][32// description
new g_zclass_model[MAX_CLASSSES][32// player model
new g_zclass_clawmodel[MAX_CLASSSES][32// claw model
new g_zclass_hp[MAX_CLASSSES// health
new g_zclass_spd[MAX_CLASSSES// speed
new g_zclass_lvl[MAX_CLASSSES// level
new Float:g_zclass_grav[MAX_CLASSSES// gravity
new Float:g_zclass_kb[MAX_CLASSSES// knockback
new g_zclass_load[MAX_CLASSSES][40// loading identifier
new g_zclass_i // loaded zombie classes counter

// Human Classes vars
new g_hclass_name[MAX_CLASSSES][32// name
new g_hclass_info[MAX_CLASSSES][32// description
new g_hclass_model[MAX_CLASSSES][32// player model
new g_hclass_weapons[MAX_CLASSSES][32// claw model
new g_hclass_hp[MAX_CLASSSES// health
new g_hclass_spd[MAX_CLASSSES// speed
new g_hclass_lvl[MAX_CLASSSES// level
new Float:g_hclass_grav[MAX_CLASSSES// gravity
new g_hclass_load[MAX_CLASSSES][40// loading identifier
new g_hclass_i // loaded zombie classes counter

// For menu handlers
#define ZCLASSES_STARTID g_menu_data[id][0]
#define ZCLASSES_SELECTION (g_menu_data[id][0]+key)
#define HCLASSES_STARTID g_menu_data[id][1]
#define HCLASSES_SELECTION (g_menu_data[id][1]+key)
new g_menu_data[33][8// data for various menus
const MENU_KEY_BACK 7
const MENU_KEY_NEXT 8
const MENU_KEY_EXIT 9
const KEYSMENU = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)

// Cvars
new cvar_welcomemsgcvar_removeweaponscvar_removexpcvar_removezombie;

// Vars
new g_zombieclassnext[33// zombie class for next infection
new g_humanclassnext[33// zombie class for next infection
new g_zombieclass[33// zombie class
new g_humanclass[33// zombie class
new g_resetparams[33// reset params?
new bool:g_hclass_showmenu[33]
new 
bool:g_zclass_showmenu[33]

const 
OFFSET_CSTEAMS 114
const OFFSET_LINUX // offsets 5 higher in Linux builds
enum
{
    
CS_TEAM_UNASSIGNED 0,
    
CS_TEAM_T,
    
CS_TEAM_CT,
    
CS_TEAM_SPECTATOR
}
new 
g_freezetime// whether it's freeze time
new bool:g_human[33]; // is zombie
new bool:loadedZombies //bugfix for cvar_removezombies being enabled after it was disabled first (and no zombies loaded)
/* --- FOR OUR HUD --- */
// Tasks for events
enum (+= 100)
{
    
TASK_SHOWHUD
}

// IDs inside tasks
#define ID_SHOWHUD (taskid - TASK_SHOWHUD)

// Message sync object
new g_MsgSync2 

// Message IDs vars
new g_msgSayText

// Constants
const PEV_SPEC_TARGET pev_iuser2
new const textHeader[] = "[ZPXP]"
new const textHeaderOrig[] = "[ZP]" //imitate Zombie Plague alerts

// HUD messages
const Float:HUD_EVENT_X = -1.0
const Float:HUD_EVENT_Y 0.17
const Float:HUD_INFECT_X 0.05
const Float:HUD_INFECT_Y 0.45
const Float:HUD_SPECT_X 0.6
const Float:HUD_SPECT_Y 0.85
const Float:HUD_STATS_X 1.005 //changed to right align
const Float:HUD_STATS_Y 0.9

/*================================================================================
    Constants JUST for giving guns
================================================================================*/

// CS Offsets
#if cellbits == 32
const OFFSET_CSTEAMS 114
const OFFSET_CSMONEY 115
const OFFSET_NVGOGGLES 129
const OFFSET_ZOOMTYPE 363
const OFFSET_CSDEATHS 444
const OFFSET_AWM_AMMO  377 
const OFFSET_SCOUT_AMMO 378
const OFFSET_PARA_AMMO 379
const OFFSET_FAMAS_AMMO 380
const OFFSET_M3_AMMO 381
const OFFSET_USP_AMMO 382
const OFFSET_FIVESEVEN_AMMO 383
const OFFSET_DEAGLE_AMMO 384
const OFFSET_P228_AMMO 385
const OFFSET_GLOCK_AMMO 386
const OFFSET_FLASH_AMMO 387
const OFFSET_HE_AMMO 388
const OFFSET_SMOKE_AMMO 389
const OFFSET_C4_AMMO 390
const OFFSET_CLIPAMMO 51
#else
const OFFSET_CSTEAMS 139
const OFFSET_CSMONEY 140
const OFFSET_NVGOGGLES 155
const OFFSET_ZOOMTYPE 402
const OFFSET_CSDEATHS 493
const OFFSET_AWM_AMMO  426
const OFFSET_SCOUT_AMMO 427
const OFFSET_PARA_AMMO 428
const OFFSET_FAMAS_AMMO 429
const OFFSET_M3_AMMO 430
const OFFSET_USP_AMMO 431
const OFFSET_FIVESEVEN_AMMO 432
const OFFSET_DEAGLE_AMMO 433
const OFFSET_P228_AMMO 434
const OFFSET_GLOCK_AMMO 435
const OFFSET_FLASH_AMMO 46
const OFFSET_HE_AMMO 437
const OFFSET_SMOKE_AMMO 438
const OFFSET_C4_AMMO 439
const OFFSET_CLIPAMMO 65
#endif

// Buy Menu: Primary and Secondary Weapons
new const g_primary_items[][] = { "weapon_galil""weapon_famas""weapon_m4a1""weapon_ak47""weapon_sg552""weapon_aug""weapon_scout",
                
"weapon_m3""weapon_xm1014""weapon_tmp""weapon_mac10""weapon_ump45""weapon_mp5navy""weapon_p90" }
new const 
g_secondary_items[][] = { "weapon_glock18""weapon_usp""weapon_p228""weapon_deagle""weapon_fiveseven""weapon_elite" }


// Max BP ammo for weapons
new const MAXBPAMMO[] = { -152, -19013232100901120100100909090100120,
            
301202003290120902359090, -1100 }

// Additional Items to give after buying all weapons (e.g. grenades)
new const g_additional_items[][] = { "weapon_hegrenade""weapon_flashbang""weapon_smokegrenade" }

// Weapon bitsums
const PRIMARY_WEAPONS_BIT_SUM = (1<<CSW_SCOUT)|(1<<CSW_XM1014)|(1<<CSW_MAC10)|(1<<CSW_AUG)|(1<<CSW_UMP45)|(1<<CSW_SG550)|(1<<CSW_GALIL)|(1<<CSW_FAMAS)|(1<<CSW_AWP)|(1<<CSW_MP5NAVY)|(1<<CSW_M249)|(1<<CSW_M3)|(1<<CSW_M4A1)|(1<<CSW_TMP)|(1<<CSW_G3SG1)|(1<<CSW_SG552)|(1<<CSW_AK47)|(1<<CSW_P90)
const 
SECONDARY_WEAPONS_BIT_SUM = (1<<CSW_P228)|(1<<CSW_ELITE)|(1<<CSW_FIVESEVEN)|(1<<CSW_USP)|(1<<CSW_GLOCK18)|(1<<CSW_DEAGLE)

const 
PEV_ADDITIONAL_AMMO pev_iuser1

/*================================================================================
    The code starts here
================================================================================*/

public plugin_precache()
{
    
// Register all our cvars
    
cvar_welcomemsg register_cvar("zp_xp_welcomemsg""1");
    
cvar_removeweapons register_cvar("zp_xp_removeweapons""0");
    
cvar_removexp register_cvar("zp_xp_removexp""0");
    
cvar_removezombie register_cvar("zp_xp_removezombie""0");
}

public 
plugin_init()
{

          
    
// Register the plugin
    
register_plugin(PLUGIN_NAMEPLUGIN_VERSION"Huh?")
    
    
// Language files
    
register_dictionary("zombie_xp.txt")

    
// Register the menus
    
register_menu("Game Menu"KEYSMENU"menu_game")
    
register_menu("Zombie Class Menu"KEYSMENU"menu_zclass")
    
register_menu("Human Class Menu"KEYSMENU"menu_hclass")
    
    
// For setting human's skills
    
register_forward(FM_PlayerPreThink"fw_PlayerPreThink")
    
    
// For setting the user human on connecting
    
RegisterHam(Ham_Spawn"player""fw_PlayerSpawn_Post"1)
    
    
// For setting humans speed also
    
register_logevent("logevent_round_start",2"1=Round_Start")
    
    
// Register event round start for humans
    
register_event("HLTV""event_round_start""a""1=0""2=0");
    
    
// Register forward for our plugins
    
g_fwRoundStart CreateMultiForward("zp_round_started_human"ET_IGNOREFP_CELL)
        
    
// Set our vars to disable zombie plague functions
    
set_task(1.0"set_cvars")
    
    
// Register variables
    
pcvars[enable] = register_cvar("zp_xp_enable""1")
    
pcvars[packslevelup] = 15 
    
    
// Register client commands
    
register_clcmd("zp_xp_costscale""SetPacksLevelUp")
    
register_clcmd("zp_xp_set_level""SetLevel")
    
register_clcmd("zp_xp_removexp""RemoveXP")
    
register_clcmd("zp_xp_removezombies""RemoveZombies")
    
register_clcmd("zp_xp_removeweapons""RemoveWeapons")
    
    
//trigger for handling the menu
    #if defined TRIGGER_ZP_ITEM
    
    #endif
    #if defined TRIGGER_SAYMENU
    
register_clcmd("say xp""handle_say_xp")
    
register_clcmd("say level""handle_say_level")
    
register_clcmd("say nivel""handle_say_level")
    
register_clcmd("say xpmenu""handle_say_xpmenu")
    
#endif
        
    //Settings variables
    
g_msgSayText get_user_msgid("SayText")
    
    
// Format mod name
    
formatex(g_modnamesizeof g_modname 1"Zombie XP %s"PLUGIN_VERSION)
    
    
// Get Max Players
    
g_maxplayers get_maxplayers()
    
    
//nVault
    
gvault nvault_open(PLUGIN_NAME);
    
    
//for our HUD (shows level on screen)
    
g_MsgSync2 CreateHudSyncObj()
}

public 
set_cvars()
{
    
// Disable zombie_plague's zombie auto menu
    
if( get_pcvar_num(cvar_removezombie) == 0set_cvar_num("zp_zombie_classes"0);
    if( 
get_pcvar_num(cvar_removeweapons) == 0set_cvar_num("zp_buy_custom"0);
}

public 
plugin_natives()
{
    
//natives
    
register_native("zpxp_register_extra_item""native_register_extra_item"1)
    
register_native("zpxp_register_human_class""native_register_human_class"1)
    
register_native("zpxp_register_zombie_class""native_register_zombie_class"1)
    
register_native("zp_get_user_human_class""native_get_user_human_class"1)
}

public 
plugin_end()
{
    if( 
get_pcvar_num(cvar_removexp) == 0)
    {
        
// Save everyone's data first
        
server_print("%s Saving your clients XP."textHeader);
    
        for( new 
133o++)
        {
            
//if ( !is_user_connected(o) || is_user_bot(o) ) continue;
            
if ( !is_user_connected(o) ) continue;
            if ( 
is_user_bot(o) ) continue;
            
            
save_data(o);
        }
    }

    
nvault_close(gvault)
    
    
//Bugfix:
    
if( (loadedZombies == false) && ( get_pcvar_num(cvar_removezombie) == )) 
    {
        
set_pcvar_num(cvar_removezombie0);
        
set_cvar_num("zp_zombie_classes"0)    
    }
}

#if defined TRIGGER_SAYMENU
public handle_say_xp(id)
{
    
    
#if defined ZP_BINDMENU
    
new strLetter[2];
    
copy(strLettersizeof strLetter 1ZP_BINDMENU);
    
strtoupper(strLetter);
    
strtoupper(ZP_BINDMENU);
    
    
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"SAY_INFO_KEY"strLetter)
    
#else
    
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"SAY_INFO")    
    
#endif
    
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"SAY_XP"pcvars[packslevelup] * userLevel[id], userLevel[id])
    return 
PLUGIN_HANDLED
}
public 
handle_say_level(id)
{
        
//return level
        
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"SAY_LEVEL"userLevel[id])
        
zp_colored_print(id"[Clan nK]^x03 %s^x01 tiene^x04 %s^x01 niveles "userNameID[id], userLevel[id])
        return 
PLUGIN_HANDLED

public 
handle_say_class(id)
{
    
//return class
    
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"SAY_CLASS"g_hclass_name[g_humanclass[id]], g_zclass_name[g_zombieclass[id]])
    return 
PLUGIN_HANDLED
}
public 
handle_say_xpmenu(id)
{
    
show_menu_game(id);
    return 
PLUGIN_HANDLED
}
#endif

#if defined TRIGGER_ZP_ITEM
public zp_extra_item_selected(playeritemid)
{
    if(
itemid == g_TriggerItem)
    {
        
//show the menu
        
show_menu_game(player);
    }
}
#endif

#if defined ZP_BANK_AUTOSAVE
public getAmmoPacks(id)
{
    return 
zp_bank_get_packs(id);
}
public 
setAmmoPacks(idvalue)
{
    return 
zp_bank_set_packs(idvalue);
}
#else
public getAmmoPacks(id)
{
    return 
zp_get_user_ammo_packs(id);
}
public 
setAmmoPacks(idvalue)
{
    return 
zp_set_user_ammo_packs(idvalue);
}
#endif


public SetLevel(id)
{    
    
//Multilang is not enabled here since I plan to remove this funtionality once this leaves BETA
    #if defined ZP_GAMERUINER
    
if ( read_argc() > ) return PLUGIN_HANDLED;
        
    new 
arg1[32], arg2[10], amount;
    
read_argv(1arg1sizeof(arg1) - 1);
    
read_argv(2arg2sizeof(arg2) - 1);
    
    
amount str_to_num(arg2);
    if( 
amount <= 0amount 1;
    new 
target cmd_target(0arg12);

    if ( 
target == )
    {
        
//couldnt find them
        
zp_colored_print(id"^x04%s^x01 Could not find the requested user."textHeader);
        
        return 
PLUGIN_HANDLED;

    } else { 

        
//we found them!
        
userLevel[id] = amount
        ShowHUD
(id)
        
        if(
id == target)
        {
            
zp_colored_print(id"^x04%s^x01 You have set yourself to level %d!"textHeaderamount );
        } else {
            new 
targetName[64];
            
get_user_name(targettargetName63);

            
zp_colored_print(id"^x04%s^x01 You have set %s to level %d!"textHeader targetNameamount );
            
zp_colored_print(target"^x04%s^x01 You have been set to level %d!"textHeader amount );
        }
        return 
PLUGIN_HANDLED;
    }
    
#else
    
zp_colored_print(id"^x04%s^x01 This functionality has been disabled."textHeader);
    
client_print(idprint_console"^x04%s^x01 This functionality has been disabled."textHeader);
    
#endif
    
return PLUGIN_HANDLED;
    


public 
getNeededPacks(id)
{
    
//return the packs needed for leveling up
    
return pcvars[packslevelup] * userLevel[id]
}

public 
SetPacksLevelUp(idvalue)
{
    
//this allows the user to change the multiplier for ammo cost
    
new arg[10], arg2
    read_argv
(1argsizeof arg 1)
    
    
arg2 str_to_num(arg)
    if(
arg2 0)
    {
        
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM")
        
pcvars[packslevelup] = arg2;
        
        
//go through each player and change the amount required to level up
        
for( new 133o++)
        {
            if ( !
is_user_connected(o) ) continue;
            
userNeededPacks[id] = getNeededPacks(id)
        }
    } else {
        
//must be a positive number - PRINTS TO CONSOLE, LEAVE ALONE!
        
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_NEGATIVE");
        
client_print(idprint_console"%s %L"textHeaderid"ERR_NEGATIVE")
    }
    
    return 
PLUGIN_HANDLED;
}


//-----------------------CVAR Handlers--------------------------

public RemoveXP(id)
{
    
//this allows the user to enable or disable XP
    
new arg[10], arg2
    read_argv
(1argsizeof arg 1)
    
    
arg2 str_to_num(arg)
    if(
arg2 >= 0)
    {
        if(
arg2 == 1) {
            
// Disable the XP
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ADMIN_CONFIRM");
            
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM")
            
set_pcvar_num(cvar_removexparg2);
            
        } else if (
arg2 == 0) {
            
// Enable the XP
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ADMIN_CONFIRM");
            
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM")
            
set_pcvar_num(cvar_removexparg2);
            
        } else {
            
// They typed something wrong
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_INVALIDENTRY");
            
client_print(idprint_console"%s %L"textHeaderid"ERR_INVALIDENTRY");
            return 
PLUGIN_HANDLED;
        }
    } else {
        
//must be a positive number - PRINTS TO CONSOLE, LEAVE ALONE!
        
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_NEGATIVE");
        
client_print(idprint_console"%s %L"textHeaderid"ERR_NEGATIVE")
    }
    
    return 
PLUGIN_HANDLED;
    
}

public 
RemoveZombies(id)
{
    
//this allows the user to enable or disable zombie classes
    
new arg[10], arg2
    read_argv
(1argsizeof arg 1)
    
    
arg2 str_to_num(arg)
    if(
arg2 >= 0)
    {
        if (
arg2 == 0) {
            
// Enable the zombie classes
            
            
if( loadedZombies == true )
            {
                
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ADMIN_CONFIRM");
                
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM")
                
set_pcvar_num(cvar_removezombie0);
                
set_cvar_num("zp_zombie_classes"0)
            } else {
                
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ADMIN_CONFIRM_NEXTROUND");
                
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM_NEXTROUND")
                
//set_pcvar_num(cvar_removezombie, 0);
                //set_cvar_num("zp_zombie_classes", 0)            
            
}
        } else if (
arg2 == 1) {
            
// Disable the zombie classes
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ADMIN_CONFIRM");
            
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM")
            
set_pcvar_num(cvar_removezombie1);
            
set_cvar_num("zp_zombie_classes"1)
            
        } else if (
arg2 == 2) {
            
// Disable, and dont add zombies to zombie plague
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ADMIN_CONFIRM_NEXTROUND");
            
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM_NEXTROUND")
            
set_pcvar_num(cvar_removezombie1);
            
set_cvar_num("zp_zombie_classes"2)
            
        } else {
            
// They typed something wrong
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_INVALIDENTRY");
            
client_print(idprint_console"%s %L"textHeaderid"ERR_INVALIDENTRY");
            return 
PLUGIN_HANDLED;
            
        }
    } else {
        
//must be a positive number - PRINTS TO CONSOLE, LEAVE ALONE!
        
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_NEGATIVE");
        
client_print(idprint_console"%s %L"textHeaderid"ERR_NEGATIVE")
    }
    
    return 
PLUGIN_HANDLED;
    
}

public 
RemoveWeapons(id)
{
    
//this allows the user to enable or disable zombie classes
    
new arg[10], arg2
    read_argv
(1argsizeof arg 1)
    
    
arg2 str_to_num(arg)
    if(
arg2 >= 0)
    {
        if(
arg2 == 1) {
            
// Disable the custom human weapons
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ADMIN_CONFIRM");
            
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM")
            
set_pcvar_num(cvar_removeweapons1);
            
set_cvar_num("zp_buy_custom"1);
            
        } else if (
arg2 == 0) {
            
// Enable the custom human weapons
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ADMIN_CONFIRM");
            
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM")
            
set_pcvar_num(cvar_removeweapons0);
            
set_cvar_num("zp_buy_custom"0);
            
        } else {
            
// They typed something wrong
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_INVALIDENTRY");
            
client_print(idprint_console"%s %L"textHeaderid"ERR_INVALIDENTRY");
            return 
PLUGIN_HANDLED;
        }
    } else {
        
//must be a positive number - PRINTS TO CONSOLE, LEAVE ALONE!
        
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_NEGATIVE");
        
client_print(idprint_console"%s %L"textHeaderid"ERR_NEGATIVE")
    }
    
    return 
PLUGIN_HANDLED;
    
}

public 
show_menu_game(id)
{
    
// Show our menu
    
static menu[250], lenindex;
    
len 0
    index 
1;
    
    
// Title
    
len += formatex(menu[len], sizeof menu len"\y%s^n^n"g_modname)
    
    if( 
get_pcvar_num(cvar_removexp) == )
    {
        
// 1. Buy a level up
        
if(getAmmoPacks(id) >= getNeededPacks(id))
        {
            
len += formatex(menu[len], sizeof menu len"\r%d.\w %L"indexid"MENU_BUY_XP")
            
len += formatex(menu[len], sizeof menu len" \y%d %L^n"getNeededPacks(id), id"AMMO_PACKS_XP")
        } else {
            
len += formatex(menu[len], sizeof menu len"\d%d. %L"indexid"MENU_BUY_XP")
            
len += formatex(menu[len], sizeof menu len" \d%d %L^n"getNeededPacks(id), id"AMMO_PACKS_XP")
        }

        
index++;
    }

    
//Human class
    
len += formatex(menu[len], sizeof menu len"\r%d.\w %L^n"indexid,"MENU_HCLASS")
    
    if (
get_pcvar_num(cvar_removezombie) == 0)
    {
        
//Zombie class
        
index++;
        
len += formatex(menu[len], sizeof menu len"\r%d.\w %L^n"indexid,"MENU_ZCLASS")
    }

    
// 0. Exit
    
len += formatex(menu[len], sizeof menu len"^n^n\r0.\w %L"id"MENU_EXIT")
    
    
show_menu(idKEYSMENUmenu, -1"Game Menu")
}

public 
save_data(id)
{
    new 
vaultkey[40],vaultData[256];
        
    new 
g_selected_zclass[sizeof g_zclass_load[]] , g_selected_hclass[sizeof g_hclass_load[]] //bug fix for not showing menu if the user hasnt picked a zombie
    
if( g_hclass_showmenu[id] == true) { g_selected_hclass "-1"; } else { formatex(g_selected_hclasssizeof g_selected_hclass 1g_hclass_load[g_humanclassnext[id]]); }
    if( 
g_zclass_showmenu[id] == true) { g_selected_zclass "-1"; } else { formatex(g_selected_zclasssizeof g_selected_zclass -1g_zclass_load[g_zombieclassnext[id]]); }
    
    
formatexvaultkeysizeof vaultkey 1"%s_stats"userNameID[id]);
    
formatexvaultDatasizeof vaultData 1"0=%i;1=%s;2=%s;"userLevel[id], g_selected_hclassg_selected_zclass);
    
    
nvault_set(gvaultvaultkeyvaultData);
}

public 
load_data(id)
{
    if( 
get_pcvar_num(cvar_removexp) != 0)
    {
        
// Do not load or save data
        
g_hclass_showmenu[id] = true;
        
g_zclass_showmenu[id] = true;
        return;
    }
    
    new 
vaultkey[40], vaultReturn[256];
    new 
vaultData[4][40], vaultResults[3][40];
    
    
// Get the Level
    
format(vaultkeysizeof vaultkey 1"%s_stats"userNameID[id]);
    
nvault_get(gvaultvaultkeyvaultReturnsizeof vaultReturn 1); 
    
    new 
Count ExplodeString(vaultDatasizeof vaultData 1sizeof vaultData[] - 1vaultReturn';')
        
    if(
Count == sizeof vaultResults 1)
    {
        new 
ivaultLeveli_hclass_id = -1i_zclass_id = -1;
        
        for( new 
0sizeof vaultData 1i++)
        {
            
ExplodeString(vaultResultssizeof vaultResults 1sizeof vaultResults[] - 1vaultData[i], '=');
            
            
// We now have our items
            
switch (str_to_num(vaultResults[0]))
            {
                case 
VAULT_LEVEL:
                {    
                    
ivaultLevel str_to_num(vaultResults[1]);
                    
                    if (
ivaultLevel == 0ivaultLevel 1;
                    
userLevel[id] = ivaultLevel
                
}
                
                case 
VAULT_HCLASS:
                {
                    
// Look for our human class
                    
if( !equali(vaultResults[1], "-1") )
                    {
                        for (new 
i2 0i2 g_hclass_ii2++)
                        {
                            if( 
equali(vaultResults[1], g_hclass_load[i2]) )
                            {
                                
i_hclass_id i2;
                                break;
                            }
                        }
                    }
                
                    if ( 
i_hclass_id == -1)
                    {
                        
// Couldnt find them
                        
g_hclass_showmenu[id] = true;
                    } else {
                        
// We found their zombie class
                        
g_humanclassnext[id] = i_hclass_id;
                        
g_hclass_showmenu[id] = false;
                    }
                }
                
                case 
VAULT_ZCLASS:
                {
                    if( !
equali(vaultResults[1], "-1") )
                    {
                        for (new 
i2 0i2 g_zclass_ii2++)
                        {
                            if( 
equali(vaultResults[1], g_zclass_load[i2]) )
                            {
                                
i_zclass_id i2;
                                break;
                            }
                        }
                    }
                    
                    if ( 
i_zclass_id == -1)
                    {
                        
g_zclass_showmenu[id] = true;
                    } else {
                        
g_zombieclassnext[id] = i_zclass_id;
                        
g_zclass_showmenu[id] = false;
                        
zp_set_user_zombie_class(idi_zclass_id);
                    }
                }
            }
        }
    } else {
        
g_hclass_showmenu[id] = true;
        
g_zclass_showmenu[id] = true;

    }    
}

public 
client_connect(id)
{
    
// Do we bind a key
    #if defined ZP_BINDMENU
    
client_cmd(id,"bind %s ^"say xpmenu^""ZP_BINDMENU);
    
#endif
}
public 
client_putinserver(id)
{
    
// Reset vars
    
resetvars(id)
        
    
// Make sure zombieplague doesnt load the last plugin as the default zombie
    
zp_set_user_zombie_class(id0)
    
    
// Load their data
    
load_data(id);
    
    
// Set amount of levels to level up (called after load_data)
    
userNeededPacks[id] = getNeededPacks(id)
    
    
// Set the custom HUD display task
    
set_task(1.0"ShowHUD"id+TASK_SHOWHUD__"b")
}

public 
client_disconnect(id)
{
    
// Save the data
    
save_data(id);
    
    
// Remove tasks
    
remove_task(id+TASK_SHOWHUD)
}

public 
fw_PlayerSpawn_Post(id)
{
    
// Both humans and zombies spawn and call this
    // Zombies can respawn if deathmatch is enabled
    
    //TODO: Check if this works
    
if (zp_get_user_zombie(id)) 
        return 
FMRES_IGNORED;
    
    if (!
is_user_alive(id)) // you could also use is_user_connected()
        
return FMRES_IGNORED;
        
    
// Set selected human and zombie class
    
g_humanclass[id] = g_humanclassnext[id]
    
g_zombieclass[id] = g_zombieclassnext[id]
    
    
// Change the default human variables
    
humanme(id)
            
    
// We know for sure they are a human, only give guns+speed+grav if they've picked a class
    
if (( g_hclass_showmenu[id] == false ) && (get_pcvar_num(cvar_removeweapons) == 0))
    {    
        
setHumanParameters(id)
        
giveWeapons(id//give weapons
    
}

    return 
FMRES_IGNORED;
}

public 
event_round_start()
{
    static 
team;
    
    
// Set our humans hp, speed, etc
    
for( new 133o++)
    {
        
// Not connected
        
if ( !is_user_connected(o) ) continue;
        
        
// Not playing
        
team fm_get_user_team(o)
        if (
team == CS_TEAM_SPECTATOR || team == CS_TEAM_UNASSIGNED) continue;
        
        
// Set our human vars
        //humanme(o)
        
        // Our next vars are now current
        //g_humanclass[o] = g_humanclassnext[o]
        //g_zombieclass[o] = g_zombieclassnext[o]
        
        // The round has started
        
ExecuteForward(g_fwRoundStartg_fwDummyResulto);
    }
    
    
// Set our vars
    
g_freezetime true
    
    
// Do we show a welcome message?
    
if( get_pcvar_num(cvar_welcomemsg) )
        
set_task(2.0"welcome_msg")
}

public 
zp_user_infected_pre(idinfector)
{
    
// Make sure he is not a human
    
g_human[id] = false
    
    
// Strip his guns (so they dont fall on the floor)
    
strip_weapons(id);
}

public 
zp_user_infected_post(idinfector)
{
    
// Do we show the menu?
    
if ((g_zclass_showmenu[id] == true) && get_pcvar_num(cvar_removezombie) ==0show_menu_zclass(id);

}
            
public 
zp_user_humanized_pre(id)
{    
    
// Set selected human class, incase he buys antidote
    
g_humanclass[id] = g_humanclassnext[id];
    
g_zombieclass[id] = g_zombieclassnext[id];
}

public 
zp_user_humanized_post(id)
{    
    
// Hes become human again, set our vars
    
if( !zp_get_user_survivor(id) )
    {
        
humanme(id)        
        
setHumanParameters(id)
        if( 
get_pcvar_num(cvar_removeweapons) == 0giveWeapons(id//give weapons
    
} else {
        
// He has become a survivor
        
g_human[id] = false
    
}
    
    
ShowHUD(id)
}




enum
{
    
WEAPON_GALIL 0,
    
WEAPON_FAMAS,
    
WEAPON_M4A1,
}

public 
humanme(id)
{
    
// Set our human's height, jump, etc
    
    
if( g_hclass_showmenu[id] == true)
    {
        
// They just entered, and no data was loaded for them
        // Show the menu (despite the fact that they are automatically lvl. 1)
        
if (get_pcvar_num(cvar_removezombie) == 0)
        { 
set_task(0.1"show_menu_hclass"id); } else { set_task(0.5"show_menu_hclass"id); }
    }
    
    
// They are human
    
g_human[id] = true;
}

public 
giveWeapons(id)
{
    
// Strip weapons first
    
strip_weapons(id);
    
    
// Give all weapons (everything is in g_hclass_weapons)
    
static iweaponid;
    for (
0sizeof g_hclass_weaponsi++)
    {
        
weaponid g_hclass_weapons[g_humanclass[id]][i];
        
        if (
weaponid >= && weaponid <= 14) {
            
// Give main weapon
            
give_primary_weapon(idweaponid 1);
    
        } else if ( 
weaponid >= 15 && weaponid <= 20)  {
            
// Give secondary gun
            
give_secondary_weapon(idweaponid 15);
            
        } else if ( 
weaponid >= 21 && weaponid <=23) {
            
// Give grenades
            
fm_give_item(idg_additional_items[weaponid 21]);
            
        } else {
            
// We have given them all their item, or they dont have any
            
return;
        }
    }    
}

public 
setHumanParameters(id)
{
    
set_pev(idpev_gravityg_hclass_grav[g_humanclass[id]])
    
fm_set_user_health(idg_hclass_hp[g_humanclass[id]])
}

public 
resetvars(id)
{
    
// This should only be called whenever a person connects!
    // Otherwise it erases a persons choices
    // Reset our human's variables
    
g_zombieclassnext[id] = 0
    
g_humanclassnext[id] = 0;
    
g_zombieclass[id] = 0;
    
g_humanclass[id] = 0;
    
    
g_hclass_showmenu[id] = false;
    
g_zclass_showmenu[id] = false;
    
    
userLevel[id] = 1;
    
    
get_user_name(iduserNameID[id], 31)
    
g_resetparams[id] = false
}

/*================================================================================
Begin Functions from the internet
================================================================================*/

//http://forums.alliedmods.net/showthread.php?p=67207#post67207
stock ExplodeStringOutput[][], MaxSizeInput[], Delimiter )
{
    new 
Idxstrlen(Input), Len;
    do 
Len += (copycOutput[Idx], SizeInput[Len], Delimiter ));
    while( (
Len l) && (++Idx Max) )
    return 
Idx;
}


/*================================================================================
Begin Code from zombie_plague (modified to suit the plugin)
================================================================================*/

// Set player's health (from fakemeta_util)
stock fm_set_user_health(idhealth)
{
    (
health 0) ? set_pev(idpev_healthfloat(health)) : dllfunc(DLLFunc_ClientKillid);
}


// Forward Player PreThink
public fw_PlayerPreThink(id)
{
    
// Not alive
    
if (!is_user_alive(id)) return;
    
    
// Not human, survivor will count as not a human
    
if(!g_human[id]) return;
    
    
// Set Player MaxSpeed
    
if (!g_freezetime)
    {
        if (
g_human[id])
        {
            
set_pev(idpev_maxspeedfloat(g_hclass_spd[g_humanclass[id]]))
            return
        }
    }
}

public 
show_menu_zclass(id)
{    
    
// Player disconnected
    
if (!is_user_connected(id))
        return;
    
    
// Bots pick default classes
    
if (is_user_bot(id))
    {
        
g_zombieclassnext[id] = //basic zombie
        
return;
    }
    
    static 
menu[800], len, class, removexp;
    new 
curClassIcon[2];
    
    
len 0
    removexp 
get_pcvar_num(cvar_removexp);
    
    
// Title
    
len += formatex(menu[len], sizeof menu len"\y%L \r [%d-%d]^n^n"id"MENU_ZCLASS_TITLE"ZCLASSES_STARTID+1min(ZCLASSES_STARTID+7g_zclass_i))
    
    
#if defined ZP_ALIGN_TEXT
    // Align text
    
new spacers[400], g_zclass_spacers1g_zclass_spacers2
    
new maxSpace1maxSpace2curSpace1[32], curSpace2[32]

    
// Get max width first
    
for (class = ZCLASSES_STARTID; class < min(ZCLASSES_STARTID+7g_zclass_i); class++)
    {
        
formatex(spacerssizeof spacers 1"%d. %s", class-ZCLASSES_STARTID+1g_zclass_name[class])
        
        
g_zclass_spacers1 strlen(spacers)
        
g_zclass_spacers2 strlen(g_zclass_info[class])
        
        if(
g_zclass_spacers1 maxSpace1maxSpace1 g_zclass_spacers1
        
if(g_zclass_spacers2 maxSpace2maxSpace2 g_zclass_spacers2
    
}
        
    
// 1-7. Class List
    
for (class = ZCLASSES_STARTID; class < min(ZCLASSES_STARTID+7g_zclass_i); class++)
    {
    
    if (
g_zclass_lvl[id] >= g_zclass_lvl[class])
        {
            if (class == 
g_zombieclassnext[id])
                
len += formatex(menu[len], sizeof menu len"\d%d. %s %s^n", class-ZCLASSES_STARTID+1g_zclass_name[class], g_zclass_info[class])
            else
                
len += formatex(menu[len], sizeof menu len"\r%d.\w %s\y %s^n", class-ZCLASSES_STARTID+1g_zclass_name[class], g_zclass_info[class])
        }
        else
            
len += formatex(menu[len], sizeof menu len"\r%d.\d %s %s\r (Nivel Requerido: %d)^n", class-ZCLASSES_STARTID+1g_zclass_name[class], g_zclass_info[class], g_zclass_lvl[class])
    }
    
#else
    
for (class = ZCLASSES_STARTID; class < min(ZCLASSES_STARTID+7g_zclass_i); class++)
    {
        if (((class == 
g_zombieclassnext[id] && g_zclass_showmenu[id] == false) || (userLevel[id] < g_zclass_lvl[class])) && (removexp == 0))
        {    
            if (class == 
g_zombieclassnext[id]) { curClassIcon "*"; } else { curClassIcon ""; }
            
            
len += formatex(menu[len], sizeof menu len"\d%s%d. %s - %s - %L %d^n"curClassIcon, class-ZCLASSES_STARTID+1g_zclass_name[class], g_zclass_info[class], id"BOTH_ATTRIB_LEVEL"g_zclass_lvl[class])
        } else if (
removexp == 1) {
            
len += formatex(menu[len], sizeof menu len"\r%d.\w %s -\y %s^n", class-ZCLASSES_STARTID+1g_zclass_name[class], g_zclass_info[class]);
        } else {
            
len += formatex(menu[len], sizeof menu len"\r%d.\w %s -\y %s\w - %L %d^n", class-ZCLASSES_STARTID+1g_zclass_name[class], g_zclass_info[class], id"BOTH_ATTRIB_LEVEL"g_zclass_lvl[class]);
        }
    }
    
#endif
    
    // 8. Back - 9. Next - 0. Exit
    
len += formatex(menu[len], sizeof menu len"^n\r8.\w %L^n\r9.\w %L^n^n\r0.\w %L"id"MENU_BACK"id"MENU_NEXT"id"MENU_EXIT")
    
    
show_menu(idKEYSMENUmenu, -1"Zombie Class Menu")
}


public 
show_menu_hclass(id)
{
    
// Player disconnected
    
if (!is_user_connected(id))
        return;
    
    
// Bots pick default classes
    
if (is_user_bot(id))
    {
        
g_humanclassnext[id] = 0
        
return;
    }
    
    static 
menu[800], len, class, removexp
    
new curClassIcon[2]
    
len 0
    removexp 
get_pcvar_num(cvar_removexp);
    
    
// Title
    
len += formatex(menu[len], sizeof menu len"\y%L \r[%d-%d]^n^n"id"MENU_HCLASS_TITLE"HCLASSES_STARTID+1min(HCLASSES_STARTID+7g_hclass_i))
    
    
#if defined ZP_ALIGN_TEXT
    // Align text
    
new spacers[400], g_hclass_spacers1g_hclass_spacers2
    
new maxSpace1maxSpace2curSpace1[32], curSpace2[32]

    
// Get max width first
    
for (class = HCLASSES_STARTID; class < min(HCLASSES_STARTID+7g_hclass_i); class++)
    {
        
formatex(spacerssizeof spacers 1"%d. %s", class-HCLASSES_STARTID+1g_hclass_name[class])
        
        
g_hclass_spacers1 strlen(spacers)
        
g_hclass_spacers2 strlen(g_hclass_info[class])
        
        if(
g_hclass_spacers1 maxSpace1maxSpace1 g_hclass_spacers1
        
if(g_hclass_spacers2 maxSpace2maxSpace2 g_hclass_spacers2
    
}
        
    
// 1-7. Class List
    
for (class = HCLASSES_STARTID; class < min(HCLASSES_STARTID+7g_hclass_i); class++)
    {
        
formatex(spacerssizeof spacers 1"%d. %s", class-HCLASSES_STARTID+1g_hclass_name[class])
        
        
g_hclass_spacers1 maxSpace1 strlen(spacers)
        
g_hclass_spacers2 maxSpace2 strlen(g_hclass_info[class])
            
        
arrayset(curSpace1'^0'sizeof curSpace1 1)
        
arrayset(curSpace2'^0'sizeof curSpace2 1)
        
        if(
g_hclass_spacers1 != 0arrayset(curSpace1'^t'g_hclass_spacers1)
        if(
g_hclass_spacers2 != 0arrayset(curSpace2'^t'g_hclass_spacers2)
        
        if (((class == 
g_humanclassnext[id] && g_hclass_showmenu[id] == false) || (userLevel[id] < g_hclass_lvl[class])) && (removexp == 0))
        {    
            if (class == 
g_humanclassnext[id]) { curClassIcon "*"; } else { curClassIcon ""; }
            
            
len += formatex(menu[len], sizeof menu len"\d%s%d. %s %s %s %s %L %d^n"curClassIcon, class-HCLASSES_STARTID+1g_hclass_name[class], curSpace1g_hclass_info[class], curSpace2id"BOTH_ATTRIB_LEVEL"g_hclass_lvl[class])
        } else if (
removexp == 1) {
            
len += formatex(menu[len], sizeof menu len"\r%d.\w %s\y %s %s^n", class-HCLASSES_STARTID+1g_hclass_name[class], curSpace1g_hclass_info[class])
        } else {
            
len += formatex(menu[len], sizeof menu len"\r%d.\w %s\y %s %s\w %s %L %d^n", class-HCLASSES_STARTID+1g_hclass_name[class], curSpace1g_hclass_info[class], curSpace2id"BOTH_ATTRIB_LEVEL"g_hclass_lvl[class])
        }
    }
    
    
#else
    
for (class = HCLASSES_STARTID; class < min(HCLASSES_STARTID+7g_hclass_i); class++)
    {
        if (((class == 
g_humanclassnext[id] && g_hclass_showmenu[id] == false) || (userLevel[id] < g_hclass_lvl[class])) && (removexp == 0))
        {
            if (class == 
g_humanclassnext[id]) { curClassIcon "*"; } else { curClassIcon ""; }
            
            
len += formatex(menu[len], sizeof menu len"\d%s%d. %s - %s - %L %d^n"curClassIcon, class-HCLASSES_STARTID+1g_hclass_name[class], g_hclass_info[class], id"BOTH_ATTRIB_LEVEL"g_hclass_lvl[class])
        } else if (
removexp == 1) {
            
len += formatex(menu[len], sizeof menu len"\r%d.\w %s -\y %s^n", class-HCLASSES_STARTID+1g_hclass_name[class], g_hclass_info[class]);
        } else {
            
len += formatex(menu[len], sizeof menu len"\r%d.\w %s -\y %s\w - %L %d^n", class-HCLASSES_STARTID+1g_hclass_name[class], g_hclass_info[class], id"BOTH_ATTRIB_LEVEL"g_hclass_lvl[class])
        }
    }
    
#endif
    
    // 8. Back - 9. Next - 0. Exit
    
len += formatex(menu[len], sizeof menu len"^n\r8.\w %L^n\r9.\w %L^n^n\r0.\w %L"id"MENU_BACK"id"MENU_NEXT"id"MENU_EXIT")
    
    
show_menu(idKEYSMENUmenu, -1"Human Class Menu")
}

/* ----------------------- Menu Handlers -------------------------*/

// Game Menu
public menu_game(idkey)
{
    if(
get_pcvar_num(cvar_removexp) == 1key++;
    
    switch (
key)
    {
        case 
0// Buy a level up
        
{
            if(
getAmmoPacks(id) >= getNeededPacks(id))
            {
                
setAmmoPacks(idgetAmmoPacks(id) - getNeededPacks(id))
                
userLevel[id] += 1
                save_data
(id)
                
                
// Inform the user they leveled up
                
zp_colored_print(id"^x04%s^x01 %L %d"textHeaderid ,"MENU_BUY_LEVEL"userLevel[id])
                
ShowHUD(id)
            } else {
                
zp_colored_print(id"^x04%s^x01 %L"textHeaderid ,"ERR_NOTENOUGHPACKS")
            }
            
            
// Return to the main xp menu
            
show_menu_game(id);
            
        }
        
        case 
1// Human Classes
        
{
            
// Restrict it here if we wanted to
            
show_menu_hclass(id)
        }
        
        case 
2// Zombie Classes
        
{
            if (
get_pcvar_num(cvar_removezombie) == 0)
            {
                
// Restrict it here if we wanted to
                
show_menu_zclass(id)
            }
        }
    }
    
    return 
PLUGIN_HANDLED;
}

// Zombie Class Menu
public menu_zclass(idkey)
{
    
// Special keys / items list exceeded
    
if (key >= MENU_KEY_BACK || ZCLASSES_SELECTION >= g_zclass_i)
    {
        switch (
key)
        {
            case 
MENU_KEY_BACK// back
            
{
            if (
ZCLASSES_STARTID->= 0ZCLASSES_STARTID -= 
            
}
            case 
MENU_KEY_NEXT// next
            
{
                if (
ZCLASSES_STARTID+g_zclass_iZCLASSES_STARTID += 7
            
}
            case 
MENU_KEY_EXIT// exit
            
{
                return 
PLUGIN_HANDLED;
            }
        }
        
        
// Show extra items menu again
        
show_menu_zclass(id)
        return 
PLUGIN_HANDLED;
    } 
    
// They selected their own class
    
if (ZCLASSES_SELECTION == g_zombieclassnext[id])
    {
        
//Plugin continues if this is false (sets class info on connect)
        
if( g_zclass_showmenu[id] == false//when a client first connects, the menu shows all zombies as a choice even the one the client defaults to (index of 0)
        
{
            
// Alert them they already have chosen a zombie
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_ALREADYSELECTED")
            
show_menu_zclass(id)
            
            
// They had already chosen this zombie, dont rerun the command
            
return PLUGIN_HANDLED;
        }
    }
    
    if (
get_pcvar_num(cvar_removexp) == 0)
    {
        if (
g_zclass_lvl[HCLASSES_SELECTION] > userLevel[id])
        {
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_NOTLEVEL")
            
show_menu_zclass(id)
            return 
PLUGIN_HANDLED;
        }
    }
    
    
// Store selection for the next infection
    
g_zombieclassnext[id] = ZCLASSES_SELECTION;
    
    
// Disable showing menu since theyve chosen
    
g_zclass_showmenu[id] = false;
        
    
// Show selected zombie class info and stats
    
zp_colored_print(id"^x04%s^x01 %L: %s"textHeaderid"ZOMBIE_SELECT_XP"g_zclass_name[g_zombieclassnext[id]])
    
zp_colored_print(id"^x04%s^x01 %L: %d %L: %d %L: %d %L: %d%%"textHeaderid"ZOMBIE_ATTRIB1_XP"g_zclass_hp[g_zombieclassnext[id]], id"ZOMBIE_ATTRIB2_XP"g_zclass_spd[g_zombieclassnext[id]],
    
id"ZOMBIE_ATTRIB3_XP"floatround(g_zclass_grav[g_zombieclassnext[id]]*800), id"ZOMBIE_ATTRIB4_XP"floatround(g_zclass_kb[g_zombieclassnext[id]]*100))
    
    
// Set the class for zombie plague
    
zp_set_user_zombie_class(idg_zombieclassnext[id])
    
    return 
PLUGIN_HANDLED;
}

// Human Class Menu
public menu_hclass(idkey)
{
    
// Special keys / items list exceeded
    
if (key >= MENU_KEY_BACK || HCLASSES_SELECTION >= g_hclass_i)
    {
        switch (
key)
        {
            case 
MENU_KEY_BACK// back
            
{
                if (
HCLASSES_STARTID->= 0HCLASSES_STARTID -= 7
            
}
            case 
MENU_KEY_NEXT// next
            
{
                if (
HCLASSES_STARTID+g_hclass_iHCLASSES_STARTID += 7
            
}
            case 
MENU_KEY_EXIT// exit
            
{
                return 
PLUGIN_HANDLED;
            }
        }
        
        
// Show human list again
        
show_menu_hclass(id)
        return 
PLUGIN_HANDLED;
    }
    
    if (
HCLASSES_SELECTION == g_humanclassnext[id])
    {
        
// When a client first connects, the menu shows all zombies as a choice even the one the client defaults to (index of 0)
        
if( g_hclass_showmenu[id] == false)
        {
            
// Alert them they alaerdy have chosen a zombie
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_ALREADYSELECTED")
            
show_menu_hclass(id)
            return 
PLUGIN_HANDLED//they had already chosen this zombie, dont rerun the command
        
}
    }
    
    if (
get_pcvar_num(cvar_removexp) == 0)
    {
        if (
g_hclass_lvl[HCLASSES_SELECTION] > userLevel[id])
        {
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_NOTLEVEL")
            
show_menu_hclass(id)
            return 
PLUGIN_HANDLED;
        }
    }

    
// Store selection for the next infection
    
g_humanclassnext[id] = HCLASSES_SELECTION;
    
    
// Disable showing menu since theyve chosen
    
g_hclass_showmenu[id] = false;
    
    
// Show selected human class info and stats
    
zp_colored_print(id"^x04%s^x01 %L: %s"textHeaderid"HUMAN_SELECT_XP"g_hclass_name[g_humanclassnext[id]])
    
zp_colored_print(id"^x04%s^x01 %L: %d %L: %d %L: %d"textHeaderid"HUMAN_ATTRIB1_XP"g_hclass_hp[g_humanclassnext[id]], id"HUMAN_ATTRIB2_XP"g_hclass_spd[g_humanclassnext[id]],
    
id"HUMAN_ATTRIB3_XP"floatround(g_hclass_grav[g_humanclassnext[id]]*800), id)
    
    return 
PLUGIN_HANDLED;
}

public 
ShowHUD(taskid)
{
    
//if (get_pcvar_num(cvar_removexp) == 1 ) return;
    
    
static id;
    
    
// Our ID
    
id ID_SHOWHUD;
    
    
// Player died?
    
if (!is_user_alive(id))
    {
        
// Get spectating target
        
id pev(idPEV_SPEC_TARGET//other persons ID
        
        // Target not alive
        
if (!is_user_alive(id)) return;
    }
    
    
// Format the classname
    
static redgreenblueg_name[sizeof g_hclass_name]; // Hopefully g_zclass_name and g_zclass_name will be left the same array size 
    
    
if ( g_human[id] == false // zombies
    
{
        
red 0
        green 
255
        blue 
0
        
        formatex
(g_namesizeof g_name 1"%L"id"HUD_ZOMBIE");        
    }
    else 
// humans
    
{
        
red 0
        green 
255
        blue 
0
        
        copy
(g_namesizeof g_name 1g_hclass_name[g_humanclass[id]]);
    }
    
    if (
id != ID_SHOWHUD)
    {
        if (
get_pcvar_num(cvar_removexp) == 
        {
            
// Set our HUD in position for spectating
            
set_hudmessage(255255255HUD_SPECT_XHUD_SPECT_Y06.01.10.00.0, -1);
            
ShowSyncHudMsg(ID_SHOWHUDg_MsgSync2"%L: %s - %L: %d"ID_SHOWHUD"HUD_CLASS"g_nameID_SHOWHUD"HUD_LEVEL"userLevel[id]);
        } else {
            
// Just show the class information
            
set_hudmessage(255255255HUD_SPECT_XHUD_SPECT_Y06.01.10.00.0, -1);
            
ShowSyncHudMsg(ID_SHOWHUDg_MsgSync2"%L: %s"ID_SHOWHUD"HUD_CLASS"g_name);
        }
    } else {
        if (
get_pcvar_num(cvar_removexp) == 
        {
            
// Set our HUD in position for the player
            
set_hudmessage(redgreenblueHUD_STATS_XHUD_STATS_Y06.01.10.00.0, -1);
            
ShowSyncHudMsg(idg_MsgSync2"%L: %s - %L: %d^t^t^t"id"HUD_CLASS"g_nameid"HUD_LEVEL"userLevel[id]);
        } else {
            
// Just show the class information
            
set_hudmessage(redgreenblueHUD_STATS_XHUD_STATS_Y06.01.10.00.0, -1);
            
ShowSyncHudMsg(idg_MsgSync2"%L: %s^t^t^t"id"HUD_CLASS"g_name);    
        }
    }
}

// Native: native_get_user_human_class
public native_get_user_human_class(id)
{
    return 
g_humanclass[id];
}

// Native: zpxp_register_human_class
public native_register_human_class(const name[], const info[], const model[], const weapons[], hpspeedFloat:gravitylevel)
{
    
// Reached human classes limit
    
if (g_hclass_i >= sizeof g_hclass_name)
        return -
1;
    
    
// Strings passed byref
    
param_convert(1)
    
param_convert(2)
    
param_convert(3)
    
param_convert(4)
    
    
// Add the class
    
copy(g_hclass_name[g_hclass_i], sizeof g_hclass_name[] - 1name)
    
copy(g_hclass_info[g_hclass_i], sizeof g_hclass_info[] - 1info)
    
copy(g_hclass_model[g_hclass_i], sizeof g_hclass_model[] - 1model)
    
copy(g_hclass_weapons[g_hclass_i], sizeof g_hclass_weapons[] - 1weapons)
    
g_hclass_hp[g_hclass_i] = hp
    g_hclass_spd
[g_hclass_i] = speed
    g_hclass_grav
[g_hclass_i] = gravity
    g_hclass_lvl
[g_hclass_i] = level
    
    
    
// For the load_data and save_data
    
new tSave[40]
    
formatex(tSavesizeof tSave 1"%s%s"nameinfo);
    
replace_all(tSavesizeof tSave 1";""")
    
replace_all(tSavesizeof tSave 1" """)
    
g_hclass_load[g_hclass_i] =  tSave;
        
    
// Increase registered classes counter
    
g_hclass_i++
    
    
// Return id under which we registered the class
    
return g_hclass_i-1;
}

// Native: zpxp_register_zombie_class
public native_register_zombie_class(const name[], const info[], const model[], const clawmodel[], hpspeedFloat:gravityFloat:knockbacklevel)
{    
    
// Dont return -1, we wil get lots of server window print errors from the plugins
    
if( get_pcvar_num(cvar_removezombie) == 2) return 0;
    
    
//Bugfix for loading zombies
    
loadedZombies true;
    
    
// Strings passed byref
    
param_convert(1)
    
param_convert(2)
    
param_convert(3)
    
param_convert(4)
    
    
// Save the name, level required, and classid
    
copy(g_zclass_name[g_zclass_i], sizeof g_zclass_name[] - 1name)
    
copy(g_zclass_info[g_zclass_i], sizeof g_zclass_info[] - 1info)
    
copy(g_zclass_model[g_zclass_i], sizeof g_zclass_model[] - 1model)
    
copy(g_zclass_clawmodel[g_zclass_i], sizeof g_zclass_clawmodel[] - 1clawmodel)
    
    
g_zclass_hp[g_zclass_i] = hp
    g_zclass_spd
[g_zclass_i] = speed
    g_zclass_grav
[g_zclass_i] = gravity
    g_zclass_kb
[g_zclass_i] = knockback
    g_zclass_lvl
[g_zclass_i] = level
    
    
// For the load_data and save_data
    
new tSave[40]
    
formatex(tSavesizeof tSave 1"%s%s"nameinfo);
    
replace_all(tSavesizeof tSave 1";""")
    
replace_all(tSavesizeof tSave 1" """)
    
g_zclass_load[g_zclass_i] =  tSave;
    
    
// Get the classid from zombie plague
    
new g_returnclass_id;
    
g_returnclass_id zp_register_zombie_class(g_zclass_name[g_zclass_i], g_zclass_info[g_zclass_i], g_zclass_model[g_zclass_i], g_zclass_clawmodel[g_zclass_i], g_zclass_hp[g_zclass_i] / 2g_zclass_spd[g_zclass_i], g_zclass_grav[g_zclass_i], g_zclass_kb[g_zclass_i]);
    
    
// Make sure there was no error
    
if( g_returnclass_id == -)
    {
        
server_print("%s %L"textHeaderLANG_PLAYER"ERR_BADRETURN");
        return -
1
    
}
    
    
// Increase registered classes counter
    
g_zclass_i++
    
    
// Return id under which we registered the class
    
return g_zclass_i-1;
}

public 
native_register_extra_item(const name[], costteam)
{
    
//TO DO 
    
}

/*================================================================================
--The following are copied directly from zombie_plague, no reinventing wheels...
[Shared Functions]
=================================================================================*/

// Welcome Message Task
public welcome_msg()
{
    
// Show mod info
    
zp_colored_print(0"^x04%s^x01 %L"textHeaderOrigLANG_PLAYER"NOTICE_INFO_XP")
}

// Log Event Round Start
public logevent_round_start()
{
    
// Freezetime ends
    
g_freezetime false
}

// Get User Team
stock fm_get_user_team(id)
{
    return 
get_pdata_int(idOFFSET_CSTEAMSOFFSET_LINUX);
}

zp_colored_print(target, const message[], any:...)
{
    static 
buffer[512], iargscount
    argscount 
numargs()
    
    
// Send to everyone
    
if (!target)
    {
        static 
player
        
for (player 1player <= g_maxplayersplayer++)
        {
            
// Not connected
            
if (!is_user_connected(player))
                continue;
            
            
// Remember changed arguments
            
static changed[5], changedcount // [5] = max LANG_PLAYER occurencies
            
changedcount 0
            
            
// Replace LANG_PLAYER with player id
            
for (2argscounti++)
            {
                if (
getarg(i) == LANG_PLAYER)
                {
                    
setarg(i0player)
                    
changed[changedcount] = i
                    changedcount
++
                }
            }
            
            
// Format message for player
            
vformat(buffersizeof buffer 1message3)
            
            
// Send it
            
message_begin(MSG_ONEg_msgSayText_player)
            
write_byte(player)
            
write_string(buffer)
            
message_end()
            
            
// Replace back player id's with LANG_PLAYER
            
for (0changedcounti++)
                
setarg(changed[i], 0LANG_PLAYER)
        }
    }
    
    
// Send to specific target
    
else
    {
        
// Replace LANG_PLAYER with player id
        
for (2argscounti++)
        {
        if (
getarg(i) == LANG_PLAYER)
            
setarg(i0target)
        }
        
        
// Format message for player
        
vformat(buffersizeof buffer 1message3)
        
        
// Send it
        
message_begin(MSG_ONEg_msgSayText_target)
        
write_byte(target)
        
write_string(buffer)
        
message_end()
    }
}

/*================================================================================
    Code JUST for giving guns
================================================================================*/

// Drop primary/secondary weapons
stock drop_weapons(iddropwhat)
{
    
// Get user weapons
    
static weapons[32], numiweaponid
    num 
// reset passed weapons count (bugfix)
    
get_user_weapons(idweaponsnum)
    
    
// Loop through them and drop primaries or secondaries
    
for (0numi++)
    {
        
// Prevent re-indexing the array
        
weaponid weapons[i]
        
        if ((
dropwhat == && ((1<<weaponid) & PRIMARY_WEAPONS_BIT_SUM)) || (dropwhat == && ((1<<weaponid) & SECONDARY_WEAPONS_BIT_SUM)))
        {
            
// Get the weapon entity
            
static wname[32], weapon_ent
            get_weaponname
(weaponidwnamesizeof wname 1)
            
weapon_ent fm_find_ent_by_owner(-1wnameid);
            
            
// Hack: store weapon bpammo on PEV_ADDITIONAL_AMMO
            
set_pev(weapon_entPEV_ADDITIONAL_AMMOfm_get_user_bpammo(idweaponid))
            
            
// Player drops the weapon and looses his bpammo
            
engclient_cmd(id"drop"wname)
            
fm_set_user_bpammo(idweaponid0)
        }
    }
}

// Set User BP Ammo
stock fm_set_user_bpammo(idweaponamount)
{
    static 
offset
    
    
switch(weapon)
    {
        case 
CSW_AWPoffset OFFSET_AWM_AMMO;
        case 
CSW_SCOUT,CSW_AK47,CSW_G3SG1offset OFFSET_SCOUT_AMMO;
        case 
CSW_M249offset OFFSET_PARA_AMMO;
        case 
CSW_M4A1,CSW_FAMAS,CSW_AUG,CSW_SG550,CSW_GALI,CSW_SG552offset OFFSET_FAMAS_AMMO;
        case 
CSW_M3,CSW_XM1014offset OFFSET_M3_AMMO;
        case 
CSW_USP,CSW_UMP45,CSW_MAC10offset OFFSET_USP_AMMO;
        case 
CSW_FIVESEVEN,CSW_P90offset OFFSET_FIVESEVEN_AMMO;
        case 
CSW_DEAGLEoffset OFFSET_DEAGLE_AMMO;
        case 
CSW_P228offset OFFSET_P228_AMMO;
        case 
CSW_GLOCK18,CSW_MP5NAVY,CSW_TMP,CSW_ELITEoffset OFFSET_GLOCK_AMMO;
        case 
CSW_FLASHBANGoffset OFFSET_FLASH_AMMO;
        case 
CSW_HEGRENADEoffset OFFSET_HE_AMMO;
        case 
CSW_SMOKEGRENADEoffset OFFSET_SMOKE_AMMO;
        case 
CSW_C4offset OFFSET_C4_AMMO;
        default: return;
    }
    
    
set_pdata_int(idoffsetamountOFFSET_LINUX)
}

// Get User BP Ammo
stock fm_get_user_bpammo(idweapon)
{
    static 
offset
    
    
switch(weapon)
    {
        case 
CSW_AWPoffset OFFSET_AWM_AMMO;
        case 
CSW_SCOUT,CSW_AK47,CSW_G3SG1offset OFFSET_SCOUT_AMMO;
        case 
CSW_M249offset OFFSET_PARA_AMMO;
        case 
CSW_M4A1,CSW_FAMAS,CSW_AUG,CSW_SG550,CSW_GALI,CSW_SG552offset OFFSET_FAMAS_AMMO;
        case 
CSW_M3,CSW_XM1014offset OFFSET_M3_AMMO;
        case 
CSW_USP,CSW_UMP45,CSW_MAC10offset OFFSET_USP_AMMO;
        case 
CSW_FIVESEVEN,CSW_P90offset OFFSET_FIVESEVEN_AMMO;
        case 
CSW_DEAGLEoffset OFFSET_DEAGLE_AMMO;
        case 
CSW_P228offset OFFSET_P228_AMMO;
        case 
CSW_GLOCK18,CSW_MP5NAVY,CSW_TMP,CSW_ELITEoffset OFFSET_GLOCK_AMMO;
        case 
CSW_FLASHBANGoffset OFFSET_FLASH_AMMO;
        case 
CSW_HEGRENADEoffset OFFSET_HE_AMMO;
        case 
CSW_SMOKEGRENADEoffset OFFSET_SMOKE_AMMO;
        case 
CSW_C4offset OFFSET_C4_AMMO;
        default: return -
1;
    }
    
    return 
get_pdata_int(idoffsetOFFSET_LINUX);
}

// Give an item to a player (from fakemeta_util)
stock fm_give_item(id, const item[])
{
    static 
ent
    ent 
engfunc(EngFunc_CreateNamedEntityengfunc(EngFunc_AllocStringitem))
    if (!
pev_valid(ent)) return;
    
    static 
Float:originF[3]
    
pev(idpev_originoriginF)
    
set_pev(entpev_originoriginF)
    
set_pev(entpev_spawnflagspev(entpev_spawnflags) | SF_NORESPAWN)
    
dllfunc(DLLFunc_Spawnent)
    
    static 
save
    save 
pev(entpev_solid)
    
dllfunc(DLLFunc_Touchentid)
    if (
pev(entpev_solid) != save)
        return;
    
    
engfunc(EngFunc_RemoveEntityent)
}

// Strip user weapons (from fakemeta_util)
stock fm_strip_user_weapons(id)
{
    static 
ent
    ent 
engfunc(EngFunc_CreateNamedEntityengfunc(EngFunc_AllocString"player_weaponstrip"))
    if (!
pev_valid(ent)) return;
    
    
dllfunc(DLLFunc_Spawnent)
    
dllfunc(DLLFunc_Useentid)
    
engfunc(EngFunc_RemoveEntityent)
}


// Find entity by its owner (from fakemeta_util)
stock fm_find_ent_by_owner(entity, const classname[], owner)
{
    while ((
entity engfunc(EngFunc_FindEntityByStringentity"classname"classname)) && pev(entitypev_owner) != owner) {}
    
    return 
entity;
}

strip_weapons (id)
{
    if( !
get_pcvar_num(cvar_removeweapons) )
    {    
        
// Drop previous weapons
        
drop_weapons(id1)
        
drop_weapons(id2)
    }

    
// Strip off from weapons
    
fm_strip_user_weapons(id)
    
fm_give_item(id"weapon_knife")    
}

// Buy Primary Weapon
give_primary_weapon(idkey)
{    
    
// Get weapon index
    
static weaponid
    weaponid 
get_weaponid(g_primary_items[key])
    
    
// Give the new weapon
    
fm_give_item(idg_primary_items[key])
    
fm_set_user_bpammo(idweaponidMAXBPAMMO[key])
    
    
/*
    // Give additional items
    static i
    for (i = 0; i < sizeof g_additional_items; i++)
        fm_give_item(id, g_additional_items[i])
    */
}

give_secondary_weapon(idkey)
{    
    
// Get weapon index
    
static weaponid
    weaponid 
get_weaponid(g_secondary_items[key])
    
    
// Give the new weapon with full ammo
    
fm_give_item(idg_secondary_items[key])
    
fm_set_user_bpammo(idweaponidMAXBPAMMO[weaponid])

}
/*================================================================================
    End Code just for giving guns
================================================================================*/ 
Responder
#14
(13/10/2013, 07:20 PM)tiomaster escribió:
(13/10/2013, 07:16 PM)Neeeeeeeeeel.- escribió: Si no podés encontrar el error quizás lo más fácil sea mudar los menúes al sistema nuevo. Ya que estos tienen paginación automática.



Nadie puede echarle un vistazo ? e.e ?

Y como los mudo ? esque no tengo ni idea ? puedes acerme un ejemplo



te paso el sma por si tu puedes echar un vistazo -..- porfa Gran sonrisa



https://forums.alliedmods.net/showthread.php?t=46364



no nos des tanto code, nadie tiene porque hacertelo completito.
(17/04/2015, 03:36 PM)Neeeeeeeeeel.- escribió: No se va a volver a conectar a internet en toda su puta vida... nadie sube porno a mi foro y vive para contarlo.
Responder
#15
Ya lo se gracias Gran sonrisa[/align]

Mm interesante ayuda mm no me sirvio , pero ya esta . jeje aora solo necesito que me ayudeis a resolver mi problema es :

Error de compilacion 1 warning :

Welcome to the AMX Mod X 1.76-300 Compiler.

Copyright © 1997-2006 ITB CompuPhase, AMX Mod X Team



Warning: Loose indentation on line 1309

Header size: 3152 bytes

Code size: 38892 bytes

Data size: 316332 bytes

Stack/heap size: 16384 bytes; max. usage is unknown, due to recursion

Total requirements: 374760 bytes



1 Warning.

Done.

y el fallo

Código PHP:
// Show extra items menu again

        
show_menu_zclass(id)

        return 
PLUGIN_HANDLED;

    } 

    
// They selected their own class

    
if (ZCLASSES_SELECTION == g_zombieclassnext[id]) //aqui xd

    
{

        
//Plugin continues if this is false (sets class info on connect)

        
if( g_zclass_showmenu[id] == false//when a client first connects, the menu shows all zombies as a choice even the one the client defaults to (index of 0)

        
{

            
// Alert them they already have chosen a zombie

            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_ALREADYSELECTED")

            
show_menu_zclass(id)

            

            
// They had already chosen this zombie, dont rerun the command

            
return PLUGIN_HANDLED;

        }

    } 





Abajo esta registrado zp_Set_user_zombie_class

Código PHP:
zp_set_user_zombie_class(idg_zombieclassnext[id]) 


Crea una variable (g_zombieclassnext)

Código PHP:
new g_zombieclassnext[33
Creando TTT : 5%
Responder
#16
sube el when a client first...
(17/04/2015, 03:36 PM)Neeeeeeeeeel.- escribió: No se va a volver a conectar a internet en toda su puta vida... nadie sube porno a mi foro y vive para contarlo.
Responder
#17
haora :



Welcome to the AMX Mod X 1.76-300 Compiler.

Copyright © 1997-2006 ITB CompuPhase, AMX Mod X Team



Error: Undefined symbol "zp_colored_print" on line 388

Error: Undefined symbol "zp_colored_print" on line 392

Error: Undefined symbol "zp_colored_print" on line 398

Error: Undefined symbol "zp_colored_print" on line 404

Error: Undefined symbol "zp_colored_print" on line 486

Error: Undefined symbol "zp_colored_print" on line 519

Error: Undefined symbol "zp_colored_print" on line 540

Error: Undefined symbol "zp_colored_print" on line 546

Error: Undefined symbol "zp_colored_print" on line 552

Error: Undefined symbol "zp_colored_print" on line 558

Error: Undefined symbol "zp_colored_print" on line 580

Error: Undefined symbol "zp_colored_print" on line 585

Error: Undefined symbol "zp_colored_print" on line 592

Error: Undefined symbol "zp_colored_print" on line 599

Error: Undefined symbol "zp_colored_print" on line 606

Error: Undefined symbol "zp_colored_print" on line 613

Error: Undefined symbol "zp_colored_print" on line 632

Error: Undefined symbol "zp_colored_print" on line 639

Error: Undefined symbol "zp_colored_print" on line 646

Error: Undefined symbol "zp_colored_print" on line 652

Error: Undefined symbol "fm_get_user_team" on line 885

Error: Undefined symbol "strip_weapons" on line 913

Error: Undefined symbol "ShowHUD" on line 943

Error: Undefined symbol "strip_weapons" on line 975

Error: Undefined symbol "give_primary_weapon" on line 985

Error: Undefined symbol "give_secondary_weapon" on line 989



Compilation aborted.

26 Errors.

Could not locate output file C:\Documents and Settings\i\Escritorio\advanced bans\sv_zp xdp.amx (compile failed).
Creando TTT : 5%
Responder
#18
a ver, muestrame como lo dejaste.
(17/04/2015, 03:36 PM)Neeeeeeeeeel.- escribió: No se va a volver a conectar a internet en toda su puta vida... nadie sube porno a mi foro y vive para contarlo.
Responder
#19
te falto cerrar una llave mas que seguro.
Ingeniero agrónomo y desarrollador de Software.

tutoriales-allied
buscas un zp?

"La imitación es la forma más sincera de admiración con la que puede pagar la mediocridad a la grandeza"

Merci Alliedmodders pour m'introduire dans la programmation.
Responder
#20
(14/10/2013, 05:25 PM)roccoxx escribió: te falto cerrar una llave mas que seguro.
ten
Código PHP:
// Zombie Class Menu
public menu_zclass(idkey)
{
    
// Special keys / items list exceeded
    
if (key >= MENU_KEY_BACK || ZCLASSES_SELECTION >= g_zclass_i)
    {
        switch (
key)
        {
            case 
MENU_KEY_BACK// back
            
{
            if (
ZCLASSES_STARTID->= 0ZCLASSES_STARTID -= 
            
}
            case 
MENU_KEY_NEXT// next
            
{
                if (
ZCLASSES_STARTID+g_zclass_iZCLASSES_STARTID += 7
            
}
            case 
MENU_KEY_EXIT// exit
            
{
                return 
PLUGIN_HANDLED;
            }
        }
        
        
// Show extra items menu again
        
show_menu_zclass(id)
        return 
PLUGIN_HANDLED;
    } 
    
// They selected their own class
    
if (ZCLASSES_SELECTION == g_zombieclassnext[id])
    {
        
//Plugin continues if this is false (sets class info on connect)
        
if( g_zclass_showmenu[id] == false//when a client first connects, the menu shows all zombies as a choice even the one the client defaults to (index of 0)
        
{
            
// Alert them they already have chosen a zombie
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_ALREADYSELECTED")
            
show_menu_zclass(id)
            
            
// They had already chosen this zombie, dont rerun the command
            
return PLUGIN_HANDLED;
        }
    }
    
    if (
get_pcvar_num(cvar_removexp) == 0)
    {
        if (
g_zclass_lvl[HCLASSES_SELECTION] > userLevel[id])
        {
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_NOTLEVEL")
            
show_menu_zclass(id)
            return 
PLUGIN_HANDLED;
        }
    }
    
    
// Store selection for the next infection
    
g_zombieclassnext[id] = ZCLASSES_SELECTION;
    
    
// Disable showing menu since theyve chosen
    
g_zclass_showmenu[id] = false;
        
    
// Show selected zombie class info and stats
    
zp_colored_print(id"^x04%s^x01 %L: %s"textHeaderid"ZOMBIE_SELECT_XP"g_zclass_name[g_zombieclassnext[id]])
    
zp_colored_print(id"^x04%s^x01 %L: %d %L: %d %L: %d %L: %d%%"textHeaderid"ZOMBIE_ATTRIB1_XP"g_zclass_hp[g_zombieclassnext[id]], id"ZOMBIE_ATTRIB2_XP"g_zclass_spd[g_zombieclassnext[id]],
    
id"ZOMBIE_ATTRIB3_XP"floatround(g_zclass_grav[g_zombieclassnext[id]]*800), id"ZOMBIE_ATTRIB4_XP"floatround(g_zclass_kb[g_zombieclassnext[id]]*100))
    
    
// Set the class for zombie plague
    
zp_set_user_zombie_class(idg_zombieclassnext[id])
    
    return 
PLUGIN_HANDLED;


ya se que esta mal falta una llave pero cuando , pongo la llave bien , dale pawn y mira los fallso tu mismo

Código PHP:
#include <amxmodx>
#include <amxmisc>
#include <nvault>
#include <fakemeta>
#include <zombieplague>
#include <hamsandwich>
#include <fun>
#include <cstrike>

/*================================================================================
    Info
==================================================================================

Zombie XP Mode by redomin8
MeRcyLeZZ coded a huuuuge portion of the code, and I learned
from his genius and maybe made some changes (some was perfect)

Also, I'd very much like to thank G-Dog for all the help with creating
ZP Bank, I used his code to learn nvault. Good job guys!

Thanks to AssKicR and xeroblood for making ExplodeString.

Enjoy it, take it apart, make a better one. Have fun!

================================================================================
    Editable Section follows
================================================================================*/

// Uncomment to have an item added to zp's extra menu
#define TRIGGER_ZP_ITEM

// Uncomment to use say commands like "xp", "levels", "class", etc
#define TRIGGER_SAYMENU

// Uncomment if you have redomin8's [ZP] Bank - With Autosave installed (fixes spending spree bug)
//#define ZP_BANK_AUTOSAVE

// Uncomment to allow experimental menu alignment
//#define ZP_ALIGN_TEXT

//Uncomment to give levels to people
//#define ZP_GAMERUINER

//Uncomment to automatically bind a letter to show our menu
#define ZP_BINDMENU "j"

/*================================================================================
    End Editable Section
================================================================================*/

#if defined TRIGGER_ZP_ITEM
new g_TriggerItem
#endif
#if defined ZP_BANK_AUTOSAVE
//compatibility with zp_banks spending spree mode
native zp_bank_get_packs(id)
native zp_bank_set_packs(idvalue)
#endif

// Plugin info
static const PLUGIN_NAME[] = "ZP XP by redomin8"
static const PLUGIN_VERSION[] = ""

// Forwards for our zombie plugins
new g_fwRoundStartg_fwDummyResult

// nVault parameters
new gvault;
#define VAULT_LEVEL 0
#define VAULT_HCLASS 1
#define VAULT_ZCLASS 2

// Internal variables
enum pcvar
{
    
enable 0,
    
packslevelup //(current level) * packslevelup = price to level up
}
new 
pcvars[pcvar];
new 
userLevel[33], userNameID[33][32], userNeededPacks[33]
new 
g_modname[32// for formating the mod name
new g_maxplayers // max players counter


/*================================================================================
    Required Code from zombie_plague (modified to suite the plugin)
================================================================================*/

const MAX_CLASSSES 200

// Note: keep g_zclass_name and g_hclass_name the same array size!
// Zombie Classes vars
new g_zclass_name[MAX_CLASSSES][32// name
new g_zclass_info[MAX_CLASSSES][32// description
new g_zclass_model[MAX_CLASSSES][32// player model
new g_zclass_clawmodel[MAX_CLASSSES][32// claw model
new g_zclass_hp[MAX_CLASSSES// health
new g_zclass_spd[MAX_CLASSSES// speed
new g_zclass_lvl[MAX_CLASSSES// level
new Float:g_zclass_grav[MAX_CLASSSES// gravity
new Float:g_zclass_kb[MAX_CLASSSES// knockback
new g_zclass_load[MAX_CLASSSES][40// loading identifier
new g_zclass_i // loaded zombie classes counter

// Human Classes vars
new g_hclass_name[MAX_CLASSSES][32// name
new g_hclass_info[MAX_CLASSSES][32// description
new g_hclass_model[MAX_CLASSSES][32// player model
new g_hclass_weapons[MAX_CLASSSES][32// claw model
new g_hclass_hp[MAX_CLASSSES// health
new g_hclass_spd[MAX_CLASSSES// speed
new g_hclass_lvl[MAX_CLASSSES// level
new Float:g_hclass_grav[MAX_CLASSSES// gravity
new g_hclass_load[MAX_CLASSSES][40// loading identifier
new g_hclass_i // loaded zombie classes counter

// For menu handlers
#define ZCLASSES_STARTID g_menu_data[id][0]
#define ZCLASSES_SELECTION (g_menu_data[id][0]+key)
#define HCLASSES_STARTID g_menu_data[id][1]
#define HCLASSES_SELECTION (g_menu_data[id][1]+key)
new g_menu_data[33][8// data for various menus
const MENU_KEY_BACK 7
const MENU_KEY_NEXT 8
const MENU_KEY_EXIT 9
const KEYSMENU = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)

// Cvars
new cvar_welcomemsgcvar_removeweaponscvar_removexpcvar_removezombie;

// Vars
new g_zombieclassnext[33// zombie class for next infection
new g_humanclassnext[33// zombie class for next infection
new g_zombieclass[33// zombie class
new g_humanclass[33// zombie class
new g_resetparams[33// reset params?
new bool:g_hclass_showmenu[33]
new 
bool:g_zclass_showmenu[33]

const 
OFFSET_CSTEAMS 114
const OFFSET_LINUX // offsets 5 higher in Linux builds
enum
{
    
CS_TEAM_UNASSIGNED 0,
    
CS_TEAM_T,
    
CS_TEAM_CT,
    
CS_TEAM_SPECTATOR
}
new 
g_freezetime// whether it's freeze time
new bool:g_human[33]; // is zombie
new bool:loadedZombies //bugfix for cvar_removezombies being enabled after it was disabled first (and no zombies loaded)
/* --- FOR OUR HUD --- */
// Tasks for events
enum (+= 100)
{
    
TASK_SHOWHUD
}

// IDs inside tasks
#define ID_SHOWHUD (taskid - TASK_SHOWHUD)

// Message sync object
new g_MsgSync2 

// Message IDs vars
new g_msgSayText

// Constants
const PEV_SPEC_TARGET pev_iuser2
new const textHeader[] = "[ZPXP]"
new const textHeaderOrig[] = "[ZP]" //imitate Zombie Plague alerts

// HUD messages
const Float:HUD_EVENT_X = -1.0
const Float:HUD_EVENT_Y 0.17
const Float:HUD_INFECT_X 0.05
const Float:HUD_INFECT_Y 0.45
const Float:HUD_SPECT_X 0.6
const Float:HUD_SPECT_Y 0.85
const Float:HUD_STATS_X 1.005 //changed to right align
const Float:HUD_STATS_Y 0.9

/*================================================================================
    Constants JUST for giving guns
================================================================================*/

// CS Offsets
#if cellbits == 32
const OFFSET_CSTEAMS 114
const OFFSET_CSMONEY 115
const OFFSET_NVGOGGLES 129
const OFFSET_ZOOMTYPE 363
const OFFSET_CSDEATHS 444
const OFFSET_AWM_AMMO  377 
const OFFSET_SCOUT_AMMO 378
const OFFSET_PARA_AMMO 379
const OFFSET_FAMAS_AMMO 380
const OFFSET_M3_AMMO 381
const OFFSET_USP_AMMO 382
const OFFSET_FIVESEVEN_AMMO 383
const OFFSET_DEAGLE_AMMO 384
const OFFSET_P228_AMMO 385
const OFFSET_GLOCK_AMMO 386
const OFFSET_FLASH_AMMO 387
const OFFSET_HE_AMMO 388
const OFFSET_SMOKE_AMMO 389
const OFFSET_C4_AMMO 390
const OFFSET_CLIPAMMO 51
#else
const OFFSET_CSTEAMS 139
const OFFSET_CSMONEY 140
const OFFSET_NVGOGGLES 155
const OFFSET_ZOOMTYPE 402
const OFFSET_CSDEATHS 493
const OFFSET_AWM_AMMO  426
const OFFSET_SCOUT_AMMO 427
const OFFSET_PARA_AMMO 428
const OFFSET_FAMAS_AMMO 429
const OFFSET_M3_AMMO 430
const OFFSET_USP_AMMO 431
const OFFSET_FIVESEVEN_AMMO 432
const OFFSET_DEAGLE_AMMO 433
const OFFSET_P228_AMMO 434
const OFFSET_GLOCK_AMMO 435
const OFFSET_FLASH_AMMO 46
const OFFSET_HE_AMMO 437
const OFFSET_SMOKE_AMMO 438
const OFFSET_C4_AMMO 439
const OFFSET_CLIPAMMO 65
#endif

// Buy Menu: Primary and Secondary Weapons
new const g_primary_items[][] = { "weapon_galil""weapon_famas""weapon_m4a1""weapon_ak47""weapon_sg552""weapon_aug""weapon_scout",
                
"weapon_m3""weapon_xm1014""weapon_tmp""weapon_mac10""weapon_ump45""weapon_mp5navy""weapon_p90" }
new const 
g_secondary_items[][] = { "weapon_glock18""weapon_usp""weapon_p228""weapon_deagle""weapon_fiveseven""weapon_elite" }


// Max BP ammo for weapons
new const MAXBPAMMO[] = { -152, -19013232100901120100100909090100120,
            
301202003290120902359090, -1100 }

// Additional Items to give after buying all weapons (e.g. grenades)
new const g_additional_items[][] = { "weapon_hegrenade""weapon_flashbang""weapon_smokegrenade" }

// Weapon bitsums
const PRIMARY_WEAPONS_BIT_SUM = (1<<CSW_SCOUT)|(1<<CSW_XM1014)|(1<<CSW_MAC10)|(1<<CSW_AUG)|(1<<CSW_UMP45)|(1<<CSW_SG550)|(1<<CSW_GALIL)|(1<<CSW_FAMAS)|(1<<CSW_AWP)|(1<<CSW_MP5NAVY)|(1<<CSW_M249)|(1<<CSW_M3)|(1<<CSW_M4A1)|(1<<CSW_TMP)|(1<<CSW_G3SG1)|(1<<CSW_SG552)|(1<<CSW_AK47)|(1<<CSW_P90)
const 
SECONDARY_WEAPONS_BIT_SUM = (1<<CSW_P228)|(1<<CSW_ELITE)|(1<<CSW_FIVESEVEN)|(1<<CSW_USP)|(1<<CSW_GLOCK18)|(1<<CSW_DEAGLE)

const 
PEV_ADDITIONAL_AMMO pev_iuser1

/*================================================================================
    The code starts here
================================================================================*/

public plugin_precache()
{
    
// Register all our cvars
    
cvar_welcomemsg register_cvar("zp_xp_welcomemsg""1");
    
cvar_removeweapons register_cvar("zp_xp_removeweapons""0");
    
cvar_removexp register_cvar("zp_xp_removexp""0");
    
cvar_removezombie register_cvar("zp_xp_removezombie""0");
}

public 
plugin_init()
{

          
    
// Register the plugin
    
register_plugin(PLUGIN_NAMEPLUGIN_VERSION"Huh?")
    
    
// Language files
    
register_dictionary("zombie_xp.txt")

    
// Register the menus
    
register_menu("Game Menu"KEYSMENU"menu_game")
    
register_menu("Zombie Class Menu"KEYSMENU"menu_zclass")
    
register_menu("Human Class Menu"KEYSMENU"menu_hclass")
    
    
// For setting human's skills
    
register_forward(FM_PlayerPreThink"fw_PlayerPreThink")
    
    
// For setting the user human on connecting
    
RegisterHam(Ham_Spawn"player""fw_PlayerSpawn_Post"1)
    
    
// For setting humans speed also
    
register_logevent("logevent_round_start",2"1=Round_Start")
    
    
// Register event round start for humans
    
register_event("HLTV""event_round_start""a""1=0""2=0");
    
    
// Register forward for our plugins
    
g_fwRoundStart CreateMultiForward("zp_round_started_human"ET_IGNOREFP_CELL)
        
    
// Set our vars to disable zombie plague functions
    
set_task(1.0"set_cvars")
    
    
// Register variables
    
pcvars[enable] = register_cvar("zp_xp_enable""1")
    
pcvars[packslevelup] = 15 
    
    
// Register client commands
    
register_clcmd("zp_xp_costscale""SetPacksLevelUp")
    
register_clcmd("zp_xp_set_level""SetLevel")
    
register_clcmd("zp_xp_removexp""RemoveXP")
    
register_clcmd("zp_xp_removezombies""RemoveZombies")
    
register_clcmd("zp_xp_removeweapons""RemoveWeapons")
    
    
//trigger for handling the menu
    #if defined TRIGGER_ZP_ITEM
    
    #endif
    #if defined TRIGGER_SAYMENU
    
register_clcmd("say xp""handle_say_xp")
    
register_clcmd("say level""handle_say_level")
    
register_clcmd("say nivel""handle_say_level")
    
register_clcmd("say xpmenu""handle_say_xpmenu")
    
#endif
        
    //Settings variables
    
g_msgSayText get_user_msgid("SayText")
    
    
// Format mod name
    
formatex(g_modnamesizeof g_modname 1"Zombie XP %s"PLUGIN_VERSION)
    
    
// Get Max Players
    
g_maxplayers get_maxplayers()
    
    
//nVault
    
gvault nvault_open(PLUGIN_NAME);
    
    
//for our HUD (shows level on screen)
    
g_MsgSync2 CreateHudSyncObj()
}

public 
set_cvars()
{
    
// Disable zombie_plague's zombie auto menu
    
if( get_pcvar_num(cvar_removezombie) == 0set_cvar_num("zp_zombie_classes"0);
    if( 
get_pcvar_num(cvar_removeweapons) == 0set_cvar_num("zp_buy_custom"0);
}

public 
plugin_natives()
{
    
//natives
    
register_native("zpxp_register_extra_item""native_register_extra_item"1)
    
register_native("zpxp_register_human_class""native_register_human_class"1)
    
register_native("zpxp_register_zombie_class""native_register_zombie_class"1)
    
register_native("zp_get_user_human_class""native_get_user_human_class"1)
}

public 
plugin_end()
{
    if( 
get_pcvar_num(cvar_removexp) == 0)
    {
        
// Save everyone's data first
        
server_print("%s Saving your clients XP."textHeader);
    
        for( new 
133o++)
        {
            
//if ( !is_user_connected(o) || is_user_bot(o) ) continue;
            
if ( !is_user_connected(o) ) continue;
            if ( 
is_user_bot(o) ) continue;
            
            
save_data(o);
        }
    }

    
nvault_close(gvault)
    
    
//Bugfix:
    
if( (loadedZombies == false) && ( get_pcvar_num(cvar_removezombie) == )) 
    {
        
set_pcvar_num(cvar_removezombie0);
        
set_cvar_num("zp_zombie_classes"0)    
    }
}

#if defined TRIGGER_SAYMENU
public handle_say_xp(id)
{
    
    
#if defined ZP_BINDMENU
    
new strLetter[2];
    
copy(strLettersizeof strLetter 1ZP_BINDMENU);
    
strtoupper(strLetter);
    
strtoupper(ZP_BINDMENU);
    
    
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"SAY_INFO_KEY"strLetter)
    
#else
    
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"SAY_INFO")    
    
#endif
    
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"SAY_XP"pcvars[packslevelup] * userLevel[id], userLevel[id])
    return 
PLUGIN_HANDLED
}
public 
handle_say_level(id)
{
    
//return level
    
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"SAY_LEVEL"userLevel[id])    
    return 
PLUGIN_HANDLED
}
public 
handle_say_class(id)
{
    
//return class
    
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"SAY_CLASS"g_hclass_name[g_humanclass[id]], g_zclass_name[g_zombieclass[id]])
    return 
PLUGIN_HANDLED
}
public 
handle_say_xpmenu(id)
{
    
show_menu_game(id);
    return 
PLUGIN_HANDLED
}
#endif

#if defined TRIGGER_ZP_ITEM
public zp_extra_item_selected(playeritemid)
{
    if(
itemid == g_TriggerItem)
    {
        
//show the menu
        
show_menu_game(player);
    }
}
#endif

#if defined ZP_BANK_AUTOSAVE
public getAmmoPacks(id)
{
    return 
zp_bank_get_packs(id);
}
public 
setAmmoPacks(idvalue)
{
    return 
zp_bank_set_packs(idvalue);
}
#else
public getAmmoPacks(id)
{
    return 
zp_get_user_ammo_packs(id);
}
public 
setAmmoPacks(idvalue)
{
    return 
zp_set_user_ammo_packs(idvalue);
}
#endif


public SetLevel(id)
{    
    
//Multilang is not enabled here since I plan to remove this funtionality once this leaves BETA
    #if defined ZP_GAMERUINER
    
if ( read_argc() > ) return PLUGIN_HANDLED;
        
    new 
arg1[32], arg2[10], amount;
    
read_argv(1arg1sizeof(arg1) - 1);
    
read_argv(2arg2sizeof(arg2) - 1);
    
    
amount str_to_num(arg2);
    if( 
amount <= 0amount 1;
    new 
target cmd_target(0arg12);

    if ( 
target == )
    {
        
//couldnt find them
        
zp_colored_print(id"^x04%s^x01 Could not find the requested user."textHeader);
        
        return 
PLUGIN_HANDLED;

    } else { 

        
//we found them!
        
userLevel[id] = amount
        ShowHUD
(id)
        
        if(
id == target)
        {
            
zp_colored_print(id"^x04%s^x01 You have set yourself to level %d!"textHeaderamount );
        } else {
            new 
targetName[64];
            
get_user_name(targettargetName63);

            
zp_colored_print(id"^x04%s^x01 You have set %s to level %d!"textHeader targetNameamount );
            
zp_colored_print(target"^x04%s^x01 You have been set to level %d!"textHeader amount );
        }
        return 
PLUGIN_HANDLED;
    }
    
#else
    
zp_colored_print(id"^x04%s^x01 This functionality has been disabled."textHeader);
    
client_print(idprint_console"^x04%s^x01 This functionality has been disabled."textHeader);
    
#endif
    
return PLUGIN_HANDLED;
    


public 
getNeededPacks(id)
{
    
//return the packs needed for leveling up
    
return pcvars[packslevelup] * userLevel[id]
}

public 
SetPacksLevelUp(idvalue)
{
    
//this allows the user to change the multiplier for ammo cost
    
new arg[10], arg2
    read_argv
(1argsizeof arg 1)
    
    
arg2 str_to_num(arg)
    if(
arg2 0)
    {
        
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM")
        
pcvars[packslevelup] = arg2;
        
        
//go through each player and change the amount required to level up
        
for( new 133o++)
        {
            if ( !
is_user_connected(o) ) continue;
            
userNeededPacks[id] = getNeededPacks(id)
        }
    } else {
        
//must be a positive number - PRINTS TO CONSOLE, LEAVE ALONE!
        
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_NEGATIVE");
        
client_print(idprint_console"%s %L"textHeaderid"ERR_NEGATIVE")
    }
    
    return 
PLUGIN_HANDLED;
}


//-----------------------CVAR Handlers--------------------------

public RemoveXP(id)
{
    
//this allows the user to enable or disable XP
    
new arg[10], arg2
    read_argv
(1argsizeof arg 1)
    
    
arg2 str_to_num(arg)
    if(
arg2 >= 0)
    {
        if(
arg2 == 1) {
            
// Disable the XP
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ADMIN_CONFIRM");
            
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM")
            
set_pcvar_num(cvar_removexparg2);
            
        } else if (
arg2 == 0) {
            
// Enable the XP
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ADMIN_CONFIRM");
            
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM")
            
set_pcvar_num(cvar_removexparg2);
            
        } else {
            
// They typed something wrong
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_INVALIDENTRY");
            
client_print(idprint_console"%s %L"textHeaderid"ERR_INVALIDENTRY");
            return 
PLUGIN_HANDLED;
        }
    } else {
        
//must be a positive number - PRINTS TO CONSOLE, LEAVE ALONE!
        
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_NEGATIVE");
        
client_print(idprint_console"%s %L"textHeaderid"ERR_NEGATIVE")
    }
    
    return 
PLUGIN_HANDLED;
    
}

public 
RemoveZombies(id)
{
    
//this allows the user to enable or disable zombie classes
    
new arg[10], arg2
    read_argv
(1argsizeof arg 1)
    
    
arg2 str_to_num(arg)
    if(
arg2 >= 0)
    {
        if (
arg2 == 0) {
            
// Enable the zombie classes
            
            
if( loadedZombies == true )
            {
                
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ADMIN_CONFIRM");
                
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM")
                
set_pcvar_num(cvar_removezombie0);
                
set_cvar_num("zp_zombie_classes"0)
            } else {
                
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ADMIN_CONFIRM_NEXTROUND");
                
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM_NEXTROUND")
                
//set_pcvar_num(cvar_removezombie, 0);
                //set_cvar_num("zp_zombie_classes", 0)            
            
}
        } else if (
arg2 == 1) {
            
// Disable the zombie classes
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ADMIN_CONFIRM");
            
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM")
            
set_pcvar_num(cvar_removezombie1);
            
set_cvar_num("zp_zombie_classes"1)
            
        } else if (
arg2 == 2) {
            
// Disable, and dont add zombies to zombie plague
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ADMIN_CONFIRM_NEXTROUND");
            
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM_NEXTROUND")
            
set_pcvar_num(cvar_removezombie1);
            
set_cvar_num("zp_zombie_classes"2)
            
        } else {
            
// They typed something wrong
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_INVALIDENTRY");
            
client_print(idprint_console"%s %L"textHeaderid"ERR_INVALIDENTRY");
            return 
PLUGIN_HANDLED;
            
        }
    } else {
        
//must be a positive number - PRINTS TO CONSOLE, LEAVE ALONE!
        
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_NEGATIVE");
        
client_print(idprint_console"%s %L"textHeaderid"ERR_NEGATIVE")
    }
    
    return 
PLUGIN_HANDLED;
    
}

public 
RemoveWeapons(id)
{
    
//this allows the user to enable or disable zombie classes
    
new arg[10], arg2
    read_argv
(1argsizeof arg 1)
    
    
arg2 str_to_num(arg)
    if(
arg2 >= 0)
    {
        if(
arg2 == 1) {
            
// Disable the custom human weapons
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ADMIN_CONFIRM");
            
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM")
            
set_pcvar_num(cvar_removeweapons1);
            
set_cvar_num("zp_buy_custom"1);
            
        } else if (
arg2 == 0) {
            
// Enable the custom human weapons
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ADMIN_CONFIRM");
            
client_print(idprint_console"%s %L"textHeaderid"ADMIN_CONFIRM")
            
set_pcvar_num(cvar_removeweapons0);
            
set_cvar_num("zp_buy_custom"0);
            
        } else {
            
// They typed something wrong
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_INVALIDENTRY");
            
client_print(idprint_console"%s %L"textHeaderid"ERR_INVALIDENTRY");
            return 
PLUGIN_HANDLED;
        }
    } else {
        
//must be a positive number - PRINTS TO CONSOLE, LEAVE ALONE!
        
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_NEGATIVE");
        
client_print(idprint_console"%s %L"textHeaderid"ERR_NEGATIVE")
    }
    
    return 
PLUGIN_HANDLED;
    
}

public 
show_menu_game(id)
{
    
// Show our menu
    
static menu[250], lenindex;
    
len 0
    index 
1;
    
    
// Title
    
len += formatex(menu[len], sizeof menu len"\y%s^n^n"g_modname)
    
    if( 
get_pcvar_num(cvar_removexp) == )
    {
        
// 1. Buy a level up
        
if(getAmmoPacks(id) >= getNeededPacks(id))
        {
            
len += formatex(menu[len], sizeof menu len"\r%d.\w %L"indexid"MENU_BUY_XP")
            
len += formatex(menu[len], sizeof menu len" \y%d %L^n"getNeededPacks(id), id"AMMO_PACKS_XP")
        } else {
            
len += formatex(menu[len], sizeof menu len"\d%d. %L"indexid"MENU_BUY_XP")
            
len += formatex(menu[len], sizeof menu len" \d%d %L^n"getNeededPacks(id), id"AMMO_PACKS_XP")
        }

        
index++;
    }

    
//Human class
    
len += formatex(menu[len], sizeof menu len"\r%d.\w %L^n"indexid,"MENU_HCLASS")
    
    if (
get_pcvar_num(cvar_removezombie) == 0)
    {
        
//Zombie class
        
index++;
        
len += formatex(menu[len], sizeof menu len"\r%d.\w %L^n"indexid,"MENU_ZCLASS")
    }

    
// 0. Exit
    
len += formatex(menu[len], sizeof menu len"^n^n\r0.\w %L"id"MENU_EXIT")
    
    
show_menu(idKEYSMENUmenu, -1"Game Menu")
}

public 
save_data(id)
{
    new 
vaultkey[40],vaultData[256];
        
    new 
g_selected_zclass[sizeof g_zclass_load[]] , g_selected_hclass[sizeof g_hclass_load[]] //bug fix for not showing menu if the user hasnt picked a zombie
    
if( g_hclass_showmenu[id] == true) { g_selected_hclass "-1"; } else { formatex(g_selected_hclasssizeof g_selected_hclass 1g_hclass_load[g_humanclassnext[id]]); }
    if( 
g_zclass_showmenu[id] == true) { g_selected_zclass "-1"; } else { formatex(g_selected_zclasssizeof g_selected_zclass -1g_zclass_load[g_zombieclassnext[id]]); }
    
    
formatexvaultkeysizeof vaultkey 1"%s_stats"userNameID[id]);
    
formatexvaultDatasizeof vaultData 1"0=%i;1=%s;2=%s;"userLevel[id], g_selected_hclassg_selected_zclass);
    
    
nvault_set(gvaultvaultkeyvaultData);
}

public 
load_data(id)
{
    if( 
get_pcvar_num(cvar_removexp) != 0)
    {
        
// Do not load or save data
        
g_hclass_showmenu[id] = true;
        
g_zclass_showmenu[id] = true;
        return;
    }
    
    new 
vaultkey[40], vaultReturn[256];
    new 
vaultData[4][40], vaultResults[3][40];
    
    
// Get the Level
    
format(vaultkeysizeof vaultkey 1"%s_stats"userNameID[id]);
    
nvault_get(gvaultvaultkeyvaultReturnsizeof vaultReturn 1); 
    
    new 
Count ExplodeString(vaultDatasizeof vaultData 1sizeof vaultData[] - 1vaultReturn';')
        
    if(
Count == sizeof vaultResults 1)
    {
        new 
ivaultLeveli_hclass_id = -1i_zclass_id = -1;
        
        for( new 
0sizeof vaultData 1i++)
        {
            
ExplodeString(vaultResultssizeof vaultResults 1sizeof vaultResults[] - 1vaultData[i], '=');
            
            
// We now have our items
            
switch (str_to_num(vaultResults[0]))
            {
                case 
VAULT_LEVEL:
                {    
                    
ivaultLevel str_to_num(vaultResults[1]);
                    
                    if (
ivaultLevel == 0ivaultLevel 1;
                    
userLevel[id] = ivaultLevel
                
}
                
                case 
VAULT_HCLASS:
                {
                    
// Look for our human class
                    
if( !equali(vaultResults[1], "-1") )
                    {
                        for (new 
i2 0i2 g_hclass_ii2++)
                        {
                            if( 
equali(vaultResults[1], g_hclass_load[i2]) )
                            {
                                
i_hclass_id i2;
                                break;
                            }
                        }
                    }
                
                    if ( 
i_hclass_id == -1)
                    {
                        
// Couldnt find them
                        
g_hclass_showmenu[id] = true;
                    } else {
                        
// We found their zombie class
                        
g_humanclassnext[id] = i_hclass_id;
                        
g_hclass_showmenu[id] = false;
                    }
                }
                
                case 
VAULT_ZCLASS:
                {
                    if( !
equali(vaultResults[1], "-1") )
                    {
                        for (new 
i2 0i2 g_zclass_ii2++)
                        {
                            if( 
equali(vaultResults[1], g_zclass_load[i2]) )
                            {
                                
i_zclass_id i2;
                                break;
                            }
                        }
                    }
                    
                    if ( 
i_zclass_id == -1)
                    {
                        
g_zclass_showmenu[id] = true;
                    } else {
                        
g_zombieclassnext[id] = i_zclass_id;
                        
g_zclass_showmenu[id] = false;
                        
zp_set_user_zombie_class(idi_zclass_id);
                    }
                }
            }
        }
    } else {
        
g_hclass_showmenu[id] = true;
        
g_zclass_showmenu[id] = true;

    }    
}

public 
client_connect(id)
{
    
// Do we bind a key
    #if defined ZP_BINDMENU
    
client_cmd(id,"bind j ^"say xpmenu^""ZP_BINDMENU);
    
#endif
}
public 
client_putinserver(id)
{
    
// Reset vars
    
resetvars(id)
        
    
// Make sure zombieplague doesnt load the last plugin as the default zombie
    
zp_set_user_zombie_class(id0)
    
    
// Load their data
    
load_data(id);
    
    
// Set amount of levels to level up (called after load_data)
    
userNeededPacks[id] = getNeededPacks(id)
    
    
// Set the custom HUD display task
    
set_task(1.0"ShowHUD"id+TASK_SHOWHUD__"b")
}

public 
client_disconnect(id)
{
    
// Save the data
    
save_data(id);
    
    
// Remove tasks
    
remove_task(id+TASK_SHOWHUD)
}

public 
fw_PlayerSpawn_Post(id)
{
    
// Both humans and zombies spawn and call this
    // Zombies can respawn if deathmatch is enabled
    
    //TODO: Check if this works
    
if (zp_get_user_zombie(id)) 
        return 
FMRES_IGNORED;
    
    if (!
is_user_alive(id)) // you could also use is_user_connected()
        
return FMRES_IGNORED;
        
    
// Set selected human and zombie class
    
g_humanclass[id] = g_humanclassnext[id]
    
g_zombieclass[id] = g_zombieclassnext[id]
    
    
// Change the default human variables
    
humanme(id)
            
    
// We know for sure they are a human, only give guns+speed+grav if they've picked a class
    
if (( g_hclass_showmenu[id] == false ) && (get_pcvar_num(cvar_removeweapons) == 0))
    {    
        
setHumanParameters(id)
        
giveWeapons(id//give weapons
    
}

    return 
FMRES_IGNORED;
}

public 
event_round_start()
{
    static 
team;
    
    
// Set our humans hp, speed, etc
    
for( new 133o++)
    {
        
// Not connected
        
if ( !is_user_connected(o) ) continue;
        
        
// Not playing
        
team fm_get_user_team(o)
        if (
team == CS_TEAM_SPECTATOR || team == CS_TEAM_UNASSIGNED) continue;
        
        
// Set our human vars
        //humanme(o)
        
        // Our next vars are now current
        //g_humanclass[o] = g_humanclassnext[o]
        //g_zombieclass[o] = g_zombieclassnext[o]
        
        // The round has started
        
ExecuteForward(g_fwRoundStartg_fwDummyResulto);
    }
    
    
// Set our vars
    
g_freezetime true
    
    
// Do we show a welcome message?
    
if( get_pcvar_num(cvar_welcomemsg) )
        
set_task(2.0"welcome_msg")
}

public 
zp_user_infected_pre(idinfector)
{
    
// Make sure he is not a human
    
g_human[id] = false
    
    
// Strip his guns (so they dont fall on the floor)
    
strip_weapons(id);
}

public 
zp_user_infected_post(idinfector)
{
    
// Do we show the menu?
    
if ((g_zclass_showmenu[id] == true) && get_pcvar_num(cvar_removezombie) ==0show_menu_zclass(id);

}
            
public 
zp_user_humanized_pre(id)
{    
    
// Set selected human class, incase he buys antidote
    
g_humanclass[id] = g_humanclassnext[id];
    
g_zombieclass[id] = g_zombieclassnext[id];
}

public 
zp_user_humanized_post(id)
{    
    
// Hes become human again, set our vars
    
if( !zp_get_user_survivor(id) )
    {
        
humanme(id)        
        
setHumanParameters(id)
        if( 
get_pcvar_num(cvar_removeweapons) == 0giveWeapons(id//give weapons
    
} else {
        
// He has become a survivor
        
g_human[id] = false
    
}
    
    
ShowHUD(id)
}




enum
{
    
WEAPON_GALIL 0,
    
WEAPON_FAMAS,
    
WEAPON_M4A1,
}

public 
humanme(id)
{
    
// Set our human's height, jump, etc
    
    
if( g_hclass_showmenu[id] == true)
    {
        
// They just entered, and no data was loaded for them
        // Show the menu (despite the fact that they are automatically lvl. 1)
        
if (get_pcvar_num(cvar_removezombie) == 0)
        { 
set_task(0.1"show_menu_hclass"id); } else { set_task(0.5"show_menu_hclass"id); }
    }
    
    
// They are human
    
g_human[id] = true;
}

public 
giveWeapons(id)
{
    
// Strip weapons first
    
strip_weapons(id);
    
    
// Give all weapons (everything is in g_hclass_weapons)
    
static iweaponid;
    for (
0sizeof g_hclass_weaponsi++)
    {
        
weaponid g_hclass_weapons[g_humanclass[id]][i];
        
        if (
weaponid >= && weaponid <= 14) {
            
// Give main weapon
            
give_primary_weapon(idweaponid 1);
    
        } else if ( 
weaponid >= 15 && weaponid <= 20)  {
            
// Give secondary gun
            
give_secondary_weapon(idweaponid 15);
            
        } else if ( 
weaponid >= 21 && weaponid <=23) {
            
// Give grenades
            
fm_give_item(idg_additional_items[weaponid 21]);
            
        } else {
            
// We have given them all their item, or they dont have any
            
return;
        }
    }    
}

public 
setHumanParameters(id)
{
    
set_pev(idpev_gravityg_hclass_grav[g_humanclass[id]])
    
fm_set_user_health(idg_hclass_hp[g_humanclass[id]])
}

public 
resetvars(id)
{
    
// This should only be called whenever a person connects!
    // Otherwise it erases a persons choices
    // Reset our human's variables
    
g_zombieclassnext[id] = 0
    
g_humanclassnext[id] = 0;
    
g_zombieclass[id] = 0;
    
g_humanclass[id] = 0;
    
    
g_hclass_showmenu[id] = false;
    
g_zclass_showmenu[id] = false;
    
    
userLevel[id] = 1;
    
    
get_user_name(iduserNameID[id], 31)
    
g_resetparams[id] = false
}

/*================================================================================
Begin Functions from the internet
================================================================================*/

//http://forums.alliedmods.net/showthread.php?p=67207#post67207
stock ExplodeStringOutput[][], MaxSizeInput[], Delimiter )
{
    new 
Idxstrlen(Input), Len;
    do 
Len += (copycOutput[Idx], SizeInput[Len], Delimiter ));
    while( (
Len l) && (++Idx Max) )
    return 
Idx;
}


/*================================================================================
Begin Code from zombie_plague (modified to suit the plugin)
================================================================================*/

// Set player's health (from fakemeta_util)
stock fm_set_user_health(idhealth)
{
    (
health 0) ? set_pev(idpev_healthfloat(health)) : dllfunc(DLLFunc_ClientKillid);
}


// Forward Player PreThink
public fw_PlayerPreThink(id)
{
    
// Not alive
    
if (!is_user_alive(id)) return;
    
    
// Not human, survivor will count as not a human
    
if(!g_human[id]) return;
    
    
// Set Player MaxSpeed
    
if (!g_freezetime)
    {
        if (
g_human[id])
        {
            
set_pev(idpev_maxspeedfloat(g_hclass_spd[g_humanclass[id]]))
            return
        }
    }
}

public 
show_menu_zclass(id)
{    
    
// Player disconnected
    
if (!is_user_connected(id))
        return;
    
    
// Bots pick default classes
    
if (is_user_bot(id))
    {
        
g_zombieclassnext[id] = //basic zombie
        
return;
    }
    
    static 
menu[800], len, class, removexp;
    new 
curClassIcon[2];
    
    
len 0
    removexp 
get_pcvar_num(cvar_removexp);
    
    
// Title
    
len += formatex(menu[len], sizeof menu len"\y%L \r [%d-%d]^n^n"id"MENU_ZCLASS_TITLE"ZCLASSES_STARTID+1min(ZCLASSES_STARTID+9g_zclass_i))
    
    
#if defined ZP_ALIGN_TEXT
    // Align text
    
new spacers[400], g_zclass_spacers1g_zclass_spacers2
    
new maxSpace1maxSpace2curSpace1[32], curSpace2[32]

    
// Get max width first
    
for (class = ZCLASSES_STARTID; class < min(ZCLASSES_STARTID+9g_zclass_i); class++)
    {
        
formatex(spacerssizeof spacers 1"%d. %s", class-ZCLASSES_STARTID+1g_zclass_name[class])
        
        
g_zclass_spacers1 strlen(spacers)
        
g_zclass_spacers2 strlen(g_zclass_info[class])
        
        if(
g_zclass_spacers1 maxSpace1maxSpace1 g_zclass_spacers1
        
if(g_zclass_spacers2 maxSpace2maxSpace2 g_zclass_spacers2
    
}
        
    
// 1-7. Class List
    
for (class = ZCLASSES_STARTID; class < min(ZCLASSES_STARTID+9g_zclass_i); class++)
    {
    
    if (
g_zclass_lvl[id] >= g_zclass_lvl[class])
        {
            if (class == 
g_zombieclassnext[id])
                
len += formatex(menu[len], sizeof menu len"\d%d. %s %s^n", class-ZCLASSES_STARTID+1g_zclass_name[class], g_zclass_info[class])
            else
                
len += formatex(menu[len], sizeof menu len"\r%d.\w %s\y %s^n", class-ZCLASSES_STARTID+1g_zclass_name[class], g_zclass_info[class])
        }
        else
            
len += formatex(menu[len], sizeof menu len"\r%d.\d %s %s\r (Nivel Requerido: %d)^n", class-ZCLASSES_STARTID+1g_zclass_name[class], g_zclass_info[class], g_zclass_lvl[class])
    }
    
#else
    
for (class = ZCLASSES_STARTID; class < min(ZCLASSES_STARTID+9g_zclass_i); class++)
    {
        if (((class == 
g_zombieclassnext[id] && g_zclass_showmenu[id] == false) || (userLevel[id] < g_zclass_lvl[class])) && (removexp == 0))
        {    
            if (class == 
g_zombieclassnext[id]) { curClassIcon "*"; } else { curClassIcon ""; }
            
            
len += formatex(menu[len], sizeof menu len"\d%s%d. %s - %s - %L %d^n"curClassIcon, class-ZCLASSES_STARTID+1g_zclass_name[class], g_zclass_info[class], id"BOTH_ATTRIB_LEVEL"g_zclass_lvl[class])
        } else if (
removexp == 1) {
            
len += formatex(menu[len], sizeof menu len"\r%d.\w %s -\y %s^n", class-ZCLASSES_STARTID+1g_zclass_name[class], g_zclass_info[class]);
        } else {
            
len += formatex(menu[len], sizeof menu len"\r%d.\w %s -\y %s\w - %L %d^n", class-ZCLASSES_STARTID+1g_zclass_name[class], g_zclass_info[class], id"BOTH_ATTRIB_LEVEL"g_zclass_lvl[class]);
        }
    }
    
#endif
    
    // 8. Back - 9. Next - 0. Exit
    
len += formatex(menu[len], sizeof menu len"^n\r8.\w %L^n\r9.\w %L^n^n\r0.\w %L"id"MENU_BACK"id"MENU_NEXT"id"MENU_EXIT")
    
    
show_menu(idKEYSMENUmenu, -1"Zombie Class Menu")
}


public 
show_menu_hclass(id)
{
    
// Player disconnected
    
if (!is_user_connected(id))
        return;
    
    
// Bots pick default classes
    
if (is_user_bot(id))
    {
        
g_humanclassnext[id] = 0
        
return;
    }
    
    static 
menu[800], len, class, removexp
    
new curClassIcon[2]
    
len 0
    removexp 
get_pcvar_num(cvar_removexp);
    
    
// Title
    
len += formatex(menu[len], sizeof menu len"\y%L \r[%d-%d]^n^n"id"MENU_HCLASS_TITLE"HCLASSES_STARTID+1min(HCLASSES_STARTID+7g_hclass_i))
    
    
#if defined ZP_ALIGN_TEXT
    // Align text
    
new spacers[400], g_hclass_spacers1g_hclass_spacers2
    
new maxSpace1maxSpace2curSpace1[32], curSpace2[32]

    
// Get max width first
    
for (class = HCLASSES_STARTID; class < min(HCLASSES_STARTID+7g_hclass_i); class++)
    {
        
formatex(spacerssizeof spacers 1"%d. %s", class-HCLASSES_STARTID+1g_hclass_name[class])
        
        
g_hclass_spacers1 strlen(spacers)
        
g_hclass_spacers2 strlen(g_hclass_info[class])
        
        if(
g_hclass_spacers1 maxSpace1maxSpace1 g_hclass_spacers1
        
if(g_hclass_spacers2 maxSpace2maxSpace2 g_hclass_spacers2
    
}
        
    
// 1-7. Class List
    
for (class = HCLASSES_STARTID; class < min(HCLASSES_STARTID+7g_hclass_i); class++)
    {
        
formatex(spacerssizeof spacers 1"%d. %s", class-HCLASSES_STARTID+1g_hclass_name[class])
        
        
g_hclass_spacers1 maxSpace1 strlen(spacers)
        
g_hclass_spacers2 maxSpace2 strlen(g_hclass_info[class])
            
        
arrayset(curSpace1'^0'sizeof curSpace1 1)
        
arrayset(curSpace2'^0'sizeof curSpace2 1)
        
        if(
g_hclass_spacers1 != 0arrayset(curSpace1'^t'g_hclass_spacers1)
        if(
g_hclass_spacers2 != 0arrayset(curSpace2'^t'g_hclass_spacers2)
        
        if (((class == 
g_humanclassnext[id] && g_hclass_showmenu[id] == false) || (userLevel[id] < g_hclass_lvl[class])) && (removexp == 0))
        {    
            if (class == 
g_humanclassnext[id]) { curClassIcon "*"; } else { curClassIcon ""; }
            
            
len += formatex(menu[len], sizeof menu len"\d%s%d. %s %s %s %s %L %d^n"curClassIcon, class-HCLASSES_STARTID+1g_hclass_name[class], curSpace1g_hclass_info[class], curSpace2id"BOTH_ATTRIB_LEVEL"g_hclass_lvl[class])
        } else if (
removexp == 1) {
            
len += formatex(menu[len], sizeof menu len"\r%d.\w %s\y %s %s^n", class-HCLASSES_STARTID+1g_hclass_name[class], curSpace1g_hclass_info[class])
        } else {
            
len += formatex(menu[len], sizeof menu len"\r%d.\w %s\y %s %s\w %s %L %d^n", class-HCLASSES_STARTID+1g_hclass_name[class], curSpace1g_hclass_info[class], curSpace2id"BOTH_ATTRIB_LEVEL"g_hclass_lvl[class])
        }
    }
    
    
#else
    
for (class = HCLASSES_STARTID; class < min(HCLASSES_STARTID+7g_hclass_i); class++)
    {
        if (((class == 
g_humanclassnext[id] && g_hclass_showmenu[id] == false) || (userLevel[id] < g_hclass_lvl[class])) && (removexp == 0))
        {
            if (class == 
g_humanclassnext[id]) { curClassIcon "*"; } else { curClassIcon ""; }
            
            
len += formatex(menu[len], sizeof menu len"\d%s%d. %s - %s - %L %d^n"curClassIcon, class-HCLASSES_STARTID+1g_hclass_name[class], g_hclass_info[class], id"BOTH_ATTRIB_LEVEL"g_hclass_lvl[class])
        } else if (
removexp == 1) {
            
len += formatex(menu[len], sizeof menu len"\r%d.\w %s -\y %s^n", class-HCLASSES_STARTID+1g_hclass_name[class], g_hclass_info[class]);
        } else {
            
len += formatex(menu[len], sizeof menu len"\r%d.\w %s -\y %s\w - %L %d^n", class-HCLASSES_STARTID+1g_hclass_name[class], g_hclass_info[class], id"BOTH_ATTRIB_LEVEL"g_hclass_lvl[class])
        }
    }
    
#endif
    
    // 8. Back - 9. Next - 0. Exit
    
len += formatex(menu[len], sizeof menu len"^n\r8.\w %L^n\r9.\w %L^n^n\r0.\w %L"id"MENU_BACK"id"MENU_NEXT"id"MENU_EXIT")
    
    
show_menu(idKEYSMENUmenu, -1"Human Class Menu")
}

/* ----------------------- Menu Handlers -------------------------*/

// Game Menu
public menu_game(idkey)
{
    if(
get_pcvar_num(cvar_removexp) == 1key++;
    
    switch (
key)
    {
        case 
0// Buy a level up
        
{
            if(
getAmmoPacks(id) >= getNeededPacks(id))
            {
                
setAmmoPacks(idgetAmmoPacks(id) - getNeededPacks(id))
                
userLevel[id] += 1
                save_data
(id)
                
                
// Inform the user they leveled up
                
zp_colored_print(id"^x04%s^x01 %L %d"textHeaderid ,"MENU_BUY_LEVEL"userLevel[id])
                
ShowHUD(id)
            } else {
                
zp_colored_print(id"^x04%s^x01 %L"textHeaderid ,"ERR_NOTENOUGHPACKS")
            }
            
            
// Return to the main xp menu
            
show_menu_game(id);
            
        }
        
        case 
1// Human Classes
        
{
            
// Restrict it here if we wanted to
            
show_menu_hclass(id)
        }
        
        case 
2// Zombie Classes
        
{
            if (
get_pcvar_num(cvar_removezombie) == 0)
            {
                
// Restrict it here if we wanted to
                
show_menu_zclass(id)
            }
        }
    }
    
    return 
PLUGIN_HANDLED;
}

// Zombie Class Menu
public menu_zclass(idkey)
{
    
// Special keys / items list exceeded
    
if (key >= MENU_KEY_BACK || ZCLASSES_SELECTION >= g_zclass_i)
    {
        switch (
key)
        {
            case 
MENU_KEY_BACK// back
            
{
            if (
ZCLASSES_STARTID->= 0ZCLASSES_STARTID -= 
            
}
            case 
MENU_KEY_NEXT// next
            
{
                if (
ZCLASSES_STARTID+g_zclass_iZCLASSES_STARTID += 7
            
}
            case 
MENU_KEY_EXIT// exit
            
{
                return 
PLUGIN_HANDLED;
            }
        }
        
        
// Show extra items menu again
        
show_menu_zclass(id)
        return 
PLUGIN_HANDLED;
    {
    
// They selected their own class
    
if (ZCLASSES_SELECTION == g_zombieclassnext[id])
    }
    {
        
//Plugin continues if this is false (sets class info on connect)
        
if( g_zclass_showmenu[id] == false//when a client first connects, the menu shows all zombies as a choice even the one the client defaults to (index of 0)
        
{
            
// Alert them they already have chosen a zombie
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_ALREADYSELECTED")
            
show_menu_zclass(id)
            
            
// They had already chosen this zombie, dont rerun the command
            
return PLUGIN_HANDLED;
        }
    }
    
    if (
get_pcvar_num(cvar_removexp) == 0)
    {
        if (
g_zclass_lvl[HCLASSES_SELECTION] > userLevel[id])
        {
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_NOTLEVEL")
            
show_menu_zclass(id)
            return 
PLUGIN_HANDLED;
        }
    }
    
    
// Store selection for the next infection
    
g_zombieclassnext[id] = ZCLASSES_SELECTION;
    
    
// Disable showing menu since theyve chosen
    
g_zclass_showmenu[id] = false;
        
    
// Show selected zombie class info and stats
    
zp_colored_print(id"^x04%s^x01 %L: %s"textHeaderid"ZOMBIE_SELECT_XP"g_zclass_name[g_zombieclassnext[id]])
    
zp_colored_print(id"^x04%s^x01 %L: %d %L: %d %L: %d %L: %d%%"textHeaderid"ZOMBIE_ATTRIB1_XP"g_zclass_hp[g_zombieclassnext[id]], id"ZOMBIE_ATTRIB2_XP"g_zclass_spd[g_zombieclassnext[id]],
    
id"ZOMBIE_ATTRIB3_XP"floatround(g_zclass_grav[g_zombieclassnext[id]]*800), id"ZOMBIE_ATTRIB4_XP"floatround(g_zclass_kb[g_zombieclassnext[id]]*100))
    
    
// Set the class for zombie plague
    
zp_set_user_zombie_class(idg_zombieclassnext[id])
    
    return 
PLUGIN_HANDLED;
}

// Human Class Menu
public menu_hclass(idkey)
{
    
// Special keys / items list exceeded
    
if (key >= MENU_KEY_BACK || HCLASSES_SELECTION >= g_hclass_i)
    {
        switch (
key)
        {
            case 
MENU_KEY_BACK// back
            
{
                if (
HCLASSES_STARTID->= 0HCLASSES_STARTID -= 7
            
}
            case 
MENU_KEY_NEXT// next
            
{
                if (
HCLASSES_STARTID+g_hclass_iHCLASSES_STARTID += 7
            
}
            case 
MENU_KEY_EXIT// exit
            
{
                return 
PLUGIN_HANDLED;
            }
        }
        
        
// Show human list again
        
show_menu_hclass(id)
        return 
PLUGIN_HANDLED;
    }
    if (
HCLASSES_SELECTION == g_humanclassnext[id])
    {
        
// When a client first connects, the menu shows all zombies as a choice even the one the client defaults to (index of 0)
        
if( g_hclass_showmenu[id] == false)
        {
            
// Alert them they alaerdy have chosen a zombie
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_ALREADYSELECTED")
            
show_menu_hclass(id)
            return 
PLUGIN_HANDLED//they had already chosen this zombie, dont rerun the command
        
}
    }
    
    if (
get_pcvar_num(cvar_removexp) == 0)
    {
        if (
g_hclass_lvl[HCLASSES_SELECTION] > userLevel[id])
        {
            
zp_colored_print(id"^x04%s^x01 %L"textHeaderid"ERR_NOTLEVEL")
            
show_menu_hclass(id)
            return 
PLUGIN_HANDLED;
        }
    }

    
// Store selection for the next infection
    
g_humanclassnext[id] = HCLASSES_SELECTION;
    
    
// Disable showing menu since theyve chosen
    
g_hclass_showmenu[id] = false;
    
    
// Show selected human class info and stats
    
zp_colored_print(id"^x04%s^x01 %L: %s"textHeaderid"HUMAN_SELECT_XP"g_hclass_name[g_humanclassnext[id]])
    
zp_colored_print(id"^x04%s^x01 %L: %d %L: %d %L: %d"textHeaderid"HUMAN_ATTRIB1_XP"g_hclass_hp[g_humanclassnext[id]], id"HUMAN_ATTRIB2_XP"g_hclass_spd[g_humanclassnext[id]],
    
id"HUMAN_ATTRIB3_XP"floatround(g_hclass_grav[g_humanclassnext[id]]*800), id)
    
    return 
PLUGIN_HANDLED;
}

public 
ShowHUD(taskid)
{
    
//if (get_pcvar_num(cvar_removexp) == 1 ) return;
    
    
static id;
    
    
// Our ID
    
id ID_SHOWHUD;
    
    
// Player died?
    
if (!is_user_alive(id))
    {
        
// Get spectating target
        
id pev(idPEV_SPEC_TARGET//other persons ID
        
        // Target not alive
        
if (!is_user_alive(id)) return;
    }
    
    
// Format the classname
    
static redgreenblueg_name[sizeof g_hclass_name]; // Hopefully g_zclass_name and g_zclass_name will be left the same array size 
    
    
if ( g_human[id] == false // zombies
    
{
        
red 0
        green 
255
        blue 
0
        
        formatex
(g_namesizeof g_name 1"%L"id"HUD_ZOMBIE");        
    }
    else 
// humans
    
{
        
red 0
        green 
255
        blue 
0
        
        copy
(g_namesizeof g_name 1g_hclass_name[g_humanclass[id]]);
    }
    
    if (
id != ID_SHOWHUD)
    {
        if (
get_pcvar_num(cvar_removexp) == 
        {
            
// Set our HUD in position for spectating
            
set_hudmessage(255255255HUD_SPECT_XHUD_SPECT_Y06.01.10.00.0, -1);
            
ShowSyncHudMsg(ID_SHOWHUDg_MsgSync2"%L: %s - %L: %d"ID_SHOWHUD"HUD_CLASS"g_nameID_SHOWHUD"HUD_LEVEL"userLevel[id]);
        } else {
            
// Just show the class information
            
set_hudmessage(255255255HUD_SPECT_XHUD_SPECT_Y06.01.10.00.0, -1);
            
ShowSyncHudMsg(ID_SHOWHUDg_MsgSync2"%L: %s"ID_SHOWHUD"HUD_CLASS"g_name);
        }
    } else {
        if (
get_pcvar_num(cvar_removexp) == 
        {
            
// Set our HUD in position for the player
            
set_hudmessage(redgreenblueHUD_STATS_XHUD_STATS_Y06.01.10.00.0, -1);
            
ShowSyncHudMsg(idg_MsgSync2"%L: %s - %L: %d^t^t^t"id"HUD_CLASS"g_nameid"HUD_LEVEL"userLevel[id]);
        } else {
            
// Just show the class information
            
set_hudmessage(redgreenblueHUD_STATS_XHUD_STATS_Y06.01.10.00.0, -1);
            
ShowSyncHudMsg(idg_MsgSync2"%L: %s^t^t^t"id"HUD_CLASS"g_name);    
        }
    }
}

// Native: native_get_user_human_class
public native_get_user_human_class(id)
{
    return 
g_humanclass[id];
}

// Native: zpxp_register_human_class
public native_register_human_class(const name[], const info[], const model[], const weapons[], hpspeedFloat:gravitylevel)
{
    
// Reached human classes limit
    
if (g_hclass_i >= sizeof g_hclass_name)
        return -
1;
    
    
// Strings passed byref
    
param_convert(1)
    
param_convert(2)
    
param_convert(3)
    
param_convert(4)
    
    
// Add the class
    
copy(g_hclass_name[g_hclass_i], sizeof g_hclass_name[] - 1name)
    
copy(g_hclass_info[g_hclass_i], sizeof g_hclass_info[] - 1info)
    
copy(g_hclass_model[g_hclass_i], sizeof g_hclass_model[] - 1model)
    
copy(g_hclass_weapons[g_hclass_i], sizeof g_hclass_weapons[] - 1weapons)
    
g_hclass_hp[g_hclass_i] = hp
    g_hclass_spd
[g_hclass_i] = speed
    g_hclass_grav
[g_hclass_i] = gravity
    g_hclass_lvl
[g_hclass_i] = level
    
    
    
// For the load_data and save_data
    
new tSave[40]
    
formatex(tSavesizeof tSave 1"%s%s"nameinfo);
    
replace_all(tSavesizeof tSave 1";""")
    
replace_all(tSavesizeof tSave 1" """)
    
g_hclass_load[g_hclass_i] =  tSave;
        
    
// Increase registered classes counter
    
g_hclass_i++
    
    
// Return id under which we registered the class
    
return g_hclass_i-1;
}

// Native: zpxp_register_zombie_class
public native_register_zombie_class(const name[], const info[], const model[], const clawmodel[], hpspeedFloat:gravityFloat:knockbacklevel)
{    
    
// Dont return -1, we wil get lots of server window print errors from the plugins
    
if( get_pcvar_num(cvar_removezombie) == 2) return 0;
    
    
//Bugfix for loading zombies
    
loadedZombies true;
    
    
// Strings passed byref
    
param_convert(1)
    
param_convert(2)
    
param_convert(3)
    
param_convert(4)
    
    
// Save the name, level required, and classid
    
copy(g_zclass_name[g_zclass_i], sizeof g_zclass_name[] - 1name)
    
copy(g_zclass_info[g_zclass_i], sizeof g_zclass_info[] - 1info)
    
copy(g_zclass_model[g_zclass_i], sizeof g_zclass_model[] - 1model)
    
copy(g_zclass_clawmodel[g_zclass_i], sizeof g_zclass_clawmodel[] - 1clawmodel)
    
    
g_zclass_hp[g_zclass_i] = hp
    g_zclass_spd
[g_zclass_i] = speed
    g_zclass_grav
[g_zclass_i] = gravity
    g_zclass_kb
[g_zclass_i] = knockback
    g_zclass_lvl
[g_zclass_i] = level
    
    
// For the load_data and save_data
    
new tSave[40]
    
formatex(tSavesizeof tSave 1"%s%s"nameinfo);
    
replace_all(tSavesizeof tSave 1";""")
    
replace_all(tSavesizeof tSave 1" """)
    
g_zclass_load[g_zclass_i] =  tSave;
    
    
// Get the classid from zombie plague
    
new g_returnclass_id;
    
g_returnclass_id zp_register_zombie_class(g_zclass_name[g_zclass_i], g_zclass_info[g_zclass_i], g_zclass_model[g_zclass_i], g_zclass_clawmodel[g_zclass_i], g_zclass_hp[g_zclass_i] / 2g_zclass_spd[g_zclass_i], g_zclass_grav[g_zclass_i], g_zclass_kb[g_zclass_i]);
    
    
// Make sure there was no error
    
if( g_returnclass_id == -)
    {
        
server_print("%s %L"textHeaderLANG_PLAYER"ERR_BADRETURN");
        return -
1
    
}
    
    
// Increase registered classes counter
    
g_zclass_i++
    
    
// Return id under which we registered the class
    
return g_zclass_i-1;
}

public 
native_register_extra_item(const name[], costteam)
{
    
//TO DO 
    
}

/*================================================================================
--The following are copied directly from zombie_plague, no reinventing wheels...
[Shared Functions]
=================================================================================*/

// Welcome Message Task
public welcome_msg()
{
    
// Show mod info
    
zp_colored_print(0"^x04%s^x01 %L"textHeaderOrigLANG_PLAYER"NOTICE_INFO_XP")
}

// Log Event Round Start
public logevent_round_start()
{
    
// Freezetime ends
    
g_freezetime false
}

// Get User Team
stock fm_get_user_team(id)
{
    return 
get_pdata_int(idOFFSET_CSTEAMSOFFSET_LINUX);
}

zp_colored_print(target, const message[], any:...)
{
    static 
buffer[512], iargscount
    argscount 
numargs()
    
    
// Send to everyone
    
if (!target)
    {
        static 
player
        
for (player 1player <= g_maxplayersplayer++)
        {
            
// Not connected
            
if (!is_user_connected(player))
                continue;
            
            
// Remember changed arguments
            
static changed[5], changedcount // [5] = max LANG_PLAYER occurencies
            
changedcount 0
            
            
// Replace LANG_PLAYER with player id
            
for (2argscounti++)
            {
                if (
getarg(i) == LANG_PLAYER)
                {
                    
setarg(i0player)
                    
changed[changedcount] = i
                    changedcount
++
                }
            }
            
            
// Format message for player
            
vformat(buffersizeof buffer 1message3)
            
            
// Send it
            
message_begin(MSG_ONEg_msgSayText_player)
            
write_byte(player)
            
write_string(buffer)
            
message_end()
            
            
// Replace back player id's with LANG_PLAYER
            
for (0changedcounti++)
                
setarg(changed[i], 0LANG_PLAYER)
        }
    }
    
    
// Send to specific target
    
else
    {
        
// Replace LANG_PLAYER with player id
        
for (2argscounti++)
        {
        if (
getarg(i) == LANG_PLAYER)
            
setarg(i0target)
        }
        
        
// Format message for player
        
vformat(buffersizeof buffer 1message3)
        
        
// Send it
        
message_begin(MSG_ONEg_msgSayText_target)
        
write_byte(target)
        
write_string(buffer)
        
message_end()
    }
}

/*================================================================================
    Code JUST for giving guns
================================================================================*/

// Drop primary/secondary weapons
stock drop_weapons(iddropwhat)
{
    
// Get user weapons
    
static weapons[32], numiweaponid
    num 
// reset passed weapons count (bugfix)
    
get_user_weapons(idweaponsnum)
    
    
// Loop through them and drop primaries or secondaries
    
for (0numi++)
    {
        
// Prevent re-indexing the array
        
weaponid weapons[i]
        
        if ((
dropwhat == && ((1<<weaponid) & PRIMARY_WEAPONS_BIT_SUM)) || (dropwhat == && ((1<<weaponid) & SECONDARY_WEAPONS_BIT_SUM)))
        {
            
// Get the weapon entity
            
static wname[32], weapon_ent
            get_weaponname
(weaponidwnamesizeof wname 1)
            
weapon_ent fm_find_ent_by_owner(-1wnameid);
            
            
// Hack: store weapon bpammo on PEV_ADDITIONAL_AMMO
            
set_pev(weapon_entPEV_ADDITIONAL_AMMOfm_get_user_bpammo(idweaponid))
            
            
// Player drops the weapon and looses his bpammo
            
engclient_cmd(id"drop"wname)
            
fm_set_user_bpammo(idweaponid0)
        }
    }
}

// Set User BP Ammo
stock fm_set_user_bpammo(idweaponamount)
{
    static 
offset
    
    
switch(weapon)
    {
        case 
CSW_AWPoffset OFFSET_AWM_AMMO;
        case 
CSW_SCOUT,CSW_AK47,CSW_G3SG1offset OFFSET_SCOUT_AMMO;
        case 
CSW_M249offset OFFSET_PARA_AMMO;
        case 
CSW_M4A1,CSW_FAMAS,CSW_AUG,CSW_SG550,CSW_GALI,CSW_SG552offset OFFSET_FAMAS_AMMO;
        case 
CSW_M3,CSW_XM1014offset OFFSET_M3_AMMO;
        case 
CSW_USP,CSW_UMP45,CSW_MAC10offset OFFSET_USP_AMMO;
        case 
CSW_FIVESEVEN,CSW_P90offset OFFSET_FIVESEVEN_AMMO;
        case 
CSW_DEAGLEoffset OFFSET_DEAGLE_AMMO;
        case 
CSW_P228offset OFFSET_P228_AMMO;
        case 
CSW_GLOCK18,CSW_MP5NAVY,CSW_TMP,CSW_ELITEoffset OFFSET_GLOCK_AMMO;
        case 
CSW_FLASHBANGoffset OFFSET_FLASH_AMMO;
        case 
CSW_HEGRENADEoffset OFFSET_HE_AMMO;
        case 
CSW_SMOKEGRENADEoffset OFFSET_SMOKE_AMMO;
        case 
CSW_C4offset OFFSET_C4_AMMO;
        default: return;
    }
    
    
set_pdata_int(idoffsetamountOFFSET_LINUX)
}

// Get User BP Ammo
stock fm_get_user_bpammo(idweapon)
{
    static 
offset
    
    
switch(weapon)
    {
        case 
CSW_AWPoffset OFFSET_AWM_AMMO;
        case 
CSW_SCOUT,CSW_AK47,CSW_G3SG1offset OFFSET_SCOUT_AMMO;
        case 
CSW_M249offset OFFSET_PARA_AMMO;
        case 
CSW_M4A1,CSW_FAMAS,CSW_AUG,CSW_SG550,CSW_GALI,CSW_SG552offset OFFSET_FAMAS_AMMO;
        case 
CSW_M3,CSW_XM1014offset OFFSET_M3_AMMO;
        case 
CSW_USP,CSW_UMP45,CSW_MAC10offset OFFSET_USP_AMMO;
        case 
CSW_FIVESEVEN,CSW_P90offset OFFSET_FIVESEVEN_AMMO;
        case 
CSW_DEAGLEoffset OFFSET_DEAGLE_AMMO;
        case 
CSW_P228offset OFFSET_P228_AMMO;
        case 
CSW_GLOCK18,CSW_MP5NAVY,CSW_TMP,CSW_ELITEoffset OFFSET_GLOCK_AMMO;
        case 
CSW_FLASHBANGoffset OFFSET_FLASH_AMMO;
        case 
CSW_HEGRENADEoffset OFFSET_HE_AMMO;
        case 
CSW_SMOKEGRENADEoffset OFFSET_SMOKE_AMMO;
        case 
CSW_C4offset OFFSET_C4_AMMO;
        default: return -
1;
    }
    
    return 
get_pdata_int(idoffsetOFFSET_LINUX);
}

// Give an item to a player (from fakemeta_util)
stock fm_give_item(id, const item[])
{
    static 
ent
    ent 
engfunc(EngFunc_CreateNamedEntityengfunc(EngFunc_AllocStringitem))
    if (!
pev_valid(ent)) return;
    
    static 
Float:originF[3]
    
pev(idpev_originoriginF)
    
set_pev(entpev_originoriginF)
    
set_pev(entpev_spawnflagspev(entpev_spawnflags) | SF_NORESPAWN)
    
dllfunc(DLLFunc_Spawnent)
    
    static 
save
    save 
pev(entpev_solid)
    
dllfunc(DLLFunc_Touchentid)
    if (
pev(entpev_solid) != save)
        return;
    
    
engfunc(EngFunc_RemoveEntityent)
}

// Strip user weapons (from fakemeta_util)
stock fm_strip_user_weapons(id)
{
    static 
ent
    ent 
engfunc(EngFunc_CreateNamedEntityengfunc(EngFunc_AllocString"player_weaponstrip"))
    if (!
pev_valid(ent)) return;
    
    
dllfunc(DLLFunc_Spawnent)
    
dllfunc(DLLFunc_Useentid)
    
engfunc(EngFunc_RemoveEntityent)
}


// Find entity by its owner (from fakemeta_util)
stock fm_find_ent_by_owner(entity, const classname[], owner)
{
    while ((
entity engfunc(EngFunc_FindEntityByStringentity"classname"classname)) && pev(entitypev_owner) != owner) {}
    
    return 
entity;
}

strip_weapons (id)
{
    if( !
get_pcvar_num(cvar_removeweapons) )
    {    
        
// Drop previous weapons
        
drop_weapons(id1)
        
drop_weapons(id2)
    }

    
// Strip off from weapons
    
fm_strip_user_weapons(id)
    
fm_give_item(id"weapon_knife")    
}

// Buy Primary Weapon
give_primary_weapon(idkey)
{    
    
// Get weapon index
    
static weaponid
    weaponid 
get_weaponid(g_primary_items[key])
    
    
// Give the new weapon
    
fm_give_item(idg_primary_items[key])
    
fm_set_user_bpammo(idweaponidMAXBPAMMO[key])
    
    
/*
    // Give additional items
    static i
    for (i = 0; i < sizeof g_additional_items; i++)
        fm_give_item(id, g_additional_items[i])
    */
}

give_secondary_weapon(idkey)
{    
    
// Get weapon index
    
static weaponid
    weaponid 
get_weaponid(g_secondary_items[key])
    
    
// Give the new weapon with full ammo
    
fm_give_item(idg_secondary_items[key])
    
fm_set_user_bpammo(idweaponidMAXBPAMMO[weaponid])

}
/*================================================================================
    End Code just for giving guns
================================================================================*/ 
Creando TTT : 5%
Responder
#21
He intentado todo lo que dicen ustedes, sigue sin restringir ... Triste alguan solucion ? gracias
No hay mejor maestro que la experiencia más amarga de uno mismo, todo parece imposible hasta que se hace.
Responder
#22
Podrías dar más información de lo que pasa. Por ejemplo si te deja elegir la clase o si ni siquiera te deja elegirla, te tira algun error en la consola del servidor

Ni te molestes en enviarme un mensaje privado para pedirme ayuda porque NO lo voy a contestar.
Gracias por su atención.
Responder
#23
(15/10/2013, 04:28 PM)alan_el_more escribió: Podrías dar más información de lo que pasa. Por ejemplo si te deja elegir la clase o si ni siquiera te deja elegirla, te tira algun error en la consola del servidor





Deja elegir las clases lo que pasa esque apartir de la segunda pagina de 8 a 14 no restringe por niveles
Creando TTT : 5%
Responder
#24
(15/10/2013, 04:28 PM)alan_el_more escribió: Podrías dar más información de lo que pasa. Por ejemplo si te deja elegir la clase o si ni siquiera te deja elegirla, te tira algun error en la consola del servidor





mira voy a explicarlo claro, yo ahora mismo tengo metidas 7 clases de zombies que son una pagina, pero quiero meter 6 mas y eso conlleva crear otra pagina pero claro, la otra pagina no la restringe por niveles, salen como que no puedes elegirlos así en gris pero si puedes
No hay mejor maestro que la experiencia más amarga de uno mismo, todo parece imposible hasta que se hace.
Responder
#25
Probá cambiando esto:

Código PHP:
for (class = ZCLASSES_STARTID; class < min(ZCLASSES_STARTID+9g_zclass_i); class++) 



Por esto:

Código PHP:
for (class = ZCLASSES_STARTID; class < g_zclass_i; class++) 



Aparece dos veces eso en tu código, cambialo en los dos lugares.
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)