local vmf = get_mod("VMF") ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ local injected_materials = {} local none_atlas_textures = {} -- @TODO: can several materials be specified via 1 material file? Figure it out. function inject_material(material_path, material_name, ...) --print("[FUCK]: Mods.gui.inject_material " .. material_path .. material_name) local material_users = {...} if #material_users == 0 then material_users = {"all"} end for _, material_user in ipairs(material_users) do if not injected_materials[material_user] then injected_materials[material_user] = {} end table.insert(injected_materials[material_user], material_path) end none_atlas_textures[material_name] = true end --table.dump(injected_materials, "injected_materials", 2) vmf:hook("UIRenderer.create", function(func, world, ...) local ui_renderer_creator = nil -- extract the part with actual callstack local callstack = Script.callstack():match('Callstack>(.-)<') if callstack then -- get the name of lua script which called 'UIRenderer.create' -- it's always the 4th string of callstack ([ ] [0] [1] >[2]<) -- print(callstack) -- @DEBUG local i = 0 for s in callstack:gmatch("(.-)\n") do i = i + 1 if i == 4 then ui_renderer_creator = s:match("([^%/]+)%.lua") break --@TODO: uncomment after debugging or ... (?) end --EchoConsole(s) -- @DELETEME end end if ui_renderer_creator then print("UI_RENDERER CREATED BY: " .. ui_renderer_creator) -- @DEBUG else --EchoConsole("You're never supposed to see this.") --assert(true, "That's not right. That's not right at all!") --EchoConsole(callstack) return func(world, ...) end local ui_renderer_materials = {...} if injected_materials[ui_renderer_creator] then for _, material in ipairs(injected_materials[ui_renderer_creator]) do table.insert(ui_renderer_materials, "material") table.insert(ui_renderer_materials, material) end end if injected_materials["all"] then for _, material in ipairs(injected_materials["all"]) do table.insert(ui_renderer_materials, "material") table.insert(ui_renderer_materials, material) end end table.dump(ui_renderer_materials, "UI_RENDERER MATERIALS", 2) -- @DEBUG return func(world, unpack(ui_renderer_materials)) end) vmf:hook("UIAtlasHelper.get_atlas_settings_by_texture_name", function(func, texture_name) if none_atlas_textures[texture_name] then return end return func(texture_name) end) --inject_material("materials/yoba_face", "yoba_face", "ui_passes", "ingame_ui") ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ local ingame_ui = nil -- 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 = {} 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 -- 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 transitions[transition_name] = transition_function end if new_view_data.view_settings.hotkey_action_name then -- create function mod.hotkey_action_name() -- so the menu will open when the keybind is pressed self[new_view_data.view_settings.hotkey_action_name] = function() 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' local new_view_name = new_view_data.view_name local new_view_init_function = new_view_data.view_settings.init_view_function if new_view_name ~= "vmf_options_view" then ingame_ui.views[new_view_name] = new_view_init_function(ingame_ui.ingame_ui_context) end -- set 'ingame_ui.blocked_transitions' local blocked_transitions = new_view_data.view_settings.blocked_transitions local current_blocked_transitions = ingame_ui.is_in_inn and blocked_transitions.inn or blocked_transitions.ingame for blocked_transition_name, _ in pairs(current_blocked_transitions) do ingame_ui.blocked_transitions[blocked_transition_name] = true end end end vmf:hook("IngameUI.setup_views", function(func, self, ingame_ui_context) func(self, ingame_ui_context) for view_name, view_settings in pairs(views_settings) do if self.is_in_inn then if view_settings.active.inn then self.views[view_name] = view_settings.init_view_function(ingame_ui_context) end for blocked_transition_name, _ in pairs(view_settings.blocked_transitions.inn) do self.blocked_transitions[blocked_transition_name] = true end else if view_settings.active.ingame then self.views[view_name] = view_settings.init_view_function(ingame_ui_context) end for blocked_transition_name, _ in pairs(view_settings.blocked_transitions.ingame) do self.blocked_transitions[blocked_transition_name] = true end end end end) vmf:hook("IngameUI.init", function(func, self, ingame_ui_context) func(self, ingame_ui_context) ingame_ui = self end) vmf:hook("IngameUI.destroy", function(func, self) 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 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[2] and not input_service:get("ctrl") or close_keybind[2] and input_service:get("ctrl")) and (not close_keybind[3] and not input_service:get("alt") or close_keybind[3] and input_service:get("alt")) and (not close_keybind[4] and not input_service:get("shift") or close_keybind[4] 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 opening_keybind_is_pressed = true end end end vmf.close_opened_custom_menus = function() if ingame_ui then local current_view = ingame_ui.current_view if views_settings[current_view] then ingame_ui:handle_transition("exit_menu") if current_view ~= "vmf_options_view" then if ingame_ui.views[current_view].destroy and get_mod(views_settings[ingame_ui.current_view].mod_name) then get_mod(views_settings[ingame_ui.current_view].mod_name):pcall(ingame_ui.views[current_view].destroy) end ingame_ui.views[current_view] = nil end end end end -- if reloading mods if not ingame_ui then local ingame_ui_exists, ingame_ui_return = pcall(function () return Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui end) if ingame_ui_exists then ingame_ui = ingame_ui_return end end ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ local mod = new_mod("SkipSplashScreen") mod:hook("StateSplashScreen.on_enter", function(func, self) self._skip_splash = true func(self) end) mod:hook("StateSplashScreen.setup_splash_screen_view", function(func, self) func(self) self.splash_view = nil end)