217 lines
4.6 KiB
Lua
217 lines
4.6 KiB
Lua
|
|
||
|
-- Simple Skins mod for minetest (5th June 2016)
|
||
|
-- Adds a simple skin selector to the inventory, using inventory_plus
|
||
|
-- or by using the /skin command to bring up selection list.
|
||
|
-- Released by TenPlus1 and based on Zeg9's code under WTFPL
|
||
|
|
||
|
skins = {}
|
||
|
skins.skins = {}
|
||
|
skins.modpath = minetest.get_modpath("simple_skins")
|
||
|
skins.armor = minetest.get_modpath("3d_armor")
|
||
|
skins.inv = minetest.get_modpath("inventory_plus")
|
||
|
|
||
|
-- load skin list
|
||
|
skins.list = {}
|
||
|
skins.add = function(skin)
|
||
|
table.insert(skins.list, skin)
|
||
|
end
|
||
|
|
||
|
local id = 1
|
||
|
local f
|
||
|
while true do
|
||
|
f = io.open(skins.modpath .. "/textures/character_" .. id .. ".png")
|
||
|
if not f then break end
|
||
|
f:close()
|
||
|
skins.add("character_" .. id)
|
||
|
id = id + 1
|
||
|
end
|
||
|
|
||
|
id = id - 1
|
||
|
|
||
|
-- load Metadata
|
||
|
skins.meta = {}
|
||
|
local f, data
|
||
|
for _, i in pairs(skins.list) do
|
||
|
skins.meta[i] = {}
|
||
|
f = io.open(skins.modpath .. "/meta/" .. i .. ".txt")
|
||
|
data = nil
|
||
|
if f then
|
||
|
data = minetest.deserialize("return {" .. f:read('*all') .. "}")
|
||
|
f:close()
|
||
|
end
|
||
|
data = data or {}
|
||
|
skins.meta[i].name = data.name or ""
|
||
|
skins.meta[i].author = data.author or ""
|
||
|
end
|
||
|
|
||
|
-- player load/save routines
|
||
|
skins.file = minetest.get_worldpath() .. "/simple_skins.mt"
|
||
|
|
||
|
skins.load = function()
|
||
|
local input = io.open(skins.file, "r")
|
||
|
local data = nil
|
||
|
if input then
|
||
|
data = input:read('*all')
|
||
|
end
|
||
|
if data and data ~= "" then
|
||
|
local lines = string.split(data, "\n")
|
||
|
for _, line in pairs(lines) do
|
||
|
data = string.split(line, ' ', 2)
|
||
|
skins.skins[data[1]] = data[2]
|
||
|
end
|
||
|
io.close(input)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- load player skins now
|
||
|
skins.load()
|
||
|
|
||
|
skins.save = function()
|
||
|
local output = io.open(skins.file,'w')
|
||
|
for name, skin in pairs(skins.skins) do
|
||
|
if name and skin then
|
||
|
output:write(name .. " " .. skin .. "\n")
|
||
|
end
|
||
|
end
|
||
|
io.close(output)
|
||
|
end
|
||
|
|
||
|
-- skin selection page
|
||
|
skins.formspec = {}
|
||
|
skins.formspec.main = function(name)
|
||
|
|
||
|
local selected = 1 -- select default
|
||
|
local formspec = "size[7,7]"
|
||
|
.. "bgcolor[#08080822;true]"
|
||
|
.. "label[.5,2;Select Player Skin:]"
|
||
|
.. "textlist[.5,2.5;5.8,4;skins_set;"
|
||
|
|
||
|
for i = 1, #skins.list do
|
||
|
|
||
|
formspec = formspec .. skins.meta[ skins.list[i] ].name .. ","
|
||
|
|
||
|
if skins.skins[name] == skins.list[i] then
|
||
|
selected = i
|
||
|
end
|
||
|
end
|
||
|
|
||
|
formspec = formspec .. ";" .. selected .. ";true]"
|
||
|
|
||
|
local meta = skins.meta[ skins.skins[name] ]
|
||
|
|
||
|
if meta then
|
||
|
if meta.name then
|
||
|
formspec = formspec .. "label[2,.5;Name: " .. meta.name .. "]"
|
||
|
end
|
||
|
if meta.author then
|
||
|
formspec = formspec .. "label[2,1;Author: " .. meta.author .. "]"
|
||
|
end
|
||
|
end
|
||
|
|
||
|
return formspec
|
||
|
end
|
||
|
|
||
|
-- update player skin
|
||
|
skins.update_player_skin = function(player)
|
||
|
|
||
|
if not player then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
local name = player:get_player_name()
|
||
|
|
||
|
if skins.armor then
|
||
|
armor.textures[name].skin = skins.skins[name] .. ".png"
|
||
|
armor:set_player_armor(player)
|
||
|
else
|
||
|
player:set_properties({
|
||
|
textures = {skins.skins[name] .. ".png"},
|
||
|
})
|
||
|
end
|
||
|
|
||
|
skins.save()
|
||
|
end
|
||
|
|
||
|
-- load player skin on join
|
||
|
minetest.register_on_joinplayer(function(player)
|
||
|
|
||
|
local name = player:get_player_name()
|
||
|
|
||
|
if not skins.skins[name] then
|
||
|
skins.skins[name] = "character_1"
|
||
|
end
|
||
|
|
||
|
skins.update_player_skin(player)
|
||
|
|
||
|
if skins.inv then
|
||
|
inventory_plus.register_button(player,"skins", "Skin")
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
-- formspec control
|
||
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||
|
|
||
|
local name = player:get_player_name()
|
||
|
|
||
|
if fields.skins then
|
||
|
inventory_plus.set_inventory_formspec(player,
|
||
|
skins.formspec.main(name) .. "button[0,.75;2,.5;main;Back]"
|
||
|
)
|
||
|
end
|
||
|
|
||
|
local event = minetest.explode_textlist_event(fields["skins_set"])
|
||
|
|
||
|
if event.type == "CHG" then
|
||
|
|
||
|
local index = event.index
|
||
|
|
||
|
if index > id then index = id end
|
||
|
|
||
|
skins.skins[name] = skins.list[index]
|
||
|
|
||
|
if skins.inv then
|
||
|
inventory_plus.set_inventory_formspec(player,
|
||
|
skins.formspec.main(name) .. "button[0,.75;2,.5;main;Back]"
|
||
|
)
|
||
|
end
|
||
|
|
||
|
skins.update_player_skin(player)
|
||
|
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
-- admin command to set player skin (usually for custom skins)
|
||
|
minetest.register_chatcommand("setskin", {
|
||
|
params = "<player> <skin number>",
|
||
|
description = "Admin command to set player skin",
|
||
|
privs = {server = true},
|
||
|
func = function(name, param)
|
||
|
|
||
|
if not param or param == "" then return end
|
||
|
|
||
|
local user, skin = string.match(param, "([^ ]+) (-?%d+)")
|
||
|
|
||
|
if not user or not skin then return end
|
||
|
|
||
|
skins.skins[user] = "character_"..tonumber(skin)
|
||
|
skins.save()
|
||
|
|
||
|
minetest.chat_send_player(name,
|
||
|
"** " .. user .. "'s skin set to character_" .. skin .. ".png")
|
||
|
end,
|
||
|
})
|
||
|
|
||
|
-- player command to set skin
|
||
|
minetest.register_chatcommand("skin", {
|
||
|
description = "Set player skin",
|
||
|
func = function(name, param)
|
||
|
minetest.show_formspec(name,
|
||
|
"skins_set",
|
||
|
skins.formspec.main(name)
|
||
|
.."button_exit[0,.75;2,.5;;Close]"
|
||
|
)
|
||
|
end,
|
||
|
})
|
||
|
|
||
|
print ("[MOD] Simple Skins loaded")
|