This repository has been archived by the owner on Nov 3, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
init.lua
697 lines (604 loc) · 20.4 KB
/
init.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
-- Parameters
local PSCA = 16 -- Player scatter. Maximum distance in chunks (80 nodes)
-- of player spawn from (0, 0, 0)
local YWATER = 1 -- Water surface y
local YSAND = 4 -- Top of beach y
local YTER = -64 -- Deepest seabed y
local YPINE = 47 -- Pines above this y
local TERSCA = 512 -- Terrain vertical scale in nodes
local BASAMP = 0.3 -- Base amplitude relative to 3D noise amplitude. Ridge network structure
local MIDAMP = 0.05 -- Mid amplitude relative to 3D noise amplitude. River valley structure
local TSTONE = 0.02 -- Maximum depth of stone under surface
local TRIVER = -0.018 -- River depth
local TRSAND = -0.022 -- Depth of river sand
local TPFLO = 0.02 -- Width of flora clearing around paths
local TTUN = 0.06 -- Tunnel width
local TFIS = 0.004 -- Fissure width
local TCAV = 1.1 -- Cavern threshold
local ORETHI = 0.003 -- Ore seam minimum thickness (diamond, mese, gold)
-- 1 / n ^ 3 where n = average distance between ores
local ORECHA = 1 / 5 ^ 3 -- Ore chance per stone node
-- 1 / n ^ 2 where n = average distance between features
local BOLCHA = 1 / 128 ^ 2 -- Boulder chance per surfacenode
local LOTET = -0.4 -- Low temperature threshold
local HITET = 0.4 -- High ^
local LOHUT = 0.2 -- Low humidity threshold (abs noise)
local HIHUT = 0.6 -- High ^
-- 2D noise for mid terrain / river
local np_mid = {
offset = 0,
scale = 1,
spread = {x = 1536, y = 1536, z = 1536},
seed = 85546,
octaves = 6,
persist = 0.4
}
-- 2D noise for base terrain / humidity
local np_base = {
offset = 0,
scale = 1,
spread = {x = 3072, y = 3072, z = 3072},
seed = -990054,
octaves = 3,
persist = 0.4
}
-- 2D noises for patha / top terrain
local np_patha = {
offset = 0,
scale = 1,
spread = {x = 768, y = 768, z = 768},
seed = 7000023,
octaves = 4,
persist = 0.4
}
-- 2D noises for pathb / top terrain
local np_pathb = {
offset = 0,
scale = 1,
spread = {x = 768, y = 768, z = 768},
seed = 23,
octaves = 4,
persist = 0.4
}
-- 2D noise for temperature
local np_temp = {
offset = 0,
scale = 1,
spread = {x = 3072, y = 3072, z = 3072},
seed = 18882,
octaves = 3,
persist = 0.4
}
-- 3D noise for terrain
local np_terrain = {
offset = 0,
scale = 1,
spread = {x = 384, y = 192, z = 384},
seed = 5900033,
octaves = 5,
persist = 0.67
}
-- 3D noise for alt terrain
local np_terrainalt = {
offset = 0,
scale = 1,
spread = {x = 311, y = 155, z = 311},
seed = -5933,
octaves = 5,
persist = 0.67
}
-- 3D noises for tunnels
local np_weba = {
offset = 0,
scale = 1,
spread = {x = 61, y = 61, z = 61},
seed = 5900033,
octaves = 3,
persist = 0.5
}
local np_webb = {
offset = 0,
scale = 1,
spread = {x = 67, y = 67, z = 67},
seed = 33,
octaves = 3,
persist = 0.5
}
-- 3D noise for strata layering
local np_strata = {
offset = 0,
scale = 1,
spread = {x = 3072, y = 48, z = 3072},
seed = 92219,
octaves = 4,
persist = 1
}
-- Do files
dofile(minetest.get_modpath("riverdev") .. "/functions.lua")
dofile(minetest.get_modpath("riverdev") .. "/nodes.lua")
-- Set mapgen parameters
minetest.set_mapgen_params({mgname = "singlenode", flags = "nolight"})
-- Mapgen functions
local function riverdev_pathbrush(x, y, z, area, data,
y0, wood, emerlen, stable, under, si)
local c_stone = minetest.get_content_id("riverdev:stone")
local c_path = minetest.get_content_id("riverdev:path")
local c_wood = minetest.get_content_id("default:junglewood")
local c_snow = minetest.get_content_id("default:snow")
if wood and math.random() < 0.2 then
local vi = area:index(x, y - 2, z)
for j = y - 2, y0 - 16, -1 do -- use mapblock shell
if data[vi] == c_stone then
break
else
data[vi] = c_wood
end
vi = vi - emerlen
end
end
for k = -1, 1 do
local vi = area:index(x - 1, y - 1, z + k)
local via = vi + emerlen
for i = -1, 1 do
if wood then
data[vi] = c_wood
else
data[vi] = c_path
end
if data[via] ~= c_path and data[via] ~= c_wood
and under[si] == 2 then
data[via] = c_snow
end
vi = vi + 1
via = via + 1
end
end
stable[si] = 0
under[si] = 0
end
local function riverdev_surface(x, y, z, area, data, y1, vi, viu,
n_abspatha, n_abspathb, n_temp, n_humid, under, si)
local c_grass = minetest.get_content_id("riverdev:grass")
local c_snowblock = minetest.get_content_id("default:snowblock")
local c_drygrass = minetest.get_content_id("riverdev:drygrass")
local c_icydirt = minetest.get_content_id("riverdev:icydirt")
if under[si] == 1 then -- tundra
data[viu] = c_icydirt
elseif under[si] == 2 then -- taiga
data[viu] = c_grass
data[vi] = c_snowblock
elseif under[si] == 3 then -- dry grassland
data[viu] = c_drygrass
elseif under[si] == 4 then -- forest/grassland
if math.random() < BOLCHA
and n_abspatha > TPFLO and n_abspathb > TPFLO then
riverdev_boulder(x, y, z, area, data)
else
data[viu] = c_grass
end
elseif under[si] == 6 then -- savanna
data[viu] = c_drygrass
elseif under[si] == 7 then -- rainforest
data[viu] = c_grass
elseif under[si] == 8 then -- sand
if math.random() < BOLCHA
and n_abspatha > TPFLO and n_abspathb > TPFLO then
riverdev_boulder(x, y, z, area, data)
end
elseif under[si] == 9 and n_temp < LOTET then -- stone
data[vi] = c_snowblock
end
end
-- initialize noise objects to nil
local nobj_terrain = nil
local nobj_terrainalt = nil
local nobj_weba = nil
local nobj_webb = nil
local nobj_strata = nil
local nobj_mid = nil
local nobj_base = nil
local nobj_patha = nil
local nobj_pathb = nil
local nobj_temp = nil
-- Localise noise buffers
local nbuf_terrain = {}
local nbuf_terrainalt = {}
local nbuf_weba = {}
local nbuf_webb = {}
local nbuf_strata = {}
local nbuf_mid = {}
local nbuf_base = {}
local nbuf_humid = {}
local nbuf_patha = {}
local nbuf_pathb = {}
local nbuf_temp = {}
-- Localise data buffer
local dbuf = {}
-- On generated function
minetest.register_on_generated(function(minp, maxp, seed)
local t0 = os.clock()
local x1 = maxp.x
local y1 = maxp.y
local z1 = maxp.z
local x0 = minp.x
local y0 = minp.y
local z0 = minp.z
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
local data = vm:get_data(dbuf)
local c_air = minetest.get_content_id("air")
local c_ignore = minetest.get_content_id("ignore")
local c_water = minetest.get_content_id("default:water_source")
local c_sand = minetest.get_content_id("default:sand")
local c_sandstone = minetest.get_content_id("default:sandstone")
local c_wood = minetest.get_content_id("default:junglewood")
local c_snowblock = minetest.get_content_id("default:snowblock")
local c_ice = minetest.get_content_id("default:ice")
local c_desand = minetest.get_content_id("default:desert_sand")
local c_stodiam = minetest.get_content_id("default:stone_with_diamond")
local c_stomese = minetest.get_content_id("default:stone_with_mese")
local c_stogold = minetest.get_content_id("default:stone_with_gold")
local c_stocopp = minetest.get_content_id("default:stone_with_copper")
local c_stoiron = minetest.get_content_id("default:stone_with_iron")
local c_stocoal = minetest.get_content_id("default:stone_with_coal")
local c_dirt = minetest.get_content_id("riverdev:dirt")
local c_grass = minetest.get_content_id("riverdev:grass")
local c_stone = minetest.get_content_id("riverdev:stone")
local c_redstone = minetest.get_content_id("riverdev:redstone")
local c_path = minetest.get_content_id("riverdev:path")
local c_freshwater = minetest.get_content_id("riverdev:freshwater")
local c_mixwater = minetest.get_content_id("riverdev:mixwater")
local c_freshwaterflow = minetest.get_content_id("riverdev:freshwaterflow")
local c_mixwaterflow = minetest.get_content_id("riverdev:mixwaterflow")
local c_permafrost = minetest.get_content_id("riverdev:permafrost")
local sidelen = x1 - x0 + 1 -- mapgen chunk side length
local overlen = sidelen + 1 -- perlinmap overgeneration horizontal side length
local emerlen = sidelen + 32 -- voxelmanip emerged volume edge length
--local emerarea = emerlen ^ 2 -- voxelmanip emerged volume face area
local chulensxyz = {x = overlen, y = sidelen + 2, z = overlen}
local minposxyz = {x = x0 - 1, y = y0 - 1, z = z0 - 1}
local chulensxz = {x = overlen, y = overlen, z = 1} -- different because here x=x, y=z
local minposxz = {x = x0 - 1, y = z0 - 1}
-- 3D and 2D noise objects created once on first mapchunk generation only
nobj_terrain = nobj_terrain or minetest.get_perlin_map(np_terrain, chulensxyz)
nobj_terrainalt = nobj_terrainalt or minetest.get_perlin_map(np_terrainalt, chulensxyz)
nobj_weba = nobj_weba or minetest.get_perlin_map(np_weba, chulensxyz)
nobj_webb = nobj_webb or minetest.get_perlin_map(np_webb, chulensxyz)
nobj_strata = nobj_strata or minetest.get_perlin_map(np_strata, chulensxyz)
nobj_mid = nobj_mid or minetest.get_perlin_map(np_mid, chulensxz)
nobj_base = nobj_base or minetest.get_perlin_map(np_base, chulensxz)
nobj_patha = nobj_patha or minetest.get_perlin_map(np_patha, chulensxz)
nobj_pathb = nobj_pathb or minetest.get_perlin_map(np_pathb, chulensxz)
nobj_temp = nobj_temp or minetest.get_perlin_map(np_temp, chulensxyz)
-- 3D and 2D perlinmaps created per mapchunk
local nvals_terrain = nobj_terrain:get3dMap_flat(minposxyz, nbuf_terrain)
local nvals_terrainalt = nobj_terrainalt:get3dMap_flat(minposxyz, nbuf_terrainalt)
local nvals_weba = nobj_weba:get3dMap_flat(minposxyz, nbuf_weba)
local nvals_webb = nobj_webb:get3dMap_flat(minposxyz, nbuf_webb)
local nvals_strata = nobj_strata:get3dMap_flat(minposxyz, nbuf_strata)
local nvals_mid = nobj_mid:get2dMap_flat(minposxz, nbuf_mid)
local nvals_base = nobj_base:get2dMap_flat(minposxz, nbuf_base)
local nvals_humid = nobj_base:get2dMap_flat({x = x0 - 1, y = z0 + 383}, nbuf_humid)
local nvals_patha = nobj_patha:get2dMap_flat(minposxz, nbuf_patha)
local nvals_pathb = nobj_pathb:get2dMap_flat(minposxz, nbuf_pathb)
local nvals_temp = nobj_temp:get2dMap_flat(minposxz, nbuf_temp)
-- ungenerated chunk below?
local viu = area:index(x0, y0 - 1, z0)
local ungen = data[viu] == c_ignore
local nixyz = 1
local nixz = 1
local stable = {}
local under = {}
for z = z0 - 1, z1 do
for y = y0 - 1, y1 + 1 do
local si = 1
local vi = area:index(x0 - 1, y, z)
local viu = vi - emerlen
local n_xprepatha = false
local n_xprepathb = false
for x = x0 - 1, x1 do
local nodid = data[vi]
local nodidu = data[viu]
local chunkxz = x >= x0 and z >= z0
local n_patha = nvals_patha[nixz]
local n_abspatha = math.abs(n_patha)
local n_zprepatha = nvals_patha[(nixz - overlen)]
local n_pathb = nvals_pathb[nixz]
local n_abspathb = math.abs(n_pathb)
local n_zprepathb = nvals_pathb[(nixz - overlen)]
local n_absweba = math.abs(nvals_weba[nixyz])
local n_abswebb = math.abs(nvals_webb[nixyz])
local novoid = not (n_absweba < TTUN and n_abswebb < TTUN)
local n_terrain = (nvals_terrain[nixyz]
+ nvals_terrainalt[nixyz] + 2) / 2
local n_absmid = (math.abs(nvals_mid[nixz])) ^ 0.8
local n_absbase = (math.abs(nvals_base[nixz])) ^ 0.8
local n_invbase = math.max(1 - n_absbase, 0)
local grad = (YTER - y) / TERSCA -- noise gradient
local densitybase = n_invbase * BASAMP + grad -- ridge surface
local densitymid = n_absmid * MIDAMP + densitybase -- river valley surface
local density = n_terrain * n_invbase * n_absmid -- actual surface
* n_abspatha ^ 1.5 * n_abspathb ^ 1.5 + densitymid
local n_strata = math.abs(nvals_strata[nixyz])
local n_temp = nvals_temp[nixz]
local n_humid = math.abs(nvals_humid[nixz]) - n_absmid * 0.5 + 0.5
local tstone = math.max(TSTONE * (1 + grad * 2), 0)
local triver = TRIVER * n_absbase
local trsand = TRSAND * n_absbase
local wood = densitybase > trsand * 2 and density < 0
if chunkxz and y == y0 - 1 then -- overgeneration, initialise tables
under[si] = 0
if ungen then -- guess by calculating density
if density >= 0 and novoid then
stable[si] = 2
else
stable[si] = 0
end
else -- scan top layer of chunk below
if nodid == c_air
or nodid == c_water
or nodid == c_freshwater
or nodid == c_freshwaterflow
or nodid == c_mixwater
or nodid == c_mixwaterflow then
stable[si] = 0
else
stable[si] = 2
end
end
elseif chunkxz and y >= y0 and y <= y1 then -- chunk generation
local biome = 0
if n_temp < LOTET then
if n_humid < LOHUT then -- tundra
biome = 1
else -- taiga
biome = 2
end
elseif n_temp > HITET then
if n_humid < LOHUT then -- desert
biome = 5
elseif n_humid > HIHUT then -- rainforest
biome = 7
else -- savanna
biome = 6
end
else
if n_humid < LOHUT then -- dry grassland
biome = 3
else -- temperate forest / grassland
biome = 4
end
end
if density >= tstone and (novoid
or (density < tstone * 1.5
and (y <= YWATER or densitybase >= triver))) then
if n_strata < 0.1 then -- sandstone
data[vi] = c_sandstone
elseif n_strata > 1.4
and n_strata < 1.4 + ORETHI then
data[vi] = c_stodiam
elseif n_strata > 1.2
and n_strata < 1.2 + ORETHI then
data[vi] = c_stomese
elseif n_strata > 1
and n_strata < 1 + ORETHI then
data[vi] = c_stogold
elseif n_strata > 0.8
and n_strata < 0.8 + ORETHI * 2 then
data[vi] = c_stocopp
elseif n_strata > 0.6
and n_strata < 0.6 + ORETHI * 3 then
data[vi] = c_stoiron
elseif n_strata > 0.4
and n_strata < 0.4 + ORETHI * 4 then
data[vi] = c_stocoal
elseif biome == 5 then
data[vi] = c_redstone -- redstone layer
else
data[vi] = c_stone -- stone
end
stable[si] = stable[si] + 1
under[si] = 9
elseif y > YSAND -- paths
and ((not wood and density < 0 and under[si] ~= 0)
or (wood and densitybase > trsand * 2
and densitybase < trsand * 2 + 0.002))
and (((n_patha >= 0 and n_xprepatha < 0)
or (n_patha < 0 and n_xprepatha >= 0))
or ((n_patha >= 0 and n_zprepatha < 0)
or (n_patha < 0 and n_zprepatha >= 0))
or ((n_pathb >= 0 and n_xprepathb < 0)
or (n_pathb < 0 and n_xprepathb >= 0))
or ((n_pathb >= 0 and n_zprepathb < 0)
or (n_pathb < 0 and n_zprepathb >= 0))) then
riverdev_pathbrush(x, y, z, area, data,
y0, wood, emerlen, stable, under, si)
elseif density >= 0 and density < tstone -- fine materials
and stable[si] >= 2 and nodid ~= c_stone then -- do not replace boulder
if y <= YSAND or densitybase >= trsand then
data[vi] = c_sand
under[si] = 8
elseif biome == 1 then -- tundra
data[vi] = c_permafrost
under[si] = 1
elseif biome == 2 then -- taiga
data[vi] = c_dirt
under[si] = 2
elseif biome == 3 then -- dry grassland
data[vi] = c_dirt
under[si] = 3
elseif biome == 4 then -- forest / grassland
data[vi] = c_dirt
under[si] = 4
elseif biome == 5 then -- desert
data[vi] = c_desand
under[si] = 5
elseif biome == 6 then -- savanna
data[vi] = c_dirt
under[si] = 6
elseif biome == 7 then -- rainforest
data[vi] = c_dirt
under[si] = 7
end
elseif y <= YWATER and density < tstone
and nodid ~= c_stone then -- sea water
data[vi] = c_water
stable[si] = 0
under[si] = 0
elseif densitybase >= triver and density < tstone
and nodid ~= c_stone then -- river water
if y == YWATER + 1 then
data[vi] = c_mixwater
else
data[vi] = c_freshwater
end
stable[si] = 0
under[si] = 0
elseif density < 0 and y > YWATER
and under[si] ~= 0 -- detect surface, place surface nodes
and nodid ~= c_stone
and nodid ~= c_snowblock and nodidu ~= c_snowblock
and nodid ~= c_path and nodidu ~= c_path
and nodid ~= c_wood and nodidu ~= c_wood then
riverdev_surface(x, y, z, area, data, y1, vi, viu,
n_abspatha, n_abspathb, n_temp, n_humid, under, si)
stable[si] = 0
under[si] = 0
else -- air or tunnel
stable[si] = 0
under[si] = 0
end
elseif chunkxz and y == y1 + 1 then -- overgeneration
if y > YSAND
and ((not wood and density < 0 and under[si] ~= 0)
or (wood and densitybase > trsand * 2
and densitybase < trsand * 2 + 0.002))
and (((n_patha >= 0 and n_xprepatha < 0)
or (n_patha < 0 and n_xprepatha >= 0)) -- patha
or ((n_patha >= 0 and n_zprepatha < 0)
or (n_patha < 0 and n_zprepatha >= 0))
or ((n_pathb >= 0 and n_xprepathb < 0)
or (n_pathb < 0 and n_xprepathb >= 0)) -- pathb
or ((n_pathb >= 0 and n_zprepathb < 0)
or (n_pathb < 0 and n_zprepathb >= 0))) then
riverdev_pathbrush(x, y, z, area, data,
y0, wood, emerlen, stable, under, si)
elseif density < 0 and y > YWATER
and under[si] ~= 0 -- detect surface, place surface nodes
and nodid ~= c_stone
and nodid ~= c_snowblock and nodidu ~= c_snowblock
and nodid ~= c_path and nodidu ~= c_path
and nodid ~= c_wood and nodidu ~= c_wood then
riverdev_surface(x, y, z, area, data, y1, vi, viu,
n_abspatha, n_abspathb, n_temp, n_humid, under, si)
end
end
n_xprepatha = n_patha
n_xprepathb = n_pathb
nixyz = nixyz + 1
nixz = nixz + 1
vi = vi + 1
viu = viu + 1
si = si + 1
end
nixz = nixz - overlen
end
nixz = nixz + overlen
end
vm:set_data(data)
vm:calc_lighting()
vm:write_to_map(data)
vm:update_liquids()
local chugent = math.ceil((os.clock() - t0) * 1000)
print ("[riverdev] " .. chugent .. " ms")
end)
-- Spawn player function
-- Only works with chunksize = 5 mapblocks
local function riverdev_spawnplayer(player)
local xsp
local ysp
local zsp
local nobj_terrain = nil
local nobj_mid = nil
local nobj_base = nil
local nobj_patha = nil
local nobj_pathb = nil
for chunk = 1, 128 do
print ("[riverdev] searching for spawn " .. chunk)
local x0 = 80 * math.random(-PSCA, PSCA) - 32
local z0 = 80 * math.random(-PSCA, PSCA) - 32
local y0 = 80 * math.floor((YWATER + 32) / 80) - 32
local x1 = x0 + 79
local z1 = z0 + 79
local y1 = y0 + 79
local sidelen = 80
local chulensxyz = {x = sidelen, y = sidelen, z = sidelen}
local minposxyz = {x = x0, y = y0, z = z0}
local chulensxz = {x = sidelen, y = sidelen, z = 1}
local minposxz = {x = x0, y = z0}
nobj_terrain = nobj_terrain or minetest.get_perlin_map(np_terrain, chulensxyz)
nobj_mid = nobj_mid or minetest.get_perlin_map(np_mid, chulensxz)
nobj_base = nobj_base or minetest.get_perlin_map(np_base, chulensxz)
nobj_patha = nobj_patha or minetest.get_perlin_map(np_patha, chulensxz)
nobj_pathb = nobj_pathb or minetest.get_perlin_map(np_pathb, chulensxz)
local nvals_terrain = nobj_terrain:get3dMap_flat(minposxyz)
local nvals_mid = nobj_mid:get2dMap_flat(minposxz)
local nvals_base = nobj_base:get2dMap_flat(minposxz)
local nvals_patha = nobj_patha:get2dMap_flat(minposxz)
local nvals_pathb = nobj_pathb:get2dMap_flat(minposxz)
local nixyz = 1
local nixz = 1
for z = z0, z1 do
for y = y0, y1 do
for x = x0, x1 do
local n_patha = nvals_patha[nixz]
local n_abspatha = math.abs(n_patha)
local n_pathb = nvals_pathb[nixz]
local n_abspathb = math.abs(n_pathb)
local n_terrain = (nvals_terrain[nixyz] + 2) / 2
local n_absmid = (math.abs(nvals_mid[nixz])) ^ 0.8
local n_absbase = (math.abs(nvals_base[nixz])) ^ 0.8
local n_invbase = math.max(1 - n_absbase, 0)
local grad = (YTER - y) / TERSCA
local densitybase = n_invbase * BASAMP + grad
local densitymid = n_absmid * MIDAMP + densitybase
local density = n_terrain * n_invbase * n_absmid *
n_abspatha ^ 1.5 * n_abspathb ^ 1.5 + densitymid
if y >= YWATER and density > -0.01 and density < 0 then
ysp = y + 1
xsp = x
zsp = z
break
end
nixz = nixz + 1
nixyz = nixyz + 1
end
if ysp then
break
end
nixz = nixz - 80
end
if ysp then
break
end
nixz = nixz + 80
end
if ysp then
break
end
end
if ysp then
print ("[riverdev] spawn player (" .. xsp .. " " .. ysp .. " " .. zsp .. ")")
player:setpos({x = xsp, y = ysp, z = zsp})
else
print ("[riverdev] no suitable spawn found")
player:setpos({x = 0, y = 2, z = 0})
end
end
minetest.register_on_newplayer(function(player)
riverdev_spawnplayer(player)
end)
minetest.register_on_respawnplayer(function(player)
riverdev_spawnplayer(player)
return true
end)