made village generation really independent from mg mapgen
This commit is contained in:
parent
8ee366feea
commit
770e6a81af
4
init.lua
4
init.lua
@ -33,3 +33,7 @@ dofile(mg_villages.modpath.."/chat_commands.lua")
|
|||||||
dofile(mg_villages.modpath.."/protection.lua")
|
dofile(mg_villages.modpath.."/protection.lua")
|
||||||
-- create and show a map of the world
|
-- create and show a map of the world
|
||||||
dofile(mg_villages.modpath.."/map_of_world.lua")
|
dofile(mg_villages.modpath.."/map_of_world.lua")
|
||||||
|
|
||||||
|
-- the interface for the mapgen;
|
||||||
|
-- also takes care of spawning the player
|
||||||
|
dofile(mg_villages.modpath.."/mapgen.lua")
|
||||||
|
|||||||
185
mapgen.lua
Normal file
185
mapgen.lua
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
|
||||||
|
mg_villages.wseed = 0;
|
||||||
|
|
||||||
|
--minetest.register_on_mapgen_init(function(mgparams)
|
||||||
|
-- mg_villages.wseed = math.floor(mgparams.seed/10000000000)
|
||||||
|
--end)
|
||||||
|
|
||||||
|
function mg_villages.get_bseed(minp)
|
||||||
|
return mg_villages.wseed + math.floor(5*minp.x/47) + math.floor(873*minp.z/91)
|
||||||
|
end
|
||||||
|
|
||||||
|
function mg_villages.get_bseed2(minp)
|
||||||
|
return mg_villages.wseed + math.floor(87*minp.x/47) + math.floor(73*minp.z/91) + math.floor(31*minp.y/12)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
mg_villages.inside_village = function(x, z, village, vnoise)
|
||||||
|
return mg_villages.get_vn(x, z, vnoise:get2d({x = x, y = z}), village) <= 40
|
||||||
|
end
|
||||||
|
|
||||||
|
mg_villages.get_vn = function(x, z, noise, village)
|
||||||
|
local vx, vz, vs = village.vx, village.vz, village.vs
|
||||||
|
return (noise - 2) * 20 +
|
||||||
|
(40 / (vs * vs)) * ((x - vx) * (x - vx) + (z - vz) * (z - vz))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
mg_villages.villages_in_mapchunk = function( minp )
|
||||||
|
local noise1raw = minetest.get_perlin(12345, 6, 0.5, 256)
|
||||||
|
|
||||||
|
local vcr = VILLAGE_CHECK_RADIUS
|
||||||
|
local villages = {}
|
||||||
|
local generate_new_villages = true;
|
||||||
|
for xi = -vcr, vcr do
|
||||||
|
for zi = -vcr, vcr do
|
||||||
|
for _, village in ipairs(mg_villages.villages_at_point({x = minp.x + xi * 80, z = minp.z + zi * 80}, noise1raw)) do
|
||||||
|
village.to_grow = {}
|
||||||
|
villages[#villages+1] = village
|
||||||
|
end
|
||||||
|
-- check if the village exists already
|
||||||
|
local v_nr = 1;
|
||||||
|
for v_nr, village in ipairs(villages) do
|
||||||
|
local village_id = tostring( village.vx )..':'..tostring( village.vz );
|
||||||
|
if( mg_villages.all_villages and mg_villages.all_villages[ village_id ]) then
|
||||||
|
villages[ v_nr ] = mg_villages.all_villages[ village_id ];
|
||||||
|
generate_new_villages = false;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return villages;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mg_villages.place_villages_via_voxelmanip = function( villages, minp, maxp, vm, data, param2_data, a, top )
|
||||||
|
|
||||||
|
local village_noise = minetest.get_perlin(7635, 3, 0.5, 16);
|
||||||
|
|
||||||
|
-- if no voxelmanip data was passed on, read the data here
|
||||||
|
if( not( vm ) or not( a) or not( data ) or not( param2_data ) ) then
|
||||||
|
vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||||
|
if( not( vm )) then
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
a = VoxelArea:new{
|
||||||
|
MinEdge={x=emin.x, y=emin.y, z=emin.z},
|
||||||
|
MaxEdge={x=emax.x, y=emax.y, z=emax.z},
|
||||||
|
}
|
||||||
|
|
||||||
|
data = vm:get_data()
|
||||||
|
param2_data = vm:get_param2_data()
|
||||||
|
end
|
||||||
|
|
||||||
|
local top_node = 'default:dirt_with_grass';
|
||||||
|
-- replace dirt_with_grass with whatever is common in that biome
|
||||||
|
if( top == c_sand ) then top_node = 'default:sand';
|
||||||
|
elseif( top == c_dsert_sand ) then top_node = 'default:desert_sand';
|
||||||
|
elseif( top == c_dry_grass ) then top_node = 'mg:dirt_with_dry_grass';
|
||||||
|
elseif( top == c_dirt_snow ) then top_node = 'default:dirt_with_snow';
|
||||||
|
else top_node = 'default:dirt_with_grass';
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, village in ipairs(villages) do
|
||||||
|
village.to_add_data = mg_villages.generate_village(village, minp, maxp, data, param2_data, a, village_noise, top_node)
|
||||||
|
end
|
||||||
|
|
||||||
|
vm:set_data(data)
|
||||||
|
vm:set_param2_data(param2_data)
|
||||||
|
|
||||||
|
vm:calc_lighting(
|
||||||
|
{x=minp.x-16, y=minp.y, z=minp.z-16},
|
||||||
|
{x=maxp.x+16, y=maxp.y, z=maxp.z+16}
|
||||||
|
)
|
||||||
|
|
||||||
|
vm:write_to_map(data)
|
||||||
|
|
||||||
|
-- initialize the pseudo random generator so that the chests will be filled in a reproducable pattern
|
||||||
|
local pr = PseudoRandom(mg_villages.get_bseed(minp));
|
||||||
|
local meta
|
||||||
|
for _, village in ipairs(villages) do
|
||||||
|
for _, n in pairs(village.to_add_data.extranodes) do
|
||||||
|
minetest.set_node(n.pos, n.node)
|
||||||
|
if n.meta ~= nil then
|
||||||
|
meta = minetest.get_meta(n.pos)
|
||||||
|
meta:from_table(n.meta)
|
||||||
|
if n.node.name == "default:chest" then
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
local items = inv:get_list("main")
|
||||||
|
for i=1, inv:get_size("main") do
|
||||||
|
inv:set_stack("main", i, ItemStack(""))
|
||||||
|
end
|
||||||
|
local numitems = pr:next(3, 20)
|
||||||
|
for i=1,numitems do
|
||||||
|
local ii = pr:next(1, #items)
|
||||||
|
local prob = items[ii]:get_count() % 2 ^ 8
|
||||||
|
local stacksz = math.floor(items[ii]:get_count() / 2 ^ 8)
|
||||||
|
if pr:next(0, prob) == 0 and stacksz>0 then
|
||||||
|
stk = ItemStack({name=items[ii]:get_name(), count=pr:next(1, stacksz), wear=items[ii]:get_wear(), metadata=items[ii]:get_metadata()})
|
||||||
|
local ind = pr:next(1, inv:get_size("main"))
|
||||||
|
while not inv:get_stack("main",ind):is_empty() do
|
||||||
|
ind = pr:next(1, inv:get_size("main"))
|
||||||
|
end
|
||||||
|
inv:set_stack("main", ind, stk)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- now add those buildings which are .mts files and need to be placed by minetest.place_schematic(...)
|
||||||
|
mg_villages.place_schematics( village.to_add_data.bpos, village.to_add_data.replacements, a, pr );
|
||||||
|
|
||||||
|
if( not( mg_villages.all_villages )) then
|
||||||
|
mg_villages.all_villages = {};
|
||||||
|
end
|
||||||
|
-- unique id - there can only be one village at a given pair of x,z coordinates
|
||||||
|
local village_id = tostring( village.vx )..':'..tostring( village.vz );
|
||||||
|
-- the village data is saved only once per village - and not whenever part of the village is generated
|
||||||
|
if( not( mg_villages.all_villages[ village_id ])) then
|
||||||
|
|
||||||
|
-- count how many villages we already have and assign each village a uniq number
|
||||||
|
local count = 1;
|
||||||
|
for _,v in pairs( mg_villages.all_villages ) do
|
||||||
|
count = count + 1;
|
||||||
|
end
|
||||||
|
village.nr = count;
|
||||||
|
mg_villages.anz_villages = count;
|
||||||
|
mg_villages.all_villages[ village_id ] = minetest.deserialize( minetest.serialize( village ));
|
||||||
|
|
||||||
|
print("Village No. "..tostring( count ).." of type \'"..tostring( village.village_type ).."\' of size "..tostring( village.vs ).." spawned at: x = "..village.vx..", z = "..village.vz)
|
||||||
|
save_restore.save_data( 'mg_all_villages.data', mg_villages.all_villages );
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function spawnplayer(player)
|
||||||
|
local noise1 = minetest.get_perlin(12345, 6, 0.5, 256)
|
||||||
|
local min_dist = math.huge
|
||||||
|
local min_pos = {x = 0, y = 3, z = 0}
|
||||||
|
for bx = -20, 20 do
|
||||||
|
for bz = -20, 20 do
|
||||||
|
local minp = {x = -32 + 80 * bx, y = -32, z = -32 + 80 * bz}
|
||||||
|
for _, village in ipairs(mg_villages.villages_at_point(minp, noise1)) do
|
||||||
|
if math.abs(village.vx) + math.abs(village.vz) < min_dist then
|
||||||
|
min_pos = {x = village.vx, y = village.vh + 2, z = village.vz}
|
||||||
|
min_dist = math.abs(village.vx) + math.abs(village.vz)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
player:setpos(min_pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_newplayer(function(player)
|
||||||
|
spawnplayer(player)
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_on_respawnplayer(function(player)
|
||||||
|
spawnplayer(player)
|
||||||
|
return true
|
||||||
|
end)
|
||||||
18
villages.lua
18
villages.lua
@ -32,7 +32,7 @@ mg_villages.villages_at_point = function(minp, noise1)
|
|||||||
for zi = -vcr, 0, vcc do
|
for zi = -vcr, 0, vcc do
|
||||||
if xi ~= 0 or zi ~= 0 then
|
if xi ~= 0 or zi ~= 0 then
|
||||||
local mp = {x = minp.x + 80*xi, z = minp.z + 80*zi}
|
local mp = {x = minp.x + 80*xi, z = minp.z + 80*zi}
|
||||||
local pi = PseudoRandom(get_bseed(mp))
|
local pi = PseudoRandom(mg_villages.get_bseed(mp))
|
||||||
local s = pi:next(1, 400)
|
local s = pi:next(1, 400)
|
||||||
local x = pi:next(mp.x, mp.x + 79)
|
local x = pi:next(mp.x, mp.x + 79)
|
||||||
local z = pi:next(mp.z, mp.z + 79)
|
local z = pi:next(mp.z, mp.z + 79)
|
||||||
@ -40,7 +40,7 @@ mg_villages.villages_at_point = function(minp, noise1)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local pr = PseudoRandom(get_bseed(minp))
|
local pr = PseudoRandom(mg_villages.get_bseed(minp))
|
||||||
if pr:next(1, 400) > VILLAGE_CHANCE then return {} end -- No village here
|
if pr:next(1, 400) > VILLAGE_CHANCE then return {} end -- No village here
|
||||||
local x = pr:next(minp.x, minp.x + 79)
|
local x = pr:next(minp.x, minp.x + 79)
|
||||||
local z = pr:next(minp.z, minp.z + 79)
|
local z = pr:next(minp.z, minp.z + 79)
|
||||||
@ -71,7 +71,7 @@ end
|
|||||||
--end
|
--end
|
||||||
|
|
||||||
local function inside_village2(bx, sx, bz, sz, village, vnoise)
|
local function inside_village2(bx, sx, bz, sz, village, vnoise)
|
||||||
return inside_village(bx, bz, village, vnoise) and inside_village(bx+sx, bz, village, vnoise) and inside_village(bx, bz+sz, village, vnoise) and inside_village(bx+sx, bz+sz, village, vnoise)
|
return mg_villages.inside_village(bx, bz, village, vnoise) and mg_villages.inside_village(bx+sx, bz, village, vnoise) and mg_villages.inside_village(bx, bz+sz, village, vnoise) and mg_villages.inside_village(bx+sx, bz+sz, village, vnoise)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function choose_building(l, pr, village_type)
|
local function choose_building(l, pr, village_type)
|
||||||
@ -178,7 +178,7 @@ local function generate_road(village, l, pr, roadsize, rx, rz, rdx, rdz, vnoise)
|
|||||||
orient1 = 3
|
orient1 = 3
|
||||||
orient2 = 1
|
orient2 = 1
|
||||||
end
|
end
|
||||||
while inside_village(rx, rz, village, vnoise) and not road_in_building(rx, rz, rdx, rdz, roadsize, l) do
|
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
|
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))
|
--generate_road(vx, vz, vs, vh, l, pr, roadsize-1, rx, rz, math.abs(rdz), math.abs(rdx))
|
||||||
calls_to_do[#calls_to_do+1] = {rx=rx+(roadsize - 1)*rdx, rz=rz+(roadsize - 1)*rdz, rdx=math.abs(rdz), rdz=math.abs(rdx)}
|
calls_to_do[#calls_to_do+1] = {rx=rx+(roadsize - 1)*rdx, rz=rz+(roadsize - 1)*rdz, rdx=math.abs(rdz), rdz=math.abs(rdx)}
|
||||||
@ -194,7 +194,7 @@ local function generate_road(village, l, pr, roadsize, rx, rz, rdx, rdz, vnoise)
|
|||||||
local bz
|
local bz
|
||||||
local tries = 0
|
local tries = 0
|
||||||
while true do
|
while true do
|
||||||
if not inside_village(rx, rz, village, vnoise) or road_in_building(rx, rz, rdx, rdz, roadsize, l) then
|
if not mg_villages.inside_village(rx, rz, village, vnoise) or road_in_building(rx, rz, rdx, rdz, roadsize, l) then
|
||||||
exitloop = true
|
exitloop = true
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
@ -227,7 +227,7 @@ local function generate_road(village, l, pr, roadsize, rx, rz, rdx, rdz, vnoise)
|
|||||||
end
|
end
|
||||||
rx = rxx
|
rx = rxx
|
||||||
rz = rzz
|
rz = rzz
|
||||||
while inside_village(rx, rz, village, vnoise) and not road_in_building(rx, rz, rdx, rdz, roadsize, l) do
|
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
|
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))
|
--generate_road(vx, vz, vs, vh, l, pr, roadsize-1, rx, rz, -math.abs(rdz), -math.abs(rdx))
|
||||||
calls_to_do[#calls_to_do+1] = {rx=rx+(roadsize - 1)*rdx, rz=rz+(roadsize - 1)*rdz, rdx=-math.abs(rdz), rdz=-math.abs(rdx)}
|
calls_to_do[#calls_to_do+1] = {rx=rx+(roadsize - 1)*rdx, rz=rz+(roadsize - 1)*rdz, rdx=-math.abs(rdz), rdz=-math.abs(rdx)}
|
||||||
@ -243,7 +243,7 @@ local function generate_road(village, l, pr, roadsize, rx, rz, rdx, rdz, vnoise)
|
|||||||
local bz
|
local bz
|
||||||
local tries = 0
|
local tries = 0
|
||||||
while true do
|
while true do
|
||||||
if not inside_village(rx, rz, village, vnoise) or road_in_building(rx, rz, rdx, rdz, roadsize, l) then
|
if not mg_villages.inside_village(rx, rz, village, vnoise) or road_in_building(rx, rz, rdx, rdz, roadsize, l) then
|
||||||
exitloop = true
|
exitloop = true
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
@ -368,7 +368,7 @@ local function generate_bpos(village, pr, vnoise)
|
|||||||
end
|
end
|
||||||
return l]=]--
|
return l]=]--
|
||||||
local rz = vz
|
local rz = vz
|
||||||
while inside_village(rx, rz, village, vnoise) do
|
while mg_villages.inside_village(rx, rz, village, vnoise) do
|
||||||
rx = rx - 1
|
rx = rx - 1
|
||||||
end
|
end
|
||||||
rx = rx + 5
|
rx = rx + 5
|
||||||
@ -799,7 +799,7 @@ end
|
|||||||
mg_villages.generate_village = function(village, minp, maxp, data, param2_data, a, vnoise, dirt_with_grass_replacement)
|
mg_villages.generate_village = function(village, minp, maxp, data, param2_data, a, vnoise, dirt_with_grass_replacement)
|
||||||
local vx, vz, vs, vh = village.vx, village.vz, village.vs, village.vh
|
local vx, vz, vs, vh = village.vx, village.vz, village.vs, village.vh
|
||||||
local village_type = village.village_type;
|
local village_type = village.village_type;
|
||||||
local seed = get_bseed({x=vx, z=vz})
|
local seed = mg_villages.get_bseed({x=vx, z=vz})
|
||||||
local pr_village = PseudoRandom(seed)
|
local pr_village = PseudoRandom(seed)
|
||||||
|
|
||||||
-- only generate a new village if the data is not already stored
|
-- only generate a new village if the data is not already stored
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user