1 /*
2 * Game settings
3 *
4 * Hj. Malthaner
5 *
6 * April 2000
7 */
8
9 #include <string>
10 #include <math.h>
11
12 #include "settings.h"
13 #include "environment.h"
14 #include "../simconst.h"
15 #include "../simtypes.h"
16 #include "../simdebug.h"
17 #include "../simworld.h"
18 #include "../bauer/wegbauer.h"
19 #include "../descriptor/way_desc.h"
20 #include "../utils/simrandom.h"
21 #include "../utils/simstring.h"
22 #include "../vehicle/simvehicle.h"
23 #include "../player/simplay.h"
24 #include "loadsave.h"
25 #include "tabfile.h"
26 #include "translator.h"
27
28 #include "../tpl/minivec_tpl.h"
29
30
31 #define NEVER 0xFFFFU
32
33
settings_t()34 settings_t::settings_t() :
35 filename(""),
36 heightfield("")
37 {
38 size_x = 256;
39 size_y = 256;
40
41 map_number = 33;
42
43 /* new setting since version 0.85.01
44 * @author prissi
45 */
46 factory_count = 12;
47 tourist_attractions = 16;
48
49 city_count = 16;
50 mean_citizen_count = 1600;
51
52 station_coverage_size = 2;
53
54 traffic_level = 5;
55
56 show_pax = true;
57
58 // default maximum length of convoi
59 max_rail_convoi_length = 24;
60 max_road_convoi_length = 4;
61 max_ship_convoi_length = 4;
62 max_air_convoi_length = 1;
63
64 world_maximum_height = 32;
65 world_minimum_height = -12;
66
67 // default climate zones
68 set_default_climates( );
69 winter_snowline = 7; // not mediterranean
70 groundwater = -2; //25-Nov-01 Markus Weber Added
71
72 max_mountain_height = 160; //can be 0-160.0 01-Dec-01 Markus Weber Added
73 map_roughness = 0.6; //can be 0-1 01-Dec-01 Markus Weber Added
74
75 river_number = 16;
76 min_river_length = 16;
77 max_river_length = 256;
78
79 // since the turning rules are different, driving must now be saved here
80 drive_on_left = false;
81 signals_on_left = false;
82
83 // forest setting ...
84 forest_base_size = 36; // Base forest size - minimal size of forest - map independent
85 forest_map_size_divisor = 38; // Map size divisor - smaller it is the larger are individual forests
86 forest_count_divisor = 16; // Forest count divisor - smaller it is, the more forest are generated
87 forest_inverse_spare_tree_density = 5; // Determines how often are spare trees going to be planted (works inversely)
88 max_no_of_trees_on_square = 3; // Number of trees on square 2 - minimal usable, 3 good, 5 very nice looking
89 tree_climates = 0; // bit set, if this climate is to be covered with trees entirely
90 no_tree_climates = 0; // bit set, if this climate is to be void of random trees
91 no_trees = false; // if set, no trees at all, may be useful for low end engines
92
93 lake = true; // if set lakes will be added to map
94
95 // some settings more
96 allow_player_change = true;
97 use_timeline = 2;
98 starting_year = 1930;
99 starting_month = 0;
100 bits_per_month = 20;
101
102 beginner_mode = false;
103 beginner_price_factor = 1500;
104
105 rotation = 0;
106
107 origin_x = origin_y = 0;
108
109 // passenger manipulation factor (=16 about old value)
110 passenger_factor = 16;
111
112 // town growth factors
113 passenger_multiplier = 40;
114 mail_multiplier = 20;
115 goods_multiplier = 20;
116 electricity_multiplier = 0;
117
118 // Also there are size dependent factors (0 causes crash !)
119 growthfactor_small = 400;
120 growthfactor_medium = 200;
121 growthfactor_large = 100;
122
123 minimum_city_distance = 16;
124 industry_increase = 2000;
125
126 special_building_distance = 3;
127
128 factory_worker_percentage = 33;
129 tourist_percentage = 16;
130 for( int i=0; i<10; i++ ) {
131 locality_factor_per_year[i].year = 0;
132 locality_factor_per_year[i].factor = 0;
133 }
134 locality_factor_per_year[0].factor = 100;
135
136 factory_worker_radius = 77;
137 // try to have at least a single town connected to a factory
138 factory_worker_minimum_towns = 1;
139 // not more than four towns should supply to a factory
140 factory_worker_maximum_towns = 4;
141
142 factory_arrival_periods = 4;
143
144 factory_enforce_demand = true;
145
146 factory_maximum_intransit_percentage = 0;
147
148 electric_promille = 330;
149
150 #ifdef OTTD_LIKE
151 /* prissi: crossconnect all factories (like OTTD and similar games) */
152 crossconnect_factories=true;
153 crossconnect_factor=100;
154 #else
155 /* prissi: crossconnect a certain number */
156 crossconnect_factories=false;
157 crossconnect_factor=33;
158 #endif
159
160 /* minimum spacing between two factories */
161 min_factory_spacing = 6;
162 max_factory_spacing = 40;
163 max_factory_spacing_percentage = 0; // off
164
165 just_in_time = env_t::just_in_time;
166
167 random_pedestrians = true;
168 stadtauto_duration = 36; // three years
169
170 // to keep names consistent
171 numbered_stations = false;
172
173 num_city_roads = 0;
174 num_intercity_roads = 0;
175
176 max_route_steps = 1000000;
177 max_choose_route_steps = 200;
178 max_transfers = 9;
179 max_hops = 2000;
180 no_routing_over_overcrowding = false;
181
182 bonus_basefactor = 125;
183
184 /* multiplier for steps on diagonal:
185 * 1024: TT-like, factor 2, vehicle will be too long and too fast
186 * 724: correct one, factor sqrt(2)
187 */
188 pak_diagonal_multiplier = 724;
189
190 // read default from env_t
191 // should be set in simmain.cc (taken from pak-set simuconf.tab
192 way_height_clearance = env_t::default_settings.get_way_height_clearance();
193 if (way_height_clearance < 0 || way_height_clearance >2) {
194 // if outside bounds, then set to default = 1
195 way_height_clearance = 1;
196 }
197
198 strcpy( language_code_names, "en" );
199
200 // default AIs active
201 for( int i=0; i<MAX_PLAYER_COUNT; i++ ) {
202 if( i<2 ) {
203 player_active[i] = true;
204 player_type[i] = player_t::HUMAN;
205 }
206 else if( i==3 ) {
207 player_active[i] = true;
208 player_type[i] = player_t::AI_PASSENGER;
209 }
210 else if( i==6 ) {
211 player_active[i] = true;
212 player_type[i] = player_t::AI_GOODS;
213 }
214 else {
215 player_active[i] = false;
216 player_type[i] = player_t::EMPTY;
217 }
218 // undefined colors
219 default_player_color[i][0] = 255;
220 default_player_color[i][1] = 255;
221 }
222 default_player_color_random = false;
223 default_ai_construction_speed = env_t::default_ai_construction_speed;
224
225 /* the big cost section */
226 freeplay = false;
227 starting_money = 20000000;
228 for( int i=0; i<10; i++ ) {
229 startingmoneyperyear[i].year = 0;
230 startingmoneyperyear[i].money = 0;
231 startingmoneyperyear[i].interpol = 0;
232 }
233
234 // six month time frame for starting first convoi
235 remove_dummy_player_months = 6;
236
237 // off
238 unprotect_abandoned_player_months = 0;
239
240 maint_building = 5000; // normal buildings
241 way_toll_runningcost_percentage = 0;
242 way_toll_waycost_percentage = 0;
243
244 allow_underground_transformers = true;
245 disable_make_way_public = false;
246
247 // stop buildings
248 cst_multiply_dock=-50000;
249 cst_multiply_station=-60000;
250 cst_multiply_roadstop=-40000;
251 cst_multiply_airterminal=-300000;
252 cst_multiply_post=-30000;
253 cst_multiply_headquarter=-100000;
254 cst_depot_rail=-100000;
255 cst_depot_road=-130000;
256 cst_depot_ship=-250000;
257 cst_depot_air=-500000;
258 allow_merge_distant_halt = 2;
259 cst_multiply_merge_halt=-50000;
260 // alter landscape
261 cst_buy_land=-10000;
262 cst_alter_land=-100000;
263 cst_alter_climate=-100000;
264 cst_set_slope=-250000;
265 cst_found_city=-500000000;
266 cst_multiply_found_industry=-2000000;
267 cst_remove_tree=-10000;
268 cst_multiply_remove_haus=-100000;
269 cst_multiply_remove_field=-500000;
270 // cost for transformers
271 cst_transformer=-250000;
272 cst_maintain_transformer=-2000;
273
274 cst_make_public_months = 60;
275
276 // costs for the way searcher
277 way_count_straight=1;
278 way_count_curve=2;
279 way_count_double_curve=6;
280 way_count_90_curve=15;
281 way_count_slope=10;
282 way_count_tunnel=8;
283 way_max_bridge_len=15;
284 way_count_leaving_road=25;
285
286 // default: joined capacities
287 separate_halt_capacities = false;
288
289 // this will pay for distance to next change station
290 pay_for_total_distance = TO_PREVIOUS;
291
292 avoid_overcrowding = false;
293
294 allow_buying_obsolete_vehicles = true;
295
296 // default: load also private extensions of the pak file
297 with_private_paks = true;
298
299 used_vehicle_reduction = 0;
300
301 // some network thing to keep client in sync
302 random_counter = 0; // will be set when actually saving
303 frames_per_second = 20;
304 frames_per_step = 4;
305 server_frames_ahead = 4;
306 }
307
308
309
set_default_climates()310 void settings_t::set_default_climates()
311 {
312 static sint16 borders[MAX_CLIMATES] = { 0, -3, -2, 3, 6, 8, 10, 10 };
313 memcpy( climate_borders, borders, sizeof(sint16)*MAX_CLIMATES );
314 }
315
316
317
rdwr(loadsave_t * file)318 void settings_t::rdwr(loadsave_t *file)
319 {
320 // used to be called einstellungen_t - keep old name during save/load for compatibility
321 xml_tag_t e( file, "einstellungen_t" );
322
323 if(file->is_version_less(86, 0)) {
324 uint32 dummy;
325
326 file->rdwr_long(size_x );
327 size_y = size_x;
328
329 file->rdwr_long(map_number );
330
331 // to be compatible with previous savegames
332 dummy = 0;
333 file->rdwr_long(dummy ); //dummy!
334 factory_count = 12;
335 tourist_attractions = 12;
336
337 // now towns
338 mean_citizen_count = 1600;
339 dummy = city_count;
340 file->rdwr_long(dummy );
341 dummy &= 127;
342 if(dummy>63) {
343 dbg->warning("settings_t::rdwr()", "This game was saved with too many cities! (%i of maximum 63). Simutrans may crash!", dummy);
344 }
345 city_count = dummy;
346
347 // rest
348 file->rdwr_long(dummy ); // scroll ignored
349 file->rdwr_long(traffic_level );
350 file->rdwr_long(show_pax );
351 dummy = groundwater;
352 file->rdwr_long(dummy );
353 groundwater = (sint16)(dummy/16);
354 file->rdwr_double(max_mountain_height );
355 file->rdwr_double(map_roughness );
356
357 station_coverage_size = 3;
358 beginner_mode = false;
359 rotation = 0;
360 }
361 else {
362 // newer versions
363 file->rdwr_long(size_x );
364 file->rdwr_long(map_number );
365
366 // industries
367 file->rdwr_long(factory_count );
368 if(file->is_version_less(99, 18)) {
369 uint32 dummy; // was city chains
370 file->rdwr_long(dummy );
371 }
372 else {
373 file->rdwr_long( electric_promille );
374 }
375 file->rdwr_long(tourist_attractions );
376
377 // now towns
378 file->rdwr_long(mean_citizen_count );
379 file->rdwr_long(city_count );
380
381 // rest
382 if(file->is_version_less(101, 0)) {
383 uint32 dummy; // was scroll dir
384 file->rdwr_long(dummy );
385 }
386 file->rdwr_long(traffic_level );
387 file->rdwr_long(show_pax );
388 sint32 dummy = groundwater;
389 file->rdwr_long(dummy );
390 if(file->is_version_less(99, 5)) {
391 groundwater = (sint16)(dummy/16);
392 }
393 else {
394 groundwater = (sint16)dummy;
395 }
396 file->rdwr_double(max_mountain_height );
397 file->rdwr_double(map_roughness );
398
399 if(file->is_version_atleast(86, 3)) {
400 dummy = station_coverage_size;
401 file->rdwr_long(dummy );
402 station_coverage_size = (uint16)dummy;
403 }
404
405 if(file->is_version_atleast(86, 6)) {
406 // handle also size on y direction
407 file->rdwr_long(size_y );
408 }
409 else {
410 size_y = size_x;
411 }
412
413 if(file->is_version_atleast(86, 11)) {
414 // some more settings
415 file->rdwr_byte(allow_player_change );
416 file->rdwr_byte(use_timeline );
417 file->rdwr_short(starting_year );
418 }
419 else {
420 allow_player_change = 1;
421 use_timeline = 1;
422 starting_year = 1930;
423 }
424
425 if(file->is_version_atleast(88, 5)) {
426 file->rdwr_short(bits_per_month );
427 }
428 else {
429 bits_per_month = 18;
430 }
431
432 if(file->is_version_atleast(89, 3)) {
433 file->rdwr_bool(beginner_mode );
434 }
435 else {
436 beginner_mode = false;
437 }
438 if( file->is_version_atleast(120, 1) ){
439 file->rdwr_byte( just_in_time );
440 }
441 else if( file->is_version_atleast(89, 4) ) {
442 bool compat = just_in_time > 0;
443 file->rdwr_bool( compat );
444 just_in_time = 0;
445 if( compat ) {
446 just_in_time = env_t::just_in_time ? env_t::just_in_time : 1;
447 }
448 }
449 // rotation of the map with respect to the original value
450 if(file->is_version_atleast(99, 15)) {
451 file->rdwr_byte(rotation );
452 }
453 else {
454 rotation = 0;
455 }
456
457 // clear the name when loading ...
458 if(file->is_loading()) {
459 filename = "";
460 }
461
462 // climate borders
463 if(file->is_version_atleast(91, 0)) {
464 if( file->is_version_less(120, 6) ) {
465 climate_borders[arctic_climate] -= groundwater;
466 }
467 for( int i=0; i<8; i++ ) {
468 file->rdwr_short(climate_borders[i] );
469 }
470 if( file->is_version_less(120, 6) ) {
471 climate_borders[arctic_climate] += groundwater;
472 }
473 file->rdwr_short(winter_snowline );
474 }
475
476 if( file->is_loading() && file->is_version_less(112, 7) ) {
477 groundwater *= env_t::pak_height_conversion_factor;
478 for( int i = 0; i < 8; i++ ) {
479 climate_borders[i] *= env_t::pak_height_conversion_factor;
480 }
481 winter_snowline *= env_t::pak_height_conversion_factor;
482 way_height_clearance = env_t::pak_height_conversion_factor;
483 }
484
485 // since vehicle will need realignment afterwards!
486 if(file->is_version_less(99, 19)) {
487 vehicle_base_t::set_diagonal_multiplier( pak_diagonal_multiplier, 1024 );
488 }
489 else {
490 uint16 old_multiplier = pak_diagonal_multiplier;
491 file->rdwr_short( old_multiplier );
492 vehicle_base_t::set_diagonal_multiplier( pak_diagonal_multiplier, old_multiplier );
493 // since vehicle will need realignment afterwards!
494 }
495
496 if(file->is_version_atleast(101, 0)) {
497 // game mechanics
498 file->rdwr_short(origin_x );
499 file->rdwr_short(origin_y );
500
501 file->rdwr_long(passenger_factor );
502
503 // town grow stuff
504 if(file->is_version_atleast(102, 2)) {
505 file->rdwr_long(passenger_multiplier );
506 file->rdwr_long(mail_multiplier );
507 file->rdwr_long(goods_multiplier );
508 file->rdwr_long(electricity_multiplier );
509 file->rdwr_long(growthfactor_small );
510 file->rdwr_long(growthfactor_medium );
511 file->rdwr_long(growthfactor_large );
512 file->rdwr_short(factory_worker_percentage );
513 file->rdwr_short(tourist_percentage );
514 file->rdwr_short(factory_worker_radius );
515 }
516
517 file->rdwr_long(electric_promille );
518
519 file->rdwr_short(min_factory_spacing );
520 file->rdwr_bool(crossconnect_factories );
521 file->rdwr_short(crossconnect_factor );
522
523 file->rdwr_bool(random_pedestrians );
524 file->rdwr_long(stadtauto_duration );
525
526 file->rdwr_bool(numbered_stations );
527 if( file->is_version_less(102, 3) ) {
528 if( file->is_loading() ) {
529 num_city_roads = 1;
530 city_roads[0].intro = 0;
531 city_roads[0].retire = 0;
532 // intercity roads were not saved in old savegames
533 num_intercity_roads = 0;
534 }
535 file->rdwr_str(city_roads[0].name, lengthof(city_roads[0].name) );
536 }
537 else {
538 // several roads ...
539 file->rdwr_short(num_city_roads );
540 if( num_city_roads>=10 ) {
541 dbg->fatal("settings_t::rdwr()", "Too many (%i) city roads!", num_city_roads);
542 }
543 for( int i=0; i<num_city_roads; i++ ) {
544 file->rdwr_str(city_roads[i].name, lengthof(city_roads[i].name) );
545 file->rdwr_short(city_roads[i].intro );
546 file->rdwr_short(city_roads[i].retire );
547 }
548 // several intercity roads ...
549 file->rdwr_short(num_intercity_roads );
550 if( num_intercity_roads>=10 ) {
551 dbg->fatal("settings_t::rdwr()", "Too many (%i) intercity roads!", num_intercity_roads);
552 }
553 for( int i=0; i<num_intercity_roads; i++ ) {
554 file->rdwr_str(intercity_roads[i].name, lengthof(intercity_roads[i].name) );
555 file->rdwr_short(intercity_roads[i].intro );
556 file->rdwr_short(intercity_roads[i].retire );
557 }
558 }
559 file->rdwr_long(max_route_steps );
560 file->rdwr_long(max_transfers );
561 file->rdwr_long(max_hops );
562
563 file->rdwr_long(beginner_price_factor );
564
565 // name of stops
566 file->rdwr_str(language_code_names, lengthof(language_code_names) );
567
568 // restore AI state
569 for( int i=0; i<15; i++ ) {
570 file->rdwr_bool(player_active[i] );
571 file->rdwr_byte(player_type[i] );
572 if( file->is_version_less(102, 3) ) {
573 char dummy[2] = { 0, 0 };
574 file->rdwr_str(dummy, lengthof(dummy) );
575 }
576 }
577
578 // cost section ...
579 file->rdwr_bool(freeplay );
580 if( file->is_version_atleast(102, 3) ) {
581 file->rdwr_longlong(starting_money );
582 // these must be saved, since new player will get different amounts eventually
583 for( int i=0; i<10; i++ ) {
584 file->rdwr_short(startingmoneyperyear[i].year );
585 file->rdwr_longlong(startingmoneyperyear[i].money );
586 file->rdwr_bool(startingmoneyperyear[i].interpol );
587 }
588 }
589 else {
590 // compatibility code
591 sint64 save_starting_money = starting_money;
592 if( file->is_saving() ) {
593 if(save_starting_money==0) {
594 save_starting_money = get_starting_money(starting_year );
595 }
596 if(save_starting_money==0) {
597 save_starting_money = env_t::default_settings.get_starting_money(starting_year );
598 }
599 if(save_starting_money==0) {
600 save_starting_money = 20000000;
601 }
602 }
603 file->rdwr_longlong(save_starting_money );
604 if(file->is_loading()) {
605 if(save_starting_money==0) {
606 save_starting_money = env_t::default_settings.get_starting_money(starting_year );
607 }
608 if(save_starting_money==0) {
609 save_starting_money = 20000000;
610 }
611 starting_money = save_starting_money;
612 }
613 }
614 file->rdwr_long(maint_building );
615
616 file->rdwr_longlong(cst_multiply_dock );
617 file->rdwr_longlong(cst_multiply_station );
618 file->rdwr_longlong(cst_multiply_roadstop );
619 file->rdwr_longlong(cst_multiply_airterminal );
620 file->rdwr_longlong(cst_multiply_post );
621 file->rdwr_longlong(cst_multiply_headquarter );
622 file->rdwr_longlong(cst_depot_rail );
623 file->rdwr_longlong(cst_depot_road );
624 file->rdwr_longlong(cst_depot_ship );
625 file->rdwr_longlong(cst_depot_air );
626 if( file->is_version_less(102, 2) ) {
627 sint64 dummy64 = 100000;
628 file->rdwr_longlong(dummy64 );
629 file->rdwr_longlong(dummy64 );
630 file->rdwr_longlong(dummy64 );
631 }
632 // alter landscape
633 file->rdwr_longlong(cst_buy_land );
634 file->rdwr_longlong(cst_alter_land );
635 file->rdwr_longlong(cst_set_slope );
636 file->rdwr_longlong(cst_found_city );
637 file->rdwr_longlong(cst_multiply_found_industry );
638 file->rdwr_longlong(cst_remove_tree );
639 file->rdwr_longlong(cst_multiply_remove_haus );
640 file->rdwr_longlong(cst_multiply_remove_field );
641 // cost for transformers
642 file->rdwr_longlong(cst_transformer );
643 file->rdwr_longlong(cst_maintain_transformer );
644
645 if( file->is_version_atleast(120, 3) ) {
646 file->rdwr_longlong(cst_make_public_months);
647 }
648
649 if( file->is_version_atleast(120, 9) ) {
650 file->rdwr_longlong(cst_multiply_merge_halt);
651 }
652
653 // wayfinder
654 file->rdwr_long(way_count_straight );
655 file->rdwr_long(way_count_curve );
656 file->rdwr_long(way_count_double_curve );
657 file->rdwr_long(way_count_90_curve );
658 file->rdwr_long(way_count_slope );
659 file->rdwr_long(way_count_tunnel );
660 file->rdwr_long(way_max_bridge_len );
661 file->rdwr_long(way_count_leaving_road );
662 }
663 else {
664 // name of stops
665 set_name_language_iso( env_t::language_iso );
666
667 // default AIs active
668 for( int i=0; i<MAX_PLAYER_COUNT; i++ ) {
669 if( i<2 ) {
670 player_type[i] = player_t::HUMAN;
671 }
672 else if( i==3 ) {
673 player_type[i] = player_t::AI_PASSENGER;
674 }
675 else if( i<8 ) {
676 player_type[i] = player_t::AI_GOODS;
677 }
678 else {
679 player_type[i] = player_t::EMPTY;
680 }
681 player_active[i] = false;
682 }
683 }
684
685 if(file->is_version_atleast(101, 1)) {
686 file->rdwr_bool( separate_halt_capacities );
687 file->rdwr_byte( pay_for_total_distance );
688
689 file->rdwr_short(starting_month );
690
691 file->rdwr_short( river_number );
692 file->rdwr_short( min_river_length );
693 file->rdwr_short( max_river_length );
694 }
695
696 if(file->is_version_atleast(102, 1)) {
697 file->rdwr_bool( avoid_overcrowding );
698 }
699 if(file->is_version_atleast(102, 2)) {
700 file->rdwr_bool( no_routing_over_overcrowding );
701 file->rdwr_bool( with_private_paks );
702 }
703 if(file->is_version_atleast(102, 3)) {
704 // network stuff
705 random_counter = get_random_seed( );
706 file->rdwr_long( random_counter );
707 if( !env_t::networkmode || env_t::server ) {
708 frames_per_second = clamp(env_t::fps,5,100 ); // update it on the server to the current setting
709 frames_per_step = env_t::network_frames_per_step;
710 }
711 file->rdwr_long( frames_per_second );
712 file->rdwr_long( frames_per_step );
713 if( !env_t::networkmode || env_t::server ) {
714 frames_per_second = env_t::fps; // update it on the server to the current setting
715 frames_per_step = env_t::network_frames_per_step;
716 }
717 file->rdwr_bool( allow_buying_obsolete_vehicles );
718 file->rdwr_long( factory_worker_minimum_towns );
719 file->rdwr_long( factory_worker_maximum_towns );
720 // forest stuff
721 file->rdwr_byte( forest_base_size );
722 file->rdwr_byte( forest_map_size_divisor );
723 file->rdwr_byte( forest_count_divisor );
724 file->rdwr_short( forest_inverse_spare_tree_density );
725 file->rdwr_byte( max_no_of_trees_on_square );
726 file->rdwr_short( tree_climates );
727 file->rdwr_short( no_tree_climates );
728 file->rdwr_bool( no_trees );
729 file->rdwr_long( minimum_city_distance );
730 file->rdwr_long( industry_increase );
731 }
732 if( file->is_version_atleast(110, 0) ) {
733 if( !env_t::networkmode || env_t::server ) {
734 server_frames_ahead = env_t::server_frames_ahead;
735 }
736 file->rdwr_long( server_frames_ahead );
737 if( !env_t::networkmode || env_t::server ) {
738 server_frames_ahead = env_t::server_frames_ahead;
739 }
740 file->rdwr_short( used_vehicle_reduction );
741 }
742
743 if( file->is_version_atleast(110, 1) ) {
744 file->rdwr_bool( default_player_color_random );
745 for( int i=0; i<MAX_PLAYER_COUNT; i++ ) {
746 file->rdwr_byte( default_player_color[i][0] );
747 file->rdwr_byte( default_player_color[i][1] );
748 }
749 }
750 else if( file->is_loading() ) {
751 default_player_color_random = false;
752 for( int i=0; i<MAX_PLAYER_COUNT; i++ ) {
753 // default colors for player ...
754 default_player_color[i][0] = 255;
755 default_player_color[i][1] = 255;
756 }
757 }
758
759 if( file->is_version_atleast(110, 5) ) {
760 file->rdwr_short(factory_arrival_periods);
761 file->rdwr_bool(factory_enforce_demand);
762 }
763
764 if( file->is_version_atleast(110, 7) ) {
765 for( int i=0; i<10; i++ ) {
766 file->rdwr_short(locality_factor_per_year[i].year );
767 file->rdwr_long(locality_factor_per_year[i].factor );
768 }
769 file->rdwr_bool( drive_on_left );
770 file->rdwr_bool( signals_on_left );
771 file->rdwr_long( way_toll_runningcost_percentage );
772 file->rdwr_long( way_toll_waycost_percentage );
773 }
774
775 if( file->is_version_atleast(111, 2) ) {
776 file->rdwr_long( bonus_basefactor );
777 }
778 else if( file->is_loading() ) {
779 bonus_basefactor = 125;
780 }
781
782 if( file->is_version_atleast(111, 4) ) {
783 file->rdwr_bool( allow_underground_transformers );
784 }
785
786 if( file->is_version_atleast(111, 5) ) {
787 file->rdwr_short( special_building_distance );
788 }
789
790 if( file->is_version_atleast(112, 1) ) {
791 file->rdwr_short( factory_maximum_intransit_percentage );
792 }
793
794 if( file->is_version_atleast(112, 2) ) {
795 file->rdwr_short( remove_dummy_player_months );
796 file->rdwr_short( unprotect_abandoned_player_months );
797 }
798
799 if( file->is_version_atleast(112, 3) ) {
800 file->rdwr_short( max_factory_spacing );
801 file->rdwr_short( max_factory_spacing_percentage );
802 }
803 if( file->is_version_atleast(112, 8) ) {
804 file->rdwr_longlong( cst_alter_climate );
805 file->rdwr_byte( way_height_clearance );
806 }
807 if( file->is_version_atleast(120, 2) ) {
808 file->rdwr_long( default_ai_construction_speed );
809 }
810 else if( file->is_loading() ) {
811 default_ai_construction_speed = env_t::default_ai_construction_speed;
812 }
813 if( file->is_version_atleast(120, 2) ) {
814 file->rdwr_bool(lake);
815 file->rdwr_bool(no_trees);
816 file->rdwr_long( max_choose_route_steps );
817 }
818 if( file->is_version_atleast(120, 4) ) {
819 file->rdwr_bool(disable_make_way_public);
820 }
821 if( file->is_version_atleast(120, 6) ) {
822 file->rdwr_byte(max_rail_convoi_length);
823 file->rdwr_byte(max_road_convoi_length);
824 file->rdwr_byte(max_ship_convoi_length);
825 file->rdwr_byte(max_air_convoi_length);
826 }
827 if( file->is_version_atleast(120, 7) ) {
828 file->rdwr_byte(world_maximum_height);
829 file->rdwr_byte(world_minimum_height);
830 }
831 if( file->is_version_atleast(120, 9) ) {
832 file->rdwr_long(allow_merge_distant_halt);
833 }
834 // otherwise the default values of the last one will be used
835 }
836 }
837
838
839 // read the settings from this file
parse_simuconf(tabfile_t & simuconf,sint16 & disp_width,sint16 & disp_height,sint16 & fullscreen,std::string & objfilename)840 void settings_t::parse_simuconf(tabfile_t& simuconf, sint16& disp_width, sint16& disp_height, sint16 &fullscreen, std::string& objfilename)
841 {
842 tabfileobj_t contents;
843
844 simuconf.read(contents );
845
846 #if COLOUR_DEPTH != 0
847 // special day/night colors
848 for( int i=0; i<LIGHT_COUNT; i++ ) {
849 char str[256];
850 sprintf( str, "special_color[%i]", i );
851 int *c = contents.get_ints( str );
852 if( c[0]>=6 ) {
853 // now update RGB values
854 for( int j=0; j<3; j++ ) {
855 display_day_lights[i*3+j] = c[j+1];
856 }
857 for( int j=0; j<3; j++ ) {
858 display_night_lights[i*3+j] = c[j+4];
859 }
860 }
861 delete [] c;
862 }
863 #endif
864
865 //check for fontname, must be a valid name!
866 const char *fname = contents.get_string( "fontname", env_t::fontname.c_str() );
867 if( FILE *f=fopen(fname,"r") ) {
868 fclose(f);
869 env_t::fontname = fname;
870 }
871
872 env_t::water_animation = contents.get_int("water_animation_ms", env_t::water_animation );
873 env_t::ground_object_probability = contents.get_int("random_grounds_probability", env_t::ground_object_probability );
874 env_t::moving_object_probability = contents.get_int("random_wildlife_probability", env_t::moving_object_probability );
875
876 env_t::straight_way_without_control = contents.get_int("straight_way_without_control", env_t::straight_way_without_control) != 0;
877
878 env_t::road_user_info = contents.get_int("pedes_and_car_info", env_t::road_user_info) != 0;
879 env_t::tree_info = contents.get_int("tree_info", env_t::tree_info) != 0;
880 env_t::ground_info = contents.get_int("ground_info", env_t::ground_info) != 0;
881 env_t::townhall_info = contents.get_int("townhall_info", env_t::townhall_info) != 0;
882 env_t::single_info = contents.get_int("only_single_info", env_t::single_info );
883
884 env_t::compass_map_position = contents.get_int("compass_map_position", env_t::compass_map_position );
885 env_t::compass_screen_position = contents.get_int("compass_screen_position", env_t::compass_screen_position );
886
887 env_t::window_snap_distance = contents.get_int("window_snap_distance", env_t::window_snap_distance );
888 env_t::window_buttons_right = contents.get_int("window_buttons_right", env_t::window_buttons_right );
889 env_t::left_to_right_graphs = contents.get_int("left_to_right_graphs", env_t::left_to_right_graphs );
890 env_t::window_frame_active = contents.get_int("window_frame_active", env_t::window_frame_active );
891 env_t::second_open_closes_win = contents.get_int("second_open_closes_win", env_t::second_open_closes_win );
892 env_t::remember_window_positions = contents.get_int("remember_window_positions", env_t::remember_window_positions );
893
894 env_t::show_tooltips = contents.get_int("show_tooltips", env_t::show_tooltips );
895 env_t::tooltip_delay = contents.get_int("tooltip_delay", env_t::tooltip_delay );
896 env_t::tooltip_duration = contents.get_int("tooltip_duration", env_t::tooltip_duration );
897 env_t::toolbar_max_width = contents.get_int("toolbar_max_width", env_t::toolbar_max_width );
898 env_t::toolbar_max_height = contents.get_int("toolbar_max_height", env_t::toolbar_max_height );
899
900 // how to show the stuff outside the map
901 env_t::draw_earth_border = contents.get_int("draw_earth_border", env_t::draw_earth_border ) != 0;
902 env_t::draw_outside_tile = contents.get_int("draw_outside_tile", env_t::draw_outside_tile ) != 0;
903
904 // display stuff
905 env_t::show_names = contents.get_int("show_names", env_t::show_names );
906 env_t::show_month = contents.get_int("show_month", env_t::show_month );
907 env_t::max_acceleration = contents.get_int("fast_forward", env_t::max_acceleration );
908 env_t::fps = contents.get_int("frames_per_second",env_t::fps );
909 env_t::num_threads = clamp( contents.get_int("threads", env_t::num_threads ), 1, MAX_THREADS );
910 env_t::simple_drawing_default = contents.get_int("simple_drawing_tile_size",env_t::simple_drawing_default );
911 env_t::simple_drawing_fast_forward = contents.get_int("simple_drawing_fast_forward",env_t::simple_drawing_fast_forward );
912 env_t::visualize_schedule = contents.get_int("visualize_schedule",env_t::visualize_schedule ) != 0;
913 env_t::show_vehicle_states = contents.get_int("show_vehicle_states",env_t::show_vehicle_states );
914 env_t::follow_convoi_underground = contents.get_int("follow_convoi_underground",env_t::follow_convoi_underground );
915
916 env_t::hide_rail_return_ticket = contents.get_int("hide_rail_return_ticket",env_t::hide_rail_return_ticket ) != 0;
917 env_t::show_delete_buttons = contents.get_int("show_delete_buttons",env_t::show_delete_buttons ) != 0;
918 env_t::chat_window_transparency = contents.get_int("chat_transparency",env_t::chat_window_transparency );
919
920 env_t::hide_keyboard = contents.get_int("hide_keyboard",env_t::hide_keyboard ) != 0;
921
922 env_t::player_finance_display_account = contents.get_int("player_finance_display_account",env_t::player_finance_display_account ) != 0;
923
924 // network stuff
925 env_t::server_frames_ahead = contents.get_int("server_frames_ahead", env_t::server_frames_ahead );
926 env_t::additional_client_frames_behind = contents.get_int("additional_client_frames_behind", env_t::additional_client_frames_behind);
927 env_t::network_frames_per_step = contents.get_int("server_frames_per_step", env_t::network_frames_per_step );
928 env_t::server_sync_steps_between_checks = contents.get_int("server_frames_between_checks", env_t::server_sync_steps_between_checks );
929 env_t::pause_server_no_clients = contents.get_int("pause_server_no_clients", env_t::pause_server_no_clients );
930 env_t::server_save_game_on_quit = contents.get_int("server_save_game_on_quit", env_t::server_save_game_on_quit );
931 env_t::reload_and_save_on_quit = contents.get_int("reload_and_save_on_quit", env_t::reload_and_save_on_quit );
932
933 env_t::server_announce = contents.get_int("announce_server", env_t::server_announce );
934 if (!env_t::server) {
935 env_t::server_port = contents.get_int("server_port", env_t::server_port);
936 }
937 else {
938 env_t::server_port = env_t::server;
939 }
940 env_t::server_announce = contents.get_int("server_announce", env_t::server_announce );
941 env_t::server_announce_interval = contents.get_int("server_announce_intervall", env_t::server_announce_interval );
942 env_t::server_announce_interval = contents.get_int("server_announce_interval", env_t::server_announce_interval );
943 if (env_t::server_announce_interval < 60) {
944 env_t::server_announce_interval = 60;
945 }
946 else if (env_t::server_announce_interval > 86400) {
947 env_t::server_announce_interval = 86400;
948 }
949 if( *contents.get("server_dns") ) {
950 env_t::server_dns = ltrim(contents.get("server_dns"));
951 }
952 if( *contents.get("server_altdns") ) {
953 env_t::server_alt_dns = ltrim(contents.get("server_altdns"));
954 }
955 if( *contents.get("server_name") ) {
956 env_t::server_name = ltrim(contents.get("server_name"));
957 }
958 if( *contents.get("server_comments") ) {
959 env_t::server_comments = ltrim(contents.get("server_comments"));
960 }
961 if( *contents.get("server_email") ) {
962 env_t::server_email = ltrim(contents.get("server_email"));
963 }
964 if( *contents.get("server_pakurl") ) {
965 env_t::server_pakurl = ltrim(contents.get("server_pakurl"));
966 }
967 if( *contents.get("server_infurl") ) {
968 env_t::server_infurl = ltrim(contents.get("server_infurl"));
969 }
970 if( *contents.get("server_admin_pw") ) {
971 env_t::server_admin_pw = ltrim(contents.get("server_admin_pw"));
972 }
973 if( *contents.get("nickname") ) {
974 env_t::nickname = ltrim(contents.get("nickname"));
975 }
976 if( *contents.get("server_motd_filename") ) {
977 env_t::server_motd_filename = ltrim(contents.get("server_motd_filename"));
978 }
979
980 // listen directive is a comma separated list of IP addresses to listen on
981 if( *contents.get("listen") ) {
982 env_t::listen.clear();
983 std::string s = ltrim(contents.get("listen"));
984
985 // Find index of first ',' copy from start of string to that position
986 // Set start index to last position, then repeat
987 // When ',' not found, copy remainder of string
988
989 size_t start = 0;
990 size_t end;
991
992 end = s.find_first_of(",");
993 env_t::listen.append_unique( ltrim( s.substr( start, end ).c_str() ) );
994 while ( end != std::string::npos ) {
995 start = end;
996 end = s.find_first_of( ",", start + 1 );
997 env_t::listen.append_unique( ltrim( s.substr( start + 1, end - 1 - start ).c_str() ) );
998 }
999 }
1000
1001 drive_on_left = contents.get_int("drive_left", drive_on_left );
1002 signals_on_left = contents.get_int("signals_on_left", signals_on_left );
1003 allow_underground_transformers = contents.get_int( "allow_underground_transformers", allow_underground_transformers )!=0;
1004 disable_make_way_public = contents.get_int("disable_make_way_public", disable_make_way_public) != 0;
1005
1006 // up to ten rivers are possible
1007 for( int i = 0; i<10; i++ ) {
1008 char name[32];
1009 sprintf( name, "river_type[%i]", i );
1010 const char *test = ltrim(contents.get(name) );
1011 if(*test) {
1012 const int add_river = i<env_t::river_types ? i : env_t::river_types;
1013 env_t::river_type[add_river] = test;
1014 if( add_river==env_t::river_types ) {
1015 env_t::river_types++;
1016 }
1017 }
1018 }
1019
1020 // old syntax for single city road
1021 const char *str = ltrim(contents.get("city_road_type") );
1022 if( str[0] ) {
1023 num_city_roads = 1;
1024 tstrncpy(city_roads[0].name, str, lengthof(city_roads[0].name) );
1025 rtrim( city_roads[0].name );
1026 // default her: always available
1027 city_roads[0].intro = 1;
1028 city_roads[0].retire = NEVER;
1029 }
1030
1031 // new: up to ten city_roads are possible
1032 if( *contents.get("city_road[0]") ) {
1033 // renew them always when a table is encountered ...
1034 num_city_roads = 0;
1035 for( int i = 0; i<10; i++ ) {
1036 char name[256];
1037 sprintf( name, "city_road[%i]", i );
1038 // format is "city_road[%i]=name_of_road,using from (year), using to (year)"
1039 const char *test = ltrim(contents.get(name) );
1040 if(*test) {
1041 const char *p = test;
1042 while(*p && *p!=',' ) {
1043 p++;
1044 }
1045 tstrncpy( city_roads[num_city_roads].name, test, (unsigned)(p-test)+1 );
1046 // default her: intro/retire=0 -> set later to intro/retire of way-desc
1047 city_roads[num_city_roads].intro = 0;
1048 city_roads[num_city_roads].retire = 0;
1049 if( *p==',' ) {
1050 ++p;
1051 city_roads[num_city_roads].intro = atoi(p)*12;
1052 while(*p && *p!=',' ) {
1053 p++;
1054 }
1055 }
1056 if( *p==',' ) {
1057 city_roads[num_city_roads].retire = atoi(p+1)*12;
1058 }
1059 num_city_roads ++;
1060 }
1061 }
1062 }
1063 if (num_city_roads == 0) {
1064 // take fallback value: "city_road"
1065 tstrncpy(city_roads[0].name, "city_road", lengthof(city_roads[0].name) );
1066 // default her: always available
1067 city_roads[0].intro = 1;
1068 city_roads[0].retire = NEVER;
1069 num_city_roads = 1;
1070 }
1071
1072 // intercity roads
1073 // old syntax for single intercity road
1074 str = ltrim(contents.get("intercity_road_type") );
1075 if( str[0] ) {
1076 num_intercity_roads = 1;
1077 tstrncpy(intercity_roads[0].name, str, lengthof(intercity_roads[0].name) );
1078 rtrim( intercity_roads[0].name );
1079 // default her: always available
1080 intercity_roads[0].intro = 1;
1081 intercity_roads[0].retire = NEVER;
1082 }
1083
1084 // new: up to ten intercity_roads are possible
1085 if( *contents.get("intercity_road[0]") ) {
1086 // renew them always when a table is encountered ...
1087 num_intercity_roads = 0;
1088 for( int i = 0; i<10; i++ ) {
1089 char name[256];
1090 sprintf( name, "intercity_road[%i]", i );
1091 // format is "intercity_road[%i]=name_of_road,using from (year), using to (year)"
1092 const char *test = ltrim(contents.get(name) );
1093 if(*test) {
1094 const char *p = test;
1095 while(*p && *p!=',' ) {
1096 p++;
1097 }
1098 tstrncpy( intercity_roads[num_intercity_roads].name, test, (unsigned)(p-test)+1 );
1099 // default her: intro/retire=0 -> set later to intro/retire of way-desc
1100 intercity_roads[num_intercity_roads].intro = 0;
1101 intercity_roads[num_intercity_roads].retire = 0;
1102 if( *p==',' ) {
1103 ++p;
1104 intercity_roads[num_intercity_roads].intro = atoi(p)*12;
1105 while(*p && *p!=',' ) {
1106 p++;
1107 }
1108 }
1109 if( *p==',' ) {
1110 intercity_roads[num_intercity_roads].retire = atoi(p+1)*12;
1111 }
1112 num_intercity_roads ++;
1113 }
1114 }
1115 }
1116 if (num_intercity_roads == 0) {
1117 // take fallback value: "asphalt_road"
1118 tstrncpy(intercity_roads[0].name, "asphalt_road", lengthof(intercity_roads[0].name) );
1119 // default her: always available
1120 intercity_roads[0].intro = 1;
1121 intercity_roads[0].retire = NEVER;
1122 num_intercity_roads = 1;
1123 }
1124
1125 env_t::autosave = (contents.get_int("autosave", env_t::autosave) );
1126
1127 // routing stuff
1128 max_route_steps = contents.get_int("max_route_steps", max_route_steps );
1129 max_choose_route_steps = contents.get_int("max_choose_route_steps", max_choose_route_steps );
1130 max_hops = contents.get_int("max_hops", max_hops );
1131 max_transfers = contents.get_int("max_transfers", max_transfers );
1132 bonus_basefactor = contents.get_int("bonus_basefactor", bonus_basefactor );
1133
1134 special_building_distance = contents.get_int("special_building_distance", special_building_distance );
1135 minimum_city_distance = contents.get_int("minimum_city_distance", minimum_city_distance );
1136 industry_increase = contents.get_int("industry_increase_every", industry_increase );
1137 passenger_factor = contents.get_int("passenger_factor", passenger_factor ); /* this can manipulate the passenger generation */
1138 factory_worker_percentage = contents.get_int("factory_worker_percentage", factory_worker_percentage );
1139 factory_worker_radius = contents.get_int("factory_worker_radius", factory_worker_radius );
1140 factory_worker_minimum_towns = contents.get_int("factory_worker_minimum_towns", factory_worker_minimum_towns );
1141 factory_worker_maximum_towns = contents.get_int("factory_worker_maximum_towns", factory_worker_maximum_towns );
1142 factory_arrival_periods = clamp( contents.get_int("factory_arrival_periods", factory_arrival_periods), 1, 16 );
1143 factory_enforce_demand = contents.get_int("factory_enforce_demand", factory_enforce_demand) != 0;
1144 factory_maximum_intransit_percentage = contents.get_int("maximum_intransit_percentage", factory_maximum_intransit_percentage);
1145
1146 tourist_percentage = contents.get_int("tourist_percentage", tourist_percentage );
1147 // .. read twice: old and right spelling
1148 separate_halt_capacities = contents.get_int("seperate_halt_capacities", separate_halt_capacities ) != 0;
1149 separate_halt_capacities = contents.get_int("separate_halt_capacities", separate_halt_capacities ) != 0;
1150
1151 pay_for_total_distance = contents.get_int("pay_for_total_distance", pay_for_total_distance );
1152 avoid_overcrowding = contents.get_int("avoid_overcrowding", avoid_overcrowding )!=0;
1153 no_routing_over_overcrowding = contents.get_int("no_routing_over_overcrowded", no_routing_over_overcrowding )!=0;
1154
1155 // city stuff
1156 passenger_multiplier = contents.get_int("passenger_multiplier", passenger_multiplier );
1157 mail_multiplier = contents.get_int("mail_multiplier", mail_multiplier );
1158 goods_multiplier = contents.get_int("goods_multiplier", goods_multiplier );
1159 electricity_multiplier = contents.get_int("electricity_multiplier", electricity_multiplier );
1160
1161 growthfactor_small = contents.get_int("growthfactor_villages", growthfactor_small );
1162 growthfactor_medium = contents.get_int("growthfactor_cities", growthfactor_medium );
1163 growthfactor_large = contents.get_int("growthfactor_capitals", growthfactor_large );
1164
1165 random_pedestrians = contents.get_int("random_pedestrians", random_pedestrians ) != 0;
1166 show_pax = contents.get_int("stop_pedestrians", show_pax ) != 0;
1167 traffic_level = contents.get_int("citycar_level", traffic_level ); // ten normal years
1168 stadtauto_duration = contents.get_int("default_citycar_life", stadtauto_duration ); // ten normal years
1169 allow_buying_obsolete_vehicles = contents.get_int("allow_buying_obsolete_vehicles", allow_buying_obsolete_vehicles );
1170 used_vehicle_reduction = clamp( contents.get_int("used_vehicle_reduction", used_vehicle_reduction ), 0, 1000 );
1171
1172 // starting money
1173 starting_money = contents.get_int64("starting_money", starting_money );
1174 /* up to ten blocks year, money, interpolation={0,1} are possible:
1175 * starting_money[i]=y,m,int
1176 * y .. year
1177 * m .. money (in 1/100 Cr)
1178 * int .. interpolation: 0 - no interpolation, !=0 linear interpolated
1179 * (m) is the starting money for player start after (y), if (i)!=0, the starting money
1180 * is linearly interpolated between (y) and the next greater year given in another entry.
1181 * starting money for given year is:
1182 */
1183 int j=0;
1184 for( int i = 0; i<10; i++ ) {
1185 char name[32];
1186 sprintf( name, "starting_money[%i]", i );
1187 sint64 *test = contents.get_sint64s( name );
1188 if( (test[0]>1) && (test[0]<=3) ) {
1189 // insert sorted by years
1190 int k=0;
1191 for (k=0; k<i; k++) {
1192 if (startingmoneyperyear[k].year > test[1]) {
1193 for (int l=j; l>=k; l--)
1194 memcpy( &startingmoneyperyear[l+1], &startingmoneyperyear[l], sizeof(yearmoney) );
1195 break;
1196 }
1197 }
1198 startingmoneyperyear[k].year = (sint16)test[1];
1199 startingmoneyperyear[k].money = test[2];
1200 if (test[0]==3) {
1201 startingmoneyperyear[k].interpol = test[3]!=0;
1202 }
1203 else {
1204 startingmoneyperyear[k].interpol = false;
1205 }
1206 // printf("smpy[%d] year=%d money=%lld\n",k,startingmoneyperyear[k].year,startingmoneyperyear[k].money);
1207 j++;
1208 }
1209 else {
1210 // invalid entry
1211 }
1212 delete [] test;
1213 }
1214 // at least one found => use this now!
1215 if( j>0 && startingmoneyperyear[0].money>0 ) {
1216 starting_money = 0;
1217 // fill remaining entries
1218 for( int i=j+1; i<10; i++ ) {
1219 startingmoneyperyear[i].year = 0;
1220 startingmoneyperyear[i].money = 0;
1221 startingmoneyperyear[i].interpol = 0;
1222 }
1223 }
1224
1225 /* up to ten blocks year, locality_factor={0...2000000000}
1226 * locality_factor[i]=y,l
1227 * y .. year
1228 * l .. factor, the larger the more widespread
1229 */
1230 j = 0;
1231 for( int i = 0; i<10; i++ ) {
1232 char name[256];
1233 sprintf( name, "locality_factor[%i]", i );
1234 sint64 *test = contents.get_sint64s( name );
1235 // two arguments, and then factor natural number
1236 if( test[0]==2 ) {
1237 if( test[2]<=0 ) {
1238 dbg->error("Parameter in simuconf.tab wrong!","locality_factor second value must be larger than zero!" );
1239 }
1240 else {
1241 // insert sorted by years
1242 int k=0;
1243 for( k=0; k<i; k++ ) {
1244 if( locality_factor_per_year[k].year > test[1] ) {
1245 for (int l=j; l>=k; l--)
1246 memcpy( &locality_factor_per_year[l+1], &locality_factor_per_year[l], sizeof(yearly_locality_factor_t) );
1247 break;
1248 }
1249 }
1250 locality_factor_per_year[k].year = (sint16)test[1];
1251 locality_factor_per_year[k].factor = (uint32)test[2];
1252 j++;
1253 }
1254 }
1255 else {
1256 // invalid entry
1257 }
1258 delete [] test;
1259 }
1260 // add default, if nothing found
1261 if( j==0 && locality_factor_per_year[0].factor==0 ) {
1262 locality_factor_per_year[0].year = 0;
1263 locality_factor_per_year[0].factor = 100;
1264 j++;
1265 }
1266 // fill remaining entries
1267 while( j>0 && j<9 ) {
1268 j++;
1269 locality_factor_per_year[j].year = 0;
1270 locality_factor_per_year[j].factor = 0;
1271 }
1272
1273 // player stuff
1274 remove_dummy_player_months = contents.get_int("remove_dummy_player_months", remove_dummy_player_months );
1275 // .. read twice: old and right spelling
1276 unprotect_abandoned_player_months = contents.get_int("unprotect_abondoned_player_months", unprotect_abandoned_player_months );
1277 unprotect_abandoned_player_months = contents.get_int("unprotect_abandoned_player_months", unprotect_abandoned_player_months );
1278 default_player_color_random = contents.get_int("random_player_colors", default_player_color_random ) != 0;
1279 for( int i = 0; i<MAX_PLAYER_COUNT; i++ ) {
1280 char name[32];
1281 sprintf( name, "player_color[%i]", i );
1282 const char *command = contents.get(name);
1283 int c1, c2;
1284 if( sscanf( command, "%i,%i", &c1, &c2 )==2 ) {
1285 default_player_color[i][0] = c1;
1286 default_player_color[i][1] = c2;
1287 }
1288 }
1289 default_ai_construction_speed = env_t::default_ai_construction_speed = contents.get_int("ai_construction_speed", env_t::default_ai_construction_speed );
1290
1291 maint_building = contents.get_int("maintenance_building", maint_building );
1292
1293 numbered_stations = contents.get_int("numbered_stations", numbered_stations );
1294 station_coverage_size = contents.get_int("station_coverage", station_coverage_size );
1295
1296 // time stuff
1297 bits_per_month = contents.get_int("bits_per_month", bits_per_month );
1298 use_timeline = contents.get_int("use_timeline", use_timeline );
1299 starting_year = contents.get_int("starting_year", starting_year );
1300 starting_month = contents.get_int("starting_month", starting_month+1)-1;
1301
1302 env_t::new_height_map_conversion = contents.get_int("new_height_map_conversion", env_t::new_height_map_conversion );
1303 river_number = contents.get_int("river_number", river_number );
1304 min_river_length = contents.get_int("river_min_length", min_river_length );
1305 max_river_length = contents.get_int("river_max_length", max_river_length );
1306
1307 // forest stuff (now part of simuconf.tab)
1308 forest_base_size = contents.get_int("forest_base_size", forest_base_size );
1309 forest_map_size_divisor = contents.get_int("forest_map_size_divisor", forest_map_size_divisor );
1310 forest_count_divisor = contents.get_int("forest_count_divisor", forest_count_divisor );
1311 forest_inverse_spare_tree_density = contents.get_int("forest_inverse_spare_tree_density", forest_inverse_spare_tree_density );
1312 max_no_of_trees_on_square = contents.get_int("max_no_of_trees_on_square", max_no_of_trees_on_square );
1313 tree_climates = contents.get_int("tree_climates", tree_climates );
1314 no_tree_climates = contents.get_int("no_tree_climates", no_tree_climates );
1315 no_trees = contents.get_int("no_trees", no_trees );
1316 lake = !contents.get_int("no_lakes", !lake );
1317
1318 // these are pak specific; the diagonal length affect travelling time (is game critical)
1319 pak_diagonal_multiplier = contents.get_int("diagonal_multiplier", pak_diagonal_multiplier );
1320 // the height in z-direction will only cause pixel errors but not a different behaviour
1321 env_t::pak_tile_height_step = contents.get_int("tile_height", env_t::pak_tile_height_step );
1322 // new height for old slopes after conversion - 1=single height, 2=double height
1323 // Must be only overwrite when reading from pak dir ...
1324 env_t::pak_height_conversion_factor = contents.get_int("height_conversion_factor", env_t::pak_height_conversion_factor );
1325
1326 // minimum clearance under under bridges: 1 or 2? (HACK: value only zero during loading of pak set config)
1327 int bounds = (way_height_clearance!=0);
1328 way_height_clearance = contents.get_int("way_height_clearance", way_height_clearance );
1329 if( way_height_clearance > 2 && way_height_clearance < bounds ) {
1330 sint8 new_whc = clamp( way_height_clearance, bounds, 2 );
1331 dbg->warning( "settings_t::parse_simuconf()", "Illegal way_height_clearance of %i set to %i", way_height_clearance, new_whc );
1332 way_height_clearance = new_whc;
1333 }
1334
1335 min_factory_spacing = contents.get_int("factory_spacing", min_factory_spacing );
1336 min_factory_spacing = contents.get_int("min_factory_spacing", min_factory_spacing );
1337 max_factory_spacing = contents.get_int("max_factory_spacing", max_factory_spacing );
1338 max_factory_spacing_percentage = contents.get_int("max_factory_spacing_percentage", max_factory_spacing_percentage );
1339 crossconnect_factories = contents.get_int("crossconnect_factories", crossconnect_factories ) != 0;
1340 crossconnect_factor = contents.get_int("crossconnect_factories_percentage", crossconnect_factor );
1341 electric_promille = contents.get_int("electric_promille", electric_promille );
1342
1343 env_t::just_in_time = (uint8)contents.get_int("just_in_time", env_t::just_in_time);
1344 if( env_t::just_in_time > 2 ) {
1345 env_t::just_in_time = 2; // Range restriction.
1346 }
1347 just_in_time = env_t::just_in_time;
1348 beginner_price_factor = contents.get_int("beginner_price_factor", beginner_price_factor ); /* this manipulates the good prices in beginner mode */
1349 beginner_mode = contents.get_int("first_beginner", beginner_mode ); /* start in beginner mode */
1350
1351 way_toll_runningcost_percentage = contents.get_int("toll_runningcost_percentage", way_toll_runningcost_percentage );
1352 way_toll_waycost_percentage = contents.get_int("toll_waycost_percentage", way_toll_waycost_percentage );
1353
1354 /* now the cost section */
1355 cst_multiply_dock = contents.get_int64("cost_multiply_dock", cst_multiply_dock/(-100) ) * -100;
1356 cst_multiply_station = contents.get_int64("cost_multiply_station", cst_multiply_station/(-100) ) * -100;
1357 cst_multiply_roadstop = contents.get_int64("cost_multiply_roadstop", cst_multiply_roadstop/(-100) ) * -100;
1358 cst_multiply_airterminal = contents.get_int64("cost_multiply_airterminal", cst_multiply_airterminal/(-100) ) * -100;
1359 cst_multiply_post = contents.get_int64("cost_multiply_post", cst_multiply_post/(-100) ) * -100;
1360 cst_multiply_headquarter = contents.get_int64("cost_multiply_headquarter", cst_multiply_headquarter/(-100) ) * -100;
1361 cst_depot_air = contents.get_int64("cost_depot_air", cst_depot_air/(-100) ) * -100;
1362 cst_depot_rail = contents.get_int64("cost_depot_rail", cst_depot_rail/(-100) ) * -100;
1363 cst_depot_road = contents.get_int64("cost_depot_road", cst_depot_road/(-100) ) * -100;
1364 cst_depot_ship = contents.get_int64("cost_depot_ship", cst_depot_ship/(-100) ) * -100;
1365
1366 allow_merge_distant_halt = contents.get_int("allow_merge_distant_halt", allow_merge_distant_halt);
1367 cst_multiply_merge_halt = contents.get_int64("cost_multiply_merge_halt", cst_multiply_merge_halt/(-100) ) * -100;
1368
1369 // alter landscape
1370 cst_buy_land = contents.get_int64("cost_buy_land", cst_buy_land/(-100) ) * -100;
1371 cst_alter_land = contents.get_int64("cost_alter_land", cst_alter_land/(-100) ) * -100;
1372 cst_set_slope = contents.get_int64("cost_set_slope", cst_set_slope/(-100) ) * -100;
1373 cst_alter_climate = contents.get_int64("cost_alter_climate", cst_alter_climate/(-100) ) * -100;
1374 cst_found_city = contents.get_int64("cost_found_city", cst_found_city/(-100) ) * -100;
1375 cst_multiply_found_industry = contents.get_int64("cost_multiply_found_industry", cst_multiply_found_industry/(-100) ) * -100;
1376 cst_remove_tree = contents.get_int64("cost_remove_tree", cst_remove_tree/(-100) ) * -100;
1377 cst_multiply_remove_haus = contents.get_int64("cost_multiply_remove_haus", cst_multiply_remove_haus/(-100) ) * -100;
1378 cst_multiply_remove_field = contents.get_int64("cost_multiply_remove_field", cst_multiply_remove_field/(-100) ) * -100;
1379 // powerlines
1380 cst_transformer = contents.get_int64("cost_transformer", cst_transformer/(-100) ) * -100;
1381 cst_maintain_transformer = contents.get_int64("cost_maintain_transformer", cst_maintain_transformer/(-100) ) * -100;
1382
1383 cst_make_public_months = contents.get_int64("cost_make_public_months", cst_make_public_months);
1384
1385 /* now the way builder */
1386 way_count_straight = contents.get_int("way_straight", way_count_straight );
1387 way_count_curve = contents.get_int("way_curve", way_count_curve );
1388 way_count_double_curve = contents.get_int("way_double_curve", way_count_double_curve );
1389 way_count_90_curve = contents.get_int("way_90_curve", way_count_90_curve );
1390 way_count_slope = contents.get_int("way_slope", way_count_slope );
1391 way_count_tunnel = contents.get_int("way_tunnel", way_count_tunnel );
1392 way_max_bridge_len = contents.get_int("way_max_bridge_len", way_max_bridge_len );
1393 way_count_leaving_road = contents.get_int("way_leaving_road", way_count_leaving_road );
1394
1395 /*
1396 * Selection of savegame format through inifile
1397 */
1398 str = contents.get("saveformat" );
1399 while (*str == ' ') str++;
1400 if (strcmp(str, "binary") == 0) {
1401 loadsave_t::set_savemode(loadsave_t::binary );
1402 }
1403 else if(strcmp(str, "zipped") == 0) {
1404 loadsave_t::set_savemode(loadsave_t::zipped );
1405 }
1406 else if(strcmp(str, "xml") == 0) {
1407 loadsave_t::set_savemode(loadsave_t::xml );
1408 }
1409 else if(strcmp(str, "xml_zipped") == 0) {
1410 loadsave_t::set_savemode(loadsave_t::xml_zipped );
1411 }
1412 else if(strcmp(str, "bzip2") == 0) {
1413 loadsave_t::set_savemode(loadsave_t::bzip2 );
1414 }
1415 else if(strcmp(str, "xml_bzip2") == 0) {
1416 loadsave_t::set_savemode(loadsave_t::xml_bzip2 );
1417 }
1418
1419 str = contents.get("autosaveformat" );
1420 while (*str == ' ') str++;
1421 if (strcmp(str, "binary") == 0) {
1422 loadsave_t::set_autosavemode(loadsave_t::binary );
1423 }
1424 else if(strcmp(str, "zipped") == 0) {
1425 loadsave_t::set_autosavemode(loadsave_t::zipped );
1426 }
1427 else if(strcmp(str, "xml") == 0) {
1428 loadsave_t::set_autosavemode(loadsave_t::xml );
1429 }
1430 else if(strcmp(str, "xml_zipped") == 0) {
1431 loadsave_t::set_autosavemode(loadsave_t::xml_zipped );
1432 }
1433 else if(strcmp(str, "bzip2") == 0) {
1434 loadsave_t::set_autosavemode(loadsave_t::bzip2 );
1435 }
1436 else if(strcmp(str, "xml_bzip2") == 0) {
1437 loadsave_t::set_autosavemode(loadsave_t::xml_bzip2 );
1438 }
1439
1440 /*
1441 * Default resolution
1442 */
1443 disp_width = contents.get_int("display_width", disp_width );
1444 disp_height = contents.get_int("display_height", disp_height );
1445 fullscreen = contents.get_int("fullscreen", fullscreen );
1446
1447 with_private_paks = contents.get_int("with_private_paks", with_private_paks)!=0;
1448
1449 max_rail_convoi_length = contents.get_int("max_rail_convoi_length",max_rail_convoi_length);
1450 max_road_convoi_length = contents.get_int("max_road_convoi_length",max_road_convoi_length);
1451 max_ship_convoi_length = contents.get_int("max_ship_convoi_length",max_ship_convoi_length);
1452 max_air_convoi_length = contents.get_int("max_air_convoi_length",max_air_convoi_length);
1453
1454 world_maximum_height = contents.get_int("world_maximum_height",world_maximum_height);
1455 world_minimum_height = contents.get_int("world_minimum_height",world_minimum_height);
1456 if( world_minimum_height>=world_maximum_height ) {
1457 world_minimum_height = world_maximum_height-1;
1458 }
1459
1460 // Default pak file path
1461 objfilename = ltrim(contents.get_string("pak_file_path", "" ) );
1462
1463 printf("Reading simuconf.tab successful!\n" );
1464 }
1465
1466 // colour stuff can only be parsed when the graphic system has already started
parse_colours(tabfile_t & simuconf)1467 void settings_t::parse_colours(tabfile_t& simuconf)
1468 {
1469 tabfileobj_t contents;
1470
1471 simuconf.read( contents );
1472
1473 env_t::default_window_title_color = contents.get_color("default_window_title_color", env_t::default_window_title_color, &env_t::default_window_title_color_rgb );
1474 env_t::front_window_text_color = contents.get_color("front_window_text_color", env_t::front_window_text_color, &env_t::front_window_text_color_rgb );
1475 env_t::bottom_window_text_color = contents.get_color("bottom_window_text_color", env_t::bottom_window_text_color, &env_t::bottom_window_text_color_rgb );
1476
1477 env_t::bottom_window_darkness = contents.get_int("env_t::bottom_window_darkness", env_t::bottom_window_darkness);
1478
1479 env_t::tooltip_color = contents.get_color("tooltip_background_color", env_t::tooltip_color, &env_t::tooltip_color_rgb );
1480 env_t::tooltip_textcolor = contents.get_color("tooltip_text_color", env_t::tooltip_textcolor, &env_t::tooltip_textcolor_rgb );
1481 env_t::cursor_overlay_color = contents.get_color("cursor_overlay_color", env_t::cursor_overlay_color, &env_t::cursor_overlay_color_rgb );
1482
1483 env_t::background_color = contents.get_color("background_color", env_t::background_color, &env_t::background_color_rgb );
1484 }
1485
1486
get_name_language_id() const1487 int settings_t::get_name_language_id() const
1488 {
1489 int lang = -1;
1490 if( env_t::networkmode ) {
1491 lang = translator::get_language( language_code_names );
1492 }
1493 if( lang == -1 ) {
1494 lang = translator::get_language();
1495 }
1496 return lang;
1497 }
1498
1499
get_starting_money(sint16 const year) const1500 sint64 settings_t::get_starting_money(sint16 const year) const
1501 {
1502 if( starting_money>0 ) {
1503 return starting_money;
1504 }
1505
1506 // search entry with startingmoneyperyear[i].year > year
1507 int i;
1508 for( i=0; i<10; i++ ) {
1509 if(startingmoneyperyear[i].year!=0) {
1510 if (startingmoneyperyear[i].year>year) {
1511 break;
1512 }
1513 }
1514 else {
1515 // year is behind the latest given date
1516 return startingmoneyperyear[i>0 ? i-1 : 0].money;
1517 }
1518 }
1519 if (i==0) {
1520 // too early: use first entry
1521 return startingmoneyperyear[0].money;
1522 }
1523 else {
1524 // now: startingmoneyperyear[i-1].year <= year < startingmoneyperyear[i].year
1525 if (startingmoneyperyear[i-1].interpol) {
1526 // linear interpolation
1527 return startingmoneyperyear[i-1].money +
1528 (startingmoneyperyear[i].money-startingmoneyperyear[i-1].money)
1529 * (year-startingmoneyperyear[i-1].year) /(startingmoneyperyear[i].year-startingmoneyperyear[i-1].year );
1530 }
1531 else {
1532 // no interpolation
1533 return startingmoneyperyear[i-1].money;
1534 }
1535
1536 }
1537 }
1538
1539
get_locality_factor(sint16 const year) const1540 uint32 settings_t::get_locality_factor(sint16 const year) const
1541 {
1542 int i;
1543 for( i=0; i<10; i++ ) {
1544 if( locality_factor_per_year[i].year!=0 ) {
1545 if( locality_factor_per_year[i].year > year ) {
1546 break;
1547 }
1548 }
1549 else {
1550 // year is behind the latest given date
1551 return locality_factor_per_year[max(i-1,0)].factor;
1552 }
1553 }
1554 if( i==0 ) {
1555 // too early: use first entry
1556 return locality_factor_per_year[0].factor;
1557 }
1558 else {
1559 #if 0
1560 // linear interpolation
1561 return locality_factor_per_year[i-1].factor +
1562 (locality_factor_per_year[i].factor-locality_factor_per_year[i-1].factor)
1563 * (year-locality_factor_per_year[i-1].year) /(locality_factor_per_year[i].year-locality_factor_per_year[i-1].year );
1564 #else
1565 // exponential evaluation
1566 sint32 diff = (locality_factor_per_year[i].factor-locality_factor_per_year[i-1].factor);
1567 double a = exp((year-locality_factor_per_year[i-1].year)/20.0);
1568 double b = exp((locality_factor_per_year[i].year-locality_factor_per_year[i-1].year)/20.0);
1569 return locality_factor_per_year[i-1].factor + (sint32)((diff*(a-1.0))/(b-1.0) + 0.5);
1570 #endif
1571 }
1572 }
1573
1574
1575 /**
1576 * returns newest way-desc for road_timeline_t arrays
1577 * @param road_timeline_t must be an array with at least num_roads elements, no range checks!
1578 */
get_timeline_road_type(uint16 year,uint16 num_roads,road_timeline_t * roads)1579 static const way_desc_t *get_timeline_road_type( uint16 year, uint16 num_roads, road_timeline_t* roads)
1580 {
1581 const way_desc_t *desc = NULL;
1582 const way_desc_t *test;
1583 for( int i=0; i<num_roads; i++ ) {
1584 test = way_builder_t::get_desc( roads[i].name, 0 );
1585 if( test ) {
1586 // return first available for no timeline
1587 if( year==0 ) {
1588 return test;
1589 }
1590 if( roads[i].intro==0 ) {
1591 // fill in real intro date
1592 roads[i].intro = test->get_intro_year_month( );
1593 }
1594 if( roads[i].retire==0 ) {
1595 // fill in real retire date
1596 roads[i].retire = test->get_retire_year_month( );
1597 if( roads[i].retire==0 ) {
1598 roads[i].retire = NEVER;
1599 }
1600 }
1601 // find newest available ...
1602 if( year>=roads[i].intro && year<roads[i].retire ) {
1603 if( desc==0 || desc->get_intro_year_month()<test->get_intro_year_month() ) {
1604 desc = test;
1605 }
1606 }
1607 }
1608 }
1609 return desc;
1610 }
1611
1612
get_city_road_type(uint16 const year)1613 way_desc_t const* settings_t::get_city_road_type(uint16 const year)
1614 {
1615 return get_timeline_road_type(year, num_city_roads, city_roads );
1616 }
1617
1618
get_intercity_road_type(uint16 const year)1619 way_desc_t const* settings_t::get_intercity_road_type(uint16 const year)
1620 {
1621 return get_timeline_road_type(year, num_intercity_roads, intercity_roads );
1622 }
1623
1624
copy_city_road(settings_t const & other)1625 void settings_t::copy_city_road(settings_t const& other)
1626 {
1627 num_city_roads = other.num_city_roads;
1628 for( int i=0; i<10; i++ ) {
1629 city_roads[i] = other.city_roads[i];
1630 }
1631 }
1632
1633
set_default_player_color(uint8 player_nr,uint8 color1,uint8 color2)1634 void settings_t::set_default_player_color(uint8 player_nr, uint8 color1, uint8 color2)
1635 {
1636 if (player_nr < MAX_PLAYER_COUNT) {
1637 default_player_color[player_nr][0] = color1 < 28 ? color1 : 255;
1638 default_player_color[player_nr][1] = color2 < 28 ? color2 : 255;
1639 }
1640 }
1641
1642
1643 // returns default player colors for new players
set_player_color_to_default(player_t * const player) const1644 void settings_t::set_player_color_to_default(player_t* const player) const
1645 {
1646 karte_ptr_t welt;
1647 uint8 color1 = default_player_color[player->get_player_nr()][0];
1648 if( color1 == 255 ) {
1649 if( default_player_color_random ) {
1650 // build a vector with all colors
1651 minivec_tpl<uint8>all_colors1(28);
1652 for( uint8 i=0; i<28; i++ ) {
1653 all_colors1.append(i);
1654 }
1655 // remove all used colors
1656 for( uint8 i=0; i<MAX_PLAYER_COUNT; i++ ) {
1657 player_t *test_sp = welt->get_player(i);
1658 if( test_sp && player!=test_sp ) {
1659 uint8 rem = 1<<(player->get_player_color1()/8);
1660 if( all_colors1.is_contained(rem) ) {
1661 all_colors1.remove( rem );
1662 }
1663 }
1664 else if( default_player_color[i][0]!=255 ) {
1665 uint8 rem = default_player_color[i][0];
1666 if( all_colors1.is_contained(rem) ) {
1667 all_colors1.remove( rem );
1668 }
1669 }
1670 }
1671 // now choose a random empty color
1672 color1 = pick_any(all_colors1);
1673 }
1674 else {
1675 color1 = player->get_player_nr();
1676 }
1677 }
1678
1679 uint8 color2 = default_player_color[player->get_player_nr()][1];
1680 if( color2 == 255 ) {
1681 if( default_player_color_random ) {
1682 // build a vector with all colors
1683 minivec_tpl<uint8>all_colors2(28);
1684 for( uint8 i=0; i<28; i++ ) {
1685 all_colors2.append(i);
1686 }
1687 // remove color1
1688 all_colors2.remove( color1/8 );
1689 // remove all used colors
1690 for( uint8 i=0; i<MAX_PLAYER_COUNT; i++ ) {
1691 player_t *test_sp = welt->get_player(i);
1692 if( test_sp && player!=test_sp ) {
1693 uint8 rem = 1<<(player->get_player_color2()/8);
1694 if( all_colors2.is_contained(rem) ) {
1695 all_colors2.remove( rem );
1696 }
1697 }
1698 else if( default_player_color[i][1]!=255 ) {
1699 uint8 rem = default_player_color[i][1];
1700 if( all_colors2.is_contained(rem) ) {
1701 all_colors2.remove( rem );
1702 }
1703 }
1704 }
1705 // now choose a random empty color
1706 color2 = pick_any(all_colors2);
1707 }
1708 else {
1709 color2 = player->get_player_nr() + 3;
1710 }
1711 }
1712
1713 player->set_player_color( color1*8, color2*8 );
1714 }
1715