diff --git a/API.md b/API.md index 5d23186..11b8de2 100644 --- a/API.md +++ b/API.md @@ -16,6 +16,10 @@ skins.assign_player_skin(player, skin) skins.update_player_skin(player) ``` +## skins.get_skin_format(file) +Returns the skin format version ("1.0" or "1.8"). File is an open file handle to the texture file + + ## skins.get_skinlist(assignment, select_unassigned) Obsolete - use get_skinlist_for_player() or get_skinlist_with_meta() instead @@ -63,7 +67,11 @@ Get the skin preview Could be redefined for dynamic preview texture generation ## skin:set_skin(player) -Apply the skin to the player. Is called in skins.update_player_skin() +Apply the skin to the player and do some resets. +Is called if skin selection started, in skins.update_player_skin() for examlpe + +skin:apply_skin_to_player(player) +Apply the skin to the player. Is called in set_skin() and other places the skin needs to be updated ## skin:set_meta(key, value) Add a meta information to the skin object diff --git a/README.md b/README.md index 4c93688..79a171f 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ This Minetest mod offers changeable player skins with a graphical interface for - Additional information for each skin - Support for different skins lists: public and a per-player list are currently implemented - Full [3d_armor](https://forum.minetest.net/viewtopic.php?t=4654) support - +- Compatible to 1.0 and 1.8 Minecraft skins format ## Update tools @@ -41,3 +41,4 @@ Fritigern: - cornernote (source code) - Krock (source code) - bell07 (source code) +- stujones11 (player models) diff --git a/api.lua b/api.lua index a0259cd..5cd9821 100644 --- a/api.lua +++ b/api.lua @@ -43,3 +43,22 @@ function skins.set_player_skin(player, skin) end return success end + +-- Check Skin format (code stohlen from stu's multiskin) +function skins.get_skin_format(file) + file:seek("set", 1) + if file:read(3) == "PNG" then + file:seek("set", 16) + local ws = file:read(4) + local hs = file:read(4) + local w = ws:sub(3, 3):byte() * 256 + ws:sub(4, 4):byte() + local h = hs:sub(3, 3):byte() * 256 + hs:sub(4, 4):byte() + if w >= 64 then + if w == h then + return "1.8" + elseif w == h * 2 then + return "1.0" + end + end + end +end diff --git a/init.lua b/init.lua index 86a137f..ba72d7d 100644 --- a/init.lua +++ b/init.lua @@ -16,7 +16,6 @@ else skins.S = function(s) return s end end - dofile(skins.modpath.."/skin_meta_api.lua") dofile(skins.modpath.."/api.lua") dofile(skins.modpath.."/skinlist.lua") @@ -41,6 +40,14 @@ if minetest.global_exists("armor") then local skin = skins.get_player_skin(minetest.get_player_by_name(name)) return skin:get_preview() end + armor.update_player_visuals = function(self, player) + if not player then + return + end + local skin = skins.get_player_skin(player) + skin:apply_skin_to_player(player) + armor:run_callbacks("on_update", player) + end end -- Update skin on join @@ -52,3 +59,21 @@ end) minetest.register_on_leaveplayer(function(player) skins.ui_context[player:get_player_name()] = nil end) + +default.player_register_model("skinsdb_3d_armor_character.b3d", { + animation_speed = 30, + textures = { + "blank.png", + "blank.png", + "blank.png", + "blank.png", + }, + animations = { + stand = {x=0, y=79}, + lay = {x=162, y=166}, + walk = {x=168, y=187}, + mine = {x=189, y=198}, + walk_mine = {x=200, y=219}, + sit = {x=81, y=160}, + }, +}) diff --git a/models/skinsdb_3d_armor_character.b3d b/models/skinsdb_3d_armor_character.b3d new file mode 100644 index 0000000..dbb8224 Binary files /dev/null and b/models/skinsdb_3d_armor_character.b3d differ diff --git a/models/skinsdb_3d_armor_character.blend b/models/skinsdb_3d_armor_character.blend new file mode 100644 index 0000000..2bf11b5 Binary files /dev/null and b/models/skinsdb_3d_armor_character.blend differ diff --git a/skin_meta_api.lua b/skin_meta_api.lua index d9ca875..f8a92e2 100644 --- a/skin_meta_api.lua +++ b/skin_meta_api.lua @@ -59,16 +59,51 @@ function skin_class:get_preview() return self._preview or "player.png" end -function skin_class:set_skin(player) +local armor_loaded = minetest.global_exists("armor") + +function skin_class:apply_skin_to_player(player) + local ver = self:get_meta("format") or "1.0" + default.player_set_model(player, "skinsdb_3d_armor_character.b3d") + + local v10_texture = "blank.png" + local v18_texture = "blank.png" + local armor_texture = "blank.png" + local wielditem_texture = "blank.png" + + if ver == "1.8" then + v18_texture = self:get_texture() + else + v10_texture = self:get_texture() + end + + if armor_loaded then + local armor_textures = armor.textures[player:get_player_name()] + if armor_textures then + armor_texture = armor_textures.armor + wielditem_texture = armor_textures.wielditem + end + end + + default.player_set_textures(player, { + v10_texture, + v18_texture, + armor_texture, + wielditem_texture, + }) + player:set_properties({ visual_size = { - x = 1, - y = 1 + x = self:get_meta("visual_size_x") or 1, + y = self:get_meta("visual_size_y") or 1 } }) - player:set_properties({ - textures = {self:get_texture()}, - }) +end + +function skin_class:set_skin(player) + -- The set_skin is used on skins selection + -- This means the method could be redefined to start an furmslec + -- See character_creator for example + self:apply_skin_to_player(player) end function skin_class:is_applicable_for_player(playername) diff --git a/skinlist.lua b/skinlist.lua index 5ed5e12..ff7d8d4 100644 --- a/skinlist.lua +++ b/skinlist.lua @@ -42,7 +42,10 @@ for _, fn in pairs(skins_dir_list) do if playername then skin_obj:set_meta("playername", playername) end - local file = io.open(skins.modpath.."/meta/"..name..".txt", "r") + local file = io.open(skins.modpath.."/textures/"..fn, "r") + skin_obj:set_meta("format", skins.get_skin_format(file)) + file:close() + file = io.open(skins.modpath.."/meta/"..name..".txt", "r") if file then local data = string.split(file:read("*all"), "\n", 3) file:close()