Add customizable skins support (WIP)

master
Wuzzy 2021-07-23 01:01:51 +02:00
parent 6bc2dbdf6f
commit 049474d81c
28 changed files with 296 additions and 0 deletions

View File

@ -0,0 +1,9 @@
Mesh hand mod for Hades Revisited
This mod uses a better-looking mesh for the wieldhand and applies the player skin color to it.
== Credits ==
Based on 3D Hand [newhand] mod by jordan4ibanez.
https://forum.minetest.net/viewtopic.php?t=16435
License: CC0

View File

@ -0,0 +1,41 @@
hades_meshhand = {}
local handdef = minetest.registered_items[""]
-- This is a fake node that should never be placed in the world
minetest.register_node("hades_meshhand:hand", {
description = "",
tiles = {"hades_skins_skin_base.png"},
use_texture_alpha = "opaque",
visual_scale = 1,
wield_scale = {x=1,y=1,z=1},
paramtype = "light",
drawtype = "mesh",
mesh = "hades_meshhand.b3d",
-- Prevent construction
node_placement_prediction = "",
on_construct = function(pos)
minetest.log("error", "[hades_meshhand] Trying to construct hades_meshhand:hand at "..minetest.pos_to_string(pos))
minetest.remove_node(pos)
end,
drop = "",
on_drop = function()
return ""
end,
-- Allow to get rid of the node if it somehow ended up in world
buildable_to = true,
groups = { dig_immediate = 3, not_in_creative_inventory = 1 },
range = handdef.range,
})
minetest.register_on_joinplayer(function(player)
player:get_inventory():set_size("hand", 1)
end)
function hades_meshhand.set_skin_color(player, colorstring)
local hand = ItemStack("hades_meshhand:hand")
local handmeta = hand:get_meta()
handmeta:set_string("color", colorstring)
player:get_inventory():set_stack("hand", 1, hand)
end

View File

@ -0,0 +1,3 @@
name = hades_meshhand
author = jordan4ibanez
description = Applies the player skin texture to the hand.

Binary file not shown.

Binary file not shown.

View File

@ -77,6 +77,12 @@ function hades_player.player_set_textures(player, textures)
player:set_properties({textures = textures,})
end
function hades_player.player_get_textures(player)
local name = player:get_player_name()
local props = player:get_properties()
return props.textures
end
function hades_player.player_set_animation(player, anim_name, speed)
local name = player:get_player_name()
if player_anim[name] == anim_name then

View File

@ -0,0 +1,40 @@
License and credits:
The overall license of the media is CC BY-SA 3.0.
In the list below, there's a list of all authors and indivudual file licenses.
Note: Files marked with an asterisk were modified from the original.
Wuzzy (CC0 1.0):
- hades_skins_eyes_base.png
- hades_skins_eyes_pupils.png
- hades_skins_mouth.png
- hades_skins_pupils.png
- hades_skins_pants_shorts.png
- hades_skins_pants_hotpants.png
- hades_skins_shirt_top.png
- hades_skins_shirt_tanktop.png
- hades_skins_accessoire_head_flowers.png
Kosanaya (CC BY-SA 3.0):
* hades_skins_accessoire_head_bikutoria.png (original skin: Bikutoria_by_Kosanaya.png)
Minetestian (CC BY-SA 3.0):
* hades_skins_shirt_minetestian.png (original skin: Minetestian_by_Minetestian.png)
nelly (CC BY-SA 3.0):
* hades_skins_hair_emma.png (original skin: Emma_by_nelly.png)
QoiOui (CC BY-SA 3.0):
* hades_skins_hair_quioui.png (original skin: QoiOui_by_QoiOui.png)
Geopbyte (CC BY-SA 3.0):
* character.png (original skin: Geopbyte_by_Geopbyte.png)
* hades_skins_belt_simple.png (original skin: Geopbyte_by_Geopbyte.png)
* hades_skins_hair_simple.png (original skin: Geopbyte_by_Geopbyte.png)
* hades_skins_pants_simple.png (original skin: Geopbyte_by_Geopbyte.png)
* hades_skins_shirt_simple.png (original skin: Geopbyte_by_Geopbyte.png)
* hades_skins_shoes_simple.png (original skin: Geopbyte_by_Geopbyte.png)
* hades_skins_skin_base.png (original skin: Geopbyte_by_Geopbyte.png)

195
mods/hades_skins/init.lua Normal file
View File

