Skip to content
Snippets Groups Projects
Commit da5af62f authored by Duane Robertson's avatar Duane Robertson
Browse files

Use default biomes. Fix respawn. Change sky.

parent fb89aa62
No related branches found
No related tags found
No related merge requests found
......@@ -86,6 +86,9 @@ minetest.register_on_newplayer(loud_walking.respawn)
minetest.register_on_respawnplayer(loud_walking.respawn)
minetest.register_on_generated(loud_walking.generate)
minetest.register_on_joinplayer(function(player)
player:set_sky("#000000", "plain", {})
end)
local function deco_list()
for i, deco in pairs(minetest.registered_decorations) do
......
local node = loud_walking.node
local bevel = 40
local data = {}
local p2data = {} -- vm rotation data buffer
......@@ -7,7 +9,7 @@ local lightmap = {}
local vm, emin, emax, a, csize, heightmap, biomemap
local div_sz_x, div_sz_z, minp, maxp, terrain, cave
local base_terrain_noise = {offset = 0,
local terrain_noise = {offset = 0,
scale = 20, seed = 8829, spread = {x = 40, y = 40, z = 40},
octaves = 6, persist = 0.4, lacunarity = 2}
......@@ -15,15 +17,52 @@ local cave_noise = {offset = 0, scale = 1,
seed = -3977, spread = {x = 30, y = 30, z = 30}, octaves = 3,
persist = 0.8, lacunarity = 2}
local tree_biomes = {}
tree_biomes["deciduous_forest"] = {"deciduous_trees"}
tree_biomes["coniferous_forest"] = {"conifer_trees"}
tree_biomes["rainforest"] = {"jungle_trees"}
local biome_names = {}
biome_names["common"] = {}
biome_names["uncommon"] = {}
local biomes = {}
do
local biome_terrain_scale = {}
biome_terrain_scale["coniferous_forest"] = 0.75
biome_terrain_scale["rainforest"] = 0.33
biome_terrain_scale["underground"] = 1.5
local tree_biomes = {}
tree_biomes["deciduous_forest"] = {"deciduous_trees"}
tree_biomes["coniferous_forest"] = {"conifer_trees"}
tree_biomes["taiga"] = {"conifer_trees"}
tree_biomes["rainforest"] = {"jungle_trees"}
tree_biomes["rainforest_swamp"] = {"jungle_trees"}
tree_biomes["deciduous_forest_swamp"] = {"deciduous_trees"}
tree_biomes["coniferous_forest"] = {"conifer_trees"}
for i, obiome in pairs(minetest.registered_biomes) do
local biome = table.copy(obiome)
local rarity = "common"
biome.terrain_scale = biome_terrain_scale[biome] or 0.5
if string.find(biome.name, "ocean") then
biome.terrain_scale = 1
rarity = "uncommon"
end
if string.find(biome.name, "swamp") then
biome.terrain_scale = 0.25
rarity = "uncommon"
end
if string.find(biome.name, "beach") then
biome.terrain_scale = 0.25
rarity = "uncommon"
end
if string.find(biome.name, "^underground$") then
biome.node_top = "default:stone"
rarity = "uncommon"
end
biome.special_trees = tree_biomes[biome.name]
biomes[biome.name] = biome
biome_names[rarity][#biome_names[rarity]+1] = biome.name
--print(dump(biome))
end
end
local biome_terrain_scale = {}
biome_terrain_scale["deciduous_forest"] = 0.5
biome_terrain_scale["coniferous_forest"] = 0.75
biome_terrain_scale["rainforest"] = 0.33
local function place_schematic(pos, schem, center)
......@@ -40,20 +79,28 @@ local function place_schematic(pos, schem, center)
end
for z = 0, schem.size.z - 1 do
local dz = pos.z - minp.z + z
for x = 0, schem.size.x - 1 do
local ivm = a:index(pos.x + x, pos.y, pos.z + z)
local isch = z * schem.size.y * schem.size.x + x + 1
for y = 0, schem.size.y - 1 do
if yslice[y] or 255 >= math.random(255) then
local prob = schem.data[isch].prob or schem.data[isch].param1 or 255
if prob >= math.random(255) and schem.data[isch].name ~= "air" then
data[ivm] = node(schem.data[isch].name)
local dx = pos.x - minp.x + x
if pos.x + x > minp.x and pos.x + x < maxp.x and pos.z + z > minp.z and pos.z + z < maxp.z then
local ivm = a:index(pos.x + x, pos.y, pos.z + z)
local isch = z * schem.size.y * schem.size.x + x + 1
for y = 0, schem.size.y - 1 do
local dy = pos.y - minp.y + y
if math.min(dx, csize.x - dx) + math.min(dy, csize.y - dy) + math.min(dz, csize.z - dz) > bevel then
if yslice[y] or 255 >= math.random(255) then
local prob = schem.data[isch].prob or schem.data[isch].param1 or 255
if prob >= math.random(255) and schem.data[isch].name ~= "air" then
data[ivm] = node(schem.data[isch].name)
end
local param2 = schem.data[isch].param2 or 0
p2data[ivm] = param2
end
end
local param2 = schem.data[isch].param2 or 0
p2data[ivm] = param2
ivm = ivm + a.ystride
isch = isch + schem.size.x
end
ivm = ivm + a.ystride
isch = isch + schem.size.x
end
end
end
......@@ -95,28 +142,29 @@ local function connection(x, y, z)
return nil
end
local function get_height(dx, dz, biome, index)
local function get_height(dx, dz, terrain_scale, ocean, index)
local terr
if index == true then
local terrain_noise = table.copy(base_terrain_noise)
terrain_noise.scale = terrain_noise.scale * biome_terrain_scale[biome]
terr = math.floor(minetest.get_perlin(terrain_noise):get2d({x=dx, y=dz}) + 0.5)
-- Still need csize here...
dx = (dx + 32) % 80
dz = (dz + 32) % 80
elseif not index then
local half = math.floor(csize.y / 2 + 0.5)
--if index == true then
-- terr = minetest.get_perlin(terrain_noise):get2d({x=dx, y=dz})
-- -- Still need csize here...
-- dx = (dx + 32) % 80
-- dz = (dz + 32) % 80
if not index then
index = dz * csize.x + dx + 1
terr = math.floor(terrain[index] + 0.5)
terr = terrain[index]
else
terr = math.floor(terrain[index] + 0.5)
terr = terrain[index]
end
local d = 38 - math.abs(math.abs(dx - 39.5) - math.abs(dz - 39.5))
terr = math.floor(terr * terrain_scale + 0.5)
local d = half - 2 - math.abs(math.abs(dx - (half - 0.5)) - math.abs(dz - (half - 0.5)))
if math.abs(terr) > d then
if terr > 0 then
terr = math.floor(d + 0.5)
else
elseif not ocean then
terr = math.floor(0.5 - d)
end
end
......@@ -125,7 +173,13 @@ local function get_height(dx, dz, biome, index)
end
local function get_biome(px, pz)
return "deciduous_forest"
local sr = math.random(5)
local rarity = "common"
if sr > 4 then
rarity = "uncommon"
end
local biome = biome_names[rarity][math.random(#biome_names[rarity])]
return biome
end
local function get_decoration(biome)
......@@ -144,7 +198,7 @@ local function get_decoration(biome)
if biome_match and deco.deco_type == "simple" then
if deco.fill_ratio and math.random(1000) < deco.fill_ratio * 1000 then
return deco.decoration
elseif math.random(1000) < 10 then
elseif math.random(1000) < 6 then
return deco.decoration
end
end
......@@ -167,23 +221,38 @@ function loud_walking.generate(p_minp, p_maxp, seed)
-- Deal with memory issues. This, of course, is supposed to be automatic.
local mem = math.floor(collectgarbage("count")/1024)
if mem > 300 then
print("Manually collecting garbage...")
print("Loud Walking: Manually collecting garbage...")
collectgarbage("collect")
end
local px = math.floor((minp.x + 32) / csize.x)
local pz = math.floor((minp.z + 32) / csize.z)
local biome = get_biome(px, pz)
local top = node("default:dirt_with_grass")
-- use the same seed (based on perlin noise).
local seed_noise = minetest.get_perlin({offset = 0, scale = 32768,
seed = 5202, spread = {x = 80, y = 80, z = 80}, octaves = 2,
persist = 0.4, lacunarity = 2})
math.randomseed(seed_noise:get2d({x=minp.x, y=minp.z}))
local terrain_noise = table.copy(base_terrain_noise)
terrain_noise.scale = terrain_noise.scale * biome_terrain_scale[biome]
-- Keep this first after seeding!
local biome = get_biome(px, pz)
local px = math.floor((minp.x + 32) / csize.x)
local pz = math.floor((minp.z + 32) / csize.z)
local top = biomes[biome].node_top or "default:dirt_with_grass"
local filler = biomes[biome].node_filler or "default:dirt"
local depth_top = biomes[biome].depth_top or 1
local depth_filler = biomes[biome].depth_filler or 1
local node_stone = biomes[biome].node_stone or "default:stone"
local ocean = string.find(biome, "ocean") and true or false
local swamp = string.find(biome, "swamp") and true or false
local beach = string.find(biome, "beach") and true or false
local half = math.floor(csize.y / 2 + 0.5)
local ground = half
if ocean then
ground = ground - 15
elseif swamp or beach then
ground = ground - 3
end
terrain = minetest.get_perlin_map(terrain_noise, csize):get2dMap_flat(minp)
cave = minetest.get_perlin_map(cave_noise, csize):get3dMap_flat(minp)
......@@ -200,18 +269,18 @@ function loud_walking.generate(p_minp, p_maxp, seed)
index3d = dz * csize.y * csize.x + dx + 1
local ivm = a:index(x, minp.y, z)
local terr = get_height(dx, dz, biome, index)
local terr = get_height(dx, dz, biomes[biome].terrain_scale, ocean, index)
local in_cave = false
for y = minp.y, maxp.y do
local dy = y - minp.y
if pod then
if math.min(dx, csize.x - dx) + math.min(dy, csize.y - dy) + math.min(dz, csize.z - dz) < 40 then
if math.min(dx, csize.x - dx) + math.min(dy, csize.y - dy) + math.min(dz, csize.z - dz) < bevel then
data[ivm] = node("air")
--lightmap[ivm] = 0
lightmap[ivm] = 0
in_cave = false
elseif math.min(dx, csize.x - dx) + math.min(dy, csize.y - dy) + math.min(dz, csize.z - dz) < 41 then
if dy < terr + 40 then
elseif math.min(dx, csize.x - dx) + math.min(dy, csize.y - dy) + math.min(dz, csize.z - dz) < bevel + 1 then
if dy < half then
data[ivm] = node("loud_walking:scrith")
lightmap[ivm] = 0
else
......@@ -220,10 +289,10 @@ function loud_walking.generate(p_minp, p_maxp, seed)
in_cave = false
write = true
elseif (dx == 0 or dx == csize.x - 1) or (dz == 0 or dz == csize.z - 1) or (dy == 0 or dy == csize.y - 1) then
if math.abs(dy - 42) < 2 and (dz == 40 or dx == 40) then
if math.abs(dy - half - 2) < 2 and (dz == half or dx == half) then
data[ivm] = node("air")
else
if dy < terr + 40 then
if dy < half then
data[ivm] = node("loud_walking:scrith")
lightmap[ivm] = 0
else
......@@ -232,41 +301,46 @@ function loud_walking.generate(p_minp, p_maxp, seed)
write = true
end
in_cave = false
elseif not in_cave and dy == terr + 41 then
elseif not in_cave and dy == terr + ground + 1 then
local deco = get_decoration(biome)
if deco then
data[ivm] = node(deco)
end
write = true
elseif dy > terr + 40 then
elseif (ocean or swamp or beach) and dy > terr + ground and dy <= half then
data[ivm] = node("default:water_source")
in_cave = false
elseif dy > terr + ground then
data[ivm] = node("air")
in_cave = false
elseif cave[index3d] ^ 2 > 0.1 + dy / 40 then
if terr + 40 >= dy and not in_cave and dy > terr + 30 then
data[ivm] = node("default:dirt")
elseif cave[index3d] ^ 2 > 0.1 + dy / half then
if terr + ground >= dy and not in_cave and dy > terr + ground - 10 then
data[ivm] = node(biomes[biome].node_filler)
elseif ocean or swamp then
data[ivm] = node("default:water_source")
else
data[ivm] = node("air")
end
in_cave = true
lightmap[ivm] = 0
elseif dy > terr + 39 then
data[ivm] = top
elseif dy > terr + ground - depth_top then
data[ivm] = node(top)
lightmap[ivm] = 0
in_cave = false
write = true
elseif dy > terr + 37 then
elseif dy > terr + ground - depth_filler - depth_top then
data[ivm] = node("default:dirt")
lightmap[ivm] = 0
in_cave = false
write = true
else
data[ivm] = node("default:stone")
data[ivm] = node(node_stone)
lightmap[ivm] = 0
in_cave = false
write = true
end
elseif connection and dy == 40 and ((dx == 40 and connection % 4 == 0) or (dz == 40 and connection % 2 == 1)) then
data[ivm] = node("default:stone")
elseif connection and dy == half and ((dx == half and connection % 4 == 0) or (dz == half and connection % 2 == 1)) then
data[ivm] = node("loud_walking:scrith")
lightmap[ivm] = 0
write = true
end
......@@ -278,21 +352,27 @@ function loud_walking.generate(p_minp, p_maxp, seed)
end
if pod then
print(biome)
for dz = 0, 75, 5 do
for dx = 0, 75, 5 do
if math.random(2) == 1 then
local x = minp.x + dx + math.random(0, 4)
local z = minp.z + dz + math.random(0, 4)
local y = minp.y + get_height(x - minp.x, z - minp.z, biome) + 40
local y = minp.y + get_height(x - minp.x, z - minp.z, biomes[biome].terrain_scale, ocean) + ground
local ivm = a:index(x, y, z)
if data[ivm + a.ystride] == node("air") and (data[ivm] == node("default:dirt") or data[ivm] == node("default:dirt_with_grass") or data[ivm] == node("default:dirt_with_snow")) then
if tree_biomes[biome] then
local tree_type = tree_biomes[biome][math.random(#tree_biomes[biome])]
local schem = loud_walking.schematics[tree_type][math.random(#loud_walking.schematics[tree_type])]
local pos = {x=x, y=y, z=z}
-- The minetest schematic functions don't seem very accurate.
place_schematic(pos, schem, true)
if biomes[biome].special_trees then
--print(dump(biomes[biome].special_trees))
local tree_type = biomes[biome].special_trees[math.random(#biomes[biome].special_trees)]
if tree_type then
local schem = loud_walking.schematics[tree_type][math.random(#loud_walking.schematics[tree_type])]
local pos = {x=x, y=y, z=z}
-- The minetest schematic functions don't seem very accurate.
place_schematic(pos, schem, true)
end
else
-- regular schematics?
end
end
end
......@@ -318,14 +398,11 @@ end
function loud_walking.respawn(player)
local success = false
while not success do
local px = math.random(-10, 10) * 2
local px = math.random(-10, 10) * 2 - 1
local pz = math.random(-10, 10) * 2
-- How do we get csize before generation?
local dx = math.random(80) - 1
local dz = math.random(80) - 1
local x = (dx - 32) + 80 * px
local z = (dz - 32) + 80 * pz
local y = get_height(x, z, get_biome(px, pz), true) + 8
local x = 80 * px + 8
local z = 80 * pz + 8
local y = 9
local pos = {x=x,y=y,z=z}
local node = minetest.get_node(pos)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment