Full refactoring, adding localization module and a lot of small features

This commit is contained in:
bi 2018-02-18 23:49:02 +03:00
parent 4000deb88f
commit eb49357241
46 changed files with 1485 additions and 951 deletions

View file

@ -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
}
}

Binary file not shown.

View file

@ -1,18 +0,0 @@
common = {
input = {
filename = "gui/header_background"
}
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
}
}

View file

@ -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
}
}

View file

@ -1,6 +1,6 @@
common = { common = {
input = { input = {
filename = "gui/header_fav_arrow" filename = "gui/vmf/header_fav_arrow"
} }
output = { output = {
apply_processing = true apply_processing = true

View file

@ -1,6 +1,6 @@
common = { common = {
input = { input = {
filename = "gui/header_fav_icon" filename = "gui/vmf/header_fav_icon"
} }
output = { output = {
apply_processing = true apply_processing = true

View file

@ -1,6 +1,6 @@
common = { common = {
input = { input = {
filename = "gui/header_fav_icon_lit" filename = "gui/vmf/header_fav_icon_lit"
} }
output = { output = {
apply_processing = true apply_processing = true

View file

@ -1,6 +1,6 @@
common = { common = {
input = { input = {
filename = "gui/search_bar_icon" filename = "gui/vmf/search_bar_icon"
} }
output = { output = {
apply_processing = true apply_processing = true

View file

@ -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 = "Лог и чат",
},
}

View file

@ -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 = {
}
}

View file

@ -1,14 +0,0 @@
header_background = {
material_contexts = {
surface_material = ""
}
shader = "gui_gradient:DIFFUSE_MAP:MASKED"
textures = {
diffuse_map = "gui/header_background"
}
variables = {
}
}

View file

@ -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 = {
}
}

View file

@ -6,7 +6,7 @@ header_fav_arrow = {
shader = "gui_gradient:DIFFUSE_MAP:MASKED" shader = "gui_gradient:DIFFUSE_MAP:MASKED"
textures = { textures = {
diffuse_map = "gui/header_fav_arrow" diffuse_map = "gui/vmf/header_fav_arrow"
} }
variables = { variables = {

View file

@ -6,7 +6,7 @@ header_fav_icon = {
shader = "gui_gradient:DIFFUSE_MAP:MASKED" shader = "gui_gradient:DIFFUSE_MAP:MASKED"
textures = { textures = {
diffuse_map = "gui/header_fav_icon" diffuse_map = "gui/vmf/header_fav_icon"
} }
variables = { variables = {

View file

@ -6,7 +6,7 @@ header_fav_icon_lit = {
shader = "gui_gradient:DIFFUSE_MAP:MASKED" shader = "gui_gradient:DIFFUSE_MAP:MASKED"
textures = { textures = {
diffuse_map = "gui/header_fav_icon_lit" diffuse_map = "gui/vmf/header_fav_icon_lit"
} }
variables = { variables = {

View file

@ -6,7 +6,7 @@ search_bar_icon = {
shader = "gui_gradient:DIFFUSE_MAP" shader = "gui_gradient:DIFFUSE_MAP"
textures = { textures = {
diffuse_map = "gui/search_bar_icon" diffuse_map = "gui/vmf/search_bar_icon"
} }
variables = { variables = {

View file

@ -7,27 +7,17 @@ package = [
] ]
material = [ material = [
"materials/header_background" "materials/vmf/*"
"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"
] ]
lua = [ lua = [
"scripts/mods/vmf/functions/*" "localization/vmf"
"scripts/mods/vmf/vmf_loader" "scripts/mods/vmf/*"
"scripts/mods/vmf/modules/dev_console" "scripts/mods/vmf/functions/*"
"scripts/mods/vmf/modules/mods" "scripts/mods/vmf/modules/*"
"scripts/mods/vmf/modules/debug" "scripts/mods/vmf/modules/core/*"
"scripts/mods/vmf/modules/hooks" "scripts/mods/vmf/modules/debug/*"
"scripts/mods/vmf/modules/chat" "scripts/mods/vmf/modules/gui/*"
"scripts/mods/vmf/modules/settings" "scripts/mods/vmf/modules/options_menu/*"
"scripts/mods/vmf/modules/keybindings"
"scripts/mods/vmf/modules/gui"
"scripts/mods/vmf/modules/vmf_options_view"
"scripts/mods/vmf/modules/testing_stuff_here"
] ]

View file

@ -1,42 +1,9 @@
local vmf = get_mod("VMF") 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 #######################################################################################################
-- #################################################################################################################### -- ####################################################################################################################
VMFMod.chat_broadcast = function(self, message) VMFMod.chat_broadcast = function(self, message)
local chat = Managers.chat local chat = Managers.chat

View file

@ -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()

View file

@ -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

View file

@ -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

View file

@ -3,9 +3,19 @@ local vmf = get_mod("VMF")
HOOKED_FUNCTIONS = {} -- global, because 'loadstring' doesn't see local variables 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 function get_function_by_name(function_name)
local _, value = pcall(loadstring("return " .. function_name)) local _, value = pcall(loadstring("return " .. function_name))
@ -117,7 +127,7 @@ end
local function modify_hook(mod, hooked_function_name, action) local function modify_hook(mod, hooked_function_name, action)
if not get_function_by_name(hooked_function_name) then 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 return
end end
@ -174,13 +184,11 @@ local function modify_all_hooks(mod, action)
if #hooked_function_entry.hooks == 0 then if #hooked_function_entry.hooks == 0 then
table.insert(no_hooks_functions_indexes, 1, i) table.insert(no_hooks_functions_indexes, 1, i)
end end
end end
for _, no_hooks_function_index in ipairs(no_hooks_functions_indexes) do for _, no_hooks_function_index in ipairs(no_hooks_functions_indexes) do
table.remove(HOOKED_FUNCTIONS, no_hooks_function_index) table.remove(HOOKED_FUNCTIONS, no_hooks_function_index)
end end
end end
-- #################################################################################################################### -- ####################################################################################################################
@ -189,9 +197,13 @@ end
VMFMod.hook = function (self, hooked_function_name, hook_function) 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) 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 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 return
end end
@ -211,16 +223,31 @@ end
VMFMod.hook_remove = function (self, hooked_function_name) 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") modify_hook(self, hooked_function_name, "remove")
end end
VMFMod.hook_disable = function (self, hooked_function_name) 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") modify_hook(self, hooked_function_name, "disable")
end end
VMFMod.hook_enable = function (self, hooked_function_name) 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") modify_hook(self, hooked_function_name, "enable")
end end
@ -240,7 +267,7 @@ VMFMod.enable_all_hooks = function (self)
end end
-- #################################################################################################################### -- ####################################################################################################################
-- ##### Event functions ############################################################################################## -- ##### VMF internal functions and variables #########################################################################
-- #################################################################################################################### -- ####################################################################################################################
-- removes all hooks when VMF is about to be reloaded -- removes all hooks when VMF is about to be reloaded

View file

@ -1,5 +1,163 @@
local vmf = get_mod("VMF") 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 keyboard_buton_name = Keyboard.button_name
local mouse_buton_name = Mouse.button_name local mouse_buton_name = Mouse.button_name
@ -152,6 +310,10 @@ vmf.keys = {
vmf.readable_key_names = {} vmf.readable_key_names = {}
-- ####################################################################################################################
-- ##### Script #######################################################################################################
-- ####################################################################################################################
for _, controller_keys in pairs(vmf.keys) do for _, controller_keys in pairs(vmf.keys) do
for _, key_info in pairs(controller_keys) do for _, key_info in pairs(controller_keys) do
vmf.readable_key_names[key_info[2]] = key_info[1] 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["alt"] = "Alt"
vmf.readable_key_names["shift"] = "Shift" 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 for _, key_info in pairs(vmf.keys.keyboard) do
VMFModsKeyMap.win32[key_info[2]] = {"keyboard", key_info[3], "held"} VMFModsKeyMap.win32[key_info[2]] = {"keyboard", key_info[3], "held"}
end end
@ -183,139 +336,4 @@ end
for i = 10, 13 do for i = 10, 13 do
local key_info = vmf.keys.mouse[i] local key_info = vmf.keys.mouse[i]
VMFModsKeyMap.win32[key_info[2]] = {"mouse", key_info[3], "pressed"} 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 end

View file

@ -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")

View file

@ -2,32 +2,25 @@
This is the settings manager. This is the settings manager.
* It operates settings within the mod namespace (you can define settings with the same name for different mods) * 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" * 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 vmf = get_mod("VMF")
local MODS_SETTINGS = {} local _MODS_SETTINGS = Application.user_setting("mods_settings") or {}
local THERE_ARE_UNSAVED_CHANGES = false
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() 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() Application.save_user_settings()
THERE_ARE_UNSAVED_CHANGES = false _THERE_ARE_UNSAVED_CHANGES = false
end end
end end
@ -42,21 +35,20 @@ end
--]] --]]
VMFMod.set = function (self, setting_name, setting_value, call_setting_changed_event) 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 if not _MODS_SETTINGS[mod_name] then
load_settings(mod_name) _MODS_SETTINGS[mod_name] = {}
end end
local mod_settings = MODS_SETTINGS[mod_name] local mod_settings = _MODS_SETTINGS[mod_name]
mod_settings[setting_name] = setting_value
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 if call_setting_changed_event then
self.setting_changed(setting_name) vmf.mod_setting_changed_event(self, setting_name)
end end
end end
@ -64,19 +56,24 @@ end
* setting_name [string]: setting name, can contain any characters lua-string can @TODO: check this * setting_name [string]: setting name, can contain any characters lua-string can @TODO: check this
--]] --]]
VMFMod.get = function (self, setting_name) VMFMod.get = function (self, setting_name)
local mod_name = self._name
if not MODS_SETTINGS[mod_name] then local mod_name = self:get_name()
load_settings(mod_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 end
local mod_settings = MODS_SETTINGS[mod_name] return type(setting_value) == "table" and table.clone(setting_value) or setting_value
return mod_settings[setting_name]
end end
-- #################################################################################################################### -- ####################################################################################################################
-- ##### Event functions ############################################################################################## -- ##### VMF internal functions and variables #########################################################################
-- #################################################################################################################### -- ####################################################################################################################
vmf.save_unsaved_settings_to_file = function() vmf.save_unsaved_settings_to_file = function()

View file

@ -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

View file

@ -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

View file

@ -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) local function table_dump(key, value, depth, max_depth)
@ -39,29 +39,47 @@ local function table_dump(key, value, depth, max_depth)
end end
end end
VMFMod.dump = function (self, t, tag, max_depth) VMFMod.dump = function (self, dumped_object, dumped_object_name, max_depth)
if tag then if not dumped_object or not max_depth then
print(string.format("<%s>", tag)) 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 end
if not max_depth then if not max_depth then
self:echo("ERROR(dump): maximum depth is not specified", true) self:error("(dump): maximum depth is not specified")
return return
end end
local success, error_message = pcall(function() 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) table_dump(key, value, 0, max_depth)
end end
end) end)
if not success then if not success then
self:echo("ERROR(dump): " .. tostring(error_message), true) self:error("(dump): %s", tostring(error_message))
end end
if tag then if dumped_object_name then
print(string.format("</%s>", tag)) print(string.format("</%s>", dumped_object_name))
end end
end end
@ -308,26 +326,26 @@ end
VMFMod.dump_to_file = function (self, dumped_object, object_name, max_depth) 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 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 return
end end
local object_type = type(dumped_object) local object_type = type(dumped_object)
if object_type ~= "table" then 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 if object_type ~= "nil" then
error_message = error_message .. " (" .. tostring(dumped_object) .. ")" error_message = error_message .. " (" .. tostring(dumped_object) .. ")"
end end
self:echo(error_message, true) self:error(error_message)
return return
end end
local success, error_message = pcall(function() table_dump_to_file(dumped_object, object_name, max_depth) end) local success, error_message = pcall(function() table_dump_to_file(dumped_object, object_name, max_depth) end)
if not success then 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
end end

View file

@ -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

View file

@ -1,116 +1,5 @@
local vmf = get_mod("VMF") 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 local ingame_ui = nil
-- needed to protect opened menus from being closed right away and vice versa -- 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 = {} local views_settings = {}
-- ####################################################################################################################
-- ##### VMFMod #######################################################################################################
-- ####################################################################################################################
VMFMod.register_new_view = function (self, new_view_data) VMFMod.register_new_view = function (self, new_view_data)
new_view_data.view_settings.mod_name = self._name new_view_data.view_settings.mod_name = self:get_name()
views_settings[new_view_data.view_name] = new_view_data.view_settings views_settings[new_view_data.view_name] = new_view_data.view_settings
@ -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_name = new_view_data.view_name
local new_view_init_function = new_view_data.view_settings.init_view_function local new_view_init_function = new_view_data.view_settings.init_view_function
if 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) ingame_ui.views[new_view_name] = new_view_init_function(ingame_ui.ingame_ui_context)
end --end
-- set 'ingame_ui.blocked_transitions' -- set 'ingame_ui.blocked_transitions'
local blocked_transitions = new_view_data.view_settings.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 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
end end
-- ####################################################################################################################
-- ##### Hooks ########################################################################################################
-- ####################################################################################################################
vmf:hook("IngameUI.setup_views", function(func, self, ingame_ui_context) vmf:hook("IngameUI.setup_views", function(func, self, ingame_ui_context)
func(self, ingame_ui_context) func(self, ingame_ui_context)
@ -193,18 +88,21 @@ vmf:hook("IngameUI.setup_views", function(func, self, ingame_ui_context)
end end
end) end)
vmf:hook("IngameUI.init", function(func, self, ingame_ui_context) vmf:hook("IngameUI.init", function(func, self, ingame_ui_context)
func(self, ingame_ui_context) func(self, ingame_ui_context)
ingame_ui = self ingame_ui = self
end) end)
vmf:hook("IngameUI.destroy", function(func, self) vmf:hook("IngameUI.destroy", function(func, self)
func(self) func(self)
ingame_ui = nil ingame_ui = nil
end) end)
-- ####################################################################################################################
-- ##### VMF internal functions and variables #########################################################################
-- ####################################################################################################################
vmf.check_custom_menus_close_keybinds = function() vmf.check_custom_menus_close_keybinds = function()
if ingame_ui then if ingame_ui then
@ -257,25 +155,27 @@ vmf.check_custom_menus_close_keybinds = function()
end end
end end
vmf.close_opened_custom_menus = function() vmf.close_opened_custom_menus = function()
if ingame_ui then if ingame_ui then
local current_view = ingame_ui.current_view local current_view = ingame_ui.current_view
if views_settings[current_view] then if views_settings[current_view] then
ingame_ui:handle_transition("exit_menu") 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 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) get_mod(views_settings[ingame_ui.current_view].mod_name):pcall(ingame_ui.views[current_view].destroy)
end end
ingame_ui.views[current_view] = nil ingame_ui.views[current_view] = nil
end --end
end end
end end
end end
-- ####################################################################################################################
-- ##### Script #######################################################################################################
-- ####################################################################################################################
-- if reloading mods -- if reloading mods
if not ingame_ui then if not ingame_ui then
@ -283,26 +183,4 @@ if not ingame_ui then
if ingame_ui_exists then if ingame_ui_exists then
ingame_ui = ingame_ui_return ingame_ui = ingame_ui_return
end end
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)

View file

@ -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)

View file

@ -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)

View file

@ -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 vmf = nil
local MODS = {} local _MODS = {}
local MODS_UNLOADING_ORDER = {} local _MODS_UNLOADING_ORDER = {}
-- #################################################################################################################### -- ####################################################################################################################
-- ##### Public functions ############################################################################################# -- ##### Public functions #############################################################################################
-- #################################################################################################################### -- ####################################################################################################################
function new_mod(mod_name) 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 return nil
end 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) local mod = VMFMod:new(mod_name)
MODS[mod_name] = mod _MODS[mod_name] = mod
return mod return mod
end end
function get_mod(mod_name) function get_mod(mod_name)
return MODS[mod_name] return _MODS[mod_name]
end end
-- #################################################################################################################### -- ####################################################################################################################
@ -32,88 +37,23 @@ end
VMFMod = class(VMFMod) VMFMod = class(VMFMod)
VMFMod.init = function (self, mod_name) VMFMod.init = function (self, mod_name)
self._name = mod_name self._name = mod_name
end end
VMFMod.get_name = function (self)
VMFMod.echo = function (self, message, show_mod_name) return self._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
end 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 Initialization ###########################################################################################
-- #################################################################################################################### -- ####################################################################################################################
vmf = new_mod("VMF") 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 = _MODS
vmf.mods_unload = function() vmf.mods_unloading_order = _MODS_UNLOADING_ORDER
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

View file

@ -8,22 +8,16 @@
* No external config files. Everything should be stored via mod:set * No external config files. Everything should be stored via mod:set
@TODO: clone in setting menu @TODO: [BUG] checkbox is checked at first tick after showing, since local_offset function is called after rect drawing
@TODO: migrate all settings to 1 table @TODO: [BUG] searchbar's insput will stop working after using russian character
@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
]] ]]
local vmf = get_mod("VMF") local vmf = get_mod("VMF")
--inject_material("materials/header_background", "header_background", "ingame_ui") inject_material("materials/vmf/header_fav_icon", "header_fav_icon", "ingame_ui")
--inject_material("materials/header_background_lit", "header_background_lit", "ingame_ui") inject_material("materials/vmf/header_fav_icon_lit", "header_fav_icon_lit", "ingame_ui")
--inject_material("materials/common_widgets_background_lit", "common_widgets_background_lit", "ingame_ui") inject_material("materials/vmf/header_fav_arrow", "header_fav_arrow", "ingame_ui")
inject_material("materials/header_fav_icon", "header_fav_icon", "ingame_ui") inject_material("materials/vmf/search_bar_icon", "search_bar_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")
-- #################################################################################################################### -- ####################################################################################################################
@ -562,12 +556,12 @@ local function create_header_widget(widget_definition, scenegraph_id)
content.callback_hide_sub_widgets(content) content.callback_hide_sub_widgets(content)
end end
local mod_name = content.mod_name local mod_name = content.mod_name
local is_mod_suspended = content.is_checkbox_checked 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
end end
@ -1344,7 +1338,7 @@ local function create_dropdown_widget(widget_definition, scenegraph_id, scenegra
pass_type = "texture", pass_type = "texture",
style_id = "background", style_id = "background",
texture_id = "background_texture", texture_id = "rect_masked_texture",
content_check_function = function (content) content_check_function = function (content)
return content.is_widget_collapsed return content.is_widget_collapsed
@ -1353,7 +1347,7 @@ local function create_dropdown_widget(widget_definition, scenegraph_id, scenegra
{ {
pass_type = "texture", pass_type = "texture",
style_id = "highlight_texture", style_id = "highlight_texture",
texture_id = "highlight_texture", texture_id = "highlight_texture",
content_check_function = function (content) content_check_function = function (content)
return content.highlight_hotspot.is_hover and content.callback_is_cursor_inside_settings_list() 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", pass_type = "text",
style_id = "text", style_id = "text",
text_id = "text" text_id = "text"
}, },
{ {
pass_type = "text", pass_type = "text",
style_id = "current_option_text", style_id = "current_option_text",
text_id = "current_option_text" text_id = "current_option_text"
}, },
{ {
pass_type = "texture", pass_type = "texture",
@ -1405,7 +1399,7 @@ local function create_dropdown_widget(widget_definition, scenegraph_id, scenegra
{ {
pass_type = "hotspot", pass_type = "hotspot",
style_id = "dropdown_hotspot", style_id = "dropdown_hotspot",
content_id = "dropdown_hotspot" content_id = "dropdown_hotspot"
}, },
-- PROCESSING -- PROCESSING
@ -2371,7 +2365,9 @@ VMFOptionsView = class(VMFOptionsView)
VMFOptionsView.init = function (self, ingame_ui_context) VMFOptionsView.init = function (self, ingame_ui_context)
self.current_setting_list_offset_y = 0 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 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") input_manager:map_device_to_service("changing_setting", "gamepad")
self.input_manager = input_manager self.input_manager = input_manager
-- wwise_world is used for making sounds (for opening menu, closing menu, etc.) -- wwise_world is used for making sounds (for opening menu, closing menu, etc.)
local world = ingame_ui_context.world_manager:world("music_world") local world = ingame_ui_context.world_manager:world("music_world")
self.wwise_world = Managers.world:wwise_world(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_favorite = callback(self, "callback_favorite")
content.callback_move_favorite = callback(self, "callback_move_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_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_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") 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 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") vmf.mod_state_changed(mod_name, is_mod_enabled)
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
WwiseWorld.trigger_event(self.wwise_world, "Play_hud_select") 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 widget_content.wrong_mouse_on_release = nil
end end
--vmf:echo("whatever")
-- #################################################################################################################### -- ####################################################################################################################
-- ##### MISCELLANEOUS: SETTINGS LIST WIDGETS ######################################################################### -- ##### MISCELLANEOUS: SETTINGS LIST WIDGETS #########################################################################
-- #################################################################################################################### -- ####################################################################################################################
@ -3452,9 +3421,7 @@ VMFOptionsView.update_picked_option_for_settings_list_widgets = function (self)
elseif widget_type == "header" then elseif widget_type == "header" then
loaded_setting_value = vmf:get("mod_suspend_state_list") widget_content.is_checkbox_checked = not vmf.disabled_mods_list[widget_content.mod_name]
widget_content.is_checkbox_checked = not loaded_setting_value[widget_content.mod_name]
elseif widget_type == "keybind" then 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 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 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 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 end
-- if 'group' -- if 'group'
else else
@ -3832,26 +3799,11 @@ VMFOptionsView.on_enter = function (self)
self:readjust_visible_settings_list_widgets_position() self:readjust_visible_settings_list_widgets_position()
end end
VMFOptionsView.on_exit = function (self) VMFOptionsView.on_exit = function (self)
WwiseWorld.trigger_event(self.wwise_world, "Play_hud_button_close") WwiseWorld.trigger_event(self.wwise_world, "Play_hud_button_close")
vmf.save_unsaved_settings_to_file() 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 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 options_menu_collapsed_widgets = vmf:get("options_menu_collapsed_widgets")
local mod_collapsed_widgets = nil local mod_collapsed_widgets = nil
if options_menu_collapsed_widgets then 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 end
-- defining header widget -- 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_type = "header"
new_widget_definition.widget_index = new_widget_index new_widget_definition.widget_index = new_widget_index
new_widget_definition.mod_name = self._name new_widget_definition.mod_name = self:get_name()
new_widget_definition.readable_mod_name = readable_mod_name or self._name new_widget_definition.readable_mod_name = readable_mod_name or self:get_name()
new_widget_definition.tooltip = mod_description new_widget_definition.tooltip = mod_description
new_widget_definition.default = true new_widget_definition.default = true
new_widget_definition.is_mod_toggable = is_mod_toggable new_widget_definition.is_mod_toggable = is_mod_toggable
if mod_collapsed_widgets then 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 end
if options_menu_favorite_mods then if options_menu_favorite_mods then
for _, current_mod_name in pairs(options_menu_favorite_mods) do 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 new_widget_definition.is_favorited = true
break break
end 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_type = current_widget.widget_type -- all
new_widget_definition.widget_index = new_widget_index -- all [gen] new_widget_definition.widget_index = new_widget_index -- all [gen]
new_widget_definition.widget_level = level -- 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.setting_name = current_widget.setting_name -- all
new_widget_definition.text = current_widget.text -- all new_widget_definition.text = current_widget.text -- all
new_widget_definition.tooltip = current_widget.tooltip -- all [optional] 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 end
if new_widget_index == 257 then 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
end end
@ -4060,12 +4012,6 @@ VMFMod.create_options = function (self, widgets_definition, is_mod_toggable, rea
end 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 if type(vmf:get("options_menu_favorite_mods")) ~= "table" then
vmf:set("options_menu_favorite_mods", {}) 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) vmf:hook("IngameView.setup_button_layout", function (func, self, layout_data)
local mods_options_button = { local mods_options_button = {
display_name = "Mods Options", display_name = vmf:localize("mods_options"),
transition = "vmf_options_view", transition = "vmf_options_view",
fade = false 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_click.localize = false
button_info.widget.style.text_hover.localize = false button_info.widget.style.text_hover.localize = false
button_info.widget.style.text_selected.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 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) 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 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)) local specific_atlas = Managers.state.game_mode._game_mode_key == "inn" and "materials/ui/ui_1080p_ingame_inn" or "materials/ui/ui_1080p_ingame"
--vmf:dump(ingame_ui.views, "whatever", 1)
end) local gui = World.create_screen_gui(ingame_ui.ui_renderer.world, "immediate",
---------------------------------------------------
--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,
"material", "material",
"materials/ui/end_screen_banners/end_screen_banners", "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,
"material", "material",
"materials/ui/end_screen_banners/end_screen_banners", "materials/ui/ui_1080p_ingame_common",
"material", "material",
"materials/ui/ui_1080p_ingame_common", specific_atlas,
"material", "material",
"materials/ui/ui_1080p_ingame_inn", "materials/ui/ui_1080p_level_images",
"material", "material",
"materials/ui/ui_1080p_level_images", "materials/ui/ui_1080p_chat",
"material", "material",
"materials/ui/ui_1080p_chat", "materials/fonts/gw_fonts",
"material", "material",
"materials/fonts/gw_fonts", "materials/vmf/header_fav_icon",
"material", "material",
"materials/header_background", "materials/vmf/header_fav_icon_lit",
"material", "material",
"materials/header_background_lit", "materials/vmf/header_fav_arrow",
"material", "material",
"materials/common_widgets_background_lit", "materials/vmf/search_bar_icon")
"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_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 World.destroy_gui(ingame_ui.ui_renderer.world, ingame_ui.ui_renderer.gui)
ingame_ui.ui_top_renderer.gui_retained = gui_retained 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 end

View file

@ -1,49 +1,4 @@
local mod = new_mod("test_mod") 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 = { local options_widgets = {
{ {
@ -95,9 +50,17 @@ local options_widgets = {
["widget_type"] = "keybind", ["widget_type"] = "keybind",
["text"] = "Some keybind", ["text"] = "Some keybind",
["tooltip"] = "Probably keybind", ["tooltip"] = "Probably keybind",
["default_value"] = {"f", "ctrl"}, ["default_value"] = {"g", "ctrl"},
["action"] = "whatever" ["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", ["setting_name"] = "game_mode2",
["widget_type"] = "dropdown", ["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 -- chat_broadcast
mod.whatever = function() mod.whatever = function ()
mod:echo("whatever") mod:echo("whatever")
end end
mod.game_state_changed = function ()
--mod:echo("whatever" .. nil)
end
--[[ --[[
mod:hook("KeystrokeHelper.parse_strokes", function(func, text, index, mode, keystrokes) mod:hook("KeystrokeHelper.parse_strokes", function(func, text, index, mode, keystrokes)
print(tostring(text) .. " " .. tostring(index) .. " " .. tostring(mode) .. " " .. tostring(keystrokes)) print(tostring(text) .. " " .. tostring(index) .. " " .. tostring(mode) .. " " .. tostring(keystrokes))
@ -257,19 +224,14 @@ end)
mod:echo("YAY") mod:echo("YAY")
end]] end]]
--[[ local mod2 = new_mod("SkipSplashScreen")
local mod = new_mod("test_mod2")
mod:create_options(options_widgets, true, "Bots Improvements", "Mod description")
local mod = new_mod("test_mod3") mod2:hook("StateSplashScreen.on_enter", function(func, self)
mod:create_options(options_widgets, true, "Show Healhbars", "Mod description") self._skip_splash = true
func(self)
end)
local mod = new_mod("test_mod4") mod2:hook("StateSplashScreen.setup_splash_screen_view", function(func, self)
mod:create_options(options_widgets, true, "Ammo Meter", "Mod description") func(self)
self.splash_view = nil
local mod = new_mod("test_mod5") end)
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")
]]

View file

@ -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

View file

@ -3,18 +3,23 @@ return {
dofile("scripts/mods/vmf/functions/table") dofile("scripts/mods/vmf/functions/table")
dofile("scripts/mods/vmf/modules/dev_console")
dofile("scripts/mods/vmf/modules/mods") dofile("scripts/mods/vmf/modules/mods")
dofile("scripts/mods/vmf/modules/debug") dofile("scripts/mods/vmf/modules/core/events")
dofile("scripts/mods/vmf/modules/hooks") dofile("scripts/mods/vmf/modules/core/settings")
dofile("scripts/mods/vmf/modules/chat") dofile("scripts/mods/vmf/modules/core/core_functions")
dofile("scripts/mods/vmf/modules/settings") dofile("scripts/mods/vmf/modules/debug/dev_console")
dofile("scripts/mods/vmf/modules/keybindings") dofile("scripts/mods/vmf/modules/debug/table_dump")
dofile("scripts/mods/vmf/modules/gui") dofile("scripts/mods/vmf/modules/core/hooks")
dofile("scripts/mods/vmf/modules/vmf_options_view") dofile("scripts/mods/vmf/modules/core/toggling")
dofile("scripts/mods/vmf/modules/core/keybindings")
--Application.set_user_setting("mod_developer_mode", true) dofile("scripts/mods/vmf/modules/core/delayed_chat_messages")
--Application.save_user_settings() 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") object.vmf = get_mod("VMF")
@ -24,13 +29,14 @@ return {
update = function(object, dt) update = function(object, dt)
object.vmf.mods_update(dt) object.vmf.mods_update_event(dt)
object.vmf.check_pressed_keybinds() object.vmf.check_pressed_keybinds()
object.vmf.check_custom_menus_close_keybinds(dt) object.vmf.check_custom_menus_close_keybinds(dt)
if not object.vmf.all_mods_were_loaded and Managers.mod._state == "done" then if not object.vmf.all_mods_were_loaded and Managers.mod._state == "done" then
object.vmf.initialize_keybinds() object.vmf.initialize_keybinds()
object.vmf.initialize_vmf_options_view()
object.vmf.all_mods_were_loaded = true object.vmf.all_mods_were_loaded = true
end end
@ -43,16 +49,17 @@ return {
on_reload = function(object) on_reload = function(object)
print("VMF:ON_RELOAD()") print("VMF:ON_RELOAD()")
object.vmf.disable_mods_options_button()
object.vmf.close_opened_custom_menus() object.vmf.close_opened_custom_menus()
object.vmf.delete_keybinds() object.vmf.delete_keybinds()
object.vmf.mods_unload() object.vmf.mods_unload_event()
object.vmf.hooks_unload() object.vmf.hooks_unload()
object.vmf.save_unsaved_settings_to_file() object.vmf.save_unsaved_settings_to_file()
end, end,
on_game_state_changed = function(object, status, state) on_game_state_changed = function(object, status, state)
print("VMF:ON_GAME_STATE_CHANGED(), status: " .. tostring(status) .. ", state: " .. tostring(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() object.vmf.save_unsaved_settings_to_file()
if status == "exit" and state == "StateTitleScreen" then if status == "exit" and state == "StateTitleScreen" then

View file

@ -1 +1 @@
boot_package = "resource_packages/vmf" boot_package = "resource_packages/vmf/vmf_resources"

View file

@ -1,11 +1,9 @@
print("Vermintide Mod Framework loading")
local ret = { local ret = {
run = function() run = function()
return dofile("scripts/mods/vmf/vmf_loader") return dofile("scripts/mods/vmf/vmf_loader")
end, end,
packages = { packages = {
"resource_packages/vmf" "resource_packages/vmf"
}, }
} }
return ret return ret