- inserted a nasty backwards compatibility shim specifically for war3ft 3.0-rc. this may be extended globally if i can find a way to generalize it without breaking menu_create().

- updated comment about player_menu_info() as it was wrong.
This commit is contained in:
David Anderson 2007-09-02 18:35:53 +00:00
parent 58c7239b48
commit a749aad1b4
11 changed files with 112 additions and 158 deletions

View File

@ -543,7 +543,9 @@ void CForwardMngr::unregisterSPForward(int id)
{
//make sure the id is valid
if (!isIdValid(id) || m_SPForwards.at(id >> 1)->isFree)
{
return;
}
CSPForward *fwd = m_SPForwards.at(id >> 1);
@ -556,6 +558,38 @@ void CForwardMngr::unregisterSPForward(int id)
}
}
int CForwardMngr::duplicateSPForward(int id)
{
if (!isIdValid(id) || m_SPForwards.at(id >> 1)->isFree)
{
return -1;
}
CSPForward *fwd = m_SPForwards.at(id >> 1);
return registerSPForward(fwd->m_Func, fwd->m_Amx, fwd->m_NumParams, fwd->m_ParamTypes);
}
int CForwardMngr::isSameSPForward(int id1, int id2)
{
if (!isIdValid(id1) || !isIdValid(id2))
{
return false;
}
CSPForward *fwd1 = m_SPForwards.at(id1 >> 1);
CSPForward *fwd2 = m_SPForwards.at(id2 >> 1);
if (fwd1->isFree || fwd2->isFree)
{
return false;
}
return ((fwd1->m_Amx == fwd2->m_Amx)
&& (fwd1->m_Func == fwd2->m_Func)
&& (fwd1->m_NumParams == fwd2->m_NumParams));
}
int registerForwardC(const char *funcName, ForwardExecType et, cell *list, size_t num, int fwd_type)
{
ForwardParam params[FORWARD_MAX_PARAMS];

View File

@ -217,6 +217,8 @@ public:
// Unregister single plugin forward
void unregisterSPForward(int id);
int duplicateSPForward(int id);
int isSameSPForward(int id1, int id2);
// execute forward
cell executeForwards(int id, cell *params);

View File

@ -35,14 +35,15 @@
// *****************************************************
// class MenuMngr
// *****************************************************
MenuMngr::MenuCommand::MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f, int n)
MenuMngr::MenuCommand::MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f, bool new_menu)
{
plugin = a;
keys = k;
menuid = mi;
function = f;
next = 0;
newmenu = n;
is_new_menu = new_menu;
function = f;
}
MenuMngr::~MenuMngr()
@ -62,112 +63,47 @@ int MenuMngr::findMenuId(const char* name, AMX* amx)
return 0;
}
void MenuMngr::removeMenuId(int id)
{
MenuIdEle *n = headid;
MenuIdEle *l = NULL;
while (n)
{
if (n->id == id)
{
if (l)
l->next = n->next;
else
headid = n->next;
delete n;
break;
}
l = n;
n = n->next;
}
MenuCommand *c = headcmd;
MenuCommand *lc = NULL;
MenuCommand *tmp;
while (c)
{
if (c->menuid == id)
{
if (m_watch_iter.a == c)
{
++m_watch_iter;
}
if (lc)
lc->next = c->next;
else
headcmd = c->next;
tmp = c->next;
delete c;
c = tmp;
} else {
lc = c;
c = c->next;
}
}
}
void MenuMngr::removeMenuCmds(int newMenu)
{
MenuCommand *c = headcmd;
MenuCommand *lc = NULL;
MenuCommand *tmp;
while (c)
{
if (c->newmenu == newMenu)
{
if (m_watch_iter.a == c)
{
++m_watch_iter;
}
if (lc)
lc->next = c->next;
else
headcmd = c->next;
tmp = c->next;
delete c;
c = tmp;
} else {
lc = c;
c = c->next;
}
}
}
int MenuMngr::registerMenuId(const char* n, AMX* a)
{
int id = findMenuId(n, a);
if (id)
{
return id;
}
headid = new MenuIdEle(n, a, headid);
if (!headid)
return 0; // :TODO: Better error report
return headid->id;
}
void MenuMngr::registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f, int n)
void MenuMngr::registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f, bool from_new_menu)
{
MenuCommand **temp = &headcmd;
if (from_new_menu)
{
MenuCommand *ptr;
while (*temp)
{
ptr = *temp;
if (n > -1
if (ptr->is_new_menu
&& ptr->plugin == a
&& ptr->menuid == mi
&& ptr->keys == k)
&& ptr->menuid == mi)
{
if (strcmp(g_forwards.getFuncName(ptr->function), g_forwards.getFuncName(f)) == 0)
if (g_forwards.isSameSPForward(ptr->function, f))
{
return;
}
}
temp = &(*temp)->next;
}
*temp = new MenuCommand(a, mi, k, f, n);
} else {
while (*temp)
{
temp = &(*temp)->next;
}
}
*temp = new MenuCommand(a, mi, k, f, from_new_menu);
}
void MenuMngr::clear()

