Merge pull request 'Advanced Skins Mod' (#313) from MrRar/MineClone5:skins into master
Reviewed-on: MineClone5/MineClone5#313
|
@ -244,17 +244,30 @@ filled_wield_def.on_place = mcl_util.call_on_rightclick
|
||||||
filled_wield_def.groups.no_wieldview = 1
|
filled_wield_def.groups.no_wieldview = 1
|
||||||
filled_wield_def._wieldview_item = "mcl_maps:empty_map"
|
filled_wield_def._wieldview_item = "mcl_maps:empty_map"
|
||||||
|
|
||||||
for _, texture in pairs(mcl_skins.list) do
|
local function player_base_to_node_id(base, colorspec, sex)
|
||||||
local def = table.copy(filled_wield_def)
|
return base:gsub("%.", "") .. minetest.colorspec_to_colorstring(colorspec):gsub("#", "") .. sex
|
||||||
def.tiles = {texture .. ".png"}
|
end
|
||||||
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)
|
bases = mcl_skins.base
|
||||||
female_def.mesh = "mcl_meshhand_female.b3d"
|
base_colors = mcl_skins.base_color
|
||||||
female_def._mcl_hand_id = texture .. "_female"
|
|
||||||
minetest.register_node("mcl_maps:filled_map_" .. texture .. "_female", female_def)
|
for _, base in pairs(bases) do
|
||||||
|
for _, base_color in pairs(base_colors) do
|
||||||
|
local node_id = player_base_to_node_id(base, base_color, "male")
|
||||||
|
local texture = mcl_skins.make_hand_texture(base, base_color)
|
||||||
|
local def = table.copy(filled_wield_def)
|
||||||
|
def.tiles = {texture}
|
||||||
|
def.mesh = "mcl_meshhand.b3d"
|
||||||
|
def._mcl_hand_id = node_id
|
||||||
|
minetest.register_node("mcl_maps:filled_map_" .. node_id, def)
|
||||||
|
|
||||||
|
node_id = player_base_to_node_id(base, base_color, "female")
|
||||||
|
def = table.copy(filled_wield_def)
|
||||||
|
def.tiles = {texture}
|
||||||
|
def.mesh = "mcl_meshhand_female.b3d"
|
||||||
|
def._mcl_hand_id = node_id
|
||||||
|
minetest.register_node("mcl_maps:filled_map_" .. node_id, def)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local old_add_item = minetest.add_item
|
local old_add_item = minetest.add_item
|
||||||
|
|
|
@ -1,79 +1,56 @@
|
||||||
local has_mcl_skins = minetest.get_modpath("mcl_skins") ~= nil
|
|
||||||
|
|
||||||
local def = minetest.registered_items[""]
|
local def = minetest.registered_items[""]
|
||||||
|
|
||||||
local list
|
local bases = mcl_skins.base
|
||||||
-- mcl_skins is enabled
|
local base_colors = mcl_skins.base_color
|
||||||
if has_mcl_skins == true then
|
|
||||||
list = mcl_skins.list
|
local function player_base_to_node_id(base, colorspec, sex)
|
||||||
else
|
return base:gsub("%.", "") .. minetest.colorspec_to_colorstring(colorspec):gsub("#", "") .. sex
|
||||||
list = { "hand" }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--generate a node for every skin
|
-- This is a fake node that should never be placed in the world
|
||||||
for _,texture in pairs(list) do
|
local node_def = {
|
||||||
-- This is a fake node that should never be placed in the world
|
description = "",
|
||||||
minetest.register_node("mcl_meshhand:"..texture, {
|
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
|
||||||
description = "",
|
visual_scale = 1,
|
||||||
tiles = {texture..".png"},
|
wield_scale = {x=1,y=1,z=1},
|
||||||
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
|
paramtype = "light",
|
||||||
visual_scale = 1,
|
drawtype = "mesh",
|
||||||
wield_scale = {x=1,y=1,z=1},
|
node_placement_prediction = "",
|
||||||
paramtype = "light",
|
on_construct = function(pos)
|
||||||
drawtype = "mesh",
|
local name = get_node(pos).name
|
||||||
mesh = "mcl_meshhand.b3d",
|
local message = "[mcl_meshhand] Trying to construct " .. name .. " at " .. minetest.pos_to_string(pos)
|
||||||
-- Prevent construction
|
minetest.log("error", message)
|
||||||
node_placement_prediction = "",
|
minetest.remove_node(pos)
|
||||||
on_construct = function(pos)
|
end,
|
||||||
minetest.log("error", "[mcl_meshhand] Trying to construct mcl_meshhand:"..texture.." at "..minetest.pos_to_string(pos))
|
drop = "",
|
||||||
minetest.remove_node(pos)
|
on_drop = function() return "" end,
|
||||||
end,
|
groups = { dig_immediate = 3, not_in_creative_inventory = 1 },
|
||||||
drop = "",
|
range = def.range
|
||||||
on_drop = function()
|
}
|
||||||
return ""
|
|
||||||
end,
|
|
||||||
groups = { dig_immediate = 3, not_in_creative_inventory = 1 },
|
|
||||||
range = def.range,
|
|
||||||
_mcl_hand_id = texture,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_node("mcl_meshhand:"..texture.. "_female", {
|
-- Generate a node for every skin
|
||||||
description = "",
|
for _, base in pairs(bases) do
|
||||||
tiles = {texture..".png"},
|
for _, base_color in pairs(base_colors) do
|
||||||
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
|
local node_id = player_base_to_node_id(base, base_color, "male")
|
||||||
visual_scale = 1,
|
local texture = mcl_skins.make_hand_texture(base, base_color)
|
||||||
wield_scale = {x=1,y=1,z=1},
|
local male = table.copy(node_def)
|
||||||
paramtype = "light",
|
male._mcl_hand_id = node_id
|
||||||
drawtype = "mesh",
|
male.mesh = "mcl_meshhand.b3d"
|
||||||
mesh = "mcl_meshhand_female.b3d",
|
male.tiles = {texture}
|
||||||
-- Prevent construction
|
minetest.register_node("mcl_meshhand:" .. node_id, male)
|
||||||
node_placement_prediction = "",
|
|
||||||
on_construct = function(pos)
|
node_id = player_base_to_node_id(base, base_color, "female")
|
||||||
minetest.log("error", "[mcl_meshhand] Trying to construct mcl_meshhand:"..texture.." at "..minetest.pos_to_string(pos))
|
local female = table.copy(node_def)
|
||||||
minetest.remove_node(pos)
|
female._mcl_hand_id = node_id
|
||||||
end,
|
female.mesh = "mcl_meshhand_female.b3d"
|
||||||
drop = "",
|
female.tiles = {texture}
|
||||||
on_drop = function()
|
minetest.register_node("mcl_meshhand:" .. node_id, female)
|
||||||
return ""
|
end
|
||||||
end,
|
|
||||||
groups = { dig_immediate = 3, not_in_creative_inventory = 1 },
|
|
||||||
range = def.range,
|
|
||||||
_mcl_hand_id = texture .. "_female",
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if has_mcl_skins == true then
|
-- Change the player's hand to their skin
|
||||||
--change the player's hand to their skin
|
mcl_skins.register_on_set_skin(function(player)
|
||||||
mcl_skins.register_on_set_skin(function(player, skin)
|
local data = mcl_skins.players[player:get_player_name()]
|
||||||
local meta = mcl_skins.meta[skin]
|
local node_id = player_base_to_node_id(data.base, data.base_color, data.slim_arms and "female" or "male")
|
||||||
if meta.gender == "female" then
|
player:get_inventory():set_stack("hand", 1, "mcl_meshhand:" .. node_id)
|
||||||
player:get_inventory():set_stack("hand", 1, "mcl_meshhand:"..skin.."_female")
|
end)
|
||||||
else
|
|
||||||
player:get_inventory():set_stack("hand", 1, "mcl_meshhand:"..skin)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
else
|
|
||||||
minetest.register_on_joinplayer(function(player)
|
|
||||||
player:get_inventory():set_stack("hand", 1, "mcl_meshhand:hand")
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
name = mcl_meshhand
|
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
|
depends = mcl_tools, mcl_skins
|
||||||
optional_depends = mcl_skins
|
|
||||||
|
|
||||||
|
|
|
@ -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,6 +1,6 @@
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2016 TenPlus1
|
Copyright (c) 2022 MrRar
|
||||||
|
|
||||||
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
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
@ -1,13 +1,77 @@
|
||||||
= Skins for MineClone 2 =
|
# Skins for MineClone 5
|
||||||
|
|
||||||
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: 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.
|
||||||
|
If texture is not 64x32 then the automatic preview will not display properly.
|
||||||
|
|
||||||
|
`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".
|
||||||
|
If texture is not 64x32 then the automatic preview will not display properly.
|
||||||
|
|
||||||
|
`preview`
|
||||||
|
Set a custom preview texture. You can use texture modifiers. If preview contains the string `{color}` it will be replaced with the item's colorstring.
|
||||||
|
|
||||||
|
`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.make_hand_texture(base, colorspec)`
|
||||||
|
Generate a texture string from a base texture and color.
|
||||||
|
This function is used by mods that want to have a first person hand textured like 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 name 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,106 @@
|
||||||
|
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.
|
||||||
|
Source: https://www.planetminecraft.com/texture-pack/pixel-perfection-chorus-edit/
|
|
@ -1,139 +1,165 @@
|
||||||
-- Skins for MineClone 2
|
-- Skins for MineClone 5
|
||||||
|
|
||||||
local modname = minetest.get_current_modname()
|
local S = minetest.get_translator("mcl_skins")
|
||||||
|
local color_to_string = minetest.colorspec_to_colorstring
|
||||||
|
|
||||||
mcl_skins = {
|
mcl_skins = {
|
||||||
skins = {}, list = {}, meta = {},
|
tab_names = {"base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear"}, -- Rendering order
|
||||||
modpath = minetest.get_modpath(modname),
|
tab_names_display_order = {"template", "base", "headwear", "hair", "eye", "mouth", "top", "arm", "bottom", "footwear"},
|
||||||
skin_count = 0, -- counter of _custom_ skins (all skins except character.png)
|
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")
|
||||||
|
},
|
||||||
|
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 = {},
|
||||||
|
previews = {},
|
||||||
|
players = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
local S = minetest.get_translator(modname)
|
function mcl_skins.register_item(item)
|
||||||
local has_mcl_inventory = minetest.get_modpath("mcl_inventory")
|
assert(mcl_skins[item.type], "Skin item type " .. item.type .. " does not exist.")
|
||||||
|
local texture = item.texture or "blank.png"
|
||||||
-- load skin list and metadata
|
if item.steve then
|
||||||
local id, f, data, skin = 0
|
mcl_skins.steve[item.type] = texture
|
||||||
|
|
||||||
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
|
|
||||||
f:close()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
mcl_skins.list[id] = skin
|
if item.alex then
|
||||||
|
mcl_skins.alex[item.type] = texture
|
||||||
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
|
end
|
||||||
|
|
||||||
-- add metadata to list
|
table.insert(mcl_skins[item.type], texture)
|
||||||
mcl_skins.meta[skin] = {
|
mcl_skins.masks[texture] = item.mask
|
||||||
name = data and data.name or "",
|
if item.preview then mcl_skins.previews[texture] = item.preview end
|
||||||
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
|
end
|
||||||
|
|
||||||
function mcl_skins.cycle_skin(player)
|
function mcl_skins.save(player)
|
||||||
local skin_id = tonumber(player:get_meta():get_string("mcl_skins:skin_id"))
|
if not player or not player:is_player() then return end
|
||||||
if not skin_id then
|
local name = player:get_player_name()
|
||||||
skin_id = 0
|
local skin = mcl_skins.players[name]
|
||||||
end
|
if not skin then return end
|
||||||
skin_id = skin_id + 1
|
player:get_meta():set_string("mcl_skins:skin", minetest.serialize(skin))
|
||||||
if skin_id > mcl_skins.skin_count then
|
|
||||||
skin_id = 0
|
|
||||||
end
|
|
||||||
mcl_skins.set_player_skin(player, skin_id)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_skins.set_player_skin(player, skin_id)
|
minetest.register_chatcommand("skin", {
|
||||||
if not player then
|
description = S("Open skin configuration screen."),
|
||||||
return false
|
privs = {},
|
||||||
|
func = function(name, param) mcl_skins.show_formspec(minetest.get_player_by_name(name)) end
|
||||||
|
})
|
||||||
|
|
||||||
|
function mcl_skins.make_hand_texture(base, colorspec)
|
||||||
|
local output = ""
|
||||||
|
if mcl_skins.masks[base] then
|
||||||
|
output = mcl_skins.masks[base] ..
|
||||||
|
"^[colorize:" .. color_to_string(colorspec) .. ":alpha"
|
||||||
end
|
end
|
||||||
local playername = player:get_player_name()
|
if #output > 0 then output = output .. "^" end
|
||||||
local skin
|
output = output .. base
|
||||||
if skin_id == nil or type(skin_id) ~= "number" or skin_id < 0 or skin_id > mcl_skins.skin_count then
|
return output
|
||||||
return false
|
end
|
||||||
elseif skin_id == 0 then
|
|
||||||
skin = "character"
|
function mcl_skins.compile_skin(skin)
|
||||||
mcl_player.player_set_model(player, "mcl_armor_character.b3d")
|
local output = ""
|
||||||
else
|
for i, tab in pairs(mcl_skins.tab_names) do
|
||||||
skin = "mcl_skins_character_" .. tostring(skin_id)
|
local texture = skin[tab]
|
||||||
local meta = mcl_skins.meta[skin]
|
if texture and texture ~= "blank.png" then
|
||||||
if meta.gender == "female" then
|
|
||||||
mcl_player.player_set_model(player, "mcl_armor_character_female.b3d")
|
if skin[tab .. "_color"] and mcl_skins.masks[texture] then
|
||||||
else
|
if #output > 0 then output = output .. "^" end
|
||||||
mcl_player.player_set_model(player, "mcl_armor_character.b3d")
|
local color = color_to_string(skin[tab .. "_color"])
|
||||||
|
output = output ..
|
||||||
|
"(" .. mcl_skins.masks[texture] .. "^[colorize:" .. color .. ":alpha)"
|
||||||
|
end
|
||||||
|
if #output > 0 then output = output .. "^" end
|
||||||
|
output = output .. texture
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
--local skin_file = skin .. ".png"
|
return output
|
||||||
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
|
end
|
||||||
|
|
||||||
function mcl_skins.update_player_skin(player)
|
function mcl_skins.update_player_skin(player)
|
||||||
if not player then
|
if not player then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local playername = player:get_player_name()
|
|
||||||
mcl_player.player_set_skin(player, mcl_skins.skins[playername] .. ".png")
|
local skin = mcl_skins.players[player:get_player_name()]
|
||||||
|
|
||||||
|
mcl_player.player_set_skin(player, mcl_skins.compile_skin(skin))
|
||||||
|
|
||||||
|
local model = skin.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
|
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 name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
local skin_id = player:get_meta():get_string("mcl_skins:skin_id")
|
local skin = player:get_meta():get_string("mcl_skins:skin")
|
||||||
local set_skin
|
if skin then
|
||||||
-- do we already have a skin in player attributes?
|
skin = minetest.deserialize(skin)
|
||||||
if skin_id and skin_id ~= "" then
|
|
||||||
set_skin = tonumber(skin_id)
|
|
||||||
-- otherwise use random skin if not set
|
|
||||||
end
|
end
|
||||||
if not set_skin then
|
if skin then
|
||||||
set_skin = math.random(0, mcl_skins.skin_count)
|
mcl_skins.players[name] = 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[name] = skin
|
||||||
end
|
end
|
||||||
local ok = mcl_skins.set_player_skin(player, set_skin)
|
mcl_skins.save(player)
|
||||||
if not ok then
|
mcl_skins.update_player_skin(player)
|
||||||
set_skin = math.random(0, mcl_skins.skin_count)
|
end)
|
||||||
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)
|
minetest.register_on_leaveplayer(function(player)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
if name then
|
||||||
|
mcl_skins.players[name] = nil
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -143,138 +169,298 @@ function mcl_skins.register_on_set_skin(func)
|
||||||
table.insert(mcl_skins.registered_on_set_skins, func)
|
table.insert(mcl_skins.registered_on_set_skins, func)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- command to set player skin (usually for custom skins)
|
function mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
minetest.register_chatcommand("setskin", {
|
active_tab = active_tab or "template"
|
||||||
params = S("[<player>] [<skin number>]"),
|
page_num = page_num or 1
|
||||||
description = S("Select player skin of yourself or another player"),
|
|
||||||
privs = {},
|
|
||||||
func = function(name, param)
|
|
||||||
|
|
||||||
if param == "" and name ~= "" then
|
local page_count
|
||||||
mcl_skins.show_formspec(name)
|
if page_num < 1 then page_num = 1 end
|
||||||
return true
|
if mcl_skins[active_tab] then
|
||||||
|
page_count = math.ceil(#mcl_skins[active_tab] / 25)
|
||||||
|
if page_num > page_count then
|
||||||
|
page_num = page_count
|
||||||
end
|
end
|
||||||
local playername, skin_id = string.match(param, "([^ ]+) (%d+)")
|
else
|
||||||
if not playername or not skin_id then
|
page_num = 1
|
||||||
skin_id = string.match(param, "(%d+)")
|
page_count = 1
|
||||||
if not skin_id then
|
end
|
||||||
return false, S("Insufficient or wrong parameters")
|
|
||||||
|
local player_name = player:get_player_name()
|
||||||
|
local skin = mcl_skins.players[player_name]
|
||||||
|
local formspec = "formspec_version[3]" ..
|
||||||
|
"size[13,10]"
|
||||||
|
|
||||||
|
for i, tab in pairs(mcl_skins.tab_names_display_order) 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] .. "]"
|
||||||
|
end
|
||||||
|
|
||||||
|
local mesh = skin.slim_arms and "mcl_armor_character_female.b3d" or "mcl_armor_character.b3d"
|
||||||
|
|
||||||
|
formspec = formspec ..
|
||||||
|
"model[9.5,0.3;3,7;player_mesh;" .. mesh .. ";" ..
|
||||||
|
mcl_skins.compile_skin(skin) ..
|
||||||
|
",blank.png,blank.png;0,180;false;true;0,0;0]"
|
||||||
|
|
||||||
|
if mcl_skins[active_tab] then
|
||||||
|
local textures = mcl_skins[active_tab]
|
||||||
|
local page_start = (page_num - 1) * 25 + 1
|
||||||
|
local page_end = math.min(page_start + 25 - 1, #textures)
|
||||||
|
|
||||||
|
for j = page_start, page_end do
|
||||||
|
local i = j - page_start + 1
|
||||||
|
local texture = textures[j]
|
||||||
|
local preview = ""
|
||||||
|
if mcl_skins.previews[texture] then
|
||||||
|
preview = mcl_skins.previews[texture]
|
||||||
|
if skin[active_tab .. "_color"] then
|
||||||
|
local color = minetest.colorspec_to_colorstring(skin[active_tab .. "_color"])
|
||||||
|
preview = preview:gsub("{color}", color)
|
||||||
|
end
|
||||||
|
elseif active_tab == "base" then
|
||||||
|
if mcl_skins.masks[texture] then
|
||||||
|
preview = mcl_skins.masks[texture] .. "^[sheet:8x4:1,1" ..
|
||||||
|
"^[colorize:" .. color_to_string(skin.base_color) .. ":alpha"
|
||||||
|
end
|
||||||
|
if #preview > 0 then preview = preview .. "^" end
|
||||||
|
preview = preview .. "(" .. texture .. "^[sheet:8x4:1,1)"
|
||||||
|
elseif active_tab == "mouth" or active_tab == "eye" then
|
||||||
|
preview = texture .. "^[sheet:8x4:1,1"
|
||||||
|
elseif active_tab == "headwear" then
|
||||||
|
preview = texture .. "^[sheet:8x4:5,1^(" .. texture .. "^[sheet:8x4:1,1)"
|
||||||
|
elseif active_tab == "hair" then
|
||||||
|
if mcl_skins.masks[texture] then
|
||||||
|
preview = mcl_skins.masks[texture] .. "^[sheet:8x4:1,1" ..
|
||||||
|
"^[colorize:" .. color_to_string(skin.hair_color) .. ":alpha^(" ..
|
||||||
|
texture .. "^[sheet:8x4:1,1)^(" ..
|
||||||
|
mcl_skins.masks[texture] .. "^[sheet:8x4:5,1" ..
|
||||||
|
"^[colorize:" .. color_to_string(skin.hair_color) .. ":alpha)" ..
|
||||||
|
"^(" .. texture .. "^[sheet:8x4:5,1)"
|
||||||
|
else
|
||||||
|
preview = texture .. "^[sheet:8x4:5,1"
|
||||||
|
end
|
||||||
|
elseif active_tab == "top" then
|
||||||
|
if mcl_skins.masks[texture] then
|
||||||
|
preview = "[combine:12x12:-18,-20=" .. mcl_skins.masks[texture] ..
|
||||||
|
"^[colorize:" .. color_to_string(skin.top_color) .. ":alpha"
|
||||||
|
end
|
||||||
|
if #preview > 0 then preview = preview .. "^" end
|
||||||
|
preview = preview .. "[combine:12x12:-18,-20=" .. texture .. "^[mask:mcl_skins_top_preview_mask.png"
|
||||||
|
elseif active_tab == "bottom" then
|
||||||
|
if mcl_skins.masks[texture] then
|
||||||
|
preview = "[combine:12x12:0,-20=" .. mcl_skins.masks[texture] ..
|
||||||
|
"^[colorize:" .. color_to_string(skin.bottom_color) .. ":alpha"
|
||||||
|
end
|
||||||
|
if #preview > 0 then preview = preview .. "^" end
|
||||||
|
preview = preview .. "[combine:12x12:0,-20=" .. texture .. "^[mask:mcl_skins_bottom_preview_mask.png"
|
||||||
|
elseif active_tab == "footwear" then
|
||||||
|
preview = "[combine:12x12:0,-20=" .. texture .. "^[mask:mcl_skins_bottom_preview_mask.png"
|
||||||
end
|
end
|
||||||
playername = name
|
|
||||||
end
|
|
||||||
skin_id = tonumber(skin_id)
|
|
||||||
|
|
||||||
local player = minetest.get_player_by_name(playername)
|
if skin[active_tab] == texture then
|
||||||
|
preview = preview .. "^mcl_skins_select_overlay.png"
|
||||||
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
|
||||||
end
|
|
||||||
|
|
||||||
local ok = mcl_skins.set_player_skin(player, skin_id)
|
i = i - 1
|
||||||
if not ok then
|
local x = 3.6 + i % 5 * 1.1
|
||||||
return false, S("Invalid skin number! Valid numbers: 0 to @1", mcl_skins.skin_count)
|
local y = 0.3 + math.floor(i / 5) * 1.1
|
||||||
|
formspec = formspec ..
|
||||||
|
"image_button[" .. x .. "," .. y ..
|
||||||
|
";1,1;" .. preview .. ";" .. texture .. ";]"
|
||||||
end
|
end
|
||||||
local skinfile = "#"..skin_id
|
elseif active_tab == "arm" then
|
||||||
|
local thick_overlay = not skin.slim_arms and "^mcl_skins_select_overlay.png" or ""
|
||||||
|
local slim_overlay = skin.slim_arms and "^mcl_skins_select_overlay.png" or ""
|
||||||
|
formspec = formspec ..
|
||||||
|
"image_button[3.6,0.3;1,1;mcl_skins_thick_arms.png" .. thick_overlay ..";thick_arms;]" ..
|
||||||
|
"image_button[4.7,0.3;1,1;mcl_skins_slim_arms.png" .. slim_overlay ..";slim_arms;]"
|
||||||
|
|
||||||
local meta = mcl_skins.meta[mcl_skins.skins[playername]]
|
elseif active_tab == "template" then
|
||||||
local your_msg
|
formspec = formspec ..
|
||||||
if not meta.name or meta.name == "" then
|
"model[4,2;2,3;player_mesh;" .. mesh .. ";" ..
|
||||||
your_msg = S("Your skin has been set to: @1", skinfile)
|
mcl_skins.compile_skin(mcl_skins.steve) ..
|
||||||
else
|
",blank.png,blank.png;0,180;false;true;0,0;0]" ..
|
||||||
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,
|
"button[4,5.2;2,0.8;steve;" .. S("Select") .. "]" ..
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
"model[6.5,2;2,3;player_mesh;" .. mesh .. ";" ..
|
||||||
if fields.__mcl_skins then
|
mcl_skins.compile_skin(mcl_skins.alex) ..
|
||||||
if mcl_skins.skin_count <= 6 then
|
",blank.png,blank.png;0,180;false;true;0,0;0]" ..
|
||||||
-- Change skin immediately if there are not many skins
|
|
||||||
mcl_skins.cycle_skin(player)
|
"button[6.5,5.2;2,0.8;alex;" .. S("Select") .. "]"
|
||||||
if player:get_attach() then
|
|
||||||
mcl_player.player_set_animation(player, "sit")
|
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"
|
||||||
|
|
||||||
|
for i, colorspec in pairs(colors) do
|
||||||
|
local overlay = ""
|
||||||
|
if skin[tab_color] == colorspec then
|
||||||
|
overlay = "^mcl_skins_select_overlay.png"
|
||||||
end
|
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 color = minetest.colorspec_to_colorstring(colorspec)
|
||||||
local formspec = "size[7,8.5]"
|
i = i - 1
|
||||||
|
local x = 3.6 + i % 8 * 1.1
|
||||||
formspec = formspec .. "label[2,2;" .. minetest.formspec_escape(minetest.colorize("#383838", S("Select player skin:"))) .. "]"
|
local y = 7 + math.floor(i / 8) * 1.1
|
||||||
.. "textlist[0,2.5;6.8,6;skins_set;"
|
formspec = formspec ..
|
||||||
|
"image_button[" .. x .. "," .. y ..
|
||||||
local meta
|
";1,1;blank.png^[noalpha^[colorize:" ..
|
||||||
local selected = 1
|
color .. ":alpha" .. overlay .. ";" .. colorspec .. ";]"
|
||||||
|
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
||||||
formspec = formspec .. ";" .. selected .. ";false]"
|
if page_num > 1 then
|
||||||
|
formspec = formspec ..
|
||||||
local player = minetest.get_player_by_name(playername)
|
"image_button[3.6,5.8;1,1;mcl_skins_arrow.png^[transformFX;previous_page;]"
|
||||||
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
|
end
|
||||||
|
|
||||||
if meta then
|
if page_num < page_count then
|
||||||
if meta.name and meta.name ~= "" then
|
formspec = formspec ..
|
||||||
formspec = formspec .. "label[2,0.5;" .. minetest.formspec_escape(minetest.colorize("#383838", S("Name: @1", meta.name))) .. "]"
|
"image_button[8,5.8;1,1;mcl_skins_arrow.png;next_page;]"
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.show_formspec(playername, "mcl_skins:skin_select", formspec)
|
if page_count > 1 then
|
||||||
|
formspec = formspec ..
|
||||||
|
"label[5.9,6.3;" .. page_num .. " / " .. page_count .. "]"
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.show_formspec(player_name, "mcl_skins:" .. active_tab .. "_" .. page_num, formspec)
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
|
if fields.__mcl_skins then
|
||||||
|
mcl_skins.show_formspec(player)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
if formname == "mcl_skins:skin_select" then
|
if not formname:find("^mcl_skins:") then return false end
|
||||||
|
local _, _, active_tab, page_num = formname:find("^mcl_skins:(%a+)_(%d+)")
|
||||||
|
if not page_num or not active_tab then return true end
|
||||||
|
page_num = math.floor(tonumber(page_num) or 1)
|
||||||
|
local player_name = player:get_player_name()
|
||||||
|
|
||||||
local name = player:get_player_name()
|
for field, value in pairs(fields) do
|
||||||
|
if field == "quit" then
|
||||||
|
mcl_skins.save(player)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
local event = minetest.explode_textlist_event(fields["skins_set"])
|
if field == "alex" then
|
||||||
|
mcl_skins.players[player_name] = table.copy(mcl_skins.alex)
|
||||||
|
mcl_skins.update_player_skin(player)
|
||||||
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
|
return true
|
||||||
|
elseif field == "steve" then
|
||||||
|
mcl_skins.players[player_name] = table.copy(mcl_skins.steve)
|
||||||
|
mcl_skins.update_player_skin(player)
|
||||||
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
if event.type == "CHG" or event.type == "DCL" then
|
for i, tab in pairs(mcl_skins.tab_names_display_order) do
|
||||||
|
if field == tab then
|
||||||
local skin_id = math.min(event.index - 1, mcl_skins.skin_count)
|
mcl_skins.show_formspec(player, tab, page_num)
|
||||||
if not mcl_skins.list[skin_id] then
|
return true
|
||||||
return -- Do not update wrong skin number
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
mcl_skins.set_player_skin(player, skin_id)
|
local skin = mcl_skins.players[player_name]
|
||||||
mcl_skins.show_formspec(name)
|
if not skin then return true end
|
||||||
|
|
||||||
|
if field == "next_page" then
|
||||||
|
page_num = page_num + 1
|
||||||
|
mcl_skins.show_formspec(player, active_tab, page_num)
|
||||||
|
return true
|
||||||
|
elseif field == "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 field == "thick_arms" then
|
||||||
|
skin.slim_arms = false
|
||||||
|
elseif field == "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
|
||||||
|
|
||||||
|
-- See if field is a texture
|
||||||
|
if 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
|
||||||
|
if skin[active_tab .. "_color"] then
|
||||||
|
local color = math.floor(tonumber(field) or 0)
|
||||||
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.log("action", "[mcl_skins] Mod initialized with "..mcl_skins.skin_count.." custom skin(s)")
|
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
|
||||||
|
mcl_skins.modpath = minetest.get_modpath("mcl_skins")
|
||||||
|
|
||||||
|
local f = io.open(mcl_skins.modpath .. "/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
|
||||||
|
|
||||||
|
mcl_skins.previews["blank.png"] = "blank.png"
|
||||||
|
end
|
||||||
|
|
||||||
|
init()
|
||||||
|
|
|
@ -0,0 +1,256 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"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": "mcl_skins_headwear_6.png^[sheet:8x4:7,1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "headwear",
|
||||||
|
"texture": "mcl_skins_headwear_7.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "headwear",
|
||||||
|
"steve": 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 +0,0 @@
|
||||||
# textdomain: mcl_skins
|
|
||||||
[<player>] [<skin number>]=[<joueur>] [<numéro d'apparence>]
|
|
||||||
Select player skin of yourself or another player=Sélectionner une apparence pour vous même ou un autre joueur
|
|
||||||
Insufficient or wrong parameters=Paramètres insuffisants ou incorrects
|
|
||||||
Player @1 not online!=Le joueur @1 n'est pas en ligne !
|
|
||||||
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 !
|
|
||||||
Invalid skin number! Valid numbers: 0 to @1=Numéro d'apparence incorrect! Numéros valides : 0 à @1
|
|
||||||
Your skin has been set to: @1=Votre apparence a été définie en : @1
|
|
||||||
Your skin has been set to: @1 (@2)=Votre apparence a été définie en : @1 (@2)
|
|
||||||
Skin of @1 set to: @2 (@3)=Apparence de @1 definie en : @2 (@3)
|
|
||||||
Select player skin:=Sélectionner l'apparence du joueur :
|
|
||||||
@1 (@2)=@1 (@2)
|
|
||||||
Name: @1=Nom : @1
|
|
||||||
|
|
|
@ -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!=你需要“服务器”特权来改变其他玩家的皮肤!
|
|
||||||
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 +1,13 @@
|
||||||
# textdomain: mcl_skins
|
# textdomain: mcl_skins
|
||||||
[<player>] [<skin number>]=
|
Templates=
|
||||||
Select player skin of yourself or another player=
|
Arm size=
|
||||||
Insufficient or wrong parameters=
|
Bases=
|
||||||
Player @1 not online!=
|
Footwears=
|
||||||
You need the “server” privilege to change the skin of other players!=
|
Eyes=
|
||||||
Invalid skin number! Valid numbers: 0 to @1=
|
Mouths=
|
||||||
Your skin has been set to: @1=
|
Bottoms=
|
||||||
Your skin has been set to: @1 (@2)=
|
Tops=
|
||||||
Skin of @1 set to: @2 (@3)=
|
Hairs=
|
||||||
Select player skin:=
|
Headwears=
|
||||||
@1 (@2)=
|
Open skin configuration screen.=
|
||||||
Name: @1=
|
Select=
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
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 |
After Width: | Height: | Size: 89 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: 167 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 |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 151 B |
After Width: | Height: | Size: 683 B |
After Width: | Height: | Size: 161 B |
After Width: | Height: | Size: 960 B |
After Width: | Height: | Size: 167 B |
After Width: | Height: | Size: 625 B |