behold with your eyes and view upon what are MENUS
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40775
This commit is contained in:
		
							parent
							
								
									30f50e6ded
								
							
						
					
					
						commit
						d7b2f9a721
					
				@ -42,6 +42,7 @@ ConCmdManager::ConCmdManager() : m_Strings(1024)
 | 
				
			|||||||
	m_pExecCmd = NULL;
 | 
						m_pExecCmd = NULL;
 | 
				
			||||||
	m_pServerCfgFile = NULL;
 | 
						m_pServerCfgFile = NULL;
 | 
				
			||||||
	m_pServerCfgFwd = NULL;
 | 
						m_pServerCfgFwd = NULL;
 | 
				
			||||||
 | 
						m_CmdClient = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ConCmdManager::~ConCmdManager()
 | 
					ConCmdManager::~ConCmdManager()
 | 
				
			||||||
 | 
				
			|||||||
@ -111,6 +111,11 @@ private:
 | 
				
			|||||||
	void RemoveConCmds(List<CmdHook *> &cmdlist, IPluginContext *pContext);
 | 
						void RemoveConCmds(List<CmdHook *> &cmdlist, IPluginContext *pContext);
 | 
				
			||||||
	bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin);
 | 
						bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin);
 | 
				
			||||||
	void OnExecCmd();
 | 
						void OnExecCmd();
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						inline int GetCommandClient()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_CmdClient;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	Trie *m_pCmds;					/* command lookup */
 | 
						Trie *m_pCmds;					/* command lookup */
 | 
				
			||||||
	Trie *m_pCmdGrps;				/* command group lookup */
 | 
						Trie *m_pCmdGrps;				/* command group lookup */
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										676
									
								
								core/MenuManager.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										676
									
								
								core/MenuManager.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,676 @@
 | 
				
			|||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					#include "MenuManager.h"
 | 
				
			||||||
 | 
					#include "sm_stringutil.h"
 | 
				
			||||||
 | 
					#include "sourcemm_api.h"
 | 
				
			||||||
 | 
					#include "PlayerManager.h"
 | 
				
			||||||
 | 
					#include "MenuStyle_Valve.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MenuManager g_Menus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*************************************
 | 
				
			||||||
 | 
					 *************************************
 | 
				
			||||||
 | 
					 **** BROADCAST HANDLING WRAPPERS ****
 | 
				
			||||||
 | 
					 *************************************
 | 
				
			||||||
 | 
					 *************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BroadcastHandler::BroadcastHandler(IMenuHandler *handler) : m_pHandler(handler), numClients(0)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int BroadcastHandler::GetMenuAPIVersion2()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return m_pHandler->GetMenuAPIVersion2();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BroadcastHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_pHandler->OnMenuCancel(menu, client, reason);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BroadcastHandler::OnMenuDisplay(IBaseMenu *menu, int client, IMenuDisplay *display)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						numClients++;
 | 
				
			||||||
 | 
						m_pHandler->OnMenuDisplay(menu, client, display);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BroadcastHandler::OnBroadcastEnd(IBaseMenu *menu)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						g_Menus.FreeBroadcastHandler(this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BroadcastHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_pHandler->OnMenuSelect(menu, client, item);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BroadcastHandler::OnMenuEnd(IBaseMenu *menu)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						assert(numClients > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Only fire if all clients have gotten a menu end */
 | 
				
			||||||
 | 
						if (--numClients == 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							IMenuHandler *pHandler = m_pHandler;
 | 
				
			||||||
 | 
							OnBroadcastEnd(menu);
 | 
				
			||||||
 | 
							pHandler->OnMenuEnd(menu);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VoteHandler::VoteHandler(IMenuVoteHandler *handler) 
 | 
				
			||||||
 | 
					: BroadcastHandler(handler), m_pVoteHandler(handler)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void VoteHandler::Initialize(IBaseMenu *menu)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int numItems = menu->GetItemCount();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (m_counts.size() >= numItems)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							for (size_t i=0; i<numItems; i++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								m_counts[i] = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							for (size_t i=0; i<m_counts.size(); i++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								m_counts[i] = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							m_counts.resize(numItems, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void VoteHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (item < numItems)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							m_counts[item]++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BroadcastHandler::OnMenuSelect(menu, client, item);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void VoteHandler::OnBroadcastEnd(IBaseMenu *menu)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_ties.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size_t highest = 0;
 | 
				
			||||||
 | 
						for (size_t i=1; i<numItems; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (m_counts[i] > m_counts[highest])
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								m_ties.clear();
 | 
				
			||||||
 | 
								highest = i;
 | 
				
			||||||
 | 
							} else if (m_counts[i] == m_counts[highest]) {
 | 
				
			||||||
 | 
								m_ties.push_back(i);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (m_ties.size())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							m_ties.push_back(highest);
 | 
				
			||||||
 | 
							srand(static_cast<unsigned int>(time(NULL)));
 | 
				
			||||||
 | 
							highest = m_ties[rand() % m_ties.size()];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						m_pVoteHandler->OnMenuVoteEnd(menu, highest);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						g_Menus.FreeVoteHandler(this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************
 | 
				
			||||||
 | 
					 *******************************
 | 
				
			||||||
 | 
					 ******** MENU MANAGER *********
 | 
				
			||||||
 | 
					 *******************************
 | 
				
			||||||
 | 
					 *******************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MenuManager::MenuManager()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_ShowMenu = -1;
 | 
				
			||||||
 | 
						m_pDefaultStyle = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MenuManager::OnSourceModAllInitialized()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int num = g_SMAPI->GetUserMessageCount();
 | 
				
			||||||
 | 
						if (num >= 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							for (int i=0; i<num; i++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (strcmp(g_SMAPI->GetUserMessage(i, NULL), "ShowMenu") == 0)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									m_ShowMenu = i;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* :TODO: styles */
 | 
				
			||||||
 | 
						m_Styles.push_back(&g_ValveMenuStyle);
 | 
				
			||||||
 | 
						SetDefaultStyle(&g_ValveMenuStyle);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MenuManager::OnSourceModAllShutdown()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						while (!m_BroadcastHandlers.empty())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							delete m_BroadcastHandlers.front();
 | 
				
			||||||
 | 
							m_BroadcastHandlers.pop();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (!m_VoteHandlers.empty())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							delete m_VoteHandlers.front();
 | 
				
			||||||
 | 
							m_VoteHandlers.pop();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool MenuManager::SetDefaultStyle(IMenuStyle *style)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!style)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						m_pDefaultStyle = style;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					IMenuStyle *MenuManager::GetStyle(unsigned int index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (index >= GetStyleCount())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return m_Styles[index];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int MenuManager::GetStyleCount()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (unsigned int)m_Styles.size();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					IMenuStyle *MenuManager::FindStyleByName(const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int count = GetStyleCount();
 | 
				
			||||||
 | 
						for (unsigned int i=0; i<count; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							IMenuStyle *ptr = GetStyle(i);
 | 
				
			||||||
 | 
							if (strcasecmp(ptr->GetStyleName(), name) == 0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return ptr;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline bool IsSlotItem(IMenuDisplay *display,
 | 
				
			||||||
 | 
										   unsigned int style)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!display->CanDrawItem(style))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if ((style & ITEMDRAW_IGNORE) == ITEMDRAW_IGNORE)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (style & ITEMDRAW_RAWLINE)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					IMenuDisplay *MenuManager::RenderMenu(int client, menu_states_t &md, ItemOrder order)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						IBaseMenu *menu = md.menu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!menu)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							unsigned int position;
 | 
				
			||||||
 | 
							ItemDrawInfo draw;
 | 
				
			||||||
 | 
						} drawItems[10];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Figure out how many items to draw */
 | 
				
			||||||
 | 
						IMenuStyle *style = menu->GetDrawStyle();
 | 
				
			||||||
 | 
						unsigned int pgn = menu->GetPagination();
 | 
				
			||||||
 | 
						unsigned int maxItems = style->GetMaxPageItems();
 | 
				
			||||||
 | 
						if (pgn != MENU_NO_PAGINATION)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							maxItems = pgn;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned int totalItems = menu->GetItemCount();
 | 
				
			||||||
 | 
						unsigned int startItem = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* For pagination, find the starting point. */
 | 
				
			||||||
 | 
						if (pgn != MENU_NO_PAGINATION)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (order == ItemOrder_Ascending)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								startItem = md.lastItem;
 | 
				
			||||||
 | 
								/* This shouldn't happen with well-coded menus.
 | 
				
			||||||
 | 
								 * If the item is out of bounds, switch the order to
 | 
				
			||||||
 | 
								 * Items_Descending and make us start from the top.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								if (startItem >= totalItems)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									startItem = totalItems - 1;
 | 
				
			||||||
 | 
									order = ItemOrder_Descending;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else if (order == ItemOrder_Descending) {
 | 
				
			||||||
 | 
								startItem = md.firstItem;
 | 
				
			||||||
 | 
								/* This shouldn't happen with well-coded menus.
 | 
				
			||||||
 | 
								 * If searching backwards doesn't give us enough room,
 | 
				
			||||||
 | 
								 * start from the beginning and change to ascending.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								if (startItem <= maxItems)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									startItem = 0;
 | 
				
			||||||
 | 
									order = ItemOrder_Ascending;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Get our Display pointer and initialize some crap */
 | 
				
			||||||
 | 
						IMenuDisplay *display = menu->CreateDisplay();
 | 
				
			||||||
 | 
						IMenuHandler *mh = md.mh;
 | 
				
			||||||
 | 
						bool foundExtra = false;
 | 
				
			||||||
 | 
						unsigned int extraItem = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * We keep searching until:
 | 
				
			||||||
 | 
						 * 1) There are no more items
 | 
				
			||||||
 | 
						 * 2) We reach one OVER the maximum number of slot items
 | 
				
			||||||
 | 
						 * 3) We have reached maxItems and pagination is MENU_NO_PAGINATION
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						unsigned int i = startItem;
 | 
				
			||||||
 | 
						unsigned int foundItems = 0;
 | 
				
			||||||
 | 
						while (true)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ItemDrawInfo &dr = drawItems[foundItems].draw;
 | 
				
			||||||
 | 
							/* Is the item valid? */
 | 
				
			||||||
 | 
							if (menu->GetItemInfo(i, &dr) != NULL)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* Ask the user to change the style, if necessary */
 | 
				
			||||||
 | 
								mh->OnMenuDrawItem(menu, client, i, dr.style);
 | 
				
			||||||
 | 
								/* Check if it's renderable */
 | 
				
			||||||
 | 
								if (IsSlotItem(display, dr.style))
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									/* If we've already found the max number of items,
 | 
				
			||||||
 | 
									 * This means we should just cancel out and log our
 | 
				
			||||||
 | 
									 * "last item."
 | 
				
			||||||
 | 
									 */
 | 
				
			||||||
 | 
									if (foundItems >= maxItems)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										foundExtra = true;
 | 
				
			||||||
 | 
										extraItem = i;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									drawItems[foundItems++].position = i;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							/* If there's no pagination, stop once the menu is full. */
 | 
				
			||||||
 | 
							if (pgn == MENU_NO_PAGINATION)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* If we've filled up, then stop */
 | 
				
			||||||
 | 
								if (foundItems >= maxItems)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							/* If we're descending and this is the first item, stop */
 | 
				
			||||||
 | 
							if (order == ItemOrder_Descending)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (i == 0)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								i--;
 | 
				
			||||||
 | 
							} 
 | 
				
			||||||
 | 
							/* If we're ascending and this is the last item, stop */
 | 
				
			||||||
 | 
							else if (order == ItemOrder_Ascending)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (i >= totalItems - 1)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								i++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* There were no items to draw! */
 | 
				
			||||||
 | 
						if (!foundItems)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							delete display;
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Check initial buttons */
 | 
				
			||||||
 | 
						bool displayPrev = false;
 | 
				
			||||||
 | 
						bool displayNext = false;
 | 
				
			||||||
 | 
						if (foundExtra)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (order == ItemOrder_Descending)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								displayPrev = true;
 | 
				
			||||||
 | 
								md.firstItem = extraItem;
 | 
				
			||||||
 | 
							} else if (order == ItemOrder_Ascending) {
 | 
				
			||||||
 | 
								displayNext = true;
 | 
				
			||||||
 | 
								md.lastItem = extraItem;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * If we're paginated, we have to find if there is another page.
 | 
				
			||||||
 | 
						 * Sadly, the only way to do this is to try drawing more items!
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (pgn != MENU_NO_PAGINATION)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							unsigned int lastItem = 0;
 | 
				
			||||||
 | 
							ItemDrawInfo dr;
 | 
				
			||||||
 | 
							/* Find the last feasible item to search from. */
 | 
				
			||||||
 | 
							if (order == ItemOrder_Descending)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								lastItem = drawItems[0].position;
 | 
				
			||||||
 | 
								if (lastItem >= totalItems - 1)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									goto skip_search;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								while (++lastItem < totalItems)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (menu->GetItemInfo(lastItem, &dr) != NULL)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										mh->OnMenuDrawItem(menu, client, lastItem, dr.style);
 | 
				
			||||||
 | 
										if (IsSlotItem(display, dr.style))
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											displayNext = true;
 | 
				
			||||||
 | 
											md.lastItem = lastItem;
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else if (order == ItemOrder_Ascending) {
 | 
				
			||||||
 | 
								lastItem = drawItems[0].position;
 | 
				
			||||||
 | 
								if (lastItem == 0)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									goto skip_search;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								lastItem--;
 | 
				
			||||||
 | 
								while (lastItem-- != 0)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (menu->GetItemInfo(lastItem, &dr) != NULL)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										mh->OnMenuDrawItem(menu, client, lastItem, dr.style);
 | 
				
			||||||
 | 
										if (IsSlotItem(display, dr.style))
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											displayPrev = true;
 | 
				
			||||||
 | 
											md.firstItem = lastItem;
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					skip_search:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Draw the item according to the order */
 | 
				
			||||||
 | 
						menu_slots_t *slots = md.slots;
 | 
				
			||||||
 | 
						unsigned int position = 0;			/* Keep track of the last position */
 | 
				
			||||||
 | 
						if (order == ItemOrder_Ascending)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							for (unsigned int i=0; i<foundItems; i++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								ItemDrawInfo &dr = drawItems[i].draw;
 | 
				
			||||||
 | 
								menu->GetItemInfo(drawItems[i].position, &dr);
 | 
				
			||||||
 | 
								mh->OnMenuDisplayItem(menu, client, drawItems[i].position, &(dr.display));
 | 
				
			||||||
 | 
								if ((position = display->DrawItem(dr)) != 0)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									slots[position].item = drawItems[i].position;
 | 
				
			||||||
 | 
									slots[position].type = ItemSel_Item;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else if (order == ItemOrder_Descending) {
 | 
				
			||||||
 | 
							unsigned int i = foundItems;
 | 
				
			||||||
 | 
							/* NOTE: There will always be at least one item because
 | 
				
			||||||
 | 
							 * of the check earlier.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							while (i--)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								ItemDrawInfo &dr = drawItems[i].draw;
 | 
				
			||||||
 | 
								menu->GetItemInfo(drawItems[i].position, &dr);
 | 
				
			||||||
 | 
								mh->OnMenuDisplayItem(menu, client, drawItems[i].position, &(dr.display));
 | 
				
			||||||
 | 
								if ((position = display->DrawItem(dr)) != 0)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									slots[position].item = drawItems[i].position;
 | 
				
			||||||
 | 
									slots[position].type = ItemSel_Item;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Now, we need to check if we need to add anything extra */
 | 
				
			||||||
 | 
						if (pgn != MENU_NO_PAGINATION)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							bool canDrawDisabled = display->CanDrawItem(ITEMDRAW_DISABLED);
 | 
				
			||||||
 | 
							bool exitButton = menu->GetExitButton();
 | 
				
			||||||
 | 
							char text[50];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Calculate how many items we are allowed for control stuff */
 | 
				
			||||||
 | 
							unsigned int padding = style->GetMaxPageItems() - maxItems;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							/* Add the number of available slots */
 | 
				
			||||||
 | 
							padding += (maxItems - foundItems);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Someday, if we are able to re-enable this, we will be very lucky men. */
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
							if (!style->FeatureExists(MenuStyleFeature_ImplicitExit))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							/* Even if we don't draw an exit button, we invalidate the slot. */
 | 
				
			||||||
 | 
							padding--;
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								/* Otherwise, we don't draw anything and leave the slot available */
 | 
				
			||||||
 | 
								exitButton = false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Subtract two slots for the displayNext/displayPrev padding */
 | 
				
			||||||
 | 
							padding -= 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/**
 | 
				
			||||||
 | 
							 * We allow next/prev to be undrawn if neither exists.
 | 
				
			||||||
 | 
							 * Thus, we only need padding if one of them will be drawn,
 | 
				
			||||||
 | 
							 * or the exit button will be drawn.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							ItemDrawInfo padItem(NULL, ITEMDRAW_SPACER);
 | 
				
			||||||
 | 
							if (exitButton || (displayNext || displayPrev))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* Add spacers so we can pad to the end */
 | 
				
			||||||
 | 
								unsigned int null_pos = 0;
 | 
				
			||||||
 | 
								for (unsigned int i=0; i<padding; i++)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									position = display->DrawItem(padItem);
 | 
				
			||||||
 | 
									slots[position].type = ItemSel_None;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ItemDrawInfo dr(text, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* PREVIOUS */
 | 
				
			||||||
 | 
							if (displayPrev || canDrawDisabled)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								CorePlayerTranslate(client, text, sizeof(text), "Back", NULL);
 | 
				
			||||||
 | 
								dr.style = displayPrev ? 0 : ITEMDRAW_DISABLED;
 | 
				
			||||||
 | 
								position = display->DrawItem(dr);
 | 
				
			||||||
 | 
								slots[position].type = ItemSel_Back;
 | 
				
			||||||
 | 
							} else if ((displayNext || canDrawDisabled) || exitButton) {
 | 
				
			||||||
 | 
								/* If we can't display this, 
 | 
				
			||||||
 | 
								 * but there is a "next" or "exit" button, we need to pad!
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								position = display->DrawItem(padItem);
 | 
				
			||||||
 | 
								slots[position].type = ItemSel_None;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* NEXT */
 | 
				
			||||||
 | 
							if (displayNext || canDrawDisabled)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								CorePlayerTranslate(client, text, sizeof(text), "Next", NULL);
 | 
				
			||||||
 | 
								dr.style = displayNext ? 0 : ITEMDRAW_DISABLED;
 | 
				
			||||||
 | 
								position = display->DrawItem(dr);
 | 
				
			||||||
 | 
								slots[position].type = ItemSel_Next;
 | 
				
			||||||
 | 
							} else if (exitButton) {
 | 
				
			||||||
 | 
								/* If we can't display this,
 | 
				
			||||||
 | 
								 * but there is an exit button, we need to pad!
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								position = display->DrawItem(padItem);
 | 
				
			||||||
 | 
								slots[position].type = ItemSel_None;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* EXIT */
 | 
				
			||||||
 | 
							if (exitButton)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								CorePlayerTranslate(client, text, sizeof(text), "Exit", NULL);
 | 
				
			||||||
 | 
								dr.style = 0;
 | 
				
			||||||
 | 
								position = display->DrawItem(dr);
 | 
				
			||||||
 | 
								slots[position].type = ItemSel_Exit;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Lastly, fill in any slots we could have missed */
 | 
				
			||||||
 | 
						for (unsigned int i = position + 1; i < 10; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							slots[i].type = ItemSel_None;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Do title stuff */
 | 
				
			||||||
 | 
						mh->OnMenuDisplay(menu, client, display);
 | 
				
			||||||
 | 
						display->DrawTitle(menu->GetDefaultTitle(), true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return display;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int MenuManager::BroadcastMenu(IBaseMenu *menu, 
 | 
				
			||||||
 | 
															IMenuHandler *handler, 
 | 
				
			||||||
 | 
															int clients[], 
 | 
				
			||||||
 | 
															unsigned int numClients, 
 | 
				
			||||||
 | 
															unsigned int time)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						BroadcastHandler *bh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (m_BroadcastHandlers.empty())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							bh = new BroadcastHandler(handler);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							bh = m_BroadcastHandlers.front();
 | 
				
			||||||
 | 
							m_BroadcastHandlers.pop();
 | 
				
			||||||
 | 
							bh->m_pHandler = handler;
 | 
				
			||||||
 | 
							bh->numClients = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						handler->OnMenuStart(menu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned int total = 0;
 | 
				
			||||||
 | 
						for (unsigned int i=0; i<numClients; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/* Only continue if displaying works */
 | 
				
			||||||
 | 
							if (!menu->Display(clients[i], bh, time))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* :TODO: Allow sourcetv only, not all bots */
 | 
				
			||||||
 | 
							CPlayer *player = g_Players.GetPlayerByIndex(clients[i]);
 | 
				
			||||||
 | 
							if (player->IsFakeClient())
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							total++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!total)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/* End the broadcast here */
 | 
				
			||||||
 | 
							handler->OnMenuEnd(menu);
 | 
				
			||||||
 | 
							FreeBroadcastHandler(bh);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return total;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int MenuManager::VoteMenu(IBaseMenu *menu,
 | 
				
			||||||
 | 
													   IMenuVoteHandler *handler,
 | 
				
			||||||
 | 
													   int clients[],
 | 
				
			||||||
 | 
													   unsigned int numClients,
 | 
				
			||||||
 | 
													   unsigned int time)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						VoteHandler *vh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (m_VoteHandlers.empty())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							vh = new VoteHandler(handler);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							vh = m_VoteHandlers.front();
 | 
				
			||||||
 | 
							m_VoteHandlers.pop();
 | 
				
			||||||
 | 
							vh->m_pHandler = handler;
 | 
				
			||||||
 | 
							vh->numClients = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vh->Initialize(menu);
 | 
				
			||||||
 | 
						handler->OnMenuStart(menu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned int total = 0;
 | 
				
			||||||
 | 
						for (unsigned int i=0; i<numClients; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/* Only continue if displaying works */
 | 
				
			||||||
 | 
							if (!menu->Display(clients[i], vh, time))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* :TODO: Allow sourcetv only, not all bots */
 | 
				
			||||||
 | 
							CPlayer *player = g_Players.GetPlayerByIndex(clients[i]);
 | 
				
			||||||
 | 
							if (player->IsFakeClient())
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							total++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!total)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/* End the broadcast here */
 | 
				
			||||||
 | 
							handler->OnMenuEnd(menu);
 | 
				
			||||||
 | 
							FreeVoteHandler(vh);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return total;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MenuManager::FreeBroadcastHandler(BroadcastHandler *bh)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_BroadcastHandlers.push(bh);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MenuManager::FreeVoteHandler(VoteHandler *vh)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_VoteHandlers.push(vh);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					IMenuStyle *MenuManager::GetDefaultStyle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return m_pDefaultStyle;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										110
									
								
								core/MenuManager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								core/MenuManager.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,110 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * vim: set ts=4 :
 | 
				
			||||||
 | 
					 * ===============================================================
 | 
				
			||||||
 | 
					 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
 | 
				
			||||||
 | 
					 * ===============================================================
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This file is not open source and may not be copied without explicit
 | 
				
			||||||
 | 
					 * written permission of AlliedModders LLC.  This file may not be redistributed 
 | 
				
			||||||
 | 
					 * in whole or significant part.
 | 
				
			||||||
 | 
					 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Version: $Id$
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _INCLUDE_SOURCEMOD_MENUMANAGER_H_
 | 
				
			||||||
 | 
					#define _INCLUDE_SOURCEMOD_MENUMANAGER_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <IMenuManager.h>
 | 
				
			||||||
 | 
					#include <sh_vector.h>
 | 
				
			||||||
 | 
					#include <sh_stack.h>
 | 
				
			||||||
 | 
					#include <sh_list.h>
 | 
				
			||||||
 | 
					#include "sm_memtable.h"
 | 
				
			||||||
 | 
					#include "sm_globals.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace SourceMod;
 | 
				
			||||||
 | 
					using namespace SourceHook;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BroadcastHandler : public IMenuHandler
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						BroadcastHandler(IMenuHandler *handler);
 | 
				
			||||||
 | 
					public: //IMenuHandler
 | 
				
			||||||
 | 
						void OnMenuDisplay(IBaseMenu *menu, int client, IMenuDisplay *display);
 | 
				
			||||||
 | 
						void OnMenuSelect(IBaseMenu *menu, int client, unsigned int item);
 | 
				
			||||||
 | 
						void OnMenuEnd(IBaseMenu *menu);
 | 
				
			||||||
 | 
						void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason);
 | 
				
			||||||
 | 
						unsigned int GetMenuAPIVersion2();
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						virtual void OnBroadcastEnd(IBaseMenu *menu);
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						IMenuHandler *m_pHandler;
 | 
				
			||||||
 | 
						unsigned int numClients;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class VoteHandler : public BroadcastHandler
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						VoteHandler(IMenuVoteHandler *handler);
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						void Initialize(IBaseMenu *menu);
 | 
				
			||||||
 | 
						void OnMenuSelect(IBaseMenu *menu, int client, unsigned int item);
 | 
				
			||||||
 | 
						void OnBroadcastEnd(IBaseMenu *menu);
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						CVector<unsigned int> m_counts;
 | 
				
			||||||
 | 
						CVector<unsigned int> m_ties;
 | 
				
			||||||
 | 
						unsigned int numItems;
 | 
				
			||||||
 | 
						IMenuVoteHandler *m_pVoteHandler;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MenuManager : 
 | 
				
			||||||
 | 
						public IMenuManager,
 | 
				
			||||||
 | 
						public SMGlobalClass
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						friend class BroadcastHandler;
 | 
				
			||||||
 | 
						friend class VoteHandler;
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						MenuManager();
 | 
				
			||||||
 | 
					public: //SMGlobalClass
 | 
				
			||||||
 | 
						void OnSourceModAllInitialized();
 | 
				
			||||||
 | 
						void OnSourceModAllShutdown();
 | 
				
			||||||
 | 
					public: //IMenuManager
 | 
				
			||||||
 | 
						virtual const char *GetInterfaceName()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return SMINTERFACE_MENUMANAGER_NAME;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						virtual unsigned int GetInterfaceVersion()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return SMINTERFACE_MENUMANAGER_VERSION;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						unsigned int GetStyleCount();
 | 
				
			||||||
 | 
						IMenuStyle *GetStyle(unsigned int index);
 | 
				
			||||||
 | 
						IMenuStyle *FindStyleByName(const char *name);
 | 
				
			||||||
 | 
						unsigned int BroadcastMenu(IBaseMenu *menu, 
 | 
				
			||||||
 | 
							IMenuHandler *handler,
 | 
				
			||||||
 | 
							int clients[], 
 | 
				
			||||||
 | 
							unsigned int numClients,
 | 
				
			||||||
 | 
							unsigned int time);
 | 
				
			||||||
 | 
						unsigned int VoteMenu(IBaseMenu *menu, 
 | 
				
			||||||
 | 
							IMenuVoteHandler *handler,
 | 
				
			||||||
 | 
							int clients[], 
 | 
				
			||||||
 | 
							unsigned int numClients,
 | 
				
			||||||
 | 
							unsigned int time);
 | 
				
			||||||
 | 
						IMenuStyle *GetDefaultStyle();
 | 
				
			||||||
 | 
						bool SetDefaultStyle(IMenuStyle *style);
 | 
				
			||||||
 | 
						IMenuDisplay *RenderMenu(int client, menu_states_t &states, ItemOrder order);
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
						void FreeBroadcastHandler(BroadcastHandler *bh);
 | 
				
			||||||
 | 
						void FreeVoteHandler(VoteHandler *vh);
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						int m_ShowMenu;
 | 
				
			||||||
 | 
						IMenuStyle *m_pDefaultStyle;
 | 
				
			||||||
 | 
						CStack<BroadcastHandler *> m_BroadcastHandlers;
 | 
				
			||||||
 | 
						CStack<VoteHandler *> m_VoteHandlers;
 | 
				
			||||||
 | 
						CVector<IMenuStyle *> m_Styles;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern MenuManager g_Menus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //_INCLUDE_SOURCEMOD_MENUMANAGER_H_
 | 
				
			||||||
							
								
								
									
										162
									
								
								core/MenuStyle_Base.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								core/MenuStyle_Base.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,162 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * vim: set ts=4 :
 | 
				
			||||||
 | 
					 * ===============================================================
 | 
				
			||||||
 | 
					 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
 | 
				
			||||||
 | 
					 * ===============================================================
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This file is not open source and may not be copied without explicit
 | 
				
			||||||
 | 
					 * written permission of AlliedModders LLC.  This file may not be redistributed 
 | 
				
			||||||
 | 
					 * in whole or significant part.
 | 
				
			||||||
 | 
					 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Version: $Id$
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					#include "sm_stringutil.h"
 | 
				
			||||||
 | 
					#include "MenuStyle_Base.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CBaseMenu::CBaseMenu(IMenuStyle *pStyle) : 
 | 
				
			||||||
 | 
					m_pStyle(pStyle), m_Strings(512), m_Pagination(7), m_ExitButton(true)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CBaseMenu::~CBaseMenu()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CBaseMenu::AppendItem(const char *info, const ItemDrawInfo &draw)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (m_Pagination == MENU_NO_PAGINATION
 | 
				
			||||||
 | 
							&& m_items.size() >= m_pStyle->GetMaxPageItems())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						CItem item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						item.infoString = m_Strings.AddString(info);
 | 
				
			||||||
 | 
						if (draw.display)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							item.displayString = m_Strings.AddString(draw.display);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						item.style = draw.style;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						m_items.push_back(item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CBaseMenu::InsertItem(unsigned int position, const char *info, const ItemDrawInfo &draw)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (m_Pagination == MENU_NO_PAGINATION
 | 
				
			||||||
 | 
							&& m_items.size() >= m_pStyle->GetMaxPageItems())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (position >= m_items.size())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						CItem item;
 | 
				
			||||||
 | 
						item.infoString = m_Strings.AddString(info);
 | 
				
			||||||
 | 
						if (draw.display)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							item.displayString = m_Strings.AddString(draw.display);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						item.style = draw.style;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						CVector<CItem>::iterator iter = m_items.iterAt(position);
 | 
				
			||||||
 | 
						m_items.insert(iter, item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CBaseMenu::RemoveItem(unsigned int position)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (position >= m_items.size())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						m_items.erase(m_items.iterAt(position));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (m_items.size() == 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							m_Strings.Reset();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CBaseMenu::RemoveAllItems()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_items.clear();
 | 
				
			||||||
 | 
						m_Strings.Reset();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =NULL */)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (position >= m_items.size())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (draw)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							draw->display = m_Strings.GetString(m_items[position].displayString);
 | 
				
			||||||
 | 
							draw->style = m_items[position].style;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return m_Strings.GetString(m_items[position].infoString);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int CBaseMenu::GetItemCount()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return m_items.size();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CBaseMenu::SetPagination(unsigned int itemsPerPage)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (itemsPerPage > 7)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						m_Pagination = itemsPerPage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int CBaseMenu::GetPagination()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return m_Pagination;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					IMenuStyle *CBaseMenu::GetDrawStyle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return m_pStyle;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CBaseMenu::SetDefaultTitle(const char *message)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_Title.assign(message);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *CBaseMenu::GetDefaultTitle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return m_Title.c_str();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CBaseMenu::GetExitButton()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return m_ExitButton;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CBaseMenu::SetExitButton(bool set)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_ExitButton = set;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										69
									
								
								core/MenuStyle_Base.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								core/MenuStyle_Base.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * vim: set ts=4 :
 | 
				
			||||||
 | 
					 * ===============================================================
 | 
				
			||||||
 | 
					 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
 | 
				
			||||||
 | 
					 * ===============================================================
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This file is not open source and may not be copied without explicit
 | 
				
			||||||
 | 
					 * written permission of AlliedModders LLC.  This file may not be redistributed 
 | 
				
			||||||
 | 
					 * in whole or significant part.
 | 
				
			||||||
 | 
					 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Version: $Id$
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _INCLUDE_MENUSTYLE_BASE_H
 | 
				
			||||||
 | 
					#define _INCLUDE_MENUSTYLE_BASE_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <IMenuManager.h>
 | 
				
			||||||
 | 
					#include <sh_string.h>
 | 
				
			||||||
 | 
					#include <sh_vector.h>
 | 
				
			||||||
 | 
					#include "sm_memtable.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace SourceMod;
 | 
				
			||||||
 | 
					using namespace SourceHook;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CItem
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						CItem()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							infoString = -1;
 | 
				
			||||||
 | 
							displayString = -1;
 | 
				
			||||||
 | 
							style = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						int infoString;
 | 
				
			||||||
 | 
						int displayString;
 | 
				
			||||||
 | 
						unsigned int style;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CBaseMenu : public IBaseMenu
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						CBaseMenu(IMenuStyle *pStyle);
 | 
				
			||||||
 | 
						virtual ~CBaseMenu();
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						virtual bool AppendItem(const char *info, const ItemDrawInfo &draw);
 | 
				
			||||||
 | 
						virtual bool InsertItem(unsigned int position, const char *info, const ItemDrawInfo &draw);
 | 
				
			||||||
 | 
						virtual bool RemoveItem(unsigned int position);
 | 
				
			||||||
 | 
						virtual void RemoveAllItems();
 | 
				
			||||||
 | 
						virtual const char *GetItemInfo(unsigned int position, ItemDrawInfo *draw=NULL);
 | 
				
			||||||
 | 
						virtual unsigned int GetItemCount();
 | 
				
			||||||
 | 
						virtual bool SetPagination(unsigned int itemsPerPage);
 | 
				
			||||||
 | 
						virtual unsigned int GetPagination();
 | 
				
			||||||
 | 
						virtual IMenuStyle *GetDrawStyle();
 | 
				
			||||||
 | 
						virtual void SetDefaultTitle(const char *message);
 | 
				
			||||||
 | 
						virtual const char *GetDefaultTitle();
 | 
				
			||||||
 | 
						virtual bool GetExitButton();
 | 
				
			||||||
 | 
						virtual bool SetExitButton(bool set);
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
						String m_Title;
 | 
				
			||||||
 | 
						IMenuStyle *m_pStyle;
 | 
				
			||||||
 | 
						unsigned int m_Pagination;
 | 
				
			||||||
 | 
						CVector<CItem> m_items;
 | 
				
			||||||
 | 
						BaseStringTable m_Strings;
 | 
				
			||||||
 | 
						bool m_ExitButton;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //_INCLUDE_MENUSTYLE_BASE_H
 | 
				
			||||||
							
								
								
									
										796
									
								
								core/MenuStyle_Valve.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										796
									
								
								core/MenuStyle_Valve.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,796 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * vim: set ts=4 :
 | 
				
			||||||
 | 
					 * ===============================================================
 | 
				
			||||||
 | 
					 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
 | 
				
			||||||
 | 
					 * ===============================================================
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This file is not open source and may not be copied without explicit
 | 
				
			||||||
 | 
					 * written permission of AlliedModders LLC.  This file may not be redistributed 
 | 
				
			||||||
 | 
					 * in whole or significant part.
 | 
				
			||||||
 | 
					 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Version: $Id$
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "sm_stringutil.h"
 | 
				
			||||||
 | 
					#include "PlayerManager.h"
 | 
				
			||||||
 | 
					#include "MenuStyle_Valve.h"
 | 
				
			||||||
 | 
					#include "Translator.h"
 | 
				
			||||||
 | 
					#include "PlayerManager.h"
 | 
				
			||||||
 | 
					#include "ConCmdManager.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SH_DECL_HOOK4_void(IServerPluginHelpers, CreateMessage, SH_NOATTRIB, false, edict_t *, DIALOG_TYPE, KeyValues *, IServerPluginCallbacks *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ValveMenuStyle g_ValveMenuStyle;
 | 
				
			||||||
 | 
					const char *g_OptionNumTable[];
 | 
				
			||||||
 | 
					const char *g_OptionCmdTable[];
 | 
				
			||||||
 | 
					IServerPluginCallbacks *g_pVSPHandle = NULL;
 | 
				
			||||||
 | 
					CallClass<IServerPluginHelpers> *g_pSPHCC = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestHandler : public IMenuHandler
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						virtual void OnMenuEnd(IBaseMenu *menu)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							menu->Destroy();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ValveMenuStyle::ValveMenuStyle() : m_players(new CValveMenuPlayer[256+1]), m_WatchList(256)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool ValveMenuStyle::OnClientCommand(int client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const char *cmd = engine->Cmd_Argv(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (strcmp(cmd, "sm_vmenuselect") == 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							int key_press = atoi(engine->Cmd_Argv(1));
 | 
				
			||||||
 | 
							g_ValveMenuStyle.ClientPressedKey(client, key_press);
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (strcmp(cmd, "sm_test") == 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							IBaseMenu *menu = g_ValveMenuStyle.CreateMenu();
 | 
				
			||||||
 | 
							menu->AppendItem("test1", ItemDrawInfo("Test #1", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test2", ItemDrawInfo("Test #2", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test3", ItemDrawInfo("Test #3", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test4", ItemDrawInfo("Test #4", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test5", ItemDrawInfo("Test #5", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test6", ItemDrawInfo("Test #6", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test7", ItemDrawInfo("Test #7", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test8", ItemDrawInfo("Test #8", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test9", ItemDrawInfo("Test #9", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test10", ItemDrawInfo("Test #10", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test11", ItemDrawInfo("Test #11", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test12", ItemDrawInfo("Test #12", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test13", ItemDrawInfo("Test #13", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test14", ItemDrawInfo("Test #14", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test15", ItemDrawInfo("Test #15", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test16", ItemDrawInfo("Test #16", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test17", ItemDrawInfo("Test #17", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test18", ItemDrawInfo("Test #18", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test19", ItemDrawInfo("Test #19", 0));
 | 
				
			||||||
 | 
							menu->AppendItem("test20", ItemDrawInfo("Test #20", 0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							menu->Display(client, new TestHandler, 20);
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						} else if (strcmp(cmd, "gaben") == 0) {
 | 
				
			||||||
 | 
							KeyValues *kv = new KeyValues("menu");
 | 
				
			||||||
 | 
							kv->SetString("msg", "hi");
 | 
				
			||||||
 | 
							serverpluginhelpers->CreateMessage(engine->PEntityOfEntIndex(client), DIALOG_MENU, kv, g_pVSPHandle);
 | 
				
			||||||
 | 
							kv->deleteThis();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValveMenuStyle::OnSourceModAllInitialized()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						g_Players.AddClientListener(this);
 | 
				
			||||||
 | 
						SH_ADD_HOOK_MEMFUNC(IServerPluginHelpers, CreateMessage, serverpluginhelpers, this, &ValveMenuStyle::HookCreateMessage, false);
 | 
				
			||||||
 | 
						g_pSPHCC = SH_GET_CALLCLASS(serverpluginhelpers);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValveMenuStyle::OnSourceModShutdown()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						SH_RELEASE_CALLCLASS(g_pSPHCC);
 | 
				
			||||||
 | 
						SH_REMOVE_HOOK_MEMFUNC(IServerPluginHelpers, CreateMessage, serverpluginhelpers, this, &ValveMenuStyle::HookCreateMessage, false);
 | 
				
			||||||
 | 
						g_Players.RemoveClientListener(this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValveMenuStyle::OnClientDisconnected(int client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						CValveMenuPlayer *player = &m_players[client];
 | 
				
			||||||
 | 
						if (!player->bInMenu)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						menu_states_t &states = player->states;
 | 
				
			||||||
 | 
						states.mh->OnMenuCancel(states.menu, client, MenuCancel_Disconnect);
 | 
				
			||||||
 | 
						states.mh->OnMenuEnd(states.menu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (player->menuHoldTime)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							m_WatchList.remove(client);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						player->bInMenu = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValveMenuStyle::HookCreateMessage(edict_t *pEdict,
 | 
				
			||||||
 | 
														   DIALOG_TYPE type,
 | 
				
			||||||
 | 
														   KeyValues *kv,
 | 
				
			||||||
 | 
														   IServerPluginCallbacks *plugin)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (type != DIALOG_MENU)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int client = engine->IndexOfEdict(pEdict);
 | 
				
			||||||
 | 
						if (client < 1 || client > 256)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						CValveMenuPlayer *player = &m_players[client];
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						/* We don't care if the player is in a menu because, for all intents and purposes,
 | 
				
			||||||
 | 
						 * the menu is completely private.  Instead, we just figure out the level we'll need
 | 
				
			||||||
 | 
						 * in order to override it.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						player->curPrioLevel = kv->GetInt("level", player->curPrioLevel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Oh no! What happens if we got a menu that overwrites ours?! */
 | 
				
			||||||
 | 
						if (player->bInMenu)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/* Okay, let the external menu survive for now.  It may live another 
 | 
				
			||||||
 | 
							 * day to avenge its grandfather, killed in the great Menu Interruption
 | 
				
			||||||
 | 
							 * battle.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							_CancelMenu(client, true);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValveMenuStyle::OnSourceModVSPReceived(IServerPluginCallbacks *iface)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						g_pVSPHandle = iface;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					IMenuDisplay *ValveMenuStyle::CreateDisplay()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return new CValveMenuDisplay();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					IBaseMenu *ValveMenuStyle::CreateMenu()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return new CValveMenu();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *ValveMenuStyle::GetStyleName()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return "valve";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int ValveMenuStyle::GetMaxPageItems()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return 8;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int do_lookup[256];
 | 
				
			||||||
 | 
					void ValveMenuStyle::ProcessWatchList()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!m_WatchList.size())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FastLink<int>::iterator iter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned int total = 0;
 | 
				
			||||||
 | 
						for (iter=m_WatchList.begin(); iter!=m_WatchList.end(); ++iter)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							do_lookup[total++] = (*iter);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int client;
 | 
				
			||||||
 | 
						CValveMenuPlayer *player;
 | 
				
			||||||
 | 
						float curTime = gpGlobals->curtime;
 | 
				
			||||||
 | 
						for (unsigned int i=0; i<total; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							client = do_lookup[i];
 | 
				
			||||||
 | 
							player = &m_players[client];
 | 
				
			||||||
 | 
							if (!player->bInMenu || !player->menuHoldTime)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								m_WatchList.remove(i);
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (curTime > player->menuStartTime + player->menuHoldTime)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								_CancelMenu(i, false);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValveMenuStyle::_CancelMenu(int client, bool bAutoIgnore)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						CValveMenuPlayer *player = &m_players[client];
 | 
				
			||||||
 | 
						menu_states_t &states = player->states;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool bOldIgnore = player->bAutoIgnore;
 | 
				
			||||||
 | 
						if (bAutoIgnore)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							player->bAutoIgnore = true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Save states */
 | 
				
			||||||
 | 
						IMenuHandler *mh = states.mh;
 | 
				
			||||||
 | 
						IBaseMenu *menu = states.menu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Clear menu */
 | 
				
			||||||
 | 
						player->bInMenu = false;
 | 
				
			||||||
 | 
						if (player->menuHoldTime)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							m_WatchList.remove(client);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Fire callbacks */
 | 
				
			||||||
 | 
						mh->OnMenuCancel(menu, client, MenuCancel_Interrupt);
 | 
				
			||||||
 | 
						mh->OnMenuEnd(menu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (bAutoIgnore)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							player->bAutoIgnore = bOldIgnore;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValveMenuStyle::CancelMenu(CValveMenu *menu)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int maxClients = g_Players.GetMaxClients();
 | 
				
			||||||
 | 
						for (int i=1; i<=maxClients; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (m_players[i].bInMenu)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								menu_states_t &states = m_players[i].states;
 | 
				
			||||||
 | 
								if (states.menu == menu)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									_CancelMenu(i);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool ValveMenuStyle::CancelClientMenu(int client, bool autoIgnore)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (client < 1 || client > 256 || !m_players[client].bInMenu)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_CancelMenu(client, autoIgnore);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ValveMenuStyle::ClientPressedKey(int client, unsigned int key_press)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						CValveMenuPlayer *player = &m_players[client];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* First question: Are we in a menu? */
 | 
				
			||||||
 | 
						if (!player->bInMenu)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool cancel = false;
 | 
				
			||||||
 | 
						unsigned int item = 0;
 | 
				
			||||||
 | 
						MenuCancelReason reason = MenuCancel_Exit;
 | 
				
			||||||
 | 
						menu_states_t &states = player->states;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert(states.mh != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (states.menu == NULL)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							item = key_press;
 | 
				
			||||||
 | 
						} else if (key_press < 1 ||  key_press > 8) {
 | 
				
			||||||
 | 
							cancel = true;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							ItemSelection type = states.slots[key_press].type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* For navigational items, we're going to redisplay */
 | 
				
			||||||
 | 
							if (type == ItemSel_Back)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (!RedoClientMenu(client, ItemOrder_Descending))
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									cancel = true;
 | 
				
			||||||
 | 
									reason = MenuCancel_NoDisplay;
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else if (type == ItemSel_Next) {
 | 
				
			||||||
 | 
								if (!RedoClientMenu(client, ItemOrder_Ascending))
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									cancel = true;						/* I like Saltines. */
 | 
				
			||||||
 | 
									reason = MenuCancel_NoDisplay;
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else if (type == ItemSel_Exit || type == ItemSel_None) {
 | 
				
			||||||
 | 
								cancel = true;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								item = states.slots[key_press].item;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Save variables */
 | 
				
			||||||
 | 
						IMenuHandler *mh = states.mh;
 | 
				
			||||||
 | 
						IBaseMenu *menu = states.menu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Clear states */
 | 
				
			||||||
 | 
						player->bInMenu = false;
 | 
				
			||||||
 | 
						if (player->menuHoldTime)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							m_WatchList.remove(client);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cancel)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							mh->OnMenuCancel(menu, client, reason);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							mh->OnMenuSelect(menu, client, item);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mh->OnMenuEnd(menu);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool ValveMenuStyle::DoClientMenu(int client, CValveMenuDisplay *menu, IMenuHandler *mh, unsigned int time)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!g_pVSPHandle || !mh)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
 | 
				
			||||||
 | 
						if (!pPlayer || pPlayer->IsFakeClient() || !pPlayer->IsInGame())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						CValveMenuPlayer *player = &m_players[client];
 | 
				
			||||||
 | 
						if (player->bAutoIgnore)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* For the duration of this, we are going to totally ignore whether
 | 
				
			||||||
 | 
						 * the player is already in a menu or not (except to cancel the old one).
 | 
				
			||||||
 | 
						 * Instead, we are simply going to ignore any further menu displays, so
 | 
				
			||||||
 | 
						 * this display can't be interrupted.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						player->bAutoIgnore = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Cancel any old menus */
 | 
				
			||||||
 | 
						menu_states_t &states = player->states;
 | 
				
			||||||
 | 
						if (player->bInMenu)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/* We need to cancel the old menu */
 | 
				
			||||||
 | 
							if (player->menuHoldTime)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								m_WatchList.remove(client);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							states.mh->OnMenuCancel(states.menu, client, MenuCancel_Interrupt);
 | 
				
			||||||
 | 
							states.mh->OnMenuEnd(states.menu);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						states.firstItem = 0;
 | 
				
			||||||
 | 
						states.lastItem = 0;
 | 
				
			||||||
 | 
						states.menu = NULL;
 | 
				
			||||||
 | 
						states.mh = mh;
 | 
				
			||||||
 | 
						states.apiVers = SMINTERFACE_MENUMANAGER_VERSION;
 | 
				
			||||||
 | 
						player->curPrioLevel--;
 | 
				
			||||||
 | 
						player->bInMenu = true;
 | 
				
			||||||
 | 
						player->menuStartTime = gpGlobals->curtime;
 | 
				
			||||||
 | 
						player->menuHoldTime = time;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (time)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							m_WatchList.push_back(client);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Draw the display */
 | 
				
			||||||
 | 
						menu->SendRawDisplay(client, player->curPrioLevel, time);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* We can be interrupted again! */
 | 
				
			||||||
 | 
						player->bAutoIgnore = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool ValveMenuStyle::DoClientMenu(int client, CValveMenu *menu, IMenuHandler *mh, unsigned int time)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						mh->OnMenuStart(menu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!g_pVSPHandle || !mh)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay);
 | 
				
			||||||
 | 
							mh->OnMenuEnd(menu);
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
 | 
				
			||||||
 | 
						if (!pPlayer || pPlayer->IsFakeClient() || !pPlayer->IsInGame())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay);
 | 
				
			||||||
 | 
							mh->OnMenuEnd(menu);
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						CValveMenuPlayer *player = &m_players[client];
 | 
				
			||||||
 | 
						if (player->bAutoIgnore)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay);
 | 
				
			||||||
 | 
							mh->OnMenuEnd(menu);
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* For the duration of this, we are going to totally ignore whether
 | 
				
			||||||
 | 
						 * the player is already in a menu or not (except to cancel the old one).
 | 
				
			||||||
 | 
						 * Instead, we are simply going to ignore any further menu displays, so
 | 
				
			||||||
 | 
						 * this display can't be interrupted.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						player->bAutoIgnore = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Cancel any old menus */
 | 
				
			||||||
 | 
						menu_states_t &states = player->states;
 | 
				
			||||||
 | 
						if (player->bInMenu)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/* We need to cancel the old menu */
 | 
				
			||||||
 | 
							if (player->menuHoldTime)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								m_WatchList.remove(client);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							states.mh->OnMenuCancel(states.menu, client, MenuCancel_Interrupt);
 | 
				
			||||||
 | 
							states.mh->OnMenuEnd(states.menu);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						states.firstItem = 0;
 | 
				
			||||||
 | 
						states.lastItem = 0;
 | 
				
			||||||
 | 
						states.menu = menu;
 | 
				
			||||||
 | 
						states.mh = mh;
 | 
				
			||||||
 | 
						states.apiVers = SMINTERFACE_MENUMANAGER_VERSION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						IMenuDisplay *display = g_Menus.RenderMenu(client, states, ItemOrder_Ascending);
 | 
				
			||||||
 | 
						if (!display)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							player->bAutoIgnore = false;
 | 
				
			||||||
 | 
							player->bInMenu = false;
 | 
				
			||||||
 | 
							mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay);
 | 
				
			||||||
 | 
							mh->OnMenuEnd(menu);
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Finally, set our states */
 | 
				
			||||||
 | 
						player->curPrioLevel--;
 | 
				
			||||||
 | 
						player->bInMenu = true;
 | 
				
			||||||
 | 
						player->menuStartTime = gpGlobals->curtime;
 | 
				
			||||||
 | 
						player->menuHoldTime = time;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (time)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							m_WatchList.push_back(client);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Draw the display */
 | 
				
			||||||
 | 
						CValveMenuDisplay *vDisplay = (CValveMenuDisplay *)display;
 | 
				
			||||||
 | 
						vDisplay->SendRawDisplay(client, player->curPrioLevel, time);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Free the display pointer */
 | 
				
			||||||
 | 
						delete display;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* We can be interrupted again! */
 | 
				
			||||||
 | 
						player->bAutoIgnore = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool ValveMenuStyle::RedoClientMenu(int client, ItemOrder order)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						CValveMenuPlayer *player = &m_players[client];
 | 
				
			||||||
 | 
						menu_states_t &states = player->states;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						player->bAutoIgnore = true;
 | 
				
			||||||
 | 
						IMenuDisplay *display = g_Menus.RenderMenu(client, states, order);
 | 
				
			||||||
 | 
						if (!display)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (player->menuHoldTime)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								m_WatchList.remove(client);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							player->bAutoIgnore = false;
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						CValveMenuDisplay *vDisplay = (CValveMenuDisplay *)display;
 | 
				
			||||||
 | 
						vDisplay->SendRawDisplay(client, --player->curPrioLevel, player->menuHoldTime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						delete display;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						player->bAutoIgnore = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MenuSource ValveMenuStyle::GetClientMenu(int client, void **object)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (client < 1 || client > 256 || !m_players[client].bInMenu)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return MenuSource_None;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						IBaseMenu *menu;
 | 
				
			||||||
 | 
						if ((menu=m_players[client].states.menu) != NULL)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (object)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*object = menu;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return MenuSource_BaseMenu;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return MenuSource_Display;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CValveMenuDisplay::CValveMenuDisplay()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_pKv = NULL;
 | 
				
			||||||
 | 
						Reset();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CValveMenuDisplay::CValveMenuDisplay(CValveMenu *pMenu)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_pKv = NULL;
 | 
				
			||||||
 | 
						Reset();
 | 
				
			||||||
 | 
						m_pKv->SetColor("color", pMenu->m_IntroColor);
 | 
				
			||||||
 | 
						m_pKv->SetString("title", pMenu->m_IntroMsg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CValveMenuDisplay::~CValveMenuDisplay()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_pKv->deleteThis();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					IMenuStyle *CValveMenuDisplay::GetParentStyle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return &g_ValveMenuStyle;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CValveMenuDisplay::Reset()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (m_pKv)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							m_pKv->deleteThis();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						m_pKv = new KeyValues("menu");
 | 
				
			||||||
 | 
						m_NextPos = 1;
 | 
				
			||||||
 | 
						m_TitleDrawn = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CValveMenuDisplay::SetExtOption(MenuOption option, const void *valuePtr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (option == MenuOption_IntroMessage)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							m_pKv->SetString("title", (const char *)valuePtr);
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						} else if (option == MenuOption_IntroColor) {
 | 
				
			||||||
 | 
							int *array = (int *)valuePtr;
 | 
				
			||||||
 | 
							m_pKv->SetColor("color", Color(array[0], array[1], array[2], array[3]));
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CValveMenuDisplay::CanDrawItem(unsigned int drawFlags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * ITEMDRAW_RAWLINE - We can't draw random text, and this doesn't add a slot,
 | 
				
			||||||
 | 
						 *  so it's completely safe to ignore it.
 | 
				
			||||||
 | 
						 * -----------------------------------------
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (drawFlags & ITEMDRAW_RAWLINE)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Special cases, explained in DrawItem()
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if ((drawFlags & ITEMDRAW_NOTEXT)
 | 
				
			||||||
 | 
							|| (drawFlags & ITEMDRAW_SPACER))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * We can't draw disabled text.  We could bump the position, but we
 | 
				
			||||||
 | 
						 * want DirectDraw() to find some actual items to display.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (drawFlags & ITEMDRAW_DISABLED)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int CValveMenuDisplay::DrawItem(const ItemDrawInfo &item)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (m_NextPos > 9 || !CanDrawItem(item.style))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * For these cases we can't draw anything at all, but
 | 
				
			||||||
 | 
						 * we can at least bump the position since we were explicitly asked to.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if ((item.style & ITEMDRAW_NOTEXT)
 | 
				
			||||||
 | 
							|| (item.style & ITEMDRAW_SPACER))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_NextPos++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char buffer[255];
 | 
				
			||||||
 | 
						UTIL_Format(buffer, sizeof(buffer), "%d. %s", m_NextPos, item.display);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						KeyValues *ki = m_pKv->FindKey(g_OptionNumTable[m_NextPos], true);
 | 
				
			||||||
 | 
						ki->SetString("command", g_OptionCmdTable[m_NextPos]);
 | 
				
			||||||
 | 
						ki->SetString("msg", buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return m_NextPos++;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CValveMenuDisplay::DrawTitle(const char *text, bool onlyIfEmpty/* =false */)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (onlyIfEmpty && m_TitleDrawn)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						m_pKv->SetString("msg", text);
 | 
				
			||||||
 | 
						m_TitleDrawn = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CValveMenuDisplay::DrawRawLine(const char *rawline)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CValveMenuDisplay::SendRawDisplay(int client, int priority, unsigned int time)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_pKv->SetInt("level", priority);
 | 
				
			||||||
 | 
						m_pKv->SetInt("time", time);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SH_CALL(g_pSPHCC, &IServerPluginHelpers::CreateMessage)(
 | 
				
			||||||
 | 
							engine->PEntityOfEntIndex(client),
 | 
				
			||||||
 | 
							DIALOG_MENU,
 | 
				
			||||||
 | 
							m_pKv,
 | 
				
			||||||
 | 
							g_pVSPHandle);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CValveMenuDisplay::SendDisplay(int client, IMenuHandler *handler, unsigned int time)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return g_ValveMenuStyle.DoClientMenu(client, this, handler, time);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CValveMenu::CValveMenu() : CBaseMenu(&g_ValveMenuStyle), 
 | 
				
			||||||
 | 
						m_IntroColor(255, 0, 0, 255), m_bShouldDelete(false), m_bCancelling(false)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						strcpy(m_IntroMsg, "You have a menu, press ESC");
 | 
				
			||||||
 | 
						m_Pagination = 5;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CValveMenu::Cancel()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (m_bCancelling)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						m_bCancelling = true;
 | 
				
			||||||
 | 
						g_ValveMenuStyle.CancelMenu(this);
 | 
				
			||||||
 | 
						m_bCancelling = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (m_bShouldDelete)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							delete this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CValveMenu::Destroy()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!m_bCancelling || m_bShouldDelete)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							Cancel();
 | 
				
			||||||
 | 
							delete this;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							m_bShouldDelete = true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CValveMenu::SetPagination(unsigned int itemsPerPage)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (itemsPerPage < 1 || itemsPerPage > 5)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						CBaseMenu::SetPagination(itemsPerPage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CValveMenu::SetExtOption(MenuOption option, const void *valuePtr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (option == MenuOption_IntroMessage)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							strncopy(m_IntroMsg, (const char *)valuePtr, sizeof(m_IntroMsg));
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						} else if (option == MenuOption_IntroColor) {
 | 
				
			||||||
 | 
							unsigned int *array = (unsigned int *)valuePtr;
 | 
				
			||||||
 | 
							m_IntroColor = Color(array[0], array[1], array[2], array[3]);
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CValveMenu::Display(int client, IMenuHandler *handler, unsigned int time)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (m_bCancelling)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return g_ValveMenuStyle.DoClientMenu(client, this, handler, time);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					IMenuDisplay *CValveMenu::CreateDisplay()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return new CValveMenuDisplay(this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CValveMenu::GetExitButton()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CValveMenu::SetExitButton(bool set)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *g_OptionNumTable[11] = 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *g_OptionCmdTable[11] = 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						"sm_vmenuselect 0", /* INVALID! */
 | 
				
			||||||
 | 
						"sm_vmenuselect 1",
 | 
				
			||||||
 | 
						"sm_vmenuselect 2",
 | 
				
			||||||
 | 
						"sm_vmenuselect 3",
 | 
				
			||||||
 | 
						"sm_vmenuselect 4",
 | 
				
			||||||
 | 
						"sm_vmenuselect 5",
 | 
				
			||||||
 | 
						"sm_vmenuselect 6",
 | 
				
			||||||
 | 
						"sm_vmenuselect 7",
 | 
				
			||||||
 | 
						"sm_vmenuselect 8",
 | 
				
			||||||
 | 
						"sm_vmenuselect 9",
 | 
				
			||||||
 | 
						"sm_vmenuselect 10"
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										127
									
								
								core/MenuStyle_Valve.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								core/MenuStyle_Valve.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,127 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * vim: set ts=4 :
 | 
				
			||||||
 | 
					 * ===============================================================
 | 
				
			||||||
 | 
					 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
 | 
				
			||||||
 | 
					 * ===============================================================
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This file is not open source and may not be copied without explicit
 | 
				
			||||||
 | 
					 * written permission of AlliedModders LLC.  This file may not be redistributed 
 | 
				
			||||||
 | 
					 * in whole or significant part.
 | 
				
			||||||
 | 
					 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Version: $Id$
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _INCLUDE_MENUSTYLE_VALVE_H
 | 
				
			||||||
 | 
					#define _INCLUDE_MENUSTYLE_VALVE_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "sm_globals.h"
 | 
				
			||||||
 | 
					#include "MenuManager.h"
 | 
				
			||||||
 | 
					#include "MenuStyle_Base.h"
 | 
				
			||||||
 | 
					#include "sourcemm_api.h"
 | 
				
			||||||
 | 
					#include "KeyValues.h"
 | 
				
			||||||
 | 
					#include <IPlayerHelpers.h>
 | 
				
			||||||
 | 
					#include "sm_fastlink.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace SourceMod;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CValveMenuPlayer
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						CValveMenuPlayer() : bInMenu(false), bAutoIgnore(false), curPrioLevel(1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						menu_states_t states;
 | 
				
			||||||
 | 
						bool bInMenu;
 | 
				
			||||||
 | 
						bool bAutoIgnore;
 | 
				
			||||||
 | 
						int curPrioLevel;
 | 
				
			||||||
 | 
						float menuStartTime;
 | 
				
			||||||
 | 
						unsigned int menuHoldTime;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CValveMenu;
 | 
				
			||||||
 | 
					class CValveMenuDisplay;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ValveMenuStyle : 
 | 
				
			||||||
 | 
						public SMGlobalClass,
 | 
				
			||||||
 | 
						public IMenuStyle,
 | 
				
			||||||
 | 
						public IClientListener
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						ValveMenuStyle();
 | 
				
			||||||
 | 
						bool DoClientMenu(int client, CValveMenu *menu, IMenuHandler *mh, unsigned int time);
 | 
				
			||||||
 | 
						bool DoClientMenu(int client, CValveMenuDisplay *menu, IMenuHandler *mh, unsigned int time);
 | 
				
			||||||
 | 
						void ClientPressedKey(int client, unsigned int key_press);
 | 
				
			||||||
 | 
						bool OnClientCommand(int client);
 | 
				
			||||||
 | 
						void CancelMenu(CValveMenu *menu);
 | 
				
			||||||
 | 
						void ProcessWatchList();
 | 
				
			||||||
 | 
					public: //SMGlobalClass
 | 
				
			||||||
 | 
						void OnSourceModAllInitialized();
 | 
				
			||||||
 | 
						void OnSourceModShutdown();
 | 
				
			||||||
 | 
						void OnSourceModVSPReceived(IServerPluginCallbacks *iface);
 | 
				
			||||||
 | 
					public: //IClientListener
 | 
				
			||||||
 | 
						void OnClientDisconnected(int client);
 | 
				
			||||||
 | 
					public: //IMenuStyle
 | 
				
			||||||
 | 
						const char *GetStyleName();
 | 
				
			||||||
 | 
						IMenuDisplay *CreateDisplay();
 | 
				
			||||||
 | 
						IBaseMenu *CreateMenu();
 | 
				
			||||||
 | 
						unsigned int GetMaxPageItems();
 | 
				
			||||||
 | 
						MenuSource GetClientMenu(int client, void **object);
 | 
				
			||||||
 | 
						bool CancelClientMenu(int client, bool autoIgnore=false);
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						bool RedoClientMenu(int client, ItemOrder order);
 | 
				
			||||||
 | 
						void HookCreateMessage(edict_t *pEdict, DIALOG_TYPE type, KeyValues *kv, IServerPluginCallbacks *plugin);
 | 
				
			||||||
 | 
						void _CancelMenu(int client, bool bAutoIgnore=false);
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						CValveMenuPlayer *m_players;
 | 
				
			||||||
 | 
						FastLink<int> m_WatchList;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CValveMenu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CValveMenuDisplay : public IMenuDisplay
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						CValveMenuDisplay();
 | 
				
			||||||
 | 
						CValveMenuDisplay(CValveMenu *pMenu);
 | 
				
			||||||
 | 
						~CValveMenuDisplay();
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						IMenuStyle *GetParentStyle();
 | 
				
			||||||
 | 
						void Reset();
 | 
				
			||||||
 | 
						void DrawTitle(const char *text, bool onlyIfEmpty=false);
 | 
				
			||||||
 | 
						unsigned int DrawItem(const ItemDrawInfo &item);
 | 
				
			||||||
 | 
						bool DrawRawLine(const char *rawline);
 | 
				
			||||||
 | 
						bool SendDisplay(int client, IMenuHandler *handler, unsigned int time);
 | 
				
			||||||
 | 
						bool SetExtOption(MenuOption option, const void *valuePtr);
 | 
				
			||||||
 | 
						bool CanDrawItem(unsigned int drawFlags);
 | 
				
			||||||
 | 
						void SendRawDisplay(int client, int priority, unsigned int time);
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						KeyValues *m_pKv;
 | 
				
			||||||
 | 
						unsigned int m_NextPos;
 | 
				
			||||||
 | 
						bool m_TitleDrawn;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CValveMenu : public CBaseMenu
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						friend class CValveMenuDisplay;
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						CValveMenu();
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						bool SetExtOption(MenuOption option, const void *valuePtr);
 | 
				
			||||||
 | 
						IMenuDisplay *CreateDisplay();
 | 
				
			||||||
 | 
						bool GetExitButton();
 | 
				
			||||||
 | 
						bool SetExitButton(bool set);
 | 
				
			||||||
 | 
						bool SetPagination(unsigned int itemsPerPage);
 | 
				
			||||||
 | 
						bool Display(int client, IMenuHandler *handler, unsigned int time);
 | 
				
			||||||
 | 
						void Cancel();
 | 
				
			||||||
 | 
						void Destroy();
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						Color m_IntroColor;
 | 
				
			||||||
 | 
						char m_IntroMsg[128];
 | 
				
			||||||
 | 
						bool m_bCancelling;
 | 
				
			||||||
 | 
						bool m_bShouldDelete;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern ValveMenuStyle g_ValveMenuStyle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //_INCLUDE_MENUSTYLE_VALVE_H
 | 
				
			||||||
@ -17,6 +17,7 @@
 | 
				
			|||||||
#include "ShareSys.h"
 | 
					#include "ShareSys.h"
 | 
				
			||||||
#include "AdminCache.h"
 | 
					#include "AdminCache.h"
 | 
				
			||||||
#include "ConCmdManager.h"
 | 
					#include "ConCmdManager.h"
 | 
				
			||||||
 | 
					#include "MenuStyle_Valve.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PlayerManager g_Players;
 | 
					PlayerManager g_Players;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -398,6 +399,12 @@ void PlayerManager::OnClientCommand(edict_t *pEntity)
 | 
				
			|||||||
		RETURN_META(MRES_SUPERCEDE);
 | 
							RETURN_META(MRES_SUPERCEDE);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool result = g_ValveMenuStyle.OnClientCommand(client);
 | 
				
			||||||
 | 
						if (result)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							res = Pl_Handled;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res = g_ConCmds.DispatchClientCommand(client, (ResultType)res);
 | 
						res = g_ConCmds.DispatchClientCommand(client, (ResultType)res);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (res >= Pl_Handled)
 | 
						if (res >= Pl_Handled)
 | 
				
			||||||
 | 
				
			|||||||
@ -227,6 +227,18 @@
 | 
				
			|||||||
				RelativePath="..\MemoryUtils.cpp"
 | 
									RelativePath="..\MemoryUtils.cpp"
 | 
				
			||||||
				>
 | 
									>
 | 
				
			||||||
			</File>
 | 
								</File>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath="..\MenuManager.cpp"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath="..\MenuStyle_Base.cpp"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath="..\MenuStyle_Valve.cpp"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
			<File
 | 
								<File
 | 
				
			||||||
				RelativePath="..\PlayerManager.cpp"
 | 
									RelativePath="..\PlayerManager.cpp"
 | 
				
			||||||
				>
 | 
									>
 | 
				
			||||||
@ -333,6 +345,18 @@
 | 
				
			|||||||
				RelativePath="..\MemoryUtils.h"
 | 
									RelativePath="..\MemoryUtils.h"
 | 
				
			||||||
				>
 | 
									>
 | 
				
			||||||
			</File>
 | 
								</File>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath="..\MenuManager.h"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath="..\MenuStyle_Base.h"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath="..\MenuStyle_Valve.h"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
			<File
 | 
								<File
 | 
				
			||||||
				RelativePath="..\PlayerManager.h"
 | 
									RelativePath="..\PlayerManager.h"
 | 
				
			||||||
				>
 | 
									>
 | 
				
			||||||
@ -341,6 +365,10 @@
 | 
				
			|||||||
				RelativePath="..\sm_autonatives.h"
 | 
									RelativePath="..\sm_autonatives.h"
 | 
				
			||||||
				>
 | 
									>
 | 
				
			||||||
			</File>
 | 
								</File>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath="..\sm_fastlink.h"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
			<File
 | 
								<File
 | 
				
			||||||
				RelativePath="..\sm_globals.h"
 | 
									RelativePath="..\sm_globals.h"
 | 
				
			||||||
				>
 | 
									>
 | 
				
			||||||
@ -438,6 +466,10 @@
 | 
				
			|||||||
				RelativePath="..\..\public\IMemoryUtils.h"
 | 
									RelativePath="..\..\public\IMemoryUtils.h"
 | 
				
			||||||
				>
 | 
									>
 | 
				
			||||||
			</File>
 | 
								</File>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath="..\..\public\IMenuManager.h"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
			<File
 | 
								<File
 | 
				
			||||||
				RelativePath="..\..\public\IPlayerHelpers.h"
 | 
									RelativePath="..\..\public\IPlayerHelpers.h"
 | 
				
			||||||
				>
 | 
									>
 | 
				
			||||||
 | 
				
			|||||||
@ -29,6 +29,7 @@
 | 
				
			|||||||
#include "Translator.h"
 | 
					#include "Translator.h"
 | 
				
			||||||
#include "ForwardSys.h"
 | 
					#include "ForwardSys.h"
 | 
				
			||||||
#include "TimerSys.h"
 | 
					#include "TimerSys.h"
 | 
				
			||||||
 | 
					#include "MenuStyle_Valve.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool);
 | 
					SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool);
 | 
				
			||||||
SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, false);
 | 
					SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, false);
 | 
				
			||||||
@ -43,6 +44,7 @@ ISourcePawnEngine *g_pSourcePawn = &g_SourcePawn;
 | 
				
			|||||||
IVirtualMachine *g_pVM;
 | 
					IVirtualMachine *g_pVM;
 | 
				
			||||||
IdentityToken_t *g_pCoreIdent = NULL;
 | 
					IdentityToken_t *g_pCoreIdent = NULL;
 | 
				
			||||||
float g_LastTime = 0.0f;
 | 
					float g_LastTime = 0.0f;
 | 
				
			||||||
 | 
					float g_LastMenuTime = 0.0f;
 | 
				
			||||||
float g_LastAuthCheck = 0.0f;
 | 
					float g_LastAuthCheck = 0.0f;
 | 
				
			||||||
IForward *g_pOnGameFrame = NULL;
 | 
					IForward *g_pOnGameFrame = NULL;
 | 
				
			||||||
IForward *g_pOnMapEnd = NULL;
 | 
					IForward *g_pOnMapEnd = NULL;
 | 
				
			||||||
@ -264,6 +266,7 @@ bool SourceModBase::LevelInit(char const *pMapName, char const *pMapEntities, ch
 | 
				
			|||||||
	m_IsMapLoading = true;
 | 
						m_IsMapLoading = true;
 | 
				
			||||||
	m_ExecPluginReload = true;
 | 
						m_ExecPluginReload = true;
 | 
				
			||||||
	g_LastTime = 0.0f;
 | 
						g_LastTime = 0.0f;
 | 
				
			||||||
 | 
						g_LastMenuTime = 0.0f;
 | 
				
			||||||
	g_LastAuthCheck = 0.0f;
 | 
						g_LastAuthCheck = 0.0f;
 | 
				
			||||||
	g_SimTicks.ticking = true;
 | 
						g_SimTicks.ticking = true;
 | 
				
			||||||
	g_SimTicks.tickcount = 0;
 | 
						g_SimTicks.tickcount = 0;
 | 
				
			||||||
@ -384,6 +387,12 @@ void SourceModBase::GameFrame(bool simulating)
 | 
				
			|||||||
		g_LastTime = curtime;
 | 
							g_LastTime = curtime;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (g_SimTicks.tickcount && (curtime - g_LastMenuTime >= 1.0f))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							g_ValveMenuStyle.ProcessWatchList();
 | 
				
			||||||
 | 
							g_LastMenuTime = curtime;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (g_pOnGameFrame && g_pOnGameFrame->GetFunctionCount())
 | 
						if (g_pOnGameFrame && g_pOnGameFrame->GetFunctionCount())
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		g_pOnGameFrame->Execute(NULL);
 | 
							g_pOnGameFrame->Execute(NULL);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user