Discord sunucumuz açılmıştır, hepinizi bekleriz
https://discord.gg/XcHzrBFDag
TÜRKÇE DUBLAJ HALF LİFE İNDİR
Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Counter Strike 1.6 Ultimate Parachute Gelişmiş Paraşüt Sistemi
#1
[Resim: 6Hj7mYF.jpeg]


🪂 HLPlayer.com Ultimate Parachute v1.0
Gelişmiş Paraşüt Sistemi
Coder: Y4S!N61
Platform: Counter-Strike 1.6 / AMX Mod X
Versiyon: 1.0

📌 Plugin Hakkında
HLPlayer.com Ultimate Parachute, Counter-Strike 1.6 sunucuları için geliştirilmiş gelişmiş ve tamamen ayarlanabilir bir paraşüt sistemidir.
Klasik paraşüt pluginlerinden farklı olarak oyunculara menü üzerinden birçok özelliği değiştirme imkanı sağlar.
Oyuncular;
  • Paraşüt açılma modunu
  • Düşüş hızını
  • Paraşüt modelini
  • Paraşüt iz efektini
  • İz rengini
  • İz uzunluğunu
  • Kamera modunu
kendileri seçebilir.
Tüm ayarlar nVault sistemi ile kayıt edilir ve oyuncu tekrar girdiğinde aynı ayarlar yüklenir.

⚙ Özellikler
🪂 3 Farklı Paraşüt Açma Sistemi
  • Basılı Tut (E tuşu)
  • Tıkla Aç / Kapat
  • Otomatik Açılma (Auto Deploy)

⚡ Ayarlanabilir Düşüş Hızı
Config üzerinden sınırsız hız eklenebilir.
Örnek:
Kod:
[speeds]
-100 "Normal"
-60 "Yavaş"
-20 "Ultra Slow"

🎥 Kamera Sistemi
Paraşüt kullanırken:
    1. şahıs
    1. şahıs
kamera seçilebilir.

🎨 Paraşüt Model Sistemi
Config üzerinden sınırsız model eklenebilir.
Kod:
[models]
models/parachute1.mdl "Classic"
models/parachute2.mdl "Military"
models/parachute3.mdl "VIP"

🌈 Trail (İz) Efekt Sistemi
Paraşüt kullanırken oyuncunun arkasında görsel iz efekti oluşur.
Configten farklı sprite izleri eklenebilir.
Kod:
[trails]
sprites/smoke.spr "Smoke"
sprites/laser.spr "Laser"

🎨 İz Renk Sistemi
Kod:
[trail_colors]
255 0 0 "Kırmızı"
0 255 0 "Yeşil"
0 0 255 "Mavi"
255 255 0 "Sarı"

📏 İz Uzunluğu
Kod:
[trail_lengths]
10 "Kısa"
30 "Orta"
60 "Uzun"

🔊 Paraşüt Açılma Sesi
Configten özel ses eklenebilir.
Kod:
deploy_sound parachute/deploy.wav

💾 Oyuncu Ayarlarını Kaydetme
Plugin nVault kullanır.
Oyuncunun şu ayarları kayıt edilir:
  • Açılma modu
  • Düşüş hızı
  • Kamera modu
  • Model
  • Trail
  • Trail rengi
  • Trail uzunluğu

🔐 Yetki Sistemi
Admin flag ile paraşüt kullanımı sınırlandırılabilir.
Kod:
access_flags "b"

👥 Takım Yetkisi
Sadece belirli takımlar kullanabilir.
Kod:
access_team_tt 1
access_team_ct 1

🔫 Paraşütte Silah Kullanımı
Paraşüt açıkken silah kullanımı kapatılabilir.
Kod:
weapon_usage 0


🔢 Round Başına Kullanım Limiti
Kod:
deploys_per_round 3

🕹 Oyuncu Komutu
Kod:
/parasut
Oyuncu paraşüt ayar menüsünü açar.

📂 Config Dosyası
Kod:
addons/amxmodx/configs/ultimate_parachute.ini
Tüm ayarlar buradan yapılır.


📦 Kurulum

1️⃣
Kod:
addons/amxmodx/plugins

2️⃣
Kod:
plugins.ini
içine ekleyin
Kod:
ultimate_parachute.amxx

3️⃣ Sunucuyu restart edin.


İNDİRMEK İÇİN TIKLA


📊 Uyumlu Sistemler
✔ ReHLDS
✔ ReGameDLL
✔ AMX Mod X 1.8+
✔ Steam / NoSteam


👨‍💻 Geliştirici ; Y4S!N61

⭐ Not

Plugin tamamen config tabanlıdır ve sunucular için maksimum esneklik sağlar.
Forumlarda paylaşabilirsiniz ancak coder bilgisi silinmemelidir.

🎮 Keyifli Oyunlar!


Kod:
/*
    Gelistirilmis, genis ozelliklere ve esnek ayarlara sahip parasut sistemi.
    Coder: Y4S!N61
*/

#include <amxmodx>
#include <fakemeta>
#include <engine>
#include <fun>
#include <hamsandwich>
#include <nvault>
#include <cstrike>

#pragma semicolon 1

#define PLUGIN      "HLPlayer.com Ultimate Parachute"
#define VERSION     "1.0"
#define AUTHOR      "Y4S!N61"

#define cm(%0)      ( sizeof(%0) - 1 )

const XO_PLAYER            = 5;
const m_flFallVelocity     = 251;

#define MAX_SPEEDS   32
#define MAX_MODELS   64

#define MAX_TRAILS         64
#define MAX_TRAIL_COLORS   32
#define MAX_TRAIL_LENGTHS  32
enum
{
    DEPLOY_HOLD = 0,
    DEPLOY_TAP  = 1,
    DEPLOY_AUTO = 2
};

new const g_szDeployModeName[3][] = { "Basili Tut", "Tikla (tekrar - kapat)", "Otomatik (tikla - kapat)" };

new const PARA_CLASS[] = "parachute";

#define TE_BEAMFOLLOW 22
#define TE_KILLBEAM   99
new g_szCfgPath[256];
new g_szAccessFlags[32];
new g_iAccessBits;

new g_iAccessTeamTT;
new g_iAccessTeamCT;

new g_iWeaponUsage;
new g_iDeployModeAccess;
new g_iDeployModeDefault;

new g_iFallSpeedAccess;
new g_szFallSpeedDefault[32];

new g_iThirdAccess;
new g_iThirdDefault;

new g_iModelAccess;
new g_szModelDefault[128];

new Float:g_flAutoThreshold;
new g_iDeploysPerRound;
new g_szDeploySound[128];

new g_iSpeedsNum;
new g_szSpeedName[MAX_SPEEDS][32];
new Float:g_flSpeedValue[MAX_SPEEDS];

new g_iModelsNum;
new g_szModelPath[MAX_MODELS][128];
new g_szModelName[MAX_MODELS][48];

new g_iTrailAccess;
new g_szTrailDefault[128];

new g_iTrailColorAccess;
new g_szTrailColorDefault[32];

new g_iTrailLengthAccess;
new g_szTrailLengthDefault[16];

