started traps, abm tweaks.
|
@ -1,3 +1,10 @@
|
|||
2015-09-02:
|
||||
Updated More_fire to fix a few missing textures.
|
||||
Tweaked around grass growth and spread ABMs. Grass will now just grow on soils that have full grass texture on top, which should help with the disparity in looks.
|
||||
Tweaked the ABM for the trail erosion, dirt nodes only change back into grass if they have air on top of them. This fixes the issue of default:dirt_with_grass showing up under water.
|
||||
Added model and start of code for a simple snare.
|
||||
Started working on food poisoning, currently there is some problem with the pathogen actually kicking in, but other coding is all set to go.
|
||||
|
||||
2015-08-27:
|
||||
Updated More_fire and Survival
|
||||
Added a couple ABMs for grass spreading and growth.
|
||||
|
|
|
@ -7,7 +7,10 @@ local grass_table = {-- mature, child
|
|||
}
|
||||
|
||||
minetest.register_abm({ --grass spreading
|
||||
nodenames = {'group:soil'},
|
||||
nodenames = {'default:dirt_with_grass',
|
||||
'woodsoils:grass_with_leaves_1',
|
||||
'valleys_mapgen:dirt_sandy_with_grass',
|
||||
'valleys_mapgen:dirty_clayey_with_grass'},
|
||||
neighbors = {'group:grass'},
|
||||
interval = 20,
|
||||
chance = 40,
|
||||
|
|
|
@ -26,8 +26,8 @@ minetest.register_node('food:smoker', { --This will allow for smoking meats
|
|||
'size[8,7]'..
|
||||
'label[0,0;Smoke meat to preserve it.]' ..
|
||||
'list[current_name;meat;1,.5;3,2;]'..
|
||||
'list[current_name;fuel;5,1.5;1,1]'..
|
||||
'list[current_player;main;0,3;8,4;]')
|
||||
'list[current_name;fuel;5,1.5;1,1]'..
|
||||
'list[current_player;main;0,3;8,4;]')
|
||||
meta:set_string('infotext', 'Smoker')
|
||||
end,
|
||||
on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
--Formspecs for the traps
|
||||
|
||||
trap_empty = --trap just built but with nothing in it.
|
||||
'size[8,6]'..
|
||||
'label[2,0;Bait the trap to catch game.]' ..
|
||||
'list[current_name;bait;3.5,.6;1,1;]'..
|
||||
'list[current_player;main;0,2;8,4;]'
|
||||
|
||||
trap_baited = --trap has bait, just waiting for an animal.
|
||||
'size[8,6]'..
|
||||
'label[1,0;Check back often to see if you caught something.]' ..
|
||||
'list[current_name;bait;2,.6;1,1;]'..
|
||||
'list[current_name;game;5,.6;1,1;]'..
|
||||
'list[current_player;main;0,2;8,4;]'
|
||||
|
||||
trap_game = --trap was successful and caught something.
|
||||
'size[8,6]'..
|
||||
"label[2,0;Put the critter out of it's misery..]" ..
|
||||
'list[current_name;bait;2,.6;1,1;]'..
|
||||
'list[current_name;game;5,.6;1,1;]'..
|
||||
'list[current_player;main;0,2;8,4;]'
|
||||
|
||||
trap_raided = --oh no, looks like something stole our catch.
|
||||
'size[8,6]'..
|
||||
'label[2,0;Looks like something stole your catch.]' ..
|
||||
'list[current_name;bait;3.5,.6;1,1;]'..
|
||||
'list[current_player;main;0,2;8,4;]'
|
|
@ -2,3 +2,5 @@ dofile(minetest.get_modpath('food')..'/spoiling.lua') --Mechanics for food to sp
|
|||
dofile(minetest.get_modpath('food')..'/fruits.lua') --Fruits, need I document things?
|
||||
dofile(minetest.get_modpath('food')..'/meats.lua') --Again, I think it's obvious
|
||||
dofile(minetest.get_modpath('food')..'/cooking_machines.lua') --Stoves, Smokers, things to cook the food.
|
||||
dofile(minetest.get_modpath('food')..'/traps.lua') --capture and eat yummy animals.
|
||||
dofile(minetest.get_modpath('food')..'/formspecs.lua') --formspecs for different things.
|
||||
|
|
|
@ -7,13 +7,13 @@ local salted_meat = {meat=1, meat_salted=1}
|
|||
local dried_meat = {meat=1, meat_cooked=1, meat_dried=1}
|
||||
|
||||
--Foods Table
|
||||
local food_table = { --craft, desc, health, hydration, groups
|
||||
{'steak_raw', 'Raw Steak', .4, .25, raw_meat},
|
||||
{'steak_cooked', 'Cooked Steak', .5, .1, cooked_meat},
|
||||
{'steak_smoked', 'Smoked Steak', .5, -.3, smoked_meat},
|
||||
{'steak_spoiled', 'Rotten Steak', -2, .1, spoiled_meat},
|
||||
{'steak_salted', 'Salted Steak', .5, -1, salted_meat},
|
||||
{'steak_dried', 'Dried Jerky', .75, -1.5, dried_meat}
|
||||
local food_table = { --craft, desc, health, hydration, groups, chance(of getting food poisoning x/10)
|
||||
{'steak_raw', 'Raw Steak', .4, .25, raw_meat, 6},
|
||||
{'steak_cooked', 'Cooked Steak', .5, .1, cooked_meat, 0},
|
||||
{'steak_smoked', 'Smoked Steak', .5, -.3, smoked_meat, 0},
|
||||
{'steak_spoiled', 'Rotten Steak', .2, .1, spoiled_meat, 10},
|
||||
{'steak_salted', 'Salted Steak', .5, -1, salted_meat, 0},
|
||||
{'steak_dried', 'Dried Jerky', .75, -1.5, dried_meat, 0}
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,6 +24,7 @@ for i in ipairs (food_table) do
|
|||
local health = food_table[i][3]
|
||||
local hydration = food_table[i][4]
|
||||
local group = food_table[i][5]
|
||||
local chance = food_table[i][6]
|
||||
|
||||
--Actual craftitem registration
|
||||
minetest.register_craftitem('food:'..craft, {
|
||||
|
@ -31,10 +32,17 @@ minetest.register_craftitem('food:'..craft, {
|
|||
inventory_image = 'food_'..craft..'.png',
|
||||
groups = group,
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
thirsty.drink(user, hydration, 20)
|
||||
local eat_func = minetest.item_eat(health)
|
||||
return eat_func(itemstack, user, pointed_thing)
|
||||
end,
|
||||
local chance_level = math.random(0,10)
|
||||
print ('chance is '..chance_level)
|
||||
if chance_level < chance then
|
||||
print ('should get sick')
|
||||
pathogen.infect = function(Influencia, singleplayer)
|
||||
end
|
||||
thirsty.drink(user, hydration, 20) --controls the hydration gain
|
||||
return eat_func(itemstack, user, pointed_thing) --controls the fullness gain
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
# Blender v2.75 (sub 4) OBJ File: ''
|
||||
# www.blender.org
|
||||
o Cube.001
|
||||
v 0.300000 -0.500000 -0.300000
|
||||
v 0.300000 0.100000 -0.300000
|
||||
v 0.300000 -0.500000 -0.400000
|
||||
v 0.300000 0.100000 -0.400000
|
||||
v 0.400000 -0.500000 -0.300000
|
||||
v 0.400000 0.100000 -0.300000
|
||||
v 0.400000 -0.500000 -0.400000
|
||||
v 0.400000 0.100000 -0.400000
|
||||
v -0.400000 -0.500000 -0.300000
|
||||
v -0.400000 0.100000 -0.300000
|
||||
v -0.400000 -0.500000 -0.400000
|
||||
v -0.400000 0.100000 -0.400000
|
||||
v -0.300000 -0.500000 -0.300000
|
||||
v -0.300000 0.100000 -0.300000
|
||||
v -0.300000 -0.500000 -0.400000
|
||||
v -0.300000 0.100000 -0.400000
|
||||
v -0.400000 -0.500000 0.400000
|
||||
v -0.400000 0.100000 0.400000
|
||||
v -0.400000 -0.500000 0.300000
|
||||
v -0.400000 0.100000 0.300000
|
||||
v -0.300000 -0.500000 0.400000
|
||||
v -0.300000 0.100000 0.400000
|
||||
v -0.300000 -0.500000 0.300000
|
||||
v -0.300000 0.100000 0.300000
|
||||
v 0.300000 -0.500000 0.400000
|
||||
v 0.300000 0.100000 0.400000
|
||||
v 0.300000 -0.500000 0.300000
|
||||
v 0.300000 0.100000 0.300000
|
||||
v 0.400000 -0.500000 0.400000
|
||||
v 0.400000 0.100000 0.400000
|
||||
v 0.400000 -0.500000 0.300000
|
||||
v 0.400000 0.100000 0.300000
|
||||
v 0.300000 -0.500000 0.050000
|
||||
v 0.300000 -0.200000 0.050000
|
||||
v 0.300000 -0.500000 -0.050000
|
||||
v 0.300000 -0.200000 -0.050000
|
||||
v 0.400000 -0.500000 0.050000
|
||||
v 0.400000 -0.200000 0.050000
|
||||
v 0.400000 -0.500000 -0.050000
|
||||
v 0.400000 -0.200000 -0.050000
|
||||
v -0.400000 -0.500000 0.050000
|
||||
v -0.400000 -0.200000 0.050000
|
||||
v -0.400000 -0.500000 -0.050000
|
||||
v -0.400000 -0.200000 -0.050000
|
||||
v -0.300000 -0.500000 0.050000
|
||||
v -0.300000 -0.200000 0.050000
|
||||
v -0.300000 -0.500000 -0.050000
|
||||
v -0.300000 -0.200000 -0.050000
|
||||
v -0.050000 -0.500000 -0.300000
|
||||
v -0.050000 -0.200000 -0.300000
|
||||
v -0.050000 -0.500000 -0.400000
|
||||
v -0.050000 -0.200000 -0.400000
|
||||
v 0.050000 -0.500000 -0.300000
|
||||
v 0.050000 -0.200000 -0.300000
|
||||
v 0.050000 -0.500000 -0.400000
|
||||
v 0.050000 -0.200000 -0.400000
|
||||
v -0.050000 -0.500000 0.400000
|
||||
v -0.050000 -0.200000 0.400000
|
||||
v -0.050000 -0.500000 0.300000
|
||||
v -0.050000 -0.200000 0.300000
|
||||
v 0.050000 -0.500000 0.400000
|
||||
v 0.050000 -0.200000 0.400000
|
||||
v 0.050000 -0.500000 0.300000
|
||||
v 0.050000 -0.200000 0.300000
|
||||
vt 0.012483 0.447336
|
||||
vt 0.012483 0.609946
|
||||
vt 0.988139 0.609946
|
||||
vt 0.988139 0.447336
|
||||
vt 0.608865 0.447336
|
||||
vt 0.446256 0.447336
|
||||
vt 0.446256 0.609946
|
||||
vt 0.608865 0.609946
|
||||
vt 0.011440 0.197854
|
||||
vt 0.011440 0.360464
|
||||
vt 0.987096 0.360464
|
||||
vt 0.987096 0.197854
|
||||
vt 0.607822 0.197854
|
||||
vt 0.445213 0.197854
|
||||
vt 0.445213 0.360464
|
||||
vt 0.607822 0.360464
|
||||
vt 0.824487 0.197854
|
||||
vt 0.661878 0.197854
|
||||
vt 0.661878 0.360464
|
||||
vt 0.824487 0.360464
|
||||
vt 0.825530 0.447336
|
||||
vt 0.662920 0.447336
|
||||
vt 0.662920 0.609946
|
||||
vt 0.825530 0.609946
|
||||
vt 0.503436 0.700302
|
||||
vt 0.503436 0.862912
|
||||
vt 0.991264 0.862912
|
||||
vt 0.991264 0.700302
|
||||
vt 0.500311 0.447336
|
||||
vt 0.500311 0.609946
|
||||
vt 0.256397 0.447336
|
||||
vt 0.093788 0.447336
|
||||
vt 0.093788 0.609946
|
||||
vt 0.256397 0.609946
|
||||
vt 0.499268 0.197854
|
||||
vt 0.499268 0.360464
|
||||
vt 0.255354 0.197854
|
||||
vt 0.092745 0.197854
|
||||
vt 0.092745 0.360464
|
||||
vt 0.255354 0.360464
|
||||
vt 0.611990 0.700302
|
||||
vt 0.449380 0.700303
|
||||
vt 0.449380 0.862912
|
||||
vt 0.611990 0.862912
|
||||
vt 0.828655 0.700302
|
||||
vt 0.666045 0.700302
|
||||
vt 0.666045 0.862912
|
||||
vt 0.828655 0.862912
|
||||
vn -1.000000 0.000000 0.000000
|
||||
vn 0.000000 0.000000 -1.000000
|
||||
vn 1.000000 0.000000 0.000000
|
||||
vn 0.000000 0.000000 1.000000
|
||||
vn 0.000000 -1.000000 0.000000
|
||||
vn 0.000000 1.000000 0.000000
|
||||
s off
|
||||
f 2/1/1 4/2/1 3/3/1 1/4/1
|
||||
f 4/1/2 8/2/2 7/3/2 3/4/2
|
||||
f 8/2/3 6/1/3 5/4/3 7/3/3
|
||||
f 6/2/4 2/1/4 1/4/4 5/3/4
|
||||
f 1/5/5 3/6/5 7/7/5 5/8/5
|
||||
f 6/8/6 8/7/6 4/6/6 2/5/6
|
||||
f 10/1/1 12/2/1 11/3/1 9/4/1
|
||||
f 12/9/2 16/10/2 15/11/2 11/12/2
|
||||
f 16/2/3 14/1/3 13/4/3 15/3/3
|
||||
f 14/10/4 10/9/4 9/12/4 13/11/4
|
||||
f 9/13/5 11/14/5 15/15/5 13/16/5
|
||||
f 14/16/6 16/15/6 12/14/6 10/13/6
|
||||
f 18/9/1 20/10/1 19/11/1 17/12/1
|
||||
f 20/9/2 24/10/2 23/11/2 19/12/2
|
||||
f 24/10/3 22/9/3 21/12/3 23/11/3
|
||||
f 22/10/4 18/9/4 17/12/4 21/11/4
|
||||
f 17/17/5 19/18/5 23/19/5 21/20/5
|
||||
f 22/20/6 24/19/6 20/18/6 18/17/6
|
||||
f 26/9/1 28/10/1 27/11/1 25/12/1
|
||||
f 28/1/2 32/2/2 31/3/2 27/4/2
|
||||
f 32/10/3 30/9/3 29/12/3 31/11/3
|
||||
f 30/2/4 26/1/4 25/4/4 29/3/4
|
||||
f 25/21/5 27/22/5 31/23/5 29/24/5
|
||||
f 30/24/6 32/23/6 28/22/6 26/21/6
|
||||
f 34/25/1 36/26/1 35/27/1 33/28/1
|
||||
f 36/29/2 40/30/2 39/3/2 35/4/2
|
||||
f 40/26/3 38/25/3 37/28/3 39/27/3
|
||||
f 38/30/4 34/29/4 33/4/4 37/3/4
|
||||
f 33/31/5 35/32/5 39/33/5 37/34/5
|
||||
f 38/34/6 40/33/6 36/32/6 34/31/6
|
||||
f 42/25/1 44/26/1 43/27/1 41/28/1
|
||||
f 44/35/2 48/36/2 47/11/2 43/12/2
|
||||
f 48/26/3 46/25/3 45/28/3 47/27/3
|
||||
f 46/36/4 42/35/4 41/12/4 45/11/4
|
||||
f 41/37/5 43/38/5 47/39/5 45/40/5
|
||||
f 46/40/6 48/39/6 44/38/6 42/37/6
|
||||
f 50/29/1 52/30/1 51/3/1 49/4/1
|
||||
f 52/25/2 56/26/2 55/27/2 51/28/2
|
||||
f 56/30/3 54/29/3 53/4/3 55/3/3
|
||||
f 54/26/4 50/25/4 49/28/4 53/27/4
|
||||
f 49/41/5 51/42/5 55/43/5 53/44/5
|
||||
f 54/44/6 56/43/6 52/42/6 50/41/6
|
||||
f 58/35/1 60/36/1 59/11/1 57/12/1
|
||||
f 60/25/2 64/26/2 63/27/2 59/28/2
|
||||
f 64/36/3 62/35/3 61/12/3 63/11/3
|
||||
f 62/26/4 58/25/4 57/28/4 61/27/4
|
||||
f 57/45/5 59/46/5 63/47/5 61/48/5
|
||||
f 62/48/6 64/47/6 60/46/6 58/45/6
|
|
@ -0,0 +1,67 @@
|
|||
--Node Definitions
|
||||
minetest.register_node('food:snare', { --simple way to catch small game
|
||||
description = 'Simple Snare',
|
||||
drawtype = 'mesh',
|
||||
mesh = 'food_snare.obj',
|
||||
tiles = {name='default_wood.png'},
|
||||
groups = {choppy=2, dig_immediate=2,},
|
||||
paramtype = 'light',
|
||||
paramtype2 = 'facedir',
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
type = 'fixed',
|
||||
fixed = {-.4, -.5, -.4, .4, .0, .4},
|
||||
},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size('main', 8*4)
|
||||
inv:set_size('bait', 1)
|
||||
inv:set_size('game', 1)
|
||||
meta:set_string('formspec', trap_empty)
|
||||
meta:set_string('infotext', 'Simple Snare')
|
||||
end,
|
||||
on_metadata_inventory_put = function(pos, listname, index, stack, player) --yes you can bait with ANYTHING.
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
minetest.swap_node(pos, {name = 'food:snare_baited'})
|
||||
meta:set_string('formspec', trap_baited)
|
||||
end,
|
||||
on_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
meta:set_string('formspec', trap_empty)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node('food:snare_baited', { --baited trap
|
||||
drawtype = 'mesh',
|
||||
mesh = 'food_snare.obj',
|
||||
tiles = {name='default_wood.png'},
|
||||
groups = {choppy=2, dig_immediate=2,},
|
||||
paramtype = 'light',
|
||||
paramtype2 = 'facedir',
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
type = 'fixed',
|
||||
fixed = {-.4, -.5, -.4, .4, .0, .4},
|
||||
},
|
||||
on_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
minetest.swap_node(pos, {name = 'food:snare'})
|
||||
meta:set_string('formspec', trap_empty)
|
||||
end,
|
||||
can_dig = function(pos,player)
|
||||
return false
|
||||
end,
|
||||
})
|
||||
|
||||
--Craft Recipes
|
||||
minetest.register_craft({
|
||||
output = 'food:snare',
|
||||
recipe = {
|
||||
{'more_fire:flintstone', 'more_fire:flintstone', 'more_fire:flintstone'},
|
||||
{'group:stick', 'farming:cotton', 'group:stick'},
|
||||
{'group:stick', 'group:stick', 'default:stick'},
|
||||
}
|
||||
})
|
|
@ -1,41 +1,36 @@
|
|||
# mobs_goblins
|
||||
|
||||
-= MOBS_GOBLINS-MOD for MINETEST =-
|
||||
by FreeLikeGNU
|
||||
|
||||
# mobs_goblins Goblins mod for Minetest
|
||||
## by Francisco "FreeLikeGNU" Athens
|
||||
https://forum.minetest.net/viewtopic.php?f=9&t=13004
|
||||
https://github.com/FreeLikeGNU/mobs_goblins
|
||||
|
||||
based on MOBS-MOD by PilzAdam, KrupnovPavel, Zeg9, TenPlus1
|
||||
https://forum.minetest.net/viewtopic.php?f=9&t=9917
|
||||
* code based on MOBS-MOD by PilzAdam, KrupnovPavel, Zeg9, TenPlus1
|
||||
https://forum.minetest.net/viewtopic.php?f=9&t=9917
|
||||
|
||||
This mod adds several Goblins to Minetest that should spawn near ore deposits or lairs underground.
|
||||
|
||||
v0.05 Fix errors in .04, remove texture names from goblin model, and add cobble goblins to build goblin lairs.
|
||||
|
||||
v0.04 Thieving goblins!
|
||||
|
||||
v0.03 This is a test version that adds a goblin king! Thanks to Napiophelios! Some more texture refinement and fixed naming of textures.
|
||||
|
||||
v0.02 This is a test version and some the goblins will not attack unless attacked. Variety varies with ore...
|
||||
|
||||
v0.01 This is a test version and all the goblins act like an NPC and will not attack unless attacked.
|
||||
|
||||
* Goblins dig caves, destroy torches, create lairs and some are aggressive.
|
||||
|
||||
License of Media Files:
|
||||
---------------------------------------
|
||||
goblins_goblin.b3d and goblins_goblin.blend
|
||||
by FreeLikeGNU Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) by FreeLikeGNU
|
||||
* goblins_goblin.b3d and goblins_goblin.blend
|
||||
Copyright 2015 by Francisco "FreeLikeGNU" Athens Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
above meshes based on character from minetest_game
|
||||
* above meshes based on character from minetest_game
|
||||
by MirceaKitsune (WTFPL)
|
||||
https://github.com/minetest/minetest_game/blob/master/mods/default/README.txt#L71
|
||||
|
||||
goblins_goblins*.png files and goblins_goblin.xcf files
|
||||
by FreeLikeGNU Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
* goblins_goblins*.png files and goblins_goblin.xcf files
|
||||
Copyright 2015 by Francisco "FreeLikeGNU" Athens Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
Thanks to Napiophelios for the goblin king skin
|
||||
* Sound files by:
|
||||
* artisticdude http://opengameart.org/content/goblins-sound-pack CC0-license
|
||||
* Ogrebane http://opengameart.org/content/monster-sound-pack-volume-1 CC0-license
|
||||
|
||||
* Thanks to Napiophelios for the goblin king skin
|
||||
https://forum.minetest.net/viewtopic.php?f=9&t=13004#p186921
|
||||
goblins_goblin_king.png
|
||||
License: Creative Commons CC-BY-SA-3.0 SummerFeilds TP
|
||||
|
|
|
@ -300,7 +300,7 @@ function mobs_goblins:register_mob(name, def)
|
|||
end
|
||||
|
||||
if self.sounds.random
|
||||
and math.random(1, 100) <= 1 then
|
||||
and math.random(1, 100) <= 10 then
|
||||
minetest.sound_play(self.sounds.random, {
|
||||
object = self.object,
|
||||
max_hear_distance = self.sounds.distance
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
default
|
|
@ -26,8 +26,12 @@ mobs_goblins:register_mob("mobs_goblins:goblin_cobble", {
|
|||
},
|
||||
makes_footstep_sound = true,
|
||||
sounds = {
|
||||
random = "mobs_pig",
|
||||
attack = "mobs_pig_angry",
|
||||
random = "goblins_goblin_ambient",
|
||||
warcry = "goblins_goblin_attack",
|
||||
attack = "goblins_goblin_attack",
|
||||
damage = "goblins_goblin_damage",
|
||||
death = "goblins_goblin_death",
|
||||
distance = 15,
|
||||
},
|
||||
walk_velocity = 2,
|
||||
run_velocity = 3,
|
||||
|
@ -43,8 +47,9 @@ mobs_goblins:register_mob("mobs_goblins:goblin_cobble", {
|
|||
water_damage = 0,
|
||||
lava_damage = 2,
|
||||
light_damage = 0,
|
||||
lifetimer = 360,
|
||||
follow = {"default:diamond"},
|
||||
replace_rate = 30,
|
||||
replace_rate = 20,
|
||||
replace_what = {"default:stone","default:desert_stone",},
|
||||
replace_with = "default:mossycobble",
|
||||
replace_offset = 1,
|
||||
|
@ -113,6 +118,118 @@ mobs_goblins:register_mob("mobs_goblins:goblin_cobble", {
|
|||
end,
|
||||
|
||||
})
|
||||
mobs_goblins:register_mob("mobs_goblins:goblin_digger", {
|
||||
description = "Digger Goblin",
|
||||
type = "animal",
|
||||
passive = false,
|
||||
damage = 1,
|
||||
attack_type = "dogfight",
|
||||
attacks_monsters = true,
|
||||
hp_min = 5,
|
||||
hp_max = 10,
|
||||
armor = 100,
|
||||
collisionbox = {-0.35,-1.0,-0.35, 0.35,0.0,0.35},
|
||||
visual = "mesh",
|
||||
mesh = "goblins_goblin.b3d",
|
||||
drawtype = "front",
|
||||
textures = {
|
||||
{"goblins_goblin_cobble2.png"},
|
||||
},
|
||||
makes_footstep_sound = true,
|
||||
sounds = {
|
||||
random = "goblins_goblin_ambient",
|
||||
warcry = "goblins_goblin_attack",
|
||||
attack = "goblins_goblin_attack",
|
||||
damage = "goblins_goblin_damage",
|
||||
death = "goblins_goblin_death",
|
||||
distance = 15,
|
||||
},
|
||||
walk_velocity = 2,
|
||||
run_velocity = 3,
|
||||
jump = true,
|
||||
drops = {
|
||||
{name = "default:mossycobble",
|
||||
chance = 1, min = 1, max = 3},
|
||||
{name = "default:apple",
|
||||
chance = 2, min = 1, max = 2},
|
||||
{name = "default:torch",
|
||||
chance = 3, min = 1, max = 10},
|
||||
},
|
||||
water_damage = 0,
|
||||
lava_damage = 2,
|
||||
light_damage = 0,
|
||||
lifetimer = 360,
|
||||
follow = {"default:diamond"},
|
||||
replace_rate = 20,
|
||||
replace_what = {"default:stone","default:desert_stone","default:torch"},
|
||||
replace_with = "air",
|
||||
replace_offset = 1,
|
||||
view_range = 15,
|
||||
owner = "",
|
||||
order = "follow",
|
||||
animation = {
|
||||
speed_normal = 30,
|
||||
speed_run = 30,
|
||||
stand_start = 0,
|
||||
stand_end = 79,
|
||||
walk_start = 168,
|
||||
walk_end = 187,
|
||||
run_start = 168,
|
||||
run_end = 187,
|
||||
punch_start = 200,
|
||||
punch_end = 219,
|
||||
},
|
||||
on_rightclick = function(self, clicker)
|
||||
local item = clicker:get_wielded_item()
|
||||
local name = clicker:get_player_name()
|
||||
|
||||
-- feed to heal goblin
|
||||
if item:get_name() == "default:apple"
|
||||
or item:get_name() == "farming:bread" then
|
||||
|
||||
local hp = self.object:get_hp()
|
||||
-- return if full health
|
||||
if hp >= self.hp_max then
|
||||
minetest.chat_send_player(name, "goblin at full health.")
|
||||
return
|
||||
end
|
||||
hp = hp + 4
|
||||
if hp > self.hp_max then hp = self.hp_max end
|
||||
self.object:set_hp(hp)
|
||||
-- take item
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
item:take_item()
|
||||
clicker:set_wielded_item(item)
|
||||
end
|
||||
|
||||
-- right clicking with gold lump drops random item from mobs_goblins.goblin_drops
|
||||
elseif item:get_name() == "default:gold_lump" then
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
item:take_item()
|
||||
clicker:set_wielded_item(item)
|
||||
end
|
||||
local pos = self.object:getpos()
|
||||
pos.y = pos.y + 0.5
|
||||
minetest.add_item(pos, {name = mobs_goblins.goblin_drops[math.random(1, #mobs_goblins.goblin_drops)]})
|
||||
|
||||
else
|
||||
-- if owner switch between follow and stand
|
||||
if self.owner and self.owner == clicker:get_player_name() then
|
||||
if self.order == "follow" then
|
||||
self.order = "stand"
|
||||
else
|
||||
self.order = "follow"
|
||||
end
|
||||
-- else
|
||||
-- self.owner = clicker:get_player_name()
|
||||
end
|
||||
end
|
||||
|
||||
mobs_goblins:capture_mob(self, clicker, 0, 5, 80, false, nil)
|
||||
end,
|
||||
|
||||
})
|
||||
|
||||
mobs_goblins:register_mob("mobs_goblins:goblin_coal", {
|
||||
description = "Coal Goblin",
|
||||
type = "animal",
|
||||
|
@ -133,8 +250,12 @@ mobs_goblins:register_mob("mobs_goblins:goblin_coal", {
|
|||
},
|
||||
makes_footstep_sound = true,
|
||||
sounds = {
|
||||
random = "mobs_pig",
|
||||
attack = "mobs_pig_angry",
|
||||
random = "goblins_goblin_ambient",
|
||||
warcry = "goblins_goblin_attack",
|
||||
attack = "goblins_goblin_attack",
|
||||
damage = "goblins_goblin_damage",
|
||||
death = "goblins_goblin_death",
|
||||
distance = 15,
|
||||
},
|
||||
walk_velocity = 2,
|
||||
run_velocity = 3,
|
||||
|
@ -151,7 +272,7 @@ mobs_goblins:register_mob("mobs_goblins:goblin_coal", {
|
|||
lava_damage = 2,
|
||||
light_damage = 0,
|
||||
follow = {"default:diamond"},
|
||||
replace_rate = 50,
|
||||
replace_rate = 30,
|
||||
replace_what = {"default:torch",},
|
||||
replace_with = "air",
|
||||
replace_offset = 2,
|
||||
|
@ -240,8 +361,12 @@ mobs_goblins:register_mob("mobs_goblins:goblin_iron", {
|
|||
},
|
||||
makes_footstep_sound = true,
|
||||
sounds = {
|
||||
random = "mobs_pig",
|
||||
attack = "mobs_pig_angry",
|
||||
random = "goblins_goblin_ambient",
|
||||
warcry = "goblins_goblin_attack",
|
||||
attack = "goblins_goblin_attack",
|
||||
damage = "goblins_goblin_damage",
|
||||
death = "goblins_goblin_death",
|
||||
distance = 15,
|
||||
},
|
||||
walk_velocity = 2,
|
||||
run_velocity = 3,
|
||||
|
@ -258,7 +383,7 @@ mobs_goblins:register_mob("mobs_goblins:goblin_iron", {
|
|||
lava_damage = 2,
|
||||
light_damage = 0,
|
||||
follow = "default:diamond",
|
||||
replace_rate = 50,
|
||||
replace_rate = 40,
|
||||
replace_what = {"default:torch",},
|
||||
replace_with = "air",
|
||||
replace_offset = 2,
|
||||
|
@ -347,8 +472,12 @@ mobs_goblins:register_mob("mobs_goblins:goblin_gold", {
|
|||
},
|
||||
makes_footstep_sound = true,
|
||||
sounds = {
|
||||
random = "mobs_pig",
|
||||
attack = "mobs_pig_angry",
|
||||
random = "goblins_goblin_ambient",
|
||||
warcry = "goblins_goblin_attack",
|
||||
attack = "goblins_goblin_attack",
|
||||
damage = "goblins_goblin_damage",
|
||||
death = "goblins_goblin_death",
|
||||
distance = 15,
|
||||
},
|
||||
walk_velocity = 2,
|
||||
run_velocity = 3,
|
||||
|
@ -365,10 +494,10 @@ mobs_goblins:register_mob("mobs_goblins:goblin_gold", {
|
|||
lava_damage = 2,
|
||||
light_damage = 0,
|
||||
follow = "default:diamond",
|
||||
replace_rate = 50,
|
||||
replace_rate = 40,
|
||||
replace_what = {"default:torch",},
|
||||
replace_with = "air",
|
||||
replace_offset = 2,
|
||||
replace_offset = 3,
|
||||
view_range = 15,
|
||||
owner = "",
|
||||
order = "follow",
|
||||
|
@ -454,8 +583,12 @@ mobs_goblins:register_mob("mobs_goblins:goblin_diamond", {
|
|||
},
|
||||
makes_footstep_sound = true,
|
||||
sounds = {
|
||||
random = "mobs_pig",
|
||||
attack = "mobs_pig_angry",
|
||||
random = "goblins_goblin_ambient",
|
||||
warcry = "goblins_goblin_attack",
|
||||
attack = "goblins_goblin_attack",
|
||||
damage = "goblins_goblin_damage",
|
||||
death = "goblins_goblin_death",
|
||||
distance = 15,
|
||||
},
|
||||
walk_velocity = 2,
|
||||
run_velocity = 3,
|
||||
|
@ -472,10 +605,10 @@ mobs_goblins:register_mob("mobs_goblins:goblin_diamond", {
|
|||
lava_damage = 2,
|
||||
light_damage = 0,
|
||||
follow = "default:diamond",
|
||||
replace_rate = 50,
|
||||
replace_rate = 40,
|
||||
replace_what = {"default:torch",},
|
||||
replace_with = "air",
|
||||
replace_offset = 2,
|
||||
replace_offset = 3,
|
||||
view_range = 15,
|
||||
owner = "",
|
||||
order = "follow",
|
||||
|
@ -560,8 +693,12 @@ mobs_goblins:register_mob("mobs_goblins:goblin_king", {
|
|||
},
|
||||
makes_footstep_sound = true,
|
||||
sounds = {
|
||||
random = "mobs_pig",
|
||||
attack = "mobs_pig_angry",
|
||||
random = "goblins_goblin_ambient",
|
||||
warcry = "goblins_goblin_attack",
|
||||
attack = "goblins_goblin_attack",
|
||||
damage = "goblins_goblin_damage",
|
||||
death = "goblins_goblin_death",
|
||||
distance = 15,
|
||||
},
|
||||
walk_velocity = 2,
|
||||
run_velocity = 3,
|
||||
|
@ -578,10 +715,10 @@ mobs_goblins:register_mob("mobs_goblins:goblin_king", {
|
|||
lava_damage = 2,
|
||||
light_damage = 0,
|
||||
follow = "default:diamond",
|
||||
replace_rate = 50,
|
||||
replace_rate = 40,
|
||||
replace_what = {"default:torch",},
|
||||
replace_with = "air",
|
||||
replace_offset = -1,
|
||||
replace_offset = 3,
|
||||
view_range = 15,
|
||||
owner = "",
|
||||
order = "follow",
|
||||
|
@ -647,12 +784,13 @@ mobs_goblins:register_mob("mobs_goblins:goblin_king", {
|
|||
end,
|
||||
|
||||
})
|
||||
-- spawn underground near ore and dungeons, except cobble goblins who create goblin lairs.
|
||||
-- spawn underground near ore and dungeons, except cobble goblins who create goblin lairs near stone.
|
||||
--function mobs_goblins:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height)
|
||||
mobs_goblins:register_spawn("mobs_goblins:goblin_cobble", {"group:stone"}, 1000, 0, 200, 1, 1)
|
||||
mobs_goblins:register_spawn("mobs_goblins:goblin_cobble", {"group:stone"}, 1000, 0, 50, 1, 1)
|
||||
mobs_goblins:register_spawn("mobs_goblins:goblin_digger", {"group:stone"}, 1000, 0, 50, 1, 1)
|
||||
mobs_goblins:register_spawn("mobs_goblins:goblin_coal", {"default:torch", "default:coal", "default:mossycobble"}, 1000, 0, 30, 1, 1)
|
||||
mobs_goblins:register_spawn("mobs_goblins:goblin_iron", {"default:stone_with_iron","default:mossycobble",}, 10, 0, 30, 1, 1)
|
||||
mobs_goblins:register_spawn("mobs_goblins:goblin_gold", {"default:stone_with_gold","default:mossycobble", }, 10, 0, 30, 1, 1)
|
||||
mobs_goblins:register_spawn("mobs_goblins:goblin_diamond", {"default:stone_with_diamond","default:mossycobble", }, 30, 0, 100, 1, 1)
|
||||
mobs_goblins:register_spawn("mobs_goblins:goblin_king", {"default:stone_with_mese","default:mossycobble", }, 10, 0, 300, 1, 1)
|
||||
mobs_goblins:register_egg("mobs_goblins:goblin_coal", "goblin egg", "default:stone_with_coal", 1)
|
||||
mobs_goblins:register_egg("mobs_goblins:goblin_cobble", "goblin egg", "default:mossycobble", 1)
|
||||
|
|
|
@ -3,8 +3,6 @@ local path = minetest.get_modpath("mobs_goblins")
|
|||
-- Mob Api
|
||||
|
||||
dofile(path.."/api.lua")
|
||||
|
||||
|
||||
dofile(path.."/goblins.lua") -- TenPlus1 and FreeLikeGNU
|
||||
|
||||
|
||||
|
|
|
@ -52,8 +52,6 @@ minetest.register_abm({ -- Controls non-contained fire
|
|||
item_percent = math.floor(src_time / cooked.time * 100)
|
||||
item_state = item_percent .. "%"
|
||||
end
|
||||
|
||||
meta:set_string("formspec", more_fire.fire_formspec(item_percent))
|
||||
|
||||
local fuel = nil
|
||||
local cooked = nil
|
||||
|
@ -78,6 +76,7 @@ minetest.register_abm({ -- Controls non-contained fire
|
|||
local stack = inv:get_stack("fuel", 1)
|
||||
stack:take_item()
|
||||
inv:set_stack("fuel", 1, stack)
|
||||
meta:set_string("formspec", more_fire.fire_formspec(item_percent))
|
||||
end,
|
||||
})
|
||||
|
||||
|
@ -136,8 +135,6 @@ minetest.register_abm({ -- Controls the contained fires.
|
|||
item_percent = math.floor(src_time / cooked.time * 100)
|
||||
item_state = item_percent .. "%"
|
||||
end
|
||||
|
||||
meta:set_string("formspec", more_fire.fire_formspec(item_percent))
|
||||
|
||||
local fuel = nil
|
||||
local cooked = nil
|
||||
|
@ -162,6 +159,7 @@ minetest.register_abm({ -- Controls the contained fires.
|
|||
local stack = inv:get_stack("fuel", 1)
|
||||
stack:take_item()
|
||||
inv:set_stack("fuel", 1, stack)
|
||||
meta:set_string("formspec", more_fire.fire_formspec(item_percent))
|
||||
end,
|
||||
})
|
||||
|
||||
|
|
|
@ -30,6 +30,14 @@ minetest.register_craft({
|
|||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'more_fire:embers 1',
|
||||
recipe = {
|
||||
{'group:flammable', 'default:torch', 'group:flammable'},
|
||||
{'group:wood', 'group:wood', 'group:wood'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'more_fire:embers_contained 1',
|
||||
recipe = {
|
||||
|
@ -67,6 +75,12 @@ minetest.register_craft({
|
|||
recipe = {'group:kindling', 'group:wood', 'group:kindling', 'group:kindling', 'group:kindling'},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = 'shapeless',
|
||||
output = 'more_fire:kindling 1',
|
||||
recipe = {'group:flammable', 'group:wood', 'group:flammable', 'group:flammable', 'group:flammable'},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'more_fire:kindling_contained 1',
|
||||
recipe = {
|
||||
|
|
|
@ -25,6 +25,21 @@ function more_fire.fire_formspec(item_percent)
|
|||
return formspec
|
||||
end
|
||||
|
||||
more_fire.embers_formspec =
|
||||
'size[8,6.75]'..
|
||||
default.gui_slots..
|
||||
'listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF]'..
|
||||
'background[8,6.75;0,0;more_fire_campfire_bg.png;true]'..
|
||||
'label[2,.75;< Add More Wood]'..
|
||||
'label[1.25,2; Cook Something >]'..
|
||||
'list[current_name;fuel;1,.5;1,1;]'..
|
||||
'list[current_name;src;4,1.75;1,1;]'..
|
||||
'image[5,1.75;1,1;gui_furnace_arrow_bg.png^[transformR270]'..
|
||||
'list[current_name;dst;6,1.75;2,1;]'..
|
||||
'list[current_player;main;0,2.75;8,1;]'..
|
||||
'list[current_player;main;0,4;8,3;8]'..
|
||||
default.get_hotbar_bg(0,2.75)
|
||||
|
||||
function burn(pointed_thing) --kindling doesn't always start from the first spark
|
||||
local ignite_chance = math.random(5)
|
||||
if ignite_chance == 1
|
||||
|
|
|
@ -7,21 +7,6 @@ default.gui_slots = 'listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF]'
|
|||
|
||||
more_fire = {}
|
||||
|
||||
-- formspecs
|
||||
more_fire.embers_formspec =
|
||||
'size[8,6.75]'..
|
||||
default.gui_slots..
|
||||
'listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF]'..
|
||||
'background[8,6.75;0,0;more_fire_campfire_bg.png;true]'..
|
||||
'label[2,.75;< Add More Wood]'..
|
||||
'label[1.25,2; Cook Something >]'..
|
||||
'list[current_name;fuel;1,.5;1,1;]'..
|
||||
'list[current_name;src;4,1.75;1,1;]'..
|
||||
'image[5,1.75;1,1;gui_furnace_arrow_bg.png^[transformR270]'..
|
||||
'list[current_name;dst;6,1.75;2,1;]'..
|
||||
'list[current_player;main;0,2.75;8,1;]'..
|
||||
'list[current_player;main;0,4;8,3;8]'..
|
||||
default.get_hotbar_bg(0,2.75)
|
||||
|
||||
dofile(minetest.get_modpath('more_fire')..'/config.txt')
|
||||
dofile(minetest.get_modpath('more_fire')..'/functions.lua')
|
||||
|
|
After Width: | Height: | Size: 489 B |
|
@ -0,0 +1 @@
|
|||
pathogen
|
|
@ -0,0 +1,43 @@
|
|||
pathogen.register_pathogen("food_poisoning", {
|
||||
description = "Symptoms include vomiting and loss of health.",
|
||||
symptoms = 10,
|
||||
latent_period = 120,
|
||||
infection_period = 420,
|
||||
on_infect = function( infection )
|
||||
local _player = minetest.get_player_by_name( infection.player )
|
||||
local _pos = _player:getpos()
|
||||
minetest.sound_play( "pathogen_cough", { pos = _pos, gain = 0.3 } )
|
||||
end,
|
||||
on_symptom = function( infection )
|
||||
local player = minetest.get_player_by_name( infection.player )
|
||||
local pos = player:getpos()
|
||||
local burp = function()
|
||||
if math.random(2) == 1 then
|
||||
return 'pathogen_burp_1'
|
||||
else
|
||||
return 'pathogen_burp_2'
|
||||
end
|
||||
end
|
||||
local contaminate = function( pos )
|
||||
local contaminate_pos = {
|
||||
x = pos.x + math.random( -5,5 ),
|
||||
y = pos.y + math.random( -5,5 ),
|
||||
z = pos.z + math.random( -5,5 )
|
||||
}
|
||||
pathogen.contaminate( contaminate_pos )
|
||||
end
|
||||
local hp = player:get_hp()
|
||||
if hp <= 5 then
|
||||
player:set_hp( hp - 1 )
|
||||
end
|
||||
if math.random(25) == 1 then
|
||||
pathogen.spawn_fluid( "feces", pos, infection.pathogen )
|
||||
minetest.sound_play( "pathogen_poop", { pos = pos, gain = 0.3} )
|
||||
else
|
||||
minetest.sound_play( burp(), { pos = pos, gain = 0.3 } )
|
||||
end
|
||||
for i=0,3 do
|
||||
contaminate( pos )
|
||||
end
|
||||
end
|
||||
})
|
|
@ -1,4 +0,0 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
See http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
@ -1,53 +0,0 @@
|
|||
# Valleys Mapgen
|
||||
Mapgen mod for Minetest 0.4.12+. Work in progress, not finished.
|
||||
|
||||
![Screenshot](http://i.imgur.com/A6CBuaV.png)
|
||||
|
||||
[Discussion on Minetest Forums](https://forum.minetest.net/viewtopic.php?f=9&t=11430)
|
||||
|
||||
## Changelog
|
||||
### 2.1 ~> Latest
|
||||
* Added flowers (6 species)
|
||||
|
||||
### 2.0 ~> 2.1 (Saturday July 4, 2015)
|
||||
* Modified conditions for desert plants
|
||||
* Added pine tree
|
||||
* Generate special water in rivers
|
||||
* Changed valley shape a bit (no more cliffs on the sides of the rivers)
|
||||
* Changed river shape (smooth floor)
|
||||
|
||||
### 1.3 ~> 2.0 (Sunday May 31, 2015)
|
||||
* Added plants, optionnal, enabled by default
|
||||
* Corrected math.random too large interval (2³² → 2²⁴)
|
||||
* Added snow
|
||||
* When a player dies, it's respawned
|
||||
* Adapted to any `chunksize` (previously the mod was only working for 5)
|
||||
* Added trees (3 species for now), optionnal, enabled by default
|
||||
* Added logs : see vmg.conf.example
|
||||
* Added temperature and humidity noises, used by trees
|
||||
* Changed parameters for lava
|
||||
|
||||
### 1.2 ~> 1.3 (Wednesday April 8, 2015)
|
||||
* Added differents types of dirts (the aim is to make real biomes in the future)
|
||||
* Added beaches
|
||||
* Added setting `water_level` to set water level (default is 1)
|
||||
* Fixed fatal error with number settings
|
||||
|
||||
### 1.1 ~> 1.2 (Tuesday March 17, 2015)
|
||||
* Added lava underground
|
||||
* Settings in minetest.conf : see file vmg.conf.example
|
||||
* Now the player can't spawn in rivers
|
||||
* Player spawn location is randomized : you can set the maximal distance from (0;0) at which the player will appear. (If it's in a big ocean, it may be farther)
|
||||
* Some minor changes about terrain :
|
||||
* Bare stone is rarer
|
||||
* Valleys are slightly larger
|
||||
* Ores are generated properly, according to [Paramat's changes](https://github.com/minetest/minetest/commit/b2b6bbf3e80f0ab06d62c43567122871ae560534) in `minetest.generate_ores`. **I advise you to update your MT version to a recent build (03/11 or later) or the ores overlapping problem will reappear.**
|
||||
|
||||
### 1.0 ~> 1.1 (Sunday March 8, 2015)
|
||||
* Added caves: they are modelised by 4 3D noises.
|
||||
* Corrected ores generation: There was too many ores because it was sometimes generated twice or even more.
|
||||
* Activated versions manager: if you update the mod from 1.0 to this version, the new mapgen will only take effect on new worlds, worlds created with 1.0 will stay in 1.0. If you want to activate mapgen 1.1 in an old world (there could be cleavages), change the file vmg.conf which is in the world directory.
|
||||
* Added… this changelog :-D
|
||||
|
||||
### 1.0 (Saturday March 7, 2015)
|
||||
* Created mapgen (using 7 noises at the moment).
|
|
@ -1,2 +0,0 @@
|
|||
default
|
||||
flowers
|
|
@ -1,91 +0,0 @@
|
|||
vmg = {}
|
||||
vmg.version = "2.2"
|
||||
|
||||
vmg.path = minetest.get_modpath("valleys_mapgen")
|
||||
|
||||
vmg.loglevel = tonumber(minetest.setting_get("vmg_log_level") or 0)
|
||||
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Loading basic functions ...")
|
||||
end
|
||||
|
||||
minetest.register_on_mapgen_init(function(mgparams)
|
||||
minetest.set_mapgen_params({mgname="singlenode", flags="nolight"})
|
||||
end)
|
||||
|
||||
if default then
|
||||
if default.register_ores then
|
||||
default.register_ores()
|
||||
end
|
||||
if default.register_blobs then
|
||||
default.register_blobs()
|
||||
end
|
||||
end
|
||||
|
||||
function pos2d(pos)
|
||||
if type(pos) == "number" then
|
||||
return {x = pos, y = pos}
|
||||
elseif pos.z then
|
||||
return {x = pos.x, y = pos.z}
|
||||
else
|
||||
return {x = pos.x, y = pos.y}
|
||||
end
|
||||
end
|
||||
|
||||
function pos3d(pos, alt)
|
||||
alt = alt or 0
|
||||
if type(pos) == "number" then
|
||||
return {x = pos, y = pos, z = pos}
|
||||
elseif pos.z then
|
||||
return {x = pos.x, y = pos.z, z = pos.z}
|
||||
else
|
||||
return {x = pos.x, y = alt, z = pos.y}
|
||||
end
|
||||
end
|
||||
|
||||
function minetest.add_group(node, groups)
|
||||
local def = minetest.registered_items[node]
|
||||
if not def then
|
||||
return false
|
||||
end
|
||||
local def_groups = def.groups or {}
|
||||
for group, value in pairs(groups) do
|
||||
if value ~= 0 then
|
||||
def_groups[group] = value
|
||||
else
|
||||
def_groups[group] = nil
|
||||
end
|
||||
end
|
||||
minetest.override_item(node, {groups = def_groups})
|
||||
return true
|
||||
end
|
||||
|
||||
function displaytime(time)
|
||||
return math.floor(time * 1000000 + 0.5) / 1000 .. " ms"
|
||||
end
|
||||
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Loading settings API ...")
|
||||
end
|
||||
|
||||
dofile(vmg.path .. "/settings.lua")
|
||||
|
||||
if vmg.define("spawn", true) then
|
||||
minetest.register_on_newplayer(vmg.spawnplayer)
|
||||
end
|
||||
|
||||
if vmg.define("respawn", true) then
|
||||
minetest.register_on_respawnplayer(vmg.spawnplayer)
|
||||
end
|
||||
|
||||
minetest.register_on_generated(vmg.generate)
|
||||
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Loading nodes ...")
|
||||
end
|
||||
|
||||
dofile(vmg.path .. "/nodes.lua")
|
||||
|
||||
if vmg.loglevel >= 1 then
|
||||
print("[Valleys Mapgen] Loaded !")
|
||||
end
|
|
@ -1,552 +0,0 @@
|
|||
-- Mapgen 2.2
|
||||
-- Monday July 6, 2015
|
||||
|
||||
vmg.noises = {
|
||||
|
||||
-- Noise 1 : Base Ground Height 2D
|
||||
{offset = -10, scale = 50, seed = 5202, spread = {x = 1024, y = 1024, z = 1024}, octaves = 6, persist = 0.4, lacunarity = 2},
|
||||
|
||||
-- Noise 2 : Valleys (River where around zero) 2D
|
||||
{offset = 0, scale = 1, seed = -6050, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.6, lacunarity = 2},
|
||||
|
||||
-- Noise 3 : Valleys Depth 2D
|
||||
{offset = 5, scale = 4, seed = -1914, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2},
|
||||
|
||||
-- Noise 4 : Valleys Profile (Higher values = Larger valleys) 2D
|
||||
{offset = 0.6, scale = 0.5, seed = 777, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2},
|
||||
|
||||
-- Noise 5 : Inter-valleys slopes 2D
|
||||
{offset = 0.5, scale = 0.5, seed = 746, spread = {x = 128, y = 128, z = 128}, octaves = 1, persist = 1, lacunarity = 2},
|
||||
|
||||
-- Noise 6 : Inter-valleys filling 3D
|
||||
{offset = 0, scale = 1, seed = 1993, spread = {x = 256, y = 512, z = 256}, octaves = 6, persist = 0.8, lacunarity = 2},
|
||||
|
||||
-- Noise 7 : Dirt thickness 2D
|
||||
{offset = 3, scale = 1.75, seed = 1605, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 8 : Caves I 3D
|
||||
{offset = 0, scale = 1, seed = -4640, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 9 : Caves II 3D
|
||||
{offset = 0, scale = 1, seed = 8804, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 10 : Caves III 3D
|
||||
{offset = 0, scale = 1, seed = -4780, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 11 : Caves IV and Lava I 3D
|
||||
{offset = 0, scale = 1, seed = -9969, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 12 : Lava II (Geologic heat) 3D
|
||||
{offset = 0, scale = 1, seed = 3314, spread = {x = 64, y = 64, z = 64}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 13 : Clayey dirt noise 2D
|
||||
{offset = 0, scale = 1, seed = 2835, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4},
|
||||
|
||||
-- Noise 14 : Silty dirt noise 2D
|
||||
{offset = 0, scale = 1, seed = 6674, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4},
|
||||
|
||||
-- Noise 15 : Sandy dirt noise 2D
|
||||
{offset = 0, scale = 1, seed = 6940, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4},
|
||||
|
||||
-- Noise 16 : Beaches 2D
|
||||
{offset = 2, scale = 8, seed = 2349, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 17 : Temperature (not in maps) 3D
|
||||
{offset = 2, scale = 1, seed = -1805, spread = {x = 768, y = 256, z = 768}, octaves = 4, persist = 0.5, lacunarity = 4},
|
||||
|
||||
-- Noise 18 : Humidity 2D
|
||||
{offset = 0, scale = 1, seed = -5787, spread = {x = 243, y = 243, z = 243}, octaves = 4, persist = 0.5, lacunarity = 3},
|
||||
|
||||
}
|
||||
|
||||
function vmg.noisemap(i, minp, chulens)
|
||||
local obj = minetest.get_perlin_map(vmg.noises[i], chulens)
|
||||
if minp.z then
|
||||
return obj:get3dMap_flat(minp)
|
||||
else
|
||||
return obj:get2dMap_flat(minp)
|
||||
end
|
||||
end
|
||||
|
||||
for i, n in ipairs(vmg.noises) do
|
||||
vmg.noises[i] = vmg.define("noise_" .. i, n)
|
||||
end
|
||||
|
||||
vmg.after_mapgen = {}
|
||||
|
||||
function vmg.register_after_mapgen(f, ...)
|
||||
table.insert(vmg.after_mapgen, {f = f, ...})
|
||||
end
|
||||
|
||||
function vmg.execute_after_mapgen()
|
||||
for i, params in ipairs(vmg.after_mapgen) do
|
||||
params.f(unpack(params))
|
||||
end
|
||||
vmg.after_mapgen = {}
|
||||
end
|
||||
|
||||
local river_depth = vmg.define("river_depth", 3) + 1
|
||||
local river_size = vmg.define("river_size", 5) / 100
|
||||
local caves_size = vmg.define("caves_size", 7) / 100
|
||||
local lava_depth = vmg.define("lava_depth", 2000)
|
||||
local lava_max_height = vmg.define("lava_max_height", -1)
|
||||
local altitude_chill = vmg.define("altitude_chill", 90)
|
||||
|
||||
local average_stone_level = vmg.define("average_stone_level", 180)
|
||||
local dirt_thickness = math.sqrt(average_stone_level) / (vmg.noises[7].offset + 0.5)
|
||||
local average_snow_level = vmg.define("average_snow_level", 100)
|
||||
local snow_threshold = vmg.noises[17].offset * 0.5 ^ (average_snow_level / altitude_chill)
|
||||
|
||||
local player_max_distance = vmg.define("player_max_distance", 450)
|
||||
|
||||
local clay_threshold = vmg.define("clay_threshold", 1)
|
||||
local silt_threshold = vmg.define("silt_threshold", 1)
|
||||
local sand_threshold = vmg.define("sand_threshold", 0.75)
|
||||
local dirt_threshold = vmg.define("dirt_threshold", 0.5)
|
||||
|
||||
local tree_density = vmg.define("tree_density", 5) / 100
|
||||
local trees = vmg.define("trees", true)
|
||||
local plant_density = vmg.define("plant_density", 32) / 100
|
||||
local plants = vmg.define("plants", true)
|
||||
|
||||
local water_level = vmg.define("water_level", 1)
|
||||
local river_water = vmg.define("river_water", true)
|
||||
|
||||
function vmg.generate(minp, maxp, seed)
|
||||
local minps, maxps = minetest.pos_to_string(minp), minetest.pos_to_string(maxp)
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Preparing to generate map from " .. minps .. " to " .. maxps .. " ...")
|
||||
elseif vmg.loglevel == 1 then
|
||||
print("[Valleys Mapgen] Generating map from " .. minps .. " to " .. maxps .. " ...")
|
||||
end
|
||||
local t0 = os.clock()
|
||||
|
||||
local c_stone = minetest.get_content_id("default:stone")
|
||||
local c_dirt = minetest.get_content_id("default:dirt")
|
||||
local c_lawn = minetest.get_content_id("default:dirt_with_grass")
|
||||
local c_snow = minetest.get_content_id("default:dirt_with_snow")
|
||||
local c_dirt_clay = minetest.get_content_id("valleys_mapgen:dirt_clayey")
|
||||
local c_lawn_clay = minetest.get_content_id("valleys_mapgen:dirt_clayey_with_grass")
|
||||
local c_snow_clay = minetest.get_content_id("valleys_mapgen:dirt_clayey_with_snow")
|
||||
local c_dirt_silt = minetest.get_content_id("valleys_mapgen:dirt_silty")
|
||||
local c_lawn_silt = minetest.get_content_id("valleys_mapgen:dirt_silty_with_grass")
|
||||
local c_snow_silt = minetest.get_content_id("valleys_mapgen:dirt_silty_with_snow")
|
||||
local c_dirt_sand = minetest.get_content_id("valleys_mapgen:dirt_sandy")
|
||||
local c_lawn_sand = minetest.get_content_id("valleys_mapgen:dirt_sandy_with_grass")
|
||||
local c_snow_sand = minetest.get_content_id("valleys_mapgen:dirt_sandy_with_snow")
|
||||
local c_desert_sand = minetest.get_content_id("default:desert_sand")
|
||||
local c_sand = minetest.get_content_id("default:sand")
|
||||
local c_gravel = minetest.get_content_id("default:gravel")
|
||||
local c_silt = minetest.get_content_id("valleys_mapgen:silt")
|
||||
local c_clay = minetest.get_content_id("valleys_mapgen:red_clay")
|
||||
local c_water = minetest.get_content_id("default:water_source")
|
||||
local c_riverwater = minetest.get_content_id("default:river_water_source")
|
||||
local c_lava = minetest.get_content_id("default:lava_source")
|
||||
local c_snow_layer = minetest.get_content_id("default:snow")
|
||||
|
||||
local c_tree = minetest.get_content_id("default:tree")
|
||||
local c_leaves = minetest.get_content_id("default:leaves")
|
||||
local c_apple = minetest.get_content_id("default:apple")
|
||||
local c_jungletree = minetest.get_content_id("default:jungletree")
|
||||
local c_jungleleaves = minetest.get_content_id("default:jungleleaves")
|
||||
local c_pinetree = minetest.get_content_id("default:pinetree")
|
||||
local c_pineleaves = minetest.get_content_id("default:pine_needles")
|
||||
local c_firtree = minetest.get_content_id("valleys_mapgen:fir_tree")
|
||||
local c_firleaves = minetest.get_content_id("valleys_mapgen:fir_needles")
|
||||
|
||||
local c_grass = {
|
||||
minetest.get_content_id("default:grass_1"),
|
||||
minetest.get_content_id("default:grass_2"),
|
||||
minetest.get_content_id("default:grass_3"),
|
||||
minetest.get_content_id("default:grass_4"),
|
||||
minetest.get_content_id("default:grass_5"),
|
||||
}
|
||||
local c_junglegrass = minetest.get_content_id("default:junglegrass")
|
||||
local c_dryshrub = minetest.get_content_id("default:dry_shrub")
|
||||
local c_cactus = minetest.get_content_id("default:cactus")
|
||||
local c_papyrus = minetest.get_content_id("default:papyrus")
|
||||
local c_geranium = minetest.get_content_id("flowers:geranium")
|
||||
local c_rose = minetest.get_content_id("flowers:rose")
|
||||
local c_tulip = minetest.get_content_id("flowers:tulip")
|
||||
local c_viola = minetest.get_content_id("flowers:viola")
|
||||
local c_dandelion_white = minetest.get_content_id("flowers:dandelion_white")
|
||||
local c_dandelion_yellow = minetest.get_content_id("flowers:dandelion_yellow")
|
||||
|
||||
local c_air = minetest.get_content_id("air")
|
||||
local c_ignore = minetest.get_content_id("ignore")
|
||||
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local data = vm:get_data()
|
||||
local a = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local ystride = a.ystride
|
||||
|
||||
local chulens = vector.add(vector.subtract(maxp, minp), 1)
|
||||
local chulens_sup = {x = chulens.x, y = chulens.y + 6, z = chulens.z}
|
||||
local minp2d = pos2d(minp)
|
||||
|
||||
local t1 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Mapgen preparation finished in " .. displaytime(t1-t0))
|
||||
print("[Valleys Mapgen] Calculating noises ...")
|
||||
end
|
||||
|
||||
local n1 = vmg.noisemap(1, minp2d, chulens)
|
||||
local n2 = vmg.noisemap(2, minp2d, chulens)
|
||||
local n3 = vmg.noisemap(3, minp2d, chulens)
|
||||
local n4 = vmg.noisemap(4, minp2d, chulens)
|
||||
local n5 = vmg.noisemap(5, minp2d, chulens)
|
||||
local n6 = vmg.noisemap(6, minp, chulens_sup)
|
||||
local n7 = vmg.noisemap(7, minp2d, chulens)
|
||||
local n8 = vmg.noisemap(8, minp, chulens)
|
||||
local n9 = vmg.noisemap(9, minp, chulens)
|
||||
local n10 = vmg.noisemap(10, minp, chulens)
|
||||
local n11 = vmg.noisemap(11, minp, chulens)
|
||||
local n12 = vmg.noisemap(12, minp, chulens)
|
||||
local n13 = vmg.noisemap(13, minp2d, chulens)
|
||||
local n14 = vmg.noisemap(14, minp2d, chulens)
|
||||
local n15 = vmg.noisemap(15, minp2d, chulens)
|
||||
local n16 = vmg.noisemap(16, minp2d, chulens)
|
||||
local n18 = vmg.noisemap(18, minp2d, chulens)
|
||||
|
||||
local t2 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Noises calculation finished in " .. displaytime(t2-t1))
|
||||
print("[Valleys Mapgen] Collecting data ...")
|
||||
end
|
||||
|
||||
local i2d = 1 -- index for 2D noises
|
||||
local i3d_sup = 1 -- index for noise 6 which has a special size
|
||||
local i3d = 1 -- index for 3D noises
|
||||
|
||||
-- Calculate increments
|
||||
local i2d_incrZ = chulens.z
|
||||
local i2d_decrX = chulens.x * chulens.z - 1
|
||||
local i3d_incrY = chulens.y
|
||||
local i3d_sup_incrZ = 6 * chulens.y
|
||||
local i3d_decrX = chulens.x * chulens.y * chulens.z - 1
|
||||
local i3d_sup_decrX = chulens.x * (chulens.y + 6) * chulens.z - 1
|
||||
|
||||
for x = minp.x, maxp.x do -- for each YZ plane
|
||||
for z = minp.z, maxp.z do -- for each vertical line in this plane
|
||||
local v1, v2, v3, v4, v5, v7, v13, v14, v15, v16, v18 = n1[i2d], n2[i2d], n3[i2d], n4[i2d], n5[i2d], n7[i2d], n13[i2d], n14[i2d], n15[i2d], n16[i2d], n18[i2d] -- n for noise, v for value
|
||||
v3 = v3 ^ 2 -- v3 must be > 0 and by the square there are high mountains but the median valleys depth is small.
|
||||
local base_ground = v1 + v3 -- v3 is here because terrain is generally higher when valleys are deep (mountains)
|
||||
v2 = math.abs(v2) - river_size
|
||||
local river = v2 < 0
|
||||
local valleys = v3 * (1 - math.exp(- (v2 / v4) ^ 2)) -- use the curve of the function 1−exp(−(x/a)²) to modelise valleys. Making "a" varying 0 < a ≤ 1 will change the shape of the valleys. Try it with a geometry software ! (here x = v2 and a = v4)
|
||||
local mountain_ground = base_ground + valleys
|
||||
local slopes = v5 * valleys
|
||||
|
||||
if river then
|
||||
local depth = river_depth * math.sqrt(1 - (v2 / river_size + 1) ^ 2) -- use the curve of the function −sqrt(1-x²) which modelizes a circle.
|
||||
mountain_ground = math.min(math.max(base_ground - depth, water_level - 6), mountain_ground)
|
||||
slopes = 0
|
||||
end
|
||||
|
||||
-- Choose biome
|
||||
local dirt = c_dirt
|
||||
local lawn = c_lawn
|
||||
local snow = c_snow
|
||||
local max = math.max(v13, v14, v15) -- the biome is the maximal of these 3 values, if bigger than 0.5. Else, make normal dirt.
|
||||
if max > dirt_threshold then
|
||||
if v13 == max then
|
||||
if v13 > clay_threshold then
|
||||
dirt = c_clay
|
||||
lawn = c_clay
|
||||
snow = c_clay
|
||||
else
|
||||
dirt = c_dirt_clay
|
||||
lawn = c_lawn_clay
|
||||
snow = c_snow_clay
|
||||
end
|
||||
elseif v14 == max then
|
||||
if v14 > silt_threshold then
|
||||
dirt = c_silt
|
||||
lawn = c_silt
|
||||
snow = c_silt
|
||||
else
|
||||
dirt = c_dirt_silt
|
||||
lawn = c_lawn_silt
|
||||
snow = c_snow_silt
|
||||
end
|
||||
else
|
||||
if v15 > sand_threshold then
|
||||
dirt = c_desert_sand
|
||||
lawn = c_desert_sand
|
||||
snow = c_desert_sand
|
||||
else
|
||||
dirt = c_dirt_sand
|
||||
lawn = c_lawn_sand
|
||||
snow = c_snow_sand
|
||||
end
|
||||
end
|
||||
end
|
||||
local is_beach = v15 > 0 and v16 > 0
|
||||
local beach = v15 * v16 + water_level -- the y coordinate below which dirt is replaced by beach sand
|
||||
|
||||
-- raw humidity
|
||||
local hraw = 2 ^ (v13 - v15 + v18 * 2)
|
||||
|
||||
for y = minp.y, maxp.y do -- for each node in vertical line
|
||||
local ivm = a:index(x, y, z)
|
||||
local v6, v8, v9, v10, v11, v12 = n6[i3d_sup], n8[i3d], n9[i3d], n10[i3d], n11[i3d], n12[i3d]
|
||||
local is_cave = v8 ^ 2 + v9 ^ 2 + v10 ^ 2 + v11 ^ 2 < caves_size
|
||||
if v6 * slopes > y - mountain_ground then -- if pos is in the ground
|
||||
if not is_cave then
|
||||
local thickness = v7 - math.sqrt(math.abs(y)) / dirt_thickness
|
||||
local above = math.ceil(thickness + math.random()) -- The following code will look for air at this many nodes up. If any, make dirt, else, make stone. So, it's the dirt layer thickness.
|
||||
|
||||
if y >= water_level and n6[i3d_sup+i3d_incrY] * slopes <= y + 1 - mountain_ground and not river then
|
||||
if is_beach and y < beach then
|
||||
data[ivm] = c_sand
|
||||
else -- if node above is not in the ground, place lawn
|
||||
|
||||
-- calculate humidity
|
||||
local sea_water = 0.5 ^ math.max((y - water_level) / 6, 0)
|
||||
local river_water = 0.5 ^ math.max((y - base_ground) / 3, 0)
|
||||
local water = sea_water + (1 - sea_water) * river_water
|
||||
local humidity = hraw + water
|
||||
|
||||
local ivm2 = ivm + ystride
|
||||
y = y + 1
|
||||
local pos = {x = x, y = y, z = z}
|
||||
|
||||
local v17 = vmg.get_noise(pos, 17)
|
||||
local temp -- calculate_temperature for node above
|
||||
if y > 0 then
|
||||
temp = v17 * 0.5 ^ (y / altitude_chill)
|
||||
else
|
||||
temp = v17 * 0.5 ^ (-y / altitude_chill) + 20 * (v12 + 1) * (1 - 2 ^ (y / lava_depth))
|
||||
end
|
||||
|
||||
if temp > snow_threshold then
|
||||
if above > 0 then
|
||||
data[ivm] = lawn
|
||||
else
|
||||
data[ivm] = c_stone
|
||||
end
|
||||
else
|
||||
if above > 0 then
|
||||
data[ivm] = snow
|
||||
else
|
||||
data[ivm] = c_stone
|
||||
end
|
||||
data[ivm2] = c_snow_layer -- set node above to snow
|
||||
end
|
||||
|
||||
if trees and math.random() < tree_density and above > 0 then -- make a tree
|
||||
|
||||
-- choose a tree from climatic and geological conditions
|
||||
if v14 < 0 and temp < 1.5 and temp >= 0.90 and humidity < 1 and v15 < 0.8 and math.abs(v13) < 0.2 and math.random() < 0.3 then -- Pine Tree
|
||||
local rand = math.random()
|
||||
local height = math.floor(9 + 6 * rand)
|
||||
local radius = 4 + 2 * rand
|
||||
vmg.make_pine_tree(pos, data, a, height, radius, c_pinetree, c_pineleaves, c_air, c_ignore)
|
||||
elseif v15 < 0.6 and temp >= 0.85 and temp < 2.3 and humidity < 3 and v16 < 2 and v14 > -0.5 and v13 < 0.8 then -- Apple Tree
|
||||
local rand = math.random()
|
||||
local height = math.floor(4 + 2.5 * rand)
|
||||
local radius = 3 + rand
|
||||
if math.random(1, 4) == 1 then
|
||||
vmg.make_apple_tree(pos, data, a, height, radius, c_tree, c_leaves, c_apple, c_air, c_ignore)
|
||||
else
|
||||
vmg.make_tree(pos, data, a, height, radius, c_tree, c_leaves, c_air, c_ignore)
|
||||
end
|
||||
elseif v15 < 0.7 and temp >= 1.9 and humidity > 2 and v16 > 2 then -- Jungle Tree
|
||||
local rand = math.random()
|
||||
local height = math.floor(8 + 4 * rand)
|
||||
local radius = 5 + 3 * rand
|
||||
vmg.make_jungle_tree(pos, data, a, height, radius, c_jungletree, c_jungleleaves, c_air, c_ignore)
|
||||
elseif temp > 0.38 and temp < 1 and humidity > 0.9 and v15 > 0 and v15 < 0.55 then -- Fir Tree
|
||||
local rand = math.random()
|
||||
local height = math.floor(9 + 6 * rand)
|
||||
local radius = 4 + 2 * rand
|
||||
vmg.make_fir_tree(pos, data, a, height, radius, c_firtree, c_firleaves, c_air, c_ignore)
|
||||
end
|
||||
elseif plants and math.random() < plant_density and above > 0 then -- make a plant
|
||||
if temp > 1 and temp < 1.8 and water > 0.7 and humidity > 3 and v13 > -0.4 and math.random() < 0.04 then -- Papyrus
|
||||
for i = 1, 4 do
|
||||
data[ivm+i*ystride] = c_papyrus
|
||||
end
|
||||
elseif v15 < 0.65 and temp >= 0.65 and temp < 1.5 and humidity < 2.6 and v16 < 1.5 and v13 < 0.8 and math.random() < 0.7 then -- Grass
|
||||
data[ivm2] = c_grass[math.random(1, 5)]
|
||||
elseif v15 > -0.6 and temp >= 1.8 and humidity > 2.2 and v16 > 1.8 then -- Jungle Grass
|
||||
data[ivm2] = c_junglegrass
|
||||
elseif v15 > 0.65 and humidity < 0.5 and math.random() < 0.2 then
|
||||
if v16 > 0 and temp > 1.6 and math.random() < 0.12 then -- Cactus
|
||||
for i = 1, 4 do
|
||||
data[ivm+i*ystride] = c_cactus
|
||||
end
|
||||
elseif temp > 1.2 then -- Dry Shrub
|
||||
data[ivm2] = c_dryshrub
|
||||
end
|
||||
elseif math.random() < 0.04 and temp > 0.98 and temp < 1.8 and humidity < 1.7 and v14 >= -0.1 and v15 < 0.4 and v15 >= -0.6 and v13 < 0.82 then -- Flowers
|
||||
if temp > 1.2 and math.random() < 0.3 then
|
||||
data[ivm2] = c_rose
|
||||
elseif thickness <= 1.3 and math.random() < 0.4 then
|
||||
data[ivm2] = c_geranium
|
||||
elseif v16 < 1.6 and math.random() < 0.7 then
|
||||
data[ivm2] = c_viola
|
||||
elseif temp > 1.3 and humidity < 1.5 and math.random() < 0.2 then
|
||||
data[ivm2] = c_tulip
|
||||
elseif math.random() < 0.5 then
|
||||
data[ivm2] = c_dandelion_white
|
||||
else
|
||||
data[ivm2] = c_dandelion_yellow
|
||||
end
|
||||
end
|
||||
end
|
||||
y = y - 1
|
||||
end
|
||||
elseif above <= 0 then
|
||||
data[ivm] = c_stone
|
||||
elseif n6[i3d_sup+above*i3d_incrY] * slopes <= y + above - mountain_ground then -- if node at "above" nodes up is not in the ground, make dirt
|
||||
if is_beach and y < beach then
|
||||
data[ivm] = c_sand
|
||||
else
|
||||
data[ivm] = dirt
|
||||
end
|
||||
else
|
||||
data[ivm] = c_stone
|
||||
end
|
||||
elseif v11 + v12 > 2 ^ (y / lava_depth) and y <= lava_max_height then
|
||||
data[ivm] = c_lava
|
||||
end
|
||||
elseif y <= water_level then -- if pos is not in the ground, and below water_level, it's an ocean
|
||||
data[ivm] = c_water
|
||||
elseif river and y + 1 < base_ground then
|
||||
if river_water then
|
||||
data[ivm] = c_riverwater
|
||||
else
|
||||
data[ivm] = c_water
|
||||
end
|
||||
end
|
||||
|
||||
i3d = i3d + i3d_incrY -- increment i3d by one line
|
||||
i3d_sup = i3d_sup + i3d_incrY -- idem
|
||||
end
|
||||
i2d = i2d + i2d_incrZ -- increment i2d by one Z
|
||||
-- useless to increment i3d, because increment would be 0 !
|
||||
i3d_sup = i3d_sup + i3d_sup_incrZ -- for i3d_sup, just avoid the 6 supplemental lines
|
||||
end
|
||||
i2d = i2d - i2d_decrX -- decrement the Z line previously incremented and increment by one X (1)
|
||||
i3d = i3d - i3d_decrX -- decrement the YZ plane previously incremented and increment by one X (1)
|
||||
i3d_sup = i3d_sup - i3d_sup_decrX -- idem, including the supplemental lines
|
||||
end
|
||||
vmg.execute_after_mapgen() -- needed for jungletree roots
|
||||
|
||||
local t3 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Data collecting finished in " .. displaytime(t3-t2))
|
||||
print("[Valleys Mapgen] Writing data ...")
|
||||
end
|
||||
|
||||
-- execute voxelmanip boring stuff to write to the map
|
||||
vm:set_data(data)
|
||||
minetest.generate_ores(vm, minp, maxp)
|
||||
vm:set_lighting({day = 0, night = 0})
|
||||
vm:calc_lighting()
|
||||
vm:update_liquids()
|
||||
vm:write_to_map()
|
||||
|
||||
local t4 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Data writing finished in " .. displaytime(t4-t3))
|
||||
end
|
||||
if vmg.loglevel >= 1 then
|
||||
print("[Valleys Mapgen] Mapgen finished in " .. displaytime(t4-t0))
|
||||
end
|
||||
end
|
||||
|
||||
dofile(vmg.path .. "/trees.lua")
|
||||
|
||||
function vmg.get_humidity_raw(pos)
|
||||
local v13 = vmg.get_noise(pos, 13)
|
||||
local v15 = vmg.get_noise(pos, 15)
|
||||
local v18 = vmg.get_noise(pos, 18)
|
||||
return 2 ^ (v13 - v15 + v18 * 2)
|
||||
end
|
||||
|
||||
function vmg.get_humidity(pos)
|
||||
local y = pos.y
|
||||
local flatpos = pos2d(pos)
|
||||
local hraw = vmg.get_humidity_raw(flatpos)
|
||||
|
||||
local v1 = vmg.get_noise(flatpos, 1)
|
||||
local v3 = vmg.get_noise(flatpos, 3) ^ 2
|
||||
local base_ground = v1 + v3
|
||||
local sea_water = 0.5 ^ math.max((y - water_level) / 6, 0)
|
||||
local river_water = 0.5 ^ math.max((y - base_ground) / 3, 0)
|
||||
local water = sea_water + (1 - sea_water) * river_water
|
||||
return hraw + water
|
||||
end
|
||||
|
||||
function vmg.get_temperature(pos)
|
||||
local v12 = vmg.get_noise(pos, 12) + 1
|
||||
local v17 = vmg.get_noise(pos, 17)
|
||||
local y = pos.y
|
||||
if y > 0 then
|
||||
return v17 * 0.5 ^ (y / altitude_chill)
|
||||
else
|
||||
return v17 * 0.5 ^ (-y / altitude_chill) + 20 * v12 * (1 - 2 ^ (y / lava_depth))
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.get_noise(pos, i)
|
||||
local n = vmg.noises[i]
|
||||
local noise = minetest.get_perlin(n.seed, n.octaves, n.persist, 1)
|
||||
if not pos.z then
|
||||
return noise:get2d({x = pos.x / n.spread.x, y = pos.y / n.spread.y}) * n.scale + n.offset
|
||||
else
|
||||
return noise:get3d({x = pos.x / n.spread.x, y = pos.y / n.spread.y, z = pos.z / n.spread.z}) * n.scale + n.offset
|
||||
end
|
||||
end
|
||||
|
||||
local function round(n)
|
||||
return math.floor(n + 0.5)
|
||||
end
|
||||
|
||||
function vmg.get_elevation(pos)
|
||||
local v1 = vmg.get_noise(pos, 1)
|
||||
local v2 = math.abs(vmg.get_noise(pos, 2)) - river_size
|
||||
local v3 = vmg.get_noise(pos, 3) ^ 2
|
||||
local base_ground = v1 + v3
|
||||
if v2 < 0 then
|
||||
return math.ceil(base_ground), true
|
||||
end
|
||||
local v4 = vmg.get_noise(pos, 4)
|
||||
local v5 = vmg.get_noise(pos, 5)
|
||||
local base_ground = v1 + v3
|
||||
local valleys = v3 * (1 - math.exp(- (v2 / v4) ^ 2))
|
||||
local mountain_ground = base_ground + valleys
|
||||
local pos = pos3d(pos, round(mountain_ground))
|
||||
local slopes = v5 * valleys
|
||||
if vmg.get_noise(pos, 6) * slopes > pos.y - mountain_ground then
|
||||
pos.y = pos.y + 1
|
||||
while vmg.get_noise(pos, 6) * slopes > pos.y - mountain_ground do
|
||||
pos.y = pos.y + 1
|
||||
end
|
||||
return pos.y, false
|
||||
else
|
||||
pos.y = pos.y - 1
|
||||
while vmg.get_noise(pos, 6) * slopes <= pos.y - mountain_ground do
|
||||
pos.y = pos.y - 1
|
||||
end
|
||||
return pos.y, false
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.spawnplayer(player)
|
||||
local angle = math.random() * math.pi * 2
|
||||
local distance = math.random() * player_max_distance
|
||||
local p_angle = {x = math.cos(angle), y = math.sin(angle)}
|
||||
local pos = {x = -p_angle.x * distance, y = -p_angle.y * distance}
|
||||
local elevation, river = vmg.get_elevation(pos)
|
||||
while elevation < water_level + 2 or river do
|
||||
pos.x = pos.x + p_angle.x
|
||||
pos.y = pos.y + p_angle.y
|
||||
elevation, river = vmg.get_elevation({x = round(pos.x), y = round(pos.y)})
|
||||
end
|
||||
pos = {x = round(pos.x), y = round(elevation + 1), z = round(pos.y)}
|
||||
player:setpos(pos)
|
||||
return true
|
||||
end
|
|
@ -1,192 +0,0 @@
|
|||
local waterflow = vmg.define("waterflow", 3)
|
||||
|
||||
minetest.override_item("default:river_water_source", {liquid_range = waterflow})
|
||||
minetest.override_item("default:river_water_flowing", {liquid_range = waterflow})
|
||||
|
||||
minetest.register_node("valleys_mapgen:silt", {
|
||||
description = "Silt",
|
||||
tiles = {"vmg_silt.png"},
|
||||
is_ground_content = true,
|
||||
groups = {crumbly=3},
|
||||
sounds = default.node_sound_dirt_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("valleys_mapgen:red_clay", {
|
||||
description = "Red Clay",
|
||||
tiles = {"vmg_red_clay.png"},
|
||||
is_ground_content = true,
|
||||
groups = {crumbly=3},
|
||||
sounds = default.node_sound_dirt_defaults(),
|
||||
})
|
||||
|
||||
minetest.override_item("default:clay", {description = "White Clay"})
|
||||
|
||||
local function register_dirts(readname)
|
||||
local name = readname:lower()
|
||||
local itemstr_dirt = "valleys_mapgen:dirt_" .. name
|
||||
local itemstr_lawn = itemstr_dirt .. "_with_grass"
|
||||
local itemstr_snow = itemstr_dirt .. "_with_snow"
|
||||
local tilestr = "vmg_dirt_" .. name .. ".png"
|
||||
|
||||
minetest.register_node(itemstr_dirt, {
|
||||
description = readname .. " Dirt",
|
||||
tiles = {tilestr},
|
||||
is_ground_content = true,
|
||||
groups = {crumbly=3,soil=1},
|
||||
sounds = default.node_sound_dirt_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node(itemstr_lawn, {
|
||||
description = readname .. " Dirt with Grass",
|
||||
tiles = {"default_grass.png", tilestr, tilestr .. "^default_grass_side.png"},
|
||||
is_ground_content = true,
|
||||
groups = {crumbly=3,soil=1},
|
||||
drop = itemstr_dirt,
|
||||
sounds = default.node_sound_dirt_defaults({
|
||||
footstep = {name="default_grass_footstep", gain=0.25},
|
||||
}),
|
||||
})
|
||||
|
||||
minetest.register_node(itemstr_snow, {
|
||||
description = readname .. " Dirt with Snow",
|
||||
tiles = {"default_snow.png", tilestr, tilestr .. "^default_snow_side.png"},
|
||||
is_ground_content = true,
|
||||
groups = {crumbly=3,soil=1},
|
||||
drop = itemstr_dirt,
|
||||
sounds = default.node_sound_dirt_defaults({
|
||||
footstep = {name="default_snow_footstep", gain=0.25},
|
||||
}),
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {itemstr_dirt},
|
||||
interval = 2,
|
||||
chance = 200,
|
||||
action = function(pos, node)
|
||||
local above = {x=pos.x, y=pos.y+1, z=pos.z}
|
||||
local name = minetest.get_node(above).name
|
||||
local nodedef = minetest.registered_nodes[name]
|
||||
if nodedef and (nodedef.sunlight_propagates or nodedef.paramtype == "light")
|
||||
and nodedef.liquidtype == "none"
|
||||
and (minetest.get_node_light(above) or 0) >= 13 then
|
||||
if name == "default:snow" or name == "default:snowblock" then
|
||||
minetest.set_node(pos, {name = itemstr_snow})
|
||||
else
|
||||
minetest.set_node(pos, {name = itemstr_lawn})
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {itemstr_lawn},
|
||||
interval = 2,
|
||||
chance = 20,
|
||||
action = function(pos, node)
|
||||
local above = {x=pos.x, y=pos.y+1, z=pos.z}
|
||||
local name = minetest.get_node(above).name
|
||||
local nodedef = minetest.registered_nodes[name]
|
||||
if name ~= "ignore" and nodedef
|
||||
and not ((nodedef.sunlight_propagates or nodedef.paramtype == "light")
|
||||
and nodedef.liquidtype == "none") then
|
||||
minetest.set_node(pos, {name = itemstr_dirt})
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
register_dirts("Clayey")
|
||||
register_dirts("Silty")
|
||||
register_dirts("Sandy")
|
||||
|
||||
-----------
|
||||
-- Trees --
|
||||
-----------
|
||||
|
||||
minetest.register_node("valleys_mapgen:fir_tree", {
|
||||
description = "Fir Tree",
|
||||
tiles = {"vmg_fir_tree_top.png", "vmg_fir_tree_top.png", "vmg_fir_tree.png"},
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
groups = {tree=1,choppy=2,oddly_breakable_by_hand=1,flammable=2},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
|
||||
on_place = minetest.rotate_node
|
||||
})
|
||||
|
||||
minetest.register_node("valleys_mapgen:fir_tree", {
|
||||
description = "Fir Tree",
|
||||
tiles = {"vmg_fir_tree_top.png", "vmg_fir_tree_top.png", "vmg_fir_tree.png"},
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
groups = {tree=1,choppy=2,oddly_breakable_by_hand=1,flammable=2},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
|
||||
on_place = minetest.rotate_node
|
||||
})
|
||||
|
||||
minetest.register_node("valleys_mapgen:fir_sapling", {
|
||||
description = "Fir Sapling",
|
||||
drawtype = "plantlike",
|
||||
visual_scale = 1.0,
|
||||
tiles = {"vmg_fir_sapling.png"},
|
||||
inventory_image = "vmg_fir_sapling.png",
|
||||
wield_image = "vmg_fir_sapling.png",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
|
||||
},
|
||||
groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1,sapling=1},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("valleys_mapgen:fir_needles", {
|
||||
description = "Fir Needles",
|
||||
drawtype = "allfaces_optional",
|
||||
waving = 1,
|
||||
visual_scale = 1.3,
|
||||
tiles = {"vmg_fir_leaves.png"},
|
||||
paramtype = "light",
|
||||
is_ground_content = false,
|
||||
groups = {snappy=3, leafdecay=7, flammable=2, leaves=1},
|
||||
drop = {
|
||||
max_items = 1,
|
||||
items = {
|
||||
{
|
||||
-- player will get sapling with 1/20 chance
|
||||
items = {'valleys_mapgen:fir_sapling'},
|
||||
rarity = 20,
|
||||
},
|
||||
{
|
||||
-- player will get leaves only if he get no saplings,
|
||||
-- this is because max_items is 1
|
||||
items = {'valleys_mapgen:fir_needles'},
|
||||
}
|
||||
}
|
||||
},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
|
||||
after_place_node = default.after_place_leaves,
|
||||
})
|
||||
|
||||
minetest.register_node("valleys_mapgen:fir_wood", {
|
||||
description = "Fir Wood Planks",
|
||||
tiles = {"vmg_fir_wood.png"},
|
||||
is_ground_content = false,
|
||||
groups = {choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "valleys_mapgen:fir_wood 5",
|
||||
recipe = {
|
||||
{"valleys_mapgen:fir_tree"}
|
||||
}
|
||||
})
|
||||
|
||||
minetest.add_group("default:leaves", {leafdecay = 5})
|
||||
minetest.add_group("default:jungleleaves", {leafdecay = 8})
|
||||
minetest.add_group("default:pine_needles", {leafdecay = 7})
|
|
@ -1,195 +0,0 @@
|
|||
-- Mapgen 1.0
|
||||
-- Saturday March 7, 2015
|
||||
|
||||
vmg.noises = {
|
||||
|
||||
-- Noise 1 : Base Ground Height 2D
|
||||
{offset = -10, scale = 50, seed = 5202, spread = {x = 1024, y = 1024, z = 1024}, octaves = 6, persist = 0.4},
|
||||
|
||||
-- Noise 2 : Valleys (River where around zero) 2D
|
||||
{offset = 0, scale = 1, seed = -6050, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.6},
|
||||
|
||||
-- Noise 3 : Valleys Depth 2D
|
||||
{offset = 5, scale = 4, seed = -1914, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1},
|
||||
|
||||
-- Noise 4 : Valleys Profile (Higher values = Larger valleys) 2D
|
||||
{offset = 0.5, scale = 0.5, seed = 777, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1},
|
||||
|
||||
-- Noise 5 : Inter-valleys slopes 2D
|
||||
{offset = 0.5, scale = 0.5, seed = 746, spread = {x = 128, y = 128, z = 128}, octaves = 1, persist = 1},
|
||||
|
||||
-- Noise 6 : Inter-valleys filling 3D
|
||||
{offset = 0, scale = 1, seed = 1993, spread = {x = 256, y = 512, z = 256}, octaves = 6, persist = 0.8},
|
||||
|
||||
-- Noise 7 : Dirt thickness 2D
|
||||
{offset = 1.75, scale = 3.25, seed = 1605, spread = {x = 256, y = 256, z = 256}, octaves = 1, persist = 1},
|
||||
|
||||
}
|
||||
|
||||
function vmg.generate(minp, maxp, seed)
|
||||
local minps, maxps = minetest.pos_to_string(minp), minetest.pos_to_string(maxp)
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Preparing to generate map from " .. minps .. " to " .. maxps .. " ...")
|
||||
elseif vmg.loglevel == 1 then
|
||||
print("[Valleys Mapgen] Generating map from " .. minps .. " to " .. maxps .. " ...")
|
||||
end
|
||||
local t0 = os.clock()
|
||||
|
||||
local c_dirt = minetest.get_content_id("default:dirt")
|
||||
local c_stone = minetest.get_content_id("default:stone")
|
||||
local c_lawn = minetest.get_content_id("default:dirt_with_grass")
|
||||
local c_water = minetest.get_content_id("default:water_source")
|
||||
local c_air = minetest.get_content_id("air")
|
||||
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local data = vm:get_data()
|
||||
local a = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
|
||||
local chulens = vector.add(vector.subtract(maxp, minp), 1)
|
||||
local chulens_sup = {x = chulens.x, y = chulens.y + 6, z = chulens.z}
|
||||
local minp2d = pos2d(minp)
|
||||
|
||||
local t1 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Mapgen preparation finished in " .. displaytime(t1-t0))
|
||||
print("[Valleys Mapgen] Calculating noises ...")
|
||||
end
|
||||
|
||||
local n1 = minetest.get_perlin_map(vmg.noises[1], chulens):get2dMap_flat(minp2d)
|
||||
local n2 = minetest.get_perlin_map(vmg.noises[2], chulens):get2dMap_flat(minp2d)
|
||||
local n3 = minetest.get_perlin_map(vmg.noises[3], chulens):get2dMap_flat(minp2d)
|
||||
local n4 = minetest.get_perlin_map(vmg.noises[4], chulens):get2dMap_flat(minp2d)
|
||||
local n5 = minetest.get_perlin_map(vmg.noises[5], chulens):get2dMap_flat(minp2d)
|
||||
local n6 = minetest.get_perlin_map(vmg.noises[6], chulens_sup):get3dMap_flat(minp)
|
||||
local n7 = minetest.get_perlin_map(vmg.noises[7], chulens):get2dMap_flat(minp2d)
|
||||
|
||||
local t2 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Noises calculation finished in " .. displaytime(t2-t1))
|
||||
print("[Valleys Mapgen] Collecting data ...")
|
||||
end
|
||||
|
||||
local i2d = 1 -- index for 2D noises
|
||||
local i3d = 1 -- index for 3D noises
|
||||
for x = minp.x, maxp.x do -- for each east-west and bottom-top plane
|
||||
for z = minp.z, maxp.z do -- for each vertical row in this plane
|
||||
local v1, v2, v3, v4, v5, v7 = n1[i2d], n2[i2d], n3[i2d], n4[i2d], n5[i2d], n7[i2d] -- n for noise, v for value
|
||||
v3 = v3 ^ 2 -- v3 must be > 0 and by the square there are high mountains but the median valleys depth is small.
|
||||
local base_ground = v1 + v3 -- v3 is here because terrain is generally higher when valleys are deep (mountains)
|
||||
local river = math.abs(v2) < 0.05
|
||||
local valleys = v3 * (1 - math.exp(- (v2 / v4) ^ 2)) -- use the curve of the function 1−exp(−(x/a)²) to modelise valleys. Making "a" varying 0 < a ≤ 1 will change the shape of the valleys. v2 = x and v4 = a.
|
||||
local mountain_ground = base_ground + valleys
|
||||
local slopes = v5 * valleys
|
||||
if river then
|
||||
mountain_ground = math.min(math.max(base_ground - 3, -5), mountain_ground)
|
||||
slopes = 0
|
||||
end
|
||||
for y = minp.y, maxp.y do -- for each node in vertical row
|
||||
local ivm = a:index(x, y, z)
|
||||
local v6 = n6[i3d]
|
||||
if v6 * slopes > y - mountain_ground then -- if pos is in the ground
|
||||
local above = math.ceil(v7 + math.random())
|
||||
if above <= 0 then
|
||||
data[ivm] = c_stone
|
||||
elseif y > 0 and n6[i3d+80] * slopes <= y + 1 - mountain_ground and not river then
|
||||
data[ivm] = c_lawn -- if node above is not in the ground, place lawn
|
||||
elseif n6[i3d+above*80] * slopes <= y + above - mountain_ground then
|
||||
data[ivm] = c_dirt
|
||||
else
|
||||
data[ivm] = c_stone
|
||||
end
|
||||
elseif y <= 1 or river and y - 2 <= mountain_ground then
|
||||
data[ivm] = c_water
|
||||
end
|
||||
|
||||
i3d = i3d + 80 -- increase i3d by one row
|
||||
end
|
||||
i2d = i2d + 80 -- increase i2d by one row
|
||||
i3d = i3d + 480 -- avoid the 6 supplemental lines
|
||||
end
|
||||
i2d = i2d - 6399 -- i2d = 6401 after the first execution of this loop, it must be 2 before the second.
|
||||
i3d = i3d - 550399 -- i3d = 550401 after the first execution of this loop, it must be 2 before the second.
|
||||
end
|
||||
|
||||
local t3 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Data collecting finished in " .. displaytime(t3-t2))
|
||||
print("[Valleys Mapgen] Writing data ...")
|
||||
end
|
||||
|
||||
-- execute voxelmanip boring stuff to write to the map
|
||||
vm:set_data(data)
|
||||
vm:calc_lighting()
|
||||
vm:update_liquids()
|
||||
minetest.generate_ores(vm) -- Thank you kwolekr ! I can generate the ores in 1 line ! And so it's compatible with moreores and other mods which add ores.
|
||||
vm:write_to_map()
|
||||
|
||||
local t4 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Data writing finished in " .. displaytime(t4-t3))
|
||||
end
|
||||
if vmg.loglevel >= 1 then
|
||||
print("[Valleys Mapgen] Mapgen finished in " .. displaytime(t4-t0))
|
||||
end
|
||||
end
|
||||
|
||||
vmg.noises_obj = {}
|
||||
|
||||
for i, n in ipairs(vmg.noises) do
|
||||
vmg.noises_obj[i] = minetest.get_perlin(n.seed, n.octaves, n.persist, 1)
|
||||
end
|
||||
|
||||
function vmg.get_noise(pos, i)
|
||||
local n = vmg.noises[i]
|
||||
local noise = minetest.get_perlin(n.seed, n.octaves, n.persist, 1)
|
||||
if not pos.z then
|
||||
return noise:get2d({x = pos.x / n.spread.x, y = pos.y / n.spread.y}) * n.scale + n.offset
|
||||
else
|
||||
return noise:get3d({x = pos.x / n.spread.x, y = pos.y / n.spread.y, z = pos.z / n.spread.z}) * n.scale + n.offset
|
||||
end
|
||||
end
|
||||
|
||||
local function round(n)
|
||||
return math.floor(n + 0.5)
|
||||
end
|
||||
|
||||
function vmg.get_elevation(pos)
|
||||
local v1 = vmg.get_noise(pos, 1)
|
||||
local v2 = vmg.get_noise(pos, 2)
|
||||
local v3 = vmg.get_noise(pos, 3) ^ 2
|
||||
local v4 = vmg.get_noise(pos, 4)
|
||||
local v5 = vmg.get_noise(pos, 5)
|
||||
local base_ground = v1 + v3
|
||||
local valleys = v3 * (1 - math.exp(- (v2 / v4) ^ 2))
|
||||
local mountain_ground = base_ground + valleys
|
||||
local pos = pos3d(pos, round(mountain_ground))
|
||||
local slopes = v5 * valleys
|
||||
if vmg.get_noise(pos, 6) * slopes > pos.y - mountain_ground then
|
||||
pos.y = pos.y + 1
|
||||
while vmg.get_noise(pos, 6) * slopes > pos.y - mountain_ground do
|
||||
pos.y = pos.y + 1
|
||||
end
|
||||
return pos.y
|
||||
else
|
||||
pos.y = pos.y - 1
|
||||
while vmg.get_noise(pos, 6) * slopes <= pos.y - mountain_ground do
|
||||
pos.y = pos.y - 1
|
||||
end
|
||||
return pos.y
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.spawnplayer(player)
|
||||
local pos = {x = 0, y = 0}
|
||||
local angle = math.random() * math.pi * 2
|
||||
local p_angle = {x = math.cos(angle), y = math.sin(angle)}
|
||||
local elevation = vmg.get_elevation(pos)
|
||||
while elevation < 2 do
|
||||
pos.x = pos.x + p_angle.x
|
||||
pos.y = pos.y + p_angle.y
|
||||
elevation = vmg.get_elevation({x = round(pos.x), y = round(pos.y)})
|
||||
end
|
||||
pos = {x = round(pos.x), y = round(elevation + 1), z = round(pos.y)}
|
||||
player:setpos(pos)
|
||||
return true
|
||||
end
|
|
@ -1,222 +0,0 @@
|
|||
-- Mapgen 1.1
|
||||
-- Sunday March 8, 2015
|
||||
|
||||
vmg.noises = {
|
||||
|
||||
-- Noise 1 : Base Ground Height 2D
|
||||
{offset = -10, scale = 50, seed = 5202, spread = {x = 1024, y = 1024, z = 1024}, octaves = 6, persist = 0.4},
|
||||
|
||||
-- Noise 2 : Valleys (River where around zero) 2D
|
||||
{offset = 0, scale = 1, seed = -6050, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.6},
|
||||
|
||||
-- Noise 3 : Valleys Depth 2D
|
||||
{offset = 5, scale = 4, seed = -1914, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1},
|
||||
|
||||
-- Noise 4 : Valleys Profile (Higher values = Larger valleys) 2D
|
||||
{offset = 0.5, scale = 0.5, seed = 777, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1},
|
||||
|
||||
-- Noise 5 : Inter-valleys slopes 2D
|
||||
{offset = 0.5, scale = 0.5, seed = 746, spread = {x = 128, y = 128, z = 128}, octaves = 1, persist = 1},
|
||||
|
||||
-- Noise 6 : Inter-valleys filling 3D
|
||||
{offset = 0, scale = 1, seed = 1993, spread = {x = 256, y = 512, z = 256}, octaves = 6, persist = 0.8},
|
||||
|
||||
-- Noise 7 : Dirt thickness 2D
|
||||
{offset = 3, scale = 2, seed = 1605, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5},
|
||||
|
||||
-- Noise 8 : Caves I
|
||||
{offset = 0, scale = 1, seed = -4640, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5},
|
||||
|
||||
-- Noise 9 : Caves II
|
||||
{offset = 0, scale = 1, seed = 8804, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5},
|
||||
|
||||
-- Noise 10 : Caves III
|
||||
{offset = 0, scale = 1, seed = -4780, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5},
|
||||
|
||||
-- Noise 11 : Caves IV
|
||||
{offset = 0, scale = 1, seed = -9969, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5},
|
||||
|
||||
}
|
||||
|
||||
function vmg.generate(minp, maxp, seed)
|
||||
local minps, maxps = minetest.pos_to_string(minp), minetest.pos_to_string(maxp)
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Preparing to generate map from " .. minps .. " to " .. maxps .. " ...")
|
||||
elseif vmg.loglevel == 1 then
|
||||
print("[Valleys Mapgen] Generating map from " .. minps .. " to " .. maxps .. " ...")
|
||||
end
|
||||
local t0 = os.clock()
|
||||
|
||||
local c_dirt = minetest.get_content_id("default:dirt")
|
||||
local c_stone = minetest.get_content_id("default:stone")
|
||||
local c_lawn = minetest.get_content_id("default:dirt_with_grass")
|
||||
local c_water = minetest.get_content_id("default:water_source")
|
||||
local c_air = minetest.get_content_id("air")
|
||||
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local data = vm:get_data()
|
||||
local a = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
|
||||
local chulens = vector.add(vector.subtract(maxp, minp), 1)
|
||||
local chulens_sup = {x = chulens.x, y = chulens.y + 6, z = chulens.z}
|
||||
local minp2d = pos2d(minp)
|
||||
|
||||
local t1 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Mapgen preparation finished in " .. displaytime(t1-t0))
|
||||
print("[Valleys Mapgen] Calculating noises ...")
|
||||
end
|
||||
|
||||
local n1 = minetest.get_perlin_map(vmg.noises[1], chulens):get2dMap_flat(minp2d)
|
||||
local n2 = minetest.get_perlin_map(vmg.noises[2], chulens):get2dMap_flat(minp2d)
|
||||
local n3 = minetest.get_perlin_map(vmg.noises[3], chulens):get2dMap_flat(minp2d)
|
||||
local n4 = minetest.get_perlin_map(vmg.noises[4], chulens):get2dMap_flat(minp2d)
|
||||
local n5 = minetest.get_perlin_map(vmg.noises[5], chulens):get2dMap_flat(minp2d)
|
||||
local n6 = minetest.get_perlin_map(vmg.noises[6], chulens_sup):get3dMap_flat(minp)
|
||||
local n7 = minetest.get_perlin_map(vmg.noises[7], chulens):get2dMap_flat(minp2d)
|
||||
local n8 = minetest.get_perlin_map(vmg.noises[8], chulens):get3dMap_flat(minp)
|
||||
local n9 = minetest.get_perlin_map(vmg.noises[9], chulens):get3dMap_flat(minp)
|
||||
local n10 = minetest.get_perlin_map(vmg.noises[10], chulens):get3dMap_flat(minp)
|
||||
local n11 = minetest.get_perlin_map(vmg.noises[11], chulens):get3dMap_flat(minp)
|
||||
|
||||
local t2 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Noises calculation finished in " .. displaytime(t2-t1))
|
||||
print("[Valleys Mapgen] Collecting data ...")
|
||||
end
|
||||
|
||||
local i2d = 1 -- index for 2D noises
|
||||
local i3d_a = 1 -- index for noise 6 which has a special size
|
||||
local i3d_b = 1 -- index for 3D noises
|
||||
for x = minp.x, maxp.x do -- for each east-west and bottom-top plane
|
||||
for z = minp.z, maxp.z do -- for each vertical row in this plane
|
||||
local v1, v2, v3, v4, v5, v7 = n1[i2d], n2[i2d], n3[i2d], n4[i2d], n5[i2d], n7[i2d] -- n for noise, v for value
|
||||
v3 = v3 ^ 2 -- v3 must be > 0 and by the square there are high mountains but the median valleys depth is small.
|
||||
local base_ground = v1 + v3 -- v3 is here because terrain is generally higher when valleys are deep (mountains)
|
||||
local river = math.abs(v2) < 0.05
|
||||
local valleys = v3 * (1 - math.exp(- (v2 / v4) ^ 2)) -- use the curve of the function 1−exp(−(x/a)²) to modelise valleys. Making "a" varying 0 < a ≤ 1 will change the shape of the valleys. v2 = x and v4 = a.
|
||||
local mountain_ground = base_ground + valleys
|
||||
local slopes = v5 * valleys
|
||||
if river then
|
||||
mountain_ground = math.min(math.max(base_ground - 3, -5), mountain_ground)
|
||||
slopes = 0
|
||||
end
|
||||
for y = minp.y, maxp.y do -- for each node in vertical row
|
||||
local ivm = a:index(x, y, z)
|
||||
local v6, v8, v9, v10, v11 = n6[i3d_a], n8[i3d_b], n9[i3d_b], n10[i3d_b], n11[i3d_b]
|
||||
local is_cave = v8 ^ 2 + v9 ^ 2 + v10 ^ 2 + v11 ^ 2 < 0.07
|
||||
if v6 * slopes > y - mountain_ground then -- if pos is in the ground
|
||||
if not is_cave then
|
||||
local above = math.ceil(v7 + math.random() - math.sqrt(math.abs(y)) / 3.5)
|
||||
if above <= 0 then
|
||||
data[ivm] = c_stone
|
||||
elseif y > 0 and n6[i3d_a+80] * slopes <= y + 1 - mountain_ground and not river then
|
||||
data[ivm] = c_lawn -- if node above is not in the ground, place lawn
|
||||
elseif n6[i3d_a+above*80] * slopes <= y + above - mountain_ground then
|
||||
data[ivm] = c_dirt
|
||||
else
|
||||
data[ivm] = c_stone
|
||||
end
|
||||
end
|
||||
elseif y <= 1 or river and y - 2 <= mountain_ground then
|
||||
data[ivm] = c_water
|
||||
end
|
||||
|
||||
i3d_a = i3d_a + 80 -- increase i3d_a by one row
|
||||
i3d_b = i3d_b + 80 -- increase i3d_b by one row
|
||||
end
|
||||
i2d = i2d + 80 -- increase i2d by one row
|
||||
i3d_a = i3d_a + 480 -- avoid the 6 supplemental lines
|
||||
end
|
||||
i2d = i2d - 6399 -- i2d = 6401 after the first execution of this loop, it must be 2 before the second.
|
||||
i3d_a = i3d_a - 550399 -- i3d_a = 550401 after the first execution of this loop, it must be 2 before the second.
|
||||
i3d_b = i3d_b - 511999 -- i3d_b = 512001 after the first execution of this loop, it must be 2 before the second.
|
||||
end
|
||||
|
||||
local t3 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Data collecting finished in " .. displaytime(t3-t2))
|
||||
print("[Valleys Mapgen] Writing data ...")
|
||||
end
|
||||
|
||||
-- execute voxelmanip boring stuff to write to the map
|
||||
vm:set_data(data)
|
||||
vm:set_lighting({day = 0, night = 0})
|
||||
vm:calc_lighting()
|
||||
vm:update_liquids()
|
||||
vm:write_to_map()
|
||||
|
||||
vm = minetest.get_voxel_manip()
|
||||
vm:read_from_map(minp, maxp)
|
||||
minetest.generate_ores(vm) -- Thank you kwolekr ! I can generate the ores in 1 line ! And so it's compatible with moreores and other mods which add ores.
|
||||
vm:write_to_map()
|
||||
|
||||
local t4 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Data writing finished in " .. displaytime(t4-t3))
|
||||
end
|
||||
if vmg.loglevel >= 1 then
|
||||
print("[Valleys Mapgen] Mapgen finished in " .. displaytime(t4-t0))
|
||||
end
|
||||
end
|
||||
|
||||
vmg.noises_obj = {}
|
||||
|
||||
for i, n in ipairs(vmg.noises) do
|
||||
vmg.noises_obj[i] = minetest.get_perlin(n.seed, n.octaves, n.persist, 1)
|
||||
end
|
||||
|
||||
function vmg.get_noise(pos, i)
|
||||
local n = vmg.noises[i]
|
||||
local noise = minetest.get_perlin(n.seed, n.octaves, n.persist, 1)
|
||||
if not pos.z then
|
||||
return noise:get2d({x = pos.x / n.spread.x, y = pos.y / n.spread.y}) * n.scale + n.offset
|
||||
else
|
||||
return noise:get3d({x = pos.x / n.spread.x, y = pos.y / n.spread.y, z = pos.z / n.spread.z}) * n.scale + n.offset
|
||||
end
|
||||
end
|
||||
|
||||
local function round(n)
|
||||
return math.floor(n + 0.5)
|
||||
end
|
||||
|
||||
function vmg.get_elevation(pos)
|
||||
local v1 = vmg.get_noise(pos, 1)
|
||||
local v2 = vmg.get_noise(pos, 2)
|
||||
local v3 = vmg.get_noise(pos, 3) ^ 2
|
||||
local v4 = vmg.get_noise(pos, 4)
|
||||
local v5 = vmg.get_noise(pos, 5)
|
||||
local base_ground = v1 + v3
|
||||
local valleys = v3 * (1 - math.exp(- (v2 / v4) ^ 2))
|
||||
local mountain_ground = base_ground + valleys
|
||||
local pos = pos3d(pos, round(mountain_ground))
|
||||
local slopes = v5 * valleys
|
||||
if vmg.get_noise(pos, 6) * slopes > pos.y - mountain_ground then
|
||||
pos.y = pos.y + 1
|
||||
while vmg.get_noise(pos, 6) * slopes > pos.y - mountain_ground do
|
||||
pos.y = pos.y + 1
|
||||
end
|
||||
return pos.y
|
||||
else
|
||||
pos.y = pos.y - 1
|
||||
while vmg.get_noise(pos, 6) * slopes <= pos.y - mountain_ground do
|
||||
pos.y = pos.y - 1
|
||||
end
|
||||
return pos.y
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.spawnplayer(player)
|
||||
local pos = {x = 0, y = 0}
|
||||
local angle = math.random() * math.pi * 2
|
||||
local p_angle = {x = math.cos(angle), y = math.sin(angle)}
|
||||
local elevation = vmg.get_elevation(pos)
|
||||
while elevation < 2 do
|
||||
pos.x = pos.x + p_angle.x
|
||||
pos.y = pos.y + p_angle.y
|
||||
elevation = vmg.get_elevation({x = round(pos.x), y = round(pos.y)})
|
||||
end
|
||||
pos = {x = round(pos.x), y = round(elevation + 1), z = round(pos.y)}
|
||||
player:setpos(pos)
|
||||
return true
|
||||
end
|
|
@ -1,251 +0,0 @@
|
|||
-- Mapgen 1.2
|
||||
-- Tuesday March 17, 2015
|
||||
|
||||
vmg.noises = {
|
||||
|
||||
-- Noise 1 : Base Ground Height 2D
|
||||
{offset = -10, scale = 50, seed = 5202, spread = {x = 1024, y = 1024, z = 1024}, octaves = 6, persist = 0.4, lacunarity = 2},
|
||||
|
||||
-- Noise 2 : Valleys (River where around zero) 2D
|
||||
{offset = 0, scale = 1, seed = -6050, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.6, lacunarity = 2},
|
||||
|
||||
-- Noise 3 : Valleys Depth 2D
|
||||
{offset = 5, scale = 4, seed = -1914, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2},
|
||||
|
||||
-- Noise 4 : Valleys Profile (Higher values = Larger valleys) 2D
|
||||
{offset = 0.6, scale = 0.5, seed = 777, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2},
|
||||
|
||||
-- Noise 5 : Inter-valleys slopes 2D
|
||||
{offset = 0.5, scale = 0.5, seed = 746, spread = {x = 128, y = 128, z = 128}, octaves = 1, persist = 1, lacunarity = 2},
|
||||
|
||||
-- Noise 6 : Inter-valleys filling 3D
|
||||
{offset = 0, scale = 1, seed = 1993, spread = {x = 256, y = 512, z = 256}, octaves = 6, persist = 0.8, lacunarity = 2},
|
||||
|
||||
-- Noise 7 : Dirt thickness 2D
|
||||
{offset = 3, scale = 1.75, seed = 1605, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 8 : Caves I 3D
|
||||
{offset = 0, scale = 1, seed = -4640, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 9 : Caves II 3D
|
||||
{offset = 0, scale = 1, seed = 8804, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 10 : Caves III 3D
|
||||
{offset = 0, scale = 1, seed = -4780, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 11 : Caves IV and Lava I 3D
|
||||
{offset = 0, scale = 1, seed = -9969, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 12 : Lava II 3D
|
||||
{offset = 0, scale = 1, seed = 3314, spread = {x = 64, y = 64, z = 64}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
}
|
||||
|
||||
function vmg.noisemap(i, minp, chulens)
|
||||
local obj = minetest.get_perlin_map(vmg.noises[i], chulens)
|
||||
if minp.z then
|
||||
return obj:get3dMap_flat(minp)
|
||||
else
|
||||
return obj:get2dMap_flat(minp)
|
||||
end
|
||||
end
|
||||
|
||||
for i, n in ipairs(vmg.noises) do
|
||||
vmg.noises[i] = vmg.define("noise_" .. i, n)
|
||||
end
|
||||
|
||||
local average_stone_level = vmg.define("average_stone_level", 180)
|
||||
local dirt_thickness = math.sqrt(average_stone_level) / (vmg.noises[7].offset + 0.5)
|
||||
|
||||
local river_size = vmg.define("river_size", 5) / 100
|
||||
local caves_size = vmg.define("caves_size", 7) / 100
|
||||
local lava_depth = vmg.define("lava_depth", 2000)
|
||||
local surface_lava = vmg.define("surface_lava", false)
|
||||
|
||||
local player_max_distance = vmg.define("player_max_distance", 450)
|
||||
|
||||
function vmg.generate(minp, maxp, seed)
|
||||
local minps, maxps = minetest.pos_to_string(minp), minetest.pos_to_string(maxp)
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Preparing to generate map from " .. minps .. " to " .. maxps .. " ...")
|
||||
elseif vmg.loglevel == 1 then
|
||||
print("[Valleys Mapgen] Generating map from " .. minps .. " to " .. maxps .. " ...")
|
||||
end
|
||||
local t0 = os.clock()
|
||||
|
||||
local c_dirt = minetest.get_content_id("default:dirt")
|
||||
local c_stone = minetest.get_content_id("default:stone")
|
||||
local c_lawn = minetest.get_content_id("default:dirt_with_grass")
|
||||
local c_water = minetest.get_content_id("default:water_source")
|
||||
local c_lava = minetest.get_content_id("default:lava_source")
|
||||
local c_air = minetest.get_content_id("air")
|
||||
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local data = vm:get_data()
|
||||
local a = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
|
||||
local chulens = vector.add(vector.subtract(maxp, minp), 1)
|
||||
local chulens_sup = {x = chulens.x, y = chulens.y + 6, z = chulens.z}
|
||||
local minp2d = pos2d(minp)
|
||||
|
||||
local t1 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Mapgen preparation finished in " .. displaytime(t1-t0))
|
||||
print("[Valleys Mapgen] Calculating noises ...")
|
||||
end
|
||||
|
||||
local n1 = vmg.noisemap(1, minp2d, chulens)
|
||||
local n2 = vmg.noisemap(2, minp2d, chulens)
|
||||
local n3 = vmg.noisemap(3, minp2d, chulens)
|
||||
local n4 = vmg.noisemap(4, minp2d, chulens)
|
||||
local n5 = vmg.noisemap(5, minp2d, chulens)
|
||||
local n6 = vmg.noisemap(6, minp, chulens_sup)
|
||||
local n7 = vmg.noisemap(7, minp2d, chulens)
|
||||
local n8 = vmg.noisemap(8, minp, chulens)
|
||||
local n9 = vmg.noisemap(9, minp, chulens)
|
||||
local n10 = vmg.noisemap(10, minp, chulens)
|
||||
local n11 = vmg.noisemap(11, minp, chulens)
|
||||
local n12 = vmg.noisemap(12, minp, chulens)
|
||||
|
||||
local t2 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Noises calculation finished in " .. displaytime(t2-t1))
|
||||
print("[Valleys Mapgen] Collecting data ...")
|
||||
end
|
||||
|
||||
local i2d = 1 -- index for 2D noises
|
||||
local i3d_a = 1 -- index for noise 6 which has a special size
|
||||
local i3d_b = 1 -- index for 3D noises
|
||||
for x = minp.x, maxp.x do -- for each east-west and bottom-top plane
|
||||
for z = minp.z, maxp.z do -- for each vertical row in this plane
|
||||
local v1, v2, v3, v4, v5, v7 = n1[i2d], n2[i2d], n3[i2d], n4[i2d], n5[i2d], n7[i2d] -- n for noise, v for value
|
||||
v3 = v3 ^ 2 -- v3 must be > 0 and by the square there are high mountains but the median valleys depth is small.
|
||||
local base_ground = v1 + v3 -- v3 is here because terrain is generally higher when valleys are deep (mountains)
|
||||
local river = math.abs(v2) < river_size
|
||||
local valleys = v3 * (1 - math.exp(- (v2 / v4) ^ 2)) -- use the curve of the function 1−exp(−(x/a)²) to modelise valleys. Making "a" varying 0 < a ≤ 1 will change the shape of the valleys. v2 = x and v4 = a.
|
||||
local mountain_ground = base_ground + valleys
|
||||
local slopes = v5 * valleys
|
||||
if river then
|
||||
mountain_ground = math.min(math.max(base_ground - 3, -5), mountain_ground)
|
||||
slopes = 0
|
||||
end
|
||||
for y = minp.y, maxp.y do -- for each node in vertical row
|
||||
local ivm = a:index(x, y, z)
|
||||
local v6, v8, v9, v10, v11, v12 = n6[i3d_a], n8[i3d_b], n9[i3d_b], n10[i3d_b], n11[i3d_b], n12[i3d_b]
|
||||
local is_cave = v8 ^ 2 + v9 ^ 2 + v10 ^ 2 + v11 ^ 2 < caves_size
|
||||
if v6 * slopes > y - mountain_ground then -- if pos is in the ground
|
||||
if not is_cave then
|
||||
local above = math.ceil(
|
||||
v7 + math.random() - math.sqrt(math.abs(y)) / dirt_thickness
|
||||
)
|
||||
if above <= 0 then
|
||||
data[ivm] = c_stone
|
||||
elseif y > 0 and n6[i3d_a+80] * slopes <= y + 1 - mountain_ground and not river then
|
||||
data[ivm] = c_lawn -- if node above is not in the ground, place lawn
|
||||
elseif n6[i3d_a+above*80] * slopes <= y + above - mountain_ground then
|
||||
data[ivm] = c_dirt
|
||||
else
|
||||
data[ivm] = c_stone
|
||||
end
|
||||
elseif v11 + v12 > 2 ^ (y / lava_depth) and (surface_lava or y < 0) then
|
||||
data[ivm] = c_lava
|
||||
end
|
||||
elseif y <= 1 or river and y - 2 <= mountain_ground then
|
||||
data[ivm] = c_water
|
||||
end
|
||||
|
||||
i3d_a = i3d_a + 80 -- increase i3d_a by one row
|
||||
i3d_b = i3d_b + 80 -- increase i3d_b by one row
|
||||
end
|
||||
i2d = i2d + 80 -- increase i2d by one row
|
||||
i3d_a = i3d_a + 480 -- avoid the 6 supplemental lines
|
||||
end
|
||||
i2d = i2d - 6399 -- i2d = 6401 after the first execution of this loop, it must be 2 before the second.
|
||||
i3d_a = i3d_a - 550399 -- i3d_a = 550401 after the first execution of this loop, it must be 2 before the second.
|
||||
i3d_b = i3d_b - 511999 -- i3d_b = 512001 after the first execution of this loop, it must be 2 before the second.
|
||||
end
|
||||
|
||||
local t3 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Data collecting finished in " .. displaytime(t3-t2))
|
||||
print("[Valleys Mapgen] Writing data ...")
|
||||
end
|
||||
|
||||
-- execute voxelmanip boring stuff to write to the map
|
||||
vm:set_data(data)
|
||||
minetest.generate_ores(vm, minp, maxp)
|
||||
vm:set_lighting({day = 0, night = 0})
|
||||
vm:calc_lighting()
|
||||
vm:update_liquids()
|
||||
vm:write_to_map()
|
||||
|
||||
local t4 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Data writing finished in " .. displaytime(t4-t3))
|
||||
end
|
||||
if vmg.loglevel >= 1 then
|
||||
print("[Valleys Mapgen] Mapgen finished in " .. displaytime(t4-t0))
|
||||
end
|
||||
end
|
||||
|
||||
vmg.noises_obj = {}
|
||||
|
||||
for i, n in ipairs(vmg.noises) do
|
||||
vmg.noises_obj[i] = minetest.get_perlin(n.seed, n.octaves, n.persist, 1)
|
||||
end
|
||||
|
||||
function vmg.get_noise(pos, i)
|
||||
local n = vmg.noises[i]
|
||||
local noise = minetest.get_perlin(n.seed, n.octaves, n.persist, 1)
|
||||
if not pos.z then
|
||||
return noise:get2d({x = pos.x / n.spread.x, y = pos.y / n.spread.y}) * n.scale + n.offset
|
||||
else
|
||||
return noise:get3d({x = pos.x / n.spread.x, y = pos.y / n.spread.y, z = pos.z / n.spread.z}) * n.scale + n.offset
|
||||
end
|
||||
end
|
||||
|
||||
local function round(n)
|
||||
return math.floor(n + 0.5)
|
||||
end
|
||||
|
||||
function vmg.get_elevation(pos)
|
||||
local v1 = vmg.get_noise(pos, 1)
|
||||
local v2 = vmg.get_noise(pos, 2)
|
||||
local v3 = vmg.get_noise(pos, 3) ^ 2
|
||||
local v4 = vmg.get_noise(pos, 4)
|
||||
local v5 = vmg.get_noise(pos, 5)
|
||||
local base_ground = v1 + v3
|
||||
local valleys = v3 * (1 - math.exp(- (v2 / v4) ^ 2))
|
||||
local mountain_ground = base_ground + valleys
|
||||
local pos = pos3d(pos, round(mountain_ground))
|
||||
local slopes = v5 * valleys
|
||||
if vmg.get_noise(pos, 6) * slopes > pos.y - mountain_ground then
|
||||
pos.y = pos.y + 1
|
||||
while vmg.get_noise(pos, 6) * slopes > pos.y - mountain_ground do
|
||||
pos.y = pos.y + 1
|
||||
end
|
||||
return pos.y
|
||||
else
|
||||
pos.y = pos.y - 1
|
||||
while vmg.get_noise(pos, 6) * slopes <= pos.y - mountain_ground do
|
||||
pos.y = pos.y - 1
|
||||
end
|
||||
return pos.y
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.spawnplayer(player)
|
||||
local angle = math.random() * math.pi * 2
|
||||
local distance = math.random() * player_max_distance
|
||||
local p_angle = {x = math.cos(angle), y = math.sin(angle)}
|
||||
local pos = {x = -p_angle.x * distance, y = -p_angle.y * distance}
|
||||
local elevation = vmg.get_elevation(pos)
|
||||
while elevation < 3 or math.abs(vmg.get_noise(pos, 2)) < river_size do
|
||||
pos.x = pos.x + p_angle.x
|
||||
pos.y = pos.y + p_angle.y
|
||||
elevation = vmg.get_elevation({x = round(pos.x), y = round(pos.y)})
|
||||
end
|
||||
pos = {x = round(pos.x), y = round(elevation + 1), z = round(pos.y)}
|
||||
player:setpos(pos)
|
||||
return true
|
||||
end
|
|
@ -1,328 +0,0 @@
|
|||
-- Mapgen 1.3
|
||||
-- Wednesday April 8, 2015
|
||||
|
||||
vmg.noises = {
|
||||
|
||||
-- Noise 1 : Base Ground Height 2D
|
||||
{offset = -10, scale = 50, seed = 5202, spread = {x = 1024, y = 1024, z = 1024}, octaves = 6, persist = 0.4, lacunarity = 2},
|
||||
|
||||
-- Noise 2 : Valleys (River where around zero) 2D
|
||||
{offset = 0, scale = 1, seed = -6050, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.6, lacunarity = 2},
|
||||
|
||||
-- Noise 3 : Valleys Depth 2D
|
||||
{offset = 5, scale = 4, seed = -1914, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2},
|
||||
|
||||
-- Noise 4 : Valleys Profile (Higher values = Larger valleys) 2D
|
||||
{offset = 0.6, scale = 0.5, seed = 777, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2},
|
||||
|
||||
-- Noise 5 : Inter-valleys slopes 2D
|
||||
{offset = 0.5, scale = 0.5, seed = 746, spread = {x = 128, y = 128, z = 128}, octaves = 1, persist = 1, lacunarity = 2},
|
||||
|
||||
-- Noise 6 : Inter-valleys filling 3D
|
||||
{offset = 0, scale = 1, seed = 1993, spread = {x = 256, y = 512, z = 256}, octaves = 6, persist = 0.8, lacunarity = 2},
|
||||
|
||||
-- Noise 7 : Dirt thickness 2D
|
||||
{offset = 3, scale = 1.75, seed = 1605, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 8 : Caves I 3D
|
||||
{offset = 0, scale = 1, seed = -4640, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 9 : Caves II 3D
|
||||
{offset = 0, scale = 1, seed = 8804, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 10 : Caves III 3D
|
||||
{offset = 0, scale = 1, seed = -4780, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 11 : Caves IV and Lava I 3D
|
||||
{offset = 0, scale = 1, seed = -9969, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 12 : Lava II 3D
|
||||
{offset = 0, scale = 1, seed = 3314, spread = {x = 64, y = 64, z = 64}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 13 : Clayey dirt noise 2D
|
||||
{offset = 0, scale = 1, seed = 2835, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4},
|
||||
|
||||
-- Noise 14 : Silty dirt noise 2D
|
||||
{offset = 0, scale = 1, seed = 6674, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4},
|
||||
|
||||
-- Noise 15 : Sandy dirt noise 2D
|
||||
{offset = 0, scale = 1, seed = 6940, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4},
|
||||
|
||||
-- Noise 16 : Beaches 2D
|
||||
{offset = 2, scale = 8, seed = 2349, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5, lacunarity = 2},
|
||||
|
||||
}
|
||||
|
||||
function vmg.noisemap(i, minp, chulens)
|
||||
local obj = minetest.get_perlin_map(vmg.noises[i], chulens)
|
||||
if minp.z then
|
||||
return obj:get3dMap_flat(minp)
|
||||
else
|
||||
return obj:get2dMap_flat(minp)
|
||||
end
|
||||
end
|
||||
|
||||
for i, n in ipairs(vmg.noises) do
|
||||
vmg.noises[i] = vmg.define("noise_" .. i, n)
|
||||
end
|
||||
|
||||
local average_stone_level = vmg.define("average_stone_level", 180)
|
||||
local dirt_thickness = math.sqrt(average_stone_level) / (vmg.noises[7].offset + 0.5)
|
||||
|
||||
local river_size = vmg.define("river_size", 5) / 100
|
||||
local caves_size = vmg.define("caves_size", 7) / 100
|
||||
local lava_depth = vmg.define("lava_depth", 2000)
|
||||
local surface_lava = vmg.define("surface_lava", false)
|
||||
|
||||
local player_max_distance = vmg.define("player_max_distance", 450)
|
||||
|
||||
local clay_threshold = vmg.define("clay_threshold", 1)
|
||||
local silt_threshold = vmg.define("silt_threshold", 1)
|
||||
local sand_threshold = vmg.define("sand_threshold", 0.75)
|
||||
local dirt_threshold = vmg.define("dirt_threshold", 0.5)
|
||||
|
||||
local water_level = vmg.define("water_level", 1)
|
||||
|
||||
function vmg.generate(minp, maxp, seed)
|
||||
local minps, maxps = minetest.pos_to_string(minp), minetest.pos_to_string(maxp)
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Preparing to generate map from " .. minps .. " to " .. maxps .. " ...")
|
||||
elseif vmg.loglevel == 1 then
|
||||
print("[Valleys Mapgen] Generating map from " .. minps .. " to " .. maxps .. " ...")
|
||||
end
|
||||
local t0 = os.clock()
|
||||
|
||||
local c_stone = minetest.get_content_id("default:stone")
|
||||
local c_dirt = minetest.get_content_id("default:dirt")
|
||||
local c_lawn = minetest.get_content_id("default:dirt_with_grass")
|
||||
local c_dirt_clay = minetest.get_content_id("valleys_mapgen:dirt_clayey")
|
||||
local c_lawn_clay = minetest.get_content_id("valleys_mapgen:dirt_clayey_with_grass")
|
||||
local c_dirt_silt = minetest.get_content_id("valleys_mapgen:dirt_silty")
|
||||
local c_lawn_silt = minetest.get_content_id("valleys_mapgen:dirt_silty_with_grass")
|
||||
local c_dirt_sand = minetest.get_content_id("valleys_mapgen:dirt_sandy")
|
||||
local c_lawn_sand = minetest.get_content_id("valleys_mapgen:dirt_sandy_with_grass")
|
||||
local c_desert_sand = minetest.get_content_id("default:desert_sand")
|
||||
local c_sand = minetest.get_content_id("default:sand")
|
||||
local c_gravel = minetest.get_content_id("default:gravel")
|
||||
local c_silt = minetest.get_content_id("valleys_mapgen:silt")
|
||||
local c_clay = minetest.get_content_id("valleys_mapgen:red_clay")
|
||||
local c_water = minetest.get_content_id("default:water_source")
|
||||
local c_lava = minetest.get_content_id("default:lava_source")
|
||||
local c_air = minetest.get_content_id("air")
|
||||
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local data = vm:get_data()
|
||||
local a = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
|
||||
local chulens = vector.add(vector.subtract(maxp, minp), 1)
|
||||
local chulens_sup = {x = chulens.x, y = chulens.y + 6, z = chulens.z}
|
||||
local minp2d = pos2d(minp)
|
||||
|
||||
local t1 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Mapgen preparation finished in " .. displaytime(t1-t0))
|
||||
print("[Valleys Mapgen] Calculating noises ...")
|
||||
end
|
||||
|
||||
local n1 = vmg.noisemap(1, minp2d, chulens)
|
||||
local n2 = vmg.noisemap(2, minp2d, chulens)
|
||||
local n3 = vmg.noisemap(3, minp2d, chulens)
|
||||
local n4 = vmg.noisemap(4, minp2d, chulens)
|
||||
local n5 = vmg.noisemap(5, minp2d, chulens)
|
||||
local n6 = vmg.noisemap(6, minp, chulens_sup)
|
||||
local n7 = vmg.noisemap(7, minp2d, chulens)
|
||||
local n8 = vmg.noisemap(8, minp, chulens)
|
||||
local n9 = vmg.noisemap(9, minp, chulens)
|
||||
local n10 = vmg.noisemap(10, minp, chulens)
|
||||
local n11 = vmg.noisemap(11, minp, chulens)
|
||||
local n12 = vmg.noisemap(12, minp, chulens)
|
||||
local n13 = vmg.noisemap(13, minp2d, chulens)
|
||||
local n14 = vmg.noisemap(14, minp2d, chulens)
|
||||
local n15 = vmg.noisemap(15, minp2d, chulens)
|
||||
local n16 = vmg.noisemap(16, minp2d, chulens)
|
||||
|
||||
local t2 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Noises calculation finished in " .. displaytime(t2-t1))
|
||||
print("[Valleys Mapgen] Collecting data ...")
|
||||
end
|
||||
|
||||
local i2d = 1 -- index for 2D noises
|
||||
local i3d_a = 1 -- index for noise 6 which has a special size
|
||||
local i3d_b = 1 -- index for 3D noises
|
||||
for x = minp.x, maxp.x do -- for each east-west and bottom-top plane
|
||||
for z = minp.z, maxp.z do -- for each vertical row in this plane
|
||||
local v1, v2, v3, v4, v5, v7, v13, v14, v15, v16 = n1[i2d], n2[i2d], n3[i2d], n4[i2d], n5[i2d], n7[i2d], n13[i2d], n14[i2d], n15[i2d], n16[i2d] -- n for noise, v for value
|
||||
v3 = v3 ^ 2 -- v3 must be > 0 and by the square there are high mountains but the median valleys depth is small.
|
||||
local base_ground = v1 + v3 -- v3 is here because terrain is generally higher when valleys are deep (mountains)
|
||||
local river = math.abs(v2) < river_size
|
||||
local valleys = v3 * (1 - math.exp(- (v2 / v4) ^ 2)) -- use the curve of the function 1−exp(−(x/a)²) to modelise valleys. Making "a" varying 0 < a ≤ 1 will change the shape of the valleys. v2 = x and v4 = a.
|
||||
local mountain_ground = base_ground + valleys
|
||||
local slopes = v5 * valleys
|
||||
|
||||
if river then
|
||||
mountain_ground = math.min(math.max(base_ground - 3, water_level - 6), mountain_ground)
|
||||
slopes = 0
|
||||
end
|
||||
|
||||
local dirt = c_dirt
|
||||
local lawn = c_lawn
|
||||
local max = math.max(v13, v14, v15)
|
||||
if max > dirt_threshold then
|
||||
if v13 == max then
|
||||
if v13 > clay_threshold then
|
||||
dirt = c_clay
|
||||
lawn = c_clay
|
||||
else
|
||||
dirt = c_dirt_clay
|
||||
lawn = c_lawn_clay
|
||||
end
|
||||
elseif v14 == max then
|
||||
if v14 > silt_threshold then
|
||||
dirt = c_silt
|
||||
lawn = c_silt
|
||||
else
|
||||
dirt = c_dirt_silt
|
||||
lawn = c_lawn_silt
|
||||
end
|
||||
else
|
||||
if v15 > sand_threshold then
|
||||
dirt = c_desert_sand
|
||||
lawn = c_desert_sand
|
||||
else
|
||||
dirt = c_dirt_sand
|
||||
lawn = c_lawn_sand
|
||||
end
|
||||
end
|
||||
end
|
||||
local is_beach = v15 > 0 and v16 > 0
|
||||
local beach = v15 * v16 + water_level
|
||||
|
||||
for y = minp.y, maxp.y do -- for each node in vertical row
|
||||
local ivm = a:index(x, y, z)
|
||||
local v6, v8, v9, v10, v11, v12 = n6[i3d_a], n8[i3d_b], n9[i3d_b], n10[i3d_b], n11[i3d_b], n12[i3d_b]
|
||||
local is_cave = v8 ^ 2 + v9 ^ 2 + v10 ^ 2 + v11 ^ 2 < caves_size
|
||||
if v6 * slopes > y - mountain_ground then -- if pos is in the ground
|
||||
if not is_cave then
|
||||
local above = math.ceil(
|
||||
v7 + math.random() - math.sqrt(math.abs(y)) / dirt_thickness
|
||||
)
|
||||
if above <= 0 then
|
||||
data[ivm] = c_stone
|
||||
elseif y >= water_level and n6[i3d_a+80] * slopes <= y + 1 - mountain_ground and not river then
|
||||
if is_beach and y < beach then
|
||||
data[ivm] = c_sand
|
||||
else
|
||||
data[ivm] = lawn -- if node above is not in the ground, place lawn
|
||||
end
|
||||
elseif n6[i3d_a+above*80] * slopes <= y + above - mountain_ground then
|
||||
if is_beach and y < beach then
|
||||
data[ivm] = c_sand
|
||||
else
|
||||
data[ivm] = dirt
|
||||
end
|
||||
else
|
||||
data[ivm] = c_stone
|
||||
end
|
||||
elseif v11 + v12 > 2 ^ (y / lava_depth) and (surface_lava or y < water_level - 1) then
|
||||
data[ivm] = c_lava
|
||||
end
|
||||
elseif y <= water_level or river and y - 2 <= mountain_ground then
|
||||
data[ivm] = c_water
|
||||
end
|
||||
|
||||
i3d_a = i3d_a + 80 -- increase i3d_a by one row
|
||||
i3d_b = i3d_b + 80 -- increase i3d_b by one row
|
||||
end
|
||||
i2d = i2d + 80 -- increase i2d by one row
|
||||
i3d_a = i3d_a + 480 -- avoid the 6 supplemental lines
|
||||
end
|
||||
i2d = i2d - 6399 -- i2d = 6401 after the first execution of this loop, it must be 2 before the second.
|
||||
i3d_a = i3d_a - 550399 -- i3d_a = 550401 after the first execution of this loop, it must be 2 before the second.
|
||||
i3d_b = i3d_b - 511999 -- i3d_b = 512001 after the first execution of this loop, it must be 2 before the second.
|
||||
end
|
||||
|
||||
local t3 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Data collecting finished in " .. displaytime(t3-t2))
|
||||
print("[Valleys Mapgen] Writing data ...")
|
||||
end
|
||||
|
||||
-- execute voxelmanip boring stuff to write to the map
|
||||
vm:set_data(data)
|
||||
minetest.generate_ores(vm, minp, maxp)
|
||||
vm:set_lighting({day = 0, night = 0})
|
||||
vm:calc_lighting()
|
||||
vm:update_liquids()
|
||||
vm:write_to_map()
|
||||
|
||||
local t4 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Data writing finished in " .. displaytime(t4-t3))
|
||||
end
|
||||
if vmg.loglevel >= 1 then
|
||||
print("[Valleys Mapgen] Mapgen finished in " .. displaytime(t4-t0))
|
||||
end
|
||||
end
|
||||
|
||||
vmg.noises_obj = {}
|
||||
|
||||
for i, n in ipairs(vmg.noises) do
|
||||
vmg.noises_obj[i] = minetest.get_perlin(n.seed, n.octaves, n.persist, 1)
|
||||
end
|
||||
|
||||
function vmg.get_noise(pos, i)
|
||||
local n = vmg.noises[i]
|
||||
local noise = minetest.get_perlin(n.seed, n.octaves, n.persist, 1)
|
||||
if not pos.z then
|
||||
return noise:get2d({x = pos.x / n.spread.x, y = pos.y / n.spread.y}) * n.scale + n.offset
|
||||
else
|
||||
return noise:get3d({x = pos.x / n.spread.x, y = pos.y / n.spread.y, z = pos.z / n.spread.z}) * n.scale + n.offset
|
||||
end
|
||||
end
|
||||
|
||||
local function round(n)
|
||||
return math.floor(n + 0.5)
|
||||
end
|
||||
|
||||
function vmg.get_elevation(pos)
|
||||
local v1 = vmg.get_noise(pos, 1)
|
||||
local v2 = vmg.get_noise(pos, 2)
|
||||
local v3 = vmg.get_noise(pos, 3) ^ 2
|
||||
local v4 = vmg.get_noise(pos, 4)
|
||||
local v5 = vmg.get_noise(pos, 5)
|
||||
local base_ground = v1 + v3
|
||||
local valleys = v3 * (1 - math.exp(- (v2 / v4) ^ 2))
|
||||
local mountain_ground = base_ground + valleys
|
||||
local pos = pos3d(pos, round(mountain_ground))
|
||||
local slopes = v5 * valleys
|
||||
if vmg.get_noise(pos, 6) * slopes > pos.y - mountain_ground then
|
||||
pos.y = pos.y + 1
|
||||
while vmg.get_noise(pos, 6) * slopes > pos.y - mountain_ground do
|
||||
pos.y = pos.y + 1
|
||||
end
|
||||
return pos.y
|
||||
else
|
||||
pos.y = pos.y - 1
|
||||
while vmg.get_noise(pos, 6) * slopes <= pos.y - mountain_ground do
|
||||
pos.y = pos.y - 1
|
||||
end
|
||||
return pos.y
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.spawnplayer(player)
|
||||
local angle = math.random() * math.pi * 2
|
||||
local distance = math.random() * player_max_distance
|
||||
local p_angle = {x = math.cos(angle), y = math.sin(angle)}
|
||||
local pos = {x = -p_angle.x * distance, y = -p_angle.y * distance}
|
||||
local elevation = vmg.get_elevation(pos)
|
||||
while elevation < water_level + 2 or math.abs(vmg.get_noise(pos, 2)) < river_size do
|
||||
pos.x = pos.x + p_angle.x
|
||||
pos.y = pos.y + p_angle.y
|
||||
elevation = vmg.get_elevation({x = round(pos.x), y = round(pos.y)})
|
||||
end
|
||||
pos = {x = round(pos.x), y = round(elevation + 1), z = round(pos.y)}
|
||||
player:setpos(pos)
|
||||
return true
|
||||
end
|
|
@ -1,203 +0,0 @@
|
|||
function default.grow_tree(pos, is_apple_tree)
|
||||
local rand = math.random()
|
||||
local height = math.floor(4 + 2.5 * rand)
|
||||
local radius = 3 + rand
|
||||
|
||||
local leaves = minetest.get_content_id("default:leaves")
|
||||
local trunk = minetest.get_content_id("default:tree")
|
||||
local air = minetest.get_content_id("air")
|
||||
local ignore = minetest.get_content_id("ignore")
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map({x = pos.x - 4, y = pos.y, z = pos.z - 4}, {x = pos.x + 4, y = pos.y + height + 4, z = pos.z + 4})
|
||||
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local data = vm:get_data()
|
||||
if is_apple_tree then
|
||||
vmg.grow_apple_tree(pos, data, area, height, radius, trunk, leaves, minetest.get_content_id("default:apple"), air, ignore)
|
||||
else
|
||||
vmg.grow_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
end
|
||||
vm:set_data(data)
|
||||
vm:write_to_map()
|
||||
vm:update_map()
|
||||
end
|
||||
|
||||
function default.grow_jungle_tree(pos)
|
||||
local rand = math.random()
|
||||
local height = math.floor(8 + 4 * rand)
|
||||
local radius = 5 + 3 * rand
|
||||
|
||||
local leaves = minetest.get_content_id("default:jungleleaves")
|
||||
local trunk = minetest.get_content_id("default:jungletree")
|
||||
local air = minetest.get_content_id("air")
|
||||
local ignore = minetest.get_content_id("ignore")
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map({x = pos.x - 8, y = pos.y - 1, z = pos.z - 8}, {x = pos.x + 8, y = pos.y + height + 5, z = pos.z + 8})
|
||||
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local data = vm:get_data()
|
||||
vmg.grow_jungle_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
vmg.execute_after_mapgen()
|
||||
vm:set_data(data)
|
||||
vm:write_to_map()
|
||||
vm:update_map()
|
||||
end
|
||||
|
||||
function default.grow_pine_tree(pos)
|
||||
local rand = math.random()
|
||||
local height = math.floor(9 + 6 * rand)
|
||||
local radius = 4 + 2 * rand
|
||||
|
||||
local leaves = minetest.get_content_id("default:pine_needles")
|
||||
local trunk = minetest.get_content_id("default:pinetree")
|
||||
local air = minetest.get_content_id("air")
|
||||
local ignore = minetest.get_content_id("ignore")
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map({x = pos.x - 6, y = pos.y - 1, z = pos.z - 6}, {x = pos.x + 6, y = pos.y + height + 2, z = pos.z + 6})
|
||||
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local data = vm:get_data()
|
||||
vmg.grow_pine_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
vm:set_data(data)
|
||||
vm:write_to_map()
|
||||
vm:update_map()
|
||||
end
|
||||
|
||||
function vmg.grow_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
if vmg.loglevel >= 3 then
|
||||
print("[Valleys Mapgen] Generating tree at " .. minetest.pos_to_string(pos) .. " ...")
|
||||
end
|
||||
local ystride = area.ystride
|
||||
local iv = area:indexp(pos)
|
||||
for i = 1, height do
|
||||
data[iv] = trunk
|
||||
iv = iv + ystride
|
||||
end
|
||||
local np = {offset = 0.8, scale = 0.4, spread = {x = 8, y = 4, z = 8}, octaves = 3, persist = 0.5}
|
||||
pos.y = pos.y + height - 1
|
||||
vmg.make_leavesblob(pos, data, area, leaves, air, ignore, {x = radius, y = radius, z = radius}, np)
|
||||
end
|
||||
|
||||
function vmg.grow_apple_tree(pos, data, area, height, radius, trunk, leaves, fruit, air, ignore)
|
||||
if vmg.loglevel >= 3 then
|
||||
print("[Valleys Mapgen] Generating apple tree at " .. minetest.pos_to_string(pos) .. " ...")
|
||||
end
|
||||
local ystride = area.ystride
|
||||
local iv = area:indexp(pos)
|
||||
for i = 1, height do
|
||||
data[iv] = trunk
|
||||
iv = iv + ystride
|
||||
end
|
||||
local np = {offset = 0.8, scale = 0.4, spread = {x = 8, y = 4, z = 8}, octaves = 3, persist = 0.5}
|
||||
pos.y = pos.y + height - 1
|
||||
vmg.make_leavesblob(pos, data, area, leaves, air, ignore, {x = radius, y = radius, z = radius}, np, 0.06, fruit)
|
||||
end
|
||||
|
||||
local function make_jungle_root(x0, y0, z0, data, area, tree, air)
|
||||
local ystride = area.ystride
|
||||
local ybot = y0 - 1
|
||||
for x = x0 - 1, x0 + 1 do
|
||||
for z = z0 - 1, z0 + 1 do
|
||||
local iv = area:index(x, ybot, z)
|
||||
for i = 0, 5 do
|
||||
if data[iv] == air then
|
||||
if math.random() < 0.6 then
|
||||
data[iv-ystride] = tree -- make jungle tree below
|
||||
if math.random() < 0.6 then
|
||||
data[iv] = tree -- make jungle tree at this air node
|
||||
end
|
||||
end
|
||||
break
|
||||
end
|
||||
iv = iv + ystride
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.grow_jungle_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
if vmg.loglevel >= 3 then
|
||||
print("[Valleys Mapgen] Generating jungle tree at " .. minetest.pos_to_string(pos) .. " ...")
|
||||
end
|
||||
local ystride = area.ystride
|
||||
local iv = area:indexp(pos)
|
||||
for i = 1, height do
|
||||
data[iv] = trunk
|
||||
iv = iv + ystride
|
||||
end
|
||||
vmg.register_after_mapgen(make_jungle_root, pos.x, pos.y, pos.z, data, area, trunk, air)
|
||||
local np = {offset = 0.8, scale = 0.4, spread = {x = 8, y = 4, z = 8}, octaves = 3, persist = 0.8}
|
||||
pos.y = pos.y + height
|
||||
vmg.make_leavesblob(pos, data, area, leaves, air, ignore, {x = radius, y = radius * 0.5, z = radius}, np)
|
||||
end
|
||||
|
||||
function vmg.grow_pine_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
if vmg.loglevel >= 3 then
|
||||
print("[Valleys Mapgen] Generating pine tree at " .. minetest.pos_to_string(pos) .. " ...")
|
||||
end
|
||||
local ystride = area.ystride
|
||||
local iv = area:indexp(pos)
|
||||
for i = 1, height do
|
||||
data[iv] = trunk
|
||||
iv = iv + ystride
|
||||
end
|
||||
|
||||
-- add leaves on the top (4% 0 ; 36% 1 ; 60% 2)
|
||||
local rand = math.random()
|
||||
if rand < 0.96 then
|
||||
data[iv] = leaves
|
||||
if rand < 0.60 then
|
||||
iv = iv + ystride
|
||||
data[iv] = leaves
|
||||
end
|
||||
end
|
||||
|
||||
-- make several leaves rings
|
||||
local max_height = pos.y + height
|
||||
local min_height = pos.y + math.floor((0.2 + 0.3 * math.random()) * height)
|
||||
local radius_increment = (radius - 1.2) / (max_height - min_height)
|
||||
local np = {offset = 0.8, scale = 0.4, spread = {x = 12, y = 4, z = 12}, octaves = 3, persist = 0.8}
|
||||
|
||||
pos.y = max_height - 1
|
||||
while pos.y >= min_height do
|
||||
local ring_radius = (max_height - pos.y) * radius_increment + 1.2
|
||||
vmg.make_leavesblob(pos, data, area, leaves, air, ignore, {x = ring_radius, y = 2, z = ring_radius}, np)
|
||||
pos.y = pos.y - math.random(2, 3)
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.make_leavesblob(pos, data, area, leaves, air, ignore, radius, np, fruit_chance, fruit)
|
||||
local count = 0
|
||||
fruit_chance = fruit_chance or 0
|
||||
|
||||
np.seed = math.random(0, 16777215)
|
||||
local round_radius = {x = math.ceil(radius.x), y = math.ceil(radius.y), z = math.ceil(radius.z)}
|
||||
|
||||
local length = vector.multiply(round_radius, 2)
|
||||
local chulens = vector.add(length, 1)
|
||||
local minp = vector.subtract(pos, round_radius)
|
||||
local maxp = vector.add(minp, length)
|
||||
local obj = minetest.get_perlin_map(np, chulens)
|
||||
local pmap = obj:get3dMap_flat(minp)
|
||||
local i = 1
|
||||
for x = minp.x, maxp.x do
|
||||
local xval = ((x - pos.x) / radius.x) ^ 2
|
||||
for y = minp.y, maxp.y do
|
||||
local yval = ((y - pos.y) / radius.y) ^ 2
|
||||
for z = minp.z, maxp.z do
|
||||
local zval = ((z - pos.z) / radius.z) ^ 2
|
||||
local dist = math.sqrt(xval + yval + zval)
|
||||
local nval = pmap[i]
|
||||
if nval > dist then
|
||||
local iv = area:index(x, y, z)
|
||||
if data[iv] == air or data[iv] == ignore then
|
||||
count = count + 1
|
||||
if math.random() < fruit_chance then
|
||||
data[iv] = fruit
|
||||
else
|
||||
data[iv] = leaves
|
||||
end
|
||||
end
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,510 +0,0 @@
|
|||
-- Mapgen 2.0
|
||||
-- Sunday May 31, 2015
|
||||
|
||||
vmg.noises = {
|
||||
|
||||
-- Noise 1 : Base Ground Height 2D
|
||||
{offset = -10, scale = 50, seed = 5202, spread = {x = 1024, y = 1024, z = 1024}, octaves = 6, persist = 0.4, lacunarity = 2},
|
||||
|
||||
-- Noise 2 : Valleys (River where around zero) 2D
|
||||
{offset = 0, scale = 1, seed = -6050, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.6, lacunarity = 2},
|
||||
|
||||
-- Noise 3 : Valleys Depth 2D
|
||||
{offset = 5, scale = 4, seed = -1914, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2},
|
||||
|
||||
-- Noise 4 : Valleys Profile (Higher values = Larger valleys) 2D
|
||||
{offset = 0.6, scale = 0.5, seed = 777, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2},
|
||||
|
||||
-- Noise 5 : Inter-valleys slopes 2D
|
||||
{offset = 0.5, scale = 0.5, seed = 746, spread = {x = 128, y = 128, z = 128}, octaves = 1, persist = 1, lacunarity = 2},
|
||||
|
||||
-- Noise 6 : Inter-valleys filling 3D
|
||||
{offset = 0, scale = 1, seed = 1993, spread = {x = 256, y = 512, z = 256}, octaves = 6, persist = 0.8, lacunarity = 2},
|
||||
|
||||
-- Noise 7 : Dirt thickness 2D
|
||||
{offset = 3, scale = 1.75, seed = 1605, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 8 : Caves I 3D
|
||||
{offset = 0, scale = 1, seed = -4640, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 9 : Caves II 3D
|
||||
{offset = 0, scale = 1, seed = 8804, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 10 : Caves III 3D
|
||||
{offset = 0, scale = 1, seed = -4780, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 11 : Caves IV and Lava I 3D
|
||||
{offset = 0, scale = 1, seed = -9969, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 12 : Lava II (Geologic heat) 3D
|
||||
{offset = 0, scale = 1, seed = 3314, spread = {x = 64, y = 64, z = 64}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 13 : Clayey dirt noise 2D
|
||||
{offset = 0, scale = 1, seed = 2835, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4},
|
||||
|
||||
-- Noise 14 : Silty dirt noise 2D
|
||||
{offset = 0, scale = 1, seed = 6674, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4},
|
||||
|
||||
-- Noise 15 : Sandy dirt noise 2D
|
||||
{offset = 0, scale = 1, seed = 6940, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4},
|
||||
|
||||
-- Noise 16 : Beaches 2D
|
||||
{offset = 2, scale = 8, seed = 2349, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 17 : Temperature (not in maps) 3D
|
||||
{offset = 2, scale = 1, seed = -1805, spread = {x = 768, y = 256, z = 768}, octaves = 4, persist = 0.5, lacunarity = 4},
|
||||
|
||||
-- Noise 18 : Humidity 2D
|
||||
{offset = 0, scale = 1, seed = -5787, spread = {x = 243, y = 243, z = 243}, octaves = 4, persist = 0.5, lacunarity = 3},
|
||||
|
||||
}
|
||||
|
||||
function vmg.noisemap(i, minp, chulens)
|
||||
local obj = minetest.get_perlin_map(vmg.noises[i], chulens)
|
||||
if minp.z then
|
||||
return obj:get3dMap_flat(minp)
|
||||
else
|
||||
return obj:get2dMap_flat(minp)
|
||||
end
|
||||
end
|
||||
|
||||
for i, n in ipairs(vmg.noises) do
|
||||
vmg.noises[i] = vmg.define("noise_" .. i, n)
|
||||
end
|
||||
|
||||
vmg.after_mapgen = {}
|
||||
|
||||
function vmg.register_after_mapgen(f, ...)
|
||||
table.insert(vmg.after_mapgen, {f = f, ...})
|
||||
end
|
||||
|
||||
function vmg.execute_after_mapgen()
|
||||
for i, params in ipairs(vmg.after_mapgen) do
|
||||
params.f(unpack(params))
|
||||
end
|
||||
vmg.after_mapgen = {}
|
||||
end
|
||||
|
||||
local river_size = vmg.define("river_size", 5) / 100
|
||||
local caves_size = vmg.define("caves_size", 7) / 100
|
||||
local lava_depth = vmg.define("lava_depth", 2000)
|
||||
local lava_max_height = vmg.define("lava_max_height", -1)
|
||||
local altitude_chill = vmg.define("altitude_chill", 90)
|
||||
|
||||
local average_stone_level = vmg.define("average_stone_level", 180)
|
||||
local dirt_thickness = math.sqrt(average_stone_level) / (vmg.noises[7].offset + 0.5)
|
||||
local average_snow_level = vmg.define("average_snow_level", 100)
|
||||
local snow_threshold = vmg.noises[17].offset * 0.5 ^ (average_snow_level / altitude_chill)
|
||||
|
||||
local player_max_distance = vmg.define("player_max_distance", 450)
|
||||
|
||||
local clay_threshold = vmg.define("clay_threshold", 1)
|
||||
local silt_threshold = vmg.define("silt_threshold", 1)
|
||||
local sand_threshold = vmg.define("sand_threshold", 0.75)
|
||||
local dirt_threshold = vmg.define("dirt_threshold", 0.5)
|
||||
|
||||
local tree_density = vmg.define("tree_density", 5) / 100
|
||||
local trees = vmg.define("trees", true)
|
||||
local plant_density = vmg.define("plant_density", 32) / 100
|
||||
local plants = vmg.define("plants", true)
|
||||
|
||||
local water_level = vmg.define("water_level", 1)
|
||||
|
||||
function vmg.generate(minp, maxp, seed)
|
||||
local minps, maxps = minetest.pos_to_string(minp), minetest.pos_to_string(maxp)
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Preparing to generate map from " .. minps .. " to " .. maxps .. " ...")
|
||||
elseif vmg.loglevel == 1 then
|
||||
print("[Valleys Mapgen] Generating map from " .. minps .. " to " .. maxps .. " ...")
|
||||
end
|
||||
local t0 = os.clock()
|
||||
|
||||
local c_stone = minetest.get_content_id("default:stone")
|
||||
local c_dirt = minetest.get_content_id("default:dirt")
|
||||
local c_lawn = minetest.get_content_id("default:dirt_with_grass")
|
||||
local c_snow = minetest.get_content_id("default:dirt_with_snow")
|
||||
local c_dirt_clay = minetest.get_content_id("valleys_mapgen:dirt_clayey")
|
||||
local c_lawn_clay = minetest.get_content_id("valleys_mapgen:dirt_clayey_with_grass")
|
||||
local c_snow_clay = minetest.get_content_id("valleys_mapgen:dirt_clayey_with_snow")
|
||||
local c_dirt_silt = minetest.get_content_id("valleys_mapgen:dirt_silty")
|
||||
local c_lawn_silt = minetest.get_content_id("valleys_mapgen:dirt_silty_with_grass")
|
||||
local c_snow_silt = minetest.get_content_id("valleys_mapgen:dirt_silty_with_snow")
|
||||
local c_dirt_sand = minetest.get_content_id("valleys_mapgen:dirt_sandy")
|
||||
local c_lawn_sand = minetest.get_content_id("valleys_mapgen:dirt_sandy_with_grass")
|
||||
local c_snow_sand = minetest.get_content_id("valleys_mapgen:dirt_sandy_with_snow")
|
||||
local c_desert_sand = minetest.get_content_id("default:desert_sand")
|
||||
local c_sand = minetest.get_content_id("default:sand")
|
||||
local c_gravel = minetest.get_content_id("default:gravel")
|
||||
local c_silt = minetest.get_content_id("valleys_mapgen:silt")
|
||||
local c_clay = minetest.get_content_id("valleys_mapgen:red_clay")
|
||||
local c_water = minetest.get_content_id("default:water_source")
|
||||
local c_lava = minetest.get_content_id("default:lava_source")
|
||||
local c_snow_layer = minetest.get_content_id("default:snow")
|
||||
|
||||
local c_tree = minetest.get_content_id("default:tree")
|
||||
local c_leaves = minetest.get_content_id("default:leaves")
|
||||
local c_apple = minetest.get_content_id("default:apple")
|
||||
local c_jungletree = minetest.get_content_id("default:jungletree")
|
||||
local c_jungleleaves = minetest.get_content_id("default:jungleleaves")
|
||||
local c_pinetree = minetest.get_content_id("default:pinetree")
|
||||
local c_pineleaves = minetest.get_content_id("default:pine_needles")
|
||||
|
||||
local c_grass = {
|
||||
minetest.get_content_id("default:grass_1"),
|
||||
minetest.get_content_id("default:grass_2"),
|
||||
minetest.get_content_id("default:grass_3"),
|
||||
minetest.get_content_id("default:grass_4"),
|
||||
minetest.get_content_id("default:grass_5"),
|
||||
}
|
||||
local c_junglegrass = minetest.get_content_id("default:junglegrass")
|
||||
local c_dryshrub = minetest.get_content_id("default:dry_shrub")
|
||||
local c_cactus = minetest.get_content_id("default:cactus")
|
||||
local c_papyrus = minetest.get_content_id("default:papyrus")
|
||||
|
||||
local c_air = minetest.get_content_id("air")
|
||||
local c_ignore = minetest.get_content_id("ignore")
|
||||
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local data = vm:get_data()
|
||||
local a = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local ystride = a.ystride
|
||||
|
||||
local chulens = vector.add(vector.subtract(maxp, minp), 1)
|
||||
local chulens_sup = {x = chulens.x, y = chulens.y + 6, z = chulens.z}
|
||||
local minp2d = pos2d(minp)
|
||||
|
||||
local t1 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Mapgen preparation finished in " .. displaytime(t1-t0))
|
||||
print("[Valleys Mapgen] Calculating noises ...")
|
||||
end
|
||||
|
||||
local n1 = vmg.noisemap(1, minp2d, chulens)
|
||||
local n2 = vmg.noisemap(2, minp2d, chulens)
|
||||
local n3 = vmg.noisemap(3, minp2d, chulens)
|
||||
local n4 = vmg.noisemap(4, minp2d, chulens)
|
||||
local n5 = vmg.noisemap(5, minp2d, chulens)
|
||||
local n6 = vmg.noisemap(6, minp, chulens_sup)
|
||||
local n7 = vmg.noisemap(7, minp2d, chulens)
|
||||
local n8 = vmg.noisemap(8, minp, chulens)
|
||||
local n9 = vmg.noisemap(9, minp, chulens)
|
||||
local n10 = vmg.noisemap(10, minp, chulens)
|
||||
local n11 = vmg.noisemap(11, minp, chulens)
|
||||
local n12 = vmg.noisemap(12, minp, chulens)
|
||||
local n13 = vmg.noisemap(13, minp2d, chulens)
|
||||
local n14 = vmg.noisemap(14, minp2d, chulens)
|
||||
local n15 = vmg.noisemap(15, minp2d, chulens)
|
||||
local n16 = vmg.noisemap(16, minp2d, chulens)
|
||||
local n18 = vmg.noisemap(18, minp2d, chulens)
|
||||
|
||||
local t2 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Noises calculation finished in " .. displaytime(t2-t1))
|
||||
print("[Valleys Mapgen] Collecting data ...")
|
||||
end
|
||||
|
||||
local i2d = 1 -- index for 2D noises
|
||||
local i3d_sup = 1 -- index for noise 6 which has a special size
|
||||
local i3d = 1 -- index for 3D noises
|
||||
|
||||
-- Calculate increments
|
||||
local i2d_incrZ = chulens.z
|
||||
local i2d_decrX = chulens.x * chulens.z - 1
|
||||
local i3d_incrY = chulens.y
|
||||
local i3d_sup_incrZ = 6 * chulens.y
|
||||
local i3d_decrX = chulens.x * chulens.y * chulens.z - 1
|
||||
local i3d_sup_decrX = chulens.x * (chulens.y + 6) * chulens.z - 1
|
||||
|
||||
for x = minp.x, maxp.x do -- for each YZ plane
|
||||
for z = minp.z, maxp.z do -- for each vertical line in this plane
|
||||
local v1, v2, v3, v4, v5, v7, v13, v14, v15, v16, v18 = n1[i2d], n2[i2d], n3[i2d], n4[i2d], n5[i2d], n7[i2d], n13[i2d], n14[i2d], n15[i2d], n16[i2d], n18[i2d] -- n for noise, v for value
|
||||
v3 = v3 ^ 2 -- v3 must be > 0 and by the square there are high mountains but the median valleys depth is small.
|
||||
local base_ground = v1 + v3 -- v3 is here because terrain is generally higher when valleys are deep (mountains)
|
||||
local river = math.abs(v2) < river_size
|
||||
local valleys = v3 * (1 - math.exp(- (v2 / v4) ^ 2)) -- use the curve of the function 1−exp(−(x/a)²) to modelise valleys. Making "a" varying 0 < a ≤ 1 will change the shape of the valleys. Try it with a geometry software ! (here x = v2 and a = v4)
|
||||
local mountain_ground = base_ground + valleys
|
||||
local slopes = v5 * valleys
|
||||
|
||||
if river then
|
||||
mountain_ground = math.min(math.max(base_ground - 3, water_level - 6), mountain_ground)
|
||||
slopes = 0
|
||||
end
|
||||
|
||||
-- Choose biome
|
||||
local dirt = c_dirt
|
||||
local lawn = c_lawn
|
||||
local snow = c_snow
|
||||
local max = math.max(v13, v14, v15) -- the biome is the maximal of these 3 values, if bigger than 0.5. Else, make normal dirt.
|
||||
if max > dirt_threshold then
|
||||
if v13 == max then
|
||||
if v13 > clay_threshold then
|
||||
dirt = c_clay
|
||||
lawn = c_clay
|
||||
snow = c_clay
|
||||
else
|
||||
dirt = c_dirt_clay
|
||||
lawn = c_lawn_clay
|
||||
snow = c_snow_clay
|
||||
end
|
||||
elseif v14 == max then
|
||||
if v14 > silt_threshold then
|
||||
dirt = c_silt
|
||||
lawn = c_silt
|
||||
snow = c_silt
|
||||
else
|
||||
dirt = c_dirt_silt
|
||||
lawn = c_lawn_silt
|
||||
snow = c_snow_silt
|
||||
end
|
||||
else
|
||||
if v15 > sand_threshold then
|
||||
dirt = c_desert_sand
|
||||
lawn = c_desert_sand
|
||||
snow = c_desert_sand
|
||||
else
|
||||
dirt = c_dirt_sand
|
||||
lawn = c_lawn_sand
|
||||
snow = c_snow_sand
|
||||
end
|
||||
end
|
||||
end
|
||||
local is_beach = v15 > 0 and v16 > 0
|
||||
local beach = v15 * v16 + water_level -- the y coordinate below which dirt is replaced by beach sand
|
||||
|
||||
-- raw humidity
|
||||
local hraw = 2 ^ (v13 - v15 + v18 * 2)
|
||||
|
||||
for y = minp.y, maxp.y do -- for each node in vertical line
|
||||
local ivm = a:index(x, y, z)
|
||||
local v6, v8, v9, v10, v11, v12 = n6[i3d_sup], n8[i3d], n9[i3d], n10[i3d], n11[i3d], n12[i3d]
|
||||
local is_cave = v8 ^ 2 + v9 ^ 2 + v10 ^ 2 + v11 ^ 2 < caves_size
|
||||
if v6 * slopes > y - mountain_ground then -- if pos is in the ground
|
||||
if not is_cave then
|
||||
local above = math.ceil(
|
||||
v7 + math.random() - math.sqrt(math.abs(y)) / dirt_thickness -- The following code will look for air at this many nodes up. If any, make dirt, else, make stone. So, it's the dirt layer thickness.
|
||||
)
|
||||
if y >= water_level and n6[i3d_sup+i3d_incrY] * slopes <= y + 1 - mountain_ground and not river then
|
||||
if is_beach and y < beach then
|
||||
data[ivm] = c_sand
|
||||
else -- if node above is not in the ground, place lawn
|
||||
|
||||
-- calculate humidity
|
||||
local sea_water = 0.5 ^ math.max((y - water_level) / 6, 0)
|
||||
local river_water = 0.5 ^ math.max((y - base_ground) / 3, 0)
|
||||
local water = sea_water + (1 - sea_water) * river_water
|
||||
local humidity = hraw + water
|
||||
|
||||
local ivm2 = ivm + ystride
|
||||
y = y + 1
|
||||
local pos = {x = x, y = y, z = z}
|
||||
|
||||
local v17 = vmg.get_noise(pos, 17)
|
||||
local temp -- calculate_temperature for node above
|
||||
if y > 0 then
|
||||
temp = v17 * 0.5 ^ (y / altitude_chill)
|
||||
else
|
||||
temp = v17 * 0.5 ^ (-y / altitude_chill) + 20 * (v12 + 1) * (1 - 2 ^ (y / lava_depth))
|
||||
end
|
||||
|
||||
if temp > snow_threshold then
|
||||
if above > 0 then
|
||||
data[ivm] = lawn
|
||||
else
|
||||
data[ivm] = c_stone
|
||||
end
|
||||
else
|
||||
if above > 0 then
|
||||
data[ivm] = snow
|
||||
else
|
||||
data[ivm] = c_stone
|
||||
end
|
||||
data[ivm2] = c_snow_layer -- set node above to snow
|
||||
end
|
||||
|
||||
if trees and math.random() < tree_density and above > 0 then -- make a tree
|
||||
|
||||
-- choose a tree from climatic and geological conditions
|
||||
if v15 < 0.6 and temp >= 0.85 and temp < 2.3 and humidity < 3 and v16 < 2 and v14 > -0.5 and v13 < 0.8 then -- Apple Tree
|
||||
local rand = math.random()
|
||||
local height = math.floor(4 + 2.5 * rand)
|
||||
local radius = 3 + rand
|
||||
if math.random(1, 4) == 1 then
|
||||
vmg.grow_apple_tree(pos, data, a, height, radius, c_tree, c_leaves, c_apple, c_air, c_ignore)
|
||||
else
|
||||
vmg.grow_tree(pos, data, a, height, radius, c_tree, c_leaves, c_air, c_ignore)
|
||||
end
|
||||
elseif v15 < 0.7 and temp >= 1.9 and humidity > 2 and v16 > 2 then -- Jungle Tree
|
||||
local rand = math.random()
|
||||
local height = math.floor(8 + 4 * rand)
|
||||
local radius = 5 + 3 * rand
|
||||
vmg.grow_jungle_tree(pos, data, a, height, radius, c_jungletree, c_jungleleaves, c_air, c_ignore)
|
||||
elseif temp > 0.38 and temp < 1 and humidity > 0.9 and v15 > 0 and v15 < 0.55 then -- Pine Tree (or Fir Tree)
|
||||
local rand = math.random()
|
||||
local height = math.floor(9 + 6 * rand)
|
||||
local radius = 4 + 2 * rand
|
||||
vmg.grow_pine_tree(pos, data, a, height, radius, c_pinetree, c_pineleaves, c_air, c_ignore)
|
||||
end
|
||||
elseif plants and math.random() < plant_density and above > 0 then -- make a plant
|
||||
if temp > 1 and temp < 1.8 and water > 0.7 and humidity > 3 and v13 > -0.4 and math.random() < 0.04 then -- Papyrus
|
||||
for i = 1, 4 do
|
||||
data[ivm+i*ystride] = c_papyrus
|
||||
end
|
||||
elseif v15 < 0.65 and temp >= 0.65 and temp < 1.5 and humidity < 2.6 and v16 < 1.5 and v13 < 0.8 and math.random() < 0.7 then -- Grass
|
||||
data[ivm2] = c_grass[math.random(1, 5)]
|
||||
elseif v15 > -0.6 and temp >= 1.8 and humidity > 2.2 and v16 > 1.8 then -- Jungle Grass
|
||||
data[ivm2] = c_junglegrass
|
||||
elseif v15 > 0.6 and v15 < 0.9 and humidity < 0.5 and temp > 1.8 and math.random() < 0.2 then
|
||||
if v16 < 0 and math.random() < 0.12 then -- Cactus
|
||||
for i = 1, 4 do
|
||||
data[ivm+i*ystride] = c_cactus
|
||||
end
|
||||
else -- Dry Shrub
|
||||
data[ivm2] = c_dryshrub
|
||||
end
|
||||
end
|
||||
end
|
||||
y = y - 1
|
||||
end
|
||||
elseif above <= 0 then
|
||||
data[ivm] = c_stone
|
||||
elseif n6[i3d_sup+above*i3d_incrY] * slopes <= y + above - mountain_ground then -- if node at "above" nodes up is not in the ground, make dirt
|
||||
if is_beach and y < beach then
|
||||
data[ivm] = c_sand
|
||||
else
|
||||
data[ivm] = dirt
|
||||
end
|
||||
else
|
||||
data[ivm] = c_stone
|
||||
end
|
||||
elseif v11 + v12 > 2 ^ (y / lava_depth) and y <= lava_max_height then
|
||||
data[ivm] = c_lava
|
||||
end
|
||||
elseif y <= water_level or river and y - 2 <= mountain_ground then -- if pos is not in the ground, and below water_level, it's an ocean
|
||||
data[ivm] = c_water
|
||||
end
|
||||
|
||||
i3d = i3d + i3d_incrY -- increment i3d by one line
|
||||
i3d_sup = i3d_sup + i3d_incrY -- idem
|
||||
end
|
||||
i2d = i2d + i2d_incrZ -- increment i2d by one Z
|
||||
-- useless to increment i3d, because increment would be 0 !
|
||||
i3d_sup = i3d_sup + i3d_sup_incrZ -- for i3d_sup, just avoid the 6 supplemental lines
|
||||
end
|
||||
i2d = i2d - i2d_decrX -- decrement the Z line previously incremented and increment by one X (1)
|
||||
i3d = i3d - i3d_decrX -- decrement the YZ plane previously incremented and increment by one X (1)
|
||||
i3d_sup = i3d_sup - i3d_sup_decrX -- idem, including the supplemental lines
|
||||
end
|
||||
vmg.execute_after_mapgen() -- needed for jungletree roots
|
||||
|
||||
local t3 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Data collecting finished in " .. displaytime(t3-t2))
|
||||
print("[Valleys Mapgen] Writing data ...")
|
||||
end
|
||||
|
||||
-- execute voxelmanip boring stuff to write to the map
|
||||
vm:set_data(data)
|
||||
minetest.generate_ores(vm, minp, maxp)
|
||||
vm:set_lighting({day = 0, night = 0})
|
||||
vm:calc_lighting()
|
||||
vm:update_liquids()
|
||||
vm:write_to_map()
|
||||
|
||||
local t4 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Data writing finished in " .. displaytime(t4-t3))
|
||||
end
|
||||
if vmg.loglevel >= 1 then
|
||||
print("[Valleys Mapgen] Mapgen finished in " .. displaytime(t4-t0))
|
||||
end
|
||||
end
|
||||
|
||||
dofile(vmg.path .. "/old_mapgens/2.0-trees.lua")
|
||||
|
||||
function vmg.get_humidity_raw(pos)
|
||||
local v13 = vmg.get_noise(pos, 13)
|
||||
local v15 = vmg.get_noise(pos, 15)
|
||||
local v18 = vmg.get_noise(pos, 18)
|
||||
return 2 ^ (v13 - v15 + v18 * 2)
|
||||
end
|
||||
|
||||
function vmg.get_humidity(pos)
|
||||
local y = pos.y
|
||||
local flatpos = pos2d(pos)
|
||||
local hraw = vmg.get_humidity_raw(flatpos)
|
||||
|
||||
local v1 = vmg.get_noise(flatpos, 1)
|
||||
local v3 = vmg.get_noise(flatpos, 3) ^ 2
|
||||
local base_ground = v1 + v3
|
||||
local sea_water = 0.5 ^ math.max((y - water_level) / 6, 0)
|
||||
local river_water = 0.5 ^ math.max((y - base_ground) / 3, 0)
|
||||
local water = sea_water + (1 - sea_water) * river_water
|
||||
return hraw + water
|
||||
end
|
||||
|
||||
function vmg.get_temperature(pos)
|
||||
local v12 = vmg.get_noise(pos, 12) + 1
|
||||
local v17 = vmg.get_noise(pos, 17)
|
||||
local y = pos.y
|
||||
if y > 0 then
|
||||
return v17 * 0.5 ^ (y / altitude_chill)
|
||||
else
|
||||
return v17 * 0.5 ^ (-y / altitude_chill) + 20 * v12 * (1 - 2 ^ (y / lava_depth))
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.get_noise(pos, i)
|
||||
local n = vmg.noises[i]
|
||||
local noise = minetest.get_perlin(n.seed, n.octaves, n.persist, 1)
|
||||
if not pos.z then
|
||||
return noise:get2d({x = pos.x / n.spread.x, y = pos.y / n.spread.y}) * n.scale + n.offset
|
||||
else
|
||||
return noise:get3d({x = pos.x / n.spread.x, y = pos.y / n.spread.y, z = pos.z / n.spread.z}) * n.scale + n.offset
|
||||
end
|
||||
end
|
||||
|
||||
local function round(n)
|
||||
return math.floor(n + 0.5)
|
||||
end
|
||||
|
||||
function vmg.get_elevation(pos)
|
||||
local v1 = vmg.get_noise(pos, 1)
|
||||
local v2 = vmg.get_noise(pos, 2)
|
||||
local v3 = vmg.get_noise(pos, 3) ^ 2
|
||||
local v4 = vmg.get_noise(pos, 4)
|
||||
local v5 = vmg.get_noise(pos, 5)
|
||||
local base_ground = v1 + v3
|
||||
local valleys = v3 * (1 - math.exp(- (v2 / v4) ^ 2))
|
||||
local mountain_ground = base_ground + valleys
|
||||
local pos = pos3d(pos, round(mountain_ground))
|
||||
local slopes = v5 * valleys
|
||||
if vmg.get_noise(pos, 6) * slopes > pos.y - mountain_ground then
|
||||
pos.y = pos.y + 1
|
||||
while vmg.get_noise(pos, 6) * slopes > pos.y - mountain_ground do
|
||||
pos.y = pos.y + 1
|
||||
end
|
||||
return pos.y
|
||||
else
|
||||
pos.y = pos.y - 1
|
||||
while vmg.get_noise(pos, 6) * slopes <= pos.y - mountain_ground do
|
||||
pos.y = pos.y - 1
|
||||
end
|
||||
return pos.y
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.spawnplayer(player)
|
||||
local angle = math.random() * math.pi * 2
|
||||
local distance = math.random() * player_max_distance
|
||||
local p_angle = {x = math.cos(angle), y = math.sin(angle)}
|
||||
local pos = {x = -p_angle.x * distance, y = -p_angle.y * distance}
|
||||
local elevation = vmg.get_elevation(pos)
|
||||
while elevation < water_level + 2 or math.abs(vmg.get_noise(pos, 2)) < river_size do
|
||||
pos.x = pos.x + p_angle.x
|
||||
pos.y = pos.y + p_angle.y
|
||||
elevation = vmg.get_elevation({x = round(pos.x), y = round(pos.y)})
|
||||
end
|
||||
pos = {x = round(pos.x), y = round(elevation + 1), z = round(pos.y)}
|
||||
player:setpos(pos)
|
||||
return true
|
||||
end
|
|
@ -1,287 +0,0 @@
|
|||
local function can_grow(pos) -- from default mod
|
||||
local node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
|
||||
if not node_under then
|
||||
return false
|
||||
end
|
||||
local name_under = node_under.name
|
||||
local is_soil = minetest.get_item_group(name_under, "soil")
|
||||
if is_soil == 0 then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"valleys_mapgen:fir_sapling"},
|
||||
interval = 14,
|
||||
chance = 50,
|
||||
action = function(pos, node)
|
||||
if not can_grow(pos) then
|
||||
return
|
||||
end
|
||||
|
||||
minetest.log("action", "A fir sapling grows into a tree at "..
|
||||
minetest.pos_to_string(pos))
|
||||
vmg.grow_fir_tree(pos)
|
||||
end
|
||||
})
|
||||
|
||||
function default.grow_tree(pos, is_apple_tree)
|
||||
local rand = math.random()
|
||||
local height = math.floor(4 + 2.5 * rand)
|
||||
local radius = 3 + rand
|
||||
|
||||
local leaves = minetest.get_content_id("default:leaves")
|
||||
local trunk = minetest.get_content_id("default:tree")
|
||||
local air = minetest.get_content_id("air")
|
||||
local ignore = minetest.get_content_id("ignore")
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map({x = pos.x - 4, y = pos.y, z = pos.z - 4}, {x = pos.x + 4, y = pos.y + height + 4, z = pos.z + 4})
|
||||
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local data = vm:get_data()
|
||||
if is_apple_tree then
|
||||
vmg.make_apple_tree(pos, data, area, height, radius, trunk, leaves, minetest.get_content_id("default:apple"), air, ignore)
|
||||
else
|
||||
vmg.make_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
end
|
||||
vm:set_data(data)
|
||||
vm:write_to_map()
|
||||
vm:update_map()
|
||||
end
|
||||
|
||||
function default.grow_jungle_tree(pos)
|
||||
local rand = math.random()
|
||||
local height = math.floor(8 + 4 * rand)
|
||||
local radius = 5 + 3 * rand
|
||||
|
||||
local leaves = minetest.get_content_id("default:jungleleaves")
|
||||
local trunk = minetest.get_content_id("default:jungletree")
|
||||
local air = minetest.get_content_id("air")
|
||||
local ignore = minetest.get_content_id("ignore")
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map({x = pos.x - 8, y = pos.y - 1, z = pos.z - 8}, {x = pos.x + 8, y = pos.y + height + 5, z = pos.z + 8})
|
||||
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local data = vm:get_data()
|
||||
vmg.make_jungle_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
vmg.execute_after_mapgen()
|
||||
vm:set_data(data)
|
||||
vm:write_to_map()
|
||||
vm:update_map()
|
||||
end
|
||||
|
||||
function default.grow_pine_tree(pos)
|
||||
local rand = math.random()
|
||||
local height = math.floor(9 + 6 * rand)
|
||||
local radius = 4 + 2 * rand
|
||||
|
||||
local leaves = minetest.get_content_id("default:pine_needles")
|
||||
local trunk = minetest.get_content_id("default:pinetree")
|
||||
local air = minetest.get_content_id("air")
|
||||
local ignore = minetest.get_content_id("ignore")
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map({x = pos.x - 6, y = pos.y - 1, z = pos.z - 6}, {x = pos.x + 6, y = pos.y + height + 2, z = pos.z + 6})
|
||||
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local data = vm:get_data()
|
||||
vmg.make_pine_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
vm:set_data(data)
|
||||
vm:write_to_map()
|
||||
vm:update_map()
|
||||
end
|
||||
|
||||
function vmg.grow_fir_tree(pos)
|
||||
local rand = math.random()
|
||||
local height = math.floor(9 + 6 * rand)
|
||||
local radius = 4 + 2 * rand
|
||||
|
||||
local leaves = minetest.get_content_id("valleys_mapgen:fir_needles")
|
||||
local trunk = minetest.get_content_id("valleys_mapgen:fir_tree")
|
||||
local air = minetest.get_content_id("air")
|
||||
local ignore = minetest.get_content_id("ignore")
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map({x = pos.x - 6, y = pos.y - 1, z = pos.z - 6}, {x = pos.x + 6, y = pos.y + height + 2, z = pos.z + 6})
|
||||
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local data = vm:get_data()
|
||||
vmg.make_fir_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
vm:set_data(data)
|
||||
vm:write_to_map()
|
||||
vm:update_map()
|
||||
end
|
||||
|
||||
function vmg.make_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
if vmg.loglevel >= 3 then
|
||||
print("[Valleys Mapgen] Generating tree at " .. minetest.pos_to_string(pos) .. " ...")
|
||||
end
|
||||
local ystride = area.ystride
|
||||
local iv = area:indexp(pos)
|
||||
for i = 1, height do
|
||||
data[iv] = trunk
|
||||
iv = iv + ystride
|
||||
end
|
||||
local np = {offset = 0.8, scale = 0.4, spread = {x = 8, y = 4, z = 8}, octaves = 3, persist = 0.5}
|
||||
pos.y = pos.y + height - 1
|
||||
vmg.make_leavesblob(pos, data, area, leaves, air, ignore, {x = radius, y = radius, z = radius}, np)
|
||||
end
|
||||
|
||||
function vmg.make_apple_tree(pos, data, area, height, radius, trunk, leaves, fruit, air, ignore)
|
||||
if vmg.loglevel >= 3 then
|
||||
print("[Valleys Mapgen] Generating apple tree at " .. minetest.pos_to_string(pos) .. " ...")
|
||||
end
|
||||
local ystride = area.ystride
|
||||
local iv = area:indexp(pos)
|
||||
for i = 1, height do
|
||||
data[iv] = trunk
|
||||
iv = iv + ystride
|
||||
end
|
||||
local np = {offset = 0.8, scale = 0.4, spread = {x = 8, y = 4, z = 8}, octaves = 3, persist = 0.5}
|
||||
pos.y = pos.y + height - 1
|
||||
vmg.make_leavesblob(pos, data, area, leaves, air, ignore, {x = radius, y = radius, z = radius}, np, 0.06, fruit)
|
||||
end
|
||||
|
||||
local function make_jungle_root(x0, y0, z0, data, area, tree, air)
|
||||
local ystride = area.ystride
|
||||
local ybot = y0 - 1
|
||||
for x = x0 - 1, x0 + 1 do
|
||||
for z = z0 - 1, z0 + 1 do
|
||||
local iv = area:index(x, ybot, z)
|
||||
for i = 0, 5 do
|
||||
if data[iv] == air then
|
||||
if math.random() < 0.6 then
|
||||
data[iv-ystride] = tree -- make jungle tree below
|
||||
if math.random() < 0.6 then
|
||||
data[iv] = tree -- make jungle tree at this air node
|
||||
end
|
||||
end
|
||||
break
|
||||
end
|
||||
iv = iv + ystride
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.make_jungle_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
if vmg.loglevel >= 3 then
|
||||
print("[Valleys Mapgen] Generating jungle tree at " .. minetest.pos_to_string(pos) .. " ...")
|
||||
end
|
||||
local ystride = area.ystride
|
||||
local iv = area:indexp(pos)
|
||||
for i = 1, height do
|
||||
data[iv] = trunk
|
||||
iv = iv + ystride
|
||||
end
|
||||
vmg.register_after_mapgen(make_jungle_root, pos.x, pos.y, pos.z, data, area, trunk, air)
|
||||
local np = {offset = 0.8, scale = 0.4, spread = {x = 8, y = 4, z = 8}, octaves = 3, persist = 0.8}
|
||||
pos.y = pos.y + height
|
||||
vmg.make_leavesblob(pos, data, area, leaves, air, ignore, {x = radius, y = radius * 0.5, z = radius}, np)
|
||||
end
|
||||
|
||||
function vmg.make_fir_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
if vmg.loglevel >= 3 then
|
||||
print("[Valleys Mapgen] Generating fir tree at " .. minetest.pos_to_string(pos) .. " ...")
|
||||
end
|
||||
local ystride = area.ystride
|
||||
local iv = area:indexp(pos)
|
||||
for i = 1, height do
|
||||
data[iv] = trunk
|
||||
iv = iv + ystride
|
||||
end
|
||||
|
||||
-- add leaves on the top (4% 0 ; 36% 1 ; 60% 2)
|
||||
local rand = math.random()
|
||||
if rand < 0.96 then
|
||||
data[iv] = leaves
|
||||
if rand < 0.60 then
|
||||
iv = iv + ystride
|
||||
data[iv] = leaves
|
||||
end
|
||||
end
|
||||
|
||||
-- make several leaves rings
|
||||
local max_height = pos.y + height
|
||||
local min_height = pos.y + math.floor((0.2 + 0.3 * math.random()) * height)
|
||||
local radius_increment = (radius - 1.2) / (max_height - min_height)
|
||||
local np = {offset = 0.8, scale = 0.4, spread = {x = 12, y = 4, z = 12}, octaves = 3, persist = 0.8}
|
||||
|
||||
pos.y = max_height - 1
|
||||
while pos.y >= min_height do
|
||||
local ring_radius = (max_height - pos.y) * radius_increment + 1.2
|
||||
vmg.make_leavesblob(pos, data, area, leaves, air, ignore, {x = ring_radius, y = 2, z = ring_radius}, np)
|
||||
pos.y = pos.y - math.random(2, 3)
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.make_pine_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
if vmg.loglevel >= 3 then
|
||||
print("[Valleys Mapgen] Generating pine tree at " .. minetest.pos_to_string(pos) .. " ...")
|
||||
end
|
||||
local ystride = area.ystride
|
||||
local iv = area:indexp(pos)
|
||||
for i = 1, height do
|
||||
data[iv] = trunk
|
||||
iv = iv + ystride
|
||||
end
|
||||
|
||||
-- add leaves on the top (4% 0 ; 36% 1 ; 60% 2)
|
||||
local rand = math.random()
|
||||
if rand < 0.96 then
|
||||
data[iv] = leaves
|
||||
if rand < 0.60 then
|
||||
iv = iv + ystride
|
||||
data[iv] = leaves
|
||||
end
|
||||
end
|
||||
|
||||
local np = {offset = 0.8, scale = 0.3, spread = {x = 8, y = 4, z = 8}, octaves = 3, persist = 1}
|
||||
local min_height = pos.y + math.floor((0.4 + 0.2 * math.random()) * height)
|
||||
local midradius = radius / 2
|
||||
|
||||
pos.y = pos.y + height - 1
|
||||
vmg.make_leavesblob(pos, data, area, leaves, air, ignore, {x = radius, y = 1.5, z = radius}, np)
|
||||
while pos.y >= min_height do
|
||||
local angle, distance = math.random() * 2 * math.pi, math.random() * midradius
|
||||
local cos, sin = math.cos(angle) * distance, math.sin(angle) * distance
|
||||
local bpos = {x = pos.x + cos, y = pos.y, z = pos.z + sin}
|
||||
vmg.make_leavesblob(bpos, data, area, leaves, air, ignore, {x = midradius, y = 1.5, z = midradius}, np)
|
||||
pos.y = pos.y - math.random(1, 2)
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.make_leavesblob(pos, data, area, leaves, air, ignore, radius, np, fruit_chance, fruit)
|
||||
local count = 0
|
||||
fruit_chance = fruit_chance or 0
|
||||
|
||||
np.seed = math.random(0, 16777215)
|
||||
local minp = vector.subtract(pos, radius)
|
||||
local maxp = vector.add(pos, radius)
|
||||
local int_minp = {x = math.floor(minp.x), y = math.floor(minp.y), z = math.floor(minp.z)}
|
||||
local int_maxp = {x = math.ceil(maxp.x), y = math.ceil(maxp.y), z = math.ceil(maxp.z)}
|
||||
|
||||
local length = vector.subtract(int_maxp, int_minp)
|
||||
local chulens = vector.add(length, 1)
|
||||
local obj = minetest.get_perlin_map(np, chulens)
|
||||
local pmap = obj:get3dMap_flat(minp)
|
||||
local i = 1
|
||||
for x = int_minp.x, int_maxp.x do
|
||||
local xval = ((x - pos.x) / radius.x) ^ 2
|
||||
for y = int_minp.y, int_maxp.y do
|
||||
local yval = ((y - pos.y) / radius.y) ^ 2
|
||||
for z = int_minp.z, int_maxp.z do
|
||||
local zval = ((z - pos.z) / radius.z) ^ 2
|
||||
local dist = math.sqrt(xval + yval + zval)
|
||||
local nval = pmap[i]
|
||||
if nval > dist then
|
||||
local iv = area:index(x, y, z)
|
||||
if data[iv] == air or data[iv] == ignore then
|
||||
count = count + 1
|
||||
if math.random() < fruit_chance then
|
||||
data[iv] = fruit
|
||||
else
|
||||
data[iv] = leaves
|
||||
end
|
||||
end
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,532 +0,0 @@
|
|||
-- Mapgen 2.1
|
||||
-- Saturday July 4, 2015
|
||||
|
||||
vmg.noises = {
|
||||
|
||||
-- Noise 1 : Base Ground Height 2D
|
||||
{offset = -10, scale = 50, seed = 5202, spread = {x = 1024, y = 1024, z = 1024}, octaves = 6, persist = 0.4, lacunarity = 2},
|
||||
|
||||
-- Noise 2 : Valleys (River where around zero) 2D
|
||||
{offset = 0, scale = 1, seed = -6050, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.6, lacunarity = 2},
|
||||
|
||||
-- Noise 3 : Valleys Depth 2D
|
||||
{offset = 5, scale = 4, seed = -1914, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2},
|
||||
|
||||
-- Noise 4 : Valleys Profile (Higher values = Larger valleys) 2D
|
||||
{offset = 0.6, scale = 0.5, seed = 777, spread = {x = 512, y = 512, z = 512}, octaves = 1, persist = 1, lacunarity = 2},
|
||||
|
||||
-- Noise 5 : Inter-valleys slopes 2D
|
||||
{offset = 0.5, scale = 0.5, seed = 746, spread = {x = 128, y = 128, z = 128}, octaves = 1, persist = 1, lacunarity = 2},
|
||||
|
||||
-- Noise 6 : Inter-valleys filling 3D
|
||||
{offset = 0, scale = 1, seed = 1993, spread = {x = 256, y = 512, z = 256}, octaves = 6, persist = 0.8, lacunarity = 2},
|
||||
|
||||
-- Noise 7 : Dirt thickness 2D
|
||||
{offset = 3, scale = 1.75, seed = 1605, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 8 : Caves I 3D
|
||||
{offset = 0, scale = 1, seed = -4640, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 9 : Caves II 3D
|
||||
{offset = 0, scale = 1, seed = 8804, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 10 : Caves III 3D
|
||||
{offset = 0, scale = 1, seed = -4780, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 11 : Caves IV and Lava I 3D
|
||||
{offset = 0, scale = 1, seed = -9969, spread = {x = 32, y = 32, z = 32}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 12 : Lava II (Geologic heat) 3D
|
||||
{offset = 0, scale = 1, seed = 3314, spread = {x = 64, y = 64, z = 64}, octaves = 4, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 13 : Clayey dirt noise 2D
|
||||
{offset = 0, scale = 1, seed = 2835, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4},
|
||||
|
||||
-- Noise 14 : Silty dirt noise 2D
|
||||
{offset = 0, scale = 1, seed = 6674, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4},
|
||||
|
||||
-- Noise 15 : Sandy dirt noise 2D
|
||||
{offset = 0, scale = 1, seed = 6940, spread = {x = 256, y = 256, z = 256}, octaves = 5, persist = 0.5, lacunarity = 4},
|
||||
|
||||
-- Noise 16 : Beaches 2D
|
||||
{offset = 2, scale = 8, seed = 2349, spread = {x = 256, y = 256, z = 256}, octaves = 3, persist = 0.5, lacunarity = 2},
|
||||
|
||||
-- Noise 17 : Temperature (not in maps) 3D
|
||||
{offset = 2, scale = 1, seed = -1805, spread = {x = 768, y = 256, z = 768}, octaves = 4, persist = 0.5, lacunarity = 4},
|
||||
|
||||
-- Noise 18 : Humidity 2D
|
||||
{offset = 0, scale = 1, seed = -5787, spread = {x = 243, y = 243, z = 243}, octaves = 4, persist = 0.5, lacunarity = 3},
|
||||
|
||||
}
|
||||
|
||||
function vmg.noisemap(i, minp, chulens)
|
||||
local obj = minetest.get_perlin_map(vmg.noises[i], chulens)
|
||||
if minp.z then
|
||||
return obj:get3dMap_flat(minp)
|
||||
else
|
||||
return obj:get2dMap_flat(minp)
|
||||
end
|
||||
end
|
||||
|
||||
for i, n in ipairs(vmg.noises) do
|
||||
vmg.noises[i] = vmg.define("noise_" .. i, n)
|
||||
end
|
||||
|
||||
vmg.after_mapgen = {}
|
||||
|
||||
function vmg.register_after_mapgen(f, ...)
|
||||
table.insert(vmg.after_mapgen, {f = f, ...})
|
||||
end
|
||||
|
||||
function vmg.execute_after_mapgen()
|
||||
for i, params in ipairs(vmg.after_mapgen) do
|
||||
params.f(unpack(params))
|
||||
end
|
||||
vmg.after_mapgen = {}
|
||||
end
|
||||
|
||||
local river_depth = vmg.define("river_depth", 3) + 1
|
||||
local river_size = vmg.define("river_size", 5) / 100
|
||||
local caves_size = vmg.define("caves_size", 7) / 100
|
||||
local lava_depth = vmg.define("lava_depth", 2000)
|
||||
local lava_max_height = vmg.define("lava_max_height", -1)
|
||||
local altitude_chill = vmg.define("altitude_chill", 90)
|
||||
|
||||
local average_stone_level = vmg.define("average_stone_level", 180)
|
||||
local dirt_thickness = math.sqrt(average_stone_level) / (vmg.noises[7].offset + 0.5)
|
||||
local average_snow_level = vmg.define("average_snow_level", 100)
|
||||
local snow_threshold = vmg.noises[17].offset * 0.5 ^ (average_snow_level / altitude_chill)
|
||||
|
||||
local player_max_distance = vmg.define("player_max_distance", 450)
|
||||
|
||||
local clay_threshold = vmg.define("clay_threshold", 1)
|
||||
local silt_threshold = vmg.define("silt_threshold", 1)
|
||||
local sand_threshold = vmg.define("sand_threshold", 0.75)
|
||||
local dirt_threshold = vmg.define("dirt_threshold", 0.5)
|
||||
|
||||
local tree_density = vmg.define("tree_density", 5) / 100
|
||||
local trees = vmg.define("trees", true)
|
||||
local plant_density = vmg.define("plant_density", 32) / 100
|
||||
local plants = vmg.define("plants", true)
|
||||
|
||||
local water_level = vmg.define("water_level", 1)
|
||||
local river_water = vmg.define("river_water", true)
|
||||
|
||||
function vmg.generate(minp, maxp, seed)
|
||||
local minps, maxps = minetest.pos_to_string(minp), minetest.pos_to_string(maxp)
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Preparing to generate map from " .. minps .. " to " .. maxps .. " ...")
|
||||
elseif vmg.loglevel == 1 then
|
||||
print("[Valleys Mapgen] Generating map from " .. minps .. " to " .. maxps .. " ...")
|
||||
end
|
||||
local t0 = os.clock()
|
||||
|
||||
local c_stone = minetest.get_content_id("default:stone")
|
||||
local c_dirt = minetest.get_content_id("default:dirt")
|
||||
local c_lawn = minetest.get_content_id("default:dirt_with_grass")
|
||||
local c_snow = minetest.get_content_id("default:dirt_with_snow")
|
||||
local c_dirt_clay = minetest.get_content_id("valleys_mapgen:dirt_clayey")
|
||||
local c_lawn_clay = minetest.get_content_id("valleys_mapgen:dirt_clayey_with_grass")
|
||||
local c_snow_clay = minetest.get_content_id("valleys_mapgen:dirt_clayey_with_snow")
|
||||
local c_dirt_silt = minetest.get_content_id("valleys_mapgen:dirt_silty")
|
||||
local c_lawn_silt = minetest.get_content_id("valleys_mapgen:dirt_silty_with_grass")
|
||||
local c_snow_silt = minetest.get_content_id("valleys_mapgen:dirt_silty_with_snow")
|
||||
local c_dirt_sand = minetest.get_content_id("valleys_mapgen:dirt_sandy")
|
||||
local c_lawn_sand = minetest.get_content_id("valleys_mapgen:dirt_sandy_with_grass")
|
||||
local c_snow_sand = minetest.get_content_id("valleys_mapgen:dirt_sandy_with_snow")
|
||||
local c_desert_sand = minetest.get_content_id("default:desert_sand")
|
||||
local c_sand = minetest.get_content_id("default:sand")
|
||||
local c_gravel = minetest.get_content_id("default:gravel")
|
||||
local c_silt = minetest.get_content_id("valleys_mapgen:silt")
|
||||
local c_clay = minetest.get_content_id("valleys_mapgen:red_clay")
|
||||
local c_water = minetest.get_content_id("default:water_source")
|
||||
local c_riverwater = minetest.get_content_id("default:river_water_source")
|
||||
local c_lava = minetest.get_content_id("default:lava_source")
|
||||
local c_snow_layer = minetest.get_content_id("default:snow")
|
||||
|
||||
local c_tree = minetest.get_content_id("default:tree")
|
||||
local c_leaves = minetest.get_content_id("default:leaves")
|
||||
local c_apple = minetest.get_content_id("default:apple")
|
||||
local c_jungletree = minetest.get_content_id("default:jungletree")
|
||||
local c_jungleleaves = minetest.get_content_id("default:jungleleaves")
|
||||
local c_pinetree = minetest.get_content_id("default:pinetree")
|
||||
local c_pineleaves = minetest.get_content_id("default:pine_needles")
|
||||
local c_firtree = minetest.get_content_id("valleys_mapgen:fir_tree")
|
||||
local c_firleaves = minetest.get_content_id("valleys_mapgen:fir_needles")
|
||||
|
||||
local c_grass = {
|
||||
minetest.get_content_id("default:grass_1"),
|
||||
minetest.get_content_id("default:grass_2"),
|
||||
minetest.get_content_id("default:grass_3"),
|
||||
minetest.get_content_id("default:grass_4"),
|
||||
minetest.get_content_id("default:grass_5"),
|
||||
}
|
||||
local c_junglegrass = minetest.get_content_id("default:junglegrass")
|
||||
local c_dryshrub = minetest.get_content_id("default:dry_shrub")
|
||||
local c_cactus = minetest.get_content_id("default:cactus")
|
||||
local c_papyrus = minetest.get_content_id("default:papyrus")
|
||||
|
||||
local c_air = minetest.get_content_id("air")
|
||||
local c_ignore = minetest.get_content_id("ignore")
|
||||
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local data = vm:get_data()
|
||||
local a = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local ystride = a.ystride
|
||||
|
||||
local chulens = vector.add(vector.subtract(maxp, minp), 1)
|
||||
local chulens_sup = {x = chulens.x, y = chulens.y + 6, z = chulens.z}
|
||||
local minp2d = pos2d(minp)
|
||||
|
||||
local t1 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Mapgen preparation finished in " .. displaytime(t1-t0))
|
||||
print("[Valleys Mapgen] Calculating noises ...")
|
||||
end
|
||||
|
||||
local n1 = vmg.noisemap(1, minp2d, chulens)
|
||||
local n2 = vmg.noisemap(2, minp2d, chulens)
|
||||
local n3 = vmg.noisemap(3, minp2d, chulens)
|
||||
local n4 = vmg.noisemap(4, minp2d, chulens)
|
||||
local n5 = vmg.noisemap(5, minp2d, chulens)
|
||||
local n6 = vmg.noisemap(6, minp, chulens_sup)
|
||||
local n7 = vmg.noisemap(7, minp2d, chulens)
|
||||
local n8 = vmg.noisemap(8, minp, chulens)
|
||||
local n9 = vmg.noisemap(9, minp, chulens)
|
||||
local n10 = vmg.noisemap(10, minp, chulens)
|
||||
local n11 = vmg.noisemap(11, minp, chulens)
|
||||
local n12 = vmg.noisemap(12, minp, chulens)
|
||||
local n13 = vmg.noisemap(13, minp2d, chulens)
|
||||
local n14 = vmg.noisemap(14, minp2d, chulens)
|
||||
local n15 = vmg.noisemap(15, minp2d, chulens)
|
||||
local n16 = vmg.noisemap(16, minp2d, chulens)
|
||||
local n18 = vmg.noisemap(18, minp2d, chulens)
|
||||
|
||||
local t2 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Noises calculation finished in " .. displaytime(t2-t1))
|
||||
print("[Valleys Mapgen] Collecting data ...")
|
||||
end
|
||||
|
||||
local i2d = 1 -- index for 2D noises
|
||||
local i3d_sup = 1 -- index for noise 6 which has a special size
|
||||
local i3d = 1 -- index for 3D noises
|
||||
|
||||
-- Calculate increments
|
||||
local i2d_incrZ = chulens.z
|
||||
local i2d_decrX = chulens.x * chulens.z - 1
|
||||
local i3d_incrY = chulens.y
|
||||
local i3d_sup_incrZ = 6 * chulens.y
|
||||
local i3d_decrX = chulens.x * chulens.y * chulens.z - 1
|
||||
local i3d_sup_decrX = chulens.x * (chulens.y + 6) * chulens.z - 1
|
||||
|
||||
for x = minp.x, maxp.x do -- for each YZ plane
|
||||
for z = minp.z, maxp.z do -- for each vertical line in this plane
|
||||
local v1, v2, v3, v4, v5, v7, v13, v14, v15, v16, v18 = n1[i2d], n2[i2d], n3[i2d], n4[i2d], n5[i2d], n7[i2d], n13[i2d], n14[i2d], n15[i2d], n16[i2d], n18[i2d] -- n for noise, v for value
|
||||
v3 = v3 ^ 2 -- v3 must be > 0 and by the square there are high mountains but the median valleys depth is small.
|
||||
local base_ground = v1 + v3 -- v3 is here because terrain is generally higher when valleys are deep (mountains)
|
||||
v2 = math.abs(v2) - river_size
|
||||
local river = v2 < 0
|
||||
local valleys = v3 * (1 - math.exp(- (v2 / v4) ^ 2)) -- use the curve of the function 1−exp(−(x/a)²) to modelise valleys. Making "a" varying 0 < a ≤ 1 will change the shape of the valleys. Try it with a geometry software ! (here x = v2 and a = v4)
|
||||
local mountain_ground = base_ground + valleys
|
||||
local slopes = v5 * valleys
|
||||
|
||||
if river then
|
||||
local depth = river_depth * math.sqrt(1 - (v2 / river_size + 1) ^ 2) -- use the curve of the function −sqrt(1-x²) which modelizes a circle.
|
||||
mountain_ground = math.min(math.max(base_ground - depth, water_level - 6), mountain_ground)
|
||||
slopes = 0
|
||||
end
|
||||
|
||||
-- Choose biome
|
||||
local dirt = c_dirt
|
||||
local lawn = c_lawn
|
||||
local snow = c_snow
|
||||
local max = math.max(v13, v14, v15) -- the biome is the maximal of these 3 values, if bigger than 0.5. Else, make normal dirt.
|
||||
if max > dirt_threshold then
|
||||
if v13 == max then
|
||||
if v13 > clay_threshold then
|
||||
dirt = c_clay
|
||||
lawn = c_clay
|
||||
snow = c_clay
|
||||
else
|
||||
dirt = c_dirt_clay
|
||||
lawn = c_lawn_clay
|
||||
snow = c_snow_clay
|
||||
end
|
||||
elseif v14 == max then
|
||||
if v14 > silt_threshold then
|
||||
dirt = c_silt
|
||||
lawn = c_silt
|
||||
snow = c_silt
|
||||
else
|
||||
dirt = c_dirt_silt
|
||||
lawn = c_lawn_silt
|
||||
snow = c_snow_silt
|
||||
end
|
||||
else
|
||||
if v15 > sand_threshold then
|
||||
dirt = c_desert_sand
|
||||
lawn = c_desert_sand
|
||||
snow = c_desert_sand
|
||||
else
|
||||
dirt = c_dirt_sand
|
||||
lawn = c_lawn_sand
|
||||
snow = c_snow_sand
|
||||
end
|
||||
end
|
||||
end
|
||||
local is_beach = v15 > 0 and v16 > 0
|
||||
local beach = v15 * v16 + water_level -- the y coordinate below which dirt is replaced by beach sand
|
||||
|
||||
-- raw humidity
|
||||
local hraw = 2 ^ (v13 - v15 + v18 * 2)
|
||||
|
||||
for y = minp.y, maxp.y do -- for each node in vertical line
|
||||
local ivm = a:index(x, y, z)
|
||||
local v6, v8, v9, v10, v11, v12 = n6[i3d_sup], n8[i3d], n9[i3d], n10[i3d], n11[i3d], n12[i3d]
|
||||
local is_cave = v8 ^ 2 + v9 ^ 2 + v10 ^ 2 + v11 ^ 2 < caves_size
|
||||
if v6 * slopes > y - mountain_ground then -- if pos is in the ground
|
||||
if not is_cave then
|
||||
local above = math.ceil(
|
||||
v7 + math.random() - math.sqrt(math.abs(y)) / dirt_thickness -- The following code will look for air at this many nodes up. If any, make dirt, else, make stone. So, it's the dirt layer thickness.
|
||||
)
|
||||
if y >= water_level and n6[i3d_sup+i3d_incrY] * slopes <= y + 1 - mountain_ground and not river then
|
||||
if is_beach and y < beach then
|
||||
data[ivm] = c_sand
|
||||
else -- if node above is not in the ground, place lawn
|
||||
|
||||
-- calculate humidity
|
||||
local sea_water = 0.5 ^ math.max((y - water_level) / 6, 0)
|
||||
local river_water = 0.5 ^ math.max((y - base_ground) / 3, 0)
|
||||
local water = sea_water + (1 - sea_water) * river_water
|
||||
local humidity = hraw + water
|
||||
|
||||
local ivm2 = ivm + ystride
|
||||
y = y + 1
|
||||
local pos = {x = x, y = y, z = z}
|
||||
|
||||
local v17 = vmg.get_noise(pos, 17)
|
||||
local temp -- calculate_temperature for node above
|
||||
if y > 0 then
|
||||
temp = v17 * 0.5 ^ (y / altitude_chill)
|
||||
else
|
||||
temp = v17 * 0.5 ^ (-y / altitude_chill) + 20 * (v12 + 1) * (1 - 2 ^ (y / lava_depth))
|
||||
end
|
||||
|
||||
if temp > snow_threshold then
|
||||
if above > 0 then
|
||||
data[ivm] = lawn
|
||||
else
|
||||
data[ivm] = c_stone
|
||||
end
|
||||
else
|
||||
if above > 0 then
|
||||
data[ivm] = snow
|
||||
else
|
||||
data[ivm] = c_stone
|
||||
end
|
||||
data[ivm2] = c_snow_layer -- set node above to snow
|
||||
end
|
||||
|
||||
if trees and math.random() < tree_density and above > 0 then -- make a tree
|
||||
|
||||
-- choose a tree from climatic and geological conditions
|
||||
if v14 < 0 and temp < 1.5 and temp >= 0.90 and humidity < 1 and v15 < 0.8 and math.abs(v13) < 0.2 and math.random() < 0.3 then -- Pine Tree
|
||||
local rand = math.random()
|
||||
local height = math.floor(9 + 6 * rand)
|
||||
local radius = 4 + 2 * rand
|
||||
vmg.make_pine_tree(pos, data, a, height, radius, c_pinetree, c_pineleaves, c_air, c_ignore)
|
||||
elseif v15 < 0.6 and temp >= 0.85 and temp < 2.3 and humidity < 3 and v16 < 2 and v14 > -0.5 and v13 < 0.8 then -- Apple Tree
|
||||
local rand = math.random()
|
||||
local height = math.floor(4 + 2.5 * rand)
|
||||
local radius = 3 + rand
|
||||
if math.random(1, 4) == 1 then
|
||||
vmg.make_apple_tree(pos, data, a, height, radius, c_tree, c_leaves, c_apple, c_air, c_ignore)
|
||||
else
|
||||
vmg.make_tree(pos, data, a, height, radius, c_tree, c_leaves, c_air, c_ignore)
|
||||
end
|
||||
elseif v15 < 0.7 and temp >= 1.9 and humidity > 2 and v16 > 2 then -- Jungle Tree
|
||||
local rand = math.random()
|
||||
local height = math.floor(8 + 4 * rand)
|
||||
local radius = 5 + 3 * rand
|
||||
vmg.make_jungle_tree(pos, data, a, height, radius, c_jungletree, c_jungleleaves, c_air, c_ignore)
|
||||
elseif temp > 0.38 and temp < 1 and humidity > 0.9 and v15 > 0 and v15 < 0.55 then -- Fir Tree
|
||||
local rand = math.random()
|
||||
local height = math.floor(9 + 6 * rand)
|
||||
local radius = 4 + 2 * rand
|
||||
vmg.make_fir_tree(pos, data, a, height, radius, c_firtree, c_firleaves, c_air, c_ignore)
|
||||
end
|
||||
elseif plants and math.random() < plant_density and above > 0 then -- make a plant
|
||||
if temp > 1 and temp < 1.8 and water > 0.7 and humidity > 3 and v13 > -0.4 and math.random() < 0.04 then -- Papyrus
|
||||
for i = 1, 4 do
|
||||
data[ivm+i*ystride] = c_papyrus
|
||||
end
|
||||
elseif v15 < 0.65 and temp >= 0.65 and temp < 1.5 and humidity < 2.6 and v16 < 1.5 and v13 < 0.8 and math.random() < 0.7 then -- Grass
|
||||
data[ivm2] = c_grass[math.random(1, 5)]
|
||||
elseif v15 > -0.6 and temp >= 1.8 and humidity > 2.2 and v16 > 1.8 then -- Jungle Grass
|
||||
data[ivm2] = c_junglegrass
|
||||
elseif v15 > 0.65 and humidity < 0.5 and math.random() < 0.2 then
|
||||
if v16 > 0 and temp > 1.6 and math.random() < 0.12 then -- Cactus
|
||||
for i = 1, 4 do
|
||||
data[ivm+i*ystride] = c_cactus
|
||||
end
|
||||
elseif temp > 1.2 then -- Dry Shrub
|
||||
data[ivm2] = c_dryshrub
|
||||
end
|
||||
end
|
||||
end
|
||||
y = y - 1
|
||||
end
|
||||
elseif above <= 0 then
|
||||
data[ivm] = c_stone
|
||||
elseif n6[i3d_sup+above*i3d_incrY] * slopes <= y + above - mountain_ground then -- if node at "above" nodes up is not in the ground, make dirt
|
||||
if is_beach and y < beach then
|
||||
data[ivm] = c_sand
|
||||
else
|
||||
data[ivm] = dirt
|
||||
end
|
||||
else
|
||||
data[ivm] = c_stone
|
||||
end
|
||||
elseif v11 + v12 > 2 ^ (y / lava_depth) and y <= lava_max_height then
|
||||
data[ivm] = c_lava
|
||||
end
|
||||
elseif y <= water_level then -- if pos is not in the ground, and below water_level, it's an ocean
|
||||
data[ivm] = c_water
|
||||
elseif river and y + 1 < base_ground then
|
||||
if river_water then
|
||||
data[ivm] = c_riverwater
|
||||
else
|
||||
data[ivm] = c_water
|
||||
end
|
||||
end
|
||||
|
||||
i3d = i3d + i3d_incrY -- increment i3d by one line
|
||||
i3d_sup = i3d_sup + i3d_incrY -- idem
|
||||
end
|
||||
i2d = i2d + i2d_incrZ -- increment i2d by one Z
|
||||
-- useless to increment i3d, because increment would be 0 !
|
||||
i3d_sup = i3d_sup + i3d_sup_incrZ -- for i3d_sup, just avoid the 6 supplemental lines
|
||||
end
|
||||
i2d = i2d - i2d_decrX -- decrement the Z line previously incremented and increment by one X (1)
|
||||
i3d = i3d - i3d_decrX -- decrement the YZ plane previously incremented and increment by one X (1)
|
||||
i3d_sup = i3d_sup - i3d_sup_decrX -- idem, including the supplemental lines
|
||||
end
|
||||
vmg.execute_after_mapgen() -- needed for jungletree roots
|
||||
|
||||
local t3 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Data collecting finished in " .. displaytime(t3-t2))
|
||||
print("[Valleys Mapgen] Writing data ...")
|
||||
end
|
||||
|
||||
-- execute voxelmanip boring stuff to write to the map
|
||||
vm:set_data(data)
|
||||
minetest.generate_ores(vm, minp, maxp)
|
||||
vm:set_lighting({day = 0, night = 0})
|
||||
vm:calc_lighting()
|
||||
vm:update_liquids()
|
||||
vm:write_to_map()
|
||||
|
||||
local t4 = os.clock()
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Data writing finished in " .. displaytime(t4-t3))
|
||||
end
|
||||
if vmg.loglevel >= 1 then
|
||||
print("[Valleys Mapgen] Mapgen finished in " .. displaytime(t4-t0))
|
||||
end
|
||||
end
|
||||
|
||||
dofile(vmg.path .. "/old_mapgens/2.1-trees.lua")
|
||||
|
||||
function vmg.get_humidity_raw(pos)
|
||||
local v13 = vmg.get_noise(pos, 13)
|
||||
local v15 = vmg.get_noise(pos, 15)
|
||||
local v18 = vmg.get_noise(pos, 18)
|
||||
return 2 ^ (v13 - v15 + v18 * 2)
|
||||
end
|
||||
|
||||
function vmg.get_humidity(pos)
|
||||
local y = pos.y
|
||||
local flatpos = pos2d(pos)
|
||||
local hraw = vmg.get_humidity_raw(flatpos)
|
||||
|
||||
local v1 = vmg.get_noise(flatpos, 1)
|
||||
local v3 = vmg.get_noise(flatpos, 3) ^ 2
|
||||
local base_ground = v1 + v3
|
||||
local sea_water = 0.5 ^ math.max((y - water_level) / 6, 0)
|
||||
local river_water = 0.5 ^ math.max((y - base_ground) / 3, 0)
|
||||
local water = sea_water + (1 - sea_water) * river_water
|
||||
return hraw + water
|
||||
end
|
||||
|
||||
function vmg.get_temperature(pos)
|
||||
local v12 = vmg.get_noise(pos, 12) + 1
|
||||
local v17 = vmg.get_noise(pos, 17)
|
||||
local y = pos.y
|
||||
if y > 0 then
|
||||
return v17 * 0.5 ^ (y / altitude_chill)
|
||||
else
|
||||
return v17 * 0.5 ^ (-y / altitude_chill) + 20 * v12 * (1 - 2 ^ (y / lava_depth))
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.get_noise(pos, i)
|
||||
local n = vmg.noises[i]
|
||||
local noise = minetest.get_perlin(n.seed, n.octaves, n.persist, 1)
|
||||
if not pos.z then
|
||||
return noise:get2d({x = pos.x / n.spread.x, y = pos.y / n.spread.y}) * n.scale + n.offset
|
||||
else
|
||||
return noise:get3d({x = pos.x / n.spread.x, y = pos.y / n.spread.y, z = pos.z / n.spread.z}) * n.scale + n.offset
|
||||
end
|
||||
end
|
||||
|
||||
local function round(n)
|
||||
return math.floor(n + 0.5)
|
||||
end
|
||||
|
||||
function vmg.get_elevation(pos)
|
||||
local v1 = vmg.get_noise(pos, 1)
|
||||
local v2 = math.abs(vmg.get_noise(pos, 2)) - river_size
|
||||
local v3 = vmg.get_noise(pos, 3) ^ 2
|
||||
local base_ground = v1 + v3
|
||||
if v2 < 0 then
|
||||
return math.ceil(base_ground), true
|
||||
end
|
||||
local v4 = vmg.get_noise(pos, 4)
|
||||
local v5 = vmg.get_noise(pos, 5)
|
||||
local base_ground = v1 + v3
|
||||
local valleys = v3 * (1 - math.exp(- (v2 / v4) ^ 2))
|
||||
local mountain_ground = base_ground + valleys
|
||||
local pos = pos3d(pos, round(mountain_ground))
|
||||
local slopes = v5 * valleys
|
||||
if vmg.get_noise(pos, 6) * slopes > pos.y - mountain_ground then
|
||||
pos.y = pos.y + 1
|
||||
while vmg.get_noise(pos, 6) * slopes > pos.y - mountain_ground do
|
||||
pos.y = pos.y + 1
|
||||
end
|
||||
return pos.y, false
|
||||
else
|
||||
pos.y = pos.y - 1
|
||||
while vmg.get_noise(pos, 6) * slopes <= pos.y - mountain_ground do
|
||||
pos.y = pos.y - 1
|
||||
end
|
||||
return pos.y, false
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.spawnplayer(player)
|
||||
local angle = math.random() * math.pi * 2
|
||||
local distance = math.random() * player_max_distance
|
||||
local p_angle = {x = math.cos(angle), y = math.sin(angle)}
|
||||
local pos = {x = -p_angle.x * distance, y = -p_angle.y * distance}
|
||||
local elevation, river = vmg.get_elevation(pos)
|
||||
while elevation < water_level + 2 or river do
|
||||
pos.x = pos.x + p_angle.x
|
||||
pos.y = pos.y + p_angle.y
|
||||
elevation, river = vmg.get_elevation({x = round(pos.x), y = round(pos.y)})
|
||||
end
|
||||
pos = {x = round(pos.x), y = round(elevation + 1), z = round(pos.y)}
|
||||
player:setpos(pos)
|
||||
return true
|
||||
end
|
|
@ -1,132 +0,0 @@
|
|||
vmg.settings = Settings(minetest.get_worldpath() .. "/vmg.conf")
|
||||
|
||||
local function define_str(flag, default, write_to_config)
|
||||
local value = vmg.settings:get(flag)
|
||||
if value then
|
||||
return value, true
|
||||
else
|
||||
local on_config = minetest.setting_get("vmg_" .. flag)
|
||||
if on_config then
|
||||
vmg.settings:set(flag, on_config)
|
||||
return on_config, false
|
||||
else
|
||||
if write_to_config then
|
||||
minetest.setting_set("vmg_" .. flag, default)
|
||||
end
|
||||
vmg.settings:set(flag, default)
|
||||
return default, false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function define_num(flag, default, write_to_config)
|
||||
local value = vmg.settings:get(flag)
|
||||
if value then
|
||||
return tonumber(value), true
|
||||
else
|
||||
local on_config = minetest.setting_get("vmg_" .. flag)
|
||||
if on_config then
|
||||
vmg.settings:set(flag, on_config)
|
||||
return tonumber(on_config), false
|
||||
else
|
||||
if write_to_config then
|
||||
minetest.setting_set("vmg_" .. flag, default)
|
||||
end
|
||||
vmg.settings:set(flag, default)
|
||||
return default, false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function define_bool(flag, default, write_to_config)
|
||||
local value = vmg.settings:get_bool(flag)
|
||||
if value ~= nil then
|
||||
return value, true
|
||||
else
|
||||
local on_config = minetest.setting_getbool("vmg_" .. flag)
|
||||
if on_config ~= nil then
|
||||
vmg.settings:set(flag, tostring(on_config))
|
||||
return on_config, false
|
||||
else
|
||||
if write_to_config then
|
||||
minetest.setting_setbool("vmg_" .. flag, default)
|
||||
end
|
||||
vmg.settings:set(flag, tostring(default))
|
||||
return default, false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function define_noise(flag, default, write_to_config)
|
||||
local value = vmg.settings:get(flag)
|
||||
if value then
|
||||
return vmg.string_to_noise(value), true
|
||||
else
|
||||
local on_config = minetest.setting_get("vmg_" .. flag)
|
||||
if on_config then
|
||||
vmg.settings:set(flag, on_config)
|
||||
return vmg.string_to_noise(on_config), false
|
||||
else
|
||||
local str_default = vmg.noise_to_string(default)
|
||||
if write_to_config then
|
||||
minetest.setting_set("vmg_" .. flag, str_default)
|
||||
end
|
||||
vmg.settings:set(flag, str_default)
|
||||
return default, false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.define(flag, default, write_to_config)
|
||||
local typeval = type(default)
|
||||
if typeval == "string" then
|
||||
return define_str(flag, default, write_to_config)
|
||||
elseif typeval == "number" then
|
||||
return define_num(flag, default, write_to_config)
|
||||
elseif typeval == "boolean" then
|
||||
return define_bool(flag, default, write_to_config)
|
||||
elseif typeval == "table" then
|
||||
return define_noise(flag, default, write_to_config)
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.noise_to_string(n)
|
||||
return n.offset ..
|
||||
", " .. n.scale ..
|
||||
", " .. minetest.pos_to_string(n.spread) ..
|
||||
", " .. n.seed ..
|
||||
", " .. n.octaves ..
|
||||
", " .. n.persist ..
|
||||
", " .. n.lacunarity
|
||||
end
|
||||
|
||||
function vmg.string_to_noise(str)
|
||||
local t = {}
|
||||
for line in str:gmatch("[%d%.%-e]+") do
|
||||
table.insert(t, tonumber(line))
|
||||
end
|
||||
return {
|
||||
offset = t[1],
|
||||
scale = t[2],
|
||||
spread = {x=t[3], y=t[4], z=t[5]},
|
||||
seed = t[6],
|
||||
octaves = t[7],
|
||||
persist = t[8],
|
||||
lacunarity = t[9],
|
||||
}
|
||||
end
|
||||
|
||||
if vmg.loglevel >= 2 then
|
||||
print("[Valleys Mapgen] Loading mapgen ...")
|
||||
end
|
||||
|
||||
-- Choose the appropriate mapgen version
|
||||
|
||||
local version = vmg.define("version", vmg.version)
|
||||
if version == vmg.version then
|
||||
dofile(vmg.path .. "/mapgen.lua")
|
||||
else
|
||||
dofile(vmg.path .. "/old_mapgens/" .. version .. ".lua")
|
||||
end
|
||||
|
||||
vmg.settings:write()
|
|
@ -1,40 +0,0 @@
|
|||
with GIMP :
|
||||
Color ~> Hue-Saturation
|
||||
|
||||
vmg_dirt_clayey.png
|
||||
from default_dirt.png
|
||||
Hue −6
|
||||
Brightness +5
|
||||
Saturation +40
|
||||
|
||||
vmg_dirt_sandy.png
|
||||
from default_dirt.png
|
||||
Hue +5
|
||||
Brightness +40
|
||||
Saturation −10
|
||||
|
||||
vmg_dirt_silty.png
|
||||
from default_dirt.png
|
||||
Hue +8
|
||||
Brightness −10
|
||||
Saturation −30
|
||||
|
||||
vmg_red_clay.png
|
||||
from default_dirt.png
|
||||
Hue −5
|
||||
Brightness +10
|
||||
Saturation +100
|
||||
|
||||
vmg_silt.png
|
||||
from default_dirt.png
|
||||
Hue +6
|
||||
Brightness +10
|
||||
Saturation −78
|
||||
|
||||
vmg_fir_tree.png :
|
||||
from default_wood.png
|
||||
Hue +6
|
||||
Brightness +50
|
||||
Saturation −24
|
||||
|
||||
And convert to indexed color.
|
Before Width: | Height: | Size: 324 B |
Before Width: | Height: | Size: 323 B |
Before Width: | Height: | Size: 323 B |
Before Width: | Height: | Size: 379 B |
Before Width: | Height: | Size: 289 B |
Before Width: | Height: | Size: 443 B |
Before Width: | Height: | Size: 362 B |
Before Width: | Height: | Size: 268 B |
Before Width: | Height: | Size: 323 B |
Before Width: | Height: | Size: 323 B |
|
@ -1,295 +0,0 @@
|
|||
local function can_grow(pos) -- from default mod
|
||||
local node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
|
||||
if not node_under then
|
||||
return false
|
||||
end
|
||||
local name_under = node_under.name
|
||||
local is_soil = minetest.get_item_group(name_under, "soil")
|
||||
if is_soil == 0 then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"valleys_mapgen:fir_sapling"},
|
||||
interval = 14,
|
||||
chance = 50,
|
||||
action = function(pos, node)
|
||||
if not can_grow(pos) then
|
||||
return
|
||||
end
|
||||
|
||||
minetest.log("action", "A fir sapling grows into a tree at "..
|
||||
minetest.pos_to_string(pos))
|
||||
vmg.grow_fir_tree(pos)
|
||||
end
|
||||
})
|
||||
|
||||
function default.grow_tree(pos, is_apple_tree)
|
||||
local rand = math.random()
|
||||
local height = math.floor(4 + 2.5 * rand)
|
||||
local radius = 3 + rand
|
||||
|
||||
local leaves = minetest.get_content_id("default:leaves")
|
||||
local trunk = minetest.get_content_id("default:tree")
|
||||
local air = minetest.get_content_id("air")
|
||||
local ignore = minetest.get_content_id("ignore")
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map({x = pos.x - 4, y = pos.y, z = pos.z - 4}, {x = pos.x + 4, y = pos.y + height + 4, z = pos.z + 4})
|
||||
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local data = vm:get_data()
|
||||
if is_apple_tree then
|
||||
vmg.make_apple_tree(pos, data, area, height, radius, trunk, leaves, minetest.get_content_id("default:apple"), air, ignore)
|
||||
else
|
||||
vmg.make_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
end
|
||||
vm:set_data(data)
|
||||
vm:write_to_map()
|
||||
vm:update_map()
|
||||
end
|
||||
|
||||
function default.grow_jungle_tree(pos)
|
||||
local rand = math.random()
|
||||
local height = math.floor(8 + 4 * rand)
|
||||
local radius = 5 + 3 * rand
|
||||
|
||||
local leaves = minetest.get_content_id("default:jungleleaves")
|
||||
local trunk = minetest.get_content_id("default:jungletree")
|
||||
local air = minetest.get_content_id("air")
|
||||
local ignore = minetest.get_content_id("ignore")
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map({x = pos.x - 8, y = pos.y - 1, z = pos.z - 8}, {x = pos.x + 8, y = pos.y + height + 5, z = pos.z + 8})
|
||||
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local data = vm:get_data()
|
||||
vmg.make_jungle_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
vmg.execute_after_mapgen()
|
||||
vm:set_data(data)
|
||||
vm:write_to_map()
|
||||
vm:update_map()
|
||||
end
|
||||
|
||||
function default.grow_pine_tree(pos)
|
||||
local rand = math.random()
|
||||
local height = math.floor(9 + 6 * rand)
|
||||
local radius = 4 + 2 * rand
|
||||
|
||||
local leaves = minetest.get_content_id("default:pine_needles")
|
||||
local trunk = minetest.get_content_id("default:pinetree")
|
||||
local air = minetest.get_content_id("air")
|
||||
local ignore = minetest.get_content_id("ignore")
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map({x = pos.x - 6, y = pos.y - 1, z = pos.z - 6}, {x = pos.x + 6, y = pos.y + height + 2, z = pos.z + 6})
|
||||
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local data = vm:get_data()
|
||||
vmg.make_pine_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
vm:set_data(data)
|
||||
vm:write_to_map()
|
||||
vm:update_map()
|
||||
end
|
||||
|
||||
function vmg.grow_fir_tree(pos)
|
||||
local rand = math.random()
|
||||
local height = math.floor(9 + 6 * rand)
|
||||
local radius = 4 + 2 * rand
|
||||
|
||||
local leaves = minetest.get_content_id("valleys_mapgen:fir_needles")
|
||||
local trunk = minetest.get_content_id("valleys_mapgen:fir_tree")
|
||||
local air = minetest.get_content_id("air")
|
||||
local ignore = minetest.get_content_id("ignore")
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map({x = pos.x - 6, y = pos.y - 1, z = pos.z - 6}, {x = pos.x + 6, y = pos.y + height + 2, z = pos.z + 6})
|
||||
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local data = vm:get_data()
|
||||
vmg.make_fir_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
vm:set_data(data)
|
||||
vm:write_to_map()
|
||||
vm:update_map()
|
||||
end
|
||||
|
||||
function vmg.make_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
if vmg.loglevel >= 3 then
|
||||
print("[Valleys Mapgen] Generating tree at " .. minetest.pos_to_string(pos) .. " ...")
|
||||
end
|
||||
local ystride = area.ystride
|
||||
local iv = area:indexp(pos)
|
||||
for i = 1, height do
|
||||
data[iv] = trunk
|
||||
iv = iv + ystride
|
||||
end
|
||||
local np = {offset = 0.8, scale = 0.4, spread = {x = 8, y = 4, z = 8}, octaves = 3, persist = 0.5}
|
||||
pos.y = pos.y + height - 1
|
||||
vmg.make_leavesblob(pos, data, area, leaves, air, ignore, {x = radius, y = radius, z = radius}, np)
|
||||
end
|
||||
|
||||
function vmg.make_apple_tree(pos, data, area, height, radius, trunk, leaves, fruit, air, ignore)
|
||||
if vmg.loglevel >= 3 then
|
||||
print("[Valleys Mapgen] Generating apple tree at " .. minetest.pos_to_string(pos) .. " ...")
|
||||
end
|
||||
local ystride = area.ystride
|
||||
local iv = area:indexp(pos)
|
||||
for i = 1, height do
|
||||
data[iv] = trunk
|
||||
iv = iv + ystride
|
||||
end
|
||||
local np = {offset = 0.8, scale = 0.4, spread = {x = 8, y = 4, z = 8}, octaves = 3, persist = 0.5}
|
||||
pos.y = pos.y + height - 1
|
||||
vmg.make_leavesblob(pos, data, area, leaves, air, ignore, {x = radius, y = radius, z = radius}, np, 0.06, fruit)
|
||||
end
|
||||
|
||||
local function make_jungle_root(x0, y0, z0, data, area, tree, air)
|
||||
local ystride = area.ystride
|
||||
local ybot = y0 - 1
|
||||
for x = x0 - 1, x0 + 1 do
|
||||
for z = z0 - 1, z0 + 1 do
|
||||
local iv = area:index(x, ybot, z)
|
||||
for i = 0, 5 do
|
||||
if data[iv] == air then
|
||||
if math.random() < 0.6 then
|
||||
data[iv-ystride] = tree -- make jungle tree below
|
||||
if math.random() < 0.6 then
|
||||
data[iv] = tree -- make jungle tree at this air node
|
||||
end
|
||||
end
|
||||
break
|
||||
end
|
||||
iv = iv + ystride
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.make_jungle_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
if vmg.loglevel >= 3 then
|
||||
print("[Valleys Mapgen] Generating jungle tree at " .. minetest.pos_to_string(pos) .. " ...")
|
||||
end
|
||||
local ystride = area.ystride
|
||||
local iv = area:indexp(pos)
|
||||
for i = 1, height do
|
||||
data[iv] = trunk
|
||||
iv = iv + ystride
|
||||
end
|
||||
vmg.register_after_mapgen(make_jungle_root, pos.x, pos.y, pos.z, data, area, trunk, air)
|
||||
local np = {offset = 0.8, scale = 0.4, spread = {x = 8, y = 4, z = 8}, octaves = 3, persist = 0.8}
|
||||
pos.y = pos.y + height
|
||||
vmg.make_leavesblob(pos, data, area, leaves, air, ignore, {x = radius, y = radius * 0.5, z = radius}, np)
|
||||
end
|
||||
|
||||
function vmg.make_fir_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
if vmg.loglevel >= 3 then
|
||||
print("[Valleys Mapgen] Generating fir tree at " .. minetest.pos_to_string(pos) .. " ...")
|
||||
end
|
||||
local ystride = area.ystride
|
||||
local iv = area:indexp(pos)
|
||||
for i = 1, height do
|
||||
data[iv] = trunk
|
||||
iv = iv + ystride
|
||||
end
|
||||
|
||||
-- add leaves on the top (4% 0 ; 36% 1 ; 60% 2)
|
||||
local rand = math.random()
|
||||
if rand < 0.96 then
|
||||
data[iv] = leaves
|
||||
if rand < 0.60 then
|
||||
iv = iv + ystride
|
||||
data[iv] = leaves
|
||||
end
|
||||
end
|
||||
|
||||
-- make several leaves rings
|
||||
local max_height = pos.y + height
|
||||
local min_height = pos.y + math.floor((0.2 + 0.3 * math.random()) * height)
|
||||
local radius_increment = (radius - 1.2) / (max_height - min_height)
|
||||
local np = {offset = 0.8, scale = 0.4, spread = {x = 12, y = 4, z = 12}, octaves = 3, persist = 0.8}
|
||||
|
||||
pos.y = max_height - 1
|
||||
while pos.y >= min_height do
|
||||
local ring_radius = (max_height - pos.y) * radius_increment + 1.2
|
||||
vmg.make_leavesblob(pos, data, area, leaves, air, ignore, {x = ring_radius, y = 2, z = ring_radius}, np)
|
||||
pos.y = pos.y - math.random(2, 3)
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.make_pine_tree(pos, data, area, height, radius, trunk, leaves, air, ignore)
|
||||
if vmg.loglevel >= 3 then
|
||||
print("[Valleys Mapgen] Generating pine tree at " .. minetest.pos_to_string(pos) .. " ...")
|
||||
end
|
||||
local ystride = area.ystride
|
||||
local iv = area:indexp(pos)
|
||||
for i = 1, height do
|
||||
data[iv] = trunk
|
||||
iv = iv + ystride
|
||||
end
|
||||
|
||||
-- add leaves on the top (4% 0 ; 36% 1 ; 60% 2)
|
||||
local rand = math.random()
|
||||
if rand < 0.96 then
|
||||
data[iv] = leaves
|
||||
if rand < 0.60 then
|
||||
iv = iv + ystride
|
||||
data[iv] = leaves
|
||||
end
|
||||
end
|
||||
|
||||
local np = {offset = 0.8, scale = 0.3, spread = {x = 8, y = 4, z = 8}, octaves = 3, persist = 1}
|
||||
local min_height = pos.y + math.floor((0.4 + 0.2 * math.random()) * height)
|
||||
local midradius = radius / 2
|
||||
|
||||
pos.y = pos.y + height - 1
|
||||
vmg.make_leavesblob(pos, data, area, leaves, air, ignore, {x = radius, y = 1.5, z = radius}, np)
|
||||
while pos.y >= min_height do
|
||||
local angle, distance = math.random() * 2 * math.pi, math.random() * midradius
|
||||
local cos, sin = math.cos(angle) * distance, math.sin(angle) * distance
|
||||
local bpos = {x = pos.x + cos, y = pos.y, z = pos.z + sin}
|
||||
vmg.make_leavesblob(bpos, data, area, leaves, air, ignore, {x = midradius, y = 1.5, z = midradius}, np)
|
||||
pos.y = pos.y - math.random(1, 2)
|
||||
end
|
||||
end
|
||||
|
||||
function vmg.make_leavesblob(pos, data, area, leaves, air, ignore, radius, np, fruit_chance, fruit)
|
||||
local count = 0
|
||||
fruit_chance = fruit_chance or 0
|
||||
|
||||
np.seed = math.random(0, 16777215)
|
||||
local minp = vector.subtract(pos, radius)
|
||||
local maxp = vector.add(pos, radius)
|
||||
local int_minp = {x = math.floor(minp.x), y = math.floor(minp.y), z = math.floor(minp.z)}
|
||||
local int_maxp = {x = math.ceil(maxp.x), y = math.ceil(maxp.y), z = math.ceil(maxp.z)}
|
||||
|
||||
local length = vector.subtract(int_maxp, int_minp)
|
||||
local chulens = vector.add(length, 1)
|
||||
local obj = minetest.get_perlin_map(np, chulens)
|
||||
local pmap = obj:get3dMap_flat(minp)
|
||||
local i = 1
|
||||
for x = int_minp.x, int_maxp.x do
|
||||
local xval = ((x - pos.x) / radius.x) ^ 2
|
||||
for y = int_minp.y, int_maxp.y do
|
||||
local yval = ((y - pos.y) / radius.y) ^ 2
|
||||
for z = int_minp.z, int_maxp.z do
|
||||
local zval = ((z - pos.z) / radius.z) ^ 2
|
||||
local dist = math.sqrt(xval + yval + zval)
|
||||
local nval = pmap[i]
|
||||
if nval > dist then
|
||||
local iv = area:index(x, y, z)
|
||||
if data[iv] == air or data[iv] == ignore then
|
||||
count = count + 1
|
||||
if math.random() < fruit_chance then
|
||||
data[iv] = fruit
|
||||
else
|
||||
data[iv] = leaves
|
||||
end
|
||||
end
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Adapt the code to the latest minetest_game that use these functions
|
||||
function default.grow_new_apple_tree(pos)
|
||||
local is_apple_tree = math.random(4) == 1
|
||||
default.grow_tree(pos, is_apple_tree)
|
||||
end
|
||||
default.grow_new_jungle_tree = default.grow_jungle_tree
|
||||
default.grow_new_pine_tree = default.grow_pine_tree
|
|
@ -1,88 +0,0 @@
|
|||
# format : FLAG = VALUE
|
||||
|
||||
# Settings are presents twice :
|
||||
# - In every world :
|
||||
# world_directory/vmg.conf
|
||||
|
||||
# - In the main directory :
|
||||
# usually main_directory/minetest.conf
|
||||
|
||||
# /!\ IMPORTANT : In minetest.conf, flags have to be preceded by "vmg_" like "vmg_average_stone_level".
|
||||
|
||||
|
||||
|
||||
#version = 2.2
|
||||
# mapgen version used.
|
||||
|
||||
#player_max_distance = 450
|
||||
# maximal distance from (0;0) at which the player will appear. (If it's in a big ocean, it may be farther)
|
||||
#spawn = true
|
||||
# New players are randomely spawned by the mod. Disable it to spawn the player another way.
|
||||
#respawn = true
|
||||
# After death, players are respawned by the mod. Disable it to respawn the player another way.
|
||||
|
||||
#water_level = 1
|
||||
#river_water = true
|
||||
# use river water instead of normal water in rivers.
|
||||
#waterflow = 3
|
||||
# maximal length of a river water flowing.
|
||||
|
||||
#average_stone_level = 180
|
||||
# height at which the half of the surface is made solely of stone.
|
||||
#average_snow_level = 100
|
||||
# height at which the half of the surface is covered by snow.
|
||||
#clay_threshold = 1
|
||||
# if noise 13 is above this value, make pure clay instead of clayey dirt.
|
||||
#silt_threshold = 1
|
||||
# if noise 14 is above this value, make pure silt instead of silty dirt.
|
||||
#sand_threshold = 0.75
|
||||
# if noise 15 is above this value, make desert sand instead of sandy dirt.
|
||||
#dirt_threshold = 0.5
|
||||
# if not any of noises 13, 14 and 15 is above this value, make normal dirt. Else make special dirt.
|
||||
#river_depth = 3
|
||||
#river_size = 5
|
||||
#caves_size = 7
|
||||
#lava_depth = 2000
|
||||
# to manage lava amount increasing by going deep underground : lower values = bigger increasing.
|
||||
#surface_lava = false
|
||||
# DEPRECATED. No longer supported since mapgen version 2.0. Use lava_max_height instead.
|
||||
#lava_max_height = -1
|
||||
# Lava can't be generated above this height. Use 31000 to disable this restriction, or -31000 to fully disable lava.
|
||||
#altitude_chill = 90
|
||||
|
||||
#trees = true
|
||||
# If false, no trees, of course !
|
||||
#plants = true
|
||||
#tree_density = 5
|
||||
# Percent of the lawn nodes that are covered by trees.
|
||||
#plant_density = 32
|
||||
|
||||
# NOISES : offset, scale, (spread), seed, octaves, persist, lacunarity
|
||||
# (see mapgen.lua to see what is the role of each noise)
|
||||
|
||||
#noise_1 = -10, 50, (1024,1024,1024), 5202, 6, 0.4, 2
|
||||
#noise_2 = 0, 1, (256,256,256), -6050, 5, 0.6, 2
|
||||
#noise_3 = 5, 4, (512,512,512), -1914, 1, 1, 2
|
||||
#noise_4 = 0.6, 0.5, (512,512,512), 777, 1, 1, 2
|
||||
#noise_5 = 0.5, 0.5, (128,128,128), 746, 1, 1, 2
|
||||
#noise_6 = 0, 1, (256,512,256), 1993, 6, 0.8, 2
|
||||
#noise_7 = 3, 1.75, (256,256,256), 1605, 3, 0.5, 2
|
||||
#noise_8 = 0, 1, (32,32,32), -4640, 4, 0.5, 2
|
||||
#noise_9 = 0, 1, (32,32,32), 8804, 4, 0.5, 2
|
||||
#noise_10 = 0, 1, (32,32,32), -4780, 4, 0.5, 2
|
||||
#noise_11 = 0, 1, (32,32,32), -9969, 4, 0.5, 2
|
||||
#noise_12 = 0, 1, (64,64,64), 3314, 4, 0.5, 2
|
||||
#noise_13 = 0, 1, (256,256,256), 2835, 5, 0.5, 4
|
||||
#noise_14 = 0, 1, (256,256,256), 6674, 5, 0.5, 4
|
||||
#noise_15 = 0, 1, (256,256,256), 6940, 5, 0.5, 4
|
||||
#noise_16 = 2, 8, (256,256,256), 2349, 3, 0.5, 2
|
||||
#noise_17 = 0, 1, (768,256,768), -1805, 4, 0.5, 4
|
||||
#noise_18 = 0, 1, (243,243,243), -5787, 4, 0.5, 3
|
||||
|
||||
# Flags that are ONLY available in minetest.conf :
|
||||
|
||||
#vmg_log_level = 0
|
||||
# 0 = Not any log from Valleys Mapgen
|
||||
# 1 = Total mapgen time
|
||||
# 2 = Detailed mapgen time (step by step)
|
||||
# 3 = Detailed mapgen time + trees
|
|
@ -278,11 +278,14 @@ if EROSION then
|
|||
local nodename = node.name
|
||||
for i in ipairs (dirt_table) do
|
||||
local original = dirt_table[i][2]
|
||||
local replacement = dirt_table[i][1]
|
||||
local replacement = dirt_table[i][1]
|
||||
local node_above = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z})
|
||||
if nodename == original then
|
||||
if node_above.name == 'air' then
|
||||
env:add_node(pos,{name=replacement})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
local players = {}
|
||||
local player_positions = {}
|
||||
local last_wielded = {}
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
local player_name = player:get_player_name()
|
||||
table.insert(players, player_name)
|
||||
local pos = player:getpos()
|
||||
pos = {x=math.floor(pos.x + 0.5),y=math.floor(pos.y + 1.5),z=math.floor(pos.z + 0.5)}
|
||||
local wielded_item = player:get_wielded_item():get_name()
|
||||
last_wielded[player_name] = wielded_item ~= "default:torch" and wielded_item ~= "walking_light:pick_mese"
|
||||
player_positions[player_name] = pos;
|
||||
end)
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local player_name = player:get_player_name()
|
||||
for i,v in ipairs(players) do
|
||||
if v == player_name then
|
||||
table.remove(players, i)
|
||||
end
|
||||
end
|
||||
if last_wielded[player_name] then
|
||||
local pos = player:getpos()
|
||||
pos = {x=math.floor(pos.x + 0.5),y=math.floor(pos.y + 1.5),z=math.floor(pos.z + 0.5)}
|
||||
minetest.env:add_node(pos,{type="node",name="air"})
|
||||
end
|
||||
last_wielded[player_name] = false
|
||||
player_positions[player_name]=nil
|
||||
end)
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
for i,player_name in ipairs(players) do
|
||||
local player = minetest.env:get_player_by_name(player_name)
|
||||
local wielded = false
|
||||
local pos
|
||||
local old_pos = player_positions[player_name]
|
||||
local pos_changed = false
|
||||
if player ~= nil then
|
||||
local wielded_item = player:get_wielded_item():get_name()
|
||||
wielded = wielded_item == "default:torch" or wielded_item == "walking_light:pick_mese"
|
||||
if wielded or last_wielded[player_name] then
|
||||
pos = player:getpos()
|
||||
pos = {x=math.floor(pos.x + 0.5),y=math.floor(pos.y + 1.5),z=math.floor(pos.z + 0.5)}
|
||||
player_positions[player_name] = pos
|
||||
pos_changed = (old_pos.x ~= pos.x or old_pos.y ~= pos.y or old_pos.z ~= pos.z)
|
||||
end
|
||||
end
|
||||
|
||||
if wielded then
|
||||
local node = minetest.env:get_node_or_nil(pos)
|
||||
if (node == nil or (node ~= nil and node.name == "air")) then
|
||||
minetest.env:add_node(pos,{type="node",name="walking_light:light"})
|
||||
end
|
||||
end
|
||||
|
||||
if last_wielded[player_name] and (pos_changed or not wielded) then
|
||||
local node = minetest.env:get_node_or_nil(old_pos)
|
||||
if node ~= nil and node.name == "walking_light:light" then
|
||||
minetest.env:add_node(old_pos,{type="node",name="air"})
|
||||
end
|
||||
end
|
||||
|
||||
last_wielded[player_name] = wielded
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_node("walking_light:light", {
|
||||
drawtype = "glasslike",
|
||||
tile_images = {"walking_light.png"},
|
||||
-- tile_images = {"walking_light_debug.png"},
|
||||
inventory_image = minetest.inventorycube("walking_light.png"),
|
||||
paramtype = "light",
|
||||
walkable = false,
|
||||
is_ground_content = true,
|
||||
light_propagates = true,
|
||||
sunlight_propagates = true,
|
||||
light_source = 13,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {0, 0, 0, 0, 0, 0},
|
||||
},
|
||||
})
|
||||
minetest.register_tool("walking_light:pick_mese", {
|
||||
description = "Mese Pickaxe with light",
|
||||
inventory_image = "walking_light_mesepick.png",
|
||||
wield_image = "default_tool_mesepick.png",
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 1.0,
|
||||
max_drop_level=3,
|
||||
groupcaps={
|
||||
cracky={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3},
|
||||
crumbly={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3},
|
||||
snappy={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'walking_light:pick_mese',
|
||||
recipe = {
|
||||
{'default:torch'},
|
||||
{'default:pick_mese'},
|
||||
}
|
||||
})
|
After Width: | Height: | Size: 246 B |
After Width: | Height: | Size: 219 B |
After Width: | Height: | Size: 402 B |