Создание Меню - Форум
Заказать Сервер Платные SourceMod Плагины Контакты Поиск

Counter-Strike Source + 2 GAMES
Grand Theft Auto V
DARK SOULS III
другие игры [ дешевле, чем в стиме ]

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

Страница 1 из 6123456»
Форум » SourceMod - Counter Strike Source && CS GO » Уроки SourceMod (SourcePawn) Скриптинга » Создание Меню (CreatePanel, CreateMenu)
Создание Меню
_wS_ Дата: Суббота, 14.01.2012, 05:57:27 | Сообщение # 1
Ниже будут приведены примеры кода для создания разных типов меню.
Лучше не копируйте код, а скачайте архив в прикреплениях, чтобы вручную отступы не поправлять.

Panel (панель)

Код
#include <sourcemod>

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 \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");
}

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, то меню само будет разбиваться на страницы и вы сможете листать их дополнительными кнопками внизу "вперед" и "назад". И еще удобно то, что можно узнать не только позицию выбранной опции, но и значение переменной, которое в ней хранится.

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

Код
#include <sourcemod>

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 \n");
      decl String:userid[15], String:name[32];
      for (new i = 1; i <= MaxClients; i++)
      {
          if (IsClientInGame(i))
          {
              IntToString(GetClientUserId(i), userid, 15);
              GetClientName(i, name, 32);
              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[15];
      GetMenuItem(menu, option, userid, 15);
      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 стиля меню

Прикрепления: 3471064.jpg(3Kb) · 9621169.jpg(110Kb) · cods.zip(1Kb)
 
ЙОДА Дата: Понедельник, 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
Сообщений: 135
Репутация: 1 [ +/- ]
А есть вопрос как создать это дело в Top Menu
На SourceMod читал что-то про это но не нашел =(
 
Scarface_slv Дата: Воскресенье, 24.06.2012, 18:24:04 | Сообщение # 6
Сообщений: 749
Репутация: 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
Репутация: -5 [ +/- ]
Представим в меню 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
Репутация: -5 [ +/- ]
Как закрыть меню только у 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
Репутация: -5 [ +/- ]
Можно ли сделать так если 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 было перебито дргим меню
     }
}

Только плохо наверно будет, если то другое меню делает то же самое.
 
Форум » SourceMod - Counter Strike Source && CS GO » Уроки SourceMod (SourcePawn) Скриптинга » Создание Меню (CreatePanel, CreateMenu)
Страница 1 из 6123456»
Поиск: