Compare commits

..

9 Commits

67 changed files with 1833 additions and 1337 deletions

View File

@ -1,111 +0,0 @@
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.modifiers, {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" and mt_reason.node then
if minetest.get_item_group(mt_reason.node, "fire") > 0 then
mcl_reason.type = "in_fire"
end
if minetest.get_item_group(mt_reason.node, "lava") > 0 then
mcl_reason.type = "lava"
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]
return mcl_reason
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)

View File

@ -1,3 +0,0 @@
name = mcl_damage
author = Fleckenstein
description = Minecraft-like damage reason system

View File

@ -150,8 +150,7 @@ end
-- raydirs - The directions for each ray
-- radius - The maximum distance each ray will go
-- info - Table containing information about explosion
-- direct - direct source object of the damage (optional)
-- source - indirect source object of the damage (optional)
-- puncher - object that punches other objects (optional)
--
-- Values in info:
-- drop_chance - The chance that destroyed nodes will drop their items
@ -166,7 +165,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, direct, source)
local function trace_explode(pos, strength, raydirs, radius, info, puncher)
local vm = get_voxel_manip()
local emin, emax = vm:read_from_map(vector.subtract(pos, radius),
@ -248,7 +247,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc
local ent = obj:get_luaentity()
-- Ignore items to lower lag
if (obj:is_player() or (ent and ent.name ~= '__builtin.item')) and obj:get_hp() > 0 then
if obj:is_player() or (ent and ent.name ~= '__builtin.item') then
local opos = obj:get_pos()
local collisionbox = nil
@ -322,6 +321,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc
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,22 +336,23 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc
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() -- 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})
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)
end, obj, damage, impact, vector.new(punch_dir))
else
mcl_util.deal_damage(obj, damage, {type = "explosion", direct = direct, source = source})
obj:punch(source, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir)
if obj:is_player() or ent.tnt_knockback then
if obj:is_player() then
obj:add_velocity(vector.multiply(punch_dir, impact * 20))
elseif ent.tnt_knockback then
obj:add_velocity(vector.multiply(punch_dir, impact * 20))
end
end
@ -421,8 +422,7 @@ 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
-- direct - direct source object of the damage (optional)
-- source - indirect source object of the damage (optional)
-- puncher - object that is reported as source of punches/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, direct, source)
function mcl_explosions.explode(pos, strength, info, puncher)
if info == nil then
info = {}
end
@ -465,7 +465,7 @@ function mcl_explosions.explode(pos, strength, info, direct, source)
info.drop_chance = 0
end
trace_explode(pos, strength, shape, radius, info, direct, source)
trace_explode(pos, strength, shape, radius, info, puncher)
if info.particles then
add_particles(pos, radius)

View File

@ -418,99 +418,3 @@ 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

View File

@ -92,6 +92,7 @@ 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
@ -106,7 +107,12 @@ function mcl_burning.damage(obj)
end
if do_damage then
mcl_util.deal_damage(obj, 1, {type = "on_fire"})
local new_hp = hp - 1
if health then
luaentity.health = new_hp
else
obj:set_hp(new_hp)
end
end
end

View File

@ -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 = mcl_armor.get_mob_view_range_factor(object, self.name)
factor = 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)
]]--
]]--

View File

@ -147,10 +147,12 @@ 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,

View File

@ -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,9 +97,11 @@ 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},

View File

