045615fbbf72f08eb5cd3c20964d1457cbcb7944
[oweals/minetest.git] / src / nodedef.cpp
1 /*
2 Minetest-c55
3 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "nodedef.h"
21
22 #include "main.h" // For g_settings
23 #include "nodemetadata.h"
24 #ifndef SERVER
25 #include "tile.h"
26 #endif
27 #include "log.h"
28
29 ContentFeatures::~ContentFeatures()
30 {
31         delete initial_metadata;
32 #ifndef SERVER
33         for(u16 j=0; j<CF_SPECIAL_COUNT; j++){
34                 delete special_materials[j];
35                 delete special_aps[j];
36         }
37 #endif
38 }
39
40 void ContentFeatures::setTexture(u16 i, std::string name)
41 {
42         used_texturenames.insert(name);
43         tname_tiles[i] = name;
44         if(tname_inventory == "")
45                 tname_inventory = name;
46 }
47
48 void ContentFeatures::setInventoryTexture(std::string imgname)
49 {
50         tname_inventory = imgname + "^[forcesingle";
51 }
52
53 void ContentFeatures::setInventoryTextureCube(std::string top,
54                 std::string left, std::string right)
55 {
56         str_replace_char(top, '^', '&');
57         str_replace_char(left, '^', '&');
58         str_replace_char(right, '^', '&');
59
60         std::string imgname_full;
61         imgname_full += "[inventorycube{";
62         imgname_full += top;
63         imgname_full += "{";
64         imgname_full += left;
65         imgname_full += "{";
66         imgname_full += right;
67         tname_inventory = imgname_full;
68 }
69
70 class CNodeDefManager: public IWritableNodeDefManager
71 {
72 public:
73         CNodeDefManager()
74         {
75                 for(u16 i=0; i<=MAX_CONTENT; i++)
76                 {
77                         ContentFeatures *f = &m_content_features[i];
78                         // Reset to defaults
79                         f->reset();
80                         if(i == CONTENT_IGNORE || i == CONTENT_AIR)
81                                 continue;
82                         f->setAllTextures("unknown_block.png");
83                         f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
84                 }
85                 // Make CONTENT_IGNORE to not block the view when occlusion culling
86                 m_content_features[CONTENT_IGNORE].solidness = 0;
87         }
88         virtual ~CNodeDefManager()
89         {
90         }
91         virtual IWritableNodeDefManager* clone()
92         {
93                 CNodeDefManager *mgr = new CNodeDefManager();
94                 for(u16 i=0; i<=MAX_CONTENT; i++)
95                 {
96                         mgr->set(i, get(i));
97                 }
98                 return mgr;
99         }
100         virtual const ContentFeatures& get(content_t c) const
101         {
102                 assert(c <= MAX_CONTENT);
103                 return m_content_features[c];
104         }
105         virtual const ContentFeatures& get(const MapNode &n) const
106         {
107                 return get(n.getContent());
108         }
109         // Writable
110         virtual void set(content_t c, const ContentFeatures &def)
111         {
112                 infostream<<"registerNode: registering content \""<<c<<"\""<<std::endl;
113                 assert(c <= MAX_CONTENT);
114                 m_content_features[c] = def;
115         }
116         virtual ContentFeatures* getModifiable(content_t c)
117         {
118                 assert(c <= MAX_CONTENT);
119                 return &m_content_features[c];
120         }
121         virtual void updateTextures(ITextureSource *tsrc)
122         {
123 #ifndef SERVER
124                 infostream<<"CNodeDefManager::updateTextures(): Updating "
125                                 <<"textures in node definitions"<<std::endl;
126                 for(u16 i=0; i<=MAX_CONTENT; i++)
127                 {
128                         infostream<<"Updating content "<<i<<std::endl;
129                         ContentFeatures *f = &m_content_features[i];
130                         // Inventory texture
131                         if(f->tname_inventory != "")
132                                 f->inventory_texture = tsrc->getTextureRaw(f->tname_inventory);
133                         else
134                                 f->inventory_texture = NULL;
135                         // Tile textures
136                         for(u16 j=0; j<6; j++){
137                                 if(f->tname_tiles[j] == "")
138                                         continue;
139                                 f->tiles[j].texture = tsrc->getTexture(f->tname_tiles[j]);
140                                 f->tiles[j].alpha = f->alpha;
141                                 if(f->alpha == 255)
142                                         f->tiles[j].material_type = MATERIAL_ALPHA_SIMPLE;
143                                 else
144                                         f->tiles[j].material_type = MATERIAL_ALPHA_VERTEX;
145                                 if(f->backface_culling)
146                                         f->tiles[j].material_flags |= MATERIAL_FLAG_BACKFACE_CULLING;
147                                 else
148                                         f->tiles[j].material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
149                         }
150                         // Special textures
151                         for(u16 j=0; j<CF_SPECIAL_COUNT; j++){
152                                 // Remove all stuff
153                                 if(f->special_aps[j]){
154                                         delete f->special_aps[j];
155                                         f->special_aps[j] = NULL;
156                                 }
157                                 if(f->special_materials[j]){
158                                         delete f->special_materials[j];
159                                         f->special_materials[j] = NULL;
160                                 }
161                                 // Skip if should not exist
162                                 if(f->mspec_special[j].tname == "")
163                                         continue;
164                                 // Create all stuff
165                                 f->special_aps[j] = new AtlasPointer(
166                                                 tsrc->getTexture(f->mspec_special[j].tname));
167                                 f->special_materials[j] = new video::SMaterial;
168                                 f->special_materials[j]->setFlag(video::EMF_LIGHTING, false);
169                                 f->special_materials[j]->setFlag(video::EMF_BACK_FACE_CULLING,
170                                                 f->mspec_special[j].backface_culling);
171                                 f->special_materials[j]->setFlag(video::EMF_BILINEAR_FILTER, false);
172                                 f->special_materials[j]->setFlag(video::EMF_FOG_ENABLE, true);
173                                 f->special_materials[j]->setTexture(0, f->special_aps[j]->atlas);
174                         }
175                 }
176 #endif
177         }
178 private:
179         ContentFeatures m_content_features[MAX_CONTENT+1];
180 };
181
182 IWritableNodeDefManager* createNodeDefManager()
183 {
184         return new CNodeDefManager();
185 }
186