Expandable Menu System
Created By: Worm
eMail: chrisfreak84@hotmail.com
Difficulty Scale: Hard

This tutorial will show you a simple menu system that you can customize for your own needs.

Step 1.

Open up Defs.qc and scroll down to the very bottom and add:

.void()	mnuchoice1;
.void()	mnuchoice2;
.void()	mnuchoice3;
.void()	mnuchoice4;
.void()	mnuchoice5;
.void()	mnuchoice6;
.void()	mnuchoice7;
.void()	mnuchoice8;
.void()	mnuchoice9;
.float	inmenu;	
The inmenu variable tells you whether a player is in a menu (i.e., if other impulses are disabled)

Step 2.

Put this in a new qc file that is before any in which you will call menus

void() ClearMenus =
	self.inmenu = 0;
	self.mnuchoice1 = SUB_Null;
	self.mnuchoice2 = SUB_Null;
	self.mnuchoice3 = SUB_Null;
	self.mnuchoice4 = SUB_Null;
	self.mnuchoice5 = SUB_Null;
	self.mnuchoice6 = SUB_Null;
	self.mnuchoice7 = SUB_Null;
	self.mnuchoice8 = SUB_Null;
	self.mnuchoice9 = SUB_Null;

Put this in the same qc file as above.

void() CallMenu =
	if (self.impulse == 1)
		self.mnuchoice1 ();
	else if (self.impulse == 2)
		self.mnuchoice2 ();
	else if (self.impulse == 3)
		self.mnuchoice3 ();
	else if (self.impulse == 4)
		self.mnuchoice4 ();
	else if (self.impulse == 5)
		self.mnuchoice5 ();
	else if (self.impulse == 6)
		self.mnuchoice6 ();
	else if (self.impulse == 7)
		self.mnuchoice7 ();
	else if (self.impulse == 8)
		self.mnuchoice8 ();
	else if (self.impulse == 9)
		self.mnuchoice9 ();

Step 3.

Add the following two lines at the top of your CheckImpulses function. You may need to edit them to make them work with your mod

	if ((self.impulse >= 1 && self.impulse <= 9) && (self.inmenu == 1))
		CallMenu ();

Using the menus

Say you wanted to create a menu where each choice does exactly the same thing. Also say that you made a trigger that will set up this menu in whoever touched it. The code that follows is what the trigger's touch function would look like:

void() trigger_touch =
	if (other.classname != "player")
		return;	//Not a player, so no menu
	if (other.health <= 0)
		return;	//Make sure they are still alive...
	other.mnuchoice1 = say_hi;	// These next ten lines set up the menu
	other.mnuchoice2 = say_hi;
	other.mnuchoice3 = say_hi;
	other.mnuchoice4 = say_hi;
	other.mnuchoice5 = say_hi;
	other.mnuchoice6 = say_hi;
	other.mnuchoice7 = say_hi;
	other.mnuchoice8 = say_hi;
	other.mnuchoice9 = say_hi;
	other.inmenu = 1;
	centerprint (other, "1-9: Do exactly the same thing\n");	// Tell the player what the menu is

Now when the player touches the trigger the menu will pop up, centerprinted. He then has to press one of the number keys (1-9) and the corresponding option (function) will 'open up'. Of course, all these ones do the same thing, so it doesnt matter which key he presses. Ok, you have the menu, but if you try to compile this, it will go blah blah... say_hi not found or something The code below is what you would put in that function. Obviously this would go before the trigger_touch code ;)

void() say_hi =
	sprint (self, "Hi\n");		// Say hi to your self... how sad
	ClearMenus ();			// Clear the menus so they can be used again without conflicts and stuff

That about sums it up. you can use these menus anywhere, and they can also be practically infinitely expanded. To do this, you need to set option 9 on the first menu to target a function that loads up a new menu (after clearing the old one). You then set the option 1 of the second one to target the first menu. This way you can scroll between multiple menus, all acting as one. Pretty neat, eh? :)