How To: ZSCRIPT MENUS?

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
User avatar
ZZYZX
 
 
Posts: 1384
Joined: Sun Oct 14, 2012 1:43 am
Location: Ukraine

Re: How To: ZSCRIPT MENUS?

Post by ZZYZX »

Actually I ditched that idea and switched to simply this:

Code: Select all

class Doom3MenuHandler : StaticEventHandler
{
	ui Doom3MenuData D3MenuData;
	override void UiTick()
	{
		if (!D3MenuData)
		{
			D3MenuData = new('Doom3MenuData');
			D3MenuData.Init();
		}
		
		Menu m = Menu.GetCurrentMenu();
		if (Doom3Menu(m))
		{
			Doom3Menu(m).p = D3MenuData;
		}
	}
}
So that you can turn the menu on/off, but the actual object that processes everything stays the same, which fixes animations and at the same time allows you to open the console during the title screen (godmode menu doesn't allow that since for whatever reason the console ignores ~ when menu is up).
The real way to fix this would anyway be an EventHandler+RenderOverlay, as event handler can't be closed but at the same time allows opening the console over it.

Either way this is the first actual use case for a StaticEventHandler that I found :)
Last edited by ZZYZX on Thu Mar 23, 2017 8:24 pm, edited 1 time in total.
User avatar
Nash
 
 
Posts: 17465
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia

Re: How To: ZSCRIPT MENUS?

Post by Nash »

That's definitely a better solution.
User avatar
Major Cooke
Posts: 8196
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: How To: ZSCRIPT MENUS?

Post by Major Cooke »

With this finally out of the way, I can begin documenting the menus somewhat.
User avatar
Nash
 
 
Posts: 17465
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia

Re: How To: ZSCRIPT MENUS?

Post by Nash »

So I find that generally, even to alter small stuff visually with the menu, it requires you to copy huge chunks of code, eg, the entire Drawer function.

Using Super doesn't always work because if you do that, then attempt to code your modifications after that, the drawing will be done twice.

I wish there was a way to specify WHOSE Drawer to call, eg if I'm inheriting from OptionMenu, and I copy/paste the entire Drawer method, I wouldn't want to use Super.Drawer, but directly Menu.Drawer (the function responsible for drawing the back button). There's no point calling Super.Drawer because I had to copy/paste the entire Drawer anyway.

Talking about things like this:

Code: Select all

Script error, ":zscript/menu/ladoptionmenuitem.zc" line 185:
Qualified member call to parent class OptionMenuItemControl::Init is not yet implemented
because of this I had to duplicate code twice for both my custom Control and MapControl widgets.
User avatar
Nash
 
 
Posts: 17465
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia

Re: How To: ZSCRIPT MENUS?

Post by Nash »

Sorry for the double post. Just posting my thoughts as I go along learning this new system.

I've been thinking that perhaps it's not always a good idea to write COMPLETELY from scratch menus. This commit had me thinking - if a mod author is not careful* (or if the mod author is absent), the mod will forever be stuck with obsolete/broken menu scripting.

I want to touch on what I said about being "careful". This is hard to define and sometimes it's not always fair to blame the mod author. The only way currently is to copy/paste the entire chunk of code. The same case was true back then before MENUDEF was scriptable - you had to copy/paste entire blocks otherwise risk things being missing from the menus. And because this is the only way to do things, it's very easy to create obsolete code. As soon as the mod author has to copy/paste entire sections, the possibility for obsolescence is magnified.

So IMO it's always best to parent to a gzdoom.pk3-defined menu, wherever possible.

I don't know if there is a better solution other than "mod author is responsible for keeping their menus in-line with gzdoom.pk3's menus"
User avatar
ZZYZX
 
 
Posts: 1384
Joined: Sun Oct 14, 2012 1:43 am
Location: Ukraine

Re: How To: ZSCRIPT MENUS?

Post by ZZYZX »

Parenting a GZDoom-based menu is no better than using MENUDEF+ACS+CVars.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49184
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: How To: ZSCRIPT MENUS?

Post by Graf Zahl »

@Nash:

It is sometimes inevitable that you have to copy code. The classes as written were designed to display a MENUDEF-designed menu. If you need something entirely different, the ListMenu and OptionMenu classes won't do much good to you and you will find yourself constantly fighting against their design.

Just have a look at the ConversationMenu for an example that wants to do something entirely different - and see that it does not inherit from one of those two menu classes. It also does not use the predefined menu widgets.

In the end it entirely depends on what you want to achieve. Keep in mind that this is no longer classic mod design but actual programming, so entirely different rules apply.
User avatar
AFADoomer
Posts: 1337
Joined: Tue Jul 15, 2003 4:18 pm

Re: How To: ZSCRIPT MENUS?

