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