1 /***************************************************************************
2 map.cpp - description
3 -------------------
4 begin : january 24th, 2004
5 copyright : (C) 2004-2006 Duong Khang NGUYEN
6 email : neoneurone @ gmail com
7
8 $Id: map.cpp 450 2010-11-21 19:11:43Z neoneurone $
9 ***************************************************************************/
10
11 /***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * any later version. *
17 * *
18 ***************************************************************************/
19
20 // Useful enumerations
21 #include "opencity_direction.h"
22 #include "opencity_structure_type.h"
23
24 // OpenCity headers
25 #include "map.h"
26 #include "layer.h"
27 #include "mapmaker.h" // Map generator
28
29 // Global settings
30 #include "globalvar.h"
31 extern GlobalVar gVars;
32
33
34 /*=====================================================================*/
Map(const uint width,const uint height)35 Map::Map(
36 const uint width,
37 const uint height ):
38 _uiMapWidth( width ),
39 _uiMapHeight( height ),
40 _pclayer( NULL )
41 {
42 OPENCITY_DEBUG("ctor");
43
44 uint size = (width + 1) * (height + 1);
45 _btabSquareHeight = new signed char[ size ];
46
47 assert(gVars.gpMapMaker != NULL);
48 int* heightMap = gVars.gpMapMaker->getMap();
49 for (uint i = 0; i < size; i++)
50 _btabSquareHeight[i] = heightMap[i];
51
52 delete [] heightMap;
53 }
54
55
56 /*=====================================================================*/
~Map()57 Map::~Map()
58 {
59 OPENCITY_DEBUG("dtor");
60
61 delete [] _btabSquareHeight;
62 _btabSquareHeight = NULL;
63 }
64
65
66 /*=====================================================================*/
67 void
SaveTo(std::fstream & rfs)68 Map::SaveTo( std::fstream& rfs )
69 {
70 OPENCITY_DEBUG( __PRETTY_FUNCTION__ << " saving...");
71
72 rfs << _uiMapWidth << std::ends;
73 rfs << _uiMapHeight << std::ends;
74 uint size = (_uiMapWidth + 1) * (_uiMapHeight + 1);
75
76 for (uint i = 0; i < size; i++)
77 rfs << (int)_btabSquareHeight[i] << std::ends;
78 }
79
80
81 /*=====================================================================*/
82 void
LoadFrom(std::fstream & rfs)83 Map::LoadFrom( std::fstream& rfs )
84 {
85 OPENCITY_DEBUG( __PRETTY_FUNCTION__ << "loading...");
86
87 rfs >> _uiMapWidth; rfs.ignore();
88 rfs >> _uiMapHeight; rfs.ignore();
89 uint size = (_uiMapWidth + 1) * (_uiMapHeight + 1);
90
91 delete [] _btabSquareHeight;
92 _btabSquareHeight = new signed char [size];
93
94 int temp = 0;
95 for (uint i = 0; i < size; i++) {
96 rfs >> temp; rfs.ignore();
97 _btabSquareHeight[i] = (signed char)temp;
98 } // for
99 }
100
101
102 /*=====================================================================*/
103 OPENCITY_ERR_CODE
ChangeHeight(const uint & rcuiW,const uint & rcuiH,const OPENCITY_MAP_VARIATION & enumVar)104 Map::ChangeHeight(
105 const uint& rcuiW,
106 const uint& rcuiH,
107 const OPENCITY_MAP_VARIATION& enumVar )
108 {
109 // debugging
110 assert(_pclayer!= NULL);
111
112 if (_pclayer != NULL) {
113 uint w1 = rcuiW;
114 uint h1 = rcuiH;
115 uint w2 = rcuiW;
116 uint h2 = rcuiH;
117 // if the surface contains something, we return
118 GetPossibleWH( w1, h1, -1, -1 );
119 GetPossibleWH( w2, h2, 1, 1 );
120 if (_pclayer->ContainStructure(
121 w1, h1, w2, h2, OC_STRUCTURE_ANY ) == true)
122 return OC_ERR_SOMETHING;
123 }
124
125 signed char tabH[4];
126 char refH = 0;
127 uint i = 0;
128 uint linear = 0;
129
130 this->GetSquareHeight( rcuiW, rcuiH, tabH );
131
132 // Check for maximum variation
133 switch (enumVar) {
134 case OC_MAP_UP:
135 refH = GetSquareMinHeight( rcuiW, rcuiH );
136 if (refH == OC_MAP_HEIGHT_MAX)
137 return OC_ERR_SOMETHING;
138 break;
139 case OC_MAP_DOWN:
140 refH = GetSquareMaxHeight( rcuiW, rcuiH );
141 if (refH == OC_MAP_HEIGHT_MIN )
142 return OC_ERR_SOMETHING;
143 break;
144 default:
145 break; // Keep GCC happy
146 }
147
148 for (i = 0; i < 4; i++)
149 if (tabH[i] == refH)
150 tabH[i] += enumVar;
151
152 //--- left-up and right-up heights ---
153 _WH2Linear( rcuiW, rcuiH, linear );
154 _btabSquareHeight[ linear ] = tabH[0];
155 _btabSquareHeight[ linear+1 ] = tabH[3];
156 //--- left-down and right-down heights ---
157 _WH2Linear( rcuiW, rcuiH+1, linear );
158 _btabSquareHeight[ linear ] = tabH[1];
159 _btabSquareHeight[ linear+1 ] = tabH[2];
160
161 return OC_ERR_FREE;
162 }
163
164
165 /*=====================================================================*/
166 void
SetLayer(const Layer * layer)167 Map::SetLayer( const Layer* layer )
168 {
169 _pclayer = layer;
170 }
171
172
173 /*=====================================================================*/
174 const char
GetLinearHeight(const uint & rcuiIndex) const175 Map::GetLinearHeight( const uint& rcuiIndex ) const
176 {
177 return _btabSquareHeight[rcuiIndex];
178 }
179
180
181 /*=====================================================================*/
182 const uint
GetMaxLinear() const183 Map::GetMaxLinear() const
184 {
185 return ((_uiMapWidth + 1) * (_uiMapHeight + 1) - 1);
186 }
187
188
189 /*=====================================================================*/
190 void
GetSquareHeight(const uint & rcuiW,const uint & rcuiH,signed char btabH[]) const191 Map::GetSquareHeight(
192 const uint& rcuiW,
193 const uint& rcuiH,
194 signed char btabH[] ) const
195 {
196 uint linear;
197
198 /*--- left-up and right-up heights ---*/
199 _WH2Linear( rcuiW, rcuiH, linear );
200 btabH[0] = _btabSquareHeight[ linear ];
201 btabH[3] = _btabSquareHeight[ linear+1 ];
202 /*--- left-down and right-down heights ---*/
203 _WH2Linear( rcuiW, rcuiH+1, linear );
204 btabH[1] = _btabSquareHeight[ linear ];
205 btabH[2] = _btabSquareHeight[ linear+1 ];
206 }
207
208
209 /*=====================================================================*/
210 const signed char
GetSquareMinHeight(const uint & rcuiW,const uint & rcuiL) const211 Map::GetSquareMinHeight(
212 const uint& rcuiW,
213 const uint& rcuiL ) const
214 {
215 signed char btabH[4];
216 signed char minH = 127;
217
218 this->GetSquareHeight( rcuiW, rcuiL, btabH );
219 for (int i = 0; i < 4; i++) {
220 if (btabH[i] < minH)
221 minH = btabH[i];
222
223 //debug cout << "minH : " << (int)minH << endl;
224 } // for
225
226 return minH;
227 }
228
229
230 /*=====================================================================*/
231 const signed char
GetSquareMaxHeight(const uint & rcuiW,const uint & rcuiH) const232 Map::GetSquareMaxHeight(
233 const uint& rcuiW,
234 const uint& rcuiH ) const
235 {
236 signed char btabH[4];
237 signed char maxH = -127;
238
239 this->GetSquareHeight( rcuiW, rcuiH, btabH );
240 for (int i = 0; i < 4; i++) {
241 if (btabH[i] > maxH)
242 maxH = btabH[i];
243 } // for
244
245 return maxH;
246 }
247
248
249 /*=====================================================================*/
250 const bool
IsSquarePlane(const uint w,const uint l) const251 Map::IsSquarePlane(
252 const uint w,
253 const uint l ) const
254 {
255 signed char btabH[4];
256
257 this->GetSquareHeight( w, l, btabH );
258 bool isPlane = (btabH[0] == btabH[1]) and (btabH[0] == btabH[2]) and (btabH[0] == btabH[3]);
259
260 return isPlane;
261 }
262
263
264 /*=====================================================================*/
265 const bool
IsSurfacePlane(const uint w1,const uint l1,const uint w2,const uint l2) const266 Map::IsSurfacePlane(
267 const uint w1, const uint l1,
268 const uint w2, const uint l2 ) const
269 {
270 bool isPlane = true;
271 uint w = w1, l = l1;
272
273 while (isPlane and l <= l2) {
274 w = w1;
275 while (isPlane and w <= w2) {
276 isPlane = this->IsSquarePlane( w, l );
277 w++;
278 } // while
279 l++;
280 } // while
281
282 return isPlane;
283 }
284
285
286 /*=====================================================================*/
287 const bool
IsSquareLinearPlane(const uint & rcuiLinearIndex)288 Map::IsSquareLinearPlane(
289 const uint& rcuiLinearIndex )
290 {
291 uint w, h;
292
293 _Linear2WH( rcuiLinearIndex, w, h );
294
295 return this->IsSquarePlane( w, h );
296 }
297
298
299 /*=====================================================================*/
300 const bool
GetNeighbourWH(const uint & rcuiMapW,const uint & rcuiMapH,uint & ruiNbrW,uint & ruiNbrH,const OPENCITY_DIRECTION & enumDir) const301 Map::GetNeighbourWH(
302 const uint& rcuiMapW,
303 const uint& rcuiMapH,
304 uint& ruiNbrW,
305 uint& ruiNbrH,
306 const OPENCITY_DIRECTION& enumDir ) const
307 {
308 int w = rcuiMapW;
309 int h = rcuiMapH;
310
311 /*debug
312 cout << "w : " << w
313 << "/ h : " << h << endl;
314 */
315
316 switch (enumDir) {
317 case OC_DIR_O_N: h--; break;
318 case OC_DIR_N_E: h--; w++; break;
319 case OC_DIR_O_E: w++; break;
320 case OC_DIR_S_E: w++; h++; break;
321 case OC_DIR_O_S: h++; break;
322 case OC_DIR_S_W: h++; w--; break;
323 case OC_DIR_O_W: w--; break;
324 case OC_DIR_N_W: w--; h--; break;
325 default: break;
326 }
327
328 /*debug
329 cout << "w : " << w
330 << "/ h : " << h << endl;
331 */
332
333 if ((w < 0) || (w >= (int)_uiMapWidth)
334 || (h < 0) || (h >= (int)_uiMapHeight)) {
335 return false;
336 }
337 else {
338 ruiNbrW = w;
339 ruiNbrH = h;
340 return true;
341 }
342 }
343
344
345 /*=====================================================================*/
346 void
GetPossibleWH(uint & rW,uint & rH,const int & deltaW,const int & deltaH) const347 Map::GetPossibleWH(
348 uint& rW,
349 uint& rH,
350 const int& deltaW,
351 const int& deltaH ) const
352 {
353 int newW = rW + deltaW;
354 int newH = rH + deltaH;
355
356 if (newW < 0)
357 newW = 0;
358 if (newW >= (int)_uiMapWidth)
359 newW = _uiMapWidth - 1;
360 if (newH < 0)
361 newH = 0;
362 if (newH >= (int)_uiMapHeight)
363 newH = _uiMapHeight - 1;
364
365 rW = newW;
366 rH = newH;
367 }
368
369
370 /*=====================================================================*/
371 void
_Linear2WH(const uint & linear,uint & w,uint & h) const372 Map::_Linear2WH( const uint& linear,
373 uint& w,
374 uint& h ) const
375 {
376 //debug
377 cout << "not implemented yet " << endl;
378 assert(0);
379 }
380
381
382 /*=====================================================================*/
383 inline uint
_WH2Linear(const uint & w,const uint & h,uint & linear) const384 Map::_WH2Linear(
385 const uint& w,
386 const uint& h,
387 uint& linear ) const
388 {
389 return (linear = h * (_uiMapWidth + 1) + w);
390 }
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417