Заказать игровой сервер Контакты (заказать плагин/исправить ошибки/другое) Пожертвовать Поиск

[ вход ]
[ последние сообщения ]

  • Страница 1 из 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • »
Создание Меню
_wS_ Дата: Суббота, 14.01.2012, 05:57:27 | Сообщение # 1
Ниже будут приведены примеры кода для создания разных типов меню.
Лучше не копируйте код, а скачайте архив в прикреплениях, чтобы вручную отступы не поправлять.

Panel (панель)

Код
public OnPluginStart() {
    RegConsoleCmd("test", test);
}

public Action:test(client, args) {
    if (client > 0 && args < 1) {
        ShowMyPanel(client);
    }
    return Plugin_Handled;
}

ShowMyPanel(client)
{
    new Handle:panel = CreatePanel();
    SetPanelTitle(panel, "Животные:\n ");
    DrawPanelItem(panel, "Кот");
    DrawPanelText(panel, "Носорог");
    DrawPanelItem(panel, "Собак");
    DrawPanelItem(panel, "Хамелеон");
    DrawPanelItem(panel, "Тигр \n ");
    DrawPanelItem(panel, "Выход");
    SendPanelToClient(panel, client, Select_Panel, 0);
    CloseHandle(panel);
    ClientCommand(client, "playgamesound items/nvg_off.wav");
}

public Select_Panel(Handle:panel, MenuAction:action, client, option) {
    if (action == MenuAction_Select) {
        PrintToChat(client, "Номер выбранной опции: %d", option);
        if (option < 5) {
            ShowMyPanel(client);
        }
    }
}

Запустите этот плагин, войдите в игру и введите в консоль test. Откроется такое меню:



Выбрав опцию, вы увидите её номер в чате, и если она меньше 5 (5 это выход), то меню снова откроется.
Опцию 'Носорог' нельзя выбрать и она без номера, это просто текст.
Максимум опций (которые можно выбрать): 10

Если в меню хранятся постоянные одинаковые данные, то нет смысла его постоянно пересоздавать, просто создайте глобальную переменную и сохраните в ней Handle вашего меню. И после отправки менюшки игроку, если оно вам еще надо, не делайте CloseHandle(), ибо это убивает меню.

Handle:CreatePanel(Handle:hStyle=INVALID_HANDLE); - создаёт панель и возвращает её Handle.
Если вернёт INVALID_HANDLE, значит произошла ошибка.

Код
hStyle (стиль меню):

MenuStyle_Default = 0 // The "default" menu style for the mod
MenuStyle_Valve = 1 // The Valve provided menu style (Used on HL2DM)
MenuStyle_Radio = 2 // The simpler menu style commonly used on CS:S

Handle:SetPanelTitle(Handle:panel, const String:text[], bool:onlyIfEmpty=false);
Устанавливает название меню. Если onlyIfEmpty true, то название установится, только если оно ещё не установлено.

DrawPanelItem(Handle:panel, const String:text[], style=ITEMDRAW_DEFAULT); - добавляет опцию в меню

Код
Тип опции (style):
ITEMDRAW_DEFAULT - используется по умолчанию
ITEMDRAW_DISABLED - опцию нельзя выбрать + текст становится белым)
ITEMDRAW_RAWLINE - Item should be a raw line, without a slot
ITEMDRAW_NOTEXT - No text should be drawn
ITEMDRAW_SPACER - Item should be drawn as a spacer, if possible
ITEMDRAW_IGNORE - Item should be completely ignored (rawline + notext)
ITEMDRAW_CONTROL - Item is control text (back/next/exit)

bool:DrawPanelText(Handle:panel, const String:text[]);
Это не считается опцией, которую можно выбрать, это добавляет обычный текст

bool:SendPanelToClient(Handle:panel, client, <функция>, time);
Отправляет (показывает) игроку меню на time секунд (0 = всегда). Функция выглядит так:

