Update 1.0.1
parent
ca882ceb66
commit
445e664f0d
7
api.txt
7
api.txt
|
@ -8,13 +8,16 @@ node_damage.damage(pos, node, digger, num)
|
|||
--or left on the ground.
|
||||
pos: The location of the node to damage
|
||||
node: The node itself to damage. This is optional. It can be provided if available, but this function can get the node itself.
|
||||
digger: Optional; the person who is damaging this node.
|
||||
digger: Optional; the person who is damaging this node. Used to determine protection permission.
|
||||
num: Optional; the amount of times to damage this node. If its 3 or more, the node will always be destroyed.
|
||||
--Returns a boolean indicating success.
|
||||
|
||||
node_damage.repair(pos, node, num)
|
||||
node_damage.repair(pos, node, fixer, num)
|
||||
--Remove damage from this node, and set it into the previous stage of cracking.
|
||||
--For reference, there are four stages in total, including the stage without damage at all.
|
||||
--If the node is already fully repaired, nothing will happen.
|
||||
pos: The location of the node to repair
|
||||
node: The node itself to damage. This is optional. It can be provided if available, but this function can get the node itself.
|
||||
fixer: Optional; A person (ObjectRef) who is repairing this node. Used to determine protection permission.
|
||||
num: Optional; the amount of times to repair this node. If its 3 or more, the node will always be fully repaired.
|
||||
--Returns a boolean indicating success.
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
1.0.1:
|
||||
+node_damage.damage() and node_damage.repair() now return a boolean value to indicate success.
|
||||
-Removed the need to reload the world a second time whenever new nodes are introduced. Now, the override character ":" is used to skip prohibitive modname checks.
|
||||
-Prevented the use of node damaging and repair tools on nodes that are protected from the user, or are otherwise not meant to be broken.
|
||||
-Fixed issue where node_damage.repair() with a num greater than 1 would start damaging nodes.
|
168
init.lua
168
init.lua
|
@ -20,73 +20,45 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
--mod-specific global storage
|
||||
node_damage = {}
|
||||
|
||||
--Get mod-private storage, which is used to remember what nodes will exist.
|
||||
local store = minetest.get_mod_storage()
|
||||
|
||||
--A list of nodes to define. Nodes added by this mod are initialized with an empty definition,
|
||||
--so that override_item can be used when all other nodes are registered.
|
||||
local queue = {}
|
||||
|
||||
--Get the node_damage version of an item's name.
|
||||
--In the original name, the comma is gsubbed into an underscore in order to comply with naming standards.
|
||||
local function get_node_damage_name(name, i)
|
||||
return "node_damage:"..(name:gsub(":", "_")).."_"..i
|
||||
end
|
||||
|
||||
--For each item name that was previously saved...
|
||||
for name in pairs(store:to_table().fields) do
|
||||
--Add it to the queue.
|
||||
queue[name] = true
|
||||
|
||||
--Also, add the three other stages of cracking to the queue after registering them with blank definitions.
|
||||
for i = 1, 3 do
|
||||
minetest.register_node(get_node_damage_name(name, i), {})
|
||||
queue[get_node_damage_name(name, i)] = true
|
||||
end
|
||||
end
|
||||
|
||||
--Check if any particular node is valid for crackification.
|
||||
local function node_is_valid(name, can_be_in_queue)
|
||||
local function node_is_valid(name)
|
||||
--Get the existing definition for this item.
|
||||
local def = minetest.registered_items[name]
|
||||
|
||||
--If this item isn't in the queue, it is nil, rather than false.
|
||||
--So, if can_be_in_queue was left as false, this function would always return false.
|
||||
if can_be_in_queue == false then
|
||||
can_be_in_queue = nil
|
||||
end
|
||||
|
||||
--Return true if all of the following is true:
|
||||
--The definition exists
|
||||
--Either an entry in the queue exists and it can be in the queue, or there is no queue entry and it can't be in the queue.
|
||||
--This item is not something that would immediately be dug up anyways
|
||||
--This item isn't already cracked
|
||||
--This item is a node
|
||||
--This item doesn't originate from this mod.
|
||||
--This item can be destroyed
|
||||
--This item is visible
|
||||
return (def and queue[name] == can_be_in_queue and minetest.get_item_group(name, "dig_immediate") == 0
|
||||
return (def and minetest.get_item_group(name, "dig_immediate") == 0
|
||||
and minetest.get_item_group(name, "node_damage") == 0 and def.type == "node" and def.mod_origin ~= "node_damage"
|
||||
and def.diggable and def.drawtype ~= "airlike")
|
||||
end
|
||||
|
||||
--Once every mod has loaded and therefore every node has been registered...
|
||||
minetest.register_on_mods_loaded(function()
|
||||
--For each node name in the queue...
|
||||
for name in pairs(queue) do
|
||||
--As long as the node is still valid
|
||||
if node_is_valid(name, true) then
|
||||
--Override the node to tell it which node to place when damaged.
|
||||
local def = {node_damaged_name = get_node_damage_name(name, 1)}
|
||||
minetest.override_item(name, def)
|
||||
--For each registered item...
|
||||
for name, def in pairs(minetest.registered_items) do
|
||||
--If there's a valid node...
|
||||
if node_is_valid(name) then
|
||||
local ndef = {node_damaged_name = get_node_damage_name(name, 1)}
|
||||
minetest.override_item(name, ndef)
|
||||
|
||||
--For each of the cracked stages...
|
||||
for i = 1, 3 do
|
||||
--Copy the base node's definition and remove information from the copy that can't be overridden.
|
||||
def = table.copy(minetest.registered_items[name])
|
||||
def.name = nil
|
||||
def.type = nil
|
||||
def.mod_origin = nil
|
||||
--def.name = get_node_damage_name(name, i)
|
||||
--def.mod_origin = "node_damage"
|
||||
|
||||
--Give it the not_in_creative_inventory and node_damage groups
|
||||
--The exact number of node_damage can be used to know how damaged a node is.
|
||||
|
@ -139,31 +111,12 @@ minetest.register_on_mods_loaded(function()
|
|||
break
|
||||
end
|
||||
|
||||
--Finally, override the cracked node's empty definition with the base node's altered definition.
|
||||
minetest.override_item(get_node_damage_name(name, i), def)
|
||||
--Finally, forcefully register a new node while skipping the mod name prefix check,
|
||||
--in order for it to work after all mods have been loaded.
|
||||
minetest.register_node(":"..get_node_damage_name(name, i), def)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--This remembers if the player should be told to reload the world or not.
|
||||
local reload_msg = false
|
||||
|
||||
--For each registered item...
|
||||
for name, def in pairs(minetest.registered_items) do
|
||||
--If there's a valid node that wasn't in the queue...
|
||||
if node_is_valid(name) then
|
||||
--Know that the reload message should be displayed.
|
||||
reload_msg = true
|
||||
|
||||
--Remember the name of this newly added node.
|
||||
store:set_int(name, 1)
|
||||
end
|
||||
end
|
||||
|
||||
--If a reload message should be displayed, show it.
|
||||
if reload_msg then
|
||||
minetest.log("New nodes have been added to the game. Please reload to enable them to use the Node Damage and Repair System.")
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
|
@ -171,64 +124,117 @@ end)
|
|||
--A function to damage a given node, as long as that's possible.
|
||||
--pos: The location of the node to damage.
|
||||
--node: Optional; the node itself. It there's already data, you can pass it along to save time, but this function can grab the data itself.
|
||||
--digger: Optional; A person who is attacking this node. If its destroyed, that person will pick it up.
|
||||
--digger: Optional; A person (ObjectRef) who is attacking this node. If its destroyed, that person will pick it up.
|
||||
--num: Optional, defaults to 1; The amount of times to damage this node. 3 will destroy any node_damage node.
|
||||
--Returns a boolean indicating success.
|
||||
function node_damage.damage(pos, node, digger, num)
|
||||
--If the node itself wasn't provided, grab it from the provided position
|
||||
if not node then
|
||||
node = minetest.get_node(pos)
|
||||
end
|
||||
|
||||
--By default, assume that there is no player directly causing the damage.
|
||||
local pname = ""
|
||||
|
||||
--If there is a player, get that player's name instead.
|
||||
if digger then
|
||||
pname = digger:get_player_name()
|
||||
end
|
||||
|
||||
--If this node is protected, fail.
|
||||
if minetest.is_protected(pos, pname) then
|
||||
return false
|
||||
end
|
||||
|
||||
--Get the node's definition
|
||||
local def = minetest.registered_items[node.name]
|
||||
|
||||
--If the definition exists...
|
||||
if def then
|
||||
--If it defines a next stage of damage, swap to that next stage.
|
||||
if def.node_damaged_name and minetest.registered_items[def.node_damaged_name] then
|
||||
minetest.swap_node(pos, {name = def.node_damaged_name})
|
||||
--Otherwise, if it doesn't because it's in the last stage of damage, destroy the node.
|
||||
elseif def.groups.node_damage == 3 then
|
||||
--If a digger was provided, use node_dig to give the node to them.
|
||||
if digger then
|
||||
minetest.node_dig(pos, node, digger)
|
||||
--Otherwise, use the standard dig_node. This leaves the drops on the ground.
|
||||
else
|
||||
minetest.dig_node(pos, node)
|
||||
end
|
||||
--If the def has no definition or specifies that it can't be dug right now, fail.
|
||||
if not def or (def.can_dig and def.can_dig()) then
|
||||
return false
|
||||
end
|
||||
|
||||
--If it defines a next stage of damage, swap to that next stage.
|
||||
if def.node_damaged_name and minetest.registered_items[def.node_damaged_name] then
|
||||
minetest.swap_node(pos, {name = def.node_damaged_name, param1 = node.param1, param2 = node.param2})
|
||||
--Otherwise, if it doesn't because it's in the last stage of damage, destroy the node.
|
||||
elseif def.groups.node_damage == 3 then
|
||||
--If a digger was provided, use node_dig to give the node to them.
|
||||
if digger then
|
||||
minetest.node_dig(pos, node, digger)
|
||||
--Otherwise, use the standard dig_node. This leaves the drops on the ground.
|
||||
else
|
||||
minetest.dig_node(pos, node)
|
||||
end
|
||||
|
||||
--If the node was dug up and left nothing behind, there's no need to apply more damage.
|
||||
if minetest.get_node(pos).name == "air" then
|
||||
return true
|
||||
end
|
||||
else
|
||||
--If it's not possible to damage this node, fail.
|
||||
return false
|
||||
end
|
||||
|
||||
--If num was provided and it was more than 1...
|
||||
if num and num > 1 then
|
||||
--Call damage again, but with 1 less num.
|
||||
node_damage.damage(pos, node, digger, num - 1)
|
||||
return node_damage.damage(pos, node, digger, num - 1)
|
||||
end
|
||||
|
||||
--Getting to the end of the function is only possible upon success.
|
||||
return true
|
||||
end
|
||||
|
||||
--The opposite of damage. Removes damage from a node, as long as its possible.
|
||||
--pos: The location of the node to repair.
|
||||
--node: Optional; the node itself. It there's already data, you can pass it along to save time, but this function can grab the data itself.
|
||||
--fixer: Optional; A person (ObjectRef) who is repairing this node. Used to determine protection permission.
|
||||
--num: Optional, defaults to 1; The amount of times to repair this node. 3 will repair any node that still exists.
|
||||
function node_damage.repair(pos, node, num)
|
||||
--Returns a boolean indicating success.
|
||||
function node_damage.repair(pos, node, fixer, num)
|
||||
--If the node itself wasn't provided, grab it from the provided position
|
||||
if not node then
|
||||
node = minetest.get_node(pos)
|
||||
end
|
||||
|
||||
--By default, assume that there is no player directly causing the repair.
|
||||
local pname = ""
|
||||
|
||||
--If there is a player, get that player's name instead.
|
||||
if fixer then
|
||||
pname = fixer:get_player_name()
|
||||
end
|
||||
|
||||
--If this node is protected, fail.
|
||||
if minetest.is_protected(pos, pname) then
|
||||
return false
|
||||
end
|
||||
|
||||
--Get the node's definition
|
||||
local def = minetest.registered_items[node.name]
|
||||
|
||||
--If the definition exists and has the name of a less damaged node to switch to, swap the node.
|
||||
if def and def.node_repaired_name and minetest.registered_items[def.node_repaired_name] then
|
||||
minetest.swap_node(pos, {name = def.node_repaired_name})
|
||||
--If there is no definition for this node, fail.
|
||||
if not def then
|
||||
return false
|
||||
end
|
||||
|
||||
--If the definition has the name of a less damaged node to switch to, swap the node.
|
||||
if def.node_repaired_name and minetest.registered_items[def.node_repaired_name] then
|
||||
minetest.swap_node(pos, {name = def.node_repaired_name, param1 = node.param1, param2 = node.param2})
|
||||
else
|
||||
--If it's not possible to repair this node, fail.
|
||||
return false
|
||||
end
|
||||
|
||||
--If num was provided and it was more than 1...
|
||||
if num and num > 1 then
|
||||
--Call repair again, but with 1 less num.
|
||||
node_damage.damage(pos, node, digger, num - 1)
|
||||
return node_damage.repair(pos, node, fixer, num - 1)
|
||||
end
|
||||
|
||||
--Getting to the end of the function is only possible upon success.
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue