diff --git a/vmf/scripts/mods/vmf/modules/ui/mutators/mutator_default_config.lua b/vmf/scripts/mods/vmf/modules/ui/mutators/mutator_default_config.lua index 425800f..ac250d1 100644 --- a/vmf/scripts/mods/vmf/modules/ui/mutators/mutator_default_config.lua +++ b/vmf/scripts/mods/vmf/modules/ui/mutators/mutator_default_config.lua @@ -1,26 +1,26 @@ return { - dice = { - grims = 0, - tomes = 0, - bonus = 0 - }, - short_title = "", - title_placement = "after", - difficulty_levels = { - "easy", - "normal", - "hard", - "harder", - "hardest", + dice = { + grims = 0, + tomes = 0, + bonus = 0 + }, + short_title = "", + title_placement = "after", + difficulty_levels = { + "easy", + "normal", + "hard", + "harder", + "hardest", - "survival_hard", - "survival_harder", - "survival_hardest" - }, - incompatible_with_all = false, - compatible_with_all = false, - incompatible_with = {}, - compatible_with = {}, - enable_before_these = {}, - enable_after_these = {} + "survival_hard", + "survival_harder", + "survival_hardest" + }, + incompatible_with_all = false, + compatible_with_all = false, + incompatible_with = {}, + compatible_with = {}, + enable_before_these = {}, + enable_after_these = {} } diff --git a/vmf/scripts/mods/vmf/modules/ui/mutators/mutator_dice.lua b/vmf/scripts/mods/vmf/modules/ui/mutators/mutator_dice.lua index 1ad18fb..851e31e 100644 --- a/vmf/scripts/mods/vmf/modules/ui/mutators/mutator_dice.lua +++ b/vmf/scripts/mods/vmf/modules/ui/mutators/mutator_dice.lua @@ -1,20 +1,20 @@ --[[ - Add additional dice to end game roll + Add additional dice to end game roll --]] local vmf = get_mod("VMF") -- List of all die types local missions = { - "bonus_dice_hidden_mission", - "tome_bonus_mission", - "grimoire_hidden_mission" + "bonus_dice_hidden_mission", + "tome_bonus_mission", + "grimoire_hidden_mission" } -- Amounts of additional dice to be added at level completion local num_dice_per_mission = { - bonus_dice_hidden_mission = 0, - tome_bonus_mission = 0, - grimoire_hidden_mission = 0 + bonus_dice_hidden_mission = 0, + tome_bonus_mission = 0, + grimoire_hidden_mission = 0 } -- #################################################################################################################### @@ -23,16 +23,16 @@ local num_dice_per_mission = { -- Adds/remove dice local function adjustDice(grims, tomes, bonus, multiplier) - if grims then - num_dice_per_mission.grimoire_hidden_mission = num_dice_per_mission.grimoire_hidden_mission + grims * multiplier - end - if tomes then - num_dice_per_mission.tome_bonus_mission = num_dice_per_mission.tome_bonus_mission + tomes * multiplier - end - if bonus then - num_dice_per_mission.bonus_dice_hidden_mission = num_dice_per_mission.bonus_dice_hidden_mission + bonus * - multiplier - end + if grims then + num_dice_per_mission.grimoire_hidden_mission = num_dice_per_mission.grimoire_hidden_mission + grims * multiplier + end + if tomes then + num_dice_per_mission.tome_bonus_mission = num_dice_per_mission.tome_bonus_mission + tomes * multiplier + end + if bonus then + num_dice_per_mission.bonus_dice_hidden_mission = num_dice_per_mission.bonus_dice_hidden_mission + bonus * + multiplier + end end -- #################################################################################################################### @@ -40,41 +40,41 @@ end -- #################################################################################################################### vmf:hook("GameModeManager.complete_level", function(func, ...) - local num_dice = 0 - local max_dice = 7 - local mission_system = Managers.state.entity:system("mission_system") - local active_mission = mission_system.active_missions + local num_dice = 0 + local max_dice = 7 + local mission_system = Managers.state.entity:system("mission_system") + local active_mission = mission_system.active_missions - -- Add additional dice - for _, mission in ipairs(missions) do - for _ = 1, num_dice_per_mission[mission] do - mission_system:request_mission(mission, nil, Network.peer_id()) - mission_system:update_mission(mission, true, nil, Network.peer_id(), nil, true) - end - end + -- Add additional dice + for _, mission in ipairs(missions) do + for _ = 1, num_dice_per_mission[mission] do + mission_system:request_mission(mission, nil, Network.peer_id()) + mission_system:update_mission(mission, true, nil, Network.peer_id(), nil, true) + end + end - -- Get total number of dice - for name, obj in pairs(active_mission) do - if table.contains(missions, name) then - num_dice = num_dice + obj.current_amount - end - end + -- Get total number of dice + for name, obj in pairs(active_mission) do + if table.contains(missions, name) then + num_dice = num_dice + obj.current_amount + end + end - -- Remove excess dice - for _, mission in ipairs(missions) do - if active_mission[mission] then - for _ = 1, active_mission[mission].current_amount do - if num_dice > max_dice then - mission_system:request_mission(mission, nil, Network.peer_id()) - mission_system:update_mission(mission, false, nil, Network.peer_id(), nil, true) - num_dice = num_dice - 1 - else break end - end - end - if num_dice <= max_dice then break end - end + -- Remove excess dice + for _, mission in ipairs(missions) do + if active_mission[mission] then + for _ = 1, active_mission[mission].current_amount do + if num_dice > max_dice then + mission_system:request_mission(mission, nil, Network.peer_id()) + mission_system:update_mission(mission, false, nil, Network.peer_id(), nil, true) + num_dice = num_dice - 1 + else break end + end + end + if num_dice <= max_dice then break end + end - func(...) + func(...) end) -- #################################################################################################################### @@ -82,11 +82,11 @@ end) -- #################################################################################################################### return { - addDice = function(dice) - adjustDice(dice.grims, dice.tomes, dice.bonus, 1) - end, + addDice = function(dice) + adjustDice(dice.grims, dice.tomes, dice.bonus, 1) + end, - removeDice = function(dice) - adjustDice(dice.grims, dice.tomes, dice.bonus, -1) - end + removeDice = function(dice) + adjustDice(dice.grims, dice.tomes, dice.bonus, -1) + end } diff --git a/vmf/scripts/mods/vmf/modules/ui/mutators/mutator_info.lua b/vmf/scripts/mods/vmf/modules/ui/mutators/mutator_info.lua index 43dfe0c..87af87f 100644 --- a/vmf/scripts/mods/vmf/modules/ui/mutators/mutator_info.lua +++ b/vmf/scripts/mods/vmf/modules/ui/mutators/mutator_info.lua @@ -1,5 +1,5 @@ --[[ - Notify players of enabled mutators via chat and tab menu + Notify players of enabled mutators via chat and tab menu --]] local vmf = get_mod("VMF") @@ -7,98 +7,98 @@ local _WERE_ENABLED_BEFORE = false -- Assembles a list of enabled mutators local function add_enabled_mutators_titles_to_string(separator, is_short) - local enabled_mutators = {} - for _, mutator in ipairs(vmf.mutators) do - if mutator:is_enabled() then - table.insert(enabled_mutators, mutator) - end - end - return vmf.add_mutator_titles_to_string(enabled_mutators, separator, is_short) + local enabled_mutators = {} + for _, mutator in ipairs(vmf.mutators) do + if mutator:is_enabled() then + table.insert(enabled_mutators, mutator) + end + end + return vmf.add_mutator_titles_to_string(enabled_mutators, separator, is_short) end -- Sets the lobby name local function set_lobby_data() - if not Managers.matchmaking or - not Managers.matchmaking.lobby or - not Managers.matchmaking.lobby.set_lobby_data or - not Managers.matchmaking.lobby.get_stored_lobby_data - then - return - end + if not Managers.matchmaking or + not Managers.matchmaking.lobby or + not Managers.matchmaking.lobby.set_lobby_data or + not Managers.matchmaking.lobby.get_stored_lobby_data + then + return + end - local name = add_enabled_mutators_titles_to_string(" ", true) -- @TODO: change separator? + local name = add_enabled_mutators_titles_to_string(" ", true) -- @TODO: change separator? - local default_name = LobbyAux.get_unique_server_name() - if string.len(name) > 0 then - name = "||" .. name .. "|| " .. default_name - else - name = default_name - end + local default_name = LobbyAux.get_unique_server_name() + if string.len(name) > 0 then + name = "||" .. name .. "|| " .. default_name + else + name = default_name + end - local lobby_data = Managers.matchmaking.lobby:get_stored_lobby_data() - lobby_data.unique_server_name = name + local lobby_data = Managers.matchmaking.lobby:get_stored_lobby_data() + lobby_data.unique_server_name = name - Managers.matchmaking.lobby:set_lobby_data(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 - peer_id = string.sub(peer_id, 1 + tonumber(tostring(string.find(peer_id, "-")))) - end - peer_id = string.sub(peer_id, 2) - peer_id = string.reverse(peer_id) - peer_id = string.sub(peer_id, 2) - peer_id = string.reverse(peer_id) + local peer_id = tostring(client_cookie) + for _ = 1, 3 do + peer_id = string.sub(peer_id, 1 + tonumber(tostring(string.find(peer_id, "-")))) + end + peer_id = string.sub(peer_id, 2) + peer_id = string.reverse(peer_id) + peer_id = string.sub(peer_id, 2) + peer_id = string.reverse(peer_id) - vmf:echo("PEER ID FROM COOKIE #1: [" .. tostring(peer_id) .. "]") - vmf:echo("PEER ID FROM COOKIE #2: [" .. tostring(string.match(client_cookie, "%[(%a+)%]")) .. "]") + vmf:echo("PEER ID FROM COOKIE #1: [" .. tostring(peer_id) .. "]") + vmf:echo("PEER ID FROM COOKIE #2: [" .. tostring(string.match(client_cookie, "%[(%a+)%]")) .. "]") - return peer_id + return peer_id end -- Append difficulty name with enabled mutators' titles 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 difficulty_settings = Managers.state.difficulty:get_difficulty_settings() + local difficulty_name = difficulty_settings.display_name - 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 -- it can be "" if player is in the inn with no selected level - name = name .. " (" .. localized_difficulty_name .. ")" - end + 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 -- it can be "" if player is in the inn with no selected level + name = name .. " (" .. localized_difficulty_name .. ")" + end - self.set_difficulty_name(self, name) + self.set_difficulty_name(self, name) - self.current_difficulty_name = difficulty_name + self.current_difficulty_name = difficulty_name end) -- Notify everybody about enabled/disabled mutators when Play button is pressed on the map screen vmf:hook("MatchmakingStateHostGame.host_game", function(func, ...) - func(...) - set_lobby_data() - local names = add_enabled_mutators_titles_to_string(", ") - if names ~= "" then - vmf:chat_broadcast(vmf:localize("broadcast_enabled_mutators") .. ": " .. names) - _WERE_ENABLED_BEFORE = true - elseif _WERE_ENABLED_BEFORE then - vmf:chat_broadcast(vmf:localize("broadcast_all_disabled")) - _WERE_ENABLED_BEFORE = false - end + func(...) + set_lobby_data() + local names = add_enabled_mutators_titles_to_string(", ") + if names ~= "" then + vmf:chat_broadcast(vmf:localize("broadcast_enabled_mutators") .. ": " .. names) + _WERE_ENABLED_BEFORE = true + elseif _WERE_ENABLED_BEFORE then + 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 vmf:hook("MatchmakingManager.rpc_matchmaking_request_join_lobby", function(func, self, sender, client_cookie, ...) - local name = add_enabled_mutators_titles_to_string(", ") - if name ~= "" then - 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, ...) + local name = add_enabled_mutators_titles_to_string(", ") + if name ~= "" then + 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, ...) end) return set_lobby_data \ No newline at end of file diff --git a/vmf/scripts/mods/vmf/modules/ui/mutators/mutator_manager.lua b/vmf/scripts/mods/vmf/modules/ui/mutators/mutator_manager.lua index d620bcb..f4643bb 100644 --- a/vmf/scripts/mods/vmf/modules/ui/mutators/mutator_manager.lua +++ b/vmf/scripts/mods/vmf/modules/ui/mutators/mutator_manager.lua @@ -1,5 +1,5 @@ --[[ - Manages everything related to mutators: loading order, enabling/disabling process, giving extra dice etc. + Manages everything related to mutators: loading order, enabling/disabling process, giving extra dice etc. --]] local vmf = get_mod("VMF") @@ -8,12 +8,12 @@ local _MUTATORS = {} -- This lists mutators and which ones should be enabled after them local _MUTATORS_SEQUENCE = { - --[[ - this_mutator = { - "will be enabled", - "before these ones" - } - ]]-- + --[[ + this_mutator = { + "will be enabled", + "before these ones" + } + ]]-- } -- So we don't sort after each one is added @@ -36,149 +36,149 @@ local _ENABLED_MUTATORS = vmf:persistent_table("enabled_mutators") -- #################################################################################################################### local function get_index(tbl, o) - for i, v in ipairs(tbl) do - if o == v then - return i - end - end - return nil + for i, v in ipairs(tbl) do + if o == v then + return i + end + end + return nil 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(get_index(_MUTATORS, mutator)) .. ")") + local config = mutator:get_config() + _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 + _ENABLED_MUTATORS[mutator:get_name()] = true end -- Called after mutator is disabled local function on_disabled(mutator, initial_call) - local config = mutator:get_config() + local config = mutator:get_config() - -- All mutators run on_disabled on initial call, so there's no need to remove dice and set lobby data - if not initial_call then - _DICE_MANAGER.removeDice(config.dice) - _SET_LOBBY_DATA() - end - print("[MUTATORS] Disabled " .. mutator:get_name() .. " (" .. tostring(get_index(_MUTATORS, mutator)) .. ")") + -- All mutators run on_disabled on initial call, so there's no need to remove dice and set lobby data + if not initial_call then + _DICE_MANAGER.removeDice(config.dice) + _SET_LOBBY_DATA() + end + print("[MUTATORS] Disabled " .. mutator:get_name() .. " (" .. tostring(get_index(_MUTATORS, mutator)) .. ")") - _ENABLED_MUTATORS[mutator:get_name()] = nil + _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 local function player_is_server() - local player = Managers.player - local state = Managers.state - return not player or player.is_server or not state or state.game_mode == nil + local player = Managers.player + local state = Managers.state + return not player or player.is_server or not state or state.game_mode == nil end -- Sorts mutators in order they should be enabled local function sort_mutators() - if _MUTATORS_SORTED then return end + if _MUTATORS_SORTED then return end - --[[ - -- LOG -- - vmf:dump(_MUTATORS_SEQUENCE, "seq", 5) - for i, v in ipairs(mutators) do - print(i, v:get_name()) - end - print("-----------") - -- /LOG -- - --]] + --[[ + -- LOG -- + vmf:dump(_MUTATORS_SEQUENCE, "seq", 5) + for i, v in ipairs(mutators) do + print(i, v:get_name()) + end + print("-----------") + -- /LOG -- + --]] - -- 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] - local mutator_name = mutator:get_name() - local enable_these_after = _MUTATORS_SEQUENCE[mutator_name] or {} + -- 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] + local mutator_name = mutator:get_name() + 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] + -- 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] - -- Moving it after the current one if it is to be enabled after it - if table.contains(enable_these_after, other_mutator:get_name()) then - table.remove(_MUTATORS, j) - table.insert(_MUTATORS, i, other_mutator) + -- Moving it after the current one if it is to be enabled after it + if table.contains(enable_these_after, other_mutator:get_name()) then + table.remove(_MUTATORS, j) + table.insert(_MUTATORS, i, other_mutator) - -- This will shift the current mutator back, so adjust the index - i = i - 1 - end - j = j - 1 - end + -- This will shift the current mutator back, so adjust the index + i = i - 1 + end + j = j - 1 + end - i = i + 1 - end - _MUTATORS_SORTED = true + i = i + 1 + end + _MUTATORS_SORTED = true - --[[ - -- LOG -- - print("[MUTATORS] Sorted") - for k, v in ipairs(_MUTATORS) do - print(" ", k, v:get_name()) - end - -- /LOG -- - --]] + --[[ + -- LOG -- + print("[MUTATORS] Sorted") + for k, v in ipairs(_MUTATORS) do + print(" ", k, v:get_name()) + end + -- /LOG -- + --]] end -- Check if a mutator can be enabled local function mutator_can_be_enabled(mutator) - -- If conflicting mutators are enabled + -- If conflicting mutators are enabled local mutator_compatibility_config = mutator:get_config().compatibility local is_mostly_compatible = mutator_compatibility_config.is_mostly_compatible local except = mutator_compatibility_config.except - for _, other_mutator in ipairs(_MUTATORS) do - if other_mutator:is_enabled() and other_mutator ~= mutator and - (is_mostly_compatible and except[other_mutator] or not is_mostly_compatible and not except[other_mutator]) then - return false - end - end + for _, other_mutator in ipairs(_MUTATORS) do + if other_mutator:is_enabled() and other_mutator ~= mutator and + (is_mostly_compatible and except[other_mutator] or not is_mostly_compatible and not except[other_mutator]) then + return false + end + end - -- If player is no longer the server - if not player_is_server() then - return false - end + -- If player is no longer the server + if not player_is_server() then + return false + end - -- If conflicting difficulty is set (if no difficulty is set, all mutators are allowed) - local actual_difficulty = Managers.state and Managers.state.difficulty:get_difficulty() - local compatible_difficulties = mutator_compatibility_config.compatible_difficulties - return not actual_difficulty or compatible_difficulties[actual_difficulty] + -- If conflicting difficulty is set (if no difficulty is set, all mutators are allowed) + local actual_difficulty = Managers.state and Managers.state.difficulty:get_difficulty() + local compatible_difficulties = mutator_compatibility_config.compatible_difficulties + return not actual_difficulty or compatible_difficulties[actual_difficulty] end -- Disables mutators that cannot be enabled right now local function disable_impossible_mutators(is_broadcast, reason_text_id) - local disabled_mutators = {} - for i = #_MUTATORS, 1, -1 do - local mutator = _MUTATORS[i] - if mutator:is_enabled() and not 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 then - local disabled_mutators_text_id = is_broadcast and "broadcast_disabled_mutators" or "local_disabled_mutators" - local message = vmf:localize(disabled_mutators_text_id) .. " " .. vmf:localize(reason_text_id) .. ":" - message = message .. " " .. vmf.add_mutator_titles_to_string(disabled_mutators, ", ", false) - if is_broadcast then - vmf:chat_broadcast(message) - else - vmf:echo(message) - end - end + local disabled_mutators = {} + for i = #_MUTATORS, 1, -1 do + local mutator = _MUTATORS[i] + if mutator:is_enabled() and not 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 then + local disabled_mutators_text_id = is_broadcast and "broadcast_disabled_mutators" or "local_disabled_mutators" + local message = vmf:localize(disabled_mutators_text_id) .. " " .. vmf:localize(reason_text_id) .. ":" + message = message .. " " .. vmf.add_mutator_titles_to_string(disabled_mutators, ", ", false) + if is_broadcast then + vmf:chat_broadcast(message) + else + vmf:echo(message) + end + end end @@ -188,80 +188,80 @@ 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) - local raw_config = mutator:get_config().raw_config - local enable_before_these = raw_config.enable_before_these - local enable_after_these = raw_config.enable_after_these - local mutator_name = mutator:get_name() + local raw_config = mutator:get_config().raw_config + local enable_before_these = raw_config.enable_before_these + local enable_after_these = raw_config.enable_after_these + local mutator_name = mutator:get_name() - if enable_before_these then - _MUTATORS_SEQUENCE[mutator_name] = _MUTATORS_SEQUENCE[mutator_name] or {} + if enable_before_these then + _MUTATORS_SEQUENCE[mutator_name] = _MUTATORS_SEQUENCE[mutator_name] or {} - for _, other_mutator_name in ipairs(enable_before_these) do - 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 + for _, other_mutator_name in ipairs(enable_before_these) do + 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 - end - if enable_after_these then - for _, other_mutator_name in ipairs(enable_after_these) do - _MUTATORS_SEQUENCE[other_mutator_name] = _MUTATORS_SEQUENCE[other_mutator_name] or {} + end + if enable_after_these then + for _, other_mutator_name in ipairs(enable_after_these) do + _MUTATORS_SEQUENCE[other_mutator_name] = _MUTATORS_SEQUENCE[other_mutator_name] or {} - if _MUTATORS_SEQUENCE[mutator_name] and table.contains(_MUTATORS_SEQUENCE[mutator_name], other_mutator_name) then - 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[other_mutator_name], mutator_name) then - table.insert(_MUTATORS_SEQUENCE[other_mutator_name], mutator_name) - end - end - end + if _MUTATORS_SEQUENCE[mutator_name] and table.contains(_MUTATORS_SEQUENCE[mutator_name], other_mutator_name) then + vmf:error("(mutators): Mutators '%s' and '%s' are both set to load after each other.", mutator_name, + other_mutator_name) + elseif not table.contains(_MUTATORS_SEQUENCE[other_mutator_name], mutator_name) then + table.insert(_MUTATORS_SEQUENCE[other_mutator_name], mutator_name) + end + end + end end -- Uses raw_config to determine if mutators are compatible both ways local function is_compatible(mutator, other_mutator) - local raw_config = mutator:get_config().raw_config - local other_raw_config = other_mutator:get_config().raw_config + local raw_config = mutator:get_config().raw_config + local other_raw_config = other_mutator:get_config().raw_config - local mutator_name = mutator:get_name() - local other_mutator_name = other_mutator:get_name() + local mutator_name = mutator:get_name() + local other_mutator_name = other_mutator:get_name() - local incompatible_specifically = ( - #raw_config.incompatible_with > 0 and ( - table.contains(raw_config.incompatible_with, other_mutator_name) - ) or - #other_raw_config.incompatible_with > 0 and ( - table.contains(other_raw_config.incompatible_with, mutator_name) - ) - ) + local incompatible_specifically = ( + #raw_config.incompatible_with > 0 and ( + table.contains(raw_config.incompatible_with, other_mutator_name) + ) or + #other_raw_config.incompatible_with > 0 and ( + table.contains(other_raw_config.incompatible_with, mutator_name) + ) + ) - local compatible_specifically = ( - #raw_config.compatible_with > 0 and ( - table.contains(raw_config.compatible_with, other_mutator_name) - ) or - #other_raw_config.compatible_with > 0 and ( - table.contains(other_raw_config.compatible_with, mutator_name) - ) - ) + local compatible_specifically = ( + #raw_config.compatible_with > 0 and ( + table.contains(raw_config.compatible_with, other_mutator_name) + ) or + #other_raw_config.compatible_with > 0 and ( + table.contains(other_raw_config.compatible_with, mutator_name) + ) + ) - local compatible - if incompatible_specifically then - compatible = false - elseif compatible_specifically then - compatible = true - elseif raw_config.compatible_with_all or other_raw_config.compatible_with_all then - compatible = true - elseif raw_config.incompatible_with_all or other_raw_config.incompatible_with_all then - compatible = false - else - compatible = true - end + local compatible + if incompatible_specifically then + compatible = false + elseif compatible_specifically then + compatible = true + elseif raw_config.compatible_with_all or other_raw_config.compatible_with_all then + compatible = true + elseif raw_config.incompatible_with_all or other_raw_config.incompatible_with_all then + compatible = false + else + compatible = true + end - return compatible + return compatible end @@ -272,88 +272,88 @@ end -- Also, converts given difficulties compatibility to optimized form. local function update_compatibility(mutator) - -- Create default 'compatibility' entry - local config = mutator:get_config() - config.compatibility = {} - local compatibility = config.compatibility + -- Create default 'compatibility' entry + local config = mutator:get_config() + config.compatibility = {} + local compatibility = config.compatibility - -- Compatibility with other mods - compatibility.is_mostly_compatible = not config.raw_config.incompatible_with_all - compatibility.except = {} + -- Compatibility with other mods + compatibility.is_mostly_compatible = not config.raw_config.incompatible_with_all + compatibility.except = {} - local is_mostly_compatible = compatibility.is_mostly_compatible - local except = compatibility.except + local is_mostly_compatible = compatibility.is_mostly_compatible + local except = compatibility.except - for _, other_mutator in ipairs(_MUTATORS) do + for _, other_mutator in ipairs(_MUTATORS) do - local other_config = other_mutator:get_config() - local other_mostly_compatible = other_config.compatibility.is_mostly_compatible - local other_except = other_config.compatibility.except + local other_config = other_mutator:get_config() + local other_mostly_compatible = other_config.compatibility.is_mostly_compatible + local other_except = other_config.compatibility.except - if is_compatible(mutator, other_mutator) then - if not is_mostly_compatible then except[other_mutator] = true end - if not other_mostly_compatible then other_except[mutator] = true end - else - if is_mostly_compatible then except[other_mutator] = true end - if other_mostly_compatible then other_except[mutator] = true end - end - end + if is_compatible(mutator, other_mutator) then + if not is_mostly_compatible then except[other_mutator] = true end + if not other_mostly_compatible then other_except[mutator] = true end + else + if is_mostly_compatible then except[other_mutator] = true end + if other_mostly_compatible then other_except[mutator] = true end + end + end - -- Compatibility with current difficulty (This part works only for VT1. Will see what to do with VT2 later.) - compatibility.compatible_difficulties = { - easy = false, - normal = false, - hard = false, - harder = false, - hardest = false, - survival_hard = false, - survival_harder = false, - survival_hardest = false, - } - local compatible_difficulties = compatibility.compatible_difficulties - local compatible_difficulties_number = 0 - for _, difficulty_key in ipairs(config.raw_config.difficulty_levels) do - if type(compatible_difficulties[difficulty_key]) ~= "nil" then - compatible_difficulties[difficulty_key] = true - compatible_difficulties_number = compatible_difficulties_number + 1 - end - end - compatibility.compatible_difficulties_number = compatible_difficulties_number + -- Compatibility with current difficulty (This part works only for VT1. Will see what to do with VT2 later.) + compatibility.compatible_difficulties = { + easy = false, + normal = false, + hard = false, + harder = false, + hardest = false, + survival_hard = false, + survival_harder = false, + survival_hardest = false, + } + local compatible_difficulties = compatibility.compatible_difficulties + local compatible_difficulties_number = 0 + for _, difficulty_key in ipairs(config.raw_config.difficulty_levels) do + if type(compatible_difficulties[difficulty_key]) ~= "nil" then + compatible_difficulties[difficulty_key] = true + compatible_difficulties_number = compatible_difficulties_number + 1 + end + end + compatibility.compatible_difficulties_number = compatible_difficulties_number end -- Converts user-made config to form used by mutators module local function initialize_mutator_config(mutator, _raw_config) - -- Shapes raw config, so it will have only elements that are intended to be in there. - -- Also, adds missing elements with their default values. - local raw_config = table.clone(_DEFAULT_CONFIG) - if type(_raw_config) == "table" then - for k, v in pairs(raw_config) do - if type(_raw_config[k]) == type(v) then - raw_config[k] = _raw_config[k] - end - end - end - if raw_config.short_title == "" then raw_config.short_title = nil end + -- Shapes raw config, so it will have only elements that are intended to be in there. + -- Also, adds missing elements with their default values. + local raw_config = table.clone(_DEFAULT_CONFIG) + if type(_raw_config) == "table" then + for k, v in pairs(raw_config) do + if type(_raw_config[k]) == type(v) then + raw_config[k] = _raw_config[k] + end + end + end + if raw_config.short_title == "" then raw_config.short_title = nil end - mutator._data.config = {} + mutator._data.config = {} - local config = mutator._data.config + local config = mutator._data.config - config.dice = raw_config.dice - config.short_title = raw_config.short_title - config.title_placement = raw_config.title_placement + config.dice = raw_config.dice + config.short_title = raw_config.short_title + config.title_placement = raw_config.title_placement - -- 'raw_config' will be used in 2 following functions to fill compatibility and mutator sequence tables. - -- It will be deleted after all mods are loaded and those 2 tables are formed. - config.raw_config = raw_config + -- 'raw_config' will be used in 2 following functions to fill compatibility and mutator sequence tables. + -- It will be deleted after all mods are loaded and those 2 tables are formed. + config.raw_config = raw_config - -- config.compatibility - update_compatibility(mutator) + -- config.compatibility + update_compatibility(mutator) - -- _MUTATORS_SEQUENCE - update_mutators_sequence(mutator) + -- _MUTATORS_SEQUENCE + update_mutators_sequence(mutator) end -- #################################################################################################################### @@ -366,125 +366,125 @@ vmf.mutators = _MUTATORS -- Appends, prepends and replaces the string with mutator titles function vmf.add_mutator_titles_to_string(mutators, separator, is_short) - if #mutators == 0 then - return "" - end + if #mutators == 0 then + return "" + end - local before = nil - local after = nil - local replace = nil + local before = nil + local after = nil + local replace = nil - for _, mutator in ipairs(mutators) do - local config = mutator:get_config() - local added_name = (is_short and config.short_title or mutator:get_readable_name()) - if config.title_placement == "before" then - if before then - before = added_name .. separator .. before - else - before = added_name - end - elseif config.title_placement == "replace" then --@TODO: get rid of replace? Or maybe title_placement as a whole? - if replace then - replace = replace .. separator .. added_name - else - replace = added_name - end - else - if after then - after = after .. separator .. added_name - else - after = added_name - end - end - end - local new_str = replace or "" - if before then - new_str = before .. (string.len(new_str) > 0 and separator or "") .. new_str - end - if after then - new_str = new_str .. (string.len(new_str) > 0 and separator or "") .. after - end - return new_str + for _, mutator in ipairs(mutators) do + local config = mutator:get_config() + local added_name = (is_short and config.short_title or mutator:get_readable_name()) + if config.title_placement == "before" then + if before then + before = added_name .. separator .. before + else + before = added_name + end + elseif config.title_placement == "replace" then --@TODO: get rid of replace? Or maybe title_placement as a whole? + if replace then + replace = replace .. separator .. added_name + else + replace = added_name + end + else + if after then + after = after .. separator .. added_name + else + after = added_name + end + end + end + local new_str = replace or "" + if before then + new_str = before .. (string.len(new_str) > 0 and separator or "") .. new_str + end + if after then + new_str = new_str .. (string.len(new_str) > 0 and separator or "") .. after + end + return new_str end -- Turns a mod into a mutator function vmf.register_mod_as_mutator(mod, raw_config) - initialize_mutator_config(mod, raw_config) + initialize_mutator_config(mod, raw_config) - table.insert(_MUTATORS, mod) + table.insert(_MUTATORS, mod) - _MUTATORS_SORTED = false + _MUTATORS_SORTED = false end -- Enables/disables mutator while preserving the sequence in which they were enabled function vmf.set_mutator_state(mutator, state, initial_call) - -- Sort mutators if this is the first call - if not _MUTATORS_SORTED then - sort_mutators() - end + -- 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 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 + 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, initial_call) - 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, initial_call) + 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 + -- 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 -- Checks if player is still hosting (on update) function vmf.check_mutators_state() - if not _ALL_MUTATORS_DISABLED and not player_is_server() then - disable_impossible_mutators(false, "disabled_reason_not_server") - _ALL_MUTATORS_DISABLED = true - end + if not _ALL_MUTATORS_DISABLED and not player_is_server() then + disable_impossible_mutators(false, "disabled_reason_not_server") + _ALL_MUTATORS_DISABLED = true + end end -- Is 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] + return _ENABLED_MUTATORS[mutator_name] end -- Removes all raw_configs which won't be used anymore function vmf.mutators_delete_raw_config() - for _, mutator in ipairs(_MUTATORS) do - mutator:get_config().raw_config = nil - end + for _, mutator in ipairs(_MUTATORS) do + mutator:get_config().raw_config = nil + end end -- #################################################################################################################### @@ -492,8 +492,8 @@ end -- #################################################################################################################### vmf:hook("DifficultyManager.set_difficulty", function(func, ...) - func(...) - disable_impossible_mutators(true, "disabled_reason_difficulty_change") + func(...) + disable_impossible_mutators(true, "disabled_reason_difficulty_change") end) -- #################################################################################################################### diff --git a/vmf/scripts/mods/vmf/modules/ui/mutators/mutators_gui.lua b/vmf/scripts/mods/vmf/modules/ui/mutators/mutators_gui.lua index 463707b..7d9f250 100644 --- a/vmf/scripts/mods/vmf/modules/ui/mutators/mutators_gui.lua +++ b/vmf/scripts/mods/vmf/modules/ui/mutators/mutators_gui.lua @@ -74,11 +74,11 @@ local function change_map_view_look(map_view, is_vmf_look) if is_vmf_look then map_view.ui_scenegraph.settings_button.position[1] = -50 - map_view.ui_scenegraph.friends_button.position[1] = 50 + map_view.ui_scenegraph.friends_button.position[1] = 50 map_view.ui_scenegraph.lobby_button.position[1] = 150 else map_view.ui_scenegraph.settings_button.position[1] = -100 - map_view.ui_scenegraph.friends_button.position[1] = 0 + map_view.ui_scenegraph.friends_button.position[1] = 0 map_view.ui_scenegraph.lobby_button.position[1] = 100 end end @@ -394,11 +394,11 @@ vmf:hook("MapView.update", function (func, self, dt, t) -- Parse currently selected difficulty in the map_view local difficulty_data = self.selected_level_index and self:get_difficulty_data(self.selected_level_index) - local difficulty_layout = difficulty_data and difficulty_data[self.selected_difficulty_stepper_index] - _SELECTED_DIFFICULTY_KEY = difficulty_layout and difficulty_layout.key + local difficulty_layout = difficulty_data and difficulty_data[self.selected_difficulty_stepper_index] + _SELECTED_DIFFICULTY_KEY = difficulty_layout and difficulty_layout.key update_mutators_ui(self, dt) - end + end end) -- #################################################################################################################### diff --git a/vmf/scripts/mods/vmf/modules/ui/mutators/mutators_gui_definitions.lua b/vmf/scripts/mods/vmf/modules/ui/mutators/mutators_gui_definitions.lua index 14f72fb..84f732e 100644 --- a/vmf/scripts/mods/vmf/modules/ui/mutators/mutators_gui_definitions.lua +++ b/vmf/scripts/mods/vmf/modules/ui/mutators/mutators_gui_definitions.lua @@ -3,8 +3,8 @@ local vmf = get_mod("VMF") local scenegraph_definition = { - sg_root = { - size = {1920, 1080}, + sg_root = { + size = {1920, 1080}, position = {0, 0, UILayer.default}, is_root = true, @@ -228,12 +228,12 @@ local function create_mutator_widget(mutator, offset_function_callback) { pass_type = "texture", - style_id = "hover_texture", + style_id = "hover_texture", texture_id = "hover_texture", - content_check_function = function (content) - return content.can_be_enabled and content.highlight_hotspot.is_hover - end - }, + content_check_function = function (content) + return content.can_be_enabled and content.highlight_hotspot.is_hover + end + }, { pass_type = "text", @@ -243,8 +243,8 @@ local function create_mutator_widget(mutator, offset_function_callback) { pass_type = "texture", - style_id = "checkbox_style", - texture_id = "checkbox_texture" + style_id = "checkbox_style", + texture_id = "checkbox_texture" }, { pass_type = "tooltip_text", @@ -292,14 +292,14 @@ local function create_mutator_widget(mutator, offset_function_callback) }, hover_texture = { - size = {370, 32}, - offset = {0, 0, 1} - }, + size = {370, 32}, + offset = {0, 0, 1} + }, checkbox_style = { - size = {20, 20}, - offset = {340, 6, 2}, - color = {255, 255, 255, 255} + size = {20, 20}, + offset = {340, 6, 2}, + color = {255, 255, 255, 255} }, tooltip_text = {