Код
public xzFuncName(Handle:panel, MenuAction:action, param1, param2)
{
    // если надо ловить момент выбора опций:
    if (action == MenuAction_Select)
    {
        // ваш код
    }
}

Внутри функции вы можете лишь проверять, какую игрок выбрал опцию (номер), и уже исходя из этого что-то делать.

MenuAction:

Код
MenuAction_Select - игрок выбрал опцию (param1 = client, param2 = номер опции)
MenuAction_Cancel - игрок закрыл меню (param1 = client, param2 = reason)
MenuAction_End - меню стало неактивным (param1 = reason)
и др.

MenuAction_Cancel reason (причина закрытия меню)

Код
MenuCancel_Disconnected - игрок покинул сервер
MenuCancel_Interrupted - меню закрылось, так как открылось новое
MenuCancel_Exit - игрок нажал "выход"
MenuCancel_NoDisplay - меню не может быть отображено клиенту
MenuCancel_Timeout - время отображения меню истекло
MenuCancel_ExitBack - клиент выбрал "exit back (выйти обратно)" на одной из страниц

MenuAction_End reason

Код
MenuEnd_Selected - выбрана опция в меню
MenuEnd_VotingDone - голосование было завершено
MenuEnd_VotingCancelled - голосование отменено
MenuEnd_Cancelled - меню было отменено (param2 = reason)
MenuEnd_Exit - игрок нажал "exit (выход)"
MenuEnd_ExitBack - нажал "back"

Handle:GetPanelStyle(Handle:panel); - возвращает Handle стиля панели

Menu (меню)

Это меню может содержать множество опций, а не 10, как в панели. Если опций больше 7, то меню само будет разбиваться на страницы и вы сможете листать их дополнительными кнопками внизу "вперед" и "назад". И еще удобно то, что можно узнать не только позицию выбранной опции, но и значение переменной, которое в ней хранится.

Протестируйте такой код:

Код
public OnPluginStart() {
    RegConsoleCmd("test", test);
}

public Action:test(client, args) {
    if (client > 0 && args < 1) {
        ShowMyMenu(client);
    }
    return Plugin_Handled;
}

ShowMyMenu(client)
{
    new Handle:menu = CreateMenu(Select_Menu);
    SetMenuTitle(menu, "Выберите Игрока:\n ");
    decl String:userid[16], String:name[32];
    for (new i = 1; i <= MaxClients; i++) {
        if (IsClientInGame(i))
        {
            IntToString(GetClientUserId(i), userid, sizeof(userid));
            GetClientName(i, name, sizeof(name));
            AddMenuItem(menu, userid, name);
        }
    }
    DisplayMenu(menu, client, 0);
}

public Select_Menu(Handle:menu, MenuAction:action, client, option)
{
    if (action == MenuAction_End)
    {
        // Если меню стало неактивным, обязательно уничтожьте его.
        // Исключение:    
        // Меню глобальное и оно еще вам нужно.
        CloseHandle(menu);
        return;
    }

    if (action != MenuAction_Select) {
        return;
    }

    decl String:userid[16];
    GetMenuItem(menu, option, userid, sizeof(userid));

    new target = GetClientOfUserId(StringToInt(userid));
    if (target > 0)
    {
        PrintToChat(client, "Индекс игрока: %d | id: %s", target, userid);
        new cash = GetEntProp(target, Prop_Send, "m_iAccount") + 1;
        if (cash < 16001)
        {
            SetEntProp(target, Prop_Send, "m_iAccount", cash);
            PrintToChatAll("Игроку < %N > добавлен $1", target);
        }
        else {
            PrintToChat(client, "У него $16000");
        }
    }
    else {
        PrintToChat(client, "Игрок не найден (вышел с сервера)");
    }
    ShowMyMenu(client);
}



Handle:CreateMenu(<функция>, MenuAction:actions=MENU_ACTIONS_DEFAULT);
Создаёт меню и возвращает его Handle

