Initial commit.

master
Duane Robertson 2016-03-31 18:11:15 -05:00
parent de588e897a
commit e195b2c6c8
14 changed files with 1003 additions and 1 deletions

View File

@ -1,2 +1,13 @@
# loud_walking
Minetest pod-based mapgen
Loud Walking is a play on the name of an old science fiction movie about an attempt to preserve Earth's endangered life in sealed pods in space. This mod creates pods with more or less normal terrain inside, including vegetation and minerals. Eventually they'll have a variety of biomes inside. It's unusual in being fully three-dimensional. There are pods above, pods below, pods to all sides, and they all work basically the same. Bridges are provided to move horizontally. Moving vertically is more challenging.
![screenshot](https://github.com/duane-r/loud_walking/raw/master/textures/screenshot02.jpg)
The source is available on github.
Code: CC0 and others, textures: CC0 and others
Mod dependencies: default
Download: https://github.com/duane-r/loud_walking/archive/master.zip

75
deco.lua Normal file
View File

@ -0,0 +1,75 @@
-----------------
-- Decorations --
-----------------
-- The main decoration handler, through the game's decoration manager.
function table.contains_substring(t, s)
if type(s) ~= "string" then
return nil
end
for key, value in pairs(t) do
if type(value) == 'string' and s:find(value) then
if key then
return key
else
return true
end
end
end
return false
end
-- Copy all the decorations except the ones I don't like.
-- This is currently used to remove the default trees.
local bad_deco = {"apple_tree", "pine_tree", "jungle_tree", "acacia_tree", "aspen_tree", }
local decos = {}
for id, deco_table in pairs(minetest.registered_decorations) do
if type(deco_table.schematic) ~= "string" or not table.contains_substring(bad_deco, deco_table.schematic) then
table.insert(decos, deco_table)
end
end
-- Create and initialize a table for a schematic.
function loud_walking.schematic_array(width, height, depth)
-- Dimensions of data array.
local s = {size={x=width, y=height, z=depth}}
s.data = {}
for z = 0,depth-1 do
for y = 0,height-1 do
for x = 0,width-1 do
local i = z*width*height + y*width + x + 1
s.data[i] = {}
s.data[i].name = "air"
s.data[i].param1 = 000
end
end
end
s.yslice_prob = {}
return s
end
-- Clear all decorations, so I can place the new trees.
minetest.clear_registered_decorations()
-- A list of all schematics, for re-use.
loud_walking.schematics = {}
dofile(loud_walking.path.."/deco_trees.lua")
-- Re-register the good decorations.
-- This has to be done after registering the trees or
-- the trees spawn on top of grass. /shrug
for _, i in pairs(decos) do
minetest.register_decoration(i)
end

193
deco_conifer.lua Normal file
View File

@ -0,0 +1,193 @@
-------------------
-- Conifer Trees --
-------------------
-- Create different colored needles with the same properties.
newnode = loud_walking.clone_node("default:pine_needles")
if loud_walking.noleafdecay then
newnode.groups.leafdecay = 0
end
newnode.tiles = {"default_pine_needles.png^[colorize:#FF0000:20"}
minetest.register_node("loud_walking:pine_needles2", newnode)
newnode.tiles = {"default_pine_needles.png^[colorize:#FFFF00:20"}
minetest.register_node("loud_walking:pine_needles3", newnode)
newnode.tiles = {"default_pine_needles.png^[colorize:#00FF00:20"}
minetest.register_node("loud_walking:pine_needles4", newnode)
if loud_walking.glow then
minetest.register_node("loud_walking:pine_tree_glowing_moss", {
description = "Pine tree with glowing moss",
tiles = {"default_pine_tree_top.png", "default_pine_tree_top.png",
"default_pine_tree.png^trunks_moss.png"},
paramtype2 = "facedir",
is_ground_content = false,
light_source = 4,
drop = 'default:pine_tree',
groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2},
sounds = default.node_sound_wood_defaults(),
on_place = minetest.rotate_node
})
end
-- similar to the general tree schematic, but basically vertical
function loud_walking.generate_conifer_schematic(trunk_height, radius, trunk, leaf)
local height = trunk_height + radius * 3 + 2
local width = 2 * radius + 1
local trunk_top = height - radius - 1
local s = loud_walking.schematic_array(width, height, width)
-- the main trunk
local probs = {200,150,100,75,50,25}
for z = -radius,radius do
for y = 1,trunk_top do
-- Gives it a vaguely conical shape.
local r1 = math.ceil((height - y) / 4)
-- But rounded at the bottom.
if y == trunk_height + 1 then
r1 = r1 -1
end
for x = -radius,radius do
local i = (z+radius)*width*height + y*width + (x+radius) + 1
local dist = math.floor(math.sqrt(x^2 + z^2 + 0.5))
if x == 0 and z == 0 then
if trunk == "default:pine_tree" and loud_walking.glow and math.random(1,10) == 1 then
s.data[i].name = "loud_walking:pine_tree_glowing_moss"
else
s.data[i].name = trunk
end
s.data[i].param1 = 255
s.data[i].force_place = true
elseif y > trunk_height and dist <= r1 then
s.data[i].name = leaf
s.data[i].param1 = probs[dist]
end
end
end
end
-- leaves at the top
for z = -1,1 do
for y = trunk_top, height-1 do
for x = -1,1 do
local i = (z+radius)*width*height + y*width + (x+radius) + 1
if (x == 0 and z == 0) or y < height - 1 then
s.data[i].name = leaf
if x == 0 and z == 0 then
s.data[i].param1 = 255
else
s.data[i].param1 = 200
end
end
end
end
end
return s
end
-- the default pine schematic
function loud_walking.generate_default_conifer_schematic(trunk, leaf)
local height = 13 + 1
local width = 5
local s = loud_walking.schematic_array(width, height, width)
-- the main trunk
local probs = {255,220,190}
for p = 0,2 do
local c = math.floor(width / 2)
local y = height - p * 3 - 1
for r = 0,2 do
for z = c-r,c+r do
for x = c-r,c+r do
local i = z*width*height + (y-r)*width + x + 1
s.data[i].name = leaf
s.data[i].param1 = probs[r]
end
end
end
s.yslice_prob = {}
for y = 1,height-3 do
local i = 2*width*height + y*width + 2 + 1
if trunk == "default:pine_tree" and loud_walking.glow and math.random(1,10) == 1 then
s.data[i].name = "loud_walking:pine_tree_glowing_moss"
else
s.data[i].name = trunk
end
s.data[i].param1 = 255
s.data[i].force_place = true
local j = (height - y - 1) / 3
if j == 0 or j == 1 or j == 2 or y <= height - 11 then
s.yslice_prob[#s.yslice_prob+1] = {ypos=y,prob=170}
end
end
end
return s
end
-- generic conifers
loud_walking.schematics.conifer_trees = {}
leaves = {"default:pine_needles", "loud_walking:pine_needles2", "loud_walking:pine_needles3", "loud_walking:pine_needles4"}
for i = 1,#leaves do
local max_r = 4
for r = 2,max_r do
local schem = loud_walking.generate_conifer_schematic(2, r, "default:pine_tree", leaves[i])
loud_walking.schematics.conifer_trees[#loud_walking.schematics.conifer_trees+1] = schem
--minetest.register_decoration({
-- deco_type = "schematic",
-- sidelen = 80,
-- place_on = {"default:dirt_with_snow", "default:dirt_with_grass"},
-- fill_ratio = (max_r-r+1)/500,
-- biomes = {"coniferous_forest", "taiga",},
-- schematic = schem,
-- flags = "place_center_x, place_center_z",
-- y_min = 2,
-- rotation = "random",
--})
end
end
if false then
-- generic conifers
loud_walking.schematics.conifer_trees = {}
leaves = {"default:pine_needles", "loud_walking:pine_needles2", "loud_walking:pine_needles3", "loud_walking:pine_needles4"}
for i = 1,#leaves do
local schem = loud_walking.generate_default_conifer_schematic("default:pine_tree", leaves[i])
loud_walking.schematics.conifer_trees[#loud_walking.schematics.conifer_trees+1] = schem
minetest.register_decoration({
deco_type = "schematic",
sidelen = 80,
place_on = {"default:dirt_with_snow", "default:dirt_with_grass"},
fill_ratio = 6/500,
biomes = {"coniferous_forest", "taiga",},
schematic = schem,
flags = "place_center_x, place_center_z",
y_min = 2,
rotation = "random",
})
end
end
-- Place the schematic when a sapling grows.
function default.grow_new_pine_tree(pos, bad)
local schem = loud_walking.schematics.conifer_trees[math.random(1,#loud_walking.schematics.conifer_trees)]
local adj = {x = pos.x - math.floor(schem.size.x / 2),
y = pos.y - 1,
z = pos.z - math.floor(schem.size.z / 2)}
minetest.place_schematic(adj, schem, 'random', nil, true)
end

164
deco_deciduous.lua Normal file
View File

@ -0,0 +1,164 @@
---------------------
-- Deciduous Trees --
---------------------
-- Make some leaves of different colors (but the same properties).
local newnode = loud_walking.clone_node("default:leaves")
if loud_walking.noleafdecay then
newnode.groups.leafdecay = 0
end
newnode.tiles = {"default_leaves.png^[colorize:#FF0000:20"}
minetest.register_node("loud_walking:leaves2", newnode)
newnode.tiles = {"default_leaves.png^[colorize:#FFFF00:20"}
minetest.register_node("loud_walking:leaves3", newnode)
newnode.tiles = {"default_leaves.png^[colorize:#00FFFF:20"}
minetest.register_node("loud_walking:leaves4", newnode)
newnode.tiles = {"default_leaves.png^[colorize:#00FF00:20"}
minetest.register_node("loud_walking:leaves5", newnode)
if loud_walking.glow then
minetest.register_node("loud_walking:tree_glowing_moss", {
description = "Tree with glowing moss",
tiles = {"default_tree_top.png", "default_tree_top.png", "default_tree.png^trunks_moss.png"},
paramtype2 = "facedir",
is_ground_content = false,
light_source = 4,
drop = 'default:tree',
groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2},
sounds = default.node_sound_wood_defaults(),
on_place = minetest.rotate_node
})
end
-- create a schematic for a spherical tree.
function loud_walking.generate_tree_schematic(trunk_height, radii, trunk, leaf, fruit, limbs)
-- trunk_height refers to the amount of trunk visible below any leaves.
local height = trunk_height + radii.y * 2 + 2
local width = 2 * radii.z + 1
local trunk_top = height-radii.y-1
local s = loud_walking.schematic_array(width, height, width)
-- the main trunk
for y = 1,trunk_top do
local i = radii.z*width*height + y*width + radii.x + 1
if trunk == "default:tree" and loud_walking.glow and math.random(1,10) == 1 then
s.data[i].name = "loud_walking:tree_glowing_moss"
else
s.data[i].name = trunk
end
s.data[i].param1 = 255
s.data[i].force_place = false
end
-- some leaves for free
loud_walking.generate_leaves(s, leaf, {x=0, y=trunk_top, z=0}, radii.x, fruit)
-- Specify a table of limb positions...
if radii.x > 3 and limbs then
for _, p in pairs(limbs) do
local i = (p.z+radii.z)*width*height + p.y*width + (p.x+radii.x) + 1
s.data[i].name = trunk
s.data[i].param1 = 255
s.data[i].force_place = false
loud_walking.generate_leaves(s, leaf, p, radii.x, fruit, true)
end
-- or just do it randomly.
elseif radii.x > 3 then
for z = -radii.z,radii.z do
for y = -radii.y,radii.y do
for x = -radii.x,radii.x do
-- a smaller spheroid inside the radii
if x^2/(radii.x-3)^2 + y^2/(radii.y-3)^2 + z^2/(radii.z-3)^2 <= 1 then
if math.random(1,6) == 1 then
local i = (z+radii.z)*width*height + (y+trunk_top)*width + (x+radii.x) + 1
s.data[i].name = trunk
s.data[i].param1 = 255
s.data[i].force_place = false
loud_walking.generate_leaves(s, leaf, {x=x, y=trunk_top+y, z=z}, radii.x, fruit, true)
end
end
end
end
end
end
return s
end
-- Create a spheroid of leaves.
function loud_walking.generate_leaves(s, leaf, pos, radius, fruit, adjust)
local height = s.size.y
local width = s.size.x
local rx = math.floor(s.size.x / 2)
local rz = math.floor(s.size.z / 2)
local r1 = math.min(3, radius) -- leaf decay radius
local probs = {255,200,150,100,75}
for z = -r1,r1 do
for y = -r1,r1 do
for x = -r1,r1 do
if x+pos.x >= -rx and x+pos.x <= rx and y+pos.y >= 0 and y+pos.y < height and z+pos.z >= -rz and z+pos.z <= rz then
local i = (z+pos.z+rz)*width*height + (y+pos.y)*width + (x+pos.x+rx) + 1
local dist1 = math.sqrt(x^2 + y^2 + z^2)
local dist2 = math.sqrt((x+pos.x)^2 + (z+pos.z)^2)
if dist1 <= r1 then
local newprob = probs[math.max(1, math.ceil(dist1))]
if s.data[i].name == "air" then
if fruit and (rx < 3 or dist2 / rx > 0.5) and math.random(1,10) == 1 then
s.data[i].name = fruit
s.data[i].param1 = 127
else
s.data[i].name = leaf
s.data[i].param1 = newprob
end
elseif adjust and s.data[i].name == leaf then
s.data[i].param1 = math.max(s.data[i].param1, newprob)
end
end
end
end
end
end
end
-- generic deciduous trees
loud_walking.schematics.deciduous_trees = {}
local leaves = {"default:leaves", "loud_walking:leaves2", "loud_walking:leaves3", "loud_walking:leaves4", "loud_walking:leaves5"}
for i = 1,#leaves do
local max_r = 6
local fruit = nil
if i == 1 then
fruit = "default:apple"
end
for r = 3,max_r do
local schem = loud_walking.generate_tree_schematic(2, {x=r, y=r, z=r}, "default:tree", leaves[i], fruit)
loud_walking.schematics.deciduous_trees[#loud_walking.schematics.deciduous_trees+1] = schem
--minetest.register_decoration({
-- deco_type = "schematic",
-- sidelen = 80,
-- place_on = {"default:dirt_with_grass", "default:dirt_with_dry_grass"},
-- y_min = 4,
-- fill_ratio = (max_r-r+1)/1700,
-- biomes = {"deciduous_forest",},
-- schematic = schem,
-- flags = "place_center_x, place_center_z",
-- rotation = "random",
--})
end
end
-- Place the schematic when a sapling grows.
function default.grow_new_apple_tree(pos, bad)
local schem = loud_walking.schematics.deciduous_trees[math.random(1,#loud_walking.schematics.deciduous_trees)]
local adj = {x = pos.x - math.floor(schem.size.x / 2),
y = pos.y - 1,
z = pos.z - math.floor(schem.size.z / 2)}
minetest.place_schematic(adj, schem, 'random', nil, true)
end

128
deco_jungle.lua Normal file
View File

@ -0,0 +1,128 @@
------------------
-- Jungle Trees --
------------------
-- Create different colored leaves with the same properties.
newnode = loud_walking.clone_node("default:jungleleaves")
newnode.tiles = {"default_jungleleaves.png^[colorize:#FF0000:10"}
minetest.register_node("loud_walking:jungleleaves2", newnode)
newnode.tiles = {"default_jungleleaves.png^[colorize:#FFFF00:30"}
minetest.register_node("loud_walking:jungleleaves3", newnode)
-- Create a schematic for a jungle tree.
function loud_walking.generate_jungle_tree_schematic(trunk_height, trunk, leaf)
local height = trunk_height * 2 + 1
local radius = 6
local width = 2 * radius + 1
local trunk_top = height - 4
local s = loud_walking.schematic_array(width, height, width)
-- roots, trunk, and extra leaves
for z = -1,1 do
for y = 1,trunk_top do
for x = -1,1 do
local i = (z+radius)*width*height + y*width + (x+radius) + 1
if x == 0 and z == 0 then
s.data[i].name = trunk
s.data[i].param1 = 255
s.data[i].force_place = true
elseif (x == 0 or z == 0) and y < 3 then
s.data[i].name = trunk
s.data[i].param1 = 255
s.data[i].force_place = true
elseif y > 3 then
s.data[i].name = leaf
s.data[i].param1 = 50
end
end
end
end
-- canopies
for y = 1,trunk_top+2 do
if y > trunk_height and (y == trunk_top or math.random(1,height - y) == 1) then
local x, z = 0, 0
while x == 0 and z == 0 do
x = math.random(-1,1) * 2
z = math.random(-1,1) * 2
end
for j = -1,1,2 do
local i = (j*z + radius)*width*height + y*width + (j*x + radius) + 1
s.data[i].name = trunk
s.data[i].param1 = 255
s.data[i].force_place = true
loud_walking.generate_canopy(s, leaf, {x=j*x, y=y, z=j*z})
end
end
end
return s
end
-- Create a canopy of leaves.
function loud_walking.generate_canopy(s, leaf, pos)
local height = s.size.y
local width = s.size.x
local rx = math.floor(s.size.x / 2)
local rz = math.floor(s.size.z / 2)
local r1 = 4 -- leaf decay radius
local probs = {255,200,150,100,75}
for z = -r1,r1 do
for y = 0,1 do
for x = -r1,r1 do
if x+pos.x >= -rx and x+pos.x <= rx and y+pos.y >= 0 and y+pos.y < height and z+pos.z >= -rz and z+pos.z <= rz then
local i = (z+pos.z+rz)*width*height + (y+pos.y)*width + (x+pos.x+rx) + 1
local dist1 = math.sqrt(x^2 + y^2 + z^2)
local dist2 = math.sqrt((x+pos.x)^2 + (z+pos.z)^2)
if dist1 <= r1 then
local newprob = probs[math.max(1, math.ceil(dist1))]
if s.data[i].name == "air" then
s.data[i].name = leaf
s.data[i].param1 = newprob
elseif s.data[i].name == leaf then
s.data[i].param1 = math.max(s.data[i].param1, newprob)
end
end
end
end
end
end
end
-- generic jungle trees
loud_walking.schematics.jungle_trees = {}
leaves = {"default:jungleleaves", "loud_walking:jungleleaves2", "loud_walking:jungleleaves3"}
for i = 1,#leaves do
local max_h = 7
for h = 5,max_h do
local schem = loud_walking.generate_jungle_tree_schematic(h*2, "default:jungletree", leaves[i])
loud_walking.schematics.jungle_trees[#loud_walking.schematics.jungle_trees+1] = schem
--minetest.register_decoration({
-- deco_type = "schematic",
-- sidelen = 80,
-- place_on = {"default:dirt_with_grass", "default:dirt"},
-- fill_ratio = (max_h-h+1)/1200,
-- biomes = {"rainforest", "rainforest_swamp",},
-- schematic = schem,
-- flags = "place_center_x, place_center_z",
-- y_min = 0,
-- rotation = "random",
--})
end
end
-- Place the schematic when a sapling grows.
function default.grow_new_jungle_tree(pos, bad)
local schem = loud_walking.schematics.jungle_trees[math.random(1,#loud_walking.schematics.jungle_trees)]
local adj = {x = pos.x - math.floor(schem.size.x / 2),
y = pos.y - 1,
z = pos.z - math.floor(schem.size.z / 2)}
minetest.place_schematic(adj, schem, 'random', nil, true)
end

14
deco_trees.lua Normal file
View File

@ -0,0 +1,14 @@
-----------
-- Trees --
-----------
-- Change leafdecay ratings
minetest.add_group("default:leaves", {leafdecay = 4})
minetest.add_group("default:jungleleaves", {leafdecay = 4})
minetest.add_group("default:pine_needles", {leafdecay = 5})
-- tree creation code
dofile(loud_walking.path.."/deco_deciduous.lua")
dofile(loud_walking.path.."/deco_conifer.lua")
dofile(loud_walking.path.."/deco_jungle.lua")

1
depends.txt Normal file
View File

@ -0,0 +1 @@
default

84
init.lua Normal file
View File

@ -0,0 +1,84 @@
-- Check for necessary mod functions and abort if they aren't available.
if not minetest.get_biome_id then
minetest.log()
minetest.log("* Not loading Cityscape *")
minetest.log("Cityscape requires mod functions which are")
minetest.log(" not exposed by your Minetest build.")
minetest.log()
return
end
loud_walking = {}
loud_walking.version = "1.0"
loud_walking.path = minetest.get_modpath(minetest.get_current_modname())
loud_walking.first_flag = 0
minetest.register_on_mapgen_init(function(mgparams)
minetest.set_mapgen_params({mgname="singlenode", flags="nolight"})
end)
if default then
if default.register_ores then
default.register_ores()
end
if default.register_blobs then
default.register_blobs()
end
--if default.register_biomes then
-- default.register_biomes()
--end
--if default.register_decorations then
-- default.register_decorations()
--end
end
-- Modify a node to add a group
function minetest.add_group(node, groups)
local def = minetest.registered_items[node]
if not def then
return false
end
local def_groups = def.groups or {}
for group, value in pairs(groups) do
if value ~= 0 then
def_groups[group] = value
else
def_groups[group] = nil
end
end
minetest.override_item(node, {groups = def_groups})
return true
end
function loud_walking.clone_node(name)
local node = minetest.registered_nodes[name]
local node2 = table.copy(node)
return node2
end
function loud_walking.node(name)
if not loud_walking.node_cache then
loud_walking.node_cache = {}
end
if not loud_walking.node_cache[name] then
loud_walking.node_cache[name] = minetest.get_content_id(name)
if name ~= "ignore" and loud_walking.node_cache[name] == 127 then
print("*** Failure to find node: "..name)
end
end
return loud_walking.node_cache[name]
end
dofile(loud_walking.path .. "/nodes.lua")
dofile(loud_walking.path .. "/deco.lua")
dofile(loud_walking.path .. "/mapgen.lua")
minetest.register_on_newplayer(loud_walking.respawn)
minetest.register_on_respawnplayer(loud_walking.respawn)
minetest.register_on_generated(loud_walking.generate)

309
mapgen.lua Normal file
View File

@ -0,0 +1,309 @@
local node = loud_walking.node
local data = {}
local p2data = {} -- vm rotation data buffer
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,
scale = 20, seed = 8829, spread = {x = 40, y = 40, z = 40},
octaves = 6, persist = 0.4, lacunarity = 2}
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_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)
local yslice = {}
if schem.yslice_prob then
for _, ys in pairs(schem.yslice_prob) do
yslice[ys.ypos] = ys.prob
end
end
if center then
pos.x = pos.x - math.floor(schem.size.x / 2)
pos.z = pos.z - math.floor(schem.size.z / 2)
end
for z = 0, schem.size.z - 1 do
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)
end
local param2 = schem.data[isch].param2 or 0
p2data[ivm] = param2
end
ivm = ivm + a.ystride
isch = isch + schem.size.x
end
end
end
end
local function is_pod(x, y, z)
local min_x = math.floor((x + 32) / csize.x)
local min_y = math.floor((y + 32) / csize.y)
local min_z = math.floor((z + 32) / csize.z)
if min_x % 2 == 0 and min_y % 2 == 0 and min_z % 2 == 0 then
return true
end
--if min_x % 2 == 1 and min_y % 4 == 0 and min_z % 2 == 1 then
-- return true
--elseif min_x % 2 == 0 and min_y % 4 == 2 and min_z % 2 == 0 then
-- return true
--end
return false
end
local function connection(x, y, z)
local min_x = math.floor((x + 32) / csize.x)
local min_y = math.floor((y + 32) / csize.y)
local min_z = math.floor((z + 32) / csize.z)
--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 ct = min_x % 2 + min_y % 2 + min_z % 2
local r = min_x % 2 + 2 * (min_y % 2) + 4 * (min_z % 2)
if ct == 1 then
return r
end
return nil
end
local function get_height(dx, dz, biome, 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
index = dz * csize.x + dx + 1
terr = math.floor(terrain[index] + 0.5)
else
terr = math.floor(terrain[index] + 0.5)
end
local d = 38 - math.abs(math.abs(dx - 39.5) - math.abs(dz - 39.5))
if math.abs(terr) > d then
if terr > 0 then
terr = math.floor(d + 0.5)
else
terr = math.floor(0.5 - d)
end
end
return terr
end
local function get_biome(px, pz)
return "deciduous_forest"
end
function loud_walking.generate(p_minp, p_maxp, seed)
minp, maxp = p_minp, p_maxp
vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
vm:get_data(data)
vm:set_lighting({day = 15, night = 0}, minp, maxp)
lightmap = vm:get_light_data()
--p2data = vm:get_param2_data()
a = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
csize = vector.add(vector.subtract(maxp, minp), 1)
local write = false
-- 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...")
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]
terrain = minetest.get_perlin_map(terrain_noise, csize):get2dMap_flat(minp)
cave = minetest.get_perlin_map(cave_noise, csize):get3dMap_flat(minp)
local pod = is_pod(minp.x, minp.y, minp.z)
local connection = connection(minp.x, minp.y, minp.z)
local index = 0
local index3d = 0
for z = minp.z, maxp.z do
local dz = z - minp.z
for x = minp.x, maxp.x do
index = index + 1
local dx = x - minp.x
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 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
data[ivm] = node("air")
--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
data[ivm] = node("loud_walking:scrith")
lightmap[ivm] = 0
else
data[ivm] = node("default:glass")
end
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
data[ivm] = node("air")
else
if dy < terr + 40 then
data[ivm] = node("loud_walking:scrith")
lightmap[ivm] = 0
else
data[ivm] = node("default:glass")
end
write = true
end
in_cave = false
elseif dy > terr + 40 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")
else
data[ivm] = node("air")
end
in_cave = true
lightmap[ivm] = 0
elseif dy > terr + 39 then
data[ivm] = top
lightmap[ivm] = 0
in_cave = false
write = true
elseif dy > terr + 37 then
data[ivm] = node("default:dirt")
lightmap[ivm] = 0
in_cave = false
write = true
else
data[ivm] = node("default: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")
lightmap[ivm] = 0
write = true
end
ivm = ivm + a.ystride
index3d = index3d + csize.x
end
end
end
if pod then
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 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)
end
end
end
end
end
end
if write then
vm:set_data(data)
minetest.generate_ores(vm, minp, maxp)
minetest.generate_decorations(vm, minp, maxp)
--vm:set_param2_data(p2data)
--vm:set_lighting({day = 15, night = 0})
vm:set_light_data(lightmap)
vm:calc_lighting(minp, maxp, false)
vm:update_liquids()
vm:write_to_map()
end
vm, a, heightmap, biomemap = nil, nil, nil, nil
end
function loud_walking.respawn(player)
local success = false
while not success do
local px = math.random(-10, 10) * 2
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 pos = {x=x,y=y,z=z}
local node = minetest.get_node(pos)
if node.name ~= "air" then
player:setpos(pos)
success = true
end
--print(node.name)
end
end

1
mod.conf Normal file
View File

@ -0,0 +1 @@
name = loud_walking

22
nodes.lua Normal file
View File

@ -0,0 +1,22 @@
minetest.register_node("loud_walking:plate_glass", {
description = "Plate Glass",
drawtype = "glasslike",
paramtype = "light",
sunlight_propagates = true,
tiles = {"loud_walking_plate_glass.png"},
light_source = 8,
use_texture_alpha = true,
is_ground_content = false,
groups = {cracky = 3, level=1},
sounds = default.node_sound_stone_defaults(),
})
minetest.register_node("loud_walking:scrith", {
description = "Scrith",
paramtype = "light",
tiles = {"default_obsidian.png"},
use_texture_alpha = true,
is_ground_content = false,
groups = {},
sounds = default.node_sound_stone_defaults(),
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

BIN
textures/screenshot02.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB