1 /***************************************************************************
2 						propertymanager.cpp  -  description
3 							-------------------
4 	begin                : feb 6th, 2004
5 	copyright            : (C) 2004-2010 by Duong Khang NGUYEN
6 	email                : neoneurone @ gmail com
7 
8 	$Id: propertymanager.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_structure_type.h"
22 
23 // OpenCity headers
24 #include "propertymanager.h"
25 #include "structure.h"
26 
27 // Standard headers
28 #include <algorithm>		// We use STL algorithms
29 #include <sstream>			// We use stringstream or data conversion
30 
31 
32    /*=====================================================================*/
PropertyManager()33 PropertyManager::PropertyManager():
34 _vpConf(OC_GRAPHIC_CODE_MAX, NULL)
35 {
36 	OPENCITY_DEBUG( "ctor" );
37 
38 	string strAc = string(".ac");
39 	string strConf = string(".conf");
40 
41 // Read the main graphism configuration file
42 	Conf* pConf = new Conf();
43 	string fileName = ocConfigDirPrefix(OC_GRAPHISM_FILE_FILENAME);
44 	if (pConf->Open( fileName ) != OC_ERR_FREE) {
45 		cerr << "WARNING: Error opening graphism config file: " << fileName << endl;
46 		delete pConf;
47 		pConf = NULL;
48 		abort();
49 	}
50 
51 // Initialize the Conf* vector
52 	string strValue;
53 	string::size_type pos;
54 	std::stringstream ss;
55 	Conf* pconfFile;
56 	for (uint i = 0; i < OC_GRAPHIC_CODE_MAX; i++ ) {
57 		ss << i;
58 		strValue = pConf->GetValue(ss.str(), "");
59 		ss.str("");
60 
61 	// IF the key is not defined in the config file THEN
62 		if (strValue == "")
63 			continue;
64 
65 	// Reverse search for the ".ac" file extension
66 		pos = strValue.rfind( strAc );
67 		if (pos != strValue.npos ) {
68 		// Replace the file extension ".ac" by ".conf"
69 			strValue.replace( pos, strConf.size(), strConf );
70 		}
71 
72 		pconfFile = new Conf();
73 		fileName = ocDataDirPrefix(strValue);
74 		if (pconfFile->Open( fileName ) == OC_ERR_FREE) {
75 			_vpConf[i] = pconfFile;
76 		}
77 		else {
78 			delete pconfFile;
79 			pconfFile = NULL;
80 		}
81 	} // for
82 
83 	pConf->Close();
84 	delete pConf;
85 	pConf = NULL;
86 }
87 
88 
89    /*=====================================================================*/
~PropertyManager()90 PropertyManager::~PropertyManager()
91 {
92 	OPENCITY_DEBUG( "dtor" );
93 
94 // delete the Conf* vector
95 	for (int i = 0; i < OC_GRAPHIC_CODE_MAX; i++ ) {
96 		if (_vpConf[i] != NULL) {
97 			_vpConf[i]->Close();		// Close the file
98 			delete _vpConf[i];			// NOTE: delete NULL pointer has no effect
99 		}
100 	}
101 }
102 
103 
104    /*=====================================================================*/
105 const int
Get(const OPENCITY_PROPERTY_CODE & pCode,const OPENCITY_STRUCTURE_CODE & sCode,const Structure * pcStruct) const106 PropertyManager::Get(
107 	const OPENCITY_PROPERTY_CODE & pCode,
108 	const OPENCITY_STRUCTURE_CODE & sCode,
109 	const Structure* pcStruct ) const
110 {
111 	static int value;
112 
113 	switch (pCode) {
114 		case OC_TOOL_COST:
115 			switch (sCode) {
116 				case OC_STRUCTURE_RES:
117 				case OC_STRUCTURE_COM:
118 					value = 5; break;
119 				case OC_STRUCTURE_IND:
120 					value = 8; break;
121 				case OC_STRUCTURE_PARK:
122 					value = 100; break;
123 				case OC_STRUCTURE_ELINE:
124 					value = 3; break;
125 				case OC_STRUCTURE_EPLANT_COAL:
126 					value = 2000; break;
127 				case OC_STRUCTURE_EPLANT_NUCLEAR:
128 					value = 5000; break;
129 				case OC_STRUCTURE_FIREDEPT:
130 				case OC_STRUCTURE_POLICEDEPT:
131 				case OC_STRUCTURE_HOSPITALDEPT:
132 				case OC_STRUCTURE_EDUCATIONDEPT:
133 					value = 1500; break;
134 				case OC_STRUCTURE_ROAD:
135 				case OC_STRUCTURE_FLORA:
136 					value = 5; break;
137 
138 				case OC_STRUCTURE_TEST:			// Development test feature
139 					value = 0; break;
140 				default:
141 					value = 0;
142 					OPENCITY_DEBUG("WARNING: game design error");
143 					assert( 0 );
144 			}
145 			break;
146 
147 		case OC_DESTROY_COST:
148 			assert( pcStruct != NULL );
149 			switch (sCode) {
150 				case OC_STRUCTURE_RES:
151 				case OC_STRUCTURE_COM:
152 					value = 2*(pcStruct->GetLevel() + 1); break;
153 				case OC_STRUCTURE_IND:
154 					value = 3*(pcStruct->GetLevel() + 1); break;
155 
156 				case OC_STRUCTURE_PARK:
157 					value = 10; break;
158 				case OC_STRUCTURE_ELINE:
159 					value = 1; break;
160 				case OC_STRUCTURE_ROAD:
161 				case OC_STRUCTURE_FLORA:
162 					value = 4; break;
163 
164 				case OC_STRUCTURE_PART:
165 				case OC_STRUCTURE_EPLANT_COAL:
166 				case OC_STRUCTURE_FIREDEPT:
167 				case OC_STRUCTURE_POLICEDEPT:
168 				case OC_STRUCTURE_HOSPITALDEPT:
169 				case OC_STRUCTURE_EDUCATIONDEPT:
170 					value = 200; break;
171 
172 				case OC_STRUCTURE_EPLANT_NUCLEAR:
173 					value = 800; break;
174 
175 				case OC_STRUCTURE_TEST:			// Development test feature
176 					value = 0; break;
177 				default:
178 					value = 0;
179 					OPENCITY_DEBUG("WARNING: game design error");
180 					assert( 0 );
181 			}
182 			break;
183 
184 		case OC_MAINTENANCE_COST:
185 			switch (sCode) {
186 				case OC_STRUCTURE_RES:
187 				case OC_STRUCTURE_COM:
188 				case OC_STRUCTURE_IND:
189 				case OC_STRUCTURE_PART:
190 					value = 0; break;
191 				case OC_STRUCTURE_PARK:
192 					value = 1; break;
193 				case OC_STRUCTURE_ELINE:
194 					value = 1; break;
195 				case OC_STRUCTURE_EPLANT_COAL:
196 					value = 20; break;
197 				case OC_STRUCTURE_EPLANT_NUCLEAR:
198 					value = 80; break;
199 				case OC_STRUCTURE_FIREDEPT:
200 				case OC_STRUCTURE_POLICEDEPT:
201 				case OC_STRUCTURE_HOSPITALDEPT:
202 				case OC_STRUCTURE_EDUCATIONDEPT:
203 					value = 15; break;
204 				case OC_STRUCTURE_ROAD:
205 				case OC_STRUCTURE_FLORA:
206 					value = 1; break;
207 
208 				case OC_STRUCTURE_TEST:			// Development test feature
209 					value = 0; break;
210 				default:
211 					value = 0;
212 					OPENCITY_DEBUG( "WARNING: game design error" );
213 					assert( 0 );
214 			}
215 			break;
216 
217 		default:
218 			value = 0;
219 			OPENCITY_DEBUG("WARNING: game design error");
220 			assert( 0 );
221 	}
222 
223 /*
224 #ifndef NDEBUG
225 // Debug code
226 	if ( value == 0 ) {
227 		cerr << "pCode: " << pCode << "/ sCode: " << sCode
228 			 << "/ pcStruct: " << pcStruct << endl;
229 		assert( 0 );
230 	}
231 #endif
232 */
233 
234 	return value;
235 }
236 
237 
238    /*=====================================================================*/
239 const OPENCITY_GRAPHIC_CODE
GetGC(const OPENCITY_STRUCTURE_CODE scode) const240 PropertyManager::GetGC(
241 	const OPENCITY_STRUCTURE_CODE scode ) const
242 {
243 // For better readability and performance (use of "static" keyword)
244 	static OPENCITY_GRAPHIC_CODE gcode;
245 
246 	switch (scode) {
247 		case OC_STRUCTURE_UNDEFINED:
248 			gcode = OC_EMPTY;
249 			break;
250 
251 	// Multi level graphic code
252 		case OC_STRUCTURE_RES:
253 			gcode = OC_RES_ZONE0;
254 			break;
255 		case OC_STRUCTURE_COM:
256 			gcode = OC_COM_ZONE0;
257 			break;
258 		case OC_STRUCTURE_IND:
259 			gcode = OC_IND_ZONE0;
260 			break;
261 		case OC_STRUCTURE_PARK:
262 			gcode = OC_PARK0;
263 			break;
264 		case OC_STRUCTURE_FLORA:
265 			gcode = OC_TREE_BEGIN;
266 			break;
267 
268 	// Special path type structure
269 		case OC_STRUCTURE_ROAD:
270 			gcode = OC_ROAD_O_N;
271 			break;
272 		case OC_STRUCTURE_ELINE:
273 			gcode = OC_ELINE_O_N;
274 			break;
275 
276 	// Single level graphic code
277 		case OC_STRUCTURE_TEST:
278 			gcode = OC_TEST_BUILDING;
279 			break;
280 		case OC_STRUCTURE_PART:
281 			gcode = OC_EMPTY;
282 			break;
283 		case OC_STRUCTURE_EPLANT_COAL:
284 			gcode = OC_EPLANT_COAL;
285 			break;
286 		case OC_STRUCTURE_EPLANT_NUCLEAR:
287 			gcode = OC_EPLANT_NUCLEAR;
288 			break;
289 		case OC_STRUCTURE_FIREDEPT:
290 			gcode = OC_FIRE_DEPT;
291 			break;
292 		case OC_STRUCTURE_POLICEDEPT:
293 			gcode = OC_POLICE_DEPT;
294 			break;
295 		case OC_STRUCTURE_HOSPITALDEPT:
296 			gcode = OC_HOSPITAL_DEPT;
297 			break;
298 		case OC_STRUCTURE_EDUCATIONDEPT:
299 			gcode = OC_EDUCATION_DEPT;
300 			break;
301 
302 		default:
303 			gcode = OC_EMPTY;
304 			OPENCITY_DEBUG( "WARNING: game design error, unknown structure !" );
305 			assert( 0 );
306 			break;
307 	}
308 
309 	return gcode;
310 }
311 
312 
313    /*=====================================================================*/
314 const OPENCITY_STRUCTURE_TYPE
GetST(const OPENCITY_STRUCTURE_CODE scode) const315 PropertyManager::GetST(
316 	const OPENCITY_STRUCTURE_CODE scode ) const
317 {
318 // For better readability and performance (use of "static" keyword)
319 	static OPENCITY_STRUCTURE_TYPE tcode;
320 
321 	switch (scode) {
322 		case OC_STRUCTURE_RES:
323 		case OC_STRUCTURE_PARK:
324 			tcode = OC_TYPE_RESIDENCE; break;
325 		case OC_STRUCTURE_COM:
326 			tcode = OC_TYPE_COMMERCE; break;
327 		case OC_STRUCTURE_IND:
328 			tcode = OC_TYPE_INDUSTRY; break;
329 
330 		case OC_STRUCTURE_EPLANT_COAL:
331 		case OC_STRUCTURE_EPLANT_NUCLEAR:
332 			tcode = OC_TYPE_ELECTRICITY; break;
333 
334 		case OC_STRUCTURE_ROAD:
335 		case OC_STRUCTURE_ELINE:
336 			tcode = OC_TYPE_PATH; break;
337 
338 		case OC_STRUCTURE_FIREDEPT:
339 		case OC_STRUCTURE_POLICEDEPT:
340 		case OC_STRUCTURE_HOSPITALDEPT:
341 		case OC_STRUCTURE_MILITARYDEPT:
342 		case OC_STRUCTURE_EDUCATIONDEPT:
343 			tcode = OC_TYPE_GOVERNMENT; break;
344 
345 		case OC_STRUCTURE_FLORA:
346 			tcode = OC_TYPE_TREE; break;
347 
348 		case OC_STRUCTURE_PART:
349 			tcode = OC_TYPE_UNDEFINED; break;
350 
351 	// TODO
352 		case OC_STRUCTURE_UNDEFINED:
353 		case OC_STRUCTURE_ANY:
354 		case OC_STRUCTURE_ELECTRIC:
355 			tcode = OC_TYPE_UNDEFINED; assert( 0 ); break;
356 
357 		case OC_STRUCTURE_TEST:			// Development test feature
358 			tcode = OC_TYPE_UNDEFINED; break;
359 		default:
360 			tcode = OC_TYPE_UNDEFINED;
361 			OPENCITY_DEBUG( "WARNING: game design error" );
362 			assert( 0 );
363 	}
364 
365 	return tcode;
366 }
367 
368 
369    /*=====================================================================*/
370 void
GetWLH(const OPENCITY_GRAPHIC_CODE gcode,uint & w,const uint defw,uint & l,const uint defl,uint & h,const uint defh)371 PropertyManager::GetWLH(
372 	const OPENCITY_GRAPHIC_CODE gcode,
373 	uint& w, const uint defw,
374 	uint& l, const uint defl,
375 	uint& h, const uint defh)
376 {
377 	static OC_LINT width, length, height;
378 
379 	propertymanagerGetLint( gcode, "width", width, defw );
380 	w = (uint)width;
381 	propertymanagerGetLint( gcode, "length", length, defl );
382 	l = (uint)length;
383 	propertymanagerGetLint( gcode, "height", height, defh );
384 	h = (uint)height;
385 
386 /* debug
387 	cout << "code: " << gcode
388 		 << "/ w: " << w
389 		 << "/ l: " << l
390 		 << "/ h: " << h << endl;
391 */
392 }
393 
394 
395 
396 
397 
398    /*=====================================================================*/
399    /*                           PRIVATE METHODS                           */
400    /*=====================================================================*/
401 const string
propertymanagerGetStr(const OPENCITY_GRAPHIC_CODE gcode,const string & key,const string & defaultValue)402 PropertyManager::propertymanagerGetStr(
403 	const OPENCITY_GRAPHIC_CODE gcode,
404 	const string& key,
405 	const string& defaultValue)
406 {
407 	return "";
408 }
409 
410 
411    /*=====================================================================*/
412 const OPENCITY_ERR_CODE
propertymanagerGetLint(const OPENCITY_GRAPHIC_CODE gcode,const string & key,OC_LINT & rlint,const OC_LINT defaultValue)413 PropertyManager::propertymanagerGetLint(
414 	const OPENCITY_GRAPHIC_CODE gcode,
415 	const string& key,
416 	OC_LINT& rlint,
417 	const OC_LINT defaultValue)
418 {
419 // Preconditions
420 	assert( (uint)gcode < _vpConf.size() );
421 
422 // Get the configuration pointer.
423 	Conf* pConf = _vpConf[gcode];
424 	assert( pConf != NULL );
425 
426 	return pConf->GetLint( key, rlint, defaultValue );
427 }
428