mutators: add prototype gui, add auto disabling of mutators

This commit is contained in:
UnShame 2018-02-20 16:45:31 +03:00
parent 81a195ec30
commit 0d417798d8
4 changed files with 298 additions and 46 deletions

View file

@ -5,8 +5,8 @@ return {
bonus = 0 bonus = 0
}, },
server_name = "", server_name = "",
title = "default_title", title = "",
--short_title = "", short_title = "",
difficulties = { difficulties = {
"easy", "easy",
"normal", "normal",

View file

@ -0,0 +1,176 @@
local vmf = get_mod("VMF")
local mutators = vmf.mutators
local window = nil
local button = nil
local window_opened = false
local function update_window_visibility(map_view)
if not window then return end
button.visible = map_view and map_view.friends and not map_view.friends:is_active()
window.visible = window_opened and button.visible
end
local function destroy_window(map_view)
if window then
window:destroy()
window = nil
button:destroy()
map_view.ui_scenegraph.settings_button.position[1] = map_view.ui_scenegraph.settings_button.position[1] - 50
map_view.ui_scenegraph.friends_button.position[1] = map_view.ui_scenegraph.friends_button.position[1] - 50
map_view.ui_scenegraph.lobby_button.position[1] = map_view.ui_scenegraph.lobby_button.position[1] - 50
end
end
local function create_window(map_view)
destroy_window(map_view)
vmf.sort_mutators()
vmf.disable_impossible_mutators()
local window_size = {0, 0}
local window_position = {50, 500}
window = get_mod("gui").create_window("mutators_window", window_position, window_size)
for i, mutator in ipairs(mutators) do
window:create_checkbox("label" .. mutator:get_name(), {10, 40 * i}, {30, 30}, mutator:get_config().title, mutator:is_enabled(), function()
if not mutator:is_enabled() and mutator:can_be_enabled() then
mutator:enable()
elseif mutator:is_enabled() then
mutator:disable()
else
create_window(map_view)
end
end)
end
window:init()
button = get_mod("gui").create_window("mutators_button", window_position, window_size)
button:create_button("mutators", {55, -75}, {65, 65}, "Mut", function()
window_opened = not window_opened
end)
button:init()
map_view.ui_scenegraph.settings_button.position[1] = map_view.ui_scenegraph.settings_button.position[1] + 50
map_view.ui_scenegraph.friends_button.position[1] = map_view.ui_scenegraph.friends_button.position[1] + 50
map_view.ui_scenegraph.lobby_button.position[1] = map_view.ui_scenegraph.lobby_button.position[1] + 50
update_window_visibility(map_view)
end
vmf:hook("MapView.on_enter", function(func, self, ...)
func(self, ...)
print("on_enter")
vmf:pcall(function() create_window(self) end)
end)
vmf:hook("MapView.on_level_index_changed", function(func, self, ...)
func(self, ...)
print("on_level_index_changed")
vmf:pcall(function() create_window(self) end)
end)
vmf:hook("MapView.on_difficulty_index_changed", function(func, self, ...)
func(self, ...)
print("on_difficulty_index_changed")
vmf:pcall(function() create_window(self) end)
end)
vmf:hook("MapView.set_difficulty_stepper_index", function(func, self, ...)
func(self, ...)
print("set_difficulty_stepper_index")
vmf:pcall(function() create_window(self) end)
end)
vmf:hook("MapView.on_exit", function(func, self, ...)
func(self, ...)
print("on_exit")
vmf:pcall(function() destroy_window(self) end)
window_opened = false
end)
vmf:hook("MapView.suspend", function(func, self, ...)
func(self, ...)
print("suspend")
vmf:pcall(function() destroy_window(self) end)
end)
vmf:hook("MapView.update", function(func, self, dt, t)
func(self, dt, t)
vmf:pcall(function() update_window_visibility(self) end)
end)
vmf:hook("MapView.draw", function(func, self, input_service, gamepad_active, dt)
local ui_renderer = self.ui_renderer
local ui_scenegraph = self.ui_scenegraph
UIRenderer.begin_pass(ui_renderer, ui_scenegraph, input_service, dt, nil, self.render_settings)
for _, widget in ipairs(self.background_widgets) do
UIRenderer.draw_widget(ui_renderer, widget)
end
local number_of_player = self.number_of_player or 0
for i = 1, number_of_player, 1 do
local widget = self.player_list_widgets[i]
UIRenderer.draw_widget(ui_renderer, widget)
end
if not window_opened then
if self.settings_button_widget.content.toggled then
for widget_name, widget in pairs(self.advanced_settings_widgets) do
UIRenderer.draw_widget(ui_renderer, widget)
end
else
for widget_name, widget in pairs(self.normal_settings_widgets) do
UIRenderer.draw_widget(ui_renderer, widget)
end
end
end
UIRenderer.draw_widget(ui_renderer, self.player_list_conuter_text_widget)
UIRenderer.draw_widget(ui_renderer, self.description_field_widget)
UIRenderer.draw_widget(ui_renderer, self.title_text_widget)
UIRenderer.draw_widget(ui_renderer, self.game_mode_selection_bar_widget)
UIRenderer.draw_widget(ui_renderer, self.game_mode_selection_bar_bg_widget)
UIRenderer.draw_widget(ui_renderer, self.private_checkbox_widget)
if not gamepad_active then
UIRenderer.draw_widget(ui_renderer, self.friends_button_widget)
UIRenderer.draw_widget(ui_renderer, self.settings_button_widget)
UIRenderer.draw_widget(ui_renderer, self.confirm_button_widget)
UIRenderer.draw_widget(ui_renderer, self.cancel_button_widget)
UIRenderer.draw_widget(ui_renderer, self.lobby_button_widget)
if not self.confirm_button_widget.content.button_hotspot.disabled then
UIRenderer.draw_widget(ui_renderer, self.button_eye_glow_widget)
else
UIRenderer.draw_widget(ui_renderer, self.confirm_button_disabled_tooltip_widget)
end
else
UIRenderer.draw_widget(ui_renderer, self.background_overlay_console_widget)
UIRenderer.draw_widget(ui_renderer, self.gamepad_button_selection_widget)
end
local draw_intro_description = self.draw_intro_description
if draw_intro_description then
for key, text_widget in pairs(self.description_text_widgets) do
UIRenderer.draw_widget(ui_renderer, text_widget)
end
end
UIRenderer.end_pass(ui_renderer)
local friends_menu_active = self.friends:is_active()
if gamepad_active and not friends_menu_active and not self.popup_id and not draw_intro_description then
self.menu_input_description:draw(ui_renderer, dt)
end
end)

View file

@ -1,12 +1,19 @@
local vmf = get_mod("VMF") local vmf = get_mod("VMF")
local mutators = vmf.mutators local mutators = vmf.mutators
local were_enabled_before = false
local function get_enabled_mutators_names(short) local function get_enabled_mutators_names(short)
local name = "" local name = nil
for _, mutator in ipairs(mutators) do for _, mutator in ipairs(mutators) do
local config = mutator:get_config() local config = mutator:get_config()
if mutator:is_enabled() then if mutator:is_enabled() then
name = name .. " " .. (short and config.short_title or config.title) local added_name = (short and config.short_title or config.title or mutator:get_name())
if name then
name = name .. " " .. added_name
else
name = added_name
end
end end
end end
return name return name
@ -63,6 +70,14 @@ end)
vmf:hook("MatchmakingStateHostGame.host_game", function(func, self, ...) vmf:hook("MatchmakingStateHostGame.host_game", function(func, self, ...)
func(self, ...) func(self, ...)
set_lobby_data() set_lobby_data()
local names = get_enabled_mutators_names()
if names then
Managers.chat:send_system_chat_message(1, "ENABLED MUTATORS: " .. names, 0, true)
were_enabled_before = true
elseif were_enabled_before then
Managers.chat:send_system_chat_message(1, "ALL MUTATORS DISABLED", 0, true)
were_enabled_before = false
end
end) end)
vmf: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)

