What is a Multiboard-based Menu System?
A multiboard-based menu system, is a multiboard made to function like a menu
I heard you just updated it not to need Custom Script!
Correct, i made GUI functions for this!
Read at the bottom for more info!
But i thought multiboards showed for all players or not at all?
this is a common perception but by the use of a certain if/then statement it is possible to over come that, the if/then statement is

JASS:
if GetLocalPlayer() == (your player comparison)
show the multiboard
endif
Wait a second, this is going to cause desyncs, isnt it?
no, this has been tested time and time again, no desyncs dont worry about it.
When can i make my own menu?
Infact let's get started making a menu that fits your needs right now!
1) first you are going to want to have several variables so that you can create/use the menu
Boolean Array inmultiboard
integer TempPNumber //temporary player number
integer Array CurrentRow
Multiboard Array Multiboards
2) you will need an initialization trigger so that when you would like to show a player their menu, the menu is ready to be used.
Trigger:
Menu Init

Events


Time - Elapsed game time is 0.75 seconds //when doesnt really matter, within the first second is preferable.

Conditions

Actions


For each (Integer A) from 1 to 4, do (Actions)



Loop - Actions




If (All Conditions are True) then do (Then Actions) else do (Else Actions)





If - Conditions






((Player((Integer A))) slot status) Equal to Is playing






((Player((Integer A))) controller) Equal to User





Then - Actions






Multiboard - Create a multiboard with 2 columns and 30 rows, titled The Help Menu






Set Multiboards[(Integer A)] = (Last created multiboard)






Multiboard - Set the display style for (Last created multiboard) item in column 0, row 0 to Show text and Hide icons






Multiboard - Set the text for (Last created multiboard) item in column 1, row 4 to What is this?







you usually want to start at about row 4 so that it isnt right at the top of the screen, and you usually want to start on an item that explains how to manipulate the menu.






Multiboard - Set the text for (Last created multiboard) item in column 1, row 5 to <Option 2>






Multiboard - Set the width for (Last created multiboard) item in column 1, row 0 to 30.00% of the total screen width






Multiboard - Set the width for (Last created multiboard) item in column 2, row 0 to 70.00% of the total screen width// set this to take up the screen






Multiboard - Hide(Last created multiboard) //you only want them to see when they need it.





Else - Actions


For each (Integer A) from 1 to 4, do (Actions)



Loop - Actions




Set inmultiboard[(Integer A)] = False




Set TempPNumber = (Integer A)


For each (Integer A) from 1 to 4, do (Actions)



Loop - Actions




If (All Conditions are True) then do (Then Actions) else do (Else Actions)





If - Conditions






((Player((Integer A))) slot status) Equal to Is playing






((Player((Integer A))) controller) Equal to User





Then - Actions






-------- A weird little thing that will only show a multiboard if the local player is appropriate. --------






-------- The concept is that if the current "local player" is being considered, we can show them a multiboard that corresponds to the player number in the loop. --------






Custom script: if( GetLocalPlayer() == ConvertedPlayer(bj_forLoopAIndex) ) then






Multiboard - Hide Multiboards[(Integer A)] // make sure they are hidden






Custom script: endif





Else - Actions
3) Now that you have an initialization trigger, you need a trigger to show the multiboard once they want/need it, this way they will be able to use your menu that you create
4) ok, now you will be able to show your multiboards, but now you ask "but how do i set descriptions? how do i move around?? Now we come to that, you need a general response trigger i title them Alter onEvent because they merely alter the menu, This trigger alters the individual menus so that the appropriate player can tell what they are doing
Trigger:
Alter onEvent

Events

Conditions

Actions


Multiboard - Set the text for Multiboards[TempPNumber] item in column 2, row 0 to <Empty String>


If (All Conditions are True) then do (Then Actions) else do (Else Actions)



If - Conditions




CurrentRow[TempPNumber] Equal to 4



Then - Actions




Multiboard - Set the text for Multiboards[TempPNumber] item in column 2, row 5 to This is an interactive menu.




Multiboard - Set the text for Multiboards[TempPNumber] item in column 2, row 6 to To use it, press the up/down arrow keys for movement,




Multiboard - Set the text for Multiboards[TempPNumber] item in column 2, row 7 to use the right arrow to exit the help menu



//I seperated the parts of the description out so that i alwas used one line of text (max) per row, giving it a more/less uniform look.


Else - Actions

If (All Conditions are True) then do (Then Actions) else do (Else Actions)


If - Conditions



CurrentRow[TempPNumber] Equal to 5


