5 local print2
=function(text
)
6 minetest
.log("verbose","rocks/gen/ "..text
)
10 rocksl
.GetNextSeed
=function()
11 rocksl
.seedseq
=rocksl
.seedseq
+20
12 print2("seed "..rocksl
.seedseq
)
16 rocksl
.register_stratus
=function(layer
,name
,param
)
17 table.insert(layer
.localized
,{
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
28 rocksl
.register_vein
=function(col
,name
,param
)
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),
36 secondary
=(param
.ores
or {}),
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
)
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
51 layer
.primary
.ctx
= minetest
.get_content_id(layer
.primary
.name
)
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
}
60 local bottom
=minetest
.get_perlin_map(layer
.bot
,map_lengths_xyz
):get2dMap_flat({x
=minp
.x
, y
=minp
.z
})
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
),
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
) )
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
90 layer
.stats
.node
[loc
.ndn
]=layer
.stats
.node
[loc
.ndn
]+1
95 noise2d_ix
=noise2d_ix
+1
96 noise3d_ix
=noise3d_ix
+1
98 noise2d_ix
=noise2d_ix
-side_length
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(
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)
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
})
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
)
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
178 --print("vein "..vein.primary.." bad environmnent -"..minetest.get_node({x0,y0,z0}).name.."="..nodes[posi])
184 manipulator
:set_data(nodes
)
185 --manipulator:calc_lighting()
186 manipulator
:write_to_map()
187 print2("end veingen "..(os
.clock()-timebefore
))
189 --print("end veingen (nothin generated)")