From eb4935724122afde79da81410566af140dd0ce34 Mon Sep 17 00:00:00 2001 From: bi Date: Sun, 18 Feb 2018 23:49:02 +0300 Subject: [PATCH] Full refactoring, adding localization module and a lot of small features --- .../gui/common_widgets_background_lit.dds | Bin 1152 -> 0 bytes .../gui/common_widgets_background_lit.texture | 18 - vmf_source/gui/header_background.dds | Bin 1152 -> 0 bytes vmf_source/gui/header_background.texture | 18 - vmf_source/gui/header_background_lit.dds | Bin 1152 -> 0 bytes vmf_source/gui/header_background_lit.texture | 18 - vmf_source/gui/{ => vmf}/.gitignore | 0 vmf_source/gui/{ => vmf}/header_fav_arrow.dds | Bin .../gui/{ => vmf}/header_fav_arrow.texture | 2 +- vmf_source/gui/{ => vmf}/header_fav_icon.dds | Bin .../gui/{ => vmf}/header_fav_icon.texture | 2 +- .../gui/{ => vmf}/header_fav_icon_lit.dds | Bin .../gui/{ => vmf}/header_fav_icon_lit.texture | 2 +- vmf_source/gui/{ => vmf}/search_bar_icon.dds | Bin .../gui/{ => vmf}/search_bar_icon.texture | 2 +- vmf_source/localization/vmf.lua | 92 ++++ .../common_widgets_background_lit.material | 14 - .../materials/header_background.material | 14 - .../materials/header_background_lit.material | 14 - .../{ => vmf}/header_fav_arrow.material | 2 +- .../{ => vmf}/header_fav_icon.material | 2 +- .../{ => vmf}/header_fav_icon_lit.material | 2 +- .../{ => vmf}/search_bar_icon.material | 2 +- vmf_source/resource_packages/vmf.package | 28 +- .../mods/vmf/modules/{ => core}/chat.lua | 33 -- .../mods/vmf/modules/core/core_functions.lua | 193 ++++++++ .../modules/core/delayed_chat_messages.lua | 34 ++ .../scripts/mods/vmf/modules/core/events.lua | 97 ++++ .../mods/vmf/modules/{ => core}/hooks.lua | 39 +- .../vmf/modules/{ => core}/keybindings.lua | 306 ++++++------ .../mods/vmf/modules/core/localization.lua | 96 ++++ .../mods/vmf/modules/{ => core}/settings.lua | 59 ++- .../mods/vmf/modules/core/toggling.lua | 78 ++++ .../mods/vmf/modules/debug/dev_console.lua | 63 +++ .../{debug.lua => debug/table_dump.lua} | 44 +- .../scripts/mods/vmf/modules/dev_console.lua | 22 - .../modules/{gui.lua => gui/custom_menus.lua} | 160 +------ .../mods/vmf/modules/gui/custom_textures.lua | 90 ++++ .../mods/vmf/modules/gui/ui_scaling.lua | 28 ++ vmf_source/scripts/mods/vmf/modules/mods.lua | 96 +--- .../{ => options_menu}/vmf_options_view.lua | 440 +++++++----------- .../mods/vmf/modules/testing_stuff_here.lua | 86 +--- .../scripts/mods/vmf/modules/vmf_options.lua | 199 ++++++++ vmf_source/scripts/mods/vmf/vmf_loader.lua | 35 +- vmf_source/settings.ini | 2 +- vmf_source/vmf.mod | 4 +- 46 files changed, 1485 insertions(+), 951 deletions(-) delete mode 100644 vmf_source/gui/common_widgets_background_lit.dds delete mode 100644 vmf_source/gui/common_widgets_background_lit.texture delete mode 100644 vmf_source/gui/header_background.dds delete mode 100644 vmf_source/gui/header_background.texture delete mode 100644 vmf_source/gui/header_background_lit.dds delete mode 100644 vmf_source/gui/header_background_lit.texture rename vmf_source/gui/{ => vmf}/.gitignore (100%) rename vmf_source/gui/{ => vmf}/header_fav_arrow.dds (100%) rename vmf_source/gui/{ => vmf}/header_fav_arrow.texture (90%) rename vmf_source/gui/{ => vmf}/header_fav_icon.dds (100%) rename vmf_source/gui/{ => vmf}/header_fav_icon.texture (90%) rename vmf_source/gui/{ => vmf}/header_fav_icon_lit.dds (100%) rename vmf_source/gui/{ => vmf}/header_fav_icon_lit.texture (89%) rename vmf_source/gui/{ => vmf}/search_bar_icon.dds (100%) rename vmf_source/gui/{ => vmf}/search_bar_icon.texture (90%) create mode 100644 vmf_source/localization/vmf.lua delete mode 100644 vmf_source/materials/common_widgets_background_lit.material delete mode 100644 vmf_source/materials/header_background.material delete mode 100644 vmf_source/materials/header_background_lit.material rename vmf_source/materials/{ => vmf}/header_fav_arrow.material (78%) rename vmf_source/materials/{ => vmf}/header_fav_icon.material (78%) rename vmf_source/materials/{ => vmf}/header_fav_icon_lit.material (77%) rename vmf_source/materials/{ => vmf}/search_bar_icon.material (77%) rename vmf_source/scripts/mods/vmf/modules/{ => core}/chat.lua (57%) create mode 100644 vmf_source/scripts/mods/vmf/modules/core/core_functions.lua create mode 100644 vmf_source/scripts/mods/vmf/modules/core/delayed_chat_messages.lua create mode 100644 vmf_source/scripts/mods/vmf/modules/core/events.lua rename vmf_source/scripts/mods/vmf/modules/{ => core}/hooks.lua (88%) rename vmf_source/scripts/mods/vmf/modules/{ => core}/keybindings.lua (84%) create mode 100644 vmf_source/scripts/mods/vmf/modules/core/localization.lua rename vmf_source/scripts/mods/vmf/modules/{ => core}/settings.lua (63%) create mode 100644 vmf_source/scripts/mods/vmf/modules/core/toggling.lua create mode 100644 vmf_source/scripts/mods/vmf/modules/debug/dev_console.lua rename vmf_source/scripts/mods/vmf/modules/{debug.lua => debug/table_dump.lua} (87%) delete mode 100644 vmf_source/scripts/mods/vmf/modules/dev_console.lua rename vmf_source/scripts/mods/vmf/modules/{gui.lua => gui/custom_menus.lua} (51%) create mode 100644 vmf_source/scripts/mods/vmf/modules/gui/custom_textures.lua create mode 100644 vmf_source/scripts/mods/vmf/modules/gui/ui_scaling.lua rename vmf_source/scripts/mods/vmf/modules/{ => options_menu}/vmf_options_view.lua (93%) create mode 100644 vmf_source/scripts/mods/vmf/modules/vmf_options.lua diff --git a/vmf_source/gui/common_widgets_background_lit.dds b/vmf_source/gui/common_widgets_background_lit.dds deleted file mode 100644 index 59e16ea87775936da9f9f841c9547eef966c3191..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1152 zcmZ>930A0KU|?Vu;9w8{(jd&h0wPEU3P3H6P;DSK1H*q9f^fiwgC*buzqs80Q9K$3 KqiJAdrU3xn*-2Lb diff --git a/vmf_source/gui/common_widgets_background_lit.texture b/vmf_source/gui/common_widgets_background_lit.texture deleted file mode 100644 index 7235865..0000000 --- a/vmf_source/gui/common_widgets_background_lit.texture +++ /dev/null @@ -1,18 +0,0 @@ -common = { - input = { - filename = "gui/common_widgets_background_lit" - } - output = { - apply_processing = true - correct_gamma = true - cut_alpha_threshold = 0.5 - enable_cut_alpha_threshold = false - format = "A8R8G8B8" - mipmap_filter = "kaiser" - mipmap_filter_wrap_mode = "mirror" - mipmap_keep_original = false - mipmap_num_largest_steps_to_discard = 0 - mipmap_num_smallest_steps_to_discard = 0 - srgb = true - } -} \ No newline at end of file diff --git a/vmf_source/gui/header_background.dds b/vmf_source/gui/header_background.dds deleted file mode 100644 index ea334f1b5042c3d2ef67381887e733b7406dc41c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1152 zcmZ>930A0KU|?Vu;9w8{(jd&h0wPEU3P3H6P;DSK1H*q9f^fiwgC*dEsJi9930A0KU|?Vu;9w8{(jd&h0wPEU3P3H6P;DSK1H*q9f^fiwgC*dEx?kS^Q9K$3 KqiJAdrU3w0is)AW diff --git a/vmf_source/gui/header_background_lit.texture b/vmf_source/gui/header_background_lit.texture deleted file mode 100644 index 2e18e40..0000000 --- a/vmf_source/gui/header_background_lit.texture +++ /dev/null @@ -1,18 +0,0 @@ -common = { - input = { - filename = "gui/header_background_lit" - } - output = { - apply_processing = true - correct_gamma = true - cut_alpha_threshold = 0.5 - enable_cut_alpha_threshold = false - format = "A8R8G8B8" - mipmap_filter = "kaiser" - mipmap_filter_wrap_mode = "mirror" - mipmap_keep_original = false - mipmap_num_largest_steps_to_discard = 0 - mipmap_num_smallest_steps_to_discard = 0 - srgb = true - } -} \ No newline at end of file diff --git a/vmf_source/gui/.gitignore b/vmf_source/gui/vmf/.gitignore similarity index 100% rename from vmf_source/gui/.gitignore rename to vmf_source/gui/vmf/.gitignore diff --git a/vmf_source/gui/header_fav_arrow.dds b/vmf_source/gui/vmf/header_fav_arrow.dds similarity index 100% rename from vmf_source/gui/header_fav_arrow.dds rename to vmf_source/gui/vmf/header_fav_arrow.dds diff --git a/vmf_source/gui/header_fav_arrow.texture b/vmf_source/gui/vmf/header_fav_arrow.texture similarity index 90% rename from vmf_source/gui/header_fav_arrow.texture rename to vmf_source/gui/vmf/header_fav_arrow.texture index 8025595..b2d574d 100644 --- a/vmf_source/gui/header_fav_arrow.texture +++ b/vmf_source/gui/vmf/header_fav_arrow.texture @@ -1,6 +1,6 @@ common = { input = { - filename = "gui/header_fav_arrow" + filename = "gui/vmf/header_fav_arrow" } output = { apply_processing = true diff --git a/vmf_source/gui/header_fav_icon.dds b/vmf_source/gui/vmf/header_fav_icon.dds similarity index 100% rename from vmf_source/gui/header_fav_icon.dds rename to vmf_source/gui/vmf/header_fav_icon.dds diff --git a/vmf_source/gui/header_fav_icon.texture b/vmf_source/gui/vmf/header_fav_icon.texture similarity index 90% rename from vmf_source/gui/header_fav_icon.texture rename to vmf_source/gui/vmf/header_fav_icon.texture index 360fb76..1d40431 100644 --- a/vmf_source/gui/header_fav_icon.texture +++ b/vmf_source/gui/vmf/header_fav_icon.texture @@ -1,6 +1,6 @@ common = { input = { - filename = "gui/header_fav_icon" + filename = "gui/vmf/header_fav_icon" } output = { apply_processing = true diff --git a/vmf_source/gui/header_fav_icon_lit.dds b/vmf_source/gui/vmf/header_fav_icon_lit.dds similarity index 100% rename from vmf_source/gui/header_fav_icon_lit.dds rename to vmf_source/gui/vmf/header_fav_icon_lit.dds diff --git a/vmf_source/gui/header_fav_icon_lit.texture b/vmf_source/gui/vmf/header_fav_icon_lit.texture similarity index 89% rename from vmf_source/gui/header_fav_icon_lit.texture rename to vmf_source/gui/vmf/header_fav_icon_lit.texture index 106792c..0d41c7c 100644 --- a/vmf_source/gui/header_fav_icon_lit.texture +++ b/vmf_source/gui/vmf/header_fav_icon_lit.texture @@ -1,6 +1,6 @@ common = { input = { - filename = "gui/header_fav_icon_lit" + filename = "gui/vmf/header_fav_icon_lit" } output = { apply_processing = true diff --git a/vmf_source/gui/search_bar_icon.dds b/vmf_source/gui/vmf/search_bar_icon.dds similarity index 100% rename from vmf_source/gui/search_bar_icon.dds rename to vmf_source/gui/vmf/search_bar_icon.dds diff --git a/vmf_source/gui/search_bar_icon.texture b/vmf_source/gui/vmf/search_bar_icon.texture similarity index 90% rename from vmf_source/gui/search_bar_icon.texture rename to vmf_source/gui/vmf/search_bar_icon.texture index b1393b0..7286b31 100644 --- a/vmf_source/gui/search_bar_icon.texture +++ b/vmf_source/gui/vmf/search_bar_icon.texture @@ -1,6 +1,6 @@ common = { input = { - filename = "gui/search_bar_icon" + filename = "gui/vmf/search_bar_icon" } output = { apply_processing = true diff --git a/vmf_source/localization/vmf.lua b/vmf_source/localization/vmf.lua new file mode 100644 index 0000000..0a3a81b --- /dev/null +++ b/vmf_source/localization/vmf.lua @@ -0,0 +1,92 @@ +return { + mods_options = { + en = "Mods Options", + ru = "Настройки модов", + }, + open_vmf_options = { + en = "Open Options Menu", + ru = "Открыть меню настроек", + }, + open_vmf_options_tooltip = { + en = "Keybind for opening and closing mods options menu.", + ru = "Клавиша / сочетание клавиш для открытия и закрытия меню настроек модов.", + }, + vmf_options_scrolling_speed = { + en = "Options Menu Scrolling Speed", + ru = "Скорость прокрутки меню", + }, + ui_scaling = { + en = "UI Scaling for FHD+ Resolutions", + ru = "Нормализация масштаба UI для FHD+ разрешений", + }, + ui_scaling_tooltip = { + en = "Automatically scale UI when resolution exceeds 1080p.", + ru = "Нормализует масштаб элементов интерфейса, если разрешений экрана превышает 1080p.", + }, + developer_mode = { + en = "Developer Mode", + ru = "Режим разработчика", + }, + developer_mode_tooltip = { + en = "Allows you to reload VMF and mods, gives you access to some debug features.", + ru = "Позволяет перезагружать VMF и моды, даёт доступ к инструментам отладки.", + }, + show_developer_console = { + en = "Show Developer Console", + ru = "Консоль разработчика", + }, + show_developer_console_tooltip = { + en = "Opens up the new window showing game log in real time.\n\n" .. + "In order to safely close this window, disable it from the menu options first, and then close the window.", + ru = "Открывает новое окно, в которое в реальном времени выводится игровой лог.\n\n" .. + "Чтобы его закрыть, сначала выключите консоль из меню настроек, и потом закройте вручную.", + }, + logging_mode = { + en = "Logging Settings.", + ru = "Настройки логирования", + }, + settings_default = { + en = "Default", + ru = "Стандартные", + }, + settings_custom = { + en = "Custom", + ru = "Пользовательские", + }, + output_mode_echo = { + en = "'Echo' output", + ru = "Вывод 'Echo'", + }, + output_mode_error = { + en = "'Error' output", + ru = "Вывод 'Error'", + }, + output_mode_warning = { + en = "'Warning' output", + ru = "Вывод 'Warning'", + }, + output_mode_info = { + en = "'Info' output", + ru = "Вывод 'Info'", + }, + output_mode_spew = { + en = "'Spew' output", + ru = "Вывод 'Spew'", + }, + output_disabled = { + en = "Disabled", + ru = "Выключен", + }, + output_log = { + en = "Log", + ru = "Лог", + }, + output_chat = { + en = "Chat", + ru = "Чат", + }, + output_log_and_chat = { + en = "Log & Chat", + ru = "Лог и чат", + }, +} \ No newline at end of file diff --git a/vmf_source/materials/common_widgets_background_lit.material b/vmf_source/materials/common_widgets_background_lit.material deleted file mode 100644 index de8a460..0000000 --- a/vmf_source/materials/common_widgets_background_lit.material +++ /dev/null @@ -1,14 +0,0 @@ -common_widgets_background_lit = { - material_contexts = { - surface_material = "" - } - - shader = "gui_gradient:DIFFUSE_MAP:MASKED" - - textures = { - diffuse_map = "gui/common_widgets_background_lit" - } - - variables = { - } -} diff --git a/vmf_source/materials/header_background.material b/vmf_source/materials/header_background.material deleted file mode 100644 index c3a142b..0000000 --- a/vmf_source/materials/header_background.material +++ /dev/null @@ -1,14 +0,0 @@ -header_background = { - material_contexts = { - surface_material = "" - } - - shader = "gui_gradient:DIFFUSE_MAP:MASKED" - - textures = { - diffuse_map = "gui/header_background" - } - - variables = { - } -} diff --git a/vmf_source/materials/header_background_lit.material b/vmf_source/materials/header_background_lit.material deleted file mode 100644 index 1ac89b9..0000000 --- a/vmf_source/materials/header_background_lit.material +++ /dev/null @@ -1,14 +0,0 @@ -header_background_lit = { - material_contexts = { - surface_material = "" - } - - shader = "gui_gradient:DIFFUSE_MAP:MASKED" - - textures = { - diffuse_map = "gui/header_background_lit" - } - - variables = { - } -} diff --git a/vmf_source/materials/header_fav_arrow.material b/vmf_source/materials/vmf/header_fav_arrow.material similarity index 78% rename from vmf_source/materials/header_fav_arrow.material rename to vmf_source/materials/vmf/header_fav_arrow.material index a9f6528..9f78214 100644 --- a/vmf_source/materials/header_fav_arrow.material +++ b/vmf_source/materials/vmf/header_fav_arrow.material @@ -6,7 +6,7 @@ header_fav_arrow = { shader = "gui_gradient:DIFFUSE_MAP:MASKED" textures = { - diffuse_map = "gui/header_fav_arrow" + diffuse_map = "gui/vmf/header_fav_arrow" } variables = { diff --git a/vmf_source/materials/header_fav_icon.material b/vmf_source/materials/vmf/header_fav_icon.material similarity index 78% rename from vmf_source/materials/header_fav_icon.material rename to vmf_source/materials/vmf/header_fav_icon.material index b78a2e9..548d034 100644 --- a/vmf_source/materials/header_fav_icon.material +++ b/vmf_source/materials/vmf/header_fav_icon.material @@ -6,7 +6,7 @@ header_fav_icon = { shader = "gui_gradient:DIFFUSE_MAP:MASKED" textures = { - diffuse_map = "gui/header_fav_icon" + diffuse_map = "gui/vmf/header_fav_icon" } variables = { diff --git a/vmf_source/materials/header_fav_icon_lit.material b/vmf_source/materials/vmf/header_fav_icon_lit.material similarity index 77% rename from vmf_source/materials/header_fav_icon_lit.material rename to vmf_source/materials/vmf/header_fav_icon_lit.material index a0130d3..e193268 100644 --- a/vmf_source/materials/header_fav_icon_lit.material +++ b/vmf_source/materials/vmf/header_fav_icon_lit.material @@ -6,7 +6,7 @@ header_fav_icon_lit = { shader = "gui_gradient:DIFFUSE_MAP:MASKED" textures = { - diffuse_map = "gui/header_fav_icon_lit" + diffuse_map = "gui/vmf/header_fav_icon_lit" } variables = { diff --git a/vmf_source/materials/search_bar_icon.material b/vmf_source/materials/vmf/search_bar_icon.material similarity index 77% rename from vmf_source/materials/search_bar_icon.material rename to vmf_source/materials/vmf/search_bar_icon.material index 73bb03c..69158d7 100644 --- a/vmf_source/materials/search_bar_icon.material +++ b/vmf_source/materials/vmf/search_bar_icon.material @@ -6,7 +6,7 @@ search_bar_icon = { shader = "gui_gradient:DIFFUSE_MAP" textures = { - diffuse_map = "gui/search_bar_icon" + diffuse_map = "gui/vmf/search_bar_icon" } variables = { diff --git a/vmf_source/resource_packages/vmf.package b/vmf_source/resource_packages/vmf.package index 68f24e9..88810b0 100644 --- a/vmf_source/resource_packages/vmf.package +++ b/vmf_source/resource_packages/vmf.package @@ -7,27 +7,17 @@ package = [ ] material = [ - "materials/header_background" - "materials/header_background_lit" - "materials/common_widgets_background_lit" - "materials/header_fav_icon" - "materials/header_fav_icon_lit" - "materials/header_fav_arrow" - "materials/search_bar_icon" + "materials/vmf/*" ] lua = [ - "scripts/mods/vmf/functions/*" + "localization/vmf" - "scripts/mods/vmf/vmf_loader" - "scripts/mods/vmf/modules/dev_console" - "scripts/mods/vmf/modules/mods" - "scripts/mods/vmf/modules/debug" - "scripts/mods/vmf/modules/hooks" - "scripts/mods/vmf/modules/chat" - "scripts/mods/vmf/modules/settings" - "scripts/mods/vmf/modules/keybindings" - "scripts/mods/vmf/modules/gui" - "scripts/mods/vmf/modules/vmf_options_view" - "scripts/mods/vmf/modules/testing_stuff_here" + "scripts/mods/vmf/*" + "scripts/mods/vmf/functions/*" + "scripts/mods/vmf/modules/*" + "scripts/mods/vmf/modules/core/*" + "scripts/mods/vmf/modules/debug/*" + "scripts/mods/vmf/modules/gui/*" + "scripts/mods/vmf/modules/options_menu/*" ] \ No newline at end of file diff --git a/vmf_source/scripts/mods/vmf/modules/chat.lua b/vmf_source/scripts/mods/vmf/modules/core/chat.lua similarity index 57% rename from vmf_source/scripts/mods/vmf/modules/chat.lua rename to vmf_source/scripts/mods/vmf/modules/core/chat.lua index ee987f7..0204a89 100644 --- a/vmf_source/scripts/mods/vmf/modules/chat.lua +++ b/vmf_source/scripts/mods/vmf/modules/core/chat.lua @@ -1,42 +1,9 @@ local vmf = get_mod("VMF") --- #################################################################################################################### --- ##### Hooks Functions ############################################################################################## --- #################################################################################################################### - --- HOOK: [ChatManager.register_channel] -local hook_send_unsent_messages = function (func, self, channel_id, members_func) - - func(self, channel_id, members_func) - - if channel_id == 1 then - for _, message in ipairs(vmf.unsent_chat_messages) do - self:add_local_system_message(1, message, true) - end - end -end - --- #################################################################################################################### --- ##### Event functions ############################################################################################## --- #################################################################################################################### - --- at the moment of loading VMF Chat Manager is not initialized yet, --- so it should be hooked with some delay -vmf.hook_chat_manager = function() - - if not vmf.is_chat_manager_hooked then - vmf.is_chat_manager_hooked = true - - vmf:hook("ChatManager.register_channel", hook_send_unsent_messages) - end -end - - -- #################################################################################################################### -- ##### VMFMod ####################################################################################################### -- #################################################################################################################### - VMFMod.chat_broadcast = function(self, message) local chat = Managers.chat diff --git a/vmf_source/scripts/mods/vmf/modules/core/core_functions.lua b/vmf_source/scripts/mods/vmf/modules/core/core_functions.lua new file mode 100644 index 0000000..c76b0f3 --- /dev/null +++ b/vmf_source/scripts/mods/vmf/modules/core/core_functions.lua @@ -0,0 +1,193 @@ +local vmf = get_mod("VMF") + +local _UNSENT_CHAT_MESSAGES = {} +local _LOGGING_SETTINGS + +-- #################################################################################################################### +-- ##### Local functions ############################################################################################## +-- #################################################################################################################### + +local function safe_format(mod, str, ...) + + -- the game still crash with unknown error if there is non-standard character after '%' @TODO: any solutions? + local success, message = pcall(string.format, str, ...) + + if success then + return message + else + mod:error("string.format: " .. tostring(message)) --@TODO: good description + end +end + +local function send_to_chat(message) + + if Managers.chat and Managers.chat:has_channel(1) then + Managers.chat:add_local_system_message(1, message, true) + else + table.insert(_UNSENT_CHAT_MESSAGES, message) + end +end + +local function send_to_log(message) + + print("[MOD]" .. message) +end + +-- #################################################################################################################### +-- ##### VMFMod ####################################################################################################### +-- #################################################################################################################### + +VMFMod.echo = function (self, message, ...) + + message = tostring(message) + + message = safe_format(self, message, ...) + + if message then + if _LOGGING_SETTINGS.echo.send_to_chat then + send_to_chat(message) + end + + message = "[" .. self:get_name() .. "][ECHO] " .. message + + if _LOGGING_SETTINGS.echo.send_to_log then + send_to_log(message) + end + end +end + + +VMFMod.error = function (self, message, ...) + + message = tostring(message) + + message = safe_format(self, message, ...) + + if message then + message = "[" .. self:get_name() .. "][ERROR] " .. message + + if _LOGGING_SETTINGS.error.send_to_chat then + send_to_chat(message) + end + + if _LOGGING_SETTINGS.error.send_to_log then + send_to_log(message) + end + end +end + + +VMFMod.warning = function (self, message, ...) + + message = tostring(message) + + message = safe_format(self, message, ...) + + if message then + message = "[" .. self:get_name() .. "][WARNING] " .. message + + if _LOGGING_SETTINGS.warning.send_to_chat then + send_to_chat(message) + end + + if _LOGGING_SETTINGS.warning.send_to_log then + send_to_log(message) + end + end +end + + +VMFMod.info = function (self, message, ...) + + message = tostring(message) + + message = safe_format(self, message, ...) + + if message then + message = "[" .. self:get_name() .. "][INFO] " .. message + + if _LOGGING_SETTINGS.info.send_to_chat then + send_to_chat(message) + end + + if _LOGGING_SETTINGS.info.send_to_log then + send_to_log(message) + end + end +end + + +VMFMod.spew = function (self, message, ...) + + message = tostring(message) + + message = safe_format(self, message, ...) + + if message then + message = "[" .. self:get_name() .. "][SPEW] " .. message + + if _LOGGING_SETTINGS.spew.send_to_chat then + send_to_chat(message) + end + + if _LOGGING_SETTINGS.spew.send_to_log then + send_to_log(message) + end + end +end + + +VMFMod.pcall = function (self, ...) + local status, value = pcall(...) + + if not status then + self:error("(pcall): %s", tostring(value)) + end + + return status, value +end + + +VMFMod.dofile = function (self, script_path) + + local success, value = pcall(dofile, script_path) + + if not success then + self:error("(loadfile): %s", value.error) + + print("\nTRACEBACK:\n\n" .. value.traceback .. "\nLOCALS:\n\n" .. value.locals) + end + + return value +end + +-- #################################################################################################################### +-- ##### VMF internal functions and variables ######################################################################### +-- #################################################################################################################### + + +vmf.unsent_chat_messages = _UNSENT_CHAT_MESSAGES + +vmf.load_logging_settings = function () + + _LOGGING_SETTINGS = { + echo = vmf:get("logging_mode") == "custom" and vmf:get("output_mode_echo") or 3, + error = vmf:get("logging_mode") == "custom" and vmf:get("output_mode_error") or 3, + warning = vmf:get("logging_mode") == "custom" and vmf:get("output_mode_warning") or 3, + info = vmf:get("logging_mode") == "custom" and vmf:get("output_mode_info") or 1, + spew = vmf:get("logging_mode") == "custom" and vmf:get("output_mode_spew") or 0, + } + + for method_name, logging_mode in pairs(_LOGGING_SETTINGS) do + _LOGGING_SETTINGS[method_name] = { + send_to_chat = logging_mode >= 2, + send_to_log = logging_mode % 2 == 1 + } + end +end + +-- #################################################################################################################### +-- ##### Script ####################################################################################################### +-- #################################################################################################################### + +vmf.load_logging_settings() \ No newline at end of file diff --git a/vmf_source/scripts/mods/vmf/modules/core/delayed_chat_messages.lua b/vmf_source/scripts/mods/vmf/modules/core/delayed_chat_messages.lua new file mode 100644 index 0000000..80e2881 --- /dev/null +++ b/vmf_source/scripts/mods/vmf/modules/core/delayed_chat_messages.lua @@ -0,0 +1,34 @@ +-- @TODO: do I need to hook it at all? + +local vmf = get_mod("VMF") + +-- #################################################################################################################### +-- ##### Hooks Functions ############################################################################################## +-- #################################################################################################################### + +-- HOOK: [ChatManager.register_channel] +local hook_send_unsent_messages = function (func, self, channel_id, members_func) + + func(self, channel_id, members_func) + + if channel_id == 1 then + for _, message in ipairs(vmf.unsent_chat_messages) do + self:add_local_system_message(1, message, true) + end + end +end + +-- #################################################################################################################### +-- ##### VMF internal functions and variables ######################################################################### +-- #################################################################################################################### + +-- at the moment of loading VMF Chat Manager is not initialized yet, +-- so it should be hooked with some delay +vmf.hook_chat_manager = function() + + if not vmf.is_chat_manager_hooked then + vmf.is_chat_manager_hooked = true + + vmf:hook("ChatManager.register_channel", hook_send_unsent_messages) + end +end \ No newline at end of file diff --git a/vmf_source/scripts/mods/vmf/modules/core/events.lua b/vmf_source/scripts/mods/vmf/modules/core/events.lua new file mode 100644 index 0000000..ae67e61 --- /dev/null +++ b/vmf_source/scripts/mods/vmf/modules/core/events.lua @@ -0,0 +1,97 @@ +local vmf = get_mod("VMF") + +local _MODS = vmf.mods +local _MODS_UNLOADING_ORDER = vmf.mods_unloading_order + +-- #################################################################################################################### +-- ##### Local functions ############################################################################################## +-- #################################################################################################################### + +local function run_event(mod, event_name, event, ...) + + local success, error_message = pcall(event, ...) + if not success then + mod:error("(mod.%s): %s", event_name, error_message) + end +end + +-- #################################################################################################################### +-- ##### VMF internal functions and variables ######################################################################### +-- #################################################################################################################### + +-- call 'unload' for every mod which defined it +vmf.mods_unload_event = function() + + local event_name = "on_unload" + + for _, mod_name in ipairs(_MODS_UNLOADING_ORDER) do + + local mod = _MODS[mod_name] + local event = mod[event_name] + if event then + run_event(mod, event_name, event) + end + end +end + +-- call 'update' for every mod which defined it +vmf.mods_update_event = function(dt) + + local event_name = "update" + + for _, mod in pairs(_MODS) do + + local event = mod[event_name] + if event then + run_event(mod, event_name, event, dt) + end + end +end + +-- call 'game_state_changed' for every mod which defined it +vmf.mods_game_state_changed_event = function(status, state) + + local event_name = "on_game_state_changed" + + for _, mod in pairs(_MODS) do + + local event = mod[event_name] + if event then + run_event(mod, event_name, event, status, state) + end + end +end + +vmf.mod_setting_changed_event = function(mod, setting_name) + + local event_name = "on_setting_changed" + + local event = mod[event_name] + if event then + run_event(mod, event_name, event, setting_name) + end +end + +vmf.mod_enabled_event = function(mod) + + local event_name = "on_enabled" + + local event = mod[event_name] + if event then + run_event(mod, event_name, event) + else + mod:warning("Attemt to call undefined event 'mod.%s'.", event_name) + end +end + +vmf.mod_disabled_event = function(mod) + + local event_name = "on_disabled" + + local event = mod[event_name] + if event then + run_event(mod, event_name, event) + else + mod:warning("Attemt to call undefined event 'mod.%s'.", event_name) + end +end \ No newline at end of file diff --git a/vmf_source/scripts/mods/vmf/modules/hooks.lua b/vmf_source/scripts/mods/vmf/modules/core/hooks.lua similarity index 88% rename from vmf_source/scripts/mods/vmf/modules/hooks.lua rename to vmf_source/scripts/mods/vmf/modules/core/hooks.lua index ad86dca..9f60bd9 100644 --- a/vmf_source/scripts/mods/vmf/modules/hooks.lua +++ b/vmf_source/scripts/mods/vmf/modules/core/hooks.lua @@ -3,9 +3,19 @@ local vmf = get_mod("VMF") HOOKED_FUNCTIONS = {} -- global, because 'loadstring' doesn't see local variables -- #################################################################################################################### --- ##### Private functions ############################################################################################ +-- ##### Local functions ############################################################################################## -- #################################################################################################################### +local function check_function_name(mod, hook_function_name, hooked_function_name) + if type(hooked_function_name) ~= "string" then + mod:error("(%s): hooked function argument should be the string, not %s", hook_function_name, type(hooked_function_name)) + return false + end + + return true +end + + local function get_function_by_name(function_name) local _, value = pcall(loadstring("return " .. function_name)) @@ -117,7 +127,7 @@ end local function modify_hook(mod, hooked_function_name, action) if not get_function_by_name(hooked_function_name) then - mod:echo("ERROR: 'hook_".. action .. "' - function [" .. hooked_function_name .. "] doesn't exist", true) + mod:error("(hook_%s): function [%s] doesn't exist", action, hooked_function_name) return end @@ -174,13 +184,11 @@ local function modify_all_hooks(mod, action) if #hooked_function_entry.hooks == 0 then table.insert(no_hooks_functions_indexes, 1, i) end - end for _, no_hooks_function_index in ipairs(no_hooks_functions_indexes) do table.remove(HOOKED_FUNCTIONS, no_hooks_function_index) end - end -- #################################################################################################################### @@ -189,9 +197,13 @@ end VMFMod.hook = function (self, hooked_function_name, hook_function) + if not check_function_name(self, "hook", hooked_function_name) then + return + end + local hooked_function_entry = get_hooked_function_entry(hooked_function_name) or create_hooked_function_entry(hooked_function_name) if not hooked_function_entry then - self:echo("ERROR: 'hook' - function [" .. hooked_function_name .. "] doesn't exist", true) + self:error("(hook): function [%s] doesn't exist", hooked_function_name) return end @@ -211,16 +223,31 @@ end VMFMod.hook_remove = function (self, hooked_function_name) + + if not check_function_name(self, "hook_remove", hooked_function_name) then + return + end + modify_hook(self, hooked_function_name, "remove") end VMFMod.hook_disable = function (self, hooked_function_name) + + if not check_function_name(self, "hook_disable", hooked_function_name) then + return + end + modify_hook(self, hooked_function_name, "disable") end VMFMod.hook_enable = function (self, hooked_function_name) + + if not check_function_name(self, "hook_enable", hooked_function_name) then + return + end + modify_hook(self, hooked_function_name, "enable") end @@ -240,7 +267,7 @@ VMFMod.enable_all_hooks = function (self) end -- #################################################################################################################### --- ##### Event functions ############################################################################################## +-- ##### VMF internal functions and variables ######################################################################### -- #################################################################################################################### -- removes all hooks when VMF is about to be reloaded diff --git a/vmf_source/scripts/mods/vmf/modules/keybindings.lua b/vmf_source/scripts/mods/vmf/modules/core/keybindings.lua similarity index 84% rename from vmf_source/scripts/mods/vmf/modules/keybindings.lua rename to vmf_source/scripts/mods/vmf/modules/core/keybindings.lua index bb3052c..14cc752 100644 --- a/vmf_source/scripts/mods/vmf/modules/keybindings.lua +++ b/vmf_source/scripts/mods/vmf/modules/core/keybindings.lua @@ -1,5 +1,163 @@ local vmf = get_mod("VMF") +VMFModsKeyMap = { + win32 = { + ["ctrl"] = {"keyboard", "left ctrl", "held"}, + ["alt"] = {"keyboard", "left alt", "held"}, + ["shift"] = {"keyboard", "left shift", "held"} + } +} + +-- ["mod_name"]["setting_name"] = {"action_name", {"primary_key", "special_key", "special_key", "special_key"}} (special_key - "ctrl"/"shift"/"alt") +local _RAW_KEYBINDS = {} + +-- ["primary_key"] = {{"mod_name", "action_name", ctrl_used(bool), alt_used(bool), shift_used(bool)}, {}, {}, ...} +local _OPTIMIZED_KEYBINDS = {} + +-- #################################################################################################################### +-- ##### Local functions ############################################################################################## +-- #################################################################################################################### + +local function apply_keybinds() + + _OPTIMIZED_KEYBINDS = {} + + for mod_name, mod_keybinds in pairs(_RAW_KEYBINDS) do + for _, keybind in pairs(mod_keybinds) do + local action_name = keybind[1] + local primary_key = keybind[2][1] + + local special_key1 = keybind[2][2] + 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 {} + table.insert(_OPTIMIZED_KEYBINDS[primary_key], {mod_name, action_name, special_keys["ctrl"], special_keys["alt"], special_keys["shift"]}) + end + end +end + +-- #################################################################################################################### +-- ##### VMFMod ####################################################################################################### +-- #################################################################################################################### + +-- use it directly only for dedugging purposes, otherwise use keybind widget +-- setting_name [string] - keybind identifyer for certain mod +-- action_name [string] - name of some mod.function which will be called when keybind is pressed +-- keys [table] = {"primary_key", "2nd_key" [optional], "3rd_key" [optional], "4th_key" [optional]} +-- 2, 3, 4 keys can contain words "ctrl", "alt", "shift" (lowercase) +VMFMod.keybind = function (self, setting_name, action_name, keys) + + if keys[1] then + + local mod_keybinds = _RAW_KEYBINDS[self:get_name()] or {} + + mod_keybinds[setting_name] = {action_name, keys} + + _RAW_KEYBINDS[self:get_name()] = mod_keybinds + else + + local mod_keybinds = _RAW_KEYBINDS[self:get_name()] + + if mod_keybinds and mod_keybinds[setting_name] then + mod_keybinds[setting_name] = nil + end + end + + if vmf.keybind_input_service then + apply_keybinds() + end +end + +-- #################################################################################################################### +-- ##### VMF internal functions and variables ######################################################################### +-- #################################################################################################################### + +vmf.initialize_keybinds = function() + Managers.input.create_input_service(Managers.input, "VMFMods", "VMFModsKeyMap") + Managers.input.map_device_to_service(Managers.input, "VMFMods", "keyboard") + Managers.input.map_device_to_service(Managers.input, "VMFMods", "mouse") + + vmf.keybind_input_service = Managers.input:get_service("VMFMods") + + apply_keybinds() +end + +vmf.check_pressed_keybinds = function() + + local input_service = vmf.keybind_input_service + 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 input_service:get(vmf.activated_pressed_key) then + return + else + vmf.activated_pressed_key = nil + end + end + + local key_has_active_keybind = false + + for key, key_bindings in pairs(_OPTIMIZED_KEYBINDS) do + if input_service:get(key) then + for _, binding_info in ipairs(key_bindings) do + 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("alt") or binding_info[4] and input_service:get("alt")) and + (not binding_info[5] and not input_service:get("shift") or binding_info[5] and input_service:get("shift")) then + + local mod = get_mod(binding_info[1]) + + if binding_info[2] == "toggle_mod" then + + vmf.mod_state_changed(mod:get_name(), not mod:is_enabled()) + + key_has_active_keybind = true + vmf.activated_pressed_key = key + + elseif mod:is_enabled() then + + local action_exists, action_function = pcall(function() return mod[binding_info[2]] end) + if action_exists then + local success, error_message = pcall(action_function) + if not success then + mod:error("(keybindings)(mod.%s): %s", tostring(binding_info[2]), tostring(error_message)) + end + else + mod:error("(keybindings): function '%s' wasn't found.", tostring(binding_info[2])) + end + + key_has_active_keybind = true + vmf.activated_pressed_key = key + 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 + +vmf.delete_keybinds = function() + VMFModsKeyMap = {} +end + local keyboard_buton_name = Keyboard.button_name local mouse_buton_name = Mouse.button_name @@ -152,6 +310,10 @@ vmf.keys = { vmf.readable_key_names = {} +-- #################################################################################################################### +-- ##### Script ####################################################################################################### +-- #################################################################################################################### + for _, controller_keys in pairs(vmf.keys) do for _, key_info in pairs(controller_keys) do vmf.readable_key_names[key_info[2]] = key_info[1] @@ -162,15 +324,6 @@ vmf.readable_key_names["ctrl"] = "Ctrl" vmf.readable_key_names["alt"] = "Alt" vmf.readable_key_names["shift"] = "Shift" -VMFModsKeyMap = { - win32 = { - ["ctrl"] = {"keyboard", "left ctrl", "held"}, - ["alt"] = {"keyboard", "left alt", "held"}, - ["shift"] = {"keyboard", "left shift", "held"} - } -} - - for _, key_info in pairs(vmf.keys.keyboard) do VMFModsKeyMap.win32[key_info[2]] = {"keyboard", key_info[3], "held"} end @@ -183,139 +336,4 @@ end for i = 10, 13 do local key_info = vmf.keys.mouse[i] VMFModsKeyMap.win32[key_info[2]] = {"mouse", key_info[3], "pressed"} -end - - - - - - - --- ["mod_name"]["setting_name"] = {"action_name", {"primary_key", "2nd_key", "3rd_key", "4th_key"}} -local raw_keybinds = {} - --- ["primary_key"] = {{"mod_name", "action_name", "2nd_key", "3rd_key", "4th_key"}, {}, {}, ...} -local optimized_keybinds = {} - - -local function apply_keybinds() - - optimized_keybinds = {} - - for mod_name, mod_keybinds in pairs(raw_keybinds) do - for _, keybind in pairs(mod_keybinds) do - local action_name = keybind[1] - local primary_key = keybind[2][1] - - local special_key1 = keybind[2][2] - 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 {} - table.insert(optimized_keybinds[primary_key], {mod_name, action_name, special_keys["ctrl"], special_keys["alt"], special_keys["shift"]}) - end - end -end - --- use it directly only for dedugging purposes, otherwise use keybind widget --- setting_name [string] - keybind identifyer for certain mod --- action_name [string] - name of some mod.function which will be called when keybind is pressed --- keys [table] = {"primary_key", "2nd_key" [optional], "3rd_key" [optional], "4th_key" [optional]} --- 2, 3, 4 keys can contain words "ctrl", "alt", "shift" (lowercase) -VMFMod.keybind = function (self, setting_name, action_name, keys) - - if keys[1] then - - local mod_keybinds = raw_keybinds[self._name] or {} - - mod_keybinds[setting_name] = {action_name, keys} - - raw_keybinds[self._name] = mod_keybinds - else - - local mod_keybinds = raw_keybinds[self._name] - - if mod_keybinds and mod_keybinds[setting_name] then - mod_keybinds[setting_name] = nil - end - end - - if vmf.keybind_input_service then - apply_keybinds() - end -end - -vmf.initialize_keybinds = function() - Managers.input.create_input_service(Managers.input, "VMFMods", "VMFModsKeyMap") - Managers.input.map_device_to_service(Managers.input, "VMFMods", "keyboard") - Managers.input.map_device_to_service(Managers.input, "VMFMods", "mouse") - - vmf.keybind_input_service = Managers.input:get_service("VMFMods") - - apply_keybinds() -end - -vmf.check_pressed_keybinds = function() - - local input_service = vmf.keybind_input_service - 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 input_service:get(vmf.activated_pressed_key) then - return - else - vmf.activated_pressed_key = nil - end - end - - local key_has_active_keybind = false - - for key, key_bindings in pairs(optimized_keybinds) do - if input_service:get(key) then - for _, binding_info in ipairs(key_bindings) do - 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("alt") or binding_info[4] and input_service:get("alt")) and - (not binding_info[5] and not input_service:get("shift") or binding_info[5] and input_service:get("shift")) then - --@TODO: also check for suspending, and perhaps add "toggle" event - - local action_exists, action_function = pcall(function() return get_mod(binding_info[1])[binding_info[2]] end) - if action_exists then - local success, error_message = pcall(action_function) - if not success then - get_mod(binding_info[1]):echo("ERROR(keybindings) in function '" .. tostring(binding_info[2]) .. "': " .. tostring(error_message), true) - end - else - get_mod(binding_info[1]):echo("ERROR(keybindings): function '" .. tostring(binding_info[2]) .. "' wasn't found.", true) - end - - key_has_active_keybind = true - - vmf.activated_pressed_key = key - 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 - -vmf.delete_keybinds = function() - VMFModsKeyMap = {} end \ No newline at end of file diff --git a/vmf_source/scripts/mods/vmf/modules/core/localization.lua b/vmf_source/scripts/mods/vmf/modules/core/localization.lua new file mode 100644 index 0000000..888282d --- /dev/null +++ b/vmf_source/scripts/mods/vmf/modules/core/localization.lua @@ -0,0 +1,96 @@ +local vmf = get_mod("VMF") + +--[[ +English (en) +French (fr) +German (de) +Spanish (es) +Russian (ru) +Portuguese-Brazil (br-pt) +Italian (it) +Polish (pl) +]] + +local _LANGUAGE_ID = Application.user_setting("language_id") +local _LOCALIZATION_DATABASE = {} + +-- #################################################################################################################### +-- ##### Local functions ############################################################################################## +-- #################################################################################################################### + +local function safe_string_format(mod, str, ...) + + -- the game still crash with unknown error if there is non-standard character after '%' + local success, message = pcall(string.format, str, ...) + + if success then + return message + else + mod:error("(localize) \"%s\": %s", tostring(str), tostring(message)) + end +end + +-- #################################################################################################################### +-- ##### VMFMod ####################################################################################################### +-- #################################################################################################################### + +VMFMod.localization = function (self, path) + + local success, value = pcall(dofile, path) + + if not success then + self:error("(localization): %s", value.error) + return + end + + if type(value) ~= "table" then + self:error("(localization): localization file should return table") + return + end + + if _LOCALIZATION_DATABASE[self:get_name()] then + self:warning("(localization): overwritting already loaded localization file") + end + + _LOCALIZATION_DATABASE[self:get_name()] = value +end + + +VMFMod.localize = function (self, text_id, ...) + + local mod_localization_table = _LOCALIZATION_DATABASE[self:get_name()] + if mod_localization_table then + + local text_translations = mod_localization_table[text_id] + if text_translations then + + local message + + if text_translations[_LANGUAGE_ID] then + + message = safe_string_format(self, text_translations[_LANGUAGE_ID], ...) + if message then + return message + end + end + + if text_translations["en"] then + + message = safe_string_format(self, text_translations["en"], ...) + if message then + return message + end + end + end + + return "<" .. tostring(text_id) .. ">" + else + self:error("(localize): localization file was not loaded for this mod") + end +end + +-- #################################################################################################################### +-- ##### Script ####################################################################################################### +-- #################################################################################################################### + +vmf:localization("localization/vmf") \ No newline at end of file diff --git a/vmf_source/scripts/mods/vmf/modules/settings.lua b/vmf_source/scripts/mods/vmf/modules/core/settings.lua similarity index 63% rename from vmf_source/scripts/mods/vmf/modules/settings.lua rename to vmf_source/scripts/mods/vmf/modules/core/settings.lua index 5ccec0c..88957ff 100644 --- a/vmf_source/scripts/mods/vmf/modules/settings.lua +++ b/vmf_source/scripts/mods/vmf/modules/core/settings.lua @@ -2,32 +2,25 @@ This is the settings manager. * It operates settings within the mod namespace (you can define settings with the same name for different mods) * Settings location: "%AppData%\Roaming\Fatshark\Warhammer End Times Vermintide\user_settings.config" - * All settings are being saved to the settings-file only when map changes + * All settings are being saved to the settings-file when game state changes, when options menu is closed and on reload --]] - local vmf = get_mod("VMF") -local MODS_SETTINGS = {} -local THERE_ARE_UNSAVED_CHANGES = false +local _MODS_SETTINGS = Application.user_setting("mods_settings") or {} + +local _THERE_ARE_UNSAVED_CHANGES = false -- #################################################################################################################### --- ##### Private functions ############################################################################################ +-- ##### Local functions ############################################################################################## -- #################################################################################################################### -local function load_settings(mod_name) - local mod_settings = Application.user_setting(mod_name) - - mod_settings = mod_settings or {} - - MODS_SETTINGS[mod_name] = mod_settings -end - local function save_all_settings() - if THERE_ARE_UNSAVED_CHANGES then + if _THERE_ARE_UNSAVED_CHANGES then + Application.set_user_setting("mods_settings", _MODS_SETTINGS) Application.save_user_settings() - THERE_ARE_UNSAVED_CHANGES = false + _THERE_ARE_UNSAVED_CHANGES = false end end @@ -42,21 +35,20 @@ end --]] VMFMod.set = function (self, setting_name, setting_value, call_setting_changed_event) - local mod_name = self._name + local mod_name = self:get_name() - if not MODS_SETTINGS[mod_name] then - load_settings(mod_name) + if not _MODS_SETTINGS[mod_name] then + _MODS_SETTINGS[mod_name] = {} end - local mod_settings = MODS_SETTINGS[mod_name] - mod_settings[setting_name] = setting_value + local mod_settings = _MODS_SETTINGS[mod_name] - Application.set_user_setting(mod_name, mod_settings) + mod_settings[setting_name] = type(setting_value) == "table" and table.clone(setting_value) or setting_value - THERE_ARE_UNSAVED_CHANGES = true + _THERE_ARE_UNSAVED_CHANGES = true - if call_setting_changed_event and self.setting_changed then - self.setting_changed(setting_name) + if call_setting_changed_event then + vmf.mod_setting_changed_event(self, setting_name) end end @@ -64,19 +56,24 @@ end * setting_name [string]: setting name, can contain any characters lua-string can @TODO: check this --]] VMFMod.get = function (self, setting_name) - local mod_name = self._name - if not MODS_SETTINGS[mod_name] then - load_settings(mod_name) + local mod_name = self:get_name() + + local mod_settings = _MODS_SETTINGS[mod_name] + + local setting_value + + if mod_settings then + setting_value = mod_settings[setting_name] + else + return nil end - local mod_settings = MODS_SETTINGS[mod_name] - - return mod_settings[setting_name] + return type(setting_value) == "table" and table.clone(setting_value) or setting_value end -- #################################################################################################################### --- ##### Event functions ############################################################################################## +-- ##### VMF internal functions and variables ######################################################################### -- #################################################################################################################### vmf.save_unsaved_settings_to_file = function() diff --git a/vmf_source/scripts/mods/vmf/modules/core/toggling.lua b/vmf_source/scripts/mods/vmf/modules/core/toggling.lua new file mode 100644 index 0000000..45eb86b --- /dev/null +++ b/vmf_source/scripts/mods/vmf/modules/core/toggling.lua @@ -0,0 +1,78 @@ +local vmf = get_mod("VMF") + +local _DISABLED_MODS_LIST = vmf:get("disabled_mods_list") or {} + +-- #################################################################################################################### +-- ##### Local functions ############################################################################################## +-- #################################################################################################################### + +local function change_mod_state(mod, enable, skip_saving) + + if enable then + + _DISABLED_MODS_LIST[mod:get_name()] = nil + + vmf.mod_enabled_event(mod) + else + + _DISABLED_MODS_LIST[mod:get_name()] = true + + vmf.mod_disabled_event(mod) + end + + if skip_saving then + return + end + + vmf:set("disabled_mods_list", _DISABLED_MODS_LIST) +end + +-- #################################################################################################################### +-- ##### VMFMod ####################################################################################################### +-- #################################################################################################################### + +VMFMod.is_enabled = function (self) + + return not _DISABLED_MODS_LIST[self:get_name()] +end + +VMFMod.disable = function (self) + + if not _DISABLED_MODS_LIST[self:get_name()] then + + change_mod_state(self, false) + end +end + +VMFMod.enable = function (self) + + if _DISABLED_MODS_LIST[self:get_name()] then + + change_mod_state(self, true) + end +end + +VMFMod.initialized = function (self) + + if _DISABLED_MODS_LIST[self:get_name()] then + + change_mod_state(self, false, true) + end +end + +-- #################################################################################################################### +-- ##### VMF internal functions and variables ######################################################################### +-- #################################################################################################################### + +vmf.disabled_mods_list = _DISABLED_MODS_LIST + +vmf.mod_state_changed = function (mod_name, is_enabled) + + local mod = get_mod(mod_name) + + if is_enabled then + mod:enable() + else + mod:disable() + end +end \ No newline at end of file diff --git a/vmf_source/scripts/mods/vmf/modules/debug/dev_console.lua b/vmf_source/scripts/mods/vmf/modules/debug/dev_console.lua new file mode 100644 index 0000000..3e36c97 --- /dev/null +++ b/vmf_source/scripts/mods/vmf/modules/debug/dev_console.lua @@ -0,0 +1,63 @@ +local vmf = get_mod("VMF") + +DEV_CONSOLE_ENABLED = DEV_CONSOLE_ENABLED or false +PRINT_ORIGINAL_FUNCTION = PRINT_ORIGINAL_FUNCTION or print + +-- #################################################################################################################### +-- ##### Local functions ############################################################################################## +-- #################################################################################################################### + +local function open_dev_console() + + if not DEV_CONSOLE_ENABLED then + + local print_hook_function = function(func, ...) + if DEV_CONSOLE_ENABLED then + CommandWindow.print(...) + func(...) + else + func(...) + end + end + + print = function(...) + print_hook_function(PRINT_ORIGINAL_FUNCTION, ...) + end + + CommandWindow.open("Developer console") + DEV_CONSOLE_ENABLED = true + end +end + +local function close_dev_console() + + if DEV_CONSOLE_ENABLED then + + print = PRINT_ORIGINAL_FUNCTION + + CommandWindow.close() + DEV_CONSOLE_ENABLED = false + end +end + +-- #################################################################################################################### +-- ##### VMF internal functions and variables ######################################################################### +-- #################################################################################################################### + +vmf.toggle_developer_console = function (open_console) + + if open_console then + open_dev_console() + else + close_dev_console() + end +end + +-- #################################################################################################################### +-- ##### Script ####################################################################################################### +-- #################################################################################################################### + +if vmf:get("developer_mode") and vmf:get("show_developer_console") then + open_dev_console() +end + diff --git a/vmf_source/scripts/mods/vmf/modules/debug.lua b/vmf_source/scripts/mods/vmf/modules/debug/table_dump.lua similarity index 87% rename from vmf_source/scripts/mods/vmf/modules/debug.lua rename to vmf_source/scripts/mods/vmf/modules/debug/table_dump.lua index de45a81..4d357bc 100644 --- a/vmf_source/scripts/mods/vmf/modules/debug.lua +++ b/vmf_source/scripts/mods/vmf/modules/debug/table_dump.lua @@ -1,4 +1,4 @@ -local vmf = get_mod("VMF") +local vmf = get_mod("VMF") -- @TODO: remove it? local function table_dump(key, value, depth, max_depth) @@ -39,29 +39,47 @@ local function table_dump(key, value, depth, max_depth) end end -VMFMod.dump = function (self, t, tag, max_depth) +VMFMod.dump = function (self, dumped_object, dumped_object_name, max_depth) - if tag then - print(string.format("<%s>", tag)) + if not dumped_object or not max_depth then + self:error("(dump_to_file): not all arguments are specified.") + return + end + + local object_type = type(dumped_object) + + if object_type ~= "table" then + local error_message = "(dump): \"object_name\" is not a table. It's " .. object_type + + if object_type ~= "nil" then + error_message = error_message .. " (" .. tostring(dumped_object) .. ")" + end + + self:error(error_message) + return + end + + if dumped_object_name then + print(string.format("<%s>", dumped_object_name)) end if not max_depth then - self:echo("ERROR(dump): maximum depth is not specified", true) + self:error("(dump): maximum depth is not specified") return end local success, error_message = pcall(function() - for key, value in pairs(t) do + for key, value in pairs(dumped_object) do table_dump(key, value, 0, max_depth) end end) if not success then - self:echo("ERROR(dump): " .. tostring(error_message), true) + self:error("(dump): %s", tostring(error_message)) end - if tag then - print(string.format("", tag)) + if dumped_object_name then + print(string.format("", dumped_object_name)) end end @@ -308,26 +326,26 @@ end VMFMod.dump_to_file = function (self, dumped_object, object_name, max_depth) if not dumped_object or not object_name or not max_depth then - self:echo("ERROR(dump_to_file): not all arguments are specified.", true) + self:error("(dump_to_file): not all arguments are specified.") return end local object_type = type(dumped_object) if object_type ~= "table" then - local error_message = "ERROR(dump_to_file): \"object_name\" is not a table. It's " .. object_type + local error_message = "(dump_to_file): \"object_name\" is not a table. It's " .. object_type if object_type ~= "nil" then error_message = error_message .. " (" .. tostring(dumped_object) .. ")" end - self:echo(error_message, true) + self:error(error_message) return end local success, error_message = pcall(function() table_dump_to_file(dumped_object, object_name, max_depth) end) if not success then - self:echo("ERROR(dump_to_file): " .. tostring(error_message), true) + self:error("(dump_to_file): %s", tostring(error_message)) end end diff --git a/vmf_source/scripts/mods/vmf/modules/dev_console.lua b/vmf_source/scripts/mods/vmf/modules/dev_console.lua deleted file mode 100644 index ae00550..0000000 --- a/vmf_source/scripts/mods/vmf/modules/dev_console.lua +++ /dev/null @@ -1,22 +0,0 @@ -DEV_CONSOLE_ENABLED = DEV_CONSOLE_ENABLED or false - -if DEV_CONSOLE_ENABLED == false then - - local print_original_function = print - - local print_hook_function = function(func, ...) - if DEV_CONSOLE_ENABLED then - CommandWindow.print(...) - func(...) - else - func(...) - end - end - - print = function(...) - print_hook_function(print_original_function, ...) - end - - CommandWindow.open("Developer console") - DEV_CONSOLE_ENABLED = true -end \ No newline at end of file diff --git a/vmf_source/scripts/mods/vmf/modules/gui.lua b/vmf_source/scripts/mods/vmf/modules/gui/custom_menus.lua similarity index 51% rename from vmf_source/scripts/mods/vmf/modules/gui.lua rename to vmf_source/scripts/mods/vmf/modules/gui/custom_menus.lua index 8014908..d5ae537 100644 --- a/vmf_source/scripts/mods/vmf/modules/gui.lua +++ b/vmf_source/scripts/mods/vmf/modules/gui/custom_menus.lua @@ -1,116 +1,5 @@ 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 @@ -119,10 +8,13 @@ local opening_keybind_is_pressed = true local views_settings = {} +-- #################################################################################################################### +-- ##### VMFMod ####################################################################################################### +-- #################################################################################################################### VMFMod.register_new_view = function (self, new_view_data) - new_view_data.view_settings.mod_name = self._name + new_view_data.view_settings.mod_name = self:get_name() views_settings[new_view_data.view_name] = new_view_data.view_settings @@ -154,9 +46,9 @@ VMFMod.register_new_view = function (self, new_view_data) 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 + --if new_view_name ~= "vmf_options_view" then ingame_ui.views[new_view_name] = new_view_init_function(ingame_ui.ingame_ui_context) - end + --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 @@ -167,6 +59,9 @@ VMFMod.register_new_view = function (self, new_view_data) end end +-- #################################################################################################################### +-- ##### Hooks ######################################################################################################## +-- #################################################################################################################### vmf:hook("IngameUI.setup_views", function(func, self, ingame_ui_context) func(self, ingame_ui_context) @@ -193,18 +88,21 @@ vmf:hook("IngameUI.setup_views", function(func, self, ingame_ui_context) 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 internal functions and variables ######################################################################### +-- #################################################################################################################### vmf.check_custom_menus_close_keybinds = function() if ingame_ui then @@ -257,25 +155,27 @@ vmf.check_custom_menus_close_keybinds = function() 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 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 end +-- #################################################################################################################### +-- ##### Script ####################################################################################################### +-- #################################################################################################################### -- if reloading mods if not ingame_ui then @@ -283,26 +183,4 @@ if not ingame_ui then 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) \ No newline at end of file +end \ No newline at end of file diff --git a/vmf_source/scripts/mods/vmf/modules/gui/custom_textures.lua b/vmf_source/scripts/mods/vmf/modules/gui/custom_textures.lua new file mode 100644 index 0000000..a964b97 --- /dev/null +++ b/vmf_source/scripts/mods/vmf/modules/gui/custom_textures.lua @@ -0,0 +1,90 @@ +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) \ No newline at end of file diff --git a/vmf_source/scripts/mods/vmf/modules/gui/ui_scaling.lua b/vmf_source/scripts/mods/vmf/modules/gui/ui_scaling.lua new file mode 100644 index 0000000..f2dcd39 --- /dev/null +++ b/vmf_source/scripts/mods/vmf/modules/gui/ui_scaling.lua @@ -0,0 +1,28 @@ +local vmf = get_mod("VMF") + +-- If enabled, scale UI for resolutions greater than 1080p when necessary. Reports to a global when active, so that existing scaling can be disabled. +local ui_resolution = UIResolution +local ui_resolution_width_fragments = UIResolutionWidthFragments +local ui_resolution_height_fragments = UIResolutionHeightFragments +local math_min = math.min +local raw_set = rawset + +vmf:hook("UIResolutionScale", function (func, ...) + + local w, h = ui_resolution() + + if (w > ui_resolution_width_fragments() and h > ui_resolution_height_fragments() and vmf:get("ui_scaling")) then + + local max_scaling_factor = 4 + + local width_scale = math_min(w / ui_resolution_width_fragments(), max_scaling_factor) -- Changed to allow scaling up to quadruple the original max scale (1 -> 4) + local height_scale = math_min(h / ui_resolution_height_fragments(), max_scaling_factor) -- Changed to allow scaling up to quadruple the original max scale (1 -> 4) + + raw_set(_G, "vmf_hd_ui_scaling_enabled", true) + return math_min(width_scale, height_scale) + else + + raw_set(_G, "vmf_hd_ui_scaling_enabled", false) + return func(...) + end +end) \ No newline at end of file diff --git a/vmf_source/scripts/mods/vmf/modules/mods.lua b/vmf_source/scripts/mods/vmf/modules/mods.lua index 8809f50..58dc3d8 100644 --- a/vmf_source/scripts/mods/vmf/modules/mods.lua +++ b/vmf_source/scripts/mods/vmf/modules/mods.lua @@ -1,29 +1,34 @@ --- @TODO: on_game_state_changed, show messages in the chat even if they were sent when the chat wasn't initialized local vmf = nil -local MODS = {} -local MODS_UNLOADING_ORDER = {} +local _MODS = {} +local _MODS_UNLOADING_ORDER = {} -- #################################################################################################################### -- ##### Public functions ############################################################################################# -- #################################################################################################################### function new_mod(mod_name) - if MODS[mod_name] then - vmf:echo("ERROR: you can't create mod \"" .. mod_name .. "\" because it already exists") + + if type(mod_name) ~= "string" then + vmf:error("(new_mod): the mod name should be the string, not '%s'", type(mod_name)) -- @EARLY_CALL: return nil end - table.insert(MODS_UNLOADING_ORDER, 1, mod_name) + if _MODS[mod_name] then + vmf:error("(new_mod): you can't use name \"%s\" for your mod, because the mod with the same name already exists", mod_name) -- @EARLY_CALL: + return nil + end + + table.insert(_MODS_UNLOADING_ORDER, 1, mod_name) local mod = VMFMod:new(mod_name) - MODS[mod_name] = mod + _MODS[mod_name] = mod return mod end function get_mod(mod_name) - return MODS[mod_name] + return _MODS[mod_name] end -- #################################################################################################################### @@ -32,88 +37,23 @@ end VMFMod = class(VMFMod) - VMFMod.init = function (self, mod_name) self._name = mod_name end - -VMFMod.echo = function (self, message, show_mod_name) - - message = tostring(message) - - print("[ECHO][" .. self._name .. "] " .. message) - - if show_mod_name then - message = "[" .. self._name .. "] " .. message - end - - if Managers.chat and Managers.chat:has_channel(1) then - Managers.chat:add_local_system_message(1, message, true) - else - table.insert(vmf.unsent_chat_messages, message) - end +VMFMod.get_name = function (self) + return self._name end - -VMFMod.pcall = function (self, ...) - local status, value = pcall(...) - - if not status then - self:echo("ERROR(pcall): " .. tostring(value), true) - end - - return status, value -end - - -VMFMod.dofile = function (self, script_path) - - local status, value = pcall(dofile, script_path) - - if not status then - self:echo("ERROR(loadfile): " .. value.error, true) - - print("\nTRACEBACK:\n\n" .. value.traceback .. "\nLOCALS:\n\n" .. value.locals) - end - - return value -end -- #################################################################################################################### -- ##### VMF Initialization ########################################################################################### -- #################################################################################################################### vmf = new_mod("VMF") -vmf.unsent_chat_messages = {} - -- #################################################################################################################### --- ##### Event functions ############################################################################################## +-- ##### VMF internal functions and variables ######################################################################### -- #################################################################################################################### --- call 'unload' for every mod which definded it -vmf.mods_unload = function() - for _, mod_name in pairs(MODS_UNLOADING_ORDER) do --@TODO: maybe ipairs? - if MODS[mod_name].unload then - MODS[mod_name].unload() - end - end -end - --- call 'update' for every mod which definded it -vmf.mods_update = function(dt) - for _, mod in pairs(MODS) do --@TODO: maybe ipairs? - if mod.update then - mod.update(dt) - end - end -end - --- call 'game_state_changed' for every mod which definded it -vmf.mods_game_state_changed = function(status, state) - for _, mod in pairs(MODS) do --@TODO: maybe ipairs? - if mod.game_state_changed then - mod.game_state_changed(status, state) - end - end -end \ No newline at end of file +vmf.mods = _MODS +vmf.mods_unloading_order = _MODS_UNLOADING_ORDER \ No newline at end of file diff --git a/vmf_source/scripts/mods/vmf/modules/vmf_options_view.lua b/vmf_source/scripts/mods/vmf/modules/options_menu/vmf_options_view.lua similarity index 93% rename from vmf_source/scripts/mods/vmf/modules/vmf_options_view.lua rename to vmf_source/scripts/mods/vmf/modules/options_menu/vmf_options_view.lua index 8e71f7f..a0c8c40 100644 --- a/vmf_source/scripts/mods/vmf/modules/vmf_options_view.lua +++ b/vmf_source/scripts/mods/vmf/modules/options_menu/vmf_options_view.lua @@ -8,22 +8,16 @@ * No external config files. Everything should be stored via mod:set - @TODO: clone in setting menu - @TODO: migrate all settings to 1 table - @TODO: move suspending list to vmf_options_menu - - Not triggering hotkeys on suspension. As well as custom event. And I'll probably do something about mod:initialized(), when I'll get to it + @TODO: [BUG] checkbox is checked at first tick after showing, since local_offset function is called after rect drawing + @TODO: [BUG] searchbar's insput will stop working after using russian character ]] local vmf = get_mod("VMF") ---inject_material("materials/header_background", "header_background", "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/header_fav_icon", "header_fav_icon", "ingame_ui") -inject_material("materials/header_fav_icon_lit", "header_fav_icon_lit", "ingame_ui") -inject_material("materials/header_fav_arrow", "header_fav_arrow", "ingame_ui") -inject_material("materials/search_bar_icon", "search_bar_icon", "ingame_ui") +inject_material("materials/vmf/header_fav_icon", "header_fav_icon", "ingame_ui") +inject_material("materials/vmf/header_fav_icon_lit", "header_fav_icon_lit", "ingame_ui") +inject_material("materials/vmf/header_fav_arrow", "header_fav_arrow", "ingame_ui") +inject_material("materials/vmf/search_bar_icon", "search_bar_icon", "ingame_ui") -- #################################################################################################################### @@ -562,12 +556,12 @@ local function create_header_widget(widget_definition, scenegraph_id) content.callback_hide_sub_widgets(content) end - local mod_name = content.mod_name - local is_mod_suspended = content.is_checkbox_checked + local mod_name = content.mod_name + local is_mod_enabled = not content.is_checkbox_checked - content.is_checkbox_checked = not content.is_checkbox_checked + content.is_checkbox_checked = is_mod_enabled - content.callback_mod_suspend_state_changed(mod_name, is_mod_suspended) + content.callback_mod_state_changed(mod_name, is_mod_enabled) end end @@ -1344,7 +1338,7 @@ local function create_dropdown_widget(widget_definition, scenegraph_id, scenegra pass_type = "texture", style_id = "background", - texture_id = "background_texture", + texture_id = "rect_masked_texture", content_check_function = function (content) return content.is_widget_collapsed @@ -1353,7 +1347,7 @@ local function create_dropdown_widget(widget_definition, scenegraph_id, scenegra { pass_type = "texture", - style_id = "highlight_texture", + style_id = "highlight_texture", texture_id = "highlight_texture", content_check_function = function (content) return content.highlight_hotspot.is_hover and content.callback_is_cursor_inside_settings_list() @@ -1363,13 +1357,13 @@ local function create_dropdown_widget(widget_definition, scenegraph_id, scenegra pass_type = "text", style_id = "text", - text_id = "text" + text_id = "text" }, { pass_type = "text", style_id = "current_option_text", - text_id = "current_option_text" + text_id = "current_option_text" }, { pass_type = "texture", @@ -1405,7 +1399,7 @@ local function create_dropdown_widget(widget_definition, scenegraph_id, scenegra { pass_type = "hotspot", - style_id = "dropdown_hotspot", + style_id = "dropdown_hotspot", content_id = "dropdown_hotspot" }, -- PROCESSING @@ -2371,7 +2365,9 @@ VMFOptionsView = class(VMFOptionsView) VMFOptionsView.init = function (self, ingame_ui_context) self.current_setting_list_offset_y = 0 - self.scroll_step = 40 + + self.default_scroll_step = 40 + self.scroll_step = self.default_scroll_step / 100 * (vmf:get("vmf_options_scrolling_speed") or 100) self.is_setting_changes_applied_immidiately = true @@ -2399,9 +2395,6 @@ VMFOptionsView.init = function (self, ingame_ui_context) input_manager:map_device_to_service("changing_setting", "gamepad") self.input_manager = input_manager - - - -- wwise_world is used for making sounds (for opening menu, closing menu, etc.) local world = ingame_ui_context.world_manager:world("music_world") self.wwise_world = Managers.world:wwise_world(world) @@ -2544,7 +2537,7 @@ VMFOptionsView.initialize_header_widget = function (self, definition, scenegraph content.callback_favorite = callback(self, "callback_favorite") content.callback_move_favorite = callback(self, "callback_move_favorite") - content.callback_mod_suspend_state_changed = callback(self, "callback_mod_suspend_state_changed") + content.callback_mod_state_changed = callback(self, "callback_mod_state_changed") content.callback_hide_sub_widgets = callback(self, "callback_hide_sub_widgets") content.callback_fit_tooltip_to_the_screen = callback(self, "callback_fit_tooltip_to_the_screen") content.callback_is_cursor_inside_settings_list = callback(self, "callback_is_cursor_inside_settings_list") @@ -2645,33 +2638,9 @@ VMFOptionsView.callback_setting_changed = function (self, mod_name, setting_name end -VMFOptionsView.callback_mod_suspend_state_changed = function (self, mod_name, is_suspended) +VMFOptionsView.callback_mod_state_changed = function (self, mod_name, is_mod_enabled) - local mod_suspend_state_list = vmf:get("mod_suspend_state_list") - - if is_suspended then - mod_suspend_state_list[mod_name] = true - else - mod_suspend_state_list[mod_name] = nil - end - - vmf:set("mod_suspend_state_list", mod_suspend_state_list) - - local mod = get_mod(mod_name) - - if is_suspended then - if mod.suspended then - mod.suspended() - else - mod:echo("ERROR: suspending from options menu is specified, but function 'mod.suspended()' is not defined", true) - end - else - if mod.unsuspended then - mod.unsuspended() - else - mod:echo("ERROR: suspending from options menu is specified, but function 'mod.unsuspended()' is not defined", true) - end - end + vmf.mod_state_changed(mod_name, is_mod_enabled) WwiseWorld.trigger_event(self.wwise_world, "Play_hud_select") @@ -3327,7 +3296,7 @@ VMFOptionsView.callback_draw_numeric_menu = function (self, widget_content) widget_content.wrong_mouse_on_release = nil end ---vmf:echo("whatever") + -- #################################################################################################################### -- ##### MISCELLANEOUS: SETTINGS LIST WIDGETS ######################################################################### -- #################################################################################################################### @@ -3452,9 +3421,7 @@ VMFOptionsView.update_picked_option_for_settings_list_widgets = function (self) elseif widget_type == "header" then - loaded_setting_value = vmf:get("mod_suspend_state_list") - - widget_content.is_checkbox_checked = not loaded_setting_value[widget_content.mod_name] + widget_content.is_checkbox_checked = not vmf.disabled_mods_list[widget_content.mod_name] elseif widget_type == "keybind" then @@ -3516,7 +3483,7 @@ VMFOptionsView.update_settings_list_widgets_visibility = function (self, mod_nam if widget.content.show_widget_condition then widget.content.is_widget_visible = widget.content.show_widget_condition[parent_widget.content.current_option_number] and parent_widget.content.is_widget_visible and not parent_widget.content.is_widget_collapsed else - get_mod(widget.content.mod_name):echo("ERROR: the dropdown widget in the options menu has sub_widgets, but some of its sub_widgets doesn't have 'show_widget_condition' (" .. widget.content.setting_name .. ")" , true) + get_mod(widget.content.mod_name):error("(vmf_options_view): the dropdown widget in the options menu has sub_widgets, but some of its sub_widgets doesn't have 'show_widget_condition' (%s)" , widget.content.setting_name) end -- if 'group' else @@ -3832,26 +3799,11 @@ VMFOptionsView.on_enter = function (self) self:readjust_visible_settings_list_widgets_position() end + VMFOptionsView.on_exit = function (self) WwiseWorld.trigger_event(self.wwise_world, "Play_hud_button_close") vmf.save_unsaved_settings_to_file() - - self.exiting = nil -end - - --- IngameUI.handle_menu_hotkeys --- Will see if I need it when I'll work on keybinds and gui module. -VMFOptionsView.exit = function (self, return_to_game) - - vmf:echo("exit!") - - local exit_transition = (return_to_game and "exit_menu") or "ingame_menu" - - self.ingame_ui:transition_with_fade(exit_transition) - - self.exiting = true end @@ -3910,7 +3862,7 @@ VMFMod.create_options = function (self, widgets_definition, is_mod_toggable, rea local options_menu_collapsed_widgets = vmf:get("options_menu_collapsed_widgets") local mod_collapsed_widgets = nil if options_menu_collapsed_widgets then - mod_collapsed_widgets = options_menu_collapsed_widgets[self._name] + mod_collapsed_widgets = options_menu_collapsed_widgets[self:get_name()] end -- defining header widget @@ -3921,19 +3873,19 @@ VMFMod.create_options = function (self, widgets_definition, is_mod_toggable, rea new_widget_definition.widget_type = "header" new_widget_definition.widget_index = new_widget_index - new_widget_definition.mod_name = self._name - new_widget_definition.readable_mod_name = readable_mod_name or self._name + new_widget_definition.mod_name = self:get_name() + new_widget_definition.readable_mod_name = readable_mod_name or self:get_name() new_widget_definition.tooltip = mod_description new_widget_definition.default = true new_widget_definition.is_mod_toggable = is_mod_toggable if mod_collapsed_widgets then - new_widget_definition.is_widget_collapsed = mod_collapsed_widgets[self._name] + new_widget_definition.is_widget_collapsed = mod_collapsed_widgets[self:get_name()] end if options_menu_favorite_mods then for _, current_mod_name in pairs(options_menu_favorite_mods) do - if current_mod_name == self._name then + if current_mod_name == self:get_name() then new_widget_definition.is_favorited = true break end @@ -3968,7 +3920,7 @@ VMFMod.create_options = function (self, widgets_definition, is_mod_toggable, rea new_widget_definition.widget_type = current_widget.widget_type -- all new_widget_definition.widget_index = new_widget_index -- all [gen] new_widget_definition.widget_level = level -- all [gen] - new_widget_definition.mod_name = self._name -- all [gen] + new_widget_definition.mod_name = self:get_name() -- all [gen] new_widget_definition.setting_name = current_widget.setting_name -- all new_widget_definition.text = current_widget.text -- all new_widget_definition.tooltip = current_widget.tooltip -- all [optional] @@ -4052,7 +4004,7 @@ VMFMod.create_options = function (self, widgets_definition, is_mod_toggable, rea end if new_widget_index == 257 then - vmf:echo("The limit of 256 options widgets was reached. You can't add any more widgets.") + self:error("(vmf_options_view) The limit of 256 options widgets was reached. You can't add any more widgets.") end end @@ -4060,12 +4012,6 @@ VMFMod.create_options = function (self, widgets_definition, is_mod_toggable, rea end -VMFMod.is_suspended = function (self) - - local mod_suspend_state_list = vmf:get("mod_suspend_state_list") - - return mod_suspend_state_list[self._name] -end @@ -4100,9 +4046,7 @@ end -if type(vmf:get("mod_suspend_state_list")) ~= "table" then - vmf:set("mod_suspend_state_list", {}) -end + if type(vmf:get("options_menu_favorite_mods")) ~= "table" then vmf:set("options_menu_favorite_mods", {}) @@ -4116,49 +4060,9 @@ end --- If enabled, scale UI for resolutions greater than 1080p when necessary. Reports to a global when active, so that existing scaling can be disabled. -local ui_resolution = UIResolution -local ui_resolution_width_fragments = UIResolutionWidthFragments -local ui_resolution_height_fragments = UIResolutionHeightFragments -local math_min = math.min -local raw_set = rawset -vmf:hook("UIResolutionScale", function (func, ...) - local w, h = ui_resolution() - if (w > ui_resolution_width_fragments() and h > ui_resolution_height_fragments() and vmf:get("auto_hd_ui_scaling")) then - local max_scaling_factor = 4 - local width_scale = math_min(w / ui_resolution_width_fragments(), max_scaling_factor) -- Changed to allow scaling up to quadruple the original max scale (1 -> 4) - local height_scale = math_min(h / ui_resolution_height_fragments(), max_scaling_factor) -- Changed to allow scaling up to quadruple the original max scale (1 -> 4) - raw_set(_G, "vmf_hd_ui_scaling_enabled", true) - return math_min(width_scale, height_scale) - else - raw_set(_G, "vmf_hd_ui_scaling_enabled", false) - return func(...) - end -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" - }, - { - ["setting_name"] = "auto_hd_ui_scaling", - ["widget_type"] = "checkbox", - ["text"] = "Automatic HD UI Scaling", - ["tooltip"] = "Automatic HD UI Scaling" .. "\n\n" .. - "Automatically scale UI when resolution exceeds 1080p.", - ["default_value"] = true - } -} - -vmf:create_options(options_widgets, false, "Vermintide Mod Framework", ":D") @@ -4210,29 +4114,39 @@ local view_data = { } } -vmf:register_new_view(view_data) - - - - - - - - - - - - - +-- disables/enables mods options buttons in the +local function change_mods_options_button_state(state) + + local ingame_menu_buttons_exist, ingame_menu_buttons = pcall(function () return Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui.ingame_menu.active_button_data end) + if ingame_menu_buttons_exist and type(ingame_menu_buttons) == "table" then + + for _, button_info in ipairs(ingame_menu_buttons) do + + if button_info.transition == "vmf_options_view" then + + button_info.widget.content.disabled = state == "disable" + button_info.widget.content.button_hotspot.disabled = state == "disable" + end + end + end +end +vmf.initialize_vmf_options_view = function () + vmf:register_new_view(view_data) + change_mods_options_button_state("enable") +end +vmf.disable_mods_options_button = function () + change_mods_options_button_state("disable") +end +-- create mods options menu button in Esc-menu vmf:hook("IngameView.setup_button_layout", function (func, self, layout_data) local mods_options_button = { - display_name = "Mods Options", + display_name = vmf:localize("mods_options"), transition = "vmf_options_view", fade = false } @@ -4257,6 +4171,10 @@ vmf:hook("IngameView.setup_button_layout", function (func, self, layout_data) button_info.widget.style.text_click.localize = false button_info.widget.style.text_hover.localize = false button_info.widget.style.text_selected.localize = false + + if not self.ingame_ui.views["vmf_options_view"] then + change_mods_options_button_state("disable") + end end end end) @@ -4269,149 +4187,111 @@ end) - - - - local ingame_ui_exists, ingame_ui = pcall(function () return Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui end) if ingame_ui_exists then - ingame_ui.handle_transition(ingame_ui, "leave_group") + --ingame_ui.handle_transition(ingame_ui, "leave_group") -vmf:pcall(function() + -- temporary fix: - print("AYYYYY" .. tostring(ingame_ui)) - --vmf:dump(ingame_ui.views, "whatever", 1) + local specific_atlas = Managers.state.game_mode._game_mode_key == "inn" and "materials/ui/ui_1080p_ingame_inn" or "materials/ui/ui_1080p_ingame" -end) - --------------------------------------------------- - - ---vmf:echo("I hope it will work!") ---[[ -local gui = World.create_screen_gui(ingame_ui.ui_renderer.world, "immediate", -"material", -"materials/ui/end_screen_banners/end_screen_banners", -"material", -"materials/ui/ui_1080p_ingame_common", -"material", -"materials/ui/ui_1080p_ingame_inn", -"material", -"materials/ui/ui_1080p_level_images", -"material", -"materials/ui/ui_1080p_chat", -"material", -"materials/fonts/gw_fonts", -"material", -"materials/header_background", -"material", -"materials/header_background_lit", -"material", -"materials/common_widgets_background_lit", -"material", -"materials/header_fav_icon", -"material", -"materials/header_fav_icon_lit", -"material", -"materials/header_fav_arrow", -"material", -"materials/search_bar_icon") - -local gui_retained = World.create_screen_gui(ingame_ui.ui_renderer.world, + local gui = World.create_screen_gui(ingame_ui.ui_renderer.world, "immediate", "material", -"materials/ui/end_screen_banners/end_screen_banners", -"material", -"materials/ui/ui_1080p_ingame_common", -"material", -"materials/ui/ui_1080p_ingame_inn", -"material", -"materials/ui/ui_1080p_level_images", -"material", -"materials/ui/ui_1080p_chat", -"material", -"materials/fonts/gw_fonts", -"material", -"materials/header_background", -"material", -"materials/header_background_lit", -"material", -"materials/common_widgets_background_lit", -"material", -"materials/header_fav_icon", -"material", -"materials/header_fav_icon_lit", -"material", -"materials/header_fav_arrow", -"material", -"materials/search_bar_icon") - - -World.destroy_gui(ingame_ui.ui_renderer.world, ingame_ui.ui_renderer.gui) - -ingame_ui.ui_renderer.gui = gui -ingame_ui.ui_renderer.gui_retained = gui_retained - - - -gui = World.create_screen_gui(ingame_ui.ui_top_renderer.world, "immediate", -"material", -"materials/ui/end_screen_banners/end_screen_banners", -"material", -"materials/ui/ui_1080p_ingame_common", -"material", -"materials/ui/ui_1080p_ingame_inn", -"material", -"materials/ui/ui_1080p_level_images", -"material", -"materials/ui/ui_1080p_chat", -"material", -"materials/fonts/gw_fonts", -"material", -"materials/header_background", -"material", -"materials/header_background_lit", -"material", -"materials/common_widgets_background_lit", -"material", -"materials/header_fav_icon", -"material", -"materials/header_fav_icon_lit", -"material", -"materials/header_fav_arrow", -"material", -"materials/search_bar_icon") - -gui_retained = World.create_screen_gui(ingame_ui.ui_top_renderer.world, + "materials/ui/end_screen_banners/end_screen_banners", "material", -"materials/ui/end_screen_banners/end_screen_banners", -"material", -"materials/ui/ui_1080p_ingame_common", -"material", -"materials/ui/ui_1080p_ingame_inn", -"material", -"materials/ui/ui_1080p_level_images", -"material", -"materials/ui/ui_1080p_chat", -"material", -"materials/fonts/gw_fonts", -"material", -"materials/header_background", -"material", -"materials/header_background_lit", -"material", -"materials/common_widgets_background_lit", -"material", -"materials/header_fav_icon", -"material", -"materials/header_fav_icon_lit", -"material", -"materials/header_fav_arrow", -"material", -"materials/search_bar_icon") + "materials/ui/ui_1080p_ingame_common", + "material", + specific_atlas, + "material", + "materials/ui/ui_1080p_level_images", + "material", + "materials/ui/ui_1080p_chat", + "material", + "materials/fonts/gw_fonts", + "material", + "materials/vmf/header_fav_icon", + "material", + "materials/vmf/header_fav_icon_lit", + "material", + "materials/vmf/header_fav_arrow", + "material", + "materials/vmf/search_bar_icon") -World.destroy_gui(ingame_ui.ui_top_renderer.world, ingame_ui.ui_top_renderer.gui) + local gui_retained = World.create_screen_gui(ingame_ui.ui_renderer.world, + "material", + "materials/ui/end_screen_banners/end_screen_banners", + "material", + "materials/ui/ui_1080p_ingame_common", + "material", + specific_atlas, + "material", + "materials/ui/ui_1080p_level_images", + "material", + "materials/ui/ui_1080p_chat", + "material", + "materials/fonts/gw_fonts", + "material", + "materials/vmf/header_fav_icon", + "material", + "materials/vmf/header_fav_icon_lit", + "material", + "materials/vmf/header_fav_arrow", + "material", + "materials/vmf/search_bar_icon") -ingame_ui.ui_top_renderer.gui = gui -ingame_ui.ui_top_renderer.gui_retained = gui_retained -]] - --------------------------------------------------- + World.destroy_gui(ingame_ui.ui_renderer.world, ingame_ui.ui_renderer.gui) + World.destroy_gui(ingame_ui.ui_renderer.world, ingame_ui.ui_renderer.gui_retained) + + ingame_ui.ui_renderer.gui = gui + ingame_ui.ui_renderer.gui_retained = gui_retained + + gui = World.create_screen_gui(ingame_ui.ui_top_renderer.world, "immediate", + "material", + "materials/ui/end_screen_banners/end_screen_banners", + "material", + "materials/ui/ui_1080p_ingame_common", + "material", + specific_atlas, + "material", + "materials/ui/ui_1080p_level_images", + "material", + "materials/ui/ui_1080p_chat", + "material", + "materials/fonts/gw_fonts", + "material", + "materials/vmf/header_fav_icon", + "material", + "materials/vmf/header_fav_icon_lit", + "material", + "materials/vmf/header_fav_arrow", + "material", + "materials/vmf/search_bar_icon") + + gui_retained = World.create_screen_gui(ingame_ui.ui_top_renderer.world, + "material", + "materials/ui/end_screen_banners/end_screen_banners", + "material", + "materials/ui/ui_1080p_ingame_common", + "material", + specific_atlas, + "material", + "materials/ui/ui_1080p_level_images", + "material", + "materials/ui/ui_1080p_chat", + "material", + "materials/fonts/gw_fonts", + "material", + "materials/vmf/header_fav_icon", + "material", + "materials/vmf/header_fav_icon_lit", + "material", + "materials/vmf/header_fav_arrow", + "material", + "materials/vmf/search_bar_icon") + + World.destroy_gui(ingame_ui.ui_top_renderer.world, ingame_ui.ui_top_renderer.gui) + World.destroy_gui(ingame_ui.ui_top_renderer.world, ingame_ui.ui_top_renderer.gui_retained) + + ingame_ui.ui_top_renderer.gui = gui + ingame_ui.ui_top_renderer.gui_retained = gui_retained end diff --git a/vmf_source/scripts/mods/vmf/modules/testing_stuff_here.lua b/vmf_source/scripts/mods/vmf/modules/testing_stuff_here.lua index 7f5561c..521d340 100644 --- a/vmf_source/scripts/mods/vmf/modules/testing_stuff_here.lua +++ b/vmf_source/scripts/mods/vmf/modules/testing_stuff_here.lua @@ -1,49 +1,4 @@ local mod = new_mod("test_mod") ---[[ - mod:hook("GenericAmmoUserExtension.update", function(func, self, unit, input, dt, context, t) - func(self, unit, input, dt, context, t) - print("333") - end) - mod:hook_disable("GenericAmmoUserExtension.update") - - mod:hook("MatchmakingManager.all_peers_ready", function(func, ...) - --if not mod:is_suspended() then - -- return true - --else - -- return func(...) - --end - mod:echo("whatever") - return true -end) - mod:disable_all_hooks() -]] - ---[[ - --mod:hook_enable("GenericAmmoUserExtension.update") - --mod:hook_disable("GenericAmmoUserExtension.update") - --mod:hook_remove("GenericAmmoUserExtension.update") - mod:hook("MatchmakingManager.update", function(func, ...) - func(...) - print("555") - end) ---]] - --mod:disable_all_hooks() - --mod:enable_all_hooks() - --mod:remove_all_hooks() - - --mod:hook_remove("GenericAmmoUserExtension.update") - --mod:hook_remove("MatchmakingManager.update") - --table.dump(HOOKED_FUNCTIONS, "HOOKED_FUNCTIONS", 3) - - - --mod.unload = function() - -- print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") - --end - - --mod:pcall(function() - -- return assert(loadstring("return bla.bla"))() - -- end) - local options_widgets = { { @@ -95,9 +50,17 @@ local options_widgets = { ["widget_type"] = "keybind", ["text"] = "Some keybind", ["tooltip"] = "Probably keybind", - ["default_value"] = {"f", "ctrl"}, + ["default_value"] = {"g", "ctrl"}, ["action"] = "whatever" }, + { + ["setting_name"] = "the_keybind2", + ["widget_type"] = "keybind", + ["text"] = "Some keybind [toggle]", + ["tooltip"] = "Probably keybind", + ["default_value"] = {"f", "ctrl"}, + ["action"] = "toggle_mod" + }, { ["setting_name"] = "game_mode2", ["widget_type"] = "dropdown", @@ -144,13 +107,17 @@ local options_widgets = { } } -mod:create_options(options_widgets, true, "Test", "Mod description") +--mod:create_options(options_widgets, true, "Test", "Mod description") -- chat_broadcast -mod.whatever = function() +mod.whatever = function () mod:echo("whatever") end +mod.game_state_changed = function () + --mod:echo("whatever" .. nil) +end + --[[ mod:hook("KeystrokeHelper.parse_strokes", function(func, text, index, mode, keystrokes) print(tostring(text) .. " " .. tostring(index) .. " " .. tostring(mode) .. " " .. tostring(keystrokes)) @@ -257,19 +224,14 @@ end) mod:echo("YAY") end]] ---[[ - local mod = new_mod("test_mod2") - mod:create_options(options_widgets, true, "Bots Improvements", "Mod description") +local mod2 = new_mod("SkipSplashScreen") - local mod = new_mod("test_mod3") - mod:create_options(options_widgets, true, "Show Healhbars", "Mod description") +mod2:hook("StateSplashScreen.on_enter", function(func, self) + self._skip_splash = true + func(self) +end) - local mod = new_mod("test_mod4") - mod:create_options(options_widgets, true, "Ammo Meter", "Mod description") - - local mod = new_mod("test_mod5") - mod:create_options(options_widgets, true, "Show Damage", "Mod description") - - local mod = new_mod("test_mod6") - mod:create_options(options_widgets, true, "Kick & Ban", "Mod description") -]] +mod2:hook("StateSplashScreen.setup_splash_screen_view", function(func, self) + func(self) + self.splash_view = nil +end) \ No newline at end of file diff --git a/vmf_source/scripts/mods/vmf/modules/vmf_options.lua b/vmf_source/scripts/mods/vmf/modules/vmf_options.lua new file mode 100644 index 0000000..6da98cc --- /dev/null +++ b/vmf_source/scripts/mods/vmf/modules/vmf_options.lua @@ -0,0 +1,199 @@ +local vmf = get_mod("VMF") + +local options_widgets = { + { + ["setting_name"] = "open_vmf_options", + ["widget_type"] = "keybind", + ["text"] = vmf:localize("open_vmf_options"), + ["tooltip"] = vmf:localize("open_vmf_options") .. "\n" .. + vmf:localize("open_vmf_options_tooltip"), + ["default_value"] = {"f4"}, + ["action"] = "open_vmf_options" + }, + { + ["setting_name"] = "vmf_options_scrolling_speed", + ["widget_type"] = "numeric", + ["text"] = vmf:localize("vmf_options_scrolling_speed"), + ["unit_text"] = "%", + ["range"] = {1, 1000}, + ["default_value"] = 100 + }, + { + ["setting_name"] = "ui_scaling", + ["widget_type"] = "checkbox", + ["text"] = vmf:localize("ui_scaling"), + ["tooltip"] = vmf:localize("ui_scaling") .. "\n" .. + vmf:localize("ui_scaling_tooltip"), + ["default_value"] = true + }, + { + ["setting_name"] = "developer_mode", + ["widget_type"] = "checkbox", + ["text"] = vmf:localize("developer_mode"), + ["tooltip"] = vmf:localize("developer_mode") .. "\n" .. + vmf:localize("developer_mode_tooltip"), + ["default_value"] = false, + ["sub_widgets"] = { + { + ["setting_name"] = "show_developer_console", + ["widget_type"] = "checkbox", + ["text"] = vmf:localize("show_developer_console"), + ["tooltip"] = vmf:localize("show_developer_console") .. "\n" .. + vmf:localize("show_developer_console_tooltip"), + ["default_value"] = false + }, +-- { +-- ["setting_name"] = "toggle_developer_console", +-- ["widget_type"] = "keybind", +-- ["text"] = "Toggle Developer Console", +-- ["default_value"] = {}, +-- ["action"] = "toggle_developer_console" +-- } + } + }, + { + ["setting_name"] = "logging_mode", + ["widget_type"] = "dropdown", + ["text"] = vmf:localize("logging_mode"), + ["options"] = { + {--[[1]] text = vmf:localize("settings_default"), value = "default"}, + {--[[2]] text = vmf:localize("settings_custom"), value = "custom"}, + }, + ["default_value"] = "default", + ["sub_widgets"] = { + { + ["show_widget_condition"] = {2}, + + ["setting_name"] = "output_mode_echo", + ["widget_type"] = "dropdown", + ["text"] = vmf:localize("output_mode_echo"), + ["options"] = { + {text = vmf:localize("output_disabled"), value = 0}, + {text = vmf:localize("output_log"), value = 1}, + {text = vmf:localize("output_chat"), value = 2}, + {text = vmf:localize("output_log_and_chat"), value = 3}, + }, + ["default_value"] = 3 + }, + { + ["show_widget_condition"] = {2}, + + ["setting_name"] = "output_mode_error", + ["widget_type"] = "dropdown", + ["text"] = vmf:localize("output_mode_error"), + ["options"] = { + {text = vmf:localize("output_disabled"), value = 0}, + {text = vmf:localize("output_log"), value = 1}, + {text = vmf:localize("output_chat"), value = 2}, + {text = vmf:localize("output_log_and_chat"), value = 3}, + }, + ["default_value"] = 3 + }, + { + ["show_widget_condition"] = {2}, + + ["setting_name"] = "output_mode_warning", + ["widget_type"] = "dropdown", + ["text"] = vmf:localize("output_mode_warning"), + ["options"] = { + {text = vmf:localize("output_disabled"), value = 0}, + {text = vmf:localize("output_log"), value = 1}, + {text = vmf:localize("output_chat"), value = 2}, + {text = vmf:localize("output_log_and_chat"), value = 3}, + }, + ["default_value"] = 3 + }, + { + ["show_widget_condition"] = {2}, + + ["setting_name"] = "output_mode_info", + ["widget_type"] = "dropdown", + ["text"] = vmf:localize("output_mode_info"), + ["options"] = { + {text = vmf:localize("output_disabled"), value = 0}, + {text = vmf:localize("output_log"), value = 1}, + {text = vmf:localize("output_chat"), value = 2}, + {text = vmf:localize("output_log_and_chat"), value = 3}, + }, + ["default_value"] = 1 + }, + { + ["show_widget_condition"] = {2}, + + ["setting_name"] = "output_mode_spew", + ["widget_type"] = "dropdown", + ["text"] = vmf:localize("output_mode_spew"), + ["options"] = { + {text = vmf:localize("output_disabled"), value = 0}, + {text = vmf:localize("output_log"), value = 1}, + {text = vmf:localize("output_chat"), value = 2}, + {text = vmf:localize("output_log_and_chat"), value = 3}, + }, + ["default_value"] = 0 + } + } + } +} +vmf:create_options(options_widgets, false, "Vermintide Mod Framework") + +vmf.setting_changed = function (setting_name) + + if setting_name == "vmf_options_scrolling_speed" then + + local ingame_ui_exists, ingame_ui = pcall(function () return Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui end) + if ingame_ui_exists then + local vmf_options_view = ingame_ui.views["vmf_options_view"] + if vmf_options_view then + vmf_options_view.scroll_step = vmf_options_view.default_scroll_step / 100 * vmf:get(setting_name) + end + end + + elseif setting_name == "developer_mode" then + + Application.set_user_setting("mod_developer_mode", vmf:get(setting_name)) + Managers.mod._developer_mode = vmf:get(setting_name) -- @TODO: update that after going to the new mod_manager version + + local show_developer_console = vmf:get(setting_name) and vmf:get("show_developer_console") + vmf.toggle_developer_console(show_developer_console) + + elseif setting_name == "show_developer_console" then + + vmf.toggle_developer_console(vmf:get(setting_name)) + + elseif setting_name == "logging_mode" then + + vmf.load_logging_settings() + + elseif setting_name == "output_mode_echo" then + + vmf.load_logging_settings() + + elseif setting_name == "output_mode_error" then + + vmf.load_logging_settings() + + elseif setting_name == "output_mode_warning" then + + vmf.load_logging_settings() + + elseif setting_name == "output_mode_info" then + + vmf.load_logging_settings() + + elseif setting_name == "output_mode_spew" then + + vmf.load_logging_settings() + end +end + +-- #################################################################################################################### +-- ##### Script ####################################################################################################### +-- #################################################################################################################### + +local mod_developer_mode = Application.user_setting("mods_settings") +local vmf_developer_mode = vmf:get("developer_mode") + +if mod_developer_mode ~= vmf_developer_mode then + Application.set_user_setting("mod_developer_mode", vmf_developer_mode) + Managers.mod._developer_mode = vmf_developer_mode -- @TODO: update that after going to the new mod_manager version +end \ No newline at end of file diff --git a/vmf_source/scripts/mods/vmf/vmf_loader.lua b/vmf_source/scripts/mods/vmf/vmf_loader.lua index 33e7724..8f46e0a 100644 --- a/vmf_source/scripts/mods/vmf/vmf_loader.lua +++ b/vmf_source/scripts/mods/vmf/vmf_loader.lua @@ -3,18 +3,23 @@ return { dofile("scripts/mods/vmf/functions/table") - dofile("scripts/mods/vmf/modules/dev_console") dofile("scripts/mods/vmf/modules/mods") - dofile("scripts/mods/vmf/modules/debug") - dofile("scripts/mods/vmf/modules/hooks") - dofile("scripts/mods/vmf/modules/chat") - dofile("scripts/mods/vmf/modules/settings") - dofile("scripts/mods/vmf/modules/keybindings") - dofile("scripts/mods/vmf/modules/gui") - dofile("scripts/mods/vmf/modules/vmf_options_view") - - --Application.set_user_setting("mod_developer_mode", true) - --Application.save_user_settings() + dofile("scripts/mods/vmf/modules/core/events") + dofile("scripts/mods/vmf/modules/core/settings") + dofile("scripts/mods/vmf/modules/core/core_functions") + dofile("scripts/mods/vmf/modules/debug/dev_console") + dofile("scripts/mods/vmf/modules/debug/table_dump") + dofile("scripts/mods/vmf/modules/core/hooks") + dofile("scripts/mods/vmf/modules/core/toggling") + dofile("scripts/mods/vmf/modules/core/keybindings") + dofile("scripts/mods/vmf/modules/core/delayed_chat_messages") + dofile("scripts/mods/vmf/modules/core/chat") + dofile("scripts/mods/vmf/modules/core/localization") + dofile("scripts/mods/vmf/modules/gui/custom_textures") + dofile("scripts/mods/vmf/modules/gui/custom_menus") + dofile("scripts/mods/vmf/modules/gui/ui_scaling") + dofile("scripts/mods/vmf/modules/options_menu/vmf_options_view") + dofile("scripts/mods/vmf/modules/vmf_options") object.vmf = get_mod("VMF") @@ -24,13 +29,14 @@ return { update = function(object, dt) - object.vmf.mods_update(dt) + object.vmf.mods_update_event(dt) 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 object.vmf.initialize_keybinds() + object.vmf.initialize_vmf_options_view() object.vmf.all_mods_were_loaded = true end @@ -43,16 +49,17 @@ return { on_reload = function(object) print("VMF:ON_RELOAD()") + object.vmf.disable_mods_options_button() object.vmf.close_opened_custom_menus() object.vmf.delete_keybinds() - object.vmf.mods_unload() + object.vmf.mods_unload_event() object.vmf.hooks_unload() object.vmf.save_unsaved_settings_to_file() end, on_game_state_changed = function(object, status, state) print("VMF:ON_GAME_STATE_CHANGED(), status: " .. tostring(status) .. ", state: " .. tostring(state)) - object.vmf.mods_game_state_changed(status, state) + object.vmf.mods_game_state_changed_event(status, state) object.vmf.save_unsaved_settings_to_file() if status == "exit" and state == "StateTitleScreen" then diff --git a/vmf_source/settings.ini b/vmf_source/settings.ini index 2353650..9b77a15 100644 --- a/vmf_source/settings.ini +++ b/vmf_source/settings.ini @@ -1 +1 @@ -boot_package = "resource_packages/vmf" \ No newline at end of file +boot_package = "resource_packages/vmf/vmf_resources" \ No newline at end of file diff --git a/vmf_source/vmf.mod b/vmf_source/vmf.mod index 7aca429..e0591a5 100644 --- a/vmf_source/vmf.mod +++ b/vmf_source/vmf.mod @@ -1,11 +1,9 @@ -print("Vermintide Mod Framework loading") - local ret = { run = function() return dofile("scripts/mods/vmf/vmf_loader") end, packages = { "resource_packages/vmf" - }, + } } return ret \ No newline at end of file