assigned numbers to roads so that houses can identify the road they belong to; added dirt roads between the fields for medieval villages
This commit is contained in:
parent
8174ef247b
commit
56ef231f96
169
villages.lua
169
villages.lua
@ -144,10 +144,15 @@ local function choose_building_rot(l, pr, orient, village_type)
|
||||
return btype, rotation, bsizex, bsizez
|
||||
end
|
||||
|
||||
local function placeable(bx, bz, bsizex, bsizez, l, exclude_roads)
|
||||
local function placeable(bx, bz, bsizex, bsizez, l, exclude_roads, orientation)
|
||||
for _, a in ipairs(l) do
|
||||
-- with < instead of <=, space_between_buildings can be zero (important for towns where houses are closely packed)
|
||||
if (a.btype ~= "road" or not exclude_roads) and math.abs(bx+bsizex/2-a.x-a.bsizex/2)<(bsizex+a.bsizex)/2 and math.abs(bz+bsizez/2-a.z-a.bsizez/2)<(bsizez+a.bsizez)/2 then return false end
|
||||
if (a.btype ~= "road" or not exclude_roads) and math.abs(bx+bsizex/2-a.x-a.bsizex/2)<(bsizex+a.bsizex)/2 and math.abs(bz+bsizez/2-a.z-a.bsizez/2)<(bsizez+a.bsizez)/2 then
|
||||
-- dirt roads which go at a 90 degree angel to the current road are not a problem
|
||||
if( not( orientation ) or a.o%2 == orientation%2 ) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
@ -164,6 +169,8 @@ local function when(a, b, c)
|
||||
if a then return b else return c end
|
||||
end
|
||||
|
||||
mg_villages.road_nr = 0;
|
||||
|
||||
local function generate_road(village, l, pr, roadsize, rx, rz, rdx, rdz, vnoise, space_between_buildings)
|
||||
local vx, vz, vh, vs = village.vx, village.vz, village.vh, village.vs
|
||||
local village_type = village.village_type;
|
||||
@ -180,6 +187,8 @@ local function generate_road(village, l, pr, roadsize, rx, rz, rdx, rdz, vnoise,
|
||||
orient1 = 3
|
||||
orient2 = 1
|
||||
end
|
||||
-- we have one more road
|
||||
mg_villages.road_nr = mg_villages.road_nr + 1;
|
||||
while mg_villages.inside_village(rx, rz, village, vnoise) and not road_in_building(rx, rz, rdx, rdz, roadsize, l) do
|
||||
if roadsize > 1 and pr:next(1, 4) == 1 then
|
||||
--generate_road(vx, vz, vs, vh, l, pr, roadsize-1, rx, rz, math.abs(rdz), math.abs(rdx))
|
||||
@ -224,7 +233,7 @@ local function generate_road(village, l, pr, roadsize, rx, rz, rdx, rdz, vnoise,
|
||||
rz = rz + (bsizez+space_between_buildings)*rdz
|
||||
mx = rx - 2*rdx
|
||||
mz = rz - 2*rdz
|
||||
l[#l+1] = {x=bx, y=vh, z=bz, btype=btype, bsizex=bsizex, bsizez=bsizez, brotate = rotation}
|
||||
l[#l+1] = {x=bx, y=vh, z=bz, btype=btype, bsizex=bsizex, bsizez=bsizez, brotate = rotation, road_nr = mg_villages.road_nr, side=1, o=orient1 }
|
||||
--end
|
||||
end
|
||||
rx = rxx
|
||||
@ -273,7 +282,7 @@ local function generate_road(village, l, pr, roadsize, rx, rz, rdx, rdz, vnoise,
|
||||
rz = rz + (bsizez+space_between_buildings)*rdz
|
||||
m2x = rx - 2*rdx
|
||||
m2z = rz - 2*rdz
|
||||
l[#l+1] = {x=bx, y=vh, z=bz, btype=btype, bsizex=bsizex, bsizez=bsizez, brotate = rotation}
|
||||
l[#l+1] = {x=bx, y=vh, z=bz, btype=btype, bsizex=bsizex, bsizez=bsizez, brotate = rotation, road_nr = mg_villages.road_nr, side=2, o=orient2}
|
||||
--end
|
||||
end
|
||||
if road_in_building(rx, rz, rdx, rdz, roadsize, l) then
|
||||
@ -294,7 +303,8 @@ local function generate_road(village, l, pr, roadsize, rx, rz, rdx, rdz, vnoise,
|
||||
rxmax = math.max(rxx, mx)
|
||||
end
|
||||
l[#l+1] = {x = rxmin, y = vh, z = rzmin, btype = "road",
|
||||
bsizex = rxmax - rxmin + 1, bsizez = rzmax - rzmin + 1, brotate = 0}
|
||||
bsizex = rxmax - rxmin + 1, bsizez = rzmax - rzmin + 1, brotate = 0, road_nr = mg_villages.road_nr}
|
||||
|
||||
for _, i in ipairs(calls_to_do) do
|
||||
local new_roadsize = roadsize - 1
|
||||
if pr:next(1, 100) <= BIG_ROAD_CHANCE then
|
||||
@ -375,16 +385,126 @@ local function generate_bpos(village, pr, vnoise, space_between_buildings)
|
||||
end
|
||||
rx = rx + 5
|
||||
calls = {index = 1}
|
||||
-- the function below is recursive; we need a way to count roads
|
||||
mg_villages.road_nr = 0;
|
||||
generate_road(village, l, pr, FIRST_ROADSIZE, rx, rz, 1, 0, vnoise, space_between_buildings)
|
||||
i = 1
|
||||
while i < calls.index do
|
||||
generate_road(unpack(calls[i]))
|
||||
i = i+1
|
||||
end
|
||||
mg_villages.road_nr = 0;
|
||||
return l
|
||||
end
|
||||
|
||||
|
||||
-- dirt roads seperate the wheat area around medieval villages into seperate fields and make it look better
|
||||
mg_villages.generate_dirt_roads = function( village, vnoise, bpos, secondary_dirt_roads )
|
||||
local dirt_roads = {};
|
||||
if( not( secondary_dirt_roads)) then
|
||||
return dirt_roads;
|
||||
end
|
||||
for _, pos in ipairs( bpos ) do
|
||||
|
||||
local x = pos.x;
|
||||
local z = pos.z;
|
||||
local sizex = pos.bsizex;
|
||||
local sizez = 2;
|
||||
local orientation = 0;
|
||||
-- prolong the roads; start with a 3x2 piece of road for testing
|
||||
if( pos.btype == 'road' ) then
|
||||
-- the road streches in x direction
|
||||
if( pos.bsizex > pos.bsizez ) then
|
||||
sizex = 3; -- start with a road of length 3
|
||||
sizez = 2;
|
||||
vx = -1; vz = 0; vsx = 1; vsz = 0;
|
||||
x = pos.x - sizex;
|
||||
z = pos.z + math.floor((pos.bsizez-2)/2); -- aim for the middle of the road
|
||||
orientation = 0;
|
||||
-- if it is not possible to prolong the road at one end, then try the other
|
||||
if( not( placeable( x, z, sizex, sizez, bpos, false, nil))) then
|
||||
x = pos.x + pos.bsizex;
|
||||
vx = 0;
|
||||
orientation = 2;
|
||||
end
|
||||
-- the road stretches in z direction
|
||||
else
|
||||
sizex = 2;
|
||||
sizez = 3;
|
||||
vx = 0; vz = -1; vsx = 0; vsz = 1;
|
||||
x = pos.x + math.floor((pos.bsizex-2)/2); -- aim for the middle of the road
|
||||
z = pos.z - sizez;
|
||||
orientation = 1;
|
||||
if( not( placeable( x, z, sizex, sizez, bpos, false, nil))) then
|
||||
z = pos.z + pos.bsizez;
|
||||
vz = 0;
|
||||
orientation = 3;
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
if( pos.o == 0 ) then
|
||||
x = pos.x-pos.side;
|
||||
z = pos.z-2;
|
||||
sizex = pos.bsizex+1;
|
||||
sizez = 2;
|
||||
vx = 0; vz = 0; vsx = 1; vsz = 0;
|
||||
|
||||
elseif( pos.o == 2 ) then
|
||||
x = pos.x-pos.side+2;
|
||||
z = pos.z-2;
|
||||
sizex = pos.bsizex+1;
|
||||
sizez = 2;
|
||||
vx = -1; vz = 0; vsx = 1; vsz = 0;
|
||||
|
||||
elseif( pos.o == 1 ) then
|
||||
x = pos.x-2;
|
||||
z = pos.z-pos.side+2;
|
||||
sizex = 2;
|
||||
sizez = pos.bsizez+1;
|
||||
vx = 0; vz = 1; vsx = 0; vsz = 1;
|
||||
|
||||
elseif( pos.o == 3 ) then
|
||||
x = pos.x-2;
|
||||
z = pos.z-pos.side;
|
||||
sizex = 2;
|
||||
sizez = pos.bsizez+1;
|
||||
vx = 0; vz = 0; vsx = 0; vsz = 1;
|
||||
end
|
||||
orientation = pos.o;
|
||||
|
||||
end
|
||||
|
||||
-- prolong the dirt road by 1
|
||||
while( placeable( x, z, sizex, sizez, bpos, false, nil)
|
||||
and placeable( x, z, sizex, sizez, dirt_roads, false, orientation)
|
||||
and mg_villages.inside_village_area(x, z, village, vnoise)
|
||||
and mg_villages.inside_village_area(x+sizex, z+sizez, village, vnoise)) do
|
||||
sizex = sizex + vsx;
|
||||
sizez = sizez + vsz;
|
||||
x = x + vx;
|
||||
z = z + vz;
|
||||
end
|
||||
|
||||
-- the dirt road may exceed the village boundaries slightly, but it may not interfere with other buildings
|
||||
if( not( placeable( x, z, sizex, sizez, bpos, false, nil))
|
||||
or not( placeable( x, z, sizex, sizez, dirt_roads, false, orientation))) then
|
||||
sizex = sizex - vsx;
|
||||
sizez = sizez - vsz;
|
||||
x = x - vx;
|
||||
z = z - vz;
|
||||
end
|
||||
|
||||
if( placeable( x, z, sizex, sizez, bpos, false, nil)
|
||||
and placeable( x, z, sizex, sizez, dirt_roads, false, orientation)) then
|
||||
dirt_roads[#dirt_roads+1] = {x=x, y=village.vh, z=z, btype="dirt_road", bsizex=sizex, bsizez=sizez, brotate = 0, o=orientation}
|
||||
end
|
||||
end
|
||||
return dirt_roads;
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- they don't all grow cotton; farming_plus fruits are far more intresting!
|
||||
-- Note: This function modifies replacements.ids and replacements.table for each building
|
||||
-- as far as fruits are concerned. It needs to be called before placing a building
|
||||
@ -819,6 +939,15 @@ mg_villages.generate_village = function(village, vnoise)
|
||||
-- actually generate the village structure
|
||||
local bpos = generate_bpos( village, pr_village, vnoise, space_between_buildings)
|
||||
|
||||
|
||||
local secondary_dirt_roads = nil;
|
||||
-- if there is enough space, add dirt roads between the buildings (those will later be prolonged so that they reach the fields)
|
||||
if( space_between_buildings >= 2 and village_type == 'medieval') then
|
||||
secondary_dirt_roads = "dirt_road";
|
||||
end
|
||||
|
||||
local dirt_roads = mg_villages.generate_dirt_roads( village, vnoise, bpos, secondary_dirt_roads );
|
||||
|
||||
-- set fruits for all buildings in the village that need it - regardless weather they will be spawned
|
||||
-- now or later; after the first call to this function here, the village data will be final
|
||||
for _, pos in ipairs( bpos ) do
|
||||
@ -837,6 +966,7 @@ mg_villages.generate_village = function(village, vnoise)
|
||||
village.to_add_data = {};
|
||||
village.to_add_data.bpos = bpos;
|
||||
village.to_add_data.replacements = replacements.list;
|
||||
village.to_add_data.dirt_roads = dirt_roads;
|
||||
|
||||
--print('VILLAGE GENREATION: GENERATING NEW VILLAGE Nr. '..tostring( village.nr ));
|
||||
end
|
||||
@ -867,7 +997,34 @@ mg_villages.place_buildings = function(village, minp, maxp, data, param2_data, a
|
||||
-- replacements are in table format for mapgen-based building spawning
|
||||
generate_building(pos, minp, maxp, data, param2_data, a, pr_village, extranodes, replacements )
|
||||
end
|
||||
|
||||
-- replacements are in list format for minetest.place_schematic(..) type spawning
|
||||
return { extranodes = extranodes, bpos = bpos, replacements = replacements.list };
|
||||
return { extranodes = extranodes, bpos = bpos, replacements = replacements.list, dirt_roads = village.to_add_data.dirt_roads };
|
||||
end
|
||||
|
||||
|
||||
-- add the dirt roads
|
||||
mg_villages.place_dirt_roads = function(village, minp, maxp, data, param2_data, a, vnoise, c_road_node)
|
||||
local c_air = minetest.get_content_id( 'air' );
|
||||
for _, pos in ipairs(village.to_add_data.dirt_roads) do
|
||||
local param2 = 0;
|
||||
if( pos.bsizex > 2 ) then
|
||||
param2 = 1;
|
||||
end
|
||||
for x = 0, pos.bsizex-1 do
|
||||
for z = 0, pos.bsizez-1 do
|
||||
local ax = pos.x+x;
|
||||
local az = pos.z+z;
|
||||
|
||||
if (ax >= minp.x and ax <= maxp.x) and (ay >= minp.y and ay <= maxp.y) and (az >= minp.z and az <= maxp.z) then
|
||||
-- roads have a height of 1 block
|
||||
data[ a:index( ax, pos.y, az)] = c_road_node;
|
||||
param2_data[ a:index( ax, pos.y, az)] = param2;
|
||||
-- ...with air above
|
||||
data[ a:index( ax, pos.y+1, az)] = c_air;
|
||||
data[ a:index( ax, pos.y+2, az)] = c_air;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user