123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612 |
- --[[
- ether_lands is a Minetest mod that adds its own floatlands-like map generation
- Copyright (C) 2019 Kurtzmusch
- This file is part of ether_lands
- ether_lands is free software; you can redistribute it and/or modify it under
- the terms of the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 2.1 of the License, or (at your option) any
- later version.
- ether_lands is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public License along
- with ether_lands. If not, see <https://www.gnu.org/licenses/>.
- --]]
- -- based on paramat's mapgen: fracture
- -- global tables --------------------------------------------------------------
- ether_lands = {} --external exposition of mod's tables and functions
- _ether_lands = {} --internal ^
- -- terrain parameters ---------------------------------------------------------
- local REALM_START = 2000 -- initial height for this realm
- local STONE_THRESHOLD = 0.03
- local DIRT_THRESHOLD = 0
- local HEIGHT_VARIANCE = 800 -- total height variance for the heightmap used to calculate biomes and overall height of layers
- local GRASS_FREQUENCY = 0.7
- local TREE_FREQUENCY = 0.001
- local TREE3_FREQUENCY = 0.1
- local CYANLANDS_DISPLACEMENT = 20
- local CYANLANDS_LAYER_HEIGHT = 350
- local CYANLANDS_BOTTOMGRADIENT_LENGHT = 32
- local CYANLANDS_TOPGRADIENT_LENGTH = 250 -- used to ease of the density of the noise as height within the layer increases
- local CYANLANDS_TOPGRADIENT_START = CYANLANDS_LAYER_HEIGHT-CYANLANDS_TOPGRADIENT_LENGTH -- height within the layer for the top gradient
- local CYANLANDS_HORIZONTAL_UPPERGRADIENT_LENGTH = 40 -- used to ease of the density of the noise in the edge with bluelands
- local CYANLANDS_HORIZONTAL_LOWERGRADIENT_LENGTH = 40 -- ^ orangelands
- -- TODO _BIOME_HEIGHT should have the same meaning for any biome
- local BLUELANDS_DISPLACEMENT = 20
- local BLUELANDS_BIOME_HEIGHT = HEIGHT_VARIANCE - 200 -- when the heightmap is above this, the biome is bluelands
- local BLUELANDS_LAYER_HEIGHT = 200
- local BLUELANDS_BOTTOMGRADIENT_LENGHT = 32
- local BLUELANDS_TOPGRADIENT_LENGTH = 100
- local BLUELANDS_TOPGRADIENT_START = BLUELANDS_LAYER_HEIGHT-BLUELANDS_TOPGRADIENT_LENGTH
- local BLUELANDS_HORIZONTAL_LOWERGRADIENT_LENGTH = 50
- local ORANGELANDS_LAYER_HEIGHT = 200
- local ORANGELANDS_TOPGRADIENT_LENGTH = 100
- local ORANGELANDS_BOTTOMGRADIENT_LENGHT = 32
- local ORANGELANDS_TOPGRADIENT_START = ORANGELANDS_LAYER_HEIGHT-ORANGELANDS_TOPGRADIENT_LENGTH
- local ORANGELANDS_BIOME_HEIGHT = 250 -- when the heightmap is below this, the biome is orangelands
- local ORANGELANDS_HORIZONTAL_UPPERGRADIENT_LENGTH = 50
- local REALM_FINISH = REALM_START+HEIGHT_VARIANCE
- +CYANLANDS_LAYER_HEIGHT+ORANGELANDS_LAYER_HEIGHT+BLUELANDS_LAYER_HEIGHT
- +CYANLANDS_DISPLACEMENT+BLUELANDS_DISPLACEMENT
- -- debug stuff
- local DEBUG_FLAGS = { debug_blocks=false, overwrite_seed = false, cherrypicked_spawn = false, cherrypick_biome=false, give_privs=false }
- local DEBUG_FREQUENCY = 5
- local DESIRED_BIOME = "orangelands"
- local debug_data = {
- mapblock_count = 0,
- timeAccumulator_total = 0,
- timeAccumulator_getNoise = 0,
- timeAccumulator_genIDs = 0,
- timeAccumulator_writeVM = 0,
- timeAccumulator_writeMap = 0,
- timeAccumulator_calcLight = 0,
- timeAccumulator_placeSchematics = 0,
- }
- local schematics_path = minetest.get_modpath("ether_lands").."/schematics/"
- ether_lands.schematics = {
- path = minetest.get_modpath("ether_lands").."/schematics/",
- cyanlands = {
- tree1 = schematics_path.."cyanlands_tree1.mts",
- tree2 = schematics_path.."cyanlands_tree2.mts",
- tree3 = schematics_path.."cyanlands_tree3.mts",
- },
- orangelands = {
- tree1 = schematics_path.."orangelands_tree1.mts",
- },
- bluelands = {
- tree1 = schematics_path.."bluelands_tree1.mts",
- },
- }
- -- noise parameters -----------------------------------------------------------
- ether_lands.trees_parameters = {
- offset = 0,
- scale = 1,
- spread = { x = 1200, y = 1200, z = 1200 },
- seed = 7,
- octaves = 2,
- persist = 1,
- lacunarity = 16,
- }
- ether_lands.heightmap_parameters = {
- offset = 0,
- scale = 1,
- spread = { x = 1200, y = 1200, z = 1200 },
- seed = 7,
- octaves = 1,
- persist = 1
- }
- ether_lands.cyanland_noise1_parameters = {
- offset = 0,
- scale = 1,
- spread = {x=384, y=128, z=384},
- seed = 593,
- octaves = 5,
- persist = 0.67
- }
- ether_lands.cyanland_noise2_parameters = {
- --second noise in golden ratio
- offset = 0,
- scale = 1,
- spread = {x=311, y=104, z=311},
- seed = 593,
- octaves = 5,
- persist = 0.67
- }
- -- mapgen ---------------------------------------------------------------------
- local modpath = minetest.get_modpath("ether_lands")
- dofile(modpath .. "/nodes.lua")
- local cid_debugnode_mapchunk = minetest.get_content_id("default:meselamp")
- local cid_debugnode_edge = minetest.get_content_id("ether_lands:debugnode_edge")
- local cid_debugnode_actualedge = minetest.get_content_id("ether_lands:debugnode_actualedge")
- local cid_stone_cyan = minetest.get_content_id("ether_lands:levistone_cyan")
- local cid_stone_blue = minetest.get_content_id("ether_lands:levistone_blue")
- local cid_stone_orange = minetest.get_content_id("ether_lands:levistone_orange")
- local cid_grass_cyan = minetest.get_content_id("ether_lands:grass_cyan")
- local cid_grass_blue = minetest.get_content_id("ether_lands:grass_blue")
- local cid_grass_orange = minetest.get_content_id("ether_lands:grass_orange")
- local cid_dirt_cyan = minetest.get_content_id("ether_lands:dirt_cyan")
- local cid_dirt_blue = minetest.get_content_id("ether_lands:dirt_blue")
- local cid_dirt_orange = minetest.get_content_id("ether_lands:dirt_orange")
- local cid_grass1_cyan = minetest.get_content_id("ether_lands:plant_1_grass_cyan")
- local cid_grass1_blue = minetest.get_content_id("ether_lands:plant_1_grass_blue")
- local cid_grass1_orange = minetest.get_content_id("ether_lands:plant_1_grass_orange")
- local cid_air = minetest.get_content_id("air")
- local emerged_dimensions
- local mapchunk_dimensions
- local cid_data
- local parama2_data
- local cyanland1_values
- local cyanland2_values
- local heightmap_values
- local mapchunk_length -- assumes mapchunks and emerged vmanips are always cubes
- local emerged_length
- minetest.register_on_mapgen_init( function(mapgen_params)
- if( DEBUG_FLAGS.overwrite_seed ) then minetest.set_mapgen_setting("seed", 10100000, true) end
- mapchunk_length = minetest.get_mapgen_setting("chunksize")*16 --TODO 16 should not be hard coded
- emerged_length = mapchunk_length+(16*2) --TODO figure out if emerged areas is always 1 mapblock bigger in all directions
-
- cid_data = {}
- cid_data[emerged_length^3] = cid_air
- param2_data = {}
- param2_data[emerged_length^3] = 0
- -- really hoping these are creating a contiguos array
- cyanland1_values = {}
- cyanland1_values[mapchunk_length^3] = 0
- cyanland2_values = {}
- cyanland2_values[mapchunk_length^3] = 0
- heightmap_values = {}
- heightmap_values[mapchunk_length^2] = 0
-
- end )
- -- places schematics directly in the map
- -- TODO figure out why placing on vmanip isnt working
- _ether_lands.generate_structures =
- function( cid_data, generate_VoxelArea, buffer_VoxelArea )
-
- local zmin = generate_VoxelArea.MinEdge.z
- local zmax = generate_VoxelArea.MaxEdge.z
- local ymin = generate_VoxelArea.MinEdge.y
- local ymax = generate_VoxelArea.MaxEdge.y
- local xmin = generate_VoxelArea.MinEdge.x
- local xmax = generate_VoxelArea.MaxEdge.x
- local node_index_in_emerged
- local node_index_in_mapchunk
- local node_2d_index = 1
-
- for z = zmin, zmax do
- for y = ymin, ymax do
- for x = xmin, xmax do
- local base_height = heightmap_values[node_2d_index] --TODO cache this for every x,z only
- base_height = (base_height+1)/2
- base_height = base_height * HEIGHT_VARIANCE
- local grass_id
- local trees_schematics
- if ( base_height > ORANGELANDS_BIOME_HEIGHT ) then
- grass_id = cid_grass_cyan
- trees_schematics = ether_lands.schematics.cyanlands
- end
- if( base_height > BLUELANDS_BIOME_HEIGHT ) then
- grass_id = cid_grass_blue
- trees_schematics = ether_lands.schematics.bluelands
- end
- if( base_height < ORANGELANDS_BIOME_HEIGHT ) then
- grass_id = cid_grass_orange
- trees_schematics = ether_lands.schematics.orangelands
- end
- local node_index_in_emerged = buffer_VoxelArea:index(x,y,z)
- if( cid_data[node_index_in_emerged] == grass_id ) then
- if( math.random() < TREE_FREQUENCY ) then
- local index_west = buffer_VoxelArea:index(x-1,y,z)
- local index_east = buffer_VoxelArea:index(x+1,y,z)
- local index_south = buffer_VoxelArea:index(x,y,z-1)
- local index_north = buffer_VoxelArea:index(x,y,z+1)
- if (cid_data[index_west] == grass_id
- and(cid_data[index_east] == grass_id )
- and(cid_data[index_south] == grass_id )
- and(cid_data[index_north] == grass_id )
- ) then
- minetest.place_schematic(
- {x=x, y=y, z=z},
- trees_schematics.tree1,
- "random",
- nil,
- true,
- "place_center_x,place_center_z"
- )
- end
- end
- end
- end
- end
- end
- end
- -- generates an area of the map and feeds the buffers, can be used for the mapgen, finding a spawnpoint or anything
- -- that needs to know about the terrain before its been generated
- -- the mapgen will call this and give it the voxelmanip buffers
- -- noise_buffers must be { heightmap_buffer=buffer, cyanland1_buffer=buffer, cyanland2_buffer=buffer }
- -- generate_VoxelArea is the area to be generated,
- -- buffer_VoxelArea is the area to be writen too( the sizes will match cid_buffer and param2_buffer), often times it is bigger than the generated area so the indexes are not the same
- ether_lands.generate_area =
- function( generate_VoxelArea, buffer_VoxelArea, cid_buffer, param2_buffer, noise_buffers, vmanip )
- local time_init
-
- local cyanland_noise1_generator = minetest.get_perlin_map(
- ether_lands.cyanland_noise1_parameters, generate_VoxelArea:getExtent() )
-
- local cyanland_noise2_generator = minetest.get_perlin_map(
- ether_lands.cyanland_noise2_parameters, generate_VoxelArea:getExtent() )
-
- local heightmap_generator = minetest.get_perlin_map(
- ether_lands.heightmap_parameters, {x=generate_VoxelArea:getExtent().x, y=generate_VoxelArea:getExtent().z} )
-
- time_init = os.clock()
- heightmap_generator:get_2d_map_flat(
- {x=generate_VoxelArea.MinEdge.x, y=generate_VoxelArea.MinEdge.z}, noise_buffers.heightmap_buffer )
- -- TODO only retrieve 3d noises if this mapchunk overlaps the biome edges
- -- otherwise skip get_map, and loops (maybe even return error so calc lighting and writing back can be skept)
- cyanland_noise1_generator:get_3d_map_flat(
- generate_VoxelArea.MinEdge, noise_buffers.cyanland1_buffer )
- cyanland_noise2_generator:get_3d_map_flat(
- generate_VoxelArea.MinEdge, noise_buffers.cyanland2_buffer )
- time_elapsed = ( os.clock()-time_init )*1000
- debug_data.timeAccumulator_getNoise = debug_data.timeAccumulator_getNoise + time_elapsed
- time_init = os.clock()
- local zmin = generate_VoxelArea.MinEdge.z
- local zmax = generate_VoxelArea.MaxEdge.z
- local ymin = generate_VoxelArea.MinEdge.y
- local ymax = generate_VoxelArea.MaxEdge.y
- local xmin = generate_VoxelArea.MinEdge.x
- local xmax = generate_VoxelArea.MaxEdge.x
- local node_index_in_emerged
- local node_index_in_mapchunk
- local node_2d_index = 1
- local grass_id = cid_grass_cyan
- local levistone_id = cid_stone_cyan
- local dirt_id = cid_dirt_cyan
- local plant1_id = cid_grass1_cyan
- for z = zmin, zmax do
- for y = ymin, ymax do
- for x = xmin, xmax do
- -- lots of stuff here can happen once per height
- local base_height = noise_buffers.heightmap_buffer[node_2d_index] --TODO cache this for every x,z only
- local height
- local max_height
- local top_gradient_start
- local top_gradient_length
- local horizontal_gradient
- local horizontal_gradient_start
- horizontal_gradient = 1
- node_2d_index = node_2d_index + 1
- base_height = (base_height+1)/2
- base_height = base_height * HEIGHT_VARIANCE
-
- height = base_height
- height = height + REALM_START
-
-
- --TODO precalc most of these and add horizontal_uppergradient_start and __lowergradient_start
- if( base_height < ORANGELANDS_BIOME_HEIGHT ) then
- levistone_id = cid_stone_orange
- grass_id = cid_grass_orange
- dirt_id = cid_dirt_orange
- plant1_id = cid_grass1_orange
- max_height = height+ORANGELANDS_LAYER_HEIGHT
- bottom_gradient_start = height
- bottom_gradient_length = ORANGELANDS_BOTTOMGRADIENT_LENGHT
- bottom_gradient_end = bottom_gradient_start + bottom_gradient_length
- top_gradient_start = height + ORANGELANDS_TOPGRADIENT_START
- top_gradient_length = ORANGELANDS_TOPGRADIENT_LENGTH
- horizontal_gradient_start = ORANGELANDS_BIOME_HEIGHT-ORANGELANDS_HORIZONTAL_UPPERGRADIENT_LENGTH
- horizontal_gradient = 1
- if( base_height > horizontal_gradient_start ) then
- horizontal_gradient = (ORANGELANDS_BIOME_HEIGHT-base_height)/ORANGELANDS_HORIZONTAL_UPPERGRADIENT_LENGTH
- end
- end
- if ( base_height > ORANGELANDS_BIOME_HEIGHT ) then
- height = height + ORANGELANDS_LAYER_HEIGHT+CYANLANDS_DISPLACEMENT
- max_height = height + CYANLANDS_LAYER_HEIGHT
- grass_id = cid_grass_cyan
- levistone_id = cid_stone_cyan
- dirt_id = cid_dirt_cyan
- plant1_id = cid_grass1_cyan
- bottom_gradient_start = height
- bottom_gradient_length = CYANLANDS_BOTTOMGRADIENT_LENGHT
- bottom_gradient_end = bottom_gradient_start + bottom_gradient_length
- top_gradient_start = height + CYANLANDS_TOPGRADIENT_START
- top_gradient_length = CYANLANDS_TOPGRADIENT_LENGTH
- horizontal_gradient = 1
- if( base_height < ORANGELANDS_BIOME_HEIGHT+CYANLANDS_HORIZONTAL_LOWERGRADIENT_LENGTH ) then
- horizontal_gradient_start = ORANGELANDS_BIOME_HEIGHT+CYANLANDS_HORIZONTAL_LOWERGRADIENT_LENGTH
- if( base_height < horizontal_gradient_start ) then
- horizontal_gradient = (base_height-ORANGELANDS_BIOME_HEIGHT)/CYANLANDS_HORIZONTAL_LOWERGRADIENT_LENGTH
- end
- elseif( base_height > BLUELANDS_BIOME_HEIGHT-CYANLANDS_HORIZONTAL_UPPERGRADIENT_LENGTH ) then
- horizontal_gradient_start = BLUELANDS_BIOME_HEIGHT-CYANLANDS_HORIZONTAL_UPPERGRADIENT_LENGTH
- if( base_height > horizontal_gradient_start ) then
- horizontal_gradient = (BLUELANDS_BIOME_HEIGHT-base_height)/CYANLANDS_HORIZONTAL_UPPERGRADIENT_LENGTH
- end
- end
- end
- if( base_height > BLUELANDS_BIOME_HEIGHT ) then
- height = height + CYANLANDS_LAYER_HEIGHT+BLUELANDS_DISPLACEMENT
- max_height = height + BLUELANDS_LAYER_HEIGHT
- levistone_id = cid_stone_blue
- grass_id = cid_grass_blue
- dirt_id = cid_dirt_blue
- plant1_id = cid_grass1_blue
- bottom_gradient_start = height
- bottom_gradient_length = BLUELANDS_BOTTOMGRADIENT_LENGHT
- bottom_gradient_end = bottom_gradient_start + bottom_gradient_length
- top_gradient_start = height + BLUELANDS_TOPGRADIENT_START
- top_gradient_length = BLUELANDS_TOPGRADIENT_LENGTH
- horizontal_gradient_start = BLUELANDS_BIOME_HEIGHT+BLUELANDS_HORIZONTAL_LOWERGRADIENT_LENGTH
- horizontal_gradient = 1
- if( base_height < horizontal_gradient_start ) then
- horizontal_gradient = (base_height-BLUELANDS_BIOME_HEIGHT)/BLUELANDS_HORIZONTAL_LOWERGRADIENT_LENGTH
- end
- end
- if( (y > height) and (y < max_height) ) then
- local node_index_in_mapchunk = generate_VoxelArea:index(x,y,z)
- local cyanland1_density = noise_buffers.cyanland1_buffer[node_index_in_mapchunk]
- local cyanland2_density = noise_buffers.cyanland2_buffer[node_index_in_mapchunk]
- local density = (cyanland1_density + cyanland2_density)/2
- local top_gradient = 1
- local bottom_gradient = 1
- local gradient = horizontal_gradient
- if( y>top_gradient_start ) then
- top_gradient = (max_height-y)/top_gradient_length
- end
- if( y<bottom_gradient_end ) then
- bottom_gradient = (y-bottom_gradient_start)/bottom_gradient_length
- end
- -- pick the smaller gradient. assumes bottom and top gradient never overlaps
- if( top_gradient < horizontal_gradient ) then gradient = top_gradient end
- if( bottom_gradient < horizontal_gradient ) then gradient = bottom_gradient end
-
- density = ( (density+1)*gradient ) -1
- if( density > STONE_THRESHOLD) then
- node_index_in_emerged = buffer_VoxelArea:index(x, y, z)
- cid_buffer[node_index_in_emerged] = levistone_id
- elseif( (y > ymin)
- and ( density > DIRT_THRESHOLD )
- --TODO by checking not air, this allows to dirt to balance above grass
- and (cid_buffer[buffer_VoxelArea:index(x, y-1, z)]~=cid_air) ) then --this seems to cause performance issues... maybe accesing array in wrong order takes it away from cpu cache?
- -- skiping checks, but still writing to array makes manip time twice as fast
- --could be the checks themselves or wrong read order
- node_index_in_emerged = buffer_VoxelArea:index(x, y, z)
- cid_buffer[node_index_in_emerged] = dirt_id
- elseif( ( y > ymin)
- and ( (cid_buffer[buffer_VoxelArea:index(x, y-1, z)]==dirt_id )
- or (cid_buffer[buffer_VoxelArea:index(x, y-1, z)]==levistone_id) ) ) then
- node_index_in_emerged = buffer_VoxelArea:index(x, y, z)
- cid_buffer[node_index_in_emerged] = grass_id
- elseif( (y > ymin)
- and ( cid_buffer[buffer_VoxelArea:index(x, y-1, z)]==grass_id )
- and ( math.random() < GRASS_FREQUENCY ) ) then
- if( math.fmod(y, 25) == 0) and (math.fmod(x, 25) == 0 ) then
- --what is this?
- end
- node_index_in_emerged = buffer_VoxelArea:index(x, y, z)
- cid_buffer[node_index_in_emerged] = plant1_id
- local p2 = 8
- local r = math.random()
- if( r > 0.7 ) then p2 = 10 elseif( r < 0.3 ) then p2 = 40 end
- param2_buffer[node_index_in_emerged] = p2
- end
-
- end
- if( DEBUG_FLAGS.debug_blocks ) then
- if (( y == math.floor(height) ) or ( y == math.floor(max_height) ))
- then
- node_index_in_emerged = buffer_VoxelArea:index(x, y, z)
- cid_buffer[node_index_in_emerged] = cid_debugnode_edge
- end
- local actualedge_min = height
- local actualedge_max = top_gradient_start+top_gradient_length*0.5 -- 0.5 is dirt density remaped to [0:1]
- if (( y == math.floor(actualedge_min) ) or ( y == math.floor(actualedge_max) ))
- then
- node_index_in_emerged = buffer_VoxelArea:index(x, y, z)
- cid_buffer[node_index_in_emerged] = cid_debugnode_actualedge
- end
- if (( x == xmin+16*2+8) or ( x == xmin+16*2+1+8 ))
- and(( y == ymin+16*2+8) or ( y == ymin+16*2+1+8 ))
- and(( z == zmin+16*2+8) or ( z == zmin+16*2+1+8 ))
- then
- node_index_in_emerged = buffer_VoxelArea:index(x, y, z)
- cid_buffer[node_index_in_emerged] = cid_debugnode_mapchunk
- end
- end
- end
- node_2d_index = node_2d_index - generate_VoxelArea:getExtent().x
- end
- node_2d_index = node_2d_index + generate_VoxelArea:getExtent().x
- end
- time_elapsed = ( os.clock()-time_init )*1000
- debug_data.timeAccumulator_genIDs = debug_data.timeAccumulator_genIDs + time_elapsed
- end
- local debug_timer = 0
- _ether_lands.on_globalstep = function( delta_time )
- debug_timer = debug_timer + delta_time
- if( debug_timer >= DEBUG_FREQUENCY ) then
- minetest.log("warning", "----timers-------------------------------------------------------------" )
- minetest.log("warning", "avg total time: "..math.ceil( debug_data.timeAccumulator_total/debug_data.mapblock_count).."ms" )
- minetest.log("warning", "avg get noise values: "..math.ceil( debug_data.timeAccumulator_getNoise/debug_data.mapblock_count).."ms" )
- minetest.log("warning", "avg manipulate mapchunk data: "..math.ceil( debug_data.timeAccumulator_genIDs/debug_data.mapblock_count).."ms" )
- minetest.log("warning", "avg write to vm: "..math.ceil( debug_data.timeAccumulator_writeVM/debug_data.mapblock_count).."ms" )
- minetest.log("warning", "avg write to map: "..math.ceil(debug_data.timeAccumulator_writeMap/debug_data.mapblock_count).."ms" )
- minetest.log("warning", "avg place schematics: "..math.ceil(debug_data.timeAccumulator_placeSchematics/debug_data.mapblock_count).."ms" )
- minetest.log( "warning", "memory: " .. math.ceil(collectgarbage("count")/1024) )
- minetest.log("warning", "-----------------------------------------------------------------------" )
- debug_timer = 0
- end
- end
- _ether_lands.on_generated = function( min_mapchunk_position, max_mapchunk_position, seed )
- if( min_mapchunk_position.y > REALM_FINISH ) then return end
- if( max_mapchunk_position.y < REALM_START ) then return end
-
- debug_data.mapblock_count = debug_data.mapblock_count + 1
- local time_total_init = os.clock()
- local time_total_elapsed
- --this is done here because afaik there is no way to get mapchunk dimensions elsewhere
- -- try to get smaller voxelmanips since we dont care whatever coremapgen is doing
- local voxelmanip, min_emerged_position, max_emerged_position = minetest.get_mapgen_object("voxelmanip")
- min_mapchunk_position.y = min_mapchunk_position.y - 8 --generate area that is bigger in -y direction to avoid discontinuities due to dirt requiring stone support
-
- local mapchunk_area = VoxelArea:new{MinEdge=min_mapchunk_position, MaxEdge=max_mapchunk_position}
- local emerged_area = VoxelArea:new{MinEdge=min_emerged_position, MaxEdge=max_emerged_position}
- voxelmanip:get_data(cid_data)
- voxelmanip:get_param2_data(param2_data)
- ether_lands.generate_area( mapchunk_area, emerged_area, cid_data, param2_data,
- { heightmap_buffer=heightmap_values, cyanland1_buffer=cyanland1_values, cyanland2_buffer=cyanland2_values }, voxelmanip )
- local time_writeToVM_init = os.clock()
- local time_writeToVM_elapsed
-
- voxelmanip:set_data(cid_data)
- voxelmanip:set_param2_data(param2_data)
- voxelmanip:set_lighting( {day=9, night=0} )
- voxelmanip:calc_lighting()
- time_writeToVM_elapsed = (os.clock()-time_writeToVM_init)*1000
- debug_data.timeAccumulator_writeVM = debug_data.timeAccumulator_writeVM + time_writeToVM_elapsed
- local time_writeToMap_init = os.clock()
- local time_writeToMap_elapsed
-
- voxelmanip:write_to_map()
-
- time_writeToMap_elapsed = (os.clock()-time_writeToMap_init)*1000
- debug_data.timeAccumulator_writeMap = debug_data.timeAccumulator_writeMap + time_writeToMap_elapsed
-
- local time_placeSchematics_init = os.clock()
- local time_placeSchematics_elapsed
-
- _ether_lands.generate_structures( cid_data, mapchunk_area, emerged_area )
-
- time_placeSchematics_elapsed = (os.clock()-time_placeSchematics_init)*1000
- debug_data.timeAccumulator_placeSchematics = debug_data.timeAccumulator_placeSchematics + time_placeSchematics_elapsed
-
- time_total_elapsed = (os.clock()-time_total_init)*1000
- debug_data.timeAccumulator_total = debug_data.timeAccumulator_total + time_total_elapsed
- end
- local function find_spawn()
- for gx = -20000, 20000, 1000 do
- for gz = -20000, 20000, 1000 do
- minetest.log("warning", "trying to find spawn at x: ".. gx .. " z: " ..gz)
- local ymax = REALM_FINISH
- local ymin = REALM_START
- local gen_area = VoxelArea:new{ MinEdge={ x=gx, y=ymin, z=gz }, MaxEdge={ x=gx+1, y=ymax, z=gz+1} } -- it seems the perling generators cant handle a 1x1 column TODO report issue on this
- local cid_buffer = {}
- cid_buffer[gen_area:getVolume()] = 0
- for i = 1, gen_area:getVolume() do
- cid_buffer[i] = cid_air
- end
- local param2_buffer = {}
- param2_buffer[gen_area:getVolume()] = 0
- local h_values = {}
- h_values[4] = 0
- local c1_values = {}
- c1_values[gen_area:getVolume()] = 0
- local c2_values = {}
- c2_values[gen_area:getVolume()] = 0
- ether_lands.generate_area( gen_area, gen_area, cid_buffer, param2_buffer,
- { heightmap_buffer=h_values, cyanland1_buffer=c1_values, cyanland2_buffer=c2_values } )
- local current_biome
- local skip=false
- local height = (h_values[1]+1)/2
- height = height*HEIGHT_VARIANCE
- if( DEBUG_FLAGS.cherrypick_biome ) then
- if( height < BLUELANDS_BIOME_HEIGHT ) then current_biome = "cyanlands" end
- if( height < ORANGELANDS_BIOME_HEIGHT ) then current_biome = "orangelands" end
- if( height > BLUELANDS_BIOME_HEIGHT ) then current_biome = "bluelands" end
- if( current_biome~=DESIRED_BIOME ) then skip=true end
- end
- if not skip then
- for y = ymax-1, ymin, -1 do
- local i = gen_area:index( gx, y, gz )
- local iabove = gen_area:index( gx, y+1, gz)
- local ibelow = gen_area:index( gx, y-1, gz)
- -- yikes
- if( ( (cid_buffer[i] == cid_air)
- or (cid_buffer[i] == cid_grass1_cyan)
- or (cid_buffer[i] == cid_grass1_orange)
- or (cid_buffer[i] == cid_grass1_blue) )
- and( cid_buffer[iabove] == cid_air)
- and( ( cid_buffer[ibelow] == cid_grass_cyan )
- or (cid_buffer[ibelow]==cid_grass_orange)
- or (cid_buffer[ibelow]==cid_grass_blue) ) )
- then
- return {x=gx, y=y, z=gz}
- end
- end
- end
- end
- end
- return {x=0,y=0,z=0}
- end
- minetest.register_on_joinplayer( function( player )
- minetest.set_timeofday(8/24)
- if( DEBUG_FLAGS.cherrypicked_spawn ) then player:set_pos({x=510,y=656, z=4850})
- else
- player:set_pos(find_spawn())
- end
- player:set_sky( {a=1,r=240,g=240,b=230}, "plain", false )
- player:set_physics_override( { speed=2} )
- if( DEBUG_FLAGS.give_privs ) then
- minetest.set_player_privs("singleplayer", {fly=true,noclip=true,fast=true, settime=true})
- end
- end )
- minetest.register_globalstep( _ether_lands.on_globalstep )
- minetest.register_on_generated( _ether_lands.on_generated )
|