Implement per-client randomized menus with MenuShufflePerClient native.
Add MenuSetClientMapping native.
This commit is contained in:
		
							parent
							
								
									7ed4e88915
								
							
						
					
					
						commit
						2c8071995d
					
				@ -308,7 +308,7 @@ IMenuPanel *MenuManager::RenderMenu(int client, menu_states_t &md, ItemOrder ord
 | 
			
		||||
	{
 | 
			
		||||
		ItemDrawInfo &dr = drawItems[foundItems].draw;
 | 
			
		||||
		/* Is the item valid? */
 | 
			
		||||
		if (menu->GetItemInfo(i, &dr) != NULL)
 | 
			
		||||
		if (menu->GetItemInfo(i, &dr, client) != NULL)
 | 
			
		||||
		{
 | 
			
		||||
			/* Ask the user to change the style, if necessary */
 | 
			
		||||
			mh->OnMenuDrawItem(menu, client, i, dr.style);
 | 
			
		||||
@ -398,7 +398,7 @@ IMenuPanel *MenuManager::RenderMenu(int client, menu_states_t &md, ItemOrder ord
 | 
			
		||||
			}
 | 
			
		||||
			while (++lastItem < totalItems)
 | 
			
		||||
			{
 | 
			
		||||
				if (menu->GetItemInfo(lastItem, &dr) != NULL)
 | 
			
		||||
				if (menu->GetItemInfo(lastItem, &dr, client) != NULL)
 | 
			
		||||
				{
 | 
			
		||||
					mh->OnMenuDrawItem(menu, client, lastItem, dr.style);
 | 
			
		||||
					if (IsSlotItem(panel, dr.style))
 | 
			
		||||
@ -420,7 +420,7 @@ IMenuPanel *MenuManager::RenderMenu(int client, menu_states_t &md, ItemOrder ord
 | 
			
		||||
			lastItem--;
 | 
			
		||||
			while (lastItem != 0)
 | 
			
		||||
			{
 | 
			
		||||
				if (menu->GetItemInfo(lastItem, &dr) != NULL)
 | 
			
		||||
				if (menu->GetItemInfo(lastItem, &dr, client) != NULL)
 | 
			
		||||
				{
 | 
			
		||||
					mh->OnMenuDrawItem(menu, client, lastItem, dr.style);
 | 
			
		||||
					if (IsSlotItem(panel, dr.style))
 | 
			
		||||
 | 
			
		||||
@ -633,7 +633,7 @@ bool CBaseMenu::AppendItem(const char *info, const ItemDrawInfo &draw)
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	CItem item;
 | 
			
		||||
	CItem item(m_items.length());
 | 
			
		||||
 | 
			
		||||
	item.info = info;
 | 
			
		||||
	if (draw.display)
 | 
			
		||||
@ -655,7 +655,7 @@ bool CBaseMenu::InsertItem(unsigned int position, const char *info, const ItemDr
 | 
			
		||||
	if (position >= m_items.length())
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	CItem item;
 | 
			
		||||
	CItem item(position);
 | 
			
		||||
	item.info = info;
 | 
			
		||||
	if (draw.display)
 | 
			
		||||
		item.display = new ke::AString(draw.display);
 | 
			
		||||
@ -679,11 +679,16 @@ void CBaseMenu::RemoveAllItems()
 | 
			
		||||
	m_items.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =NULL */)
 | 
			
		||||
const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =NULL */, int client/* =0 */)
 | 
			
		||||
{
 | 
			
		||||
	if (position >= m_items.length())
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	if (client > 0 && position < m_RandomMaps[client].length())
 | 
			
		||||
	{
 | 
			
		||||
		position = m_RandomMaps[client][position];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (draw)
 | 
			
		||||
	{
 | 
			
		||||
		draw->display = m_items[position].display->chars();
 | 
			
		||||
@ -693,6 +698,62 @@ const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =
 | 
			
		||||
	return m_items[position].info.chars();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CBaseMenu::ShufflePerClient(int start, int stop)
 | 
			
		||||
{
 | 
			
		||||
	// limit map len to 255 items since it's using uint8
 | 
			
		||||
	int length = MIN(GetItemCount(), 255);
 | 
			
		||||
	if (stop >= 0)
 | 
			
		||||
		length = MIN(length, stop);
 | 
			
		||||
 | 
			
		||||
	for (int i = 1; i < SM_MAXPLAYERS + 1; i++)
 | 
			
		||||
	{
 | 
			
		||||
		// populate per-client map ...
 | 
			
		||||
		m_RandomMaps[i].resize(length);
 | 
			
		||||
		for (int j = 0; j < length; j++)
 | 
			
		||||
			m_RandomMaps[i][j] = j;
 | 
			
		||||
 | 
			
		||||
		// ... and random shuffle it
 | 
			
		||||
		for (int j = length - 1; j > start; j--)
 | 
			
		||||
		{
 | 
			
		||||
			int x = rand() % (j - start + 1) + start;
 | 
			
		||||
			uint8_t tmp = m_RandomMaps[i][x];
 | 
			
		||||
			m_RandomMaps[i][x] = m_RandomMaps[i][j];
 | 
			
		||||
			m_RandomMaps[i][j] = tmp;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CBaseMenu::SetClientMapping(int client, int *array, int length)
 | 
			
		||||
{
 | 
			
		||||
	length = MIN(length, 255);
 | 
			
		||||
	m_RandomMaps[client].resize(length);
 | 
			
		||||
	for (int i = 0; i < length; i++)
 | 
			
		||||
	{
 | 
			
		||||
		m_RandomMaps[client][i] = array[i];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CBaseMenu::IsPerClientShuffled()
 | 
			
		||||
{
 | 
			
		||||
	for (int i = 1; i < SM_MAXPLAYERS + 1; i++)
 | 
			
		||||
	{
 | 
			
		||||
		if(m_RandomMaps[i].length() > 0)
 | 
			
		||||
			return true;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int CBaseMenu::GetRealItemIndex(int client, unsigned int position)
 | 
			
		||||
{
 | 
			
		||||
	if (client > 0 && position < m_RandomMaps[client].length())
 | 
			
		||||
	{
 | 
			
		||||
		position = m_RandomMaps[client][position];
 | 
			
		||||
		return m_items[position].index;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return position;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int CBaseMenu::GetItemCount()
 | 
			
		||||
{
 | 
			
		||||
	return m_items.length();
 | 
			
		||||
 | 
			
		||||
@ -44,8 +44,9 @@ using namespace SourceMod;
 | 
			
		||||
class CItem
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	CItem()
 | 
			
		||||
	CItem(unsigned int index)
 | 
			
		||||
	{
 | 
			
		||||
		this->index = index;
 | 
			
		||||
		style = 0;
 | 
			
		||||
		access = 0;
 | 
			
		||||
	}
 | 
			
		||||
@ -53,11 +54,13 @@ public:
 | 
			
		||||
	: info(ke::Move(other.info)),
 | 
			
		||||
	  display(ke::Move(other.display))
 | 
			
		||||
	{
 | 
			
		||||
		index = other.index;
 | 
			
		||||
		style = other.style;
 | 
			
		||||
		access = other.access;
 | 
			
		||||
	}
 | 
			
		||||
	CItem & operator =(CItem &&other)
 | 
			
		||||
	{
 | 
			
		||||
		index = other.index;
 | 
			
		||||
		info = ke::Move(other.info);
 | 
			
		||||
		display = ke::Move(other.display);
 | 
			
		||||
		style = other.style;
 | 
			
		||||
@ -66,6 +69,7 @@ public:
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	unsigned int index;
 | 
			
		||||
	ke::AString info;
 | 
			
		||||
	ke::AutoPtr<ke::AString> display;
 | 
			
		||||
	unsigned int style;
 | 
			
		||||
@ -138,7 +142,7 @@ public:
 | 
			
		||||
	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 const char *GetItemInfo(unsigned int position, ItemDrawInfo *draw=NULL, int client=0);
 | 
			
		||||
	virtual unsigned int GetItemCount();
 | 
			
		||||
	virtual bool SetPagination(unsigned int itemsPerPage);
 | 
			
		||||
	virtual unsigned int GetPagination();
 | 
			
		||||
@ -152,6 +156,10 @@ public:
 | 
			
		||||
	virtual unsigned int GetMenuOptionFlags();
 | 
			
		||||
	virtual void SetMenuOptionFlags(unsigned int flags);
 | 
			
		||||
	virtual IMenuHandler *GetHandler();
 | 
			
		||||
	virtual void ShufflePerClient(int start, int stop);
 | 
			
		||||
	virtual void SetClientMapping(int client, int *array, int length);
 | 
			
		||||
	virtual bool IsPerClientShuffled();
 | 
			
		||||
	virtual unsigned int GetRealItemIndex(int client, unsigned int position);
 | 
			
		||||
	unsigned int GetBaseMemUsage();
 | 
			
		||||
private:
 | 
			
		||||
	void InternalDelete();
 | 
			
		||||
@ -168,6 +176,7 @@ protected:
 | 
			
		||||
	Handle_t m_hHandle;
 | 
			
		||||
	IMenuHandler *m_pHandler;
 | 
			
		||||
	unsigned int m_nFlags;
 | 
			
		||||
	ke::Vector<uint8_t> m_RandomMaps[SM_MAXPLAYERS+1];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif //_INCLUDE_MENUSTYLE_BASE_H
 | 
			
		||||
 | 
			
		||||
@ -514,15 +514,16 @@ void VoteMenuHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int ite
 | 
			
		||||
	/* Check by our item count, NOT the vote array size */
 | 
			
		||||
	if (item < m_Items)
 | 
			
		||||
	{
 | 
			
		||||
		m_ClientVotes[client] = item;
 | 
			
		||||
		m_Votes[item]++;
 | 
			
		||||
		unsigned int index = menu->GetRealItemIndex(client, item);
 | 
			
		||||
		m_ClientVotes[client] = index;
 | 
			
		||||
		m_Votes[index]++;
 | 
			
		||||
		m_NumVotes++;
 | 
			
		||||
 | 
			
		||||
		if (sm_vote_chat.GetBool() || sm_vote_console.GetBool() || sm_vote_client_console.GetBool())
 | 
			
		||||
		{
 | 
			
		||||
			static char buffer[1024];
 | 
			
		||||
			ItemDrawInfo dr;
 | 
			
		||||
			menu->GetItemInfo(item, &dr);
 | 
			
		||||
			menu->GetItemInfo(item, &dr, client);
 | 
			
		||||
 | 
			
		||||
			if (sm_vote_console.GetBool())
 | 
			
		||||
			{
 | 
			
		||||
 | 
			
		||||
@ -816,8 +816,14 @@ static cell_t GetMenuItem(IPluginContext *pContext, const cell_t *params)
 | 
			
		||||
 | 
			
		||||
	ItemDrawInfo dr;
 | 
			
		||||
	const char *info;
 | 
			
		||||
	cell_t client = (params[0] >= 8) ? params[8] : 0;
 | 
			
		||||
	if(!client && menu->IsPerClientShuffled())
 | 
			
		||||
	{
 | 
			
		||||
		return pContext->ThrowNativeError("This menu has been per-client random shuffled. "
 | 
			
		||||
										  "You have to call GetMenuItem with a client index!");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((info=menu->GetItemInfo(params[2], &dr)) == NULL)
 | 
			
		||||
	if ((info=menu->GetItemInfo(params[2], &dr, client)) == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@ -832,6 +838,57 @@ static cell_t GetMenuItem(IPluginContext *pContext, const cell_t *params)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cell_t MenuShufflePerClient(IPluginContext *pContext, const cell_t *params)
 | 
			
		||||
{
 | 
			
		||||
	Handle_t hndl = (Handle_t)params[1];
 | 
			
		||||
	HandleError err;
 | 
			
		||||
	IBaseMenu *menu;
 | 
			
		||||
 | 
			
		||||
	if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
 | 
			
		||||
	{
 | 
			
		||||
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int start = params[2];
 | 
			
		||||
	int stop = params[3];
 | 
			
		||||
 | 
			
		||||
	if (stop > 0 && !(stop >= start))
 | 
			
		||||
	{
 | 
			
		||||
		return pContext->ThrowNativeError("Stop must be -1 or >= start!");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	menu->ShufflePerClient(start, stop);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cell_t MenuSetClientMapping(IPluginContext *pContext, const cell_t *params)
 | 
			
		||||
{
 | 
			
		||||
	Handle_t hndl = (Handle_t)params[1];
 | 
			
		||||
	HandleError err;
 | 
			
		||||
	IBaseMenu *menu;
 | 
			
		||||
 | 
			
		||||
	if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
 | 
			
		||||
	{
 | 
			
		||||
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int client = params[2];
 | 
			
		||||
	if (client < 1 || client > SM_MAXPLAYERS)
 | 
			
		||||
	{
 | 
			
		||||
		return pContext->ThrowNativeError("Invalid client index!");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cell_t *array;
 | 
			
		||||
	pContext->LocalToPhysAddr(params[3], &array);
 | 
			
		||||
 | 
			
		||||
	int length = params[4];
 | 
			
		||||
 | 
			
		||||
	menu->SetClientMapping(client, array, length);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cell_t SetMenuPagination(IPluginContext *pContext, const cell_t *params)
 | 
			
		||||
{
 | 
			
		||||
	Handle_t hndl = (Handle_t)params[1];
 | 
			
		||||
@ -1645,6 +1702,8 @@ REGISTER_NATIVES(menuNatives)
 | 
			
		||||
	{"SetPanelKeys",			SetPanelKeys},
 | 
			
		||||
	{"SetVoteResultCallback",	SetVoteResultCallback},
 | 
			
		||||
	{"VoteMenu",				VoteMenu},
 | 
			
		||||
	{"MenuShufflePerClient",	MenuShufflePerClient},
 | 
			
		||||
	{"MenuSetClientMapping",	MenuSetClientMapping},
 | 
			
		||||
	{"SetMenuNoVoteButton",		SetMenuNoVoteButton},
 | 
			
		||||
 | 
			
		||||
	// Transitional syntax support.
 | 
			
		||||
@ -1673,6 +1732,8 @@ REGISTER_NATIVES(menuNatives)
 | 
			
		||||
	{"Menu.ToPanel",			CreatePanelFromMenu},
 | 
			
		||||
	{"Menu.Cancel",				CancelMenu},
 | 
			
		||||
	{"Menu.DisplayVote",		VoteMenu},
 | 
			
		||||
	{"Menu.ShufflePerClient",	MenuShufflePerClient},
 | 
			
		||||
	{"Menu.SetClientMapping",	MenuSetClientMapping},
 | 
			
		||||
	{"Menu.Pagination.get",		GetMenuPagination},
 | 
			
		||||
	{"Menu.Pagination.set",		SetMenuPagination},
 | 
			
		||||
	{"Menu.OptionFlags.get",	GetMenuOptionFlags},
 | 
			
		||||
 | 
			
		||||
@ -307,9 +307,23 @@ methodmap Menu < Handle
 | 
			
		||||
	// @param style         By-reference variable to store drawing flags.
 | 
			
		||||
	// @param dispBuf       Display buffer.
 | 
			
		||||
	// @param dispBufLen    Maximum length of the display buffer.
 | 
			
		||||
	// @param client		Client index. Must be specified if menu is per-client random shuffled, -1 to ignore.
 | 
			
		||||
	// @return              True on success, false if position is invalid.
 | 
			
		||||
	public native bool GetItem(int position, char[] infoBuf, int infoBufLen,
 | 
			
		||||
							   int &style=0, char[] dispBuf="", int dispBufLen=0);
 | 
			
		||||
							   int &style=0, char[] dispBuf="", int dispBufLen=0, int client=0);
 | 
			
		||||
 | 
			
		||||
	// Generates a per-client random mapping for the current vote options.
 | 
			
		||||
	//
 | 
			
		||||
	// @param start         Menu item index to start randomizing from.
 | 
			
		||||
	// @param stop          Menu item index to stop randomizing at. -1 = infinite
 | 
			
		||||
	public native void ShufflePerClient(int start=0, int stop=-1);
 | 
			
		||||
 | 
			
		||||
	// Fills the client vote option mapping with user supplied values.
 | 
			
		||||
	//
 | 
			
		||||
	// @param client		Client index.
 | 
			
		||||
	// @param array			Integer array with mapping.
 | 
			
		||||
	// @param length		Length of array.
 | 
			
		||||
	public native void SetClientMapping(int client, int[] array, int length);
 | 
			
		||||
 | 
			
		||||
	// Sets the menu's default title/instruction message.
 | 
			
		||||
	//
 | 
			
		||||
@ -537,6 +551,7 @@ native void RemoveAllMenuItems(Handle menu);
 | 
			
		||||
 * @param style         By-reference variable to store drawing flags.
 | 
			
		||||
 * @param dispBuf       Display buffer.
 | 
			
		||||
 * @param dispBufLen    Maximum length of the display buffer.
 | 
			
		||||
 * @param client		Client index. Must be specified if menu is per-client random shuffled, -1 to ignore.
 | 
			
		||||
 * @return              True on success, false if position is invalid.
 | 
			
		||||
 * @error               Invalid Handle.
 | 
			
		||||
 */
 | 
			
		||||
@ -546,7 +561,27 @@ native bool GetMenuItem(Handle menu,
 | 
			
		||||
						int infoBufLen,
 | 
			
		||||
						int &style=0,
 | 
			
		||||
						char[] dispBuf="",
 | 
			
		||||
						int dispBufLen=0);
 | 
			
		||||
						int dispBufLen=0,
 | 
			
		||||
						int client=0);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generates a per-client random mapping for the current vote options.
 | 
			
		||||
 *
 | 
			
		||||
 * @param menu          Menu Handle.
 | 
			
		||||
 * @param start         Menu item index to start randomizing from.
 | 
			
		||||
 * @param stop          Menu item index to stop randomizing at. -1 = infinite
 | 
			
		||||
 */
 | 
			
		||||
native void MenuShufflePerClient(Handle menu, int start=0, int stop=-1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Fills the client vote option mapping with user supplied values.
 | 
			
		||||
 *
 | 
			
		||||
 * @param menu          Menu Handle.
 | 
			
		||||
 * @param client		Client index.
 | 
			
		||||
 * @param array			Integer array with mapping.
 | 
			
		||||
 * @param length		Length of array.
 | 
			
		||||
 */
 | 
			
		||||
native void MenuSetClientMapping(Handle menu, int client, int[] array, int length);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns the first item on the page of a currently selected menu.
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@
 | 
			
		||||
#include <IHandleSys.h>
 | 
			
		||||
 | 
			
		||||
#define SMINTERFACE_MENUMANAGER_NAME		"IMenuManager"
 | 
			
		||||
#define SMINTERFACE_MENUMANAGER_VERSION		16
 | 
			
		||||
#define SMINTERFACE_MENUMANAGER_VERSION		17
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file IMenuManager.h
 | 
			
		||||
@ -485,9 +485,10 @@ namespace SourceMod
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param position		Position, starting from 0.
 | 
			
		||||
		 * @param draw			Optional pointer to store a draw information.
 | 
			
		||||
		 * @param client		Client index. (Important for randomized menus.)
 | 
			
		||||
		 * @return				Info string pointer, or NULL if position was invalid.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual const char *GetItemInfo(unsigned int position, ItemDrawInfo *draw) =0;
 | 
			
		||||
		virtual const char *GetItemInfo(unsigned int position, ItemDrawInfo *draw, int client=0) =0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Returns the number of items.
 | 
			
		||||
@ -636,6 +637,35 @@ namespace SourceMod
 | 
			
		||||
		 * @return				Approximate number of bytes being used.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual unsigned int GetApproxMemUsage() =0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Generates a per-client random mapping for the current vote options.
 | 
			
		||||
		 * @param start			Menu item index to start randomizing from.
 | 
			
		||||
		 * @param stop			Menu item index to stop randomizing at. -1 = infinite
 | 
			
		||||
		 */
 | 
			
		||||
		virtual void ShufflePerClient(int start=0, int stop=-1) =0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Fills the client vote option mapping with user supplied values.
 | 
			
		||||
		 * @param client		Client index.
 | 
			
		||||
		 * @param array			Integer array with mapping.
 | 
			
		||||
		 * @param length		Length of array.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual void SetClientMapping(int client, int *array, int length) =0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Returns true if the menu has a per-client random mapping.
 | 
			
		||||
		 * @return				True on success, false otherwise.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual bool IsPerClientShuffled() =0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Returns the actual (not shuffled) item index from the client position.
 | 
			
		||||
		 * @param client		Client index.
 | 
			
		||||
		 * @param position		Position, starting from 0.
 | 
			
		||||
		 * @return				Actual item index in menu.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual unsigned int GetRealItemIndex(int client, unsigned int position) =0;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user