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