Creating a Generic Menu
This article has been marked by editors or authors as incomplete. Please see the Talk page for details. Discussion and collaboration can improve an article and lead to a better Wiki.
This guide will explain the different parts involved for making and interacting with a GenericMenu. It is highly recommended to learn how Oblivion's XML works and what the mostly-used traits and tricks are. Which can be done by looking at how some of the other, simple, menus work and look like.
Aim[edit | edit source]
The aim of our menu will be to display a single picture along with a small description. The image will be one of the birthsign pictures and the description explains some extra feature for that birthsign. It will be shown when the user clicks on the birthsign in the stats menu. To close the menu the user must click on the image.
Basics[edit | edit source]
There are a few things that are useful or important to keep in mind.
- The <class> trait must be either &GenericMenu; or the number 1011.
- The exact name of the menu does not matter and is only used within the menu itself.
- The <stackingtype> trait must be either &no_click_past; or the number 102.
- If an element has a <id> trait of above 0 the menu will be closed as soon as the user clicks on that element. Assuming it can be targeted.
- There can only be one generic menu at a time, each time one gets opened the existing menu is closed.
Apart from these things everything is possible. Well, within the limits of Oblivion's XML syntax ofcourse.
Layout[edit | edit source]
To begin our generic menu we start with the bare minimum and save it at Data\Menus\Generic\Demo.xml; with the following content:
<!-- demo.xml, only here for easy reference --> <menu name="DemoMenu"> <class> &GenericMenu; </class> <stackingtype> &no_click_past; </stackingtype> <locus> &true; </locus> <explorefade> 0.25 </explorefade> </menu>
But when it is used the result would be a menu that has no visible components nor any means of closing. So it needs some elements, starting with a standard background.
<menu name="DemoMenu"> .... <rect name="background"> <include src="generic_background.xml" /> <!-- one of many default prefabricated elements --> <visible> &true; </visible> <locus> &true; </locus> <target> &true; </target> <user0> 400 </user0> <!-- the width of the background, excluding the borders --> <user1> 320 </user1> <!-- the height of the background, excluding the borders --> <depth> 15 </depth> <x> <!-- this puts it nicely in the center of the screen --> <copy src="screen()" trait="width" /> <sub src="me()" trait="width" /> <div> 2 </div> </x> <y> <!-- this puts it nicely in the center of the screen --> <copy src="screen()" trait="height" /> <sub src="me()" trait="height" /> <div> 2 </div> </y> </rect>
And now we have a background, empty perhaps, but there nonetheless. Next step would be to add the image that is to be displayed and that serves as a means for closing the menu.
<menu name="DemoMenu"> .... <rect name="background"> .... <image name="icon"> <id> 1 </id> <!-- this is what will cause the menu to be closed when it is clicked --> <locus> &true; </locus> <target> &true; </target> <filename> Menus\Birthsign\Birthsign_the warrior.dds </filename> <zoom> 75 </zoom> <depth> 3 </depth> <width> <copy> 500 </copy> <mul src="me()" trait="zoom" /> <div> 100 </div> </width> <height> <copy> 400 </copy> <mul src="me()" trait="zoom" /> <div> 100 </div> </height> <x> 30 </x> <y> 25 </y> </image>
Script[edit | edit source]
In order to know when to display our menu we need to monitor the player's mouse input while the stats menu is open. For that we use a simple quest with the following script attached.
scn DemoMenuScript float fQuestDelayTime ref birthsign string_var text string_var icon string_var name begin MenuMode 1003 set fQuestDelayTime to 0.0001 if OnKeyDown 256 ;LeftMouseButton if GetActiveMenuComponentID == 14 ;the ID of stat_p1_birthsign_layout PrintC "Clicked on the birthsign in the statsmenu" set birthsign to GetPlayerBirthsign set name to GetName birthsign set icon to GetTexturePath birthsign set text to sv_Construct "Your custom description based on what exact birthsign was found." ShowGenericMenu "demo.xml" SetMenuStringValue "user0|%z", icon, 1011 SetMenuStringValue "user1|%z", text, 1011 SetMenuStringValue "user2|%z", name, 1011 endif endif end
Final[edit | edit source]
The final menu will contain a few more elements to explain what and how the user should do.
<!-- demo.xml --> <menu name="DemoMenu"> <class> &GenericMenu; </class> <stackingtype> &no_click_past; </stackingtype> <locus> &true; </locus> <explorefade> 0.25 </explorefade> <user0> Menus\Birthsign\Birthsign_the warrior.dds</user0> <user1> Description </user1> <user2> Name </user2> <user3> Click on the image to close this menu... </user3> <rect name="background"> <include src="generic_background.xml" /> <visible> &true; </visible> <depth> 15 </depth> <locus> &true; </locus> <target> &true; </target> <user0> <copy src="icon" trait="x" /> <add src="icon" trait="width" /> <add> 250 </add> </user0> <user1> <copy src="icon" trait="y" /> <add src="icon" trait="height" /> <add> 60 </add> </user1> <x> <copy src="screen()" trait="width" /> <sub src="me()" trait="width" /> <div> 2 </div> </x> <y> <copy src="screen()" trait="height" /> <sub src="me()" trait="height" /> <div> 2 </div> </y> <image name="icon"> <id> 1 </id> <locus> &true; </locus> <target> &true; </target> <filename> <copy src="DemoMenu" trait="user0" /> </filename> <zoom> 75 </zoom> <depth> 3 </depth> <width> <copy> 510 </copy> <mul src="me()" trait="zoom" /> <div> 100 </div> </width> <height> <copy> 400 </copy> <mul src="me()" trait="zoom" /> <div> 100 </div> </height> <x> 30 </x> <y> 25 </y> </image> <text name="hint"> <string> <copy src="DemoMenu" trait="user3" /> </string> <depth> 3 </depth> <font> 3 </font> <red> 0 </red> <green> 0 </green> <blue> 0 </blue> <alpha> 200 </alpha> <visible> &true; </visible> <locus> &true; </locus> <target> &true; </target> <wrapwidth> 500 </wrapwidth> <x> <copy src="icon" trait="x"/> <add> 10 </add> </x> <y> <copy src="icon" trait="y"/> <add src="icon" trait="height" /> <add> 5 </add> </y> </text> <text name="description"> <string> <copy src="DemoMenu" trait="user1"/> </string> <depth> 3 </depth> <font> 3 </font> <red> 0 </red> <green> 0 </green> <blue> 0 </blue> <alpha> 200 </alpha> <visible> &true; </visible> <locus> &true; </locus> <target> &true; </target> <clips> &true; </clips> <wrapwidth> 230 </wrapwidth> <x> <copy src="icon" trait="x"/> <add src="icon" trait="width"/> <add> 20 </add> </x> <y> <copy src="icon" trait="y"/> <add> 40 </add> </y> </text> <rect name="title"> <locus> &true; </locus> <target> &true; </target> <x> <copy src="description" trait="x" /> </x> <y> <copy src="icon" trait="y" /> </y> <width> 240 </width> <height> 25 </height> <depth> 3 </depth> <text name="title_text"> <locus> &true; </locus> <target> &true; </target> <depth> 3 </depth> <font> 3 </font> <alpha> 200 </alpha> <red> 0 </red> <green> 0 </green> <blue> 0 </blue> <string> <copy src="DemoMenu" trait="user2" /> </string> <wrapwidth> <copy src="parent()" trait="width"/> </wrapwidth> </text> <image name="line1"> <depth> 1 </depth> <x> -8 </x> <y> <copy src="title_text" trait="height" /> <add> 6 </add> </y> <filename> Stats\stat_border_horizontal_1.dds </filename> <zoom> 50 </zoom> <width> <copy src="description" trait="wrapwidth" /> <sub> 25 </sub> </width> <height> 3 </height> </image> </rect> </rect> </menu>