From 5aabd814066ecb9643a9718563a7017f2023a87a Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sun, 13 May 2007 03:38:36 +0000 Subject: [PATCH] moved a whole crapload of code into a BaseMenuStyle so I can keep my precious sanity --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40781 --- core/MenuStyle_Base.cpp | 425 ++++++++++++++++++++++++++++++++++++++- core/MenuStyle_Base.h | 53 +++++ core/MenuStyle_Valve.cpp | 406 +++---------------------------------- core/MenuStyle_Valve.h | 35 +--- 4 files changed, 512 insertions(+), 407 deletions(-) diff --git a/core/MenuStyle_Base.cpp b/core/MenuStyle_Base.cpp index e0728dc6..eb139b50 100644 --- a/core/MenuStyle_Base.cpp +++ b/core/MenuStyle_Base.cpp @@ -15,9 +15,403 @@ #include #include "sm_stringutil.h" #include "MenuStyle_Base.h" +#include "PlayerManager.h" +#include "MenuManager.h" + +BaseMenuStyle::BaseMenuStyle() : m_WatchList(256) +{ +} + +void BaseMenuStyle::AddClientToWatch(int client) +{ + m_WatchList.push_back(client); +} + +void BaseMenuStyle::RemoveClientFromWatch(int client) +{ + m_WatchList.remove(client); +} + +void BaseMenuStyle::_CancelClientMenu(int client, bool bAutoIgnore/* =false */, MenuCancelReason reason/* =MenuCancel_Interrupt */) +{ + CBaseMenuPlayer *player = GetMenuPlayer(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) + { + RemoveClientFromWatch(client); + } + + /* Fire callbacks */ + mh->OnMenuCancel(menu, client, reason); + mh->OnMenuEnd(menu); + + if (bAutoIgnore) + { + player->bAutoIgnore = bOldIgnore; + } +} + +void BaseMenuStyle::CancelMenu(CBaseMenu *menu) +{ + int maxClients = g_Players.GetMaxClients(); + for (int i=1; i<=maxClients; i++) + { + CBaseMenuPlayer *player = GetMenuPlayer(i); + if (player->bInMenu) + { + menu_states_t &states = player->states; + if (states.menu == menu) + { + _CancelClientMenu(i); + } + } + } +} + +bool BaseMenuStyle::CancelClientMenu(int client, bool autoIgnore) +{ + if (client < 1 || client > g_Players.MaxClients()) + { + return false; + } + + CBaseMenuPlayer *player = GetMenuPlayer(client); + if (!player->bInMenu) + { + return false; + } + + _CancelClientMenu(client, autoIgnore); + + return true; +} + +MenuSource BaseMenuStyle::GetClientMenu(int client, void **object) +{ + if (client < 1 || client > g_Players.GetMaxClients()) + { + return MenuSource_None; + } + + CBaseMenuPlayer *player = GetMenuPlayer(client); + + if (player->bInMenu) + { + IBaseMenu *menu; + if ((menu=player->states.menu) != NULL) + { + if (object) + { + *object = menu; + } + return MenuSource_BaseMenu; + } + + return MenuSource_Display; + } else { + return GetClientExternMenu(client, object); + } +} + +MenuSource BaseMenuStyle::GetClientExternMenu(int client, void **object) +{ + return MenuSource_None; +} + +void BaseMenuStyle::OnClientDisconnected(int client) +{ + CBaseMenuPlayer *player = GetMenuPlayer(client); + if (!player->bInMenu) + { + return; + } + + _CancelClientMenu(client, true, MenuCancel_Disconnect); + + player->bInMenu = false; +} + +static int do_lookup[256]; +void BaseMenuStyle::ProcessWatchList() +{ + if (!m_WatchList.size()) + { + return; + } + + unsigned int total = 0; + for (FastLink::iterator iter=m_WatchList.begin(); iter!=m_WatchList.end(); ++iter) + { + do_lookup[total++] = (*iter); + } + + int client; + CBaseMenuPlayer *player; + float curTime = gpGlobals->curtime; + for (unsigned int i=0; ibInMenu || !player->menuHoldTime) + { + m_WatchList.remove(i); + continue; + } + if (curTime > player->menuStartTime + player->menuHoldTime) + { + _CancelClientMenu(client, false); + } + } +} + +void BaseMenuStyle::ClientPressedKey(int client, unsigned int key_press) +{ + CBaseMenuPlayer *player = GetMenuPlayer(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 BaseMenuStyle::DoClientMenu(int client, IMenuDisplay *menu, IMenuHandler *mh, unsigned int time) +{ + CPlayer *pPlayer = g_Players.GetPlayerByIndex(client); + if (!pPlayer || pPlayer->IsFakeClient() || !pPlayer->IsInGame()) + { + return false; + } + + CBaseMenuPlayer *player = GetMenuPlayer(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) + { + RemoveClientFromWatch(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->bInMenu = true; + player->menuStartTime = gpGlobals->curtime; + player->menuHoldTime = time; + + if (time) + { + AddClientToWatch(client); + } + + /* Draw the display */ + SendDisplay(client, menu); + + /* We can be interrupted again! */ + player->bAutoIgnore = false; + + return true; +} + +bool BaseMenuStyle::DoClientMenu(int client, CBaseMenu *menu, IMenuHandler *mh, unsigned int time) +{ + mh->OnMenuStart(menu); + + if (!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; + } + + CBaseMenuPlayer *player = GetMenuPlayer(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) + { + _CancelClientMenu(client, true); + } + + 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->bInMenu = true; + player->menuStartTime = gpGlobals->curtime; + player->menuHoldTime = time; + + if (time) + { + AddClientToWatch(client); + } + + /* Draw the display */ + SendDisplay(client, display); + + /* Free the display pointer */ + delete display; + + /* We can be interrupted again! */ + player->bAutoIgnore = false; + + return true; +} + +bool BaseMenuStyle::RedoClientMenu(int client, ItemOrder order) +{ + CBaseMenuPlayer *player = GetMenuPlayer(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; + } + + SendDisplay(client, display); + + delete display; + + player->bAutoIgnore = false; + + return true; +} CBaseMenu::CBaseMenu(IMenuStyle *pStyle) : -m_pStyle(pStyle), m_Strings(512), m_Pagination(7), m_ExitButton(true) +m_pStyle(pStyle), m_Strings(512), m_Pagination(7), m_ExitButton(true), m_bShouldDelete(false), m_bCancelling(false) { } @@ -161,3 +555,32 @@ bool CBaseMenu::SetExitButton(bool set) m_ExitButton = set; return true; } + +void CBaseMenu::Cancel() +{ + if (m_bCancelling) + { + return; + } + + m_bCancelling = true; + Cancel_Finally(); + m_bCancelling = false; + + if (m_bShouldDelete) + { + delete this; + } +} + +void CBaseMenu::Destroy() +{ + if (!m_bCancelling || m_bShouldDelete) + { + Cancel(); + delete this; + } else { + m_bShouldDelete = true; + } +} + diff --git a/core/MenuStyle_Base.h b/core/MenuStyle_Base.h index fdfa8c29..cff8bd73 100644 --- a/core/MenuStyle_Base.h +++ b/core/MenuStyle_Base.h @@ -16,9 +16,11 @@ #define _INCLUDE_MENUSTYLE_BASE_H #include +#include #include #include #include "sm_memtable.h" +#include "sm_fastlink.h" using namespace SourceMod; using namespace SourceHook; @@ -38,6 +40,52 @@ public: unsigned int style; }; +class CBaseMenuPlayer +{ +public: + CBaseMenuPlayer() : bInMenu(false), bAutoIgnore(false) + { + } + menu_states_t states; + bool bInMenu; + bool bAutoIgnore; + float menuStartTime; + unsigned int menuHoldTime; +}; + +class CBaseMenu; + +class BaseMenuStyle : + public IMenuStyle, + public IClientListener +{ +public: + BaseMenuStyle(); +public: //IMenuStyle + bool CancelClientMenu(int client, bool autoIgnore/* =false */); + MenuSource GetClientMenu(int client, void **object); +public: //IClientListener + void OnClientDisconnected(int client); +public: //what derived must implement + virtual CBaseMenuPlayer *GetMenuPlayer(int client) =0; + virtual void SendDisplay(int client, IMenuDisplay *display) =0; +public: //what derived may implement + virtual bool DoClientMenu(int client, CBaseMenu *menu, IMenuHandler *mh, unsigned int time); + virtual bool DoClientMenu(int client, IMenuDisplay *menu, IMenuHandler *mh, unsigned int time); + virtual void AddClientToWatch(int client); + virtual void RemoveClientFromWatch(int client); + virtual void ProcessWatchList(); + virtual MenuSource GetClientExternMenu(int client, void **object); +public: //helpers + void CancelMenu(CBaseMenu *menu); + void ClientPressedKey(int client, unsigned int key_press); +protected: + void _CancelClientMenu(int client, bool bAutoIgnore=false, MenuCancelReason reason=MenuCancel_Interrupt); + bool RedoClientMenu(int client, ItemOrder order); +protected: + FastLink m_WatchList; +}; + class CBaseMenu : public IBaseMenu { public: @@ -57,6 +105,9 @@ public: virtual const char *GetDefaultTitle(); virtual bool GetExitButton(); virtual bool SetExitButton(bool set); + virtual void Cancel(); + virtual void Destroy(); + virtual void Cancel_Finally() =0; protected: String m_Title; IMenuStyle *m_pStyle; @@ -64,6 +115,8 @@ protected: CVector m_items; BaseStringTable m_Strings; bool m_ExitButton; + bool m_bCancelling; + bool m_bShouldDelete; }; #endif //_INCLUDE_MENUSTYLE_BASE_H diff --git a/core/MenuStyle_Valve.cpp b/core/MenuStyle_Valve.cpp index 21f56365..7d8282df 100644 --- a/core/MenuStyle_Valve.cpp +++ b/core/MenuStyle_Valve.cpp @@ -36,10 +36,15 @@ public: } }; -ValveMenuStyle::ValveMenuStyle() : m_players(new CValveMenuPlayer[256+1]), m_WatchList(256) +ValveMenuStyle::ValveMenuStyle() : m_players(new CValveMenuPlayer[256+1]) { } +CBaseMenuPlayer *ValveMenuStyle::GetMenuPlayer(int client) +{ + return &m_players[client]; +} + bool ValveMenuStyle::OnClientCommand(int client) { const char *cmd = engine->Cmd_Argv(0); @@ -68,19 +73,6 @@ void ValveMenuStyle::OnSourceModShutdown() g_Players.RemoveClientListener(this); } -void ValveMenuStyle::OnClientDisconnected(int client) -{ - CValveMenuPlayer *player = &m_players[client]; - if (!player->bInMenu) - { - return; - } - - _CancelMenu(client, true, MenuCancel_Disconnect); - - player->bInMenu = false; -} - void ValveMenuStyle::HookCreateMessage(edict_t *pEdict, DIALOG_TYPE type, KeyValues *kv, @@ -112,7 +104,7 @@ void ValveMenuStyle::HookCreateMessage(edict_t *pEdict, * day to avenge its grandfather, killed in the great Menu Interruption * battle. */ - _CancelMenu(client, true); + _CancelClientMenu(client, true); } } @@ -141,360 +133,34 @@ unsigned int ValveMenuStyle::GetMaxPageItems() return 8; } -static int do_lookup[256]; -void ValveMenuStyle::ProcessWatchList() +void ValveMenuStyle::SendDisplay(int client, IMenuDisplay *display) { - if (!m_WatchList.size()) - { - return; - } - - unsigned int total = 0; - for (FastLink::iterator 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; ibInMenu || !player->menuHoldTime) - { - m_WatchList.remove(i); - continue; - } - if (curTime > player->menuStartTime + player->menuHoldTime) - { - _CancelMenu(client, false); - } - } -} - -void ValveMenuStyle::_CancelMenu(int client, bool bAutoIgnore, MenuCancelReason reason) -{ - 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, reason); - 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) - { - _CancelMenu(client, true); - } - - 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 */ + m_players[client].curPrioLevel--; 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; + vDisplay->SendRawDisplay(client, m_players[client].curPrioLevel, m_players[client].menuHoldTime); } -bool ValveMenuStyle::RedoClientMenu(int client, ItemOrder order) +bool ValveMenuStyle::DoClientMenu(int client, IMenuDisplay *menu, IMenuHandler *mh, unsigned int time) { - 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 (!g_pVSPHandle) { - 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; + return BaseMenuStyle::DoClientMenu(client, menu, mh, time); } -MenuSource ValveMenuStyle::GetClientMenu(int client, void **object) +bool ValveMenuStyle::DoClientMenu(int client, CBaseMenu *menu, IMenuHandler *mh, unsigned int time) { - if (client < 1 || client > 256 || !m_players[client].bInMenu) + if (!g_pVSPHandle) { - return MenuSource_None; + mh->OnMenuStart(menu); + mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay); + mh->OnMenuEnd(menu); + return false; } - IBaseMenu *menu; - if ((menu=m_players[client].states.menu) != NULL) - { - if (object) - { - *object = menu; - } - return MenuSource_BaseMenu; - } - - return MenuSource_Display; + return BaseMenuStyle::DoClientMenu(client, menu, mh, time); } CValveMenuDisplay::CValveMenuDisplay() @@ -542,6 +208,9 @@ bool CValveMenuDisplay::SetExtOption(MenuOption option, const void *valuePtr) int *array = (int *)valuePtr; m_pKv->SetColor("color", Color(array[0], array[1], array[2], array[3])); return true; + } else if (option == MenuOption_Priority) { + m_pKv->SetInt("level", *(int *)valuePtr); + return true; } return false; @@ -626,7 +295,7 @@ bool CValveMenuDisplay::DrawRawLine(const char *rawline) void CValveMenuDisplay::SendRawDisplay(int client, int priority, unsigned int time) { m_pKv->SetInt("level", priority); - m_pKv->SetInt("time", time); + m_pKv->SetInt("time", time ? time : 200); SH_CALL(g_pSPHCC, &IServerPluginHelpers::CreateMessage)( engine->PEntityOfEntIndex(client), @@ -641,38 +310,15 @@ bool CValveMenuDisplay::SendDisplay(int client, IMenuHandler *handler, unsigned } CValveMenu::CValveMenu() : CBaseMenu(&g_ValveMenuStyle), - m_IntroColor(255, 0, 0, 255), m_bShouldDelete(false), m_bCancelling(false) + m_IntroColor(255, 0, 0, 255) { strcpy(m_IntroMsg, "You have a menu, press ESC"); m_Pagination = 5; } -void CValveMenu::Cancel() +void CValveMenu::Cancel_Finally() { - 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) diff --git a/core/MenuStyle_Valve.h b/core/MenuStyle_Valve.h index cc66826e..78d1a887 100644 --- a/core/MenuStyle_Valve.h +++ b/core/MenuStyle_Valve.h @@ -20,23 +20,17 @@ #include "MenuStyle_Base.h" #include "sourcemm_api.h" #include "KeyValues.h" -#include #include "sm_fastlink.h" using namespace SourceMod; -class CValveMenuPlayer +class CValveMenuPlayer : public CBaseMenuPlayer { public: - CValveMenuPlayer() : bInMenu(false), bAutoIgnore(false), curPrioLevel(1) + CValveMenuPlayer() : curPrioLevel(1) { } - menu_states_t states; - bool bInMenu; - bool bAutoIgnore; int curPrioLevel; - float menuStartTime; - unsigned int menuHoldTime; }; class CValveMenu; @@ -44,37 +38,29 @@ class CValveMenuDisplay; class ValveMenuStyle : public SMGlobalClass, - public IMenuStyle, - public IClientListener + public BaseMenuStyle { 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: //BaseMenuStyle + CBaseMenuPlayer *GetMenuPlayer(int client); + void SendDisplay(int client, IMenuDisplay *display); + bool DoClientMenu(int client, CBaseMenu *menu, IMenuHandler *mh, unsigned int time); + bool DoClientMenu(int client, IMenuDisplay *menu, IMenuHandler *mh, unsigned int time); 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, MenuCancelReason reason=MenuCancel_Interrupt); private: CValveMenuPlayer *m_players; - FastLink m_WatchList; }; class CValveMenu; @@ -113,13 +99,10 @@ public: bool SetExitButton(bool set); bool SetPagination(unsigned int itemsPerPage); bool Display(int client, IMenuHandler *handler, unsigned int time); - void Cancel(); - void Destroy(); + void Cancel_Finally(); private: Color m_IntroColor; char m_IntroMsg[128]; - bool m_bCancelling; - bool m_bShouldDelete; }; extern ValveMenuStyle g_ValveMenuStyle;