Merge pull request 'Add advanced skin customization' (#2607) from skins into master
Reviewed-on: MineClone2/MineClone2#2607 Reviewed-by: cora <cora@noreply.git.minetest.land>
|
@ -364,7 +364,8 @@ function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size,
|
||||||
-- Survival inventory slots
|
-- Survival inventory slots
|
||||||
main_list = "list[current_player;main;0,3.75;9,3;9]" ..
|
main_list = "list[current_player;main;0,3.75;9,3;9]" ..
|
||||||
mcl_formspec.get_itemslot_bg(0, 3.75, 9, 3) ..
|
mcl_formspec.get_itemslot_bg(0, 3.75, 9, 3) ..
|
||||||
-- armor
|
|
||||||
|
-- Armor
|
||||||
"list[current_player;armor;2.5,1.3;1,1;1]" ..
|
"list[current_player;armor;2.5,1.3;1,1;1]" ..
|
||||||
"list[current_player;armor;2.5,2.75;1,1;2]" ..
|
"list[current_player;armor;2.5,2.75;1,1;2]" ..
|
||||||
"list[current_player;armor;5.5,1.3;1,1;3]" ..
|
"list[current_player;armor;5.5,1.3;1,1;3]" ..
|
||||||
|
@ -376,26 +377,35 @@ function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size,
|
||||||
"list[current_player;offhand;1.5,2.025;1,1]" ..
|
"list[current_player;offhand;1.5,2.025;1,1]" ..
|
||||||
mcl_formspec.get_itemslot_bg(1.5, 2.025, 1, 1) ..
|
mcl_formspec.get_itemslot_bg(1.5, 2.025, 1, 1) ..
|
||||||
armor_slot_imgs ..
|
armor_slot_imgs ..
|
||||||
-- player preview
|
|
||||||
|
-- Player preview
|
||||||
mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "") ..
|
mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "") ..
|
||||||
-- crafting guide button
|
|
||||||
|
-- Crafting guide button
|
||||||
"image_button[9,1;1,1;craftguide_book.png;__mcl_craftguide;]" ..
|
"image_button[9,1;1,1;craftguide_book.png;__mcl_craftguide;]" ..
|
||||||
"tooltip[__mcl_craftguide;"..F(S("Recipe book")) .. "]" ..
|
"tooltip[__mcl_craftguide;"..F(S("Recipe book")) .. "]" ..
|
||||||
-- help button
|
|
||||||
|
-- Help button
|
||||||
"image_button[9,2;1,1;doc_button_icon_lores.png;__mcl_doc;]" ..
|
"image_button[9,2;1,1;doc_button_icon_lores.png;__mcl_doc;]" ..
|
||||||
"tooltip[__mcl_doc;" .. F(S("Help")) .. "]" ..
|
"tooltip[__mcl_doc;" .. F(S("Help")) .. "]" ..
|
||||||
-- skins button
|
|
||||||
"image_button[9,3;1,1;mcl_skins_button.png;__mcl_skins;]"..
|
-- Achievements button
|
||||||
"tooltip[__mcl_skins;"..F(S("Select player skin")).."]"..
|
"image_button[9,3;1,1;mcl_achievements_button.png;__mcl_achievements;]" ..
|
||||||
-- achievements button
|
|
||||||
"image_button[9,4;1,1;mcl_achievements_button.png;__mcl_achievements;]"..
|
|
||||||
--"style_type[image_button;border=;bgimg=;bgimg_pressed=]" ..
|
--"style_type[image_button;border=;bgimg=;bgimg_pressed=]" ..
|
||||||
"tooltip[__mcl_achievements;"..F(S("Achievements")) .. "]" ..
|
"tooltip[__mcl_achievements;"..F(S("Achievements")) .. "]" ..
|
||||||
-- switch stack size button
|
|
||||||
"image_button[9,5;1,1;default_apple.png;__switch_stack;]"..
|
-- Switch stack size button
|
||||||
"label[9.4,5.4;".. F(C("#FFFFFF", stack_size ~= 1 and stack_size or "")) .."]"..
|
"image_button[9,4;1,1;default_apple.png;__switch_stack;]" ..
|
||||||
|
"label[9.4,4.4;" .. F(C("#FFFFFF", stack_size ~= 1 and stack_size or "")) .. "]" ..
|
||||||
"tooltip[__switch_stack;" .. F(S("Switch stack size")) .. "]"
|
"tooltip[__switch_stack;" .. F(S("Switch stack size")) .. "]"
|
||||||
|
|
||||||
|
-- Skins button
|
||||||
|
if minetest.global_exists("mcl_skins") then
|
||||||
|
main_list = main_list ..
|
||||||
|
"image_button[9,5;1,1;mcl_skins_button.png;__mcl_skins;]" ..
|
||||||
|
"tooltip[__mcl_skins;"..F(S("Select player skin")) .. "]"
|
||||||
|
end
|
||||||
|
|
||||||
-- For shortcuts
|
-- For shortcuts
|
||||||
listrings = listrings ..
|
listrings = listrings ..
|
||||||
"listring[detached:"..playername.."_armor;armor]"..
|
"listring[detached:"..playername.."_armor;armor]"..
|
||||||
|
|
|
@ -75,7 +75,8 @@ local function set_inventory(player, armor_change_only)
|
||||||
local form = "size[9,8.75]" ..
|
local form = "size[9,8.75]" ..
|
||||||
"background[-0.19,-0.25;9.41,9.49;crafting_formspec_bg.png]" ..
|
"background[-0.19,-0.25;9.41,9.49;crafting_formspec_bg.png]" ..
|
||||||
mcl_player.get_player_formspec_model(player, 1.0, 0.0, 2.25, 4.5, "") ..
|
mcl_player.get_player_formspec_model(player, 1.0, 0.0, 2.25, 4.5, "") ..
|
||||||
--armor
|
|
||||||
|
-- Armor
|
||||||
"list[current_player;armor;0,0;1,1;1]" ..
|
"list[current_player;armor;0,0;1,1;1]" ..
|
||||||
"list[current_player;armor;0,1;1,1;2]" ..
|
"list[current_player;armor;0,1;1,1;2]" ..
|
||||||
"list[current_player;armor;0,2;1,1;3]" ..
|
"list[current_player;armor;0,2;1,1;3]" ..
|
||||||
|
@ -87,7 +88,8 @@ local function set_inventory(player, armor_change_only)
|
||||||
"list[current_player;offhand;3,2;1,1]" ..
|
"list[current_player;offhand;3,2;1,1]" ..
|
||||||
mcl_formspec.get_itemslot_bg(3,2,1,1) ..
|
mcl_formspec.get_itemslot_bg(3,2,1,1) ..
|
||||||
armor_slot_imgs ..
|
armor_slot_imgs ..
|
||||||
-- craft and inventory
|
|
||||||
|
-- Craft and inventory
|
||||||
"label[0,4;"..F(minetest.colorize("#313131", S("Inventory"))) .. "]" ..
|
"label[0,4;"..F(minetest.colorize("#313131", S("Inventory"))) .. "]" ..
|
||||||
"list[current_player;main;0,4.5;9,3;9]" ..
|
"list[current_player;main;0,4.5;9,3;9]" ..
|
||||||
"list[current_player;main;0,7.74;9,1;]" ..
|
"list[current_player;main;0,7.74;9,1;]" ..
|
||||||
|
@ -98,24 +100,34 @@ local function set_inventory(player, armor_change_only)
|
||||||
mcl_formspec.get_itemslot_bg(0, 7.74, 9, 1) ..
|
mcl_formspec.get_itemslot_bg(0, 7.74, 9, 1) ..
|
||||||
mcl_formspec.get_itemslot_bg(4, 1,2, 2) ..
|
mcl_formspec.get_itemslot_bg(4, 1,2, 2) ..
|
||||||
mcl_formspec.get_itemslot_bg(7, 1.5, 1, 1) ..
|
mcl_formspec.get_itemslot_bg(7, 1.5, 1, 1) ..
|
||||||
-- crafting guide button
|
|
||||||
|
-- Crafting guide button
|
||||||
"image_button[4.5,3;1,1;craftguide_book.png;__mcl_craftguide;]" ..
|
"image_button[4.5,3;1,1;craftguide_book.png;__mcl_craftguide;]" ..
|
||||||
"tooltip[__mcl_craftguide;"..F(S("Recipe book")) .. "]" ..
|
"tooltip[__mcl_craftguide;"..F(S("Recipe book")) .. "]" ..
|
||||||
-- help button
|
|
||||||
|
-- Help button
|
||||||
"image_button[8,3;1,1;doc_button_icon_lores.png;__mcl_doc;]" ..
|
"image_button[8,3;1,1;doc_button_icon_lores.png;__mcl_doc;]" ..
|
||||||
"tooltip[__mcl_doc;"..F(S("Help")).."]"..
|
"tooltip[__mcl_doc;" .. F(S("Help")) .. "]"
|
||||||
-- skins button
|
|
||||||
|
-- Skins button
|
||||||
|
if minetest.global_exists("mcl_skins") then
|
||||||
|
form = form ..
|
||||||
"image_button[3,3;1,1;mcl_skins_button.png;__mcl_skins;]" ..
|
"image_button[3,3;1,1;mcl_skins_button.png;__mcl_skins;]" ..
|
||||||
"tooltip[__mcl_skins;"..F(S("Select player skin")).."]"..
|
"tooltip[__mcl_skins;" .. F(S("Select player skin")) .. "]"
|
||||||
-- achievements button
|
end
|
||||||
|
|
||||||
|
form = form ..
|
||||||
|
-- Achievements button
|
||||||
"image_button[7,3;1,1;mcl_achievements_button.png;__mcl_achievements;]" ..
|
"image_button[7,3;1,1;mcl_achievements_button.png;__mcl_achievements;]" ..
|
||||||
"tooltip[__mcl_achievements;" .. F(S("Achievements")) .. "]" ..
|
"tooltip[__mcl_achievements;" .. F(S("Achievements")) .. "]" ..
|
||||||
-- for shortcuts
|
|
||||||
|
-- For shortcuts
|
||||||
"listring[current_player;main]" ..
|
"listring[current_player;main]" ..
|
||||||
"listring[current_player;armor]" ..
|
"listring[current_player;armor]" ..
|
||||||
"listring[current_player;main]" ..
|
"listring[current_player;main]" ..
|
||||||
"listring[current_player;craft]" ..
|
"listring[current_player;craft]" ..
|
||||||
"listring[current_player;main]"
|
"listring[current_player;main]"
|
||||||
|
|
||||||
player:set_inventory_formspec(form)
|
player:set_inventory_formspec(form)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -229,17 +229,31 @@ filled_wield_def.range = minetest.registered_items[""].range
|
||||||
filled_wield_def.on_place = mcl_util.call_on_rightclick
|
filled_wield_def.on_place = mcl_util.call_on_rightclick
|
||||||
filled_wield_def._mcl_wieldview_item = "mcl_maps:filled_map"
|
filled_wield_def._mcl_wieldview_item = "mcl_maps:filled_map"
|
||||||
|
|
||||||
for _, texture in pairs(mcl_skins.list) do
|
local mcl_skins_enabled = minetest.global_exists("mcl_skins")
|
||||||
local def = table.copy(filled_wield_def)
|
|
||||||
def.tiles = {texture .. ".png"}
|
|
||||||
def.mesh = "mcl_meshhand.b3d"
|
|
||||||
def._mcl_hand_id = texture
|
|
||||||
minetest.register_node("mcl_maps:filled_map_" .. texture, def)
|
|
||||||
|
|
||||||
local female_def = table.copy(def)
|
if mcl_skins_enabled then
|
||||||
female_def.mesh = "mcl_meshhand_female.b3d"
|
-- Generate a node for every skin
|
||||||
female_def._mcl_hand_id = texture .. "_female"
|
local list = mcl_skins.get_skin_list()
|
||||||
minetest.register_node("mcl_maps:filled_map_" .. texture .. "_female", female_def)
|
for _, skin in pairs(list) do
|
||||||
|
if skin.slim_arms then
|
||||||
|
local female = table.copy(filled_wield_def)
|
||||||
|
female._mcl_hand_id = skin.id
|
||||||
|
female.mesh = "mcl_meshhand_female.b3d"
|
||||||
|
female.tiles = {skin.texture}
|
||||||
|
minetest.register_node("mcl_maps:filled_map_" .. skin.id, female)
|
||||||
|
else
|
||||||
|
local male = table.copy(filled_wield_def)
|
||||||
|
male._mcl_hand_id = skin.id
|
||||||
|
male.mesh = "mcl_meshhand.b3d"
|
||||||
|
male.tiles = {skin.texture}
|
||||||
|
minetest.register_node("mcl_maps:filled_map_" .. skin.id, male)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
filled_wield_def._mcl_hand_id = "hand"
|
||||||
|
filled_wield_def.mesh = "mcl_meshhand.b3d"
|
||||||
|
filled_wield_def.tiles = {"character.png"}
|
||||||
|
minetest.register_node("mcl_maps:filled_map_hand", filled_wield_def)
|
||||||
end
|
end
|
||||||
|
|
||||||
local old_add_item = minetest.add_item
|
local old_add_item = minetest.add_item
|
||||||
|
|
|
@ -1,76 +1,56 @@
|
||||||
local has_mcl_skins = minetest.get_modpath("mcl_skins") ~= nil
|
local mcl_skins_enabled = minetest.global_exists("mcl_skins")
|
||||||
|
|
||||||
local def = minetest.registered_items[""]
|
|
||||||
|
|
||||||
local list
|
|
||||||
-- mcl_skins is enabled
|
|
||||||
if has_mcl_skins == true then
|
|
||||||
list = mcl_skins.list
|
|
||||||
else
|
|
||||||
list = { "hand" }
|
|
||||||
end
|
|
||||||
|
|
||||||
--generate a node for every skin
|
|
||||||
for _,texture in pairs(list) do
|
|
||||||
-- This is a fake node that should never be placed in the world
|
-- This is a fake node that should never be placed in the world
|
||||||
minetest.register_node("mcl_meshhand:"..texture, {
|
local node_def = {
|
||||||
description = "",
|
description = "",
|
||||||
tiles = {texture..".png"},
|
|
||||||
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
|
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
|
||||||
visual_scale = 1,
|
visual_scale = 1,
|
||||||
wield_scale = {x=1,y=1,z=1},
|
wield_scale = {x=1,y=1,z=1},
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
drawtype = "mesh",
|
drawtype = "mesh",
|
||||||
mesh = "mcl_meshhand.b3d",
|
|
||||||
-- Prevent construction
|
|
||||||
node_placement_prediction = "",
|
node_placement_prediction = "",
|
||||||
on_construct = function(pos)
|
on_construct = function(pos)
|
||||||
minetest.log("error", "[mcl_meshhand] Trying to construct mcl_meshhand:"..texture.." at "..minetest.pos_to_string(pos))
|
local name = get_node(pos).name
|
||||||
|
local message = "[mcl_meshhand] Trying to construct " .. name .. " at " .. minetest.pos_to_string(pos)
|
||||||
|
minetest.log("error", message)
|
||||||
minetest.remove_node(pos)
|
minetest.remove_node(pos)
|
||||||
end,
|
end,
|
||||||
drop = "",
|
drop = "",
|
||||||
on_drop = function()
|
on_drop = function() return "" end,
|
||||||
return ""
|
|
||||||
end,
|
|
||||||
groups = { dig_immediate = 3, not_in_creative_inventory = 1 },
|
groups = { dig_immediate = 3, not_in_creative_inventory = 1 },
|
||||||
range = def.range,
|
range = minetest.registered_items[""].range
|
||||||
_mcl_hand_id = texture,
|
}
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_node("mcl_meshhand:"..texture.. "_female", {
|
if mcl_skins_enabled then
|
||||||
description = "",
|
-- Generate a node for every skin
|
||||||
tiles = {texture..".png"},
|
local list = mcl_skins.get_skin_list()
|
||||||
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
|
for _, skin in pairs(list) do
|
||||||
visual_scale = 1,
|
if skin.slim_arms then
|
||||||
wield_scale = {x=1,y=1,z=1},
|
local female = table.copy(node_def)
|
||||||
paramtype = "light",
|
female._mcl_hand_id = skin.id
|
||||||
drawtype = "mesh",
|
female.mesh = "mcl_meshhand_female.b3d"
|
||||||
mesh = "mcl_meshhand_female.b3d",
|
female.tiles = {skin.texture}
|
||||||
-- Prevent construction
|
minetest.register_node("mcl_meshhand:" .. skin.id, female)
|
||||||
node_placement_prediction = "",
|
|
||||||
on_construct = function(pos)
|
|
||||||
minetest.log("error", "[mcl_meshhand] Trying to construct mcl_meshhand:"..texture.." at "..minetest.pos_to_string(pos))
|
|
||||||
minetest.remove_node(pos)
|
|
||||||
end,
|
|
||||||
drop = "",
|
|
||||||
on_drop = function()
|
|
||||||
return ""
|
|
||||||
end,
|
|
||||||
groups = { dig_immediate = 3, not_in_creative_inventory = 1 },
|
|
||||||
range = def.range,
|
|
||||||
_mcl_hand_id = texture .. "_female",
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
if has_mcl_skins == true then
|
|
||||||
--change the player's hand to their skin
|
|
||||||
mcl_skins.register_on_set_skin(function(player, skin)
|
|
||||||
local meta = mcl_skins.meta[skin]
|
|
||||||
if meta.gender == "female" then
|
|
||||||
player:get_inventory():set_stack("hand", 1, "mcl_meshhand:"..skin.."_female")
|
|
||||||
else
|
else
|
||||||
player:get_inventory():set_stack("hand", 1, "mcl_meshhand:"..skin)
|
local male = table.copy(node_def)
|
||||||
|
male._mcl_hand_id = skin.id
|
||||||
|
male.mesh = "mcl_meshhand.b3d"
|
||||||
|
male.tiles = {skin.texture}
|
||||||
|
minetest.register_node("mcl_meshhand:" .. skin.id, male)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
node_def._mcl_hand_id = "hand"
|
||||||
|
node_def.mesh = "mcl_meshhand.b3d"
|
||||||
|
node_def.tiles = {"character.png"}
|
||||||
|
minetest.register_node("mcl_meshhand:hand", node_def)
|
||||||
|
end
|
||||||
|
|
||||||
|
if mcl_skins_enabled then
|
||||||
|
-- Change the player's hand to their skin
|
||||||
|
mcl_skins.register_on_set_skin(function(player)
|
||||||
|
local node_id = mcl_skins.get_node_id_by_player(player)
|
||||||
|
player:get_inventory():set_stack("hand", 1, "mcl_meshhand:" .. node_id)
|
||||||
end)
|
end)
|
||||||
else
|
else
|
||||||
minetest.register_on_joinplayer(function(player)
|
minetest.register_on_joinplayer(function(player)
|
||||||
|
|
|
@ -129,7 +129,7 @@ minetest.register_on_joinplayer(function(player)
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
mcl_player.player_attached[name] = false
|
mcl_player.player_attached[name] = false
|
||||||
mcl_player.player_set_model(player, "character.b3d")
|
mcl_player.player_set_model(player, "character.b3d")
|
||||||
player_textures[name] = {"blank.png", "blank.png", "blank.png"}
|
player_textures[name] = {"character.png", "blank.png", "blank.png"}
|
||||||
--player:set_local_animation({x=0, y=79}, {x=168, y=187}, {x=189, y=198}, {x=200, y=219}, 30)
|
--player:set_local_animation({x=0, y=79}, {x=168, y=187}, {x=189, y=198}, {x=200, y=219}, 30)
|
||||||
player:set_fov(86.1) -- see <https://minecraft.gamepedia.com/Options#Video_settings>>>>
|
player:set_fov(86.1) -- see <https://minecraft.gamepedia.com/Options#Video_settings>>>>
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
!textures/mcl_skins_character_1.png
|
|
||||||
textures/mcl_skins_character_*
|
|
||||||
!meta/mcl_skins_character_1.txt
|
|
||||||
meta/mcl_skins_character_*
|
|
|
@ -1,5 +1,6 @@
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2022 MrRar
|
||||||
Copyright (c) 2016 TenPlus1
|
Copyright (c) 2016 TenPlus1
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
|
|
@ -1,13 +1,84 @@
|
||||||
= Skins for MineClone 2 =
|
# Mineclone Skins
|
||||||
|
|
||||||
Simple mod to allow players to select a skin.
|
This mod allows advanced skin customization.
|
||||||
Use the chat command /setskin to change skin.
|
Use the /skin command to open the skin configuration screen.
|
||||||
|
|
||||||
Forked from Simple Skins by TenPlus1.
|
## License
|
||||||
https://forum.minetest.net/viewtopic.php?id=9100
|
|
||||||
|
|
||||||
== License ==
|
|
||||||
Code under MIT license
|
Code under MIT license
|
||||||
Origial authors:
|
Author: TenPlus1, Zeg9, MrRar
|
||||||
- TenPlus1
|
|
||||||
- Zeg9
|
See image_credits.txt for image licensing.
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
### `mcl_skins.register_item(item)`
|
||||||
|
Register a skin item. `item` is a table with item properties listed below.
|
||||||
|
|
||||||
|
### Item properties
|
||||||
|
`type`
|
||||||
|
Set the item type. Valid values are: "base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear"
|
||||||
|
|
||||||
|
`texture`
|
||||||
|
Set to the image file that will be used. If this property is omitted "blank.png" is used.
|
||||||
|
|
||||||
|
`mask`
|
||||||
|
Set the color mask texture. Coloring is only applied to non transparent areas of the texture.
|
||||||
|
Coloring only works for "base", "bottom, "top", and "hair".
|
||||||
|
|
||||||
|
`preview_rotation`
|
||||||
|
A table containing properties x and y. x and y represent the x and y rotation of the item preview.
|
||||||
|
|
||||||
|
`alex`
|
||||||
|
If set to true the item will be default for female character.
|
||||||
|
|
||||||
|
`steve`
|
||||||
|
If set to true the item will be default for male character.
|
||||||
|
|
||||||
|
|
||||||
|
### `mcl_skins.show_formspec(player, active_tab, page_num)`
|
||||||
|
Show the skin configuration screen.
|
||||||
|
`player` is a player ObjectRef.
|
||||||
|
`active_tab` is the tab that will be displayed. This parameter is optional.
|
||||||
|
Can be one of: "arm", "base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear"
|
||||||
|
|
||||||
|
`page_num` The page number to display of there are multiple pages of items.
|
||||||
|
This parameter is optional. Must be a number. If it is not a valid page number the closest page number will be shown.
|
||||||
|
|
||||||
|
### `mcl_skins.register_on_set_skin(func)`
|
||||||
|
Register a function to be called whenever a player skin changes.
|
||||||
|
The function will be given a player ObjectRef as a parameter.
|
||||||
|
|
||||||
|
### `mcl_skins.get_skin_list()`
|
||||||
|
This function is used by mods that want a list of skins to register nodes that use the player skin as a texture.
|
||||||
|
Returns an array of tables containing information about each skin.
|
||||||
|
Each table contains the following properties:
|
||||||
|
|
||||||
|
`id`: A string representing the node ID. A node can be registered using this node ID.
|
||||||
|
`texture`: A texture string that can be used in the node defintion.
|
||||||
|
`slim_arms`: A boolean value. If true, this texture is used with the "female" player mesh. Otherwise the regular mesh is to be used.
|
||||||
|
|
||||||
|
### `mcl_skins.get_node_id_by_player(player)`
|
||||||
|
`player` is a player ObjectRef.
|
||||||
|
Returns a string node ID based on players current skin for use by mods that want to register nodes that use the player skin.
|
||||||
|
|
||||||
|
### `mcl_skins.save(player)`
|
||||||
|
Save player skin. `player` is a player ObjectRef.
|
||||||
|
|
||||||
|
### `mcl_skins.update_player_skin(player)`
|
||||||
|
Update a player based on skin data in mcl_skins.players.
|
||||||
|
`player` is a player ObjectRef.
|
||||||
|
|
||||||
|
### `mcl_skins.base_color`
|
||||||
|
A table of ColorSpec integers that the player can select to color the base item.
|
||||||
|
These colors are separate from `mcl_skins.color` because some mods register two nodes per base color so the amount of base colors needs to be limited.
|
||||||
|
|
||||||
|
### `mcl_skins.color`
|
||||||
|
A table of ColorSpec integers that the player can select to color colorable skin items.
|
||||||
|
|
||||||
|
### `mcl_skins.players`
|
||||||
|
A table mapped by player ObjectRef containing tables holding the player's selected skin items and colors.
|
||||||
|
Only stores skin information for logged in users.
|
||||||
|
|
||||||
|
### mcl_skins.compile_skin(skin)
|
||||||
|
`skin` is a table with skin item properties.
|
||||||
|
Returns an image string.
|
||||||
|
|
|
@ -0,0 +1,602 @@
|
||||||
|
local S = minetest.get_translator("mcl_skins")
|
||||||
|
local color_to_string = minetest.colorspec_to_colorstring
|
||||||
|
|
||||||
|
mcl_skins = {
|
||||||
|
simple_skins = {},
|
||||||
|
item_names = {"base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear"},
|
||||||
|
tab_names = {"template", "base", "headwear", "hair", "eye", "mouth", "top", "arm", "bottom", "footwear"},
|
||||||
|
tab_descriptions = {
|
||||||
|
template = S("Templates"),
|
||||||
|
arm = S("Arm size"),
|
||||||
|
base = S("Bases"),
|
||||||
|
footwear = S("Footwears"),
|
||||||
|
eye = S("Eyes"),
|
||||||
|
mouth = S("Mouths"),
|
||||||
|
bottom = S("Bottoms"),
|
||||||
|
top = S("Tops"),
|
||||||
|
hair = S("Hairs"),
|
||||||
|
headwear = S("Headwears"),
|
||||||
|
skin = S("Skins"),
|
||||||
|
},
|
||||||
|
steve = {}, -- Stores skin values for Steve skin
|
||||||
|
alex = {}, -- Stores skin values for Alex skin
|
||||||
|
base = {}, -- List of base textures
|
||||||
|
|
||||||
|
-- Base color is separate to keep the number of junk nodes registered in check
|
||||||
|
base_color = {0xffeeb592, 0xffb47a57, 0xff8d471d},
|
||||||
|
color = {
|
||||||
|
0xff613915, -- 1 Dark brown Steve hair, Alex bottom
|
||||||
|
0xff97491b, -- 2 Medium brown
|
||||||
|
0xffb17050, -- 3 Light brown
|
||||||
|
0xffe2bc7b, -- 4 Beige
|
||||||
|
0xff706662, -- 5 Gray
|
||||||
|
0xff151515, -- 6 Black
|
||||||
|
0xffc21c1c, -- 7 Red
|
||||||
|
0xff178c32, -- 8 Green Alex top
|
||||||
|
0xffae2ad3, -- 9 Plum
|
||||||
|
0xffebe8e4, -- 10 White
|
||||||
|
0xffe3dd26, -- 11 Yellow
|
||||||
|
0xff449acc, -- 12 Light blue Steve top
|
||||||
|
0xff124d87, -- 13 Dark blue Steve bottom
|
||||||
|
0xfffc0eb3, -- 14 Pink
|
||||||
|
0xffd0672a, -- 15 Orange Alex hair
|
||||||
|
},
|
||||||
|
footwear = {},
|
||||||
|
mouth = {},
|
||||||
|
eye = {},
|
||||||
|
bottom = {},
|
||||||
|
top = {},
|
||||||
|
hair = {},
|
||||||
|
headwear = {},
|
||||||
|
masks = {},
|
||||||
|
preview_rotations = {},
|
||||||
|
players = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mcl_skins.register_item(item)
|
||||||
|
assert(mcl_skins[item.type], "Skin item type " .. item.type .. " does not exist.")
|
||||||
|
local texture = item.texture or "blank.png"
|
||||||
|
if item.steve then
|
||||||
|
mcl_skins.steve[item.type] = texture
|
||||||
|
end
|
||||||
|
|
||||||
|
if item.alex then
|
||||||
|
mcl_skins.alex[item.type] = texture
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(mcl_skins[item.type], texture)
|
||||||
|
mcl_skins.masks[texture] = item.mask
|
||||||
|
if item.preview_rotation then
|
||||||
|
mcl_skins.preview_rotations[texture] = item.preview_rotation
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function mcl_skins.save(player)
|
||||||
|
local skin = mcl_skins.players[player]
|
||||||
|
if not skin then return end
|
||||||
|
|
||||||
|
local meta = player:get_meta()
|
||||||
|
meta:set_string("mcl_skins:skin", minetest.serialize(skin))
|
||||||
|
|
||||||
|
meta:set_string("mcl_skins:skin_id", tostring(skin.simple_skins_id or ""))
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_chatcommand("skin", {
|
||||||
|
description = S("Open skin configuration screen."),
|
||||||
|
privs = {},
|
||||||
|
func = function(name, param) mcl_skins.show_formspec(minetest.get_player_by_name(name)) end
|
||||||
|
})
|
||||||
|
|
||||||
|
function mcl_skins.compile_skin(skin)
|
||||||
|
if skin.simple_skins_id then
|
||||||
|
return mcl_skins.simple_skins[skin.simple_skins_id].texture
|
||||||
|
end
|
||||||
|
|
||||||
|
local output = ""
|
||||||
|
for i, item in pairs(mcl_skins.item_names) do
|
||||||
|
local texture = skin[item]
|
||||||
|
if texture and texture ~= "blank.png" then
|
||||||
|
|
||||||
|
if skin[item .. "_color"] and mcl_skins.masks[texture] then
|
||||||
|
if #output > 0 then output = output .. "^" end
|
||||||
|
local color = color_to_string(skin[item .. "_color"])
|
||||||
|
output = output ..
|
||||||
|
"(" .. mcl_skins.masks[texture] .. "^[colorize:" .. color .. ":alpha)"
|
||||||
|
end
|
||||||
|
if #output > 0 then output = output .. "^" end
|
||||||
|
output = output .. texture
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return output
|
||||||
|
end
|
||||||
|
|
||||||
|
function mcl_skins.update_player_skin(player)
|
||||||
|
if not player then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local skin = mcl_skins.players[player]
|
||||||
|
|
||||||
|
mcl_player.player_set_skin(player, mcl_skins.compile_skin(skin))
|
||||||
|
|
||||||
|
local slim_arms
|
||||||
|
if skin.simple_skins_id then
|
||||||
|
slim_arms = mcl_skins.simple_skins[skin.simple_skins_id].slim_arms
|
||||||
|
else
|
||||||
|
slim_arms = skin.slim_arms
|
||||||
|
end
|
||||||
|
local model = slim_arms and "mcl_armor_character_female.b3d" or "mcl_armor_character.b3d"
|
||||||
|
mcl_player.player_set_model(player, model)
|
||||||
|
|
||||||
|
mcl_inventory.update_inventory_formspec(player)
|
||||||
|
|
||||||
|
for i=1, #mcl_skins.registered_on_set_skins do
|
||||||
|
mcl_skins.registered_on_set_skins[i](player)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Load player skin on join
|
||||||
|
minetest.register_on_joinplayer(function(player)
|
||||||
|
local function table_get_random(t)
|
||||||
|
return t[math.random(#t)]
|
||||||
|
end
|
||||||
|
local skin = player:get_meta():get_string("mcl_skins:skin")
|
||||||
|
if skin then
|
||||||
|
skin = minetest.deserialize(skin)
|
||||||
|
end
|
||||||
|
if skin then
|
||||||
|
mcl_skins.players[player] = skin
|
||||||
|
else
|
||||||
|
if math.random() > 0.5 then
|
||||||
|
skin = table.copy(mcl_skins.steve)
|
||||||
|
else
|
||||||
|
skin = table.copy(mcl_skins.alex)
|
||||||
|
end
|
||||||
|
mcl_skins.players[player] = skin
|
||||||
|
end
|
||||||
|
|
||||||
|
mcl_skins.players[player].simple_skins_id = nil
|
||||||
|
if #mcl_skins.simple_skins > 0 then
|
||||||
|
local skin_id = tonumber(player:get_meta():get_string("mcl_skins:skin_id"))
|
||||||
|
if skin_id and mcl_skins.simple_skins[skin_id] then
|
||||||
|
mcl_skins.players[player].simple_skins_id = skin_id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
mcl_skins.save(player)
|
||||||
|
mcl_skins.update_player_skin(player)
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_on_leaveplayer(function(player)
|
||||||
|
mcl_skins.players[player] = nil
|
||||||
|
end)
|
||||||
|
|
||||||
|
mcl_skins.registered_on_set_skins = {}
|
||||||
|
|
||||||
|
function mcl_skins.register_on_set_skin(func)
|
||||||
|
table.insert(mcl_skins.registered_on_set_skins, func)
|
||||||
|
end
|
||||||
|
|
||||||
|
function mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
|
local skin = mcl_skins.players[player]
|
||||||
|
local default = #mcl_skins.simple_skins > 0 and "skin" or "template"
|
||||||
|
active_tab = active_tab or default
|
||||||
|
page_num = page_num or 1
|
||||||
|
|
||||||
|
local page_count
|
||||||
|
if page_num < 1 then page_num = 1 end
|
||||||
|
if mcl_skins[active_tab] then
|
||||||
|
page_count = math.ceil(#mcl_skins[active_tab] / 16)
|
||||||
|
if page_num > page_count then
|
||||||
|
page_num = page_count
|
||||||
|
end
|
||||||
|
elseif active_tab == "skin" then
|
||||||
|
page_count = math.ceil((#mcl_skins.simple_skins + 2) / 8)
|
||||||
|
if page_num > page_count then
|
||||||
|
page_num = page_count
|
||||||
|
end
|
||||||
|
else
|
||||||
|
page_num = 1
|
||||||
|
page_count = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local formspec = "formspec_version[3]size[13.2,11]"
|
||||||
|
|
||||||
|
for i, tab in pairs(mcl_skins.tab_names) do
|
||||||
|
if tab == active_tab then
|
||||||
|
formspec = formspec ..
|
||||||
|
"style[" .. tab .. ";bgcolor=green]"
|
||||||
|
end
|
||||||
|
|
||||||
|
local y = 0.3 + (i - 1) * 0.8
|
||||||
|
formspec = formspec ..
|
||||||
|
"button[0.3," .. y .. ";3,0.8;" .. tab .. ";" .. mcl_skins.tab_descriptions[tab] .. "]"
|
||||||
|
|
||||||
|
if skin.simple_skins_id then break end
|
||||||
|
end
|
||||||
|
|
||||||
|
local slim_arms
|
||||||
|
if skin.simple_skins_id then
|
||||||
|
slim_arms = mcl_skins.simple_skins[skin.simple_skins_id].slim_arms
|
||||||
|
else
|
||||||
|
slim_arms = skin.slim_arms
|
||||||
|
end
|
||||||
|
local mesh = slim_arms and "mcl_armor_character_female.b3d" or "mcl_armor_character.b3d"
|
||||||
|
|
||||||
|
formspec = formspec ..
|
||||||
|
"model[10,0.3;3,7;player_mesh;" .. mesh .. ";" ..
|
||||||
|
mcl_skins.compile_skin(skin) ..
|
||||||
|
",blank.png,blank.png;0,180;false;true;0,0;0]"
|
||||||
|
|
||||||
|
if active_tab == "skin" then
|
||||||
|
local page_start = (page_num - 1) * 8 - 1
|
||||||
|
local page_end = math.min(page_start + 8 - 1, #mcl_skins.simple_skins)
|
||||||
|
formspec = formspec ..
|
||||||
|
"style_type[button;bgcolor=#00000000]"
|
||||||
|
|
||||||
|
local skin = table.copy(skin)
|
||||||
|
skin_id = skin.simple_skins_id or -1
|
||||||
|
skin.simple_skins_id = nil
|
||||||
|
|
||||||
|
local skins = table.copy(mcl_skins.simple_skins)
|
||||||
|
skins[-1] = {
|
||||||
|
slim_arms = skin.slim_arms,
|
||||||
|
texture = mcl_skins.compile_skin(skin),
|
||||||
|
}
|
||||||
|
|
||||||
|
for i = page_start, page_end do
|
||||||
|
local skin = skins[i]
|
||||||
|
local j = i - page_start - 1
|
||||||
|
local mesh = skin.slim_arms and "mcl_armor_character_female.b3d" or "mcl_armor_character.b3d"
|
||||||
|
|
||||||
|
local x = 3.5 + (j + 1) % 4 * 1.6
|
||||||
|
local y = 0.3 + math.floor((j + 1) / 4) * 3.1
|
||||||
|
|
||||||
|
formspec = formspec ..
|
||||||
|
"model[" .. x .. "," .. y .. ";1.5,3;player_mesh;" .. mesh .. ";" ..
|
||||||
|
skin.texture ..
|
||||||
|
",blank.png,blank.png;0,180;false;true;0,0;0]"
|
||||||
|
|
||||||
|
if skin_id == i then
|
||||||
|
formspec = formspec ..
|
||||||
|
"style[" .. i ..
|
||||||
|
";bgcolor=;bgimg=mcl_skins_select_overlay.png;" ..
|
||||||
|
"bgimg_pressed=mcl_skins_select_overlay.png;bgimg_middle=14,14]"
|
||||||
|
end
|
||||||
|
formspec = formspec ..
|
||||||
|
"button[" .. x .. "," .. y .. ";1.5,3;" .. i .. ";]"
|
||||||
|
end
|
||||||
|
|
||||||
|
if page_start == -1 then
|
||||||
|
formspec = formspec .. "image[3.85,1;0.8,0.8;mcl_skins_button.png]"
|
||||||
|
end
|
||||||
|
elseif active_tab == "template" then
|
||||||
|
formspec = formspec ..
|
||||||
|
"model[4,2;2,3;player_mesh;mcl_armor_character.b3d;" ..
|
||||||
|
mcl_skins.compile_skin(mcl_skins.steve) ..
|
||||||
|
",blank.png,blank.png;0,180;false;true;0,0;0]" ..
|
||||||
|
|
||||||
|
"button[4,5.2;2,0.8;steve;" .. S("Select") .. "]" ..
|
||||||
|
|
||||||
|
"model[6.5,2;2,3;player_mesh;mcl_armor_character_female.b3d;" ..
|
||||||
|
mcl_skins.compile_skin(mcl_skins.alex) ..
|
||||||
|
",blank.png,blank.png;0,180;false;true;0,0;0]" ..
|
||||||
|
|
||||||
|
"button[6.5,5.2;2,0.8;alex;" .. S("Select") .. "]"
|
||||||
|
|
||||||
|
elseif mcl_skins[active_tab] then
|
||||||
|
formspec = formspec ..
|
||||||
|
"style_type[button;bgcolor=#00000000]"
|
||||||
|
local textures = mcl_skins[active_tab]
|
||||||
|
local page_start = (page_num - 1) * 16 + 1
|
||||||
|
local page_end = math.min(page_start + 16 - 1, #textures)
|
||||||
|
|
||||||
|
for j = page_start, page_end do
|
||||||
|
local i = j - page_start + 1
|
||||||
|
local texture = textures[j]
|
||||||
|
local preview = mcl_skins.masks[skin.base] .. "^[colorize:gray^" .. skin.base
|
||||||
|
local color = color_to_string(skin[active_tab .. "_color"])
|
||||||
|
local mask = mcl_skins.masks[texture]
|
||||||
|
if color and mask then
|
||||||
|
preview = preview .. "^(" .. mask .. "^[colorize:" .. color .. ":alpha)"
|
||||||
|
end
|
||||||
|
preview = preview .. "^" .. texture
|
||||||
|
|
||||||
|
local mesh = "mcl_skins_head.obj"
|
||||||
|
if active_tab == "top" then
|
||||||
|
mesh = "mcl_skins_top.obj"
|
||||||
|
elseif active_tab == "bottom" or active_tab == "footwear" then
|
||||||
|
mesh = "mcl_skins_bottom.obj"
|
||||||
|
end
|
||||||
|
|
||||||
|
local rot_x = -10
|
||||||
|
local rot_y = 20
|
||||||
|
if mcl_skins.preview_rotations[texture] then
|
||||||
|
rot_x = mcl_skins.preview_rotations[texture].x
|
||||||
|
rot_y = mcl_skins.preview_rotations[texture].y
|
||||||
|
end
|
||||||
|
|
||||||
|
i = i - 1
|
||||||
|
local x = 3.5 + i % 4 * 1.6
|
||||||
|
local y = 0.3 + math.floor(i / 4) * 1.6
|
||||||
|
formspec = formspec ..
|
||||||
|
"model[" .. x .. "," .. y ..
|
||||||
|
";1.5,1.5;" .. mesh .. ";" .. mesh .. ";" ..
|
||||||
|
preview ..
|
||||||
|
";" .. rot_x .. "," .. rot_y .. ";false;false;0,0;0]"
|
||||||
|
|
||||||
|
if skin[active_tab] == texture then
|
||||||
|
formspec = formspec ..
|
||||||
|
"style[" .. texture ..
|
||||||
|
";bgcolor=;bgimg=mcl_skins_select_overlay.png;" ..
|
||||||
|
"bgimg_pressed=mcl_skins_select_overlay.png;bgimg_middle=14,14]"
|
||||||
|
end
|
||||||
|
formspec = formspec .. "button[" .. x .. "," .. y .. ";1.5,1.5;" .. texture .. ";]"
|
||||||
|
end
|
||||||
|
elseif active_tab == "arm" then
|
||||||
|
local x = skin.slim_arms and 4.7 or 3.6
|
||||||
|
formspec = formspec ..
|
||||||
|
"image_button[3.6,0.3;1,1;mcl_skins_thick_arms.png;thick_arms;]" ..
|
||||||
|
"image_button[4.7,0.3;1,1;mcl_skins_slim_arms.png;slim_arms;]" ..
|
||||||
|
"style[arm;bgcolor=;bgimg=mcl_skins_select_overlay.png;bgimg_middle=14,14;bgimg_pressed=mcl_skins_select_overlay.png]" ..
|
||||||
|
"button[" .. x .. ",0.3;1,1;arm;]"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if skin[active_tab .. "_color"] then
|
||||||
|
local colors = mcl_skins.color
|
||||||
|
if active_tab == "base" then colors = mcl_skins.base_color end
|
||||||
|
|
||||||
|
local tab_color = active_tab .. "_color"
|
||||||
|
local selected_color = skin[tab_color]
|
||||||
|
for i, colorspec in pairs(colors) do
|
||||||
|
local color = color_to_string(colorspec)
|
||||||
|
i = i - 1
|
||||||
|
local x = 3.6 + i % 6 * 0.9
|
||||||
|
local y = 8 + math.floor(i / 6) * 0.9
|
||||||
|
formspec = formspec ..
|
||||||
|
"image_button[" .. x .. "," .. y ..
|
||||||
|
";0.8,0.8;blank.png^[noalpha^[colorize:" ..
|
||||||
|
color .. ":alpha;" .. colorspec .. ";]"
|
||||||
|
|
||||||
|
if selected_color == colorspec then
|
||||||
|
formspec = formspec ..
|
||||||
|
"style[" .. color ..
|
||||||
|
";bgcolor=;bgimg=mcl_skins_select_overlay.png;bgimg_middle=14,14;bgimg_pressed=mcl_skins_select_overlay.png]" ..
|
||||||
|
"button[" .. x .. "," .. y .. ";0.8,0.8;" .. color .. ";]"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
if not (active_tab == "base") then
|
||||||
|
-- Bitwise Operations !?!?!
|
||||||
|
local red = math.floor(selected_color / 0x10000) - 0xff00
|
||||||
|
local green = math.floor(selected_color / 0x100) - 0xff0000 - red * 0x100
|
||||||
|
local blue = selected_color - 0xff000000 - red * 0x10000 - green * 0x100
|
||||||
|
formspec = formspec ..
|
||||||
|
"container[9.2,8]" ..
|
||||||
|
"scrollbaroptions[min=0;max=255;smallstep=20]" ..
|
||||||
|
|
||||||
|
"box[0.4,0;2.49,0.38;red]" ..
|
||||||
|
"label[0.2,0.2;-]" ..
|
||||||
|
"scrollbar[0.4,0;2.5,0.4;horizontal;red;" .. red .."]" ..
|
||||||
|
"label[2.9,0.2;+]" ..
|
||||||
|
|
||||||
|
"box[0.4,0.6;2.49,0.38;green]" ..
|
||||||
|
"label[0.2,0.8;-]" ..
|
||||||
|
"scrollbar[0.4,0.6;2.5,0.4;horizontal;green;" .. green .."]" ..
|
||||||
|
"label[2.9,0.8;+]" ..
|
||||||
|
|
||||||
|
"box[0.4,1.2;2.49,0.38;blue]" ..
|
||||||
|
"label[0.2,1.4;-]" ..
|
||||||
|
"scrollbar[0.4,1.2;2.5,0.4;horizontal;blue;" .. blue .. "]" ..
|
||||||
|
"label[2.9,1.4;+]" ..
|
||||||
|
|
||||||
|
"container_end[]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if page_num > 1 then
|
||||||
|
formspec = formspec ..
|
||||||
|
"image_button[3.5,6.7;1,1;mcl_skins_arrow.png^[transformFX;previous_page;]"
|
||||||
|
end
|
||||||
|
|
||||||
|
if page_num < page_count then
|
||||||
|
formspec = formspec ..
|
||||||
|
"image_button[8.8,6.7;1,1;mcl_skins_arrow.png;next_page;]"
|
||||||
|
end
|
||||||
|
|
||||||
|
if page_count > 1 then
|
||||||
|
formspec = formspec ..
|
||||||
|
"label[6.3,7.2;" .. page_num .. " / " .. page_count .. "]"
|
||||||
|
end
|
||||||
|
|
||||||
|
local player_name = player:get_player_name()
|
||||||
|
minetest.show_formspec(player_name, "mcl_skins:" .. active_tab .. "_" .. page_num, formspec)
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
|
if fields.__mcl_skins then
|
||||||
|
mcl_skins.show_formspec(player)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if not formname:find("^mcl_skins:") then return false end
|
||||||
|
local _, _, active_tab, page_num = formname:find("^mcl_skins:(%a+)_(%d+)")
|
||||||
|
|
||||||
|
local active_tab_found = false
|
||||||
|
for _, tab in pairs(mcl_skins.tab_names) do
|
||||||
|
if tab == active_tab then active_tab_found = true end
|
||||||
|
end
|
||||||
|
active_tab = active_tab_found and active_tab or "template"
|
||||||
|
|
||||||
|
if not page_num or not active_tab then return true end
|
||||||
|
page_num = math.floor(tonumber(page_num) or 1)
|
||||||
|
|
||||||
|
-- Cancel formspec resend after scrollbar move
|
||||||
|
if mcl_skins.players[player].form_send_job then
|
||||||
|
mcl_skins.players[player].form_send_job:cancel()
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.quit then
|
||||||
|
mcl_skins.save(player)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.alex then
|
||||||
|
mcl_skins.players[player] = table.copy(mcl_skins.alex)
|
||||||
|
mcl_skins.update_player_skin(player)
|
||||||
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
|
return true
|
||||||
|
elseif fields.steve then
|
||||||
|
mcl_skins.players[player] = table.copy(mcl_skins.steve)
|
||||||
|
mcl_skins.update_player_skin(player)
|
||||||
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, tab in pairs(mcl_skins.tab_names) do
|
||||||
|
if fields[tab] then
|
||||||
|
mcl_skins.show_formspec(player, tab, page_num)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local skin = mcl_skins.players[player]
|
||||||
|
if not skin then return true end
|
||||||
|
|
||||||
|
if fields.next_page then
|
||||||
|
page_num = page_num + 1
|
||||||
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
|
return true
|
||||||
|
elseif fields.previous_page then
|
||||||
|
page_num = page_num - 1
|
||||||
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if active_tab == "arm" then
|
||||||
|
if fields.thick_arms then
|
||||||
|
skin.slim_arms = false
|
||||||
|
elseif fields.slim_arms then
|
||||||
|
skin.slim_arms = true
|
||||||
|
end
|
||||||
|
mcl_skins.update_player_skin(player)
|
||||||
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if
|
||||||
|
skin[active_tab .. "_color"] and (
|
||||||
|
fields.red and fields.red:find("^CHG") or
|
||||||
|
fields.green and fields.green:find("^CHG") or
|
||||||
|
fields.blue and fields.blue:find("^CHG")
|
||||||
|
)
|
||||||
|
then
|
||||||
|
local red = fields.red:gsub("%a%a%a:", "")
|
||||||
|
local green = fields.green:gsub("%a%a%a:", "")
|
||||||
|
local blue = fields.blue:gsub("%a%a%a:", "")
|
||||||
|
red = tonumber(red) or 0
|
||||||
|
green = tonumber(green) or 0
|
||||||
|
blue = tonumber(blue) or 0
|
||||||
|
|
||||||
|
local color = 0xff000000 + red * 0x10000 + green * 0x100 + blue
|
||||||
|
if color >= 0 and color <= 0xffffffff then
|
||||||
|
-- We delay resedning the form because otherwise it will break dragging scrollbars
|
||||||
|
mcl_skins.players[player].form_send_job = minetest.after(0.2, function()
|
||||||
|
if player and player:is_player() then
|
||||||
|
skin[active_tab .. "_color"] = color
|
||||||
|
mcl_skins.update_player_skin(player)
|
||||||
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
|
mcl_skins.players[player].form_send_job = nil
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local field
|
||||||
|
for f, value in pairs(fields) do
|
||||||
|
if value == "" then
|
||||||
|
field = f
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if field and active_tab == "skin" then
|
||||||
|
local skin_id = tonumber(field)
|
||||||
|
skin_id = skin_id and math.floor(skin_id) or 0
|
||||||
|
if
|
||||||
|
#mcl_skins.simple_skins > 0 and
|
||||||
|
skin_id >= -1 and skin_id <= #mcl_skins.simple_skins
|
||||||
|
then
|
||||||
|
if skin_id == -1 then skin_id = nil end
|
||||||
|
skin.simple_skins_id = skin_id
|
||||||
|
mcl_skins.update_player_skin(player)
|
||||||
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- See if field is a texture
|
||||||
|
if field and mcl_skins[active_tab] then
|
||||||
|
for i, texture in pairs(mcl_skins[active_tab]) do
|
||||||
|
if texture == field then
|
||||||
|
skin[active_tab] = texture
|
||||||
|
mcl_skins.update_player_skin(player)
|
||||||
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- See if field is a color
|
||||||
|
local number = tonumber(field)
|
||||||
|
if number and skin[active_tab .. "_color"] then
|
||||||
|
local color = math.floor(number)
|
||||||
|
if color and color >= 0 and color <= 0xffffffff then
|
||||||
|
skin[active_tab .. "_color"] = color
|
||||||
|
mcl_skins.update_player_skin(player)
|
||||||
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
|
||||||
|
local function init()
|
||||||
|
local function file_exists(name)
|
||||||
|
local f = io.open(name)
|
||||||
|
if not f then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
f:close()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local f = io.open(minetest.get_modpath("mcl_skins") .. "/list.json")
|
||||||
|
assert(f, "Can't open the file list.json")
|
||||||
|
local data = f:read("*all")
|
||||||
|
assert(data, "Can't read data from list.json")
|
||||||
|
local json, error = minetest.parse_json(data)
|
||||||
|
assert(json, error)
|
||||||
|
f:close()
|
||||||
|
|
||||||
|
for _, item in pairs(json) do
|
||||||
|
mcl_skins.register_item(item)
|
||||||
|
end
|
||||||
|
mcl_skins.steve.base_color = mcl_skins.base_color[1]
|
||||||
|
mcl_skins.steve.hair_color = mcl_skins.color[1]
|
||||||
|
mcl_skins.steve.top_color = mcl_skins.color[12]
|
||||||
|
mcl_skins.steve.bottom_color = mcl_skins.color[13]
|
||||||
|
mcl_skins.steve.slim_arms = false
|
||||||
|
|
||||||
|
mcl_skins.alex.base_color = mcl_skins.base_color[1]
|
||||||
|
mcl_skins.alex.hair_color = mcl_skins.color[15]
|
||||||
|
mcl_skins.alex.top_color = mcl_skins.color[8]
|
||||||
|
mcl_skins.alex.bottom_color = mcl_skins.color[1]
|
||||||
|
mcl_skins.alex.slim_arms = true
|
||||||
|
end
|
||||||
|
|
||||||
|
init()
|
|
@ -1,280 +1,8 @@
|
||||||
-- Skins for MineClone 2
|
local mod_path = minetest.get_modpath(minetest.get_current_modname())
|
||||||
|
|
||||||
local modname = minetest.get_current_modname()
|
local mcl_skins_enabled = minetest.settings:get_bool("mcl_enable_skin_customization", true)
|
||||||
|
if mcl_skins_enabled then
|
||||||
mcl_skins = {
|
dofile(mod_path .. "/edit_skin.lua")
|
||||||
skins = {}, list = {}, meta = {},
|
dofile(mod_path .. "/simple_skins.lua")
|
||||||
modpath = minetest.get_modpath(modname),
|
dofile(mod_path .. "/mesh_hand.lua")
|
||||||
skin_count = 0, -- counter of _custom_ skins (all skins except character.png)
|
|
||||||
}
|
|
||||||
|
|
||||||
local S = minetest.get_translator(modname)
|
|
||||||
local has_mcl_inventory = minetest.get_modpath("mcl_inventory")
|
|
||||||
|
|
||||||
-- load skin list and metadata
|
|
||||||
local id, f, data, skin = 0
|
|
||||||
|
|
||||||
while true do
|
|
||||||
|
|
||||||
if id == 0 then
|
|
||||||
skin = "character"
|
|
||||||
else
|
|
||||||
skin = "mcl_skins_character_" .. id
|
|
||||||
|
|
||||||
-- Does skin file exist?
|
|
||||||
f = io.open(mcl_skins.modpath .. "/textures/" .. skin .. ".png")
|
|
||||||
|
|
||||||
-- escape loop if not found
|
|
||||||
if not f then
|
|
||||||
break
|
|
||||||
end
|
end
|
||||||
f:close()
|
|
||||||
end
|
|
||||||
|
|
||||||
mcl_skins.list[id] = skin
|
|
||||||
|
|
||||||
local metafile
|
|
||||||
|
|
||||||
-- does metadata exist for that skin file ?
|
|
||||||
if id == 0 then
|
|
||||||
metafile = "mcl_skins_character.txt"
|
|
||||||
else
|
|
||||||
metafile = "mcl_skins_character_"..id..".txt"
|
|
||||||
end
|
|
||||||
f = io.open(mcl_skins.modpath .. "/meta/" .. metafile)
|
|
||||||
|
|
||||||
data = nil
|
|
||||||
if f then
|
|
||||||
data = minetest.deserialize("return {" .. f:read("*all") .. "}")
|
|
||||||
f:close()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add metadata to list
|
|
||||||
mcl_skins.meta[skin] = {
|
|
||||||
name = data and data.name or "",
|
|
||||||
author = data and data.author or "",
|
|
||||||
gender = data and data.gender or "",
|
|
||||||
}
|
|
||||||
|
|
||||||
if id > 0 then
|
|
||||||
mcl_skins.skin_count = mcl_skins.skin_count + 1
|
|
||||||
end
|
|
||||||
id = id + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
function mcl_skins.cycle_skin(player)
|
|
||||||
local skin_id = tonumber(player:get_meta():get_string("mcl_skins:skin_id"))
|
|
||||||
if not skin_id then
|
|
||||||
skin_id = 0
|
|
||||||
end
|
|
||||||
skin_id = skin_id + 1
|
|
||||||
if skin_id > mcl_skins.skin_count then
|
|
||||||
skin_id = 0
|
|
||||||
end
|
|
||||||
mcl_skins.set_player_skin(player, skin_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
function mcl_skins.set_player_skin(player, skin_id)
|
|
||||||
if not player then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
local playername = player:get_player_name()
|
|
||||||
local skin
|
|
||||||
if skin_id == nil or type(skin_id) ~= "number" or skin_id < 0 or skin_id > mcl_skins.skin_count then
|
|
||||||
return false
|
|
||||||
elseif skin_id == 0 then
|
|
||||||
skin = "character"
|
|
||||||
mcl_player.player_set_model(player, "mcl_armor_character.b3d")
|
|
||||||
else
|
|
||||||
skin = "mcl_skins_character_" .. tostring(skin_id)
|
|
||||||
local meta = mcl_skins.meta[skin]
|
|
||||||
if meta.gender == "female" then
|
|
||||||
mcl_player.player_set_model(player, "mcl_armor_character_female.b3d")
|
|
||||||
else
|
|
||||||
mcl_player.player_set_model(player, "mcl_armor_character.b3d")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--local skin_file = skin .. ".png"
|
|
||||||
mcl_skins.skins[playername] = skin
|
|
||||||
player:get_meta():set_string("mcl_skins:skin_id", tostring(skin_id))
|
|
||||||
mcl_skins.update_player_skin(player)
|
|
||||||
if has_mcl_inventory then
|
|
||||||
mcl_inventory.update_inventory_formspec(player)
|
|
||||||
end
|
|
||||||
for i=1, #mcl_skins.registered_on_set_skins do
|
|
||||||
mcl_skins.registered_on_set_skins[i](player, skin)
|
|
||||||
end
|
|
||||||
minetest.log("action", "[mcl_skins] Player skin for "..playername.." set to skin #"..skin_id)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
function mcl_skins.update_player_skin(player)
|
|
||||||
if not player then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local playername = player:get_player_name()
|
|
||||||
mcl_player.player_set_skin(player, mcl_skins.skins[playername] .. ".png")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- load player skin on join
|
|
||||||
minetest.register_on_joinplayer(function(player)
|
|
||||||
local name = player:get_player_name()
|
|
||||||
local skin_id = player:get_meta():get_string("mcl_skins:skin_id")
|
|
||||||
local set_skin
|
|
||||||
-- do we already have a skin in player attributes?
|
|
||||||
if skin_id and skin_id ~= "" then
|
|
||||||
set_skin = tonumber(skin_id)
|
|
||||||
-- otherwise use random skin if not set
|
|
||||||
end
|
|
||||||
if not set_skin then
|
|
||||||
set_skin = math.random(0, mcl_skins.skin_count)
|
|
||||||
end
|
|
||||||
local ok = mcl_skins.set_player_skin(player, set_skin)
|
|
||||||
if not ok then
|
|
||||||
set_skin = math.random(0, mcl_skins.skin_count)
|
|
||||||
minetest.log("warning", "[mcl_skins] Player skin for "..name.." not found, falling back to skin #"..set_skin)
|
|
||||||
mcl_skins.set_player_skin(player, set_skin)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
mcl_skins.registered_on_set_skins = {}
|
|
||||||
|
|
||||||
function mcl_skins.register_on_set_skin(func)
|
|
||||||
table.insert(mcl_skins.registered_on_set_skins, func)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- command to set player skin (usually for custom skins)
|
|
||||||
minetest.register_chatcommand("setskin", {
|
|
||||||
params = S("[<player>] [<skin number>]"),
|
|
||||||
description = S("Select player skin of yourself or another player"),
|
|
||||||
privs = {},
|
|
||||||
func = function(name, param)
|
|
||||||
|
|
||||||
if param == "" and name ~= "" then
|
|
||||||
mcl_skins.show_formspec(name)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
local playername, skin_id = string.match(param, "([^ ]+) (%d+)")
|
|
||||||
if not playername or not skin_id then
|
|
||||||
skin_id = string.match(param, "(%d+)")
|
|
||||||
if not skin_id then
|
|
||||||
return false, S("Insufficient or wrong parameters")
|
|
||||||
end
|
|
||||||
playername = name
|
|
||||||
end
|
|
||||||
skin_id = tonumber(skin_id)
|
|
||||||
|
|
||||||
local player = minetest.get_player_by_name(playername)
|
|
||||||
|
|
||||||
if not player then
|
|
||||||
return false, S("Player @1 not online!", playername)
|
|
||||||
end
|
|
||||||
if name ~= playername then
|
|
||||||
local privs = minetest.get_player_privs(name)
|
|
||||||
if not privs.server then
|
|
||||||
return false, S("You need the “server” privilege to change the skin of other players!")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local ok = mcl_skins.set_player_skin(player, skin_id)
|
|
||||||
if not ok then
|
|
||||||
return false, S("Invalid skin number! Valid numbers: 0 to @1", mcl_skins.skin_count)
|
|
||||||
end
|
|
||||||
local skinfile = "#"..skin_id
|
|
||||||
|
|
||||||
local meta = mcl_skins.meta[mcl_skins.skins[playername]]
|
|
||||||
local your_msg
|
|
||||||
if not meta.name or meta.name == "" then
|
|
||||||
your_msg = S("Your skin has been set to: @1", skinfile)
|
|
||||||
else
|
|
||||||
your_msg = S("Your skin has been set to: @1 (@2)", meta.name, skinfile)
|
|
||||||
end
|
|
||||||
if name == playername then
|
|
||||||
return true, your_msg
|
|
||||||
else
|
|
||||||
minetest.chat_send_player(playername, your_msg)
|
|
||||||
return true, S("Skin of @1 set to: @2 (@3)", playername, meta.name, skinfile)
|
|
||||||
end
|
|
||||||
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
||||||
if fields.__mcl_skins then
|
|
||||||
if mcl_skins.skin_count <= 6 then
|
|
||||||
-- Change skin immediately if there are not many skins
|
|
||||||
mcl_skins.cycle_skin(player)
|
|
||||||
if player:get_attach() then
|
|
||||||
mcl_player.player_set_animation(player, "sit")
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- Show skin selection formspec otherwise
|
|
||||||
mcl_skins.show_formspec(player:get_player_name())
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
function mcl_skins.show_formspec(playername)
|
|
||||||
local formspec = "size[7,8.5]"
|
|
||||||
|
|
||||||
formspec = formspec .. "label[2,2;" .. minetest.formspec_escape(minetest.colorize("#383838", S("Select player skin:"))) .. "]"
|
|
||||||
.. "textlist[0,2.5;6.8,6;skins_set;"
|
|
||||||
|
|
||||||
local meta
|
|
||||||
local selected = 1
|
|
||||||
|
|
||||||
for i = 0, mcl_skins.skin_count do
|
|
||||||
|
|
||||||
local label = S("@1 (@2)", mcl_skins.meta[mcl_skins.list[i]].name, "#"..i)
|
|
||||||
|
|
||||||
formspec = formspec .. minetest.formspec_escape(label)
|
|
||||||
|
|
||||||
if mcl_skins.skins[playername] == mcl_skins.list[i] then
|
|
||||||
selected = i + 1
|
|
||||||
meta = mcl_skins.meta[mcl_skins.list[i]]
|
|
||||||
end
|
|
||||||
|
|
||||||
if i < #mcl_skins.list then
|
|
||||||
formspec = formspec ..","
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
formspec = formspec .. ";" .. selected .. ";false]"
|
|
||||||
|
|
||||||
local player = minetest.get_player_by_name(playername)
|
|
||||||
if player then
|
|
||||||
--maybe the function could accept both player object and player name?
|
|
||||||
formspec = formspec .. mcl_player.get_player_formspec_model(player, 0, 0, 1.35, 2.7, "mcl_skins:skin_select")
|
|
||||||
end
|
|
||||||
|
|
||||||
if meta then
|
|
||||||
if meta.name and meta.name ~= "" then
|
|
||||||
formspec = formspec .. "label[2,0.5;" .. minetest.formspec_escape(minetest.colorize("#383838", S("Name: @1", meta.name))) .. "]"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.show_formspec(playername, "mcl_skins:skin_select", formspec)
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
||||||
|
|
||||||
if formname == "mcl_skins:skin_select" then
|
|
||||||
|
|
||||||
local name = player:get_player_name()
|
|
||||||
|
|
||||||
local event = minetest.explode_textlist_event(fields["skins_set"])
|
|
||||||
|
|
||||||
if event.type == "CHG" or event.type == "DCL" then
|
|
||||||
|
|
||||||
local skin_id = math.min(event.index - 1, mcl_skins.skin_count)
|
|
||||||
if not mcl_skins.list[skin_id] then
|
|
||||||
return -- Do not update wrong skin number
|
|
||||||
end
|
|
||||||
|
|
||||||
mcl_skins.set_player_skin(player, skin_id)
|
|
||||||
mcl_skins.show_formspec(name)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
minetest.log("action", "[mcl_skins] Mod initialized with "..mcl_skins.skin_count.." custom skin(s)")
|
|
||||||
|
|
|
@ -0,0 +1,260 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "footwear",
|
||||||
|
"texture": "mcl_skins_footwear_1.png",
|
||||||
|
"steve": true,
|
||||||
|
"alex": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "footwear",
|
||||||
|
"texture": "mcl_skins_footwear_2.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "footwear",
|
||||||
|
"texture": "mcl_skins_footwear_3.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "footwear"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "eye",
|
||||||
|
"texture": "mcl_skins_eye_1.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "eye",
|
||||||
|
"texture": "mcl_skins_eye_2.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "eye",
|
||||||
|
"texture": "mcl_skins_eye_3.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "eye",
|
||||||
|
"texture": "mcl_skins_eye_4.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "eye",
|
||||||
|
"texture": "mcl_skins_eye_5.png",
|
||||||
|
"steve": true,
|
||||||
|
"alex": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "eye",
|
||||||
|
"texture": "mcl_skins_eye_6.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "eye",
|
||||||
|
"texture": "mcl_skins_eye_7.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "mouth",
|
||||||
|
"texture": "mcl_skins_mouth_1.png",
|
||||||
|
"steve": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "mouth",
|
||||||
|
"texture": "mcl_skins_mouth_2.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "mouth",
|
||||||
|
"texture": "mcl_skins_mouth_3.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "mouth",
|
||||||
|
"texture": "mcl_skins_mouth_4.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "mouth",
|
||||||
|
"texture": "mcl_skins_mouth_5.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "mouth",
|
||||||
|
"texture": "mcl_skins_mouth_6.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "mouth",
|
||||||
|
"texture": "mcl_skins_mouth_7.png",
|
||||||
|
"alex": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "mouth"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hair",
|
||||||
|
"texture": "mcl_skins_hair_1.png",
|
||||||
|
"mask": "mcl_skins_hair_1_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hair",
|
||||||
|
"texture": "mcl_skins_hair_2.png",
|
||||||
|
"mask": "mcl_skins_hair_2_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hair",
|
||||||
|
"texture": "mcl_skins_hair_3.png",
|
||||||
|
"mask": "mcl_skins_hair_3_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hair",
|
||||||
|
"texture": "mcl_skins_hair_4.png",
|
||||||
|
"mask": "mcl_skins_hair_4_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hair",
|
||||||
|
"texture": "mcl_skins_hair_5.png",
|
||||||
|
"mask": "mcl_skins_hair_5_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hair",
|
||||||
|
"texture": "mcl_skins_hair_6.png",
|
||||||
|
"mask": "mcl_skins_hair_6_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hair",
|
||||||
|
"texture": "mcl_skins_hair_7.png",
|
||||||
|
"mask": "mcl_skins_hair_7_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hair",
|
||||||
|
"texture": "mcl_skins_hair_8.png",
|
||||||
|
"mask": "mcl_skins_hair_8_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hair",
|
||||||
|
"texture": "mcl_skins_hair_9.png",
|
||||||
|
"mask": "mcl_skins_hair_9_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hair",
|
||||||
|
"texture": "mcl_skins_hair_10.png",
|
||||||
|
"mask": "mcl_skins_hair_10_mask.png",
|
||||||
|
"steve": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hair",
|
||||||
|
"texture": "mcl_skins_hair_11.png",
|
||||||
|
"mask": "mcl_skins_hair_11_mask.png",
|
||||||
|
"alex": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hair"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "headwear",
|
||||||
|
"texture": "mcl_skins_headwear_1.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "headwear",
|
||||||
|
"texture": "mcl_skins_headwear_2.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "headwear",
|
||||||
|
"texture": "mcl_skins_headwear_3.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "headwear",
|
||||||
|
"texture": "mcl_skins_headwear_4.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "headwear",
|
||||||
|
"texture": "mcl_skins_headwear_5.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "headwear",
|
||||||
|
"texture": "mcl_skins_headwear_6.png",
|
||||||
|
"preview_rotation": {
|
||||||
|
"x": -10,
|
||||||
|
"y": 200
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "headwear",
|
||||||
|
"texture": "mcl_skins_headwear_7.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "headwear",
|
||||||
|
"steve": true,
|
||||||
|
"alex": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "bottom",
|
||||||
|
"texture": "mcl_skins_bottom_1.png",
|
||||||
|
"mask": "mcl_skins_bottom_1_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "bottom",
|
||||||
|
"texture": "mcl_skins_bottom_2.png",
|
||||||
|
"mask": "mcl_skins_bottom_2_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "bottom",
|
||||||
|
"texture": "mcl_skins_bottom_3.png",
|
||||||
|
"mask": "mcl_skins_bottom_3_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "bottom",
|
||||||
|
"texture": "mcl_skins_bottom_4.png",
|
||||||
|
"mask": "mcl_skins_bottom_4_mask.png",
|
||||||
|
"steve": true,
|
||||||
|
"alex": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "top",
|
||||||
|
"texture": "mcl_skins_top_1.png",
|
||||||
|
"mask": "mcl_skins_top_1_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "top",
|
||||||
|
"texture": "mcl_skins_top_2.png",
|
||||||
|
"mask": "mcl_skins_top_2_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "top",
|
||||||
|
"texture": "mcl_skins_top_3.png",
|
||||||
|
"mask": "mcl_skins_top_3_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "top",
|
||||||
|
"texture": "mcl_skins_top_4.png",
|
||||||
|
"mask": "mcl_skins_top_4_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "top",
|
||||||
|
"texture": "mcl_skins_top_5.png",
|
||||||
|
"mask": "mcl_skins_top_5_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "top",
|
||||||
|
"texture": "mcl_skins_top_6.png",
|
||||||
|
"mask": "mcl_skins_top_6_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "top",
|
||||||
|
"texture": "mcl_skins_top_7.png",
|
||||||
|
"mask": "mcl_skins_top_7_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "top",
|
||||||
|
"texture": "mcl_skins_top_8.png",
|
||||||
|
"mask": "mcl_skins_top_8_mask.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "top",
|
||||||
|
"texture": "mcl_skins_top_9.png",
|
||||||
|
"mask": "mcl_skins_top_9_mask.png",
|
||||||
|
"alex": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "top",
|
||||||
|
"texture": "mcl_skins_top_10.png",
|
||||||
|
"mask": "mcl_skins_top_10_mask.png",
|
||||||
|
"steve": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "base",
|
||||||
|
"texture": "mcl_skins_base_1.png",
|
||||||
|
"mask": "mcl_skins_base_1_mask.png",
|
||||||
|
"steve": true,
|
||||||
|
"alex": true
|
||||||
|
}
|
||||||
|
]
|
|
@ -1,13 +0,0 @@
|
||||||
# textdomain: mcl_skins
|
|
||||||
[<player>] [<skin number>]=[<Spieler>] [<Aussehens-Nummer>]
|
|
||||||
Select player skin of yourself or another player=Spieleraussehen von Ihnen oder einem anderen Spieler auswählen
|
|
||||||
Insufficient or wrong parameters=Unzureichende oder falsche Parameter
|
|
||||||
Player @1 not online!=Spieler @1 ist nicht online!
|
|
||||||
You need the “server” privilege to change the skin of other players!=Sie brauchen das „server“-Privileg, um das Aussehen anderer Spieler zu ändern!
|
|
||||||
Invalid skin number! Valid numbers: 0 to @1=Ungültige Aussehens-Nummer! Gültige Nummern: 0 bis @1
|
|
||||||
Your skin has been set to: @1=Ihr Aussehen wurde geändert auf: @1
|
|
||||||
Your skin has been set to: @1 (@2)=Ihr Aussehen wurde geändert auf: @1 (@2)
|
|
||||||
Skin of @1 set to: @2 (@3)=Aussehen von @1 gesetzt auf: @2 (@3)
|
|
||||||
Select player skin:=Spieleraussehen wählen:
|
|
||||||
@1 (@2)=@1 (@2)
|
|
||||||
Name: @1=Name: @1
|
|
|
@ -1,13 +0,0 @@
|
||||||
# textdomain: mcl_skins
|
|
||||||
[<player>] [<skin number>]=[<Jugador>] [<Número de skin>]
|
|
||||||
Select player skin of yourself or another player=Selecciona el skin tuyo o de otro jugador
|
|
||||||
Insufficient or wrong parameters=Parámetros insuficientes o incorrectos
|
|
||||||
Player @1 not online!=¡El jugador @1 no está en línea!
|
|
||||||
You need the “server” privilege to change the skin of other players!=¡Necesitas el privilegio de "servidor" para cambiar el aspecto de otros jugadores!
|
|
||||||
Invalid skin number! Valid numbers: 0 to @1=¡Número de piel no válido! Números válidos: 0 a @1
|
|
||||||
Your skin has been set to: @1=Su skin se ha configurado a: @1
|
|
||||||
Your skin has been set to: @1 (@2)=Su skin se ha configurado a: @1 (@2)
|
|
||||||
Skin of @1 set to: @2 (@3)=El skin de @1 se ha configurado a: @2 (@3)
|
|
||||||
Select player skin:=Selecciona el skin del jugador:
|
|
||||||
@1 (@2)=@1 (@2)
|
|
||||||
Name: @1=Nombre: @1
|
|
|
@ -1,14 +1,13 @@
|
||||||
# textdomain: mcl_skins
|
# textdomain: mcl_skins
|
||||||
[<player>] [<skin number>]=[<joueur>] [<numéro d'apparence>]
|
Templates=Modèles
|
||||||
Select player skin of yourself or another player=Sélectionner une apparence pour vous même ou un autre joueur
|
Arm size=Taille des bras
|
||||||
Insufficient or wrong parameters=Paramètres insuffisants ou incorrects
|
Bases=Teint
|
||||||
Player @1 not online!=Le joueur @1 n'est pas en ligne!
|
Footwears=Chaussures
|
||||||
You need the “server” privilege to change the skin of other players!=Vous avez besoin du privilège “server” pour changer l'apparence des autres joueurs!
|
Eyes=Yeux
|
||||||
Invalid skin number! Valid numbers: 0 to @1=Numéro d'apparence incorrect! Numéros valides : 0 à @1
|
Mouths=Bouches
|
||||||
Your skin has been set to: @1=Votre apparence a été définie à: @1
|
Bottoms=Bas
|
||||||
Your skin has been set to: @1 (@2)=Votre apparence a été définie à: @1 (@2)
|
Tops=Haut
|
||||||
Skin of @1 set to: @2 (@3)=Apparence of @1 set to: @2 (@3)=
|
Hairs=Cheveux
|
||||||
Select player skin:=Sélectionner l'apparence du joueur :
|
Headwears=Coiffe
|
||||||
@1 (@2)=@1 (@2)
|
Open skin configuration screen.=Ouvrir l'écran de configuration du costume.
|
||||||
Name: @1=Nom : @
|
Select=Sélectionner
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
# textdomain: mcl_skins
|
|
||||||
# UNFINISHED translation!
|
|
||||||
# TODO: Remove the # sign from the translations below and add the missing translations.
|
|
||||||
|
|
||||||
[<player>] [<skin number>]=
|
|
||||||
Select player skin of yourself or another player=
|
|
||||||
Insufficient or wrong parameters=
|
|
||||||
Player @1 not online!=
|
|
||||||
You need the “server” privilege to change the skin of other players!=
|
|
||||||
Invalid skin number! Valid numbers: 0 to @1=
|
|
||||||
Your skin has been set to: @1=
|
|
||||||
Your skin has been set to: @1 (@2)=
|
|
||||||
Skin of @1 set to: @2 (@3)=
|
|
||||||
Select player skin:=Pilih Kulit Pemain:
|
|
||||||
@1 (@2)=
|
|
||||||
Name: @1=Nama: @1
|
|
|
@ -1,13 +0,0 @@
|
||||||
# textdomain: mcl_skins
|
|
||||||
[<player>] [<skin number>]=[<gracz>] [<numer skina>]
|
|
||||||
Select player skin of yourself or another player=Wybierz skin gracza dla siebie lub innego gracza
|
|
||||||
Insufficient or wrong parameters=Niewystarczające lub złe parametry
|
|
||||||
Player @1 not online!=Gracz @1 nie jest online!
|
|
||||||
You need the “server” privilege to change the skin of other players!=Potrzebujesz uprawnienia "serwer", aby zmieniać skiny innych graczy!
|
|
||||||
Invalid skin number! Valid numbers: 0 to @1=Niepoprawny numer skina! Poprawne numery: od 0 do @1
|
|
||||||
Your skin has been set to: @1=Twój skin został ustawiony na: @1
|
|
||||||
Your skin has been set to: @1 (@2)=Twój skin został ustawiony na: @1 (@2)
|
|
||||||
Skin of @1 set to: @2 (@3)=Skin gracza @1 ustawiony na @2 (@3)
|
|
||||||
Select player skin:=Wybierz skin gracza:
|
|
||||||
@1 (@2)=@1 (@2)
|
|
||||||
Name: @1=Nazwa: @1
|
|
|
@ -1,13 +0,0 @@
|
||||||
# textdomain: mcl_skins
|
|
||||||
[<player>] [<skin number>]=[<игрок>] [<номер скина>]
|
|
||||||
Select player skin of yourself or another player=Выберите скин для себя или для другого игрока
|
|
||||||
Insufficient or wrong parameters=Недопустимые или неправильные параметры
|
|
||||||
Player @1 not online!=Игрок @1 не в сети!
|
|
||||||
You need the “server” privilege to change the skin of other players!=Для смены скинов другим игрокам у вас должна быть привилегия “server”!
|
|
||||||
Invalid skin number! Valid numbers: 0 to @1=Недопустимый номер скина! Правильные номера: от 0 до @1
|
|
||||||
Your skin has been set to: @1=Ваш скин выбран: @1
|
|
||||||
Your skin has been set to: @1 (@2)=Ваш скин установлен: @1 (@2)
|
|
||||||
Skin of @1 set to: @2 (@3)=Скин игрока @1 установлен: @2 (@3)
|
|
||||||
Select player skin:=Выбор скина игрока:
|
|
||||||
@1 (@2)=@1 (@2)
|
|
||||||
Name: @1=Имя: @1
|
|
|
@ -1,13 +0,0 @@
|
||||||
# textdomain: mcl_skins
|
|
||||||
[<player>] [<skin number>]=[<玩家名字>] [<皮膚篇號>]
|
|
||||||
Select player skin of yourself or another player=替自己或其他玩家選擇皮膚
|
|
||||||
Insufficient or wrong parameters=無效或錯誤參數
|
|
||||||
Player @1 not online!=玩家 @1 不在線!
|
|
||||||
You need the “server” privilege to change the skin of other players!=你需要「server」權限來替換其他玩家的皮膚!
|
|
||||||
Invalid skin number! Valid numbers: 0 to @1=無效皮膚篇號!有效篇號:0至@1
|
|
||||||
Your skin has been set to: @1=你的皮膚已換成:@1
|
|
||||||
Your skin has been set to: @1 (@2)=你的皮膚已換成:@1(@2)
|
|
||||||
Skin of @1 set to: @2 (@3)=@1的皮膚已換成:@1
|
|
||||||
Select player skin:=選擇玩家皮膚:
|
|
||||||
@1 (@2)=@1(@2)
|
|
||||||
Name: @1=名稱:@1
|
|
|
@ -1,13 +1,14 @@
|
||||||
# textdomain: mcl_skins
|
# textdomain: mcl_skins
|
||||||
[<player>] [<skin number>]=
|
Skins=
|
||||||
Select player skin of yourself or another player=
|
Templates=
|
||||||
Insufficient or wrong parameters=
|
Arm size=
|
||||||
Player @1 not online!=
|
Bases=
|
||||||
You need the “server” privilege to change the skin of other players!=
|
Footwears=
|
||||||
Invalid skin number! Valid numbers: 0 to @1=
|
Eyes=
|
||||||
Your skin has been set to: @1=
|
Mouths=
|
||||||
Your skin has been set to: @1 (@2)=
|
Bottoms=
|
||||||
Skin of @1 set to: @2 (@3)=
|
Tops=
|
||||||
Select player skin:=
|
Hairs=
|
||||||
@1 (@2)=
|
Headwears=
|
||||||
Name: @1=
|
Open skin configuration screen.=
|
||||||
|
Select=
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
mcl_skins_base_1.png
|
||||||
|
mcl_skins_button.png
|
||||||
|
mcl_skins_footwear_3.png
|
||||||
|
mcl_skins_headgear_1.png
|
||||||
|
mcl_skins_headgear_3.png
|
||||||
|
mcl_skins_headgear_4.png
|
||||||
|
mcl_skins_headgear_5.png
|
||||||
|
mcl_skins_mouth_2.png
|
||||||
|
mcl_skins_mouth_3.png
|
||||||
|
mcl_skins_mouth_4.png
|
||||||
|
mcl_skins_mouth_5.png
|
||||||
|
mcl_skins_select_overlay.png
|
||||||
|
mcl_skins_slim_arms.png
|
||||||
|
mcl_skins_thick_arms.png
|
||||||
|
mcl_skins_top_2.png
|
||||||
|
mcl_skins_top_5.png
|
||||||
|
mcl_skins_eye_5.png
|
||||||
|
mcl_skins_hair_8.png
|
||||||
|
mcl_skins_top_6.png
|
||||||
|
mcl_skins_bottom_3.png
|
||||||
|
mcl_skins_eye_7.png
|
||||||
|
mcl_skins_mouth_7.png
|
||||||
|
Original work by MrRar
|
||||||
|
License: CC BY-SA 4.0
|
||||||
|
|
||||||
|
mcl_skins_top_1.png
|
||||||
|
mcl_skins_mouth_1.png
|
||||||
|
mcl_skins_hair_1.png
|
||||||
|
mcl_skins_hair_2.png
|
||||||
|
mcl_skins_eye_1.png
|
||||||
|
mcl_skins_eye_2.png
|
||||||
|
mcl_skins_footwear_1.png
|
||||||
|
mcl_skins_headgear_2.png
|
||||||
|
mcl_skins_mouth_1.png
|
||||||
|
mcl_skins_top_1.png
|
||||||
|
mcl_skins_mouth_2.png
|
||||||
|
Name: Pixel Perfection resource pack for Minecraft 1.11
|
||||||
|
Author: XSSheep. Adapted for mcl_skins by MrRar.
|
||||||
|
License: CC BY-SA 4.0
|
||||||
|
Source: https://www.planetminecraft.com/texture_pack/131pixel-perfection/
|
||||||
|
|
||||||
|
mcl_skins_hair_3.png
|
||||||
|
mcl_skins_eye_3.png
|
||||||
|
mcl_skins_footwear_2.png
|
||||||
|
Name: the 10the doctor
|
||||||
|
Author: lovehart. Adapted for mcl_skins by MrRar.
|
||||||
|
License: CC BY-SA 3.0
|
||||||
|
Source: http://minetest.fensta.bplaced.net/#!page:1,filtertype:Id,filter:367
|
||||||
|
|
||||||
|
mcl_skins_hair_4.png
|
||||||
|
Blonde Girl
|
||||||
|
Author: Rin. Adapted for mcl_skins by MrRar.
|
||||||
|
License: CC BY-SA 3.0
|
||||||
|
Source: http://minetest.fensta.bplaced.net/#id=918
|
||||||
|
|
||||||
|
mcl_skins_hair_5.png
|
||||||
|
Name: hobbit from lottmob
|
||||||
|
Author: lovehart. Adapted for mcl_skins by MrRar.
|
||||||
|
License: CC BY-SA 3.0
|
||||||
|
Source: http://minetest.fensta.bplaced.net/#id=336
|
||||||
|
|
||||||
|
mcl_skins_top_4.png
|
||||||
|
Name: Oliver_MV
|
||||||
|
Author: hansuke123. Adapted for mcl_skins by MrRar.
|
||||||
|
License: CC BY-SA 3.0
|
||||||
|
Source: http://minetest.fensta.bplaced.net/#!page:1,filtertype:Id,filter:291
|
||||||
|
|
||||||
|
mcl_skins_hair_6.png
|
||||||
|
mcl_skins_eye_6.png
|
||||||
|
Name: Mumbo Jumbo
|
||||||
|
Author: ZestyZachary
|
||||||
|
License: CC 0 (1.0)
|
||||||
|
Source: http://minetest.fensta.bplaced.net/#!page:1,filtertype:Id,filter:2100
|
||||||
|
|
||||||
|
mcl_skins_eye_4.png
|
||||||
|
Name: lisa
|
||||||
|
Author: hansuke123
|
||||||
|
License: CC BY-SA 3.0
|
||||||
|
Source: http://minetest.fensta.bplaced.net/#!page:1,filtertype:Id,filter:88
|
||||||
|
|
||||||
|
mcl_skins_headwear_7.png
|
||||||
|
Name: Ryu
|
||||||
|
Author: Ginsu23. Adapted for mcl_skins by MrRar.
|
||||||
|
License: CC BY-SA 3.0
|
||||||
|
Source: http://minetest.fensta.bplaced.net/#id=464
|
||||||
|
|
||||||
|
mcl_skins_top_8.png
|
||||||
|
Name: Hoodie Enderman
|
||||||
|
Author: Kpenguin. Adapted for mcl_skins by MrRar.
|
||||||
|
License: CC BY-SA 3.0
|
||||||
|
Source: http://minetest.fensta.bplaced.net/#id=962
|
||||||
|
|
||||||
|
mcl_skins_hair_9.png
|
||||||
|
Name: Trader 1
|
||||||
|
Author: TenPlus1. Adapted for mcl_skins by MrRar.
|
||||||
|
License: CC BY-SA 3.0
|
||||||
|
Source: http://minetest.fensta.bplaced.net/#id=1258
|
||||||
|
|
||||||
|
mcl_skins_bottom_4.png
|
||||||
|
mcl_skins_top_9.png
|
||||||
|
mcl_skins_top_10.png
|
||||||
|
mcl_skins_hair_10.png
|
||||||
|
mcl_skins_hair_11.png
|
||||||
|
Name: Pixel Perfection Legacy 1.19
|
||||||
|
Author: Nova_Wostra. Adapted for mcl_skins by MrRar.
|
||||||
|
License: CC BY-SA 4.0
|
||||||
|
Source: https://www.planetminecraft.com/texture-pack/pixel-perfection-chorus-edit/
|
||||||
|
|
||||||
|
mcl_skins_bottom.obj
|
||||||
|
mcl_skins_head.obj
|
||||||
|
mcl_skins_top.obj
|
||||||
|
Name: character.blend in player_api mod from Minetest Game
|
||||||
|
Author: celeron55, MirceaKitsune, Jordach, kilbith, sofar, xunto, Rogier-5, TeTpaAka, Desour, stujones11, An0n3m0us. Adapted for mcl_skins by MrRar.
|
||||||
|
License: CC BY-SA 3.0
|
||||||
|
Source: https://github.com/minetest/minetest_game
|
|
@ -0,0 +1,53 @@
|
||||||
|
local function make_texture(base, colorspec)
|
||||||
|
local output = ""
|
||||||
|
if mcl_skins.masks[base] then
|
||||||
|
output = mcl_skins.masks[base] ..
|
||||||
|
"^[colorize:" .. minetest.colorspec_to_colorstring(colorspec) .. ":alpha"
|
||||||
|
end
|
||||||
|
if #output > 0 then output = output .. "^" end
|
||||||
|
output = output .. base
|
||||||
|
return output
|
||||||
|
end
|
||||||
|
|
||||||
|
function mcl_skins.get_skin_list()
|
||||||
|
local list = {}
|
||||||
|
for _, base in pairs(mcl_skins.base) do
|
||||||
|
for _, base_color in pairs(mcl_skins.base_color) do
|
||||||
|
local id = base:gsub(".png$", "") .. minetest.colorspec_to_colorstring(base_color):gsub("#", "")
|
||||||
|
local female = {
|
||||||
|
texture = make_texture(base, base_color),
|
||||||
|
slim_arms = true,
|
||||||
|
id = id .. "_female"
|
||||||
|
}
|
||||||
|
table.insert(list, female)
|
||||||
|
|
||||||
|
local male = {
|
||||||
|
texture = make_texture(base, base_color),
|
||||||
|
slim_arms = false,
|
||||||
|
id = id .. "_male"
|
||||||
|
}
|
||||||
|
table.insert(list, male)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for _, skin in pairs(mcl_skins.simple_skins) do
|
||||||
|
table.insert(list, {
|
||||||
|
texture = skin.texture,
|
||||||
|
slim_arms = skin.slim_arms,
|
||||||
|
id = skin.texture:gsub(".png$", "") .. "_" .. (skin.slim_arms and "female" or "male"),
|
||||||
|
})
|
||||||
|
end
|
||||||
|
return list
|
||||||
|
end
|
||||||
|
|
||||||
|
function mcl_skins.get_node_id_by_player(player)
|
||||||
|
local skin = mcl_skins.players[player]
|
||||||
|
if skin.simple_skins_id then
|
||||||
|
local skin = mcl_skins.simple_skins[skin.simple_skins_id]
|
||||||
|
return skin.texture:gsub(".png$", "") ..
|
||||||
|
"_" .. (skin.slim_arms and "female" or "male")
|
||||||
|
else
|
||||||
|
return skin.base:gsub(".png$", "") ..
|
||||||
|
minetest.colorspec_to_colorstring(skin.base_color):gsub("#", "") ..
|
||||||
|
"_" .. (skin.slim_arms and "female" or "male")
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,3 +0,0 @@
|
||||||
name = "Steve",
|
|
||||||
author = "%TEXTURE_PACK_AUTHOR%",
|
|
||||||
gender = "male",
|
|
|
@ -1,3 +0,0 @@
|
||||||
name = "Alex",
|
|
||||||
author = "%TEXTURE_PACK_AUTHOR%",
|
|
||||||
gender = "female",
|
|
|
@ -1,5 +1,4 @@
|
||||||
name = mcl_skins
|
name = mcl_skins
|
||||||
author = TenPlus1
|
author = MrRar
|
||||||
description = Mod that allows players to set their individual skins.
|
description = Advanced player skin customization.
|
||||||
depends = mcl_player
|
depends = mcl_player,mcl_inventory
|
||||||
optional_depends = mcl_inventory, intllib
|
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
# Blender v2.93.5 OBJ File: ''
|
||||||
|
# www.blender.org
|
||||||
|
mtllib bottom.mtl
|
||||||
|
o bottom
|
||||||
|
v -2.100000 4.358421 1.050001
|
||||||
|
v -2.100000 1.648314 1.049999
|
||||||
|
v 2.100000 1.648314 1.049999
|
||||||
|
v 2.100000 4.358421 1.050001
|
||||||
|
v -2.100000 1.648314 -1.050001
|
||||||
|
v -2.100000 4.358421 -1.049998
|
||||||
|
v 2.100000 1.648314 -1.050001
|
||||||
|
v 2.100000 4.358421 -1.049998
|
||||||
|
v 0.000000 1.648314 -1.050001
|
||||||
|
v 0.000000 -4.651686 -1.050003
|
||||||
|
v 0.000000 -4.651686 1.049997
|
||||||
|
v 0.000000 1.648314 1.049999
|
||||||
|
v 0.000000 -4.651686 -1.050003
|
||||||
|
v 0.000000 -4.651686 1.049997
|
||||||
|
v -2.100000 -4.651685 1.049997
|
||||||
|
v -2.100000 -4.651685 -1.050003
|
||||||
|
v -2.100000 1.648315 1.049999
|
||||||
|
v -2.100000 1.648315 -1.050001
|
||||||
|
v 0.000000 1.648314 1.049999
|
||||||
|
v 2.100000 1.648315 -1.050001
|
||||||
|
v 2.100000 -4.651685 -1.050003
|
||||||
|
v 0.000000 1.648314 -1.050001
|
||||||
|
v 2.100000 -4.651685 1.049997
|
||||||
|
v 2.100000 1.648315 1.049999
|
||||||
|
vt 0.500000 0.161316
|
||||||
|
vt 0.500000 0.000000
|
||||||
|
vt 0.625000 0.000000
|
||||||
|
vt 0.625000 0.161316
|
||||||
|
vt 0.437500 0.000000
|
||||||
|
vt 0.437500 0.161316
|
||||||
|
vt 0.312500 0.000000
|
||||||
|
vt 0.312500 0.161316
|
||||||
|
vt 0.562500 0.375000
|
||||||
|
vt 0.562500 0.500000
|
||||||
|
vt 0.437500 0.500000
|
||||||
|
vt 0.437500 0.375000
|
||||||
|
vt 0.125000 0.375000
|
||||||
|
vt 0.125000 0.000000
|
||||||
|
vt 0.187500 0.000000
|
||||||
|
vt 0.187500 0.375000
|
||||||
|
vt 0.187500 0.375000
|
||||||
|
vt 0.187500 0.500000
|
||||||
|
vt 0.125000 0.500000
|
||||||
|
vt 0.125000 0.375000
|
||||||
|
vt 0.000000 0.375000
|
||||||
|
vt 0.062500 0.375000
|
||||||
|
vt 0.062500 0.000000
|
||||||
|
vt 0.000000 0.000000
|
||||||
|
vt 0.187500 0.375000
|
||||||
|
vt 0.250000 0.375000
|
||||||
|
vt 0.250000 0.000000
|
||||||
|
vt 0.187500 0.000000
|
||||||
|
vt 0.062500 0.375000
|
||||||
|
vt 0.062500 0.000000
|
||||||
|
vt 0.125000 0.375000
|
||||||
|
vt 0.125000 0.000000
|
||||||
|
vt 0.250000 0.000000
|
||||||
|
vt 0.250000 0.375000
|
||||||
|
vt 0.000000 0.375000
|
||||||
|
vt 0.000000 0.000000
|
||||||
|
vt 0.250000 0.161316
|
||||||
|
vt 0.250000 0.000000
|
||||||
|
vt 0.125000 0.375000
|
||||||
|
vt 0.125000 0.500000
|
||||||
|
vt 0.062500 0.500000
|
||||||
|
vt 0.062500 0.375000
|
||||||
|
vt 0.187500 0.375000
|
||||||
|
vt 0.125000 0.375000
|
||||||
|
vt 0.125000 0.500000
|
||||||
|
vt 0.187500 0.500000
|
||||||
|
vt 0.125000 0.375000
|
||||||
|
vt 0.062500 0.375000
|
||||||
|
vt 0.062500 0.500000
|
||||||
|
vt 0.125000 0.500000
|
||||||
|
vt 0.000000 1.000000
|
||||||
|
vt 0.000000 1.000000
|
||||||
|
vt 0.000000 1.000000
|
||||||
|
vt 0.000000 1.000000
|
||||||
|
vn 0.0000 -0.0000 1.0000
|
||||||
|
vn -1.0000 -0.0000 0.0000
|
||||||
|
vn 0.0000 0.0000 -1.0000
|
||||||
|
vn 0.0000 -1.0000 -0.0000
|
||||||
|
vn 1.0000 0.0000 0.0000
|
||||||
|
vn 0.0000 1.0000 0.0000
|
||||||
|
usemtl Character
|
||||||
|
s 1
|
||||||
|
f 1/1/1 2/2/1 3/3/1 4/4/1
|
||||||
|
f 5/5/2 2/2/2 1/1/2 6/6/2
|
||||||
|
f 7/7/3 5/5/3 6/6/3 8/8/3
|
||||||
|
f 7/9/4 3/10/4 2/11/4 5/12/4
|
||||||
|
f 9/13/2 10/14/2 11/15/2 12/16/2
|
||||||
|
f 13/17/4 14/18/4 15/19/4 16/20/4
|
||||||
|
f 17/21/2 18/22/2 16/23/2 15/24/2
|
||||||
|
f 19/25/1 17/26/1 15/27/1 14/28/1
|
||||||
|
f 20/29/3 21/30/3 10/14/3 9/13/3
|
||||||
|
f 18/22/3 22/31/3 13/32/3 16/23/3
|
||||||
|
f 12/16/1 11/15/1 23/33/1 24/34/1
|
||||||
|
f 22/31/5 19/25/5 14/28/5 13/32/5
|
||||||
|
f 24/35/5 23/36/5 21/30/5 20/29/5
|
||||||
|
f 4/37/5 3/38/5 7/7/5 8/8/5
|
||||||
|
f 18/39/6 17/40/6 19/41/6 22/42/6
|
||||||
|
f 10/43/4 21/44/4 23/45/4 11/46/4
|
||||||
|
f 20/47/6 9/48/6 12/49/6 24/50/6
|
||||||
|
f 4/51/6 8/52/6 6/53/6 1/54/6
|
|
@ -0,0 +1,72 @@
|
||||||
|
# Blender v2.93.5 OBJ File: ''
|
||||||
|
# www.blender.org
|
||||||
|
mtllib head.mtl
|
||||||
|
o head
|
||||||
|
v -2.100000 -2.100004 2.099999
|
||||||
|
v 2.100000 2.099997 -2.100001
|
||||||
|
v 2.100000 2.099997 2.099999
|
||||||
|
v 2.300000 -2.300003 -2.300001
|
||||||
|
v 2.300000 2.299997 2.299999
|
||||||
|
v 2.100000 -2.100004 2.099999
|
||||||
|
v 2.100000 -2.100004 -2.100001
|
||||||
|
v -2.100000 2.099997 2.099999
|
||||||
|
v -2.100000 2.099997 -2.100001
|
||||||
|
v -2.100000 -2.100004 -2.100001
|
||||||
|
v 2.300000 2.299997 -2.300001
|
||||||
|
v 2.300000 -2.300003 2.299999
|
||||||
|
v -2.300000 2.299997 2.299999
|
||||||
|
v -2.300000 -2.300003 2.299999
|
||||||
|
v -2.300000 2.299997 -2.300001
|
||||||
|
v -2.300000 -2.300003 -2.300001
|
||||||
|
vt 0.500000 0.750000
|
||||||
|
vt 0.375000 0.750000
|
||||||
|
vt 0.375000 0.500000
|
||||||
|
vt 0.500000 0.500000
|
||||||
|
vt 0.250000 0.750000
|
||||||
|
vt 0.250000 0.500000
|
||||||
|
vt 0.125000 0.750000
|
||||||
|
vt 0.125000 0.500000
|
||||||
|
vt 0.375000 0.750000
|
||||||
|
vt 0.375000 1.000000
|
||||||
|
vt 0.250000 1.000000
|
||||||
|
vt 0.250000 0.750000
|
||||||
|
vt 0.250000 1.000000
|
||||||
|
vt 0.125000 1.000000
|
||||||
|
vt 0.000000 0.750000
|
||||||
|
vt 0.000000 0.500000
|
||||||
|
vt 1.000000 0.750000
|
||||||
|
vt 0.875000 0.750000
|
||||||
|
vt 0.875000 0.500000
|
||||||
|
vt 1.000000 0.500000
|
||||||
|
vt 0.750000 0.750000
|
||||||
|
vt 0.750000 0.500000
|
||||||
|
vt 0.625000 0.750000
|
||||||
|
vt 0.625000 0.500000
|
||||||
|
vt 0.875000 0.750000
|
||||||
|
vt 0.875000 1.000000
|
||||||
|
vt 0.750000 1.000000
|
||||||
|
vt 0.750000 0.750000
|
||||||
|
vt 0.750000 1.000000
|
||||||
|
vt 0.625000 1.000000
|
||||||
|
vt 0.500000 0.750000
|
||||||
|
vt 0.500000 0.500000
|
||||||
|
vn 0.0000 0.0000 1.0000
|
||||||
|
vn -1.0000 0.0000 0.0000
|
||||||
|
vn 0.0000 0.0000 -1.0000
|
||||||
|
vn 0.0000 -1.0000 0.0000
|
||||||
|
vn 0.0000 1.0000 0.0000
|
||||||
|
vn 1.0000 0.0000 0.0000
|
||||||
|
usemtl Character
|
||||||
|
s off
|
||||||
|
f 3/1/1 8/2/1 1/3/1 6/4/1
|
||||||
|
f 8/2/2 9/5/2 10/6/2 1/3/2
|
||||||
|
f 9/5/3 2/7/3 7/8/3 10/6/3
|
||||||
|
f 7/9/4 6/10/4 1/11/4 10/12/4
|
||||||
|
f 9/5/5 8/13/5 3/14/5 2/7/5
|
||||||
|
f 3/15/6 6/16/6 7/8/6 2/7/6
|
||||||
|
f 5/17/1 13/18/1 14/19/1 12/20/1
|
||||||
|
f 13/18/2 15/21/2 16/22/2 14/19/2
|
||||||
|
f 15/21/3 11/23/3 4/24/3 16/22/3
|
||||||
|
f 4/25/4 12/26/4 14/27/4 16/28/4
|
||||||
|
f 15/21/5 13/29/5 5/30/5 11/23/5
|
||||||
|
f 5/31/6 12/32/6 4/24/6 11/23/6
|
|
@ -0,0 +1,174 @@
|
||||||
|
# Blender v2.93.5 OBJ File: ''
|
||||||
|
# www.blender.org
|
||||||
|
mtllib top.mtl
|
||||||
|
o top
|
||||||
|
v -2.100000 -3.149994 1.049999
|
||||||
|
v -2.100000 -3.149994 -1.050001
|
||||||
|
v -2.100000 3.150004 1.049999
|
||||||
|
v -2.100000 3.150004 -1.050001
|
||||||
|
v -4.200000 3.150003 -1.050001
|
||||||
|
v -4.200000 3.150003 1.049999
|
||||||
|
v -2.100000 3.150003 1.049999
|
||||||
|
v -2.100000 3.150003 -1.050001
|
||||||
|
v -4.200000 -3.149994 -1.050001
|
||||||
|
v -4.200000 -3.149994 1.049999
|
||||||
|
v -2.100000 -3.149994 1.049999
|
||||||
|
v -2.100000 -3.149994 -1.050001
|
||||||
|
v 2.100000 -3.149994 -1.050001
|
||||||
|
v 2.100000 -3.149994 1.049999
|
||||||
|
v 2.100000 3.150004 -1.050001
|
||||||
|
v 2.100000 3.150004 1.049999
|
||||||
|
v 2.100000 -3.149994 -1.050001
|
||||||
|
v 2.100000 -3.149994 1.049999
|
||||||
|
v 4.200000 -3.149994 1.049999
|
||||||
|
v 4.200000 -3.149994 -1.050001
|
||||||
|
v 2.100000 3.150003 -1.050001
|
||||||
|
v 2.100000 3.150003 1.049999
|
||||||
|
v 4.200000 3.150003 1.049999
|
||||||
|
v 4.200000 3.150003 -1.050001
|
||||||
|
v 2.100000 3.150004 -1.050001
|
||||||
|
v 2.100000 3.150004 -1.050001
|
||||||
|
v 2.100000 3.150004 1.049999
|
||||||
|
v 2.100000 3.150004 1.049999
|
||||||
|
v 2.100000 -3.149994 1.049999
|
||||||
|
v 2.100000 -3.149994 1.049999
|
||||||
|
v 2.100000 -3.149994 -1.050001
|
||||||
|
v 2.100000 -3.149994 -1.050001
|
||||||
|
v -2.100000 3.150004 1.049999
|
||||||
|
v -2.100000 3.150004 1.049999
|
||||||
|
v -2.100000 -3.149994 1.049999
|
||||||
|
v -2.100000 -3.149994 1.049999
|
||||||
|
v -2.100000 3.150004 -1.050001
|
||||||
|
v -2.100000 3.150004 -1.050001
|
||||||
|
v -2.100000 -3.149994 -1.050001
|
||||||
|
v -2.100000 -3.149994 -1.050001
|
||||||
|
v -4.200000 3.150003 -1.050001
|
||||||
|
v -4.200000 3.150003 -1.050001
|
||||||
|
v -4.200000 -3.149994 -1.050001
|
||||||
|
v -4.200000 -3.149994 -1.050001
|
||||||
|
v -2.100000 3.150003 1.049999
|
||||||
|
v -2.100000 3.150003 1.049999
|
||||||
|
v -2.100000 -3.149994 1.049999
|
||||||
|
v -2.100000 -3.149994 1.049999
|
||||||
|
v -4.200000 3.150003 1.049999
|
||||||
|
v -4.200000 3.150003 1.049999
|
||||||
|
v -4.200000 -3.149994 1.049999
|
||||||
|
v -4.200000 -3.149994 1.049999
|
||||||
|
v -2.100000 3.150003 -1.050001
|
||||||
|
v -2.100000 3.150003 -1.050001
|
||||||
|
v -2.100000 -3.149994 -1.050001
|
||||||
|
v -2.100000 -3.149994 -1.050001
|
||||||
|
v 2.100000 3.150003 -1.050001
|
||||||
|
v 2.100000 3.150003 -1.050001
|
||||||
|
v 2.100000 3.150003 1.049999
|
||||||
|
v 2.100000 3.150003 1.049999
|
||||||
|
v 2.100000 -3.149994 1.049999
|
||||||
|
v 2.100000 -3.149994 1.049999
|
||||||
|
v 2.100000 -3.149994 -1.050001
|
||||||
|
v 2.100000 -3.149994 -1.050001
|
||||||
|
v 4.200000 3.150003 1.049999
|
||||||
|
v 4.200000 3.150003 1.049999
|
||||||
|
v 4.200000 -3.149994 1.049999
|
||||||
|
v 4.200000 -3.149994 1.049999
|
||||||
|
v 4.200000 3.150003 -1.050001
|
||||||
|
v 4.200000 3.150003 -1.050001
|
||||||
|
v 4.200000 -3.149994 -1.050001
|
||||||
|
v 4.200000 -3.149994 -1.050001
|
||||||
|
vt 0.625000 0.375000
|
||||||
|
vt 0.500000 0.375000
|
||||||
|
vt 0.500000 0.000000
|
||||||
|
vt 0.625000 0.000000
|
||||||
|
vt 0.500000 0.375000
|
||||||
|
vt 0.437500 0.375000
|
||||||
|
vt 0.437500 0.000000
|
||||||
|
vt 0.500000 0.000000
|
||||||
|
vt 0.437500 0.375000
|
||||||
|
vt 0.312500 0.375000
|
||||||
|
vt 0.312500 0.000000
|
||||||
|
vt 0.437500 0.000000
|
||||||
|
vt 0.562500 0.375000
|
||||||
|
vt 0.562500 0.500000
|
||||||
|
vt 0.437500 0.500000
|
||||||
|
vt 0.437500 0.375000
|
||||||
|
vt 0.437500 0.375000
|
||||||
|
vt 0.437500 0.500000
|
||||||
|
vt 0.312500 0.500000
|
||||||
|
vt 0.312500 0.375000
|
||||||
|
vt 0.812500 0.375000
|
||||||
|
vt 0.875000 0.375000
|
||||||
|
vt 0.875000 0.000000
|
||||||
|
vt 0.812500 0.000000
|
||||||
|
vt 0.750000 0.375000
|
||||||
|
vt 0.812500 0.375000
|
||||||
|
vt 0.812500 0.000000
|
||||||
|
vt 0.750000 0.000000
|
||||||
|
vt 0.750000 0.375000
|
||||||
|
vt 0.812500 0.375000
|
||||||
|
vt 0.812500 0.500000
|
||||||
|
vt 0.750000 0.500000
|
||||||
|
vt 0.687500 0.375000
|
||||||
|
vt 0.750000 0.375000
|
||||||
|
vt 0.750000 0.500000
|
||||||
|
vt 0.687500 0.500000
|
||||||
|
vt 0.250000 0.375000
|
||||||
|
vt 0.250000 0.000000
|
||||||
|
vt 0.312500 0.000000
|
||||||
|
vt 0.312500 0.375000
|
||||||
|
vt 0.687500 0.375000
|
||||||
|
vt 0.750000 0.375000
|
||||||
|
vt 0.750000 0.000000
|
||||||
|
vt 0.687500 0.000000
|
||||||
|
vt 0.625000 0.375000
|
||||||
|
vt 0.687500 0.375000
|
||||||
|
vt 0.687500 0.000000
|
||||||
|
vt 0.625000 0.000000
|
||||||
|
vt 0.625000 0.375000
|
||||||
|
vt 0.625000 0.000000
|
||||||
|
vt 0.687500 0.000000
|
||||||
|
vt 0.687500 0.375000
|
||||||
|
vt 0.687500 0.375000
|
||||||
|
vt 0.687500 0.500000
|
||||||
|
vt 0.750000 0.500000
|
||||||
|
vt 0.750000 0.375000
|
||||||
|
vt 0.687500 0.375000
|
||||||
|
vt 0.687500 0.000000
|
||||||
|
vt 0.750000 0.000000
|
||||||
|
vt 0.750000 0.375000
|
||||||
|
vt 0.750000 0.375000
|
||||||
|
vt 0.750000 0.000000
|
||||||
|
vt 0.812500 0.000000
|
||||||
|
vt 0.812500 0.375000
|
||||||
|
vt 0.750000 0.375000
|
||||||
|
vt 0.750000 0.500000
|
||||||
|
vt 0.812500 0.500000
|
||||||
|
vt 0.812500 0.375000
|
||||||
|
vt 0.812500 0.375000
|
||||||
|
vt 0.812500 0.000000
|
||||||
|
vt 0.875000 0.000000
|
||||||
|
vt 0.875000 0.375000
|
||||||
|
vn -0.0000 0.0000 1.0000
|
||||||
|
vn -1.0000 0.0000 0.0000
|
||||||
|
vn 0.0000 0.0000 -1.0000
|
||||||
|
vn 0.0000 -1.0000 0.0000
|
||||||
|
vn 0.0000 1.0000 0.0000
|
||||||
|
vn 1.0000 0.0000 0.0000
|
||||||
|
usemtl Character
|
||||||
|
s off
|
||||||
|
f 27/1/1 3/2/1 1/3/1 14/4/1
|
||||||
|
f 33/5/2 4/6/2 2/7/2 35/8/2
|
||||||
|
f 37/9/3 25/10/3 31/11/3 39/12/3
|
||||||
|
f 13/13/4 29/14/4 36/15/4 40/16/4
|
||||||
|
f 38/17/5 34/18/5 16/19/5 15/20/5
|
||||||
|
f 7/21/1 6/22/1 10/23/1 11/24/1
|
||||||
|
f 8/25/6 45/26/6 47/27/6 12/28/6
|
||||||
|
f 17/29/4 20/30/4 19/31/4 18/32/4
|
||||||
|
f 24/33/5 21/34/5 22/35/5 23/36/5
|
||||||
|
f 28/37/6 30/38/6 32/39/6 26/40/6
|
||||||
|
f 5/41/3 53/42/3 55/43/3 9/44/3
|
||||||
|
f 49/45/2 41/46/2 43/47/2 51/48/2
|
||||||
|
f 65/49/6 67/50/6 71/51/6 69/52/6
|
||||||
|
f 42/53/5 50/54/5 46/55/5 54/56/5
|
||||||
|
f 70/57/3 72/58/3 63/59/3 57/60/3
|
||||||
|
f 58/61/2 64/62/2 61/63/2 59/64/2
|
||||||
|
f 56/65/4 48/66/4 52/67/4 44/68/4
|
||||||
|
f 60/69/1 62/70/1 68/71/1 66/72/1
|
|
@ -0,0 +1,52 @@
|
||||||
|
local function init_simple_skins()
|
||||||
|
local id, f, data, skin = 0
|
||||||
|
local mod_path = minetest.get_modpath("mcl_skins")
|
||||||
|
while true do
|
||||||
|
|
||||||
|
if id == 0 then
|
||||||
|
skin = "character.png"
|
||||||
|
else
|
||||||
|
skin = "mcl_skins_character_" .. id .. ".png"
|
||||||
|
|
||||||
|
-- Does skin file exist?
|
||||||
|
f = io.open(mod_path .. "/textures/" .. skin)
|
||||||
|
|
||||||
|
-- escape loop if not found
|
||||||
|
if not f then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
f:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
local metafile
|
||||||
|
|
||||||
|
-- does metadata exist for that skin file ?
|
||||||
|
if id == 0 then
|
||||||
|
metafile = "mcl_skins_character.txt"
|
||||||
|
else
|
||||||
|
metafile = "mcl_skins_character_"..id..".txt"
|
||||||
|
end
|
||||||
|
f = io.open(mod_path .. "/meta/" .. metafile)
|
||||||
|
|
||||||
|
data = nil
|
||||||
|
if f then
|
||||||
|
data = minetest.deserialize("return {" .. f:read("*all") .. "}")
|
||||||
|
f:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- add metadata to list
|
||||||
|
mcl_skins.simple_skins[id] = {
|
||||||
|
texture = skin,
|
||||||
|
slim_arms = data and data.gender == "female",
|
||||||
|
}
|
||||||
|
id = id + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if #mcl_skins.simple_skins > 0 then
|
||||||
|
table.insert(mcl_skins.tab_names, 1, "skin")
|
||||||
|
else
|
||||||
|
mcl_skins.simple_skins = {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
init_simple_skins()
|
After Width: | Height: | Size: 137 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 153 B |
After Width: | Height: | Size: 377 B |
After Width: | Height: | Size: 144 B |
After Width: | Height: | Size: 694 B |
After Width: | Height: | Size: 151 B |
After Width: | Height: | Size: 604 B |
After Width: | Height: | Size: 137 B |
After Width: | Height: | Size: 680 B |
After Width: | Height: | Size: 141 B |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 203 B |
Before Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 171 B |
After Width: | Height: | Size: 131 B |
After Width: | Height: | Size: 121 B |
After Width: | Height: | Size: 136 B |
After Width: | Height: | Size: 107 B |
After Width: | Height: | Size: 151 B |
After Width: | Height: | Size: 99 B |
After Width: | Height: | Size: 927 B |
After Width: | Height: | Size: 229 B |
After Width: | Height: | Size: 331 B |
After Width: | Height: | Size: 484 B |
After Width: | Height: | Size: 328 B |
After Width: | Height: | Size: 170 B |
After Width: | Height: | Size: 454 B |
After Width: | Height: | Size: 202 B |
After Width: | Height: | Size: 196 B |
After Width: | Height: | Size: 490 B |
After Width: | Height: | Size: 169 B |
After Width: | Height: | Size: 445 B |
After Width: | Height: | Size: 175 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 196 B |
After Width: | Height: | Size: 886 B |
After Width: | Height: | Size: 282 B |
After Width: | Height: | Size: 680 B |
After Width: | Height: | Size: 161 B |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 195 B |
After Width: | Height: | Size: 582 B |
After Width: | Height: | Size: 172 B |
After Width: | Height: | Size: 730 B |
After Width: | Height: | Size: 243 B |
After Width: | Height: | Size: 648 B |
After Width: | Height: | Size: 886 B |
After Width: | Height: | Size: 120 B |
After Width: | Height: | Size: 125 B |
After Width: | Height: | Size: 120 B |
After Width: | Height: | Size: 140 B |
After Width: | Height: | Size: 291 B |
After Width: | Height: | Size: 99 B |
After Width: | Height: | Size: 122 B |
After Width: | Height: | Size: 139 B |
After Width: | Height: | Size: 129 B |
After Width: | Height: | Size: 95 B |
After Width: | Height: | Size: 99 B |
After Width: | Height: | Size: 98 B |
After Width: | Height: | Size: 178 B |
After Width: | Height: | Size: 93 B |
After Width: | Height: | Size: 93 B |
After Width: | Height: | Size: 606 B |
After Width: | Height: | Size: 392 B |
After Width: | Height: | Size: 154 B |
After Width: | Height: | Size: 131 B |
After Width: | Height: | Size: 568 B |
After Width: | Height: | Size: 146 B |
After Width: | Height: | Size: 941 B |
After Width: | Height: | Size: 138 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 150 B |