Added VT2 compatibility; updated project the last VMB version
This commit is contained in:
parent
4853ebccf4
commit
1615ec1598
17 changed files with 539 additions and 136 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
.temp
|
||||
.vscode
|
||||
vmf/dist
|
17
README.MD
17
README.MD
|
@ -1,4 +1,13 @@
|
|||
1) Clone project somewhere
|
||||
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"`
|
||||
3) Run .bat-file every time you need to compile project
|
||||
# Building
|
||||
|
||||
## Prerequisites
|
||||
- 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.
|
76
compile.bat
76
compile.bat
|
@ -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
|
BIN
vmf/core/physx_metadata/physx_341_win32.physx_metadata
Normal file
BIN
vmf/core/physx_metadata/physx_341_win32.physx_metadata
Normal file
Binary file not shown.
BIN
vmf/core/physx_metadata/physx_341_win32_64bit.physx_metadata
Normal file
BIN
vmf/core/physx_metadata/physx_341_win32_64bit.physx_metadata
Normal file
Binary file not shown.
|
@ -3,5 +3,5 @@ description = "My Description";
|
|||
preview = "preview.jpg";
|
||||
content = "dist";
|
||||
language = "english";
|
||||
visibility = "private";
|
||||
visibility = "public";
|
||||
published_id = 1289946781L;
|
7
vmf/itemV2.cfg
Normal file
7
vmf/itemV2.cfg
Normal file
|
@ -0,0 +1,7 @@
|
|||
title = "Vermintide Mod Framework";
|
||||
description = "My Description";
|
||||
preview = "preview.jpg";
|
||||
content = "dist";
|
||||
language = "english";
|
||||
visibility = "public";
|
||||
published_id = 1369573612L;
|
|
@ -1,6 +1,6 @@
|
|||
return {
|
||||
mods_options = {
|
||||
en = "Mods Options",
|
||||
en = "Mod Options",
|
||||
ru = "Настройки модов",
|
||||
},
|
||||
open_vmf_options = {
|
||||
|
|
|
@ -51,6 +51,7 @@ VMFMod.echo = function (self, message, ...)
|
|||
message = safe_format(self, message, ...)
|
||||
|
||||
if message then
|
||||
|
||||
if _LOGGING_SETTINGS.echo.send_to_chat then
|
||||
send_to_chat(message)
|
||||
end
|
||||
|
@ -197,11 +198,11 @@ 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, @TODO: clean up?
|
||||
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,
|
||||
debug = vmf:get("logging_mode") == "custom" and vmf:get("output_mode_debug"),-- or 0,
|
||||
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,
|
||||
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,
|
||||
debug = vmf:get("logging_mode") == "custom" and vmf:get("output_mode_debug") or 0,
|
||||
}
|
||||
|
||||
for method_name, logging_mode in pairs(_LOGGING_SETTINGS) do
|
||||
|
|
|
@ -49,7 +49,7 @@ vmf.mods_update_event = function(dt)
|
|||
end
|
||||
|
||||
-- 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"
|
||||
|
||||
|
@ -57,7 +57,7 @@ vmf.mods_game_state_changed_event = function(status, state)
|
|||
|
||||
local event = mod[event_name]
|
||||
if event then
|
||||
run_event(mod, event_name, event, status, state)
|
||||
run_event(mod, event_name, event, status, state_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -34,7 +34,7 @@ VMFMod.initialize_data = function (self, mod_data)
|
|||
self._data.is_mutator = mod_data.is_mutator
|
||||
|
||||
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
|
||||
|
||||
if mod_data.options_widgets or (mod_data.is_togglable and not mod_data.is_mutator) then
|
||||
|
|
|
@ -30,7 +30,15 @@ VMFMod.register_new_view = function (self, new_view_data)
|
|||
-- so the menu will open when the keybind is pressed
|
||||
self[new_view_data.view_settings.hotkey_action_name] = function()
|
||||
|
||||
if not closing_keybind_is_pressed and ingame_ui and not ingame_ui:pending_transition() and not ingame_ui:end_screen_active() and not ingame_ui.menu_active and not ingame_ui.leave_game and not ingame_ui.return_to_title_screen and not ingame_ui.popup_join_lobby_handler.visible then
|
||||
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)
|
||||
end
|
||||
|
||||
|
@ -177,10 +185,15 @@ end
|
|||
-- ##### Script #######################################################################################################
|
||||
-- ####################################################################################################################
|
||||
|
||||
-- if reloading mods
|
||||
if not ingame_ui then
|
||||
local ingame_ui_exists, ingame_ui_return = pcall(function () return Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui end)
|
||||
if ingame_ui_exists then
|
||||
ingame_ui = ingame_ui_return
|
||||
end
|
||||
|
||||
local ingame_ui_exists, ingame_ui_return
|
||||
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
|
||||
ingame_ui = ingame_ui_return
|
||||
end
|
|
@ -4,7 +4,7 @@ local mod_data = {}
|
|||
mod_data.name = "Test"
|
||||
mod_data.description = "Test mod description"
|
||||
mod_data.is_togglable = true
|
||||
--mod_data.mutator_setting = nil
|
||||
--mod_data.mutator_settings = nil
|
||||
mod_data.options_widgets = {
|
||||
{
|
||||
["setting_name"] = "game_mode",
|
||||
|
@ -64,7 +64,7 @@ mod_data.options_widgets = {
|
|||
["text"] = "Some keybind [toggle]",
|
||||
["tooltip"] = "Probably keybind",
|
||||
["default_value"] = {"f", "ctrl"},
|
||||
["action"] = "toggle_mod"
|
||||
["action"] = "toggle_mod_state"
|
||||
},
|
||||
{
|
||||
["setting_name"] = "game_mode2",
|
||||
|
@ -134,12 +134,9 @@ mod:command("test", "short command description\n params: [parameter1] [parameter
|
|||
-- for serialization:
|
||||
-- table.maxn (table)
|
||||
|
||||
|
||||
|
||||
|
||||
mod.whatever = function ()
|
||||
--mod:echo("whatever")
|
||||
|
||||
--mod:dtf(Boot, "Boot", 5)
|
||||
--[[
|
||||
mod:pcall(function()
|
||||
|
||||
|
@ -162,9 +159,11 @@ mod.whatever = function ()
|
|||
|
||||
--mod:network_send("rpc_whatever", "all", 1, "yay", true, nil, {4, 5})
|
||||
|
||||
--[[
|
||||
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))
|
||||
end)
|
||||
]]
|
||||
|
||||
|
||||
--mod.simulate(1, "yay", true, Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui.wwise_world, {4, 5})
|
||||
|
|
|
@ -34,6 +34,12 @@ local function clean_chat_history()
|
|||
_CHAT_HISTORY_INDEX = 0
|
||||
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 ########################################################################################################
|
||||
-- ####################################################################################################################
|
||||
|
@ -98,7 +104,8 @@ vmf:hook("ChatGui._update_input", function(func, self, input_service, menu_input
|
|||
_COMMANDS_LIST = {}
|
||||
_COMMAND_INDEX = 0
|
||||
|
||||
self.chat_message = ""
|
||||
set_chat_message(self, "")
|
||||
|
||||
command_executed = true
|
||||
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)
|
||||
|
||||
if chat_closed then
|
||||
self.chat_message = ""
|
||||
set_chat_message(self, "")
|
||||
|
||||
_CHAT_OPENED = false
|
||||
|
||||
|
@ -141,6 +148,12 @@ vmf:hook("ChatGui._update_input", function(func, self, input_service, menu_input
|
|||
|
||||
-- chat history
|
||||
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
|
||||
if self.chat_message ~= self.previous_chat_message then
|
||||
_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[new_index] then
|
||||
|
||||
self.chat_message = _CHAT_HISTORY[new_index]
|
||||
self.chat_index = KeystrokeHelper.num_utf8chars(self.chat_message) + 1
|
||||
self.chat_input_widget.content.text_index = 1
|
||||
set_chat_message(self, _CHAT_HISTORY[new_index])
|
||||
|
||||
self.previous_chat_message = self.chat_message
|
||||
|
||||
_CHAT_HISTORY_INDEX = new_index
|
||||
else -- new_index == 0
|
||||
self.chat_message = ""
|
||||
self.chat_index = 1
|
||||
set_chat_message(self, "")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -170,8 +180,8 @@ vmf:hook("ChatGui._update_input", function(func, self, input_service, menu_input
|
|||
|
||||
-- ctrl + v
|
||||
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
|
||||
self.chat_index = KeystrokeHelper.num_utf8chars(self.chat_message) + 1
|
||||
local new_chat_message = self.chat_message .. tostring(Clipboard.get()):gsub(string.char(0x0D), "") -- remove CR characters
|
||||
set_chat_message(self, new_chat_message)
|
||||
end
|
||||
|
||||
-- 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
|
||||
|
||||
self.chat_message = "/" .. _COMMANDS_LIST[_COMMAND_INDEX].name
|
||||
self.chat_index = KeystrokeHelper.num_utf8chars(self.chat_message) + 1
|
||||
set_chat_message(self, "/" .. _COMMANDS_LIST[_COMMAND_INDEX].name)
|
||||
|
||||
-- so the next block won't update the commands list
|
||||
old_chat_message = self.chat_message
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
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_SIZE = 22
|
||||
|
|
|
@ -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
|
||||
|
@ -3789,6 +4182,8 @@ end
|
|||
|
||||
VMFOptionsView.on_enter = function (self)
|
||||
|
||||
if ShowCursorStack.stack_depth == 0 then ShowCursorStack.push() end
|
||||
|
||||
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", "mouse", 1)
|
||||
|
@ -3806,6 +4201,9 @@ end
|
|||
VMFOptionsView.on_exit = function (self)
|
||||
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()
|
||||
end
|
||||
|
||||
|
@ -4085,7 +4483,7 @@ local view_data = {
|
|||
},
|
||||
hotkey_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
|
||||
},
|
||||
view_transitions = {
|
||||
|
@ -4097,6 +4495,7 @@ local view_data = {
|
|||
end,
|
||||
|
||||
vmf_options_view_force = function (self)
|
||||
|
||||
ShowCursorStack.push()
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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"
|
||||
-- it's enough to enable/disable buttons in V1, but it doesn't do anything in V2
|
||||
-- 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
|
||||
|
@ -4127,7 +4550,6 @@ end
|
|||
|
||||
vmf.initialize_vmf_options_view = function ()
|
||||
vmf:register_new_view(view_data)
|
||||
|
||||
change_mods_options_button_state("enable")
|
||||
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
|
||||
|
||||
if button_info.transition == "options_menu" then
|
||||
|
||||
table.insert(layout_data, i + 1, mods_options_button)
|
||||
break
|
||||
end
|
||||
|
@ -4157,14 +4577,19 @@ vmf:hook("IngameView.setup_button_layout", function (func, self, layout_data)
|
|||
func(self, layout_data)
|
||||
|
||||
for _, button_info in ipairs(self.active_button_data) do
|
||||
|
||||
if button_info.transition == "vmf_options_view" then
|
||||
|
||||
if VT1 then
|
||||
button_info.widget.style.text.localize = false
|
||||
button_info.widget.style.text_disabled.localize = false
|
||||
button_info.widget.style.text_click.localize = false
|
||||
button_info.widget.style.text_hover.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
|
||||
change_mods_options_button_state("disable")
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
VT1 = true
|
||||
|
||||
return {
|
||||
init = function(object)
|
||||
|
||||
|
@ -26,7 +28,7 @@ return {
|
|||
dofile("scripts/mods/vmf/modules/ui/options/vmf_options_view")
|
||||
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")
|
||||
|
||||
|
@ -36,6 +38,9 @@ return {
|
|||
func(self)
|
||||
end)
|
||||
|
||||
-- @TODO: temporary V2 fix for not working event
|
||||
if not VT1 then Boot._machine._notify_mod_manager = true end
|
||||
|
||||
-- temporary solution:
|
||||
local mod = new_mod("test_mod")
|
||||
mod:initialize("scripts/mods/vmf/modules/testing_stuff_here")
|
||||
|
@ -46,7 +51,7 @@ return {
|
|||
object.vmf.mods_update_event(dt)
|
||||
object.vmf.check_pressed_keybinds()
|
||||
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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue