Pagina 1 din 1

Zombie Experience

Scris: Mie Noi 27, 2024 1:36 pm
de Diliul
Descriere: Acest xp chiar e simplu si usor de utilizat pe langa asta castigati ca beneficiu human class ce va ajuta pentru update-uri viitoare la server si asa mai departe , xp-ul e pe baza de ammo asa ca fiecare zm/om ce cumpara xp primeste un level, eu am facut pe acest xp in general 100 de levele pentru a continua sa joace lumea si totodata sa fie un motiv bun pentru a ajunge la level 100, pentru serverele de zombi ce vor sa implementeze XP

Descarcare: https://www.mediafire.com/file/8tp6krxjas5nlfa/zombieXP.rar/file

Cod: Selectaţi tot

#include <amxmodx>
#include <amxmisc>
#include <nvault>
#include <fakemeta>
#include <zombieplague>
#include <hamsandwich>
#include <fun>

#define TRIGGER_SAYMENU

new sound_level_up[] = { "misc/zp_level_up_zpa.wav"}
new sound_health[] = { "items/medshot4_zpa.wav" }

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

#if defined ZP_BANK_AUTOSAVE // Daca il dezactivezi nu o sa mai poti lua xp cu ammo

native zp_bank_get_packs(id)
native zp_bank_set_packs(id, value)
#endif

static const SAVEXP[] = "salvarexp"

new gvault;
#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], userAuthID[33][32], userNeededPacks[33] , userName[33][32]
new g_modname[32] // for formating the mod name
new g_maxplayers // max players counter
new g_logfile[64] 

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

const MAX_CLASSSES = 40

// 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_removexp, cvar_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 = 5 // offsets 5 higher in Linux builds
enum
{
    CS_TEAM_UNASSIGNED = 0,
    CS_TEAM_T,
    CS_TEAM_CT,
    CS_TEAM_SPECTATOR
}
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)

// Message IDs vars
new g_msgSayText

// Constants
new const textHeader[] = "[ZPXP]"

public plugin_precache()
{
    // Register all our cvars
    cvar_removexp = register_cvar("zp_xp_remove", "0");
    cvar_removezombie = register_cvar("zp_xp_remove_zm", "0");
    precache_sound( sound_level_up )
    precache_sound( sound_health )
}

public plugin_init()
{
    // Register the plugin
    register_plugin("Zombie Experience", "2.0", "Rainq")

    // 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 the user human on connecting
    RegisterHam(Ham_Spawn, "player", "fw_PlayerSpawn_Post", 1)

    // Set our vars to disable zombie plague functions
    set_task(1.0, "set_cvars")

    // Register variables
    pcvars[enable] = register_cvar("zp_xp_mod", "1")
    pcvars[packslevelup] = 10

    #if defined TRIGGER_SAYMENU
    register_clcmd("say xp", "handle_say_xp")
    register_clcmd("say level", "handle_say_level")
    register_clcmd("say class", "handle_say_class")
    register_clcmd("say xpmenu", "handle_say_xpmenu")
    #endif

    //Settings variables
    g_msgSayText = get_user_msgid("SayText")

    // Format mod name
    formatex(g_modname, sizeof g_modname - 1, ".:: Zombie XP ::.")

    // Get Max Players
    g_maxplayers = get_maxplayers()
    //nVault
    gvault = nvault_open(SAVEXP);
}
public set_cvars()
{
    // Disable zombie_plague's zombie auto menu
    if( get_pcvar_num(cvar_removezombie) == 0) set_cvar_num("zp_zombie_classes", 0);
}

public plugin_natives()
{
    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)
    register_native("zp_set_level","native_level",1)
    register_native("zp_get_level","native_get_lvl",1)
}
public native_level(id,amount)
{
    userLevel[id] = amount;
}
public native_get_lvl(id)
{
    return userLevel[id];
}
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 o = 1; o < 33; o++)
        {
            if ( !is_user_connected(o) ) continue;
            save_data(o);
        }
    }
}

