]> git.lizzy.rs Git - minetest.git/blob - src/mapsector.cpp
Modernize various files (src/m*) (#6267)
[minetest.git] / src / mapsector.cpp
1 /*
2 Minetest
3 Copyright (C) 2013 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 Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser 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 "mapsector.h"
21 #include "exceptions.h"
22 #include "mapblock.h"
23 #include "serialization.h"
24
25 MapSector::MapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
26                 m_parent(parent),
27                 m_pos(pos),
28                 m_gamedef(gamedef)
29 {
30 }
31
32 MapSector::~MapSector()
33 {
34         deleteBlocks();
35 }
36
37 void MapSector::deleteBlocks()
38 {
39         // Clear cache
40         m_block_cache = nullptr;
41
42         // Delete all
43         for (auto &block : m_blocks) {
44                 delete block.second;
45         }
46
47         // Clear container
48         m_blocks.clear();
49 }
50
51 MapBlock * MapSector::getBlockBuffered(s16 y)
52 {
53         MapBlock *block;
54
55         if (m_block_cache && y == m_block_cache_y) {
56                 return m_block_cache;
57         }
58
59         // If block doesn't exist, return NULL
60         std::unordered_map<s16, MapBlock*>::const_iterator n = m_blocks.find(y);
61         block = (n != m_blocks.end() ? n->second : nullptr);
62
63         // Cache the last result
64         m_block_cache_y = y;
65         m_block_cache = block;
66
67         return block;
68 }
69
70 MapBlock * MapSector::getBlockNoCreateNoEx(s16 y)
71 {
72         return getBlockBuffered(y);
73 }
74
75 MapBlock * MapSector::createBlankBlockNoInsert(s16 y)
76 {
77         assert(getBlockBuffered(y) == NULL);    // Pre-condition
78
79         v3s16 blockpos_map(m_pos.X, y, m_pos.Y);
80
81         MapBlock *block = new MapBlock(m_parent, blockpos_map, m_gamedef);
82
83         return block;
84 }
85
86 MapBlock * MapSector::createBlankBlock(s16 y)
87 {
88         MapBlock *block = createBlankBlockNoInsert(y);
89
90         m_blocks[y] = block;
91
92         return block;
93 }
94
95 void MapSector::insertBlock(MapBlock *block)
96 {
97         s16 block_y = block->getPos().Y;
98
99         MapBlock *block2 = getBlockBuffered(block_y);
100         if (block2) {
101                 throw AlreadyExistsException("Block already exists");
102         }
103
104         v2s16 p2d(block->getPos().X, block->getPos().Z);
105         assert(p2d == m_pos);
106
107         // Insert into container
108         m_blocks[block_y] = block;
109 }
110
111 void MapSector::deleteBlock(MapBlock *block)
112 {
113         s16 block_y = block->getPos().Y;
114
115         // Clear from cache
116         m_block_cache = nullptr;
117
118         // Remove from container
119         m_blocks.erase(block_y);
120
121         // Delete
122         delete block;
123 }
124
125 void MapSector::getBlocks(MapBlockVect &dest)
126 {
127         for (auto &block : m_blocks) {
128                 dest.push_back(block.second);
129         }
130 }
131
132 /*
133         ServerMapSector
134 */
135
136 ServerMapSector::ServerMapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
137                 MapSector(parent, pos, gamedef)
138 {
139 }
140
141 void ServerMapSector::serialize(std::ostream &os, u8 version)
142 {
143         if(!ser_ver_supported(version))
144                 throw VersionMismatchException("ERROR: MapSector format not supported");
145
146         /*
147                 [0] u8 serialization version
148                 + heightmap data
149         */
150
151         // Server has both of these, no need to support not having them.
152         //assert(m_objects != NULL);
153
154         // Write version
155         os.write((char*)&version, 1);
156
157         /*
158                 Add stuff here, if needed
159         */
160
161 }
162
163 ServerMapSector* ServerMapSector::deSerialize(
164                 std::istream &is,
165                 Map *parent,
166                 v2s16 p2d,
167                 std::map<v2s16, MapSector*> & sectors,
168                 IGameDef *gamedef
169         )
170 {
171         /*
172                 [0] u8 serialization version
173                 + heightmap data
174         */
175
176         /*
177                 Read stuff
178         */
179
180         // Read version
181         u8 version = SER_FMT_VER_INVALID;
182         is.read((char*)&version, 1);
183
184         if(!ser_ver_supported(version))
185                 throw VersionMismatchException("ERROR: MapSector format not supported");
186
187         /*
188                 Add necessary reading stuff here
189         */
190
191         /*
192                 Get or create sector
193         */
194
195         ServerMapSector *sector = NULL;
196
197         std::map<v2s16, MapSector*>::iterator n = sectors.find(p2d);
198
199         if(n != sectors.end())
200         {
201                 warningstream<<"deSerializing existent sectors not supported "
202                                 "at the moment, because code hasn't been tested."
203                                 <<std::endl;
204
205                 MapSector *sector = n->second;
206                 assert(sector->getId() == MAPSECTOR_SERVER);
207                 return (ServerMapSector*)sector;
208         }
209
210         sector = new ServerMapSector(parent, p2d, gamedef);
211         sectors[p2d] = sector;
212
213         /*
214                 Set stuff in sector
215         */
216
217         // Nothing here
218
219         return sector;
220 }
221
222 #ifndef SERVER
223 /*
224         ClientMapSector
225 */
226
227 ClientMapSector::ClientMapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
228                 MapSector(parent, pos, gamedef)
229 {
230 }
231 #endif // !SERVER
232
233 //END