Damage anvil after falling

This commit is contained in:
Wuzzy 2018-02-05 19:58:31 +01:00
parent 32561ec658
commit 30be3e742f
3 changed files with 62 additions and 22 deletions

1
API.md
View File

@ -21,6 +21,7 @@ All nodes can have these fields:
* `_mcl_hardness`: Hardness of the block, ranges from 0 to infinity (represented by -1). Determines digging times. Default: 0
* `_mcl_blast_resistance`: How well this block blocks and resists explosions. Default: 0
* `_mcl_after_falling(pos)`: Called after a falling node finished falling and turned into a node.
Use the `mcl_sounds` mod for the sounds.

View File

@ -1,6 +1,14 @@
local dmes = minetest.get_modpath("mcl_death_messages") ~= nil
local hung = minetest.get_modpath("mcl_hunger") ~= nil
local get_falling_depth = function(self)
if not self._startpos then
-- Fallback
self._startpos = self.object:get_pos()
end
return self._startpos.y - vector.round(self.object:get_pos()).y
end
local deal_falling_damage = function(self, dtime)
if minetest.get_item_group(self.node.name, "falling_node_damage") == 0 then
return
@ -10,6 +18,7 @@ local deal_falling_damage = function(self, dtime)
-- TODO: Support smashing other objects, too.
local pos = self.object:get_pos()
if not self._startpos then
-- Fallback
self._startpos = pos
end
local objs = minetest.get_objects_inside_radius(pos, 1)
@ -128,6 +137,10 @@ minetest.register_entity(":__builtin:falling_node", {
elseif staticdata ~= "" then
self:set_node({name = staticdata})
end
if not self._startpos then
self._startpos = self.object:get_pos()
end
self._startpos = vector.round(self._startpos)
end,
on_step = function(self, dtime)
@ -167,6 +180,9 @@ minetest.register_entity(":__builtin:falling_node", {
addlevel = bcd.leveled
end
if minetest.add_node_level(bcp, addlevel) == 0 then
if minetest.registered_nodes[self.node.name]._mcl_after_falling then
minetest.registered_nodes[self.node.name]._mcl_after_falling(bcp, get_falling_depth(self))
end
deal_falling_damage(self, dtime)
self.object:remove()
return
@ -190,6 +206,9 @@ minetest.register_entity(":__builtin:falling_node", {
end
if minetest.registered_nodes[self.node.name] then
minetest.add_node(np, self.node)
if minetest.registered_nodes[self.node.name]._mcl_after_falling then
minetest.registered_nodes[self.node.name]._mcl_after_falling(np, get_falling_depth(self))
end
if self.meta then
local meta = minetest.get_meta(np)
meta:from_table(self.meta)
@ -223,6 +242,9 @@ minetest.register_entity(":__builtin:falling_node", {
local npos3 = table.copy(npos)
npos3.y = npos3.y - 1
minetest.add_node(npos3, self.node)
if minetest.registered_nodes[self.node.name]._mcl_after_falling then
minetest.registered_nodes[self.node.name]._mcl_after_falling(npos3, get_falling_depth(self))
end
deal_falling_damage(self, dtime)
self.object:remove()
minetest.check_for_falling(npos3)

View File

@ -204,33 +204,49 @@ local function drop_anvil_items(pos, meta)
end
end
-- Roll a virtual dice and with a low chance, damage the anvil by 1 level.
-- Damage the anvil by 1 level.
-- Destroy anvil when at highest damage level.
-- Returns true if anvil was destroyed.
local function damage_anvil(pos)
local node = minetest.get_node(pos)
local new
if node.name == "mcl_anvils:anvil" then
minetest.swap_node(pos, {name="mcl_anvils:anvil_damage_1", param2=node.param2})
minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dig, {pos=pos, max_hear_distance=16})
return false
elseif node.name == "mcl_anvils:anvil_damage_1" then
minetest.swap_node(pos, {name="mcl_anvils:anvil_damage_2", param2=node.param2})
minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dig, {pos=pos, max_hear_distance=16})
return false
elseif node.name == "mcl_anvils:anvil_damage_2" then
-- Destroy anvil
local meta = minetest.get_meta(pos)
drop_anvil_items(pos, meta)
minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dug, {pos=pos, max_hear_distance=16})
minetest.remove_node(pos)
return true
end
end
-- Roll a virtual dice and damage anvil at a low chance.
local function damage_anvil_by_using(pos)
local r = math.random(1, 100)
-- 12% chance
if r <= 12 then
local node = minetest.get_node(pos)
local new
if node.name == "mcl_anvils:anvil" then
minetest.swap_node(pos, {name="mcl_anvils:anvil_damage_1", param2=node.param2})
minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dig, {pos=pos, max_hear_distance=16})
return false
elseif node.name == "mcl_anvils:anvil_damage_1" then
minetest.swap_node(pos, {name="mcl_anvils:anvil_damage_2", param2=node.param2})
minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dig, {pos=pos, max_hear_distance=16})
return false
elseif node.name == "mcl_anvils:anvil_damage_2" then
-- Destroy anvil
local meta = minetest.get_meta(pos)
drop_anvil_items(pos, meta)
minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dug, {pos=pos, max_hear_distance=16})
minetest.remove_node(pos)
return true
return damage_anvil(pos)
else
return false
end
end
local function damage_anvil_by_falling(pos, distance)
local chance
local r = math.random(1, 100)
if distance > 1 then
if r <= (5*distance) then
damage_anvil(pos)
end
end
return false
end
local anvildef = {
@ -252,6 +268,7 @@ local anvildef = {
sounds = mcl_sounds.node_sound_metal_defaults(),
_mcl_blast_resistance = 6000,
_mcl_hardness = 5,
_mcl_after_falling = damage_anvil_by_falling,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
local meta = minetest.get_meta(pos)
@ -301,7 +318,7 @@ local anvildef = {
update_anvil_slots(meta)
if from_list == "output" then
local destroyed = damage_anvil(pos, player)
local destroyed = damage_anvil_by_using(pos)
-- Close formspec if anvil was destroyed
if destroyed then
--[[ Closing the formspec w/ emptyformname is discouraged. But this is justified
@ -354,7 +371,7 @@ local anvildef = {
inv:set_stack("input", 2, input2)
end
end
local destroyed = damage_anvil(pos, player)
local destroyed = damage_anvil_by_using(pos)
-- Close formspec if anvil was destroyed
if destroyed then
-- See above for justification.
@ -404,7 +421,7 @@ anvildef0._doc_items_usagehelp =
"• Tool + Tool: Place two tools of the same type in the input slots. The “health” of the repaired tool is the sum of the “health” of both input tools, plus a 12% bonus.".."\n"..
"• Tool + Material: Some tools can also be repaired by combining them with an item that it's made of. For example, iron pickaxes can be repaired with iron ingots. This repairs the tool by 25%.".."\n"..
"Armor counts as a tool. It is possible to repair and rename a tool in a single step.".."\n\n"..
"The anvil has limited durability and 3 damage levels: undamaged, slightly damaged and very damaged. Each time you repair or rename something, there is a 12% chance the anvil gets damaged. If a very damaged anvil is damaged again, it is destroyed."
"The anvil has limited durability and 3 damage levels: undamaged, slightly damaged and very damaged. Each time you repair or rename something, there is a 12% chance the anvil gets damaged. Anvils also have a chance of being damaged when they fall by more than 1 block. If a very damaged anvil is damaged again, it is destroyed."
local anvildef1 = table.copy(anvildef)
anvildef1.description = "Slightly Damaged Anvil"