#if defined TRIGGER_SAYMENU
public handle_say_xp(id)
{
    zp_colored_print(id, "^x04%s^x01 %L", textHeader, id, "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", textHeader, id, "SAY_LEVEL", userLevel[id])
    return PLUGIN_HANDLED
}
public handle_say_class(id)
{
    //return class
    zp_colored_print(id, "^x04%s^x01 %L", textHeader, id, "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 ZP_BANK_AUTOSAVE
public getAmmoPacks(id)
{
    return zp_bank_get_packs(id);
}
public setAmmoPacks(id, value)
{
    return zp_bank_set_packs(id, value);
}
#else
public getAmmoPacks(id)
{
    return zp_get_user_ammo_packs(id);
}
public setAmmoPacks(id, value)
{
    return zp_set_user_ammo_packs(id, value);
}
#endif

public SetLevel(id, level, cid)
{
    if (!cmd_access(id, level, cid, 2)) 
    return PLUGIN_HANDLED; 

    new arg[32] 
    read_argv(1, arg, 31) 

    new player = cmd_target(id, arg, CMDTARGET_ALLOW_SELF) 
    
    if (!player) 
    return PLUGIN_HANDLED 

    new spower[32], name2[32], name[32] 

    get_user_name(id, name, 31) 
    get_user_name(player, name2, 31) 

    read_argv(2, spower, 31) 
    
    new arg2 = str_to_num(spower) 
    
    if(arg2 <= 0)
    {
        return PLUGIN_HANDLED;
    }
    if(arg2 > g_hclass_i)
    {
        return PLUGIN_HANDLED;
    }
    if(id == player)
    {
        userLevel[id] = arg2;
        g_humanclassnext[id] = userLevel[id]-1; 
        g_humanclass[id] = g_humanclassnext[id]; 
        g_zombieclassnext[id] = userLevel[id]-1; 
        setHumanParameters(id) 

        save_data(id)
    }
    else
    {
        userLevel[player] = arg2; 
        g_humanclassnext[player] = userLevel[player]-1; 
        g_humanclass[player] = g_humanclassnext[player]; 
        g_zombieclassnext[player] = userLevel[player]-1; 
        setHumanParameters(id) 
    
        save_data(player)
    }
    return PLUGIN_HANDLED;
}

public getNeededPacks(id)
{
    switch(userLevel[id])
    {
        //case 1 : return 5
        case 2 : return 10
        case 3 : return 15
        case 4 : return 20
        case 5 : return 30
        case 6 : return 60
        case 7 : return 80
        case 8 : return 100
        case 9 : return 105
        case 10: return 110
        case 11: return 115
        case 12: return 125
        case 13: return 150
        case 14: return 175
        case 15: return 200
        case 16: return 215
        case 17: return 230
        case 18: return 245
        case 19: return 260
        case 20: return 280
        case 21: return 300
        case 22: return 310
        case 23: return 330
        case 24: return 350
        case 25: return 400
        case 26: return 420
        case 27: return 440
        case 28: return 460
        case 29: return 480
        case 30: return 500
        case 31: return 520
        case 32: return 540
        case 33: return 560
        case 34: return 580
        case 35: return 600
        case 36: return 640
        case 37: return 680
        case 38: return 700
        case 39: return 715
        case 40: return 730
        case 41: return 760
        case 42: return 790
        case 43: return 820
        case 44: return 850
        case 45: return 900
        case 46: return 920
        case 47: return 940
        case 48: return 960
        case 49: return 980
        case 50: return 1000
        case 51: return 1050
        case 52: return 1070
        case 53: return 1100
        case 54: return 1120
        case 55: return 1140
        case 56: return 1160
        case 57: return 1180
        case 58: return 1200
        case 59: return 1220
        case 60: return 1240
        case 61: return 1260
        case 62: return 1280
        case 63: return 1300
        case 64: return 1320
        case 65: return 1340
        case 66: return 1360
        case 67: return 1380
        case 68: return 1400
        case 69: return 1450
        case 70: return 1500
        case 71: return 1700
        case 72: return 2000
        case 73: return 2020
        case 74: return 2023
        case 75: return 2050
        case 76: return 2080
        case 77: return 2100
        case 78: return 2120
        case 79: return 2140
        case 80: return 2160
        case 81: return 2180
        case 82: return 2200
        case 83: return 2220
        case 84: return 2240
        case 85: return 2260
        case 86: return 2280
        case 87: return 2300
        case 88: return 2340
        case 89: return 2380
        case 90: return 2400
        case 91: return 3000
        case 92: return 4000
        case 93: return 5000
        case 94: return 6000
        case 95: return 7000
        case 96: return 8000
        case 97: return 9000
        case 98: return 10000
        case 99: return 50000
        case 100: return 100000  // Nivel Maxim
    }
    return pcvars[packslevelup] * userLevel[id]
}

public SetPacksLevelUp(id, value)
{
    //this allows the user to change the multiplier for ammo cost
    new arg[10], arg2
    read_argv(1, arg, sizeof arg - 1)

    arg2 = str_to_num(arg)
    if(arg2 > 0)
    {
        pcvars[packslevelup] = arg2;

        //go through each player and change the amount required to level up
        for( new o = 1; o < 33; o++)
        {
            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", textHeader, id, "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(1, arg, sizeof arg - 1)

    arg2 = str_to_num(arg)
    if(arg2 >= 0)
    {
        if(arg2 == 1)
        {
            // Disable the XP
            zp_colored_print(id, "^x04%s^x01 %L", textHeader, id, "ADMIN_CONFIRM");
            set_pcvar_num(cvar_removexp, arg2);
        }
        else if (arg2 == 0)
        {
            // Enable the XP
            zp_colored_print(id, "^x04%s^x01 %L", textHeader, id, "ADMIN_CONFIRM");
            set_pcvar_num(cvar_removexp, arg2);
        }
        else
        {
            // They typed something wrong
            zp_colored_print(id, "^x04%s^x01 %L", textHeader, id, "ERR_INVALIDENTRY");
            return PLUGIN_HANDLED;
        }
    }
    else
    {
        //must be a positive number - PRINTS TO CONSOLE, LEAVE ALONE!
        zp_colored_print(id, "^x04%s^x01 %L", textHeader, id, "ERR_NEGATIVE");
    }
    return PLUGIN_HANDLED;
}

public RemoveZombies(id)
{
    //this allows the user to enable or disable zombie classes
    new arg[10], arg2
    read_argv(1, arg, sizeof 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", textHeader, id, "ADMIN_CONFIRM");
                set_pcvar_num(cvar_removezombie, 0);
                set_cvar_num("zp_zombie_classes", 0)
            }
            else
            {
                zp_colored_print(id, "^x04%s^x01 %L", textHeader, id, "ADMIN_CONFIRM_NEXTROUND");
            }
        }
        else if (arg2 == 1)
        {
            // Disable the zombie classes
            zp_colored_print(id, "^x04%s^x01 %L", textHeader, id, "ADMIN_CONFIRM");
            set_pcvar_num(cvar_removezombie, 1);
            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", textHeader, id, "ADMIN_CONFIRM_NEXTROUND");
            set_pcvar_num(cvar_removezombie, 1);
            set_cvar_num("zp_zombie_classes", 2)
        }
        else
        {
            // They typed something wrong
            zp_colored_print(id, "^x04%s^x01 %L", textHeader, id, "ERR_INVALIDENTRY");
            return PLUGIN_HANDLED;
        }
    }
    else
    {
        //must be a positive number - PRINTS TO CONSOLE, LEAVE ALONE!
        zp_colored_print(id, "^x04%s^x01 %L", textHeader, id, "ERR_NEGATIVE");
    }
    return PLUGIN_HANDLED;
}

public show_menu_game(id)
{
    // Show our menu
    static menu[250], len, index;
    len = 0
    index = 1;

    // Title
    len += formatex(menu[len], sizeof menu - 1 - len, "\y%s^n^n", g_modname)

    if( get_pcvar_num(cvar_removexp) == 0 )
    {
        // 1. Buy a level up
        if(getAmmoPacks(id) >= getNeededPacks(id))
        {
            len += formatex(menu[len], sizeof menu - 1 - len, "\r%d.\w %L", index, id, "MENU_BUY_XP")
            len += formatex(menu[len], sizeof menu - 1 - len, " \y%d %L^n", getNeededPacks(id), id, "AMMO_PACKS_XP")
        }
        else
        {
            len += formatex(menu[len], sizeof menu - 1 - len, "\d%d. %L", index, id, "MENU_BUY_XP")
            len += formatex(menu[len], sizeof menu - 1 - len, " \d%d %L^n", getNeededPacks(id), id, "AMMO_PACKS_XP")
        }
        index++;
    }
    //Human class
    len += formatex(menu[len], sizeof menu - 1 - len, "\r%d.\w %L^n", index, id,"MENU_HCLASS")

    if (get_pcvar_num(cvar_removezombie) == 0)
    {
        //Zombie class
        index++;
        len += formatex(menu[len], sizeof menu - 1 - len, "\r%d.\w %L^n", index, id,"MENU_ZCLASS")
    }
    // 0. Exit
    len += formatex(menu[len], sizeof menu - 1 - len, "^n^n\r0.\w %L", id, "MENU_EXIT")

    show_menu(id, KEYSMENU, menu, -1, "Game Menu")
}

public log_in_player(id)
{
    new szSteam[ 36 ], szText[ 164 ];	
    get_user_name( id, szSteam, charsmax( szSteam ) );
    formatex( szText, charsmax( szText ),"[IN] %s (%i) a intrat avand %i ammo si level %i", szSteam, id, zp_get_user_ammo_packs(id), userLevel[id] );
    log_to_file( g_logfile, szText );
}

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_hclass, sizeof g_selected_hclass - 1, g_hclass_load[g_humanclassnext[id]]); }
    if( g_zclass_showmenu[id] == true) { g_selected_zclass = "-1"; } else { formatex(g_selected_zclass, sizeof g_selected_zclass -1, g_zclass_load[g_zombieclassnext[id]]); }

    formatex( vaultkey, sizeof vaultkey - 1, "%s_stats", userAuthID[id]);
    formatex( vaultData, sizeof vaultData - 1, ";1=%s;2=%s;", g_selected_hclass, g_selected_zclass);

    nvault_set(gvault, vaultkey, vaultData);

    new szSteam[ 36 ], szText[ 164 ];	
    get_user_name( id, szSteam, charsmax( szSteam ) );
    formatex( szText, charsmax( szText ),"[OUT] %s (%i) a iesit avand %i ammo si lvl %i", szSteam, id, zp_get_user_ammo_packs(id), userLevel[id] );
    log_to_file( g_logfile, szText );
}

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(vaultkey, sizeof vaultkey - 1, "%s_stats", userAuthID[id]);
    nvault_get(gvault, vaultkey, vaultReturn, sizeof vaultReturn - 1);

    new Count = ExplodeString(vaultData, sizeof vaultData - 1, sizeof vaultData[] - 1, vaultReturn, ';')

    if(Count == sizeof vaultResults - 1)
    {
        new i_hclass_id = -1, i_zclass_id = -1;

        for( new i = 0; i < sizeof vaultData - 1; i++)
        {
            ExplodeString(vaultResults, sizeof vaultResults - 1, sizeof vaultResults[] - 1, vaultData[i], '=');

            // We now have our items
            switch (str_to_num(vaultResults[0]))
            {
                case VAULT_HCLASS:
                {
                    // Look for our human class
                    if( !equali(vaultResults[1], "-1") )
                    {
                        for (new i2 = 0; i2 < g_hclass_i; i2++)
                        {
                            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 = 0; i2 < g_zclass_i; i2++)
                        {
                            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(id, i_zclass_id);
                    }
                }
            }
        }
    }
    else
    {
        g_hclass_showmenu[id] = true;
        g_zclass_showmenu[id] = true;
    }
    new szSteam[ 36 ], szText[ 164 ];	
    get_user_name( id, szSteam, charsmax( szSteam ) );
    formatex( szText, charsmax( szText ),"[INGAME] %s (%i) a salvat in timpul jocului %i ammo si level %i", szSteam, id, zp_get_user_ammo_packs(id), userLevel[id] );
    log_to_file( g_logfile, szText );
}

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(id, 0)

    // Load their data
    load_data(id);

    // Set amount of levels to level up (called after load_data)
    userNeededPacks[id] = getNeededPacks(id)
    get_user_name(id, userName[id], 31)
}

