Mutators module reworking
1) Fixed delayed chat messages 2) mod:is_togglable() 3) Keybind action "toggle_mod" -> "toggle_mod_state" 4) mod:persistent_table("name") 5) Removed "enable" and "disable" methods 6) Now all mod data is stored in mod._data 7) New way of initialization mod and initialization data 8) Mutators will be run after reload (also note init_state) 9) Removed table.lua 10) Lots of small changes and fixes
This commit is contained in:
parent
92005e0340
commit
4853ebccf4
26 changed files with 808 additions and 717 deletions
Binary file not shown.
|
@ -1,78 +0,0 @@
|
|||
return {
|
||||
easy = {
|
||||
en = "Easy"
|
||||
},
|
||||
normal = {
|
||||
en = "Normal"
|
||||
},
|
||||
hard = {
|
||||
en = "Hard"
|
||||
},
|
||||
harder = {
|
||||
en = "Nightmare"
|
||||
},
|
||||
hardest = {
|
||||
en = "Cataclysm"
|
||||
},
|
||||
survival_hard = {
|
||||
en = "Veteran"
|
||||
},
|
||||
survival_harder = {
|
||||
en = "Champion"
|
||||
},
|
||||
survival_hardest = {
|
||||
en = "Heroic"
|
||||
},
|
||||
|
||||
broadcast_enabled_mutators = {
|
||||
en = "ENABLED MUTATORS"
|
||||
},
|
||||
broadcast_all_disabled = {
|
||||
en = "ALL MUTATORS DISABLED"
|
||||
},
|
||||
broadcast_disabled_mutators = {
|
||||
en = "MUTATORS DISABLED"
|
||||
},
|
||||
local_disabled_mutators = {
|
||||
en = "Mutators disabled"
|
||||
},
|
||||
whisper_enabled_mutators = {
|
||||
en = "[Automated message] This lobby has the following mutators active"
|
||||
},
|
||||
|
||||
disabled_reason_not_server = {
|
||||
en = "because you're no longer the host"
|
||||
},
|
||||
disabled_reason_difficulty_change = {
|
||||
en = "DUE TO CHANGE IN DIFFICULTY"
|
||||
},
|
||||
|
||||
mutators_title = {
|
||||
en = "Mutators"
|
||||
},
|
||||
mutators_banner_tooltip = {
|
||||
en = "Enable and disable mutators"
|
||||
},
|
||||
no_mutators = {
|
||||
en = "No mutators installed"
|
||||
},
|
||||
no_mutators_tooltip = {
|
||||
en = "Subscribe to mods and mutators on the workshop"
|
||||
},
|
||||
|
||||
tooltip_supported_difficulty = {
|
||||
en = "Supported difficulty levels"
|
||||
},
|
||||
tooltip_incompatible_with_all = {
|
||||
en = "Incompatible with all other mutators"
|
||||
},
|
||||
tooltip_incompatible_with = {
|
||||
en = "Incompatible with"
|
||||
},
|
||||
tooltip_compatible_with_all = {
|
||||
en = "Compatible with all other mutators"
|
||||
},
|
||||
tooltip_will_be_disabled = {
|
||||
en = "Will be disabled when Play is pressed"
|
||||
}
|
||||
}
|
|
@ -187,4 +187,85 @@ return {
|
|||
en = "Developer console closed.",
|
||||
ru = "Консоль разработчика закрыта.",
|
||||
},
|
||||
|
||||
|
||||
-- MUTATORS
|
||||
|
||||
|
||||
easy = {
|
||||
en = "Easy"
|
||||
},
|
||||
normal = {
|
||||
en = "Normal"
|
||||
},
|
||||
hard = {
|
||||
en = "Hard"
|
||||
},
|
||||
harder = {
|
||||
en = "Nightmare"
|
||||
},
|
||||
hardest = {
|
||||
en = "Cataclysm"
|
||||
},
|
||||
survival_hard = {
|
||||
en = "Veteran"
|
||||
},
|
||||
survival_harder = {
|
||||
en = "Champion"
|
||||
},
|
||||
survival_hardest = {
|
||||
en = "Heroic"
|
||||
},
|
||||
|
||||
broadcast_enabled_mutators = {
|
||||
en = "ENABLED MUTATORS"
|
||||
},
|
||||
broadcast_all_disabled = {
|
||||
en = "ALL MUTATORS DISABLED"
|
||||
},
|
||||
broadcast_disabled_mutators = {
|
||||
en = "MUTATORS DISABLED"
|
||||
},
|
||||
local_disabled_mutators = {
|
||||
en = "Mutators disabled"
|
||||
},
|
||||
whisper_enabled_mutators = {
|
||||
en = "[Automated message] This lobby has the following mutators active"
|
||||
},
|
||||
|
||||
disabled_reason_not_server = {
|
||||
en = "because you're no longer the host"
|
||||
},
|
||||
disabled_reason_difficulty_change = {
|
||||
en = "DUE TO CHANGE IN DIFFICULTY"
|
||||
},
|
||||
|
||||
mutators_title = {
|
||||
en = "Mutators"
|
||||
},
|
||||
mutators_banner_tooltip = {
|
||||
en = "Enable and disable mutators"
|
||||
},
|
||||
no_mutators = {
|
||||
en = "No mutators installed"
|
||||
},
|
||||
no_mutators_tooltip = {
|
||||
en = "Subscribe to mods and mutators on the workshop"
|
||||
},
|
||||
|
||||
tooltip_supported_difficulty = {
|
||||
en = "Supported difficulty levels"
|
||||
},
|
||||
tooltip_incompatible_with_all = {
|
||||
en = "Incompatible with all other mutators"
|
||||
},
|
||||
tooltip_incompatible_with = {
|
||||
en = "Incompatible with"
|
||||
},
|
||||
tooltip_compatible_with_all = {
|
||||
en = "Compatible with all other mutators"
|
||||
},
|
||||
tooltip_will_be_disabled = {
|
||||
en = "Will be disabled when Play is pressed"
|
||||
}
|
||||
}
|
|
@ -1,33 +1,38 @@
|
|||
-- Image Source: ../test
|
||||
-- Image Source:
|
||||
return {
|
||||
header_fav_arrow = {
|
||||
size = { 48, 48, },
|
||||
uv00 = { 0.187500, 0.687500, },
|
||||
uv11 = { 0.375000, 0.875000, },
|
||||
uv00 = { 0.181641, 0.880859, },
|
||||
uv11 = { 0.228516, 0.974609, },
|
||||
},
|
||||
header_fav_icon = {
|
||||
size = { 48, 48, },
|
||||
uv00 = { 0.187500, 0.500000, },
|
||||
uv11 = { 0.375000, 0.687500, },
|
||||
},
|
||||
search_bar_icon = {
|
||||
size = { 48, 48, },
|
||||
uv00 = { 0.000000, 0.687500, },
|
||||
uv11 = { 0.187500, 0.875000, },
|
||||
uv00 = { 0.130859, 0.880859, },
|
||||
uv11 = { 0.177734, 0.974609, },
|
||||
},
|
||||
header_fav_icon_lit = {
|
||||
size = { 48, 48, },
|
||||
uv00 = { 0.000000, 0.500000, },
|
||||
uv11 = { 0.187500, 0.687500, },
|
||||
uv00 = { 0.052734, 0.880859, },
|
||||
uv11 = { 0.099609, 0.974609, },
|
||||
},
|
||||
mutator_button = {
|
||||
size = { 128, 128, },
|
||||
uv00 = { 0.500000, 0.000000, },
|
||||
uv11 = { 1.000000, 0.500000, },
|
||||
search_bar_icon = {
|
||||
size = { 48, 48, },
|
||||
uv00 = { 0.001953, 0.880859, },
|
||||
uv11 = { 0.048828, 0.974609, },
|
||||
},
|
||||
mutator_button_hover = {
|
||||
map_view_party_button = {
|
||||
size = { 128, 128, },
|
||||
uv00 = { 0.000000, 0.000000, },
|
||||
uv11 = { 0.500000, 0.500000, },
|
||||
uv00 = { 0.130859, 0.623047, },
|
||||
uv11 = { 0.255859, 0.873047, },
|
||||
},
|
||||
map_view_party_button_lit = {
|
||||
size = { 128, 128, },
|
||||
uv00 = { 0.001953, 0.623047, },
|
||||
uv11 = { 0.126953, 0.873047, },
|
||||
},
|
||||
map_view_mutators_area = {
|
||||
size = { 547, 313, },
|
||||
uv00 = { 0.001953, 0.003906, },
|
||||
uv11 = { 0.536133, 0.615234, },
|
||||
},
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ lua = [
|
|||
"localization/*"
|
||||
|
||||
"scripts/mods/vmf/*"
|
||||
"scripts/mods/vmf/functions/*"
|
||||
"scripts/mods/vmf/modules/*"
|
||||
"scripts/mods/vmf/modules/core/*"
|
||||
"scripts/mods/vmf/modules/debug/*"
|
||||
|
@ -22,6 +21,7 @@ lua = [
|
|||
"scripts/mods/vmf/modules/ui/options/*"
|
||||
"scripts/mods/vmf/modules/ui/chat/*"
|
||||
"scripts/mods/vmf/modules/ui/mutators/*"
|
||||
"scripts/mods/vmf/modules/ui/mutators/test/*"
|
||||
|
||||
"materials/vmf/vmf_atlas"
|
||||
]
|
|
@ -1,176 +0,0 @@
|
|||
table.pack = function(...)
|
||||
return { n = select("#", ...); ... }
|
||||
end
|
||||
|
||||
table.combine = function(a, b)
|
||||
local r = {unpack(a)}
|
||||
|
||||
for i = 1, #b do
|
||||
r[#a + i] = b[i]
|
||||
end
|
||||
|
||||
return r;
|
||||
end
|
||||
|
||||
-- Check item exist in table
|
||||
table.has_item = function(tbl, item)
|
||||
for _, value in ipairs(tbl) do
|
||||
if value == item then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
table.has_item2 = function(tbl, item)
|
||||
for _, value in pairs(tbl) do
|
||||
if value == item then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
table.index_of = function(t, o)
|
||||
if type(t) ~= "table" then
|
||||
return nil
|
||||
end
|
||||
for i,v in ipairs(t) do
|
||||
if o == v then
|
||||
return i
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
table.adress = function(tbl)
|
||||
local str = tostring(tbl)
|
||||
|
||||
return string.sub(str, 8, str:len())
|
||||
end
|
||||
|
||||
-- Serialization and deserialization
|
||||
local serialization = function(key, value)
|
||||
local str = ""
|
||||
|
||||
if type(value) == "string" then
|
||||
str = str .. tostring(key) .. "=\"" .. value .. "\","
|
||||
elseif type(value) == "number" then
|
||||
str = str .. tostring(key) .. "=" .. tostring(value) .. ","
|
||||
elseif type(value) == "boolean" then
|
||||
str = str .. tostring(key) .. "="
|
||||
|
||||
if value then
|
||||
str = str .. "true"
|
||||
else
|
||||
str = str .. "false"
|
||||
end
|
||||
|
||||
str = str .. ","
|
||||
|
||||
elseif type(value) == "table" then
|
||||
str = str .. tostring(key) .. "=" .. table.serialization(value) .. ","
|
||||
end
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
local deserialization = function(str)
|
||||
for i = 1, string.len(str) do
|
||||
local value = string.sub(str, i, i)
|
||||
|
||||
if value == "=" then
|
||||
local key = string.sub(str, 1, i - 1)
|
||||
local value = string.sub(str, i + 1, string.len(str))
|
||||
|
||||
-- Check key
|
||||
if string.sub(key, 1, 1) == "[" then
|
||||
key = string.sub(key, 3, string.len(key) - 2)
|
||||
else
|
||||
key = tonumber(key)
|
||||
end
|
||||
|
||||
-- Check value
|
||||
if value == "true" then
|
||||
value = true
|
||||
elseif value == "false" then
|
||||
value = false
|
||||
elseif string.sub(value, 1, 1) == "\"" then
|
||||
value = string.sub(value, 2, string.len(value) - 1)
|
||||
elseif string.sub(value, 1, 1) == "{" then
|
||||
value = table.deserialization(value)
|
||||
else
|
||||
value = tonumber(value)
|
||||
end
|
||||
|
||||
return key, value
|
||||
end
|
||||
end
|
||||
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
table.serialization = function(tbl)
|
||||
local str = "{"
|
||||
|
||||
for key, value in ipairs(tbl) do
|
||||
str = str .. serialization(key, value)
|
||||
end
|
||||
for key, value in pairs(tbl) do
|
||||
if type(key) ~= "number" then
|
||||
str = str .. serialization("[\"" .. key .. "\"]", value)
|
||||
end
|
||||
end
|
||||
|
||||
str = str .. "}"
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
table.deserialization = function(str)
|
||||
local tbl = {}
|
||||
|
||||
-- Collected data
|
||||
local data = ""
|
||||
|
||||
-- Checks
|
||||
local c_list = 0
|
||||
local c_str = false
|
||||
|
||||
for i = 2, string.len(str) do
|
||||
local before_value = string.sub(str, i - 1, i - 1)
|
||||
local value = string.sub(str, i, i)
|
||||
|
||||
-- If not inside a list or string
|
||||
if value == "," and c_list == 0 then
|
||||
-- Save propety
|
||||
local key, val = deserialization(data)
|
||||
|
||||
if key then
|
||||
tbl[key] = val
|
||||
end
|
||||
|
||||
-- Search for new propety
|
||||
data = ""
|
||||
else
|
||||
-- Detect string type
|
||||
if value == "\"" and not before_value ~= "\\" then
|
||||
c_str = not c_str
|
||||
end
|
||||
|
||||
-- Detect list type
|
||||
if not c_str then
|
||||
if value == "{" then
|
||||
c_list = c_list + 1
|
||||
elseif value == "}" then
|
||||
c_list = c_list - 1
|
||||
end
|
||||
end
|
||||
|
||||
-- save value
|
||||
data = data .. value
|
||||
end
|
||||
end
|
||||
|
||||
return tbl
|
||||
end
|
|
@ -175,7 +175,7 @@ end
|
|||
-- ####################################################################################################################
|
||||
-- ##### VMF internal functions and variables #########################################################################
|
||||
-- ####################################################################################################################
|
||||
-- @TODO: maybe it doesn't belong in here
|
||||
-- @TODO: rename it (get rid of "wrong")
|
||||
vmf.check_wrong_argument_type = function(mod, vmf_function_name, argument_name, argument, ...)
|
||||
|
||||
local allowed_types = {...}
|
||||
|
|
|
@ -1,34 +1,20 @@
|
|||
-- @TODO: do I need to hook it at all?
|
||||
|
||||
local vmf = get_mod("VMF")
|
||||
|
||||
-- ####################################################################################################################
|
||||
-- ##### Hooks Functions ##############################################################################################
|
||||
-- ##### Hooks ########################################################################################################
|
||||
-- ####################################################################################################################
|
||||
|
||||
-- HOOK: [ChatManager.register_channel]
|
||||
local hook_send_unsent_messages = function (func, self, channel_id, members_func)
|
||||
vmf:hook("ChatManager.register_channel", function (func, self, channel_id, members_func)
|
||||
|
||||
func(self, channel_id, members_func)
|
||||
|
||||
if channel_id == 1 then
|
||||
if (channel_id == 1) and (#vmf.unsent_chat_messages > 0) then
|
||||
for _, message in ipairs(vmf.unsent_chat_messages) do
|
||||
self:add_local_system_message(1, message, true)
|
||||
end
|
||||
|
||||
for i, _ in ipairs(vmf.unsent_chat_messages) do
|
||||
vmf.unsent_chat_messages[i] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- ####################################################################################################################
|
||||
-- ##### VMF internal functions and variables #########################################################################
|
||||
-- ####################################################################################################################
|
||||
|
||||
-- at the moment of loading VMF Chat Manager is not initialized yet,
|
||||
-- so it should be hooked with some delay
|
||||
vmf.hook_chat_manager = function()
|
||||
|
||||
if not vmf.is_chat_manager_hooked then
|
||||
vmf.is_chat_manager_hooked = true
|
||||
|
||||
vmf:hook("ChatManager.register_channel", hook_send_unsent_messages)
|
||||
end
|
||||
end
|
||||
end)
|
43
vmf/scripts/mods/vmf/modules/core/initialization.lua
Normal file
43
vmf/scripts/mods/vmf/modules/core/initialization.lua
Normal file
|
@ -0,0 +1,43 @@
|
|||
local vmf = get_mod("VMF")
|
||||
|
||||
--@TODO: array where I track if data was already initialized (initialize and initialize_data can be called only once)
|
||||
|
||||
-- ####################################################################################################################
|
||||
-- ##### VMFMod #######################################################################################################
|
||||
-- ####################################################################################################################
|
||||
|
||||
VMFMod.initialize = function (self, script_path)
|
||||
|
||||
local success, error_details = pcall(dofile, script_path)
|
||||
if not success then
|
||||
if error_details.error then
|
||||
self:error("(initialize): %s", error_details.error)
|
||||
print("\nTRACEBACK:\n\n" .. error_details.traceback .. "\nLOCALS:\n\n" .. error_details.locals)
|
||||
else
|
||||
self:error("(initialize): %s", tostring(error_details))
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if self:is_togglable() then
|
||||
vmf.initialize_mod_state(self)
|
||||
end
|
||||
end
|
||||
|
||||
VMFMod.initialize_data = function (self, mod_data)
|
||||
|
||||
if mod_data.name then
|
||||
self._data.readable_name = mod_data.name
|
||||
end
|
||||
self._data.description = mod_data.description
|
||||
self._data.is_togglable = mod_data.is_togglable or mod_data.is_mutator
|
||||
self._data.is_mutator = mod_data.is_mutator
|
||||
|
||||
if mod_data.is_mutator then
|
||||
vmf.register_mod_as_mutator(self, mod_data.mutator_setting)
|
||||
end
|
||||
|
||||
if mod_data.options_widgets or (mod_data.is_togglable and not mod_data.is_mutator) then
|
||||
vmf.create_options(self, mod_data.options_widgets)
|
||||
end
|
||||
end
|
|
@ -14,6 +14,8 @@ local _RAW_KEYBINDS = {}
|
|||
-- ["primary_key"] = {{"mod_name", "action_name", ctrl_used(bool), alt_used(bool), shift_used(bool)}, {}, {}, ...}
|
||||
local _OPTIMIZED_KEYBINDS = {}
|
||||
|
||||
local _ACTIVATED_PRESSED_KEY
|
||||
|
||||
-- ####################################################################################################################
|
||||
-- ##### Local functions ##############################################################################################
|
||||
-- ####################################################################################################################
|
||||
|
@ -101,11 +103,11 @@ vmf.check_pressed_keybinds = function()
|
|||
if input_service then
|
||||
|
||||
-- don't check for the pressed keybindings until player will release already pressed keybind
|
||||
if vmf.activated_pressed_key then
|
||||
if input_service:get(vmf.activated_pressed_key) then
|
||||
if _ACTIVATED_PRESSED_KEY then
|
||||
if input_service:get(_ACTIVATED_PRESSED_KEY) then
|
||||
return
|
||||
else
|
||||
vmf.activated_pressed_key = nil
|
||||
_ACTIVATED_PRESSED_KEY = nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -120,12 +122,12 @@ vmf.check_pressed_keybinds = function()
|
|||
|
||||
local mod = get_mod(binding_info[1])
|
||||
|
||||
if binding_info[2] == "toggle_mod" then
|
||||
if binding_info[2] == "toggle_mod_state" and not mod:is_mutator() then
|
||||
|
||||
vmf.mod_state_changed(mod:get_name(), not mod:is_enabled())
|
||||
|
||||
key_has_active_keybind = true
|
||||
vmf.activated_pressed_key = key
|
||||
_ACTIVATED_PRESSED_KEY = key
|
||||
|
||||
elseif mod:is_enabled() then
|
||||
|
||||
|
@ -140,7 +142,7 @@ vmf.check_pressed_keybinds = function()
|
|||
end
|
||||
|
||||
key_has_active_keybind = true
|
||||
vmf.activated_pressed_key = key
|
||||
_ACTIVATED_PRESSED_KEY = key
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -82,11 +82,11 @@ VMFMod.localize = function (self, text_id, ...)
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
return "<" .. tostring(text_id) .. ">"
|
||||
else
|
||||
self:error("(localize): localization file was not loaded for this mod")
|
||||
end
|
||||
|
||||
return "<" .. tostring(text_id) .. ">"
|
||||
end
|
||||
|
||||
-- ####################################################################################################################
|
||||
|
|
32
vmf/scripts/mods/vmf/modules/core/persistent_tables.lua
Normal file
32
vmf/scripts/mods/vmf/modules/core/persistent_tables.lua
Normal file
|
@ -0,0 +1,32 @@
|
|||
local vmf = get_mod("VMF")
|
||||
|
||||
Managers.vmf.persistent_tables = Managers.vmf.persistent_tables or {}
|
||||
|
||||
local _PERSISTENT_TABLES = Managers.vmf.persistent_tables
|
||||
|
||||
-- ####################################################################################################################
|
||||
-- ##### VMFMod #######################################################################################################
|
||||
-- ####################################################################################################################
|
||||
|
||||
VMFMod.persistent_table = function (self, table_name)
|
||||
|
||||
if vmf.check_wrong_argument_type(self, "persistent_table", "table_name", table_name, "string") then
|
||||
return
|
||||
end
|
||||
|
||||
local mod_name = self:get_name()
|
||||
|
||||
_PERSISTENT_TABLES[mod_name] = _PERSISTENT_TABLES[mod_name] or {}
|
||||
|
||||
local mod_tables = _PERSISTENT_TABLES[mod_name]
|
||||
|
||||
mod_tables[table_name] = mod_tables[table_name] or {}
|
||||
|
||||
return mod_tables[table_name]
|
||||
end
|
||||
|
||||
-- ####################################################################################################################
|
||||
-- ##### Script #######################################################################################################
|
||||
-- ####################################################################################################################
|
||||
|
||||
vmf.persistent_data = vmf:persistent_table("persistent_data")
|
|
@ -1,77 +1,60 @@
|
|||
local vmf = get_mod("VMF")
|
||||
|
||||
local _DISABLED_MODS_LIST = vmf:get("disabled_mods_list") or {}
|
||||
|
||||
-- ####################################################################################################################
|
||||
-- ##### Local functions ##############################################################################################
|
||||
-- ####################################################################################################################
|
||||
|
||||
local function change_mod_state(mod, enable, initial_call)
|
||||
|
||||
if enable then
|
||||
|
||||
_DISABLED_MODS_LIST[mod:get_name()] = nil
|
||||
|
||||
vmf.mod_enabled_event(mod, initial_call)
|
||||
else
|
||||
|
||||
_DISABLED_MODS_LIST[mod:get_name()] = true
|
||||
|
||||
vmf.mod_disabled_event(mod, initial_call)
|
||||
end
|
||||
|
||||
if initial_call then
|
||||
return
|
||||
end
|
||||
|
||||
vmf:set("disabled_mods_list", _DISABLED_MODS_LIST)
|
||||
end
|
||||
|
||||
-- ####################################################################################################################
|
||||
-- ##### VMFMod #######################################################################################################
|
||||
-- ####################################################################################################################
|
||||
|
||||
VMFMod.is_enabled = function (self)
|
||||
|
||||
return not _DISABLED_MODS_LIST[self:get_name()]
|
||||
end
|
||||
|
||||
VMFMod.disable = function (self)
|
||||
|
||||
if not _DISABLED_MODS_LIST[self:get_name()] then
|
||||
|
||||
change_mod_state(self, false, false)
|
||||
end
|
||||
end
|
||||
|
||||
VMFMod.enable = function (self)
|
||||
|
||||
if _DISABLED_MODS_LIST[self:get_name()] then
|
||||
|
||||
change_mod_state(self, true, false)
|
||||
end
|
||||
end
|
||||
|
||||
VMFMod.init_state = function (self, state)
|
||||
if type(state) ~= "boolean" then
|
||||
state = not _DISABLED_MODS_LIST[self:get_name()]
|
||||
end
|
||||
change_mod_state(self, state, true)
|
||||
end
|
||||
local _DISABLED_MODS = vmf:get("disabled_mods_list") or {}
|
||||
|
||||
-- ####################################################################################################################
|
||||
-- ##### VMF internal functions and variables #########################################################################
|
||||
-- ####################################################################################################################
|
||||
|
||||
vmf.disabled_mods_list = _DISABLED_MODS_LIST
|
||||
vmf.set_mod_state = function (mod, is_enabled, initial_call)
|
||||
|
||||
mod._data.is_enabled = is_enabled
|
||||
|
||||
if is_enabled then
|
||||
vmf.mod_enabled_event(mod, initial_call)
|
||||
else
|
||||
vmf.mod_disabled_event(mod, initial_call)
|
||||
end
|
||||
|
||||
if not (initial_call or mod:is_mutator()) then
|
||||
if is_enabled then
|
||||
_DISABLED_MODS[mod:get_name()] = nil
|
||||
else
|
||||
_DISABLED_MODS[mod:get_name()] = true
|
||||
end
|
||||
vmf:set("disabled_mods_list", _DISABLED_MODS)
|
||||
end
|
||||
end
|
||||
|
||||
-- Called when mod is loaded for the first time using mod:initialize()
|
||||
vmf.initialize_mod_state = function (mod)
|
||||
|
||||
local state
|
||||
if mod:is_mutator() then
|
||||
-- if VMF was reloaded and mutator was activated
|
||||
if vmf.is_mutator_enabled(mod:get_name()) then
|
||||
state = true
|
||||
else
|
||||
state = false
|
||||
end
|
||||
vmf.set_mutator_state(mod, state, true)
|
||||
else
|
||||
state = not _DISABLED_MODS[mod:get_name()]
|
||||
vmf.set_mod_state(mod, state, true)
|
||||
end
|
||||
end
|
||||
|
||||
vmf.mod_state_changed = function (mod_name, is_enabled)
|
||||
|
||||
local mod = get_mod(mod_name)
|
||||
|
||||
if is_enabled then
|
||||
mod:enable()
|
||||
if not mod:is_togglable() or is_enabled == mod:is_enabled() then
|
||||
return
|
||||
end
|
||||
|
||||
if mod:is_mutator() then
|
||||
vmf.set_mutator_state(mod, is_enabled, false)
|
||||
else
|
||||
mod:disable()
|
||||
vmf.set_mod_state(mod, is_enabled, false)
|
||||
end
|
||||
end
|
|
@ -38,11 +38,39 @@ end
|
|||
VMFMod = class(VMFMod)
|
||||
|
||||
VMFMod.init = function (self, mod_name)
|
||||
self._name = mod_name
|
||||
self._data = {}
|
||||
-- @TODO: forbid changing _data table
|
||||
self._data.name = mod_name
|
||||
self._data.readable_name = mod_name
|
||||
self._data.is_enabled = true
|
||||
self._data.is_togglable = false
|
||||
self._data.is_mutator = false
|
||||
end
|
||||
|
||||
-- DATA
|
||||
|
||||
VMFMod.get_name = function (self)
|
||||
return self._name
|
||||
return self._data.name
|
||||
end
|
||||
|
||||
VMFMod.get_readable_name = function (self)
|
||||
return self._data.readable_name
|
||||
end
|
||||
|
||||
VMFMod.get_description = function (self)
|
||||
return self._data.description
|
||||
end
|
||||
|
||||
VMFMod.is_enabled = function (self)
|
||||
return self._data.is_enabled
|
||||
end
|
||||
|
||||
VMFMod.is_togglable = function (self)
|
||||
return self._data.is_togglable
|
||||
end
|
||||
|
||||
VMFMod.is_mutator = function (self)
|
||||
return self._data.is_mutator
|
||||
end
|
||||
|
||||
-- ####################################################################################################################
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
local mod = new_mod("test_mod")
|
||||
local mod = get_mod("test_mod")
|
||||
|
||||
local options_widgets = {
|
||||
local mod_data = {}
|
||||
mod_data.name = "Test"
|
||||
mod_data.description = "Test mod description"
|
||||
mod_data.is_togglable = true
|
||||
--mod_data.mutator_setting = nil
|
||||
mod_data.options_widgets = {
|
||||
{
|
||||
["setting_name"] = "game_mode",
|
||||
["widget_type"] = "dropdown",
|
||||
|
@ -106,8 +111,7 @@ local options_widgets = {
|
|||
["default_value"] = 0
|
||||
}
|
||||
}
|
||||
|
||||
mod:create_options(options_widgets, true, "Test", "Mod description")
|
||||
mod:initialize_data(mod_data)
|
||||
|
||||
mod:command("whatever", "description whatever", function() mod:echo("whatever") end)
|
||||
mod:command("what", "description what", function() mod:echo("what") end)
|
||||
|
@ -115,7 +119,24 @@ mod:command("wh", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Susp
|
|||
mod:command("whoa", "description whoa", function() mod:echo("whoa") end)
|
||||
mod:command("wheat", "description wheat", function() mod:echo("wheat") end)
|
||||
mod:command("test", "short command description\n params: [parameter1] [parameter2]\nparameter1 - string\nparameter2 - number", function(p1, p2) mod:echo("Test function executed.\nParameter1: " .. tostring(p1) .. "\nParameter2: " .. tostring(p2)) end)
|
||||
|
||||
-- chat_broadcast
|
||||
|
||||
--[[
|
||||
local what = 1337
|
||||
local loadstring_function = assert( loadstring( "return UIAtlasHelper.has_atlas_settings_by_texture_name" ) )
|
||||
local loadstring_locals = { what = what}
|
||||
setfenv(loadstring_function, setmetatable(loadstring_locals, { __index = _G }))
|
||||
mod:echo(loadstring_function())
|
||||
mod:echo(getfenv(loadstring_function).what)
|
||||
]]
|
||||
|
||||
-- for serialization:
|
||||
-- table.maxn (table)
|
||||
|
||||
|
||||
|
||||
|
||||
mod.whatever = function ()
|
||||
--mod:echo("whatever")
|
||||
|
||||
|
@ -154,6 +175,27 @@ mod.whatever = function ()
|
|||
--mod.custom_mod_rpc()
|
||||
end
|
||||
--ingame_ui.handle_transition(ingame_ui, "leave_group")
|
||||
--[[
|
||||
|
||||
mod.update = function()
|
||||
local experience = ScriptBackendProfileAttribute.get("experience")
|
||||
local level = 30
|
||||
|
||||
if level ~= ExperienceSettings.get_level(experience) then
|
||||
local new_experience = experience
|
||||
|
||||
while level > ExperienceSettings.get_level(new_experience) do
|
||||
new_experience = new_experience + 500
|
||||
end
|
||||
|
||||
while level < ExperienceSettings.get_level(new_experience) do
|
||||
new_experience = new_experience - 500
|
||||
end
|
||||
|
||||
ScriptBackendProfileAttribute.set("experience", new_experience)
|
||||
end
|
||||
end
|
||||
]]
|
||||
|
||||
function mod.simulate(...)
|
||||
|
||||
|
@ -229,19 +271,16 @@ mod:pcall(
|
|||
)
|
||||
|
||||
|
||||
mod:network_register("rpc_whatever", mod.game_state_changed)
|
||||
mod:network_register("yo",mod.game_state_changed)
|
||||
mod:network_register("test", mod.game_state_changed)
|
||||
|
||||
--mod:hook("bla.bla", mod.game_state_changed)
|
||||
--mod:hook("bla.bla2", mod.game_state_changed)
|
||||
--mod:hook("bla.bla3", mod.game_state_changed)
|
||||
|
||||
local mod3 = new_mod("test_mod3")
|
||||
--local mod3 = new_mod("test_mod3")
|
||||
--mod3:hook("bla.bla", mod.game_state_changed)
|
||||
--mod3:hook("bla.bla2", mod.game_state_changed)
|
||||
--mod3:hook("bla.bla3", mod.game_state_changed)
|
||||
mod3:network_register("what", mod.game_state_changed)
|
||||
--mod3:network_register("what", mod.game_state_changed)
|
||||
|
||||
--[[
|
||||
mod:hook("ChatManager.rpc_chat_message", function (func, self, sender, channel_id, message_sender, message, localization_param, is_system_message, pop_chat, is_dev)
|
||||
|
|
|
@ -4,8 +4,7 @@ return {
|
|||
tomes = 0,
|
||||
bonus = 0
|
||||
},
|
||||
title = "",
|
||||
short_title = "",
|
||||
short_title = "", --@TODO: rename it?
|
||||
title_placement = "after",
|
||||
description = "No description provided",
|
||||
difficulty_levels = {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
--[[ Add additional dice to end game roll --]]
|
||||
|
||||
local manager = get_mod("vmf_mutator_manager")
|
||||
local vmf = get_mod("VMF")
|
||||
|
||||
-- List of all die types
|
||||
local missions = {
|
||||
|
@ -16,7 +15,7 @@ local num_dice_per_mission = {
|
|||
grimoire_hidden_mission = 0
|
||||
}
|
||||
|
||||
manager:hook("GameModeManager.complete_level", function(func, self)
|
||||
vmf:hook("GameModeManager.complete_level", function(func, self)
|
||||
local num_dice = 0
|
||||
local max_dice = 7
|
||||
local mission_system = Managers.state.entity:system("mission_system")
|
||||
|
@ -32,7 +31,7 @@ manager:hook("GameModeManager.complete_level", function(func, self)
|
|||
|
||||
-- Get total number of dice
|
||||
for name, obj in pairs(active_mission) do
|
||||
if table.has_item(missions, name) then
|
||||
if table.contains(missions, name) then
|
||||
num_dice = num_dice + obj.current_amount
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
--[[ Add mutators panel to the map view --]]
|
||||
--@TODO: button highlighted incorrectly
|
||||
local vmf = get_mod("VMF")
|
||||
|
||||
local manager = get_mod("vmf_mutator_manager")
|
||||
local mutators = manager.mutators
|
||||
local _MUTATORS = vmf.mutators
|
||||
|
||||
--manager:custom_textures("mutator_button", "mutator_button_hover")
|
||||
--manager:inject_materials("ingame_ui", "materials/vmf/mutator_button", "materials/vmf/mutator_button_hover")
|
||||
--vmf:custom_textures("mutator_button", "mutator_button_hover")
|
||||
--vmf:inject_materials("ingame_ui", "materials/vmf/mutator_button", "materials/vmf/mutator_button_hover")
|
||||
|
||||
local definitions = manager:dofile("scripts/mods/vmf/modules/ui/mutators/mutator_gui_definitions")
|
||||
local _DEFINITIONS = vmf:dofile("scripts/mods/vmf/modules/ui/mutators/mutator_gui_definitions")
|
||||
|
||||
local PER_PAGE = definitions.PER_PAGE
|
||||
local _PER_PAGE = _DEFINITIONS.PER_PAGE
|
||||
|
||||
local mutators_view = {
|
||||
|
||||
|
@ -29,17 +30,17 @@ local mutators_view = {
|
|||
self:update_mutator_list()
|
||||
|
||||
-- Recreate the map_view scenegraph defs
|
||||
self.map_view.scenegraph_definition = UISceneGraph.init_scenegraph(definitions.scenegraph_definition)
|
||||
self.map_view.scenegraph_definition = UISceneGraph.init_scenegraph(_DEFINITIONS.scenegraph_definition)
|
||||
|
||||
-- Setup custom widgets
|
||||
self.widgets = {
|
||||
banner_mutators = UIWidget.init(definitions.new_widgets.banner_mutators_widget),
|
||||
mutators_button = UIWidget.init(definitions.new_widgets.mutators_button_widget),
|
||||
no_mutators_text = UIWidget.init(definitions.new_widgets.no_mutators_text_widget)
|
||||
banner_mutators = UIWidget.init(_DEFINITIONS.new_widgets.banner_mutators_widget),
|
||||
mutators_button = UIWidget.init(_DEFINITIONS.new_widgets.mutators_button_widget),
|
||||
no_mutators_text = UIWidget.init(_DEFINITIONS.new_widgets.no_mutators_text_widget)
|
||||
}
|
||||
|
||||
for i = 1, PER_PAGE do
|
||||
table.insert(self.mutator_checkboxes, UIWidget.init(definitions.new_widgets["mutator_checkbox_" .. i]))
|
||||
for i = 1, _PER_PAGE do
|
||||
table.insert(self.mutator_checkboxes, UIWidget.init(_DEFINITIONS.new_widgets["mutator_checkbox_" .. i]))
|
||||
end
|
||||
|
||||
-- Save widgets we're gonna mess with
|
||||
|
@ -102,8 +103,8 @@ local mutators_view = {
|
|||
-- Sorts mutators by title
|
||||
update_mutator_list = function(self)
|
||||
self.mutators_sorted = {}
|
||||
for _, mutator in ipairs(mutators) do
|
||||
table.insert(self.mutators_sorted, {mutator:get_name(), mutator:get_config().title or mutator:get_name()})
|
||||
for _, mutator in ipairs(_MUTATORS) do
|
||||
table.insert(self.mutators_sorted, {mutator:get_name(), mutator:get_readable_name()})
|
||||
end
|
||||
table.sort(self.mutators_sorted, function(a, b) return string.lower(a[2]) < string.lower(b[2]) end)
|
||||
end,
|
||||
|
@ -160,9 +161,9 @@ local mutators_view = {
|
|||
|
||||
local widgets = self.map_view.normal_settings_widget_types
|
||||
|
||||
for i = 1, PER_PAGE do
|
||||
for i = 1, _PER_PAGE do
|
||||
|
||||
local current_index = PER_PAGE * (self.current_page - 1) + i
|
||||
local current_index = _PER_PAGE * (self.current_page - 1) + i
|
||||
|
||||
local checkbox = self.mutator_checkboxes[i]
|
||||
local hotspot = checkbox.content.button_hotspot
|
||||
|
@ -189,7 +190,7 @@ local mutators_view = {
|
|||
widgets.survival["mutator_checkbox_" .. i] = checkbox
|
||||
|
||||
-- Set colors based on whether mutator can be enabled
|
||||
local active = mutator:can_be_enabled()
|
||||
local active = vmf.mutator_can_be_enabled(mutator)
|
||||
local color = active and "cheeseburger" or "slate_gray"
|
||||
local color_hover = active and "white" or "slate_gray"
|
||||
checkbox.style.setting_text.text_color = Colors.get_color_table_with_alpha(color, 255)
|
||||
|
@ -205,9 +206,9 @@ local mutators_view = {
|
|||
if hotspot.on_release then
|
||||
self.map_view:play_sound("Play_hud_select")
|
||||
if mutator:is_enabled() then
|
||||
mutator:disable()
|
||||
vmf.mod_state_changed(mutator:get_name(), false)
|
||||
else
|
||||
mutator:enable()
|
||||
vmf.mod_state_changed(mutator:get_name(), true)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -215,7 +216,7 @@ local mutators_view = {
|
|||
end
|
||||
end
|
||||
|
||||
if #mutators == 0 then
|
||||
if #_MUTATORS == 0 then
|
||||
|
||||
widgets.adventure["no_mutators_text"] = self.widgets.no_mutators_text
|
||||
widgets.survival["no_mutators_text"] = self.widgets.no_mutators_text
|
||||
|
@ -245,7 +246,7 @@ local mutators_view = {
|
|||
|
||||
-- Update steppers
|
||||
local level_stepper_widget = self.map_view.steppers.level.widget
|
||||
local num_pages = math.ceil(#mutators/PER_PAGE)
|
||||
local num_pages = math.ceil(#_MUTATORS/_PER_PAGE)
|
||||
level_stepper_widget.style.setting_text.offset[2] = -10000
|
||||
level_stepper_widget.style.hover_texture.offset[2] = -10000
|
||||
level_stepper_widget.content.left_button_hotspot.disable_button = num_pages <= 1
|
||||
|
@ -285,7 +286,7 @@ local mutators_view = {
|
|||
self.map_view:update_level_stepper()
|
||||
|
||||
-- Mutator checkboxes
|
||||
for i = 1, PER_PAGE do
|
||||
for i = 1, _PER_PAGE do
|
||||
widgets.adventure["mutator_checkbox_" .. i] = nil
|
||||
widgets.survival["mutator_checkbox_" .. i] = nil
|
||||
end
|
||||
|
@ -300,7 +301,7 @@ local mutators_view = {
|
|||
if self.active then
|
||||
local current_index = self.current_page
|
||||
local new_index = current_index + index_change
|
||||
local num_pages = math.ceil(#mutators/PER_PAGE)
|
||||
local num_pages = math.ceil(#_MUTATORS/_PER_PAGE)
|
||||
|
||||
if new_index < 1 then
|
||||
new_index = num_pages
|
||||
|
@ -316,48 +317,47 @@ local mutators_view = {
|
|||
|
||||
-- Creates and return text for checkbox tooltip
|
||||
generate_tooltip_for = function(self, mutator)
|
||||
local config = mutator:get_config()
|
||||
local config = vmf.get_mutator_config(mutator)
|
||||
local text = ""
|
||||
|
||||
-- Show supported difficulty when can't be enabled due to difficulty level
|
||||
local supports_difficulty = mutator:supports_current_difficulty()
|
||||
local supports_difficulty = vmf.mutator_supports_current_difficulty(mutator)
|
||||
if not supports_difficulty then
|
||||
text = text .. "\n" .. manager:localize("tooltip_supported_difficulty") .. ":"
|
||||
text = text .. "\n" .. vmf:localize("tooltip_supported_difficulty") .. ":"
|
||||
for i, difficulty in ipairs(config.difficulty_levels) do
|
||||
text = text .. (i == 1 and " " or ", ") .. manager:localize(difficulty)
|
||||
text = text .. (i == 1 and " " or ", ") .. vmf:localize(difficulty)
|
||||
end
|
||||
end
|
||||
|
||||
-- Show enabled incompatible
|
||||
local incompatible_mutators = mutator:get_incompatible_mutators(true)
|
||||
local incompatible_mutators = vmf.get_incompatible_mutators(mutator, true)
|
||||
local currently_compatible = #incompatible_mutators == 0
|
||||
|
||||
-- Or all incompatible if difficulty is compatible
|
||||
if supports_difficulty and #incompatible_mutators == 0 then
|
||||
incompatible_mutators = mutator:get_incompatible_mutators()
|
||||
incompatible_mutators = vmf.get_incompatible_mutators(mutator)
|
||||
end
|
||||
|
||||
if #incompatible_mutators > 0 then
|
||||
|
||||
if currently_compatible and config.incompatible_with_all or #incompatible_mutators == #mutators - 1 then
|
||||
if currently_compatible and config.incompatible_with_all or #incompatible_mutators == #_MUTATORS - 1 then
|
||||
-- Show special message when incompatible with all
|
||||
text = text .. "\n" .. manager:localize("tooltip_incompatible_with_all")
|
||||
text = text .. "\n" .. vmf:localize("tooltip_incompatible_with_all")
|
||||
else
|
||||
text = text .. "\n" .. manager:localize("tooltip_incompatible_with") .. ":"
|
||||
text = text .. "\n" .. vmf:localize("tooltip_incompatible_with") .. ":"
|
||||
for i, other_mutator in ipairs(incompatible_mutators) do
|
||||
local name = (other_mutator:get_config().title or other_mutator:get_name())
|
||||
text = text .. (i == 1 and " " or ", ") .. name
|
||||
text = text .. (i == 1 and " " or ", ") .. other_mutator:get_readable_name()
|
||||
end
|
||||
end
|
||||
|
||||
elseif config.compatible_with_all then
|
||||
-- Special message when compatible with all
|
||||
text = text .. "\n" .. manager:localize("tooltip_compatible_with_all")
|
||||
text = text .. "\n" .. vmf:localize("tooltip_compatible_with_all")
|
||||
end
|
||||
|
||||
-- Special message if switched to unsupported difficulty level
|
||||
if mutator:is_enabled() and not supports_difficulty then
|
||||
text = text .. "\n" .. manager:localize("tooltip_will_be_disabled")
|
||||
text = text .. "\n" .. vmf:localize("tooltip_will_be_disabled")
|
||||
end
|
||||
|
||||
-- Description
|
||||
|
@ -372,13 +372,13 @@ local mutators_view = {
|
|||
setup_hooks = function(self)
|
||||
|
||||
-- Update the view after map_view has updated
|
||||
manager:hook("MapView.update", function(func, map_view, dt, t)
|
||||
vmf:hook("MapView.update", function(func, map_view, dt, t)
|
||||
func(map_view, dt, t)
|
||||
self:update(dt, t)
|
||||
end)
|
||||
|
||||
-- Activate the view on enter if it was active on exit
|
||||
manager:hook("MapView.on_enter", function(func, map_view)
|
||||
vmf:hook("MapView.on_enter", function(func, map_view)
|
||||
func(map_view)
|
||||
if self.was_active then
|
||||
self.widgets.mutators_button.content.toggled = true
|
||||
|
@ -387,47 +387,47 @@ local mutators_view = {
|
|||
end)
|
||||
|
||||
-- Deactivate the view on exit
|
||||
manager:hook("MapView.on_exit", function(func, map_view)
|
||||
vmf:hook("MapView.on_exit", function(func, map_view)
|
||||
func(map_view)
|
||||
self:deactivate()
|
||||
end)
|
||||
|
||||
-- We don't want to let the game disable steppers when mutators view is active
|
||||
manager:hook("MapView.update_level_stepper", function(func, map_view)
|
||||
vmf:hook("MapView.update_level_stepper", function(func, map_view)
|
||||
if not self.active then
|
||||
func(map_view)
|
||||
end
|
||||
end)
|
||||
|
||||
--[[
|
||||
manager:hook("MapView.on_level_index_changed", function(func, map_view, ...)
|
||||
vmf:hook("MapView.on_level_index_changed", function(func, map_view, ...)
|
||||
func(map_view, ...)
|
||||
print("on_level_index_changed")
|
||||
manager.disable_impossible_mutators(true)
|
||||
vmf.disable_impossible_mutators(true)
|
||||
end)
|
||||
|
||||
manager:hook("MapView.on_difficulty_index_changed", function(func, map_view, ...)
|
||||
vmf:hook("MapView.on_difficulty_index_changed", function(func, map_view, ...)
|
||||
func(map_view, ...)
|
||||
print("on_difficulty_index_changed")
|
||||
manager.disable_impossible_mutators(true)
|
||||
vmf.disable_impossible_mutators(true)
|
||||
end)
|
||||
|
||||
manager:hook("MapView.set_difficulty_stepper_index", function(func, map_view, ...)
|
||||
vmf:hook("MapView.set_difficulty_stepper_index", function(func, map_view, ...)
|
||||
func(map_view, ...)
|
||||
print("set_difficulty_stepper_index")
|
||||
manager.disable_impossible_mutators(true)
|
||||
vmf.disable_impossible_mutators(true)
|
||||
end)
|
||||
--]]
|
||||
end,
|
||||
|
||||
reset_hooks = function(self)
|
||||
manager:hook_remove("MapView.update")
|
||||
manager:hook_remove("MapView.on_enter")
|
||||
manager:hook_remove("MapView.on_exit")
|
||||
manager:hook_remove("MapView.update_level_stepper")
|
||||
-- manager:hook_remove("MapView.on_level_index_changed")
|
||||
-- manager:hook_remove("MapView.on_difficulty_index_changed")
|
||||
-- manager:hook_remove("MapView.set_difficulty_stepper_index")
|
||||
vmf:hook_remove("MapView.update")
|
||||
vmf:hook_remove("MapView.on_enter")
|
||||
vmf:hook_remove("MapView.on_exit")
|
||||
vmf:hook_remove("MapView.update_level_stepper")
|
||||
-- vmf:hook_remove("MapView.on_level_index_changed")
|
||||
-- vmf:hook_remove("MapView.on_difficulty_index_changed")
|
||||
-- vmf:hook_remove("MapView.set_difficulty_stepper_index")
|
||||
end,
|
||||
|
||||
get_map_view = function(self)
|
||||
|
@ -437,13 +437,13 @@ local mutators_view = {
|
|||
}
|
||||
|
||||
-- Initialize mutators view after map view
|
||||
manager:hook("MapView.init", function(func, self, ...)
|
||||
vmf:hook("MapView.init", function(func, self, ...)
|
||||
func(self, ...)
|
||||
mutators_view:init(self)
|
||||
end)
|
||||
|
||||
-- Destroy mutators view after map view
|
||||
manager:hook("MapView.destroy", function(func, ...)
|
||||
vmf:hook("MapView.destroy", function(func, ...)
|
||||
mutators_view:deinitialize()
|
||||
func(...)
|
||||
end)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
local manager = get_mod("vmf_mutator_manager")
|
||||
local vmf = get_mod("VMF")
|
||||
local definitions = local_require("scripts/ui/views/map_view_definitions")
|
||||
local scenegraph_definition = definitions.scenegraph_definition
|
||||
|
||||
|
@ -58,8 +58,8 @@ local new_widgets = {
|
|||
-- This will replace the banner behind the Mission text
|
||||
banner_mutators_widget = UIWidgets.create_texture_with_text_and_tooltip(
|
||||
"title_bar",
|
||||
manager:localize("mutators_title"),
|
||||
manager:localize("mutators_banner_tooltip"),
|
||||
vmf:localize("mutators_title"),
|
||||
vmf:localize("mutators_banner_tooltip"),
|
||||
"banner_level",
|
||||
"banner_mutators_text", {
|
||||
vertical_alignment = "center",
|
||||
|
@ -96,10 +96,10 @@ local new_widgets = {
|
|||
toggle_texture = "octagon_button_toggled",
|
||||
hover_texture = "octagon_button_hover",
|
||||
normal_texture = "octagon_button_normal",
|
||||
icon_texture = "mutator_button",
|
||||
icon_hover_texture = "mutator_button_hover",
|
||||
tooltip_text = manager:localize("mutators_title"),
|
||||
toggled_tooltip_text = manager:localize("mutators_title"),
|
||||
icon_texture = "map_view_party_button",
|
||||
icon_hover_texture = "map_view_party_button_lit",
|
||||
tooltip_text = vmf:localize("mutators_title"),
|
||||
toggled_tooltip_text = vmf:localize("mutators_title"),
|
||||
button_hotspot = {}
|
||||
},
|
||||
style = {
|
||||
|
@ -224,8 +224,8 @@ local new_widgets = {
|
|||
}
|
||||
},
|
||||
content = {
|
||||
text = manager:localize("no_mutators"),
|
||||
tooltip_text = manager:localize("no_mutators_tooltip"),
|
||||
text = vmf:localize("no_mutators"),
|
||||
tooltip_text = vmf:localize("no_mutators_tooltip"),
|
||||
tooltip_hotspot = {},
|
||||
color = Colors.get_color_table_with_alpha("slate_gray", 255)
|
||||
},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
--[[ Notify players of enabled mutators via chat and tab menu --]]
|
||||
local vmf = get_mod("VMF")
|
||||
|
||||
local manager = get_mod("vmf_mutator_manager")
|
||||
local mutators = manager.mutators
|
||||
local mutators = vmf.mutators
|
||||
|
||||
local were_enabled_before = false
|
||||
|
||||
|
@ -13,7 +13,7 @@ local function add_enabled_mutators_titles_to_string(str, separator, short)
|
|||
table.insert(_mutators, mutator)
|
||||
end
|
||||
end
|
||||
return manager.add_mutator_titles_to_string(_mutators, str, separator, short)
|
||||
return vmf.add_mutator_titles_to_string(_mutators, str, separator, short)
|
||||
end
|
||||
|
||||
-- Sets the lobby name
|
||||
|
@ -41,6 +41,7 @@ local function set_lobby_data()
|
|||
Managers.matchmaking.lobby:set_lobby_data(lobby_data)
|
||||
end
|
||||
|
||||
--@TODO: maybe rewrite?
|
||||
local function get_peer_id_from_cookie(client_cookie)
|
||||
local peer_id = tostring(client_cookie)
|
||||
for _ = 1, 3 do
|
||||
|
@ -55,12 +56,20 @@ local function get_peer_id_from_cookie(client_cookie)
|
|||
end
|
||||
|
||||
-- Append difficulty name with enabled mutators' titles
|
||||
manager:hook("IngamePlayerListUI.update_difficulty", function(func, self)
|
||||
vmf:hook("IngamePlayerListUI.update_difficulty", function(func, self)
|
||||
local difficulty_settings = Managers.state.difficulty:get_difficulty_settings()
|
||||
local difficulty_name = difficulty_settings.display_name
|
||||
|
||||
local name = not self.is_in_inn and Localize(difficulty_name) or ""
|
||||
name = add_enabled_mutators_titles_to_string(name, " ", true)
|
||||
--local name = not self.is_in_inn and Localize(difficulty_name) or ""
|
||||
--name = add_enabled_mutators_titles_to_string(name, ", ", true)
|
||||
|
||||
local name = add_enabled_mutators_titles_to_string("", ", ", true)
|
||||
local localized_difficulty_name = not self.is_in_inn and Localize(difficulty_name) or ""
|
||||
if name == "" then -- no mutators
|
||||
name = localized_difficulty_name
|
||||
elseif localized_difficulty_name ~= "" then -- no difficulty (inn)
|
||||
name = name .. " (" .. localized_difficulty_name .. ")"
|
||||
end
|
||||
|
||||
self.set_difficulty_name(self, name)
|
||||
|
||||
|
@ -68,25 +77,25 @@ manager:hook("IngamePlayerListUI.update_difficulty", function(func, self)
|
|||
end)
|
||||
|
||||
-- Notify everybody about enabled/disabled mutators when Play button is pressed on the map screen
|
||||
manager:hook("MatchmakingStateHostGame.host_game", function(func, self, ...)
|
||||
vmf:hook("MatchmakingStateHostGame.host_game", function(func, self, ...)
|
||||
func(self, ...)
|
||||
set_lobby_data()
|
||||
local names = add_enabled_mutators_titles_to_string("", ", ")
|
||||
if string.len(names) > 0 then
|
||||
manager:chat_broadcast(manager:localize("broadcast_enabled_mutators") .. ": " .. names)
|
||||
vmf:chat_broadcast(vmf:localize("broadcast_enabled_mutators") .. ": " .. names)
|
||||
were_enabled_before = true
|
||||
elseif were_enabled_before then
|
||||
manager:chat_broadcast(manager:localize("broadcast_all_disabled"))
|
||||
vmf:chat_broadcast(vmf:localize("broadcast_all_disabled"))
|
||||
were_enabled_before = false
|
||||
end
|
||||
end)
|
||||
|
||||
-- Send special messages with enabled mutators list to players just joining the lobby
|
||||
manager:hook("MatchmakingManager.rpc_matchmaking_request_join_lobby", function(func, self, sender, client_cookie, host_cookie, lobby_id, friend_join)
|
||||
vmf:hook("MatchmakingManager.rpc_matchmaking_request_join_lobby", function(func, self, sender, client_cookie, host_cookie, lobby_id, friend_join)
|
||||
local name = add_enabled_mutators_titles_to_string("", ", ")
|
||||
if string.len(name) > 0 then
|
||||
local message = manager:localize("whisper_enabled_mutators") .. ": " .. name
|
||||
manager:chat_whisper(get_peer_id_from_cookie(client_cookie), message)
|
||||
local message = vmf:localize("whisper_enabled_mutators") .. ": " .. name
|
||||
vmf:chat_whisper(get_peer_id_from_cookie(client_cookie), message)
|
||||
end
|
||||
func(self, sender, client_cookie, host_cookie, lobby_id, friend_join)
|
||||
end)
|
||||
|
|
|
@ -1,21 +1,17 @@
|
|||
--[[ Add ability to turn mods into mutators --]]
|
||||
|
||||
local manager = new_mod("vmf_mutator_manager")
|
||||
|
||||
manager:localization("localization/mutator_manager")
|
||||
local vmf = get_mod("VMF")
|
||||
|
||||
-- List of mods that are also mutators in order in which they should be enabled
|
||||
-- This is populated via VMFMod.register_as_mutator
|
||||
manager.mutators = {}
|
||||
local mutators = manager.mutators
|
||||
-- This is populated via vmf.register_mod_as_mutator
|
||||
local _MUTATORS = {}
|
||||
|
||||
-- Table of mutators' configs by name
|
||||
local mutators_config = {}
|
||||
local default_config = manager:dofile("scripts/mods/vmf/modules/ui/mutators/mutator_default_config")
|
||||
local _MUTATORS_CONFIG = {}
|
||||
local _DEFAULT_CONFIG
|
||||
|
||||
-- This lists mutators and which ones should be enabled after them
|
||||
-- This is populated via VMFMod.register_as_mutator
|
||||
local mutators_sequence = {
|
||||
-- This is populated via vmf.register_mod_as_mutator
|
||||
local _MUTATORS_SEQUENCE = {
|
||||
--[[
|
||||
this_mutator = {
|
||||
"will be enabled",
|
||||
|
@ -25,59 +21,71 @@ local mutators_sequence = {
|
|||
}
|
||||
|
||||
-- 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
|
||||
local all_mutators_disabled = false
|
||||
local _ALL_MUTATORS_DISABLED = false
|
||||
|
||||
-- External modules
|
||||
local _MUTATORS_VIEW
|
||||
local _DICE_MANAGER
|
||||
local _SET_LOBBY_DATA
|
||||
|
||||
--[[
|
||||
PRIVATE METHODS
|
||||
]]--
|
||||
local _MUTATORS_GUI
|
||||
|
||||
local mutators_view = manager:dofile("scripts/mods/vmf/modules/ui/mutators/mutator_gui")
|
||||
local dice_manager = manager:dofile("scripts/mods/vmf/modules/ui/mutators/mutator_dice")
|
||||
local set_lobby_data = manager:dofile("scripts/mods/vmf/modules/ui/mutators/mutator_info")
|
||||
-- List of enabled mutators in case VMF is reloaded in the middle of the game
|
||||
local _ENABLED_MUTATORS = vmf:persistent_table("enabled_mutators")
|
||||
|
||||
-- ####################################################################################################################
|
||||
-- ##### Local functions ##############################################################################################
|
||||
-- ####################################################################################################################
|
||||
|
||||
local function get_index(tbl, o)
|
||||
for i, v in ipairs(tbl) do
|
||||
if o == v then
|
||||
return i
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Adds mutator names from enable_these_after to the list of mutators that should be enabled after the mutator_name
|
||||
local function update_mutators_sequence(mutator_name, enable_these_after)
|
||||
if not mutators_sequence[mutator_name] then
|
||||
mutators_sequence[mutator_name] = {}
|
||||
if not _MUTATORS_SEQUENCE[mutator_name] then
|
||||
_MUTATORS_SEQUENCE[mutator_name] = {}
|
||||
end
|
||||
for _, other_mutator_name in ipairs(enable_these_after) do
|
||||
|
||||
if mutators_sequence[other_mutator_name] and table.has_item(mutators_sequence[other_mutator_name], mutator_name) then
|
||||
manager:error("Mutators '" .. mutator_name .. "' and '" .. other_mutator_name .. "' are both set to load after the other one.")
|
||||
elseif not table.has_item(mutators_sequence[mutator_name], other_mutator_name) then
|
||||
table.insert(mutators_sequence[mutator_name], other_mutator_name)
|
||||
if _MUTATORS_SEQUENCE[other_mutator_name] and 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, other_mutator_name)
|
||||
elseif not table.contains(_MUTATORS_SEQUENCE[mutator_name], other_mutator_name) then
|
||||
table.insert(_MUTATORS_SEQUENCE[mutator_name], other_mutator_name)
|
||||
end
|
||||
|
||||
end
|
||||
table.combine(mutators_sequence[mutator_name], enable_these_after)
|
||||
end
|
||||
|
||||
-- Checks if mutators are compatible both ways
|
||||
local function is_compatible(mutator, other_mutator)
|
||||
local config = mutator:get_config()
|
||||
local config = vmf.get_mutator_config(mutator)
|
||||
local name = mutator:get_name()
|
||||
local other_config = other_mutator:get_config()
|
||||
local other_config = vmf.get_mutator_config(other_mutator)
|
||||
local other_name = other_mutator:get_name()
|
||||
|
||||
local incompatible_specifically = (
|
||||
#config.incompatible_with > 0 and (
|
||||
table.has_item(config.incompatible_with, other_name)
|
||||
table.contains(config.incompatible_with, other_name)
|
||||
) or
|
||||
#other_config.incompatible_with > 0 and (
|
||||
table.has_item(other_config.incompatible_with, name)
|
||||
table.contains(other_config.incompatible_with, name)
|
||||
)
|
||||
)
|
||||
|
||||
local compatible_specifically = (
|
||||
#config.compatible_with > 0 and (
|
||||
table.has_item(config.compatible_with, other_name)
|
||||
table.contains(config.compatible_with, other_name)
|
||||
) or
|
||||
#other_config.compatible_with > 0 and (
|
||||
table.has_item(other_config.compatible_with, name)
|
||||
table.contains(other_config.compatible_with, name)
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -99,79 +107,22 @@ end
|
|||
|
||||
-- Called after mutator is enabled
|
||||
local function on_enabled(mutator)
|
||||
local config = mutator:get_config()
|
||||
dice_manager.addDice(config.dice)
|
||||
set_lobby_data()
|
||||
print("[MUTATORS] Enabled " .. mutator:get_name() .. " (" .. tostring(table.index_of(mutators, mutator)) .. ")")
|
||||
local config = vmf.get_mutator_config(mutator)
|
||||
_DICE_MANAGER.addDice(config.dice)
|
||||
_SET_LOBBY_DATA()
|
||||
print("[MUTATORS] Enabled " .. mutator:get_name() .. " (" .. tostring(get_index(_MUTATORS, mutator)) .. ")")
|
||||
|
||||
_ENABLED_MUTATORS[mutator:get_name()] = true
|
||||
end
|
||||
|
||||
-- Called after mutator is disabled
|
||||
local function on_disabled(mutator)
|
||||
local config = mutator:get_config()
|
||||
dice_manager.removeDice(config.dice)
|
||||
set_lobby_data()
|
||||
print("[MUTATORS] Disabled " .. mutator:get_name() .. " (" .. tostring(table.index_of(mutators, mutator)) .. ")")
|
||||
end
|
||||
local config = vmf.get_mutator_config(mutator)
|
||||
_DICE_MANAGER.removeDice(config.dice)
|
||||
_SET_LOBBY_DATA()
|
||||
print("[MUTATORS] Disabled " .. mutator:get_name() .. " (" .. tostring(get_index(_MUTATORS, mutator)) .. ")")
|
||||
|
||||
-- Enables/disables mutator while preserving the sequence in which they were enabled
|
||||
local function set_mutator_state(mutator, state)
|
||||
|
||||
local i = table.index_of(mutators, mutator)
|
||||
if i == nil then
|
||||
mutator:error("Mutator isn't in the list")
|
||||
return
|
||||
end
|
||||
|
||||
if state == mutator:is_enabled() then
|
||||
return
|
||||
end
|
||||
|
||||
if state and (
|
||||
not mutator:can_be_enabled() or
|
||||
Managers.state and Managers.state.game_mode and Managers.state.game_mode._game_mode_key ~= "inn"
|
||||
) then
|
||||
return
|
||||
end
|
||||
|
||||
-- Sort mutators if this is the first call
|
||||
if not mutators_sorted then
|
||||
manager.sort_mutators()
|
||||
end
|
||||
|
||||
local disabled_mutators = {}
|
||||
local enable_these_after = mutators_sequence[mutator:get_name()]
|
||||
|
||||
-- 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, mutator3 will be disabled before mutator2
|
||||
-- Yeah this is super confusing
|
||||
if enable_these_after and #mutators > i then
|
||||
for j = #mutators, i + 1, -1 do
|
||||
if mutators[j]:is_enabled() and table.has_item(enable_these_after, mutators[j]:get_name()) then
|
||||
--print("Disabled ", mutators[j]:get_name())
|
||||
mutators[j]:disable()
|
||||
table.insert(disabled_mutators, 1, mutators[j])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Enable/disable current mutator
|
||||
-- We're calling methods on the class object because we've overwritten them on the current one
|
||||
if state then
|
||||
VMFMod.enable(mutator)
|
||||
on_enabled(mutator)
|
||||
else
|
||||
VMFMod.disable(mutator)
|
||||
on_disabled(mutator)
|
||||
end
|
||||
|
||||
-- Re-enable disabled mutators
|
||||
-- This will be recursive
|
||||
if #disabled_mutators > 0 then
|
||||
for j = #disabled_mutators, 1, -1 do
|
||||
--print("Enabled ", disabled_mutators[j]:get_name())
|
||||
disabled_mutators[j]:enable()
|
||||
end
|
||||
end
|
||||
_ENABLED_MUTATORS[mutator:get_name()] = nil
|
||||
end
|
||||
|
||||
-- Checks if the player is server in a way that doesn't incorrectly return false during loading screens
|
||||
|
@ -181,18 +132,14 @@ local function player_is_server()
|
|||
return not player or player.is_server or not state or state.game_mode == nil
|
||||
end
|
||||
|
||||
--[[
|
||||
PUBLIC METHODS
|
||||
]]--
|
||||
|
||||
-- Sorts mutators in order they should be enabled
|
||||
manager.sort_mutators = function()
|
||||
local function sort_mutators()
|
||||
|
||||
if mutators_sorted then return end
|
||||
if _MUTATORS_SORTED then return end
|
||||
|
||||
--[[
|
||||
-- LOG --
|
||||
manager:dump(mutators_sequence, "seq", 5)
|
||||
vmf:dump(_MUTATORS_SEQUENCE, "seq", 5)
|
||||
for i, v in ipairs(mutators) do
|
||||
print(i, v:get_name())
|
||||
end
|
||||
|
@ -201,26 +148,26 @@ manager.sort_mutators = function()
|
|||
--]]
|
||||
|
||||
-- Preventing endless loops (worst case is n*(n+1)/2 I believe)
|
||||
local maxIter = #mutators * (#mutators + 1)/2
|
||||
local maxIter = #_MUTATORS * (#_MUTATORS + 1) / 2
|
||||
local numIter = 0
|
||||
|
||||
-- The idea is that all mutators before the current one are already in the right order
|
||||
-- Starting from second mutator
|
||||
local i = 2
|
||||
while i <= #mutators do
|
||||
local mutator = mutators[i]
|
||||
while i <= #_MUTATORS do
|
||||
local mutator = _MUTATORS[i]
|
||||
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
|
||||
local j = i - 1
|
||||
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
|
||||
if table.has_item(enable_these_after, other_mutator:get_name()) then
|
||||
table.remove(mutators, j)
|
||||
table.insert(mutators, i, other_mutator)
|
||||
if table.contains(enable_these_after, other_mutator:get_name()) then
|
||||
table.remove(_MUTATORS, j)
|
||||
table.insert(_MUTATORS, i, other_mutator)
|
||||
|
||||
-- This will shift the current mutator back, so adjust the index
|
||||
i = i - 1
|
||||
|
@ -232,47 +179,40 @@ manager.sort_mutators = function()
|
|||
|
||||
numIter = numIter + 1
|
||||
if numIter > maxIter then
|
||||
manager:error("Mutators: too many iterations. Check for loops in 'enable_before_these'/'enable_after_these'.")
|
||||
vmf:error("(mutators): too many iterations. Check for loops in 'enable_before_these'/'enable_after_these'.")
|
||||
return
|
||||
end
|
||||
end
|
||||
mutators_sorted = true
|
||||
_MUTATORS_SORTED = true
|
||||
|
||||
-- LOG --
|
||||
print("[MUTATORS] Sorted")
|
||||
for k, v in ipairs(mutators) do
|
||||
for k, v in ipairs(_MUTATORS) do
|
||||
print(" ", k, v:get_name())
|
||||
end
|
||||
-- /LOG --
|
||||
end
|
||||
|
||||
-- Disables mutators that cannot be enabled right now
|
||||
manager.disable_impossible_mutators = function(notify, everybody, reason)
|
||||
local disabled_mutators = {}
|
||||
for i = #mutators, 1, -1 do
|
||||
local mutator = mutators[i]
|
||||
if mutator:is_enabled() and not mutator:can_be_enabled() then
|
||||
mutator:disable()
|
||||
table.insert(disabled_mutators, mutator)
|
||||
end
|
||||
end
|
||||
if #disabled_mutators > 0 and notify then
|
||||
if not reason then reason = "" end
|
||||
local loc = everybody and "broadcast_disabled_mutators" or "local_disabled_mutators"
|
||||
local message = manager:localize(loc) .. " " .. manager:localize(reason) .. ":"
|
||||
message = message .. " " .. manager.add_mutator_titles_to_string(disabled_mutators, "", ", ", false)
|
||||
if everybody then
|
||||
manager:chat_broadcast(message)
|
||||
else
|
||||
manager:echo(message)
|
||||
end
|
||||
end
|
||||
return disabled_mutators
|
||||
-- ####################################################################################################################
|
||||
-- ##### VMF internal functions and variables #########################################################################
|
||||
-- ####################################################################################################################
|
||||
|
||||
vmf.mutators = _MUTATORS
|
||||
|
||||
-- #########
|
||||
-- # LOCAL #
|
||||
-- #########
|
||||
|
||||
-- Checks current difficulty, map selection screen settings (optionally), incompatible mutators and whether player is server
|
||||
-- to determine if a mutator can be enabled
|
||||
function vmf.mutator_can_be_enabled(mutator)
|
||||
if #vmf.get_incompatible_mutators(mutator, true) > 0 then return false end
|
||||
return player_is_server() and vmf.mutator_supports_current_difficulty(mutator)
|
||||
end
|
||||
|
||||
-- Appends, prepends and replaces the string with mutator titles
|
||||
manager.add_mutator_titles_to_string = function(_mutators, str, separator, short)
|
||||
|
||||
-- M, I
|
||||
function vmf.add_mutator_titles_to_string(_mutators, str, separator, short)
|
||||
if #_mutators == 0 then return str end
|
||||
|
||||
local before = nil
|
||||
|
@ -280,8 +220,8 @@ manager.add_mutator_titles_to_string = function(_mutators, str, separator, short
|
|||
local replace = nil
|
||||
|
||||
for _, mutator in ipairs(_mutators) do
|
||||
local config = mutator:get_config()
|
||||
local added_name = (short and config.short_title or config.title or mutator:get_name())
|
||||
local config = vmf.get_mutator_config(mutator)
|
||||
local added_name = (short and config.short_title or mutator:get_readable_name())
|
||||
if config.title_placement == "before" then
|
||||
if before then
|
||||
before = added_name .. separator .. before
|
||||
|
@ -312,44 +252,55 @@ manager.add_mutator_titles_to_string = function(_mutators, str, separator, short
|
|||
return new_str
|
||||
end
|
||||
|
||||
-- Check if player is still hosting
|
||||
manager.update = function()
|
||||
if not all_mutators_disabled and not player_is_server() then
|
||||
manager.disable_impossible_mutators(true, false, "disabled_reason_not_server")
|
||||
all_mutators_disabled = true
|
||||
-- Returns a list of incompatible with self mutators, all or only enabled ones
|
||||
-- M, G
|
||||
function vmf.get_incompatible_mutators(mutator, enabled_only)
|
||||
local incompatible_mutators = {}
|
||||
for _, other_mutator in ipairs(_MUTATORS) do
|
||||
if (
|
||||
other_mutator ~= mutator and
|
||||
(not enabled_only or other_mutator:is_enabled()) and
|
||||
not is_compatible(mutator, other_mutator)
|
||||
) then
|
||||
table.insert(incompatible_mutators, other_mutator)
|
||||
end
|
||||
end
|
||||
return incompatible_mutators
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
MUTATOR'S OWN METHODS
|
||||
]]--
|
||||
|
||||
-- Enables mutator
|
||||
local function enable_mutator(self)
|
||||
set_mutator_state(self, true)
|
||||
all_mutators_disabled = false
|
||||
end
|
||||
|
||||
-- Disables mutator
|
||||
local function disable_mutator(self)
|
||||
set_mutator_state(self, false)
|
||||
end
|
||||
|
||||
-- Checks current difficulty, map selection screen settings (optionally), incompatible mutators and whether player is server
|
||||
-- to determine if a mutator can be enabled
|
||||
local function can_be_enabled(self, ignore_map)
|
||||
if #self:get_incompatible_mutators(true) > 0 then return false end
|
||||
return player_is_server() and self:supports_current_difficulty(ignore_map)
|
||||
-- Disables mutators that cannot be enabled right now
|
||||
-- M, G
|
||||
function vmf.disable_impossible_mutators(notify, everybody, reason)
|
||||
local disabled_mutators = {}
|
||||
for i = #_MUTATORS, 1, -1 do
|
||||
local mutator = _MUTATORS[i]
|
||||
if mutator:is_enabled() and not vmf.mutator_can_be_enabled(mutator) then
|
||||
vmf.mod_state_changed(mutator:get_name(), false)
|
||||
table.insert(disabled_mutators, mutator)
|
||||
end
|
||||
end
|
||||
if #disabled_mutators > 0 and notify then
|
||||
if not reason then reason = "" end
|
||||
local loc = everybody and "broadcast_disabled_mutators" or "local_disabled_mutators"
|
||||
local message = vmf:localize(loc) .. " " .. vmf:localize(reason) .. ":"
|
||||
message = message .. " " .. vmf.add_mutator_titles_to_string(disabled_mutators, "", ", ", false)
|
||||
if everybody then
|
||||
vmf:chat_broadcast(message)
|
||||
else
|
||||
vmf:echo(message)
|
||||
end
|
||||
end
|
||||
return disabled_mutators
|
||||
end
|
||||
|
||||
-- Only checks difficulty
|
||||
local function supports_current_difficulty(self, ignore_map)
|
||||
local mutator_difficulty_levels = self:get_config().difficulty_levels
|
||||
-- M, G
|
||||
function vmf.mutator_supports_current_difficulty(mutator)
|
||||
local mutator_difficulty_levels = vmf.get_mutator_config(mutator).difficulty_levels
|
||||
local actual_difficulty = Managers.state and Managers.state.difficulty:get_difficulty()
|
||||
local right_difficulty = not actual_difficulty or table.has_item(mutator_difficulty_levels, actual_difficulty)
|
||||
local right_difficulty = not actual_difficulty or table.contains(mutator_difficulty_levels, actual_difficulty)
|
||||
|
||||
local map_view = not ignore_map and mutators_view.map_view
|
||||
local map_view = _MUTATORS_VIEW.map_view
|
||||
local map_view_active = map_view and map_view.active
|
||||
local right_unapplied_difficulty = false
|
||||
|
||||
|
@ -358,55 +309,39 @@ local function supports_current_difficulty(self, ignore_map)
|
|||
local difficulty_data = map_view.selected_level_index and map_view:get_difficulty_data(map_view.selected_level_index)
|
||||
local difficulty_layout = difficulty_data and difficulty_data[map_view.selected_difficulty_stepper_index]
|
||||
local difficulty_key = difficulty_layout and difficulty_layout.key
|
||||
right_unapplied_difficulty = difficulty_key and table.has_item(mutator_difficulty_levels, difficulty_key)
|
||||
right_unapplied_difficulty = difficulty_key and table.contains(mutator_difficulty_levels, difficulty_key)
|
||||
end
|
||||
|
||||
return (map_view_active and right_unapplied_difficulty) or (not map_view_active and right_difficulty)
|
||||
end
|
||||
|
||||
-- Returns the config object for mutator from mutators_config
|
||||
local function get_config(self)
|
||||
return mutators_config[self:get_name()]
|
||||
-- Returns the config object for mutator from _MUTATORS_CONFIG
|
||||
-- M, G
|
||||
function vmf.get_mutator_config(mutator)
|
||||
return _MUTATORS_CONFIG[mutator:get_name()]
|
||||
end
|
||||
|
||||
-- Returns a list of incompatible with self mutators, all or only enabled ones
|
||||
local function get_incompatible_mutators(self, enabled_only)
|
||||
local incompatible_mutators = {}
|
||||
for _, other_mutator in ipairs(mutators) do
|
||||
if (
|
||||
other_mutator ~= self and
|
||||
(not enabled_only or other_mutator:is_enabled()) and
|
||||
not is_compatible(self, other_mutator)
|
||||
) then
|
||||
table.insert(incompatible_mutators, other_mutator)
|
||||
end
|
||||
end
|
||||
return incompatible_mutators
|
||||
end
|
||||
-- ##########
|
||||
-- # GLOBAL #
|
||||
-- ##########
|
||||
|
||||
-- Turns a mod into a mutator
|
||||
VMFMod.register_as_mutator = function(self, config)
|
||||
function vmf.register_mod_as_mutator(mod, config)
|
||||
if not config then config = {} end
|
||||
|
||||
local mod_name = self:get_name()
|
||||
table.insert(_MUTATORS, mod)
|
||||
|
||||
if table.has_item(mutators, self) then
|
||||
self:error("Mod is already registered as mutator")
|
||||
return
|
||||
end
|
||||
|
||||
table.insert(mutators, self)
|
||||
local mod_name = mod:get_name()
|
||||
|
||||
-- Save config
|
||||
mutators_config[mod_name] = table.clone(default_config)
|
||||
local _config = mutators_config[mod_name]
|
||||
_MUTATORS_CONFIG[mod_name] = table.clone(_DEFAULT_CONFIG)
|
||||
local _config = _MUTATORS_CONFIG[mod_name]
|
||||
for k, _ in pairs(_config) do
|
||||
if config[k] ~= nil then
|
||||
_config[k] = config[k]
|
||||
end
|
||||
end
|
||||
if _config.short_title == "" then _config.short_title = nil end
|
||||
if _config.title == "" then _config.title = nil end
|
||||
|
||||
if config.enable_before_these then
|
||||
update_mutators_sequence(mod_name, config.enable_before_these)
|
||||
|
@ -418,42 +353,94 @@ VMFMod.register_as_mutator = function(self, config)
|
|||
end
|
||||
end
|
||||
|
||||
self.enable = enable_mutator
|
||||
self.disable = disable_mutator
|
||||
self.can_be_enabled = can_be_enabled
|
||||
self.supports_current_difficulty = supports_current_difficulty
|
||||
_MUTATORS_SORTED = false
|
||||
|
||||
self.get_config = get_config
|
||||
self.get_incompatible_mutators = get_incompatible_mutators
|
||||
|
||||
mutators_sorted = false
|
||||
|
||||
-- Always init in the off state
|
||||
self:init_state(false)
|
||||
|
||||
mutators_view:update_mutator_list()
|
||||
_MUTATORS_VIEW:update_mutator_list()
|
||||
end
|
||||
|
||||
-- Enables/disables mutator while preserving the sequence in which they were enabled
|
||||
function vmf.set_mutator_state(mutator, state, initial_call)
|
||||
|
||||
--[[
|
||||
HOOKS
|
||||
]]--
|
||||
manager:hook("DifficultyManager.set_difficulty", function(func, self, difficulty)
|
||||
manager.disable_impossible_mutators(true, true, "disabled_reason_difficulty_change")
|
||||
-- Sort mutators if this is the first call
|
||||
if not _MUTATORS_SORTED then
|
||||
sort_mutators()
|
||||
end
|
||||
|
||||
local disabled_mutators = {}
|
||||
local enable_these_after = _MUTATORS_SEQUENCE[mutator:get_name()]
|
||||
|
||||
local i = get_index(_MUTATORS, mutator)
|
||||
-- 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, mutator3 will be disabled before mutator2
|
||||
-- Yeah this is super confusing
|
||||
if enable_these_after and #_MUTATORS > i then
|
||||
for j = #_MUTATORS, i + 1, -1 do
|
||||
if _MUTATORS[j]:is_enabled() and table.contains(enable_these_after, _MUTATORS[j]:get_name()) then
|
||||
--print("Disabled ", _MUTATORS[j]:get_name())
|
||||
vmf.set_mutator_state(_MUTATORS[j], false, false)
|
||||
table.insert(disabled_mutators, 1, _MUTATORS[j])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Enable/disable current mutator
|
||||
-- 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)
|
||||
if state then
|
||||
_ALL_MUTATORS_DISABLED = false
|
||||
on_enabled(mutator)
|
||||
else
|
||||
on_disabled(mutator)
|
||||
end
|
||||
|
||||
-- Re-enable disabled mutators
|
||||
-- This will be recursive
|
||||
if #disabled_mutators > 0 then
|
||||
for j = #disabled_mutators, 1, -1 do
|
||||
--print("Enabled ", disabled_mutators[j]:get_name())
|
||||
vmf.set_mutator_state(disabled_mutators[j], true, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if player is still hosting (on update)
|
||||
function vmf.check_mutators_state()
|
||||
if not _ALL_MUTATORS_DISABLED and not player_is_server() then
|
||||
vmf.disable_impossible_mutators(true, false, "disabled_reason_not_server")
|
||||
_ALL_MUTATORS_DISABLED = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Called only after VMF reloading to check if some mutators were enabled before reloading
|
||||
function vmf.is_mutator_enabled(mutator_name)
|
||||
return _ENABLED_MUTATORS[mutator_name]
|
||||
end
|
||||
|
||||
-- ####################################################################################################################
|
||||
-- ##### Hooks ########################################################################################################
|
||||
-- ####################################################################################################################
|
||||
|
||||
vmf:hook("DifficultyManager.set_difficulty", function(func, self, difficulty)
|
||||
vmf.disable_impossible_mutators(true, true, "disabled_reason_difficulty_change")
|
||||
return func(self, difficulty)
|
||||
end)
|
||||
|
||||
-- ####################################################################################################################
|
||||
-- ##### Script #######################################################################################################
|
||||
-- ####################################################################################################################
|
||||
|
||||
--[[
|
||||
INITIALIZE
|
||||
--]]
|
||||
_DEFAULT_CONFIG = vmf:dofile("scripts/mods/vmf/modules/ui/mutators/mutator_default_config")
|
||||
|
||||
_MUTATORS_VIEW = vmf:dofile("scripts/mods/vmf/modules/ui/mutators/mutator_gui")
|
||||
_DICE_MANAGER = vmf:dofile("scripts/mods/vmf/modules/ui/mutators/mutator_dice")
|
||||
_SET_LOBBY_DATA = vmf:dofile("scripts/mods/vmf/modules/ui/mutators/mutator_info")
|
||||
|
||||
_MUTATORS_GUI = vmf:dofile("scripts/mods/vmf/modules/ui/mutators/mutators_gui")
|
||||
|
||||
-- Initialize mutators view when map_view has been initialized already
|
||||
mutators_view:init(mutators_view:get_map_view())
|
||||
_MUTATORS_VIEW:init(_MUTATORS_VIEW:get_map_view())
|
||||
|
||||
--[[
|
||||
Testing
|
||||
--]]
|
||||
-- manager:dofile("scripts/mods/vmf/modules/ui/mutators/mutator_test")
|
||||
-- manager:dofile("scripts/mods/vmf/modules/ui/mutators/mutators/mutation")
|
||||
-- manager:dofile("scripts/mods/vmf/modules/ui/mutators/mutators/deathwish")
|
||||
-- Testing
|
||||
--vmf:dofile("scripts/mods/vmf/modules/ui/mutators/test/mutator_test")
|
||||
--vmf:dofile("scripts/mods/vmf/modules/ui/mutators/test/mutation")
|
||||
--vmf:dofile("scripts/mods/vmf/modules/ui/mutators/test/deathwish")
|
145
vmf/scripts/mods/vmf/modules/ui/mutators/test/mutator_test.lua
Normal file
145
vmf/scripts/mods/vmf/modules/ui/mutators/test/mutator_test.lua
Normal file
|
@ -0,0 +1,145 @@
|
|||
local vmf = get_mod("VMF")
|
||||
|
||||
local mod_data
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
local mutator555 = new_mod("mutator555")
|
||||
mod_data = {}
|
||||
mod_data.name = "Legendary"
|
||||
mod_data.description = "Legendary description"
|
||||
mod_data.is_mutator = true
|
||||
mod_data.mutator_setting = {
|
||||
incompatible_with_all = true,
|
||||
compatible_with = {
|
||||
--"mutator3"
|
||||
}
|
||||
--title = "Legendary"
|
||||
}
|
||||
mutator555:initialize_data(mod_data)
|
||||
mutator555.on_enabled = function(init_call) mutator555:echo("Legendary on_enabled(" .. (init_call and "init)" or ")")) end
|
||||
mutator555.on_disabled = function(init_call) mutator555:echo("Legendary on_disabled(" .. (init_call and "init)" or ")")) end
|
||||
vmf.initialize_mod_state(mutator555)
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
local mutator3 = new_mod("mutator3")
|
||||
mod_data = {}
|
||||
mod_data.name = "Something"
|
||||
mod_data.is_mutator = true
|
||||
mod_data.mutator_setting = {
|
||||
incompatible_with = {
|
||||
"mutator4"
|
||||
},
|
||||
--title = "Something"
|
||||
}
|
||||
mutator3:initialize_data(mod_data)
|
||||
mutator3.on_enabled = function(init_call) mutator3:echo("Something on_enabled(" .. (init_call and "init)" or ")")) end
|
||||
mutator3.on_disabled = function(init_call) mutator3:echo("Something on_disabled(" .. (init_call and "init)" or ")")) end
|
||||
vmf.initialize_mod_state(mutator3)
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
local mutator2 = new_mod("mutator2")
|
||||
mod_data = {}
|
||||
mod_data.name = "?Deathwish"
|
||||
mod_data.is_mutator = true
|
||||
mod_data.mutator_setting = {
|
||||
difficulty_levels = {
|
||||
"hardest",
|
||||
"survival_hardest"
|
||||
},
|
||||
--title = "?Deathwish",
|
||||
title_placement = "after"
|
||||
}
|
||||
mutator2:initialize_data(mod_data)
|
||||
mutator2.on_enabled = function(init_call) mutator3:echo("?Deathwish on_enabled(" .. (init_call and "init)" or ")")) end
|
||||
mutator2.on_disabled = function(init_call) mutator3:echo("?Deathwish on_disabled(" .. (init_call and "init)" or ")")) end
|
||||
vmf.initialize_mod_state(mutator2)
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
local slayer = new_mod("slayer")
|
||||
mod_data = {}
|
||||
mod_data.name = "Slayer's Oath"
|
||||
mod_data.is_mutator = true
|
||||
mod_data.mutator_setting = {
|
||||
difficulty_levels = {
|
||||
"survival_hard",
|
||||
"survival_harder",
|
||||
"survival_hardest"
|
||||
},
|
||||
--title = "Slayer's Oath"
|
||||
}
|
||||
slayer:initialize_data(mod_data)
|
||||
slayer.on_enabled = function(init_call) mutator3:echo("Slayer's Oath on_enabled(" .. (init_call and "init)" or ")")) end
|
||||
slayer.on_disabled = function(init_call) mutator3:echo("Slayer's Oath on_disabled(" .. (init_call and "init)" or ")")) end
|
||||
vmf.initialize_mod_state(slayer)
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
local true_solo = new_mod("true_solo")
|
||||
mod_data = {}
|
||||
mod_data.name = "True Solo"
|
||||
mod_data.is_mutator = true
|
||||
mod_data.mutator_setting = {
|
||||
compatible_with_all = true,
|
||||
--title = "True Solo",
|
||||
title_placement = "before"
|
||||
}
|
||||
true_solo:initialize_data(mod_data)
|
||||
true_solo.on_enabled = function(init_call) mutator3:echo("True Solo on_enabled(" .. (init_call and "init)" or ")")) end
|
||||
true_solo.on_disabled = function(init_call) mutator3:echo("True Solo on_disabled(" .. (init_call and "init)" or ")")) end
|
||||
vmf.initialize_mod_state(true_solo)
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
local onslaught = new_mod("onslaught")
|
||||
mod_data = {}
|
||||
mod_data.name = "Onslaught"
|
||||
mod_data.is_mutator = true
|
||||
--mod_data.mutator_setting = {
|
||||
-- title = "Onslaught"
|
||||
--}
|
||||
onslaught:initialize_data(mod_data)
|
||||
onslaught.on_enabled = function(init_call) mutator3:echo("Onslaught on_enabled(" .. (init_call and "init)" or ")")) end
|
||||
onslaught.on_disabled = function(init_call) mutator3:echo("Onslaught on_disabled(" .. (init_call and "init)" or ")")) end
|
||||
vmf.initialize_mod_state(onslaught)
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
local one_hit_one_kill = new_mod("one_hit_one_kill")
|
||||
mod_data = {}
|
||||
mod_data.name = "One Hit One Kill"
|
||||
mod_data.is_mutator = true
|
||||
mod_data.mutator_setting = {
|
||||
--title = "One Hit One Kill",
|
||||
difficulty_levels = {"hardest"},
|
||||
enable_after_these = {"more_rat_weapons"}
|
||||
}
|
||||
one_hit_one_kill:initialize_data(mod_data)
|
||||
one_hit_one_kill.on_enabled = function(init_call) mutator3:echo("One Hit One Kill on_enabled(" .. (init_call and "init)" or ")")) end
|
||||
one_hit_one_kill.on_disabled = function(init_call) mutator3:echo("One Hit One Kill on_disabled(" .. (init_call and "init)" or ")")) end
|
||||
vmf.initialize_mod_state(one_hit_one_kill)
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
local more_rat_weapons = new_mod("more_rat_weapons")
|
||||
mod_data = {}
|
||||
mod_data.name = "More Rat Weapons"
|
||||
mod_data.is_mutator = true
|
||||
mod_data.mutator_setting = {
|
||||
compatible_with_all = true,
|
||||
--title = "More Rat Weapons",
|
||||
difficulty_levels = {"hardest"}
|
||||
}
|
||||
more_rat_weapons:initialize_data(mod_data)
|
||||
more_rat_weapons.on_enabled = function(init_call) mutator3:echo("More Rat Weapons on_enabled(" .. (init_call and "init)" or ")")) end
|
||||
more_rat_weapons.on_disabled = function(init_call) mutator3:echo("More Rat Weapons on_disabled(" .. (init_call and "init)" or ")")) end
|
||||
vmf.initialize_mod_state(more_rat_weapons)
|
||||
|
||||
--[[for i=4,17 do
|
||||
local mutator = new_mod("mutator" .. i)
|
||||
mutator:register_as_mutator({})
|
||||
mutator.on_enabled = function(init_call) end
|
||||
mutator.on_disabled = function(init_call) end
|
||||
end--]]
|
|
@ -3424,7 +3424,7 @@ VMFOptionsView.update_picked_option_for_settings_list_widgets = function (self)
|
|||
|
||||
elseif widget_type == "header" then
|
||||
|
||||
widget_content.is_checkbox_checked = not vmf.disabled_mods_list[widget_content.mod_name]
|
||||
widget_content.is_checkbox_checked = get_mod(widget_content.mod_name):is_enabled()
|
||||
|
||||
elseif widget_type == "keybind" then
|
||||
|
||||
|
@ -3881,7 +3881,7 @@ vmf.load_vmf_options_view_settings()
|
|||
-- ####################################################################################################################
|
||||
|
||||
|
||||
VMFMod.create_options = function (self, widgets_definition, is_mod_toggable, readable_mod_name, mod_description)
|
||||
vmf.create_options = function (mod, widgets_definition)
|
||||
|
||||
local mod_settings_list_widgets_definitions = {}
|
||||
|
||||
|
@ -3892,7 +3892,7 @@ VMFMod.create_options = function (self, widgets_definition, is_mod_toggable, rea
|
|||
local options_menu_collapsed_widgets = vmf:get("options_menu_collapsed_widgets")
|
||||
local mod_collapsed_widgets = nil
|
||||
if options_menu_collapsed_widgets then
|
||||
mod_collapsed_widgets = options_menu_collapsed_widgets[self:get_name()]
|
||||
mod_collapsed_widgets = options_menu_collapsed_widgets[mod:get_name()]
|
||||
end
|
||||
|
||||
-- defining header widget
|
||||
|
@ -3903,19 +3903,19 @@ VMFMod.create_options = function (self, widgets_definition, is_mod_toggable, rea
|
|||
|
||||
new_widget_definition.widget_type = "header"
|
||||
new_widget_definition.widget_index = new_widget_index
|
||||
new_widget_definition.mod_name = self:get_name()
|
||||
new_widget_definition.readable_mod_name = readable_mod_name or self:get_name()
|
||||
new_widget_definition.tooltip = mod_description
|
||||
new_widget_definition.mod_name = mod:get_name()
|
||||
new_widget_definition.readable_mod_name = mod:get_readable_name()
|
||||
new_widget_definition.tooltip = mod:get_description()
|
||||
new_widget_definition.default = true
|
||||
new_widget_definition.is_mod_toggable = is_mod_toggable
|
||||
new_widget_definition.is_mod_toggable = mod:is_togglable() and not mod:is_mutator()
|
||||
|
||||
if mod_collapsed_widgets then
|
||||
new_widget_definition.is_widget_collapsed = mod_collapsed_widgets[self:get_name()]
|
||||
new_widget_definition.is_widget_collapsed = mod_collapsed_widgets[mod:get_name()]
|
||||
end
|
||||
|
||||
if options_menu_favorite_mods then
|
||||
for _, current_mod_name in pairs(options_menu_favorite_mods) do
|
||||
if current_mod_name == self:get_name() then
|
||||
if current_mod_name == mod:get_name() then
|
||||
new_widget_definition.is_favorited = true
|
||||
break
|
||||
end
|
||||
|
@ -3950,7 +3950,7 @@ VMFMod.create_options = function (self, widgets_definition, is_mod_toggable, rea
|
|||
new_widget_definition.widget_type = current_widget.widget_type -- all
|
||||
new_widget_definition.widget_index = new_widget_index -- all [gen]
|
||||
new_widget_definition.widget_level = level -- all [gen]
|
||||
new_widget_definition.mod_name = self:get_name() -- all [gen]
|
||||
new_widget_definition.mod_name = mod:get_name() -- all [gen]
|
||||
new_widget_definition.setting_name = current_widget.setting_name -- all
|
||||
new_widget_definition.text = current_widget.text -- all
|
||||
new_widget_definition.tooltip = current_widget.tooltip -- all [optional]
|
||||
|
@ -3967,15 +3967,15 @@ VMFMod.create_options = function (self, widgets_definition, is_mod_toggable, rea
|
|||
new_widget_definition.is_widget_collapsed = mod_collapsed_widgets[current_widget.setting_name]
|
||||
end
|
||||
|
||||
if type(self:get(current_widget.setting_name)) == "nil" then
|
||||
self:set(current_widget.setting_name, current_widget.default_value)
|
||||
if type(mod:get(current_widget.setting_name)) == "nil" then
|
||||
mod:set(current_widget.setting_name, current_widget.default_value)
|
||||
end
|
||||
|
||||
if current_widget.widget_type == "keybind" then
|
||||
local keybind = self:get(current_widget.setting_name)
|
||||
local keybind = mod:get(current_widget.setting_name)
|
||||
new_widget_definition.keybind_text = build_keybind_string(keybind)
|
||||
if current_widget.action then
|
||||
self:keybind(current_widget.setting_name, current_widget.action, keybind)
|
||||
mod:keybind(current_widget.setting_name, current_widget.action, keybind)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -4034,7 +4034,7 @@ VMFMod.create_options = function (self, widgets_definition, is_mod_toggable, rea
|
|||
end
|
||||
|
||||
if new_widget_index == 257 then
|
||||
self:error("(vmf_options_view) The limit of 256 options widgets was reached. You can't add any more widgets.")
|
||||
mod:error("(vmf_options_view) The limit of 256 options widgets was reached. You can't add any more widgets.")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -4135,6 +4135,7 @@ vmf.disable_mods_options_button = function ()
|
|||
change_mods_options_button_state("disable")
|
||||
end
|
||||
|
||||
-- @BUG: Game crashes occasionaly here. See attached log
|
||||
-- create mods options menu button in Esc-menu
|
||||
vmf:hook("IngameView.setup_button_layout", function (func, self, layout_data)
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
local vmf = get_mod("VMF")
|
||||
|
||||
local options_widgets = {
|
||||
local vmf_mod_data = {}
|
||||
vmf_mod_data.name = "Vermintide Mod Framework"
|
||||
vmf_mod_data.options_widgets = {
|
||||
{
|
||||
["setting_name"] = "open_vmf_options",
|
||||
["widget_type"] = "keybind",
|
||||
|
@ -268,7 +270,7 @@ end
|
|||
-- ##### Script #######################################################################################################
|
||||
-- ####################################################################################################################
|
||||
|
||||
vmf:create_options(options_widgets, false, "Vermintide Mod Framework")
|
||||
vmf:initialize_data(vmf_mod_data)
|
||||
|
||||
-- first VMF initialization
|
||||
-- it will be run only 1 time, when the player launch the game with VMF for the first time
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
return {
|
||||
init = function(object)
|
||||
|
||||
dofile("scripts/mods/vmf/functions/table")
|
||||
Managers.vmf = Managers.vmf or {}
|
||||
|
||||
dofile("scripts/mods/vmf/modules/mods")
|
||||
dofile("scripts/mods/vmf/modules/core/events")
|
||||
dofile("scripts/mods/vmf/modules/core/settings")
|
||||
dofile("scripts/mods/vmf/modules/core/core_functions")
|
||||
dofile("scripts/mods/vmf/modules/core/initialization")
|
||||
dofile("scripts/mods/vmf/modules/core/persistent_tables")
|
||||
dofile("scripts/mods/vmf/modules/debug/dev_console")
|
||||
dofile("scripts/mods/vmf/modules/debug/table_dump")
|
||||
dofile("scripts/mods/vmf/modules/core/hooks")
|
||||
|
@ -35,7 +37,8 @@ return {
|
|||
end)
|
||||
|
||||
-- temporary solution:
|
||||
dofile("scripts/mods/vmf/modules/testing_stuff_here")
|
||||
local mod = new_mod("test_mod")
|
||||
mod:initialize("scripts/mods/vmf/modules/testing_stuff_here")
|
||||
end,
|
||||
|
||||
update = function(object, dt)
|
||||
|
@ -43,6 +46,7 @@ return {
|
|||
object.vmf.mods_update_event(dt)
|
||||
object.vmf.check_pressed_keybinds()
|
||||
object.vmf.check_custom_menus_close_keybinds(dt)
|
||||
object.vmf.check_mutators_state()
|
||||
|
||||
if not object.vmf.all_mods_were_loaded and Managers.mod._state == "done" then
|
||||
|
||||
|
@ -79,9 +83,9 @@ return {
|
|||
object.vmf.save_unsaved_settings_to_file()
|
||||
object.vmf.apply_delayed_hooks()
|
||||
|
||||
if status == "exit" and state == "StateTitleScreen" then
|
||||
object.vmf.hook_chat_manager()
|
||||
end
|
||||
--if status == "exit" and state == "StateTitleScreen" then
|
||||
-- object.vmf.hook_chat_manager()
|
||||
--end
|
||||
|
||||
if status == "enter" and state == "StateIngame" then
|
||||
object.vmf.initialize_keybinds()
|
||||
|
|
Loading…
Add table
Reference in a new issue