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