streamline mapgen code: reduce index calculations

M  src/mapgen_v6.lua
This commit is contained in:
HybridDog 2016-09-14 16:53:01 +02:00
parent 9f73cc4778
commit 7774eb3f7f
1 changed files with 50 additions and 48 deletions

View File

@ -247,33 +247,31 @@ minetest.register_on_generated(function(minp, maxp, seed)
-- remove trees near alpine -- remove trees near alpine
local ground_y local ground_y
if data[area:index(x, maxp.y, z)] == c.air then if data[area:index(x, maxp.y, z)] == c.air then
for y = math.min(heightmap[ni]+20, maxp.y), math.max(minp.y, heightmap[ni]-5), -1 do local ytop = math.min(heightmap[ni]+20, maxp.y)
if data[area:index(x, y, z)] ~= c.air then local vi = area:index(x, ytop, z)
for y = ytop, math.max(minp.y, heightmap[ni]-5), -1 do
if data[vi] ~= c.air then
ground_y = y ground_y = y
break break
end end
vi = vi - area.ystride
end end
end end
if ground_y then if ground_y then
local vi = area:index(x, ground_y, z) local vi = area:index(x, ground_y, z)
if data[vi] == c.leaves for _ = minp.y - 16, ground_y do
or data[vi] == c.jungleleaves then local id = data[vi]
nodes_added = true if id == c.leaves
for y = ground_y, -16, -1 do or id == c.jungleleaves
local vi = area:index(x, y, z) or id == c.tree
local id = data[vi] or id == c.apple then
if id ~= c.air then data[vi] = c.air
if id == c.leaves nodes_added = true
or id == c.jungleleaves else
or id == c.tree break
or id == c.apple then
data[vi] = c.air
else
break
end
end
end end
vi = vi - area.ystride
end end
end end
end end
@ -295,11 +293,14 @@ minetest.register_on_generated(function(minp, maxp, seed)
-- avoid generating underground -- avoid generating underground
if data[area:index(x, maxp.y, z)] == c.air then if data[area:index(x, maxp.y, z)] == c.air then
-- search for non air node from 20 m above ground down to 5 m below ground (confined by minp and maxp) -- search for non air node from 20 m above ground down to 5 m below ground (confined by minp and maxp)
for y = math.min(heightmap[ni]+20, maxp.y), math.max(minp.y, heightmap[ni]-5), -1 do local ytop = math.min(heightmap[ni]+20, maxp.y)
if data[area:index(x, y, z)] ~= c.air then local vi = area:index(x, ytop, z)
for y = ytop, math.max(minp.y, heightmap[ni]-5), -1 do
if data[vi] ~= c.air then
ground_y = y ground_y = y
break break
end end
vi = vi - area.ystride
end end
end end
@ -313,12 +314,13 @@ minetest.register_on_generated(function(minp, maxp, seed)
snow_tab[num] = {ground_y, z, x, test} snow_tab[num] = {ground_y, z, x, test}
num = num+1 num = num+1
-- generate stone ground -- generate stone ground
for y = ground_y, math.max(-6, minp.y-6), -1 do local vi = area:index(x, ground_y, z)
local vi = area:index(x, y, z) for _ = math.max(-6, minp.y-6), ground_y do
if data[vi] == c.stone then if data[vi] == c.stone then
break break
end end
data[vi] = c.stone data[vi] = c.stone
vi = vi - area.ystride
end end
elseif pines elseif pines
and pr:next(1,36) == 1 then and pr:next(1,36) == 1 then
@ -354,15 +356,16 @@ minetest.register_on_generated(function(minp, maxp, seed)
local ice local ice
if pr:next(1,4) == 1 if pr:next(1,4) == 1
and (cool or icebergs) then and (cool or icebergs) then
for _,i in ipairs(nds) do for i = 1,#nds do
if i == c.ice then if nds[i] == c.ice then
ice = true ice = true
break break
end end
end end
end end
if not ice then if not ice then
for _,i in ipairs(nds) do for i = 1,#nds do
i = nds[i]
if i ~= c.water if i ~= c.water
and i ~= c.ice and i ~= c.ice
and i ~= c.air and i ~= c.air
@ -385,12 +388,13 @@ minetest.register_on_generated(function(minp, maxp, seed)
data[node] = c.ice data[node] = c.ice
end end
if icecave then if icecave then
for y = ground_y-1, -33, -1 do local vi = area:index(x, ground_y-1, z)
local vi = area:index(x, y, z) for _ = math.max(minp.y-16, -33), ground_y-1 do
if data[vi] ~= c.water then if data[vi] ~= c.water then
break break
end end
data[vi] = c.air data[vi] = c.air
vi = vi - area.ystride
end end
end end
if icesheet then if icesheet then
@ -409,24 +413,23 @@ minetest.register_on_generated(function(minp, maxp, seed)
snow_tab[num] = {ground_y, z, x, test} snow_tab[num] = {ground_y, z, x, test}
num = num+1 num = num+1
-- replace papyrus plants with snowblocks -- replace papyrus plants with snowblocks
local y = ground_y local vi = area:index(x, ground_y, z)
for _ = 1,7 do for _ = 1,7 do
local vi = area:index(x, y, z) if data[vi] ~= c.papyrus then
if data[vi] == c.papyrus then
data[vi] = c.snow_block
y = y-1
else
break break
end end
data[vi] = c.snow_block
vi = vi - area.ystride
end end
elseif alpine then elseif alpine then
-- make stone pillars out of trees and other stuff -- make stone pillars out of trees and other stuff
for y = ground_y, math.max(-6, minp.y-6), -1 do local vi = area:index(x, ground_y, z)
local stone = area:index(x, y, z) for _ = 0, ground_y - math.max(-6, minp.y-6) do
if data[stone] == c.stone then if data[vi] == c.stone then
break break
end end
data[stone] = c.stone data[vi] = c.stone
vi = vi - area.ystride
end end
-- put snow onto it -- put snow onto it
snow_tab[num] = {ground_y, z, x, test} snow_tab[num] = {ground_y, z, x, test}
@ -437,9 +440,8 @@ minetest.register_on_generated(function(minp, maxp, seed)
snow_tab[num] = {ground_y, z, x, test} snow_tab[num] = {ground_y, z, x, test}
num = num+1 num = num+1
end end
for y = 0, 12 do local vi = area:index(x, ground_y, z)
y = ground_y-y for _ = 0, 12 do
local vi = area:index(x, y, z)
local nd = data[vi] local nd = data[vi]
local plantlike = is_plantlike(nd) local plantlike = is_plantlike(nd)
if replacements[nd] then if replacements[nd] then
@ -451,7 +453,7 @@ minetest.register_on_generated(function(minp, maxp, seed)
data[vi] = c.dirt_with_snow data[vi] = c.dirt_with_snow
break break
elseif plantlike then elseif plantlike then
local under = area:index(x, y-1, z) local under = vi - area.ystride
if data[under] == c.dirt_with_grass then if data[under] == c.dirt_with_grass then
-- replace other plants with shrubs -- replace other plants with shrubs
data[vi] = c.snow_shrub data[vi] = c.snow_shrub
@ -462,6 +464,7 @@ minetest.register_on_generated(function(minp, maxp, seed)
elseif nd == c.stone then elseif nd == c.stone then
break break
end end
vi = vi - area.ystride
end end
end end
end end
@ -475,15 +478,14 @@ minetest.register_on_generated(function(minp, maxp, seed)
return return
end end
-- try to fix oom memory crashes
minetest.after(0, collectgarbage)
if num ~= 1 then if num ~= 1 then
for _,i in pairs(snow_tab) do for i = 1, num-1 do
i = snow_tab[i]
-- set snow -- set snow
data[area:index(i[3], i[1]+1, i[2])] = c.snow data[area:index(i[3], i[1]+1, i[2])] = c.snow
end end
for _,i in pairs(snow_tab) do for i = 1, num-1 do
i = snow_tab[i]
local y,z,x,test = unpack(i) local y,z,x,test = unpack(i)
test = (test-nosmooth_rarity)/(1-nosmooth_rarity) -- /(1-0.53) test = (test-nosmooth_rarity)/(1-nosmooth_rarity) -- /(1-0.53)
if test > 0 then if test > 0 then
@ -528,8 +530,8 @@ minetest.register_on_generated(function(minp, maxp, seed)
if pines if pines
and pnum ~= 1 then and pnum ~= 1 then
local spawn_pine = snow.voxelmanip_pine local spawn_pine = snow.voxelmanip_pine
for _,pos in pairs(pines_tab) do for i = 1, pnum-1 do
spawn_pine(pos, area, data) spawn_pine(pines_tab[i], area, data)
end end
end end