added experimental voting API
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40883
This commit is contained in:
parent
2884483bef
commit
aea69f5fe8
@ -12,9 +12,9 @@
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include "MenuManager.h"
|
||||
#include "sm_stringutil.h"
|
||||
#include "sourcemm_api.h"
|
||||
@ -25,115 +25,188 @@
|
||||
|
||||
MenuManager g_Menus;
|
||||
|
||||
/*************************************
|
||||
*************************************
|
||||
**** BROADCAST HANDLING WRAPPERS ****
|
||||
*************************************
|
||||
*************************************/
|
||||
/*******************************
|
||||
*******************************
|
||||
******** VOTE HANDLER *********
|
||||
*******************************
|
||||
*******************************/
|
||||
|
||||
BroadcastHandler::BroadcastHandler(IMenuHandler *handler) : m_pHandler(handler), numClients(0)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int BroadcastHandler::GetMenuAPIVersion2()
|
||||
unsigned int VoteMenuHandler::GetMenuAPIVersion2()
|
||||
{
|
||||
return m_pHandler->GetMenuAPIVersion2();
|
||||
}
|
||||
|
||||
void BroadcastHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
|
||||
bool VoteMenuHandler::IsVoteInProgress()
|
||||
{
|
||||
return (m_pCurMenu != NULL);
|
||||
}
|
||||
|
||||
void VoteMenuHandler::InitializeVoting(IBaseMenu *menu)
|
||||
{
|
||||
m_Items = menu->GetItemCount();
|
||||
|
||||
if (m_Votes.size() < (size_t)m_Items)
|
||||
{
|
||||
/* Only clear the items we need to... */
|
||||
size_t size = m_Votes.size();
|
||||
for (size_t i=0; i<size; i++)
|
||||
{
|
||||
m_Votes[i] = 0;
|
||||
}
|
||||
m_Votes.resize(m_Items, 0);
|
||||
} else {
|
||||
for (unsigned int i=0; i<m_Items; i++)
|
||||
{
|
||||
m_Votes[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
m_pCurMenu = menu;
|
||||
|
||||
m_pHandler->OnMenuStart(m_pCurMenu);
|
||||
}
|
||||
|
||||
void VoteMenuHandler::StartVoting()
|
||||
{
|
||||
m_bStarted = true;
|
||||
|
||||
m_pHandler->OnMenuVoteStart(m_pCurMenu);
|
||||
|
||||
/* By now we know how many clients were set.
|
||||
* If there are none, we should end IMMEDIATELY.
|
||||
*/
|
||||
if (m_Clients == 0)
|
||||
{
|
||||
EndVoting();
|
||||
}
|
||||
}
|
||||
|
||||
void VoteMenuHandler::DecrementPlayerCount()
|
||||
{
|
||||
assert(m_Clients > 0);
|
||||
|
||||
m_Clients--;
|
||||
|
||||
if (m_bStarted && m_Clients == 0)
|
||||
{
|
||||
EndVoting();
|
||||
}
|
||||
}
|
||||
|
||||
void VoteMenuHandler::EndVoting()
|
||||
{
|
||||
unsigned int chosen = 0;
|
||||
|
||||
/* If we got zero votes, take a shortcut. */
|
||||
if (m_NumVotes == 0)
|
||||
{
|
||||
/* Pick a random item and then jump far, far away. */
|
||||
srand((unsigned int)(time(NULL)));
|
||||
chosen = (unsigned int)rand() % static_cast<unsigned int>(m_Votes.size());
|
||||
goto picked_item;
|
||||
}
|
||||
|
||||
/* We can't have more dups than this!
|
||||
* This is the max number of players.
|
||||
*/
|
||||
unsigned int dup_array[256];
|
||||
unsigned int dup_count = 0;
|
||||
|
||||
size_t highest = 0;
|
||||
for (size_t i=1; i<m_Votes.size(); i++)
|
||||
{
|
||||
if (m_Votes[i] > m_Votes[highest])
|
||||
{
|
||||
/* If we have a new highest count, mark it and trash the duplicate
|
||||
* list by setting the total to 0.
|
||||
*/
|
||||
highest = i;
|
||||
dup_count = 0;
|
||||
} else if (m_Votes[i] == m_Votes[highest]) {
|
||||
/* If they're equal, mark it in the duplicate list.
|
||||
* We'll add in the original later.
|
||||
*/
|
||||
dup_array[dup_count++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we need to pick from the duplicate list */
|
||||
if (dup_count)
|
||||
{
|
||||
/* Re-add the original to the list because it's not in there. */
|
||||
dup_array[dup_count++] = (unsigned int)highest;
|
||||
|
||||
/* Pick a random slot. */
|
||||
srand((unsigned int)(time(NULL)));
|
||||
unsigned int r = (unsigned int)rand() % dup_count;
|
||||
|
||||
/* Pick the item. */
|
||||
chosen = dup_array[r];
|
||||
} else {
|
||||
chosen = (unsigned int)highest;
|
||||
}
|
||||
|
||||
picked_item:
|
||||
m_pHandler->OnMenuVoteEnd(m_pCurMenu, chosen);
|
||||
m_pHandler->OnMenuEnd(m_pCurMenu);
|
||||
InternalReset();
|
||||
}
|
||||
|
||||
void VoteMenuHandler::OnMenuStart(IBaseMenu *menu)
|
||||
{
|
||||
m_Clients++;
|
||||
}
|
||||
|
||||
void VoteMenuHandler::OnMenuEnd(IBaseMenu *menu)
|
||||
{
|
||||
DecrementPlayerCount();
|
||||
}
|
||||
|
||||
void VoteMenuHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
|
||||
{
|
||||
m_pHandler->OnMenuCancel(menu, client, reason);
|
||||
}
|
||||
|
||||
void BroadcastHandler::OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *display)
|
||||
void VoteMenuHandler::OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *display)
|
||||
{
|
||||
numClients++;
|
||||
m_pHandler->OnMenuDisplay(menu, client, display);
|
||||
}
|
||||
|
||||
void BroadcastHandler::OnBroadcastEnd(IBaseMenu *menu)
|
||||
void VoteMenuHandler::OnMenuDisplayItem(IBaseMenu *menu, int client, unsigned int item, const char **display)
|
||||
{
|
||||
g_Menus.FreeBroadcastHandler(this);
|
||||
m_pHandler->OnMenuDisplayItem(menu, client, item, display);
|
||||
}
|
||||
|
||||
void BroadcastHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
|
||||
void VoteMenuHandler::OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style)
|
||||
{
|
||||
m_pHandler->OnMenuDrawItem(menu, client, item, style);
|
||||
}
|
||||
|
||||
void VoteMenuHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
|
||||
{
|
||||
/* Check by our item count, NOT the vote array size */
|
||||
if (item < m_Items)
|
||||
{
|
||||
m_Votes[item]++;
|
||||
m_NumVotes++;
|
||||
}
|
||||
|
||||
m_pHandler->OnMenuSelect(menu, client, item);
|
||||
}
|
||||
|
||||
void BroadcastHandler::OnMenuEnd(IBaseMenu *menu)
|
||||
void VoteMenuHandler::Reset(IMenuHandler *mh)
|
||||
{
|
||||
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);
|
||||
}
|
||||
m_pHandler = mh;
|
||||
InternalReset();
|
||||
}
|
||||
|
||||
VoteHandler::VoteHandler(IMenuVoteHandler *handler)
|
||||
: BroadcastHandler(handler), m_pVoteHandler(handler)
|
||||
void VoteMenuHandler::InternalReset()
|
||||
{
|
||||
}
|
||||
|
||||
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);
|
||||
m_Clients = 0;
|
||||
m_Items = 0;
|
||||
m_bStarted = false;
|
||||
m_pCurMenu = NULL;
|
||||
m_NumVotes = 0;
|
||||
}
|
||||
|
||||
/*******************************
|
||||
@ -169,12 +242,6 @@ void MenuManager::OnSourceModAllShutdown()
|
||||
g_HandleSys.RemoveType(m_MenuType, g_pCoreIdent);
|
||||
g_HandleSys.RemoveType(m_StyleType, g_pCoreIdent);
|
||||
|
||||
while (!m_BroadcastHandlers.empty())
|
||||
{
|
||||
delete m_BroadcastHandlers.front();
|
||||
m_BroadcastHandlers.pop();
|
||||
}
|
||||
|
||||
while (!m_VoteHandlers.empty())
|
||||
{
|
||||
delete m_VoteHandlers.front();
|
||||
@ -659,119 +726,34 @@ skip_search:
|
||||
return display;
|
||||
}
|
||||
|
||||
#if 0
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
void MenuManager::FreeBroadcastHandler(BroadcastHandler *bh)
|
||||
{
|
||||
m_BroadcastHandlers.push(bh);
|
||||
}
|
||||
|
||||
void MenuManager::FreeVoteHandler(VoteHandler *vh)
|
||||
{
|
||||
m_VoteHandlers.push(vh);
|
||||
}
|
||||
|
||||
IMenuStyle *MenuManager::GetDefaultStyle()
|
||||
{
|
||||
return m_pDefaultStyle;
|
||||
}
|
||||
|
||||
IVoteMenuHandler *MenuManager::CreateVoteWrapper(IMenuHandler *mh)
|
||||
{
|
||||
VoteMenuHandler *vh = NULL;
|
||||
|
||||
if (m_VoteHandlers.empty())
|
||||
{
|
||||
vh = new VoteMenuHandler;
|
||||
} else {
|
||||
vh = m_VoteHandlers.front();
|
||||
m_VoteHandlers.pop();
|
||||
}
|
||||
|
||||
vh->Reset(mh);
|
||||
|
||||
return vh;
|
||||
}
|
||||
|
||||
void MenuManager::ReleaseVoteWrapper(IVoteMenuHandler *mh)
|
||||
{
|
||||
if (mh == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_VoteHandlers.push((VoteMenuHandler *)mh);
|
||||
}
|
||||
|
@ -25,36 +25,36 @@
|
||||
using namespace SourceMod;
|
||||
using namespace SourceHook;
|
||||
|
||||
class BroadcastHandler : public IMenuHandler
|
||||
class VoteMenuHandler : public IVoteMenuHandler
|
||||
{
|
||||
public:
|
||||
BroadcastHandler(IMenuHandler *handler);
|
||||
public: //IMenuHandler
|
||||
unsigned int GetMenuAPIVersion2();
|
||||
void OnMenuStart(IBaseMenu *menu);
|
||||
void OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *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();
|
||||
void OnMenuEnd(IBaseMenu *menu);
|
||||
void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
|
||||
void OnMenuDisplayItem(IBaseMenu *menu, int client, unsigned int item, const char **display);
|
||||
public: //IVoteMenuHandler
|
||||
bool IsVoteInProgress();
|
||||
void InitializeVoting(IBaseMenu *menu);
|
||||
void StartVoting();
|
||||
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);
|
||||
void Reset(IMenuHandler *mh);
|
||||
private:
|
||||
CVector<unsigned int> m_counts;
|
||||
CVector<unsigned int> m_ties;
|
||||
unsigned int numItems;
|
||||
IMenuVoteHandler *m_pVoteHandler;
|
||||
void DecrementPlayerCount();
|
||||
void EndVoting();
|
||||
void InternalReset();
|
||||
private:
|
||||
IMenuHandler *m_pHandler;
|
||||
unsigned int m_Clients;
|
||||
unsigned int m_Items;
|
||||
CVector<unsigned int> m_Votes;
|
||||
CVector<unsigned int> m_Dups;
|
||||
IBaseMenu *m_pCurMenu;
|
||||
bool m_bStarted;
|
||||
unsigned int m_NumVotes;
|
||||
};
|
||||
|
||||
class MenuManager :
|
||||
@ -84,35 +84,24 @@ 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();
|
||||
void AddStyle(IMenuStyle *style);
|
||||
bool SetDefaultStyle(IMenuStyle *style);
|
||||
IMenuPanel *RenderMenu(int client, menu_states_t &states, ItemOrder order);
|
||||
IVoteMenuHandler *CreateVoteWrapper(IMenuHandler *mh);
|
||||
void ReleaseVoteWrapper(IVoteMenuHandler *mh);
|
||||
public: //IHandleTypeDispatch
|
||||
void OnHandleDestroy(HandleType_t type, void *object);
|
||||
public:
|
||||
HandleError ReadMenuHandle(Handle_t handle, IBaseMenu **menu);
|
||||
HandleError ReadStyleHandle(Handle_t handle, IMenuStyle **style);
|
||||
protected:
|
||||
void FreeBroadcastHandler(BroadcastHandler *bh);
|
||||
void FreeVoteHandler(VoteHandler *vh);
|
||||
Handle_t CreateMenuHandle(IBaseMenu *menu, IdentityToken_t *pOwner);
|
||||
Handle_t CreateStyleHandle(IMenuStyle *style);
|
||||
private:
|
||||
int m_ShowMenu;
|
||||
IMenuStyle *m_pDefaultStyle;
|
||||
CStack<BroadcastHandler *> m_BroadcastHandlers;
|
||||
CStack<VoteHandler *> m_VoteHandlers;
|
||||
CStack<VoteMenuHandler *> m_VoteHandlers;
|
||||
CVector<IMenuStyle *> m_Styles;
|
||||
HandleType_t m_StyleType;
|
||||
HandleType_t m_MenuType;
|
||||
|
@ -434,12 +434,14 @@ bool BaseMenuStyle::RedoClientMenu(int client, ItemOrder order)
|
||||
CBaseMenu::CBaseMenu(IMenuHandler *pHandler, IMenuStyle *pStyle, IdentityToken_t *pOwner) :
|
||||
m_pStyle(pStyle), m_Strings(512), m_Pagination(7), m_ExitButton(true),
|
||||
m_bShouldDelete(false), m_bCancelling(false), m_pOwner(pOwner ? pOwner : g_pCoreIdent),
|
||||
m_bDeleting(false), m_bWillFreeHandle(false), m_hHandle(BAD_HANDLE), m_pHandler(pHandler)
|
||||
m_bDeleting(false), m_bWillFreeHandle(false), m_hHandle(BAD_HANDLE), m_pHandler(pHandler),
|
||||
m_pVoteHandler(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CBaseMenu::~CBaseMenu()
|
||||
{
|
||||
g_Menus.ReleaseVoteWrapper(m_pVoteHandler);
|
||||
}
|
||||
|
||||
Handle_t CBaseMenu::GetHandle()
|
||||
@ -647,3 +649,24 @@ void CBaseMenu::InternalDelete()
|
||||
delete this;
|
||||
}
|
||||
|
||||
bool CBaseMenu::BroadcastVote(int clients[],
|
||||
unsigned int numClients,
|
||||
unsigned int maxTime,
|
||||
unsigned int flags)
|
||||
{
|
||||
if (!m_pVoteHandler)
|
||||
{
|
||||
m_pVoteHandler = g_Menus.CreateVoteWrapper(m_pHandler);
|
||||
} else if (m_pVoteHandler->IsVoteInProgress()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pVoteHandler->InitializeVoting(this);
|
||||
|
||||
for (unsigned int i=0; i<numClients; i++)
|
||||
{
|
||||
VoteDisplay(clients[i], maxTime);
|
||||
}
|
||||
|
||||
m_pVoteHandler->StartVoting();
|
||||
}
|
||||
|
@ -111,6 +111,12 @@ public:
|
||||
virtual void Destroy(bool releaseHandle);
|
||||
virtual void Cancel_Finally() =0;
|
||||
virtual Handle_t GetHandle();
|
||||
bool BroadcastVote(int clients[],
|
||||
unsigned int numClients,
|
||||
unsigned int maxTime,
|
||||
unsigned int flags=0);
|
||||
public:
|
||||
virtual void VoteDisplay(int client, unsigned int maxTime) =0;
|
||||
private:
|
||||
void InternalDelete();
|
||||
protected:
|
||||
@ -127,6 +133,7 @@ protected:
|
||||
bool m_bWillFreeHandle;
|
||||
Handle_t m_hHandle;
|
||||
IMenuHandler *m_pHandler;
|
||||
IVoteMenuHandler *m_pVoteHandler;
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_MENUSTYLE_BASE_H
|
||||
|
@ -366,9 +366,24 @@ IMenuPanel *CRadioMenu::CreatePanel()
|
||||
|
||||
bool CRadioMenu::Display(int client, unsigned int time)
|
||||
{
|
||||
if (m_bCancelling)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return g_RadioMenuStyle.DoClientMenu(client, this, m_pHandler, time);
|
||||
}
|
||||
|
||||
void CRadioMenu::VoteDisplay(int client, unsigned int maxTime)
|
||||
{
|
||||
if (m_bCancelling)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_RadioMenuStyle.DoClientMenu(client, this, m_pVoteHandler, maxTime);
|
||||
}
|
||||
|
||||
void CRadioMenu::Cancel_Finally()
|
||||
{
|
||||
g_RadioMenuStyle.CancelMenu(this);
|
||||
|
@ -98,6 +98,7 @@ public:
|
||||
IMenuPanel *CreatePanel();
|
||||
bool Display(int client, unsigned int time);
|
||||
void Cancel_Finally();
|
||||
void VoteDisplay(int client, unsigned int maxTime);
|
||||
};
|
||||
|
||||
extern CRadioStyle g_RadioMenuStyle;
|
||||
|
@ -375,6 +375,16 @@ bool CValveMenu::Display(int client, unsigned int time)
|
||||
return g_ValveMenuStyle.DoClientMenu(client, this, m_pHandler, time);
|
||||
}
|
||||
|
||||
void CValveMenu::VoteDisplay(int client, unsigned int maxTime)
|
||||
{
|
||||
if (m_bCancelling)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_ValveMenuStyle.DoClientMenu(client, this, m_pVoteHandler, maxTime);
|
||||
}
|
||||
|
||||
IMenuPanel *CValveMenu::CreatePanel()
|
||||
{
|
||||
return new CValveMenuDisplay(this);
|
||||
|
@ -103,6 +103,7 @@ public: //IBaseMenu
|
||||
bool SetExitButton(bool set);
|
||||
bool SetPagination(unsigned int itemsPerPage);
|
||||
bool Display(int client, unsigned int time);
|
||||
void VoteDisplay(int client, unsigned int maxTime);
|
||||
public: //CBaseMenu
|
||||
void Cancel_Finally();
|
||||
private:
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <IHandleSys.h>
|
||||
|
||||
#define SMINTERFACE_MENUMANAGER_NAME "IMenuManager"
|
||||
#define SMINTERFACE_MENUMANAGER_VERSION 1
|
||||
#define SMINTERFACE_MENUMANAGER_VERSION 2
|
||||
|
||||
/**
|
||||
* @file IMenuManager.h
|
||||
@ -498,6 +498,23 @@ namespace SourceMod
|
||||
* @return Handle_t handle value.
|
||||
*/
|
||||
virtual Handle_t GetHandle() =0;
|
||||
|
||||
/**
|
||||
* @brief Sends a menu to multiple clients as a vote menu. All callbacks
|
||||
* will be sent as normal, except two extras, OnMenuVoteStart and
|
||||
* OnMenuVoteEnd, will be called.
|
||||
*
|
||||
* @param clients Array of client indexes.
|
||||
* @param numClients Number of client indexes in the array.
|
||||
* @param maxTime Maximum amount of time to hold the vote.
|
||||
* @param flags Optional voting flags (currently unused).
|
||||
* @return True on success, false if a vote is already in
|
||||
* progress (the menu must be cancelled first).
|
||||
*/
|
||||
virtual bool BroadcastVote(int clients[],
|
||||
unsigned int numClients,
|
||||
unsigned int maxTime,
|
||||
unsigned int flags=0) =0;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -600,21 +617,55 @@ namespace SourceMod
|
||||
virtual void OnMenuDisplayItem(IBaseMenu *menu, int client, unsigned int item, const char **display)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Handles a vote menu.
|
||||
*/
|
||||
class IMenuVoteHandler : public IMenuHandler
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Called when a vote ends.
|
||||
* @brief Called when a vote has been started and displayed to
|
||||
* clients. This is called after OnMenuStart() and OnMenuDisplay(),
|
||||
* but before OnMenuSelect().
|
||||
*
|
||||
* @param menu Menu pointer.
|
||||
*/
|
||||
virtual void OnMenuVoteStart(IBaseMenu *menu)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Called when a vote ends. This is automatically called by the
|
||||
* wrapper, and never needs to called from a style implementation.
|
||||
*
|
||||
* @param menu Menu pointer.
|
||||
* @param item Item position that was chosen by a majority.
|
||||
*/
|
||||
virtual void OnMenuVoteEnd(IBaseMenu *menu, unsigned int item) =0;
|
||||
virtual void OnMenuVoteEnd(IBaseMenu *menu, unsigned int item)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Contains functions for managing a vote handler.
|
||||
*/
|
||||
class IVoteMenuHandler : public IMenuHandler
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Returns whether or not a vote is in progress.
|
||||
*
|
||||
* @return True if a vote is in progress, false otherwise.
|
||||
*/
|
||||
virtual bool IsVoteInProgress() =0;
|
||||
|
||||
/**
|
||||
* @brief Use this to mark the vote as in progress (start).
|
||||
*
|
||||
* @param menu Menu pointer.
|
||||
*/
|
||||
virtual void InitializeVoting(IBaseMenu *menu) =0;
|
||||
|
||||
/**
|
||||
* @brief Use this to notify that all clients' displays have been
|
||||
* processed (i.e., there are no more clients to display to).
|
||||
*/
|
||||
virtual void StartVoting() =0;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -640,39 +691,6 @@ namespace SourceMod
|
||||
*/
|
||||
virtual IMenuStyle *FindStyleByName(const char *name) =0;
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* @brief Broadcasts a menu to a number of clients.
|
||||
*
|
||||
* @param menu Menu pointer.
|
||||
* @param clients Array of client indexes.
|
||||
* @param numClients Number of clients in the array.
|
||||
* @param time Time to hold the menu.
|
||||
* @return Number of clients the menu will be waiting on.
|
||||
*/
|
||||
virtual unsigned int BroadcastMenu(IBaseMenu *menu,
|
||||
IMenuHandler *handler,
|
||||
int clients[],
|
||||
unsigned int numClients,
|
||||
unsigned int time) =0;
|
||||
|
||||
/**
|
||||
* @brief Broadcasts a menu to a number of clients as a vote menu.
|
||||
*
|
||||
* @param menu Menu pointer.
|
||||
* @param handler IMenuHandler pointer.
|
||||
* @param clients Array of client indexes.
|
||||
* @param numClients Number of clients in the array.
|
||||
* @param time Time to hold the menu.
|
||||
* @return Number of clients the menu will be waiting on.
|
||||
*/
|
||||
virtual unsigned int VoteMenu(IBaseMenu *menu,
|
||||
IMenuVoteHandler *handler,
|
||||
int clients[],
|
||||
unsigned int numClients,
|
||||
unsigned int time) =0;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Returns the default draw style Core is using.
|
||||
*
|
||||
@ -695,6 +713,27 @@ namespace SourceMod
|
||||
* be freed using IMenuPanel::DeleteThis.
|
||||
*/
|
||||
virtual IMenuPanel *RenderMenu(int client, menu_states_t &states, ItemOrder order) =0;
|
||||
|
||||
/**
|
||||
* @brief Creates a standard voting wrapper. The wrapper is not
|
||||
* re-entrant; a second menu cannot be displayed on the same handler
|
||||
* at the same time.
|
||||
*
|
||||
* @param mh Menu handler to wrap around.
|
||||
* @return An IMenuHandler pointer that is a wrapper
|
||||
* around IMenuHandler callbacks to invoke
|
||||
* voting related callbacks.
|
||||
*/
|
||||
virtual IVoteMenuHandler *CreateVoteWrapper(IMenuHandler *mh) =0;
|
||||
|
||||
/**
|
||||
* @brief Frees a standard voting wrapper.
|
||||
*
|
||||
* @param mh Menu handler pointer created by
|
||||
* CreateVoteWrapper(). NULL values will be
|
||||
* safely ignored.
|
||||
*/
|
||||
virtual void ReleaseVoteWrapper(IVoteMenuHandler *mh) =0;
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user