1
0
mirror of git://repo.or.cz/rocks.git synced 2024-09-28 23:30:39 +02:00

Split source code to init mapgen and register.

This commit is contained in:
Tomáš Brada 2014-12-29 20:16:14 +01:00
parent 3c3248108c
commit 0d5facc4c5
3 changed files with 161 additions and 160 deletions

163
init.lua
View File

@ -8,11 +8,9 @@ if (minetest.get_modpath("intllib")) then
S = function ( s ) return s end
end
rocks = {}
local modpath=minetest.get_modpath(minetest.get_current_modname()))
rocks.layers = {}
rocks.veins = {}
rocks.ores = {}
dofile(modpath.."/register.lua")
rocks.noiseparams_layers = {
offset = 0,
@ -22,60 +20,6 @@ rocks.noiseparams_layers = {
persist = 0.63
}
rocks.register_layer=function(name,params,rock)
assert(name)
assert(params)
assert(params.gain)
assert(params.height)
local maxheight
for ln,ld in pairs(rocks.layers) do
if (ld.height<params.height)and ((not ld.maxheight) or (ld.maxheight>params.height)) then ld.maxheight=params.height end
if (ld.height>params.height)and((not maxheight) or (maxheight>ld.height)) then maxheight=ld.height end
end
rocks.layers[name]= {
gain=params.gain,
height=params.height,
maxheight=maxheight,
limit=params.limit,
seed=params.seed,
rock={ block=rock },
veins={}
}
print("[rocks] layer "..name)
end
rocks.register_vein=function(name,params)
assert(name)
assert(params)
assert(not rocks.veins[name])
rocks.veins[name]={
np={
offset=0, scale=1, octaves=1, presist=0.8,
spread=params.spread, seed=params.seed
},
treshold=params.treshold,
hmin=params.hmin, hmax=params.hmax,
layers=params.layers,
ores={}
}
for ln,ld in pairs(rocks.layers) do
ld.veins[name]=rocks.veins[name]
end
print("[rocks] vein "..name)
end
rocks.register_ore=function( vein, node, params )
-- params= {treshold=0, chance=1 }
ore={ node=node }
if params.treshold and (params.treshold>rocks.veins[vein].treshold) then
ore.treshold=params.treshold
end
if params.chance and (params.chance<1) then
ore.chance=params.chance
end
table.insert(rocks.veins[vein].ores, ore)
print("[rocks] ore "..node.." in "..vein.." chance="..(ore.chance or "1").." treshold="..(ore.treshold or rocks.veins[vein].treshold))
end
--
-- test layer
@ -115,108 +59,7 @@ rocks.register_ore( "testvein1", "default:lava_source", {treshold=0.8, chance=1
-- 20% wood, lava in center, dirt the rest
-- ore with smallest chance and highest treshold is selected
for ln,ld in pairs(rocks.layers) do
-- print("[rocks] debug: "..ln..": "..minetest.serialize(ld))
end
--
-- layer generator
--
local function mknoises(layers,minp,maxp)
local nm={}
for ln,ld in pairs(rocks.layers) do
if (ld.height-ld.gain<maxp.y)and((not ld.maxheight)or(ld.maxheight+ld.gain>minp.y)) then
local np=rocks.noiseparams_layers
np.seed=ld.seed
local side_length = maxp.x - minp.x + 1
ld.nmap=minetest.get_perlin_map(np,{x=side_length, y=side_length, z=side_length}):get2dMap({x=minp.x, y=minp.z})
table.insert(nm,ld)
end
end
return nm
end
local function mkheightmap(layers,x,z,minp,maxp)
local hm={}
for ln,ld in pairs(layers) do
local noise=ld.nmap[z-minp.z+1][x-minp.x+1]
if math.abs(noise)<ld.limit then
ld.nh = (noise*ld.gain)+ld.height
-- if (ld.nh<maxy)and(ld.nh>miny)
table.insert(hm,ld)
end
end
return hm
end
local stonectx=nil
minetest.register_on_generated(function(minp, maxp, seed)
if not stonectx then stonectx= minetest.get_content_id("default:stone") end
-- noise values range (-1;+1) (1 octave)
-- 3 octaves it is like 1.7 max
-- 4 octaves with 0.8 presist = 2.125 max !!
-- if ...
local timebefore=os.clock();
local manipulator, emin, emax = minetest.get_mapgen_object("voxelmanip")
local nodes = manipulator:get_data()
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
-- initialize noises and sort out unused layers
local availlayers=mknoises(rocks.layers,minp,maxp)
--
for x=minp.x,maxp.x,1 do
for z=minp.z,maxp.z,1 do
--* initialize layers hmap
local layers=mkheightmap(availlayers,x,z,minp,maxp)
if (minp.x>0)and(minp.x<200) then layers=nil end --< debug
if layers then for y=minp.y,maxp.y,1 do
--* select layer
local layer
for ln,ld in pairs(layers) do
if (ld)and
(ld.nh<y)and
((not layer)or(ld.height>layer.height))
then
layer=ld
end
end
--* select vein
local vein=nil
if layer then
-- vein=todo... iterate vein's noises and select one above it's treshold
end
--* select rock
local rock=nil
if vein then
rock=nil -- todo... --> based on pseudorandom, no pattern, just random
elseif layer then
rock=layer.rock -- not in vein > select base rock
end
--* place rocks
if rock then
if not rock.ctx then
rock.ctx=minetest.get_content_id(rock.block)
end
local p_pos = area:index(x, y, z)
nodes[p_pos] = rock.ctx
end
end end
end
end
manipulator:set_data(nodes)
-- manipulator:calc_lighting()
-- manipulator:update_liquids()
manipulator:write_to_map()
print("[rocks] gen "..os.clock()-timebefore)
end)
dofile(modpath.."/mapgen.lua")
--
--Bedrock

96
mapgen.lua Normal file
View File

@ -0,0 +1,96 @@
--
-- layer generator
--
local function mknoises(layers,minp,maxp)
local nm={}
for ln,ld in pairs(rocks.layers) do
if (ld.height-ld.gain<maxp.y)and((not ld.maxheight)or(ld.maxheight+ld.gain>minp.y)) then
local np=rocks.noiseparams_layers
np.seed=ld.seed
local side_length = maxp.x - minp.x + 1
ld.nmap=minetest.get_perlin_map(np,{x=side_length, y=side_length, z=side_length}):get2dMap({x=minp.x, y=minp.z})
table.insert(nm,ld)
end
end
return nm
end
local function mkheightmap(layers,x,z,minp,maxp)
local hm={}
for ln,ld in pairs(layers) do
local noise=ld.nmap[z-minp.z+1][x-minp.x+1]
if math.abs(noise)<ld.limit then
ld.nh = (noise*ld.gain)+ld.height
-- if (ld.nh<maxy)and(ld.nh>miny)
table.insert(hm,ld)
end
end
return hm
end
local stonectx=nil
minetest.register_on_generated(function(minp, maxp, seed)
if not stonectx then stonectx= minetest.get_content_id("default:stone") end
-- noise values range (-1;+1) (1 octave)
-- 3 octaves it is like 1.7 max
-- 4 octaves with 0.8 presist = 2.125 max !!
-- if ...
local timebefore=os.clock();
local manipulator, emin, emax = minetest.get_mapgen_object("voxelmanip")
local nodes = manipulator:get_data()
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
-- initialize noises and sort out unused layers
local availlayers=mknoises(rocks.layers,minp,maxp)
--
for x=minp.x,maxp.x,1 do
for z=minp.z,maxp.z,1 do
--* initialize layers hmap
local layers=mkheightmap(availlayers,x,z,minp,maxp)
if (minp.x>0)and(minp.x<200) then layers=nil end --< debug
if layers then for y=minp.y,maxp.y,1 do
--* select layer
local layer
for ln,ld in pairs(layers) do
if (ld)and
(ld.nh<y)and
((not layer)or(ld.height>layer.height))
then
layer=ld
end
end
--* select vein
local vein=nil
if layer then
-- vein=todo... iterate vein's noises and select one above it's treshold
end
--* select rock
local rock=nil
if vein then
rock=nil -- todo... --> based on pseudorandom, no pattern, just random
elseif layer then
rock=layer.rock -- not in vein > select base rock
end
--* place rocks
if rock then
if not rock.ctx then
rock.ctx=minetest.get_content_id(rock.block)
end
local p_pos = area:index(x, y, z)
nodes[p_pos] = rock.ctx
end
end end
end
end
manipulator:set_data(nodes)
-- manipulator:calc_lighting()
-- manipulator:update_liquids()
manipulator:write_to_map()
print("[rocks] gen "..os.clock()-timebefore)
end)

62
register.lua Normal file
View File

@ -0,0 +1,62 @@
-- global table and register_* functions
rocks = {}
rocks.layers = {}
rocks.veins = {}
rocks.ores = {}
rocks.register_layer=function(name,params,rock)
assert(name)
assert(params)
assert(params.gain)
assert(params.height)
local maxheight
for ln,ld in pairs(rocks.layers) do
if (ld.height<params.height)and ((not ld.maxheight) or (ld.maxheight>params.height)) then ld.maxheight=params.height end
if (ld.height>params.height)and((not maxheight) or (maxheight>ld.height)) then maxheight=ld.height end
end
rocks.layers[name]= {
gain=params.gain,
height=params.height,
maxheight=maxheight,
limit=params.limit,
seed=params.seed,
rock={ block=rock },
veins={}
}
print("[rocks] layer "..name)
end
rocks.register_vein=function(name,params)
assert(name)
assert(params)
assert(not rocks.veins[name])
rocks.veins[name]={
np={
offset=0, scale=1, octaves=1, presist=0.8,
spread=params.spread, seed=params.seed
},
treshold=params.treshold,
hmin=params.hmin, hmax=params.hmax,
layers=params.layers,
ores={}
}
for ln,ld in pairs(rocks.layers) do
ld.veins[name]=rocks.veins[name]
end
print("[rocks] vein "..name)
end
rocks.register_ore=function( vein, node, params )
-- params= {treshold=0, chance=1 }
ore={ node=node }
if params.treshold and (params.treshold>rocks.veins[vein].treshold) then
ore.treshold=params.treshold
end
if params.chance and (params.chance<1) then
ore.chance=params.chance
end
table.insert(rocks.veins[vein].ores, ore)
print("[rocks] ore "..node.." in "..vein.." chance="..(ore.chance or "1").." treshold="..(ore.treshold or rocks.veins[vein].treshold))
end