new g_iTrailsNum;
new g_szTrailPath[MAX_TRAILS][128];
new g_szTrailName[MAX_TRAILS][48];
new g_iTrailSpriteIdx[MAX_TRAILS];

new g_iTrailColorsNum;
new g_szTrailColorName[MAX_TRAIL_COLORS][48];
new g_iTrailColorRGB[MAX_TRAIL_COLORS][3];

new g_iTrailLengthsNum;
new g_szTrailLengthName[MAX_TRAIL_LENGTHS][48];
new g_iTrailLengthVal[MAX_TRAIL_LENGTHS];

new g_iDefaultTrailIndex;
new g_iDefaultTrailColorIndex;
new g_iDefaultTrailLengthIndex;

new g_iTrailWidth = 10;

new g_iTrailIndex[33];
new g_iTrailColorIndex[33];
new g_iTrailLengthIndex[33];

new g_iTrailMenuPage[33];
new g_iTrailColorMenuPage[33];
new g_iTrailLengthMenuPage[33];

new bool:g_bTrailActive[33];

new g_iDefaultSpeedIndex;
new g_iDefaultModelIndex;

new g_iVault;

new g_iParaEnt[33];
new bool:g_bParaDeployed[33];
new g_iDeployMode[33];
new g_iSpeedIndex[33];
new bool:g_bThird[33];
new g_iModelIndex[33];
new g_iModelMenuPage[33];

new g_iLastWeapon[33];

new g_iDeploysUsed[33];

public plugin_precache()
{
    precache_model("models/rpgrocket.mdl");
    BuildConfigPath();
    LoadConfig(true);
}

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR);

    register_clcmd("say /parasut", "Cmd_Menu");
    register_clcmd("say_team /parasut", "Cmd_Menu");

    RegisterHam(Ham_Player_PreThink, "player", "OnPreThink", 0);
    RegisterHam(Ham_Spawn, "player", "OnSpawnPost", 1);
    RegisterHam(Ham_Killed, "player", "OnKilledPost", 1);

    register_logevent("OnRoundStart", 2, "1=Round_Start");
}

public plugin_cfg()
{
    BuildConfigPath();
    LoadConfig(false);

    g_iVault = nvault_open("ultimate_parachute");
    if (g_iVault == INVALID_HANDLE)
        set_fail_state("Error opening nVault (ultimate_parachute)");
}

public plugin_end()
{
    if (g_iVault != INVALID_HANDLE)
        nvault_close(g_iVault);
}

public OnSpawnPost(id)
{
    if(!is_user_connected(id)) return;

    RemoveParachute(id, true);

    g_iDeploysUsed[id] = 0;

    LoadPlayerData(id);
}

public OnKilledPost(victim, attacker, shouldgib)
{
    if(!is_user_connected(victim)) return;
    RemoveParachute(victim, true);
}

public OnRoundStart()
{
    for(new id=1; id<=32; id++)
    {
        g_iDeploysUsed[id] = 0;
        if(is_user_connected(id))
            RemoveParachute(id, true);
    }
}

public client_putinserver(id)
{
    ResetPlayerState(id);
}

public client_disconnected(id)
{
    SavePlayerData(id);
    ResetPlayerState(id);
}

public OnPreThink(id)
{
    if(!is_user_alive(id))
        return;

    if(!HasParachuteAccess(id))
    {
        RemoveParachute(id, false);
        return;
    }

    if(pev(id, pev_movetype) == MOVETYPE_FLY)
    {
        RemoveParachute(id, false);
        return;
    }

    new buttons = pev(id, pev_button);
    new oldbuttons = pev(id, pev_oldbuttons);
    new flags = pev(id, pev_flags);

    static Float:vel[3];
    pev(id, pev_velocity, vel);

    new bool:bDescending = (vel[2] < 0.0);

    switch(g_iDeployMode[id])
    {
        case DEPLOY_HOLD:
        {
            if( (buttons & IN_USE) && !(flags & FL_ONGROUND) && bDescending )
            {
                    if(!g_bParaDeployed[id])
                    {
                        if(!TryStartDeploy(id))
                        {
                            RemoveParachute(id, false);
                            return;
                        }
                        g_bParaDeployed[id] = true;
                    StartTrailIfNeeded(id);
                    }

                    EnsureEntity(id);
                    ApplyParachute(id, vel);
            }
            else
            {
                RemoveParachute(id, false);
            }
        }
        case DEPLOY_TAP:
        {
            if( (buttons & IN_USE) && !(oldbuttons & IN_USE) && !(flags & FL_ONGROUND) && bDescending )
            {
                if(!g_bParaDeployed[id])
                {
                        if(!TryStartDeploy(id))
                            return;

                    EnsureEntity(id);
                    g_bParaDeployed[id] = true;
                    StartTrailIfNeeded(id);
                }
                else
                {
                    RemoveParachute(id, false);
                }
            }

            if(g_bParaDeployed[id] && !(flags & FL_ONGROUND) && bDescending)
            {
                EnsureEntity(id);
                ApplyParachute(id, vel);
            }
            else if(flags & FL_ONGROUND)
            {
                RemoveParachute(id, false);
            }
        }
        case DEPLOY_AUTO:
        {
            static Float:fallvel;
            fallvel = get_pdata_float(id, m_flFallVelocity, XO_PLAYER);

                if(!g_bParaDeployed[id] && bDescending && fallvel >= g_flAutoThreshold && !(flags & FL_ONGROUND))
            {
                    if(!TryStartDeploy(id))
                        return;
                EnsureEntity(id);
                g_bParaDeployed[id] = true;
                StartTrailIfNeeded(id);
            }

            if(g_bParaDeployed[id] && !(flags & FL_ONGROUND) && bDescending)
            {
                EnsureEntity(id);
                ApplyParachute(id, vel);
            }
            else if(flags & FL_ONGROUND)
            {
                RemoveParachute(id, false);
            }

            if(g_bParaDeployed[id] && (buttons & IN_USE) && !(oldbuttons & IN_USE) && !(flags & FL_ONGROUND))
            {
                RemoveParachute(id, false);
            }
        }
    }

    if(!(buttons & IN_USE) && (oldbuttons & IN_USE))
    {
        RestoreGravityIfNeeded(id);
    }
}

