// POISON IVY! - from Batman. Poison Ivy is immune to all forms of poison and her body manufactures poisons at will.

/* CVARS - copy and paste to shconfig.cfg

//Poison Ivy
poisonivy_level 0
poisonivy_damage 1        //Damage per second from infection
poisonivy_cooldown 0.0    //Seconds before you can infect another player
poisonivy_xpbased 0        //Do they cause more damage each xp level, 0=no 1=yes (def=0)
poisonivy_dpl 1        //Amount of additonal damage per level
poisonivy_maxdpl 0        //Maximum possible damage amount if xpbased (0=no max set)
poisonivy_self 1        //Can users with Poison Ivy be infected, 0=no 1=yes

*/

/*
* v1.2 - vittu - 4/7/05
*      - Removed some useless code and cleaned up.
*      - Added poison HUD icon and a sound to when a user gets poisoned.
*      - Added cooldown cvar and XP based damage possiblity thru cvar.
*      - Added cvar option for not poisoning users with Poison Ivy,
*         since the charater is immune to all poisons.
*
*    Hero orginally created by AssKicR
*/

#include <amxmodx>
#include <superheromod>

// GLOBAL VARIABLES
new gHeroName[]="Poison Ivy"
new bool:gHasPoisonIvyPower[SH_MAXSLOTS+1]
new gIsPoisoned[SH_MAXSLOTS+1][SH_MAXSLOTS+1]
new gPoisonDamage[SH_MAXSLOTS+1]
new gPlayerLevels[SH_MAXSLOTS+1]
new gmsgDamage, gmsgIcon
//----------------------------------------------------------------------------------------------
public plugin_init()
{
    // Plugin Info
    register_plugin("SUPERHERO Poison Ivy", "1.2", "AssKicR/Shadowleader")

    // DO NOT EDIT THIS FILE TO CHANGE CVARS, USE THE SHCONFIG.CFG
    register_cvar("poisonivy_level", "0")
    register_cvar("poisonivy_damage", "0")
    register_cvar("poisonivy_cooldown", "0.0")
    register_cvar("poisonivy_xpbased", "1")
    register_cvar("poisonivy_dpl", "1")
    register_cvar("poisonivy_maxdpl", "0")
    register_cvar("poisonivy_self", "1")

    // FIRE THE EVENT TO CREATE THIS SUPERHERO!
    shCreateHero(gHeroName, "Infect Poison", "Infect the enemy with your Poisoned Bullets or Poisoned Knife", false, "poisonivy_level")

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

    register_event("ResetHUD", "newSpawn", "b")
    register_event("Damage", "poisonivy_damage", "b", "2!0")
    register_event("DeathMsg", "poisonivy_death", "a")

    // LOOP
    set_task(1.0, "poisonivy_loop", 0, "", 0, "b")

    // LEVELS
    register_srvcmd("poisonivy_levels", "poisonivy_levels")
    shRegLevels(gHeroName, "poisonivy_levels")

    gmsgDamage = get_user_msgid("Damage")
    gmsgIcon = get_user_msgid("StatusIcon")
}
//----------------------------------------------------------------------------------------------
public plugin_precache()
{
    precache_sound("hornet/ag_hornethit1.wav")
}
//----------------------------------------------------------------------------------------------
public poisonivy_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 Poison Ivy
    read_argv(2,temp,5)
    new hasPowers = str_to_num(temp)

    gHasPoisonIvyPower[id] = (hasPowers != 0)

    if ( !gHasPoisonIvyPower[id] && is_user_connected(id) ) {
        remove_poison(id)
    }
}
//----------------------------------------------------------------------------------------------
public poisonivy_levels()
{
    new id[5]
    new lev[5]

    read_argv(1,id,4)
    read_argv(2,lev,4)

    gPlayerLevels[str_to_num(id)] = str_to_num(lev)
}
//----------------------------------------------------------------------------------------------
public newSpawn(id)
{
    if ( is_user_alive(id) && shModActive() ) {

        reset_poisoned(id)

        if( gHasPoisonIvyPower[id] ) {

            gPlayerUltimateUsed[id] = false

            // Set damage amount per user
            if (get_cvar_num("poisonivy_xpbased")) {

                new poison = ( (gPlayerLevels[id] - get_cvar_num("poisonivy_level")) * get_cvar_num("poisonivy_dpl") + get_cvar_num("poisonivy_damage") )

                // Set max possible damage if one is set
                if ( get_cvar_num("poisonivy_maxdpl") > 0) {
                    if ( poison > get_cvar_num("poisonivy_maxdpl")) {
                        poison = get_cvar_num("poisonivy_maxdpl")
                    }
                }

                // Stupid checks
                if (poison > 0) {
                    gPoisonDamage[id] = poison
                }
                else if (poison == 0) {
                    gPoisonDamage[id] = get_cvar_num("poisonivy_damage")
                }
                else {
                    gPoisonDamage[id] = 0
                }
            }
            else {
                gPoisonDamage[id] = get_cvar_num("poisonivy_damage")
            }
        }
    }
}
//----------------------------------------------------------------------------------------------
public poisonivy_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 already poisoned no need to set it twice
    if( gIsPoisoned[id][attacker] ) return

    // Can users with Poison Ivy be poisoned
    if ( !get_cvar_num("poisonivy_self") ) {
        if ( gHasPoisonIvyPower[id] ) return
    }

    if ( gHasPoisonIvyPower[attacker] && weapon!=CSW_HEGRENADE && is_user_alive(id) && !gPlayerUltimateUsed[attacker] && id != attacker) {
        // do Poison damage
        emit_sound(id, CHAN_STATIC, "hornet/ag_hornethit1.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)
        gIsPoisoned[id][attacker] = true

        // Set a cooldown if there is one until user can poison another player
        if (get_cvar_float("poisonivy_cooldown") > 0.0) ultimateTimer(attacker, get_cvar_float("poisonivy_cooldown"))
    }
}
//----------------------------------------------------------------------------------------------
public poisonivy_loop()
{
    if (!shModActive()) return

    for ( new attacker = 1; attacker <= SH_MAXSLOTS; attacker++ ) {
        if ( !gHasPoisonIvyPower[attacker] || !is_user_connected(attacker) ) continue

        for ( new id = 1; id <= SH_MAXSLOTS; id++ ) {
            if ( gIsPoisoned[id][attacker] && is_user_alive(id) ) {

                shExtraDamage(id, attacker, gPoisonDamage[attacker], "Poison Infection")

                new origin[3]
                get_user_origin(id, origin)

                // Poison HUD Icon
                message_begin( MSG_ONE, gmsgIcon, {0,0,0}, id)
                write_byte(1) // status (0=hide, 1=show, 2=flash)
                write_string("dmg_poison") // sprite name
                write_byte(0) // red
                write_byte(125) // green
                write_byte(0) // blue
                message_end()

                // Remove poison icon
                set_task(0.3, "remove_poisonicon", id)

                // Show damage, damage origin is self
                message_begin(MSG_ONE, gmsgDamage, {0,0,0}, id)
                write_byte(30) // dmg_save
                write_byte(30) // dmg_take
                write_long((1 << 16)) // visibleDamageBits
                write_coord(origin[0]) // damageOrigin.x
                write_coord(origin[1]) // damageOrigin.y
                write_coord(origin[2]) // damageOrigin.z
                message_end()
            }
        }
    }
}
//----------------------------------------------------------------------------------------------
public client_connect(id)
{
    reset_poisoned(id)
}
//----------------------------------------------------------------------------------------------
public client_disconnected(id)
{
    remove_poison(id)

    reset_poisoned(id)
}
//----------------------------------------------------------------------------------------------
public poisonivy_death()
{
    new id = read_data(2)

    reset_poisoned(id)
}
//----------------------------------------------------------------------------------------------
public reset_poisoned(id)
{
    // Resets poison from all players, id is poisoned player
    for ( new attacker = 1; attacker <= SH_MAXSLOTS; attacker++ ) {
        if ( gIsPoisoned[id][attacker] ) {
            gIsPoisoned[id][attacker] = false
        }
    }
}
//----------------------------------------------------------------------------------------------
public remove_poison(id)
{
    new players[SH_MAXSLOTS], pnum, victim
    get_players(players, pnum, "a")

    // Removes poison on alive players that the id poisoned
    for (new i = 0; i < pnum; i++) {
        victim = players[i]
        if ( gIsPoisoned[victim][id] ) {
            gIsPoisoned[victim][id] = false
        }
    }
}
//----------------------------------------------------------------------------------------------
public remove_poisonicon(id)
{
    if ( !is_user_connected(id) ) return

    // Poison HUD Icon, reset to none
    message_begin(MSG_ONE, gmsgIcon, {0,0,0}, id)
    write_byte(0) // status (0=hide, 1=show, 2=flash)
    write_string("dmg_poison") // sprite name
    write_byte(0) // red
    write_byte(0) // green
    write_byte(0) // blue
    message_end()
}
//----------------------------------------------------------------------------------------------