merged jungle and bluish shadows
commit
501034a792
Binary file not shown.
After Width: | Height: | Size: 672 B |
Binary file not shown.
After Width: | Height: | Size: 502 B |
Binary file not shown.
After Width: | Height: | Size: 507 B |
|
@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "content_mapnode.h"
|
#include "content_mapnode.h"
|
||||||
#include "main.h" // For g_settings and g_texturesource
|
#include "main.h" // For g_settings and g_texturesource
|
||||||
#include "mineral.h"
|
#include "mineral.h"
|
||||||
|
#include "mapblock_mesh.h" // For MapBlock_LightColor()
|
||||||
|
|
||||||
#ifndef SERVER
|
#ifndef SERVER
|
||||||
// Create a cuboid.
|
// Create a cuboid.
|
||||||
|
@ -198,6 +199,17 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
AtlasPointer pa_papyrus = g_texturesource->getTexture(
|
AtlasPointer pa_papyrus = g_texturesource->getTexture(
|
||||||
g_texturesource->getTextureId("papyrus.png"));
|
g_texturesource->getTextureId("papyrus.png"));
|
||||||
material_papyrus.setTexture(0, pa_papyrus.atlas);
|
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 z=0; z<MAP_BLOCKSIZE; z++)
|
||||||
for(s16 y=0; y<MAP_BLOCKSIZE; y++)
|
for(s16 y=0; y<MAP_BLOCKSIZE; y++)
|
||||||
for(s16 x=0; x<MAP_BLOCKSIZE; x++)
|
for(s16 x=0; x<MAP_BLOCKSIZE; x++)
|
||||||
|
@ -275,7 +287,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
else if(n.getContent() == CONTENT_SIGN_WALL)
|
else if(n.getContent() == CONTENT_SIGN_WALL)
|
||||||
{
|
{
|
||||||
u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
|
u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
|
||||||
video::SColor c(255,l,l,l);
|
video::SColor c = MapBlock_LightColor(255, l);
|
||||||
|
|
||||||
float d = (float)BS/16;
|
float d = (float)BS/16;
|
||||||
// Wall at X+ of node
|
// Wall at X+ of node
|
||||||
|
@ -341,7 +353,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
// Otherwise use the light of this node (the water)
|
// Otherwise use the light of this node (the water)
|
||||||
else
|
else
|
||||||
l = decode_light(n.getLightBlend(data->m_daynight_ratio));
|
l = decode_light(n.getLightBlend(data->m_daynight_ratio));
|
||||||
video::SColor c(WATER_ALPHA,l,l,l);
|
video::SColor c = MapBlock_LightColor(WATER_ALPHA, l);
|
||||||
|
|
||||||
// Neighbor water levels (key = relative position)
|
// Neighbor water levels (key = relative position)
|
||||||
// Includes current node
|
// Includes current node
|
||||||
|
@ -607,7 +619,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
|
u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
|
||||||
video::SColor c(WATER_ALPHA,l,l,l);
|
video::SColor c = MapBlock_LightColor(WATER_ALPHA, l);
|
||||||
|
|
||||||
video::S3DVertex vertices[4] =
|
video::S3DVertex vertices[4] =
|
||||||
{
|
{
|
||||||
|
@ -642,7 +654,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
{
|
{
|
||||||
/*u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));*/
|
/*u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));*/
|
||||||
u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
|
u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
|
||||||
video::SColor c(255,l,l,l);
|
video::SColor c = MapBlock_LightColor(255, l);
|
||||||
|
|
||||||
for(u32 j=0; j<6; j++)
|
for(u32 j=0; j<6; j++)
|
||||||
{
|
{
|
||||||
|
@ -709,7 +721,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
else if(n.getContent() == CONTENT_GLASS)
|
else if(n.getContent() == CONTENT_GLASS)
|
||||||
{
|
{
|
||||||
u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
|
u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
|
||||||
video::SColor c(255,l,l,l);
|
video::SColor c = MapBlock_LightColor(255, l);
|
||||||
|
|
||||||
for(u32 j=0; j<6; j++)
|
for(u32 j=0; j<6; j++)
|
||||||
{
|
{
|
||||||
|
@ -772,7 +784,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
else if(n.getContent() == CONTENT_FENCE)
|
else if(n.getContent() == CONTENT_FENCE)
|
||||||
{
|
{
|
||||||
u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
|
u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
|
||||||
video::SColor c(255,l,l,l);
|
video::SColor c = MapBlock_LightColor(255, l);
|
||||||
|
|
||||||
const f32 post_rad=(f32)BS/10;
|
const f32 post_rad=(f32)BS/10;
|
||||||
const f32 bar_rad=(f32)BS/20;
|
const f32 bar_rad=(f32)BS/20;
|
||||||
|
@ -861,7 +873,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
else
|
else
|
||||||
l = 255;*/
|
l = 255;*/
|
||||||
u8 l = 255;
|
u8 l = 255;
|
||||||
video::SColor c(255,l,l,l);
|
video::SColor c = MapBlock_LightColor(255, l);
|
||||||
|
|
||||||
// Get the right texture
|
// Get the right texture
|
||||||
TileSpec ts = n.getTile(dir);
|
TileSpec ts = n.getTile(dir);
|
||||||
|
@ -920,7 +932,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
else if(n.getContent() == CONTENT_PAPYRUS)
|
else if(n.getContent() == CONTENT_PAPYRUS)
|
||||||
{
|
{
|
||||||
u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
|
u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
|
||||||
video::SColor c(255,l,l,l);
|
video::SColor c = MapBlock_LightColor(255, l);
|
||||||
|
|
||||||
for(u32 j=0; j<4; j++)
|
for(u32 j=0; j<4; j++)
|
||||||
{
|
{
|
||||||
|
@ -967,10 +979,61 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
collector.append(material_papyrus, vertices, 4, indices, 6);
|
collector.append(material_papyrus, vertices, 4, indices, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(n.getContent() == CONTENT_JUNGLEGRASS)
|
||||||
|
{
|
||||||
|
u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
|
||||||
|
video::SColor c = MapBlock_LightColor(255, 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.getContent() == CONTENT_RAIL)
|
else if(n.getContent() == CONTENT_RAIL)
|
||||||
{
|
{
|
||||||
u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
|
u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
|
||||||
video::SColor c(255,l,l,l);
|
video::SColor c = MapBlock_LightColor(255, l);
|
||||||
|
|
||||||
bool is_rail_x [] = { false, false }; /* x-1, x+1 */
|
bool is_rail_x [] = { false, false }; /* x-1, x+1 */
|
||||||
bool is_rail_z [] = { false, false }; /* z-1, z+1 */
|
bool is_rail_z [] = { false, false }; /* z-1, z+1 */
|
||||||
|
|
|
@ -195,12 +195,34 @@ void content_mapnode_init()
|
||||||
f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
|
f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
|
||||||
setWoodLikeDiggingProperties(f->digging_properties, 1.0);
|
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;
|
i = CONTENT_LEAVES;
|
||||||
f = &content_features(i);
|
f = &content_features(i);
|
||||||
f->light_propagates = true;
|
f->light_propagates = true;
|
||||||
//f->param_type = CPT_MINERAL;
|
//f->param_type = CPT_MINERAL;
|
||||||
f->param_type = CPT_LIGHT;
|
f->param_type = CPT_LIGHT;
|
||||||
f->is_ground_content = true;
|
//f->is_ground_content = true;
|
||||||
if(new_style_leaves)
|
if(new_style_leaves)
|
||||||
{
|
{
|
||||||
f->solidness = 0; // drawn separately, makes no faces
|
f->solidness = 0; // drawn separately, makes no faces
|
||||||
|
|
|
@ -44,6 +44,8 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version);
|
||||||
#define CONTENT_FURNACE 16
|
#define CONTENT_FURNACE 16
|
||||||
#define CONTENT_FENCE 21
|
#define CONTENT_FENCE 21
|
||||||
#define CONTENT_RAIL 30
|
#define CONTENT_RAIL 30
|
||||||
|
#define CONTENT_JUNGLETREE 31
|
||||||
|
#define CONTENT_JUNGLEGRASS 32
|
||||||
|
|
||||||
// 0x800...0xfff (2048...4095): higher 4 bytes of param2 are not usable
|
// 0x800...0xfff (2048...4095): higher 4 bytes of param2 are not usable
|
||||||
#define CONTENT_GRASS 0x800 //1
|
#define CONTENT_GRASS 0x800 //1
|
||||||
|
|
|
@ -233,3 +233,4 @@ void clearKeyCache()
|
||||||
{
|
{
|
||||||
g_key_setting_cache.clear();
|
g_key_setting_cache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,9 +140,24 @@ void getNodeVertexDirs(v3s16 dir, v3s16 *vertex_dirs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline video::SColor lightColor(u8 alpha, u8 light)
|
video::SColor MapBlock_LightColor(u8 alpha, u8 light)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
return video::SColor(alpha,light,light,light);
|
return video::SColor(alpha,light,light,light);
|
||||||
|
#endif
|
||||||
|
//return video::SColor(alpha,light,light,MYMAX(0, (s16)light-25)+25);
|
||||||
|
/*return video::SColor(alpha,light,light,MYMAX(0,
|
||||||
|
pow((float)light/255.0, 0.8)*255.0));*/
|
||||||
|
#if 1
|
||||||
|
// Emphase blue a bit in darker places
|
||||||
|
float lim = 80;
|
||||||
|
float power = 0.7;
|
||||||
|
if(light > lim)
|
||||||
|
return video::SColor(alpha,light,light,light);
|
||||||
|
else
|
||||||
|
return video::SColor(alpha,light,light,MYMAX(0,
|
||||||
|
pow((float)light/lim, power)*lim));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FastFace
|
struct FastFace
|
||||||
|
@ -198,7 +213,7 @@ void makeFastFace(TileSpec tile, u8 li0, u8 li1, u8 li2, u8 li3, v3f p,
|
||||||
float w = tile.texture.size.X;
|
float w = tile.texture.size.X;
|
||||||
float h = tile.texture.size.Y;
|
float h = tile.texture.size.Y;
|
||||||
|
|
||||||
/*video::SColor c = lightColor(alpha, li);
|
/*video::SColor c = MapBlock_LightColor(alpha, li);
|
||||||
|
|
||||||
face.vertices[0] = video::S3DVertex(vertex_pos[0], v3f(0,1,0), c,
|
face.vertices[0] = video::S3DVertex(vertex_pos[0], v3f(0,1,0), c,
|
||||||
core::vector2d<f32>(x0+w*abs_scale, y0+h));
|
core::vector2d<f32>(x0+w*abs_scale, y0+h));
|
||||||
|
@ -210,16 +225,16 @@ void makeFastFace(TileSpec tile, u8 li0, u8 li1, u8 li2, u8 li3, v3f p,
|
||||||
core::vector2d<f32>(x0+w*abs_scale, y0));*/
|
core::vector2d<f32>(x0+w*abs_scale, y0));*/
|
||||||
|
|
||||||
face.vertices[0] = video::S3DVertex(vertex_pos[0], v3f(0,1,0),
|
face.vertices[0] = video::S3DVertex(vertex_pos[0], v3f(0,1,0),
|
||||||
lightColor(alpha, li0),
|
MapBlock_LightColor(alpha, li0),
|
||||||
core::vector2d<f32>(x0+w*abs_scale, y0+h));
|
core::vector2d<f32>(x0+w*abs_scale, y0+h));
|
||||||
face.vertices[1] = video::S3DVertex(vertex_pos[1], v3f(0,1,0),
|
face.vertices[1] = video::S3DVertex(vertex_pos[1], v3f(0,1,0),
|
||||||
lightColor(alpha, li1),
|
MapBlock_LightColor(alpha, li1),
|
||||||
core::vector2d<f32>(x0, y0+h));
|
core::vector2d<f32>(x0, y0+h));
|
||||||
face.vertices[2] = video::S3DVertex(vertex_pos[2], v3f(0,1,0),
|
face.vertices[2] = video::S3DVertex(vertex_pos[2], v3f(0,1,0),
|
||||||
lightColor(alpha, li2),
|
MapBlock_LightColor(alpha, li2),
|
||||||
core::vector2d<f32>(x0, y0));
|
core::vector2d<f32>(x0, y0));
|
||||||
face.vertices[3] = video::S3DVertex(vertex_pos[3], v3f(0,1,0),
|
face.vertices[3] = video::S3DVertex(vertex_pos[3], v3f(0,1,0),
|
||||||
lightColor(alpha, li3),
|
MapBlock_LightColor(alpha, li3),
|
||||||
core::vector2d<f32>(x0+w*abs_scale, y0));
|
core::vector2d<f32>(x0+w*abs_scale, y0));
|
||||||
|
|
||||||
face.tile = tile;
|
face.tile = tile;
|
||||||
|
|
|
@ -121,6 +121,9 @@ private:
|
||||||
core::array<PreMeshBuffer> m_prebuffers;
|
core::array<PreMeshBuffer> m_prebuffers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Helper functions
|
||||||
|
video::SColor MapBlock_LightColor(u8 alpha, u8 light);
|
||||||
|
|
||||||
class MapBlock;
|
class MapBlock;
|
||||||
|
|
||||||
struct MeshMakeData
|
struct MeshMakeData
|
||||||
|
@ -137,6 +140,7 @@ struct MeshMakeData
|
||||||
void fill(u32 daynight_ratio, MapBlock *block);
|
void fill(u32 daynight_ratio, MapBlock *block);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This is the highest-level function in here
|
||||||
scene::SMesh* makeMapBlockMesh(MeshMakeData *data);
|
scene::SMesh* makeMapBlockMesh(MeshMakeData *data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
163
src/mapgen.cpp
163
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].getContent() != CONTENT_AIR
|
||||||
|
&& vmanip.m_data[vi].getContent() != 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)
|
void make_papyrus(VoxelManipulator &vmanip, v3s16 p0)
|
||||||
{
|
{
|
||||||
MapNode papyrusnode(CONTENT_PAPYRUS);
|
MapNode papyrusnode(CONTENT_PAPYRUS);
|
||||||
|
@ -1004,13 +1090,26 @@ double tree_amount_2d(u64 seed, v2s16 p)
|
||||||
double noise = noise2d_perlin(
|
double noise = noise2d_perlin(
|
||||||
0.5+(float)p.X/125, 0.5+(float)p.Y/125,
|
0.5+(float)p.X/125, 0.5+(float)p.Y/125,
|
||||||
seed+2, 4, 0.66);
|
seed+2, 4, 0.66);
|
||||||
double zeroval = -0.35;
|
double zeroval = -0.39;
|
||||||
if(noise < zeroval)
|
if(noise < zeroval)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
return 0.04 * (noise-zeroval) / (1.0-zeroval);
|
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
|
#if 0
|
||||||
double randomstone_amount_2d(u64 seed, v2s16 p)
|
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
|
// Amount of trees
|
||||||
u32 tree_count = block_area_nodes * tree_amount_2d(data->seed, p2d_center);
|
u32 tree_count = block_area_nodes * tree_amount_2d(data->seed, p2d_center);
|
||||||
|
if(is_jungle)
|
||||||
|
tree_count *= 5;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add trees
|
||||||
|
*/
|
||||||
PseudoRandom treerandom(blockseed);
|
PseudoRandom treerandom(blockseed);
|
||||||
// Put trees in random places on part of division
|
// Put trees in random places on part of division
|
||||||
for(u32 i=0; i<tree_count; i++)
|
for(u32 i=0; i<tree_count; i++)
|
||||||
|
@ -1965,7 +2072,11 @@ void make_block(BlockMakeData *data)
|
||||||
else if((n->getContent() == CONTENT_MUD || n->getContent() == CONTENT_GRASS) && y > WATER_LEVEL + 2)
|
else if((n->getContent() == CONTENT_MUD || n->getContent() == CONTENT_GRASS) && y > WATER_LEVEL + 2)
|
||||||
{
|
{
|
||||||
p.Y++;
|
p.Y++;
|
||||||
|
//if(surface_humidity_2d(data->seed, v2s16(x, y)) < 0.5)
|
||||||
|
if(is_jungle == false)
|
||||||
make_tree(vmanip, p);
|
make_tree(vmanip, p);
|
||||||
|
else
|
||||||
|
make_jungletree(vmanip, p);
|
||||||
}
|
}
|
||||||
// Cactii grow only on sand, on land
|
// Cactii grow only on sand, on land
|
||||||
else if(n->getContent() == CONTENT_SAND && y > WATER_LEVEL + 2)
|
else if(n->getContent() == CONTENT_SAND && y > WATER_LEVEL + 2)
|
||||||
|
@ -1976,6 +2087,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).is_ground_content
|
||||||
|
|| n->getContent() == 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)].getContent() != 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
|
#if 0
|
||||||
/*
|
/*
|
||||||
Add some kind of random stones
|
Add some kind of random stones
|
||||||
|
|
|
@ -116,6 +116,7 @@ struct ContentFeatures
|
||||||
|
|
||||||
video::ITexture *inventory_texture;
|
video::ITexture *inventory_texture;
|
||||||
|
|
||||||
|
// True for all ground-like things like stone and mud, false for eg. trees
|
||||||
bool is_ground_content;
|
bool is_ground_content;
|
||||||
bool light_propagates;
|
bool light_propagates;
|
||||||
bool sunlight_propagates;
|
bool sunlight_propagates;
|
||||||
|
|
Loading…
Reference in New Issue