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++)
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));
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
}
}
+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);
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)
{
}
/*
- 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++)
{
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;
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)
}
}
+ /*
+ 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