#include <sourcemod>
#include <shop>
#include <timers>

enum BetType
{
    Bet_None,
    Bet_Color,
    Bet_Dozen,
    Bet_Number,
    Bet_Column,
    Bet_Row
};

int g_PlayerBet[MAXPLAYERS + 1];       
BetType g_PlayerBetType[MAXPLAYERS + 1];   
int g_PlayerBetValue[MAXPLAYERS + 1];  
bool g_PlayerHasBet[MAXPLAYERS + 1]; 

public Plugin myinfo =
{
    name = "Roulette Plugin",
    author = "anon",
    description = "A simple roulette plugin for CS:Source",
    version = "1.0",
    url = "https://www.youtube.com"
};

public void OnPluginStart()
{
    RegConsoleCmd("sm_roul", Command_Roul);
    RegConsoleCmd("sm_bet", Command_Bet);
    
    // Инициализация массивов на старте плагина
    ResetAllBets();
}

public void OnMapStart()
{
    CreateTimer(50.0, Timer_RouletteEnd, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
    ResetAllBets(); // Сброс всех ставок при старте карты
}

public void ResetAllBets()
{
    for (int i = 1; i <= MaxClients; i++)
    {
        g_PlayerBet[i] = 0;
        g_PlayerBetType[i] = Bet_None;
        g_PlayerBetValue[i] = 0;
        g_PlayerHasBet[i] = false;
        
        // Логирование для отладки
        LogMessage("ResetAllBets(): Player %d reset with BetType: %d, BetValue: %d, Bet: %d, HasBet: %b", i, g_PlayerBetType[i], g_PlayerBetValue[i], g_PlayerBet[i], g_PlayerHasBet[i]);
    }
}

public Action Command_Roul(int client, int args)
{
    if (!IsClientInGame(client))
    {
        return Plugin_Handled;
    }

    ShowRouletteMenu(client);
    return Plugin_Handled;
}

public void ShowRouletteMenu(int client)
{
    Menu menu = CreateMenu(MenuHandler_Roulette);

    menu.SetTitle("Выберите ставку");
    menu.AddItem("color", "На цвет");
    menu.AddItem("dozen", "На дюжину");
    menu.AddItem("number", "На число");
    menu.AddItem("column", "На колонну");
    menu.AddItem("row", "На столбец");

    menu.Display(client, 0);
}

public void SelectColorMenu(int client)
{
    Menu menu = CreateMenu(MenuHandler_SelectColor);
    menu.SetTitle("Выберите цвет");
    menu.AddItem("red", "Красный");
    menu.AddItem("black", "Черный");
    menu.Display(client, 0);
}

public void SelectDozenMenu(int client)
{
    Menu menu = CreateMenu(MenuHandler_SelectDozen);
    menu.SetTitle("Выберите дюжину");
    menu.AddItem("dozen1", "1-12");
    menu.AddItem("dozen2", "13-24");
    menu.AddItem("dozen3", "25-36");
    menu.Display(client, 0);
}

public void SelectNumberMenu(int client)
{
    Menu menu = CreateMenu(MenuHandler_SelectNumber);
    menu.SetTitle("Выберите число");
    for (int i = 0; i <= 36; i++)
    {
        char num[4];
        IntToString(i, num, sizeof(num));
        menu.AddItem(num, num);
    }
    menu.Display(client, 0);
}

public void SelectColumnMenu(int client)
{
    Menu menu = CreateMenu(MenuHandler_SelectColumn);
    menu.SetTitle("Выберите колонну");
    menu.AddItem("col1", "Колонна 1");
    menu.AddItem("col2", "Колонна 2");
    menu.AddItem("col3", "Колонна 3");
    menu.Display(client, 0);
}

public void SelectRowMenu(int client)
{
    Menu menu = CreateMenu(MenuHandler_SelectRow);
    menu.SetTitle("Выберите строку");
    for (int i = 1; i <= 12; i++)
    {
        char num[4];
        IntToString(i, num, sizeof(num));
        menu.AddItem(num, num);
    }
    menu.Display(client, 0);
}

public int MenuHandler_Roulette(Menu menu, MenuAction action, int client, int param)
{
    if (action == MenuAction_End)
    {
        menu.Close();
    }
    else if (action == MenuAction_Select)
    {
        char selection[32];
        menu.GetItem(param, selection, sizeof(selection));

        if (StrEqual(selection, "color"))
        {
            SelectColorMenu(client);
        }
        else if (StrEqual(selection, "dozen"))
        {
            SelectDozenMenu(client);
        }
        else if (StrEqual(selection, "number"))
        {
            SelectNumberMenu(client);
        }
        else if (StrEqual(selection, "column"))
        {
            SelectColumnMenu(client);
        }
        else if (StrEqual(selection, "row"))
        {
            SelectRowMenu(client);
        }
    }
    return 0;
}

public Action Command_Bet(int client, int args)
{
    if (!IsClientInGame(client) || args < 1)
    {
        return Plugin_Handled;
    }

    char arg[32];
    GetCmdArg(1, arg, sizeof(arg));

    int bet = StringToInt(arg);
    int credits = Shop_GetClientCredits(client);

    if (bet <= 0 || bet > credits)
    {
        PrintToChat(client, "\x07000000[Рулетка] \x07af2a22Некорректная ставка.");
        return Plugin_Handled;
    }

    g_PlayerBet[client] = bet;
    g_PlayerHasBet[client] = true;
    Shop_SetClientCredits(client, credits - bet);

    PrintToChat(client, "\x07000000[Рулетка] \x07ffffffИгрок \x07276f5c%N \x07ffffffпоставил \x04%d \x07ffffffкредитов.", client, bet);

    return Plugin_Handled;
}

public int MenuHandler_SelectColor(Menu menu, MenuAction action, int client, int param)
{
    if (action == MenuAction_End)
    {
        menu.Close();
    }
    else if (action == MenuAction_Select)
    {
        g_PlayerBetType[client] = Bet_Color;
        char selection[32];
        menu.GetItem(param, selection, sizeof(selection));
        g_PlayerBetValue[client] = StrEqual(selection, "red") ? 1 : 2;
        PrintToChat(client, "\x07000000[Рулетка] \x07ffffffВведите свою ставку в чат (Пример: \x07af2a22!bet \x0450\x07ffffff)");
    }
    return 0;
}

public int MenuHandler_SelectDozen(Menu menu, MenuAction action, int client, int param)
{
    if (action == MenuAction_End)
    {
        menu.Close();
    }
    else if (action == MenuAction_Select)
    {
        g_PlayerBetType[client] = Bet_Dozen;
        g_PlayerBetValue[client] = param + 1;
        PrintToChat(client, "\x07000000[Рулетка] \x07ffffffВведите свою ставку в чат (Пример: \x07af2a22!bet \x0450\x07ffffff)");
    }
    return 0;
}

public int MenuHandler_SelectNumber(Menu menu, MenuAction action, int client, int param)
{
    if (action == MenuAction_End)
    {
        menu.Close();
    }
    else if (action == MenuAction_Select)
    {
        g_PlayerBetType[client] = Bet_Number;
        char number[4];
        menu.GetItem(param, number, sizeof(number));
        g_PlayerBetValue[client] = StringToInt(number);
        PrintToChat(client, "\x07000000[Рулетка] \x07ffffffВведите свою ставку в чат (Пример: \x07af2a22!bet \x0450\x07ffffff)");
    }
    return 0;
}

public int MenuHandler_SelectColumn(Menu menu, MenuAction action, int client, int param)
{
    if (action == MenuAction_End)
    {
        menu.Close();
    }
    else if (action == MenuAction_Select)
    {
        g_PlayerBetType[client] = Bet_Column;
        g_PlayerBetValue[client] = param + 1;
        PrintToChat(client, "\x07000000[Рулетка] \x07ffffffВведите свою ставку в чат (Пример: \x07af2a22!bet \x0450\x07ffffff)");
    }
    return 0;
}

public int MenuHandler_SelectRow(Menu menu, MenuAction action, int client, int param)
{
    if (action == MenuAction_End)
    {
        menu.Close();
    }
    else if (action == MenuAction_Select)
    {
        g_PlayerBetType[client] = Bet_Row;
        g_PlayerBetValue[client] = param + 1;
        PrintToChat(client, "\x07000000[Рулетка] \x07ffffffВведите свою ставку в чат (Пример: \x07af2a22!bet \x0450\x07ffffff)");
    }
    return 0;
}

public Action Timer_RouletteEnd(Handle timer)
{
    RouletteEnd();
    return Plugin_Continue;
}

public void ResetPlayerBets(int client)
{
	g_PlayerHasBet[client] = false;
	g_PlayerBet[client] = 0;
	g_PlayerBetType[client] = Bet_None;
	g_PlayerBetValue[client] = 0;
}

public void RouletteEnd()
{
    int result = GetRandomInt(0, 36);

    PrintToChatAll("\x07000000[Рулетка] \x07ffffffВыпало число: %d", result);

    for (int i = 1; i <= MaxClients; i++)
    {
        // Для отладки: выводим состояния перед проверкой
        LogMessage("RouletteEnd(): Before check - Player %d: BetType: %d, BetValue: %d, Bet: %d, HasBet: %b", i, g_PlayerBetType[i], g_PlayerBetValue[i], g_PlayerBet[i], g_PlayerHasBet[i]);

        if (g_PlayerHasBet[i])
        {
            bool won = false;
            int payout = 0;

            switch (g_PlayerBetType[i])
            {
                case Bet_Color:
                {
                    if ((g_PlayerBetValue[i] == 1 && IsRed(result)) ||
                        (g_PlayerBetValue[i] == 2 && !IsRed(result)))
                    {
                        won = true;
                        payout = 2 * g_PlayerBet[i];
                        PrintToChat(i, "\x07000000[Рулетка] \x07ffffffВы выиграли \x04%d кредитов.", payout);
                        Shop_SetClientCredits(i, Shop_GetClientCredits(i) + payout);
                    }
                    else
                    {
                        won = false;
                        PrintToChat(i, "\x07000000[Рулетка] \x07ffffffВы програли!");
                    }
                    break;
                }

                case Bet_Dozen:
                {
                    if (ResultMatchesDozen(result, g_PlayerBetValue[i]))
                    {
                        won = true;
                        payout = 3 * g_PlayerBet[i];
                        PrintToChat(i, "\x07000000[Рулетка] \x07ffffffВы выиграли \x04%d кредитов.", payout);
                        Shop_SetClientCredits(i, Shop_GetClientCredits(i) + payout);
                    }
                    else
                    {
                        won = false;
                        PrintToChat(i, "\x07000000[Рулетка] \x07ffffffВы програли!");
                    }
                    break;
                }

                case Bet_Number:
                {
                    if (result == g_PlayerBetValue[i])
                    {
                        won = true;
                        payout = 36 * g_PlayerBet[i];
                        PrintToChat(i, "\x07000000[Рулетка] \x07ffffffВы выиграли \x04%d кредитов.", payout);
                        Shop_SetClientCredits(i, Shop_GetClientCredits(i) + payout);
                    }
                    else
                    {
                        won = false;
                        PrintToChat(i, "\x07000000[Рулетка] \x07ffffffВы програли!");
                    }
                    break;
                }

                case Bet_Column:
                {
                    if (ResultMatchesColumn(result, g_PlayerBetValue[i]))
                    {
                        won = true;
                        payout = 3 * g_PlayerBet[i];
                        PrintToChat(i, "\x07000000[Рулетка] \x07ffffffВы выиграли \x04%d кредитов.", payout);
                        Shop_SetClientCredits(i, Shop_GetClientCredits(i) + payout);
                    }
                    else
                    {
                        won = false;
                        PrintToChat(i, "\x07000000[Рулетка] \x07ffffffВы програли!");
                    }
                    break;
                }

                case Bet_Row:
                {
                    if (ResultMatchesRow(result, g_PlayerBetValue[i]))
                    {
                        won = true;
                        payout = 3 * g_PlayerBet[i];
                        PrintToChat(i, "\x07000000[Рулетка] \x07ffffffВы выиграли \x04%d кредитов.", payout);
                        Shop_SetClientCredits(i, Shop_GetClientCredits(i) + payout);
                    }
                    else
                    {
                        won = false;
                        PrintToChat(i, "\x07000000[Рулетка] \x07ffffffВы програли!");
                    }
                    break;
                }
            }

            // Логирование для дебага
            LogMessage("RouletteEnd(): After check - Player %d: BetType: %d, BetValue: %d, Bet: %d, Won: %b", i, g_PlayerBetType[i], g_PlayerBetValue[i], g_PlayerBet[i], won);

            // Сбрасываем данные игрока
            g_PlayerHasBet[i] = false;
            LogMessage("RouletteEnd(): After reset HasBet - Player %d: HasBet: %b", i, g_PlayerHasBet[i]);
            
            g_PlayerBet[i] = 0;
            LogMessage("RouletteEnd(): After reset Bet - Player %d: Bet: %d", i, g_PlayerBet[i]);
            
            g_PlayerBetType[i] = Bet_None;
            LogMessage("RouletteEnd(): After reset BetType - Player %d: BetType: %d", i, g_PlayerBetType[i]);
            
            g_PlayerBetValue[i] = 0;
            LogMessage("RouletteEnd(): After reset BetValue - Player %d: BetValue: %d", i, g_PlayerBetValue[i]);
        }
		ResetPlayerBets(i);
        // Логирование после сброса данных
        LogMessage("RouletteEnd(): After reset - Player %d: BetType: %d, BetValue: %d, Bet: %d, HasBet: %b", i, g_PlayerBetType[i], g_PlayerBetValue[i], g_PlayerBet[i], g_PlayerHasBet[i]);
    }
}

const int RED_NUMBERS_COUNT = 18;
int redNumbers[RED_NUMBERS_COUNT] = 
    {1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36};

bool IsRed(int number)
{
    for (int i = 0; i < RED_NUMBERS_COUNT; i++)
    {
        if (redNumbers[i] == number)
        {
            return true;
        }
    }
    return false;
}

bool ResultMatchesDozen(int result, int dozen)
{
    switch (dozen)
    {
        case 1:
            return result >= 1 && result <= 12;
        case 2:
            return result >= 13 && result <= 24;
        case 3:
            return result >= 25 && result <= 36;
        default:
            return false;
    }
}

bool ResultMatchesColumn(int result, int column)
{
    switch (column)
    {
        case 1:
            return (result % 3 == 1);
        case 2:
            return (result % 3 == 2);
        case 3:
            return (result % 3 == 0);
        default:
            return false;
    }
}

bool ResultMatchesRow(int result, int row)
{
    return ((result - 1) / 3) + 1 == row;
}



Не сбрасывается ставка
В логах пишет

L 06/06/2024 - 19:23:15: [roul2.smx] RouletteEnd(): Before check - Player 2: BetType: 5, BetValue: 3, Bet: 6000, HasBet: 1
L 06/06/2024 - 19:24:05: [roul2.smx] RouletteEnd(): Before check - Player 1: BetType: 0, BetValue: 0, Bet: 0, HasBet: 0
L 06/06/2024 - 19:24:05: [roul2.smx] RouletteEnd(): After reset - Player 1: BetType: 0, BetValue: 0, Bet: 0, HasBet: 0
L 06/06/2024 - 19:24:05: [roul2.smx] RouletteEnd(): Before check - Player 2: BetType: 5, BetValue: 3, Bet: 6000, HasBet: 1
L 06/06/2024 - 19:24:55: [roul2.smx] RouletteEnd(): Before check - Player 1: BetType: 0, BetValue: 0, Bet: 0, HasBet: 0
L 06/06/2024 - 19:24:55: [roul2.smx] RouletteEnd(): After reset - Player 1: BetType: 0, BetValue: 0, Bet: 0, HasBet: 0
L 06/06/2024 - 19:24:55: [roul2.smx] RouletteEnd(): Before check - Player 2: BetType: 5, BetValue: 3, Bet: 6000, HasBet: 1