#include <amxmodx>
#include <fakemeta>
#include <fun>
#include <xs>
#include <hamsandwich>
#include <cstrike>
#include <engine>

new const PLUGIN[] = "Graffiti + VIP";
new const VERSION[] = "1.0";
new const AUTHOR[] = "ChatGPT + Osmanbnm";
new const TAG[] = "^4[Graffiti]^1";

new pGraffiti_Ammo;
new pGraffiti_Reload;
new pGraffiti_VIP_Ammo;
new Graffiti_LastTime[33];
new Graffiti_Ammo[33];
new bool:isVip[33];
new g_spray_spr;

public plugin_precache()
{
    g_spray_spr = precache_model("sprites/spray.spr");
}

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR);
    register_clcmd("+graffiti", "cmdGraffiti");
    
    register_logevent("eventNewRound", 2, "1=Round_Start");
    
    pGraffiti_Ammo = register_cvar("graffiti_normal_ammo", "3");
    pGraffiti_Reload = register_cvar("graffiti_reload", "8");
    pGraffiti_VIP_Ammo = register_cvar("graffiti_vip_ammo", "10");
}

public eventNewRound()
{
    new players[32], num;
    get_players(players, num, "ch");
    
    for(new i = 0; i < num; i++)
    {
        new id = players[i];
        Graffiti_LastTime[id] = 0;
        
        if(isVip[id])
            Graffiti_Ammo[id] = get_pcvar_num(pGraffiti_VIP_Ammo);
        else
            Graffiti_Ammo[id] = get_pcvar_num(pGraffiti_Ammo);
    }
}

public client_putinserver(id)
{
    Graffiti_LastTime[id] = 0;
    
    if(get_user_flags(id) & ADMIN_RESERVATION)
    {
        isVip[id] = true;
        Graffiti_Ammo[id] = get_pcvar_num(pGraffiti_VIP_Ammo);
    }
    else
    {
        isVip[id] = false;
        Graffiti_Ammo[id] = get_pcvar_num(pGraffiti_Ammo);
    }
}

public client_disconnected(id)
{
    Graffiti_Ammo[id] = 0;
    Graffiti_LastTime[id] = 0;
    isVip[id] = false;
}

public cmdGraffiti(id)
{
    if(!is_user_alive(id))
    {
        ColorChat(id, "Olu iken spray atamazsin!");
        return PLUGIN_HANDLED;
    }
    
    new Float:origin[3], Float:angles[3], Float:normal[3];
    
    if(!TraceToWall(id, origin, angles, normal))
    {
        ColorChat(id, "Sadece duvara spray atabilirsin!");
        return PLUGIN_HANDLED;
    }
    
    if(isVip[id])
    {
        if(Graffiti_Ammo[id] <= 0)
        {
            ColorChat(id, "^3[VIP]^1 Spray hakkin bitti!");
            return PLUGIN_HANDLED;
        }
        
        Graffiti_Ammo[id]--;
        CreateGraffiti(origin, normal);
        ColorChat(id, "^3[VIP]^1 Spray atildi! Kalan:^4 %d", Graffiti_Ammo[id]);
        return PLUGIN_HANDLED;
    }
    
    new systime = get_systime();
    new reload_time = get_pcvar_num(pGraffiti_Reload);
    
    if(Graffiti_Ammo[id] <= 0)
    {
        if((systime - Graffiti_LastTime[id]) >= reload_time)
        {
            Graffiti_Ammo[id] = get_pcvar_num(pGraffiti_Ammo);
            Graffiti_LastTime[id] = 0;
        }
        else
        {
            new wait_time = reload_time - (systime - Graffiti_LastTime[id]);
            ColorChat(id, "Spray hakki yenilemek icin^3 %d^1 saniye bekle!", wait_time);
            return PLUGIN_HANDLED;
        }
    }
    
    Graffiti_Ammo[id]--;
    CreateGraffiti(origin, normal);
    ColorChat(id, "Spray atildi! Kalan:^4 %d", Graffiti_Ammo[id]);
    
    if(Graffiti_Ammo[id] == 0)
        Graffiti_LastTime[id] = systime;
    
    return PLUGIN_HANDLED;
}

bool:TraceToWall(id, Float:origin[3], Float:angles[3], Float:normal[3])
{
    new Float:src[3], Float:view_ofs[3], Float:dest[3];
    pev(id, pev_origin, src);
    pev(id, pev_view_ofs, view_ofs);
    xs_vec_add(src, view_ofs, src);
    
    pev(id, pev_v_angle, angles);
    angle_vector(angles, ANGLEVECTOR_FORWARD, dest);
    xs_vec_mul_scalar(dest, 128.0, dest);
    xs_vec_add(src, dest, dest);
    
    new trace = create_tr2();
    engfunc(EngFunc_TraceLine, src, dest, IGNORE_MONSTERS, id, trace);
    
    new Float:fraction;
    get_tr2(trace, TR_flFraction, fraction);
    
    if(fraction < 1.0)
    {
        get_tr2(trace, TR_vecEndPos, origin);
        get_tr2(trace, TR_vecPlaneNormal, normal);
        free_tr2(trace);
        return true;
    }
    
    free_tr2(trace);
    return false;
}

CreateGraffiti(Float:origin[3], Float:normal[3])
{
    message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
    write_byte(TE_SPRITE);
    engfunc(EngFunc_WriteCoord, origin[0] + normal[0] * 5.0);
    engfunc(EngFunc_WriteCoord, origin[1] + normal[1] * 5.0);
    engfunc(EngFunc_WriteCoord, origin[2] + normal[2] * 5.0);
    write_short(g_spray_spr);
    write_byte(20);
    write_byte(255);
    message_end();
}

stock ColorChat(const id, const string[], any:...)
{
    static message[256], finalMsg[256];
    vformat(message, charsmax(message), string, 3);
    
    formatex(finalMsg, charsmax(finalMsg), "%s %s", TAG, message);
    
    replace_all(finalMsg, charsmax(finalMsg), "^4", "^x04");
    replace_all(finalMsg, charsmax(finalMsg), "^3", "^x03");
    replace_all(finalMsg, charsmax(finalMsg), "^1", "^x01");
    
    static msg_saytext;
    if(!msg_saytext)
        msg_saytext = get_user_msgid("SayText");
    
    message_begin(id ? MSG_ONE_UNRELIABLE : MSG_BROADCAST, msg_saytext, _, id);
    write_byte(id ? id : 33);
    write_string(finalMsg);
    message_end();
}