@ -0,0 +1,195 @@
local S = minetest.get_translator("hades_skins")
local F = minetest.formspec_escape
hades_skins = {}
local editor_color_states = {}
local editor_cloth_states = {}
local get_color = function(r, g, b)
if not r then
r = math.random(0,255)
end
if not g then
g = math.random(0,255)
end
if not b then
b = math.random(0,255)
end
local cstr = string.format("#%.2X%.2X%.2X", r, g, b)
return cstr
end
local styles = {
hair = { "simple", "emma", "quioui" },
accessoire_head = { "blank", "bikutoria", "headband", "flowers" },
shirt = { "simple", "tanktop", "top", "minetestian"},
belt = { "blank", "simple" },
pants = { "simple", "shorts", "hotpants" },
shoes = { "simple" },
skin = { "base" },
eyes = { "pupils" },
}
local styles_sorted = {
"skin", "accessoire_head", "hair", "eyes", "shirt", "belt", "pants", "shoes"
}
function hades_skins.get_random_textures_and_colors()
local color = {}
local base = {}
local tex = {}
for k, v in pairs(styles) do
color[k] = get_color()
base[k] = v[math.random(1, #v)]
end
color.skin = get_color()
color.eyes = get_color()
return { colors = color, bases = base }
end
function hades_skins.build_texture(base, color)
local tex = {}
for k, v in pairs(styles) do
if base[k] ~= "blank" then
tex[k] = "^(hades_skins_"..k.."_"..base[k]..".png"
tex[k] = tex[k] .. "^[multiply:"..color[k]..")"
else
tex[k] = ""
end
end
if not color.skin then
color.skin = get_color()
end
if not color.eyes then
color.eyes = get_color()
end
local eyes = "^(hades_skins_eyes_base.png"
.. "^(hades_skins_eyes_pupils.png^[multiply:"..color.eyes.."))"
local skin = "((hades_skins_skin_base.png^hades_skins_mouth.png)^[multiply:"..color.skin..")"
local texture = skin
.. eyes
.. tex.pants
.. tex.shoes
.. tex.shirt
.. tex.belt
.. tex.hair
.. tex.accessoire_head
return { textures = { texture }, colors = color }
end
function hades_skins.editor_state_to_textures(player)
local name = player:get_player_name()
local bases = {}
local colors = {}
for k,v in pairs(editor_cloth_states[name]) do
bases[k] = styles[k][v]
end
for k,v in pairs(editor_color_states[name]) do
colors[k] = string.format("#%.6X", v)
end
return hades_skins.build_texture(bases, colors)
end
function hades_skins.player_set_textures(player, textures, skin_color)
hades_player.player_set_textures(player, textures)
-- Set meshhand
hades_meshhand.set_skin_color(player, skin_color)
end
function hades_skins.player_set_random_textures(player)
local texcol = hades_skins.get_random_textures_and_colors()
local out = hades_skins.build_texture(texcol.bases, texcol.colors)
hades_skins.player_set_textures(player, out.textures, out.colors.skin)
end
function hades_skins.show_skin_editor(player, texture)
if not texture then
texture = hades_player.player_get_textures(player)
if not texture then
return
end
texture = texture[1]
end
local formspec = [[
formspec_version[4]
size[12,11]
box[0.4,0.4;4.2,8.2;#FFFFFF4F]
box[0.5,0.5;4,8;#000000FF]
model[0.5,0.5;4,8;playerpreview;character.b3d;]]..texture..[[;0,180;false;true;0,79]
button[5.15,9.75;1,0.8;random;]]..F(S("Random"))..[[]
button[6.15,9.75;1,0.8;reset;]]..F(S("Reset"))..[[]
button_exit[7.55,9.75;2,0.8;cancel;]]..F(S("Cancel"))..[[]
button_exit[9.55,9.75;2,0.8;submit;]]..F(S("OK"))..[[]
]]
local name = player:get_player_name()
local y = 0.5
for i=1, #styles_sorted do
local s = styles_sorted[i]
local id = editor_cloth_states[name][s]
local choice = styles[s][id]
formspec = formspec .. "button[5.15,"..y..";1,0.8;"..s.."_prev;<]"
formspec = formspec .. "button[6.15,"..y..";3,0.8;"..s..";"..F(S("@1: @2", s, choice)).."]"
formspec = formspec .. "button[9.15,"..y..";1,0.8;"..s.."_next;>]"
formspec = formspec .. "button[10.55,"..y..";1,0.8;"..s.."_color;"..F(S("Color")).."]"
y = y + 0.9
end
minetest.show_formspec(player:get_player_name(), "hades_skins:skin_editor", formspec)
end
minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
editor_color_states[name] = {}
editor_cloth_states[name] = {}
for k,_ in pairs(styles) do
editor_cloth_states[name][k] = 1
editor_color_states[name][k] = math.random(0, 0xFFFFFF)
end
end)
minetest.register_on_leaveplayer(function(player)
local name = player:get_player_name()
editor_color_states[name] = nil
editor_cloth_states[name] = nil
end)
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "hades_skins:skin_editor" then
return
end
local name = player:get_player_name()
local update_skin = function(player)
local out = hades_skins.editor_state_to_textures(player)
hades_skins.player_set_textures(player, out.textures, out.colors.skin)
hades_skins.show_skin_editor(player)
end
for stylename,_ in pairs(styles) do
if fields[stylename] or fields[stylename.."_next"] then
editor_cloth_states[name][stylename] = editor_cloth_states[name][stylename] + 1
if editor_cloth_states[name][stylename] > #styles[stylename] then
editor_cloth_states[name][stylename] = 1
end
update_skin(player)
return
elseif fields[stylename.."_prev"] then
editor_cloth_states[name][stylename] = editor_cloth_states[name][stylename] - 1
if editor_cloth_states[name][stylename] < 1 then
editor_cloth_states[name][stylename] = #styles[stylename]
end
update_skin(player)
return
elseif fields[stylename.."_color"] then
editor_color_states[name][stylename] = math.random(0, 0xFFFFFF)
update_skin(player)
return
end
end
if fields.random then
hades_skins.player_set_random_textures(player)
hades_skins.show_skin_editor(player)
end
end)

View File

@ -0,0 +1,2 @@
name = hades_skins
depends = hades_player, hades_meshhand

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 669 B