commit
9b9211a8b1
20 changed files with 463 additions and 371 deletions
|
@ -7,7 +7,7 @@ local vmf = get_mod("VMF")
|
||||||
|
|
||||||
not sure about UI scaling
|
not sure about UI scaling
|
||||||
]]
|
]]
|
||||||
local _COMMANDS = {}
|
local _commands = {}
|
||||||
|
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
-- ##### VMFMod #######################################################################################################
|
-- ##### VMFMod #######################################################################################################
|
||||||
|
@ -30,12 +30,14 @@ VMFMod.command = function (self, command_name, command_description, command_func
|
||||||
|
|
||||||
command_name = command_name:lower()
|
command_name = command_name:lower()
|
||||||
|
|
||||||
if _COMMANDS[command_name] and _COMMANDS[command_name].mod ~= self then
|
local command_data = _commands[command_name]
|
||||||
self:error("(command): command name '%s' is already used by another mod '%s'", command_name, _COMMANDS[command_name].mod:get_name())
|
if command_data and command_data.mod ~= self then
|
||||||
|
self:error("(command): command name '%s' is already used by another mod '%s'",
|
||||||
|
command_name, command_data.mod:get_name())
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
_COMMANDS[command_name] = {
|
_commands[command_name] = {
|
||||||
mod = self,
|
mod = self,
|
||||||
exec_function = command_function,
|
exec_function = command_function,
|
||||||
description = command_description,
|
description = command_description,
|
||||||
|
@ -50,7 +52,7 @@ VMFMod.command_remove = function (self, command_name)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
_COMMANDS[command_name] = nil
|
_commands[command_name] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,8 +62,8 @@ VMFMod.command_disable = function (self, command_name)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if _COMMANDS[command_name] then
|
if _commands[command_name] then
|
||||||
_COMMANDS[command_name].is_enabled = false
|
_commands[command_name].is_enabled = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -72,35 +74,35 @@ VMFMod.command_enable = function (self, command_name)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if _COMMANDS[command_name] then
|
if _commands[command_name] then
|
||||||
_COMMANDS[command_name].is_enabled = true
|
_commands[command_name].is_enabled = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
VMFMod.remove_all_commands = function (self)
|
VMFMod.remove_all_commands = function (self)
|
||||||
|
|
||||||
for command_name, command_entry in pairs(_COMMANDS) do
|
for command_name, command_data in pairs(_commands) do
|
||||||
if command_entry.mod == self then
|
if command_data.mod == self then
|
||||||
_COMMANDS[command_name] = nil
|
_commands[command_name] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
VMFMod.disable_all_commands = function (self)
|
VMFMod.disable_all_commands = function (self)
|
||||||
for _, command_entry in pairs(_COMMANDS) do
|
for _, command_data in pairs(_commands) do
|
||||||
if command_entry.mod == self then
|
if command_data.mod == self then
|
||||||
command_entry.is_enabled = false
|
command_data.is_enabled = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
VMFMod.enable_all_commands = function (self)
|
VMFMod.enable_all_commands = function (self)
|
||||||
for _, command_entry in pairs(_COMMANDS) do
|
for _, command_data in pairs(_commands) do
|
||||||
if command_entry.mod == self then
|
if command_data.mod == self then
|
||||||
command_entry.is_enabled = true
|
command_data.is_enabled = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -115,18 +117,21 @@ vmf.get_commands_list = function(name_contains, exact_match)
|
||||||
|
|
||||||
local commands_list = {}
|
local commands_list = {}
|
||||||
|
|
||||||
for command_name, command_entry in pairs(_COMMANDS) do
|
for command_name, command_data in pairs(_commands) do
|
||||||
|
|
||||||
if exact_match then
|
if exact_match then
|
||||||
if command_name == name_contains and command_entry.is_enabled then
|
|
||||||
table.insert(commands_list, {name = command_name, description = command_entry.description})
|
if command_name == name_contains and command_data.is_enabled then
|
||||||
|
table.insert(commands_list, {name = command_name, description = command_data.description})
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
if string.sub(command_name, 1, string.len(name_contains)) == name_contains and command_entry.is_enabled and command_entry.mod:is_enabled() then
|
local command_match = ( string.sub(command_name, 1, string.len(name_contains)) == name_contains )
|
||||||
table.insert(commands_list, {name = command_name, description = command_entry.description})
|
if command_match and command_data.is_enabled and command_data.mod:is_enabled() then
|
||||||
|
table.insert(commands_list, {name = command_name, description = command_data.description})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
table.sort(commands_list, function(a, b) return a.name < b.name end)
|
table.sort(commands_list, function(a, b) return a.name < b.name end)
|
||||||
|
@ -137,10 +142,10 @@ end
|
||||||
|
|
||||||
vmf.run_command = function(command_name, ...)
|
vmf.run_command = function(command_name, ...)
|
||||||
|
|
||||||
local command_entry = _COMMANDS[command_name]
|
local command_data = _commands[command_name]
|
||||||
if command_entry then
|
if command_data then
|
||||||
local error_prefix = "(commands) " .. tostring(command_name)
|
local error_prefix = "(commands) " .. tostring(command_name)
|
||||||
vmf.xpcall_no_return_values(command_entry.mod, error_prefix, command_entry.exec_function, ...)
|
vmf.xpcall_no_return_values(command_data.mod, error_prefix, command_data.exec_function, ...)
|
||||||
else
|
else
|
||||||
vmf:error("(commands): command '%s' wasn't found.", command_name) -- should never see this
|
vmf:error("(commands): command '%s' wasn't found.", command_name) -- should never see this
|
||||||
end
|
end
|
||||||
|
|
|
@ -112,7 +112,8 @@ vmf.check_wrong_argument_type = function(mod, vmf_function_name, argument_name,
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
mod:error("(%s): argument '%s' should have the '%s' type, not '%s'", vmf_function_name, argument_name, table.concat(allowed_types, "/"), argument_type)
|
mod:error("(%s): argument '%s' should have the '%s' type, not '%s'",
|
||||||
|
vmf_function_name, argument_name, table.concat(allowed_types, "/"), argument_type)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
local vmf = get_mod("VMF")
|
local vmf = get_mod("VMF")
|
||||||
|
--luacheck: ignore
|
||||||
HOOKED_FUNCTIONS = {} -- global, because 'loadstring' doesn't see local variables
|
HOOKED_FUNCTIONS = {} -- global, because 'loadstring' doesn't see local variables
|
||||||
|
|
||||||
if type(DELAYED_HOOKING_ENABLED) == "boolean" then
|
if type(DELAYED_HOOKING_ENABLED) == "boolean" then
|
||||||
|
|
|
@ -9,13 +9,22 @@ VMFModsKeyMap = {
|
||||||
xb1 = {}
|
xb1 = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
-- ["mod_name"]["setting_name"] = {"action_name", {"primary_key", "special_key", "special_key", "special_key"}} (special_key - "ctrl"/"shift"/"alt")
|
-- ["mod_name"]["setting_name"] = {
|
||||||
local _RAW_KEYBINDS = {}
|
-- "action_name",
|
||||||
|
-- {"primary_key", "special_key", "special_key", "special_key"}
|
||||||
|
-- }
|
||||||
|
-- Special Keys: "ctrl" / "shift" / "alt"
|
||||||
|
local _raw_keybinds = {}
|
||||||
|
|
||||||
-- ["primary_key"] = {{"mod_name", "action_name", ctrl_used(bool), alt_used(bool), shift_used(bool)}, {}, {}, ...}
|
-- ["primary_key"] = {
|
||||||
local _OPTIMIZED_KEYBINDS = {}
|
-- {"mod_name", "action_name", ctrl_used(bool), alt_used(bool), shift_used(bool)},
|
||||||
|
-- {},
|
||||||
|
-- {},
|
||||||
|
-- ...
|
||||||
|
-- }
|
||||||
|
local _optimized_keybinds = {}
|
||||||
|
|
||||||
local _ACTIVATED_PRESSED_KEY
|
local _activated_pressed_key
|
||||||
|
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
-- ##### Local functions ##############################################################################################
|
-- ##### Local functions ##############################################################################################
|
||||||
|
@ -23,9 +32,9 @@ local _ACTIVATED_PRESSED_KEY
|
||||||
|
|
||||||
local function apply_keybinds()
|
local function apply_keybinds()
|
||||||
|
|
||||||
_OPTIMIZED_KEYBINDS = {}
|
_optimized_keybinds = {}
|
||||||
|
|
||||||
for mod_name, mod_keybinds in pairs(_RAW_KEYBINDS) do
|
for mod_name, mod_keybinds in pairs(_raw_keybinds) do
|
||||||
for _, keybind in pairs(mod_keybinds) do
|
for _, keybind in pairs(mod_keybinds) do
|
||||||
local action_name = keybind[1]
|
local action_name = keybind[1]
|
||||||
local primary_key = keybind[2][1]
|
local primary_key = keybind[2][1]
|
||||||
|
@ -46,8 +55,13 @@ local function apply_keybinds()
|
||||||
special_keys[special_key3] = true
|
special_keys[special_key3] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
_OPTIMIZED_KEYBINDS[primary_key] = _OPTIMIZED_KEYBINDS[primary_key] or {}
|
_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"]})
|
table.insert(_optimized_keybinds[primary_key], {
|
||||||
|
mod_name, action_name,
|
||||||
|
special_keys["ctrl"],
|
||||||
|
special_keys["alt"],
|
||||||
|
special_keys["shift"]
|
||||||
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -65,14 +79,14 @@ VMFMod.keybind = function (self, setting_name, action_name, keys)
|
||||||
|
|
||||||
if keys[1] then
|
if keys[1] then
|
||||||
|
|
||||||
local mod_keybinds = _RAW_KEYBINDS[self:get_name()] or {}
|
local mod_keybinds = _raw_keybinds[self:get_name()] or {}
|
||||||
|
|
||||||
mod_keybinds[setting_name] = {action_name, keys}
|
mod_keybinds[setting_name] = {action_name, keys}
|
||||||
|
|
||||||
_RAW_KEYBINDS[self:get_name()] = mod_keybinds
|
_raw_keybinds[self:get_name()] = mod_keybinds
|
||||||
else
|
else
|
||||||
|
|
||||||
local mod_keybinds = _RAW_KEYBINDS[self:get_name()]
|
local mod_keybinds = _raw_keybinds[self:get_name()]
|
||||||
|
|
||||||
if mod_keybinds and mod_keybinds[setting_name] then
|
if mod_keybinds and mod_keybinds[setting_name] then
|
||||||
mod_keybinds[setting_name] = nil
|
mod_keybinds[setting_name] = nil
|
||||||
|
@ -104,22 +118,26 @@ vmf.check_pressed_keybinds = function()
|
||||||
if input_service then
|
if input_service then
|
||||||
|
|
||||||
-- don't check for the pressed keybindings until player will release already pressed keybind
|
-- don't check for the pressed keybindings until player will release already pressed keybind
|
||||||
if _ACTIVATED_PRESSED_KEY then
|
if _activated_pressed_key then
|
||||||
if input_service:get(_ACTIVATED_PRESSED_KEY) then
|
if input_service:get(_activated_pressed_key) then
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
_ACTIVATED_PRESSED_KEY = nil
|
_activated_pressed_key = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local key_has_active_keybind = false
|
local key_has_active_keybind = false
|
||||||
|
local input_ctrl = input_service:get("ctrl")
|
||||||
|
local input_shift = input_service:get("shift")
|
||||||
|
local input_alt = input_service:get("alt")
|
||||||
|
|
||||||
for key, key_bindings in pairs(_OPTIMIZED_KEYBINDS) do
|
for key, key_bindings in pairs(_optimized_keybinds) do
|
||||||
if input_service:get(key) then
|
if input_service:get(key) then
|
||||||
|
|
||||||
for _, binding_info in ipairs(key_bindings) do
|
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
|
if (not binding_info[3] and not input_ctrl or binding_info[3] and input_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[4] and not input_alt or binding_info[4] and input_alt) and
|
||||||
(not binding_info[5] and not input_service:get("shift") or binding_info[5] and input_service:get("shift")) then
|
(not binding_info[5] and not input_shift or binding_info[5] and input_shift) then
|
||||||
|
|
||||||
local mod = get_mod(binding_info[1])
|
local mod = get_mod(binding_info[1])
|
||||||
|
|
||||||
|
@ -128,7 +146,7 @@ vmf.check_pressed_keybinds = function()
|
||||||
vmf.mod_state_changed(mod:get_name(), not mod:is_enabled())
|
vmf.mod_state_changed(mod:get_name(), not mod:is_enabled())
|
||||||
|
|
||||||
key_has_active_keybind = true
|
key_has_active_keybind = true
|
||||||
_ACTIVATED_PRESSED_KEY = key
|
_activated_pressed_key = key
|
||||||
|
|
||||||
elseif mod:is_enabled() then
|
elseif mod:is_enabled() then
|
||||||
|
|
||||||
|
@ -141,7 +159,7 @@ vmf.check_pressed_keybinds = function()
|
||||||
end
|
end
|
||||||
|
|
||||||
key_has_active_keybind = true
|
key_has_active_keybind = true
|
||||||
_ACTIVATED_PRESSED_KEY = key
|
_activated_pressed_key = key
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,8 +11,8 @@ Italian (it)
|
||||||
Polish (pl)
|
Polish (pl)
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local _LANGUAGE_ID = Application.user_setting("language_id")
|
local _language_id = Application.user_setting("language_id")
|
||||||
local _LOCALIZATION_DATABASE = {}
|
local _localization_database = {}
|
||||||
|
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
-- ##### Local functions ##############################################################################################
|
-- ##### Local functions ##############################################################################################
|
||||||
|
@ -36,7 +36,7 @@ end
|
||||||
|
|
||||||
VMFMod.localize = function (self, text_id, ...)
|
VMFMod.localize = function (self, text_id, ...)
|
||||||
|
|
||||||
local mod_localization_table = _LOCALIZATION_DATABASE[self:get_name()]
|
local mod_localization_table = _localization_database[self:get_name()]
|
||||||
if mod_localization_table then
|
if mod_localization_table then
|
||||||
|
|
||||||
local text_translations = mod_localization_table[text_id]
|
local text_translations = mod_localization_table[text_id]
|
||||||
|
@ -44,9 +44,9 @@ VMFMod.localize = function (self, text_id, ...)
|
||||||
|
|
||||||
local message
|
local message
|
||||||
|
|
||||||
if text_translations[_LANGUAGE_ID] then
|
if text_translations[_language_id] then
|
||||||
|
|
||||||
message = safe_string_format(self, text_translations[_LANGUAGE_ID], ...)
|
message = safe_string_format(self, text_translations[_language_id], ...)
|
||||||
if message then
|
if message then
|
||||||
return message
|
return message
|
||||||
end
|
end
|
||||||
|
@ -78,11 +78,11 @@ vmf.load_mod_localization = function (mod, localization_table)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if _LOCALIZATION_DATABASE[mod:get_name()] then
|
if _localization_database[mod:get_name()] then
|
||||||
mod:warning("(localization): overwritting already loaded localization file")
|
mod:warning("(localization): overwritting already loaded localization file")
|
||||||
end
|
end
|
||||||
|
|
||||||
_LOCALIZATION_DATABASE[mod:get_name()] = localization_table
|
_localization_database[mod:get_name()] = localization_table
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
--]]
|
--]]
|
||||||
local vmf = get_mod("VMF")
|
local vmf = get_mod("VMF")
|
||||||
|
|
||||||
local _WERE_ENABLED_BEFORE = false
|
local _were_enabled_before = false
|
||||||
|
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
-- ##### Local functions ##############################################################################################
|
-- ##### Local functions ##############################################################################################
|
||||||
|
@ -82,10 +82,10 @@ vmf:hook("MatchmakingStateHostGame.host_game", function(func, ...)
|
||||||
local names = add_enabled_mutators_titles_to_string(", ")
|
local names = add_enabled_mutators_titles_to_string(", ")
|
||||||
if names ~= "" then
|
if names ~= "" then
|
||||||
vmf:chat_broadcast(vmf:localize("broadcast_enabled_mutators") .. ": " .. names)
|
vmf:chat_broadcast(vmf:localize("broadcast_enabled_mutators") .. ": " .. names)
|
||||||
_WERE_ENABLED_BEFORE = true
|
_were_enabled_before = true
|
||||||
elseif _WERE_ENABLED_BEFORE then
|
elseif _were_enabled_before then
|
||||||
vmf:chat_broadcast(vmf:localize("broadcast_all_disabled"))
|
vmf:chat_broadcast(vmf:localize("broadcast_all_disabled"))
|
||||||
_WERE_ENABLED_BEFORE = false
|
_were_enabled_before = false
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
local vmf = get_mod("VMF")
|
local vmf = get_mod("VMF")
|
||||||
|
|
||||||
-- List of mods that are also mutators in order in which they should be enabled
|
-- List of mods that are also mutators in order in which they should be enabled
|
||||||
local _MUTATORS = {}
|
local _mutators = {}
|
||||||
|
|
||||||
-- This lists mutators and which ones should be enabled after them
|
-- This lists mutators and which ones should be enabled after them
|
||||||
local _MUTATORS_SEQUENCE = {
|
local _mutators_sequence = {
|
||||||
--[[
|
--[[
|
||||||
this_mutator = {
|
this_mutator = {
|
||||||
"will be enabled",
|
"will be enabled",
|
||||||
|
@ -17,19 +17,20 @@ local _MUTATORS_SEQUENCE = {
|
||||||
}
|
}
|
||||||
|
|
||||||
-- So we don't sort after each one is added
|
-- So we don't sort after each one is added
|
||||||
local _MUTATORS_SORTED = false
|
local _mutators_sorted = false
|
||||||
|
|
||||||
-- So we don't have to check when player isn't hosting
|
-- So we don't have to check when player isn't hosting
|
||||||
local _ALL_MUTATORS_DISABLED = false
|
local _all_mutators_disabled = false
|
||||||
|
|
||||||
-- External modules
|
-- External modules
|
||||||
local _DICE_MANAGER = vmf:dofile("scripts/mods/vmf/modules/core/mutators/mutators_dice")
|
local dice_manager = vmf:dofile("scripts/mods/vmf/modules/core/mutators/mutators_dice")
|
||||||
local _SET_LOBBY_DATA = vmf:dofile("scripts/mods/vmf/modules/core/mutators/mutators_info")
|
local set_lobby_data = vmf:dofile("scripts/mods/vmf/modules/core/mutators/mutators_info")
|
||||||
|
|
||||||
local _DEFAULT_CONFIG = vmf:dofile("scripts/mods/vmf/modules/core/mutators/mutators_default_config")
|
-- Get default configuration
|
||||||
|
local _default_config = vmf:dofile("scripts/mods/vmf/modules/core/mutators/mutators_default_config")
|
||||||
|
|
||||||
-- List of enabled mutators in case VMF is reloaded in the middle of the game
|
-- List of enabled mutators in case VMF is reloaded in the middle of the game
|
||||||
local _ENABLED_MUTATORS = vmf:persistent_table("enabled_mutators")
|
local _enabled_mutators = vmf:persistent_table("enabled_mutators")
|
||||||
|
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
-- ##### Local functions ##############################################################################################
|
-- ##### Local functions ##############################################################################################
|
||||||
|
@ -48,11 +49,11 @@ end
|
||||||
-- Called after mutator is enabled
|
-- Called after mutator is enabled
|
||||||
local function on_enabled(mutator)
|
local function on_enabled(mutator)
|
||||||
local config = mutator:get_config()
|
local config = mutator:get_config()
|
||||||
_DICE_MANAGER.addDice(config.dice)
|
dice_manager.addDice(config.dice)
|
||||||
_SET_LOBBY_DATA()
|
set_lobby_data()
|
||||||
print("[MUTATORS] Enabled " .. mutator:get_name() .. " (" .. tostring(get_index(_MUTATORS, mutator)) .. ")")
|
print("[MUTATORS] Enabled " .. mutator:get_name() .. " (" .. tostring(get_index(_mutators, mutator)) .. ")")
|
||||||
|
|
||||||
_ENABLED_MUTATORS[mutator:get_name()] = true
|
_enabled_mutators[mutator:get_name()] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,12 +63,12 @@ local function on_disabled(mutator, initial_call)
|
||||||
|
|
||||||
-- All mutators run on_disabled on initial call, so there's no need to remove dice and set lobby data
|
-- All mutators run on_disabled on initial call, so there's no need to remove dice and set lobby data
|
||||||
if not initial_call then
|
if not initial_call then
|
||||||
_DICE_MANAGER.removeDice(config.dice)
|
dice_manager.removeDice(config.dice)
|
||||||
_SET_LOBBY_DATA()
|
set_lobby_data()
|
||||||
end
|
end
|
||||||
print("[MUTATORS] Disabled " .. mutator:get_name() .. " (" .. tostring(get_index(_MUTATORS, mutator)) .. ")")
|
print("[MUTATORS] Disabled " .. mutator:get_name() .. " (" .. tostring(get_index(_mutators, mutator)) .. ")")
|
||||||
|
|
||||||
_ENABLED_MUTATORS[mutator:get_name()] = nil
|
_enabled_mutators[mutator:get_name()] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,11 +83,11 @@ end
|
||||||
-- Sorts mutators in order they should be enabled
|
-- Sorts mutators in order they should be enabled
|
||||||
local function sort_mutators()
|
local function sort_mutators()
|
||||||
|
|
||||||
if _MUTATORS_SORTED then return end
|
if _mutators_sorted then return end
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
-- LOG --
|
-- LOG --
|
||||||
vmf:dump(_MUTATORS_SEQUENCE, "seq", 5)
|
vmf:dump(_mutators_sequence, "seq", 5)
|
||||||
for i, v in ipairs(mutators) do
|
for i, v in ipairs(mutators) do
|
||||||
print(i, v:get_name())
|
print(i, v:get_name())
|
||||||
end
|
end
|
||||||
|
@ -97,20 +98,20 @@ local function sort_mutators()
|
||||||
-- The idea is that all mutators before the current one are already in the right order
|
-- The idea is that all mutators before the current one are already in the right order
|
||||||
-- Starting from second mutator
|
-- Starting from second mutator
|
||||||
local i = 2
|
local i = 2
|
||||||
while i <= #_MUTATORS do
|
while i <= #_mutators do
|
||||||
local mutator = _MUTATORS[i]
|
local mutator = _mutators[i]
|
||||||
local mutator_name = mutator:get_name()
|
local mutator_name = mutator:get_name()
|
||||||
local enable_these_after = _MUTATORS_SEQUENCE[mutator_name] or {}
|
local enable_these_after = _mutators_sequence[mutator_name] or {}
|
||||||
|
|
||||||
-- Going back from the previous mutator to the start of the list
|
-- Going back from the previous mutator to the start of the list
|
||||||
local j = i - 1
|
local j = i - 1
|
||||||
while j > 0 do
|
while j > 0 do
|
||||||
local other_mutator = _MUTATORS[j]
|
local other_mutator = _mutators[j]
|
||||||
|
|
||||||
-- Moving it after the current one if it is to be enabled after it
|
-- Moving it after the current one if it is to be enabled after it
|
||||||
if table.contains(enable_these_after, other_mutator:get_name()) then
|
if table.contains(enable_these_after, other_mutator:get_name()) then
|
||||||
table.remove(_MUTATORS, j)
|
table.remove(_mutators, j)
|
||||||
table.insert(_MUTATORS, i, other_mutator)
|
table.insert(_mutators, i, other_mutator)
|
||||||
|
|
||||||
-- This will shift the current mutator back, so adjust the index
|
-- This will shift the current mutator back, so adjust the index
|
||||||
i = i - 1
|
i = i - 1
|
||||||
|
@ -120,12 +121,12 @@ local function sort_mutators()
|
||||||
|
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
_MUTATORS_SORTED = true
|
_mutators_sorted = true
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
-- LOG --
|
-- LOG --
|
||||||
print("[MUTATORS] Sorted")
|
print("[MUTATORS] Sorted")
|
||||||
for k, v in ipairs(_MUTATORS) do
|
for k, v in ipairs(_mutators) do
|
||||||
print(" ", k, v:get_name())
|
print(" ", k, v:get_name())
|
||||||
end
|
end
|
||||||
-- /LOG --
|
-- /LOG --
|
||||||
|
@ -140,7 +141,7 @@ local function mutator_can_be_enabled(mutator)
|
||||||
local mutator_compatibility_config = mutator:get_config().compatibility
|
local mutator_compatibility_config = mutator:get_config().compatibility
|
||||||
local is_mostly_compatible = mutator_compatibility_config.is_mostly_compatible
|
local is_mostly_compatible = mutator_compatibility_config.is_mostly_compatible
|
||||||
local except = mutator_compatibility_config.except
|
local except = mutator_compatibility_config.except
|
||||||
for _, other_mutator in ipairs(_MUTATORS) do
|
for _, other_mutator in ipairs(_mutators) do
|
||||||
if other_mutator:is_enabled() and other_mutator ~= mutator and
|
if other_mutator:is_enabled() and other_mutator ~= mutator and
|
||||||
(is_mostly_compatible and except[other_mutator] or not is_mostly_compatible and not except[other_mutator]) then
|
(is_mostly_compatible and except[other_mutator] or not is_mostly_compatible and not except[other_mutator]) then
|
||||||
return false
|
return false
|
||||||
|
@ -162,8 +163,8 @@ end
|
||||||
-- Disables mutators that cannot be enabled right now
|
-- Disables mutators that cannot be enabled right now
|
||||||
local function disable_impossible_mutators(is_broadcast, reason_text_id)
|
local function disable_impossible_mutators(is_broadcast, reason_text_id)
|
||||||
local disabled_mutators = {}
|
local disabled_mutators = {}
|
||||||
for i = #_MUTATORS, 1, -1 do
|
for i = #_mutators, 1, -1 do
|
||||||
local mutator = _MUTATORS[i]
|
local mutator = _mutators[i]
|
||||||
if mutator:is_enabled() and not mutator_can_be_enabled(mutator) then
|
if mutator:is_enabled() and not mutator_can_be_enabled(mutator) then
|
||||||
vmf.mod_state_changed(mutator:get_name(), false)
|
vmf.mod_state_changed(mutator:get_name(), false)
|
||||||
table.insert(disabled_mutators, mutator)
|
table.insert(disabled_mutators, mutator)
|
||||||
|
@ -194,28 +195,28 @@ local function update_mutators_sequence(mutator)
|
||||||
local mutator_name = mutator:get_name()
|
local mutator_name = mutator:get_name()
|
||||||
|
|
||||||
if enable_before_these then
|
if enable_before_these then
|
||||||
_MUTATORS_SEQUENCE[mutator_name] = _MUTATORS_SEQUENCE[mutator_name] or {}
|
_mutators_sequence[mutator_name] = _mutators_sequence[mutator_name] or {}
|
||||||
|
|
||||||
for _, other_mutator_name in ipairs(enable_before_these) do
|
for _, other_mutator_name in ipairs(enable_before_these) do
|
||||||
if _MUTATORS_SEQUENCE[other_mutator_name] and
|
if _mutators_sequence[other_mutator_name] and
|
||||||
table.contains(_MUTATORS_SEQUENCE[other_mutator_name], mutator_name) then
|
table.contains(_mutators_sequence[other_mutator_name], mutator_name) then
|
||||||
vmf:error("(mutators): Mutators '%s' and '%s' are both set to load after each other.", mutator_name,
|
vmf:error("(mutators): Mutators '%s' and '%s' are both set to load after each other.", mutator_name,
|
||||||
other_mutator_name)
|
other_mutator_name)
|
||||||
elseif not table.contains(_MUTATORS_SEQUENCE[mutator_name], other_mutator_name) then
|
elseif not table.contains(_mutators_sequence[mutator_name], other_mutator_name) then
|
||||||
table.insert(_MUTATORS_SEQUENCE[mutator_name], other_mutator_name)
|
table.insert(_mutators_sequence[mutator_name], other_mutator_name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
if enable_after_these then
|
if enable_after_these then
|
||||||
for _, other_mutator_name in ipairs(enable_after_these) do
|
for _, other_mutator_name in ipairs(enable_after_these) do
|
||||||
_MUTATORS_SEQUENCE[other_mutator_name] = _MUTATORS_SEQUENCE[other_mutator_name] or {}
|
_mutators_sequence[other_mutator_name] = _mutators_sequence[other_mutator_name] or {}
|
||||||
|
|
||||||
if _MUTATORS_SEQUENCE[mutator_name] and table.contains(_MUTATORS_SEQUENCE[mutator_name], other_mutator_name) then
|
if _mutators_sequence[mutator_name] and table.contains(_mutators_sequence[mutator_name], other_mutator_name) then
|
||||||
vmf:error("(mutators): Mutators '%s' and '%s' are both set to load after each other.", mutator_name,
|
vmf:error("(mutators): Mutators '%s' and '%s' are both set to load after each other.", mutator_name,
|
||||||
other_mutator_name)
|
other_mutator_name)
|
||||||
elseif not table.contains(_MUTATORS_SEQUENCE[other_mutator_name], mutator_name) then
|
elseif not table.contains(_mutators_sequence[other_mutator_name], mutator_name) then
|
||||||
table.insert(_MUTATORS_SEQUENCE[other_mutator_name], mutator_name)
|
table.insert(_mutators_sequence[other_mutator_name], mutator_name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -284,7 +285,7 @@ local function update_compatibility(mutator)
|
||||||
local is_mostly_compatible = compatibility.is_mostly_compatible
|
local is_mostly_compatible = compatibility.is_mostly_compatible
|
||||||
local except = compatibility.except
|
local except = compatibility.except
|
||||||
|
|
||||||
for _, other_mutator in ipairs(_MUTATORS) do
|
for _, other_mutator in ipairs(_mutators) do
|
||||||
|
|
||||||
local other_config = other_mutator:get_config()
|
local other_config = other_mutator:get_config()
|
||||||
local other_mostly_compatible = other_config.compatibility.is_mostly_compatible
|
local other_mostly_compatible = other_config.compatibility.is_mostly_compatible
|
||||||
|
@ -327,7 +328,7 @@ local function initialize_mutator_config(mutator, _raw_config)
|
||||||
|
|
||||||
-- Shapes raw config, so it will have only elements that are intended to be in there.
|
-- Shapes raw config, so it will have only elements that are intended to be in there.
|
||||||
-- Also, adds missing elements with their default values.
|
-- Also, adds missing elements with their default values.
|
||||||
local raw_config = table.clone(_DEFAULT_CONFIG)
|
local raw_config = table.clone(_default_config)
|
||||||
if type(_raw_config) == "table" then
|
if type(_raw_config) == "table" then
|
||||||
for k, v in pairs(raw_config) do
|
for k, v in pairs(raw_config) do
|
||||||
if type(_raw_config[k]) == type(v) then
|
if type(_raw_config[k]) == type(v) then
|
||||||
|
@ -352,7 +353,7 @@ local function initialize_mutator_config(mutator, _raw_config)
|
||||||
-- config.compatibility
|
-- config.compatibility
|
||||||
update_compatibility(mutator)
|
update_compatibility(mutator)
|
||||||
|
|
||||||
-- _MUTATORS_SEQUENCE
|
-- _mutators_sequence
|
||||||
update_mutators_sequence(mutator)
|
update_mutators_sequence(mutator)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -360,7 +361,7 @@ end
|
||||||
-- ##### VMF internal functions and variables #########################################################################
|
-- ##### VMF internal functions and variables #########################################################################
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
|
|
||||||
vmf.mutators = _MUTATORS
|
vmf.mutators = _mutators
|
||||||
|
|
||||||
|
|
||||||
-- Appends, prepends and replaces the string with mutator titles
|
-- Appends, prepends and replaces the string with mutator titles
|
||||||
|
@ -413,9 +414,9 @@ function vmf.register_mod_as_mutator(mod, raw_config)
|
||||||
|
|
||||||
initialize_mutator_config(mod, raw_config)
|
initialize_mutator_config(mod, raw_config)
|
||||||
|
|
||||||
table.insert(_MUTATORS, mod)
|
table.insert(_mutators, mod)
|
||||||
|
|
||||||
_MUTATORS_SORTED = false
|
_mutators_sorted = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -423,24 +424,24 @@ end
|
||||||
function vmf.set_mutator_state(mutator, state, initial_call)
|
function vmf.set_mutator_state(mutator, state, initial_call)
|
||||||
|
|
||||||
-- Sort mutators if this is the first call
|
-- Sort mutators if this is the first call
|
||||||
if not _MUTATORS_SORTED then
|
if not _mutators_sorted then
|
||||||
sort_mutators()
|
sort_mutators()
|
||||||
end
|
end
|
||||||
|
|
||||||
local disabled_mutators = {}
|
local disabled_mutators = {}
|
||||||
local enable_these_after = _MUTATORS_SEQUENCE[mutator:get_name()]
|
local enable_these_after = _mutators_sequence[mutator:get_name()]
|
||||||
|
|
||||||
local i = get_index(_MUTATORS, mutator)
|
local i = get_index(_mutators, mutator)
|
||||||
-- Disable mutators that were and are required to be enabled after the current one
|
-- Disable mutators that were and are required to be enabled after the current one
|
||||||
-- This will be recursive so that if mutator2 requires mutator3 to be enabled after it,
|
-- This will be recursive so that if mutator2 requires mutator3 to be enabled after it,
|
||||||
-- mutator3 will be disabled before mutator2
|
-- mutator3 will be disabled before mutator2
|
||||||
-- Yeah this is super confusing
|
-- Yeah this is super confusing
|
||||||
if enable_these_after and #_MUTATORS > i then
|
if enable_these_after and #_mutators > i then
|
||||||
for j = #_MUTATORS, i + 1, -1 do
|
for j = #_mutators, i + 1, -1 do
|
||||||
if _MUTATORS[j]:is_enabled() and table.contains(enable_these_after, _MUTATORS[j]:get_name()) then
|
if _mutators[j]:is_enabled() and table.contains(enable_these_after, _mutators[j]:get_name()) then
|
||||||
--print("Disabled ", _MUTATORS[j]:get_name())
|
--print("Disabled ", _mutators[j]:get_name())
|
||||||
vmf.set_mutator_state(_MUTATORS[j], false, false)
|
vmf.set_mutator_state(_mutators[j], false, false)
|
||||||
table.insert(disabled_mutators, 1, _MUTATORS[j])
|
table.insert(disabled_mutators, 1, _mutators[j])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -449,7 +450,7 @@ function vmf.set_mutator_state(mutator, state, initial_call)
|
||||||
-- We're calling methods on the class object because we've overwritten them on the current one
|
-- We're calling methods on the class object because we've overwritten them on the current one
|
||||||
vmf.set_mod_state(mutator, state, initial_call)
|
vmf.set_mod_state(mutator, state, initial_call)
|
||||||
if state then
|
if state then
|
||||||
_ALL_MUTATORS_DISABLED = false
|
_all_mutators_disabled = false
|
||||||
on_enabled(mutator)
|
on_enabled(mutator)
|
||||||
else
|
else
|
||||||
on_disabled(mutator, initial_call)
|
on_disabled(mutator, initial_call)
|
||||||
|
@ -468,21 +469,21 @@ end
|
||||||
|
|
||||||
-- Checks if player is still hosting (on update)
|
-- Checks if player is still hosting (on update)
|
||||||
function vmf.check_mutators_state()
|
function vmf.check_mutators_state()
|
||||||
if not _ALL_MUTATORS_DISABLED and not player_is_server() then
|
if not _all_mutators_disabled and not player_is_server() then
|
||||||
disable_impossible_mutators(false, "disabled_reason_not_server")
|
disable_impossible_mutators(false, "disabled_reason_not_server")
|
||||||
_ALL_MUTATORS_DISABLED = true
|
_all_mutators_disabled = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Is called only after VMF reloading to check if some mutators were enabled before reloading
|
-- Is called only after VMF reloading to check if some mutators were enabled before reloading
|
||||||
function vmf.is_mutator_enabled(mutator_name)
|
function vmf.is_mutator_enabled(mutator_name)
|
||||||
return _ENABLED_MUTATORS[mutator_name]
|
return _enabled_mutators[mutator_name]
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Removes all raw_configs which won't be used anymore
|
-- Removes all raw_configs which won't be used anymore
|
||||||
function vmf.mutators_delete_raw_config()
|
function vmf.mutators_delete_raw_config()
|
||||||
for _, mutator in ipairs(_MUTATORS) do
|
for _, mutator in ipairs(_mutators) do
|
||||||
mutator:get_config().raw_config = nil
|
mutator:get_config().raw_config = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
local vmf = get_mod("VMF")
|
local vmf = get_mod("VMF")
|
||||||
|
|
||||||
local _VMF_USERS = {}
|
local _vmf_users = {}
|
||||||
local _RPC_CALLBACKS = {}
|
local _rpc_callbacks = {}
|
||||||
|
|
||||||
local _LOCAL_MODS_MAP = {}
|
local _local_mods_map = {}
|
||||||
local _LOCAL_RPCS_MAP = {}
|
local _local_rpcs_map = {}
|
||||||
|
|
||||||
local _SHARED_MODS_MAP = ""
|
local _shared_mods_map = ""
|
||||||
local _SHARED_RPCS_MAP = ""
|
local _shared_rpcs_map = ""
|
||||||
|
|
||||||
local _NETWORK_MODULE_IS_INITIALIZED = false
|
local _network_module_is_initialized = false
|
||||||
|
local _network_debug = false
|
||||||
|
|
||||||
local _NETWORK_DEBUG = false
|
local VERMINTIDE_CHANNEL_ID = 1
|
||||||
|
local RPC_VMF_REQUEST_CHANNEL_ID = 3
|
||||||
|
local RPC_VMF_RESPONCE_CHANNEL_ID = 4
|
||||||
|
local RPC_VMF_UNKNOWN_CHANNEL_ID = 5 -- Note(Siku): No clue what 5 is supposed to mean.
|
||||||
|
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
-- ##### Local functions ##############################################################################################
|
-- ##### Local functions ##############################################################################################
|
||||||
|
@ -19,7 +23,7 @@ local _NETWORK_DEBUG = false
|
||||||
|
|
||||||
local function is_rpc_registered(mod_name, rpc_name)
|
local function is_rpc_registered(mod_name, rpc_name)
|
||||||
|
|
||||||
local success = pcall(function() return _RPC_CALLBACKS[mod_name][rpc_name] end)
|
local success = pcall(function() return _rpc_callbacks[mod_name][rpc_name] end)
|
||||||
return success
|
return success
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -27,7 +31,7 @@ end
|
||||||
|
|
||||||
local function convert_names_to_numbers(peer_id, mod_name, rpc_name)
|
local function convert_names_to_numbers(peer_id, mod_name, rpc_name)
|
||||||
|
|
||||||
local user_rpcs_dictionary = _VMF_USERS[peer_id]
|
local user_rpcs_dictionary = _vmf_users[peer_id]
|
||||||
if user_rpcs_dictionary then
|
if user_rpcs_dictionary then
|
||||||
|
|
||||||
local mod_number = user_rpcs_dictionary[1][mod_name]
|
local mod_number = user_rpcs_dictionary[1][mod_name]
|
||||||
|
@ -45,10 +49,10 @@ end
|
||||||
|
|
||||||
local function convert_numbers_to_names(mod_number, rpc_number)
|
local function convert_numbers_to_names(mod_number, rpc_number)
|
||||||
|
|
||||||
local mod_name = _LOCAL_MODS_MAP[mod_number]
|
local mod_name = _local_mods_map[mod_number]
|
||||||
if mod_name then
|
if mod_name then
|
||||||
|
|
||||||
local rpc_name = _LOCAL_RPCS_MAP[mod_number][rpc_number]
|
local rpc_name = _local_rpcs_map[mod_number][rpc_number]
|
||||||
if rpc_name then
|
if rpc_name then
|
||||||
|
|
||||||
return mod_name, rpc_name
|
return mod_name, rpc_name
|
||||||
|
@ -84,14 +88,18 @@ end
|
||||||
|
|
||||||
local function network_debug(rpc_type, action_type, peer_id, mod_name, rpc_name, data)
|
local function network_debug(rpc_type, action_type, peer_id, mod_name, rpc_name, data)
|
||||||
|
|
||||||
if _NETWORK_DEBUG then
|
if _network_debug then
|
||||||
|
|
||||||
local debug_message = nil
|
local debug_message
|
||||||
|
|
||||||
if action_type == "local" then
|
if action_type == "local" then
|
||||||
debug_message = "[NETWORK][LOCAL]"
|
debug_message = "[NETWORK][LOCAL]"
|
||||||
else
|
else
|
||||||
debug_message = "[NETWORK][" .. peer_id .. " (" .. tostring(Managers.player:player_from_peer_id(peer_id)) .. ")]" .. (action_type == "sent" and "<-" or "->")
|
local msg_direction = (action_type == "sent" and "<-" or "->")
|
||||||
|
local player_string = tostring(Managers.player:player_from_peer_id(peer_id))
|
||||||
|
--NOTE (Siku): Multiple concatenation requires the creation of multiple strings, look into it.
|
||||||
|
--debug_message = string.format("[NETWORK][%s (%s)] %s", peer_id, player_string, msg_direction)
|
||||||
|
debug_message = "[NETWORK][" .. peer_id .. " (" .. player_string .. ")]" .. msg_direction
|
||||||
end
|
end
|
||||||
|
|
||||||
if rpc_type == "ping" then
|
if rpc_type == "ping" then
|
||||||
|
@ -104,6 +112,7 @@ local function network_debug(rpc_type, action_type, peer_id, mod_name, rpc_name,
|
||||||
|
|
||||||
elseif rpc_type == "data" then
|
elseif rpc_type == "data" then
|
||||||
|
|
||||||
|
--debug_message = string.format("%s[DATA][%s][%s]: ", debug_message, mod_name, rpc_name)
|
||||||
debug_message = debug_message .. "[DATA][" .. mod_name .. "][" .. rpc_name .. "]: "
|
debug_message = debug_message .. "[DATA][" .. mod_name .. "][" .. rpc_name .. "]: "
|
||||||
|
|
||||||
if type(data) == "string" then
|
if type(data) == "string" then
|
||||||
|
@ -131,7 +140,7 @@ end
|
||||||
local function send_rpc_vmf_pong(peer_id)
|
local function send_rpc_vmf_pong(peer_id)
|
||||||
|
|
||||||
network_debug("pong", "sent", peer_id)
|
network_debug("pong", "sent", peer_id)
|
||||||
RPC.rpc_chat_message(peer_id, 4, Network.peer_id(), _SHARED_MODS_MAP, _SHARED_RPCS_MAP, false, true, false)
|
RPC.rpc_chat_message(peer_id, 4, Network.peer_id(), _shared_mods_map, _shared_rpcs_map, false, true, false)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function send_rpc_vmf_data(peer_id, mod_name, rpc_name, ...)
|
local function send_rpc_vmf_data(peer_id, mod_name, rpc_name, ...)
|
||||||
|
@ -156,7 +165,7 @@ local function send_rpc_vmf_data_local(mod_name, rpc_name, ...)
|
||||||
network_debug("data", "local", nil, mod_name, rpc_name, {...})
|
network_debug("data", "local", nil, mod_name, rpc_name, {...})
|
||||||
|
|
||||||
local error_prefix = "(local rpc) " .. tostring(rpc_name)
|
local error_prefix = "(local rpc) " .. tostring(rpc_name)
|
||||||
vmf.xpcall_no_return_values(mod, error_prefix, _RPC_CALLBACKS[mod_name][rpc_name], Network.peer_id(), ...)
|
vmf.xpcall_no_return_values(mod, error_prefix, _rpc_callbacks[mod_name][rpc_name], Network.peer_id(), ...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -166,7 +175,7 @@ end
|
||||||
|
|
||||||
VMFMod.network_register = function (self, rpc_name, rpc_function)
|
VMFMod.network_register = function (self, rpc_name, rpc_function)
|
||||||
|
|
||||||
if _NETWORK_MODULE_IS_INITIALIZED then
|
if _network_module_is_initialized then
|
||||||
self:error("(network_register): you can't register new rpc after mod initialization")
|
self:error("(network_register): you can't register new rpc after mod initialization")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -176,9 +185,9 @@ VMFMod.network_register = function (self, rpc_name, rpc_function)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
_RPC_CALLBACKS[self:get_name()] = _RPC_CALLBACKS[self:get_name()] or {}
|
_rpc_callbacks[self:get_name()] = _rpc_callbacks[self:get_name()] or {}
|
||||||
|
|
||||||
_RPC_CALLBACKS[self:get_name()][rpc_name] = rpc_function
|
_rpc_callbacks[self:get_name()][rpc_name] = rpc_function
|
||||||
end
|
end
|
||||||
|
|
||||||
-- recipient = "all", "local", "others", peer_id
|
-- recipient = "all", "local", "others", peer_id
|
||||||
|
@ -192,7 +201,7 @@ VMFMod.network_send = function (self, rpc_name, recipient, ...)
|
||||||
|
|
||||||
if recipient == "all" then
|
if recipient == "all" then
|
||||||
|
|
||||||
for peer_id, _ in pairs(_VMF_USERS) do
|
for peer_id, _ in pairs(_vmf_users) do
|
||||||
send_rpc_vmf_data(peer_id, self:get_name(), rpc_name, ...)
|
send_rpc_vmf_data(peer_id, self:get_name(), rpc_name, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -200,7 +209,7 @@ VMFMod.network_send = function (self, rpc_name, recipient, ...)
|
||||||
|
|
||||||
elseif recipient == "others" then
|
elseif recipient == "others" then
|
||||||
|
|
||||||
for peer_id, _ in pairs(_VMF_USERS) do
|
for peer_id, _ in pairs(_vmf_users) do
|
||||||
send_rpc_vmf_data(peer_id, self:get_name(), rpc_name, ...)
|
send_rpc_vmf_data(peer_id, self:get_name(), rpc_name, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -218,27 +227,29 @@ end
|
||||||
-- ##### Hooks ########################################################################################################
|
-- ##### Hooks ########################################################################################################
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
|
|
||||||
vmf:hook("ChatManager.rpc_chat_message", function(func, self, sender, channel_id, message_sender, message, localization_param, ...)
|
vmf:hook("ChatManager.rpc_chat_message",
|
||||||
|
function(func, self, sender, channel_id, message_sender, message, localization_param, ...)
|
||||||
|
|
||||||
if channel_id == 1 then
|
if channel_id == VERMINTIDE_CHANNEL_ID then
|
||||||
|
|
||||||
func(self, sender, channel_id, message_sender, message, localization_param, ...)
|
func(self, sender, channel_id, message_sender, message, localization_param, ...)
|
||||||
else
|
else
|
||||||
|
|
||||||
if not _NETWORK_MODULE_IS_INITIALIZED then
|
if not _network_module_is_initialized then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if channel_id == 3 then -- rpc_vmf_request
|
if channel_id == RPC_VMF_REQUEST_CHANNEL_ID then -- rpc_vmf_request
|
||||||
|
|
||||||
network_debug("ping", "received", sender)
|
network_debug("ping", "received", sender)
|
||||||
|
|
||||||
send_rpc_vmf_pong(sender)
|
send_rpc_vmf_pong(sender)
|
||||||
|
|
||||||
elseif channel_id == 4 then -- rpc_vmf_responce (@TODO: maybe I should protect it from sending by the player who's not in the game?)
|
elseif channel_id == RPC_VMF_RESPONCE_CHANNEL_ID then -- rpc_vmf_responce
|
||||||
|
-- @TODO: maybe I should protect it from sending by the player who's not in the game?
|
||||||
|
|
||||||
network_debug("pong", "received", sender)
|
network_debug("pong", "received", sender)
|
||||||
if _NETWORK_DEBUG then
|
if _network_debug then
|
||||||
vmf:info("[RECEIVED MODS TABLE]: " .. message)
|
vmf:info("[RECEIVED MODS TABLE]: " .. message)
|
||||||
vmf:info("[RECEIVED RPCS TABLE]: " .. localization_param)
|
vmf:info("[RECEIVED RPCS TABLE]: " .. localization_param)
|
||||||
end
|
end
|
||||||
|
@ -250,7 +261,7 @@ vmf:hook("ChatManager.rpc_chat_message", function(func, self, sender, channel_id
|
||||||
user_rpcs_dictionary[1] = cjson.decode(message) -- mods
|
user_rpcs_dictionary[1] = cjson.decode(message) -- mods
|
||||||
user_rpcs_dictionary[2] = cjson.decode(localization_param) -- rpcs
|
user_rpcs_dictionary[2] = cjson.decode(localization_param) -- rpcs
|
||||||
|
|
||||||
_VMF_USERS[sender] = user_rpcs_dictionary
|
_vmf_users[sender] = user_rpcs_dictionary
|
||||||
|
|
||||||
vmf:info("Added %s to the VMF users list.", sender)
|
vmf:info("Added %s to the VMF users list.", sender)
|
||||||
|
|
||||||
|
@ -267,7 +278,7 @@ vmf:hook("ChatManager.rpc_chat_message", function(func, self, sender, channel_id
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
elseif channel_id == 5 then
|
elseif channel_id == RPC_VMF_UNKNOWN_CHANNEL_ID then
|
||||||
|
|
||||||
local mod_number, rpc_number = unpack(cjson.decode(message))
|
local mod_number, rpc_number = unpack(cjson.decode(message))
|
||||||
|
|
||||||
|
@ -281,7 +292,7 @@ vmf:hook("ChatManager.rpc_chat_message", function(func, self, sender, channel_id
|
||||||
vmf.xpcall_no_return_values(
|
vmf.xpcall_no_return_values(
|
||||||
get_mod(mod_name),
|
get_mod(mod_name),
|
||||||
error_prefix,
|
error_prefix,
|
||||||
function() _RPC_CALLBACKS[mod_name][rpc_name](sender, deserialize_data(localization_param)) end
|
function() _rpc_callbacks[mod_name][rpc_name](sender, deserialize_data(localization_param)) end
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -299,7 +310,7 @@ end)
|
||||||
|
|
||||||
vmf:hook("PlayerManager.remove_player", function (func, self, peer_id, local_player_id)
|
vmf:hook("PlayerManager.remove_player", function (func, self, peer_id, local_player_id)
|
||||||
|
|
||||||
if _VMF_USERS[peer_id] then
|
if _vmf_users[peer_id] then
|
||||||
|
|
||||||
-- make sure it's not the bot
|
-- make sure it's not the bot
|
||||||
for _, player in pairs(Managers.player:human_players()) do
|
for _, player in pairs(Managers.player:human_players()) do
|
||||||
|
@ -308,14 +319,14 @@ vmf:hook("PlayerManager.remove_player", function (func, self, peer_id, local_pla
|
||||||
vmf:info("Removed %s from the VMF users list.", peer_id)
|
vmf:info("Removed %s from the VMF users list.", peer_id)
|
||||||
|
|
||||||
-- event
|
-- event
|
||||||
for mod_name, _ in pairs(_VMF_USERS[peer_id][1]) do
|
for mod_name, _ in pairs(_vmf_users[peer_id][1]) do
|
||||||
local mod = get_mod(mod_name)
|
local mod = get_mod(mod_name)
|
||||||
if mod then
|
if mod then
|
||||||
vmf.mod_user_left_the_game(mod, player)
|
vmf.mod_user_left_the_game(mod, player)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
_VMF_USERS[peer_id] = nil
|
_vmf_users[peer_id] = nil
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -330,34 +341,32 @@ end)
|
||||||
|
|
||||||
vmf.create_network_dictionary = function()
|
vmf.create_network_dictionary = function()
|
||||||
|
|
||||||
_SHARED_MODS_MAP = {}
|
_shared_mods_map = {}
|
||||||
_SHARED_RPCS_MAP = {}
|
_shared_rpcs_map = {}
|
||||||
|
|
||||||
local i = 0
|
local i = 0
|
||||||
for mod_name, mod_rpcs in pairs(_RPC_CALLBACKS) do
|
for mod_name, mod_rpcs in pairs(_rpc_callbacks) do
|
||||||
|
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
|
||||||
_SHARED_MODS_MAP[mod_name] = i
|
_shared_mods_map[mod_name] = i
|
||||||
_LOCAL_MODS_MAP[i] = mod_name
|
_local_mods_map[i] = mod_name
|
||||||
|
|
||||||
_SHARED_RPCS_MAP[i] = {}
|
_shared_rpcs_map[i] = {}
|
||||||
_LOCAL_RPCS_MAP[i] = {}
|
_local_rpcs_map[i] = {}
|
||||||
|
|
||||||
local j = 0
|
local j = 0
|
||||||
for rpc_name, _ in pairs(mod_rpcs) do
|
for rpc_name, _ in pairs(mod_rpcs) do
|
||||||
|
|
||||||
j = j + 1
|
j = j + 1
|
||||||
|
|
||||||
_SHARED_RPCS_MAP[i][rpc_name] = j
|
_shared_rpcs_map[i][rpc_name] = j
|
||||||
_LOCAL_RPCS_MAP[i][j] = rpc_name
|
_local_rpcs_map[i][j] = rpc_name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
_SHARED_MODS_MAP = cjson.encode(_SHARED_MODS_MAP)
|
_shared_mods_map = cjson.encode(_shared_mods_map)
|
||||||
_SHARED_RPCS_MAP = cjson.encode(_SHARED_RPCS_MAP)
|
_shared_rpcs_map = cjson.encode(_shared_rpcs_map)
|
||||||
|
|
||||||
_NETWORK_MODULE_IS_INITIALIZED = true
|
_network_module_is_initialized = true
|
||||||
end
|
end
|
||||||
|
|
||||||
vmf.ping_vmf_users = function()
|
vmf.ping_vmf_users = function()
|
||||||
|
@ -374,7 +383,7 @@ vmf.ping_vmf_users = function()
|
||||||
end
|
end
|
||||||
|
|
||||||
vmf.load_network_settings = function()
|
vmf.load_network_settings = function()
|
||||||
_NETWORK_DEBUG = vmf:get("developer_mode") and vmf:get("show_network_debug_info")
|
_network_debug = vmf:get("developer_mode") and vmf:get("show_network_debug_info")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
|
|
|
@ -2,7 +2,7 @@ local vmf = get_mod("VMF")
|
||||||
|
|
||||||
Managers.vmf.persistent_tables = Managers.vmf.persistent_tables or {}
|
Managers.vmf.persistent_tables = Managers.vmf.persistent_tables or {}
|
||||||
|
|
||||||
local _PERSISTENT_TABLES = Managers.vmf.persistent_tables
|
local _persistent_tables = Managers.vmf.persistent_tables
|
||||||
|
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
-- ##### VMFMod #######################################################################################################
|
-- ##### VMFMod #######################################################################################################
|
||||||
|
@ -15,11 +15,9 @@ VMFMod.persistent_table = function (self, table_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
local mod_name = self:get_name()
|
local mod_name = self:get_name()
|
||||||
|
_persistent_tables[mod_name] = _persistent_tables[mod_name] or {}
|
||||||
|
|
||||||
_PERSISTENT_TABLES[mod_name] = _PERSISTENT_TABLES[mod_name] or {}
|
local mod_tables = _persistent_tables[mod_name]
|
||||||
|
|
||||||
local mod_tables = _PERSISTENT_TABLES[mod_name]
|
|
||||||
|
|
||||||
mod_tables[table_name] = mod_tables[table_name] or {}
|
mod_tables[table_name] = mod_tables[table_name] or {}
|
||||||
|
|
||||||
return mod_tables[table_name]
|
return mod_tables[table_name]
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
--]]
|
--]]
|
||||||
local vmf = get_mod("VMF")
|
local vmf = get_mod("VMF")
|
||||||
|
|
||||||
local _MODS_SETTINGS = Application.user_setting("mods_settings") or {}
|
local _mods_settings = Application.user_setting("mods_settings") or {}
|
||||||
|
|
||||||
local _THERE_ARE_UNSAVED_CHANGES = false
|
local _there_are_unsaved_changes = false
|
||||||
|
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
-- ##### Local functions ##############################################################################################
|
-- ##### Local functions ##############################################################################################
|
||||||
|
@ -16,11 +16,11 @@ local _THERE_ARE_UNSAVED_CHANGES = false
|
||||||
|
|
||||||
local function save_all_settings()
|
local function save_all_settings()
|
||||||
|
|
||||||
if _THERE_ARE_UNSAVED_CHANGES then
|
if _there_are_unsaved_changes then
|
||||||
Application.set_user_setting("mods_settings", _MODS_SETTINGS)
|
Application.set_user_setting("mods_settings", _mods_settings)
|
||||||
Application.save_user_settings()
|
Application.save_user_settings()
|
||||||
|
|
||||||
_THERE_ARE_UNSAVED_CHANGES = false
|
_there_are_unsaved_changes = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -31,21 +31,23 @@ end
|
||||||
--[[
|
--[[
|
||||||
* setting_name [string] : setting name, can contain any characters lua-string can
|
* setting_name [string] : setting name, can contain any characters lua-string can
|
||||||
* setting_value [anything]: setting value, will be serialized to SJSON format, so you can save whole tables
|
* setting_value [anything]: setting value, will be serialized to SJSON format, so you can save whole tables
|
||||||
* call_setting_changed_event [bool] : if 'true', when some setting will be changed, 'setting_changed' event will be called (if mod defined one)
|
|
||||||
|
* call_setting_changed_event [bool]:
|
||||||
|
if 'true', when some setting will be changed, 'setting_changed' event will be called (if mod defined one)
|
||||||
--]]
|
--]]
|
||||||
VMFMod.set = function (self, setting_name, setting_value, call_setting_changed_event)
|
VMFMod.set = function (self, setting_name, setting_value, call_setting_changed_event)
|
||||||
|
|
||||||
local mod_name = self:get_name()
|
local mod_name = self:get_name()
|
||||||
|
|
||||||
if not _MODS_SETTINGS[mod_name] then
|
if not _mods_settings[mod_name] then
|
||||||
_MODS_SETTINGS[mod_name] = {}
|
_mods_settings[mod_name] = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
local mod_settings = _MODS_SETTINGS[mod_name]
|
local mod_settings = _mods_settings[mod_name]
|
||||||
|
|
||||||
mod_settings[setting_name] = type(setting_value) == "table" and table.clone(setting_value) or setting_value
|
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 then
|
if call_setting_changed_event then
|
||||||
vmf.mod_setting_changed_event(self, setting_name)
|
vmf.mod_setting_changed_event(self, setting_name)
|
||||||
|
@ -59,7 +61,7 @@ VMFMod.get = function (self, setting_name)
|
||||||
|
|
||||||
local mod_name = self:get_name()
|
local mod_name = self:get_name()
|
||||||
|
|
||||||
local mod_settings = _MODS_SETTINGS[mod_name]
|
local mod_settings = _mods_settings[mod_name]
|
||||||
|
|
||||||
local setting_value
|
local setting_value
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
local vmf = get_mod("VMF")
|
local vmf = get_mod("VMF")
|
||||||
|
|
||||||
local _DISABLED_MODS = vmf:get("disabled_mods_list") or {}
|
local _disabled_mods = vmf:get("disabled_mods_list") or {}
|
||||||
|
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
-- ##### VMF internal functions and variables #########################################################################
|
-- ##### VMF internal functions and variables #########################################################################
|
||||||
|
@ -20,11 +20,11 @@ vmf.set_mod_state = function (mod, is_enabled, initial_call)
|
||||||
|
|
||||||
if not (initial_call or mod:is_mutator()) then
|
if not (initial_call or mod:is_mutator()) then
|
||||||
if is_enabled then
|
if is_enabled then
|
||||||
_DISABLED_MODS[mod:get_name()] = nil
|
_disabled_mods[mod:get_name()] = nil
|
||||||
else
|
else
|
||||||
_DISABLED_MODS[mod:get_name()] = true
|
_disabled_mods[mod:get_name()] = true
|
||||||
end
|
end
|
||||||
vmf:set("disabled_mods_list", _DISABLED_MODS)
|
vmf:set("disabled_mods_list", _disabled_mods)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ vmf.initialize_mod_state = function (mod)
|
||||||
end
|
end
|
||||||
vmf.set_mutator_state(mod, state, true)
|
vmf.set_mutator_state(mod, state, true)
|
||||||
else
|
else
|
||||||
state = not _DISABLED_MODS[mod:get_name()]
|
state = not _disabled_mods[mod:get_name()]
|
||||||
vmf.set_mod_state(mod, state, true)
|
vmf.set_mod_state(mod, state, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
local vmf = get_mod("VMF")
|
local vmf = get_mod("VMF")
|
||||||
|
|
||||||
DEV_CONSOLE_ENABLED = DEV_CONSOLE_ENABLED or false
|
-- Note(Siku): This file could definitely use the hooking system if we could figure out a way.
|
||||||
PRINT_ORIGINAL_FUNCTION = PRINT_ORIGINAL_FUNCTION or print
|
-- It would requires hooks to be pushed higher in the loading order, but then we lose hooks printing to console
|
||||||
|
-- Unless we find a way to store our logging messages in memory before the console is loaded.
|
||||||
|
|
||||||
|
local _console_data = vmf:persistent_table("dev_console_data")
|
||||||
|
if not _console_data.enabled then _console_data.enabled = false end
|
||||||
|
if not _console_data.original_print then _console_data.original_print = print end
|
||||||
|
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
-- ##### Local functions ##############################################################################################
|
-- ##### Local functions ##############################################################################################
|
||||||
|
@ -9,10 +14,10 @@ PRINT_ORIGINAL_FUNCTION = PRINT_ORIGINAL_FUNCTION or print
|
||||||
|
|
||||||
local function open_dev_console()
|
local function open_dev_console()
|
||||||
|
|
||||||
if not DEV_CONSOLE_ENABLED then
|
if not _console_data.enabled then
|
||||||
|
|
||||||
local print_hook_function = function(func, ...)
|
local print_hook_function = function(func, ...)
|
||||||
if DEV_CONSOLE_ENABLED then
|
if _console_data.enabled then
|
||||||
CommandWindow.print(...)
|
CommandWindow.print(...)
|
||||||
func(...)
|
func(...)
|
||||||
else
|
else
|
||||||
|
@ -21,19 +26,19 @@ local function open_dev_console()
|
||||||
end
|
end
|
||||||
|
|
||||||
print = function(...)
|
print = function(...)
|
||||||
print_hook_function(PRINT_ORIGINAL_FUNCTION, ...)
|
print_hook_function(_console_data.original_print, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
CommandWindow.open("Developer console")
|
CommandWindow.open("Developer console")
|
||||||
DEV_CONSOLE_ENABLED = true
|
_console_data.enabled = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function close_dev_console()
|
local function close_dev_console()
|
||||||
|
|
||||||
if DEV_CONSOLE_ENABLED then
|
if _console_data.enabled then
|
||||||
|
|
||||||
print = PRINT_ORIGINAL_FUNCTION
|
print = _console_data.original_print
|
||||||
|
|
||||||
CommandWindow.close()
|
CommandWindow.close()
|
||||||
|
|
||||||
|
@ -49,7 +54,7 @@ local function close_dev_console()
|
||||||
ffi.C.SendMessageA(hwnd, WM_CLOSE, 0, 0)
|
ffi.C.SendMessageA(hwnd, WM_CLOSE, 0, 0)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
DEV_CONSOLE_ENABLED = false
|
_console_data.enabled = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -188,7 +188,8 @@ local function table_dump_to_file(dumped_table, dumped_table_name, max_depth)
|
||||||
table_entry[key] = "[" .. value_type .. "]"
|
table_entry[key] = "[" .. value_type .. "]"
|
||||||
else
|
else
|
||||||
|
|
||||||
table_entry[key] = tostring(value):gsub('\\','\\\\'):gsub('\"','\\\"'):gsub('\t','\\t'):gsub('\n','\\n') .. " (" .. value_type .. ")"
|
value = tostring(value):gsub('\\','\\\\'):gsub('\"','\\\"'):gsub('\t','\\t'):gsub('\n','\\n')
|
||||||
|
table_entry[key] = value .. " (" .. value_type .. ")"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,7 +37,8 @@ VMFMod.register_new_view = function (self, new_view_data)
|
||||||
and not ingame_ui.menu_active
|
and not ingame_ui.menu_active
|
||||||
and not ingame_ui.leave_game
|
and not ingame_ui.leave_game
|
||||||
and not ingame_ui.return_to_title_screen
|
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'
|
-- V2 doesn't have 'popup_join_lobby_handler'
|
||||||
|
and not (ingame_ui.popup_join_lobby_handler and ingame_ui.popup_join_lobby_handler.visible)
|
||||||
then
|
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
|
||||||
|
@ -137,12 +138,16 @@ vmf.check_custom_menus_close_keybinds = function()
|
||||||
opening_keybind_is_pressed = false
|
opening_keybind_is_pressed = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local input_ctrl = input_service:get("ctrl")
|
||||||
|
local input_shift = input_service:get("shift")
|
||||||
|
local input_alt = input_service:get("alt")
|
||||||
|
|
||||||
local close_menu = false
|
local close_menu = false
|
||||||
if not opening_keybind_is_pressed then
|
if not opening_keybind_is_pressed then
|
||||||
if input_service:get(close_keybind[1]) and
|
if input_service:get(close_keybind[1]) and
|
||||||
(not close_keybind[2] and not input_service:get("ctrl") or close_keybind[2] and input_service:get("ctrl")) and
|
(not close_keybind[2] and not input_ctrl or close_keybind[2] and input_ctrl) and
|
||||||
(not close_keybind[3] and not input_service:get("alt") or close_keybind[3] and input_service:get("alt")) and
|
(not close_keybind[3] and not input_alt or close_keybind[3] and input_alt) and
|
||||||
(not close_keybind[4] and not input_service:get("shift") or close_keybind[4] and input_service:get("shift")) then
|
(not close_keybind[4] and not input_shift or close_keybind[4] and input_shift) then
|
||||||
|
|
||||||
close_menu = not ingame_ui.views[ingame_ui.current_view]:input_service():is_blocked()
|
close_menu = not ingame_ui.views[ingame_ui.current_view]:input_service():is_blocked()
|
||||||
end
|
end
|
||||||
|
@ -188,9 +193,13 @@ end
|
||||||
|
|
||||||
local ingame_ui_exists, ingame_ui_return
|
local ingame_ui_exists, ingame_ui_return
|
||||||
if VT1 then
|
if VT1 then
|
||||||
ingame_ui_exists, ingame_ui_return = pcall(function () return Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui end)
|
ingame_ui_exists, ingame_ui_return = pcall(function()
|
||||||
|
return Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui
|
||||||
|
end)
|
||||||
else
|
else
|
||||||
ingame_ui_exists, ingame_ui_return = pcall(function () return Managers.player.network_manager.matchmaking_manager._ingame_ui end)
|
ingame_ui_exists, ingame_ui_return = pcall(function()
|
||||||
|
return Managers.player.network_manager.matchmaking_manager._ingame_ui
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- if VMF is reloaded mid-game
|
-- if VMF is reloaded mid-game
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
local vmf = get_mod("VMF")
|
local vmf = get_mod("VMF")
|
||||||
|
|
||||||
UI_RENDERERS = UI_RENDERERS or {}
|
local _ui_renderers = vmf:persistent_table("_ui_renderers")
|
||||||
|
|
||||||
local _CUSTOM_NONE_ATLAS_TEXTURES = {}
|
local _custom_none_atlas_textures = {}
|
||||||
local _CUSTOM_UI_ATLAS_SETTINGS = {}
|
local _custom_ui_atlas_settings = {}
|
||||||
|
|
||||||
local _INJECTED_MATERIALS = {}
|
local _injected_materials = {}
|
||||||
|
|
||||||
local _SHOW_DEBUG_INFO = false
|
local _show_debug_info = false
|
||||||
|
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
-- ##### Local functions ##############################################################################################
|
-- ##### Local functions ##############################################################################################
|
||||||
|
@ -20,22 +20,26 @@ local function check_texture_availability(mod, texture_name)
|
||||||
if texture_exists then
|
if texture_exists then
|
||||||
|
|
||||||
if type(texture_settings) == "nil" then
|
if type(texture_settings) == "nil" then
|
||||||
mod:error("(custom texture/atlas): texture name '%s' is already used by Fatshark in 'none_atlas_textures'", texture_name)
|
mod:error("(custom texture/atlas): texture name '%s' is already used by Fatshark in 'none_atlas_textures'",
|
||||||
|
texture_name)
|
||||||
else
|
else
|
||||||
mod:error("(custom texture/atlas): texture name '%s' is already used by Fatshark in atlas '%s'", texture_name, tostring(texture_settings.material_name))
|
mod:error("(custom texture/atlas): texture name '%s' is already used by Fatshark in atlas '%s'",
|
||||||
|
texture_name, tostring(texture_settings.material_name))
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if _CUSTOM_NONE_ATLAS_TEXTURES[texture_name] then
|
if _custom_none_atlas_textures[texture_name] then
|
||||||
mod:error("(custom texture/atlas): texture name '%s' is already used by the mod '%s' as none atlas texture", texture_name, _CUSTOM_NONE_ATLAS_TEXTURES[texture_name])
|
mod:error("(custom texture/atlas): texture name '%s' is already used by the mod '%s' as none atlas texture",
|
||||||
|
texture_name, _custom_none_atlas_textures[texture_name])
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if _CUSTOM_UI_ATLAS_SETTINGS[texture_name] then
|
if _custom_ui_atlas_settings[texture_name] then
|
||||||
texture_settings = _CUSTOM_UI_ATLAS_SETTINGS[texture_name]
|
texture_settings = _custom_ui_atlas_settings[texture_name]
|
||||||
mod:error("(custom texture/atlas): texture name '%s' is already used by the mod '%s' in atlas '%s'", texture_name, texture_settings.mod_name, tostring(texture_settings.material_name))
|
mod:error("(custom texture/atlas): texture name '%s' is already used by the mod '%s' in atlas '%s'",
|
||||||
|
texture_name, texture_settings.mod_name, tostring(texture_settings.material_name))
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -51,23 +55,31 @@ vmf.custom_textures = function (mod, ...)
|
||||||
for i, texture_name in ipairs({...}) do
|
for i, texture_name in ipairs({...}) do
|
||||||
if type(texture_name) == "string" then
|
if type(texture_name) == "string" then
|
||||||
if check_texture_availability(mod, texture_name) then
|
if check_texture_availability(mod, texture_name) then
|
||||||
_CUSTOM_NONE_ATLAS_TEXTURES[texture_name] = mod:get_name()
|
_custom_none_atlas_textures[texture_name] = mod:get_name()
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
mod:error("(custom_textures): all arguments should have the string type, but the argument #%s is %s", i, type(texture_name))
|
mod:error("(custom_textures): all arguments should have the string type, but the argument #%s is %s",
|
||||||
|
i, type(texture_name))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
vmf.custom_atlas = function (mod, material_settings_file, material_name, masked_material_name, point_sample_material_name,
|
vmf.custom_atlas = function (mod, material_settings_file, material_name, masked_material_name,
|
||||||
masked_point_sample_material_name, saturated_material_name)
|
point_sample_material_name, masked_point_sample_material_name,
|
||||||
|
saturated_material_name)
|
||||||
|
|
||||||
if vmf.check_wrong_argument_type(mod, "custom_atlas", "material_settings_file", material_settings_file, "string") or
|
if vmf.check_wrong_argument_type(mod, "custom_atlas", "material_settings_file",
|
||||||
vmf.check_wrong_argument_type(mod, "custom_atlas", "material_name", material_name, "string", "nil") or
|
material_settings_file, "string") or
|
||||||
vmf.check_wrong_argument_type(mod, "custom_atlas", "masked_material_name", masked_material_name, "string", "nil") or
|
vmf.check_wrong_argument_type(mod, "custom_atlas", "material_name",
|
||||||
vmf.check_wrong_argument_type(mod, "custom_atlas", "point_sample_material_name", point_sample_material_name, "string", "nil") or
|
material_name, "string", "nil") or
|
||||||
vmf.check_wrong_argument_type(mod, "custom_atlas", "masked_point_sample_material_name", masked_point_sample_material_name, "string", "nil") or
|
vmf.check_wrong_argument_type(mod, "custom_atlas", "masked_material_name",
|
||||||
vmf.check_wrong_argument_type(mod, "custom_atlas", "saturated_material_name", saturated_material_name, "string", "nil") then
|
masked_material_name, "string", "nil") or
|
||||||
|
vmf.check_wrong_argument_type(mod, "custom_atlas", "point_sample_material_name",
|
||||||
|
point_sample_material_name, "string", "nil") or
|
||||||
|
vmf.check_wrong_argument_type(mod, "custom_atlas", "masked_point_sample_material_name",
|
||||||
|
masked_point_sample_material_name, "string", "nil") or
|
||||||
|
vmf.check_wrong_argument_type(mod, "custom_atlas", "saturated_material_name",
|
||||||
|
saturated_material_name, "string", "nil") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -86,7 +98,7 @@ vmf.custom_atlas = function (mod, material_settings_file, material_name, masked_
|
||||||
texture_settings.masked_point_sample_material_name = masked_point_sample_material_name
|
texture_settings.masked_point_sample_material_name = masked_point_sample_material_name
|
||||||
texture_settings.saturated_material_name = saturated_material_name
|
texture_settings.saturated_material_name = saturated_material_name
|
||||||
|
|
||||||
_CUSTOM_UI_ATLAS_SETTINGS[texture_name] = texture_settings
|
_custom_ui_atlas_settings[texture_name] = texture_settings
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -101,7 +113,7 @@ vmf.inject_materials = function (mod, ui_renderer_creator, ...)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local injected_materials_list = _INJECTED_MATERIALS[ui_renderer_creator] or {}
|
local injected_materials_list = _injected_materials[ui_renderer_creator] or {}
|
||||||
|
|
||||||
local can_inject
|
local can_inject
|
||||||
for i, new_injected_material in ipairs({...}) do
|
for i, new_injected_material in ipairs({...}) do
|
||||||
|
@ -122,16 +134,17 @@ vmf.inject_materials = function (mod, ui_renderer_creator, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
mod:error("(inject_materials): all arguments should have the string type, but the argument #%s is %s", i + 1, type(new_injected_material))
|
mod:error("(inject_materials): all arguments should have the string type, but the argument #%s is %s",
|
||||||
|
i + 1, type(new_injected_material) )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
_INJECTED_MATERIALS[ui_renderer_creator] = injected_materials_list
|
_injected_materials[ui_renderer_creator] = injected_materials_list
|
||||||
|
|
||||||
-- recreate GUIs with injected materials for ui_renderers created by 'ui_renderer_creator'
|
-- recreate GUIs with injected materials for ui_renderers created by 'ui_renderer_creator'
|
||||||
local vmf_data
|
local vmf_data
|
||||||
|
|
||||||
for ui_renderer, _ in pairs(UI_RENDERERS) do
|
for ui_renderer, _ in pairs(_ui_renderers) do
|
||||||
|
|
||||||
vmf_data = rawget(ui_renderer, "vmf_data")
|
vmf_data = rawget(ui_renderer, "vmf_data")
|
||||||
|
|
||||||
|
@ -190,8 +203,8 @@ vmf:hook("UIRenderer.create", function(func, world, ...)
|
||||||
|
|
||||||
local ui_renderer_materials = {...}
|
local ui_renderer_materials = {...}
|
||||||
|
|
||||||
if _INJECTED_MATERIALS[ui_renderer_creator] then
|
if _injected_materials[ui_renderer_creator] then
|
||||||
for _, injected_material in ipairs(_INJECTED_MATERIALS[ui_renderer_creator]) do
|
for _, injected_material in ipairs(_injected_materials[ui_renderer_creator]) do
|
||||||
table.insert(ui_renderer_materials, "material")
|
table.insert(ui_renderer_materials, "material")
|
||||||
table.insert(ui_renderer_materials, injected_material)
|
table.insert(ui_renderer_materials, injected_material)
|
||||||
end
|
end
|
||||||
|
@ -200,7 +213,7 @@ vmf:hook("UIRenderer.create", function(func, world, ...)
|
||||||
|
|
||||||
-- DEBUG INFO
|
-- DEBUG INFO
|
||||||
|
|
||||||
if _SHOW_DEBUG_INFO then
|
if _show_debug_info then
|
||||||
vmf:info("UI_RENDERER CREATED BY:")
|
vmf:info("UI_RENDERER CREATED BY:")
|
||||||
vmf:info(" %s", ui_renderer_creator)
|
vmf:info(" %s", ui_renderer_creator)
|
||||||
vmf:info("UI_RENDERER MATERIALS:")
|
vmf:info("UI_RENDERER MATERIALS:")
|
||||||
|
@ -213,7 +226,7 @@ vmf:hook("UIRenderer.create", function(func, world, ...)
|
||||||
|
|
||||||
local ui_renderer = func(world, unpack(ui_renderer_materials))
|
local ui_renderer = func(world, unpack(ui_renderer_materials))
|
||||||
|
|
||||||
UI_RENDERERS[ui_renderer] = true
|
_ui_renderers[ui_renderer] = true
|
||||||
|
|
||||||
local vmf_data = {}
|
local vmf_data = {}
|
||||||
vmf_data.original_materials = {...}
|
vmf_data.original_materials = {...}
|
||||||
|
@ -227,7 +240,7 @@ end)
|
||||||
|
|
||||||
vmf:hook("UIRenderer.destroy", function(func, self, world)
|
vmf:hook("UIRenderer.destroy", function(func, self, world)
|
||||||
|
|
||||||
UI_RENDERERS[self] = nil
|
_ui_renderers[self] = nil
|
||||||
|
|
||||||
func(self, world)
|
func(self, world)
|
||||||
end)
|
end)
|
||||||
|
@ -235,7 +248,7 @@ end)
|
||||||
|
|
||||||
vmf:hook("UIAtlasHelper.has_atlas_settings_by_texture_name", function(func, texture_name)
|
vmf:hook("UIAtlasHelper.has_atlas_settings_by_texture_name", function(func, texture_name)
|
||||||
|
|
||||||
if _CUSTOM_UI_ATLAS_SETTINGS[texture_name] then
|
if _custom_ui_atlas_settings[texture_name] then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -245,12 +258,12 @@ end)
|
||||||
|
|
||||||
vmf:hook("UIAtlasHelper.get_atlas_settings_by_texture_name", function(func, texture_name)
|
vmf:hook("UIAtlasHelper.get_atlas_settings_by_texture_name", function(func, texture_name)
|
||||||
|
|
||||||
if _CUSTOM_NONE_ATLAS_TEXTURES[texture_name] then
|
if _custom_none_atlas_textures[texture_name] then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if _CUSTOM_UI_ATLAS_SETTINGS[texture_name] then
|
if _custom_ui_atlas_settings[texture_name] then
|
||||||
return _CUSTOM_UI_ATLAS_SETTINGS[texture_name]
|
return _custom_ui_atlas_settings[texture_name]
|
||||||
end
|
end
|
||||||
|
|
||||||
return func(texture_name)
|
return func(texture_name)
|
||||||
|
@ -261,11 +274,11 @@ end)
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
|
|
||||||
vmf.load_custom_textures_settings = function()
|
vmf.load_custom_textures_settings = function()
|
||||||
_SHOW_DEBUG_INFO = vmf:get("developer_mode") and vmf:get("log_ui_renderers_info")
|
_show_debug_info = vmf:get("developer_mode") and vmf:get("log__ui_renderers_info")
|
||||||
end
|
end
|
||||||
|
|
||||||
vmf.reset_guis = function()
|
vmf.reset_guis = function()
|
||||||
for ui_renderer, _ in pairs(UI_RENDERERS) do
|
for ui_renderer, _ in pairs(_ui_renderers) do
|
||||||
local vmf_data = rawget(ui_renderer, "vmf_data")
|
local vmf_data = rawget(ui_renderer, "vmf_data")
|
||||||
if vmf_data.is_modified then
|
if vmf_data.is_modified then
|
||||||
World.destroy_gui(ui_renderer.world, ui_renderer.gui)
|
World.destroy_gui(ui_renderer.world, ui_renderer.gui)
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
-- If enabled, scale UI for resolutions greater than 1080p when necessary. Reports to a global when active, so that existing scaling can be disabled.
|
-- 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 vmf = get_mod("VMF")
|
local vmf = get_mod("VMF")
|
||||||
|
|
||||||
local _UI_RESOLUTION = UIResolution
|
local _ui_scaling_enabled
|
||||||
local _UI_RESOLUTION_WIDTH_FRAGMENTS = UIResolutionWidthFragments
|
|
||||||
local _UI_RESOLUTION_HEIGHT_FRAGMENTS = UIResolutionHeightFragments
|
|
||||||
local _MATH_MIN = math.min
|
|
||||||
|
|
||||||
local _UI_SCALING_ENABLED
|
|
||||||
|
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
-- ##### Hooks ########################################################################################################
|
-- ##### Hooks ########################################################################################################
|
||||||
|
@ -14,16 +10,17 @@ local _UI_SCALING_ENABLED
|
||||||
|
|
||||||
vmf:hook("UIResolutionScale", function (func, ...)
|
vmf:hook("UIResolutionScale", function (func, ...)
|
||||||
|
|
||||||
local w, h = _UI_RESOLUTION()
|
local width, height = UIResolution()
|
||||||
|
|
||||||
if (w > _UI_RESOLUTION_WIDTH_FRAGMENTS() and h > _UI_RESOLUTION_HEIGHT_FRAGMENTS() and _UI_SCALING_ENABLED) then
|
if (width > UIResolutionWidthFragments() and height > UIResolutionHeightFragments() and _ui_scaling_enabled) then
|
||||||
|
|
||||||
local max_scaling_factor = 4
|
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)
|
-- 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)
|
local width_scale = math.min(width / UIResolutionWidthFragments(), max_scaling_factor)
|
||||||
|
local height_scale = math.min(height / UIResolutionHeightFragments(), max_scaling_factor)
|
||||||
|
|
||||||
return _MATH_MIN(width_scale, height_scale)
|
return math.min(width_scale, height_scale)
|
||||||
else
|
else
|
||||||
return func(...)
|
return func(...)
|
||||||
end
|
end
|
||||||
|
@ -34,8 +31,8 @@ end)
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
|
|
||||||
vmf.load_ui_scaling_settings = function ()
|
vmf.load_ui_scaling_settings = function ()
|
||||||
_UI_SCALING_ENABLED = vmf:get("ui_scaling")
|
_ui_scaling_enabled = vmf:get("ui_scaling")
|
||||||
if _UI_SCALING_ENABLED then
|
if _ui_scaling_enabled then
|
||||||
RESOLUTION_LOOKUP.ui_scaling = true
|
RESOLUTION_LOOKUP.ui_scaling = true
|
||||||
else
|
else
|
||||||
RESOLUTION_LOOKUP.ui_scaling = false
|
RESOLUTION_LOOKUP.ui_scaling = false
|
||||||
|
|
|
@ -5,35 +5,35 @@
|
||||||
]]
|
]]
|
||||||
local vmf = get_mod("VMF")
|
local vmf = get_mod("VMF")
|
||||||
|
|
||||||
local _CHAT_OPENED = false
|
local _chat_opened = false
|
||||||
|
|
||||||
local _COMMANDS_LIST = {}
|
local _commands_list = {}
|
||||||
local _COMMAND_INDEX = 0 -- 0 => nothing selected
|
local _command_index = 0 -- 0 => nothing selected
|
||||||
|
|
||||||
local _COMMANDS_LIST_GUI_DRAW = nil
|
local _commands_list_gui_draw
|
||||||
|
|
||||||
local _CHAT_HISTORY = {}
|
local _chat_history = {}
|
||||||
local _CHAT_HISTORY_INDEX = 0
|
local _chat_history_index = 0
|
||||||
local _CHAT_HISTORY_ENABLED = true
|
local _chat_history_enabled = true
|
||||||
local _CHAT_HISTORY_SAVE = true
|
local _chat_history_save = true
|
||||||
local _CHAT_HISTORY_MAX = 50
|
local _chat_history_max = 50
|
||||||
local _CHAT_HISTORY_REMOVE_DUPS_LAST = false
|
local _chat_history_remove_dups_last = false
|
||||||
local _CHAT_HISTORY_REMOVE_DUPS_ALL = false
|
local _chat_history_remove_dups_all = false
|
||||||
local _CHAT_HISTORY_SAVE_COMMANDS_ONLY = false
|
local _chat_history_save_commands_only = false
|
||||||
|
|
||||||
local _QUEUED_COMMAND -- is a workaround for VT2 where raycast is blocked during ui update
|
local _queued_command -- is a workaround for VT2 where raycast is blocked during ui update
|
||||||
|
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
-- ##### Local functions ##############################################################################################
|
-- ##### Local functions ##############################################################################################
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
|
|
||||||
local function initialize_drawing_function()
|
local function initialize_drawing_function()
|
||||||
_COMMANDS_LIST_GUI_DRAW = dofile("scripts/mods/vmf/modules/ui/chat/commands_list_gui")
|
_commands_list_gui_draw = dofile("scripts/mods/vmf/modules/ui/chat/commands_list_gui")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function clean_chat_history()
|
local function clean_chat_history()
|
||||||
_CHAT_HISTORY = {}
|
_chat_history = {}
|
||||||
_CHAT_HISTORY_INDEX = 0
|
_chat_history_index = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
local function set_chat_message(chat_gui, message)
|
local function set_chat_message(chat_gui, message)
|
||||||
|
@ -60,7 +60,7 @@ end)
|
||||||
vmf:hook("ChatGui.block_input", function(func, ...)
|
vmf:hook("ChatGui.block_input", function(func, ...)
|
||||||
func(...)
|
func(...)
|
||||||
|
|
||||||
_CHAT_OPENED = true
|
_chat_opened = true
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,21 +72,21 @@ vmf:hook("ChatGui._update_input", function(func, self, input_service, menu_input
|
||||||
if Keyboard.pressed(Keyboard.button_index("enter")) then
|
if Keyboard.pressed(Keyboard.button_index("enter")) then
|
||||||
|
|
||||||
-- chat history
|
-- chat history
|
||||||
if _CHAT_HISTORY_ENABLED
|
if _chat_history_enabled
|
||||||
and self.chat_message ~= ""
|
and self.chat_message ~= ""
|
||||||
and not (_CHAT_HISTORY_REMOVE_DUPS_LAST and (self.chat_message == _CHAT_HISTORY[1]))
|
and not (_chat_history_remove_dups_last and (self.chat_message == _chat_history[1]))
|
||||||
and (not _CHAT_HISTORY_SAVE_COMMANDS_ONLY or (_COMMAND_INDEX ~= 0)) then
|
and (not _chat_history_save_commands_only or (_command_index ~= 0)) then
|
||||||
table.insert(_CHAT_HISTORY, 1, self.chat_message)
|
table.insert(_chat_history, 1, self.chat_message)
|
||||||
|
|
||||||
if #_CHAT_HISTORY == _CHAT_HISTORY_MAX + 1 then
|
if #_chat_history == _chat_history_max + 1 then
|
||||||
table.remove(_CHAT_HISTORY, #_CHAT_HISTORY)
|
table.remove(_chat_history, #_chat_history)
|
||||||
end
|
end
|
||||||
|
|
||||||
if _CHAT_HISTORY_REMOVE_DUPS_ALL then
|
if _chat_history_remove_dups_all then
|
||||||
|
|
||||||
for i = 2, #_CHAT_HISTORY do
|
for i = 2, #_chat_history do
|
||||||
if _CHAT_HISTORY[i] == self.chat_message then
|
if _chat_history[i] == self.chat_message then
|
||||||
table.remove(_CHAT_HISTORY, i)
|
table.remove(_chat_history, i)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -94,20 +94,20 @@ vmf:hook("ChatGui._update_input", function(func, self, input_service, menu_input
|
||||||
end
|
end
|
||||||
|
|
||||||
-- command execution
|
-- command execution
|
||||||
if _COMMAND_INDEX ~= 0 then
|
if _command_index ~= 0 then
|
||||||
local args = {}
|
local args = {}
|
||||||
for arg in string.gmatch(self.chat_message, "%S+") do
|
for arg in string.gmatch(self.chat_message, "%S+") do
|
||||||
table.insert(args, arg)
|
table.insert(args, arg)
|
||||||
end
|
end
|
||||||
table.remove(args, 1)
|
table.remove(args, 1)
|
||||||
|
|
||||||
_QUEUED_COMMAND = {
|
_queued_command = {
|
||||||
name = _COMMANDS_LIST[_COMMAND_INDEX].name,
|
name = _commands_list[_command_index].name,
|
||||||
args = args
|
args = args
|
||||||
}
|
}
|
||||||
|
|
||||||
_COMMANDS_LIST = {}
|
_commands_list = {}
|
||||||
_COMMAND_INDEX = 0
|
_command_index = 0
|
||||||
|
|
||||||
set_chat_message(self, "")
|
set_chat_message(self, "")
|
||||||
|
|
||||||
|
@ -117,16 +117,17 @@ vmf:hook("ChatGui._update_input", function(func, self, input_service, menu_input
|
||||||
|
|
||||||
local old_chat_message = self.chat_message
|
local old_chat_message = self.chat_message
|
||||||
|
|
||||||
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
|
||||||
set_chat_message(self, "")
|
set_chat_message(self, "")
|
||||||
|
|
||||||
_CHAT_OPENED = false
|
_chat_opened = false
|
||||||
|
|
||||||
_COMMANDS_LIST = {}
|
_commands_list = {}
|
||||||
_COMMAND_INDEX = 0
|
_command_index = 0
|
||||||
_CHAT_HISTORY_INDEX = 0
|
_chat_history_index = 0
|
||||||
|
|
||||||
if command_executed then
|
if command_executed then
|
||||||
chat_closed = false
|
chat_closed = false
|
||||||
|
@ -134,7 +135,7 @@ vmf:hook("ChatGui._update_input", function(func, self, input_service, menu_input
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if _CHAT_OPENED then
|
if _chat_opened then
|
||||||
|
|
||||||
-- getting state of 'tab', 'arrow up' and 'arrow down' buttons
|
-- getting state of 'tab', 'arrow up' and 'arrow down' buttons
|
||||||
local tab_pressed = false
|
local tab_pressed = false
|
||||||
|
@ -143,7 +144,8 @@ vmf:hook("ChatGui._update_input", function(func, self, input_service, menu_input
|
||||||
for _, stroke in ipairs(Keyboard.keystrokes()) do
|
for _, stroke in ipairs(Keyboard.keystrokes()) do
|
||||||
if stroke == Keyboard.TAB then
|
if stroke == Keyboard.TAB then
|
||||||
tab_pressed = true
|
tab_pressed = true
|
||||||
-- game considers some "ctrl + [something]" combinations as arrow buttons, so I have to check for ctrl not pressed
|
-- game considers some "ctrl + [something]" combinations as arrow buttons,
|
||||||
|
-- so I have to check for ctrl not pressed
|
||||||
elseif stroke == Keyboard.UP and Keyboard.button(Keyboard.button_index("left ctrl")) == 0 then
|
elseif stroke == Keyboard.UP and Keyboard.button(Keyboard.button_index("left ctrl")) == 0 then
|
||||||
arrow_up_pressed = true
|
arrow_up_pressed = true
|
||||||
elseif stroke == Keyboard.DOWN and Keyboard.button(Keyboard.button_index("left ctrl")) == 0 then
|
elseif stroke == Keyboard.DOWN and Keyboard.button(Keyboard.button_index("left ctrl")) == 0 then
|
||||||
|
@ -152,30 +154,31 @@ vmf:hook("ChatGui._update_input", function(func, self, input_service, menu_input
|
||||||
end
|
end
|
||||||
|
|
||||||
-- chat history
|
-- chat history
|
||||||
if _CHAT_HISTORY_ENABLED then
|
if _chat_history_enabled then
|
||||||
|
|
||||||
-- reverse result of native chat history in VT2
|
-- 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
|
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)
|
set_chat_message(self, old_chat_message)
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
if arrow_up_pressed or arrow_down_pressed then
|
if arrow_up_pressed or arrow_down_pressed then
|
||||||
|
|
||||||
local new_index = _CHAT_HISTORY_INDEX + (arrow_up_pressed and 1 or -1)
|
local new_index = _chat_history_index + (arrow_up_pressed and 1 or -1)
|
||||||
new_index = math.clamp(new_index, 0, #_CHAT_HISTORY)
|
new_index = math.clamp(new_index, 0, #_chat_history)
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
set_chat_message(self, _CHAT_HISTORY[new_index])
|
set_chat_message(self, _chat_history[new_index])
|
||||||
|
|
||||||
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
|
||||||
set_chat_message(self, "")
|
set_chat_message(self, "")
|
||||||
end
|
end
|
||||||
|
@ -185,7 +188,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
|
||||||
local new_chat_message = self.chat_message .. tostring(Clipboard.get()):gsub(string.char(0x0D), "") -- remove CR characters
|
-- remove CR characters
|
||||||
|
local new_chat_message = self.chat_message .. tostring(Clipboard.get()):gsub(string.char(0x0D), "")
|
||||||
set_chat_message(self, new_chat_message)
|
set_chat_message(self, new_chat_message)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -197,14 +201,16 @@ vmf:hook("ChatGui._update_input", function(func, self, input_service, menu_input
|
||||||
-- entered chat message starts with "/"
|
-- entered chat message starts with "/"
|
||||||
if string.sub(self.chat_message, 1, 1) == "/" then
|
if string.sub(self.chat_message, 1, 1) == "/" then
|
||||||
|
|
||||||
if not string.find(self.chat_message, " ") -- if there's no space after '/part_of_command_name'
|
-- if there's no space after '/part_of_command_name' and if TAB was pressed
|
||||||
and tab_pressed -- if TAB was pressed
|
if not string.find(self.chat_message, " ") and tab_pressed and
|
||||||
and (string.len(self.chat_message) + 1) == self.chat_index -- if TAB was pressed with caret at the end of the string
|
-- if TAB was pressed with caret at the end of the string
|
||||||
and (#_COMMANDS_LIST > 0) then -- if there are any commands matching entered '/part_of_command_name'
|
(string.len(self.chat_message) + 1) == self.chat_index and
|
||||||
|
-- if there are any commands matching entered '/part_of_command_name
|
||||||
|
(#_commands_list > 0) then
|
||||||
|
|
||||||
_COMMAND_INDEX = _COMMAND_INDEX % #_COMMANDS_LIST + 1
|
_command_index = _command_index % #_commands_list + 1
|
||||||
|
|
||||||
set_chat_message(self, "/" .. _COMMANDS_LIST[_COMMAND_INDEX].name)
|
set_chat_message(self, "/" .. _commands_list[_command_index].name)
|
||||||
|
|
||||||
-- 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
|
||||||
|
@ -217,27 +223,27 @@ vmf:hook("ChatGui._update_input", function(func, self, input_service, menu_input
|
||||||
local command_name_contains = self.chat_message:match("%S+"):sub(2, -1)
|
local command_name_contains = self.chat_message:match("%S+"):sub(2, -1)
|
||||||
|
|
||||||
if string.find(self.chat_message, " ") then
|
if string.find(self.chat_message, " ") then
|
||||||
_COMMANDS_LIST = vmf.get_commands_list(command_name_contains, true)
|
_commands_list = vmf.get_commands_list(command_name_contains, true)
|
||||||
else
|
else
|
||||||
_COMMANDS_LIST = vmf.get_commands_list(command_name_contains)
|
_commands_list = vmf.get_commands_list(command_name_contains)
|
||||||
end
|
end
|
||||||
|
|
||||||
_COMMAND_INDEX = 0
|
_command_index = 0
|
||||||
|
|
||||||
if #_COMMANDS_LIST > 0 and command_name_contains:lower() == _COMMANDS_LIST[1].name then
|
if #_commands_list > 0 and command_name_contains:lower() == _commands_list[1].name then
|
||||||
_COMMAND_INDEX = 1
|
_command_index = 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- chat message was modified and doesn't start with '/'
|
-- chat message was modified and doesn't start with '/'
|
||||||
elseif self.chat_message ~= old_chat_message and #_COMMANDS_LIST > 0 then
|
elseif self.chat_message ~= old_chat_message and #_commands_list > 0 then
|
||||||
_COMMANDS_LIST = {}
|
_commands_list = {}
|
||||||
_COMMAND_INDEX = 0
|
_command_index = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
if #_COMMANDS_LIST > 0 then
|
if #_commands_list > 0 then
|
||||||
_COMMANDS_LIST_GUI_DRAW(_COMMANDS_LIST, _COMMAND_INDEX)
|
_commands_list_gui_draw(_commands_list, _command_index)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -250,20 +256,21 @@ end)
|
||||||
|
|
||||||
vmf.load_chat_history_settings = function(clean_chat_history_)
|
vmf.load_chat_history_settings = function(clean_chat_history_)
|
||||||
|
|
||||||
_CHAT_HISTORY_ENABLED = vmf:get("chat_history_enable")
|
_chat_history_enabled = vmf:get("chat_history_enable")
|
||||||
_CHAT_HISTORY_SAVE = vmf:get("chat_history_save")
|
_chat_history_save = vmf:get("chat_history_save")
|
||||||
_CHAT_HISTORY_MAX = vmf:get("chat_history_buffer_size")
|
_chat_history_max = vmf:get("chat_history_buffer_size")
|
||||||
_CHAT_HISTORY_REMOVE_DUPS_LAST = vmf:get("chat_history_remove_dups")
|
_chat_history_remove_dups_last = vmf:get("chat_history_remove_dups")
|
||||||
_CHAT_HISTORY_REMOVE_DUPS_ALL = vmf:get("chat_history_remove_dups") and (vmf:get("chat_history_remove_dups_mode") == "all")
|
_chat_history_remove_dups_all = vmf:get("chat_history_remove_dups") and
|
||||||
_CHAT_HISTORY_SAVE_COMMANDS_ONLY = vmf:get("chat_history_commands_only")
|
(vmf:get("chat_history_remove_dups_mode") == "all")
|
||||||
|
_chat_history_save_commands_only = vmf:get("chat_history_commands_only")
|
||||||
|
|
||||||
if _CHAT_HISTORY_ENABLED then
|
if _chat_history_enabled then
|
||||||
vmf:command("clean_chat_history", vmf:localize("clean_chat_history"), clean_chat_history)
|
vmf:command("clean_chat_history", vmf:localize("clean_chat_history"), clean_chat_history)
|
||||||
else
|
else
|
||||||
vmf:command_remove("clean_chat_history")
|
vmf:command_remove("clean_chat_history")
|
||||||
end
|
end
|
||||||
|
|
||||||
if not _CHAT_HISTORY_SAVE then
|
if not _chat_history_save then
|
||||||
vmf:set("chat_history", nil)
|
vmf:set("chat_history", nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -273,15 +280,15 @@ vmf.load_chat_history_settings = function(clean_chat_history_)
|
||||||
end
|
end
|
||||||
|
|
||||||
vmf.save_chat_history = function()
|
vmf.save_chat_history = function()
|
||||||
if _CHAT_HISTORY_SAVE then
|
if _chat_history_save then
|
||||||
vmf:set("chat_history", _CHAT_HISTORY)
|
vmf:set("chat_history", _chat_history)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
vmf.execute_queued_chat_command = function()
|
vmf.execute_queued_chat_command = function()
|
||||||
if _QUEUED_COMMAND then
|
if _queued_command then
|
||||||
vmf.run_command(_QUEUED_COMMAND.name, unpack(_QUEUED_COMMAND.args))
|
vmf.run_command(_queued_command.name, unpack(_queued_command.args))
|
||||||
_QUEUED_COMMAND = nil
|
_queued_command = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -291,8 +298,8 @@ end
|
||||||
|
|
||||||
vmf.load_chat_history_settings()
|
vmf.load_chat_history_settings()
|
||||||
|
|
||||||
if _CHAT_HISTORY_SAVE then
|
if _chat_history_save then
|
||||||
_CHAT_HISTORY = vmf:get("chat_history") or _CHAT_HISTORY
|
_chat_history = vmf:get("chat_history") or _chat_history
|
||||||
end
|
end
|
||||||
|
|
||||||
if Managers.world and Managers.world:has_world("top_ingame_view") then
|
if Managers.world and Managers.world:has_world("top_ingame_view") then
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
local vmf = get_mod("VMF") --@TODO: remove it?
|
local vmf = get_mod("VMF") --@TODO: remove it?
|
||||||
|
|
||||||
local _GUI
|
local _gui
|
||||||
|
|
||||||
if VT1 then
|
if VT1 then
|
||||||
-- @TODO: I don't think I need the 2nd texture
|
-- @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")
|
_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
|
else
|
||||||
_GUI = World.create_screen_gui(Managers.world:world("top_ingame_view"), "material", "materials/fonts/gw_fonts", "immediate")
|
_gui = World.create_screen_gui(Managers.world:world("top_ingame_view"),
|
||||||
|
"material", "materials/fonts/gw_fonts", "immediate")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- DebugScreen.gui = World.create_screen_gui(world, "material", "materials/fonts/gw_fonts", "material", "materials/menu/debug_screen", "immediate")
|
-- 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"
|
||||||
|
@ -33,7 +37,7 @@ local _WIDTH = 550
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
|
|
||||||
local function get_text_width(text, font_material, font_size)
|
local function get_text_width(text, font_material, font_size)
|
||||||
local text_extent_min, text_extent_max = Gui.text_extents(_GUI, text, font_material, font_size)
|
local text_extent_min, text_extent_max = Gui.text_extents(_gui, text, font_material, font_size)
|
||||||
local text_height = text_extent_max[1] - text_extent_min[1]
|
local text_height = text_extent_max[1] - text_extent_min[1]
|
||||||
return text_height
|
return text_height
|
||||||
end
|
end
|
||||||
|
@ -45,7 +49,8 @@ local function word_wrap(text, font_material, font_size, max_width)
|
||||||
local reuse_global_table = true
|
local reuse_global_table = true
|
||||||
local scale = RESOLUTION_LOOKUP.scale
|
local scale = RESOLUTION_LOOKUP.scale
|
||||||
|
|
||||||
return Gui.word_wrap(_GUI, text, font_material, font_size, max_width * scale, whitespace, soft_dividers, return_dividers, reuse_global_table)
|
return Gui.word_wrap(_gui, text, font_material, font_size, max_width * scale, whitespace,
|
||||||
|
soft_dividers, return_dividers, reuse_global_table)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function draw(commands_list, selected_command_index)
|
local function draw(commands_list, selected_command_index)
|
||||||
|
@ -80,8 +85,13 @@ local function draw(commands_list, selected_command_index)
|
||||||
for i, command in ipairs(displayed_commands) do
|
for i, command in ipairs(displayed_commands) do
|
||||||
|
|
||||||
-- draw "/command_name" text
|
-- draw "/command_name" text
|
||||||
local string_position = Vector3((_OFFSET_X + _STRING_X_MARGIN) * scale, (_OFFSET_Y - _STRING_HEIGHT * (i + selected_strings_number - 1) + _STRING_Y_OFFSET) * scale, _OFFSET_Z + 2)
|
local scaled_offet_x = (_OFFSET_X + _STRING_X_MARGIN) * scale
|
||||||
Gui.text(_GUI, command.name, font_material, font_size, font_name, string_position, Color(255, 100, 255, 100))
|
|
||||||
|
local selected_string_height = _STRING_HEIGHT * (i + selected_strings_number - 1) + _STRING_Y_OFFSET
|
||||||
|
local scaled_offset_y = (_OFFSET_Y - selected_string_height) * scale
|
||||||
|
|
||||||
|
local string_position = Vector3(scaled_offet_x, scaled_offset_y, _OFFSET_Z + 2)
|
||||||
|
Gui.text(_gui, command.name, font_material, font_size, font_name, string_position, Color(255, 100, 255, 100))
|
||||||
|
|
||||||
local command_text_strings = word_wrap(command.full_text, font_material, font_size, _WIDTH - _STRING_X_MARGIN * 2)
|
local command_text_strings = word_wrap(command.full_text, font_material, font_size, _WIDTH - _STRING_X_MARGIN * 2)
|
||||||
local multistring = #command_text_strings > 1
|
local multistring = #command_text_strings > 1
|
||||||
|
@ -91,11 +101,14 @@ local function draw(commands_list, selected_command_index)
|
||||||
selected_strings_number = #command_text_strings
|
selected_strings_number = #command_text_strings
|
||||||
else
|
else
|
||||||
local multistring_indicator_width = get_text_width(_MULTISTRING_INDICATOR_TEXT, font_material, font_size)
|
local multistring_indicator_width = get_text_width(_MULTISTRING_INDICATOR_TEXT, font_material, font_size)
|
||||||
command_text_strings = word_wrap(command.full_text, font_material, font_size, _WIDTH - _STRING_X_MARGIN * 2 - (multistring_indicator_width / scale))
|
local command_text_width = _WIDTH - _STRING_X_MARGIN * 2 - (multistring_indicator_width / scale)
|
||||||
|
command_text_strings = word_wrap(command.full_text, font_material, font_size, command_text_width)
|
||||||
|
|
||||||
-- draw that [...] thing
|
-- draw that [...] thing
|
||||||
local multistring_indicator_position = Vector3((_OFFSET_X + _WIDTH) * scale - multistring_indicator_width, string_position.y, string_position.z)
|
local multistring_offset_x = (_OFFSET_X + _WIDTH) * scale - multistring_indicator_width
|
||||||
Gui.text(_GUI, _MULTISTRING_INDICATOR_TEXT, font_material, font_size, font_name, multistring_indicator_position, Color(255, 100, 100, 100))
|
local multistring_indicator_position = Vector3(multistring_offset_x, string_position.y, string_position.z)
|
||||||
|
Gui.text(_gui, _MULTISTRING_INDICATOR_TEXT, font_material, font_size, font_name,
|
||||||
|
multistring_indicator_position, Color(255, 100, 100, 100))
|
||||||
end
|
end
|
||||||
first_description_string = string.sub(command_text_strings[1], #command.name + 2)
|
first_description_string = string.sub(command_text_strings[1], #command.name + 2)
|
||||||
else
|
else
|
||||||
|
@ -104,14 +117,18 @@ local function draw(commands_list, selected_command_index)
|
||||||
|
|
||||||
-- draw command description text (1st string)
|
-- draw command description text (1st string)
|
||||||
local first_description_string_width = get_text_width(command.name, font_material, font_size)
|
local first_description_string_width = get_text_width(command.name, font_material, font_size)
|
||||||
local first_description_string_position = Vector3(string_position.x + first_description_string_width, string_position.y, string_position.z)
|
|
||||||
Gui.text(_GUI, first_description_string, font_material, font_size, font_name, first_description_string_position, Color(255, 255, 255, 255))
|
local first_description_pos_x = string_position.x + first_description_string_width
|
||||||
|
local first_description_string_position = Vector3(first_description_pos_x, string_position.y, string_position.z)
|
||||||
|
Gui.text(_gui, first_description_string, font_material, font_size, font_name,
|
||||||
|
first_description_string_position, Color(255, 255, 255, 255))
|
||||||
|
|
||||||
-- draw command description text (2+ strings)
|
-- draw command description text (2+ strings)
|
||||||
if command.selected and multistring then
|
if command.selected and multistring then
|
||||||
for j = 2, selected_strings_number do
|
for j = 2, selected_strings_number do
|
||||||
string_position.y = string_position.y - _STRING_HEIGHT * scale
|
string_position.y = string_position.y - _STRING_HEIGHT * scale
|
||||||
Gui.text(_GUI, command_text_strings[j], font_material, font_size, font_name, string_position, Color(255, 255, 255, 255))
|
Gui.text(_gui, command_text_strings[j], font_material, font_size, font_name,
|
||||||
|
string_position, Color(255, 255, 255, 255))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -123,7 +140,7 @@ local function draw(commands_list, selected_command_index)
|
||||||
local bg_position = Vector3(_OFFSET_X * scale, bg_pos_y * scale, _OFFSET_Z)
|
local bg_position = Vector3(_OFFSET_X * scale, bg_pos_y * scale, _OFFSET_Z)
|
||||||
local bg_size = Vector2(_WIDTH * scale, bg_height * scale)
|
local bg_size = Vector2(_WIDTH * scale, bg_height * scale)
|
||||||
local bg_color = Color(200, 10, 10, 10)
|
local bg_color = Color(200, 10, 10, 10)
|
||||||
Gui.rect(_GUI, bg_position, bg_size, bg_color)
|
Gui.rect(_gui, bg_position, bg_size, bg_color)
|
||||||
|
|
||||||
-- selection rectangle
|
-- selection rectangle
|
||||||
if selected_command_new_index > 0 then
|
if selected_command_new_index > 0 then
|
||||||
|
@ -133,7 +150,7 @@ local function draw(commands_list, selected_command_index)
|
||||||
local selection_position = Vector3(_OFFSET_X * scale, selection_pos_y * scale, _OFFSET_Z + 1)
|
local selection_position = Vector3(_OFFSET_X * scale, selection_pos_y * scale, _OFFSET_Z + 1)
|
||||||
local selection_size = Vector2(_WIDTH * scale, selection_height * scale)
|
local selection_size = Vector2(_WIDTH * scale, selection_height * scale)
|
||||||
local selection_color = Color(100, 120, 120, 120)
|
local selection_color = Color(100, 120, 120, 120)
|
||||||
Gui.rect(_GUI, selection_position, selection_size, selection_color)
|
Gui.rect(_gui, selection_position, selection_size, selection_color)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- "selected command number / total commands number" indicator
|
-- "selected command number / total commands number" indicator
|
||||||
|
@ -143,8 +160,11 @@ local function draw(commands_list, selected_command_index)
|
||||||
total_number_indicator = selected_command_index .. "/" .. total_number_indicator
|
total_number_indicator = selected_command_index .. "/" .. total_number_indicator
|
||||||
end
|
end
|
||||||
local total_number_indicator_width = get_text_width(total_number_indicator, font_material, font_size)
|
local total_number_indicator_width = get_text_width(total_number_indicator, font_material, font_size)
|
||||||
local total_number_indicator_position = Vector3((_WIDTH) * scale - total_number_indicator_width, (_OFFSET_Y + _STRING_Y_OFFSET) * scale, _OFFSET_Z + 2)
|
local total_number_indicator_x = (_WIDTH) * scale - total_number_indicator_width
|
||||||
Gui.text(_GUI, total_number_indicator, font_material, font_size, font_name, total_number_indicator_position, Color(255, 100, 100, 100))
|
local total_number_indicator_y = (_OFFSET_Y + _STRING_Y_OFFSET) * scale
|
||||||
|
local total_number_indicator_position = Vector3(total_number_indicator_x, total_number_indicator_y, _OFFSET_Z + 2)
|
||||||
|
Gui.text(_gui, total_number_indicator, font_material, font_size, font_name,
|
||||||
|
total_number_indicator_position, Color(255, 100, 100, 100))
|
||||||
end
|
end
|
||||||
--end)
|
--end)
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,6 +25,10 @@ vmf.inject_materials(vmf, "ingame_ui", "materials/vmf/vmf_atlas")
|
||||||
-- ##### MENU WIDGETS DEFINITIONS #####################################################################################
|
-- ##### MENU WIDGETS DEFINITIONS #####################################################################################
|
||||||
-- ####################################################################################################################
|
-- ####################################################################################################################
|
||||||
|
|
||||||
|
-- Bandaid Fix for fancy ass ascii causing line checking errors.
|
||||||
|
-- luacheck: no max_line_length
|
||||||
|
-- Bandaid Fix for this file using lots of duplicated code and shadowed variables that could be refactored
|
||||||
|
-- luacheck: ignore 4
|
||||||
|
|
||||||
-- ███████╗ ██████╗███████╗███╗ ██╗███████╗ ██████╗ ██████╗ █████╗ ██████╗ ██╗ ██╗███████╗
|
-- ███████╗ ██████╗███████╗███╗ ██╗███████╗ ██████╗ ██████╗ █████╗ ██████╗ ██╗ ██╗███████╗
|
||||||
-- ██╔════╝██╔════╝██╔════╝████╗ ██║██╔════╝██╔════╝ ██╔══██╗██╔══██╗██╔══██╗██║ ██║██╔════╝
|
-- ██╔════╝██╔════╝██╔════╝████╗ ██║██╔════╝██╔════╝ ██╔══██╗██╔══██╗██╔══██╗██║ ██║██╔════╝
|
||||||
|
@ -186,7 +190,7 @@ local function create_scrollbar(height, scenegraph_id)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pass_type = "local_offset",
|
pass_type = "local_offset",
|
||||||
offset_function = function (ui_scenegraph, ui_style, ui_content, input_service)
|
offset_function = function (ui_scenegraph_, ui_style, ui_content, input_service_)
|
||||||
local scroll_bar_info = ui_content.scroll_bar_info
|
local scroll_bar_info = ui_content.scroll_bar_info
|
||||||
local scroll_bar_box = ui_style.scroll_bar_box
|
local scroll_bar_box = ui_style.scroll_bar_box
|
||||||
local scroll_size_y = scroll_bar_box.scroll_size_y
|
local scroll_size_y = scroll_bar_box.scroll_size_y
|
||||||
|
@ -215,14 +219,14 @@ local function create_scrollbar(height, scenegraph_id)
|
||||||
local scroll_size_y = scroll_bar_box.scroll_size_y
|
local scroll_size_y = scroll_bar_box.scroll_size_y
|
||||||
local start_y = scroll_bar_box.start_offset[2]
|
local start_y = scroll_bar_box.start_offset[2]
|
||||||
local end_y = (start_y + scroll_size_y) - size_y
|
local end_y = (start_y + scroll_size_y) - size_y
|
||||||
local step = size_y / (start_y + end_y)
|
local step_ = size_y / (start_y + end_y)
|
||||||
scroll_bar_info.value = math.max(scroll_bar_info.value - button_scroll_step, 0)
|
scroll_bar_info.value = math.max(scroll_bar_info.value - button_scroll_step, 0)
|
||||||
elseif button_down_hotspot.on_release then
|
elseif button_down_hotspot.on_release then
|
||||||
local size_y = scroll_bar_box.size[2]
|
local size_y = scroll_bar_box.size[2]
|
||||||
local scroll_size_y = scroll_bar_box.scroll_size_y
|
local scroll_size_y = scroll_bar_box.scroll_size_y
|
||||||
local start_y = scroll_bar_box.start_offset[2]
|
local start_y = scroll_bar_box.start_offset[2]
|
||||||
local end_y = (start_y + scroll_size_y) - size_y
|
local end_y = (start_y + scroll_size_y) - size_y
|
||||||
local step = size_y / (start_y + end_y)
|
local step_ = size_y / (start_y + end_y)
|
||||||
scroll_bar_info.value = math.min(scroll_bar_info.value + button_scroll_step, 1)
|
scroll_bar_info.value = math.min(scroll_bar_info.value + button_scroll_step, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -272,7 +276,7 @@ local function create_scrollbar(height, scenegraph_id)
|
||||||
|
|
||||||
return
|
return
|
||||||
end,
|
end,
|
||||||
release_function = function (ui_scenegraph, ui_style, ui_content, input_service)
|
release_function = function (ui_scenegraph_, ui_style_, ui_content, input_service_)
|
||||||
ui_content.click_pos_y = nil
|
ui_content.click_pos_y = nil
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -281,7 +285,7 @@ local function create_scrollbar(height, scenegraph_id)
|
||||||
{
|
{
|
||||||
pass_type = "local_offset",
|
pass_type = "local_offset",
|
||||||
content_id = "scroll_bar_info",
|
content_id = "scroll_bar_info",
|
||||||
offset_function = function (ui_scenegraph, ui_style, ui_content, input_service)
|
offset_function = function (ui_scenegraph_, ui_style, ui_content, input_service_)
|
||||||
local box_style = ui_style.scroll_bar_box
|
local box_style = ui_style.scroll_bar_box
|
||||||
local box_size_y = box_style.size[2]
|
local box_size_y = box_style.size[2]
|
||||||
local start_y = box_style.start_offset[2]
|
local start_y = box_style.start_offset[2]
|
||||||
|
@ -2848,7 +2852,7 @@ VMFOptionsView.initialize_settings_list_widgets = function (self)
|
||||||
local list_size_y = 0
|
local list_size_y = 0
|
||||||
|
|
||||||
local all_widgets = {}
|
local all_widgets = {}
|
||||||
local mod_widgets = nil
|
local mod_widgets
|
||||||
|
|
||||||
for _, mod_settings_list_definitions in ipairs(self.definitions.settings_list_widgets) do
|
for _, mod_settings_list_definitions in ipairs(self.definitions.settings_list_widgets) do
|
||||||
|
|
||||||
|
@ -3151,7 +3155,7 @@ VMFOptionsView.callback_move_favorite = function (self, widget_content, is_moved
|
||||||
|
|
||||||
local mod_name = widget_content.mod_name
|
local mod_name = widget_content.mod_name
|
||||||
|
|
||||||
local new_index = nil
|
local new_index
|
||||||
|
|
||||||
local favorite_mods_list = vmf:get("options_menu_favorite_mods")
|
local favorite_mods_list = vmf:get("options_menu_favorite_mods")
|
||||||
|
|
||||||
|
@ -3774,9 +3778,9 @@ end
|
||||||
|
|
||||||
VMFOptionsView.update_picked_option_for_settings_list_widgets = function (self)
|
VMFOptionsView.update_picked_option_for_settings_list_widgets = function (self)
|
||||||
|
|
||||||
local widget_content = nil
|
local widget_content
|
||||||
local widget_type = nil
|
local widget_type
|
||||||
local loaded_setting_value = nil
|
local loaded_setting_value
|
||||||
|
|
||||||
for _, mod_widgets in ipairs(self.settings_list_widgets) do
|
for _, mod_widgets in ipairs(self.settings_list_widgets) do
|
||||||
for _, widget in ipairs(mod_widgets) do
|
for _, widget in ipairs(mod_widgets) do
|
||||||
|
@ -4298,8 +4302,8 @@ vmf.create_options = function (mod, widgets_definition)
|
||||||
|
|
||||||
local mod_settings_list_widgets_definitions = {}
|
local mod_settings_list_widgets_definitions = {}
|
||||||
|
|
||||||
local new_widget_definition = nil
|
local new_widget_definition
|
||||||
local new_widget_index = nil
|
local new_widget_index
|
||||||
|
|
||||||
local options_menu_favorite_mods = vmf:get("options_menu_favorite_mods")
|
local options_menu_favorite_mods = vmf:get("options_menu_favorite_mods")
|
||||||
local options_menu_collapsed_widgets = vmf:get("options_menu_collapsed_widgets")
|
local options_menu_collapsed_widgets = vmf:get("options_menu_collapsed_widgets")
|
||||||
|
|
|
@ -257,7 +257,9 @@ vmf.on_setting_changed = function (setting_name)
|
||||||
or setting_name == "chat_history_remove_dups_mode"
|
or setting_name == "chat_history_remove_dups_mode"
|
||||||
or setting_name == "chat_history_commands_only" then
|
or setting_name == "chat_history_commands_only" then
|
||||||
|
|
||||||
vmf.load_chat_history_settings(setting_name == "chat_history_enable" or setting_name == "chat_history_buffer_size" or setting_name == "chat_history_commands_only")
|
vmf.load_chat_history_settings(setting_name == "chat_history_enable" or
|
||||||
|
setting_name == "chat_history_buffer_size" or
|
||||||
|
setting_name == "chat_history_commands_only")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue