Merge pull request 'Add support for external custom skins mod' (#3653) from skins into master
Reviewed-on: https://git.minetest.land/MineClone2/MineClone2/pulls/3653 Reviewed-by: ancientmarinerdev <ancientmariner_dev@proton.me>
@ -158,8 +158,10 @@ minetest.register_on_player_inventory_action(function(player, action, inventory,
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.register_on_joinplayer(function(player)
|
minetest.register_on_joinplayer(function(player)
|
||||||
mcl_player.player_set_model(player, "mcl_armor_character.b3d")
|
|
||||||
player:get_inventory():set_size("armor", 5)
|
player:get_inventory():set_size("armor", 5)
|
||||||
|
if not minetest.global_exists("mcl_skins") then
|
||||||
|
mcl_player.player_set_model(player, "mcl_armor_character.b3d")
|
||||||
|
end
|
||||||
|
|
||||||
minetest.after(1, function()
|
minetest.after(1, function()
|
||||||
if player:is_player() then
|
if player:is_player() then
|
||||||
|
@ -2,4 +2,4 @@ name = mcl_meshhand
|
|||||||
author = jordan4ibanez
|
author = jordan4ibanez
|
||||||
description = Applies the player skin texture to the hand.
|
description = Applies the player skin texture to the hand.
|
||||||
depends = mcl_tools, mcl_player
|
depends = mcl_tools, mcl_player
|
||||||
optional_depends = mcl_skins
|
optional_depends = mcl_skins, mcl_custom_skins
|
||||||
|
@ -28,28 +28,6 @@ function mcl_player.player_register_model(name, def)
|
|||||||
models[name] = def
|
models[name] = def
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Default player appearance
|
|
||||||
mcl_player.player_register_model("character.b3d", {
|
|
||||||
animation_speed = 30,
|
|
||||||
textures = {"character.png", },
|
|
||||||
animations = {
|
|
||||||
-- Standard animations.
|
|
||||||
stand = {x= 0, y= 79},
|
|
||||||
lay = {x=162, y=166},
|
|
||||||
walk = {x=168, y=187},
|
|
||||||
mine = {x=189, y=198},
|
|
||||||
walk_mine = {x=200, y=219},
|
|
||||||
sit = {x= 81, y=160},
|
|
||||||
sneak_stand = {x=222, y=302},
|
|
||||||
sneak_mine = {x=346, y=366},
|
|
||||||
sneak_walk = {x=304, y=323},
|
|
||||||
sneak_walk_mine = {x=325, y=344},
|
|
||||||
run_walk = {x=440, y=460},
|
|
||||||
run_walk_mine = {x=461, y=481},
|
|
||||||
sit_mount = {x=484, y=484},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Player stats and animations
|
-- Player stats and animations
|
||||||
local player_model = {}
|
local player_model = {}
|
||||||
local player_textures = {}
|
local player_textures = {}
|
||||||
@ -112,6 +90,7 @@ function mcl_player.player_set_model(player, model_name)
|
|||||||
if player_model[name] == model_name then
|
if player_model[name] == model_name then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
player_model[name] = model_name
|
||||||
player:set_properties({
|
player:set_properties({
|
||||||
mesh = model_name,
|
mesh = model_name,
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
@ -119,14 +98,20 @@ function mcl_player.player_set_model(player, model_name)
|
|||||||
damage_texture_modifier = "^[colorize:red:130",
|
damage_texture_modifier = "^[colorize:red:130",
|
||||||
})
|
})
|
||||||
update_player_textures(player)
|
update_player_textures(player)
|
||||||
mcl_player.player_set_animation(player, "stand")
|
|
||||||
|
local new_anim = "stand"
|
||||||
|
local model_animations = models[model_name].animations
|
||||||
|
local old_anim = player_anim[name]
|
||||||
|
if model_animations and old_anim and model_animations[old_anim] then
|
||||||
|
new_anim = old_anim
|
||||||
|
end
|
||||||
|
mcl_player.player_set_animation(player, new_anim)
|
||||||
else
|
else
|
||||||
player:set_properties({
|
player:set_properties({
|
||||||
textures = { "player.png", "player_back.png", },
|
textures = { "player.png", "player_back.png", },
|
||||||
visual = "upright_sprite",
|
visual = "upright_sprite",
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
player_model[name] = model_name
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_player.player_set_visibility(player, visible)
|
function mcl_player.player_set_visibility(player, visible)
|
||||||
@ -180,7 +165,6 @@ 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
|
||||||
player_visible[name] = true
|
player_visible[name] = true
|
||||||
mcl_player.player_set_model(player, "character.b3d")
|
|
||||||
player_textures[name] = {"character.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>>>>
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
This mod allows advanced skin customization.
|
This mod allows advanced skin customization.
|
||||||
Use the /skin command to open the skin configuration screen.
|
Use the /skin command to open the skin configuration screen.
|
||||||
|
|
||||||
|
To include custom skins in MineClone2, please download [mcl_custom_skins](https://git.minetest.land/mineclone2/mcl_custom_skins)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
Code under MIT license
|
Code under MIT license
|
||||||
Author: TenPlus1, Zeg9, MrRar
|
Author: MrRar
|
||||||
|
|
||||||
See image_credits.txt for image licensing.
|
See image_credits.txt for image licensing.
|
||||||
|
|
||||||
@ -15,6 +17,7 @@ See image_credits.txt for image licensing.
|
|||||||
Register a skin item. `item` is a table with item properties listed below.
|
Register a skin item. `item` is a table with item properties listed below.
|
||||||
|
|
||||||
### Item properties
|
### Item properties
|
||||||
|
|
||||||
`type`
|
`type`
|
||||||
Set the item type. Valid values are: "base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear"
|
Set the item type. Valid values are: "base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear"
|
||||||
|
|
||||||
@ -28,16 +31,40 @@ Coloring only works for "base", "bottom, "top", and "hair".
|
|||||||
`preview_rotation`
|
`preview_rotation`
|
||||||
A table containing properties x and y. x and y represent the x and y rotation of the item preview.
|
A table containing properties x and y. x and y represent the x and y rotation of the item preview.
|
||||||
|
|
||||||
`alex`
|
`template2`
|
||||||
If set to true the item will be default for female character.
|
If set to true the item will be default for female template.
|
||||||
|
|
||||||
`steve`
|
`template1`
|
||||||
If set to true the item will be default for male character.
|
If set to true the item will be default for male template.
|
||||||
|
|
||||||
|
`rank`
|
||||||
|
This property is used to change the application order of the skin item when applied to a player.
|
||||||
|
The default ranks for each item type are:
|
||||||
|
|
||||||
|
base: 10
|
||||||
|
|
||||||
|
footwear: 20
|
||||||
|
|
||||||
|
eye: 30
|
||||||
|
|
||||||
|
mouth: 40
|
||||||
|
|
||||||
|
bottom: 50
|
||||||
|
|
||||||
|
top: 60
|
||||||
|
|
||||||
|
hair: 70
|
||||||
|
|
||||||
|
headwear: 80
|
||||||
|
|
||||||
|
Lower ranks are applied to the player first and can thus be covered by higher rank items.
|
||||||
|
|
||||||
|
|
||||||
### `mcl_skins.show_formspec(player, active_tab, page_num)`
|
### `mcl_skins.show_formspec(player, active_tab, page_num)`
|
||||||
Show the skin configuration screen.
|
Show the skin configuration screen.
|
||||||
|
|
||||||
`player` is a player ObjectRef.
|
`player` is a player ObjectRef.
|
||||||
|
|
||||||
`active_tab` is the tab that will be displayed. This parameter is optional.
|
`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"
|
Can be one of: "arm", "base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear"
|
||||||
|
|
||||||
@ -50,7 +77,9 @@ Returns an array of tables containing information about each skin.
|
|||||||
Each table contains the following properties:
|
Each table contains the following properties:
|
||||||
|
|
||||||
`id`: A string representing the node ID. A node can be registered using this node ID.
|
`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.
|
`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.
|
`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)`
|
### `mcl_skins.get_node_id_by_player(player)`
|
||||||
@ -71,10 +100,19 @@ These colors are separate from `mcl_skins.color` because some mods register two
|
|||||||
### `mcl_skins.color`
|
### `mcl_skins.color`
|
||||||
A table of ColorSpec integers that the player can select to color colorable skin items.
|
A table of ColorSpec integers that the player can select to color colorable skin items.
|
||||||
|
|
||||||
### `mcl_skins.players`
|
### `mcl_skins.player_skins`
|
||||||
A table mapped by player ObjectRef containing tables holding the player's selected skin items and colors.
|
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.
|
Only stores skin information for logged in users.
|
||||||
|
|
||||||
### mcl_skins.compile_skin(skin)
|
### `mcl_skins.compile_skin(skin)`
|
||||||
`skin` is a table with skin item properties.
|
`skin` is a table with skin item properties.
|
||||||
Returns an image string.
|
Returns an image string.
|
||||||
|
|
||||||
|
### `mcl_skins.register_simple_skin(skin)`
|
||||||
|
`skin` is a table with the following properties:
|
||||||
|
|
||||||
|
`texture`
|
||||||
|
The texture of the skin.
|
||||||
|
|
||||||
|
`slim_arms`
|
||||||
|
A boolean value. If set to true, the slim armed player mesh will be used with this skin.
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
local S = minetest.get_translator("mcl_skins")
|
local S = minetest.get_translator("mcl_skins")
|
||||||
local color_to_string = minetest.colorspec_to_colorstring
|
local color_to_string = minetest.colorspec_to_colorstring
|
||||||
|
local EDIT_SKIN_KEY = -1 -- The key used for edit skin in the mcl_skins.simple_skins table
|
||||||
|
|
||||||
mcl_skins = {
|
mcl_skins = {
|
||||||
simple_skins = {},
|
simple_skins = {},
|
||||||
|
texture_to_simple_skin = {},
|
||||||
item_names = {"base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear"},
|
item_names = {"base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear"},
|
||||||
tab_names = {"template", "base", "headwear", "hair", "eye", "mouth", "top", "arm", "bottom", "footwear"},
|
tab_names = {"skin", "template", "base", "headwear", "hair", "eye", "mouth", "top", "arm", "bottom", "footwear"},
|
||||||
tab_descriptions = {
|
tab_descriptions = {
|
||||||
template = S("Templates"),
|
template = S("Templates"),
|
||||||
arm = S("Arm size"),
|
arm = S("Arm size"),
|
||||||
@ -18,8 +20,8 @@ mcl_skins = {
|
|||||||
headwear = S("Headwears"),
|
headwear = S("Headwears"),
|
||||||
skin = S("Skins"),
|
skin = S("Skins"),
|
||||||
},
|
},
|
||||||
steve = {}, -- Stores skin values for Steve skin
|
template1 = {}, -- Stores edit skin values for template1
|
||||||
alex = {}, -- Stores skin values for Alex skin
|
template2 = {}, -- Stores edit skin values for template2
|
||||||
base = {}, -- List of base textures
|
base = {}, -- List of base textures
|
||||||
|
|
||||||
-- Base color is separate to keep the number of junk nodes registered in check
|
-- Base color is separate to keep the number of junk nodes registered in check
|
||||||
@ -50,63 +52,90 @@ mcl_skins = {
|
|||||||
headwear = {},
|
headwear = {},
|
||||||
masks = {},
|
masks = {},
|
||||||
preview_rotations = {},
|
preview_rotations = {},
|
||||||
players = {}
|
ranks = {},
|
||||||
|
player_skins = {},
|
||||||
|
player_formspecs = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
function mcl_skins.register_item(item)
|
function mcl_skins.register_item(item)
|
||||||
assert(mcl_skins[item.type], "Skin item type " .. item.type .. " does not exist.")
|
assert(mcl_skins[item.type], "Skin item type " .. item.type .. " does not exist.")
|
||||||
local texture = item.texture or "blank.png"
|
local texture = item.texture or "blank.png"
|
||||||
if item.steve then
|
if item.template1 then
|
||||||
mcl_skins.steve[item.type] = texture
|
mcl_skins.template1[item.type] = texture
|
||||||
end
|
end
|
||||||
|
|
||||||
if item.alex then
|
if item.template2 then
|
||||||
mcl_skins.alex[item.type] = texture
|
mcl_skins.template2[item.type] = texture
|
||||||
end
|
end
|
||||||
|
|
||||||
table.insert(mcl_skins[item.type], texture)
|
table.insert(mcl_skins[item.type], texture)
|
||||||
mcl_skins.masks[texture] = item.mask
|
mcl_skins.masks[texture] = item.mask
|
||||||
if item.preview_rotation then
|
mcl_skins.preview_rotations[texture] = item.preview_rotation
|
||||||
mcl_skins.preview_rotations[texture] = item.preview_rotation
|
mcl_skins.ranks[texture] = item.rank
|
||||||
|
end
|
||||||
|
|
||||||
|
function mcl_skins.register_simple_skin(skin)
|
||||||
|
if skin.index then
|
||||||
|
mcl_skins.simple_skins[skin.index] = skin
|
||||||
|
else
|
||||||
|
table.insert(mcl_skins.simple_skins, skin)
|
||||||
end
|
end
|
||||||
|
mcl_skins.texture_to_simple_skin[skin.texture] = skin
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_skins.save(player)
|
function mcl_skins.save(player)
|
||||||
local skin = mcl_skins.players[player]
|
local skin = mcl_skins.player_skins[player]
|
||||||
if not skin then return end
|
if not skin then return end
|
||||||
|
|
||||||
local meta = player:get_meta()
|
local meta = player:get_meta()
|
||||||
meta:set_string("mcl_skins:skin", minetest.serialize(skin))
|
meta:set_string("mcl_skins:skin", minetest.serialize(skin))
|
||||||
|
|
||||||
meta:set_string("mcl_skins:skin_id", tostring(skin.simple_skins_id or ""))
|
-- Clear out the old way of storing the simple skin ID
|
||||||
|
meta:set_string("mcl_skins:skin_id", "")
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_chatcommand("skin", {
|
minetest.register_chatcommand("skin", {
|
||||||
description = S("Open skin configuration screen."),
|
description = S("Open skin configuration screen."),
|
||||||
privs = {},
|
privs = {},
|
||||||
func = function(name, param) mcl_skins.show_formspec(minetest.get_player_by_name(name)) end
|
func = function(name, param)
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
local formspec_data = mcl_skins.player_formspecs[player]
|
||||||
|
local active_tab = formspec_data.active_tab
|
||||||
|
local page_num = formspec_data.page_num
|
||||||
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
function mcl_skins.compile_skin(skin)
|
function mcl_skins.compile_skin(skin)
|
||||||
|
if not skin then return "blank.png" end
|
||||||
|
|
||||||
if skin.simple_skins_id then
|
if skin.simple_skins_id then
|
||||||
return mcl_skins.simple_skins[skin.simple_skins_id].texture
|
return skin.simple_skins_id
|
||||||
end
|
end
|
||||||
|
|
||||||
local output = ""
|
local ranks = {}
|
||||||
for i, item in pairs(mcl_skins.item_names) do
|
local layers = {}
|
||||||
|
for i, item in ipairs(mcl_skins.item_names) do
|
||||||
local texture = skin[item]
|
local texture = skin[item]
|
||||||
|
local layer = ""
|
||||||
|
local rank = mcl_skins.ranks[texture] or i * 10
|
||||||
if texture and texture ~= "blank.png" then
|
if texture and texture ~= "blank.png" then
|
||||||
|
|
||||||
if skin[item .. "_color"] and mcl_skins.masks[texture] 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"])
|
local color = color_to_string(skin[item .. "_color"])
|
||||||
output = output ..
|
layer = "(" .. mcl_skins.masks[texture] .. "^[colorize:" .. color .. ":alpha)"
|
||||||
"(" .. mcl_skins.masks[texture] .. "^[colorize:" .. color .. ":alpha)"
|
|
||||||
end
|
end
|
||||||
if #output > 0 then output = output .. "^" end
|
if #layer > 0 then layer = layer .. "^" end
|
||||||
output = output .. texture
|
layer = layer .. texture
|
||||||
|
layers[rank] = layer
|
||||||
|
table.insert(ranks, rank)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
table.sort(ranks)
|
||||||
|
local output = ""
|
||||||
|
for i, rank in ipairs(ranks) do
|
||||||
|
if #output > 0 then output = output .. "^" end
|
||||||
|
output = output .. layers[rank]
|
||||||
|
end
|
||||||
return output
|
return output
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -115,13 +144,13 @@ function mcl_skins.update_player_skin(player)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local skin = mcl_skins.players[player]
|
local skin = mcl_skins.player_skins[player]
|
||||||
|
|
||||||
mcl_player.player_set_skin(player, mcl_skins.compile_skin(skin))
|
mcl_player.player_set_skin(player, mcl_skins.compile_skin(skin))
|
||||||
|
|
||||||
local slim_arms
|
local slim_arms
|
||||||
if skin.simple_skins_id then
|
if skin.simple_skins_id then
|
||||||
slim_arms = mcl_skins.simple_skins[skin.simple_skins_id].slim_arms
|
slim_arms = mcl_skins.texture_to_simple_skin[skin.simple_skins_id].slim_arms
|
||||||
else
|
else
|
||||||
slim_arms = skin.slim_arms
|
slim_arms = skin.slim_arms
|
||||||
end
|
end
|
||||||
@ -131,33 +160,35 @@ end
|
|||||||
|
|
||||||
-- Load player skin on join
|
-- Load player skin on join
|
||||||
minetest.register_on_joinplayer(function(player)
|
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")
|
local skin = player:get_meta():get_string("mcl_skins:skin")
|
||||||
if skin then
|
if skin then
|
||||||
skin = minetest.deserialize(skin)
|
skin = minetest.deserialize(skin)
|
||||||
end
|
end
|
||||||
if skin then
|
if skin then
|
||||||
-- If the player moves a slider and then quickly exits the game, form_send_job gets saved.
|
if not mcl_skins.texture_to_simple_skin[skin.simple_skins_id] then
|
||||||
-- This should never have been put in with the skin data in the first place.
|
skin.simple_skins_id = nil
|
||||||
skin.form_send_job = nil
|
end
|
||||||
|
|
||||||
mcl_skins.players[player] = skin
|
mcl_skins.player_skins[player] = skin
|
||||||
else
|
else
|
||||||
if math.random() > 0.5 then
|
if math.random() > 0.5 then
|
||||||
skin = table.copy(mcl_skins.steve)
|
skin = table.copy(mcl_skins.template1)
|
||||||
else
|
else
|
||||||
skin = table.copy(mcl_skins.alex)
|
skin = table.copy(mcl_skins.template2)
|
||||||
end
|
end
|
||||||
mcl_skins.players[player] = skin
|
mcl_skins.player_skins[player] = skin
|
||||||
end
|
end
|
||||||
|
|
||||||
mcl_skins.players[player].simple_skins_id = nil
|
mcl_skins.player_formspecs[player] = {
|
||||||
|
active_tab = "skin",
|
||||||
|
page_num = 1
|
||||||
|
}
|
||||||
|
|
||||||
if #mcl_skins.simple_skins > 0 then
|
if #mcl_skins.simple_skins > 0 then
|
||||||
local skin_id = tonumber(player:get_meta():get_string("mcl_skins:skin_id"))
|
local skin_id = tonumber(player:get_meta():get_string("mcl_skins:skin_id"))
|
||||||
if skin_id and mcl_skins.simple_skins[skin_id] then
|
if skin_id and mcl_skins.simple_skins[skin_id] then
|
||||||
mcl_skins.players[player].simple_skins_id = skin_id
|
local texture = mcl_skins.simple_skins[skin_id].texture
|
||||||
|
mcl_skins.player_skins[player].simple_skins_id = texture
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
mcl_skins.save(player)
|
mcl_skins.save(player)
|
||||||
@ -165,33 +196,30 @@ minetest.register_on_joinplayer(function(player)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.register_on_leaveplayer(function(player)
|
minetest.register_on_leaveplayer(function(player)
|
||||||
mcl_skins.players[player] = nil
|
mcl_skins.player_skins[player] = nil
|
||||||
|
mcl_skins.player_formspecs[player] = nil
|
||||||
end)
|
end)
|
||||||
|
|
||||||
function mcl_skins.show_formspec(player, active_tab, page_num)
|
local function calculate_page_count(tab)
|
||||||
local skin = mcl_skins.players[player]
|
if tab == "skin" then
|
||||||
local default = #mcl_skins.simple_skins > 0 and "skin" or "template"
|
return math.ceil((#mcl_skins.simple_skins + 2) / 8)
|
||||||
active_tab = active_tab or default
|
elseif mcl_skins[tab] then
|
||||||
page_num = page_num or 1
|
return math.ceil(#mcl_skins[tab] / 16)
|
||||||
|
|
||||||
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
|
end
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
|
local formspec_data = mcl_skins.player_formspecs[player]
|
||||||
|
local skin = mcl_skins.player_skins[player]
|
||||||
|
formspec_data.active_tab = active_tab
|
||||||
|
|
||||||
local formspec = "formspec_version[3]size[13.2,11]"
|
local page_count = calculate_page_count(active_tab)
|
||||||
|
if page_num < 1 then page_num = 1 end
|
||||||
|
if page_num > page_count then page_num = page_count end
|
||||||
|
formspec_data.page_num = page_num
|
||||||
|
|
||||||
|
local formspec = "formspec_version[3]size[14.2,11]"
|
||||||
|
|
||||||
for i, tab in pairs(mcl_skins.tab_names) do
|
for i, tab in pairs(mcl_skins.tab_names) do
|
||||||
if tab == active_tab then
|
if tab == active_tab then
|
||||||
@ -201,21 +229,23 @@ function mcl_skins.show_formspec(player, active_tab, page_num)
|
|||||||
|
|
||||||
local y = 0.3 + (i - 1) * 0.8
|
local y = 0.3 + (i - 1) * 0.8
|
||||||
formspec = formspec ..
|
formspec = formspec ..
|
||||||
"button[0.3," .. y .. ";3,0.8;" .. tab .. ";" .. mcl_skins.tab_descriptions[tab] .. "]"
|
"style[" .. tab .. ";content_offset=16,0]" ..
|
||||||
|
"button[0.3," .. y .. ";4,0.8;" .. tab .. ";" .. mcl_skins.tab_descriptions[tab] .. "]" ..
|
||||||
|
"image[0.4," .. y + 0.1 .. ";0.6,0.6;mcl_skins_icons.png^[verticalframe:11:" .. i - 1 .. "]"
|
||||||
|
|
||||||
if skin.simple_skins_id then break end
|
if skin.simple_skins_id then break end
|
||||||
end
|
end
|
||||||
|
|
||||||
local slim_arms
|
local slim_arms
|
||||||
if skin.simple_skins_id then
|
if skin.simple_skins_id then
|
||||||
slim_arms = mcl_skins.simple_skins[skin.simple_skins_id].slim_arms
|
slim_arms = mcl_skins.texture_to_simple_skin[skin.simple_skins_id].slim_arms
|
||||||
else
|
else
|
||||||
slim_arms = skin.slim_arms
|
slim_arms = skin.slim_arms
|
||||||
end
|
end
|
||||||
local mesh = slim_arms and "mcl_armor_character_female.b3d" or "mcl_armor_character.b3d"
|
local mesh = slim_arms and "mcl_armor_character_female.b3d" or "mcl_armor_character.b3d"
|
||||||
|
|
||||||
formspec = formspec ..
|
formspec = formspec ..
|
||||||
"model[10,0.3;3,7;player_mesh;" .. mesh .. ";" ..
|
"model[11,0.3;3,7;player_mesh;" .. mesh .. ";" ..
|
||||||
mcl_skins.compile_skin(skin) ..
|
mcl_skins.compile_skin(skin) ..
|
||||||
",blank.png,blank.png;0,180;false;true;0,0]"
|
",blank.png,blank.png;0,180;false;true;0,0]"
|
||||||
|
|
||||||
@ -224,23 +254,24 @@ function mcl_skins.show_formspec(player, active_tab, page_num)
|
|||||||
local page_end = math.min(page_start + 8 - 1, #mcl_skins.simple_skins)
|
local page_end = math.min(page_start + 8 - 1, #mcl_skins.simple_skins)
|
||||||
formspec = formspec ..
|
formspec = formspec ..
|
||||||
"style_type[button;bgcolor=#00000000]"
|
"style_type[button;bgcolor=#00000000]"
|
||||||
|
|
||||||
local skin = table.copy(skin)
|
local skin = table.copy(skin)
|
||||||
local skin_id = skin.simple_skins_id or -1
|
local simple_skins_id = skin.simple_skins_id
|
||||||
skin.simple_skins_id = nil
|
skin.simple_skins_id = nil
|
||||||
|
mcl_skins.simple_skins[EDIT_SKIN_KEY] = {
|
||||||
local skins = table.copy(mcl_skins.simple_skins)
|
|
||||||
skins[-1] = {
|
|
||||||
slim_arms = skin.slim_arms,
|
slim_arms = skin.slim_arms,
|
||||||
texture = mcl_skins.compile_skin(skin),
|
texture = mcl_skins.compile_skin(skin),
|
||||||
}
|
}
|
||||||
|
simple_skins_id = simple_skins_id or
|
||||||
|
mcl_skins.simple_skins[EDIT_SKIN_KEY].texture
|
||||||
|
|
||||||
for i = page_start, page_end do
|
for i = page_start, page_end do
|
||||||
local skin = skins[i]
|
local skin = mcl_skins.simple_skins[i]
|
||||||
local j = i - page_start - 1
|
local j = i - page_start - 1
|
||||||
local mesh = skin.slim_arms and "mcl_armor_character_female.b3d" or "mcl_armor_character.b3d"
|
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 x = 4.5 + (j + 1) % 4 * 1.6
|
||||||
local y = 0.3 + math.floor((j + 1) / 4) * 3.1
|
local y = 0.3 + math.floor((j + 1) / 4) * 3.1
|
||||||
|
|
||||||
formspec = formspec ..
|
formspec = formspec ..
|
||||||
@ -248,7 +279,7 @@ function mcl_skins.show_formspec(player, active_tab, page_num)
|
|||||||
skin.texture ..
|
skin.texture ..
|
||||||
",blank.png,blank.png;0,180;false;true;0,0]"
|
",blank.png,blank.png;0,180;false;true;0,0]"
|
||||||
|
|
||||||
if skin_id == i then
|
if simple_skins_id == skin.texture then
|
||||||
formspec = formspec ..
|
formspec = formspec ..
|
||||||
"style[" .. i ..
|
"style[" .. i ..
|
||||||
";bgcolor=;bgimg=mcl_skins_select_overlay.png;" ..
|
";bgcolor=;bgimg=mcl_skins_select_overlay.png;" ..
|
||||||
@ -258,22 +289,22 @@ function mcl_skins.show_formspec(player, active_tab, page_num)
|
|||||||
"button[" .. x .. "," .. y .. ";1.5,3;" .. i .. ";]"
|
"button[" .. x .. "," .. y .. ";1.5,3;" .. i .. ";]"
|
||||||
end
|
end
|
||||||
|
|
||||||
if page_start == -1 then
|
if page_start == EDIT_SKIN_KEY then
|
||||||
formspec = formspec .. "image[3.85,1;0.8,0.8;mcl_skins_button.png]"
|
formspec = formspec .. "image[4.85,1;0.8,0.8;mcl_skins_button.png]"
|
||||||
end
|
end
|
||||||
elseif active_tab == "template" then
|
elseif active_tab == "template" then
|
||||||
formspec = formspec ..
|
formspec = formspec ..
|
||||||
"model[4,2;2,3;player_mesh;mcl_armor_character.b3d;" ..
|
"model[5,2;2,3;player_mesh;mcl_armor_character.b3d;" ..
|
||||||
mcl_skins.compile_skin(mcl_skins.steve) ..
|
mcl_skins.compile_skin(mcl_skins.template1) ..
|
||||||
",blank.png,blank.png;0,180;false;true;0,0]" ..
|
",blank.png,blank.png;0,180;false;true;0,0]" ..
|
||||||
|
|
||||||
"button[4,5.2;2,0.8;steve;" .. S("Select") .. "]" ..
|
"button[5,5.2;2,0.8;template1;" .. S("Select") .. "]" ..
|
||||||
|
|
||||||
"model[6.5,2;2,3;player_mesh;mcl_armor_character_female.b3d;" ..
|
"model[7.5,2;2,3;player_mesh;mcl_armor_character_female.b3d;" ..
|
||||||
mcl_skins.compile_skin(mcl_skins.alex) ..
|
mcl_skins.compile_skin(mcl_skins.template2) ..
|
||||||
",blank.png,blank.png;0,180;false;true;0,0]" ..
|
",blank.png,blank.png;0,180;false;true;0,0]" ..
|
||||||
|
|
||||||
"button[6.5,5.2;2,0.8;alex;" .. S("Select") .. "]"
|
"button[7.5,5.2;2,0.8;template2;" .. S("Select") .. "]"
|
||||||
|
|
||||||
elseif mcl_skins[active_tab] then
|
elseif mcl_skins[active_tab] then
|
||||||
formspec = formspec ..
|
formspec = formspec ..
|
||||||
@ -308,7 +339,7 @@ function mcl_skins.show_formspec(player, active_tab, page_num)
|
|||||||
end
|
end
|
||||||
|
|
||||||
i = i - 1
|
i = i - 1
|
||||||
local x = 3.5 + i % 4 * 1.6
|
local x = 4.5 + i % 4 * 1.6
|
||||||
local y = 0.3 + math.floor(i / 4) * 1.6
|
local y = 0.3 + math.floor(i / 4) * 1.6
|
||||||
formspec = formspec ..
|
formspec = formspec ..
|
||||||
"model[" .. x .. "," .. y ..
|
"model[" .. x .. "," .. y ..
|
||||||
@ -325,11 +356,12 @@ function mcl_skins.show_formspec(player, active_tab, page_num)
|
|||||||
formspec = formspec .. "button[" .. x .. "," .. y .. ";1.5,1.5;" .. texture .. ";]"
|
formspec = formspec .. "button[" .. x .. "," .. y .. ";1.5,1.5;" .. texture .. ";]"
|
||||||
end
|
end
|
||||||
elseif active_tab == "arm" then
|
elseif active_tab == "arm" then
|
||||||
local x = skin.slim_arms and 4.7 or 3.6
|
local x = skin.slim_arms and 5.7 or 4.6
|
||||||
formspec = formspec ..
|
formspec = formspec ..
|
||||||
"image_button[3.6,0.3;1,1;mcl_skins_thick_arms.png;thick_arms;]" ..
|
"image_button[4.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;]" ..
|
"image_button[5.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]" ..
|
"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;]"
|
"button[" .. x .. ",0.3;1,1;arm;]"
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -343,7 +375,7 @@ function mcl_skins.show_formspec(player, active_tab, page_num)
|
|||||||
for i, colorspec in pairs(colors) do
|
for i, colorspec in pairs(colors) do
|
||||||
local color = color_to_string(colorspec)
|
local color = color_to_string(colorspec)
|
||||||
i = i - 1
|
i = i - 1
|
||||||
local x = 3.6 + i % 6 * 0.9
|
local x = 4.6 + i % 6 * 0.9
|
||||||
local y = 8 + math.floor(i / 6) * 0.9
|
local y = 8 + math.floor(i / 6) * 0.9
|
||||||
formspec = formspec ..
|
formspec = formspec ..
|
||||||
"image_button[" .. x .. "," .. y ..
|
"image_button[" .. x .. "," .. y ..
|
||||||
@ -353,7 +385,8 @@ function mcl_skins.show_formspec(player, active_tab, page_num)
|
|||||||
if selected_color == colorspec then
|
if selected_color == colorspec then
|
||||||
formspec = formspec ..
|
formspec = formspec ..
|
||||||
"style[" .. color ..
|
"style[" .. color ..
|
||||||
";bgcolor=;bgimg=mcl_skins_select_overlay.png;bgimg_middle=14,14;bgimg_pressed=mcl_skins_select_overlay.png]" ..
|
";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 .. ";]"
|
"button[" .. x .. "," .. y .. ";0.8,0.8;" .. color .. ";]"
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -365,7 +398,7 @@ function mcl_skins.show_formspec(player, active_tab, page_num)
|
|||||||
local green = math.floor(selected_color / 0x100) - 0xff0000 - red * 0x100
|
local green = math.floor(selected_color / 0x100) - 0xff0000 - red * 0x100
|
||||||
local blue = selected_color - 0xff000000 - red * 0x10000 - green * 0x100
|
local blue = selected_color - 0xff000000 - red * 0x10000 - green * 0x100
|
||||||
formspec = formspec ..
|
formspec = formspec ..
|
||||||
"container[9.2,8]" ..
|
"container[10.2,8]" ..
|
||||||
"scrollbaroptions[min=0;max=255;smallstep=20]" ..
|
"scrollbaroptions[min=0;max=255;smallstep=20]" ..
|
||||||
|
|
||||||
"box[0.4,0;2.49,0.38;red]" ..
|
"box[0.4,0;2.49,0.38;red]" ..
|
||||||
@ -386,49 +419,42 @@ function mcl_skins.show_formspec(player, active_tab, page_num)
|
|||||||
"container_end[]"
|
"container_end[]"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if page_num > 1 then
|
if page_num > 1 then
|
||||||
formspec = formspec ..
|
formspec = formspec ..
|
||||||
"image_button[3.5,6.7;1,1;mcl_skins_arrow.png^[transformFX;previous_page;]"
|
"image_button[4.5,6.7;1,1;mcl_skins_arrow.png^[transformFX;previous_page;]"
|
||||||
end
|
end
|
||||||
|
|
||||||
if page_num < page_count then
|
if page_num < page_count then
|
||||||
formspec = formspec ..
|
formspec = formspec ..
|
||||||
"image_button[8.8,6.7;1,1;mcl_skins_arrow.png;next_page;]"
|
"image_button[9.8,6.7;1,1;mcl_skins_arrow.png;next_page;]"
|
||||||
end
|
end
|
||||||
|
|
||||||
if page_count > 1 then
|
if page_count > 1 then
|
||||||
formspec = formspec ..
|
formspec = formspec ..
|
||||||
"label[6.3,7.2;" .. page_num .. " / " .. page_count .. "]"
|
"label[7.3,7.2;" .. page_num .. " / " .. page_count .. "]"
|
||||||
end
|
end
|
||||||
|
|
||||||
local player_name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
minetest.show_formspec(player_name, "mcl_skins:" .. active_tab .. "_" .. page_num, formspec)
|
minetest.show_formspec(player_name, "mcl_skins:skins", formspec)
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
|
local formspec_data = mcl_skins.player_formspecs[player]
|
||||||
|
local active_tab = formspec_data.active_tab
|
||||||
|
local page_num = formspec_data.page_num
|
||||||
|
|
||||||
if fields.__mcl_skins then
|
if fields.__mcl_skins then
|
||||||
mcl_skins.show_formspec(player)
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if formname ~= "mcl_skins:skins" then 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
|
-- Cancel formspec resend after scrollbar move
|
||||||
if mcl_skins.players[player].form_send_job then
|
if formspec_data.form_send_job then
|
||||||
mcl_skins.players[player].form_send_job:cancel()
|
formspec_data.form_send_job:cancel()
|
||||||
mcl_skins.players[player].form_send_job = nil
|
formspec_data.form_send_job = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
if fields.quit then
|
if fields.quit then
|
||||||
@ -436,13 +462,13 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
if fields.alex then
|
if fields.template2 then
|
||||||
mcl_skins.players[player] = table.copy(mcl_skins.alex)
|
mcl_skins.player_skins[player] = table.copy(mcl_skins.template2)
|
||||||
mcl_skins.update_player_skin(player)
|
mcl_skins.update_player_skin(player)
|
||||||
mcl_skins.show_formspec(player, active_tab, page_num)
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
return true
|
return true
|
||||||
elseif fields.steve then
|
elseif fields.template1 then
|
||||||
mcl_skins.players[player] = table.copy(mcl_skins.steve)
|
mcl_skins.player_skins[player] = table.copy(mcl_skins.template1)
|
||||||
mcl_skins.update_player_skin(player)
|
mcl_skins.update_player_skin(player)
|
||||||
mcl_skins.show_formspec(player, active_tab, page_num)
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
return true
|
return true
|
||||||
@ -450,12 +476,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
|
|
||||||
for i, tab in pairs(mcl_skins.tab_names) do
|
for i, tab in pairs(mcl_skins.tab_names) do
|
||||||
if fields[tab] then
|
if fields[tab] then
|
||||||
mcl_skins.show_formspec(player, tab, page_num)
|
mcl_skins.show_formspec(player, tab, 1)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local skin = mcl_skins.players[player]
|
local skin = mcl_skins.player_skins[player]
|
||||||
if not skin then return true end
|
if not skin then return true end
|
||||||
|
|
||||||
if fields.next_page then
|
if fields.next_page then
|
||||||
@ -496,12 +522,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
local color = 0xff000000 + red * 0x10000 + green * 0x100 + blue
|
local color = 0xff000000 + red * 0x10000 + green * 0x100 + blue
|
||||||
if color >= 0 and color <= 0xffffffff then
|
if color >= 0 and color <= 0xffffffff then
|
||||||
-- We delay resedning the form because otherwise it will break dragging scrollbars
|
-- We delay resedning the form because otherwise it will break dragging scrollbars
|
||||||
mcl_skins.players[player].form_send_job = minetest.after(0.2, function()
|
formspec_data.form_send_job = minetest.after(0.2, function()
|
||||||
if player and player:is_player() then
|
if player and player:is_player() then
|
||||||
skin[active_tab .. "_color"] = color
|
skin[active_tab .. "_color"] = color
|
||||||
mcl_skins.update_player_skin(player)
|
mcl_skins.update_player_skin(player)
|
||||||
mcl_skins.show_formspec(player, active_tab, page_num)
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
mcl_skins.players[player].form_send_job = nil
|
formspec_data.form_send_job = nil
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
return true
|
return true
|
||||||
@ -517,14 +543,14 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if field and active_tab == "skin" then
|
if field and active_tab == "skin" then
|
||||||
local skin_id = tonumber(field)
|
local index = tonumber(field)
|
||||||
skin_id = skin_id and math.floor(skin_id) or 0
|
index = index and math.floor(index) or 0
|
||||||
|
mcl_skins.simple_skins[EDIT_SKIN_KEY].texture = nil
|
||||||
if
|
if
|
||||||
#mcl_skins.simple_skins > 0 and
|
#mcl_skins.simple_skins > 0 and
|
||||||
skin_id >= -1 and skin_id <= #mcl_skins.simple_skins
|
index >= EDIT_SKIN_KEY and index <= #mcl_skins.simple_skins
|
||||||
then
|
then
|
||||||
if skin_id == -1 then skin_id = nil end
|
skin.simple_skins_id = mcl_skins.simple_skins[index].texture
|
||||||
skin.simple_skins_id = skin_id
|
|
||||||
mcl_skins.update_player_skin(player)
|
mcl_skins.update_player_skin(player)
|
||||||
mcl_skins.show_formspec(player, active_tab, page_num)
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
end
|
end
|
||||||
@ -532,15 +558,14 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- See if field is a texture
|
-- See if field is a texture
|
||||||
if field and mcl_skins[active_tab] then
|
if
|
||||||
for i, texture in pairs(mcl_skins[active_tab]) do
|
field and mcl_skins[active_tab] and
|
||||||
if texture == field then
|
table.indexof(mcl_skins[active_tab], field) ~= -1
|
||||||
skin[active_tab] = texture
|
then
|
||||||
mcl_skins.update_player_skin(player)
|
skin[active_tab] = field
|
||||||
mcl_skins.show_formspec(player, active_tab, page_num)
|
mcl_skins.update_player_skin(player)
|
||||||
return true
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
end
|
return true
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- See if field is a color
|
-- See if field is a color
|
||||||
@ -559,15 +584,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
local function init()
|
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")
|
local f = io.open(minetest.get_modpath("mcl_skins") .. "/list.json")
|
||||||
assert(f, "Can't open the file list.json")
|
assert(f, "Can't open the file list.json")
|
||||||
local data = f:read("*all")
|
local data = f:read("*all")
|
||||||
@ -579,17 +595,27 @@ local function init()
|
|||||||
for _, item in pairs(json) do
|
for _, item in pairs(json) do
|
||||||
mcl_skins.register_item(item)
|
mcl_skins.register_item(item)
|
||||||
end
|
end
|
||||||
mcl_skins.steve.base_color = mcl_skins.base_color[2]
|
mcl_skins.template1.base_color = mcl_skins.base_color[2]
|
||||||
mcl_skins.steve.hair_color = 0xff5d473b
|
mcl_skins.template1.hair_color = 0xff5d473b
|
||||||
mcl_skins.steve.top_color = 0xff993535
|
mcl_skins.template1.top_color = 0xff993535
|
||||||
mcl_skins.steve.bottom_color = 0xff644939
|
mcl_skins.template1.bottom_color = 0xff644939
|
||||||
mcl_skins.steve.slim_arms = false
|
mcl_skins.template1.slim_arms = false
|
||||||
|
|
||||||
mcl_skins.alex.base_color = mcl_skins.base_color[1]
|
mcl_skins.template2.base_color = mcl_skins.base_color[1]
|
||||||
mcl_skins.alex.hair_color = 0xff715d57
|
mcl_skins.template2.hair_color = 0xff715d57
|
||||||
mcl_skins.alex.top_color = 0xff346840
|
mcl_skins.template2.top_color = 0xff346840
|
||||||
mcl_skins.alex.bottom_color = 0xff383532
|
mcl_skins.template2.bottom_color = 0xff383532
|
||||||
mcl_skins.alex.slim_arms = true
|
mcl_skins.template2.slim_arms = true
|
||||||
|
|
||||||
|
mcl_skins.register_simple_skin({
|
||||||
|
index = 0,
|
||||||
|
texture = "character.png"
|
||||||
|
})
|
||||||
|
mcl_skins.register_simple_skin({
|
||||||
|
index = 1,
|
||||||
|
texture = "mcl_skins_character_1.png",
|
||||||
|
slim_arms = true
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
init()
|
init()
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
{
|
{
|
||||||
"type": "footwear",
|
"type": "footwear",
|
||||||
"texture": "mcl_skins_footwear_1.png",
|
"texture": "mcl_skins_footwear_1.png",
|
||||||
"steve": true,
|
"template1": true,
|
||||||
"alex": true
|
"template2": true,
|
||||||
|
"rank": 55
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "footwear",
|
"type": "footwear",
|
||||||
@ -19,12 +20,12 @@
|
|||||||
{
|
{
|
||||||
"type": "eye",
|
"type": "eye",
|
||||||
"texture": "mcl_skins_eye_1.png",
|
"texture": "mcl_skins_eye_1.png",
|
||||||
"alex": true
|
"template2": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "eye",
|
"type": "eye",
|
||||||
"texture": "mcl_skins_eye_2.png",
|
"texture": "mcl_skins_eye_2.png",
|
||||||
"steve": true
|
"template1": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "eye",
|
"type": "eye",
|
||||||
@ -49,7 +50,7 @@
|
|||||||
{
|
{
|
||||||
"type": "mouth",
|
"type": "mouth",
|
||||||
"texture": "mcl_skins_mouth_1.png",
|
"texture": "mcl_skins_mouth_1.png",
|
||||||
"steve": true
|
"template1": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "mouth",
|
"type": "mouth",
|
||||||
@ -77,19 +78,19 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "mouth",
|
"type": "mouth",
|
||||||
"alex": true
|
"template1": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hair",
|
"type": "hair",
|
||||||
"texture": "mcl_skins_hair_1.png",
|
"texture": "mcl_skins_hair_1.png",
|
||||||
"mask": "mcl_skins_hair_1_mask.png",
|
"mask": "mcl_skins_hair_1_mask.png",
|
||||||
"alex": true
|
"template2": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hair",
|
"type": "hair",
|
||||||
"texture": "mcl_skins_hair_2.png",
|
"texture": "mcl_skins_hair_2.png",
|
||||||
"mask": "mcl_skins_hair_2_mask.png",
|
"mask": "mcl_skins_hair_2_mask.png",
|
||||||
"steve": true
|
"template1": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hair",
|
"type": "hair",
|
||||||
@ -146,7 +147,7 @@
|
|||||||
{
|
{
|
||||||
"type": "headwear",
|
"type": "headwear",
|
||||||
"texture": "mcl_skins_headwear_2.png",
|
"texture": "mcl_skins_headwear_2.png",
|
||||||
"alex": true
|
"template2": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "headwear",
|
"type": "headwear",
|
||||||
@ -174,14 +175,14 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "headwear",
|
"type": "headwear",
|
||||||
"steve": true
|
"template1": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "bottom",
|
"type": "bottom",
|
||||||
"texture": "mcl_skins_bottom_1.png",
|
"texture": "mcl_skins_bottom_1.png",
|
||||||
"mask": "mcl_skins_bottom_1_mask.png",
|
"mask": "mcl_skins_bottom_1_mask.png",
|
||||||
"steve": true,
|
"template1": true,
|
||||||
"alex": true
|
"template2": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "bottom",
|
"type": "bottom",
|
||||||
@ -198,12 +199,18 @@
|
|||||||
"texture": "mcl_skins_bottom_4.png",
|
"texture": "mcl_skins_bottom_4.png",
|
||||||
"mask": "mcl_skins_bottom_4_mask.png"
|
"mask": "mcl_skins_bottom_4_mask.png"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "bottom",
|
||||||
|
"texture": "mcl_skins_bottom_5.png",
|
||||||
|
"mask": "mcl_skins_bottom_5_mask.png",
|
||||||
|
"rank": 65
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "top",
|
"type": "top",
|
||||||
"texture": "mcl_skins_top_1.png",
|
"texture": "mcl_skins_top_1.png",
|
||||||
"mask": "mcl_skins_top_1_mask.png",
|
"mask": "mcl_skins_top_1_mask.png",
|
||||||
"steve": true,
|
"template1": true,
|
||||||
"alex": true
|
"template2": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "top",
|
"type": "top",
|
||||||
@ -254,7 +261,7 @@
|
|||||||
"type": "base",
|
"type": "base",
|
||||||
"texture": "mcl_skins_base_1.png",
|
"texture": "mcl_skins_base_1.png",
|
||||||
"mask": "mcl_skins_base_1_mask.png",
|
"mask": "mcl_skins_base_1_mask.png",
|
||||||
"steve": true,
|
"template1": true,
|
||||||
"alex": true
|
"template2": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -21,6 +21,9 @@ mcl_skins_bottom_3.png
|
|||||||
mcl_skins_eye_7.png
|
mcl_skins_eye_7.png
|
||||||
mcl_skins_mouth_7.png
|
mcl_skins_mouth_7.png
|
||||||
mcl_skins_hair_10.png
|
mcl_skins_hair_10.png
|
||||||
|
mcl_skins_hair_6.png
|
||||||
|
mcl_skins_eye_6.png
|
||||||
|
mcl_skins_bottom_5.png
|
||||||
Original work by MrRar
|
Original work by MrRar
|
||||||
License: CC BY-SA 4.0
|
License: CC BY-SA 4.0
|
||||||
|
|
||||||
@ -66,13 +69,6 @@ Author: hansuke123. Adapted for mcl_skins by MrRar.
|
|||||||
License: CC BY-SA 3.0
|
License: CC BY-SA 3.0
|
||||||
Source: http://minetest.fensta.bplaced.net/#!page:1,filtertype:Id,filter:291
|
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
|
mcl_skins_eye_4.png
|
||||||
Name: lisa
|
Name: lisa
|
||||||
Author: hansuke123
|
Author: hansuke123
|
||||||
|
@ -14,7 +14,9 @@ function mcl_skins.get_skin_list()
|
|||||||
for _, game_mode in pairs({"_crea", "_surv"}) do
|
for _, game_mode in pairs({"_crea", "_surv"}) do
|
||||||
for _, base in pairs(mcl_skins.base) do
|
for _, base in pairs(mcl_skins.base) do
|
||||||
for _, base_color in pairs(mcl_skins.base_color) do
|
for _, base_color in pairs(mcl_skins.base_color) do
|
||||||
local id = base:gsub(".png$", "") .. minetest.colorspec_to_colorstring(base_color):gsub("#", "")
|
local id = base:gsub(".png$", "")
|
||||||
|
.. minetest.colorspec_to_colorstring(base_color):gsub("#", "")
|
||||||
|
|
||||||
local female = {
|
local female = {
|
||||||
texture = make_texture(base, base_color),
|
texture = make_texture(base, base_color),
|
||||||
slim_arms = true,
|
slim_arms = true,
|
||||||
@ -36,7 +38,8 @@ function mcl_skins.get_skin_list()
|
|||||||
table.insert(list, {
|
table.insert(list, {
|
||||||
texture = skin.texture,
|
texture = skin.texture,
|
||||||
slim_arms = skin.slim_arms,
|
slim_arms = skin.slim_arms,
|
||||||
id = skin.texture:gsub(".png$", "") .. (skin.slim_arms and "_female" or "_male") .. game_mode,
|
id = skin.texture:gsub(".png$", "")
|
||||||
|
.. (skin.slim_arms and "_female" or "_male") .. game_mode,
|
||||||
creative = game_mode == "_crea"
|
creative = game_mode == "_crea"
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
@ -45,10 +48,10 @@ function mcl_skins.get_skin_list()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function mcl_skins.get_node_id_by_player(player)
|
function mcl_skins.get_node_id_by_player(player)
|
||||||
local skin = mcl_skins.players[player]
|
local skin = mcl_skins.player_skins[player]
|
||||||
local simple_skin = skin.simple_skins_id
|
local simple_skin = skin.simple_skins_id
|
||||||
if simple_skin then
|
if simple_skin then
|
||||||
skin = mcl_skins.simple_skins[skin.simple_skins_id]
|
skin = mcl_skins.texture_to_simple_skin[skin.simple_skins_id]
|
||||||
end
|
end
|
||||||
local creative = minetest.is_creative_enabled(player:get_player_name())
|
local creative = minetest.is_creative_enabled(player:get_player_name())
|
||||||
local append = (skin.slim_arms and "_female" or "_male") .. (creative and "_crea" or "_surv")
|
local append = (skin.slim_arms and "_female" or "_male") .. (creative and "_crea" or "_surv")
|
||||||
|
@ -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,5 @@
|
|||||||
local function init_simple_skins()
|
local function init_simple_skins()
|
||||||
local id, f, data, skin = 0
|
local id, f, data, skin = 2
|
||||||
local mod_path = minetest.get_modpath("mcl_skins")
|
local mod_path = minetest.get_modpath("mcl_skins")
|
||||||
while true do
|
while true do
|
||||||
|
|
||||||
@ -35,18 +35,13 @@ local function init_simple_skins()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- add metadata to list
|
-- add metadata to list
|
||||||
mcl_skins.simple_skins[id] = {
|
mcl_skins.register_simple_skin({
|
||||||
|
index = id,
|
||||||
texture = skin,
|
texture = skin,
|
||||||
slim_arms = data and data.gender == "female",
|
slim_arms = data and data.gender == "female",
|
||||||
}
|
})
|
||||||
id = id + 1
|
id = id + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
if #mcl_skins.simple_skins > 0 then
|
|
||||||
table.insert(mcl_skins.tab_names, 1, "skin")
|
|
||||||
else
|
|
||||||
mcl_skins.simple_skins = {}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
init_simple_skins()
|
init_simple_skins()
|
||||||
|
3
mods/PLAYER/mcl_skins/textures/README.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
To add custom skins to the game, please use the mcl_custom_skins mod.
|
||||||
|
Download it from https://git.minetest.land/mineclone2/mcl_custom_skins
|
||||||
|
Support for adding custom skins to mcl_skins will be removed in a future MineClone2 release.
|
Before Width: | Height: | Size: 226 B After Width: | Height: | Size: 375 B |
Before Width: | Height: | Size: 117 B After Width: | Height: | Size: 142 B |
Before Width: | Height: | Size: 680 B After Width: | Height: | Size: 749 B |
Before Width: | Height: | Size: 117 B After Width: | Height: | Size: 142 B |
BIN
textures/mcl_skins_bottom_5.png
Normal file
After Width: | Height: | Size: 891 B |
BIN
textures/mcl_skins_bottom_5_mask.png
Normal file
After Width: | Height: | Size: 183 B |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 135 B After Width: | Height: | Size: 141 B |
Before Width: | Height: | Size: 501 B After Width: | Height: | Size: 535 B |
Before Width: | Height: | Size: 134 B After Width: | Height: | Size: 168 B |
BIN
textures/mcl_skins_icons.png
Normal file
After Width: | Height: | Size: 554 B |
Before Width: | Height: | Size: 124 B After Width: | Height: | Size: 110 B |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 122 B After Width: | Height: | Size: 151 B |