public Cmd_Menu(id)
{
    if(!is_user_connected(id)) return PLUGIN_HANDLED;

    if(!HasParachuteAccess(id))
    {
        client_print(id, print_chat, "[Ultimate Parachute] Parasut yetkiniz yok.");
        return PLUGIN_HANDLED;
    }

    if(g_bParaDeployed[id] || g_iParaEnt[id] > 0)
        return PLUGIN_HANDLED;

    new menu = menu_create("Parasut Ayarlari", "Menu_Handler");

    new sz[192];

    if(g_iDeployModeAccess)
    {
        formatex(sz, cm(sz), "Acilis Modu: %s", g_szDeployModeName[g_iDeployMode[id]]);
        menu_additem(menu, sz, "0");
    }
    else
    {
        formatex(sz, cm(sz), "Acilis Modu: d%s", g_szDeployModeName[g_iDeployMode[id]]);
        menu_additem(menu, sz, "0");
    }

    if(g_iThirdAccess)
    {
        formatex(sz, cm(sz), "Gorunus: %s", g_bThird[id] ? "3. Sahis" : "1. Sahis");
        menu_additem(menu, sz, "1");
    }
    else
    {
        formatex(sz, cm(sz), "Gorunus: d%s", g_bThird[id] ? "3. Sahis" : "1. Sahis");
        menu_additem(menu, sz, "1");
    }

    if(g_iFallSpeedAccess && g_iSpeedsNum > 0)
    {
        formatex(sz, cm(sz), "Dusus Hizi: %s", g_szSpeedName[g_iSpeedIndex[id]]);
        menu_additem(menu, sz, "2");
    }
    else
    {
        formatex(sz, cm(sz), "Dusus Hizi: d%s", (g_iSpeedsNum > 0) ? g_szSpeedName[g_iSpeedIndex[id]] : "liste yok");
        menu_additem(menu, sz, "2");
    }

    if(g_iModelsNum > 0)
    {
        new const szRandom[] = "Degisen model";
        if(g_iModelIndex[id] == -1)
            formatex(sz, cm(sz), "Model: %s", szRandom);
        else
            formatex(sz, cm(sz), "Model: %s", g_szModelName[g_iModelIndex[id]]);

        if(!g_iModelAccess)
            replace(sz, cm(sz), "y", "d");

        menu_additem(menu, sz, "3");
    }
    else
    {
        formatex(sz, cm(sz), "Model: dliste yok");
        menu_additem(menu, sz, "3");
    }

    if(g_iTrailsNum > 0)
    {
        new const szRandomTrail[] = "Degisen iz";
        if(g_iTrailIndex[id] == -1)
            formatex(sz, cm(sz), "Iz: %s", szRandomTrail);
        else
            formatex(sz, cm(sz), "Iz: %s", g_szTrailName[g_iTrailIndex[id]]);

        if(!g_iTrailAccess)
            replace(sz, cm(sz), "y", "d");

        menu_additem(menu, sz, "4");
    }
    else
    {
        formatex(sz, cm(sz), "Iz: dliste yok");
        menu_additem(menu, sz, "4");
    }

    if(g_iTrailColorsNum > 0)
    {
        new const szRandomColor[] = "Rastgele";
        if(g_iTrailColorIndex[id] == -1)
            formatex(sz, cm(sz), "Iz Rengi: %s", szRandomColor);
        else
            formatex(sz, cm(sz), "Iz Rengi: %s", g_szTrailColorName[g_iTrailColorIndex[id]]);

        if(!g_iTrailColorAccess || !g_iTrailAccess)
            replace(sz, cm(sz), "y", "d");

        menu_additem(menu, sz, "5");
    }
    else
    {
        formatex(sz, cm(sz), "Iz Rengi: dliste yok");
        menu_additem(menu, sz, "5");
    }

    if(g_iTrailLengthsNum > 0)
    {
        new const szRandomLen[] = "Rastgele";
        if(g_iTrailLengthIndex[id] == -1)
            formatex(sz, cm(sz), "Iz Uzunlugu: %s", szRandomLen);
        else
            formatex(sz, cm(sz), "Iz Uzunlugu: %s", g_szTrailLengthName[g_iTrailLengthIndex[id]]);

        if(!g_iTrailLengthAccess || !g_iTrailAccess)
            replace(sz, cm(sz), "y", "d");

        menu_additem(menu, sz, "6");
    }
    else
    {
        formatex(sz, cm(sz), "Iz Uzunlugu: dliste yok");
        menu_additem(menu, sz, "6");
    }

    menu_setprop(menu, MPROP_EXIT, MEXIT_ALL);
    menu_display(id, menu);

    return PLUGIN_HANDLED;
}

public Menu_Handler(id, menu, item)
{
    if(item == MENU_EXIT)
    {
        menu_destroy(menu);
        SavePlayerData(id);
        return PLUGIN_HANDLED;
    }

    new info[8], access, callback;
    menu_item_getinfo(menu, item, access, info, cm(info), _, _, callback);
    new key = str_to_num(info);

    switch(key)
    {
        case 0:
        {
            if(g_iDeployModeAccess)
            {
                g_iDeployMode[id]++;
                if(g_iDeployMode[id] > DEPLOY_AUTO) g_iDeployMode[id] = DEPLOY_HOLD;
            }
        }
        case 1:
        {
            if(g_iThirdAccess)
            {
                g_bThird[id] = !g_bThird[id];
                if(!g_bThird[id]) set_view(id, CAMERA_NONE);
            }
        }
        case 2:
        {
            if(g_iFallSpeedAccess && g_iSpeedsNum > 0)
            {
                g_iSpeedIndex[id]++;
                if(g_iSpeedIndex[id] >= g_iSpeedsNum) g_iSpeedIndex[id] = 0;
            }
        }
        case 3:
        {
            if(g_iModelAccess && g_iModelsNum > 0)
            {
                menu_destroy(menu);
                ShowModelMenu(id, 0);
                return PLUGIN_HANDLED;
            }
        }
        case 4:
        {
            if(g_iTrailAccess && g_iTrailsNum > 0)
            {
                menu_destroy(menu);
                ShowTrailMenu(id, 0);
                return PLUGIN_HANDLED;
            }
        }
        case 5:
        {
            if(g_iTrailAccess && g_iTrailColorAccess && g_iTrailColorsNum > 0)
            {
                menu_destroy(menu);
                ShowTrailColorMenu(id, 0);
                return PLUGIN_HANDLED;
            }
        }
        case 6:
        {
            if(g_iTrailAccess && g_iTrailLengthAccess && g_iTrailLengthsNum > 0)
            {
                menu_destroy(menu);
                ShowTrailLengthMenu(id, 0);
                return PLUGIN_HANDLED;
            }
        }
    }

    menu_destroy(menu);
    Cmd_Menu(id);

    SavePlayerData(id);
    return PLUGIN_HANDLED;
}

stock ShowModelMenu(id, page)
{
    if(!is_user_connected(id)) return;

    new const perPage = 7;

    new totalItems = g_iModelsNum + 1;
    new maxPage = 0;
    if(totalItems > 0)
        maxPage = (totalItems - 1) / perPage;

    if(page < 0) page = 0;
    if(page > maxPage) page = maxPage;

    g_iModelMenuPage[id] = page;

    new menu = menu_create("Model Secimi", "ModelMenu_Handler");

    menu_additem(menu, "Degisen model", "R");

    new sz[96], info[12];
    for(new i = 0; i < g_iModelsNum; i++)
    {
        formatex(sz, charsmax(sz), "%s", g_szModelName[i]);
        formatex(info, charsmax(info), "%d", i);
        menu_additem(menu, sz, info);
    }

    menu_setprop(menu, MPROP_PERPAGE, perPage);
    menu_setprop(menu, MPROP_BACKNAME, "Geri");
    menu_setprop(menu, MPROP_NEXTNAME, "Ileri");
    menu_setprop(menu, MPROP_EXITNAME, "Cikis");

    menu_display(id, menu, page);
}

