// MASTER CHIEF! - Master Chief Petty Officer John-117 from the game Halo.

/* CVARS - copy and paste to shconfig.cfg

//Master Chief
masterchief_level 0
masterchief_health 100        //Default 100 (no extra health)
masterchief_armor 150        //Default 150
masterchief_gravity 1.0        //Default 1.0 = no extra gravity (0.50 is 50% of normal gravity, ect.)
masterchief_speed -1        //Default -1 = no extra speed, this cvar is for all weapons (for faster then normal speed set to 261 or higher)
masterchief_p90mult 1.3        //Damage multiplyer for his P90
// Below Only used if PLAYER_MODEL define = 1
masterchief_teamglow 0        //Glow Team Color when player skin in use (0=no 1=yes)

*/

/*
* v1.6 - vittu - 11/19/07
*      - Added use of const requires amxx 1.76d or higher
*      - Added define options for more customization.
*      - Team colored models can be set with define now.
*      - Now verifies models are loaded else does not use them.
*
* v1.5 - vittu - 6/3/06
*      - Updated to amxmodx only, requires amxx 1.75 or higher.
*      - Removed engine for fakemeta only support.
*      - Changed 2 default cvar values.
*      - Added excessive checking plus other minor code changes.
*      - Fixed rare issue with stale varible giving users the hero that shouldn't have it.
*
* v1.4 - vittu - 6/14/05
*      - Minor code clean up.
*      - Lowered glow value so it's not so bright.
*
* v1.3 - vittu - 1/3/05
*      - Fixed up task set for team glow, so as not to interfere
*         with other tasks when it's removed.
*      - This should be the final version for now.
*
* v1.2 - vittu - 12/26/04
*      - Changed 2 default cvars, gravity and speed to avoid bugs.
*      - Changed give weapon time on ResetHUD, to avoid bugs.
*
* v1.1 - vittu - 12/21/04
*      - set a delay to change player model, better for servers with
*         sh_loadimmediate 0.
*
* v1.0 - vittu - 12/20/04
*      - Complete rework of entire code, started from scratch.
*      - Changed player model to automatic rather than a keydown.
*      - Added p_ weapon model (for 3rd person view).
*
*   Concept by Spartan-117 and JASerrano
*   Player and Weapon models by Strykerwolf (aka Alex Wright) & Grenappels
*/


//---------- User Changeable Defines --------//


// 0-no player model
// 1-green master chief model + glow cvar option [Default]
// 2-team colored master chief models t=red ct=blue (Note:Requires models from optional zip)
#define PLAYER_MODEL 2

// 0-continuous shooting, no reload [Default]
// 1-drop weapon and get a new one with full clip
// 4-normal cs, no reload mode
#define AMMO_MODE 0

// Comment out to not use the P90 model
#define USE_WPN_MODEL

// Comment out to not give a free P90
#define GIVE_WEAPON


//------- Do not edit below this point ------//


#include <amxmodx>
#include <fakemeta>
#include <superheromod>

// GLOBAL VARIABLES
new HeroName[] = "Master Chief"
new bool:HasMasterChief[SH_MAXSLOTS+1]
new CvarP90DmgMult

#if PLAYER_MODEL > 0
    new bool:ModelPlayerSet[SH_MAXSLOTS+1]
    new bool:ModelPlayerLoaded
    new const MasterChiefSound[] = "items/suitchargeno1.wav"

    #if PLAYER_MODEL == 1
        new const Model_Player[] = "models/player/masterchief/masterchief.mdl"
        new const Model_Player_Name[] = "masterchief"
        new CvarTeamGlow
    //#elseif does not work right
    #else
        #if PLAYER_MODEL == 2
            new const Model_Player_T[] = "models/player/masterchief_t/masterchief_t.mdl"
            new const Model_Player_CT[] = "models/player/masterchief_ct/masterchief_ct.mdl"
            new const Model_Player_Name[2][] = {
                "masterchief_t",
                "masterchief_ct"
            }
        #endif
    #endif
#endif

