Post your mapgen questions here (modding or engine)
Re: Post your mapgen questions here (modding or engine)
My bad, I'll start keeping it confined to the 'Noob here, needing help...' thread that I made for this problem.
- paramat
- Developer
- Posts: 3700
- Joined: Sun Oct 28, 2012 00:05
- GitHub: paramat
- IRC: paramat
- Location: UK
Re: Post your mapgen questions here (modding or engine)
It is better to do what i described earlier:
Clear the registered biomes, decorations and ores (in a mod that depends on 'default', 'butterflies', 'fireflies, and 'flowers' mods), then reregister biomes, decorations and ores with the desired changes.
If you do that then you will no longer need to use custom heat and humidity noises.
The clearing code is:
minetest.clear_registered_biomes()
minetest.clear_registered_decorations()
minetest.clear_registered_ores()
Clear the registered biomes, decorations and ores (in a mod that depends on 'default', 'butterflies', 'fireflies, and 'flowers' mods), then reregister biomes, decorations and ores with the desired changes.
If you do that then you will no longer need to use custom heat and humidity noises.
The clearing code is:
minetest.clear_registered_biomes()
minetest.clear_registered_decorations()
minetest.clear_registered_ores()
- paramat
- Developer
- Posts: 3700
- Joined: Sun Oct 28, 2012 00:05
- GitHub: paramat
- IRC: paramat
- Location: UK
Re: Post your mapgen questions here (modding or engine)
Copy-paste into the mod the biome, decoration and ore registrations from MTGame, and delete or edit them according to your needs.
-
- New member
- Posts: 2
- Joined: Sat Feb 15, 2020 07:44
- GitHub: qu4ntumrush
- In-game: qu4ntumrush
Re: Post your mapgen questions here (modding or engine)
I want to use open-mapgen (posting here because the official thread is dead) for a school project and I have large DEMs (20 km wide) of Florida as GeoTIFFs I want to convert into Minetest maps. I get errors no matter which DEM I use or the mod's parameters including scaling down. Recently every error says this:
I often try using a land cover and I may have had slightly more luck getting a map to load without it (I've lost track), but when it does load, it's completely flat so it must not be reading the DEM as a height map.
Other error messages I have gotten:
First error message I got when it was installed on my desktop before moving to C:\Games\Minetest\mods\:
Once I ran the converter w/o land cover, the world opened but crashed:
I know nothing about Lua scripts and only basic Python knowledge (pip install, QGIS, etc.), so all I can understand from "invalid or incomplete deflate data" is that something is wrong with the compression or file format. Well it works perfectly fine in QGIS (I've used it to make hillshade and slope rasters, and I've even added height maps to Worldpainter but without land cover classes), but it also won't open in MicroDEM because "not acceptable DEM." If you must know, I downloaded from the NOAA Data Access Viewer and if the proper data is chosen, it should be multiple TIFF files with multiple world files and an index sheet shapefile. I don't know why open-mapgen and MicroDEM consider it corrupted whereas every other program can use it. This has driven me insane for three days now and ideally I would like to contact the original programmer (Gail de Sailly) directly, but I welcome any Lua experts for help.
Code: Select all
zerr: invalid or incomplete deflate data
ModError: Failed to load and run script from C:\Games\minetest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:
decompressZlib: inflate failed
stack traceback:
[C]: in function 'decompress'
...etest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:121: in main chunk
Check debug.txt for details.
Other error messages I have gotten:
First error message I got when it was installed on my desktop before moving to C:\Games\Minetest\mods\:
Code: Select all
2020-02-11 02:24:06: ERROR[Main]: ModError: Failed to load and run script from C:\Users\[Me]\Desktop\minetest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:
2020-02-11 02:24:06: ERROR[Main]: ...etest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:34: attempt to index local 'str' (a nil value)
2020-02-11 02:24:06: ERROR[Main]: stack traceback:
2020-02-11 02:24:06: ERROR[Main]: ...etest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:34: in function 'parse'
2020-02-11 02:24:06: ERROR[Main]: ...etest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:105: in main chunk
2020-02-11 02:24:06: ERROR[Main]: Check debug.txt for details.
Code: Select all
AsyncErr: Lua: finishGenRuntime error from mod 'geo_mapgen' in callback environment_OnGenerated(): decompressZlib: inflate failed
stack traceback:
[C]: in function 'decompress'
...etest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:81: in function '__index'
...etest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:192: in function 'value'
...etest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:231: in function <...etest-5.1.1-win64\bin\..\mods\geo-mapgen-master\init.lua:195>
...es\minetest-5.1.1-win64\bin\..\builtin\game\register.lua:429: in function <...es\minetest-5.1.1-win64\bin\..\builtin\game\register.lua:413>
- duane
- Member
- Posts: 1715
- Joined: Wed Aug 19, 2015 19:11
- GitHub: duane-r
- Location: Oklahoma City
- Contact:
Re: Post your mapgen questions here (modding or engine)
I think you'd have better luck posting to the project thread, anyway. Gael de Sailly is more likely to monitor his own posts; but don't expect an immediate response, as he may not be working on minetest much these days. I don't have any experience with topographical maps, but I've worked closely with Gael de Sailly's code in the past. It usually looks straight-forward, but the principles can be insanely difficult.qu4ntumrush wrote:I want to use open-mapgen (posting here because the official thread is dead) for a school project
You might want to make sure that the format for those maps hasn't changed in the last year or so. They might be using a different compression method.
Believe in people and you don't need to believe anything else.
- paramat
- Developer
- Posts: 3700
- Joined: Sun Oct 28, 2012 00:05
- GitHub: paramat
- IRC: paramat
- Location: UK
Re: Post your mapgen questions here (modding or engine)
Yes, best also post in the dedicated thread, then it will not be 'dead' =)
That mod is beyond my understanding.
That mod is beyond my understanding.
- CBugDCoder
- Member
- Posts: 32
- Joined: Tue Jul 31, 2018 12:13
- GitHub: CBugDCoder
- IRC: CBugDCoder
- In-game: CalebDavis
- Location: Home
Re: Post your mapgen questions here (modding or engine)
I am trying to generate wallmounted vines on the underside of floating islands. My inital plan was to use decorations and minetest.get_mapgen_object("gennotify") but the gennotify mapgen object does not include decorations placed in the VM. How would I get the locations of the vines without having to sort through all the nodes again?
- CBugDCoder
- Member
- Posts: 32
- Joined: Tue Jul 31, 2018 12:13
- GitHub: CBugDCoder
- IRC: CBugDCoder
- In-game: CalebDavis
- Location: Home
Re: Post your mapgen questions here (modding or engine)
I was able to find them by only searching through the x and z axis and using the terrain noise values. But if anyone has a better solution I am open to them.
- CBugDCoder
- Member
- Posts: 32
- Joined: Tue Jul 31, 2018 12:13
- GitHub: CBugDCoder
- IRC: CBugDCoder
- In-game: CalebDavis
- Location: Home
Re: Post your mapgen questions here (modding or engine)
- Attachments
-
- screenshot_20200218_094730.png (323.75 KiB) Viewed 2490 times
-
- screenshot_20200218_094716.png (224.47 KiB) Viewed 2490 times
Re: Post your mapgen questions here (modding or engine)
i read somewhere that it was possible to add x-z-limits to biomes.
but how would i do that?
according to the given y_min, y_max and vertical_blend, i tried x_min, x_max and horizontal_blend but nothing happened.
the mapgen still generates the biome all over the world, even though i set it to generate only on the +x side and another biome on the -x side.
i can't seem to find what i have read in the search either. but i clearly remember that it came with a screenshot and examples...
but how would i do that?
according to the given y_min, y_max and vertical_blend, i tried x_min, x_max and horizontal_blend but nothing happened.
the mapgen still generates the biome all over the world, even though i set it to generate only on the +x side and another biome on the -x side.
i can't seem to find what i have read in the search either. but i clearly remember that it came with a screenshot and examples...
✨🏳️🌈♣️✨
- paramat
- Developer
- Posts: 3700
- Joined: Sun Oct 28, 2012 00:05
- GitHub: paramat
- IRC: paramat
- Location: UK
Re: Post your mapgen questions here (modding or engine)
https://github.com/minetest/minetest/bl ... .txt#L7181
Did you search through the documentation?
If using XYZ biome limits you must use the 'min_pos', 'max_pos' format.
Also, there is no 'horizontal blend'.
Did you search through the documentation?
If using XYZ biome limits you must use the 'min_pos', 'max_pos' format.
Also, there is no 'horizontal blend'.
-
- Member
- Posts: 1482
- Joined: Fri Apr 19, 2013 16:19
- GitHub: twoelk
- IRC: twoelk
- In-game: twoelk
- Location: northern Germany
Re: Post your mapgen questions here (modding or engine)
if only we could do this with mapgenerators as well :D
like in a different mapgen for every quadrant or maybe some 1000 meter wide mg5 blob in the center surrounded by mg7 terrain and in a strip of maybe 2000 m width along the map edges mg-valleys.
if only ...
like in a different mapgen for every quadrant or maybe some 1000 meter wide mg5 blob in the center surrounded by mg7 terrain and in a strip of maybe 2000 m width along the map edges mg-valleys.
if only ...
Re: Post your mapgen questions here (modding or engine)
How to increase the number of available dungeon in a map?
There is dungeon noise, but i dont understand the use of every params (every noise is different)
There is dungeon noise, but i dont understand the use of every params (every noise is different)
- paramat
- Developer
- Posts: 3700
- Joined: Sun Oct 28, 2012 00:05
- GitHub: paramat
- IRC: paramat
- Location: UK
Re: Post your mapgen questions here (modding or engine)
In dungeon noise, the 'offset' is the average number of dungeons per mapchunk, the 'scale' is the typical variation (of the number of dungeons per mapchunk) either side of 'offset'.
So for 2 dungeons per mapchunk everywhere: offset 2.0 scale 0.0
For a variation of 1-3 dungeons per mapchunk: offset 2.0 scale 1.0
So for 2 dungeons per mapchunk everywhere: offset 2.0 scale 0.0
For a variation of 1-3 dungeons per mapchunk: offset 2.0 scale 1.0
Re: Post your mapgen questions here (modding or engine)
Thank you!. Now i can make valley world filled with dungeonsparamat wrote:In dungeon noise, the 'offset' is the average number of dungeons per mapchunk, the 'scale' is the typical variation (of the number of dungeons per mapchunk) either side of 'offset'.
So for 2 dungeons per mapchunk everywhere: offset 2.0 scale 0.0
For a variation of 1-3 dungeons per mapchunk: offset 2.0 scale 1.0
Re: Post your mapgen questions here (modding or engine)
How to add ores to the mapgen ?
- CBugDCoder
- Member
- Posts: 32
- Joined: Tue Jul 31, 2018 12:13
- GitHub: CBugDCoder
- IRC: CBugDCoder
- In-game: CalebDavis
- Location: Home
Re: Post your mapgen questions here (modding or engine)
Use minetest.register_ore(ore_def) where ore_def is a table in the format described in https://rubenwardy.com/minetest_modding ... gister_ore
Re: Post your mapgen questions here (modding or engine)
I've got a singlenode with custom mapgen.
How do I place grass and dirt on the top areas?
Edit: It's a 3d mapgen if that is important
How do I place grass and dirt on the top areas?
Edit: It's a 3d mapgen if that is important
Creator of jelys_pizzaria and motorbike, and player of persistent kingdoms. RIP
-
- Member
- Posts: 1118
- Joined: Mon Dec 29, 2014 08:07
- Location: USA
Re: Post your mapgen questions here (modding or engine)
Extex,
Most mapgens I've seen determine the surface, and then drill down to place those.
You'll have to determine the surface. Once you do, you can use the biome definition data to determine how deep to go down for placing the filler and top nodes of the biome def.
The advantage is that as you find the surface and the biome, you can have your lua mapgen 2d index those to build a usable heightmap and biomemap for other mods.
I have not posted or otherwise shared the following code, but there is a whole lot of goodness in the code below. The gist of the mapgen code below is to use a voronoi diagram to influence terrain height. There are additional functions included as well.
The On_Gen call, at the bottom, is where you'll find my example of both heightmap and biomemap generation, once I've determined both the surface height and biome.
For a 3D mapgen, you have to determine what factor makes the surface, since the 3D noise value is more a true/false versus a hardcoded y-value. This can be tricky.
Most mapgens I've seen determine the surface, and then drill down to place those.
You'll have to determine the surface. Once you do, you can use the biome definition data to determine how deep to go down for placing the filler and top nodes of the biome def.
The advantage is that as you find the surface and the biome, you can have your lua mapgen 2d index those to build a usable heightmap and biomemap for other mods.
I have not posted or otherwise shared the following code, but there is a whole lot of goodness in the code below. The gist of the mapgen code below is to use a voronoi diagram to influence terrain height. There are additional functions included as well.
The On_Gen call, at the bottom, is where you'll find my example of both heightmap and biomemap generation, once I've determined both the surface height and biome.
For a 3D mapgen, you have to determine what factor makes the surface, since the 3D noise value is more a true/false versus a hardcoded y-value. This can be tricky.
Code: Select all
minetest.set_mapgen_setting('mg_name','singlenode',true)
minetest.set_mapgen_setting('flags','nolight',true)
--minetest.set_mapgen_params({mgname="singlenode"})
--local storage = minetest.get_mod_storage()
local mg_map_view = false
local c_desertsandstone = minetest.get_content_id("lib_materials:stone_sandstone_desert")
local c_sandstone = minetest.get_content_id("lib_materials:stone_sandstone")
local c_desertstone = minetest.get_content_id("lib_materials:stone_desert")
local c_stone = minetest.get_content_id("lib_materials:stone")
local c_desertsand = minetest.get_content_id("lib_materials:sand_desert")
local c_sand = minetest.get_content_id("lib_materials:sand")
local c_brick = minetest.get_content_id("lib_materials:stone_brick")
local c_block = minetest.get_content_id("lib_materials:stone_block")
local c_desertstoneblock= minetest.get_content_id("lib_materials:stone_desert_block")
local c_desertstonebrick= minetest.get_content_id("lib_materials:stone_desert_brick")
local c_obsidian = minetest.get_content_id("lib_materials:stone_obsidian")
local c_dirt = minetest.get_content_id("lib_materials:dirt")
local c_dirtgrass = minetest.get_content_id("lib_materials:dirt_with_grass")
local c_dirtdrygrass = minetest.get_content_id("lib_materials:dirt_with_grass_dry")
local c_top = minetest.get_content_id("lib_materials:dirt_with_litter_coniferous")
local c_snow = minetest.get_content_id("lib_materials:dirt_with_snow")
local c_water = minetest.get_content_id("lib_materials:liquid_water_source")
local c_tree = minetest.get_content_id("lib_ecology:tree_default_trunk")
local c_air = minetest.get_content_id("air")
local c_ignore = minetest.get_content_id("ignore")
local fill_depth = 4
local top_depth = 1
local map_world_size
if mg_map_view == false then
map_world_size = 62000
else
map_world_size = 1000
end
local map_base_scale = 100
local map_size_scale = 10
--local map_scale = map_base_scale * map_size_scale
local map_scale = map_base_scale * map_size_scale
local map_noise_scale_multiplier = 3
local map_tectonic_scale = map_world_size / map_scale
local map_noise_scale = map_tectonic_scale * map_noise_scale_multiplier
--31 --29 --43 --17 --330 --83
local voronoi_cells = 31
local heightmap_base = 5
local noisemap_base = 7
local cliffmap_base = 7
local abs = math.abs
local max = math.max
local sqrt = math.sqrt
local floor = math.floor
local convex = false
local mult = lib_materials.mapgen_scale_factor or 4
local mg_golden_ratio = ((1 + (5^0.5)) * 0.5)
--[[
local np_terrain = {
offset = -4,
scale = map_noise_scale,
seed = 5934,
spread = {x = map_world_size/map_size_scale, y = map_world_size/map_size_scale, z = map_world_size/map_size_scale},
octaves = 5,
persist = 0.6,
lacunarity = 2.11,
--flags = "defaults"
}
--]]
local np_terrain = {
offset = -4,
scale = 50,
seed = 5934,
spread = {x = 2400, y = 2400, z = 2400},
octaves = 8,
persist = 0.4,
lacunarity = 2.11,
--flags = "defaults"
}
local np_cliffs = {
offset = 0,
scale = 0.72,
spread = {x = 180*mult, y =180*mult, z = 180*mult},
seed = 78901,
octaves = 2,
persist = 0.4,
lacunarity = 2.11,
-- flags = "absvalue"
}
local np_heat = {
flags = "defaults",
lacunarity = 2,
offset = 50,
scale = 50,
spread = {x = 1000, y = 1000, z = 1000},
seed = 5349,
octaves = 3,
persistence = 0.5,
}
local np_heat_blend = {
flags = "defaults",
lacunarity = 2,
offset = 0,
scale = 1.5,
spread = {x = 8, y = 8, z = 8},
seed = 13,
octaves = 2,
persistence = 1,
}
local np_humid = {
flags = "defaults",
lacunarity = 2,
offset = 50,
scale = 50,
spread = {x = 1000, y = 1000, z = 1000},
seed = 842,
octaves = 3,
persistence = 0.5,
}
local np_humid_blend = {
flags = "defaults",
lacunarity = 2,
offset = 0,
scale = 1.5,
spread = {x = 8, y = 8, z = 8},
seed = 90003,
octaves = 2,
persistence = 1,
}
local v_points = {
{x=-350,z=-350},
{x=-35,z=-350},
{x=-135,z=-135},
{x=-35,z=-35},
{x=-350,z=350},
{x=-350,z=35},
{x=-135,z=135},
{x=-35,z=35},
{x=350,z=-350},
{x=35,z=350},
{x=135,z=-135},
{x=35,z=-35},
{x=350,z=350},
{x=350,z=-35},
{x=135,z=135},
}
local nobj_terrain = nil
--local nbase_terrain = nil
local isln_terrain = nil
local nobj_cliffs = nil
local isln_cliffs = nil
local nobj_heatmap = nil
local nbase_heatmap = nil
local nobj_heatblend = nil
local nbase_heatblend = nil
local nobj_humiditymap = nil
local nbase_humiditymap = nil
local nobj_humidityblend = nil
local nbase_humidityblend = nil
local mg_custom_data = {}
lib_mg_continental.heightmap = {}
lib_mg_continental.biomemap = {}
local hills_offset = 64*mult
local hills_thresh = math.floor((np_terrain.scale)*0.5)
local shelf_thresh = math.floor((np_terrain.scale)*0.5)
local cliffs_thresh = math.floor((np_terrain.scale)*0.5)
local function max_height(noiseprm)
local height = 0 -- 30 18
local scale = noiseprm.scale -- 18 10.8
for i=1,noiseprm.octaves do -- 10.8 6.48
height=height + scale -- 6.48 3.88
scale = scale * noiseprm.persist -- 3.88 2.328
end -- ----- ------
return height+noiseprm.offset -- 41.496 + (-4)
end -- 37.496
local function min_height(noiseprm)
local height = 0
local scale = noiseprm.scale
for i=1,noiseprm.octaves do
height=height - scale
scale = scale * noiseprm.persist
end
return height+noiseprm.offset
end
local base_min = min_height(np_terrain)
local base_max = max_height(np_terrain)
local base_rng = base_max-base_min
local easing_factor = 1/(base_max*base_max*4)
local function get_terrain_height_shelf(theight)
-- parabolic gradient
if theight > 0 and theight < shelf_thresh then
theight = theight * (theight*theight/(shelf_thresh*shelf_thresh)*0.5 + 0.5)
end
return theight
end
local function get_terrain_height_hills_adjustable_shelf(theight,hheight,cheight,shlf_thresh)
-- parabolic gradient
if theight > 0 and theight < shlf_thresh then
theight = theight * (theight*theight/(shlf_thresh*shlf_thresh)*0.5 + 0.5)
end
-- hills
if theight > hills_thresh then
theight = theight + math.max((theight-hills_thresh) * hheight,0)
-- cliffs
elseif theight > 1 and theight < hills_thresh then
local clifh = math.max(math.min(cheight,1),0)
if clifh > 0 then
clifh = -1*(clifh-1)*(clifh-1) + 1
theight = theight + (hills_thresh-theight) * clifh * ((theight<2) and theight-1 or 1)
end
end
return theight
end
local function get_distance(a,b) --get_distance(a,b)
return (max(abs(a.x-b.x), abs(a.y-b.y))) --returns the chebyshev distance between two points
end
local function get_avg_distance(a,b) --get_avg_distance(a,b)
return ((abs(a.x-b.x) + abs(a.y-b.y)) * 0.5) --returns the average distance between two points
end
local function get_manhattan_distance(a,b) --get_manhattan_distance(a,b)
return (abs(a.x-b.x) + abs(a.y-b.y)) --returns the manhattan distance between two points
end
local function get_euclid_distance(a,b)
local dx = a.x - b.x
local dy = a.y - b.y
return (dx*dx+dy*dy)^0.5
end
local function get_midpoint(a,b) --get_midpoint(a,b)
return ((a.x+b.x)/2), ((a.y+b.y)/2) --returns the midpoint between two points
end
--
-- save list of generated lib_mg_continental
--
function lib_mg_continental.save(pobj, pfilename)
local file = io.open(lib_mg_continental.path_world.."/"..pfilename.."", "w")
if file then
file:write(minetest.serialize(pobj))
file:close()
end
end
--
-- load list of generated lib_mg_continental
--
function lib_mg_continental.load(pfilename)
local file = io.open(lib_mg_continental.path_world.."/"..pfilename.."", "r")
if file then
local table = minetest.deserialize(file:read("*all"))
if type(table) == "table" then
return table
end
end
--return {}
return nil
end
--
-- save .csv file format
--
function lib_mg_continental.save_csv(pobj, pfilename)
local file = io.open(lib_mg_continental.path_world.."/"..pfilename.."", "w")
if file then
file:write(pobj)
file:close()
end
end
function lib_mg_continental.load_csv(separator, path)
local file = io.open(lib_mg_continental.path_world.."/"..path, "r")
if file then
local t = {}
for line in file:lines() do
if line:sub(1,1) ~= "#" and line:find("[^%"..separator.."% ]") then
table.insert(t, line:split(separator, true))
end
end
if type(t) == "table" then
return t
end
end
--return {}
return nil
end
-- Create a table of biome ids, so I can use the biomemap.
if not lib_mg_continental.biome_ids then
--local get_cid = minetest.get_content_id
lib_mg_continental.biome_info = {}
for name, desc in pairs(minetest.registered_biomes) do
local b_cid = minetest.get_biome_id(name)
local b_top = minetest.get_content_id(desc.node_top)
local b_top_depth = desc.depth_top or ""
local b_filler = minetest.get_content_id(desc.node_filler)
local b_filler_depth = desc.depth_filler or ""
local b_stone = minetest.get_content_id(desc.node_stone)
local b_water_top = minetest.get_content_id(desc.node_water_top)
local b_water_top_depth = desc.depth_water_top or ""
local b_water = minetest.get_content_id(desc.node_water)
local b_river = minetest.get_content_id(desc.node_river_water)
local b_riverbed = minetest.get_content_id(desc.node_riverbed)
local b_riverbed_depth = desc.depth_riverbed or ""
local b_cave_liquid = minetest.get_content_id(desc.node_cave_liquid)
local b_dungeon = minetest.get_content_id(desc.node_dungeon)
local b_dungeon_alt = minetest.get_content_id(desc.node_dungeon_alt)
local b_dungeon_stair = minetest.get_content_id(desc.node_dungeon_stair)
local b_node_dust = minetest.get_content_id(desc.node_dust)
local b_miny = desc.y_min or ""
local b_maxy = desc.y_max or ""
local b_heat = desc.heat_point or ""
local b_humid = desc.humidity_point or ""
lib_mg_continental.biome_info[desc.name] = name .. "|" .. b_cid .. "|" .. b_top .. "|" .. b_top_depth .. "|" .. b_filler .. "|" .. b_filler_depth .. "|" .. b_stone .. "|" .. b_water_top
.. "|" .. b_water_top_depth .. "|" .. b_water .. "|" .. b_river .. "|" .. b_riverbed .. "|" .. b_riverbed_depth .. "|" .. b_cave_liquid .. "|" .. b_dungeon
.. "|" .. b_dungeon_alt .. "|" .. b_dungeon_stair .. "|" .. b_node_dust .. "|" .. b_miny .. "|" .. b_maxy .. "|" .. b_heat .. "|" .. b_humid .. "\n"
end
end
local function make_voronoi(cells, size)
if not cells or not size then
return
end
-- Start time of voronoi generation.
local t0 = os.clock()
minetest.log("[lib_mg_continental_voronoi] Random Points generation start")
--Prevents points from too near edges, ideally creating more evenly sized cells.
--Minumum: 50
local size_offset = 125
local size_half = size / 2
local t_map_cell = {}
if cells > 0 then
local temp_points = "#Index|Pos.Z|Pos.X\n"
v_points = {}
for i_c = 1, cells do
local t_pt = {x = (math.random(1 + size_offset, size - size_offset) - size_half), z = (math.random(1 + size_offset, size - size_offset) - size_half)}
v_points[i_c] = t_pt
temp_points = temp_points .. i_c .. "|" .. t_pt.z .. "|" .. t_pt.x .. "\n"
end
lib_mg_continental.save_csv(temp_points, "lib_mg_continental_data_points.txt")
minetest.log("[lib_mg_continental_voronoi] Voronoi Cell Point List:\n" .. temp_points .. "")
elseif cells == 0 then
v_points = {}
for i, point in ipairs(mg_custom_data.base_points) do
local idx, p_z, p_x = unpack(point)
local t_pt = {x = tonumber(p_x), z = tonumber(p_z)}
v_points[tonumber(idx)] = t_pt
end
minetest.log("[lib_mg_continental_voronoi] Voronoi Cell Point List loaded from file.")
else
end
-- Random Points generation finished. Check the timer to know the elapsed time.
local t1 = os.clock()
minetest.log("[lib_mg_continental_voronoi] Random Points generation time " .. (t1-t0) .. " ms")
minetest.log("[lib_mg_continental_voronoi] Cell Data (Cells, Neighbors, Midpoints) generation start")
local temp_cells = "#Index|LinkIdx|Pos.Z|Pos.X|ClosestIndex|ClosestPosZ|ClosestPosX\n"
local temp_neighbors = "#CellIndex|LinkIdx|CellPosZ|CellPosX|ClosestNeighborIndex|ClosestNeighborPosZ|ClosestNeighborPosX|ClosestNeighborDist|ClosestNeighborEDist|ClosestNeighborMDist|ClosestNeighborADist|NeighborMidPosZ|NeighborMidPosX\n"
local temp_midpoints = "#LinkIdx|Pos.Z|Pos.X|DistBetweenCells|Cell1Idx|Cell1Dist|Cell2Idx|Cell2Dist|\n"
for i, pos in pairs(v_points) do
local closest_neighbor_idx = 0
local closest_neighbor_pos_x = 0
local closest_neighbor_pos_z = 0
local closest_dist = 0 --chebyshev
local closest_edist = 0 --euclidean
local closest_adist = 0 --average
local closest_mdist = 0 --manhattan
local e_dist
local m_dist
local a_dist
local s_dist
local t_dist
--local t_point_x, t_point_z
for k, pt in pairs(v_points) do
if i ~= k then
local neighbor_add = false
e_dist = get_euclid_distance({x=pt.x,y=pt.z}, {x=pos.x,y=pos.z})
--t_dist = get_euclidean2_distance({x=pt.x,y=pt.z}, {x=pos.x,y=pos.z})
t_dist = get_distance({x=pt.x,y=pt.z}, {x=pos.x,y=pos.z})
m_dist = get_manhattan_distance({x=pt.x,y=pt.z}, {x=pos.x,y=pos.z})
a_dist = get_avg_distance({x=pt.x,y=pt.z}, {x=pos.x,y=pos.z})
if s_dist then
if s_dist > t_dist then
s_dist = t_dist
closest_neighbor_idx = k
closest_neighbor_pos_x = pt.x
closest_neighbor_pos_z = pt.z
closest_dist = t_dist
closest_edist = e_dist
closest_mdist = m_dist
closest_adist = a_dist
neighbor_add = true
elseif s_dist == t_dist then
s_dist = t_dist
closest_neighbor_idx = 0
closest_neighbor_pos_x = pt.x
closest_neighbor_pos_z = pt.z
closest_dist = t_dist
end
else
s_dist = t_dist
closest_neighbor_idx = k
closest_neighbor_pos_x = pt.x
closest_neighbor_pos_z = pt.z
end
local m_point_x, m_point_z = get_midpoint({x=pt.x,y=pt.z}, {x=pos.x,y=pos.z})
temp_midpoints = temp_midpoints .. i .. "-" .. k .. "|" .. m_point_z .. "|" .. m_point_x .. "|" .. get_distance({x=pt.x,y=pt.z}, {x=pos.x,y=pos.z}) .. "|" .. i .. "|" .. get_distance({x=m_point_x,y=m_point_z}, {x=pos.x,y=pos.z}) .. "|" .. k .. "|" .. get_distance({x=pt.x,y=pt.z}, {x=m_point_x,y=m_point_z}) .. "\n"
if neighbor_add == true then
local t_point_x, t_point_z = get_midpoint({x=pt.x,y=pt.z}, {x=pos.x,y=pos.z})
temp_neighbors = temp_neighbors .. i .. "|" .. i .. "-" .. closest_neighbor_idx .. "|" .. pos.z .. "|" .. pos.x .. "|" .. closest_neighbor_idx .. "|" .. closest_neighbor_pos_z .. "|" .. closest_neighbor_pos_x .. "|" .. s_dist .. "|" .. e_dist .. "|" .. m_dist .. "|" .. a_dist .. "|" .. t_point_z .. "|" .. t_point_x .. "\n"
end
end
end
t_map_cell[i] = {
link_idx = i .. "-" .. closest_neighbor_idx,
z = pos.z,
x = pos.x,
closest_idx = closest_neighbor_idx,
closestposz = closest_neighbor_pos_z,
closestposx = closest_neighbor_pos_x,
}
temp_cells = temp_cells .. i .. "|" .. i .. "-" .. closest_neighbor_idx .. "|" .. pos.z .. "|" .. pos.x .. "|" .. closest_neighbor_idx .. "|" .. closest_neighbor_pos_z .. "|" .. closest_neighbor_pos_x .. "\n"
end
-- Random cell generation finished. Check the timer to know the elapsed time.
local t2 = os.clock()
minetest.log("[lib_mg_continental_voronoi] Cell Data (Cells, Neighbors, Midpoints) generation time " .. (t2-t1) .. " ms")
lib_mg_continental.save_csv(temp_cells, "lib_mg_continental_data_cells.txt")
lib_mg_continental.save_csv(temp_neighbors, "lib_mg_continental_data_neighbors.txt")
lib_mg_continental.save_csv(temp_midpoints, "lib_mg_continental_data_midpoints.txt")
-- Random cell generation finished. Check the timer to know the elapsed time.
local t3 = os.clock()
minetest.log("[lib_mg_continental_voronoi] Cell Data save time " .. (t3-t2) .. " ms")
-- Print generation time of this mapchunk.
local chugent = math.ceil((os.clock() - t0) * 1000)
minetest.log("[lib_mg_continental_voronoi] Voronoi Data generation time " .. chugent .. " ms")
--return t_map_cell
return t_map_cell, temp_midpoints, temp_neighbors --, temp_points
end
local function make_edge_map(size)
-- Start time of voronoi generation.
local t0 = os.clock()
minetest.log("[lib_mg_continental_voronoi] Edge Map generation start")
local t_map_edge = {}
local temp_edges = "#ID|Index|Pos.Z|Pos.X|Cell1 Index|Cell1 Distance|Cell1 EDistance|Cell1 MDistance|Cell1 ADistance|Cell Index|Cell2 Distance|Cell2 EDistance|Cell2 MDistance|Cell2 ADistance\n"
local idx = 1
for i_z = (1-(size/2)), (size-(size/2)) do
t_map_edge[i_z] = {}
for i_x = (1-(size/2)), (size-(size/2)) do
local closest_cell_idx = 0
local closest_cell_dist
local closest_cell_edist = 0
local closest_cell_mdist = 0
local closest_cell_adist = 0
local last_closest_idx = 0
local last_dist
local this_dist
local last_edist
local last_mdist
local last_adist
local e_dist
local m_dist
local a_dist
for i, pos in pairs(v_points) do
local edge_add = false
e_dist = get_euclid_distance({x=i_x,y=i_z}, {x=pos.x,y=pos.z})
--this_dist = get_euclidean2_distance({{x=i_x,y=i_z}, {x=pos.x,y=pos.z})
this_dist = get_distance({x=i_x,y=i_z}, {x=pos.x,y=pos.z})
m_dist = get_manhattan_distance({x=i_x,y=i_z}, {x=pos.x,y=pos.z})
a_dist = get_avg_distance({x=i_x,y=i_z}, {x=pos.x,y=pos.z})
if last_dist then
if last_dist > this_dist then
closest_cell_idx = i
closest_cell_dist = this_dist
closest_cell_edist = e_dist
last_dist = this_dist
last_edist = e_dist
last_mdist = m_dist
last_adist = a_dist
last_closest_idx = i
elseif last_dist == this_dist then
closest_cell_idx = 0
edge_add = true
end
else
closest_cell_idx = i
closest_cell_dist = this_dist
closest_cell_edist = e_dist
last_dist = this_dist
last_edist = e_dist
last_mdist = m_dist
last_adist = a_dist
last_closest_idx = i
end
if edge_add == true then
t_map_edge[i_z][i_x] = {
index = idx,
cells_index = "" .. i .. "-" .. last_closest_idx .. "",
cell1_index = i,
cell1_distance = this_dist,
cell1_edistance = e_dist,
cell1_mdistance = m_dist,
cell1_adistance = a_dist,
cell2_index = last_closest_idx,
cell2_distance = last_dist,
cell2_edistance = last_edist,
cell2_mdistance = last_mdist,
cell2_adistance = last_adist,
}
temp_edges = temp_edges .. i_z .. "|" .. i_x .. "|" .. idx .. "|" .. i .. "-" .. last_closest_idx .. "|" .. i .. "|" .. this_dist .. "|" .. e_dist .. "|" .. m_dist .. "|" .. a_dist .. "|" .. last_closest_idx .. "|" .. last_dist .. "|" .. last_edist .. "|" .. last_mdist .. "|" .. last_adist .. "\n"
end
end
idx = idx + 1
end
end
local t1 = os.clock()
minetest.log("[lib_mg_continental_voronoi] Edge Map generation time " .. (t1-t0) .. " ms")
lib_mg_continental.save_csv(temp_edges, "lib_mg_continental_data_edges.txt")
local t2 = os.clock()
minetest.log("[lib_mg_continental_voronoi] Edge Map save time " .. (t2-t1) .. " ms")
-- Print generation time of this mapchunk.
local chugent = math.ceil((os.clock() - t0) * 1000)
minetest.log("[lib_mg_continental_voronoi] Edge Map Total generation time " .. chugent .. " ms")
return t_map_edge
end
local function make_voronoi_maps(size)
-- Start time of voronoi generation.
local t0 = os.clock()
minetest.log("[lib_mg_continental_voronoi] Voronoi and Edges Maps generation start")
local t_map_voronoi = {}
local t_map_edge = {}
local temp_voronoi = "#Index|Pos.Z|Pos.X|ClosestIndex|ClosestDistance\n"
local temp_edges = "#ID|Index|Pos.Z|Pos.X|Cell1 Index|Cell1 Distance|Cell1 EDistance|Cell1 MDistance|Cell1 ADistance|Cell Index|Cell2 Distance|Cell2 EDistance|Cell2 MDistance|Cell2 ADistance\n"
local idx = 1
for i_z = (1-(size/2)), (size-(size/2)) do
t_map_voronoi[i_z] = {}
t_map_edge[i_z] = {}
for i_x = (1-(size/2)), (size-(size/2)) do
local closest_cell_idx = 0
local closest_cell_dist
local closest_cell_edist = 0
local closest_cell_mdist = 0
local closest_cell_adist = 0
local last_closest_idx = 0
local last_dist
local this_dist
local last_edist
local last_mdist
local last_adist
local e_dist
local m_dist
local a_dist
for i, pos in pairs(v_points) do
local edge_add = false
e_dist = get_euclid_distance({x=i_x,y=i_z}, {x=pos.x,y=pos.z})
--this_dist = get_euclidean2_distance({{x=i_x,y=i_z}, {x=pos.x,y=pos.z})
this_dist = get_distance({x=i_x,y=i_z}, {x=pos.x,y=pos.z})
m_dist = get_manhattan_distance({x=i_x,y=i_z}, {x=pos.x,y=pos.z})
a_dist = get_avg_distance({x=i_x,y=i_z}, {x=pos.x,y=pos.z})
if last_dist then
if last_dist > this_dist then
closest_cell_idx = i
closest_cell_dist = this_dist
closest_cell_edist = e_dist
last_dist = this_dist
last_edist = e_dist
last_mdist = m_dist
last_adist = a_dist
last_closest_idx = i
elseif last_dist == this_dist then
closest_cell_idx = 0
edge_add = true
end
else
closest_cell_idx = i
closest_cell_dist = this_dist
closest_cell_edist = e_dist
last_dist = this_dist
last_edist = e_dist
last_mdist = m_dist
last_adist = a_dist
last_closest_idx = i
end
if edge_add == true then
t_map_edge[i_z][i_x] = {
index = "" .. i .. "-" .. last_closest_idx .. "",
z = i_z,
x = i_x,
cell1_index = i,
cell1_distance = this_dist,
cell1_edistance = e_dist,
cell1_mdistance = m_dist,
cell1_adistance = a_dist,
cell2_index = last_closest_idx,
cell2_distance = last_dist,
cell2_edistance = last_edist,
cell2_mdistance = last_mdist,
cell2_adistance = last_adist,
}
temp_edges = temp_edges .. idx .. "|" .. i .. "-" .. last_closest_idx .. "|" .. i_z .. "|" .. i_x .. "|" .. i .. "|" .. this_dist .. "|" .. e_dist .. "|" .. m_dist .. "|" .. a_dist .. "|" .. last_closest_idx .. "|" .. last_dist .. "|" .. last_edist .. "|" .. last_mdist .. "|" .. last_adist .. "\n"
end
end
t_map_voronoi[i_z][i_x] = {
closest_idx = closest_cell_idx,
closest_dist = closest_cell_dist,
closest_edist = closest_cell_edist,
closest_mdist = closest_cell_mdist,
closest_adist = closest_cell_adist,
}
--temp_voronoi = temp_voronoi .. i_z .. "|" .. i_x .. "|" .. closest_cell_idx .. "|" .. closest_cell_dist .. "\n"
idx = idx + 1
end
end
local t1 = os.clock()
minetest.log("[lib_mg_continental_voronoi] Voronoi and Edges Maps generation time " .. (t1-t0) .. " ms")
--lib_mg_continental.save_csv(temp_voronoi, "lib_mg_continental_data_voronoi.txt")
lib_mg_continental.save_csv(temp_edges, "lib_mg_continental_data_edges.txt")
local t2 = os.clock()
minetest.log("[lib_mg_continental_voronoi] Voronoi and Edges Maps save time " .. (t2-t1) .. " ms")
-- Print generation time of this mapchunk.
local chugent = math.ceil((os.clock() - t0) * 1000)
minetest.log("[lib_mg_continental_voronoi] Voronoi and Edges Maps Total generation time " .. chugent .. " ms")
return t_map_voronoi, t_map_edge
--return t_map_voronoi, temp_edges
end
minetest.log("[lib_mg_continental_mg_dev_voronoi] Custom Data Load / Gen Start")
mg_custom_data.base_points = lib_mg_continental.load_csv("|", "lib_mg_continental_data_points.txt")
mg_custom_data.base_cells = lib_mg_continental.load_csv("|", "lib_mg_continental_data_cells.txt")
mg_custom_data.base_cellmap = lib_mg_continental.load("lib_mg_continental_data_cellmap.txt")
mg_custom_data.base_midpoints = lib_mg_continental.load_csv("|", "lib_mg_continental_data_midpoints.txt")
mg_custom_data.base_tectonicmap = lib_mg_continental.load("lib_mg_continental_data_tectonicmap.txt")
mg_custom_data.base_edgemap = lib_mg_continental.load("lib_mg_continental_data_edgemap.txt")
--mg_custom_data.base_edgemap = lib_mg_continental.load_csv("|", "lib_mg_continental_data_edges.txt")
if not (mg_custom_data.base_cellmap) then
if (mg_custom_data.base_midpoints == nil) then
if (mg_custom_data.base_points == nil) then
mg_custom_data.base_cellmap, mg_custom_data.base_midpoints, mg_custom_data.base_neighbors = make_voronoi(voronoi_cells, map_scale)
lib_mg_continental.save(mg_custom_data.base_cellmap, "lib_mg_continental_data_cellmap.txt")
else
mg_custom_data.base_cellmap, mg_custom_data.base_midpoints, mg_custom_data.base_neighbors = make_voronoi(0, map_scale)
lib_mg_continental.save(mg_custom_data.base_cellmap, "lib_mg_continental_data_cellmap.txt")
end
end
end
if not (mg_custom_data.base_tectonicmap) or not (mg_custom_data.base_edgemap) then
mg_custom_data.base_tectonicmap, mg_custom_data.base_edgemap = make_voronoi_maps(map_scale)
lib_mg_continental.save(mg_custom_data.base_tectonicmap, "lib_mg_continental_data_tectonicmap.txt")
lib_mg_continental.save(mg_custom_data.base_edgemap, "lib_mg_continental_data_edgemap.txt")
end
minetest.log("[lib_mg_continental_voronoi] Custom Data Load / Gen End")
local mapgen_times = {
liquid_lighting = {},
loops = {},
make_chunk = {},
noisemaps = {},
preparation = {},
writing = {},
}
local data = {}
minetest.register_on_generated(function(minp, maxp, seed)
-- Start time of mapchunk generation.
local t0 = os.clock()
--ShadMOrdre
local x1 = maxp.x
local y1 = maxp.y
local z1 = maxp.z
local x0 = minp.x
local y0 = minp.y
local z0 = minp.z
--
local sidelen = maxp.x - minp.x + 1
local permapdims3d = {x = sidelen, y = sidelen, z = 0}
--ShadMOrdre
local overlen = sidelen + 5
local chulens = {x = overlen, y = overlen, z = 1}
local minpos = {x = x0 - 3, y = z0 - 3}
--
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
data = vm:get_data()
local a = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
local csize = vector.add(vector.subtract(maxp, minp), 1)
nobj_terrain = nobj_terrain or minetest.get_perlin_map(np_terrain, csize)
--nbase_terrain = nobj_terrain:get2dMap_flat({x=minp.x, y=minp.z})
isln_terrain=nobj_terrain:get_2d_map({x=minp.x,y=minp.z})
---- cliffs
nobj_cliffs = nobj_cliffs or minetest.get_perlin_map(np_cliffs, permapdims3d)
isln_cliffs = nobj_cliffs:get_2d_map({x=minp.x,y=minp.z})
nobj_heatmap = nobj_heatmap or minetest.get_perlin_map(np_heat, chulens)
nbase_heatmap = nobj_heatmap:get2dMap_flat({x=minp.x, y=minp.z})
nobj_heatblend = nobj_heatblend or minetest.get_perlin_map(np_heat_blend, chulens)
nbase_heatblend = nobj_heatblend:get2dMap_flat({x=minp.x, y=minp.z})
nobj_humiditymap = nobj_humiditymap or minetest.get_perlin_map(np_humid, chulens)
nbase_humiditymap = nobj_humiditymap:get2dMap_flat({x=minp.x, y=minp.z})
nobj_humidityblend = nobj_humidityblend or minetest.get_perlin_map(np_humid_blend, chulens)
nbase_humidityblend = nobj_humidityblend:get2dMap_flat({x=minp.x, y=minp.z})
-- Mapgen preparation is now finished. Check the timer to know the elapsed time.
local t1 = os.clock()
local write = false
-- 2D Generation loop.
local index2d = 0
for z = minp.z, maxp.z do
for x = minp.x, maxp.x do
index2d = (z - minp.z) * csize.x + (x - minp.x) + 1
--2D HEIGHTMAP GENERATION
local s_z, s_z_r
local s_x, s_x_r
local theight
local ntectonic_idx
local ntectonic_dist
local ntectonic_edist
--local ntectonic_mist
--local ntectonic_aist
if mg_map_view == false then
s_z, s_z_r = math.modf(z / map_tectonic_scale)
s_x, s_x_r = math.modf(x / map_tectonic_scale)
if s_z_r >= 5 then
s_z = s_z + 1
end
if s_x_r >= 5 then
s_x = s_x + 1
end
ntectonic_idx = mg_custom_data.base_tectonicmap[s_z][s_x].closest_idx
ntectonic_dist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_dist
ntectonic_edist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_edist
--ntectonic_mdist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_mdist
--ntectonic_adist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_adist
else
s_z = z
s_x = x
if ((z > -500) and (z < 500)) and ((x > -500) and (x < 500)) then
ntectonic_idx = mg_custom_data.base_tectonicmap[z][x].closest_idx
ntectonic_dist = mg_custom_data.base_tectonicmap[z][x].closest_dist
ntectonic_edist = mg_custom_data.base_tectonicmap[z][x].closest_edist
--ntectonic_mdist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_mdist
--ntectonic_adist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_adist
else
ntectonic_idx = -1234
ntectonic_dist = -2
ntectonic_edist = -2
end
end
--
if mg_map_view == false then
if ntectonic_idx <= 0 then
local cell1_idx
local cell1_pos_x
local cell1_pos_z
local cell2_idx
local cell2_pos_x
local cell2_pos_z
cell1_idx = mg_custom_data.base_edgemap[s_z][s_x].cell1_index
cell2_idx = mg_custom_data.base_edgemap[s_z][s_x].cell2_index
cell1_pos_x = mg_custom_data.base_cellmap[cell1_idx].x * map_tectonic_scale
cell1_pos_z = mg_custom_data.base_cellmap[cell1_idx].z * map_tectonic_scale
cell2_pos_x = mg_custom_data.base_cellmap[cell2_idx].x * map_tectonic_scale
cell2_pos_z = mg_custom_data.base_cellmap[cell2_idx].z * map_tectonic_scale
local cell1_dist = get_distance({x=x,y=z}, {x=cell1_pos_x,y=cell1_pos_z})
local cell1_edist = get_euclid_distance({x=x,y=z}, {x=cell1_pos_x,y=cell1_pos_z})
local cell2_dist = get_distance({x=x,y=z}, {x=cell2_pos_x,y=cell2_pos_z})
local cell2_edist = get_euclid_distance({x=x,y=z}, {x=cell2_pos_x,y=cell2_pos_z})
if cell1_dist == cell2_dist then
ntectonic_idx = 0
--ntectonic_dist = cell1_dist
--if cell1_edist > cell2_edist then
-- ntectonic_edist = (cell1_edist - cell2_edist) * 0.5
--elseif cell1_edist < cell2_edist then
-- ntectonic_edist = (cell2_edist - cell1_edist) * 0.5
--end
elseif cell1_dist > cell2_dist then
ntectonic_idx = cell2_idx
--ntectonic_dist = cell2_dist
--if cell1_edist > cell2_edist then
-- ntectonic_edist = (cell1_edist - cell2_edist) * 0.5
--elseif cell1_edist < cell2_edist then
-- ntectonic_edist = (cell2_edist - cell1_edist) * 0.5
--end
else
ntectonic_idx = cell1_idx
--ntectonic_dist = cell1_dist
--if cell1_edist > cell2_edist then
-- ntectonic_edist = (cell1_edist - cell2_edist) * 0.5
--elseif cell1_edist < cell2_edist then
-- ntectonic_edist = (cell2_edist - cell1_edist) * 0.5
--end
end
end
--
end
local ntectonic_rdist = (ntectonic_dist + ntectonic_edist) * 0.5 --ridges
local ntect_dist, ntect_dist_r = math.modf(ntectonic_dist * 0.1)
local ntect_edist, ntect_edist_r = math.modf(ntectonic_edist * 0.1)
--local ntect_mdist, ntect_mdist_r = math.modf(ntectonic_mdist * 0.1)
--local ntect_adist, ntect_adist_r = math.modf(ntectonic_adist * 0.1)
local ntect_rdist, ntect_rdist_r = math.modf(ntectonic_rdist * 0.1)
local nterrain = isln_terrain[z-minp.z+1][x-minp.x+1]
local cheight = isln_cliffs[z-minp.z+1][x-minp.x+1]
local ncontinental = get_terrain_height_shelf(ntectonic_edist) * -0.1
local nmountain = (get_terrain_height_shelf(ntectonic_rdist) * 0.1) - 2
if mg_map_view == false then
theight = get_terrain_height_hills_adjustable_shelf(nterrain + (math.max(ncontinental,nmountain)*0.5),(math.max(ncontinental,nmountain)*0.1),cheight,(ntect_rdist + (ntect_rdist / mg_golden_ratio))) - 2
else
theight = get_terrain_height_hills_adjustable_shelf(nterrain + (nmountain * 0.1),(nmountain * 0.1),cheight,(ntect_rdist + (ntect_rdist / mg_golden_ratio)) * 0.1) + 3
end
lib_mg_continental.heightmap[index2d] = theight - 1
end
end
--2D HEIGHTMAP GENERATION
local index2d = 0
--local idx = 1
for z = minp.z, maxp.z do
for y = minp.y, maxp.y do
for x = minp.x, maxp.x do
index2d = (z - minp.z) * csize.x + (x - minp.x) + 1
local ivm = a:index(x, y, z)
local theight = lib_mg_continental.heightmap[index2d]
if y <= theight + 1 then
local t_heat, t_humid, t_altitude, t_name
local nheat = nbase_heatmap[index2d] + nbase_heatblend[index2d]
local nhumid = nbase_humiditymap[index2d] + nbase_humidityblend[index2d]
if nheat < 12.5 then
t_heat = "cold"
elseif nheat >= 12.5 and nheat < 37.5 then
t_heat = "cool"
elseif nheat >= 37.5 and nheat < 62.5 then
t_heat = "temperate"
elseif nheat >= 62.5 and nheat < 87.5 then
t_heat = "warm"
elseif nheat >= 87.5 then
t_heat = "hot"
else
--t_heat = ""
end
if nhumid < 12.5 then
t_humid = "arid"
elseif nhumid >= 12.5 and nhumid < 37.5 then
t_humid = "semiarid"
elseif nhumid >= 37.5 and nhumid < 62.5 then
t_humid = "temperate"
elseif nhumid >= 62.5 and nhumid < 87.5 then
t_humid = "semihumid"
elseif nhumid >= 87.5 then
t_humid = "humid"
else
--t_humid = ""
end
if y >= lib_materials.ocean_depth and y < lib_materials.beach_depth then
t_altitude = "ocean"
elseif y >= lib_materials.beach_depth and y < lib_materials.maxheight_beach then
t_altitude = "beach"
elseif y >= lib_materials.maxheight_beach and y < lib_materials.maxheight_coastal then
t_altitude = "coastal"
elseif y >= lib_materials.maxheight_coastal and y < lib_materials.maxheight_lowland then
t_altitude = "lowland"
elseif y >= lib_materials.maxheight_lowland and y < lib_materials.maxheight_shelf then
t_altitude = "shelf"
elseif y >= lib_materials.maxheight_shelf and y < lib_materials.maxheight_highland then
t_altitude = "highland"
elseif y >= lib_materials.maxheight_highland and y < lib_materials.maxheight_mountain then
t_altitude = "mountain"
elseif y >= lib_materials.maxheight_mountain and y < lib_materials.maxheight_strato then
t_altitude = "strato"
else
--t_altitude = ""
end
if t_heat and t_heat ~= "" and t_humid and t_humid ~= "" and t_altitude and t_altitude ~= "" then
t_name = t_heat .. "_" .. t_humid .. "_" .. t_altitude
end
if y >= -31000 and y < -20000 then
t_name = "generic_mantle"
elseif y >= -20000 and y < -15000 then
t_name = "stone_basalt_01_layer"
elseif y >= -15000 and y < -10000 then
t_name = "stone_brown_layer"
elseif y >= -10000 and y < -6000 then
t_name = "stone_sand_layer"
elseif y >= -6000 and y < -5000 then
t_name = "desert_stone_layer"
elseif y >= -5000 and y < -4000 then
t_name = "desert_sandstone_layer"
elseif y >= -4000 and y < -3000 then
t_name = "generic_stone_limestone_01_layer"
elseif y >= -3000 and y < -2000 then
t_name = "generic_granite_layer"
elseif y >= -2000 and y < lib_materials.ocean_depth then
t_name = "generic_stone_layer"
else
end
local b_name, b_cid, b_top, b_top_d, b_fill, b_fill_d, b_stone, b_water_top, b_water_top_d, b_water, b_river, b_riverbed, b_riverbed_d
local b_caveliquid, b_dungeon, b_dungeonalt, b_dungeonstair, b_dust, b_ymin, b_ymax, b_heat, b_humid
if t_name == "" then
t_name = minetest.get_biome_name(minetest.get_biome_data({x,y,z}).biome)
end
local fill_depth = 1
local top_depth = 1
if t_name and t_name ~= "" then
b_name, b_cid, b_top, b_top_d, b_fill, b_fill_d, b_stone, b_water_top, b_water_top_d, b_water, b_river, b_riverbed, b_riverbed_d, b_caveliquid, b_dungeon, b_dungeonalt, b_dungeonstair, b_dust, b_ymin, b_ymax, b_heat, b_humid = unpack(lib_mg_continental.biome_info[t_name]:split("|", false))
c_stone = b_stone
c_dirt = b_fill
fill_depth = b_fill_d or 6
c_top = b_top
top_depth = b_top_d or 1
end
lib_mg_continental.biomemap[index2d] = b_cid
--VORONOI MARKERS FROM TECTONICMAP
local s_z, s_z_r
local s_x, s_x_r
local ntectonic_idx
local ntectonic_dist
--local ntectonic_eist
--local ntectonic_mist
--local ntectonic_aist
if mg_map_view == false then
s_z, s_z_r = math.modf(z / map_tectonic_scale)
s_x, s_x_r = math.modf(x / map_tectonic_scale)
if s_z_r >= 5 then
s_z = s_z + 1
end
if s_x_r >= 5 then
s_x = s_x + 1
end
ntectonic_idx = mg_custom_data.base_tectonicmap[s_z][s_x].closest_idx
ntectonic_dist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_dist
--ntectonic_edist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_edist
--ntectonic_mdist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_mdist
--ntectonic_adist = mg_custom_data.base_tectonicmap[s_z][s_x].closest_adist
else
s_z = z
s_x = x
if ((z > -500) and (z < 500)) and ((x > -500) and (x < 500)) then
ntectonic_idx = mg_custom_data.base_tectonicmap[z][x].closest_idx
ntectonic_dist = mg_custom_data.base_tectonicmap[z][x].closest_dist
ntectonic_edist = mg_custom_data.base_tectonicmap[z][x].closest_edist
else
ntectonic_idx = -1234
ntectonic_dist = -2
ntectonic_edist = -2
end
end
if ntectonic_dist == 0 then
c_top = c_obsidian
end
if mg_map_view == false then
if ntectonic_idx <= 0 then
local cell1_idx
local cell1_pos_x
local cell1_pos_z
local cell2_idx
local cell2_pos_x
local cell2_pos_z
cell1_idx = mg_custom_data.base_edgemap[s_z][s_x].cell1_index
cell2_idx = mg_custom_data.base_edgemap[s_z][s_x].cell2_index
cell1_pos_x = mg_custom_data.base_cellmap[cell1_idx].x * map_tectonic_scale
cell1_pos_z = mg_custom_data.base_cellmap[cell1_idx].z * map_tectonic_scale
cell2_pos_x = mg_custom_data.base_cellmap[cell2_idx].x * map_tectonic_scale
cell2_pos_z = mg_custom_data.base_cellmap[cell2_idx].z * map_tectonic_scale
local cell1_dist = get_distance({x=x,y=z}, {x=cell1_pos_x,y=cell1_pos_z})
local cell1_edist = get_euclid_distance({x=x,y=z}, {x=cell1_pos_x,y=cell1_pos_z})
local cell2_dist = get_distance({x=x,y=z}, {x=cell2_pos_x,y=cell2_pos_z})
local cell2_edist = get_euclid_distance({x=x,y=z}, {x=cell2_pos_x,y=cell2_pos_z})
if cell1_dist == cell2_dist then
ntectonic_idx = 0
ntectonic_dist = cell1_dist
ntectonic_edist = cell1_edist
c_top = c_obsidian
elseif cell1_dist > cell2_dist then
ntectonic_idx = cell2_idx
ntectonic_dist = cell2_dist
ntectonic_edist = cell2_edist
else
ntectonic_idx = cell1_idx
ntectonic_dist = cell1_dist
ntectonic_edist = cell1_edist
end
end
end
end
--NODE PLACEMENT FROM HEIGHTMAP
if y < (theight - (fill_depth + top_depth)) then
data[ivm] = c_stone
write = true
elseif y >= (theight - (fill_depth + top_depth)) and y < (theight - top_depth) then --math.ceil(nobj_terrain[index2d])
data[ivm] = c_dirt
write = true
elseif y >= (theight - top_depth) and y <= theight then --math.ceil(nobj_terrain[index2d])
data[ivm] = c_top
write = true
elseif y > theight and y <= 1 then
data[ivm] = c_water
write = true
else
data[ivm] = c_air
write = true
end
end
end
end
local t2 = os.clock()
if write then
vm:set_data(data)
end
local t3 = os.clock()
if write then
minetest.generate_ores(vm,minp,maxp)
minetest.generate_decorations(vm,minp,maxp)
vm:set_lighting({day = 0, night = 0})
vm:calc_lighting()
vm:update_liquids()
end
local t4 = os.clock()
if write then
vm:write_to_map()
end
local t5 = os.clock()
-- Print generation time of this mapchunk.
local chugent = math.ceil((os.clock() - t0) * 1000)
print ("[lib_mg_continental_mg_custom_biomes] Mapchunk generation time " .. chugent .. " ms")
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 > 1000 then
print("lib_mg_continental_mg_custom_biomes 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("lib_mg_continental_mg_custom_biomes 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)
minetest.register_on_newplayer(function(obj)
local nobj_terrain = minetest.get_perlin_map(np_terrain, {x=1,y=1,z=0})
local th=nobj_terrain:get_2d_map({x=1,y=1})
local height = 0
local ntect_idx = mg_custom_data.base_tectonicmap[0][0].closest_idx
local ntect_dist = mg_custom_data.base_tectonicmap[0][0].closest_dist
if ntect_dist == 0 then
ntect_dist = 1
end
height = ntect_dist / th[1][1]
minetest.set_timeofday(0.30)
return true
end)
Re: Post your mapgen questions here (modding or engine)
Hi all, hope you're all coping with the Current World Situation.
Question re V7 map - the trees all sit 1 node below ground level, where in V6 they sit ON ground level. Not an issue unless you're using Round Trunks, then things start to look a little untidy.
Is there a simple way to move all the trees up by 1 node in the generation of the map?
Question re V7 map - the trees all sit 1 node below ground level, where in V6 they sit ON ground level. Not an issue unless you're using Round Trunks, then things start to look a little untidy.
Is there a simple way to move all the trees up by 1 node in the generation of the map?
- Skamiz Kazzarch
- Member
- Posts: 618
- Joined: Fri Mar 09, 2018 20:34
- GitHub: Skamiz
- In-game: Skamiz
- Location: la lojbaugag.
Re: Post your mapgen questions here (modding or engine)
The simplest I can think of is going to the decoration definition and adding: 'place_offset_y = 1,'
The tree decoration deffinitions can be found in "your_minetest_folder/games/minetest_game/mods/default/magen.lua" and begin at line 1815.
If you want to know more about how decorations are registered, here is the documentation:
https://github.com/minetest/minetest/bl ... .txt#L7585
The tree decoration deffinitions can be found in "your_minetest_folder/games/minetest_game/mods/default/magen.lua" and begin at line 1815.
If you want to know more about how decorations are registered, here is the documentation:
https://github.com/minetest/minetest/bl ... .txt#L7585
- paramat
- Developer
- Posts: 3700
- Joined: Sun Oct 28, 2012 00:05
- GitHub: paramat
- IRC: paramat
- Location: UK
Re: Post your mapgen questions here (modding or engine)
> The simplest I can think of is going to the decoration definition and adding: 'place_offset_y = 1,'
This.
This.
Re: Post your mapgen questions here (modding or engine)
Thanks guys. I think I was trying place_offset_y + 1, and it took exception to the +. Will try this out.
Take care, y'all!
Take care, y'all!
-
- Member
- Posts: 41
- Joined: Sat Oct 21, 2017 18:12
- In-game: Kurtzmusch
Re: Post your mapgen questions here (modding or engine)
is it possible to obtain a vmanip of an area that hasnt been emerged or generated yet? if yes, will the singlenode mapgen eventually overwrite it with air?
Like Puzzles? Escape The Dungeon
Re: Post your mapgen questions here (modding or engine)
Mod A has a custom lua mapgen.
Mod B depends on mod A and defines schematic type decorations to be placed on nodes added by mod A.
No errors, mod A generates terrain just fine, but the schematics are never placed.
I checked that the right nodes are referenced, I've tried various things and the schematics are placed just fine in the default mapgen using default nodes, and I'm starting to think I'm missing something here.
Any idea?
edit: I guess I need to use https://dev.minetest.net/minetest.place ... _on_vmanip instead? Gonna try and wrap my head around that stuff.
Mod B depends on mod A and defines schematic type decorations to be placed on nodes added by mod A.
No errors, mod A generates terrain just fine, but the schematics are never placed.
I checked that the right nodes are referenced, I've tried various things and the schematics are placed just fine in the default mapgen using default nodes, and I'm starting to think I'm missing something here.
Any idea?
edit: I guess I need to use https://dev.minetest.net/minetest.place ... _on_vmanip instead? Gonna try and wrap my head around that stuff.
Who is online
Users browsing this forum: No registered users and 6 guests