SetMenuTitle(Handle:menu, const String:fmt[], any:...); - устанавливает название
AddMenuItem(Handle:menu, const String:info[], const String:display[], style=ITEMDRAW_DEFAULT);

Добавляет опцию в меню:
info - строка, которую можно будет получить с помощью GetMenuItem
display - текст, отображающийся в меню

bool:DisplayMenu(Handle:menu, client, time); - отправить меню игроку на time сек (0 = всегда)
bool:DisplayMenuAtItem(Handle:menu, client, first_item, time);
То же самое, но меню можно открыть на определенной странице/опции, надо указать позицию first_item

GetMenuSelectionPosition() - возвращает позицию первого элемента на текущей странице (MenuAction_Select).
Используется для того, чтобы можно было отправить меню в исходном положении.
Можно использовать так:

Код
DisplayMenuAtItem(menu, client, GetMenuSelectionPosition(), 0);

bool:GetMenuItem(Handle:menu, position, String:infoBuf[], infoBufLen, &style=0, String:dispBuf[]="", dispBufLen=0);
Это позволять получить значение, которое было записано в info, когда делали AddMenuItem.
dispBuf - это текст, отображаемый в меню, и dispBufLen его длина.

GetMenuTitle(Handle:menu, String:buffer[], maxlength); - получить название меню (запишется в buffer)

bool:GetMenuExitButton(Handle:menu); - вернёт true, если в меню есть кнопка "выход"
bool:SetMenuExitButton(Handle:menu, bool:button); - запретить(false)/разрешить(true) кнопку "выход"

bool:GetMenuExitBackButton(Handle:menu); - true, если есть кнопка "назад"
SetMenuExitBackButton(Handle:menu, bool:button); - запретить(false)/разрешить(true) кнопку "назад"
Если на 1 страницу добавить эту кнопку, то при её выборе сработает MenuEnd_ExitBack.

GetMenuItemCount(Handle:menu); - возвращает количество пунктов (опций) в меню
Handle:GetMenuStyle(Handle:menu); - возвращает Handle стиля меню

Гости не могут скачивать файлы
 
ЙОДА Дата: Понедельник, 28.05.2012, 03:22:39 | Сообщение # 2
Сообщений: 41
Репутация: 0 [ +/- ]
Хотелось бы узнать, как добавлять текстовую анселектовую строку в меню типа CreateMenu() , также как DrawPanelText() в CreatePanel()

Добавлено (28.05.2012, 03:22:39)
---------------------------------------------
Перерыл весь инклуд menus.inc, но так и не смог найти ответ.

 
_wS_ Дата: Понедельник, 28.05.2012, 09:28:10 | Сообщение # 3
AddMenuItem(menu, "", "Текст\nБелый текст");
 
ЙОДА Дата: Среда, 20.06.2012, 23:16:47 | Сообщение # 4
Сообщений: 41
Репутация: 0 [ +/- ]
Спасибо :)

Добавлено (30.05.2012, 02:10:13)
---------------------------------------------
Code
. . .
        new Handle:panel = CreatePanel();    
        SetPanelTitle(panel, "Животные:\n \n");    
        DrawPanelItem(panel, "Кот");    
        DrawPanelText(panel, "Носорог");    
        DrawPanelItem(panel, "Собак");  
        DrawPanelItem(panel, "Хамелеон");    
        DrawPanelItem(panel, "Тигр \n \n");    
        DrawPanelItem(panel, "Выход");    
        SendPanelToClient(panel, client, Select_Panel, 0);    
        CloseHandle(panel);    
        ClientCommand(client, "playgamesound items/nvg_off.wav");    
. . .


Собак xD Просто убило ^__^

Добавлено (20.06.2012, 20:25:53)
---------------------------------------------
2 вопроса:

1 - Можно ли создать пустое меню, где бует только текст с тайтла через /n /n /n и кнопка выхода?
2 - Можно ли в панели заставить нумерацию кнопок идти не с 1, например ставлю 2 кнопки:назад, выход - как сделать их на 8 и 0?

Добавлено (20.06.2012, 23:16:47)
---------------------------------------------
Вытащил из исходников сурсмода :

SetPanelCurrentKey(panel,n)
n - сдвиг на позицию
при n=10, следующий
DrawPanelItem будет на цифре 0.



Сообщение отредактировал ЙОДА - Среда, 30.05.2012, 02:10:46
 
Vitaminoz Дата: Воскресенье, 24.06.2012, 12:53:37 | Сообщение # 5
Сообщений: 141
Репутация: 1 [ +/- ]
А есть вопрос как создать это дело в Top Menu
На SourceMod читал что-то про это но не нашел =(
 
Scarface_slv Дата: Воскресенье, 24.06.2012, 18:24:04 | Сообщение # 6
Сообщений: 737
Репутация: 61 [ +/- ]
вот тут это обсуждалось http://world-source.ru/forum/102-2549-1
 
sssw Дата: Воскресенье, 29.07.2012, 07:47:20 | Сообщение # 7
Сообщений: 123
Репутация: 14 [ +/- ]
Мне придёться пересдавать меню, если мне нужно изменить одно название пункта из него?
К примеру "aktel[MUTED]" поменять на "aktel[UNMUTED]" возможно?
 
Naykon Дата: Четверг, 13.09.2012, 01:44:50 | Сообщение # 8
Сообщений: 439
Репутация: -4 [ +/- ]
Представим в меню 15 пунктов на 1 страницу к примеру влезло 8 а на вторую 7, когда я выбираю пункт со 2 страницы нужно чтоб меню не исчезало а оставалось на той-же 2 странице. как это можно воплотить?
 
_wS_ Дата: Четверг, 13.09.2012, 12:14:54 | Сообщение # 9
Quote (sssw)
Мне придёться пересдавать меню, если мне нужно изменить одно название пункта из него?

Попробуй RemoveMenuItem, а затем InsertMenuItem (можно и наоборот).

Naykon:

Code
DisplayMenuAtItem(menu, client, GetMenuSelectionPosition(), 0);
 
Naykon Дата: Четверг, 27.09.2012, 17:32:19 | Сообщение # 10
Сообщений: 439
Репутация: -4 [ +/- ]
Как закрыть меню только у 1 игрока ( с индекстом client)
 
_wS_ Дата: Четверг, 27.09.2012, 17:39:22 | Сообщение # 11
Можно попробовать заставить выбрать опцию (вряд ли получится):
ClientCommand(client, "menuselect 10 или 0");

Ну а точно работающий вариант, это создать пустую панель (CreatePanel()) и отправить игроку.
Новое меню перебьет старое.
 
Skybi Дата: Четверг, 27.09.2012, 19:16:04 | Сообщение # 12
Сообщений: 4
Репутация: 1 [ +/- ]
Как можно перевести пункты и название меню через translations phrases(файл перевода)?
 
_wS_ Дата: Четверг, 27.09.2012, 19:41:05 | Сообщение # 13
Есть же урок (%T)
 
Naykon Дата: Четверг, 04.10.2012, 17:36:35 | Сообщение # 14
Сообщений: 439
Репутация: -4 [ +/- ]
Можно ли сделать так если 1 меню открыто то его не может свернуть другое меню..??
 
_wS_ Дата: Четверг, 04.10.2012, 17:56:11 | Сообщение # 15
Думаю нет. Можно только узнать, когда менюшка была перебита, и отправить ее снова.

Code
public xz(Handle:menu, MenuAction:action, param1, param2)
{
     if (action == MenuAction_Cancel && param2 == MenuCancel_Interrupted)
     {
         // menu было перебито дргим меню
     }
}

Только плохо наверно будет, если то другое меню делает то же самое.
 
  • Страница 1 из 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • »
Поиск: