dvander@769: /** dvander@769: * vim: set ts=4 : dvander@769: * =============================================================== dvander@769: * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. dvander@769: * =============================================================== dvander@769: * dvander@769: * This file is not open source and may not be copied without explicit dvander@769: * written permission of AlliedModders LLC. This file may not be redistributed dvander@769: * in whole or significant part. dvander@769: * For information, see LICENSE.txt or http://www.sourcemod.net/license.php dvander@769: * dvander@769: * Version: $Id$ dvander@769: */ dvander@769: dvander@769: #include "sm_stringutil.h" dvander@769: #include "PlayerManager.h" dvander@769: #include "MenuStyle_Valve.h" dvander@769: #include "Translator.h" dvander@769: #include "PlayerManager.h" dvander@769: #include "ConCmdManager.h" dvander@769: dvander@769: SH_DECL_HOOK4_void(IServerPluginHelpers, CreateMessage, SH_NOATTRIB, false, edict_t *, DIALOG_TYPE, KeyValues *, IServerPluginCallbacks *); dvander@769: dvander@769: ValveMenuStyle g_ValveMenuStyle; dvander@769: const char *g_OptionNumTable[]; dvander@769: const char *g_OptionCmdTable[]; dvander@769: IServerPluginCallbacks *g_pVSPHandle = NULL; dvander@769: CallClass *g_pSPHCC = NULL; dvander@769: dvander@769: class TestHandler : public IMenuHandler dvander@769: { dvander@769: public: dvander@769: virtual void OnMenuEnd(IBaseMenu *menu) dvander@769: { dvander@769: menu->Destroy(); dvander@769: } dvander@769: }; dvander@769: dvander@769: ValveMenuStyle::ValveMenuStyle() : m_players(new CValveMenuPlayer[256+1]), m_WatchList(256) dvander@769: { dvander@769: } dvander@769: dvander@769: bool ValveMenuStyle::OnClientCommand(int client) dvander@769: { dvander@769: const char *cmd = engine->Cmd_Argv(0); dvander@769: dvander@769: if (strcmp(cmd, "sm_vmenuselect") == 0) dvander@769: { dvander@769: int key_press = atoi(engine->Cmd_Argv(1)); dvander@769: g_ValveMenuStyle.ClientPressedKey(client, key_press); dvander@769: return true; dvander@769: } dvander@769: dvander@769: return false; dvander@769: } dvander@769: dvander@769: void ValveMenuStyle::OnSourceModAllInitialized() dvander@769: { dvander@769: g_Players.AddClientListener(this); dvander@769: SH_ADD_HOOK_MEMFUNC(IServerPluginHelpers, CreateMessage, serverpluginhelpers, this, &ValveMenuStyle::HookCreateMessage, false); dvander@769: g_pSPHCC = SH_GET_CALLCLASS(serverpluginhelpers); dvander@769: } dvander@769: dvander@769: void ValveMenuStyle::OnSourceModShutdown() dvander@769: { dvander@769: SH_RELEASE_CALLCLASS(g_pSPHCC); dvander@769: SH_REMOVE_HOOK_MEMFUNC(IServerPluginHelpers, CreateMessage, serverpluginhelpers, this, &ValveMenuStyle::HookCreateMessage, false); dvander@769: g_Players.RemoveClientListener(this); dvander@769: } dvander@769: dvander@769: void ValveMenuStyle::OnClientDisconnected(int client) dvander@769: { dvander@769: CValveMenuPlayer *player = &m_players[client]; dvander@769: if (!player->bInMenu) dvander@769: { dvander@769: return; dvander@769: } dvander@769: dvander@774: _CancelMenu(client, true, MenuCancel_Disconnect); dvander@769: dvander@769: player->bInMenu = false; dvander@769: } dvander@769: dvander@769: void ValveMenuStyle::HookCreateMessage(edict_t *pEdict, dvander@769: DIALOG_TYPE type, dvander@769: KeyValues *kv, dvander@769: IServerPluginCallbacks *plugin) dvander@769: { dvander@769: if (type != DIALOG_MENU) dvander@769: { dvander@769: return; dvander@769: } dvander@769: dvander@769: int client = engine->IndexOfEdict(pEdict); dvander@769: if (client < 1 || client > 256) dvander@769: { dvander@769: return; dvander@769: } dvander@769: dvander@769: CValveMenuPlayer *player = &m_players[client]; dvander@769: dvander@769: /* We don't care if the player is in a menu because, for all intents and purposes, dvander@769: * the menu is completely private. Instead, we just figure out the level we'll need dvander@769: * in order to override it. dvander@769: */ dvander@769: player->curPrioLevel = kv->GetInt("level", player->curPrioLevel); dvander@769: dvander@769: /* Oh no! What happens if we got a menu that overwrites ours?! */ dvander@769: if (player->bInMenu) dvander@769: { dvander@769: /* Okay, let the external menu survive for now. It may live another dvander@769: * day to avenge its grandfather, killed in the great Menu Interruption dvander@769: * battle. dvander@769: */ dvander@769: _CancelMenu(client, true); dvander@769: } dvander@769: } dvander@769: dvander@769: void ValveMenuStyle::OnSourceModVSPReceived(IServerPluginCallbacks *iface) dvander@769: { dvander@769: g_pVSPHandle = iface; dvander@769: } dvander@769: dvander@769: IMenuDisplay *ValveMenuStyle::CreateDisplay() dvander@769: { dvander@769: return new CValveMenuDisplay(); dvander@769: } dvander@769: dvander@769: IBaseMenu *ValveMenuStyle::CreateMenu() dvander@769: { dvander@769: return new CValveMenu(); dvander@769: } dvander@769: dvander@769: const char *ValveMenuStyle::GetStyleName() dvander@769: { dvander@769: return "valve"; dvander@769: } dvander@769: dvander@769: unsigned int ValveMenuStyle::GetMaxPageItems() dvander@769: { dvander@769: return 8; dvander@769: } dvander@769: dvander@769: static int do_lookup[256]; dvander@769: void ValveMenuStyle::ProcessWatchList() dvander@769: { dvander@769: if (!m_WatchList.size()) dvander@769: { dvander@769: return; dvander@769: } dvander@769: dvander@769: unsigned int total = 0; dvander@772: for (FastLink::iterator iter=m_WatchList.begin(); iter!=m_WatchList.end(); ++iter) dvander@769: { dvander@769: do_lookup[total++] = (*iter); dvander@769: } dvander@769: dvander@769: int client; dvander@769: CValveMenuPlayer *player; dvander@769: float curTime = gpGlobals->curtime; dvander@769: for (unsigned int i=0; ibInMenu || !player->menuHoldTime) dvander@769: { dvander@769: m_WatchList.remove(i); dvander@769: continue; dvander@769: } dvander@769: if (curTime > player->menuStartTime + player->menuHoldTime) dvander@769: { dvander@772: _CancelMenu(client, false); dvander@769: } dvander@769: } dvander@769: } dvander@769: dvander@774: void ValveMenuStyle::_CancelMenu(int client, bool bAutoIgnore, MenuCancelReason reason) dvander@769: { dvander@769: CValveMenuPlayer *player = &m_players[client]; dvander@769: menu_states_t &states = player->states; dvander@769: dvander@769: bool bOldIgnore = player->bAutoIgnore; dvander@769: if (bAutoIgnore) dvander@769: { dvander@769: player->bAutoIgnore = true; dvander@769: } dvander@769: dvander@769: /* Save states */ dvander@769: IMenuHandler *mh = states.mh; dvander@769: IBaseMenu *menu = states.menu; dvander@769: dvander@769: /* Clear menu */ dvander@769: player->bInMenu = false; dvander@769: if (player->menuHoldTime) dvander@769: { dvander@769: m_WatchList.remove(client); dvander@769: } dvander@769: dvander@769: /* Fire callbacks */ dvander@774: mh->OnMenuCancel(menu, client, reason); dvander@769: mh->OnMenuEnd(menu); dvander@769: dvander@769: if (bAutoIgnore) dvander@769: { dvander@769: player->bAutoIgnore = bOldIgnore; dvander@769: } dvander@769: } dvander@769: dvander@769: void ValveMenuStyle::CancelMenu(CValveMenu *menu) dvander@769: { dvander@769: int maxClients = g_Players.GetMaxClients(); dvander@769: for (int i=1; i<=maxClients; i++) dvander@769: { dvander@769: if (m_players[i].bInMenu) dvander@769: { dvander@769: menu_states_t &states = m_players[i].states; dvander@769: if (states.menu == menu) dvander@769: { dvander@769: _CancelMenu(i); dvander@769: } dvander@769: } dvander@769: } dvander@769: } dvander@769: dvander@769: bool ValveMenuStyle::CancelClientMenu(int client, bool autoIgnore) dvander@769: { dvander@769: if (client < 1 || client > 256 || !m_players[client].bInMenu) dvander@769: { dvander@769: return false; dvander@769: } dvander@769: dvander@769: _CancelMenu(client, autoIgnore); dvander@769: dvander@769: return true; dvander@769: } dvander@769: dvander@769: dvander@769: void ValveMenuStyle::ClientPressedKey(int client, unsigned int key_press) dvander@769: { dvander@769: CValveMenuPlayer *player = &m_players[client]; dvander@769: dvander@769: /* First question: Are we in a menu? */ dvander@769: if (!player->bInMenu) dvander@769: { dvander@769: return; dvander@769: } dvander@769: dvander@769: bool cancel = false; dvander@769: unsigned int item = 0; dvander@769: MenuCancelReason reason = MenuCancel_Exit; dvander@769: menu_states_t &states = player->states; dvander@769: dvander@769: assert(states.mh != NULL); dvander@769: dvander@769: if (states.menu == NULL) dvander@769: { dvander@769: item = key_press; dvander@769: } else if (key_press < 1 || key_press > 8) { dvander@769: cancel = true; dvander@769: } else { dvander@769: ItemSelection type = states.slots[key_press].type; dvander@769: dvander@769: /* For navigational items, we're going to redisplay */ dvander@769: if (type == ItemSel_Back) dvander@769: { dvander@769: if (!RedoClientMenu(client, ItemOrder_Descending)) dvander@769: { dvander@769: cancel = true; dvander@769: reason = MenuCancel_NoDisplay; dvander@769: } else { dvander@769: return; dvander@769: } dvander@769: } else if (type == ItemSel_Next) { dvander@769: if (!RedoClientMenu(client, ItemOrder_Ascending)) dvander@769: { dvander@769: cancel = true; /* I like Saltines. */ dvander@769: reason = MenuCancel_NoDisplay; dvander@769: } else { dvander@769: return; dvander@769: } dvander@769: } else if (type == ItemSel_Exit || type == ItemSel_None) { dvander@769: cancel = true; dvander@769: } else { dvander@769: item = states.slots[key_press].item; dvander@769: } dvander@769: } dvander@769: dvander@769: /* Save variables */ dvander@769: IMenuHandler *mh = states.mh; dvander@769: IBaseMenu *menu = states.menu; dvander@769: dvander@769: /* Clear states */ dvander@769: player->bInMenu = false; dvander@769: if (player->menuHoldTime) dvander@769: { dvander@769: m_WatchList.remove(client); dvander@769: } dvander@769: dvander@769: if (cancel) dvander@769: { dvander@769: mh->OnMenuCancel(menu, client, reason); dvander@769: } else { dvander@769: mh->OnMenuSelect(menu, client, item); dvander@769: } dvander@769: dvander@769: mh->OnMenuEnd(menu); dvander@769: } dvander@769: dvander@769: bool ValveMenuStyle::DoClientMenu(int client, CValveMenuDisplay *menu, IMenuHandler *mh, unsigned int time) dvander@769: { dvander@769: if (!g_pVSPHandle || !mh) dvander@769: { dvander@769: return false; dvander@769: } dvander@769: dvander@769: CPlayer *pPlayer = g_Players.GetPlayerByIndex(client); dvander@769: if (!pPlayer || pPlayer->IsFakeClient() || !pPlayer->IsInGame()) dvander@769: { dvander@769: return false; dvander@769: } dvander@769: dvander@769: CValveMenuPlayer *player = &m_players[client]; dvander@769: if (player->bAutoIgnore) dvander@769: { dvander@769: return false; dvander@769: } dvander@769: dvander@769: /* For the duration of this, we are going to totally ignore whether dvander@769: * the player is already in a menu or not (except to cancel the old one). dvander@769: * Instead, we are simply going to ignore any further menu displays, so dvander@769: * this display can't be interrupted. dvander@769: */ dvander@769: player->bAutoIgnore = true; dvander@769: dvander@769: /* Cancel any old menus */ dvander@769: menu_states_t &states = player->states; dvander@769: if (player->bInMenu) dvander@769: { dvander@769: /* We need to cancel the old menu */ dvander@769: if (player->menuHoldTime) dvander@769: { dvander@769: m_WatchList.remove(client); dvander@769: } dvander@769: states.mh->OnMenuCancel(states.menu, client, MenuCancel_Interrupt); dvander@769: states.mh->OnMenuEnd(states.menu); dvander@769: } dvander@769: dvander@769: states.firstItem = 0; dvander@769: states.lastItem = 0; dvander@769: states.menu = NULL; dvander@769: states.mh = mh; dvander@769: states.apiVers = SMINTERFACE_MENUMANAGER_VERSION; dvander@769: player->curPrioLevel--; dvander@769: player->bInMenu = true; dvander@769: player->menuStartTime = gpGlobals->curtime; dvander@769: player->menuHoldTime = time; dvander@769: dvander@769: if (time) dvander@769: { dvander@769: m_WatchList.push_back(client); dvander@769: } dvander@769: dvander@769: /* Draw the display */ dvander@769: menu->SendRawDisplay(client, player->curPrioLevel, time); dvander@769: dvander@769: /* We can be interrupted again! */ dvander@769: player->bAutoIgnore = false; dvander@769: dvander@769: return true; dvander@769: } dvander@769: dvander@769: bool ValveMenuStyle::DoClientMenu(int client, CValveMenu *menu, IMenuHandler *mh, unsigned int time) dvander@769: { dvander@769: mh->OnMenuStart(menu); dvander@769: dvander@769: if (!g_pVSPHandle || !mh) dvander@769: { dvander@769: mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay); dvander@769: mh->OnMenuEnd(menu); dvander@769: return false; dvander@769: } dvander@769: dvander@769: CPlayer *pPlayer = g_Players.GetPlayerByIndex(client); dvander@769: if (!pPlayer || pPlayer->IsFakeClient() || !pPlayer->IsInGame()) dvander@769: { dvander@769: mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay); dvander@769: mh->OnMenuEnd(menu); dvander@769: return false; dvander@769: } dvander@769: dvander@769: CValveMenuPlayer *player = &m_players[client]; dvander@769: if (player->bAutoIgnore) dvander@769: { dvander@769: mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay); dvander@769: mh->OnMenuEnd(menu); dvander@769: return false; dvander@769: } dvander@769: dvander@769: /* For the duration of this, we are going to totally ignore whether dvander@769: * the player is already in a menu or not (except to cancel the old one). dvander@769: * Instead, we are simply going to ignore any further menu displays, so dvander@769: * this display can't be interrupted. dvander@769: */ dvander@769: player->bAutoIgnore = true; dvander@769: dvander@769: /* Cancel any old menus */ dvander@769: menu_states_t &states = player->states; dvander@769: if (player->bInMenu) dvander@769: { dvander@774: _CancelMenu(client, true); dvander@769: } dvander@769: dvander@769: states.firstItem = 0; dvander@769: states.lastItem = 0; dvander@769: states.menu = menu; dvander@769: states.mh = mh; dvander@769: states.apiVers = SMINTERFACE_MENUMANAGER_VERSION; dvander@769: dvander@769: IMenuDisplay *display = g_Menus.RenderMenu(client, states, ItemOrder_Ascending); dvander@769: if (!display) dvander@769: { dvander@769: player->bAutoIgnore = false; dvander@769: player->bInMenu = false; dvander@769: mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay); dvander@769: mh->OnMenuEnd(menu); dvander@769: return false; dvander@769: } dvander@769: dvander@769: /* Finally, set our states */ dvander@769: player->curPrioLevel--; dvander@769: player->bInMenu = true; dvander@769: player->menuStartTime = gpGlobals->curtime; dvander@769: player->menuHoldTime = time; dvander@769: dvander@769: if (time) dvander@769: { dvander@769: m_WatchList.push_back(client); dvander@769: } dvander@769: dvander@769: /* Draw the display */ dvander@769: CValveMenuDisplay *vDisplay = (CValveMenuDisplay *)display; dvander@769: vDisplay->SendRawDisplay(client, player->curPrioLevel, time); dvander@769: dvander@769: /* Free the display pointer */ dvander@769: delete display; dvander@769: dvander@769: /* We can be interrupted again! */ dvander@769: player->bAutoIgnore = false; dvander@769: dvander@769: return true; dvander@769: } dvander@769: dvander@769: bool ValveMenuStyle::RedoClientMenu(int client, ItemOrder order) dvander@769: { dvander@769: CValveMenuPlayer *player = &m_players[client]; dvander@769: menu_states_t &states = player->states; dvander@769: dvander@769: player->bAutoIgnore = true; dvander@769: IMenuDisplay *display = g_Menus.RenderMenu(client, states, order); dvander@769: if (!display) dvander@769: { dvander@769: if (player->menuHoldTime) dvander@769: { dvander@769: m_WatchList.remove(client); dvander@769: } dvander@769: player->bAutoIgnore = false; dvander@769: return false; dvander@769: } dvander@769: dvander@769: CValveMenuDisplay *vDisplay = (CValveMenuDisplay *)display; dvander@769: vDisplay->SendRawDisplay(client, --player->curPrioLevel, player->menuHoldTime); dvander@769: dvander@769: delete display; dvander@769: dvander@769: player->bAutoIgnore = false; dvander@769: dvander@769: return true; dvander@769: } dvander@769: dvander@769: MenuSource ValveMenuStyle::GetClientMenu(int client, void **object) dvander@769: { dvander@769: if (client < 1 || client > 256 || !m_players[client].bInMenu) dvander@769: { dvander@769: return MenuSource_None; dvander@769: } dvander@769: dvander@769: IBaseMenu *menu; dvander@769: if ((menu=m_players[client].states.menu) != NULL) dvander@769: { dvander@769: if (object) dvander@769: { dvander@769: *object = menu; dvander@769: } dvander@769: return MenuSource_BaseMenu; dvander@769: } dvander@769: dvander@769: return MenuSource_Display; dvander@769: } dvander@769: dvander@769: CValveMenuDisplay::CValveMenuDisplay() dvander@769: { dvander@769: m_pKv = NULL; dvander@769: Reset(); dvander@769: } dvander@769: dvander@769: CValveMenuDisplay::CValveMenuDisplay(CValveMenu *pMenu) dvander@769: { dvander@769: m_pKv = NULL; dvander@769: Reset(); dvander@769: m_pKv->SetColor("color", pMenu->m_IntroColor); dvander@769: m_pKv->SetString("title", pMenu->m_IntroMsg); dvander@769: } dvander@769: dvander@769: CValveMenuDisplay::~CValveMenuDisplay() dvander@769: { dvander@769: m_pKv->deleteThis(); dvander@769: } dvander@769: dvander@769: IMenuStyle *CValveMenuDisplay::GetParentStyle() dvander@769: { dvander@769: return &g_ValveMenuStyle; dvander@769: } dvander@769: dvander@769: void CValveMenuDisplay::Reset() dvander@769: { dvander@769: if (m_pKv) dvander@769: { dvander@769: m_pKv->deleteThis(); dvander@769: } dvander@769: m_pKv = new KeyValues("menu"); dvander@769: m_NextPos = 1; dvander@769: m_TitleDrawn = false; dvander@769: } dvander@769: dvander@769: bool CValveMenuDisplay::SetExtOption(MenuOption option, const void *valuePtr) dvander@769: { dvander@769: if (option == MenuOption_IntroMessage) dvander@769: { dvander@769: m_pKv->SetString("title", (const char *)valuePtr); dvander@769: return true; dvander@769: } else if (option == MenuOption_IntroColor) { dvander@769: int *array = (int *)valuePtr; dvander@769: m_pKv->SetColor("color", Color(array[0], array[1], array[2], array[3])); dvander@769: return true; dvander@769: } dvander@769: dvander@769: return false; dvander@769: } dvander@769: dvander@769: bool CValveMenuDisplay::CanDrawItem(unsigned int drawFlags) dvander@769: { dvander@769: /** dvander@769: * ITEMDRAW_RAWLINE - We can't draw random text, and this doesn't add a slot, dvander@769: * so it's completely safe to ignore it. dvander@769: * ----------------------------------------- dvander@769: */ dvander@769: if (drawFlags & ITEMDRAW_RAWLINE) dvander@769: { dvander@769: return false; dvander@769: } dvander@769: dvander@769: /** dvander@769: * Special cases, explained in DrawItem() dvander@769: */ dvander@769: if ((drawFlags & ITEMDRAW_NOTEXT) dvander@769: || (drawFlags & ITEMDRAW_SPACER)) dvander@769: { dvander@769: return true; dvander@769: } dvander@769: dvander@769: /** dvander@769: * We can't draw disabled text. We could bump the position, but we dvander@769: * want DirectDraw() to find some actual items to display. dvander@769: */ dvander@769: if (drawFlags & ITEMDRAW_DISABLED) dvander@769: { dvander@769: return false; dvander@769: } dvander@769: dvander@769: return true; dvander@769: } dvander@769: dvander@769: unsigned int CValveMenuDisplay::DrawItem(const ItemDrawInfo &item) dvander@769: { dvander@769: if (m_NextPos > 9 || !CanDrawItem(item.style)) dvander@769: { dvander@769: return 0; dvander@769: } dvander@769: dvander@769: /** dvander@769: * For these cases we can't draw anything at all, but dvander@769: * we can at least bump the position since we were explicitly asked to. dvander@769: */ dvander@769: if ((item.style & ITEMDRAW_NOTEXT) dvander@769: || (item.style & ITEMDRAW_SPACER)) dvander@769: { dvander@769: return m_NextPos++; dvander@769: } dvander@769: dvander@769: char buffer[255]; dvander@769: UTIL_Format(buffer, sizeof(buffer), "%d. %s", m_NextPos, item.display); dvander@769: dvander@769: KeyValues *ki = m_pKv->FindKey(g_OptionNumTable[m_NextPos], true); dvander@769: ki->SetString("command", g_OptionCmdTable[m_NextPos]); dvander@769: ki->SetString("msg", buffer); dvander@769: dvander@769: return m_NextPos++; dvander@769: } dvander@769: dvander@769: void CValveMenuDisplay::DrawTitle(const char *text, bool onlyIfEmpty/* =false */) dvander@769: { dvander@769: if (onlyIfEmpty && m_TitleDrawn) dvander@769: { dvander@769: return; dvander@769: } dvander@769: dvander@769: m_pKv->SetString("msg", text); dvander@769: m_TitleDrawn = true; dvander@769: } dvander@769: dvander@769: bool CValveMenuDisplay::DrawRawLine(const char *rawline) dvander@769: { dvander@769: return false; dvander@769: } dvander@769: dvander@769: void CValveMenuDisplay::SendRawDisplay(int client, int priority, unsigned int time) dvander@769: { dvander@769: m_pKv->SetInt("level", priority); dvander@769: m_pKv->SetInt("time", time); dvander@769: dvander@769: SH_CALL(g_pSPHCC, &IServerPluginHelpers::CreateMessage)( dvander@769: engine->PEntityOfEntIndex(client), dvander@769: DIALOG_MENU, dvander@769: m_pKv, dvander@769: g_pVSPHandle); dvander@769: } dvander@769: dvander@769: bool CValveMenuDisplay::SendDisplay(int client, IMenuHandler *handler, unsigned int time) dvander@769: { dvander@769: return g_ValveMenuStyle.DoClientMenu(client, this, handler, time); dvander@769: } dvander@769: dvander@769: CValveMenu::CValveMenu() : CBaseMenu(&g_ValveMenuStyle), dvander@769: m_IntroColor(255, 0, 0, 255), m_bShouldDelete(false), m_bCancelling(false) dvander@769: { dvander@769: strcpy(m_IntroMsg, "You have a menu, press ESC"); dvander@769: m_Pagination = 5; dvander@769: } dvander@769: dvander@769: void CValveMenu::Cancel() dvander@769: { dvander@769: if (m_bCancelling) dvander@769: { dvander@769: return; dvander@769: } dvander@769: dvander@769: m_bCancelling = true; dvander@769: g_ValveMenuStyle.CancelMenu(this); dvander@769: m_bCancelling = false; dvander@769: dvander@769: if (m_bShouldDelete) dvander@769: { dvander@769: delete this; dvander@769: } dvander@769: } dvander@769: dvander@769: void CValveMenu::Destroy() dvander@769: { dvander@769: if (!m_bCancelling || m_bShouldDelete) dvander@769: { dvander@769: Cancel(); dvander@769: delete this; dvander@769: } else { dvander@769: m_bShouldDelete = true; dvander@769: } dvander@769: } dvander@769: dvander@769: bool CValveMenu::SetPagination(unsigned int itemsPerPage) dvander@769: { dvander@769: if (itemsPerPage < 1 || itemsPerPage > 5) dvander@769: { dvander@769: return false; dvander@769: } dvander@769: dvander@769: CBaseMenu::SetPagination(itemsPerPage); dvander@769: dvander@769: return true; dvander@769: } dvander@769: dvander@769: bool CValveMenu::SetExtOption(MenuOption option, const void *valuePtr) dvander@769: { dvander@769: if (option == MenuOption_IntroMessage) dvander@769: { dvander@769: strncopy(m_IntroMsg, (const char *)valuePtr, sizeof(m_IntroMsg)); dvander@769: return true; dvander@769: } else if (option == MenuOption_IntroColor) { dvander@769: unsigned int *array = (unsigned int *)valuePtr; dvander@769: m_IntroColor = Color(array[0], array[1], array[2], array[3]); dvander@769: return true; dvander@769: } dvander@769: dvander@769: return false; dvander@769: } dvander@769: dvander@769: bool CValveMenu::Display(int client, IMenuHandler *handler, unsigned int time) dvander@769: { dvander@769: if (m_bCancelling) dvander@769: { dvander@769: return false; dvander@769: } dvander@769: dvander@769: return g_ValveMenuStyle.DoClientMenu(client, this, handler, time); dvander@769: } dvander@769: dvander@769: IMenuDisplay *CValveMenu::CreateDisplay() dvander@769: { dvander@769: return new CValveMenuDisplay(this); dvander@769: } dvander@769: dvander@769: bool CValveMenu::GetExitButton() dvander@769: { dvander@769: return true; dvander@769: } dvander@769: dvander@769: bool CValveMenu::SetExitButton(bool set) dvander@769: { dvander@769: return false; dvander@769: } dvander@769: dvander@769: static const char *g_OptionNumTable[11] = dvander@769: { dvander@769: "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" dvander@769: }; dvander@769: dvander@769: static const char *g_OptionCmdTable[11] = dvander@769: { dvander@769: "sm_vmenuselect 0", /* INVALID! */ dvander@769: "sm_vmenuselect 1", dvander@769: "sm_vmenuselect 2", dvander@769: "sm_vmenuselect 3", dvander@769: "sm_vmenuselect 4", dvander@769: "sm_vmenuselect 5", dvander@769: "sm_vmenuselect 6", dvander@769: "sm_vmenuselect 7", dvander@769: "sm_vmenuselect 8", dvander@769: "sm_vmenuselect 9", dvander@769: "sm_vmenuselect 10" dvander@769: };