Rewrote module with custom menus.
Keybindings:
  All actions with the same key will be executed.
  Check for action existing before executing.
  Fixed bug with false keybind action firing
This commit is contained in:
Azumgi 2018-02-01 22:55:39 +03:00
parent b482a2c954
commit 588fb0b47c
4 changed files with 150 additions and 128 deletions

View file

@ -110,31 +110,58 @@ end)
------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------
------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------
-- @TODO: close and unload menu on_reload
-- something for hotkeys local ingame_ui = nil
--IngameUI.init to make hotkeys? no
-- needed to protect opened menus from being closed right away and vice versa
local closing_keybind_is_pressed = false
local opening_keybind_is_pressed = true
local views_settings = {} local views_settings = {}
local transitions = {}
VMFMod.register_new_view = function (self, new_view_data) VMFMod.register_new_view = function (self, new_view_data)
new_view_data.view_settings.mod_name = self._name
views_settings[new_view_data.view_name] = new_view_data.view_settings views_settings[new_view_data.view_name] = new_view_data.view_settings
-- there's no direct access to local variable 'transitions' in ingame_ui
local transitions = require("scripts/ui/views/ingame_ui_settings").transitions
for transition_name, transition_function in pairs(new_view_data.view_transitions) do for transition_name, transition_function in pairs(new_view_data.view_transitions) do
transitions[transition_name] = transition_function transitions[transition_name] = transition_function
end end
-- @TODO: maybe there's better way to do this? if new_view_data.view_settings.hotkey_action_name then
-- can be called only on reloading vmf -- create function mod.hotkey_action_name()
local ingame_ui_exists, ingame_ui = pcall(function () return Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui end) -- so the menu will open when the keybind is pressed
self[new_view_data.view_settings.hotkey_action_name] = function()
if ingame_ui_exists then if not closing_keybind_is_pressed and ingame_ui and not ingame_ui:pending_transition() and not ingame_ui:end_screen_active() and not ingame_ui.menu_active and not ingame_ui.leave_game and not ingame_ui.return_to_title_screen and not ingame_ui.popup_join_lobby_handler.visible then
ingame_ui:handle_transition(new_view_data.view_settings.hotkey_transition_name)
end
closing_keybind_is_pressed = false
end
end
-- if reloading mods, ingame_ui exists and hook "IngameUI.setup_views" won't work
-- so set new variables and create new menu manually
if ingame_ui then
-- set 'ingame_ui.views' -- set 'ingame_ui.views'
local new_view_name = new_view_data.view_name local new_view_name = new_view_data.view_name
local new_view_init_function = new_view_data.view_settings.init_view_function local new_view_init_function = new_view_data.view_settings.init_view_function
if not ingame_ui.views[new_view_name] then --@TODO: since I do this check, close and unload custom menus while reloading if not ingame_ui.views[new_view_name] then --@TODO: since I do this check, close and unload custom menus while reloading
if ingame_ui.views[new_view_name] then
if new_view_name == ingame_ui.current_view then
ingame_ui:handle_transition("exit_menu")
end
ingame_ui.views[new_view_name]:destroy()
end
ingame_ui.views[new_view_name] = new_view_init_function(ingame_ui.ingame_ui_context) ingame_ui.views[new_view_name] = new_view_init_function(ingame_ui.ingame_ui_context)
end end
@ -145,16 +172,10 @@ VMFMod.register_new_view = function (self, new_view_data)
for blocked_transition_name, _ in pairs(current_blocked_transitions) do for blocked_transition_name, _ in pairs(current_blocked_transitions) do
ingame_ui.blocked_transitions[blocked_transition_name] = true ingame_ui.blocked_transitions[blocked_transition_name] = true
end end
--vmf:echo("INGAME_UI EXISTS")
else
--vmf:echo("INGAME_UI DOESN'T EXIST")
end end
end end
--@TODO: hotkey_mapping
vmf:hook("IngameUI.setup_views", function(func, self, ingame_ui_context) vmf:hook("IngameUI.setup_views", function(func, self, ingame_ui_context)
func(self, ingame_ui_context) func(self, ingame_ui_context)
@ -163,7 +184,6 @@ vmf:hook("IngameUI.setup_views", function(func, self, ingame_ui_context)
if self.is_in_inn then if self.is_in_inn then
if view_settings.active.inn then if view_settings.active.inn then
self.views[view_name] = view_settings.init_view_function(ingame_ui_context) self.views[view_name] = view_settings.init_view_function(ingame_ui_context)
--self.hotkey_mapping = view_settings.hotkey_mapping
end end
for blocked_transition_name, _ in pairs(view_settings.blocked_transitions.inn) do for blocked_transition_name, _ in pairs(view_settings.blocked_transitions.inn) do
@ -172,94 +192,85 @@ vmf:hook("IngameUI.setup_views", function(func, self, ingame_ui_context)
else else
if view_settings.active.ingame then if view_settings.active.ingame then
self.views[view_name] = view_settings.init_view_function(ingame_ui_context) self.views[view_name] = view_settings.init_view_function(ingame_ui_context)
--self.hotkey_mapping = view_settings.hotkey_mapping
end end
for blocked_transition_name, _ in pairs(view_settings.blocked_transitions.ingame) do for blocked_transition_name, _ in pairs(view_settings.blocked_transitions.ingame) do
self.blocked_transitions[blocked_transition_name] = true self.blocked_transitions[blocked_transition_name] = true
end end
end end
end end
end) end)
vmf:hook("IngameUI.init", function(func, self, ingame_ui_context)
func(self, ingame_ui_context)
vmf:hook("IngameUI.handle_transition", function(func, self, new_transition, ...) ingame_ui = self
end)
local successful_execution = pcall(func, self, new_transition, ...) vmf:hook("IngameUI.destroy", function(func, self)
if successful_execution then func(self)
ingame_ui = nil
end)
vmf.check_custom_menus_close_keybinds = function(dt)
if ingame_ui then
if views_settings[ingame_ui.current_view] then
local opened_view_settings = views_settings[ingame_ui.current_view]
local mod_name = opened_view_settings.mod_name
local hotkey_name = opened_view_settings.hotkey_name
if not hotkey_name then
return return
end
local close_keybind = get_mod(mod_name):get(hotkey_name)
-- vmf keybinds input service
local input_service = Managers.input:get_service("VMFMods")
local original_is_blocked = input_service:is_blocked()
if original_is_blocked then
Managers.input:device_unblock_service("keyboard", 1, "VMFMods")
end
if opening_keybind_is_pressed and not input_service:get(close_keybind[1]) then
opening_keybind_is_pressed = false
end
local close_menu = false
if not opening_keybind_is_pressed then
if input_service:get(close_keybind[1]) and
(not close_keybind[3] and not input_service:get("ctrl") or close_keybind[3] and input_service:get("ctrl")) and
(not close_keybind[4] and not input_service:get("alt") or close_keybind[4] and input_service:get("alt")) and
(not close_keybind[5] and not input_service:get("shift") or close_keybind[5] and input_service:get("shift")) then
close_menu = not ingame_ui.views[ingame_ui.current_view]:input_service():is_blocked()
end
end
if original_is_blocked then
Managers.input:device_block_service("keyboard", 1, "VMFMods")
end
if close_menu then
ingame_ui:handle_transition("exit_menu")
closing_keybind_is_pressed = true
end
else else
if not transitions[new_transition] then -- @TODO: is it right? opening_keybind_is_pressed = true
vmf:echo("Some mod is trying to use non existing view transition: " .. new_transition)
return
end
-- this block is pure copypasta from 'IngameUI.handle_transition'
local blocked_transitions = self.blocked_transitions
if blocked_transitions and blocked_transitions[new_transition] then
return
end
local previous_transition = self._previous_transition
if not self.is_transition_allowed(self, new_transition) or (previous_transition and previous_transition == new_transition) then
return
end
local transition_params = {
...
}
if self.new_transition_old_view then
return
end
local old_view = self.current_view
transitions[new_transition](self, unpack(transition_params))
local new_view = self.current_view
if old_view ~= new_view then
if self.views[old_view] and self.views[old_view].on_exit then
printf("[IngameUI] menu view on_exit %s", old_view)
self.views[old_view]:on_exit(unpack(transition_params))
end
if new_view and self.views[new_view] and self.views[new_view].on_enter then
printf("[IngameUI] menu view on_enter %s", new_view)
self.views[new_view]:on_enter(unpack(transition_params))
Managers.state.event:trigger("ingame_ui_view_on_enter", new_view)
end end
end end
end
self.new_transition = new_transition -- if reloading mods
self.new_transition_old_view = old_view if not ingame_ui then
self.transition_params = transition_params local ingame_ui_exists, ingame_ui_return = pcall(function () return Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui end)
self._previous_transition = new_transition if ingame_ui_exists then
ingame_ui = ingame_ui_return
end end
end) end
--[[
Mods.hook.set("whatever", "IngameUI.update", function(func, self, dt, t, disable_ingame_ui, end_of_level_ui)
func(self, dt, t, disable_ingame_ui, end_of_level_ui)
local end_screen_active = self.end_screen_active(self)
local gdc_build = Development.parameter("gdc")
local input_service = self.input_manager:get_service("ingame_menu")
if not self.pending_transition(self) and not end_screen_active and not self.menu_active and not self.leave_game and not self.return_to_title_screen and not gdc_build and not self.popup_join_lobby_handler.visible and input_service.get(input_service, "cancel_matchmaking", true) then
self.handle_transition(self, "vmf_options_view_force")
--MOOD_BLACKBOARD.menu = true
end
end)
]]
------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------
------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------

View file

@ -206,12 +206,25 @@ local function apply_keybinds()
for setting_name, keybind in pairs(mod_keybinds) do for setting_name, keybind in pairs(mod_keybinds) do
local action_name = keybind[1] local action_name = keybind[1]
local primary_key = keybind[2][1] local primary_key = keybind[2][1]
local key2 = keybind[2][2]
local key3 = keybind[2][3] local special_key1 = keybind[2][2]
local key4 = keybind[2][4] local special_key2 = keybind[2][3]
local special_key3 = keybind[2][4]
local special_keys = {}
if special_key1 then
special_keys[special_key1] = true
end
if special_key2 then
special_keys[special_key2] = true
end
if special_key3 then
special_keys[special_key3] = true
end
optimized_keybinds[primary_key] = optimized_keybinds[primary_key] or {} optimized_keybinds[primary_key] = optimized_keybinds[primary_key] or {}
table.insert(optimized_keybinds[primary_key], {mod_name, action_name, key2, key3, key4}) table.insert(optimized_keybinds[primary_key], {mod_name, action_name, special_keys["ctrl"], special_keys["alt"], special_keys["shift"]})
end end
end end
end end
@ -253,12 +266,13 @@ vmf.initialize_keybinds = function()
apply_keybinds() apply_keybinds()
end end
vmf:echo("hmm")
vmf.check_pressed_keybinds = function() vmf.check_pressed_keybinds = function()
local input_service = vmf.keybind_input_service local input_service = vmf.keybind_input_service
if input_service then if input_service then
-- don't check for the pressed keybindings until player will release already pressed keybind
if vmf.activated_pressed_key then if vmf.activated_pressed_key then
if input_service:get(vmf.activated_pressed_key) then if input_service:get(vmf.activated_pressed_key) then
return return
@ -267,18 +281,31 @@ vmf.check_pressed_keybinds = function()
end end
end end
local key_has_active_keybind = false
for key, key_bindings in pairs(optimized_keybinds) do for key, key_bindings in pairs(optimized_keybinds) do
if input_service:get(key) then if input_service:get(key) then
for _, binding_info in ipairs(key_bindings) do for _, binding_info in ipairs(key_bindings) do
if (not binding_info[3] and not input_service:get(binding_info[3]) or binding_info[3] and input_service:get(binding_info[3])) and if (not binding_info[3] and not input_service:get("ctrl") or binding_info[3] and input_service:get("ctrl")) and
(not binding_info[4] and not input_service:get(binding_info[4]) or binding_info[4] and input_service:get(binding_info[4])) and (not binding_info[4] and not input_service:get("alt") or binding_info[4] and input_service:get("alt")) and
(not binding_info[5] and not input_service:get(binding_info[5]) or binding_info[5] and input_service:get(binding_info[5])) then (not binding_info[5] and not input_service:get("shift") or binding_info[5] and input_service:get("shift")) then
get_mod(binding_info[1])[binding_info[2]]() --@TODO: add pcall, also check for suspending, and perhaps add "toggle" event
if not pcall(get_mod(binding_info[1])[binding_info[2]]) then
get_mod(binding_info[1]):echo("ERROR(keybindings): function '" .. tostring(binding_info[2]) .. "' wasn't found.", true)
end
key_has_active_keybind = true
--table.dump(optimized_keybinds, "optimized_keybinds", 2)
vmf.activated_pressed_key = key vmf.activated_pressed_key = key
return
end end
end end
-- return here because some other mods can have the same keybind which also need to be executed
if key_has_active_keybind then
return
end
end end
end end
end end
@ -287,3 +314,7 @@ end
vmf.delete_keybinds = function() vmf.delete_keybinds = function()
VMFModsKeyMap = {} VMFModsKeyMap = {}
end end
local something = false and 1 + 1
print("SADASDASDASDASDASDASDASDASDASD: " .. tostring(something))
print("SADASDASDASDASDASDASDASDASDASD: ")

View file

@ -15,7 +15,6 @@
local vmf = get_mod("VMF") local vmf = get_mod("VMF")
inject_material("materials/header_background", "header_background", "ingame_ui") inject_material("materials/header_background", "header_background", "ingame_ui")
inject_material("materials/header_background_lit", "header_background_lit", "ingame_ui") inject_material("materials/header_background_lit", "header_background_lit", "ingame_ui")
inject_material("materials/common_widgets_background_lit", "common_widgets_background_lit", "ingame_ui") inject_material("materials/common_widgets_background_lit", "common_widgets_background_lit", "ingame_ui")
@ -2645,37 +2644,26 @@ end
local options_widgets = {
{
["setting_name"] = "open_vmf_options",
["widget_type"] = "keybind",
["text"] = "Open menu hotkey",
["tooltip"] = "Probably keybind",
["default_value"] = {"f5"},
["action"] = "open_vmf_options"
vmf:hook("IngameUI.update", function(func, self, dt, t, disable_ingame_ui, end_of_level_ui)
func(self, dt, t, disable_ingame_ui, end_of_level_ui)
local end_screen_active = self.end_screen_active(self)
local gdc_build = Development.parameter("gdc")
local input_service = self.input_manager:get_service("ingame_menu")
if not self.pending_transition(self) and not end_screen_active and not self.menu_active and not self.leave_game and not self.return_to_title_screen and not gdc_build and not self.popup_join_lobby_handler.visible and input_service.get(input_service, "open_vmf_options", true) then
self.handle_transition(self, "vmf_options_view_force")
--vmf:echo("F10")
--MOOD_BLACKBOARD.menu = true
end
--vmf:echo("F10")
end)
--vmf:echo("F10")
IngameMenuKeymaps.win32.open_vmf_options = {
"keyboard",
"f4",
"pressed"
} }
}
vmf:create_options(options_widgets, true, "Vermintide Mod Framework", ":D")
local view_data = { local view_data = {
@ -2695,18 +2683,9 @@ local view_data = {
--vmf_options_view_force = true --vmf_options_view_force = true
} }
}, },
hotkey_mapping = { --@TODO: find out what the hell is this -> 'IngameUI.handle_menu_hotkeys' (only in inn -> useless)
--view = "inventory_view",
--error_message = "matchmaking_ready_interaction_message_inventory",
--in_transition = "inventory_view_force", --opening from hotkey
--in_transition_menu = "inventory_view" -- opening from esc menu
},
hotkey_name = "open_vmf_options", hotkey_name = "open_vmf_options",
hotkey = { hotkey_action_name = "open_vmf_options",
"keyboard", hotkey_transition_name = "vmf_options_view_force",
"f9",
"pressed"
},
transition_fade = false transition_fade = false
}, },
view_transitions = { view_transitions = {

View file

@ -23,6 +23,7 @@ return {
object.vmf.mods_update(dt) object.vmf.mods_update(dt)
object.vmf.check_pressed_keybinds() object.vmf.check_pressed_keybinds()
object.vmf.check_custom_menus_close_keybinds(dt)
if not object.vmf.all_mods_were_loaded and Managers.mod._state == "done" then if not object.vmf.all_mods_were_loaded and Managers.mod._state == "done" then