public ModelMenu_Handler(id, menu, item)
{
    if(item == MENU_EXIT)
    {
        menu_destroy(menu);
        Cmd_Menu(id);
        return PLUGIN_HANDLED;
    }

    if(item == MENU_BACK)
    {
        menu_destroy(menu);
        ShowModelMenu(id, g_iModelMenuPage[id] - 1);
        return PLUGIN_HANDLED;
    }
    if(item == MENU_MORE)
    {
        menu_destroy(menu);
        ShowModelMenu(id, g_iModelMenuPage[id] + 1);
        return PLUGIN_HANDLED;
    }

    new info[12], access, callback;
    menu_item_getinfo(menu, item, access, info, charsmax(info), _, _, callback);

    if(info[0] == 'R')
    {
        g_iModelIndex[id] = -1;
    }
    else
    {
        new idx = str_to_num(info);
        if(idx >= 0 && idx < g_iModelsNum)
            g_iModelIndex[id] = idx;
    }

    menu_destroy(menu);
    SavePlayerData(id);
    Cmd_Menu(id);

    return PLUGIN_HANDLED;
}

stock bool:TryStartDeploy(id)
{
    if(g_iDeploysPerRound > 0 && g_iDeploysUsed[id] >= g_iDeploysPerRound)
        return false;

    g_iDeploysUsed[id]++;

    if(g_szDeploySound[0])
        emit_sound(id, CHAN_ITEM, g_szDeploySound, 1.0, ATTN_NORM, 0, PITCH_NORM);

    if(!g_iWeaponUsage)
        DenyWeapons(id);

    if(g_bThird[id])
        set_view(id, CAMERA_3RDPERSON);

    set_pev(id, pev_gravity, 0.1);

    return true;
}

stock EnsureEntity(id)
{
    if(g_iParaEnt[id] > 0 && is_valid_ent(g_iParaEnt[id]))
        return;

    new ent = create_entity("info_target");
    if(ent <= 0) return;

    entity_set_string(ent, EV_SZ_classname, PARA_CLASS);

    if(g_iModelsNum > 0)
    {
        new mdlIndex = g_iModelIndex[id];
        if(mdlIndex < 0) mdlIndex = random_num(0, g_iModelsNum - 1);
        entity_set_model(ent, g_szModelPath[mdlIndex]);
    }

    entity_set_int(ent, EV_INT_movetype, MOVETYPE_FOLLOW);
    entity_set_int(ent, EV_INT_solid, SOLID_NOT);
    entity_set_edict(ent, EV_ENT_aiment, id);
    entity_set_edict(ent, EV_ENT_owner, id);

    entity_set_int(ent, EV_INT_sequence, 0);
    entity_set_int(ent, EV_INT_gaitsequence, 1);
    entity_set_float(ent, EV_FL_frame, 0.0);
    entity_set_float(ent, EV_FL_fuser1, 0.0);

    g_iParaEnt[id] = ent;
}

stock ShowTrailMenu(id, page)
{
    if(!is_user_connected(id)) return;

    new const perPage = 7;

    new totalItems = g_iTrailsNum + 1;
    new maxPage = 0;
    if(totalItems > 0)
        maxPage = (totalItems - 1) / perPage;

    if(page < 0) page = 0;
    if(page > maxPage) page = maxPage;

    g_iTrailMenuPage[id] = page;

    new menu = menu_create("Iz Secimi", "TrailMenu_Handler");

    menu_additem(menu, "Degisen iz", "R");

    new sz[96], info[12];
    for(new i = 0; i < g_iTrailsNum; i++)
    {
        formatex(sz, charsmax(sz), "%s", g_szTrailName[i]);
        formatex(info, charsmax(info), "%d", i);
        menu_additem(menu, sz, info);
    }

    menu_setprop(menu, MPROP_PERPAGE, perPage);
    menu_setprop(menu, MPROP_BACKNAME, "Geri");
    menu_setprop(menu, MPROP_NEXTNAME, "Ileri");
    menu_setprop(menu, MPROP_EXITNAME, "Cikis");

    menu_display(id, menu, page);
}

public TrailMenu_Handler(id, menu, item)
{
    if(item == MENU_EXIT)
    {
        menu_destroy(menu);
        Cmd_Menu(id);
        return PLUGIN_HANDLED;
    }

    if(item == MENU_BACK)
    {
        menu_destroy(menu);
        ShowTrailMenu(id, g_iTrailMenuPage[id] - 1);
        return PLUGIN_HANDLED;
    }
    if(item == MENU_MORE)
    {
        menu_destroy(menu);
        ShowTrailMenu(id, g_iTrailMenuPage[id] + 1);
        return PLUGIN_HANDLED;
    }

    new info[12], access, callback;
    menu_item_getinfo(menu, item, access, info, charsmax(info), _, _, callback);

    if(info[0] == 'R')
    {
        g_iTrailIndex[id] = -1;
    }
    else
    {
        new idx = str_to_num(info);
        if(idx >= 0 && idx < g_iTrailsNum)
            g_iTrailIndex[id] = idx;
    }

    menu_destroy(menu);
    SavePlayerData(id);
    Cmd_Menu(id);

    return PLUGIN_HANDLED;
}

stock ShowTrailColorMenu(id, page)
{
    if(!is_user_connected(id)) return;

    new const perPage = 7;

    new totalItems = g_iTrailColorsNum + 1;
    new maxPage = 0;
    if(totalItems > 0)
        maxPage = (totalItems - 1) / perPage;

    if(page < 0) page = 0;
    if(page > maxPage) page = maxPage;

    g_iTrailColorMenuPage[id] = page;

    new menu = menu_create("Iz Rengi Secimi", "TrailColorMenu_Handler");

    menu_additem(menu, "Rastgele", "R");

    new sz[96], info[12];
    for(new i = 0; i < g_iTrailColorsNum; i++)
    {
        formatex(sz, charsmax(sz), "%s", g_szTrailColorName[i]);
        formatex(info, charsmax(info), "%d", i);
        menu_additem(menu, sz, info);
    }

    menu_setprop(menu, MPROP_PERPAGE, perPage);
    menu_setprop(menu, MPROP_BACKNAME, "Geri");
    menu_setprop(menu, MPROP_NEXTNAME, "Ileri");
    menu_setprop(menu, MPROP_EXITNAME, "Cikis");

    menu_display(id, menu, page);
}

public TrailColorMenu_Handler(id, menu, item)
{
    if(item == MENU_EXIT)
    {
        menu_destroy(menu);
        Cmd_Menu(id);
        return PLUGIN_HANDLED;
    }

    if(item == MENU_BACK)
    {
        menu_destroy(menu);
        ShowTrailColorMenu(id, g_iTrailColorMenuPage[id] - 1);
        return PLUGIN_HANDLED;
    }
    if(item == MENU_MORE)
    {
        menu_destroy(menu);
        ShowTrailColorMenu(id, g_iTrailColorMenuPage[id] + 1);
        return PLUGIN_HANDLED;
    }

    new info[12], access, callback;
    menu_item_getinfo(menu, item, access, info, charsmax(info), _, _, callback);

    if(info[0] == 'R')
    {
        g_iTrailColorIndex[id] = -1;
    }
    else
    {
        new idx = str_to_num(info);
        if(idx >= 0 && idx < g_iTrailColorsNum)
            g_iTrailColorIndex[id] = idx;
    }

    menu_destroy(menu);
    SavePlayerData(id);
    Cmd_Menu(id);

    return PLUGIN_HANDLED;
}


