Add files via upload
parent
15e8296863
commit
94a2cad7fe
|
@ -0,0 +1,522 @@
|
|||
--
|
||||
-- Register biomes
|
||||
--
|
||||
|
||||
if true then
|
||||
--minetest.clear_registered_biomes()
|
||||
|
||||
-- Permanent ice
|
||||
|
||||
minetest.register_biome({name = "lib_ecology_glacier",
|
||||
node_dust = "default:snowblock",
|
||||
node_top = "default:snowblock",
|
||||
depth_top = 1,
|
||||
node_filler = "default:snowblock",
|
||||
depth_filler = 3,
|
||||
node_stone = "default:ice",
|
||||
node_water_top = "lib_ecology:ice",
|
||||
depth_water_top = 10,
|
||||
--node_water = "",
|
||||
node_river_water = "lib_ecology:ice",
|
||||
y_min = -8,
|
||||
y_max = 31000,
|
||||
heat_point = 0,
|
||||
humidity_point = 50,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_glacier_ocean",
|
||||
node_dust = "default:snowblock",
|
||||
node_top = "default:sand",
|
||||
depth_top = 1,
|
||||
node_filler = "default:sand",
|
||||
depth_filler = 3,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = -112,
|
||||
y_max = -9,
|
||||
heat_point = 0,
|
||||
humidity_point = 50,
|
||||
})
|
||||
|
||||
-- Cold
|
||||
minetest.register_biome({name = "lib_ecology_tundra",
|
||||
--node_dust = "",
|
||||
node_top = "default:dirt_with_snow",
|
||||
depth_top = 1,
|
||||
node_filler = "default:dirt",
|
||||
depth_filler = 1,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = 2,
|
||||
y_max = 31000,
|
||||
heat_point = 15,
|
||||
humidity_point = 35,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_tundra_beach",
|
||||
--node_dust = "",
|
||||
node_top = "default:gravel",
|
||||
depth_top = 1,
|
||||
node_filler = "default:gravel",
|
||||
depth_filler = 2,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = -3,
|
||||
y_max = 1,
|
||||
heat_point = 15,
|
||||
humidity_point = 35,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_tundra_ocean",
|
||||
--node_dust = "",
|
||||
node_top = "default:sand",
|
||||
depth_top = 1,
|
||||
node_filler = "default:sand",
|
||||
depth_filler = 3,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = -112,
|
||||
y_max = -4,
|
||||
heat_point = 15,
|
||||
humidity_point = 35,
|
||||
})
|
||||
|
||||
minetest.register_biome({name = "lib_ecology_taiga",
|
||||
node_dust = "default:snow",
|
||||
node_top = "default:dirt_with_snow",
|
||||
depth_top = 1,
|
||||
node_filler = "default:dirt",
|
||||
depth_filler = 3,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = 2,
|
||||
y_max = 31000,
|
||||
heat_point = 15,
|
||||
humidity_point = 65,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_taiga_ocean",
|
||||
--node_dust = "",
|
||||
node_top = "default:sand",
|
||||
depth_top = 1,
|
||||
node_filler = "default:sand",
|
||||
depth_filler = 3,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = -112,
|
||||
y_max = 1,
|
||||
heat_point = 15,
|
||||
humidity_point = 65,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_cold_desert",
|
||||
--node_dust = "",
|
||||
node_top = "default:desert_sand",
|
||||
depth_top = 1,
|
||||
node_filler = "default:desert_sand",
|
||||
depth_filler = 1,
|
||||
node_stone = "default:desert_stone",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = 5,
|
||||
y_max = 31000,
|
||||
heat_point = 25,
|
||||
humidity_point = 0,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_cold_desert_ocean",
|
||||
--node_dust = "",
|
||||
node_top = "default:sand",
|
||||
depth_top = 1,
|
||||
node_filler = "default:sand",
|
||||
depth_filler = 3,
|
||||
node_stone = "default:desert_stone",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = -112,
|
||||
y_max = 4,
|
||||
heat_point = 25,
|
||||
humidity_point = 10,
|
||||
})
|
||||
|
||||
|
||||
-- Temperate
|
||||
minetest.register_biome({name = "lib_ecology_stone_grassland",
|
||||
--node_dust = "",
|
||||
node_top = "default:dirt_with_grass",
|
||||
depth_top = 1,
|
||||
node_filler = "default:dirt",
|
||||
depth_filler = 1,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = 6,
|
||||
y_max = 31000,
|
||||
heat_point = 35,
|
||||
humidity_point = 40,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_stone_grassland_dunes",
|
||||
--node_dust = "",
|
||||
node_top = "default:sand",
|
||||
depth_top = 1,
|
||||
node_filler = "default:sand",
|
||||
depth_filler = 2,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = 5,
|
||||
y_max = 5,
|
||||
heat_point = 35,
|
||||
humidity_point = 40,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_stone_grassland_ocean",
|
||||
--node_dust = "",
|
||||
node_top = "default:sand",
|
||||
depth_top = 1,
|
||||
node_filler = "default:sand",
|
||||
depth_filler = 3,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = -112,
|
||||
y_max = 4,
|
||||
heat_point = 35,
|
||||
humidity_point = 40,
|
||||
})
|
||||
|
||||
minetest.register_biome({name = "lib_ecology_coniferous_forest",
|
||||
--node_dust = "",
|
||||
node_top = "default:dirt_with_rainforest_litter",
|
||||
depth_top = 1,
|
||||
node_filler = "default:dirt",
|
||||
depth_filler = 3,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = 6,
|
||||
y_max = 31000,
|
||||
heat_point = 35,
|
||||
humidity_point = 60,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_coniferous_forest_dunes",
|
||||
--node_dust = "",
|
||||
node_top = "default:sand",
|
||||
depth_top = 1,
|
||||
node_filler = "default:dirt",
|
||||
depth_filler = 3,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = 5,
|
||||
y_max = 5,
|
||||
heat_point = 35,
|
||||
humidity_point = 60,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_coniferous_forest_ocean",
|
||||
--node_dust = "",
|
||||
node_top = "default:sand",
|
||||
depth_top = 1,
|
||||
node_filler = "default:sand",
|
||||
depth_filler = 3,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = -112,
|
||||
y_max = 4,
|
||||
heat_point = 35,
|
||||
humidity_point = 60,
|
||||
})
|
||||
|
||||
minetest.register_biome({name = "lib_ecology_sandstone_grassland",
|
||||
--node_dust = "",
|
||||
node_top = "default:dirt_with_dry_grass",
|
||||
depth_top = 1,
|
||||
node_filler = "default:dirt",
|
||||
depth_filler = 1,
|
||||
node_stone = "default:sandstone",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = 6,
|
||||
y_max = 31000,
|
||||
heat_point = 55,
|
||||
humidity_point = 40,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_sandstone_grassland_dunes",
|
||||
--node_dust = "",
|
||||
node_top = "default:sand",
|
||||
depth_top = 1,
|
||||
node_filler = "default:sand",
|
||||
depth_filler = 2,
|
||||
node_stone = "default:sandstone",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = 5,
|
||||
y_max = 5,
|
||||
heat_point = 55,
|
||||
humidity_point = 40,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_sandstone_grassland_ocean",
|
||||
--node_dust = "",
|
||||
node_top = "default:sand",
|
||||
depth_top = 1,
|
||||
node_filler = "default:sand",
|
||||
depth_filler = 3,
|
||||
node_stone = "default:sandstone",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = -112,
|
||||
y_max = 4,
|
||||
heat_point = 55,
|
||||
humidity_point = 40,
|
||||
})
|
||||
|
||||
minetest.register_biome({name = "lib_ecology_deciduous_forest",
|
||||
--node_dust = "",
|
||||
node_top = "default:dirt_with_grass",
|
||||
depth_top = 1,
|
||||
node_filler = "default:dirt",
|
||||
depth_filler = 3,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = 1,
|
||||
y_max = 31000,
|
||||
heat_point = 60,
|
||||
humidity_point = 60,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_deciduous_forest_swamp",
|
||||
--node_dust = "",
|
||||
node_top = "default:dirt",
|
||||
depth_top = 1,
|
||||
node_filler = "default:dirt",
|
||||
depth_filler = 3,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = -3,
|
||||
y_max = 0,
|
||||
heat_point = 60,
|
||||
humidity_point = 60,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_deciduous_forest_ocean",
|
||||
--node_dust = "",
|
||||
node_top = "default:sand",
|
||||
depth_top = 1,
|
||||
node_filler = "default:sand",
|
||||
depth_filler = 3,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = -112,
|
||||
y_max = -4,
|
||||
heat_point = 60,
|
||||
humidity_point = 60,
|
||||
})
|
||||
|
||||
-- Hot
|
||||
minetest.register_biome({name = "lib_ecology_desert",
|
||||
--node_dust = "",
|
||||
node_top = "default:desert_sand",
|
||||
depth_top = 1,
|
||||
node_filler = "default:desert_sandstone",
|
||||
depth_filler = 1,
|
||||
node_stone = "default:desert_stone",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = 5,
|
||||
y_max = 31000,
|
||||
heat_point = 80,
|
||||
humidity_point = 10,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_desert_ocean",
|
||||
--node_dust = "",
|
||||
node_top = "default:sand",
|
||||
depth_top = 1,
|
||||
node_filler = "default:sand",
|
||||
depth_filler = 3,
|
||||
node_stone = "default:desert_stone",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = -112,
|
||||
y_max = 4,
|
||||
heat_point = 80,
|
||||
humidity_point = 10,
|
||||
})
|
||||
|
||||
|
||||
minetest.register_biome({name = "lib_ecology_savanna",
|
||||
--node_dust = "",
|
||||
node_top = "default:dirt_with_dry_grass",
|
||||
depth_top = 1,
|
||||
node_filler = "default:dirt",
|
||||
depth_filler = 1,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = 1,
|
||||
y_max = 31000,
|
||||
heat_point = 80,
|
||||
humidity_point = 25,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_savanna_swamp",
|
||||
--node_dust = "",
|
||||
node_top = "default:dirt_with_rainforest_litter",
|
||||
depth_top = 1,
|
||||
node_filler = "default:clay",
|
||||
depth_filler = 3,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = -3,
|
||||
y_max = 0,
|
||||
heat_point = 80,
|
||||
humidity_point = 25,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_savanna_ocean",
|
||||
--node_dust = "",
|
||||
node_top = "default:sand",
|
||||
depth_top = 1,
|
||||
node_filler = "default:sand",
|
||||
depth_filler = 3,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = -112,
|
||||
y_max = -4,
|
||||
heat_point = 80,
|
||||
humidity_point = 25,
|
||||
})
|
||||
|
||||
minetest.register_biome({name = "lib_ecology_desertstone_grassland",
|
||||
--node_dust = "",
|
||||
node_top = "default:dirt_with_dry_grass",
|
||||
depth_top = 1,
|
||||
node_filler = "default:dirt",
|
||||
depth_filler = 1,
|
||||
node_stone = "default:desert_stone",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = 6,
|
||||
y_max = 31000,
|
||||
heat_point = 80,
|
||||
humidity_point = 55,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_rainforest",
|
||||
--node_dust = "",
|
||||
node_top = "default:dirt_with_rainforest_litter",
|
||||
depth_top = 1,
|
||||
node_filler = "default:dirt",
|
||||
depth_filler = 3,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = 1,
|
||||
y_max = 31000,
|
||||
heat_point = 85,
|
||||
humidity_point = 70,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_rainforest_swamp",
|
||||
--node_dust = "",
|
||||
node_top = "default:dirt_with_rainforest_litter",
|
||||
depth_top = 1,
|
||||
node_filler = "default:clay",
|
||||
depth_filler = 3,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = -3,
|
||||
y_max = 0,
|
||||
heat_point = 85,
|
||||
humidity_point = 70,
|
||||
})
|
||||
minetest.register_biome({name = "lib_ecology_rainforest_ocean",
|
||||
--node_dust = "",
|
||||
node_top = "default:sand",
|
||||
depth_top = 1,
|
||||
node_filler = "default:sand",
|
||||
depth_filler = 3,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = -112,
|
||||
y_max = -4,
|
||||
heat_point = 85,
|
||||
humidity_point = 70,
|
||||
})
|
||||
|
||||
-- Underground
|
||||
minetest.register_biome({name = "lib_ecology_underground",
|
||||
--node_dust = "",
|
||||
--node_top = "",
|
||||
--depth_top = ,
|
||||
--node_filler = "",
|
||||
--depth_filler = ,
|
||||
--node_stone = "",
|
||||
--node_water_top = "",
|
||||
--depth_water_top = ,
|
||||
--node_water = "",
|
||||
--node_river_water = "",
|
||||
y_min = -31000,
|
||||
y_max = -113,
|
||||
heat_point = 50,
|
||||
humidity_point = 50,
|
||||
})
|
||||
end
|
|
@ -0,0 +1,89 @@
|
|||
|
||||
|
||||
-- Copy all the decorations except the ones I don't like.
|
||||
-- This is currently used to remove the default trees.
|
||||
local bad_deco = {"apple_tree", "pine_tree", "jungle_tree", "junglegrass", }
|
||||
local decos = {}
|
||||
for id, deco_table in pairs(minetest.registered_decorations) do
|
||||
if type(deco_table.schematic) ~= "string" or not table.contains_substring(bad_deco, deco_table.schematic) then
|
||||
table.insert(decos, deco_table)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Create and initialize a table for a schematic.
|
||||
function lib_ecology.schematic_array(width, height, depth)
|
||||
-- Dimensions of data array.
|
||||
local s = {size={x=width, y=height, z=depth}}
|
||||
s.data = {}
|
||||
|
||||
for z = 0,depth-1 do
|
||||
for y = 0,height-1 do
|
||||
for x = 0,width-1 do
|
||||
local i = z*width*height + y*width + x + 1
|
||||
s.data[i] = {}
|
||||
s.data[i].name = "air"
|
||||
s.data[i].param1 = 000
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
s.yslice_prob = {}
|
||||
|
||||
return s
|
||||
end
|
||||
|
||||
|
||||
-- Clear all decorations, so I can place the new trees.
|
||||
minetest.clear_registered_decorations()
|
||||
|
||||
-- A list of all schematics, for re-use.
|
||||
lib_ecology.schematics = {}
|
||||
|
||||
|
||||
-- Specific decoration code.
|
||||
if lib_ecology.houses then
|
||||
dofile(lib_ecology.path.."/valleys_c/deco_houses.lua")
|
||||
end
|
||||
|
||||
dofile(lib_ecology.path.."/valleys_c/deco_coral.lua")
|
||||
dofile(lib_ecology.path.."/valleys_c/deco_dirt.lua")
|
||||
dofile(lib_ecology.path.."/valleys_c/deco_trees.lua")
|
||||
dofile(lib_ecology.path.."/valleys_c/deco_plants.lua")
|
||||
dofile(lib_ecology.path.."/valleys_c/deco_rocks.lua")
|
||||
dofile(lib_ecology.path.."/valleys_c/deco_caves.lua")
|
||||
dofile(lib_ecology.path.."/valleys_c/deco_fungal_tree.lua")
|
||||
dofile(lib_ecology.path.."/valleys_c/deco_ferns.lua")
|
||||
dofile(lib_ecology.path.."/valleys_c/deco_ferns_tree.lua")
|
||||
dofile(lib_ecology.path.."/valleys_c/deco_water.lua")
|
||||
|
||||
|
||||
-- biomes = {"sandstone_grassland", "glacier", "tundra", "taiga", "stone_grassland", "coniferous_forest", "deciduous_forest", "desert", "savanna", "rainforest", "rainforest_swamp", "desertstone_grassland", },
|
||||
|
||||
|
||||
-- Re-register the good decorations.
|
||||
-- This has to be done after registering the trees or
|
||||
-- the trees spawn on top of grass. /shrug
|
||||
for _, i in pairs(decos) do
|
||||
minetest.register_decoration(i)
|
||||
end
|
||||
|
||||
minetest.register_decoration({
|
||||
deco_type = "simple",
|
||||
place_on = {"default:dirt_with_grass", "default:dirt_with_rainforest_litter"},
|
||||
sidelen = 80,
|
||||
fill_ratio = 0.1,
|
||||
biomes = {"lib_ecology_rainforest", "lib_ecology_desertstone_grassland"},
|
||||
y_min = 1,
|
||||
y_max = 31000,
|
||||
decoration = "default:junglegrass",
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:stick 2",
|
||||
recipe = {
|
||||
{"default:cactus"}
|
||||
}
|
||||
})
|
||||
|
||||
minetest.add_group("default:cactus", {oddly_breakable_by_hand=1})
|
|
@ -0,0 +1,68 @@
|
|||
-------------------
|
||||
-- Banana Plants --
|
||||
-------------------
|
||||
|
||||
-- A shock of leaves at the top and some fruit.
|
||||
function lib_ecology.generate_banana_schematic(trunk_height)
|
||||
local height = trunk_height + 3
|
||||
local radius = 1
|
||||
local width = 3
|
||||
local s = lib_ecology.schematic_array(width, height, width)
|
||||
|
||||
-- the main trunk
|
||||
for y = 0,trunk_height do
|
||||
local i = (0+radius)*width*height + y*width + (0+radius) + 1
|
||||
s.data[i].name = "lib_ecology:banana_tree"
|
||||
s.data[i].param1 = 255
|
||||
s.data[i].force_place = true
|
||||
end
|
||||
|
||||
-- leaves at the top
|
||||
for z = -1,1 do
|
||||
for y = trunk_height+1, height-1 do
|
||||
for x = -1,1 do
|
||||
local i = (z+radius)*width*height + y*width + (x+radius) + 1
|
||||
if y > height - 2 then
|
||||
s.data[i].name = "lib_ecology:banana_leaves"
|
||||
if x == 0 and z == 0 then
|
||||
s.data[i].param1 = 255
|
||||
else
|
||||
s.data[i].param1 = 127
|
||||
end
|
||||
elseif x == 0 and z == 0 then
|
||||
s.data[i].name = "lib_ecology:banana_leaves"
|
||||
s.data[i].param1 = 255
|
||||
elseif x ~= 0 or z ~= 0 then
|
||||
s.data[i].name = "lib_ecology:banana"
|
||||
s.data[i].param1 = 75
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return s
|
||||
end
|
||||
|
||||
|
||||
-- banana plant (It's not a tree.)
|
||||
lib_ecology.schematics.banana_plants = {}
|
||||
do
|
||||
local max_h = 4
|
||||
for h = 2,max_h do
|
||||
local schem = lib_ecology.generate_banana_schematic(h)
|
||||
|
||||
push(lib_ecology.schematics.banana_plants, schem)
|
||||
|
||||
minetest.register_decoration({
|
||||
deco_type = "schematic",
|
||||
sidelen = 80,
|
||||
place_on = {"default:dirt_with_dry_grass", "default:grass", "dirt_with_rainforest_litter"},
|
||||
fill_ratio = (max_h-h+1)/5000,
|
||||
biomes = {"lib_ecology_rainforest", "lib_ecology_desertstone_grassland", },
|
||||
schematic = schem,
|
||||
flags = "place_center_x, place_center_z",
|
||||
rotation = "random",
|
||||
})
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,518 @@
|
|||
----------------------
|
||||
-- Cave Decorations --
|
||||
----------------------
|
||||
|
||||
-- Mushrooms and Speleothems
|
||||
-- These are instantiated by voxel.lua since the decoration manager
|
||||
-- only works at the surface of the world.
|
||||
|
||||
local light_max = 9
|
||||
|
||||
minetest.register_node("lib_ecology:huge_mushroom_cap", {
|
||||
description = "Huge Mushroom Cap",
|
||||
tiles = {"vmg_mushroom_giant_cap.png", "vmg_mushroom_giant_under.png", "vmg_mushroom_giant_cap.png"},
|
||||
is_ground_content = false,
|
||||
paramtype = "light",
|
||||
drawtype = "nodebox",
|
||||
node_box = { type = "fixed",
|
||||
fixed = {
|
||||
{-0.5, -0.5, -0.33, 0.5, -0.33, 0.33},
|
||||
{-0.33, -0.5, 0.33, 0.33, -0.33, 0.5},
|
||||
{-0.33, -0.5, -0.33, 0.33, -0.33, -0.5},
|
||||
{-0.33, -0.33, -0.33, 0.33, -0.17, 0.33},
|
||||
} },
|
||||
light_source = 4,
|
||||
groups = {fleshy=1, dig_immediate=3, flammable=2, plant=1, leafdecay=1},
|
||||
})
|
||||
|
||||
minetest.register_node("lib_ecology:giant_mushroom_cap", {
|
||||
description = "Giant Mushroom Cap",
|
||||
tiles = {"vmg_mushroom_giant_cap.png", "vmg_mushroom_giant_under.png", "vmg_mushroom_giant_cap.png"},
|
||||
is_ground_content = false,
|
||||
paramtype = "light",
|
||||
drawtype = "nodebox",
|
||||
node_box = { type = "fixed",
|
||||
fixed = {
|
||||
{-0.4, -0.5, -0.4, 0.4, 0.0, 0.4},
|
||||
{-0.75, -0.5, -0.4, -0.4, -0.25, 0.4},
|
||||
{0.4, -0.5, -0.4, 0.75, -0.25, 0.4},
|
||||
{-0.4, -0.5, -0.75, 0.4, -0.25, -0.4},
|
||||
{-0.4, -0.5, 0.4, 0.4, -0.25, 0.75},
|
||||
} },
|
||||
light_source = 8,
|
||||
groups = {fleshy=1, dig_immediate=3, flammable=2, plant=1, leafdecay=1},
|
||||
})
|
||||
|
||||
minetest.register_node("lib_ecology:giant_mushroom_stem", {
|
||||
description = "Giant Mushroom Stem",
|
||||
tiles = {"vmg_mushroom_giant_stem.png", "vmg_mushroom_giant_stem.png", "vmg_mushroom_giant_stem.png"},
|
||||
is_ground_content = false,
|
||||
groups = {tree=1,choppy=2,oddly_breakable_by_hand=1,flammable=2, plant=1},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
paramtype = "light",
|
||||
drawtype = "nodebox",
|
||||
node_box = { type = "fixed", fixed = { {-0.25, -0.5, -0.25, 0.25, 0.5, 0.25}, }},
|
||||
})
|
||||
|
||||
-- Mushroom stems can be used as wood, ala Journey to the Center of the Earth.
|
||||
minetest.register_craft({
|
||||
output = "default:wood",
|
||||
recipe = {
|
||||
{"lib_ecology:giant_mushroom_stem"}
|
||||
}
|
||||
})
|
||||
|
||||
-- Caps can be cooked and eaten.
|
||||
minetest.register_node("lib_ecology:mushroom_steak", {
|
||||
description = "Mushroom Steak",
|
||||
drawtype = "plantlike",
|
||||
paramtype = "light",
|
||||
tiles = {"vmg_mushroom_steak.png"},
|
||||
inventory_image = "vmg_mushroom_steak.png",
|
||||
on_use = minetest.item_eat(4),
|
||||
groups = {dig_immediate = 3, attached_node = 1},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "lib_ecology:mushroom_steak",
|
||||
recipe = "lib_ecology:huge_mushroom_cap",
|
||||
cooktime = 2,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "lib_ecology:mushroom_steak 2",
|
||||
recipe = "lib_ecology:giant_mushroom_cap",
|
||||
cooktime = 2,
|
||||
})
|
||||
|
||||
-- Glowing fungal stone provides an eerie light.
|
||||
minetest.register_node("lib_ecology:glowing_fungal_stone", {
|
||||
description = "Glowing Fungal Stone",
|
||||
tiles = {"default_stone.png^vmg_glowing_fungal.png",},
|
||||
is_ground_content = true,
|
||||
light_source = 8,
|
||||
groups = {cracky=3, stone=1},
|
||||
drop = {items={ {items={"default:cobble"},}, {items={"lib_ecology:glowing_fungus",},},},},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("lib_ecology:glowing_fungus", {
|
||||
description = "Glowing Fungus",
|
||||
drawtype = "plantlike",
|
||||
paramtype = "light",
|
||||
tiles = {"vmg_glowing_fungus.png"},
|
||||
inventory_image = "vmg_glowing_fungus.png",
|
||||
groups = {dig_immediate = 3, attached_node = 1},
|
||||
})
|
||||
|
||||
-- The fungus can be made into juice and then into glowing glass.
|
||||
minetest.register_node("lib_ecology:moon_juice", {
|
||||
description = "Moon Juice",
|
||||
drawtype = "plantlike",
|
||||
paramtype = "light",
|
||||
tiles = {"vmg_moon_juice.png"},
|
||||
inventory_image = "vmg_moon_juice.png",
|
||||
groups = {dig_immediate = 3, attached_node = 1},
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("lib_ecology:moon_glass", {
|
||||
description = "Moon Glass",
|
||||
drawtype = "glasslike",
|
||||
tiles = {"default_glass.png",},
|
||||
inventory_image = minetest.inventorycube("default_glass.png"),
|
||||
is_ground_content = true,
|
||||
light_source = default.LIGHT_MAX,
|
||||
groups = {cracky=3},
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "lib_ecology:moon_juice",
|
||||
recipe = {
|
||||
{"lib_ecology:glowing_fungus", "lib_ecology:glowing_fungus", "lib_ecology:glowing_fungus"},
|
||||
{"lib_ecology:glowing_fungus", "lib_ecology:glowing_fungus", "lib_ecology:glowing_fungus"},
|
||||
{"lib_ecology:glowing_fungus", "vessels:glass_bottle", "lib_ecology:glowing_fungus"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "lib_ecology:moon_glass",
|
||||
type = "shapeless",
|
||||
recipe = {
|
||||
"lib_ecology:moon_juice",
|
||||
"lib_ecology:moon_juice",
|
||||
"default:glass",
|
||||
},
|
||||
})
|
||||
|
||||
-- What's a cave without speleothems?
|
||||
local spel = {
|
||||
{type1="stalactite", type2="stalagmite", tile="default_stone.png"},
|
||||
{type1="stalactite_slimy", type2="stalagmite_slimy", tile="default_stone.png^valc_algae.png"},
|
||||
{type1="stalactite_mossy", type2="stalagmite_mossy", tile="default_stone.png^valc_moss.png"},
|
||||
{type1="icicle_down", type2="icicle_up", desc="Icicle", tile="caverealms_thin_ice.png", drop="default:ice"},
|
||||
}
|
||||
|
||||
for _, desc in pairs(spel) do
|
||||
minetest.register_node("lib_ecology:"..desc.type1, {
|
||||
description = (desc.desc or "Stalactite"),
|
||||
tiles = {desc.tile},
|
||||
is_ground_content = true,
|
||||
walkable = false,
|
||||
paramtype = "light",
|
||||
--light_source = 14,
|
||||
drop = (desc.drop or "lib_ecology:stalactite"),
|
||||
drawtype = "nodebox",
|
||||
node_box = { type = "fixed",
|
||||
fixed = {
|
||||
{-0.07, 0.0, -0.07, 0.07, 0.5, 0.07},
|
||||
{-0.04, -0.25, -0.04, 0.04, 0.0, 0.04},
|
||||
{-0.02, -0.5, -0.02, 0.02, 0.25, 0.02},
|
||||
} },
|
||||
groups = {rock=1, cracky=3},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("lib_ecology:"..desc.type2, {
|
||||
description = (desc.desc or "Stalagmite"),
|
||||
tiles = {desc.tile},
|
||||
is_ground_content = true,
|
||||
walkable = false,
|
||||
paramtype = "light",
|
||||
--light_source = 14,
|
||||
drop = "lib_ecology:stalagmite",
|
||||
drawtype = "nodebox",
|
||||
node_box = { type = "fixed",
|
||||
fixed = {
|
||||
{-0.07, -0.5, -0.07, 0.07, 0.0, 0.07},
|
||||
{-0.04, 0.0, -0.04, 0.04, 0.25, 0.04},
|
||||
{-0.02, 0.25, -0.02, 0.02, 0.5, 0.02},
|
||||
} },
|
||||
groups = {rock=1, cracky=3},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
end
|
||||
|
||||
-- They can be made into cobblestone, to get them out of inventory.
|
||||
minetest.register_craft({
|
||||
output = "default:cobble",
|
||||
recipe = {
|
||||
{"", "", ""},
|
||||
{"lib_ecology:stalactite", "lib_ecology:stalactite", ""},
|
||||
{"lib_ecology:stalactite", "lib_ecology:stalactite", ""},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:cobble",
|
||||
recipe = {
|
||||
{"", "", ""},
|
||||
{"lib_ecology:stalagmite", "lib_ecology:stalagmite", ""},
|
||||
{"lib_ecology:stalagmite", "lib_ecology:stalagmite", ""},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_node("lib_ecology:glowing_dirt", {
|
||||
description = "Glowing Dirt",
|
||||
tiles = {"default_dirt.png"},
|
||||
groups = {crumbly = 3, soil = 1},
|
||||
light_source = default.LIGHT_MAX,
|
||||
sounds = default.node_sound_dirt_defaults(),
|
||||
soil = {
|
||||
base = "lib_ecology:glowing_dirt",
|
||||
dry = "lib_ecology:glowing_soil",
|
||||
wet = "lib_ecology:glowing_soil_wet"
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_node("lib_ecology:glowing_soil", {
|
||||
description = "Glowing Soil",
|
||||
tiles = {"default_dirt.png^farming_soil.png", "default_dirt.png"},
|
||||
drop = "lib_ecology:glowing_dirt",
|
||||
groups = {crumbly=3, not_in_creative_inventory=1, soil=2, grassland = 1, field = 1},
|
||||
sounds = default.node_sound_dirt_defaults(),
|
||||
light_source = default.LIGHT_MAX,
|
||||
soil = {
|
||||
base = "lib_ecology:glowing_dirt",
|
||||
dry = "lib_ecology:glowing_soil",
|
||||
wet = "lib_ecology:glowing_soil_wet"
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_node("lib_ecology:glowing_soil_wet", {
|
||||
description = "Wet Glowing Soil",
|
||||
tiles = {"default_dirt.png^farming_soil_wet.png", "default_dirt.png^farming_soil_wet_side.png"},
|
||||
drop = "lib_ecology:glowing_dirt",
|
||||
groups = {crumbly=3, not_in_creative_inventory=1, soil=3, wet = 1, grassland = 1, field = 1},
|
||||
sounds = default.node_sound_dirt_defaults(),
|
||||
light_source = default.LIGHT_MAX,
|
||||
soil = {
|
||||
base = "lib_ecology:glowing_dirt",
|
||||
dry = "lib_ecology:glowing_soil",
|
||||
wet = "lib_ecology:glowing_soil_wet"
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "lib_ecology:glowing_dirt",
|
||||
type = "shapeless",
|
||||
recipe = {
|
||||
"lib_ecology:moon_juice",
|
||||
"default:dirt",
|
||||
},
|
||||
})
|
||||
|
||||
--thin (transparent) ice
|
||||
minetest.register_node("lib_ecology:thin_ice", {
|
||||
description = "Thin Ice",
|
||||
tiles = {"caverealms_thin_ice.png"},
|
||||
is_ground_content = true,
|
||||
groups = {cracky=3},
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
use_texture_alpha = true,
|
||||
light_source = 1,
|
||||
drawtype = "glasslike",
|
||||
sunlight_propagates = true,
|
||||
freezemelt = "default:water_source",
|
||||
paramtype = "light",
|
||||
})
|
||||
|
||||
minetest.register_node("lib_ecology:stone_with_moss", {
|
||||
description = "Cave Stone with Moss",
|
||||
tiles = {"default_stone.png^valc_moss.png"},
|
||||
is_ground_content = true,
|
||||
light_source = 1,
|
||||
groups = {stone=1, crumbly=3},
|
||||
drop = 'default:cobble',
|
||||
sounds = default.node_sound_dirt_defaults({
|
||||
footstep = {name="default_grass_footstep", gain=0.25},
|
||||
}),
|
||||
})
|
||||
|
||||
minetest.register_node("lib_ecology:stone_with_lichen", {
|
||||
description = "Cave Stone with Lichen",
|
||||
tiles = {"default_stone.png^valc_lichen.png"},
|
||||
is_ground_content = true,
|
||||
light_source = 1,
|
||||
groups = {stone=1, crumbly=3},
|
||||
drop = 'default:cobble',
|
||||
sounds = default.node_sound_dirt_defaults({
|
||||
footstep = {name="default_grass_footstep", gain=0.25},
|
||||
}),
|
||||
})
|
||||
|
||||
minetest.register_node("lib_ecology:stone_with_algae", {
|
||||
description = "Cave Stone with Algae",
|
||||
tiles = {"default_stone.png^valc_algae.png"},
|
||||
is_ground_content = true,
|
||||
light_source = 1,
|
||||
groups = {stone=1, crumbly=3},
|
||||
drop = 'default:cobble',
|
||||
sounds = default.node_sound_dirt_defaults({
|
||||
footstep = {name="default_grass_footstep", gain=0.25},
|
||||
}),
|
||||
})
|
||||
|
||||
minetest.register_node("lib_ecology:stone_with_salt", {
|
||||
description = "Cave Stone with Salt",
|
||||
tiles = {"caverealms_salty2.png"},--{"caverealms_salty2.png^caverealms_salty.png", "caverealms_salty2.png", "caverealms_salty2.png^caverealms_salty_side.png"},
|
||||
light_source = 9,
|
||||
paramtype = "light",
|
||||
use_texture_alpha = true,
|
||||
drawtype = "glasslike",
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = true,
|
||||
groups = {stone=1, crumbly=3},
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
})
|
||||
|
||||
--Glow Obsidian
|
||||
minetest.register_node("lib_ecology:glow_obsidian", {
|
||||
description = "Glowing Obsidian",
|
||||
tiles = {"caverealms_glow_obsidian.png"},
|
||||
is_ground_content = true,
|
||||
groups = {stone=2, crumbly=1},
|
||||
light_source = 7,
|
||||
sounds = default.node_sound_stone_defaults({
|
||||
footstep = {name="default_stone_footstep", gain=0.25},
|
||||
}),
|
||||
})
|
||||
|
||||
--Glow Obsidian 2 - has traces of lava
|
||||
minetest.register_node("lib_ecology:glow_obsidian_2", {
|
||||
description = "Hot Glow Obsidian",
|
||||
tiles = {"caverealms_glow_obsidian2.png"},
|
||||
is_ground_content = true,
|
||||
groups = {stone=2, crumbly=1, hot=1},
|
||||
damage_per_second = 1,
|
||||
light_source = 9,
|
||||
sounds = default.node_sound_stone_defaults({
|
||||
footstep = {name="default_stone_footstep", gain=0.25},
|
||||
}),
|
||||
})
|
||||
|
||||
|
||||
--minetest.register_node("lib_ecology:bright_air", {
|
||||
-- drawtype = "glasslike",
|
||||
-- tiles = {"technic_light.png"},
|
||||
-- paramtype = "light",
|
||||
-- groups = {not_in_creative_inventory=1},
|
||||
-- drop = "",
|
||||
-- walkable = false,
|
||||
-- buildable_to = true,
|
||||
-- sunlight_propagates = true,
|
||||
-- light_source = LIGHT_MAX,
|
||||
-- pointable = false,
|
||||
--})
|
||||
|
||||
--define special flame so that it does not expire
|
||||
minetest.register_node("lib_ecology:constant_flame", {
|
||||
description = "Fire",
|
||||
drawtype = "plantlike",
|
||||
tiles = {{
|
||||
name="fire_basic_flame_animated.png",
|
||||
animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=1},
|
||||
}},
|
||||
inventory_image = "fire_basic_flame.png",
|
||||
light_source = 14,
|
||||
groups = {igniter=2,dig_immediate=3,hot=3, not_in_creative_inventory=1},
|
||||
drop = '',
|
||||
walkable = false,
|
||||
buildable_to = true,
|
||||
damage_per_second = 4,
|
||||
|
||||
--after_place_node = function(pos, placer)
|
||||
-- if pos.y > -7000 then
|
||||
-- minetest.remove_node(pos)
|
||||
-- end
|
||||
--end,
|
||||
})
|
||||
|
||||
--Hot Cobble - cobble with lava instead of mortar XD
|
||||
minetest.register_node("lib_ecology:hot_cobble", {
|
||||
description = "Hot Cobble",
|
||||
tiles = {"caverealms_hot_cobble.png"},
|
||||
is_ground_content = true,
|
||||
groups = {crumbly=2, hot=1},
|
||||
damage_per_second = 1,
|
||||
light_source = 3,
|
||||
sounds = default.node_sound_stone_defaults({
|
||||
footstep = {name="default_stone_footstep", gain=0.25},
|
||||
}),
|
||||
})
|
||||
|
||||
-- mushroom growth
|
||||
minetest.register_abm({
|
||||
nodenames = {"flowers:mushroom_brown", "flowers:mushroom_red"},
|
||||
interval = 50 * lib_ecology.time_factor,
|
||||
chance = 100,
|
||||
action = function(pos, node)
|
||||
if pos.y > -50 then
|
||||
return
|
||||
end
|
||||
local pos_up = {x=pos.x,y=pos.y+1,z=pos.z}
|
||||
local node_up = minetest.get_node_or_nil(pos_up)
|
||||
if not node_up then
|
||||
return
|
||||
end
|
||||
if node_up.name ~= "air" then
|
||||
return
|
||||
end
|
||||
local node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
|
||||
if not node_under then
|
||||
return
|
||||
end
|
||||
if minetest.get_item_group(node_under.name, "soil") ~= 0 and
|
||||
minetest.get_node_light(pos_up, nil) <= light_max then
|
||||
minetest.set_node(pos_up, {name = "lib_ecology:huge_mushroom_cap"})
|
||||
minetest.set_node(pos, {name = "lib_ecology:giant_mushroom_stem"})
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
-- mushroom growth
|
||||
minetest.register_abm({
|
||||
nodenames = {"lib_ecology:huge_mushroom_cap"},
|
||||
interval = 100 * lib_ecology.time_factor,
|
||||
chance = 150,
|
||||
action = function(pos, node)
|
||||
if minetest.get_node_light(pos, nil) >= 14 then
|
||||
minetest.set_node(pos, {name = "air"})
|
||||
return
|
||||
end
|
||||
local pos_up = {x=pos.x,y=pos.y+1,z=pos.z}
|
||||
local node_up = minetest.get_node_or_nil(pos_up)
|
||||
if not node_up then
|
||||
return
|
||||
end
|
||||
if node_up.name ~= "air" then
|
||||
return
|
||||
end
|
||||
local node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
|
||||
if not node_under or node_under.name ~= "lib_ecology:giant_mushroom_stem" then
|
||||
return
|
||||
end
|
||||
node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 2, z = pos.z})
|
||||
if not node_under then
|
||||
return
|
||||
end
|
||||
if minetest.get_item_group(node_under.name, "soil") ~= 0 and
|
||||
minetest.get_node_light(pos_up, nil) <= light_max then
|
||||
minetest.set_node(pos_up, {name = "lib_ecology:giant_mushroom_cap"})
|
||||
minetest.set_node(pos, {name = "lib_ecology:giant_mushroom_stem"})
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
-- mushroom growth
|
||||
minetest.register_abm({
|
||||
nodenames = {"lib_ecology:giant_mushroom_stem"},
|
||||
interval = 5 * lib_ecology.time_factor,
|
||||
chance = 5,
|
||||
action = function(pos, node)
|
||||
local pos_up = {x=pos.x,y=pos.y+1,z=pos.z}
|
||||
local node_up = minetest.get_node_or_nil(pos_up)
|
||||
if not node_up then
|
||||
return
|
||||
end
|
||||
if node_up.name ~= "air" then
|
||||
return
|
||||
end
|
||||
if minetest.get_node_light(pos_up, nil) <= light_max then
|
||||
minetest.set_node(pos_up, {name = "lib_ecology:huge_mushroom_cap"})
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
-- mushroom spread
|
||||
minetest.register_abm({
|
||||
nodenames = {"lib_ecology:giant_mushroom_cap", "lib_ecology:huge_mushroom_cap"},
|
||||
interval = 3 * lib_ecology.time_factor,
|
||||
chance = 40,
|
||||
action = function(pos, node)
|
||||
if minetest.get_node_light(pos, nil) >= 14 then
|
||||
minetest.set_node(pos, {name = "air"})
|
||||
return
|
||||
end
|
||||
local pos_down = pos
|
||||
pos_down.y = pos_down.y - 1
|
||||
local pos1, count = minetest.find_nodes_in_area_under_air(vector.subtract(pos_down, 4), vector.add(pos_down, 4), {"group:soil"})
|
||||
if #pos1 < 1 then
|
||||
return
|
||||
end
|
||||
local random = pos1[math.random(1, #pos1)]
|
||||
random.y = random.y + 1
|
||||
local mushroom_type
|
||||
if math.random(1,2) == 1 then
|
||||
mushroom_type = "flowers:mushroom_red"
|
||||
else
|
||||
mushroom_type = "flowers:mushroom_brown"
|
||||
end
|
||||
if minetest.get_node_light(random, nil) <= light_max then
|
||||
minetest.set_node(random, {name = mushroom_type})
|
||||
end
|
||||
end
|
||||
})
|
|
@ -0,0 +1,193 @@
|
|||
-------------------
|
||||
-- Conifer Trees --
|
||||
-------------------
|
||||
|
||||
-- Create different colored needles with the same properties.
|
||||
newnode = lib_ecology.clone_node("default:pine_needles")
|
||||
if lib_ecology.noleafdecay then
|
||||
newnode.groups.leafdecay = 0
|
||||
end
|
||||
newnode.tiles = {"default_pine_needles.png^[colorize:#FF0000:20"}
|
||||
minetest.register_node("lib_ecology:pine_needles2", newnode)
|
||||
newnode.tiles = {"default_pine_needles.png^[colorize:#FFFF00:20"}
|
||||
minetest.register_node("lib_ecology:pine_needles3", newnode)
|
||||
newnode.tiles = {"default_pine_needles.png^[colorize:#00FF00:20"}
|
||||
minetest.register_node("lib_ecology:pine_needles4", newnode)
|
||||
|
||||
if lib_ecology.glow then
|
||||
minetest.register_node("lib_ecology:pine_tree_glowing_moss", {
|
||||
description = "Pine tree with glowing moss",
|
||||
tiles = {"default_pine_tree_top.png", "default_pine_tree_top.png",
|
||||
"default_pine_tree.png^trunks_moss.png"},
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
light_source = 4,
|
||||
drop = 'default:pine_tree',
|
||||
groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
|
||||
on_place = minetest.rotate_node
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
-- similar to the general tree schematic, but basically vertical
|
||||
function lib_ecology.generate_conifer_schematic(trunk_height, radius, trunk, leaf)
|
||||
local height = trunk_height + radius * 3 + 2
|
||||
local width = 2 * radius + 1
|
||||
local trunk_top = height - radius - 1
|
||||
local s = lib_ecology.schematic_array(width, height, width)
|
||||
|
||||
-- the main trunk
|
||||
local probs = {200,150,100,75,50,25}
|
||||
for z = -radius,radius do
|
||||
for y = 1,trunk_top do
|
||||
-- Gives it a vaguely conical shape.
|
||||
local r1 = math.ceil((height - y) / 4)
|
||||
-- But rounded at the bottom.
|
||||
if y == trunk_height + 1 then
|
||||
r1 = r1 -1
|
||||
end
|
||||
|
||||
for x = -radius,radius do
|
||||
local i = (z+radius)*width*height + y*width + (x+radius) + 1
|
||||
local dist = math.round(math.sqrt(x^2 + z^2))
|
||||
if x == 0 and z == 0 then
|
||||
if trunk == "default:pine_tree" and lib_ecology.glow and math.random(1,10) == 1 then
|
||||
s.data[i].name = "lib_ecology:pine_tree_glowing_moss"
|
||||
else
|
||||
s.data[i].name = trunk
|
||||
end
|
||||
s.data[i].param1 = 255
|
||||
s.data[i].force_place = true
|
||||
elseif y > trunk_height and dist <= r1 then
|
||||
s.data[i].name = leaf
|
||||
s.data[i].param1 = probs[dist]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- leaves at the top
|
||||
for z = -1,1 do
|
||||
for y = trunk_top, height-1 do
|
||||
for x = -1,1 do
|
||||
local i = (z+radius)*width*height + y*width + (x+radius) + 1
|
||||
if (x == 0 and z == 0) or y < height - 1 then
|
||||
s.data[i].name = leaf
|
||||
if x == 0 and z == 0 then
|
||||
s.data[i].param1 = 255
|
||||
else
|
||||
s.data[i].param1 = 200
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return s
|
||||
end
|
||||
|
||||
|
||||
-- the default pine schematic
|
||||
function lib_ecology.generate_default_conifer_schematic(trunk, leaf)
|
||||
local height = 13 + 1
|
||||
local width = 5
|
||||
local s = lib_ecology.schematic_array(width, height, width)
|
||||
|
||||
-- the main trunk
|
||||
local probs = {255,220,190}
|
||||
|
||||
for p = 0,2 do
|
||||
local c = math.floor(width / 2)
|
||||
local y = height - p * 3 - 1
|
||||
for r = 0,2 do
|
||||
for z = c-r,c+r do
|
||||
for x = c-r,c+r do
|
||||
local i = z*width*height + (y-r)*width + x + 1
|
||||
s.data[i].name = leaf
|
||||
s.data[i].param1 = probs[r]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
s.yslice_prob = {}
|
||||
for y = 1,height-3 do
|
||||
local i = 2*width*height + y*width + 2 + 1
|
||||
if trunk == "default:pine_tree" and lib_ecology.glow and math.random(1,10) == 1 then
|
||||
s.data[i].name = "lib_ecology:pine_tree_glowing_moss"
|
||||
else
|
||||
s.data[i].name = trunk
|
||||
end
|
||||
|
||||
s.data[i].param1 = 255
|
||||
s.data[i].force_place = true
|
||||
|
||||
local j = (height - y - 1) / 3
|
||||
if j == 0 or j == 1 or j == 2 or y <= height - 11 then
|
||||
s.yslice_prob[#s.yslice_prob+1] = {ypos=y,prob=170}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return s
|
||||
end
|
||||
|
||||
|
||||
-- generic conifers
|
||||
lib_ecology.schematics.conifer_trees = {}
|
||||
leaves = {"default:pine_needles", "lib_ecology:pine_needles2", "lib_ecology:pine_needles3", "lib_ecology:pine_needles4"}
|
||||
for i = 1,#leaves do
|
||||
local max_r = 4
|
||||
for r = 2,max_r do
|
||||
local schem = lib_ecology.generate_conifer_schematic(2, r, "default:pine_tree", leaves[i])
|
||||
|
||||
push(lib_ecology.schematics.conifer_trees, schem)
|
||||
|
||||
minetest.register_decoration({
|
||||
deco_type = "schematic",
|
||||
sidelen = 80,
|
||||
place_on = {"default:dirt_with_snow", "default:dirt_with_grass", "dirt_with_rainforest_litter"},
|
||||
fill_ratio = (max_r-r+1)/500,
|
||||
biomes = {"lib_ecology_coniferous_forest", "lib_ecology_taiga",},
|
||||
schematic = schem,
|
||||
flags = "place_center_x, place_center_z",
|
||||
y_min = 2,
|
||||
rotation = "random",
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if false then
|
||||
-- generic conifers
|
||||
lib_ecology.schematics.conifer_trees = {}
|
||||
leaves = {"default:pine_needles", "lib_ecology:pine_needles2", "lib_ecology:pine_needles3", "lib_ecology:pine_needles4"}
|
||||
for i = 1,#leaves do
|
||||
local schem = lib_ecology.generate_default_conifer_schematic("default:pine_tree", leaves[i])
|
||||
|
||||
push(lib_ecology.schematics.conifer_trees, schem)
|
||||
|
||||
minetest.register_decoration({
|
||||
deco_type = "schematic",
|
||||
sidelen = 80,
|
||||
place_on = {"default:dirt_with_snow", "default:dirt_with_grass"},
|
||||
fill_ratio = 6/500,
|
||||
biomes = {"lib_ecology_coniferous_forest", "lib_ecology_taiga",},
|
||||
schematic = schem,
|
||||
flags = "place_center_x, place_center_z",
|
||||
y_min = 2,
|
||||
rotation = "random",
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- Place the schematic when a sapling grows.
|
||||
function default.grow_new_pine_tree(pos, bad)
|
||||
local schem = lib_ecology.schematics.conifer_trees[math.random(1,#lib_ecology.schematics.conifer_trees)]
|
||||
local adj = {x = pos.x - math.floor(schem.size.x / 2),
|
||||
y = pos.y - 1,
|
||||
z = pos.z - math.floor(schem.size.z / 2)}
|
||||
minetest.place_schematic(adj, schem, 'random', nil, true)
|
||||
end
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
|
||||
|
||||
|
||||
-- The pillars are neat, but a huge fps killer en masse.
|
||||
--local grid = {}
|
||||
--local pillars = 5
|
||||
--for x = 1,pillars do
|
||||
-- for z = 1,pillars do
|
||||
-- local d2 = (2 / (pillars + 2)) / (pillars - 1)
|
||||
-- local d1 = (1 + d2) / pillars
|
||||
-- local g = {}
|
||||
-- g[#g + 1] = (x - 1) * d1 - 0.5
|
||||
-- g[#g + 1] = -0.5
|
||||
-- g[#g + 1] = (z - 1) * d1 - 0.5
|
||||
-- g[#g + 1] = x * d1 - d2 - 0.5
|
||||
-- g[#g + 1] = 0.5 - (math.random(1,4) + math.random(4)) * 0.1
|
||||
-- g[#g + 1] = z * d1 - d2 - 0.5
|
||||
-- grid[#grid + 1] = g
|
||||
-- end
|
||||
--end
|
||||
|
||||
minetest.register_node("lib_ecology:pillar_coral", {
|
||||
description = "Pillar Coral",
|
||||
tiles = {"valc_pillar_coral.png"},
|
||||
paramtype = "light",
|
||||
-- drawtype = "nodebox",
|
||||
light_source = 2,
|
||||
-- node_box = {
|
||||
-- type = "fixed",
|
||||
-- fixed = grid,
|
||||
-- },
|
||||
-- selection_box = {
|
||||
-- type = "fixed",
|
||||
-- fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
||||
-- },
|
||||
-- groups = {cracky = 3, stone=1, sea=1},
|
||||
groups = {cracky = 3, stone=1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_node("lib_ecology:brain_coral", {
|
||||
description = "Brain Coral",
|
||||
tiles = {"valc_brain_coral.png"},
|
||||
light_source = 4,
|
||||
groups = {cracky = 3, stone=1,},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_node("lib_ecology:dragon_eye", {
|
||||
description = "Dragon Eye",
|
||||
tiles = {"valc_dragon_eye.png"},
|
||||
light_source = 4,
|
||||
groups = {cracky = 3, stone=1,},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_node("lib_ecology:staghorn_coral", {
|
||||
description = "Staghorn Coral",
|
||||
drawtype = "plantlike",
|
||||
tiles = {"valc_staghorn_coral.png"},
|
||||
waving = false,
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
light_source = 2,
|
||||
walkable = false,
|
||||
groups = {cracky = 3, stone=1, attached_node=1, sea=1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
|
||||
},
|
||||
})
|
|
@ -0,0 +1,214 @@
|
|||
---------------------
|
||||
-- Deciduous Trees --
|
||||
---------------------
|
||||
|
||||
-- Make some leaves of different colors (but the same properties).
|
||||
local newnode = lib_ecology.clone_node("default:leaves")
|
||||
if lib_ecology.noleafdecay then
|
||||
newnode.groups.leafdecay = 0
|
||||
end
|
||||
newnode.tiles = {"default_leaves.png^[colorize:#FF0000:20"}
|
||||
minetest.register_node("lib_ecology:leaves2", newnode)
|
||||
newnode.tiles = {"default_leaves.png^[colorize:#FFFF00:20"}
|
||||
minetest.register_node("lib_ecology:leaves3", newnode)
|
||||
newnode.tiles = {"default_leaves.png^[colorize:#00FFFF:20"}
|
||||
minetest.register_node("lib_ecology:leaves4", newnode)
|
||||
newnode.tiles = {"default_leaves.png^[colorize:#00FF00:20"}
|
||||
minetest.register_node("lib_ecology:leaves5", newnode)
|
||||
|
||||
if lib_ecology.glow then
|
||||
minetest.register_node("lib_ecology:tree_glowing_moss", {
|
||||
description = "Tree with glowing moss",
|
||||
tiles = {"default_tree_top.png", "default_tree_top.png", "default_tree.png^trunks_moss.png"},
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
light_source = 4,
|
||||
drop = 'default:tree',
|
||||
groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
|
||||
on_place = minetest.rotate_node
|
||||
})
|
||||
end
|
||||
|
||||
-- create a schematic for a spherical tree.
|
||||
function lib_ecology.generate_tree_schematic(trunk_height, radii, trunk, leaf, fruit, limbs)
|
||||
-- trunk_height refers to the amount of trunk visible below any leaves.
|
||||
local height = trunk_height + radii.y * 2 + 2
|
||||
local width = 2 * radii.z + 1
|
||||
local trunk_top = height-radii.y-1
|
||||
|
||||
local s = lib_ecology.schematic_array(width, height, width)
|
||||
|
||||
-- the main trunk
|
||||
for y = 1,trunk_top do
|
||||
local i = radii.z*width*height + y*width + radii.x + 1
|
||||
if trunk == "default:tree" and lib_ecology.glow and math.random(1,10) == 1 then
|
||||
s.data[i].name = "lib_ecology:tree_glowing_moss"
|
||||
else
|
||||
s.data[i].name = trunk
|
||||
end
|
||||
s.data[i].param1 = 255
|
||||
s.data[i].force_place = false
|
||||
end
|
||||
|
||||
-- some leaves for free
|
||||
lib_ecology.generate_leaves(s, leaf, {x=0, y=trunk_top, z=0}, radii.x, fruit)
|
||||
|
||||
-- Specify a table of limb positions...
|
||||
if radii.x > 3 and limbs then
|
||||
for _, p in pairs(limbs) do
|
||||
local i = (p.z+radii.z)*width*height + p.y*width + (p.x+radii.x) + 1
|
||||
s.data[i].name = trunk
|
||||
s.data[i].param1 = 255
|
||||
s.data[i].force_place = false
|
||||
lib_ecology.generate_leaves(s, leaf, p, radii.x, fruit, true)
|
||||
end
|
||||
-- or just do it randomly.
|
||||
elseif radii.x > 3 then
|
||||
for z = -radii.z,radii.z do
|
||||
for y = -radii.y,radii.y do
|
||||
for x = -radii.x,radii.x do
|
||||
-- a smaller spheroid inside the radii
|
||||
if x^2/(radii.x-3)^2 + y^2/(radii.y-3)^2 + z^2/(radii.z-3)^2 <= 1 then
|
||||
if math.random(1,6) == 1 then
|
||||
local i = (z+radii.z)*width*height + (y+trunk_top)*width + (x+radii.x) + 1
|
||||
|
||||
s.data[i].name = trunk
|
||||
s.data[i].param1 = 255
|
||||
s.data[i].force_place = false
|
||||
lib_ecology.generate_leaves(s, leaf, {x=x, y=trunk_top+y, z=z}, radii.x, fruit, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return s
|
||||
end
|
||||
|
||||
-- Create a spheroid of leaves.
|
||||
function lib_ecology.generate_leaves(s, leaf, pos, radius, fruit, adjust)
|
||||
local height = s.size.y
|
||||
local width = s.size.x
|
||||
local rx = math.floor(s.size.x / 2)
|
||||
local rz = math.floor(s.size.z / 2)
|
||||
local r1 = math.min(3, radius) -- leaf decay radius
|
||||
local probs = {255,200,150,100,75}
|
||||
|
||||
for z = -r1,r1 do
|
||||
for y = -r1,r1 do
|
||||
for x = -r1,r1 do
|
||||
if x+pos.x >= -rx and x+pos.x <= rx and y+pos.y >= 0 and y+pos.y < height and z+pos.z >= -rz and z+pos.z <= rz then
|
||||
local i = (z+pos.z+rz)*width*height + (y+pos.y)*width + (x+pos.x+rx) + 1
|
||||
local dist1 = math.sqrt(x^2 + y^2 + z^2)
|
||||
local dist2 = math.sqrt((x+pos.x)^2 + (z+pos.z)^2)
|
||||
if dist1 <= r1 then
|
||||
local newprob = probs[math.max(1, math.ceil(dist1))]
|
||||
if s.data[i].name == "air" then
|
||||
if fruit and (rx < 3 or dist2 / rx > 0.5) and math.random(1,10) == 1 then
|
||||
s.data[i].name = fruit
|
||||
s.data[i].param1 = 127
|
||||
else
|
||||
s.data[i].name = leaf
|
||||
s.data[i].param1 = newprob
|
||||
end
|
||||
elseif adjust and s.data[i].name == leaf then
|
||||
s.data[i].param1 = math.max(s.data[i].param1, newprob)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- generic deciduous trees
|
||||
lib_ecology.schematics.deciduous_trees = {}
|
||||
local leaves = {"default:leaves", "lib_ecology:leaves2", "lib_ecology:leaves3", "lib_ecology:leaves4", "lib_ecology:leaves5"}
|
||||
for i = 1,#leaves do
|
||||
local max_r = 6
|
||||
local fruit = nil
|
||||
|
||||
if i == 1 then
|
||||
fruit = "default:apple"
|
||||
end
|
||||
|
||||
for r = 3,max_r do
|
||||
local schem = lib_ecology.generate_tree_schematic(2, {x=r, y=r, z=r}, "default:tree", leaves[i], fruit)
|
||||
|
||||
push(lib_ecology.schematics.deciduous_trees, schem)
|
||||
|
||||
minetest.register_decoration({
|
||||
deco_type = "schematic",
|
||||
sidelen = 80,
|
||||
place_on = {"default:dirt_with_grass", "default:dirt_with_dry_grass", "dirt_with_rainforest_litter"},
|
||||
y_min = 4,
|
||||
fill_ratio = (max_r-r+1)/1700,
|
||||
biomes = {"lib_ecology_deciduous_forest",},
|
||||
schematic = schem,
|
||||
flags = "place_center_x, place_center_z",
|
||||
rotation = "random",
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- Place the schematic when a sapling grows.
|
||||
function default.grow_new_apple_tree(pos, bad)
|
||||
local schem = lib_ecology.schematics.deciduous_trees[math.random(1,#lib_ecology.schematics.deciduous_trees)]
|
||||
local adj = {x = pos.x - math.floor(schem.size.x / 2),
|
||||
y = pos.y - 1,
|
||||
z = pos.z - math.floor(schem.size.z / 2)}
|
||||
minetest.place_schematic(adj, schem, 'random', nil, true)
|
||||
end
|
||||
|
||||
-- Cherries
|
||||
lib_ecology.schematics.cherry_trees = {}
|
||||
do
|
||||
local max_r = 3
|
||||
local fruit = nil
|
||||
|
||||
for r = 2,max_r do
|
||||
local schem = lib_ecology.generate_tree_schematic(2, {x=r, y=r, z=r}, "lib_ecology:cherry_blossom_tree", "lib_ecology:cherry_blossom_leaves", fruit)
|
||||
|
||||
push(lib_ecology.schematics.cherry_trees, schem)
|
||||
|
||||
minetest.register_decoration({
|
||||
deco_type = "schematic",
|
||||
sidelen = 80,
|
||||
place_on = {"default:dirt_with_grass", "default:dirt_with_dry_grass"},
|
||||
y_min = 4,
|
||||
fill_ratio = (max_r-r+1)/5000,
|
||||
biomes = {"lib_ecology_deciduous_forest",},
|
||||
schematic = schem,
|
||||
flags = "place_center_x, place_center_z",
|
||||
rotation = "random",
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- Birch trees
|
||||
lib_ecology.schematics.birch_trees = {}
|
||||
do
|
||||
local max_h = 4
|
||||
|
||||
for h = 2,max_h do
|
||||
local schem = lib_ecology.generate_tree_schematic(h, {x=2, y=3, z=2}, "lib_ecology:birch_tree", "lib_ecology:birch_leaves")
|
||||
|
||||
push(lib_ecology.schematics.birch_trees, schem)
|
||||
|
||||
minetest.register_decoration({
|
||||
deco_type = "schematic",
|
||||
sidelen = 80,
|
||||
place_on = {"default:dirt_with_snow", "default:dirt_with_grass"},
|
||||
y_min = 4,
|
||||
fill_ratio = (max_h-h+1)/3000,
|
||||
biomes = {"lib_ecology_coniferous_forest", "lib_ecology_taiga",},
|
||||
schematic = schem,
|
||||
flags = "place_center_x, place_center_z",
|
||||
rotation = "random",
|
||||
})
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
|
||||
-- Add silt
|
||||
minetest.register_node("lib_ecology:silt", {
|
||||
description = "Silt",
|
||||
tiles = {"vmg_silt.png"},
|
||||
is_ground_content = true,
|
||||
groups = {crumbly=3},
|
||||
sounds = default.node_sound_dirt_defaults(),
|
||||
})
|
||||
|
||||
-- I don't like the default:clay, this does not look like clay. So add red clay.
|
||||
minetest.register_node("lib_ecology:red_clay", {
|
||||
description = "Red Clay",
|
||||
tiles = {"vmg_red_clay.png"},
|
||||
is_ground_content = true,
|
||||
groups = {crumbly=3},
|
||||
sounds = default.node_sound_dirt_defaults(),
|
||||
})
|
||||
|
||||
minetest.override_item("default:clay", {description = "White Clay"})
|
||||
|
||||
-- Add dirts
|
||||
local function register_dirts(readname)
|
||||
local name = readname:lower()
|
||||
local itemstr_dirt = "lib_ecology:dirt_" .. name
|
||||
local itemstr_lawn = itemstr_dirt .. "_with_grass"
|
||||
local itemstr_dry = itemstr_dirt .. "_with_dry_grass"
|
||||
local itemstr_rain = itemstr_dirt .. "_with_rainforest_litter"
|
||||
local itemstr_snow = itemstr_dirt .. "_with_snow"
|
||||
local tilestr = "vmg_dirt_" .. name .. ".png"
|
||||
|
||||
minetest.register_node(itemstr_dirt, {
|
||||
description = readname .. " Dirt",
|
||||
tiles = {tilestr},
|
||||
is_ground_content = true,
|
||||
groups = {crumbly=3,soil=1},
|
||||
sounds = default.node_sound_dirt_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node(itemstr_lawn, {
|
||||
description = readname .. " Dirt with Grass",
|
||||
tiles = {"default_grass.png", tilestr, tilestr .. "^default_grass_side.png"},
|
||||
is_ground_content = true,
|
||||
groups = {crumbly=3,soil=1},
|
||||
drop = itemstr_dirt,
|
||||
sounds = default.node_sound_dirt_defaults({
|
||||
footstep = {name="default_grass_footstep", gain=0.25},
|
||||
}),
|
||||
})
|
||||
|
||||
minetest.register_node(itemstr_rain, {
|
||||
description = readname .. " Dirt with Rainforest Litter",
|
||||
tiles = {"default_rainforest_litter.png", tilestr, tilestr .. "^default_rainforest_litter_side.png"},
|
||||
is_ground_content = true,
|
||||
groups = {crumbly=3,soil=1},
|
||||
drop = itemstr_dirt,
|
||||
sounds = default.node_sound_dirt_defaults({
|
||||
footstep = {name="default_grass_footstep", gain=0.25},
|
||||
}),
|
||||
})
|
||||
|
||||
minetest.register_node(itemstr_dry, {
|
||||
description = readname .. " Dirt with Dry Grass",
|
||||
tiles = {"default_dry_grass.png", tilestr, tilestr .. "^default_dry_grass_side.png"},
|
||||
groups = {crumbly=3, soil=1},
|
||||
drop = itemstr_dirt,
|
||||
sounds = default.node_sound_dirt_defaults({
|
||||
footstep = {name = "default_grass_footstep", gain=0.4},
|
||||
}),
|
||||
})
|
||||
|
||||
minetest.register_node(itemstr_snow, {
|
||||
description = readname .. " Dirt with Snow",
|
||||
tiles = {"default_snow.png", tilestr, tilestr .. "^default_snow_side.png"},
|
||||
is_ground_content = true,
|
||||
groups = {crumbly=3,soil=1},
|
||||
drop = itemstr_dirt,
|
||||
sounds = default.node_sound_dirt_defaults({
|
||||
footstep = {name="default_snow_footstep", gain=0.25},
|
||||
}),
|
||||
})
|
||||
|
||||
|
||||
|
||||
if false then
|
||||
minetest.register_abm({
|
||||
nodenames = {itemstr_dirt},
|
||||
interval = 2,
|
||||
chance = 200,
|
||||
action = function(pos, node)
|
||||
local above = {x=pos.x, y=pos.y+1, z=pos.z}
|
||||
local name = minetest.get_node(above).name
|
||||
local nodedef = minetest.registered_nodes[name]
|
||||
if nodedef and (nodedef.sunlight_propagates or nodedef.paramtype == "light")
|
||||
and nodedef.liquidtype == "none"
|
||||
and (minetest.get_node_light(above) or 0) >= 13 then
|
||||
if name == "default:snow" or name == "default:snowblock" or (lib_ecology.test_snow and lib_ecology.test_snow({x=pos.x, y=pos.y+1, z=pos.z})) then
|
||||
minetest.set_node(pos, {name = itemstr_snow})
|
||||
elseif lib_ecology.test_dry and lib_ecology.test_dry(pos) then
|
||||
minetest.set_node(pos, {name = itemstr_dry})
|
||||
else
|
||||
minetest.set_node(pos, {name = itemstr_lawn})
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {itemstr_lawn, itemstr_dry},
|
||||
interval = 2,
|
||||
chance = 20,
|
||||
action = function(pos, node)
|
||||
local above = {x=pos.x, y=pos.y+1, z=pos.z}
|
||||
local name = minetest.get_node(above).name
|
||||
local nodedef = minetest.registered_nodes[name]
|
||||
if name ~= "ignore" and nodedef
|
||||
and not ((nodedef.sunlight_propagates or nodedef.paramtype == "light")
|
||||
and nodedef.liquidtype == "none") then
|
||||
minetest.set_node(pos, {name = itemstr_dirt})
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
-- 3 types of dirt :
|
||||
-- Clayey dirt is a dirt that contains clay, but is not pure clay
|
||||
register_dirts("Clayey")
|
||||
-- Idem for silty dirt that contains silt without beeing pure silt
|
||||
register_dirts("Silty")
|
||||
-- And sandy dirt
|
||||
register_dirts("Sandy")
|
|
@ -0,0 +1,197 @@
|
|||
--------------------------------------------------------------
|
||||
-- Adapted from the work by Mossmanikin and VanessaE
|
||||
-- License (everything): WTFPL
|
||||
--------------------------------------------------------------
|
||||
|
||||
-----------
|
||||
-- Ferns --
|
||||
-----------
|
||||
|
||||
-- This is a simpler implementation of ferns as regular decorations.
|
||||
|
||||
|
||||
-- Check that the original ferns mod is not loaded.
|
||||
abstract_ferns = nil
|
||||
if not abstract_ferns then
|
||||
local max_s = 3
|
||||
local images = { "ferns_fern.png", "ferns_fern_mid.png", "ferns_fern_big.png" }
|
||||
local sizes = {1,2,2.2}
|
||||
|
||||
for s = 1,max_s do
|
||||
local fern_name = "lib_ecology:fern_"..string.format("%02d", s)
|
||||
minetest.register_node(fern_name, {
|
||||
description = "Lady-fern (Athyrium)",
|
||||
inventory_image = "ferns_fern.png",
|
||||
drawtype = "plantlike",
|
||||
visual_scale = sizes[s],
|
||||
paramtype = "light",
|
||||
tiles = { images[s] },
|
||||
walkable = false,
|
||||
buildable_to = true,
|
||||
groups = {snappy=3,flammable=2,attached_node=1,not_in_creative_inventory=1},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
|
||||
},
|
||||
drop = "lib_ecology:fern_01",
|
||||
})
|
||||
|
||||
minetest.register_decoration({
|
||||
deco_type = "simple",
|
||||
decoration = fern_name,
|
||||
sidelen = 80,
|
||||
place_on = {"default:dirt_with_grass", "default:mossycobble", "default:sand", "default:jungletree", "dirt_with_rainforest_litter"},
|
||||
fill_ratio = (max_s-s+1)/400,
|
||||
biomes = {"lib_ecology_taiga", "lib_ecology_coniferous_forest", "lib_ecology_deciduous_forest", "lib_ecology_savanna", "lib_ecology_savanna_swamp", "lib_ecology_rainforest", "lib_ecology_rainforest_swamp", "lib_ecology_desertstone_grassland", },
|
||||
})
|
||||
|
||||
-- Supposedly ferns sometimes signal the presence of ores.
|
||||
-- I could try to plant them near ore, but why bother?
|
||||
-- Just place it under them occasionally.
|
||||
minetest.register_decoration({
|
||||
deco_type = "schematic",
|
||||
schematic = {size={x=1,y=5,z=1},
|
||||
data={{name="default:stone_with_iron", param1=255},
|
||||
{name="default:dirt", param1=255},
|
||||
{name="default:dirt_with_grass", param1=255},
|
||||
{name=fern_name, param1=255},
|
||||
{name="air", param1=255}, }, },
|
||||
flags = "place_center_y, force_placement",
|
||||
sidelen = 80,
|
||||
place_on = {"default:dirt_with_grass", "default:mossycobble", "default:sand", "default:jungletree",},
|
||||
fill_ratio = (max_s-s+1)/4000,
|
||||
biomes = {"lib_ecology_taiga", "lib_ecology_coniferous_forest", "lib_ecology_deciduous_forest", "lib_ecology_savanna", "lib_ecology_savanna_swamp", "lib_ecology_rainforest", "lib_ecology_rainforest_swamp", "lib_ecology_desertstone_grassland", },
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
----------------------------
|
||||
-- HORSETAIL (EQUISETUM) --
|
||||
-- A true living fossil! --
|
||||
----------------------------
|
||||
|
||||
local node_names = {}
|
||||
|
||||
for i = 1, 4 do
|
||||
local node_name = "lib_ecology:horsetail_" .. string.format("%02d", i)
|
||||
local node_img = "ferns_horsetail_" .. string.format("%02d", i) .. ".png"
|
||||
local node_desc
|
||||
local node_on_use = nil
|
||||
local node_drop = "lib_ecology:horsetail_04"
|
||||
|
||||
if i == 1 then
|
||||
node_desc = "Young Horsetail (Equisetum)"
|
||||
node_on_use = minetest.item_eat(1) -- young ones edible https://en.wikipedia.org/wiki/Equisetum
|
||||
node_drop = node_name
|
||||
else
|
||||
node_desc = "Horsetail (Equisetum)"
|
||||
end
|
||||
|
||||
node_names[i] = node_name
|
||||
|
||||
minetest.register_node(node_name, {
|
||||
description = node_desc,
|
||||
drawtype = "plantlike",
|
||||
paramtype = "light",
|
||||
tiles = { node_img },
|
||||
inventory_image = node_img,
|
||||
walkable = false,
|
||||
buildable_to = true,
|
||||
groups = {snappy=3,flammable=2,attached_node=1,horsetail=1},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
|
||||
},
|
||||
on_use = node_on_use,
|
||||
drop = node_drop,
|
||||
})
|
||||
|
||||
minetest.register_decoration({
|
||||
deco_type = "simple",
|
||||
decoration = node_name,
|
||||
sidelen = 80,
|
||||
place_on = {"default:dirt_with_grass", "default:mossycobble", "default:sand", "default:jungletree", "default:gravel",},
|
||||
fill_ratio = 0.003,
|
||||
biomes = {"lib_ecology_taiga", "lib_ecology_coniferous_forest", "lib_ecology_deciduous_forest", "lib_ecology_savanna", "lib_ecology_savanna_swamp", "lib_ecology_rainforest", "lib_ecology_rainforest_swamp", "lib_ecology_desertstone_grassland", },
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
----------------------------------
|
||||
-- Ferns - Crafting
|
||||
----------------------------------
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "lib_ecology:fiddlehead 3",
|
||||
recipe = {"lib_ecology:fern_01"},
|
||||
replacements = {
|
||||
{"lib_ecology:fern_01", "lib_ecology:ferntuber"}
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "lib_ecology:fiddlehead 3",
|
||||
recipe = {"lib_ecology:tree_fern_leaves"},
|
||||
replacements = {
|
||||
{"lib_ecology:tree_fern_leaves", "lib_ecology:sapling_tree_fern"}
|
||||
},
|
||||
})
|
||||
|
||||
-----------------------
|
||||
-- FIDDLEHEAD
|
||||
-----------------------
|
||||
minetest.register_craftitem("lib_ecology:fiddlehead", {
|
||||
description = "Fiddlehead",
|
||||
inventory_image = "ferns_fiddlehead.png",
|
||||
on_use = minetest.item_eat(-1), -- slightly poisonous when raw
|
||||
})
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "lib_ecology:fiddlehead_roasted",
|
||||
recipe = "lib_ecology:fiddlehead",
|
||||
cooktime = 1,
|
||||
})
|
||||
minetest.register_craftitem("lib_ecology:fiddlehead_roasted", {
|
||||
description = "Roasted Fiddlehead",
|
||||
inventory_image = "ferns_fiddlehead_roasted.png",
|
||||
on_use = minetest.item_eat(1), -- edible when cooked
|
||||
})
|
||||
|
||||
------------------
|
||||
-- FERN TUBER
|
||||
------------------
|
||||
minetest.register_alias("archaeplantae:ferntuber", "lib_ecology:ferntuber")
|
||||
|
||||
minetest.register_craftitem("lib_ecology:ferntuber", {
|
||||
description = "Fern Tuber",
|
||||
inventory_image = "ferns_ferntuber.png",
|
||||
})
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "lib_ecology:ferntuber_roasted",
|
||||
recipe = "lib_ecology:ferntuber",
|
||||
cooktime = 3,
|
||||
})
|
||||
|
||||
minetest.register_alias("archaeplantae:ferntuber_roasted", "lib_ecology:ferntuber_roasted")
|
||||
|
||||
minetest.register_craftitem("lib_ecology:ferntuber_roasted", {
|
||||
description = "Roasted Fern Tuber",
|
||||
inventory_image = "ferns_ferntuber_roasted.png",
|
||||
on_use = minetest.item_eat(3),
|
||||
})
|
||||
|
||||
--------------------------
|
||||
-- HORSETAIL (EQUISETUM)
|
||||
-- --> GREEN DYE https://en.wikipedia.org/wiki/Equisetum
|
||||
--------------------------
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "dye:green",
|
||||
recipe = {"group:horsetail"},
|
||||
})
|
||||
end
|
|
@ -0,0 +1,194 @@
|
|||
--------------------------------------------------------------
|
||||
-- Adapted from the work by Mossmanikin and VanessaE
|
||||
-- License (everything): WTFPL
|
||||
--------------------------------------------------------------
|
||||
|
||||
-----------------
|
||||
-- Giant Ferns --
|
||||
-----------------
|
||||
|
||||
minetest.register_node("lib_ecology:tree_fern_leaves_giant", {
|
||||
description = "Tree Fern Crown (Dicksonia)",
|
||||
drawtype = "plantlike",
|
||||
visual_scale = math.sqrt(8),
|
||||
wield_scale = {x=0.175, y=0.175, z=0.175},
|
||||
paramtype = "light",
|
||||
tiles = {"ferns_fern_tree_giant.png"},
|
||||
inventory_image = "ferns_fern_tree.png",
|
||||
walkable = false,
|
||||
groups = {
|
||||
snappy=3,
|
||||
flammable=2,
|
||||
attached_node=1,
|
||||
not_in_creative_inventory=1
|
||||
},
|
||||
drop = {
|
||||
max_items = 2,
|
||||
items = {
|
||||
{
|
||||
-- occasionally, drop a second sapling instead of leaves
|
||||
-- (extra saplings can also be obtained by replanting and
|
||||
-- reharvesting leaves)
|
||||
items = {"lib_ecology:sapling_giant_tree_fern"},
|
||||
rarity = 10,
|
||||
},
|
||||
{
|
||||
items = {"lib_ecology:sapling_giant_tree_fern"},
|
||||
},
|
||||
{
|
||||
items = {"lib_ecology:tree_fern_leaves_giant"},
|
||||
}
|
||||
}
|
||||
},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-7/16, -1/2, -7/16, 7/16, 0, 7/16},
|
||||
},
|
||||
})
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- GIANT TREE FERN LEAVE PART
|
||||
-----------------------------------------------------------------------------------------------
|
||||
minetest.register_node("lib_ecology:tree_fern_leaf_big", {
|
||||
description = "Giant Tree Fern Leaf",
|
||||
drawtype = "raillike",
|
||||
paramtype = "light",
|
||||
tiles = {
|
||||
"ferns_tree_fern_leave_big.png",
|
||||
},
|
||||
walkable = false,
|
||||
groups = {
|
||||
snappy=3,
|
||||
flammable=2,
|
||||
attached_node=1,
|
||||
not_in_creative_inventory=1
|
||||
},
|
||||
drop = "",
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
})
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- GIANT TREE FERN LEAVE END
|
||||
-----------------------------------------------------------------------------------------------
|
||||
minetest.register_node("lib_ecology:tree_fern_leaf_big_end", {
|
||||
description = "Giant Tree Fern Leaf End",
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
tiles = { "ferns_tree_fern_leave_big_end.png" },
|
||||
walkable = false,
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
-- {left, bottom, front, right, top, back }
|
||||
fixed = {-1/2, -1/2, 1/2, 1/2, 33/64, 1/2},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, 1/2, 1/2, 33/64, 1/2},
|
||||
},
|
||||
groups = {
|
||||
snappy=3,
|
||||
flammable=2,
|
||||
attached_node=1,
|
||||
not_in_creative_inventory=1
|
||||
},
|
||||
drop = "",
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
})
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- GIANT TREE FERN TRUNK TOP
|
||||
-----------------------------------------------------------------------------------------------
|
||||
minetest.register_node("lib_ecology:fern_trunk_big_top", {
|
||||
description = "Giant Fern Trunk",
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
tiles = {
|
||||
"ferns_fern_trunk_big_top.png^ferns_tree_fern_leave_big_cross.png",
|
||||
"ferns_fern_trunk_big_top.png^ferns_tree_fern_leave_big_cross.png",
|
||||
"ferns_fern_trunk_big.png"
|
||||
},
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
-- {left, bottom, front, right, top, back }
|
||||
fixed = {
|
||||
{-1/2, 33/64, -1/2, 1/2, 33/64, 1/2},
|
||||
{-1/4, -1/2, -1/4, 1/4, 1/2, 1/4},
|
||||
}
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/4, -1/2, -1/4, 1/4, 1/2, 1/4},
|
||||
},
|
||||
groups = {
|
||||
tree=1,
|
||||
choppy=2,
|
||||
oddly_breakable_by_hand=2,
|
||||
flammable=3,
|
||||
wood=1,
|
||||
not_in_creative_inventory=1,
|
||||
leafdecay=3 -- to support vines
|
||||
},
|
||||
drop = "lib_ecology:fern_trunk_big",
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- GIANT TREE FERN TRUNK
|
||||
-----------------------------------------------------------------------------------------------
|
||||
minetest.register_node("lib_ecology:fern_trunk_big", {
|
||||
description = "Giant Fern Trunk",
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
tiles = {
|
||||
"ferns_fern_trunk_big_top.png",
|
||||
"ferns_fern_trunk_big_top.png",
|
||||
"ferns_fern_trunk_big.png"
|
||||
},
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/4, -1/2, -1/4, 1/4, 1/2, 1/4},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/4, -1/2, -1/4, 1/4, 1/2, 1/4},
|
||||
},
|
||||
groups = {tree=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
after_destruct = function(pos,oldnode)
|
||||
local node = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z})
|
||||
if node.name == "lib_ecology:fern_trunk_big" or node.name == "lib_ecology:fern_trunk_big_top" then
|
||||
minetest.dig_node({x=pos.x,y=pos.y+1,z=pos.z})
|
||||
minetest.add_item(pos,"lib_ecology:fern_trunk_big")
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- GIANT TREE FERN SAPLING
|
||||
-----------------------------------------------------------------------------------------------
|
||||
minetest.register_node("lib_ecology:sapling_giant_tree_fern", {
|
||||
description = "Giant Tree Fern Sapling",
|
||||
drawtype = "plantlike",
|
||||
paramtype = "light",
|
||||
tiles = {"ferns_sapling_tree_fern_giant.png"},
|
||||
inventory_image = "ferns_sapling_tree_fern_giant.png",
|
||||
walkable = false,
|
||||
groups = {snappy=3,flammable=2,flora=1,attached_node=1},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-7/16, -1/2, -7/16, 7/16, 0, 7/16},
|
||||
},
|
||||
})
|
||||
|
||||
-- abm
|
||||
minetest.register_abm({
|
||||
nodenames = "lib_ecology:sapling_giant_tree_fern",
|
||||
interval = 1000,
|
||||
chance = 4,
|
||||
action = function(pos, node, _, _)
|
||||
abstract_ferns.grow_giant_tree_fern({x = pos.x, y = pos.y-1, z = pos.z})
|
||||
end
|
||||
})
|
||||
|
|
@ -0,0 +1,356 @@
|
|||
-------------------
|
||||
-- Fungal Tree --
|
||||
-------------------
|
||||
|
||||
local light_max = 9
|
||||
|
||||
local colors = {"^[colorize:#FF00FF:60", "", "^[colorize:#0000FF:60", "^[colorize:#FF4500:80"}
|
||||
lib_ecology.fungal_tree_leaves = {}
|
||||
|
||||
-- all leaves
|
||||
function lib_ecology.make_fungal_tree(data, area, pos, height, leaves, fruit)
|
||||
for y = 0, height do
|
||||
local radius = 1
|
||||
if y > 1 and y < height - 2 then
|
||||
radius = 2
|
||||
end
|
||||
local force_x = math.random(1,3) - 2
|
||||
local force_y = math.random(1,3) - 2
|
||||
for z = -radius,radius do
|
||||
for x = -radius,radius do
|
||||
local sr = math.random(1,27)
|
||||
local i = pos + z*area.zstride + y*area.ystride + x
|
||||
if force_x == x and force_y == y then
|
||||
data[i] = leaves
|
||||
elseif sr == 1 then
|
||||
data[i] = fruit
|
||||
elseif sr < 14 then
|
||||
data[i] = leaves
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- multicolored growths
|
||||
local count = 0
|
||||
for _, color in pairs(colors) do
|
||||
count = count + 1
|
||||
local name = "lib_ecology:fungal_tree_leaves_"..count
|
||||
lib_ecology.fungal_tree_leaves[#lib_ecology.fungal_tree_leaves+1] = name
|
||||
|
||||
minetest.register_node(name, {
|
||||
description = "Fungal tree growths",
|
||||
drawtype = "allfaces_optional",
|
||||
waving = 1,
|
||||
visual_scale = 1.3,
|
||||
tiles = {"valc_fungal_tree_leaves.png"..color},
|
||||
paramtype = "light",
|
||||
is_ground_content = false,
|
||||
groups = {snappy=3, flammable=3, leaves=1, plant=1},
|
||||
drop = {
|
||||
max_items = 1,
|
||||
items = {
|
||||
--{items = {"lib_ecology:"..tree.name.."_sapling"}, rarity = tree.drop_rarity },
|
||||
{items = {name} }
|
||||
}
|
||||
},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
after_place_node = default.after_place_leaves,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:stick",
|
||||
recipe = {
|
||||
{name}
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
local leaves_and_air = table.copy(lib_ecology.fungal_tree_leaves)
|
||||
leaves_and_air[#leaves_and_air+1] = "air"
|
||||
local good_stone = {"lib_ecology:stone_with_lichen", "lib_ecology:stone_with_algae"}
|
||||
|
||||
local function find_ground(pos)
|
||||
for y1 = 1, 16 do
|
||||
local node = minetest.get_node_or_nil({x=pos.x, y=pos.y-y1, z=pos.z})
|
||||
if node then
|
||||
if minetest.get_item_group(node.name, "soil") ~= 0 or
|
||||
table.contains(good_stone, node.name) then
|
||||
return y1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return 1000
|
||||
end
|
||||
|
||||
|
||||
-- fungal spread
|
||||
minetest.register_abm({
|
||||
nodenames = lib_ecology.fungal_tree_leaves,
|
||||
interval = 2 * lib_ecology.time_factor,
|
||||
chance = 10,
|
||||
action = function(pos, node)
|
||||
if minetest.get_node_light(pos, nil) == 15 then
|
||||
minetest.remove_node(pos)
|
||||
return
|
||||
end
|
||||
if find_ground(pos) > 16 then
|
||||
minetest.remove_node(pos)
|
||||
return
|
||||
end
|
||||
|
||||
local grow_pos = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||
local grow_node = minetest.get_node_or_nil(grow_pos)
|
||||
if grow_node and grow_node.name == "air" then
|
||||
minetest.set_node(grow_pos, {name = node.name})
|
||||
return
|
||||
end
|
||||
if math.random(1,3) ~= 1 then
|
||||
return
|
||||
end
|
||||
|
||||
local foreign = {}
|
||||
for _, i in pairs(lib_ecology.fungal_tree_leaves) do
|
||||
if i ~= node.name then
|
||||
foreign[#foreign+1] = i
|
||||
end
|
||||
end
|
||||
local pos1, count = minetest.find_nodes_in_area(vector.subtract(pos, 3), vector.add(pos, 3), foreign)
|
||||
if #pos1 > 0 then
|
||||
minetest.set_node(pos1[math.random(1,#pos1)], {name="air"})
|
||||
return
|
||||
end
|
||||
|
||||
if math.random(1,201) == 1 then
|
||||
local new = lib_ecology.fungal_tree_leaves[math.random(1,#lib_ecology.fungal_tree_leaves)]
|
||||
local pos1, count = minetest.find_nodes_in_area({x=pos.x-8, y=pos.y-16, z=pos.z-8}, {x=pos.x+8, y=pos.y+16, z=pos.z+8}, node.name)
|
||||
for _, p in pairs(pos1) do
|
||||
minetest.set_node(p, {name=new})
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
grow_pos = {x = pos.x + math.random(-1,1), y = pos.y + math.random(-1,1), z = pos.z + math.random(-1,1)}
|
||||
grow_node = minetest.get_node_or_nil(grow_pos)
|
||||
--if math.random(1,2) == 1 then
|
||||
minetest.set_node(pos, {name = "air"})
|
||||
--end
|
||||
if not grow_node or not table.contains(leaves_and_air, grow_node.name) or find_ground(grow_pos) > 16 then
|
||||
return
|
||||
end
|
||||
if minetest.get_node_light(grow_pos, nil) <= light_max then
|
||||
minetest.set_node(pos, {name = "air"})
|
||||
if math.random(1,27) == 1 then
|
||||
minetest.set_node(grow_pos, {name = "lib_ecology:fungal_tree_fruit"})
|
||||
else
|
||||
minetest.set_node(grow_pos, {name = node.name})
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
-- Fill a list with data for content IDs, after all nodes are registered
|
||||
local cid_data = {}
|
||||
minetest.after(0, function()
|
||||
for name, def in pairs(minetest.registered_nodes) do
|
||||
cid_data[minetest.get_content_id(name)] = {
|
||||
name = name,
|
||||
--drops = def.drops,
|
||||
flammable = def.groups.flammable,
|
||||
choppy = def.groups.choppy,
|
||||
fleshy = def.groups.fleshy,
|
||||
snappy = def.groups.snappy,
|
||||
on_blast = def.on_blast,
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
local function add_effects(pos, radius)
|
||||
minetest.add_particlespawner({
|
||||
amount = 128,
|
||||
time = 1,
|
||||
minpos = vector.subtract(pos, radius / 2),
|
||||
maxpos = vector.add(pos, radius / 2),
|
||||
minvel = {x=-20, y=-20, z=-20},
|
||||
maxvel = {x=20, y=20, z=20},
|
||||
minacc = vector.new(),
|
||||
maxacc = vector.new(),
|
||||
minexptime = 1,
|
||||
maxexptime = 3,
|
||||
minsize = 8,
|
||||
maxsize = 16,
|
||||
texture = "tnt_smoke.png",
|
||||
})
|
||||
end
|
||||
|
||||
local function destroy(pos, cid)
|
||||
if minetest.is_protected(pos, "") then
|
||||
return
|
||||
end
|
||||
local def = cid_data[cid]
|
||||
if def and def.on_blast then
|
||||
def.on_blast(vector.new(pos), 1)
|
||||
return
|
||||
end
|
||||
if def.snappy == nil and def.choppy == nil and def.fleshy == nil and def.name ~= "fire:basic_flame" then
|
||||
return
|
||||
end
|
||||
local new = "air"
|
||||
--if math.random(1,2) == 1 then
|
||||
if true then
|
||||
local node_under = minetest.get_node_or_nil({x = pos.x,
|
||||
y = pos.y - 1, z = pos.z})
|
||||
if node_under and node_under.name ~= "air" then
|
||||
--new = node.name
|
||||
end
|
||||
end
|
||||
minetest.set_node(pos, {name=new})
|
||||
end
|
||||
|
||||
local function explode(pos, radius)
|
||||
local pos = vector.round(pos)
|
||||
local vm = VoxelManip()
|
||||
local p1 = vector.subtract(pos, radius)
|
||||
local p2 = vector.add(pos, radius)
|
||||
local minp, maxp = vm:read_from_map(p1, p2)
|
||||
local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp})
|
||||
local data = vm:get_data()
|
||||
|
||||
local drops = {}
|
||||
local p = {}
|
||||
|
||||
local c_air = minetest.get_content_id("air")
|
||||
|
||||
for z = -radius, radius do
|
||||
for y = -radius, 4*radius do
|
||||
local vi = a:index(pos.x + (-radius), pos.y + y, pos.z + z)
|
||||
for x = -radius, radius do
|
||||
if (x * x) + (y * y / 4) + (z * z) <=
|
||||
(radius * radius) + math.random(-radius, radius) then
|
||||
local cid = data[vi]
|
||||
p.x = pos.x + x
|
||||
p.y = pos.y + y
|
||||
p.z = pos.z + z
|
||||
if cid ~= c_air then
|
||||
destroy(p, cid)
|
||||
end
|
||||
end
|
||||
vi = vi + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function calc_velocity(pos1, pos2, old_vel, power)
|
||||
local vel = vector.direction(pos1, pos2)
|
||||
vel = vector.normalize(vel)
|
||||
vel = vector.multiply(vel, power)
|
||||
|
||||
-- Divide by distance
|
||||
local dist = vector.distance(pos1, pos2)
|
||||
dist = math.max(dist, 1)
|
||||
vel = vector.divide(vel, dist)
|
||||
|
||||
-- Add old velocity
|
||||
vel = vector.add(vel, old_vel)
|
||||
return vel
|
||||
end
|
||||
|
||||
local function entity_physics(pos, radius)
|
||||
-- Make the damage radius larger than the destruction radius
|
||||
radius = radius * 2
|
||||
local objs = minetest.get_objects_inside_radius(pos, radius)
|
||||
for _, obj in pairs(objs) do
|
||||
local obj_pos = obj:getpos()
|
||||
local obj_vel = obj:getvelocity()
|
||||
local dist = math.max(1, vector.distance(pos, obj_pos))
|
||||
|
||||
if obj_vel ~= nil then
|
||||
obj:setvelocity(calc_velocity(pos, obj_pos,
|
||||
obj_vel, radius * 10))
|
||||
end
|
||||
|
||||
local damage = (4 / dist) * radius
|
||||
obj:set_hp(obj:get_hp() - damage)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function boom(pos)
|
||||
if not pos then
|
||||
return
|
||||
end
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
if not node then
|
||||
return
|
||||
end
|
||||
|
||||
minetest.sound_play("tnt_explode", {pos=pos, gain=1.5, max_hear_distance=2*64})
|
||||
local radius = 5
|
||||
minetest.set_node(pos, {name="air"})
|
||||
explode(pos, radius)
|
||||
entity_physics(pos, radius)
|
||||
add_effects(pos, radius)
|
||||
end
|
||||
|
||||
local function burn(pos)
|
||||
minetest.get_node_timer(pos):start(1)
|
||||
end
|
||||
|
||||
|
||||
-- Exploding fruit
|
||||
minetest.register_abm({
|
||||
nodenames = {"lib_ecology:fungal_tree_fruit"},
|
||||
interval = 3 * lib_ecology.time_factor,
|
||||
chance = 20,
|
||||
action = function(pos, node)
|
||||
local pos1, count = minetest.find_nodes_in_area(vector.subtract(pos, 1), vector.add(pos, 1), {"fire:basic_flame"})
|
||||
if #pos1 > 0 then
|
||||
boom(pos)
|
||||
return
|
||||
end
|
||||
|
||||
local pos1, count = minetest.find_nodes_in_area(vector.subtract(pos, 1), vector.add(pos, 1), lib_ecology.fungal_tree_leaves)
|
||||
if #pos1 < 3 then
|
||||
minetest.set_node(pos, {name="air"})
|
||||
return
|
||||
end
|
||||
|
||||
local g = find_ground(pos)
|
||||
if g > 4 and g < 17 then
|
||||
if math.random(1,17 - g) == 1 then
|
||||
boom(pos)
|
||||
end
|
||||
elseif math.random(1,2) == 1 then
|
||||
minetest.set_node(pos, {name="air"})
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
minetest.register_node("lib_ecology:fungal_tree_fruit", {
|
||||
description = "Fungal tree fruit",
|
||||
drawtype = "plantlike",
|
||||
visual_scale = 0.75,
|
||||
tiles = {"valc_fungal_tree_fruit.png"},
|
||||
--inventory_image = ".png",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
light_source = 6,
|
||||
walkable = false,
|
||||
is_ground_content = false,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.2, -0.5, -0.2, 0.2, 0, 0.2}
|
||||
},
|
||||
groups = {fleshy = 3, dig_immediate = 3, flammable = 2},
|
||||
--on_use = minetest.item_eat(2),
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
on_timer = boom,
|
||||
on_punch = boom,
|
||||
})
|
||||
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
|
||||
--
|
||||
|
||||
local newnode = lib_ecology.clone_node("default:wood")
|
||||
newnode.tiles = {"default_wood.png^[colorize:#9F0000:150"}
|
||||
newnode.drop = "default:wood",
|
||||
minetest.register_node("lib_ecology:wood_red", newnode)
|
||||
newnode = lib_ecology.clone_node("default:wood")
|
||||
newnode.tiles = {"default_wood.png^[colorize:#009F00:150"}
|
||||
newnode.drop = "default:wood",
|
||||
minetest.register_node("lib_ecology:wood_green", newnode)
|
||||
newnode = lib_ecology.clone_node("default:wood")
|
||||
newnode.tiles = {"default_wood.png^[colorize:#00009F:150"}
|
||||
newnode.drop = "default:wood",
|
||||
minetest.register_node("lib_ecology:wood_blue", newnode)
|
||||
|
||||
local max_h = 8
|
||||
|
||||
function lib_ecology.generate_test_house_schematic(size, floor, walls, ceiling)
|
||||
local offset = {x=0,y=0,z=0}
|
||||
local width = size.x + 2 * offset.x
|
||||
local height = size.y + offset.y
|
||||
local depth = size.z + 2 * offset.z + 1
|
||||
local s = lib_ecology.schematic_array(width, height, depth)
|
||||
|
||||
for z = 0,depth-1 do
|
||||
for y = 0,height-1 do
|
||||
for x = 0,width-1 do
|
||||
local i = z*width*height + y*width + x + 1
|
||||
local c = math.floor(width/2)
|
||||
local p = math.min(height - 1, math.max(4, height - math.abs(c - x)))
|
||||
|
||||
local p_prev = math.min(height - 1, math.max(4, height - math.abs(c - (x - 1))))
|
||||
if x == 0 then
|
||||
p_prev = 0
|
||||
end
|
||||
|
||||
local p_next = math.min(height - 1, math.max(4, height - math.abs(c - (x + 1))))
|
||||
if x == width-1 then
|
||||
p_next = 0
|
||||
end
|
||||
|
||||
if y <= offset.y then
|
||||
if floor == "default:dirt" and z == 0 then
|
||||
s.data[i].name = "default:dirt_with_grass"
|
||||
else
|
||||
s.data[i].name = floor
|
||||
end
|
||||
s.data[i].param1 = 255
|
||||
s.data[i].force_place = true
|
||||
elseif (x == offset.x or x == width - offset.x - 1 or z == offset.z + 1 or z == depth - offset.z - 1) and y >= offset.y and y < p and z >= offset.z + 1 and x >= offset.x and x <= width - offset.x - 1 and z <= depth - offset.z - 1 then
|
||||
if x == c and y == offset.y + 1 and z == offset.z + 1 then
|
||||
s.data[i].name = "doors:door_wood_b"
|
||||
s.data[i].param1 = 255
|
||||
s.data[i].param2 = 0
|
||||
s.data[i].force_place = true
|
||||
elseif x == c and y == offset.y + 2 and z == offset.z + 1 then
|
||||
s.data[i].name = "air"
|
||||
s.data[i].param1 = 255
|
||||
s.data[i].param2 = 0
|
||||
s.data[i].force_place = true
|
||||
elseif y == offset.y + 2 and ((x > offset.x and x < width - offset.x - 1) or (z > offset.z + 1 and z < depth - offset.z - 1)) then
|
||||
s.data[i].name = walls
|
||||
s.data[i].param1 = 150
|
||||
s.data[i].force_place = true
|
||||
else
|
||||
s.data[i].name = walls
|
||||
s.data[i].param1 = 255
|
||||
s.data[i].force_place = true
|
||||
end
|
||||
elseif y == p and z >= offset.z + 1 and x >= offset.x and x <= width - offset.x - 1 and z <= depth - offset.z - 1 then
|
||||
if ((x < c and p ~= p_prev) or (x > c and p ~= p_next)) and ceiling == "farming:straw" then
|
||||
s.data[i].name = "stairs:stair_straw"
|
||||
if x > c then
|
||||
s.data[i].param2 = 3
|
||||
else
|
||||
s.data[i].param2 = 1
|
||||
end
|
||||
else
|
||||
s.data[i].name = ceiling
|
||||
end
|
||||
s.data[i].param1 = 255
|
||||
s.data[i].force_place = true
|
||||
elseif z == offset.z and x == c and y == offset.y + 3 then
|
||||
s.data[i].name = "default:torch"
|
||||
s.data[i].param1 = 125
|
||||
s.data[i].param2 = 4
|
||||
s.data[i].force_place = true
|
||||
else
|
||||
s.data[i].name = "air"
|
||||
s.data[i].param1 = 255
|
||||
s.data[i].force_place = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return s
|
||||
end
|
||||
|
||||
|
||||
lib_ecology.schematics.houses = {}
|
||||
do
|
||||
local colors = {"red", "green", "blue"}
|
||||
for color = 1,#colors do
|
||||
for h = 4,max_h do
|
||||
local schem = lib_ecology.generate_test_house_schematic({x=h,y=h,z=h}, "default:dirt", "lib_ecology:wood_"..colors[color], "farming:straw")
|
||||
|
||||
push(lib_ecology.schematics.houses, schem)
|
||||
|
||||
minetest.register_decoration({
|
||||
deco_type = "schematic",
|
||||
sidelen = 80,
|
||||
place_on = {"group:soil"},
|
||||
-- noise_params = {
|
||||
-- offset = -0.9,
|
||||
-- scale = 1.0,
|
||||
-- spread = {x = 400, y = 400, z = 400},
|
||||
-- seed = 37248,
|
||||
-- octaves = 5,
|
||||
-- persist = 5.0
|
||||
-- },
|
||||
fill_ratio = 1/500000,
|
||||
biomes = {"lib_ecology_sandstone_grassland", "lib_ecology_tundra", "lib_ecology_stone_grassland", "lib_ecology_taiga", "lib_ecology_coniferous_forest", "lib_ecology_deciduous_forest", "lib_ecology_savanna", "lib_ecology_savanna_swamp", "lib_ecology_rainforest", "lib_ecology_rainforest_swamp", "lib_ecology_desertstone_grassland",},
|
||||
schematic = schem,
|
||||
flags = "place_center_x, place_center_z, force_placement",
|
||||
rotation = "random",
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
lib_ecology.house_replacements = {["default:leaves"] = "air", ["lib_ecology:leaves2"] = "air", ["lib_ecology:leaves3"] = "air", ["lib_ecology:leaves4"] = "air", ["lib_ecology:leaves5"] = "air", ["default:pine_needles"] = "air", ["lib_ecology:pine_needles2"] = "air", ["lib_ecology:pine_needles3"] = "air", ["lib_ecology:pine_needles4"] = "air", }
|
|
@ -0,0 +1,128 @@
|
|||
------------------
|
||||
-- Jungle Trees --
|
||||
------------------
|
||||
|
||||
-- Create different colored leaves with the same properties.
|
||||
|
||||
newnode = lib_ecology.clone_node("default:jungleleaves")
|
||||
newnode.tiles = {"default_jungleleaves.png^[colorize:#FF0000:10"}
|
||||
minetest.register_node("lib_ecology:jungleleaves2", newnode)
|
||||
newnode.tiles = {"default_jungleleaves.png^[colorize:#FFFF00:30"}
|
||||
minetest.register_node("lib_ecology:jungleleaves3", newnode)
|
||||
|
||||
|
||||
-- Create a schematic for a jungle tree.
|
||||
function lib_ecology.generate_jungle_tree_schematic(trunk_height, trunk, leaf)
|
||||
local height = trunk_height * 2 + 1
|
||||
local radius = 6
|
||||
local width = 2 * radius + 1
|
||||
local trunk_top = height - 4
|
||||
|
||||
local s = lib_ecology.schematic_array(width, height, width)
|
||||
|
||||
-- roots, trunk, and extra leaves
|
||||
for z = -1,1 do
|
||||
for y = 1,trunk_top do
|
||||
for x = -1,1 do
|
||||
local i = (z+radius)*width*height + y*width + (x+radius) + 1
|
||||
if x == 0 and z == 0 then
|
||||
s.data[i].name = trunk
|
||||
s.data[i].param1 = 255
|
||||
s.data[i].force_place = true
|
||||
elseif (x == 0 or z == 0) and y < 3 then
|
||||
s.data[i].name = trunk
|
||||
s.data[i].param1 = 255
|
||||
s.data[i].force_place = true
|
||||
elseif y > 3 then
|
||||
s.data[i].name = leaf
|
||||
s.data[i].param1 = 50
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- canopies
|
||||
for y = 1,trunk_top+2 do
|
||||
if y > trunk_height and (y == trunk_top or math.random(1,height - y) == 1) then
|
||||
local x, z = 0, 0
|
||||
while x == 0 and z == 0 do
|
||||
x = math.random(-1,1) * 2
|
||||
z = math.random(-1,1) * 2
|
||||
end
|
||||
for j = -1,1,2 do
|
||||
local i = (j*z + radius)*width*height + y*width + (j*x + radius) + 1
|
||||
s.data[i].name = trunk
|
||||
s.data[i].param1 = 255
|
||||
s.data[i].force_place = true
|
||||
lib_ecology.generate_canopy(s, leaf, {x=j*x, y=y, z=j*z})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return s
|
||||
end
|
||||
|
||||
-- Create a canopy of leaves.
|
||||
function lib_ecology.generate_canopy(s, leaf, pos)
|
||||
local height = s.size.y
|
||||
local width = s.size.x
|
||||
local rx = math.floor(s.size.x / 2)
|
||||
local rz = math.floor(s.size.z / 2)
|
||||
local r1 = 4 -- leaf decay radius
|
||||
local probs = {255,200,150,100,75}
|
||||
|
||||
for z = -r1,r1 do
|
||||
for y = 0,1 do
|
||||
for x = -r1,r1 do
|
||||
if x+pos.x >= -rx and x+pos.x <= rx and y+pos.y >= 0 and y+pos.y < height and z+pos.z >= -rz and z+pos.z <= rz then
|
||||
local i = (z+pos.z+rz)*width*height + (y+pos.y)*width + (x+pos.x+rx) + 1
|
||||
local dist1 = math.sqrt(x^2 + y^2 + z^2)
|
||||
local dist2 = math.sqrt((x+pos.x)^2 + (z+pos.z)^2)
|
||||
if dist1 <= r1 then
|
||||
local newprob = probs[math.max(1, math.ceil(dist1))]
|
||||
if s.data[i].name == "air" then
|
||||
s.data[i].name = leaf
|
||||
s.data[i].param1 = newprob
|
||||
elseif s.data[i].name == leaf then
|
||||
s.data[i].param1 = math.max(s.data[i].param1, newprob)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- generic jungle trees
|
||||
lib_ecology.schematics.jungle_trees = {}
|
||||
leaves = {"default:jungleleaves", "lib_ecology:jungleleaves2", "lib_ecology:jungleleaves3"}
|
||||
for i = 1,#leaves do
|
||||
local max_h = 7
|
||||
for h = 5,max_h do
|
||||
local schem = lib_ecology.generate_jungle_tree_schematic(h*2, "default:jungletree", leaves[i])
|
||||
|
||||
push(lib_ecology.schematics.jungle_trees, schem)
|
||||
|
||||
minetest.register_decoration({
|
||||
deco_type = "schematic",
|
||||
sidelen = 80,
|
||||
place_on = {"default:dirt_with_rainforest_litter", "dirt_with_grass"},
|
||||
fill_ratio = (max_h-h+1)/1200,
|
||||
biomes = {"lib_ecology_rainforest", "lib_ecology_rainforest_swamp",},
|
||||
schematic = schem,
|
||||
flags = "place_center_x, place_center_z",
|
||||
y_min = 0,
|
||||
rotation = "random",
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- Place the schematic when a sapling grows.
|
||||
function default.grow_new_jungle_tree(pos, bad)
|
||||
local schem = lib_ecology.schematics.jungle_trees[math.random(1,#lib_ecology.schematics.jungle_trees)]
|
||||
local adj = {x = pos.x - math.floor(schem.size.x / 2),
|
||||
y = pos.y - 1,
|
||||
z = pos.z - math.floor(schem.size.z / 2)}
|
||||
minetest.place_schematic(adj, schem, 'random', nil, true)
|
||||
end
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
---------------------
|
||||
-- Luminous Trees --
|
||||
---------------------
|
||||
|
||||
minetest.register_node("lib_ecology:leaves_lumin", {
|
||||
description = "Leaves",
|
||||
drawtype = "allfaces_optional",
|
||||
waving = 1,
|
||||
visual_scale = 1.3,
|
||||
tiles = {"default_leaves.png^[brighten"},
|
||||
special_tiles = {"default_leaves_simple.png^[brighten"},
|
||||
paramtype = "light",
|
||||
is_ground_content = false,
|
||||
light_source = 8,
|
||||
groups = {snappy = 3, leafdecay = 4, flammable = 2, leaves = 1},
|
||||
drop = {
|
||||
max_items = 1,
|
||||
items = {
|
||||
--{
|
||||
-- -- player will get sapling with 1/20 chance
|
||||
-- items = {'default:sapling'},
|
||||
-- rarity = 20,
|
||||
--},
|
||||
{
|
||||
-- player will get leaves only if he get no saplings,
|
||||
-- this is because max_items is 1
|
||||
items = {'lib_ecology:leaves_lumin'},
|
||||
}
|
||||
}
|
||||
},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
|
||||
after_place_node = default.after_place_leaves,
|
||||
})
|
||||
|
||||
minetest.register_node("lib_ecology:lumin_tree", {
|
||||
description = "Lumin Tree",
|
||||
tiles = {
|
||||
"default_tree_top.png", "default_tree_top.png", "valc_lumin_tree.png"
|
||||
},
|
||||
paramtype = "light",
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { {-0.25, -0.5, -0.25, 0.25, 0.5, 0.25}, }
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
|
||||
on_place = minetest.rotate_node
|
||||
})
|
||||
|
||||
|
||||
function lib_ecology.generate_luminous_schematic(trunk_height_in)
|
||||
local trunk_height = trunk_height_in + 1
|
||||
local height = trunk_height + 3
|
||||
local radius = 1
|
||||
local width = 3
|
||||
local s = lib_ecology.schematic_array(width, height, width)
|
||||
|
||||
-- the main trunk
|
||||
for y = 1,trunk_height do
|
||||
local i = (0+radius)*width*height + y*width + (0+radius) + 1
|
||||
s.data[i].name = "lib_ecology:lumin_tree"
|
||||
s.data[i].param1 = 255
|
||||
s.data[i].force_place = true
|
||||
end
|
||||
|
||||
for z = -1,1 do
|
||||
for y = 3, height-1 do
|
||||
for x = -1,1 do
|
||||
local i = (z+radius)*width*height + y*width + (x+radius) + 1
|
||||
if y > height then
|
||||
s.data[i].name = "lib_ecology:leaves_lumin"
|
||||
if x == 0 and z == 0 then
|
||||
s.data[i].param1 = 255
|
||||
else
|
||||
s.data[i].param1 = 127
|
||||
end
|
||||
elseif x == 0 and z == 0 then
|
||||
s.data[i].name = "lib_ecology:leaves_lumin"
|
||||
s.data[i].param1 = 255
|
||||
elseif x ~= 0 or z ~= 0 then
|
||||
s.data[i].name = "lib_ecology:leaves_lumin"
|
||||
s.data[i].param1 = 127
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return s
|
||||
end
|
||||
|
||||
-- generic luminous trees
|
||||
lib_ecology.schematics.luminous_trees = {}
|
||||
local leaves = {"lib_ecology:leaves_lumin"}
|
||||
for i = 1,#leaves do
|
||||
local max_r = 6
|
||||
local fruit = nil
|
||||
|
||||
for r = 3,max_r do
|
||||
local schem = lib_ecology.generate_luminous_schematic(r)
|
||||
|
||||
push(lib_ecology.schematics.luminous_trees, schem)
|
||||
|
||||
minetest.register_decoration({
|
||||
deco_type = "schematic",
|
||||
sidelen = 80,
|
||||
place_on = {"group:soil"},
|
||||
y_min = 4,
|
||||
fill_ratio = (max_r-r+1)/5000,
|
||||
biomes = {"lib_ecology_coniferous_forest", "lib_ecology_deciduous_forest"},
|
||||
schematic = schem,
|
||||
flags = "place_center_x, place_center_z",
|
||||
rotation = "random",
|
||||
})
|
||||
end
|
||||
end
|
|
@ -0,0 +1,209 @@
|
|||
----------------------
|
||||
-- Flowers / Plants --
|
||||
----------------------
|
||||
|
||||
-- See textures/image-credits.txt
|
||||
|
||||
lib_ecology.water_plants = {}
|
||||
function lib_ecology.register_water_plant(desc)
|
||||
push(lib_ecology.water_plants, desc)
|
||||
end
|
||||
|
||||
|
||||
lib_ecology.plantlist = {
|
||||
{name="arrow_arum",
|
||||
desc="Arrow Arum",
|
||||
water=true,
|
||||
wave=true,
|
||||
group="plantnodye",
|
||||
},
|
||||
|
||||
{name="bird_of_paradise",
|
||||
desc="Bird of Paradise",
|
||||
light=true,
|
||||
group="flowernodye",
|
||||
},
|
||||
|
||||
{name="calla_lily",
|
||||
desc="Calla Lily",
|
||||
wave=true,
|
||||
light=true,
|
||||
group="flowerwhitedye",
|
||||
},
|
||||
|
||||
{name="gerbera",
|
||||
desc="Gerbera",
|
||||
light=true,
|
||||
group="flowerpinkdye",
|
||||
},
|
||||
|
||||
{name="hibiscus",
|
||||
desc="Hibiscus",
|
||||
wave=true,
|
||||
group="flowerwhitedye",
|
||||
},
|
||||
|
||||
{name="orchid",
|
||||
desc="Orchid",
|
||||
wave=true,
|
||||
light=true,
|
||||
group="flowerwhitedye",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
for _, plant in ipairs(lib_ecology.plantlist) do
|
||||
groups = {snappy=3,flammable=2,flora=1,attached_node=1}
|
||||
if plant.group == "flowernodye" then
|
||||
groups.flower = 1
|
||||
elseif plant.group == "flowerpinkdye" then
|
||||
groups.flower = 1
|
||||
groups.color_pink = 1
|
||||
elseif plant.group == "flowerwhitedye" then
|
||||
groups.flower = 1
|
||||
groups.color_white = 1
|
||||
end
|
||||
|
||||
minetest.register_node("lib_ecology:"..plant.name, {
|
||||
description = plant.desc,
|
||||
drawtype = "plantlike",
|
||||
tiles = {"vmg_"..plant.name..".png"},
|
||||
inventory_image = "vmg_"..plant.name..".png",
|
||||
waving = plant.wave,
|
||||
sunlight_propagates = plant.light,
|
||||
paramtype = "light",
|
||||
walkable = false,
|
||||
groups = groups,
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
|
||||
},
|
||||
})
|
||||
|
||||
if plant.water then
|
||||
local def = {
|
||||
description = plant.desc,
|
||||
drawtype = "nodebox",
|
||||
node_box = {type='fixed', fixed={{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, {-0.5, 0.5, -0.001, 0.5, 1.5, 0.001}, {-0.001, 0.5, -0.5, 0.001, 1.5, 0.5}}},
|
||||
drop = {max_items=2, items={{items={"lib_ecology:"..plant.name}, rarity=1}, {items={"default:sand"}, rarity=1}}},
|
||||
tiles = { "default_sand.png", "vmg_"..plant.name..".png",},
|
||||
--tiles = { "default_dirt.png", "vmg_"..plant.name..".png",},
|
||||
sunlight_propagates = plant.light,
|
||||
--light_source = 14,
|
||||
paramtype = "light",
|
||||
walkable = false,
|
||||
groups = groups,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, 0.5, -0.5, 0.5, 11/16, 0.5},
|
||||
},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
}
|
||||
minetest.register_node("lib_ecology:"..plant.name.."_water_sand", def)
|
||||
def2 = table.copy(def)
|
||||
def2.tiles = { "default_dirt.png", "vmg_"..plant.name..".png",}
|
||||
def2.drop = {max_items=2, items={{items={"lib_ecology:"..plant.name}, rarity=1}, {items={"default:dirt"}, rarity=1}}}
|
||||
minetest.register_node("lib_ecology:"..plant.name.."_water_soil", def2)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function register_flower(name, seed, biomes)
|
||||
local param = {
|
||||
deco_type = "simple",
|
||||
place_on = {"default:dirt_with_grass"},
|
||||
sidelen = 16,
|
||||
noise_params = {
|
||||
offset = -0.02,
|
||||
scale = 0.03,
|
||||
spread = {x = 200, y = 200, z = 200},
|
||||
seed = seed,
|
||||
octaves = 3,
|
||||
persist = 0.6
|
||||
},
|
||||
biomes = biomes,
|
||||
y_min = 6,
|
||||
y_max = 31000,
|
||||
decoration = "lib_ecology:"..name,
|
||||
}
|
||||
|
||||
-- Let rainforest plants show up more often.
|
||||
local key1 = table.contains(biomes, "rainforest")
|
||||
local key2 = table.contains(biomes, "desertstone_grassland")
|
||||
if key1 or key2 then
|
||||
if key1 then
|
||||
table.remove(param.biomes, key1)
|
||||
else
|
||||
table.remove(param.biomes, key2)
|
||||
end
|
||||
if #param.biomes > 0 then
|
||||
minetest.register_decoration(param)
|
||||
end
|
||||
|
||||
local param2 = table.copy(param)
|
||||
param2.biomes = {"lib_ecology_rainforest", "lib_ecology_desertstone_grassland", }
|
||||
param2.noise_params.seed = param2.noise_params.seed + 20
|
||||
param2.noise_params.offset = param2.noise_params.offset + 0.01
|
||||
minetest.register_decoration(param2)
|
||||
else
|
||||
minetest.register_decoration(param)
|
||||
end
|
||||
end
|
||||
|
||||
register_flower("bird_of_paradise", 8402, {"lib_ecology_rainforest", "lib_ecology_desertstone_grassland", })
|
||||
register_flower("orchid", 3944, {"lib_ecology_sandstone_grassland", "lib_ecology_tundra", "lib_ecology_taiga", "lib_ecology_stone_grassland", "lib_ecology_coniferous_forest", "lib_ecology_deciduous_forest", "lib_ecology_savanna", "lib_ecology_rainforest", "lib_ecology_rainforest_swamp", "lib_ecology_desertstone_grassland", })
|
||||
register_flower("hibiscus", 7831, {"lib_ecology_sandstone_grassland", "lib_ecology_deciduous_forest", "lib_ecology_savanna", "lib_ecology_rainforest", "lib_ecology_rainforest_swamp", "lib_ecology_desertstone_grassland", })
|
||||
register_flower("calla_lily", 7985, {"lib_ecology_sandstone_grassland", "lib_ecology_stone_grassland", "lib_ecology_deciduous_forest", "lib_ecology_rainforest", "lib_ecology_desertstone_grassland", })
|
||||
register_flower("gerbera", 1976, {"lib_ecology_savanna", "lib_ecology_rainforest", "lib_ecology_desertstone_grassland", })
|
||||
|
||||
do
|
||||
-- Water Plant: Arrow Arum
|
||||
local arrow_def_sand = {
|
||||
fill_ratio = 0.05,
|
||||
place_on = {"group:sand"},
|
||||
decoration = {"lib_ecology:arrow_arum_water_sand",},
|
||||
--biomes = {"sandstone_grassland", "stone_grassland", "coniferous_forest", "deciduous_forest", "desert", "savanna", "rainforest", "rainforest_swamp", "desertstone_grassland", },
|
||||
biomes = {"lib_ecology_sandstone_grassland", "lib_ecology_stone_grassland", "lib_ecology_coniferous_forest", "lib_ecology_deciduous_forest", "lib_ecology_desert", "lib_ecology_savanna", "lib_ecology_rainforest", "lib_ecology_rainforest_swamp","lib_ecology_sandstone_grassland_ocean", "lib_ecology_stone_grassland_ocean", "lib_ecology_coniferous_forest_ocean", "lib_ecology_deciduous_forest_ocean", "lib_ecology_desert_ocean", "lib_ecology_savanna_ocean", "lib_ecology_desertstone_grassland", },
|
||||
y_max = 60,
|
||||
}
|
||||
local arrow_def_soil = table.copy(arrow_def_sand)
|
||||
arrow_def_soil.place_on = {"group:soil"}
|
||||
arrow_def_soil.decoration = {"lib_ecology:arrow_arum_water_soil",}
|
||||
|
||||
lib_ecology.register_water_plant(arrow_def_sand)
|
||||
lib_ecology.register_water_plant(arrow_def_soil)
|
||||
end
|
||||
|
||||
|
||||
if lib_ecology.glow then
|
||||
minetest.register_node("lib_ecology:moon_weed", {
|
||||
description = "Moon Weed",
|
||||
drawtype = "plantlike",
|
||||
tiles = {"vmg_moon_weed.png"},
|
||||
inventory_image = "vmg_moon_weed.png",
|
||||
waving = false,
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
light_source = 8,
|
||||
walkable = false,
|
||||
groups = {snappy=3,flammable=2,flora=1,attached_node=1},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
|
||||
},
|
||||
})
|
||||
|
||||
local param = {
|
||||
deco_type = "simple",
|
||||
place_on = {"default:dirt_with_grass"},
|
||||
sidelen = 80,
|
||||
biomes = {"lib_ecology_sandstone_grassland", "lib_ecology_tundra", "lib_ecology_taiga", "lib_ecology_stone_grassland", "lib_ecology_coniferous_forest", "lib_ecology_deciduous_forest", "lib_ecology_savanna", "lib_ecology_rainforest", "lib_ecology_rainforest_swamp", "lib_ecology_desertstone_grassland", },
|
||||
fill_ratio = 1/1000,
|
||||
y_min = 6,
|
||||
y_max = 31000,
|
||||
decoration = "lib_ecology:moon_weed",
|
||||
}
|
||||
minetest.register_decoration(param)
|
||||
end
|
|
@ -0,0 +1,201 @@
|
|||
----------------------
|
||||
-- Decorative Rocks --
|
||||
----------------------
|
||||
|
||||
-- I'm feeling a bit zen...
|
||||
|
||||
-- Create a simple sphereoid from nodeboxes.
|
||||
-- This isn't as nifty as I originally thought. The large ones are
|
||||
-- ugly and the small ones are nearly invisible. I may stick with cubes.
|
||||
local function step_sphere(grid, pos, diameters, embed)
|
||||
local step = {x=diameters.x * 0.2, y=diameters.y * 0.2, z=diameters.z * 0.2}
|
||||
local rock = {}
|
||||
|
||||
if embed then
|
||||
embed = 1
|
||||
else
|
||||
embed = 0
|
||||
end
|
||||
|
||||
rock[1] = pos.x + step.x
|
||||
rock[2] = pos.y + (step.y * embed)
|
||||
rock[3] = pos.z
|
||||
rock[4] = pos.x + diameters.x - step.x
|
||||
rock[5] = diameters.y + pos.y - step.y - (step.y * embed)
|
||||
rock[6] = pos.z + diameters.z
|
||||
push(grid, rock)
|
||||
|
||||
rock = {}
|
||||
rock[1] = pos.x
|
||||
rock[2] = pos.y + (step.y * embed)
|
||||
rock[3] = pos.z + step.z
|
||||
rock[4] = pos.x + step.x
|
||||
rock[5] = diameters.y + pos.y - step.y - (step.y * embed)
|
||||
rock[6] = pos.z + diameters.z - step.z
|
||||
push(grid, rock)
|
||||
|
||||
rock = {}
|
||||
rock[1] = pos.x + diameters.x - step.x
|
||||
rock[2] = pos.y + (step.y * embed)
|
||||
rock[3] = pos.z + step.z
|
||||
rock[4] = pos.x + diameters.x
|
||||
rock[5] = diameters.y + pos.y - step.y - (step.y * embed)
|
||||
rock[6] = pos.z + diameters.z - step.z
|
||||
push(grid, rock)
|
||||
|
||||
if not embed then
|
||||
rock = {}
|
||||
rock[1] = pos.x + step.x
|
||||
rock[2] = pos.y
|
||||
rock[3] = pos.z + step.z
|
||||
rock[4] = pos.x + diameters.x - step.x
|
||||
rock[5] = step.y + pos.y
|
||||
rock[6] = pos.z + diameters.z - step.z
|
||||
push(grid, rock)
|
||||
end
|
||||
|
||||
rock = {}
|
||||
rock[1] = pos.x + step.x
|
||||
rock[2] = diameters.y + pos.y - step.y - (step.y * embed)
|
||||
rock[3] = pos.z + step.z
|
||||
rock[4] = pos.x + diameters.x - step.x
|
||||
rock[5] = diameters.y + pos.y - (step.y * embed)
|
||||
rock[6] = pos.z + diameters.z - step.z
|
||||
push(grid, rock)
|
||||
end
|
||||
|
||||
-- Place a small nodebox.
|
||||
local function small_cube(grid, pos, diameters)
|
||||
local rock = {}
|
||||
|
||||
rock[1] = pos.x
|
||||
rock[2] = pos.y
|
||||
rock[3] = pos.z
|
||||
rock[4] = pos.x + diameters.x
|
||||
rock[5] = pos.y + diameters.y
|
||||
rock[6] = pos.z + diameters.z
|
||||
push(grid, rock)
|
||||
end
|
||||
|
||||
|
||||
-- Create some tiles of small rocks that can be picked up.
|
||||
local default_grid
|
||||
local tiles = {"default_stone.png", "default_desert_stone.png", "default_sandstone.png"}
|
||||
|
||||
for grid_count = 1,6 do
|
||||
local grid = {}
|
||||
for rock_count = 2, math.random(1,4) + 1 do
|
||||
local diameter = math.random(5,15)/100
|
||||
local x = math.random(1,80)/100 - 0.5
|
||||
local z = math.random(1,80)/100 - 0.5
|
||||
--step_sphere(grid, {x=x,y=-0.5,z=z}, {x=diameter, y=diameter, z=diameter})
|
||||
small_cube(grid, {x=x,y=-0.5,z=z}, {x=diameter, y=diameter, z=diameter})
|
||||
end
|
||||
|
||||
--local stone = tiles[math.random(1,#tiles)]
|
||||
local stone = tiles[(grid_count % #tiles) + 1]
|
||||
|
||||
minetest.register_node("lib_ecology:small_rocks"..grid_count, {
|
||||
description = "Small Rocks",
|
||||
tiles = {stone},
|
||||
is_ground_content = true,
|
||||
walkable = false,
|
||||
paramtype = "light",
|
||||
drawtype = "nodebox",
|
||||
buildable_to = true,
|
||||
node_box = { type = "fixed",
|
||||
fixed = grid },
|
||||
selection_box = { type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
|
||||
},
|
||||
groups = {stone=1, oddly_breakable_by_hand=3},
|
||||
drop = "lib_ecology:small_rocks",
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_decoration({
|
||||
deco_type = "simple",
|
||||
decoration = "lib_ecology:small_rocks"..grid_count,
|
||||
sidelen = 80,
|
||||
place_on = {"group:soil", "group:sand", "group:stone"},
|
||||
fill_ratio = 0.002,
|
||||
biomes = {"lib_ecology_sandstone_grassland", "lib_ecology_tundra", "lib_ecology_taiga", "lib_ecology_stone_grassland", "lib_ecology_coniferous_forest", "lib_ecology_deciduous_forest", "lib_ecology_desert", "lib_ecology_cold_desert", "lib_ecology_savanna", "lib_ecology_rainforest", "lib_ecology_desertstone_grassland", },
|
||||
flags = "place_center_x, place_center_z",
|
||||
rotation = "random",
|
||||
})
|
||||
|
||||
default_grid = grid
|
||||
end
|
||||
|
||||
-- This is the inventory item, so we don't have six different stacks.
|
||||
minetest.register_node("lib_ecology:small_rocks", {
|
||||
description = "Small Rocks",
|
||||
tiles = {"default_stone.png"},
|
||||
inventory_image = "vmg_small_rocks.png",
|
||||
is_ground_content = true,
|
||||
walkable = false,
|
||||
paramtype = "light",
|
||||
drawtype = "nodebox",
|
||||
node_box = { type = "fixed",
|
||||
fixed = default_grid },
|
||||
selection_box = { type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
|
||||
},
|
||||
groups = {stone=1, oddly_breakable_by_hand=3},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
|
||||
---- Create some larger rocks that can be mined.
|
||||
--local tiles = {"default_stone.png", "default_desert_stone.png", "default_sandstone.png"}
|
||||
--local sel = {{-0.4,-0.5,-0.4,0.4,0.0,0.3}, {-0.4,-0.5,-0.4,0.2,-0.1,0.3}, {-0.3,-0.5,-0.3,0.2,-0.2,0.3}}
|
||||
--
|
||||
--for count = 1,9 do
|
||||
-- local stone = tiles[(count % #tiles) + 1]
|
||||
-- --local grid = {}
|
||||
-- --step_sphere(grid, {x=-0.25,y=-0.5,z=-0.25}, {x=0.5, y=0.3, z=0.5})
|
||||
--
|
||||
-- minetest.register_node("lib_ecology:medium_rock"..count, {
|
||||
-- description = "Medium Rock",
|
||||
-- tiles = {stone},
|
||||
-- is_ground_content = true,
|
||||
-- walkable = true,
|
||||
-- paramtype = "light",
|
||||
-- --drawtype = "mesh",
|
||||
-- drawtype = "nodebox",
|
||||
-- --mesh = "rock0"..math.ceil(count / 3)..".b3d",
|
||||
-- node_box = {
|
||||
-- type = "fixed",
|
||||
-- fixed = {
|
||||
-- -0.25, -0.5, -0.25, 0.25, -0.25, 0.25,
|
||||
-- },
|
||||
-- },
|
||||
-- selection_box = {type="fixed", fixed=sel[math.ceil(count / 3)]},
|
||||
-- groups = {stone=1, cracky=3},
|
||||
-- drop = "default:cobble",
|
||||
-- sounds = default.node_sound_stone_defaults(),
|
||||
-- })
|
||||
--
|
||||
-- minetest.register_decoration({
|
||||
-- deco_type = "simple",
|
||||
-- decoration = "lib_ecology:medium_rock"..count,
|
||||
-- sidelen = 80,
|
||||
-- place_on = {"group:soil", "group:sand"},
|
||||
-- fill_ratio = 0.001,
|
||||
-- biomes = {"sandstone_grassland", "tundra", "taiga", "stone_grassland", "coniferous_forest", "deciduous_forest", "desert", "cold_desert", "savanna", "rainforest", "desertstone_grassland", },
|
||||
-- flags = "place_center_x, place_center_z",
|
||||
-- rotation = "random",
|
||||
-- })
|
||||
--end
|
||||
|
||||
|
||||
-- Small rocks can be used to create cobblestone, if you like.
|
||||
minetest.register_craft({
|
||||
output = "default:cobble",
|
||||
recipe = {
|
||||
{"", "", ""},
|
||||
{"lib_ecology:small_rocks", "lib_ecology:small_rocks", ""},
|
||||
{"lib_ecology:small_rocks", "lib_ecology:small_rocks", ""},
|
||||
},
|
||||
})
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
-----------
|
||||
-- Trees --
|
||||
-----------
|
||||
|
||||
-- See textures/image-credits.txt
|
||||
|
||||
-- Change leafdecay ratings
|
||||
minetest.add_group("default:leaves", {leafdecay = 4})
|
||||
minetest.add_group("default:jungleleaves", {leafdecay = 4})
|
||||
minetest.add_group("default:pine_needles", {leafdecay = 5})
|
||||
|
||||
|
||||
-- a list of tree descriptions
|
||||
lib_ecology.treelist = {
|
||||
{name="banana",
|
||||
desc="Banana",
|
||||
leaf="leaves",
|
||||
leaf_desc="Leaves",
|
||||
leaf_tile="banana_leaves",
|
||||
fruit="banana",
|
||||
fruit_desc="Banana",
|
||||
drop_rarity=20,
|
||||
selbox={-0.35, -0.5, -0.35, 0.35, 0.5, 0.35},
|
||||
health=3,
|
||||
trunk_dia=0.75},
|
||||
|
||||
{name="birch",
|
||||
desc="Birch",
|
||||
leaf="leaves",
|
||||
leaf_desc="Leaves",
|
||||
leaf_tile="birch_leaves",
|
||||
drop_rarity=20,
|
||||
trunk_dia=0.5},
|
||||
{name="cherry_blossom",
|
||||
desc="Cherry Blossom",
|
||||
leaf="leaves",
|
||||
leaf_desc="Leaves",
|
||||
leaf_tile="cherry_blossom_leaves",
|
||||
drop_rarity=20,
|
||||
trunk_dia=0.5},
|
||||
|
||||
{name="fir",
|
||||
desc="Fir",
|
||||
leaf="needles",
|
||||
leaf_desc="Needles",
|
||||
leaf_tile="fir_leaves",
|
||||
drop_rarity=20,
|
||||
trunk_dia=1.0},
|
||||
}
|
||||
|
||||
|
||||
for _, tree in ipairs(lib_ecology.treelist) do
|
||||
-- a standard node description
|
||||
local node_d = {
|
||||
description = tree.desc.." Tree",
|
||||
tiles = {
|
||||
"vmg_"..tree.name.."_tree_top.png",
|
||||
"vmg_"..tree.name.."_tree_top.png",
|
||||
"vmg_"..tree.name.."_tree.png"
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = true,
|
||||
groups = {tree=1,choppy=2,oddly_breakable_by_hand=1,flammable=2},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
on_place = minetest.rotate_node,
|
||||
}
|
||||
-- Some trunks aren't a meter wide.
|
||||
if tree.trunk_dia and tree.trunk_dia ~= 1 then
|
||||
local radius = tree.trunk_dia / 2
|
||||
node_d.paramtype = "light"
|
||||
node_d.drawtype = "nodebox"
|
||||
node_d.node_box = { type = "fixed",
|
||||
fixed = { {-radius, -0.5, -radius, radius, 0.5, radius}, }
|
||||
}
|
||||
end
|
||||
minetest.register_node("lib_ecology:"..tree.name.."_tree", node_d)
|
||||
|
||||
if tree.name ~= "banana" then
|
||||
-- planks that come from the tree
|
||||
minetest.register_node("lib_ecology:"..tree.name.."_wood", {
|
||||
description = tree.desc.." Planks",
|
||||
tiles = {"vmg_"..tree.name.."_wood.png"},
|
||||
is_ground_content = true,
|
||||
groups = {choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
-- how to get the planks
|
||||
minetest.register_craft({
|
||||
output = "lib_ecology:"..tree.name.."_wood 5",
|
||||
recipe = {
|
||||
{"lib_ecology:"..tree.name.."_tree"}
|
||||
}
|
||||
})
|
||||
|
||||
-- appropriate wooden stairs and slabs
|
||||
-- -- if minetest.get_modpath("stairs") then
|
||||
-- -- stairs.register_stair_and_slab(
|
||||
-- -- "vmg_"..tree.name.."_tree",
|
||||
-- -- "lib_ecology:"..tree.name.."_tree",
|
||||
-- -- {snappy=1, choppy=2, oddly_breakable_by_hand=1, flammable=2 },
|
||||
-- -- { "vmg_"..tree.name.."_tree_top.png",
|
||||
-- -- "vmg_"..tree.name.."_tree_top.png",
|
||||
-- -- "vmg_"..tree.name.."_tree.png"
|
||||
-- -- },
|
||||
-- -- tree.desc.." Tree Stair",
|
||||
-- -- tree.desc.." Tree Slab",
|
||||
-- -- default.node_sound_wood_defaults()
|
||||
-- -- )
|
||||
-- -- stairs.register_stair_and_slab(
|
||||
-- -- "vmg_"..tree.name.."_wood",
|
||||
-- -- "lib_ecology:"..tree.name.."_wood",
|
||||
-- -- { snappy=1, choppy=2, oddly_breakable_by_hand=2, flammable=3 },
|
||||
-- -- {"vmg_"..tree.name.."_wood.png" },
|
||||
-- -- tree.desc.." Planks Stair",
|
||||
-- -- tree.desc.." Planks Slab",
|
||||
-- -- default.node_sound_wood_defaults()
|
||||
-- -- )
|
||||
-- -- end
|
||||
end
|
||||
|
||||
-- the tree's sapling form
|
||||
minetest.register_node("lib_ecology:"..tree.name.."_sapling", {
|
||||
description = tree.desc.." Sapling",
|
||||
drawtype = "plantlike",
|
||||
visual_scale = 1.0,
|
||||
tiles = {"vmg_"..tree.name.."_sapling.png"},
|
||||
inventory_image = "vmg_"..tree.name.."_sapling.png",
|
||||
wield_image = "vmg_"..tree.name.."_sapling.png",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
|
||||
},
|
||||
groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1,sapling=1},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
})
|
||||
|
||||
-- leaves for the tree
|
||||
minetest.register_node("lib_ecology:"..tree.name.."_"..tree.leaf.."", {
|
||||
description = tree.desc.." "..tree.leaf_desc.."",
|
||||
drawtype = "allfaces_optional",
|
||||
waving = 1,
|
||||
visual_scale = 1.3,
|
||||
tiles = { "vmg_"..tree.leaf_tile..".png"},
|
||||
paramtype = "light",
|
||||
is_ground_content = false,
|
||||
groups = {snappy=3, leafdecay=4, flammable=2, leaves=1, leafdecay=1},
|
||||
drop = {
|
||||
max_items = 1,
|
||||
items = {
|
||||
{items = {"lib_ecology:"..tree.name.."_sapling"}, rarity = tree.drop_rarity },
|
||||
{items = {"lib_ecology:"..tree.name.."_"..tree.leaf..""} }
|
||||
}
|
||||
},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
after_place_node = default.after_place_leaves,
|
||||
})
|
||||
|
||||
-- appropriate fruit
|
||||
if tree.fruit then
|
||||
minetest.register_node("lib_ecology:"..tree.fruit.."", {
|
||||
description = tree.fruit_desc,
|
||||
drawtype = "plantlike",
|
||||
visual_scale = 1.0,
|
||||
tiles = { "vmg_"..tree.fruit..".png" },
|
||||
inventory_image = "vmg_"..tree.fruit..".png",
|
||||
wield_image = "vmg_"..tree.fruit..".png",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
is_ground_content = false,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = tree.selbox
|
||||
},
|
||||
groups = {fleshy=3,dig_immediate=3,flammable=2, leafdecay=3,leafdecay_drop=1},
|
||||
-- Fruit makes you healthy.
|
||||
on_use = minetest.item_eat(tree.health),
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
if placer:is_player() then
|
||||
minetest.set_node(pos, {name="lib_ecology:"..tree.fruit.."", param2=1})
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- list of all lib_ecology-specific saplings
|
||||
lib_ecology.saplings = {
|
||||
{sapling="lib_ecology:banana_sapling",
|
||||
schematics=lib_ecology.schematics.banana_plants},
|
||||
{sapling="lib_ecology:cherry_blossom_sapling",
|
||||
schematics=lib_ecology.schematics.cherry_trees},
|
||||
{sapling="lib_ecology:birch_sapling",
|
||||
schematics=lib_ecology.schematics.birch_trees},
|
||||
}
|
||||
|
||||
-- create a list of just the node names
|
||||
local sapling_list = {}
|
||||
for _, sap in pairs(lib_ecology.saplings) do
|
||||
push(sapling_list, sap.sapling)
|
||||
end
|
||||
|
||||
-- This abm can handle all saplings.
|
||||
minetest.register_abm({
|
||||
nodenames = sapling_list,
|
||||
interval = 10,
|
||||
chance = 50,
|
||||
action = function(pos, node)
|
||||
local node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
|
||||
if not node_under or
|
||||
minetest.get_item_group(node_under.name, "soil") == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
for _, sap in lib_ecology.saplings do
|
||||
if node.name == sap.sapling then
|
||||
minetest.log("action", "A sapling grows into a tree at "..
|
||||
minetest.pos_to_string(pos))
|
||||
|
||||
local schem = sap.schematics[math.random(1,#sap.schematics)]
|
||||
local adj = {x = pos.x - math.floor(schem.size.x / 2),
|
||||
y = pos.y - 1,
|
||||
z = pos.z - math.floor(schem.size.z / 2)}
|
||||
minetest.place_schematic(adj, schem, 'random', nil, true)
|
||||
break
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
-- tree creation code
|
||||
dofile(lib_ecology.path.."/valleys_c/deco_deciduous.lua")
|
||||
dofile(lib_ecology.path.."/valleys_c/deco_conifer.lua")
|
||||
dofile(lib_ecology.path.."/valleys_c/deco_jungle.lua")
|
||||
dofile(lib_ecology.path.."/valleys_c/deco_banana.lua")
|
||||
|
||||
if lib_ecology.glow then
|
||||
dofile(lib_ecology.path.."/valleys_c/deco_lumin.lua")
|
||||
end
|
|
@ -0,0 +1,61 @@
|
|||
-- Modified from Perttu Ahola's <celeron55@gmail.com> "noairblocks"
|
||||
-- mod and released as LGPL 2.1, as the original.
|
||||
|
||||
|
||||
local water_nodes = {"default:water_source", "default:water_flowing", "default:river_water_source", "default:river_water_flowing"}
|
||||
local lib_ecology_nodes = {"lib_ecology:water_source", "lib_ecology:water_flowing", "lib_ecology:river_water_source", "lib_ecology:river_water_flowing"}
|
||||
|
||||
for _, name in pairs(water_nodes) do
|
||||
local water = table.copy(minetest.registered_nodes[name])
|
||||
local new_name = string.gsub(name, 'default', 'lib_ecology')
|
||||
local new_source = string.gsub(water.liquid_alternative_source, 'default', 'lib_ecology')
|
||||
local new_flowing = string.gsub(water.liquid_alternative_flowing, 'default', 'lib_ecology')
|
||||
water.alpha = 0
|
||||
water.liquid_alternative_source = new_source
|
||||
water.liquid_alternative_flowing = new_flowing
|
||||
water.groups.not_in_creative_inventory = 1
|
||||
|
||||
minetest.register_node(new_name, water)
|
||||
end
|
||||
|
||||
|
||||
local check_pos = {
|
||||
{x=-1, y=0, z=0},
|
||||
{x=1, y=0, z=0},
|
||||
{x=0, y=0, z=-1},
|
||||
{x=0, y=0, z=1},
|
||||
{x=0, y=1, z=0},
|
||||
}
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"group:sea"},
|
||||
neighbors = {"group:water"},
|
||||
interval = 10,
|
||||
chance = 1,
|
||||
action = function(pos)
|
||||
for _,offset in pairs(check_pos) do
|
||||
local check = vector.add(pos, offset)
|
||||
local check_above = vector.add(check, {x=0,y=1,z=0})
|
||||
if offset == {0,-1,0} or minetest.get_node(check_above).name ~= "air" then
|
||||
local name = minetest.get_node(check).name
|
||||
for node_num=1,#water_nodes do
|
||||
if name == water_nodes[node_num] then
|
||||
minetest.add_node(check, {name = lib_ecology_nodes[node_num]})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = lib_ecology_nodes,
|
||||
neighbors = {"air"},
|
||||
interval = 20,
|
||||
chance = 1,
|
||||
action = function(pos)
|
||||
if minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name == "air" then
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
end,
|
||||
})
|
|
@ -0,0 +1,987 @@
|
|||
----------------------
|
||||
-- Voxel Manip Loop --
|
||||
----------------------
|
||||
|
||||
-- This is only used to handle cases the decoration manager can't,
|
||||
-- such as water plants and cave decorations.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- Define perlin noises used in this mapgen by default
|
||||
lib_ecology.noises = {}
|
||||
|
||||
if lib_ecology.noise_set_id == 1 then
|
||||
-- Noise 1 : Base Ground Height 2D
|
||||
--lib_ecology.noises[1] = {offset = -10, scale = 50, seed = 5202, spread = {x = 1024, y = 1024, z = 1024}, octaves = 6, persist = 0.4, lacunarity = 2},
|
||||
lib_ecology.noises[1] = {offset = -10, scale = 25, seed = 5202, spread = {x = 4096, y = 4096, z = 4096}, octaves = 6, persist = 0.4, lacunarity = 2}
|
||||
-- Noise 2 : Valleys (River where around zero) 2D
|
||||
lib_ecology.noises[2] = {offset = 0, scale = 1, seed = -6050, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.6, lacunarity = 2}
|
||||
-- Noise 3 : Valleys Depth 2D
|
||||
lib_ecology.noises[3] = {offset = 5, scale = 4, seed = -1914, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2}
|
||||
-- Noise 4 : Valleys Profile (Higher values = Larger valleys) 2D
|
||||
lib_ecology.noises[4] = {offset = 0.6, scale = 0.5, seed = 777, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2}
|
||||
-- Noise 5 : Inter-valleys slopes 2D
|
||||
lib_ecology.noises[5] = {offset = 0.5, scale = 0.5, seed = 746, spread = {x = 128, y = 128, z = 128}, octaves = 1, persist = 1, lacunarity = 2}
|
||||
-- Noise 6 : Inter-valleys filling 3D
|
||||
lib_ecology.noises[6] = {offset = 0, scale = 1, seed = 1993, spread = {x = 256, y = 512, z = 256}, octaves = 6, persist = 0.8, lacunarity = 2}
|
||||
-- Noise 7 : Dirt thickness 2D
|
||||
lib_ecology.noises[7] = {offset = 3, scale = 1.75, seed = 1605, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5, lacunarity = 2}
|
||||
-- Noise 8 : Caves I 3D
|
||||
lib_ecology.noises[8] = {offset = 0, scale = 1, seed = -4640, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
-- Noise 9 : Caves II 3D
|
||||
lib_ecology.noises[9] = {offset = 0, scale = 1, seed = 8804, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
-- Noise 10 : Caves III 3D
|
||||
lib_ecology.noises[10] = {offset = 0, scale = 1, seed = -4780, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
-- Noise 11 : Caves IV and Lava I 3D
|
||||
lib_ecology.noises[11] = {offset = 0, scale = 1, seed = -9969, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
-- Noise 12 : Lava II (Geologic heat) 3D
|
||||
lib_ecology.noises[12] = {offset = 0, scale = 1, seed = 3314, spread = {x = 64, y = 64, z = 64}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
|
||||
-- Noise 13 : Clayey dirt noise 2D
|
||||
lib_ecology.noises[13] = {offset = 0, scale = 1, seed = 2835, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4}
|
||||
-- Noise 14 : Silty dirt noise 2D
|
||||
lib_ecology.noises[14] = {offset = 0, scale = 1, seed = 6674, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4}
|
||||
-- Noise 15 : Sandy dirt noise 2D
|
||||
lib_ecology.noises[15] = {offset = 0, scale = 1, seed = 6940, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4}
|
||||
-- Noise 16 : Beaches 2D
|
||||
lib_ecology.noises[16] = {offset = 2, scale = 8, seed = 2349, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5, lacunarity = 2}
|
||||
|
||||
-- Noise 17 : Temperature (not in maps) 3D
|
||||
lib_ecology.noises[17] = {offset = 2, scale = 1, seed = -1805, spread = {x = 768, y = 256, z = 768}, octaves = 4, persist = 0.5, lacunarity = 4}
|
||||
-- Noise 18 : Humidity 2D
|
||||
lib_ecology.noises[18] = {offset = 0, scale = 1, seed = -5787, spread = {x = 243, y = 243, z = 243}, octaves = 4, persist = 0.5, lacunarity = 3}
|
||||
|
||||
-- Noise 21 : Water plants 2D
|
||||
lib_ecology.noises[21] = {offset = 0.0, scale = 1.0, spread = {x = 200, y = 200, z = 200}, seed = 33, octaves = 3, persist = 0.7, lacunarity = 2.0}
|
||||
-- Noise 22 : Cave blend 2D
|
||||
lib_ecology.noises[22] = {offset = 0.0, scale = 0.1, spread = {x = 8, y = 8, z = 8}, seed = 4023, octaves = 2, persist = 1.0, lacunarity = 2.0}
|
||||
-- Noise 23 : Cave noise 2D
|
||||
lib_ecology.noises[23] = {offset = 0.0, scale = 1.0, spread = {x = 400, y = 400, z = 400}, seed = 903, octaves = 3, persist = 0.5, lacunarity = 2.0}
|
||||
end
|
||||
|
||||
if lib_ecology.noise_set_id == 2 then
|
||||
-- Noise 1 : Base Ground Height 2D
|
||||
--lib_ecology.noises[1] = {offset = -10, scale = 50, seed = 5202, spread = {x = 1024, y = 1024, z = 1024}, octaves = 6, persist = 0.4, lacunarity = 2},
|
||||
lib_ecology.noises[1] = {offset = -10, scale = 50, seed = 5202, spread = {x = 1024, y = 1024, z = 1024}, octaves = 6, persist = 0.4, lacunarity = 2}
|
||||
-- Noise 2 : Valleys (River where around zero) 2D
|
||||
lib_ecology.noises[2] = {offset = 0, scale = 1, seed = -6050, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.6, lacunarity = 2}
|
||||
-- Noise 3 : Valleys Depth 2D
|
||||
lib_ecology.noises[3] = {offset = 5, scale = 4, seed = -1914, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2}
|
||||
-- Noise 4 : Valleys Profile (Higher values = Larger valleys) 2D
|
||||
lib_ecology.noises[4] = {offset = 0.6, scale = 0.5, seed = 777, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2}
|
||||
-- Noise 5 : Inter-valleys slopes 2D
|
||||
lib_ecology.noises[5] = {offset = 0.5, scale = 0.5, seed = 746, spread = {x = 128, y = 128, z = 128}, octaves = 1, persist = 1, lacunarity = 2}
|
||||
-- Noise 6 : Inter-valleys filling 3D
|
||||
lib_ecology.noises[6] = {offset = 0, scale = 1, seed = 1993, spread = {x = 256, y = 512, z = 256}, octaves = 6, persist = 0.8, lacunarity = 2}
|
||||
-- Noise 7 : Dirt thickness 2D
|
||||
lib_ecology.noises[7] = {offset = 3, scale = 1.75, seed = 1605, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5, lacunarity = 2}
|
||||
-- Noise 8 : Caves I 3D
|
||||
lib_ecology.noises[8] = {offset = 0, scale = 1, seed = -4640, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
-- Noise 9 : Caves II 3D
|
||||
lib_ecology.noises[9] = {offset = 0, scale = 1, seed = 8804, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
-- Noise 10 : Caves III 3D
|
||||
lib_ecology.noises[10] = {offset = 0, scale = 1, seed = -4780, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
-- Noise 11 : Caves IV and Lava I 3D
|
||||
lib_ecology.noises[11] = {offset = 0, scale = 1, seed = -9969, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
-- Noise 12 : Lava II (Geologic heat) 3D
|
||||
lib_ecology.noises[12] = {offset = 0, scale = 1, seed = 3314, spread = {x = 64, y = 64, z = 64}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
|
||||
-- Noise 13 : Clayey dirt noise 2D
|
||||
lib_ecology.noises[13] = {offset = 0, scale = 1, seed = 2835, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4}
|
||||
-- Noise 14 : Silty dirt noise 2D
|
||||
lib_ecology.noises[14] = {offset = 0, scale = 1, seed = 6674, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4}
|
||||
-- Noise 15 : Sandy dirt noise 2D
|
||||
lib_ecology.noises[15] = {offset = 0, scale = 1, seed = 6940, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4}
|
||||
-- Noise 16 : Beaches 2D
|
||||
lib_ecology.noises[16] = {offset = 2, scale = 8, seed = 2349, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5, lacunarity = 2}
|
||||
|
||||
-- Noise 17 : Temperature (not in maps) 3D
|
||||
lib_ecology.noises[17] = {offset = 2, scale = 1, seed = -1805, spread = {x = 768, y = 256, z = 768}, octaves = 4, persist = 0.5, lacunarity = 4}
|
||||
-- Noise 18 : Humidity 2D
|
||||
lib_ecology.noises[18] = {offset = 0, scale = 1, seed = -5787, spread = {x = 243, y = 243, z = 243}, octaves = 4, persist = 0.5, lacunarity = 3}
|
||||
|
||||
-- Noise 21 : Water plants 2D
|
||||
lib_ecology.noises[21] = {offset = 0.0, scale = 1.0, spread = {x = 200, y = 200, z = 200}, seed = 33, octaves = 3, persist = 0.7, lacunarity = 2.0}
|
||||
-- Noise 22 : Cave blend 2D
|
||||
lib_ecology.noises[22] = {offset = 0.0, scale = 0.1, spread = {x = 8, y = 8, z = 8}, seed = 4023, octaves = 2, persist = 1.0, lacunarity = 2.0}
|
||||
-- Noise 23 : Cave noise 2D
|
||||
lib_ecology.noises[23] = {offset = 0.0, scale = 1.0, spread = {x = 400, y = 400, z = 400}, seed = 903, octaves = 3, persist = 0.5, lacunarity = 2.0}
|
||||
|
||||
end
|
||||
|
||||
if lib_ecology.noise_set_id == 3 then
|
||||
-- Noise 1 : Base Ground Height 2D
|
||||
--lib_ecology.noises[1] = {offset = -10, scale = 50, seed = 5202, spread = {x = 1024, y = 1024, z = 1024}, octaves = 6, persist = 0.4, lacunarity = 2},
|
||||
lib_ecology.noises[1] = {offset = -10, scale = 25, seed = 5202, spread = {x = 4096, y = 4096, z = 4096}, octaves = 6, persist = 0.4, lacunarity = 2}
|
||||
-- Noise 2 : Valleys (River where around zero) 2D
|
||||
lib_ecology.noises[2] = {offset = 0, scale = 1, seed = -6050, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.6, lacunarity = 2}
|
||||
-- Noise 3 : Valleys Depth 2D
|
||||
lib_ecology.noises[3] = {offset = 5, scale = 4, seed = -1914, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2}
|
||||
-- Noise 4 : Valleys Profile (Higher values = Larger valleys) 2D
|
||||
lib_ecology.noises[4] = {offset = 0.6, scale = 0.5, seed = 777, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2}
|
||||
-- Noise 5 : Inter-valleys slopes 2D
|
||||
lib_ecology.noises[5] = {offset = 0.5, scale = 0.5, seed = 746, spread = {x = 128, y = 128, z = 128}, octaves = 1, persist = 1, lacunarity = 2}
|
||||
-- Noise 6 : Inter-valleys filling 3D
|
||||
lib_ecology.noises[6] = {offset = 0, scale = 1, seed = 1993, spread = {x = 256, y = 512, z = 256}, octaves = 6, persist = 0.8, lacunarity = 2}
|
||||
-- Noise 7 : Dirt thickness 2D
|
||||
lib_ecology.noises[7] = {offset = 3, scale = 1.75, seed = 1605, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5, lacunarity = 2}
|
||||
-- Noise 8 : Caves I 3D
|
||||
lib_ecology.noises[8] = {offset = 0, scale = 1, seed = -4640, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
-- Noise 9 : Caves II 3D
|
||||
lib_ecology.noises[9] = {offset = 0, scale = 1, seed = 8804, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
-- Noise 10 : Caves III 3D
|
||||
lib_ecology.noises[10] = {offset = 0, scale = 1, seed = -4780, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
-- Noise 11 : Caves IV and Lava I 3D
|
||||
lib_ecology.noises[11] = {offset = 0, scale = 1, seed = -9969, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
-- Noise 12 : Lava II (Geologic heat) 3D
|
||||
lib_ecology.noises[12] = {offset = 0, scale = 1, seed = 3314, spread = {x = 64, y = 64, z = 64}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
|
||||
-- Noise 13 : Clayey dirt noise 2D
|
||||
lib_ecology.noises[13] = {offset = 0, scale = 1, seed = 2835, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4}
|
||||
-- Noise 14 : Silty dirt noise 2D
|
||||
lib_ecology.noises[14] = {offset = 0, scale = 1, seed = 6674, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4}
|
||||
-- Noise 15 : Sandy dirt noise 2D
|
||||
lib_ecology.noises[15] = {offset = 0, scale = 1, seed = 6940, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4}
|
||||
-- Noise 16 : Beaches 2D
|
||||
lib_ecology.noises[16] = {offset = 2, scale = 8, seed = 2349, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5, lacunarity = 2}
|
||||
|
||||
-- Noise 17 : Temperature (not in maps) 3D
|
||||
lib_ecology.noises[17] = {offset = 2, scale = 1, seed = -1805, spread = {x = 768, y = 256, z = 768}, octaves = 4, persist = 0.5, lacunarity = 4}
|
||||
-- Noise 18 : Humidity 2D
|
||||
lib_ecology.noises[18] = {offset = 0, scale = 1, seed = -5787, spread = {x = 243, y = 243, z = 243}, octaves = 4, persist = 0.5, lacunarity = 3}
|
||||
|
||||
-- Noise 21 : Water plants 2D
|
||||
lib_ecology.noises[21] = {offset = 0.0, scale = 1.0, spread = {x = 200, y = 200, z = 200}, seed = 33, octaves = 3, persist = 0.7, lacunarity = 2.0}
|
||||
-- Noise 22 : Cave blend 2D
|
||||
lib_ecology.noises[22] = {offset = 0.0, scale = 0.1, spread = {x = 8, y = 8, z = 8}, seed = 4023, octaves = 2, persist = 1.0, lacunarity = 2.0}
|
||||
-- Noise 23 : Cave noise 2D
|
||||
lib_ecology.noises[23] = {offset = 0.0, scale = 1.0, spread = {x = 400, y = 400, z = 400}, seed = 903, octaves = 3, persist = 0.5, lacunarity = 2.0}
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- function to get noisemaps
|
||||
function lib_ecology.noisemap(i, minp, chulens)
|
||||
local obj = minetest.get_perlin_map(lib_ecology.noises[i], chulens)
|
||||
if minp.z then
|
||||
return obj:get3dMap_flat(minp)
|
||||
else
|
||||
return obj:get2dMap_flat(minp)
|
||||
end
|
||||
end
|
||||
|
||||
-- useful function to convert a 3D pos to 2D
|
||||
function pos2d(pos)
|
||||
if type(pos) == "number" then
|
||||
return {x = pos, y = pos}
|
||||
elseif pos.z then
|
||||
return {x = pos.x, y = pos.z}
|
||||
else
|
||||
return {x = pos.x, y = pos.y}
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if a chunk contains a huge cave.
|
||||
-- This sucks. Use gennotify when possible.
|
||||
local function survey(data, area, maxp, minp, lava, water, air)
|
||||
local index_3d
|
||||
local space = 0
|
||||
for z = minp.z, maxp.z do
|
||||
for x = minp.x, maxp.x do
|
||||
index_3d = area:index(x, maxp.y, z)
|
||||
for y = maxp.y, minp.y, -1 do
|
||||
index_3d = index_3d - area.ystride
|
||||
-- The mapgen won't place lava or water near a huge cave.
|
||||
if data[index_3d] == lava or data[index_3d] == water then
|
||||
return false
|
||||
elseif data[index_3d] == air then
|
||||
space = space + 1
|
||||
end
|
||||
|
||||
-- This shortcut may skip lava or water, causing a false
|
||||
-- positive, but it can save a lot of time.
|
||||
-- This is an extremely poor way to check, but there aren't
|
||||
-- any good ways, and all the others take more cpu time.
|
||||
if space > 20000 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local mapgen_times = {
|
||||
liquid_lighting = {},
|
||||
loops = {},
|
||||
make_chunk = {},
|
||||
noisemaps = {},
|
||||
preparation = {},
|
||||
writing = {},
|
||||
}
|
||||
|
||||
|
||||
-- Define content IDs
|
||||
-- A content ID is a number that represents a node in the core of Minetest.
|
||||
-- Every nodename has its ID.
|
||||
-- The VoxelManipulator uses content IDs instead of nodenames.
|
||||
|
||||
local node = {}
|
||||
|
||||
local nodes = {
|
||||
-- Ground nodes
|
||||
{"sand_stone", "lib_materials:sand_stone"},
|
||||
{"brown_stone", "lib_materials:brown_stone"},
|
||||
{"granite", "lib_materials:granite"},
|
||||
{"marble", "lib_materials:marble"},
|
||||
{"basalt", "darkage:basalt"},
|
||||
{"chalk", "darkage:chalk"},
|
||||
{"darkdirt", "darkage:darkdirt"},
|
||||
{"gneiss", "darkage:gneiss"},
|
||||
{"darkdirt", "darkage:mud"},
|
||||
{"darkdirt", "darkage:ors"},
|
||||
{"darkdirt", "darkage:serpentine"},
|
||||
{"darkdirt", "darkage:shale"},
|
||||
{"darkdirt", "darkage:schist"},
|
||||
{"darkdirt", "darkage:silt"},
|
||||
{"darkdirt", "darkage:slate"},
|
||||
{"desertstone", "default:desert_stone"},
|
||||
{"desert_sandstone", "default:desert_sandstone"},
|
||||
{"sandstone", "default:sandstone"},
|
||||
{"silver_sandstone", "default:silver_sandstone"},
|
||||
{"stone", "default:stone"},
|
||||
{"gravel", "default:gravel"},
|
||||
{"dirt_with_grass", "default:dirt_with_grass"},
|
||||
{"dirt_with_dry_grass", "default:dirt_with_dry_grass"},
|
||||
{"dirt_with_snow", "default:dirt_with_snow"},
|
||||
{"dirt_with_rainforest_litter", "default:dirt_with_rainforest_litter"},
|
||||
{"dirt_with_coniferous_litter", "default:dirt_with_coniferous_litter"},
|
||||
{"dirt", "default:dirt"},
|
||||
{"green_dirt", "lib_ecology:green_dirt"},
|
||||
{"dry_dirt", "lib_ecology:dry_dirt"},
|
||||
{"bamboo_dirt", "lib_ecology:bamboo_dirt"},
|
||||
{"cold_dirt", "lib_ecology:cold_dirt"},
|
||||
{"crystal_dirt", "lib_ecology:crystal_dirt"},
|
||||
{"fiery_dirt", "lib_ecology:fiery_dirt"},
|
||||
{"gray_dirt", "lib_ecology:gray_dirt"},
|
||||
{"grove_dirt", "lib_ecology:grove_dirt"},
|
||||
{"jungle_dirt", "lib_ecology:jungle_dirt"},
|
||||
{"mushroom_dirt_dirt", "lib_ecology:mushroom_dirt_dirt"},
|
||||
{"prairie_dirt", "lib_ecology:prairie_dirt"},
|
||||
{"bamboo_dirt", "ethereal:bamboo_dirt"},
|
||||
{"cold_dirt", "ethereal:cold_dirt"},
|
||||
{"crystal_dirt", "ethereal:crystal_dirt"},
|
||||
{"fiery_dirt", "ethereal:fiery_dirt"},
|
||||
{"gray_dirt", "ethereal:gray_dirt"},
|
||||
{"grove_dirt", "ethereal:grove_dirt"},
|
||||
{"jungle_dirt", "ethereal:jungle_dirt"},
|
||||
{"mushroom_dirt_dirt", "ethereal:mushroom_dirt_dirt"},
|
||||
{"prairie_dirt", "ethereal:prairie_dirt"},
|
||||
{"quicksand", "lib_ecology:quicksand"},
|
||||
{"quicksand2", "lib_ecology:quicksand2"},
|
||||
{"quicksand", "ethereal:quicksand"},
|
||||
{"quicksand2", "ethereal:quicksand2"},
|
||||
{"desert_sand", "default:desert_sand"},
|
||||
{"silver_sand", "default:silver_sand"},
|
||||
{"sand", "default:sand"},
|
||||
{"clay", "default:clay"},
|
||||
{"river_water_source", "default:river_water_source"},
|
||||
{"water_source", "default:water_source"},
|
||||
{"lava", "default:lava_source"},
|
||||
|
||||
{"sand_with_rocks", "lib_ecology:sand_with_rocks"},
|
||||
--{"glowing_sand", "lib_ecology:glowing_sand"},
|
||||
{"fungal_stone", "lib_ecology:glowing_fungal_stone"},
|
||||
{"stalactite", "lib_ecology:stalactite"},
|
||||
{"stalactite_slimy", "lib_ecology:stalactite_slimy"},
|
||||
{"stalactite_mossy", "lib_ecology:stalactite_mossy"},
|
||||
{"stalagmite", "lib_ecology:stalagmite"},
|
||||
{"stalagmite_slimy", "lib_ecology:stalagmite_slimy"},
|
||||
{"stalagmite_mossy", "lib_ecology:stalagmite_mossy"},
|
||||
{"mushroom_cap_giant", "lib_ecology:giant_mushroom_cap"},
|
||||
{"mushroom_cap_huge", "lib_ecology:huge_mushroom_cap"},
|
||||
{"mushroom_stem", "lib_ecology:giant_mushroom_stem"},
|
||||
{"mushroom_red", "flowers:mushroom_red"},
|
||||
{"mushroom_brown", "flowers:mushroom_brown"},
|
||||
{"waterlily", "flowers:waterlily"},
|
||||
{"brain_coral", "lib_ecology:brain_coral"},
|
||||
--{"dragon_eye", "lib_ecology:dragon_eye"},
|
||||
{"pillar_coral", "lib_ecology:pillar_coral"},
|
||||
{"staghorn_coral", "lib_ecology:staghorn_coral"},
|
||||
{"coral_brown", "default:coral_brown"},
|
||||
{"coral_orange", "default:coral_orange"},
|
||||
{"coral_skeleton", "default:coral_skeleton"},
|
||||
|
||||
|
||||
{"dirt_clay", "lib_ecology:dirt_clayey"},
|
||||
{"lawn_clay", "lib_ecology:dirt_clayey_with_grass"},
|
||||
{"dry_clay", "lib_ecology:dirt_clayey_with_dry_grass"},
|
||||
{"snow_clay", "lib_ecology:dirt_clayey_with_snow"},
|
||||
{"dirt_silt", "lib_ecology:dirt_silty"},
|
||||
{"lawn_silt", "lib_ecology:dirt_silty_with_grass"},
|
||||
{"dry_silt", "lib_ecology:dirt_silty_with_dry_grass"},
|
||||
{"snow_silt", "lib_ecology:dirt_silty_with_snow"},
|
||||
{"dirt_sand", "lib_ecology:dirt_sandy"},
|
||||
{"lawn_sand", "lib_ecology:dirt_sandy_with_grass"},
|
||||
{"dry_sand", "lib_ecology:dirt_sandy_with_dry_grass"},
|
||||
{"snow_sand", "lib_ecology:dirt_sandy_with_snow"},
|
||||
{"silt", "lib_ecology:silt"},
|
||||
{"clay", "lib_ecology:red_clay"},
|
||||
|
||||
{"tree", "default:tree"},
|
||||
{"leaves", "default:leaves"},
|
||||
{"apple", "default:apple"},
|
||||
{"bamboo", "lib_ecology:bamboo"},
|
||||
{"bamboo_leaves", "lib_ecology:bamboo_leaves"},
|
||||
{"banana_tree", "lib_ecology:banana_tree"},
|
||||
{"banana_leaves", "lib_ecology:banana_leaves"},
|
||||
{"banana", "lib_ecology:banana"},
|
||||
{"birch_tree", "lib_ecology:birch_tree"},
|
||||
{"birch_leaves", "lib_ecology:birch_leaves"},
|
||||
{"cherry_blossom_tree", "lib_ecology:cherry_blossom_tree"},
|
||||
{"cherry_blossom_leaves", "lib_ecology:cherry_blossom_leaves"},
|
||||
{"fir_tree", "lib_ecology:fir_tree"},
|
||||
{"fir_needles", "lib_ecology:fir_needles"},
|
||||
{"redwood_trunk", "ethereal:redwood_trunk"},
|
||||
{"redwood_leaves", "ethereal:redwood_leaves"},
|
||||
{"willow_trunk", "ethereal:willow_trunk"},
|
||||
{"willow_twig", "ethereal:willow_twig"},
|
||||
{"yellow_trunk", "ethereal:yellow_trunk"},
|
||||
{"yellowleaves", "ethereal:yellowleaves"},
|
||||
{"palm_trunk", "ethereal:palm_trunk"},
|
||||
{"palmleaves", "ethereal:palmleaves"},
|
||||
{"frost_tree", "ethereal:frost_tree"},
|
||||
{"frost_leaves", "ethereal:frost_leaves"},
|
||||
{"default:junglegrass", "lib_ecology:default:junglegrass"},
|
||||
{"dry_shrub", "default:dry_shrub"},
|
||||
{"cactus", "default:cactus"},
|
||||
{"papyrus", "default:papyrus"},
|
||||
{"geranium", "flowers:geranium"},
|
||||
{"rose", "flowers:rose"},
|
||||
{"tulip", "flowers:tulip"},
|
||||
{"viola", "flowers:viola"},
|
||||
{"gerbera", "lib_ecology:gerbera"},
|
||||
{"fiddlehead", "lib_ecology:"},
|
||||
{"fern", "lib_ecology:fern"},
|
||||
{"arrow_arum", "lib_ecology:arrow_arum"},
|
||||
{"bird_of_paradise", "lib_ecology:bird_of_paradise"},
|
||||
{"calla_lily", "lib_ecology:calla_lily"},
|
||||
{"fire_flower", "lib_ecology:fire_flower"},
|
||||
{"giant_mushroom_stem", "lib_ecology:giant_mushroom_stem"},
|
||||
{"giant_mushroom_cap", "lib_ecology:giant_mushroom_cap"},
|
||||
{"hibiscus", "lib_ecology:hibiscus"},
|
||||
{"gerbera", "lib_ecology:gerbera"},
|
||||
|
||||
|
||||
-- Air and Ignore
|
||||
{"air", "air"},
|
||||
{"ignore", "ignore"},
|
||||
|
||||
{"ice", "default:ice"},
|
||||
{"thinice", "lib_ecology:thin_ice"},
|
||||
--{"crystal", "lib_ecology:glow_crystal"},
|
||||
--node["gem"]1 = minetest.get_content_id("lib_ecology:glow_gem")
|
||||
--node["gem"]2 = minetest.get_content_id("lib_ecology:glow_gem_2")
|
||||
--node["gem"]3 = minetest.get_content_id("lib_ecology:glow_gem_3")
|
||||
--node["gem"]4 = minetest.get_content_id("lib_ecology:glow_gem_4")
|
||||
--node["gem"]5 = minetest.get_content_id("lib_ecology:glow_gem_5")
|
||||
--node["saltgem"]1 = minetest.get_content_id("lib_ecology:salt_gem")
|
||||
--node["saltgem"]2 = minetest.get_content_id("lib_ecology:salt_gem_2")
|
||||
--node["saltgem"]3 = minetest.get_content_id("lib_ecology:salt_gem_3")
|
||||
--node["saltgem"]4 = minetest.get_content_id("lib_ecology:salt_gem_4")
|
||||
--node["saltgem"]5 = minetest.get_content_id("lib_ecology:salt_gem_5")
|
||||
--node["spike"]1 = minetest.get_content_id("lib_ecology:spike")
|
||||
--node["spike"]2 = minetest.get_content_id("lib_ecology:spike_2")
|
||||
--node["spike"]3 = minetest.get_content_id("lib_ecology:spike_3")
|
||||
--node["spike"]4 = minetest.get_content_id("lib_ecology:spike_4")
|
||||
--node["spike"]5 = minetest.get_content_id("lib_ecology:spike_5")
|
||||
{"moss", "lib_ecology:stone_with_moss"},
|
||||
{"lichen", "lib_ecology:stone_with_lichen"},
|
||||
{"algae", "lib_ecology:stone_with_algae"},
|
||||
{"salt", "lib_ecology:stone_with_salt"},
|
||||
--{"hcobble", "lib_ecology:hot_cobble"},
|
||||
--{"gobsidian", "lib_ecology:glow_obsidian"},
|
||||
--{"gobsidian2", "lib_ecology:glow_obsidian_2"},
|
||||
--{"coalblock", "default:coalblock"},
|
||||
{"obsidian", "default:obsidian"},
|
||||
--{"desand", "default:desert_sand"},
|
||||
--{"coaldust", "lib_ecology:coal_dust"},
|
||||
--{"fungus", "lib_ecology:fungus"},
|
||||
--{"mycena", "lib_ecology:mycena"},
|
||||
--{"worm", "lib_ecology:glow_worm"},
|
||||
{"icicle_up", "lib_ecology:icicle_up"},
|
||||
{"icicle_down", "lib_ecology:icicle_down"},
|
||||
{"flame", "lib_ecology:constant_flame"},
|
||||
--{"fountain", "lib_ecology:s_fountain"},
|
||||
--{"fortress", "lib_ecology:s_fortress"},
|
||||
|
||||
{"fungal_tree_fruit", "lib_ecology:fungal_tree_fruit"},
|
||||
}
|
||||
|
||||
for _, i in pairs(nodes) do
|
||||
node[i[1]] = minetest.get_content_id(i[2])
|
||||
end
|
||||
|
||||
node["fungal_tree_leaves"] = {}
|
||||
for _, name in pairs(lib_ecology.fungal_tree_leaves) do
|
||||
node["fungal_tree_leaves"][#node["fungal_tree_leaves"]+1] = minetest.get_content_id(name)
|
||||
end
|
||||
|
||||
local soil_translate = {}
|
||||
soil_translate["clay_over"] = {
|
||||
dirt = node["clay"],
|
||||
lawn = node["clay"],
|
||||
dry = node["clay"],
|
||||
snow = node["clay"],
|
||||
}
|
||||
soil_translate["clay_under"] = {
|
||||
dirt = node["dirt_clay"],
|
||||
lawn = node["lawn_clay"],
|
||||
dry = node["dry_clay"],
|
||||
snow = node["snow_clay"],
|
||||
}
|
||||
soil_translate["silt_over"] = {
|
||||
dirt = node["silt"],
|
||||
lawn = node["silt"],
|
||||
dry = node["silt"],
|
||||
snow = node["silt"],
|
||||
}
|
||||
soil_translate["silt_under"] = {
|
||||
dirt = node["dirt_silt"],
|
||||
lawn = node["lawn_silt"],
|
||||
dry = node["dry_silt"],
|
||||
snow = node["snow_silt"],
|
||||
}
|
||||
soil_translate["sand"] = {
|
||||
dirt = node["dirt_sand"],
|
||||
lawn = node["lawn_sand"],
|
||||
dry = node["dry_sand"],
|
||||
snow = node["snow_sand"],
|
||||
}
|
||||
soil_translate["dirt"] = {
|
||||
dirt = node["dirt"],
|
||||
lawn = node["dirt_with_grass"],
|
||||
dry = node["dirt_with_dry_grass"],
|
||||
snow = node["dirt_with_snow"],
|
||||
}
|
||||
|
||||
local water_lily_biomes = {"lib_ecology_rainforest_swamp", "lib_ecology_rainforest", "lib_ecology_savanna_swamp", "lib_ecology_savanna", "lib_ecology_deciduous_forest_swamp", "lib_ecology_deciduous_forest", "lib_ecology_desertstone_grassland", }
|
||||
local coral_biomes = {"lib_ecology_desert_ocean", "lib_ecology_savanna_ocean", "lib_ecology_rainforest_ocean", }
|
||||
|
||||
local clay_threshold = 1
|
||||
local silt_threshold = 1
|
||||
local sand_threshold = 0.75
|
||||
local dirt_threshold = 0.75
|
||||
|
||||
--local clay_threshold = vmg.define("clay_threshold", 1)
|
||||
--local silt_threshold = vmg.define("silt_threshold", 1)
|
||||
--local sand_threshold = vmg.define("sand_threshold", 0.75)
|
||||
--local dirt_threshold = vmg.define("dirt_threshold", 0.5)
|
||||
|
||||
local light_depth = -13
|
||||
local deep = -7000
|
||||
|
||||
-- Create a table of biome ids, so I can use the biomemap.
|
||||
if not lib_ecology.biome_ids then
|
||||
local i
|
||||
lib_ecology.biome_ids = {}
|
||||
for name, desc in pairs(minetest.registered_biomes) do
|
||||
i = minetest.get_biome_id(desc.name)
|
||||
lib_ecology.biome_ids[i] = desc.name
|
||||
end
|
||||
end
|
||||
|
||||
-- Get the content ids for all registered water plants.
|
||||
for _, desc in pairs(lib_ecology.water_plants) do
|
||||
if type(desc.decoration) == 'string' then
|
||||
desc.content_id = minetest.get_content_id(desc.decoration)
|
||||
elseif type(desc.decoration) == 'table' then
|
||||
desc.content_id = minetest.get_content_id(desc.decoration[1])
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local data = {}
|
||||
|
||||
|
||||
-- the mapgen function
|
||||
function lib_ecology.generate(minp, maxp, seed)
|
||||
local t0 = os.clock()
|
||||
|
||||
-- minp and maxp strings, used by logs
|
||||
local minps, maxps = minetest.pos_to_string(minp), minetest.pos_to_string(maxp)
|
||||
|
||||
-- The VoxelManipulator, a complicated but speedy method to set many nodes at the same time
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local heightmap = minetest.get_mapgen_object("heightmap")
|
||||
-- local heatmap = minetest.get_mapgen_object("heatmap")
|
||||
local gennotify = minetest.get_mapgen_object("gennotify")
|
||||
--print(dump(gennotify))
|
||||
local water_level = 1
|
||||
|
||||
vm:get_data(data) -- data is the original array of content IDs (solely or mostly air)
|
||||
-- Be careful: emin ≠ minp and emax ≠ maxp !
|
||||
-- The data array is not limited by minp and maxp. It exceeds it by 16 nodes in the 6 directions.
|
||||
-- The real limits of data array are emin and emax.
|
||||
-- The VoxelArea is used to convert a position into an index for the array.
|
||||
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local ystride = area.ystride -- Tip : the ystride of a VoxelArea is the number to add to the array index to get the index of the position above. It's faster because it avoids to completely recalculate the index.
|
||||
local zstride = area.zstride
|
||||
|
||||
local chulens = vector.add(vector.subtract(maxp, minp), 1) -- Size of the generated area, used by noisemaps
|
||||
local minp2d = pos2d(minp)
|
||||
|
||||
-- The biomemap is a table of biome index numbers for each horizontal
|
||||
-- location. It's created in the mapgen, and is right most of the time.
|
||||
-- It's off in about 1% of cases, for various reasons.
|
||||
-- Bear in mind that biomes can change from one voxel to the next.
|
||||
local biomemap = minetest.get_mapgen_object("biomemap")
|
||||
--local filename = "biome_coords.txt";
|
||||
--local path = minetest.get_worldpath()..'/'..filename;
|
||||
--local file = io.open( path, 'w' );
|
||||
|
||||
-- Calculate the noise values
|
||||
local n1 = lib_ecology.noisemap(1, minp2d, chulens)
|
||||
local n2 = lib_ecology.noisemap(2, minp2d, chulens)
|
||||
local n3 = lib_ecology.noisemap(3, minp2d, chulens)
|
||||
local n4 = lib_ecology.noisemap(4, minp2d, chulens)
|
||||
local n5 = lib_ecology.noisemap(5, minp2d, chulens)
|
||||
local n6 = lib_ecology.noisemap(6, minp, chulens)
|
||||
local n7 = lib_ecology.noisemap(7, minp2d, chulens)
|
||||
local n8 = lib_ecology.noisemap(8, minp, chulens)
|
||||
local n9 = lib_ecology.noisemap(9, minp, chulens)
|
||||
local n10 = lib_ecology.noisemap(10, minp, chulens)
|
||||
local n11 = lib_ecology.noisemap(11, minp, chulens)
|
||||
local n12 = lib_ecology.noisemap(12, minp, chulens)
|
||||
local n13 = lib_ecology.noisemap(13, minp2d, chulens)
|
||||
local n14 = lib_ecology.noisemap(14, minp2d, chulens)
|
||||
local n15 = lib_ecology.noisemap(15, minp2d, chulens)
|
||||
local n16 = lib_ecology.noisemap(16, minp2d, chulens)
|
||||
local n17 = lib_ecology.noisemap(17, minp2d, chulens)
|
||||
local n18 = lib_ecology.noisemap(18, minp2d, chulens)
|
||||
local n21 = lib_ecology.noisemap(21, minp2d, chulens)
|
||||
local n22 = lib_ecology.noisemap(22, minp2d, chulens)
|
||||
local n23 = lib_ecology.noisemap(23, minp2d, chulens)
|
||||
|
||||
local node_match_cache = {}
|
||||
|
||||
-- Mapgen preparation is now finished. Check the timer to know the elapsed time.
|
||||
local t1 = os.clock()
|
||||
|
||||
-- the mapgen algorithm
|
||||
local index_2d = 0
|
||||
local write = false
|
||||
local relight = false
|
||||
local huge_cave = false
|
||||
local hug
|
||||
|
||||
if lib_ecology.use_gennotify then
|
||||
if gennotify.alternative_cave then
|
||||
huge_cave = true
|
||||
end
|
||||
elseif maxp.y < -300 then
|
||||
if gennotify.alternative_cave then
|
||||
huge_cave = true
|
||||
end
|
||||
|
||||
hug = survey(data, area, maxp, minp, node['lava'], node['water'], node['air'])
|
||||
|
||||
if huge_cave ~= hug then
|
||||
print("fake gennotify screwed up")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local index_3d, air_count, ground
|
||||
local index_3d_below, index_3d_above, surround
|
||||
local v1, v2, v3, v4, v5, v7, v13, v14, v15, v16, v18
|
||||
local n, biome, sr, placeable, pos, count
|
||||
local stone_type, stone_depth, n23_val
|
||||
local soil, max
|
||||
|
||||
for z = minp.z, maxp.z do
|
||||
for x = minp.x, maxp.x do
|
||||
index_2d = index_2d + 1
|
||||
|
||||
index_3d = area:index(x, maxp.y, z) -- index of the data array, matching the position {x, y, z}
|
||||
air_count = 0
|
||||
ground = heightmap[index_2d]
|
||||
--if ground >= minp.y and ground <= maxp.y then
|
||||
-- local index_ground = index_3d - ystride * (maxp.y - ground)
|
||||
-- if data[index_ground] == node["air"] then
|
||||
-- print("*** bad heightmap at ("..x..","..ground..","..z..")")
|
||||
-- --ground = -31000
|
||||
-- end
|
||||
--end
|
||||
|
||||
v1, v2, v3, v4, v5, v7, v13, v14, v15, v16, v18 = n1[index_2d], n2[index_2d], n3[index_2d], n4[index_2d], n5[index_2d], n7[index_2d], n13[index_2d], n14[index_2d], n15[index_2d], n16[index_2d], n18[index_2d] -- take the noise values for 2D noises
|
||||
|
||||
for y = maxp.y, minp.y, -1 do -- for each node in vertical line
|
||||
index_3d_below = index_3d - ystride
|
||||
index_3d_above = index_3d + ystride
|
||||
surround = true
|
||||
|
||||
-- Determine if a plant/dirt block can be placed without showing.
|
||||
-- Avoid the edges of the chunk, just to make things easier.
|
||||
if y < maxp.y and x > minp.x and x < maxp.x and z > minp.z and z < maxp.z and (data[index_3d] == node["sand"] or data[index_3d] == node["dirt"]) then
|
||||
if data[index_3d_above] == node["river_water_source"] or data[index_3d_above] == node["water_source"] then
|
||||
-- Check to make sure that a plant root is fully surrounded.
|
||||
-- This is due to the kludgy way you have to make water plants
|
||||
-- in minetest, to avoid bubbles.
|
||||
for x1 = -1,1,2 do
|
||||
n = data[index_3d+x1]
|
||||
if n == node["river_water_source"] or n == node["water_source"] or n == node["air"] then
|
||||
surround = false
|
||||
end
|
||||
end
|
||||
for z1 = -zstride,zstride,2*zstride do
|
||||
n = data[index_3d+z1]
|
||||
if n == node["river_water_source"] or n == node["water_source"] or n == node["air"] then
|
||||
surround = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if y >= light_depth and (data[index_3d] == node["sand"] or data[index_3d] == node["dirt"]) and (data[index_3d_above] == node["water_source"] or data[index_3d_above] == node["river_water_source"]) then
|
||||
-- Check the biomes and plant water plants, if called for.
|
||||
biome = lib_ecology.biome_ids[biomemap[index_2d]]
|
||||
--file:write(biome .. " @: X " .. x .. ", Z " .. z .. "\n")
|
||||
if y < water_level and data[index_3d_above + ystride] == node["water_source"] and table.contains(coral_biomes, biome) and n21[index_2d] < -0.1 and math.random(1,3) ~= 1 then
|
||||
sr = math.random(1,100)
|
||||
if sr < 4 then
|
||||
data[index_3d_above] = node["brain_coral"]
|
||||
elseif sr < 6 then
|
||||
data[index_3d_above] = node["dragon_eye"]
|
||||
elseif sr < 35 then
|
||||
data[index_3d_above] = node["staghorn_coral"]
|
||||
elseif sr < 100 then
|
||||
data[index_3d_above] = node["pillar_coral"]
|
||||
end
|
||||
elseif surround then
|
||||
for _, desc in pairs(lib_ecology.water_plants) do
|
||||
placeable = false
|
||||
|
||||
if not node_match_cache[desc] then
|
||||
node_match_cache[desc] = {}
|
||||
end
|
||||
|
||||
if node_match_cache[desc][data[index_3d]] then
|
||||
placeable = node_match_cache[desc][data[index_3d]]
|
||||
else
|
||||
-- This is a great way to match all node type strings
|
||||
-- against a given node (or nodes). However, it's slow.
|
||||
-- To speed it up, we cache the results for each plant
|
||||
-- on each node, and avoid calling find_nodes every time.
|
||||
pos, count = minetest.find_nodes_in_area({x=x,y=y,z=z}, {x=x,y=y,z=z}, desc.place_on)
|
||||
if #pos > 0 then
|
||||
placeable = true
|
||||
end
|
||||
node_match_cache[desc][data[index_3d]] = placeable
|
||||
end
|
||||
|
||||
if placeable and desc.fill_ratio and desc.content_id then
|
||||
biome = lib_ecology.biome_ids[biomemap[index_2d]]
|
||||
--file:write(biome .. " @: X " .. x .. ", Z " .. z .. "\n")
|
||||
|
||||
if not desc.biomes or (biome and desc.biomes and table.contains(desc.biomes, biome)) then
|
||||
if math.random() <= desc.fill_ratio then
|
||||
data[index_3d] = desc.content_id
|
||||
write = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- on top of the water
|
||||
if y > minp.y and data[index_3d] == node["air"] and data[index_3d_below] == node["river_water_source"] then
|
||||
biome = lib_ecology.biome_ids[biomemap[index_2d]]
|
||||
--file:write(biome .. " @: X " .. x .. ", Z " .. z .. "\n")
|
||||
-- I haven't figured out what the decoration manager is
|
||||
-- doing with the noise functions, but this works ok.
|
||||
if table.contains(water_lily_biomes, biome) and n21[index_2d] > 0.5 and math.random(1,15) == 1 then
|
||||
data[index_3d] = node["waterlily"]
|
||||
write = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Handle caves.
|
||||
if (y < ground - 5 or y < -100) and (data[index_3d] == node["air"] or data[index_3d] == node["river_water_source"] or data[index_3d] == node["water_source"]) then
|
||||
relight = true
|
||||
|
||||
stone_type = node["stone"]
|
||||
stone_depth = 1
|
||||
n23_val = n23[index_2d] + n22[index_2d]
|
||||
if n23_val < -0.8 then
|
||||
if y < deep then
|
||||
stone_type = node["ice"]
|
||||
stone_depth = 2
|
||||
else
|
||||
stone_type = node["thinice"]
|
||||
stone_depth = 2
|
||||
end
|
||||
elseif n23_val < -0.7 then
|
||||
stone_type = node["lichen"]
|
||||
elseif n23_val < -0.3 then
|
||||
stone_type = node["moss"]
|
||||
elseif n23_val < 0.2 then
|
||||
stone_type = node["lichen"]
|
||||
elseif n23_val < 0.5 then
|
||||
stone_type = node["algae"]
|
||||
elseif n23_val < 0.6 then
|
||||
stone_type = node["salt"]
|
||||
stone_depth = 2
|
||||
elseif n23_val < 0.8 then
|
||||
stone_type = node["coalblock"]
|
||||
stone_depth = 2
|
||||
else
|
||||
stone_type = node["hcobble"]
|
||||
end
|
||||
-- "glow"
|
||||
|
||||
-- Change stone per biome.
|
||||
if data[index_3d_below] == node["stone"] then
|
||||
data[index_3d_below] = stone_type
|
||||
if stone_depth == 2 then
|
||||
data[index_3d_below - ystride] = stone_type
|
||||
end
|
||||
write = true
|
||||
end
|
||||
if data[index_3d_above] == node["stone"] then
|
||||
data[index_3d_above] = stone_type
|
||||
if stone_depth == 2 then
|
||||
data[index_3d_above + ystride] = stone_type
|
||||
end
|
||||
write = true
|
||||
end
|
||||
|
||||
if (data[index_3d_above] == node["lichen"] or data[index_3d_above] == node["moss"]) and math.random(1,20) == 1 then
|
||||
data[index_3d_above] = node["fungal_stone"]
|
||||
write = true
|
||||
end
|
||||
|
||||
if data[index_3d] == node["air"] then
|
||||
sr = math.random(1,1000)
|
||||
|
||||
-- fluids
|
||||
if (not huge_cave) and data[index_3d_below] == node["stone"] and sr < 10 then
|
||||
data[index_3d] = node["lava"]
|
||||
elseif (not huge_cave) and data[index_3d_below] == node["moss"] and sr < 10 then
|
||||
data[index_3d] = node["river_water_source"]
|
||||
-- hanging down
|
||||
elseif data[index_3d_above] == node["ice"] and sr < 80 then
|
||||
data[index_3d] = node["icicle_down"]
|
||||
write = true
|
||||
elseif (data[index_3d_above] == node["lichen"] or data[index_3d_above] == node["moss"] or data[index_3d_above] == node["algae"] or data[index_3d_above] == node["stone"]) and sr < 80 then
|
||||
if data[index_3d_above] == node["algae"] then
|
||||
data[index_3d] = node["stalactite_slimy"]
|
||||
elseif data[index_3d_above] == node["moss"] then
|
||||
data[index_3d] = node["stalactite_mossy"]
|
||||
else
|
||||
data[index_3d] = node["stalactite"]
|
||||
end
|
||||
write = true
|
||||
-- standing up
|
||||
elseif data[index_3d_below] == node["coalblock"] and sr < 20 then
|
||||
data[index_3d] = node["flame"]
|
||||
elseif data[index_3d_below] == node["ice"] and sr < 80 then
|
||||
data[index_3d] = node["icicle_up"]
|
||||
write = true
|
||||
elseif (data[index_3d_below] == node["lichen"] or data[index_3d_below] == node["algae"] or data[index_3d_below] == node["stone"] or data[index_3d_below] == node["moss"]) and sr < 80 then
|
||||
if data[index_3d_below] == node["algae"] then
|
||||
data[index_3d] = node["stalagmite_slimy"]
|
||||
elseif data[index_3d_below] == node["moss"] then
|
||||
data[index_3d] = node["stalagmite_mossy"]
|
||||
elseif data[index_3d_below] == node["lichen"] or data[index_3d_above] == node["stone"] then
|
||||
data[index_3d] = node["stalagmite"]
|
||||
end
|
||||
-- vegetation
|
||||
elseif (data[index_3d_below] == node["lichen"] or data[index_3d_below] == node["algae"]) and n23_val >= -0.7 then
|
||||
if sr < 110 then
|
||||
data[index_3d] = node["mushroom_red"]
|
||||
elseif sr < 140 then
|
||||
data[index_3d] = node["mushroom_brown"]
|
||||
elseif air_count > 1 and sr < 160 then
|
||||
data[index_3d_above] = node["mushroom_cap_huge"]
|
||||
data[index_3d] = node["mushroom_stem"]
|
||||
elseif air_count > 2 and sr < 170 then
|
||||
data[index_3d + 2 * ystride] = node["mushroom_cap_giant"]
|
||||
data[index_3d_above] = node["mushroom_stem"]
|
||||
data[index_3d] = node["mushroom_stem"]
|
||||
elseif huge_cave and air_count > 5 and sr < 180 then
|
||||
lib_ecology.make_fungal_tree(data, area, index_3d, math.random(2,math.min(air_count, 12)), node["fungal_tree_leaves"][math.random(1,#node["fungal_tree_leaves"])], node["fungal_tree_fruit"])
|
||||
data[index_3d_below] = node["dirt"]
|
||||
write = true
|
||||
elseif sr < 300 then
|
||||
data[index_3d_below] = node["dirt"]
|
||||
write = true
|
||||
end
|
||||
if data[index_3d] ~= node["air"] then
|
||||
data[index_3d_below] = node["dirt"]
|
||||
write = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if data[index_3d] == node["air"] then
|
||||
air_count = air_count + 1
|
||||
end
|
||||
end
|
||||
|
||||
if data[index_3d] == node["dirt"] or data[index_3d] == node["dirt_with_snow"] or data[index_3d] == node["dirt_with_grass"] or data[index_3d] == node["dirt_with_dry_grass"] or data[index_3d] == node["sand"] then
|
||||
-- Choose biome, by default normal dirt
|
||||
soil = "dirt"
|
||||
max = math.max(v13, v14, v15) -- the biome is the maximal of these 3 values.
|
||||
if max > dirt_threshold then -- if one of these values is bigger than dirt_threshold, make clayey, silty or sandy dirt, depending on the case. If none of clay, silt or sand is predominant, make normal dirt.
|
||||
if v13 == max then
|
||||
if v13 > clay_threshold then
|
||||
soil = "clay_over"
|
||||
else
|
||||
soil = "clay_under"
|
||||
end
|
||||
elseif v14 == max then
|
||||
if v14 > silt_threshold then
|
||||
soil = "silt_over"
|
||||
else
|
||||
soil = "silt_under"
|
||||
end
|
||||
else
|
||||
soil = "sand"
|
||||
end
|
||||
end
|
||||
|
||||
if data[index_3d] == node["dirt"] then
|
||||
data[index_3d] = soil_translate[soil].dirt
|
||||
write = true
|
||||
elseif data[index_3d] == node["dirt_with_snow"] then
|
||||
data[index_3d] = soil_translate[soil].snow
|
||||
write = true
|
||||
elseif data[index_3d] == node["dirt_with_grass"] then
|
||||
data[index_3d] = soil_translate[soil].lawn
|
||||
write = true
|
||||
elseif data[index_3d] == node["dirt_with_dry_grass"] then
|
||||
data[index_3d] = soil_translate[soil].dry
|
||||
write = true
|
||||
elseif data[index_3d] == node["sand"] then
|
||||
sr = math.random(1,50)
|
||||
if lib_ecology.glow and sr == 1 then
|
||||
data[index_3d] = node["glowing_sand"]
|
||||
write = true
|
||||
elseif sr < 10 then
|
||||
data[index_3d] = node["sand_with_rocks"]
|
||||
write = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if data[index_3d] ~= node["air"] then
|
||||
air_count = 0
|
||||
end
|
||||
index_3d = index_3d_below
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--file:write("BIOME DATA EOF")
|
||||
--file:close();
|
||||
|
||||
local t2 = os.clock()
|
||||
|
||||
-- execute voxelmanip boring stuff to write to the map...
|
||||
if write then
|
||||
vm:set_data(data)
|
||||
end
|
||||
|
||||
local t3 = os.clock()
|
||||
|
||||
if write then
|
||||
-- probably not necessary
|
||||
if relight then
|
||||
--vm:set_lighting({day = 10, night = 10})
|
||||
end
|
||||
|
||||
-- This seems to be necessary to avoid lighting problems.
|
||||
vm:calc_lighting()
|
||||
|
||||
-- probably not necessary
|
||||
--vm:update_liquids()
|
||||
end
|
||||
|
||||
local t4 = os.clock()
|
||||
|
||||
if write then
|
||||
vm:write_to_map()
|
||||
end
|
||||
|
||||
local t5 = os.clock()
|
||||
|
||||
table.insert(mapgen_times.noisemaps, 0)
|
||||
table.insert(mapgen_times.preparation, t1 - t0)
|
||||
table.insert(mapgen_times.loops, t2 - t1)
|
||||
table.insert(mapgen_times.writing, t3 - t2 + t5 - t4)
|
||||
table.insert(mapgen_times.liquid_lighting, t4 - t3)
|
||||
table.insert(mapgen_times.make_chunk, t5 - t0)
|
||||
|
||||
-- Deal with memory issues. This, of course, is supposed to be automatic.
|
||||
local mem = math.floor(collectgarbage("count")/1024)
|
||||
if mem > 500 then
|
||||
print("Valleys_c is manually collecting garbage as memory use has exceeded 500K.")
|
||||
collectgarbage("collect")
|
||||
end
|
||||
end
|
||||
|
||||
local function mean( t )
|
||||
local sum = 0
|
||||
local count= 0
|
||||
|
||||
for k,v in pairs(t) do
|
||||
if type(v) == 'number' then
|
||||
sum = sum + v
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
|
||||
return (sum / count)
|
||||
end
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
if #mapgen_times.make_chunk == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local average, standard_dev
|
||||
minetest.log("Valleys_C lua Mapgen Times:")
|
||||
|
||||
average = mean(mapgen_times.liquid_lighting)
|
||||
minetest.log(" liquid_lighting: - - - - - - - - - - - - "..average)
|
||||
|
||||
average = mean(mapgen_times.loops)
|
||||
minetest.log(" loops: - - - - - - - - - - - - - - - - - "..average)
|
||||
|
||||
average = mean(mapgen_times.make_chunk)
|
||||
minetest.log(" makeChunk: - - - - - - - - - - - - - - - "..average)
|
||||
|
||||
average = mean(mapgen_times.noisemaps)
|
||||
minetest.log(" noisemaps: - - - - - - - - - - - - - - - "..average)
|
||||
|
||||
average = mean(mapgen_times.preparation)
|
||||
minetest.log(" preparation: - - - - - - - - - - - - - - "..average)
|
||||
|
||||
average = mean(mapgen_times.writing)
|
||||
minetest.log(" writing: - - - - - - - - - - - - - - - - "..average)
|
||||
end)
|
||||
|
||||
|
||||
-- Call the mapgen function lib_ecology.generate on mapgen.
|
||||
-- (located in voxel.lua)
|
||||
minetest.register_on_generated(lib_ecology.generate)
|
||||
|
|
@ -0,0 +1,856 @@
|
|||
----------------------
|
||||
-- Voxel Manip Loop --
|
||||
----------------------
|
||||
|
||||
-- This is only used to handle cases the decoration manager can't,
|
||||
-- such as water plants and cave decorations.
|
||||
|
||||
|
||||
-- Define perlin noises used in this mapgen by default
|
||||
lib_ecology.noises = {}
|
||||
|
||||
|
||||
-- Noise 1 : Base Ground Height 2D
|
||||
--lib_ecology.noises[1] = {offset = -10, scale = 50, seed = 5202, spread = {x = 1024, y = 1024, z = 1024}, octaves = 6, persist = 0.4, lacunarity = 2},
|
||||
lib_ecology.noises[1] = {offset = -10, scale = 25, seed = 5202, spread = {x = 4096, y = 4096, z = 4096}, octaves = 6, persist = 0.4, lacunarity = 2}
|
||||
|
||||
-- Noise 2 : Valleys (River where around zero) 2D
|
||||
lib_ecology.noises[2] = {offset = 0, scale = 1, seed = -6050, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.6, lacunarity = 2}
|
||||
|
||||
-- Noise 3 : Valleys Depth 2D
|
||||
lib_ecology.noises[3] = {offset = 5, scale = 4, seed = -1914, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2}
|
||||
|
||||
-- Noise 4 : Valleys Profile (Higher values = Larger valleys) 2D
|
||||
lib_ecology.noises[4] = {offset = 0.6, scale = 0.5, seed = 777, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2}
|
||||
|
||||
-- Noise 5 : Inter-valleys slopes 2D
|
||||
lib_ecology.noises[5] = {offset = 0.5, scale = 0.5, seed = 746, spread = {x = 128, y = 128, z = 128}, octaves = 1, persist = 1, lacunarity = 2}
|
||||
|
||||
-- Noise 6 : Inter-valleys filling 3D
|
||||
lib_ecology.noises[6] = {offset = 0, scale = 1, seed = 1993, spread = {x = 256, y = 512, z = 256}, octaves = 6, persist = 0.8, lacunarity = 2}
|
||||
|
||||
-- Noise 7 : Dirt thickness 2D
|
||||
lib_ecology.noises[7] = {offset = 3, scale = 1.75, seed = 1605, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5, lacunarity = 2}
|
||||
|
||||
-- Noise 8 : Caves I 3D
|
||||
lib_ecology.noises[8] = {offset = 0, scale = 1, seed = -4640, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
|
||||
-- Noise 9 : Caves II 3D
|
||||
lib_ecology.noises[9] = {offset = 0, scale = 1, seed = 8804, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
|
||||
-- Noise 10 : Caves III 3D
|
||||
lib_ecology.noises[10] = {offset = 0, scale = 1, seed = -4780, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
|
||||
-- Noise 11 : Caves IV and Lava I 3D
|
||||
lib_ecology.noises[11] = {offset = 0, scale = 1, seed = -9969, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
|
||||
-- Noise 12 : Lava II (Geologic heat) 3D
|
||||
lib_ecology.noises[12] = {offset = 0, scale = 1, seed = 3314, spread = {x = 64, y = 64, z = 64}, octaves = 4, persist = 0.5, lacunarity = 2}
|
||||
|
||||
|
||||
|
||||
|
||||
-- Noise 13 : Clayey dirt noise 2D
|
||||
lib_ecology.noises[13] = {offset = 0, scale = 1, seed = 2835, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4}
|
||||
|
||||
-- Noise 14 : Silty dirt noise 2D
|
||||
lib_ecology.noises[14] = {offset = 0, scale = 1, seed = 6674, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4}
|
||||
|
||||
-- Noise 15 : Sandy dirt noise 2D
|
||||
lib_ecology.noises[15] = {offset = 0, scale = 1, seed = 6940, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4}
|
||||
|
||||
-- Noise 16 : Beaches 2D
|
||||
lib_ecology.noises[16] = {offset = 2, scale = 8, seed = 2349, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5, lacunarity = 2}
|
||||
|
||||
|
||||
-- Noise 17 : Temperature (not in maps) 3D
|
||||
lib_ecology.noises[17] = {offset = 2, scale = 1, seed = -1805, spread = {x = 768, y = 256, z = 768}, octaves = 4, persist = 0.5, lacunarity = 4}
|
||||
|
||||
-- Noise 18 : Humidity 2D
|
||||
lib_ecology.noises[18] = {offset = 0, scale = 1, seed = -5787, spread = {x = 243, y = 243, z = 243}, octaves = 4, persist = 0.5, lacunarity = 3}
|
||||
|
||||
|
||||
|
||||
-- Noise 21 : Water plants 2D
|
||||
lib_ecology.noises[21] = {offset = 0.0, scale = 1.0, spread = {x = 200, y = 200, z = 200}, seed = 33, octaves = 3, persist = 0.7, lacunarity = 2.0}
|
||||
|
||||
-- Noise 22 : Cave blend 2D
|
||||
lib_ecology.noises[22] = {offset = 0.0, scale = 0.1, spread = {x = 8, y = 8, z = 8}, seed = 4023, octaves = 2, persist = 1.0, lacunarity = 2.0}
|
||||
|
||||
-- Noise 23 : Cave noise 2D
|
||||
lib_ecology.noises[23] = {offset = 0.0, scale = 1.0, spread = {x = 400, y = 400, z = 400}, seed = 903, octaves = 3, persist = 0.5, lacunarity = 2.0}
|
||||
|
||||
-- function to get noisemaps
|
||||
function lib_ecology.noisemap(i, minp, chulens)
|
||||
local obj = minetest.get_perlin_map(lib_ecology.noises[i], chulens)
|
||||
if minp.z then
|
||||
return obj:get3dMap_flat(minp)
|
||||
else
|
||||
return obj:get2dMap_flat(minp)
|
||||
end
|
||||
end
|
||||
|
||||
-- useful function to convert a 3D pos to 2D
|
||||
function pos2d(pos)
|
||||
if type(pos) == "number" then
|
||||
return {x = pos, y = pos}
|
||||
elseif pos.z then
|
||||
return {x = pos.x, y = pos.z}
|
||||
else
|
||||
return {x = pos.x, y = pos.y}
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if a chunk contains a huge cave.
|
||||
-- This sucks. Use gennotify when possible.
|
||||
local function survey(data, area, maxp, minp, lava, water, air)
|
||||
local index_3d
|
||||
local space = 0
|
||||
for z = minp.z, maxp.z do
|
||||
for x = minp.x, maxp.x do
|
||||
index_3d = area:index(x, maxp.y, z)
|
||||
for y = maxp.y, minp.y, -1 do
|
||||
index_3d = index_3d - area.ystride
|
||||
-- The mapgen won't place lava or water near a huge cave.
|
||||
if data[index_3d] == lava or data[index_3d] == water then
|
||||
return false
|
||||
elseif data[index_3d] == air then
|
||||
space = space + 1
|
||||
end
|
||||
|
||||
-- This shortcut may skip lava or water, causing a false
|
||||
-- positive, but it can save a lot of time.
|
||||
-- This is an extremely poor way to check, but there aren't
|
||||
-- any good ways, and all the others take more cpu time.
|
||||
if space > 20000 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local mapgen_times = {
|
||||
liquid_lighting = {},
|
||||
loops = {},
|
||||
make_chunk = {},
|
||||
noisemaps = {},
|
||||
preparation = {},
|
||||
writing = {},
|
||||
}
|
||||
|
||||
|
||||
-- Define content IDs
|
||||
-- A content ID is a number that represents a node in the core of Minetest.
|
||||
-- Every nodename has its ID.
|
||||
-- The VoxelManipulator uses content IDs instead of nodenames.
|
||||
|
||||
local node = {}
|
||||
|
||||
local nodes = {
|
||||
-- Ground nodes
|
||||
{"sand_stone", "lib_materials:sand_stone"},
|
||||
{"brown_stone", "lib_materials:brown_stone"},
|
||||
{"granite", "lib_materials:granite"},
|
||||
{"marble", "lib_materials:marble"},
|
||||
{"basalt", "darkage:basalt"},
|
||||
{"chalk", "darkage:chalk"},
|
||||
{"darkdirt", "darkage:darkdirt"},
|
||||
{"gneiss", "darkage:gneiss"},
|
||||
{"darkdirt", "darkage:mud"},
|
||||
{"darkdirt", "darkage:ors"},
|
||||
{"darkdirt", "darkage:serpentine"},
|
||||
{"darkdirt", "darkage:shale"},
|
||||
{"darkdirt", "darkage:schist"},
|
||||
{"darkdirt", "darkage:silt"},
|
||||
{"darkdirt", "darkage:slate"},
|
||||
{"desertstone", "default:desert_stone"},
|
||||
{"desert_sandstone", "default:desert_sandstone"},
|
||||
{"sandstone", "default:sandstone"},
|
||||
{"silver_sandstone", "default:silver_sandstone"},
|
||||
{"stone", "default:stone"},
|
||||
{"gravel", "default:gravel"},
|
||||
{"dirt_with_grass", "default:dirt_with_grass"},
|
||||
{"dirt_with_dry_grass", "default:dirt_with_dry_grass"},
|
||||
{"dirt_with_snow", "default:dirt_with_snow"},
|
||||
{"dirt_with_rainforest_litter", "default:dirt_with_rainforest_litter"},
|
||||
{"dirt_with_coniferous_litter", "default:dirt_with_coniferous_litter"},
|
||||
{"dirt", "default:dirt"},
|
||||
{"green_dirt", "lib_ecology:green_dirt"},
|
||||
{"dry_dirt", "lib_ecology:dry_dirt"},
|
||||
{"bamboo_dirt", "lib_ecology:bamboo_dirt"},
|
||||
{"cold_dirt", "lib_ecology:cold_dirt"},
|
||||
{"crystal_dirt", "lib_ecology:crystal_dirt"},
|
||||
{"fiery_dirt", "lib_ecology:fiery_dirt"},
|
||||
{"gray_dirt", "lib_ecology:gray_dirt"},
|
||||
{"grove_dirt", "lib_ecology:grove_dirt"},
|
||||
{"jungle_dirt", "lib_ecology:jungle_dirt"},
|
||||
{"mushroom_dirt_dirt", "lib_ecology:mushroom_dirt_dirt"},
|
||||
{"prairie_dirt", "lib_ecology:prairie_dirt"},
|
||||
{"bamboo_dirt", "ethereal:bamboo_dirt"},
|
||||
{"cold_dirt", "ethereal:cold_dirt"},
|
||||
{"crystal_dirt", "ethereal:crystal_dirt"},
|
||||
{"fiery_dirt", "ethereal:fiery_dirt"},
|
||||
{"gray_dirt", "ethereal:gray_dirt"},
|
||||
{"grove_dirt", "ethereal:grove_dirt"},
|
||||
{"jungle_dirt", "ethereal:jungle_dirt"},
|
||||
{"mushroom_dirt_dirt", "ethereal:mushroom_dirt_dirt"},
|
||||
{"prairie_dirt", "ethereal:prairie_dirt"},
|
||||
{"quicksand", "lib_ecology:quicksand"},
|
||||
{"quicksand2", "lib_ecology:quicksand2"},
|
||||
{"quicksand", "ethereal:quicksand"},
|
||||
{"quicksand2", "ethereal:quicksand2"},
|
||||
{"desert_sand", "default:desert_sand"},
|
||||
{"silver_sand", "default:silver_sand"},
|
||||
{"sand", "default:sand"},
|
||||
{"clay", "default:clay"},
|
||||
{"river_water_source", "default:river_water_source"},
|
||||
{"water_source", "default:water_source"},
|
||||
{"lava", "default:lava_source"},
|
||||
|
||||
{"sand_with_rocks", "lib_ecology:sand_with_rocks"},
|
||||
--{"glowing_sand", "lib_ecology:glowing_sand"},
|
||||
{"fungal_stone", "lib_ecology:glowing_fungal_stone"},
|
||||
{"stalactite", "lib_ecology:stalactite"},
|
||||
{"stalactite_slimy", "lib_ecology:stalactite_slimy"},
|
||||
{"stalactite_mossy", "lib_ecology:stalactite_mossy"},
|
||||
{"stalagmite", "lib_ecology:stalagmite"},
|
||||
{"stalagmite_slimy", "lib_ecology:stalagmite_slimy"},
|
||||
{"stalagmite_mossy", "lib_ecology:stalagmite_mossy"},
|
||||
{"mushroom_cap_giant", "lib_ecology:giant_mushroom_cap"},
|
||||
{"mushroom_cap_huge", "lib_ecology:huge_mushroom_cap"},
|
||||
{"mushroom_stem", "lib_ecology:giant_mushroom_stem"},
|
||||
{"mushroom_red", "flowers:mushroom_red"},
|
||||
{"mushroom_brown", "flowers:mushroom_brown"},
|
||||
{"waterlily", "flowers:waterlily"},
|
||||
{"brain_coral", "lib_ecology:brain_coral"},
|
||||
--{"dragon_eye", "lib_ecology:dragon_eye"},
|
||||
{"pillar_coral", "lib_ecology:pillar_coral"},
|
||||
{"staghorn_coral", "lib_ecology:staghorn_coral"},
|
||||
{"coral_brown", "default:coral_brown"},
|
||||
{"coral_orange", "default:coral_orange"},
|
||||
{"coral_skeleton", "default:coral_skeleton"},
|
||||
|
||||
|
||||
{"dirt_clay", "lib_ecology:dirt_clayey"},
|
||||
{"lawn_clay", "lib_ecology:dirt_clayey_with_grass"},
|
||||
{"dry_clay", "lib_ecology:dirt_clayey_with_dry_grass"},
|
||||
{"snow_clay", "lib_ecology:dirt_clayey_with_snow"},
|
||||
{"dirt_silt", "lib_ecology:dirt_silty"},
|
||||
{"lawn_silt", "lib_ecology:dirt_silty_with_grass"},
|
||||
{"dry_silt", "lib_ecology:dirt_silty_with_dry_grass"},
|
||||
{"snow_silt", "lib_ecology:dirt_silty_with_snow"},
|
||||
{"dirt_sand", "lib_ecology:dirt_sandy"},
|
||||
{"lawn_sand", "lib_ecology:dirt_sandy_with_grass"},
|
||||
{"dry_sand", "lib_ecology:dirt_sandy_with_dry_grass"},
|
||||
{"snow_sand", "lib_ecology:dirt_sandy_with_snow"},
|
||||
{"silt", "lib_ecology:silt"},
|
||||
{"clay", "lib_ecology:red_clay"},
|
||||
|
||||
-- Air and Ignore
|
||||
{"air", "air"},
|
||||
{"ignore", "ignore"},
|
||||
|
||||
{"ice", "default:ice"},
|
||||
{"thinice", "lib_ecology:thin_ice"},
|
||||
--{"crystal", "lib_ecology:glow_crystal"},
|
||||
--node["gem"]1 = minetest.get_content_id("lib_ecology:glow_gem")
|
||||
--node["gem"]2 = minetest.get_content_id("lib_ecology:glow_gem_2")
|
||||
--node["gem"]3 = minetest.get_content_id("lib_ecology:glow_gem_3")
|
||||
--node["gem"]4 = minetest.get_content_id("lib_ecology:glow_gem_4")
|
||||
--node["gem"]5 = minetest.get_content_id("lib_ecology:glow_gem_5")
|
||||
--node["saltgem"]1 = minetest.get_content_id("lib_ecology:salt_gem")
|
||||
--node["saltgem"]2 = minetest.get_content_id("lib_ecology:salt_gem_2")
|
||||
--node["saltgem"]3 = minetest.get_content_id("lib_ecology:salt_gem_3")
|
||||
--node["saltgem"]4 = minetest.get_content_id("lib_ecology:salt_gem_4")
|
||||
--node["saltgem"]5 = minetest.get_content_id("lib_ecology:salt_gem_5")
|
||||
--node["spike"]1 = minetest.get_content_id("lib_ecology:spike")
|
||||
--node["spike"]2 = minetest.get_content_id("lib_ecology:spike_2")
|
||||
--node["spike"]3 = minetest.get_content_id("lib_ecology:spike_3")
|
||||
--node["spike"]4 = minetest.get_content_id("lib_ecology:spike_4")
|
||||
--node["spike"]5 = minetest.get_content_id("lib_ecology:spike_5")
|
||||
{"moss", "lib_ecology:stone_with_moss"},
|
||||
{"lichen", "lib_ecology:stone_with_lichen"},
|
||||
{"algae", "lib_ecology:stone_with_algae"},
|
||||
{"salt", "lib_ecology:stone_with_salt"},
|
||||
--{"hcobble", "lib_ecology:hot_cobble"},
|
||||
--{"gobsidian", "lib_ecology:glow_obsidian"},
|
||||
--{"gobsidian2", "lib_ecology:glow_obsidian_2"},
|
||||
--{"coalblock", "default:coalblock"},
|
||||
{"obsidian", "default:obsidian"},
|
||||
--{"desand", "default:desert_sand"},
|
||||
--{"coaldust", "lib_ecology:coal_dust"},
|
||||
--{"fungus", "lib_ecology:fungus"},
|
||||
--{"mycena", "lib_ecology:mycena"},
|
||||
--{"worm", "lib_ecology:glow_worm"},
|
||||
{"icicle_up", "lib_ecology:icicle_up"},
|
||||
{"icicle_down", "lib_ecology:icicle_down"},
|
||||
{"flame", "lib_ecology:constant_flame"},
|
||||
--{"fountain", "lib_ecology:s_fountain"},
|
||||
--{"fortress", "lib_ecology:s_fortress"},
|
||||
|
||||
{"fungal_tree_fruit", "lib_ecology:fungal_tree_fruit"},
|
||||
}
|
||||
|
||||
for _, i in pairs(nodes) do
|
||||
node[i[1]] = minetest.get_content_id(i[2])
|
||||
end
|
||||
|
||||
node["fungal_tree_leaves"] = {}
|
||||
for _, name in pairs(lib_ecology.fungal_tree_leaves) do
|
||||
node["fungal_tree_leaves"][#node["fungal_tree_leaves"]+1] = minetest.get_content_id(name)
|
||||
end
|
||||
|
||||
local soil_translate = {}
|
||||
soil_translate["clay_over"] = {
|
||||
dirt = node["clay"],
|
||||
lawn = node["clay"],
|
||||
dry = node["clay"],
|
||||
snow = node["clay"],
|
||||
}
|
||||
soil_translate["clay_under"] = {
|
||||
dirt = node["dirt_clay"],
|
||||
lawn = node["lawn_clay"],
|
||||
dry = node["dry_clay"],
|
||||
snow = node["snow_clay"],
|
||||
}
|
||||
soil_translate["silt_over"] = {
|
||||
dirt = node["silt"],
|
||||
lawn = node["silt"],
|
||||
dry = node["silt"],
|
||||
snow = node["silt"],
|
||||
}
|
||||
soil_translate["silt_under"] = {
|
||||
dirt = node["dirt_silt"],
|
||||
lawn = node["lawn_silt"],
|
||||
dry = node["dry_silt"],
|
||||
snow = node["snow_silt"],
|
||||
}
|
||||
soil_translate["sand"] = {
|
||||
dirt = node["dirt_sand"],
|
||||
lawn = node["lawn_sand"],
|
||||
dry = node["dry_sand"],
|
||||
snow = node["snow_sand"],
|
||||
}
|
||||
soil_translate["dirt"] = {
|
||||
dirt = node["dirt"],
|
||||
lawn = node["dirt_with_grass"],
|
||||
dry = node["dirt_with_dry_grass"],
|
||||
snow = node["dirt_with_snow"],
|
||||
}
|
||||
|
||||
local water_lily_biomes = {"lib_ecology_rainforest_swamp", "lib_ecology_rainforest", "lib_ecology_savanna_swamp", "lib_ecology_savanna", "lib_ecology_deciduous_forest_swamp", "lib_ecology_deciduous_forest", "lib_ecology_desertstone_grassland", }
|
||||
local coral_biomes = {"lib_ecology_desert_ocean", "lib_ecology_savanna_ocean", "lib_ecology_rainforest_ocean", }
|
||||
|
||||
local clay_threshold = 1
|
||||
local silt_threshold = 1
|
||||
local sand_threshold = 0.75
|
||||
local dirt_threshold = 0.75
|
||||
|
||||
--local clay_threshold = vmg.define("clay_threshold", 1)
|
||||
--local silt_threshold = vmg.define("silt_threshold", 1)
|
||||
--local sand_threshold = vmg.define("sand_threshold", 0.75)
|
||||
--local dirt_threshold = vmg.define("dirt_threshold", 0.5)
|
||||
|
||||
local light_depth = -13
|
||||
local deep = -7000
|
||||
|
||||
-- Create a table of biome ids, so I can use the biomemap.
|
||||
if not lib_ecology.biome_ids then
|
||||
local i
|
||||
lib_ecology.biome_ids = {}
|
||||
for name, desc in pairs(minetest.registered_biomes) do
|
||||
i = minetest.get_biome_id(desc.name)
|
||||
lib_ecology.biome_ids[i] = desc.name
|
||||
end
|
||||
end
|
||||
|
||||
-- Get the content ids for all registered water plants.
|
||||
for _, desc in pairs(lib_ecology.water_plants) do
|
||||
if type(desc.decoration) == 'string' then
|
||||
desc.content_id = minetest.get_content_id(desc.decoration)
|
||||
elseif type(desc.decoration) == 'table' then
|
||||
desc.content_id = minetest.get_content_id(desc.decoration[1])
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local data = {}
|
||||
|
||||
|
||||
-- the mapgen function
|
||||
function lib_ecology.generate(minp, maxp, seed)
|
||||
local t0 = os.clock()
|
||||
|
||||
-- minp and maxp strings, used by logs
|
||||
local minps, maxps = minetest.pos_to_string(minp), minetest.pos_to_string(maxp)
|
||||
|
||||
-- The VoxelManipulator, a complicated but speedy method to set many nodes at the same time
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local heightmap = minetest.get_mapgen_object("heightmap")
|
||||
-- local heatmap = minetest.get_mapgen_object("heatmap")
|
||||
local gennotify = minetest.get_mapgen_object("gennotify")
|
||||
--print(dump(gennotify))
|
||||
local water_level = 1
|
||||
|
||||
vm:get_data(data) -- data is the original array of content IDs (solely or mostly air)
|
||||
-- Be careful: emin ≠ minp and emax ≠ maxp !
|
||||
-- The data array is not limited by minp and maxp. It exceeds it by 16 nodes in the 6 directions.
|
||||
-- The real limits of data array are emin and emax.
|
||||
-- The VoxelArea is used to convert a position into an index for the array.
|
||||
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local ystride = area.ystride -- Tip : the ystride of a VoxelArea is the number to add to the array index to get the index of the position above. It's faster because it avoids to completely recalculate the index.
|
||||
local zstride = area.zstride
|
||||
|
||||
local chulens = vector.add(vector.subtract(maxp, minp), 1) -- Size of the generated area, used by noisemaps
|
||||
local minp2d = pos2d(minp)
|
||||
|
||||
-- The biomemap is a table of biome index numbers for each horizontal
|
||||
-- location. It's created in the mapgen, and is right most of the time.
|
||||
-- It's off in about 1% of cases, for various reasons.
|
||||
-- Bear in mind that biomes can change from one voxel to the next.
|
||||
local biomemap = minetest.get_mapgen_object("biomemap")
|
||||
--local filename = "biome_coords.txt";
|
||||
--local path = minetest.get_worldpath()..'/'..filename;
|
||||
--local file = io.open( path, 'w' );
|
||||
|
||||
-- Calculate the noise values
|
||||
local n1 = lib_ecology.noisemap(1, minp2d, chulens)
|
||||
local n2 = lib_ecology.noisemap(2, minp2d, chulens)
|
||||
local n3 = lib_ecology.noisemap(3, minp2d, chulens)
|
||||
local n4 = lib_ecology.noisemap(4, minp2d, chulens)
|
||||
local n5 = lib_ecology.noisemap(5, minp2d, chulens)
|
||||
local n6 = lib_ecology.noisemap(6, minp, chulens)
|
||||
local n7 = lib_ecology.noisemap(7, minp2d, chulens)
|
||||
local n8 = lib_ecology.noisemap(8, minp, chulens)
|
||||
local n9 = lib_ecology.noisemap(9, minp, chulens)
|
||||
local n10 = lib_ecology.noisemap(10, minp, chulens)
|
||||
local n11 = lib_ecology.noisemap(11, minp, chulens)
|
||||
local n12 = lib_ecology.noisemap(12, minp, chulens)
|
||||
local n13 = lib_ecology.noisemap(13, minp2d, chulens)
|
||||
local n14 = lib_ecology.noisemap(14, minp2d, chulens)
|
||||
local n15 = lib_ecology.noisemap(15, minp2d, chulens)
|
||||
local n16 = lib_ecology.noisemap(16, minp2d, chulens)
|
||||
local n17 = lib_ecology.noisemap(17, minp2d, chulens)
|
||||
local n18 = lib_ecology.noisemap(18, minp2d, chulens)
|
||||
local n21 = lib_ecology.noisemap(21, minp2d, chulens)
|
||||
local n22 = lib_ecology.noisemap(22, minp2d, chulens)
|
||||
local n23 = lib_ecology.noisemap(23, minp2d, chulens)
|
||||
|
||||
local node_match_cache = {}
|
||||
|
||||
-- Mapgen preparation is now finished. Check the timer to know the elapsed time.
|
||||
local t1 = os.clock()
|
||||
|
||||
-- the mapgen algorithm
|
||||
local index_2d = 0
|
||||
local write = false
|
||||
local relight = false
|
||||
local huge_cave = false
|
||||
local hug
|
||||
|
||||
if lib_ecology.use_gennotify then
|
||||
if gennotify.alternative_cave then
|
||||
huge_cave = true
|
||||
end
|
||||
elseif maxp.y < -300 then
|
||||
if gennotify.alternative_cave then
|
||||
huge_cave = true
|
||||
end
|
||||
|
||||
hug = survey(data, area, maxp, minp, node['lava'], node['water'], node['air'])
|
||||
|
||||
if huge_cave ~= hug then
|
||||
print("fake gennotify screwed up")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local index_3d, air_count, ground
|
||||
local index_3d_below, index_3d_above, surround
|
||||
local v1, v2, v3, v4, v5, v7, v13, v14, v15, v16, v18
|
||||
local n, biome, sr, placeable, pos, count
|
||||
local stone_type, stone_depth, n23_val
|
||||
local soil, max
|
||||
|
||||
for z = minp.z, maxp.z do
|
||||
for x = minp.x, maxp.x do
|
||||
index_2d = index_2d + 1
|
||||
|
||||
index_3d = area:index(x, maxp.y, z) -- index of the data array, matching the position {x, y, z}
|
||||
air_count = 0
|
||||
ground = heightmap[index_2d]
|
||||
--if ground >= minp.y and ground <= maxp.y then
|
||||
-- local index_ground = index_3d - ystride * (maxp.y - ground)
|
||||
-- if data[index_ground] == node["air"] then
|
||||
-- print("*** bad heightmap at ("..x..","..ground..","..z..")")
|
||||
-- --ground = -31000
|
||||
-- end
|
||||
--end
|
||||
|
||||
v1, v2, v3, v4, v5, v7, v13, v14, v15, v16, v18 = n1[index_2d], n2[index_2d], n3[index_2d], n4[index_2d], n5[index_2d], n7[index_2d], n13[index_2d], n14[index_2d], n15[index_2d], n16[index_2d], n18[index_2d] -- take the noise values for 2D noises
|
||||
|
||||
for y = maxp.y, minp.y, -1 do -- for each node in vertical line
|
||||
index_3d_below = index_3d - ystride
|
||||
index_3d_above = index_3d + ystride
|
||||
surround = true
|
||||
|
||||
-- Determine if a plant/dirt block can be placed without showing.
|
||||
-- Avoid the edges of the chunk, just to make things easier.
|
||||
if y < maxp.y and x > minp.x and x < maxp.x and z > minp.z and z < maxp.z and (data[index_3d] == node["sand"] or data[index_3d] == node["dirt"]) then
|
||||
if data[index_3d_above] == node["river_water_source"] or data[index_3d_above] == node["water_source"] then
|
||||
-- Check to make sure that a plant root is fully surrounded.
|
||||
-- This is due to the kludgy way you have to make water plants
|
||||
-- in minetest, to avoid bubbles.
|
||||
for x1 = -1,1,2 do
|
||||
n = data[index_3d+x1]
|
||||
if n == node["river_water_source"] or n == node["water_source"] or n == node["air"] then
|
||||
surround = false
|
||||
end
|
||||
end
|
||||
for z1 = -zstride,zstride,2*zstride do
|
||||
n = data[index_3d+z1]
|
||||
if n == node["river_water_source"] or n == node["water_source"] or n == node["air"] then
|
||||
surround = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if y >= light_depth and (data[index_3d] == node["sand"] or data[index_3d] == node["dirt"]) and (data[index_3d_above] == node["water_source"] or data[index_3d_above] == node["river_water_source"]) then
|
||||
-- Check the biomes and plant water plants, if called for.
|
||||
biome = lib_ecology.biome_ids[biomemap[index_2d]]
|
||||
--file:write(biome .. " @: X " .. x .. ", Z " .. z .. "\n")
|
||||
if y < water_level and data[index_3d_above + ystride] == node["water_source"] and table.contains(coral_biomes, biome) and n21[index_2d] < -0.1 and math.random(1,3) ~= 1 then
|
||||
sr = math.random(1,100)
|
||||
if sr < 4 then
|
||||
data[index_3d_above] = node["brain_coral"]
|
||||
elseif sr < 6 then
|
||||
data[index_3d_above] = node["dragon_eye"]
|
||||
elseif sr < 35 then
|
||||
data[index_3d_above] = node["staghorn_coral"]
|
||||
elseif sr < 100 then
|
||||
data[index_3d_above] = node["pillar_coral"]
|
||||
end
|
||||
elseif surround then
|
||||
for _, desc in pairs(lib_ecology.water_plants) do
|
||||
placeable = false
|
||||
|
||||
if not node_match_cache[desc] then
|
||||
node_match_cache[desc] = {}
|
||||
end
|
||||
|
||||
if node_match_cache[desc][data[index_3d]] then
|
||||
placeable = node_match_cache[desc][data[index_3d]]
|
||||
else
|
||||
-- This is a great way to match all node type strings
|
||||
-- against a given node (or nodes). However, it's slow.
|
||||
-- To speed it up, we cache the results for each plant
|
||||
-- on each node, and avoid calling find_nodes every time.
|
||||
pos, count = minetest.find_nodes_in_area({x=x,y=y,z=z}, {x=x,y=y,z=z}, desc.place_on)
|
||||
if #pos > 0 then
|
||||
placeable = true
|
||||
end
|
||||
node_match_cache[desc][data[index_3d]] = placeable
|
||||
end
|
||||
|
||||
if placeable and desc.fill_ratio and desc.content_id then
|
||||
biome = lib_ecology.biome_ids[biomemap[index_2d]]
|
||||
--file:write(biome .. " @: X " .. x .. ", Z " .. z .. "\n")
|
||||
|
||||
if not desc.biomes or (biome and desc.biomes and table.contains(desc.biomes, biome)) then
|
||||
if math.random() <= desc.fill_ratio then
|
||||
data[index_3d] = desc.content_id
|
||||
write = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- on top of the water
|
||||
if y > minp.y and data[index_3d] == node["air"] and data[index_3d_below] == node["river_water_source"] then
|
||||
biome = lib_ecology.biome_ids[biomemap[index_2d]]
|
||||
--file:write(biome .. " @: X " .. x .. ", Z " .. z .. "\n")
|
||||
-- I haven't figured out what the decoration manager is
|
||||
-- doing with the noise functions, but this works ok.
|
||||
if table.contains(water_lily_biomes, biome) and n21[index_2d] > 0.5 and math.random(1,15) == 1 then
|
||||
data[index_3d] = node["waterlily"]
|
||||
write = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Handle caves.
|
||||
if (y < ground - 5 or y < -100) and (data[index_3d] == node["air"] or data[index_3d] == node["river_water_source"] or data[index_3d] == node["water_source"]) then
|
||||
relight = true
|
||||
|
||||
stone_type = node["stone"]
|
||||
stone_depth = 1
|
||||
n23_val = n23[index_2d] + n22[index_2d]
|
||||
if n23_val < -0.8 then
|
||||
if y < deep then
|
||||
stone_type = node["ice"]
|
||||
stone_depth = 2
|
||||
else
|
||||
stone_type = node["thinice"]
|
||||
stone_depth = 2
|
||||
end
|
||||
elseif n23_val < -0.7 then
|
||||
stone_type = node["lichen"]
|
||||
elseif n23_val < -0.3 then
|
||||
stone_type = node["moss"]
|
||||
elseif n23_val < 0.2 then
|
||||
stone_type = node["lichen"]
|
||||
elseif n23_val < 0.5 then
|
||||
stone_type = node["algae"]
|
||||
elseif n23_val < 0.6 then
|
||||
stone_type = node["salt"]
|
||||
stone_depth = 2
|
||||
elseif n23_val < 0.8 then
|
||||
stone_type = node["coalblock"]
|
||||
stone_depth = 2
|
||||
else
|
||||
stone_type = node["hcobble"]
|
||||
end
|
||||
-- "glow"
|
||||
|
||||
-- Change stone per biome.
|
||||
if data[index_3d_below] == node["stone"] then
|
||||
data[index_3d_below] = stone_type
|
||||
if stone_depth == 2 then
|
||||
data[index_3d_below - ystride] = stone_type
|
||||
end
|
||||
write = true
|
||||
end
|
||||
if data[index_3d_above] == node["stone"] then
|
||||
data[index_3d_above] = stone_type
|
||||
if stone_depth == 2 then
|
||||
data[index_3d_above + ystride] = stone_type
|
||||
end
|
||||
write = true
|
||||
end
|
||||
|
||||
if (data[index_3d_above] == node["lichen"] or data[index_3d_above] == node["moss"]) and math.random(1,20) == 1 then
|
||||
data[index_3d_above] = node["fungal_stone"]
|
||||
write = true
|
||||
end
|
||||
|
||||
if data[index_3d] == node["air"] then
|
||||
sr = math.random(1,1000)
|
||||
|
||||
-- fluids
|
||||
if (not huge_cave) and data[index_3d_below] == node["stone"] and sr < 10 then
|
||||
data[index_3d] = node["lava"]
|
||||
elseif (not huge_cave) and data[index_3d_below] == node["moss"] and sr < 10 then
|
||||
data[index_3d] = node["river_water_source"]
|
||||
-- hanging down
|
||||
elseif data[index_3d_above] == node["ice"] and sr < 80 then
|
||||
data[index_3d] = node["icicle_down"]
|
||||
write = true
|
||||
elseif (data[index_3d_above] == node["lichen"] or data[index_3d_above] == node["moss"] or data[index_3d_above] == node["algae"] or data[index_3d_above] == node["stone"]) and sr < 80 then
|
||||
if data[index_3d_above] == node["algae"] then
|
||||
data[index_3d] = node["stalactite_slimy"]
|
||||
elseif data[index_3d_above] == node["moss"] then
|
||||
data[index_3d] = node["stalactite_mossy"]
|
||||
else
|
||||
data[index_3d] = node["stalactite"]
|
||||
end
|
||||
write = true
|
||||
-- standing up
|
||||
elseif data[index_3d_below] == node["coalblock"] and sr < 20 then
|
||||
data[index_3d] = node["flame"]
|
||||
elseif data[index_3d_below] == node["ice"] and sr < 80 then
|
||||
data[index_3d] = node["icicle_up"]
|
||||
write = true
|
||||
elseif (data[index_3d_below] == node["lichen"] or data[index_3d_below] == node["algae"] or data[index_3d_below] == node["stone"] or data[index_3d_below] == node["moss"]) and sr < 80 then
|
||||
if data[index_3d_below] == node["algae"] then
|
||||
data[index_3d] = node["stalagmite_slimy"]
|
||||
elseif data[index_3d_below] == node["moss"] then
|
||||
data[index_3d] = node["stalagmite_mossy"]
|
||||
elseif data[index_3d_below] == node["lichen"] or data[index_3d_above] == node["stone"] then
|
||||
data[index_3d] = node["stalagmite"]
|
||||
end
|
||||
-- vegetation
|
||||
elseif (data[index_3d_below] == node["lichen"] or data[index_3d_below] == node["algae"]) and n23_val >= -0.7 then
|
||||
if sr < 110 then
|
||||
data[index_3d] = node["mushroom_red"]
|
||||
elseif sr < 140 then
|
||||
data[index_3d] = node["mushroom_brown"]
|
||||
elseif air_count > 1 and sr < 160 then
|
||||
data[index_3d_above] = node["mushroom_cap_huge"]
|
||||
data[index_3d] = node["mushroom_stem"]
|
||||
elseif air_count > 2 and sr < 170 then
|
||||
data[index_3d + 2 * ystride] = node["mushroom_cap_giant"]
|
||||
data[index_3d_above] = node["mushroom_stem"]
|
||||
data[index_3d] = node["mushroom_stem"]
|
||||
elseif huge_cave and air_count > 5 and sr < 180 then
|
||||
lib_ecology.make_fungal_tree(data, area, index_3d, math.random(2,math.min(air_count, 12)), node["fungal_tree_leaves"][math.random(1,#node["fungal_tree_leaves"])], node["fungal_tree_fruit"])
|
||||
data[index_3d_below] = node["dirt"]
|
||||
write = true
|
||||
elseif sr < 300 then
|
||||
data[index_3d_below] = node["dirt"]
|
||||
write = true
|
||||
end
|
||||
if data[index_3d] ~= node["air"] then
|
||||
data[index_3d_below] = node["dirt"]
|
||||
write = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if data[index_3d] == node["air"] then
|
||||
air_count = air_count + 1
|
||||
end
|
||||
end
|
||||
|
||||
if data[index_3d] == node["dirt"] or data[index_3d] == node["dirt_with_snow"] or data[index_3d] == node["dirt_with_grass"] or data[index_3d] == node["dirt_with_dry_grass"] or data[index_3d] == node["sand"] then
|
||||
-- Choose biome, by default normal dirt
|
||||
soil = "dirt"
|
||||
max = math.max(v13, v14, v15) -- the biome is the maximal of these 3 values.
|
||||
if max > dirt_threshold then -- if one of these values is bigger than dirt_threshold, make clayey, silty or sandy dirt, depending on the case. If none of clay, silt or sand is predominant, make normal dirt.
|
||||
if v13 == max then
|
||||
if v13 > clay_threshold then
|
||||
soil = "clay_over"
|
||||
else
|
||||
soil = "clay_under"
|
||||
end
|
||||
elseif v14 == max then
|
||||
if v14 > silt_threshold then
|
||||
soil = "silt_over"
|
||||
else
|
||||
soil = "silt_under"
|
||||
end
|
||||
else
|
||||
soil = "sand"
|
||||
end
|
||||
end
|
||||
|
||||
if data[index_3d] == node["dirt"] then
|
||||
data[index_3d] = soil_translate[soil].dirt
|
||||
write = true
|
||||
elseif data[index_3d] == node["dirt_with_snow"] then
|
||||
data[index_3d] = soil_translate[soil].snow
|
||||
write = true
|
||||
elseif data[index_3d] == node["dirt_with_grass"] then
|
||||
data[index_3d] = soil_translate[soil].lawn
|
||||
write = true
|
||||
elseif data[index_3d] == node["dirt_with_dry_grass"] then
|
||||
data[index_3d] = soil_translate[soil].dry
|
||||
write = true
|
||||
elseif data[index_3d] == node["sand"] then
|
||||
sr = math.random(1,50)
|
||||
if lib_ecology.glow and sr == 1 then
|
||||
data[index_3d] = node["glowing_sand"]
|
||||
write = true
|
||||
elseif sr < 10 then
|
||||
data[index_3d] = node["sand_with_rocks"]
|
||||
write = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if data[index_3d] ~= node["air"] then
|
||||
air_count = 0
|
||||
end
|
||||
index_3d = index_3d_below
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--file:write("BIOME DATA EOF")
|
||||
--file:close();
|
||||
|
||||
local t2 = os.clock()
|
||||
|
||||
-- execute voxelmanip boring stuff to write to the map...
|
||||
if write then
|
||||
vm:set_data(data)
|
||||
end
|
||||
|
||||
local t3 = os.clock()
|
||||
|
||||
if write then
|
||||
-- probably not necessary
|
||||
if relight then
|
||||
--vm:set_lighting({day = 10, night = 10})
|
||||
end
|
||||
|
||||
-- This seems to be necessary to avoid lighting problems.
|
||||
vm:calc_lighting()
|
||||
|
||||
-- probably not necessary
|
||||
--vm:update_liquids()
|
||||
end
|
||||
|
||||
local t4 = os.clock()
|
||||
|
||||
if write then
|
||||
vm:write_to_map()
|
||||
end
|
||||
|
||||
local t5 = os.clock()
|
||||
|
||||
table.insert(mapgen_times.noisemaps, 0)
|
||||
table.insert(mapgen_times.preparation, t1 - t0)
|
||||
table.insert(mapgen_times.loops, t2 - t1)
|
||||
table.insert(mapgen_times.writing, t3 - t2 + t5 - t4)
|
||||
table.insert(mapgen_times.liquid_lighting, t4 - t3)
|
||||
table.insert(mapgen_times.make_chunk, t5 - t0)
|
||||
|
||||
-- Deal with memory issues. This, of course, is supposed to be automatic.
|
||||
local mem = math.floor(collectgarbage("count")/1024)
|
||||
if mem > 500 then
|
||||
print("Valleys_c is manually collecting garbage as memory use has exceeded 500K.")
|
||||
collectgarbage("collect")
|
||||
end
|
||||
end
|
||||
|
||||
local function mean( t )
|
||||
local sum = 0
|
||||
local count= 0
|
||||
|
||||
for k,v in pairs(t) do
|
||||
if type(v) == 'number' then
|
||||
sum = sum + v
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
|
||||
return (sum / count)
|
||||
end
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
if #mapgen_times.make_chunk == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local average, standard_dev
|
||||
minetest.log("Valleys_C lua Mapgen Times:")
|
||||
|
||||
average = mean(mapgen_times.liquid_lighting)
|
||||
minetest.log(" liquid_lighting: - - - - - - - - - - - - "..average)
|
||||
|
||||
average = mean(mapgen_times.loops)
|
||||
minetest.log(" loops: - - - - - - - - - - - - - - - - - "..average)
|
||||
|
||||
average = mean(mapgen_times.make_chunk)
|
||||
minetest.log(" makeChunk: - - - - - - - - - - - - - - - "..average)
|
||||
|
||||
average = mean(mapgen_times.noisemaps)
|
||||
minetest.log(" noisemaps: - - - - - - - - - - - - - - - "..average)
|
||||
|
||||
average = mean(mapgen_times.preparation)
|
||||
minetest.log(" preparation: - - - - - - - - - - - - - - "..average)
|
||||
|
||||
average = mean(mapgen_times.writing)
|
||||
minetest.log(" writing: - - - - - - - - - - - - - - - - "..average)
|
||||
end)
|
||||
|
||||
|
||||
-- Call the mapgen function lib_ecology.generate on mapgen.
|
||||
-- (located in voxel.lua)
|
||||
minetest.register_on_generated(lib_ecology.generate)
|
||||
|
Loading…
Reference in New Issue