diff --git a/game/engines/default/engine/Module.lua b/game/engines/default/engine/Module.lua index 778112424a29b3ba897b837e844c6a9936e6b22a..9a854f028fe07d8ee6e78822fe26477f88232e4c 100644 --- a/game/engines/default/engine/Module.lua +++ b/game/engines/default/engine/Module.lua @@ -254,7 +254,7 @@ function _M:listVaultSavesForCurrent() end --- List all available addons -function _M:loadAddons(mod) +function _M:listAddons(mod, ignore_compat) local adds = {} local load = function(dir, teaa) local add_def = loadfile(dir.."/init.lua") @@ -263,9 +263,11 @@ function _M:loadAddons(mod) setfenv(add_def, add) add_def() - if engine.version_string(add.version) == engine.version_string(mod.version) and add.for_module == mod.short_name then + if (ignore_compat or engine.version_string(add.version) == engine.version_string(mod.version)) and add.for_module == mod.short_name then add.dir = dir add.teaa = teaa + add.natural_compatible = engine.version_string(add.version) == engine.version_string(mod.version) + add.version_txt = ("%d.%d.%d"):format(add.version[1], add.version[2], add.version[3]) adds[#adds+1] = add end end @@ -287,6 +289,28 @@ function _M:loadAddons(mod) end end table.sort(adds, function(a, b) return a.weight < b.weight end) + return adds +end + +function _M:loadAddons(mod) + local adds = self:listAddons(mod, true) + + -- Filter based on settings + for i = #adds, 1, -1 do + local add = adds[i] + if config.settings.addons[add.for_module] and config.settings.addons[add.for_module][add.short_name] ~= nil then + -- Forbidden by config + if config.settings.addons[add.for_module][add.short_name] == false then + print("Removing addon"..add.short_name..": not allowed by config") + table.remove(adds, i) + end + else + -- Forbidden by version + if not add.natural_compatible then + table.remove(adds, i) + end + end + end mod.addons = {} for i, add in ipairs(adds) do diff --git a/game/engines/default/engine/init.lua b/game/engines/default/engine/init.lua index 114e4a8a6aa39ef35976cee13caec33c945eba42..c16dfd24d5a6acd4b4cd8a213718ec12f3d9c945 100644 --- a/game/engines/default/engine/init.lua +++ b/game/engines/default/engine/init.lua @@ -60,6 +60,7 @@ display_fps = 30 gamma_correction = 120 mouse_move = true chat.filter = {} +addons = {} ]] for i, file in ipairs(fs.list("/settings/")) do if file:find(".cfg$") then diff --git a/game/engines/default/modules/boot/dialogs/Addons.lua b/game/engines/default/modules/boot/dialogs/Addons.lua new file mode 100644 index 0000000000000000000000000000000000000000..8f6891e9ab8197c8c33eaa10178672beb28b5d85 --- /dev/null +++ b/game/engines/default/modules/boot/dialogs/Addons.lua @@ -0,0 +1,143 @@ +-- TE4 - T-Engine 4 +-- Copyright (C) 2009, 2010, 2011 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +require "engine.class" +local Module = require "engine.Module" +local Dialog = require "engine.ui.Dialog" +local ListColumns = require "engine.ui.ListColumns" +local Textzone = require "engine.ui.Textzone" +local Separator = require "engine.ui.Separator" +local Checkbox = require "engine.ui.Checkbox" +local Button = require "engine.ui.Button" + +module(..., package.seeall, class.inherit(Dialog)) + +function _M:init() + Dialog.init(self, "Configure Addons", game.w * 0.8, game.h * 0.8) + + self.c_compat = Checkbox.new{default=false, width=math.floor(self.iw / 3 - 40), title="Show incompatible", on_change=function() self:switch() end} + + self:generateList() + + self.c_list = ListColumns.new{width=math.floor(self.iw / 3 - 10), height=self.ih - 10 - self.c_compat.h, scrollbar=true, columns={ + {name="Game Module", width=80, display_prop="name"}, + {name="Version", width=20, display_prop="version_txt"}, + }, list=self.list, fct=function(item) end, select=function(item, sel) self:select(item) end} + + self.c_adds = ListColumns.new{width=math.floor(self.iw * 2 / 3 - 10), height=self.ih - 10 - self.c_compat.h, scrollbar=true, columns={ + {name="Addon", width=60, display_prop="long_name"}, + {name="Active", width=20, display_prop=function(item) + if config.settings.addons[item.for_module] and config.settings.addons[item.for_module][item.short_name] ~= nil then + return (config.settings.addons[item.for_module][item.short_name] and "#LIGHT_GREEN#Manual: Active" or "#LIGHT_RED#Manual: Disabled"):toTString() + else + return (item.natural_compatible and "#LIGHT_GREEN#Auto: Active" or "#LIGHT_RED#Auto: Incompatible"):toTString() + end + end}, + {name="Version", width=20, display_prop="version_txt"}, + }, list={}, fct=function(item) self:switchAddon(item) end, select=function(item, sel) self:select(item) end} + + self:loadUI{ + {left=0, top=0, ui=self.c_list}, + {right=0, top=0, ui=self.c_adds}, + {left=0, bottom=0, ui=self.c_compat}, + {left=self.c_list.w + 5, top=5, ui=Separator.new{dir="horizontal", size=self.ih - 10}}, + } + self:setFocus(self.c_list) + self:setupUI() + + self:select(self.list[1]) + + self.key:addBinds{ + EXIT = function() game:unregisterDialog(self) end, + } +end + +function _M:on_register() + if #self.list == 1 then + game:unregisterDialog(self) + self.list[1]:fct() + end +end + +function _M:select(item) + if item and item.adds and self.c_adds then + self.c_adds.list = item.adds + self.c_adds:generate() + end +end + +function _M:switchAddon(item) + config.settings.addons[item.for_module] = config.settings.addons[item.for_module] or {} + local v = config.settings.addons[item.for_module][item.short_name] + if v == nil then config.settings.addons[item.for_module][item.short_name] = true + elseif v == true then config.settings.addons[item.for_module][item.short_name] = false + elseif v == false then config.settings.addons[item.for_module][item.short_name] = nil + end + self.c_adds:drawItem(item) + + local lines = {} + lines[#lines+1] = ("addons = {}"):format(w) + for mod, adds in pairs(config.settings.addons) do + lines[#lines+1] = ("addons[%q] = {}"):format(mod) + for k, v in pairs(adds) do + lines[#lines+1] = ("addons[%q][%q] = %s"):format(mod, k, v and "true" or "false") + end + end + + game:saveSettings("addons", table.concat(lines, "\n")) +end + +function _M:generateList() + local list = Module:listModules(self.c_compat.checked) + self.list = {} + for i = 1, #list do + for j, mod in ipairs(list[i].versions) do + if j > 1 then break end + if not mod.is_boot and (not mod.show_only_on_cheat or config.settings.cheat) then + mod.name = tstring{{"font","bold"}, {"color","GOLD"}, mod.name, {"font","normal"}} + mod.fct = function(mod) + if mod.no_get_name then + Module:instanciate(mod, "player", true, false) + else + game:registerDialog(require('engine.dialogs.GetText').new("Enter your character's name", "Name", 2, 25, function(text) + local savename = text:gsub("[^a-zA-Z0-9_-.]", "_") + if fs.exists(("/%s/save/%s/game.teag"):format(mod.short_name, savename)) then + Dialog:yesnoPopup("Overwrite character?", "There is already a character with this name, do you want to overwrite it?", function(ret) + if not ret then Module:instanciate(mod, text, true) end + end, "No", "Yes") + else + Module:instanciate(mod, text, true) + end + end)) + end + end + mod.version_txt = ("%d.%d.%d"):format(mod.version[1], mod.version[2], mod.version[3]) + mod.adds = Module:listAddons(mod, true) + + table.insert(self.list, mod) + end + end + end +end + +function _M:switch() + self:generateList() + self.c_list.list = self.list + self.c_list:generate() +end diff --git a/game/engines/default/modules/boot/dialogs/MainMenu.lua b/game/engines/default/modules/boot/dialogs/MainMenu.lua index 0c894238f703c5f579024b018c969a58ddf3c1eb..00c2885da59773f594068f28ff4c8033c8db4ec7 100644 --- a/game/engines/default/modules/boot/dialogs/MainMenu.lua +++ b/game/engines/default/modules/boot/dialogs/MainMenu.lua @@ -36,6 +36,7 @@ function _M:init() l[#l+1] = {name="Load Game", fct=function() game:registerDialog(require("mod.dialogs.LoadGame").new()) end} l[#l+1] = {name="Player Profile", fct=function() game:registerDialog(require("mod.dialogs.Profile").new()) end} l[#l+1] = {name="View High Scores", fct=function() game:registerDialog(require("mod.dialogs.ViewHighScores").new()) end} + l[#l+1] = {name="Addons", fct=function() game:registerDialog(require("mod.dialogs.Addons").new()) end} if config.settings.install_remote then l[#l+1] = {name="Install Module", fct=function() end} end if config.settings.update_remote then l[#l+1] = {name="Update", fct=function() game:registerDialog(require("mod.dialogs.UpdateAll").new()) end} end l[#l+1] = {name="Options", fct=function()