]> git.lizzy.rs Git - dragonfireclient.git/blob - src/nodemetadata.cpp
Chests work now!
[dragonfireclient.git] / src / nodemetadata.cpp
1 /*
2 Minetest-c55
3 Copyright (C) 2010-2011 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 "nodemetadata.h"
21 #include "utility.h"
22 #include "mapnode.h"
23 #include "exceptions.h"
24 #include "inventory.h"
25
26 /*
27         NodeMetadata
28 */
29
30 core::map<u16, NodeMetadata::Factory> NodeMetadata::m_types;
31
32 NodeMetadata::NodeMetadata()
33 {
34 }
35
36 NodeMetadata::~NodeMetadata()
37 {
38 }
39
40 NodeMetadata* NodeMetadata::deSerialize(std::istream &is)
41 {
42         u8 buf[2];
43         is.read((char*)buf, 2);
44         s16 id = readS16(buf);
45
46         core::map<u16, Factory>::Node *n;
47         n = m_types.find(id);
48         if(n == NULL)
49         {
50                 dstream<<"NodeMetadata(): No factory for typeId="<<id<<std::endl;
51                 throw SerializationError("Unknown metadata id");
52         }
53         
54         Factory f = n->getValue();
55         NodeMetadata *meta = (*f)(is);
56         return meta;
57 }
58
59 void NodeMetadata::serialize(std::ostream &os)
60 {
61         u8 buf[2];
62         writeU16(buf, typeId());
63         os.write((char*)buf, 2);
64
65         serializeBody(os);
66 }
67
68 void NodeMetadata::registerType(u16 id, Factory f)
69 {
70         core::map<u16, Factory>::Node *n;
71         n = m_types.find(id);
72         if(n)
73                 return;
74         m_types.insert(id, f);
75 }
76
77 /*
78         SignNodeMetadata
79 */
80
81 SignNodeMetadata::SignNodeMetadata(std::string text):
82         m_text(text)
83 {
84         NodeMetadata::registerType(typeId(), create);
85 }
86 u16 SignNodeMetadata::typeId() const
87 {
88         return CONTENT_SIGN_WALL;
89 }
90 NodeMetadata* SignNodeMetadata::create(std::istream &is)
91 {
92         std::string text = deSerializeString(is);
93         return new SignNodeMetadata(text);
94 }
95 NodeMetadata* SignNodeMetadata::clone()
96 {
97         return new SignNodeMetadata(m_text);
98 }
99 void SignNodeMetadata::serializeBody(std::ostream &os)
100 {
101         os<<serializeString(m_text);
102 }
103 std::string SignNodeMetadata::infoText()
104 {
105         return std::string("\"")+m_text+"\"";
106 }
107
108 /*
109         ChestNodeMetadata
110 */
111
112 ChestNodeMetadata::ChestNodeMetadata()
113 {
114         NodeMetadata::registerType(typeId(), create);
115         
116         m_inventory = new Inventory();
117         m_inventory->addList("0", 8*4);
118 }
119 ChestNodeMetadata::~ChestNodeMetadata()
120 {
121         delete m_inventory;
122 }
123 u16 ChestNodeMetadata::typeId() const
124 {
125         return CONTENT_CHEST;
126 }
127 NodeMetadata* ChestNodeMetadata::create(std::istream &is)
128 {
129         ChestNodeMetadata *d = new ChestNodeMetadata();
130         d->m_inventory->deSerialize(is);
131         return d;
132 }
133 NodeMetadata* ChestNodeMetadata::clone()
134 {
135         ChestNodeMetadata *d = new ChestNodeMetadata();
136         *d->m_inventory = *m_inventory;
137         return d;
138 }
139 void ChestNodeMetadata::serializeBody(std::ostream &os)
140 {
141         m_inventory->serialize(os);
142 }
143 std::string ChestNodeMetadata::infoText()
144 {
145         return "Chest";
146 }
147 /*Inventory* ChestNodeMetadata::getInventory()
148 {
149         return m_inventory;
150 }*/
151
152 /*
153         NodeMetadatalist
154 */
155
156 void NodeMetadataList::serialize(std::ostream &os)
157 {
158         u8 buf[6];
159         
160         u16 count = m_data.size();
161         writeU16(buf, count);
162         os.write((char*)buf, 2);
163
164         for(core::map<v3s16, NodeMetadata*>::Iterator
165                         i = m_data.getIterator();
166                         i.atEnd()==false; i++)
167         {
168                 v3s16 p = i.getNode()->getKey();
169                 NodeMetadata *data = i.getNode()->getValue();
170                 
171                 u16 p16 = p.Z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + p.Y*MAP_BLOCKSIZE + p.X;
172                 writeU16(buf, p16);
173                 os.write((char*)buf, 2);
174
175                 data->serialize(os);
176         }
177         
178 }
179 void NodeMetadataList::deSerialize(std::istream &is)
180 {
181         m_data.clear();
182
183         u8 buf[6];
184         
185         is.read((char*)buf, 2);
186         u16 count = readU16(buf);
187         
188         for(u16 i=0; i<count; i++)
189         {
190                 is.read((char*)buf, 2);
191                 u16 p16 = readU16(buf);
192
193                 v3s16 p(0,0,0);
194                 p.Z += p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE;
195                 p16 -= p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE;
196                 p.Y += p16 / MAP_BLOCKSIZE;
197                 p16 -= p.Y * MAP_BLOCKSIZE;
198                 p.X += p16;
199                 
200                 if(m_data.find(p))
201                 {
202                         dstream<<"ERROR: NodeMetadataList::deSerialize(): "
203                                         <<"already set data at position"
204                                         <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
205                                         <<std::endl;
206                         throw SerializationError("NodeMetadataList::deSerialize()");
207                 }
208
209                 NodeMetadata *data = NodeMetadata::deSerialize(is);
210                 
211                 m_data.insert(p, data);
212         }
213 }
214         
215 NodeMetadataList::~NodeMetadataList()
216 {
217         for(core::map<v3s16, NodeMetadata*>::Iterator
218                         i = m_data.getIterator();
219                         i.atEnd()==false; i++)
220         {
221                 delete i.getNode()->getValue();
222         }
223 }
224
225 NodeMetadata* NodeMetadataList::get(v3s16 p)
226 {
227         core::map<v3s16, NodeMetadata*>::Node *n;
228         n = m_data.find(p);
229         if(n == NULL)
230                 return NULL;
231         return n->getValue();
232 }
233
234 void NodeMetadataList::remove(v3s16 p)
235 {
236         NodeMetadata *olddata = get(p);
237         if(olddata)
238         {
239                 delete olddata;
240                 m_data.remove(p);
241         }
242 }
243
244 void NodeMetadataList::set(v3s16 p, NodeMetadata *d)
245 {
246         remove(p);
247         m_data.insert(p, d);
248 }
249