Правильно передать данные из одного меню в другое

oleg_nelasy

Участник
Сообщения
664
Реакции
46
C-подобный:
int g_iPlayerTag;

public int Menu_playersTag(Menu menu, MenuAction action, int iClient, int iItem)
{
    int iNumberItem;
    //char name[255];
    switch (action)
    {
        case MenuAction_Select:
        {
            for (int i = 1; i <= MaxClients; i++)
            if (IsClientInGame(i) && !IsFakeClient(i)) //&& IsPlayerAlive(iClient)
            {
                iNumberItem=i-1;
                if(iItem == iNumberItem)
                {
                    //GetClientName(i, name, sizeof(name))
                    //PrintToChatAll("Nмя выбраного игрока %s индекс равен %d", name, i);    
                    ReasonsTag(iClient);
                    g_iPlayerTag = i;
                }    
            }
        }
        case MenuAction_Cancel:    // Меню было отменено
        {
            if(iItem == MenuCancel_ExitBack && g_hAdminMenu != null)    // Если игрок нажал кнопку "Назад"
            {
                
                g_hAdminMenu.DisplayCategory(g_hAdminMenu.FindCategory(ADMINMENU_PLAYERCOMMANDS), iClient);
            }
        }
    }
}

public void PlayersMenuTag(int iClient)
{
    char name[255];
    char Player[10];
    Menu hMenuPlayers = new Menu(Menu_playersTag, MenuAction_Select);
    hMenuPlayers.SetTitle("%t", "SetTitlePlayers");
    
    for (int i = 1; i <= MaxClients; i++)
        if (IsClientInGame(i) && !IsFakeClient(i))
        {
            GetClientName(i, name, sizeof(name))
            FormatEx(Player, sizeof(Player), "Player %d", i); 
            //PrintToChatAll("Player = %s", Player)
            hMenuPlayers.AddItem(Player, name);
        }        
    hMenuPlayers.ExitBackButton = true;            
    hMenuPlayers.Display(iClient, 0);
}

public int Menu_ReasonsTag(Menu menu, MenuAction action, int iClient, int iItem)
{
    AdminId PlayerID, PlayerID2;
    switch (action)
    {
        case MenuAction_Select:
        {
            switch (iItem)
            {
                case 0:
                {
                
                    PlayerID = GetUserAdmin(iClient);
                    PlayerID2 = GetUserAdmin(g_iPlayerTag);
                    if(GetAdminImmunityLevel(PlayerID) >= GetAdminImmunityLevel(PlayerID2))
                        CS_SetClientClanTag(g_iPlayerTag, "");
                        else CGOPrintToChat(iClient, "%t %t", "Tag", "No access")
                }
                case 1:
                {
                    PlayerID = GetUserAdmin(iClient);
                    PlayerID2 = GetUserAdmin(g_iPlayerTag);
                    if(GetAdminImmunityLevel(PlayerID) >= GetAdminImmunityLevel(PlayerID2))
                        CS_SetClientClanTag(g_iPlayerTag, sReasonsTag[1]);
                        else CGOPrintToChat(iClient, "%t %t", "Tag", "No access")
                }
            }
        }
        case MenuAction_Cancel:    // Меню было отменено
        {
            if(iItem == MenuCancel_ExitBack)    // Если игрок нажал кнопку "Назад"
            {
                PlayersMenuTag(iClient);
            }
        }   
    }
}

public void ReasonsTag(int iClient)
{
    //char sReasonsTag[2][50];
    SetGlobalTransTarget(iClient);
    FormatEx(sReasonsTag[0], sizeof(sReasonsTag[]), "%t", "ReasonsTag1");
    FormatEx(sReasonsTag[1], sizeof(sReasonsTag[]), "%t", "ReasonsTag2");
    
    Menu hMenuReasonsTag = new Menu(Menu_ReasonsTag, MenuAction_Select);
    hMenuReasonsTag.SetTitle("%t", "SetTitleTag");
    hMenuReasonsTag.AddItem(sReasonsTag[0], sReasonsTag[0]);
    hMenuReasonsTag.AddItem(sReasonsTag[1], sReasonsTag[1]);
    hMenuReasonsTag.ExitBackButton = true;
    hMenuReasonsTag.Display(iClient, 0);
}
В данный момент открывая меню PlayersMenuTag перебираю игроков и формирую меню, дальше выбираю игрока в момент нажатия кнопки снова перебираю игроков пока не попаду на нужно дальше присваиваю глобальной переменной g_iPlayerTag значения индекса игрока и открываю меню ReasonsTag выбираю какой тег установить и делаю CS_SetClientClanTag(g_iPlayerTag, ...); где с помощью g_iPlayerTag передаю какого игрока надо наказать.

