Merge pull request 'Add capes' (#4046) from capes into master

Reviewed-on: https://git.minetest.land/MineClone2/MineClone2/pulls/4046
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
This commit is contained in:
the-real-herowl 2024-01-20 03:26:10 +00:00
commit cfd41d458a
18 changed files with 219 additions and 62 deletions

View file

@ -227,5 +227,27 @@ minetest.register_tool("mcl_armor:elytra", {
on_place = mcl_armor.equip_on_use, on_place = mcl_armor.equip_on_use,
on_secondary_use = mcl_armor.equip_on_use, on_secondary_use = mcl_armor.equip_on_use,
_mcl_armor_element = "torso", _mcl_armor_element = "torso",
_mcl_armor_texture = "mcl_armor_elytra.png" _mcl_armor_texture = function(obj, itemstack)
if obj:is_player() then
local cape = mcl_skins.player_skins[obj].cape
if cape ~= "blank.png" then
return cape:gsub("_body", "_elytra")
end
end
return "mcl_armor_elytra.png"
end,
_on_equip = function(obj, itemstack)
if not obj:is_player() then return end
local cape = mcl_skins.player_skins[obj].cape
if cape ~= "blank.png" then
local skinval = mcl_player.player_get_skin(obj)
skinval = skinval:gsub("%^" .. cape, "")
mcl_player.player_set_skin(obj, skinval)
-- this doesn't mess with the data mcl_skins has, so when mcl_skins reloads (which happens when the elytra is unequipped), the normal cape returns
end
end,
_on_unequip = function(obj, itemstack)
if not obj:is_player() then return end
mcl_skins.update_player_skin(obj)
end
}) })

View file

@ -129,6 +129,11 @@ function mcl_player.player_set_skin(player, texture)
update_player_textures(player) update_player_textures(player)
end end
function mcl_player.player_get_skin(player)
local name = player:get_player_name()
return player_textures[name][1]
end
function mcl_player.player_set_armor(player, texture) function mcl_player.player_set_armor(player, texture)
local name = player:get_player_name() local name = player:get_player_name()
player_textures[name][2] = texture player_textures[name][2] = texture

View file

@ -5,8 +5,8 @@ local EDIT_SKIN_KEY = -1 -- The key used for edit skin in the mcl_skins.simple_s
mcl_skins = { mcl_skins = {
simple_skins = {}, simple_skins = {},
texture_to_simple_skin = {}, texture_to_simple_skin = {},
item_names = {"base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear"}, item_names = {"base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear", "cape"},
tab_names = {"skin", "template", "base", "headwear", "hair", "eye", "mouth", "top", "arm", "bottom", "footwear"}, tab_names = {"skin", "template", "base", "headwear", "hair", "eye", "mouth", "top", "arm", "bottom", "footwear", "cape"},
tab_descriptions = { tab_descriptions = {
template = S("Templates"), template = S("Templates"),
arm = S("Arm size"), arm = S("Arm size"),
@ -19,7 +19,9 @@ mcl_skins = {
hair = S("Hairs"), hair = S("Hairs"),
headwear = S("Headwears"), headwear = S("Headwears"),
skin = S("Skins"), skin = S("Skins"),
cape = S("Capes")
}, },
cape = {},
template1 = {}, -- Stores edit skin values for template1 template1 = {}, -- Stores edit skin values for template1
template2 = {}, -- Stores edit skin values for template2 template2 = {}, -- Stores edit skin values for template2
base = {}, -- List of base textures base = {}, -- List of base textures
@ -59,7 +61,21 @@ mcl_skins = {
function mcl_skins.register_item(item) function mcl_skins.register_item(item)
assert(mcl_skins[item.type], "Skin item type " .. item.type .. " does not exist.") assert(mcl_skins[item.type], "Skin item type " .. item.type .. " does not exist.")
if item.type == "cape" then
local func = item.selector_func
if type(func) == "string" then
func = loadstring(func)()
end
table.insert(mcl_skins.cape, {name=item.name, selector_func=func, mask=item.mask})
mcl_skins.masks[item.name] = item.mask
return
end
local texture = item.texture or "blank.png" local texture = item.texture or "blank.png"
if item.template1 then if item.template1 then
mcl_skins.template1[item.type] = texture mcl_skins.template1[item.type] = texture
end end
@ -145,8 +161,16 @@ function mcl_skins.update_player_skin(player)
end end
local skin = mcl_skins.player_skins[player] local skin = mcl_skins.player_skins[player]
local skinval = mcl_skins.compile_skin(skin)
mcl_player.player_set_skin(player, mcl_skins.compile_skin(skin)) if player:get_inventory():get_stack("armor", 3):get_name() == "mcl_armor:elytra" then
skinval = skinval:gsub("%^" .. skin.cape, "")
-- don't render the "normal" cape on players while wearing the elytra.
-- this is NOT used when the player puts an elytra on, see register.lua in mcl_armor for that.
-- this is used when a player joins or changes something regarding their skin.
end
mcl_player.player_set_skin(player, skinval)
local slim_arms local slim_arms
if skin.simple_skins_id then if skin.simple_skins_id then
@ -200,9 +224,17 @@ minetest.register_on_leaveplayer(function(player)
mcl_skins.player_formspecs[player] = nil mcl_skins.player_formspecs[player] = nil
end) end)
local function calculate_page_count(tab) local function calculate_page_count(tab, player)
if tab == "skin" then if tab == "skin" then
return math.ceil((#mcl_skins.simple_skins + 2) / 8) return math.ceil((#mcl_skins.simple_skins + 2) / 8)
elseif tab == "cape" then
local player_capes = 0
for _, cape in pairs(mcl_skins.cape) do
if type(cape.selector_func) == "nil" or cape.selector_func(player) then
player_capes = player_capes + 1
end
end
return math.ceil((player_capes + 1) / 5) -- add one so the player can select no cape as well
elseif mcl_skins[tab] then elseif mcl_skins[tab] then
return math.ceil(#mcl_skins[tab] / 16) return math.ceil(#mcl_skins[tab] / 16)
end end
@ -214,7 +246,7 @@ function mcl_skins.show_formspec(player, active_tab, page_num)
local skin = mcl_skins.player_skins[player] local skin = mcl_skins.player_skins[player]
formspec_data.active_tab = active_tab formspec_data.active_tab = active_tab
local page_count = calculate_page_count(active_tab) local page_count = calculate_page_count(active_tab, player)
if page_num < 1 then page_num = 1 end if page_num < 1 then page_num = 1 end
if page_num > page_count then page_num = page_count end if page_num > page_count then page_num = page_count end
formspec_data.page_num = page_num formspec_data.page_num = page_num
@ -231,7 +263,7 @@ function mcl_skins.show_formspec(player, active_tab, page_num)
formspec = formspec .. formspec = formspec ..
"style[" .. tab .. ";content_offset=16,0]" .. "style[" .. tab .. ";content_offset=16,0]" ..
"button[0.3," .. y .. ";4,0.8;" .. tab .. ";" .. mcl_skins.tab_descriptions[tab] .. "]" .. "button[0.3," .. y .. ";4,0.8;" .. tab .. ";" .. mcl_skins.tab_descriptions[tab] .. "]" ..
"image[0.4," .. y + 0.1 .. ";0.6,0.6;mcl_skins_icons.png^[verticalframe:11:" .. i - 1 .. "]" "image[0.4," .. y + 0.1 .. ";0.6,0.6;mcl_skins_icons.png^[verticalframe:12:" .. i - 1 .. "]"
if skin.simple_skins_id then break end if skin.simple_skins_id then break end
end end
@ -249,6 +281,9 @@ function mcl_skins.show_formspec(player, active_tab, page_num)
mcl_skins.compile_skin(skin) .. mcl_skins.compile_skin(skin) ..
",blank.png,blank.png;0,180;false;true;0,0]" ",blank.png,blank.png;0,180;false;true;0,0]"
local cape_tab = active_tab == "cape"
if active_tab == "skin" then if active_tab == "skin" then
local page_start = (page_num - 1) * 8 - 1 local page_start = (page_num - 1) * 8 - 1
local page_end = math.min(page_start + 8 - 1, #mcl_skins.simple_skins) local page_end = math.min(page_start + 8 - 1, #mcl_skins.simple_skins)
@ -306,6 +341,36 @@ function mcl_skins.show_formspec(player, active_tab, page_num)
"button[7.5,5.2;2,0.8;template2;" .. S("Select") .. "]" "button[7.5,5.2;2,0.8;template2;" .. S("Select") .. "]"
elseif cape_tab then
local possize = {{"6,2;1,2", "5.5,4.2;2,0.8"}, {"9,2;1,2","8.5,4.2;2,0.8"}, {"6,7;1,2","5.5,9.2;2,0.8"}, {"9,7;1,2","8.5,9.2;2,0.8"},{"12,7;1,2","11.5,9.2;2,0.8"}}
local player_capes = {} -- contains all capes the player is allowed to wear
for _, cape in pairs (mcl_skins.cape) do
if type(cape.selector_func) == "nil" or cape.selector_func(player) then
table.insert(player_capes, cape)
end
end
local slot_offset = 0
if page_num == 1 then
formspec = formspec ..
"label[6,3;" .. S("(None)") .. "]"..
"button[5.5,4.2;2,0.8;nocape;" .. S("Select") .. "]"
slot_offset = 1
end
local array_start = page_num * 5 - 4
local index_offset = page_num == 1 and 1 or 2
for slot = 1 + slot_offset, page_num ~= page_count and 5 or (#player_capes % 5 == 0 and 1 or #player_capes % 5) + slot_offset do
local cape = player_capes[array_start + slot - slot_offset - index_offset]
local pos = possize[slot]
formspec = formspec ..
"image[" .. possize[slot][1] .. ";" .. cape.name ..".png]"..
"button[" .. possize[slot][2] .. ";" .. cape.name ..";" .. S("Select") .. "]"
end
elseif mcl_skins[active_tab] then elseif mcl_skins[active_tab] then
formspec = formspec .. formspec = formspec ..
"style_type[button;bgcolor=#00000000]" "style_type[button;bgcolor=#00000000]"
@ -421,19 +486,34 @@ function mcl_skins.show_formspec(player, active_tab, page_num)
end end
if page_num > 1 then if page_num > 1 then
if cape_tab then
formspec = formspec ..
"image_button[4.5,0.7;1,1;mcl_skins_arrow.png^[transformFX;previous_page;]"
else
formspec = formspec .. formspec = formspec ..
"image_button[4.5,6.7;1,1;mcl_skins_arrow.png^[transformFX;previous_page;]" "image_button[4.5,6.7;1,1;mcl_skins_arrow.png^[transformFX;previous_page;]"
end end
end
if page_num < page_count then if page_num < page_count then
if cape_tab then
formspec = formspec ..
"image_button[9.8,0.7;1,1;mcl_skins_arrow.png;next_page;]"
else
formspec = formspec .. formspec = formspec ..
"image_button[9.8,6.7;1,1;mcl_skins_arrow.png;next_page;]" "image_button[9.8,6.7;1,1;mcl_skins_arrow.png;next_page;]"
end end
end
if page_count > 1 then if page_count > 1 then
if cape_tab then
formspec = formspec ..
"label[7.3,1.2;" .. page_num .. " / " .. page_count .. "]"
else
formspec = formspec .. formspec = formspec ..
"label[7.3,7.2;" .. page_num .. " / " .. page_count .. "]" "label[7.3,7.2;" .. page_num .. " / " .. page_count .. "]"
end end
end
local player_name = player:get_player_name() local player_name = player:get_player_name()
minetest.show_formspec(player_name, "mcl_skins:skins", formspec) minetest.show_formspec(player_name, "mcl_skins:skins", formspec)
@ -472,6 +552,23 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
mcl_skins.update_player_skin(player) mcl_skins.update_player_skin(player)
mcl_skins.show_formspec(player, active_tab, page_num) mcl_skins.show_formspec(player, active_tab, page_num)
return true return true
elseif fields.nocape then
mcl_skins.player_skins[player].cape = "blank.png"
mcl_skins.update_player_skin(player)
mcl_armor.update(player) --update elytra cape
mcl_skins.show_formspec(player, active_tab, page_num)
return true
elseif active_tab == "cape" then
for cape_index = ((page_num - 1) * 5) + 1, math.min(#mcl_skins.cape, page_num * 5) do
local cape = mcl_skins.cape[cape_index]
if fields[cape.name] then
mcl_skins.player_skins[player].cape = cape.mask -- the actual overlay image
mcl_skins.update_player_skin(player)
mcl_armor.update(player) --update elytra cape
mcl_skins.show_formspec(player, active_tab, page_num)
return true
end
end
end end
for i, tab in pairs(mcl_skins.tab_names) do for i, tab in pairs(mcl_skins.tab_names) do
@ -600,12 +697,14 @@ local function init()
mcl_skins.template1.top_color = 0xff993535 mcl_skins.template1.top_color = 0xff993535
mcl_skins.template1.bottom_color = 0xff644939 mcl_skins.template1.bottom_color = 0xff644939
mcl_skins.template1.slim_arms = false mcl_skins.template1.slim_arms = false
mcl_skins.template1.cape = "blank.png"
mcl_skins.template2.base_color = mcl_skins.base_color[1] mcl_skins.template2.base_color = mcl_skins.base_color[1]
mcl_skins.template2.hair_color = 0xff715d57 mcl_skins.template2.hair_color = 0xff715d57
mcl_skins.template2.top_color = 0xff346840 mcl_skins.template2.top_color = 0xff346840
mcl_skins.template2.bottom_color = 0xff383532 mcl_skins.template2.bottom_color = 0xff383532
mcl_skins.template2.slim_arms = true mcl_skins.template2.slim_arms = true
mcl_skins.template2.cape = "blank.png"
mcl_skins.register_simple_skin({ mcl_skins.register_simple_skin({
index = 0, index = 0,
@ -619,3 +718,9 @@ local function init()
end end
init() init()
if not minetest.settings:get_bool("mcl_keepInventory", false) then
minetest.register_on_respawnplayer(function(player)
mcl_skins.update_player_skin(player) -- ensures players have their cape again after dying with an elytra
end)
end

View file

@ -263,5 +263,29 @@
"mask": "mcl_skins_base_1_mask.png", "mask": "mcl_skins_base_1_mask.png",
"template1": true, "template1": true,
"template2": true "template2": true
},
{
"type": "cape",
"name": "mtcape",
"mask": "mtcape_body.png",
"selector_func" : null
},
{
"type": "cape",
"name": "slimecape",
"mask": "slimecape_body.png",
"selector_func" : null
},
{
"type": "cape",
"name": "ghastcape",
"mask": "ghastcape_body.png",
"selector_func" : null
},
{
"type": "cape",
"name": "mclcape",
"mask": "mclcape_body.png",
"selector_func" : null
} }
] ]

View file

@ -12,3 +12,4 @@ Hairs=
Headwears= Headwears=
Open skin configuration screen.= Open skin configuration screen.=
Select= Select=
Capes=

BIN
textures/ghastcape.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
textures/ghastcape_body.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 420 B

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
textures/mclcape.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

BIN
textures/mclcape_body.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 803 B

BIN
textures/mclcape_elytra.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

BIN
textures/mtcape.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
textures/mtcape_body.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 780 B

BIN
textures/mtcape_elytra.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
textures/slimecape.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

BIN
textures/slimecape_body.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 821 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB