
A modification for the Menu tutorial; This allows you to update a
single line of the menu and not worry about the others. This tut means you have
to remember to do slightly more with the selection function which is why I
havn't just intergrated it into the original.
I got this idea while considering ways to get angles from the
player for cameras and such. You can use it to create menus which change a
value, and do it repeatedly.
You MUST have done the menu tut before doing this. If you have
implemented any menus before doing this tut, you MUST have converted them to
the new format before running the mod. It should compile without a problem if
you don't but it will not work properly. I just don't want emails
saying 'this doesn't work' when the person sending it didn't read this
paragraph
The first change you need to do is to modify menuselect function
in menu.c. We no longer want the menu cleared when an option is selected. so
change the function to read as below
void menuselect(edict_t *ent){ent->client->menustorage.optionselected(ent,ent->client->menustorage.messages[ent->client->menustorage.currentline].option); // call the select function with the value that has been alocated for that selection.}
What these means is that the clean up functions are going to have
to be called in the option selected code for each menu. as we have a function
for closing menus, we may as well put the code in that so we only need a single
function call
find close menu in menu.c; Modify it to read
void closemenu(edict_t *ent){ ent->client->menustorage.optionselected=NULL;clearmenu(ent);ent->client->showscores = false;ent->client->menustorage.menu_active = false;ent->client->menustorage.displaymsg = false;ent->client->showinventory = false; }
now, when you are finished with the menu (the user selects a
finishing option [or any option depending on the menu]) call closemenu from the
selected-option function
Now down to the meat of the tutorial. Add the function below to
menu.c; position isn't important as long as you don't get stupid and stick it
within one of the other functions :)
void changeline(edict_t *ent,int linenum ,char *line,int option){if (linenum>(ent->client->menustorage.num_of_lines)) return; // no changing lines that don't exist :) sprintf(ent->client->menustorage.messages[linenum].msg,"%-21s",line); // copies the first 21 characters to the storage string. the 22nd character is for the delimiting '/0'ent->client->menustorage.messages[linenum].option=option; }
remember to call showmenu after redefining the menu to show the
results.
add the line below to menu.h it's just a prototype of the function
above, so you can use it anywhere
void changeline(edict_t *ent,int linenum ,char *line,int option);
And thats us done. Here is an example of what I am doing. replace
the functions in menu.c with the same names as these two to see how it works.
void testmenuhandler(edict_t *ent,int option){char *line;switch (option){case 1:ent->health+=5;break;case 2:ent->health-=5;break;case 3:closemenu(ent);return;break;default:gi.centerprintf(ent,"fuckup\n");}sprintf(line,"%d",ent->health); // just copies the players healthchangeline(ent,4,line,0);showmenu(ent); } void Menu_test(edict_t *ent){char *line; if (ent->client->showscores || ent->client->showinventory || ent->client->menustorage.menu_active) return; sprintf(line,"%d",ent->health); // just copies the players health clearmenu(ent);addlinetomenu(ent,"This is a test menu,",0);addlinetomenu(ent,"for setting your health",0); addlinetomenu(ent,"Health Up 5",1);addlinetomenu(ent,line,0);addlinetomenu(ent,"Health Down 5",2);addlinetomenu(ent,"Exit",3);setmenuhandler(ent,testmenuhandler);ent->client->menustorage.currentline=3;showmenu(ent); }
Try it :)