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 = {
input = {
filename = "gui/header_fav_arrow"
filename = "gui/vmf/header_fav_arrow"
}
output = {
apply_processing = true

View file

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

View file

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

View file

@ -1,6 +1,6 @@
common = {
input = {
filename = "gui/search_bar_icon"
filename = "gui/vmf/search_bar_icon"
}
output = {
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"
textures = {
diffuse_map = "gui/header_fav_arrow"
diffuse_map = "gui/vmf/header_fav_arrow"
}
variables = {

View file

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

View file

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

View file

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

View file

@ -7,27 +7,17 @@ package = [
]
material = [
"materials/header_background"
"materials/header_background_lit"
"materials/common_widgets_background_lit"
"materials/header_fav_icon"
"materials/header_fav_icon_lit"
"materials/header_fav_arrow"
"materials/search_bar_icon"
"materials/vmf/*"
]
lua = [
"scripts/mods/vmf/functions/*"
"localization/vmf"
"scripts/mods/vmf/vmf_loader"
"scripts/mods/vmf/modules/dev_console"
"scripts/mods/vmf/modules/mods"
"scripts/mods/vmf/modules/debug"
"scripts/mods/vmf/modules/hooks"
"scripts/mods/vmf/modules/chat"
"scripts/mods/vmf/modules/settings"
"scripts/mods/vmf/modules/keybindings"
"scripts/mods/vmf/modules/gui"
"scripts/mods/vmf/modules/vmf_options_view"
"scripts/mods/vmf/modules/testing_stuff_here"
"scripts/mods/vmf/*"
"scripts/mods/vmf/functions/*"
"scripts/mods/vmf/modules/*"
"scripts/mods/vmf/modules/core/*"
"scripts/mods/vmf/modules/debug/*"
"scripts/mods/vmf/modules/gui/*"
"scripts/mods/vmf/modules/options_menu/*"
]

View file

@ -1,42 +1,9 @@
local vmf = get_mod("VMF")
-- ####################################################################################################################
-- ##### Hooks Functions ##############################################################################################
-- ####################################################################################################################
-- HOOK: [ChatManager.register_channel]
local hook_send_unsent_messages = function (func, self, channel_id, members_func)
func(self, channel_id, members_func)
if channel_id == 1 then
for _, message in ipairs(vmf.unsent_chat_messages) do
self:add_local_system_message(1, message, true)
end
end
end
-- ####################################################################################################################
-- ##### Event functions ##############################################################################################
-- ####################################################################################################################
-- at the moment of loading VMF Chat Manager is not initialized yet,
-- so it should be hooked with some delay
vmf.hook_chat_manager = function()
if not vmf.is_chat_manager_hooked then
vmf.is_chat_manager_hooked = true
vmf:hook("ChatManager.register_channel", hook_send_unsent_messages)
end
end
-- ####################################################################################################################
-- ##### VMFMod #######################################################################################################
-- ####################################################################################################################
VMFMod.chat_broadcast = function(self, message)
local chat = Managers.chat

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
-- ####################################################################################################################
-- ##### Private functions ############################################################################################
-- ##### Local functions ##############################################################################################
-- ####################################################################################################################
local function check_function_name(mod, hook_function_name, hooked_function_name)
if type(hooked_function_name) ~= "string" then
mod:error("(%s): hooked function argument should be the string, not %s", hook_function_name, type(hooked_function_name))
return false
end
return true
end
local function get_function_by_name(function_name)
local _, value = pcall(loadstring("return " .. function_name))
@ -117,7 +127,7 @@ end
local function modify_hook(mod, hooked_function_name, action)
if not get_function_by_name(hooked_function_name) then
mod:echo("ERROR: 'hook_".. action .. "' - function [" .. hooked_function_name .. "] doesn't exist", true)
mod:error("(hook_%s): function [%s] doesn't exist", action, hooked_function_name)
return
end
@ -174,13 +184,11 @@ local function modify_all_hooks(mod, action)
if #hooked_function_entry.hooks == 0 then
table.insert(no_hooks_functions_indexes, 1, i)
end
end
for _, no_hooks_function_index in ipairs(no_hooks_functions_indexes) do
table.remove(HOOKED_FUNCTIONS, no_hooks_function_index)
end
end
-- ####################################################################################################################
@ -189,9 +197,13 @@ end
VMFMod.hook = function (self, hooked_function_name, hook_function)
if not check_function_name(self, "hook", hooked_function_name) then
return
end
local hooked_function_entry = get_hooked_function_entry(hooked_function_name) or create_hooked_function_entry(hooked_function_name)
if not hooked_function_entry then
self:echo("ERROR: 'hook' - function [" .. hooked_function_name .. "] doesn't exist", true)
self:error("(hook): function [%s] doesn't exist", hooked_function_name)
return
end
@ -211,16 +223,31 @@ end
VMFMod.hook_remove = function (self, hooked_function_name)
if not check_function_name(self, "hook_remove", hooked_function_name) then
return
end
modify_hook(self, hooked_function_name, "remove")
end
VMFMod.hook_disable = function (self, hooked_function_name)
if not check_function_name(self, "hook_disable", hooked_function_name) then
return
end
modify_hook(self, hooked_function_name, "disable")
end
VMFMod.hook_enable = function (self, hooked_function_name)
if not check_function_name(self, "hook_enable", hooked_function_name) then
return
end
modify_hook(self, hooked_function_name, "enable")
end
@ -240,7 +267,7 @@ VMFMod.enable_all_hooks = function (self)
end
-- ####################################################################################################################
-- ##### Event functions ##############################################################################################
-- ##### VMF internal functions and variables #########################################################################
-- ####################################################################################################################
-- removes all hooks when VMF is about to be reloaded

View file

@ -1,5 +1,163 @@
local vmf = get_mod("VMF")
VMFModsKeyMap = {
win32 = {
["ctrl"] = {"keyboard", "left ctrl", "held"},
["alt"] = {"keyboard", "left alt", "held"},
["shift"] = {"keyboard", "left shift", "held"}
}
}
-- ["mod_name"]["setting_name"] = {"action_name", {"primary_key", "special_key", "special_key", "special_key"}} (special_key - "ctrl"/"shift"/"alt")
local _RAW_KEYBINDS = {}
-- ["primary_key"] = {{"mod_name", "action_name", ctrl_used(bool), alt_used(bool), shift_used(bool)}, {}, {}, ...}
local _OPTIMIZED_KEYBINDS = {}
-- ####################################################################################################################
-- ##### Local functions ##############################################################################################
-- ####################################################################################################################
local function apply_keybinds()
_OPTIMIZED_KEYBINDS = {}
for mod_name, mod_keybinds in pairs(_RAW_KEYBINDS) do
for _, keybind in pairs(mod_keybinds) do
local action_name = keybind[1]
local primary_key = keybind[2][1]
local special_key1 = keybind[2][2]
local special_key2 = keybind[2][3]
local special_key3 = keybind[2][4]
local special_keys = {}
if special_key1 then
special_keys[special_key1] = true
end
if special_key2 then
special_keys[special_key2] = true
end
if special_key3 then
special_keys[special_key3] = true
end
_OPTIMIZED_KEYBINDS[primary_key] = _OPTIMIZED_KEYBINDS[primary_key] or {}
table.insert(_OPTIMIZED_KEYBINDS[primary_key], {mod_name, action_name, special_keys["ctrl"], special_keys["alt"], special_keys["shift"]})
end
end
end
-- ####################################################################################################################
-- ##### VMFMod #######################################################################################################
-- ####################################################################################################################
-- use it directly only for dedugging purposes, otherwise use keybind widget
-- setting_name [string] - keybind identifyer for certain mod
-- action_name [string] - name of some mod.function which will be called when keybind is pressed
-- keys [table] = {"primary_key", "2nd_key" [optional], "3rd_key" [optional], "4th_key" [optional]}
-- 2, 3, 4 keys can contain words "ctrl", "alt", "shift" (lowercase)
VMFMod.keybind = function (self, setting_name, action_name, keys)
if keys[1] then
local mod_keybinds = _RAW_KEYBINDS[self:get_name()] or {}
mod_keybinds[setting_name] = {action_name, keys}
_RAW_KEYBINDS[self:get_name()] = mod_keybinds
else
local mod_keybinds = _RAW_KEYBINDS[self:get_name()]
if mod_keybinds and mod_keybinds[setting_name] then
mod_keybinds[setting_name] = nil
end
end
if vmf.keybind_input_service then
apply_keybinds()
end
end
-- ####################################################################################################################
-- ##### VMF internal functions and variables #########################################################################
-- ####################################################################################################################
vmf.initialize_keybinds = function()
Managers.input.create_input_service(Managers.input, "VMFMods", "VMFModsKeyMap")
Managers.input.map_device_to_service(Managers.input, "VMFMods", "keyboard")
Managers.input.map_device_to_service(Managers.input, "VMFMods", "mouse")
vmf.keybind_input_service = Managers.input:get_service("VMFMods")
apply_keybinds()
end
vmf.check_pressed_keybinds = function()
local input_service = vmf.keybind_input_service
if input_service then
-- don't check for the pressed keybindings until player will release already pressed keybind
if vmf.activated_pressed_key then
if input_service:get(vmf.activated_pressed_key) then
return
else
vmf.activated_pressed_key = nil
end
end
local key_has_active_keybind = false
for key, key_bindings in pairs(_OPTIMIZED_KEYBINDS) do
if input_service:get(key) then
for _, binding_info in ipairs(key_bindings) do
if (not binding_info[3] and not input_service:get("ctrl") or binding_info[3] and input_service:get("ctrl")) and
(not binding_info[4] and not input_service:get("alt") or binding_info[4] and input_service:get("alt")) and
(not binding_info[5] and not input_service:get("shift") or binding_info[5] and input_service:get("shift")) then
local mod = get_mod(binding_info[1])
if binding_info[2] == "toggle_mod" then
vmf.mod_state_changed(mod:get_name(), not mod:is_enabled())
key_has_active_keybind = true
vmf.activated_pressed_key = key
elseif mod:is_enabled() then
local action_exists, action_function = pcall(function() return mod[binding_info[2]] end)
if action_exists then
local success, error_message = pcall(action_function)
if not success then
mod:error("(keybindings)(mod.%s): %s", tostring(binding_info[2]), tostring(error_message))
end
else
mod:error("(keybindings): function '%s' wasn't found.", tostring(binding_info[2]))
end
key_has_active_keybind = true
vmf.activated_pressed_key = key
end
end
end
-- return here because some other mods can have the same keybind which also need to be executed
if key_has_active_keybind then
return
end
end
end
end
end
vmf.delete_keybinds = function()
VMFModsKeyMap = {}
end
local keyboard_buton_name = Keyboard.button_name
local mouse_buton_name = Mouse.button_name
@ -152,6 +310,10 @@ vmf.keys = {
vmf.readable_key_names = {}
-- ####################################################################################################################
-- ##### Script #######################################################################################################
-- ####################################################################################################################
for _, controller_keys in pairs(vmf.keys) do
for _, key_info in pairs(controller_keys) do
vmf.readable_key_names[key_info[2]] = key_info[1]
@ -162,15 +324,6 @@ vmf.readable_key_names["ctrl"] = "Ctrl"
vmf.readable_key_names["alt"] = "Alt"
vmf.readable_key_names["shift"] = "Shift"
VMFModsKeyMap = {
win32 = {
["ctrl"] = {"keyboard", "left ctrl", "held"},
["alt"] = {"keyboard", "left alt", "held"},
["shift"] = {"keyboard", "left shift", "held"}
}
}
for _, key_info in pairs(vmf.keys.keyboard) do
VMFModsKeyMap.win32[key_info[2]] = {"keyboard", key_info[3], "held"}
end
@ -184,138 +337,3 @@ for i = 10, 13 do
local key_info = vmf.keys.mouse[i]
VMFModsKeyMap.win32[key_info[2]] = {"mouse", key_info[3], "pressed"}
end
-- ["mod_name"]["setting_name"] = {"action_name", {"primary_key", "2nd_key", "3rd_key", "4th_key"}}
local raw_keybinds = {}
-- ["primary_key"] = {{"mod_name", "action_name", "2nd_key", "3rd_key", "4th_key"}, {}, {}, ...}
local optimized_keybinds = {}
local function apply_keybinds()
optimized_keybinds = {}
for mod_name, mod_keybinds in pairs(raw_keybinds) do
for _, keybind in pairs(mod_keybinds) do
local action_name = keybind[1]
local primary_key = keybind[2][1]
local special_key1 = keybind[2][2]
local special_key2 = keybind[2][3]
local special_key3 = keybind[2][4]
local special_keys = {}
if special_key1 then
special_keys[special_key1] = true
end
if special_key2 then
special_keys[special_key2] = true
end
if special_key3 then
special_keys[special_key3] = true
end
optimized_keybinds[primary_key] = optimized_keybinds[primary_key] or {}
table.insert(optimized_keybinds[primary_key], {mod_name, action_name, special_keys["ctrl"], special_keys["alt"], special_keys["shift"]})
end
end
end
-- use it directly only for dedugging purposes, otherwise use keybind widget
-- setting_name [string] - keybind identifyer for certain mod
-- action_name [string] - name of some mod.function which will be called when keybind is pressed
-- keys [table] = {"primary_key", "2nd_key" [optional], "3rd_key" [optional], "4th_key" [optional]}
-- 2, 3, 4 keys can contain words "ctrl", "alt", "shift" (lowercase)
VMFMod.keybind = function (self, setting_name, action_name, keys)
if keys[1] then
local mod_keybinds = raw_keybinds[self._name] or {}
mod_keybinds[setting_name] = {action_name, keys}
raw_keybinds[self._name] = mod_keybinds
else
local mod_keybinds = raw_keybinds[self._name]
if mod_keybinds and mod_keybinds[setting_name] then
mod_keybinds[setting_name] = nil
end
end
if vmf.keybind_input_service then
apply_keybinds()
end
end
vmf.initialize_keybinds = function()
Managers.input.create_input_service(Managers.input, "VMFMods", "VMFModsKeyMap")
Managers.input.map_device_to_service(Managers.input, "VMFMods", "keyboard")
Managers.input.map_device_to_service(Managers.input, "VMFMods", "mouse")
vmf.keybind_input_service = Managers.input:get_service("VMFMods")
apply_keybinds()
end
vmf.check_pressed_keybinds = function()
local input_service = vmf.keybind_input_service
if input_service then
-- don't check for the pressed keybindings until player will release already pressed keybind
if vmf.activated_pressed_key then
if input_service:get(vmf.activated_pressed_key) then
return
else
vmf.activated_pressed_key = nil
end
end
local key_has_active_keybind = false
for key, key_bindings in pairs(optimized_keybinds) do
if input_service:get(key) then
for _, binding_info in ipairs(key_bindings) do
if (not binding_info[3] and not input_service:get("ctrl") or binding_info[3] and input_service:get("ctrl")) and
(not binding_info[4] and not input_service:get("alt") or binding_info[4] and input_service:get("alt")) and
(not binding_info[5] and not input_service:get("shift") or binding_info[5] and input_service:get("shift")) then
--@TODO: also check for suspending, and perhaps add "toggle" event
local action_exists, action_function = pcall(function() return get_mod(binding_info[1])[binding_info[2]] end)
if action_exists then
local success, error_message = pcall(action_function)
if not success then
get_mod(binding_info[1]):echo("ERROR(keybindings) in function '" .. tostring(binding_info[2]) .. "': " .. tostring(error_message), true)
end
else
get_mod(binding_info[1]):echo("ERROR(keybindings): function '" .. tostring(binding_info[2]) .. "' wasn't found.", true)
end
key_has_active_keybind = true
vmf.activated_pressed_key = key
end
end
-- return here because some other mods can have the same keybind which also need to be executed
if key_has_active_keybind then
return
end
end
end
end
end
vmf.delete_keybinds = function()
VMFModsKeyMap = {}
end

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.
* It operates settings within the mod namespace (you can define settings with the same name for different mods)
* Settings location: "%AppData%\Roaming\Fatshark\Warhammer End Times Vermintide\user_settings.config"
* All settings are being saved to the settings-file only when map changes
* All settings are being saved to the settings-file when game state changes, when options menu is closed and on reload
--]]
local vmf = get_mod("VMF")
local MODS_SETTINGS = {}
local THERE_ARE_UNSAVED_CHANGES = false
local _MODS_SETTINGS = Application.user_setting("mods_settings") or {}
local _THERE_ARE_UNSAVED_CHANGES = false
-- ####################################################################################################################
-- ##### Private functions ############################################################################################
-- ##### Local functions ##############################################################################################
-- ####################################################################################################################
local function load_settings(mod_name)
local mod_settings = Application.user_setting(mod_name)
mod_settings = mod_settings or {}
MODS_SETTINGS[mod_name] = mod_settings
end
local function save_all_settings()
if THERE_ARE_UNSAVED_CHANGES then
if _THERE_ARE_UNSAVED_CHANGES then
Application.set_user_setting("mods_settings", _MODS_SETTINGS)
Application.save_user_settings()
THERE_ARE_UNSAVED_CHANGES = false
_THERE_ARE_UNSAVED_CHANGES = false
end
end
@ -42,21 +35,20 @@ end
--]]
VMFMod.set = function (self, setting_name, setting_value, call_setting_changed_event)
local mod_name = self._name
local mod_name = self:get_name()
if not MODS_SETTINGS[mod_name] then
load_settings(mod_name)
if not _MODS_SETTINGS[mod_name] then
_MODS_SETTINGS[mod_name] = {}
end
local mod_settings = MODS_SETTINGS[mod_name]
mod_settings[setting_name] = setting_value
local mod_settings = _MODS_SETTINGS[mod_name]
Application.set_user_setting(mod_name, mod_settings)
mod_settings[setting_name] = type(setting_value) == "table" and table.clone(setting_value) or setting_value
THERE_ARE_UNSAVED_CHANGES = true
_THERE_ARE_UNSAVED_CHANGES = true
if call_setting_changed_event and self.setting_changed then
self.setting_changed(setting_name)
if call_setting_changed_event then
vmf.mod_setting_changed_event(self, setting_name)
end
end
@ -64,19 +56,24 @@ end
* setting_name [string]: setting name, can contain any characters lua-string can @TODO: check this
--]]
VMFMod.get = function (self, setting_name)
local mod_name = self._name
if not MODS_SETTINGS[mod_name] then
load_settings(mod_name)
local mod_name = self:get_name()
local mod_settings = _MODS_SETTINGS[mod_name]
local setting_value
if mod_settings then
setting_value = mod_settings[setting_name]
else
return nil
end
local mod_settings = MODS_SETTINGS[mod_name]
return mod_settings[setting_name]
return type(setting_value) == "table" and table.clone(setting_value) or setting_value
end
-- ####################################################################################################################
-- ##### Event functions ##############################################################################################
-- ##### VMF internal functions and variables #########################################################################
-- ####################################################################################################################
vmf.save_unsaved_settings_to_file = function()

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

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 injected_materials = {}
local none_atlas_textures = {}
-- @TODO: can several materials be specified via 1 material file? Figure it out.
function inject_material(material_path, material_name, ...)
--print("[FUCK]: Mods.gui.inject_material " .. material_path .. material_name)
local material_users = {...}
if #material_users == 0 then
material_users = {"all"}
end
for _, material_user in ipairs(material_users) do
if not injected_materials[material_user] then
injected_materials[material_user] = {}
end
table.insert(injected_materials[material_user], material_path)
end
none_atlas_textures[material_name] = true
end
--table.dump(injected_materials, "injected_materials", 2)
vmf:hook("UIRenderer.create", function(func, world, ...)
local ui_renderer_creator = nil
-- extract the part with actual callstack
local callstack = Script.callstack():match('Callstack>(.-)<')
if callstack then
-- get the name of lua script which called 'UIRenderer.create'
-- it's always the 4th string of callstack ([ ] [0] [1] >[2]<)
-- print(callstack) -- @DEBUG
local i = 0
for s in callstack:gmatch("(.-)\n") do
i = i + 1
if i == 4 then
ui_renderer_creator = s:match("([^%/]+)%.lua")
break --@TODO: uncomment after debugging or ... (?)
end
--EchoConsole(s) -- @DELETEME
end
end
if ui_renderer_creator then
print("UI_RENDERER CREATED BY: " .. ui_renderer_creator) -- @DEBUG
else
--EchoConsole("You're never supposed to see this.")
--assert(true, "That's not right. That's not right at all!")
--EchoConsole(callstack)
return func(world, ...)
end
local ui_renderer_materials = {...}
if injected_materials[ui_renderer_creator] then
for _, material in ipairs(injected_materials[ui_renderer_creator]) do
table.insert(ui_renderer_materials, "material")
table.insert(ui_renderer_materials, material)
end
end
if injected_materials["all"] then
for _, material in ipairs(injected_materials["all"]) do
table.insert(ui_renderer_materials, "material")
table.insert(ui_renderer_materials, material)
end
end
table.dump(ui_renderer_materials, "UI_RENDERER MATERIALS", 2) -- @DEBUG
return func(world, unpack(ui_renderer_materials))
end)
vmf:hook("UIAtlasHelper.get_atlas_settings_by_texture_name", function(func, texture_name)
if none_atlas_textures[texture_name] then
return
end
return func(texture_name)
end)
--inject_material("materials/yoba_face", "yoba_face", "ui_passes", "ingame_ui")
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
local ingame_ui = nil
-- needed to protect opened menus from being closed right away and vice versa
@ -119,10 +8,13 @@ local opening_keybind_is_pressed = true
local views_settings = {}
-- ####################################################################################################################
-- ##### VMFMod #######################################################################################################
-- ####################################################################################################################
VMFMod.register_new_view = function (self, new_view_data)
new_view_data.view_settings.mod_name = self._name
new_view_data.view_settings.mod_name = self:get_name()
views_settings[new_view_data.view_name] = new_view_data.view_settings
@ -154,9 +46,9 @@ VMFMod.register_new_view = function (self, new_view_data)
local new_view_name = new_view_data.view_name
local new_view_init_function = new_view_data.view_settings.init_view_function
if new_view_name ~= "vmf_options_view" then
--if new_view_name ~= "vmf_options_view" then
ingame_ui.views[new_view_name] = new_view_init_function(ingame_ui.ingame_ui_context)
end
--end
-- set 'ingame_ui.blocked_transitions'
local blocked_transitions = new_view_data.view_settings.blocked_transitions
local current_blocked_transitions = ingame_ui.is_in_inn and blocked_transitions.inn or blocked_transitions.ingame
@ -167,6 +59,9 @@ VMFMod.register_new_view = function (self, new_view_data)
end
end
-- ####################################################################################################################
-- ##### Hooks ########################################################################################################
-- ####################################################################################################################
vmf:hook("IngameUI.setup_views", function(func, self, ingame_ui_context)
func(self, ingame_ui_context)
@ -193,18 +88,21 @@ vmf:hook("IngameUI.setup_views", function(func, self, ingame_ui_context)
end
end)
vmf:hook("IngameUI.init", function(func, self, ingame_ui_context)
func(self, ingame_ui_context)
ingame_ui = self
end)
vmf:hook("IngameUI.destroy", function(func, self)
func(self)
ingame_ui = nil
end)
-- ####################################################################################################################
-- ##### VMF internal functions and variables #########################################################################
-- ####################################################################################################################
vmf.check_custom_menus_close_keybinds = function()
if ingame_ui then
@ -257,25 +155,27 @@ vmf.check_custom_menus_close_keybinds = function()
end
end
vmf.close_opened_custom_menus = function()
if ingame_ui then
local current_view = ingame_ui.current_view
if views_settings[current_view] then
ingame_ui:handle_transition("exit_menu")
if current_view ~= "vmf_options_view" then
--if current_view ~= "vmf_options_view" then
if ingame_ui.views[current_view].destroy and get_mod(views_settings[ingame_ui.current_view].mod_name) then
get_mod(views_settings[ingame_ui.current_view].mod_name):pcall(ingame_ui.views[current_view].destroy)
end
ingame_ui.views[current_view] = nil
end
--end
end
end
end
-- ####################################################################################################################
-- ##### Script #######################################################################################################
-- ####################################################################################################################
-- if reloading mods
if not ingame_ui then
@ -284,25 +184,3 @@ if not ingame_ui then
ingame_ui = ingame_ui_return
end
end
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
local mod = new_mod("SkipSplashScreen")
mod:hook("StateSplashScreen.on_enter", function(func, self)
self._skip_splash = true
func(self)
end)
mod:hook("StateSplashScreen.setup_splash_screen_view", function(func, self)
func(self)
self.splash_view = nil
end)

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 MODS = {}
local MODS_UNLOADING_ORDER = {}
local _MODS = {}
local _MODS_UNLOADING_ORDER = {}
-- ####################################################################################################################
-- ##### Public functions #############################################################################################
-- ####################################################################################################################
function new_mod(mod_name)
if MODS[mod_name] then
vmf:echo("ERROR: you can't create mod \"" .. mod_name .. "\" because it already exists")
if type(mod_name) ~= "string" then
vmf:error("(new_mod): the mod name should be the string, not '%s'", type(mod_name)) -- @EARLY_CALL:
return nil
end
table.insert(MODS_UNLOADING_ORDER, 1, mod_name)
if _MODS[mod_name] then
vmf:error("(new_mod): you can't use name \"%s\" for your mod, because the mod with the same name already exists", mod_name) -- @EARLY_CALL:
return nil
end
table.insert(_MODS_UNLOADING_ORDER, 1, mod_name)
local mod = VMFMod:new(mod_name)
MODS[mod_name] = mod
_MODS[mod_name] = mod
return mod
end
function get_mod(mod_name)
return MODS[mod_name]
return _MODS[mod_name]
end
-- ####################################################################################################################
@ -32,88 +37,23 @@ end
VMFMod = class(VMFMod)
VMFMod.init = function (self, mod_name)
self._name = mod_name
end
VMFMod.echo = function (self, message, show_mod_name)
message = tostring(message)
print("[ECHO][" .. self._name .. "] " .. message)
if show_mod_name then
message = "[" .. self._name .. "] " .. message
VMFMod.get_name = function (self)
return self._name
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
VMFMod.pcall = function (self, ...)
local status, value = pcall(...)
if not status then
self:echo("ERROR(pcall): " .. tostring(value), true)
end
return status, value
end
VMFMod.dofile = function (self, script_path)
local status, value = pcall(dofile, script_path)
if not status then
self:echo("ERROR(loadfile): " .. value.error, true)
print("\nTRACEBACK:\n\n" .. value.traceback .. "\nLOCALS:\n\n" .. value.locals)
end
return value
end
-- ####################################################################################################################
-- ##### VMF Initialization ###########################################################################################
-- ####################################################################################################################
vmf = new_mod("VMF")
vmf.unsent_chat_messages = {}
-- ####################################################################################################################
-- ##### Event functions ##############################################################################################
-- ##### VMF internal functions and variables #########################################################################
-- ####################################################################################################################
-- call 'unload' for every mod which definded it
vmf.mods_unload = function()
for _, mod_name in pairs(MODS_UNLOADING_ORDER) do --@TODO: maybe ipairs?
if MODS[mod_name].unload then
MODS[mod_name].unload()
end
end
end
-- call 'update' for every mod which definded it
vmf.mods_update = function(dt)
for _, mod in pairs(MODS) do --@TODO: maybe ipairs?
if mod.update then
mod.update(dt)
end
end
end
-- call 'game_state_changed' for every mod which definded it
vmf.mods_game_state_changed = function(status, state)
for _, mod in pairs(MODS) do --@TODO: maybe ipairs?
if mod.game_state_changed then
mod.game_state_changed(status, state)
end
end
end
vmf.mods = _MODS
vmf.mods_unloading_order = _MODS_UNLOADING_ORDER

View file

@ -8,22 +8,16 @@
* No external config files. Everything should be stored via mod:set
@TODO: clone in setting menu
@TODO: migrate all settings to 1 table
@TODO: move suspending list to vmf_options_menu
Not triggering hotkeys on suspension. As well as custom event. And I'll probably do something about mod:initialized(), when I'll get to it
@TODO: [BUG] checkbox is checked at first tick after showing, since local_offset function is called after rect drawing
@TODO: [BUG] searchbar's insput will stop working after using russian character
]]
local vmf = get_mod("VMF")
--inject_material("materials/header_background", "header_background", "ingame_ui")
--inject_material("materials/header_background_lit", "header_background_lit", "ingame_ui")
--inject_material("materials/common_widgets_background_lit", "common_widgets_background_lit", "ingame_ui")
inject_material("materials/header_fav_icon", "header_fav_icon", "ingame_ui")
inject_material("materials/header_fav_icon_lit", "header_fav_icon_lit", "ingame_ui")
inject_material("materials/header_fav_arrow", "header_fav_arrow", "ingame_ui")
inject_material("materials/search_bar_icon", "search_bar_icon", "ingame_ui")
inject_material("materials/vmf/header_fav_icon", "header_fav_icon", "ingame_ui")
inject_material("materials/vmf/header_fav_icon_lit", "header_fav_icon_lit", "ingame_ui")
inject_material("materials/vmf/header_fav_arrow", "header_fav_arrow", "ingame_ui")
inject_material("materials/vmf/search_bar_icon", "search_bar_icon", "ingame_ui")
-- ####################################################################################################################
@ -563,11 +557,11 @@ local function create_header_widget(widget_definition, scenegraph_id)
end
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
@ -1344,7 +1338,7 @@ local function create_dropdown_widget(widget_definition, scenegraph_id, scenegra
pass_type = "texture",
style_id = "background",
texture_id = "background_texture",
texture_id = "rect_masked_texture",
content_check_function = function (content)
return content.is_widget_collapsed
@ -2371,7 +2365,9 @@ VMFOptionsView = class(VMFOptionsView)
VMFOptionsView.init = function (self, ingame_ui_context)
self.current_setting_list_offset_y = 0
self.scroll_step = 40
self.default_scroll_step = 40
self.scroll_step = self.default_scroll_step / 100 * (vmf:get("vmf_options_scrolling_speed") or 100)
self.is_setting_changes_applied_immidiately = true
@ -2399,9 +2395,6 @@ VMFOptionsView.init = function (self, ingame_ui_context)
input_manager:map_device_to_service("changing_setting", "gamepad")
self.input_manager = input_manager
-- wwise_world is used for making sounds (for opening menu, closing menu, etc.)
local world = ingame_ui_context.world_manager:world("music_world")
self.wwise_world = Managers.world:wwise_world(world)
@ -2544,7 +2537,7 @@ VMFOptionsView.initialize_header_widget = function (self, definition, scenegraph
content.callback_favorite = callback(self, "callback_favorite")
content.callback_move_favorite = callback(self, "callback_move_favorite")
content.callback_mod_suspend_state_changed = callback(self, "callback_mod_suspend_state_changed")
content.callback_mod_state_changed = callback(self, "callback_mod_state_changed")
content.callback_hide_sub_widgets = callback(self, "callback_hide_sub_widgets")
content.callback_fit_tooltip_to_the_screen = callback(self, "callback_fit_tooltip_to_the_screen")
content.callback_is_cursor_inside_settings_list = callback(self, "callback_is_cursor_inside_settings_list")
@ -2645,33 +2638,9 @@ VMFOptionsView.callback_setting_changed = function (self, mod_name, setting_name
end
VMFOptionsView.callback_mod_suspend_state_changed = function (self, mod_name, is_suspended)
VMFOptionsView.callback_mod_state_changed = function (self, mod_name, is_mod_enabled)
local mod_suspend_state_list = vmf:get("mod_suspend_state_list")
if is_suspended then
mod_suspend_state_list[mod_name] = true
else
mod_suspend_state_list[mod_name] = nil
end
vmf:set("mod_suspend_state_list", mod_suspend_state_list)
local mod = get_mod(mod_name)
if is_suspended then
if mod.suspended then
mod.suspended()
else
mod:echo("ERROR: suspending from options menu is specified, but function 'mod.suspended()' is not defined", true)
end
else
if mod.unsuspended then
mod.unsuspended()
else
mod:echo("ERROR: suspending from options menu is specified, but function 'mod.unsuspended()' is not defined", true)
end
end
vmf.mod_state_changed(mod_name, is_mod_enabled)
WwiseWorld.trigger_event(self.wwise_world, "Play_hud_select")
@ -3327,7 +3296,7 @@ VMFOptionsView.callback_draw_numeric_menu = function (self, widget_content)
widget_content.wrong_mouse_on_release = nil
end
--vmf:echo("whatever")
-- ####################################################################################################################
-- ##### MISCELLANEOUS: SETTINGS LIST WIDGETS #########################################################################
-- ####################################################################################################################
@ -3452,9 +3421,7 @@ VMFOptionsView.update_picked_option_for_settings_list_widgets = function (self)
elseif widget_type == "header" then
loaded_setting_value = vmf:get("mod_suspend_state_list")
widget_content.is_checkbox_checked = not loaded_setting_value[widget_content.mod_name]
widget_content.is_checkbox_checked = not vmf.disabled_mods_list[widget_content.mod_name]
elseif widget_type == "keybind" then
@ -3516,7 +3483,7 @@ VMFOptionsView.update_settings_list_widgets_visibility = function (self, mod_nam
if widget.content.show_widget_condition then
widget.content.is_widget_visible = widget.content.show_widget_condition[parent_widget.content.current_option_number] and parent_widget.content.is_widget_visible and not parent_widget.content.is_widget_collapsed
else
get_mod(widget.content.mod_name):echo("ERROR: the dropdown widget in the options menu has sub_widgets, but some of its sub_widgets doesn't have 'show_widget_condition' (" .. widget.content.setting_name .. ")" , true)
get_mod(widget.content.mod_name):error("(vmf_options_view): the dropdown widget in the options menu has sub_widgets, but some of its sub_widgets doesn't have 'show_widget_condition' (%s)" , widget.content.setting_name)
end
-- if 'group'
else
@ -3832,26 +3799,11 @@ VMFOptionsView.on_enter = function (self)
self:readjust_visible_settings_list_widgets_position()
end
VMFOptionsView.on_exit = function (self)
WwiseWorld.trigger_event(self.wwise_world, "Play_hud_button_close")
vmf.save_unsaved_settings_to_file()
self.exiting = nil
end
-- IngameUI.handle_menu_hotkeys
-- Will see if I need it when I'll work on keybinds and gui module.
VMFOptionsView.exit = function (self, return_to_game)
vmf:echo("exit!")
local exit_transition = (return_to_game and "exit_menu") or "ingame_menu"
self.ingame_ui:transition_with_fade(exit_transition)
self.exiting = true
end
@ -3910,7 +3862,7 @@ VMFMod.create_options = function (self, widgets_definition, is_mod_toggable, rea
local options_menu_collapsed_widgets = vmf:get("options_menu_collapsed_widgets")
local mod_collapsed_widgets = nil
if options_menu_collapsed_widgets then
mod_collapsed_widgets = options_menu_collapsed_widgets[self._name]
mod_collapsed_widgets = options_menu_collapsed_widgets[self:get_name()]
end
-- defining header widget
@ -3921,19 +3873,19 @@ VMFMod.create_options = function (self, widgets_definition, is_mod_toggable, rea
new_widget_definition.widget_type = "header"
new_widget_definition.widget_index = new_widget_index
new_widget_definition.mod_name = self._name
new_widget_definition.readable_mod_name = readable_mod_name or self._name
new_widget_definition.mod_name = self:get_name()
new_widget_definition.readable_mod_name = readable_mod_name or self:get_name()
new_widget_definition.tooltip = mod_description
new_widget_definition.default = true
new_widget_definition.is_mod_toggable = is_mod_toggable
if mod_collapsed_widgets then
new_widget_definition.is_widget_collapsed = mod_collapsed_widgets[self._name]
new_widget_definition.is_widget_collapsed = mod_collapsed_widgets[self:get_name()]
end
if options_menu_favorite_mods then
for _, current_mod_name in pairs(options_menu_favorite_mods) do
if current_mod_name == self._name then
if current_mod_name == self:get_name() then
new_widget_definition.is_favorited = true
break
end
@ -3968,7 +3920,7 @@ VMFMod.create_options = function (self, widgets_definition, is_mod_toggable, rea
new_widget_definition.widget_type = current_widget.widget_type -- all
new_widget_definition.widget_index = new_widget_index -- all [gen]
new_widget_definition.widget_level = level -- all [gen]
new_widget_definition.mod_name = self._name -- all [gen]
new_widget_definition.mod_name = self:get_name() -- all [gen]
new_widget_definition.setting_name = current_widget.setting_name -- all
new_widget_definition.text = current_widget.text -- all
new_widget_definition.tooltip = current_widget.tooltip -- all [optional]
@ -4052,7 +4004,7 @@ VMFMod.create_options = function (self, widgets_definition, is_mod_toggable, rea
end
if new_widget_index == 257 then
vmf:echo("The limit of 256 options widgets was reached. You can't add any more widgets.")
self:error("(vmf_options_view) The limit of 256 options widgets was reached. You can't add any more widgets.")
end
end
@ -4060,12 +4012,6 @@ VMFMod.create_options = function (self, widgets_definition, is_mod_toggable, rea
end
VMFMod.is_suspended = function (self)
local mod_suspend_state_list = vmf:get("mod_suspend_state_list")
return mod_suspend_state_list[self._name]
end
@ -4100,9 +4046,7 @@ end
if type(vmf:get("mod_suspend_state_list")) ~= "table" then
vmf:set("mod_suspend_state_list", {})
end
if type(vmf:get("options_menu_favorite_mods")) ~= "table" then
vmf:set("options_menu_favorite_mods", {})
@ -4116,49 +4060,9 @@ end
-- If enabled, scale UI for resolutions greater than 1080p when necessary. Reports to a global when active, so that existing scaling can be disabled.
local ui_resolution = UIResolution
local ui_resolution_width_fragments = UIResolutionWidthFragments
local ui_resolution_height_fragments = UIResolutionHeightFragments
local math_min = math.min
local raw_set = rawset
vmf:hook("UIResolutionScale", function (func, ...)
local w, h = ui_resolution()
if (w > ui_resolution_width_fragments() and h > ui_resolution_height_fragments() and vmf:get("auto_hd_ui_scaling")) then
local max_scaling_factor = 4
local width_scale = math_min(w / ui_resolution_width_fragments(), max_scaling_factor) -- Changed to allow scaling up to quadruple the original max scale (1 -> 4)
local height_scale = math_min(h / ui_resolution_height_fragments(), max_scaling_factor) -- Changed to allow scaling up to quadruple the original max scale (1 -> 4)
raw_set(_G, "vmf_hd_ui_scaling_enabled", true)
return math_min(width_scale, height_scale)
else
raw_set(_G, "vmf_hd_ui_scaling_enabled", false)
return func(...)
end
end)
local options_widgets = {
{
["setting_name"] = "open_vmf_options",
["widget_type"] = "keybind",
["text"] = "Open menu hotkey",
["tooltip"] = "Probably keybind",
["default_value"] = {"f5"},
["action"] = "open_vmf_options"
},
{
["setting_name"] = "auto_hd_ui_scaling",
["widget_type"] = "checkbox",
["text"] = "Automatic HD UI Scaling",
["tooltip"] = "Automatic HD UI Scaling" .. "\n\n" ..
"Automatically scale UI when resolution exceeds 1080p.",
["default_value"] = true
}
}
vmf:create_options(options_widgets, false, "Vermintide Mod Framework", ":D")
@ -4210,29 +4114,39 @@ local view_data = {
}
}
-- disables/enables mods options buttons in the
local function change_mods_options_button_state(state)
local ingame_menu_buttons_exist, ingame_menu_buttons = pcall(function () return Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui.ingame_menu.active_button_data end)
if ingame_menu_buttons_exist and type(ingame_menu_buttons) == "table" then
for _, button_info in ipairs(ingame_menu_buttons) do
if button_info.transition == "vmf_options_view" then
button_info.widget.content.disabled = state == "disable"
button_info.widget.content.button_hotspot.disabled = state == "disable"
end
end
end
end
vmf.initialize_vmf_options_view = function ()
vmf:register_new_view(view_data)
change_mods_options_button_state("enable")
end
vmf.disable_mods_options_button = function ()
change_mods_options_button_state("disable")
end
-- create mods options menu button in Esc-menu
vmf:hook("IngameView.setup_button_layout", function (func, self, layout_data)
local mods_options_button = {
display_name = "Mods Options",
display_name = vmf:localize("mods_options"),
transition = "vmf_options_view",
fade = false
}
@ -4257,6 +4171,10 @@ vmf:hook("IngameView.setup_button_layout", function (func, self, layout_data)
button_info.widget.style.text_click.localize = false
button_info.widget.style.text_hover.localize = false
button_info.widget.style.text_selected.localize = false
if not self.ingame_ui.views["vmf_options_view"] then
change_mods_options_button_state("disable")
end
end
end
end)
@ -4269,32 +4187,21 @@ end)
local ingame_ui_exists, ingame_ui = pcall(function () return Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui end)
if ingame_ui_exists then
ingame_ui.handle_transition(ingame_ui, "leave_group")
--ingame_ui.handle_transition(ingame_ui, "leave_group")
vmf:pcall(function()
-- temporary fix:
print("AYYYYY" .. tostring(ingame_ui))
--vmf:dump(ingame_ui.views, "whatever", 1)
local specific_atlas = Managers.state.game_mode._game_mode_key == "inn" and "materials/ui/ui_1080p_ingame_inn" or "materials/ui/ui_1080p_ingame"
end)
---------------------------------------------------
--vmf:echo("I hope it will work!")
--[[
local gui = World.create_screen_gui(ingame_ui.ui_renderer.world, "immediate",
"material",
"materials/ui/end_screen_banners/end_screen_banners",
"material",
"materials/ui/ui_1080p_ingame_common",
"material",
"materials/ui/ui_1080p_ingame_inn",
specific_atlas,
"material",
"materials/ui/ui_1080p_level_images",
"material",
@ -4302,19 +4209,13 @@ local gui = World.create_screen_gui(ingame_ui.ui_renderer.world, "immediate",
"material",
"materials/fonts/gw_fonts",
"material",
"materials/header_background",
"materials/vmf/header_fav_icon",
"material",
"materials/header_background_lit",
"materials/vmf/header_fav_icon_lit",
"material",
"materials/common_widgets_background_lit",
"materials/vmf/header_fav_arrow",
"material",
"materials/header_fav_icon",
"material",
"materials/header_fav_icon_lit",
"material",
"materials/header_fav_arrow",
"material",
"materials/search_bar_icon")
"materials/vmf/search_bar_icon")
local gui_retained = World.create_screen_gui(ingame_ui.ui_renderer.world,
"material",
@ -4322,7 +4223,7 @@ local gui_retained = World.create_screen_gui(ingame_ui.ui_renderer.world,
"material",
"materials/ui/ui_1080p_ingame_common",
"material",
"materials/ui/ui_1080p_ingame_inn",
specific_atlas,
"material",
"materials/ui/ui_1080p_level_images",
"material",
@ -4330,35 +4231,27 @@ local gui_retained = World.create_screen_gui(ingame_ui.ui_renderer.world,
"material",
"materials/fonts/gw_fonts",
"material",
"materials/header_background",
"materials/vmf/header_fav_icon",
"material",
"materials/header_background_lit",
"materials/vmf/header_fav_icon_lit",
"material",
"materials/common_widgets_background_lit",
"materials/vmf/header_fav_arrow",
"material",
"materials/header_fav_icon",
"material",
"materials/header_fav_icon_lit",
"material",
"materials/header_fav_arrow",
"material",
"materials/search_bar_icon")
"materials/vmf/search_bar_icon")
World.destroy_gui(ingame_ui.ui_renderer.world, ingame_ui.ui_renderer.gui)
World.destroy_gui(ingame_ui.ui_renderer.world, ingame_ui.ui_renderer.gui_retained)
ingame_ui.ui_renderer.gui = gui
ingame_ui.ui_renderer.gui_retained = gui_retained
gui = World.create_screen_gui(ingame_ui.ui_top_renderer.world, "immediate",
"material",
"materials/ui/end_screen_banners/end_screen_banners",
"material",
"materials/ui/ui_1080p_ingame_common",
"material",
"materials/ui/ui_1080p_ingame_inn",
specific_atlas,
"material",
"materials/ui/ui_1080p_level_images",
"material",
@ -4366,19 +4259,13 @@ gui = World.create_screen_gui(ingame_ui.ui_top_renderer.world, "immediate",
"material",
"materials/fonts/gw_fonts",
"material",
"materials/header_background",
"materials/vmf/header_fav_icon",
"material",
"materials/header_background_lit",
"materials/vmf/header_fav_icon_lit",
"material",
"materials/common_widgets_background_lit",
"materials/vmf/header_fav_arrow",
"material",
"materials/header_fav_icon",
"material",
"materials/header_fav_icon_lit",
"material",
"materials/header_fav_arrow",
"material",
"materials/search_bar_icon")
"materials/vmf/search_bar_icon")
gui_retained = World.create_screen_gui(ingame_ui.ui_top_renderer.world,
"material",
@ -4386,7 +4273,7 @@ gui_retained = World.create_screen_gui(ingame_ui.ui_top_renderer.world,
"material",
"materials/ui/ui_1080p_ingame_common",
"material",
"materials/ui/ui_1080p_ingame_inn",
specific_atlas,
"material",
"materials/ui/ui_1080p_level_images",
"material",
@ -4394,24 +4281,17 @@ gui_retained = World.create_screen_gui(ingame_ui.ui_top_renderer.world,
"material",
"materials/fonts/gw_fonts",
"material",
"materials/header_background",
"materials/vmf/header_fav_icon",
"material",
"materials/header_background_lit",
"materials/vmf/header_fav_icon_lit",
"material",
"materials/common_widgets_background_lit",
"materials/vmf/header_fav_arrow",
"material",
"materials/header_fav_icon",
"material",
"materials/header_fav_icon_lit",
"material",
"materials/header_fav_arrow",
"material",
"materials/search_bar_icon")
"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

View file

@ -1,49 +1,4 @@
local mod = new_mod("test_mod")
--[[
mod:hook("GenericAmmoUserExtension.update", function(func, self, unit, input, dt, context, t)
func(self, unit, input, dt, context, t)
print("333")
end)
mod:hook_disable("GenericAmmoUserExtension.update")
mod:hook("MatchmakingManager.all_peers_ready", function(func, ...)
--if not mod:is_suspended() then
-- return true
--else
-- return func(...)
--end
mod:echo("whatever")
return true
end)
mod:disable_all_hooks()
]]
--[[
--mod:hook_enable("GenericAmmoUserExtension.update")
--mod:hook_disable("GenericAmmoUserExtension.update")
--mod:hook_remove("GenericAmmoUserExtension.update")
mod:hook("MatchmakingManager.update", function(func, ...)
func(...)
print("555")
end)
--]]
--mod:disable_all_hooks()
--mod:enable_all_hooks()
--mod:remove_all_hooks()
--mod:hook_remove("GenericAmmoUserExtension.update")
--mod:hook_remove("MatchmakingManager.update")
--table.dump(HOOKED_FUNCTIONS, "HOOKED_FUNCTIONS", 3)
--mod.unload = function()
-- print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
--end
--mod:pcall(function()
-- return assert(loadstring("return bla.bla"))()
-- end)
local options_widgets = {
{
@ -95,9 +50,17 @@ local options_widgets = {
["widget_type"] = "keybind",
["text"] = "Some keybind",
["tooltip"] = "Probably keybind",
["default_value"] = {"f", "ctrl"},
["default_value"] = {"g", "ctrl"},
["action"] = "whatever"
},
{
["setting_name"] = "the_keybind2",
["widget_type"] = "keybind",
["text"] = "Some keybind [toggle]",
["tooltip"] = "Probably keybind",
["default_value"] = {"f", "ctrl"},
["action"] = "toggle_mod"
},
{
["setting_name"] = "game_mode2",
["widget_type"] = "dropdown",
@ -144,13 +107,17 @@ local options_widgets = {
}
}
mod:create_options(options_widgets, true, "Test", "Mod description")
--mod:create_options(options_widgets, true, "Test", "Mod description")
-- chat_broadcast
mod.whatever = function ()
mod:echo("whatever")
end
mod.game_state_changed = function ()
--mod:echo("whatever" .. nil)
end
--[[
mod:hook("KeystrokeHelper.parse_strokes", function(func, text, index, mode, keystrokes)
print(tostring(text) .. " " .. tostring(index) .. " " .. tostring(mode) .. " " .. tostring(keystrokes))
@ -257,19 +224,14 @@ end)
mod:echo("YAY")
end]]
--[[
local mod = new_mod("test_mod2")
mod:create_options(options_widgets, true, "Bots Improvements", "Mod description")
local mod2 = new_mod("SkipSplashScreen")
local mod = new_mod("test_mod3")
mod:create_options(options_widgets, true, "Show Healhbars", "Mod description")
mod2:hook("StateSplashScreen.on_enter", function(func, self)
self._skip_splash = true
func(self)
end)
local mod = new_mod("test_mod4")
mod:create_options(options_widgets, true, "Ammo Meter", "Mod description")
local mod = new_mod("test_mod5")
mod:create_options(options_widgets, true, "Show Damage", "Mod description")
local mod = new_mod("test_mod6")
mod:create_options(options_widgets, true, "Kick & Ban", "Mod description")
]]
mod2:hook("StateSplashScreen.setup_splash_screen_view", function(func, self)
func(self)
self.splash_view = nil
end)

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

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 = {
run = function()
return dofile("scripts/mods/vmf/vmf_loader")
end,
packages = {
"resource_packages/vmf"
},
}
}
return ret