1 /*
2  * Copyright (c) 1997 - 2001 Hj. Malthaner
3  *
4  * This file is part of the Simutrans project under the artistic license.
5  * (see license.txt)
6  *
7  * construction of cities, creation of passengers
8  *
9  */
10 
11 #include <string>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <math.h>
16 
17 #include "boden/wege/strasse.h"
18 #include "boden/grund.h"
19 #include "boden/boden.h"
20 #include "gui/simwin.h"
21 #include "simworld.h"
22 #include "simware.h"
23 #include "player/simplay.h"
24 #include "simplan.h"
25 #include "display/simimg.h"
26 #include "vehicle/simroadtraffic.h"
27 #include "simhalt.h"
28 #include "simfab.h"
29 #include "simcity.h"
30 #include "simmesg.h"
31 #include "simcolor.h"
32 
33 #include "gui/minimap.h"
34 #include "gui/city_info.h"
35 
36 #include "descriptor/building_desc.h"
37 
38 #include "simintr.h"
39 #include "simdebug.h"
40 
41 #include "obj/gebaeude.h"
42 
43 #include "dataobj/translator.h"
44 #include "dataobj/settings.h"
45 #include "dataobj/loadsave.h"
46 #include "dataobj/tabfile.h"
47 #include "dataobj/environment.h"
48 
49 #include "finder/building_placefinder.h"
50 #include "bauer/wegbauer.h"
51 #include "bauer/brueckenbauer.h"
52 #include "bauer/hausbauer.h"
53 #include "bauer/fabrikbauer.h"
54 #include "utils/cbuffer_t.h"
55 #include "utils/simrandom.h"
56 #include "utils/simstring.h"
57 
58 
59 #define PACKET_SIZE (7)
60 
61 /**
62  * This variable is used to control the fractional precision of growth to prevent loss when quantities are small.
63  * Growth calculations use 64 bit signed integers.
64  * Although this is actually scale factor, a power of two is recommended for optimization purposes.
65  */
66 static sint64 const CITYGROWTH_PER_CITICEN = 1ll << 32; // Q31.32 fractional form.
67 
68 karte_ptr_t stadt_t::welt; // one is enough ...
69 
70 
71 /********************************* From here on cityrules stuff *****************************************/
72 
73 
74 /**
75  * in this fixed interval, construction will happen
76  * 21s = 21000 per house
77  */
78 const uint32 stadt_t::city_growth_step = 21000;
79 
80 /**
81  * this is the default factor to prefer clustering
82  */
83 uint32 stadt_t::cluster_factor = 10;
84 
85 /*
86  * chance to do renovation instead new building (in percent)
87  * @author prissi
88  */
89 static uint32 renovation_percentage = 12;
90 
91 /*
92  * minimum ratio of city area to building area to allow expansion
93  * the higher this value, the slower the city expansion if there are still "holes"
94  * @author prissi
95  */
96 static uint32 min_building_density = 25;
97 
98 // the following are the scores for the different building types
99 static sint16 ind_start_score =   0;
100 static sint16 com_start_score = -10;
101 static sint16 res_start_score =   0;
102 
103 // order: res, com, ind
104 static sint16 ind_neighbour_score[] = { -8, 0,  8 };
105 static sint16 com_neighbour_score[] = {  1, 8,  1 };
106 static sint16 res_neighbour_score[] = {  8, 0, -8 };
107 
108 /**
109  * Rule data structure
110  * maximum 7x7 rules
111  * @author Hj. Malthaner
112  */
113 class rule_entry_t {
114 public:
115 	uint8 x,y;
116 	char flag;
rule_entry_t(uint8 x_=0,uint8 y_=0,char f_='.')117 	rule_entry_t(uint8 x_=0, uint8 y_=0, char f_='.') : x(x_), y(y_), flag(f_) {}
118 
rdwr(loadsave_t * file)119 	void rdwr(loadsave_t* file)
120 	{
121 		file->rdwr_byte(x);
122 		file->rdwr_byte(y);
123 		uint8 c = flag;
124 		file->rdwr_byte(c);
125 		flag = c;
126 	}
127 };
128 
129 class rule_t {
130 public:
131 	sint16  chance;
132 	vector_tpl<rule_entry_t> rule;
rule_t(uint32 count=0)133 	rule_t(uint32 count=0) : chance(0), rule(count) {}
134 
rdwr(loadsave_t * file)135 	void rdwr(loadsave_t* file)
136 	{
137 		file->rdwr_short(chance);
138 
139 		if (file->is_loading()) {
140 			rule.clear();
141 		}
142 		uint32 count = rule.get_count();
143 		file->rdwr_long(count);
144 		for(uint32 i=0; i<count; i++) {
145 			if (file->is_loading()) {
146 				rule.append(rule_entry_t());
147 			}
148 			rule[i].rdwr(file);
149 		}
150 	}
151 };
152 
153 // house rules
154 static vector_tpl<rule_t *> house_rules;
155 
156 // and road rules
157 static vector_tpl<rule_t *> road_rules;
158 
159 /**
160  * Symbols in rules:
161  * S = not a road
162  * s = is a road
163  * n = is nature/empty
164  * H = not a house
165  * h = is a house
166  * T = not a stop	// added in 88.03.3
167  * t = is a stop // added in 88.03.3
168  * u = good slope for way
169  * U = not a slope for ways
170  * . = beliebig
171  */
172 
173 // here '.' is ignored, since it will not be tested anyway
174 static char const* const allowed_chars_in_rule = "SsnHhTtUu";
175 
176 /*
177  * @param pos position to check
178  * @param regel the rule to evaluate
179  * @return true on match, false otherwise
180  * @author Hj. Malthaner
181  */
bewerte_loc(const koord pos,const rule_t & regel,int rotation)182 bool stadt_t::bewerte_loc(const koord pos, const rule_t &regel, int rotation)
183 {
184 	//printf("Test for (%s) in rotation %d\n", pos.get_str(), rotation);
185 	koord k;
186 
187 	FOR(vector_tpl<rule_entry_t>, const& r, regel.rule) {
188 		uint8 x,y;
189 		switch (rotation) {
190 			default:
191 			case   0: x=r.x; y=r.y; break;
192 			case  90: x=r.y; y=6-r.x; break;
193 			case 180: x=6-r.x; y=6-r.y; break;
194 			case 270: x=6-r.y; y=r.x; break;
195 		}
196 
197 		const koord k(pos.x+x-3, pos.y+y-3);
198 		const grund_t* gr = welt->lookup_kartenboden(k);
199 		if (gr == NULL) {
200 			// outside of the map => cannot apply this rule
201 			return false;
202 		}
203 		switch (r.flag) {
204 			case 's':
205 				// road?
206 				if (!gr->hat_weg(road_wt)) return false;
207 				break;
208 			case 'S':
209 				// not road?
210 				if (gr->hat_weg(road_wt)) return false;
211 				break;
212 			case 'h':
213 				// is house
214 				if (gr->get_typ() != grund_t::fundament  ||  gr->obj_bei(0)->get_typ()!=obj_t::gebaeude) return false;
215 				break;
216 			case 'H':
217 				// no house
218 				if (gr->get_typ() == grund_t::fundament) return false;
219 				break;
220 			case 'n':
221 				// nature/empty
222 				if (!gr->ist_natur() || gr->kann_alle_obj_entfernen(NULL) != NULL) return false;
223 				break;
224 			case 'U':
225 				// unbuildable for road
226 				if (!slope_t::is_way(gr->get_grund_hang())) return false;
227 				break;
228 			case 'u':
229 				// road may be buildable
230 				if (slope_t::is_way(gr->get_grund_hang())) return false;
231 				break;
232 			case 't':
233 				// here is a stop/extension building
234 				if (!gr->is_halt()) return false;
235 				break;
236 			case 'T':
237 				// no stop
238 				if (gr->is_halt()) return false;
239 				break;
240 			default: ;
241 				// ignore
242 		}
243 	}
244 	return true;
245 }
246 
247 
248 /**
249  * Check rule in all transformations at given position
250  * prissi: but the rules should explicitly forbid building then?!?
251  * @author Hj. Malthaner
252  */
bewerte_pos(const koord pos,const rule_t & regel)253 sint32 stadt_t::bewerte_pos(const koord pos, const rule_t &regel)
254 {
255 	// will be called only a single time, so we can stop after a single match
256 	if(bewerte_loc(pos, regel,   0) ||
257 		 bewerte_loc(pos, regel,  90) ||
258 		 bewerte_loc(pos, regel, 180) ||
259 		 bewerte_loc(pos, regel, 270)) {
260 		return 1;
261 	}
262 	return 0;
263 }
264 
265 
bewerte_strasse(koord k,sint32 rd,const rule_t & regel)266 void stadt_t::bewerte_strasse(koord k, sint32 rd, const rule_t &regel)
267 {
268 	if (simrand(rd) == 0) {
269 		best_strasse.check(k, bewerte_pos(k, regel));
270 	}
271 }
272 
273 
bewerte_haus(koord k,sint32 rd,const rule_t & regel)274 void stadt_t::bewerte_haus(koord k, sint32 rd, const rule_t &regel)
275 {
276 	if (simrand(rd) == 0) {
277 		best_haus.check(k, bewerte_pos(k, regel));
278 	}
279 }
280 
281 
282 /**
283  * Reads city configuration data
284  * @author Hj. Malthaner
285  */
cityrules_init(const std::string & objfilename)286 bool stadt_t::cityrules_init(const std::string &objfilename)
287 {
288 	tabfile_t cityconf;
289 	// first take user data, then user global data
290 	const std::string user_dir=env_t::user_dir;
291 	if (!cityconf.open((user_dir+"cityrules.tab").c_str())) {
292 		if (!cityconf.open((objfilename+"config/cityrules.tab").c_str())) {
293 			dbg->fatal("stadt_t::init()", "Can't read cityrules.tab" );
294 			return false;
295 		}
296 	}
297 
298 	tabfileobj_t contents;
299 	cityconf.read(contents);
300 
301 	char buf[128];
302 
303 	cluster_factor = (uint32)contents.get_int("cluster_factor", 10);
304 	renovation_percentage = (uint32)contents.get_int("renovation_percentage", 25);
305 	// to keep compatible with the typo, here both are ok
306 	min_building_density = (uint32)contents.get_int("minimum_building_desity", 25);
307 	min_building_density = (uint32)contents.get_int("minimum_building_density", min_building_density);
308 
309 	// init the building value tables
310 	ind_start_score = contents.get_int("ind_start_score", 0);
311 	ind_neighbour_score[0] = contents.get_int("ind_near_res", -8);
312 	ind_neighbour_score[1] = contents.get_int("ind_near_com",  0);
313 	ind_neighbour_score[2] = contents.get_int("ind_near_ind",  8);
314 
315 	com_start_score = contents.get_int("com_start_score", -10);
316 	com_neighbour_score[0] = contents.get_int("com_near_res", 1);
317 	com_neighbour_score[1] = contents.get_int("com_near_com", 8);
318 	com_neighbour_score[2] = contents.get_int("com_near_ind", 1);
319 
320 	res_start_score = contents.get_int("res_start_score", 0);
321 	res_neighbour_score[0] = contents.get_int("res_near_res",  8);
322 	res_neighbour_score[1] = contents.get_int("res_near_com",  0);
323 	res_neighbour_score[2] = contents.get_int("res_near_ind", -8);
324 
325 	uint32 num_house_rules = 0;
326 	for (;;) {
327 		sprintf(buf, "house_%d", num_house_rules + 1);
328 		if (contents.get_string(buf, 0)) {
329 			num_house_rules++;
330 		} else {
331 			break;
332 		}
333 	}
334 	DBG_MESSAGE("stadt_t::init()", "Read %d house building rules", num_house_rules);
335 
336 	uint32 num_road_rules = 0;
337 	for (;;) {
338 		sprintf(buf, "road_%d", num_road_rules + 1);
339 		if (contents.get_string(buf, 0)) {
340 			num_road_rules++;
341 		} else {
342 			break;
343 		}
344 	}
345 	DBG_MESSAGE("stadt_t::init()", "Read %d road building rules", num_road_rules);
346 
347 	clear_ptr_vector( house_rules );
348 	for (uint32 i = 0; i < num_house_rules; i++) {
349 		house_rules.append(new rule_t());
350 		sprintf(buf, "house_%d.chance", i + 1);
351 		house_rules[i]->chance = contents.get_int(buf, 0);
352 
353 		sprintf(buf, "house_%d", i + 1);
354 		const char* rule = contents.get_string(buf, "");
355 
356 		// skip leading spaces (use . for padding)
357 		while (*rule == ' ') {
358 			rule++;
359 		}
360 
361 		// find out rule size
362 		size_t size = 0;
363 		size_t maxlen = strlen(rule);
364 		while (size < maxlen  &&  rule[size]!=' ') {
365 			size++;
366 		}
367 
368 		if (size > 7  ||  maxlen < size * (size + 1) - 1  ||  (size & 1) == 0  ||  size <= 2 ) {
369 			dbg->fatal("stadt_t::cityrules_init()", "house rule %d has bad format!", i + 1);
370 		}
371 
372 		// put rule into memory
373 		const uint8 offset = (7 - (uint)size) / 2;
374 		for (uint y = 0; y < size; y++) {
375 			for (uint x = 0; x < size; x++) {
376 				const char flag = rule[x + y * (size + 1)];
377 				// check for allowed characters; ignore '.';
378 				// leave midpoint out, should be 'n', which is checked in build() anyway
379 				if ((x+offset!=3  ||  y+offset!=3)  &&  (flag!=0  &&  strchr(allowed_chars_in_rule, flag))) {
380 					house_rules[i]->rule.append(rule_entry_t(x+offset,y+offset,flag));
381 				}
382 				else {
383 					if ((x+offset!=3  ||  y+offset!=3)  &&  flag!='.') {
384 						dbg->warning("stadt_t::cityrules_init()", "house rule %d entry (%d,%d) is '%c' and will be ignored", i + 1, x+offset, y+offset, flag);
385 					}
386 				}
387 			}
388 		}
389 	}
390 
391 	clear_ptr_vector( road_rules );
392 	for (uint32 i = 0; i < num_road_rules; i++) {
393 		road_rules.append(new rule_t());
394 		sprintf(buf, "road_%d.chance", i + 1);
395 		road_rules[i]->chance = contents.get_int(buf, 0);
396 
397 		sprintf(buf, "road_%d", i + 1);
398 		const char* rule = contents.get_string(buf, "");
399 
400 		// skip leading spaces (use . for padding)
401 		while (*rule == ' ') {
402 			rule++;
403 		}
404 
405 		// find out rule size
406 		size_t size = 0;
407 		size_t maxlen = strlen(rule);
408 		while (size < maxlen && rule[size] != ' ') {
409 			size++;
410 		}
411 
412 		if (  size > 7  ||  maxlen < size * (size + 1) - 1  ||  (size & 1) == 0  ||  size <= 2  ) {
413 			dbg->fatal("stadt_t::cityrules_init()", "road rule %d has bad format!", i + 1);
414 		}
415 
416 		// put rule into memory
417 		const uint8 offset = (7 - (uint)size) / 2;
418 		for (uint y = 0; y < size; y++) {
419 			for (uint x = 0; x < size; x++) {
420 				const char flag = rule[x + y * (size + 1)];
421 				// check for allowed characters; ignore '.';
422 				// leave midpoint out, should be 'n', which is checked in build() anyway
423 				if ((x+offset!=3  ||  y+offset!=3)  &&  (flag!=0  &&  strchr(allowed_chars_in_rule, flag))) {
424 					road_rules[i]->rule.append(rule_entry_t(x+offset,y+offset,flag));
425 				}
426 				else {
427 					if ((x+offset!=3  ||  y+offset!=3)  &&  flag!='.') {
428 						dbg->warning("stadt_t::cityrules_init()", "road rule %d entry (%d,%d) is '%c' and will be ignored", i + 1, x+offset, y+offset, flag);
429 					}
430 				}
431 			}
432 		}
433 	}
434 	return true;
435 }
436 
437 /**
438 * Reads/writes city configuration data from/to a savegame
439 * called from karte_t::speichern and karte_t::laden
440 * only written for networkgames
441 * @author Dwachs
442 */
cityrules_rdwr(loadsave_t * file)443 void stadt_t::cityrules_rdwr(loadsave_t *file)
444 {
445 	if(  file->is_version_atleast(112, 8)  ) {
446 		file->rdwr_long( cluster_factor );
447 	}
448 
449 	file->rdwr_long(renovation_percentage);
450 	file->rdwr_long(min_building_density);
451 
452 	file->rdwr_short(ind_start_score);
453 	file->rdwr_short(ind_neighbour_score[0]);
454 	file->rdwr_short(ind_neighbour_score[1]);
455 	file->rdwr_short(ind_neighbour_score[2]);
456 
457 	file->rdwr_short(com_start_score);
458 	file->rdwr_short(com_neighbour_score[0]);
459 	file->rdwr_short(com_neighbour_score[1]);
460 	file->rdwr_short(com_neighbour_score[2]);
461 
462 	file->rdwr_short(res_start_score);
463 	file->rdwr_short(res_neighbour_score[0]);
464 	file->rdwr_short(res_neighbour_score[1]);
465 	file->rdwr_short(res_neighbour_score[2]);
466 
467 	// house rules
468 	if (file->is_loading()) {
469 		clear_ptr_vector( house_rules );
470 	}
471 	uint32 count = house_rules.get_count();
472 	file->rdwr_long(count);
473 	for(uint32 i=0; i<count; i++) {
474 		if (file->is_loading()) {
475 			house_rules.append(new rule_t());
476 		}
477 		house_rules[i]->rdwr(file);
478 	}
479 	// road rules
480 	if (file->is_loading()) {
481 		clear_ptr_vector( road_rules );
482 	}
483 	count = road_rules.get_count();
484 	file->rdwr_long(count);
485 	for(uint32 i=0; i<count; i++) {
486 		if (file->is_loading()) {
487 			road_rules.append(new rule_t());
488 		}
489 		road_rules[i]->rdwr(file);
490 	}
491 }
492 
493 /**
494  * monument_placefinder_t:
495  *
496  * Search a free place for a monument building
497  * Im Gegensatz zum building_placefinder_t werden Strassen auf den Raendern
498  * toleriert.
499  *
500  * 22-Dec-02: Hajo: added safety checks for gr != 0 and plan != 0
501  *
502  * @author V. Meyer
503  */
504 class monument_placefinder_t : public placefinder_t {
505 	public:
monument_placefinder_t(karte_t * welt,sint16 radius)506 		monument_placefinder_t(karte_t* welt, sint16 radius) : placefinder_t(welt, radius) {}
507 
is_tile_ok(koord pos,koord d,climate_bits cl) const508 		bool is_tile_ok(koord pos, koord d, climate_bits cl) const OVERRIDE
509 		{
510 			const planquadrat_t* plan = welt->access(pos + d);
511 
512 			// Hajo: can't build here
513 			if (plan == NULL) {
514 				return false;
515 			}
516 
517 			const grund_t* gr = plan->get_kartenboden();
518 			if(  ((1 << welt->get_climate( gr->get_pos().get_2d() )) & cl) == 0  ) {
519 				return false;
520 			}
521 
522 			if (is_boundary_tile(d)) {
523 				return
524 					gr->get_grund_hang() == slope_t::flat &&     // Flat
525 					gr->get_typ() == grund_t::boden &&           // Boden -> no building
526 					(!gr->hat_wege() || gr->hat_weg(road_wt)) && // only roads
527 					gr->kann_alle_obj_entfernen(NULL) == NULL;   // Irgendwas verbaut den Platz?
528 			}
529 			else {
530 				return
531 					gr->get_grund_hang() == slope_t::flat &&
532 					gr->get_typ() == grund_t::boden &&
533 					gr->ist_natur() &&                         // No way here
534 					gr->kann_alle_obj_entfernen(NULL) == NULL; // Irgendwas verbaut den Platz?
535 			}
536 		}
537 };
538 
539 
540 /**
541  * townhall_placefinder_t:
542  *
543  * 22-Dec-02: Hajo: added safety checks for gr != 0 and plan != 0
544  *
545  * @author V. Meyer
546  */
547 class townhall_placefinder_t : public placefinder_t {
548 	public:
townhall_placefinder_t(karte_t * welt,uint8 dir_)549 		townhall_placefinder_t(karte_t* welt, uint8 dir_) : placefinder_t(welt), dir(dir_) {}
550 
is_tile_ok(koord pos,koord d,climate_bits cl) const551 		bool is_tile_ok(koord pos, koord d, climate_bits cl) const OVERRIDE
552 		{
553 			const grund_t* gr = welt->lookup_kartenboden(pos + d);
554 			if (gr == NULL  ||  gr->get_grund_hang() != slope_t::flat) {
555 				return false;
556 			}
557 
558 			if(  ((1 << welt->get_climate( gr->get_pos().get_2d() )) & cl) == 0  ) {
559 				return false;
560 			}
561 
562 			if (d.x > 0 || d.y > 0) {
563 				if (welt->lookup_kartenboden(pos)->get_hoehe() != gr->get_hoehe()) {
564 					// height wrong!
565 					return false;
566 				}
567 			}
568 
569 			if ( ((dir & ribi_t::south)!=0  &&  d.y == h - 1) ||
570 				((dir & ribi_t::west)!=0  &&  d.x == 0) ||
571 				((dir & ribi_t::north)!=0  &&  d.y == 0) ||
572 				((dir & ribi_t::east)!=0  &&  d.x == w - 1)) {
573 				// we want to build a road here:
574 				return
575 					gr->get_typ() == grund_t::boden &&
576 					(!gr->hat_wege() || (gr->hat_weg(road_wt) && !gr->has_two_ways())) && // build only on roads, no other ways
577 					!gr->is_halt() &&
578 					gr->kann_alle_obj_entfernen(NULL) == NULL;
579 			} else {
580 				// we want to build the townhall here: maybe replace existing buildings
581 				return ((gr->get_typ()==grund_t::boden  &&  gr->ist_natur()) ||	gr->get_typ()==grund_t::fundament) &&
582 					gr->kann_alle_obj_entfernen(NULL) == NULL;
583 			}
584 		}
585 private:
586 	uint8 dir;
587 };
588 
589 
compare_gebaeude_pos(const gebaeude_t * a,const gebaeude_t * b)590 static bool compare_gebaeude_pos(const gebaeude_t* a, const gebaeude_t* b)
591 {
592 	const uint32 pos_a = (a->get_pos().y<<16)+a->get_pos().x;
593 	const uint32 pos_b = (b->get_pos().y<<16)+b->get_pos().x;
594 	return pos_a<pos_b;
595 }
596 
597 
598 // this function adds houses to the city house list
add_gebaeude_to_stadt(const gebaeude_t * gb,bool ordered)599 void stadt_t::add_gebaeude_to_stadt(const gebaeude_t* gb, bool ordered)
600 {
601 	if (gb != NULL) {
602 		const building_tile_desc_t* tile  = gb->get_tile();
603 		koord size = tile->get_desc()->get_size(tile->get_layout());
604 		const koord pos = gb->get_pos().get_2d() - tile->get_offset();
605 		koord k;
606 
607 		// add all tiles
608 		for (k.y = 0; k.y < size.y; k.y++) {
609 			for (k.x = 0; k.x < size.x; k.x++) {
610 				if (gebaeude_t* const add_gb = obj_cast<gebaeude_t>(welt->lookup_kartenboden(pos + k)->first_obj())) {
611 					if (gb->is_same_building(add_gb)) {
612 
613 						if(  ordered  ) {
614 							buildings.insert_ordered(add_gb, tile->get_desc()->get_level() + 1, compare_gebaeude_pos);
615 						}
616 						else {
617 							buildings.append(add_gb, tile->get_desc()->get_level() + 1);
618 						}
619 
620 						add_gb->set_stadt(this);
621 						if (add_gb->get_tile()->get_desc()->is_townhall()) {
622 							has_townhall = true;
623 						}
624 					}
625 					else {
626 						// found tile of another building, ignore it
627 					}
628 				}
629 			}
630 		}
631 		// no update of city limits
632 		// as has_low_density may depend on the order the buildings list is filled
633 		if (!ordered) {
634 			// check borders
635 			pruefe_grenzen(pos);
636 			if(size!=koord(1,1)) {
637 				pruefe_grenzen(pos+size-koord(1,1));
638 			}
639 		}
640 	}
641 }
642 
643 
644 // this function removes houses from the city house list
remove_gebaeude_from_stadt(gebaeude_t * gb)645 void stadt_t::remove_gebaeude_from_stadt(gebaeude_t* gb)
646 {
647 	buildings.remove(gb);
648 	gb->set_stadt(NULL);
649 	recalc_city_size();
650 }
651 
652 
653 // just updates the weight count of this building (after a renovation)
update_gebaeude_from_stadt(gebaeude_t * gb)654 void stadt_t::update_gebaeude_from_stadt(gebaeude_t* gb)
655 {
656 	buildings.remove(gb);
657 	buildings.append(gb, gb->get_tile()->get_desc()->get_level() + 1);
658 }
659 
660 
pruefe_grenzen(koord k)661 void stadt_t::pruefe_grenzen(koord k)
662 {
663 	// WARNING: do not call this during multithreaded loading,
664 	// as has_low_density may depend on the order the buildings list is filled
665 	if(  has_low_density  ) {
666 		// has extra wide borders => change density calculation
667 		has_low_density = (buildings.get_count()<10  ||  (buildings.get_count()*100l)/(abs(ur.x-lo.x-4)*abs(ur.y-lo.y-4)+1) > min_building_density);
668 		if(!has_low_density)  {
669 			// full recalc needed due to map borders ...
670 			recalc_city_size();
671 			return;
672 		}
673 	}
674 	else {
675 		has_low_density = (buildings.get_count()<10  ||  (buildings.get_count()*100l)/((ur.x-lo.x)*(ur.y-lo.y)+1) > min_building_density);
676 		if(has_low_density)  {
677 			// wide borders again ..
678 			lo -= koord(2,2);
679 			ur += koord(2,2);
680 		}
681 	}
682 	// now just add single coordinates
683 	if(  has_low_density  ) {
684 		lo.clip_max(k-koord(2,2));
685 		ur.clip_min(k+koord(2,2));
686 	}
687 	else {
688 		// first grow within ...
689 		lo.clip_max(k);
690 		ur.clip_min(k);
691 	}
692 
693 	lo.clip_min(koord(0,0));
694 	ur.clip_max(koord(welt->get_size().x-1,welt->get_size().y-1));
695 }
696 
697 
698 // recalculate the spreading of a city
699 // will be updated also after house deletion
recalc_city_size()700 void stadt_t::recalc_city_size()
701 {
702 	// WARNING: do not call this during multithreaded loading,
703 	// as has_low_density may depend on the order the buildings list is filled
704 	lo = pos;
705 	ur = pos;
706 	FOR(weighted_vector_tpl<gebaeude_t*>, const i, buildings) {
707 		if (i->get_tile()->get_desc()->get_type() != building_desc_t::headquarters) {
708 			koord const& gb_pos = i->get_pos().get_2d();
709 			lo.clip_max(gb_pos);
710 			ur.clip_min(gb_pos);
711 		}
712 	}
713 
714 	has_low_density = (buildings.get_count()<10  ||  (buildings.get_count()*100l)/((ur.x-lo.x)*(ur.y-lo.y)+1) > min_building_density);
715 	if(  has_low_density  ) {
716 		// wider borders for faster growth of sparse small towns
717 		lo -= koord(2,2);
718 		ur += koord(2,2);
719 	}
720 
721 	lo.clip_min(koord(0,0));
722 	ur.clip_max(koord(welt->get_size().x-1,welt->get_size().y-1));
723 }
724 
725 
init_pax_destinations()726 void stadt_t::init_pax_destinations()
727 {
728 	pax_destinations_old.clear();
729 	pax_destinations_new.clear();
730 	pax_destinations_new_change = 0;
731 }
732 
733 
rdwr(loadsave_t * file)734 void stadt_t::factory_entry_t::rdwr(loadsave_t *file)
735 {
736 	if(  file->is_version_atleast(110, 5)  ) {
737 		koord factory_pos;
738 		if(  file->is_saving()  ) {
739 			factory_pos = factory->get_pos().get_2d();
740 		}
741 		factory_pos.rdwr( file );
742 		if(  file->is_loading()  ) {
743 			// position will be resolved back into fabrik_t* later
744 			factory_pos_x = factory_pos.x;
745 			factory_pos_y = factory_pos.y;
746 		}
747 		file->rdwr_long( demand );
748 		file->rdwr_long( supply );
749 		file->rdwr_long( remaining );
750 	}
751 }
752 
753 
resolve_factory()754 void stadt_t::factory_entry_t::resolve_factory()
755 {
756 	factory = fabrik_t::get_fab( koord(factory_pos_x, factory_pos_y) );
757 }
758 
759 
get_entry(const fabrik_t * const factory) const760 const stadt_t::factory_entry_t* stadt_t::factory_set_t::get_entry(const fabrik_t *const factory) const
761 {
762 	FOR(vector_tpl<factory_entry_t>, const& e, entries) {
763 		if (e.factory == factory) {
764 			return &e;
765 		}
766 	}
767 	return NULL;	// not found
768 }
769 
770 
get_random_entry()771 stadt_t::factory_entry_t* stadt_t::factory_set_t::get_random_entry()
772 {
773 	if(  total_remaining>0  ) {
774 		sint32 weight = simrand(total_remaining);
775 		FOR(vector_tpl<factory_entry_t>, & entry, entries) {
776 			if(  entry.remaining>0  ) {
777 				if(  weight<entry.remaining  ) {
778 					return &entry;
779 				}
780 				weight -= entry.remaining;
781 			}
782 		}
783 	}
784 	return NULL;
785 }
786 
787 
update_factory(fabrik_t * const factory,const sint32 demand)788 void stadt_t::factory_set_t::update_factory(fabrik_t *const factory, const sint32 demand)
789 {
790 	if(  entries.is_contained( factory_entry_t(factory) )  ) {
791 		// existing target factory
792 		factory_entry_t &entry = entries[ entries.index_of( factory_entry_t(factory) ) ];
793 		total_demand += demand - entry.demand;
794 		entry.demand = demand;
795 		// entry.supply, entry.remaining and total_remaining will be adjusted in recalc_generation_ratio()
796 	}
797 	else {
798 		// new target factory
799 		entries.append( factory_entry_t(factory, demand) );
800 		total_demand += demand;
801 	}
802 	ratio_stale = true;		// always trigger recalculation of ratio
803 }
804 
805 
remove_factory(fabrik_t * const factory)806 void stadt_t::factory_set_t::remove_factory(fabrik_t *const factory)
807 {
808 	if(  entries.is_contained( factory_entry_t(factory) )  ) {
809 		factory_entry_t &entry = entries[ entries.index_of( factory_entry_t(factory) ) ];
810 		total_demand -= entry.demand;
811 		total_remaining -= entry.remaining;
812 		entries.remove( entry );
813 		ratio_stale = true;
814 	}
815 }
816 
817 
818 #define SUPPLY_BITS   (3)
819 #define SUPPLY_FACTOR (9)	// out of 2^SUPPLY_BITS
recalc_generation_ratio(const sint32 default_percent,const sint64 * city_stats,const int stats_count,const int stat_type)820 void stadt_t::factory_set_t::recalc_generation_ratio(const sint32 default_percent, const sint64 *city_stats, const int stats_count, const int stat_type)
821 {
822 	ratio_stale = false;		// reset flag
823 
824 	// calculate an average of at most 3 previous months' pax/mail generation amounts
825 	uint32 months = 0;
826 	sint64 average_generated = 0;
827 	sint64 month_generated;
828 	while(  months<3  &&  (month_generated=city_stats[(months+1)*stats_count+stat_type])>0  ) {
829 		average_generated += month_generated;
830 		++months;
831 	}
832 	if(  months>1  ) {
833 		average_generated /= months;
834 	}
835 
836 	/* ratio formula -> ((supply * 100) / total) shifted by RATIO_BITS */
837 	// we supply 1/8 more than demand
838 	const sint32 target_supply = (total_demand * SUPPLY_FACTOR + ((1<<(DEMAND_BITS+SUPPLY_BITS))-1)) >> (DEMAND_BITS+SUPPLY_BITS);
839 	if(  total_demand==0  ) {
840 		// no demand -> zero ratio
841 		generation_ratio = 0;
842 	}
843 	else if(  !welt->get_settings().get_factory_enforce_demand()  ||  average_generated == 0  ) {
844 		// demand not enforced or no pax generation data from previous month(s) -> simply use default ratio
845 		generation_ratio = (uint32)default_percent << RATIO_BITS;
846 	}
847 	else {
848 		// ratio of target supply (plus allowances for rounding up) to previous months' average generated pax (less 6.25% or 1/16 allowance for fluctuation), capped by default ratio
849 		const sint64 default_ratio = (sint64)default_percent << RATIO_BITS;
850 		const sint64 supply_ratio = ((sint64)((target_supply+(sint32)entries.get_count())*100)<<RATIO_BITS) / (average_generated-(average_generated>>4)+1);
851 		generation_ratio = (uint32)( default_ratio<supply_ratio ? default_ratio : supply_ratio );
852 	}
853 
854 	// adjust supply and remaining figures
855 	if(  welt->get_settings().get_factory_enforce_demand()  &&  (generation_ratio >> RATIO_BITS) == (uint32)default_percent && average_generated > 0 && total_demand > 0  ) {
856 		const sint64 supply_promille = ( ( (average_generated << 10) * (sint64)default_percent ) / 100 ) / (sint64)target_supply;
857 		if(  supply_promille < 1024  ) {
858 			// expected supply is really smaller than target supply
859 			FOR(vector_tpl<factory_entry_t>, & entry, entries) {
860 				const sint32 new_supply = (sint32)( ( (sint64)entry.demand * SUPPLY_FACTOR * supply_promille + ((1<<(DEMAND_BITS+SUPPLY_BITS+10))-1) ) >> (DEMAND_BITS+SUPPLY_BITS+10) );
861 				const sint32 delta_supply = new_supply - entry.supply;
862 				if(  delta_supply==0  ) {
863 					continue;
864 				}
865 				else if(  delta_supply>0  ||  (entry.remaining+delta_supply)>=0  ) {
866 					// adjust remaining figures by the change in supply
867 					total_remaining += delta_supply;
868 					entry.remaining += delta_supply;
869 				}
870 				else {
871 					// avoid deducting more than allowed
872 					total_remaining -= entry.remaining;
873 					entry.remaining = 0;
874 				}
875 				entry.supply = new_supply;
876 			}
877 			return;
878 		}
879 	}
880 	// expected supply is unknown or sufficient to meet target supply
881 	FOR(vector_tpl<factory_entry_t>, & entry, entries) {
882 		const sint32 new_supply = ( entry.demand * SUPPLY_FACTOR + ((1<<(DEMAND_BITS+SUPPLY_BITS))-1) ) >> (DEMAND_BITS+SUPPLY_BITS);
883 		const sint32 delta_supply = new_supply - entry.supply;
884 		if(  delta_supply==0  ) {
885 			continue;
886 		}
887 		else if(  delta_supply>0  ||  (entry.remaining+delta_supply)>=0  ) {
888 			// adjust remaining figures by the change in supply
889 			total_remaining += delta_supply;
890 			entry.remaining += delta_supply;
891 		}
892 		else {
893 			// avoid deducting more than allowed
894 			total_remaining -= entry.remaining;
895 			entry.remaining = 0;
896 		}
897 		entry.supply = new_supply;
898 	}
899 }
900 
901 
new_month()902 void stadt_t::factory_set_t::new_month()
903 {
904 	FOR(vector_tpl<factory_entry_t>, & e, entries) {
905 		e.new_month();
906 	}
907 	total_remaining = 0;
908 	total_generated = 0;
909 	ratio_stale = true;
910 }
911 
912 
rdwr(loadsave_t * file)913 void stadt_t::factory_set_t::rdwr(loadsave_t *file)
914 {
915 	if(  file->is_version_atleast(110, 5)  ) {
916 		uint32 entry_count = entries.get_count();
917 		file->rdwr_long(entry_count);
918 		if(  file->is_loading()  ) {
919 			entries.resize( entry_count );
920 			factory_entry_t entry;
921 			for(  uint32 e=0;  e<entry_count;  ++e  ) {
922 				entry.rdwr( file );
923 				total_demand += entry.demand;
924 				total_remaining += entry.remaining;
925 				entries.append( entry );
926 			}
927 		}
928 		else {
929 			for(  uint32 e=0;  e<entry_count;  ++e  ) {
930 				entries[e].rdwr( file );
931 			}
932 		}
933 		file->rdwr_long( total_generated );
934 	}
935 }
936 
937 
resolve_factories()938 void stadt_t::factory_set_t::resolve_factories()
939 {
940 	uint32 remove_count = 0;
941 	FOR(vector_tpl<factory_entry_t>, & e, entries) {
942 		e.resolve_factory();
943 		if (!e.factory) {
944 			remove_count ++;
945 		}
946 	}
947 	for(  uint32 e=0;  e<remove_count;  ++e  ) {
948 		this->remove_factory( NULL );
949 	}
950 }
951 
952 
~stadt_t()953 stadt_t::~stadt_t()
954 {
955 	// close info win
956 	destroy_win((ptrdiff_t)this);
957 
958 	if(  minimap_t::get_instance()->is_city_selected(this)  ) {
959 		minimap_t::get_instance()->set_selected_city(NULL);
960 	}
961 
962 	// only if there is still a world left to delete from
963 	if( welt->get_size().x > 1 ) {
964 
965 		welt->lookup_kartenboden(pos)->set_text(NULL);
966 
967 		if (!welt->is_destroying()) {
968 			// remove city info and houses
969 			while (!buildings.empty()) {
970 
971 				gebaeude_t* const gb = buildings.pop_back();
972 				assert(  gb!=NULL  &&  !buildings.is_contained(gb)  );
973 
974 				if(gb->get_tile()->get_desc()->get_type()==building_desc_t::headquarters) {
975 					stadt_t *city = welt->find_nearest_city(gb->get_pos().get_2d());
976 					gb->set_stadt( city );
977 					if(city) {
978 						city->buildings.append(gb, gb->get_passagier_level());
979 					}
980 				}
981 				else {
982 					gb->set_stadt( NULL );
983 					hausbauer_t::remove(welt->get_public_player(),gb);
984 				}
985 			}
986 			// avoid the bookkeeping if world gets destroyed
987 		}
988 	}
989 }
990 
991 
name_used(weighted_vector_tpl<stadt_t * > const & cities,char const * const name)992 static bool name_used(weighted_vector_tpl<stadt_t*> const& cities, char const* const name)
993 {
994 	FOR(weighted_vector_tpl<stadt_t*>, const i, cities) {
995 		if (strcmp(i->get_name(), name) == 0) {
996 			return true;
997 		}
998 	}
999 	return false;
1000 }
1001 
1002 
stadt_t(player_t * player,koord pos,sint32 citizens)1003 stadt_t::stadt_t(player_t* player, koord pos, sint32 citizens) :
1004 	buildings(16),
1005 	pax_destinations_old(koord(PAX_DESTINATIONS_SIZE, PAX_DESTINATIONS_SIZE)),
1006 	pax_destinations_new(koord(PAX_DESTINATIONS_SIZE, PAX_DESTINATIONS_SIZE))
1007 {
1008 	assert(welt->is_within_limits(pos));
1009 
1010 	step_count = 0;
1011 	pax_destinations_new_change = 0;
1012 	next_step = 0;
1013 	step_interval = 1;
1014 	next_growth_step = 0;
1015 	has_low_density = false;
1016 	has_townhall = false;
1017 
1018 	stadtinfo_options = 3;	// citizen and growth
1019 
1020 	owner = player;
1021 
1022 	this->pos = pos;
1023 	last_center = koord::invalid;
1024 
1025 	bev = 0;
1026 	arb = 0;
1027 	won = 0;
1028 
1029 	lo = ur = pos;
1030 
1031 	/* get a unique cityname */
1032 	char                          const* n       = "simcity";
1033 	weighted_vector_tpl<stadt_t*> const& staedte = welt->get_cities();
1034 
1035 	const vector_tpl<char*>& city_names = translator::get_city_name_list();
1036 
1037 	// make sure we do only ONE random call regardless of how many names are available (to avoid desyncs in network games)
1038 	if(  const uint32 count = city_names.get_count()  ) {
1039 		uint32 idx = simrand( count );
1040 		static const uint32 some_primes[] = { 19, 31, 109, 199, 409, 571, 631, 829, 1489, 1999, 2341, 2971, 3529, 4621, 4789, 7039, 7669, 8779, 9721 };
1041 		// find prime that does not divide count
1042 		uint32 offset = 1;
1043 		for(  uint8 i=0;  i < lengthof(some_primes);  i++  ) {
1044 			if(  count % some_primes[i] != 0  ) {
1045 				offset = some_primes[i];
1046 				break;
1047 			}
1048 		}
1049 		// as count % offset != 0 we are guaranteed to test all city names
1050 		for(uint32 i=0; i<count; i++) {
1051 			char const* const cand = city_names[idx];
1052 			if(  !name_used(staedte, cand)  ) {
1053 				n = cand;
1054 				break;
1055 			}
1056 			idx = (idx+offset) % count;
1057 		}
1058 	}
1059 	else {
1060 		/* the one random call to avoid desyncs */
1061 		simrand(5);
1062 	}
1063 	DBG_MESSAGE("stadt_t::stadt_t()", "founding new city named '%s'", n);
1064 	name = n;
1065 	has_townhall = false;
1066 
1067 	// 1. Rathaus bei 0 Leuten bauen
1068 	check_bau_townhall(true);
1069 
1070 	unsupplied_city_growth = 0;
1071 	allow_citygrowth = true;
1072 
1073 	// only build any houses if townhall is already there
1074 	// city should be deleted if it has no buildings
1075 	if (!buildings.empty()) {
1076 		change_size( citizens, true );
1077 	}
1078 
1079 	// fill with start citizen ...
1080 	sint64 bew = get_einwohner();
1081 	for (uint year = 0; year < MAX_CITY_HISTORY_YEARS; year++) {
1082 		city_history_year[year][HIST_CITICENS] = bew;
1083 	}
1084 	for (uint month = 0; month < MAX_CITY_HISTORY_MONTHS; month++) {
1085 		city_history_month[month][HIST_CITICENS] = bew;
1086 	}
1087 
1088 	// initialize history array
1089 	for (uint year = 0; year < MAX_CITY_HISTORY_YEARS; year++) {
1090 		for (uint hist_type = 1; hist_type < MAX_CITY_HISTORY; hist_type++) {
1091 			city_history_year[year][hist_type] = 0;
1092 		}
1093 	}
1094 	for (uint month = 0; month < MAX_CITY_HISTORY_YEARS; month++) {
1095 		for (uint hist_type = 1; hist_type < MAX_CITY_HISTORY; hist_type++) {
1096 			city_history_month[month][hist_type] = 0;
1097 		}
1098 	}
1099 	city_history_year[0][HIST_CITICENS]  = get_einwohner();
1100 	city_history_month[0][HIST_CITICENS] = get_einwohner();
1101 #ifdef DESTINATION_CITYCARS
1102 	number_of_cars = 0;
1103 #endif
1104 }
1105 
1106 
stadt_t(loadsave_t * file)1107 stadt_t::stadt_t(loadsave_t* file) :
1108 	buildings(16),
1109 	pax_destinations_old(koord(PAX_DESTINATIONS_SIZE, PAX_DESTINATIONS_SIZE)),
1110 	pax_destinations_new(koord(PAX_DESTINATIONS_SIZE, PAX_DESTINATIONS_SIZE))
1111 {
1112 	step_count = 0;
1113 	next_step = 0;
1114 	step_interval = 1;
1115 	next_growth_step = 0;
1116 	has_low_density = false;
1117 	has_townhall = false;
1118 
1119 	unsupplied_city_growth = 0;
1120 	stadtinfo_options = 3;
1121 
1122 	rdwr(file);
1123 }
1124 
1125 
rdwr(loadsave_t * file)1126 void stadt_t::rdwr(loadsave_t* file)
1127 {
1128 	sint32 owner_n;
1129 
1130 	if (file->is_saving()) {
1131 		owner_n = welt->sp2num(owner);
1132 	}
1133 	file->rdwr_str(name);
1134 	pos.rdwr(file);
1135 	uint32 lli = lo.x;
1136 	uint32 lob = lo.y;
1137 	uint32 lre = ur.x;
1138 	uint32 lun = ur.y;
1139 	file->rdwr_long(lli);
1140 	file->rdwr_long(lob);
1141 	file->rdwr_long(lre);
1142 	file->rdwr_long(lun);
1143 	lo.x = lli;
1144 	lo.y = lob;
1145 	ur.x = lre;
1146 	ur.y = lun;
1147 	file->rdwr_long(owner_n);
1148 	file->rdwr_long(bev);
1149 	file->rdwr_long(arb);
1150 	file->rdwr_long(won);
1151 
1152 	if(  file->is_version_atleast(112, 9)  ) {
1153 		// Must record the partial (less than 1 citizen) growth factor
1154 		// Otherwise we will get network desyncs
1155 		// Also allows accumulation of small growth factors
1156 		file->rdwr_longlong(unsupplied_city_growth);
1157 	}
1158 	else if( file->is_loading()  ) {
1159 		unsupplied_city_growth = 0;
1160 	}
1161 	// old values zentrum_namen_cnt : aussen_namen_cnt
1162 	if(file->is_version_less(99, 18)) {
1163 		sint32 dummy=0;
1164 		file->rdwr_long(dummy);
1165 		file->rdwr_long(dummy);
1166 	}
1167 
1168 	if (file->is_loading()) {
1169 		owner = welt->get_player(owner_n);
1170 	}
1171 
1172 	if(file->is_loading()) {
1173 		// initialize history array
1174 		for (uint year = 0; year < MAX_CITY_HISTORY_YEARS; year++) {
1175 			for (uint hist_type = 0; hist_type < MAX_CITY_HISTORY; hist_type++) {
1176 				city_history_year[year][hist_type] = 0;
1177 			}
1178 		}
1179 		for (uint month = 0; month < MAX_CITY_HISTORY_MONTHS; month++) {
1180 			for (uint hist_type = 0; hist_type < MAX_CITY_HISTORY; hist_type++) {
1181 				city_history_month[month][hist_type] = 0;
1182 			}
1183 		}
1184 		city_history_year[0][HIST_CITICENS] = get_einwohner();
1185 		city_history_year[0][HIST_CITICENS] = get_einwohner();
1186 	}
1187 
1188 	// we probably need to load/save the city history
1189 	if (file->is_version_less(86, 0)) {
1190 		DBG_DEBUG("stadt_t::rdwr()", "is old version: No history!");
1191 	} else if(file->is_version_less(99, 16)) {
1192 		// 86.00.0 introduced city history
1193 		for (uint year = 0; year < MAX_CITY_HISTORY_YEARS; year++) {
1194 			for (uint hist_type = 0; hist_type < 2; hist_type++) {
1195 				file->rdwr_longlong(city_history_year[year][hist_type]);
1196 			}
1197 			for (uint hist_type = 4; hist_type < 6; hist_type++) {
1198 				file->rdwr_longlong(city_history_year[year][hist_type]);
1199 			}
1200 		}
1201 		for (uint month = 0; month < MAX_CITY_HISTORY_MONTHS; month++) {
1202 			for (uint hist_type = 0; hist_type < 2; hist_type++) {
1203 				file->rdwr_longlong(city_history_month[month][hist_type]);
1204 			}
1205 			for (uint hist_type = 4; hist_type < 6; hist_type++) {
1206 				file->rdwr_longlong(city_history_month[month][hist_type]);
1207 			}
1208 		}
1209 		// not needed any more
1210 		sint32 dummy = 0;
1211 		file->rdwr_long(dummy);
1212 		file->rdwr_long(dummy);
1213 		file->rdwr_long(dummy);
1214 		file->rdwr_long(dummy);
1215 	}
1216 	else if(  file->is_version_less(120, 1)  ) {
1217 		// 99.17.0 extended city history
1218 		for (uint year = 0; year < MAX_CITY_HISTORY_YEARS; year++) {
1219 			for (uint hist_type = 0; hist_type < MAX_CITY_HISTORY; hist_type++) {
1220 				if(  hist_type==HIST_PAS_WALKED  ||  hist_type==HIST_MAIL_WALKED  ) {
1221 					continue;
1222 				}
1223 				file->rdwr_longlong(city_history_year[year][hist_type]);
1224 			}
1225 		}
1226 		for (uint month = 0; month < MAX_CITY_HISTORY_MONTHS; month++) {
1227 			for (uint hist_type = 0; hist_type < MAX_CITY_HISTORY; hist_type++) {
1228 				if(  hist_type==HIST_PAS_WALKED  ||  hist_type==HIST_MAIL_WALKED  ) {
1229 					continue;
1230 				}
1231 				file->rdwr_longlong(city_history_month[month][hist_type]);
1232 			}
1233 		}
1234 		// save button settings for this town
1235 		file->rdwr_long( stadtinfo_options);
1236 	}
1237 	else {
1238 		// 120,001 with walking (direct connections) recored seperately
1239 		for (uint year = 0; year < MAX_CITY_HISTORY_YEARS; year++) {
1240 			for (uint hist_type = 0; hist_type < MAX_CITY_HISTORY; hist_type++) {
1241 				file->rdwr_longlong(city_history_year[year][hist_type]);
1242 			}
1243 		}
1244 		for (uint month = 0; month < MAX_CITY_HISTORY_MONTHS; month++) {
1245 			for (uint hist_type = 0; hist_type < MAX_CITY_HISTORY; hist_type++) {
1246 				file->rdwr_longlong(city_history_month[month][hist_type]);
1247 			}
1248 		}
1249 		// save button settings for this town
1250 		file->rdwr_long( stadtinfo_options);
1251 	}
1252 
1253 	// differential history
1254 	if (  file->is_version_less(120, 1)  ) {
1255 		if (  file->is_loading()  ) {
1256 			// Initalize differential statistics assuming a differential of 0.
1257 			city_growth_get_factors(city_growth_factor_previous, 0);
1258 		}
1259 	}
1260 	else {
1261 		// load/save differential statistics.
1262 		for (uint32 i = 0; i < GROWTH_FACTOR_NUMBER; i++) {
1263 			file->rdwr_longlong(city_growth_factor_previous[i].demand);
1264 			file->rdwr_longlong(city_growth_factor_previous[i].supplied);
1265 		}
1266 	}
1267 
1268 	if(file->is_version_atleast(99, 15)  &&  file->is_version_less(99, 16)) {
1269 		sint32 dummy = 0;
1270 		file->rdwr_long(dummy);
1271 		file->rdwr_long(dummy);
1272 	}
1273 
1274 	// since 102.2 there are static cities
1275 	if(file->is_version_atleast(102, 2)) {
1276 		file->rdwr_bool(allow_citygrowth);
1277 	}
1278 	else if(  file->is_loading()  ) {
1279 		allow_citygrowth = true;
1280 	}
1281 	// save townhall road position
1282 	if(file->is_version_atleast(102, 3)) {
1283 		townhall_road.rdwr(file);
1284 	}
1285 	else if(  file->is_loading()  ) {
1286 		townhall_road = koord::invalid;
1287 	}
1288 
1289 	// data related to target factories
1290 	target_factories_pax.rdwr( file );
1291 	target_factories_mail.rdwr( file );
1292 
1293 	if(file->is_loading()) {
1294 		// 08-Jan-03: Due to some bugs in the special buildings/town hall
1295 		// placement code, li,re,ob,un could've gotten irregular values
1296 		// If a game is loaded, the game might suffer from such an mistake
1297 		// and we need to correct it here.
1298 		DBG_MESSAGE("stadt_t::rdwr()", "borders (%i,%i) -> (%i,%i)", lo.x, lo.y, ur.x, ur.y);
1299 
1300 		// recalculate borders
1301 		recalc_city_size();
1302 	}
1303 }
1304 
1305 
finish_rd()1306 void stadt_t::finish_rd()
1307 {
1308 	step_count = 0;
1309 	next_step = 0;
1310 	next_growth_step = 0;
1311 
1312 	// there might be broken savegames
1313 	if (!name) {
1314 		set_name( "simcity" );
1315 	}
1316 
1317 	if (!has_townhall) {
1318 		dbg->warning("stadt_t::finish_rd()", "City %s has no valid townhall after loading the savegame, try to build a new one.", get_name());
1319 		check_bau_townhall(true);
1320 	}
1321 	// new city => need to grow
1322 	if (buildings.empty()) {
1323 		step_grow_city(true);
1324 	}
1325 
1326 	// clear the minimaps
1327 	init_pax_destinations();
1328 
1329 	// init step counter with meaningful value
1330 	step_interval = (2 << 18u) / (buildings.get_count() * 4 + 1);
1331 	if (step_interval < 1) {
1332 		step_interval = 1;
1333 	}
1334 
1335 	if(townhall_road==koord::invalid) {
1336 		// guess road tile based on current orientation
1337 		gebaeude_t const* const gb = obj_cast<gebaeude_t>(welt->lookup_kartenboden(pos)->first_obj());
1338 		if(  gb  &&  gb->is_townhall()  ) {
1339 			koord k(gb->get_tile()->get_desc()->get_size(gb->get_tile()->get_layout()));
1340 			switch (gb->get_tile()->get_layout()) {
1341 				default:
1342 				case 0:
1343 					townhall_road = pos + koord(0, k.y);
1344 					break;
1345 				case 1:
1346 					townhall_road = pos + koord(k.x, 0);
1347 					break;
1348 				case 2:
1349 					townhall_road = pos + koord(0, -1);
1350 					break;
1351 				case 3:
1352 					townhall_road = pos + koord(-1, 0);
1353 					break;
1354 			}
1355 		}
1356 	}
1357 	recalc_city_size();
1358 
1359 	next_step = 0;
1360 	next_growth_step = 0;
1361 
1362 	// resolve target factories
1363 	target_factories_pax.resolve_factories();
1364 	target_factories_mail.resolve_factories();
1365 }
1366 
1367 
rotate90(const sint16 y_size)1368 void stadt_t::rotate90( const sint16 y_size )
1369 {
1370 	// rotate town origin
1371 	pos.rotate90( y_size );
1372 	townhall_road.rotate90( y_size );
1373 	// rotate an rectangle
1374 	lo.rotate90( y_size );
1375 	ur.rotate90( y_size );
1376 	sint16 lox = lo.x;
1377 	lo.x = ur.x;
1378 	ur.x = lox;
1379 	// reset building search
1380 	best_strasse.reset(pos);
1381 	best_haus.reset(pos);
1382 	// townhall position may be changed a little!
1383 	sparse_tpl<PIXVAL> pax_destinations_temp(koord( PAX_DESTINATIONS_SIZE, PAX_DESTINATIONS_SIZE ));
1384 
1385 	PIXVAL color;
1386 	koord pos;
1387 	for( uint16 i = 0; i < pax_destinations_new.get_data_count(); i++ ) {
1388 		pax_destinations_new.get_nonzero(i, pos, color);
1389 		assert( color != 0 );
1390 		pax_destinations_temp.set( PAX_DESTINATIONS_SIZE-1-pos.y, pos.x, color );
1391 	}
1392 	swap<PIXVAL>( pax_destinations_temp, pax_destinations_new );
1393 
1394 	pax_destinations_temp.clear();
1395 	for( uint16 i = 0; i < pax_destinations_old.get_data_count(); i++ ) {
1396 		pax_destinations_old.get_nonzero(i, pos, color);
1397 		assert( color != 0 );
1398 		pax_destinations_temp.set( PAX_DESTINATIONS_SIZE-1-pos.y, pos.x, color );
1399 	}
1400 	pax_destinations_new_change ++;
1401 	swap<PIXVAL>( pax_destinations_temp, pax_destinations_old );
1402 }
1403 
1404 
set_name(const char * new_name)1405 void stadt_t::set_name(const char *new_name)
1406 {
1407 	if (new_name == NULL) {
1408 		return;
1409 	}
1410 	name = new_name;
1411 	grund_t *gr = welt->lookup_kartenboden(pos);
1412 	if(gr) {
1413 		gr->set_text( new_name );
1414 	}
1415 	city_info_t *win = dynamic_cast<city_info_t*>(win_get_magic((ptrdiff_t)this));
1416 	if (win) {
1417 		win->update_data();
1418 	}
1419 }
1420 
1421 
1422 /* show city info dialogue
1423  * @author prissi
1424  */
open_info_window()1425 void stadt_t::open_info_window()
1426 {
1427 	create_win( new city_info_t(this), w_info, (ptrdiff_t)this );
1428 }
1429 
1430 
1431 /* calculates the factories which belongs to certain cities */
verbinde_fabriken()1432 void stadt_t::verbinde_fabriken()
1433 {
1434 	DBG_MESSAGE("stadt_t::verbinde_fabriken()", "search factories near %s (center at %i,%i)", get_name(), pos.x, pos.y);
1435 	assert( target_factories_pax.get_entries().empty() );
1436 	assert( target_factories_mail.get_entries().empty() );
1437 
1438 	FOR(slist_tpl<fabrik_t*>, const fab, welt->get_fab_list()) {
1439 		const uint32 count = fab->get_target_cities().get_count();
1440 		if(  count < welt->get_settings().get_factory_worker_maximum_towns()  &&  koord_distance(fab->get_pos(), pos) < welt->get_settings().get_factory_worker_radius()  ) {
1441 			fab->add_target_city(this);
1442 		}
1443 	}
1444 	DBG_MESSAGE("stadt_t::verbinde_fabriken()", "is connected with %i/%i factories (total demand=%i/%i) for pax/mail.", target_factories_pax.get_entries().get_count(), target_factories_mail.get_entries().get_count(), target_factories_pax.total_demand, target_factories_mail.total_demand);
1445 }
1446 
1447 
1448 /* change size of city
1449  * @author prissi */
change_size(sint64 delta_citizen,bool new_town)1450 void stadt_t::change_size( sint64 delta_citizen, bool new_town)
1451 {
1452 	DBG_MESSAGE("stadt_t::change_size()", "%i + %i", bev, delta_citizen);
1453 	if(  delta_citizen > 0  ) {
1454 		unsupplied_city_growth += delta_citizen * CITYGROWTH_PER_CITICEN;
1455 		step_grow_city(new_town);
1456 	}
1457 	if(  delta_citizen < 0  ) {
1458 		if(  bev > -delta_citizen  ) {
1459 			bev += (sint32)delta_citizen;
1460 		}
1461 		else {
1462 //				remove_city();
1463 			bev = 1;
1464 		}
1465 		step_grow_city(new_town);
1466 	}
1467 	DBG_MESSAGE("stadt_t::change_size()", "%i+%i", bev, delta_citizen);
1468 }
1469 
1470 
step(uint32 delta_t)1471 void stadt_t::step(uint32 delta_t)
1472 {
1473 	// recalculate factory going ratios where necessary
1474 	const sint16 factory_worker_percentage = welt->get_settings().get_factory_worker_percentage();
1475 	if(  target_factories_pax.ratio_stale  ) {
1476 		target_factories_pax.recalc_generation_ratio( factory_worker_percentage, *city_history_month, MAX_CITY_HISTORY, HIST_PAS_GENERATED);
1477 	}
1478 	if(  target_factories_mail.ratio_stale  ) {
1479 		target_factories_mail.recalc_generation_ratio( factory_worker_percentage, *city_history_month, MAX_CITY_HISTORY, HIST_MAIL_GENERATED);
1480 	}
1481 
1482 	// is it time for the next step?
1483 	next_step += delta_t;
1484 	next_growth_step += delta_t;
1485 
1486 	step_interval = (1 << 21U) / (buildings.get_count() * welt->get_settings().get_passenger_factor() + 1);
1487 	if (step_interval < 1) {
1488 		step_interval = 1;
1489 	}
1490 
1491 	while(stadt_t::city_growth_step < next_growth_step) {
1492 		calc_growth();
1493 		step_grow_city();
1494 		next_growth_step -= stadt_t::city_growth_step;
1495 	}
1496 
1497 	// create passenger rate proportional to town size
1498 	while(step_interval < next_step) {
1499 		step_passagiere();
1500 		step_count++;
1501 		next_step -= step_interval;
1502 	}
1503 
1504 	// update history (might be changed do to construction/destroying of houses)
1505 	city_history_month[0][HIST_CITICENS] = get_einwohner();	// total number
1506 	city_history_year[0][HIST_CITICENS] = get_einwohner();
1507 
1508 	city_history_month[0][HIST_GROWTH] = city_history_month[0][HIST_CITICENS]-city_history_month[1][HIST_CITICENS];	// growth
1509 	city_history_year[0][HIST_GROWTH] = city_history_year[0][HIST_CITICENS]-city_history_year[1][HIST_CITICENS];
1510 
1511 	city_history_month[0][HIST_BUILDING] = buildings.get_count();
1512 	city_history_year[0][HIST_BUILDING] = buildings.get_count();
1513 }
1514 
1515 
1516 /* updates the city history
1517  * @author prissi
1518  */
roll_history()1519 void stadt_t::roll_history()
1520 {
1521 	// roll months
1522 	for (int i = MAX_CITY_HISTORY_MONTHS - 1; i > 0; i--) {
1523 		for (int hist_type = 0; hist_type < MAX_CITY_HISTORY; hist_type++) {
1524 			city_history_month[i][hist_type] = city_history_month[i - 1][hist_type];
1525 		}
1526 	}
1527 	// init this month
1528 	for (int hist_type = 1; hist_type < MAX_CITY_HISTORY; hist_type++) {
1529 		city_history_month[0][hist_type] = 0;
1530 	}
1531 	city_history_month[0][HIST_CITICENS] = get_einwohner();
1532 	city_history_month[0][HIST_BUILDING] = buildings.get_count();
1533 	city_history_month[0][HIST_GOODS_NEEDED] = 0;
1534 
1535 	//need to roll year too?
1536 	if (welt->get_last_month() == 0) {
1537 		for (int i = MAX_CITY_HISTORY_YEARS - 1; i > 0; i--) {
1538 			for (int hist_type = 0; hist_type < MAX_CITY_HISTORY; hist_type++) {
1539 				city_history_year[i][hist_type] = city_history_year[i - 1][hist_type];
1540 			}
1541 		}
1542 		// init this year
1543 		for (int hist_type = 1; hist_type < MAX_CITY_HISTORY; hist_type++) {
1544 			city_history_year[0][hist_type] = 0;
1545 		}
1546 		city_history_year[0][HIST_CITICENS] = get_einwohner();
1547 		city_history_year[0][HIST_BUILDING] = buildings.get_count();
1548 		city_history_year[0][HIST_GOODS_NEEDED] = 0;
1549 	}
1550 
1551 }
1552 
city_growth_get_factors(city_growth_factor_t (& factors)[GROWTH_FACTOR_NUMBER],uint32 const month) const1553 void stadt_t::city_growth_get_factors(city_growth_factor_t(&factors)[GROWTH_FACTOR_NUMBER], uint32 const month) const {
1554 	// optimize view of history for convenience
1555 	sint64 const (&h)[MAX_CITY_HISTORY] = city_history_month[month];
1556 
1557 	// go through each index one at a time
1558 	uint32 index = 0;
1559 
1560 	// passenger growth factors
1561 	factors[index].demand = h[HIST_PAS_GENERATED];
1562 	factors[index++].supplied = h[HIST_PAS_TRANSPORTED] + h[HIST_PAS_WALKED];
1563 
1564 	// mail growth factors
1565 	factors[index].demand = h[HIST_MAIL_GENERATED];
1566 	factors[index++].supplied = h[HIST_MAIL_TRANSPORTED] + h[HIST_MAIL_WALKED];
1567 
1568 	// goods growth factors
1569 	factors[index].demand = h[HIST_GOODS_NEEDED];
1570 	factors[index++].supplied = h[HIST_GOODS_RECEIVED];
1571 }
1572 
city_growth_base(uint32 const rprec,uint32 const cprec)1573 sint32 stadt_t::city_growth_base(uint32 const rprec, uint32 const cprec)
1574 {
1575 	// Resolve constant references.
1576 	settings_t const & s = welt->get_settings();
1577 	sint32 const weight[GROWTH_FACTOR_NUMBER] = { s.get_passenger_multiplier(), s.get_mail_multiplier(),
1578 	    s.get_goods_multiplier() };
1579 
1580 	sint32 acc = 0; // The weighted satisfaction accululator.
1581 	sint32 div = 0; // The weight dividend.
1582 	sint32 total = 0; // The total weight.
1583 
1584 	// initalize const growth array
1585 	city_growth_factor_t growthfactors[GROWTH_FACTOR_NUMBER];
1586 	city_growth_get_factors(growthfactors, 0);
1587 
1588 	// Loop through each growth factor and compute it.
1589 	for( uint32 i = 0; i < GROWTH_FACTOR_NUMBER; i += 1 ) {
1590 		// Resolve the weight.
1591 		total += weight[i];
1592 
1593 		// Compute the differentials.
1594 		sint64 const had = growthfactors[i].demand - city_growth_factor_previous[i].demand;
1595 		city_growth_factor_previous[i].demand = growthfactors[i].demand;
1596 		sint64 const got = growthfactors[i].supplied - city_growth_factor_previous[i].supplied;
1597 		city_growth_factor_previous[i].supplied = growthfactors[i].supplied;
1598 
1599 		// If we had anything to satisfy add it to weighting otherwise skip.
1600 		if( had == 0 ) {
1601 			continue;
1602 		}
1603 
1604 		// Compute fractional satisfaction.
1605 		sint32 const frac = (sint32)((got << cprec) / had);
1606 
1607 		// Add to weight and div.
1608 		acc += frac * weight[i];
1609 		div += weight[i];
1610 	}
1611 
1612 	// If there was not anything to satisfy then use last month averages.
1613 	if (  div == 0  ) {
1614 		// initalize growth factor array
1615 		city_growth_factor_t prev_growthfactors[GROWTH_FACTOR_NUMBER];
1616 		city_growth_get_factors(prev_growthfactors, 1);
1617 
1618 		for( uint32 i = 0; i < GROWTH_FACTOR_NUMBER; i += 1 ){
1619 
1620 			// Extract the values of growth.
1621 			sint64 const had = prev_growthfactors[i].demand;
1622 			sint64 const got = prev_growthfactors[i].supplied;
1623 
1624 			// If we had anything to satisfy add it to weighting otherwise skip.
1625 			if( had == 0 ) {
1626 				continue;
1627 			}
1628 
1629 			// Compute fractional satisfaction.
1630 			sint32 const frac = (sint32)((got << cprec) / had);
1631 
1632 			// Add to weight and div.
1633 			acc += frac * weight[i];
1634 			div += weight[i];
1635 		}
1636 	}
1637 
1638 	// Return computed result. If still no demand then assume no growth to prevent self-growing new hamlets.
1639 	return div != 0 ? (total * (acc / div)) >> (cprec - rprec) : 0;
1640 }
1641 
1642 
city_growth_monthly(uint32 const month)1643 void stadt_t::city_growth_monthly(uint32 const month)
1644 {
1645 	// initalize growth factor array
1646 	city_growth_factor_t growthfactors[GROWTH_FACTOR_NUMBER];
1647 	city_growth_get_factors(growthfactors, month);
1648 
1649 	// Perform roll over.
1650 	for( uint32 i = 0; i < GROWTH_FACTOR_NUMBER; i += 1 ){
1651 		// Compute the differentials.
1652 		sint64 const had = growthfactors[i].demand - city_growth_factor_previous[i].demand;
1653 		city_growth_factor_previous[i].demand = -had;
1654 		sint64 const got = growthfactors[i].supplied - city_growth_factor_previous[i].supplied;
1655 		city_growth_factor_previous[i].supplied = -got;
1656 	}
1657 }
1658 
1659 
new_month(bool recalc_destinations)1660 void stadt_t::new_month( bool recalc_destinations )
1661 {
1662 	swap<PIXVAL>( pax_destinations_old, pax_destinations_new );
1663 	pax_destinations_new.clear();
1664 	pax_destinations_new_change = 0;
1665 
1666 	city_growth_monthly(0);
1667 	roll_history();
1668 	target_factories_pax.new_month();
1669 	target_factories_mail.new_month();
1670 
1671 	const sint16 factory_worker_percentage = welt->get_settings().get_factory_worker_percentage();
1672 //	settings_t const& s = welt->get_settings();
1673 	target_factories_pax.recalc_generation_ratio( factory_worker_percentage, *city_history_month, MAX_CITY_HISTORY, HIST_PAS_GENERATED);
1674 	target_factories_mail.recalc_generation_ratio( factory_worker_percentage, *city_history_month, MAX_CITY_HISTORY, HIST_MAIL_GENERATED);
1675 	recalc_target_cities();
1676 
1677 	// center has moved => change attraction weights
1678 	if(  recalc_destinations  ||  last_center != get_center()  ) {
1679 		last_center = get_center();
1680 		recalc_target_attractions();
1681 	}
1682 
1683 	if(  !private_car_t::list_empty()  &&  welt->get_settings().get_traffic_level() > 0  ) {
1684 		// spawn eventual citycars
1685 		// the more transported, the less are spawned
1686 		// the larger the city, the more spawned ...
1687 
1688 		/* original implementation that is replaced by integer-only version below
1689 		double pfactor = (double)(city_history_month[1][HIST_PAS_TRANSPORTED]) / (double)(city_history_month[1][HIST_PAS_GENERATED]+1);
1690 		double mfactor = (double)(city_history_month[1][HIST_MAIL_TRANSPORTED]) / (double)(city_history_month[1][HIST_MAIL_GENERATED]+1);
1691 		double gfactor = (double)(city_history_month[1][HIST_GOODS_RECEIVED]) / (double)(city_history_month[1][HIST_GOODS_NEEDED]+1);
1692 
1693 		double factor = pfactor > mfactor ? (gfactor > pfactor ? gfactor : pfactor ) : mfactor;
1694 		factor = (1.0-factor)*city_history_month[1][HIST_CITICENS];
1695 		factor = log10( factor );
1696 		*/
1697 
1698 		// placeholder for fractions
1699 #		define decl_stat(name, i0, i1) sint64 name##_stat[2]; name##_stat[0] = city_history_month[1][i0];  name##_stat[1] = city_history_month[1][i1]+1;
1700 
1701 		// defines and initializes local sint64[2] arrays
1702 		decl_stat(pax, HIST_PAS_TRANSPORTED, HIST_PAS_GENERATED);
1703 		decl_stat(mail, HIST_MAIL_TRANSPORTED, HIST_MAIL_GENERATED);
1704 		decl_stat(good, HIST_GOODS_RECEIVED, HIST_GOODS_NEEDED);
1705 
1706 		// true if s1[0] / s1[1] > s2[0] / s2[1]
1707 #		define comp_stats(s1,s2) ( s1[0]*s2[1] > s2[0]*s1[1] )
1708 		// computes (1.0 - s[0]/s[1]) * city_history_month[1][HIST_CITICENS]
1709 #		define comp_factor(s) (city_history_month[1][HIST_CITICENS] *( s[1]-s[0] )) / s[1]
1710 
1711 		uint32 factor = (uint32)( comp_stats(pax_stat, mail_stat) ? (comp_stats(good_stat, pax_stat) ? comp_factor(good_stat) : comp_factor(pax_stat)) : comp_factor(mail_stat) );
1712 		factor = log10(factor);
1713 
1714 #ifndef DESTINATION_CITYCARS
1715 		uint16 number_of_cars = simrand( factor * welt->get_settings().get_traffic_level() ) / 16;
1716 
1717 		city_history_month[0][HIST_CITYCARS] = number_of_cars;
1718 		city_history_year[0][HIST_CITYCARS] += number_of_cars;
1719 
1720 		koord k;
1721 		koord pos = get_zufallspunkt();
1722 		for (k.y = pos.y - 3; k.y < pos.y + 3; k.y++) {
1723 			for (k.x = pos.x - 3; k.x < pos.x + 3; k.x++) {
1724 				if(number_of_cars==0) {
1725 					return;
1726 				}
1727 
1728 				grund_t* gr = welt->lookup_kartenboden(k);
1729 				if(  gr != NULL  &&  gr->get_weg(road_wt)  &&  ribi_t::is_twoway(gr->get_weg_ribi_unmasked(road_wt))  &&  gr->find<private_car_t>() == NULL) {
1730 					private_car_t* vt = new private_car_t(gr, koord::invalid);
1731 					gr->obj_add(vt);
1732 					welt->sync.add(vt);
1733 					number_of_cars--;
1734 				}
1735 			}
1736 		}
1737 
1738 		// correct statistics for ungenerated cars
1739 		city_history_month[0][HIST_CITYCARS] -= number_of_cars;
1740 		city_history_year[0][HIST_CITYCARS] -= number_of_cars;
1741 #else
1742 		city_history_month[0][HIST_CITYCARS] = 0;
1743 		number_of_cars = simrand( factor * welt->get_settings().get_traffic_level() ) / 16;
1744 #endif
1745 	}
1746 }
1747 
1748 
calc_growth()1749 void stadt_t::calc_growth()
1750 {
1751 	// now iterate over all factories to get the ratio of producing version non-producing factories
1752 	// we use the incoming storage as a measure and we will only look for end consumers (power stations, markets)
1753 	FOR(vector_tpl<factory_entry_t>, const& i, target_factories_pax.get_entries()) {
1754 		fabrik_t *const fab = i.factory;
1755 		if (fab->get_lieferziele().empty() && !fab->get_suppliers().empty()) {
1756 			// consumer => check for it storage
1757 			const factory_desc_t *const desc = fab->get_desc();
1758 			for(  int i=0;  i<desc->get_supplier_count();  i++  ) {
1759 				city_history_month[0][HIST_GOODS_NEEDED] ++;
1760 				city_history_year[0][HIST_GOODS_NEEDED] ++;
1761 				if(  fab->input_vorrat_an( desc->get_supplier(i)->get_input_type() )>0  ) {
1762 					city_history_month[0][HIST_GOODS_RECEIVED] ++;
1763 					city_history_year[0][HIST_GOODS_RECEIVED] ++;
1764 				}
1765 			}
1766 		}
1767 	}
1768 
1769 	// maybe this town should stay static
1770 	if(  !allow_citygrowth  ) {
1771 		unsupplied_city_growth = 0;
1772 		return;
1773 	}
1774 
1775 	// Compute base growth.
1776 	sint32 const total_supply_percentage = city_growth_base();
1777 
1778 	// By construction, this is a percentage times 2^6 (Q25.6).
1779 	// Although intended to be out of 100, it can be more or less.
1780 	// We will divide it by 2^4=16 for traditional reasons, which means
1781 	// it generates 2^2 (=4) or fewer people at 100%.
1782 
1783 	// smaller towns should grow slower to have villages for a longer time
1784 	sint32 const weight_factor =
1785 		bev <  1000 ? welt->get_settings().get_growthfactor_small()  :
1786 		bev < 10000 ? welt->get_settings().get_growthfactor_medium() :
1787 		welt->get_settings().get_growthfactor_large();
1788 
1789 	// now compute the growth for this step
1790 	sint32 growth_factor = weight_factor > 0 ? total_supply_percentage / weight_factor : 0;
1791 
1792 	// Scale up growth to have a larger fractional component. This allows small growth units to accumulate in the case of long months.
1793 	sint64 new_unsupplied_city_growth = growth_factor * (CITYGROWTH_PER_CITICEN / 16);
1794 
1795 	// Growth is scaled down by month length.
1796 	// The result is that ~ the same monthly growth will occur independent of month length.
1797 	new_unsupplied_city_growth = welt->inverse_scale_with_month_length( new_unsupplied_city_growth );
1798 
1799 	// Add the computed growth to the growth accumulator.
1800 	// Future growth scale factors can be applied here.
1801 	unsupplied_city_growth += new_unsupplied_city_growth;
1802 }
1803 
1804 
1805 // does constructions ...
step_grow_city(bool new_town)1806 void stadt_t::step_grow_city( bool new_town )
1807 {
1808 	// Try harder to build if this is a new town
1809 	int num_tries = new_town ? 1000 : 30;
1810 
1811 	// since we use internally a finer value ...
1812 	const sint64 growth_steps = unsupplied_city_growth / CITYGROWTH_PER_CITICEN;
1813 	if(  growth_steps > 0  ) {
1814 		unsupplied_city_growth %= CITYGROWTH_PER_CITICEN;
1815 	}
1816 
1817 	// Hajo: let city grow in steps of 1
1818 	// @author prissi: No growth without development
1819 	for(  sint64 n = 0;  n < growth_steps;  n++  ) {
1820 		bev++;
1821 
1822 		for(  int i = 0;  i < num_tries  &&  bev * 2 > won + arb + 100;  i++  ) {
1823 			build();
1824 		}
1825 
1826 		check_bau_spezial(new_town);
1827 		check_bau_townhall(new_town);
1828 		check_bau_factory(new_town); // add industry? (not during creation)
1829 		INT_CHECK("simcity 275");
1830 	}
1831 }
1832 
1833 
1834 /* this creates passengers and mail for everything is is therefore one of the CPU hogs of the machine
1835  * think trice, before applying optimisation here ...
1836  */
step_passagiere()1837 void stadt_t::step_passagiere()
1838 {
1839 	// decide whether to generate passengers or mail
1840 	const bool ispass = simrand(GENERATE_RATIO_PASS + GENERATE_RATIO_MAIL) < GENERATE_RATIO_PASS;
1841 	const goods_desc_t *const wtyp = ispass ? goods_manager_t::passengers : goods_manager_t::mail;
1842 	const uint32 history_type = ispass ? HIST_BASE_PASS : HIST_BASE_MAIL;
1843 	factory_set_t &target_factories = ispass ? target_factories_pax : target_factories_mail;
1844 
1845 	// restart at first building?
1846 	if (step_count >= buildings.get_count()) {
1847 		step_count = 0;
1848 	}
1849 	if (buildings.empty()) {
1850 		return;
1851 	}
1852 	const gebaeude_t* gb = buildings[step_count];
1853 
1854 	// prissi: since now backtravels occur, we damp the numbers a little
1855 	const uint32 num_pax =
1856 		(ispass) ?
1857 			(gb->get_tile()->get_desc()->get_level()      + 6) >> 2 :
1858 			(gb->get_tile()->get_desc()->get_mail_level() + 8) >> 3 ;
1859 
1860 	// create pedestrians in the near area?
1861 	if (welt->get_settings().get_random_pedestrians()  &&  ispass) {
1862 		haltestelle_t::generate_pedestrians(gb->get_pos(), num_pax);
1863 	}
1864 
1865 	// suitable start search
1866 	const koord origin_pos = gb->get_pos().get_2d();
1867 	const planquadrat_t *const plan = welt->access(origin_pos);
1868 	const halthandle_t *const halt_list = plan->get_haltlist();
1869 
1870 	// suitable start search
1871 	static vector_tpl<halthandle_t> start_halts(16);
1872 	start_halts.clear();
1873 	for (uint h = 0; h < plan->get_haltlist_count(); h++) {
1874 		halthandle_t halt = halt_list[h];
1875 		if(  halt.is_bound()  &&  halt->is_enabled(wtyp)  &&  !halt->is_overcrowded(wtyp->get_index())  ) {
1876 			start_halts.append(halt);
1877 		}
1878 	}
1879 
1880 	// Hajo: track number of generated passengers.
1881 	city_history_year[0][history_type + HIST_OFFSET_GENERATED] += num_pax;
1882 	city_history_month[0][history_type + HIST_OFFSET_GENERATED] += num_pax;
1883 
1884 	// only continue, if this is a good start halt
1885 	if(  !start_halts.empty()  ) {
1886 		// Find passenger destination
1887 		for(  uint pax_routed=0, pax_left_to_do=0;  pax_routed < num_pax;  pax_routed += pax_left_to_do  ) {
1888 			// number of passengers that want to travel
1889 			// Hajo: for efficiency we try to route not every
1890 			// single pax, but packets. If possible, we do 7 passengers at a time
1891 			// the last packet might have less then 7 pax
1892 			pax_left_to_do = min(PACKET_SIZE, num_pax - pax_routed);
1893 
1894 			// search target for the passenger
1895 			pax_return_type will_return;
1896 			factory_entry_t *factory_entry = NULL;
1897 			stadt_t *dest_city = NULL;
1898 			const koord dest_pos = find_destination(target_factories, city_history_month[0][history_type + HIST_OFFSET_GENERATED], &will_return, factory_entry, dest_city);
1899 			if(  factory_entry  ) {
1900 				if (welt->get_settings().get_factory_enforce_demand()) {
1901 					// ensure no more than remaining amount
1902 					pax_left_to_do = min( pax_left_to_do, factory_entry->remaining );
1903 					factory_entry->remaining -= pax_left_to_do;
1904 					target_factories.total_remaining -= pax_left_to_do;
1905 				}
1906 				target_factories.total_generated += pax_left_to_do;
1907 				factory_entry->factory->book_stat(pax_left_to_do, ispass ? FAB_PAX_GENERATED : FAB_MAIL_GENERATED);
1908 			}
1909 
1910 			ware_t pax(wtyp);
1911 			pax.set_zielpos(dest_pos);
1912 			pax.menge = pax_left_to_do;
1913 			pax.to_factory = ( factory_entry ? 1 : 0 );
1914 
1915 			ware_t return_pax(wtyp);
1916 
1917 			// now, finally search a route; this consumes most of the time
1918 			int const route_result = haltestelle_t::search_route( &start_halts[0], start_halts.get_count(), welt->get_settings().is_no_routing_over_overcrowding(), pax, &return_pax);
1919 			halthandle_t start_halt = return_pax.get_ziel();
1920 			if(  route_result==haltestelle_t::ROUTE_OK  ) {
1921 				// so we have happy traveling passengers
1922 				start_halt->starte_mit_route(pax);
1923 				start_halt->add_pax_happy(pax.menge);
1924 
1925 				// people were transported so are logged
1926 				city_history_year[0][history_type + HIST_OFFSET_TRANSPORTED] += pax_left_to_do;
1927 				city_history_month[0][history_type + HIST_OFFSET_TRANSPORTED] += pax_left_to_do;
1928 
1929 				// destination logged
1930 				merke_passagier_ziel(dest_pos, color_idx_to_rgb(COL_YELLOW));
1931 			}
1932 			else if(  route_result==haltestelle_t::ROUTE_WALK  ) {
1933 				if(  factory_entry  ) {
1934 					// workers and mail delivered instantly to factory
1935 					factory_entry->factory->liefere_an(wtyp, pax_left_to_do);
1936 				}
1937 
1938 				// log walked at stop
1939 				start_halt->add_pax_walked(pax_left_to_do);
1940 
1941 				// people who walk or deliver by hand logged as walking
1942 				city_history_year[0][history_type + HIST_OFFSET_WALKED] += pax_left_to_do;
1943 				city_history_month[0][history_type + HIST_OFFSET_WALKED] += pax_left_to_do;
1944 
1945 				// probably not a good idea to mark them as player only cares about remote traffic
1946 				//merke_passagier_ziel(dest_pos, color_idx_to_rgb(COL_YELLOW));
1947 			}
1948 			else if(  route_result==haltestelle_t::ROUTE_OVERCROWDED  ) {
1949 				// overcrowded routes cause unhappiness to be logged
1950 
1951 				if(  start_halt.is_bound()  ) {
1952 					start_halt->add_pax_unhappy(pax_left_to_do);
1953 				}
1954 				else {
1955 					// all routes to goal are overcrowded -> register at first stop (closest)
1956 					FOR(vector_tpl<halthandle_t>, const s, start_halts) {
1957 						s->add_pax_unhappy(pax_left_to_do);
1958 						merke_passagier_ziel(dest_pos, color_idx_to_rgb(COL_ORANGE));
1959 						break;
1960 					}
1961 				}
1962 
1963 				// destination logged
1964 				merke_passagier_ziel(dest_pos, color_idx_to_rgb(COL_ORANGE));
1965 			}
1966 			else if (  route_result == haltestelle_t::NO_ROUTE  ) {
1967 				// since there is no route from any start halt -> register no route at first halts (closest)
1968 				FOR(vector_tpl<halthandle_t>, const s, start_halts) {
1969 					s->add_pax_no_route(pax_left_to_do);
1970 					break;
1971 				}
1972 				merke_passagier_ziel(dest_pos, color_idx_to_rgb(COL_DARK_ORANGE));
1973 #ifdef DESTINATION_CITYCARS
1974 				//citycars with destination
1975 				generate_private_cars( origin_pos, dest_pos );
1976 #endif
1977 			}
1978 
1979 			// return passenger traffic
1980 			if(  will_return != no_return  ) {
1981 				// compute return amount
1982 				uint32 pax_return = pax_left_to_do;
1983 
1984 				// apply return modifiers
1985 				if(  will_return != city_return  &&  wtyp == goods_manager_t::mail  ) {
1986 					// attractions and factories return more mail than they receive
1987 					pax_return *= MAIL_RETURN_MULTIPLIER_PRODUCERS;
1988 				}
1989 
1990 				// log potential return passengers at destination city
1991 				dest_city->city_history_year[0][history_type + HIST_OFFSET_GENERATED] += pax_return;
1992 				dest_city->city_history_month[0][history_type + HIST_OFFSET_GENERATED] += pax_return;
1993 
1994 				// factories generate return traffic
1995 				if (  factory_entry  ) {
1996 					factory_entry->factory->book_stat(pax_return, (ispass ? FAB_PAX_GENERATED : FAB_MAIL_GENERATED));
1997 				}
1998 
1999 				// route type specific logic
2000 				if(  route_result == haltestelle_t::ROUTE_OK  ) {
2001 					// send return packet
2002 					halthandle_t return_halt = pax.get_ziel();
2003 					if(  !return_halt->is_overcrowded(wtyp->get_index())  ) {
2004 						// stop can receive passengers
2005 
2006 						// register departed pax/mail at factory
2007 						if (factory_entry) {
2008 							factory_entry->factory->book_stat(pax_return, ispass ? FAB_PAX_DEPARTED : FAB_MAIL_DEPARTED);
2009 						}
2010 
2011 						// setup ware packet
2012 						return_pax.menge = pax_return;
2013 						return_pax.set_zielpos(origin_pos);
2014 						return_halt->starte_mit_route(return_pax);
2015 
2016 						// log departed at stop
2017 						return_halt->add_pax_happy(pax_return);
2018 
2019 						// log departed at destination city
2020 						dest_city->city_history_year[0][history_type + HIST_OFFSET_TRANSPORTED] += pax_return;
2021 						dest_city->city_history_month[0][history_type + HIST_OFFSET_TRANSPORTED] += pax_return;
2022 					}
2023 					else {
2024 						// stop is crowded
2025 						return_halt->add_pax_unhappy(pax_return);
2026 					}
2027 
2028 				}
2029 				else if(  route_result == haltestelle_t::ROUTE_WALK  ) {
2030 					// walking can produce return flow as a result of commuters to industry, monuments or stupidly big stops
2031 
2032 					// register departed pax/mail at factory
2033 					if (  factory_entry  ) {
2034 						factory_entry->factory->book_stat(pax_return, ispass ? FAB_PAX_DEPARTED : FAB_MAIL_DEPARTED);
2035 					}
2036 
2037 					// log walked at stop (source and destination stops are the same)
2038 					start_halt->add_pax_walked(pax_return);
2039 
2040 					// log people who walk or deliver by hand
2041 					dest_city->city_history_year[0][history_type + HIST_OFFSET_WALKED] += pax_return;
2042 					dest_city->city_history_month[0][history_type + HIST_OFFSET_WALKED] += pax_return;
2043 				}
2044 				else if(  route_result == haltestelle_t::ROUTE_OVERCROWDED  ) {
2045 					// overcrowded routes cause unhappiness to be logged
2046 
2047 					if (pax.get_ziel().is_bound()) {
2048 						pax.get_ziel()->add_pax_unhappy(pax_return);
2049 					}
2050 					else {
2051 						// the unhappy passengers will be added to the first stops near destination (might be none)
2052 						const planquadrat_t *const dest_plan = welt->access(dest_pos);
2053 						const halthandle_t *const dest_halt_list = dest_plan->get_haltlist();
2054 						for (uint h = 0; h < dest_plan->get_haltlist_count(); h++) {
2055 							halthandle_t halt = dest_halt_list[h];
2056 							if (halt->is_enabled(wtyp)) {
2057 								halt->add_pax_unhappy(pax_return);
2058 								break;
2059 							}
2060 						}
2061 					}
2062 				}
2063 				else if (route_result == haltestelle_t::NO_ROUTE) {
2064 					// passengers who cannot find a route will be added to the first stops near destination (might be none)
2065 					const planquadrat_t *const dest_plan = welt->access(dest_pos);
2066 					const halthandle_t *const dest_halt_list = dest_plan->get_haltlist();
2067 					for (uint h = 0; h < dest_plan->get_haltlist_count(); h++) {
2068 						halthandle_t halt = dest_halt_list[h];
2069 						if (halt->is_enabled(wtyp)) {
2070 							halt->add_pax_no_route(pax_return);
2071 							break;
2072 						}
2073 					}
2074 				}
2075 			}
2076 			INT_CHECK( "simcity 1579" );
2077 		}
2078 	}
2079 	else {
2080 		// assume no free stop to start at all
2081 		bool is_there_any_stop = false;
2082 
2083 		// the unhappy passengers will be added to the first stop if any
2084 		for(  uint h=0;  h<plan->get_haltlist_count(); h++  ) {
2085 			halthandle_t halt = plan->get_haltlist()[h];
2086 			if(  halt->is_enabled(wtyp)  ) {
2087 				halt->add_pax_unhappy(num_pax);
2088 				is_there_any_stop = true;	// only overcrowded
2089 				break;
2090 			}
2091 		}
2092 
2093 		// all passengers without suitable start:
2094 		// fake one ride to get a proper display of destinations (although there may be more) ...
2095 		pax_return_type will_return;
2096 		factory_entry_t *factory_entry = NULL;
2097 		stadt_t *dest_city = NULL;
2098 		const koord ziel = find_destination(target_factories, city_history_month[0][history_type + HIST_OFFSET_GENERATED], &will_return, factory_entry, dest_city);
2099 		if(  factory_entry  ) {
2100 			// consider at most 1 packet's amount as factory-going
2101 			sint32 amount = min(PACKET_SIZE, num_pax);
2102 			if(  welt->get_settings().get_factory_enforce_demand()  ) {
2103 				// ensure no more than remaining amount
2104 				amount = min( amount, factory_entry->remaining );
2105 				factory_entry->remaining -= amount;
2106 				target_factories.total_remaining -= amount;
2107 			}
2108 			target_factories.total_generated += amount;
2109 			factory_entry->factory->book_stat( amount, ( ispass ? FAB_PAX_GENERATED : FAB_MAIL_GENERATED ) );
2110 		}
2111 
2112 
2113 		// log reverse flow at destination city for accurate tally
2114 		if(  will_return != no_return  ) {
2115 			uint32 pax_return = num_pax;
2116 
2117 			// apply return modifiers
2118 			if(  will_return != city_return  &&  wtyp == goods_manager_t::mail  ) {
2119 				// attractions and factories return more mail than they receive
2120 				pax_return *= MAIL_RETURN_MULTIPLIER_PRODUCERS;
2121 			}
2122 
2123 			// log potential return passengers at destination city
2124 			dest_city->city_history_year[0][history_type + HIST_OFFSET_GENERATED] += pax_return;
2125 			dest_city->city_history_month[0][history_type + HIST_OFFSET_GENERATED] += pax_return;
2126 
2127 			// factories generate return traffic
2128 			if (  factory_entry  ) {
2129 				factory_entry->factory->book_stat(pax_return, (ispass ? FAB_PAX_GENERATED : FAB_MAIL_GENERATED));
2130 			}
2131 
2132 			// passengers with no route will be added to the first stops near destination (might be none)
2133 			const planquadrat_t *const dest_plan = welt->access(ziel);
2134 			const halthandle_t *const dest_halt_list = dest_plan->get_haltlist();
2135 			for (uint h = 0; h < dest_plan->get_haltlist_count(); h++) {
2136 				halthandle_t halt = dest_halt_list[h];
2137 				if (  halt->is_enabled(wtyp)  ) {
2138 					if(  is_there_any_stop  ) {
2139 						// "just" overcrowded
2140 						halt->add_pax_unhappy(pax_return);
2141 					}
2142 					else {
2143 						// no stops at all
2144 						halt->add_pax_no_route(pax_return);
2145 					}
2146 					break;
2147 				}
2148 			}
2149 		}
2150 
2151 #ifdef DESTINATION_CITYCARS
2152 		//citycars with destination
2153 		generate_private_cars( origin_pos, ziel );
2154 #endif
2155 		merke_passagier_ziel(ziel, color_idx_to_rgb(COL_ORANGE));
2156 		// we show unhappy instead no route for destination stop
2157 	}
2158 }
2159 
2160 
2161 /**
2162  * returns a random and uniformly distributed point within city borders
2163  * @author Hj. Malthaner
2164  */
get_zufallspunkt() const2165 koord stadt_t::get_zufallspunkt() const
2166 {
2167 	if(!buildings.empty()) {
2168 		gebaeude_t* const gb = pick_any_weighted(buildings);
2169 		koord k = gb->get_pos().get_2d();
2170 		if(!welt->is_within_limits(k)) {
2171 			// this building should not be in this list, since it has been already deleted!
2172 			dbg->error("stadt_t::get_zufallspunkt()", "illegal building in city list of %s: %p removing!", this->get_name(), gb);
2173 			const_cast<stadt_t*>(this)->buildings.remove(gb);
2174 			k = koord(0, 0);
2175 		}
2176 		return k;
2177 	}
2178 	// might happen on slow computers during creation of new cities or start of map
2179 	return koord(0,0);
2180 }
2181 
2182 
add_target_city(stadt_t * const city)2183 void stadt_t::add_target_city(stadt_t *const city)
2184 {
2185 	target_cities.append(
2186 		city,
2187 		weight_by_distance( city->get_einwohner()+1, shortest_distance( get_center(), city->get_center() ) )
2188 	);
2189 }
2190 
2191 
recalc_target_cities()2192 void stadt_t::recalc_target_cities()
2193 {
2194 	target_cities.clear();
2195 	FOR(weighted_vector_tpl<stadt_t*>, const c, welt->get_cities()) {
2196 		add_target_city(c);
2197 	}
2198 }
2199 
2200 
add_target_attraction(gebaeude_t * const attraction)2201 void stadt_t::add_target_attraction(gebaeude_t *const attraction)
2202 {
2203 	assert( attraction != NULL );
2204 	target_attractions.append(
2205 		attraction,
2206 		weight_by_distance( attraction->get_passagier_level() << 4, shortest_distance( get_center(), attraction->get_pos().get_2d() ) )
2207 	);
2208 }
2209 
2210 
recalc_target_attractions()2211 void stadt_t::recalc_target_attractions()
2212 {
2213 	target_attractions.clear();
2214 	FOR(weighted_vector_tpl<gebaeude_t*>, const a, welt->get_attractions()) {
2215 		add_target_attraction(a);
2216 	}
2217 }
2218 
2219 
2220 /* this function generates a random target for passenger/mail
2221  * changing this strongly affects selection of targets and thus game strategy
2222  */
find_destination(factory_set_t & target_factories,const sint64 generated,pax_return_type * will_return,factory_entry_t * & factory_entry,stadt_t * & dest_city)2223 koord stadt_t::find_destination(factory_set_t &target_factories, const sint64 generated, pax_return_type* will_return, factory_entry_t* &factory_entry, stadt_t* &dest_city)
2224 {
2225 	// generate factory traffic when required
2226 	if(  target_factories.total_remaining>0  &&  (sint64)target_factories.generation_ratio>((sint64)(target_factories.total_generated*100)<<RATIO_BITS)/(generated+1)  ) {
2227 		factory_entry_t *const entry = target_factories.get_random_entry();
2228 		assert( entry );
2229 		*will_return = factory_return;	// worker will return
2230 		factory_entry = entry;
2231 		dest_city = this; // factory is part of city
2232 		return entry->factory->get_pos().get_2d();
2233 	}
2234 
2235 	// chance to generate tourist traffic
2236 	const sint16 rand = simrand(100 - (target_factories.generation_ratio >> RATIO_BITS));
2237 	if(  rand < welt->get_settings().get_tourist_percentage()  &&  target_attractions.get_sum_weight() > 0  ) {
2238 		*will_return = tourist_return;	// tourists will return
2239 		gebaeude_t *const &attraction = pick_any_weighted(target_attractions);
2240 		dest_city = attraction->get_stadt(); // unsure if return value always valid
2241 		if (dest_city == NULL) {
2242 			// if destination city was invalid assume this city is the source
2243 			dest_city = this;
2244 		}
2245 		return attraction->get_pos().get_2d();
2246 	}
2247 
2248 	// generate general traffic between buildings
2249 
2250 	// since the locality is already taken into account for us, we just use the random weight
2251 	stadt_t *const selected_city = pick_any_weighted( target_cities );
2252 	// no return trip if the destination is inside the same city
2253 	*will_return = selected_city == this ? no_return : city_return;
2254 	dest_city = selected_city;
2255 	// find a random spot inside the selected city
2256 	return selected_city->get_zufallspunkt();
2257 
2258 }
2259 
2260 
merke_passagier_ziel(koord k,PIXVAL color)2261 void stadt_t::merke_passagier_ziel(koord k, PIXVAL color)
2262 {
2263 	const koord p = koord(
2264 		((k.x * PAX_DESTINATIONS_SIZE) / welt->get_size().x) & (PAX_DESTINATIONS_SIZE-1),
2265 		((k.y * PAX_DESTINATIONS_SIZE) / welt->get_size().y) & (PAX_DESTINATIONS_SIZE-1)
2266 	);
2267 	pax_destinations_new_change ++;
2268 	pax_destinations_new.set(p, color);
2269 }
2270 
2271 
2272 /**
2273  * building_place_with_road_finder:
2274  * Search a free place for a building using function suche_platz() (search place).
2275  * added: Minimum distance between monuments
2276  * @author V. Meyer/prissi
2277  */
2278 class building_place_with_road_finder: public building_placefinder_t
2279 {
2280 	public:
2281 		/// if false, this will the check 'do not build next other to special buildings'
2282 		bool big_city;
2283 
building_place_with_road_finder(karte_t * welt,sint16 radius,bool big)2284 		building_place_with_road_finder(karte_t* welt, sint16 radius, bool big) : building_placefinder_t(welt, radius), big_city(big) {}
2285 
2286 		// get distance to next special building
find_dist_next_special(koord pos) const2287 		int find_dist_next_special(koord pos) const
2288 		{
2289 			const weighted_vector_tpl<gebaeude_t*>& attractions = welt->get_attractions();
2290 			int dist = welt->get_size().x * welt->get_size().y;
2291 			FOR(  weighted_vector_tpl<gebaeude_t*>, const i, attractions  ) {
2292 				int const d = koord_distance(i->get_pos(), pos);
2293 				if(  d < dist  ) {
2294 					dist = d;
2295 				}
2296 			}
2297 			FOR(  weighted_vector_tpl<stadt_t *>, const city, welt->get_cities() ) {
2298 				int const d = koord_distance(city->get_pos(), pos);
2299 				if(  d < dist  ) {
2300 					dist = d;
2301 				}
2302 			}
2303 			return dist;
2304 		}
2305 
is_area_ok(koord pos,sint16 w,sint16 h,climate_bits cl) const2306 		bool is_area_ok(koord pos, sint16 w, sint16 h, climate_bits cl) const OVERRIDE
2307 		{
2308 			if(  !building_placefinder_t::is_area_ok(pos, w, h, cl)  ) {
2309 				return false;
2310 			}
2311 			bool next_to_road = false;
2312 			// not direct next to factories or townhalls
2313 			for (sint16 x = -1; x < w; x++) {
2314 				for (sint16 y = -1;  y < h; y++) {
2315 					grund_t *gr = welt->lookup_kartenboden(pos + koord(x,y));
2316 					if (!gr) {
2317 						return false;
2318 					}
2319 					if (	0 <= x  &&  x < w-1  &&  0 <= y  &&  y < h-1) {
2320 						// inside: nothing on top like elevated monorails?
2321 						if(  gr->get_leitung()!=NULL  ||  welt->lookup(gr->get_pos()+koord3d(0,0,1)  )!=NULL) {
2322 							// something on top (monorail or powerlines)
2323 							return false;
2324 						}
2325 
2326 					}
2327 					else {
2328 						// border: not direct next to special buildings
2329 						if (big_city) {
2330 							if(  gebaeude_t *gb=gr->find<gebaeude_t>()  ) {
2331 								const building_desc_t::btype utyp = gb->get_tile()->get_desc()->get_type();
2332 								if(  building_desc_t::attraction_city <= utyp  &&  utyp <= building_desc_t::headquarters) {
2333 									return false;
2334 								}
2335 							}
2336 						}
2337 						// but near a road if possible
2338 						if (!next_to_road) {
2339 							next_to_road = gr->hat_weg(road_wt);
2340 						}
2341 					}
2342 				}
2343 			}
2344 			if (!next_to_road) {
2345 				return false;
2346 			}
2347 
2348 			// try to built a little away from previous ones
2349 			if (big_city  &&  find_dist_next_special(pos) < w + h + welt->get_settings().get_special_building_distance()  ) {
2350 				return false;
2351 			}
2352 			return true;
2353 		}
2354 };
2355 
2356 
check_bau_spezial(bool new_town)2357 void stadt_t::check_bau_spezial(bool new_town)
2358 {
2359 	// tourist attraction buildings
2360 	const building_desc_t* desc = hausbauer_t::get_special( bev, building_desc_t::attraction_city, welt->get_timeline_year_month(), new_town, welt->get_climate(pos) );
2361 	if (desc != NULL) {
2362 		if (simrand(100) < (uint)desc->get_distribution_weight()) {
2363 
2364 			bool big_city = buildings.get_count() >= 10;
2365 			bool is_rotate = desc->get_all_layouts() > 1;
2366 			sint16 radius = koord_distance( get_rechtsunten(), get_linksoben() )/2 + 10;
2367 			// find place
2368 			koord best_pos = building_place_with_road_finder(welt, radius, big_city).find_place(pos, desc->get_x(), desc->get_y(), desc->get_allowed_climate_bits(), &is_rotate);
2369 
2370 			if (best_pos != koord::invalid) {
2371 				// then built it
2372 				int rotate = 0;
2373 				if (desc->get_all_layouts() > 1) {
2374 					rotate = (simrand(20) & 2) + is_rotate;
2375 				}
2376 				hausbauer_t::build( owner, welt->lookup_kartenboden(best_pos)->get_pos(), rotate, desc );
2377 				// tell the player, if not during initialization
2378 				if (!new_town) {
2379 					cbuffer_t buf;
2380 					buf.printf( translator::translate("To attract more tourists\n%s built\na %s\nwith the aid of\n%i tax payers."), get_name(), make_single_line_string(translator::translate(desc->get_name()), 2), get_einwohner());
2381 					welt->get_message()->add_message(buf, best_pos, message_t::city, CITY_KI, desc->get_tile(0)->get_background(0, 0, 0));
2382 				}
2383 			}
2384 		}
2385 	}
2386 
2387 	if ((bev & 511) == 0) {
2388 		// Build a monument
2389 		desc = hausbauer_t::get_random_monument(welt->get_timeline_year_month());
2390 		if (desc) {
2391 			koord total_size = koord(2 + desc->get_x(), 2 + desc->get_y());
2392 			sint16 radius = koord_distance( get_rechtsunten(), get_linksoben() )/2 + 10;
2393 			koord best_pos(monument_placefinder_t(welt, radius).find_place(pos, total_size.x, total_size.y, desc->get_allowed_climate_bits()));
2394 
2395 			if (best_pos != koord::invalid) {
2396 				// check if borders around the monument are inside the map limits
2397 				const bool pre_ok = welt->is_within_limits( koord(best_pos) - koord(1, 1) )  &&  \
2398 					welt->is_within_limits( koord(best_pos) + total_size + koord(1, 1) );
2399 				if (!pre_ok){
2400 					return;
2401 				}
2402 
2403 				bool ok=false;
2404 
2405 				// We build the monument only if there is already at least one road
2406 				for (int i = 0; i < total_size.x && !ok; i++) {
2407 					ok = ok ||
2408 						welt->access(best_pos + koord(i, -1))->get_kartenboden()->hat_weg(road_wt) ||
2409 						welt->access(best_pos + koord(i, total_size.y))->get_kartenboden()->hat_weg(road_wt);
2410 				}
2411 				for (int i = 0; i < total_size.y && !ok; i++) {
2412 					ok = ok ||
2413 						welt->access(best_pos + koord(total_size.x, i))->get_kartenboden()->hat_weg(road_wt) ||
2414 						welt->access(best_pos + koord(-1, i))->get_kartenboden()->hat_weg(road_wt);
2415 				}
2416 				if (ok) {
2417 					// build roads around the monument
2418 					sint16 h=welt->lookup_kartenboden(best_pos)->get_hoehe();
2419 					for (int i = 0; i < total_size.y; i++) {
2420 						// only build in same height and not on slopes...
2421 						const grund_t *gr = welt->lookup_kartenboden(best_pos + koord(0, i));
2422 						if(gr->get_hoehe()==h  &&  gr->get_grund_hang()==0) {
2423 							build_road(best_pos + koord(0, i), NULL, true);
2424 						}
2425 						gr = welt->lookup_kartenboden(best_pos + koord(total_size.x - 1, i));
2426 						if(gr->get_hoehe()==h  &&  gr->get_grund_hang()==0) {
2427 							build_road(best_pos + koord(total_size.x - 1, i), NULL, true);
2428 						}
2429 					}
2430 					for (int i = 0; i < total_size.x; i++) {
2431 						// only build in same height and not on slopes...
2432 						const grund_t *gr = welt->lookup_kartenboden(best_pos + koord(i, 0));
2433 						if(gr->get_hoehe()==h  &&  gr->get_grund_hang()==0) {
2434 							build_road(best_pos + koord(i, 0), NULL, true);
2435 						}
2436 						gr = welt->lookup_kartenboden(best_pos + koord(i, total_size.y - 1));
2437 						if(gr->get_hoehe()==h  &&  gr->get_grund_hang()==0) {
2438 							build_road(best_pos + koord(i, total_size.y - 1), NULL, true);
2439 						}
2440 					}
2441 					// and then build it
2442 					const gebaeude_t* gb = hausbauer_t::build(owner, welt->lookup_kartenboden(best_pos + koord(1, 1))->get_pos(), 0, desc);
2443 					hausbauer_t::monument_erected(desc);
2444 					add_gebaeude_to_stadt(gb);
2445 					// tell the player, if not during initialization
2446 					if (!new_town) {
2447 						cbuffer_t buf;
2448 						buf.printf( translator::translate("With a big festival\n%s built\na new monument.\n%i citicens rejoiced."), get_name(), get_einwohner() );
2449 						welt->get_message()->add_message(buf, best_pos + koord(1, 1), message_t::city, CITY_KI, desc->get_tile(0)->get_background(0, 0, 0));
2450 					}
2451 				}
2452 			}
2453 		}
2454 	}
2455 }
2456 
2457 
check_bau_townhall(bool new_town)2458 void stadt_t::check_bau_townhall(bool new_town)
2459 {
2460 	const building_desc_t* desc = hausbauer_t::get_special( has_townhall ? bev : 0, building_desc_t::townhall, welt->get_timeline_year_month(), (bev == 0) || !has_townhall, welt->get_climate(pos) );
2461 	if(desc != NULL) {
2462 		grund_t* gr = welt->lookup_kartenboden(pos);
2463 		gebaeude_t* gb = obj_cast<gebaeude_t>(gr->first_obj());
2464 		bool neugruendung = !has_townhall ||  !gb || !gb->is_townhall();
2465 		bool umziehen = !neugruendung;
2466 		koord alte_str(koord::invalid);
2467 		koord best_pos(pos);
2468 		koord k;
2469 		int old_layout(0);
2470 
2471 		DBG_MESSAGE("check_bau_townhall()", "bev=%d, new=%d name=%s", bev, neugruendung, name.c_str());
2472 
2473 		if(  umziehen  ) {
2474 
2475 			const building_desc_t* desc_old = gb->get_tile()->get_desc();
2476 			if (desc_old->get_level() == desc->get_level()) {
2477 				DBG_MESSAGE("check_bau_townhall()", "town hall already ok.");
2478 				return; // Rathaus ist schon okay
2479 			}
2480 			old_layout = gb->get_tile()->get_layout();
2481 			const sint8 old_z = gb->get_pos().z;
2482 			koord pos_alt = best_pos = gr->get_pos().get_2d() - gb->get_tile()->get_offset();
2483 			// guess layout for broken townhall's
2484 			if(desc_old->get_x() != desc_old->get_y()  &&  desc_old->get_all_layouts()==1) {
2485 				// test all layouts
2486 				koord corner_offset(desc_old->get_x()-1, desc_old->get_y()-1);
2487 				for(uint8 test_layout = 0; test_layout<4; test_layout++) {
2488 					// is there a part of our townhall in this corner
2489 					grund_t *gr0 = welt->lookup_kartenboden(pos + corner_offset);
2490 					gebaeude_t const* const gb0 = gr0 ? obj_cast<gebaeude_t>(gr0->first_obj()) : 0;
2491 					if (gb0  &&  gb0->is_townhall()  &&  gb0->get_tile()->get_desc()==desc_old  &&  gb0->get_stadt()==this) {
2492 						old_layout = test_layout;
2493 						pos_alt = best_pos = gr->get_pos().get_2d() + koord(test_layout%3!=0 ? corner_offset.x : 0, test_layout&2 ? corner_offset.y : 0);
2494 						break;
2495 					}
2496 					corner_offset = koord(-corner_offset.y, corner_offset.x);
2497 				}
2498 			}
2499 			koord groesse_alt = desc_old->get_size(old_layout);
2500 
2501 			// do we need to move
2502 			if(  old_layout<=desc->get_all_layouts()  &&  desc->get_x(old_layout) <= groesse_alt.x  &&  desc->get_y(old_layout) <= groesse_alt.y  ) {
2503 				// no, the size is ok
2504 				// still need to check whether the existing townhall is not broken in some way
2505 				umziehen = false;
2506 				for(k.y = 0; k.y < groesse_alt.y; k.y ++) {
2507 					for(k.x = 0; k.x < groesse_alt.x; k.x ++) {
2508 						// for buildings with holes the hole could be on a different height ->gr==NULL
2509 						bool ok = false;
2510 						if (grund_t *gr = welt->lookup_kartenboden(k + pos)) {
2511 							if(gebaeude_t *gb_part = gr->find<gebaeude_t>()) {
2512 								// there may be buildings with holes, so we only remove our building!
2513 								if(gb_part->get_tile()  ==  desc_old->get_tile(old_layout, k.x, k.y)) {
2514 									ok = true;
2515 								}
2516 							}
2517 						}
2518 						umziehen |= !ok;
2519 					}
2520 				}
2521 				if (!umziehen) {
2522 					// correct position if new townhall is smaller than old
2523 					if(  old_layout == 0  ) {
2524 						best_pos.y -= desc->get_y(old_layout) - groesse_alt.y;
2525 					}
2526 					else if (old_layout == 1) {
2527 						best_pos.x -= desc->get_x(old_layout) - groesse_alt.x;
2528 					}
2529 				}
2530 			}
2531 			if (umziehen) {
2532 				// we need to built a new road, thus we will use the old as a starting point (if found)
2533 				if (welt->lookup_kartenboden(townhall_road)  &&  welt->lookup_kartenboden(townhall_road)->hat_weg(road_wt)) {
2534 					alte_str = townhall_road;
2535 				}
2536 				else {
2537 					koord k = pos + (old_layout==0 ? koord(0, desc_old->get_y()) : koord(desc_old->get_x(),0) );
2538 					if (welt->lookup_kartenboden(k)->hat_weg(road_wt)) {
2539 						alte_str = k;
2540 					}
2541 					else {
2542 						k = pos - (old_layout==0 ? koord(0, desc_old->get_y()) : koord(desc_old->get_x(),0) );
2543 						if (welt->lookup_kartenboden(k)->hat_weg(road_wt)) {
2544 							alte_str = k;
2545 						}
2546 					}
2547 				}
2548 			}
2549 
2550 			// remove old townhall
2551 			if(  gb  ) {
2552 				DBG_MESSAGE("stadt_t::check_bau_townhall()", "delete townhall at (%s)", pos_alt.get_str());
2553 				hausbauer_t::remove(NULL, gb);
2554 			}
2555 
2556 			// replace old space by normal houses level 0 (must be 1x1!)
2557 			if(  umziehen  ) {
2558 				for (k.x = 0; k.x < groesse_alt.x; k.x++) {
2559 					for (k.y = 0; k.y < groesse_alt.y; k.y++) {
2560 						// we iterate over all tiles, since the townhalls are allowed sizes bigger than 1x1
2561 						const koord pos = pos_alt + k;
2562 						gr = welt->lookup_kartenboden(pos);
2563 						if (gr  &&  gr->ist_natur() &&  gr->kann_alle_obj_entfernen(NULL) == NULL  &&
2564 							  (  gr->get_grund_hang() == slope_t::flat  ||  welt->lookup(koord3d(k, welt->max_hgt(k))) == NULL  ) ) {
2565 							DBG_MESSAGE("stadt_t::check_bau_townhall()", "fill empty spot at (%s)", pos.get_str());
2566 							build_city_building(pos);
2567 						}
2568 					}
2569 				}
2570 			}
2571 			else {
2572 				// make tiles flat, hausbauer_t::remove could have set some natural slopes
2573 				for(  k.x = 0;  k.x < desc->get_x(old_layout);  k.x++  ) {
2574 					for(  k.y = 0;  k.y < desc->get_y(old_layout);  k.y++  ) {
2575 						gr = welt->lookup_kartenboden(best_pos + k);
2576 						if(  gr  &&  gr->ist_natur()  ) {
2577 							// make flat and use right height
2578 							gr->set_grund_hang(slope_t::flat);
2579 							gr->set_pos( koord3d( best_pos + k, old_z ) );
2580 						}
2581 					}
2582 				}
2583 			}
2584 		}
2585 
2586 		// Now built the new townhall (remember old orientation)
2587 		int layout = umziehen || neugruendung ? simrand(desc->get_all_layouts()) : old_layout % desc->get_all_layouts();
2588 		// on which side should we place the road?
2589 		uint8 dir;
2590 		// offset of building within searched place, start and end of road
2591 		koord offset(0,0), road0(0,0),road1(0,0);
2592 		dir = ribi_t::layout_to_ribi[layout & 3];
2593 		switch(dir) {
2594 			case ribi_t::east:
2595 				road0.x = desc->get_x(layout);
2596 				road1.x = desc->get_x(layout);
2597 				road1.y = desc->get_y(layout)-1;
2598 				break;
2599 			case ribi_t::north:
2600 				road1.x = desc->get_x(layout)-1;
2601 				if (neugruendung || umziehen) {
2602 					offset.y = 1;
2603 				}
2604 				else {
2605 					// offset already included in position of old townhall
2606 					road0.y=-1;
2607 					road1.y=-1;
2608 				}
2609 				break;
2610 			case ribi_t::west:
2611 				road1.y = desc->get_y(layout)-1;
2612 				if (neugruendung || umziehen) {
2613 					offset.x = 1;
2614 				}
2615 				else {
2616 					// offset already included in in position of old townhall
2617 					road0.x=-1;
2618 					road1.x=-1;
2619 				}
2620 				break;
2621 			case ribi_t::south:
2622 			default:
2623 				road0.y = desc->get_y(layout);
2624 				road1.x = desc->get_x(layout)-1;
2625 				road1.y = desc->get_y(layout);
2626 		}
2627 		if (neugruendung || umziehen) {
2628 			best_pos = townhall_placefinder_t(welt, dir).find_place(pos, desc->get_x(layout) + (dir & ribi_t::eastwest ? 1 : 0), desc->get_y(layout) + (dir & ribi_t::northsouth ? 1 : 0), desc->get_allowed_climate_bits());
2629 		}
2630 		// check, if the was something found
2631 		if(best_pos==koord::invalid) {
2632 			dbg->error( "stadt_t::check_bau_townhall", "no better position found!" );
2633 			return;
2634 		}
2635 		gebaeude_t const* const new_gb = hausbauer_t::build(owner, welt->lookup_kartenboden(best_pos + offset)->get_pos(), layout, desc);
2636 		DBG_MESSAGE("new townhall", "use layout=%i", layout);
2637 		add_gebaeude_to_stadt(new_gb);
2638 		// sets has_townhall to true
2639 		DBG_MESSAGE("stadt_t::check_bau_townhall()", "add townhall (bev=%i, ptr=%p)", buildings.get_sum_weight(),welt->lookup_kartenboden(best_pos)->first_obj());
2640 
2641 		// if not during initialization
2642 		if (!new_town) {
2643 			cbuffer_t buf;
2644 			buf.printf(translator::translate("%s wasted\nyour money with a\nnew townhall\nwhen it reached\n%i inhabitants."), name.c_str(), get_einwohner());
2645 			welt->get_message()->add_message(buf, best_pos, message_t::city, CITY_KI, desc->get_tile(layout, 0, 0)->get_background(0, 0, 0));
2646 		}
2647 		else {
2648 			welt->lookup_kartenboden(best_pos + offset)->set_text( name );
2649 		}
2650 
2651 		if (neugruendung || umziehen) {
2652 			// build the road in front of the townhall
2653 			if (road0!=road1) {
2654 				way_builder_t bauigel(NULL);
2655 				bauigel.init_builder(way_builder_t::strasse, welt->get_city_road(), NULL, NULL);
2656 				bauigel.set_build_sidewalk(true);
2657 				bauigel.calc_straight_route(welt->lookup_kartenboden(best_pos + road0)->get_pos(), welt->lookup_kartenboden(best_pos + road1)->get_pos());
2658 				bauigel.build();
2659 			}
2660 			else {
2661 				build_road(best_pos + road0, NULL, true);
2662 			}
2663 			townhall_road = best_pos + road0;
2664 		}
2665 		if (umziehen  &&  alte_str != koord::invalid) {
2666 			// Strasse vom ehemaligen Rathaus zum neuen verlegen.
2667 			way_builder_t bauer(NULL);
2668 			bauer.init_builder(way_builder_t::strasse | way_builder_t::terraform_flag, welt->get_city_road());
2669 			bauer.calc_route(welt->lookup_kartenboden(alte_str)->get_pos(), welt->lookup_kartenboden(townhall_road)->get_pos());
2670 			bauer.build();
2671 		}
2672 		else if (neugruendung) {
2673 			lo = best_pos+offset - koord(2, 2);
2674 			ur = best_pos+offset + koord(desc->get_x(layout), desc->get_y(layout)) + koord(2, 2);
2675 		}
2676 		const koord new_pos = best_pos + offset;
2677 		if(  pos!=new_pos  ) {
2678 			// update position (where the name is)
2679 			welt->lookup_kartenboden(pos)->set_text( NULL );
2680 			pos = new_pos;
2681 			welt->lookup_kartenboden(pos)->set_text( name );
2682 		}
2683 	}
2684 }
2685 
2686 
2687 /* eventually adds a new industry
2688  * so with growing number of inhabitants the industry grows
2689  * @date 12.1.05
2690  * @author prissi
2691  */
check_bau_factory(bool new_town)2692 void stadt_t::check_bau_factory(bool new_town)
2693 {
2694 	uint32 const inc = welt->get_settings().get_industry_increase_every();
2695 	if(  !new_town && inc > 0  &&  bev % inc == 0  ) {
2696 		uint32 const div = bev / inc;
2697 		for( uint8 i = 0; i < 8; i++  ) {
2698 			if(  div == (1u<<i)  ) {
2699 				DBG_MESSAGE("stadt_t::check_bau_factory", "adding new industry at %i inhabitants.", get_einwohner());
2700 				factory_builder_t::increase_industry_density( true );
2701 			}
2702 		}
2703 	}
2704 }
2705 
2706 
2707 // find out, what building matches best
bewerte_res_com_ind(const koord pos,int & ind_score,int & com_score,int & res_score)2708 void stadt_t::bewerte_res_com_ind(const koord pos, int &ind_score, int &com_score, int &res_score)
2709 {
2710 	koord k;
2711 
2712 	ind_score = ind_start_score;
2713 	com_score = com_start_score;
2714 	res_score = res_start_score;
2715 
2716 	for (k.y = pos.y - 2; k.y <= pos.y + 2; k.y++) {
2717 		for (k.x = pos.x - 2; k.x <= pos.x + 2; k.x++) {
2718 
2719 			building_desc_t::btype t = building_desc_t::unknown;
2720 			if (const grund_t* gr = welt->lookup_kartenboden(k)) {
2721 				if (gebaeude_t const* const gb = obj_cast<gebaeude_t>(gr->first_obj())) {
2722 					t = gb->get_tile()->get_desc()->get_type();
2723 				}
2724 			}
2725 
2726 			int i = -1;
2727 			switch(t) {
2728 				case building_desc_t::city_res: i = 0; break;
2729 				case building_desc_t::city_com: i = 1; break;
2730 				case building_desc_t::city_ind: i = 2; break;
2731 				default: ;
2732 			}
2733 			if (i >= 0) {
2734 				ind_score += ind_neighbour_score[i];
2735 				com_score += com_neighbour_score[i];
2736 				res_score += res_neighbour_score[i];
2737 			}
2738 		}
2739 	}
2740 }
2741 
2742 
2743 // return the eight neighbors:
2744 // orthogonal before diagonal
2745 static koord const neighbors[] = {
2746 	koord( 0,  1),
2747 	koord( 1,  0),
2748 	koord( 0, -1),
2749 	koord(-1,  0),
2750 	// now the diagonals
2751 	koord( 1,  1),
2752 	koord( 1, -1),
2753 	koord(-1,  1),
2754 	koord(-1, -1)
2755 };
2756 
2757 static koord const area3x3[] = {
2758 	koord( 0, 1),  //  1x2
2759 	koord( 1, 0),  //  2x1
2760 	koord( 1, 1),  //  2x2
2761 	koord( 2, 0),  //  3x1
2762 	koord( 2, 1),  //  3x2
2763 	koord( 0, 2),  //  1x3
2764 	koord( 2, 2)   // 3x3
2765 };
2766 
2767 // updates one surrounding road with current city road
update_city_street(koord pos)2768 bool update_city_street(koord pos)
2769 {
2770 // !!! We should take the bulding size into consideration, missing!!!
2771 	const way_desc_t* cr = world()->get_city_road();
2772 	for(  int i=0;  i<8;  i++  ) {
2773 		if(  grund_t *gr = world()->lookup_kartenboden(pos+neighbors[i])  ) {
2774 			if(  weg_t* const weg = gr->get_weg(road_wt)  ) {
2775 				// Check if any changes are needed.
2776 				if(  !weg->hat_gehweg()  ||  weg->get_desc() != cr  ) {
2777 					player_t *sp = weg->get_owner();
2778 					if(  sp  ){
2779 						player_t::add_maintenance(sp, -weg->get_desc()->get_maintenance(), road_wt);
2780 						weg->set_owner(NULL); // make public
2781 					}
2782 					weg->set_gehweg(true);
2783 					weg->set_desc(cr);
2784 					gr->calc_image();
2785 					minimap_t::get_instance()->calc_map_pixel(pos+neighbors[i]);
2786 					return true;	// update only one road per renovation
2787 				}
2788 			}
2789 		}
2790 	}
2791 	return false;
2792 }
2793 
2794 
2795 // return layout
2796 #define CHECK_NEIGHBOUR (128)
2797 static int const building_layout[] = { CHECK_NEIGHBOUR | 0, 0, 1, 4, 2, 0, 5, CHECK_NEIGHBOUR | 1, 3, 7, 1, CHECK_NEIGHBOUR | 0, 6, CHECK_NEIGHBOUR | 3, CHECK_NEIGHBOUR | 2, CHECK_NEIGHBOUR | 0 };
2798 
2799 
2800 // calculates the "best" oreintation of a citybuilding
orient_city_building(const koord k,const building_desc_t * h,koord maxarea)2801 int stadt_t::orient_city_building(const koord k, const building_desc_t *h, koord maxarea )
2802 {
2803 	/*******************************************************
2804 	* these are the layout possible for city buildings
2805 	********************************************************
2806 	dims=1,1,1
2807 	+---+
2808 	|000|
2809 	|0 0|
2810 	|000|
2811 	+---+
2812 	dims=1,1,2
2813 	+---+
2814 	|001|
2815 	|1 1|
2816 	|100|
2817 	+---+
2818 	dims=1,1,4
2819 	+---+
2820 	|221|
2821 	|3 1|
2822 	|300|
2823 	+---+
2824 	dims=1,1,8
2825 	+---+
2826 	|625|
2827 	|3 1|
2828 	|704|
2829 	+---+
2830 	********************************************************/
2831 
2832 	// we have something to built here ...
2833 	if(  h == NULL  ) {
2834 		return -1;
2835 	}
2836 
2837 	// old, highly sophisticated routines for 1x1 buildings
2838 	if(  h->get_x()*h->get_y()==1  ) {
2839 		if(  grund_t *gr = welt->lookup_kartenboden(k)  ) {
2840 			int rotation = 0;
2841 			int max_layout = h->get_all_layouts()-1;
2842 			if(  max_layout  ) {
2843 				// check for pavement
2844 				int streetdir = 0;
2845 				for(  int i = 0;  i < 4;  i++  ) {
2846 					// Neighbors goes through these in 'preferred' order, orthogonal first
2847 					gr = welt->lookup_kartenboden(k + neighbors[i]);
2848 					if(  gr  &&  gr->get_weg_hang() == gr->get_grund_hang()  &&  gr->hat_weg(road_wt)  ){
2849 						streetdir += (1 << i);
2850 					}
2851 				}
2852 				// not completely unique layout, see if any of the neighbouring building gives a hint
2853 				rotation = building_layout[streetdir] & ~CHECK_NEIGHBOUR;
2854 				// for four rotation stop here ...
2855 				if(  max_layout<7  ) {
2856 					return rotation & max_layout;
2857 				}
2858 				// now this is an eight roation building, so we must put in more effort
2859 				bool unique_orientation = !(building_layout[streetdir] & CHECK_NEIGHBOUR);
2860 				if(  !unique_orientation  ) {
2861 					// no unique answer, check nearby buildings (more likely to fail)
2862 					int gb_dir = 0;
2863 					for(  int i = 0;  i < 4;  i++  ) {
2864 						// look for adjacent buildings
2865 						gr = welt->lookup_kartenboden(k + neighbors[i]);
2866 						if(  gr  &&  gr->get_typ()==grund_t::fundament  ){
2867 							if(  gr->find<gebaeude_t>()  ) {
2868 								gb_dir |= (1<<i);
2869 							}
2870 						}
2871 					}
2872 					// lets hope this gives an unique answer
2873 					static uint8 gb_dir_to_layout[16] = { CHECK_NEIGHBOUR, 1, 0, 6, 1, 1, 7, CHECK_NEIGHBOUR, 0, 5, 0, CHECK_NEIGHBOUR, 4, CHECK_NEIGHBOUR, CHECK_NEIGHBOUR, CHECK_NEIGHBOUR };
2874 					if(  gb_dir_to_layout[gb_dir] == CHECK_NEIGHBOUR  ) {
2875 						return rotation;
2876 					}
2877 					// ok our answer is unique, now we just check for left and right via street nearby
2878 					rotation = gb_dir_to_layout[gb_dir];
2879 					if(  rotation<2  ) {
2880 						// check on which side is the road
2881 						if(  streetdir & 0x0C  ) {
2882 							return rotation + 2;
2883 						}
2884 					}
2885 				}
2886 			}
2887 			return rotation;
2888 		}
2889 		return -1;
2890 	}
2891 
2892 	// if we arrive here, we have a multitile building
2893 	if(  grund_t *gr = welt->lookup_kartenboden(k)  ) {
2894 		int rotation = -1;
2895 		int max_layout = h->get_all_layouts()-1;
2896 		if(  max_layout  ) {
2897 
2898 			// we counting the streetiles, but asymmetric buildings will have an uneven number; we init with negative width
2899 			int streetdir[4];
2900 			for(  int i = 0;  i < 4;  i++  ) {
2901 				streetdir[i] = -h->get_x(i&1);
2902 			}
2903 			int roads_found = 0;
2904 
2905 			// now just counting street tiles north/south of the house ...
2906 			sint16 extra_offset = h->get_y(0)-1;
2907 			for(  int offset = -1;  offset <= h->get_x(0);  offset++  ) {
2908 				gr = welt->lookup_kartenboden(k + koord(offset,1+extra_offset) );
2909 				if(  gr  &&  gr->hat_weg(road_wt)  ){
2910 					streetdir[0] ++;
2911 					roads_found ++;
2912 				}
2913 				gr = welt->lookup_kartenboden(k + koord(offset,-1) );
2914 				if(  gr  &&  gr->hat_weg(road_wt)  ){
2915 					streetdir[2] ++;
2916 					roads_found ++;
2917 				}
2918 			}
2919 			// ... and east/west
2920 			for(  int offset = -1;  offset <= h->get_x(1);  offset++  ) {
2921 				// Neighbors goes through these in 'preferred' order, orthogonal first
2922 				gr = welt->lookup_kartenboden(k + koord(1+extra_offset,offset) );
2923 				if(  gr  &&  gr->hat_weg(road_wt)  ){
2924 					streetdir[1] ++;
2925 					roads_found ++;
2926 				}
2927 				// Neighbors goes through these in 'preferred' order, orthogonal first
2928 				gr = welt->lookup_kartenboden(k + koord(-1,offset) );
2929 				if(  gr  &&  gr->hat_weg(road_wt)  ){
2930 					streetdir[3] ++;
2931 					roads_found ++;
2932 				}
2933 			}
2934 
2935 			// first, make sure we found some roads
2936 			if(  roads_found > 0  ) {
2937 
2938 				// now find the two sides with most streets around
2939 				int largest_dir_count = -9999, largest_2nd_count = -9999;
2940 				int largest_dir = -1, largest_2nd_dir = -1;
2941 				for(  int i=0;  i<4;  i++  ) {
2942 					if(  streetdir[i] > largest_dir_count  ) {
2943 						largest_dir_count = streetdir[i];
2944 						largest_dir = i;
2945 					}
2946 					else if(  streetdir[i] > largest_2nd_count  ) {
2947 						largest_2nd_dir = i;
2948 					}
2949 				}
2950 
2951 				// so we have two adjacent corners with the most roads
2952 				if(  max_layout > 3  &&  ((largest_2nd_dir-largest_dir)==1  ||  (largest_2nd_dir-largest_dir)==3)  ) {
2953 					// corner cases: only roads on two sides
2954 					if(  streetdir[0]<0  &&  streetdir[1]<0  ) {
2955 						rotation = 7;
2956 					}
2957 					else if(  streetdir[2]<0  &&  streetdir[3]<0  ) {
2958 						rotation = 4;
2959 					}
2960 					else if(  streetdir[3]<0  &&  streetdir[0]<0  ) {
2961 						rotation = 5;
2962 					}
2963 					else if(  streetdir[0]<0  &&  streetdir[1]<0  ) {
2964 						rotation = 6;
2965 					}
2966 					// some valid found?
2967 					if(  rotation >=0  &&  h->get_x(rotation) <= maxarea.x  &&  h->get_y(rotation) <= maxarea.y  ) {
2968 						return rotation;
2969 					}
2970 				}
2971 
2972 				// now we have to check right of it
2973 				if(  streetdir[(largest_dir+1)&3] == largest_dir_count  ) {
2974 					// but since we take the first, if the next two corner have the same street count, better rotate one further
2975 					if(  streetdir[(largest_dir+2)&3] == largest_dir_count  ) {
2976 						// both next corners same count
2977 						rotation = largest_dir+1;
2978 					}
2979 					else {
2980 						rotation = largest_dir;
2981 					}
2982 					rotation &= max_layout;
2983 				}
2984 				// and left of it
2985 				else if(  streetdir[(largest_dir+3)&3] == largest_dir_count  ) {
2986 					// but since we take the first, if the next two corner have the same street count, better rotate one further
2987 					if(  streetdir[(largest_dir+2)&3] == largest_dir_count  ) {
2988 						// both next corners same count
2989 						rotation = largest_dir+3;
2990 					}
2991 					else {
2992 						rotation = largest_dir;
2993 					}
2994 					rotation &= max_layout;
2995 				}
2996 				// this is the really only longest one
2997 				else {
2998 					rotation = largest_dir & max_layout;
2999 				}
3000 
3001 				// some valid found?
3002 				if(  rotation >= 0  &&  h->get_x(rotation) <= maxarea.x  &&  h->get_y(rotation) <= maxarea.y  ) {
3003 					return rotation;
3004 				}
3005 
3006 				return -1;
3007 			}
3008 
3009 			// no roads or not fitting
3010 			if(  roads_found == 0  ) {
3011 				bool even_ok = (maxarea.x <= h->get_x(0)  &&  maxarea.y <= h->get_y(0));
3012 				bool odd_ok = (maxarea.x <= h->get_x(1)  &&  maxarea.y <= h->get_y(1));
3013 
3014 				if(  even_ok  &&  odd_ok  ) {
3015 					// no roads at all and both rotations fit => random oreintation (but no corner)
3016 					return simrand(4) % max_layout;
3017 				}
3018 				else if(  even_ok  ) {
3019 					return (simrand(2)*2) % max_layout;
3020 				}
3021 				else if(  odd_ok  ) {
3022 					return (simrand(2)*2+1) % max_layout;
3023 				}
3024 				// nothing fits, should not happen!
3025 				assert(1);
3026 			}
3027 
3028 			// we have a preferred orientation, but it does not fit  => gave up
3029 			return -1;
3030 		}
3031 
3032 		// we landed here but maxlayout == 1, so we have only to test for fit
3033 		if(  maxarea.x <= h->get_x(0)  &&  maxarea.y <= h->get_y(0)  ) {
3034 			return 0;
3035 		}
3036 
3037 	}
3038 
3039 	return -1;
3040 }
3041 
3042 
build_city_building(const koord k)3043 void stadt_t::build_city_building(const koord k)
3044 {
3045 	grund_t* gr = welt->lookup_kartenboden(k);
3046 
3047 	// Not building on ways (this was actually tested before be the cityrules), but you can construct manually
3048 	if(  !gr->ist_natur() ) {
3049 		return;
3050 	}
3051 	// test ownership of all objects that can block construction
3052 	for(  uint8 i = 0;  i < gr->obj_count();  i++  ) {
3053 		obj_t *const obj = gr->obj_bei(i);
3054 		if(  obj->is_deletable(NULL) != NULL  &&  obj->get_typ() != obj_t::pillar  ) {
3055 			return;
3056 		}
3057 	}
3058 	// Refuse to build on a slope, when there is a ground right on top of it (=> the house would sit on the bridge then!)
3059 	if(  gr->get_grund_hang() != slope_t::flat  &&  welt->lookup(koord3d(k, welt->max_hgt(k))) != NULL  ) {
3060 		return;
3061 	}
3062 
3063 	// Divide unemployed by 4, because it counts towards commercial and industrial,
3064 	// and both of those count 'double' for population relative to residential.
3065 	int employment_wanted  = get_unemployed() / 4;
3066 	int housing_wanted = get_homeless();
3067 
3068 	int industrial_suitability, commercial_suitability, residential_suitability;
3069 	bewerte_res_com_ind(k, industrial_suitability, commercial_suitability, residential_suitability );
3070 
3071 	const int sum_industrial   = industrial_suitability  + employment_wanted;
3072 	const int sum_commercial = commercial_suitability  + employment_wanted;
3073 	const int sum_residential   = residential_suitability + housing_wanted;
3074 
3075 	// does the timeline allow this building?
3076 	const uint16 current_month = welt->get_timeline_year_month();
3077 	const climate cl = welt->get_climate(k);
3078 
3079 
3080 	// Run through orthogonal neighbors (only) looking for which cluster to build
3081 	// This is a bitmap -- up to 32 clustering types are allowed.
3082 	uint32 neighbor_building_clusters = 0;
3083 	uint8 area_level=0; // used to calculate the maximum size
3084 	sint8 zpos = gr->get_pos().z + slope_t::max_diff(gr->get_grund_hang());
3085 	for(  int i = 0;  i < 4;  i++  ) {
3086 		grund_t* gr = welt->lookup_kartenboden(k + neighbors[i]);
3087 		if(  gr  &&  gr->get_typ() == grund_t::fundament  &&  gr->obj_bei(0)->get_typ() == obj_t::gebaeude  ) {
3088 			// We have a building as a neighbor...
3089 			if(  gebaeude_t const* const gb = obj_cast<gebaeude_t>(gr->first_obj())  ) {
3090 				// We really have a building as a neighbor...
3091 				const building_desc_t* neighbor_building = gb->get_tile()->get_desc();
3092 				neighbor_building_clusters |= neighbor_building->get_clusters();
3093 				if(  gb->get_pos().z == zpos  &&  neighbor_building->get_x()*neighbor_building->get_y()==1  ) {
3094 					// also in right height and citybuilding, and (1x1) (so we don not tear down existing larger building, even if we can do that)
3095 					area_level |= (neighbor_building->is_city_building() << i);
3096 				}
3097 			}
3098 			else if(  gr->ist_natur()  &&  gr->get_pos().z+slope_t::max_diff(gr->get_grund_hang())==zpos  ) {
3099 				// we can of course also build on nature
3100 					area_level |= (1 << i);
3101 			}
3102 		}
3103 	}
3104 
3105 	// since the above test is only enough for 2x1 and 1x2, we must test more tiles, if we want larger
3106 	koord maxsize=koord(1,1);
3107 	switch(  area_level&3  ) {
3108 		case 3:
3109 			if(  hausbauer_t::get_largest_city_building_area() > 2  ) {
3110 				// now test the remaining tiles for even laregr size
3111 				for(  area_level=2;  area_level < 8;  area_level++  ) {
3112 					grund_t* gr = welt->lookup_kartenboden(k + area3x3[area_level]);
3113 					if(  gr  &&  gr->get_typ() == grund_t::fundament  &&  gr->obj_bei(0)->get_typ() == obj_t::gebaeude  ) {
3114 						// We have a building as a neighbor...
3115 						if(  gebaeude_t const* const testgb = obj_cast<gebaeude_t>(gr->first_obj())  ) {
3116 							// We really have a building as a neighbor...
3117 							const building_desc_t* neighbor_building = testgb->get_tile()->get_desc();
3118 							if(  testgb->get_pos().z == zpos  &&  neighbor_building->is_city_building()  &&  neighbor_building->get_x()*neighbor_building->get_y()==1  ) {
3119 								// also in right height and citybuilding
3120 								maxsize = area3x3[area_level]+koord(1,1);
3121 								continue;
3122 							}
3123 						}
3124 						else if(  gr->ist_natur()  &&  gr->get_pos().z+slope_t::max_diff(gr->get_grund_hang())==zpos  ) {
3125 							// we can of course also build on nature
3126 							maxsize = area3x3[area_level]+koord(1,1);
3127 							continue;
3128 						}
3129 					}
3130 					// we only reach here upon unsuitable ground
3131 					break;
3132 				}
3133 			}
3134 			break;
3135 		case 2:
3136 			maxsize = area3x3[1]+koord(1,1);
3137 			break;
3138 		case 1:
3139 			maxsize = area3x3[0]+koord(1,1);
3140 			break;
3141 		default:
3142 			break;
3143 	}
3144 
3145 	// Find a house to build
3146 	const building_desc_t* h = NULL;
3147 
3148 	if (sum_commercial > sum_industrial  &&  sum_commercial >= sum_residential) {
3149 		h = hausbauer_t::get_commercial(0, current_month, cl, neighbor_building_clusters, koord(1,1), maxsize);
3150 		if (h != NULL) {
3151 			arb += (h->get_level()+1) * 20;
3152 		}
3153 	}
3154 
3155 	if (h == NULL  &&  sum_industrial > sum_residential  &&  sum_industrial >= sum_commercial) {
3156 		h = hausbauer_t::get_industrial(0, current_month, cl, neighbor_building_clusters, koord(1,1), maxsize);
3157 		if (h != NULL) {
3158 			arb += (h->get_level()+1) * 20;
3159 		}
3160 	}
3161 
3162 	if (h == NULL  &&  sum_residential > sum_industrial  &&  sum_residential >= sum_commercial) {
3163 		h = hausbauer_t::get_residential(0, current_month, cl, neighbor_building_clusters, koord(1,1), maxsize);
3164 		if (h != NULL) {
3165 			// will be aligned next to a street
3166 			won += (h->get_level()+1) * 10;
3167 		}
3168 	}
3169 
3170 	// so we found at least one suitable building for this place
3171 	int rotation = orient_city_building( k, h, maxsize );
3172 	if(  rotation >= 0  ) {
3173 		const gebaeude_t* gb = hausbauer_t::build(NULL, welt->lookup_kartenboden(k)->get_pos(), rotation, h);
3174 		add_gebaeude_to_stadt(gb);
3175 	}
3176 	// to be extended for larger building ...
3177 	update_city_street(k);
3178 }
3179 
3180 
3181 
renovate_city_building(gebaeude_t * gb)3182 void stadt_t::renovate_city_building(gebaeude_t *gb)
3183 {
3184 	const building_desc_t::btype alt_typ = gb->get_tile()->get_desc()->get_type();
3185 	if(  !gb->is_city_building()  ) {
3186 		return; // only renovate res, com, ind
3187 	}
3188 
3189 	// Now we are sure that this is a city building
3190 	const building_desc_t *gb_desc = gb->get_tile()->get_desc();
3191 	const int level = gb_desc->get_level();
3192 
3193 	koord k = gb->get_pos().get_2d() - gb->get_tile()->get_offset();
3194 
3195 	// Divide unemployed by 4, because it counts towards commercial and industrial,
3196 	// and both of those count 'double' for population relative to residential.
3197 	const int employment_wanted  = get_unemployed() / 4;
3198 	const int housing_wanted = get_homeless() / 4;
3199 
3200 	int industrial_suitability, commercial_suitability, residential_suitability;
3201 	bewerte_res_com_ind(k, industrial_suitability, commercial_suitability, residential_suitability );
3202 
3203 	const int sum_industrial   = industrial_suitability  + employment_wanted;
3204 	const int sum_commercial = commercial_suitability  + employment_wanted;
3205 	const int sum_residential   = residential_suitability + housing_wanted;
3206 
3207 	// does the timeline allow this building?
3208 	const uint16 current_month = welt->get_timeline_year_month();
3209 	const climate cl = welt->get_climate( gb->get_pos().get_2d() );
3210 
3211 	// Run through orthogonal neighbors (only), and oneself  looking for which cluster to build
3212 	// This is a bitmap -- up to 32 clustering types are allowed.
3213 	uint32 neighbor_building_clusters = gb->get_tile()->get_desc()->get_clusters();
3214 	sint8 zpos = gb->get_pos().z;
3215 	koord minsize = gb->get_tile()->get_desc()->get_size(gb->get_tile()->get_layout());
3216 	for(  int i = 0;  i < 4;  i++  ) {
3217 		// since we handle buildings larger than (1x1) we add an offset
3218 		koord ktest = k + neighbors[i];
3219 		if( neighbors[i].x > 0 ) {
3220 			ktest.x += minsize.x - 1;
3221 		}
3222 		if( neighbors[i].y > 0 ) {
3223 			ktest.y += minsize.y - 1;
3224 		}
3225 		grund_t* gr = welt->lookup_kartenboden(ktest);
3226 		if(  gr  &&  gr->get_typ() == grund_t::fundament  &&  gr->obj_bei(0)->get_typ() == obj_t::gebaeude  ) {
3227 			// We have a building as a neighbor...
3228 			if(  gebaeude_t const* const testgb = obj_cast<gebaeude_t>(gr->first_obj())  ) {
3229 				// We really have a building as a neighbor...
3230 				const building_desc_t* neighbor_building = testgb->get_tile()->get_desc();
3231 				neighbor_building_clusters |= neighbor_building->get_clusters();
3232 			}
3233 		}
3234 	}
3235 
3236 	// now test the surrounding tiles for larger size
3237 	koord maxsize=minsize;
3238 	if(  hausbauer_t::get_largest_city_building_area() > 1  ) {
3239 		for(  int area_level=0;  area_level < 8;  area_level++  ) {
3240 			grund_t* gr = welt->lookup_kartenboden(k + area3x3[area_level]);
3241 			if(  gr  &&  gr->get_typ() == grund_t::fundament  &&  gr->obj_bei(0)->get_typ() == obj_t::gebaeude  ) {
3242 				// We have a building as a neighbor...
3243 				if(  gebaeude_t const* const testgb = obj_cast<gebaeude_t>(gr->first_obj())  ) {
3244 					// We really have a building as a neighbor...
3245 					const building_desc_t* neighbor_building = testgb->get_tile()->get_desc();
3246 					if(  gb->get_tile()->get_desc() == neighbor_building  &&  testgb->get_tile()->get_offset() == area3x3[area_level]  ) {
3247 						// part of same building
3248 						maxsize = area3x3[area_level]+koord(1,1);
3249 						continue;
3250 					}
3251 					if(  testgb->get_pos().z == zpos  &&  neighbor_building  &&  neighbor_building->get_x()*neighbor_building->get_y()==1  ) {
3252 						// also in right height and citybuilding
3253 						maxsize = area3x3[area_level]+koord(1,1);
3254 						continue;
3255 					}
3256 				}
3257 #if 0
3258 /* since we only replace tiles, natur is not allowed for the moment, but could be easily changed */
3259 				else if(  gr->ist_natur()  &&  gr->get_pos().z+slope_t::max_diff(gr->get_grund_hang())==zpos  ) {
3260 					// we can of course also build on nature
3261 					maxsize = area3x3[area_level]+koord(1,1);
3262 					continue;
3263 				}
3264 #endif
3265 			}
3266 			// we only reach here upon unsuitable ground
3267 			break;
3268 		}
3269 	}
3270 
3271 	building_desc_t::btype want_to_have = building_desc_t::unknown;
3272 	int sum = 0;
3273 
3274 	// try to build
3275 	const building_desc_t* h = NULL;
3276 	if (sum_commercial > sum_industrial && sum_commercial > sum_residential) {
3277 		// we must check, if we can really update to higher level ...
3278 		const int try_level = (alt_typ == building_desc_t::city_com ? level + 1 : level);
3279 		h = hausbauer_t::get_commercial(try_level, current_month, cl, neighbor_building_clusters, minsize, maxsize );
3280 		if(  h != NULL  &&  h->get_level() >= try_level  ) {
3281 			want_to_have = building_desc_t::city_com;
3282 			sum = sum_commercial;
3283 		}
3284 	}
3285 	// check for industry, also if we wanted com, but there was no com good enough ...
3286 	if(    (sum_industrial > sum_commercial  &&  sum_industrial > sum_residential)
3287       || (sum_commercial > sum_residential  &&  want_to_have == building_desc_t::unknown)  ) {
3288 		// we must check, if we can really update to higher level ...
3289 		const int try_level = (alt_typ == building_desc_t::city_ind ? level + 1 : level);
3290 		h = hausbauer_t::get_industrial(try_level , current_month, cl, neighbor_building_clusters, minsize, maxsize );
3291 		if(  h != NULL  &&  h->get_level() >= try_level  ) {
3292 			want_to_have = building_desc_t::city_ind;
3293 			sum = sum_industrial;
3294 		}
3295 	}
3296 	// check for residence
3297 	// (sum_wohnung>sum_industrie  &&  sum_wohnung>sum_gewerbe
3298 	if(  want_to_have == building_desc_t::unknown  ) {
3299 		// we must check, if we can really update to higher level ...
3300 		const int try_level = (alt_typ == building_desc_t::city_res ? level + 1 : level);
3301 		h = hausbauer_t::get_residential(try_level, current_month, cl, neighbor_building_clusters, minsize, maxsize );
3302 		if(  h != NULL  &&  h->get_level() >= try_level  ) {
3303 			want_to_have = building_desc_t::city_res;
3304 			sum = sum_residential;
3305 		}
3306 		else {
3307 			h = NULL;
3308 		}
3309 	}
3310 
3311 	if (alt_typ != want_to_have) {
3312 		sum -= level * 10;
3313 	}
3314 
3315 	// good enough to renovate, and we found a building?
3316 	if(  sum > 0  &&  h != NULL  ) {
3317 //		DBG_MESSAGE("stadt_t::renovate_city_building()", "renovation at %i,%i (%i level) of typ %i to typ %i with desire %i", k.x, k.y, alt_typ, want_to_have, sum);
3318 
3319 		// no renovation for now, if new is smaller
3320 		assert(  gb_desc->get_x()*gb_desc->get_y() <= h->get_x()*h->get_y()  );
3321 
3322 		int rotation = 0;
3323 		if(  h->get_all_layouts()>1  ) {
3324 
3325 			// only do this of symmetric of small enough building
3326 			if(  h->get_x()==h->get_y()  ||  (h->get_x()<maxsize.y  &&  h->get_x()<maxsize.x)  ) {
3327 				// check for pavement
3328 				int streetdir = 0;
3329 				for(  int i = 0;  i < 4;  i++  ) {
3330 					// Neighbors goes through these in 'preferred' order, orthogonal first
3331 					grund_t *gr = welt->lookup_kartenboden(k + neighbors[i]);
3332 					if(  gr  &&  gr->get_weg_hang() == gr->get_grund_hang()  &&  gr->hat_weg(road_wt)  ){
3333 						streetdir += (1 << i);
3334 					}
3335 				}
3336 				// not completely unique layout, see if any of the neighbouring building gives a hint
3337 				rotation = building_layout[streetdir] & ~CHECK_NEIGHBOUR;
3338 				bool unique_orientation = !(building_layout[streetdir] & CHECK_NEIGHBOUR);
3339 				// only streets in diagonal corners => make a house there in L direction
3340 				if(  !streetdir  ) {
3341 					int count = 0;
3342 					for(  int i = 4;  i < 8;  i++  ) {
3343 						// Neighbors goes through these in 'preferred' order, orthogonal first
3344 						grund_t *gr = welt->lookup_kartenboden(k + neighbors[i]);
3345 						if(  gr  &&  gr->get_weg_hang() == gr->get_grund_hang()  &&  gr->hat_weg(road_wt)  ) {
3346 							rotation = i;
3347 							count ++;
3348 						}
3349 					}
3350 					unique_orientation = (count==1);
3351 				}
3352 				if(  !unique_orientation  ) {
3353 					int max_layout = h->get_all_layouts()-1;
3354 					for(  int i = 0;  i < 4;  i++  ) {
3355 						// Neighbors goes through these in 'preferred' order, orthogonal first
3356 						grund_t *gr = welt->lookup_kartenboden(k + neighbors[i]);
3357 						if(  gr  &&  gr->get_typ()==grund_t::fundament  ){
3358 							if(  gebaeude_t *gb = gr->find<gebaeude_t>()  ) {
3359 								if(  gb->get_tile()->get_desc()->get_all_layouts() > max_layout  ) {
3360 									// so take the roation of the next bilding with similar or more rotations
3361 									rotation = gb->get_tile()->get_layout();
3362 									max_layout = gb->get_tile()->get_desc()->get_all_layouts();
3363 									if(  h->get_clusters() == 0  &&  gb->get_tile()->get_desc() == h  ) {
3364 										// we only renovate, if there is not an identical building (unless its a cluster)
3365 										return;
3366 									}
3367 								}
3368 							}
3369 						}
3370 					}
3371 				}
3372 			}
3373 			else {
3374 				// asymmetric building
3375 				rotation = (h->get_x(0)<=maxsize.x  &&  h->get_y(0)<=maxsize.y) ? 0 : 1;
3376 			}
3377 		}
3378 
3379 		// we only renovate, if there is not an identical building (unless its a cluster)
3380 		if(  !h->get_clusters() ) {
3381 			for( int i = 0; i < 8; i++ ) {
3382 				koord p = k;
3383 				p.x += neighbors[i].x > 0 ? h->get_x( rotation ) : neighbors[i].x;
3384 				p.y += neighbors[i].y > 0 ? h->get_y( rotation ) : neighbors[i].y;
3385 				grund_t *gr = welt->lookup_kartenboden(p);
3386 				if( gr  &&  gr->get_typ() == grund_t::fundament ) {
3387 					if( gebaeude_t *gb = gr->find<gebaeude_t>() ) {
3388 						if( gb->get_tile()->get_desc() == h ) {
3389 							// same building => do not renovate
3390 							return;
3391 						}
3392 					}
3393 				}
3394 			}
3395 		}
3396 
3397 		// ok now finally replace
3398 		for(  int x=0;  x<h->get_x(rotation);  x++  ) {
3399 			for(  int y=0;  y<h->get_y(rotation);  y++  ) {
3400 				koord kpos = k+koord(x,y);
3401 				grund_t *gr = welt->lookup_kartenboden(kpos);
3402 				gebaeude_t *oldgb = gr->find<gebaeude_t>();
3403 				switch(oldgb->get_tile()->get_desc()->get_type()) {
3404 					case building_desc_t::city_res: won -= level * 10; break;
3405 					case building_desc_t::city_com: arb -= level * 20; break;
3406 					case building_desc_t::city_ind: arb -= level * 20; break;
3407 					default: break;
3408 				}
3409 				// exchange building; try to face it to street in front
3410 				oldgb->mark_images_dirty();
3411 				oldgb->set_tile( h->get_tile(rotation, x, y), true );
3412 				welt->lookup_kartenboden(kpos)->calc_image();
3413 				update_gebaeude_from_stadt(oldgb);
3414 				update_city_street(kpos);
3415 				switch(h->get_type()) {
3416 					case building_desc_t::city_res: won += h->get_level() * 10; break;
3417 					case building_desc_t::city_com: arb += h->get_level() * 20; break;
3418 					case building_desc_t::city_ind: arb += h->get_level() * 20; break;
3419 					default: break;
3420 				}
3421 			}
3422 		}
3423 	}
3424 }
3425 
3426 
3427 #ifdef DESTINATION_CITYCARS
generate_private_cars(koord pos,koord target)3428 void stadt_t::generate_private_cars(koord pos, koord target)
3429 {
3430 	if (!private_car_t::list_empty()  &&  number_of_cars>0  ) {
3431 		koord k;
3432 		for (k.y = pos.y - 1; k.y <= pos.y + 1; k.y++) {
3433 			for (k.x = pos.x - 1; k.x <= pos.x + 1; k.x++) {
3434 				if(  grund_t* gr = welt->lookup_kartenboden(k) ) {
3435 					const weg_t* weg = gr->get_weg(road_wt);
3436 					if (weg != NULL && (
3437 								gr->get_weg_ribi_unmasked(road_wt) == ribi_t::northsouth ||
3438 								gr->get_weg_ribi_unmasked(road_wt) == ribi_t::eastwest
3439 							)) {
3440 						// already a car here => avoid congestion
3441 						if(gr->obj_bei(gr->get_top()-1)->is_moving()) {
3442 							continue;
3443 						}
3444 						private_car_t* vt = new private_car_t(gr, target);
3445 						gr->obj_add(vt);
3446 						welt->sync.add(vt);
3447 						city_history_month[0][HIST_CITYCARS] ++;
3448 						city_history_year[0][HIST_CITYCARS] ++;
3449 						number_of_cars --;
3450 						return;
3451 					}
3452 				}
3453 			}
3454 		}
3455 	}
3456 }
3457 #endif
3458 
3459 
3460 /**
3461  * baut ein Stueck Strasse
3462  *
3463  * @param k         Bauposition
3464  *
3465  * @author Hj. Malthaner, V. Meyer
3466  */
build_road(const koord k,player_t * player_,bool forced)3467 bool stadt_t::build_road(const koord k, player_t* player_, bool forced)
3468 {
3469 	grund_t* bd = welt->lookup_kartenboden(k);
3470 
3471 	if (bd->get_typ() != grund_t::boden) {
3472 		// not on water, monorails, foundations, tunnel or bridges
3473 		return false;
3474 	}
3475 
3476 	// we must not built on water or runways etc.
3477 	if(  bd->hat_wege()  &&  !bd->hat_weg(road_wt)  &&  !bd->hat_weg(track_wt)  ) {
3478 		return false;
3479 	}
3480 
3481 	// somebody else's things on it?
3482 	if(  bd->kann_alle_obj_entfernen(NULL)  ) {
3483 		return false;
3484 	}
3485 
3486 	// dwachs: If not able to built here, try to make artificial slope
3487 	slope_t::type slope = bd->get_grund_hang();
3488 	if (!slope_t::is_way(slope)) {
3489 		climate c = welt->get_climate(k);
3490 		if (welt->can_flatten_tile(NULL, k, bd->get_hoehe()+1, true)) {
3491 			welt->flatten_tile(NULL, k, bd->get_hoehe()+1, true);
3492 		}
3493 		else if(  bd->get_hoehe() > welt->get_water_hgt(k)  &&  welt->can_flatten_tile(NULL, k, bd->get_hoehe() )  ) {
3494 			welt->flatten_tile(NULL, k, bd->get_hoehe());
3495 		}
3496 		else {
3497 			return false;
3498 		}
3499 		// kartenboden may have changed - also ensure is land
3500 		bd = welt->lookup_kartenboden(k);
3501 		if (bd->get_typ() == grund_t::wasser) {
3502 			welt->set_water_hgt(k, bd->get_hoehe()-1);
3503 			welt->access(k)->correct_water();
3504 			welt->set_climate(k, c, true);
3505 			bd = welt->lookup_kartenboden(k);
3506 		}
3507 	}
3508 
3509 	// initially allow all possible directions ...
3510 	ribi_t::ribi allowed_dir = (bd->get_grund_hang() != slope_t::flat ? ribi_t::doubles(ribi_type(bd->get_weg_hang())) : (ribi_t::ribi)ribi_t::all);
3511 
3512 	// we have here a road: check for four corner stops
3513 	const gebaeude_t* gb = bd->find<gebaeude_t>();
3514 	if(gb) {
3515 		// nothing to connect
3516 		if(gb->get_tile()->get_desc()->get_all_layouts()==4) {
3517 			// single way
3518 			allowed_dir = ribi_t::layout_to_ribi[gb->get_tile()->get_layout()];
3519 		}
3520 		else if(gb->get_tile()->get_desc()->get_all_layouts()) {
3521 			// through way
3522 			allowed_dir = ribi_t::doubles( ribi_t::layout_to_ribi[gb->get_tile()->get_layout() & 1] );
3523 		}
3524 		else {
3525 			dbg->error("stadt_t::build_road()", "building on road with not directions at %i,%i?!?", k.x, k.y );
3526 		}
3527 	}
3528 
3529 	// we must not built on water or runways etc.
3530 	// only crossing or tramways allowed
3531 	if(  bd->hat_weg(track_wt)  ) {
3532 		weg_t* sch = bd->get_weg(track_wt);
3533 		if (sch->get_desc()->get_styp() != type_tram) {
3534 			// not a tramway
3535 			ribi_t::ribi r = sch->get_ribi_unmasked();
3536 			if (!ribi_t::is_straight(r)) {
3537 				// no building on crossings, curves, dead ends
3538 				return false;
3539 			}
3540 			// just the other directions are allowed
3541 			allowed_dir &= ~r;
3542 		}
3543 	}
3544 
3545 	// determine now, in which directions we can connect to another road
3546 	ribi_t::ribi connection_roads = ribi_t::none;
3547 	// add ribi's to connection_roads if possible
3548 	for (int r = 0; r < 4; r++) {
3549 		if (ribi_t::nsew[r] & allowed_dir) {
3550 			// now we have to check for several problems ...
3551 			grund_t* bd2;
3552 			if(bd->get_neighbour(bd2, invalid_wt, ribi_t::nsew[r])) {
3553 				if(bd2->get_typ()==grund_t::fundament  ||  bd2->get_typ()==grund_t::wasser) {
3554 					// not connecting to a building of course ...
3555 				}
3556 				else if (!bd2->ist_karten_boden()) {
3557 					// do not connect to elevated ways / bridges
3558 				}
3559 				else if (bd2->get_typ()==grund_t::tunnelboden  &&  ribi_t::nsew[r]!=ribi_type(bd2->get_grund_hang())) {
3560 					// not the correct slope
3561 				}
3562 				else if (bd2->get_typ()==grund_t::brueckenboden
3563 					&&  (bd2->get_grund_hang()==slope_t::flat  ?  ribi_t::nsew[r]!=ribi_type(bd2->get_weg_hang())
3564 					                                           :  ribi_t::backward(ribi_t::nsew[r])!=ribi_type(bd2->get_grund_hang()))) {
3565 					// not the correct slope
3566 				}
3567 				else if(bd2->hat_weg(road_wt)) {
3568 					const gebaeude_t* gb = bd2->find<gebaeude_t>();
3569 					if(gb) {
3570 						uint8 layouts = gb->get_tile()->get_desc()->get_all_layouts();
3571 						// nothing to connect
3572 						if(layouts==4) {
3573 							// single way
3574 							if(ribi_t::nsew[r]==ribi_t::backward(ribi_t::layout_to_ribi[gb->get_tile()->get_layout()])) {
3575 								// allowed ...
3576 								connection_roads |= ribi_t::nsew[r];
3577 							}
3578 						}
3579 						else if(layouts==2 || layouts==8 || layouts==16) {
3580 							// through way
3581 							if((ribi_t::doubles( ribi_t::layout_to_ribi[gb->get_tile()->get_layout() & 1] )&ribi_t::nsew[r])!=0) {
3582 								// allowed ...
3583 								connection_roads |= ribi_t::nsew[r];
3584 							}
3585 						}
3586 						else {
3587 							dbg->error("stadt_t::build_road()", "building on road with not directions at %i,%i?!?", k.x, k.y );
3588 						}
3589 					}
3590 					else if(bd2->get_depot()) {
3591 						// do not enter depots
3592 					}
3593 					else {
3594 						// check slopes
3595 						way_builder_t bauer( NULL );
3596 						bauer.init_builder( way_builder_t::strasse | way_builder_t::terraform_flag, welt->get_city_road() );
3597 						if(  bauer.check_slope( bd, bd2 )  ) {
3598 							// allowed ...
3599 							connection_roads |= ribi_t::nsew[r];
3600 						}
3601 					}
3602 				}
3603 			}
3604 		}
3605 	}
3606 
3607 	// now add the ribis to the other ways (if there)
3608 	for (int r = 0; r < 4; r++) {
3609 		if (ribi_t::nsew[r] & connection_roads) {
3610 			grund_t* bd2 = welt->lookup_kartenboden(k + koord::nsew[r]);
3611 			weg_t* w2 = bd2->get_weg(road_wt);
3612 			w2->ribi_add(ribi_t::backward(ribi_t::nsew[r]));
3613 			bd2->calc_image();
3614 			bd2->set_flag( grund_t::dirty );
3615 		}
3616 	}
3617 
3618 	if (connection_roads != ribi_t::none || forced) {
3619 
3620 		if (!bd->weg_erweitern(road_wt, connection_roads)) {
3621 			strasse_t* weg = new strasse_t();
3622 			// Hajo: city roads should not belong to any player => so we can ignore any construction costs ...
3623 			weg->set_desc(welt->get_city_road());
3624 			weg->set_gehweg(true);
3625 			bd->neuen_weg_bauen(weg, connection_roads, player_);
3626 			bd->calc_image();	// otherwise the
3627 		}
3628 		// check to bridge a river
3629 		if(ribi_t::is_single(connection_roads)) {
3630 			koord zv = koord(ribi_t::backward(connection_roads));
3631 			grund_t *bd_next = welt->lookup_kartenboden( k + zv );
3632 			if(bd_next  &&  (bd_next->is_water()  ||  (bd_next->hat_weg(water_wt)  &&  bd_next->get_weg(water_wt)->get_desc()->get_styp()== type_river))) {
3633 				// ok there is a river
3634 				const bridge_desc_t *bridge = bridge_builder_t::find_bridge(road_wt, welt->get_city_road()->get_topspeed(), welt->get_timeline_year_month() );
3635 				if(  bridge==NULL  ) {
3636 					// does not have a bridge available ...
3637 					return false;
3638 				}
3639 				const char *err = NULL;
3640 				sint8 bridge_height;
3641 				koord3d end = bridge_builder_t::find_end_pos(NULL, bd->get_pos(), zv, bridge, err, bridge_height, false);
3642 				if(err  ||   koord_distance( k, end.get_2d())>3) {
3643 					// try to find shortest possible
3644 					end = bridge_builder_t::find_end_pos(NULL, bd->get_pos(), zv, bridge, err, bridge_height, true);
3645 				}
3646 				if((err==NULL||*err == 0)  &&   koord_distance( k, end.get_2d())<=3  &&  welt->is_within_limits((end+zv).get_2d())) {
3647 					bridge_builder_t::build_bridge(NULL, bd->get_pos(), end, zv, bridge_height, bridge, welt->get_city_road());
3648 					// try to build one connecting piece of road
3649 					build_road( (end+zv).get_2d(), NULL, false);
3650 					// try to build a house near the bridge end
3651 					uint32 old_count = buildings.get_count();
3652 					for(uint8 i=0; i<lengthof(koord::neighbours)  &&  buildings.get_count() == old_count; i++) {
3653 						koord c(end.get_2d()+zv+koord::neighbours[i]);
3654 						if (welt->is_within_limits(c)) {
3655 							build_city_building(end.get_2d()+zv+koord::neighbours[i]);
3656 						}
3657 					}
3658 				}
3659 			}
3660 		}
3661 		return true;
3662 	}
3663 
3664 	return false;
3665 }
3666 
3667 
3668 // will check a single random pos in the city, then build will be called
build()3669 void stadt_t::build()
3670 {
3671 	const koord k(lo + koord::koord_random(ur.x - lo.x + 2,ur.y - lo.y + 2)-koord(1,1) );
3672 
3673 	// do not build on any border tile
3674 	if(  !welt->is_within_limits(k+koord(1,1))  ||  k.x<=0  ||  k.y<=0  ) {
3675 		return;
3676 	}
3677 
3678 	grund_t *gr = welt->lookup_kartenboden(k);
3679 	if(gr==NULL) {
3680 		return;
3681 	}
3682 
3683 	// checks only make sense on empty ground
3684 	if(gr->ist_natur()) {
3685 
3686 		// since only a single location is checked, we can stop after we have found a positive rule
3687 		best_strasse.reset(k);
3688 		const uint32 num_road_rules = road_rules.get_count();
3689 		uint32 offset = simrand(num_road_rules);	// start with random rule
3690 		for (uint32 i = 0; i < num_road_rules  &&  !best_strasse.found(); i++) {
3691 			uint32 rule = ( i+offset ) % num_road_rules;
3692 			bewerte_strasse(k, 8 + road_rules[rule]->chance, *road_rules[rule]);
3693 		}
3694 		// ok => then built road
3695 		if (best_strasse.found()) {
3696 			build_road(best_strasse.get_pos(), NULL, false);
3697 			INT_CHECK("simcity 1156");
3698 			return;
3699 		}
3700 
3701 		// not good for road => test for house
3702 
3703 		// since only a single location is checked, we can stop after we have found a positive rule
3704 		best_haus.reset(k);
3705 		const uint32 num_house_rules = house_rules.get_count();
3706 		offset = simrand(num_house_rules);	// start with random rule
3707 		for(  uint32 i = 0;  i < num_house_rules  &&  !best_haus.found();  i++  ) {
3708 			uint32 rule = ( i+offset ) % num_house_rules;
3709 			bewerte_haus(k, 8 + house_rules[rule]->chance, *house_rules[rule]);
3710 		}
3711 		// one rule applied?
3712 		if(  best_haus.found()  ) {
3713 			build_city_building(best_haus.get_pos());
3714 			INT_CHECK("simcity 1163");
3715 			return;
3716 		}
3717 
3718 	}
3719 
3720 	// renovation (only done when nothing matches a certain location
3721 	if(  !buildings.empty()  &&  simrand(100) <= renovation_percentage  ) {
3722 		// try to find a public owned building
3723 		for(  uint8 i=0;  i<4;  i++  ) {
3724 			gebaeude_t* const gb = pick_any(buildings);
3725 			if(  player_t::check_owner(gb->get_owner(),NULL)  ) {
3726 				renovate_city_building(gb);
3727 				break;
3728 			}
3729 		}
3730 		INT_CHECK("simcity 876");
3731 	}
3732 }
3733 
3734 
3735 // find suitable places for cities
random_place(const sint32 count,sint16 old_x,sint16 old_y)3736 vector_tpl<koord>* stadt_t::random_place(const sint32 count, sint16 old_x, sint16 old_y)
3737 {
3738 	int cl = 0;
3739 	for (int i = 0; i < MAX_CLIMATES; i++) {
3740 		if (hausbauer_t::get_special(0, building_desc_t::townhall, welt->get_timeline_year_month(), false, (climate)i)) {
3741 			cl |= (1 << i);
3742 		}
3743 	}
3744 	DBG_DEBUG("karte_t::init()", "get random places in climates %x", cl);
3745 	// search at least places which are 5x5 squares large
3746 	slist_tpl<koord>* list = welt->find_squares( 5, 5, (climate_bits)cl, old_x, old_y);
3747 	DBG_DEBUG("karte_t::init()", "found %i places", list->get_count());
3748 	vector_tpl<koord>* result = new vector_tpl<koord>(count);
3749 
3750 	// pre processed array: max 1 city from each square can be built
3751 	// each entry represents a cell of minimum_city_distance/2 length and width
3752 	const uint32 minimum_city_distance = welt->get_settings().get_minimum_city_distance();
3753 	const uint32 xmax = (2*welt->get_size().x)/minimum_city_distance+1;
3754 	const uint32 ymax = (2*welt->get_size().y)/minimum_city_distance+1;
3755 	array2d_tpl< vector_tpl<koord> > places(xmax, ymax);
3756 	while (!list->empty()) {
3757 		const koord k = list->remove_first();
3758 		places.at( (2*k.x)/minimum_city_distance, (2*k.y)/minimum_city_distance).append(k);
3759 	}
3760 	// weighted index vector into places array
3761 	weighted_vector_tpl<koord> index_to_places(xmax*ymax);
3762 	for(uint32 i=0; i<xmax; i++) {
3763 		for(uint32 j=0; j<ymax; j++) {
3764 			vector_tpl<koord> const& p = places.at(i, j);
3765 			if (!p.empty()) {
3766 				index_to_places.append(koord(i,j), p.get_count());
3767 			}
3768 		}
3769 	}
3770 	// post-processing array:
3771 	// each entry represents a cell of minimum_city_distance length and width
3772 	// to limit the search for neighboring cities
3773 	const uint32 xmax2 = welt->get_size().x/minimum_city_distance+1;
3774 	const uint32 ymax2 = welt->get_size().y/minimum_city_distance+1;
3775 	array2d_tpl< vector_tpl<koord> > result_places(xmax2, ymax2);
3776 
3777 	for (int i = 0; i < count; i++) {
3778 		// check distances of all cities to their respective neighbours
3779 		while (!index_to_places.empty()) {
3780 			// find a random cell
3781 			koord const ip = pick_any_weighted(index_to_places);
3782 			// remove this cell from index list
3783 			index_to_places.remove(ip);
3784 			vector_tpl<koord>& p = places.at(ip);
3785 			// get random place in the cell
3786 			if (p.empty()) continue;
3787 			uint32 const j = simrand(p.get_count());
3788 			koord  const k = p[j];
3789 
3790 			const koord k2mcd = koord( k.x/minimum_city_distance, k.y/minimum_city_distance );
3791 			for (sint32 i = k2mcd.x - 1; i <= k2mcd.x + 1; ++i) {
3792 				for (sint32 j = k2mcd.y - 1; j <= k2mcd.y + 1; ++j) {
3793 					if (i>=0 && i<(sint32)xmax2 && j>=0 && j<(sint32)ymax2) {
3794 						FOR(vector_tpl<koord>, const& l, result_places.at(i, j)) {
3795 							if (koord_distance(k, l) < minimum_city_distance) {
3796 								goto too_close;
3797 							}
3798 						}
3799 					}
3800 				}
3801 			}
3802 
3803 			// all cities are far enough => ok, find next place
3804 			result->append(k);
3805 			result_places.at(k2mcd).append(k);
3806 			break;
3807 
3808 too_close:
3809 			// remove the place from the list
3810 			p.remove_at(j);
3811 			// re-insert in index list with new weight
3812 			if (!p.empty()) {
3813 				index_to_places.append(ip, p.get_count());
3814 			}
3815 			// if we reached here, the city was not far enough => try again
3816 		}
3817 
3818 		if (index_to_places.empty() && i < count - 1) {
3819 			dbg->warning("stadt_t::random_place()", "Not enough places found!");
3820 			break;
3821 		}
3822 	}
3823 	delete list;
3824 
3825 	return result;
3826 }
3827