View File

@ -66,14 +66,17 @@ private:
int menuid;
int keys;
int function;
int is_new_menu;
MenuCommand* next;
MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f, int n=-1);
MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f, bool new_menu=false);
public:
inline int getFunction() { return function; }
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
inline bool matchCommand(int m, int k) { return ((m == menuid) && (keys & k)); }
int newmenu;
inline bool matchCommand(int m, int k)
{
return ((m == menuid) && (keys & k));
}
} *headcmd;
public:
@ -85,9 +88,7 @@ public:
int findMenuId(const char* name, AMX* a = 0);
int registerMenuId(const char* n, AMX* a);
void removeMenuId(int id);
void removeMenuCmds(int newMenu);
void registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f, int n=-1);
void registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f, bool from_new_menu=false);
void clear();
class iterator
@ -112,4 +113,6 @@ private:
MenuMngr::iterator m_watch_iter;
};
extern MenuMngr g_menucmds;
#endif //MENUS_H

View File

@ -31,6 +31,7 @@
#include <time.h>
#include "amxmodx.h"
#include "CMenu.h"
#include "natives.h"
#include "debugger.h"
#include "binlog.h"

View File

@ -65,7 +65,6 @@
#include "CLogEvent.h"
#include "CForward.h"
#include "CCmd.h"
#include "CMenu.h"
#include "CEvent.h"
#include "CLang.h"
#include "fakemeta.h"
@ -183,7 +182,6 @@ extern CList<CPlayer*> g_auth;
extern EventsMngr g_events;
extern Grenades g_grenades;
extern LogEventsMngr g_logevents;
extern MenuMngr g_menucmds;
extern CLangMngr g_langMngr;
extern String g_log_dir;
extern String g_mod_name;

View File

@ -30,6 +30,7 @@
*/
#include "amxmodx.h"
#include "CMenu.h"
int gmsgAmmoPickup;
int gmsgAmmoX;

View File

