2024-01-10 22:16:52 -06:00
--[[
Everness . Never ending discovery in Everness mapgen .
Copyright ( C ) 2024 SaKeL
This library 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 .
This library 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 .
--]]
--
-- Register biomes
--
local y_max = Everness.settings . biomes.everness_mineral_waters . y_max
local y_min = Everness.settings . biomes.everness_mineral_waters . y_min
-- Mineral Waters
2024-01-25 14:31:55 -06:00
Everness : register_biome ( {
name = ' everness:mineral_waters ' ,
2024-01-10 22:16:52 -06:00
node_top = ' everness:mineral_sand ' ,
depth_top = 1 ,
node_filler = ' everness:mineral_stone ' ,
depth_filler = 1 ,
node_stone = ' everness:mineral_stone ' ,
node_riverbed = ' everness:mineral_sand ' ,
depth_riverbed = 2 ,
node_dungeon = ' everness:mineral_stone_brick ' ,
node_dungeon_alt = ' everness:mineral_stone_brick_with_growth ' ,
2024-01-19 14:41:16 -06:00
node_dungeon_stair = ' stairs:stair_mineral_stone_brick ' ,
2024-01-10 22:16:52 -06:00
y_max = y_max ,
y_min = y_min ,
2024-01-19 14:47:12 -06:00
vertical_blend = 16 ,
2024-01-10 22:16:52 -06:00
heat_point = 78 ,
humidity_point = 58 ,
} )
2024-01-11 14:11:24 -06:00
--
-- Register ores
--
-- Scatter ores
-- Coal
2024-01-25 14:31:55 -06:00
Everness : register_ore ( {
2024-01-11 14:11:24 -06:00
ore_type = ' scatter ' ,
ore = ' everness:mineral_stone_with_coal ' ,
wherein = ' everness:mineral_stone ' ,
clust_scarcity = 8 * 8 * 8 ,
clust_num_ores = 9 ,
clust_size = 3 ,
y_max = y_max ,
y_min = y_min ,
2024-01-25 19:44:27 -06:00
biomes = { ' everness:mineral_waters ' }
2024-01-11 14:11:24 -06:00
} )
2024-01-25 14:31:55 -06:00
Everness : register_ore ( {
2024-01-22 13:48:57 -06:00
ore_type = ' scatter ' ,
ore = ' everness:mineral_stone_with_ceramic_sherds ' ,
wherein = ' everness:mineral_stone ' ,
clust_scarcity = 14 * 14 * 14 ,
clust_num_ores = 5 ,
clust_size = 3 ,
y_max = y_max ,
y_min = y_min ,
2024-01-25 19:44:27 -06:00
biomes = { ' everness:mineral_waters ' }
2024-01-22 13:48:57 -06:00
} )
2024-01-10 22:16:52 -06:00
--
-- Register decorations
2024-01-19 12:03:26 -06:00
-- placeholder node `everness:crystal_stone` will be replaced in VM
2024-01-10 22:16:52 -06:00
--
2024-01-25 14:31:55 -06:00
Everness : register_decoration ( {
2024-01-19 12:03:26 -06:00
name = ' everness:palm_trees ' ,
deco_type = ' simple ' ,
2024-01-10 22:16:52 -06:00
place_on = { ' everness:mineral_sand ' } ,
sidelen = 16 ,
noise_params = {
offset = 0 ,
2024-01-19 12:03:26 -06:00
scale = 0.005 ,
spread = { x = 250 , y = 250 , z = 250 } ,
2024-01-10 22:16:52 -06:00
seed = 329 ,
octaves = 3 ,
persist = 0.6
} ,
2024-01-25 19:44:27 -06:00
biomes = { ' everness:mineral_waters ' } ,
2024-01-10 22:16:52 -06:00
y_max = y_max ,
y_min = y_min ,
2024-01-19 12:03:26 -06:00
decoration = { ' everness:crystal_stone ' } ,
2024-01-10 22:16:52 -06:00
} )
2024-01-25 14:31:55 -06:00
Everness : register_decoration ( {
2024-01-19 12:03:26 -06:00
name = ' everness:pots ' ,
deco_type = ' simple ' ,
2024-01-10 22:16:52 -06:00
place_on = { ' everness:mineral_sand ' } ,
sidelen = 16 ,
noise_params = {
offset = 0 ,
2024-01-19 12:03:26 -06:00
scale = 0.002 ,
spread = { x = 250 , y = 250 , z = 250 } ,
seed = 2 ,
2024-01-10 22:16:52 -06:00
octaves = 3 ,
2024-01-19 12:03:26 -06:00
persist = 0.66
2024-01-10 22:16:52 -06:00
} ,
2024-01-25 19:44:27 -06:00
biomes = { ' everness:mineral_waters ' } ,
2024-01-10 22:16:52 -06:00
y_max = y_max ,
y_min = y_min ,
2024-01-19 12:03:26 -06:00
decoration = { ' everness:crystal_stone ' } ,
_decoration = {
2024-01-22 13:48:57 -06:00
' everness:ceramic_pot_blank ' ,
' everness:ceramic_pot_flowers ' ,
' everness:ceramic_pot_lines ' ,
' everness:ceramic_pot_tribal '
2024-01-19 12:03:26 -06:00
}
2024-01-10 22:16:52 -06:00
} )
2024-01-25 14:31:55 -06:00
Everness : register_decoration ( {
2024-01-10 22:16:52 -06:00
name = ' everness:water_geyser ' ,
deco_type = ' simple ' ,
place_on = { ' everness:mineral_sand ' } ,
sidelen = 16 ,
noise_params = {
2024-01-11 14:11:24 -06:00
offset = - 0.004 ,
2024-01-10 22:16:52 -06:00
scale = 0.02 ,
2024-01-11 14:11:24 -06:00
spread = { x = 100 , y = 100 , z = 100 } ,
seed = 137 ,
2024-01-10 22:16:52 -06:00
octaves = 3 ,
2024-01-11 14:11:24 -06:00
persist = 0.7 ,
2024-01-10 22:16:52 -06:00
} ,
2024-01-25 19:44:27 -06:00
biomes = { ' everness:mineral_waters ' } ,
2024-01-10 22:16:52 -06:00
y_max = y_max ,
y_min = y_min ,
2024-01-19 12:03:26 -06:00
decoration = { ' everness:crystal_stone ' } ,
spawn_by = { ' air ' } ,
num_spawn_by = 16 ,
check_offset = 1 ,
} )
2024-01-25 14:31:55 -06:00
Everness : register_decoration ( {
2024-01-19 12:03:26 -06:00
name = ' everness:rose_bush ' ,
deco_type = ' simple ' ,
place_on = { ' everness:mineral_sand ' } ,
sidelen = 16 ,
noise_params = {
offset = - 0.004 ,
scale = 0.01 ,
spread = { x = 100 , y = 100 , z = 100 } ,
seed = 137 ,
octaves = 3 ,
persist = 0.7 ,
2024-01-10 22:16:52 -06:00
} ,
2024-01-25 19:44:27 -06:00
biomes = { ' everness:mineral_waters ' } ,
2024-01-19 12:03:26 -06:00
y_max = y_max ,
y_min = y_min ,
decoration = { ' everness:crystal_stone ' } ,
_decoration = { ' everness:rose_bush ' } ,
spawn_by = { ' air ' } ,
num_spawn_by = 16 ,
check_offset = 1 ,
2024-01-10 22:16:52 -06:00
} )
--
-- On Generated
--
-- Get the content IDs for the nodes used
local c_everness_mineral_water_source = minetest.get_content_id ( ' everness:mineral_water_source ' )
local c_everness_mineral_stone = minetest.get_content_id ( ' everness:mineral_stone ' )
local c_everness_mineral_stone_brick = minetest.get_content_id ( ' everness:mineral_stone_brick ' )
local c_everness_mineral_stone_brick_with_growth = minetest.get_content_id ( ' everness:mineral_stone_brick_with_growth ' )
local c_everness_mineral_stone_brick_with_flower_growth = minetest.get_content_id ( ' everness:mineral_stone_brick_with_flower_growth ' )
local c_everness_mineral_sand = minetest.get_content_id ( ' everness:mineral_sand ' )
local c_everness_mineral_sandstone = minetest.get_content_id ( ' everness:mineral_sandstone ' )
local c_everness_mineral_sandstone_block = minetest.get_content_id ( ' everness:mineral_sandstone_block ' )
2024-01-25 22:36:05 -06:00
local c_everness_chest = minetest.get_content_id ( ' everness:chest ' )
2024-01-11 14:11:24 -06:00
local c_everness_mineral_stone_with_coal = minetest.get_content_id ( ' everness:mineral_stone_with_coal ' )
2024-01-22 13:48:57 -06:00
local c_everness_mineral_stone_with_ceramic_sherds = minetest.get_content_id ( ' everness:mineral_stone_with_ceramic_sherds ' )
2024-01-19 12:03:26 -06:00
local c_everness_lotus_flower_white = minetest.get_content_id ( ' everness:lotus_flower_white ' )
local c_everness_lotus_flower_purple = minetest.get_content_id ( ' everness:lotus_flower_purple ' )
local c_everness_lotus_flower_pink = minetest.get_content_id ( ' everness:lotus_flower_pink ' )
local c_everness_lotus_lotus_leaf = minetest.get_content_id ( ' everness:lotus_leaf ' )
local c_everness_lotus_lotus_leaf_2 = minetest.get_content_id ( ' everness:lotus_leaf_2 ' )
local c_everness_lotus_lotus_leaf_3 = minetest.get_content_id ( ' everness:lotus_leaf_3 ' )
2024-01-22 13:48:57 -06:00
local c_everness_ceramic_pot_blank = minetest.get_content_id ( ' everness:ceramic_pot_blank ' )
local c_everness_ceramic_pot_flowers = minetest.get_content_id ( ' everness:ceramic_pot_flowers ' )
local c_everness_ceramic_pot_lines = minetest.get_content_id ( ' everness:ceramic_pot_lines ' )
local c_everness_ceramic_pot_tribal = minetest.get_content_id ( ' everness:ceramic_pot_tribal ' )
2024-01-19 12:03:26 -06:00
local c_everness_mineral_water_weed_1 = minetest.get_content_id ( ' everness:mineral_water_weed_1 ' )
local c_everness_mineral_water_weed_2 = minetest.get_content_id ( ' everness:mineral_water_weed_2 ' )
local c_everness_mineral_water_weed_3 = minetest.get_content_id ( ' everness:mineral_water_weed_3 ' )
-- Biome IDs
2024-01-25 19:44:27 -06:00
local biome_id_everness_mineral_waters = minetest.get_biome_id ( ' everness:mineral_waters ' )
2024-01-19 12:03:26 -06:00
-- Decoration IDs
local d_everness_palm_trees = minetest.get_decoration_id ( ' everness:palm_trees ' )
local d_everness_water_geyser = minetest.get_decoration_id ( ' everness:water_geyser ' )
local d_everness_pots = minetest.get_decoration_id ( ' everness:pots ' )
local d_rose_bush = minetest.get_decoration_id ( ' everness:rose_bush ' )
2024-01-10 22:16:52 -06:00
2024-01-19 12:03:26 -06:00
-- Pool building blocks variations
2024-01-10 22:16:52 -06:00
local pool_build_nodes = {
{
c_everness_mineral_stone ,
c_everness_mineral_stone_brick ,
c_everness_mineral_stone_brick_with_growth ,
c_everness_mineral_stone_brick_with_flower_growth
} ,
{
c_everness_mineral_sandstone ,
c_everness_mineral_sandstone_block
}
}
2024-01-19 12:03:26 -06:00
local c_lotus_flowers = {
c_everness_lotus_flower_white ,
c_everness_lotus_flower_purple ,
c_everness_lotus_flower_pink
}
local c_lotus_leaves = {
c_everness_lotus_lotus_leaf ,
c_everness_lotus_lotus_leaf_2 ,
c_everness_lotus_lotus_leaf_3
}
local c_pots = {
2024-01-22 13:48:57 -06:00
c_everness_ceramic_pot_blank ,
c_everness_ceramic_pot_flowers ,
c_everness_ceramic_pot_lines ,
c_everness_ceramic_pot_tribal
2024-01-19 12:03:26 -06:00
}
local c_water_weeds = {
c_everness_mineral_water_weed_1 ,
c_everness_mineral_water_weed_2
}
2024-01-10 22:16:52 -06:00
local function find_irecursive ( table , c_id )
local found = false
for i , v in ipairs ( table ) do
if type ( v ) == ' table ' then
find_irecursive ( v , c_id )
end
if c_id == v then
found = true
break
end
end
return found
end
2024-01-19 12:03:26 -06:00
local function place_decoration ( pos , vm , area , data , deco_id , callback )
local deco_def = minetest.registered_decorations [ deco_id ]
if not deco_def then
return
end
-- Position of the 'place_on' node
local vi = area : indexp ( pos )
local place_on_valid = false
local data_node_name = minetest.get_name_from_content_id ( data [ vi ] )
local placeholder_node_name = type ( deco_def.decoration ) == ' string ' and deco_def.decoration or deco_def.decoration [ 1 ]
if type ( deco_def.place_on ) == ' string ' then
if deco_def.place_on == data_node_name and data [ vi + area.ystride * 2 ] == minetest.CONTENT_AIR then
place_on_valid = true
end
else
for i , v in ipairs ( deco_def.place_on ) do
if v == data_node_name and data [ vi + area.ystride * 2 ] == minetest.CONTENT_AIR then
place_on_valid = true
break
end
end
end
local pos_above = vector.new ( pos.x , pos.y + 1 , pos.z )
local node_above = vm : get_node_at ( pos_above )
if node_above.name == placeholder_node_name then
if place_on_valid then
callback ( pos_above , deco_def )
else
vm : set_node_at ( pos_above , { name = ' air ' } )
end
end
end
2024-01-11 14:11:24 -06:00
-- Localize data buffer table outside the loop, to be re-used for all
-- mapchunks, therefore minimising memory use
local data = { }
2024-01-19 12:03:26 -06:00
local p2data = { }
minetest.set_gen_notify ( { decoration = true } , {
d_everness_palm_trees ,
d_everness_water_geyser ,
d_everness_pots ,
d_rose_bush
} )
2024-01-11 14:11:24 -06:00
2024-01-10 22:16:52 -06:00
-- Called after generating a piece of world. Modifying nodes inside the area is a bit faster than usual.
minetest.register_on_generated ( function ( minp , maxp , blockseed )
-- Start time of mapchunk generation.
-- local t0 = os.clock()
2024-01-11 14:11:24 -06:00
-- Returns an array containing the biome IDs of nodes in the most recently generated chunk by the current mapgen
local biomemap = minetest.get_mapgen_object ( ' biomemap ' )
2024-01-25 22:36:05 -06:00
local chest_positions = { }
2024-01-19 12:03:26 -06:00
-- Above sea level
if maxp.y >= y_min and table.indexof ( biomemap , biome_id_everness_mineral_waters ) ~= - 1 then
local rand = PcgRandom ( blockseed )
2024-01-10 22:16:52 -06:00
local rand_version = rand : next ( 1 , 2 )
2024-01-19 12:03:26 -06:00
-- Load the voxelmanip with the result of engine mapgen
local vm , emin , emax = minetest.get_mapgen_object ( ' voxelmanip ' )
-- Returns a table mapping requested generation notification types to arrays of positions at which the corresponding generated structures are located within the current chunk
local gennotify = minetest.get_mapgen_object ( ' gennotify ' )
-- 'area' is used later to get the voxelmanip indexes for positions
local area = VoxelArea : new ( { MinEdge = emin , MaxEdge = emax } )
-- Get the content ID data from the voxelmanip in the form of a flat array.
-- Set the buffer parameter to use and reuse 'data' for this.
vm : get_data ( data )
vm : get_param2_data ( p2data )
local pot_pos = { }
2024-01-10 22:16:52 -06:00
if rand_version == 1 then
2024-01-11 14:11:24 -06:00
--
-- Pools
--
2024-01-10 22:16:52 -06:00
for y = minp.y , maxp.y do
for z = minp.z , maxp.z do
2024-01-11 14:11:24 -06:00
local precision_perc = 75
2024-01-10 22:16:52 -06:00
for x = minp.x , maxp.x do
local ai = area : index ( x , y , z )
local node_name = minetest.get_name_from_content_id ( data [ ai ] )
local node_def = minetest.registered_nodes [ node_name ]
if
data [ ai + area.ystride ] == minetest.CONTENT_AIR
and node_def
and node_def.walkable
then
local length = 5 + rand : next ( 0 , 10 )
local width = 5 + rand : next ( 0 , 10 )
local height = 3 + rand : next ( 0 , 4 )
2024-01-11 14:11:24 -06:00
local walkable_nodes = 0
2024-01-10 22:16:52 -06:00
-- find space for lake (walkable rectangle)
2024-01-11 14:11:24 -06:00
for li = 1 , length do
for wi = 1 , width do
local ai_rec = ( ai + li ) + ( area.zstride * wi )
local n_name = minetest.get_name_from_content_id ( data [ ai_rec ] )
local n_def = minetest.registered_nodes [ n_name ]
local b_data = minetest.get_biome_data ( area : position ( ai_rec ) )
if not b_data then
return
end
2024-01-10 22:16:52 -06:00
2024-01-11 14:11:24 -06:00
local b_name = minetest.get_biome_name ( b_data.biome )
2024-01-10 22:16:52 -06:00
2024-01-11 14:11:24 -06:00
if not b_name then
return
end
2024-01-10 22:16:52 -06:00
2024-01-25 19:44:27 -06:00
if b_name ~= ' everness:mineral_waters '
2024-01-11 14:11:24 -06:00
-- for mese trees, they dont have specific biome
or minetest.get_item_group ( n_name , ' tree ' ) > 0
or minetest.get_item_group ( n_name , ' leaves ' ) > 0
then
-- bordering with anohter biome, be more precise in placing
precision_perc = 100
end
2024-01-10 22:16:52 -06:00
2024-01-11 14:11:24 -06:00
if n_def
and n_def.walkable
and data [ ai_rec + area.ystride ] == minetest.CONTENT_AIR
then
walkable_nodes = walkable_nodes + 1
2024-01-10 22:16:52 -06:00
end
end
2024-01-11 14:11:24 -06:00
end
2024-01-10 22:16:52 -06:00
-- build pool (cuboid)
local pool_build_nodes_group = pool_build_nodes [ rand : next ( 1 , # pool_build_nodes ) ]
2024-01-11 14:11:24 -06:00
if walkable_nodes >= ( width * length / 100 ) * precision_perc then
-- offset y so the pools are sticking out / sinking in from the ground vertically
local ai_offset_y = ai - ( area.ystride * height ) + ( area.ystride * rand : next ( 0 , math.ceil ( height / 2 ) ) )
2024-01-10 22:16:52 -06:00
for hi = 1 , height do
for li = 1 , length do
for wi = 1 , width do
local mineral_stone = pool_build_nodes_group [ rand : next ( 1 , # pool_build_nodes_group ) ]
2024-01-11 14:11:24 -06:00
local ai_cub = ( ai_offset_y + li ) + ( area.ystride * hi ) + ( area.zstride * wi )
local current_c_id = data [ ai_cub ]
2024-01-10 22:16:52 -06:00
-- Check for water and build nodes before replacing, this will make pools connected and will not replace already built walls from another pool near by
if hi == 1
and current_c_id ~= c_everness_mineral_water_source
and not find_irecursive ( pool_build_nodes , current_c_id )
then
-- build pool floor
2024-01-11 14:11:24 -06:00
data [ ai_cub ] = mineral_stone
2024-01-10 22:16:52 -06:00
elseif hi ~= 1
and ( wi == 1 or wi == width )
and current_c_id ~= c_everness_mineral_water_source
and not find_irecursive ( pool_build_nodes , current_c_id )
then
-- build pool wall
2024-01-11 14:11:24 -06:00
data [ ai_cub ] = mineral_stone
2024-01-10 22:16:52 -06:00
elseif hi ~= 1
and ( li == 1 or li == length )
and ( wi ~= 1 or wi ~= width )
and current_c_id ~= c_everness_mineral_water_source
and not find_irecursive ( pool_build_nodes , current_c_id )
then
-- build pool wall
2024-01-11 14:11:24 -06:00
data [ ai_cub ] = mineral_stone
2024-01-10 22:16:52 -06:00
else
-- fill in the pool with water
2024-01-11 14:11:24 -06:00
data [ ai_cub ] = c_everness_mineral_water_source
2024-01-10 22:16:52 -06:00
end
2024-01-25 22:36:05 -06:00
-- place loot chest in the middle of the pool floor
2024-01-10 22:16:52 -06:00
if hi == 2
and height > 4
and math.ceil ( length / 2 ) == li
and math.ceil ( width / 2 ) == wi
2024-01-11 14:11:24 -06:00
and data [ ai_cub - area.ystride ] ~= c_everness_mineral_water_source
2024-01-10 22:16:52 -06:00
and rand : next ( 0 , 100 ) < 3
then
2024-01-25 22:36:05 -06:00
data [ ai_cub ] = c_everness_chest
table.insert ( chest_positions , vector.new ( area : position ( ai_cub ) ) )
2024-01-10 22:16:52 -06:00
end
end
end
end
end
end
end
end
end
elseif rand_version == 2 then
2024-01-11 14:11:24 -06:00
--
-- Lakes
--
2024-01-10 22:16:52 -06:00
for z = minp.z , maxp.z do
for y = minp.y , maxp.y do
for x = minp.x , maxp.x do
local ai = area : index ( x , y , z )
local c_current = data [ ai ]
-- +Y, -Y, +X, -X, +Z, -Z
-- top, bottom, right, left, front, back
-- right
local c_right = data [ ai + 1 ]
-- left
local c_left = data [ ai - 1 ]
-- front
local c_front = data [ ai + ( area.zstride * 2 ) ]
-- back
local c_back = data [ ai - ( area.zstride * 2 ) ]
local keep_going = true
local while_count = 1
local max_dig_depth = 11
if
c_current == c_everness_mineral_sand
and (
c_right == c_everness_mineral_sand
or c_right == c_everness_mineral_water_source
or c_right == c_everness_mineral_stone
2024-01-11 14:11:24 -06:00
or c_right == c_everness_mineral_stone_with_coal
2024-01-22 13:48:57 -06:00
or c_right == c_everness_mineral_stone_with_ceramic_sherds
2024-01-10 22:16:52 -06:00
)
and (
c_left == c_everness_mineral_sand
or c_left == c_everness_mineral_water_source
or c_left == c_everness_mineral_stone
2024-01-11 14:11:24 -06:00
or c_left == c_everness_mineral_stone_with_coal
2024-01-22 13:48:57 -06:00
or c_left == c_everness_mineral_stone_with_ceramic_sherds
2024-01-10 22:16:52 -06:00
)
and (
c_front == c_everness_mineral_sand
or c_front == c_everness_mineral_water_source
or c_front == c_everness_mineral_stone
2024-01-11 14:11:24 -06:00
or c_front == c_everness_mineral_stone_with_coal
2024-01-22 13:48:57 -06:00
or c_front == c_everness_mineral_stone_with_ceramic_sherds
2024-01-10 22:16:52 -06:00
)
and (
c_back == c_everness_mineral_sand
or c_back == c_everness_mineral_water_source
or c_back == c_everness_mineral_stone
2024-01-11 14:11:24 -06:00
or c_back == c_everness_mineral_stone_with_coal
2024-01-22 13:48:57 -06:00
or c_back == c_everness_mineral_stone_with_ceramic_sherds
2024-01-10 22:16:52 -06:00
)
then
-- dig below
2024-01-11 14:11:24 -06:00
while keep_going and while_count <= max_dig_depth do
2024-01-10 22:16:52 -06:00
local while_index = ai - area.ystride * while_count
if
-- below
2024-01-11 14:11:24 -06:00
(
data [ while_index ] == c_everness_mineral_stone
or data [ while_index ] == c_everness_mineral_stone_with_coal
2024-01-22 13:48:57 -06:00
or data [ while_index ] == c_everness_mineral_stone_with_ceramic_sherds
2024-01-11 14:11:24 -06:00
)
2024-01-10 22:16:52 -06:00
and (
-- right
data [ while_index + 1 + area.ystride ] == c_everness_mineral_sand
or data [ while_index + 1 + area.ystride ] == c_everness_mineral_water_source
or data [ while_index + 1 + area.ystride ] == c_everness_mineral_stone
2024-01-11 14:11:24 -06:00
or data [ while_index + 1 + area.ystride ] == c_everness_mineral_stone_with_coal
2024-01-22 13:48:57 -06:00
or data [ while_index + 1 + area.ystride ] == c_everness_mineral_stone_with_ceramic_sherds
2024-01-10 22:16:52 -06:00
)
and (
-- left
data [ while_index - 1 + area.ystride ] == c_everness_mineral_sand
or data [ while_index - 1 + area.ystride ] == c_everness_mineral_water_source
or data [ while_index - 1 + area.ystride ] == c_everness_mineral_stone
2024-01-11 14:11:24 -06:00
or data [ while_index - 1 + area.ystride ] == c_everness_mineral_stone_with_coal
2024-01-22 13:48:57 -06:00
or data [ while_index - 1 + area.ystride ] == c_everness_mineral_stone_with_ceramic_sherds
2024-01-10 22:16:52 -06:00
)
and (
-- front
data [ while_index + area.zstride + area.ystride ] == c_everness_mineral_sand
or data [ while_index + area.zstride + area.ystride ] == c_everness_mineral_water_source
or data [ while_index + area.zstride + area.ystride ] == c_everness_mineral_stone
2024-01-11 14:11:24 -06:00
or data [ while_index + area.zstride + area.ystride ] == c_everness_mineral_stone_with_coal
2024-01-22 13:48:57 -06:00
or data [ while_index + area.zstride + area.ystride ] == c_everness_mineral_stone_with_ceramic_sherds
2024-01-10 22:16:52 -06:00
)
and (
-- back
data [ while_index - area.zstride + area.ystride ] == c_everness_mineral_sand
or data [ while_index - area.zstride + area.ystride ] == c_everness_mineral_water_source
or data [ while_index - area.zstride + area.ystride ] == c_everness_mineral_stone
2024-01-11 14:11:24 -06:00
or data [ while_index - area.zstride + area.ystride ] == c_everness_mineral_stone_with_coal
2024-01-22 13:48:57 -06:00
or data [ while_index - area.zstride + area.ystride ] == c_everness_mineral_stone_with_ceramic_sherds
2024-01-10 22:16:52 -06:00
)
then
data [ while_index + area.ystride ] = c_everness_mineral_water_source
else
keep_going = false
end
while_count = while_count + 1
end
end
end
end
end
end
2024-01-19 12:03:26 -06:00
-- Place decorations after generating (2nd pass)
for y = minp.y , maxp.y do
for z = minp.z , maxp.z do
for x = minp.x , maxp.x do
local ai = area : index ( x , y , z )
--
-- Place Lotus Flowers and Leaves
--
if
data [ ai ] == c_everness_mineral_water_source
-- spawn around water
and data [ ai + 1 + area.zstride ] == c_everness_mineral_water_source
and data [ ai + 1 - area.zstride ] == c_everness_mineral_water_source
and data [ ai + 1 ] == c_everness_mineral_water_source
and data [ ai - 1 ] == c_everness_mineral_water_source
and data [ ai - 1 + area.zstride ] == c_everness_mineral_water_source
and data [ ai - 1 - area.zstride ] == c_everness_mineral_water_source
and data [ ai + area.zstride ] == c_everness_mineral_water_source
and data [ ai - area.zstride ] == c_everness_mineral_water_source
-- make sure there is space above
and data [ ai + area.ystride ] == minetest.CONTENT_AIR
-- spawn around air above
and data [ ai + area.ystride + 1 ] == minetest.CONTENT_AIR
and data [ ai + area.ystride + 1 + area.zstride ] == minetest.CONTENT_AIR
and data [ ai + area.ystride + 1 - area.zstride ] == minetest.CONTENT_AIR
and data [ ai + area.ystride - 1 ] == minetest.CONTENT_AIR
and data [ ai + area.ystride - 1 + area.zstride ] == minetest.CONTENT_AIR
and data [ ai + area.ystride - 1 - area.zstride ] == minetest.CONTENT_AIR
and data [ ai + area.ystride + area.zstride ] == minetest.CONTENT_AIR
and data [ ai + area.ystride - area.zstride ] == minetest.CONTENT_AIR
then
if rand : next ( 0 , 100 ) < 2 then
data [ ai + area.ystride ] = c_lotus_flowers [ rand : next ( 1 , # c_lotus_flowers ) ]
-- Place Lotus Leaves around Flowers
local radius = 3
local chance_max = 80
for i = - radius , radius do
for j = - radius , radius do
local idx = ai + i + ( area.zstride * j ) + area.ystride
local distance = math.round ( vector.distance ( area : position ( ai ) , area : position ( idx ) ) )
local chance = math.round ( chance_max / distance )
if chance > chance_max then
chance = chance_max
end
if
rand : next ( 0 , 100 ) < chance
and data [ idx ] == minetest.CONTENT_AIR
and data [ idx - area.ystride ] == c_everness_mineral_water_source
then
data [ idx ] = c_lotus_leaves [ rand : next ( 1 , # c_lotus_leaves ) ]
2024-01-19 14:41:16 -06:00
p2data [ idx ] = rand : next ( 0 , 3 )
2024-01-19 12:03:26 -06:00
end
end
end
elseif rand : next ( 0 , 100 ) < 4 then
data [ ai + area.ystride ] = c_lotus_leaves [ rand : next ( 1 , # c_lotus_leaves ) ]
2024-01-19 14:41:16 -06:00
p2data [ ai + area.ystride ] = rand : next ( 0 , 3 )
2024-01-19 12:03:26 -06:00
-- add some more leaves around the leaf
for i = - 1 , 1 do
for j = - 1 , 1 do
local idx = ai + i + ( area.zstride * j ) + area.ystride
if
rand : next ( 0 , 100 ) < 25
and data [ idx ] == minetest.CONTENT_AIR
and data [ idx - area.ystride ] == c_everness_mineral_water_source
then
data [ idx ] = c_lotus_leaves [ rand : next ( 1 , # c_lotus_leaves ) ]
2024-01-19 14:41:16 -06:00
p2data [ idx ] = rand : next ( 0 , 3 )
2024-01-19 12:03:26 -06:00
end
end
end
end
end
--
-- Place Seaweed
--
if
data [ ai ] == c_everness_mineral_water_source
and data [ ai + area.ystride ] == c_everness_mineral_water_source
and rand : next ( 0 , 100 ) < 33
then
local c_weed = c_water_weeds [ rand : next ( 1 , # c_water_weeds ) ]
if rand : next ( 0 , 100 ) < 5 then
-- Weed with light source with a bit less probability
c_weed = c_everness_mineral_water_weed_3
end
if data [ ai + 1 ] == c_everness_mineral_stone then
data [ ai + 1 ] = c_weed
data [ ai + 1 ] = c_weed
data [ ai + 1 ] = c_weed
p2data [ ai + 1 ] = 2
elseif data [ ai - 1 ] == c_everness_mineral_stone then
data [ ai - 1 ] = c_weed
data [ ai - 1 ] = c_weed
data [ ai - 1 ] = c_weed
p2data [ ai - 1 ] = 3
elseif data [ ai + area.zstride ] == c_everness_mineral_stone then
data [ ai + area.zstride ] = c_weed
data [ ai + area.zstride ] = c_weed
data [ ai + area.zstride ] = c_weed
p2data [ ai + area.zstride ] = 4
elseif data [ ai - area.zstride ] == c_everness_mineral_stone then
data [ ai - area.zstride ] = c_weed
data [ ai - area.zstride ] = c_weed
data [ ai - area.zstride ] = c_weed
p2data [ ai - area.zstride ] = 5
elseif data [ ai - area.ystride ] == c_everness_mineral_stone then
data [ ai - area.ystride ] = c_weed
data [ ai - area.ystride ] = c_weed
data [ ai - area.ystride ] = c_weed
p2data [ ai - area.ystride ] = 1
end
end
--
-- Place pots under water
--
if
data [ ai ] == c_everness_mineral_water_source
-- spawn around water
and data [ ai + 1 + area.zstride ] == c_everness_mineral_water_source
and data [ ai + 1 - area.zstride ] == c_everness_mineral_water_source
and data [ ai + 1 ] == c_everness_mineral_water_source
and data [ ai - 1 ] == c_everness_mineral_water_source
and data [ ai - 1 + area.zstride ] == c_everness_mineral_water_source
and data [ ai - 1 - area.zstride ] == c_everness_mineral_water_source
and data [ ai + area.zstride ] == c_everness_mineral_water_source
and data [ ai - area.zstride ] == c_everness_mineral_water_source
-- spawn around water above
and data [ ai + area.ystride ] == c_everness_mineral_water_source
and data [ ai + area.ystride + 1 ] == c_everness_mineral_water_source
and data [ ai + area.ystride + 1 + area.zstride ] == c_everness_mineral_water_source
and data [ ai + area.ystride + 1 - area.zstride ] == c_everness_mineral_water_source
and data [ ai + area.ystride - 1 ] == c_everness_mineral_water_source
and data [ ai + area.ystride - 1 + area.zstride ] == c_everness_mineral_water_source
and data [ ai + area.ystride - 1 - area.zstride ] == c_everness_mineral_water_source
and data [ ai + area.ystride + area.zstride ] == c_everness_mineral_water_source
and data [ ai + area.ystride - area.zstride ] == c_everness_mineral_water_source
-- spawn on solid node below
and data [ ai - area.ystride ] ~= c_everness_mineral_water_source
then
if rand : next ( 0 , 100 ) < 1 then
table.insert ( pot_pos , vector.new ( area : position ( ai ) ) )
end
end
end
end
end
2024-01-10 22:16:52 -06:00
vm : set_data ( data )
2024-01-19 12:03:26 -06:00
vm : set_param2_data ( p2data )
--
-- Place Decorations
--
--
-- Palm Trees
--
for _ , pos in ipairs ( gennotify [ ' decoration# ' .. ( d_everness_palm_trees or ' ' ) ] or { } ) do
place_decoration ( pos , vm , area , data , ' everness:palm_trees ' , function ( p )
minetest.place_schematic_on_vmanip (
vm ,
p ,
minetest.get_modpath ( ' everness ' ) .. ' /schematics/everness_palm_tree.mts ' ,
nil ,
nil ,
true ,
' place_center_x, place_center_z '
)
end )
end
--
-- Water Geyser
--
for _ , pos in ipairs ( gennotify [ ' decoration# ' .. ( d_everness_water_geyser or ' ' ) ] or { } ) do
place_decoration ( pos , vm , area , data , ' everness:water_geyser ' , function ( p )
vm : set_node_at ( p , { name = ' everness:water_geyser ' } )
end )
end
--
-- Rose Bush
--
for _ , pos in ipairs ( gennotify [ ' decoration# ' .. ( d_rose_bush or ' ' ) ] or { } ) do
place_decoration ( pos , vm , area , data , ' everness:rose_bush ' , function ( p )
vm : set_node_at ( p , { name = ' everness:rose_bush ' } )
end )
end
--
-- Pots (above water)
--
for _ , pos in ipairs ( gennotify [ ' decoration# ' .. ( d_everness_pots or ' ' ) ] or { } ) do
place_decoration ( pos , vm , area , data , ' everness:pots ' , function ( p , deco_def )
if deco_def._decoration then
-- Use `minetest.set_node` so we can set inventory on node construct
minetest.set_node ( p , { name = deco_def._decoration [ rand : next ( 1 , # deco_def._decoration ) ] } )
local inv = minetest.get_inventory ( { type = ' node ' , pos = p } )
local item_def = Everness.loot_chest . default [ rand : next ( 1 , # Everness.loot_chest . default ) ]
if not minetest.registered_items [ item_def.name ] then
return
end
if rand : next ( 0 , 100 ) <= item_def.chance then
local stack = ItemStack ( item_def.name )
if minetest.registered_tools [ item_def.name ] then
stack : set_wear ( rand : next ( 1 , 65535 ) )
else
2024-01-25 22:36:05 -06:00
stack : set_count ( rand : next ( 1 , math.min ( item_def.max_count , stack : get_stack_max ( ) ) ) )
2024-01-19 12:03:26 -06:00
end
inv : set_stack ( ' main ' , 1 , stack )
end
end
end )
end
--
-- Pots (under water)
--
for _ , v in ipairs ( pot_pos ) do
-- Use `minetest.set_node` so we can set inventory on node construct
minetest.set_node ( v , { name = minetest.get_name_from_content_id ( c_pots [ rand : next ( 1 , # c_pots ) ] ) } )
local inv = minetest.get_inventory ( { type = ' node ' , pos = v } )
local item_def = Everness.loot_chest . default [ rand : next ( 1 , # Everness.loot_chest . default ) ]
if not minetest.registered_items [ item_def.name ] then
return
end
if rand : next ( 0 , 100 ) <= item_def.chance then
local stack = ItemStack ( item_def.name )
if minetest.registered_tools [ item_def.name ] then
stack : set_wear ( rand : next ( 1 , 65535 ) )
else
2024-01-25 22:36:05 -06:00
stack : set_count ( rand : next ( 1 , math.min ( item_def.max_count , stack : get_stack_max ( ) ) ) )
2024-01-19 12:03:26 -06:00
end
inv : set_stack ( ' main ' , 1 , stack )
end
end
2024-01-11 14:11:24 -06:00
-- Set the lighting within the `VoxelManip` to a uniform value
2024-01-19 12:03:26 -06:00
vm : set_lighting ( { day = 0 , night = 0 } , minp , maxp )
2024-01-10 22:16:52 -06:00
-- Calculate lighting for what has been created.
vm : calc_lighting ( )
-- Liquid nodes were placed so set them flowing.
vm : update_liquids ( )
-- Write what has been created to the world.
vm : write_to_map ( )
2024-01-25 22:36:05 -06:00
-- Populate loot chest inventory
local chest_def = minetest.registered_nodes [ ' everness:chest ' ]
if chest_def then
for i , p in ipairs ( chest_positions ) do
chest_def.on_construct ( p )
local inv = minetest.get_inventory ( { type = ' node ' , pos = p } )
if not inv then
minetest.log ( ' action ' , ' [Everness] FAILED to populate loot chests inventory at ' .. p : to_string ( ) )
return
end
for index , value in ipairs ( inv : get_list ( ' main ' ) ) do
local item_def = Everness.loot_chest . default [ rand : next ( 1 , # Everness.loot_chest . default ) ]
if not minetest.registered_items [ item_def.name ] then
return
end
if rand : next ( 0 , 100 ) <= item_def.chance then
local stack = ItemStack ( item_def.name )
if minetest.registered_tools [ item_def.name ] then
stack : set_wear ( rand : next ( 1 , 65535 ) )
else
stack : set_count ( rand : next ( 1 , math.min ( item_def.max_count , stack : get_stack_max ( ) ) ) )
end
inv : set_stack ( ' main ' , index , stack )
end
end
minetest.log ( ' action ' , ' [Everness] Loot chests inventory populated at ' .. p : to_string ( ) )
end
end
2024-01-10 22:16:52 -06:00
end
-- Print generation time of this mapchunk.
-- local chugent = math.ceil((os.clock() - t0) * 1000)
-- print('[lvm_example] Mapchunk generation time ' .. chugent .. ' ms')
end )