mapgen: Fix ground detection and clean code a bit

This commit is contained in:
HybridDog 2018-08-07 11:00:17 +02:00
parent d4c348de96
commit df97e1e4ee
1 changed files with 30 additions and 49 deletions

View File

@ -21,7 +21,6 @@ local function define_contents()
riesenpilz_glowshroom = minetest.get_content_id("riesenpilz:glowshroom"), riesenpilz_glowshroom = minetest.get_content_id("riesenpilz:glowshroom"),
riesenpilz_parasol = minetest.get_content_id("riesenpilz:parasol"), riesenpilz_parasol = minetest.get_content_id("riesenpilz:parasol"),
GROUND = {},
TREE_STUFF = { TREE_STUFF = {
minetest.get_content_id("default:tree"), minetest.get_content_id("default:tree"),
minetest.get_content_id("default:leaves"), minetest.get_content_id("default:leaves"),
@ -35,27 +34,9 @@ local function define_contents()
[minetest.get_content_id("default:papyrus")] = true [minetest.get_content_id("default:papyrus")] = true
}, },
} }
for name,data in pairs(minetest.registered_nodes) do
local groups = data.groups
if groups then
if groups.crumbly == 3
or groups.soil == 1 then
table.insert(c.GROUND, minetest.get_content_id(name))
end
end
end
end end
local function find_ground(a,list)
for i = 1,#list do
if a == list[i] then
return true
end
end
return false
end
local grounds = {} local grounds = {}
function is_ground(id) function is_ground(id)
local is = grounds[id] local is = grounds[id]
@ -63,7 +44,8 @@ function is_ground(id)
return is return is
end end
local data = minetest.registered_nodes[minetest.get_name_from_content_id(id)] local data = minetest.registered_nodes[minetest.get_name_from_content_id(id)]
if not data then if not data
or data.paramtype == "light" then
grounds[id] = false grounds[id] = false
return false return false
end end
@ -78,26 +60,20 @@ function is_ground(id)
end end
local data, area local data, area, pr
function riesenpilz_circle(nam, pos, radius, chance) function riesenpilz_circle(nam, pos, radius, chance)
for _,p in pairs(vector.circle(radius)) do local circle = vector.circle(radius)
if pr:next(1,chance) == 1 then for i = 1,#circle do
local p = vector.add(pos, p) if pr:next(1, chance) == 1 then
local p_p = area:indexp(p) local vi = area:indexp(vector.add(pos, circle[i]))
if (data[p_p] == c.air or data[p_p] == c.ignore) if data[vi] == c.air
and find_ground(data[area:index(p.x, p.y-1, p.z)], c.GROUND) then and is_ground(data[vi - area.ystride]) then
data[p_p] = nam data[vi] = nam
end end
end end
end end
end end
local function say_info(info)
local info = "[riesenpilz] "..info
print(info)
minetest.chat_send_all(info)
end
-- perlin noise "hills" are not peaks but looking like sinus curve -- perlin noise "hills" are not peaks but looking like sinus curve
local function upper_rarity(rarity) local function upper_rarity(rarity)
return math.sign(rarity)*math.sin(math.abs(rarity)*math.pi/2) return math.sign(rarity)*math.sin(math.abs(rarity)*math.pi/2)
@ -203,47 +179,52 @@ minetest.register_on_generated(function(minp, maxp, seed)
if in_biome then if in_biome then
local ymin = math.max(heightmap[hmi]-5, minp.y) local ymin = math.max(heightmap[hmi]-5, minp.y)
local ymax = math.min(heightmap[hmi]+20, maxp.y)
-- skip the air part -- skip the air part
local ground local ground
for y = math.min(heightmap[hmi]+20, maxp.y),ymin,-1 do local vi = area:index(x, ymax, z)
if data[area:index(x, y, z)] ~= c.air then for y = ymax, ymin, -1 do
if data[vi] ~= c.air then
ground = y ground = y
break break
end end
vi = vi - area.ystride
end end
local ground_y local ground_y
if ground then if ground then
for y = ground,ymin,-1 do for y = ground, ymin, -1 do
local p_pos = area:index(x, y, z) local d_p_pos = data[vi]
local d_p_pos = data[p_pos] if c.USUAL_STUFF[d_p_pos] then
if c.USUAL_STUFF[d_p_pos] then --remove usual stuff -- remove trees etc.
data[p_pos] = c.air data[vi] = c.air
else else
if d_p_pos ~= c.water if is_ground(d_p_pos) then
and is_ground(d_p_pos) then --else search ground_y
ground_y = y ground_y = y
end end
break break
end end
vi = vi - area.ystride
end end
end end
if ground_y then if ground_y then
data[area:index(x, ground_y, z)] = c.ground -- add ground and dirt below if needed
data[vi] = c.ground
for i = -1,-5,-1 do for i = -1,-5,-1 do
local p_pos = area:index(x, ground_y+i, z) local p_pos = vi + i * area.ystride
if data[p_pos] == c.desert_sand then if not is_ground(data[p_pos])
data[p_pos] = c.dirt or data[p_pos] == c.dirt then
else
break break
end end
data[p_pos] = c.dirt
end end
local bigtype local bigtype
local boden = {x=x,y=ground_y+1,z=z} local boden = {x=x,y=ground_y+1,z=z}
if pr:next(1,15) == 1 then if pr:next(1,15) == 1 then
data[area:index(x, ground_y+1, z)] = c.dry_shrub data[vi + area.ystride] = c.dry_shrub
elseif pr:next(1,80) == 1 then elseif pr:next(1,80) == 1 then
riesenpilz_circle(c.riesenpilz_brown, boden, pr:next(3,4), 3) riesenpilz_circle(c.riesenpilz_brown, boden, pr:next(3,4), 3)
elseif pr:next(1,85) == 1 then elseif pr:next(1,85) == 1 then