@ -30,13 +30,14 @@ local skeleton = {
"mcl_bows_bow_0.png", -- bow
"mobs_mc_skeleton.png", -- skeleton
} },
visual_size = {x=3, y=3},
visual_size = {x=1, y=1},
makes_footstep_sound = true,
sounds = {
random = "mobs_mc_skeleton_random",
death = "mobs_mc_skeleton_death",
damage = "mobs_mc_skeleton_hurt",
distance = 16,
textures = {
{
"mobs_mc_empty.png", -- armor
"mobs_mc_skeleton.png", -- texture
"mcl_bows_bow_0.png", -- wielded_item
}
},
walk_velocity = 1.2,
run_velocity = 2.4,
@ -111,9 +112,9 @@ local stray = table.copy(skeleton)
stray.mesh = "mobs_mc_stray.b3d"
stray.textures = {
{
"mcl_bows_bow_0.png",
"mobs_mc_stray.png",
"mobs_mc_stray_overlay.png",
"mobs_mc_stray.png",
"mcl_bows_bow_0.png",
},
}
-- TODO: different sound (w/ echo)
@ -140,8 +141,8 @@ mobs:register_mob("mobs_mc:stray", stray)
-- Overworld spawn
mobs:spawn_specific(
"mobs_mc:skeleton",
"overworld",
"mobs_mc:skeleton",
"overworld",
"ground",
{
"Mesa",
@ -284,36 +285,36 @@ mobs:spawn_specific(
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
7,
20,
17000,
2,
mobs_mc.spawn_height.overworld_min,
0,
7,
20,
17000,
2,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
-- Nether spawn
mobs:spawn_specific(
"mobs_mc:skeleton",
"nether",
"ground",
"mobs_mc:skeleton",
"nether",
"ground",
{
"Nether"
},
0,
7,
30,
10000,
3,
mobs_mc.spawn_height.nether_min,
0,
7,
30,
10000,
3,
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
-- Stray spawn
-- TODO: Spawn directly under the sky
mobs:spawn_specific(
"mobs_mc:stray",
"overworld",
"mobs_mc:stray",
"overworld",
"ground",
{
"ColdTaiga",
@ -321,12 +322,12 @@ mobs:spawn_specific(
"IcePlains",
"ExtremeHills+_snowtop",
},
0,
7,
20,
19000,
2,
mobs_mc.spawn_height.water,
0,
7,
20,
19000,
2,
mobs_mc.spawn_height.water,
mobs_mc.spawn_height.overworld_max)

View File

@ -25,11 +25,12 @@ mobs:register_mob("mobs_mc:witherskeleton", {
mesh = "mobs_mc_witherskeleton.b3d",
textures = {
{
"default_tool_stonesword.png", -- sword
"mobs_mc_empty.png", -- armor
"mobs_mc_wither_skeleton.png", -- wither skeleton
"default_tool_stonesword.png", -- sword
}
},
visual_size = {x=3.6, y=3.6},
visual_size = {x=1.2, y=1.2},
makes_footstep_sound = true,
sounds = {
random = "mobs_mc_skeleton_random",
@ -110,4 +111,4 @@ mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
-- spawn eggs
mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0)
mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0)

View File

@ -58,7 +58,11 @@ local zombie = {
visual = "mesh",
mesh = "mobs_mc_zombie.b3d",
textures = {
{"mobs_mc_zombie.png"},
{
"mobs_mc_empty.png", -- armor
"mobs_mc_zombie.png", -- texture
"mobs_mc_empty.png", -- wielded_item
}
},
visual_size = {x=3, y=3},
makes_footstep_sound = true,
@ -111,7 +115,13 @@ mobs:register_mob("mobs_mc:baby_zombie", baby_zombie)
-- Husk.
-- Desert variant of the zombie
local husk = table.copy(zombie)
husk.textures = {{"mobs_mc_husk.png"}}
husk.textures = {
{
"mobs_mc_empty.png", -- armor
"mobs_mc_husk.png", -- texture
"mobs_mc_empty.png", -- wielded_item
}
}
husk.ignited_by_sunlight = false
husk.sunlight_damage = 0
husk.drops = drops_common
@ -136,8 +146,8 @@ mobs:register_mob("mobs_mc:baby_husk", baby_husk)
-- Spawning
mobs:spawn_specific(
"mobs_mc:zombie",
"overworld",
"mobs_mc:zombie",
"overworld",
"ground",
{
"FlowerForest_underground",
@ -220,17 +230,17 @@ mobs:spawn_specific(
"MesaBryce_sandlevel",
"Mesa_sandlevel",
},
0,
7,
30,
6000,
4,
mobs_mc.spawn_height.overworld_min,
0,
7,
30,
6000,
4,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
-- Baby zombie is 20 times less likely than regular zombies
mobs:spawn_specific(
"mobs_mc:baby_zombie",
"overworld",
"mobs_mc:baby_zombie",
"overworld",
"ground",
{
"FlowerForest_underground",
@ -313,18 +323,18 @@ mobs:spawn_specific(
"MesaBryce_sandlevel",
"Mesa_sandlevel",
},
0,
7,
30,
60000,
4,
mobs_mc.spawn_height.overworld_min,
0,
7,
30,
60000,
4,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific(
"mobs_mc:husk",
"overworld",
"mobs_mc:husk",
"overworld",
"ground",
{
"Desert",
@ -332,29 +342,29 @@ mobs:spawn_specific(
"Savanna",
"Savanna_beach",
},
0,
7,
30,
6500,
4,
mobs_mc.spawn_height.overworld_min,
0,
7,
30,
6500,
4,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific(
"mobs_mc:baby_husk",
"overworld",
"ground",
"mobs_mc:baby_husk",
"overworld",
"ground",
{
"Desert",
"SavannaM",
"Savanna",
"Savanna_beach",
},
0,
7,
30,
65000,
4,
mobs_mc.spawn_height.overworld_min,
0,
7,
30,
65000,
4,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
-- Spawn eggs

View File

@ -139,42 +139,48 @@ lightning.strike = function(pos)
for o=1, #objs do
local obj = objs[o]
local lua = obj:get_luaentity()
-- pig → zombie pigman (no damage)
if lua and lua.name == "mobs_mc:pig" then
local rot = obj:get_yaw()
obj:remove()
obj = add_entity(pos2, "mobs_mc:pigman")
obj:set_yaw(rot)
-- mooshroom: toggle color red/brown (no damage)
elseif lua and lua.name == "mobs_mc:mooshroom" then
if lua.base_texture[1] == "mobs_mc_mooshroom.png" then
lua.base_texture = { "mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" }
else
lua.base_texture = { "mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png" }
end
obj:set_properties({textures = lua.base_texture})
-- villager → witch (no damage)
elseif lua and lua.name == "mobs_mc:villager" then
-- Witches are incomplete, this code is unused
-- TODO: Enable this code when witches are working.
--[[
local rot = obj:get_yaw()
obj:remove()
obj = minetest.add_entity(pos2, "mobs_mc:witch")
obj:set_yaw(rot)
]]
-- charged creeper
elseif lua and lua.name == "mobs_mc:creeper" then
local rot = obj:get_yaw()
obj:remove()
obj = add_entity(pos2, "mobs_mc:creeper_charged")
obj:set_yaw(rot)
-- Other objects: Just damage
else
if obj:is_player() and has_mcl_death_msg then
if obj:is_player() then
-- Player damage
if has_mcl_death_msg then
mcl_death_messages.player_damage(obj, S("@1 was struck by lightning.", obj:get_player_name()))
end
mcl_util.deal_damage(obj, 5, {type = "lightning_bolt"})
obj:set_hp(obj:get_hp()-5, { type = "punch", from = "mod" })
-- Mobs
elseif lua and lua._cmi_is_mob then
-- pig → zombie pigman (no damage)
if lua.name == "mobs_mc:pig" then
local rot = obj:get_yaw()
obj:remove()
obj = add_entity(pos2, "mobs_mc:pigman")
obj:set_yaw(rot)
-- mooshroom: toggle color red/brown (no damage)
elseif lua.name == "mobs_mc:mooshroom" then
if lua.base_texture[1] == "mobs_mc_mooshroom.png" then
lua.base_texture = { "mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" }
else
lua.base_texture = { "mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png" }
end
obj:set_properties({textures = lua.base_texture})
-- villager → witch (no damage)
elseif lua.name == "mobs_mc:villager" then
-- Witches are incomplete, this code is unused
-- TODO: Enable this code when witches are working.
--[[
local rot = obj:get_yaw()
obj:remove()
obj = minetest.add_entity(pos2, "mobs_mc:witch")
obj:set_yaw(rot)
]]
-- charged creeper
elseif lua.name == "mobs_mc:creeper" then
local rot = obj:get_yaw()
obj:remove()
obj = add_entity(pos2, "mobs_mc:creeper_charged")
obj:set_yaw(rot)
-- Other mobs: Just damage
else
obj:set_hp(obj:get_hp()-5, { type = "punch", from = "mod" })
end
end
end

View File

@ -40,6 +40,7 @@ minetest.register_on_mods_loaded(function()
end
self._void_timer = 0
local pos = obj:get_pos()
local void, void_deadly = is_in_void(pos)
if void_deadly then
local ent = obj:get_luaentity()
@ -80,7 +81,7 @@ minetest.register_globalstep(function(dtime)
-- Damage enabled, not immortal: Deal void damage (4 HP / 0.5 seconds)
if player:get_hp() > 0 then
death_msg(player, S("@1 fell into the endless void.", player:get_player_name()))
mcl_util.deal_damage(player, VOID_DAMAGE, {type = "out_of_world"})
player:set_hp(player:get_hp() - VOID_DAMAGE)
end
end
end

View File

@ -263,7 +263,34 @@ 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 = mcl_util.calculate_durability(itemstack)
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 multiplier = 2 * 65535 / uses
local repair = experience * multiplier
local new_wear = wear - repair

View File

@ -1,5 +1,9 @@
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
@ -56,8 +60,11 @@ 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 = player:get_meta():get_int("mcl_armor:armor_points")
local pts = armor:get_armor_points(player)
if not pts then
return false
else

View File

@ -7,7 +7,8 @@ local players = {}
-- Containing all the items for each Creative Mode tab
local inventory_lists = {}
+local mod_player = minetest.get_modpath("mcl_player") ~= nil
local show_armor = minetest.get_modpath("mcl_armor") ~= 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"}
@ -333,7 +334,23 @@ 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
player_preview = "image[3.9,1.4;1.2333,2.4666;"..mcl_player.player_get_preview(player).."]"
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
end
-- Background images for armor slots (hide if occupied)
@ -356,10 +373,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[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]"..
"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]"..
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)..

View File

@ -3,6 +3,7 @@ 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
@ -67,7 +68,23 @@ 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
player_preview = "image[1.1,0.2;2,4;"..mcl_player.player_get_preview(player).."]"
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
end
local armor_slots = {"helmet", "chestplate", "leggings", "boots"}
@ -82,10 +99,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[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]"..
"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]"..
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)..
@ -116,10 +133,10 @@ local function set_inventory(player, armor_change_only)
"tooltip[__mcl_achievements;"..F(S("Achievements")).."]"..
-- for shortcuts
"listring[current_player;main]"..
"listring[current_player;armor]"..
"listring[current_player;main]" ..
"listring[current_player;craft]" ..
"listring[current_player;main]"
"listring[current_player;craft]"..
"listring[current_player;main]"..
"listring[detached:"..player_name.."_armor;armor]"
player:set_inventory_formspec(form)
end
@ -159,10 +176,18 @@ 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")
local old_update_player = mcl_armor.update_player
mcl_armor.update_player = function(player, info)
old_update_player(player, info)
set_inventory(player, true)
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)
end
-- In Creative Mode, the initial inventory setup is handled in creative.lua

View File

@ -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)
mcl_armor.play_equip_sound(dropitem, nil, standpos)
armor:play_equip_sound(dropitem, nil, standpos)
armor_dispensed = true
end
else
@ -202,8 +202,9 @@ 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)
mcl_armor.update(player)
mcl_armor.play_equip_sound(dropitem, player)
armor:set_player_armor(player)
armor:update_inventory(player)
armor:play_equip_sound(dropitem, player)
stack:take_item()
inv:set_stack("main", stack_id, stack)

View File

@ -1,232 +0,0 @@
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

View File

@ -0,0 +1,675 @@
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)

View File

@ -1,99 +0,0 @@
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 = inv:get_stack("armor", element.index)
if not itemstack:is_empty() then
local itemname = itemstack: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)
inv: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)
inv:set_stack("armor", thorns_item.index, thorns_item.itemstack)
end
mcl_armor.update(obj)
return -math.floor(damage + 0.5)
end

View File

@ -1,67 +1,405 @@
local S = minetest.get_translator("mcl_armor")
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,
}
}
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"} ,
}
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")
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

View File

@ -1,145 +0,0 @@
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)
mcl_damage.register_modifier(function(player, hp_change, _, reason)
return mcl_armor.damage_modifier(player, hp_change, reason)
end)

View File

@ -1,204 +0,0 @@
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",
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 746 B

After

Width:  |  Height:  |  Size: 271 B

View File

@ -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)
mcl_armor.play_equip_sound(single_item, nil, pos)
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
mcl_armor.play_equip_sound(stand_armor, nil, pos, true)
armor:play_equip_sound(stand_armor, nil, pos, true)
stand_armor:take_item()
inv:set_stack("armor_" .. elements[e], 1, stand_armor)
end

View File

@ -35,6 +35,49 @@ mcl_banners.colors = {
["unicolor_light_blue"] = {"light_blue", S("Light Blue Banner"), "mcl_wool:light_blue", "#4040CF", "mcl_dye:lightblue", N("Light Blue") },
}
local pattern_names = {
"",
"border",
"bricks",
"circle",
"creeper",
"cross",
"curly_border",
"diagonal_up_left",
"diagonal_up_right",
"diagonal_right",
"diagonal_left",
"flower",
"gradient",
"gradient_up",
"half_horizontal_bottom",
"half_horizontal",
"half_vertical",
"half_vertical_right",
"thing",
"rhombus",
"skull",
"small_stripes",
"square_bottom_left",
"square_bottom_right",
"square_top_left",
"square_top_right",
"straight_cross",
"stripe_bottom",
"stripe_center",
"stripe_downleft",
"stripe_downright",
"stripe_left",
"stripe_middle",
"stripe_right",
"stripe_top",
"triangle_bottom",
"triangle_top",
"triangles_bottom",
"triangles_top",
}
local colors_reverse = {}
for k,v in pairs(mcl_banners.colors) do
colors_reverse["mcl_banners:banner_item_"..v[1]] = k
@ -300,24 +343,72 @@ minetest.register_node("mcl_banners:hanging_banner", {
end,
})
-- for pattern_name, pattern in pairs(patterns) do
for colorid, colortab in pairs(mcl_banners.colors) do
for i, pattern_name in ipairs(pattern_names) do
local itemid = colortab[1]
local desc = colortab[2]
local wool = colortab[3]
local colorize = colortab[4]
local itemstring = "mcl_banners:banner_item_"..itemid
local inv
if colorize then
inv = "mcl_banners_item_base.png^(mcl_banners_item_overlay.png^[colorize:"..colorize..")"
local itemstring
if pattern_name == "" then
itemstring = "mcl_banners:banner_item_" .. itemid
else
inv = "mcl_banners_item_base.png^mcl_banners_item_overlay.png"
itemstring = "mcl_banners:banner_preview" .. "_" .. pattern_name .. "_" .. itemid
end
local inv
local base
local finished_banner
if pattern_name == "" then
if colorize then
-- Base texture with base color
base = "mcl_banners_item_base.png^(mcl_banners_item_overlay.png^[colorize:"..colorize..")^[resize:32x32"
else
base = "mcl_banners_item_base.png^mcl_banners_item_overlay.png^[resize:32x32"
end
finished_banner = base
else
-- Banner item preview background
base = "mcl_banners_item_base.png^(mcl_banners_item_overlay.png^[colorize:#CCCCCC)^[resize:32x32"
desc = S("Preview Banner")
local pattern = "mcl_banners_" .. pattern_name .. ".png"
local color = colorize
-- Generate layer texture
-- TODO: The layer texture in the icon is squished
-- weirdly because the width/height aspect ratio of
-- the banner icon is 1:1.5, whereas the aspect ratio
-- of the banner entity is 1:2. A solution would be to
-- redraw the pattern textures as low-resolution pixel
-- art and use that instead.
local layer = "(([combine:20x40:-2,-2="..pattern.."^[resize:16x24^[colorize:"..color..":"..layer_ratio.."))"
function escape(text)
return text:gsub("%^", "\\%^"):gsub(":", "\\:") -- :gsub("%(", "\\%("):gsub("%)", "\\%)")
end
finished_banner = "[combine:32x32:0,0=" .. escape(base) .. ":8,4=" .. escape(layer)
end
inv = finished_banner
-- Banner items.
-- This is the player-visible banner item. It comes in 16 base colors.
-- This is the player-visible banner item. It comes in 16 base colors with a lot of patterns.
-- The multiple items are really only needed for the different item images.
-- TODO: Combine the items into only 1 item.
local groups
if pattern_name == "" then
groups = { banner = 1, deco_block = 1, flammable = -1 }
else
groups = { not_in_creative_inventory = 1 }
end
minetest.register_craftitem(itemstring, {
description = desc,
_tt_help = S("Paintable decoration"),
@ -326,7 +417,7 @@ for colorid, colortab in pairs(mcl_banners.colors) do
wield_image = inv,
-- Banner group groups together the banner items, but not the nodes.
-- Used for crafting.
groups = { banner = 1, deco_block = 1, flammable = -1 },
groups = groups,
stack_max = 16,
on_place = function(itemstack, placer, pointed_thing)
@ -492,6 +583,7 @@ for colorid, colortab in pairs(mcl_banners.colors) do
-- Add item to node alias
doc.add_entry_alias("nodes", "mcl_banners:standing_banner", "craftitems", itemstring)
end
end
end
if minetest.get_modpath("doc") then

View File

@ -253,6 +253,11 @@ for colorid, colortab in pairs(mcl_banners.colors) do
dye_to_colorid_mapping[colortab[5]] = colorid
end
local dye_to_itemid_mapping = {}
for colorid, colortab in pairs(mcl_banners.colors) do
dye_to_itemid_mapping[colortab[5]] = colortab[1]
end
-- Create a banner description containing all the layer names
mcl_banners.make_advanced_banner_description = function(description, layers)
if layers == nil or #layers == 0 then
@ -491,7 +496,14 @@ local banner_pattern_craft = function(itemstack, player, old_craft_grid, craft_i
imeta:set_string("description", ometa:get_string("description"))
imeta:set_string("name", mname)
end
return itemstack
if craft_predict then
local itemid_prefix = "mcl_banners:banner_preview"
local coloritemid = dye_to_itemid_mapping[dye]
return ItemStack(itemid_prefix .. "_" .. matching_pattern .. "_" .. coloritemid)
else
return itemstack
end
end
minetest.register_craft_predict(function(itemstack, player, old_craft_grid, craft_inv)

View File

@ -69,7 +69,6 @@ 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
@ -255,6 +254,9 @@ 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

View File

@ -59,7 +59,6 @@ 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

View File

@ -1,4 +1,4 @@
# textdomain: mcl_compass
Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Kompasse sind Werkzeuge, die zum Ursprungspunkt der Welt (X@=0, Z@=0) oder den Einstiegspunkt der Welt zeigen.
Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Kompasse sind Werkzeuge, die zum Ursprungspunkt der Welt (X@=0, Z@=0) oder zum Einstiegspunkt der Welt zeigen.
Compass=Kompass
Points to the world origin=Zeigt zum Startpunkt der Welt

View File

@ -190,6 +190,22 @@ minetest.register_abm({
end,
})
-- Make cactus destroy items
minetest.register_abm({
label = "Cactus destroy items",
nodenames = {"mcl_core:cactus"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
for _,object in pairs(minetest.get_objects_inside_radius(pos, 0.9)) do
if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then
object:remove()
end
end
end,
})
minetest.register_abm({
label = "Sugar canes growth",
nodenames = {"mcl_core:reeds"},

View File

@ -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, fire_damage=1},
groups = { lava=3, lava_source=1, liquid=2, destroys_items=1, not_in_creative_inventory=1, dig_by_piston=1, set_on_fire=15},
_mcl_blast_resistance = 100,
-- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode
_mcl_hardness = -1,

View File

@ -16,9 +16,9 @@ Birch Trapdoor=Birkenfalltür
Spruce Trapdoor=Fichtenfalltür
Dark Oak Trapdoor=Schwarzeichenfalltür
Jungle Trapdoor=Dschungelfalltür
Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder.=Holzfalltüren sind horizontale Barrieren, die von Hand oder mit einem Redstone-Signal geöffnet oder geschlossen werden können. Sie belegen den oberen oder unteren Teil eines Blocks, je nach dem, wie sie platziert wurden. Wenn geöffnet, können sie wie eine Leiter erklommen werden.
Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder.=Holzfalltüren sind horizontale Barrieren, die von Hand oder mit einem Redstone-Signal geöffnet oder geschlossen werden können. Sie belegen den oberen oder unteren Teil eines Blocks, je nachdem, wie sie platziert wurden. Wenn geöffnet, können sie wie eine Leiter erklommen werden.
To open or close the trapdoor, rightclick it or send a redstone signal to it.=Um die Falltür zu öffnen oder zu schließen, rechtsklicken Sie sie oder schicken Sie ein Redstone-Signal zu ihr.
Iron Trapdoor=Eisenfalltür
Iron trapdoors are horizontal barriers which can only be opened and closed by redstone signals, but not by hand. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder.=Eisenfalltüren sind horizontale Barrieren, die nur mit einem Redstone-Signal geöffnet oder geschlossen werden können, nicht von Hand. Sie belegen den oberen oder unteren Teil eines Blocks, je nach dem, wie sie platziert wurden. Wenn geöffnet, können sie wie eine Leiter erklommen werden.
Iron trapdoors are horizontal barriers which can only be opened and closed by redstone signals, but not by hand. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder.=Eisenfalltüren sind horizontale Barrieren, die nur mit einem Redstone-Signal geöffnet oder geschlossen werden können, nicht von Hand. Sie belegen den oberen oder unteren Teil eines Blocks, je nachdem, wie sie platziert wurden. Wenn geöffnet, können sie wie eine Leiter erklommen werden.
Openable by players and redstone power=Zu öffnen von Spielern und Redstoneenergie
Openable by redstone power=Zu öffnen von Redstoneenergie

View File

@ -10,6 +10,25 @@ 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"),
@ -29,6 +48,25 @@ 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"),
@ -48,6 +86,25 @@ mcl_enchanting.enchantments.bane_of_arthropods = {
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"),
@ -107,6 +164,24 @@ 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"),
@ -138,6 +213,25 @@ 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,
@ -436,6 +530,44 @@ 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"),
@ -607,6 +739,25 @@ 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"),

View File

@ -266,8 +266,7 @@ 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._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.texture = itemdef.texture or itemname:gsub("%:", "_")
new_def._mcl_enchanting_enchanted_tool = new_name
new_def.after_use = get_after_use_callback(itemdef)
local register_list = register_item_list

View File

@ -17,8 +17,8 @@ Efficiency=Effizienz
Increases mining speed.=Erhöht Grabegeschwindigkeit.
Feather Falling=Federfall
Reduces fall damage.=Reduziert Fallschaden.
Fire Aspect=Feieraspekt
Sets target on fire.=Zündes das Ziel an.
Fire Aspect=Feueraspekt
Sets target on fire.=Zündet das Ziel an.
Fire Protection=Feuerschutz
Reduces fire damage.=Reduziert Feuerschaden
Flame=Flamme
@ -31,7 +31,7 @@ Impaling=Aufspießen
Trident deals additional damage to ocean mobs.=Dreizack richtet Zusatzschaden an Ozeanmobs an.
Infinity=Unendlichkeit
Shooting consumes no regular arrows.=Schüsse verbrauchen keine regulären Pfeile.
Knockback=Rückschlag.
Knockback=Rückschlag
Increases knockback.=Verstärkt Rückschlag.
Looting=Plünderer
Increases mob loot.=Erhöht Abwürfe von Mobs.
@ -43,7 +43,7 @@ Lure=Köder
Decreases time until rod catches something.=Reduziert die Zeit, bis die Angel etwas fängt.
Mending=Ausbessern
Repair the item while gaining XP orbs.=Gegenstand reparieren, während man Erfahrungskugeln erhält.
Multishot=Mehrschuss
Multishot=Mehrfachschuss
Shoot 3 arrows at the cost of one.=3 Pfeile zum Preis von 1 schießen.
Piercing=Durchbohren
Arrows passes through multiple objects.=Pfeile durchdringen mehrere Objekte.
@ -74,7 +74,7 @@ Increases sweeping attack damage.=Erhöht Schwungangriffsschaden.
Thorns=Dornen
Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Reflektiert etwas des Schadens beim Erleiden eines Treffers, auf Kosten der Haltbarkeit.
Unbreaking=Haltbarkeit
Increases item durability.=Erhöht Haldbarkeit des Gegenstands.
Increases item durability.=Erhöht Haltbarkeit des Gegenstands.
Inventory=Inventar
@1 Lapis Lazuli=@1 Lapislazuli
@1 Enchantment Levels=@1 Verzauberungsstufen

View File

@ -111,16 +111,12 @@ 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 = mcl_armor.equip_on_use
pumpkin_face_base_def.on_secondary_use = armor.on_armor_use
end
-- Register stem growth

View File

@ -1,6 +1,6 @@
# textdomain: mcl_fences
Fences are structures which block the way. Fences will connect to each other and solid blocks. They cannot be jumped over with a simple jump.=Zäune sind Gebäude, die den Weg blockieren. Sie verbinden sich gegenseitig und anderen festen Blöcken. Man kann sie nicht mit normalen Sprüngen überspringen.
Fence gates can be opened or closed and can't be jumped over. Fences will connect nicely to fence gates.=Zauntore können geöffnet und geschlossen werden und können nicht übersprungen werden. Zäune werden sich gut mit Zauntoren verbinden.
Fence gates can be opened or closed and can't be jumped over. Fences will connect nicely to fence gates.=Zauntore können geöffnet und geschlossen werden und können nicht übersprungen werden. Zäune lassen sich gut mit Zauntoren verbinden.
Right-click the fence gate to open or close it.=Rechtsklicken Sie auf ein Zauntor, um es zu öffnen oder zu schließen.
Oak Fence=Eichenzaun
Oak Fence Gate=Eichenzauntor

View File

@ -7,12 +7,12 @@ Raw fish is obtained by fishing and is a food item which can be eaten safely. Co
Cooked Fish=Gekochter Fisch
Mmh, fish! This is a healthy food item.=Mhh, Fisch! Ein gesundes Lebensmittel.
Raw Salmon=Roher Lachs
Raw salmon is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=Lohen Lachs erhält man beim Angeln. Er ist ein Lebensmittel, der sicher verzehrt werden kann.
Raw salmon is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=Rohen Lachs erhält man beim Angeln. Er ist ein Lebensmittel, das sicher verzehrt werden kann.
Cooked Salmon=Gekochter Lachs
This is a healthy food item which can be eaten.=Ein gesundes essbares Lebensmittel.
Clownfish=Clownfisch
Clownfish may be obtained by fishing (and luck) and is a food item which can be eaten safely.=Einen Clownfisch kann man beim Angeln mit etwas Glück fangen. Er ist ein Lebensmittel, der sicher verzehrt werden kann.
Clownfish may be obtained by fishing (and luck) and is a food item which can be eaten safely.=Einen Clownfisch kann man beim Angeln mit etwas Glück fangen. Er ist ein Lebensmittel, das sicher verzehrt werden kann.
Pufferfish=Kugelfisch
Pufferfish are a common species of fish and can be obtained by fishing. They can technically be eaten, but they are very bad for humans. Eating a pufferfish only restores 1 hunger point and will poison you very badly (which drains your health non-fatally) and causes serious food poisoning (which increases your hunger).=Kugelfische sind eine verbreitete Fischart, die geangelt werden können. Sie können theoretisch gegessen werden, aber sie sind sehr schlecht für Menschen. Es gibt nur 1 Hungerpunkt und es wird Sie schwer vergiften (was Ihre Gesundheit verringert, aber nicht bis zum Tod) und Ihr Hungerpegel wird aufgrund der schweren Lebensmittelvergiftung stark ansteigen.
Pufferfish are a common species of fish and can be obtained by fishing. They can technically be eaten, but they are very bad for humans. Eating a pufferfish only restores 1 hunger point and will poison you very badly (which drains your health non-fatally) and causes serious food poisoning (which increases your hunger).=Kugelfische sind eine verbreitete Fischart, die geangelt werden kann. Sie können theoretisch gegessen werden, aber sie sind sehr schlecht für Menschen. Es gibt nur 1 Hungerpunkt und es wird Sie schwer vergiften (was Ihre Gesundheit verringert, aber nicht bis zum Tod) und Ihr Hungerpegel wird aufgrund der schweren Lebensmittelvergiftung stark ansteigen.
Catches fish in water=Fängt Fische im Wasser
Very poisonous=Sehr giftig

View File

@ -12,9 +12,9 @@ Allium=Sternlauch
Azure Bluet=Porzellansternchen
Blue Orchid=Blaue Orchidee
Tall Grass=Hohes Gras
Tall grass is a small plant which often occurs on the surface of grasslands. It can be harvested for wheat seeds. By using bone meal, tall grass can be turned into double tallgrass which is two blocks high.=Hohes Gras ist eine kleine Pflanze, die oft auf Wiesenflächen wächst. Es kann für Weizensamen abgeerntet werden. Mit Knochenmehl wird sich hohes Gras zu doppelhohem Gras verwandeln.
Tall grass is a small plant which often occurs on the surface of grasslands. It can be harvested for wheat seeds. By using bone meal, tall grass can be turned into double tallgrass which is two blocks high.=Hohes Gras ist eine kleine Pflanze, die oft auf Wiesenflächen wächst. Es kann für Weizensamen abgeerntet werden. Mit Knochenmehl lässt sich hohes Gras zu doppelhohem Gras verwandeln.
Fern=Farn
Ferns are small plants which occur naturally in jungles and taigas. They can be harvested for wheat seeds. By using bone meal, a fern can be turned into a large fern which is two blocks high.=Farne sind kleine Pflanzen, die oft in Dschungeln und Taigas vorkommen. Sie können für Weizensamen abgeerntet werden. Mit Knochenmehl wird sich ein Farn zu einem großen Farn, der zwei Blöcke hoch ist, verwandeln.
Ferns are small plants which occur naturally in jungles and taigas. They can be harvested for wheat seeds. By using bone meal, a fern can be turned into a large fern which is two blocks high.=Farne sind kleine Pflanzen, die oft in Dschungeln und Taigas vorkommen. Sie können für Weizensamen abgeerntet werden. Mit Knochenmehl lässt sich ein Farn zu einem großen Farn, der zwei Blöcke hoch ist, verwandeln.
(Top Part)=(Oberseite)
Peony=Pfingstrose
A peony is a large plant which occupies two blocks. It is mainly used in dye production.=Eine Pfingstrose ist eine große Pflanze, die zwei Blöcke hoch ist. Sie wird hauptsächlich für die Farbenproduktion gebraucht.

View File

@ -5,7 +5,7 @@ local mod_screwdriver = minetest.get_modpath("screwdriver")
local equip_armor
if minetest.get_modpath("mcl_armor") then
equip_armor = mcl_armor.equip_on_use
equip_armor = armor.on_armor_use
end
-- Heads system

View File

@ -61,7 +61,7 @@ This item is mainly used for crafting.=Dieser Gegenstand wird hauptsächlich in
Magma Cream=Magmacreme
Magma cream is a crafting component.=Magmacreme ist eine Fertigungskomponente.
Ghast Tear=Ghast-Träne
Place this item in an item frame as decoration.=Platzieren Sie diesen Gegenstand in einem Rahmel als Deko.
Place this item in an item frame as decoration.=Platzieren Sie diesen Gegenstand in einem Rahmen als Deko.
Nether Star=Nether-Stern
A nether star is dropped when the Wither dies. Place it in an item frame to show the world how hardcore you are! Or just as decoration.=Ein Netherstern wird abgeworfen, wenn der Wither stirbt. Platzieren Sie ihn in einen Rahmen, um der Welt zu zeigen, wie großartig Sie sind!

View File

@ -114,7 +114,7 @@ minetest.register_node("mcl_nether:magma", {
if mod_death_messages then
mcl_death_messages.player_damage(player, S("@1 stood too long on a magma block.", player:get_player_name()))
end
mcl_util.deal_damage(player, 1, {type = "hot_floor"})
player:set_hp(player:get_hp() - 1, { type = "punch", from = "mod" })
end
end,
_mcl_blast_resistance = 0.5,

View File

@ -603,18 +603,21 @@ function mcl_potions.make_invisible(player, toggle)
return
end
if player:is_player() then
mcl_player.player_set_skin(player, "mobs_mc_empty.png")
elseif not player:is_player() then
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
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 player:is_player() then
mcl_skins.update_player_skin(player)
elseif not player:is_player() then
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
player:set_properties({visual_size = EF.invisible[player].old_size})
end
player:set_nametag_attributes({color = {r = 255, g = 255, b = 255, a = 255}})

View File

@ -257,7 +257,7 @@ minetest.register_lbm({
nodenames = {"group:torch_particles"},
run_at_every_load = true,
action = function(pos, node)
local torch_group = minetest.get_item_group(node.name, "torch")
local torch_group = minetest.get_node_group(node.name, "torch")
if torch_group == 1 then
spawn_flames_floor(pos)
elseif torch_group == 2 then

View File

@ -22,7 +22,7 @@ Blue Carpet=Blauer Teppich
Magenta Wool=Magenta Wolle
Magenta Carpet=Magenta Teppich
Orange Wool=Orange Wolle
Orange Carpet=Orange Teppich
Orange Carpet=Oranger Teppich
Purple Wool=Violette Wolle
Purple Carpet=Violetter Teppich
Brown Wool=Braune Wolle

View File

@ -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))

View File

@ -1,2 +1,2 @@
# textdomain: screwdriver
Screwdriver=Schraubendreher
Screwdriver=Schraubenzieher

View File

@ -11,6 +11,7 @@ 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)
@ -49,6 +50,7 @@ minetest.register_on_dieplayer(function(player)
inv:set_list(listname, {})
end
end
mcl_armor.update(player)
armor:set_player_armor(player)
armor:update_inventory(player)
end
end)

View File

@ -164,7 +164,7 @@ minetest.register_globalstep(function(dtime)
if mod_death_messages then
mcl_death_messages.player_damage(player, S("@1 starved to death.", name))
end
mcl_util.deal_damage(player, 1, {type = "starve"})
player:set_hp(hp-1)
end
end
end

View File

@ -88,41 +88,22 @@ function mcl_player.player_set_model(player, model_name)
player_model[name] = model_name
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)
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
end
function mcl_player.player_get_preview(player)
local preview = player:get_meta():get_string("mcl_player:skin_preview")
if preview == "" then
preview = "player.png"
local preview = player:get_meta():get_string("mcl_player:preview")
if preview == nil or preview == "" then
return "player.png"
else
return preview
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)
@ -148,10 +129,8 @@ end
-- Update appearance when the player joins
minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
mcl_player.player_attached[name] = false
mcl_player.player_attached[player:get_player_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)

View File

@ -183,8 +183,6 @@ 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()
-- control head bone
local pitch = - degrees(player:get_look_vertical())
local yaw = degrees(player:get_look_horizontal())
@ -199,7 +197,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.1, 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
local chestplate = player:get_inventory():get_stack("armor", 3)
@ -255,14 +253,6 @@ 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 control.RMB and not control.LMB and not control.up and not control.down and not control.left and not control.right then
player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35))
@ -440,7 +430,7 @@ minetest.register_globalstep(function(dtime)
and (not check_player_privs(name, {noclip = true})) then
if player:get_hp() > 0 then
mcl_death_messages.player_damage(player, S("@1 suffocated to death.", name))
mcl_util.deal_damage(player, 1, {type = "in_wall"})
player:set_hp(player:get_hp() - 1)
end
end
@ -456,7 +446,7 @@ minetest.register_globalstep(function(dtime)
if dist < 1.1 or dist_feet < 1.1 then
if player:get_hp() > 0 then
mcl_death_messages.player_damage(player, S("@1 was prickled to death by a cactus.", name))
mcl_util.deal_damage(player, 1, {type = "cactus"})
player:set_hp(player:get_hp() - 1, { type = "punch", from = "mod" })
end
end
end

View File

@ -7,6 +7,7 @@ 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
@ -114,6 +115,10 @@ 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
@ -129,7 +134,7 @@ mcl_skins.update_player_skin = function(player)
return
end
local playername = player:get_player_name()
mcl_player.player_set_skin(player, mcl_skins.skins[playername] .. ".png", mcl_skins.previews[playername] .. ".png")
mcl_player.player_set_textures(player, { mcl_skins.skins[playername] .. ".png" }, mcl_skins.previews[playername] .. ".png" )
end
-- load player skin on join

View File

@ -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
optional_depends = mcl_inventory, intllib, mcl_armor

View File

@ -1,122 +0,0 @@
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,
})

View File

@ -0,0 +1,132 @@
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,
})

View File

@ -1,4 +1,5 @@
name = mcl_wieldview
name = wieldview
author = stujones11
description = Makes hand wielded items visible to other players.
depends = mcl_player
depends = mcl_armor

View File

@ -0,0 +1,10 @@
-- 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",
}