Index: dataobj/settings.cc =================================================================== --- dataobj/settings.cc (revision 9140) +++ dataobj/settings.cc (working copy) @@ -62,8 +62,8 @@ // default climate zones set_default_climates( ); + groundwater = -2; winter_snowline = 7; // not mediterranean - groundwater = -2; max_mountain_height = 160; //can be 0-160.0 map_roughness = 0.6; //can be 0-1 @@ -305,8 +305,12 @@ void settings_t::set_default_climates() { - static sint16 borders[MAX_CLIMATES] = { 0, -3, -2, 3, 6, 8, 10, 10 }; - memcpy( climate_borders, borders, sizeof(sint16)*MAX_CLIMATES ); + static sint16 borders[MAX_CLIMATES+1] = { -3, -3, -2, 3, 6, 8, 9, 10, 11 }; + for( int i = 0; i < MAX_CLIMATES; i++ ) { + climate_borders[i][0] = borders[i]; + climate_borders[i][1] = borders[i+1]; + } + climate_borders[0][1] = borders[0]; } @@ -455,30 +459,49 @@ filename = ""; } - // climate borders - if(file->is_version_atleast(91, 0)) { - if( file->is_version_less(120, 6) ) { - climate_borders[arctic_climate] -= groundwater; + // climate borders, no overlapping borders are possible + if( file->is_version_atleast(91, 0) ){ + if( file->is_version_less(121,1) ) { + sint16 old_climate_borders[ MAX_CLIMATES ]; + for( int cl = 0; cl < MAX_CLIMATES; cl++ ) { + old_climate_borders[cl] = climate_borders[cl][0]; + } + if( file->is_version_less(120, 6) ) { + old_climate_borders[arctic_climate] -= groundwater; + } + for( int i=0; i<8; i++ ) { + file->rdwr_short(old_climate_borders[i] ); + } + if( file->is_version_less(120, 6) ) { + old_climate_borders[arctic_climate] += groundwater; + } + + if( file->is_loading() && file->is_version_less(112, 7) ) { + groundwater *= env_t::pak_height_conversion_factor; + for( int i = 0; i < MAX_CLIMATES; i++ ) { + old_climate_borders[i] *= env_t::pak_height_conversion_factor; + } + } + // convert to new borders if loading, es keep the current + if( file->is_loading() ) { + for( int cl = 0; cl < MAX_CLIMATES-1; cl++ ) { + climate_borders[cl][0] = old_climate_borders[cl]; + climate_borders[cl][1] = old_climate_borders[cl+1]; + } + climate_borders[0][1] = old_climate_borders[0]; + climate_borders[arctic_climate][1] = old_climate_borders[arctic_climate]; + } } - for( int i=0; i<8; i++ ) { - file->rdwr_short(climate_borders[i] ); + else { + for( int i=0; i<8; i++ ) { + file->rdwr_short( climate_borders[i][0] ); + file->rdwr_short( climate_borders[i][1] ); + } } - if( file->is_version_less(120, 6) ) { - climate_borders[arctic_climate] += groundwater; - } - file->rdwr_short(winter_snowline ); + file->rdwr_short( winter_snowline ); } - if( file->is_loading() && file->is_version_less(112, 7) ) { - groundwater *= env_t::pak_height_conversion_factor; - for( int i = 0; i < 8; i++ ) { - climate_borders[i] *= env_t::pak_height_conversion_factor; - } - winter_snowline *= env_t::pak_height_conversion_factor; - way_height_clearance = env_t::pak_height_conversion_factor; - } - - // since vehicle will need realignment afterwards! + // vehicle may need realignment afterwards! if(file->is_version_less(99, 19)) { vehicle_base_t::set_diagonal_multiplier( pak_diagonal_multiplier, 1024 ); } Index: dataobj/settings.h =================================================================== --- dataobj/settings.h (revision 9140) +++ dataobj/settings.h (working copy) @@ -11,8 +11,6 @@ #include "../simtypes.h" #include "../simconst.h" - - class player_t; class loadsave_t; class tabfile_t; @@ -119,10 +117,9 @@ /** * waterlevel, climate borders, lowest snow in winter */ - sint16 groundwater; - sint16 climate_borders[MAX_CLIMATES]; sint16 winter_snowline; + sint16 climate_borders[MAX_CLIMATES][2]; double max_mountain_height; double map_roughness; @@ -430,9 +427,9 @@ uint8 get_just_in_time() const {return just_in_time;} void set_default_climates(); - const sint16 *get_climate_borders() const { return climate_borders; } + sint8 get_climate_borders( sint8 climate, sint8 start_end ) const { return climate_borders[climate][start_end]; } - sint16 get_winter_snowline() const {return winter_snowline;} + sint16 get_winter_snowline() const { return winter_snowline; } void rotate90() { rotation = (rotation+1)&3; Index: gui/climates.cc =================================================================== --- gui/climates.cc (revision 9140) +++ gui/climates.cc (working copy) @@ -25,83 +25,91 @@ gui_frame_t( translator::translate("Climate Control") ) { sets = sets_par; - set_table_layout(2,0); + set_table_layout(1,0); - // Water level - new_component("Water level"); + add_table( 2, 0 ); + { + // Water level + new_component("Water level"); + water_level.init( sets->get_groundwater(), -20*(ground_desc_t::double_grounds?2:1), 20, gui_numberinput_t::AUTOLINEAR, false ); + water_level.add_listener( this ); + add_component( &water_level ); - water_level.init( sets->get_groundwater(), -20*(ground_desc_t::double_grounds?2:1), 20, gui_numberinput_t::AUTOLINEAR, false ); - water_level.add_listener( this ); - add_component( &water_level ); + // Height and roughness + int mountain_height_start = (int)sets->get_max_mountain_height(); + int mountain_roughness_start = (int)(sets->get_map_roughness()*20.0 + 0.5)-8; - // Height and roughness - int mountain_height_start = (int)sets->get_max_mountain_height(); - int mountain_roughness_start = (int)(sets->get_map_roughness()*20.0 + 0.5)-8; + // Mountain height + new_component("Mountain height"); + mountain_height.init( mountain_height_start, 0, min(1000,100*(11-mountain_roughness_start)), 10, false ); + mountain_height.add_listener( this ); + add_component( &mountain_height ); - // Mountain height - new_component("Mountain height"); - mountain_height.init( mountain_height_start, 0, min(1000,100*(11-mountain_roughness_start)), 10, false ); - mountain_height.add_listener( this ); - add_component( &mountain_height ); + // Mountain roughness + new_component("Map roughness"); + mountain_roughness.init( mountain_roughness_start, 0, min(10, 11-((mountain_height_start+99)/100)), gui_numberinput_t::AUTOLINEAR, false ); + mountain_roughness.add_listener( this ); + add_component( &mountain_roughness ); - // Mountain roughness - new_component("Map roughness"); - mountain_roughness.init( mountain_roughness_start, 0, min(10, 11-((mountain_height_start+99)/100)), gui_numberinput_t::AUTOLINEAR, false ); - mountain_roughness.add_listener( this ); - add_component( &mountain_roughness ); + // summer snowline always starting above highest climate + new_component("Summer snowline"); + summer_snowline.init(SYSCOL_TEXT_HIGHLIGHT, gui_label_t::centered); + summer_snowline.buf().printf("%d", sets->get_climate_borders(arctic_climate,1) ); + summer_snowline.update(); + add_component( &summer_snowline ); - // summer snowline always starting above highest climate - new_component("Summer snowline"); + // Winter snowline + new_component("Winter snowline"); + snowline_winter.init( sets->get_winter_snowline(), sets->get_groundwater(), 127, gui_numberinput_t::AUTOLINEAR, false ); + snowline_winter.add_listener( this ); + add_component( &snowline_winter ); + } + end_table(); - summer_snowline.init(SYSCOL_TEXT_HIGHLIGHT, gui_label_t::centered); - summer_snowline.buf().printf("%d", sets->get_climate_borders()[arctic_climate] ); - summer_snowline.update(); - add_component( &summer_snowline ); - - // Winter snowline - new_component("Winter snowline"); - snowline_winter.init( sets->get_winter_snowline(), sets->get_groundwater(), 127, gui_numberinput_t::AUTOLINEAR, false ); - snowline_winter.add_listener( this ); - add_component( &snowline_winter ); - - // other climate borders ... - sint16 arctic = 0; - for( int i=desert_climate-1; i<=rocky_climate-1; i++ ) { - new_component( ground_desc_t::get_climate_name_from_bit((climate)(i+1)) ); - climate_borders_ui[i].init( sets->get_climate_borders()[i+1], sets->get_groundwater(), 127, gui_numberinput_t::AUTOLINEAR, false ); - climate_borders_ui[i].add_listener( this ); - add_component( climate_borders_ui+i ); - if(sets->get_climate_borders()[i+1]>arctic) { - arctic = sets->get_climate_borders()[i+1]; + add_table(3,0); + { + // other climate borders ... + sint16 arctic = 0; + for( int i=desert_climate-1; iget_climate_borders(i+1,0), sets->get_groundwater(), 127, gui_numberinput_t::AUTOLINEAR, false ); + climate_borders_ui[i][0].add_listener( this ); + add_component( &(climate_borders_ui[i][0]) ); + new_component( ground_desc_t::get_climate_name_from_bit((climate)(i+1)) ); + climate_borders_ui[i][1].init( sets->get_climate_borders(i+1,1), sets->get_climate_borders(i+1,0), 127, gui_numberinput_t::AUTOLINEAR, false ); + climate_borders_ui[i][1].add_listener( this ); + add_component( &(climate_borders_ui[i][1]) ); } } - snowline_winter.set_limits( sets->get_groundwater(), arctic ); - snowline_winter.set_value( snowline_winter.get_value() ); + end_table(); no_tree.init( button_t::square_state, "no tree" ); no_tree.pressed = sets->get_no_trees(); no_tree.add_listener( this ); - add_component( &no_tree, 2); + add_component( &no_tree ); lake.init( button_t::square_state, "lake" ); lake.pressed = sets->get_lake(); lake.add_listener( this ); - add_component( &lake, 2 ); + add_component( &lake ); - new_component("Number of rivers"); - river_n.init( sets->get_river_number(), 0, 1024, gui_numberinput_t::POWER2, false ); - river_n.add_listener(this); - add_component( &river_n ); + add_table(2,0); + { + new_component("Number of rivers"); + river_n.init( sets->get_river_number(), 0, 1024, gui_numberinput_t::POWER2, false ); + river_n.add_listener(this); + add_component( &river_n ); - new_component("minimum length of rivers"); - river_min.init( sets->get_min_river_length(), 0, max(16,sets->get_max_river_length())-16, gui_numberinput_t::AUTOLINEAR, false ); - river_min.add_listener(this); - add_component( &river_min ); + new_component("minimum length of rivers"); + river_min.init( sets->get_min_river_length(), 0, max(16,sets->get_max_river_length())-16, gui_numberinput_t::AUTOLINEAR, false ); + river_min.add_listener(this); + add_component( &river_min ); - new_component("maximum length of rivers"); - river_max.init( sets->get_max_river_length(), sets->get_min_river_length()+16, 1024, gui_numberinput_t::AUTOLINEAR, false ); - river_max.add_listener(this); - add_component( &river_max ); + new_component("maximum length of rivers"); + river_max.init( sets->get_max_river_length(), sets->get_min_river_length()+16, 1024, gui_numberinput_t::AUTOLINEAR, false ); + river_max.add_listener(this); + add_component( &river_max ); + } + end_table(); reset_min_windowsize(); set_windowsize(get_min_windowsize()); @@ -125,12 +133,6 @@ else if(comp==&water_level) { sets->groundwater = (sint16)v.i; - // Update borders if necessary - for( int i=desert_climate-1; i<=rocky_climate-1; i++ ) { - climate_borders_ui[i].set_limits( sets->get_groundwater(), 127 ); - climate_borders_ui[i].set_value( climate_borders_ui[i].get_value() ); - } - if( welt_gui ) { welt_gui->update_preview(); } @@ -165,23 +167,24 @@ } // climate border buttons - // Arctic starts at maximum end of climate - sint16 arctic = 0; - for( int i=desert_climate; i<=rocky_climate; i++ ) { - if( comp==climate_borders_ui+i-1 ) { - sets->climate_borders[i] = (sint16)v.i; + for( int i=desert_climate; iclimate_borders[i][0] = (sint16)v.i; } - - if( sets->climate_borders[i] > arctic ) { - arctic = sets->climate_borders[i]; + if( comp==&(climate_borders_ui[i-1][1]) ) { + sets->climate_borders[i][1] = (sint16)v.i; } } - snowline_winter.set_limits( sets->get_groundwater()-1, arctic ); - snowline_winter.set_value( snowline_winter.get_value() ); - sets->climate_borders[arctic_climate] = arctic; + // Update borders + for( int i=desert_climate-1; i<=arctic_climate-1; i++ ) { + climate_borders_ui[i][0].set_limits( sets->get_groundwater(), 127 ); + climate_borders_ui[i][0].set_value( climate_borders_ui[i][0].get_value() ); + climate_borders_ui[i][1].set_limits( climate_borders_ui[i][0].get_value(), 127 ); + climate_borders_ui[i][1].set_value( climate_borders_ui[i][1].get_value() ); + } - summer_snowline.buf().printf("%d", sets->get_climate_borders()[arctic_climate] ); + summer_snowline.buf().printf("%d", sets->get_climate_borders(arctic_climate,1) ); summer_snowline.update(); return true; } Index: gui/climates.h =================================================================== --- gui/climates.h (revision 9140) +++ gui/climates.h (working copy) @@ -30,7 +30,7 @@ mountain_height, mountain_roughness, snowline_winter, - climate_borders_ui[rocky_climate]; + climate_borders_ui[MAX_CLIMATES][2]; gui_label_buf_t summer_snowline; Index: gui/map_frame.cc =================================================================== --- gui/map_frame.cc (revision 9140) +++ gui/map_frame.cc (working copy) @@ -228,11 +228,20 @@ add_component(&b_rotate45); // show contour - b_show_contour.init(button_t::square_state, "Show contour"); - b_show_contour.set_tooltip("Color-coded terrain according to altitude."); - b_show_contour.add_listener(this); - b_show_contour.pressed = (karte->get_display_mode() & minimap_t::MAP_HIDE_CONTOUR)==0; - add_component(&b_show_contour); + c_show_outlines.new_component( translator::translate( "Show contour" ), SYSCOL_TEXT ); + c_show_outlines.new_component( translator::translate( "Show climates" ), SYSCOL_TEXT ); + c_show_outlines.new_component( translator::translate( "Show outline" ), SYSCOL_TEXT ); + c_show_outlines.add_listener( this ); + if( env_t::default_mapmode & minimap_t::MAP_CLIMATES != 0 ) { + c_show_outlines.set_selection( 1 ); + } + else if( env_t::default_mapmode & minimap_t::MAP_HIDE_CONTOUR != 0 ) { + c_show_outlines.set_selection( 2 ); + } + else { + c_show_outlines.set_selection( 0 ); + } + add_component(&c_show_outlines); new_component(); } @@ -434,7 +443,7 @@ } -bool map_frame_t::action_triggered( gui_action_creator_t *comp, value_t) +bool map_frame_t::action_triggered( gui_action_creator_t *comp, value_t v ) { if( comp == &b_show_legend ) { show_hide_legend( !b_show_legend.pressed ); @@ -445,14 +454,18 @@ else if( comp == &b_show_directory ) { show_hide_directory( !b_show_directory.pressed ); } - else if( comp == &b_show_contour ) { - if( !b_show_contour.pressed ) { - b_show_contour.pressed = 1; + else if( comp == &c_show_outlines ) { + if( v.i == 2 ) { + env_t::default_mapmode |= minimap_t::MAP_HIDE_CONTOUR; + env_t::default_mapmode &= ~minimap_t::MAP_CLIMATES; + } + else if( v.i == 1 ) { + env_t::default_mapmode |= minimap_t::MAP_CLIMATES; env_t::default_mapmode &= ~minimap_t::MAP_HIDE_CONTOUR; } else { - b_show_contour.pressed = 0; - env_t::default_mapmode |= minimap_t::MAP_HIDE_CONTOUR; + env_t::default_mapmode &= ~minimap_t::MAP_CLIMATES; + env_t::default_mapmode &= ~minimap_t::MAP_HIDE_CONTOUR; } minimap_t::get_instance()->set_display_mode( ( minimap_t::MAP_DISPLAY_MODE)env_t::default_mapmode ); } Index: gui/map_frame.h =================================================================== --- gui/map_frame.h (revision 9140) +++ gui/map_frame.h (working copy) @@ -72,7 +72,7 @@ button_t b_rotate45; button_t b_show_legend; button_t b_show_scale; - button_t b_show_contour; + gui_combobox_t c_show_outlines; button_t b_show_directory; button_t b_overlay_networks; button_t b_overlay_networks_load_factor; Index: gui/minimap.cc =================================================================== --- gui/minimap.cc (revision 9140) +++ gui/minimap.cc (working copy) @@ -787,6 +787,10 @@ if( mode&MAP_HIDE_CONTOUR ) { color = color_idx_to_rgb(map_type_color[MAX_MAP_TYPE_WATER+2]); // lowest land color } + else if( mode&MAP_CLIMATES ) { + static uint8 climate_color[ 8 ] = { 0, COL_YELLOW, COL_LIGHT_GREEN, COL_GREEN, COL_DARK_GREEN, COL_DARK_YELLOW, COL_BROWN, COL_GREY4 }; + color = color_idx_to_rgb( climate_color[ world->get_climate(gr->get_pos().get_2d()) ] ); + } else { sint16 height = corner_sw(gr->get_grund_hang()); if( gr->get_hoehe() > world->get_groundwater() ) { Index: gui/minimap.h =================================================================== --- gui/minimap.h (revision 9140) +++ gui/minimap.h (working copy) @@ -62,6 +62,7 @@ MAP_LEVEL = 1<<21, MAP_WAITCHANGE = 1<<22, MAP_HIDE_CONTOUR = 1<<23, + MAP_CLIMATES = 1<<24, MAP_MODE_HALT_FLAGS = (MAP_STATUS|MAP_SERVICE|MAP_ORIGIN|MAP_TRANSFER|MAP_WAITING|MAP_WAITCHANGE), MAP_MODE_FLAGS = (MAP_TOWN|MAP_CITYLIMIT|MAP_STATUS|MAP_SERVICE|MAP_WAITING|MAP_WAITCHANGE|MAP_TRANSFER|MAP_LINES|MAP_FACTORIES|MAP_ORIGIN|MAP_DEPOT|MAP_TOURIST|MAP_PAX_DEST) Index: gui/settings_stats.cc =================================================================== --- gui/settings_stats.cc (revision 9140) +++ gui/settings_stats.cc (working copy) @@ -497,25 +497,22 @@ INIT_NUM_NEW( "Water level", sets->get_groundwater(), -20*(ground_desc_t::double_grounds?2:1), 20, gui_numberinput_t::AUTOLINEAR, false ); INIT_NUM_NEW( "Mountain height", mountain_height_start, 0, min(1000,100*(11-mountain_roughness_start)), 10, false ); INIT_NUM_NEW( "Map roughness", mountain_roughness_start, 0, min(10, 11-((mountain_height_start+99)/100)), gui_numberinput_t::AUTOLINEAR, false ); - SEPERATOR - INIT_LB( "Summer snowline" ); - summer = new_component(); - INIT_NUM( "Winter snowline", sets->get_winter_snowline(), sets->get_groundwater(), 127, gui_numberinput_t::AUTOLINEAR, false ); SEPERATOR - // other climate borders ... - sint16 arctic = 0; - for( int i=desert_climate; i!=arctic_climate; i++ ) { - INIT_NUM( ground_desc_t::get_climate_name_from_bit((climate)i), sets->get_climate_borders()[i], sets->get_groundwater(), 127, gui_numberinput_t::AUTOLINEAR, false ); - if(sets->get_climate_borders()[i]>arctic) { - arctic = sets->get_climate_borders()[i]; + INIT_LB( "" ); + add_table(3,0); + { + // other climate borders ... + sint16 arctic = 0; + for( int i=desert_climate; i<=arctic_climate; i++ ) { + INIT_NUM( ground_desc_t::get_climate_name_from_bit((climate)i), sets->get_climate_borders(i,0), sets->get_groundwater(), 127, gui_numberinput_t::AUTOLINEAR, false ); + gui_numberinput_t *ni = new_component(); + ni->init( sets->get_climate_borders(i,1), sets->get_groundwater(), 127, gui_numberinput_t::AUTOLINEAR, false ); + numinp.append( ni ); } } + end_table(); - cbuffer_t buf; - summer->buf().printf("%s %i", translator::translate( "Summer snowline" ), arctic ); - summer->update(); - SEPERATOR INIT_BOOL( "lake", sets->get_lake() ); INIT_NUM_NEW( "Number of rivers", sets->get_river_number(), 0, 1024, gui_numberinput_t::AUTOLINEAR, false ); @@ -551,19 +548,15 @@ if( new_world ) { sets->map_roughness = (n+8.0)/20.0; } - READ_NUM_VALUE( sets->winter_snowline ); // other climate borders ... sint16 arctic = 0; - for( int i=desert_climate; i!=arctic_climate; i++ ) { + for( int i=desert_climate; i<=arctic_climate; i++ ) { sint16 ch; READ_NUM_VALUE( ch ); - sets->climate_borders[i] = ch; - if( ch>arctic ) { - arctic = ch; - } + sets->climate_borders[i][0] = ch; + READ_NUM_VALUE( ch ); + sets->climate_borders[i][1] = ch; } - summer->buf().printf("%s %i", translator::translate( "Summer snowline" ), arctic ); - summer->update(); READ_BOOL_VALUE( sets->lake ); READ_NUM_VALUE_NEW( sets->river_number ); READ_NUM_VALUE_NEW( sets->min_river_length ); Index: simworld.cc =================================================================== --- simworld.cc (revision 9140) +++ simworld.cc (working copy) @@ -71,10 +71,12 @@ #include "network/network_file_transfer.h" #include "network/network_socket_list.h" #include "network/network_cmd_ingame.h" + #include "dataobj/height_map_loader.h" #include "dataobj/ribi.h" #include "dataobj/translator.h" #include "dataobj/loadsave.h" +#include "dataobj/marker.h" #include "dataobj/scenario.h" #include "dataobj/settings.h" #include "dataobj/environment.h" @@ -304,7 +306,7 @@ } const sint16 winterline = settings.get_winter_snowline(); - const sint16 summerline = settings.get_climate_borders()[arctic_climate] + 1; + const sint16 summerline = max(settings.get_climate_borders(arctic_climate,1),settings.get_climate_borders(arctic_climate,0)); snowline = summerline - (sint16)(((summerline-winterline)*factor)/100); if( old_snowline != snowline && set_pending ) { pending_snowline_change++; @@ -1619,30 +1621,26 @@ void karte_t::init_height_to_climate() { - // create height table - sint16 climate_border[MAX_CLIMATES]; - memcpy(climate_border, get_settings().get_climate_borders(), sizeof(climate_border)); - // set climate_border[0] to sea level - climate_border[0] = groundwater; - - for( int cl=0; clclimate_border[arctic_climate]) { - // unused climate - climate_border[cl] = groundwater-1; + // mark unused as arctic + memset( height_to_climate, arctic_climate, lengthof(height_to_climate) ); + memset( num_climates_at_height, 0, lengthof(num_climates_at_height) ); + + // now just add them, the later climates will win (we will do a fineer assessment later + for( int cl=0; cl= (sint16)h + groundwater && climate_border[cl] < current_height ) { - current_height = climate_border[cl]; - current_cl = cl; - } + for( int h = 0; h < 128; h++ ) { + if( h-groundwater > settings.get_climate_borders( arctic_climate, 1 ) && num_climates_at_height[h]==0 ) { + height_to_climate[h] = h==0 ? (uint8)arctic_climate : desert_climate; + num_climates_at_height[h] = 1; } - height_to_climate[h] = (uint8)current_cl; + if( num_climates_at_height[ h ] > 0 ) { + DBG_DEBUG( "init_height_to_climate()", "Height %i, climate %i, num_climates %i", h - groundwater, height_to_climate[ h ], num_climates_at_height[ h ] ); + } } } @@ -1850,12 +1848,15 @@ ls.set_progress(13); } - // set climates in new area and old map near seam - for( sint16 iy = 0; iy < new_size_y; iy++ ) { - for( sint16 ix = (iy >= old_y - 19) ? 0 : max( old_x - 19, 0 ); ix < new_size_x; ix++ ) { - calc_climate( koord( ix, iy ), false ); - } + // set climates in new area + if( old_x == 0 && old_y == 0 ) { + calc_climate_region( 0, 0, new_size_x, new_size_y ); } + else { + calc_climate_region( old_x, 0, new_size_x, new_size_y ); + calc_climate_region( 0, old_y, old_x, new_size_y ); + } + if ( old_x == 0 && old_y == 0 ) { ls.set_progress(14); } @@ -1979,7 +1980,8 @@ settings(env_t::default_settings), convoi_array(0), attractions(16), - stadt(0) + stadt(0), + climate_map(0,0) { destroying = false; @@ -5267,7 +5269,7 @@ if( file->is_version_less(112, 7) ) { // r7930 fixed a bug in init_height_to_climate // recover old behavior to not mix up climate when loading old savegames - groundwater = settings.get_climate_borders()[0]; + groundwater = settings.get_climate_borders(0,0); init_height_to_climate(); groundwater = settings.get_groundwater(); } @@ -5888,6 +5890,122 @@ } +// distributes climates in a rectangle +void karte_t::calc_climate_region( sint16 xtop, sint16 ytop, sint16 xbottom, sint16 ybottom ) +{ + sint32 points = (xbottom - xtop)*(ybottom - ytop); + + if( xtop == 0 && ytop == 0 ) { + climate_map.clear(); + } + climate_map.resize( xbottom, ybottom, 0xFF ); + + sint16 groundwater = settings.get_groundwater(); + + // first remove water and beach tiles from distribution effort + for( sint16 y = ytop; y < ybottom; y++ ) { + for( sint16 x = xtop; x < xbottom; x++ ) { + if( planquadrat_t *pl = access( x, y ) ) { + if( pl->get_kartenboden()->is_water() ) { + // full water tile + points--; + pl->set_climate( water_climate ); + pl->set_climate_transition_flag(false); + pl->set_climate_corners(0); + climate_map.at( x, y ) = water_climate; + } + else { + // test for beach tiles + grund_t *gr = pl->get_kartenboden(); + bool beach = false; + if( gr->get_pos().z == groundwater ) { + for( int i = 0; i < 8 && !beach; i++ ) { + grund_t *gr2 = lookup_kartenboden( koord(x,y) + koord::neighbours[i] ); + if( gr2 && gr2->is_water() ) { + beach = true; + } + } + } + sint8 rel_h = max( gr->get_pos().z - groundwater, 1 ); + if( beach || num_climates_at_height[rel_h] <= 1 ) { + // beach or only one climate + uint8 cl = beach ? desert_climate : (num_climates_at_height[rel_h] == 0 ? temperate_climate : height_to_climate[rel_h]); + points--; + pl->set_climate( (climate)cl ); + climate_map.at( x, y ) = cl; + pl->set_climate_transition_flag(false); + pl->set_climate_corners(0); + } + } + } + } + } + + /* Now all unmarked tiles are still pending to get their climate + * We will start an ellispe at the first tile than is inmarked with a random allowed climate for that height + * The region sizes depends on the map (within reason) + */ + const sint16 max_patchsize_x = clamp( 5, xbottom / 24, 256 ); + const sint16 max_patchsize_y = clamp( 5, ybottom / 24, 256 ); + + sint16 last_x = xtop, last_y = ytop; + minivec_tpl allowed( 8 ); + { + // find the next climateless tile + for( sint16 y = ytop; y < ybottom; y++ ) { + for( sint16 x = xtop; x < xbottom; x++ ) { + if( climate_map.at( x, y ) == 0xFF ) { + planquadrat_t *pl = access( x, y ); + grund_t *gr = pl->get_kartenboden(); + // not assigned yet => start with a random allowed climate + allowed.clear(); + for( int cl=1; clget_hoehe() >= settings.get_climate_borders( cl, 0 ) && gr->get_hoehe() <= settings.get_climate_borders( cl, 1 ) ) { + allowed.append(cl); + } + } + climate cl = (climate)allowed[ simrand( allowed.get_count() - 1 ) ]; + // now we do an ellipse with size wx and wy around the starting point + const sint32 wx = simrand( max_patchsize_x ); + const sint32 wy = simrand( max_patchsize_y ); + for( sint16 j = 0; j < wx; j++) { + for( sint16 i = 0; i < wy; i++) { + + const sint32 x_off = (j-(wx>>1)); + const sint32 y_off = (i-(wy>>1)); + if( x+x_off>=xtop && x+x_off=ytop && y+y_off 40 ) { + planquadrat_t *pl = access( x+x_off, y+y_off ); + grund_t *gr = pl->get_kartenboden(); + // find out if the climate is still allowed here + if( gr->get_hoehe() >= settings.get_climate_borders( cl, 0 ) && gr->get_hoehe() <= settings.get_climate_borders( cl, 1 ) ) { + points--; + pl->set_climate( cl ); + climate_map.at( x+x_off, y+y_off ) = cl; + pl->set_climate_transition_flag(false); + pl->set_climate_corners(0); + } + } + } + } + } + // all set = finish + if( points == 0 ) { + return; + } + } + } + } + } +} + + + + // fills array with neighbour heights void karte_t::get_neighbour_heights(const koord k, sint8 neighbour_height[8][4]) const { Index: simworld.h =================================================================== --- simworld.h (revision 9140) +++ simworld.h (working copy) @@ -15,6 +15,7 @@ #include "halthandle_t.h" #include "tpl/weighted_vector_tpl.h" +#include "tpl/array2d_tpl.h" #include "tpl/vector_tpl.h" #include "tpl/slist_tpl.h" @@ -256,8 +257,15 @@ * Table for fast conversion from height to climate. */ uint8 height_to_climate[128]; + uint8 num_climates_at_height[128]; /** + * Contains the intended climate for a tile + * (needed to restore tiles after height changes) + */ + array2d_tplclimate_map; + + /** * Array containing the convois. */ vector_tpl convoi_array; @@ -1343,8 +1351,6 @@ ~karte_t(); - - /** * File version used when loading (or current if generated) * @note Useful for finish_rd @@ -1617,6 +1623,11 @@ void calc_climate(koord k, bool recalc); /** + * Calculates appropriate climate for a region using elliptic areas for each + */ + void calc_climate_region( sint16 xtop, sint16 ytop, sint16 xbottom, sint16 ybottom ); + + /** * Rotates climate and water transitions for a tile */ void rotate_transitions(koord k); Index: tpl/array2d_tpl.h =================================================================== --- tpl/array2d_tpl.h (revision 9140) +++ tpl/array2d_tpl.h (working copy) @@ -7,6 +7,10 @@ #define TPL_ARRAY2D_TPL_H + +#include +#include + #include "../dataobj/koord.h" #include "../simdebug.h" @@ -47,6 +51,13 @@ return h; } + void clear() + { + delete [] data; + data = 0; + w = h = 0; + } + void init( T value ) { if(sizeof(T)==1) { @@ -60,7 +71,7 @@ } } - // YOu will loose all informations in the array + // all informations in the array are lost void resize(unsigned resize_x, unsigned resize_y ) { if( w*h != resize_x*resize_y ) { @@ -72,6 +83,28 @@ h = resize_y; } + // kepp old informations, new cell get default + void resize(unsigned resize_x, unsigned resize_y, T default_value ) + { + if( w*h != resize_x*resize_y ) { + T* new_data = new T[resize_x*resize_y]; + for( uint y = 0; y < resize_y; y++ ) { + for( uint x = 0; x < resize_x; x++ ) { + if( x < w && y < h ) { + new_data[ x + y*resize_x ] = data[x+y*w]; + } + else { + new_data[ x + y*resize_x ] = default_value; + } + } + } + delete [] data; + data = new_data; + } + w = resize_x; + h = resize_y; + } + T& at(unsigned x, unsigned y) { if( (int)((w-x)|(h-y))<0 ) {