Rewrite armor; new damage system
This commit is contained in:
parent
78d387e2df
commit
ce0148d9a8
107
mods/CORE/mcl_damage/init.lua
Normal file
107
mods/CORE/mcl_damage/init.lua
Normal file
@ -0,0 +1,107 @@
|
||||
mcl_damage = {
|
||||
modifiers = {},
|
||||
types = {
|
||||
in_fire = {is_fire = true},
|
||||
lightning_bolt = {is_lightning = true},
|
||||
on_fire = {is_fire = true},
|
||||
lava = {is_fire = true},
|
||||
hot_floor = {is_fire = true},
|
||||
in_wall = {bypasses_armor = true},
|
||||
drown = {bypasses_armor = true},
|
||||
starve = {bypasses_armor = true, bypasses_magic = true},
|
||||
cactus = {},
|
||||
fall = {bypasses_armor = true},
|
||||
fly_into_wall = {bypasses_armor = true}, -- unused
|
||||
out_of_world = {bypasses_armor = true, bypasses_invulnerability = true, bypasses_magic = true},
|
||||
generic = {bypasses_armor = true},
|
||||
magic = {is_magic = true, bypasses_armor = true},
|
||||
wither = {bypasses_armor = true}, -- unused
|
||||
anvil = {},
|
||||
falling_node = {}, -- unused
|
||||
dragon_breath = {bypasses_armor = true}, -- unused
|
||||
mob = {},
|
||||
player = {},
|
||||
arrow = {is_projectile = true},
|
||||
fireball = {is_projectile = true, is_fire = true},
|
||||
thorns = {is_magic = true},
|
||||
explosion = {is_explosion = true},
|
||||
}
|
||||
}
|
||||
|
||||
local old_register_hpchange = minetest.register_on_player_hpchange
|
||||
|
||||
function minetest.register_on_player_hpchange(func, modifier)
|
||||
if modifier then
|
||||
mcl_damage.register_modifier(func, 0)
|
||||
else
|
||||
old_register_hpchange(func, modifier)
|
||||
end
|
||||
end
|
||||
|
||||
function mcl_damage.register_modifier(func, priority)
|
||||
table.insert(mcl_damage, {func = func, priority = priority or 0})
|
||||
end
|
||||
|
||||
function mcl_damage.get_mcl_damage_reason(mt_reason)
|
||||
local mcl_reason = {
|
||||
type = "generic",
|
||||
}
|
||||
|
||||
if mt_reason._mcl_type then
|
||||
mcl_reason.type = mt_reason._mcl_type
|
||||
elseif mt_reason.type == "fall" then
|
||||
mcl_reason.type = "fall"
|
||||
elseif mt_reason.type == "drown" then
|
||||
mcl_reason.type = "drown"
|
||||
elseif mt_reason.type == "punch" then
|
||||
mcl_reason.direct = mt_reason.object
|
||||
if mcl_reason.direct then
|
||||
local luaentity = mcl_reason.direct:get_luaentity()
|
||||
if luaentity then
|
||||
if luaentity._is_arrow then
|
||||
mcl_reason.type = "arrow"
|
||||
elseif luaentity._is_fireball then
|
||||
mcl_reason.type = "fireball"
|
||||
elseif luaentity._cmi_is_mob then
|
||||
mcl_reason.type = "mob"
|
||||
end
|
||||
mcl_reason.source = mcl_reason.source or luaentity._source_object
|
||||
else
|
||||
mcl_reason.type = "player"
|
||||
end
|
||||
end
|
||||
elseif mt_reason.type == "node_damage" then
|
||||
if minetest.get_item_group(reason.node or "", "fire_damage") > 0 then
|
||||
mcl_reason.type = "in_fire"
|
||||
end
|
||||
end
|
||||
|
||||
for key, value in pairs(mt_reason) do
|
||||
if key:find("_mcl_") == 1 then
|
||||
mcl_reason[key:sub(6, #key)] = value
|
||||
end
|
||||
end
|
||||
|
||||
mcl_reason.source = mcl_reason.source or mcl_reason.direct
|
||||
|
||||
mcl_reason.flags = mcl_damage.types[mcl_reason.type]
|
||||
end
|
||||
|
||||
function mcl_damage.register_type(name, def)
|
||||
mcl_damage.types[name] = def
|
||||
end
|
||||
|
||||
old_register_hpchange(function(player, hp_change, mt_reason)
|
||||
local mcl_reason = mcl_damage.get_mcl_damage_reason(mt_reason)
|
||||
|
||||
for _, modf in ipairs(mcl_damage.modifiers) do
|
||||
hp_change = modf.func(player, hp_change, mt_reason, mcl_reason) or hp_change
|
||||
end
|
||||
|
||||
return hp_change
|
||||
end, true)
|
||||
|
||||
minetest.register_on_mods_loaded(function()
|
||||
table.sort(mcl_damage.modifiers, function(a, b) return a.priority < b.priority end)
|
||||
end)
|
||||
|
3
mods/CORE/mcl_damage/mod.conf
Normal file
3
mods/CORE/mcl_damage/mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = mcl_damage
|
||||
author = Fleckenstein
|
||||
description = Minecraft-like damage reason system
|
@ -150,7 +150,8 @@ end
|
||||
-- raydirs - The directions for each ray
|
||||
-- radius - The maximum distance each ray will go
|
||||
-- info - Table containing information about explosion
|
||||
-- puncher - object that punches other objects (optional)
|
||||
-- direct - direct source object of the damage (optional)
|
||||
-- source - indirect source object of the damage (optional)
|
||||
--
|
||||
-- Values in info:
|
||||
-- drop_chance - The chance that destroyed nodes will drop their items
|
||||
@ -165,7 +166,7 @@ end
|
||||
-- Note that this function has been optimized, it contains code which has been
|
||||
-- inlined to avoid function calls and unnecessary table creation. This was
|
||||
-- measured to give a significant performance increase.
|
||||
local function trace_explode(pos, strength, raydirs, radius, info, puncher)
|
||||
local function trace_explode(pos, strength, raydirs, radius, info, direct, source)
|
||||
local vm = get_voxel_manip()
|
||||
|
||||
local emin, emax = vm:read_from_map(vector.subtract(pos, radius),
|
||||
@ -247,7 +248,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
|
||||
local ent = obj:get_luaentity()
|
||||
|
||||
-- Ignore items to lower lag
|
||||
if obj:is_player() or (ent and ent.name ~= '__builtin.item') then
|
||||
if (obj:is_player() or (ent and ent.name ~= '__builtin.item')) and obj:get_hp() > 0 then
|
||||
local opos = obj:get_pos()
|
||||
local collisionbox = nil
|
||||
|
||||
@ -321,7 +322,6 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
|
||||
impact = 0
|
||||
end
|
||||
local damage = math.floor((impact * impact + impact) * 7 * strength + 1)
|
||||
local source = puncher or obj
|
||||
|
||||
local sleep_formspec_doesnt_close_mt53 = false
|
||||
if obj:is_player() then
|
||||
@ -336,23 +336,22 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
|
||||
if mod_death_messages then
|
||||
mcl_death_messages.player_damage(obj, S("@1 was caught in an explosion.", name))
|
||||
end
|
||||
if rawget(_G, "armor") and armor.last_damage_types then
|
||||
armor.last_damage_types[name] = "explosion"
|
||||
end
|
||||
end
|
||||
|
||||
if sleep_formspec_doesnt_close_mt53 then
|
||||
minetest.after(0.3, function(obj, damage, impact, punch_dir) -- 0.2 is minimum delay for closing old formspec and open died formspec -- TODO: REMOVE THIS IN THE FUTURE
|
||||
if not obj then return end
|
||||
obj:punch(obj, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir)
|
||||
obj:add_velocity(vector.multiply(punch_dir, impact * 20))
|
||||
end, obj, damage, impact, vector.new(punch_dir))
|
||||
else
|
||||
obj:punch(source, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir)
|
||||
minetest.after(0.3, function() -- 0.2 is minimum delay for closing old formspec and open died formspec -- TODO: REMOVE THIS IN THE FUTURE
|
||||
if not obj:is_player() then
|
||||
return
|
||||
end
|
||||
|
||||
mcl_util.deal_damage(obj, damage, {type = "explosion", direct = direct, source = source})
|
||||
|
||||
if obj:is_player() then
|
||||
obj:add_velocity(vector.multiply(punch_dir, impact * 20))
|
||||
elseif ent.tnt_knockback then
|
||||
end)
|
||||
else
|
||||
mcl_util.deal_damage(obj, damage, {type = "explosion", direct = direct, source = source})
|
||||
|
||||
if obj:is_player() or ent.tnt_knockback then
|
||||
obj:add_velocity(vector.multiply(punch_dir, impact * 20))
|
||||
end
|
||||
end
|
||||
@ -422,7 +421,8 @@ end
|
||||
-- pos - The position where the explosion originates from
|
||||
-- strength - The blast strength of the explosion (a TNT explosion uses 4)
|
||||
-- info - Table containing information about explosion
|
||||
-- puncher - object that is reported as source of punches/damage (optional)
|
||||
-- direct - direct source object of the damage (optional)
|
||||
-- source - indirect source object of the damage (optional)
|
||||
--
|
||||
-- Values in info:
|
||||
-- drop_chance - If specified becomes the drop chance of all nodes in the
|
||||
@ -436,7 +436,7 @@ end
|
||||
-- griefing - If true, the explosion will destroy nodes (default: true)
|
||||
-- grief_protected - If true, the explosion will also destroy nodes which have
|
||||
-- been protected (default: false)
|
||||
function mcl_explosions.explode(pos, strength, info, puncher)
|
||||
function mcl_explosions.explode(pos, strength, info, direct, source)
|
||||
if info == nil then
|
||||
info = {}
|
||||
end
|
||||
@ -465,7 +465,7 @@ function mcl_explosions.explode(pos, strength, info, puncher)
|
||||
info.drop_chance = 0
|
||||
end
|
||||
|
||||
trace_explode(pos, strength, shape, radius, info, puncher)
|
||||
trace_explode(pos, strength, shape, radius, info, direct, source)
|
||||
|
||||
if info.particles then
|
||||
add_particles(pos, radius)
|
||||
|
@ -418,3 +418,99 @@ function mcl_util.get_color(colorstr)
|
||||
return colorstr, hex
|
||||
end
|
||||
end
|
||||
|
||||
function mcl_util.call_on_rightclick(itemstack, player, pointed_thing)
|
||||
-- Call on_rightclick if the pointed node defines it
|
||||
if pointed_thing and pointed_thing.type == "node" then
|
||||
local node = minetest.get_node(pointed_thing.under)
|
||||
if player and not player:get_player_control().sneak then
|
||||
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then
|
||||
return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mcl_util.calculate_durability(itemstack)
|
||||
local unbreaking_level = mcl_enchanting.get_enchantment(itemstack, "unbreaking")
|
||||
local armor_uses = minetest.get_item_group(itemstack:get_name(), "mcl_armor_uses")
|
||||
|
||||
local uses
|
||||
|
||||
if armor_uses > 0 then
|
||||
uses = armor_uses
|
||||
if unbreaking_level > 0 then
|
||||
uses = uses / (0.6 + 0.4 / (unbreaking_level + 1))
|
||||
end
|
||||
else
|
||||
local def = itemstack:get_definition()
|
||||
if def then
|
||||
local fixed_uses = def._mcl_uses
|
||||
if fixed_uses then
|
||||
uses = fixed_uses
|
||||
if unbreaking_level > 0 then
|
||||
uses = uses * (unbreaking_level + 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
if not uses then
|
||||
local toolcaps = itemstack:get_tool_capabilities()
|
||||
local groupcaps = toolcaps.groupcaps
|
||||
for _, v in pairs(groupcaps) do
|
||||
uses = v.uses
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return uses or 0
|
||||
end
|
||||
|
||||
function mcl_util.use_item_durability(itemstack, n)
|
||||
local uses = mcl_util.calculate_durability(itemstack)
|
||||
itemstack:add_wear(65535 / uses * n)
|
||||
end
|
||||
|
||||
function mcl_util.deal_damage(target, damage, mcl_reason)
|
||||
mcl_reason = mcl_reason or {}
|
||||
|
||||
local luaentity = target:get_luaentity()
|
||||
|
||||
if luaentity then
|
||||
if luaentity.deal_damage then
|
||||
luaentity:deal_damage(damage, mcl_reason)
|
||||
return
|
||||
elseif luaentity._cmi_is_mob then
|
||||
local puncher = mcl_reason.direct or target
|
||||
target:punch(puncher, 1.0, {full_punch_interval = 1.0, damage_groups = {fleshy = damage}}, vector.direction(puncher:get_pos(), target:get_pos()), damage)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local mt_reason
|
||||
|
||||
if target:is_player() then
|
||||
mt_reason = {}
|
||||
|
||||
for key, value in pairs(mcl_reason) do
|
||||
mt_reason["_mcl_" .. key] = value
|
||||
end
|
||||
end
|
||||
|
||||
target:set_hp(target:get_hp() - damage, mt_reason)
|
||||
end
|
||||
|
||||
function mcl_util.get_inventory(object, create)
|
||||
if object:is_player() then
|
||||
return object:get_inventory()
|
||||
else
|
||||
local luaentity = object:get_luaentity()
|
||||
local inventory = luaentity.inventory
|
||||
|
||||
if create and not inventory and luaentity.create_inventory then
|
||||
inventory = luaentity:create_inventory()
|
||||
end
|
||||
|
||||
return inventory
|
||||
end
|
||||
end
|
||||
|
@ -92,7 +92,6 @@ function mcl_burning.damage(obj)
|
||||
do_damage = false
|
||||
else
|
||||
local name = obj:get_player_name()
|
||||
armor.last_damage_types[name] = "fire"
|
||||
local deathmsg = S("@1 burned to death.", name)
|
||||
local reason = mcl_burning.get(obj, "string", "reason")
|
||||
if reason ~= "" then
|
||||
@ -107,12 +106,7 @@ function mcl_burning.damage(obj)
|
||||
end
|
||||
|
||||
if do_damage then
|
||||
local new_hp = hp - 1
|
||||
if health then
|
||||
luaentity.health = new_hp
|
||||
else
|
||||
obj:set_hp(new_hp)
|
||||
end
|
||||
mcl_util.deal_damage(obj, 1, {type = "in_fire"})
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -177,7 +177,7 @@ local function object_in_range(self, object)
|
||||
local factor
|
||||
-- Apply view range reduction for special player armor
|
||||
if object:is_player() and mod_armor then
|
||||
factor = armor:get_mob_view_range_factor(object, self.name)
|
||||
factor = mcl_armor.get_mob_view_range_factor(object, self.name)
|
||||
end
|
||||
-- Distance check
|
||||
local dist
|
||||
@ -3906,7 +3906,7 @@ minetest.register_entity(name, {
|
||||
--default built in engine collision detection
|
||||
self.object:set_properties({
|
||||
collide_with_objects = false,
|
||||
})
|
||||
})
|
||||
return mob_activate(self, staticdata, def, dtime)
|
||||
end,
|
||||
|
||||
@ -4367,4 +4367,4 @@ minetest.register_globalstep(function(dtime)
|
||||
end
|
||||
timer = 0
|
||||
end)
|
||||
]]--
|
||||
]]--
|
||||
|
@ -147,12 +147,10 @@ mobs:register_arrow("mobs_mc:blaze_fireball", {
|
||||
visual_size = {x = 0.3, y = 0.3},
|
||||
textures = {"mcl_fire_fire_charge.png"},
|
||||
velocity = 15,
|
||||
_is_fireball = true,
|
||||
|
||||
-- Direct hit, no fire... just plenty of pain
|
||||
hit_player = function(self, player)
|
||||
if rawget(_G, "armor") and armor.last_damage_types then
|
||||
armor.last_damage_types[player:get_player_name()] = "fireball"
|
||||
end
|
||||
mcl_burning.set_on_fire(player, 5, "blaze")
|
||||
player:punch(self.object, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
|
@ -76,18 +76,18 @@ mobs:register_mob("mobs_mc:ghast", {
|
||||
|
||||
|
||||
mobs:spawn_specific(
|
||||
"mobs_mc:ghast",
|
||||
"nether",
|
||||
"mobs_mc:ghast",
|
||||
"nether",
|
||||
"ground",
|
||||
{
|
||||
"Nether"
|
||||
},
|
||||
0,
|
||||
minetest.LIGHT_MAX+1,
|
||||
30,
|
||||
18000,
|
||||
2,
|
||||
mobs_mc.spawn_height.nether_min,
|
||||
0,
|
||||
minetest.LIGHT_MAX+1,
|
||||
30,
|
||||
18000,
|
||||
2,
|
||||
mobs_mc.spawn_height.nether_min,
|
||||
mobs_mc.spawn_height.nether_max)
|
||||
|
||||
-- fireball (projectile)
|
||||
@ -97,11 +97,9 @@ mobs:register_arrow("mobs_mc:fireball", {
|
||||
textures = {"mcl_fire_fire_charge.png"},
|
||||
velocity = 15,
|
||||
collisionbox = {-.5, -.5, -.5, .5, .5, .5},
|
||||
_is_fireball = true,
|
||||
|
||||
hit_player = function(self, player)
|
||||
if rawget(_G, "armor") and armor.last_damage_types then
|
||||
armor.last_damage_types[player:get_player_name()] = "fireball"
|
||||
end
|
||||
player:punch(self.object, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = 6},
|
||||
|
@ -263,34 +263,7 @@ function mcl_experience.add_experience(player, experience)
|
||||
local can = final_candidates[math.random(#final_candidates)]
|
||||
local stack, list, index, wear = can.stack, can.list, can.index, can.wear
|
||||
local unbreaking_level = mcl_enchanting.get_enchantment(stack, "unbreaking")
|
||||
local uses
|
||||
local armor_uses = minetest.get_item_group(stack:get_name(), "mcl_armor_uses")
|
||||
if armor_uses > 0 then
|
||||
uses = armor_uses
|
||||
if unbreaking_level > 0 then
|
||||
uses = uses / (0.6 + 0.4 / (unbreaking_level + 1))
|
||||
end
|
||||
else
|
||||
local def = stack:get_definition()
|
||||
if def then
|
||||
local fixed_uses = def._mcl_uses
|
||||
if fixed_uses then
|
||||
uses = fixed_uses
|
||||
if unbreaking_level > 0 then
|
||||
uses = uses * (unbreaking_level + 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
if not uses then
|
||||
local toolcaps = stack:get_tool_capabilities()
|
||||
local groupcaps = toolcaps.groupcaps
|
||||
for _, v in pairs(groupcaps) do
|
||||
uses = v.uses
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
uses = uses or 0
|
||||
local uses = mcl_util.calculate_durability(itemstack)
|
||||
local multiplier = 2 * 65535 / uses
|
||||
local repair = experience * multiplier
|
||||
local new_wear = wear - repair
|
||||
|
@ -1,9 +1,5 @@
|
||||
local S = minetest.get_translator("mcl_hbarmor")
|
||||
|
||||
if (not armor) or (not armor.def) then
|
||||
minetest.log("error", "[mcl_hbarmor] Outdated mcl_armor version. Please update your version of mcl_armor!")
|
||||
end
|
||||
|
||||
local mcl_hbarmor = {}
|
||||
|
||||
-- HUD statbar values
|
||||
@ -60,11 +56,8 @@ end
|
||||
hb.register_hudbar("armor", 0xFFFFFF, S("Armor"), { icon = "hbarmor_icon.png", bgicon = "hbarmor_bgicon.png", bar = "hbarmor_bar.png" }, 0, 0, 20, mcl_hbarmor.autohide)
|
||||
|
||||
function mcl_hbarmor.get_armor(player)
|
||||
if not player or not armor.def then
|
||||
return false
|
||||
end
|
||||
local name = player:get_player_name()
|
||||
local pts = armor:get_armor_points(player)
|
||||
local pts = player:get_meta():get_int("mcl_armor:armor_points")
|
||||
if not pts then
|
||||
return false
|
||||
else
|
||||
|
@ -7,8 +7,7 @@ local players = {}
|
||||
-- Containing all the items for each Creative Mode tab
|
||||
local inventory_lists = {}
|
||||
|
||||
local show_armor = minetest.get_modpath("mcl_armor") ~= nil
|
||||
local mod_player = minetest.get_modpath("mcl_player") ~= nil
|
||||
+local mod_player = minetest.get_modpath("mcl_player") ~= nil
|
||||
|
||||
-- Create tables
|
||||
local builtin_filter_ids = {"blocks","deco","redstone","rail","food","tools","combat","mobs","brew","matr","misc","all"}
|
||||
@ -334,23 +333,7 @@ mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_siz
|
||||
if minetest.settings:get_bool("3d_player_preview", true) then
|
||||
player_preview = mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "")
|
||||
else
|
||||
local img, img_player
|
||||
if mod_player then
|
||||
img_player = mcl_player.player_get_preview(player)
|
||||
else
|
||||
img_player = "player.png"
|
||||
end
|
||||
img = img_player
|
||||
player_preview = "image[3.9,1.4;1.2333,2.4666;"..img.."]"
|
||||
if show_armor and armor.textures[playername] and armor.textures[playername].preview then
|
||||
img = armor.textures[playername].preview
|
||||
local s1 = img:find("character_preview")
|
||||
if s1 ~= nil then
|
||||
s1 = img:sub(s1+21)
|
||||
img = img_player..s1
|
||||
end
|
||||
player_preview = "image[3.9,1.4;1.2333,2.4666;"..img.."]"
|
||||
end
|
||||
player_preview = "image[3.9,1.4;1.2333,2.4666;"..mcl_player.player_get_preview(player).."]"
|
||||
end
|
||||
|
||||
-- Background images for armor slots (hide if occupied)
|
||||
@ -373,10 +356,10 @@ mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_siz
|
||||
main_list = "list[current_player;main;0,3.75;9,3;9]"..
|
||||
mcl_formspec.get_itemslot_bg(0,3.75,9,3)..
|
||||
-- armor
|
||||
"list[detached:"..playername.."_armor;armor;2.5,1.3;1,1;1]"..
|
||||
"list[detached:"..playername.."_armor;armor;2.5,2.75;1,1;2]"..
|
||||
"list[detached:"..playername.."_armor;armor;5.5,1.3;1,1;3]"..
|
||||
"list[detached:"..playername.."_armor;armor;5.5,2.75;1,1;4]"..
|
||||
"list[current_player;armor;2.5,1.3;1,1;1]"..
|
||||
"list[current_player;armor;2.5,2.75;1,1;2]"..
|
||||
"list[current_player;armor;5.5,1.3;1,1;3]"..
|
||||
"list[current_player;armor;5.5,2.75;1,1;4]"..
|
||||
mcl_formspec.get_itemslot_bg(2.5,1.3,1,1)..
|
||||
mcl_formspec.get_itemslot_bg(2.5,2.75,1,1)..
|
||||
mcl_formspec.get_itemslot_bg(5.5,1.3,1,1)..
|
||||
|
@ -3,7 +3,6 @@ local F = minetest.formspec_escape
|
||||
|
||||
mcl_inventory = {}
|
||||
|
||||
local show_armor = minetest.get_modpath("mcl_armor") ~= nil
|
||||
local mod_player = minetest.get_modpath("mcl_player") ~= nil
|
||||
local mod_craftguide = minetest.get_modpath("mcl_craftguide") ~= nil
|
||||
|
||||
@ -68,23 +67,7 @@ local function set_inventory(player, armor_change_only)
|
||||
if minetest.settings:get_bool("3d_player_preview", true) then
|
||||
player_preview = mcl_player.get_player_formspec_model(player, 1.0, 0.0, 2.25, 4.5, "")
|
||||
else
|
||||
local img, img_player
|
||||
if mod_player then
|
||||
img_player = mcl_player.player_get_preview(player)
|
||||
else
|
||||
img_player = "player.png"
|
||||
end
|
||||
img = img_player
|
||||
player_preview = "image[0.6,0.2;2,4;"..img.."]"
|
||||
if show_armor and armor.textures[player_name] and armor.textures[player_name].preview then
|
||||
img = armor.textures[player_name].preview
|
||||
local s1 = img:find("character_preview")
|
||||
if s1 ~= nil then
|
||||
s1 = img:sub(s1+21)
|
||||
img = img_player..s1
|
||||
end
|
||||
player_preview = "image[1.1,0.2;2,4;"..img.."]"
|
||||
end
|
||||
player_preview = "image[1.1,0.2;2,4;"..mcl_player.player_get_preview(player).."]"
|
||||
end
|
||||
|
||||
local armor_slots = {"helmet", "chestplate", "leggings", "boots"}
|
||||
@ -99,10 +82,10 @@ local function set_inventory(player, armor_change_only)
|
||||
"background[-0.19,-0.25;9.41,9.49;crafting_formspec_bg.png]"..
|
||||
player_preview..
|
||||
--armor
|
||||
"list[detached:"..player_name.."_armor;armor;0,0;1,1;1]"..
|
||||
"list[detached:"..player_name.."_armor;armor;0,1;1,1;2]"..
|
||||
"list[detached:"..player_name.."_armor;armor;0,2;1,1;3]"..
|
||||
"list[detached:"..player_name.."_armor;armor;0,3;1,1;4]"..
|
||||
"list[current_player;armor;0,0;1,1;1]"..
|
||||
"list[current_player;armor;0,1;1,1;2]"..
|
||||
"list[current_player;armor;0,2;1,1;3]"..
|
||||
"list[current_player;armor;0,3;1,1;4]"..
|
||||
mcl_formspec.get_itemslot_bg(0,0,1,1)..
|
||||
mcl_formspec.get_itemslot_bg(0,1,1,1)..
|
||||
mcl_formspec.get_itemslot_bg(0,2,1,1)..
|
||||
@ -133,10 +116,10 @@ local function set_inventory(player, armor_change_only)
|
||||
"tooltip[__mcl_achievements;"..F(S("Achievements")).."]"..
|
||||
-- for shortcuts
|
||||
"listring[current_player;main]"..
|
||||
"listring[current_player;craft]"..
|
||||
"listring[current_player;main]"..
|
||||
"listring[detached:"..player_name.."_armor;armor]"
|
||||
|
||||
"listring[current_player;armor]"..
|
||||
"listring[current_player;main]" ..
|
||||
"listring[current_player;craft]" ..
|
||||
"listring[current_player;main]"
|
||||
player:set_inventory_formspec(form)
|
||||
end
|
||||
|
||||
@ -176,18 +159,10 @@ minetest.register_on_joinplayer(function(player)
|
||||
player:hud_set_hotbar_image("mcl_inventory_hotbar.png")
|
||||
player:hud_set_hotbar_selected_image("mcl_inventory_hotbar_selected.png")
|
||||
|
||||
if show_armor then
|
||||
local set_player_armor_original = armor.set_player_armor
|
||||
local update_inventory_original = armor.update_inventory
|
||||
armor.set_player_armor = function(self, player)
|
||||
set_player_armor_original(self, player)
|
||||
end
|
||||
armor.update_inventory = function(self, player)
|
||||
update_inventory_original(self, player)
|
||||
set_inventory(player, true)
|
||||
end
|
||||
armor:set_player_armor(player)
|
||||
armor:update_inventory(player)
|
||||
local old_update_player = mcl_armor.update_player
|
||||
mcl_armor.update_player = function(player, info)
|
||||
old_update_player(player, info)
|
||||
set_inventory(player, true)
|
||||
end
|
||||
|
||||
-- In Creative Mode, the initial inventory setup is handled in creative.lua
|
||||
|
@ -170,7 +170,7 @@ local dispenserdef = {
|
||||
minetest.registered_nodes["mcl_armor_stand:armor_stand"].on_metadata_inventory_put(standpos)
|
||||
stack:take_item()
|
||||
inv:set_stack("main", stack_id, stack)
|
||||
armor:play_equip_sound(dropitem, nil, standpos)
|
||||
mcl_armor.play_equip_sound(dropitem, nil, standpos)
|
||||
armor_dispensed = true
|
||||
end
|
||||
else
|
||||
@ -202,9 +202,8 @@ local dispenserdef = {
|
||||
if ainv:get_stack("armor", armor_slot):is_empty() and pinv:get_stack("armor", armor_slot):is_empty() then
|
||||
ainv:set_stack("armor", armor_slot, dropitem)
|
||||
pinv:set_stack("armor", armor_slot, dropitem)
|
||||
armor:set_player_armor(player)
|
||||
armor:update_inventory(player)
|
||||
armor:play_equip_sound(dropitem, player)
|
||||
mcl_armor.update(player)
|
||||
mcl_armor.play_equip_sound(dropitem, player)
|
||||
|
||||
stack:take_item()
|
||||
inv:set_stack("main", stack_id, stack)
|
||||
|
232
mods/ITEMS/mcl_armor/api.lua
Normal file
232
mods/ITEMS/mcl_armor/api.lua
Normal file
@ -0,0 +1,232 @@
|
||||
function mcl_armor.play_equip_sound(stack, obj, pos, unequip)
|
||||
local def = stack:get_definition()
|
||||
local estr = "equip"
|
||||
if unequip then
|
||||
estr = "unequip"
|
||||
end
|
||||
local snd = def.sounds and def.sounds["_mcl_armor_" .. estr]
|
||||
if not snd then
|
||||
-- Fallback sound
|
||||
snd = { name = "mcl_armor_" .. estr .. "_generic" }
|
||||
end
|
||||
if snd then
|
||||
local dist = 8
|
||||
if pos then
|
||||
dist = 16
|
||||
end
|
||||
minetest.sound_play(snd, {object = obj, pos = pos, gain = 0.5, max_hear_distance = dist}, true)
|
||||
end
|
||||
end
|
||||
|
||||
function mcl_armor.equip(itemstack, obj)
|
||||
local def = itemstack:get_definition()
|
||||
local element = mcl_armor.elements[def._mcl_armor_element or ""]
|
||||
local inv = mcl_util.get_inventory(obj)
|
||||
|
||||
if element and inv then
|
||||
if inv:get_stack("armor", element.index):is_empty() then
|
||||
local equipping_item = itemstack:take_item()
|
||||
inv:set_stack("armor", element.index, equipping_item)
|
||||
if def._on_equip then
|
||||
def._on_equip(equipping_item)
|
||||
end
|
||||
mcl_armor.update(obj)
|
||||
end
|
||||
end
|
||||
|
||||
return itemstack
|
||||
end
|
||||
|
||||
function mcl_armor.equip_on_use(itemstack, player, pointed_thing)
|
||||
if not player or not player:is_player() then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local new_stack = mcl_util.call_on_rightclick(itemstack, player, pointed_thing)
|
||||
if new_stack then
|
||||
return new_stack
|
||||
end
|
||||
|
||||
return mcl_armor.equip(itemstack, player)
|
||||
end
|
||||
|
||||
function mcl_armor.register_set(def)
|
||||
local modname = minetest.get_current_modname()
|
||||
local S = minetest.get_translator(modname)
|
||||
local descriptions = def.descriptions or {}
|
||||
local groups = def.groups or {}
|
||||
for name, element in pairs(mcl_armor.elements) do
|
||||
local itemname = element.name .. "_" .. def.name
|
||||
local itemstring = modname .. ":" .. itemname
|
||||
|
||||
local groups = table.copy(groups)
|
||||
groups["armor_" .. name] = 1
|
||||
groups["combat_armor_" .. name] = 1
|
||||
groups.armor = 1
|
||||
groups.combat_armor = 1
|
||||
groups.mcl_armor_points = def.points[name]
|
||||
groups.mcl_armor_toughness = def.toughness
|
||||
groups.mcl_armor_uses = math.floor(def.durability * element.durability) + 1
|
||||
groups.enchantability = def.enchantability
|
||||
|
||||
minetest.register_tool(itemstring, {
|
||||
description = S(def.description .. " " .. (descriptions[name] or element.description)),
|
||||
_doc_items_longdesc = mcl_armor.longdesc,
|
||||
_doc_items_usagehelp = mcl_armor.usage,
|
||||
inventory_image = modname .. "_inv_" .. itemname .. ".png",
|
||||
_repair_material = def.repair_material or def.craft_material,
|
||||
groups = groups,
|
||||
sounds = {
|
||||
_mcl_armor_equip = def.sound_equip or modname .. "_equip_" .. def.name,
|
||||
_mcl_armor_unequip = def.sound_unequip or modname .. "_unequip_" .. def.name,
|
||||
},
|
||||
on_place = mcl_armor.equip_on_use,
|
||||
on_secondary_use = mcl_armor.equip_on_use,
|
||||
_on_equip = def.on_equip,
|
||||
_on_unequip = def.on_unequip,
|
||||
_mcl_armor_element = name,
|
||||
_mcl_armor_texture = modname .. "_" .. itemname .. ".png",
|
||||
_mcl_armor_preview = modname .. "_" .. itemname .. "_preview.png",
|
||||
})
|
||||
|
||||
if def.craft_material then
|
||||
minetest.register_craft({
|
||||
output = itemstring,
|
||||
recipe = element.craft(def.craft_material),
|
||||
})
|
||||
end
|
||||
|
||||
if def.cook_material then
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = def.cook_material,
|
||||
recipe = itemstring,
|
||||
cooktime = 10,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mcl_armor.protection_enchantments = {
|
||||
flags = {},
|
||||
types = {},
|
||||
wildcard = {},
|
||||
}
|
||||
|
||||
function mcl_armor.register_protection_enchantment(def)
|
||||
local prot_def = {id = def.id, factor = def.factor}
|
||||
if def.damage_flag then
|
||||
local tbl = mcl_armor.protection_enchantments.flags[def.damage_flag] or {}
|
||||
table.insert(tbl, prot_def)
|
||||
mcl_armor.protection_enchantments.flags = tbl
|
||||
elseif def.damage_type then
|
||||
local tbl = mcl_armor.protection_enchantments.types[def.damage_type] or {}
|
||||
table.insert(tbl, prot_def)
|
||||
mcl_armor.protection_enchantments.types = tbl
|
||||
else
|
||||
table.insert(mcl_armor.protection_enchantments.wildcard, prot_def)
|
||||
end
|
||||
mcl_enchanting.enchantments[def.id] = {
|
||||
name = def.name,
|
||||
max_level = def.max_level or 4,
|
||||
primary = def.primary or {combat_armor = true},
|
||||
secondary = {},
|
||||
disallow = {},
|
||||
incompatible = def.incompatible or {},
|
||||
weight = def.weight or 5,
|
||||
description = def.description,
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = def.treasure or false,
|
||||
power_range_table = def.power_range_table,
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
end
|
||||
|
||||
function mcl_armor.get_armor_points(obj)
|
||||
local points = 0
|
||||
local inv = mcl_util.get_inventory(obj)
|
||||
if inv then
|
||||
for i = 2, 5 do
|
||||
local itemstack = inv:get_stack("armor", i)
|
||||
if not itemstack:is_empty() then
|
||||
points = points + minetest.get_item_group(itemstack:get_name(), "mcl_armor_points")
|
||||
end
|
||||
end
|
||||
end
|
||||
return points
|
||||
end
|
||||
|
||||
-- Returns a change factor for a mob's view_range for the given object
|
||||
-- or nil, if there's no change. Certain armors (like mob heads) can
|
||||
-- affect the view range of mobs.
|
||||
function mcl_armor.get_mob_view_range_factor(obj, mob)
|
||||
local inv = mcl_util.get_inventory(obj)
|
||||
local factor
|
||||
if inv then
|
||||
for i = 2, 5 do
|
||||
local itemstack = inv:get_stack("armor", i)
|
||||
if not itemstack:is_empty() then
|
||||
local def = itemstack:get_definition()
|
||||
if def._mcl_armor_mob_range_mob == mob then
|
||||
if not factor then
|
||||
factor = def._mcl_armor_mob_range_factor
|
||||
elseif factor == 0 then
|
||||
return 0
|
||||
else
|
||||
factor = factor * def._mcl_armor_mob_range_factor
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return factor
|
||||
end
|
||||
|
||||
function mcl_armor.update(obj)
|
||||
local info = {points = 0}
|
||||
|
||||
local inv = mcl_util.get_inventory(obj)
|
||||
|
||||
if inv then
|
||||
for i = 2, 5 do
|
||||
local itemstack = inv:get_stack("armor", i)
|
||||
|
||||
local itemname = itemstack:get_name()
|
||||
if minetest.registered_aliases[itemname] then
|
||||
itemname = minetest.registered_aliases[itemname]
|
||||
end
|
||||
|
||||
if not itemstack:is_empty() then
|
||||
local def = itemstack:get_definition()
|
||||
|
||||
if def._mcl_armor_texture then
|
||||
info.texture = "(" .. def._mcl_armor_texture .. ")" .. (info.texture and "^" .. info.texture or "")
|
||||
end
|
||||
|
||||
if obj:is_player() and def._mcl_armor_preview then
|
||||
info.preview = "(player.png^[opacity:0^" .. def._mcl_armor_preview .. ")" .. (info.preview and "^" .. info.preview or "" )
|
||||
end
|
||||
|
||||
info.points = info.points + minetest.get_item_group(itemname, "mcl_armor_points")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
info.texture = info.texture or "blank.png"
|
||||
|
||||
if obj:is_player() then
|
||||
info.preview = info.preview or "blank.png"
|
||||
|
||||
mcl_armor.update_player(obj, info)
|
||||
else
|
||||
local luaentity = obj:get_luaentity()
|
||||
|
||||
if luaentity.update_armor then
|
||||
luaentity:update_armor(info)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,675 +0,0 @@
|
||||
local ARMOR_INIT_DELAY = 1
|
||||
local ARMOR_INIT_TIMES = 1
|
||||
local ARMOR_BONES_DELAY = 1
|
||||
|
||||
local skin_mod = nil
|
||||
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
armor = {
|
||||
timer = 0,
|
||||
elements = {"head", "torso", "legs", "feet"},
|
||||
physics = {"jump","speed","gravity"},
|
||||
formspec = "size[8,8.5]image[2,0.75;2,4;armor_preview]"
|
||||
.."list[current_player;main;0,4.5;8,4;]"
|
||||
.."list[current_player;craft;4,1;3,3;]"
|
||||
.."list[current_player;craftpreview;7,2;1,1;]"
|
||||
.."listring[current_player;main]"
|
||||
.."listring[current_player;craft]",
|
||||
textures = {},
|
||||
default_skin = "character",
|
||||
last_damage_types = {},
|
||||
}
|
||||
|
||||
if minetest.get_modpath("mcl_skins") then
|
||||
skin_mod = "mcl_skins"
|
||||
elseif minetest.get_modpath("skins") then
|
||||
skin_mod = "skins"
|
||||
elseif minetest.get_modpath("simple_skins") then
|
||||
skin_mod = "simple_skins"
|
||||
elseif minetest.get_modpath("u_skins") then
|
||||
skin_mod = "u_skins"
|
||||
elseif minetest.get_modpath("wardrobe") then
|
||||
skin_mod = "wardrobe"
|
||||
end
|
||||
|
||||
function armor.on_armor_use(itemstack, user, pointed_thing)
|
||||
if not user or user:is_player() == false then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
-- Call on_rightclick if the pointed node defines it
|
||||
if pointed_thing.type == "node" then
|
||||
local node = minetest.get_node(pointed_thing.under)
|
||||
if user and not user:get_player_control().sneak then
|
||||
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then
|
||||
return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local name, player_inv, armor_inv = armor:get_valid_player(user, "[on_armor_use]")
|
||||
if not name then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local def = itemstack:get_definition()
|
||||
local slot
|
||||
if def.groups and def.groups.armor_head then
|
||||
slot = 2
|
||||
elseif def.groups and def.groups.armor_torso then
|
||||
slot = 3
|
||||
elseif def.groups and def.groups.armor_legs then
|
||||
slot = 4
|
||||
elseif def.groups and def.groups.armor_feet then
|
||||
slot = 5
|
||||
end
|
||||
|
||||
if slot then
|
||||
local itemstack_single = ItemStack(itemstack)
|
||||
itemstack_single:set_count(1)
|
||||
local itemstack_slot = armor_inv:get_stack("armor", slot)
|
||||
if itemstack_slot:is_empty() then
|
||||
armor_inv:set_stack("armor", slot, itemstack_single)
|
||||
player_inv:set_stack("armor", slot, itemstack_single)
|
||||
armor:set_player_armor(user)
|
||||
armor:update_inventory(user)
|
||||
armor:play_equip_sound(itemstack_single, user)
|
||||
itemstack:take_item()
|
||||
elseif itemstack:get_count() <= 1 and not mcl_enchanting.has_enchantment(itemstack_slot, "curse_of_binding") then
|
||||
armor_inv:set_stack("armor", slot, itemstack_single)
|
||||
player_inv:set_stack("armor", slot, itemstack_single)
|
||||
armor:set_player_armor(user)
|
||||
armor:update_inventory(user)
|
||||
armor:play_equip_sound(itemstack_single, user)
|
||||
itemstack = ItemStack(itemstack_slot)
|
||||
end
|
||||
end
|
||||
|
||||
return itemstack
|
||||
end
|
||||
|
||||
armor.def = {
|
||||
count = 0,
|
||||
}
|
||||
|
||||
armor.update_player_visuals = function(self, player)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
|
||||
local wielditem = player:get_wielded_item()
|
||||
local def = wielditem:get_definition()
|
||||
if def and def._mcl_toollike_wield then
|
||||
player:set_bone_position("Wield_Item", vector.new(0,3.9,1.3), vector.new(90,0,0))
|
||||
elseif string.find(wielditem:get_name(), "mcl_bows:bow") then
|
||||
player:set_bone_position("Wield_Item", vector.new(.5,4.5,-1.6), vector.new(90,0,20))
|
||||
else
|
||||
player:set_bone_position("Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(135,0,90))
|
||||
end
|
||||
|
||||
local name = player:get_player_name()
|
||||
if self.textures[name] then
|
||||
mcl_player.player_set_textures(player, {
|
||||
self.textures[name].skin,
|
||||
self.textures[name].armor,
|
||||
self.textures[name].wielditem,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
armor.set_player_armor = function(self, player)
|
||||
local name, player_inv = armor:get_valid_player(player, "[set_player_armor]")
|
||||
if not name then
|
||||
return
|
||||
end
|
||||
local armor_texture = "blank.png"
|
||||
local armor_level = 0
|
||||
local mcl_armor_points = 0
|
||||
local items = 0
|
||||
local elements = {}
|
||||
local textures = {}
|
||||
local physics_o = {speed=1,gravity=1,jump=1}
|
||||
local material = {type=nil, count=1}
|
||||
local preview
|
||||
for _,v in ipairs(self.elements) do
|
||||
elements[v] = false
|
||||
end
|
||||
for i=1, 6 do
|
||||
local stack = player_inv:get_stack("armor", i)
|
||||
local item = stack:get_name()
|
||||
if minetest.registered_aliases[item] then
|
||||
item = minetest.registered_aliases[item]
|
||||
end
|
||||
if stack:get_count() == 1 then
|
||||
local def = stack:get_definition()
|
||||
for k, v in pairs(elements) do
|
||||
if v == false then
|
||||
local level = def.groups["armor_"..k]
|
||||
if level then
|
||||
local texture = def.texture or item:gsub("%:", "_")
|
||||
local enchanted_addition = (mcl_enchanting.is_enchanted(item) and mcl_enchanting.overlay or "")
|
||||
table.insert(textures, "("..texture..".png"..enchanted_addition..")")
|
||||
preview = "(player.png^[opacity:0^"..texture.."_preview.png"..enchanted_addition..")"..(preview and "^"..preview or "")
|
||||
armor_level = armor_level + level
|
||||
items = items + 1
|
||||
mcl_armor_points = mcl_armor_points + (def.groups["mcl_armor_points"] or 0)
|
||||
for kk,vv in ipairs(self.physics) do
|
||||
local o_value = def.groups["physics_"..vv]
|
||||
if o_value then
|
||||
physics_o[vv] = physics_o[vv] + o_value
|
||||
end
|
||||
end
|
||||
local mat = string.match(item, "%:.+_(.+)$")
|
||||
if material.type then
|
||||
if material.type == mat then
|
||||
material.count = material.count + 1
|
||||
end
|
||||
else
|
||||
material.type = mat
|
||||
end
|
||||
elements[k] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
preview = (armor:get_preview(name) or "character_preview.png")..(preview and "^"..preview or "")
|
||||
if minetest.get_modpath("shields") then
|
||||
armor_level = armor_level * 0.9
|
||||
end
|
||||
if material.type and material.count == #self.elements then
|
||||
armor_level = armor_level * 1.1
|
||||
end
|
||||
if #textures > 0 then
|
||||
armor_texture = table.concat(textures, "^")
|
||||
end
|
||||
local armor_groups = player:get_armor_groups()
|
||||
armor_groups.fleshy = 100
|
||||
armor_groups.level = nil
|
||||
if armor_level > 0 then
|
||||
armor_groups.level = math.floor(armor_level / 20)
|
||||
armor_groups.fleshy = 100 - armor_level
|
||||
end
|
||||
player:set_armor_groups(armor_groups)
|
||||
-- Physics override intentionally removed because of possible conflicts
|
||||
self.textures[name].armor = armor_texture
|
||||
self.textures[name].preview = preview
|
||||
self.def[name].count = items
|
||||
self.def[name].level = armor_level
|
||||
self.def[name].heal = mcl_armor_points
|
||||
self.def[name].jump = physics_o.jump
|
||||
self.def[name].speed = physics_o.speed
|
||||
self.def[name].gravity = physics_o.gravity
|
||||
self:update_player_visuals(player)
|
||||
end
|
||||
|
||||
armor.update_armor = function(self, player)
|
||||
-- Legacy support: Called when armor levels are changed
|
||||
-- Other mods can hook on to this function, see hud mod for example
|
||||
end
|
||||
|
||||
armor.get_armor_points = function(self, player)
|
||||
local name, player_inv, armor_inv = armor:get_valid_player(player, "[get_armor_points]")
|
||||
if not name then
|
||||
return nil
|
||||
end
|
||||
local pts = 0
|
||||
for i=1, 6 do
|
||||
local stack = player_inv:get_stack("armor", i)
|
||||
if stack:get_count() > 0 then
|
||||
local p = minetest.get_item_group(stack:get_name(), "mcl_armor_points")
|
||||
if p then
|
||||
pts = pts + p
|
||||
end
|
||||
end
|
||||
end
|
||||
return pts
|
||||
end
|
||||
|
||||
-- Returns a change factor for a mob's view_range for the given player
|
||||
-- or nil, if there's no change. Certain armors (like mob heads) can
|
||||
-- affect the view range of mobs.
|
||||
armor.get_mob_view_range_factor = function(self, player, mob)
|
||||
local name, player_inv, armor_inv = armor:get_valid_player(player, "[get_mob_view_range_factor]")
|
||||
if not name then
|
||||
return
|
||||
end
|
||||
local factor
|
||||
for i=1, 6 do
|
||||
local stack = player_inv:get_stack("armor", i)
|
||||
if stack:get_count() > 0 then
|
||||
local def = stack:get_definition()
|
||||
if def._mcl_armor_mob_range_mob == mob then
|
||||
if not factor then
|
||||
factor = def._mcl_armor_mob_range_factor
|
||||
elseif factor == 0 then
|
||||
return 0
|
||||
else
|
||||
factor = factor * def._mcl_armor_mob_range_factor
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return factor
|
||||
end
|
||||
|
||||
armor.get_player_skin = function(self, name)
|
||||
local skin = nil
|
||||
if skin_mod == "mcl_skins" then
|
||||
skin = mcl_skins.skins[name]
|
||||
elseif 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
|
||||
skin = string.gsub(wardrobe.playerSkins[name], "%.png$","")
|
||||
end
|
||||
return skin or armor.default_skin
|
||||
end
|
||||
|
||||
armor.get_preview = function(self, name)
|
||||
if skin_mod == "skins" then
|
||||
return armor:get_player_skin(name).."_preview.png"
|
||||
end
|
||||
end
|
||||
|
||||
armor.get_armor_formspec = function(self, name)
|
||||
if not armor.textures[name] then
|
||||
minetest.log("error", "mcl_armor: Player texture["..name.."] is nil [get_armor_formspec]")
|
||||
return ""
|
||||
end
|
||||
if not armor.def[name] then
|
||||
minetest.log("error", "mcl_armor: Armor def["..name.."] is nil [get_armor_formspec]")
|
||||
return ""
|
||||
end
|
||||
local formspec = armor.formspec.."list[detached:"..name.."_armor;armor;0,1;2,3;]"
|
||||
formspec = formspec:gsub("armor_preview", armor.textures[name].preview)
|
||||
formspec = formspec:gsub("armor_level", armor.def[name].level)
|
||||
formspec = formspec:gsub("mcl_armor_points", armor.def[name].heal)
|
||||
return formspec
|
||||
end
|
||||
|
||||
armor.update_inventory = function(self, player)
|
||||
end
|
||||
|
||||
armor.get_valid_player = function(self, player, msg)
|
||||
msg = msg or ""
|
||||
if not player then
|
||||
minetest.log("error", "mcl_armor: Player reference is nil "..msg)
|
||||
return
|
||||
end
|
||||
local name = player:get_player_name()
|
||||
if not name then
|
||||
minetest.log("error", "mcl_armor: Player name is nil "..msg)
|
||||
return
|
||||
end
|
||||
local pos = player:get_pos()
|
||||
local player_inv = player:get_inventory()
|
||||
local armor_inv = minetest.get_inventory({type="detached", name=name.."_armor"})
|
||||
if not pos then
|
||||
minetest.log("error", "mcl_armor: Player position is nil "..msg)
|
||||
return
|
||||
elseif not player_inv then
|
||||
minetest.log("error", "mcl_armor: Player inventory is nil "..msg)
|
||||
return
|
||||
elseif not armor_inv then
|
||||
minetest.log("error", "mcl_armor: Detached armor inventory is nil "..msg)
|
||||
return
|
||||
end
|
||||
return name, player_inv, armor_inv, pos
|
||||
end
|
||||
|
||||
armor.play_equip_sound = function(self, stack, player, pos, unequip)
|
||||
local def = stack:get_definition()
|
||||
local estr = "equip"
|
||||
if unequip then
|
||||
estr = "unequip"
|
||||
end
|
||||
local snd = def.sounds and def.sounds["_mcl_armor_"..estr]
|
||||
if not snd then
|
||||
-- Fallback sound
|
||||
snd = { name = "mcl_armor_"..estr.."_generic" }
|
||||
end
|
||||
if snd then
|
||||
local dist = 8
|
||||
if pos then
|
||||
dist = 16
|
||||
end
|
||||
minetest.sound_play(snd, {object=player, pos=pos, gain=0.5, max_hear_distance=dist}, true)
|
||||
end
|
||||
end
|
||||
|
||||
-- Register Player Model
|
||||
|
||||
mcl_player.player_register_model("mcl_armor_character.b3d", {
|
||||
animation_speed = 30,
|
||||
textures = {
|
||||
armor.default_skin..".png",
|
||||
"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},
|
||||
sneak_stand = {x=222, y=302},
|
||||
sneak_mine = {x=346, y=365},
|
||||
sneak_walk = {x=304, y=323},
|
||||
sneak_walk_mine = {x=325, y=344},
|
||||
swim_walk = {x=368, y=387},
|
||||
swim_walk_mine = {x=389, y=408},
|
||||
swim_stand = {x=434, y=434},
|
||||
swim_mine = {x=411, y=430},
|
||||
run_walk = {x=440, y=459},
|
||||
run_walk_mine = {x=461, y=480},
|
||||
sit_mount = {x=484, y=484},
|
||||
die = {x=498, y=498},
|
||||
fly = {x=502, y=581},
|
||||
},
|
||||
})
|
||||
|
||||
mcl_player.player_register_model("mcl_armor_character_female.b3d", {
|
||||
animation_speed = 30,
|
||||
textures = {
|
||||
armor.default_skin..".png",
|
||||
"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},
|
||||
sneak_stand = {x=222, y=302},
|
||||
sneak_mine = {x=346, y=365},
|
||||
sneak_walk = {x=304, y=323},
|
||||
sneak_walk_mine = {x=325, y=344},
|
||||
swim_walk = {x=368, y=387},
|
||||
swim_walk_mine = {x=389, y=408},
|
||||
swim_stand = {x=434, y=434},
|
||||
swim_mine = {x=411, y=430},
|
||||
run_walk = {x=440, y=459},
|
||||
run_walk_mine = {x=461, y=480},
|
||||
sit_mount = {x=484, y=484},
|
||||
die = {x=498, y=498},
|
||||
fly = {x=502, y=581},
|
||||
},
|
||||
})
|
||||
|
||||
-- Register Callbacks
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
local name = armor:get_valid_player(player, "[on_player_receive_fields]")
|
||||
if not name then
|
||||
return
|
||||
end
|
||||
if fields.armor then
|
||||
return
|
||||
end
|
||||
for field, _ in pairs(fields) do
|
||||
if string.find(field, "skins_set") then
|
||||
minetest.after(0, function(name)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
local skin = armor:get_player_skin(name)
|
||||
armor.textures[name].skin = skin..".png"
|
||||
armor:set_player_armor(player)
|
||||
end, player:get_player_name())
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
mcl_player.player_set_model(player, "mcl_armor_character.b3d")
|
||||
local name = player:get_player_name()
|
||||
local player_inv = player:get_inventory()
|
||||
local armor_inv = minetest.create_detached_inventory(name.."_armor", {
|
||||
on_put = function(inv, listname, index, stack, player)
|
||||
player:get_inventory():set_stack(listname, index, stack)
|
||||
armor:set_player_armor(player)
|
||||
armor:update_inventory(player)
|
||||
armor:play_equip_sound(stack, player)
|
||||
end,
|
||||
on_take = function(inv, listname, index, stack, player)
|
||||
player:get_inventory():set_stack(listname, index, nil)
|
||||
armor:set_player_armor(player)
|
||||
armor:update_inventory(player)
|
||||
armor:play_equip_sound(stack, player, nil, true)
|
||||
end,
|
||||
on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
|
||||
local plaver_inv = player:get_inventory()
|
||||
local stack = inv:get_stack(to_list, to_index)
|
||||
player_inv:set_stack(to_list, to_index, stack)
|
||||
player_inv:set_stack(from_list, from_index, nil)
|
||||
armor:set_player_armor(player)
|
||||
armor:update_inventory(player)
|
||||
armor:play_equip_sound(stack, player)
|
||||
end,
|
||||
allow_put = function(inv, listname, index, stack, player)
|
||||
local iname = stack:get_name()
|
||||
local g
|
||||
local groupcheck
|
||||
if index == 2 then
|
||||
g = minetest.get_item_group(iname, "armor_head")
|
||||
elseif index == 3 then
|
||||
g = minetest.get_item_group(iname, "armor_torso")
|
||||
elseif index == 4 then
|
||||
g = minetest.get_item_group(iname, "armor_legs")
|
||||
elseif index == 5 then
|
||||
g = minetest.get_item_group(iname, "armor_feet")
|
||||
end
|
||||
-- Minor FIXME: If player attempts to place stack into occupied slot, this is rejected.
|
||||
-- It would be better if 1 item is placed in exchanged for the item in the slot.
|
||||
if g ~= 0 and g ~= nil and (inv:get_stack(listname, index):is_empty() or (inv:get_stack(listname, index):get_name() ~= stack:get_name()) and stack:get_count() <= 1) then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end,
|
||||
allow_take = function(inv, listname, index, stack, player)
|
||||
if mcl_enchanting.has_enchantment(stack, "curse_of_binding") and not minetest.settings:get_bool("creative") then
|
||||
return 0
|
||||
end
|
||||
return stack:get_count()
|
||||
end,
|
||||
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
|
||||
return 0
|
||||
end,
|
||||
}, name)
|
||||
armor_inv:set_size("armor", 6)
|
||||
player_inv:set_size("armor", 6)
|
||||
for i=1, 6 do
|
||||
local stack = player_inv:get_stack("armor", i)
|
||||
armor_inv:set_stack("armor", i, stack)
|
||||
end
|
||||
armor.def[name] = {
|
||||
count = 0,
|
||||
level = 0,
|
||||
heal = 0,
|
||||
jump = 1,
|
||||
speed = 1,
|
||||
gravity = 1,
|
||||
}
|
||||
armor.textures[name] = {
|
||||
skin = armor.default_skin..".png",
|
||||
armor = "blank.png",
|
||||
wielditem = "blank.png",
|
||||
preview = armor.default_skin.."_preview.png",
|
||||
}
|
||||
if skin_mod == "mcl_skins" then
|
||||
local skin = mcl_skins.skins[name]
|
||||
if skin then
|
||||
armor.textures[name].skin = skin..".png"
|
||||
end
|
||||
elseif skin_mod == "skins" then
|
||||
local skin = skins.skins[name]
|
||||
if skin and skins.get_type(skin) == skins.type.MODEL then
|
||||
armor.textures[name].skin = skin..".png"
|
||||
end
|
||||
elseif skin_mod == "simple_skins" then
|
||||
local skin = skins.skins[name]
|
||||
if skin then
|
||||
armor.textures[name].skin = skin..".png"
|
||||
end
|
||||
elseif skin_mod == "u_skins" then
|
||||
local skin = u_skins.u_skins[name]
|
||||
if skin and u_skins.get_type(skin) == u_skins.type.MODEL then
|
||||
armor.textures[name].skin = skin..".png"
|
||||
end
|
||||
elseif skin_mod == "wardrobe" then
|
||||
local skin = wardrobe.playerSkins[name]
|
||||
if skin then
|
||||
armor.textures[name].skin = skin
|
||||
end
|
||||
end
|
||||
if minetest.get_modpath("player_textures") then
|
||||
local filename = minetest.get_modpath("player_textures").."/textures/player_"..name
|
||||
local f = io.open(filename..".png")
|
||||
if f then
|
||||
f:close()
|
||||
armor.textures[name].skin = "player_"..name..".png"
|
||||
end
|
||||
end
|
||||
for i=1, ARMOR_INIT_TIMES do
|
||||
minetest.after(ARMOR_INIT_DELAY * i, function(name)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
armor:set_player_armor(player)
|
||||
end, player:get_player_name())
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_player_hpchange(function(player, hp_change, reason)
|
||||
local name, player_inv, armor_inv = armor:get_valid_player(player, "[on_hpchange]")
|
||||
if name and hp_change < 0 then
|
||||
local damage_type = armor.last_damage_types[name]
|
||||
armor.last_damage_types[name] = nil
|
||||
|
||||
-- Armor doesn't protect from set_hp (commands like /kill),
|
||||
if reason.type == "set_hp" then
|
||||
return hp_change
|
||||
end
|
||||
|
||||
local regular_reduction = reason.type ~= "drown" and reason.type ~= "fall" and reason.other ~= "harming" and reason.other ~= "poison"
|
||||
|
||||
local heal_max = 0
|
||||
local items = 0
|
||||
local armor_damage = math.max(1, math.floor(math.abs(hp_change)/4))
|
||||
|
||||
local total_points = 0
|
||||
local total_toughness = 0
|
||||
local epf = 0
|
||||
local thorns_damage = 0
|
||||
local thorns_damage_regular = 0
|
||||
for i=1, 6 do
|
||||
local stack = player_inv:get_stack("armor", i)
|
||||
if stack:get_count() > 0 then
|
||||
local enchantments = mcl_enchanting.get_enchantments(stack)
|
||||
local pts = stack:get_definition().groups["mcl_armor_points"] or 0
|
||||
local tough = stack:get_definition().groups["mcl_armor_toughness"] or 0
|
||||
total_points = total_points + pts
|
||||
total_toughness = total_toughness + tough
|
||||
|
||||
local protection_level = enchantments.protection or 0
|
||||
if protection_level > 0 then
|
||||
epf = epf + protection_level * 1
|
||||
end
|
||||
local blast_protection_level = enchantments.blast_protection or 0
|
||||
if blast_protection_level > 0 and damage_type == "explosion" then
|
||||
epf = epf + blast_protection_level * 2
|
||||
end
|
||||
local fire_protection_level = enchantments.fire_protection or 0
|
||||
if fire_protection_level > 0 and (damage_type == "burning" or damage_type == "fireball" or reason.type == "node_damage" and
|
||||
(reason.node == "mcl_fire:fire" or reason.node == "mcl_core:lava_source" or reason.node == "mcl_core:lava_flowing")) then
|
||||
epf = epf + fire_protection_level * 2
|
||||
end
|
||||
local projectile_protection_level = enchantments.projectile_protection or 0
|
||||
if projectile_protection_level and (damage_type == "projectile" or damage_type == "fireball") then
|
||||
epf = epf + projectile_protection_level * 2
|
||||
end
|
||||
local feather_falling_level = enchantments.feather_falling or 0
|
||||
if feather_falling_level and reason.type == "fall" then
|
||||
epf = epf + feather_falling_level * 3
|
||||
end
|
||||
|
||||
local did_thorns_damage = false
|
||||
local thorns_level = enchantments.thorns or 0
|
||||
if thorns_level then
|
||||
if thorns_level > 10 then
|
||||
thorns_damage = thorns_damage + thorns_level - 10
|
||||
did_thorns_damage = true
|
||||
elseif thorns_damage_regular < 4 and thorns_level * 0.15 > math.random() then
|
||||
local thorns_damage_regular_new = math.min(4, thorns_damage_regular + math.random(4))
|
||||
thorns_damage = thorns_damage + thorns_damage_regular_new - thorns_damage_regular
|
||||
thorns_damage_regular = thorns_damage_regular_new
|
||||
did_thorns_damage = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Damage armor
|
||||
local use = stack:get_definition().groups["mcl_armor_uses"] or 0
|
||||
if use > 0 and regular_reduction then
|
||||
local unbreaking_level = enchantments.unbreaking or 0
|
||||
if unbreaking_level > 0 then
|
||||
use = use / (0.6 + 0.4 / (unbreaking_level + 1))
|
||||
end
|
||||
local wear = armor_damage * math.floor(65536/use)
|
||||
if did_thorns_damage then
|
||||
wear = wear * 3
|
||||
end
|
||||
stack:add_wear(wear)
|
||||
end
|
||||
|
||||
local item = stack:get_name()
|
||||
armor_inv:set_stack("armor", i, stack)
|
||||
player_inv:set_stack("armor", i, stack)
|
||||
items = items + 1
|
||||
if stack:get_count() == 0 then
|
||||
armor:set_player_armor(player)
|
||||
armor:update_inventory(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
local damage = math.abs(hp_change)
|
||||
|
||||
if regular_reduction then
|
||||
-- Damage calculation formula (from <https://minecraft.gamepedia.com/Armor#Damage_protection>)
|
||||
damage = damage * (1 - math.min(20, math.max((total_points/5), total_points - damage / (2+(total_toughness/4)))) / 25)
|
||||
end
|
||||
damage = damage * (1 - (math.min(20, epf) / 25))
|
||||
damage = math.floor(damage+0.5)
|
||||
|
||||
if reason.type == "punch" and thorns_damage > 0 then
|
||||
local obj = reason.object
|
||||
if obj then
|
||||
local luaentity = obj:get_luaentity()
|
||||
if luaentity then
|
||||
local shooter = obj._shooter
|
||||
if shooter then
|
||||
obj = shooter
|
||||
end
|
||||
end
|
||||
obj:punch(player, 1.0, {
|
||||
full_punch_interval=1.0,
|
||||
damage_groups = {fleshy = thorns_damage},
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
hp_change = -math.abs(damage)
|
||||
|
||||
armor.def[name].count = items
|
||||
armor:update_armor(player)
|
||||
end
|
||||
return hp_change
|
||||
end, true)
|
103
mods/ITEMS/mcl_armor/damage.lua
Normal file
103
mods/ITEMS/mcl_armor/damage.lua
Normal file
@ -0,0 +1,103 @@
|
||||
function mcl_armor.damage_modifier(obj, hp_change, reason)
|
||||
if hp_change > 0 then
|
||||
return hp_change
|
||||
end
|
||||
|
||||
local damage = -hp_change
|
||||
local flags = reason.flags
|
||||
|
||||
if flags.bypasses_armor and flags.bypasses_magic then
|
||||
return hp_change
|
||||
end
|
||||
|
||||
local uses = math.max(1, math.floor(damage / 4))
|
||||
|
||||
local points = 0
|
||||
local toughness = 0
|
||||
local enchantment_protection_factor = 0
|
||||
|
||||
local thorns_damage_regular = 0
|
||||
local thorns_damage_irregular = 0
|
||||
local thorns_pieces = {}
|
||||
|
||||
local inv = mcl_util.get_inventory(obj)
|
||||
|
||||
if inv then
|
||||
for name, element in pairs(mcl_armor.elements) do
|
||||
local itemstack = inventory:get_stack("armor", element.index)
|
||||
if not stack:is_empty() then
|
||||
local itemname = stack:get_name()
|
||||
local enchantments = mcl_enchanting.get_enchantments(itemstack)
|
||||
|
||||
if not flags.bypasses_armor then
|
||||
points = points + minetest.get_item_group(itemname, "mcl_armor_points")
|
||||
toughness = toughness + minetest.get_item_group(itemname, "mcl_armor_toughness")
|
||||
|
||||
mcl_util.use_item_durability(itemstack, uses)
|
||||
inventory:set_stack("armor", element.index, itemstack)
|
||||
end
|
||||
|
||||
if not flags.bypasses_magic then
|
||||
local function add_enchantments(tbl)
|
||||
if tbl then
|
||||
for _, enchantment in pairs(tbl) do
|
||||
local level = enchantments[enchantment.id]
|
||||
|
||||
if level > 0 then
|
||||
enchantment_protection_factor = enchantment_protection_factor + level * enchantment.factor
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
add_enchantments(mcl_armor.protection_enchantments.wildcard)
|
||||
add_enchantments(mcl_armor.protection_enchantments.types[reason.type])
|
||||
|
||||
for flag, value in pairs(flags) do
|
||||
if value then
|
||||
add_enchantments(mcl_armor.protection_enchantments.flags[flag])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if reason.source and enchantments.thorns > 0 then
|
||||
local do_irregular_damage = enchantments.thorns > 10
|
||||
|
||||
if do_irregular_damage or thorns_damage_regular < 4 and math.random() < enchantments.thorns * 0.15 then
|
||||
if do_irregular_damage then
|
||||
thorns_damage_irregular = thorns_damage_irregular + throrns_level - 10
|
||||
else
|
||||
thorns_damage_regular = math.min(4, thorns_damage_regular + math.random(4))
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(thorns_pieces, {index = element.index, itemstack = itemstack})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- https://minecraft.gamepedia.com/Armor#Damage_protection
|
||||
damage = damage * (1 - math.min(20, math.max((points / 5), points - damage / (2 + (toughness / 4)))) / 25)
|
||||
|
||||
-- https://minecraft.gamepedia.com/Armor#Enchantments
|
||||
damage = damage * (1 - math.min(20, enchantment_protection_factor) / 25)
|
||||
|
||||
local thorns_damage = thorns_damage_regular + thorns_damage_irregular
|
||||
|
||||
if thorns_damage > 0 and reason.source ~= obj then
|
||||
mcl_util.deal_damage(reason.source, {type = "thorns", direct = obj, source = reason.source})
|
||||
|
||||
local thorns_item = thorns_pieces[math.random(#thorns_pieces)]
|
||||
mcl_util.use_item_durability(thorns_item.itemstack, 2)
|
||||
inventory:set_stack("armor", thorns_item.index, thorns_item.itemstack)
|
||||
end
|
||||
|
||||
mcl_armor.update(obj)
|
||||
|
||||
return -math.floor(damage + 0.5)
|
||||
end
|
||||
|
||||
mcl_damage.register_modifier(function(player, hp_change, _, reason)
|
||||
return mcl_armor.damage_modifier(player, hp_change, reason)
|
||||
end)
|
@ -1,405 +1,67 @@
|
||||
local S = minetest.get_translator("mcl_armor")
|
||||
|
||||
dofile(minetest.get_modpath(minetest.get_current_modname()).."/armor.lua")
|
||||
dofile(minetest.get_modpath(minetest.get_current_modname()).."/alias.lua")
|
||||
|
||||
-- Regisiter Head Armor
|
||||
|
||||
local longdesc = S("This is a piece of equippable armor which reduces the amount of damage you receive.")
|
||||
local usage = S("To equip it, put it on the corresponding armor slot in your inventory menu.")
|
||||
|
||||
minetest.register_tool("mcl_armor:elytra", {
|
||||
description = S("Elytra"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_elytra.png",
|
||||
groups = {armor_torso=1, mcl_armor_points=0, mcl_armor_uses=10, enchantability=0},
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_leather",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_leather",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
minetest.register_tool("mcl_armor:helmet_leather", {
|
||||
description = S("Leather Cap"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_helmet_leather.png",
|
||||
groups = {armor_head=1, mcl_armor_points=1, mcl_armor_uses=56, enchantability=15},
|
||||
_repair_material = "mcl_mobitems:leather",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_leather",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_leather",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
minetest.register_tool("mcl_armor:helmet_iron", {
|
||||
description = S("Iron Helmet"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_helmet_iron.png",
|
||||
groups = {armor_head=1, mcl_armor_points=2, mcl_armor_uses=166, enchantability=9 },
|
||||
_repair_material = "mcl_core:iron_ingot",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_iron",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_iron",
|
||||
},
|
||||
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
minetest.register_tool("mcl_armor:helmet_gold", {
|
||||
description = S("Golden Helmet"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_helmet_gold.png",
|
||||
groups = {armor_head=1, mcl_armor_points=2, mcl_armor_uses=78, enchantability=25 },
|
||||
_repair_material = "mcl_core:gold_ingot",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_iron",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_iron",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
minetest.register_tool("mcl_armor:helmet_diamond",{
|
||||
description = S("Diamond Helmet"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_helmet_diamond.png",
|
||||
groups = {armor_head=1, mcl_armor_points=3, mcl_armor_uses=364, mcl_armor_toughness=2, enchantability=10 },
|
||||
_repair_material = "mcl_core:diamond",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_diamond",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_diamond",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
minetest.register_tool("mcl_armor:helmet_chain", {
|
||||
description = S("Chain Helmet"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_helmet_chain.png",
|
||||
groups = {armor_head=1, mcl_armor_points=2, mcl_armor_uses=166, enchantability=12 },
|
||||
_repair_material = "mcl_core:iron_ingot",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_chainmail",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_chainmail",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
-- Regisiter Torso Armor
|
||||
|
||||
minetest.register_tool("mcl_armor:chestplate_leather", {
|
||||
description = S("Leather Tunic"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_chestplate_leather.png",
|
||||
groups = {armor_torso=1, mcl_armor_points=3, mcl_armor_uses=81, enchantability=15 },
|
||||
_repair_material = "mcl_mobitems:leather",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_leather",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_leather",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
minetest.register_tool("mcl_armor:chestplate_iron", {
|
||||
description = S("Iron Chestplate"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_chestplate_iron.png",
|
||||
groups = {armor_torso=1, mcl_armor_points=6, mcl_armor_uses=241, enchantability=9 },
|
||||
_repair_material = "mcl_core:iron_ingot",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_iron",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_iron",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
minetest.register_tool("mcl_armor:chestplate_gold", {
|
||||
description = S("Golden Chestplate"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_chestplate_gold.png",
|
||||
groups = {armor_torso=1, mcl_armor_points=5, mcl_armor_uses=113, enchantability=25 },
|
||||
_repair_material = "mcl_core:gold_ingot",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_iron",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_iron",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
minetest.register_tool("mcl_armor:chestplate_diamond",{
|
||||
description = S("Diamond Chestplate"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_chestplate_diamond.png",
|
||||
groups = {armor_torso=1, mcl_armor_points=8, mcl_armor_uses=529, mcl_armor_toughness=2, enchantability=10 },
|
||||
_repair_material = "mcl_core:diamond",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_diamond",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_diamond",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
minetest.register_tool("mcl_armor:chestplate_chain", {
|
||||
description = S("Chain Chestplate"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_chestplate_chain.png",
|
||||
groups = {armor_torso=1, mcl_armor_points=5, mcl_armor_uses=241, enchantability=12 },
|
||||
_repair_material = "mcl_core:iron_ingot",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_chainmail",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_chainmail",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
-- Regisiter Leg Armor
|
||||
|
||||
minetest.register_tool("mcl_armor:leggings_leather", {
|
||||
description = S("Leather Pants"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_leggings_leather.png",
|
||||
groups = {armor_legs=1, mcl_armor_points=2, mcl_armor_uses=76, enchantability=15 },
|
||||
_repair_material = "mcl_mobitems:leather",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_leather",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_leather",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
minetest.register_tool("mcl_armor:leggings_iron", {
|
||||
description = S("Iron Leggings"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_leggings_iron.png",
|
||||
groups = {armor_legs=1, mcl_armor_points=5, mcl_armor_uses=226, enchantability=9 },
|
||||
_repair_material = "mcl_core:iron_ingot",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_iron",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_iron",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
minetest.register_tool("mcl_armor:leggings_gold", {
|
||||
description = S("Golden Leggings"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_leggings_gold.png",
|
||||
groups = {armor_legs=1, mcl_armor_points=3, mcl_armor_uses=106, enchantability=25 },
|
||||
_repair_material = "mcl_core:gold_ingot",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_iron",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_iron",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
minetest.register_tool("mcl_armor:leggings_diamond",{
|
||||
description = S("Diamond Leggings"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_leggings_diamond.png",
|
||||
groups = {armor_legs=1, mcl_armor_points=6, mcl_armor_uses=496, mcl_armor_toughness=2, enchantability=10 },
|
||||
_repair_material = "mcl_core:diamond",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_diamond",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_diamond",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
minetest.register_tool("mcl_armor:leggings_chain", {
|
||||
description = S("Chain Leggings"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_leggings_chain.png",
|
||||
groups = {armor_legs=1, mcl_armor_points=4, mcl_armor_uses=226, enchantability=12 },
|
||||
_repair_material = "mcl_core:iron_ingot",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_chainmail",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_chainmail",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
-- Regisiter Boots
|
||||
|
||||
minetest.register_tool("mcl_armor:boots_leather", {
|
||||
description = S("Leather Boots"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_boots_leather.png",
|
||||
groups = {armor_feet=1, mcl_armor_points=1, mcl_armor_uses=66, enchantability=15 },
|
||||
_repair_material = "mcl_mobitems:leather",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_leather",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_leather",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
minetest.register_tool("mcl_armor:boots_iron", {
|
||||
description = S("Iron Boots"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_boots_iron.png",
|
||||
groups = {armor_feet=1, mcl_armor_points=2, mcl_armor_uses=196, enchantability=9 },
|
||||
_repair_material = "mcl_core:iron_ingot",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_iron",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_iron",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
minetest.register_tool("mcl_armor:boots_gold", {
|
||||
description = S("Golden Boots"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_boots_gold.png",
|
||||
groups = {armor_feet=1, mcl_armor_points=1, mcl_armor_uses=92, enchantability=25 },
|
||||
_repair_material = "mcl_core:gold_ingot",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_iron",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_iron",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
minetest.register_tool("mcl_armor:boots_diamond",{
|
||||
description = S("Diamond Boots"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_boots_diamond.png",
|
||||
groups = {armor_feet=1, mcl_armor_points=3, mcl_armor_uses=430, mcl_armor_toughness=2, enchantability=10 },
|
||||
_repair_material = "mcl_core:diamond",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_diamond",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_diamond",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
minetest.register_tool("mcl_armor:boots_chain", {
|
||||
description = S("Chain Boots"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usage,
|
||||
inventory_image = "mcl_armor_inv_boots_chain.png",
|
||||
groups = {armor_feet=1, mcl_armor_points=1, mcl_armor_uses=196, enchantability=12 },
|
||||
_repair_material = "mcl_core:iron_ingot",
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_chainmail",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_chainmail",
|
||||
},
|
||||
on_place = armor.on_armor_use,
|
||||
on_secondary_use = armor.on_armor_use,
|
||||
})
|
||||
|
||||
-- Register Craft Recipies
|
||||
|
||||
local craft_ingreds = {
|
||||
leather = { "mcl_mobitems:leather" },
|
||||
iron = { "mcl_core:iron_ingot", "mcl_core:iron_nugget" },
|
||||
gold = { "mcl_core:gold_ingot", "mcl_core:gold_nugget" },
|
||||
diamond = { "mcl_core:diamond" },
|
||||
chain = { nil, "mcl_core:iron_nugget"} ,
|
||||
mcl_armor = {
|
||||
longdesc = S("This is a piece of equippable armor which reduces the amount of damage you receive."),
|
||||
usage = S("To equip it, put it on the corresponding armor slot in your inventory menu."),
|
||||
elements = {
|
||||
head = {
|
||||
name = "helmet",
|
||||
description = "Helmet",
|
||||
durability = 0.6857,
|
||||
index = 2,
|
||||
craft = function(m)
|
||||
return {
|
||||
{ m, m, m},
|
||||
{ m, "", m},
|
||||
{"", "", ""},
|
||||
}
|
||||
end,
|
||||
},
|
||||
torso = {
|
||||
name = "chestplate",
|
||||
description = "Chestplate",
|
||||
durability = 1.0,
|
||||
index = 3,
|
||||
craft = function(m)
|
||||
return {
|
||||
{ m, "", m},
|
||||
{ m, m, m},
|
||||
{ m, m, m},
|
||||
}
|
||||
end,
|
||||
},
|
||||
legs = {
|
||||
name = "leggings",
|
||||
description = "Leggings",
|
||||
durability = 0.9375,
|
||||
index = 4,
|
||||
craft = function(m)
|
||||
return {
|
||||
{ m, m, m},
|
||||
{ m, "", m},
|
||||
{ m, "", m},
|
||||
}
|
||||
end,
|
||||
},
|
||||
feet = {
|
||||
name = "boots",
|
||||
description = "Boots",
|
||||
durability = 0.8125,
|
||||
index = 5,
|
||||
craft = function(m)
|
||||
return {
|
||||
{ m, "", m},
|
||||
{ m, "", m},
|
||||
}
|
||||
end,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for k, v in pairs(craft_ingreds) do
|
||||
-- material
|
||||
local m = v[1]
|
||||
-- cooking result
|
||||
local c = v[2]
|
||||
if m ~= nil then
|
||||
minetest.register_craft({
|
||||
output = "mcl_armor:helmet_"..k,
|
||||
recipe = {
|
||||
{m, m, m},
|
||||
{m, "", m},
|
||||
{"", "", ""},
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "mcl_armor:chestplate_"..k,
|
||||
recipe = {
|
||||
{m, "", m},
|
||||
{m, m, m},
|
||||
{m, m, m},
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "mcl_armor:leggings_"..k,
|
||||
recipe = {
|
||||
{m, m, m},
|
||||
{m, "", m},
|
||||
{m, "", m},
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "mcl_armor:boots_"..k,
|
||||
recipe = {
|
||||
{m, "", m},
|
||||
{m, "", m},
|
||||
},
|
||||
})
|
||||
end
|
||||
if c ~= nil then
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = c,
|
||||
recipe = "mcl_armor:helmet_"..k,
|
||||
cooktime = 10,
|
||||
})
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = c,
|
||||
recipe = "mcl_armor:chestplate_"..k,
|
||||
cooktime = 10,
|
||||
})
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = c,
|
||||
recipe = "mcl_armor:leggings_"..k,
|
||||
cooktime = 10,
|
||||
})
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = c,
|
||||
recipe = "mcl_armor:boots_"..k,
|
||||
cooktime = 10,
|
||||
})
|
||||
end
|
||||
end
|
||||
local modpath = minetest.get_modpath("mcl_armor")
|
||||
|
||||
dofile(modpath .. "/api.lua")
|
||||
dofile(modpath .. "/player.lua")
|
||||
dofile(modpath .. "/damage.lua")
|
||||
dofile(modpath .. "/register.lua")
|
||||
dofile(modpath .. "/alias.lua")
|
||||
|
143
mods/ITEMS/mcl_armor/player.lua
Normal file
143
mods/ITEMS/mcl_armor/player.lua
Normal file
@ -0,0 +1,143 @@
|
||||
mcl_player.player_register_model("mcl_armor_character.b3d", {
|
||||
animation_speed = 30,
|
||||
textures = {
|
||||
"character.png",
|
||||
"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},
|
||||
sneak_stand = {x=222, y=302},
|
||||
sneak_mine = {x=346, y=365},
|
||||
sneak_walk = {x=304, y=323},
|
||||
sneak_walk_mine = {x=325, y=344},
|
||||
swim_walk = {x=368, y=387},
|
||||
swim_walk_mine = {x=389, y=408},
|
||||
swim_stand = {x=434, y=434},
|
||||
swim_mine = {x=411, y=430},
|
||||
run_walk = {x=440, y=459},
|
||||
run_walk_mine = {x=461, y=480},
|
||||
sit_mount = {x=484, y=484},
|
||||
die = {x=498, y=498},
|
||||
fly = {x=502, y=581},
|
||||
},
|
||||
})
|
||||
|
||||
mcl_player.player_register_model("mcl_armor_character_female.b3d", {
|
||||
animation_speed = 30,
|
||||
textures = {
|
||||
"character.png",
|
||||
"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},
|
||||
sneak_stand = {x=222, y=302},
|
||||
sneak_mine = {x=346, y=365},
|
||||
sneak_walk = {x=304, y=323},
|
||||
sneak_walk_mine = {x=325, y=344},
|
||||
swim_walk = {x=368, y=387},
|
||||
swim_walk_mine = {x=389, y=408},
|
||||
swim_stand = {x=434, y=434},
|
||||
swim_mine = {x=411, y=430},
|
||||
run_walk = {x=440, y=459},
|
||||
run_walk_mine = {x=461, y=480},
|
||||
sit_mount = {x=484, y=484},
|
||||
die = {x=498, y=498},
|
||||
fly = {x=502, y=581},
|
||||
},
|
||||
})
|
||||
|
||||
function mcl_armor.update_player(player, info)
|
||||
mcl_player.player_set_armor(player, info.texture, info.preview)
|
||||
|
||||
player:get_meta():set_int("mcl_armor:armor_point", info.points)
|
||||
end
|
||||
|
||||
local function is_armor_action(inventory_info)
|
||||
return inventory_info.from_list == "armor" or inventory_info.to_list == "armor" or inventory_info.listname == "armor"
|
||||
end
|
||||
|
||||
local function limit_put(player, inventory, index, stack, count)
|
||||
local def = stack:get_definition()
|
||||
|
||||
if not def then
|
||||
return 0
|
||||
end
|
||||
|
||||
local element = def._mcl_armor_element
|
||||
|
||||
if not element then
|
||||
return 0
|
||||
end
|
||||
|
||||
if mcl_armor.elements[element].index ~= index then
|
||||
return 0
|
||||
end
|
||||
|
||||
local old_stack = inventory:get_stack("armor", index)
|
||||
|
||||
if old_stack:is_empty() or old_stack:get_name() ~= stack:get_name() and count <= 1 then
|
||||
return count
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
local function limit_take(player, inventory, index, stack, count)
|
||||
if mcl_enchanting.has_enchantment(stack, "curse_of_binding") and not minetest.is_creative_enabled(player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
|
||||
return count
|
||||
end
|
||||
|
||||
minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info)
|
||||
if not is_armor_action(inventory_info) then
|
||||
return
|
||||
end
|
||||
|
||||
if action == "put" then
|
||||
return limit_put(player, inventory, inventory_info.index, inventory_info.stack, inventory_info.stack:get_count())
|
||||
elseif action == "take" then
|
||||
return limit_take(player, inventory, inventory_info.index, inventory_info.stack, inventory_info.stack:get_count())
|
||||
else
|
||||
if inventory_info.from_list ~= "armor" then
|
||||
return limit_put(player, inventory, inventory_info.to_index, inventory:get_stack(inventory_info.from_list, inventory_info.from_index), inventory_info.count)
|
||||
elseif inventory_info.to_list ~= "armor" then
|
||||
return limit_take(player, inventory, inventory_info.from_index, inventory:get_stack(inventory_info.from_list, inventory_info.from_index), inventory_info.count)
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- ToDo: Call unequip callbacks & play uneqip sound
|
||||
minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info)
|
||||
if is_armor_action(inventory_info) then
|
||||
mcl_armor.update(player)
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
mcl_player.player_set_model(player, "mcl_armor_character.b3d")
|
||||
player:get_inventory():set_size("armor", 5)
|
||||
|
||||
minetest.after(1, function()
|
||||
if player:is_player() then
|
||||
mcl_armor.update(player)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
|
204
mods/ITEMS/mcl_armor/register.lua
Normal file
204
mods/ITEMS/mcl_armor/register.lua
Normal file
@ -0,0 +1,204 @@
|
||||
local S = minetest.get_translator("mcl_armor")
|
||||
|
||||
mcl_armor.register_set({
|
||||
name = "leather",
|
||||
description = "Leather",
|
||||
descriptions = {
|
||||
head = "Cap",
|
||||
torso = "Tunic",
|
||||
legs = "Pants",
|
||||
},
|
||||
durability = 80,
|
||||
enchantability = 15,
|
||||
points = {
|
||||
head = 1,
|
||||
torso = 3,
|
||||
legs = 2,
|
||||
feet = 1,
|
||||
},
|
||||
craft_material = "mcl_mobitems:leather",
|
||||
})
|
||||
|
||||
mcl_armor.register_set({
|
||||
name = "gold",
|
||||
description = "Golden",
|
||||
durability = 112,
|
||||
enchantability = 25,
|
||||
points = {
|
||||
head = 2,
|
||||
torso = 5,
|
||||
legs = 3,
|
||||
feet = 1,
|
||||
},
|
||||
craft_material = "mcl_core:gold_ingot",
|
||||
cook_material = "mcl_core:gold_nugget",
|
||||
sound_equip = "mcl_armor_equip_iron",
|
||||
sound_unequip = "mcl_armor_unequip_iron",
|
||||
})
|
||||
|
||||
mcl_armor.register_set({
|
||||
name = "chain",
|
||||
description = "Chain",
|
||||
durability = 240,
|
||||
enchantability = 12,
|
||||
points = {
|
||||
head = 2,
|
||||
torso = 5,
|
||||
legs = 4,
|
||||
feet = 1,
|
||||
},
|
||||
repair_material = "mcl_core:iron_ingot",
|
||||
cook_material = "mcl_core:iron_nugget",
|
||||
})
|
||||
|
||||
mcl_armor.register_set({
|
||||
name = "iron",
|
||||
description = "Iron",
|
||||
durability = 240,
|
||||
enchantability = 9,
|
||||
points = {
|
||||
head = 2,
|
||||
torso = 6,
|
||||
legs = 5,
|
||||
feet = 2,
|
||||
},
|
||||
craft_material = "mcl_core:iron_ingot",
|
||||
cook_material = "mcl_core:iron_nugget",
|
||||
})
|
||||
|
||||
mcl_armor.register_set({
|
||||
name = "diamond",
|
||||
description = "Diamond",
|
||||
durability = 528,
|
||||
enchantability = 10,
|
||||
points = {
|
||||
head = 3,
|
||||
torso = 8,
|
||||
legs = 6,
|
||||
feet = 3,
|
||||
},
|
||||
toughness = 2,
|
||||
craft_material = "mcl_core:diamond",
|
||||
})
|
||||
|
||||
mcl_armor.register_protection_enchantment({
|
||||
id = "projectile_protection",
|
||||
name = S("Projectile Protection"),
|
||||
description = S("Reduces projectile damage."),
|
||||
power_range_table = {{1, 16}, {11, 26}, {21, 36}, {31, 46}, {41, 56}},
|
||||
incompatible = {blast_protection = true, fire_protection = true, protection = true},
|
||||
factor = 2,
|
||||
damage_flag = "is_projectile",
|
||||
})
|
||||
|
||||
mcl_armor.register_protection_enchantment({
|
||||
id = "blast_protection",
|
||||
name = S("Blast Protection"),
|
||||
description = S("Reduces explosion damage and knockback."),
|
||||
power_range_table = {{5, 13}, {13, 21}, {21, 29}, {29, 37}},
|
||||
weight = 2,
|
||||
incompatible = {fire_protection = true, protection = true, projectile_protection = true},
|
||||
factor = 2,
|
||||
damage_flag = "is_explosion",
|
||||
})
|
||||
|
||||
mcl_armor.register_protection_enchantment({
|
||||
id = "fire_protection",
|
||||
name = S("Fire Protection"),
|
||||
description = S("Reduces fire damage."),
|
||||
power_range_table = {{5, 13}, {13, 21}, {21, 29}, {29, 37}},
|
||||
incompatible = {blast_protection = true, protection = true, projectile_protection = true},
|
||||
factor = 2,
|
||||
damage_flag = "is_fire",
|
||||
})
|
||||
|
||||
mcl_armor.register_protection_enchantment({
|
||||
id = "protection",
|
||||
name = S("Protection"),
|
||||
description = S("Reduces most types of damage by 4% for each level."),
|
||||
power_range_table = {{1, 12}, {12, 23}, {23, 34}, {34, 45}},
|
||||
incompatible = {blast_protection = true, fire_protection = true, projectile_protection = true},
|
||||
factor = 1,
|
||||
})
|
||||
|
||||
mcl_armor.register_protection_enchantment({
|
||||
id = "feather_falling",
|
||||
name = S("Feather Falling"),
|
||||
description = S("Reduces fall damage."),
|
||||
power_range_table = {{5, 11}, {11, 17}, {17, 23}, {23, 29}},
|
||||
factor = 3,
|
||||
primary = {combat_armor_feet = true},
|
||||
damage_type = "fall",
|
||||
})
|
||||
|
||||
-- requires engine change
|
||||
--[[mcl_enchanting.enchantments.aqua_affinity = {
|
||||
name = S("Aqua Affinity"),
|
||||
max_level = 1,
|
||||
primary = {armor_head = true},
|
||||
secondary = {},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {},
|
||||
weight = 2,
|
||||
description = S("Increases underwater mining speed."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{1, 41}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}]]--
|
||||
|
||||
mcl_enchanting.enchantments.curse_of_binding = {
|
||||
name = S("Curse of Binding"),
|
||||
max_level = 1,
|
||||
primary = {},
|
||||
secondary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true},
|
||||
disallow = {},
|
||||
incompatible = {},
|
||||
weight = 1,
|
||||
description = S("Item cannot be removed from armor slots except due to death, breaking or in Creative Mode."),
|
||||
curse = true,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = true,
|
||||
power_range_table = {{25, 50}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
mcl_enchanting.enchantments.thorns = {
|
||||
name = S("Thorns"),
|
||||
max_level = 3,
|
||||
primary = {combat_armor_chestplate = true},
|
||||
secondary = {combat_armor = true},
|
||||
disallow = {},
|
||||
incompatible = {},
|
||||
weight = 1,
|
||||
description = S("Reflects some of the damage taken when hit, at the cost of reducing durability with each proc."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{10, 61}, {30, 71}, {50, 81}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
-- Elytra
|
||||
|
||||
minetest.register_tool("mcl_armor:elytra", {
|
||||
description = S("Elytra"),
|
||||
_doc_items_longdesc = mcl_armor.longdesc,
|
||||
_doc_items_usagehelp = mcl_armor.usage,
|
||||
inventory_image = "mcl_armor_inv_elytra.png",
|
||||
groups = {armor = 1, non_combat_armor = 1, armor_torso = 1, non_combat_torso = 1, mcl_armor_uses = 10},
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_leather",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_leather",
|
||||
},
|
||||
on_place = mcl_armor.equip_on_use,
|
||||
on_secondary_use = mcl_armor.equip_on_use,
|
||||
_mcl_armor_element = "torso",
|
||||
})
|
@ -150,7 +150,7 @@ minetest.register_node("mcl_armor_stand:armor_stand", {
|
||||
single_item:set_count(1)
|
||||
if inv:is_empty(list) then
|
||||
inv:add_item(list, single_item)
|
||||
armor:play_equip_sound(single_item, nil, pos)
|
||||
mcl_armor.play_equip_sound(single_item, nil, pos)
|
||||
update_entity(pos)
|
||||
itemstack:take_item()
|
||||
return itemstack
|
||||
@ -175,7 +175,7 @@ minetest.register_node("mcl_armor_stand:armor_stand", {
|
||||
taken = true
|
||||
end
|
||||
if taken then
|
||||
armor:play_equip_sound(stand_armor, nil, pos, true)
|
||||
mcl_armor.play_equip_sound(stand_armor, nil, pos, true)
|
||||
stand_armor:take_item()
|
||||
inv:set_stack("armor_" .. elements[e], 1, stand_armor)
|
||||
end
|
||||
|
@ -69,6 +69,7 @@ local ARROW_ENTITY={
|
||||
_stuckrechecktimer=nil,-- An additional timer for periodically re-checking the stuck status of an arrow
|
||||
_stuckin=nil, --Position of node in which arow is stuck.
|
||||
_shooter=nil, -- ObjectRef of player or mob who shot it
|
||||
_is_arrow = true,
|
||||
|
||||
_viscosity=0, -- Viscosity of node the arrow is currently in
|
||||
_deflection_cooloff=0, -- Cooloff timer after an arrow deflection, to prevent many deflections in quick succession
|
||||
@ -254,9 +255,6 @@ ARROW_ENTITY.on_step = function(self, dtime)
|
||||
|
||||
-- Punch target object but avoid hurting enderman.
|
||||
if not lua or lua.name ~= "mobs_mc:enderman" then
|
||||
if obj:is_player() and rawget(_G, "armor") and armor.last_damage_types then
|
||||
armor.last_damage_types[obj:get_player_name()] = "projectile"
|
||||
end
|
||||
if self._in_player == false then
|
||||
damage_particles(self.object:get_pos(), self._is_critical)
|
||||
end
|
||||
|
@ -59,6 +59,7 @@ mcl_bows.shoot_arrow = function(arrow_item, pos, dir, yaw, shooter, power, damag
|
||||
obj:set_yaw(yaw-math.pi/2)
|
||||
local le = obj:get_luaentity()
|
||||
le._shooter = shooter
|
||||
le._source_object = shooter
|
||||
le._damage = damage
|
||||
le._is_critical = is_critical
|
||||
le._startpos = pos
|
||||
|
@ -203,7 +203,7 @@ S("• When lava is directly above water, the water turns into stone."),
|
||||
_mcl_node_death_message = lava_death_messages,
|
||||
post_effect_color = {a=245, r=208, g=73, b=10},
|
||||
stack_max = 64,
|
||||
groups = { lava=3, lava_source=1, liquid=2, destroys_items=1, not_in_creative_inventory=1, dig_by_piston=1, set_on_fire=15},
|
||||
groups = { lava=3, lava_source=1, liquid=2, destroys_items=1, not_in_creative_inventory=1, dig_by_piston=1, set_on_fire=15, fire_damage=1},
|
||||
_mcl_blast_resistance = 100,
|
||||
-- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode
|
||||
_mcl_hardness = -1,
|
||||
|
@ -10,25 +10,6 @@ local function increase_damage(damage_group, factor)
|
||||
end
|
||||
end
|
||||
|
||||
-- requires engine change
|
||||
--[[mcl_enchanting.enchantments.aqua_affinity = {
|
||||
name = S("Aqua Affinity"),
|
||||
max_level = 1,
|
||||
primary = {armor_head = true},
|
||||
secondary = {},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {},
|
||||
weight = 2,
|
||||
description = S("Increases underwater mining speed."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{1, 41}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}]]--
|
||||
|
||||
-- implemented via on_enchant and additions in mobs_mc; Slowness IV part unimplemented
|
||||
mcl_enchanting.enchantments.bane_of_arthropods = {
|
||||
name = S("Bane of Arthropods"),
|
||||
@ -48,25 +29,6 @@ mcl_enchanting.enchantments.bane_of_arthropods = {
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
-- implemented in mcl_armor
|
||||
mcl_enchanting.enchantments.blast_protection = {
|
||||
name = S("Blast Protection"),
|
||||
max_level = 4,
|
||||
primary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true},
|
||||
secondary = {},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {fire_protection = true, protection = true, projectile_protection = true},
|
||||
weight = 2,
|
||||
description = S("Reduces explosion damage and knockback."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{5, 13}, {13, 21}, {21, 29}, {29, 37}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
-- requires missing MineClone2 feature
|
||||
--[[mcl_enchanting.enchantments.channeling = {
|
||||
name = S("Channeling"),
|
||||
@ -86,25 +48,6 @@ mcl_enchanting.enchantments.blast_protection = {
|
||||
inv_tool_tab = false,
|
||||
}]]--
|
||||
|
||||
-- implemented in mcl_armor
|
||||
mcl_enchanting.enchantments.curse_of_binding = {
|
||||
name = S("Curse of Binding"),
|
||||
max_level = 1,
|
||||
primary = {},
|
||||
secondary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true},
|
||||
disallow = {},
|
||||
incompatible = {},
|
||||
weight = 1,
|
||||
description = S("Item cannot be removed from armor slots except due to death, breaking or in Creative Mode."),
|
||||
curse = true,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = true,
|
||||
power_range_table = {{25, 50}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
-- implemented in mcl_death_drop
|
||||
mcl_enchanting.enchantments.curse_of_vanishing = {
|
||||
name = S("Curse of Vanishing"),
|
||||
@ -164,24 +107,6 @@ mcl_enchanting.enchantments.efficiency = {
|
||||
inv_tool_tab = true,
|
||||
}
|
||||
|
||||
-- implemented in mcl_armor
|
||||
mcl_enchanting.enchantments.feather_falling = {
|
||||
name = S("Feather Falling"),
|
||||
max_level = 4,
|
||||
primary = {armor_feet = true},
|
||||
secondary = {},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {},
|
||||
weight = 5,
|
||||
description = S("Reduces fall damage."),curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{5, 11}, {11, 17}, {17, 23}, {23, 29}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
-- implemented in mcl_mobs and via register_on_punchplayer callback
|
||||
mcl_enchanting.enchantments.fire_aspect = {
|
||||
name = S("Fire Aspect"),
|
||||
@ -213,25 +138,6 @@ minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch,
|
||||
end
|
||||
end)
|
||||
|
||||
-- implemented in mcl_armor
|
||||
mcl_enchanting.enchantments.fire_protection = {
|
||||
name = S("Fire Protection"),
|
||||
max_level = 4,
|
||||
primary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true},
|
||||
secondary = {},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {blast_protection = true, protection = true, projectile_protection = true},
|
||||
weight = 5,
|
||||
description = S("Reduces fire damage."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{10, 18}, {18, 26}, {26, 34}, {34, 42}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
mcl_enchanting.enchantments.flame = {
|
||||
name = S("Flame"),
|
||||
max_level = 1,
|
||||
@ -530,44 +436,6 @@ mcl_enchanting.enchantments.power = {
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
-- implemented in mcl_armor
|
||||
mcl_enchanting.enchantments.projectile_protection = {
|
||||
name = S("Projectile Protection"),
|
||||
max_level = 4,
|
||||
primary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true},
|
||||
secondary = {},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {blast_protection = true, fire_protection = true, protection = true},
|
||||
weight = 5,
|
||||
description = S("Reduces projectile damage."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{1, 16}, {11, 26}, {21, 36}, {31, 46}, {41, 56}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
-- implemented in mcl_armor
|
||||
mcl_enchanting.enchantments.protection = {
|
||||
name = S("Protection"),
|
||||
max_level = 4,
|
||||
primary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true},
|
||||
secondary = {},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {blast_protection = true, fire_protection = true, projectile_protection = true},
|
||||
weight = 10,
|
||||
description = S("Reduces most types of damage by 4% for each level."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{1, 12}, {12, 23}, {23, 34}, {34, 45}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
-- implemented via minetest.calculate_knockback (together with the Knockback enchantment) and mcl_bows
|
||||
mcl_enchanting.enchantments.punch = {
|
||||
name = S("Punch"),
|
||||
@ -739,25 +607,6 @@ mcl_enchanting.enchantments.soul_speed = {
|
||||
inv_tool_tab = false,
|
||||
}]]--
|
||||
|
||||
-- implemented in mcl_armor
|
||||
mcl_enchanting.enchantments.thorns = {
|
||||
name = S("Thorns"),
|
||||
max_level = 3,
|
||||
primary = {armor_head = true},
|
||||
secondary = {armor_torso = true, armor_legs = true, armor_feet = true},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {},
|
||||
weight = 1,
|
||||
description = S("Reflects some of the damage taken when hit, at the cost of reducing durability with each proc."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{10, 61}, {30, 71}, {50, 81}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
-- for tools & weapons implemented via on_enchant; for bows implemented in mcl_bows; for armor implemented in mcl_armor and mcl_tt; for fishing rods implemented in mcl_fishing
|
||||
mcl_enchanting.enchantments.unbreaking = {
|
||||
name = S("Unbreaking"),
|
||||
|
@ -266,7 +266,8 @@ function mcl_enchanting.initialize()
|
||||
new_def.groups.not_in_creative_inventory = 1
|
||||
new_def.groups.not_in_craft_guide = 1
|
||||
new_def.groups.enchanted = 1
|
||||
new_def.texture = itemdef.texture or itemname:gsub("%:", "_")
|
||||
new_def._mcl_armor_texture = new_def._mcl_armor_texture and new_def._mcl_armor_texture .. mcl_enchanting.overlay
|
||||
new_def._mcl_armor_preview = new_def._mcl_armor_preview and new_def._mcl_armor_preview .. mcl_enchanting.overlay
|
||||
new_def._mcl_enchanting_enchanted_tool = new_name
|
||||
new_def.after_use = get_after_use_callback(itemdef)
|
||||
local register_list = register_item_list
|
||||
|
@ -111,12 +111,16 @@ pumpkin_face_base_def.description = S("Pumpkin")
|
||||
pumpkin_face_base_def._doc_items_longdesc = S("A pumpkin can be worn as a helmet. Pumpkins grow from pumpkin stems, which in turn grow from pumpkin seeds.")
|
||||
pumpkin_face_base_def._doc_items_usagehelp = nil
|
||||
pumpkin_face_base_def.tiles = {"farming_pumpkin_top.png", "farming_pumpkin_top.png", "farming_pumpkin_side.png", "farming_pumpkin_side.png", "farming_pumpkin_side.png", "farming_pumpkin_face.png"}
|
||||
pumpkin_face_base_def.groups.armor=1
|
||||
pumpkin_face_base_def.groups.non_combat_armor=1
|
||||
pumpkin_face_base_def.groups.armor_head=1
|
||||
pumpkin_face_base_def.groups.non_combat_armor_head=1
|
||||
pumpkin_face_base_def._mcl_armor_mob_range_factor = 0
|
||||
pumpkin_face_base_def._mcl_armor_mob_range_mob = "mobs_mc:enderman"
|
||||
pumpkin_face_base_def._mcl_armor_entry = "head"
|
||||
pumpkin_face_base_def.groups.non_combat_armor=1
|
||||
if minetest.get_modpath("mcl_armor") then
|
||||
pumpkin_face_base_def.on_secondary_use = armor.on_armor_use
|
||||
pumpkin_face_base_def.on_secondary_use = mcl_armor.equip_on_use
|
||||
end
|
||||
|
||||
-- Register stem growth
|
||||
|
@ -203,7 +203,7 @@ minetest.register_node("mcl_fire:fire", {
|
||||
sunlight_propagates = true,
|
||||
damage_per_second = 1,
|
||||
_mcl_node_death_message = fire_death_messages,
|
||||
groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston=1, destroys_items=1, set_on_fire=8},
|
||||
groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston=1, destroys_items=1, set_on_fire=8, fire_damage=1},
|
||||
floodable = true,
|
||||
on_flood = function(pos, oldnode, newnode)
|
||||
if get_item_group(newnode.name, "water") ~= 0 then
|
||||
@ -334,7 +334,7 @@ minetest.register_node("mcl_fire:eternal_fire", {
|
||||
sunlight_propagates = true,
|
||||
damage_per_second = 1,
|
||||
_mcl_node_death_message = fire_death_messages,
|
||||
groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston = 1, destroys_items = 1, set_on_fire=8},
|
||||
groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston = 1, destroys_items = 1, set_on_fire=8, fire_damage=1},
|
||||
floodable = true,
|
||||
on_flood = function(pos, oldnode, newnode)
|
||||
if get_item_group(newnode.name, "water") ~= 0 then
|
||||
|
@ -5,7 +5,7 @@ local mod_screwdriver = minetest.get_modpath("screwdriver")
|
||||
|
||||
local equip_armor
|
||||
if minetest.get_modpath("mcl_armor") then
|
||||
equip_armor = armor.on_armor_use
|
||||
equip_armor = mcl_armor.equip_on_use
|
||||
end
|
||||
|
||||
-- Heads system
|
||||
|
@ -603,21 +603,18 @@ function mcl_potions.make_invisible(player, toggle)
|
||||
return
|
||||
end
|
||||
|
||||
if minetest.get_modpath("mcl_armor") and player:is_player() then
|
||||
armor.textures[playername].skin = skin_file
|
||||
armor:update_player_visuals(player)
|
||||
elseif not player:is_player() and minetest.get_modpath("mcl_armor") or not player:is_player() and not minetest.get_modpath("mcl_armor") then
|
||||
if player:is_player() then
|
||||
mcl_player.player_set_skin(player, "mobs_mc_empty.png")
|
||||
elseif not player:is_player() then
|
||||
player:set_properties({visual_size = {x = 0, y = 0}})
|
||||
end
|
||||
player:set_nametag_attributes({color = {a = 0}})
|
||||
|
||||
elseif EF.invisible[player] then -- show player
|
||||
|
||||
if minetest.get_modpath("mcl_armor") and player:is_player() then
|
||||
skin_file = mcl_skins.skins[playername] .. ".png"
|
||||
armor.textures[playername].skin = skin_file
|
||||
armor:update_player_visuals(player)
|
||||
elseif not player:is_player() and minetest.get_modpath("mcl_armor") or not player:is_player() and not minetest.get_modpath("mcl_armor") then
|
||||
if player:is_player() then
|
||||
mcl_skins.update_player_skin(player)
|
||||
elseif not player:is_player() then
|
||||
player:set_properties({visual_size = EF.invisible[player].old_size})
|
||||
end
|
||||
player:set_nametag_attributes({color = {r = 255, g = 255, b = 255, a = 255}})
|
||||
|
@ -277,7 +277,7 @@ minetest.register_lbm({
|
||||
nodenames = {"group:torch_particles"},
|
||||
run_at_every_load = true,
|
||||
action = function(pos, node)
|
||||
local torch_group = minetest.get_node_group(node.name, "torch")
|
||||
local torch_group = minetest.get_item_group(node.name, "torch")
|
||||
if torch_group == 1 then
|
||||
spawn_flames_floor(pos)
|
||||
elseif torch_group == 2 then
|
||||
|
@ -157,7 +157,7 @@ screwdriver.handler = function(itemstack, user, pointed_thing, mode, uses)
|
||||
if should_rotate and new_param2 ~= node.param2 then
|
||||
node.param2 = new_param2
|
||||
minetest.swap_node(pos, node)
|
||||
|
||||
|
||||
minetest.check_for_falling(pos)
|
||||
if ndef.after_rotate then
|
||||
ndef.after_rotate(vector.new(pos))
|
||||
|
@ -11,7 +11,6 @@ end
|
||||
mcl_death_drop.register_dropped_list("PLAYER", "main", true)
|
||||
mcl_death_drop.register_dropped_list("PLAYER", "craft", true)
|
||||
mcl_death_drop.register_dropped_list("PLAYER", "armor", true)
|
||||
mcl_death_drop.register_dropped_list(function(player) return select(3, armor:get_valid_player(player)) end , "armor", false)
|
||||
|
||||
minetest.register_on_dieplayer(function(player)
|
||||
local keep = minetest.settings:get_bool("mcl_keepInventory", false)
|
||||
@ -50,7 +49,6 @@ minetest.register_on_dieplayer(function(player)
|
||||
inv:set_list(listname, {})
|
||||
end
|
||||
end
|
||||
armor:set_player_armor(player)
|
||||
armor:update_inventory(player)
|
||||
mcl_armor.update(player)
|
||||
end
|
||||
end)
|
||||
|
@ -88,22 +88,41 @@ function mcl_player.player_set_model(player, model_name)
|
||||
player_model[name] = model_name
|
||||
end
|
||||
|
||||
function mcl_player.player_set_textures(player, textures, preview)
|
||||
local name = player:get_player_name()
|
||||
player_textures[name] = textures
|
||||
player:set_properties({textures = textures,})
|
||||
if preview then
|
||||
player:get_meta():set_string("mcl_player:preview", preview)
|
||||
end
|
||||
local function set_texture(player, index, texture)
|
||||
local textures = player_textures[player:get_player_name()]
|
||||
textures[index] = texture
|
||||
player:set_properties({textures = textures})
|
||||
end
|
||||
|
||||
local function set_preview(player, field, preview)
|
||||
player:get_meta():set_string("mcl_player:" .. field .. "_preview", preview)
|
||||
end
|
||||
|
||||
function mcl_player.player_set_skin(player, texture, preview)
|
||||
set_texture(player, 1, texture)
|
||||
set_preview(player, "skin", preview)
|
||||
end
|
||||
|
||||
function mcl_player.player_set_armor(player, texture, preview)
|
||||
set_texture(player, 2, texture)
|
||||
set_preview(player, "armor", preview)
|
||||
end
|
||||
|
||||
function mcl_player.player_set_wielditem(player, texture)
|
||||
set_texture(player, 3, texture)
|
||||
end
|
||||
|
||||
function mcl_player.player_get_preview(player)
|
||||
local preview = player:get_meta():get_string("mcl_player:preview")
|
||||
if preview == nil or preview == "" then
|
||||
return "player.png"
|
||||
else
|
||||
return preview
|
||||
local preview = player:get_meta():get_string("mcl_player:skin_preview")
|
||||
if preview == "" then
|
||||
preview = "player.png"
|
||||
end
|
||||
local armor_preview = player:get_meta():set_string("mcl_player:armor_preview")
|
||||
if armor_preview ~= "" then
|
||||
preview = preview .. "^" .. armor_preview
|
||||
end
|
||||
return preview
|
||||
|
||||
end
|
||||
|
||||
function mcl_player.get_player_formspec_model(player, x, y, w, h, fsname)
|
||||
@ -129,8 +148,10 @@ end
|
||||
|
||||
-- Update appearance when the player joins
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
mcl_player.player_attached[player:get_player_name()] = false
|
||||
local name = player:get_player_name()
|
||||
mcl_player.player_attached[name] = false
|
||||
mcl_player.player_set_model(player, "character.b3d")
|
||||
player_textures[name] = {"blank.png", "blank.png", "blank.png"}
|
||||
--player:set_local_animation({x=0, y=79}, {x=168, y=187}, {x=189, y=198}, {x=200, y=219}, 30)
|
||||
player:set_fov(86.1) -- see <https://minecraft.gamepedia.com/Options#Video_settings>>>>
|
||||
end)
|
||||
|
@ -182,6 +182,8 @@ minetest.register_globalstep(function(dtime)
|
||||
local wielded = player:get_wielded_item()
|
||||
local player_velocity = player:get_velocity() or player:get_player_velocity()
|
||||
|
||||
local wielded_def = wielded:get_definition()
|
||||
|
||||
-- controls head bone
|
||||
local pitch = - degrees(player:get_look_vertical())
|
||||
local yaw = degrees(player:get_look_horizontal())
|
||||
@ -196,7 +198,7 @@ minetest.register_globalstep(function(dtime)
|
||||
if minetest.get_node_or_nil({x=player:get_pos().x, y=player:get_pos().y - 0.5, z=player:get_pos().z}) then
|
||||
node_stand_return = minetest.get_node_or_nil({x=player:get_pos().x, y=player:get_pos().y - 0.5, z=player:get_pos().z}).name
|
||||
else
|
||||
minetest.log("action", "somehow player got of loaded areas")
|
||||
-- minetest.log("action", "somehow player got of loaded areas")
|
||||
end
|
||||
|
||||
if player:get_inventory():get_stack("armor", 3):get_name() == "mcl_armor:elytra" and player_velocity.y < -6 and elytra[player] ~= true and is_sprinting(name) then
|
||||
@ -224,6 +226,14 @@ minetest.register_globalstep(function(dtime)
|
||||
playerphysics.remove_physics_factor(player, "gravity", "mcl_playerplus:elytra")
|
||||
end
|
||||
|
||||
if wielded_def and wielded_def._mcl_toollike_wield then
|
||||
player:set_bone_position("Wield_Item", vector.new(0,3.9,1.3), vector.new(90,0,0))
|
||||
elseif string.find(wielded:get_name(), "mcl_bows:bow") then
|
||||
player:set_bone_position("Wield_Item", vector.new(.5,4.5,-1.6), vector.new(90,0,20))
|
||||
else
|
||||
player:set_bone_position("Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(135,0,90))
|
||||
end
|
||||
|
||||
-- controls right and left arms pitch when shooting a bow
|
||||
if string.find(wielded:get_name(), "mcl_bows:bow") and controls.RMB and not controls.LMB and not controls.up and not controls.down and not controls.left and not controls.right then
|
||||
player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35))
|
||||
|
@ -7,7 +7,6 @@ mcl_skins = {
|
||||
}
|
||||
|
||||
local S = minetest.get_translator("mcl_skins")
|
||||
local has_mcl_armor = minetest.get_modpath("mcl_armor")
|
||||
local has_mcl_inventory = minetest.get_modpath("mcl_inventory")
|
||||
|
||||
-- load skin list and metadata
|
||||
@ -115,10 +114,6 @@ mcl_skins.set_player_skin = function(player, skin_id)
|
||||
mcl_skins.previews[playername] = preview
|
||||
player:get_meta():set_string("mcl_skins:skin_id", tostring(skin_id))
|
||||
mcl_skins.update_player_skin(player)
|
||||
if has_mcl_armor then
|
||||
armor.textures[playername].skin = skin_file
|
||||
armor:update_player_visuals(player)
|
||||
end
|
||||
if has_mcl_inventory then
|
||||
mcl_inventory.update_inventory_formspec(player)
|
||||
end
|
||||
@ -134,7 +129,7 @@ mcl_skins.update_player_skin = function(player)
|
||||
return
|
||||
end
|
||||
local playername = player:get_player_name()
|
||||
mcl_player.player_set_textures(player, { mcl_skins.skins[playername] .. ".png" }, mcl_skins.previews[playername] .. ".png" )
|
||||
mcl_player.player_set_skin(player, mcl_skins.skins[playername] .. ".png", mcl_skins.previews[playername] .. ".png")
|
||||
end
|
||||
|
||||
-- load player skin on join
|
||||
|
@ -2,4 +2,4 @@ name = mcl_skins
|
||||
author = TenPlus1
|
||||
description = Mod that allows players to set their individual skins.
|
||||
depends = mcl_player
|
||||
optional_depends = mcl_inventory, intllib, mcl_armor
|
||||
optional_depends = mcl_inventory, intllib
|
||||
|
122
mods/PLAYER/mcl_wieldview/init.lua
Normal file
122
mods/PLAYER/mcl_wieldview/init.lua
Normal file
@ -0,0 +1,122 @@
|
||||
mcl_wieldview = {
|
||||
players = {}
|
||||
}
|
||||
|
||||
function mcl_wieldview.get_item_texture(itemname)
|
||||
if itemname == "" then
|
||||
return
|
||||
end
|
||||
|
||||
local def = minetest.registered_items[itemname]
|
||||
if not def then
|
||||
return
|
||||
end
|
||||
|
||||
local inv_image = def.inventory_image
|
||||
if inv_image == "" then
|
||||
return
|
||||
end
|
||||
|
||||
local texture = inv_image
|
||||
|
||||
local transform = minetest.get_item_group(itemname, "wieldview_transform")
|
||||
if transform then
|
||||
-- This actually works with groups ratings because transform1, transform2, etc.
|
||||
-- have meaning and transform0 is used for identidy, so it can be ignored
|
||||
texture = texture .. "^[transform" .. transform
|
||||
end
|
||||
|
||||
return texture
|
||||
end
|
||||
|
||||
function mcl_wieldview.update_wielded_item(player)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
local name = player:get_player_name()
|
||||
local itemstack = player:get_wielded_item()
|
||||
local itemname = itemstack:get_name()
|
||||
|
||||
local def = mcl_wieldview.players[name]
|
||||
|
||||
if def.item == itemname then
|
||||
return
|
||||
end
|
||||
|
||||
def.item = itemname
|
||||
def.texture = mcl_wieldview.get_item_texture(itemname) or "blank.png"
|
||||
|
||||
mcl_player.player_set_wielditem(player, def.texture)
|
||||
end
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
mcl_wieldview.players[name] = {item = "", texture = "blank.png"}
|
||||
|
||||
minetest.after(0, function()
|
||||
if not player:is_player() then
|
||||
return
|
||||
end
|
||||
|
||||
mcl_wieldview.update_wielded_item(player)
|
||||
|
||||
local itementity = minetest.add_entity(player:get_pos(), "mcl_wieldview:wieldnode")
|
||||
itementity:set_attach(player, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 0, 45))
|
||||
itementity:get_luaentity().wielder = name
|
||||
end)
|
||||
end)
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
mcl_wieldview.players[name] = nil
|
||||
end)
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
for _, player in pairs(minetest.get_connected_players()) do
|
||||
mcl_wieldview.update_wielded_item(player)
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_entity("mcl_wieldview:wieldnode", {
|
||||
initial_properties = {
|
||||
hp_max = 1,
|
||||
visual = "wielditem",
|
||||
physical = false,
|
||||
textures = {""},
|
||||
automatic_rotate = 1.5,
|
||||
is_visible = true,
|
||||
pointable = false,
|
||||
collide_with_objects = false,
|
||||
static_save = false,
|
||||
collisionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21},
|
||||
selectionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21},
|
||||
visual_size = {x = 0.21, y = 0.21},
|
||||
},
|
||||
|
||||
itemstring = "",
|
||||
|
||||
on_step = function(self)
|
||||
local player = minetest.get_player_by_name(self.wielder)
|
||||
if player then
|
||||
local wielded = player:get_wielded_item()
|
||||
local itemstring = wielded:get_name()
|
||||
|
||||
if self.itemstring ~= itemstring then
|
||||
local def = minetest.registered_items[itemstring]
|
||||
self.object:set_properties({glow = def and def.light_source or 0})
|
||||
|
||||
-- wield item as cubic
|
||||
if mcl_wieldview.players[self.wielder].texture == "blank.png" then
|
||||
self.object:set_properties({textures = {itemstring}})
|
||||
-- wield item as flat
|
||||
else
|
||||
self.object:set_properties({textures = {""}})
|
||||
end
|
||||
|
||||
self.itemstring = itemstring
|
||||
end
|
||||
else
|
||||
self.object:remove()
|
||||
end
|
||||
end,
|
||||
})
|
@ -1,5 +1,4 @@
|
||||
name = wieldview
|
||||
name = mcl_wieldview
|
||||
author = stujones11
|
||||
description = Makes hand wielded items visible to other players.
|
||||
depends = mcl_armor
|
||||
|
||||
depends = mcl_player
|
@ -1,132 +0,0 @@
|
||||
local time = 0
|
||||
local update_time = tonumber(minetest.settings:get("wieldview_update_time"))
|
||||
if not update_time then
|
||||
update_time = 2
|
||||
minetest.settings:set("wieldview_update_time", tostring(update_time))
|
||||
end
|
||||
local node_tiles = minetest.settings:get_bool("wieldview_node_tiles")
|
||||
if not node_tiles then
|
||||
node_tiles = false
|
||||
minetest.settings:set("wieldview_node_tiles", "false")
|
||||
end
|
||||
|
||||
wieldview = {
|
||||
wielded_item = {},
|
||||
transform = {},
|
||||
}
|
||||
|
||||
dofile(minetest.get_modpath(minetest.get_current_modname()).."/transform.lua")
|
||||
|
||||
wieldview.get_item_texture = function(self, item)
|
||||
local texture = "blank.png"
|
||||
if item ~= "" then
|
||||
if minetest.registered_items[item] then
|
||||
if minetest.registered_items[item].inventory_image ~= "" then
|
||||
texture = minetest.registered_items[item].inventory_image
|
||||
elseif node_tiles == true and minetest.registered_items[item].tiles
|
||||
and type(minetest.registered_items[item].tiles[1]) == "string"
|
||||
and minetest.registered_items[item].tiles[1] ~= "" then
|
||||
texture = minetest.inventorycube(minetest.registered_items[item].tiles[1])
|
||||
end
|
||||
end
|
||||
-- Get item image transformation, first from group, then from transform.lua
|
||||
local transform = minetest.get_item_group(item, "wieldview_transform")
|
||||
if transform == 0 then
|
||||
transform = wieldview.transform[item]
|
||||
end
|
||||
if transform then
|
||||
-- This actually works with groups ratings because transform1, transform2, etc.
|
||||
-- have meaning and transform0 is used for identidy, so it can be ignored
|
||||
texture = texture.."^[transform"..tostring(transform)
|
||||
end
|
||||
end
|
||||
return texture
|
||||
end
|
||||
|
||||
wieldview.update_wielded_item = function(self, player)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
local name = player:get_player_name()
|
||||
local stack = player:get_wielded_item()
|
||||
local item = stack:get_name()
|
||||
if not item then
|
||||
return
|
||||
end
|
||||
if self.wielded_item[name] then
|
||||
if self.wielded_item[name] == item then
|
||||
return
|
||||
end
|
||||
if not armor.textures[name] then
|
||||
return
|
||||
end
|
||||
armor.textures[name].wielditem = self:get_item_texture(item)
|
||||
armor:update_player_visuals(player)
|
||||
end
|
||||
self.wielded_item[name] = item
|
||||
end
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
wieldview.wielded_item[name] = ""
|
||||
minetest.after(0, function(player)
|
||||
-- if the player left :is_player() will return nil
|
||||
if not player:is_player() then
|
||||
return
|
||||
end
|
||||
wieldview:update_wielded_item(player)
|
||||
local itementity = minetest.add_entity(player:get_pos(), "wieldview:wieldnode")
|
||||
itementity:set_attach(player, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 0, 45))
|
||||
itementity:get_luaentity().wielder = name
|
||||
end, player)
|
||||
end)
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
for _,player in pairs(minetest.get_connected_players()) do
|
||||
wieldview:update_wielded_item(player)
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_entity("wieldview:wieldnode", {
|
||||
initial_properties = {
|
||||
hp_max = 1,
|
||||
visual = "wielditem",
|
||||
physical = false,
|
||||
textures = {""},
|
||||
automatic_rotate = 1.5,
|
||||
is_visible = true,
|
||||
pointable = false,
|
||||
collide_with_objects = false,
|
||||
static_save = false,
|
||||
collisionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21},
|
||||
selectionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21},
|
||||
visual_size = {x = 0.21, y = 0.21},
|
||||
},
|
||||
|
||||
itemstring = "",
|
||||
|
||||
on_step = function(self)
|
||||
local player = minetest.get_player_by_name(self.wielder)
|
||||
if player then
|
||||
local wielded = player:get_wielded_item()
|
||||
local itemstring = wielded:get_name()
|
||||
|
||||
if self.itemstring ~= itemstring then
|
||||
local def = minetest.registered_items[itemstring]
|
||||
self.object:set_properties({glow = def and def.light_source or 0})
|
||||
|
||||
-- wield item as cubic
|
||||
if armor.textures[self.wielder].wielditem == "blank.png" then
|
||||
self.object:set_properties({textures = {itemstring}})
|
||||
-- wield item as flat
|
||||
else
|
||||
self.object:set_properties({textures = {""}})
|
||||
end
|
||||
|
||||
self.itemstring = itemstring
|
||||
end
|
||||
else
|
||||
self.object:remove()
|
||||
end
|
||||
end,
|
||||
})
|
@ -1,10 +0,0 @@
|
||||
-- Wielded Item Transformations - http://dev.minetest.net/texture
|
||||
|
||||
wieldview.transform = {
|
||||
["screwdriver:screwdriver"]="R90",
|
||||
["screwdriver:screwdriver1"]="R90",
|
||||
["screwdriver:screwdriver2"]="R90",
|
||||
["screwdriver:screwdriver3"]="R90",
|
||||
["screwdriver:screwdriver4"]="R90",
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user