Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0bda47d85b |
@@ -308,7 +308,7 @@ IMenuPanel *MenuManager::RenderMenu(int client, menu_states_t &md, ItemOrder ord
|
|||||||
{
|
{
|
||||||
ItemDrawInfo &dr = drawItems[foundItems].draw;
|
ItemDrawInfo &dr = drawItems[foundItems].draw;
|
||||||
/* Is the item valid? */
|
/* Is the item valid? */
|
||||||
if (menu->GetItemInfo(i, &dr, client) != NULL)
|
if (menu->GetItemInfo(i, &dr) != NULL)
|
||||||
{
|
{
|
||||||
/* Ask the user to change the style, if necessary */
|
/* Ask the user to change the style, if necessary */
|
||||||
mh->OnMenuDrawItem(menu, client, i, dr.style);
|
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)
|
while (++lastItem < totalItems)
|
||||||
{
|
{
|
||||||
if (menu->GetItemInfo(lastItem, &dr, client) != NULL)
|
if (menu->GetItemInfo(lastItem, &dr) != NULL)
|
||||||
{
|
{
|
||||||
mh->OnMenuDrawItem(menu, client, lastItem, dr.style);
|
mh->OnMenuDrawItem(menu, client, lastItem, dr.style);
|
||||||
if (IsSlotItem(panel, dr.style))
|
if (IsSlotItem(panel, dr.style))
|
||||||
@@ -420,7 +420,7 @@ IMenuPanel *MenuManager::RenderMenu(int client, menu_states_t &md, ItemOrder ord
|
|||||||
lastItem--;
|
lastItem--;
|
||||||
while (lastItem != 0)
|
while (lastItem != 0)
|
||||||
{
|
{
|
||||||
if (menu->GetItemInfo(lastItem, &dr, client) != NULL)
|
if (menu->GetItemInfo(lastItem, &dr) != NULL)
|
||||||
{
|
{
|
||||||
mh->OnMenuDrawItem(menu, client, lastItem, dr.style);
|
mh->OnMenuDrawItem(menu, client, lastItem, dr.style);
|
||||||
if (IsSlotItem(panel, dr.style))
|
if (IsSlotItem(panel, dr.style))
|
||||||
|
|||||||
+3
-64
@@ -633,7 +633,7 @@ bool CBaseMenu::AppendItem(const char *info, const ItemDrawInfo &draw)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CItem item(m_items.length());
|
CItem item;
|
||||||
|
|
||||||
item.info = info;
|
item.info = info;
|
||||||
if (draw.display)
|
if (draw.display)
|
||||||
@@ -655,7 +655,7 @@ bool CBaseMenu::InsertItem(unsigned int position, const char *info, const ItemDr
|
|||||||
if (position >= m_items.length())
|
if (position >= m_items.length())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CItem item(position);
|
CItem item;
|
||||||
item.info = info;
|
item.info = info;
|
||||||
if (draw.display)
|
if (draw.display)
|
||||||
item.display = new ke::AString(draw.display);
|
item.display = new ke::AString(draw.display);
|
||||||
@@ -679,16 +679,11 @@ void CBaseMenu::RemoveAllItems()
|
|||||||
m_items.clear();
|
m_items.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =NULL */, int client/* =0 */)
|
const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =NULL */)
|
||||||
{
|
{
|
||||||
if (position >= m_items.length())
|
if (position >= m_items.length())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (client > 0 && position < m_RandomMaps[client].length())
|
|
||||||
{
|
|
||||||
position = m_RandomMaps[client][position];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (draw)
|
if (draw)
|
||||||
{
|
{
|
||||||
draw->display = m_items[position].display->chars();
|
draw->display = m_items[position].display->chars();
|
||||||
@@ -698,62 +693,6 @@ const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =
|
|||||||
return m_items[position].info.chars();
|
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()
|
unsigned int CBaseMenu::GetItemCount()
|
||||||
{
|
{
|
||||||
return m_items.length();
|
return m_items.length();
|
||||||
|
|||||||
+2
-11
@@ -44,9 +44,8 @@ using namespace SourceMod;
|
|||||||
class CItem
|
class CItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CItem(unsigned int index)
|
CItem()
|
||||||
{
|
{
|
||||||
this->index = index;
|
|
||||||
style = 0;
|
style = 0;
|
||||||
access = 0;
|
access = 0;
|
||||||
}
|
}
|
||||||
@@ -54,13 +53,11 @@ public:
|
|||||||
: info(ke::Move(other.info)),
|
: info(ke::Move(other.info)),
|
||||||
display(ke::Move(other.display))
|
display(ke::Move(other.display))
|
||||||
{
|
{
|
||||||
index = other.index;
|
|
||||||
style = other.style;
|
style = other.style;
|
||||||
access = other.access;
|
access = other.access;
|
||||||
}
|
}
|
||||||
CItem & operator =(CItem &&other)
|
CItem & operator =(CItem &&other)
|
||||||
{
|
{
|
||||||
index = other.index;
|
|
||||||
info = ke::Move(other.info);
|
info = ke::Move(other.info);
|
||||||
display = ke::Move(other.display);
|
display = ke::Move(other.display);
|
||||||
style = other.style;
|
style = other.style;
|
||||||
@@ -69,7 +66,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned int index;
|
|
||||||
ke::AString info;
|
ke::AString info;
|
||||||
ke::AutoPtr<ke::AString> display;
|
ke::AutoPtr<ke::AString> display;
|
||||||
unsigned int style;
|
unsigned int style;
|
||||||
@@ -142,7 +138,7 @@ public:
|
|||||||
virtual bool InsertItem(unsigned int position, const char *info, const ItemDrawInfo &draw);
|
virtual bool InsertItem(unsigned int position, const char *info, const ItemDrawInfo &draw);
|
||||||
virtual bool RemoveItem(unsigned int position);
|
virtual bool RemoveItem(unsigned int position);
|
||||||
virtual void RemoveAllItems();
|
virtual void RemoveAllItems();
|
||||||
virtual const char *GetItemInfo(unsigned int position, ItemDrawInfo *draw=NULL, int client=0);
|
virtual const char *GetItemInfo(unsigned int position, ItemDrawInfo *draw=NULL);
|
||||||
virtual unsigned int GetItemCount();
|
virtual unsigned int GetItemCount();
|
||||||
virtual bool SetPagination(unsigned int itemsPerPage);
|
virtual bool SetPagination(unsigned int itemsPerPage);
|
||||||
virtual unsigned int GetPagination();
|
virtual unsigned int GetPagination();
|
||||||
@@ -156,10 +152,6 @@ public:
|
|||||||
virtual unsigned int GetMenuOptionFlags();
|
virtual unsigned int GetMenuOptionFlags();
|
||||||
virtual void SetMenuOptionFlags(unsigned int flags);
|
virtual void SetMenuOptionFlags(unsigned int flags);
|
||||||
virtual IMenuHandler *GetHandler();
|
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();
|
unsigned int GetBaseMemUsage();
|
||||||
private:
|
private:
|
||||||
void InternalDelete();
|
void InternalDelete();
|
||||||
@@ -176,7 +168,6 @@ protected:
|
|||||||
Handle_t m_hHandle;
|
Handle_t m_hHandle;
|
||||||
IMenuHandler *m_pHandler;
|
IMenuHandler *m_pHandler;
|
||||||
unsigned int m_nFlags;
|
unsigned int m_nFlags;
|
||||||
ke::Vector<uint8_t> m_RandomMaps[SM_MAXPLAYERS+1];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //_INCLUDE_MENUSTYLE_BASE_H
|
#endif //_INCLUDE_MENUSTYLE_BASE_H
|
||||||
|
|||||||
+3
-4
@@ -514,16 +514,15 @@ void VoteMenuHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int ite
|
|||||||
/* Check by our item count, NOT the vote array size */
|
/* Check by our item count, NOT the vote array size */
|
||||||
if (item < m_Items)
|
if (item < m_Items)
|
||||||
{
|
{
|
||||||
unsigned int index = menu->GetRealItemIndex(client, item);
|
m_ClientVotes[client] = item;
|
||||||
m_ClientVotes[client] = index;
|
m_Votes[item]++;
|
||||||
m_Votes[index]++;
|
|
||||||
m_NumVotes++;
|
m_NumVotes++;
|
||||||
|
|
||||||
if (sm_vote_chat.GetBool() || sm_vote_console.GetBool() || sm_vote_client_console.GetBool())
|
if (sm_vote_chat.GetBool() || sm_vote_console.GetBool() || sm_vote_client_console.GetBool())
|
||||||
{
|
{
|
||||||
static char buffer[1024];
|
static char buffer[1024];
|
||||||
ItemDrawInfo dr;
|
ItemDrawInfo dr;
|
||||||
menu->GetItemInfo(item, &dr, client);
|
menu->GetItemInfo(item, &dr);
|
||||||
|
|
||||||
if (sm_vote_console.GetBool())
|
if (sm_vote_console.GetBool())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -816,14 +816,8 @@ static cell_t GetMenuItem(IPluginContext *pContext, const cell_t *params)
|
|||||||
|
|
||||||
ItemDrawInfo dr;
|
ItemDrawInfo dr;
|
||||||
const char *info;
|
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, client)) == NULL)
|
if ((info=menu->GetItemInfo(params[2], &dr)) == NULL)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -838,57 +832,6 @@ static cell_t GetMenuItem(IPluginContext *pContext, const cell_t *params)
|
|||||||
return 1;
|
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)
|
static cell_t SetMenuPagination(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
Handle_t hndl = (Handle_t)params[1];
|
Handle_t hndl = (Handle_t)params[1];
|
||||||
@@ -1702,8 +1645,6 @@ REGISTER_NATIVES(menuNatives)
|
|||||||
{"SetPanelKeys", SetPanelKeys},
|
{"SetPanelKeys", SetPanelKeys},
|
||||||
{"SetVoteResultCallback", SetVoteResultCallback},
|
{"SetVoteResultCallback", SetVoteResultCallback},
|
||||||
{"VoteMenu", VoteMenu},
|
{"VoteMenu", VoteMenu},
|
||||||
{"MenuShufflePerClient", MenuShufflePerClient},
|
|
||||||
{"MenuSetClientMapping", MenuSetClientMapping},
|
|
||||||
{"SetMenuNoVoteButton", SetMenuNoVoteButton},
|
{"SetMenuNoVoteButton", SetMenuNoVoteButton},
|
||||||
|
|
||||||
// Transitional syntax support.
|
// Transitional syntax support.
|
||||||
@@ -1732,8 +1673,6 @@ REGISTER_NATIVES(menuNatives)
|
|||||||
{"Menu.ToPanel", CreatePanelFromMenu},
|
{"Menu.ToPanel", CreatePanelFromMenu},
|
||||||
{"Menu.Cancel", CancelMenu},
|
{"Menu.Cancel", CancelMenu},
|
||||||
{"Menu.DisplayVote", VoteMenu},
|
{"Menu.DisplayVote", VoteMenu},
|
||||||
{"Menu.ShufflePerClient", MenuShufflePerClient},
|
|
||||||
{"Menu.SetClientMapping", MenuSetClientMapping},
|
|
||||||
{"Menu.Pagination.get", GetMenuPagination},
|
{"Menu.Pagination.get", GetMenuPagination},
|
||||||
{"Menu.Pagination.set", SetMenuPagination},
|
{"Menu.Pagination.set", SetMenuPagination},
|
||||||
{"Menu.OptionFlags.get", GetMenuOptionFlags},
|
{"Menu.OptionFlags.get", GetMenuOptionFlags},
|
||||||
|
|||||||
+28
-14
@@ -1458,24 +1458,23 @@ static cell_t IsClientInKickQueue(IPluginContext *pContext, const cell_t *params
|
|||||||
return pPlayer->IsInKickQueue() ? 1 : 0;
|
return pPlayer->IsInKickQueue() ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd_target_info_t g_ProcessTargetString_info;
|
||||||
static cell_t ProcessTargetString(IPluginContext *pContext, const cell_t *params)
|
static cell_t ProcessTargetString(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
cmd_target_info_t info;
|
pContext->LocalToString(params[1], (char **) &g_ProcessTargetString_info.pattern);
|
||||||
|
g_ProcessTargetString_info.admin = params[2];
|
||||||
pContext->LocalToString(params[1], (char **) &info.pattern);
|
pContext->LocalToPhysAddr(params[3], &g_ProcessTargetString_info.targets);
|
||||||
info.admin = params[2];
|
g_ProcessTargetString_info.max_targets = params[4];
|
||||||
pContext->LocalToPhysAddr(params[3], &info.targets);
|
g_ProcessTargetString_info.flags = params[5];
|
||||||
info.max_targets = params[4];
|
pContext->LocalToString(params[6], &g_ProcessTargetString_info.target_name);
|
||||||
info.flags = params[5];
|
g_ProcessTargetString_info.target_name_maxlength = params[7];
|
||||||
pContext->LocalToString(params[6], &info.target_name);
|
|
||||||
info.target_name_maxlength = params[7];
|
|
||||||
|
|
||||||
cell_t *tn_is_ml;
|
cell_t *tn_is_ml;
|
||||||
pContext->LocalToPhysAddr(params[8], &tn_is_ml);
|
pContext->LocalToPhysAddr(params[8], &tn_is_ml);
|
||||||
|
|
||||||
playerhelpers->ProcessCommandTarget(&info);
|
playerhelpers->ProcessCommandTarget(&g_ProcessTargetString_info);
|
||||||
|
|
||||||
if (info.target_name_style == COMMAND_TARGETNAME_ML)
|
if (g_ProcessTargetString_info.target_name_style == COMMAND_TARGETNAME_ML)
|
||||||
{
|
{
|
||||||
*tn_is_ml = 1;
|
*tn_is_ml = 1;
|
||||||
}
|
}
|
||||||
@@ -1484,16 +1483,30 @@ static cell_t ProcessTargetString(IPluginContext *pContext, const cell_t *params
|
|||||||
*tn_is_ml = 0;
|
*tn_is_ml = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.num_targets == 0)
|
if (g_ProcessTargetString_info.num_targets == 0)
|
||||||
{
|
{
|
||||||
return info.reason;
|
return g_ProcessTargetString_info.reason;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return info.num_targets;
|
return g_ProcessTargetString_info.num_targets;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cell_t GetLastProcessTargetString(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
cell_t *admin, *flags;
|
||||||
|
|
||||||
|
pContext->StringToLocalUTF8(params[1], params[2], g_ProcessTargetString_info.pattern, NULL);
|
||||||
|
pContext->LocalToPhysAddr(params[3], &admin);
|
||||||
|
pContext->LocalToPhysAddr(params[4], &flags);
|
||||||
|
|
||||||
|
*admin = g_ProcessTargetString_info.admin;
|
||||||
|
*flags = g_ProcessTargetString_info.flags;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static cell_t FormatActivitySource(IPluginContext *pContext, const cell_t *params)
|
static cell_t FormatActivitySource(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
@@ -1645,6 +1658,7 @@ REGISTER_NATIVES(playernatives)
|
|||||||
{ "NotifyPostAdminCheck", NotifyPostAdminCheck },
|
{ "NotifyPostAdminCheck", NotifyPostAdminCheck },
|
||||||
{ "IsClientInKickQueue", IsClientInKickQueue },
|
{ "IsClientInKickQueue", IsClientInKickQueue },
|
||||||
{ "ProcessTargetString", ProcessTargetString },
|
{ "ProcessTargetString", ProcessTargetString },
|
||||||
|
{ "GetLastProcessTargetString", GetLastProcessTargetString },
|
||||||
{ "FormatActivitySource", FormatActivitySource },
|
{ "FormatActivitySource", FormatActivitySource },
|
||||||
{ "GetClientSerial", sm_GetClientSerial },
|
{ "GetClientSerial", sm_GetClientSerial },
|
||||||
{ "GetClientFromSerial", sm_GetClientFromSerial },
|
{ "GetClientFromSerial", sm_GetClientFromSerial },
|
||||||
|
|||||||
@@ -789,6 +789,16 @@ static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cell_t sm_IsCommandCallback(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
const ICommandArgs *pCmd = g_HL2.PeekCommandStack();
|
||||||
|
|
||||||
|
if (!pCmd)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static cell_t sm_GetCmdArgs(IPluginContext *pContext, const cell_t *params)
|
static cell_t sm_GetCmdArgs(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
const ICommandArgs *pCmd = g_HL2.PeekCommandStack();
|
const ICommandArgs *pCmd = g_HL2.PeekCommandStack();
|
||||||
@@ -1467,6 +1477,7 @@ REGISTER_NATIVES(consoleNatives)
|
|||||||
{"GetConVarDefault", GetConVarDefault},
|
{"GetConVarDefault", GetConVarDefault},
|
||||||
{"RegServerCmd", sm_RegServerCmd},
|
{"RegServerCmd", sm_RegServerCmd},
|
||||||
{"RegConsoleCmd", sm_RegConsoleCmd},
|
{"RegConsoleCmd", sm_RegConsoleCmd},
|
||||||
|
{"IsCommandCallback", sm_IsCommandCallback},
|
||||||
{"GetCmdArgString", sm_GetCmdArgString},
|
{"GetCmdArgString", sm_GetCmdArgString},
|
||||||
{"GetCmdArgs", sm_GetCmdArgs},
|
{"GetCmdArgs", sm_GetCmdArgs},
|
||||||
{"GetCmdArg", sm_GetCmdArg},
|
{"GetCmdArg", sm_GetCmdArg},
|
||||||
|
|||||||
+2
-1
@@ -24,7 +24,8 @@ files = [
|
|||||||
'basecommands.sp',
|
'basecommands.sp',
|
||||||
'mapchooser.sp',
|
'mapchooser.sp',
|
||||||
'randomcycle.sp',
|
'randomcycle.sp',
|
||||||
'sql-admin-manager.sp'
|
'sql-admin-manager.sp',
|
||||||
|
'DynamicTargeting.sp'
|
||||||
]
|
]
|
||||||
|
|
||||||
spcomp_argv = [
|
spcomp_argv = [
|
||||||
|
|||||||
@@ -0,0 +1,266 @@
|
|||||||
|
#pragma semicolon 1
|
||||||
|
#define PLUGIN_VERSION "1.0"
|
||||||
|
|
||||||
|
#include <sourcemod>
|
||||||
|
#include <DynamicTargeting>
|
||||||
|
|
||||||
|
#pragma newdecls required
|
||||||
|
|
||||||
|
public Plugin myinfo =
|
||||||
|
{
|
||||||
|
name = "Dynamic Targeting",
|
||||||
|
author = "BotoX",
|
||||||
|
description = "",
|
||||||
|
version = PLUGIN_VERSION,
|
||||||
|
url = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
char g_PlayerNames[MAXPLAYERS + 1][MAX_NAME_LENGTH];
|
||||||
|
Handle g_PlayerData[MAXPLAYERS + 1];
|
||||||
|
|
||||||
|
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
|
||||||
|
{
|
||||||
|
CreateNative("AmbiguousMenu", Native_AmbiguousMenu);
|
||||||
|
RegPluginLibrary("DynamicTargeting");
|
||||||
|
|
||||||
|
return APLRes_Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnClientDisconnect(int client)
|
||||||
|
{
|
||||||
|
if(g_PlayerData[client] != INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
CloseHandle(g_PlayerData[client]);
|
||||||
|
g_PlayerData[client] = INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int CreateAmbiguousMenu(int client, const char[] sCommand, const char[] sArgString, const char[] sPattern, int FilterFlags)
|
||||||
|
{
|
||||||
|
Menu menu = new Menu(MenuHandler_AmbiguousMenu, MenuAction_Select|MenuAction_Cancel|MenuAction_End|MenuAction_DrawItem|MenuAction_DisplayItem);
|
||||||
|
menu.ExitButton = true;
|
||||||
|
|
||||||
|
char sTitle[32 + MAX_TARGET_LENGTH];
|
||||||
|
FormatEx(sTitle, sizeof(sTitle), "Target \"%s\" is ambiguous.", sPattern);
|
||||||
|
menu.SetTitle(sTitle);
|
||||||
|
|
||||||
|
int Players = 0;
|
||||||
|
int[] aClients = new int[MaxClients + 1];
|
||||||
|
|
||||||
|
for(int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if(!IsClientConnected(i) || i == client)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(FilterFlags & COMMAND_FILTER_NO_BOTS && IsFakeClient(i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(!(FilterFlags & COMMAND_FILTER_CONNECTED) && !IsClientInGame(i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(FilterFlags & COMMAND_FILTER_ALIVE && !IsPlayerAlive(i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(FilterFlags & COMMAND_FILTER_DEAD && IsPlayerAlive(i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// insert player names into g_PlayerNames array
|
||||||
|
GetClientName(i, g_PlayerNames[i], sizeof(g_PlayerNames[]));
|
||||||
|
|
||||||
|
if(StrContains(g_PlayerNames[i], sPattern, false) != -1)
|
||||||
|
aClients[Players++] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort aClients array by player name
|
||||||
|
SortCustom1D(aClients, Players, SortByPlayerName);
|
||||||
|
|
||||||
|
// insert players sorted
|
||||||
|
char sUserId[12];
|
||||||
|
char sDisp[MAX_NAME_LENGTH + 16];
|
||||||
|
for(int i = 0; i < Players; i++)
|
||||||
|
{
|
||||||
|
IntToString(GetClientUserId(aClients[i]), sUserId, sizeof(sUserId));
|
||||||
|
|
||||||
|
FormatEx(sDisp, sizeof(sDisp), "%s (%s)", g_PlayerNames[aClients[i]], sUserId);
|
||||||
|
menu.AddItem(sUserId, sDisp);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataPack pack = new DataPack();
|
||||||
|
pack.WriteString(sCommand);
|
||||||
|
pack.WriteString(sArgString);
|
||||||
|
pack.WriteString(sPattern);
|
||||||
|
pack.WriteCell(FilterFlags);
|
||||||
|
|
||||||
|
if(g_PlayerData[client] != INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
CloseHandle(g_PlayerData[client]);
|
||||||
|
g_PlayerData[client] = INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
CancelClientMenu(client);
|
||||||
|
|
||||||
|
g_PlayerData[client] = pack;
|
||||||
|
menu.Display(client, MENU_TIME_FOREVER);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int MenuHandler_AmbiguousMenu(Menu menu, MenuAction action, int param1, int param2)
|
||||||
|
{
|
||||||
|
switch(action)
|
||||||
|
{
|
||||||
|
case MenuAction_End:
|
||||||
|
{
|
||||||
|
CloseHandle(menu);
|
||||||
|
}
|
||||||
|
case MenuAction_Cancel:
|
||||||
|
{
|
||||||
|
if(g_PlayerData[param1] != INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
CloseHandle(g_PlayerData[param1]);
|
||||||
|
g_PlayerData[param1] = INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case MenuAction_Select:
|
||||||
|
{
|
||||||
|
int Style;
|
||||||
|
char sItem[32];
|
||||||
|
char sDisp[MAX_NAME_LENGTH + 16];
|
||||||
|
menu.GetItem(param2, sItem, sizeof(sItem), Style, sDisp, sizeof(sDisp));
|
||||||
|
|
||||||
|
int UserId = StringToInt(sItem);
|
||||||
|
int client = GetClientOfUserId(UserId);
|
||||||
|
if(!client)
|
||||||
|
{
|
||||||
|
PrintToChat(param1, "\x04[DynamicTargeting]\x01 Player no longer available.");
|
||||||
|
menu.DisplayAt(param1, GetMenuSelectionPosition(), MENU_TIME_FOREVER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataPack pack = view_as<DataPack>(g_PlayerData[param1]);
|
||||||
|
pack.Reset();
|
||||||
|
|
||||||
|
char sCommand[128];
|
||||||
|
pack.ReadString(sCommand, sizeof(sCommand));
|
||||||
|
|
||||||
|
char sArgString[256];
|
||||||
|
pack.ReadString(sArgString, sizeof(sArgString));
|
||||||
|
|
||||||
|
char sPattern[MAX_TARGET_LENGTH];
|
||||||
|
pack.ReadString(sPattern, sizeof(sPattern));
|
||||||
|
|
||||||
|
int Result = ReCallAmbiguous(param1, client, sCommand, sArgString, sPattern);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
case MenuAction_DrawItem:
|
||||||
|
{
|
||||||
|
int Style;
|
||||||
|
char sItem[32];
|
||||||
|
menu.GetItem(param2, sItem, sizeof(sItem), Style);
|
||||||
|
|
||||||
|
int UserId = StringToInt(sItem);
|
||||||
|
int client = GetClientOfUserId(UserId);
|
||||||
|
if(!client) // Player disconnected
|
||||||
|
return ITEMDRAW_DISABLED;
|
||||||
|
|
||||||
|
return Style;
|
||||||
|
}
|
||||||
|
case MenuAction_DisplayItem:
|
||||||
|
{
|
||||||
|
int Style;
|
||||||
|
char sItem[32];
|
||||||
|
char sDisp[MAX_NAME_LENGTH + 16];
|
||||||
|
menu.GetItem(param2, sItem, sizeof(sItem), Style, sDisp, sizeof(sDisp));
|
||||||
|
|
||||||
|
if(!sItem[0])
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
char sBuffer[MAX_NAME_LENGTH + 16];
|
||||||
|
int UserId = StringToInt(sItem);
|
||||||
|
int client = GetClientOfUserId(UserId);
|
||||||
|
if(!client) // Player disconnected
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
GetClientName(client, g_PlayerNames[client], sizeof(g_PlayerNames[]));
|
||||||
|
FormatEx(sBuffer, sizeof(sBuffer), "%s (%d)", g_PlayerNames[client], UserId);
|
||||||
|
|
||||||
|
if(!StrEqual(sDisp, sBuffer))
|
||||||
|
return RedrawMenuItem(sBuffer);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ReCallAmbiguous(int client, int newClient, const char[] sCommand, const char[] sArgString, const char[] sPattern)
|
||||||
|
{
|
||||||
|
char sTarget[16];
|
||||||
|
FormatEx(sTarget, sizeof(sTarget), "#%d", GetClientUserId(newClient));
|
||||||
|
|
||||||
|
char sNewArgString[256];
|
||||||
|
strcopy(sNewArgString, sizeof(sNewArgString), sArgString);
|
||||||
|
|
||||||
|
char sPart[256];
|
||||||
|
int CurrentIndex = 0;
|
||||||
|
int NextIndex = 0;
|
||||||
|
|
||||||
|
while(NextIndex != -1 && CurrentIndex < sizeof(sNewArgString))
|
||||||
|
{
|
||||||
|
NextIndex = BreakString(sNewArgString[CurrentIndex], sPart, sizeof(sPart));
|
||||||
|
|
||||||
|
if(StrEqual(sPart, sPattern))
|
||||||
|
{
|
||||||
|
ReplaceStringEx(sNewArgString[CurrentIndex], sizeof(sNewArgString) - CurrentIndex, sPart, sTarget);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentIndex += NextIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
FakeClientCommandEx(client, "%s %s", sCommand, sNewArgString);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Native_AmbiguousMenu(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
int client = GetNativeCell(1);
|
||||||
|
|
||||||
|
if(client > MaxClients || client <= 0)
|
||||||
|
{
|
||||||
|
ThrowNativeError(SP_ERROR_NATIVE, "Client is not valid.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!IsClientInGame(client))
|
||||||
|
{
|
||||||
|
ThrowNativeError(SP_ERROR_NATIVE, "Client is not in-game.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(IsFakeClient(client))
|
||||||
|
{
|
||||||
|
ThrowNativeError(SP_ERROR_NATIVE, "Client is fake-client.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char sCommand[128];
|
||||||
|
GetNativeString(2, sCommand, sizeof(sCommand));
|
||||||
|
|
||||||
|
char sArgString[256];
|
||||||
|
GetNativeString(3, sArgString, sizeof(sArgString));
|
||||||
|
|
||||||
|
char sPattern[MAX_TARGET_LENGTH];
|
||||||
|
GetNativeString(4, sPattern, sizeof(sPattern));
|
||||||
|
|
||||||
|
int FilterFlags = GetNativeCell(5);
|
||||||
|
|
||||||
|
return CreateAmbiguousMenu(client, sCommand, sArgString, sPattern, FilterFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SortByPlayerName(int elem1, int elem2, const int[] array, Handle hndl)
|
||||||
|
{
|
||||||
|
return strcmp(g_PlayerNames[elem1], g_PlayerNames[elem2], false);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#if defined _DynamicTargeting_Included
|
||||||
|
#endinput
|
||||||
|
#endif
|
||||||
|
#define _DynamicTargeting_Included
|
||||||
|
|
||||||
|
native int AmbiguousMenu(int client, char[] sCommand, char[] sArgString, char[] sPattern, int FilterFlags);
|
||||||
|
|
||||||
|
public SharedPlugin __pl_DynamicTargeting =
|
||||||
|
{
|
||||||
|
name = "DynamicTargeting",
|
||||||
|
file = "DynamicTargeting.smx",
|
||||||
|
#if defined REQUIRE_PLUGIN
|
||||||
|
required = 1,
|
||||||
|
#else
|
||||||
|
required = 0,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined REQUIRE_PLUGIN
|
||||||
|
public __pl_DynamicTargeting_SetNTVOptional()
|
||||||
|
{
|
||||||
|
MarkNativeAsOptional("AmbiguousMenu");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -84,6 +84,25 @@ native int ProcessTargetString(const char[] pattern,
|
|||||||
int tn_maxlength,
|
int tn_maxlength,
|
||||||
bool &tn_is_ml);
|
bool &tn_is_ml);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves arguments that were passed to the last ProcessTargetString call.
|
||||||
|
*
|
||||||
|
* @param pattern Buffer to store the pattern.
|
||||||
|
* @param p_maxlen Maximum length of the pattern buffer.
|
||||||
|
* @param admin OUTPUT: Admin performing the action, or 0 if the server.
|
||||||
|
* @param filter_flags OUTPUT: Filter flags.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void GetLastProcessTargetString(char[] pattern,
|
||||||
|
int p_maxlen,
|
||||||
|
int &admin,
|
||||||
|
int &filter_flags);
|
||||||
|
|
||||||
|
#undef REQUIRE_PLUGIN
|
||||||
|
#include <DynamicTargeting>
|
||||||
|
#define REQUIRE_PLUGIN
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replies to a client with a given message describing a targetting
|
* Replies to a client with a given message describing a targetting
|
||||||
* failure reason.
|
* failure reason.
|
||||||
@@ -93,7 +112,7 @@ native int ProcessTargetString(const char[] pattern,
|
|||||||
* @param client Client index, or 0 for server.
|
* @param client Client index, or 0 for server.
|
||||||
* @param reason COMMAND_TARGET reason.
|
* @param reason COMMAND_TARGET reason.
|
||||||
*/
|
*/
|
||||||
stock void ReplyToTargetError(int client, int reason)
|
stock void ReplyToTargetError(int client, int reason, bool dynamic=true)
|
||||||
{
|
{
|
||||||
switch (reason)
|
switch (reason)
|
||||||
{
|
{
|
||||||
@@ -128,6 +147,34 @@ stock void ReplyToTargetError(int client, int reason)
|
|||||||
case COMMAND_TARGET_AMBIGUOUS:
|
case COMMAND_TARGET_AMBIGUOUS:
|
||||||
{
|
{
|
||||||
ReplyToCommand(client, "[SM] %t", "More than one client matched");
|
ReplyToCommand(client, "[SM] %t", "More than one client matched");
|
||||||
|
|
||||||
|
if(dynamic &&
|
||||||
|
GetFeatureStatus(FeatureType_Native, "GetLastProcessTargetString") == FeatureStatus_Available &&
|
||||||
|
LibraryExists("DynamicTargeting"))
|
||||||
|
{
|
||||||
|
if(GetFeatureStatus(FeatureType_Native, "IsCommandCallback") == FeatureStatus_Available &&
|
||||||
|
!IsCommandCallback())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char sCommand[128];
|
||||||
|
GetCmdArg(0, sCommand, sizeof(sCommand));
|
||||||
|
|
||||||
|
char sArgString[256];
|
||||||
|
GetCmdArgString(sArgString, sizeof(sArgString));
|
||||||
|
|
||||||
|
char pattern[MAX_TARGET_LENGTH];
|
||||||
|
int admin;
|
||||||
|
int filter_flags;
|
||||||
|
|
||||||
|
GetLastProcessTargetString(pattern, sizeof(pattern), admin, filter_flags);
|
||||||
|
|
||||||
|
if(!admin || !IsClientInGame(admin) || IsFakeClient(admin))
|
||||||
|
return;
|
||||||
|
|
||||||
|
AmbiguousMenu(admin, sCommand, sArgString, pattern, filter_flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -402,7 +402,14 @@ native void RegAdminCmd(const char[] cmd,
|
|||||||
const char[] description="",
|
const char[] description="",
|
||||||
const char[] group="",
|
const char[] group="",
|
||||||
int flags=0);
|
int flags=0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether there is a command callback available.
|
||||||
|
*
|
||||||
|
* @return True if called from inside a command callback.
|
||||||
|
*/
|
||||||
|
native bool IsCommandCallback();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of arguments from the current console or server command.
|
* Returns the number of arguments from the current console or server command.
|
||||||
* @note Unlike the HL2 engine call, this does not include the command itself.
|
* @note Unlike the HL2 engine call, this does not include the command itself.
|
||||||
|
|||||||
@@ -311,6 +311,9 @@ public void __ext_core_SetNTVOptional()
|
|||||||
MarkNativeAsOptional("Protobuf.ReadRepeatedMessage");
|
MarkNativeAsOptional("Protobuf.ReadRepeatedMessage");
|
||||||
MarkNativeAsOptional("Protobuf.AddMessage");
|
MarkNativeAsOptional("Protobuf.AddMessage");
|
||||||
|
|
||||||
|
MarkNativeAsOptional("IsCommandCallback");
|
||||||
|
MarkNativeAsOptional("GetLastProcessTargetString");
|
||||||
|
|
||||||
VerifyCoreVersion();
|
VerifyCoreVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -307,23 +307,9 @@ methodmap Menu < Handle
|
|||||||
// @param style By-reference variable to store drawing flags.
|
// @param style By-reference variable to store drawing flags.
|
||||||
// @param dispBuf Display buffer.
|
// @param dispBuf Display buffer.
|
||||||
// @param dispBufLen Maximum length of the 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.
|
// @return True on success, false if position is invalid.
|
||||||
public native bool GetItem(int position, char[] infoBuf, int infoBufLen,
|
public native bool GetItem(int position, char[] infoBuf, int infoBufLen,
|
||||||
int &style=0, char[] dispBuf="", int dispBufLen=0, int client=0);
|
int &style=0, char[] dispBuf="", int dispBufLen=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.
|
// Sets the menu's default title/instruction message.
|
||||||
//
|
//
|
||||||
@@ -551,7 +537,6 @@ native void RemoveAllMenuItems(Handle menu);
|
|||||||
* @param style By-reference variable to store drawing flags.
|
* @param style By-reference variable to store drawing flags.
|
||||||
* @param dispBuf Display buffer.
|
* @param dispBuf Display buffer.
|
||||||
* @param dispBufLen Maximum length of the 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.
|
* @return True on success, false if position is invalid.
|
||||||
* @error Invalid Handle.
|
* @error Invalid Handle.
|
||||||
*/
|
*/
|
||||||
@@ -561,27 +546,7 @@ native bool GetMenuItem(Handle menu,
|
|||||||
int infoBufLen,
|
int infoBufLen,
|
||||||
int &style=0,
|
int &style=0,
|
||||||
char[] dispBuf="",
|
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.
|
* Returns the first item on the page of a currently selected menu.
|
||||||
|
|||||||
@@ -47,6 +47,92 @@ struct Plugin
|
|||||||
public const char[] url; /**< Plugin URL */
|
public const char[] url; /**< Plugin URL */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a library exists. This function should be considered
|
||||||
|
* expensive; it should only be called on plugin to determine availability
|
||||||
|
* of resources. Use OnLibraryAdded()/OnLibraryRemoved() to detect changes
|
||||||
|
* in optional resources.
|
||||||
|
*
|
||||||
|
* @param name Library name of a plugin or extension.
|
||||||
|
* @return True if exists, false otherwise.
|
||||||
|
*/
|
||||||
|
native bool LibraryExists(const char[] name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Feature types.
|
||||||
|
*/
|
||||||
|
enum FeatureType
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A native function call.
|
||||||
|
*/
|
||||||
|
FeatureType_Native,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A named capability. This is distinctly different from checking for a
|
||||||
|
* native, because the underlying functionality could be enabled on-demand
|
||||||
|
* to improve loading time. Thus a native may appear to exist, but it might
|
||||||
|
* be part of a set of features that are not compatible with the current game
|
||||||
|
* or version of SourceMod.
|
||||||
|
*/
|
||||||
|
FeatureType_Capability
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Feature statuses.
|
||||||
|
*/
|
||||||
|
enum FeatureStatus
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Feature is available for use.
|
||||||
|
*/
|
||||||
|
FeatureStatus_Available,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Feature is not available.
|
||||||
|
*/
|
||||||
|
FeatureStatus_Unavailable,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Feature is not known at all.
|
||||||
|
*/
|
||||||
|
FeatureStatus_Unknown
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether "GetFeatureStatus" will work. Using this native
|
||||||
|
* or this function will not cause SourceMod to fail loading on older versions,
|
||||||
|
* however, GetFeatureStatus will only work if this function returns true.
|
||||||
|
*
|
||||||
|
* @return True if GetFeatureStatus will work, false otherwise.
|
||||||
|
*/
|
||||||
|
stock bool CanTestFeatures()
|
||||||
|
{
|
||||||
|
return LibraryExists("__CanTestFeatures__");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a feature exists, and if so, whether it is usable.
|
||||||
|
*
|
||||||
|
* @param type Feature type.
|
||||||
|
* @param name Feature name.
|
||||||
|
* @return Feature status.
|
||||||
|
*/
|
||||||
|
native FeatureStatus GetFeatureStatus(FeatureType type, const char[] name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requires that a given feature is available. If it is not, SetFailState()
|
||||||
|
* is called with the given message.
|
||||||
|
*
|
||||||
|
* @param type Feature type.
|
||||||
|
* @param name Feature name.
|
||||||
|
* @param fmt Message format string, or empty to use default.
|
||||||
|
* @param ... Message format parameters, if any.
|
||||||
|
*/
|
||||||
|
native void RequireFeature(FeatureType type, const char[] name,
|
||||||
|
const char[] fmt="", any ...);
|
||||||
|
|
||||||
|
|
||||||
#include <core>
|
#include <core>
|
||||||
#include <float>
|
#include <float>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -448,17 +534,6 @@ native void AutoExecConfig(bool autoCreate=true, const char[] name="", const cha
|
|||||||
*/
|
*/
|
||||||
native void RegPluginLibrary(const char[] name);
|
native void RegPluginLibrary(const char[] name);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether a library exists. This function should be considered
|
|
||||||
* expensive; it should only be called on plugin to determine availability
|
|
||||||
* of resources. Use OnLibraryAdded()/OnLibraryRemoved() to detect changes
|
|
||||||
* in optional resources.
|
|
||||||
*
|
|
||||||
* @param name Library name of a plugin or extension.
|
|
||||||
* @return True if exists, false otherwise.
|
|
||||||
*/
|
|
||||||
native bool LibraryExists(const char[] name);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the status of an extension, by filename.
|
* Returns the status of an extension, by filename.
|
||||||
*
|
*
|
||||||
@@ -582,80 +657,6 @@ forward bool OnClientFloodCheck(int client);
|
|||||||
*/
|
*/
|
||||||
forward void OnClientFloodResult(int client, bool blocked);
|
forward void OnClientFloodResult(int client, bool blocked);
|
||||||
|
|
||||||
/**
|
|
||||||
* Feature types.
|
|
||||||
*/
|
|
||||||
enum FeatureType
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* A native function call.
|
|
||||||
*/
|
|
||||||
FeatureType_Native,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A named capability. This is distinctly different from checking for a
|
|
||||||
* native, because the underlying functionality could be enabled on-demand
|
|
||||||
* to improve loading time. Thus a native may appear to exist, but it might
|
|
||||||
* be part of a set of features that are not compatible with the current game
|
|
||||||
* or version of SourceMod.
|
|
||||||
*/
|
|
||||||
FeatureType_Capability
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Feature statuses.
|
|
||||||
*/
|
|
||||||
enum FeatureStatus
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Feature is available for use.
|
|
||||||
*/
|
|
||||||
FeatureStatus_Available,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Feature is not available.
|
|
||||||
*/
|
|
||||||
FeatureStatus_Unavailable,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Feature is not known at all.
|
|
||||||
*/
|
|
||||||
FeatureStatus_Unknown
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether "GetFeatureStatus" will work. Using this native
|
|
||||||
* or this function will not cause SourceMod to fail loading on older versions,
|
|
||||||
* however, GetFeatureStatus will only work if this function returns true.
|
|
||||||
*
|
|
||||||
* @return True if GetFeatureStatus will work, false otherwise.
|
|
||||||
*/
|
|
||||||
stock bool CanTestFeatures()
|
|
||||||
{
|
|
||||||
return LibraryExists("__CanTestFeatures__");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether a feature exists, and if so, whether it is usable.
|
|
||||||
*
|
|
||||||
* @param type Feature type.
|
|
||||||
* @param name Feature name.
|
|
||||||
* @return Feature status.
|
|
||||||
*/
|
|
||||||
native FeatureStatus GetFeatureStatus(FeatureType type, const char[] name);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Requires that a given feature is available. If it is not, SetFailState()
|
|
||||||
* is called with the given message.
|
|
||||||
*
|
|
||||||
* @param type Feature type.
|
|
||||||
* @param name Feature name.
|
|
||||||
* @param fmt Message format string, or empty to use default.
|
|
||||||
* @param ... Message format parameters, if any.
|
|
||||||
*/
|
|
||||||
native void RequireFeature(FeatureType type, const char[] name,
|
|
||||||
const char[] fmt="", any ...);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents how many bytes we can read from an address with one load
|
* Represents how many bytes we can read from an address with one load
|
||||||
*/
|
*/
|
||||||
|
|||||||
+2
-32
@@ -36,7 +36,7 @@
|
|||||||
#include <IHandleSys.h>
|
#include <IHandleSys.h>
|
||||||
|
|
||||||
#define SMINTERFACE_MENUMANAGER_NAME "IMenuManager"
|
#define SMINTERFACE_MENUMANAGER_NAME "IMenuManager"
|
||||||
#define SMINTERFACE_MENUMANAGER_VERSION 17
|
#define SMINTERFACE_MENUMANAGER_VERSION 16
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file IMenuManager.h
|
* @file IMenuManager.h
|
||||||
@@ -485,10 +485,9 @@ namespace SourceMod
|
|||||||
*
|
*
|
||||||
* @param position Position, starting from 0.
|
* @param position Position, starting from 0.
|
||||||
* @param draw Optional pointer to store a draw information.
|
* @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.
|
* @return Info string pointer, or NULL if position was invalid.
|
||||||
*/
|
*/
|
||||||
virtual const char *GetItemInfo(unsigned int position, ItemDrawInfo *draw, int client=0) =0;
|
virtual const char *GetItemInfo(unsigned int position, ItemDrawInfo *draw) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the number of items.
|
* @brief Returns the number of items.
|
||||||
@@ -637,35 +636,6 @@ namespace SourceMod
|
|||||||
* @return Approximate number of bytes being used.
|
* @return Approximate number of bytes being used.
|
||||||
*/
|
*/
|
||||||
virtual unsigned int GetApproxMemUsage() =0;
|
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -324,6 +324,7 @@ CopyFiles('plugins', 'addons/sourcemod/scripting',
|
|||||||
'rockthevote.sp',
|
'rockthevote.sp',
|
||||||
'sounds.sp',
|
'sounds.sp',
|
||||||
'sql-admin-manager.sp',
|
'sql-admin-manager.sp',
|
||||||
|
'DynamicTargeting.sp',
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
CopyFiles('plugins/include', 'addons/sourcemod/scripting/include',
|
CopyFiles('plugins/include', 'addons/sourcemod/scripting/include',
|
||||||
@@ -394,6 +395,7 @@ CopyFiles('plugins/include', 'addons/sourcemod/scripting/include',
|
|||||||
'usermessages.inc',
|
'usermessages.inc',
|
||||||
'vector.inc',
|
'vector.inc',
|
||||||
'version.inc',
|
'version.inc',
|
||||||
|
'DynamicTargeting.inc',
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
CopyFiles('translations', 'addons/sourcemod/translations',
|
CopyFiles('translations', 'addons/sourcemod/translations',
|
||||||
|
|||||||
Reference in New Issue
Block a user