#if defined USE_WPN_MODEL
    new const Model_V_P90[] = "models/shmod/masterchief_v_p90.mdl"
    new const Model_P_P90[] = "models/shmod/masterchief_p_p90.mdl"
    new bool:ModelWeaponLoaded
#endif
//----------------------------------------------------------------------------------------------
public plugin_init()
{
    // Plugin Info
    register_plugin("SUPERHERO Master Chief", "1.6", "Spartan-117/vittu")

    register_dictionary("sh_masterchief.txt")

    // DO NOT EDIT THIS FILE TO CHANGE CVARS, USE THE SHCONFIG.CFG
    register_cvar("masterchief_level", "0")
    register_cvar("masterchief_health", "100")
    register_cvar("masterchief_armor", "150")
    register_cvar("masterchief_gravity", "1.0")
    register_cvar("masterchief_speed", "-1")
    CvarP90DmgMult = register_cvar("masterchief_p90mult", "1.3")

    #if PLAYER_MODEL == 1
        CvarTeamGlow = register_cvar("masterchief_teamglow", "0")
    #endif

    // FIRE THE EVENT TO CREATE THIS SUPERHERO!
    shCreateHero(HeroName, "SPARTAN project", "Become Master Chief - get a MJOLNIR battlesuit and MA5B Assault Rifle (P90), which does more damage.", false, "masterchief_level")

    // REGISTER EVENTS THIS HERO WILL RESPOND TO! (AND SERVER COMMANDS)
    // INIT
    register_srvcmd("masterchief_init", "masterchief_init")
    shRegHeroInit(HeroName, "masterchief_init")

    // EVENTS
    register_event("Damage", "masterchief_damage", "b", "2!0")

    #if PLAYER_MODEL > 0 || defined GIVE_WEAPON
        register_event("ResetHUD", "new_spawn", "b")
    #endif

    #if defined USE_WPN_MODEL || AMMO_MODE < 4
        register_event("CurWeapon", "weapon_change", "be", "1=1")
    #endif

    #if PLAYER_MODEL > 0
        register_event("DeathMsg", "masterchief_death", "a")
    #endif

    // Let Server know about the hero's variables
    shSetMaxHealth(HeroName, "masterchief_health")
    shSetMaxArmor(HeroName, "masterchief_armor")
    shSetMinGravity(HeroName, "masterchief_gravity")
    shSetMaxSpeed(HeroName, "masterchief_speed", "[0]")

    #if defined GIVE_WEAPON
        shSetShieldRestrict(HeroName)
    #endif
}
//----------------------------------------------------------------------------------------------
#if PLAYER_MODEL > 0 || defined USE_WPN_MODEL
public plugin_precache()
{
    #if PLAYER_MODEL > 0
        precache_sound(MasterChiefSound)
        ModelPlayerLoaded = true
        #if PLAYER_MODEL == 1
            if ( file_exists(Model_Player) ) {
                precache_model(Model_Player)
            }
            else {
                log_amx("[SH](%s)Aborted loading ^"%s^", file does not exist on server", HeroName, Model_Player)
                ModelPlayerLoaded = false
            }
        #else
            #if PLAYER_MODEL == 2
                if ( file_exists(Model_Player_T) ) {
                    precache_model(Model_Player_T)
                }
                else {
                    log_amx("[SH](%s)Aborted loading ^"%s^", file does not exist on server", HeroName, Model_Player_T)
                    ModelPlayerLoaded = false
                }

                if ( file_exists(Model_Player_CT) ) {
                    precache_model(Model_Player_CT)
                }
                else {
                    log_amx("[SH](%s)Aborted loading ^"%s^", file does not exist on server", HeroName, Model_Player_CT)
                    ModelPlayerLoaded = false
                }
            #endif
        #endif
    #endif

    #if defined USE_WPN_MODEL
        ModelWeaponLoaded = true
        if ( file_exists(Model_V_P90) ) {
            precache_model(Model_V_P90)
        }
        else {
            log_amx("[SH](%s)Aborted loading ^"%s^", file does not exist on server", HeroName, Model_V_P90)
            ModelWeaponLoaded = false
        }

        if ( file_exists(Model_P_P90) ) {
            precache_model(Model_P_P90)
        }
        else {
            log_amx("[SH](%s)Aborted loading ^"%s^", file does not exist on server", HeroName, Model_P_P90)
            ModelWeaponLoaded = false
        }
    #endif
}
#endif
//----------------------------------------------------------------------------------------------
public masterchief_init()
{
    // First Argument is an id
    new temp[6]
    read_argv(1, temp, 5)
    new id = str_to_num(temp)

    // 2nd Argument is 0 or 1 depending on whether the id has the hero
    read_argv(2, temp, 5)
    new hasPowers = str_to_num(temp)

    // Reset thier shield restrict status
    // Shield restrict MUST be before weapons are given out
    #if defined GIVE_WEAPON
        shResetShield(id)
    #endif

    switch(hasPowers)
    {
        case true:
        {
            HasMasterChief[id] = true

            if ( is_user_alive(id) )
            {
                #if defined GIVE_WEAPON
                    masterchief_weapons(id)
                #endif

                #if defined USE_WPN_MODEL
                    if ( ModelWeaponLoaded )
                        switch_model(id)
                #endif

                #if PLAYER_MODEL > 0
                    if ( ModelPlayerLoaded )
                        masterchief_tasks(id)
                #endif
            }
        }

        case false:
        {
            // Check is needed since this gets run on clearpowers even if user didn't have this hero
            if ( is_user_alive(id) && HasMasterChief[id] )
            {
                // This gets run if they had the power but don't anymore
                #if defined GIVE_WEAPON
                    engclient_cmd(id, "drop", "weapon_p90")
                #endif

                #if PLAYER_MODEL > 0
                    if ( ModelPlayerLoaded )
                        masterchief_unmorph(id)
                #endif

                shRemHealthPower(id)
                shRemArmorPower(id)
                shRemGravityPower(id)
                shRemSpeedPower(id)
            }

            HasMasterChief[id] = false
        }
    }
}
//----------------------------------------------------------------------------------------------
#if PLAYER_MODEL > 0 || defined GIVE_WEAPON
public new_spawn(id)
{
    if ( shModActive() && is_user_alive(id) && HasMasterChief[id] )
    {
        #if defined GIVE_WEAPON
            set_task(0.1, "masterchief_weapons", id)
        #endif

        #if PLAYER_MODEL > 0
            if ( ModelPlayerLoaded )
                masterchief_tasks(id)
        #endif
    }
}
#endif
//----------------------------------------------------------------------------------------------
#if PLAYER_MODEL > 0
masterchief_tasks(id)
{
    set_task(1.0, "masterchief_morph", id)

    #if PLAYER_MODEL == 1
        if ( get_pcvar_num(CvarTeamGlow) )
            set_task(1.0, "masterchief_glow", id+100, _, _, "b")
    #endif
}
#endif
//----------------------------------------------------------------------------------------------
#if defined GIVE_WEAPON
public masterchief_weapons(id)
{
    if ( !shModActive() || !is_user_alive(id) || !HasMasterChief[id] )
        return

    shGiveWeapon(id, "weapon_p90")
}
#endif
//----------------------------------------------------------------------------------------------
#if defined USE_WPN_MODEL
switch_model(id)
{
    if ( !shModActive() || !is_user_alive(id) || !HasMasterChief[id] )
        return

    new clip, ammo, wpnid = get_user_weapon(id, clip, ammo)

    if ( wpnid == CSW_P90 )
    {
        set_pev(id, pev_viewmodel2, Model_V_P90)
        set_pev(id, pev_weaponmodel2, Model_P_P90)
    }
}
#endif
//----------------------------------------------------------------------------------------------
#if defined USE_WPN_MODEL || AMMO_MODE < 4
public weapon_change(id)
{
    if ( !shModActive() || !HasMasterChief[id] )
        return

    //weaponID = read_data(2)
    if ( read_data(2) != CSW_P90 )
        return

    #if defined USE_WPN_MODEL
        if ( ModelWeaponLoaded )
            switch_model(id)
    #endif

    // Never Run Out of Ammo!
    #if AMMO_MODE < 4
        //clip = read_data(3)
        if ( read_data(3) == 0 )
            shReloadAmmo(id, AMMO_MODE)
    #endif
}
#endif
//----------------------------------------------------------------------------------------------
public masterchief_damage(id)
{
    if ( !shModActive() || !is_user_alive(id) )
        return

    new weapon, bodypart, attacker = get_user_attacker(id, weapon, bodypart)

    if ( attacker <= 0 || attacker > SH_MAXSLOTS )
        return

    if ( HasMasterChief[attacker] && weapon == CSW_P90 )
    {
        new damage = read_data(2)
        new headshot = bodypart == 1 ? 1 : 0

        // do extra damage
        new extraDamage = floatround(damage * get_pcvar_float(CvarP90DmgMult) - damage)
        if ( extraDamage > 0 )
            shExtraDamage(id, attacker, extraDamage, "p90", headshot)
    }
}
//----------------------------------------------------------------------------------------------
#if PLAYER_MODEL > 0
masterchief_sound(id)
{
    emit_sound(id, CHAN_AUTO, MasterChiefSound, 0.2, ATTN_NORM, SND_STOP, PITCH_NORM)
    emit_sound(id, CHAN_AUTO, MasterChiefSound, 0.2, ATTN_NORM, 0, PITCH_NORM)
}
//----------------------------------------------------------------------------------------------
public masterchief_morph(id)
{
    if ( ModelPlayerSet[id] || !is_user_alive(id) || !HasMasterChief[id] )
        return

    #if PLAYER_MODEL == 1
        cs_set_user_model(id, Model_Player_Name)
    #else
        #if PLAYER_MODEL == 2
            // Done this way for safety (ie user is spec alive)
            switch(cs_get_user_team(id))
            {
                case CS_TEAM_T: cs_set_user_model(id, Model_Player_Name[0])
                case CS_TEAM_CT: cs_set_user_model(id, Model_Player_Name[1])
                default: return
            }    
        #endif
    #endif

    masterchief_sound(id)

    // Message
    set_hudmessage(50, 205, 50, -1.0, 0.40, 2, 0.02, 4.0, 0.01, 0.1, -1)
    show_hudmessage(id, "%L", LANG_PLAYER, "SH_MASTERCHIEF_SPARTAN", HeroName)

    ModelPlayerSet[id] = true
}
//----------------------------------------------------------------------------------------------
masterchief_unmorph(id)
{
    if ( ModelPlayerSet[id] && is_user_connected(id) )
    {
        if ( is_user_alive(id) )
        {
            // Message only shows if alive and dropping hero
            set_hudmessage(50, 205, 50, -1.0, 0.40, 2, 0.02, 4.0, 0.01, 0.1, -1)
            show_hudmessage(id, "%L", LANG_PLAYER, "SH_MASTERCHIEF_MODE_OFF", HeroName)
        }

        cs_reset_user_model(id)

        masterchief_sound(id)

        ModelPlayerSet[id] = false

        #if PLAYER_MODEL == 1
            if ( get_pcvar_num(CvarTeamGlow) )
            {
                remove_task(id+100)
                set_user_rendering(id)
            }
        #endif
    }
}
//----------------------------------------------------------------------------------------------
#if PLAYER_MODEL == 1
public masterchief_glow(id)
{
    id -= 100

    if ( !shModActive() || !is_user_connected(id) )
    {
        //Don't want any left over residuals
        remove_task(id+100)
        return
    }

    if ( HasMasterChief[id] && is_user_alive(id) )
    {
        switch(cs_get_user_team(id))
        {
            case CS_TEAM_T: shGlow(id, 100, 0, 0)
            case CS_TEAM_CT: shGlow(id, 0, 0, 100)
        }
    }
}
#endif
//----------------------------------------------------------------------------------------------
public masterchief_death()
{
    new id = read_data(2)

    if ( !HasMasterChief[id] )
        return

    if ( ModelPlayerLoaded )
        masterchief_unmorph(id)
}
#endif
//----------------------------------------------------------------------------------------------
public client_connect(id)
{
    HasMasterChief[id] = false

    #if PLAYER_MODEL > 0
        ModelPlayerSet[id] = false
    #endif
}
//----------------------------------------------------------------------------------------------