forked from ThomasMonroe314/ugxrealms
enable [multiskin]
This commit is contained in:
parent
6a36c3b6ed
commit
2aee4873af
21
worldmods/multiskin/LICENSE
Normal file
21
worldmods/multiskin/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2017
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
51
worldmods/multiskin/README.md
Normal file
51
worldmods/multiskin/README.md
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
[mod] Multiskin [multiskin] [0.1.1]
|
||||||
|
===================================
|
||||||
|
|
||||||
|
**Minetest Version:** 0.4.16
|
||||||
|
|
||||||
|
**Depends:** default
|
||||||
|
|
||||||
|
Adds per-player support for version 1.8 minecraft skins.
|
||||||
|
|
||||||
|
On its own this mod acts as a replacement for the out-dated player_textures
|
||||||
|
mod by PilzAdam. Individual player textures can be placed in the mod's
|
||||||
|
textures directory and will be automatically assigned to a player by naming
|
||||||
|
the texture file as `player_<player_name>.png`
|
||||||
|
|
||||||
|
This mod also supports the following skin-switching mods which can be used
|
||||||
|
in conjuction with the multiskin default skins and chat commands.
|
||||||
|
```
|
||||||
|
[mod] Skins [skins] by Zeg9
|
||||||
|
[mod] Simple Skins [simple_skins] by TenPlus1
|
||||||
|
[mod] Unified Skins [u_skins] by SmallJoker
|
||||||
|
[mod] Wardrobe [wardrobe] by prestidigitator
|
||||||
|
```
|
||||||
|
Note that auto skin format detection is only available for these mods if
|
||||||
|
the multiskin mod is listed in the `secure.trusted_mods` setting.
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
-------------
|
||||||
|
|
||||||
|
You can set the default skin by including the following settings in your
|
||||||
|
minetest.conf
|
||||||
|
|
||||||
|
Supported formats are `1.0` and `1.8`
|
||||||
|
```
|
||||||
|
multiskin_skin = <texture>
|
||||||
|
multiskin_format = <format>
|
||||||
|
```
|
||||||
|
Chat Commands
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Requires `server` priv in multiplayer mode, no privs required in singleplayer.
|
||||||
|
```
|
||||||
|
/multiskin format <player_name> <format>
|
||||||
|
/multiskin set <player_name> <texture>
|
||||||
|
/multiskin unset <player_name>
|
||||||
|
/multiskin help
|
||||||
|
```
|
||||||
|
TODO
|
||||||
|
----
|
||||||
|
|
||||||
|
Document the api and add support to my 3d_armor and clothing mods.
|
||||||
|
|
2
worldmods/multiskin/depends.txt
Normal file
2
worldmods/multiskin/depends.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
default
|
||||||
|
sfinv?
|
2
worldmods/multiskin/description.txt
Normal file
2
worldmods/multiskin/description.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Dual skin format player model.
|
||||||
|
Supports minecraft 1.0 and 1.8 skin formats on a per-player basis.
|
264
worldmods/multiskin/init.lua
Normal file
264
worldmods/multiskin/init.lua
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
local modname = minetest.get_current_modname()
|
||||||
|
local modpath = minetest.get_modpath(modname)
|
||||||
|
local dir_list = minetest.get_dir_list(modpath.."/textures")
|
||||||
|
local default_skin = minetest.setting_get("multiskin_skin") or "character.png"
|
||||||
|
local default_format = minetest.setting_get("multiskin_format") or "1.0"
|
||||||
|
local player_skins = {}
|
||||||
|
local player_format = {}
|
||||||
|
local player_textures = {}
|
||||||
|
local skin_previews = {}
|
||||||
|
local skin_format = {[default_skin]=default_format}
|
||||||
|
|
||||||
|
local function get_skin_format(file)
|
||||||
|
file:seek("set", 1)
|
||||||
|
if file:read(3) == "PNG" then
|
||||||
|
file:seek("set", 16)
|
||||||
|
local ws = file:read(4)
|
||||||
|
local hs = file:read(4)
|
||||||
|
local w = ws:sub(3, 3):byte() * 256 + ws:sub(4, 4):byte()
|
||||||
|
local h = hs:sub(3, 3):byte() * 256 + hs:sub(4, 4):byte()
|
||||||
|
if w >= 64 then
|
||||||
|
if w == h then
|
||||||
|
return "1.8"
|
||||||
|
elseif w == h * 2 then
|
||||||
|
return "1.0"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, fn in pairs(dir_list) do
|
||||||
|
local file = io.open(modpath.."/textures/"..fn, "rb")
|
||||||
|
if file then
|
||||||
|
skin_format[fn] = get_skin_format(file)
|
||||||
|
file:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 3rd party skin-switcher support
|
||||||
|
-- may be removed from future versions as these mods do not
|
||||||
|
-- use the proper api method for setting player textures
|
||||||
|
--
|
||||||
|
-- Auto skin format detection for 3rd party mods requires
|
||||||
|
-- that multiskin is included in 'trusted mods'
|
||||||
|
|
||||||
|
local env = minetest.request_insecure_environment()
|
||||||
|
local skin_mod = modname
|
||||||
|
local skin_mods = {"skins", "u_skins", "simple_skins", "wardrobe"}
|
||||||
|
for _, mod in pairs(skin_mods) do
|
||||||
|
local path = minetest.get_modpath(mod)
|
||||||
|
if path then
|
||||||
|
local dir_list = minetest.get_dir_list(path.."/textures")
|
||||||
|
for _, fn in pairs(dir_list) do
|
||||||
|
if fn:find("_preview.png$") then
|
||||||
|
skin_previews[fn] = true
|
||||||
|
elseif env then
|
||||||
|
local file = env.io.open(path.."/textures/"..fn, "rb")
|
||||||
|
if file then
|
||||||
|
skin_format[fn] = get_skin_format(file)
|
||||||
|
file:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
skin_mod = mod
|
||||||
|
end
|
||||||
|
end
|
||||||
|
env = nil
|
||||||
|
|
||||||
|
local function get_player_skin(player)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
if name then
|
||||||
|
local skin = nil
|
||||||
|
if skin_mod == "skins" or skin_mod == "simple_skins" then
|
||||||
|
skin = skins.skins[name]
|
||||||
|
elseif skin_mod == "u_skins" then
|
||||||
|
skin = u_skins.u_skins[name]
|
||||||
|
elseif skin_mod == "wardrobe" then
|
||||||
|
local skins = wardrobe.playerSkins or {}
|
||||||
|
if skins[name] then
|
||||||
|
return skins[name]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if skin then
|
||||||
|
return skin..".png"
|
||||||
|
end
|
||||||
|
for _, fn in pairs(dir_list) do
|
||||||
|
if fn == "player_"..name..".png" then
|
||||||
|
return fn
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return default_skin
|
||||||
|
end
|
||||||
|
|
||||||
|
multiskin = {
|
||||||
|
model = "multiskin.b3d",
|
||||||
|
skins = player_skins,
|
||||||
|
textures = player_textures,
|
||||||
|
}
|
||||||
|
|
||||||
|
multiskin.set_player_skin = function(player, skin)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local format = skin_format[skin]
|
||||||
|
if format then
|
||||||
|
player_format[name] = format
|
||||||
|
player:set_attribute("multiskin_format", format)
|
||||||
|
end
|
||||||
|
player_skins[name].skin = skin
|
||||||
|
player:set_attribute("multiskin_skin", skin)
|
||||||
|
end
|
||||||
|
|
||||||
|
multiskin.set_player_format = function(player, format)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
player_format[name] = format
|
||||||
|
player:set_attribute("multiskin_format", format)
|
||||||
|
end
|
||||||
|
|
||||||
|
multiskin.add_preview = function(texture)
|
||||||
|
skin_previews[texture] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
multiskin.get_preview = function(player)
|
||||||
|
local skin = player:get_attribute("multiskin_skin")
|
||||||
|
if skin then
|
||||||
|
local preview = skin:gsub(".png$", "_preview.png")
|
||||||
|
if skin_previews[preview] then
|
||||||
|
return preview
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
multiskin.update_player_visuals = function(player)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
if not name or not player_skins[name] then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local anim = default.player_get_animation(player) or {}
|
||||||
|
if anim.model == "character.b3d" then
|
||||||
|
default.player_set_model(player, multiskin.model)
|
||||||
|
elseif anim.model ~= multiskin.model then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local textures = player_textures[name] or {}
|
||||||
|
local skin = player_skins[name].skin or "blank.png"
|
||||||
|
local cape = player_skins[name].cape
|
||||||
|
local layers = {}
|
||||||
|
for k, v in pairs(player_skins[name]) do
|
||||||
|
if k ~= "skin" and k ~= "cape" then
|
||||||
|
table.insert(layers, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local overlay = table.concat(layers, "^")
|
||||||
|
local format = player_format[name] or default_format
|
||||||
|
if format == "1.8" then
|
||||||
|
if overlay ~= "" then
|
||||||
|
skin = skin.."^"..overlay
|
||||||
|
end
|
||||||
|
textures[1] = cape or "blank.png"
|
||||||
|
textures[2] = skin
|
||||||
|
else
|
||||||
|
if cape then
|
||||||
|
skin = skin.."^"..cape
|
||||||
|
end
|
||||||
|
if overlay == "" then
|
||||||
|
overlay = "blank.png"
|
||||||
|
end
|
||||||
|
textures[1] = skin
|
||||||
|
textures[2] = overlay
|
||||||
|
end
|
||||||
|
default.player_set_textures(player, table.copy(textures))
|
||||||
|
end
|
||||||
|
|
||||||
|
default.player_register_model("multiskin.b3d", {
|
||||||
|
animation_speed = 30,
|
||||||
|
textures = {
|
||||||
|
"blank.png",
|
||||||
|
"blank.png",
|
||||||
|
},
|
||||||
|
animations = {
|
||||||
|
stand = {x=0, y=79},
|
||||||
|
lay = {x=162, y=166},
|
||||||
|
walk = {x=168, y=187},
|
||||||
|
mine = {x=189, y=198},
|
||||||
|
walk_mine = {x=200, y=219},
|
||||||
|
sit = {x=81, y=160},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_on_joinplayer(function(player)
|
||||||
|
minetest.after(0, function(player)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local skin = player:get_attribute("multiskin_skin") or
|
||||||
|
get_player_skin(player)
|
||||||
|
local anim = default.player_get_animation(player) or {}
|
||||||
|
player_textures[name] = anim.textures or {}
|
||||||
|
player_skins[name] = {skin=skin}
|
||||||
|
player_format[name] = player:get_attribute("multiskin_format")
|
||||||
|
multiskin.set_player_skin(player, skin)
|
||||||
|
multiskin.update_player_visuals(player)
|
||||||
|
end, player)
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_on_leaveplayer(function(player)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
if name then
|
||||||
|
player_skins[name] = nil
|
||||||
|
player_format[name] = nil
|
||||||
|
player_textures[name] = nil
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
for field, _ in pairs(fields) do
|
||||||
|
if string.find(field, "skins_set") then
|
||||||
|
minetest.after(0, function(player)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local skin = get_player_skin(player)
|
||||||
|
multiskin.set_player_skin(player, skin)
|
||||||
|
multiskin.update_player_visuals(player)
|
||||||
|
end, player)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_chatcommand("multiskin", {
|
||||||
|
params = "<cmd> [name] [args]",
|
||||||
|
description = "Multiskin player skin and format management",
|
||||||
|
func = function(name, param)
|
||||||
|
if not minetest.is_singleplayer() and
|
||||||
|
not minetest.check_player_privs(name, {server=true}) then
|
||||||
|
return false, "Insufficient privileges"
|
||||||
|
end
|
||||||
|
local cmd, player_name, args = string.match(param, "^([^ ]+) (.-) (.+)$")
|
||||||
|
if not args then
|
||||||
|
cmd, player_name = string.match(param, "([^ ]+) (.+)")
|
||||||
|
end
|
||||||
|
local player = nil
|
||||||
|
if player_name then
|
||||||
|
player = minetest.get_player_by_name(player_name)
|
||||||
|
else
|
||||||
|
cmd = string.match(param, "([^ ]+)")
|
||||||
|
end
|
||||||
|
if cmd == "help" then
|
||||||
|
local msg = "\nUsage: /multiskin <cmd> [name] [args]\n\n"..
|
||||||
|
" format <player_name> <format> (1.0 or 1.8)\n"..
|
||||||
|
" set <player_name> <texture>\n"..
|
||||||
|
" unset <player_name>\n"..
|
||||||
|
" help (show this message)\n\n"
|
||||||
|
minetest.chat_send_player(name, msg)
|
||||||
|
elseif cmd == "format" and player and args then
|
||||||
|
multiskin.set_player_format(player, args)
|
||||||
|
multiskin.update_player_visuals(player)
|
||||||
|
elseif cmd == "set" and player and args then
|
||||||
|
multiskin.set_player_skin(player, args)
|
||||||
|
multiskin.update_player_visuals(player)
|
||||||
|
elseif cmd == "unset" and player then
|
||||||
|
player_skins[player_name].skin = get_player_skin(player)
|
||||||
|
player:set_attribute("multiskin_skin", nil)
|
||||||
|
multiskin.update_player_visuals(player)
|
||||||
|
else
|
||||||
|
return false, "Invalid parameters, see /multiskin help"
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
1
worldmods/multiskin/mod.conf
Normal file
1
worldmods/multiskin/mod.conf
Normal file
@ -0,0 +1 @@
|
|||||||
|
name = multiskin
|
BIN
worldmods/multiskin/models/multiskin.b3d
Normal file
BIN
worldmods/multiskin/models/multiskin.b3d
Normal file
Binary file not shown.
BIN
worldmods/multiskin/models/multiskin.blend
Normal file
BIN
worldmods/multiskin/models/multiskin.blend
Normal file
Binary file not shown.
1
worldmods/multiskin/textures/skins_here.txt
Normal file
1
worldmods/multiskin/textures/skins_here.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Place your player skins here named as `player_<player_name>.png`
|
Loading…
x
Reference in New Issue
Block a user