aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/sapling.pngbin0 -> 502 bytes
-rw-r--r--src/content_mapblock.cpp61
-rw-r--r--src/content_mapnode.cpp14
-rw-r--r--src/content_mapnode.h2
-rw-r--r--src/environment.cpp43
-rw-r--r--src/map.cpp1
-rw-r--r--src/mapgen.cpp2
-rw-r--r--src/mapgen.h3
-rw-r--r--src/mapnode.h4
-rw-r--r--src/server.cpp28
10 files changed, 155 insertions, 3 deletions
diff --git a/data/sapling.png b/data/sapling.png
new file mode 100644
index 000000000..73f502306
--- /dev/null
+++ b/data/sapling.png
Binary files differ
diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp
index 1cc37b969..9a156cb55 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 a573ca141..8f2c4bd50 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 366c9b1a0..4090f76f4 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 ff570554d..92263c675 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<v3s16, MapBlock*> 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<v3s16, MapBlock*> lighting_modified_blocks;
+ for(core::map<v3s16, MapBlock*>::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<v3s16, MapBlock*>::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 eb55d3a57..05ec6ff67 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 a07f4cac8..9a7c7ba90 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 57d0ee8a0..f848389a8 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 19dfb2802..e99407f86 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 5395d7618..44889d67e 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);
+ }
}
/*