From fd027e71d3f094baf551cd66531eebd5acecad60 Mon Sep 17 00:00:00 2001 From: Alexander Weber Date: Mon, 25 May 2020 08:13:20 +0200 Subject: [PATCH] add skinsdb5 - skinsdb based skins manager with preview support --- mods/skinsdb5/API.md | 9 ++ mods/skinsdb5/README.md | 24 ++++ mods/skinsdb5/api.lua | 37 +++++ mods/skinsdb5/chatcommands.lua | 104 ++++++++++++++ mods/skinsdb5/formspecs.lua | 132 ++++++++++++++++++ mods/skinsdb5/init.lua | 29 ++++ mods/skinsdb5/locale/skinsdb.de.tr | 19 +++ mods/skinsdb5/locale/skinsdb.fr.tr | 18 +++ mods/skinsdb5/locale/skinsdb.ms.tr | 18 +++ mods/skinsdb5/locale/skinsdb.zh_CN.tr | 20 +++ mods/skinsdb5/locale/skinsdb.zh_TW.tr | 19 +++ mods/skinsdb5/locale/template.txt | 20 +++ mods/skinsdb5/meta/readme.txt | 3 + mods/skinsdb5/mod.conf | 4 + mods/skinsdb5/preview.lua | 60 ++++++++ mods/skinsdb5/sfinv_page.lua | 29 ++++ .../textures/inventory_plus_skins.png | Bin 0 -> 673 bytes mods/skinsdb5/textures/readme.txt | 6 + mods/skinsdb5/textures/skindb_mask_chest.png | Bin 0 -> 114 bytes mods/skinsdb5/textures/skindb_mask_head.png | Bin 0 -> 139 bytes mods/skinsdb5/textures/skindb_mask_rarm.png | Bin 0 -> 118 bytes mods/skinsdb5/textures/skindb_mask_rleg.png | Bin 0 -> 118 bytes mods/skinsdb5/textures/skindb_transform.png | Bin 0 -> 191 bytes mods/skinsdb5/textures/skins_button.png | Bin 0 -> 250 bytes mods/skinsdb5/textures/ui_misc_form.png | Bin 0 -> 6177 bytes mods/skinsdb5/unified_inventory_page.lua | 57 ++++++++ 26 files changed, 608 insertions(+) create mode 100644 mods/skinsdb5/API.md create mode 100644 mods/skinsdb5/README.md create mode 100644 mods/skinsdb5/api.lua create mode 100644 mods/skinsdb5/chatcommands.lua create mode 100644 mods/skinsdb5/formspecs.lua create mode 100644 mods/skinsdb5/init.lua create mode 100644 mods/skinsdb5/locale/skinsdb.de.tr create mode 100644 mods/skinsdb5/locale/skinsdb.fr.tr create mode 100644 mods/skinsdb5/locale/skinsdb.ms.tr create mode 100644 mods/skinsdb5/locale/skinsdb.zh_CN.tr create mode 100644 mods/skinsdb5/locale/skinsdb.zh_TW.tr create mode 100644 mods/skinsdb5/locale/template.txt create mode 100644 mods/skinsdb5/meta/readme.txt create mode 100644 mods/skinsdb5/mod.conf create mode 100644 mods/skinsdb5/preview.lua create mode 100644 mods/skinsdb5/sfinv_page.lua create mode 100644 mods/skinsdb5/textures/inventory_plus_skins.png create mode 100644 mods/skinsdb5/textures/readme.txt create mode 100644 mods/skinsdb5/textures/skindb_mask_chest.png create mode 100644 mods/skinsdb5/textures/skindb_mask_head.png create mode 100644 mods/skinsdb5/textures/skindb_mask_rarm.png create mode 100644 mods/skinsdb5/textures/skindb_mask_rleg.png create mode 100644 mods/skinsdb5/textures/skindb_transform.png create mode 100644 mods/skinsdb5/textures/skins_button.png create mode 100644 mods/skinsdb5/textures/ui_misc_form.png create mode 100644 mods/skinsdb5/unified_inventory_page.lua diff --git a/mods/skinsdb5/API.md b/mods/skinsdb5/API.md new file mode 100644 index 00000000..1c38984d --- /dev/null +++ b/mods/skinsdb5/API.md @@ -0,0 +1,9 @@ +# Skinsdb Interface + +## skinsdb5.get_skinlist_for_player(playername) +Get all allowed skins for player. All public and all player's private skins. If playername not given only public skins returned + +## skinsdb5.get_skinlist_with_meta(key, value) +Get all skins with metadata key is set to value. Example: +skinsdb5.get_skinlist_with_meta("playername", playername) - Get all private skins (w.o. public) for playername + diff --git a/mods/skinsdb5/README.md b/mods/skinsdb5/README.md new file mode 100644 index 00000000..1103f6e9 --- /dev/null +++ b/mods/skinsdb5/README.md @@ -0,0 +1,24 @@ +# skinsdb5 + +This Minetest mod offers changeable player skins with a graphical interface for multiple inventory mods. + +## Features + +- player_api Skins management compatible, as proposed for minetest_game-0.5 +- Skin change menu for sfinv (in minetest_game) and [unified_inventory](https://forum.minetest.net/viewtopic.php?t=12767) +- Own skin change menu and command line using chat command /skinsdb (set | show | list | list private | list public | ui) +- Skin previews supported in selection +- Additional information for each skin +- Support for different skins lists: public and a per-player list are currently implemented + +## License + +If nothing else is specified, it is licensed as GPLv3. + +### Credits + +- RealBadAngel (unified_inventory) +- Zeg9 (skinsdb) +- cornernote (source code) +- Krock (source code) +- bell07 (source code) diff --git a/mods/skinsdb5/api.lua b/mods/skinsdb5/api.lua new file mode 100644 index 00000000..76bb34df --- /dev/null +++ b/mods/skinsdb5/api.lua @@ -0,0 +1,37 @@ +local function skins_sort(skinslist) + table.sort(skinslist, function(a,b) + local a_sortid = a.sort_id or "" + local b_sortid = b.sort_id or "" + if a_sortid ~= b_sortid then + return a_sortid < b_sortid + else + return tostring(a.description or a.name or "") < tostring(b.description or b.name or "") + end + end) +end + +-- Get skinlist for player. If no player given, public skins only selected +function skinsdb5.get_skinlist_for_player(playername) + local skinslist = {} + for _, skin in pairs(player_api.registered_skins) do + if skin.in_inventory_list ~= false and + (not skin.playername or (playername and skin.playername:lower() == playername:lower())) then + table.insert(skinslist, skin) + end + end + skins_sort(skinslist) + return skinslist +end + +-- Get skinlist selected by metadata +function skinsdb5.get_skinlist_with_meta(key, value) + assert(key, "key parameter for skinsdb5.get_skinlist_with_meta() missed") + local skinslist = {} + for _, skin in pairs(player_api.registered_skins) do + if skin[key] == value then + table.insert(skinslist, skin) + end + end + skins_sort(skinslist) + return skinslist +end diff --git a/mods/skinsdb5/chatcommands.lua b/mods/skinsdb5/chatcommands.lua new file mode 100644 index 00000000..09a3d6a6 --- /dev/null +++ b/mods/skinsdb5/chatcommands.lua @@ -0,0 +1,104 @@ +local S = minetest.get_translator("skinsdb") + +local function show_selection_formspec(player) + local context = skinsdb5.get_formspec_context(player) + local name = player:get_player_name() + local skin = player_api.get_skin(player) + local formspec = "size[8,8]"..skinsdb5.get_skin_info_formspec(skin) + formspec = formspec..skinsdb5.get_skin_selection_formspec(player, context, 3.5) + minetest.show_formspec(name, 'skinsdb_show_ui', formspec) +end + + +minetest.register_chatcommand("skinsdb", { + params = "[set] | show [] | list | list private | list public | [ui]", + description = S("Show, list or set player's skin"), + func = function(name, param) + local player = minetest.get_player_by_name(name) + if not player then + return false, S("Player not found") + end + + -- parse command line + local command, parameter + local words = param:split(" ") + local word = words[1] + if word == 'set' or word == 'list' or word == 'show' or word == 'ui' then + command = word + parameter = words[2] + elseif player_api.registered_skins[word] then + command = 'set' + parameter = word + elseif not word then + command = 'ui' + else + return false, S("unknown command").." "..word..", "..S("see /help skinsdb for supported parameters") + end + + if command == "set" then + if parameter then + if player_api.registered_skins[parameter] then + player_api.set_skin(player, parameter) + return true, S("skin set to").." "..parameter + else + return false, S("invalid skin").." "..parameter + end + else + return false, S("requires skin key") + end + elseif command == "list" then + local list + if parameter == "private" then + list = skinsdb5.get_skinlist_with_meta("playername", name) + elseif parameter == "public" then + list = skinsdb5.get_skinlist_for_player() + elseif not parameter then + list = skinsdb5.get_skinlist_for_player(name) + else + return false, S("unknown parameter"), parameter + end + + local current_skin_key = player_api.get_skin(player) + for _, skin in ipairs(list) do + local info = skin.name.." - " + ..S("Name").."="..(skin.description or skin.name or "").." " + ..S("Author").."="..(skin.author or "").." " + ..S("License").."="..(skin.license or "") + if skin.name == current_skin_key then + info = minetest.colorize("#00FFFF", info) + end + minetest.chat_send_player(name, info) + end + elseif command == "show" then + local skin + if parameter then + skin = parameter + else + skin = player_api.get_skin(player) + end + if not skin then + return false, S("invalid skin") + end + local formspec = "size[8,3]"..skinsdb5.get_skin_info_formspec(skin) + minetest.show_formspec(name, 'skinsdb_show_skin', formspec) + elseif command == "ui" then + show_selection_formspec(player) + end + end, +}) + + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "skinsdb_show_ui" then + return + end + + local context = skinsdb5.get_formspec_context(player) + + local action = skinsdb5.on_skin_selection_receive_fields(player, context, fields) + if action == 'set' then + minetest.close_formspec(player:get_player_name(), formname) + elseif action == 'page' then + show_selection_formspec(player) + end +end) diff --git a/mods/skinsdb5/formspecs.lua b/mods/skinsdb5/formspecs.lua new file mode 100644 index 00000000..d2ffe72f --- /dev/null +++ b/mods/skinsdb5/formspecs.lua @@ -0,0 +1,132 @@ +local S = minetest.get_translator("skinsdb") + +function skinsdb5.get_formspec_context(player) + if player then + local playername = player:get_player_name() + skinsdb5.ui_context[playername] = skinsdb5.ui_context[playername] or {} + return skinsdb5.ui_context[playername] + else + return {} + end +end + +-- Show skin info +function skinsdb5.get_skin_info_formspec(skin_name) + local skin = player_api.registered_skins[skin_name] + if not skin then + return "" + end + local texture = skin.texture or (skin.textures and skin.textures[1]) + if not skin.preview and texture then + skin.preview = skinsdb5.get_preview(texture, skin.format) + end + local formspec = "" + if skin.preview then + formspec = formspec.."image[0,.75;1,2;"..skin.preview.."]" + end + if texture then + local raw_size = skin.format == "1.8" and "2,2" or "2,1" + formspec = formspec.."label[6,.5;"..S("Raw texture")..":]image[6,1;"..raw_size..";"..texture.."]" + end + formspec = formspec.."label[2,.5;"..S("Name")..": "..minetest.formspec_escape(skin.description or skin.name).."]" + if skin.author then + formspec = formspec.."label[2,1;"..S("Author")..": "..minetest.formspec_escape(skin.author).."]" + end + if skin.license then + formspec = formspec.."label[2,1.5;"..S("License")..": "..minetest.formspec_escape(skin.license).."]" + end + return formspec +end + +function skinsdb5.get_skin_selection_formspec(player, context, y_delta) + local skins_list = skinsdb5.get_skinlist_for_player(player:get_player_name()) + local current_skin = player_api.registered_skins[player_api.get_skin(player)] + context.skins_list = {} + context.total_pages = 1 + context.dropdown_values = nil + + for i, skin in ipairs(skins_list) do + local page = math.floor((i-1) / 16)+1 + local page_index = (i-1)%16+1 + context.total_pages = page + context.skins_list[i] = { + name = skin.name, + page = page, + page_index = page_index + } + + if not context.skins_page and skin.name == current_skin then + context.skins_page = page + end + end + + context.skins_page = context.skins_page or 1 + local current_page = context.skins_page + local formspec = "" + for i = (current_page-1)*16+1, current_page*16 do + local skin = skins_list[i] + if not skin then + break + end + + if not skin.preview then + local texture = skin.texture or (skin.textures and skin.textures[1]) + if texture then + skin.preview = skinsdb5.get_preview(texture, skin.format) + end + end + + local index_p = context.skins_list[i].page_index + local x = (index_p-1) % 8 + local y + if index_p > 8 then + y = y_delta + 1.9 + else + y = y_delta + end + formspec = formspec.."image_button["..x..","..y..";1,2;".. + (skin.preview or "")..";skins_set$"..i..";]".. + "tooltip[skins_set$"..i..";"..minetest.formspec_escape(skin.description or skin.name).."]" + end + + if context.total_pages > 1 then + local page_prev = current_page - 1 + local page_next = current_page + 1 + if page_prev < 1 then + page_prev = context.total_pages + end + if page_next > context.total_pages then + page_next = 1 + end + local page_list = "" + context.dropdown_values = {} + for pg=1, context.total_pages do + local pagename = S("Page").." "..pg.."/"..context.total_pages + context.dropdown_values[pagename] = pg + if pg > 1 then page_list = page_list.."," end + page_list = page_list..pagename + end + formspec = formspec + .."button[0,"..(y_delta+4.0)..";1,.5;skins_page$"..page_prev..";<<]" + .."dropdown[0.9,"..(y_delta+3.88)..";6.5,.5;skins_selpg;"..page_list..";"..context.skins_page.."]" + .."button[7,"..(y_delta+4.0)..";1,.5;skins_page$"..page_next..";>>]" + end + return formspec +end + +function skinsdb5.on_skin_selection_receive_fields(player, context, fields) + for field, _ in pairs(fields) do + local current = string.split(field, "$", 2) + if current[1] == "skins_set" then + player_api.set_skin(player, context.skins_list[tonumber(current[2])].name) + return 'set' + elseif current[1] == "skins_page" then + context.skins_page = tonumber(current[2]) + return 'page' + end + end + if fields.skins_selpg then + context.skins_page = tonumber(context.dropdown_values[fields.skins_selpg]) + return 'page' + end +end diff --git a/mods/skinsdb5/init.lua b/mods/skinsdb5/init.lua new file mode 100644 index 00000000..accf1a1a --- /dev/null +++ b/mods/skinsdb5/init.lua @@ -0,0 +1,29 @@ +-- Rework 2018-2020 by bell07 +-- License: GPLv3 + +skinsdb5 = {} +local modpath = minetest.get_modpath(minetest.get_current_modname()) +skinsdb5.modpath = modpath + +dofile(modpath.."/api.lua") +dofile(modpath.."/preview.lua") +dofile(modpath.."/formspecs.lua") +dofile(modpath.."/chatcommands.lua") + +-- Unified inventory page/integration +if minetest.get_modpath("unified_inventory") then + dofile(modpath.."/unified_inventory_page.lua") +end + +if minetest.get_modpath("sfinv") then + dofile(modpath.."/sfinv_page.lua") +end + +-- Update skin on join +skinsdb5.ui_context = {} +minetest.register_on_leaveplayer(function(player) + skinsdb5.ui_context[player:get_player_name()] = nil +end) + +-- Read current mod textures- and meta- folder +player_api.read_textures_and_meta() diff --git a/mods/skinsdb5/locale/skinsdb.de.tr b/mods/skinsdb5/locale/skinsdb.de.tr new file mode 100644 index 00000000..2f6e0cf4 --- /dev/null +++ b/mods/skinsdb5/locale/skinsdb.de.tr @@ -0,0 +1,19 @@ +# textdomain: skinsdb +# Translation by Xanthin + +Raw texture=Rohtextur +Name=Name +Author=Autor +Change=Wechseln +Page=Seite +License=Lizenz +Description=Beschreibung +Show, list or set player's skin=Anzeigen oder setzen der Spieler-Skins +Player not found=Spieler nicht da +unknown command=unbekannter Befehl +see /help skinsdb for supported parameters=Lese /help für erlaubte Parameter +skin set to=Skin ist jetzt +invalid skin=unbekannter Skin +requires skin key=Skin key benötigt +unknown parameter=unbekannter Parameter +Skins=Aussehen diff --git a/mods/skinsdb5/locale/skinsdb.fr.tr b/mods/skinsdb5/locale/skinsdb.fr.tr new file mode 100644 index 00000000..7122d781 --- /dev/null +++ b/mods/skinsdb5/locale/skinsdb.fr.tr @@ -0,0 +1,18 @@ +# textdomain: skinsdb + +Raw texture=Texture +Name=Nom +Author=Auteur +Change=Changer +Page=Page +License=Licence +Description=Description +Show, list or set player's skin=Afficher, lister ou définir le skin du joueur +Player not found=Joueur non trouvé +unknown command=commande inconnue +see /help skinsdb for supported parameters=voir /help skinsdb pour les paramètres supportés +skin set to=skin définie sur +invalid skin=skin peau invalide +unknown parameter=paramètre inconnu +unknown skin=skin inconnue + diff --git a/mods/skinsdb5/locale/skinsdb.ms.tr b/mods/skinsdb5/locale/skinsdb.ms.tr new file mode 100644 index 00000000..61eb1a03 --- /dev/null +++ b/mods/skinsdb5/locale/skinsdb.ms.tr @@ -0,0 +1,18 @@ +# textdomain: skinsdb +# Malay translation by muhdnurhidayat + +Raw texture=Tekstur mentah +Name=Nama +Author=Pencipta +Change=Ubah +Page=Halaman +License=Lesen +Description=Keterangan +Show, list or set player's skin=Tunjukkan, senaraikan atau tetapkan kulit pemain +Player not found=Pemain tidak dijumpai +unknown command=perintah tidak diketahui +see /help skinsdb for supported parameters=lihat /help skinsdb untuk parameter yang disokong +skin set to=kulit ditetapkan kepada +invalid skin=kulit tidak sah +unknown parameter=parameter tidak diketahui +unknown skin=kulit tidak diketahui diff --git a/mods/skinsdb5/locale/skinsdb.zh_CN.tr b/mods/skinsdb5/locale/skinsdb.zh_CN.tr new file mode 100644 index 00000000..b6832dd5 --- /dev/null +++ b/mods/skinsdb5/locale/skinsdb.zh_CN.tr @@ -0,0 +1,20 @@ +# textdomain: skinsdb +#Translation by IFRFSX(BingFengFSX) + +Raw texture=自然状态的纹理 +Name=名称 +Author=作者 +Change=更换 +Page=页面 +License=许可证 +Description=说明 +Show, list or set player's skin=显示,列出或者设置玩家的皮肤 +Player not found=玩家未找到 +unknown command=未知命令 +see /help skinsdb for supported parameters=有关skinsdb支持的参数,参见 /help +skin set to=皮肤设置为 +invalid skin=无效皮肤 +unknown parameter=未知参数 +unknown skin=未知皮肤 +Downloads the specified range of skins and shuts down the server=下载指定范围的皮肤并关闭服务器 +Skins=皮肤 diff --git a/mods/skinsdb5/locale/skinsdb.zh_TW.tr b/mods/skinsdb5/locale/skinsdb.zh_TW.tr new file mode 100644 index 00000000..236b55d2 --- /dev/null +++ b/mods/skinsdb5/locale/skinsdb.zh_TW.tr @@ -0,0 +1,19 @@ +# textdomain: skinsdb +#Translation by IFRFSX(BingFengFSX) +Raw texture=自然狀態的紋理 +Name=名稱 +Author=作者 +Change=更換 +Page=頁面 +License=許可證 +Description=說明 +Show,list or set player's skin=顯示,列出或者設定玩家的皮膚 +Player not found=玩家未找到 +unknown command=未知命令 +see /help skinsdb for supported parameters=有關skinsdb支持的參數,參見/help +skin set to=皮膚設定為 +invalid skin=無效皮膚 +unknown parameter=未知參數 +unknown skin=未知皮膚 +Downloads the specified range of skins and shuts down the server=下載指定範圍的皮膚並關閉服務器 +Skins=皮膚 diff --git a/mods/skinsdb5/locale/template.txt b/mods/skinsdb5/locale/template.txt new file mode 100644 index 00000000..d974d7d3 --- /dev/null +++ b/mods/skinsdb5/locale/template.txt @@ -0,0 +1,20 @@ +# textdomain: skinsdb + +Raw texture= +Name= +Author= +Change= +Page= +License= +Description= +Show, list or set player's skin= +Player not found= +unknown command= +see /help skinsdb for supported parameters= +skin set to= +invalid skin= +requires skin key= +unknown parameter= +unknown skin= +Downloads the specified range of skins and shuts down the server= +Skins= diff --git a/mods/skinsdb5/meta/readme.txt b/mods/skinsdb5/meta/readme.txt new file mode 100644 index 00000000..a62312a3 --- /dev/null +++ b/mods/skinsdb5/meta/readme.txt @@ -0,0 +1,3 @@ +For each skin in textures folder a metadata file can be applied with ".txt" suffix. +character.png requires character.txt for example. +For file content see player_api/skin_api.txt for reference. diff --git a/mods/skinsdb5/mod.conf b/mods/skinsdb5/mod.conf new file mode 100644 index 00000000..5750d3f7 --- /dev/null +++ b/mods/skinsdb5/mod.conf @@ -0,0 +1,4 @@ +name = skinsdb5 +description = Player skin mod, supporting sfinv and unified_inventory +depends = player_api +optional_depends = sfinv,unified_inventory diff --git a/mods/skinsdb5/preview.lua b/mods/skinsdb5/preview.lua new file mode 100644 index 00000000..d5787a06 --- /dev/null +++ b/mods/skinsdb5/preview.lua @@ -0,0 +1,60 @@ +-- stohlen from https://github.com/GreenXenith/skinsdb/blob/master/skin_meta_api.lua +function skinsdb5.get_preview(texture, format) + local player_skin = "("..texture..")" + local skin = "" + + -- Consistent on both sizes: + --Chest + skin = skin .. "([combine:16x32:-16,-12=" .. player_skin .. "^[mask:skindb_mask_chest.png)^" + --Head + skin = skin .. "([combine:16x32:-4,-8=" .. player_skin .. "^[mask:skindb_mask_head.png)^" + --Hat + skin = skin .. "([combine:16x32:-36,-8=" .. player_skin .. "^[mask:skindb_mask_head.png)^" + --Right Arm + skin = skin .. "([combine:16x32:-44,-12=" .. player_skin .. "^[mask:skindb_mask_rarm.png)^" + --Right Leg + skin = skin .. "([combine:16x32:0,0=" .. player_skin .. "^[mask:skindb_mask_rleg.png)^" + + -- 64x skins have non-mirrored arms and legs + local left_arm + local left_leg + + if format == "1.8" then + left_arm = "([combine:16x32:-24,-44=" .. player_skin .. "^[mask:(skindb_mask_rarm.png^[transformFX))^" + left_leg = "([combine:16x32:-12,-32=" .. player_skin .. "^[mask:(skindb_mask_rleg.png^[transformFX))^" + else + left_arm = "([combine:16x32:-44,-12=" .. player_skin .. "^[mask:skindb_mask_rarm.png^[transformFX)^" + left_leg = "([combine:16x32:0,0=" .. player_skin .. "^[mask:skindb_mask_rleg.png^[transformFX)^" + end + + -- Left Arm + skin = skin .. left_arm + --Left Leg + skin = skin .. left_leg + + -- Add overlays for 64x skins. these wont appear if skin is 32x because it will be cropped out + --Chest Overlay + skin = skin .. "([combine:16x32:-16,-28=" .. player_skin .. "^[mask:skindb_mask_chest.png)^" + --Right Arm Overlay + skin = skin .. "([combine:16x32:-44,-28=" .. player_skin .. "^[mask:skindb_mask_rarm.png)^" + --Right Leg Overlay + skin = skin .. "([combine:16x32:0,-16=" .. player_skin .. "^[mask:skindb_mask_rleg.png)^" + --Left Arm Overlay + skin = skin .. "([combine:16x32:-40,-44=" .. player_skin .. "^[mask:(skindb_mask_rarm.png^[transformFX))^" + --Left Leg Overlay + skin = skin .. "([combine:16x32:4,-32=" .. player_skin .. "^[mask:(skindb_mask_rleg.png^[transformFX))" + + -- Full Preview + skin = "(((" .. skin .. ")^[resize:64x128)^[mask:skindb_transform.png)" + return minetest.formspec_escape(skin) +end + +player_api.register_on_skin_change(function(player, model_name, skin_name) + local skin = player_api.registered_skins[skin_name] + if not skin.preview then + local texture = skin.texture or (skin.textures and skin.textures[1]) + if texture then + skin.preview = skinsdb5.get_preview(texture, skin.format) + end + end +end) diff --git a/mods/skinsdb5/sfinv_page.lua b/mods/skinsdb5/sfinv_page.lua new file mode 100644 index 00000000..f47f6ea5 --- /dev/null +++ b/mods/skinsdb5/sfinv_page.lua @@ -0,0 +1,29 @@ +local S = minetest.get_translator("skinsdb") + +-- generate the current formspec +local function get_formspec(player, context) + local skin = player_api.get_skin(player) + local formspec = skinsdb5.get_skin_info_formspec(skin) + formspec = formspec..skinsdb5.get_skin_selection_formspec(player, context, 4) + return formspec +end + +sfinv.register_page("skinsdb5:overview", { + title = S("Skins"), + get = function(self, player, context) + -- collect skins data + return sfinv.make_formspec(player, context, get_formspec(player, context)) + end, + on_player_receive_fields = function(self, player, context, fields) + local action = skinsdb5.on_skin_selection_receive_fields(player, context, fields) + if action == "page" then + sfinv.set_player_inventory_formspec(player) + end + end +}) + +player_api.register_on_skin_change(function(player, model_name, skin_name) + if sfinv.enabled then + sfinv.set_player_inventory_formspec(player) + end +end) diff --git a/mods/skinsdb5/textures/inventory_plus_skins.png b/mods/skinsdb5/textures/inventory_plus_skins.png new file mode 100644 index 0000000000000000000000000000000000000000..781b42ff1fb4c9972cd4c08e3b980d878a554d25 GIT binary patch literal 673 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP)8waPjX-Oip3Q$NjGbEzKIX^cyHLrw$5h%bhvsll| zSI5&gP~*JL$$*0IUw9c9%;&N`5;iLUvKaq*x;Tbd2(ljBn!W{^RrZA8#I)XKG-m`1T|*O>M{48|B4yhu6tp@tK|X`fAbA%qYR5 zlhg0BJ1}xMGR@@Kx(WzS`8aei09|$T-*vV*P5Iumsb3{Lr%p`Qp(o(vw38JnW|G;n z+`MML^_wZ6tim9WU*}k^xcqp^(%lK$pFDj1{-jU+nfmX4euz)sZ?yO9Gns==#Pt1K z&)6v(+Z4AbfNy2?v3!QFUH|+~_59+0D&UwG`CsE7yKL*NzQ^(R=7VC*)78&qol`;+ E0Q%+@_y7O^ literal 0 HcmV?d00001 diff --git a/mods/skinsdb5/textures/readme.txt b/mods/skinsdb5/textures/readme.txt new file mode 100644 index 00000000..7bcff790 --- /dev/null +++ b/mods/skinsdb5/textures/readme.txt @@ -0,0 +1,6 @@ +In this folder the skin files could be placed according the next file naming convention +character_[number].png - Public skin, available for all users +character_[name].png - Public skin, but named as "name" - usefull to enhance already provided skins like sam +player_[nick].png or player_[nick]_[number].png - one or multiple private skins for player "nick" +*_preview.png - Preview files for public and private skins - Optional, overrides the generated preview + diff --git a/mods/skinsdb5/textures/skindb_mask_chest.png b/mods/skinsdb5/textures/skindb_mask_chest.png new file mode 100644 index 0000000000000000000000000000000000000000..b0456da44cf232578425bb3744c28132bdb45748 GIT binary patch literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^0zj<5!2%>VHW;`ADb50q$YKTtZeb8+WSBKa0w}2B z>Eak-aXR_W`389d!yXP+odU6{1_M4h_dWsEp2e9(7c>|c>?bnYfBE-&6;M5cr>mdK II;Vst0N`pHc>n+a literal 0 HcmV?d00001 diff --git a/mods/skinsdb5/textures/skindb_mask_head.png b/mods/skinsdb5/textures/skindb_mask_head.png new file mode 100644 index 0000000000000000000000000000000000000000..50586731233520d2b5ab3b3523ff4dea19b7edc0 GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^0zj<5!2%>VHW;`ADb50q$YKTtZeb8+WSBKa0w`$f z>Eak-aXR_Wc?Q-3HW33OBLfgH6ks^)%&6SVHW;`ADb50q$YKTtZeb8+WSBKa0w}2A z>Eak-aXL9cf|Umddj9`E9C1U`K+q^LgmJ5g!N28KS^`?mC98mxO literal 0 HcmV?d00001 diff --git a/mods/skinsdb5/textures/skindb_mask_rleg.png b/mods/skinsdb5/textures/skindb_mask_rleg.png new file mode 100644 index 0000000000000000000000000000000000000000..d06c3d8a396f2dc41af89d89ef66e66ebd330610 GIT binary patch literal 118 zcmeAS@N?(olHy`uVBq!ia0vp^0zj<5!2%>VHW;`ADb50q$YKTtZeb8+WSBKa0w}2A z>Eak-aXL9cf|Umddj4~2Bq*gETEUd1nb5d7Vd5c+A2OCsA`A@Ar!pB{<(tk9)WhKE L>gTe~DWM4f9>^OU literal 0 HcmV?d00001 diff --git a/mods/skinsdb5/textures/skindb_transform.png b/mods/skinsdb5/textures/skindb_transform.png new file mode 100644 index 0000000000000000000000000000000000000000..a36bf543650db5cc2b9ffb90a77541991fba4a59 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!2%=&JC;8LQk(@Ik;M!QddeWoSh3W;3@BLW z>EaktaqI1^jhqYy94rTFzTLl>Bf!0S!tbz&hy4t;&f3E3TcrQ~;g3R~Vq_3>`S<^? nyvQO*>?8JyNIV4d!1o5`v?px8@(#TI3ljBo^>bP0l+XkKL0v9J literal 0 HcmV?d00001 diff --git a/mods/skinsdb5/textures/skins_button.png b/mods/skinsdb5/textures/skins_button.png new file mode 100644 index 0000000000000000000000000000000000000000..f4c006c4e73828340e0605906a72e0588da5347a GIT binary patch literal 250 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2VGmzZ%#=aj&c?9@`xNbGIw^0=~R}wT+6f{u~ z(3jyeRS>XJ7P3+iHk9MHR2F)CV6m;5$iuz!?`)p@|Nnn8v)2!H&$+W{(w!|+?(dj+ zW@+2K?KAFdo+O^3Cj>N;u_VYZn8D%MjWi&Kv%n*=n1O*?7=#%aX3dcR3VM6GIEHXs z_dRPa#GuH-;_sT9+-|IgxHaj!@-+k1u1!ydTr>mdKI;Vst05e2Y$^ZZW literal 0 HcmV?d00001 diff --git a/mods/skinsdb5/textures/ui_misc_form.png b/mods/skinsdb5/textures/ui_misc_form.png new file mode 100644 index 0000000000000000000000000000000000000000..2a7edb9d51f4cc3bfeb04861868b8a366ea56d60 GIT binary patch literal 6177 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 H^WDDyE1|wV literal 0 HcmV?d00001 diff --git a/mods/skinsdb5/unified_inventory_page.lua b/mods/skinsdb5/unified_inventory_page.lua new file mode 100644 index 00000000..7e357b52 --- /dev/null +++ b/mods/skinsdb5/unified_inventory_page.lua @@ -0,0 +1,57 @@ +local S = minetest.get_translator("skinsdb") + +unified_inventory.register_page("skins", { + get_formspec = function(player) + local skin = player_api.get_skin(player) + local formspec = "background[0.06,0.99;7.92,7.52;ui_misc_form.png]"..skinsdb5.get_skin_info_formspec(skin).. + "button[.75,3;6.5,.5;skins_page;"..S("Change").."]" + return {formspec=formspec} + end, +}) + +unified_inventory.register_button("skins", { + type = "image", + image = "skins_button.png", + tooltip = S("Skins"), +}) + +local function get_formspec(player) + local context = skinsdb5.get_formspec_context(player) + local formspec = "background[0.06,0.99;7.92,7.52;ui_misc_form.png]".. + skinsdb5.get_skin_selection_formspec(player, context, -0.2) + return formspec +end + +unified_inventory.register_page("skins_page", { + get_formspec = function(player) + return {formspec=get_formspec(player)} + end +}) + +-- click button handlers +minetest.register_on_player_receive_fields(function(player, formname, fields) + if fields.skins then + unified_inventory.set_inventory_formspec(player, "craft") + return + end + + if formname ~= "" then + return + end + + local context = skinsdb5.get_formspec_context(player) + local action = skinsdb5.on_skin_selection_receive_fields(player, context, fields) + if action == "set" then + unified_inventory.set_inventory_formspec(player, "skins") + elseif action == "page" then + unified_inventory.set_inventory_formspec(player, "skins_page") + end +end) + +player_api.register_on_skin_change(function(player, model_name, skin_name) + local player_name = player:get_player_name() + -- refresh skins page if selected + if unified_inventory.current_page[player_name] == "skins" then + unified_inventory.set_inventory_formspec(player, "skins") + end +end)