X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fmapgen.cpp;h=3212b693289921012b1be52d3b7c7d920ecdf404;hb=75821c6889378ff7eba7cddac28acab1537ed934;hp=74521d3a1d873fbc86fb639dddb2844c5515ea8b;hpb=4f01db256f7ee4ece5515c417919fb975dab0dca;p=oweals%2Fminetest.git diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 74521d3a1..3212b6932 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -70,13 +70,14 @@ static s16 find_ground_level_clever(VoxelManipulator &vmanip, v2s16 p2d, 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); @@ -96,7 +97,7 @@ static s16 find_stone_level(VoxelManipulator &vmanip, v2s16 p2d, 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]; @@ -115,9 +116,9 @@ static s16 find_stone_level(VoxelManipulator &vmanip, v2s16 p2d, 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; @@ -192,11 +193,12 @@ void make_tree(ManualMapVoxelManipulator &vmanip, v3s16 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++) @@ -279,10 +281,10 @@ static void make_jungletree(VoxelManipulator &vmanip, v3s16 p0, } } -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; @@ -294,10 +296,10 @@ void make_papyrus(VoxelManipulator &vmanip, v3s16 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; @@ -308,7 +310,9 @@ void make_cactus(VoxelManipulator &vmanip, v3s16 p0, p1.Y++; } } +#endif +#if 0 /* Dungeon making routines */ @@ -332,7 +336,7 @@ static void make_room1(VoxelManipulator &vmanip, v3s16 roomsize, v3s16 roomplace 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); @@ -341,7 +345,7 @@ static void make_room1(VoxelManipulator &vmanip, v3s16 roomsize, v3s16 roomplace 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")); } } @@ -356,7 +360,7 @@ static void make_room1(VoxelManipulator &vmanip, v3s16 roomsize, v3s16 roomplace 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); @@ -365,7 +369,7 @@ static void make_room1(VoxelManipulator &vmanip, v3s16 roomsize, v3s16 roomplace 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")); } } @@ -380,7 +384,7 @@ static void make_room1(VoxelManipulator &vmanip, v3s16 roomsize, v3s16 roomplace 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); @@ -389,7 +393,7 @@ static void make_room1(VoxelManipulator &vmanip, v3s16 roomsize, v3s16 roomplace 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")); } } @@ -437,7 +441,7 @@ static void make_door1(VoxelManipulator &vmanip, v3s16 doorplace, v3s16 doordir, { 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) @@ -524,7 +528,7 @@ static void make_corridor(VoxelManipulator &vmanip, v3s16 doorplace, 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), @@ -533,7 +537,7 @@ static void make_corridor(VoxelManipulator &vmanip, v3s16 doorplace, 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);*/ @@ -612,9 +616,9 @@ public: 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; @@ -628,25 +632,25 @@ public: */ // 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(); @@ -798,7 +802,7 @@ static void make_dungeon1(VoxelManipulator &vmanip, PseudoRandom &random, 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) @@ -860,7 +864,9 @@ static void make_dungeon1(VoxelManipulator &vmanip, PseudoRandom &random, } } +#endif +#if 0 static void make_nc(VoxelManipulator &vmanip, PseudoRandom &random, INodeDefManager *ndef) { @@ -887,14 +893,15 @@ static void make_nc(VoxelManipulator &vmanip, PseudoRandom &random, 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; jgetId("mapgen_nyancat_rainbow")); } } +#endif /* Noise functions. Make sure seed is mangled differently in each one. @@ -1200,9 +1207,9 @@ double base_rock_level_2d(u64 seed, v2s16 p) 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 @@ -1214,11 +1221,19 @@ double base_rock_level_2d(u64 seed, v2s16 p) 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="< -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 @@ -1319,15 +1340,12 @@ void make_block(BlockMakeData *data) //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 @@ -1335,7 +1353,7 @@ void make_block(BlockMakeData *data) // 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); @@ -1409,12 +1427,14 @@ void make_block(BlockMakeData *data) 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); } @@ -1423,6 +1443,42 @@ void make_block(BlockMakeData *data) #endif }//timer1 + + /* + Add blobs of dirt and gravel underground + */ + { + PseudoRandom pr(blockseed+983); + for(int i=0; i -32 && pr.range(0,1) == 0) + n1 = MapNode(c_dirt); + else + n1 = MapNode(c_gravel); + for(int x1=0; x1seed, p2d) / 2.0; @@ -1701,6 +1775,14 @@ void make_block(BlockMakeData *data) 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 @@ -1727,7 +1809,7 @@ void make_block(BlockMakeData *data) break; MapNode &n = vmanip.m_data[i]; - n = MapNode(c_dirt); + n = addnode; mudcount++; vmanip.m_area.add_y(em, i, 1); @@ -2288,7 +2370,7 @@ void make_block(BlockMakeData *data) // 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;