From b169d1d11e2afb7d6cdac707004f52b129e7ab69 Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Sat, 14 Nov 2015 16:30:04 -0800 Subject: [PATCH] implement greedy menu input handler --- .gitignore | 1 + Lua/cheat menu.lua | 67 ++++++++++++++++-------------------- Lua/classes.lua | 1 + Lua/classes/InputHandler.lua | 21 ++++++++++- Lua/classes/JoyWrapper.lua | 20 +++++++++++ Lua/menu classes.lua | 18 ++++++---- Lua/menu input handlers.lua | 51 +++++++++++++++++++++++++++ 7 files changed, 134 insertions(+), 45 deletions(-) create mode 100644 Lua/classes/JoyWrapper.lua create mode 100644 Lua/menu input handlers.lua diff --git a/.gitignore b/.gitignore index 38a0c9d..815965f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ lua chest test lua movement test +cheat menu.save.lua * - Copy* diff --git a/Lua/cheat menu.lua b/Lua/cheat menu.lua index 8008336..3bd618f 100755 --- a/Lua/cheat menu.lua +++ b/Lua/cheat menu.lua @@ -3,6 +3,7 @@ require "boilerplate" require "addrs.init" require "classes" require "menu classes" +require "menu input handlers" require "messages" require "flag manager" @@ -13,19 +14,28 @@ normal: (alt_input = false; eat_input = false) L opens the menu L selects menu items D-Pad navigates up/down items and left/right through pages -alternate: (alt_input = true; eat_input = false) +alternate: (alt_input = true; eat_input = false) L+R opens/closes the menu L goes back a menu (or closes) R selects menu items - L+Z hides menu without closing (FIXME: interferes with back) + L+Z hides the menu without closing (FIXME: interferes with back button) D-Pad navigates greedy: (alt_input = false; eat_input = true) + L opens the menu + while the menu is open, the game receives no inputs + D-Pad/Joystick/C-Buttons navigate through items and pages + A/L select menu items + B/R go back a menu (or closes) + Z hides the menu without closing TODO: joystick, a/b button etc +greedy alt: (alt_input = true; eat_input = true) + same as greedy but pauses the game while in menu + (enables run_while_paused) --]] local run_while_paused = true local alt_input = true -local eat_input = false +local eat_input = true local fn = 'cheat menu.save.lua' local saved = deserialize('cheat menu.save.lua') or {} @@ -277,51 +287,32 @@ local main_menu = Menu{ }, } -local input = InputHandler{ - L = "P1 L", - R = "P1 R", - Z = "P1 Z", - up = "P1 DPad U", - down = "P1 DPad D", - left = "P1 DPad L", - right = "P1 DPad R", -} +local input = InputHandler() +input = JoyWrapper(input) local handle = MenuHandler(main_menu, T_TL) -function handle_alt_input(handle, ctrl, pressed) - pressed.enter = false - ctrl.enter = false - local open_close = ctrl.L and ctrl.R and (pressed.L or pressed.R) - local hide = ctrl.L and ctrl.Z and (pressed.L or pressed.Z) - if open_close then - if handle.menu then -- if menu is open - handle:navigate('close') - else - pressed.enter = true - ctrl.enter = true - end - else - if hide then - handle:navigate('hide') - elseif pressed.L then - handle:navigate('back') - elseif handle.menu then - pressed.enter = pressed.R - ctrl.enter = ctrl.R - end - end -end - while mm or oot do local ctrl, pressed = input:update() - if alt_input then + + if eat_input then + local old_menu = handle.menu + handle_eat_input(handle, ctrl, pressed) + if alt_input and handle.menu ~= old_menu then + run_while_paused = true + if handle.menu then client.pause() else client.unpause() end + end + elseif alt_input then handle_alt_input(handle, ctrl, pressed) else + for _, v in ipairs{'left', 'right', 'up', 'down'} do + ctrl[v] = ctrl['d_'..v] + pressed[v] = pressed['d_'..v] + end ctrl.enter = ctrl.L pressed.enter = pressed.L + handle:update(ctrl, pressed) end - handle:update(ctrl, pressed) for i, passive in ipairs(passives) do passive:tick() diff --git a/Lua/classes.lua b/Lua/classes.lua index 78d07f6..1d7649d 100644 --- a/Lua/classes.lua +++ b/Lua/classes.lua @@ -11,6 +11,7 @@ local classes = { "SceneFlagMonitor", "ActorLister", "InputHandler", + "JoyWrapper", } for _, class in ipairs(classes) do diff --git a/Lua/classes/InputHandler.lua b/Lua/classes/InputHandler.lua index 08b3d63..dd20cee 100644 --- a/Lua/classes/InputHandler.lua +++ b/Lua/classes/InputHandler.lua @@ -1,6 +1,25 @@ local InputHandler = Class() function InputHandler:init(binds) - self.binds = binds + self.binds = binds or { + A = "P1 A", + B = "P1 B", + L = "P1 L", + R = "P1 R", + Z = "P1 Z", + d_up = "P1 DPad U", + d_down = "P1 DPad D", + d_left = "P1 DPad L", + d_right = "P1 DPad R", + j_up = "P1 Joy U", + j_down = "P1 Joy D", + j_left = "P1 Joy L", + j_right = "P1 Joy R", + c_up = "P1 C Up", + c_down = "P1 C Down", + c_left = "P1 C Left", + c_right = "P1 C Right", + start = "P1 Start", + } self.old_ctrl = {} end diff --git a/Lua/classes/JoyWrapper.lua b/Lua/classes/JoyWrapper.lua new file mode 100644 index 0000000..d6599bf --- /dev/null +++ b/Lua/classes/JoyWrapper.lua @@ -0,0 +1,20 @@ +local JoyWrapper = Class() +function JoyWrapper:init(handler, threshold) + self.handler = handler + self.old_ctrl = {} + self.threshold = threshold or 80 +end + +function JoyWrapper:update(inputs) + local j = inputs or joypad.getimmediate() + local jj = joypad.get() + local jx = jj['P1 X Axis'] + local jy = jj['P1 Y Axis'] + j["P1 Joy R"] = jx >= self.threshold or jj['P1 A Right'] + j["P1 Joy L"] = jx <= -self.threshold or jj['P1 A Left'] + j["P1 Joy U"] = jy >= self.threshold or jj['P1 A Up'] + j["P1 Joy D"] = jy <= -self.threshold or jj['P1 A Down'] + return self.handler:update(j) +end + +return JoyWrapper diff --git a/Lua/menu classes.lua b/Lua/menu classes.lua index 0872eda..cd5b93f 100644 --- a/Lua/menu classes.lua +++ b/Lua/menu classes.lua @@ -275,7 +275,7 @@ function MenuHandler:init(main_menu, brush) self.backstack = {} self.brush = brush self.menu = nil - self.hidden = false + self.hidden = nil end function MenuHandler:push(menu) @@ -286,7 +286,14 @@ function MenuHandler:pop() return table.remove(self.backstack) end +function MenuHandler:unhide() + if not self.hidden then return end + self.menu = self.hidden + self.hidden = nil +end + function MenuHandler:navigate(new_menu) + self:unhide() if new_menu ~= self.menu then if new_menu == 'back' then new_menu = self:pop() @@ -294,8 +301,8 @@ function MenuHandler:navigate(new_menu) self.backstack = {} new_menu = nil elseif new_menu == 'hide' then - self.hidden = true - return + self.hidden = self.menu + new_menu = nil elseif self.menu and new_menu ~= self.menu then self:push(self.menu) self.menu:unfocus() @@ -308,9 +315,8 @@ end function MenuHandler:update(ctrl, pressed) if self.hidden then if not pressed.enter then return end - self.hidden = false - end - if not self.menu and pressed.enter then + self:unhide() + elseif not self.menu and pressed.enter then self:navigate(self.main_menu) elseif self.menu then local new_menu = self.menu:navigate(ctrl, pressed) diff --git a/Lua/menu input handlers.lua b/Lua/menu input handlers.lua new file mode 100644 index 0000000..09310fc --- /dev/null +++ b/Lua/menu input handlers.lua @@ -0,0 +1,51 @@ +function handle_alt_input(handle, ctrl, pressed) + for _, v in ipairs{'left', 'right', 'up', 'down'} do + ctrl[v] = ctrl['d_'..v] + pressed[v] = pressed['d_'..v] + end + pressed.enter = false + ctrl.enter = false + local open_close = ctrl.L and ctrl.R and (pressed.L or pressed.R) + local hide = ctrl.L and ctrl.Z and (pressed.L or pressed.Z) + if open_close then + if handle.menu then -- if menu is open + handle:navigate('close') + else + pressed.enter = true + ctrl.enter = true + end + else + if hide then + handle:navigate('hide') + elseif pressed.L then + handle:navigate('back') + elseif handle.menu then + pressed.enter = pressed.R + ctrl.enter = ctrl.R + end + end + handle:update(ctrl, pressed) +end + +function handle_eat_input(handle, ctrl, pressed) + for _, v in ipairs{'left', 'right', 'up', 'down'} do + ctrl[v] = ctrl['d_'..v] or ctrl['j_'..v] or ctrl['c_'..v] + pressed[v] = pressed['d_'..v] or pressed['j_'..v] or pressed['c_'..v] + end + if not handle.menu then + pressed.enter = pressed.L + else + if pressed.Z then + handle:navigate('hide') + elseif pressed.R or pressed.B then + handle:navigate('back') + end + + pressed.enter = pressed.A or pressed.L + ctrl.enter = ctrl.A or ctrl.L + + joypad.set({}, 1) + joypad.setanalog({["X Axis"]=false, ["Y Axis"]=false}, 1) + end + handle:update(ctrl, pressed) +end