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 
8 /*
9  * Hauptklasse fuer Simutrans, Datenstruktur die alles Zusammenhaelt
10  * Hj. Malthaner, 1997
11  */
12 
13 #include <algorithm>
14 
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <math.h>
19 
20 #include <sys/stat.h>
21 
22 #include "simcity.h"
23 #include "simcolor.h"
24 #include "simconvoi.h"
25 #include "simdebug.h"
26 #include "simdepot.h"
27 #include "simfab.h"
28 #include "display/simgraph.h"
29 #include "display/viewport.h"
30 #include "simhalt.h"
31 #include "display/simimg.h"
32 #include "siminteraction.h"
33 #include "simintr.h"
34 #include "simio.h"
35 #include "simlinemgmt.h"
36 #include "simloadingscreen.h"
37 #include "simmenu.h"
38 #include "simmesg.h"
39 #include "simskin.h"
40 #include "simsound.h"
41 #include "simsys.h"
42 #include "simticker.h"
43 #include "simunits.h"
44 #include "simversion.h"
45 #include "display/simview.h"
46 #include "simtool.h"
47 #include "gui/simwin.h"
48 #include "simworld.h"
49 
50 #include "tpl/vector_tpl.h"
51 #include "tpl/binary_heap_tpl.h"
52 
53 #include "boden/boden.h"
54 #include "boden/wasser.h"
55 
56 #include "old_blockmanager.h"
57 #include "vehicle/simvehicle.h"
58 #include "vehicle/simroadtraffic.h"
59 #include "vehicle/simpeople.h"
60 #include "vehicle/movingobj.h"
61 #include "boden/wege/schiene.h"
62 
63 #include "obj/zeiger.h"
64 #include "obj/baum.h"
65 #include "obj/signal.h"
66 #include "obj/roadsign.h"
67 #include "obj/wayobj.h"
68 #include "obj/groundobj.h"
69 #include "obj/gebaeude.h"
70 #include "obj/leitung2.h"
71 
72 #include "gui/password_frame.h"
73 #include "gui/messagebox.h"
74 #include "gui/help_frame.h"
75 #include "gui/minimap.h"
76 #include "gui/player_frame_t.h"
77 
78 #include "network/network.h"
79 #include "network/network_file_transfer.h"
80 #include "network/network_socket_list.h"
81 #include "network/network_cmd_ingame.h"
82 #include "dataobj/height_map_loader.h"
83 #include "dataobj/ribi.h"
84 #include "dataobj/translator.h"
85 #include "dataobj/loadsave.h"
86 #include "dataobj/scenario.h"
87 #include "dataobj/settings.h"
88 #include "dataobj/environment.h"
89 #include "dataobj/powernet.h"
90 #include "dataobj/records.h"
91 
92 #include "utils/cbuffer_t.h"
93 #include "utils/simrandom.h"
94 #include "utils/simstring.h"
95 
96 #include "network/memory_rw.h"
97 
98 #include "bauer/brueckenbauer.h"
99 #include "bauer/tunnelbauer.h"
100 #include "bauer/fabrikbauer.h"
101 #include "bauer/wegbauer.h"
102 #include "bauer/hausbauer.h"
103 #include "bauer/vehikelbauer.h"
104 
105 #include "descriptor/ground_desc.h"
106 
107 #include "player/simplay.h"
108 #include "player/finance.h"
109 #include "player/ai_passenger.h"
110 #include "player/ai_goods.h"
111 #include "player/ai_scripted.h"
112 
113 // forward declaration - management of rotation for scripting
114 namespace script_api
115 {
116 	void rotate90();
117 	void new_world();
118 };
119 
120 // advance 201 ms per sync_step in fast forward mode
121 #define MAGIC_STEP (201)
122 
123 // frame per second for fast forward
124 #define FF_PPS (10)
125 
126 
127 static uint32 last_clients = -1;
128 static uint8 last_active_player_nr = 0;
129 static std::string last_network_game;
130 
131 karte_t* karte_t::world = NULL;
132 
133 stringhashtable_tpl<karte_t::missing_level_t>missing_pak_names;
134 
135 #ifdef MULTI_THREAD
136 #include "utils/simthread.h"
137 #include <semaphore.h>
138 
139 bool spawned_world_threads=false; // global job indicator array
140 static simthread_barrier_t world_barrier_start;
141 static simthread_barrier_t world_barrier_end;
142 
143 
144 // to start a thread
145 typedef struct{
146 	karte_t *welt;
147 	int thread_num;
148 	sint16 x_step;
149 	sint16 x_world_max;
150 	sint16 y_min;
151 	sint16 y_max;
152 	sem_t* wait_for_previous;
153 	sem_t* signal_to_next;
154 	xy_loop_func function;
155 	bool keep_running;
156 } world_thread_param_t;
157 
158 
159 // now the parameters
160 static world_thread_param_t world_thread_param[MAX_THREADS];
161 
world_xy_loop_thread(void * ptr)162 void *karte_t::world_xy_loop_thread(void *ptr)
163 {
164 	world_thread_param_t *param = reinterpret_cast<world_thread_param_t *>(ptr);
165 	while(true) {
166 		if(param->keep_running) {
167 			simthread_barrier_wait( &world_barrier_start );	// wait for all to start
168 		}
169 
170 		sint16 x_min = 0;
171 		sint16 x_max = param->x_step;
172 
173 		while(  x_min < param->x_world_max  ) {
174 			// wait for predecessor to finish its block
175 			if(  param->wait_for_previous  ) {
176 				sem_wait( param->wait_for_previous );
177 			}
178 			(param->welt->*(param->function))(x_min, x_max, param->y_min, param->y_max);
179 
180 			// signal to next thread that we finished one block
181 			if(  param->signal_to_next  ) {
182 				sem_post( param->signal_to_next );
183 			}
184 			x_min = x_max;
185 			x_max = min(x_max + param->x_step, param->x_world_max);
186 		}
187 
188 		if(param->keep_running) {
189 			simthread_barrier_wait( &world_barrier_end );	// wait for all to finish
190 		}
191 		else {
192 			return NULL;
193 		}
194 	}
195 
196 	return ptr;
197 }
198 #endif
199 
200 
world_xy_loop(xy_loop_func function,uint8 flags)201 void karte_t::world_xy_loop(xy_loop_func function, uint8 flags)
202 {
203 	const bool use_grids = (flags & GRIDS_FLAG) == GRIDS_FLAG;
204 	uint16 max_x = use_grids?(cached_grid_size.x+1):cached_grid_size.x;
205 	uint16 max_y = use_grids?(cached_grid_size.y+1):cached_grid_size.y;
206 #ifdef MULTI_THREAD
207 	set_random_mode( INTERACTIVE_RANDOM ); // do not allow simrand() here!
208 
209 	const bool sync_x_steps = (flags & SYNCX_FLAG) == SYNCX_FLAG;
210 
211 	// semaphores to synchronize progress in x direction
212 	sem_t sems[MAX_THREADS-1];
213 
214 	for(  int t = 0;  t < env_t::num_threads;  t++  ) {
215 		if(  sync_x_steps  &&  t < env_t::num_threads - 1  ) {
216 			sem_init(&sems[t], 0, 0);
217 		}
218 
219    		world_thread_param[t].welt = this;
220    		world_thread_param[t].thread_num = t;
221 		world_thread_param[t].x_step = min( 64, max_x / env_t::num_threads );
222 		world_thread_param[t].x_world_max = max_x;
223 		world_thread_param[t].y_min = (t * max_y) / env_t::num_threads;
224 		world_thread_param[t].y_max = ((t + 1) * max_y) / env_t::num_threads;
225 		world_thread_param[t].function = function;
226 
227 		world_thread_param[t].wait_for_previous = sync_x_steps  &&  t > 0 ? &sems[t-1] : NULL;
228 		world_thread_param[t].signal_to_next    = sync_x_steps  &&  t < env_t::num_threads - 1 ? &sems[t] : NULL;
229 
230 		world_thread_param[t].keep_running = t < env_t::num_threads - 1;
231 	}
232 
233 	if(  !spawned_world_threads  ) {
234 		// we can do the parallel display using posix threads ...
235 		pthread_t thread[MAX_THREADS];
236 		/* Initialize and set thread detached attribute */
237 		pthread_attr_t attr;
238 		pthread_attr_init( &attr );
239 		pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
240 		// init barrier
241 		simthread_barrier_init( &world_barrier_start, NULL, env_t::num_threads );
242 		simthread_barrier_init( &world_barrier_end, NULL, env_t::num_threads );
243 
244 		for(  int t = 0;  t < env_t::num_threads - 1;  t++  ) {
245 			if(  pthread_create( &thread[t], &attr, world_xy_loop_thread, (void *)&world_thread_param[t] )  ) {
246 				dbg->fatal( "karte_t::world_xy_loop()", "cannot multithread, error at thread #%i", t+1 );
247 				return;
248 			}
249 		}
250 		spawned_world_threads = true;
251 		pthread_attr_destroy( &attr );
252 	}
253 
254 	// and start processing
255 	simthread_barrier_wait( &world_barrier_start );
256 
257 	// the last we can run ourselves
258 	world_xy_loop_thread(&world_thread_param[env_t::num_threads-1]);
259 
260 	simthread_barrier_wait( &world_barrier_end );
261 
262 	// return from thread
263 	for(  int t = 0;  t < env_t::num_threads - 1;  t++  ) {
264 		if(  sync_x_steps  ) {
265 			sem_destroy(&sems[t]);
266 		}
267 	}
268 
269 	clear_random_mode( INTERACTIVE_RANDOM ); // do not allow simrand() here!
270 
271 #else
272 	// slow serial way of display
273 	(this->*function)( 0, max_x, 0, max_y );
274 #endif
275 }
276 
277 
rdwr(memory_rw_t * buffer)278 void checklist_t::rdwr(memory_rw_t *buffer)
279 {
280 	buffer->rdwr_long(random_seed);
281 	buffer->rdwr_short(halt_entry);
282 	buffer->rdwr_short(line_entry);
283 	buffer->rdwr_short(convoy_entry);
284 }
285 
286 
print(char * buffer,const char * entity) const287 int checklist_t::print(char *buffer, const char *entity) const
288 {
289 	return sprintf(buffer, "%s=[rand=%u halt=%u line=%u cnvy=%u] ", entity, random_seed, halt_entry, line_entry, convoy_entry);
290 }
291 
292 
recalc_season_snowline(bool set_pending)293 void karte_t::recalc_season_snowline(bool set_pending)
294 {
295 	static const sint8 mfactor[12] = { 99, 95, 80, 50, 25, 10, 0, 5, 20, 35, 65, 85 };
296 	static const uint8 month_to_season[12] = { 2, 2, 2, 3, 3, 0, 0, 0, 0, 1, 1, 2 };
297 
298 	// calculate snowline with day precision
299 	// use linear interpolation
300 	const sint32 ticks_this_month = get_ticks() & (karte_t::ticks_per_world_month - 1);
301 	const sint32 factor = mfactor[last_month] + (  ( (mfactor[(last_month + 1) % 12] - mfactor[last_month]) * (ticks_this_month >> 12) ) >> (karte_t::ticks_per_world_month_shift - 12) );
302 
303 	// just remember them
304 	const uint8 old_season = season;
305 	const sint16 old_snowline = snowline;
306 
307 	// and calculate new values
308 	season = month_to_season[last_month];   //  (2+last_month/3)&3; // summer always zero
309 	if(  old_season != season  && set_pending  ) {
310 		pending_season_change++;
311 	}
312 
313 	const sint16 winterline = settings.get_winter_snowline();
314 	const sint16 summerline = settings.get_climate_borders()[arctic_climate] + 1;
315 	snowline = summerline - (sint16)(((summerline-winterline)*factor)/100);
316 	if(  old_snowline != snowline  &&  set_pending  ) {
317 		pending_snowline_change++;
318 	}
319 }
320 
321 
perlin_hoehe_loop(sint16 x_min,sint16 x_max,sint16 y_min,sint16 y_max)322 void karte_t::perlin_hoehe_loop( sint16 x_min, sint16 x_max, sint16 y_min, sint16 y_max )
323 {
324 	for(  int y = y_min;  y < y_max;  y++  ) {
325 		for(  int x = x_min; x < x_max;  x++  ) {
326 			// loop all tiles
327 			koord k(x,y);
328 			sint16 const h = perlin_hoehe(&settings, k, koord(0, 0));
329 			set_grid_hgt( k, (sint8) h);
330 		}
331 	}
332 }
333 
334 
335 /**
336  * Height one point in the map with "perlin noise"
337  *
338  * @param frequency in 0..1.0 roughness, the higher the rougher
339  * @param amplitude in 0..160.0 top height of mountains, may not exceed 160.0!!!
340  * @author Hj. Malthaner
341  */
perlin_hoehe(settings_t const * const sets,koord k,koord const size)342 sint32 karte_t::perlin_hoehe(settings_t const* const sets, koord k, koord const size)
343 {
344 	// Hajo: to Markus: replace the fixed values with your
345 	// settings. Amplitude is the top highness of the
346 	// mountains, frequency is something like landscape 'roughness'
347 	// amplitude may not be greater than 160.0 !!!
348 	// please don't allow frequencies higher than 0.8 it'll
349 	// break the AI's pathfinding. Frequency values of 0.5 .. 0.7
350 	// seem to be ok, less is boring flat, more is too crumbled
351 	// the old defaults are given here: f=0.6, a=160.0
352 	switch( sets->get_rotation() ) {
353 		// 0: do nothing
354 		case 1: k = koord(k.y,size.x-k.x); break;
355 		case 2: k = koord(size.x-k.x,size.y-k.y); break;
356 		case 3: k = koord(size.y-k.y,k.x); break;
357 	}
358 //    double perlin_noise_2D(double x, double y, double persistence);
359 //    return ((int)(perlin_noise_2D(x, y, 0.6)*160.0)) & 0xFFFFFFF0;
360 	k = k + koord(sets->get_origin_x(), sets->get_origin_y());
361 	return ((int)(perlin_noise_2D(k.x, k.y, sets->get_map_roughness())*(double)sets->get_max_mountain_height())) / 16;
362 }
363 
364 
cleanup_grounds_loop(sint16 x_min,sint16 x_max,sint16 y_min,sint16 y_max)365 void karte_t::cleanup_grounds_loop( sint16 x_min, sint16 x_max, sint16 y_min, sint16 y_max )
366 {
367 	for(  int y = y_min;  y < y_max;  y++  ) {
368 		for(  int x = x_min; x < x_max;  x++  ) {
369 			planquadrat_t *pl = access_nocheck(x,y);
370 			grund_t *gr = pl->get_kartenboden();
371 			koord k(x,y);
372 			uint8 slope = calc_natural_slope(k);
373 			sint8 height = min_hgt_nocheck(k);
374 			sint8 water_hgt = get_water_hgt_nocheck(k);
375 
376 			if(  height < water_hgt) {
377 				const sint8 disp_hn_sw = max( height + corner_sw(slope), water_hgt );
378 				const sint8 disp_hn_se = max( height + corner_se(slope), water_hgt );
379 				const sint8 disp_hn_ne = max( height + corner_ne(slope), water_hgt );
380 				const sint8 disp_hn_nw = max( height + corner_nw(slope), water_hgt );
381 				height = water_hgt;
382 				slope = (disp_hn_sw - height) + ((disp_hn_se - height) * 3) + ((disp_hn_ne - height) * 9) + ((disp_hn_nw - height) * 27);
383 			}
384 
385 			gr->set_pos( koord3d( k, height) );
386 			if(  gr->get_typ() != grund_t::wasser  &&  max_hgt_nocheck(k) <= water_hgt  ) {
387 				// below water but ground => convert
388 				pl->kartenboden_setzen( new wasser_t(gr->get_pos()), true /* do not calc_image for water tiles */ );
389 			}
390 			else if(  gr->get_typ() == grund_t::wasser  &&  max_hgt_nocheck(k) > water_hgt  ) {
391 				// water above ground => to ground
392 				pl->kartenboden_setzen( new boden_t(gr->get_pos(), slope ) );
393 			}
394 			else {
395 				gr->set_grund_hang( slope );
396 			}
397 
398 			if(  max_hgt_nocheck(k) > water_hgt  ) {
399 				set_water_hgt(k, groundwater-4);
400 			}
401 		}
402 	}
403 }
404 
405 
cleanup_karte(int xoff,int yoff)406 void karte_t::cleanup_karte( int xoff, int yoff )
407 {
408 	// we need a copy to smooth the map to a realistic level
409 	const sint32 grid_size = (get_size().x+1)*(sint32)(get_size().y+1);
410 	sint8 *grid_hgts_cpy = new sint8[grid_size];
411 	memcpy( grid_hgts_cpy, grid_hgts, grid_size );
412 
413 	// the trick for smoothing is to raise each tile by one
414 	sint32 i,j;
415 	for(j=0; j<=get_size().y; j++) {
416 		for(i=j>=yoff?0:xoff; i<=get_size().x; i++) {
417 			raise_grid_to(i,j, grid_hgts_cpy[i+j*(get_size().x+1)] + 1);
418 		}
419 	}
420 	delete [] grid_hgts_cpy;
421 
422 	// but to leave the map unchanged, we lower the height again
423 	for(j=0; j<=get_size().y; j++) {
424 		for(i=j>=yoff?0:xoff; i<=get_size().x; i++) {
425 			grid_hgts[i+j*(get_size().x+1)] --;
426 		}
427 	}
428 
429 	if(  xoff==0 && yoff==0  ) {
430 		world_xy_loop(&karte_t::cleanup_grounds_loop, 0);
431 	}
432 	else {
433 		cleanup_grounds_loop( 0, get_size().x, yoff, get_size().y );
434 		cleanup_grounds_loop( xoff, get_size().x, 0, yoff );
435 	}
436 }
437 
438 
destroy()439 void karte_t::destroy()
440 {
441 	is_sound = false; // karte_t::play_sound_area_clipped needs valid zeiger (pointer/drawer)
442 	destroying = true;
443 	DBG_MESSAGE("karte_t::destroy()", "destroying world");
444 
445 	uint32 max_display_progress = 256+stadt.get_count()*10 + haltestelle_t::get_alle_haltestellen().get_count() + convoi_array.get_count() + (cached_size.x*cached_size.y)*2;
446 	uint32 old_progress = 0;
447 
448 	loadingscreen_t ls( translator::translate("Destroying map ..."), max_display_progress, true );
449 
450 	// rotate the map until it can be saved
451 	nosave_warning = false;
452 	if(  nosave  ) {
453 		max_display_progress += 256;
454 		for( int i=0;  i<4  &&  nosave;  i++  ) {
455 			DBG_MESSAGE("karte_t::destroy()", "rotating");
456 			rotate90();
457 		}
458 		old_progress += 256;
459 		ls.set_max( max_display_progress );
460 		ls.set_progress( old_progress );
461 	}
462 	if(nosave) {
463 		dbg->fatal( "karte_t::destroy()","Map cannot be cleanly destroyed in any rotation!" );
464 	}
465 
466 	goods_in_game.clear();
467 
468 	DBG_MESSAGE("karte_t::destroy()", "label clear");
469 	labels.clear();
470 
471 	if(zeiger) {
472 		zeiger->set_pos(koord3d::invalid);
473 		delete zeiger;
474 		zeiger = NULL;
475 	}
476 
477 	old_progress += 256;
478 	ls.set_progress( old_progress );
479 
480 	// removes all moving stuff from the sync_step
481 	sync.clear();
482 	sync_eyecandy.clear();
483 	sync_way_eyecandy.clear();
484 	old_progress += cached_size.x*cached_size.y;
485 	ls.set_progress( old_progress );
486 	DBG_MESSAGE("karte_t::destroy()", "sync list cleared");
487 
488 	// alle convois aufraeumen
489 	while (!convoi_array.empty()) {
490 		convoihandle_t cnv = convoi_array.back();
491 		cnv->destroy();
492 		old_progress ++;
493 		if(  (old_progress&0x00FF) == 0  ) {
494 			ls.set_progress( old_progress );
495 		}
496 	}
497 	convoi_array.clear();
498 	DBG_MESSAGE("karte_t::destroy()", "convois destroyed");
499 
500 	// alle haltestellen aufraeumen
501 	old_progress += haltestelle_t::get_alle_haltestellen().get_count();
502 	haltestelle_t::destroy_all();
503 	DBG_MESSAGE("karte_t::destroy()", "stops destroyed");
504 	ls.set_progress( old_progress );
505 
506 	// remove all target cities (we can skip recalculation anyway)
507 	FOR(slist_tpl<fabrik_t*>, const f, fab_list) {
508 		f->clear_target_cities();
509 	}
510 
511 	// delete towns first (will also delete all their houses)
512 	// for the next game we need to remember the desired number ...
513 	sint32 const no_of_cities = settings.get_city_count();
514 	for(  uint32 i=0;  !stadt.empty();  i++  ) {
515 		remove_city(stadt.front());
516 		old_progress += 10;
517 		if(  (i&0x00F) == 0  ) {
518 			ls.set_progress( old_progress );
519 		}
520 	}
521 	settings.set_city_count(no_of_cities);
522 	DBG_MESSAGE("karte_t::destroy()", "towns destroyed");
523 
524 	ls.set_progress( old_progress );
525 	// dinge aufraeumen
526 	cached_grid_size.x = cached_grid_size.y = 1;
527 	cached_size.x = cached_size.y = 0;
528 	delete [] plan;
529 	plan = NULL;
530 	DBG_MESSAGE("karte_t::destroy()", "planquadrat destroyed");
531 
532 	old_progress += (cached_size.x*cached_size.y)/2;
533 	ls.set_progress( old_progress );
534 
535 	// gitter aufraeumen
536 	delete [] grid_hgts;
537 	grid_hgts = NULL;
538 
539 	delete [] water_hgts;
540 	water_hgts = NULL;
541 
542 	// player cleanup
543 	for(int i=0; i<MAX_PLAYER_COUNT; i++) {
544 		delete players[i];
545 		players[i] = NULL;
546 	}
547 	DBG_MESSAGE("karte_t::destroy()", "player destroyed");
548 
549 	old_progress += (cached_size.x*cached_size.y)/4;
550 	ls.set_progress( old_progress );
551 
552 	// alle fabriken aufraeumen
553 	FOR(slist_tpl<fabrik_t*>, const f, fab_list) {
554 		delete f;
555 	}
556 	fab_list.clear();
557 	DBG_MESSAGE("karte_t::destroy()", "factories destroyed");
558 
559 	// hier nur entfernen, aber nicht loeschen
560 	attractions.clear();
561 	DBG_MESSAGE("karte_t::destroy()", "attraction list destroyed");
562 
563 	delete scenario;
564 	scenario = NULL;
565 
566 assert( depot_t::get_depot_list().empty() );
567 
568 	DBG_MESSAGE("karte_t::destroy()", "world destroyed");
569 	destroying = false;
570 }
571 
572 
add_convoi(convoihandle_t const cnv)573 void karte_t::add_convoi(convoihandle_t const cnv)
574 {
575 	assert(cnv.is_bound());
576 	convoi_array.append_unique(cnv);
577 }
578 
579 
rem_convoi(convoihandle_t const cnv)580 void karte_t::rem_convoi(convoihandle_t const cnv)
581 {
582 	convoi_array.remove(cnv);
583 }
584 
585 
add_city(stadt_t * s)586 void karte_t::add_city(stadt_t *s)
587 {
588 	settings.set_city_count(settings.get_city_count() + 1);
589 	stadt.append(s, s->get_einwohner());
590 
591 	// Knightly : add links between this city and other cities as well as attractions
592 	FOR(weighted_vector_tpl<stadt_t*>, const c, stadt) {
593 		c->add_target_city(s);
594 	}
595 	s->recalc_target_cities();
596 	s->recalc_target_attractions();
597 }
598 
599 
remove_city(stadt_t * s)600 bool karte_t::remove_city(stadt_t *s)
601 {
602 	if(s == NULL  ||  stadt.empty()) {
603 		// no town there to delete ...
604 		return false;
605 	}
606 
607 	// reduce number of towns
608 	if(s->get_name()) {
609 		DBG_MESSAGE("karte_t::remove_city()", "%s", s->get_name());
610 	}
611 	stadt.remove(s);
612 	DBG_DEBUG4("karte_t::remove_city()", "reduce city to %i", settings.get_city_count() - 1);
613 	settings.set_city_count(settings.get_city_count() - 1);
614 
615 	// Knightly : remove links between this city and other cities
616 	FOR(weighted_vector_tpl<stadt_t*>, const c, stadt) {
617 		c->remove_target_city(s);
618 	}
619 
620 	// remove all links from factories
621 	DBG_DEBUG4("karte_t::remove_city()", "fab_list %i", fab_list.get_count() );
622 	FOR(slist_tpl<fabrik_t*>, const f, fab_list) {
623 		f->remove_target_city(s);
624 	}
625 
626 	// ok, we can delete this
627 	DBG_MESSAGE("karte_t::remove_city()", "delete" );
628 	delete s;
629 
630 	return true;
631 }
632 
633 
634 // just allocates space;
init_tiles()635 void karte_t::init_tiles()
636 {
637 	assert(plan==0);
638 
639 	uint32 const x = get_size().x;
640 	uint32 const y = get_size().y;
641 	plan      = new planquadrat_t[x * y];
642 	grid_hgts = new sint8[(x + 1) * (y + 1)];
643 	max_height = min_height = 0;
644 	MEMZERON(grid_hgts, (x + 1) * (y + 1));
645 	water_hgts = new sint8[x * y];
646 	MEMZERON(water_hgts, x * y);
647 
648 	win_set_world( this );
649 	minimap_t::get_instance()->init();
650 
651 	for(int i=0; i<MAX_PLAYER_COUNT ; i++) {
652 		// old default: AI 3 passenger, other goods
653 		players[i] = (i<2) ? new player_t(i) : NULL;
654 	}
655 	active_player = players[0];
656 	active_player_nr = 0;
657 
658 	// defaults without timeline
659 	average_speed[0] = 60;
660 	average_speed[1] = 80;
661 	average_speed[2] = 40;
662 	average_speed[3] = 350;
663 
664 	// clear world records
665 	records->clear_speed_records();
666 
667 	// make timer loop invalid
668 	for( int i=0;  i<32;  i++ ) {
669 		last_frame_ms[i] = 0x7FFFFFFFu;
670 		last_step_nr[i] = 0xFFFFFFFFu;
671 	}
672 	last_frame_idx = 0;
673 	pending_season_change = 0;
674 	pending_snowline_change = 0;
675 
676 	// init global history
677 	for (int year=0; year<MAX_WORLD_HISTORY_YEARS; year++) {
678 		for (int cost_type=0; cost_type<MAX_WORLD_COST; cost_type++) {
679 			finance_history_year[year][cost_type] = 0;
680 		}
681 	}
682 	for (int month=0; month<MAX_WORLD_HISTORY_MONTHS; month++) {
683 		for (int cost_type=0; cost_type<MAX_WORLD_COST; cost_type++) {
684 			finance_history_month[month][cost_type] = 0;
685 		}
686 	}
687 	last_month_bev = 0;
688 
689 	tile_counter = 0;
690 
691 	convoihandle_t::init( 1024 );
692 	linehandle_t::init( 1024 );
693 
694 	halthandle_t::init( 1024 );
695 
696 	vehicle_base_t::set_overtaking_offsets( get_settings().is_drive_left() );
697 
698 	scenario = new scenario_t(this);
699 
700 	nosave_warning = nosave = false;
701 
702 	if (env_t::server) {
703 		nwc_auth_player_t::init_player_lock_server(this);
704 	}
705 }
706 
707 
set_scenario(scenario_t * s)708 void karte_t::set_scenario(scenario_t *s)
709 {
710 	if (scenario != s) {
711 		delete scenario;
712 	}
713 	scenario = s;
714 }
715 
716 
create_rivers(sint16 number)717 void karte_t::create_rivers( sint16 number )
718 {
719 	// First check, whether there is a canal:
720 	const way_desc_t* river_desc = way_builder_t::get_desc( env_t::river_type[env_t::river_types-1], 0 );
721 	if(  river_desc == NULL  ) {
722 		// should never reaching here ...
723 		dbg->warning("karte_t::create_rivers()","There is no river defined!\n");
724 		return;
725 	}
726 
727 	// create a vector of the highest points
728 	vector_tpl<koord> water_tiles;
729 	weighted_vector_tpl<koord> mountain_tiles;
730 
731 	sint8 last_height = 1;
732 	koord last_koord(0,0);
733 	const sint16 max_dist = cached_size.y+cached_size.x;
734 
735 	// trunk of 16 will ensure that rivers are long enough apart ...
736 	for(  sint16 y = 8;  y < cached_size.y;  y+=16  ) {
737 		for(  sint16 x = 8;  x < cached_size.x;  x+=16  ) {
738 			koord k(x,y);
739 			grund_t *gr = lookup_kartenboden_nocheck(k);
740 			const sint8 h = gr->get_hoehe() - get_water_hgt_nocheck(k);
741 			if(  gr->is_water()  ) {
742 				// may be good to start a river here
743 				water_tiles.append(k);
744 			}
745 			else if(  h>=last_height  ||  koord_distance(last_koord,k)>simrand(max_dist)  ) {
746 				// something worth to add here
747 				if(  h>last_height  ) {
748 					last_height = h;
749 				}
750 				last_koord = k;
751 				// using h*h as weight would give mountain sources more preferences
752 				// on the other hand most rivers do not string near summits ...
753 				mountain_tiles.append( k, h );
754 			}
755 		}
756 	}
757 	if (water_tiles.empty()) {
758 		dbg->message("karte_t::create_rivers()","There aren't any water tiles!\n");
759 		return;
760 	}
761 
762 	// now make rivers
763 	sint16 retrys = number*2;
764 	while(  number > 0  &&  !mountain_tiles.empty()  &&  retrys>0  ) {
765 
766 		// start with random coordinates
767 		koord const start = pick_any_weighted(mountain_tiles);
768 		mountain_tiles.remove( start );
769 
770 		// build a list of matching targets
771 		vector_tpl<koord> valid_water_tiles;
772 		for(  uint32 i=0;  i<water_tiles.get_count();  i++  ) {
773 			sint16 dist = koord_distance(start,water_tiles[i]);
774 			if(  settings.get_min_river_length() < dist  &&  dist < settings.get_max_river_length()  ) {
775 				valid_water_tiles.append( water_tiles[i] );
776 			}
777 		}
778 
779 		// now try 256 random locations
780 		for(  sint32 i=0;  i<256  &&  !valid_water_tiles.empty();  i++  ) {
781 			koord const end = pick_any(valid_water_tiles);
782 			valid_water_tiles.remove( end );
783 			way_builder_t riverbuilder(players[1]);
784 			riverbuilder.init_builder(way_builder_t::river, river_desc);
785 			sint16 dist = koord_distance(start,end);
786 			riverbuilder.set_maximum( dist*50 );
787 			riverbuilder.calc_route( lookup_kartenboden(end)->get_pos(), lookup_kartenboden(start)->get_pos() );
788 			if(  riverbuilder.get_count() >= (uint32)settings.get_min_river_length()  ) {
789 				// do not built too short rivers
790 				riverbuilder.build();
791 				number --;
792 				retrys++;
793 				break;
794 			}
795 		}
796 
797 		retrys--;
798 	}
799 	// we gave up => tell the user
800 	if(  number>0  ) {
801 		dbg->warning( "karte_t::create_rivers()","Too many rivers requested! (%i not constructed)", number );
802 	}
803 }
804 
805 
distribute_groundobjs_cities(int new_city_count,sint32 new_mean_citizen_count,sint16 old_x,sint16 old_y)806 void karte_t::distribute_groundobjs_cities(int new_city_count, sint32 new_mean_citizen_count, sint16 old_x, sint16 old_y )
807 {
808 DBG_DEBUG("karte_t::distribute_groundobjs_cities()","distributing rivers");
809 	if(  env_t::river_types > 0  &&  settings.get_river_number() > 0  ) {
810 		create_rivers( settings.get_river_number() );
811 	}
812 
813 	DBG_DEBUG("karte_t::distribute_groundobjs_cities()","prepare cities");
814 	vector_tpl<koord> *pos = stadt_t::random_place(new_city_count, old_x, old_y);
815 
816 	if(  !pos->empty()  ) {
817 		const sint32 old_city_count = stadt.get_count();
818 		new_city_count = pos->get_count();
819 		DBG_DEBUG("karte_t::distribute_groundobjs_cities()", "Creating cities: %d", new_city_count);
820 
821 		// prissi if we could not generate enough positions ...
822 		settings.set_city_count(old_city_count);
823 		int old_progress = 16;
824 
825 		loadingscreen_t ls( translator::translate( "distributing cities" ), 16 + 2 * (old_city_count + new_city_count) + 2 * new_city_count + (old_x == 0 ? settings.get_factory_count() : 0), true, true );
826 
827 		{
828 			// Loop only new cities:
829 #ifdef DEBUG
830 			uint32 tbegin = dr_time();
831 #endif
832 			for(  int i=0;  i<new_city_count;  i++  ) {
833 				stadt_t* s = new stadt_t(players[1], (*pos)[i], 1 );
834 				DBG_DEBUG("karte_t::distribute_groundobjs_cities()","Erzeuge stadt %i with %ld inhabitants",i,(s->get_city_history_month())[HIST_CITICENS] );
835 				if (s->get_buildings() > 0) {
836 					add_city(s);
837 				}
838 				else {
839 					delete(s);
840 				}
841 			}
842 			// center on first city
843 			if(  old_x+old_y == 0  &&  stadt.get_count()>0) {
844 				viewport->change_world_position( stadt[0]->get_pos() );
845 			}
846 
847 			delete pos;
848 #ifdef DEBUG
849 			dbg->message("karte_t::distribute_groundobjs_cities()","took %lu ms for all towns", dr_time()-tbegin );
850 #endif
851 
852 			uint32 game_start = current_month;
853 			// townhalls available since?
854 			FOR(vector_tpl<building_desc_t const*>, const desc, *hausbauer_t::get_list(building_desc_t::townhall)) {
855 				uint32 intro_year_month = desc->get_intro_year_month();
856 				if(  intro_year_month<game_start  ) {
857 					game_start = intro_year_month;
858 				}
859 			}
860 			// streets since when?
861 			game_start = max( game_start, way_builder_t::get_earliest_way(road_wt)->get_intro_year_month() );
862 
863 			uint32 original_start_year = current_month;
864 			uint32 original_industry_growth = settings.get_industry_increase_every();
865 			settings.set_industry_increase_every( 0 );
866 
867 			for(  uint32 i=old_city_count;  i<stadt.get_count();  i++  ) {
868 				// Hajo: do final init after world was loaded/created
869 				stadt[i]->finish_rd();
870 
871 	//			int citizens=(int)(new_mean_citizen_count*0.9);
872 	//			citizens = citizens/10+simrand(2*citizens+1);
873 				const sint32 citizens = (2500l * new_mean_citizen_count) /(simrand(20000)+100);
874 
875 				sint32 diff = (original_start_year-game_start)/2;
876 				sint32 growth = 32;
877 				sint32 current_bev = 1;
878 
879 				/* grow gradually while aging
880 				 * the difference to the current end year will be halved,
881 				 * while the growth step is doubled
882 				 */
883 				current_month = game_start;
884 				bool not_updated = false;
885 				bool new_town = true;
886 				while(  current_bev < citizens  ) {
887 					growth = min( citizens-current_bev, growth*2 );
888 					current_bev += growth;
889 					stadt[i]->change_size( growth, new_town );
890 					// Only "new" for the first change_size call
891 					new_town = false;
892 					if(  current_bev > citizens/2  &&  not_updated  ) {
893 						ls.set_progress( ++old_progress );
894 						not_updated = true;
895 					}
896 					current_month += diff;
897 					diff >>= 1;
898 				}
899 
900 				// the growth is slow, so update here the progress bar
901 				ls.set_progress( ++old_progress );
902 			}
903 
904 			current_month = original_start_year;
905 			settings.set_industry_increase_every( original_industry_growth );
906 			msg->clear();
907 		}
908 		finance_history_year[0][WORLD_TOWNS] = finance_history_month[0][WORLD_TOWNS] = stadt.get_count();
909 		finance_history_year[0][WORLD_CITICENS] = finance_history_month[0][WORLD_CITICENS] = last_month_bev;
910 
911 		// Hajo: connect some cities with roads
912 		way_desc_t const* desc = settings.get_intercity_road_type(get_timeline_year_month());
913 		if(desc == 0) {
914 			// Hajo: try some default (might happen with timeline ... )
915 			desc = way_builder_t::weg_search(road_wt,80,get_timeline_year_month(),type_flat);
916 		}
917 
918 		way_builder_t bauigel (players[1] );
919 		bauigel.init_builder(way_builder_t::strasse | way_builder_t::terraform_flag, desc, tunnel_builder_t::get_tunnel_desc(road_wt,15,get_timeline_year_month()), bridge_builder_t::find_bridge(road_wt,15,get_timeline_year_month()) );
920 		bauigel.set_keep_existing_ways(true);
921 		bauigel.set_maximum(env_t::intercity_road_length);
922 
923 		// **** intercity road construction
924 		int count = 0;
925 		sint32 const n_cities  = settings.get_city_count();
926 		int    const max_count = n_cities * (n_cities - 1) / 2 - old_city_count * (old_city_count - 1) / 2;
927 		// something to do??
928 		if(  max_count > 0  ) {
929 			// print("Building intercity roads ...\n");
930 			ls.set_max( 16 + 2 * (old_city_count + new_city_count) + 2 * new_city_count + (old_x == 0 ? settings.get_factory_count() : 0) );
931 			// find townhall of city i and road in front of it
932 			vector_tpl<koord3d> k;
933 			for (int i = 0;  i < settings.get_city_count(); ++i) {
934 				koord k1(stadt[i]->get_townhall_road());
935 				if (lookup_kartenboden(k1)  &&  lookup_kartenboden(k1)->hat_weg(road_wt)) {
936 					k.append(lookup_kartenboden(k1)->get_pos());
937 				}
938 				else {
939 					// look for a road near the townhall
940 					gebaeude_t const* const gb = obj_cast<gebaeude_t>(lookup_kartenboden(stadt[i]->get_pos())->first_obj());
941 					bool ok = false;
942 					if(  gb  &&  gb->is_townhall()  ) {
943 						koord k_check = stadt[i]->get_pos() + koord(-1,-1);
944 						const koord size = gb->get_tile()->get_desc()->get_size(gb->get_tile()->get_layout());
945 						koord inc(1,0);
946 						// scan all adjacent tiles, take the first that has a road
947 						for(sint32 i=0; i<2*size.x+2*size.y+4  &&  !ok; i++) {
948 							grund_t *gr = lookup_kartenboden(k_check);
949 							if (gr  &&  gr->hat_weg(road_wt)) {
950 								k.append(gr->get_pos());
951 								ok = true;
952 							}
953 							k_check = k_check + inc;
954 							if (i==size.x+1) {
955 								inc = koord(0,1);
956 							}
957 							else if (i==size.x+size.y+2) {
958 								inc = koord(-1,0);
959 							}
960 							else if (i==2*size.x+size.y+3) {
961 								inc = koord(0,-1);
962 							}
963 						}
964 					}
965 					if (!ok) {
966 						k.append( koord3d::invalid );
967 					}
968 				}
969 			}
970 			// compute all distances
971 			uint8 conn_comp=1; // current connection component for phase 0
972 			vector_tpl<uint8> city_flag; // city already connected to the graph? >0 nr of connection component
973 			array2d_tpl<sint32> city_dist(settings.get_city_count(), settings.get_city_count());
974 			for (sint32 i = 0; i < settings.get_city_count(); ++i) {
975 				city_dist.at(i,i) = 0;
976 				for (sint32 j = i + 1; j < settings.get_city_count(); ++j) {
977 					city_dist.at(i,j) = koord_distance(k[i], k[j]);
978 					city_dist.at(j,i) = city_dist.at(i,j);
979 					// count unbuildable connections to new cities
980 					if(  j>=old_city_count && city_dist.at(i,j) >= env_t::intercity_road_length  ) {
981 						count++;
982 					}
983 				}
984 				city_flag.append( i < old_city_count ? conn_comp : 0 );
985 
986 				// progress bar stuff
987 				ls.set_progress( 16 + 2 * new_city_count + count * settings.get_city_count() * 2 / max_count );
988 			}
989 			// mark first town as connected
990 			if (old_city_count==0) {
991 				city_flag[0]=conn_comp;
992 			}
993 
994 			// get a default vehikel
995 			route_t verbindung;
996 			vehicle_t* test_driver;
997 			vehicle_desc_t test_drive_desc(road_wt, 500, vehicle_desc_t::diesel );
998 			test_driver = vehicle_builder_t::build(koord3d(), players[1], NULL, &test_drive_desc);
999 			test_driver->set_flag( obj_t::not_on_map );
1000 
1001 			bool ready=false;
1002 			uint8 phase=0;
1003 			// 0 - first phase: built minimum spanning tree (edge weights: city distance)
1004 			// 1 - second phase: try to complete the graph, avoid edges that
1005 			// == have similar length then already existing connection
1006 			// == lead to triangles with an angle >90 deg
1007 
1008 			while( phase < 2  ) {
1009 				ready = true;
1010 				koord conn = koord::invalid;
1011 				sint32 best = env_t::intercity_road_length;
1012 
1013 				if(  phase == 0  ) {
1014 					// loop over all unconnected cities
1015 					for (int i = 0; i < settings.get_city_count(); ++i) {
1016 						if(  city_flag[i] == conn_comp  ) {
1017 							// loop over all connections to connected cities
1018 							for (int j = old_city_count; j < settings.get_city_count(); ++j) {
1019 								if(  city_flag[j] == 0  ) {
1020 									ready=false;
1021 									if(  city_dist.at(i,j) < best  ) {
1022 										best = city_dist.at(i,j);
1023 										conn = koord(i,j);
1024 									}
1025 								}
1026 							}
1027 						}
1028 					}
1029 					// did we completed a connection component?
1030 					if(  !ready  &&  best == env_t::intercity_road_length  ) {
1031 						// next component
1032 						conn_comp++;
1033 						// try the first not connected city
1034 						ready = true;
1035 						for(  int i = old_city_count;  i < settings.get_city_count();  ++i  ) {
1036 							if(  city_flag[i] ==0  ) {
1037 								city_flag[i] = conn_comp;
1038 								ready = false;
1039 								break;
1040 							}
1041 						}
1042 					}
1043 				}
1044 				else {
1045 					// loop over all unconnected cities
1046 					for (int i = 0; i < settings.get_city_count(); ++i) {
1047 						for (int j = max(old_city_count, i + 1);  j < settings.get_city_count(); ++j) {
1048 							if(  city_dist.at(i,j) < best  &&  city_flag[i] == city_flag[j]  ) {
1049 								bool ok = true;
1050 								// is there a connection i..l..j ? forbid stumpfe winkel
1051 								for (int l = 0; l < settings.get_city_count(); ++l) {
1052 									if(  city_flag[i] == city_flag[l]  &&  city_dist.at(i,l) == env_t::intercity_road_length  &&  city_dist.at(j,l) == env_t::intercity_road_length  ) {
1053 										// cosine < 0 ?
1054 										koord3d d1 = k[i]-k[l];
1055 										koord3d d2 = k[j]-k[l];
1056 										if(  d1.x*d2.x + d1.y*d2.y < 0  ) {
1057 											city_dist.at(i,j) = env_t::intercity_road_length+1;
1058 											city_dist.at(j,i) = env_t::intercity_road_length+1;
1059 											ok = false;
1060 											count ++;
1061 											break;
1062 										}
1063 									}
1064 								}
1065 								if(ok) {
1066 									ready = false;
1067 									best = city_dist.at(i,j);
1068 									conn = koord(i,j);
1069 								}
1070 							}
1071 						}
1072 					}
1073 				}
1074 				// valid connection?
1075 				if(  conn.x >= 0  ) {
1076 					// is there a connection already
1077 					const bool connected = (  phase==1  &&  verbindung.calc_route( this, k[conn.x], k[conn.y], test_driver, 0, 0 )  );
1078 					// build this connection?
1079 					bool build = false;
1080 					// set appropriate max length for way builder
1081 					if(  connected  ) {
1082 						if(  2*verbindung.get_count() > (uint32)city_dist.at(conn)  ) {
1083 							bauigel.set_maximum(verbindung.get_count() / 2);
1084 							build = true;
1085 						}
1086 					}
1087 					else {
1088 						bauigel.set_maximum(env_t::intercity_road_length);
1089 						build = true;
1090 					}
1091 
1092 					if(  build  ) {
1093 						bauigel.calc_route(k[conn.x],k[conn.y]);
1094 					}
1095 
1096 					if(  build  &&  bauigel.get_count() >= 2  ) {
1097 						bauigel.build();
1098 						if (phase==0) {
1099 							city_flag[ conn.y ] = conn_comp;
1100 						}
1101 						// mark as built
1102 						city_dist.at(conn) =  env_t::intercity_road_length;
1103 						city_dist.at(conn.y, conn.x) =  env_t::intercity_road_length;
1104 						count ++;
1105 					}
1106 					else {
1107 						// do not try again
1108 						city_dist.at(conn) =  env_t::intercity_road_length+1;
1109 						city_dist.at(conn.y, conn.x) =  env_t::intercity_road_length+1;
1110 						count ++;
1111 
1112 						if(  phase == 0  ) {
1113 							// do not try to connect to this connected component again
1114 							for(  int i = 0;  i < settings.get_city_count();  ++i  ) {
1115 								if(  city_flag[i] == conn_comp  && city_dist.at(i, conn.y)<env_t::intercity_road_length) {
1116 									city_dist.at(i, conn.y) =  env_t::intercity_road_length+1;
1117 									city_dist.at(conn.y, i) =  env_t::intercity_road_length+1;
1118 									count++;
1119 								}
1120 							}
1121 						}
1122 					}
1123 				}
1124 
1125 				// progress bar stuff
1126 				ls.set_progress( 16 + 2 * new_city_count + count * settings.get_city_count() * 2 / max_count );
1127 
1128 				// next phase?
1129 				if(ready) {
1130 					phase++;
1131 					ready = false;
1132 				}
1133 			}
1134 			delete test_driver;
1135 		}
1136 	}
1137 	else {
1138 		// could not generate any town
1139 		delete pos;
1140 		settings.set_city_count( stadt.get_count() ); // new number of towns (if we did not find enough positions)
1141 	}
1142 
1143 DBG_DEBUG("karte_t::distribute_groundobjs_cities()","distributing groundobjs");
1144 	if(  env_t::ground_object_probability > 0  ) {
1145 		// add eyecandy like rocky, moles, flowers, ...
1146 		koord k;
1147 		sint32 queried = simrand(env_t::ground_object_probability*2-1);
1148 		for(  k.y=0;  k.y<get_size().y;  k.y++  ) {
1149 			for(  k.x=(k.y<old_y)?old_x:0;  k.x<get_size().x;  k.x++  ) {
1150 				grund_t *gr = lookup_kartenboden_nocheck(k);
1151 				if(  gr->get_typ()==grund_t::boden  &&  !gr->hat_wege()  ) {
1152 					queried --;
1153 					if(  queried<0  ) {
1154 						// test for beach
1155 						bool neighbour_water = false;
1156 						for(int i=0; i<8; i++) {
1157 							if(  is_within_limits(k + koord::neighbours[i])  &&  get_climate( k + koord::neighbours[i] ) == water_climate  ) {
1158 								neighbour_water = true;
1159 								break;
1160 							}
1161 						}
1162 						const climate_bits cl = neighbour_water ? water_climate_bit : (climate_bits)(1<<get_climate(k));
1163 						const groundobj_desc_t *desc = groundobj_t::random_groundobj_for_climate( cl, gr->get_grund_hang() );
1164 						queried = simrand(env_t::ground_object_probability*2-1);
1165 						if(desc) {
1166 							gr->obj_add( new groundobj_t( gr->get_pos(), desc ) );
1167 						}
1168 					}
1169 				}
1170 			}
1171 		}
1172 	}
1173 
1174 DBG_DEBUG("karte_t::distribute_groundobjs_cities()","distributing movingobjs");
1175 	if(  env_t::moving_object_probability > 0  ) {
1176 		// add animals and so on (must be done after growing and all other objects, that could change ground coordinates)
1177 		koord k;
1178 		bool has_water = movingobj_t::random_movingobj_for_climate( water_climate )!=NULL;
1179 		sint32 queried = simrand(env_t::moving_object_probability*2);
1180 		// no need to test the borders, since they are mostly slopes anyway
1181 		for(k.y=1; k.y<get_size().y-1; k.y++) {
1182 			for(k.x=(k.y<old_y)?old_x:1; k.x<get_size().x-1; k.x++) {
1183 				grund_t *gr = lookup_kartenboden_nocheck(k);
1184 				// flat ground or open water
1185 				if(  gr->get_top()==0  &&  (  (gr->get_typ()==grund_t::boden  &&  gr->get_grund_hang()==slope_t::flat)  ||  (has_water  &&  gr->is_water())  )  ) {
1186 					queried --;
1187 					if(  queried<0  ) {
1188 						const groundobj_desc_t *desc = movingobj_t::random_movingobj_for_climate( get_climate(k) );
1189 						if(  desc  &&  ( desc->get_waytype() != water_wt  ||  gr->get_hoehe() <= get_water_hgt_nocheck(k) )  ) {
1190 							if(desc->get_speed()!=0) {
1191 								queried = simrand(env_t::moving_object_probability*2);
1192 								gr->obj_add( new movingobj_t( gr->get_pos(), desc ) );
1193 							}
1194 						}
1195 					}
1196 				}
1197 			}
1198 		}
1199 	}
1200 }
1201 
1202 
init(settings_t * const sets,sint8 const * const h_field)1203 void karte_t::init(settings_t* const sets, sint8 const* const h_field)
1204 {
1205 	clear_random_mode( 7 );
1206 	mute_sound(true);
1207 	if (env_t::networkmode) {
1208 		if (env_t::server) {
1209 			network_reset_server();
1210 		}
1211 		else {
1212 			network_core_shutdown();
1213 		}
1214 	}
1215 	step_mode  = PAUSE_FLAG;
1216 	intr_disable();
1217 
1218 	if(plan) {
1219 		destroy();
1220 	}
1221 
1222 	for(  uint i=0;  i<MAX_PLAYER_COUNT;  i++  ) {
1223 		selected_tool[i] = tool_t::general_tool[TOOL_QUERY];
1224 	}
1225 	if(is_display_init()) {
1226 		display_show_pointer(false);
1227 	}
1228 	viewport->change_world_position( koord(0,0), 0, 0 );
1229 
1230 	settings = *sets;
1231 	// names during creation time
1232 	settings.set_name_language_iso(env_t::language_iso);
1233 	settings.set_use_timeline(settings.get_use_timeline() & 1);
1234 
1235 	ticks = 0;
1236 	last_step_ticks = ticks;
1237 	schedule_counter = 0;
1238 	// ticks = 0x7FFFF800;  // Testing the 31->32 bit step
1239 
1240 	last_month = 0;
1241 	last_year = settings.get_starting_year();
1242 	current_month = last_month + (last_year*12);
1243 	set_ticks_per_world_month_shift(settings.get_bits_per_month());
1244 	next_month_ticks =  karte_t::ticks_per_world_month;
1245 	season=(2+last_month/3)&3; // summer always zero
1246 	steps = 0;
1247 	network_frame_count = 0;
1248 	sync_steps = 0;
1249 	sync_steps_barrier = sync_steps;
1250 	map_counter = 0;
1251 	recalc_average_speed();	// resets timeline
1252 	koord::locality_factor = settings.get_locality_factor( last_year );
1253 
1254 	world_maximum_height = sets->get_maximumheight();
1255 	world_minimum_height = sets->get_minimumheight();
1256 	groundwater = (sint8)sets->get_groundwater();      //29-Nov-01     Markus Weber    Changed
1257 
1258 	init_height_to_climate();
1259 	snowline = sets->get_winter_snowline() + groundwater;
1260 
1261 	if(sets->get_beginner_mode()) {
1262 		goods_manager_t::set_multiplier(settings.get_beginner_price_factor());
1263 		settings.set_just_in_time( 0 );
1264 	}
1265 	else {
1266 		goods_manager_t::set_multiplier( 1000 );
1267 	}
1268 
1269 	recalc_season_snowline(false);
1270 
1271 	stadt.clear();
1272 
1273 DBG_DEBUG("karte_t::init()","hausbauer_t::new_world()");
1274 	// Call this before building cities
1275 	hausbauer_t::new_world();
1276 
1277 	cached_grid_size.x = 0;
1278 	cached_grid_size.y = 0;
1279 
1280 DBG_DEBUG("karte_t::init()","init_tiles");
1281 	init_tiles();
1282 
1283 	enlarge_map(&settings, h_field);
1284 
1285 	script_api::new_world();
1286 
1287 DBG_DEBUG("karte_t::init()","distributing trees");
1288 	if (!settings.get_no_trees()) {
1289 		baum_t::distribute_trees(3);
1290 	}
1291 
1292 DBG_DEBUG("karte_t::init()","built timeline");
1293 	private_car_t::build_timeline_list(this);
1294 	pedestrian_t::build_timeline_list(this);
1295 
1296 	nosave_warning = nosave = false;
1297 
1298 	dbg->error("karte_t::init()", "Creating factories ...");
1299 	factory_builder_t::new_world();
1300 
1301 	int consecutive_build_failures = 0;
1302 
1303 	loadingscreen_t ls( translator::translate("distributing factories"), 16 + settings.get_city_count() * 4 + settings.get_factory_count(), true, true );
1304 
1305 	while(  fab_list.get_count() < (uint32)settings.get_factory_count()  ) {
1306 		if(  !factory_builder_t::increase_industry_density( false )  ) {
1307 			if(  ++consecutive_build_failures > 3  ) {
1308 				// Industry chain building starts failing consecutively as map approaches full.
1309 				break;
1310 			}
1311 		}
1312 		else {
1313 			consecutive_build_failures = 0;
1314 		}
1315 		ls.set_progress( 16 + settings.get_city_count() * 4 + min(fab_list.get_count(),settings.get_factory_count()) );
1316 	}
1317 
1318 	settings.set_factory_count( fab_list.get_count() );
1319 	finance_history_year[0][WORLD_FACTORIES] = finance_history_month[0][WORLD_FACTORIES] = fab_list.get_count();
1320 
1321 	// tourist attractions
1322 	factory_builder_t::distribute_attractions(settings.get_tourist_attractions());
1323 
1324 	dbg->message("karte_t::init()", "Preparing startup ...");
1325 	if(zeiger == 0) {
1326 		zeiger = new zeiger_t(koord3d::invalid, NULL );
1327 	}
1328 
1329 	// finishes the line preparation and sets id 0 to invalid ...
1330 	players[0]->simlinemgmt.finish_rd();
1331 
1332 	set_tool( tool_t::general_tool[TOOL_QUERY], get_active_player() );
1333 
1334 	recalc_average_speed();
1335 
1336 	for (int i = 0; i < MAX_PLAYER_COUNT; i++) {
1337 		if(  players[i]  ) {
1338 			players[i]->set_active(settings.player_active[i]);
1339 		}
1340 	}
1341 
1342 	active_player_nr = 0;
1343 	active_player = players[0];
1344 	tool_t::update_toolbars();
1345 
1346 	set_dirty();
1347 	step_mode = PAUSE_FLAG;
1348 	simloops = 60;
1349 	reset_timer();
1350 
1351 	if(is_display_init()) {
1352 		display_show_pointer(true);
1353 	}
1354 	mute_sound(false);
1355 }
1356 
1357 
1358 #define array_koord(px,py) (px + py * get_size().x)
1359 
1360 
1361 /* Lakes:
1362  * For each height from groundwater+1 to max_lake_height we loop over
1363  * all tiles in the map trying to increase water height to this value
1364  * To start with every tile in the map is checked - but when we fail for
1365  * a tile then it is excluded from subsequent checks
1366  */
create_lakes(int xoff,int yoff)1367 void karte_t::create_lakes(  int xoff, int yoff  )
1368 {
1369 	if(  xoff > 0  ||  yoff > 0  ) {
1370 		// too complicated to add lakes to an already existing world...
1371 		return;
1372 	}
1373 
1374 	const sint8 max_lake_height = groundwater + 8;
1375 	const uint16 size_x = get_size().x;
1376 	const uint16 size_y = get_size().y;
1377 
1378 	sint8 *max_water_hgt = new sint8[size_x * size_y];
1379 	memset( max_water_hgt, 1, sizeof(sint8) * size_x * size_y );
1380 
1381 	sint8 *stage = new sint8[size_x * size_y];
1382 	sint8 *new_stage = new sint8[size_x * size_y];
1383 	sint8 *local_stage = new sint8[size_x * size_y];
1384 
1385 	for(  sint8 h = groundwater+1; h<max_lake_height; h++  ) {
1386 		bool need_to_flood = false;
1387 		memset( stage, -1, sizeof(sint8) * size_x * size_y );
1388 		for(  uint16 y = 1;  y < size_y-1;  y++  ) {
1389 			for(  uint16 x = 1;  x < size_x-1;  x++  ) {
1390 				uint32 offset = array_koord(x,y);
1391 				if(  max_water_hgt[offset]==1  &&  stage[offset]==-1  ) {
1392 
1393 					sint8 hgt = lookup_hgt_nocheck( x, y );
1394 					const sint8 water_hgt = water_hgts[offset]; // optimised <- get_water_hgt_nocheck(x, y);
1395 					const sint8 new_water_hgt = max(hgt, water_hgt);
1396 					if(  new_water_hgt>max_lake_height  ) {
1397 						max_water_hgt[offset] = 0;
1398 					}
1399 					else if(  h>new_water_hgt  ) {
1400 						koord k(x,y);
1401 						memcpy( new_stage, stage, sizeof(sint8) * size_x * size_y );
1402 						if(can_flood_to_depth(  k, h, new_stage, local_stage )) {
1403 							sint8 *tmp_stage = new_stage;
1404 							new_stage = stage;
1405 							stage = tmp_stage;
1406 							need_to_flood = true;
1407 						}
1408 						else {
1409 							for(  uint16 iy = 1;  iy<size_y - 1;  iy++  ) {
1410 								uint32 offset_end = array_koord(size_x - 1,iy);
1411 								for(  uint32 local_offset = array_koord(0,iy);  local_offset<offset_end;  local_offset++  ) {
1412 									if(  local_stage[local_offset] > -1  ) {
1413 										max_water_hgt[local_offset] = 0;
1414 									}
1415 								}
1416 							}
1417 						}
1418 					}
1419 				}
1420 			}
1421 		}
1422 		if(need_to_flood) {
1423 			flood_to_depth(  h, stage  );
1424 		}
1425 		else {
1426 			break;
1427 		}
1428 	}
1429 
1430 	delete [] max_water_hgt;
1431 	delete [] stage;
1432 	delete [] new_stage;
1433 	delete [] local_stage;
1434 
1435 	for (planquadrat_t *pl = plan; pl < (plan + size_x * size_y); pl++) {
1436 		pl->correct_water();
1437 	}
1438 }
1439 
1440 
can_flood_to_depth(koord k,sint8 new_water_height,sint8 * stage,sint8 * our_stage) const1441 bool karte_t::can_flood_to_depth(  koord k, sint8 new_water_height, sint8 *stage, sint8 *our_stage  ) const
1442 {
1443 	bool succeeded = true;
1444 	if(  k == koord::invalid  ) {
1445 		return false;
1446 	}
1447 
1448 	if(  new_water_height < get_groundwater() - 3  ) {
1449 		return false;
1450 	}
1451 
1452 	// make a list of tiles to change
1453 	// cannot use a recursive method as stack is not large enough!
1454 
1455 	sint8 *from_dir = new sint8[get_size().x * get_size().y];
1456 	bool local_stage = (our_stage==NULL);
1457 
1458 	if(  local_stage  ) {
1459 		our_stage = new sint8[get_size().x * get_size().y];
1460 	}
1461 
1462 	memset( from_dir, -1, sizeof(sint8) * get_size().x * get_size().y );
1463 	memset( our_stage, -1, sizeof(sint8) * get_size().x * get_size().y );
1464 	uint32 offset = array_koord(k.x,k.y);
1465 	stage[offset]=0;
1466 	our_stage[offset]=0;
1467 	do {
1468 		for(  int i = our_stage[offset];  i < 8;  i++  ) {
1469 			koord k_neighbour = k + koord::neighbours[i];
1470 			if(  is_within_limits(k_neighbour)  ) {
1471 				const uint32 neighbour_offset = array_koord(k_neighbour.x,k_neighbour.y);
1472 
1473 				// already visited
1474 				if(our_stage[neighbour_offset] != -1) goto next_neighbour;
1475 
1476 				// water height above
1477 				if(water_hgts[neighbour_offset] >= new_water_height) goto next_neighbour;
1478 
1479 				grund_t *gr2 = lookup_kartenboden_nocheck(k_neighbour);
1480 				if(  !gr2  ) goto next_neighbour;
1481 
1482 				sint8 neighbour_height = gr2->get_hoehe();
1483 
1484 				// land height above
1485 				if(neighbour_height >= new_water_height) goto next_neighbour;
1486 
1487 				//move on to next tile
1488 				from_dir[neighbour_offset] = i;
1489 				stage[neighbour_offset] = 0;
1490 				our_stage[neighbour_offset] = 0;
1491 				our_stage[offset] = i;
1492 				k = k_neighbour;
1493 				offset = array_koord(k.x,k.y);
1494 				break;
1495 			}
1496 			else {
1497 				// edge of map - we keep iterating so we can mark all connected tiles as failing
1498 				succeeded = false;
1499 			}
1500 			next_neighbour:
1501 			//return back to previous tile
1502 			if(  i==7  ) {
1503 				k = k - koord::neighbours[from_dir[offset]];
1504 			}
1505 		}
1506 		offset = array_koord(k.x,k.y);
1507 	} while(  from_dir[offset] != -1  );
1508 
1509 	delete [] from_dir;
1510 
1511 	if(  local_stage  ) {
1512 		delete [] our_stage;
1513 	}
1514 
1515 	return succeeded;
1516 }
1517 
1518 
flood_to_depth(sint8 new_water_height,sint8 * stage)1519 void karte_t::flood_to_depth( sint8 new_water_height, sint8 *stage )
1520 {
1521 	const uint16 size_x = get_size().x;
1522 	const uint16 size_y = get_size().y;
1523 
1524 	uint32 offset_max = size_x*size_y;
1525 	for(  uint32 offset = 0;  offset < offset_max;  offset++  ) {
1526 		if(  stage[offset] == -1  ) {
1527 			continue;
1528 		}
1529 		water_hgts[offset] = new_water_height;
1530 	}
1531 }
1532 
1533 
create_beaches(int xoff,int yoff)1534 void karte_t::create_beaches(  int xoff, int yoff  )
1535 {
1536 	const uint16 size_x = get_size().x;
1537 	const uint16 size_y = get_size().y;
1538 
1539 	// bays have wide beaches
1540 	for(  uint16 iy = 0;  iy < size_y;  iy++  ) {
1541 		for(  uint16 ix = (iy >= yoff - 19) ? 0 : max( xoff - 19, 0 );  ix < size_x;  ix++  ) {
1542 			grund_t *gr = lookup_kartenboden_nocheck(ix,iy);
1543 			if(  gr->is_water()  &&  gr->get_hoehe()==groundwater  &&  gr->kann_alle_obj_entfernen(NULL)==NULL) {
1544 				koord k( ix, iy );
1545 				uint8 neighbour_water = 0;
1546 				bool water[8];
1547 				// check whether nearby tiles are water
1548 				for(  int i = 0;  i < 8;  i++  ) {
1549 					grund_t *gr2 = lookup_kartenboden( k + koord::neighbours[i] );
1550 					water[i] = (!gr2  ||  gr2->is_water());
1551 				}
1552 
1553 				// make a count of nearby tiles - where tiles on opposite (+-1 direction) sides are water these count much more so we don't block straits
1554 				for(  int i = 0;  i < 8;  i++  ) {
1555 					if(  water[i]  ) {
1556 						neighbour_water++;
1557 						if(  water[(i + 3) & 7]  ||  water[(i + 4) & 7]  ||  water[(i + 5) & 7]  ) {
1558 							neighbour_water++;
1559 						}
1560 					}
1561 				}
1562 
1563 				// if not much nearby water then turn into a beach
1564 				if(  neighbour_water < 4  ) {
1565 					set_water_hgt( k, gr->get_hoehe() - 1 );
1566 					raise_grid_to( ix, iy, gr->get_hoehe() );
1567 					raise_grid_to( ix + 1, iy, gr->get_hoehe() );
1568 					raise_grid_to( ix, iy + 1, gr->get_hoehe() );
1569 					raise_grid_to( ix + 1, iy + 1 , gr->get_hoehe() );
1570 					access_nocheck(k)->correct_water();
1571 					access_nocheck(k)->set_climate( desert_climate );
1572 				}
1573 			}
1574 		}
1575 	}
1576 
1577 	// headlands should not have beaches at all
1578 	for(  uint16 iy = 0;  iy < size_y;  iy++  ) {
1579 		for(  uint16 ix = (iy >= yoff - 19) ? 0 : max( xoff - 19, 0 );  ix < size_x;  ix++  ) {
1580 			koord k( ix, iy );
1581 			grund_t *gr = lookup_kartenboden_nocheck(k);
1582 			if(  !gr->is_water()  &&  gr->get_pos().z == groundwater  ) {
1583 				uint8 neighbour_water = 0;
1584 				for(  int i = 0;  i < 8;  i++  ) {
1585 					grund_t *gr2 = lookup_kartenboden( k + koord::neighbours[i] );
1586 					if(  !gr2  ||  gr2->is_water()  ) {
1587 						neighbour_water++;
1588 					}
1589 				}
1590 				// if a lot of water nearby we are a headland
1591 				if(  neighbour_water > 3  ) {
1592 					access_nocheck(k)->set_climate( get_climate_at_height( groundwater + 1 ) );
1593 				}
1594 			}
1595 		}
1596 	}
1597 
1598 	// remove any isolated 1 tile beaches
1599 	for(  uint16 iy = 0;  iy < size_y;  iy++  ) {
1600 		for(  uint16 ix = (iy >= yoff - 19) ? 0 : max( xoff - 19, 0 );  ix < size_x;  ix++  ) {
1601 			koord k( ix, iy );
1602 			if(  access_nocheck(k)->get_climate()  ==  desert_climate  ) {
1603 				uint8 neighbour_beach = 0;
1604 				//look up neighbouring climates
1605 				climate neighbour_climate[8];
1606 				for(  int i = 0;  i < 8;  i++  ) {
1607 					koord k_neighbour = k + koord::neighbours[i];
1608 					if(  !is_within_limits(k_neighbour)  ) {
1609 						k_neighbour = get_closest_coordinate(k_neighbour);
1610 					}
1611 					neighbour_climate[i] = get_climate( k_neighbour );
1612 				}
1613 
1614 				// get transition climate - look for each corner in turn
1615 				for( int i = 0;  i < 4;  i++  ) {
1616 					climate transition_climate = (climate) max( max( neighbour_climate[(i * 2 + 1) & 7], neighbour_climate[(i * 2 + 3) & 7] ), neighbour_climate[(i * 2 + 2) & 7] );
1617 					climate min_climate = (climate) min( min( neighbour_climate[(i * 2 + 1) & 7], neighbour_climate[(i * 2 + 3) & 7] ), neighbour_climate[(i * 2 + 2) & 7] );
1618 					if(  min_climate <= desert_climate  &&  transition_climate == desert_climate  ) {
1619 						neighbour_beach++;
1620 					}
1621 				}
1622 				if(  neighbour_beach == 0  ) {
1623 					access_nocheck(k)->set_climate( get_climate_at_height( groundwater + 1 ) );
1624 				}
1625 			}
1626 		}
1627 	}
1628 }
1629 
1630 
init_height_to_climate()1631 void karte_t::init_height_to_climate()
1632 {
1633 	// create height table
1634 	sint16 climate_border[MAX_CLIMATES];
1635 	memcpy(climate_border, get_settings().get_climate_borders(), sizeof(climate_border));
1636 	// set climate_border[0] to sea level
1637 	climate_border[0] = groundwater;
1638 
1639 	for( int cl=0;  cl<MAX_CLIMATES-1;  cl++ ) {
1640 		if(climate_border[cl]>climate_border[arctic_climate]) {
1641 			// unused climate
1642 			climate_border[cl] = groundwater-1;
1643 		}
1644 	}
1645 
1646 	// now arrange the remaining ones
1647 	for( uint h=0;  h<lengthof(height_to_climate);  h++  ) {
1648 		sint16 current_height = 999;	      // current maximum
1649 		sint16 current_cl = arctic_climate;	// and the climate
1650 		for( int cl=0;  cl<MAX_CLIMATES;  cl++ ) {
1651 			if(  climate_border[cl] >= (sint16)h + groundwater  &&  climate_border[cl] < current_height  ) {
1652 				current_height = climate_border[cl];
1653 				current_cl = cl;
1654 			}
1655 		}
1656 		height_to_climate[h] = (uint8)current_cl;
1657 	}
1658 }
1659 
1660 
enlarge_map(settings_t const * sets,sint8 const * const h_field)1661 void karte_t::enlarge_map(settings_t const* sets, sint8 const* const h_field)
1662 {
1663 	sint16 new_size_x = sets->get_size_x();
1664 	sint16 new_size_y = sets->get_size_y();
1665 
1666 	if(  cached_grid_size.y>0  &&  cached_grid_size.y!=new_size_y  ) {
1667 		// to keep the labels
1668 		grund_t::enlarge_map( new_size_x, new_size_y );
1669 	}
1670 
1671 	planquadrat_t *new_plan = new planquadrat_t[new_size_x*new_size_y];
1672 	sint8 *new_grid_hgts = new sint8[(new_size_x + 1) * (new_size_y + 1)];
1673 	sint8 *new_water_hgts = new sint8[new_size_x * new_size_y];
1674 
1675 	memset( new_grid_hgts, groundwater, sizeof(sint8) * (new_size_x + 1) * (new_size_y + 1) );
1676 	memset( new_water_hgts, groundwater, sizeof(sint8) * new_size_x * new_size_y );
1677 
1678 	sint16 old_x = cached_grid_size.x;
1679 	sint16 old_y = cached_grid_size.y;
1680 
1681 	settings.set_size_x(new_size_x);
1682 	settings.set_size_y(new_size_y);
1683 	cached_grid_size.x = new_size_x;
1684 	cached_grid_size.y = new_size_y;
1685 	cached_size_max = max(cached_grid_size.x,cached_grid_size.y);
1686 	cached_size.x = cached_grid_size.x-1;
1687 	cached_size.y = cached_grid_size.y-1;
1688 
1689 	intr_disable();
1690 
1691 	const bool minimap_was_visible = minimap_t::is_visible;
1692 
1693 	int max_display_progress;
1694 
1695 	// If this is not called by karte_t::init
1696 	if(  old_x != 0  ) {
1697 		mute_sound(true);
1698 		minimap_t::is_visible = false;
1699 
1700 		if(is_display_init()) {
1701 			display_show_pointer(false);
1702 		}
1703 
1704 // Copy old values:
1705 		for (sint16 iy = 0; iy<old_y; iy++) {
1706 			for (sint16 ix = 0; ix<old_x; ix++) {
1707 				uint32 nr = ix+(iy*old_x);
1708 				uint32 nnr = ix+(iy*new_size_x);
1709 				swap(new_plan[nnr], plan[nr]);
1710 				new_water_hgts[nnr] = water_hgts[nr];
1711 			}
1712 		}
1713 		for (sint16 iy = 0; iy<=old_y; iy++) {
1714 			for (sint16 ix = 0; ix<=old_x; ix++) {
1715 				uint32 nr = ix+(iy*(old_x+1));
1716 				uint32 nnr = ix+(iy*(new_size_x+1));
1717 				new_grid_hgts[nnr] = grid_hgts[nr];
1718 			}
1719 		}
1720 		max_display_progress = 16 + sets->get_city_count()*2 + stadt.get_count()*4;
1721 	}
1722 	else {
1723 		max_display_progress = 16 + sets->get_city_count() * 4 + settings.get_factory_count();
1724 	}
1725 	loadingscreen_t ls( translator::translate( old_x ? "enlarge map" : "Init map ..."), max_display_progress, true, true );
1726 
1727 	delete [] plan;
1728 	plan = new_plan;
1729 	delete [] grid_hgts;
1730 	grid_hgts = new_grid_hgts;
1731 	delete [] water_hgts;
1732 	water_hgts = new_water_hgts;
1733 
1734 	if(  old_x==0  ) {
1735 		// init max and min with defaults
1736 		max_height = groundwater;
1737 		min_height = groundwater;
1738 	}
1739 
1740 	setsimrand(0xFFFFFFFF, settings.get_map_number());
1741 	clear_random_mode( 0xFFFF );
1742 	set_random_mode( MAP_CREATE_RANDOM );
1743 
1744 	if(  old_x == 0  &&  !settings.heightfield.empty()  ) {
1745 		// init from file
1746 		for(int y=0; y<cached_grid_size.y; y++) {
1747 			for(int x=0; x<cached_grid_size.x; x++) {
1748 				grid_hgts[x + y*(cached_grid_size.x+1)] = h_field[x+(y*(sint32)cached_grid_size.x)]+1;
1749 			}
1750 			grid_hgts[cached_grid_size.x + y*(cached_grid_size.x+1)] = grid_hgts[cached_grid_size.x-1 + y*(cached_grid_size.x+1)];
1751 		}
1752 		// lower border
1753 		memcpy( grid_hgts+(cached_grid_size.x+1)*(sint32)cached_grid_size.y, grid_hgts+(cached_grid_size.x+1)*(sint32)(cached_grid_size.y-1), cached_grid_size.x+1 );
1754 		ls.set_progress(2);
1755 	}
1756 	else {
1757 		if(  sets->get_rotation()==0  &&  sets->get_origin_x()==0  &&  sets->get_origin_y()==0) {
1758 			// otherwise negative offsets may occur, so we cache only non-rotated maps
1759 			init_perlin_map(new_size_x,new_size_y);
1760 		}
1761 		if (  old_x > 0  &&  old_y > 0  ) {
1762 			// loop only new tiles:
1763 			for(  sint16 y = 0;  y<=new_size_y;  y++  ) {
1764 				for(  sint16 x = (y>old_y) ? 0 : old_x+1;  x<=new_size_x;  x++  ) {
1765 					koord k(x,y);
1766 					sint16 const h = perlin_hoehe(&settings, k, koord(old_x, old_y));
1767 					set_grid_hgt( k, (sint8) h);
1768 				}
1769 				ls.set_progress( (y*16)/new_size_y );
1770 			}
1771 		}
1772 		else {
1773 			world_xy_loop(&karte_t::perlin_hoehe_loop, GRIDS_FLAG);
1774 			ls.set_progress(2);
1775 		}
1776 		exit_perlin_map();
1777 	}
1778 
1779 	/** @note First we'll copy the border heights to the adjacent tile.
1780 	 * The best way I could find is raising the first new grid point to
1781 	 * the same height the adjacent old grid point was and lowering to the
1782 	 * same height again. This doesn't preserve the old area 100%, but it respects it
1783 	 * somehow.
1784 	 *
1785 	 * This does not work for water tiles as for them get_hoehe will return the
1786 	 * z-coordinate of the water surface, not the height of the underwater
1787 	 * landscape.
1788 	 */
1789 
1790 	sint32 i;
1791 	grund_t *gr;
1792 	sint8 h;
1793 
1794 	if ( old_x > 0  &&  old_y > 0){
1795 		for(i=0; i<old_x; i++) {
1796 			gr = lookup_kartenboden_nocheck(i, old_y-1);
1797 			if (!gr->is_water()) {
1798 				h = gr->get_hoehe(slope4_t::corner_SW);
1799 				raise_grid_to(i, old_y+1, h);
1800 				lower_grid_to(i, old_y+1, h );
1801 			}
1802 		}
1803 		for(i=0; i<old_y; i++) {
1804 			gr = lookup_kartenboden_nocheck(old_x-1, i);
1805 			if (!gr->is_water()) {
1806 				h = gr->get_hoehe(slope4_t::corner_NE);
1807 				raise_grid_to(old_x+1, i, h);
1808 				lower_grid_to(old_x+1, i, h);
1809 			}
1810 		}
1811 		gr = lookup_kartenboden_nocheck(old_x-1, old_y -1);
1812 		if (!gr->is_water()) {
1813 			h = gr->get_hoehe(slope4_t::corner_SE);
1814 			raise_grid_to(old_x+1, old_y+1, h);
1815 			lower_grid_to(old_x+1, old_y+1, h);
1816 		}
1817 	}
1818 
1819 	if (  old_x > 0  &&  old_y > 0  ) {
1820 		// create grounds on new part
1821 		for (sint16 iy = 0; iy<new_size_y; iy++) {
1822 			for (sint16 ix = (iy>=old_y)?0:old_x; ix<new_size_x; ix++) {
1823 				koord k(ix,iy);
1824 				access_nocheck(k)->kartenboden_setzen( new boden_t( koord3d( ix, iy, max( min_hgt_nocheck(k), get_water_hgt_nocheck(k) ) ), 0 ) );
1825 			}
1826 		}
1827 	}
1828 	else {
1829 		world_xy_loop(&karte_t::create_grounds_loop, 0);
1830 		ls.set_progress(10);
1831 	}
1832 
1833 	// update height bounds
1834 	for(  sint16 iy = 0;  iy < new_size_y;  iy++  ) {
1835 		for(  sint16 ix = (iy >= old_y) ? 0 : max( old_x, 0 );  ix < new_size_x;  ix++  ) {
1836 			sint8 hgt = lookup_kartenboden_nocheck(ix, iy)->get_hoehe();
1837 			if (hgt < min_height) {
1838 				min_height = hgt;
1839 			}
1840 			if (hgt > max_height) {
1841 				max_height = hgt;
1842 			}
1843 		}
1844 	}
1845 
1846 	if (  old_x == 0  &&  old_y == 0  ) {
1847 		ls.set_progress(11);
1848 	}
1849 
1850 	// smooth the new part, reassign slopes on new part
1851 	cleanup_karte( old_x, old_y );
1852 	if (  old_x == 0  &&  old_y == 0  ) {
1853 		ls.set_progress(12);
1854 	}
1855 
1856 	if(  sets->get_lake()  ) {
1857 		create_lakes( old_x, old_y );
1858 	}
1859 
1860 	if (  old_x == 0  &&  old_y == 0  ) {
1861 		ls.set_progress(13);
1862 	}
1863 
1864 	// set climates in new area and old map near seam
1865 	for(  sint16 iy = 0;  iy < new_size_y;  iy++  ) {
1866 		for(  sint16 ix = (iy >= old_y - 19) ? 0 : max( old_x - 19, 0 );  ix < new_size_x;  ix++  ) {
1867 			calc_climate( koord( ix, iy ), false );
1868 		}
1869 	}
1870 	if (  old_x == 0  &&  old_y == 0  ) {
1871 		ls.set_progress(14);
1872 	}
1873 
1874 	create_beaches( old_x, old_y );
1875 	if (  old_x == 0  &&  old_y == 0  ) {
1876 		ls.set_progress(15);
1877 	}
1878 
1879 	if (  old_x > 0  &&  old_y > 0  ) {
1880 		// and calculate transitions in a 1 tile larger area
1881 		for(  sint16 iy = 0;  iy < new_size_y;  iy++  ) {
1882 			for(  sint16 ix = (iy >= old_y - 20) ? 0 : max( old_x - 20, 0 );  ix < new_size_x;  ix++  ) {
1883 				recalc_transitions( koord( ix, iy ) );
1884 			}
1885 		}
1886 	}
1887 	else {
1888 		// new world -> calculate all transitions
1889 		world_xy_loop(&karte_t::recalc_transitions_loop, 0);
1890 		ls.set_progress(16);
1891 	}
1892 
1893 	// now recalc the images of the old map near the seam ...
1894 	for(  sint16 y = 0;  y < old_y - 20;  y++  ) {
1895 		for(  sint16 x = max( old_x - 20, 0 );  x < old_x;  x++  ) {
1896 			lookup_kartenboden_nocheck(x,y)->calc_image();
1897 		}
1898 	}
1899 	for(  sint16 y = max( old_y - 20, 0 );  y < old_y;  y++) {
1900 		for(  sint16 x = 0;  x < old_x;  x++  ) {
1901 			lookup_kartenboden_nocheck(x,y)->calc_image();
1902 		}
1903 	}
1904 
1905 	// eventual update origin
1906 	switch(  settings.get_rotation()  ) {
1907 		case 1: {
1908 			settings.set_origin_y( settings.get_origin_y() - new_size_y + old_y );
1909 			break;
1910 		}
1911 		case 2: {
1912 			settings.set_origin_x( settings.get_origin_x() - new_size_x + old_x );
1913 			settings.set_origin_y( settings.get_origin_y() - new_size_y + old_y );
1914 			break;
1915 		}
1916 		case 3: {
1917 			settings.set_origin_x( settings.get_origin_x() - new_size_y + old_y );
1918 			break;
1919 		}
1920 	}
1921 
1922 	distribute_groundobjs_cities( sets->get_city_count(), sets->get_mean_citizen_count(), old_x, old_y );
1923 
1924 	// hausbauer_t::new_world(); <- this would reinit monuments! do not do this!
1925 	factory_builder_t::new_world();
1926 	set_schedule_counter();
1927 
1928 	// Refresh the haltlist for the affected tiles / stations.
1929 	// It is enough to check the tile just at the border ...
1930 	uint16 const cov = settings.get_station_coverage();
1931 	if(  old_y < new_size_y  ) {
1932 		for(  sint16 y=0;  y<old_y;  y++  ) {
1933 			for(  sint16 x=max(0,old_x-cov);  x<old_x;  x++  ) {
1934 				const planquadrat_t* pl = access_nocheck(x,y);
1935 				for(  uint8 i=0;  i < pl->get_boden_count();  i++  ) {
1936 					// update halt
1937 					halthandle_t h = pl->get_boden_bei(i)->get_halt();
1938 					if(  h.is_bound()  ) {
1939 						for(  sint16 xp=max(0,x-cov);  xp<min(new_size_x,x+cov+1);  xp++  ) {
1940 							for(  sint16 yp=y;  yp<min(new_size_y,y+cov+1);  yp++  ) {
1941 								access_nocheck(xp,yp)->add_to_haltlist(h);
1942 							}
1943 						}
1944 					}
1945 				}
1946 			}
1947 		}
1948 	}
1949 	if(  old_x < new_size_x  ) {
1950 		for(  sint16 y=max(0,old_y-cov);  y<old_y;  y++  ) {
1951 			for(  sint16 x=0;  x<old_x;  x++  ) {
1952 				const planquadrat_t* pl = access_nocheck(x,y);
1953 				for(  uint8 i=0;  i < pl->get_boden_count();  i++  ) {
1954 					// update halt
1955 					halthandle_t h = pl->get_boden_bei(i)->get_halt();
1956 					if(  h.is_bound()  ) {
1957 						for(  sint16 xp=x;  xp<min(new_size_x,x+cov+1);  xp++  ) {
1958 							for(  sint16 yp=max(0,y-cov);  yp<min(new_size_y,y+cov+1);  yp++  ) {
1959 								access_nocheck(xp,yp)->add_to_haltlist(h);
1960 							}
1961 						}
1962 					}
1963 				}
1964 			}
1965 		}
1966 	}
1967 	clear_random_mode( MAP_CREATE_RANDOM );
1968 
1969 	if ( old_x != 0 ) {
1970 		if(is_display_init()) {
1971 			display_show_pointer(true);
1972 		}
1973 		mute_sound(false);
1974 
1975 		minimap_t::is_visible = minimap_was_visible;
1976 		minimap_t::get_instance()->init();
1977 		minimap_t::get_instance()->calc_map();
1978 		minimap_t::get_instance()->set_display_mode( minimap_t::get_instance()->get_display_mode() );
1979 
1980 		set_dirty();
1981 		reset_timer();
1982 	}
1983 	// update main menu
1984 	tool_t::update_toolbars();
1985 }
1986 
1987 
1988 
karte_t()1989 karte_t::karte_t() :
1990 	settings(env_t::default_settings),
1991 	convoi_array(0),
1992 	attractions(16),
1993 	stadt(0)
1994 {
1995 	destroying = false;
1996 
1997 	// length of day and other time stuff
1998 	ticks_per_world_month_shift = 20;
1999 	ticks_per_world_month = (1 << ticks_per_world_month_shift);
2000 	last_step_ticks = 0;
2001 	server_last_announce_time = 0;
2002 	last_interaction = dr_time();
2003 	step_mode = PAUSE_FLAG;
2004 	time_multiplier = 16;
2005 	next_midi_time = next_step_time = last_step_time = 0;
2006 	fix_ratio_frame_time = 200;
2007 	idle_time = 0;
2008 	network_frame_count = 0;
2009 	sync_steps = 0;
2010 	sync_steps_barrier = sync_steps;
2011 
2012 	for(  uint i=0;  i<MAX_PLAYER_COUNT;  i++  ) {
2013 		selected_tool[i] = tool_t::general_tool[TOOL_QUERY];
2014 	}
2015 
2016 	viewport = new viewport_t(this);
2017 
2018 	set_dirty();
2019 
2020 	// for new world just set load version to current savegame version
2021 	load_version = loadsave_t::int_version( env_t::savegame_version_str, NULL );
2022 
2023 	// standard prices
2024 	goods_manager_t::set_multiplier( 1000 );
2025 
2026 	zeiger = 0;
2027 	plan = 0;
2028 
2029 	grid_hgts = 0;
2030 	water_hgts = 0;
2031 	schedule_counter = 0;
2032 	nosave_warning = nosave = false;
2033 	loaded_rotation = 0;
2034 	last_year = 1930;
2035 	last_month = 0;
2036 
2037 	for(int i=0; i<MAX_PLAYER_COUNT ; i++) {
2038 		players[i] = NULL;
2039 		MEMZERO(player_password_hash[i]);
2040 	}
2041 
2042 	// no distance to show at first ...
2043 	show_distance = koord3d::invalid;
2044 	scenario = NULL;
2045 
2046 	map_counter = 0;
2047 
2048 	msg = new message_t();
2049 	cached_size.x = 0;
2050 	cached_size.y = 0;
2051 
2052 	records = new records_t(this->msg);
2053 
2054 	// generate ground textures once
2055 	ground_desc_t::init_ground_textures(this);
2056 
2057 	// set single instance
2058 	world = this;
2059 }
2060 
2061 
~karte_t()2062 karte_t::~karte_t()
2063 {
2064 	is_sound = false;
2065 
2066 	destroy();
2067 
2068 	// not deleting the tools of this map ...
2069 	delete viewport;
2070 	delete msg;
2071 	delete records;
2072 
2073 	// unset single instance
2074 	if (world == this) {
2075 		world = NULL;
2076 	}
2077 }
2078 
can_lower_plan_to(const player_t * player,sint16 x,sint16 y,sint8 h) const2079 const char* karte_t::can_lower_plan_to(const player_t *player, sint16 x, sint16 y, sint8 h) const
2080 {
2081 	const planquadrat_t *plan = access(x,y);
2082 
2083 	if(  plan==NULL  ) {
2084 		return "";
2085 	}
2086 
2087 	if(  h < groundwater - 3  ) {
2088 		return "";
2089 	}
2090 
2091 	const sint8 hmax = plan->get_kartenboden()->get_hoehe();
2092 	if(  (hmax == h  ||  hmax == h - 1)  &&  (plan->get_kartenboden()->get_grund_hang() == 0  ||  is_plan_height_changeable( x, y ))  ) {
2093 		return NULL;
2094 	}
2095 
2096 	if(  !is_plan_height_changeable(x, y)  ) {
2097 		return "";
2098 	}
2099 
2100 	// tunnel slope below?
2101 	grund_t *gr = plan->get_boden_in_hoehe( h - 1 );
2102 	if(  !gr  ) {
2103 		gr = plan->get_boden_in_hoehe( h - 2 );
2104 	}
2105 	if(  !gr  && settings.get_way_height_clearance()==2  ) {
2106 		gr = plan->get_boden_in_hoehe( h - 3 );
2107 	}
2108 	if(  gr  &&  h < gr->get_pos().z + slope_t::max_diff( gr->get_weg_hang() ) + settings.get_way_height_clearance()  ) {
2109 		return "";
2110 	}
2111 
2112 	// tunnel below?
2113 	while(h < hmax) {
2114 		if(plan->get_boden_in_hoehe(h)) {
2115 			return "";
2116 		}
2117 		h ++;
2118 	}
2119 
2120 	// check allowance by scenario
2121 	if (get_scenario()->is_scripted()) {
2122 		return get_scenario()->is_work_allowed_here(player, TOOL_LOWER_LAND|GENERAL_TOOL, ignore_wt, plan->get_kartenboden()->get_pos());
2123 	}
2124 
2125 	return NULL;
2126 }
2127 
2128 
can_raise_plan_to(const player_t * player,sint16 x,sint16 y,sint8 h) const2129 const char* karte_t::can_raise_plan_to(const player_t *player, sint16 x, sint16 y, sint8 h) const
2130 {
2131 	const planquadrat_t *plan = access(x,y);
2132 	if(  plan == 0  ||  !is_plan_height_changeable(x, y)  ) {
2133 		return "";
2134 	}
2135 
2136 	// irgendwo eine Bruecke im Weg?
2137 	int hmin = plan->get_kartenboden()->get_hoehe();
2138 	while(h > hmin) {
2139 		if(plan->get_boden_in_hoehe(h)) {
2140 			return "";
2141 		}
2142 		h --;
2143 	}
2144 
2145 	// check allowance by scenario
2146 	if (get_scenario()->is_scripted()) {
2147 		return get_scenario()->is_work_allowed_here(player, TOOL_RAISE_LAND|GENERAL_TOOL, ignore_wt, plan->get_kartenboden()->get_pos());
2148 	}
2149 
2150 	return NULL;
2151 }
2152 
2153 
is_plan_height_changeable(sint16 x,sint16 y) const2154 bool karte_t::is_plan_height_changeable(sint16 x, sint16 y) const
2155 {
2156 	const planquadrat_t *plan = access(x,y);
2157 	bool ok = true;
2158 
2159 	if(plan != NULL) {
2160 		grund_t *gr = plan->get_kartenboden();
2161 
2162 		ok = (gr->ist_natur() || gr->is_water())  &&  !gr->hat_wege()  &&  !gr->is_halt();
2163 
2164 		for(  int i=0; ok  &&  i<gr->get_top(); i++  ) {
2165 			const obj_t *obj = gr->obj_bei(i);
2166 			assert(obj != NULL);
2167 			ok =
2168 				obj->get_typ() == obj_t::baum  ||
2169 				obj->get_typ() == obj_t::zeiger  ||
2170 				obj->get_typ() == obj_t::wolke  ||
2171 				obj->get_typ() == obj_t::sync_wolke  ||
2172 				obj->get_typ() == obj_t::async_wolke  ||
2173 				obj->get_typ() == obj_t::groundobj;
2174 		}
2175 	}
2176 
2177 	return ok;
2178 }
2179 
2180 
comp(const karte_t::terraformer_t::node_t & a,const karte_t::terraformer_t::node_t & b)2181 bool karte_t::terraformer_t::node_t::comp(const karte_t::terraformer_t::node_t& a, const karte_t::terraformer_t::node_t& b)
2182 {
2183 	int diff = a.x- b.x;
2184 	if (diff == 0) {
2185 		diff = a.y - b.y;
2186 	}
2187 	return diff<0;
2188 }
2189 
2190 
add_node(bool raise,sint16 x,sint16 y,sint8 hsw,sint8 hse,sint8 hne,sint8 hnw)2191 void karte_t::terraformer_t::add_node(bool raise, sint16 x, sint16 y, sint8 hsw, sint8 hse, sint8 hne, sint8 hnw)
2192 {
2193 	if (!welt->is_within_limits(x,y)) {
2194 		return;
2195 	}
2196 	node_t test(x, y, hsw, hse, hne, hnw, actual_flag^3);
2197 	node_t *other = list.insert_unique_ordered(test, node_t::comp);
2198 
2199 	sint8 factor = raise ? +1 : -1;
2200 
2201 	if (other) {
2202 		for(int i=0; i<4; i++) {
2203 			if (factor*other->h[i] < factor*test.h[i]) {
2204 				other->h[i] = test.h[i];
2205 				other->changed |= actual_flag^3;
2206 				ready = false;
2207 			}
2208 		}
2209 	}
2210 	else {
2211 		ready = false;
2212 	}
2213 }
2214 
add_raise_node(sint16 x,sint16 y,sint8 hsw,sint8 hse,sint8 hne,sint8 hnw)2215 void karte_t::terraformer_t::add_raise_node(sint16 x, sint16 y, sint8 hsw, sint8 hse, sint8 hne, sint8 hnw)
2216 {
2217 	add_node(true, x, y, hsw, hse, hne, hnw);
2218 }
2219 
add_lower_node(sint16 x,sint16 y,sint8 hsw,sint8 hse,sint8 hne,sint8 hnw)2220 void karte_t::terraformer_t::add_lower_node(sint16 x, sint16 y, sint8 hsw, sint8 hse, sint8 hne, sint8 hnw)
2221 {
2222 	add_node(false, x, y, hsw, hse, hne, hnw);
2223 }
2224 
iterate(bool raise)2225 void karte_t::terraformer_t::iterate(bool raise)
2226 {
2227 	while( !ready) {
2228 		actual_flag ^= 3; // flip bits
2229 		// clear new_flag bit
2230 		FOR(vector_tpl<node_t>, &i, list) {
2231 			i.changed &= actual_flag;
2232 		}
2233 		// process nodes with actual_flag set
2234 		ready = true;
2235 		for(uint32 j=0; j < list.get_count(); j++) {
2236 			node_t& i = list[j];
2237 			if (i.changed & actual_flag) {
2238 				i.changed &= ~ actual_flag;
2239 				if (raise) {
2240 					welt->prepare_raise(*this, i.x, i.y, i.h[0], i.h[1], i.h[2], i.h[3]);
2241 				}
2242 				else {
2243 					welt->prepare_lower(*this, i.x, i.y, i.h[0], i.h[1], i.h[2], i.h[3]);
2244 				}
2245 			}
2246 		}
2247 	}
2248 }
2249 
2250 
can_raise_all(const player_t * player,bool keep_water) const2251 const char* karte_t::terraformer_t::can_raise_all(const player_t *player, bool keep_water) const
2252 {
2253 	const char* err = NULL;
2254 	FOR(vector_tpl<node_t>, const &i, list) {
2255 		err = welt->can_raise_to(player, i.x, i.y, keep_water, i.h[0], i.h[1], i.h[2], i.h[3]);
2256 		if (err) return err;
2257 	}
2258 	return NULL;
2259 }
2260 
can_lower_all(const player_t * player) const2261 const char* karte_t::terraformer_t::can_lower_all(const player_t *player) const
2262 {
2263 	const char* err = NULL;
2264 	FOR(vector_tpl<node_t>, const &i, list) {
2265 		err = welt->can_lower_to(player, i.x, i.y, i.h[0], i.h[1], i.h[2], i.h[3]);
2266 		if (err) {
2267 			return err;
2268 		}
2269 	}
2270 	return NULL;
2271 }
2272 
raise_all()2273 int karte_t::terraformer_t::raise_all()
2274 {
2275 	int n=0;
2276 	FOR(vector_tpl<node_t>, &i, list) {
2277 		n += welt->raise_to(i.x, i.y, i.h[0], i.h[1], i.h[2], i.h[3]);
2278 	}
2279 	return n;
2280 }
2281 
lower_all()2282 int karte_t::terraformer_t::lower_all()
2283 {
2284 	int n=0;
2285 	FOR(vector_tpl<node_t>, &i, list) {
2286 		n += welt->lower_to(i.x, i.y, i.h[0], i.h[1], i.h[2], i.h[3]);
2287 	}
2288 	return n;
2289 }
2290 
2291 
can_raise_to(const player_t * player,sint16 x,sint16 y,bool keep_water,sint8 hsw,sint8 hse,sint8 hne,sint8 hnw) const2292 const char* karte_t::can_raise_to(const player_t *player, sint16 x, sint16 y, bool keep_water, sint8 hsw, sint8 hse, sint8 hne, sint8 hnw) const
2293 {
2294 	assert(is_within_limits(x,y));
2295 	grund_t *gr = lookup_kartenboden_nocheck(x,y);
2296 	const sint8 water_hgt = get_water_hgt_nocheck(x,y);
2297 
2298 	const sint8 max_hgt = max(max(hsw,hse),max(hne,hnw));
2299 
2300 	if(  gr->is_water()  &&  keep_water  &&  max_hgt > water_hgt  ) {
2301 		return "";
2302 	}
2303 
2304 	const char* err = can_raise_plan_to(player, x, y, max_hgt);
2305 
2306 	return err;
2307 }
2308 
2309 
prepare_raise(terraformer_t & digger,sint16 x,sint16 y,sint8 hsw,sint8 hse,sint8 hne,sint8 hnw)2310 void karte_t::prepare_raise(terraformer_t& digger, sint16 x, sint16 y, sint8 hsw, sint8 hse, sint8 hne, sint8 hnw)
2311 {
2312 	assert(is_within_limits(x,y));
2313 	grund_t *gr = lookup_kartenboden_nocheck(x,y);
2314 	const sint8 water_hgt = get_water_hgt_nocheck(x,y);
2315 	const sint8 h0 = gr->get_hoehe();
2316 	// old height
2317 	const sint8 h0_sw = gr->is_water() ? min(water_hgt, lookup_hgt_nocheck(x,y+1) )   : h0 + corner_sw( gr->get_grund_hang() );
2318 	const sint8 h0_se = gr->is_water() ? min(water_hgt, lookup_hgt_nocheck(x+1,y+1) ) : h0 + corner_se( gr->get_grund_hang() );
2319 	const sint8 h0_ne = gr->is_water() ? min(water_hgt, lookup_hgt_nocheck(x+1,y) )   : h0 + corner_ne( gr->get_grund_hang() );
2320 	const sint8 h0_nw = gr->is_water() ? min(water_hgt, lookup_hgt_nocheck(x,y) )     : h0 + corner_nw( gr->get_grund_hang() );
2321 
2322 	// new height
2323 	const sint8 hn_sw = max(hsw, h0_sw);
2324 	const sint8 hn_se = max(hse, h0_se);
2325 	const sint8 hn_ne = max(hne, h0_ne);
2326 	const sint8 hn_nw = max(hnw, h0_nw);
2327 
2328 	// nothing to do?
2329 	if(  !gr->is_water()  &&  h0_sw >= hsw  &&  h0_se >= hse  &&  h0_ne >= hne  &&  h0_nw >= hnw  ) {
2330 		return;
2331 	}
2332 
2333 	// calc new height and slope
2334 	const sint8 hneu = min( min( hn_sw, hn_se ), min( hn_ne, hn_nw ) );
2335 	const sint8 hmaxneu = max( max( hn_sw, hn_se ), max( hn_ne, hn_nw ) );
2336 
2337 	const uint8 max_hdiff = ground_desc_t::double_grounds ? 2 : 1;
2338 
2339 	bool ok = (hmaxneu - hneu <= max_hdiff); // may fail on water tiles since lookup_hgt might be modified from previous raise_to calls
2340 	if(  !ok  &&  !gr->is_water()  ) {
2341 		assert(false);
2342 	}
2343 
2344 	// sw
2345 	if (h0_sw < hsw) {
2346 		digger.add_raise_node( x - 1, y + 1, hsw - max_hdiff, hsw - max_hdiff, hsw, hsw - max_hdiff );
2347 	}
2348 	// s
2349 	if (h0_sw < hsw  ||  h0_se < hse) {
2350 		const sint8 hs = max( hse, hsw ) - max_hdiff;
2351 		digger.add_raise_node( x, y + 1, hs, hs, hse, hsw );
2352 	}
2353 	// se
2354 	if (h0_se < hse) {
2355 		digger.add_raise_node( x + 1, y + 1, hse - max_hdiff, hse - max_hdiff, hse - max_hdiff, hse );
2356 	}
2357 	// e
2358 	if (h0_se < hse  ||  h0_ne < hne) {
2359 		const sint8 he = max( hse, hne ) - max_hdiff;
2360 		digger.add_raise_node( x + 1, y, hse, he, he, hne );
2361 	}
2362 	// ne
2363 	if (h0_ne < hne) {
2364 		digger.add_raise_node( x + 1,y - 1, hne, hne - max_hdiff, hne - max_hdiff, hne - max_hdiff );
2365 	}
2366 	// n
2367 	if (h0_nw < hnw  ||  h0_ne < hne) {
2368 		const sint8 hn = max( hnw, hne ) - max_hdiff;
2369 		digger.add_raise_node( x, y - 1, hnw, hne, hn, hn );
2370 	}
2371 	// nw
2372 	if (h0_nw < hnw) {
2373 		digger.add_raise_node( x - 1, y - 1, hnw - max_hdiff, hnw, hnw - max_hdiff, hnw - max_hdiff );
2374 	}
2375 	// w
2376 	if (h0_sw < hsw  ||  h0_nw < hnw) {
2377 		const sint8 hw = max( hnw, hsw ) - max_hdiff;
2378 		digger.add_raise_node( x - 1, y, hw, hsw, hnw, hw );
2379 	}
2380 }
2381 
2382 
raise_to(sint16 x,sint16 y,sint8 hsw,sint8 hse,sint8 hne,sint8 hnw)2383 int karte_t::raise_to(sint16 x, sint16 y, sint8 hsw, sint8 hse, sint8 hne, sint8 hnw)
2384 {
2385 	int n=0;
2386 	assert(is_within_limits(x,y));
2387 	grund_t *gr = lookup_kartenboden_nocheck(x,y);
2388 	const sint8 water_hgt = get_water_hgt_nocheck(x,y);
2389 	const sint8 h0 = gr->get_hoehe();
2390 
2391 	// old height
2392 	const sint8 h0_sw = gr->is_water() ? min(water_hgt, lookup_hgt_nocheck(x,y+1) )   : h0 + corner_sw( gr->get_grund_hang() );
2393 	const sint8 h0_se = gr->is_water() ? min(water_hgt, lookup_hgt_nocheck(x+1,y+1) ) : h0 + corner_se( gr->get_grund_hang() );
2394 	const sint8 h0_ne = gr->is_water() ? min(water_hgt, lookup_hgt_nocheck(x+1,y) )   : h0 + corner_ne( gr->get_grund_hang() );
2395 	const sint8 h0_nw = gr->is_water() ? min(water_hgt, lookup_hgt_nocheck(x,y) )     : h0 + corner_nw( gr->get_grund_hang() );
2396 
2397 	// new height
2398 	const sint8 hn_sw = max(hsw, h0_sw);
2399 	const sint8 hn_se = max(hse, h0_se);
2400 	const sint8 hn_ne = max(hne, h0_ne);
2401 	const sint8 hn_nw = max(hnw, h0_nw);
2402 	// nothing to do?
2403 	if(  !gr->is_water()  &&  h0_sw >= hsw  &&  h0_se >= hse  &&  h0_ne >= hne  &&  h0_nw >= hnw  ) {
2404 		return 0;
2405 	}
2406 
2407 	// calc new height and slope
2408 	const sint8 hneu = min( min( hn_sw, hn_se ), min( hn_ne, hn_nw ) );
2409 	const sint8 hmaxneu = max( max( hn_sw, hn_se ), max( hn_ne, hn_nw ) );
2410 
2411 	const uint8 max_hdiff = ground_desc_t::double_grounds ? 2 : 1;
2412 	const sint8 disp_hneu = max( hneu, water_hgt );
2413 	const sint8 disp_hn_sw = max( hn_sw, water_hgt );
2414 	const sint8 disp_hn_se = max( hn_se, water_hgt );
2415 	const sint8 disp_hn_ne = max( hn_ne, water_hgt );
2416 	const sint8 disp_hn_nw = max( hn_nw, water_hgt );
2417 	const uint8 sneu = (disp_hn_sw - disp_hneu) + ((disp_hn_se - disp_hneu) * 3) + ((disp_hn_ne - disp_hneu) * 9) + ((disp_hn_nw - disp_hneu) * 27);
2418 
2419 	bool ok = (hmaxneu - hneu <= max_hdiff); // may fail on water tiles since lookup_hgt might be modified from previous raise_to calls
2420 	if (!ok && !gr->is_water()) {
2421 		assert(false);
2422 	}
2423 	// change height and slope, for water tiles only if they will become land
2424 	if(  !gr->is_water()  ||  (hmaxneu > water_hgt  ||  (hneu == water_hgt  &&  hmaxneu == water_hgt)  )  ) {
2425 		gr->set_pos( koord3d( x, y, disp_hneu ) );
2426 		gr->set_grund_hang( (slope_t::type)sneu );
2427 		access_nocheck(x,y)->angehoben();
2428 		set_water_hgt(x, y, groundwater-4);
2429 	}
2430 
2431 	// update north point in grid
2432 	set_grid_hgt(x, y, hn_nw);
2433 	calc_climate(koord(x,y), true);
2434 	if ( x == cached_size.x ) {
2435 		// update eastern grid coordinates too if we are in the edge.
2436 		set_grid_hgt(x+1, y, hn_ne);
2437 		set_grid_hgt(x+1, y+1, hn_se);
2438 	}
2439 	if ( y == cached_size.y ) {
2440 		// update southern grid coordinates too if we are in the edge.
2441 		set_grid_hgt(x, y+1, hn_sw);
2442 		set_grid_hgt(x+1, y+1, hn_se);
2443 	}
2444 
2445 	n += hn_sw - h0_sw + hn_se - h0_se + hn_ne - h0_ne  + hn_nw - h0_nw;
2446 
2447 	lookup_kartenboden_nocheck(x,y)->calc_image();
2448 	if ( (x+1) < cached_size.x ) {
2449 		lookup_kartenboden_nocheck(x+1,y)->calc_image();
2450 	}
2451 	if ( (y+1) < cached_size.y ) {
2452 		lookup_kartenboden_nocheck(x,y+1)->calc_image();
2453 	}
2454 
2455 	return n;
2456 }
2457 
2458 
2459 // raise height in the hgt-array
raise_grid_to(sint16 x,sint16 y,sint8 h)2460 void karte_t::raise_grid_to(sint16 x, sint16 y, sint8 h)
2461 {
2462 	if(is_within_grid_limits(x,y)) {
2463 		const sint32 offset = x + y*(cached_grid_size.x+1);
2464 
2465 		if(  grid_hgts[offset] < h  ) {
2466 			grid_hgts[offset] = h;
2467 
2468 			const sint8 hh = h - (ground_desc_t::double_grounds ? 2 : 1);
2469 
2470 			// set new height of neighbor grid points
2471 			raise_grid_to(x-1, y-1, hh);
2472 			raise_grid_to(x  , y-1, hh);
2473 			raise_grid_to(x+1, y-1, hh);
2474 			raise_grid_to(x-1, y  , hh);
2475 			raise_grid_to(x+1, y  , hh);
2476 			raise_grid_to(x-1, y+1, hh);
2477 			raise_grid_to(x  , y+1, hh);
2478 			raise_grid_to(x+1, y+1, hh);
2479 		}
2480 	}
2481 }
2482 
2483 
grid_raise(const player_t * player,koord k,const char * & err)2484 int karte_t::grid_raise(const player_t *player, koord k, const char*&err)
2485 {
2486 	int n = 0;
2487 
2488 	if(is_within_grid_limits(k)) {
2489 
2490 		const grund_t *gr = lookup_kartenboden_gridcoords(k);
2491 		const slope_t::type corner_to_raise = get_corner_to_operate(k);
2492 
2493 		const sint16 x = gr->get_pos().x;
2494 		const sint16 y = gr->get_pos().y;
2495 		const sint8 hgt = gr->get_hoehe(corner_to_raise);
2496 
2497 		sint8 hsw, hse, hne, hnw;
2498 		if(  !gr->is_water()  ) {
2499 			const sint8 f = ground_desc_t::double_grounds ?  2 : 1;
2500 			const sint8 o = ground_desc_t::double_grounds ?  1 : 0;
2501 
2502 			hsw = hgt - o + scorner_sw( corner_to_raise ) * f;
2503 			hse = hgt - o + scorner_se( corner_to_raise ) * f;
2504 			hne = hgt - o + scorner_ne( corner_to_raise ) * f;
2505 			hnw = hgt - o + scorner_nw( corner_to_raise ) * f;
2506 		}
2507 		else {
2508 			hsw = hse = hne = hnw = hgt;
2509 		}
2510 
2511 		terraformer_t digger(this);
2512 		digger.add_raise_node(x, y, hsw, hse, hne, hnw);
2513 		digger.iterate(true);
2514 
2515 		err = digger.can_raise_all(player);
2516 		if (err) {
2517 			return 0;
2518 		}
2519 		n = digger.raise_all();
2520 
2521 		// force world full redraw, or background could be dirty.
2522 		set_dirty();
2523 
2524 		if(  max_height < lookup_kartenboden_gridcoords(k)->get_hoehe()  ) {
2525 			max_height = lookup_kartenboden_gridcoords(k)->get_hoehe();
2526 		}
2527 	}
2528 	return (n+3)>>2;
2529 }
2530 
2531 
prepare_lower(terraformer_t & digger,sint16 x,sint16 y,sint8 hsw,sint8 hse,sint8 hne,sint8 hnw)2532 void karte_t::prepare_lower(terraformer_t& digger, sint16 x, sint16 y, sint8 hsw, sint8 hse, sint8 hne, sint8 hnw)
2533 {
2534 	assert(is_within_limits(x,y));
2535 	grund_t *gr = lookup_kartenboden_nocheck(x,y);
2536 	const sint8 water_hgt = get_water_hgt_nocheck(x,y);
2537 	const sint8 h0 = gr->get_hoehe();
2538 	// which corners have to be raised?
2539 	const sint8 h0_sw = gr->is_water() ? min( water_hgt, lookup_hgt_nocheck(x,y+1) )   : h0 + corner_sw( gr->get_grund_hang() );
2540 	const sint8 h0_se = gr->is_water() ? min( water_hgt, lookup_hgt_nocheck(x+1,y+1) ) : h0 + corner_se( gr->get_grund_hang() );
2541 	const sint8 h0_ne = gr->is_water() ? min( water_hgt, lookup_hgt_nocheck(x,y+1) )   : h0 + corner_ne( gr->get_grund_hang() );
2542 	const sint8 h0_nw = gr->is_water() ? min( water_hgt, lookup_hgt_nocheck(x,y) )     : h0 + corner_nw( gr->get_grund_hang() );
2543 
2544 	const uint8 max_hdiff = ground_desc_t::double_grounds ?  2 : 1;
2545 
2546 	// sw
2547 	if (h0_sw > hsw) {
2548 		digger.add_lower_node(x - 1, y + 1, hsw + max_hdiff, hsw + max_hdiff, hsw, hsw + max_hdiff);
2549 	}
2550 	// s
2551 	if (h0_se > hse || h0_sw > hsw) {
2552 		const sint8 hs = min( hse, hsw ) + max_hdiff;
2553 		digger.add_lower_node( x, y + 1, hs, hs, hse, hsw);
2554 	}
2555 	// se
2556 	if (h0_se > hse) {
2557 		digger.add_lower_node( x + 1, y + 1, hse + max_hdiff, hse + max_hdiff, hse + max_hdiff, hse);
2558 	}
2559 	// e
2560 	if (h0_se > hse || h0_ne > hne) {
2561 		const sint8 he = max( hse, hne ) + max_hdiff;
2562 		digger.add_lower_node( x + 1,y, hse, he, he, hne);
2563 	}
2564 	// ne
2565 	if (h0_ne > hne) {
2566 		digger.add_lower_node( x + 1, y - 1, hne, hne + max_hdiff, hne + max_hdiff, hne + max_hdiff);
2567 	}
2568 	// n
2569 	if (h0_nw > hnw  ||  h0_ne > hne) {
2570 		const sint8 hn = min( hnw, hne ) + max_hdiff;
2571 		digger.add_lower_node( x, y - 1, hnw, hne, hn, hn);
2572 	}
2573 	// nw
2574 	if (h0_nw > hnw) {
2575 		digger.add_lower_node( x - 1, y - 1, hnw + max_hdiff, hnw, hnw + max_hdiff, hnw + max_hdiff);
2576 	}
2577 	// w
2578 	if (h0_nw > hnw || h0_sw > hsw) {
2579 		const sint8 hw = min( hnw, hsw ) + max_hdiff;
2580 		digger.add_lower_node( x - 1, y, hw, hsw, hnw, hw);
2581 	}
2582 }
2583 
2584 // lower plan
2585 // new heights for each corner given
2586 // only test corners in ctest to avoid infinite loops
can_lower_to(const player_t * player,sint16 x,sint16 y,sint8 hsw,sint8 hse,sint8 hne,sint8 hnw) const2587 const char* karte_t::can_lower_to(const player_t* player, sint16 x, sint16 y, sint8 hsw, sint8 hse, sint8 hne, sint8 hnw) const
2588 {
2589 	assert(is_within_limits(x,y));
2590 
2591 	const sint8 hneu = min( min( hsw, hse ), min( hne, hnw ) );
2592 	// water heights
2593 	// check if need to lower water height for higher neighbouring tiles
2594 	for(  sint16 i = 0 ;  i < 8 ;  i++  ) {
2595 		const koord neighbour = koord( x, y ) + koord::neighbours[i];
2596 		if(  is_within_limits(neighbour)  &&  get_water_hgt_nocheck(neighbour) > hneu  ) {
2597 			if (!is_plan_height_changeable( neighbour.x, neighbour.y )) {
2598 				return "";
2599 			}
2600 		}
2601 	}
2602 
2603 	return can_lower_plan_to(player, x, y, hneu );
2604 }
2605 
2606 
lower_to(sint16 x,sint16 y,sint8 hsw,sint8 hse,sint8 hne,sint8 hnw)2607 int karte_t::lower_to(sint16 x, sint16 y, sint8 hsw, sint8 hse, sint8 hne, sint8 hnw)
2608 {
2609 	int n=0;
2610 	assert(is_within_limits(x,y));
2611 	grund_t *gr = lookup_kartenboden_nocheck(x,y);
2612 	const uint8 old_slope = gr->get_grund_hang();
2613 	sint8 water_hgt = get_water_hgt_nocheck(x,y);
2614 	const sint8 h0 = gr->get_hoehe();
2615 	// old height
2616 	const sint8 h0_sw = gr->is_water() ? min( water_hgt, lookup_hgt_nocheck(x,y+1) )   : h0 + corner_sw( gr->get_grund_hang() );
2617 	const sint8 h0_se = gr->is_water() ? min( water_hgt, lookup_hgt_nocheck(x+1,y+1) ) : h0 + corner_se( gr->get_grund_hang() );
2618 	const sint8 h0_ne = gr->is_water() ? min( water_hgt, lookup_hgt_nocheck(x+1,y) )   : h0 + corner_ne( gr->get_grund_hang() );
2619 	const sint8 h0_nw = gr->is_water() ? min( water_hgt, lookup_hgt_nocheck(x,y) )     : h0 + corner_nw( gr->get_grund_hang() );
2620 	// new height
2621 	const sint8 hn_sw = min(hsw, h0_sw);
2622 	const sint8 hn_se = min(hse, h0_se);
2623 	const sint8 hn_ne = min(hne, h0_ne);
2624 	const sint8 hn_nw = min(hnw, h0_nw);
2625 	// nothing to do?
2626 	if(  gr->is_water()  ) {
2627 		if(  h0_nw <= hnw  ) {
2628 			return 0;
2629 		}
2630 	}
2631 	else {
2632 		if(  h0_sw <= hsw  &&  h0_se <= hse  &&  h0_ne <= hne  &&  h0_nw <= hnw  ) {
2633 			return 0;
2634 		}
2635 	}
2636 
2637 	// calc new height and slope
2638 	const sint8 hneu = min( min( hn_sw, hn_se ), min( hn_ne, hn_nw ) );
2639 	const sint8 hmaxneu = max( max( hn_sw, hn_se ), max( hn_ne, hn_nw ) );
2640 
2641 	// only slope could have been shores
2642 	if(  old_slope  ) {
2643 		// if there are any shore corners, then the new tile must be all water since it is lowered
2644 		const bool make_water =
2645 			get_water_hgt_nocheck(x,y) <= lookup_hgt_nocheck(x,y)  ||
2646 			get_water_hgt_nocheck(x+1,y) <= lookup_hgt_nocheck(x+1,y)  ||
2647 			get_water_hgt_nocheck(x,y+1) <= lookup_hgt_nocheck(x,y+1)  ||
2648 			get_water_hgt_nocheck(x+1,y+1) <= lookup_hgt_nocheck(x+1,y+1);
2649 		if(  make_water  ) {
2650 			sint8 water_table = water_hgt >= hneu ? water_hgt : hneu;
2651 			set_water_hgt(x, y, water_table );
2652 		}
2653 	}
2654 
2655 	if(  hneu >= water_hgt  ) {
2656 		// calculate water table from surrounding tiles - start off with height on this tile
2657 		sint8 water_table = water_hgt >= h0 ? water_hgt : groundwater - 4;
2658 
2659 		/* we test each corner in turn to see whether it is at the base height of the tile
2660 			if it is we then mark the 3 surrounding tiles for that corner for checking
2661 			surrounding tiles are indicated by bits going anti-clockwise from
2662 			(binary) 00000001 for north-west through to (binary) 10000000 for north
2663 			as this is the order of directions used by koord::neighbours[] */
2664 
2665 		uint8 neighbour_flags = 0;
2666 
2667 		if(  hn_nw == hneu  ) {
2668 			neighbour_flags |= 0x83;
2669 		}
2670 		if(  hn_ne == hneu  ) {
2671 			neighbour_flags |= 0xe0;
2672 		}
2673 		if(  hn_se == hneu  ) {
2674 			neighbour_flags |= 0x38;
2675 		}
2676 		if(  hn_sw == hneu  ) {
2677 			neighbour_flags |= 0x0e;
2678 		}
2679 
2680 		for(  sint16 i = 0;  i < 8 ;  i++  ) {
2681 			const koord neighbour = koord( x, y ) + koord::neighbours[i];
2682 
2683 			// here we look at the bit in neighbour_flags for this direction
2684 			// we shift it i bits to the right and test the least significant bit
2685 
2686 			if(  is_within_limits( neighbour )  &&  ((neighbour_flags >> i) & 1)  ) {
2687 				grund_t *gr2 = lookup_kartenboden_nocheck( neighbour );
2688 				const sint8 water_hgt_neighbour = get_water_hgt_nocheck( neighbour );
2689 				if(  gr2  &&  (water_hgt_neighbour >= gr2->get_hoehe())  &&  water_hgt_neighbour <= hneu  ) {
2690 					water_table = max( water_table, water_hgt_neighbour );
2691 				}
2692 			}
2693 		}
2694 
2695 		for(  sint16 i = 0;  i < 8 ;  i++  ) {
2696 			const koord neighbour = koord( x, y ) + koord::neighbours[i];
2697 			if(  is_within_limits( neighbour )  ) {
2698 				grund_t *gr2 = lookup_kartenboden_nocheck( neighbour );
2699 				if(  gr2  &&  gr2->get_hoehe() < water_table  ) {
2700 					i = 8;
2701 					water_table = groundwater - 4;
2702 				}
2703 			}
2704 		}
2705 
2706 		// only allow water table to be lowered (except for case of sea level)
2707 		// this prevents severe (errors!
2708 		if(  water_table < get_water_hgt_nocheck(x,y)  ) {
2709 			water_hgt = water_table;
2710 			set_water_hgt(x, y, water_table );
2711 		}
2712 	}
2713 
2714 	// calc new height and slope
2715 	const sint8 disp_hneu = max( hneu, water_hgt );
2716 	const sint8 disp_hn_sw = max( hn_sw, water_hgt );
2717 	const sint8 disp_hn_se = max( hn_se, water_hgt );
2718 	const sint8 disp_hn_ne = max( hn_ne, water_hgt );
2719 	const sint8 disp_hn_nw = max( hn_nw, water_hgt );
2720 	const uint8 sneu = (disp_hn_sw - disp_hneu) + ((disp_hn_se - disp_hneu) * 3) + ((disp_hn_ne - disp_hneu) * 9) + ((disp_hn_nw - disp_hneu) * 27);
2721 
2722 	// change height and slope for land tiles only
2723 	if(  !gr->is_water()  ||  (hmaxneu > water_hgt)  ) {
2724 		gr->set_pos( koord3d( x, y, disp_hneu ) );
2725 		gr->set_grund_hang( (slope_t::type)sneu );
2726 		access_nocheck(x,y)->abgesenkt();
2727 	}
2728 	// update north point in grid
2729 	set_grid_hgt(x, y, hn_nw);
2730 	if ( x == cached_size.x ) {
2731 		// update eastern grid coordinates too if we are in the edge.
2732 		set_grid_hgt(x+1, y, hn_ne);
2733 		set_grid_hgt(x+1, y+1, hn_se);
2734 	}
2735 	if ( y == cached_size.y ) {
2736 		// update southern grid coordinates too if we are in the edge.
2737 		set_grid_hgt(x, y+1, hn_sw);
2738 		set_grid_hgt(x+1, y+1, hn_se);
2739 	}
2740 
2741 	// water heights
2742 	// lower water height for higher neighbouring tiles
2743 	// find out how high water is
2744 	for(  sint16 i = 0;  i < 8;  i++  ) {
2745 		const koord neighbour = koord( x, y ) + koord::neighbours[i];
2746 		if(  is_within_limits( neighbour )  ) {
2747 			const sint8 water_hgt_neighbour = get_water_hgt_nocheck( neighbour );
2748 			if(water_hgt_neighbour > hneu  ) {
2749 				if(  min_hgt_nocheck( neighbour ) < water_hgt_neighbour  ) {
2750 					// convert to flat ground before lowering water level
2751 					raise_grid_to( neighbour.x, neighbour.y, water_hgt_neighbour );
2752 					raise_grid_to( neighbour.x + 1, neighbour.y, water_hgt_neighbour );
2753 					raise_grid_to( neighbour.x, neighbour.y + 1, water_hgt_neighbour );
2754 					raise_grid_to( neighbour.x + 1, neighbour.y + 1, water_hgt_neighbour );
2755 				}
2756 				set_water_hgt( neighbour, hneu );
2757 				access_nocheck(neighbour)->correct_water();
2758 			}
2759 		}
2760 	}
2761 
2762 	calc_climate( koord( x, y ), false );
2763 	for(  sint16 i = 0;  i < 8;  i++  ) {
2764 		const koord neighbour = koord( x, y ) + koord::neighbours[i];
2765 		calc_climate( neighbour, false );
2766 	}
2767 
2768 	// recalc landscape images - need to extend 2 in each direction
2769 	for(  sint16 j = y - 2;  j <= y + 2;  j++  ) {
2770 		for(  sint16 i = x - 2;  i <= x + 2;  i++  ) {
2771 			if(  is_within_limits( i, j )  /*&&  (i != x  ||  j != y)*/  ) {
2772 				recalc_transitions( koord (i, j ) );
2773 			}
2774 		}
2775 	}
2776 
2777 	n += h0_sw-hn_sw + h0_se-hn_se + h0_ne-hn_ne + h0_nw-hn_nw;
2778 
2779 	lookup_kartenboden_nocheck(x,y)->calc_image();
2780 	if( (x+1) < cached_size.x ) {
2781 		lookup_kartenboden_nocheck(x+1,y)->calc_image();
2782 	}
2783 	if( (y+1) < cached_size.y ) {
2784 		lookup_kartenboden_nocheck(x,y+1)->calc_image();
2785 	}
2786 	return n;
2787 }
2788 
2789 
lower_grid_to(sint16 x,sint16 y,sint8 h)2790 void karte_t::lower_grid_to(sint16 x, sint16 y, sint8 h)
2791 {
2792 	if(is_within_grid_limits(x,y)) {
2793 		const sint32 offset = x + y*(cached_grid_size.x+1);
2794 
2795 		if(  grid_hgts[offset] > h  ) {
2796 			grid_hgts[offset] = h;
2797 			sint8 hh = h + 2;
2798 			// set new height of neighbor grid points
2799 			lower_grid_to(x-1, y-1, hh);
2800 			lower_grid_to(x  , y-1, hh);
2801 			lower_grid_to(x+1, y-1, hh);
2802 			lower_grid_to(x-1, y  , hh);
2803 			lower_grid_to(x+1, y  , hh);
2804 			lower_grid_to(x-1, y+1, hh);
2805 			lower_grid_to(x  , y+1, hh);
2806 			lower_grid_to(x+1, y+1, hh);
2807 		}
2808 	}
2809 }
2810 
2811 
grid_lower(const player_t * player,koord k,const char * & err)2812 int karte_t::grid_lower(const player_t *player, koord k, const char*&err)
2813 {
2814 	int n = 0;
2815 
2816 	if(is_within_grid_limits(k)) {
2817 
2818 		const grund_t *gr = lookup_kartenboden_gridcoords(k);
2819 		const slope_t::type corner_to_lower = get_corner_to_operate(k);
2820 
2821 		const sint16 x = gr->get_pos().x;
2822 		const sint16 y = gr->get_pos().y;
2823 		const sint8 hgt = gr->get_hoehe(corner_to_lower);
2824 
2825 		const sint8 f = ground_desc_t::double_grounds ?  2 : 1;
2826 		const sint8 o = ground_desc_t::double_grounds ?  1 : 0;
2827 		const sint8 hsw = hgt + o - scorner_sw( corner_to_lower ) * f;
2828 		const sint8 hse = hgt + o - scorner_se( corner_to_lower ) * f;
2829 		const sint8 hne = hgt + o - scorner_ne( corner_to_lower ) * f;
2830 		const sint8 hnw = hgt + o - scorner_nw( corner_to_lower ) * f;
2831 
2832 		terraformer_t digger(this);
2833 		digger.add_lower_node(x, y, hsw, hse, hne, hnw);
2834 		digger.iterate(false);
2835 
2836 		err = digger.can_lower_all(player);
2837 		if (err) {
2838 			return 0;
2839 		}
2840 
2841 		n = digger.lower_all();
2842 		err = NULL;
2843 
2844 		// force world full redraw, or background could be dirty.
2845 		set_dirty();
2846 
2847 		if(  min_height > min_hgt_nocheck( koord(x,y) )  ) {
2848 			min_height = min_hgt_nocheck( koord(x,y) );
2849 		}
2850 	}
2851 	return (n+3)>>2;
2852 }
2853 
2854 
can_flatten_tile(player_t * player,koord k,sint8 hgt,bool keep_water,bool make_underwater_hill)2855 bool karte_t::can_flatten_tile(player_t *player, koord k, sint8 hgt, bool keep_water, bool make_underwater_hill)
2856 {
2857 	return flatten_tile(player, k, hgt, keep_water, make_underwater_hill, true /* just check */);
2858 }
2859 
2860 
2861 // make a flat level at this position (only used for AI at the moment)
flatten_tile(player_t * player,koord k,sint8 hgt,bool keep_water,bool make_underwater_hill,bool justcheck)2862 bool karte_t::flatten_tile(player_t *player, koord k, sint8 hgt, bool keep_water, bool make_underwater_hill, bool justcheck)
2863 {
2864 	int n = 0;
2865 	bool ok = true;
2866 	const grund_t *gr = lookup_kartenboden(k);
2867 	const slope_t::type slope = gr->get_grund_hang();
2868 	const sint8 old_hgt = make_underwater_hill  &&  gr->is_water() ? min_hgt(k) : gr->get_hoehe();
2869 	const sint8 max_hgt = old_hgt + slope_t::max_diff(slope);
2870 	if(  max_hgt > hgt  ) {
2871 
2872 		terraformer_t digger(this);
2873 		digger.add_lower_node(k.x, k.y, hgt, hgt, hgt, hgt);
2874 		digger.iterate(false);
2875 
2876 		ok = digger.can_lower_all(player) == NULL;
2877 
2878 		if (ok  &&  !justcheck) {
2879 			n += digger.lower_all();
2880 		}
2881 	}
2882 	if(  ok  &&  old_hgt < hgt  ) {
2883 
2884 		terraformer_t digger(this);
2885 		digger.add_raise_node(k.x, k.y, hgt, hgt, hgt, hgt);
2886 		digger.iterate(true);
2887 
2888 		ok = digger.can_raise_all(player, keep_water) == NULL;
2889 
2890 		if (ok  &&  !justcheck) {
2891 			n += digger.raise_all();
2892 		}
2893 	}
2894 	// was changed => pay for it
2895 	if(n>0) {
2896 		n = (n+3) >> 2;
2897 		player_t::book_construction_costs(player, n * settings.cst_alter_land, k, ignore_wt);
2898 	}
2899 	return ok;
2900 }
2901 
2902 
store_player_password_hash(uint8 player_nr,const pwd_hash_t & hash)2903 void karte_t::store_player_password_hash( uint8 player_nr, const pwd_hash_t& hash )
2904 {
2905 	player_password_hash[player_nr] = hash;
2906 }
2907 
2908 
clear_player_password_hashes()2909 void karte_t::clear_player_password_hashes()
2910 {
2911 	for(int i=0; i<MAX_PLAYER_COUNT ; i++) {
2912 		player_password_hash[i].clear();
2913 		if (players[i]) {
2914 			players[i]->check_unlock(player_password_hash[i]);
2915 		}
2916 	}
2917 }
2918 
2919 
rdwr_player_password_hashes(loadsave_t * file)2920 void karte_t::rdwr_player_password_hashes(loadsave_t *file)
2921 {
2922 	pwd_hash_t dummy;
2923 	for(  int i=0;  i<PLAYER_UNOWNED; i++  ) {
2924 		pwd_hash_t *p = players[i] ? &players[i]->access_password_hash() : &dummy;
2925 		for(  uint8 j=0; j<20; j++) {
2926 			file->rdwr_byte( (*p)[j] );
2927 		}
2928 	}
2929 }
2930 
2931 
call_change_player_tool(uint8 cmd,uint8 player_nr,uint16 param,bool scripted_call)2932 void karte_t::call_change_player_tool(uint8 cmd, uint8 player_nr, uint16 param, bool scripted_call)
2933 {
2934 	if (env_t::networkmode) {
2935 		nwc_chg_player_t *nwc = new nwc_chg_player_t(sync_steps, map_counter, cmd, player_nr, param, scripted_call);
2936 
2937 		network_send_server(nwc);
2938 	}
2939 	else {
2940 		change_player_tool(cmd, player_nr, param, !get_public_player()->is_locked()  ||  scripted_call, true);
2941 		// update the window
2942 		ki_kontroll_t* playerwin = (ki_kontroll_t*)win_get_magic(magic_ki_kontroll_t);
2943 		if (playerwin) {
2944 			playerwin->update_data();
2945 		}
2946 	}
2947 }
2948 
2949 
change_player_tool(uint8 cmd,uint8 player_nr,uint16 param,bool public_player_unlocked,bool exec)2950 bool karte_t::change_player_tool(uint8 cmd, uint8 player_nr, uint16 param, bool public_player_unlocked, bool exec)
2951 {
2952 	switch(cmd) {
2953 		case new_player: {
2954 			// only public player can start AI
2955 			if(  (param != player_t::HUMAN  &&  !public_player_unlocked)  ||  param >= player_t::MAX_AI  ) {
2956 				return false;
2957 			}
2958 			// range check, player already existent?
2959 			if(  player_nr >= PLAYER_UNOWNED  ||   get_player(player_nr)  ) {
2960 				return false;
2961 			}
2962 			if(exec) {
2963 				init_new_player( player_nr, (uint8) param );
2964 				// activate/deactivate AI immediately
2965 				player_t *player = get_player(player_nr);
2966 				if (param != player_t::HUMAN  &&  player) {
2967 					player->set_active(true);
2968 					settings.set_player_active(player_nr, player->is_active());
2969 				}
2970 			}
2971 			return true;
2972 		}
2973 		case toggle_freeplay: {
2974 			// only public player can change freeplay mode
2975 			if (!public_player_unlocked  ||  !settings.get_allow_player_change()) {
2976 				return false;
2977 			}
2978 			if (exec) {
2979 				settings.set_freeplay( !settings.is_freeplay() );
2980 			}
2981 			return true;
2982 		}
2983 		case delete_player: {
2984 			// range check, player existent?
2985 			if ( player_nr >= PLAYER_UNOWNED  ||   get_player(player_nr)==NULL ) {
2986 				return false;
2987 			}
2988 			if (exec) {
2989 				remove_player(player_nr);
2990 			}
2991 			return true;
2992 		}
2993 		// unknown command: delete
2994 		default: ;
2995 	}
2996 	return false;
2997 }
2998 
2999 
set_tool(tool_t * tool_in,player_t * player)3000 void karte_t::set_tool( tool_t *tool_in, player_t *player )
3001 {
3002 	if(  get_random_mode()&LOAD_RANDOM  ) {
3003 		dbg->warning("karte_t::set_tool", "Ignored tool %i during loading.", tool_in->get_id() );
3004 		return;
3005 	}
3006 	bool needs_check = !tool_in->no_check();
3007 	// check for scenario conditions
3008 	if(  needs_check  &&  !scenario->is_tool_allowed(player, tool_in->get_id(), tool_in->get_waytype())  ) {
3009 		return;
3010 	}
3011 	// check for password-protected players
3012 	if(  (!tool_in->is_init_network_save()  ||  !tool_in->is_work_network_save())  &&  needs_check  &&
3013 		 !(tool_in->get_id()==(TOOL_CHANGE_PLAYER|SIMPLE_TOOL)  ||  tool_in->get_id()==(TOOL_ADD_MESSAGE|SIMPLE_TOOL))  &&
3014 		 player  &&  player->is_locked()  ) {
3015 		// player is currently password protected => request unlock first
3016 		create_win( -1, -1, new password_frame_t(player), w_info, magic_pwd_t + player->get_player_nr() );
3017 		return;
3018 	}
3019 	tool_in->flags |= event_get_last_control_shift();
3020 	if(!env_t::networkmode  ||  tool_in->is_init_network_save()  ) {
3021 		local_set_tool(tool_in, player);
3022 	}
3023 	else {
3024 		// queue tool for network
3025 		nwc_tool_t *nwc = new nwc_tool_t(player, tool_in, zeiger->get_pos(), steps, map_counter, true);
3026 		network_send_server(nwc);
3027 	}
3028 }
3029 
3030 
3031 // set a new tool on our client, calls init
local_set_tool(tool_t * tool_in,player_t * player)3032 void karte_t::local_set_tool( tool_t *tool_in, player_t * player )
3033 {
3034 	tool_in->flags |= tool_t::WFL_LOCAL;
3035 	// now call init
3036 	bool init_result = tool_in->init(player);
3037 	// for unsafe tools init() must return false
3038 	assert(tool_in->is_init_network_save()  ||  !init_result);
3039 
3040 	if (player  && init_result  &&  !tool_in->is_scripted()) {
3041 
3042 		set_dirty();
3043 		tool_t *sp_tool = selected_tool[player->get_player_nr()];
3044 		if(tool_in != sp_tool) {
3045 
3046 			// reinit same tool => do not play sound twice
3047 			sound_play(SFX_SELECT);
3048 
3049 			// only exit, if it is not the same tool again ...
3050 			sp_tool->flags |= tool_t::WFL_LOCAL;
3051 			sp_tool->exit(player);
3052 			sp_tool->flags =0;
3053 		}
3054 
3055 		if(  player==active_player  ) {
3056 			// reset pointer
3057 			koord3d zpos = zeiger->get_pos();
3058 			// remove marks
3059 			zeiger->change_pos( koord3d::invalid );
3060 			// set new cursor properties
3061 			tool_in->init_cursor(zeiger);
3062 			// .. and mark again (if the position is acceptable for the tool)
3063 			if( tool_in->check_valid_pos(zpos.get_2d())) {
3064 				zeiger->change_pos( zpos );
3065 			}
3066 			else {
3067 				zeiger->change_pos( koord3d::invalid );
3068 			}
3069 		}
3070 		selected_tool[player->get_player_nr()] = tool_in;
3071 	}
3072 	tool_in->flags = 0;
3073 	toolbar_last_used_t::last_used_tools->append( tool_in, player );
3074 }
3075 
3076 
min_hgt_nocheck(const koord k) const3077 sint8 karte_t::min_hgt_nocheck(const koord k) const
3078 {
3079 	// more optimised version of min_hgt code
3080 	const sint8 * p = &grid_hgts[k.x + k.y*(sint32)(cached_grid_size.x+1)];
3081 
3082 	const int h1 = *p;
3083 	const int h2 = *(p+1);
3084 	const int h3 = *(p+get_size().x+2);
3085 	const int h4 = *(p+get_size().x+1);
3086 
3087 	return min(min(h1,h2), min(h3,h4));
3088 }
3089 
3090 
max_hgt_nocheck(const koord k) const3091 sint8 karte_t::max_hgt_nocheck(const koord k) const
3092 {
3093 	// more optimised version of max_hgt code
3094 	const sint8 * p = &grid_hgts[k.x + k.y*(sint32)(cached_grid_size.x+1)];
3095 
3096 	const int h1 = *p;
3097 	const int h2 = *(p+1);
3098 	const int h3 = *(p+get_size().x+2);
3099 	const int h4 = *(p+get_size().x+1);
3100 
3101 	return max(max(h1,h2), max(h3,h4));
3102 }
3103 
3104 
min_hgt(const koord k) const3105 sint8 karte_t::min_hgt(const koord k) const
3106 {
3107 	const sint8 h1 = lookup_hgt(k);
3108 	const sint8 h2 = lookup_hgt(k+koord(1, 0));
3109 	const sint8 h3 = lookup_hgt(k+koord(1, 1));
3110 	const sint8 h4 = lookup_hgt(k+koord(0, 1));
3111 
3112 	return min(min(h1,h2), min(h3,h4));
3113 }
3114 
3115 
max_hgt(const koord k) const3116 sint8 karte_t::max_hgt(const koord k) const
3117 {
3118 	const sint8 h1 = lookup_hgt(k);
3119 	const sint8 h2 = lookup_hgt(k+koord(1, 0));
3120 	const sint8 h3 = lookup_hgt(k+koord(1, 1));
3121 	const sint8 h4 = lookup_hgt(k+koord(0, 1));
3122 
3123 	return max(max(h1,h2), max(h3,h4));
3124 }
3125 
3126 
3127 planquadrat_t *rotate90_new_plan;
3128 sint8 *rotate90_new_water;
3129 
rotate90_plans(sint16 x_min,sint16 x_max,sint16 y_min,sint16 y_max)3130 void karte_t::rotate90_plans(sint16 x_min, sint16 x_max, sint16 y_min, sint16 y_max)
3131 {
3132 	const int LOOP_BLOCK = 64;
3133 	if(  (loaded_rotation + settings.get_rotation()) & 1  ) {  // 1 || 3
3134 		for(  int yy = y_min;  yy < y_max;  yy += LOOP_BLOCK  ) {
3135 			for(  int xx = x_min;  xx < x_max;  xx += LOOP_BLOCK  ) {
3136 				for(  int y = yy;  y < min(yy + LOOP_BLOCK, y_max);  y++  ) {
3137 					for(  int x = xx;  x < min(xx + LOOP_BLOCK, x_max);  x++  ) {
3138 						const int nr = x + (y * cached_grid_size.x);
3139 						const int new_nr = (cached_size.y - y) + (x * cached_grid_size.y);
3140 						// first rotate everything on the ground(s)
3141 						for(  uint i = 0;  i < plan[nr].get_boden_count();  i++  ) {
3142 							plan[nr].get_boden_bei(i)->rotate90();
3143 						}
3144 						// rotate climate transitions
3145 						rotate_transitions( koord( x, y ) );
3146 						// now: rotate all things on the map
3147 						swap(rotate90_new_plan[new_nr], plan[nr]);
3148 					}
3149 				}
3150 			}
3151 		}
3152 	}
3153 	else {
3154 		// first: rotate all things on the map
3155 		for(  int xx = x_min;  xx < x_max;  xx += LOOP_BLOCK  ) {
3156 			for(  int yy = y_min;  yy < y_max;  yy += LOOP_BLOCK  ) {
3157 				for(  int x = xx;  x < min(xx + LOOP_BLOCK, x_max);  x++  ) {
3158 					for(  int y=yy;  y < min(yy + LOOP_BLOCK, y_max);  y++  ) {
3159 						// rotate climate transitions
3160 						rotate_transitions( koord( x, y ) );
3161 						const int nr = x + (y * cached_grid_size.x);
3162 						const int new_nr = (cached_size.y - y) + (x * cached_grid_size.y);
3163 						swap(rotate90_new_plan[new_nr], plan[nr]);
3164 					}
3165 				}
3166 			}
3167 		}
3168 		// now rotate everything on the ground(s)
3169 		for(  int xx = x_min;  xx < x_max;  xx += LOOP_BLOCK  ) {
3170 			for(  int yy = y_min;  yy < y_max;  yy += LOOP_BLOCK  ) {
3171 				for(  int x = xx;  x < min(xx + LOOP_BLOCK, x_max);  x++  ) {
3172 					for(  int y = yy;  y < min(yy + LOOP_BLOCK, y_max);  y++  ) {
3173 						const int new_nr = (cached_size.y - y) + (x * cached_grid_size.y);
3174 						for(  uint i = 0;  i < rotate90_new_plan[new_nr].get_boden_count();  i++  ) {
3175 							rotate90_new_plan[new_nr].get_boden_bei(i)->rotate90();
3176 						}
3177 					}
3178 				}
3179 			}
3180 		}
3181 	}
3182 
3183 	// rotate water
3184 	for(  int xx = 0;  xx < cached_grid_size.x;  xx += LOOP_BLOCK  ) {
3185 		for(  int yy = y_min;  yy < y_max;  yy += LOOP_BLOCK  ) {
3186 			for(  int x = xx;  x < min( xx + LOOP_BLOCK, cached_grid_size.x );  x++  ) {
3187 				int nr = x + (yy * cached_grid_size.x);
3188 				int new_nr = (cached_size.y - yy) + (x * cached_grid_size.y);
3189 				for(  int y = yy;  y < min( yy + LOOP_BLOCK, y_max );  y++  ) {
3190 					rotate90_new_water[new_nr] = water_hgts[nr];
3191 					nr += cached_grid_size.x;
3192 					new_nr--;
3193 				}
3194 			}
3195 		}
3196 	}
3197 }
3198 
3199 
rotate90()3200 void karte_t::rotate90()
3201 {
3202 DBG_MESSAGE( "karte_t::rotate90()", "called" );
3203 	// assume we can save this rotation
3204 	nosave_warning = nosave = false;
3205 
3206 	//announce current target rotation
3207 	settings.rotate90();
3208 
3209 	// clear marked region
3210 	zeiger->change_pos( koord3d::invalid );
3211 
3212 	// preprocessing, detach stops from factories to prevent crash
3213 	FOR(vector_tpl<halthandle_t>, const s, haltestelle_t::get_alle_haltestellen()) {
3214 		s->release_factory_links();
3215 	}
3216 
3217 	//rotate plans in parallel posix thread ...
3218 	rotate90_new_plan = new planquadrat_t[cached_grid_size.y * cached_grid_size.x];
3219 	rotate90_new_water = new sint8[cached_grid_size.y * cached_grid_size.x];
3220 
3221 	world_xy_loop(&karte_t::rotate90_plans, 0);
3222 
3223 	grund_t::finish_rotate90();
3224 
3225 	delete [] plan;
3226 	plan = rotate90_new_plan;
3227 	delete [] water_hgts;
3228 	water_hgts = rotate90_new_water;
3229 
3230 	// rotate heightmap
3231 	sint8 *new_hgts = new sint8[(cached_grid_size.x+1)*(cached_grid_size.y+1)];
3232 	const int LOOP_BLOCK = 64;
3233 	for(  int yy=0;  yy<=cached_grid_size.y;  yy+=LOOP_BLOCK  ) {
3234 		for(  int xx=0;  xx<=cached_grid_size.x;  xx+=LOOP_BLOCK  ) {
3235 			for(  int x=xx;  x<=min(xx+LOOP_BLOCK,cached_grid_size.x);  x++  ) {
3236 				for(  int y=yy;  y<=min(yy+LOOP_BLOCK,cached_grid_size.y);  y++  ) {
3237 					const int nr = x+(y*(cached_grid_size.x+1));
3238 					const int new_nr = (cached_grid_size.y-y)+(x*(cached_grid_size.y+1));
3239 					new_hgts[new_nr] = grid_hgts[nr];
3240 				}
3241 			}
3242 		}
3243 	}
3244 	delete [] grid_hgts;
3245 	grid_hgts = new_hgts;
3246 
3247 	// rotate borders
3248 	sint16 xw = cached_size.x;
3249 	cached_size.x = cached_size.y;
3250 	cached_size.y = xw;
3251 
3252 	int wx = cached_grid_size.x;
3253 	cached_grid_size.x = cached_grid_size.y;
3254 	cached_grid_size.y = wx;
3255 
3256 	// now step all towns (to generate passengers)
3257 	FOR(weighted_vector_tpl<stadt_t*>, const i, stadt) {
3258 		i->rotate90(cached_size.x);
3259 	}
3260 
3261 	// fixed order factory, halts, convois
3262 	FOR(slist_tpl<fabrik_t*>, const f, fab_list) {
3263 		f->rotate90(cached_size.x);
3264 	}
3265 	// after rotation of factories, rotate everything that holds freight: stations and convoys
3266 	FOR(vector_tpl<halthandle_t>, const s, haltestelle_t::get_alle_haltestellen()) {
3267 		s->rotate90(cached_size.x);
3268 	}
3269 
3270 	FOR(vector_tpl<convoihandle_t>, const i, convoi_array) {
3271 		i->rotate90(cached_size.x);
3272 	}
3273 
3274 	for(  int i=0;  i<MAX_PLAYER_COUNT;  i++  ) {
3275 		if(  players[i]  ) {
3276 			players[i]->rotate90( cached_size.x );
3277 		}
3278 	}
3279 
3280 	// rotate label texts
3281 	FOR(slist_tpl<koord>, & l, labels) {
3282 		l.rotate90(cached_size.x);
3283 	}
3284 
3285 	// rotate view
3286 	viewport->rotate90( cached_size.x );
3287 
3288 	// rotate messages
3289 	msg->rotate90( cached_size.x );
3290 
3291 	// rotate view in dialog windows
3292 	win_rotate90( cached_size.x );
3293 
3294 	if( cached_grid_size.x != cached_grid_size.y ) {
3295 		// the map must be reinit
3296 		minimap_t::get_instance()->init();
3297 	}
3298 
3299 	//  rotate map search array
3300 	factory_builder_t::new_world();
3301 
3302 	// update minimap
3303 	if( minimap_t::is_visible) {
3304 		minimap_t::get_instance()->set_display_mode( minimap_t::get_instance()->get_display_mode() );
3305 	}
3306 
3307 	get_scenario()->rotate90( cached_size.x );
3308 
3309 	script_api::rotate90();
3310 
3311 	// finally recalculate schedules for goods in transit ...
3312 	set_schedule_counter();
3313 
3314 	set_dirty();
3315 }
3316 // -------- Verwaltung von Fabriken -----------------------------
3317 
3318 
add_fab(fabrik_t * fab)3319 bool karte_t::add_fab(fabrik_t *fab)
3320 {
3321 //DBG_MESSAGE("karte_t::add_fab()","fab = %p",fab);
3322 	assert(fab != NULL);
3323 	fab_list.insert( fab );
3324 	goods_in_game.clear(); // Force rebuild of goods list
3325 	return true;
3326 }
3327 
3328 
3329 // beware: must remove also links from stops and towns
rem_fab(fabrik_t * fab)3330 bool karte_t::rem_fab(fabrik_t *fab)
3331 {
3332 	if(!fab_list.remove( fab )) {
3333 		return false;
3334 	}
3335 
3336 	// Force rebuild of goods list
3337 	goods_in_game.clear();
3338 
3339 	// now all the interwoven connections must be cleared
3340 	koord k = fab->get_pos().get_2d();
3341 	planquadrat_t* plan = access(k);
3342 	if(plan) {
3343 
3344 		// we need a copy, since the verbinde fabriken is modifying the list
3345 		halthandle_t list[16];
3346 		const uint8 count = plan->get_haltlist_count();
3347 		assert(count<16);
3348 		memcpy( list, plan->get_haltlist(), count*sizeof(halthandle_t) );
3349 		for( uint8 i=0;  i<count;  i++  ) {
3350 			// first remove all the tiles that do not connect
3351 			plan->remove_from_haltlist( list[i] );
3352 			// then reconnect
3353 			list[i]->verbinde_fabriken();
3354 		}
3355 
3356 		// remove all links from factories
3357 		FOR(slist_tpl<fabrik_t*>, const fab, fab_list) {
3358 			fab->rem_lieferziel(k);
3359 			fab->rem_supplier(k);
3360 		}
3361 
3362 		// remove all links to cities
3363 		fab->clear_target_cities();
3364 
3365 		// finally delete it
3366 		delete fab;
3367 
3368 		// recalculate factory position map
3369 		factory_builder_t::new_world();
3370 	}
3371 	return true;
3372 }
3373 
3374 
3375 /*----------------------------------------------------------------------------------------------------------------------*/
3376 /* same procedure for tourist attractions */
3377 
3378 
add_attraction(gebaeude_t * gb)3379 void karte_t::add_attraction(gebaeude_t *gb)
3380 {
3381 	assert(gb != NULL);
3382 	attractions.append( gb, gb->get_tile()->get_desc()->get_level() );
3383 
3384 	// Knightly : add links between this attraction and all cities
3385 	FOR(weighted_vector_tpl<stadt_t*>, const c, stadt) {
3386 		c->add_target_attraction(gb);
3387 	}
3388 }
3389 
3390 
remove_attraction(gebaeude_t * gb)3391 void karte_t::remove_attraction(gebaeude_t *gb)
3392 {
3393 	assert(gb != NULL);
3394 	attractions.remove( gb );
3395 
3396 	// Knightly : remove links between this attraction and all cities
3397 	FOR(weighted_vector_tpl<stadt_t*>, const c, stadt) {
3398 		c->remove_target_attraction(gb);
3399 	}
3400 }
3401 
3402 
3403 // -------- Verwaltung von Staedten -----------------------------
3404 
find_nearest_city(const koord k) const3405 stadt_t *karte_t::find_nearest_city(const koord k) const
3406 {
3407 	uint32 min_dist = 99999999;
3408 	bool contains = false;
3409 	stadt_t *best = NULL;	// within city limits
3410 
3411 	if(  is_within_limits(k)  ) {
3412 		FOR(  weighted_vector_tpl<stadt_t*>,  const s,  stadt  ) {
3413 			if(  k.x >= s->get_linksoben().x  &&  k.y >= s->get_linksoben().y  &&  k.x < s->get_rechtsunten().x  &&  k.y < s->get_rechtsunten().y  ) {
3414 				const uint32 dist = koord_distance( k, s->get_center() );
3415 				if(  !contains  ) {
3416 					// no city within limits => this is best
3417 					best = s;
3418 					min_dist = dist;
3419 				}
3420 				else if(  dist < min_dist  ) {
3421 					best = s;
3422 					min_dist = dist;
3423 				}
3424 				contains = true;
3425 			}
3426 			else if(  !contains  ) {
3427 				// so far no cities found within its city limit
3428 				const uint32 dist = koord_distance( k, s->get_center() );
3429 				if(  dist < min_dist  ) {
3430 					best = s;
3431 					min_dist = dist;
3432 				}
3433 			}
3434 		}
3435 	}
3436 	return best;
3437 }
3438 
3439 
3440 // -------- Verwaltung von synchronen Objekten ------------------
3441 
add(sync_steppable * obj)3442 void karte_t::sync_list_t::add(sync_steppable *obj)
3443 {
3444 	assert(!sync_step_running);
3445 	list.append(obj);
3446 }
3447 
remove(sync_steppable * obj)3448 void karte_t::sync_list_t::remove(sync_steppable *obj)
3449 {
3450 	if(sync_step_running) {
3451 		if (obj == currently_deleting) {
3452 			return;
3453 		}
3454 		assert(false);
3455 	}
3456 	else {
3457 		list.remove(obj);
3458 	}
3459 }
3460 
clear()3461 void karte_t::sync_list_t::clear()
3462 {
3463 	list.clear();
3464 	currently_deleting = NULL;
3465 	sync_step_running = false;
3466 }
3467 
sync_step(uint32 delta_t)3468 void karte_t::sync_list_t::sync_step(uint32 delta_t)
3469 {
3470 	sync_step_running = true;
3471 	currently_deleting = NULL;
3472 
3473 	for(uint32 i=0; i<list.get_count();i++) {
3474 		sync_steppable *ss = list[i];
3475 		switch(ss->sync_step(delta_t)) {
3476 			case SYNC_OK:
3477 				break;
3478 			case SYNC_DELETE:
3479 				currently_deleting = ss;
3480 				delete ss;
3481 				currently_deleting = NULL;
3482 				/* fall-through */
3483 			case SYNC_REMOVE:
3484 				ss = list.pop_back();
3485 				if (i < list.get_count()) {
3486 					list[i] = ss;
3487 				}
3488 		}
3489 	}
3490 	sync_step_running = false;
3491 }
3492 
3493 
3494 /*
3495  * this routine is called before an image is displayed
3496  * it moves vehicles and pedestrians
3497  * only time consuming thing are done in step()
3498  * everything else is done here
3499  */
sync_step(uint32 delta_t,bool do_sync_step,bool display)3500 void karte_t::sync_step(uint32 delta_t, bool do_sync_step, bool display )
3501 {
3502 	set_random_mode( SYNC_STEP_RANDOM );
3503 	if(do_sync_step) {
3504 		// only omitted, when called to display a new frame during fast forward
3505 
3506 		// just for progress
3507 		if(  delta_t > 10000  ) {
3508 			dbg->error( "karte_t::sync_step()", "delta_t too large: %li", delta_t );
3509 			delta_t = 10000;
3510 		}
3511 		ticks += delta_t;
3512 
3513 		set_random_mode( INTERACTIVE_RANDOM );
3514 
3515 		/* animations do not require exact sync
3516 		 * foundations etc are added removed frequently during city growth
3517 		 * => they are now in a hastable!
3518 		 */
3519 		sync_eyecandy.sync_step( delta_t );
3520 
3521 		/* pedestrians do not require exact sync and are added/removed frequently
3522 		 * => they are now in a hastable!
3523 		 */
3524 		sync_way_eyecandy.sync_step( delta_t );
3525 
3526 		clear_random_mode( INTERACTIVE_RANDOM );
3527 
3528 		sync.sync_step( delta_t );
3529 
3530 		ticker::update();
3531 	}
3532 
3533 	if(display) {
3534 		// only omitted in fast forward mode for the magic steps
3535 
3536 		for(int x=0; x<MAX_PLAYER_COUNT-1; x++) {
3537 			if(players[x]) {
3538 				players[x]->age_messages(delta_t);
3539 			}
3540 		}
3541 
3542 		// change view due to following a convoi?
3543 		convoihandle_t follow_convoi = viewport->get_follow_convoi();
3544 		if(follow_convoi.is_bound()  &&  follow_convoi->get_vehicle_count()>0) {
3545 			vehicle_t const& v       = *follow_convoi->front();
3546 			koord3d   const  new_pos = v.get_pos();
3547 			if(new_pos!=koord3d::invalid) {
3548 				const sint16 rw = get_tile_raster_width();
3549 				int new_xoff = 0;
3550 				int new_yoff = 0;
3551 				v.get_screen_offset( new_xoff, new_yoff, get_tile_raster_width() );
3552 				new_xoff -= tile_raster_scale_x(-v.get_xoff(), rw);
3553 				new_yoff -= tile_raster_scale_y(-v.get_yoff(), rw) + tile_raster_scale_y(new_pos.z * TILE_HEIGHT_STEP, rw);
3554 				viewport->change_world_position( new_pos.get_2d(), -new_xoff, -new_yoff );
3555 
3556 				// auto underground to follow convois
3557 				if( env_t::follow_convoi_underground ) {
3558 					grund_t *gr = lookup_kartenboden( new_pos.get_2d() );
3559 					bool redraw = false;
3560 					if( new_pos.z < gr->get_hoehe() ) {
3561 						redraw = grund_t::underground_mode == grund_t::ugm_none ? grund_t::underground_level != new_pos.z : true;
3562 						grund_t::set_underground_mode( env_t::follow_convoi_underground, new_pos.z );
3563 					}
3564 					else {
3565 						redraw = grund_t::underground_mode != grund_t::ugm_none;
3566 						grund_t::set_underground_mode( grund_t::ugm_none, 0 );
3567 					}
3568 					if(  redraw  ) {
3569 						// recalc all images on map
3570 						update_underground();
3571 					}
3572 				}
3573 			}
3574 		}
3575 
3576 		// display new frame with water animation
3577 		intr_refresh_display( false );
3578 		update_frame_sleep_time();
3579 	}
3580 	clear_random_mode( SYNC_STEP_RANDOM );
3581 }
3582 
3583 
3584 // does all the magic about frame timing
update_frame_sleep_time()3585 void karte_t::update_frame_sleep_time()
3586 {
3587 	// get average frame time
3588 	uint32 last_ms = dr_time();
3589 	last_frame_ms[last_frame_idx] = last_ms;
3590 	last_frame_idx = (last_frame_idx+1) % 32;
3591 	sint32 ms_diff = (sint32)( last_ms - last_frame_ms[last_frame_idx] );
3592 	if(ms_diff > 0) {
3593 		realFPS = (32000u*16) / ms_diff;
3594 	}
3595 	else {
3596 		realFPS = env_t::fps*16;
3597 		simloops = 60;
3598 	}
3599 
3600 	if(  step_mode&PAUSE_FLAG  ) {
3601 		// not changing pauses
3602 		next_step_time = dr_time() + 1000 / env_t::fps;
3603 		idle_time = 100;
3604 	}
3605 	else if(  step_mode==FIX_RATIO) {
3606 		simloops = realFPS/16;
3607 	}
3608 	else if(step_mode==NORMAL) {
3609 		// calculate simloops
3610 		uint16 last_step = (steps+31)%32;
3611 		if(last_step_nr[last_step]>last_step_nr[steps%32]) {
3612 			simloops = (10000*32l)/(last_step_nr[last_step]-last_step_nr[steps%32]);
3613 		}
3614 		// (de-)activate faster redraw
3615 		env_t::simple_drawing = (env_t::simple_drawing_normal >= get_tile_raster_width());
3616 
3617 		// calculate and activate fast redraw ..
3618 		if(  realFPS > (env_t::fps*17/16)  ) {
3619 			// decrease fast tile zoom by one
3620 			if(  env_t::simple_drawing_normal > env_t::simple_drawing_default  ) {
3621 				env_t::simple_drawing_normal --;
3622 			}
3623 		}
3624 		else if(  realFPS < env_t::fps*16/2  ) {
3625 			// activate simple redraw
3626 			env_t::simple_drawing_normal = max( env_t::simple_drawing_normal, get_tile_raster_width()+1 );
3627 		}
3628 		else if(  realFPS < (env_t::fps*15)  )  {
3629 			// increase fast tile redraw by one if below current tile size
3630 			if(  env_t::simple_drawing_normal <= (get_tile_raster_width()*3)/2  ) {
3631 				env_t::simple_drawing_normal ++;
3632 			}
3633 		}
3634 		else if(  idle_time > 0  ) {
3635 			// decrease fast tile zoom by one
3636 			if(  env_t::simple_drawing_normal > env_t::simple_drawing_default  ) {
3637 				env_t::simple_drawing_normal --;
3638 			}
3639 		}
3640 		env_t::simple_drawing = (env_t::simple_drawing_normal >= get_tile_raster_width());
3641 
3642 		// way too slow => try to increase time ...
3643 		if(  last_ms-last_interaction > 100  ) {
3644 			if(  last_ms-last_interaction > 500  ) {
3645 				set_frame_time( 1+get_frame_time() );
3646 				// more than 1s since last zoom => check if zoom out is a way to improve it
3647 				if(  last_ms-last_interaction > 5000  &&  get_current_tile_raster_width() < 32  ) {
3648 					zoom_factor_up();
3649 					set_dirty();
3650 					last_interaction = last_ms-1000;
3651 				}
3652 			}
3653 			else {
3654 				increase_frame_time();
3655 				increase_frame_time();
3656 				increase_frame_time();
3657 				increase_frame_time();
3658 			}
3659 		}
3660 		else {
3661 			// change frame spacing ... (pause will be changed by step() directly)
3662 			if(realFPS>(env_t::fps*17)) {
3663 				increase_frame_time();
3664 			}
3665 			else if(realFPS<env_t::fps*16) { //15 for deadband
3666 				if(  1000u*16/get_frame_time() < 2*realFPS  ) {
3667 					if(  realFPS < (env_t::fps*16/2)  ) {
3668 						set_frame_time( get_frame_time()-1 );
3669 						next_step_time = last_ms;
3670 					}
3671 					else {
3672 						reduce_frame_time();
3673 					}
3674 				}
3675 				else {
3676 					// do not set time too short!
3677 					set_frame_time( 500/max(1,realFPS/16) );
3678 					next_step_time = last_ms;
3679 				}
3680 			}
3681 		}
3682 	}
3683 	else  { // here only with fyst forward ...
3684 		// try to get 10 fps or lower rate (if set)
3685 		uint32 frame_intervall = max( 100, 1000/env_t::fps );
3686 		if(get_frame_time()>frame_intervall) {
3687 			reduce_frame_time();
3688 		}
3689 		else {
3690 			increase_frame_time();
3691 		}
3692 		// (de-)activate faster redraw
3693 		env_t::simple_drawing = env_t::simple_drawing_fast_forward  ||  (env_t::simple_drawing_normal >= get_tile_raster_width());
3694 	}
3695 }
3696 
3697 
3698 // add an amount to a subcategory
buche(sint64 const betrag,player_cost const type)3699 void karte_t::buche(sint64 const betrag, player_cost const type)
3700 {
3701 	assert(type < MAX_WORLD_COST);
3702 	finance_history_year[0][type] += betrag;
3703 	finance_history_month[0][type] += betrag;
3704 	// to do: check for dependencies
3705 }
3706 
3707 
get_population(stadt_t const * const c)3708 inline sint32 get_population(stadt_t const* const c)
3709 {
3710 	return c->get_einwohner();
3711 }
3712 
3713 
new_month()3714 void karte_t::new_month()
3715 {
3716 	bool need_locality_update = false;
3717 
3718 	update_history();
3719 
3720 	// advance history ...
3721 	last_month_bev = finance_history_month[0][WORLD_CITICENS];
3722 	for(  int hist=0;  hist<karte_t::MAX_WORLD_COST;  hist++  ) {
3723 		for( int y=MAX_WORLD_HISTORY_MONTHS-1; y>0;  y--  ) {
3724 			finance_history_month[y][hist] = finance_history_month[y-1][hist];
3725 		}
3726 	}
3727 
3728 	current_month ++;
3729 	last_month ++;
3730 	if( last_month > 11 ) {
3731 		last_month = 0;
3732 		// check for changed distance weight
3733 		uint32 old_locality_factor = koord::locality_factor;
3734 		koord::locality_factor = settings.get_locality_factor( last_year+1 );
3735 		need_locality_update = (old_locality_factor != koord::locality_factor);
3736 	}
3737 	DBG_MESSAGE("karte_t::new_month()","Month (%d/%d) has started", (last_month%12)+1, last_month/12 );
3738 
3739 	// this should be done before a map update, since the map may want an update of the way usage
3740 //	DBG_MESSAGE("karte_t::new_month()","ways");
3741 	FOR(slist_tpl<weg_t*>, const w, weg_t::get_alle_wege()) {
3742 		w->new_month();
3743 	}
3744 
3745 	// recalc old settings (and maybe update the stops with the current values)
3746 	minimap_t::get_instance()->new_month();
3747 
3748 	INT_CHECK("simworld 1701");
3749 
3750 //	DBG_MESSAGE("karte_t::new_month()","convois");
3751 	// hsiegeln - call new month for convois
3752 	FOR(vector_tpl<convoihandle_t>, const cnv, convoi_array) {
3753 		cnv->new_month();
3754 	}
3755 
3756 	INT_CHECK("simworld 1701");
3757 
3758 //	DBG_MESSAGE("karte_t::new_month()","factories");
3759 	FOR(slist_tpl<fabrik_t*>, const fab, fab_list) {
3760 		fab->new_month();
3761 	}
3762 	INT_CHECK("simworld 1278");
3763 
3764 
3765 //	DBG_MESSAGE("karte_t::new_month()","cities");
3766 	stadt.update_weights(get_population);
3767 	FOR(weighted_vector_tpl<stadt_t*>, const i, stadt) {
3768 		i->new_month(need_locality_update);
3769 	}
3770 
3771 	INT_CHECK("simworld 1282");
3772 
3773 	// player
3774 	for(uint i=0; i<MAX_PLAYER_COUNT; i++) {
3775 		if( i>=2  &&  last_month == 0  &&  !settings.is_freeplay() ) {
3776 			// remove all player (but first and second) who went bankrupt during last year
3777 			if(  players[i] != NULL  &&  players[i]->get_finance()->is_bancrupted()  )
3778 			{
3779 				remove_player(i);
3780 			}
3781 		}
3782 
3783 		if(  players[i] != NULL  ) {
3784 			// if returns false -> remove player
3785 			if (!players[i]->new_month()) {
3786 				remove_player(i);
3787 			}
3788 		}
3789 	}
3790 	// update the window
3791 	ki_kontroll_t* playerwin = (ki_kontroll_t*)win_get_magic(magic_ki_kontroll_t);
3792 	if(  playerwin  ) {
3793 		playerwin->update_data();
3794 	}
3795 
3796 	INT_CHECK("simworld 1289");
3797 
3798 //	DBG_MESSAGE("karte_t::new_month()","halts");
3799 	FOR(vector_tpl<halthandle_t>, const s, haltestelle_t::get_alle_haltestellen()) {
3800 		s->new_month();
3801 		INT_CHECK("simworld 1877");
3802 	}
3803 
3804 	INT_CHECK("simworld 2522");
3805 	depot_t::new_month();
3806 
3807 	scenario->new_month();
3808 
3809 	// now switch year to get the right year for all timeline stuff ...
3810 	if( last_month == 0 ) {
3811 		new_year();
3812 		INT_CHECK("simworld 1299");
3813 	}
3814 
3815 	way_builder_t::new_month();
3816 	INT_CHECK("simworld 1299");
3817 
3818 	recalc_average_speed();
3819 	INT_CHECK("simworld 1921");
3820 
3821 	// update toolbars (i.e. new waytypes
3822 	tool_t::update_toolbars();
3823 
3824 	// no autosave in networkmode or when the new world dialogue is shown
3825 	if( !env_t::networkmode  &&  env_t::autosave>0  &&  last_month%env_t::autosave==0  &&  !win_get_magic(magic_welt_gui_t)  ) {
3826 		char buf[128];
3827 		sprintf( buf, "save/autosave%02i.sve", last_month+1 );
3828 		save( buf, loadsave_t::autosave_mode, env_t::savegame_version_str, true );
3829 	}
3830 }
3831 
3832 
new_year()3833 void karte_t::new_year()
3834 {
3835 	last_year = current_month/12;
3836 
3837 	// advance history ...
3838 	for(  int hist=0;  hist<karte_t::MAX_WORLD_COST;  hist++  ) {
3839 		for( int y=MAX_WORLD_HISTORY_YEARS-1; y>0;  y--  ) {
3840 			finance_history_year[y][hist] = finance_history_year[y-1][hist];
3841 		}
3842 	}
3843 
3844 DBG_MESSAGE("karte_t::new_year()","speedbonus for %d %i, %i, %i, %i, %i, %i, %i, %i", last_year,
3845 			average_speed[0], average_speed[1], average_speed[2], average_speed[3], average_speed[4], average_speed[5], average_speed[6], average_speed[7] );
3846 
3847 	cbuffer_t buf;
3848 	buf.printf( translator::translate("Year %i has started."), last_year );
3849 	msg->add_message(buf,koord::invalid,message_t::general,color_idx_to_rgb(COL_BLACK),skinverwaltung_t::neujahrsymbol->get_image_id(0));
3850 
3851 	FOR(vector_tpl<convoihandle_t>, const cnv, convoi_array) {
3852 		cnv->new_year();
3853 	}
3854 
3855 	for(int i=0; i<MAX_PLAYER_COUNT; i++) {
3856 		if(  players[i] != NULL  ) {
3857 			players[i]->new_year();
3858 		}
3859 	}
3860 
3861 	scenario->new_year();
3862 }
3863 
3864 
3865 // recalculated speed bonus for different vehicles
3866 // and takes care of all timeline stuff
recalc_average_speed()3867 void karte_t::recalc_average_speed()
3868 {
3869 	// retire/allocate vehicles
3870 	private_car_t::build_timeline_list(this);
3871 	pedestrian_t::build_timeline_list(this);
3872 
3873 	for(int i=road_wt; i<=narrowgauge_wt; i++) {
3874 		const int typ = i==4 ? 3 : (i-1)&7;
3875 		average_speed[typ] = vehicle_builder_t::get_speedbonus( this->get_timeline_year_month(), i==4 ? air_wt : (waytype_t)i );
3876 	}
3877 
3878 	//	DBG_MESSAGE("karte_t::recalc_average_speed()","");
3879 	if(use_timeline()) {
3880 		for(int i=road_wt; i<=air_wt; i++) {
3881 			const char *vehicle_type=NULL;
3882 			switch(i) {
3883 				case road_wt:
3884 					vehicle_type = "road vehicle";
3885 					break;
3886 				case track_wt:
3887 					vehicle_type = "rail car";
3888 					break;
3889 				case water_wt:
3890 					vehicle_type = "water vehicle";
3891 					break;
3892 				case monorail_wt:
3893 					vehicle_type = "monorail vehicle";
3894 					break;
3895 				case tram_wt:
3896 					vehicle_type = "street car";
3897 					break;
3898 				case air_wt:
3899 					vehicle_type = "airplane";
3900 					break;
3901 				case maglev_wt:
3902 					vehicle_type = "maglev vehicle";
3903 					break;
3904 				case narrowgauge_wt:
3905 					vehicle_type = "narrowgauge vehicle";
3906 					break;
3907 				default:
3908 					// this is not a valid waytype
3909 					continue;
3910 			}
3911 			vehicle_type = translator::translate( vehicle_type );
3912 
3913 			FOR(slist_tpl<vehicle_desc_t const*>, const info, vehicle_builder_t::get_info((waytype_t)i)) {
3914 				const uint16 intro_month = info->get_intro_year_month();
3915 				if(intro_month == current_month) {
3916 					cbuffer_t buf;
3917 					buf.printf( translator::translate("New %s now available:\n%s\n"), vehicle_type, translator::translate(info->get_name()) );
3918 					msg->add_message(buf,koord::invalid,message_t::new_vehicle,NEW_VEHICLE,info->get_base_image());
3919 				}
3920 
3921 				const uint16 retire_month = info->get_retire_year_month();
3922 				if(retire_month == current_month) {
3923 					cbuffer_t buf;
3924 					buf.printf( translator::translate("Production of %s has been stopped:\n%s\n"), vehicle_type, translator::translate(info->get_name()) );
3925 					msg->add_message(buf,koord::invalid,message_t::new_vehicle,NEW_VEHICLE,info->get_base_image());
3926 				}
3927 			}
3928 		}
3929 
3930 		// city road (try to use always a timeline)
3931 		if (way_desc_t const* city_road_test = settings.get_city_road_type(current_month) ) {
3932 			city_road = city_road_test;
3933 		}
3934 		else {
3935 			DBG_MESSAGE("karte_t::new_month()","Month %d has started", last_month);
3936 			city_road = way_builder_t::weg_search(road_wt,50,get_timeline_year_month(),type_flat);
3937 		}
3938 
3939 	}
3940 	else {
3941 		// defaults
3942 		city_road = settings.get_city_road_type(0);
3943 		if(city_road==NULL) {
3944 			city_road = way_builder_t::weg_search(road_wt,50,0,type_flat);
3945 		}
3946 	}
3947 }
3948 
3949 
3950 // returns the current speed record
get_record_speed(waytype_t w) const3951 sint32 karte_t::get_record_speed( waytype_t w ) const
3952 {
3953 	return records->get_record_speed(w);
3954 }
3955 
3956 
3957 // sets the new speed record
notify_record(convoihandle_t cnv,sint32 max_speed,koord k)3958 void karte_t::notify_record( convoihandle_t cnv, sint32 max_speed, koord k )
3959 {
3960 	records->notify_record(cnv, max_speed, k, current_month);
3961 }
3962 
3963 
set_schedule_counter()3964 void karte_t::set_schedule_counter()
3965 {
3966 	// do not call this from gui when playing in network mode!
3967 	assert( (get_random_mode() & INTERACTIVE_RANDOM) == 0  );
3968 
3969 	schedule_counter++;
3970 }
3971 
3972 
step()3973 void karte_t::step()
3974 {
3975 	DBG_DEBUG4("karte_t::step", "start step");
3976 	uint32 time = dr_time();
3977 
3978 	// calculate delta_t before handling overflow in ticks
3979 	uint32 delta_t = ticks - last_step_ticks;
3980 
3981 	// first: check for new month
3982 	if(ticks > next_month_ticks) {
3983 
3984 		if(  next_month_ticks > next_month_ticks+karte_t::ticks_per_world_month  ) {
3985 			// avoid overflow here ...
3986 			dbg->warning("karte_t::step()", "Ticks were overflowing => reset");
3987 			ticks %= karte_t::ticks_per_world_month;
3988 			next_month_ticks %= karte_t::ticks_per_world_month;
3989 		}
3990 		next_month_ticks += karte_t::ticks_per_world_month;
3991 
3992 		DBG_DEBUG4("karte_t::step", "calling new_month");
3993 		new_month();
3994 	}
3995 
3996 	DBG_DEBUG4("karte_t::step", "time calculations");
3997 	if(  step_mode==NORMAL  ) {
3998 		/* Try to maintain a decent pause, with a step every 170-250 ms (~5,5 simloops/s)
3999 		 * Also avoid too large or negative steps
4000 		 */
4001 
4002 		// needs plausibility check?!?
4003 		if(delta_t>10000) {
4004 			dbg->error( "karte_t::step()", "delta_t (%li) out of bounds!", delta_t );
4005 			last_step_ticks = ticks;
4006 			next_step_time = time+10;
4007 			return;
4008 		}
4009 		idle_time = 0;
4010 		last_step_nr[steps%32] = ticks;
4011 		next_step_time = time+(3200/get_time_multiplier());
4012 	}
4013 	else if(  step_mode==FAST_FORWARD  ) {
4014 		// fast forward first: get average simloops (i.e. calculate acceleration)
4015 		last_step_nr[steps%32] = dr_time();
4016 		int last_5_simloops = simloops;
4017 		if(  last_step_nr[(steps+32-5)%32] < last_step_nr[steps%32]  ) {
4018 			// since 5 steps=1s
4019 			last_5_simloops = (1000) / (last_step_nr[steps%32]-last_step_nr[(steps+32-5)%32]);
4020 		}
4021 		if(  last_step_nr[(steps+1)%32] < last_step_nr[steps%32]  ) {
4022 			simloops = (10000*32) / (last_step_nr[steps%32]-last_step_nr[(steps+1)%32]);
4023 		}
4024 		// now try to approach the target speed
4025 		if(last_5_simloops<env_t::max_acceleration) {
4026 			if(idle_time>0) {
4027 				idle_time --;
4028 			}
4029 		}
4030 		else if(simloops>8u*env_t::max_acceleration) {
4031 			if(idle_time + 10u < get_frame_time()) {
4032 				idle_time ++;
4033 			}
4034 		}
4035 		// cap it ...
4036 		if( idle_time + 10u >= get_frame_time()) {
4037 			idle_time = get_frame_time()-10;
4038 		}
4039 		next_step_time = time+idle_time;
4040 	}
4041 	else {
4042 		// network mode
4043 	}
4044 	// now do the step ...
4045 	last_step_ticks = ticks;
4046 	steps ++;
4047 
4048 	// to make sure the tick counter will be updated
4049 	INT_CHECK("karte_t::step");
4050 
4051 	// check for pending seasons change
4052 	const bool season_change = pending_season_change > 0;
4053 	const bool snowline_change = pending_snowline_change > 0;
4054 	if(  season_change  ||  snowline_change  ) {
4055 		DBG_DEBUG4("karte_t::step", "pending_season_change");
4056 		// process
4057 		const uint32 end_count = min( cached_grid_size.x * cached_grid_size.y,  tile_counter + max( 16384, cached_grid_size.x * cached_grid_size.y / 16 ) );
4058 		while(  tile_counter < end_count  ) {
4059 			plan[tile_counter].check_season_snowline( season_change, snowline_change );
4060 			tile_counter++;
4061 			if(  (tile_counter & 0x3FF) == 0  ) {
4062 				INT_CHECK("karte_t::step");
4063 			}
4064 		}
4065 
4066 		if(  tile_counter >= (uint32)cached_grid_size.x * (uint32)cached_grid_size.y  ) {
4067 			if(  season_change ) {
4068 				pending_season_change--;
4069 			}
4070 			if(  snowline_change  ) {
4071 				pending_snowline_change--;
4072 			}
4073 			tile_counter = 0;
4074 		}
4075 	}
4076 
4077 	// to make sure the tick counter will be updated
4078 	INT_CHECK("karte_t::step");
4079 
4080 	DBG_DEBUG4("karte_t::step", "step convois");
4081 	// since convois will be deleted during stepping, we need to step backwards
4082 	for (size_t i = convoi_array.get_count(); i-- != 0;) {
4083 		convoihandle_t cnv = convoi_array[i];
4084 		cnv->step();
4085 		if((i&7)==0) {
4086 			INT_CHECK("simworld 1947");
4087 		}
4088 	}
4089 
4090 	// now step all towns (to generate passengers)
4091 	DBG_DEBUG4("karte_t::step", "step cities");
4092 	sint64 bev=0;
4093 	FOR(weighted_vector_tpl<stadt_t*>, const i, stadt) {
4094 		i->step(delta_t);
4095 		bev += i->get_finance_history_month(0, HIST_CITICENS);
4096 	}
4097 
4098 	// the inhabitants stuff
4099 	finance_history_month[0][WORLD_CITICENS] = bev;
4100 
4101 	DBG_DEBUG4("karte_t::step", "step factories");
4102 	FOR(slist_tpl<fabrik_t*>, const f, fab_list) {
4103 		f->step(delta_t);
4104 	}
4105 	finance_history_year[0][WORLD_FACTORIES] = finance_history_month[0][WORLD_FACTORIES] = fab_list.get_count();
4106 
4107 	// step powerlines - required order: powernet, pumpe then senke
4108 	DBG_DEBUG4("karte_t::step", "step poweline stuff");
4109 	powernet_t::step_all(delta_t);
4110 	pumpe_t::step_all(delta_t);
4111 	senke_t::step_all(delta_t);
4112 
4113 	DBG_DEBUG4("karte_t::step", "step players");
4114 	// then step all players
4115 	for(  int i=0;  i<MAX_PLAYER_COUNT;  i++  ) {
4116 		if(  players[i] != NULL  ) {
4117 			players[i]->step();
4118 		}
4119 	}
4120 
4121 	DBG_DEBUG4("karte_t::step", "step halts");
4122 	haltestelle_t::step_all();
4123 
4124 	// ok, next step
4125 	INT_CHECK("simworld 1975");
4126 
4127 	recalc_season_snowline(true);
4128 
4129 	// number of playing clients changed
4130 	if(  env_t::server  &&  last_clients!=socket_list_t::get_playing_clients()  ) {
4131 		if(  env_t::server_announce  ) {
4132 			// inform the master server
4133 			announce_server( 1 );
4134 		}
4135 
4136 		// check if player has left and send message
4137 		for(uint32 i=0; i < socket_list_t::get_count(); i++) {
4138 			socket_info_t& info = socket_list_t::get_client(i);
4139 			if (info.state == socket_info_t::has_left) {
4140 				nwc_nick_t::server_tools(this, i, nwc_nick_t::FAREWELL, NULL);
4141 				info.state = socket_info_t::inactive;
4142 			}
4143 		}
4144 		last_clients = socket_list_t::get_playing_clients();
4145 		// add message via tool
4146 		cbuffer_t buf;
4147 		buf.printf("%d,", message_t::general | message_t::local_flag);
4148 		buf.printf(translator::translate("Now %u clients connected.", settings.get_name_language_id()), last_clients);
4149 		tool_t *tmp_tool = create_tool( TOOL_ADD_MESSAGE | SIMPLE_TOOL );
4150 		tmp_tool->set_default_param( buf );
4151 		set_tool( tmp_tool, NULL );
4152 		// since init always returns false, it is safe to delete immediately
4153 		delete tmp_tool;
4154 	}
4155 
4156 	if(  get_scenario()->is_scripted() ) {
4157 		get_scenario()->step();
4158 	}
4159 	DBG_DEBUG4("karte_t::step", "end");
4160 }
4161 
4162 
4163 // recalculates world statistics for older versions
restore_history(bool restore_transported_only)4164 void karte_t::restore_history(bool restore_transported_only)
4165 {
4166 	// update total transported, including passenger and mail
4167 	for(  int m=min(MAX_WORLD_HISTORY_MONTHS,MAX_PLAYER_HISTORY_MONTHS)-1;  m>0;  m--  ) {
4168 		sint64 transported = 0;
4169 		for(  uint i=0;  i<MAX_PLAYER_COUNT;  i++ ) {
4170 			if(  players[i]!=NULL  ) {
4171 				players[i]->get_finance()->calc_finance_history();
4172 				transported += players[i]->get_finance()->get_history_veh_month( TT_ALL, m, ATV_TRANSPORTED );
4173 			}
4174 		}
4175 		finance_history_month[m][WORLD_TRANSPORTED_GOODS] = max(transported, finance_history_month[m][WORLD_TRANSPORTED_GOODS]);
4176 	}
4177 	for(  int y=min(MAX_WORLD_HISTORY_YEARS,MAX_CITY_HISTORY_YEARS)-1;  y>0;  y--  ) {
4178 		sint64 transported_year = 0;
4179 		for(  uint i=0;  i<MAX_PLAYER_COUNT;  i++ ) {
4180 			if(  players[i]  ) {
4181 				transported_year += players[i]->get_finance()->get_history_veh_year( TT_ALL, y, ATV_TRANSPORTED );
4182 			}
4183 		}
4184 		finance_history_year[y][WORLD_TRANSPORTED_GOODS] = max(transported_year, finance_history_year[y][WORLD_TRANSPORTED_GOODS]);
4185 	}
4186 	if (restore_transported_only) {
4187 		return;
4188 	}
4189 
4190 	last_month_bev = -1;
4191 	for(  int m=12-1;  m>0;  m--  ) {
4192 		// now step all towns (to generate passengers)
4193 		sint64 bev=0;
4194 		sint64 total_pas = 1, trans_pas = 0;
4195 		sint64 total_mail = 1, trans_mail = 0;
4196 		sint64 total_goods = 1, supplied_goods = 0;
4197 		FOR(weighted_vector_tpl<stadt_t*>, const i, stadt) {
4198 			bev            += i->get_finance_history_month(m, HIST_CITICENS);
4199 			trans_pas      += i->get_finance_history_month(m, HIST_PAS_TRANSPORTED);
4200 			total_pas      += i->get_finance_history_month(m, HIST_PAS_GENERATED);
4201 			trans_mail     += i->get_finance_history_month(m, HIST_MAIL_TRANSPORTED);
4202 			total_mail     += i->get_finance_history_month(m, HIST_MAIL_GENERATED);
4203 			supplied_goods += i->get_finance_history_month(m, HIST_GOODS_RECEIVED);
4204 			total_goods    += i->get_finance_history_month(m, HIST_GOODS_NEEDED);
4205 		}
4206 
4207 		// the inhabitants stuff
4208 		if(last_month_bev == -1) {
4209 			last_month_bev = bev;
4210 		}
4211 		finance_history_month[m][WORLD_GROWTH] = bev-last_month_bev;
4212 		finance_history_month[m][WORLD_CITICENS] = bev;
4213 		last_month_bev = bev;
4214 
4215 		// transportation ratio and total number
4216 		finance_history_month[m][WORLD_PAS_RATIO] = (10000*trans_pas)/total_pas;
4217 		finance_history_month[m][WORLD_PAS_GENERATED] = total_pas-1;
4218 		finance_history_month[m][WORLD_MAIL_RATIO] = (10000*trans_mail)/total_mail;
4219 		finance_history_month[m][WORLD_MAIL_GENERATED] = total_mail-1;
4220 		finance_history_month[m][WORLD_GOODS_RATIO] = (10000*supplied_goods)/total_goods;
4221 	}
4222 
4223 	sint64 bev_last_year = -1;
4224 	for(  int y=min(MAX_WORLD_HISTORY_YEARS,MAX_CITY_HISTORY_YEARS)-1;  y>0;  y--  ) {
4225 		// now step all towns (to generate passengers)
4226 		sint64 bev=0;
4227 		sint64 total_pas_year = 1, trans_pas_year = 0;
4228 		sint64 total_mail_year = 1, trans_mail_year = 0;
4229 		sint64 total_goods_year = 1, supplied_goods_year = 0;
4230 		FOR(weighted_vector_tpl<stadt_t*>, const i, stadt) {
4231 			bev                 += i->get_finance_history_year(y, HIST_CITICENS);
4232 			trans_pas_year      += i->get_finance_history_year(y, HIST_PAS_TRANSPORTED);
4233 			total_pas_year      += i->get_finance_history_year(y, HIST_PAS_GENERATED);
4234 			trans_mail_year     += i->get_finance_history_year(y, HIST_MAIL_TRANSPORTED);
4235 			total_mail_year     += i->get_finance_history_year(y, HIST_MAIL_GENERATED);
4236 			supplied_goods_year += i->get_finance_history_year(y, HIST_GOODS_RECEIVED);
4237 			total_goods_year    += i->get_finance_history_year(y, HIST_GOODS_NEEDED);
4238 		}
4239 
4240 		// the inhabitants stuff
4241 		if(bev_last_year == -1) {
4242 			bev_last_year = bev;
4243 		}
4244 		finance_history_year[y][WORLD_GROWTH] = bev-bev_last_year;
4245 		finance_history_year[y][WORLD_CITICENS] = bev;
4246 		bev_last_year = bev;
4247 
4248 		// transportation ratio and total number
4249 		finance_history_year[y][WORLD_PAS_RATIO] = (10000*trans_pas_year)/total_pas_year;
4250 		finance_history_year[y][WORLD_PAS_GENERATED] = total_pas_year-1;
4251 		finance_history_year[y][WORLD_MAIL_RATIO] = (10000*trans_mail_year)/total_mail_year;
4252 		finance_history_year[y][WORLD_MAIL_GENERATED] = total_mail_year-1;
4253 		finance_history_year[y][WORLD_GOODS_RATIO] = (10000*supplied_goods_year)/total_goods_year;
4254 	}
4255 
4256 	// fix current month/year
4257 	update_history();
4258 }
4259 
4260 
update_history()4261 void karte_t::update_history()
4262 {
4263 	finance_history_year[0][WORLD_CONVOIS] = finance_history_month[0][WORLD_CONVOIS] = convoi_array.get_count();
4264 	finance_history_year[0][WORLD_FACTORIES] = finance_history_month[0][WORLD_FACTORIES] = fab_list.get_count();
4265 
4266 	// now step all towns (to generate passengers)
4267 	sint64 bev=0;
4268 	sint64 total_pas = 1, trans_pas = 0;
4269 	sint64 total_mail = 1, trans_mail = 0;
4270 	sint64 total_goods = 1, supplied_goods = 0;
4271 	sint64 total_pas_year = 1, trans_pas_year = 0;
4272 	sint64 total_mail_year = 1, trans_mail_year = 0;
4273 	sint64 total_goods_year = 1, supplied_goods_year = 0;
4274 	FOR(weighted_vector_tpl<stadt_t*>, const i, stadt) {
4275 		bev                 += i->get_finance_history_month(0, HIST_CITICENS);
4276 		trans_pas           += i->get_finance_history_month(0, HIST_PAS_TRANSPORTED);
4277 		total_pas           += i->get_finance_history_month(0, HIST_PAS_GENERATED);
4278 		trans_mail          += i->get_finance_history_month(0, HIST_MAIL_TRANSPORTED);
4279 		total_mail          += i->get_finance_history_month(0, HIST_MAIL_GENERATED);
4280 		supplied_goods      += i->get_finance_history_month(0, HIST_GOODS_RECEIVED);
4281 		total_goods         += i->get_finance_history_month(0, HIST_GOODS_NEEDED);
4282 		trans_pas_year      += i->get_finance_history_year( 0, HIST_PAS_TRANSPORTED);
4283 		total_pas_year      += i->get_finance_history_year( 0, HIST_PAS_GENERATED);
4284 		trans_mail_year     += i->get_finance_history_year( 0, HIST_MAIL_TRANSPORTED);
4285 		total_mail_year     += i->get_finance_history_year( 0, HIST_MAIL_GENERATED);
4286 		supplied_goods_year += i->get_finance_history_year( 0, HIST_GOODS_RECEIVED);
4287 		total_goods_year    += i->get_finance_history_year( 0, HIST_GOODS_NEEDED);
4288 	}
4289 
4290 	finance_history_month[0][WORLD_GROWTH] = bev-last_month_bev;
4291 	finance_history_year[0][WORLD_GROWTH] = bev - (finance_history_year[1][WORLD_CITICENS]==0 ? finance_history_month[0][WORLD_CITICENS] : finance_history_year[1][WORLD_CITICENS]);
4292 
4293 	// the inhabitants stuff
4294 	finance_history_year[0][WORLD_TOWNS] = finance_history_month[0][WORLD_TOWNS] = stadt.get_count();
4295 	finance_history_year[0][WORLD_CITICENS] = finance_history_month[0][WORLD_CITICENS] = bev;
4296 	finance_history_month[0][WORLD_GROWTH] = bev-last_month_bev;
4297 	finance_history_year[0][WORLD_GROWTH] = bev - (finance_history_year[1][WORLD_CITICENS]==0 ? finance_history_month[0][WORLD_CITICENS] : finance_history_year[1][WORLD_CITICENS]);
4298 
4299 	// transportation ratio and total number
4300 	finance_history_month[0][WORLD_PAS_RATIO] = (10000*trans_pas)/total_pas;
4301 	finance_history_month[0][WORLD_PAS_GENERATED] = total_pas-1;
4302 	finance_history_month[0][WORLD_MAIL_RATIO] = (10000*trans_mail)/total_mail;
4303 	finance_history_month[0][WORLD_MAIL_GENERATED] = total_mail-1;
4304 	finance_history_month[0][WORLD_GOODS_RATIO] = (10000*supplied_goods)/total_goods;
4305 
4306 	finance_history_year[0][WORLD_PAS_RATIO] = (10000*trans_pas_year)/total_pas_year;
4307 	finance_history_year[0][WORLD_PAS_GENERATED] = total_pas_year-1;
4308 	finance_history_year[0][WORLD_MAIL_RATIO] = (10000*trans_mail_year)/total_mail_year;
4309 	finance_history_year[0][WORLD_MAIL_GENERATED] = total_mail_year-1;
4310 	finance_history_year[0][WORLD_GOODS_RATIO] = (10000*supplied_goods_year)/total_goods_year;
4311 
4312 	// update total transported, including passenger and mail
4313 	sint64 transported = 0;
4314 	sint64 transported_year = 0;
4315 	for(  uint i=0;  i<MAX_PLAYER_COUNT;  i++ ) {
4316 		if(  players[i]!=NULL  ) {
4317 			players[i]->get_finance()->calc_finance_history();
4318 			transported += players[i]->get_finance()->get_history_veh_month( TT_ALL, 0, ATV_TRANSPORTED_GOOD );
4319 			transported_year += players[i]->get_finance()->get_history_veh_year( TT_ALL, 0, ATV_TRANSPORTED_GOOD );
4320 		}
4321 	}
4322 	finance_history_month[0][WORLD_TRANSPORTED_GOODS] = transported;
4323 	finance_history_year[0][WORLD_TRANSPORTED_GOODS] = transported_year;
4324 }
4325 
4326 
median(sint8 a,sint8 b,sint8 c)4327 static sint8 median( sint8 a, sint8 b, sint8 c )
4328 {
4329 #if 0
4330 	if(  a==b  ||  a==c  ) {
4331 		return a;
4332 	}
4333 	else if(  b==c  ) {
4334 		return b;
4335 	}
4336 	else {
4337 		// noting matches
4338 //		return (3*128+1 + a+b+c)/3-128;
4339 		return -128;
4340 	}
4341 #elif 0
4342 	if(  a<=b  ) {
4343 		return b<=c ? b : max(a,c);
4344 	}
4345 	else {
4346 		return b>c ? b : min(a,c);
4347 	}
4348 #else
4349 		return (6*128+3 + a+a+b+b+c+c)/6-128;
4350 #endif
4351 }
4352 
4353 
recalc_natural_slope(const koord k,sint8 & new_height) const4354 uint8 karte_t::recalc_natural_slope( const koord k, sint8 &new_height ) const
4355 {
4356 	grund_t *gr = lookup_kartenboden(k);
4357 	if(!gr) {
4358 		return slope_t::flat;
4359 	}
4360 	else {
4361 		const sint8 max_hdiff = ground_desc_t::double_grounds ? 2 : 1;
4362 
4363 		sint8 corner_height[4];
4364 
4365 		// get neighbour corner heights
4366 		sint8 neighbour_height[8][4];
4367 		get_neighbour_heights( k, neighbour_height );
4368 
4369 		//check whether neighbours are foundations
4370 		bool neighbour_fundament[8];
4371 		for(  int i = 0;  i < 8;  i++  ) {
4372 			grund_t *gr2 = lookup_kartenboden( k + koord::neighbours[i] );
4373 			neighbour_fundament[i] = (gr2  &&  gr2->get_typ() == grund_t::fundament);
4374 		}
4375 
4376 		for(  uint8 i = 0;  i < 4;  i++  ) { // 0 = sw, 1 = se etc.
4377 			// corner_sw (i=0): tests vs neighbour 1:w (corner 2 j=1),2:sw (corner 3) and 3:s (corner 4)
4378 			// corner_se (i=1): tests vs neighbour 3:s (corner 3 j=2),4:se (corner 4) and 5:e (corner 1)
4379 			// corner_ne (i=2): tests vs neighbour 5:e (corner 4 j=3),6:ne (corner 1) and 7:n (corner 2)
4380 			// corner_nw (i=3): tests vs neighbour 7:n (corner 1 j=0),0:nw (corner 2) and 1:w (corner 3)
4381 
4382 			sint16 median_height = 0;
4383 			uint8 natural_corners = 0;
4384 			for(  int j = 1;  j < 4;  j++  ) {
4385 				if(  !neighbour_fundament[(i * 2 + j) & 7]  ) {
4386 					natural_corners++;
4387 					median_height += neighbour_height[(i * 2 + j) & 7][(i + j) & 3];
4388 				}
4389 			}
4390 			switch(  natural_corners  ) {
4391 				case 1: {
4392 					corner_height[i] = (sint8)median_height;
4393 					break;
4394 				}
4395 				case 2: {
4396 					corner_height[i] = median_height >> 1;
4397 					break;
4398 				}
4399 				default: {
4400 					// take the average of all 3 corners (if no natural corners just use the artificial ones anyway)
4401 					corner_height[i] = median( neighbour_height[(i * 2 + 1) & 7][(i + 1) & 3], neighbour_height[(i * 2 + 2) & 7][(i + 2) & 3], neighbour_height[(i * 2 + 3) & 7][(i + 3) & 3] );
4402 					break;
4403 				}
4404 			}
4405 		}
4406 
4407 		// new height of that tile ...
4408 		sint8 min_height = min( min( corner_height[0], corner_height[1] ), min( corner_height[2], corner_height[3] ) );
4409 		sint8 max_height = max( max( corner_height[0], corner_height[1] ), max( corner_height[2], corner_height[3] ) );
4410 		/* check for an artificial slope on a steep sidewall */
4411 		bool not_ok = abs( max_height - min_height ) > max_hdiff  ||  min_height == -128;
4412 
4413 		sint8 old_height = gr->get_hoehe();
4414 		new_height = min_height;
4415 
4416 		// now we must make clear, that there is no ground above/below the slope
4417 		if(  old_height!=new_height  ) {
4418 			not_ok |= lookup(koord3d(k,new_height))!=NULL;
4419 			if(  old_height > new_height  ) {
4420 				not_ok |= lookup(koord3d(k,old_height-1))!=NULL;
4421 			}
4422 			if(  old_height < new_height  ) {
4423 				not_ok |= lookup(koord3d(k,old_height+1))!=NULL;
4424 			}
4425 		}
4426 
4427 		if(  not_ok  ) {
4428 			/* difference too high or ground above/below
4429 			 * we just keep it as it was ...
4430 			 */
4431 			new_height = old_height;
4432 			return gr->get_grund_hang();
4433 		}
4434 
4435 		const sint16 d1 = min( corner_height[0] - new_height, max_hdiff );
4436 		const sint16 d2 = min( corner_height[1] - new_height, max_hdiff );
4437 		const sint16 d3 = min( corner_height[2] - new_height, max_hdiff );
4438 		const sint16 d4 = min( corner_height[3] - new_height, max_hdiff );
4439 		return d4 * 27 + d3 * 9 + d2 * 3 + d1;
4440 	}
4441 	return 0;
4442 }
4443 
4444 
calc_natural_slope(const koord k) const4445 uint8 karte_t::calc_natural_slope( const koord k ) const
4446 {
4447 	if(is_within_grid_limits(k.x, k.y)) {
4448 
4449 		const sint8 * p = &grid_hgts[k.x + k.y*(sint32)(get_size().x+1)];
4450 
4451 		const int h1 = *p;
4452 		const int h2 = *(p+1);
4453 		const int h3 = *(p+get_size().x+2);
4454 		const int h4 = *(p+get_size().x+1);
4455 
4456 		const int mini = min(min(h1,h2), min(h3,h4));
4457 
4458 		const int d1=h1-mini;
4459 		const int d2=h2-mini;
4460 		const int d3=h3-mini;
4461 		const int d4=h4-mini;
4462 
4463 		return d1 * 27 + d2 * 9 + d3 * 3 + d4;
4464 	}
4465 	return 0;
4466 }
4467 
4468 
is_water(koord k,koord dim) const4469 bool karte_t::is_water(koord k, koord dim) const
4470 {
4471 	koord k_check;
4472 	for(  k_check.x = k.x;  k_check.x < k.x + dim.x;  k_check.x++  ) {
4473 		for(  k_check.y = k.y;  k_check.y < k.y + dim.y;  k_check.y++  ) {
4474 			if(  !is_within_grid_limits( k_check + koord(1, 1) )  ||  max_hgt(k_check) > get_water_hgt(k_check)  ) {
4475 				return false;
4476 			}
4477 		}
4478 	}
4479 	return true;
4480 }
4481 
4482 
square_is_free(koord k,sint16 w,sint16 h,int * last_y,climate_bits cl) const4483 bool karte_t::square_is_free(koord k, sint16 w, sint16 h, int *last_y, climate_bits cl) const
4484 {
4485 	if(k.x < 0  ||  k.y < 0  ||  k.x+w > get_size().x || k.y+h > get_size().y) {
4486 		return false;
4487 	}
4488 
4489 	grund_t *gr = lookup_kartenboden(k);
4490 	const sint16 platz_h = gr->get_grund_hang() ? max_hgt(k) : gr->get_hoehe();	// remember the max height of the first tile
4491 
4492 	koord k_check;
4493 	for(k_check.y=k.y+h-1; k_check.y>=k.y; k_check.y--) {
4494 		for(k_check.x=k.x; k_check.x<k.x+w; k_check.x++) {
4495 			const grund_t *gr = lookup_kartenboden(k_check);
4496 
4497 			// we can built, if: max height all the same, everything removable and no buildings there
4498 			slope_t::type slope = gr->get_grund_hang();
4499 			sint8 max_height = gr->get_hoehe() + slope_t::max_diff(slope);
4500 			climate test_climate = get_climate(k_check);
4501 			if(  cl & (1 << water_climate)  &&  test_climate != water_climate  ) {
4502 				bool neighbour_water = false;
4503 				for(int i=0; i<8  &&  !neighbour_water; i++) {
4504 					if(  is_within_limits(k_check + koord::neighbours[i])  &&  get_climate( k_check + koord::neighbours[i] ) == water_climate  ) {
4505 						neighbour_water = true;
4506 					}
4507 				}
4508 				if(  neighbour_water  ) {
4509 					test_climate = water_climate;
4510 				}
4511 			}
4512 			if(  platz_h != max_height  ||  !gr->ist_natur()  ||  gr->kann_alle_obj_entfernen(NULL) != NULL  ||
4513 			     (cl & (1 << test_climate)) == 0  ||  ( slope && (lookup( gr->get_pos()+koord3d(0,0,1) ) ||
4514 			     (slope_t::max_diff(slope)==2 && lookup( gr->get_pos()+koord3d(0,0,2) )) ))  ) {
4515 				if(  last_y  ) {
4516 					*last_y = k_check.y;
4517 				}
4518 				return false;
4519 			}
4520 		}
4521 	}
4522 	return true;
4523 }
4524 
4525 
find_squares(sint16 w,sint16 h,climate_bits cl,sint16 old_x,sint16 old_y) const4526 slist_tpl<koord> *karte_t::find_squares(sint16 w, sint16 h, climate_bits cl, sint16 old_x, sint16 old_y) const
4527 {
4528 	slist_tpl<koord> * list = new slist_tpl<koord>();
4529 	koord start;
4530 	int last_y;
4531 
4532 DBG_DEBUG("karte_t::finde_plaetze()","for size (%i,%i) in map (%i,%i)",w,h,get_size().x,get_size().y );
4533 	for(start.x=0; start.x<get_size().x-w; start.x++) {
4534 		for(start.y=start.x<old_x?old_y:0; start.y<get_size().y-h; start.y++) {
4535 			if(square_is_free(start, w, h, &last_y, cl)) {
4536 				list->insert(start);
4537 			}
4538 			else {
4539 				// Optimiert fuer groessere Felder, hehe!
4540 				// Die Idee: wenn bei 2x2 die untere Reihe nicht geht, koennen
4541 				// wir gleich 2 tiefer weitermachen! V. Meyer
4542 				start.y = last_y;
4543 			}
4544 		}
4545 	}
4546 	return list;
4547 }
4548 
4549 
4550 /**
4551  * Play a sound, but only if near enough.
4552  * Sounds are muted by distance and clipped completely if too far away.
4553  *
4554  * @author Hj. Malthaner
4555  */
play_sound_area_clipped(koord const k,uint16 const idx) const4556 bool karte_t::play_sound_area_clipped(koord const k, uint16 const idx) const
4557 {
4558 	if(is_sound  &&  zeiger) {
4559 		const int dist = koord_distance( k, zeiger->get_pos() );
4560 
4561 		if(dist < 100) {
4562 			int xw = (2*display_get_width())/get_tile_raster_width();
4563 			int yw = (4*display_get_height())/get_tile_raster_width();
4564 
4565 			uint8 const volume = (uint8)(255U * (xw + yw) / (xw + yw + 64 * dist));
4566 			if (volume > 8) {
4567 				sound_play(idx, volume);
4568 			}
4569 		}
4570 		return dist < 25;
4571 	}
4572 	return false;
4573 }
4574 
4575 
save(const char * filename,loadsave_t::mode_t savemode,const char * version_str,bool silent)4576 void karte_t::save(const char *filename, loadsave_t::mode_t savemode, const char *version_str, bool silent )
4577 {
4578 DBG_MESSAGE("karte_t::save()", "saving game to '%s'", filename);
4579 	loadsave_t  file;
4580 	std::string savename = filename;
4581 	savename[savename.length()-1] = '_';
4582 
4583 	display_show_load_pointer( true );
4584 	if(!file.wr_open( savename.c_str(), savemode, env_t::objfilename.c_str(), version_str )) {
4585 		create_win(new news_img("Kann Spielstand\nnicht speichern.\n"), w_info, magic_none);
4586 		dbg->error("karte_t::save()","cannot open file for writing! check permissions!");
4587 	}
4588 	else {
4589 		save(&file,silent);
4590 		const char *success = file.close();
4591 		if(success) {
4592 			static char err_str[512];
4593 			sprintf( err_str, translator::translate("Error during saving:\n%s"), success );
4594 			create_win( new news_img(err_str), w_time_delete, magic_none);
4595 		}
4596 		else {
4597 			dr_rename( savename.c_str(), filename );
4598 			if(!silent) {
4599 				create_win( new news_img("Spielstand wurde\ngespeichert!\n"), w_time_delete, magic_none);
4600 				// update the filename, if no autosave
4601 				settings.set_filename(filename);
4602 			}
4603 		}
4604 		reset_interaction();
4605 	}
4606 	display_show_load_pointer( false );
4607 }
4608 
4609 
save(loadsave_t * file,bool silent)4610 void karte_t::save(loadsave_t *file,bool silent)
4611 {
4612 	bool needs_redraw = false;
4613 
4614 	loadingscreen_t *ls = NULL;
4615 DBG_MESSAGE("karte_t::save(loadsave_t *file)", "start");
4616 	if(!silent) {
4617 		ls = new loadingscreen_t( translator::translate("Saving map ..."), get_size().y );
4618 	}
4619 
4620 	// rotate the map until it can be saved completely
4621 	for( int i=0;  i<4  &&  nosave_warning;  i++  ) {
4622 		rotate90();
4623 		needs_redraw = true;
4624 	}
4625 	// seems not successful
4626 	if(nosave_warning) {
4627 		// but then we try to rotate until only warnings => some buildings may be broken, but factories should be fine
4628 		for( int i=0;  i<4  &&  nosave;  i++  ) {
4629 			rotate90();
4630 			needs_redraw = true;
4631 		}
4632 		if(  nosave  ) {
4633 			dbg->error( "karte_t::save()","Map cannot be saved in any rotation!" );
4634 			create_win( new news_img("Map may be not saveable in any rotation!"), w_info, magic_none);
4635 			// still broken, but we try anyway to save it ...
4636 		}
4637 	}
4638 	// only broken buildings => just warn
4639 	if(nosave_warning) {
4640 		dbg->error( "karte_t::save()","Some buildings may be broken by saving!" );
4641 	}
4642 
4643 	/* If the current tool is a two_click_tool_t, call cleanup() in order to delete dummy grounds (tunnel + monorail preview)
4644 	 * THIS MUST NOT BE DONE IN NETWORK MODE!
4645 	 */
4646 	for(  uint8 sp_nr=0;  sp_nr<MAX_PLAYER_COUNT;  sp_nr++  ) {
4647 		if (two_click_tool_t* tool = dynamic_cast<two_click_tool_t*>(selected_tool[sp_nr])) {
4648 			tool->cleanup();
4649 		}
4650 	}
4651 
4652 	file->set_buffered(true);
4653 
4654 	// do not set value for empty player
4655 	uint8 old_players[MAX_PLAYER_COUNT];
4656 	for(  int i=0;  i<MAX_PLAYER_COUNT;  i++  ) {
4657 		old_players[i] = settings.get_player_type(i);
4658 		if(  players[i]==NULL  ) {
4659 			settings.set_player_type(i, player_t::EMPTY);
4660 		}
4661 	}
4662 	settings.rdwr(file);
4663 	for(  int i=0;  i<MAX_PLAYER_COUNT;  i++  ) {
4664 		settings.set_player_type(i, old_players[i]);
4665 	}
4666 
4667 	file->rdwr_long(ticks);
4668 	file->rdwr_long(last_month);
4669 	file->rdwr_long(last_year);
4670 
4671 	// rdwr satic states
4672 	senke_t::static_rdwr(file);
4673 
4674 	// rdwr cityrules for networkgames
4675 	if(file->is_version_atleast(102, 3)) {
4676 		bool do_rdwr = env_t::networkmode;
4677 		file->rdwr_bool(do_rdwr);
4678 		if (do_rdwr) {
4679 			stadt_t::cityrules_rdwr(file);
4680 			if(file->is_version_atleast(102, 4)) {
4681 				vehicle_builder_t::rdwr_speedbonus(file);
4682 			}
4683 		}
4684 	}
4685 
4686 	FOR(weighted_vector_tpl<stadt_t*>, const i, stadt) {
4687 		i->rdwr(file);
4688 		if(silent) {
4689 			INT_CHECK("saving");
4690 		}
4691 	}
4692 DBG_MESSAGE("karte_t::save(loadsave_t *file)", "saved cities ok");
4693 
4694 	for(int j=0; j<get_size().y; j++) {
4695 		for(int i=0; i<get_size().x; i++) {
4696 			plan[i+j*cached_grid_size.x].rdwr(file, koord(i,j) );
4697 		}
4698 		if(silent) {
4699 			INT_CHECK("saving");
4700 		}
4701 		else {
4702 			ls->set_progress(j);
4703 		}
4704 	}
4705 DBG_MESSAGE("karte_t::save(loadsave_t *file)", "saved tiles");
4706 
4707 	if(  file->is_version_less(102, 2)  ) {
4708 		// not needed any more
4709 		for(int j=0; j<(get_size().y+1)*(sint32)(get_size().x+1); j++) {
4710 			file->rdwr_byte(grid_hgts[j]);
4711 		}
4712 	DBG_MESSAGE("karte_t::save(loadsave_t *file)", "saved hgt");
4713 	}
4714 
4715 	sint32 fabs = fab_list.get_count();
4716 	file->rdwr_long(fabs);
4717 	FOR(slist_tpl<fabrik_t*>, const f, fab_list) {
4718 		f->rdwr(file);
4719 		if(silent) {
4720 			INT_CHECK("saving");
4721 		}
4722 	}
4723 DBG_MESSAGE("karte_t::save(loadsave_t *file)", "saved fabs");
4724 
4725 	sint32 haltcount=haltestelle_t::get_alle_haltestellen().get_count();
4726 	file->rdwr_long(haltcount);
4727 	FOR(vector_tpl<halthandle_t>, const s, haltestelle_t::get_alle_haltestellen()) {
4728 		s->rdwr(file);
4729 	}
4730 DBG_MESSAGE("karte_t::save(loadsave_t *file)", "saved stops");
4731 
4732 	// save number of convois
4733 	if(  file->is_version_atleast(101, 0)  ) {
4734 		uint16 i=convoi_array.get_count();
4735 		file->rdwr_short(i);
4736 	}
4737 	FOR(vector_tpl<convoihandle_t>, const cnv, convoi_array) {
4738 		// one MUST NOT call INT_CHECK here or else the convoi will be broken during reloading!
4739 		cnv->rdwr(file);
4740 	}
4741 	if(  file->is_version_less(101, 0)  ) {
4742 		file->wr_obj_id("Ende Convois");
4743 	}
4744 	if(silent) {
4745 		INT_CHECK("saving");
4746 	}
4747 DBG_MESSAGE("karte_t::save(loadsave_t *file)", "saved %i convois",convoi_array.get_count());
4748 
4749 	for(int i=0; i<MAX_PLAYER_COUNT; i++) {
4750 // **** REMOVE IF SOON! *********
4751 		if(file->is_version_less(101, 0)) {
4752 			if(  i<8  ) {
4753 				if(  players[i]  ) {
4754 					players[i]->rdwr(file);
4755 				}
4756 				else {
4757 					// simulate old ones ...
4758 					player_t *player = new player_t( i );
4759 					player->rdwr(file);
4760 					delete player;
4761 				}
4762 			}
4763 		}
4764 		else {
4765 			if(  players[i]  ) {
4766 				players[i]->rdwr(file);
4767 			}
4768 		}
4769 	}
4770 DBG_MESSAGE("karte_t::save(loadsave_t *file)", "saved players");
4771 
4772 	// saving messages
4773 	if(  file->is_version_atleast(102, 5)  ) {
4774 		msg->rdwr(file);
4775 	}
4776 DBG_MESSAGE("karte_t::save(loadsave_t *file)", "saved messages");
4777 
4778 	// centered on what?
4779 	sint32 dummy = viewport->get_world_position().x;
4780 	file->rdwr_long(dummy);
4781 	dummy = viewport->get_world_position().y;
4782 	file->rdwr_long(dummy);
4783 
4784 	if(file->is_version_atleast(99, 18)) {
4785 		// most recent version is 99018
4786 		for (int year = 0;  year</*MAX_WORLD_HISTORY_YEARS*/12;  year++) {
4787 			for (int cost_type = 0; cost_type</*MAX_WORLD_COST*/12; cost_type++) {
4788 				file->rdwr_longlong(finance_history_year[year][cost_type]);
4789 			}
4790 		}
4791 		for (int month = 0;month</*MAX_WORLD_HISTORY_MONTHS*/12;month++) {
4792 			for (int cost_type = 0; cost_type</*MAX_WORLD_COST*/12; cost_type++) {
4793 				file->rdwr_longlong(finance_history_month[month][cost_type]);
4794 			}
4795 		}
4796 	}
4797 
4798 	// finally a possible scenario
4799 	scenario->rdwr( file );
4800 
4801 	if(  file->is_version_atleast(112, 8)  ) {
4802 		xml_tag_t t( file, "motd_t" );
4803 
4804 		dr_chdir( env_t::user_dir );
4805 		// maybe show message about server
4806 DBG_MESSAGE("karte_t::save(loadsave_t *file)", "motd filename %s", env_t::server_motd_filename.c_str() );
4807 		if(  FILE *fmotd = dr_fopen( env_t::server_motd_filename.c_str(), "r" )  ) {
4808 			struct stat st;
4809 			stat( env_t::server_motd_filename.c_str(), &st );
4810 			sint32 len = min( 32760, st.st_size+1 );
4811 			char *motd = (char *)malloc( len );
4812 			fread( motd, len-1, 1, fmotd );
4813 			fclose( fmotd );
4814 			motd[len-1] = 0;
4815 			file->rdwr_str( motd, len );
4816 			free( motd );
4817 		}
4818 		else {
4819 			// no message
4820 			plainstring motd("");
4821 			file->rdwr_str( motd );
4822 		}
4823 	}
4824 
4825 	// save all open windows (upon request)
4826 	file->rdwr_byte( active_player_nr );
4827 	rdwr_all_win(file);
4828 
4829 	file->set_buffered(false);
4830 
4831 	if(needs_redraw) {
4832 		update_map();
4833 	}
4834 	if(!silent) {
4835 		delete ls;
4836 	}
4837 }
4838 
4839 
4840 // store missing obj during load and their severity
add_missing_paks(const char * name,missing_level_t level)4841 void karte_t::add_missing_paks( const char *name, missing_level_t level )
4842 {
4843 	if(  missing_pak_names.get( name )==NOT_MISSING  ) {
4844 		missing_pak_names.put( strdup(name), level );
4845 	}
4846 }
4847 
4848 
4849 
switch_server(bool start_server,bool port_forwarding)4850 void karte_t::switch_server( bool start_server, bool port_forwarding )
4851 {
4852 	if(  !start_server  ) {
4853 		// end current server session
4854 
4855 		if(  env_t::server  ) {
4856 			// take down server
4857 			announce_server(2);
4858 			remove_port_forwarding( env_t::server );
4859 		}
4860 		network_core_shutdown();
4861 		env_t::easy_server = 0;
4862 
4863 		clear_random_mode( INTERACTIVE_RANDOM );
4864 		step_mode = NORMAL;
4865 		reset_timer();
4866 		clear_command_queue();
4867 		last_active_player_nr = active_player_nr;
4868 
4869 		if(  port_forwarding  &&  env_t::fps<=15  ) {
4870 			env_t::fps = 25;
4871 		}
4872 	}
4873 	else {
4874 
4875 		// convert current game into server game
4876 		if(  env_t::server  ) {
4877 			// kick all clients out
4878 			network_reset_server();
4879 		}
4880 		else {
4881 			// now start a server with defaults
4882 			env_t::networkmode = network_init_server( env_t::server_port );
4883 			if(  env_t::networkmode  ) {
4884 
4885 				// query IP and try to open ports on router
4886 				char IP[256], altIP[256];
4887 				if(  port_forwarding  &&  prepare_for_server( IP, altIP, env_t::server_port )  ) {
4888 					// we have forwarded a port in router, so we can continue
4889 					env_t::server_dns = IP;
4890 					if(  env_t::server_name.empty()  ) {
4891 						env_t::server_name = std::string("Server at ")+IP;
4892 					}
4893 					env_t::server_alt_dns = altIP;
4894 					env_t::server_announce = 1;
4895 					env_t::easy_server = 1;
4896 					if(  env_t::fps>15  ) {
4897 						env_t::fps = 15;
4898 					}
4899 				}
4900 
4901 				reset_timer();
4902 				clear_command_queue();
4903 
4904 				// meaningless to use a locked map; there are passwords now
4905 				settings.set_allow_player_change(true);
4906 				// language of map becomes server language
4907 				settings.set_name_language_iso(translator::get_lang()->iso_base);
4908 
4909 				nwc_auth_player_t::init_player_lock_server(this);
4910 
4911 				last_active_player_nr = active_player_nr;
4912 			}
4913 		}
4914 	}
4915 }
4916 
4917 
4918 
4919 // just the preliminaries, opens the file, checks the versions ...
load(const char * filename)4920 bool karte_t::load(const char *filename)
4921 {
4922 	cbuffer_t name;
4923 	bool ok = false;
4924 	bool restore_player_nr = false;
4925 	bool server_reload_pwd_hashes = false;
4926 	mute_sound(true);
4927 	display_show_load_pointer(true);
4928 	loadsave_t file;
4929 
4930 	// clear hash table with missing paks (may cause some small memory loss though)
4931 	missing_pak_names.clear();
4932 
4933 	DBG_MESSAGE("karte_t::load", "loading game from '%s'", filename);
4934 
4935 	// reloading same game? Remember pos
4936 	const koord oldpos = settings.get_filename()[0]>0  &&  strncmp(filename,settings.get_filename(),strlen(settings.get_filename()))==0 ? viewport->get_world_position() : koord::invalid;
4937 
4938 	if(  strstart(filename, "net:")  ) {
4939 
4940 		// probably finish network mode?
4941 		if(  env_t::networkmode  ) {
4942 			network_core_shutdown();
4943 		}
4944 		dr_chdir( env_t::user_dir );
4945 		const char *err = network_connect(filename+4, this);
4946 		if(err) {
4947 			create_win( new news_img(err), w_info, magic_none );
4948 			display_show_load_pointer(false);
4949 			step_mode = NORMAL;
4950 			return false;
4951 		}
4952 		else {
4953 			env_t::networkmode = true;
4954 			name.printf( "client%i-network.sve", network_get_client_id() );
4955 			restore_player_nr = strcmp( last_network_game.c_str(), filename )==0;
4956 			if(  !restore_player_nr  ) {
4957 				last_network_game = filename;
4958 			}
4959 		}
4960 	}
4961 	else {
4962 		// probably finish network mode first?
4963 		if(  env_t::networkmode  ) {
4964 			if(  env_t::server  ) {
4965 				char fn[256];
4966 				sprintf( fn, "server%d-network.sve", env_t::server );
4967 				if(  strcmp(filename, fn) != 0  ) {
4968 					// stay in networkmode, but disconnect clients
4969 					dbg->warning("karte_t::load","disconnecting all clients");
4970 				}
4971 				else {
4972 					// read password hashes from separate file
4973 					// as they are not in the savegame to avoid sending them over network
4974 					server_reload_pwd_hashes = true;
4975 				}
4976 			}
4977 			else {
4978 				// check, if reload during sync
4979 				char fn[256];
4980 				sprintf( fn, "client%i-network.sve", network_get_client_id() );
4981 				if(  strcmp(filename,fn)!=0  ) {
4982 					// no sync => finish network mode
4983 					dbg->warning("karte_t::load","finished network mode");
4984 					network_disconnect();
4985 					finish_loop = false; // do not trigger intro screen
4986 					// closing the socket will tell the server, I am away too
4987 				}
4988 			}
4989 		}
4990 		name.append(filename);
4991 	}
4992 
4993 	if(!file.rd_open(name)) {
4994 
4995 		if(  file.get_version_int()==0  ||  file.get_version_int()>loadsave_t::int_version(SAVEGAME_VER_NR, NULL )  ) {
4996 			dbg->warning("karte_t::load()", translator::translate("WRONGSAVE") );
4997 			create_win( new news_img("WRONGSAVE"), w_info, magic_none );
4998 		}
4999 		else {
5000 			dbg->warning("karte_t::load()", translator::translate("Kann Spielstand\nnicht laden.\n") );
5001 			create_win(new news_img("Kann Spielstand\nnicht laden.\n"), w_info, magic_none);
5002 		}
5003 	}
5004 	else if(file.is_version_less(84, 6)) {
5005 		// too old
5006 		dbg->warning("karte_t::load()", translator::translate("WRONGSAVE") );
5007 		create_win(new news_img("WRONGSAVE"), w_info, magic_none);
5008 	}
5009 	else {
5010 DBG_MESSAGE("karte_t::load()","Savegame version is %u", file.get_version_int());
5011 
5012 		load(&file);
5013 
5014 		if(  env_t::networkmode  ) {
5015 			clear_command_queue();
5016 		}
5017 
5018 		if(  env_t::server  ) {
5019 			step_mode = FIX_RATIO;
5020 			if(  env_t::server  ) {
5021 				// meaningless to use a locked map; there are passwords now
5022 				settings.set_allow_player_change(true);
5023 				// language of map becomes server language
5024 				settings.set_name_language_iso(translator::get_lang()->iso_base);
5025 			}
5026 
5027 			if(  server_reload_pwd_hashes  ) {
5028 				char fn[256];
5029 				sprintf( fn, "server%d-pwdhash.sve", env_t::server );
5030 				loadsave_t pwdfile;
5031 				if(  pwdfile.rd_open(fn)  ) {
5032 					rdwr_player_password_hashes( &pwdfile );
5033 					// correct locking info
5034 					nwc_auth_player_t::init_player_lock_server(this);
5035 					pwdfile.close();
5036 				}
5037 			}
5038 		}
5039 		else if(  env_t::networkmode  ) {
5040 			step_mode = PAUSE_FLAG|FIX_RATIO;
5041 			switch_active_player( last_active_player_nr, true );
5042 			if(  is_within_limits(oldpos)  ) {
5043 				// go to position when last disconnected
5044 				viewport->change_world_position( oldpos );
5045 			}
5046 		}
5047 		else {
5048 			step_mode = NORMAL;
5049 		}
5050 
5051 		ok = true;
5052 		file.close();
5053 
5054 		if(  !scenario->rdwr_ok()  ) {
5055 			// error during loading of savegame of scenario
5056 			const char* err = scenario->get_error_text();
5057 			if (err == NULL) {
5058 				err = "Loading scenario failed.";
5059 			}
5060 			create_win( new news_img( err ), w_info, magic_none);
5061 			delete scenario;
5062 			scenario = new scenario_t(this);
5063 		}
5064 		else if(  !env_t::networkmode  ||  !env_t::restore_UI  ) {
5065 			// warning message about missing paks
5066 			if(  !missing_pak_names.empty()  ) {
5067 
5068 				cbuffer_t msg;
5069 				msg.append("<title>");
5070 				msg.append(translator::translate("Missing pakfiles"));
5071 				msg.append("</title>\n");
5072 
5073 				cbuffer_t error_paks;
5074 				cbuffer_t warning_paks;
5075 
5076 				cbuffer_t paklog;
5077 				paklog.append( "\n" );
5078 				FOR(stringhashtable_tpl<missing_level_t>, const& i, missing_pak_names) {
5079 					if (i.value <= MISSING_ERROR) {
5080 						error_paks.append(translator::translate(i.key));
5081 						error_paks.append("<br>\n");
5082 						paklog.append( i.key );
5083 						paklog.append("\n" );
5084 					}
5085 					else {
5086 						warning_paks.append(translator::translate(i.key));
5087 						warning_paks.append("<br>\n");
5088 					}
5089 				}
5090 
5091 				if(  error_paks.len()>0  ) {
5092 					msg.append("<h1>");
5093 					msg.append(translator::translate("Pak which may cause severe errors:"));
5094 					msg.append("</h1><br>\n");
5095 					msg.append("<br>\n");
5096 					msg.append( error_paks );
5097 					msg.append("<br>\n");
5098 					dbg->warning( "The following paks are missing and may cause errors", paklog );
5099 				}
5100 
5101 				if(  warning_paks.len()>0  ) {
5102 					msg.append("<h1>");
5103 					msg.append(translator::translate("Pak which may cause visual errors:"));
5104 					msg.append("</h1><br>\n");
5105 					msg.append("<br>\n");
5106 					msg.append( warning_paks );
5107 					msg.append("<br>\n");
5108 				}
5109 
5110 				help_frame_t *win = new help_frame_t();
5111 				win->set_text( msg );
5112 				create_win(win, w_info, magic_pakset_info_t);
5113 			}
5114 			// will not notify if we restore everything
5115 			if(  scenario->is_scripted()  ) {
5116 				scenario->open_info_win();
5117 			}
5118 			create_win( new news_img("Spielstand wurde\ngeladen!\n"), w_time_delete, magic_none);
5119 		}
5120 		set_dirty();
5121 
5122 		reset_timer();
5123 		recalc_average_speed();
5124 		mute_sound(false);
5125 
5126 		tool_t::update_toolbars();
5127 		toolbar_last_used_t::last_used_tools->clear();
5128 		set_tool( tool_t::general_tool[TOOL_QUERY], get_active_player() );
5129 	}
5130 	settings.set_filename(filename);
5131 	display_show_load_pointer(false);
5132 	return ok;
5133 }
5134 
5135 
5136 
5137 #ifdef MULTI_THREAD
5138 static pthread_mutex_t height_mutex;
5139 static recursive_mutex_maker_t height_mutex_maker(height_mutex);
5140 #endif
5141 
5142 
plans_finish_rd(sint16 x_min,sint16 x_max,sint16 y_min,sint16 y_max)5143 void karte_t::plans_finish_rd( sint16 x_min, sint16 x_max, sint16 y_min, sint16 y_max )
5144 {
5145 	sint8 min_h = min_height, max_h = max_height;
5146 	for(  int y = y_min;  y < y_max;  y++  ) {
5147 		for(  int x = x_min; x < x_max;  x++  ) {
5148 			planquadrat_t *plan = access_nocheck(x,y);
5149 			plan->sort_haltlist();
5150 			const int boden_count = plan->get_boden_count();
5151 			for(  int schicht = 0;  schicht < boden_count;  schicht++  ) {
5152 				grund_t *gr = plan->get_boden_bei(schicht);
5153 				if(  min_h > gr->get_hoehe()  ) {
5154 					min_h = gr->get_hoehe();
5155 				}
5156 				else if(  max_h < gr->get_hoehe()  ) {
5157 					max_h = gr->get_hoehe();
5158 				}
5159 				for(  int n = 0;  n < gr->get_top();  n++  ) {
5160 					obj_t *obj = gr->obj_bei(n);
5161 					if(obj) {
5162 						obj->finish_rd();
5163 					}
5164 				}
5165 				if(  load_version<=111000  &&  gr->ist_natur()  ) {
5166 					gr->sort_trees();
5167 				}
5168 				gr->calc_image();
5169 			}
5170 		}
5171 	}
5172 	// update heights
5173 #ifdef MULTI_THREAD
5174 	pthread_mutex_lock( &height_mutex );
5175 	if(  min_height > min_h  ) {
5176 		min_height = min_h;
5177 	}
5178 	if(  max_height < max_h  ) {
5179 		max_height = max_h;
5180 	}
5181 	pthread_mutex_unlock( &height_mutex );
5182 #else
5183 	min_height = min_h;
5184 	max_height = max_h;
5185 #endif
5186 }
5187 
5188 
load(loadsave_t * file)5189 void karte_t::load(loadsave_t *file)
5190 {
5191 	char buf[80];
5192 
5193 	intr_disable();
5194 	dbg->message("karte_t::load()", "Prepare for loading" );
5195 
5196 	for(  uint8 sp_nr=0;  sp_nr<MAX_PLAYER_COUNT;  sp_nr++  ) {
5197 		if (two_click_tool_t* tool = dynamic_cast<two_click_tool_t*>(selected_tool[sp_nr])) {
5198 			tool->cleanup();
5199 		}
5200 	}
5201 	destroy_all_win(true);
5202 
5203 	clear_random_mode(~LOAD_RANDOM);
5204 	set_random_mode(LOAD_RANDOM);
5205 	destroy();
5206 
5207 	loadingscreen_t ls(translator::translate("Loading map ..."), 1, true, true );
5208 
5209 	tile_counter = 0;
5210 	simloops = 60;
5211 
5212 	// zum laden vorbereiten -> tabelle loeschen
5213 	powernet_t::new_world();
5214 	pumpe_t::new_world();
5215 	senke_t::new_world();
5216 	script_api::new_world();
5217 
5218 	file->set_buffered(true);
5219 
5220 	// jetzt geht das laden los
5221 	dbg->warning("karte_t::load", "Fileversion: %u", file->get_version_int());
5222 	settings = env_t::default_settings;
5223 	settings.rdwr(file);
5224 	loaded_rotation = settings.get_rotation();
5225 
5226 	// some functions (finish_rd) need to know what version was loaded
5227 	load_version = file->get_version_int();
5228 
5229 	if(  env_t::networkmode  ) {
5230 		// to have games synchronized, transfer random counter too
5231 		setsimrand(settings.get_random_counter(), 0xFFFFFFFFu );
5232 		translator::init_custom_names(settings.get_name_language_id());
5233 	}
5234 
5235 	if(  !env_t::networkmode  ||  (env_t::server  &&  socket_list_t::get_playing_clients()==0)  ) {
5236 		if (settings.get_allow_player_change() && env_t::default_settings.get_use_timeline() < 2) {
5237 			// not locked => eventually switch off timeline settings, if explicitly stated
5238 			settings.set_use_timeline(env_t::default_settings.get_use_timeline());
5239 			DBG_DEBUG("karte_t::load", "timeline: reset to %i", env_t::default_settings.get_use_timeline() );
5240 		}
5241 	}
5242 	if (settings.get_beginner_mode()) {
5243 		goods_manager_t::set_multiplier(settings.get_beginner_price_factor());
5244 	}
5245 	else {
5246 		goods_manager_t::set_multiplier( 1000 );
5247 	}
5248 
5249 	world_maximum_height = settings.get_maximumheight();
5250 	world_minimum_height = settings.get_minimumheight();
5251 
5252 	groundwater = (sint8)(settings.get_groundwater());
5253 	min_height = max_height = groundwater;
5254 	DBG_DEBUG("karte_t::load()","groundwater %i",groundwater);
5255 
5256 	if(  file->is_version_less(112, 7)  ) {
5257 		// r7930 fixed a bug in init_height_to_climate
5258 		// recover old behavior to not mix up climate when loading old savegames
5259 		groundwater = settings.get_climate_borders()[0];
5260 		init_height_to_climate();
5261 		groundwater = settings.get_groundwater();
5262 	}
5263 	else {
5264 		init_height_to_climate();
5265 	}
5266 
5267 	// just an initialisation for the loading
5268 	season = (2+last_month/3)&3; // summer always zero
5269 	snowline = settings.get_winter_snowline() + groundwater;
5270 
5271 	DBG_DEBUG("karte_t::load", "settings loaded (size %i,%i) timeline=%i beginner=%i", settings.get_size_x(), settings.get_size_y(), settings.get_use_timeline(), settings.get_beginner_mode());
5272 
5273 	// wird gecached, um den Pointerzugriff zu sparen, da
5274 	// die size _sehr_ oft referenziert wird
5275 	cached_grid_size.x = settings.get_size_x();
5276 	cached_grid_size.y = settings.get_size_y();
5277 	cached_size_max = max(cached_grid_size.x,cached_grid_size.y);
5278 	cached_size.x = cached_grid_size.x-1;
5279 	cached_size.y = cached_grid_size.y-1;
5280 	viewport->set_x_off(0);
5281 	viewport->set_y_off(0);
5282 
5283 	// Update minimap for new world
5284 	minimap_t::get_instance()->init();
5285 
5286 	ls.set_max( get_size().y*2+256 );
5287 	init_tiles();
5288 
5289 
5290 	// reinit pointer with new pointer object and old values
5291 	zeiger = new zeiger_t(koord3d::invalid, NULL );
5292 
5293 	hausbauer_t::new_world();
5294 	factory_builder_t::new_world();
5295 
5296 DBG_DEBUG("karte_t::load", "init felder ok");
5297 
5298 	file->rdwr_long(ticks);
5299 	file->rdwr_long(last_month);
5300 	file->rdwr_long(last_year);
5301 	if(file->is_version_less(86, 6)) {
5302 		last_year += env_t::default_settings.get_starting_year();
5303 	}
5304 	// old game might have wrong month
5305 	last_month %= 12;
5306 	// set the current month count
5307 	set_ticks_per_world_month_shift(settings.get_bits_per_month());
5308 	current_month = last_month + (last_year*12);
5309 	season = (2+last_month/3)&3; // summer always zero
5310 	next_month_ticks = 	( (ticks >> karte_t::ticks_per_world_month_shift) + 1 ) << karte_t::ticks_per_world_month_shift;
5311 	last_step_ticks = ticks;
5312 	steps = 0;
5313 	network_frame_count = 0;
5314 	sync_steps = 0;
5315 	sync_steps_barrier = sync_steps;
5316 	step_mode = PAUSE_FLAG;
5317 
5318 DBG_MESSAGE("karte_t::load()","savegame loading at tick count %i",ticks);
5319 	recalc_average_speed();	// resets timeline
5320 	koord::locality_factor = settings.get_locality_factor( last_year );	// resets weight factor
5321 	// recalc_average_speed may have opened message windows
5322 	destroy_all_win(true);
5323 
5324 DBG_MESSAGE("karte_t::load()", "init player");
5325 	for(int i=0; i<MAX_PLAYER_COUNT; i++) {
5326 		if(  file->is_version_atleast(101, 0)  ) {
5327 			// since we have different kind of AIs
5328 			delete players[i];
5329 			players[i] = NULL;
5330 			init_new_player(i, settings.player_type[i]);
5331 		}
5332 		else if(i<8) {
5333 			// get the old player ...
5334 			if(  players[i]==NULL  ) {
5335 				init_new_player( i, (i==3) ? player_t::AI_PASSENGER : player_t::AI_GOODS );
5336 			}
5337 			settings.player_type[i] = players[i]->get_ai_id();
5338 		}
5339 	}
5340 	// so far, player 1 will be active (may change in future)
5341 	active_player = players[0];
5342 	active_player_nr = 0;
5343 
5344 	// rdwr static states
5345 	senke_t::static_rdwr(file);
5346 
5347 	// rdwr cityrules, speedbonus for networkgames
5348 	if(file->is_version_atleast(102, 3)) {
5349 		bool do_rdwr = env_t::networkmode;
5350 		file->rdwr_bool(do_rdwr);
5351 		if (do_rdwr) {
5352 			stadt_t::cityrules_rdwr(file);
5353 			if(file->is_version_atleast(102, 4)) {
5354 				vehicle_builder_t::rdwr_speedbonus(file);
5355 			}
5356 		}
5357 	}
5358 	DBG_DEBUG("karte_t::load", "init %i cities", settings.get_city_count());
5359 	stadt.clear();
5360 	stadt.resize(settings.get_city_count());
5361 	for (int i = 0; i < settings.get_city_count(); ++i) {
5362 		stadt_t *s = new stadt_t(file);
5363 		stadt.append( s, s->get_einwohner());
5364 	}
5365 
5366 	DBG_MESSAGE("karte_t::load()","loading blocks");
5367 	old_blockmanager_t::rdwr(this, file);
5368 
5369 	DBG_MESSAGE("karte_t::load()","loading tiles");
5370 	for (int y = 0; y < get_size().y; y++) {
5371 		for (int x = 0; x < get_size().x; x++) {
5372 			plan[x+y*cached_grid_size.x].rdwr(file, koord(x,y) );
5373 		}
5374 		if(file->is_eof()) {
5375 			dbg->fatal("karte_t::load()","Savegame file mangled (too short)!");
5376 		}
5377 		ls.set_progress( y/2 );
5378 	}
5379 
5380 	if(file->is_version_less(99, 5)) {
5381 		DBG_MESSAGE("karte_t::load()","loading grid for older versions");
5382 		for (int y = 0; y <= get_size().y; y++) {
5383 			for (int x = 0; x <= get_size().x; x++) {
5384 				sint32 hgt;
5385 				file->rdwr_long(hgt);
5386 				// old height step was 16!
5387 				set_grid_hgt(x, y, hgt/16 );
5388 			}
5389 		}
5390 	}
5391 	else if(  file->is_version_less(102, 2)  )  {
5392 		// hgt now bytes
5393 		DBG_MESSAGE("karte_t::load()","loading grid for older versions");
5394 		for( sint32 i=0;  i<(get_size().y+1)*(sint32)(get_size().x+1);  i++  ) {
5395 			file->rdwr_byte(grid_hgts[i]);
5396 		}
5397 	}
5398 
5399 	if(file->is_version_less(88, 9)) {
5400 		DBG_MESSAGE("karte_t::load()","loading slopes from older version");
5401 		// Hajo: load slopes for older versions
5402 		// now part of the grund_t structure
5403 		for (int y = 0; y < get_size().y; y++) {
5404 			for (int x = 0; x < get_size().x; x++) {
5405 				sint8 slope;
5406 				file->rdwr_byte(slope);
5407 				// convert slopes from old single height saved game
5408 				slope = (scorner_sw(slope) + scorner_se(slope) * 3 + scorner_ne(slope) * 9 + scorner_nw(slope) * 27) * env_t::pak_height_conversion_factor;
5409 				access_nocheck(x, y)->get_kartenboden()->set_grund_hang(slope);
5410 			}
5411 		}
5412 	}
5413 
5414 	if(file->is_version_less(88, 1)) {
5415 		// because from 88.01.4 on the foundations are handled differently
5416 		for (int y = 0; y < get_size().y; y++) {
5417 			for (int x = 0; x < get_size().x; x++) {
5418 				koord k(x,y);
5419 				grund_t *gr = access_nocheck(x, y)->get_kartenboden();
5420 				if(  gr->get_typ()==grund_t::fundament  ) {
5421 					gr->set_hoehe( max_hgt_nocheck(k) );
5422 					gr->set_grund_hang( slope_t::flat );
5423 					// transfer object to on new grund
5424 					for(  int i=0;  i<gr->get_top();  i++  ) {
5425 						gr->obj_bei(i)->set_pos( gr->get_pos() );
5426 					}
5427 				}
5428 			}
5429 		}
5430 	}
5431 
5432 	if(  file->is_version_less(112, 7)  ) {
5433 		// set climates
5434 		for(  sint16 y = 0;  y < get_size().y;  y++  ) {
5435 			for(  sint16 x = 0;  x < get_size().x;  x++  ) {
5436 				calc_climate( koord( x, y ), false );
5437 			}
5438 		}
5439 	}
5440 
5441 	// Update minimap for new world
5442 	DBG_MESSAGE("karte_t::load()", "init minimap");
5443 	win_set_world( this );
5444 	minimap_t::get_instance()->init();
5445 
5446 	// tick all power nets so that they update with loaded power
5447 	powernet_t::step_all(1);
5448 
5449 	// load factories
5450 	sint32 fabs;
5451 	file->rdwr_long(fabs);
5452 	DBG_MESSAGE("karte_t::load()", "prepare for %i factories", fabs);
5453 
5454 	for(sint32 i = 0; i < fabs; i++) {
5455 		// list in gleicher reihenfolge wie vor dem speichern wieder aufbauen
5456 		fabrik_t *fab = new fabrik_t(file);
5457 		if(fab->get_desc()) {
5458 			fab_list.append( fab );
5459 		}
5460 		else {
5461 			dbg->error("karte_t::load()","Unknown factory skipped!");
5462 			delete fab;
5463 		}
5464 		if(i&7) {
5465 			ls.set_progress( get_size().y/2+(128*i)/fabs );
5466 		}
5467 	}
5468 
5469 	// load linemanagement status (and lines)
5470 	// @author hsiegeln
5471 	if (file->is_version_atleast(82, 4)  &&  file->is_version_less(88, 3)) {
5472 		DBG_MESSAGE("karte_t::load()", "load linemanagement");
5473 		get_player(0)->simlinemgmt.rdwr(file, get_player(0));
5474 	}
5475 	// end load linemanagement
5476 
5477 	DBG_MESSAGE("karte_t::load()", "load stops");
5478 	// now load the stops
5479 	// (the players will be load later and overwrite some values,
5480 	//  like the total number of stops build (for the numbered station feature)
5481 	haltestelle_t::start_load_game();
5482 	if(file->is_version_atleast(99, 8)) {
5483 		sint32 halt_count;
5484 		file->rdwr_long(halt_count);
5485 		DBG_MESSAGE("karte_t::load()","%d halts loaded",halt_count);
5486 		for(int i=0; i<halt_count; i++) {
5487 			halthandle_t halt = haltestelle_t::create( file );
5488 			if(!halt->existiert_in_welt()) {
5489 				dbg->warning("karte_t::load()", "could not restore stop near %i,%i", halt->get_init_pos().x, halt->get_init_pos().y );
5490 			}
5491 			ls.set_progress( get_size().y/2+128+(get_size().y*i)/(2*halt_count) );
5492 		}
5493 	}
5494 
5495 	DBG_MESSAGE("karte_t::load()", "load convois");
5496 	uint16 convoi_nr = 65535;
5497 	uint16 max_convoi = 65535;
5498 	if(  file->is_version_atleast(101, 0)  ) {
5499 		file->rdwr_short(convoi_nr);
5500 		max_convoi = convoi_nr;
5501 	}
5502 	while(  convoi_nr-->0  ) {
5503 
5504 		if(  file->is_version_less(101, 0)  ) {
5505 			file->rd_obj_id(buf, 79);
5506 			if (strcmp(buf, "Ende Convois") == 0) {
5507 				break;
5508 			}
5509 		}
5510 		convoi_t *cnv = new convoi_t(file);
5511 		convoi_array.append(cnv->self);
5512 
5513 		if(cnv->in_depot()) {
5514 			grund_t * gr = lookup(cnv->get_pos());
5515 			depot_t *dep = gr ? gr->get_depot() : 0;
5516 			if(dep) {
5517 				cnv->betrete_depot(dep);
5518 			}
5519 			else {
5520 				dbg->error("karte_t::load()", "no depot for convoi, blocks may now be wrongly reserved!");
5521 				cnv->destroy();
5522 			}
5523 		}
5524 		else {
5525 			sync.add( cnv );
5526 		}
5527 		if(  (convoi_array.get_count()&7) == 0  ) {
5528 			ls.set_progress( get_size().y+(get_size().y*convoi_array.get_count())/(2*max_convoi)+128 );
5529 		}
5530 	}
5531 DBG_MESSAGE("karte_t::load()", "%d convois/trains loaded", convoi_array.get_count());
5532 
5533 	// now the player can be loaded
5534 	for(int i=0; i<MAX_PLAYER_COUNT; i++) {
5535 		if(  players[i]  ) {
5536 			players[i]->rdwr(file);
5537 			settings.player_active[i] = players[i]->is_active();
5538 		}
5539 		else {
5540 			settings.player_active[i] = false;
5541 		}
5542 		ls.set_progress( (get_size().y*3)/2+128+8*i );
5543 	}
5544 DBG_MESSAGE("karte_t::load()", "players loaded");
5545 
5546 	// loading messages
5547 	if(  file->is_version_atleast(102, 5)  ) {
5548 		msg->rdwr(file);
5549 	}
5550 	else if(  !env_t::networkmode  ) {
5551 		msg->clear();
5552 	}
5553 DBG_MESSAGE("karte_t::load()", "messages loaded");
5554 
5555 	// nachdem die welt jetzt geladen ist koennen die Blockstrecken neu
5556 	// angelegt werden
5557 	old_blockmanager_t::finish_rd(this);
5558 	DBG_MESSAGE("karte_t::load()", "blocks loaded");
5559 
5560 	sint32 mi,mj;
5561 	file->rdwr_long(mi);
5562 	file->rdwr_long(mj);
5563 	DBG_MESSAGE("karte_t::load()", "Setting view to %d,%d", mi,mj);
5564 	viewport->change_world_position( koord3d(mi,mj,0) );
5565 
5566 	// right season for recalculations
5567 	recalc_season_snowline(false);
5568 
5569 DBG_MESSAGE("karte_t::load()", "%d ways loaded",weg_t::get_alle_wege().get_count());
5570 
5571 	ls.set_progress( (get_size().y*3)/2+256 );
5572 
5573 	world_xy_loop(&karte_t::plans_finish_rd, SYNCX_FLAG);
5574 
5575 	if(  file->is_version_less(112, 7)  ) {
5576 		// set transitions - has to be done after plans_finish_rd
5577 		world_xy_loop(&karte_t::recalc_transitions_loop, 0);
5578 	}
5579 
5580 	ls.set_progress( (get_size().y*3)/2+256+get_size().y/8 );
5581 
5582 DBG_MESSAGE("karte_t::load()", "laden_abschliesen for tiles finished" );
5583 
5584 	// must finish loading cities first before cleaning up factories
5585 	weighted_vector_tpl<stadt_t*> new_weighted_stadt(stadt.get_count() + 1);
5586 	FOR(weighted_vector_tpl<stadt_t*>, const s, stadt) {
5587 		s->finish_rd();
5588 		s->recalc_target_cities();
5589 		new_weighted_stadt.append(s, s->get_einwohner());
5590 		INT_CHECK("simworld 1278");
5591 	}
5592 	swap(stadt, new_weighted_stadt);
5593 	DBG_MESSAGE("karte_t::load()", "cities initialized");
5594 
5595 	ls.set_progress( (get_size().y*3)/2+256+get_size().y/4 );
5596 
5597 	DBG_MESSAGE("karte_t::load()", "clean up factories");
5598 	FOR(slist_tpl<fabrik_t*>, const f, fab_list) {
5599 		f->finish_rd();
5600 	}
5601 
5602 DBG_MESSAGE("karte_t::load()", "%d factories loaded", fab_list.get_count());
5603 
5604 	// old versions did not save factory connections
5605 	if(file->is_version_less(99, 14)) {
5606 		sint32 const temp_min = settings.get_factory_worker_minimum_towns();
5607 		sint32 const temp_max = settings.get_factory_worker_maximum_towns();
5608 		// this needs to avoid the first city to be connected to all town
5609 		settings.set_factory_worker_minimum_towns(0);
5610 		settings.set_factory_worker_maximum_towns(stadt.get_count() + 1);
5611 		FOR(weighted_vector_tpl<stadt_t*>, const i, stadt) {
5612 			i->verbinde_fabriken();
5613 		}
5614 		settings.set_factory_worker_minimum_towns(temp_min);
5615 		settings.set_factory_worker_maximum_towns(temp_max);
5616 	}
5617 	ls.set_progress( (get_size().y*3)/2+256+get_size().y/3 );
5618 
5619 	// resolve dummy stops into real stops first ...
5620 	FOR(vector_tpl<halthandle_t>, const i, haltestelle_t::get_alle_haltestellen()) {
5621 		if (i->get_owner() && i->existiert_in_welt()) {
5622 			i->finish_rd();
5623 		}
5624 	}
5625 
5626 	// ... before removing dummy stops
5627 	for(  vector_tpl<halthandle_t>::const_iterator i=haltestelle_t::get_alle_haltestellen().begin(); i!=haltestelle_t::get_alle_haltestellen().end();  ) {
5628 		halthandle_t const h = *i;
5629 		if(  !h->get_owner()  ||  !h->existiert_in_welt()  ) {
5630 			// this stop was only needed for loading goods ...
5631 			haltestelle_t::destroy(h);	// remove from list
5632 		}
5633 		else {
5634 			++i;
5635 		}
5636 	}
5637 
5638 	ls.set_progress( (get_size().y*3)/2+256+(get_size().y*3)/8 );
5639 
5640 	// adding lines and other stuff for convois
5641 	for(unsigned i=0;  i<convoi_array.get_count();  i++ ) {
5642 		convoihandle_t cnv = convoi_array[i];
5643 		cnv->finish_rd();
5644 		// was deleted during loading => use same position again
5645 		if(!cnv.is_bound()) {
5646 			i--;
5647 		}
5648 	}
5649 	haltestelle_t::end_load_game();
5650 
5651 	// register all line stops and change line types, if needed
5652 	for(int i=0; i<MAX_PLAYER_COUNT ; i++) {
5653 		if(  players[i]  ) {
5654 			players[i]->finish_rd();
5655 		}
5656 	}
5657 
5658 #ifdef DEBUG
5659 	uint32 dt = dr_time();
5660 #endif
5661 	// recalculate halt connections
5662 	haltestelle_t::reset_routing();
5663 	do {
5664 		haltestelle_t::step_all();
5665 	} while (  haltestelle_t::get_rerouting_status()==RECONNECTING  );
5666 #ifdef DEBUG
5667 	dbg->message("rebuild_destinations()","for all haltstellen_t took %ld ms", dr_time()-dt );
5668 #endif
5669 
5670 #if 0
5671 	// reroute goods for benchmarking
5672 	dt = dr_time();
5673 	FOR(vector_tpl<halthandle_t>, const i, haltestelle_t::get_alle_haltestellen()) {
5674 		sint16 dummy = 0x7FFF;
5675 		i->reroute_goods(dummy);
5676 	}
5677 	DBG_MESSAGE("reroute_goods()","for all haltstellen_t took %ld ms", dr_time()-dt );
5678 #endif
5679 
5680 	// load history/create world history
5681 	if(file->is_version_less(99, 18)) {
5682 		restore_history(false);
5683 	}
5684 	else {
5685 		for (int year = 0;  year</*MAX_WORLD_HISTORY_YEARS*/12;  year++) {
5686 			for (int cost_type = 0; cost_type</*MAX_WORLD_COST*/12; cost_type++) {
5687 				file->rdwr_longlong(finance_history_year[year][cost_type]);
5688 			}
5689 		}
5690 		for (int month = 0;month</*MAX_WORLD_HISTORY_MONTHS*/12;month++) {
5691 			for (int cost_type = 0; cost_type</*MAX_WORLD_COST*/12; cost_type++) {
5692 				file->rdwr_longlong(finance_history_month[month][cost_type]);
5693 			}
5694 		}
5695 		last_month_bev = finance_history_month[1][WORLD_CITICENS];
5696 
5697 		if (file->is_version_atleast(112, 5) &&  file->is_version_less(120, 6)) {
5698 			restore_history(true);
5699 		}
5700 	}
5701 
5702 	// finally: do we run a scenario?
5703 	if(file->is_version_atleast(99, 18)) {
5704 		scenario->rdwr(file);
5705 	}
5706 
5707 	// restore locked state
5708 	// network game this will be done in nwc_sync_t::do_command
5709 	if(  !env_t::networkmode  ) {
5710 		for(  uint8 i=0;  i<PLAYER_UNOWNED;  i++  ) {
5711 			if(  players[i]  ) {
5712 				players[i]->check_unlock( player_password_hash[i] );
5713 			}
5714 		}
5715 	}
5716 
5717 	// initialize lock info for local server player
5718 	// if call from sync command, lock info will be corrected there
5719 	if(  env_t::server  ) {
5720 		nwc_auth_player_t::init_player_lock_server(this);
5721 	}
5722 
5723 	// show message about server
5724 	if(  file->is_version_atleast(112, 8)  ) {
5725 		xml_tag_t t( file, "motd_t" );
5726 		char msg[32766];
5727 		file->rdwr_str( msg, 32766 );
5728 		if(  *msg  &&  !env_t::server  ) {
5729 			// if not empty ...
5730 			help_frame_t *win = new help_frame_t();
5731 			win->set_text( msg );
5732 			create_win(win, w_info, magic_motd);
5733 		}
5734 	}
5735 
5736 	if(  file->is_version_atleast(102, 4)  ) {
5737 		if(  env_t::restore_UI  ) {
5738 			file->rdwr_byte( active_player_nr );
5739 			active_player = players[active_player_nr];
5740 			/* restore all open windows
5741 			 * otherwise it will be ignored
5742 			 * which is save, since it is the end of file
5743 			 */
5744 			rdwr_all_win( file );
5745 		}
5746 	}
5747 
5748 	file->set_buffered(false);
5749 	clear_random_mode(LOAD_RANDOM);
5750 
5751 	// loading finished, reset savegame version to current
5752 	load_version = loadsave_t::int_version( env_t::savegame_version_str, NULL );
5753 
5754 	dbg->warning("karte_t::load()","loaded savegame from %i/%i, next month=%i, ticks=%i (per month=1<<%i)",last_month,last_year,next_month_ticks,ticks,karte_t::ticks_per_world_month_shift);
5755 }
5756 
5757 
5758 // recalcs all ground tiles on the map
update_map_intern(sint16 x_min,sint16 x_max,sint16 y_min,sint16 y_max)5759 void karte_t::update_map_intern(sint16 x_min, sint16 x_max, sint16 y_min, sint16 y_max)
5760 {
5761 	if(  (loaded_rotation + settings.get_rotation()) & 1  ) {  // 1 || 3  // ~14% faster loop blocking rotations 1 and 3
5762 		const int LOOP_BLOCK = 128;
5763 		for(  int xx = x_min;  xx < x_max;  xx += LOOP_BLOCK  ) {
5764 			for(  int yy = y_min;  yy < y_max;  yy += LOOP_BLOCK  ) {
5765 				for(  int y = yy;  y < min(yy + LOOP_BLOCK, y_max);  y++  ) {
5766 					for(  int x = xx;  x < min(xx + LOOP_BLOCK, x_max);  x++  ) {
5767 						const int nr = y * cached_grid_size.x + x;
5768 						for(  uint i = 0;  i < plan[nr].get_boden_count();  i++  ) {
5769 							plan[nr].get_boden_bei(i)->calc_image();
5770 						}
5771 					}
5772 				}
5773 			}
5774 		}
5775 	}
5776 	else {
5777 		for(  int y = y_min;  y < y_max;  y++  ) {
5778 			for(  int x = x_min;  x < x_max;  x++  ) {
5779 				const int nr = y * cached_grid_size.x + x;
5780 				for(  uint i = 0;  i < plan[nr].get_boden_count();  i++  ) {
5781 					plan[nr].get_boden_bei(i)->calc_image();
5782 				}
5783 			}
5784 		}
5785 	}
5786 }
5787 
5788 
5789 // recalcs all ground tiles on the map
update_map()5790 void karte_t::update_map()
5791 {
5792 	DBG_MESSAGE( "karte_t::update_map()", "" );
5793 	world_xy_loop(&karte_t::update_map_intern, SYNCX_FLAG);
5794 	set_dirty();
5795 }
5796 
5797 
update_underground()5798 void karte_t::update_underground()
5799 {
5800 	DBG_MESSAGE( "karte_t::update_underground_map()", "" );
5801 	get_view()->clear_prepared();
5802 	world_view_t::invalidate_all();
5803 	set_dirty();
5804 }
5805 
prepare_tiles(rect_t const & new_area,rect_t const & old_area)5806 void karte_t::prepare_tiles(rect_t const &new_area, rect_t const &old_area) {
5807 	if (new_area == old_area) {
5808 		// area already prepared
5809 		return;
5810 	}
5811 
5812 	size_t const prepare_rects_capacity = rect_t::MAX_FRAGMENT_DIFFERENCE_COUNT;
5813 	rect_t prepare_rects[prepare_rects_capacity];
5814 	size_t const prepare_rects_length = new_area.fragment_difference(old_area, prepare_rects, prepare_rects_capacity);
5815 
5816 	// additional tiles to prepare for correct hiding behaviour
5817 	sint16 const prefix_tiles_x = min(grund_t::MAXIMUM_HIDE_TEST_DISTANCE, new_area.origin.x);
5818 	sint16 const prefix_tiles_y = min(grund_t::MAXIMUM_HIDE_TEST_DISTANCE, new_area.origin.y);
5819 
5820 	for (size_t rect_index = 0 ; rect_index < prepare_rects_length ; rect_index++) {
5821 		rect_t const &prepare_rect = prepare_rects[rect_index];
5822 
5823 		sint16 x_start = prepare_rect.origin.x;
5824 		sint16 const x_end = x_start + prepare_rect.size.x;
5825 		if (x_start == new_area.origin.x) {
5826 			x_start-= prefix_tiles_x;
5827 		}
5828 
5829 		sint16 y_start = prepare_rect.origin.y;
5830 		sint16 const y_end = y_start + prepare_rect.size.y;
5831 		if (y_start == new_area.origin.y) {
5832 			y_start-= prefix_tiles_y;
5833 		}
5834 
5835 		for (sint16 y = y_start ; y < y_end ; y++) {
5836 			for (sint16 x = x_start ; x < x_end ; x++) {
5837 				const planquadrat_t &tile = plan[y * cached_grid_size.x + x];
5838 				tile.update_underground();
5839 			}
5840 		}
5841 	}
5842 }
5843 
calc_climate(koord k,bool recalc)5844 void karte_t::calc_climate(koord k, bool recalc)
5845 {
5846 	planquadrat_t *pl = access(k);
5847 	if(  !pl  ) {
5848 		return;
5849 	}
5850 
5851 	grund_t *gr = pl->get_kartenboden();
5852 	if(  gr  ) {
5853 		if(  !gr->is_water()  ) {
5854 			bool beach = false;
5855 			if(  gr->get_pos().z == groundwater  ) {
5856 				for(  int i = 0;  i < 8 && !beach;  i++  ) {
5857 					grund_t *gr2 = lookup_kartenboden( k + koord::neighbours[i] );
5858 					if(  gr2 && gr2->is_water()  ) {
5859 						beach = true;
5860 					}
5861 				}
5862 			}
5863 			pl->set_climate( beach ? desert_climate : get_climate_at_height( max( gr->get_pos().z, groundwater + 1 ) ) );
5864 		}
5865 		else {
5866 			pl->set_climate( water_climate );
5867 		}
5868 		pl->set_climate_transition_flag(false);
5869 		pl->set_climate_corners(0);
5870 	}
5871 
5872 	if(  recalc  ) {
5873 		recalc_transitions(k);
5874 		for(  int i = 0;  i < 8;  i++  ) {
5875 			recalc_transitions( k + koord::neighbours[i] );
5876 		}
5877 	}
5878 }
5879 
5880 
5881 // fills array with neighbour heights
get_neighbour_heights(const koord k,sint8 neighbour_height[8][4]) const5882 void karte_t::get_neighbour_heights(const koord k, sint8 neighbour_height[8][4]) const
5883 {
5884 	for(  int i = 0;  i < 8;  i++  ) { // 0 = nw, 1 = w etc.
5885 		planquadrat_t *pl2 = access( k + koord::neighbours[i] );
5886 		if(  pl2  ) {
5887 			grund_t *gr2 = pl2->get_kartenboden();
5888 			slope_t::type slope_corner = gr2->get_grund_hang();
5889 			for(  int j = 0;  j < 4;  j++  ) {
5890 				neighbour_height[i][j] = gr2->get_hoehe() + slope_corner % 3;
5891 				slope_corner /= 3;
5892 			}
5893 		}
5894 		else {
5895 			switch(i) {
5896 				case 0: // nw
5897 					neighbour_height[i][0] = groundwater;
5898 					neighbour_height[i][1] = max( lookup_hgt( k+koord(0,0) ), get_water_hgt( k ) );
5899 					neighbour_height[i][2] = groundwater;
5900 					neighbour_height[i][3] = groundwater;
5901 				break;
5902 				case 1: // w
5903 					neighbour_height[i][0] = groundwater;
5904 					neighbour_height[i][1] = max( lookup_hgt( k+koord(0,1) ), get_water_hgt( k ) );
5905 					neighbour_height[i][2] = max( lookup_hgt( k+koord(0,0) ), get_water_hgt( k ) );
5906 					neighbour_height[i][3] = groundwater;
5907 				break;
5908 				case 2: // sw
5909 					neighbour_height[i][0] = groundwater;
5910 					neighbour_height[i][1] = groundwater;
5911 					neighbour_height[i][2] = max( lookup_hgt( k+koord(0,1) ), get_water_hgt( k ) );
5912 					neighbour_height[i][3] = groundwater;
5913 				break;
5914 				case 3: // s
5915 					neighbour_height[i][0] = groundwater;
5916 					neighbour_height[i][1] = groundwater;
5917 					neighbour_height[i][2] = max( lookup_hgt( k+koord(1,1) ), get_water_hgt( k ) );
5918 					neighbour_height[i][3] = max( lookup_hgt( k+koord(0,1) ), get_water_hgt( k ) );
5919 				break;
5920 				case 4: // se
5921 					neighbour_height[i][0] = groundwater;
5922 					neighbour_height[i][1] = groundwater;
5923 					neighbour_height[i][2] = groundwater;
5924 					neighbour_height[i][3] = max( lookup_hgt( k+koord(1,1) ), get_water_hgt( k ) );
5925 				break;
5926 				case 5: // e
5927 					neighbour_height[i][0] = max( lookup_hgt( k+koord(1,1) ), get_water_hgt( k ) );
5928 					neighbour_height[i][1] = groundwater;
5929 					neighbour_height[i][2] = groundwater;
5930 					neighbour_height[i][3] = max( lookup_hgt( k+koord(1,0) ), get_water_hgt( k ) );
5931 				break;
5932 				case 6: // ne
5933 					neighbour_height[i][0] = max( lookup_hgt( k+koord(1,0) ), get_water_hgt( k ) );
5934 					neighbour_height[i][1] = groundwater;
5935 					neighbour_height[i][2] = groundwater;
5936 					neighbour_height[i][3] = groundwater;
5937 				break;
5938 				case 7: // n
5939 					neighbour_height[i][0] = max( lookup_hgt( k+koord(0,0) ), get_water_hgt( k ) );
5940 					neighbour_height[i][1] = max( lookup_hgt( k+koord(1,0) ), get_water_hgt( k ) );
5941 					neighbour_height[i][2] = groundwater;
5942 					neighbour_height[i][3] = groundwater;
5943 				break;
5944 			}
5945 
5946 			/*neighbour_height[i][0] = groundwater;
5947 			neighbour_height[i][1] = groundwater;
5948 			neighbour_height[i][2] = groundwater;
5949 			neighbour_height[i][3] = groundwater;*/
5950 		}
5951 	}
5952 }
5953 
5954 
rotate_transitions(koord k)5955 void karte_t::rotate_transitions(koord k)
5956 {
5957 	planquadrat_t *pl = access(k);
5958 	if(  !pl  ) {
5959 		return;
5960 	}
5961 
5962 	uint8 climate_corners = pl->get_climate_corners();
5963 	if(  climate_corners != 0  ) {
5964 		climate_corners = (climate_corners >> 1) | ((climate_corners & 1) << 3);
5965 		pl->set_climate_corners( climate_corners );
5966 	}
5967 }
5968 
5969 
recalc_transitions_loop(sint16 x_min,sint16 x_max,sint16 y_min,sint16 y_max)5970 void karte_t::recalc_transitions_loop( sint16 x_min, sint16 x_max, sint16 y_min, sint16 y_max )
5971 {
5972 	for(  int y = y_min;  y < y_max;  y++  ) {
5973 		for(  int x = x_min; x < x_max;  x++  ) {
5974 			recalc_transitions( koord( x, y ) );
5975 		}
5976 	}
5977 }
5978 
5979 
recalc_transitions(koord k)5980 void karte_t::recalc_transitions(koord k)
5981 {
5982 	planquadrat_t *pl = access(k);
5983 	if(  !pl  ) {
5984 		return;
5985 	}
5986 
5987 	grund_t *gr = pl->get_kartenboden();
5988 	if(  !gr->is_water()  ) {
5989 		// get neighbour corner heights
5990 		sint8 neighbour_height[8][4];
5991 		get_neighbour_heights( k, neighbour_height );
5992 
5993 		// look up neighbouring climates
5994 		climate neighbour_climate[8];
5995 		for(  int i = 0;  i < 8;  i++  ) { // 0 = nw, 1 = w etc.
5996 			koord k_neighbour = k + koord::neighbours[i];
5997 			if(  !is_within_limits(k_neighbour)  ) {
5998 				k_neighbour = get_closest_coordinate(k_neighbour);
5999 			}
6000 			neighbour_climate[i] = get_climate( k_neighbour );
6001 		}
6002 
6003 		uint8 climate_corners = 0;
6004 		climate climate0 = get_climate(k);
6005 
6006 		slope_t::type slope_corner = gr->get_grund_hang();
6007 		for(  uint8 i = 0;  i < 4;  i++  ) { // 0 = sw, 1 = se etc.
6008 			// corner_sw (i=0): tests vs neighbour 1:w (corner 2 j=1),2:sw (corner 3) and 3:s (corner 4)
6009 			// corner_se (i=1): tests vs neighbour 3:s (corner 3 j=2),4:se (corner 4) and 5:e (corner 1)
6010 			// corner_ne (i=2): tests vs neighbour 5:e (corner 4 j=3),6:ne (corner 1) and 7:n (corner 2)
6011 			// corner_nw (i=3): tests vs neighbour 7:n (corner 1 j=0),0:nw (corner 2) and 1:w (corner 3)
6012 			sint8 corner_height = gr->get_hoehe() + slope_corner % 3;
6013 
6014 			climate transition_climate = water_climate;
6015 			climate min_climate = arctic_climate;
6016 
6017 			for(  int j = 1;  j < 4;  j++  ) {
6018 				if(  corner_height == neighbour_height[(i * 2 + j) & 7][(i + j) & 3]) {
6019 					climate climatej = neighbour_climate[(i * 2 + j) & 7];
6020 					climatej > transition_climate ? transition_climate = climatej : 0;
6021 					climatej < min_climate ? min_climate = climatej : 0;
6022 				}
6023 			}
6024 
6025 			if(  min_climate == water_climate  ||  transition_climate > climate0  ) {
6026 				climate_corners |= 1 << i;
6027 			}
6028 			slope_corner /= 3;
6029 		}
6030 		pl->set_climate_transition_flag( climate_corners != 0 );
6031 		pl->set_climate_corners( climate_corners );
6032 	}
6033 	gr->calc_image();
6034 }
6035 
6036 
create_grounds_loop(sint16 x_min,sint16 x_max,sint16 y_min,sint16 y_max)6037 void karte_t::create_grounds_loop( sint16 x_min, sint16 x_max, sint16 y_min, sint16 y_max )
6038 {
6039 	for(  int y = y_min;  y < y_max;  y++  ) {
6040 		for(  int x = x_min; x < x_max;  x++  ) {
6041 			koord k(x,y);
6042 			access_nocheck(k)->kartenboden_setzen( new boden_t( koord3d( x, y, max(min_hgt_nocheck(k),get_water_hgt_nocheck(k)) ), 0 ) );
6043 		}
6044 	}
6045 }
6046 
6047 
sp2num(player_t * player)6048 uint8 karte_t::sp2num(player_t *player)
6049 {
6050 	if(  player==NULL  ) {
6051 		return PLAYER_UNOWNED;
6052 	}
6053 	for(int i=0; i<MAX_PLAYER_COUNT; i++) {
6054 		if(players[i] == player) {
6055 			return i;
6056 		}
6057 	}
6058 	dbg->fatal( "karte_t::sp2num()", "called with an invalid player!" );
6059 }
6060 
6061 
load_heightfield(settings_t * const sets)6062 void karte_t::load_heightfield(settings_t* const sets)
6063 {
6064 	sint16 w, h;
6065 	sint8 *h_field;
6066 	height_map_loader_t hml(sets);
6067 	if(hml.get_height_data_from_file(sets->heightfield.c_str(), (sint8)(sets->get_groundwater()), h_field, w, h, false )) {
6068 		sets->set_size(w,h);
6069 		// create map
6070 		init(sets,h_field);
6071 		delete [] h_field;
6072 	}
6073 	else {
6074 		dbg->error("karte_t::load_heightfield()","Cant open file '%s'", sets->heightfield.c_str());
6075 		create_win( new news_img("\nCan't open heightfield file.\n"), w_info, magic_none );
6076 	}
6077 }
6078 
6079 
mark_area(const koord3d pos,const koord size,const bool mark) const6080 void karte_t::mark_area( const koord3d pos, const koord size, const bool mark ) const
6081 {
6082 	for( sint16 y=pos.y;  y<pos.y+size.y;  y++  ) {
6083 		for( sint16 x=pos.x;  x<pos.x+size.x;  x++  ) {
6084 			grund_t *gr = lookup( koord3d(x,y,pos.z));
6085 			if (!gr) {
6086 				gr = lookup_kartenboden( x,y );
6087 			}
6088 			if(gr) {
6089 				if(mark) {
6090 					gr->set_flag(grund_t::marked);
6091 				}
6092 				else {
6093 					gr->clear_flag(grund_t::marked);
6094 				}
6095 				gr->set_flag(grund_t::dirty);
6096 			}
6097 		}
6098 	}
6099 }
6100 
6101 
reset_timer()6102 void karte_t::reset_timer()
6103 {
6104 	// Reset timers
6105 	uint32 last_tick_sync = dr_time();
6106 	mouse_rest_time = last_tick_sync;
6107 	sound_wait_time = AMBIENT_SOUND_INTERVALL;
6108 	intr_set_last_time(last_tick_sync);
6109 
6110 	if(  env_t::networkmode  &&  (step_mode&PAUSE_FLAG)==0  ) {
6111 		step_mode = FIX_RATIO;
6112 	}
6113 
6114 	last_step_time = last_interaction = last_tick_sync;
6115 	last_step_ticks = ticks;
6116 
6117 	// reinit simloop counter
6118 	for(  int i=0;  i<32;  i++  ) {
6119 		last_step_nr[i] = steps;
6120 	}
6121 
6122 	if(  step_mode&PAUSE_FLAG  ) {
6123 		intr_disable();
6124 	}
6125 	else if(step_mode==FAST_FORWARD) {
6126 		next_step_time = last_tick_sync+1;
6127 		idle_time = 0;
6128 		set_frame_time( 100 );
6129 		time_multiplier = 16;
6130 		intr_enable();
6131 	}
6132 	else if(step_mode==FIX_RATIO) {
6133 		last_frame_idx = 0;
6134 		fix_ratio_frame_time = 1000 / clamp(settings.get_frames_per_second(), 5, 100);
6135 		next_step_time = last_tick_sync + fix_ratio_frame_time;
6136 		set_frame_time( fix_ratio_frame_time );
6137 		intr_disable();
6138 		// other stuff needed to synchronize
6139 		tile_counter = 0;
6140 		pending_season_change = 1;
6141 		pending_snowline_change = 1;
6142 	}
6143 	else {
6144 		// make timer loop invalid
6145 		for( int i=0;  i<32;  i++ ) {
6146 			last_frame_ms[i] = dr_time();
6147 		}
6148 		last_frame_idx = 0;
6149 		simloops = 60;
6150 
6151 		set_frame_time( 1000/env_t::fps );
6152 		next_step_time = last_tick_sync+(3200/get_time_multiplier() );
6153 		intr_enable();
6154 	}
6155 	DBG_MESSAGE("karte_t::reset_timer()","called, mode=$%X", step_mode);
6156 }
6157 
6158 
reset_interaction()6159 void karte_t::reset_interaction()
6160 {
6161 	last_interaction = dr_time();
6162 }
6163 
6164 
set_map_counter(uint32 new_map_counter)6165 void karte_t::set_map_counter(uint32 new_map_counter)
6166 {
6167 	map_counter = new_map_counter;
6168 	if(  env_t::server  ) {
6169 		nwc_ready_t::append_map_counter(map_counter);
6170 	}
6171 }
6172 
6173 
generate_new_map_counter() const6174 uint32 karte_t::generate_new_map_counter() const
6175 {
6176 	return dr_time();
6177 }
6178 
6179 
6180 // jump one year ahead
6181 // (not updating history!)
step_year()6182 void karte_t::step_year()
6183 {
6184 	DBG_MESSAGE("karte_t::step_year()","called");
6185 	current_month += 12;
6186 	last_year ++;
6187 	reset_timer();
6188 	recalc_average_speed();
6189 	koord::locality_factor = settings.get_locality_factor( last_year );
6190 	FOR(weighted_vector_tpl<stadt_t*>, const i, stadt) {
6191 		i->recalc_target_cities();
6192 		i->recalc_target_attractions();
6193 	}
6194 }
6195 
6196 
6197 // jump one or more months ahead
6198 // (updating history!)
step_month(sint16 months)6199 void karte_t::step_month( sint16 months )
6200 {
6201 	while(  months-->0  ) {
6202 		new_month();
6203 	}
6204 	reset_timer();
6205 }
6206 
6207 
get_time_multiplier() const6208 sint32 karte_t::get_time_multiplier() const
6209 {
6210 	return step_mode==FAST_FORWARD ? env_t::max_acceleration : time_multiplier;
6211 }
6212 
6213 
change_time_multiplier(sint32 delta)6214 void karte_t::change_time_multiplier(sint32 delta)
6215 {
6216 	if(  step_mode == FAST_FORWARD  ) {
6217 		if(  env_t::max_acceleration+delta > 2  ) {
6218 			env_t::max_acceleration += delta;
6219 		}
6220 	}
6221 	else {
6222 		time_multiplier += delta;
6223 		if(time_multiplier<=0) {
6224 			time_multiplier = 1;
6225 		}
6226 		if(step_mode!=NORMAL) {
6227 			step_mode = NORMAL;
6228 			reset_timer();
6229 		}
6230 	}
6231 }
6232 
6233 
set_pause(bool p)6234 void karte_t::set_pause(bool p)
6235 {
6236 	bool pause = step_mode&PAUSE_FLAG;
6237 	if(p!=pause) {
6238 		step_mode ^= PAUSE_FLAG;
6239 		if(p) {
6240 			intr_disable();
6241 		}
6242 		else {
6243 			reset_timer();
6244 		}
6245 	}
6246 }
6247 
6248 
set_fast_forward(bool ff)6249 void karte_t::set_fast_forward(bool ff)
6250 {
6251 	if(  !env_t::networkmode  ) {
6252 		if(  ff  ) {
6253 			if(  step_mode==NORMAL  ) {
6254 				step_mode = FAST_FORWARD;
6255 				reset_timer();
6256 			}
6257 		}
6258 		else {
6259 			if(  step_mode==FAST_FORWARD  ) {
6260 				step_mode = NORMAL;
6261 				reset_timer();
6262 			}
6263 		}
6264 	}
6265 }
6266 
6267 
get_closest_coordinate(koord outside_pos)6268 koord karte_t::get_closest_coordinate(koord outside_pos)
6269 {
6270 	outside_pos.clip_min(koord(0,0));
6271 	outside_pos.clip_max(koord(get_size().x-1,get_size().y-1));
6272 
6273 	return outside_pos;
6274 }
6275 
6276 
6277 /* creates a new player with this type */
init_new_player(uint8 new_player_in,uint8 type)6278 const char *karte_t::init_new_player(uint8 new_player_in, uint8 type)
6279 {
6280 	if(  new_player_in>=PLAYER_UNOWNED  ||  get_player(new_player_in)!=NULL  ) {
6281 		return "Id invalid/already in use!";
6282 	}
6283 	switch( type ) {
6284 		case player_t::EMPTY: break;
6285 		case player_t::HUMAN:        players[new_player_in] = new player_t(new_player_in); break;
6286 		case player_t::AI_GOODS:     players[new_player_in] = new ai_goods_t(new_player_in); break;
6287 		case player_t::AI_PASSENGER: players[new_player_in] = new ai_passenger_t(new_player_in); break;
6288 		case player_t::AI_SCRIPTED:  players[new_player_in] = new ai_scripted_t(new_player_in); break;
6289 		default: return "Unknown AI type!";
6290 	}
6291 	settings.set_player_type(new_player_in, type);
6292 	return NULL;
6293 }
6294 
6295 
remove_player(uint8 player_nr)6296 void karte_t::remove_player(uint8 player_nr)
6297 {
6298 	if ( player_nr!=1  &&  player_nr<PLAYER_UNOWNED  &&  players[player_nr]!=NULL) {
6299 		players[player_nr]->ai_bankrupt();
6300 		delete players[player_nr];
6301 		players[player_nr] = 0;
6302 		nwc_chg_player_t::company_removed(player_nr);
6303 		// if default human, create new instace of it (to avoid crashes)
6304 		if(  player_nr == 0  ) {
6305 			players[0] = new player_t( 0 );
6306 		}
6307 		// if currently still active => reset to default human
6308 		if(  player_nr == active_player_nr  ) {
6309 			active_player_nr = 0;
6310 			active_player = players[0];
6311 			if(  !env_t::server  ) {
6312 				create_win( display_get_width()/2-128, 40, new news_img("Bankrott:\n\nDu bist bankrott.\n"), w_info, magic_none);
6313 			}
6314 		}
6315 	}
6316 }
6317 
6318 
6319 /* goes to next active player */
switch_active_player(uint8 new_player,bool silent)6320 void karte_t::switch_active_player(uint8 new_player, bool silent)
6321 {
6322 	for(  uint8 i=0;  i<MAX_PLAYER_COUNT;  i++  ) {
6323 		if(  players[(i+new_player)%MAX_PLAYER_COUNT] != NULL  ) {
6324 			new_player = (i+new_player)%MAX_PLAYER_COUNT;
6325 			break;
6326 		}
6327 	}
6328 	koord3d old_zeiger_pos = zeiger->get_pos();
6329 
6330 	// no cheating allowed?
6331 	if (!settings.get_allow_player_change() && players[1]->is_locked()) {
6332 		active_player_nr = 0;
6333 		active_player = players[0];
6334 		if(new_player!=0) {
6335 			create_win( new news_img("On this map, you are not\nallowed to change player!\n"), w_time_delete, magic_none);
6336 		}
6337 	}
6338 	else {
6339 		zeiger->change_pos( koord3d::invalid ); // unmark area
6340 		// exit active tool to remove pointers (for two_click_tool_t's, stop mover, factory linker)
6341 		if(selected_tool[active_player_nr]) {
6342 			selected_tool[active_player_nr]->exit(active_player);
6343 		}
6344 		active_player_nr = new_player;
6345 		active_player = players[new_player];
6346 		if(  !silent  ) {
6347 			// tell the player
6348 			cbuffer_t buf;
6349 			buf.printf( translator::translate("Now active as %s.\n"), get_active_player()->get_name() );
6350 			msg->add_message(buf, koord::invalid, message_t::ai | message_t::local_flag, PLAYER_FLAG|get_active_player()->get_player_nr(), IMG_EMPTY);
6351 		}
6352 
6353 		// update menu entries
6354 		tool_t::update_toolbars();
6355 		set_dirty();
6356 	}
6357 
6358 	// update pointer image / area
6359 	selected_tool[active_player_nr]->init_cursor(zeiger);
6360 	// set position / mark area
6361 	zeiger->change_pos( old_zeiger_pos );
6362 }
6363 
6364 
stop(bool exit_game)6365 void karte_t::stop(bool exit_game)
6366 {
6367 	finish_loop = true;
6368 	env_t::quit_simutrans = exit_game;
6369 }
6370 
6371 
network_game_set_pause(bool pause_,uint32 syncsteps_)6372 void karte_t::network_game_set_pause(bool pause_, uint32 syncsteps_)
6373 {
6374 	if (env_t::networkmode) {
6375 		time_multiplier = 16;	// reset to normal speed
6376 		sync_steps = syncsteps_;
6377 		sync_steps_barrier = sync_steps;
6378 		steps = sync_steps / settings.get_frames_per_step();
6379 		network_frame_count = sync_steps % settings.get_frames_per_step();
6380 		dbg->warning("karte_t::network_game_set_pause", "steps=%d sync_steps=%d pause=%d", steps, sync_steps, pause_);
6381 		if (pause_) {
6382 			if (!env_t::server) {
6383 				reset_timer();
6384 				step_mode = PAUSE_FLAG|FIX_RATIO;
6385 			}
6386 			else {
6387 				// TODO
6388 			}
6389 		}
6390 		else {
6391 			step_mode = FIX_RATIO;
6392 			reset_timer();
6393 			if(  !env_t::server  ) {
6394 				// allow server to run ahead the specified number of frames, plus an extra 50%. Better to catch up than be ahead.
6395 				next_step_time = dr_time() + (settings.get_server_frames_ahead() + (uint32)env_t::additional_client_frames_behind) * fix_ratio_frame_time * 3 / 2;
6396 			}
6397 		}
6398 	}
6399 	else {
6400 		set_pause(pause_);
6401 	}
6402 }
6403 
6404 
call_work(tool_t * tool,player_t * player,koord3d pos,bool & suspended)6405 const char* karte_t::call_work(tool_t *tool, player_t *player, koord3d pos, bool &suspended)
6406 {
6407 	const char *err = NULL;
6408 	if (!env_t::networkmode  ||  tool->is_work_network_save()  ||  tool->is_work_here_network_save( player, pos) ) {
6409 		// do the work
6410 		tool->flags |= tool_t::WFL_LOCAL;
6411 		// check allowance by scenario
6412 		if ( (tool->flags & tool_t::WFL_NO_CHK) == 0  &&  get_scenario()->is_scripted()) {
6413 			if (!get_scenario()->is_tool_allowed(player, tool->get_id(), tool->get_waytype()) ) {
6414 				err = "";
6415 			}
6416 			else {
6417 				err = get_scenario()->is_work_allowed_here(player, tool->get_id(), tool->get_waytype(), pos);
6418 			}
6419 		}
6420 		if (err == NULL) {
6421 			err = tool->work(player, pos);
6422 		}
6423 		suspended = false;
6424 	}
6425 	else {
6426 		// queue tool for network
6427 		nwc_tool_t *nwc = new nwc_tool_t(player, tool, pos, get_steps(), get_map_counter(), false);
6428 		network_send_server(nwc);
6429 		suspended = true;
6430 		// reset tool
6431 		tool->init(player);
6432 	}
6433 	return err;
6434 }
6435 
6436 
6437 static slist_tpl<network_world_command_t*> command_queue;
6438 
command_queue_append(network_world_command_t * nwc) const6439 void karte_t::command_queue_append(network_world_command_t* nwc) const
6440 {
6441 	slist_tpl<network_world_command_t*>::iterator i = command_queue.begin();
6442 	slist_tpl<network_world_command_t*>::iterator end = command_queue.end();
6443 	while(i != end  &&  network_world_command_t::cmp(*i, nwc)) {
6444 		++i;
6445 	}
6446 	command_queue.insert(i, nwc);
6447 }
6448 
6449 
clear_command_queue() const6450 void karte_t::clear_command_queue() const
6451 {
6452 	while (!command_queue.empty()) {
6453 		delete command_queue.remove_first();
6454 	}
6455 }
6456 
6457 
encode_URI(cbuffer_t & buf,char const * const text)6458 static void encode_URI(cbuffer_t& buf, char const* const text)
6459 {
6460 	for (char const* i = text; *i != '\0'; ++i) {
6461 		char const c = *i;
6462 		if (('A' <= c && c <= 'Z') ||
6463 				('a' <= c && c <= 'z') ||
6464 				('0' <= c && c <= '9') ||
6465 				c == '-' || c == '.' || c == '_' || c == '~') {
6466 			char const two[] = { c, '\0' };
6467 			buf.append(two);
6468 		} else {
6469 			buf.printf("%%%02X", (unsigned char)c);
6470 		}
6471 	}
6472 }
6473 
6474 
process_network_commands(sint32 * ms_difference)6475 void karte_t::process_network_commands(sint32 *ms_difference)
6476 {
6477 	// did we receive a new command?
6478 	uint32 ms = dr_time();
6479 	sint32 time_to_next_step = (sint32)next_step_time - (sint32)ms;
6480 	network_command_t *nwc = network_check_activity( this, time_to_next_step > 0 ? min( time_to_next_step, 5) : 0 );
6481 	if(  nwc==NULL  &&  !network_check_server_connection()  ) {
6482 		dbg->warning("karte_t::process_network_commands", "lost connection to server");
6483 		network_disconnect();
6484 		return;
6485 	}
6486 
6487 	// process the received command
6488 	while(  nwc  ) {
6489 		// check timing
6490 		uint16 const nwcid = nwc->get_id();
6491 		if(  nwcid == NWC_CHECK  ||  nwcid == NWC_STEP  ) {
6492 			// pull out server sync step
6493 			const uint32 server_sync_step = nwcid == NWC_CHECK ? dynamic_cast<nwc_check_t *>(nwc)->server_sync_step : dynamic_cast<nwc_step_t *>(nwc)->get_sync_step();
6494 
6495 			// are we on time?
6496 			*ms_difference = 0;
6497 			const uint32 timems = dr_time();
6498 			const sint32 time_to_next = (sint32)next_step_time - (sint32)timems; // +'ve - still waiting for next,  -'ve - lagging
6499 			const sint64 frame_timediff = ((sint64)server_sync_step - sync_steps - settings.get_server_frames_ahead() - env_t::additional_client_frames_behind) * fix_ratio_frame_time; // +'ve - server is ahead,  -'ve - client is ahead
6500 			const sint64 timediff = time_to_next + frame_timediff;
6501 			dbg->warning("NWC_CHECK", "time difference to server %lli", frame_timediff );
6502 
6503 			if(  frame_timediff < (0 - (sint64)settings.get_server_frames_ahead() - (sint64)env_t::additional_client_frames_behind) * (sint64)fix_ratio_frame_time / 2  ) {
6504 				// running way ahead - more than half margin, simply set next_step_time ahead to where it should be
6505 				next_step_time = (sint64)timems - frame_timediff;
6506 			}
6507 			else if(  frame_timediff < 0  ) {
6508 				// running ahead
6509 				if(  time_to_next > -frame_timediff  ) {
6510 					// already waiting longer than how far we're ahead, so set wait time shorter to the time ahead.
6511 					next_step_time = (sint64)timems - frame_timediff;
6512 			}
6513 			else if(  nwcid == NWC_CHECK  ) {
6514 					// gentle slowing down
6515 					*ms_difference = timediff;
6516 				}
6517 			}
6518 			else if(  frame_timediff > 0  ) {
6519 				// running behind
6520 				if(  time_to_next > (sint32)fix_ratio_frame_time / 4  ) {
6521 					// behind but we're still waiting for the next step time - get going.
6522 					next_step_time = timems;
6523 					*ms_difference = frame_timediff;
6524 				}
6525 				else if(  nwcid == NWC_CHECK  ) {
6526 					// gentle catching up
6527 					*ms_difference = timediff;
6528 				}
6529 			}
6530 
6531 			if(  sync_steps_barrier < server_sync_step  ) {
6532 				sync_steps_barrier = server_sync_step;
6533 			}
6534 		}
6535 
6536 		// check random number generator states
6537 		if(  env_t::server  &&  nwcid  ==  NWC_TOOL  ) {
6538 			nwc_tool_t *nwt = dynamic_cast<nwc_tool_t *>(nwc);
6539 			if(  nwt->is_from_initiator()  ) {
6540 				if(  nwt->last_sync_step>sync_steps  ) {
6541 					dbg->warning("karte_t::process_network_commands", "client was too fast (skipping command)" );
6542 					delete nwc;
6543 					nwc = NULL;
6544 				}
6545 				// out of sync => drop client (but we can only compare if nwt->last_sync_step is not too old)
6546 				else if(  is_checklist_available(nwt->last_sync_step)  &&  LCHKLST(nwt->last_sync_step)!=nwt->last_checklist  ) {
6547 					// lost synchronisation -> server kicks client out actively
6548 					char buf[256];
6549 					const int offset = LCHKLST(nwt->last_sync_step).print(buf, "server");
6550 					nwt->last_checklist.print(buf + offset, "initiator");
6551 					dbg->warning("karte_t::process_network_commands", "kicking client due to checklist mismatch : sync_step=%u %s", nwt->last_sync_step, buf);
6552 					socket_list_t::remove_client( nwc->get_sender() );
6553 					delete nwc;
6554 					nwc = NULL;
6555 				}
6556 			}
6557 		}
6558 
6559 		// execute command, append to command queue if necessary
6560 		if(nwc  &&  nwc->execute(this)) {
6561 			// network_world_command_t's will be appended to command queue in execute
6562 			// all others have to be deleted here
6563 			delete nwc;
6564 
6565 		}
6566 		// fetch the next command
6567 		nwc = network_get_received_command();
6568 	}
6569 	uint32 next_command_step = get_next_command_step();
6570 
6571 	// send data
6572 	ms = dr_time();
6573 	network_process_send_queues( next_step_time>ms ? min( next_step_time-ms, 5) : 0 );
6574 
6575 	// process enqueued network world commands
6576 	while(  !command_queue.empty()  &&  (next_command_step<=sync_steps/*  ||  step_mode&PAUSE_FLAG*/)  ) {
6577 		network_world_command_t *nwc = command_queue.remove_first();
6578 		if (nwc) {
6579 			do_network_world_command(nwc);
6580 			delete nwc;
6581 		}
6582 		next_command_step = get_next_command_step();
6583 	}
6584 }
6585 
do_network_world_command(network_world_command_t * nwc)6586 void karte_t::do_network_world_command(network_world_command_t *nwc)
6587 {
6588 	// want to execute something in the past?
6589 	if (nwc->get_sync_step() < sync_steps) {
6590 		if (!nwc->ignore_old_events()) {
6591 			dbg->warning("karte_t:::do_network_world_command", "wanted to do_command(%d) in the past", nwc->get_id());
6592 			network_disconnect();
6593 		}
6594 	}
6595 	// check map counter
6596 	else if (nwc->get_map_counter() != map_counter) {
6597 		dbg->warning("karte_t:::do_network_world_command", "wanted to do_command(%d) from another world", nwc->get_id());
6598 	}
6599 	// check random counter?
6600 	else if(  nwc->get_id()==NWC_CHECK  ) {
6601 		nwc_check_t* nwcheck = (nwc_check_t*)nwc;
6602 		// this was the random number at the previous sync step on the server
6603 		const checklist_t &server_checklist = nwcheck->server_checklist;
6604 		const uint32 server_sync_step = nwcheck->server_sync_step;
6605 		char buf[256];
6606 		const int offset = server_checklist.print(buf, "server");
6607 		LCHKLST(server_sync_step).print(buf + offset, "client");
6608 		dbg->warning("karte_t:::do_network_world_command", "sync_step=%u  %s", server_sync_step, buf);
6609 		if(  LCHKLST(server_sync_step)!=server_checklist  ) {
6610 			dbg->warning("karte_t:::do_network_world_command", "disconnecting due to checklist mismatch" );
6611 			network_disconnect();
6612 		}
6613 	}
6614 	else {
6615 		if(  nwc->get_id()==NWC_TOOL  ) {
6616 			nwc_tool_t *nwt = dynamic_cast<nwc_tool_t *>(nwc);
6617 			if(  is_checklist_available(nwt->last_sync_step)  &&  LCHKLST(nwt->last_sync_step)!=nwt->last_checklist  ) {
6618 				// lost synchronisation ...
6619 				char buf[256];
6620 				const int offset = nwt->last_checklist.print(buf, "server");
6621 				LCHKLST(nwt->last_sync_step).print(buf + offset, "executor");
6622 				dbg->warning("karte_t:::do_network_world_command", "skipping command due to checklist mismatch : sync_step=%u %s", nwt->last_sync_step, buf);
6623 				if(  !env_t::server  ) {
6624 					network_disconnect();
6625 				}
6626 				return;
6627 			}
6628 		}
6629 		nwc->do_command(this);
6630 	}
6631 }
6632 
get_next_command_step()6633 uint32 karte_t::get_next_command_step()
6634 {
6635 	// when execute next command?
6636 	if(  !command_queue.empty()  ) {
6637 		return command_queue.front()->get_sync_step();
6638 	}
6639 	else {
6640 		return 0xFFFFFFFFu;
6641 	}
6642 }
6643 
get_sound_id(grund_t * gr)6644 sint16 karte_t::get_sound_id(grund_t *gr)
6645 {
6646 	if(  gr->ist_natur()  ||  gr->is_water()  ) {
6647 		sint16 id = NO_SOUND;
6648 		if(  gr->get_pos().z >= get_snowline()  ) {
6649 			id = sound_desc_t::climate_sounds[ arctic_climate ];
6650 		}
6651 		else {
6652 			id = sound_desc_t::climate_sounds[get_climate( zeiger->get_pos().get_2d() )];
6653 		}
6654 		if (id != NO_SOUND) {
6655 			return id;
6656 		}
6657 		// try, if there is another sound ready
6658 		if(  zeiger->get_pos().z==groundwater  &&  !gr->is_water()  ) {
6659 			return sound_desc_t::beach_sound;
6660 		}
6661 		else if(  gr->get_top()>0  &&  gr->obj_bei(0)->get_typ()==obj_t::baum  ) {
6662 			return sound_desc_t::forest_sound;
6663 		}
6664 	}
6665 	return NO_SOUND;
6666 }
6667 
6668 
interactive(uint32 quit_month)6669 bool karte_t::interactive(uint32 quit_month)
6670 {
6671 
6672 	finish_loop = false;
6673 	sync_steps = 0;
6674 	sync_steps_barrier = sync_steps;
6675 
6676 	network_frame_count = 0;
6677 	vector_tpl<uint16>hashes_ok;	// bit set: this client can do something with this player
6678 
6679 	if(  !scenario->rdwr_ok()  ) {
6680 		// error during loading of savegame of scenario
6681 		create_win( new news_img( scenario->get_error_text() ), w_info, magic_none);
6682 		scenario->stop();
6683 	}
6684 	// only needed for network
6685 	if(  env_t::networkmode  ) {
6686 		// clear the checklist history
6687 		for(  int i=0;  i<LAST_CHECKLISTS_COUNT;  ++i  ) {
6688 			last_checklists[i] = checklist_t();
6689 		}
6690 	}
6691 	sint32 ms_difference = 0;
6692 	reset_timer();
6693 	DBG_DEBUG4("karte_t::interactive", "welcome in this routine");
6694 
6695 	if(  env_t::server  ) {
6696 		step_mode |= FIX_RATIO;
6697 
6698 		reset_timer();
6699 		// Announce server startup to the listing server
6700 		if(  env_t::server_announce  ) {
6701 			announce_server( 0 );
6702 		}
6703 	}
6704 
6705 	DBG_DEBUG4("karte_t::interactive", "start the loop");
6706 	do {
6707 		// check for too much time eaten by frame updates ...
6708 		if(  step_mode==NORMAL  ) {
6709 			DBG_DEBUG4("karte_t::interactive", "decide to play a sound");
6710 			last_interaction = dr_time();
6711 			if(  sound_wait_time < last_interaction - mouse_rest_time ) {
6712 				// we play an ambient sound, if enabled
6713 				grund_t *gr = lookup(zeiger->get_pos());
6714 				if(  gr  ) {
6715 					sint16 id = get_sound_id(gr);
6716 					if(  id!=NO_SOUND  ) {
6717 						sound_play(id);
6718 					}
6719 				}
6720 				sound_wait_time *= 2;
6721 			}
6722 			DBG_DEBUG4("karte_t::interactive", "end of sound");
6723 		}
6724 
6725 		// check events queued since our last iteration
6726 		eventmanager->check_events();
6727 
6728 		if (env_t::quit_simutrans){
6729 			break;
6730 		}
6731 
6732 		if(  env_t::networkmode  ) {
6733 			process_network_commands(&ms_difference);
6734 		}
6735 		else {
6736 			// we wait here for maximum 9ms
6737 			// average is 5 ms, so we usually
6738 			// are quite responsive
6739 			DBG_DEBUG4("karte_t::interactive", "can I get some sleep?");
6740 			INT_CHECK( "karte_t::interactive()" );
6741 			const sint32 wait_time = (sint32)next_step_time - (sint32)dr_time();
6742 			if(wait_time>0) {
6743 				if(  wait_time < 4  ) {
6744 					dr_sleep( wait_time );
6745 				}
6746 				else {
6747 					dr_sleep( 3 );
6748 				}
6749 				INT_CHECK( "karte_t::interactive()" );
6750 			}
6751 			DBG_DEBUG4("karte_t::interactive", "end of sleep");
6752 		}
6753 
6754 		uint32 time = dr_time();
6755 
6756 		// check midi if next songs needs to be started
6757 		if(  (sint32)next_midi_time - (sint32)time <= 0  ) {
6758 			DBG_DEBUG4("karte_t::interactive", "checkmidi");
6759 			check_midi();
6760 			next_midi_time = time + 1500; // check every 1.5 s if we need to start next song
6761 		}
6762 
6763 		// time for the next step?
6764 		if(  (sint32)next_step_time - (sint32)time <= 0  ) {
6765 			if(  step_mode&PAUSE_FLAG  ) {
6766 				// only update display
6767 				sync_step( 0, false, true );
6768 				idle_time = 100;
6769 			}
6770 			else if(  env_t::networkmode  &&  !env_t::server  &&  sync_steps >= sync_steps_barrier  ) {
6771 				sync_step( 0, false, true );
6772 				next_step_time = time + fix_ratio_frame_time;
6773 			}
6774 			else {
6775 				if(  step_mode==FAST_FORWARD  ) {
6776 					sync_step( 100, true, false );
6777 					set_random_mode( STEP_RANDOM );
6778 					step();
6779 					clear_random_mode( STEP_RANDOM );
6780 				}
6781 				else if(  step_mode==FIX_RATIO  ) {
6782 					if(  env_t::server  ) {
6783 						next_step_time += fix_ratio_frame_time;
6784 					}
6785 					else {
6786 						const sint32 lag_time = (sint32)time - (sint32)next_step_time;
6787 						if(  lag_time > 0  ) {
6788 							ms_difference += lag_time;
6789 							next_step_time = time;
6790 						}
6791 
6792 						const sint32 nst_diff = clamp( ms_difference, -fix_ratio_frame_time * 2, fix_ratio_frame_time * 8 ) / 10; // allows timerate between 83% and 500% of normal
6793 						next_step_time += fix_ratio_frame_time - nst_diff;
6794 						ms_difference -= nst_diff;
6795 					}
6796 
6797 					sync_step( (fix_ratio_frame_time*time_multiplier)/16, true, true );
6798 					if (++network_frame_count == settings.get_frames_per_step()) {
6799 						// ever fourth frame
6800 						set_random_mode( STEP_RANDOM );
6801 						step();
6802 						clear_random_mode( STEP_RANDOM );
6803 						network_frame_count = 0;
6804 					}
6805 					sync_steps = steps * settings.get_frames_per_step() + network_frame_count;
6806 					LCHKLST(sync_steps) = checklist_t(get_random_seed(), halthandle_t::get_next_check(), linehandle_t::get_next_check(), convoihandle_t::get_next_check());
6807 					// some server side tasks
6808 					if(  env_t::networkmode  &&  env_t::server  ) {
6809 						// broadcast sync info regularly and when lagged
6810 						const sint64 timelag = (sint32)dr_time() - (sint32)next_step_time;
6811 						if(  (network_frame_count == 0  &&  timelag > fix_ratio_frame_time * settings.get_server_frames_ahead() / 2)  ||  (sync_steps % env_t::server_sync_steps_between_checks) == 0  ) {
6812 							if(  timelag > fix_ratio_frame_time * settings.get_frames_per_step()  ) {
6813 								// log when server is lagged more than one step
6814 								dbg->warning("karte_t::interactive", "server lagging by %lli", timelag );
6815 							}
6816 
6817 							nwc_check_t* nwc = new nwc_check_t(sync_steps + 1, map_counter, LCHKLST(sync_steps), sync_steps);
6818 							network_send_all(nwc, true);
6819 						}
6820 						else {
6821 							// broadcast sync_step
6822 							nwc_step_t* nwcstep = new nwc_step_t(sync_steps, map_counter);
6823 							network_send_all(nwcstep, true);
6824 						}
6825 					}
6826 #if DEBUG>4
6827 					if(  env_t::networkmode  &&  (sync_steps & 7)==0  &&  env_t::verbose_debug>4  ) {
6828 						dbg->message("karte_t::interactive", "time=%lu sync=%d  rand=%d", dr_time(), sync_steps, LRAND(sync_steps));
6829 					}
6830 #endif
6831 
6832 					// no clients -> pause game
6833 					if (  env_t::networkmode  &&  env_t::pause_server_no_clients  &&  socket_list_t::get_playing_clients() == 0  &&  !nwc_join_t::is_pending()  ) {
6834 						set_pause(true);
6835 					}
6836 				}
6837 				else {
6838 					INT_CHECK( "karte_t::interactive()" );
6839 					set_random_mode( STEP_RANDOM );
6840 					step();
6841 					clear_random_mode( STEP_RANDOM );
6842 					idle_time = ((idle_time*7) + next_step_time - dr_time())/8;
6843 					INT_CHECK( "karte_t::interactive()" );
6844 				}
6845 			}
6846 		}
6847 
6848 		// Interval-based server announcements
6849 		if (  env_t::server  &&  env_t::server_announce  &&  env_t::server_announce_interval > 0  &&
6850 			dr_time() - server_last_announce_time >= (uint32)env_t::server_announce_interval * 1000  ) {
6851 			announce_server( 1 );
6852 		}
6853 
6854 		DBG_DEBUG4("karte_t::interactive", "point of loop return");
6855 	} while(!finish_loop  &&  get_current_month()<quit_month);
6856 
6857 	if(  get_current_month() >= quit_month  ) {
6858 		env_t::quit_simutrans = true;
6859 	}
6860 
6861 	// On quit announce server as being offline
6862 	if(  env_t::server  &&  env_t::server_announce  ) {
6863 		announce_server( 2 );
6864 	}
6865 
6866 	intr_enable();
6867 	display_show_pointer(true);
6868 	return finish_loop;
6869 #undef LRAND
6870 }
6871 
6872 
6873 // Announce server to central listing server
6874 // Status is one of:
6875 // 0 - startup
6876 // 1 - interval
6877 // 2 - shutdown
announce_server(int status)6878 void karte_t::announce_server(int status)
6879 {
6880 	DBG_DEBUG( "announce_server()", "status: %i",  status );
6881 	// Announce game info to server, format is:
6882 	// st=on&dns=server.com&port=13353&rev=1234&pak=pak128&name=some+name&time=3,1923&size=256,256&active=[0-16]&locked=[0-16]&clients=[0-16]&towns=15&citizens=3245&factories=33&convoys=56&stops=17
6883 	// (This is the data part of an HTTP POST)
6884 	if(  env_t::server  &&  env_t::server_announce  ) {
6885 		// in easy_server mode, we assume the IP may change frequently and thus query it before each announce
6886 		cbuffer_t buf, altbuf;
6887 		if(  env_t::easy_server  &&  status<2  &&  get_external_IP(buf,altbuf)  ) {
6888 			// ipdate IP just in case
6889 			if(  status == 1  &&  (env_t::server_dns.compare( buf )  ||  env_t::server_alt_dns.compare( altbuf ))  ) {
6890 				announce_server( 2 );
6891 				status = 0; // since starting with new IP
6892 				// if we had uPnP, we may need to drill another hole in the firewall again; the delay is no problem, since all clients will be lost anyway
6893 				char IP[256], altIP[256];
6894 				prepare_for_server( IP, altIP, env_t::server_port );
6895 			}
6896 			// now update DNS info
6897 			env_t::server_dns = (const char *)buf;
6898 			env_t::server_alt_dns = (const char *)altbuf;
6899 		}
6900 		// Always send dns and port as these are used as the unique identifier for the server
6901 		buf.clear();
6902 		buf.append( "&dns=" );
6903 		encode_URI( buf, env_t::server_dns.c_str() );
6904 		buf.append( "&alt_dns=" );
6905 		encode_URI( buf, env_t::server_alt_dns.c_str() );
6906 		buf.printf( "&port=%u", env_t::server );
6907 		// Always send announce interval to allow listing server to predict next announce
6908 		buf.printf( "&aiv=%u", env_t::server_announce_interval );
6909 		// Always send status, either online or offline
6910 		if (  status == 0  ||  status == 1  ) {
6911 			buf.append( "&st=1" );
6912 		}
6913 		else {
6914 			buf.append( "&st=0" );
6915 		}
6916 #ifndef REVISION
6917 #	define REVISION 0
6918 #endif
6919 		// Simple revision used for matching (integer)
6920 		buf.printf( "&rev=%d", atol( QUOTEME(REVISION) ) );
6921 		// Complex version string used for display
6922 		buf.printf( "&ver=Simutrans %s (r%s) built %s", QUOTEME(VERSION_NUMBER), QUOTEME(REVISION), QUOTEME(VERSION_DATE) );
6923 		// Pakset version
6924 		buf.append( "&pak=" );
6925 		// Announce pak set, ideally get this from the copyright field of ground.Outside.pak
6926 		char const* const copyright = ground_desc_t::outside->get_copyright();
6927 		if (copyright && STRICMP("none", copyright) != 0) {
6928 			// construct from outside object copyright string
6929 			encode_URI( buf, copyright );
6930 		}
6931 		else {
6932 			// construct from pak name
6933 			std::string pak_name = env_t::objfilename;
6934 			pak_name.erase( pak_name.length() - 1 );
6935 			encode_URI( buf, pak_name.c_str() );
6936 		}
6937 		// TODO - change this to be the start date of the current map
6938 		buf.printf( "&start=%u,%u", settings.get_starting_month() + 1, settings.get_starting_year() );
6939 		// Add server name for listing
6940 		buf.append( "&name=" );
6941 		encode_URI( buf, env_t::server_name.c_str() );
6942 		// Add server comments for listing
6943 		buf.append( "&comments=" );
6944 		encode_URI( buf, env_t::server_comments.c_str() );
6945 		// Add server maintainer email for listing
6946 		buf.append( "&email=" );
6947 		encode_URI( buf, env_t::server_email.c_str() );
6948 		// Add server pakset URL for listing
6949 		buf.append( "&pakurl=" );
6950 		encode_URI( buf, env_t::server_pakurl.c_str() );
6951 		// Add server info URL for listing
6952 		buf.append( "&infurl=" );
6953 		encode_URI( buf, env_t::server_infurl.c_str() );
6954 
6955 		// Now add the game data part
6956 		uint8 active = 0, locked = 0;
6957 		for(  uint8 i=0;  i<MAX_PLAYER_COUNT;  i++  ) {
6958 			if(  players[i]  &&  players[i]->get_ai_id()!=player_t::EMPTY  ) {
6959 				active ++;
6960 				if(  players[i]->is_locked()  ) {
6961 					locked ++;
6962 				}
6963 			}
6964 		}
6965 		buf.printf( "&time=%u,%u",   (get_current_month() % 12) + 1, get_current_month() / 12 );
6966 		buf.printf( "&size=%u,%u",   get_size().x, get_size().y );
6967 		buf.printf( "&active=%u",    active );
6968 		buf.printf( "&locked=%u",    locked );
6969 		buf.printf( "&clients=%u",   socket_list_t::get_playing_clients() );
6970 		buf.printf( "&towns=%u",     stadt.get_count() );
6971 		buf.printf( "&citizens=%u",  stadt.get_sum_weight() );
6972 		buf.printf( "&factories=%u", fab_list.get_count() );
6973 		buf.printf( "&convoys=%u",   convoys().get_count());
6974 		buf.printf( "&stops=%u",     haltestelle_t::get_alle_haltestellen().get_count() );
6975 
6976 		network_http_post( ANNOUNCE_SERVER, ANNOUNCE_URL, buf, NULL );
6977 
6978 		// Record time of this announce
6979 		server_last_announce_time = dr_time();
6980 	}
6981 }
6982 
6983 
network_disconnect()6984 void karte_t::network_disconnect()
6985 {
6986 	// force disconnect
6987 	dbg->warning("karte_t::network_disconnect()", "Lost synchronisation with server.");
6988 	network_core_shutdown();
6989 	destroy_all_win(true);
6990 
6991 	clear_random_mode( INTERACTIVE_RANDOM );
6992 	step_mode = NORMAL;
6993 	reset_timer();
6994 	clear_command_queue();
6995 	create_win( display_get_width()/2-128, 40, new news_img("Lost synchronisation\nwith server."), w_info, magic_none);
6996 	ticker::add_msg( translator::translate("Lost synchronisation\nwith server."), koord::invalid, color_idx_to_rgb(COL_BLACK) );
6997 	last_active_player_nr = active_player_nr;
6998 
6999 	stop(false);
7000 }
7001 
7002 
sort_ware_by_name(const goods_desc_t * a,const goods_desc_t * b)7003 static bool sort_ware_by_name(const goods_desc_t* a, const goods_desc_t* b)
7004 {
7005 	int diff = strcmp(translator::translate(a->get_name()), translator::translate(b->get_name()));
7006 	return diff < 0;
7007 }
7008 
7009 
7010 // Returns a list of goods produced by factories that exist in current game
get_goods_list()7011 const vector_tpl<const goods_desc_t*> &karte_t::get_goods_list()
7012 {
7013 	if (goods_in_game.empty()) {
7014 		// Goods list needs to be rebuilt
7015 
7016 		// Reset last vehicle filter in all depots, in case goods list has changed
7017 		FOR(slist_tpl<depot_t*>, const d, depot_t::get_depot_list()) {
7018 			d->selected_filter = VEHICLE_FILTER_RELEVANT;
7019 		}
7020 
7021 		FOR(slist_tpl<fabrik_t*>, const factory, get_fab_list()) {
7022 			slist_tpl<goods_desc_t const*>* const produced_goods = factory->get_produced_goods();
7023 			FOR(slist_tpl<goods_desc_t const*>, const good, *produced_goods) {
7024 				goods_in_game.insert_unique_ordered(good, sort_ware_by_name);
7025 			}
7026 			delete produced_goods;
7027 		}
7028 		goods_in_game.insert_at(0, goods_manager_t::passengers);
7029 		goods_in_game.insert_at(1, goods_manager_t::mail);
7030 	}
7031 
7032 	return goods_in_game;
7033 }
7034 
get_public_player() const7035 player_t *karte_t::get_public_player() const
7036 {
7037 	return get_player(1);
7038 }
7039