@ -39,6 +39,7 @@
#include "amxmodx.h"
#include "fakemeta.h"
#include "CMenu.h"
#include "newmenus.h"
#include "natives.h"
#include "binlog.h"
@ -965,6 +966,7 @@ void C_ClientCommand(edict_t *pEntity)
pPlayer->menu = 0;
/* First, do new menus */
int func_was_executed = -1;
if (pPlayer->newmenu != -1)
{
int menu = pPlayer->newmenu;
@ -988,6 +990,11 @@ void C_ClientCommand(edict_t *pEntity)
RETURN_META(MRES_SUPERCEDE);
}
}
/**
* No matter what we marked it as executed, since the callback styles are
* entirely different. After all, this is a backwards compat shim.
*/
func_was_executed = pMenu->func;
}
}
@ -997,7 +1004,11 @@ void C_ClientCommand(edict_t *pEntity)
while (a)
{
g_menucmds.SetWatchIter(a);
if ((*a).matchCommand(menuid, bit_key) && (*a).getPlugin()->isExecutable((*a).getFunction()))
if ((*a).matchCommand(menuid, bit_key)
&& (*a).getPlugin()->isExecutable((*a).getFunction())
&& (func_was_executed == -1
|| !g_forwards.isSameSPForward(func_was_executed, (*a).getFunction()))
)
{
ret = executeForwards((*a).getFunction(), static_cast<cell>(pPlayer->index),
static_cast<cell>(pressed_key), 0);

View File

@ -29,6 +29,7 @@
*/
#include "amxmodx.h"
#include "CMenu.h"
#include "newmenus.h"
CVector<Menu *> g_NewMenus;
@ -48,28 +49,6 @@ void ClearMenus()
}
}
void RemoveMenuIdIfOkay(Menu *pMenu, int menuid)
{
/* :TODO: Move this to some sort of referencing counting thingy */
bool removeMenuId = true;
for (size_t i = 0; i < g_NewMenus.size(); i++)
{
if (!g_NewMenus[i] || g_NewMenus[i]->isDestroying)
{
continue;
}
if (g_NewMenus[i]->menuId == menuid)
{
removeMenuId = false;
break;
}
}
if (removeMenuId)
{
g_menucmds.removeMenuId(menuid);
}
}
void validate_menu_text(char *str)
{
if (!g_coloredmenus)
@ -102,23 +81,31 @@ void validate_menu_text(char *str)
}
}
Menu::Menu(const char *title, int mid, int tid)
Menu::Menu(const char *title, AMX *amx, int fid) : m_Title(title), m_ItemColor("\\r"),
m_NeverExit(false), m_AutoColors(g_coloredmenus), thisId(0), func(fid),
isDestroying(false), items_per_page(7)
{
m_Title.assign(title);
menuId = mid;
thisId = tid;
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
menuId = g_menucmds.registerMenuId(title, amx);
if (strcmp(pPlugin->getName(), "war3ft.amxx") == 0)
{
const char *version = pPlugin->getVersion();
if (strncmp(pPlugin->getVersion(), "3.0 RC", 6) == 0
&& atoi(&version[6]) <= 8)
{
g_menucmds.registerMenuCmd(
g_plugins.findPluginFast(amx),
menuId,
-1,
g_forwards.duplicateSPForward(fid),
true);
}
}
m_OptNames[abs(MENU_BACK)].assign("Back");
m_OptNames[abs(MENU_MORE)].assign("More");
m_OptNames[abs(MENU_EXIT)].assign("Exit");
m_ItemColor.assign("\\r");
m_NeverExit = false;
m_AutoColors = g_coloredmenus;
items_per_page = 7;
func = 0;
isDestroying = false;
}
Menu::~Menu()
@ -605,11 +592,7 @@ static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
return 0;
}
int id = g_menucmds.registerMenuId(title, amx);
Menu *pMenu = new Menu(title, id, 0);
pMenu->func = func;
Menu *pMenu = new Menu(title, amx, func);
if (g_MenuFreeStack.empty())
{
@ -727,7 +710,7 @@ static cell AMX_NATIVE_CALL menu_display(AMX *amx, cell *params)
/* Infinite loop counter */
if (++loops >= 10)
{
LogError(amx, AMX_ERR_NATIVE, "Recursion bug detected in menu handler");
LogError(amx, AMX_ERR_NATIVE, "Plugin called menu_display when item=MENU_EXIT");
return 0;
}
}
@ -902,22 +885,7 @@ static cell AMX_NATIVE_CALL menu_setprop(AMX *amx, cell *params)
case MPROP_TITLE:
{
char *str = get_amxstring(amx, params[3], 0, len);
int old = pMenu->menuId;
RemoveMenuIdIfOkay(pMenu, old);
pMenu->m_Title.assign(str);
pMenu->menuId = g_menucmds.registerMenuId(str, amx);
CPlayer *pl;
/**
* NOTE - this is actually bogus
* the client's screen won't actually match the cmd here
* I think, this scenario needs to be tested.
*/
for (int i=1; i<=gpGlobals->maxClients; i++)
{
pl = GET_PLAYER_POINTER_I(i);
if (pl->menu == old)
pl->menu = pMenu->menuId;
}
break;
}
case MPROP_EXITALL:
@ -1005,8 +973,6 @@ static cell AMX_NATIVE_CALL menu_destroy(AMX *amx, cell *params)
pMenu->isDestroying = true;
RemoveMenuIdIfOkay(pMenu, pMenu->menuId);
CPlayer *player;
for (int i=1; i<=gpGlobals->maxClients; i++)
{

View File

@ -75,7 +75,7 @@ typedef unsigned int page_t;
class Menu
{
public:
Menu(const char *title, int menuId, int thisId);
Menu(const char *title, AMX *amx, int fid);
~Menu();
menuitem *GetMenuItem(item_t item);

View File

@ -192,7 +192,10 @@ native menu_destroy(menu);
/**
* Returns information about a menu (if any) the client is currently viewing.
*
* Either menu or newmenu can return a valid menu, but never both.
* If newmenu is valid, then the menu will refer to the menuid associated with
* the title. If newmenu is not valid, and the menu is valid, then the player
* is viewing a menu displayed with show_menu().
*
* Both may be invalid if the player is not viewing a menu.
*
* @param id Client index.
@ -201,7 +204,6 @@ native menu_destroy(menu);
* @param newmenu Variable to store new menu id. If none, then -1 will be
* stored.
* @param menupage Variable to store current page of the new menu, if any.
*
* @return 1 if the player is viewing a menu, 0 otherwise.
* @error Invalid client.
*/