Post by AFADoomer »

But what if we literally only want to replace one menu widget? Say, making key binds use a different font, or changing the default cursor something other than a CONFONT glyph, or graphical slider bars... Right now that means copying large chunks of MENUDEFS, so any future changes to the core menus won't show up unless they are added to the mod manually.
User avatar
Major Cooke
Posts: 8196
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: How To: ZSCRIPT MENUS?

Post by Major Cooke »

Currently, there is no getting around that I don't think. Unlike menus, menu items are only initialized when the game is launched.

You may, however, be able to get away with modifying the font by using the menu's item initialization section where it goes through and has them all call OnMenuCreated(). Uncertain though... That might not work if the font is acquired from elsewhere.
User avatar
Jaxxoon R
Posts: 772
Joined: Sun May 04, 2014 7:22 pm

Re: How To: ZSCRIPT MENUS?

Post by Jaxxoon R »

So how will people use this then? The nice part about the actor side of Zscript is that there are different layers of complexity. Will non-programmers just have to stick to MENUDEFS or will there be a bab mode to the new menu system?
User avatar
Nash
 
 
Posts: 17465
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia

Re: How To: ZSCRIPT MENUS?

Post by Nash »

Well, in /theory/ someone COULD write some sort of visual editor like the C# form editor, where you can place widgets, and edit code for each widget... things like that. Some sort of WYSIWYG editor thingy. And then it finally generates the ZScript code for you... but I don't think anyone is willing to do that.

Also, some generic menu advice, especially if you plan to design and code completely custom menus. The same advice could also be applied to making game menus in general, not just ZScript.

It's very important that you have some design worked out before you even type your first line of code. Do a mockup in Photoshop or something, get a feel for where your widgets are going to end up on the screen. This gives you a rough idea of what you actually need to program.

You will see LITTERED everywhere in the engine's menu code, where it tries to subtract 160 here, nudge something 8 pixels there... you'll see expressions with multiple layers of parentheses and subtractions and divisions and multiplications everywhere, and you'll start to get a headache. This looks to me like there was no design involved and were just kludges to compensate for something that wasn't thought of carefully in the beginning, and/or it could also be a relic to work around the fact that Doom's original menus were in 320x200. You don't want your user scripts to look like this because it would be painful to maintain and almost impossible to learn from, for newcomers.

What would have been a good way is to define constants. This is where the mockup design part would be very helpful. Make meaningful constants, like MENU_RESOLUTION_WIDTH, MENU_RESOLUTION_HEIGHT, BUTTON_X_OFFSET, SLIDER_POSITION_Y, things like that. This also means that you won't lock your menu to a specific resolution. If one day you decide to replace your art assets (let's say you started menus with a 320x200 design and suddenly you want crisp 1080p menus with high res art assets), you just change these constants once and your entire menu will (hopefully!) update to reflect the new art assets.

On the other hand, if you're just interested in plugging in widgets into the existing ZDoom menu design, then, perhaps not much design process is required beforehand. You just have to learn the programming conventions that the widgets use and adapt to that.

But for building new menus, careful design and preparation upfront will go a LONG way towards clean and maintainable code.
User avatar
Major Cooke
Posts: 8196
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: How To: ZSCRIPT MENUS?

Post by Major Cooke »

Graf Zahl wrote:Keep in mind that this is no longer classic mod design but actual programming, so entirely different rules apply.
Ultimately, everyone needs to bear this in mind. Sure, someone could indeed come up with an API of sorts for it, but until that day comes, you're stuck with the hardest parts -- learning it all and doing it yourself.

Graf has, however, taken some lengths to make it a bit easier. However, there is much to learn.

Now that the events and handlers are documented I can begin working on the menu code documentation since people will want to know how to interact with players.
User avatar
Nash
 
 
Posts: 17465
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia

Re: How To: ZSCRIPT MENUS?

Post by Nash »

How do I limit the amount of items shown in an OptionMenu? Currently it will just keep filling up the screen until it hits the user's screen height. But I want to limit it to a set number, say, 10. The code is all over the place and not having Intellisense just makes this even harder to figure out...

EDIT: Talking about modifying the existing menu, of course. Not making new menus.
User avatar
Major Cooke
Posts: 8196
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: How To: ZSCRIPT MENUS?

Post by Major Cooke »

You could have the draw function just return the indent and draw nothing. Then it won't take up anything, last I checked.
User avatar
ZZYZX
 
 
Posts: 1384
Joined: Sun Oct 14, 2012 1:43 am
Location: Ukraine

Re: How To: ZSCRIPT MENUS?

Post by ZZYZX »

How do I prevent MenuEvent eating my precious key presses?
Currently I reliably receive MenuEvent with MKEY_Enter instead of the actual UiEvent.

Return to “Scripting”