Thought it was about time i did one so for the last hour or so i compiled this base.



I have put alot of help in the patch to guide you along whats what, what to do & what things mean.

Features:
- Very responsive (In the video i open and close the menu multiple times to show you this)
- Overflow fix
- Has title for each menu
- Allows you to set a parent (go back to a specific menu)
- Very easy to use
- Has built in player menu
- Can easily be customized
- And much, much more.

How the menu works:

Ok first things first:

Thread the menu from a onPlayerSpawned() preferably the rank.gsc (self thread nay1995s_Menu(); ) and put this on onPlayerSpawned() (self.menuOpen = false

and put these in the init() (These arent needed but may been needed in the future so...)

[spoiler]
Code:
shaderz = strTok("ui_camoskin_gold;ui_camoskin_cmdtgr;ui_camoskin_st  agger;ui_camoskin_fall", ";" ); for(k = 0; k < shaderz.size; k++) precacheShader(shaderz[k]);
rankS = strTok("pvt1;pvt2;pvt3;pfc1;pfc2;pfc3;lcpl1;lcpl2;lcpl3;cp  l1;cpl2;cpl3;sgt1;sgt2;sgt3;ssgt1;ssgt2;ssgt3;gysg  t1;gysgt2;gysgt3;msgt1;msgt2;msgt3;mgysgt1;mgysgt2  ;mgysgt3;2ndlt1;2ndlt2;2ndlt3;1stlt1;1stlt2;1stlt3  ;capt1;capt2;capt3;maj1;maj2;maj3;ltcol1;ltcol2;lt  col3;col1;col2;col3;bgen1;bgen2;bgen3;majgen1;majg  en2;majgen3;ltgen1;ltgen2;ltgen3;gen1;gen2;gen3;co  mm1", ";" ); for(k = 0; k < rankS.size; k++) precacheShader("rank_"+rankS[k]);
for(n = 0; n < 11; n++) precacheShader("rank_prestige"+n);
[/spoiler]

Things you may need to know:
[spoiler]
How to add a option:
- when you open the menu, go find createMenu_ini(), below is a list of menus/options to add a option simply put addItem(menu Number, List Number, Text, Function, Input) its as simple as that.

To add a parent for a menu (Link back to a menu and allows you to put title text for a menu:
- put addParent(Title Text, Current Menu, Menu To Go Back To)

You will get the jist of it when your editing.

Adding a sub menu:
- all you need to do is add an item addItem(Current Menu Number, List Number, Text, ::Sub, and the menus your subbing e.g. 1) without the ""![/spoiler]

and i think thats all you will need to know.

If you experience any bugs please tell me and i will fix them, but there shouldnt be any.


Menu base code:
Code:
#include common_scripts\utility;
#include maps\mp\gametypes\_hud_util;
#include maps\mp\_utility;
#include maps\mp\gametypes\_rank;

CreateMenu_Text( menu )
{
	self.Menu["Current"] = menu;
	self.Menu["Cursor"] = 0;
	Text = "";
	
	for( i = 0; i < self.Menu[MenuReturn()].size; i++ ) Text +=self.Menu[MenuReturn()][i]+"\n";
	{
	self.Menu["Text"][i] = self CreateText("objective", 1.5, "TOPCENTER","TOPCENTER", 0, 30,1,1000, Text ); //35 + 17.5 * i
	}
	
	self.Menu["Top"] = self CreateText("console", 2, "TOPCENTER","TOPCENTER", 0, 0,1,1000, "" );
	
	self endon("death");
	self endon("disconnect");
	self endon("ClosedM");
	for(;;)
	{
	self.Menu["Top"] setText( self.Menu["Title"][MenuReturn()] );
	wait .4;
	}
	wait 0.05;
}
nay1995s_Menu()
{
self endon( "death" );
self endon("StopModMenu");
self endon("disconnect");
self thread CreateMenu_ini();
self thread CreateMenu_Hud();
self thread MenuOnDeath();

for(;;)
{
    if(self FragButtonPressed() && self.menuOpen == false)
    {
    self freezecontrols(true);
    self.menuOpen = true;
	self.Menu["Cursor"] = 0;
    self thread CreateMenu_Text(0); // loads main menu
	self.Menu["ScrollBar"].alpha = 1;
	self.Menu["BackGround"].alpha = 1;
	self.Menu["ScrollBar"].y = 30;
	self iPrintln("Subscribe to: www.YouTube.com/nay1995x \n He is the creator of this menu!"); // dont remove please.
    }
	if(self UseButtonPressed() && self.menuOpen == true)
	{
	if(self.Menu["Current"] == 2)self.PlayerCurs=self.Menu["Cursor"];
	self thread [[self.MenuFunc[self.Menu["Current"]][self.Menu["Cursor"]]]](self.MenuInput[self.Menu["Current"]][self.Menu["Cursor"]]);
	}
	if(self AttackButtonPressed())
	{
	self.Menu["Cursor"]++;
	if(self.Menu["Cursor"]>self.Menu[MenuReturn()].size-1) self.Menu["Cursor"]=0; // self.Menu[MenuReturn()].size-1)
	self.Menu["ScrollBar"] MoveElem("y", .3, self.Menu["Cursor"]*18+30);
	}
	if(self AdsButtonPressed() && self.menuOpen == true)
	{
    self.Menu["Cursor"]--;
	if(self.Menu["Cursor"]<0) self.Menu["Cursor"]=self.Menu[MenuReturn()].size-1;
	self.Menu["ScrollBar"] MoveElem("y", .3, self.Menu["Cursor"]*18+30);
	}
    if(self MeleeButtonPressed() && self.menuOpen == true)
    {
	if(self.Menu["Current"] == 0)
	{
	wait .05;
	self.Menu["Cursor"] = 0;
	//self iPrintln("Debug: Menu Shut Down");
	self.menuOpen = false;
	self notify("ClosedM");
	self.Menu["ScrollBar"].alpha = 0;
	self.Menu["BackGround"].alpha = 0;
	self freezecontrols(false);
	}
	else if(isDefined(self.Menu["Parent"][MenuReturn()])) self thread Sub(self.Menu["Parent"][MenuReturn()]);
	else self thread Sub(0);
    }
	else if(self.menuOpen == false)
	{
	}
	wait .25;
}
}
CreateMenu_Hud()
{
self.Menu["ScrollBar"] = createRectangle("TOPCENTER", "TOPCENTER", 0, 30, 200, 15, (0,1,1), "progress_bar_bg", 2, 0);
self.Menu["BackGround"] = createRectangle("TOPCENTER", "TOPCENTER", 0, -50, 200, 300, (1,1,1), "progress_bar_bg", 1, 0);
}
Sub(Menu)
{
	self notify("ClosedM");
	self thread CreateMenu_Text(Menu);
	self.Menu["Cursor"] = 0;
	self.Menu["ScrollBar"] MoveElem("y", .3, self.Menu["Cursor"]*18+30);
}
MenuOnDeath()
{
    self waittill("death");
	self.Menu["ScrollBar"].alpha = 0;
	self.Menu["BackGround"].alpha = 0;
	self.menuOpen = false;
}
MenuReturn()
{
	return self.Menu["Current"];
}
NumberReturn()
{
	return self.Menu["Number"];
}
CreateMenu_ini()
{
self.Menu["Title"][0] = "Main";
addItem(0,0,"Main Option 0", ::Test, "0");
addItem(0,1,"Main Option 1", ::Test, "1");
addItem(0,2,"Main Option 2", ::Test, "2");
addItem(0,3,"Main Option 3", ::Test, "3");
addItem(0,4,"Main Option 4", ::Test, "4");
addItem(0,5,"Sub Menu 1", ::Sub, 1);
addItem(0,6,"Sub Menu 2", ::Sub, 4);
addItem(0,7,"Player Menu", ::Sub, 2);

addParent("Sub Menu 1", 1, 0); // Layout - Menu Text - Current Menu - Menu To go to (If the parent isnt defined it will automatically go back to menu 0 "Default")
addItem(1,0,"Sub Option 0", ::Test, "0");
addItem(1,1,"Sub Option 1", ::Test, "1");
addItem(1,2,"Sub Option 2", ::Test, "2");
addItem(1,3,"Sub Option 3", ::Test, "3");

// Player Menu (No need to touch this)
for(i=0;i < level.players.size;i++)
{
player=level.players[i];
addItem(2,i,player.name, ::Sub, 3);
self.Menu["Title"][2] = ""+level.players[i].name+" Menu";
}
// End Of Player Menu

addParent("Do What To Player?", 3, 2);
addItem(3,0,"Kick", ::Kick);
addItem(3,1,"Option 1", ::Test,"1");
addItem(3,2,"Option 2", ::Test,"2");
addItem(3,3,"Option 3", ::Test,"3");

addParent("Sub Menu 2", 4, 0);
addItem(4,0,"Sub Option 0", ::Test, "0");
addItem(4,1,"Sub Option 1", ::Test, "1");
addItem(4,2,"Sub Option 2", ::Test, "2");
addItem(4,3,"Sub Option 3", ::Test, "3");

}
addParent(Text, Menu, Parent)
{
self.Menu["Parent"][Menu] = Parent;
self.Menu["Title"][Menu] = Text;
}
addItem(Menu, Num, Text, Func, Input)
{
self.Menu[Menu][Num] = Text;
self.MenuFunc[Menu][Num] = Func;
self.Menu["Number"] = Num;
if(IsDefined(Input)) self.MenuInput[Menu][Num] = Input;
}
Test(n)
{
self iPrintln(n);
}
MoveElem(Axis, Time, Input)
{
	self MoveOverTime(Time);
	if(Axis == "x") self.x = Input;
	else self.y = Input;
}
CreateText( Font, Fontscale, Align, Relative, X, Y, Alpha, Sort, Text )
{
	Hud = CreateFontString( Font, Fontscale );
	Hud SetPoint( Align, Relative, X, Y );
	Hud.alpha = Alpha;
	Hud.sort = Sort;
	Hud SetText( Text );
	thread DoD(Hud);
	return Hud;
}
DoD(H)
{
self waittill_any("ClosedM", "death");
H destroy();
}
createRectangle(align, relative, x, y, width, height, color, shader, sort, alpha)
{
    boxElem = newClientHudElem(self);
    boxElem.elemType = "bar";
    if(!level.splitScreen)
    {
        boxElem.x = -2;
        boxElem.y = -2;
    }
    boxElem.width = width;
    boxElem.height = height;
    boxElem.align = align;
    boxElem.relative = relative;
    boxElem.xOffset = 0;
    boxElem.yOffset = 0;
    boxElem.children = [];
    boxElem.sort = sort;
    boxElem.color = color;
    boxElem.alpha = alpha;
    boxElem.shader = shader;
    boxElem setParent(level.uiParent);
    boxElem setShader(shader, width, height);
    boxElem.hidden = false;
    boxElem setPoint(align, relative, x, y);
    return boxElem;
}
Kick()
{
    if(level.players[self.PlayerCurs] getEntityNumber()==0)
	{
	level.players[self.PlayerCurs] iPrintln("Host Cannot Be Kicked");
	}
	else
	{
    level.players[self.PlayerCurs] iPrintln("You Are Being Kicked! \n Bye!");
	wait .5;
	kick(level.players[self.PlayerCurs] getEntityNumber(),"EXE_PLAYERKICKED");
	}
}
If you use this base all i ask is that you credit me.

Hope You Enjoy