2013-05-19 18:43:04 +02:00
|
|
|
-- mods/default/functions.lua
|
|
|
|
|
|
|
|
--
|
|
|
|
-- Sounds
|
|
|
|
--
|
|
|
|
|
|
|
|
function default.node_sound_defaults(table)
|
|
|
|
table = table or {}
|
|
|
|
table.footstep = table.footstep or
|
2015-06-07 23:48:26 +02:00
|
|
|
{name = "", gain = 1.0}
|
2013-05-19 18:43:04 +02:00
|
|
|
table.dug = table.dug or
|
2015-06-07 23:48:26 +02:00
|
|
|
{name = "default_dug_node", gain = 0.25}
|
2013-05-19 18:43:04 +02:00
|
|
|
table.place = table.place or
|
2015-06-07 23:48:26 +02:00
|
|
|
{name = "default_place_node_hard", gain = 1.0}
|
2013-05-19 18:43:04 +02:00
|
|
|
return table
|
|
|
|
end
|
|
|
|
|
|
|
|
function default.node_sound_stone_defaults(table)
|
|
|
|
table = table or {}
|
|
|
|
table.footstep = table.footstep or
|
2016-12-15 09:13:36 +01:00
|
|
|
{name = "default_hard_footstep", gain = 0.3}
|
2013-06-13 16:30:33 +02:00
|
|
|
table.dug = table.dug or
|
2015-06-07 23:48:26 +02:00
|
|
|
{name = "default_hard_footstep", gain = 1.0}
|
2013-05-19 18:43:04 +02:00
|
|
|
default.node_sound_defaults(table)
|
|
|
|
return table
|
|
|
|
end
|
|
|
|
|
|
|
|
function default.node_sound_dirt_defaults(table)
|
|
|
|
table = table or {}
|
|
|
|
table.footstep = table.footstep or
|
2016-12-15 09:13:36 +01:00
|
|
|
{name = "default_dirt_footstep", gain = 0.4}
|
2013-06-13 16:30:33 +02:00
|
|
|
table.dug = table.dug or
|
2016-12-15 09:13:36 +01:00
|
|
|
{name = "default_dirt_footstep", gain = 1.0}
|
2013-06-11 23:23:10 +02:00
|
|
|
table.place = table.place or
|
2015-06-07 23:48:26 +02:00
|
|
|
{name = "default_place_node", gain = 1.0}
|
2013-05-19 18:43:04 +02:00
|
|
|
default.node_sound_defaults(table)
|
|
|
|
return table
|
|
|
|
end
|
|
|
|
|
|
|
|
function default.node_sound_sand_defaults(table)
|
|
|
|
table = table or {}
|
|
|
|
table.footstep = table.footstep or
|
2016-03-24 04:00:43 +01:00
|
|
|
{name = "default_sand_footstep", gain = 0.12}
|
2013-05-19 18:43:04 +02:00
|
|
|
table.dug = table.dug or
|
2016-03-24 04:00:43 +01:00
|
|
|
{name = "default_sand_footstep", gain = 0.24}
|
2013-06-11 23:23:10 +02:00
|
|
|
table.place = table.place or
|
2015-06-07 23:48:26 +02:00
|
|
|
{name = "default_place_node", gain = 1.0}
|
2013-05-19 18:43:04 +02:00
|
|
|
default.node_sound_defaults(table)
|
|
|
|
return table
|
|
|
|
end
|
|
|
|
|
2016-04-25 00:10:46 +02:00
|
|
|
function default.node_sound_gravel_defaults(table)
|
|
|
|
table = table or {}
|
|
|
|
table.footstep = table.footstep or
|
2016-12-15 09:13:36 +01:00
|
|
|
{name = "default_gravel_footstep", gain = 0.4}
|
2016-04-25 00:10:46 +02:00
|
|
|
table.dug = table.dug or
|
|
|
|
{name = "default_gravel_footstep", gain = 1.0}
|
|
|
|
table.place = table.place or
|
|
|
|
{name = "default_place_node", gain = 1.0}
|
|
|
|
default.node_sound_defaults(table)
|
|
|
|
return table
|
|
|
|
end
|
|
|
|
|
2013-05-19 18:43:04 +02:00
|
|
|
function default.node_sound_wood_defaults(table)
|
|
|
|
table = table or {}
|
|
|
|
table.footstep = table.footstep or
|
2016-12-15 09:13:36 +01:00
|
|
|
{name = "default_wood_footstep", gain = 0.3}
|
2013-06-13 16:30:33 +02:00
|
|
|
table.dug = table.dug or
|
2015-06-07 23:48:26 +02:00
|
|
|
{name = "default_wood_footstep", gain = 1.0}
|
2013-05-19 18:43:04 +02:00
|
|
|
default.node_sound_defaults(table)
|
|
|
|
return table
|
|
|
|
end
|
|
|
|
|
|
|
|
function default.node_sound_leaves_defaults(table)
|
|
|
|
table = table or {}
|
|
|
|
table.footstep = table.footstep or
|
2016-12-15 09:13:36 +01:00
|
|
|
{name = "default_grass_footstep", gain = 0.45}
|
2013-06-13 16:30:33 +02:00
|
|
|
table.dug = table.dug or
|
2015-06-07 23:48:26 +02:00
|
|
|
{name = "default_grass_footstep", gain = 0.7}
|
2013-06-11 23:23:10 +02:00
|
|
|
table.place = table.place or
|
2015-06-07 23:48:26 +02:00
|
|
|
{name = "default_place_node", gain = 1.0}
|
2013-05-19 18:43:04 +02:00
|
|
|
default.node_sound_defaults(table)
|
|
|
|
return table
|
|
|
|
end
|
|
|
|
|
|
|
|
function default.node_sound_glass_defaults(table)
|
|
|
|
table = table or {}
|
|
|
|
table.footstep = table.footstep or
|
2016-12-15 09:13:36 +01:00
|
|
|
{name = "default_glass_footstep", gain = 0.3}
|
2016-12-10 02:05:16 +01:00
|
|
|
table.dig = table.dig or
|
2016-12-15 09:13:36 +01:00
|
|
|
{name = "default_glass_footstep", gain = 0.5}
|
2013-05-19 18:43:04 +02:00
|
|
|
table.dug = table.dug or
|
2015-06-07 23:48:26 +02:00
|
|
|
{name = "default_break_glass", gain = 1.0}
|
2013-05-19 18:43:04 +02:00
|
|
|
default.node_sound_defaults(table)
|
|
|
|
return table
|
|
|
|
end
|
|
|
|
|
2016-10-20 01:23:05 +02:00
|
|
|
function default.node_sound_metal_defaults(table)
|
|
|
|
table = table or {}
|
|
|
|
table.footstep = table.footstep or
|
2016-12-15 09:13:36 +01:00
|
|
|
{name = "default_metal_footstep", gain = 0.4}
|
2016-10-20 01:23:05 +02:00
|
|
|
table.dig = table.dig or
|
|
|
|
{name = "default_dig_metal", gain = 0.5}
|
|
|
|
table.dug = table.dug or
|
|
|
|
{name = "default_dug_metal", gain = 0.5}
|
|
|
|
table.place = table.place or
|
|
|
|
{name = "default_place_node_metal", gain = 0.5}
|
|
|
|
default.node_sound_defaults(table)
|
|
|
|
return table
|
|
|
|
end
|
2014-08-26 13:55:53 +02:00
|
|
|
|
2016-11-17 03:41:38 +01:00
|
|
|
function default.node_sound_water_defaults(table)
|
|
|
|
table = table or {}
|
|
|
|
table.footstep = table.footstep or
|
|
|
|
{name = "default_water_footstep", gain = 0.2}
|
|
|
|
default.node_sound_defaults(table)
|
|
|
|
return table
|
|
|
|
end
|
|
|
|
|
2013-05-19 18:43:04 +02:00
|
|
|
--
|
|
|
|
-- Lavacooling
|
|
|
|
--
|
|
|
|
|
2016-02-13 09:33:58 +01:00
|
|
|
default.cool_lava = function(pos, node)
|
|
|
|
if node.name == "default:lava_source" then
|
|
|
|
minetest.set_node(pos, {name = "default:obsidian"})
|
|
|
|
else -- Lava flowing
|
|
|
|
minetest.set_node(pos, {name = "default:stone"})
|
|
|
|
end
|
2015-08-02 06:16:01 +02:00
|
|
|
minetest.sound_play("default_cool_lava",
|
|
|
|
{pos = pos, max_hear_distance = 16, gain = 0.25})
|
2013-05-19 18:43:04 +02:00
|
|
|
end
|
|
|
|
|
2017-05-22 15:41:17 +02:00
|
|
|
if minetest.settings:get_bool("enable_lavacooling") ~= false then
|
2017-05-07 18:25:53 +02:00
|
|
|
minetest.register_abm({
|
|
|
|
label = "Lava cooling",
|
|
|
|
nodenames = {"default:lava_source", "default:lava_flowing"},
|
|
|
|
neighbors = {"group:cools_lava", "group:water"},
|
2017-07-27 02:16:17 +02:00
|
|
|
interval = 2,
|
2017-05-07 18:25:53 +02:00
|
|
|
chance = 2,
|
|
|
|
catch_up = false,
|
2017-06-06 19:20:58 +02:00
|
|
|
action = function(...)
|
|
|
|
default.cool_lava(...)
|
|
|
|
end,
|
2017-05-07 18:25:53 +02:00
|
|
|
})
|
|
|
|
end
|
2014-08-26 13:55:53 +02:00
|
|
|
|
2016-04-16 04:21:45 +02:00
|
|
|
--
|
|
|
|
-- optimized helper to put all items in an inventory into a drops list
|
|
|
|
--
|
2016-08-07 04:54:08 +02:00
|
|
|
|
2016-04-16 04:21:45 +02:00
|
|
|
function default.get_inventory_drops(pos, inventory, drops)
|
|
|
|
local inv = minetest.get_meta(pos):get_inventory()
|
|
|
|
local n = #drops
|
|
|
|
for i = 1, inv:get_size(inventory) do
|
|
|
|
local stack = inv:get_stack(inventory, i)
|
|
|
|
if stack:get_count() > 0 then
|
|
|
|
drops[n+1] = stack:to_table()
|
|
|
|
n = n + 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-05-19 18:43:04 +02:00
|
|
|
--
|
|
|
|
-- Papyrus and cactus growing
|
|
|
|
--
|
|
|
|
|
2015-06-07 23:48:26 +02:00
|
|
|
-- wrapping the functions in abm action is necessary to make overriding them possible
|
|
|
|
|
2014-08-26 13:55:53 +02:00
|
|
|
function default.grow_cactus(pos, node)
|
2015-06-07 04:31:23 +02:00
|
|
|
if node.param2 >= 4 then
|
2014-08-26 13:55:53 +02:00
|
|
|
return
|
|
|
|
end
|
2015-06-07 23:48:26 +02:00
|
|
|
pos.y = pos.y - 1
|
2014-08-26 13:55:53 +02:00
|
|
|
if minetest.get_item_group(minetest.get_node(pos).name, "sand") == 0 then
|
|
|
|
return
|
|
|
|
end
|
2015-06-07 23:48:26 +02:00
|
|
|
pos.y = pos.y + 1
|
2014-08-26 13:55:53 +02:00
|
|
|
local height = 0
|
2015-06-07 23:48:26 +02:00
|
|
|
while node.name == "default:cactus" and height < 4 do
|
|
|
|
height = height + 1
|
|
|
|
pos.y = pos.y + 1
|
2014-08-26 13:55:53 +02:00
|
|
|
node = minetest.get_node(pos)
|
|
|
|
end
|
2015-06-07 23:48:26 +02:00
|
|
|
if height == 4 or node.name ~= "air" then
|
2014-08-26 13:55:53 +02:00
|
|
|
return
|
|
|
|
end
|
2016-12-27 16:18:49 +01:00
|
|
|
if minetest.get_node_light(pos) < 13 then
|
|
|
|
return
|
|
|
|
end
|
2015-06-07 23:48:26 +02:00
|
|
|
minetest.set_node(pos, {name = "default:cactus"})
|
2014-08-26 13:55:53 +02:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
function default.grow_papyrus(pos, node)
|
2015-06-07 23:48:26 +02:00
|
|
|
pos.y = pos.y - 1
|
2014-08-26 13:55:53 +02:00
|
|
|
local name = minetest.get_node(pos).name
|
2015-10-05 02:25:23 +02:00
|
|
|
if name ~= "default:dirt_with_grass" and name ~= "default:dirt" then
|
2014-08-26 13:55:53 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
if not minetest.find_node_near(pos, 3, {"group:water"}) then
|
|
|
|
return
|
|
|
|
end
|
2015-06-07 23:48:26 +02:00
|
|
|
pos.y = pos.y + 1
|
2014-08-26 13:55:53 +02:00
|
|
|
local height = 0
|
|
|
|
while node.name == "default:papyrus" and height < 4 do
|
2015-06-07 23:48:26 +02:00
|
|
|
height = height + 1
|
|
|
|
pos.y = pos.y + 1
|
2014-08-26 13:55:53 +02:00
|
|
|
node = minetest.get_node(pos)
|
|
|
|
end
|
2015-06-07 23:48:26 +02:00
|
|
|
if height == 4 or node.name ~= "air" then
|
2014-08-26 13:55:53 +02:00
|
|
|
return
|
|
|
|
end
|
2016-12-27 16:18:49 +01:00
|
|
|
if minetest.get_node_light(pos) < 13 then
|
|
|
|
return
|
|
|
|
end
|
2015-06-07 23:48:26 +02:00
|
|
|
minetest.set_node(pos, {name = "default:papyrus"})
|
2014-08-26 13:55:53 +02:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2013-05-19 18:43:04 +02:00
|
|
|
minetest.register_abm({
|
2016-08-08 11:56:13 +02:00
|
|
|
label = "Grow cactus",
|
2013-05-19 18:43:04 +02:00
|
|
|
nodenames = {"default:cactus"},
|
|
|
|
neighbors = {"group:sand"},
|
2016-02-13 09:33:58 +01:00
|
|
|
interval = 12,
|
|
|
|
chance = 83,
|
2017-06-06 19:20:58 +02:00
|
|
|
action = function(...)
|
|
|
|
default.grow_cactus(...)
|
|
|
|
end
|
2013-05-19 18:43:04 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
minetest.register_abm({
|
2016-08-08 11:56:13 +02:00
|
|
|
label = "Grow papyrus",
|
2013-05-19 18:43:04 +02:00
|
|
|
nodenames = {"default:papyrus"},
|
2016-02-13 09:33:58 +01:00
|
|
|
neighbors = {"default:dirt", "default:dirt_with_grass"},
|
|
|
|
interval = 14,
|
|
|
|
chance = 71,
|
2017-06-06 19:20:58 +02:00
|
|
|
action = function(...)
|
|
|
|
default.grow_papyrus(...)
|
|
|
|
end
|
2013-05-19 18:43:04 +02:00
|
|
|
})
|
|
|
|
|
2014-08-26 13:55:53 +02:00
|
|
|
|
2013-05-19 18:43:04 +02:00
|
|
|
--
|
2013-12-02 19:23:29 +01:00
|
|
|
-- dig upwards
|
|
|
|
--
|
|
|
|
|
|
|
|
function default.dig_up(pos, node, digger)
|
|
|
|
if digger == nil then return end
|
|
|
|
local np = {x = pos.x, y = pos.y + 1, z = pos.z}
|
|
|
|
local nn = minetest.get_node(np)
|
|
|
|
if nn.name == node.name then
|
|
|
|
minetest.node_dig(np, nn, digger)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-08-26 13:55:53 +02:00
|
|
|
|
Create API for fence.register, and use it.
This converts the call to minetest.register() for the default
fence node, so it can be called by other mods to quickly
setup other fences.
Since this creates an API, insert it into the game_api.txt.
The api looks like minetest.register(name, {def}), and has two
uncommon fields: "texture" and "material". Any normal nodedef
property can be passed through, except "drawtype". The "fence"
group will always be added.
The default fence recipe is modified to be as follows:
wood, stick, wood
wood, stick, wood
This recipe yields 4 fence nodes.
This allows us to create according recipes for acacia, pine,
aspen, and junglewood fences without adding new stick types:
pine wood, stick, pine wood
pine wood, stick, pine wood
This is a from-scratch implementation, written by heart but inspired
by (#665 - Add many wooden fences).
Stick and fences nodes are named in a consistent way.
2015-12-15 06:49:20 +01:00
|
|
|
--
|
|
|
|
-- Fence registration helper
|
|
|
|
--
|
2016-08-07 04:54:08 +02:00
|
|
|
|
Create API for fence.register, and use it.
This converts the call to minetest.register() for the default
fence node, so it can be called by other mods to quickly
setup other fences.
Since this creates an API, insert it into the game_api.txt.
The api looks like minetest.register(name, {def}), and has two
uncommon fields: "texture" and "material". Any normal nodedef
property can be passed through, except "drawtype". The "fence"
group will always be added.
The default fence recipe is modified to be as follows:
wood, stick, wood
wood, stick, wood
This recipe yields 4 fence nodes.
This allows us to create according recipes for acacia, pine,
aspen, and junglewood fences without adding new stick types:
pine wood, stick, pine wood
pine wood, stick, pine wood
This is a from-scratch implementation, written by heart but inspired
by (#665 - Add many wooden fences).
Stick and fences nodes are named in a consistent way.
2015-12-15 06:49:20 +01:00
|
|
|
function default.register_fence(name, def)
|
|
|
|
minetest.register_craft({
|
|
|
|
output = name .. " 4",
|
|
|
|
recipe = {
|
|
|
|
{ def.material, 'group:stick', def.material },
|
|
|
|
{ def.material, 'group:stick', def.material },
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
local fence_texture = "default_fence_overlay.png^" .. def.texture ..
|
|
|
|
"^default_fence_overlay.png^[makealpha:255,126,126"
|
|
|
|
-- Allow almost everything to be overridden
|
|
|
|
local default_fields = {
|
|
|
|
paramtype = "light",
|
2015-12-15 06:49:20 +01:00
|
|
|
drawtype = "nodebox",
|
|
|
|
node_box = {
|
|
|
|
type = "connected",
|
|
|
|
fixed = {{-1/8, -1/2, -1/8, 1/8, 1/2, 1/8}},
|
|
|
|
-- connect_top =
|
|
|
|
-- connect_bottom =
|
|
|
|
connect_front = {{-1/16,3/16,-1/2,1/16,5/16,-1/8},
|
|
|
|
{-1/16,-5/16,-1/2,1/16,-3/16,-1/8}},
|
|
|
|
connect_left = {{-1/2,3/16,-1/16,-1/8,5/16,1/16},
|
|
|
|
{-1/2,-5/16,-1/16,-1/8,-3/16,1/16}},
|
|
|
|
connect_back = {{-1/16,3/16,1/8,1/16,5/16,1/2},
|
|
|
|
{-1/16,-5/16,1/8,1/16,-3/16,1/2}},
|
|
|
|
connect_right = {{1/8,3/16,-1/16,1/2,5/16,1/16},
|
|
|
|
{1/8,-5/16,-1/16,1/2,-3/16,1/16}},
|
|
|
|
},
|
|
|
|
connects_to = {"group:fence", "group:wood", "group:tree"},
|
Create API for fence.register, and use it.
This converts the call to minetest.register() for the default
fence node, so it can be called by other mods to quickly
setup other fences.
Since this creates an API, insert it into the game_api.txt.
The api looks like minetest.register(name, {def}), and has two
uncommon fields: "texture" and "material". Any normal nodedef
property can be passed through, except "drawtype". The "fence"
group will always be added.
The default fence recipe is modified to be as follows:
wood, stick, wood
wood, stick, wood
This recipe yields 4 fence nodes.
This allows us to create according recipes for acacia, pine,
aspen, and junglewood fences without adding new stick types:
pine wood, stick, pine wood
pine wood, stick, pine wood
This is a from-scratch implementation, written by heart but inspired
by (#665 - Add many wooden fences).
Stick and fences nodes are named in a consistent way.
2015-12-15 06:49:20 +01:00
|
|
|
inventory_image = fence_texture,
|
|
|
|
wield_image = fence_texture,
|
2015-12-15 06:49:20 +01:00
|
|
|
tiles = {def.texture},
|
Create API for fence.register, and use it.
This converts the call to minetest.register() for the default
fence node, so it can be called by other mods to quickly
setup other fences.
Since this creates an API, insert it into the game_api.txt.
The api looks like minetest.register(name, {def}), and has two
uncommon fields: "texture" and "material". Any normal nodedef
property can be passed through, except "drawtype". The "fence"
group will always be added.
The default fence recipe is modified to be as follows:
wood, stick, wood
wood, stick, wood
This recipe yields 4 fence nodes.
This allows us to create according recipes for acacia, pine,
aspen, and junglewood fences without adding new stick types:
pine wood, stick, pine wood
pine wood, stick, pine wood
This is a from-scratch implementation, written by heart but inspired
by (#665 - Add many wooden fences).
Stick and fences nodes are named in a consistent way.
2015-12-15 06:49:20 +01:00
|
|
|
sunlight_propagates = true,
|
|
|
|
is_ground_content = false,
|
|
|
|
groups = {},
|
|
|
|
}
|
|
|
|
for k, v in pairs(default_fields) do
|
2017-08-13 12:47:43 +02:00
|
|
|
if def[k] == nil then
|
Create API for fence.register, and use it.
This converts the call to minetest.register() for the default
fence node, so it can be called by other mods to quickly
setup other fences.
Since this creates an API, insert it into the game_api.txt.
The api looks like minetest.register(name, {def}), and has two
uncommon fields: "texture" and "material". Any normal nodedef
property can be passed through, except "drawtype". The "fence"
group will always be added.
The default fence recipe is modified to be as follows:
wood, stick, wood
wood, stick, wood
This recipe yields 4 fence nodes.
This allows us to create according recipes for acacia, pine,
aspen, and junglewood fences without adding new stick types:
pine wood, stick, pine wood
pine wood, stick, pine wood
This is a from-scratch implementation, written by heart but inspired
by (#665 - Add many wooden fences).
Stick and fences nodes are named in a consistent way.
2015-12-15 06:49:20 +01:00
|
|
|
def[k] = v
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Always add to the fence group, even if no group provided
|
|
|
|
def.groups.fence = 1
|
|
|
|
|
|
|
|
def.texture = nil
|
|
|
|
def.material = nil
|
|
|
|
|
|
|
|
minetest.register_node(name, def)
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2013-12-02 19:23:29 +01:00
|
|
|
--
|
2013-05-19 18:43:04 +02:00
|
|
|
-- Leafdecay
|
|
|
|
--
|
|
|
|
|
2016-08-07 04:54:08 +02:00
|
|
|
-- Prevent decay of placed leaves
|
2013-05-19 18:43:04 +02:00
|
|
|
|
2014-12-06 11:08:41 +01:00
|
|
|
default.after_place_leaves = function(pos, placer, itemstack, pointed_thing)
|
2017-10-01 15:41:58 +02:00
|
|
|
if placer and placer:is_player() and not placer:get_player_control().sneak then
|
2016-02-23 00:28:43 +01:00
|
|
|
local node = minetest.get_node(pos)
|
|
|
|
node.param2 = 1
|
|
|
|
minetest.set_node(pos, node)
|
|
|
|
end
|
2014-12-06 11:08:41 +01:00
|
|
|
end
|
|
|
|
|
Leafdecay: Node timer based implementation, API
This implements a node-timer based leafdecay mechanism, and exposes
an API to use it in mods.
The API is documented in game_api.txt.
`default.register_leafdecay(leafdecaydef)`
`leafdecaydef` is a table, with following members:
{
trunks = { "default:tree"}, -- nodes considered trunks
leaves = { "default:leaves", "default:apple"}, -- nodes considered leaves
radius = 3, -- activates leafdecay this far from the trunk
}
The algorithm will drop `leaves` items in the area if no `trunks` are found
in the `trunk_radius` sized area around the position of the leaf. If a node
listed in `leaves` has a group `leafdecay_drop > 0`, then the item is dropped,
otherwise the item is removed but not dropped.
The algorithm also implements a value `default.leafdecay_speed` (default
15) which can be modified to increase or decrease of the leaf decay. The
algorithm will vary the actual speed a bit to introduce randomness.
Leaf decay is randomized by 0.1 seconds to reduce the chance that
decay happens many times on the same second interval. This requires
nodetimer_interval to be set to values lower than 1.0 to have an
effect.
The leaves will decay between 2 and 10 seconds after digging the trunk,
and happen at non-integer second intervals.
-- The API was added by sofar.
2017-02-08 01:28:02 +01:00
|
|
|
-- Leafdecay
|
|
|
|
local function leafdecay_after_destruct(pos, oldnode, def)
|
|
|
|
for _, v in pairs(minetest.find_nodes_in_area(vector.subtract(pos, def.radius),
|
|
|
|
vector.add(pos, def.radius), def.leaves)) do
|
|
|
|
local node = minetest.get_node(v)
|
2017-03-30 06:06:49 +02:00
|
|
|
local timer = minetest.get_node_timer(v)
|
|
|
|
if node.param2 == 0 and not timer:is_started() then
|
|
|
|
timer:start(math.random(20, 120) / 10)
|
2013-05-19 18:43:04 +02:00
|
|
|
end
|
Leafdecay: Node timer based implementation, API
This implements a node-timer based leafdecay mechanism, and exposes
an API to use it in mods.
The API is documented in game_api.txt.
`default.register_leafdecay(leafdecaydef)`
`leafdecaydef` is a table, with following members:
{
trunks = { "default:tree"}, -- nodes considered trunks
leaves = { "default:leaves", "default:apple"}, -- nodes considered leaves
radius = 3, -- activates leafdecay this far from the trunk
}
The algorithm will drop `leaves` items in the area if no `trunks` are found
in the `trunk_radius` sized area around the position of the leaf. If a node
listed in `leaves` has a group `leafdecay_drop > 0`, then the item is dropped,
otherwise the item is removed but not dropped.
The algorithm also implements a value `default.leafdecay_speed` (default
15) which can be modified to increase or decrease of the leaf decay. The
algorithm will vary the actual speed a bit to introduce randomness.
Leaf decay is randomized by 0.1 seconds to reduce the chance that
decay happens many times on the same second interval. This requires
nodetimer_interval to be set to values lower than 1.0 to have an
effect.
The leaves will decay between 2 and 10 seconds after digging the trunk,
and happen at non-integer second intervals.
-- The API was added by sofar.
2017-02-08 01:28:02 +01:00
|
|
|
end
|
|
|
|
end
|
2016-08-07 04:54:08 +02:00
|
|
|
|
Leafdecay: Node timer based implementation, API
This implements a node-timer based leafdecay mechanism, and exposes
an API to use it in mods.
The API is documented in game_api.txt.
`default.register_leafdecay(leafdecaydef)`
`leafdecaydef` is a table, with following members:
{
trunks = { "default:tree"}, -- nodes considered trunks
leaves = { "default:leaves", "default:apple"}, -- nodes considered leaves
radius = 3, -- activates leafdecay this far from the trunk
}
The algorithm will drop `leaves` items in the area if no `trunks` are found
in the `trunk_radius` sized area around the position of the leaf. If a node
listed in `leaves` has a group `leafdecay_drop > 0`, then the item is dropped,
otherwise the item is removed but not dropped.
The algorithm also implements a value `default.leafdecay_speed` (default
15) which can be modified to increase or decrease of the leaf decay. The
algorithm will vary the actual speed a bit to introduce randomness.
Leaf decay is randomized by 0.1 seconds to reduce the chance that
decay happens many times on the same second interval. This requires
nodetimer_interval to be set to values lower than 1.0 to have an
effect.
The leaves will decay between 2 and 10 seconds after digging the trunk,
and happen at non-integer second intervals.
-- The API was added by sofar.
2017-02-08 01:28:02 +01:00
|
|
|
local function leafdecay_on_timer(pos, def)
|
|
|
|
if minetest.find_node_near(pos, def.radius, def.trunks) then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
local node = minetest.get_node(pos)
|
|
|
|
local drops = minetest.get_node_drops(node.name)
|
|
|
|
for _, item in ipairs(drops) do
|
|
|
|
local is_leaf
|
|
|
|
for _, v in pairs(def.leaves) do
|
|
|
|
if v == item then
|
|
|
|
is_leaf = true
|
2013-05-19 18:43:04 +02:00
|
|
|
end
|
|
|
|
end
|
Leafdecay: Node timer based implementation, API
This implements a node-timer based leafdecay mechanism, and exposes
an API to use it in mods.
The API is documented in game_api.txt.
`default.register_leafdecay(leafdecaydef)`
`leafdecaydef` is a table, with following members:
{
trunks = { "default:tree"}, -- nodes considered trunks
leaves = { "default:leaves", "default:apple"}, -- nodes considered leaves
radius = 3, -- activates leafdecay this far from the trunk
}
The algorithm will drop `leaves` items in the area if no `trunks` are found
in the `trunk_radius` sized area around the position of the leaf. If a node
listed in `leaves` has a group `leafdecay_drop > 0`, then the item is dropped,
otherwise the item is removed but not dropped.
The algorithm also implements a value `default.leafdecay_speed` (default
15) which can be modified to increase or decrease of the leaf decay. The
algorithm will vary the actual speed a bit to introduce randomness.
Leaf decay is randomized by 0.1 seconds to reduce the chance that
decay happens many times on the same second interval. This requires
nodetimer_interval to be set to values lower than 1.0 to have an
effect.
The leaves will decay between 2 and 10 seconds after digging the trunk,
and happen at non-integer second intervals.
-- The API was added by sofar.
2017-02-08 01:28:02 +01:00
|
|
|
if minetest.get_item_group(item, "leafdecay_drop") ~= 0 or
|
|
|
|
not is_leaf then
|
|
|
|
minetest.add_item({
|
|
|
|
x = pos.x - 0.5 + math.random(),
|
|
|
|
y = pos.y - 0.5 + math.random(),
|
|
|
|
z = pos.z - 0.5 + math.random(),
|
|
|
|
}, item)
|
|
|
|
end
|
2013-05-19 18:43:04 +02:00
|
|
|
end
|
2013-11-07 17:48:00 +01:00
|
|
|
|
Leafdecay: Node timer based implementation, API
This implements a node-timer based leafdecay mechanism, and exposes
an API to use it in mods.
The API is documented in game_api.txt.
`default.register_leafdecay(leafdecaydef)`
`leafdecaydef` is a table, with following members:
{
trunks = { "default:tree"}, -- nodes considered trunks
leaves = { "default:leaves", "default:apple"}, -- nodes considered leaves
radius = 3, -- activates leafdecay this far from the trunk
}
The algorithm will drop `leaves` items in the area if no `trunks` are found
in the `trunk_radius` sized area around the position of the leaf. If a node
listed in `leaves` has a group `leafdecay_drop > 0`, then the item is dropped,
otherwise the item is removed but not dropped.
The algorithm also implements a value `default.leafdecay_speed` (default
15) which can be modified to increase or decrease of the leaf decay. The
algorithm will vary the actual speed a bit to introduce randomness.
Leaf decay is randomized by 0.1 seconds to reduce the chance that
decay happens many times on the same second interval. This requires
nodetimer_interval to be set to values lower than 1.0 to have an
effect.
The leaves will decay between 2 and 10 seconds after digging the trunk,
and happen at non-integer second intervals.
-- The API was added by sofar.
2017-02-08 01:28:02 +01:00
|
|
|
minetest.remove_node(pos)
|
|
|
|
minetest.check_for_falling(pos)
|
|
|
|
end
|
|
|
|
|
|
|
|
function default.register_leafdecay(def)
|
|
|
|
assert(def.leaves)
|
|
|
|
assert(def.trunks)
|
|
|
|
assert(def.radius)
|
|
|
|
for _, v in pairs(def.trunks) do
|
|
|
|
minetest.override_item(v, {
|
|
|
|
after_destruct = function(pos, oldnode)
|
|
|
|
leafdecay_after_destruct(pos, oldnode, def)
|
|
|
|
end,
|
|
|
|
})
|
|
|
|
end
|
|
|
|
for _, v in pairs(def.leaves) do
|
|
|
|
minetest.override_item(v, {
|
|
|
|
on_timer = function(pos)
|
|
|
|
leafdecay_on_timer(pos, def)
|
|
|
|
end,
|
|
|
|
})
|
|
|
|
end
|
|
|
|
end
|
2015-06-07 23:48:26 +02:00
|
|
|
|
2014-12-07 16:29:36 +01:00
|
|
|
--
|
Change how dirt turns to dirt_with_(something)
This changes how dirt blocks turn to dirt_with -grass, -dry_grass
or -snow.
Previously, dirt that was sunlit would turn to dirt_with_grass no
matter what, but this happened without any context, so you could
get green patches of dirt_with_grass in the middle of a savannah or
even desert.
Dirt no longer turns to covered dirt unless it's within 1 node from
another dirt_with_grass or dirt_with_dry_grass or dirt_with_snow.
This makes dirt_with_grass "growback" a lot slower, since it now only
happens on the edges, but it retains the context nicely now.
If there is any dirt with a grass or dry grass plant, or snow on top,
and enough light, we'll convert it sporadically to dirt_with_grass
or dirt_with_dry_grass or dirt_with_snow.
This allows us to plant grass of our choice in a large dirt patch,
or in a region where otherwise that type of grass is not present.
This used to be done by 2 abms, but I've combined them in to a single
ABM that is ordered to run with maximum efficiency, solving for the
most common outcome first before attempting more complex checks.
2016-04-01 06:58:59 +02:00
|
|
|
-- Convert dirt to something that fits the environment
|
2014-12-07 16:29:36 +01:00
|
|
|
--
|
|
|
|
|
|
|
|
minetest.register_abm({
|
2016-08-08 11:56:13 +02:00
|
|
|
label = "Grass spread",
|
2014-12-07 16:29:36 +01:00
|
|
|
nodenames = {"default:dirt"},
|
Change how dirt turns to dirt_with_(something)
This changes how dirt blocks turn to dirt_with -grass, -dry_grass
or -snow.
Previously, dirt that was sunlit would turn to dirt_with_grass no
matter what, but this happened without any context, so you could
get green patches of dirt_with_grass in the middle of a savannah or
even desert.
Dirt no longer turns to covered dirt unless it's within 1 node from
another dirt_with_grass or dirt_with_dry_grass or dirt_with_snow.
This makes dirt_with_grass "growback" a lot slower, since it now only
happens on the edges, but it retains the context nicely now.
If there is any dirt with a grass or dry grass plant, or snow on top,
and enough light, we'll convert it sporadically to dirt_with_grass
or dirt_with_dry_grass or dirt_with_snow.
This allows us to plant grass of our choice in a large dirt patch,
or in a region where otherwise that type of grass is not present.
This used to be done by 2 abms, but I've combined them in to a single
ABM that is ordered to run with maximum efficiency, solving for the
most common outcome first before attempting more complex checks.
2016-04-01 06:58:59 +02:00
|
|
|
neighbors = {
|
2016-09-22 12:56:15 +02:00
|
|
|
"air",
|
2016-04-16 22:53:03 +02:00
|
|
|
"group:grass",
|
|
|
|
"group:dry_grass",
|
Change how dirt turns to dirt_with_(something)
This changes how dirt blocks turn to dirt_with -grass, -dry_grass
or -snow.
Previously, dirt that was sunlit would turn to dirt_with_grass no
matter what, but this happened without any context, so you could
get green patches of dirt_with_grass in the middle of a savannah or
even desert.
Dirt no longer turns to covered dirt unless it's within 1 node from
another dirt_with_grass or dirt_with_dry_grass or dirt_with_snow.
This makes dirt_with_grass "growback" a lot slower, since it now only
happens on the edges, but it retains the context nicely now.
If there is any dirt with a grass or dry grass plant, or snow on top,
and enough light, we'll convert it sporadically to dirt_with_grass
or dirt_with_dry_grass or dirt_with_snow.
This allows us to plant grass of our choice in a large dirt patch,
or in a region where otherwise that type of grass is not present.
This used to be done by 2 abms, but I've combined them in to a single
ABM that is ordered to run with maximum efficiency, solving for the
most common outcome first before attempting more complex checks.
2016-04-01 06:58:59 +02:00
|
|
|
"default:snow",
|
|
|
|
},
|
2016-02-13 09:33:58 +01:00
|
|
|
interval = 6,
|
2016-10-05 22:07:05 +02:00
|
|
|
chance = 50,
|
2015-11-05 02:17:13 +01:00
|
|
|
catch_up = false,
|
2014-12-07 16:29:36 +01:00
|
|
|
action = function(pos, node)
|
2016-09-22 12:56:15 +02:00
|
|
|
-- Check for darkness: night, shadow or under a light-blocking node
|
|
|
|
-- Returns if ignore above
|
2015-06-07 23:48:26 +02:00
|
|
|
local above = {x = pos.x, y = pos.y + 1, z = pos.z}
|
Change how dirt turns to dirt_with_(something)
This changes how dirt blocks turn to dirt_with -grass, -dry_grass
or -snow.
Previously, dirt that was sunlit would turn to dirt_with_grass no
matter what, but this happened without any context, so you could
get green patches of dirt_with_grass in the middle of a savannah or
even desert.
Dirt no longer turns to covered dirt unless it's within 1 node from
another dirt_with_grass or dirt_with_dry_grass or dirt_with_snow.
This makes dirt_with_grass "growback" a lot slower, since it now only
happens on the edges, but it retains the context nicely now.
If there is any dirt with a grass or dry grass plant, or snow on top,
and enough light, we'll convert it sporadically to dirt_with_grass
or dirt_with_dry_grass or dirt_with_snow.
This allows us to plant grass of our choice in a large dirt patch,
or in a region where otherwise that type of grass is not present.
This used to be done by 2 abms, but I've combined them in to a single
ABM that is ordered to run with maximum efficiency, solving for the
most common outcome first before attempting more complex checks.
2016-04-01 06:58:59 +02:00
|
|
|
if (minetest.get_node_light(above) or 0) < 13 then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2016-09-22 12:56:15 +02:00
|
|
|
-- Look for spreading dirt-type neighbours
|
|
|
|
local p2 = minetest.find_node_near(pos, 1, "group:spreading_dirt_type")
|
Change how dirt turns to dirt_with_(something)
This changes how dirt blocks turn to dirt_with -grass, -dry_grass
or -snow.
Previously, dirt that was sunlit would turn to dirt_with_grass no
matter what, but this happened without any context, so you could
get green patches of dirt_with_grass in the middle of a savannah or
even desert.
Dirt no longer turns to covered dirt unless it's within 1 node from
another dirt_with_grass or dirt_with_dry_grass or dirt_with_snow.
This makes dirt_with_grass "growback" a lot slower, since it now only
happens on the edges, but it retains the context nicely now.
If there is any dirt with a grass or dry grass plant, or snow on top,
and enough light, we'll convert it sporadically to dirt_with_grass
or dirt_with_dry_grass or dirt_with_snow.
This allows us to plant grass of our choice in a large dirt patch,
or in a region where otherwise that type of grass is not present.
This used to be done by 2 abms, but I've combined them in to a single
ABM that is ordered to run with maximum efficiency, solving for the
most common outcome first before attempting more complex checks.
2016-04-01 06:58:59 +02:00
|
|
|
if p2 then
|
2016-09-22 12:56:15 +02:00
|
|
|
local n3 = minetest.get_node(p2)
|
|
|
|
minetest.set_node(pos, {name = n3.name})
|
Change how dirt turns to dirt_with_(something)
This changes how dirt blocks turn to dirt_with -grass, -dry_grass
or -snow.
Previously, dirt that was sunlit would turn to dirt_with_grass no
matter what, but this happened without any context, so you could
get green patches of dirt_with_grass in the middle of a savannah or
even desert.
Dirt no longer turns to covered dirt unless it's within 1 node from
another dirt_with_grass or dirt_with_dry_grass or dirt_with_snow.
This makes dirt_with_grass "growback" a lot slower, since it now only
happens on the edges, but it retains the context nicely now.
If there is any dirt with a grass or dry grass plant, or snow on top,
and enough light, we'll convert it sporadically to dirt_with_grass
or dirt_with_dry_grass or dirt_with_snow.
This allows us to plant grass of our choice in a large dirt patch,
or in a region where otherwise that type of grass is not present.
This used to be done by 2 abms, but I've combined them in to a single
ABM that is ordered to run with maximum efficiency, solving for the
most common outcome first before attempting more complex checks.
2016-04-01 06:58:59 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2016-09-22 12:56:15 +02:00
|
|
|
-- Else, any seeding nodes on top?
|
|
|
|
local name = minetest.get_node(above).name
|
|
|
|
-- Snow check is cheapest, so comes first
|
Change how dirt turns to dirt_with_(something)
This changes how dirt blocks turn to dirt_with -grass, -dry_grass
or -snow.
Previously, dirt that was sunlit would turn to dirt_with_grass no
matter what, but this happened without any context, so you could
get green patches of dirt_with_grass in the middle of a savannah or
even desert.
Dirt no longer turns to covered dirt unless it's within 1 node from
another dirt_with_grass or dirt_with_dry_grass or dirt_with_snow.
This makes dirt_with_grass "growback" a lot slower, since it now only
happens on the edges, but it retains the context nicely now.
If there is any dirt with a grass or dry grass plant, or snow on top,
and enough light, we'll convert it sporadically to dirt_with_grass
or dirt_with_dry_grass or dirt_with_snow.
This allows us to plant grass of our choice in a large dirt patch,
or in a region where otherwise that type of grass is not present.
This used to be done by 2 abms, but I've combined them in to a single
ABM that is ordered to run with maximum efficiency, solving for the
most common outcome first before attempting more complex checks.
2016-04-01 06:58:59 +02:00
|
|
|
if name == "default:snow" then
|
|
|
|
minetest.set_node(pos, {name = "default:dirt_with_snow"})
|
2016-09-22 12:56:15 +02:00
|
|
|
-- Most likely case first
|
2016-04-16 22:53:03 +02:00
|
|
|
elseif minetest.get_item_group(name, "grass") ~= 0 then
|
Change how dirt turns to dirt_with_(something)
This changes how dirt blocks turn to dirt_with -grass, -dry_grass
or -snow.
Previously, dirt that was sunlit would turn to dirt_with_grass no
matter what, but this happened without any context, so you could
get green patches of dirt_with_grass in the middle of a savannah or
even desert.
Dirt no longer turns to covered dirt unless it's within 1 node from
another dirt_with_grass or dirt_with_dry_grass or dirt_with_snow.
This makes dirt_with_grass "growback" a lot slower, since it now only
happens on the edges, but it retains the context nicely now.
If there is any dirt with a grass or dry grass plant, or snow on top,
and enough light, we'll convert it sporadically to dirt_with_grass
or dirt_with_dry_grass or dirt_with_snow.
This allows us to plant grass of our choice in a large dirt patch,
or in a region where otherwise that type of grass is not present.
This used to be done by 2 abms, but I've combined them in to a single
ABM that is ordered to run with maximum efficiency, solving for the
most common outcome first before attempting more complex checks.
2016-04-01 06:58:59 +02:00
|
|
|
minetest.set_node(pos, {name = "default:dirt_with_grass"})
|
2016-04-16 22:53:03 +02:00
|
|
|
elseif minetest.get_item_group(name, "dry_grass") ~= 0 then
|
Change how dirt turns to dirt_with_(something)
This changes how dirt blocks turn to dirt_with -grass, -dry_grass
or -snow.
Previously, dirt that was sunlit would turn to dirt_with_grass no
matter what, but this happened without any context, so you could
get green patches of dirt_with_grass in the middle of a savannah or
even desert.
Dirt no longer turns to covered dirt unless it's within 1 node from
another dirt_with_grass or dirt_with_dry_grass or dirt_with_snow.
This makes dirt_with_grass "growback" a lot slower, since it now only
happens on the edges, but it retains the context nicely now.
If there is any dirt with a grass or dry grass plant, or snow on top,
and enough light, we'll convert it sporadically to dirt_with_grass
or dirt_with_dry_grass or dirt_with_snow.
This allows us to plant grass of our choice in a large dirt patch,
or in a region where otherwise that type of grass is not present.
This used to be done by 2 abms, but I've combined them in to a single
ABM that is ordered to run with maximum efficiency, solving for the
most common outcome first before attempting more complex checks.
2016-04-01 06:58:59 +02:00
|
|
|
minetest.set_node(pos, {name = "default:dirt_with_dry_grass"})
|
|
|
|
end
|
2014-12-07 16:29:36 +01:00
|
|
|
end
|
|
|
|
})
|
|
|
|
|
2016-08-07 04:54:08 +02:00
|
|
|
|
2015-10-22 19:54:18 +02:00
|
|
|
--
|
|
|
|
-- Grass and dry grass removed in darkness
|
|
|
|
--
|
|
|
|
|
2014-12-07 16:29:36 +01:00
|
|
|
minetest.register_abm({
|
2016-08-08 11:56:13 +02:00
|
|
|
label = "Grass covered",
|
2016-09-22 12:56:15 +02:00
|
|
|
nodenames = {"group:spreading_dirt_type"},
|
2016-02-13 09:33:58 +01:00
|
|
|
interval = 8,
|
|
|
|
chance = 50,
|
2015-11-05 02:17:13 +01:00
|
|
|
catch_up = false,
|
2014-12-07 16:29:36 +01:00
|
|
|
action = function(pos, node)
|
2015-06-07 23:48:26 +02:00
|
|
|
local above = {x = pos.x, y = pos.y + 1, z = pos.z}
|
2014-12-07 16:29:36 +01:00
|
|
|
local name = minetest.get_node(above).name
|
|
|
|
local nodedef = minetest.registered_nodes[name]
|
2015-06-07 23:48:26 +02:00
|
|
|
if name ~= "ignore" and nodedef and not ((nodedef.sunlight_propagates or
|
|
|
|
nodedef.paramtype == "light") and
|
|
|
|
nodedef.liquidtype == "none") then
|
2014-12-07 16:29:36 +01:00
|
|
|
minetest.set_node(pos, {name = "default:dirt"})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
})
|
2015-06-07 23:48:26 +02:00
|
|
|
|
2015-10-22 19:54:18 +02:00
|
|
|
|
|
|
|
--
|
|
|
|
-- Moss growth on cobble near water
|
|
|
|
--
|
|
|
|
|
|
|
|
minetest.register_abm({
|
2016-08-08 11:56:13 +02:00
|
|
|
label = "Moss growth",
|
2016-11-30 09:59:49 +01:00
|
|
|
nodenames = {"default:cobble", "stairs:slab_cobble", "stairs:stair_cobble", "walls:cobble"},
|
2015-10-22 19:54:18 +02:00
|
|
|
neighbors = {"group:water"},
|
2016-02-13 09:33:58 +01:00
|
|
|
interval = 16,
|
2015-10-22 19:54:18 +02:00
|
|
|
chance = 200,
|
|
|
|
catch_up = false,
|
|
|
|
action = function(pos, node)
|
2016-05-30 21:03:55 +02:00
|
|
|
if node.name == "default:cobble" then
|
|
|
|
minetest.set_node(pos, {name = "default:mossycobble"})
|
|
|
|
elseif node.name == "stairs:slab_cobble" then
|
|
|
|
minetest.set_node(pos, {name = "stairs:slab_mossycobble", param2 = node.param2})
|
|
|
|
elseif node.name == "stairs:stair_cobble" then
|
|
|
|
minetest.set_node(pos, {name = "stairs:stair_mossycobble", param2 = node.param2})
|
2016-11-30 09:59:49 +01:00
|
|
|
elseif node.name == "walls:cobble" then
|
|
|
|
minetest.set_node(pos, {name = "walls:mossycobble", param2 = node.param2})
|
2016-05-30 21:03:55 +02:00
|
|
|
end
|
2015-10-22 19:54:18 +02:00
|
|
|
end
|
|
|
|
})
|
2016-07-19 02:01:59 +02:00
|
|
|
|
|
|
|
|
|
|
|
--
|
|
|
|
-- Checks if specified volume intersects a protected volume
|
|
|
|
--
|
|
|
|
|
|
|
|
function default.intersects_protection(minp, maxp, player_name, interval)
|
|
|
|
-- 'interval' is the largest allowed interval for the 3D lattice of checks
|
|
|
|
|
|
|
|
-- Compute the optimal float step 'd' for each axis so that all corners and
|
|
|
|
-- borders are checked. 'd' will be smaller or equal to 'interval'.
|
|
|
|
-- Subtracting 1e-4 ensures that the max co-ordinate will be reached by the
|
|
|
|
-- for loop (which might otherwise not be the case due to rounding errors).
|
|
|
|
local d = {}
|
|
|
|
for _, c in pairs({"x", "y", "z"}) do
|
|
|
|
if maxp[c] > minp[c] then
|
|
|
|
d[c] = (maxp[c] - minp[c]) / math.ceil((maxp[c] - minp[c]) / interval) - 1e-4
|
|
|
|
elseif maxp[c] == minp[c] then
|
|
|
|
d[c] = 1 -- Any value larger than 0 to avoid division by zero
|
|
|
|
else -- maxp[c] < minp[c], print error and treat as protection intersected
|
|
|
|
minetest.log("error", "maxp < minp in 'default.intersects_protection()'")
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
for zf = minp.z, maxp.z, d.z do
|
|
|
|
local z = math.floor(zf + 0.5)
|
|
|
|
for yf = minp.y, maxp.y, d.y do
|
|
|
|
local y = math.floor(yf + 0.5)
|
|
|
|
for xf = minp.x, maxp.x, d.x do
|
|
|
|
local x = math.floor(xf + 0.5)
|
|
|
|
if minetest.is_protected({x = x, y = y, z = z}, player_name) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return false
|
|
|
|
end
|
2016-10-12 02:49:31 +02:00
|
|
|
|
|
|
|
|
|
|
|
--
|
|
|
|
-- Coral death near air
|
|
|
|
--
|
|
|
|
|
|
|
|
minetest.register_abm({
|
|
|
|
nodenames = {"default:coral_brown", "default:coral_orange"},
|
|
|
|
neighbors = {"air"},
|
|
|
|
interval = 17,
|
|
|
|
chance = 5,
|
|
|
|
catch_up = false,
|
|
|
|
action = function(pos, node)
|
|
|
|
minetest.set_node(pos, {name = "default:coral_skeleton"})
|
|
|
|
end,
|
|
|
|
})
|
2017-02-10 20:35:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
--
|
|
|
|
-- NOTICE: This method is not an official part of the API yet!
|
|
|
|
-- This method may change in future.
|
|
|
|
--
|
|
|
|
|
|
|
|
function default.can_interact_with_node(player, pos)
|
|
|
|
if player then
|
|
|
|
if minetest.check_player_privs(player, "protection_bypass") then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
else
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
local meta = minetest.get_meta(pos)
|
2017-03-18 17:19:19 +01:00
|
|
|
local owner = meta:get_string("owner")
|
2017-02-10 20:35:26 +01:00
|
|
|
|
2017-03-18 17:19:19 +01:00
|
|
|
if not owner or owner == "" or owner == player:get_player_name() then
|
2017-03-12 14:03:37 +01:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2017-02-10 20:35:26 +01:00
|
|
|
-- is player wielding the right key?
|
|
|
|
local item = player:get_wielded_item()
|
|
|
|
if item:get_name() == "default:key" then
|
2017-03-12 14:03:37 +01:00
|
|
|
local key_meta = item:get_meta()
|
2017-02-10 20:35:26 +01:00
|
|
|
|
2017-03-12 14:03:37 +01:00
|
|
|
if key_meta:get_string("secret") == "" then
|
2017-03-16 06:03:52 +01:00
|
|
|
local key_oldmeta = item:get_metadata()
|
|
|
|
if key_oldmeta == "" or not minetest.parse_json(key_oldmeta) then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
key_meta:set_string("secret", minetest.parse_json(key_oldmeta).secret)
|
2017-03-12 14:03:37 +01:00
|
|
|
item:set_metadata("")
|
|
|
|
end
|
2017-02-10 20:35:26 +01:00
|
|
|
|
2017-03-12 14:03:37 +01:00
|
|
|
return meta:get_string("key_lock_secret") == key_meta:get_string("secret")
|
2017-02-10 20:35:26 +01:00
|
|
|
end
|
|
|
|
|
2017-03-12 14:03:37 +01:00
|
|
|
return false
|
|
|
|
end
|