Version MFF.
0
.gitignore
vendored
Normal file → Executable file
9
LICENSE
Normal file → Executable file
@ -4,15 +4,6 @@ Minetest mod moretrees
|
|||||||
All source code:
|
All source code:
|
||||||
© 2013, Vanessa Ezekowitz <vanessaezekowitz@gmail.com>
|
© 2013, Vanessa Ezekowitz <vanessaezekowitz@gmail.com>
|
||||||
Published under the terms and conditions of the WTFPL.
|
Published under the terms and conditions of the WTFPL.
|
||||||
Date & cocos palm code (date_palm.lua, cocos_palm.lua)
|
|
||||||
© 2016, Rogier <rogier777@gmail.com>
|
|
||||||
Published under the terms and conditions of the WTFPL.
|
|
||||||
All date & date palm textures, date-based food, cocos flower & green coconuts:
|
|
||||||
© 2016, Rogier <rogier777@gmail.com>
|
|
||||||
Published under the terms and conditions of CC-BY-SA-3.0 Unported.
|
|
||||||
- Three of the date palm textures are modifications of existing moretrees textures
|
|
||||||
- The green coconuts are a modification of the brown coconut
|
|
||||||
- The date cake batter is a modification of the acorn muffin batter
|
|
||||||
All sapling textures (textures/*_sapling.png):
|
All sapling textures (textures/*_sapling.png):
|
||||||
© 2013, Tim Huppertz <mitroman@naturalnet.de>
|
© 2013, Tim Huppertz <mitroman@naturalnet.de>
|
||||||
Published under the terms and conditions of CC-BY-SA-3.0 Unported.
|
Published under the terms and conditions of CC-BY-SA-3.0 Unported.
|
||||||
|
34
biome_defs.lua
Normal file → Executable file
@ -24,40 +24,6 @@ moretrees.palm_biome = {
|
|||||||
max_count = 10,
|
max_count = 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
moretrees.date_palm_biome = {
|
|
||||||
surface = "default:desert_sand",
|
|
||||||
avoid_nodes = moretrees.avoidnodes,
|
|
||||||
avoid_radius = 10,
|
|
||||||
seed_diff = 339,
|
|
||||||
min_elevation = -1,
|
|
||||||
max_elevation = 10,
|
|
||||||
near_nodes = {"default:water_source"},
|
|
||||||
near_nodes_size = 20,
|
|
||||||
near_nodes_count = 100,
|
|
||||||
near_nodes_vertical = 20,
|
|
||||||
temp_min = -0.20,
|
|
||||||
humidity_max = 0.20,
|
|
||||||
rarity = 10,
|
|
||||||
max_count = 30,
|
|
||||||
}
|
|
||||||
|
|
||||||
moretrees.date_palm_biome_2 = {
|
|
||||||
surface = "default:desert_sand",
|
|
||||||
avoid_nodes = moretrees.avoidnodes,
|
|
||||||
avoid_radius = 10,
|
|
||||||
seed_diff = 340,
|
|
||||||
min_elevation = 11,
|
|
||||||
max_elevation = 30,
|
|
||||||
near_nodes = {"default:water_source"},
|
|
||||||
near_nodes_size = 1,
|
|
||||||
near_nodes_count = 1,
|
|
||||||
near_nodes_vertical = 30,
|
|
||||||
temp_min = -0.20,
|
|
||||||
humidity_max = 0.20,
|
|
||||||
rarity = 10,
|
|
||||||
max_count = 30,
|
|
||||||
}
|
|
||||||
|
|
||||||
moretrees.apple_tree_biome = {
|
moretrees.apple_tree_biome = {
|
||||||
surface = "default:dirt_with_grass",
|
surface = "default:dirt_with_grass",
|
||||||
avoid_nodes = moretrees.avoidnodes,
|
avoid_nodes = moretrees.avoidnodes,
|
||||||
|
283
cocos_palm.lua
@ -1,283 +0,0 @@
|
|||||||
local S = moretrees.intllib
|
|
||||||
|
|
||||||
-- © 2016, Rogier <rogier777@gmail.com>
|
|
||||||
|
|
||||||
-- Some constants
|
|
||||||
|
|
||||||
local coconut_drop_ichance = 8
|
|
||||||
|
|
||||||
-- Make the cocos palm fruit trunk a real trunk (it is generated as a fruit)
|
|
||||||
local trunk = minetest.registered_nodes["moretrees:palm_trunk"]
|
|
||||||
local ftrunk = {}
|
|
||||||
local gftrunk = {}
|
|
||||||
for k,v in pairs(trunk) do
|
|
||||||
ftrunk[k] = v
|
|
||||||
gftrunk[k] = v
|
|
||||||
end
|
|
||||||
ftrunk.tiles = {}
|
|
||||||
gftrunk.tiles = {}
|
|
||||||
for k,v in pairs(trunk.tiles) do
|
|
||||||
ftrunk.tiles[k] = v
|
|
||||||
gftrunk.tiles[k] = v
|
|
||||||
end
|
|
||||||
ftrunk.drop = "moretrees:palm_trunk"
|
|
||||||
gftrunk.drop = "moretrees:palm_trunk"
|
|
||||||
ftrunk.after_destruct = function(pos, oldnode)
|
|
||||||
local coconuts = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y, z=pos.z-1}, {x=pos.x+1, y=pos.y, z=pos.z+1}, {"group:moretrees_coconut"})
|
|
||||||
for _,coconutpos in pairs(coconuts) do
|
|
||||||
-- minetest.dig_node(coconutpos) does not cause nearby coconuts to be dropped :-( ...
|
|
||||||
--minetest.dig_node(coconutpos)
|
|
||||||
local items = minetest.get_node_drops(minetest.get_node(coconutpos).name)
|
|
||||||
minetest.remove_node(coconutpos)
|
|
||||||
for _, itemname in pairs(items) do
|
|
||||||
minetest.add_item(coconutpos, itemname)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Make the different trunk types distinguishable (but barely)
|
|
||||||
ftrunk.tiles[1] = "moretrees_palm_trunk_top.png^[transformR90"
|
|
||||||
gftrunk.tiles[1] = "moretrees_palm_trunk_top.png^[transformR180"
|
|
||||||
gftrunk.description = gftrunk.description.." (gen)"
|
|
||||||
minetest.register_node("moretrees:palm_fruit_trunk", ftrunk)
|
|
||||||
minetest.register_node("moretrees:palm_fruit_trunk_gen", gftrunk)
|
|
||||||
|
|
||||||
local coconut_regrow_abm_spec = {
|
|
||||||
nodenames = { "moretrees:palm_fruit_trunk" },
|
|
||||||
interval = moretrees.coconut_flower_interval,
|
|
||||||
chance = moretrees.coconut_flower_chance,
|
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
|
||||||
local coconuts = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y, z=pos.z-1}, {x=pos.x+1, y=pos.y, z=pos.z+1}, "group:moretrees_coconut")
|
|
||||||
-- Expected growth interval increases exponentially with number of coconuts already hanging.
|
|
||||||
-- Also: if more coconuts are hanging, the chance of picking an empty spot decreases as well...
|
|
||||||
if math.random(2^#coconuts) <= 2 then
|
|
||||||
-- Grow in area of 3x3 round trunk
|
|
||||||
local dx=math.floor(math.random(3)-2)
|
|
||||||
local dz=math.floor(math.random(3)-2)
|
|
||||||
local coconutpos = {x=pos.x+dx, y=pos.y, z=pos.z+dz}
|
|
||||||
local coconutnode = minetest.get_node(coconutpos)
|
|
||||||
if coconutnode.name == "air" then
|
|
||||||
minetest.set_node(coconutpos, {name="moretrees:coconut_0"})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
}
|
|
||||||
if moretrees.coconuts_regrow then
|
|
||||||
minetest.register_abm(coconut_regrow_abm_spec)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Spawn initial coconuts
|
|
||||||
|
|
||||||
-- Spawn initial coconuts
|
|
||||||
-- (Instead of coconuts, a generated-palm fruit trunk is generated with the tree. This
|
|
||||||
-- ABM converts the trunk to a regular fruit trunk, and spawns some coconuts)
|
|
||||||
minetest.register_abm({
|
|
||||||
nodenames = { "moretrees:palm_fruit_trunk_gen" },
|
|
||||||
interval = 1,
|
|
||||||
chance = 1,
|
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
|
||||||
minetest.swap_node(pos, {name="moretrees:palm_fruit_trunk"})
|
|
||||||
local poslist = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y, z=pos.z-1}, {x=pos.x+1, y=pos.y, z=pos.z+1}, "air")
|
|
||||||
local genlist = {}
|
|
||||||
for k,v in pairs(poslist) do
|
|
||||||
genlist[k] = {x = math.random(100), pos = v}
|
|
||||||
end
|
|
||||||
table.sort(genlist, function(a, b) return a.x < b.x; end)
|
|
||||||
local gen
|
|
||||||
local count = 0
|
|
||||||
for _,gen in pairs(genlist) do
|
|
||||||
minetest.set_node(gen.pos, {name = "moretrees:coconut_3"})
|
|
||||||
count = count + 1
|
|
||||||
if count == 4 then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Register coconuts, and make them regrow
|
|
||||||
|
|
||||||
local coconut_growfn = function(pos, elapsed)
|
|
||||||
local node = minetest.get_node(pos)
|
|
||||||
local delay = moretrees.coconut_grow_interval
|
|
||||||
if not node then
|
|
||||||
return
|
|
||||||
elseif not moretrees.coconuts_regrow then
|
|
||||||
-- Regrowing has been turned off. Make coconust grow instantly
|
|
||||||
minetest.swap_node(pos, {name="moretrees:coconut_3"})
|
|
||||||
return
|
|
||||||
elseif node.name == "moretrees:coconut_3" then
|
|
||||||
-- Drop coconuts (i.e. remove them), so that new coconuts can grow.
|
|
||||||
-- Coconuts will drop as items with a small chance
|
|
||||||
if math.random(coconut_drop_ichance) == 1 then
|
|
||||||
if moretrees.coconut_item_drop_ichance > 0 and math.random(moretrees.coconut_item_drop_ichance) == 1 then
|
|
||||||
local items = minetest.get_node_drops(minetest.get_node(pos).name)
|
|
||||||
for _, itemname in pairs(items) do
|
|
||||||
minetest.add_item(pos, itemname)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
minetest.remove_node(pos)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- Grow coconuts to the next stage
|
|
||||||
local offset = string.len("moretrees:coconut_x")
|
|
||||||
local n = string.sub(node.name, offset)
|
|
||||||
minetest.swap_node(pos, {name=string.sub(node.name, 1, offset-1)..n+1})
|
|
||||||
end
|
|
||||||
-- Don't catch up when elapsed time is large. Regular visits are needed for growth...
|
|
||||||
local timer = minetest.get_node_timer(pos)
|
|
||||||
timer:start(delay + math.random(moretrees.coconut_grow_interval))
|
|
||||||
end
|
|
||||||
|
|
||||||
local coconut_starttimer = function(pos, elapsed)
|
|
||||||
local timer = minetest.get_node_timer(pos)
|
|
||||||
local base_interval = moretrees.coconut_grow_interval * 2 / 3
|
|
||||||
timer:set(base_interval + math.random(base_interval), elapsed or 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
for _,suffix in ipairs({"_0", "_1", "_2", "_3", ""}) do
|
|
||||||
local name
|
|
||||||
if suffix == "_0" then
|
|
||||||
name = S("Coconut Flower")
|
|
||||||
else
|
|
||||||
name = S("Coconut")
|
|
||||||
end
|
|
||||||
local drop = ""
|
|
||||||
local coco_group = 1
|
|
||||||
local tile = "moretrees_coconut"..suffix..".png"
|
|
||||||
local timerfn = coconut_growfn
|
|
||||||
local constructfn = coconut_starttimer
|
|
||||||
if suffix == "_3" then
|
|
||||||
drop = "moretrees:coconut"
|
|
||||||
tile = "moretrees_coconut.png"
|
|
||||||
elseif suffix == "" then
|
|
||||||
drop = nil
|
|
||||||
coco_group = nil
|
|
||||||
timerfn = nil
|
|
||||||
constructfn = nil
|
|
||||||
end
|
|
||||||
local coconutdef = {
|
|
||||||
description = name,
|
|
||||||
tiles = {tile},
|
|
||||||
drawtype = "plantlike",
|
|
||||||
paramtype = "light",
|
|
||||||
sunlight_propagates = true,
|
|
||||||
walkable = false,
|
|
||||||
groups = { fleshy=3, dig_immediate=3, flammable=2, moretrees_coconut=coco_group },
|
|
||||||
inventory_image = tile.."^[transformR180",
|
|
||||||
wield_image = tile.."^[transformR180",
|
|
||||||
sounds = default.node_sound_defaults(),
|
|
||||||
drop = drop,
|
|
||||||
selection_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {-0.3, -0.3, -0.3, 0.3, 0.3, 0.3}
|
|
||||||
},
|
|
||||||
on_timer = timerfn,
|
|
||||||
on_construct = constructfn,
|
|
||||||
|
|
||||||
}
|
|
||||||
minetest.register_node("moretrees:coconut"..suffix, coconutdef)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- convert exisiting cocos palms. This is a bit tricky...
|
|
||||||
-- Try to make sure that this is indeed a generated tree, and not manually-placed trunks and/or coconuts
|
|
||||||
if moretrees.coconuts_convert_existing_palms then
|
|
||||||
local spec = {
|
|
||||||
name = "moretrees:convert_existing_cocos_palms_to_regrow_coconuts",
|
|
||||||
nodenames = "moretrees:coconut",
|
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
|
||||||
local trunks
|
|
||||||
local cvtrunks
|
|
||||||
local leaves
|
|
||||||
local coconuts
|
|
||||||
-- One regular trunk must be adjacent to the coconut
|
|
||||||
trunks = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y, z=pos.z-1}, {x=pos.x+1, y=pos.y, z=pos.z+1}, "moretrees:palm_trunk")
|
|
||||||
if #trunks ~= 1 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local tpos = trunks[1]
|
|
||||||
-- 1 or 2 other trunks must be one level below to the trunk being converted.
|
|
||||||
trunks = minetest.find_nodes_in_area({x=tpos.x-1, y=tpos.y-1, z=tpos.z-1}, {x=tpos.x+1, y=tpos.y-1, z=tpos.z+1}, "moretrees:palm_trunk")
|
|
||||||
if #trunks < 1 or #trunks > 2 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- 1 or 2 other trunks must be two levels below to the trunk being converted.
|
|
||||||
trunks = minetest.find_nodes_in_area({x=tpos.x-1, y=tpos.y-2, z=tpos.z-1}, {x=tpos.x+1, y=tpos.y-2, z=tpos.z+1}, "moretrees:palm_trunk")
|
|
||||||
if #trunks < 1 or #trunks > 2 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- 1 or 2 trunks must at the level of the trunk being converted.
|
|
||||||
cvtrunks = minetest.find_nodes_in_area({x=tpos.x-1, y=tpos.y, z=tpos.z-1}, {x=tpos.x+1, y=tpos.y, z=tpos.z+1}, "moretrees:palm_trunk")
|
|
||||||
if #cvtrunks < 1 or #cvtrunks > 2 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- No trunks may be one level above the trunk being converted.
|
|
||||||
trunks = minetest.find_nodes_in_area({x=tpos.x-1, y=tpos.y+1, z=tpos.z-1}, {x=tpos.x+1, y=tpos.y+1, z=tpos.z+1}, "moretrees:palm_trunk")
|
|
||||||
if #trunks ~= 0 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- Leaves must be one level above the trunk being converted.
|
|
||||||
leaves = minetest.find_nodes_in_area({x=tpos.x-1, y=tpos.y+1, z=tpos.z-1}, {x=tpos.x+1, y=tpos.y+1, z=tpos.z+1}, "moretrees:palm_leaves")
|
|
||||||
if #leaves == 0 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- Leaves must be two levels above the trunk being converted.
|
|
||||||
leaves = minetest.find_nodes_in_area({x=tpos.x-1, y=tpos.y+2, z=tpos.z-1}, {x=tpos.x+1, y=tpos.y+2, z=tpos.z+1}, "moretrees:palm_leaves")
|
|
||||||
if #leaves == 0 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- No cocos fruit trunk may already be adjacent to the coconut
|
|
||||||
trunks = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y, z=pos.z-1}, {x=pos.x+1, y=pos.y, z=pos.z+1}, "moretrees:palm_fruit_trunk")
|
|
||||||
if #trunks ~= 0 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- No cocos fruit trunk may be adjacent to or below the trunk being converted.
|
|
||||||
trunks = minetest.find_nodes_in_area({x=tpos.x-1, y=tpos.y-2, z=tpos.z-1}, {x=tpos.x+1, y=tpos.y, z=tpos.z+1}, "moretrees:palm_fruit_trunk")
|
|
||||||
if #trunks ~= 0 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- Convert trunk and all coconuts nearby. Maybe convert 2 trunks, just in case...
|
|
||||||
for _, tpos in pairs(cvtrunks) do
|
|
||||||
minetest.swap_node(tpos, {name = "moretrees:palm_fruit_trunk"})
|
|
||||||
coconuts = minetest.find_nodes_in_area({x=tpos.x-1, y=tpos.y, z=tpos.z-1}, {x=tpos.x+1, y=tpos.y, z=tpos.z+1}, "moretrees:coconut")
|
|
||||||
for _, coconutpos in pairs(coconuts) do
|
|
||||||
minetest.set_node(coconutpos, {name = "moretrees:coconut_3"})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
if minetest.register_lbm then
|
|
||||||
minetest.register_lbm(spec)
|
|
||||||
else
|
|
||||||
spec.interval = 3691
|
|
||||||
spec.chance = 10
|
|
||||||
minetest.register_abm(spec)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- If regrowing was previously disabled, but is enabled now, make sure timers are started for existing coconuts
|
|
||||||
if moretrees.coconuts_regrow then
|
|
||||||
local spec = {
|
|
||||||
name = "moretrees:restart_coconut_regrow_timer",
|
|
||||||
nodenames = "group:moretrees_coconut",
|
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
|
||||||
local timer = minetest.get_node_timer(pos)
|
|
||||||
if not timer:is_started() then
|
|
||||||
coconut_starttimer(pos)
|
|
||||||
else
|
|
||||||
local timeout = timer:get_timeout()
|
|
||||||
local elapsed = timer:get_elapsed()
|
|
||||||
if timeout - elapsed > moretrees.coconut_grow_interval * 4/3 then
|
|
||||||
coconut_starttimer(pos, math.random(moretrees.coconut_grow_interval * 4/3))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
if minetest.register_lbm then
|
|
||||||
minetest.register_lbm(spec)
|
|
||||||
else
|
|
||||||
spec.interval = 3659
|
|
||||||
spec.chance = 10
|
|
||||||
minetest.register_abm(spec)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
90
crafts.lua
Normal file → Executable file
@ -3,6 +3,8 @@ local S = moretrees.intllib
|
|||||||
for i in ipairs(moretrees.treelist) do
|
for i in ipairs(moretrees.treelist) do
|
||||||
local treename = moretrees.treelist[i][1]
|
local treename = moretrees.treelist[i][1]
|
||||||
|
|
||||||
|
-- MODIFICATION MADE FOR MFF //MFF(Mg|08/12/15)
|
||||||
|
if minetest.registered_items["moretrees:" .. treename .. "_trunk_sideways"] then
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = "moretrees:"..treename.."_trunk 2",
|
output = "moretrees:"..treename.."_trunk 2",
|
||||||
recipe = {
|
recipe = {
|
||||||
@ -15,15 +17,16 @@ for i in ipairs(moretrees.treelist) do
|
|||||||
type = "shapeless",
|
type = "shapeless",
|
||||||
output = "moretrees:"..treename.."_planks 4",
|
output = "moretrees:"..treename.."_planks 4",
|
||||||
recipe = {
|
recipe = {
|
||||||
"moretrees:"..treename.."_trunk"
|
"moretrees:"..treename.."_trunk_sideways"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
end
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
type = "shapeless",
|
type = "shapeless",
|
||||||
output = "moretrees:"..treename.."_planks 4",
|
output = "moretrees:"..treename.."_planks 4",
|
||||||
recipe = {
|
recipe = {
|
||||||
"moretrees:"..treename.."_trunk_sideways"
|
"moretrees:"..treename.."_trunk"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -63,35 +66,6 @@ minetest.register_craftitem("moretrees:raw_coconut", {
|
|||||||
on_use = minetest.item_eat(4),
|
on_use = minetest.item_eat(4),
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_craftitem("moretrees:date", {
|
|
||||||
description = S("Date"),
|
|
||||||
inventory_image = "moretrees_date.png",
|
|
||||||
on_use = minetest.item_eat(1),
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craftitem("moretrees:date_nut_snack", {
|
|
||||||
description = S("Date & nut snack"),
|
|
||||||
inventory_image = "moretrees_date_nut_snack.png",
|
|
||||||
on_use = minetest.item_eat(4),
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craftitem("moretrees:date_nut_batter", {
|
|
||||||
description = S("Date-nut cake batter"),
|
|
||||||
inventory_image = "moretrees_date_nut_batter.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craftitem("moretrees:date_nut_cake", {
|
|
||||||
description = S("Date-nut cake"),
|
|
||||||
inventory_image = "moretrees_date_nut_cake.png",
|
|
||||||
on_use = minetest.item_eat(32),
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craftitem("moretrees:date_nut_bar", {
|
|
||||||
description = S("Date-nut energy bar"),
|
|
||||||
inventory_image = "moretrees_date_nut_bar.png",
|
|
||||||
on_use = minetest.item_eat(4),
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craftitem("moretrees:acorn_muffin_batter", {
|
minetest.register_craftitem("moretrees:acorn_muffin_batter", {
|
||||||
description = S("Acorn Muffin batter"),
|
description = S("Acorn Muffin batter"),
|
||||||
inventory_image = "moretrees_acorn_muffin_batter.png",
|
inventory_image = "moretrees_acorn_muffin_batter.png",
|
||||||
@ -138,60 +112,6 @@ for i in ipairs(moretrees.cutting_tools) do
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
type = "shapeless",
|
|
||||||
output = "moretrees:date_nut_snack",
|
|
||||||
recipe = {
|
|
||||||
"moretrees:date",
|
|
||||||
"moretrees:date",
|
|
||||||
"moretrees:date",
|
|
||||||
"moretrees:spruce_nuts",
|
|
||||||
"moretrees:cedar_nuts",
|
|
||||||
"moretrees:fir_nuts",
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
-- The date-nut cake is an exceptional food item due to its highly
|
|
||||||
-- concentrated nature (32 food units). Because of that, it requires
|
|
||||||
-- many different ingredients, and, starting from the base ingredients
|
|
||||||
-- found or harvested in nature, it requires many steps to prepare.
|
|
||||||
local flour
|
|
||||||
if minetest.registered_nodes["farming:flour"] then
|
|
||||||
flour = "farming:flour"
|
|
||||||
else
|
|
||||||
flour = "moretrees:acorn_muffin_batter"
|
|
||||||
end
|
|
||||||
minetest.register_craft({
|
|
||||||
type = "shapeless",
|
|
||||||
output = "moretrees:date_nut_batter",
|
|
||||||
recipe = {
|
|
||||||
"moretrees:date_nut_snack",
|
|
||||||
"moretrees:date_nut_snack",
|
|
||||||
"moretrees:date_nut_snack",
|
|
||||||
"moretrees:coconut_milk",
|
|
||||||
"moretrees:date_nut_snack",
|
|
||||||
"moretrees:raw_coconut",
|
|
||||||
"moretrees:coconut_milk",
|
|
||||||
flour,
|
|
||||||
"moretrees:raw_coconut",
|
|
||||||
},
|
|
||||||
replacements = {
|
|
||||||
{ "moretrees:coconut_milk", "vessels:drinking_glass 2" }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
type = "cooking",
|
|
||||||
output = "moretrees:date_nut_cake",
|
|
||||||
recipe = "moretrees:date_nut_batter",
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
type = "shapeless",
|
|
||||||
output = "moretrees:date_nut_bar 8",
|
|
||||||
recipe = {"moretrees:date_nut_cake"},
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
type = "shapeless",
|
type = "shapeless",
|
||||||
output = "moretrees:acorn_muffin_batter",
|
output = "moretrees:acorn_muffin_batter",
|
||||||
|
731
date_palm.lua
@ -1,731 +0,0 @@
|
|||||||
-- Date palms.
|
|
||||||
--
|
|
||||||
-- Date palms grow in hot and dry desert, but they require water. This makes them
|
|
||||||
-- a bit harder to find. If found in the middle of the desert, their presence
|
|
||||||
-- indicates a water source below the surface.
|
|
||||||
--
|
|
||||||
-- As an additional feature (which can be disabled), dates automatically regrow after
|
|
||||||
-- harvesting (provided a male tree is sufficiently nearby).
|
|
||||||
-- If regrowing is enabled, then ripe dates will not hang forever. Most will disappear
|
|
||||||
-- (e.g. eaten by birds, ...), and a small fraction will drop as items.
|
|
||||||
|
|
||||||
-- © 2016, Rogier <rogier777@gmail.com>
|
|
||||||
-- License: WTFPL
|
|
||||||
|
|
||||||
local S = moretrees.intllib
|
|
||||||
|
|
||||||
-- Some constants
|
|
||||||
|
|
||||||
local dates_drop_ichance = 4
|
|
||||||
local stems_drop_ichance = 4
|
|
||||||
local flowers_wither_ichance = 3
|
|
||||||
|
|
||||||
-- implementation
|
|
||||||
|
|
||||||
-- Make the date palm fruit trunk a real trunk (it is generated as a fruit)
|
|
||||||
local trunk = minetest.registered_nodes["moretrees:date_palm_trunk"]
|
|
||||||
local ftrunk = {}
|
|
||||||
local fftrunk = {}
|
|
||||||
local mftrunk = {}
|
|
||||||
for k,v in pairs(trunk) do
|
|
||||||
ftrunk[k] = v
|
|
||||||
end
|
|
||||||
ftrunk.tiles = {}
|
|
||||||
for k,v in pairs(trunk.tiles) do
|
|
||||||
ftrunk.tiles[k] = v
|
|
||||||
end
|
|
||||||
ftrunk.drop = "moretrees:date_palm_trunk"
|
|
||||||
ftrunk.after_destruct = function(pos, oldnode)
|
|
||||||
local dates = minetest.find_nodes_in_area({x=pos.x-2, y=pos.y, z=pos.z-2}, {x=pos.x+2, y=pos.y, z=pos.z+2}, {"group:moretrees_dates"})
|
|
||||||
for _,datespos in pairs(dates) do
|
|
||||||
-- minetest.dig_node(datespos) does not cause nearby dates to be dropped :-( ...
|
|
||||||
local items = minetest.get_node_drops(minetest.get_node(datespos).name)
|
|
||||||
minetest.remove_node(datespos)
|
|
||||||
for _, itemname in pairs(items) do
|
|
||||||
minetest.add_item(datespos, itemname)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for k,v in pairs(ftrunk) do
|
|
||||||
mftrunk[k] = v
|
|
||||||
fftrunk[k] = v
|
|
||||||
end
|
|
||||||
fftrunk.tiles = {}
|
|
||||||
mftrunk.tiles = {}
|
|
||||||
for k,v in pairs(trunk.tiles) do
|
|
||||||
fftrunk.tiles[k] = v
|
|
||||||
mftrunk.tiles[k] = v
|
|
||||||
end
|
|
||||||
-- Make the different types of trunk distinguishable (but not too easily)
|
|
||||||
ftrunk.tiles[1] = "moretrees_date_palm_trunk_top.png^[transformR180"
|
|
||||||
ftrunk.description = ftrunk.description.." (gen)"
|
|
||||||
fftrunk.tiles[1] = "moretrees_date_palm_trunk_top.png^[transformR90"
|
|
||||||
mftrunk.tiles[1] = "moretrees_date_palm_trunk_top.png^[transformR-90"
|
|
||||||
minetest.register_node("moretrees:date_palm_fruit_trunk", ftrunk)
|
|
||||||
minetest.register_node("moretrees:date_palm_ffruit_trunk", fftrunk)
|
|
||||||
minetest.register_node("moretrees:date_palm_mfruit_trunk", mftrunk)
|
|
||||||
|
|
||||||
-- ABM to grow new date blossoms
|
|
||||||
local date_regrow_abm_spec = {
|
|
||||||
nodenames = { "moretrees:date_palm_ffruit_trunk", "moretrees:date_palm_mfruit_trunk" },
|
|
||||||
interval = moretrees.dates_flower_interval,
|
|
||||||
chance = moretrees.dates_flower_chance,
|
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
|
||||||
local dates = minetest.find_nodes_in_area({x=pos.x-2, y=pos.y, z=pos.z-2}, {x=pos.x+2, y=pos.y, z=pos.z+2}, "group:moretrees_dates")
|
|
||||||
|
|
||||||
-- New blossom interval increases exponentially with number of dates already hanging
|
|
||||||
-- In addition: if more dates are hanging, the chance of picking an empty spot decreases as well...
|
|
||||||
if math.random(2^#dates) <= 2 then
|
|
||||||
-- Grow in area of 5x5 round trunk; higher probability in 3x3 area close to trunk
|
|
||||||
local dx=math.floor((math.random(50)-18)/16)
|
|
||||||
local dz=math.floor((math.random(50)-18)/16)
|
|
||||||
local datepos = {x=pos.x+dx, y=pos.y, z=pos.z+dz}
|
|
||||||
local datenode = minetest.get_node(datepos)
|
|
||||||
if datenode.name == "air" then
|
|
||||||
if node.name == "moretrees:date_palm_ffruit_trunk" then
|
|
||||||
minetest.set_node(datepos, {name="moretrees:dates_f0"})
|
|
||||||
else
|
|
||||||
minetest.set_node(datepos, {name="moretrees:dates_m0"})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
}
|
|
||||||
if moretrees.dates_regrow then
|
|
||||||
minetest.register_abm(date_regrow_abm_spec)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Choose male or female palm, and spawn initial dates
|
|
||||||
-- (Instead of dates, a dates fruit trunk is generated with the tree. This
|
|
||||||
-- ABM converts the trunk to a female or male fruit trunk, and spawns some
|
|
||||||
-- hanging dates)
|
|
||||||
minetest.register_abm({
|
|
||||||
nodenames = { "moretrees:date_palm_fruit_trunk" },
|
|
||||||
interval = 1,
|
|
||||||
chance = 1,
|
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
|
||||||
local type
|
|
||||||
if math.random(100) <= moretrees.dates_female_percent then
|
|
||||||
type = "f"
|
|
||||||
minetest.swap_node(pos, {name="moretrees:date_palm_ffruit_trunk"})
|
|
||||||
else
|
|
||||||
type = "m"
|
|
||||||
minetest.swap_node(pos, {name="moretrees:date_palm_mfruit_trunk"})
|
|
||||||
end
|
|
||||||
local dates1 = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y, z=pos.z-1}, {x=pos.x+1, y=pos.y, z=pos.z+1}, "air")
|
|
||||||
local genpos
|
|
||||||
for _,genpos in pairs(dates1) do
|
|
||||||
if math.random(100) <= 20 then
|
|
||||||
if type == "m" then
|
|
||||||
minetest.set_node(genpos, {name = "moretrees:dates_n"})
|
|
||||||
else
|
|
||||||
minetest.set_node(genpos, {name = "moretrees:dates_f4"})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local dates2 = minetest.find_nodes_in_area({x=pos.x-2, y=pos.y, z=pos.z-2}, {x=pos.x+2, y=pos.y, z=pos.z+2}, "air")
|
|
||||||
for _,genpos in pairs(dates2) do
|
|
||||||
if math.random(100) <= 5 then
|
|
||||||
if type == "m" then
|
|
||||||
minetest.set_node(genpos, {name = "moretrees:dates_n"})
|
|
||||||
else
|
|
||||||
minetest.set_node(genpos, {name = "moretrees:dates_f4"})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Dates growing functions.
|
|
||||||
|
|
||||||
-- This is a bit complex, as the purpose is to find male flowers at horizontal distances of over
|
|
||||||
-- 100 nodes. As searching such a large area is time consuming, this is optimized in four ways:
|
|
||||||
-- - The search result (the locations of male trees) is cached, so that it can be used again
|
|
||||||
-- - Only 1/9th of the desired area is searched at a time. A new search is only performed if no male
|
|
||||||
-- flowers are found in the previously searched parts.
|
|
||||||
-- - Search results are shared with other female palms nearby.
|
|
||||||
-- - If previous searches for male palms have consumed too much CPU time, the search is skipped
|
|
||||||
-- (This means no male palms will be found, and the pollination of the flowers affected will be
|
|
||||||
-- delayed. If this happens repeatedly, eventually, the female flowers will wither...)
|
|
||||||
-- A caching method was selected that is suited for the case where most date trees are long-lived,
|
|
||||||
-- and where the number of trees nearby is limited:
|
|
||||||
-- - Locations of male palms are stored as metadata for every female palm. This means that a player
|
|
||||||
-- visiting a remote area with some date palms will not cause extensive searches for male palms as
|
|
||||||
-- long overdue blossoming ABMs are triggered for every date palm.
|
|
||||||
-- - Even when male palms *are* cut down, a cache refill will only be performed if the cached results do not
|
|
||||||
-- contain a male palm with blossoms.
|
|
||||||
-- The method will probably perform suboptimally:
|
|
||||||
-- - If female palms are frequently chopped down and replanted.
|
|
||||||
-- Freshly grown palms will need to search for male palms again
|
|
||||||
-- (this is mitigated by the long blossoming interval, which increases the chance that search
|
|
||||||
-- results have already been shared)
|
|
||||||
-- - If an area contains a large number of male and female palms.
|
|
||||||
-- In this area, every female palm will have an almost identical list of male palm locations
|
|
||||||
-- as metadata.
|
|
||||||
-- - If all male palms within range of a number of female palms have been chopped down (with possibly
|
|
||||||
-- new ones planted). Although an attempt was made to share search results in this case as well,
|
|
||||||
-- a number of similar searches will unavoidably be performed by the different female palms.
|
|
||||||
-- - If no male palms are in range of a female palm. In that case, there will be frequent searches
|
|
||||||
-- for newly-grown male palms.
|
|
||||||
|
|
||||||
-- Search statistics - used to limit the search load.
|
|
||||||
local sect_search_stats = {} -- Search statistics - server-wide
|
|
||||||
local function reset_sect_search_stats()
|
|
||||||
sect_search_stats.count = 0 -- # of searches
|
|
||||||
sect_search_stats.skip = 0 -- # of times skipped
|
|
||||||
sect_search_stats.sum = 0 -- total time spent
|
|
||||||
sect_search_stats.min = 999999999 -- min time spent
|
|
||||||
sect_search_stats.max = 0 -- max time spent
|
|
||||||
end
|
|
||||||
reset_sect_search_stats()
|
|
||||||
sect_search_stats.last_us = 0 -- last time a search was done (microseconds, max: 2^32)
|
|
||||||
sect_search_stats.last_s = 0 -- last time a search was done (system time in seconds)
|
|
||||||
|
|
||||||
-- Find male trunks in one section (=1/9 th) of the searchable area.
|
|
||||||
-- sect is -4 to 4, where 0 is the center section
|
|
||||||
local function find_fruit_trunks_near(ftpos, sect)
|
|
||||||
local r = moretrees.dates_pollination_distance + 2 * math.sqrt(2)
|
|
||||||
local sect_hr = math.floor(r / 3 + 0.9999)
|
|
||||||
local sect_vr = math.floor(r / 2 + 0.9999)
|
|
||||||
local t0us = core.get_us_time()
|
|
||||||
local t0s = os.time()
|
|
||||||
|
|
||||||
-- Compute elapsed time since last search.
|
|
||||||
-- Unfortunately, the time value wraps after about 71 minutes (2^32 microseconds),
|
|
||||||
-- so it must be corrected to obtain the actual elapsed time.
|
|
||||||
if t0us < sect_search_stats.last_us then
|
|
||||||
-- Correct a simple wraparound.
|
|
||||||
-- This is not sufficient, as the time value may have wrapped more than once...
|
|
||||||
sect_search_stats.last_us = sect_search_stats.last_us - 2^32
|
|
||||||
end
|
|
||||||
if t0s - sect_search_stats.last_s > 2^32/1000000 then
|
|
||||||
-- One additional correction is enough for our purposes.
|
|
||||||
-- For exact results, more corrections may be needed though...
|
|
||||||
-- (and even not applying this correction at all would still only yield
|
|
||||||
-- a minimal risk of a non-serious miscalculation...)
|
|
||||||
sect_search_stats.last_us = sect_search_stats.last_us - 2^32
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Skip the search if it is consuming too much CPU time
|
|
||||||
if sect_search_stats.count > 0 and moretrees.dates_blossom_search_iload > 0
|
|
||||||
and sect_search_stats.sum / sect_search_stats.count > moretrees.dates_blossom_search_time_treshold
|
|
||||||
and t0us - sect_search_stats.last_us < moretrees.dates_blossom_search_iload * (sect_search_stats.sum / sect_search_stats.count) then
|
|
||||||
sect_search_stats.skip = sect_search_stats.skip + 1
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local all_palms = minetest.find_nodes_in_area(
|
|
||||||
{ x = ftpos.x + 2 * sect.x * sect_hr - sect_hr,
|
|
||||||
y = ftpos.y - sect_vr,
|
|
||||||
z = ftpos.z + 2 * sect.z * sect_hr - sect_hr },
|
|
||||||
{ x = ftpos.x + 2 * sect.x * sect_hr + sect_hr,
|
|
||||||
y = ftpos.y + sect_vr,
|
|
||||||
z = ftpos.z + 2 * sect.z * sect_hr + sect_hr },
|
|
||||||
{"moretrees:date_palm_mfruit_trunk", "moretrees:date_palm_ffruit_trunk"})
|
|
||||||
|
|
||||||
-- Collect different palms in separate lists.
|
|
||||||
local female_palms = {}
|
|
||||||
local male_palms = {}
|
|
||||||
local all_male_palms = {}
|
|
||||||
for _, pos in pairs(all_palms) do
|
|
||||||
if pos.x ~= ftpos.x or pos.y ~= ftpos.y or pos.z ~= ftpos.z then
|
|
||||||
local node = minetest.get_node(pos)
|
|
||||||
if node and node.name == "moretrees:date_palm_ffruit_trunk" then
|
|
||||||
table.insert(female_palms,pos)
|
|
||||||
elseif node then
|
|
||||||
table.insert(all_male_palms,pos)
|
|
||||||
-- In sector 0, all palms are of interest.
|
|
||||||
-- In other sectors, forget about palms that are too far away.
|
|
||||||
if sect == 0 then
|
|
||||||
table.insert(male_palms,pos)
|
|
||||||
else
|
|
||||||
local ssq = 0
|
|
||||||
for _, c in pairs({"x", "z"}) do
|
|
||||||
local dc = pos[c] - ftpos[c]
|
|
||||||
ssq = ssq + dc * dc
|
|
||||||
end
|
|
||||||
if math.sqrt(ssq) <= r then
|
|
||||||
table.insert(male_palms,pos)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Update search statistics
|
|
||||||
local t1us = core.get_us_time()
|
|
||||||
if t1us < t0us then
|
|
||||||
-- Wraparound. Assume the search lasted less than 2^32 microseconds (~71 min)
|
|
||||||
-- (so no need to apply another correction)
|
|
||||||
t0us = t0us - 2^32
|
|
||||||
end
|
|
||||||
sect_search_stats.last_us = t0us
|
|
||||||
sect_search_stats.last_s = t0s
|
|
||||||
sect_search_stats.count = sect_search_stats.count + 1
|
|
||||||
sect_search_stats.sum = sect_search_stats.sum + t1us-t0us
|
|
||||||
if t1us - t0us < sect_search_stats.min then
|
|
||||||
sect_search_stats.min = t1us - t0us
|
|
||||||
end
|
|
||||||
if t1us - t0us > sect_search_stats.max then
|
|
||||||
sect_search_stats.max = t1us - t0us
|
|
||||||
end
|
|
||||||
|
|
||||||
return male_palms, female_palms, all_male_palms
|
|
||||||
end
|
|
||||||
|
|
||||||
local function dates_print_search_stats(log)
|
|
||||||
local stats
|
|
||||||
if sect_search_stats.count > 0 then
|
|
||||||
stats = string.format("Male date tree searching stats: count: %d/%d: average: %d µs (%d..%d)",
|
|
||||||
sect_search_stats.count, sect_search_stats.count + sect_search_stats.skip,
|
|
||||||
sect_search_stats.sum/sect_search_stats.count, sect_search_stats.min, sect_search_stats.max)
|
|
||||||
else
|
|
||||||
stats = string.format("Male date tree searching stats: (not yet available)")
|
|
||||||
end
|
|
||||||
if log then
|
|
||||||
minetest.log("action", "[moretrees] " .. stats)
|
|
||||||
end
|
|
||||||
return true, stats
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_chatcommand("dates_stats", {
|
|
||||||
description = "Print male date palm search statistics",
|
|
||||||
params = "|chat|log|reset",
|
|
||||||
privs = { server = true },
|
|
||||||
func = function(name, param)
|
|
||||||
param = string.lower(string.trim(param))
|
|
||||||
if param == "" or param == "chat" then
|
|
||||||
return dates_print_search_stats(false)
|
|
||||||
elseif param == "log" then
|
|
||||||
return dates_print_search_stats(true)
|
|
||||||
elseif param == "reset" then
|
|
||||||
reset_sect_search_stats()
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return false, "Invalid subcommand; expected: '' or 'chat' or 'log' or 'reset'"
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Find the female trunk near the female flowers to be pollinated
|
|
||||||
local function find_female_trunk(fbpos)
|
|
||||||
local trunks = minetest.find_nodes_in_area({x=fbpos.x-2, y=fbpos.y, z=fbpos.z-2},
|
|
||||||
{x=fbpos.x+2, y=fbpos.y, z=fbpos.z+2},
|
|
||||||
"moretrees:date_palm_ffruit_trunk")
|
|
||||||
local ftpos
|
|
||||||
local d = 99
|
|
||||||
for x, pos in pairs(trunks) do
|
|
||||||
local ssq = 0
|
|
||||||
for _, c in pairs({"x", "z"}) do
|
|
||||||
local dc = pos[c] - fbpos[c]
|
|
||||||
ssq = ssq + dc * dc
|
|
||||||
end
|
|
||||||
if math.sqrt(ssq) < d then
|
|
||||||
ftpos = pos
|
|
||||||
d = math.sqrt(ssq)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return ftpos
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Find male blossom near a male trunk,
|
|
||||||
-- the male blossom must be in range of a specific female blossom as well
|
|
||||||
local function find_male_blossom_near_trunk(fbpos, mtpos)
|
|
||||||
local r = moretrees.dates_pollination_distance
|
|
||||||
local blossoms = minetest.find_nodes_in_area({x=mtpos.x-2, y=mtpos.y, z=mtpos.z-2},
|
|
||||||
{x=mtpos.x+2, y=mtpos.y, z=mtpos.z+2},
|
|
||||||
"moretrees:dates_m0")
|
|
||||||
for x, mbpos in pairs(blossoms) do
|
|
||||||
local ssq = 0
|
|
||||||
for _, c in pairs({"x", "z"}) do
|
|
||||||
local dc = mbpos[c] - fbpos[c]
|
|
||||||
ssq = ssq + dc * dc
|
|
||||||
end
|
|
||||||
if math.sqrt(ssq) <= r then
|
|
||||||
return mbpos
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Find a male blossom in range of a specific female blossom,
|
|
||||||
-- using a nested list of male blossom positions
|
|
||||||
local function find_male_blossom_in_mpalms(ftpos, fbpos, mpalms)
|
|
||||||
-- Process the elements of mpalms.sect (index -4 .. 4) in random order
|
|
||||||
-- First, compute the order in which the sectors will be searched
|
|
||||||
local sect_index = {}
|
|
||||||
local sect_rnd = {}
|
|
||||||
for i = -4,4 do
|
|
||||||
local n = math.random(1023)
|
|
||||||
sect_index[n] = i
|
|
||||||
table.insert(sect_rnd, n)
|
|
||||||
end
|
|
||||||
table.sort(sect_rnd)
|
|
||||||
|
|
||||||
-- Search the sectors
|
|
||||||
local sect_old = 0
|
|
||||||
local sect_time = minetest.get_gametime()
|
|
||||||
for _, n in pairs(sect_rnd) do
|
|
||||||
-- Record the oldest sector, so that it can be searched if no male
|
|
||||||
-- blossoms were found
|
|
||||||
if not mpalms.sect_time[sect_index[n]] then
|
|
||||||
sect_old = sect_index[n]
|
|
||||||
sect_time = 0
|
|
||||||
elseif mpalms.sect_time[sect_index[n]] < sect_time then
|
|
||||||
sect_old = sect_index[n]
|
|
||||||
sect_time = mpalms.sect_time[sect_index[n]]
|
|
||||||
end
|
|
||||||
if mpalms.sect[sect_index[n]] and #mpalms.sect[sect_index[n]] then
|
|
||||||
for px, mtpos in pairs(mpalms.sect[sect_index[n]]) do
|
|
||||||
local node = minetest.get_node(mtpos)
|
|
||||||
if node and node.name == "moretrees:date_palm_mfruit_trunk" then
|
|
||||||
local mbpos = find_male_blossom_near_trunk(fbpos, mtpos)
|
|
||||||
if mbpos then
|
|
||||||
return mbpos
|
|
||||||
end
|
|
||||||
elseif node and node.name ~= "ignore" then
|
|
||||||
-- no more male trunk here.
|
|
||||||
mpalms.sect[sect_index[n]][px] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil, sect_old
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Find a male blossom in range of a specific female blossom,
|
|
||||||
-- using the cache associated with the given female trunk
|
|
||||||
-- If necessary, recompute part of the cache
|
|
||||||
local last_search_result = {}
|
|
||||||
local function find_male_blossom_with_ftrunk(fbpos,ftpos)
|
|
||||||
local meta = minetest.get_meta(ftpos)
|
|
||||||
local mpalms
|
|
||||||
local cache_changed = true
|
|
||||||
|
|
||||||
-- Load cache. If distance has changed, start with empty cache instead.
|
|
||||||
local mpalms_dist = meta:get_int("male_palms_dist")
|
|
||||||
if mpalms_dist and mpalms_dist == moretrees.dates_pollination_distance then
|
|
||||||
mpalms = meta:get_string("male_palms")
|
|
||||||
if mpalms and mpalms ~= "" then
|
|
||||||
mpalms = minetest.deserialize(mpalms)
|
|
||||||
cache_changed = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not mpalms or not mpalms.sect then
|
|
||||||
mpalms = {}
|
|
||||||
mpalms.sect = {}
|
|
||||||
mpalms.sect_time = {}
|
|
||||||
meta:set_int("male_palms_dist", moretrees.dates_pollination_distance)
|
|
||||||
cache_changed = true
|
|
||||||
end
|
|
||||||
local fpalms_list
|
|
||||||
local all_mpalms_list
|
|
||||||
local sector0_searched = false
|
|
||||||
|
|
||||||
-- Always make sure that sector 0 is cached
|
|
||||||
if not mpalms.sect[0] then
|
|
||||||
mpalms.sect[0], fpalms_list, all_mpalms_list = find_fruit_trunks_near(ftpos, {x = 0, z = 0})
|
|
||||||
mpalms.sect_time[0] = minetest.get_gametime()
|
|
||||||
sector0_searched = true
|
|
||||||
cache_changed = true
|
|
||||||
last_search_result.female = fpalms_list
|
|
||||||
last_search_result.male = all_mpalms_list
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Find male palms
|
|
||||||
local mbpos, sect_old = find_male_blossom_in_mpalms(ftpos, fbpos, mpalms)
|
|
||||||
|
|
||||||
-- If not found, (re)generate the cache for an additional sector. But don't search it yet (for performance reasons)
|
|
||||||
-- (Use the globally cached results if possible)
|
|
||||||
if not mbpos and not sector0_searched then
|
|
||||||
if not mpalms.sect_time[0] or mpalms.sect_time[0] == 0 or math.random(3) == 1 then
|
|
||||||
-- Higher probability of re-searching the center sector
|
|
||||||
sect_old = 0
|
|
||||||
end
|
|
||||||
-- Use globally cached result if possible
|
|
||||||
mpalms.sect[sect_old] = nil
|
|
||||||
if sect_old == 0 and mpalms.sect_time[0] and mpalms.sect_time[0] > 0
|
|
||||||
and last_search_result.male and #last_search_result.male then
|
|
||||||
for _, pos in pairs(last_search_result.female) do
|
|
||||||
if pos.x == ftpos.x and pos.y == ftpos.y and pos.z == ftpos.z then
|
|
||||||
mpalms.sect[sect_old] = last_search_result.male
|
|
||||||
-- Next time, don't use the cached result
|
|
||||||
mpalms.sect_time[sect_old] = nil
|
|
||||||
cache_changed = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Else do a new search
|
|
||||||
if not mpalms.sect[sect_old] then
|
|
||||||
mpalms.sect[sect_old], fpalms_list, all_mpalms_list = find_fruit_trunks_near(ftpos, {x = (sect_old + 4) % 3 - 1, z = (sect_old + 4) / 3 - 1})
|
|
||||||
cache_changed = true
|
|
||||||
if sect_old == 0 then
|
|
||||||
-- Save the results if it is sector 0
|
|
||||||
-- (chance of reusing results from another sector are smaller)
|
|
||||||
last_search_result.female = fpalms_list
|
|
||||||
last_search_result.male = all_mpalms_list
|
|
||||||
end
|
|
||||||
if mpalms.sect[sect_old] then
|
|
||||||
mpalms.sect_time[sect_old] = minetest.get_gametime()
|
|
||||||
else
|
|
||||||
mpalms.sect_time[sect_old] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Share search results with other female trunks in the same area
|
|
||||||
-- Note that the list of female trunks doesn't (shouldn't :-) contain the current female trunk.
|
|
||||||
if fpalms_list and #fpalms_list and #all_mpalms_list then
|
|
||||||
local all_mpalms = {}
|
|
||||||
all_mpalms.sect = {}
|
|
||||||
all_mpalms.sect_time = {}
|
|
||||||
all_mpalms.sect[0] = all_mpalms_list
|
|
||||||
-- Don't set sect_time[0], so that the cached sector will be re-searched soon (if necessary)
|
|
||||||
local all_mpalms_serialized = minetest.serialize(all_mpalms)
|
|
||||||
for _, pos in pairs(fpalms_list) do
|
|
||||||
local fmeta = minetest.get_meta(pos)
|
|
||||||
local fdist = fmeta:get_int("male_palms_dist")
|
|
||||||
if not fdist or fdist ~= moretrees.dates_pollination_distance then
|
|
||||||
fmeta:set_string("male_palms", all_mpalms_serialized)
|
|
||||||
fmeta:set_int("male_palms_dist", moretrees.dates_pollination_distance)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Save cache.
|
|
||||||
if cache_changed then
|
|
||||||
meta:set_string("male_palms", minetest.serialize(mpalms))
|
|
||||||
end
|
|
||||||
|
|
||||||
return mbpos
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Find a male blossom in range of a specific female blossom
|
|
||||||
local function find_male_blossom(fbpos)
|
|
||||||
local ftpos = find_female_trunk(fbpos)
|
|
||||||
if ftpos then
|
|
||||||
return find_male_blossom_with_ftrunk(fbpos, ftpos)
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Growing function for dates
|
|
||||||
local dates_growfn = function(pos, elapsed)
|
|
||||||
local node = minetest.get_node(pos)
|
|
||||||
local delay = moretrees.dates_grow_interval
|
|
||||||
local r = moretrees.dates_pollination_distance
|
|
||||||
local action
|
|
||||||
if not node then
|
|
||||||
return
|
|
||||||
elseif not moretrees.dates_regrow then
|
|
||||||
if string.find(node.name, "moretrees:dates_f") then
|
|
||||||
minetest.swap_node(pos, {name="moretrees:dates_f4"})
|
|
||||||
elseif string.find(node.name, "moretrees:dates_m") then
|
|
||||||
minetest.swap_node(pos, {name="moretrees:dates_n"})
|
|
||||||
else
|
|
||||||
minetest.remove_node(pos)
|
|
||||||
end
|
|
||||||
return
|
|
||||||
elseif node.name == "moretrees:dates_f0" and find_male_blossom(pos) then
|
|
||||||
-- Pollinate flowers
|
|
||||||
minetest.swap_node(pos, {name="moretrees:dates_f1"})
|
|
||||||
action = "pollinate"
|
|
||||||
elseif string.match(node.name, "0$") then
|
|
||||||
-- Make female unpollinated and male flowers last a bit longer
|
|
||||||
if math.random(flowers_wither_ichance) == 1 then
|
|
||||||
if node.name == "moretrees:dates_f0" then
|
|
||||||
minetest.swap_node(pos, {name="moretrees:dates_fn"})
|
|
||||||
else
|
|
||||||
minetest.swap_node(pos, {name="moretrees:dates_n"})
|
|
||||||
end
|
|
||||||
action = "wither"
|
|
||||||
else
|
|
||||||
action = "nowither"
|
|
||||||
end
|
|
||||||
elseif node.name == "moretrees:dates_f4" then
|
|
||||||
-- Remove dates, and optionally drop them as items
|
|
||||||
if math.random(dates_drop_ichance) == 1 then
|
|
||||||
if moretrees.dates_item_drop_ichance > 0 and math.random(moretrees.dates_item_drop_ichance) == 1 then
|
|
||||||
local items = minetest.get_node_drops(minetest.get_node(pos).name)
|
|
||||||
for _, itemname in pairs(items) do
|
|
||||||
minetest.add_item(pos, itemname)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
minetest.swap_node(pos, {name="moretrees:dates_n"})
|
|
||||||
action = "drop"
|
|
||||||
else
|
|
||||||
action = "nodrop"
|
|
||||||
end
|
|
||||||
elseif string.match(node.name, "n$") then
|
|
||||||
-- Remove stems.
|
|
||||||
if math.random(stems_drop_ichance) == 1 then
|
|
||||||
minetest.remove_node(pos)
|
|
||||||
return "stemdrop"
|
|
||||||
end
|
|
||||||
action = "nostemdrop"
|
|
||||||
else
|
|
||||||
-- Grow dates
|
|
||||||
local offset = 18
|
|
||||||
local n = string.sub(node.name, offset)
|
|
||||||
minetest.swap_node(pos, {name=string.sub(node.name, 1, offset-1)..n+1})
|
|
||||||
action = "grow"
|
|
||||||
end
|
|
||||||
-- Don't catch up when elapsed time is large. Regular visits are needed for growth...
|
|
||||||
local timer = minetest.get_node_timer(pos)
|
|
||||||
timer:start(delay + math.random(moretrees.dates_grow_interval))
|
|
||||||
return action
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Alternate growth function for dates.
|
|
||||||
-- It calls the primary growth function, but also measures CPU time consumed.
|
|
||||||
-- Use this function to analyze date growing performance.
|
|
||||||
local stat = {}
|
|
||||||
stat.count = 0
|
|
||||||
local dates_growfn_profiling = function(pos, elapsed)
|
|
||||||
local t0 = core.get_us_time()
|
|
||||||
local action = dates_growfn(pos, elapsed)
|
|
||||||
local t1 = core.get_us_time()
|
|
||||||
if t1 < t0 then
|
|
||||||
t1 = t1 + 2^32
|
|
||||||
end
|
|
||||||
stat.count = stat.count + 1
|
|
||||||
if not stat[action] then
|
|
||||||
stat[action] = {}
|
|
||||||
stat[action].count = 0
|
|
||||||
stat[action].sum = 0
|
|
||||||
stat[action].min = 9999999999
|
|
||||||
stat[action].max = 0
|
|
||||||
end
|
|
||||||
stat[action].count = stat[action].count + 1
|
|
||||||
stat[action].sum = stat[action].sum + t1-t0
|
|
||||||
if t1-t0 < stat[action].min then
|
|
||||||
stat[action].min = t1-t0
|
|
||||||
end
|
|
||||||
if t1-t0 > stat[action].max then
|
|
||||||
stat[action].max = t1-t0
|
|
||||||
end
|
|
||||||
|
|
||||||
if stat.count % 10 == 0 then
|
|
||||||
io.write(".")
|
|
||||||
io.flush()
|
|
||||||
end
|
|
||||||
if stat.count % 100 == 0 then
|
|
||||||
print(string.format("Date grow statistics %5d:", stat.count))
|
|
||||||
local sum = 0
|
|
||||||
local count = 0
|
|
||||||
if sect_search_stats.count > 0 and stat.pollinate and stat.pollinate.count > 0 then
|
|
||||||
print(string.format("\t%-10s: %6d (%4.1f%%): %6dus (%d..%d)",
|
|
||||||
"search", sect_search_stats.count,
|
|
||||||
100*sect_search_stats.count/stat.pollinate.count,
|
|
||||||
sect_search_stats.sum/sect_search_stats.count,
|
|
||||||
sect_search_stats.min, sect_search_stats.max))
|
|
||||||
else
|
|
||||||
print(string.format("\t%-10s: %6d (%4.1f%%): %6dus (%d..%d)",
|
|
||||||
"search", sect_search_stats.count,
|
|
||||||
0, 0, 0, 0))
|
|
||||||
end
|
|
||||||
for action,data in pairs(stat) do
|
|
||||||
if action ~= "count" then
|
|
||||||
count = count + data.count
|
|
||||||
sum = sum + data.sum
|
|
||||||
print(string.format("\t%-10s: %6d (%4.1f%%): %6dus (%d..%d)",
|
|
||||||
action, data.count,
|
|
||||||
100*data.count/stat.count, data.sum/data.count,
|
|
||||||
data.min, data.max))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
print(string.format("\t%-10s: %6d ( 100%%): %6dus",
|
|
||||||
"TOTAL", count, sum/count))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Register dates
|
|
||||||
|
|
||||||
local dates_starttimer = function(pos, elapsed)
|
|
||||||
local timer = minetest.get_node_timer(pos)
|
|
||||||
local base_interval = moretrees.dates_grow_interval * 2 / 3
|
|
||||||
timer:set(base_interval + math.random(base_interval), elapsed or 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
local dates_drop = {
|
|
||||||
items = {
|
|
||||||
{items = { "moretrees:date" }},
|
|
||||||
{items = { "moretrees:date" }},
|
|
||||||
{items = { "moretrees:date" }},
|
|
||||||
{items = { "moretrees:date" }},
|
|
||||||
{items = { "moretrees:date" }, rarity = 2 },
|
|
||||||
{items = { "moretrees:date" }, rarity = 2 },
|
|
||||||
{items = { "moretrees:date" }, rarity = 2 },
|
|
||||||
{items = { "moretrees:date" }, rarity = 2 },
|
|
||||||
{items = { "moretrees:date" }, rarity = 5 },
|
|
||||||
{items = { "moretrees:date" }, rarity = 5 },
|
|
||||||
{items = { "moretrees:date" }, rarity = 5 },
|
|
||||||
{items = { "moretrees:date" }, rarity = 5 },
|
|
||||||
{items = { "moretrees:date" }, rarity = 20 },
|
|
||||||
{items = { "moretrees:date" }, rarity = 20 },
|
|
||||||
{items = { "moretrees:date" }, rarity = 20 },
|
|
||||||
{items = { "moretrees:date" }, rarity = 20 },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _,suffix in ipairs({"f0", "f1", "f2", "f3", "f4", "m0", "fn", "n"}) do
|
|
||||||
local name
|
|
||||||
if suffix == "f0" or suffix == "m0" then
|
|
||||||
name = S("Date Flowers")
|
|
||||||
elseif suffix == "n" or suffix == "fn" then
|
|
||||||
name = S("Date Stem")
|
|
||||||
else
|
|
||||||
name = S("Dates")
|
|
||||||
end
|
|
||||||
local dropfn = suffix == "f4" and dates_drop or ""
|
|
||||||
local datedef = {
|
|
||||||
description = name,
|
|
||||||
tiles = {"moretrees_dates_"..suffix..".png"},
|
|
||||||
visual_scale = 2,
|
|
||||||
drawtype = "plantlike",
|
|
||||||
paramtype = "light",
|
|
||||||
sunlight_propagates = true,
|
|
||||||
walkable = false,
|
|
||||||
groups = { fleshy=3, dig_immediate=3, flammable=2, moretrees_dates=1 },
|
|
||||||
inventory_image = "moretrees_dates_"..suffix..".png^[transformR0",
|
|
||||||
wield_image = "moretrees_dates_"..suffix..".png^[transformR90",
|
|
||||||
sounds = default.node_sound_defaults(),
|
|
||||||
drop = dropfn,
|
|
||||||
selection_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {-0.3, -0.3, -0.3, 0.3, 3.5, 0.3}
|
|
||||||
},
|
|
||||||
on_timer = dates_growfn,
|
|
||||||
on_construct = moretrees.dates_regrow and dates_starttimer,
|
|
||||||
|
|
||||||
}
|
|
||||||
minetest.register_node("moretrees:dates_"..suffix, datedef)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- If regrowing was previously disabled, but is enabled now, make sure timers are started for existing dates
|
|
||||||
if moretrees.dates_regrow then
|
|
||||||
local spec = {
|
|
||||||
name = "moretrees:restart_dates_regrow_timer",
|
|
||||||
nodenames = "group:moretrees_dates",
|
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
|
||||||
local timer = minetest.get_node_timer(pos)
|
|
||||||
if not timer:is_started() then
|
|
||||||
dates_starttimer(pos)
|
|
||||||
else
|
|
||||||
local timeout = timer:get_timeout()
|
|
||||||
local elapsed = timer:get_elapsed()
|
|
||||||
if timeout - elapsed > moretrees.dates_grow_interval * 4/3 then
|
|
||||||
dates_starttimer(pos, math.random(moretrees.dates_grow_interval * 4/3))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
if minetest.register_lbm then
|
|
||||||
minetest.register_lbm(spec)
|
|
||||||
else
|
|
||||||
spec.interval = 3557
|
|
||||||
spec.chance = 10
|
|
||||||
minetest.register_abm(spec)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
40
default_settings.txt
Normal file → Executable file
@ -6,7 +6,6 @@ moretrees.enable_apple_tree = true
|
|||||||
moretrees.enable_oak = true
|
moretrees.enable_oak = true
|
||||||
moretrees.enable_sequoia = true
|
moretrees.enable_sequoia = true
|
||||||
moretrees.enable_palm = true
|
moretrees.enable_palm = true
|
||||||
moretrees.enable_date_palm = true
|
|
||||||
moretrees.enable_cedar = true
|
moretrees.enable_cedar = true
|
||||||
moretrees.enable_rubber_tree = true
|
moretrees.enable_rubber_tree = true
|
||||||
moretrees.enable_willow = true
|
moretrees.enable_willow = true
|
||||||
@ -58,45 +57,6 @@ moretrees.firs_remove_default_trees = false
|
|||||||
moretrees.firs_remove_interval = 2
|
moretrees.firs_remove_interval = 2
|
||||||
moretrees.firs_remove_chance = 150
|
moretrees.firs_remove_chance = 150
|
||||||
|
|
||||||
-- Cocos palm settings
|
|
||||||
|
|
||||||
moretrees.coconuts_regrow = true
|
|
||||||
moretrees.coconuts_convert_existing_palms = true -- Converting existing palm trees will make coconuts regrow on them as well
|
|
||||||
-- Else, they will only regrow on newly-spawned palms
|
|
||||||
-- However, conversion is not an exact science, and although an attempt is
|
|
||||||
-- made to detect whether a trunk belongs to an actual palm, some coconut trunks
|
|
||||||
-- and some coconuts may be incorrectly converted.
|
|
||||||
moretrees.coconut_flower_interval = 59
|
|
||||||
moretrees.coconut_flower_chance = 67
|
|
||||||
moretrees.coconut_grow_interval = 2 * moretrees.coconut_flower_interval * moretrees.coconut_flower_chance
|
|
||||||
-- Actual interval will randomly vary between 67% and 133% of this value
|
|
||||||
-- 2 * 59 * 67 ~ 2 hours. So flowers become coconuts in about 6 hours
|
|
||||||
moretrees.coconut_item_drop_ichance = 10 -- inverse probability of ripe coconuts dropping as items (instead of disappearing)
|
|
||||||
|
|
||||||
-- Date palm settings
|
|
||||||
|
|
||||||
moretrees.dates_regrow = true
|
|
||||||
moretrees.dates_female_percent = 57 -- Ratio of female to male trees - tune this to improve # of generated trees that actually bear fruit
|
|
||||||
-- ~57% gives near optimal results for groups of 3 random trees, while it is only slightly suboptimal
|
|
||||||
-- for groups of 2 and 4 random trees (~2% less fruit than optimal).
|
|
||||||
-- Optimal values per group size: 2: 50%, 3: 57.78%, 4: 63%, 5: 66.9%, 6: 69.9%, [...], 12: 79.8%
|
|
||||||
-- So 57% is optimal for small groups of trees. As larger groups have more female palms anyway, a
|
|
||||||
-- less than optimal proportion of female to male trees is not a problem.
|
|
||||||
moretrees.dates_pollination_distance = 120
|
|
||||||
moretrees.dates_blossom_search_time_treshold = 1000 -- If average male blossom search time exceeds this, start limiting the search load.
|
|
||||||
moretrees.dates_blossom_search_iload = 10 -- Inverse fraction of CPU time that male blossom searching search may consume.
|
|
||||||
-- As searching a large area (radius: dates_pollination_distance/3 per attempt) can cause lag,
|
|
||||||
-- this limits the search frequency server-wide so that the impact on server lag is minimised
|
|
||||||
-- For personal servers, this can be set lower, or even to 1 or 0 (0 disables load limiting).
|
|
||||||
-- Obtain the current average search time using /dates_stats
|
|
||||||
moretrees.dates_flower_interval = 59
|
|
||||||
moretrees.dates_flower_chance = 181
|
|
||||||
moretrees.dates_grow_interval = 2 * moretrees.dates_flower_interval * moretrees.dates_flower_chance
|
|
||||||
-- As date palms have a high yield, don't grow dates too fast
|
|
||||||
-- The actual interval will vary randomly between 67% and 133% of this value.
|
|
||||||
-- 2 * 59 * 181 ~ 6 hours. So by default flowers become dates in about one (human) day.
|
|
||||||
moretrees.dates_item_drop_ichance = 10 -- inverse probability of ripe dates dropping as items (instead of disappearing)
|
|
||||||
|
|
||||||
-- Sapling settings
|
-- Sapling settings
|
||||||
|
|
||||||
moretrees.sapling_interval = 500
|
moretrees.sapling_interval = 500
|
||||||
|
2
depends.txt
Normal file → Executable file
@ -1,8 +1,6 @@
|
|||||||
default
|
default
|
||||||
biome_lib
|
biome_lib
|
||||||
vessels
|
|
||||||
stairs?
|
stairs?
|
||||||
moreblocks?
|
moreblocks?
|
||||||
intllib?
|
intllib?
|
||||||
farming?
|
|
||||||
|
|
||||||
|
22
init.lua
Normal file → Executable file
@ -64,17 +64,16 @@ moretrees.cutting_tools = {
|
|||||||
"default:axe_diamond",
|
"default:axe_diamond",
|
||||||
"default:axe_mese",
|
"default:axe_mese",
|
||||||
"default:axe_steel",
|
"default:axe_steel",
|
||||||
"glooptest:axe_alatro",
|
-- "glooptest:axe_alatro",
|
||||||
"glooptest:axe_arol",
|
-- "glooptest:axe_arol",
|
||||||
"moreores:axe_mithril",
|
"default:axe_mithril",
|
||||||
"moreores:axe_silver",
|
"default:axe_silver",
|
||||||
"titanium:axe",
|
-- "titanium:axe",
|
||||||
}
|
}
|
||||||
|
-- Cutting tools disabled. They are unknown //MFF(Mg|08/09/15)
|
||||||
|
|
||||||
dofile(modpath.."/tree_models.lua")
|
dofile(modpath.."/tree_models.lua")
|
||||||
dofile(modpath.."/node_defs.lua")
|
dofile(modpath.."/node_defs.lua")
|
||||||
dofile(modpath.."/date_palm.lua")
|
|
||||||
dofile(modpath.."/cocos_palm.lua")
|
|
||||||
dofile(modpath.."/biome_defs.lua")
|
dofile(modpath.."/biome_defs.lua")
|
||||||
dofile(modpath.."/saplings.lua")
|
dofile(modpath.."/saplings.lua")
|
||||||
dofile(modpath.."/crafts.lua")
|
dofile(modpath.."/crafts.lua")
|
||||||
@ -87,7 +86,6 @@ if moretrees.spawn_saplings then
|
|||||||
moretrees.spawn_oak_object = "moretrees:oak_sapling_ongen"
|
moretrees.spawn_oak_object = "moretrees:oak_sapling_ongen"
|
||||||
moretrees.spawn_sequoia_object = "moretrees:sequoia_sapling_ongen"
|
moretrees.spawn_sequoia_object = "moretrees:sequoia_sapling_ongen"
|
||||||
moretrees.spawn_palm_object = "moretrees:palm_sapling_ongen"
|
moretrees.spawn_palm_object = "moretrees:palm_sapling_ongen"
|
||||||
moretrees.spawn_date_palm_object = "moretrees:date_palm_sapling_ongen"
|
|
||||||
moretrees.spawn_cedar_object = "moretrees:cedar_sapling_ongen"
|
moretrees.spawn_cedar_object = "moretrees:cedar_sapling_ongen"
|
||||||
moretrees.spawn_rubber_tree_object = "moretrees:rubber_tree_sapling_ongen"
|
moretrees.spawn_rubber_tree_object = "moretrees:rubber_tree_sapling_ongen"
|
||||||
moretrees.spawn_willow_object = "moretrees:willow_sapling_ongen"
|
moretrees.spawn_willow_object = "moretrees:willow_sapling_ongen"
|
||||||
@ -103,7 +101,6 @@ else
|
|||||||
moretrees.spawn_oak_object = moretrees.oak_model
|
moretrees.spawn_oak_object = moretrees.oak_model
|
||||||
moretrees.spawn_sequoia_object = moretrees.sequoia_model
|
moretrees.spawn_sequoia_object = moretrees.sequoia_model
|
||||||
moretrees.spawn_palm_object = moretrees.palm_model
|
moretrees.spawn_palm_object = moretrees.palm_model
|
||||||
moretrees.spawn_date_palm_object = moretrees.date_palm_model
|
|
||||||
moretrees.spawn_cedar_object = moretrees.cedar_model
|
moretrees.spawn_cedar_object = moretrees.cedar_model
|
||||||
moretrees.spawn_rubber_tree_object = moretrees.rubber_tree_model
|
moretrees.spawn_rubber_tree_object = moretrees.rubber_tree_model
|
||||||
moretrees.spawn_willow_object = moretrees.willow_model
|
moretrees.spawn_willow_object = moretrees.willow_model
|
||||||
@ -135,11 +132,6 @@ if moretrees.enable_palm then
|
|||||||
biome_lib:register_generate_plant(moretrees.palm_biome, moretrees.spawn_palm_object)
|
biome_lib:register_generate_plant(moretrees.palm_biome, moretrees.spawn_palm_object)
|
||||||
end
|
end
|
||||||
|
|
||||||
if moretrees.enable_date_palm then
|
|
||||||
biome_lib:register_generate_plant(moretrees.date_palm_biome, moretrees.spawn_date_palm_object)
|
|
||||||
biome_lib:register_generate_plant(moretrees.date_palm_biome_2, moretrees.spawn_date_palm_object)
|
|
||||||
end
|
|
||||||
|
|
||||||
if moretrees.enable_cedar then
|
if moretrees.enable_cedar then
|
||||||
biome_lib:register_generate_plant(moretrees.cedar_biome, moretrees.spawn_cedar_object)
|
biome_lib:register_generate_plant(moretrees.cedar_biome, moretrees.spawn_cedar_object)
|
||||||
end
|
end
|
||||||
@ -305,4 +297,4 @@ function moretrees.grow_fir_snow(pos)
|
|||||||
minetest.spawn_tree(pos,moretrees.fir_model)
|
minetest.spawn_tree(pos,moretrees.fir_model)
|
||||||
end
|
end
|
||||||
|
|
||||||
print(S("[Moretrees] Loaded (2013-02-11)"))
|
minetest.log("action", S("[Moretrees] Loaded (2013-02-11)"))
|
||||||
|
0
locale/de.txt
Normal file → Executable file
0
locale/template.txt
Normal file → Executable file
12
node_defs.lua
Normal file → Executable file
@ -8,8 +8,7 @@ moretrees.treelist = {
|
|||||||
{"oak", "Oak Tree", "acorn", "Acorn", {-0.2, -0.5, -0.2, 0.2, 0, 0.2}, 0.8 },
|
{"oak", "Oak Tree", "acorn", "Acorn", {-0.2, -0.5, -0.2, 0.2, 0, 0.2}, 0.8 },
|
||||||
{"sequoia", "Giant Sequoia"},
|
{"sequoia", "Giant Sequoia"},
|
||||||
{"birch", "Birch Tree"},
|
{"birch", "Birch Tree"},
|
||||||
{"palm", "Palm Tree", "palm_fruit_trunk_gen", "Palm Tree", {-0.2, -0.5, -0.2, 0.2, 0, 0.2}, 1.0 },
|
{"palm", "Palm Tree", "coconut", "Coconut", {-0.2, -0.5, -0.2, 0.2, 0, 0.2}, 1.0 },
|
||||||
{"date_palm", "Date Palm Tree", "date_palm_fruit_trunk", "Date Palm Tree", {0, 0, 0, 0, 0, 0}, 0.0 },
|
|
||||||
{"spruce", "Spruce Tree", "spruce_cone", "Spruce Cone", {-0.2, -0.5, -0.2, 0.2, 0, 0.2}, 0.8 },
|
{"spruce", "Spruce Tree", "spruce_cone", "Spruce Cone", {-0.2, -0.5, -0.2, 0.2, 0, 0.2}, 0.8 },
|
||||||
{"cedar", "Cedar Tree", "cedar_cone", "Cedar Cone", {-0.2, -0.5, -0.2, 0.2, 0, 0.2}, 0.8 },
|
{"cedar", "Cedar Tree", "cedar_cone", "Cedar Cone", {-0.2, -0.5, -0.2, 0.2, 0, 0.2}, 0.8 },
|
||||||
{"willow", "Willow Tree"},
|
{"willow", "Willow Tree"},
|
||||||
@ -124,8 +123,6 @@ for i in ipairs(moretrees.treelist) do
|
|||||||
if treename == "palm" then
|
if treename == "palm" then
|
||||||
droprarity = 20
|
droprarity = 20
|
||||||
decay = moretrees.palm_leafdecay_radius
|
decay = moretrees.palm_leafdecay_radius
|
||||||
elseif treename == "date_palm" then
|
|
||||||
decay = moretrees.palm_leafdecay_radius
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local moretrees_leaves_inventory_image = nil
|
local moretrees_leaves_inventory_image = nil
|
||||||
@ -260,7 +257,7 @@ for i in ipairs(moretrees.treelist) do
|
|||||||
chance = 1,
|
chance = 1,
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||||
local fdir = node.param2 or 0
|
local fdir = node.param2 or 0
|
||||||
nfdir = dirs2[fdir+1]
|
local nfdir = dirs2[fdir+1]
|
||||||
minetest.add_node(pos, {name = "moretrees:"..treename.."_trunk", param2 = nfdir})
|
minetest.add_node(pos, {name = "moretrees:"..treename.."_trunk", param2 = nfdir})
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
@ -385,6 +382,8 @@ minetest.register_abm({
|
|||||||
-- we need our own copy of that node, which moretrees will match against.
|
-- we need our own copy of that node, which moretrees will match against.
|
||||||
|
|
||||||
local jungle_tree = moretrees.clone_node("default:jungletree")
|
local jungle_tree = moretrees.clone_node("default:jungletree")
|
||||||
|
jungle_tree.drop = jungle_tree.drop or { items = {} }
|
||||||
|
table.insert(jungle_tree.drop.items, { items = {"default:jungletree"}})
|
||||||
minetest.register_node("moretrees:jungletree_trunk", jungle_tree)
|
minetest.register_node("moretrees:jungletree_trunk", jungle_tree)
|
||||||
|
|
||||||
-- For compatibility with old nodes, recently-changed nodes, and default nodes
|
-- For compatibility with old nodes, recently-changed nodes, and default nodes
|
||||||
@ -434,4 +433,5 @@ minetest.register_alias("moretrees:pine_leaves", "moretrees:cedar_leaves")
|
|||||||
minetest.register_alias("moretrees:pine_cone", "moretrees:cedar_cone")
|
minetest.register_alias("moretrees:pine_cone", "moretrees:cedar_cone")
|
||||||
minetest.register_alias("moretrees:pine_nuts", "moretrees:cedar_nuts")
|
minetest.register_alias("moretrees:pine_nuts", "moretrees:cedar_nuts")
|
||||||
|
|
||||||
minetest.register_alias("moretrees:dates", "moretrees:dates_f4")
|
-- Overriding moretrees' palm leaves:
|
||||||
|
minetest.override_item("moretrees:palm_leaves",{walkable = false})
|
||||||
|
0
saplings.lua
Normal file → Executable file
BIN
screenshot.png
Before Width: | Height: | Size: 113 KiB |
BIN
textures/moretrees_acorn.png
Normal file → Executable file
Before Width: | Height: | Size: 417 B After Width: | Height: | Size: 398 B |
BIN
textures/moretrees_acorn_muffin.png
Normal file → Executable file
Before Width: | Height: | Size: 782 B After Width: | Height: | Size: 765 B |
BIN
textures/moretrees_acorn_muffin_batter.png
Normal file → Executable file
Before Width: | Height: | Size: 619 B After Width: | Height: | Size: 602 B |
0
textures/moretrees_apple_tree_leaves.png
Normal file → Executable file
Before Width: | Height: | Size: 351 B After Width: | Height: | Size: 351 B |
BIN
textures/moretrees_apple_tree_sapling.png
Normal file → Executable file
Before Width: | Height: | Size: 183 B After Width: | Height: | Size: 178 B |
0
textures/moretrees_apple_tree_trunk.png
Normal file → Executable file
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
0
textures/moretrees_apple_tree_trunk_top.png
Normal file → Executable file
Before Width: | Height: | Size: 503 B After Width: | Height: | Size: 503 B |
0
textures/moretrees_apple_tree_wood.png
Normal file → Executable file
Before Width: | Height: | Size: 464 B After Width: | Height: | Size: 464 B |
0
textures/moretrees_beech_leaves.png
Normal file → Executable file
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 201 B |
0
textures/moretrees_beech_sapling.png
Normal file → Executable file
Before Width: | Height: | Size: 177 B After Width: | Height: | Size: 177 B |
BIN
textures/moretrees_beech_trunk.png
Normal file → Executable file
Before Width: | Height: | Size: 980 B After Width: | Height: | Size: 964 B |
0
textures/moretrees_beech_trunk_top.png
Normal file → Executable file
Before Width: | Height: | Size: 926 B After Width: | Height: | Size: 926 B |
BIN
textures/moretrees_beech_wood.png
Normal file → Executable file
Before Width: | Height: | Size: 175 B After Width: | Height: | Size: 170 B |
0
textures/moretrees_birch_leaves.png
Normal file → Executable file
Before Width: | Height: | Size: 459 B After Width: | Height: | Size: 459 B |
BIN
textures/moretrees_birch_sapling.png
Normal file → Executable file
Before Width: | Height: | Size: 208 B After Width: | Height: | Size: 204 B |
BIN
textures/moretrees_birch_trunk.png
Normal file → Executable file
Before Width: | Height: | Size: 975 B After Width: | Height: | Size: 959 B |
0
textures/moretrees_birch_trunk_top.png
Normal file → Executable file
Before Width: | Height: | Size: 811 B After Width: | Height: | Size: 811 B |
0
textures/moretrees_birch_wood.png
Normal file → Executable file
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
0
textures/moretrees_coconut.png
Normal file → Executable file
Before Width: | Height: | Size: 963 B After Width: | Height: | Size: 963 B |
Before Width: | Height: | Size: 877 B |
Before Width: | Height: | Size: 429 B |
Before Width: | Height: | Size: 1009 B |
BIN
textures/moretrees_coconut_milk.png
Normal file → Executable file
Before Width: | Height: | Size: 227 B After Width: | Height: | Size: 211 B |
0
textures/moretrees_coconut_milk_inv.png
Normal file → Executable file
Before Width: | Height: | Size: 199 B After Width: | Height: | Size: 199 B |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 685 B |
Before Width: | Height: | Size: 608 B |
Before Width: | Height: | Size: 695 B |
Before Width: | Height: | Size: 450 B |
Before Width: | Height: | Size: 757 B |
Before Width: | Height: | Size: 261 B |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 673 B |
Before Width: | Height: | Size: 735 B |
Before Width: | Height: | Size: 9.2 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 8.9 KiB |
Before Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 2.1 KiB |
BIN
textures/moretrees_fir_cone.png
Normal file → Executable file
Before Width: | Height: | Size: 244 B After Width: | Height: | Size: 227 B |
0
textures/moretrees_fir_leaves.png
Normal file → Executable file
Before Width: | Height: | Size: 205 B After Width: | Height: | Size: 205 B |
0
textures/moretrees_fir_leaves_bright.png
Normal file → Executable file
Before Width: | Height: | Size: 205 B After Width: | Height: | Size: 205 B |
0
textures/moretrees_fir_nuts.png
Normal file → Executable file
Before Width: | Height: | Size: 361 B After Width: | Height: | Size: 361 B |
BIN
textures/moretrees_fir_sapling.png
Normal file → Executable file
Before Width: | Height: | Size: 166 B After Width: | Height: | Size: 161 B |
0
textures/moretrees_fir_trunk.png
Normal file → Executable file
Before Width: | Height: | Size: 753 B After Width: | Height: | Size: 753 B |
0
textures/moretrees_fir_trunk_top.png
Normal file → Executable file
Before Width: | Height: | Size: 924 B After Width: | Height: | Size: 924 B |
BIN
textures/moretrees_fir_wood.png
Normal file → Executable file
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
0
textures/moretrees_jungletree_leaves_green.png
Normal file → Executable file
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 201 B |
0
textures/moretrees_jungletree_leaves_red.png
Normal file → Executable file
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 201 B |
0
textures/moretrees_jungletree_leaves_yellow.png
Normal file → Executable file
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 201 B |
0
textures/moretrees_oak_leaves.png
Normal file → Executable file
Before Width: | Height: | Size: 730 B After Width: | Height: | Size: 730 B |
0
textures/moretrees_oak_sapling.png
Normal file → Executable file
Before Width: | Height: | Size: 172 B After Width: | Height: | Size: 172 B |
BIN
textures/moretrees_oak_trunk.png
Normal file → Executable file
Before Width: | Height: | Size: 998 B After Width: | Height: | Size: 982 B |
0
textures/moretrees_oak_trunk_top.png
Normal file → Executable file
Before Width: | Height: | Size: 519 B After Width: | Height: | Size: 519 B |
BIN
textures/moretrees_oak_wood.png
Normal file → Executable file
Before Width: | Height: | Size: 618 B After Width: | Height: | Size: 599 B |
BIN
textures/moretrees_palm_leaves.png
Normal file → Executable file
Before Width: | Height: | Size: 918 B After Width: | Height: | Size: 902 B |
0
textures/moretrees_palm_sapling.png
Normal file → Executable file
Before Width: | Height: | Size: 122 B After Width: | Height: | Size: 122 B |
0
textures/moretrees_palm_trunk.png
Normal file → Executable file
Before Width: | Height: | Size: 295 B After Width: | Height: | Size: 295 B |
0
textures/moretrees_palm_trunk_top.png
Normal file → Executable file
Before Width: | Height: | Size: 400 B After Width: | Height: | Size: 400 B |
BIN
textures/moretrees_palm_wood.png
Normal file → Executable file
Before Width: | Height: | Size: 598 B After Width: | Height: | Size: 580 B |
0
textures/moretrees_raw_coconut.png
Normal file → Executable file
Before Width: | Height: | Size: 466 B After Width: | Height: | Size: 466 B |
0
textures/moretrees_rubber_tree_leaves.png
Normal file → Executable file
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 201 B |
0
textures/moretrees_rubber_tree_sapling.png
Normal file → Executable file
Before Width: | Height: | Size: 151 B After Width: | Height: | Size: 151 B |
0
textures/moretrees_rubber_tree_trunk.png
Normal file → Executable file
Before Width: | Height: | Size: 693 B After Width: | Height: | Size: 693 B |
BIN
textures/moretrees_rubber_tree_trunk_empty.png
Normal file → Executable file
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
0
textures/moretrees_rubber_tree_trunk_top.png
Normal file → Executable file
Before Width: | Height: | Size: 534 B After Width: | Height: | Size: 534 B |
0
textures/moretrees_rubber_tree_wood.png
Normal file → Executable file
Before Width: | Height: | Size: 435 B After Width: | Height: | Size: 435 B |
0
textures/moretrees_sequoia_leaves.png
Normal file → Executable file
Before Width: | Height: | Size: 205 B After Width: | Height: | Size: 205 B |
BIN
textures/moretrees_sequoia_sapling.png
Normal file → Executable file
Before Width: | Height: | Size: 209 B After Width: | Height: | Size: 199 B |
BIN
textures/moretrees_sequoia_trunk.png
Normal file → Executable file
Before Width: | Height: | Size: 621 B After Width: | Height: | Size: 620 B |
0
textures/moretrees_sequoia_trunk_top.png
Normal file → Executable file
Before Width: | Height: | Size: 594 B After Width: | Height: | Size: 594 B |
BIN
textures/moretrees_sequoia_wood.png
Normal file → Executable file
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1021 B |
BIN
textures/moretrees_spruce_cone.png
Normal file → Executable file
Before Width: | Height: | Size: 496 B After Width: | Height: | Size: 478 B |
0
textures/moretrees_spruce_leaves.png
Normal file → Executable file
Before Width: | Height: | Size: 205 B After Width: | Height: | Size: 205 B |
0
textures/moretrees_spruce_nuts.png
Normal file → Executable file
Before Width: | Height: | Size: 365 B After Width: | Height: | Size: 365 B |
BIN
textures/moretrees_spruce_sapling.png
Normal file → Executable file
Before Width: | Height: | Size: 153 B After Width: | Height: | Size: 151 B |
0
textures/moretrees_spruce_trunk.png
Normal file → Executable file
Before Width: | Height: | Size: 753 B After Width: | Height: | Size: 753 B |
0
textures/moretrees_spruce_trunk_top.png
Normal file → Executable file
Before Width: | Height: | Size: 414 B After Width: | Height: | Size: 414 B |
0
textures/moretrees_spruce_wood.png
Normal file → Executable file
Before Width: | Height: | Size: 536 B After Width: | Height: | Size: 536 B |
0
textures/moretrees_willow_leaves.png
Normal file → Executable file
Before Width: | Height: | Size: 409 B After Width: | Height: | Size: 409 B |
0
textures/moretrees_willow_sapling.png
Normal file → Executable file
Before Width: | Height: | Size: 168 B After Width: | Height: | Size: 168 B |