Experiments with layers.
[rocks.git] / rocks / gensed.lua
blob9dd67dda55beb10b8ad6ed2552ee41446a52c418
1 -- experimental sedimentary layer generator
3 local np_elv = {
4 offset = 0, octaves = 2, persist = 0.4,
5 scale = 8,
6 spread = {x=25, y=25, z=25},
7 seed = -546,
9 local np_typ1 = {
10 offset = 0, octaves = 2, persist = 0.33,
11 scale = 1,
12 spread = {x=50, y=50, z=50},
13 seed = -5500,
15 local np_typ2 = {
16 offset = 0, octaves = 2, persist = 0.33,
17 scale = 1,
18 spread = {x=70, y=70, z=70},
19 seed = -5472,
21 local np_vc = {
22 offset = 0, octaves = 2, persist = 0.33,
23 scale = 1,
24 spread = {x=100, y=100, z=100},
25 seed = 749,
27 local np_sp = {
28 offset = 0, octaves = 2, persist = 0.33,
29 scale = 1,
30 spread = {x=150, y=150, z=150},
31 seed = -1284,
34 local stats
35 stats={ total=0 }
37 rocksl.gensed = function (minp, maxp, seed, vm, area)
38 local t1 = os.clock()
39 local data = vm:get_data()
41 local chunksize = maxp.x - minp.x + 1
42 local pmapsize = {x = chunksize, y = chunksize, z = chunksize}
43 local minpxz = {x = minp.x, y = minp.z}
44 local c_stone= minetest.get_content_id("default:stone")
45 local c_dwg= c_stone
47 local sla = {
48 {min=18, sd=169},
49 {min=9, sd=324},
50 {min=0, sd=-230},
51 {min=-6, sd=850},
52 {min=-12, sd=-643},
53 {min=-18, sd=0},
55 if minp.y<(sla[#sla].min-10) then return end
56 local biomes = {
57 lava={ mod="default" },
58 nyancat={ mod="default" },
59 wood={ mod="default" },
60 gravel={ mod="default" },
61 sand={ mod="default" },
62 sandstone={ mod="default" },
63 clay={ mod="default" },
64 claystone={ mod="rocks" },
65 slate={ mod="rocks" },
66 conglomerate={ mod="rocks" },
67 mudstone={ mod="rocks" },
68 limestone={ mod="rocks" },
69 blackcoal={ mod="rocks" },
70 lignite={ mod="rocks" },
71 anthracite={ mod="rocks" },
73 for k,v in pairs(biomes) do
74 v.ctx=v.ctx or minetest.get_content_id(v.mod..":"..k)
75 if stats and (stats[k]==nil) then stats[k]=0 end
76 end
77 n_elv= minetest.get_perlin_map(np_elv, pmapsize) : get2dMap_flat(minp)
79 local generated
80 local nixz= 0
81 local nixyz= 0
82 for z=minp.z, maxp.z do for x=minp.x, maxp.x do
83 nixz= nixz+1
84 -- loop
85 local bi
86 local li
87 for y=maxp.y, minp.y, -1 do
88 nixyz=nixyz+1
89 local di=area:index(x,y,z)
90 local yn=y +n_elv[nixz]
91 if (data[di]==c_stone) and ((not bi)or(yn<sla[li].min)) then
92 -- go to deeper layer
93 if not li then li=1 end
94 while (li<=#sla)and(sla[li].min>yn) do
95 li=li+1
96 end
97 -- create noises for this layer
98 if li>#sla then break end -- break y loop if too low
99 if (not sla[li].n_tp1) then
100 local altminpxz={ x=minp.x+sla[li].sd,
101 y=minp.z-sla[li].sd}
102 sla[li].n_tp1= minetest.get_perlin_map(np_typ1, pmapsize) : get2dMap_flat(altminpxz)
103 sla[li].n_tp2= minetest.get_perlin_map(np_typ2, pmapsize) : get2dMap_flat(altminpxz)
104 sla[li].n_vc= minetest.get_perlin_map(np_vc, pmapsize) : get2dMap_flat(altminpxz)
105 sla[li].n_sp= minetest.get_perlin_map(np_sp, pmapsize) : get2dMap_flat(altminpxz)
107 -- BEGIN geome resolution
108 local vcva= math.abs(sla[li].n_vc[nixz])
109 local vcv= sla[li].n_vc[nixz]
110 local spv= sla[li].n_sp[nixz]
111 local tp=1 --=particulates, 2=biosediments, 3=chemosediments, 4=vulcanosediments
112 if sla[li].n_tp1[nixz]>0.2 then tp=2
113 if sla[li].n_tp2[nixz]>0.81 then tp=4 end
114 elseif sla[li].n_tp2[nixz]>0.76 then tp=3 end
116 if tp==1 then
117 -- particulates
118 if vcva>0.453 then
119 -- clay-(0,stone,slate)
120 if spv>0.23 then bi="slate"
121 elseif spv>-0.2 then bi="claystone"
122 else bi="clay" end
123 elseif vcva>0.4 then
124 bi="mudstone"
125 elseif vcva>0.2 then
126 -- sand-(0,stone)
127 if spv>-0.3 then bi="sandstone" else bi="sand" end
128 else
129 -- gravel/conglomerate
130 if spv>-0.34 then bi="conglomerate" else bi="gravel" end
131 -- breccia?
133 elseif tp==2 then
134 -- biosediments
135 if vcv>0.05 then
136 bi="limestone"
137 elseif vcv>-0.1 then
138 --uhlia
139 if spv>0.7 then bi="anthracite"
140 elseif spv>0 then bi="blackcoal"
141 else bi="lignite" end
142 else
143 --ine
144 bi="wood"
148 -- END geome resolution
150 if not bi then bi="nyancat" end
151 generated=true
153 if (data[di]==c_stone) then
154 data[di]=biomes[bi].ctx
155 if stats then stats.total=stats.total+1 stats[bi]=stats[bi]+1 end
158 end end
159 if generated then
160 vm:set_data(data)
161 if stats then for k,v in pairs(stats) do print("stat: "..k..": "..((v/stats.total)*100).."%") end end
162 else
163 print("no sed layer y="..minp.y)
165 minetest.log("action", "rocks/gensed/ "..math.ceil((os.clock() - t1) * 1000).." ms ")
168 minetest.register_node( "rocks:slate", {
169 description = S("Slate"),
170 tiles = { "rocks_Slate.png" },
171 is_ground_content = true, sounds = default.node_sound_dirt_defaults(),
172 groups = {cracky=3},
174 minetest.register_node( "rocks:claystone", {
175 description = S("Claystone"),
176 tiles = { "rocks_claystone.png" },
177 is_ground_content = true, sounds = default.node_sound_dirt_defaults(),
178 groups = {crumbly=1, cracky=3},
181 minetest.register_node( "rocks:conglomerate", {
182 description = S("Conglomerate"),
183 tiles = { "rocks_conglomerate.png" },
184 is_ground_content = true, sounds = default.node_sound_dirt_defaults(),
185 groups = {crumbly=3},
188 minetest.register_node( "rocks:lignite", {
189 description = S("Lignite coal"),
190 tiles = { "rocks_Mudstone.png^rocks_lignite.png" },
191 is_ground_content = true,
192 groups = {crumbly=3},
194 minetest.register_node( "rocks:blackcoal", {
195 description = S("Black coal"),
196 tiles = { "rocks_Mudstone.png^default_mineral_coal.png" },
197 is_ground_content = true,
198 groups = {crumbly=3},
200 minetest.register_node( "rocks:anthracite", {
201 description = S("Anthracite coal"),
202 tiles = { "rocks_Mudstone.png^rocks_anthracite.png" },
203 is_ground_content = true,
204 groups = {crumbly=3},