diff options
Diffstat (limited to 'src/gui.lua')
-rw-r--r-- | src/gui.lua | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/src/gui.lua b/src/gui.lua new file mode 100644 index 0000000..cfc82af --- /dev/null +++ b/src/gui.lua @@ -0,0 +1,269 @@ +-- Copyright (c) 2013-18 rubenwardy. MIT. + +local S = awards.gettext + +local function order_awards(name) + local hash_is_unlocked = {} + local retval = {} + + local data = awards.player(name) + if data and data.unlocked then + for awardname, _ in pairs(data.unlocked) do + local def = awards.registered_awards[awardname] + if def then + hash_is_unlocked[awardname] = true + local score = -100000 + + local difficulty = def.difficulty or 1 + if def.trigger and def.trigger.target then + difficulty = difficulty * def.trigger.target + end + score = score + difficulty + + retval[#retval + 1] = { + name = awardname, + def = def, + unlocked = true, + started = true, + score = score, + } + end + end + end + + for _, def in pairs(awards.registered_awards) do + if not hash_is_unlocked[def.name] and def:can_unlock(data) then + local started = false + local score = def.difficulty or 1 + if def.secret then + score = 1000000 + elseif def.trigger and def.trigger.target and def.getProgress then + local progress = def:getProgress(data).perc + score = score * (1 - progress) * def.trigger.target + if progress < 0.001 then + score = score + 100 + else + started = true + end + else + score = 100 + end + + retval[#retval + 1] = { + name = def.name, + def = def, + unlocked = false, + started = started, + score = score, + } + end + end + + table.sort(retval, function(a, b) + return a.score < b.score + end) + return retval +end + +function awards.get_formspec(name, to, sid) + local formspec = "" + local awards_list = order_awards(name) + local data = awards.player(name) + + if #awards_list == 0 then + formspec = formspec .. "label[3.9,1.5;"..minetest.formspec_escape(S("Error: No achivements available.")).."]" + formspec = formspec .. "button_exit[4.2,2.3;3,1;close;"..minetest.formspec_escape(S("OK")).."]" + return formspec + end + sid = awards_list[sid] and sid or 1 + + -- Sidebar + local sitem = awards_list[sid] + local sdef = sitem.def + if sdef and sdef.secret and not sitem.unlocked then + formspec = formspec .. "label[1,2.75;".. + minetest.formspec_escape(S("(Secret Award)")).."]".. + "image[1,0;3,3;awards_unknown.png]" + if sdef and sdef.description then + formspec = formspec .. "textarea[0.25,3.25;4.8,1.7;;".. + minetest.formspec_escape( + S("Unlock this award to find out what it is."))..";]" + end + else + local title = sitem.name + if sdef and sdef.title then + title = sdef.title + end + local status = "%s" + if sitem.unlocked then + status = S("%s (unlocked)") + end + + formspec = formspec .. "textarea[0.5,3.1;4.8,1.45;;" .. + string.format(status, minetest.formspec_escape(title)) .. + ";]" + + if sdef and sdef.icon then + formspec = formspec .. "image[0.6,0;3,3;" .. sdef.icon .. "]" + end + local barwidth = 3.95 + local perc = nil + local label = nil + if sdef.getProgress and data then + local res = sdef:getProgress(data) + perc = res.perc + label = res.label + end + if perc then + if perc > 1 then + perc = 1 + end + formspec = formspec .. "background[0,8.24;" .. barwidth ..",0.4;awards_progress_gray.png;false]" + formspec = formspec .. "background[0,8.24;" .. (barwidth * perc) ..",0.4;awards_progress_green.png;false]" + if label then + formspec = formspec .. "label[1.6,8.15;" .. minetest.formspec_escape(label) .. "]" + end + end + if sdef and sdef.description then + formspec = formspec .. "box[-0.05,3.75;3.9,4.2;#000]" + formspec = formspec .. "textarea[0.25,3.75;3.9,4.2;;" .. + minetest.formspec_escape(sdef.description) .. ";]" + end + end + + -- Create list box + formspec = formspec .. "textlist[4,0;3.8,8.6;awards;" + local first = true + for _, award in pairs(awards_list) do + local def = award.def + if def then + if not first then + formspec = formspec .. "," + end + first = false + + if def.secret and not award.unlocked then + formspec = formspec .. "#707070"..minetest.formspec_escape(S("(Secret Award)")) + else + local title = award.name + if def and def.title then + title = def.title + end + -- title = title .. " [" .. award.score .. "]" + if award.unlocked then + formspec = formspec .. minetest.formspec_escape(title) + elseif award.started then + formspec = formspec .. "#c0c0c0".. minetest.formspec_escape(title) + else + formspec = formspec .. "#a0a0a0".. minetest.formspec_escape(title) + end + end + end + end + return formspec .. ";"..sid.."]" +end + + +function awards.show_to(name, to, sid, text) + if name == "" or name == nil then + name = to + end + local data = awards.player(to) + if name == to and data.disabled then + minetest.chat_send_player(name, S("You've disabled awards. Type /awards enable to reenable.")) + return + end + if text then + local awards_list = order_awards(name) + if #awards_list == 0 then + minetest.chat_send_player(to, S("Error: No award available.")) + return + elseif not data or not data.unlocked then + minetest.chat_send_player(to, S("You have not unlocked any awards.")) + return + end + minetest.chat_send_player(to, string.format(S("%s’s awards:"), name)) + + for str, _ in pairs(data.unlocked) do + local def = awards.registered_awards[str] + if def then + if def.title then + if def.description then + minetest.chat_send_player(to, string.format(S("%s: %s"), def.title, def.description)) + else + minetest.chat_send_player(to, def.title) + end + else + minetest.chat_send_player(to, str) + end + end + end + else + local deco = "" + if minetest.global_exists("default") then + deco = default.gui_bg .. default.gui_bg_img + end + -- Show formspec to user + minetest.show_formspec(to,"awards:awards", + "size[8,8.6]" .. deco .. + awards.get_formspec(name, to, sid)) + end +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "awards:awards" then + return false + end + if fields.quit then + return true + end + local name = player:get_player_name() + if fields.awards then + local event = minetest.explode_textlist_event(fields.awards) + if event.type == "CHG" then + awards.show_to(name, name, event.index, false) + end + end + + return true +end) + +if minetest.get_modpath("sfinv") then + sfinv.register_page("awards:awards", { + title = S("Awards"), + on_enter = function(self, player, context) + context.awards_idx = 1 + end, + is_in_nav = function(self, player, context) + local data = awards.player(player:get_player_name()) + return not data.disabled + end, + get = function(self, player, context) + local name = player:get_player_name() + return sfinv.make_formspec(player, context, + awards.get_formspec(name, name, context.awards_idx), + false) + end, + on_player_receive_fields = function(self, player, context, fields) + if fields.awards then + local event = minetest.explode_textlist_event(fields.awards) + if event.type == "CHG" then + context.awards_idx = event.index + sfinv.set_player_inventory_formspec(player, context) + end + end + end + }) +end + +if minetest.get_modpath("unified_inventory") ~= nil then + unified_inventory.register_button("awards", { + type = "image", + image = "awards_ui_icon.png", + tooltip = S("Awards"), + action = function(player) + local name = player:get_player_name() + awards.show_to(name, name, nil, false) + end, + }) +end |