Generalized skin changing methods, allowing integration with other mods. Default uses 3d_armor if present, or default mesh texture change if not.

master
prestidigitator 2015-05-21 16:03:10 -07:00
parent fe4c644b84
commit c48b01180c
2 changed files with 151 additions and 73 deletions

120
init.lua
View File

@ -5,87 +5,61 @@ local WORLD_PATH = minetest.get_worldpath();
if MOD_NAME ~= "wardrobe" then
error("mod directory must be named 'wardrobe'");
end
local armor_mod = false;
if minetest.get_modpath("3d_armor") then armor_mod = true; end;
wardrobe = {};
local initSkin, changeSkin, updateSkin = dofile(MOD_PATH.."/skinMethods.lua");
dofile(MOD_PATH.."/storage.lua");
dofile(MOD_PATH.."/wardrobe.lua");
-- API
--- Updates the visual appearance of a player's skin according to whatever skin
-- has been set for the player.
--
-- @param player
-- The Player object for the player.
--
wardrobe.updatePlayerSkin = updateSkin;
--- Compatibility method.
--
-- Identical to wardrobe.updatePlayerSkin(player).
--
wardrobe.setPlayerSkin = updateSkin;
--- Changes the skin set for a named player.
--
-- Player need not be logged in. Automatically updates the player's visual
-- appearance accordingly if they ARE logged in.
--
-- @param playerName
-- Name of the player.
-- @param skin
-- Name of the skin.
--
function wardrobe.changePlayerSkin(playerName, skin)
changeSkin(playerName, skin);
local player = minetest.get_player_by_name(playerName);
if player then updateSkin(player); end;
end
wardrobe.storage.loadSkins();
wardrobe.storage.loadPlayerSkins();
local playerMesh = "character.b3d";
-- autodetect version of player mesh used by default
do
if default and default.registered_player_models then
local haveCharName = false; -- 'character.*' has priority
local name = nil;
local nNames = 0;
for k in pairs(default.registered_player_models) do
if string.find(k, "^character\\.[^\\.]+$") then
if haveCharName then nNames = 2; break; end;
name = k;
nNames = 1;
haveCharName = true;
elseif not haveCharName then
name = k;
nNames = nNames + 1;
end;
end;
if nNames == 1 then playerMesh = name; end;
end;
if initSkin then
minetest.register_on_joinplayer(
function(player)
minetest.after(1, initSkin, player)
end);
end;
function wardrobe.setPlayerSkin(player)
-- If 3d_armor is installed, let him set the model and textures
if armor_mod then return end
if not changeSkin then
error("No wardrobe skin change method registered. Check skinMethods.lua.");
end;
if not updateSkin then
error("No wardrobe skin update method registered. Check skinMethods.lua.");
end;
local playerName = player:get_player_name();
if not playerName or playerName == "" then return; end;
local skin = wardrobe.playerSkins[playerName];
if not skin or not wardrobe.skinNames[skin] then return; end;
player:set_properties(
{
visual = "mesh",
visual_size = { x = 1, y = 1 },
mesh = playerMesh,
textures = { skin }
});
end
function wardrobe.changePlayerSkin(playerName, skin)
local player = minetest.get_player_by_name(playerName);
if not player then
error("unknown player '"..playerName.."'");
return;
end
if skin and not wardrobe.skinNames[skin] then
error("unknown skin '"..skin.."'");
return;
end
wardrobe.playerSkins[playerName] = skin;
wardrobe.storage.savePlayerSkins();
-- If 3d_armor is installed, update the skin texture and the armor
if armor_mod then
armor.textures[playerName].skin = skin;
armor:update_player_visuals(player);
else wardrobe.setPlayerSkin(player) end
end
minetest.register_on_joinplayer(
function(player)
minetest.after(1,
function(player)
wardrobe.setPlayerSkin(player);
end,
player);
end);

104
skinMethods.lua Normal file
View File

@ -0,0 +1,104 @@
-- Returns:
-- initSkin(player)
-- changeSkin(playerName, skin)
-- updateSkin(player)
local wardrobe = wardrobe or {};
--- Methods for initializing/changing/updating skin. Valid values are keys
-- from the SKIN_CHANGE_METHODS table (below). nil means use the default
-- method.
local SKIN_CHANGE_METHOD = '3d_armor';
local playerMesh = "character.b3d";
do -- autodetect version of player mesh used by default
if default and default.registered_player_models then
local haveCharName = false; -- 'character.*' has priority
local name = nil;
local nNames = 0;
for k in pairs(default.registered_player_models) do
if string.find(k, "^character\\.[^\\.]+$") then
if haveCharName then nNames = 2; break; end;
name = k;
nNames = 1;
haveCharName = true;
elseif not haveCharName then
name = k;
nNames = nNames + 1;
end;
end;
if nNames == 1 then playerMesh = name; end;
end;
end;
local function changeWardrobeSkin(playerName, skin)
local player = minetest.get_player_by_name(playerName);
if not player then
error("unknown player '"..playerName.."'");
end;
if skin and not wardrobe.skinNames[skin] then
error("unknown skin '"..skin.."'");
end;
wardrobe.playerSkins[playerName] = skin;
wardrobe.storage.savePlayerSkins();
end;
local function defaultUpdateSkin(player)
local playerName = player:get_player_name();
if not playerName or playerName == "" then return; end;
local skin = wardrobe.playerSkins[playerName];
if not skin or not wardrobe.skinNames[skin] then return; end;
player:set_properties(
{
visual = "mesh",
visual_size = { x = 1, y = 1 },
mesh = playerMesh,
textures = { skin }
});
end;
--- Method for updating the player skin, IF the dependent mod is enabled.
local SKIN_CHANGE_METHODS =
{
default =
{
required_mods = {},
initSkin = defaultUpdateSkin,
changeSkin = changeWardrobeSkin,
updateSkin = defaultUpdateSkin
},
["3d_armor"] =
{
required_mods = { '3d_armor' },
initSkin = nil,
changeSkin = function(playerName, skin)
changeWardrobeSkin(playerName, skin);
armor.textures[playerName].skin = skin;
end,
updateSkin = function(player)
armor:update_player_visuals(player);
end,
},
};
local methods = SKIN_CHANGE_METHODS[SKIN_CHANGE_METHOD];
if methods then
for _, mod in ipairs(methods.required_mods) do
if not minetest.get_modpath(mod) then methods = nil; break; end;
end;
end;
if not methods then methods = SKIN_CHANGE_METHODS.default; end;
return methods.initSkin, methods.changeSkin, methods.updateSkin;