added far better terrain blend (programmed by paramat); added update_liquids
parent
2be8658704
commit
32d1e0c1e6
2
init.lua
2
init.lua
|
@ -45,6 +45,8 @@ dofile(mg_villages.modpath.."/map_of_world.lua")
|
|||
|
||||
dofile(mg_villages.modpath.."/fill_chest.lua")
|
||||
|
||||
-- terrain blending for individual houses
|
||||
dofile(mg_villages.modpath.."/terrain_blend.lua")
|
||||
-- the interface for the mapgen;
|
||||
-- also takes care of spawning the player
|
||||
dofile(mg_villages.modpath.."/mapgen.lua")
|
||||
|
|
54
mapgen.lua
54
mapgen.lua
|
@ -373,8 +373,11 @@ mg_villages.village_area_mark_inside_village_area = function( village_area, vill
|
|||
local n_rawnoise = village_noise:get2d({x = x, y = z}) -- create new blended terrain
|
||||
for village_nr, village in ipairs(villages) do
|
||||
local vn = mg_villages.get_vn(x, z, n_rawnoise, village);
|
||||
if( village.is_single_house ) then
|
||||
-- do nothing here; the village area will be specificly marked later on
|
||||
|
||||
-- the village core; this is where the houses stand (but there's no house or road at this particular spot)
|
||||
if( vn <= 40 ) then
|
||||
elseif( vn <= 40 ) then
|
||||
village_area[ x ][ z ] = { village_nr, 6};
|
||||
|
||||
-- the flattened land around the village where wheat, cotton, trees or grass may be grown (depending on village type)
|
||||
|
@ -396,6 +399,14 @@ mg_villages.village_area_mark_inside_village_area = function( village_area, vill
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- single houses get their own form of terrain blend
|
||||
local pr = PseudoRandom(mg_villages.get_bseed(minp));
|
||||
for village_nr, village in ipairs( villages ) do
|
||||
if( village and village.is_single_house and village.to_add_data and village.to_add_data.bpos and #village.to_add_data.bpos>=1) then
|
||||
mg_villages.village_area_mark_single_house_area( village_area, minp, maxp, village.to_add_data.bpos[1], pr, village_nr );
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
@ -710,26 +721,28 @@ mg_villages.place_villages_via_voxelmanip = function( villages, minp, maxp, vm,
|
|||
mg_villages.generate_village( village, village_noise);
|
||||
t1 = time_elapsed( t1, 'generate_village' );
|
||||
|
||||
-- only add artificial snow if the village has at least a size of 15 (else it might look too artificial)
|
||||
if( not( village.artificial_snow ) and village.vs > 15) then
|
||||
if( mg_villages.artificial_snow_probability and math.random( 1, mg_villages.artificial_snow_probability )==1) then
|
||||
village.artificial_snow = 1;
|
||||
else
|
||||
village.artificial_snow = 0;
|
||||
if( not( village.is_single_house )) then
|
||||
-- only add artificial snow if the village has at least a size of 15 (else it might look too artificial)
|
||||
if( not( village.artificial_snow ) and village.vs > 15) then
|
||||
if( mg_villages.artificial_snow_probability and math.random( 1, mg_villages.artificial_snow_probability )==1) then
|
||||
village.artificial_snow = 1;
|
||||
else
|
||||
village.artificial_snow = 0;
|
||||
end
|
||||
end
|
||||
|
||||
-- will set village_area to N where .. is:
|
||||
-- 2: a building
|
||||
-- 3: border around a building
|
||||
-- 4: a road
|
||||
-- 5: border around a road
|
||||
mg_villages.village_area_mark_buildings( village_area, village_nr, village.to_add_data.bpos );
|
||||
t1 = time_elapsed( t1, 'mark_buildings' );
|
||||
-- will set village_area to N where .. is:
|
||||
-- 8: a dirt road
|
||||
mg_villages.village_area_mark_dirt_roads( village_area, village_nr, village.to_add_data.dirt_roads );
|
||||
t1 = time_elapsed( t1, 'mark_dirt_roads' );
|
||||
end
|
||||
|
||||
-- will set village_area to N where .. is:
|
||||
-- 2: a building
|
||||
-- 3: border around a building
|
||||
-- 4: a road
|
||||
-- 5: border around a road
|
||||
mg_villages.village_area_mark_buildings( village_area, village_nr, village.to_add_data.bpos );
|
||||
t1 = time_elapsed( t1, 'mark_buildings' );
|
||||
-- will set village_area to N where .. is:
|
||||
-- 8: a dirt road
|
||||
mg_villages.village_area_mark_dirt_roads( village_area, village_nr, village.to_add_data.dirt_roads );
|
||||
t1 = time_elapsed( t1, 'mark_dirt_roads' );
|
||||
end
|
||||
|
||||
-- if no voxelmanip data was passed on, read the data here
|
||||
|
@ -833,6 +846,9 @@ mg_villages.place_villages_via_voxelmanip = function( villages, minp, maxp, vm,
|
|||
vm:write_to_map(data)
|
||||
t1 = time_elapsed( t1, 'vm data written' );
|
||||
|
||||
vm:update_liquids()
|
||||
t1 = time_elapsed( t1, 'vm update liquids' );
|
||||
|
||||
-- do on_construct calls AFTER the map data has been written - else i.e. realtest fences can not update themshevles
|
||||
for _, village in ipairs(villages) do
|
||||
for k, v in pairs( village.to_add_data.extra_calls.on_constr ) do
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
|
||||
-- this function needs to be fed house x, z dimensions and rotation
|
||||
-- it will then calculate the minimum point (xbmin, avsurfy, zbmin) where the house should be spawned
|
||||
-- and mark a mapchunk-sized 'house area' for terrain blending
|
||||
|
||||
mg_villages.village_area_mark_single_house_area = function(village_area, minp, maxp, pos, pr, village_nr)
|
||||
|
||||
local YFLATMIN = 2 -- Lowest flat area height
|
||||
local FFAPROP = 0.5 -- front flat area proportion of dimension
|
||||
local np_blend = {
|
||||
offset = 0,
|
||||
scale = 1,
|
||||
spread = {x=12, y=12, z=12},
|
||||
seed = 38393,
|
||||
octaves = 3,
|
||||
persist = 0.67
|
||||
}
|
||||
|
||||
local sidelen = maxp.x - minp.x + 1
|
||||
|
||||
local xdim, zdim -- dimensions of house plus front flat area
|
||||
if pos.brotate == 0 or pos.brotate == 2 then
|
||||
xdim = pos.bsizex
|
||||
zdim = pos.bsizez + math.floor(FFAPROP * pos.bsizez)
|
||||
else
|
||||
xdim = pos.bsizex + math.floor(FFAPROP * pos.bsizex)
|
||||
zdim = pos.bsizez
|
||||
end
|
||||
local blenrad = math.floor((math.max(xdim, zdim) + 16) / 2) -- radius of blend area
|
||||
local blendim = 2 * blenrad + 1 -- blend area dimensions
|
||||
local blencenx = minp.x + pr:next(blenrad+16, sidelen - blenrad - 1 -16) -- blend area centre point
|
||||
local blencenz = minp.z + pr:next(blenrad+16, sidelen - blenrad - 1 -16)
|
||||
local minx = blencenx - math.ceil(xdim / 2) -- minimum point of house plus front flat area
|
||||
local minz = blencenz - math.ceil(zdim / 2)
|
||||
local xbmin, zbmin -- house minimum point
|
||||
if pos.brotate == 2 or pos.brotate == 3 then -- N, E
|
||||
xbmin = minx
|
||||
zbmin = minz
|
||||
elseif pos.brotate == 1 then -- W
|
||||
xbmin = minx + math.floor(FFAPROP * pos.bsizex)
|
||||
zbmin = minz
|
||||
else -- pos.brotate = 2, S
|
||||
xbmin = minx
|
||||
zbmin = minz + math.floor(FFAPROP * pos.bsizez)
|
||||
end
|
||||
|
||||
-- CHANGE the position of the house so that it sits where the terrain is blended:
|
||||
-- *** spawn building at (xbmin, avsurfy, zbmin) after landscaping ***
|
||||
pos.x = xbmin;
|
||||
pos.z = zbmin;
|
||||
|
||||
-- 2D noise perlinmap
|
||||
local chulens = {x=sidelen, y=sidelen, z=sidelen}
|
||||
local minpos = {x=minp.x, y=minp.z}
|
||||
local nvals_blend = minetest.get_perlin_map(np_blend, chulens):get2dMap_flat(minpos)
|
||||
|
||||
-- mark mapchunk-sized house area
|
||||
local ni = 1
|
||||
-- for z = minp.z, maxp.z do
|
||||
-- for x = minp.x, maxp.x do -- for each column do
|
||||
for z = math.max( blencenz - blenrad, minp.z), math.min(blencenz + blenrad, maxp.z), 1 do
|
||||
for x = math.max( blencenx - blenrad, minp.x), math.min(blencenx + blenrad, maxp.x), 1 do -- for each column do
|
||||
|
||||
local xrm = x - minp.x -- relative to mapchunk minp
|
||||
local zrm = z - minp.z
|
||||
local xr = x - blencenx -- relative to blend centre
|
||||
local zr = z - blencenz
|
||||
local xre1 = (zdim / 2) * (xr / zr)
|
||||
local zre1 = zdim / 2
|
||||
local xre2 = xdim / 2
|
||||
local zre2 = (xdim / 2) * (zr / xr)
|
||||
local rade1 = math.sqrt(xre1 ^ 2 + zre1 ^ 2)
|
||||
local rade2 = math.sqrt(xre2 ^ 2 + zre2 ^ 2)
|
||||
local flatrad = math.min(rade1, rade2) -- radius at edge of rectangular house flat area
|
||||
local n_absblend = math.abs(nvals_blend[ni])
|
||||
local blenradn = blenrad - n_absblend * 2 -- vary blend radius
|
||||
local flatradn = flatrad + n_absblend * 2 -- vary shape of house flat area
|
||||
local nodrad = math.sqrt(xr ^ 2 + zr ^ 2) -- node radius
|
||||
|
||||
if x >= xbmin and x <= xbmin + pos.bsizex -- area reserved for house
|
||||
and z >= zbmin and z <= zbmin + pos.bsizez then
|
||||
village_area[ x ][ z ] = {village_nr, 4}
|
||||
elseif nodrad <= flatradn or (xr == 0 and zr == 0) then -- irregular flat area around house
|
||||
village_area[ x ][ z ] = {village_nr, 1}
|
||||
elseif nodrad <= blenradn then -- terrain blend area
|
||||
local blenprop = ((nodrad - flatradn) / (blenradn - flatradn))
|
||||
village_area[ x ][ z ] = {village_nr, -1 * blenprop} -- terrain blending
|
||||
else -- no change to terrain
|
||||
--village_area[xrm][zrm] = {village_nr, 0}
|
||||
end
|
||||
ni = ni + 1
|
||||
end
|
||||
end
|
||||
end
|
10
villages.lua
10
villages.lua
|
@ -775,8 +775,10 @@ end
|
|||
-- they may be so close to the border that they will affect this mapchunk
|
||||
mg_villages.houses_in_mapchunk = function( minp, mapchunk_size, villages )
|
||||
local village_noise = minetest.get_perlin(7635, 3, 0.5, 16);
|
||||
for x=-1,1 do
|
||||
for z=-1,1 do
|
||||
-- for x=-1,1 do
|
||||
-- for z=-1,1 do
|
||||
local x = 0;
|
||||
local z = 0;
|
||||
local new_village = mg_villages.houses_in_one_mapchunk(
|
||||
{x=minp.x+(x*mapchunk_size), y=minp.y, z=minp.z+(z*mapchunk_size)},
|
||||
mapchunk_size,
|
||||
|
@ -785,7 +787,7 @@ mg_villages.houses_in_mapchunk = function( minp, mapchunk_size, villages )
|
|||
if( new_village and new_village.vs and new_village.vx and new_village.vz ) then
|
||||
table.insert( villages, new_village );
|
||||
end
|
||||
end
|
||||
end
|
||||
-- end
|
||||
-- end
|
||||
return villages;
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue