s16 y_nodes_min = vmanip.m_area.MinEdge.Y;
u32 i = vmanip.m_area.index(v3s16(p2d.X, y_nodes_max, p2d.Y));
s16 y;
+ content_t c_tree = ndef->getId("mapgen_tree");
+ content_t c_leaves = ndef->getId("mapgen_leaves");
for(y=y_nodes_max; y>=y_nodes_min; y--)
{
MapNode &n = vmanip.m_data[i];
if(ndef->get(n).walkable
- // TODO: Cache LEGN values
- && n.getContent() != LEGN(ndef, "CONTENT_TREE")
- && n.getContent() != LEGN(ndef, "CONTENT_LEAVES"))
+ && n.getContent() != c_tree
+ && n.getContent() != c_leaves)
break;
vmanip.m_area.add_y(em, i, -1);
s16 y_nodes_min = vmanip.m_area.MinEdge.Y;
u32 i = vmanip.m_area.index(v3s16(p2d.X, y_nodes_max, p2d.Y));
s16 y;
- content_t c_stone = LEGN(ndef, "CONTENT_STONE");
+ content_t c_stone = ndef->getId("mapgen_stone");
for(y=y_nodes_max; y>=y_nodes_min; y--)
{
MapNode &n = vmanip.m_data[i];
void make_tree(ManualMapVoxelManipulator &vmanip, v3s16 p0,
bool is_apple_tree, INodeDefManager *ndef)
{
- MapNode treenode(LEGN(ndef, "CONTENT_TREE"));
- MapNode leavesnode(LEGN(ndef, "CONTENT_LEAVES"));
- MapNode applenode(LEGN(ndef, "CONTENT_APPLE"));
+ MapNode treenode(ndef->getId("mapgen_tree"));
+ MapNode leavesnode(ndef->getId("mapgen_leaves"));
+ MapNode applenode(ndef->getId("mapgen_apple"));
s16 trunk_h = myrand_range(4, 5);
v3s16 p1 = p0;
}
}
+#if 0
static void make_jungletree(VoxelManipulator &vmanip, v3s16 p0,
INodeDefManager *ndef)
{
- MapNode treenode(LEGN(ndef, "CONTENT_JUNGLETREE"));
- MapNode leavesnode(LEGN(ndef, "CONTENT_LEAVES"));
+ MapNode treenode(ndef->getId("mapgen_jungletree"));
+ MapNode leavesnode(ndef->getId("mapgen_leaves"));
for(s16 x=-1; x<=1; x++)
for(s16 z=-1; z<=1; z++)
}
}
-void make_papyrus(VoxelManipulator &vmanip, v3s16 p0,
+static void make_papyrus(VoxelManipulator &vmanip, v3s16 p0,
INodeDefManager *ndef)
{
- MapNode papyrusnode(LEGN(ndef, "CONTENT_PAPYRUS"));
+ MapNode papyrusnode(ndef->getId("mapgen_papyrus"));
s16 trunk_h = myrand_range(2, 3);
v3s16 p1 = p0;
}
}
-void make_cactus(VoxelManipulator &vmanip, v3s16 p0,
+static void make_cactus(VoxelManipulator &vmanip, v3s16 p0,
INodeDefManager *ndef)
{
- MapNode cactusnode(LEGN(ndef, "CONTENT_CACTUS"));
+ MapNode cactusnode(ndef->getId("mapgen_cactus"));
s16 trunk_h = 3;
v3s16 p1 = p0;
p1.Y++;
}
}
+#endif
+#if 0
/*
Dungeon making routines
*/
u32 vi = vmanip.m_area.index(p);
if(vmanip.m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE)
continue;
- vmanip.m_data[vi] = MapNode(LEGN(ndef, "CONTENT_COBBLE"));
+ vmanip.m_data[vi] = MapNode(ndef->getId("mapgen_cobble"));
}
{
v3s16 p = roomplace + v3s16(roomsize.X-1,y,z);
u32 vi = vmanip.m_area.index(p);
if(vmanip.m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE)
continue;
- vmanip.m_data[vi] = MapNode(LEGN(ndef, "CONTENT_COBBLE"));
+ vmanip.m_data[vi] = MapNode(ndef->getId("mapgen_cobble"));
}
}
u32 vi = vmanip.m_area.index(p);
if(vmanip.m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE)
continue;
- vmanip.m_data[vi] = MapNode(LEGN(ndef, "CONTENT_COBBLE"));
+ vmanip.m_data[vi] = MapNode(ndef->getId("mapgen_cobble"));
}
{
v3s16 p = roomplace + v3s16(x,y,roomsize.Z-1);
u32 vi = vmanip.m_area.index(p);
if(vmanip.m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE)
continue;
- vmanip.m_data[vi] = MapNode(LEGN(ndef, "CONTENT_COBBLE"));
+ vmanip.m_data[vi] = MapNode(ndef->getId("mapgen_cobble"));
}
}
u32 vi = vmanip.m_area.index(p);
if(vmanip.m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE)
continue;
- vmanip.m_data[vi] = MapNode(LEGN(ndef, "CONTENT_COBBLE"));
+ vmanip.m_data[vi] = MapNode(ndef->getId("mapgen_cobble"));
}
{
v3s16 p = roomplace + v3s16(x,roomsize.Y-1,z);
u32 vi = vmanip.m_area.index(p);
if(vmanip.m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE)
continue;
- vmanip.m_data[vi] = MapNode(LEGN(ndef, "CONTENT_COBBLE"));
+ vmanip.m_data[vi] = MapNode(ndef->getId("mapgen_cobble"));
}
}
{
make_hole1(vmanip, doorplace, ndef);
// Place torch (for testing)
- //vmanip.m_data[vmanip.m_area.index(doorplace)] = MapNode(LEGN(ndef, "CONTENT_TORCH"));
+ //vmanip.m_data[vmanip.m_area.index(doorplace)] = MapNode(ndef->getId("mapgen_torch"));
}
static v3s16 rand_ortho_dir(PseudoRandom &random)
if(make_stairs)
{
make_fill(vmanip, p+v3s16(-1,-1,-1), v3s16(3,5,3),
- VMANIP_FLAG_DUNGEON_UNTOUCHABLE, MapNode(LEGN(ndef, "CONTENT_COBBLE")), 0);
+ VMANIP_FLAG_DUNGEON_UNTOUCHABLE, MapNode(ndef->getId("mapgen_cobble")), 0);
make_fill(vmanip, p, v3s16(1,2,1), 0, MapNode(CONTENT_AIR),
VMANIP_FLAG_DUNGEON_INSIDE);
make_fill(vmanip, p-dir, v3s16(1,2,1), 0, MapNode(CONTENT_AIR),
else
{
make_fill(vmanip, p+v3s16(-1,-1,-1), v3s16(3,4,3),
- VMANIP_FLAG_DUNGEON_UNTOUCHABLE, MapNode(LEGN(ndef, "CONTENT_COBBLE")), 0);
+ VMANIP_FLAG_DUNGEON_UNTOUCHABLE, MapNode(ndef->getId("mapgen_cobble")), 0);
make_hole1(vmanip, p, ndef);
/*make_fill(vmanip, p, v3s16(1,2,1), 0, MapNode(CONTENT_AIR),
VMANIP_FLAG_DUNGEON_INSIDE);*/
continue;
}
if(vmanip.getNodeNoExNoEmerge(p).getContent()
- == LEGN(m_ndef, "CONTENT_COBBLE")
+ == m_ndef->getId("mapgen_cobble")
&& vmanip.getNodeNoExNoEmerge(p1).getContent()
- == LEGN(m_ndef, "CONTENT_COBBLE"))
+ == m_ndef->getId("mapgen_cobble"))
{
// Found wall, this is a good place!
result_place = p;
*/
// Jump one up if the actual space is there
if(vmanip.getNodeNoExNoEmerge(p+v3s16(0,0,0)).getContent()
- == LEGN(m_ndef, "CONTENT_COBBLE")
+ == m_ndef->getId("mapgen_cobble")
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,1,0)).getContent()
- == LEGN(m_ndef, "CONTENT_AIR")
+ == CONTENT_AIR
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,2,0)).getContent()
- == LEGN(m_ndef, "CONTENT_AIR"))
+ == CONTENT_AIR)
p += v3s16(0,1,0);
// Jump one down if the actual space is there
if(vmanip.getNodeNoExNoEmerge(p+v3s16(0,1,0)).getContent()
- == LEGN(m_ndef, "CONTENT_COBBLE")
+ == m_ndef->getId("mapgen_cobble")
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,0,0)).getContent()
- == LEGN(m_ndef, "CONTENT_AIR")
+ == CONTENT_AIR
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,-1,0)).getContent()
- == LEGN(m_ndef, "CONTENT_AIR"))
+ == CONTENT_AIR)
p += v3s16(0,-1,0);
// Check if walking is now possible
if(vmanip.getNodeNoExNoEmerge(p).getContent()
- != LEGN(m_ndef, "CONTENT_AIR")
+ != CONTENT_AIR
|| vmanip.getNodeNoExNoEmerge(p+v3s16(0,1,0)).getContent()
- != LEGN(m_ndef, "CONTENT_AIR"))
+ != CONTENT_AIR)
{
// Cannot continue walking here
randomizeDir();
v3s16 room_center = roomplace + v3s16(roomsize.X/2,1,roomsize.Z/2);
// Place torch at room center (for testing)
- //vmanip.m_data[vmanip.m_area.index(room_center)] = MapNode(LEGN(ndef, "CONTENT_TORCH"));
+ //vmanip.m_data[vmanip.m_area.index(room_center)] = MapNode(ndef->getId("mapgen_torch"));
// Quit if last room
if(i == room_count-1)
}
}
+#endif
+#if 0
static void make_nc(VoxelManipulator &vmanip, PseudoRandom &random,
INodeDefManager *ndef)
{
16+random.range(0,15),
16+random.range(0,15),
16+random.range(0,15));
- vmanip.m_data[vmanip.m_area.index(p)] = MapNode(LEGN(ndef, "CONTENT_NC"), facedir_i);
+ vmanip.m_data[vmanip.m_area.index(p)] = MapNode(ndef->getId("mapgen_nyancat"), facedir_i);
u32 length = random.range(3,15);
for(u32 j=0; j<length; j++)
{
p -= dir;
- vmanip.m_data[vmanip.m_area.index(p)] = MapNode(LEGN(ndef, "CONTENT_NC_RB"));
+ vmanip.m_data[vmanip.m_area.index(p)] = MapNode(ndef->getId("mapgen_nyancat_rainbow"));
}
}
+#endif
/*
Noise functions. Make sure seed is mangled differently in each one.
base = base2;*/
#if 1
// Higher ground level
- double higher = (double)WATER_LEVEL + 20. + 10. * noise2d_perlin(
- 0.5+(float)p.X/250., 0.5+(float)p.Y/250.,
- seed+85039, 4, 0.6);
+ double higher = (double)WATER_LEVEL + 20. + 16. * noise2d_perlin(
+ 0.5+(float)p.X/500., 0.5+(float)p.Y/500.,
+ seed+85039, 5, 0.6);
//higher = 30; // For debugging
// Limit higher to at least base
0.5+(float)p.X/125., 0.5+(float)p.Y/125.,
seed-932, 5, 0.7);
b = rangelim(b, 0.0, 1000.0);
- b = pow(b, 8);
+ b = pow(b, 7);
b *= 5;
- b = rangelim(b, 3.0, 1000.0);
+ b = rangelim(b, 0.5, 1000.0);
+ // Values 1.5...100 give quite horrible looking slopes
+ if(b > 1.5 && b < 100.0){
+ if(b < 10.0)
+ b = 1.5;
+ else
+ b = 100.0;
+ }
//dstream<<"b="<<b<<std::endl;
//double b = 20;
+ //b = 0.25;
// Offset to more low
double a_off = -0.20;
seed+91013, 3, 0.55));
}
-bool get_have_sand(u64 seed, v2s16 p2d)
+bool get_have_beach(u64 seed, v2s16 p2d)
{
// Determine whether to have sand here
double sandnoise = noise2d_perlin(
0.5+(float)p2d.X/500, 0.5+(float)p2d.Y/500,
seed+59420, 3, 0.50);
- return (sandnoise > -0.15);
+ return (sandnoise > 0.15);
+}
+
+u32 get_blockseed(u64 seed, v3s16 p)
+{
+ s32 x=p.X, y=p.Y, z=p.Z;
+ return (u32)(seed%0x100000000ULL) + z*38134234 + y*42123 + x*23;
}
#define VMANIP_FLAG_CAVE VOXELFLAG_CHECKED1
//double gen_area_nodes = MAP_BLOCKSIZE*MAP_BLOCKSIZE * rel_volume;
// Horribly wrong heuristic, but better than nothing
- bool block_is_underground = (WATER_LEVEL /* local minimum ground level */ >
- MAP_BLOCKSIZE * (data->blockpos_max.X
- - data->blockpos_min.X + 1) / 2);
+ bool block_is_underground = (WATER_LEVEL > node_max.Y);
/*
Create a block-specific seed
*/
- /*u32 blockseed = (u32)(data->seed%0x100000000ULL) + full_node_min.Z*38134234
- + full_node_min.Y*42123 + full_node_min.X*23;*/
+ u32 blockseed = get_blockseed(data->seed, full_node_min);
/*
Cache some ground type values for speed
// Creates variables c_name=id and n_name=node
#define CONTENT_VARIABLE(ndef, name)\
- content_t c_##name = ndef->getId(#name);\
+ content_t c_##name = ndef->getId("mapgen_" #name);\
MapNode n_##name(c_##name);
CONTENT_VARIABLE(ndef, stone);
u32 i = vmanip.m_area.index(v3s16(p2d.X, node_min.Y, p2d.Y));
for(s16 y=node_min.Y; y<=node_max.Y; y++)
{
- if(y <= surface_y)
- vmanip.m_data[i] = MapNode(c_stone);
- else if(y <= WATER_LEVEL)
+ if(y <= surface_y){
+ if(vmanip.m_data[i].getContent() == CONTENT_IGNORE)
+ vmanip.m_data[i] = MapNode(c_stone);
+ } else if(y <= WATER_LEVEL){
vmanip.m_data[i] = MapNode(c_water_source);
- else
+ } else {
vmanip.m_data[i] = MapNode(c_air);
+ }
vmanip.m_area.add_y(em, i, 1);
}
#endif
}//timer1
+
+ /*
+ Add blobs of dirt and gravel underground
+ */
+ {
+ PseudoRandom pr(blockseed+983);
+ for(int i=0; i<volume_nodes/12/12/12; i++){
+ v3s16 size(
+ pr.range(1, 6),
+ pr.range(1, 6),
+ pr.range(1, 6)
+ );
+ v3s16 p0(
+ pr.range(node_min.X, node_max.X)-size.X/2,
+ pr.range(node_min.Y, node_max.Y)-size.Y/2,
+ pr.range(node_min.Z, node_max.Z)-size.Z/2
+ );
+ MapNode n1;
+ if(p0.Y > -32 && pr.range(0,1) == 0)
+ n1 = MapNode(c_dirt);
+ else
+ n1 = MapNode(c_gravel);
+ for(int x1=0; x1<size.X; x1++)
+ for(int y1=0; y1<size.Y; y1++)
+ for(int z1=0; z1<size.Z; z1++)
+ {
+ v3s16 p = p0 + v3s16(x1,y1,z1);
+ u32 i = vmanip.m_area.index(p);
+ if(!vmanip.m_area.contains(i))
+ continue;
+ if(vmanip.m_data[i].getContent() != c_stone)
+ continue;
+ vmanip.m_data[i] = n1;
+ }
+ }
+ }
// Limit dirt flow area by 1 because mud is flown into neighbors.
assert(central_area_size.X == central_area_size.Z);
u32 bruises_count = volume_nodes * stone_surface_max_y / 40000000;
if(stone_surface_max_y < WATER_LEVEL - 20)
bruises_count = 0;
- /*u32 caves_count = 0;
- u32 bruises_count = 0;*/
for(u32 jj=0; jj<caves_count+bruises_count; jj++)
{
s16 min_tunnel_diameter = 2;
- s16 max_tunnel_diameter = 5;
+ s16 max_tunnel_diameter = myrand_range(4,5);
u16 tunnel_routepoints = 20;
v3f main_direction(0,0,0);
);
MapNode airnode(CONTENT_AIR);
+ MapNode waternode(c_water_source);
/*
Generate some tunnel starting from orp
v3s16 maxlen;
if(bruise_surface)
{
- maxlen = v3s16(rs*7,rs*7,rs*7);
+ maxlen = v3s16(rs*7,rs*2,rs*7);
}
else
{
);
}
+ if(bruise_surface){
+ v3f p = orp + vec;
+ s16 h = find_ground_level_clever(vmanip,
+ v2s16(p.X, p.Z), ndef);
+ route_y_min = h - rs/3;
+ route_y_max = h + rs;
+ }
+
vec += main_direction;
v3f rp = orp + vec;
for(float f=0; f<1.0; f+=1.0/vec.getLength())
{
v3f fp = orp + vec * f;
+ fp.X += 0.1*myrand_range(-10,10);
+ fp.Z += 0.1*myrand_range(-10,10);
v3s16 cp(fp.X, fp.Y, fp.Z);
s16 d0 = -rs/2;
s16 d1 = d0 + rs - 1;
for(s16 z0=d0; z0<=d1; z0++)
{
- //s16 si = rs - MYMAX(0, abs(z0)-rs/4);
- s16 si = rs - MYMAX(0, abs(z0)-rs/7);
+ s16 si = rs - MYMAX(0, abs(z0)-rs/4);
+ //s16 si = rs - MYMAX(0, abs(z0)-rs/7);
for(s16 x0=-si; x0<=si-1; x0++)
{
s16 maxabsxz = MYMAX(abs(x0), abs(z0));
// Just set it to air, it will be changed to
// water afterwards
u32 i = vmanip.m_area.index(p);
- vmanip.m_data[i] = airnode;
+ if(bruise_surface){
+ if(p.Y <= WATER_LEVEL)
+ vmanip.m_data[i] = waternode;
+ else
+ vmanip.m_data[i] = airnode;
+ } else {
+ vmanip.m_data[i] = airnode;
+ }
if(bruise_surface == false)
{
// Node position in 2d
v2s16 p2d = v2s16(x,z);
+ MapNode addnode(c_dirt);
+
// Randomize mud amount
s16 mud_add_amount = get_mud_add_amount(data->seed, p2d) / 2.0;
if(surface_y == vmanip.m_area.MinEdge.Y - 1)
continue;
+ if(mud_add_amount <= 0){
+ mud_add_amount = 1 - mud_add_amount;
+ addnode = MapNode(c_gravel);
+ } else if(get_have_beach(data->seed, p2d) &&
+ surface_y + mud_add_amount <= WATER_LEVEL+2){
+ addnode = MapNode(c_sand);
+ }
+
/*
If topmost node is grass, change it to mud.
It might be if it was flown to there from a neighboring
break;
MapNode &n = vmanip.m_data[i];
- n = MapNode(c_dirt);
+ n = addnode;
mudcount++;
vmanip.m_area.add_y(em, i, 1);
// Node position
v2s16 p2d(x,z);
{
- bool possibly_have_sand = get_have_sand(data->seed, p2d);
+ bool possibly_have_sand = get_have_beach(data->seed, p2d);
bool have_sand = false;
u32 current_depth = 0;
bool air_detected = false;