forked from VoxeLibre/VoxeLibre
Compare commits
9 Commits
Author | SHA1 | Date |
---|---|---|
Elias Fleckenstein | 0c5096db13 | |
NO11 | 3fbeab7c85 | |
NO11 | a8760c0375 | |
NO11 | bbffda3635 | |
Nils Dagsson Moskopp | 2575e20e7e | |
epCode | 5fe30d7287 | |
Benjamin Schötz | bffd032a8b | |
Benjamin Schötz | e4c8ba795a | |
epCode | 18cdd13c06 |
|
@ -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)
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
name = mcl_damage
|
||||
author = Fleckenstein
|
||||
description = Minecraft-like damage reason system
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
]]--
|
||||
]]--
|
|
@ -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,
|
||||
|
|
|
@ -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},
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)..
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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)
|
|
@ -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
|
|
@ -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
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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)
|
|
@ -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 |
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"},
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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}})
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
# textdomain: screwdriver
|
||||
Screwdriver=Schraubendreher
|
||||
Screwdriver=Schraubenzieher
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
})
|
|
@ -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,
|
||||
})
|
|
@ -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
|
||||
|
|
@ -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",
|
||||
}
|
||||
|
Loading…
Reference in New Issue