diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/content_mapblock.cpp | 62 | ||||
-rw-r--r-- | src/content_mapnode.cpp | 24 | ||||
-rw-r--r-- | src/content_mapnode.h | 2 | ||||
-rw-r--r-- | src/mapgen.cpp | 168 | ||||
-rw-r--r-- | src/mapnode.h | 3 |
5 files changed, 253 insertions, 6 deletions
diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index d8bf71dc0..730907222 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -198,6 +198,17 @@ void mapblock_mesh_generate_special(MeshMakeData *data, AtlasPointer pa_papyrus = g_texturesource->getTexture( g_texturesource->getTextureId("papyrus.png")); material_papyrus.setTexture(0, pa_papyrus.atlas); + + // junglegrass material + video::SMaterial material_junglegrass; + material_junglegrass.setFlag(video::EMF_LIGHTING, false); + material_junglegrass.setFlag(video::EMF_BILINEAR_FILTER, false); + material_junglegrass.setFlag(video::EMF_FOG_ENABLE, true); + material_junglegrass.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + AtlasPointer pa_junglegrass = g_texturesource->getTexture( + g_texturesource->getTextureId("junglegrass.png")); + material_junglegrass.setTexture(0, pa_junglegrass.atlas); + for(s16 z=0; z<MAP_BLOCKSIZE; z++) for(s16 y=0; y<MAP_BLOCKSIZE; y++) for(s16 x=0; x<MAP_BLOCKSIZE; x++) @@ -966,6 +977,57 @@ void mapblock_mesh_generate_special(MeshMakeData *data, collector.append(material_papyrus, vertices, 4, indices, 6); } } + else if(n.d == CONTENT_JUNGLEGRASS) + { + u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio))); + video::SColor c(255,l,l,l); + + for(u32 j=0; j<4; j++) + { + video::S3DVertex vertices[4] = + { + video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, + pa_papyrus.x0(), pa_papyrus.y1()), + video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, + pa_papyrus.x1(), pa_papyrus.y1()), + video::S3DVertex(BS/2,BS/1,0, 0,0,0, c, + pa_papyrus.x1(), pa_papyrus.y0()), + video::S3DVertex(-BS/2,BS/1,0, 0,0,0, c, + pa_papyrus.x0(), pa_papyrus.y0()), + }; + + if(j == 0) + { + for(u16 i=0; i<4; i++) + vertices[i].Pos.rotateXZBy(45); + } + else if(j == 1) + { + for(u16 i=0; i<4; i++) + vertices[i].Pos.rotateXZBy(-45); + } + else if(j == 2) + { + for(u16 i=0; i<4; i++) + vertices[i].Pos.rotateXZBy(135); + } + else if(j == 3) + { + for(u16 i=0; i<4; i++) + vertices[i].Pos.rotateXZBy(-135); + } + + for(u16 i=0; i<4; i++) + { + vertices[i].Pos *= 1.3; + vertices[i].Pos += intToFloat(p + blockpos_nodes, BS); + } + + u16 indices[] = {0,1,2,2,3,0}; + // Add to mesh collector + collector.append(material_junglegrass, vertices, 4, indices, 6); + } + } else if(n.d == CONTENT_RAIL) { u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio)); diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp index 79e10fd61..be7f95adc 100644 --- a/src/content_mapnode.cpp +++ b/src/content_mapnode.cpp @@ -136,12 +136,34 @@ void content_mapnode_init() f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; setWoodLikeDiggingProperties(f->digging_properties, 1.0); + i = CONTENT_JUNGLETREE; + f = &content_features(i); + f->setAllTextures("jungletree.png"); + f->setTexture(0, "jungletree_top.png"); + f->setTexture(1, "jungletree_top.png"); + f->param_type = CPT_MINERAL; + //f->is_ground_content = true; + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + setWoodLikeDiggingProperties(f->digging_properties, 1.0); + + i = CONTENT_JUNGLEGRASS; + f = &content_features(i); + f->setInventoryTexture("junglegrass.png"); + f->light_propagates = true; + f->param_type = CPT_LIGHT; + //f->is_ground_content = true; + f->air_equivalent = false; // grass grows underneath + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + f->solidness = 0; // drawn separately, makes no faces + f->walkable = false; + setWoodLikeDiggingProperties(f->digging_properties, 0.10); + i = CONTENT_LEAVES; f = &content_features(i); f->light_propagates = true; //f->param_type = CPT_MINERAL; f->param_type = CPT_LIGHT; - f->is_ground_content = true; + //f->is_ground_content = true; if(new_style_leaves) { f->solidness = 0; // drawn separately, makes no faces diff --git a/src/content_mapnode.h b/src/content_mapnode.h index e53624c21..f7d3269ea 100644 --- a/src/content_mapnode.h +++ b/src/content_mapnode.h @@ -57,6 +57,8 @@ void content_mapnode_init(); #define CONTENT_PAPYRUS 28 #define CONTENT_BOOKSHELF 29 #define CONTENT_RAIL 30 +#define CONTENT_JUNGLETREE 31 +#define CONTENT_JUNGLEGRASS 32 #endif diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 8dda93c96..0bb6560a8 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -152,6 +152,92 @@ static void make_tree(VoxelManipulator &vmanip, v3s16 p0) } } +static void make_jungletree(VoxelManipulator &vmanip, v3s16 p0) +{ + MapNode treenode(CONTENT_JUNGLETREE); + MapNode leavesnode(CONTENT_LEAVES); + + for(s16 x=-1; x<=1; x++) + for(s16 z=-1; z<=1; z++) + { + if(myrand_range(0, 2) == 0) + continue; + v3s16 p1 = p0 + v3s16(x,0,z); + v3s16 p2 = p0 + v3s16(x,-1,z); + if(vmanip.m_area.contains(p2) + && vmanip.m_data[vmanip.m_area.index(p2)] == CONTENT_AIR) + vmanip.m_data[vmanip.m_area.index(p2)] = treenode; + else if(vmanip.m_area.contains(p1)) + vmanip.m_data[vmanip.m_area.index(p1)] = treenode; + } + + s16 trunk_h = myrand_range(8, 12); + v3s16 p1 = p0; + for(s16 ii=0; ii<trunk_h; ii++) + { + if(vmanip.m_area.contains(p1)) + vmanip.m_data[vmanip.m_area.index(p1)] = treenode; + p1.Y++; + } + + // p1 is now the last piece of the trunk + p1.Y -= 1; + + VoxelArea leaves_a(v3s16(-3,-2,-3), v3s16(3,2,3)); + //SharedPtr<u8> leaves_d(new u8[leaves_a.getVolume()]); + Buffer<u8> leaves_d(leaves_a.getVolume()); + for(s32 i=0; i<leaves_a.getVolume(); i++) + leaves_d[i] = 0; + + // Force leaves at near the end of the trunk + { + s16 d = 1; + for(s16 z=-d; z<=d; z++) + for(s16 y=-d; y<=d; y++) + for(s16 x=-d; x<=d; x++) + { + leaves_d[leaves_a.index(v3s16(x,y,z))] = 1; + } + } + + // Add leaves randomly + for(u32 iii=0; iii<30; iii++) + { + s16 d = 1; + + v3s16 p( + myrand_range(leaves_a.MinEdge.X, leaves_a.MaxEdge.X-d), + myrand_range(leaves_a.MinEdge.Y, leaves_a.MaxEdge.Y-d), + myrand_range(leaves_a.MinEdge.Z, leaves_a.MaxEdge.Z-d) + ); + + for(s16 z=0; z<=d; z++) + for(s16 y=0; y<=d; y++) + for(s16 x=0; x<=d; x++) + { + leaves_d[leaves_a.index(p+v3s16(x,y,z))] = 1; + } + } + + // Blit leaves to vmanip + for(s16 z=leaves_a.MinEdge.Z; z<=leaves_a.MaxEdge.Z; z++) + for(s16 y=leaves_a.MinEdge.Y; y<=leaves_a.MaxEdge.Y; y++) + for(s16 x=leaves_a.MinEdge.X; x<=leaves_a.MaxEdge.X; x++) + { + v3s16 p(x,y,z); + p += p1; + if(vmanip.m_area.contains(p) == false) + continue; + u32 vi = vmanip.m_area.index(p); + if(vmanip.m_data[vi].d != CONTENT_AIR + && vmanip.m_data[vi].d != CONTENT_IGNORE) + continue; + u32 i = leaves_a.index(x,y,z); + if(leaves_d[i] == 1) + vmanip.m_data[vi] = leavesnode; + } +} + void make_papyrus(VoxelManipulator &vmanip, v3s16 p0) { MapNode papyrusnode(CONTENT_PAPYRUS); @@ -1004,13 +1090,26 @@ double tree_amount_2d(u64 seed, v2s16 p) double noise = noise2d_perlin( 0.5+(float)p.X/125, 0.5+(float)p.Y/125, seed+2, 4, 0.66); - double zeroval = -0.35; + double zeroval = -0.39; if(noise < zeroval) return 0; else return 0.04 * (noise-zeroval) / (1.0-zeroval); } +double surface_humidity_2d(u64 seed, v2s16 p) +{ + double noise = noise2d_perlin( + 0.5+(float)p.X/500, 0.5+(float)p.Y/500, + seed+72384, 4, 0.66); + noise = (noise + 1.0)/2.0; + if(noise < 0.0) + noise = 0.0; + if(noise > 1.0) + noise = 1.0; + return noise; +} + #if 0 double randomstone_amount_2d(u64 seed, v2s16 p) { @@ -1909,11 +2008,19 @@ void make_block(BlockMakeData *data) } /* - Add trees + Calculate some stuff */ + float surface_humidity = surface_humidity_2d(data->seed, p2d_center); + bool is_jungle = surface_humidity > 0.75; // Amount of trees u32 tree_count = block_area_nodes * tree_amount_2d(data->seed, p2d_center); + if(is_jungle) + tree_count *= 5; + + /* + Add trees + */ PseudoRandom treerandom(blockseed); // Put trees in random places on part of division for(u32 i=0; i<tree_count; i++) @@ -1938,7 +2045,8 @@ void make_block(BlockMakeData *data) { u32 i = data->vmanip->m_area.index(p); MapNode *n = &data->vmanip->m_data[i]; - if(n->d != CONTENT_AIR && n->d != CONTENT_WATERSOURCE && n->d != CONTENT_IGNORE) + //if(n->d != CONTENT_AIR && n->d != CONTENT_WATERSOURCE && n->d != CONTENT_IGNORE) + if(content_features(n->d).is_ground_content) { found = true; break; @@ -1965,7 +2073,11 @@ void make_block(BlockMakeData *data) else if((n->d == CONTENT_MUD || n->d == CONTENT_GRASS) && y > WATER_LEVEL + 2) { p.Y++; - make_tree(vmanip, p); + //if(surface_humidity_2d(data->seed, v2s16(x, y)) < 0.5) + if(is_jungle == false) + make_tree(vmanip, p); + else + make_jungletree(vmanip, p); } // Cactii grow only on sand, on land else if(n->d == CONTENT_SAND && y > WATER_LEVEL + 2) @@ -1976,6 +2088,54 @@ void make_block(BlockMakeData *data) } } + /* + Add jungle grass + */ + if(is_jungle) + { + PseudoRandom grassrandom(blockseed); + for(u32 i=0; i<surface_humidity*5*tree_count; i++) + { + s16 x = grassrandom.range(node_min.X, node_max.X); + s16 z = grassrandom.range(node_min.Z, node_max.Z); + s16 y = find_ground_level_from_noise(data->seed, v2s16(x,z), 4); + if(y < WATER_LEVEL) + continue; + if(y < node_min.Y || y > node_max.Y) + continue; + /* + Find exact ground level + */ + v3s16 p(x,y+6,z); + bool found = false; + for(; p.Y >= y-6; p.Y--) + { + u32 i = data->vmanip->m_area.index(p); + MapNode *n = &data->vmanip->m_data[i]; + if(content_features(n->d).is_ground_content + || n->d == CONTENT_JUNGLETREE) + { + found = true; + break; + } + } + // If not found, handle next one + if(found == false) + continue; + p.Y++; + if(vmanip.m_area.contains(p) == false) + continue; + if(vmanip.m_data[vmanip.m_area.index(p)].d != CONTENT_AIR) + continue; + /*p.Y--; + if(vmanip.m_area.contains(p)) + vmanip.m_data[vmanip.m_area.index(p)] = CONTENT_MUD; + p.Y++;*/ + if(vmanip.m_area.contains(p)) + vmanip.m_data[vmanip.m_area.index(p)] = CONTENT_JUNGLEGRASS; + } + } + #if 0 /* Add some kind of random stones diff --git a/src/mapnode.h b/src/mapnode.h index 33128049a..ebca3755a 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -119,7 +119,8 @@ struct ContentFeatures TileSpec tiles[6]; video::ITexture *inventory_texture; - + + // True for all ground-like things like stone and mud, false for eg. trees bool is_ground_content; bool light_propagates; bool sunlight_propagates; |