diff --git a/init.lua b/init.lua index ed6ad0d..2f092fa 100644 --- a/init.lua +++ b/init.lua @@ -8,7 +8,7 @@ if (minetest.get_modpath("intllib")) then S = function ( s ) return s end end -local modpath=minetest.get_modpath(minetest.get_current_modname())) +local modpath=minetest.get_modpath(minetest.get_current_modname()) dofile(modpath.."/register.lua") @@ -25,36 +25,36 @@ rocks.noiseparams_layers = { -- test layer -- -rocks.register_layer("test1",{ gain=40, height=70, limit=2, seed=1 },"rocks:black_granite") +rocks.register_layer("test1",{ gain=40, height=70, limit=2, seed=1 }, "air") --"rocks:black_granite") -- uhlie ako vrstva je kokotina. -rocks.register_layer("test3",{ gain=40, height=65, limit=2, seed=3 },"rocks:pink_granite") +rocks.register_layer("test3",{ gain=40, height=65, limit=2, seed=3 },"air") --"rocks:pink_granite") -rocks.register_layer("test4",{ gain=40, height=90, limit=2, seed=4 },"rocks:white_granite") +rocks.register_layer("test4",{ gain=40, height=90, limit=2, seed=4 },"air") --"rocks:white_granite") -- -- test vein -- rocks.register_vein("testvein1",{ - spread = {x=5, y=90, z=5}, -- tall, narrow + spread = {x=15, y=15, z=15}, -- tall, narrow -- larger values -> larger and less frequent vein - treshold=0.5, -- betveen -2 and +2, mapgen will use this or per-ore treshold if it is larger + treshold=0.8, -- betveen -2 and +2, mapgen will use this or per-ore treshold if it is larger -- 2 never generate -- 1 extremly rare -- 0 50% chance -- less than 0 = SPAM seed = 9, -- random seed - hmin=65, -- set to nil to generate everywhere - hmax=90, + hmin=5, -- set to nil to generate everywhere + hmax=100, layers={ "test3" }, -- only occur in layers }) -rocks.register_ore( "testvein1", "default:dirt" , {treshold=0, chance=1 } ) +rocks.register_ore( "testvein1", "default:glass" , {treshold=0, chance=1 } ) -- treshold=0 chance=1 ... generate everywhere rocks.register_ore( "testvein1", "default:wood" , {treshold=0, chance=0.2} ) -- chance<1 ... vein contains chance*100% of the material, evenly randomly distributed -rocks.register_ore( "testvein1", "default:lava_source", {treshold=0.8, chance=1 } ) +rocks.register_ore( "testvein1", "default:tree", {treshold=0.87, chance=1 } ) -- treshold>0 ... generate in the center, larger value -> narrower -- 20% wood, lava in center, dirt the rest -- ore with smallest chance and highest treshold is selected diff --git a/mapgen.lua b/mapgen.lua index 6258218..83e6ac3 100644 --- a/mapgen.lua +++ b/mapgen.lua @@ -2,14 +2,21 @@ -- layer generator -- -local function mknoises(layers,minp,maxp) +local function mknoises(layers,minp,maxp,seed) local nm={} for ln,ld in pairs(rocks.layers) do if (ld.height-ld.gainminp.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}) + local side_length = (maxp.x - minp.x) + 1 + local map_lengths_xyz = {x=side_length, y=side_length, z=side_length} + ld.nmap=minetest.get_perlin_map(np,map_lengths_xyz):get2dMap({x=minp.x, y=minp.z}) + local vidx=1 + for vn,vd in pairs(ld.veins) do + -- todo check if hmax,hmin is in current block + vd.onmap=minetest.get_perlin_map(vd.np,map_lengths_xyz):get3dMap_flat(minp) + vidx=vidx+1 + end table.insert(nm,ld) end end @@ -32,17 +39,17 @@ end local stonectx=nil minetest.register_on_generated(function(minp, maxp, seed) - if not stonectx then stonectx= minetest.get_content_id("default:stone") end + if not stone_ctx then stone_ctx= minetest.get_content_id("air") 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) + local availlayers=mknoises(rocks.layers,minp,maxp,seed) + local perlin_index = 1 -- for x=minp.x,maxp.x,1 do for z=minp.z,maxp.z,1 do @@ -51,6 +58,8 @@ minetest.register_on_generated(function(minp, maxp, seed) if (minp.x>0)and(minp.x<200) then layers=nil end --< debug if layers then for y=minp.y,maxp.y,1 do + local p_pos = area:index(x, y, z) + --* select layer local layer for ln,ld in pairs(layers) do @@ -65,26 +74,47 @@ minetest.register_on_generated(function(minp, maxp, seed) --* select vein local vein=nil if layer then - -- vein=todo... iterate vein's noises and select one above it's treshold + for vn,vd in pairs(layer.veins) do + if ((not vd.hmin) or y>vd.hmin) + and((not vd.hmax) or yvd.treshold) + then + vein=vd + end + end + --if vein then print("[rocks] generate vein") end 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 + for von,vod in pairs(vein.ores) do + if not vod.pr then vod.pr=PseudoRandom(seed+von) end + if (vein.onmap[perlin_index]>vod.treshold) + and(vod.pr:next(0,1)<=vod.chance) --< todo add pseudorandom chance + and( (not rock) or + (vod.treshold>=rock.treshold + -- or vod.chance<=rock.chance works better with this disabled + ) + ) + then + rock=vod + end + end + end + if (not rock) and layer then + rock=layer.rock -- not in vein? > select base rock end --* place rocks - if rock then + if (rock) and(nodes[p_pos]==stone_ctx) then if not rock.ctx then - rock.ctx=minetest.get_content_id(rock.block) + rock.ctx=minetest.get_content_id(rock.node) end - local p_pos = area:index(x, y, z) nodes[p_pos] = rock.ctx end - + + perlin_index =perlin_index+1 end end end end diff --git a/register.lua b/register.lua index 4144919..1dc2ab0 100644 --- a/register.lua +++ b/register.lua @@ -22,7 +22,7 @@ rocks.register_layer=function(name,params,rock) maxheight=maxheight, limit=params.limit, seed=params.seed, - rock={ block=rock }, + rock={ node=rock }, veins={} } print("[rocks] layer "..name) @@ -35,7 +35,9 @@ rocks.register_vein=function(name,params) rocks.veins[name]={ np={ offset=0, scale=1, octaves=1, presist=0.8, - spread=params.spread, seed=params.seed + spread={x=params.spread.y, y=params.spread.z, z=params.spread.x}, + -- swapped, becouse we generate by horizontal layers + seed=params.seed }, treshold=params.treshold, hmin=params.hmin, hmax=params.hmax, @@ -51,12 +53,8 @@ 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 + ore.treshold=(params.treshold or rocks.veins[vein].treshold) + ore.chance= (params.chance or 1) 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)) + print("[rocks] ore "..node.." in "..vein.." chance="..ore.chance.." treshold="..ore.treshold) end