- Joined
- Feb 7, 2020
- Messages
- 398
ded gaem
Can't figure out a more elegant solution. Guess it's FDFs or bust.
Can't figure out a more elegant solution. Guess it's FDFs or bust.
I was experimenting with some methods to make a fix snippet for the ENTER/EXIT infinite loop bug introduced by Deforged 1.33.
The demo map is attached.
With some caffeine and nerd rage, I ended up with something that semi-works (this is a functional test, so local player isn't implemented).
It registers leave functions independent of the frame event API and instead runs them when a 'listener frame' receives the next ENTER event (since only one frame can be in context at a time). Not too complicated of an idea. This is accomplished alongside some flag management madness (toggling an "outside of button" boolean and then setting the most recent mouse enter framehandle).
However, it's not perfect. The primary issue is that if you mouse over a button very quickly before the next 'enter' event can register then only the 'enter' function runs - this can be solved by widening the size of the catch frame or by using a single fullscreen listener, but that would then limit how buttons can be used around the screen.
I tried a few twisted contortions, this has been the closest solution so far.
Is this over-engineered? Has anyone had success with their own experimental fixes?
The demo map is attached.
With some caffeine and nerd rage, I ended up with something that semi-works (this is a functional test, so local player isn't implemented).
It registers leave functions independent of the frame event API and instead runs them when a 'listener frame' receives the next ENTER event (since only one frame can be in context at a time). Not too complicated of an idea. This is accomplished alongside some flag management madness (toggling an "outside of button" boolean and then setting the most recent mouse enter framehandle).
However, it's not perfect. The primary issue is that if you mouse over a button very quickly before the next 'enter' event can register then only the 'enter' function runs - this can be solved by widening the size of the catch frame or by using a single fullscreen listener, but that would then limit how buttons can be used around the screen.
I tried a few twisted contortions, this has been the closest solution so far.
Is this over-engineered? Has anyone had success with their own experimental fixes?
Lua:
--- An experimental fix for the WC3 Reforged v1.33 mouse enter/exit infinite loop bug.
--- By Planetary @ hiveworkshop.com
----------------------------------
-- REQUIRED GLOBALS AND FUNCS --
----------------------------------
LAST_TRIGGER_FRAMEHANDLE = {
[FRAMEEVENT_MOUSE_ENTER] = 0,
[FRAMEEVENT_MOUSE_LEAVE] = 0,
-- UP/DOWN events no longer work as of 1.33, use CONTROL_CLICK instead
}
TRIGGER_MOUSE_EXIT_FUNCTION = {}
TRIGGER_MOUSE_EXIT_IS_OUTSIDE = false
TRIGGER_CATCH_EXIT_FH = 0
function TriggerMoveExitCatchFrame(to_target_fh)
BlzFrameClearAllPoints(TRIGGER_CATCH_EXIT_FH)
BlzFrameSetPoint(TRIGGER_CATCH_EXIT_FH, FRAMEPOINT_CENTER, to_target_fh, FRAMEPOINT_CENTER, 0, 0)
BlzFrameSetSize(TRIGGER_CATCH_EXIT_FH, BlzFrameGetWidth(to_target_fh)*1.3, BlzFrameGetHeight(to_target_fh)*1.6)
end
function TriggerShouldRunMouseEvent(fh, frameevent)
if frameevent == FRAMEEVENT_MOUSE_ENTER then
if LAST_TRIGGER_FRAMEHANDLE[FRAMEEVENT_MOUSE_ENTER] and LAST_TRIGGER_FRAMEHANDLE[FRAMEEVENT_MOUSE_ENTER] == fh then
return false
else
LAST_TRIGGER_FRAMEHANDLE[FRAMEEVENT_MOUSE_ENTER] = fh
TRIGGER_MOUSE_EXIT_IS_OUTSIDE = false
TriggerMoveExitCatchFrame(fh)
return true
end
end
end
-- helper function, not needed in normal use:
function TriggerAddMouseAction(t, fh, eventtype, func)
TriggerAddAction(t, function()
if BlzGetTriggerFrame() == fh and TriggerShouldRunMouseEvent(fh, eventtype) then
func()
end
end)
end
-- new API function:
function TriggerAddMouseEnterAction(t, fh, func)
TriggerAddMouseAction(t, fh, FRAMEEVENT_MOUSE_ENTER, func)
end
-- new API function:
function TriggerAddMouseLeaveAction(t, fh, func)
-- support multiple actions:
if not TRIGGER_MOUSE_EXIT_FUNCTION[fh] then
TRIGGER_MOUSE_EXIT_FUNCTION[fh] = {}
end
table.insert(TRIGGER_MOUSE_EXIT_FUNCTION[fh], function()
func()
end)
end
----------------------------------
-- DEMO --
----------------------------------
do
local real = MarkGameStarted
function MarkGameStarted()
real()
local enter_t, exit_t = CreateTrigger(), CreateTrigger()
local catch_exit_fh = BlzCreateFrameByType("BUTTON", "MyCatchExitButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)
local button = BlzCreateFrameByType("GLUETEXTBUTTON", "MyScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScriptDialogButton", 0)
local button2 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyScriptDialogButton2", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScriptDialogButton", 0)
BlzFrameSetTexture(catch_exit_fh, "UI\\Widgets\\EscMenu\\Human\\blank-background.blp", 0, true)
BlzFrameSetAlpha(catch_exit_fh, 0)
BlzTriggerRegisterFrameEvent(enter_t, catch_exit_fh, FRAMEEVENT_MOUSE_ENTER)
BlzTriggerRegisterFrameEvent(enter_t, button, FRAMEEVENT_MOUSE_ENTER)
BlzTriggerRegisterFrameEvent(exit_t, button, FRAMEEVENT_MOUSE_LEAVE)
BlzTriggerRegisterFrameEvent(enter_t, button2, FRAMEEVENT_MOUSE_ENTER)
BlzTriggerRegisterFrameEvent(exit_t, button2, FRAMEEVENT_MOUSE_LEAVE)
BlzFrameSetSize(catch_exit_fh, 0.25, 0.3)
BlzFrameSetAbsPoint(catch_exit_fh, FRAMEPOINT_CENTER, 0.4, 0.35)
BlzFrameSetAbsPoint(button, FRAMEPOINT_CENTER, 0.4, 0.4)
BlzFrameSetAbsPoint(button2, FRAMEPOINT_CENTER, 0.4, 0.3)
-- set the Button's text
BlzFrameSetText(button, "Example Hover Button 1")
BlzFrameSetText(button2, "Example Hover Button 2")
TriggerAddAction(enter_t, function()
if BlzGetTriggerFrame() == TRIGGER_CATCH_EXIT_FH and LAST_TRIGGER_FRAMEHANDLE[FRAMEEVENT_MOUSE_ENTER] then
if not TRIGGER_MOUSE_EXIT_IS_OUTSIDE and TRIGGER_MOUSE_EXIT_FUNCTION[LAST_TRIGGER_FRAMEHANDLE[FRAMEEVENT_MOUSE_ENTER]] then
for _,func in ipairs(TRIGGER_MOUSE_EXIT_FUNCTION[LAST_TRIGGER_FRAMEHANDLE[FRAMEEVENT_MOUSE_ENTER]]) do
func()
end
TRIGGER_MOUSE_EXIT_IS_OUTSIDE = true
LAST_TRIGGER_FRAMEHANDLE[FRAMEEVENT_MOUSE_ENTER] = nil
end
end
end)
-- demo 1-time run functions (no longer looping infinitely):
TriggerAddMouseEnterAction(enter_t, button, function()
print("|cffffff00button 1 ENTER function|r")
end)
TriggerAddMouseEnterAction(enter_t, button2, function()
print("|cff00ff00button 2 ENTER function|r\n")
end)
TriggerAddMouseLeaveAction(exit_t, button, function()
print("|cffffff00button 1 EXIT function|r")
end)
TriggerAddMouseLeaveAction(exit_t, button2, function()
print("|cff00ff00button 2 EXIT function|r\n")
end)
TRIGGER_CATCH_EXIT_FH = catch_exit_fh
end
end
Attachments
Last edited: