315 lines
7.6 KiB
Lua
315 lines
7.6 KiB
Lua
--
|
|
-- Armor mod
|
|
-- By Kaadmy, for Pixture
|
|
--
|
|
|
|
armor = {}
|
|
|
|
armor.player_skin = "character.png"
|
|
armor.update_time = 1
|
|
|
|
armor.materials = {
|
|
-- material craftitem % description
|
|
{"wood", "group:planks", 15, "Wooden"},
|
|
{"steel", "default:ingot_steel", 30, "Steel"},
|
|
{"chainmail", "armor:chainmail_sheet", 45, "Chainmail"},
|
|
{"carbonsteel", "default:ingot_carbonsteel", 60, "Carbonsteel"},
|
|
}
|
|
|
|
armor.slots = {"helmet", "chestplate", "boots"}
|
|
|
|
local form_armor = default.ui.get_page("core_2part")
|
|
default.ui.register_page("core_armor", form_armor)
|
|
|
|
local enable_drop = core.setting_getbool("drop_items_on_die") or false
|
|
|
|
local armor_timer = 10
|
|
|
|
function armor.is_armor(itemname)
|
|
local item = core.registered_items[itemname]
|
|
|
|
if item ~= nil and item.groups ~= nil then
|
|
if item.groups.is_armor then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
|
|
function armor.is_slot(itemname, slot)
|
|
local match = string.find(itemname, "armor:" .. slot .. "_")
|
|
local matchbool = false
|
|
if match ~= nil and match >= 1 then
|
|
matchbool = true
|
|
end
|
|
return matchbool
|
|
end
|
|
|
|
function armor.get_base_skin(player)
|
|
if core.get_modpath("player_skins") ~= nil then
|
|
return player_skins.get_skin(player:get_player_name())
|
|
else
|
|
return armor.player_skin
|
|
end
|
|
end
|
|
|
|
function armor.get_texture(player, base)
|
|
local inv = player:get_inventory()
|
|
|
|
local image = base
|
|
|
|
for _, slot in ipairs(armor.slots) do
|
|
local itemstack = inv:get_stack("armor_"..slot, 1)
|
|
local itemname = itemstack:get_name()
|
|
if armor.is_armor(itemname) and armor.is_slot(itemname, slot) then
|
|
local item = core.registered_items[itemname]
|
|
local mat = armor.materials[item.groups.armor_material][1]
|
|
|
|
image = image .. "^armor_" .. slot .. "_" .. mat ..".png"
|
|
end
|
|
end
|
|
|
|
-- print("[armor] Got armor texture: " .. image)
|
|
|
|
return image
|
|
end
|
|
|
|
function armor.get_groups(player)
|
|
local groups = {fleshy = 100}
|
|
|
|
local match_mat = nil
|
|
local match_amt = 0
|
|
|
|
local inv = player:get_inventory()
|
|
|
|
for _, slot in ipairs(armor.slots) do
|
|
local itemstack = inv:get_stack("armor_"..slot, 1)
|
|
local itemname = itemstack:get_name()
|
|
|
|
if armor.is_armor(itemname) then
|
|
local item = core.registered_items[itemname]
|
|
|
|
for mat_index, _ in ipairs(armor.materials) do
|
|
local mat = armor.materials[mat_index][1]
|
|
|
|
if mat_index == item.groups.armor_material then
|
|
groups.fleshy = groups.fleshy - item.groups.armor
|
|
if match_mat == nil then
|
|
match_mat = mat
|
|
end
|
|
if mat == match_mat then
|
|
match_amt = match_amt + 1
|
|
end
|
|
break
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
if match_amt == #armor.slots then -- if full set of same armor material, then boost armor by 10%
|
|
groups.fleshy = groups.fleshy - 10
|
|
end
|
|
|
|
-- print("[armor] Armor groups: " .. dump(groups))
|
|
|
|
return groups
|
|
end
|
|
|
|
function armor.init(player)
|
|
local inv = player:get_inventory()
|
|
|
|
for _, slot in ipairs(armor.slots) do
|
|
if inv:get_size("armor_"..slot) ~= 1 then
|
|
inv:set_size("armor_"..slot, 1)
|
|
end
|
|
end
|
|
end
|
|
|
|
function armor.update(player)
|
|
local groups = armor.get_groups(player)
|
|
player:set_armor_groups({fleshy = groups.fleshy})
|
|
|
|
local image = armor.get_texture(player, armor.get_base_skin(player))
|
|
if image ~= default.player_get_textures(player)[1] then
|
|
default.player_set_textures(player, {image})
|
|
end
|
|
end
|
|
|
|
local function on_newplayer(player)
|
|
armor.init(player)
|
|
end
|
|
|
|
local function on_joinplayer(player)
|
|
armor.init(player)
|
|
end
|
|
|
|
local function on_die(player)
|
|
local pos = player:getpos()
|
|
|
|
local inv = player:get_inventory()
|
|
|
|
for _, slot in ipairs(armor.slots) do
|
|
local item = inv:get_stack("armor_"..slot, 1)
|
|
|
|
local rpos = {
|
|
x = pos.x + math.random(-0.2, 0.2),
|
|
y = pos.y,
|
|
z = pos.z + math.random(-0.2, 0.2)
|
|
}
|
|
|
|
local drop = core.add_item(rpos, item)
|
|
|
|
if drop then
|
|
drop:setvelocity(
|
|
{
|
|
x = math.random(-0.3, 0.3),
|
|
y = 3,
|
|
z = math.random(-0.3, 0.3),
|
|
})
|
|
end
|
|
|
|
item:clear()
|
|
inv:set_stack("armor_" .. slot, 1, item)
|
|
end
|
|
end
|
|
|
|
local function step(dtime)
|
|
armor_timer = armor_timer + dtime
|
|
|
|
if armor_timer > armor.update_time then
|
|
for _, player in pairs(core.get_connected_players()) do
|
|
armor.update(player)
|
|
end
|
|
armor_timer = 0
|
|
end
|
|
end
|
|
|
|
core.register_craftitem(
|
|
"armor:chainmail_sheet",
|
|
{
|
|
description = "Chainmail sheet",
|
|
|
|
inventory_image = "armor_chainmail.png",
|
|
wield_image = "armor_chainmail.png",
|
|
|
|
stack_max = 20,
|
|
})
|
|
|
|
core.register_craft(
|
|
{
|
|
output = "armor:chainmail_sheet 3",
|
|
recipe = {
|
|
{"default:ingot_steel", "", "default:ingot_steel"},
|
|
{"", "default:ingot_steel", ""},
|
|
{"default:ingot_steel", "", "default:ingot_steel"},
|
|
}
|
|
})
|
|
|
|
for mat_index, _ in ipairs(armor.materials) do
|
|
local def = armor.materials[mat_index]
|
|
local mat = def[1]
|
|
|
|
local armor_def = math.floor(def[3] / #armor.slots)
|
|
-- print("Material " .. mat .. ": " .. armor_def)
|
|
|
|
for _, slot in ipairs(armor.slots) do
|
|
core.register_craftitem(
|
|
"armor:"..slot.."_"..mat,
|
|
{
|
|
description = def[4].." "..slot,
|
|
|
|
inventory_image = "armor_"..slot.."_"..mat.."_inventory.png",
|
|
wield_image = "armor_"..slot.."_"..mat.."_inventory.png",
|
|
|
|
groups = {
|
|
is_armor = 1,
|
|
armor = armor_def,
|
|
armor_material = mat_index
|
|
},
|
|
|
|
stack_max = 1,
|
|
})
|
|
end
|
|
|
|
local n = def[2]
|
|
|
|
core.register_craft(
|
|
{
|
|
output = "armor:helmet_"..mat,
|
|
recipe = {
|
|
{n, n, n},
|
|
{n, "", n},
|
|
{"", "", ""},
|
|
}
|
|
})
|
|
core.register_craft(
|
|
{
|
|
output = "armor:chestplate_"..mat,
|
|
recipe = {
|
|
{n, "", n},
|
|
{n, n, n},
|
|
{n, n, n},
|
|
}
|
|
})
|
|
core.register_craft(
|
|
{
|
|
output = "armor:boots_"..mat,
|
|
recipe = {
|
|
{"", "", ""},
|
|
{n, "", n},
|
|
{n, "", n},
|
|
}
|
|
})
|
|
end
|
|
|
|
core.register_on_newplayer(on_newplayer)
|
|
core.register_on_joinplayer(on_joinplayer)
|
|
if enable_drop then
|
|
core.register_on_dieplayer(on_die)
|
|
end
|
|
core.register_globalstep(step)
|
|
|
|
local form_armor = default.ui.get_page("core_2part")
|
|
form_armor = form_armor .. "list[current_player;main;0.25,4.75;8,4;]"
|
|
form_armor = form_armor .. default.ui.get_hotbar_itemslot_bg(0.25, 4.75, 8, 1)
|
|
form_armor = form_armor .. default.ui.get_itemslot_bg(0.25, 5.75, 8, 3)
|
|
form_armor = form_armor .. "listring[current_player;main]"
|
|
|
|
form_armor = form_armor .. "label[3.25,3;Boots]"
|
|
form_armor = form_armor .. "list[current_player;armor_boots;2.25,2.75;1,1;]"
|
|
form_armor = form_armor .. "listring[current_player;armor_boots]"
|
|
form_armor = form_armor .. default.ui.get_itemslot_bg(2.25, 2.75, 1, 1)
|
|
|
|
form_armor = form_armor .. "label[3.25,2;Chestplate]"
|
|
form_armor = form_armor .. "list[current_player;armor_chestplate;2.25,1.75;1,1;]"
|
|
form_armor = form_armor .. "listring[current_player;armor_chestplate]"
|
|
form_armor = form_armor .. default.ui.get_itemslot_bg(2.25, 1.75, 1, 1)
|
|
|
|
form_armor = form_armor .. "label[3.25,1;Helmet]"
|
|
form_armor = form_armor .. "list[current_player;armor_helmet;2.25,0.75;1,1;]"
|
|
form_armor = form_armor .. "listring[current_player;armor_helmet]"
|
|
form_armor = form_armor .. default.ui.get_itemslot_bg(2.25, 0.75, 1, 1)
|
|
|
|
default.ui.register_page("core_armor", form_armor)
|
|
|
|
-- Achievements
|
|
|
|
achievements.register_achievement(
|
|
"armored",
|
|
{
|
|
title = "Armored",
|
|
description = "Craft a piece of armor",
|
|
times = 1,
|
|
craftitem = "group:is_armor",
|
|
})
|
|
|
|
achievements.register_achievement(
|
|
"warrior",
|
|
{
|
|
title = "Warrior",
|
|
description = "Craft 10 piece of armor",
|
|
times = 10,
|
|
craftitem = "group:is_armor",
|
|
})
|
|
|
|
default.log("mod:armor", "loaded") |