diff --git a/data/sapling.png b/data/sapling.png new file mode 100644 index 0000000..73f5023 Binary files /dev/null and b/data/sapling.png differ diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index 1cc37b9..9a156cb 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -199,6 +199,18 @@ void mapblock_mesh_generate_special(MeshMakeData *data, g_texturesource->getTextureId("apple.png")); material_apple.setTexture(0, pa_apple.atlas); + + // Sapling material + video::SMaterial material_sapling; + material_sapling.setFlag(video::EMF_LIGHTING, false); + material_sapling.setFlag(video::EMF_BILINEAR_FILTER, false); + material_sapling.setFlag(video::EMF_FOG_ENABLE, true); + material_sapling.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + AtlasPointer pa_sapling = g_texturesource->getTexture( + g_texturesource->getTextureId("sapling.png")); + material_sapling.setTexture(0, pa_sapling.atlas); + + // junglegrass material video::SMaterial material_junglegrass; material_junglegrass.setFlag(video::EMF_LIGHTING, false); @@ -1263,6 +1275,55 @@ void mapblock_mesh_generate_special(MeshMakeData *data, collector.append(material_apple, vertices, 4, indices, 6); } } + else if(n.getContent() == CONTENT_SAPLING) { + 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_sapling.x0(), pa_sapling.y1()), + video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, + pa_sapling.x1(), pa_sapling.y1()), + video::S3DVertex(BS/2,BS/1,0, 0,0,0, c, + pa_sapling.x1(), pa_sapling.y0()), + video::S3DVertex(-BS/2,BS/1,0, 0,0,0, c, + pa_sapling.x0(), pa_sapling.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 += intToFloat(p + blockpos_nodes, BS); + } + + u16 indices[] = {0,1,2,2,3,0}; + // Add to mesh collector + collector.append(material_sapling, vertices, 4, indices, 6); + } + } } } #endif diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp index a573ca1..8f2c4bd 100644 --- a/src/content_mapnode.cpp +++ b/src/content_mapnode.cpp @@ -244,6 +244,8 @@ void content_mapnode_init() { f->setAllTextures("[noalpha:leaves.png"); } + f->extra_dug_item = std::string("MaterialItem2 ")+itos(CONTENT_SAPLING)+" 1"; + f->extra_dug_item_rarity = 20; f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; setWoodLikeDiggingProperties(f->digging_properties, 0.15); @@ -651,6 +653,18 @@ void content_mapnode_init() f->setInventoryTexture("nc_rb.png"); f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; setStoneLikeDiggingProperties(f->digging_properties, 3.0); + + i = CONTENT_SAPLING; + f = &content_features(i); + f->param_type = CPT_LIGHT; + f->setAllTextures("sapling.png"); + f->setInventoryTexture("sapling.png"); + f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; + f->light_propagates = true; + f->air_equivalent = false; + f->solidness = 0; // drawn separately, makes no faces + f->walkable = false; + f->digging_properties.set("", DiggingProperties(true, 0.0, 0)); i = CONTENT_APPLE; f = &content_features(i); diff --git a/src/content_mapnode.h b/src/content_mapnode.h index 366c9b1..4090f76 100644 --- a/src/content_mapnode.h +++ b/src/content_mapnode.h @@ -85,7 +85,7 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version); #define CONTENT_NC 0x817 #define CONTENT_NC_RB 0x818 #define CONTENT_APPLE 0x819 - +#define CONTENT_SAPLING 0x820 #endif diff --git a/src/environment.cpp b/src/environment.cpp index ff57055..92263c6 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapblock.h" #include "serverobject.h" #include "content_sao.h" +#include "mapgen.h" Environment::Environment(): m_time_of_day(9000) @@ -922,7 +923,47 @@ void ServerEnvironment::step(float dtime) addActiveObject(obj); } } - } + } + /* + Make trees from saplings! + */ + if(n.getContent() == CONTENT_SAPLING) + { + if(myrand()%50 == 0) + { + core::map modified_blocks; + v3s16 tree_p = p; + ManualMapVoxelManipulator vmanip(m_map); + v3s16 tree_blockp = getNodeBlockPos(tree_p); + vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,1,1)); + bool is_apple_tree = myrand()%4 == 0; + mapgen::make_tree(vmanip, tree_p, is_apple_tree); + vmanip.blitBackAll(&modified_blocks); + + // update lighting + core::map lighting_modified_blocks; + for(core::map::Iterator + i = modified_blocks.getIterator(); + i.atEnd() == false; i++) + { + lighting_modified_blocks.insert(i.getNode()->getKey(), i.getNode()->getValue()); + } + m_map->updateLighting(lighting_modified_blocks, modified_blocks); + + // Send a MEET_OTHER event + MapEditEvent event; + event.type = MEET_OTHER; + for(core::map::Iterator + i = modified_blocks.getIterator(); + i.atEnd() == false; i++) + { + v3s16 p = i.getNode()->getKey(); + event.modified_blocks.insert(p, true); + } + m_map->dispatchEvent(&event); + } + } + } } } diff --git a/src/map.cpp b/src/map.cpp index eb55d3a..05ec6ff 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "porting.h" #include "mapgen.h" #include "nodemetadata.h" +#include "content_mapnode.h" /* SQLite format specification: diff --git a/src/mapgen.cpp b/src/mapgen.cpp index a07f4ca..9a7c7ba 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -80,7 +80,7 @@ static s16 find_ground_level_clever(VoxelManipulator &vmanip, v2s16 p2d) } #endif -static void make_tree(VoxelManipulator &vmanip, v3s16 p0, bool is_apple_tree) +void make_tree(ManualMapVoxelManipulator &vmanip, v3s16 p0, bool is_apple_tree) { MapNode treenode(CONTENT_TREE); MapNode leavesnode(CONTENT_LEAVES); diff --git a/src/mapgen.h b/src/mapgen.h index 57d0ee8..f848389 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -40,6 +40,9 @@ namespace mapgen // Add objects according to block content void add_random_objects(MapBlock *block); + + // Add a tree + void make_tree(ManualMapVoxelManipulator &vmanip, v3s16 p0, bool is_apple_tree); /* These are used by FarMesh diff --git a/src/mapnode.h b/src/mapnode.h index 19dfb28..e99407f 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -145,6 +145,10 @@ struct ContentFeatures // Inventory item string as which the node appears in inventory when dug. // Mineral overrides this. std::string dug_item; + + // Extra dug item and its rarity + std::string extra_dug_item; + s32 extra_dug_item_rarity; // Initial metadata is cloned from this NodeMetadata *initial_metadata; diff --git a/src/server.cpp b/src/server.cpp index 5395d76..44889d6 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2748,6 +2748,34 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) UpdateCrafting(player->peer_id); SendInventory(player->peer_id); } + + item = NULL; + + if(mineral != MINERAL_NONE) + item = getDiggedMineralItem(mineral); + + // If not mineral + if(item == NULL) + { + std::string &extra_dug_s = content_features(material).extra_dug_item; + s32 extra_rarity = content_features(material).extra_dug_item_rarity; + if(extra_dug_s != "" && extra_rarity != 0 + && myrand() % extra_rarity == 0) + { + std::istringstream is(extra_dug_s, std::ios::binary); + item = InventoryItem::deSerialize(is); + } + } + + if(item != NULL) + { + // Add a item to inventory + player->inventory.addItem("main", item); + + // Send inventory + UpdateCrafting(player->peer_id); + SendInventory(player->peer_id); + } } /*