diff --git a/simhalt.cc b/simhalt.cc index 4d4630417..b7fa8c3a7 100644 --- a/simhalt.cc +++ b/simhalt.cc @@ -2356,6 +2356,99 @@ void haltestelle_t::make_public_and_join( player_t *player ) } +// merge stop +void haltestelle_t::merge_halt( player_t *player, halthandle_t halt_merged ) +{ + player_t *const public_owner = welt->get_public_player(); + + // process every tile of stop + slist_tpl joining; + FOR(slist_tpl, const& i, tiles) { + grund_t* const gr = i.grund; + gebaeude_t* gb = gr->find(); + if( gb ) { + gb->set_flag(obj_t::dirty); + } + + // search for stops to join, starting with this tile + const planquadrat_t *pl = welt->access(gr->get_pos().get_2d()); + for( uint8 i=0; i < pl->get_boden_count(); i++ ) { + halthandle_t my_halt = pl->get_boden_bei(i)->get_halt(); + if( my_halt.is_bound() && !joining.is_contained(my_halt) ) { + joining.append(my_halt); + } + } + } + + // search for stops merged to + FOR(slist_tpl, const& i, halt_merged->get_tiles()) { + grund_t* const gr = i.grund; + gebaeude_t* gb = gr->find(); + if( gb ) { + gb->set_flag(obj_t::dirty); + } + + const planquadrat_t *pl2 = welt->access(gr->get_pos().get_2d()); + for( uint8 i=0; i < pl2->get_boden_count(); i++ ) { + halthandle_t my_halt = pl2->get_boden_bei(i)->get_halt(); + if( my_halt.is_bound() && !joining.is_contained(my_halt) ) { + joining.append(my_halt); + } + } + } + + // set name to name of first stop + if( !joining.empty() ) { + set_name( joining.front()->get_name()); + } + + while( !joining.empty() ) { + // join this halt with me + halthandle_t halt = joining.remove_first(); + + // now with the second stop + while( halt.is_bound() && halt!=self ) { + // add statistics + for( int month=0; monthfinancial_history[month][type]; + halt->financial_history[month][type] = 0; // to avoid counting twice + } + } + + // we always take the first remaining tile and transfer it => more safe + koord3d t = halt->get_basis_pos3d(); + grund_t *gr = welt->lookup(t); + + // transfer tiles to us + halt->rem_grund(gr); + add_grund(gr); + // and check for existence + if(!halt->existiert_in_welt()) { + // transfer goods + halt->transfer_goods(self); + + // rebuild connections of all linked halts + // otherwise these halts would lose connections and freight might get lost + // (until complete rebuild_connections task is finished) + halt->rebuild_linked_connections(); + + destroy(halt); + } + } + } + + // tell the world of it ... + if( player != public_owner && env_t::networkmode ) { + cbuffer_t buf; + buf.printf( translator::translate("%s at (%i,%i) now merged to %s at (%i,%i)."), halt_merged->get_name(), halt_merged->get_basis_pos().x, halt_merged->get_basis_pos().y, get_name(), get_basis_pos().x, get_basis_pos().y ); + welt->get_message()->add_message( buf, get_basis_pos(), message_t::ai, PLAYER_FLAG|player->get_player_nr(), IMG_EMPTY ); + } + + recalc_station_type(); +} + + void haltestelle_t::transfer_goods(halthandle_t halt) { if (!self.is_bound() || !halt.is_bound()) { diff --git a/simhalt.h b/simhalt.h index a0f581630..35fb59f13 100644 --- a/simhalt.h +++ b/simhalt.h @@ -429,6 +429,8 @@ public: void make_public_and_join( player_t *player ); + void merge_halt( player_t *player, halthandle_t halt_merged ); + vector_tpl const& get_pax_connections() const { return all_links[goods_manager_t::INDEX_PAS].connections; } vector_tpl const& get_mail_connections() const { return all_links[goods_manager_t::INDEX_MAIL].connections; } diff --git a/simhalt.h.gch b/simhalt.h.gch new file mode 100644 index 000000000..38df1f6ed Binary files /dev/null and b/simhalt.h.gch differ diff --git a/simmenu.cc b/simmenu.cc index 1a2d94a25..cc80883c6 100644 --- a/simmenu.cc +++ b/simmenu.cc @@ -120,6 +120,7 @@ tool_t *create_general_tool(int toolnr) case TOOL_CHANGE_WATER_HEIGHT: tool = new tool_change_water_height_t(); break; case TOOL_SET_CLIMATE: tool = new tool_set_climate_t(); break; case TOOL_ROTATE_BUILDING: tool = new tool_rotate_building_t(); break; + case TOOL_MERGE_STOP: tool = new tool_merge_stop_t(); break; default: dbg->error("create_general_tool()","cannot satisfy request for general_tool[%i]!",toolnr); return NULL; } diff --git a/simmenu.h b/simmenu.h index 9a6f46f95..de3a4ba92 100644 --- a/simmenu.h +++ b/simmenu.h @@ -73,6 +73,7 @@ enum { TOOL_CHANGE_WATER_HEIGHT, TOOL_SET_CLIMATE, TOOL_ROTATE_BUILDING, + TOOL_MERGE_STOP, GENERAL_TOOL_COUNT, GENERAL_TOOL = 0x1000 }; diff --git a/simmenu.h.gch b/simmenu.h.gch new file mode 100644 index 000000000..e837aff16 Binary files /dev/null and b/simmenu.h.gch differ diff --git a/simres.d b/simres.d new file mode 100644 index 000000000..1369acbe0 --- /dev/null +++ b/simres.d @@ -0,0 +1 @@ +build/default/simres.o: simres.rc simversion.h diff --git a/simtool.cc b/simtool.cc index 2ef8def6a..bc0d46ad4 100644 --- a/simtool.cc +++ b/simtool.cc @@ -6200,7 +6200,6 @@ bool tool_daynight_level_t::init( player_t * ) { } - /* make all tiles of this player a public stop * if this player is public, make all connected tiles a public stop */ bool tool_make_stop_public_t::init( player_t * ) @@ -6370,6 +6369,53 @@ const char *tool_make_stop_public_t::work( player_t *player, koord3d p ) } +/* merge stop */ +image_id tool_merge_stop_t::get_marker_image() +{ + return cursor; +} + +uint8 tool_merge_stop_t::is_valid_pos( player_t *player, const koord3d &pos, const char *&error, const koord3d &) +{ + grund_t *bd = welt->lookup(pos); + if (bd==NULL) { + error = ""; + return 0; + } + // check halt ownership + halthandle_t h = haltestelle_t::get_halt(pos,player); + if( h.is_bound() && !player_t::check_owner( player, h->get_owner() ) ) { + error = "Das Feld gehoert\neinem anderen Spieler\n"; + return 0; + } + // check for halt on the tile + if( h.is_bound() && ( bd->is_halt() || (h->get_station_type()&haltestelle_t::dock && bd->is_water()) ) ) { + return 2; + } + error = NOTICE_UNSUITABLE_GROUND; + return 0; +} + +const char *tool_merge_stop_t::do_work( player_t *player, const koord3d &last_pos, const koord3d &pos) +{ + halt_be_merged_from = halthandle_t(); + halt_be_merged_to = halthandle_t(); + + //grund_t *gr = welt->lookup(pos); + halt_be_merged_from = haltestelle_t::get_halt(last_pos,player); + halt_be_merged_to = haltestelle_t::get_halt(pos,player); + + if( ( halt_be_merged_to.is_bound() && player_t::check_owner(halt_be_merged_to->get_owner(), player) ) && + ( halt_be_merged_from.is_bound() && player_t::check_owner(halt_be_merged_from->get_owner(), player) ) ) { + // merge stop + halt_be_merged_to->merge_halt(player, halt_be_merged_from); + return NULL; + } + + // nothing to do + return NULL; +} + bool tool_show_trees_t::init( player_t * ) { diff --git a/simtool.h b/simtool.h index a9bb98707..5b06a57b6 100644 --- a/simtool.h +++ b/simtool.h @@ -613,6 +613,24 @@ public: }; +/* merge stop */ +class tool_merge_stop_t : public two_click_tool_t { +private: + halthandle_t halt_be_merged_from; + halthandle_t halt_be_merged_to; +public: + tool_merge_stop_t() : two_click_tool_t(TOOL_MERGE_STOP | GENERAL_TOOL) {} + char const* get_tooltip(player_t const*) const OVERRIDE { return translator::translate("merge stop"); } + bool is_init_network_save() const OVERRIDE { return true; } + +private: + char const* do_work(player_t*, koord3d const&, koord3d const&) OVERRIDE; + void mark_tiles(player_t*, koord3d const&, koord3d const&) OVERRIDE {} + uint8 is_valid_pos(player_t*, koord3d const&, char const*&, koord3d const&) OVERRIDE; + image_id get_marker_image() OVERRIDE; +}; + + // internal tool: show error message at specific coordinate // used for scenario error messages send by server class tool_error_message_t : public tool_t {