stock ShowTrailLengthMenu(id, page)
{
    if(!is_user_connected(id)) return;

    new const perPage = 7;

    new totalItems = g_iTrailLengthsNum + 1;
    new maxPage = 0;
    if(totalItems > 0)
        maxPage = (totalItems - 1) / perPage;

    if(page < 0) page = 0;
    if(page > maxPage) page = maxPage;

    g_iTrailLengthMenuPage[id] = page;

    new menu = menu_create("Iz Uzunlugu Secimi", "TrailLengthMenu_Handler");

    menu_additem(menu, "Rastgele", "R");

    new sz[96], info[12];
    for(new i = 0; i < g_iTrailLengthsNum; i++)
    {
        formatex(sz, charsmax(sz), "%s", g_szTrailLengthName[i]);
        formatex(info, charsmax(info), "%d", i);
        menu_additem(menu, sz, info);
    }

    menu_setprop(menu, MPROP_PERPAGE, perPage);
    menu_setprop(menu, MPROP_BACKNAME, "Geri");
    menu_setprop(menu, MPROP_NEXTNAME, "Ileri");
    menu_setprop(menu, MPROP_EXITNAME, "Cikis");

    menu_display(id, menu, page);
}

public TrailLengthMenu_Handler(id, menu, item)
{
    if(item == MENU_EXIT)
    {
        menu_destroy(menu);
        Cmd_Menu(id);
        return PLUGIN_HANDLED;
    }

    if(item == MENU_BACK)
    {
        menu_destroy(menu);
        ShowTrailLengthMenu(id, g_iTrailLengthMenuPage[id] - 1);
        return PLUGIN_HANDLED;
    }
    if(item == MENU_MORE)
    {
        menu_destroy(menu);
        ShowTrailLengthMenu(id, g_iTrailLengthMenuPage[id] + 1);
        return PLUGIN_HANDLED;
    }

    new info[12], access, callback;
    menu_item_getinfo(menu, item, access, info, charsmax(info), _, _, callback);

    if(info[0] == 'R')
    {
        g_iTrailLengthIndex[id] = -1;
    }
    else
    {
        new idx = str_to_num(info);
        if(idx >= 0 && idx < g_iTrailLengthsNum)
            g_iTrailLengthIndex[id] = idx;
    }

    menu_destroy(menu);
    SavePlayerData(id);
    Cmd_Menu(id);

    return PLUGIN_HANDLED;
}

stock ApplyParachute(id, Float:vel[3])
{
    set_pev(id, pev_gravity, 0.1);

    if(g_iSpeedsNum > 0)
    {
        new i = g_iSpeedIndex[id];
        new Float:target = g_flSpeedValue[i];

        vel[2] = (vel[2] + 40.0 < target) ? (vel[2] + 40.0) : target;
        set_pev(id, pev_velocity, vel);
    }

    new ent = g_iParaEnt[id];
    if(ent > 0 && is_valid_ent(ent))
    {
        new Float:frame;

        if(entity_get_int(ent, EV_INT_sequence) == 0)
        {
            frame = entity_get_float(ent, EV_FL_fuser1) + 1.0;
            entity_set_float(ent, EV_FL_fuser1, frame);
            entity_set_float(ent, EV_FL_frame, frame);

            if(frame > 100.0)
            {
                entity_set_float(ent, EV_FL_animtime, 0.0);
                entity_set_float(ent, EV_FL_framerate, 0.4);
                entity_set_int(ent, EV_INT_sequence, 1);
                entity_set_int(ent, EV_INT_gaitsequence, 1);
                entity_set_float(ent, EV_FL_frame, 0.0);
                entity_set_float(ent, EV_FL_fuser1, 0.0);
            }
        }
    }
}

stock RemoveParachute(id, bool:bForce)
{
    if(g_iParaEnt[id] > 0)
    {
        if(is_valid_ent(g_iParaEnt[id]))
            remove_entity(g_iParaEnt[id]);
        g_iParaEnt[id] = 0;
    }

    if(g_bParaDeployed[id] || bForce)
    {
        g_bParaDeployed[id] = false;

        KillTrail(id);

        set_view(id, CAMERA_NONE);

        if(!g_iWeaponUsage)
            RestoreWeapon(id);

        RestoreGravityIfNeeded(id);
    }
}

stock RestoreGravityIfNeeded(id)
{
    if(!is_user_alive(id)) return;

    static Float:gr;
    pev(id, pev_gravity, gr);

    if(gr == 0.1)
        set_pev(id, pev_gravity, 1.0);
}

stock KillTrail(id)
{
    if(!g_bTrailActive[id])
        return;

    message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
    write_byte(TE_KILLBEAM);
    write_short(id);
    message_end();

    g_bTrailActive[id] = false;
}

stock StartTrailIfNeeded(id)
{
    if(!g_bParaDeployed[id])
        return;

    if(!g_iTrailAccess || g_iTrailsNum <= 0 || g_iTrailLengthsNum <= 0)
        return;

    new iLenIdx = g_iTrailLengthIndex[id];
    if(iLenIdx == -1 && g_iTrailLengthsNum > 0)
        iLenIdx = random_num(0, g_iTrailLengthsNum - 1);

    if(iLenIdx < 0 || iLenIdx >= g_iTrailLengthsNum)
        return;

    new life = g_iTrailLengthVal[iLenIdx];
    if(life <= 0)
    {
        KillTrail(id);
        return;
    }

    new iTrailIdx = g_iTrailIndex[id];
    if(iTrailIdx == -1 && g_iTrailsNum > 0)
        iTrailIdx = random_num(0, g_iTrailsNum - 1);

    if(iTrailIdx < 0 || iTrailIdx >= g_iTrailsNum)
        return;

    new sprite = g_iTrailSpriteIdx[iTrailIdx];
    if(sprite <= 0)
        return;

    new iColorIdx = g_iTrailColorIndex[id];
    if(iColorIdx == -1 && g_iTrailColorsNum > 0)
        iColorIdx = random_num(0, g_iTrailColorsNum - 1);

    new r = 255, g = 255, b = 255;
    if(iColorIdx >= 0 && iColorIdx < g_iTrailColorsNum)
    {
        r = g_iTrailColorRGB[iColorIdx][0];
        g = g_iTrailColorRGB[iColorIdx][1];
        b = g_iTrailColorRGB[iColorIdx][2];
    }

    KillTrail(id);

    message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
    write_byte(TE_BEAMFOLLOW);
    write_short(id);
    write_short(sprite);
    write_byte(clamp(life, 0, 255));
    write_byte(g_iTrailWidth);
    write_byte(r);
    write_byte(g);
    write_byte(b);
    write_byte(255);
    message_end();

    g_bTrailActive[id] = true;
}