View file

@ -3,8 +3,8 @@ 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
-- This is populated via VMFMod.register_as_mutator -- This is populated via VMFMod.register_as_mutator
local mutators = {} vmf.mutators = {}
vmf.mutators = mutators local mutators = vmf.mutators
local mutators_config = {} local mutators_config = {}
local default_config = dofile("scripts/mods/vmf/modules/mutators/default_config") local default_config = dofile("scripts/mods/vmf/modules/mutators/default_config")
@ -25,31 +25,13 @@ local mutators_sorted = false
--[[ --[[
PRIVATE METHODS PUBLIC METHODS
]]-- ]]--
local addDice, removeDice = dofile("scripts/mods/vmf/modules/mutators/dice")
local set_lobby_data = dofile("scripts/mods/vmf/modules/mutators/info")
-- 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] = {}
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
vmf: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)
end
end
table.combine(mutators_sequence[mutator_name], enable_these_after)
end
-- Sorts mutators in order they should be enabled -- Sorts mutators in order they should be enabled
local function sort_mutators() vmf.sort_mutators = function()
if mutators_sorted then return end
-- LOG -- -- LOG --
vmf:dump(mutators_sequence, "seq", 5) vmf:dump(mutators_sequence, "seq", 5)
@ -105,16 +87,48 @@ local function sort_mutators()
-- /LOG -- -- /LOG --
end end
local function mutator_can_be_enabled(mutator) -- Disables mutators that cannot be enabled right now
return (not Managers.state or not Managers.state.difficulty:get_difficulty()) or table.has_item(mutator:get_config().difficulties, Managers.state.difficulty:get_difficulty()) vmf.disable_impossible_mutators = function()
for _, mutator in pairs(mutators) do
if mutator:is_enabled() and not mutator:can_be_enabled() then
mutator:disable()
end
end
end end
--[[
PRIVATE METHODS
]]--
local addDice, removeDice = dofile("scripts/mods/vmf/modules/mutators/dice")
local set_lobby_data = dofile("scripts/mods/vmf/modules/mutators/info")
-- 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] = {}
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
vmf: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)
end
end
table.combine(mutators_sequence[mutator_name], enable_these_after)
end
-- 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()
addDice(config.dice) addDice(config.dice)
set_lobby_data() set_lobby_data()
end end
-- Called after mutator is disabled
local function on_disabled(mutator) local function on_disabled(mutator)
local config = mutator:get_config() local config = mutator:get_config()
removeDice(config.dice) removeDice(config.dice)
@ -130,14 +144,17 @@ local function set_mutator_state(mutator, state)
return return
end end
if state and not mutator_can_be_enabled(mutator) then if state == mutator:is_enabled() then
mutator:error("Can't enable mutator - incorrect difficulty") return
end
if state and not mutator:can_be_enabled() then
return return
end end
-- 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() vmf.sort_mutators()
end end
local disabled_mutators = {} local disabled_mutators = {}
@ -179,6 +196,11 @@ local function set_mutator_state(mutator, state)
print("---------") print("---------")
end end
--[[
MUTATOR'S OWN METHODS
]]--
-- Enables mutator (pcall for now) -- Enables mutator (pcall for now)
local function enable_mutator(self) local function enable_mutator(self)
vmf:pcall(function() set_mutator_state(self, true) end) vmf:pcall(function() set_mutator_state(self, true) end)
@ -189,15 +211,35 @@ local function disable_mutator(self)
vmf:pcall(function() set_mutator_state(self, false) end) vmf:pcall(function() set_mutator_state(self, false) end)
end end
-- Checks current difficulty and map selection screen settings to determine if a mutator can be enabled
local function can_be_enabled(self)
local mutator_difficulties = self:get_config().difficulties
local actual_difficulty = Managers.state and Managers.state.difficulty:get_difficulty()
local right_difficulty = not actual_difficulty or table.has_item(mutator_difficulties, actual_difficulty)
local ingame_ui = Managers.matchmaking and Managers.matchmaking.ingame_ui
local map_view = ingame_ui and ingame_ui.views and ingame_ui.views.map_view
local map_view_active = map_view and map_view.active
local right_unapplied_difficulty = false
if map_view_active then
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_difficulties, 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) local function get_config(self)
return mutators_config[self:get_name()] return mutators_config[self:get_name()]
end end
--[[
PUBLIC METHODS
]]--
-- Turns a mod into a mutator -- Turns a mod into a mutator
VMFMod.register_as_mutator = function(self, config) VMFMod.register_as_mutator = function(self, config)
if not config then config = {} end if not config then config = {} end
@ -220,6 +262,7 @@ VMFMod.register_as_mutator = function(self, config)
end end
end end
if _config.short_title == "" then _config.short_title = nil 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 if config.enable_before_these then
update_mutators_sequence(mod_name, config.enable_before_these) update_mutators_sequence(mod_name, config.enable_before_these)
@ -233,6 +276,7 @@ VMFMod.register_as_mutator = function(self, config)
self.enable = enable_mutator self.enable = enable_mutator
self.disable = disable_mutator self.disable = disable_mutator
self.can_be_enabled = can_be_enabled
self.get_config = get_config self.get_config = get_config
@ -242,19 +286,21 @@ VMFMod.register_as_mutator = function(self, config)
self:init_state(false) self:init_state(false)
end end
--[[ --[[
HOOKS HOOKS
]]-- ]]--
vmf:hook("DifficultyManager.set_difficulty", function(func, self, difficulty) vmf:hook("DifficultyManager.set_difficulty", function(func, self, difficulty)
for _, mutator in ipairs(mutators) do vmf.disable_impossible_mutators()
if mutator:is_enabled() and not mutator_can_be_enabled(mutator:get_config()) then
mutator:disable()
end
end
return func(self, difficulty) return func(self, difficulty)
end) end)
--[[
GUI
]]--
dofile("scripts/mods/vmf/modules/mutators/gui")
@ -283,7 +329,8 @@ local mutator_whatever = new_mod("mutator_whatever")
mutator555:register_as_mutator({ mutator555:register_as_mutator({
enable_after_these = { enable_after_these = {
"mutation" "mutation"
} },
title = "mutator555"
}) })
mutator555:create_options({}, true, "mutator555", "mutator555 description") mutator555:create_options({}, true, "mutator555", "mutator555 description")
mutator555.on_enabled = function() end mutator555.on_enabled = function() end
@ -298,7 +345,8 @@ deathwish:register_as_mutator({
}, },
difficulties = { difficulties = {
"hardest" "hardest"
} },
title = "deathwish"
}) })
deathwish:create_options({}, true, "deathwish", "deathwish description") deathwish:create_options({}, true, "deathwish", "deathwish description")
deathwish.on_enabled = function() deathwish.on_enabled = function()
@ -312,6 +360,11 @@ local breeds
mutation:register_as_mutator({ mutation:register_as_mutator({
enable_after_these = { enable_after_these = {
"deathwish" "deathwish"
},
title = "mutation",
dice = {
grims = 5,
tomes = 1
} }
}) })
mutation:create_options({}, true, "mutation", "mutation description") mutation:create_options({}, true, "mutation", "mutation description")
@ -333,13 +386,21 @@ end
mutator3:register_as_mutator({ mutator3:register_as_mutator({
enable_before_these = { enable_before_these = {
"mutator555" "mutator555"
},
title = "mutator3",
dice = {
grims = 5,
tomes = 1,
bonus = 22
} }
}) })
mutator3:create_options({}, true, "mutator3", "mutator3 description") mutator3:create_options({}, true, "mutator3", "mutator3 description")
mutator3.on_enabled = function() end mutator3.on_enabled = function() end
mutator3.on_disabled = function() end mutator3.on_disabled = function() end
mutator_whatever:register_as_mutator() mutator_whatever:register_as_mutator({
title = "mutator_whatever"
})
mutator_whatever:create_options({}, true, "mutator_whatever", "mutator_whatever description") mutator_whatever:create_options({}, true, "mutator_whatever", "mutator_whatever description")
mutator_whatever.on_enabled = function() end mutator_whatever.on_enabled = function() end
mutator_whatever.on_disabled = function() end mutator_whatever.on_disabled = function() end