Поймал себя на мысли если несколько админов решать воспользоваться эти меню одновременно на разных игроков то они начнут перезаписывать друг другу g_iPlayerTag и начнется жесть. Подскажете можно как-то передать индекс игрока из одного меню в другое другими методами кроме как глобальная переменная g_iPlayerTag?
 

DeathScore13

пирожок. пирожочек.
Сообщения
734
Реакции
403
C-подобный:
int g_iPlayerTag;

public int Menu_playersTag(Menu menu, MenuAction action, int iClient, int iItem)
{
    int iNumberItem;
    //char name[255];
    switch (action)
    {
        case MenuAction_Select:
        {
            for (int i = 1; i <= MaxClients; i++)
            if (IsClientInGame(i) && !IsFakeClient(i)) //&& IsPlayerAlive(iClient)
            {
                iNumberItem=i-1;
                if(iItem == iNumberItem)
                {
                    //GetClientName(i, name, sizeof(name))
                    //PrintToChatAll("Nмя выбраного игрока %s индекс равен %d", name, i);  
                    ReasonsTag(iClient);
                    g_iPlayerTag = i;
                }  
            }
        }
        case MenuAction_Cancel:    // Меню было отменено
        {
            if(iItem == MenuCancel_ExitBack && g_hAdminMenu != null)    // Если игрок нажал кнопку "Назад"
            {
              
                g_hAdminMenu.DisplayCategory(g_hAdminMenu.FindCategory(ADMINMENU_PLAYERCOMMANDS), iClient);
            }
        }
    }
}

public void PlayersMenuTag(int iClient)
{
    char name[255];
    char Player[10];
    Menu hMenuPlayers = new Menu(Menu_playersTag, MenuAction_Select);
    hMenuPlayers.SetTitle("%t", "SetTitlePlayers");
  
    for (int i = 1; i <= MaxClients; i++)
        if (IsClientInGame(i) && !IsFakeClient(i))
        {
            GetClientName(i, name, sizeof(name))
            FormatEx(Player, sizeof(Player), "Player %d", i);
            //PrintToChatAll("Player = %s", Player)
            hMenuPlayers.AddItem(Player, name);
        }      
    hMenuPlayers.ExitBackButton = true;          
    hMenuPlayers.Display(iClient, 0);
}

public int Menu_ReasonsTag(Menu menu, MenuAction action, int iClient, int iItem)
{
    AdminId PlayerID, PlayerID2;
    switch (action)
    {
        case MenuAction_Select:
        {
            switch (iItem)
            {
                case 0:
                {
              
                    PlayerID = GetUserAdmin(iClient);
                    PlayerID2 = GetUserAdmin(g_iPlayerTag);
                    if(GetAdminImmunityLevel(PlayerID) >= GetAdminImmunityLevel(PlayerID2))
                        CS_SetClientClanTag(g_iPlayerTag, "");
                        else CGOPrintToChat(iClient, "%t %t", "Tag", "No access")
                }
                case 1:
                {
                    PlayerID = GetUserAdmin(iClient);
                    PlayerID2 = GetUserAdmin(g_iPlayerTag);
                    if(GetAdminImmunityLevel(PlayerID) >= GetAdminImmunityLevel(PlayerID2))
                        CS_SetClientClanTag(g_iPlayerTag, sReasonsTag[1]);
                        else CGOPrintToChat(iClient, "%t %t", "Tag", "No access")
                }
            }
        }
        case MenuAction_Cancel:    // Меню было отменено
        {
            if(iItem == MenuCancel_ExitBack)    // Если игрок нажал кнопку "Назад"
            {
                PlayersMenuTag(iClient);
            }
        } 
    }
}

public void ReasonsTag(int iClient)
{
    //char sReasonsTag[2][50];
    SetGlobalTransTarget(iClient);
    FormatEx(sReasonsTag[0], sizeof(sReasonsTag[]), "%t", "ReasonsTag1");
    FormatEx(sReasonsTag[1], sizeof(sReasonsTag[]), "%t", "ReasonsTag2");
  
    Menu hMenuReasonsTag = new Menu(Menu_ReasonsTag, MenuAction_Select);
    hMenuReasonsTag.SetTitle("%t", "SetTitleTag");
    hMenuReasonsTag.AddItem(sReasonsTag[0], sReasonsTag[0]);
    hMenuReasonsTag.AddItem(sReasonsTag[1], sReasonsTag[1]);
    hMenuReasonsTag.ExitBackButton = true;
    hMenuReasonsTag.Display(iClient, 0);
}
В данный момент открывая меню PlayersMenuTag перебираю игроков и формирую меню, дальше выбираю игрока в момент нажатия кнопки снова перебираю игроков пока не попаду на нужно дальше присваиваю глобальной переменной g_iPlayerTag значения индекса игрока и открываю меню ReasonsTag выбираю какой тег установить и делаю CS_SetClientClanTag(g_iPlayerTag, ...); где с помощью g_iPlayerTag передаю какого игрока надо наказать.

Поймал себя на мысли если несколько админов решать воспользоваться эти меню одновременно на разных игроков то они начнут перезаписывать друг другу g_iPlayerTag и начнется жесть. Подскажете можно как-то передать индекс игрока из одного меню в другое другими методами кроме как глобальная переменная g_iPlayerTag?
C-подобный:
int g_iPlayerTag[MAXPLAYERS + 1]; // будем использовать индекс админа, который открыл меню, как идентификатор

// пример (admin - индекс админа, client - индекс клиента):
void func(int admin, int client = 1)
{
  g_iPlayerTag[admin] = client;
  func2(admin);
}

void func2(int admin)
{
  PrintToServer("%i", g_iPlayerTag[admin]); // получим 1
}
 

xtance

Участник
Сообщения
513
Реакции
743
Нужен массив, чтобы для каждого игрока записывалось в свою ячейку, да это может показаться неоптимальным с учетом того что админов ощутимо меньше чем игроков, но по-другому вроде никак.
То есть: int g_iPlayerTag[MAXPLAYERS+1];
И затем записываем выбор игрока туда: g_iPlayerTag[iClient] = i;

Кстати
Когда формируешь меню из игроков, передавай не индекс клиента, а его юзерайди

C-подобный:
for (int i = 1; i <= MaxClients; i++)
{
    if (IsClientInGame(i) && !IsFakeClient(i))
    {
        GetClientName(i, name, sizeof(name));
        FormatEx(Player, sizeof(Player), "%i", GetClientUserId(i));
        hMenuPlayers.AddItem(Player, name);
    }
}

Поскольку пока юзер тыкался в менюшку, айди клиента могло измениться
Потом в функции обработки меню вместо цикла просто преобразуй его обратно в client id и проверь всё ли с ним норм (вдруг он там отключился и т.д.)

C-подобный:
public int Menu_playersTag(Menu menu, MenuAction action, int iClient, int iItem)
{
   
    switch (action)
    {
        case MenuAction_Select:
        {
            char item[32];
            menu.GetItem(iItem, item, sizeof(item));
            int iUserID = StringToInt(item);
            int iPlayer = GetClientOfUserId(iUserID);
          
            if (iPlayer && IsClientInGame(iPlayer))
            {
                // действия с игроком
                ReasonsTag(iClient);
                g_iPlayerTag[iClient] = iPlayer;
            }
        // дальнейший код...
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,519
Реакции
4,979
Ещё вместо if(GetAdminImmunityLevel(PlayerID) >= GetAdminImmunityLevel(PlayerID2)) нужно использовать bool CanUserTarget(int client, int target) (используются настройки иммунитета SM и достаточно индексов игроков для сравнения).
Сообщения автоматически склеены:

И вообще:
C-подобный:
            switch (iItem)
            {
                case 0:
                {
                
                    PlayerID = GetUserAdmin(iClient);
                    PlayerID2 = GetUserAdmin(g_iPlayerTag);
                    if(GetAdminImmunityLevel(PlayerID) >= GetAdminImmunityLevel(PlayerID2))
                        CS_SetClientClanTag(g_iPlayerTag, "");
                        else CGOPrintToChat(iClient, "%t %t", "Tag", "No access")
                }
                case 1:
                {
                    PlayerID = GetUserAdmin(iClient);
                    PlayerID2 = GetUserAdmin(g_iPlayerTag);
                    if(GetAdminImmunityLevel(PlayerID) >= GetAdminImmunityLevel(PlayerID2))
                        CS_SetClientClanTag(g_iPlayerTag, sReasonsTag[1]);
                        else CGOPrintToChat(iClient, "%t %t", "Tag", "No access")
                }
            }
==>
C-подобный:
            if(CanUserTarget(iClient, g_iPlayerTag[iClient]))
                CS_SetClientClanTag(g_iPlayerTag, iItem ? sReasonsTag[1] : "");
            else CGOPrintToChat(iClient, "%t %t", "Tag", "No access");
 
Сверху Снизу