diff --git a/depends.txt b/depends.txt index 39bf229..22a723e 100644 --- a/depends.txt +++ b/depends.txt @@ -1,4 +1,6 @@ 3d_armor? multiskin? inventory_plus? -unified_inventory? \ No newline at end of file +unified_inventory? +skinsdb? +sfinv_buttons? diff --git a/init.lua b/init.lua index 6353a5a..8adab29 100644 --- a/init.lua +++ b/init.lua @@ -1,5 +1,10 @@ character_creator = {} character_creator.skins = dofile(minetest.get_modpath("character_creator") .. "/skins.lua") + +local skinsdb +if minetest.get_modpath("skinsdb") and minetest.global_exists("skins") then + skinsdb = skins +end local skin_default = { gender = "Male", @@ -47,6 +52,7 @@ local indexes = skin_indexes[player] local formspec = "size[15,9.5]" + .. "no_prepend[]" .. "bgcolor[#00000000]" -- Gender .. "button[10,;2.5,.5;male;Male]" @@ -99,20 +105,22 @@ local function load_skin(player) skin_indexes[player] = {} - if not player:get_attribute("character_creator:gender") then - player:set_attribute("character_creator:gender", skin_default.gender) - end - - if not player:get_attribute("character_creator:width") then - player:set_attribute("character_creator:width", skin_default.width) - end - - if not player:get_attribute("character_creator:height") then - player:set_attribute("character_creator:height", skin_default.height) + local player_meta = player:get_meta() + + if not player_meta:contains("character_creator:gender") then + player_meta:set_string("character_creator:gender", skin_default.gender) + end + + if not player_meta:contains("character_creator:width") then + player_meta:set_float("character_creator:width", skin_default.width) + end + + if not player_meta:contains("character_creator:height") then + player_meta:set_float("character_creator:height", skin_default.height) end local function load_data(data_name) - local key = player:get_attribute("character_creator:" .. data_name) + local key = player_meta:get_string("character_creator:" .. data_name) local index = table.indexof(skins_array[data_name], key) if index == -1 then index = table.indexof(skins_array[data_name], skin_default[data_name]) @@ -133,11 +141,13 @@ end local function save_skin(player) + local player_meta = player:get_meta() + local function save_data(data_name) local indexes = skin_indexes[player] local index = indexes[data_name] local key = skins_array[data_name][index] - player:set_attribute("character_creator:" .. data_name, key) + player_meta:set_string("character_creator:" .. data_name, key) end save_data("skin") @@ -150,47 +160,49 @@ save_data("shoes") end +local function get_texture(player) + local player_meta = player:get_meta() + local indexes = skin_indexes[player] + local texture = "" + local gender = player_meta:get_string("character_creator:gender") + + local skin_key = skins_array.skin[indexes.skin] + local skin = skins.skin[skin_key] + texture = texture .. "(" .. skin .. ")" + + local face_key = skins_array.face[indexes.face] + local face = skins.face[face_key][gender][skin_key] + texture = texture .. "^(" .. face .. ")" + + local eyes_key = skins_array.eyes[indexes.eyes] + local eyes = skins.eyes[eyes_key] + texture = texture .. "^(" .. eyes .. ")" + + local hair_style = skins_array.hair_style[indexes.hair_style] + local hair_key = skins_array.hair[indexes.hair] + local hair = skins.hair[hair_key][gender][hair_style] + texture = texture .. "^(" .. hair .. ")" + + local tshirt_key = skins_array.tshirt[indexes.tshirt] + local tshirt = skins.tshirt[tshirt_key] + texture = texture .. "^(" .. tshirt .. ")" + + local pants_key = skins_array.pants[indexes.pants] + local pants = skins.pants[pants_key] + texture = texture .. "^(" .. pants .. ")" + + local shoes_key = skins_array.shoes[indexes.shoes] + local shoes = skins.shoes[shoes_key] + texture = texture .. "^(" .. shoes .. ")" + return texture +end + local function change_skin(player) - local indexes = skin_indexes[player] - - local texture = (function() - local texture = "" - local gender = player:get_attribute("character_creator:gender") - - local skin_key = skins_array.skin[indexes.skin] - local skin = skins.skin[skin_key] - texture = texture .. skin - - local face_key = skins_array.face[indexes.face] - local face = skins.face[face_key][gender][skin_key] - texture = texture .. "^" .. face - - local eyes_key = skins_array.eyes[indexes.eyes] - local eyes = skins.eyes[eyes_key] - texture = texture .. "^" .. eyes - - local hair_style = skins_array.hair_style[indexes.hair_style] - local hair_key = skins_array.hair[indexes.hair] - local hair = skins.hair[hair_key][gender][hair_style] - texture = texture .. "^" .. hair - - local tshirt_key = skins_array.tshirt[indexes.tshirt] - local tshirt = skins.tshirt[tshirt_key] - texture = texture .. "^" .. tshirt - - local pants_key = skins_array.pants[indexes.pants] - local pants = skins.pants[pants_key] - texture = texture .. "^" .. pants - - local shoes_key = skins_array.shoes[indexes.shoes] - local shoes = skins.shoes[shoes_key] - texture = texture .. "^" .. shoes - - return texture - end)() - - local width = tonumber(player:get_attribute("character_creator:width")) - local height = tonumber(player:get_attribute("character_creator:height")) + local player_meta = player:get_meta() + local texture = get_texture(player) + + local width = player_meta:get_float("character_creator:width") + local height = player_meta:get_float("character_creator:height") player:set_properties({ visual_size = { @@ -215,9 +227,61 @@ save_skin(player) end +if skinsdb then + --change skin redefinition for skinsdb + function change_skin(player) + local player_meta = player:get_meta() + local playername = player:get_player_name() + local skinname = "character_creator:"..playername + local skin_obj = skinsdb.get(skinname) or skinsdb.new(skinname) + skin_obj:set_meta("format", "1.0") + skin_obj:set_meta("visual_size_x", player_meta:get_float("character_creator:width")) + skin_obj:set_meta("visual_size_y", player_meta:get_float("character_creator:height")) + skin_obj:apply_skin_to_player(player) + skinsdb.assign_player_skin(player, "character_creator:"..playername) + save_skin(player) + end +end + minetest.register_on_joinplayer(function(player) load_skin(player) - minetest.after(0, change_skin, player) + if skinsdb then + local playername = player:get_player_name() + local skinname = "character_creator:"..playername + local skin_obj = skinsdb.get(skinname) or skinsdb.new(skinname) + -- redefinitions + function skin_obj:set_skin(player) + if not player or not skin_indexes[player] then + return -- not loaded or disconnected + end + change_skin(player) + show_formspec(player) + end + function skin_obj:get_texture() + return get_texture(minetest.get_player_by_name(self:get_meta("playername"))) + end + + -- set data + skin_obj:set_preview("inventory_plus_character_creator.png") + skin_obj:set_meta("name","Character Creator") + --skin_obj:set_meta("author", "???") + skin_obj:set_meta("license", "MIT / CC-BY-SA 3.0 Unported") + skin_obj:set_meta("playername",playername) + --check if active and start the update (avoid race condition for both register_on_joinplayer) + if skinsdb.get_player_skin(player):get_key() == skinname then + minetest.after(0, change_skin, player) + end + else + minetest.after(0, change_skin, player) + end +end) + +minetest.register_on_leaveplayer(function(player) + if skinsdb then + local skinname = "character_creator:"..player:get_player_name() + skinsdb.meta[skinname] = nil + end + skin_indexes[player] = nil end) local skin_temp = {} @@ -226,12 +290,14 @@ return end + local player_meta = player:get_meta() local indexes = skin_indexes[player] + if not skin_temp[player] then skin_temp[player] = { - gender = player:get_attribute("character_creator:gender"), - width = player:get_attribute("character_creator:width"), - height = player:get_attribute("character_creator:height"), + gender = player_meta:get_string("character_creator:gender"), + width = player_meta:get_float("character_creator:width"), + height = player_meta:get_float("character_creator:height"), indexes = table.copy(indexes) } end @@ -239,47 +305,52 @@ -- Gender do if fields.male then - player:set_attribute("character_creator:gender", "Male") - player:set_attribute("character_creator:width", 1) - player:set_attribute("character_creator:height", 1) + player_meta:set_string("character_creator:gender", "Male") + player_meta:set_float("character_creator:width", 1) + player_meta:set_float("character_creator:height", 1) end if fields.female then - player:set_attribute("character_creator:gender", "Female") - player:set_attribute("character_creator:width", 0.95) - player:set_attribute("character_creator:height", 1) + player_meta:set_string("character_creator:gender", "Female") + player_meta:set_float("character_creator:width", 0.95) + player_meta:set_float("character_creator:height", 1) end end -- Height do - local height = tonumber(player:get_attribute("character_creator:height")) + local height = tonumber(player_meta:get_float("character_creator:height")) if fields.taller and height < 1.25 then - player:set_attribute("character_creator:height", height + 0.05) + player_meta:set_float("character_creator:height", height + 0.05) end if fields.shorter and height > 0.75 then - player:set_attribute("character_creator:height", height - 0.05) + player_meta:set_float("character_creator:height", height - 0.05) end end -- Width do - local width = tonumber(player:get_attribute("character_creator:width")) + local width = tonumber(player_meta:get_float("character_creator:width")) if fields.wider and width < 1.25 then - player:set_attribute("character_creator:width", width + 0.05) + player_meta:set_float("character_creator:width", width + 0.05) end if fields.thinner and width > 0.75 then - player:set_attribute("character_creator:width", width - 0.05) + player_meta:set_float("character_creator:width", width - 0.05) end end -- Switch skin do local function switch_skin(data_name, next_index) + if not indexes[data_name] + or not skins_array[data_name] then + return -- Supplied invalid data + end + local index = indexes[data_name] + next_index local max = #skins_array[data_name] @@ -309,9 +380,9 @@ if fields.cancel then local temp = skin_temp[player] - player:set_attribute("character_creator:gender", temp.gender) - player:set_attribute("character_creator:width", temp.width) - player:set_attribute("character_creator:height", temp.height) + player_meta:set_string("character_creator:gender", temp.gender) + player_meta:set_float("character_creator:width", temp.width) + player_meta:set_float("character_creator:height", temp.height) skin_indexes[player] = table.copy(temp.indexes) skin_temp[player] = nil quit = true @@ -324,7 +395,6 @@ show_formspec(player) end end - change_skin(player) end) @@ -354,4 +424,10 @@ show_formspec(player) end end) -end \ No newline at end of file +elseif not skinsdb and minetest.get_modpath("sfinv_buttons") then + sfinv_buttons.register_button("character_creator", { + image = "inventory_plus_character_creator.png", + title = "Character Creator", + action = show_formspec, + }) +end diff --git a/mod.conf b/mod.conf index a01ea61..92ca239 100644 --- a/mod.conf +++ b/mod.conf @@ -1 +1,4 @@ -name = character_creator \ No newline at end of file +name = character_creator +description = Allows the creation of customized character skins inside the game. +license = MIT +optional_depends = 3d_armor, multiskin, inventory_plus, unified_inventory, skinsdb, sfinv_buttons