Then - Actions



Multiboard - Set the text for Multiboards[TempPNumber] item in column 2, row 5 to <description 2a> Multiboard - Set the text for Multiboards[TempPNumber] item in column 2, row 6 to future, <description 2b>



Multiboard - Set the text for Multiboards[TempPNumber] item in column 2, row 7 to <description 2c>


Else - Actions

Multiboard - Set the color for Multiboards[TempPNumber] item in column 1, row 0 to (0.00%, 100.00%, 0.00%) with 0.00% transparency// make all items look the same

Multiboard - Set the color for Multiboards[TempPNumber] item in column 2, row 0 to (50.00%, 50.00%, 75.00%) with 0.00% transparency //this gives a bluish/purplish color to the item description text for nice effect.

Multiboard - Set the color for Multiboards[TempPNumber] item in column 1, row CurrentRow[TempPNumber] to (0.00%, 0.00%, 100.00%) with 0.00% transparency //highlight the current item so they know where they are
5) ok now you have the general response trigger, now you need to know they want to look around so we create response triggers for those, in this way we can use the trigger we just made so that they can actually have a use for your menu, that you are making.
the up arrow trigger so that when they press the up arrow the select the item above that which they have selected.
The down arrow trigger so when they press the down arrow they select the item beneath that which they are selected on
the right arrow trigger so that they can select an item, or exit, or just a general action function
a left arrow one could be made, but i didnt need one so i didnt make one since i would have no explanation for it.
if you would like to have more than one menu then for each menu, repeat steps 1 - 5 just add prefixes/suffixes like Help_ or _Help onto the variables after copy and pasting so that you can have more than one menu.
Ok so you now know the basics, but you want to know more.
This type of menu system is best if it is response based not time elapse based. I have noticed rare instances where the system will corrupt and needs to be remade (ingame) (by corrupt i mean for instance showing the wrong menu, this is discussed further just keep reading.) so i usually have a debug function on the init trigger that registers player 1 saying like -menuerror and it remakes the menus from scratch. the times this almost always will happen is if you display them ALL at the same time. some people are rather dense and
will refuse to read help/descriptions (one of the most irksome things) so i usually have it be like Bob's Help Menu at the title so if nothing else a more experinced person may ask "hey bob does it say "Bob's Help Menu" at the top? to make sure that it isnt an error just refusal to read the description, if it is an error that is where the debug comes into play because it would remake all the menus so that the error would go away. errors are not a normal event as Genesis of Empires II will tell you since 90% of the controls are menus not dislike this system. i ,however, could not access the code because it is protected so i asked the makers on their forums how they did it. they were kind and taught me how to do by sending me vague example maps.
KEY FACTS:
1) do not display all menus at the same time, more likely to cause an error
2) remember to add a debug function and tell in a help section somewhere that Player 1 can type that to fix the errors, however unlikely.
3) Player 1's menu is the very least likely to fail, so another reason that fact 2 should be usable by player 1
I have attached a sample map that portrays this tutorial, errors and comments are very welcome.
please download my example map so that you will further understand this concept, thank you.
UPDATE: GUI functions for this!
Download the zip and extract it into your war3 directory take the UI folder out and place it in the directory!
Note: You MUST copy the following code into your header (thingy that says name of your map at top of trigger section)

JASS:
function MultiboardDisplayforPlayer takes player p, multiboard board ,boolean bool returns nothing
if( GetLocalPlayer() == p ) then
call MultiboardDisplay( board, bool )
endif
endfunction
function MultiboardMinimizeforPlayer takes player p, multiboard board, boolean bool returns nothing
if( GetLocalPlayer() == p ) then
call MultiboardMinimize( board, bool )
endif
endfunction
function CreateMultiboardforPlayer takes integer cols, integer rows, string title, player p returns multiboard
if( GetLocalPlayer() == p ) then
set bj_lastCreatedMultiboard = CreateMultiboard()
call MultiboardSetRowCount(bj_lastCreatedMultiboard, rows)
call MultiboardSetColumnCount(bj_lastCreatedMultiboard, cols)
call MultiboardSetTitleText(bj_lastCreatedMultiboard, title)
call MultiboardDisplayforPlayer(p, bj_lastCreatedMultiboard, true)
endif
return bj_lastCreatedMultiboard
endfunction
Then you won't have to touch jass again for that map (if you dont want to)!!
This GUI patch gives you 3 new functions under the multiboard section
Multiboard - Create for Player
Multiboard - Minimize/Maximize for Player
Multiboard - Show/Hide for Player