Added VT2 compatibility; updated project the last VMB version

This commit is contained in:
bi 2018-05-05 19:07:40 +03:00
parent 4853ebccf4
commit 1615ec1598
17 changed files with 539 additions and 136 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
.temp .temp
.vscode
vmf/dist vmf/dist

View file

@ -1,4 +1,13 @@
1) Clone project somewhere # Building
2) Make a hardlink of SDK bin folder inside cloned project
`mklink /J "C:\Vermintide\VMF_SDK\bin" "C:\Program Files (x86)\Steam\steamapps\common\Warhammer End Times Vermintide Mod Tools\bin"` ## Prerequisites
3) Run .bat-file every time you need to compile project - You should be subscribed to VMF in Steam Workshop [[VT1](https://steamcommunity.com/sharedfiles/filedetails/?id=1289946781), [VT2](https://steamcommunity.com/sharedfiles/filedetails/?id=1369573612)], depending on which version you want to compile.
- You will also need [Vermintide Mod Builder](https://github.com/Vermintide-Mod-Framework/Vermintide-Mod-Builder).
## Building steps:
1. Unpack VMB somewhere. Let's assume, it's unpacked into the folder named `vermintide-mod-builer`.
2. Create a folder inside `vermintide-mod-builer` (we'll call it `vermintide-mod-framework`) and then clone VMF repo into this folder.
3. Open console window inside `vermintide-mod-builer` and use following command to build VMF: `vmb build vmf -f vermintide-mod-framework --ignore-errors -g [1/2]`, where number after `-g` indicates the Vermintide game number for which VMF is built.
You can find more information on how mod building works in Vermintide Mod Builder documentation.

View file

@ -1,76 +0,0 @@
@setlocal enableextensions
@echo off
:: project-defined variable, you probably shouldn't change them
set SOUCE_CODE_DIR=.\vmf
set TEMP_DIR=.\.temp\vmf
set ORIGINAL_VMF_BUNDLE_FILE_NAME=98161451961848df
set NEW_VMF_BUNDLE_FILE_NAME=VMF
:: manual setting pathes (in case this batch file won't be able to find steam installation folders) [you can change them :D]
set MANUAL_MODS_DIR=C:\Program Files (x86)\Steam\steamapps\workshop\content\235540\1289946781
set MANUAL_STINGRAY_EXE=C:\Program Files (x86)\Steam\steamapps\common\Warhammer End Times Vermintide Mod Tools\bin\stingray_win64_dev_x64.exe
:: find Vermintide folder
set KEY_NAME="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 235540"
set VALUE_NAME=InstallLocation
for /F "usebackq skip=2 tokens=1-2*" %%A in (`REG QUERY %KEY_NAME% /v %VALUE_NAME% 2^>nul`) do (
set MODS_DIR=%%C\..\..\workshop\content\235540\1289946781
)
:: find Stingray SDK folder
set KEY_NAME="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 718610"
set VALUE_NAME=InstallLocation
FOR /F "usebackq skip=2 tokens=1-2*" %%A in (`REG QUERY %KEY_NAME% /v %VALUE_NAME% 2^>nul`) do (
set STINGRAY_EXE=%%C\bin\stingray_win64_dev_x64.exe
)
:: checking if Vermintide mods folder and Sringray binary exist
if not exist "%MODS_DIR%" set MODS_DIR=%MANUAL_MODS_DIR%
if not exist "%MODS_DIR%" (
echo ERROR: Vermintide install location not found. Script execution aborted.
pause
exit
)
if not exist "%STINGRAY_EXE%" set MODS_DIR=%MANUAL_STINGRAY_EXE%
if not exist "%STINGRAY_EXE%" (
echo ERROR: stingray_win64_dev_x64.exe not found. Script execution aborted.
pause
exit
)
::compiling
echo Starting...
"%STINGRAY_EXE%" --compile-for win32 --source-dir "%SOUCE_CODE_DIR%" --data-dir "%TEMP_DIR%\compile" --bundle-dir "%TEMP_DIR%\bundle"
echo Done.
::moving compiled file to the mods directory (overwritting if needed)
move /y %TEMP_DIR%\bundle\*. "%MODS_DIR%"
::if ORIGINAL_VMF_BUNDLE_FILE_NAME and NEW_VMF_BUNDLE_FILE_NAME specified, delete the old renamed file and rename the new one
if not "%ORIGINAL_VMF_BUNDLE_FILE_NAME%"== "" ^
if not "%NEW_VMF_BUNDLE_FILE_NAME%"== "" ^
if exist "%MODS_DIR%\%NEW_VMF_BUNDLE_FILE_NAME%" ^
del "%MODS_DIR%\%NEW_VMF_BUNDLE_FILE_NAME%"
if not "%ORIGINAL_VMF_BUNDLE_FILE_NAME%"== "" ^
if not "%NEW_VMF_BUNDLE_FILE_NAME%"== "" ^
ren "%MODS_DIR%\%ORIGINAL_VMF_BUNDLE_FILE_NAME%" "%NEW_VMF_BUNDLE_FILE_NAME%"
pause

Binary file not shown.

View file

@ -3,5 +3,5 @@ description = "My Description";
preview = "preview.jpg"; preview = "preview.jpg";
content = "dist"; content = "dist";
language = "english"; language = "english";
visibility = "private"; visibility = "public";
published_id = 1289946781L; published_id = 1289946781L;

7
vmf/itemV2.cfg Normal file
View file

@ -0,0 +1,7 @@
title = "Vermintide Mod Framework";
description = "My Description";
preview = "preview.jpg";
content = "dist";
language = "english";
visibility = "public";
published_id = 1369573612L;

View file

@ -1,6 +1,6 @@
return { return {
mods_options = { mods_options = {
en = "Mods Options", en = "Mod Options",
ru = "Настройки модов", ru = "Настройки модов",
}, },
open_vmf_options = { open_vmf_options = {

View file

@ -51,6 +51,7 @@ VMFMod.echo = function (self, message, ...)
message = safe_format(self, message, ...) message = safe_format(self, message, ...)
if message then if message then
if _LOGGING_SETTINGS.echo.send_to_chat then if _LOGGING_SETTINGS.echo.send_to_chat then
send_to_chat(message) send_to_chat(message)
end end
@ -197,11 +198,11 @@ vmf.unsent_chat_messages = _UNSENT_CHAT_MESSAGES
vmf.load_logging_settings = function () vmf.load_logging_settings = function ()
_LOGGING_SETTINGS = { _LOGGING_SETTINGS = {
echo = vmf:get("logging_mode") == "custom" and vmf:get("output_mode_echo"),-- or 3, @TODO: clean up? echo = vmf:get("logging_mode") == "custom" and vmf:get("output_mode_echo") or 3, -- @TODO: clean up?
error = vmf:get("logging_mode") == "custom" and vmf:get("output_mode_error"),-- 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, 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, info = vmf:get("logging_mode") == "custom" and vmf:get("output_mode_info") or 1,
debug = vmf:get("logging_mode") == "custom" and vmf:get("output_mode_debug"),-- or 0, debug = vmf:get("logging_mode") == "custom" and vmf:get("output_mode_debug") or 0,
} }
for method_name, logging_mode in pairs(_LOGGING_SETTINGS) do for method_name, logging_mode in pairs(_LOGGING_SETTINGS) do

View file

@ -49,7 +49,7 @@ vmf.mods_update_event = function(dt)
end end
-- call 'on_game_state_changed' for every mod which defined it -- call 'on_game_state_changed' for every mod which defined it
vmf.mods_game_state_changed_event = function(status, state) vmf.mods_game_state_changed_event = function(status, state_name)
local event_name = "on_game_state_changed" local event_name = "on_game_state_changed"
@ -57,7 +57,7 @@ vmf.mods_game_state_changed_event = function(status, state)
local event = mod[event_name] local event = mod[event_name]
if event then if event then
run_event(mod, event_name, event, status, state) run_event(mod, event_name, event, status, state_name)
end end
end end
end end

View file

@ -34,7 +34,7 @@ VMFMod.initialize_data = function (self, mod_data)
self._data.is_mutator = mod_data.is_mutator self._data.is_mutator = mod_data.is_mutator
if mod_data.is_mutator then if mod_data.is_mutator then
vmf.register_mod_as_mutator(self, mod_data.mutator_setting) vmf.register_mod_as_mutator(self, mod_data.mutator_settings)
end end
if mod_data.options_widgets or (mod_data.is_togglable and not mod_data.is_mutator) then if mod_data.options_widgets or (mod_data.is_togglable and not mod_data.is_mutator) then

View file

@ -30,7 +30,15 @@ VMFMod.register_new_view = function (self, new_view_data)
-- so the menu will open when the keybind is pressed -- so the menu will open when the keybind is pressed
self[new_view_data.view_settings.hotkey_action_name] = function() self[new_view_data.view_settings.hotkey_action_name] = function()
if not closing_keybind_is_pressed and ingame_ui and not ingame_ui:pending_transition() and not ingame_ui:end_screen_active() and not ingame_ui.menu_active and not ingame_ui.leave_game and not ingame_ui.return_to_title_screen and not ingame_ui.popup_join_lobby_handler.visible then if not closing_keybind_is_pressed
and ingame_ui
and not ingame_ui:pending_transition()
and not ingame_ui:end_screen_active()
and not ingame_ui.menu_active
and not ingame_ui.leave_game
and not ingame_ui.return_to_title_screen
and not (ingame_ui.popup_join_lobby_handler and ingame_ui.popup_join_lobby_handler.visible) -- V2 doesn't have 'popup_join_lobby_handler'
then
ingame_ui:handle_transition(new_view_data.view_settings.hotkey_transition_name) ingame_ui:handle_transition(new_view_data.view_settings.hotkey_transition_name)
end end
@ -177,10 +185,15 @@ end
-- ##### Script ####################################################################################################### -- ##### Script #######################################################################################################
-- #################################################################################################################### -- ####################################################################################################################
-- if reloading mods
if not ingame_ui then local ingame_ui_exists, ingame_ui_return
local ingame_ui_exists, ingame_ui_return = pcall(function () return Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui end) if VT1 then
ingame_ui_exists, ingame_ui_return = pcall(function () return Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui end)
else
ingame_ui_exists, ingame_ui_return = pcall(function () return Managers.player.network_manager.matchmaking_manager._ingame_ui end)
end
-- if VMF is reloaded mid-game
if ingame_ui_exists then if ingame_ui_exists then
ingame_ui = ingame_ui_return ingame_ui = ingame_ui_return
end end
end

View file

@ -4,7 +4,7 @@ local mod_data = {}
mod_data.name = "Test" mod_data.name = "Test"
mod_data.description = "Test mod description" mod_data.description = "Test mod description"
mod_data.is_togglable = true mod_data.is_togglable = true
--mod_data.mutator_setting = nil --mod_data.mutator_settings = nil
mod_data.options_widgets = { mod_data.options_widgets = {
{ {
["setting_name"] = "game_mode", ["setting_name"] = "game_mode",
@ -64,7 +64,7 @@ mod_data.options_widgets = {
["text"] = "Some keybind [toggle]", ["text"] = "Some keybind [toggle]",
["tooltip"] = "Probably keybind", ["tooltip"] = "Probably keybind",
["default_value"] = {"f", "ctrl"}, ["default_value"] = {"f", "ctrl"},
["action"] = "toggle_mod" ["action"] = "toggle_mod_state"
}, },
{ {
["setting_name"] = "game_mode2", ["setting_name"] = "game_mode2",
@ -134,12 +134,9 @@ mod:command("test", "short command description\n params: [parameter1] [parameter
-- for serialization: -- for serialization:
-- table.maxn (table) -- table.maxn (table)
mod.whatever = function () mod.whatever = function ()
--mod:echo("whatever") --mod:echo("whatever")
--mod:dtf(Boot, "Boot", 5)
--[[ --[[
mod:pcall(function() mod:pcall(function()
@ -162,9 +159,11 @@ mod.whatever = function ()
--mod:network_send("rpc_whatever", "all", 1, "yay", true, nil, {4, 5}) --mod:network_send("rpc_whatever", "all", 1, "yay", true, nil, {4, 5})
--[[
mod:pcall(function() mod:pcall(function()
RPC.rpc_play_simple_particle_with_vector_variable(Managers.player:local_player().peer_id, 27, Vector3(-3.72465, -1.52876, 2.02713), 32, Vector3(5, 1, 1)) RPC.rpc_play_simple_particle_with_vector_variable(Managers.player:local_player().peer_id, 27, Vector3(-3.72465, -1.52876, 2.02713), 32, Vector3(5, 1, 1))
end) end)
]]
--mod.simulate(1, "yay", true, Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui.wwise_world, {4, 5}) --mod.simulate(1, "yay", true, Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui.wwise_world, {4, 5})

View file

@ -34,6 +34,12 @@ local function clean_chat_history()
_CHAT_HISTORY_INDEX = 0 _CHAT_HISTORY_INDEX = 0
end end
local function set_chat_message(chat_gui, message)
chat_gui.chat_message = message
chat_gui.chat_index = KeystrokeHelper.num_utf8chars(chat_gui.chat_message) + 1
chat_gui.chat_input_widget.content.text_index = 1
end
-- #################################################################################################################### -- ####################################################################################################################
-- ##### Hooks ######################################################################################################## -- ##### Hooks ########################################################################################################
-- #################################################################################################################### -- ####################################################################################################################
@ -98,7 +104,8 @@ vmf:hook("ChatGui._update_input", function(func, self, input_service, menu_input
_COMMANDS_LIST = {} _COMMANDS_LIST = {}
_COMMAND_INDEX = 0 _COMMAND_INDEX = 0
self.chat_message = "" set_chat_message(self, "")
command_executed = true command_executed = true
end end
end end
@ -108,7 +115,7 @@ vmf:hook("ChatGui._update_input", function(func, self, input_service, menu_input
local chat_focused, chat_closed, chat_close_time = func(self, input_service, menu_input_service, dt, no_unblock, chat_enabled) local chat_focused, chat_closed, chat_close_time = func(self, input_service, menu_input_service, dt, no_unblock, chat_enabled)
if chat_closed then if chat_closed then
self.chat_message = "" set_chat_message(self, "")
_CHAT_OPENED = false _CHAT_OPENED = false
@ -141,6 +148,12 @@ vmf:hook("ChatGui._update_input", function(func, self, input_service, menu_input
-- chat history -- chat history
if _CHAT_HISTORY_ENABLED then if _CHAT_HISTORY_ENABLED then
-- reverse result of native chat history in VT2
if not VT1 and input_service.get(input_service, "chat_next_old_message") or input_service.get(input_service, "chat_previous_old_message") then
set_chat_message(self, old_chat_message)
end
-- message was modified by player -- message was modified by player
if self.chat_message ~= self.previous_chat_message then if self.chat_message ~= self.previous_chat_message then
_CHAT_HISTORY_INDEX = 0 _CHAT_HISTORY_INDEX = 0
@ -153,16 +166,13 @@ vmf:hook("ChatGui._update_input", function(func, self, input_service, menu_input
if _CHAT_HISTORY_INDEX ~= new_index then if _CHAT_HISTORY_INDEX ~= new_index then
if _CHAT_HISTORY[new_index] then if _CHAT_HISTORY[new_index] then
self.chat_message = _CHAT_HISTORY[new_index] set_chat_message(self, _CHAT_HISTORY[new_index])
self.chat_index = KeystrokeHelper.num_utf8chars(self.chat_message) + 1
self.chat_input_widget.content.text_index = 1
self.previous_chat_message = self.chat_message self.previous_chat_message = self.chat_message
_CHAT_HISTORY_INDEX = new_index _CHAT_HISTORY_INDEX = new_index
else -- new_index == 0 else -- new_index == 0
self.chat_message = "" set_chat_message(self, "")
self.chat_index = 1
end end
end end
end end
@ -170,8 +180,8 @@ vmf:hook("ChatGui._update_input", function(func, self, input_service, menu_input
-- ctrl + v -- ctrl + v
if Keyboard.pressed(Keyboard.button_index("v")) and Keyboard.button(Keyboard.button_index("left ctrl")) == 1 then if Keyboard.pressed(Keyboard.button_index("v")) and Keyboard.button(Keyboard.button_index("left ctrl")) == 1 then
self.chat_message = self.chat_message .. tostring(Clipboard.get()):gsub(string.char(0x0D), "") -- remove CR characters local new_chat_message = self.chat_message .. tostring(Clipboard.get()):gsub(string.char(0x0D), "") -- remove CR characters
self.chat_index = KeystrokeHelper.num_utf8chars(self.chat_message) + 1 set_chat_message(self, new_chat_message)
end end
-- ctrl + c -- ctrl + c
@ -189,8 +199,7 @@ vmf:hook("ChatGui._update_input", function(func, self, input_service, menu_input
_COMMAND_INDEX = _COMMAND_INDEX % #_COMMANDS_LIST + 1 _COMMAND_INDEX = _COMMAND_INDEX % #_COMMANDS_LIST + 1
self.chat_message = "/" .. _COMMANDS_LIST[_COMMAND_INDEX].name set_chat_message(self, "/" .. _COMMANDS_LIST[_COMMAND_INDEX].name)
self.chat_index = KeystrokeHelper.num_utf8chars(self.chat_message) + 1
-- so the next block won't update the commands list -- so the next block won't update the commands list
old_chat_message = self.chat_message old_chat_message = self.chat_message

View file

@ -1,6 +1,16 @@
local vmf = get_mod("VMF") --@TODO: remove it? local vmf = get_mod("VMF") --@TODO: remove it?
local _GUI = World.create_screen_gui(Managers.world:world("top_ingame_view"), "immediate", "material", "materials/fonts/gw_fonts", "material", "materials/ui/ui_1080p_ingame_common") local _GUI
if VT1 then
-- @TODO: I don't think I need the 2nd texture
_GUI = World.create_screen_gui(Managers.world:world("top_ingame_view"), "immediate", "material", "materials/fonts/gw_fonts", "material", "materials/ui/ui_1080p_ingame_common")
else
_GUI = World.create_screen_gui(Managers.world:world("top_ingame_view"), "material", "materials/fonts/gw_fonts", "immediate")
end
-- DebugScreen.gui = World.create_screen_gui(world, "material", "materials/fonts/gw_fonts", "material", "materials/menu/debug_screen", "immediate")
local _FONT_TYPE = "hell_shark_arial" local _FONT_TYPE = "hell_shark_arial"
local _FONT_SIZE = 22 local _FONT_SIZE = 22

View file

@ -105,6 +105,399 @@ local scenegraph_definition = {
} }
local function create_scrollbar(height, scenegraph_id)
return {
element = {
passes = {
{
pass_type = "texture",
style_id = "scroll_bar_bottom",
texture_id = "scroll_bar_bottom",
content_check_function = function (content)
return not content.disable_frame
end
},
{
pass_type = "texture",
style_id = "scroll_bar_bottom_bg",
texture_id = "scroll_bar_bottom_bg",
content_check_function = function (content)
return not content.disable_frame
end
},
{
pass_type = "tiled_texture",
style_id = "scroll_bar_middle",
texture_id = "scroll_bar_middle",
content_check_function = function (content)
return not content.disable_frame
end
},
{
pass_type = "tiled_texture",
style_id = "scroll_bar_middle_bg",
texture_id = "scroll_bar_middle_bg",
content_check_function = function (content)
return not content.disable_frame
end
},
{
pass_type = "texture",
style_id = "scroll_bar_top",
texture_id = "scroll_bar_top",
content_check_function = function (content)
return not content.disable_frame
end
},
{
pass_type = "texture",
style_id = "scroll_bar_top_bg",
texture_id = "scroll_bar_top_bg",
content_check_function = function (content)
return not content.disable_frame
end
},
{
style_id = "button_down",
pass_type = "hotspot",
content_id = "button_down_hotspot"
},
{
style_id = "button_up",
pass_type = "hotspot",
content_id = "button_up_hotspot"
},
{
pass_type = "local_offset",
offset_function = function (ui_scenegraph, ui_style, ui_content, input_service)
local scroll_bar_info = ui_content.scroll_bar_info
local scroll_bar_box = ui_style.scroll_bar_box
local scroll_size_y = scroll_bar_box.scroll_size_y
local percentage = math.max(scroll_bar_info.bar_height_percentage, 0.05)
scroll_bar_box.size[2] = scroll_size_y * percentage
local button_up_hotspot = ui_content.button_up_hotspot
if button_up_hotspot.is_hover and button_up_hotspot.is_clicked == 0 then
ui_content.button_up = "scroll_bar_button_up_clicked"
else
ui_content.button_up = "scroll_bar_button_up"
end
local button_down_hotspot = ui_content.button_down_hotspot
if button_down_hotspot.is_hover and button_down_hotspot.is_clicked == 0 then
ui_content.button_down = "scroll_bar_button_down_clicked"
else
ui_content.button_down = "scroll_bar_button_down"
end
local button_scroll_step = ui_content.button_scroll_step or 0.1
if button_up_hotspot.on_release then
local size_y = scroll_bar_box.size[2]
local scroll_size_y = scroll_bar_box.scroll_size_y
local start_y = scroll_bar_box.start_offset[2]
local end_y = (start_y + scroll_size_y) - size_y
local step = size_y / (start_y + end_y)
scroll_bar_info.value = math.max(scroll_bar_info.value - button_scroll_step, 0)
elseif button_down_hotspot.on_release then
local size_y = scroll_bar_box.size[2]
local scroll_size_y = scroll_bar_box.scroll_size_y
local start_y = scroll_bar_box.start_offset[2]
local end_y = (start_y + scroll_size_y) - size_y
local step = size_y / (start_y + end_y)
scroll_bar_info.value = math.min(scroll_bar_info.value + button_scroll_step, 1)
end
return
end
},
{
pass_type = "texture",
style_id = "button_down",
texture_id = "button_down"
},
{
pass_type = "texture",
style_id = "button_up",
texture_id = "button_up"
},
{
style_id = "scroll_bar_box",
pass_type = "hotspot",
content_id = "scroll_bar_info"
},
{
style_id = "scroll_bar_box",
pass_type = "held",
content_id = "scroll_bar_info",
held_function = function (ui_scenegraph, ui_style, ui_content, input_service)
local cursor = UIInverseScaleVectorToResolution(input_service.get(input_service, "cursor"))
local cursor_y = cursor[2]
local world_pos = UISceneGraph.get_world_position(ui_scenegraph, ui_content.scenegraph_id)
local world_pos_y = world_pos[2]
local offset = ui_style.offset
local scroll_box_start = world_pos_y + offset[2]
local cursor_y_norm = cursor_y - scroll_box_start
if not ui_content.click_pos_y then
ui_content.click_pos_y = cursor_y_norm
end
local click_pos_y = ui_content.click_pos_y
local delta = cursor_y_norm - click_pos_y
local start_y = ui_style.start_offset[2]
local end_y = (start_y + ui_style.scroll_size_y) - ui_style.size[2]
local offset_y = math.clamp(offset[2] + delta, start_y, end_y)
local scroll_size = end_y - start_y
local scroll = end_y - offset_y
ui_content.value = (scroll ~= 0 and scroll / scroll_size) or 0
return
end,
release_function = function (ui_scenegraph, ui_style, ui_content, input_service)
ui_content.click_pos_y = nil
return
end
},
{
pass_type = "local_offset",
content_id = "scroll_bar_info",
offset_function = function (ui_scenegraph, ui_style, ui_content, input_service)
local box_style = ui_style.scroll_bar_box
local box_size_y = box_style.size[2]
local start_y = box_style.start_offset[2]
local end_y = (start_y + box_style.scroll_size_y) - box_size_y
local scroll_size = end_y - start_y
local value = ui_content.value
local offset_y = start_y + scroll_size * (1 - value)
box_style.offset[2] = offset_y
local box_bottom = ui_style.scroll_bar_box_bottom
local box_middle = ui_style.scroll_bar_box_middle
local box_top = ui_style.scroll_bar_box_top
local box_bottom_size_y = box_bottom.size[2]
local box_top_size_y = box_top.size[2]
box_bottom.offset[2] = offset_y
box_top.offset[2] = (offset_y + box_size_y) - box_top_size_y
box_middle.offset[2] = offset_y + box_bottom_size_y
box_middle.size[2] = box_size_y - box_bottom_size_y - box_top_size_y
return
end
},
{
pass_type = "texture",
style_id = "scroll_bar_box_bottom",
texture_id = "scroll_bar_box_bottom"
},
{
pass_type = "tiled_texture",
style_id = "scroll_bar_box_middle",
texture_id = "scroll_bar_box_middle"
},
{
pass_type = "texture",
style_id = "scroll_bar_box_top",
texture_id = "scroll_bar_box_top"
}
}
},
content = {
scroll_bar_bottom_bg = "scroll_bar_bottom_bg",
scroll_bar_top_bg = "scroll_bar_top_bg",
scroll_bar_middle = "scroll_bar_middle",
button_up = "scroll_bar_button_up",
scroll_bar_box_bottom = "scroll_bar_box_bottom",
scroll_bar_middle_bg = "scroll_bar_middle_bg",
scroll_bar_bottom = "scroll_bar_bottom",
disable_frame = false,
scroll_bar_box_middle = "scroll_bar_box_middle",
scroll_bar_box_top = "scroll_bar_box_top",
button_down = "scroll_bar_button_down",
scroll_bar_top = "scroll_bar_top",
scroll_bar_info = {
button_scroll_step = 0.1,
value = 0,
bar_height_percentage = 1,
scenegraph_id = scenegraph_id
},
button_up_hotspot = {},
button_down_hotspot = {}
},
style = {
scroll_bar_bottom = {
size = {
26,
116
}
},
scroll_bar_bottom_bg = {
offset = {
0,
0,
-1
},
size = {
26,
116
}
},
scroll_bar_middle = {
offset = {
0,
116,
0
},
size = {
26,
height - 232
},
texture_tiling_size = {
26,
44
}
},
scroll_bar_middle_bg = {
offset = {
0,
116,
-1
},
size = {
26,
height - 232
},
texture_tiling_size = {
26,
44
}
},
scroll_bar_top = {
offset = {
0,
height - 116,
0
},
size = {
26,
116
}
},
scroll_bar_top_bg = {
offset = {
0,
height - 116,
-1
},
size = {
26,
116
}
},
button_down = {
offset = {
5,
4,
0
},
size = {
16,
18
}
},
button_up = {
offset = {
5,
height - 22,
0
},
size = {
16,
18
}
},
scroll_bar_box = {
offset = {
4,
22,
100
},
size = {
18,
height - 44
},
color = {
255,
255,
255,
255
},
start_offset = {
4,
22,
0
},
scroll_size_y = height - 44
},
scroll_bar_box_bottom = {
offset = {
4,
0,
0
},
size = {
18,
8
}
},
scroll_bar_box_middle = {
offset = {
4,
0,
0
},
size = {
18,
26
},
texture_tiling_size = {
18,
26
}
},
scroll_bar_box_top = {
offset = {
4,
0,
0
},
size = {
18,
8
}
}
},
scenegraph_id = scenegraph_id
}
end
--███╗ ███╗███████╗███╗ ██╗██╗ ██╗ ██╗ ██╗██╗██████╗ ██████╗ ███████╗████████╗███████╗ --███╗ ███╗███████╗███╗ ██╗██╗ ██╗ ██╗ ██╗██╗██████╗ ██████╗ ███████╗████████╗███████╗
--████╗ ████║██╔════╝████╗ ██║██║ ██║ ██║ ██║██║██╔══██╗██╔════╝ ██╔════╝╚══██╔══╝██╔════╝ --████╗ ████║██╔════╝████╗ ██║██║ ██║ ██║ ██║██║██╔══██╗██╔════╝ ██╔════╝╚══██╔══╝██╔════╝
--██╔████╔██║█████╗ ██╔██╗ ██║██║ ██║ ██║ █╗ ██║██║██║ ██║██║ ███╗█████╗ ██║ ███████╗ --██╔████╔██║█████╗ ██╔██╗ ██║██║ ██║ ██║ █╗ ██║██║██║ ██║██║ ███╗█████╗ ██║ ███████╗
@ -293,7 +686,7 @@ local menu_widgets_definition = {
} }
}, },
scrollbar = UIWidgets.create_scrollbar(scenegraph_definition.sg_scrollbar.size[2], "sg_scrollbar") scrollbar = create_scrollbar(scenegraph_definition.sg_scrollbar.size[2], "sg_scrollbar")
} }
-- @TODO: make scrollbar full windowed o_O -- @TODO: make scrollbar full windowed o_O
@ -3789,6 +4182,8 @@ end
VMFOptionsView.on_enter = function (self) VMFOptionsView.on_enter = function (self)
if ShowCursorStack.stack_depth == 0 then ShowCursorStack.push() end
local input_manager = self.input_manager local input_manager = self.input_manager
input_manager.block_device_except_service(input_manager, "vmf_options_menu", "keyboard", 1) input_manager.block_device_except_service(input_manager, "vmf_options_menu", "keyboard", 1)
input_manager.block_device_except_service(input_manager, "vmf_options_menu", "mouse", 1) input_manager.block_device_except_service(input_manager, "vmf_options_menu", "mouse", 1)
@ -3806,6 +4201,9 @@ 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")
-- in VT1 cursor will be romover automatically
if not VT1 then ShowCursorStack.pop() end
vmf.save_unsaved_settings_to_file() vmf.save_unsaved_settings_to_file()
end end
@ -4085,7 +4483,7 @@ local view_data = {
}, },
hotkey_name = "open_vmf_options", hotkey_name = "open_vmf_options",
hotkey_action_name = "open_vmf_options", hotkey_action_name = "open_vmf_options",
hotkey_transition_name = "vmf_options_view_force", hotkey_transition_name = "vmf_options_view",
transition_fade = false transition_fade = false
}, },
view_transitions = { view_transitions = {
@ -4097,6 +4495,7 @@ local view_data = {
end, end,
vmf_options_view_force = function (self) vmf_options_view_force = function (self)
ShowCursorStack.push() ShowCursorStack.push()
self.current_view = "vmf_options_view" self.current_view = "vmf_options_view"
@ -4107,18 +4506,42 @@ local view_data = {
} }
} }
if not V1 and not IngameView.umoes_is_hooked then
local umoes_original_function = IngameView.update_menu_options_enabled_states
IngameView.update_menu_options_enabled_states = function(self)
umoes_original_function(self)
if self.active_button_data then
for _, menu_option in ipairs(self.active_button_data) do
if menu_option.transition == "vmf_options_view" then
menu_option.widget.content.button_hotspot.disable_button = menu_option.widget.content.button_hotspot.disabled
end
end
end
end
IngameView.umoes_is_hooked = true
end
-- disables/enables mods options buttons in the -- disables/enables mods options buttons in the
local function change_mods_options_button_state(state) 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) local ingame_menu_buttons_exist, ingame_menu_buttons
if VT1 then
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)
else
ingame_menu_buttons_exist, ingame_menu_buttons = pcall(function () return Managers.player.network_manager.matchmaking_manager._ingame_ui.views.ingame_menu.active_button_data end)
end
if ingame_menu_buttons_exist and type(ingame_menu_buttons) == "table" then if ingame_menu_buttons_exist and type(ingame_menu_buttons) == "table" then
for _, button_info in ipairs(ingame_menu_buttons) do for _, button_info in ipairs(ingame_menu_buttons) do
if button_info.transition == "vmf_options_view" then if button_info.transition == "vmf_options_view" then
button_info.widget.content.disabled = state == "disable" -- it's enough to enable/disable buttons in V1, but it doesn't do anything in V2
button_info.widget.content.button_hotspot.disabled = state == "disable" -- there is special hook for V2 that updates button state every tick
-- and it uses this value to figure out if button is enabled
button_info.widget.content.disabled = (state == "disable")
button_info.widget.content.button_hotspot.disabled = (state == "disable")
end end
end end
end end
@ -4127,7 +4550,6 @@ end
vmf.initialize_vmf_options_view = function () vmf.initialize_vmf_options_view = function ()
vmf:register_new_view(view_data) vmf:register_new_view(view_data)
change_mods_options_button_state("enable") change_mods_options_button_state("enable")
end end
@ -4146,9 +4568,7 @@ vmf:hook("IngameView.setup_button_layout", function (func, self, layout_data)
} }
for i, button_info in ipairs(layout_data) do for i, button_info in ipairs(layout_data) do
if button_info.transition == "options_menu" then if button_info.transition == "options_menu" then
table.insert(layout_data, i + 1, mods_options_button) table.insert(layout_data, i + 1, mods_options_button)
break break
end end
@ -4157,14 +4577,19 @@ vmf:hook("IngameView.setup_button_layout", function (func, self, layout_data)
func(self, layout_data) func(self, layout_data)
for _, button_info in ipairs(self.active_button_data) do for _, button_info in ipairs(self.active_button_data) do
if button_info.transition == "vmf_options_view" then if button_info.transition == "vmf_options_view" then
if VT1 then
button_info.widget.style.text.localize = false button_info.widget.style.text.localize = false
button_info.widget.style.text_disabled.localize = false button_info.widget.style.text_disabled.localize = false
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
else
button_info.widget.style.title_text.localize = false
button_info.widget.style.title_text_disabled.localize = false
button_info.widget.style.title_text_shadow.localize = false
end
if not self.ingame_ui.views["vmf_options_view"] then if not self.ingame_ui.views["vmf_options_view"] then
change_mods_options_button_state("disable") change_mods_options_button_state("disable")

View file

@ -1,3 +1,5 @@
VT1 = true
return { return {
init = function(object) init = function(object)
@ -26,7 +28,7 @@ return {
dofile("scripts/mods/vmf/modules/ui/options/vmf_options_view") dofile("scripts/mods/vmf/modules/ui/options/vmf_options_view")
dofile("scripts/mods/vmf/modules/vmf_options") dofile("scripts/mods/vmf/modules/vmf_options")
dofile("scripts/mods/vmf/modules/ui/mutators/mutator_manager") if VT1 then dofile("scripts/mods/vmf/modules/ui/mutators/mutator_manager") end
object.vmf = get_mod("VMF") object.vmf = get_mod("VMF")
@ -36,6 +38,9 @@ return {
func(self) func(self)
end) end)
-- @TODO: temporary V2 fix for not working event
if not VT1 then Boot._machine._notify_mod_manager = true end
-- temporary solution: -- temporary solution:
local mod = new_mod("test_mod") local mod = new_mod("test_mod")
mod:initialize("scripts/mods/vmf/modules/testing_stuff_here") mod:initialize("scripts/mods/vmf/modules/testing_stuff_here")
@ -46,7 +51,7 @@ return {
object.vmf.mods_update_event(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)
object.vmf.check_mutators_state() if VT1 then object.vmf.check_mutators_state() end
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