Skip to content

Instantly share code, notes, and snippets.

@Y-Less
Created July 31, 2015 16:48
Show Gist options
  • Save Y-Less/e9db39940a00eee63c01 to your computer and use it in GitHub Desktop.
Save Y-Less/e9db39940a00eee63c01 to your computer and use it in GitHub Desktop.
SA:MP Menu DSL core
// This bit isn't important.
enum MENU_ITEM_DATA
{
bool:MENU_ITEM_TITLE,
bool:MENU_ITEM_DISABLED,
MENU_ITEM_DATA_TEXT[32],
MENU_ITEM_CHILD,
MENU_ITEM_PARENT,
MENU_ITEM_SIBLING
// All your other menu item data.
}
enum MENU_DATA
{
MENU_CHILD,
MENU_LAST_BUILD
}
static stock
gMenuItemData[MAX_MENU_ITEMS][MENU_ITEM_DATA],
gMenuData[MAX_MENUS][MENU_DATA],
gFreeMenuData,
gFreeMenuItem;
stock MENU:NewMenu()
{
if (gFreeMenuData == MAX_MENUS)
return MENU:-1;
gMenuData[gFreeMenuData][MENU_CHILD] = -1;
gMenuData[gFreeMenuData][MENU_LAST_BUILD] = -1;
return MENU:(gFreeMenuData++);
}
stock MENU:operator%(MENU:menu, MenuItem:item)
{
if (menu == MENU:-1 || item == MenuItem:-1)
return menu;
// Make a new submenu.
if (gMenuData[_:menu][MENU_CHILD] == -1)
{
// First entry.
gMenuData[_:menu][MENU_CHILD] = _:item;
gMenuItemData[_:item][MENU_ITEM_PARENT] = -1;
}
else
{
// Add extra checking here that the current item doesn't have children.
// New child of the current item.
new
parent = gMenuData[_:menu][MENU_LAST_BUILD];
gMenuItemData[parent][MENU_ITEM_CHILD] = _:item;
gMenuItemData[_:item][MENU_ITEM_PARENT] = parent;
}
// Propagate.
gMenuData[_:menu][MENU_LAST_BUILD] = _:item;
return menu;
}
stock MENU:operator*(MENU:menu, MenuItem:item)
{
if (menu == MENU:-1 || item == MenuItem:-1)
return menu;
// Add to the current submenu.
if (gMenuData[_:menu][MENU_CHILD] != -1)
{
new
sibling = gMenuData[_:menu][MENU_LAST_BUILD],
parent = gMenuItemData[sibling][MENU_ITEM_PARENT];
gMenuItemData[sibling][MENU_ITEM_SIBLING] = _:item;
gMenuItemData[_:item][MENU_ITEM_PARENT] = parent;
gMenuData[_:menu][MENU_LAST_BUILD] = _:item;
}
// Propagate.
return menu;
}
stock MENU:operator/(MENU:menu, MenuItem:item)
{
if (menu == MENU:-1 || item == MenuItem:-1)
return menu;
// End the current submenu.
if (gMenuData[_:menu][MENU_CHILD] != -1)
{
new
sibling = gMenuData[_:menu][MENU_LAST_BUILD],
parent = gMenuItemData[sibling][MENU_ITEM_PARENT];
gMenuItemData[sibling][MENU_ITEM_SIBLING] = _:item;
gMenuItemData[_:item][MENU_ITEM_PARENT] = parent;
gMenuData[_:menu][MENU_LAST_BUILD] = parent;
}
// Propagate.
return menu;
}
stock MenuItem:MEntry(txt[])
{
return NewMenuItem(txt, false, false);
}
stock MenuItem:MTitle(txt[])
{
return NewMenuItem(txt, true, false);
}
stock MenuItem:MDisabled(txt[])
{
return NewMenuItem(txt, false, true);
}
static stock MenuItem:NewMenuItem(const txt[], bool:title, bool:disabled)
{
if (gFreeMenuItem == MAX_MENUS)
return MenuItem:-1;
gMenuItemData[gFreeMenuItem][MENU_ITEM_TITLE] = title;
gMenuItemData[gFreeMenuItem][MENU_ITEM_DISABLED] = disabled;
strcpy(gMenuItemData[gFreeMenuItem][MENU_ITEM_DATA_TEXT[32], txt, 32);
gMenuItemData[gFreeMenuItem][MENU_ITEM_CHILD] = -1;
gMenuItemData[gFreeMenuItem][MENU_ITEM_PARENT] = -1;
gMenuItemData[gFreeMenuItem][MENU_ITEM_SIBLING] = -1;
return MenuItem:(gFreeMenuItem++);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment