Pegmatite vein def.
[rocks.git] / mapgen.lua
blobbc036fa6f5886f594a0ead5323ed8bf1842c8800
1 --
2 -- layer generator
3 --
5 local print2=function(text)
6 minetest.log("verbose","rocks/gen/ "..text)
7 end
9 rocksl.seedseq=0
10 rocksl.GetNextSeed=function()
11 rocksl.seedseq=rocksl.seedseq+20
12 print2("seed "..rocksl.seedseq)
13 return rocksl.seedseq
14 end
16 rocksl.register_stratus=function(layer,name,param)
17 table.insert(layer.localized,{
18 primary=name,
19 spread=(param.spread or 20),
20 height=(param.height or 15),
21 treshold=(param.treshold or 0.85),
22 secondary=param.secondary,
23 seed=(rocksl.GetNextSeed()),
25 layer.stats.node[name]=0
26 end
28 rocksl.register_vein=function(col,name,param)
29 local d={
30 primary=name,
31 wherein=param.wherein,
32 miny=param.miny, maxy=param.maxy,
33 radius={ average=param.radius.average, amplitude=param.radius.amplitude, frequency=param.radius.frequency },
34 density=(param.density or 1),
35 rarity=param.rarity,
36 secondary=(param.ores or {}),
38 table.insert(col,d)
39 end
41 rocksl.layergen=function(layer, minp, maxp, seed)
42 if ( (layer.top.offset+layer.top.scale)>minp.y )
43 and ( (layer.bot.offset-layer.bot.scale)<maxp.y )
44 then
45 local stone_ctx= minetest.get_content_id("default:stone")
46 local air_ctx= minetest.get_content_id("air")
47 local dirt_ctx= minetest.get_content_id("default:dirt")
48 if layer.debugging then
49 layer.primary.ctx= air_ctx
50 else
51 layer.primary.ctx= minetest.get_content_id(layer.primary.name)
52 end
53 local timebefore=os.clock();
54 local manipulator, emin, emax = minetest.get_mapgen_object("voxelmanip")
55 local nodes = manipulator:get_data()
56 local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
57 local side_length = (maxp.x - minp.x) + 1
58 local map_lengths_xyz = {x=side_length, y=side_length, z=side_length}
59 -- noises:
60 local bottom=minetest.get_perlin_map(layer.bot,map_lengths_xyz):get2dMap_flat({x=minp.x, y=minp.z})
61 local localized={}
62 for _,loc in ipairs(layer.localized) do
63 --defaults and overrides
64 local np={ offset = 0, scale = 1, octaves = 1, persist = 0.7,
65 spread = {x=loc.spread, y=loc.height, z=loc.spread}, seed=loc.seed}
66 --get noise and content ids
67 table.insert(localized,
69 noise=minetest.get_perlin_map(np,map_lengths_xyz):get3dMap_flat(minp),
70 treshold=loc.treshold,
71 ctx= minetest.get_content_id(loc.primary),
72 ndn=loc.primary
74 end
75 local noise2d_ix = 1
76 local noise3d_ix = 1
77 print2("after noise: "..(os.clock()-timebefore))
78 for z=minp.z,maxp.z,1 do
79 for y=minp.y,maxp.y,1 do
80 for x=minp.x,maxp.x,1 do
81 local pos = area:index(x, y, z)
82 if (y>bottom[noise2d_ix]) and (y<layer.top.offset)
83 and ( (nodes[pos]==stone_ctx) or (nodes[pos]==dirt_ctx) )
84 then
85 layer.stats.totalnodes=layer.stats.totalnodes+1
86 if nodes[pos]==stone_ctx then nodes[pos] = layer.primary.ctx end
87 for k,loc in pairs(localized) do
88 if ( loc.noise[noise3d_ix] > loc.treshold) then
89 nodes[pos]=loc.ctx
90 layer.stats.node[loc.ndn]=layer.stats.node[loc.ndn]+1
91 break
92 end
93 end
94 end
95 noise2d_ix=noise2d_ix+1
96 noise3d_ix=noise3d_ix+1
97 end
98 noise2d_ix=noise2d_ix-side_length
99 end
100 noise2d_ix=noise2d_ix+side_length
102 print2("after loop: "..(os.clock()-timebefore))
103 manipulator:set_data(nodes)
104 --manipulator:calc_lighting()
105 --manipulator:update_liquids()
106 if layer.debugging then
107 manipulator:set_lighting({day=15,night=15})
109 manipulator:write_to_map()
110 print2("after commit: "..(os.clock()-timebefore))
111 layer.stats.count=layer.stats.count+1
112 layer.stats.total=layer.stats.total+(os.clock()-timebefore)
113 layer.stats.side=side_length
117 local ignore_wherein=nil
119 rocksl.veingen=function(veins,minp,maxp,seed)
120 local side_length=(maxp.y-minp.y)
121 local random=PseudoRandom(seed-79)
122 local timebefore=os.clock();
123 local manipulator, emin, emax = minetest.get_mapgen_object("voxelmanip")
124 local nodes = manipulator:get_data()
125 local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
126 local did_generate=nil
127 for _,vein in ipairs(veins) do
128 if (minp.y<vein.maxy) and (maxp.y>vein.maxy) then
129 local vr2=vein.radius.average^2
130 local vrm=vein.radius.average+vein.radius.amplitude
131 local noise_map=minetest.get_perlin_map(
133 seed=-79,
134 scale=vein.radius.amplitude,
135 offset=0, octaves=1, persist=0.7,
136 spread={x=vein.radius.frequency, y=vein.radius.frequency, z=vein.radius.frequency}
137 },{x=(vrm*2)+1, y=(vrm*2)+1, z=(vrm*2)+1}
139 local iterations_count= (vein.rarity*side_length)^3
140 -- Resolve node names to id's
141 iterations_count=iterations_count+(random:next(0,100)/100)
142 local primary_ctx=minetest.get_content_id(vein.primary)
143 for _,sec in pairs(vein.secondary) do sec.ctx=minetest.get_content_id(sec.ore) end
144 --old:local wherein_ctx=minetest.get_content_id(vein.wherein)
145 local wherein_set={}
146 for _,wi in pairs(vein.wherein) do wherein_set[minetest.get_content_id(wi)]=true end
147 --print("vein "..vein.primary.." ic="..iterations_count.." p="..primary_ctx)
148 for iteration=1, iterations_count do
149 local x0=minp.x+ random:next(0,side_length)
150 local y0=minp.y+ random:next(0,side_length)
151 local z0=minp.z+ random:next(0,side_length)
152 local noise=noise_map:get3dMap_flat({x=x0-vrm, y=y0-vrm, z=z0-vrm})
153 local noise_ix=1
154 local posi = area:index(x0, y0, z0)
155 if ignore_wherein or wherein_set[nodes[posi]] then
156 print("[rocks] vein "..vein.primary.." @ "..x0..","..y0..","..z0.." vrm="..vrm)
157 did_generate=1
158 for x=-vrm, vrm do
159 for y=-vrm, vrm do
160 for z=-vrm, vrm do
161 local posc = {x=x+x0,y=y+y0,z=z+z0}
162 posi = area:index(posc.x, posc.y, posc.z)
163 local nv=noise[noise_ix]
164 if (ignore_wherein or wherein_set[nodes[posi]]) and (((x^2)+(y^2)+(z^2))<((vein.radius.average+nv)^2)) then
165 nodes[posi]=primary_ctx
166 local luck=random:next(0,99)
167 for _,sec in pairs(vein.secondary) do
168 luck=luck-sec.percent
169 if luck<=0 then
170 nodes[posi]=sec.ctx
171 break
175 noise_ix=noise_ix+1
176 end end end
177 else
178 --print("vein "..vein.primary.." bad environmnent -"..minetest.get_node({x0,y0,z0}).name.."="..nodes[posi])
183 if did_generate then
184 manipulator:set_data(nodes)
185 --manipulator:calc_lighting()
186 manipulator:write_to_map()
187 print2("end veingen "..(os.clock()-timebefore))
188 else
189 --print("end veingen (nothin generated)")
193 -- ~ Tomas Brod