stock DenyWeapons(id)
{
    new weapon = get_user_weapon(id);
    if(weapon != CSW_KNIFE)
    {
        g_iLastWeapon[id] = weapon;
        engclient_cmd(id, "weapon_knife");
    }

    new buttons = pev(id, pev_button);
    buttons &= ~IN_ATTACK;
    buttons &= ~IN_ATTACK2;
    set_pev(id, pev_button, buttons);
}

stock RestoreWeapon(id)
{
    if(g_iLastWeapon[id] <= 0) return;

    new szWpn[32];
    get_weaponname(g_iLastWeapon[id], szWpn, cm(szWpn));
    engclient_cmd(id, szWpn);
    g_iTrailIndex[id] = (g_iTrailsNum > 0) ? g_iDefaultTrailIndex : 0;
    g_iTrailColorIndex[id] = (g_iTrailColorsNum > 0) ? g_iDefaultTrailColorIndex : 0;
    g_iTrailLengthIndex[id] = (g_iTrailLengthsNum > 0) ? g_iDefaultTrailLengthIndex : 0;
    g_bTrailActive[id] = false;

g_iLastWeapon[id] = 0;
}

stock BuildConfigPath()
{
    new cfgdir[128];
    get_localinfo("amxx_configsdir", cfgdir, cm(cfgdir));
    formatex(g_szCfgPath, cm(g_szCfgPath), "%s/ultimate_parachute.ini", cfgdir);
}

stock LoadConfig(bool:bPrecacheOnly)
{
    g_szAccessFlags[0] = 0;
    g_iAccessBits = 0;

    g_iAccessTeamTT = 1;
    g_iAccessTeamCT = 1;

    g_iWeaponUsage = 1;
    g_iDeployModeAccess = 1;
    g_iDeployModeDefault = DEPLOY_HOLD;
    g_flAutoThreshold = 350.0;
    g_iDeploysPerRound = 0;

    g_iFallSpeedAccess = 1;
    g_szFallSpeedDefault[0] = 0;

    g_iThirdAccess = 1;
    g_iThirdDefault = 0;

    g_iModelAccess = 1;
    g_szModelDefault[0] = 0;
    g_szDeploySound[0] = 0;

    g_iSpeedsNum = 0;
    g_iModelsNum = 0;

    g_iTrailAccess = 1;
    g_szTrailDefault[0] = 0;
    g_iTrailColorAccess = 1;
    g_szTrailColorDefault[0] = 0;
    g_iTrailLengthAccess = 1;
    g_szTrailLengthDefault[0] = 0;

    g_iTrailsNum = 0;
    g_iTrailColorsNum = 0;
    g_iTrailLengthsNum = 0;
    g_iDefaultSpeedIndex = 0;
    g_iDefaultModelIndex = 0;

    g_iDefaultTrailIndex = -1;
    g_iDefaultTrailColorIndex = -1;
    g_iDefaultTrailLengthIndex = 0;
    if(!file_exists(g_szCfgPath))
    {
        return;
    }

    new line[256], section[32];
    section[0] = 0;

    new fp = fopen(g_szCfgPath, "rt");
    if(!fp) return;

    while(!feof(fp))
    {
        fgets(fp, line, cm(line));
        trim(line);

        if(!line[0]) continue;
        if(line[0] == ';') continue;
        if(line[0] == '/' && line[1] == '/') continue;

        if(line[0] == '[')
        {
            new iEnd = contain(line, "]");
            if(iEnd > 1)
            {
                new j = 0;
                for(new i = 1; i < iEnd && j < cm(section); i++)
                    section[j++] = line[i];
                section[j] = 0;
                strtolower(section);
            }
            continue;
        }

        if(equali(section, "settings"))
        {
            new k[64], v[192];
            k[0]=0; v[0]=0;

            parse(line, k, cm(k), v, cm(v));
            strtolower(k);

            StripQuotes(v);

            if(equali(k, "access_flags"))
            {
                copy(g_szAccessFlags, cm(g_szAccessFlags), v);
                g_iAccessBits = read_flags(g_szAccessFlags);
            }
            else if(equali(k, "access_team_tt"))
            {
                g_iAccessTeamTT = clamp(str_to_num(v), 0, 1);
            }
            else if(equali(k, "access_team_ct"))
            {
                g_iAccessTeamCT = clamp(str_to_num(v), 0, 1);
            }
            else if(equali(k, "weapon_usage"))
            {
                g_iWeaponUsage = clamp(str_to_num(v), 0, 1);
            }
            else if(equali(k, "deploy_mode_access"))
            {
                g_iDeployModeAccess = clamp(str_to_num(v), 0, 1);
            }
            else if(equali(k, "deploy_mode_default"))
            {
                g_iDeployModeDefault = clamp(str_to_num(v), 0, 2);
            }
            else if(equali(k, "autodeploy_threshold"))
            {
                g_flAutoThreshold = floatclamp(str_to_float(v), 0.0, 9999.0);
            }
            else if(equali(k, "deploys_per_round"))
            {
                g_iDeploysPerRound = max(0, str_to_num(v));
            }
            else if(equali(k, "fall_speed_access"))
            {
                g_iFallSpeedAccess = clamp(str_to_num(v), 0, 1);
            }
            else if(equali(k, "fall_speed_default"))
            {
                copy(g_szFallSpeedDefault, cm(g_szFallSpeedDefault), v);
            }
            else if(equali(k, "3rd_person_view_access"))
            {
                g_iThirdAccess = clamp(str_to_num(v), 0, 1);
            }
            else if(equali(k, "3rd_person_view_default"))
            {
                g_iThirdDefault = clamp(str_to_num(v), 0, 1);
            }
            else if(equali(k, "model_access"))
            {
                g_iModelAccess = clamp(str_to_num(v), 0, 1);
            }
            else if(equali(k, "model_default"))
            {
                copy(g_szModelDefault, cm(g_szModelDefault), v);
            }
            else if(equali(k, "trail_access"))
            {
                g_iTrailAccess = clamp(str_to_num(v), 0, 1);
            }
            else if(equali(k, "trail_default"))
            {
                copy(g_szTrailDefault, cm(g_szTrailDefault), v);
            }
            else if(equali(k, "trail_color_access"))
            {
                g_iTrailColorAccess = clamp(str_to_num(v), 0, 1);
            }
            else if(equali(k, "trail_color_default"))
            {
                copy(g_szTrailColorDefault, cm(g_szTrailColorDefault), v);
            }
            else if(equali(k, "trail_length_access"))
            {
                g_iTrailLengthAccess = clamp(str_to_num(v), 0, 1);
            }
            else if(equali(k, "trail_length_default"))
            {
                copy(g_szTrailLengthDefault, cm(g_szTrailLengthDefault), v);
            }
            else if(equali(k, "trail_width"))
            {
                g_iTrailWidth = clamp(str_to_num(v), 0, 255);
            }
            else if(equali(k, "deploy_sound"))
            {
                copy(g_szDeploySound, cm(g_szDeploySound), v);
            }
        }
        else if(equali(section, "speeds"))
        {
            if(g_iSpeedsNum >= MAX_SPEEDS) continue;

            new sSpeed[32], sName[64];
            sSpeed[0]=0; sName[0]=0;
            parse(line, sSpeed, cm(sSpeed), sName, cm(sName));
            StripQuotes(sSpeed);
            StripQuotes(sName);

            if(!sSpeed[0] || !sName[0]) continue;

            copy(g_szSpeedName[g_iSpeedsNum], cm(g_szSpeedName[]), sName);
            g_flSpeedValue[g_iSpeedsNum] = str_to_float(sSpeed);
            g_iSpeedsNum++;
        }
        else if(equali(section, "models"))
        {
            if(g_iModelsNum >= MAX_MODELS) continue;

            new path[160], name[64];
            path[0]=0; name[0]=0;

            parse(line, path, cm(path), name, cm(name));
            StripQuotes(path);
            StripQuotes(name);

            if(!path[0]) continue;

            copy(g_szModelPath[g_iModelsNum], cm(g_szModelPath[]), path);

            if(name[0])
                copy(g_szModelName[g_iModelsNum], cm(g_szModelName[]), name);
            else
                formatex(g_szModelName[g_iModelsNum], cm(g_szModelName[]), "Model %d", g_iModelsNum + 1);

            if(bPrecacheOnly)
            {
                if(containi(path, ".mdl") != -1)
                    precache_model(path);
            }

            g_iModelsNum++;
        }

        else if(equali(section, "trails"))
        {
            if(g_iTrailsNum >= MAX_TRAILS) continue;

            new path[160], name[64];
            path[0]=0; name[0]=0;

            parse(line, path, cm(path), name, cm(name));
            StripQuotes(path);
            StripQuotes(name);

            if(!path[0]) continue;

            copy(g_szTrailPath[g_iTrailsNum], cm(g_szTrailPath[]), path);

            if(name[0])
                copy(g_szTrailName[g_iTrailsNum], cm(g_szTrailName[]), name);
            else
                formatex(g_szTrailName[g_iTrailsNum], cm(g_szTrailName[]), "Iz %d", g_iTrailsNum + 1);

            if(bPrecacheOnly)
            {
                if(containi(path, ".spr") != -1)
                    g_iTrailSpriteIdx[g_iTrailsNum] = precache_model(path);
            }
            else
            {
                g_iTrailSpriteIdx[g_iTrailsNum] = engfunc(EngFunc_ModelIndex, path);
            }

            g_iTrailsNum++;
        }
        else if(equali(section, "trail_colors"))
        {
            if(g_iTrailColorsNum >= MAX_TRAIL_COLORS) continue;

            new rgb[32], name[64];
            rgb[0]=0; name[0]=0;

            parse(line, rgb, cm(rgb), name, cm(name));
            StripQuotes(rgb);
            StripQuotes(name);

            if(!rgb[0]) continue;

            new sr[8], sg[8], sb[8];
            sr[0]=sg[0]=sb[0]=0;
            parse(rgb, sr, cm(sr), sg, cm(sg), sb, cm(sb));

            new r = clamp(str_to_num(sr), 0, 255);
            new g = clamp(str_to_num(sg), 0, 255);
            new b = clamp(str_to_num(sb), 0, 255);

            g_iTrailColorRGB[g_iTrailColorsNum][0] = r;
            g_iTrailColorRGB[g_iTrailColorsNum][1] = g;
            g_iTrailColorRGB[g_iTrailColorsNum][2] = b;

            if(name[0])
                copy(g_szTrailColorName[g_iTrailColorsNum], cm(g_szTrailColorName[]), name);
            else
                formatex(g_szTrailColorName[g_iTrailColorsNum], cm(g_szTrailColorName[]), "Цвет %d", g_iTrailColorsNum + 1);

            g_iTrailColorsNum++;
        }
        else if(equali(section, "trail_lengths"))
        {
            if(g_iTrailLengthsNum >= MAX_TRAIL_LENGTHS) continue;

            new lenStr[16], name[64];
            lenStr[0]=0; name[0]=0;

            parse(line, lenStr, cm(lenStr), name, cm(name));
            StripQuotes(lenStr);
            StripQuotes(name);

            if(!lenStr[0]) continue;

            g_iTrailLengthVal[g_iTrailLengthsNum] = max(0, str_to_num(lenStr));

            if(name[0])
                copy(g_szTrailLengthName[g_iTrailLengthsNum], cm(g_szTrailLengthName[]), name);
            else
                formatex(g_szTrailLengthName[g_iTrailLengthsNum], cm(g_szTrailLengthName[]), "Uzunluk %d", g_iTrailLengthsNum + 1);

            g_iTrailLengthsNum++;
        }

    }

    fclose(fp);

    ResolveDefaults();

    NormalizeDeploySound(bPrecacheOnly);
}

stock ResolveDefaults()
{
    g_iDefaultSpeedIndex = 0;
    if(g_iSpeedsNum > 0)
    {
        if(g_szFallSpeedDefault[0])
        {
            new bool:isIndex = true;
            for(new j=0; g_szFallSpeedDefault[j]; j++)
            {
                if(g_szFallSpeedDefault[j] == '-' || g_szFallSpeedDefault[j] == '.' )
                {
                    isIndex = false;
                    break;
                }
            }

            if(isIndex)
            {
                new idx = str_to_num(g_szFallSpeedDefault);
                if(idx >= 0 && idx < g_iSpeedsNum)
                    g_iDefaultSpeedIndex = idx;
            }
            else
            {
                new Float:f = str_to_float(g_szFallSpeedDefault);
                for(new i=0;i<g_iSpeedsNum;i++)
                {
                    if(floatabs(g_flSpeedValue[i] - f) < 0.01)
                    {
                        g_iDefaultSpeedIndex = i;
                        break;
                    }
                }
            }
        }
        else
        {
            for(new i=0;i<g_iSpeedsNum;i++)
            {
                if(floatabs(g_flSpeedValue[i] - (-100.0)) < 0.01)
                {
                    g_iDefaultSpeedIndex = i;
                    break;
                }
            }
        }
    }

    g_iDefaultModelIndex = -1;
    if(g_iModelsNum > 0)
    {
        if(g_szModelDefault[0])
        {
            for(new i=0;i<g_iModelsNum;i++)
            {
                if(equali(g_szModelPath[i], g_szModelDefault))
                {
                    g_iDefaultModelIndex = i;
                    break;
                }
            }
        }
    }

    g_iDefaultTrailIndex = -1;
    if(g_iTrailsNum > 0)
    {
        if(g_szTrailDefault[0])
        {
            for(new i=0;i<g_iTrailsNum;i++)
            {
                if(equali(g_szTrailPath[i], g_szTrailDefault))
                {
                    g_iDefaultTrailIndex = i;
                    break;
                }
            }
        }
    }

    g_iDefaultTrailColorIndex = -1;
    if(g_iTrailColorsNum > 0)
    {
        if(g_szTrailColorDefault[0])
        {
            new sr[8], sg[8], sb[8];
            sr[0]=sg[0]=sb[0]=0;
            parse(g_szTrailColorDefault, sr, cm(sr), sg, cm(sg), sb, cm(sb));

            new dr = clamp(str_to_num(sr), 0, 255);
            new dg = clamp(str_to_num(sg), 0, 255);
            new db = clamp(str_to_num(sb), 0, 255);

            for(new i=0;i<g_iTrailColorsNum;i++)
            {
                if(g_iTrailColorRGB[i][0] == dr && g_iTrailColorRGB[i][1] == dg && g_iTrailColorRGB[i][2] == db)
                {
                    g_iDefaultTrailColorIndex = i;
                    break;
                }
            }
        }
    }

    g_iDefaultTrailLengthIndex = 0;
    if(g_iTrailLengthsNum > 0)
    {
        if(g_szTrailLengthDefault[0])
        {
            new dl = max(0, str_to_num(g_szTrailLengthDefault));
            for(new i=0;i<g_iTrailLengthsNum;i++)
            {
                if(g_iTrailLengthVal[i] == dl)
                {
                    g_iDefaultTrailLengthIndex = i;
                    break;
                }
            }
        }
        if(g_iDefaultTrailLengthIndex >= g_iTrailLengthsNum)
            g_iDefaultTrailLengthIndex = 0;
    }

}