public fw_PlayerSpawn_Post(id)
{
    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)

    setHumanParameters(id)
    return FMRES_IGNORED;
}

public zp_user_infected_pre(id, infector)
{
    // Make sure he is not a human
    g_human[id] = false
}

public zp_user_infected_post(id, infector)
{
    // Do we show the menu?
    if ((g_zclass_showmenu[id] == true) && get_pcvar_num(cvar_removezombie) ==0) show_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 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 setHumanParameters(id)
{
    set_pev(id, pev_gravity, g_hclass_grav[g_humanclass[id]])
    fm_set_user_health(id, g_hclass_hp[g_humanclass[id]])
}

public resetvars(id)
{
    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(id, userAuthID[id], 31)
    g_resetparams[id] = false
}

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

stock ExplodeString( Output[][], Max, Size, Input[], Delimiter )
{
    new Idx, l = strlen(Input), Len;
    do Len += (1 + copyc( Output[Idx], Size, Input[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(id, health)
{
    (health > 0) ? set_pev(id, pev_health, float(health)) : dllfunc(DLLFunc_ClientKill, id);
}

public show_menu_zclass(id)
{
    // Player disconnected
    if (!is_user_connected(id))
    return;

    static menu[1000], len, class, removexp;
    new curClassIcon[2];

    len = 0
    removexp = get_pcvar_num(cvar_removexp);

    // Title
    len += formatex(menu[len], sizeof menu - 1 - len, "\y%L \r [%d-%d]^n^n", id, "MENU_ZCLASS_TITLE", ZCLASSES_STARTID+1, min(ZCLASSES_STARTID+7, g_zclass_i))

    #if defined ZP_ALIGN_TEXT
    // Align text
    new spacers[400], g_zclass_spacers1, g_zclass_spacers2
    new maxSpace1, maxSpace2, curSpace1[32], curSpace2[32]

    // Get max width first
    for (class = ZCLASSES_STARTID; class < min(ZCLASSES_STARTID+7, g_zclass_i); class++)
    {
        formatex(spacers, sizeof spacers - 1, "%d. %s", class-ZCLASSES_STARTID+1, g_zclass_name[class])

        g_zclass_spacers1 = strlen(spacers)
        g_zclass_spacers2 = strlen(g_zclass_info[class])

        if(g_zclass_spacers1 > maxSpace1) maxSpace1 = g_zclass_spacers1
        if(g_zclass_spacers2 > maxSpace2) maxSpace2 = g_zclass_spacers2
    }
    // 1-7. Class List
    for (class = ZCLASSES_STARTID; class < min(ZCLASSES_STARTID+7, g_zclass_i); class++)
    {
        formatex(spacers, sizeof spacers - 1, "%d. %s", class-ZCLASSES_STARTID+1, g_zclass_name[class])

        g_zclass_spacers1 = maxSpace1 - strlen(spacers)
        g_zclass_spacers2 = maxSpace2 - strlen(g_zclass_info[class])

        arrayset(curSpace1, '^0', sizeof curSpace1 - 1)
        arrayset(curSpace2, '^0', sizeof curSpace2 - 1)

        if(g_zclass_spacers1 != 0) arrayset(curSpace1, '^t', g_zclass_spacers1)
        if(g_zclass_spacers2 != 0) arrayset(curSpace2, '^t', g_zclass_spacers2)

        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 - 1 - len, "\d%s%d. %s %s %s %s^n", curClassIcon, class-ZCLASSES_STARTID+1, g_zclass_name[class], curSpace1, g_zclass_info[class], curSpace2, id)
        }
        else if (removexp == 1)
        {
            len += formatex(menu[len], sizeof menu - 1 - len, "\r%d.\w %s\y %s %s^n", class-ZCLASSES_STARTID+1, g_zclass_name[class], curSpace1, g_zclass_info[class])
        }
        else
        {
            len += formatex(menu[len], sizeof menu - 1 - len, "\r%d.\w %s\y %s %s\w %s^n", class-ZCLASSES_STARTID+1, g_zclass_name[class], curSpace1, g_zclass_info[class], curSpace2, id)
        }
    }
    #else
    for (class = ZCLASSES_STARTID; class < min(ZCLASSES_STARTID+7, g_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 - 1 - len, "\d%s%d. %s - %s^n", curClassIcon, class-ZCLASSES_STARTID+1, g_zclass_name[class], g_zclass_info[class], id)
        }
        else if (removexp == 1)
        {
            len += formatex(menu[len], sizeof menu - 1 - len, "\r%d.\w %s -\y %s^n", class-ZCLASSES_STARTID+1, g_zclass_name[class], g_zclass_info[class]);
        }
        else
        {
            len += formatex(menu[len], sizeof menu - 1 - len, "\r%d.\w %s -\y %s\w^n", class-ZCLASSES_STARTID+1, g_zclass_name[class], g_zclass_info[class], id);
        }
    }
    #endif

    // 8. Back - 9. Next - 0. Exit
    len += formatex(menu[len], sizeof menu - 1 - 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(id, KEYSMENU, menu, -1, "Zombie Class Menu")
}

public show_menu_hclass(id)
{
    // Player disconnected
    if (!is_user_connected(id))
    return;

    static menu[900], len, class, removexp
    new curClassIcon[2]
    len = 0
    removexp = get_pcvar_num(cvar_removexp);

    // Title
    len += formatex(menu[len], sizeof menu - 1 - len, "\y%L \r[%d-%d]^n^n", id, "MENU_HCLASS_TITLE", HCLASSES_STARTID+1, min(HCLASSES_STARTID+7, g_hclass_i))

    #if defined ZP_ALIGN_TEXT
    // Align text
    new spacers[400], g_hclass_spacers1, g_hclass_spacers2
    new maxSpace1, maxSpace2, curSpace1[32], curSpace2[32]

    // Get max width first
    for (class = HCLASSES_STARTID; class < min(HCLASSES_STARTID+7, g_hclass_i); class++)
    {
        formatex(spacers, sizeof spacers - 1, "%d. %s", class-HCLASSES_STARTID+1, g_hclass_name[class])

        g_hclass_spacers1 = strlen(spacers)
        g_hclass_spacers2 = strlen(g_hclass_info[class])

        if(g_hclass_spacers1 > maxSpace1) maxSpace1 = g_hclass_spacers1
        if(g_hclass_spacers2 > maxSpace2) maxSpace2 = g_hclass_spacers2
    }
    // 1-7. Class List
    for (class = HCLASSES_STARTID; class < min(HCLASSES_STARTID+7, g_hclass_i); class++)
    {
        formatex(spacers, sizeof spacers - 1, "%d. %s", class-HCLASSES_STARTID+1, g_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 != 0) arrayset(curSpace1, '^t', g_hclass_spacers1)
        if(g_hclass_spacers2 != 0) arrayset(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 - 1 - len, "\d%s%d. %s %s %s %s^n", curClassIcon, class-HCLASSES_STARTID+1, g_hclass_name[class], curSpace1, g_hclass_info[class], curSpace2, id)
        }
        else if (removexp == 1)
        {
            len += formatex(menu[len], sizeof menu - 1 - len, "\r%d.\w %s\y %s %s^n", class-HCLASSES_STARTID+1, g_hclass_name[class], curSpace1, g_hclass_info[class])
        }
        else
        {
            len += formatex(menu[len], sizeof menu - 1 - len, "\r%d.\w %s\y %s %s\w %s^n", class-HCLASSES_STARTID+1, g_hclass_name[class], curSpace1, g_hclass_info[class], curSpace2, id)
        }
    }
    #else
    for (class = HCLASSES_STARTID; class < min(HCLASSES_STARTID+7, g_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 - 1 - len, "\d%s%d. %s - %s^n", curClassIcon, class-HCLASSES_STARTID+1, g_hclass_name[class], g_hclass_info[class], id)
        }
        else if (removexp == 1)
        {
            len += formatex(menu[len], sizeof menu - 1 - len, "\r%d.\w %s -\y %s^n", class-HCLASSES_STARTID+1, g_hclass_name[class], g_hclass_info[class]);
        }
        else
        {
            len += formatex(menu[len], sizeof menu - 1 - len, "\r%d.\w %s -\y %s\w^n", class-HCLASSES_STARTID+1, g_hclass_name[class], g_hclass_info[class], id)
        }
    }
    #endif

    // 8. Back - 9. Next - 0. Exit
    len += formatex(menu[len], sizeof menu - 1 - 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(id, KEYSMENU, menu, -1, "Human Class Menu")
}

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

// Game Menu
public menu_game(id, key)
{
    if(get_pcvar_num(cvar_removexp) == 1) key++;
    switch (key)
    {
        case 0: // Buy a level up
        {
            if(getAmmoPacks(id) >= getNeededPacks(id))
            {
                if(userLevel[id]<100)
                {
                    setAmmoPacks(id, getAmmoPacks(id) - getNeededPacks(id))
                    userLevel[id] += 1
                    save_data(id)
                    new szSteam[ 36 ], szText[ 164 ];
                    get_user_name( id, szSteam, charsmax( szSteam ) );
                    formatex( szText, charsmax( szText ),"%s a urcat la levelul %i.", szSteam, userLevel[id] );
                    log_to_file( g_logfile, szText );

                    // Inform the user they leveled up
                    zp_colored_print(id, "^x04%s^x01 %L %d", textHeader, id ,"MENU_BUY_LEVEL", userLevel[id])
                    emit_sound(id, CHAN_STREAM, sound_level_up, 1.0, ATTN_NORM, 0, PITCH_HIGH );
                }
                else zp_colored_print(id, "^x04%s^x01 Maximum level has been reached!", textHeader);
            }
            else
            {
                zp_colored_print(id, "^x04%s^x01 %L", textHeader, id ,"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(id, key)
{
    // 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-7 >= 0) ZCLASSES_STARTID -= 7
            }
            case MENU_KEY_NEXT: // next
            {
                if (ZCLASSES_STARTID+7 < g_zclass_i) ZCLASSES_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", textHeader, id, "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[ZCLASSES_SELECTION] > userLevel[id])
        {
            zp_colored_print(id, "^x04%s^x01 %L", textHeader, id, "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", textHeader, id, "ZOMBIE_SELECT_XP", g_zclass_name[g_zombieclassnext[id]])
    zp_colored_print(id, "^x04%s^x01 %L: %d %L: %d %L: %d %L: %d%%", textHeader, id, "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(id, g_zombieclassnext[id])

    return PLUGIN_HANDLED;
}

// Human Class Menu
public menu_hclass(id, key)
{
    // 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-7 >= 0) HCLASSES_STARTID -= 7
            }
            case MENU_KEY_NEXT: // next
            {
                if (HCLASSES_STARTID+7 < g_hclass_i) HCLASSES_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", textHeader, id, "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", textHeader, id, "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", textHeader, id, "HUMAN_SELECT_XP", g_hclass_name[g_humanclassnext[id]])
    zp_colored_print(id, "^x04%s^x01 %L: %d %L: %d %L: %d", textHeader, id, "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;
}

// 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[], hp, speed, Float:gravity, level)
{
    // 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[] - 1, name)
    copy(g_hclass_info[g_hclass_i], sizeof g_hclass_info[] - 1, info)
    copy(g_hclass_model[g_hclass_i], sizeof g_hclass_model[] - 1, model)
    copy(g_hclass_weapons[g_hclass_i], sizeof g_hclass_weapons[] - 1, weapons)
    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(tSave, sizeof tSave - 1, "%s%s", name, info);
    replace_all(tSave, sizeof tSave - 1, ";", "")
    replace_all(tSave, sizeof 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[], hp, speed, Float:gravity, Float:knockback, level)
{
    // 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[] - 1, name)
    copy(g_zclass_info[g_zclass_i], sizeof g_zclass_info[] - 1, info)
    copy(g_zclass_model[g_zclass_i], sizeof g_zclass_model[] - 1, model)
    copy(g_zclass_clawmodel[g_zclass_i], sizeof g_zclass_clawmodel[] - 1, clawmodel)

    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(tSave, sizeof tSave - 1, "%s%s", name, info);
    replace_all(tSave, sizeof tSave - 1, ";", "")
    replace_all(tSave, sizeof 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], g_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 == -1 )
    {
        server_print("%s %L", textHeader, LANG_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;
}

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

// Get User Team
stock fm_get_user_team(id)
{
    return get_pdata_int(id, OFFSET_CSTEAMS, OFFSET_LINUX);
}
zp_colored_print(target, const message[], any:...)
{
    static buffer[512], i, argscount
    argscount = numargs()

    // Send to everyone
    if (!target)
    {
        static player
        for (player = 1; player <= g_maxplayers; player++)
        {
            // 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 (i = 2; i < argscount; i++)
            {
                if (getarg(i) == LANG_PLAYER)
                {
                    setarg(i, 0, player)
                    changed[changedcount] = i
                    changedcount++
                }
            }
            // Format message for player
            vformat(buffer, sizeof buffer - 1, message, 3)

            // Send it
            message_begin(MSG_ONE, g_msgSayText, _, player)
            write_byte(player)
            write_string(buffer)
            message_end()

            // Replace back player id's with LANG_PLAYER
            for (i = 0; i < changedcount; i++)
            setarg(changed[i], 0, LANG_PLAYER)
        }
    }
    // Send to specific target
    else
    {
        // Replace LANG_PLAYER with player id
        for (i = 2; i < argscount; i++)
        {
            if (getarg(i) == LANG_PLAYER)
            setarg(i, 0, target)
        }
        // Format message for player
        vformat(buffer, sizeof buffer - 1, message, 3)

        // Send it
        message_begin(MSG_ONE, g_msgSayText, _, target)
        write_byte(target)
        write_string(buffer)
        message_end()
    }
}
Nume: Zombie Experience
Versiune: 2.0
Link oficial: cspower / thexforce

Instalare:
1. Fisierul zombie_experience.sma il puneti in addons/amxmodx/scripting
2. Fisierul zombie_experience.amxx il puneti in addons/amxmodx/plugins
3. Intrati in fisierul addons/amxmodx/configs/plugins.ini si adaugati la urma:

Cod: Selectaţi tot

zombie_experience.amxx
4. Alti pasi necesari....

Cvar-uri (se adauga in fisierul amxmodx\configs\amxx.cfg):

Cod: Selectaţi tot

cvar_removexp - pentru a scoate xp-ul
zp_xp_remove_zm - pentru a activa alt cvar din baza ce dezactiveaza clasele de zombi din zp-ul original
Imagini: -