Closed bearU369 closed 3 months ago
Out of curiosity, if you use the existing getFrameChildUnderMouse(...) != null
instead of mouseOverUI
, does it fail for some reason? I guess that existing system only reported a value for things that were meant to be clickable?
If that's the case, what's the rationale for not making mouseOverUI
or whatever we want to call it a recursive thing that is likewise processed by child frames? It still might not fix the time indicator since that one is a wonky 3D model sprite frame, but it would probably fix the escape menu if I'm recalling things correctly.
Out of curiosity, if you use the existing
getFrameChildUnderMouse(...) != null
instead ofmouseOverUI
, does it fail for some reason? I guess that existing system only reported a value for things that were meant to be clickable?
Yeah, getFrameChildUnderMouse
only picks up the clickable frames as it failed to find the decorated frames since they only recursively jumps to other frames. Initially tried to implement them being picked up as well but something like button highlights starting to break in the main menu.
If that's the case, what's the rationale for not making
mouseOverUI
or whatever we want to call it a recursive thing that is likewise processed by child frames?
If I understand, the parent frame is already stretched out by its child frames so its not really worth continuing to process recursively. I noticed from consoleUI
since it has child frames from upper buttons to inventory frame, encompassing most of the screen as I tried to debug why it failed to pick up units outside of the UI beforehand. I'm still trying to make the function able to recursively check other frames so I would only pick up the rootFrame
but I'm having difficulty trying to make the function differentiate between a decorated frame and a blank, parent frame.
I wonder if there's a way to intersect the model with a mouse for to able to be picked up instead of the renderBounds
if that's the case. It seems to work for picking up units in war3MapViewer
but I'm not sure how it can handle picking up 3D UI model.
After some tweaks and bugfixing, it's stable enough for gameplay thus ready to be merged. Although this have not yet resolve the issue with SpriteFrame
I did some brainstorming looking at this PR tonight. Some ideas:
Set<String>
instead of an String[]
when name matching, to possibly improve performance, or if not performance at least the conceptual time complexity (I've been told sometimes in very small cases, when N=4 it's better to do something O(N) than O(1)). If doing a Set, the literal values could still be declared fairly easy with something short like final Set<String> foobar = new HashSet<>(Arrays.asList("asdf", "qwer"));
So I kind of went in a circle -- thinking that maybe I would recommend this be some enum with minimal code aiming for high performance -- back to thinking maybe you had it right and we simply didn't understand the rule for which frames block out the mouse and which don't. And that led me to some intuitions about what I think would help:
"EscMenuMainPanel"
(not a Warsmash file, provided by game assets in UI\FrameDef\UI\EscMenuMainPanel.fdf
) is using SetAllPoints
meaning that this frame expands to fill its container. Warsmash is abusing the fact that its windowing system is hacked together and allows the parent of a frame not to necessarily entirely contain its child frame, and thus wraps "EscMenuMainPanel"
inside of an invented container "SmashEscMenu"
(software defined) that has zero size but is used for some hacked offset from the top of the screen to try to make the sizing and position on this stuff look loosely like WC3. So although "EscMenuMainPanel"
on Warsmash is expanding to fill the size of its container, its container "SmashEscMenu"
is probably a zero-side degenerate single point of a frame if I was reading the code correctly. By contrast, with how this probably should have been, I'm theorizing that "EscMenuMainPanel"
on Warcraft 3 probably is expanding to fill the entire actual screen, thus preventing use of the mouse for 3D game world interactions while browsing the menus. Doing that would honestly make a lot of sense. Similarly, I never found the files that defined "TimeOfDayIndicator"
SpriteFrame on Warcraft 3 and so in Warsmash I am using an invented one <WarsmashModEngine>/resources/UI/FrameDef/SmashUI/TimeOfDayIndicator.fdf
and this is probably also aberrantly spawning with width=0 and height=0 because there is not currently a constraint that the 3D sprite of a sprite frame must fall within the bounding of its corresponding UIFrame.
In the long term, this makes me think it might be better to:
"SmashEscMenu"
"EscMenuMainPanel"
as a child of rootFrame (the GameUI) so that it fills the whole screen<WarsmashModEngine>/resources/UI/FrameDef/SmashUI/TimeOfDayIndicator.fdf
so that it also prevents clicking the 3D game world, because using the same UIFrame click interaction is probably easier and more performant than doing a 3D mesh intersect (although 3D mesh intersect would be physically possible if desired, like you mentioned, but I just think it's probably currently totally unnecessary)But despite all of these ideas described above, I definitely appreciate that the current UI system is a mess because I tried to make my own thing in order to be able to stylize the FDF loading in the way that I wanted, and it's very hacked together in places currently. So I'll be tempted to merge this anyway after getting your thoughts.
A tagging system for UIFrames would've made a lot sense for frame with varieties like the SmashHpBar
variables though I'm not sure if the system will be only used in MeleeUI
or could be used elsewhere too, like an rework with the UIFrame's getFrameChildUnderMouse
that would recognize backdrop frames too instead of having a two, identical methods aiming to do the same?
Though for now, getHoveredFrame
isn't playing nice with finding the current UIFrame accurately, as SmashConsoleInventoryCover
has renderbound bigger than what it's texture rendered and UnitPortrait
somehow when hovering the mouse near the bottom of the screen. Fortunately its main purpose for now is to blocking the mouse from interacting with the ingame while in the UI so it's not a big deal as for now but could be an issue if we intend to merge both functions.
I believe that during multiplayer, the menu wouldn't block out the screen as everything still functions ingame (unless one of the player asked for a pause) compared in the single-player, the menu will block the whole screen as everything is on pause. So I think Wc3's UI system works pretty robust with its mouse interaction than having a different states for UI interactions as the EscMainMenuPanel
covering the whole screen is probably a cheesy way of preventing any ingame interaction with the mouse during a pause on singleplayer.
This is a PR attempting to stop units behind UI from being highlighted/selected. It's partially able to stop highlighting units behind frames in
consoleUI
buttimeIndicator
frame and some dialogs (Game Menu, Victory, Exit, etc.) were able to highlight units. It is wonky right now so I would be aiming to do an elegant implementation of this.