stock NormalizeDeploySound(bool:bPrecacheOnly)
{
    if(!g_szDeploySound[0])
        return;

    if(containi(g_szDeploySound, "sound/") == 0)
    {
        new tmp[128];
        copy(tmp, cm(tmp), g_szDeploySound[6]);
        copy(g_szDeploySound, cm(g_szDeploySound), tmp);
    }
    else if(containi(g_szDeploySound, "sound\") == 0)
    {
        new tmp2[128];
        copy(tmp2, cm(tmp2), g_szDeploySound[6]);
        copy(g_szDeploySound, cm(g_szDeploySound), tmp2);
    }

    if(bPrecacheOnly)
        precache_sound(g_szDeploySound);
}

stock ResetPlayerState(id)
{
    g_iParaEnt[id] = 0;
    g_bParaDeployed[id] = false;

    g_iDeployMode[id] = g_iDeployModeDefault;
    g_iSpeedIndex[id] = g_iDefaultSpeedIndex;
    g_bThird[id] = (g_iThirdDefault != 0);

    if(g_iModelsNum > 0)
    {
        g_iModelIndex[id] = g_iDefaultModelIndex;
        if(g_iModelIndex[id] >= g_iModelsNum) g_iModelIndex[id] = -1;
    }
    else
    {
        g_iModelIndex[id] = 0;
    }

    g_iLastWeapon[id] = 0;
}

stock HasParachuteAccess(id)
{
    if(g_szAccessFlags[0] && (get_user_flags(id) & g_iAccessBits) == 0)
        return false;

    new CsTeams:t = cs_get_user_team(id);
    if(t == CS_TEAM_T && !g_iAccessTeamTT) return false;
    if(t == CS_TEAM_CT && !g_iAccessTeamCT) return false;

    return true;
}

stock GetVaultKey(id, key[], keylen)
{
    new auth[32];
    get_user_authid(id, auth, cm(auth));

    if(equali(auth, "BOT") || equali(auth, "HLTV") || equali(auth, "STEAM_ID_LAN") || equali(auth, "VALVE_ID_LAN") || equali(auth, "STEAM_ID_PENDING"))
    {
        new ip[32];
        get_user_ip(id, ip, cm(ip), 1);
        formatex(key, keylen, "IP_%s", ip);
        return;
    }

    formatex(key, keylen, "SID_%s", auth);
}

stock LoadPlayerData(id)
{
    ResetPlayerState(id);

    if(g_iVault == INVALID_HANDLE)
        return;

    new key[64];
    GetVaultKey(id, key, cm(key));

    new data[128];
    if(!nvault_get(g_iVault, key, data, cm(data)))
        return;

    new s1[8], s2[8], s3[8], s4[8], s5[8], s6[8], s7[8];
    s1[0]=s2[0]=s3[0]=s4[0]=s5[0]=s6[0]=s7[0]=0;
    parse(data, s1, cm(s1), s2, cm(s2), s3, cm(s3), s4, cm(s4), s5, cm(s5), s6, cm(s6), s7, cm(s7));

    new m = str_to_num(s1);
    new sp = str_to_num(s2);
    new th = str_to_num(s3);
    new md = str_to_num(s4);
    new tr = str_to_num(s5);
    new tc = str_to_num(s6);
    new tl = str_to_num(s7);
    g_iDeployMode[id] = clamp(m, 0, 2);

    if(g_iSpeedsNum > 0)
        g_iSpeedIndex[id] = clamp(sp, 0, g_iSpeedsNum-1);
    else
        g_iSpeedIndex[id] = 0;

    g_bThird[id] = (th != 0);

    if(g_iModelsNum > 0)
    {
        if(md < 0)
            g_iModelIndex[id] = -1;
        else
            g_iModelIndex[id] = clamp(md, 0, g_iModelsNum-1);
    }
    else
    {
        g_iModelIndex[id] = 0;
    }
    if(g_iTrailsNum > 0)
    {
        if(tr < 0)
            g_iTrailIndex[id] = -1;
        else
            g_iTrailIndex[id] = clamp(tr, 0, g_iTrailsNum-1);
    }
    else
    {
        g_iTrailIndex[id] = 0;
    }

    if(g_iTrailColorsNum > 0)
    {
        if(tc < 0)
            g_iTrailColorIndex[id] = -1;
        else
            g_iTrailColorIndex[id] = clamp(tc, 0, g_iTrailColorsNum-1);
    }
    else
    {
        g_iTrailColorIndex[id] = 0;
    }

    if(g_iTrailLengthsNum > 0)
    {
        if(tl < 0)
            g_iTrailLengthIndex[id] = -1;
        else
            g_iTrailLengthIndex[id] = clamp(tl, 0, g_iTrailLengthsNum-1);
    }
    else
    {
        g_iTrailLengthIndex[id] = 0;
    }
}

stock SavePlayerData(id)
{
    if(!is_user_connected(id)) return;
    if(!HasParachuteAccess(id)) return;

    if(g_iVault == INVALID_HANDLE) return;

    new key[64];
    GetVaultKey(id, key, cm(key));

    new data[128];
    formatex(data, cm(data), "%d %d %d %d %d %d %d",
        g_iDeployMode[id],
        g_iSpeedIndex[id],
        g_bThird[id] ? 1 : 0,
        g_iModelIndex[id],
        g_iTrailIndex[id],
        g_iTrailColorIndex[id],
        g_iTrailLengthIndex[id]
    );

    nvault_set(g_iVault, key, data);
}

stock StripQuotes(str[])
{
    if(!str[0]) return;

    new len = strlen(str);
    if(len >= 2 && str[0] == '"' && str[len-1] == '"')
    {
        str[len-1] = 0;
        for(new i=0; i<len; i++)
            str[i] = str[i+1];
    }
}
[Resim: b_560_95_1.png]
Cevapla


Hızlı Menü:


Konuyu Okuyanlar: 1 Ziyaretçi