// AquaMan! - Made By AssKicR & Lazy <[email protected]>
// Some sprite and code tweaks by JTP10181

/* CVARS - copy and paste to shconfig.cfg

//Aquaman
aquaman_level 0
aquaman_armorcost 0            //How much amour each bubble thrower blast uses
aquaman_numbubbles 7            //How many giant killer bubbles
aquaman_bubbledamage 10            //How much damage each bubble does

*/

#include <superheromod>

// GLOBAL VARIABLES
new gHeroID
new const gHeroName[] = "Aquaman"
new bool:gHasAquaman[SH_MAXSLOTS+1]
new bool:gIsBubbling[SH_MAXSLOTS+1]
new gSpriteBubble
new const gSoundBubbleShot[] = "player/pl_swim3.wav"
new const gSoundBubbling[] = "ambience/waterrun.wav"
new const gSoundBubblePain[] = "scientist/scream1.wav"
new gPcvarArmorCost, gPcvarNumBubbles, gPcvarBubbleDamage
//----------------------------------------------------------------------------------------------
public plugin_init()
{
    // Plugin Info
    register_plugin("SUPERHERO Aquaman", SH_VERSION_STR, "AssKicR/Lazy/JTP10181")

    register_dictionary("sh_aquaman.txt")

    // DO NOT EDIT THIS FILE TO CHANGE CVARS, USE THE SHCONFIG.CFG
    new pcvarLevel = register_cvar("aquaman_level", "0")
    gPcvarArmorCost = register_cvar("aquaman_armorcost", "0")
    gPcvarNumBubbles = register_cvar("aquaman_numbubbles", "7")
    gPcvarBubbleDamage = register_cvar("aquaman_bubbledamage", "10")

    // FIRE THE EVENTS TO CREATE THIS SUPERHERO!
    gHeroID = sh_create_hero(gHeroName, pcvarLevel)
    sh_set_hero_info(gHeroID, "Gills & Bubble Attack", "You can Breathe Underwater and use your Bubble Attack")
    sh_set_hero_bind(gHeroID)

    set_task(1.0, "under_the_sea", _, _, _, "b")
}
//----------------------------------------------------------------------------------------------
public plugin_precache()
{
    gSpriteBubble = precache_model("sprites/bubble.spr")
    precache_sound(gSoundBubbleShot)
    precache_sound(gSoundBubbling)
    precache_sound(gSoundBubblePain)
}
//----------------------------------------------------------------------------------------------
public sh_hero_init(id, heroID, mode)
{
    if ( gHeroID != heroID ) return

    gHasAquaman[id] = mode ? true : false

    sh_debug_message(id, 1, "%s %s", gHeroName, mode ? "ADDED" : "DROPPED")
}
//----------------------------------------------------------------------------------------------
public under_the_sea()
{
    if ( !sh_is_active() ) return

    static players[SH_MAXSLOTS], playerCount, player, i
    get_players(players, playerCount, "ah")

    for ( i = 0; i < playerCount; i++ ) {
        player = players[i]
        if ( gHasAquaman[player] ) {
            if ( pev(player, pev_waterlevel) == 3 ) {
                set_pev(player, pev_air_finished, pev(player, pev_air_finished) + 2.0)
            }
        }
    }
}
//----------------------------------------------------------------------------------------------
public sh_hero_key(id, heroID, key)
{
    if ( gHeroID != heroID || sh_is_freezetime() ) return
    if ( !is_user_alive(id) || !gHasAquaman[id] ) return

    if ( key == SH_KEYDOWN ) {
        if ( pev(id, pev_waterlevel) != 3 ) {
            sh_chat_message(id, gHeroID, "[SH] %L", LANG_PLAYER, "SH_AQUAMAN_YM")
            sh_sound_deny(id)
            return
        }

        new armorCost = get_pcvar_num(gPcvarArmorCost)

        // Does it cost to use Bubble Attack?
        if ( armorCost > 0 ) {
            new CsArmorType:armorType
            new userArmor = cs_get_user_armor(id, armorType)

            if ( userArmor < armorCost ) {
                sh_chat_message(id, gHeroID, "[SH] %L", LANG_PLAYER, "SH_AQUAMAN_COST", armorCost, armorCost == 1 ? "" : "s")
                sh_sound_deny(id)
                return
            }

            cs_set_user_armor(id, (userArmor - armorCost), armorType)
        }

        emit_sound(id, CHAN_WEAPON, gSoundBubbleShot, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)

        // Ludwigs flame thrower
        new vec[3], aimvec[3]
        get_user_origin(id, vec)
        get_user_origin(id, aimvec, 2)

        new dist = get_distance(vec, aimvec)
        new speed = 10
        new speed1 = 160
        new speed2 = 350
        new radius = 105

        switch(dist)
        {
            case 0..49: {
                radius = 0
                speed = 5
            }
            case 50..149: {
                speed1 = speed2 = 1
                speed = 5
                radius = 50
            }
            case 150..199: {
                speed1 = speed2 = 1
                speed = 5
                radius = 90
            }
            case 200..249: {
                speed1 = speed2 = 90
                speed = 6
                radius = 90
            }
            case 250..299: {
                speed1 = speed2 = 140
                speed = 7
            }
            case 300..349: {
                speed1 = speed2 = 190
                speed = 7
            }
            case 350..399: {
                speed1 = 150
                speed2 = 240
                speed = 8
            }
            case 400..449: {
                speed1 = 150
                speed2 = 290
                speed = 8
            }
            case 450..499: {
                speed1 = 180
                speed2 = 340
                speed = 9
            }
        }

        new vecdif[3], velocityvec[3], length

        vecdif[0] = aimvec[0]-vec[0]
        vecdif[1] = aimvec[1]-vec[1]
        vecdif[2] = aimvec[2]-vec[2]

        length = sqroot(vecdif[0]*vecdif[0] + vecdif[1]*vecdif[1] + vecdif[2]*vecdif[2])

        // Make sure 0 is not returned so we don't devide by it
        if ( length == 0 ) length++

        velocityvec[0] = vecdif[0]*speed/length
        velocityvec[1] = vecdif[1]*speed/length
        velocityvec[2] = vecdif[2]*speed/length

        new args[6]
        args[0] = vec[0]
        args[1] = vec[1]
        args[2] = vec[2]
        args[3] = velocityvec[0]
        args[4] = velocityvec[1]
        args[5] = velocityvec[2]

        set_task(0.1, "te_spray", _, args, 6, "a", 4)

        check_bubblezone(id, vec, vecdif, length, speed1, speed2, radius)
    }
}
//----------------------------------------------------------------------------------------------
public te_spray(args[])
{
    // Throws a shower of sprites or models
    message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
    write_byte(TE_SPRAY)        // 120
    write_coord(args[0])        // start pos
    write_coord(args[1])
    write_coord(args[2])
    write_coord(args[3])        // velocity
    write_coord(args[4])
    write_coord(args[5])
    write_short(gSpriteBubble)    // spr
    write_byte(4)        // count
    write_byte(100)        // speed
    write_byte(100)        // noise
    write_byte(1)        // rendermode
    message_end()
}
//----------------------------------------------------------------------------------------------
check_bubblezone(id, vec[], vecdif[], length, speed1, speed2, radius)
{
    if ( !is_user_connected(id) ) return

    new tbody, tid
    get_user_aiming(id, tid, tbody, 550)

    if ( !is_user_alive(tid) ) return

    new bool:FFOn = sh_friendlyfire_on()
    new CsTeams:idTeam = cs_get_user_team(id)

    if ( FFOn ) {
        bubble_victim(id, tid)
    }
    else if ( idTeam != cs_get_user_team(tid) ) {
        bubble_victim(id, tid)
    }

    new bubblevec1[3], bubblevec2[3]

    bubblevec1[0] = vecdif[0]*speed1/length + vec[0]
    bubblevec1[1] = vecdif[1]*speed1/length + vec[1]
    bubblevec1[2] = vecdif[2]*speed1/length + vec[2]

    bubblevec2[0] = vecdif[0]*speed2/length + vec[0]
    bubblevec2[1] = vecdif[1]*speed2/length + vec[1]
    bubblevec2[2] = vecdif[2]*speed2/length + vec[2]

    new players[SH_MAXSLOTS], origin[3]
    new playerCount, player
    get_players(players, playerCount, "a")

    for ( new i = 0; i < playerCount; i++ ) {
        player = players[i]

        if ( player != id && (idTeam != cs_get_user_team(player) || FFOn) ) {
            get_user_origin(player, origin)

            if ( get_distance(origin, bubblevec1) < radius ) {
                bubble_victim(id, player)
            }
            else if ( get_distance(origin, bubblevec2) < radius ) {
                bubble_victim(id, player)
            }
        }
    }
}
//----------------------------------------------------------------------------------------------
bubble_victim(id, victim)
{
    if ( gIsBubbling[victim] ) return

    gIsBubbling[victim] = true

    emit_sound(victim, CHAN_ITEM, gSoundBubbling, 0.6, ATTN_NORM, 0, PITCH_NORM)

    new args[2]
    args[0] = id
    args[1] = victim
    set_task(0.3, "drowning", 451, args, 2, "a", get_pcvar_num(gPcvarNumBubbles))
    set_task(0.7, "drown_scream", victim)
    set_task(5.5, "stop_bubble_sound", victim)
}
//----------------------------------------------------------------------------------------------
public drowning(args[])
{
    new id = args[0]
    new victim = args[1]
    new rx, ry, rz, Float:forigin[3]

    rx = random_num(-30, 30)
    ry = random_num(-30, 30)
    rz = random_num(-20, 40)

    pev(victim, pev_origin, forigin)

    // additive sprite, plays 1 cycle
    message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
    write_byte(TE_SPRITE)        // 17
    engfunc(EngFunc_WriteCoord, forigin[0] + rx)    // position
    engfunc(EngFunc_WriteCoord, forigin[1] + ry)
    engfunc(EngFunc_WriteCoord, forigin[2] + rz)
    write_short(gSpriteBubble)    // sprite index
    write_byte(30)            // scale in 0.1's
    write_byte(200)            // brightness
    message_end()

    if ( !is_user_alive(victim) ) return

    if ( !gHasAquaman[victim] ) {
        set_pev(id, pev_air_finished, pev(id, pev_air_finished) - 1.0)
    }

    sh_extra_damage(victim, id, get_pcvar_num(gPcvarBubbleDamage), "bubble attack", _, SH_DMG_NORM, _, false, forigin)
}
//----------------------------------------------------------------------------------------------
public drown_scream(victim)
{
    emit_sound(victim, CHAN_AUTO, gSoundBubblePain, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
}
//----------------------------------------------------------------------------------------------
public stop_bubble_sound(victim)
{
    gIsBubbling[victim] = false
    emit_sound(victim, CHAN_ITEM, gSoundBubbling, 0.6, ATTN_NORM, SND_STOP, PITCH_NORM)
}
//----------------------------------------------------------------------------------------------
public client_connect(id)
{
    gHasAquaman[id] = false
    gIsBubbling[id] = false
}
//----------------------------------------------------------------------------------------------