#pragma semicolon 1
#pragma newdecls optional

#include <tf2>
#include <tf2_stocks>
#include <sdkhooks>
#include <sdktools>
#include <multicolors>

#define MAX_PLAYERS 64
#define VERSION "1.4.0.9"
#define URL "https://foxsys-tech.ru"
#define FCVARS (FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY)

new iS[MAX_PLAYERS+1][MAX_PLAYERS+1];
new Count5[MAX_PLAYERS+1];
new Count10[MAX_PLAYERS+1];

new g_contrib5[MAX_PLAYERS+1][MAX_PLAYERS+1];
new g_contrib10[MAX_PLAYERS+1][MAX_PLAYERS+1];
new g_hasReduced[MAX_PLAYERS+1][MAX_PLAYERS+1];

public Plugin:myinfo = {
    name = "[FXSS] Scoring Players",
    author = "Lappland_Bro, Chat-GPT 4",
    description = "Автоматическое ведение счёта между игроками",
    version = VERSION,
    url = URL
};

public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max) {
    if (GetEngineVersion() != Engine_TF2) {
        Format(error, err_max, "This plugin only works for Team Fortress 2");
        return APLRes_Failure;
    }
    return APLRes_Success;
}

public OnMapStart() {
    AddFileToDownloadsTable("sound/gl_endmusic/ows_50_96.mp3");
    AddFileToDownloadsTable("sound/gl_endmusic/ows_10_96.mp3");
    PrecacheSound("gl_endmusic/ows_50_96.mp3", true);
    PrecacheSound("gl_endmusic/ows_10_96.mp3", true);
}

public OnPluginStart() {
    CreateConVar("sm_scoring_version", VERSION, "Version of Scoring Players plugin.", FCVARS);
    
    AddFileToDownloadsTable("sound/gl_endmusic/ows_50_96.mp3");
    AddFileToDownloadsTable("sound/gl_endmusic/ows_10_96.mp3");
    PrecacheSound("gl_endmusic/ows_50_96.mp3", true);
    PrecacheSound("gl_endmusic/ows_10_96.mp3", true);

    HookEvent("player_death", PlayerDeath);
}

public OnClientDisconnect_Post(int client) {
    for (int i = 1; i <= MAX_PLAYERS; i++) {
        iS[i][client] = 0;
        iS[client][i] = 0;
        g_hasReduced[i][client] = 0;
        g_hasReduced[client][i] = 0;
    }
    Count5[client] = 0;
    Count10[client] = 0;
}

public PlayerDeath(Handle:E, String:N[], bool:B) {
    int attacker = GetClientOfUserId(GetEventInt(E, "attacker"));
    int victim   = GetClientOfUserId(GetEventInt(E, "userid"));
    int death_flags = GetEventInt(E, "death_flags");

    if (!IsValidClient(attacker) || !IsValidClient(victim) || attacker == victim) {
        return;
    }

    if (death_flags != TF_DEATHFLAG_DEADRINGER) {
        iS[attacker][victim]++;
        CPrintToChat(attacker, "{GRAY}► СЧЁТ: %N {DARKGREEN}%i{GRAY}:{DARKGREEN}%i {GRAY}%N",
                      attacker, iS[attacker][victim], iS[victim][attacker], victim);
        CPrintToChat(victim, "{GRAY}► СЧЁТ: %N {DARKGREEN}%i{GRAY}:{DARKGREEN}%i {GRAY}%N",
                      victim, iS[victim][attacker], iS[attacker][victim], attacker);
    } else {
        int fakeScore = iS[attacker][victim] + 1;
        CPrintToChat(attacker, "{GRAY}► СЧЁТ: %N {DARKGREEN}%i{GRAY}:{DARKGREEN}%i {GRAY}%N",
                      attacker, fakeScore, iS[victim][attacker], victim);
    }

    CheckSpecialConditionsCombined(attacker, victim);
}

public CheckSpecialConditionsCombined(int attacker, int victim) {
    bool validKill = (iS[victim][attacker] == 0);

    if (iS[attacker][victim] == 5) {
        if (validKill && g_contrib5[attacker][victim] == 0) {
            Count5[attacker]++;
            g_contrib5[attacker][victim] = 1;
        }
        if (Count5[attacker] > 0 && validKill) {  // Добавлено validKill
            char sPlayers[32];
            FormatPlayersWord(Count5[attacker], sPlayers, sizeof(sPlayers));
            CPrintToChatAll("{GRAY}►{GRAY} Игрок {WHITE}%N{GRAY} сделал 5 убийств ПОДРЯД без смертей %s!", 
                            attacker, Count5[attacker] > 1 ? sPlayers : "");
            EmitSoundToAll("gl_endmusic/ows_50_96.mp3", SOUND_FROM_PLAYER, SNDCHAN_AUTO, SNDLEVEL_CONVO);
        }
    }

    if (iS[attacker][victim] == 10) {
        if (validKill && g_contrib10[attacker][victim] == 0) {
            Count10[attacker]++;
            g_contrib10[attacker][victim] = 1;
        }
        if (Count10[attacker] > 0 && validKill) {  // Добавлено validKill
            char sPlayers[32];
            FormatPlayersWord(Count10[attacker], sPlayers, sizeof(sPlayers));
            CPrintToChatAll("{GRAY}►{GRAY} Игрок {WHITE}%N{GRAY} сделал 10 убийств ПОДРЯД без смертей %s!", 
                            attacker, Count10[attacker] > 1 ? sPlayers : "");
            EmitSoundToAll("gl_endmusic/ows_10_96.mp3", SOUND_FROM_PLAYER, SNDCHAN_AUTO, SNDLEVEL_CONVO);
        }
    }

    if (iS[victim][attacker] >= 1 && g_hasReduced[attacker][victim] == 0) {
        g_hasReduced[attacker][victim] = 1;
        if (g_contrib5[attacker][victim] == 1 && Count5[attacker] > 0) {
            Count5[attacker]--;
        }
        if (g_contrib10[attacker][victim] == 1 && Count10[attacker] > 0) {
            Count10[attacker]--;
        }
    }
}

stock FormatPlayersWord(int count, char[] sPlayers, int maxLen) {
    switch (count) {
		case 0: Format(sPlayers, maxLen, "ERROR");
		case 1: Format(sPlayers, maxLen, "с ОДНИМ ИГРОКОМ");
        case 2: Format(sPlayers, maxLen, "с ДВУМЯ ИГРОКАМИ");
        case 3: Format(sPlayers, maxLen, "с ТРЕМЯ ИГРОКАМИ");
        case 4: Format(sPlayers, maxLen, "с ЧЕТЫРЬМЯ ИГРОКАМИ");
        default: Format(sPlayers, maxLen, "с %d-Ю ИГРОКАМИ", count);
    }
}

bool IsValidClient(int client) {
    return (client >= 1 && client <= MAX_PLAYERS &&
            IsClientConnected(client) && IsClientInGame(client) &&
            !IsClientReplay(client) && !IsClientSourceTV(client) && !IsFakeClient(client));
}

