Index: simtool.cc =================================================================== --- simtool.cc (revision 10484) +++ simtool.cc (working copy) @@ -3945,91 +3945,109 @@ if(!slope_t::is_single(hang)) { return "Dock must be built on single slope!"; } - else { - // iterate up to max(len,1) to ensure that there is at least one tile of water - // in front of the dock - for(int i=0; i<=max(len,1); i++ ) { - if(!welt->is_within_limits(k-dx*i)) { - // need at least a single tile to navigate ... - return "Zu nah am Kartenrand"; - } - // search for nearby stops - const planquadrat_t* pl = welt->access(k-dx*i); - for( uint8 j=0; j < pl->get_boden_count(); j++ ) { - halthandle_t test_halt = pl->get_boden_bei(j)->get_halt(); - if(test_halt.is_bound()) { - if(!player_t::check_owner( player, test_halt->get_owner())) { - return "Das Feld gehoert\neinem anderen Spieler\n"; + + koord bau_pos = k; + int layout = 0; + koord dx2; + switch (hang) { + case slope_t::south: + case slope_t::south * 2: + layout = 0; + dx2 = koord::west; + break; + case slope_t::east: + case slope_t::east * 2: + layout = 1; + dx2 = koord::north; + break; + case slope_t::north: + case slope_t::north * 2: + layout = 2; + dx2 = koord::west; + bau_pos = k - desc->get_size(layout) + koord(1, 1); + break; + case slope_t::west: + case slope_t::west * 2: + layout = 3; + dx2 = koord::north; + bau_pos = k - desc->get_size(layout) + koord(1, 1); + break; + } + + const koord sz = desc->get_size( layout ); + + if( k==bau_pos && !welt->is_within_limits(k+sz+koord(1,1)) ) { + // need at least a single tile to navigate ... + return "Zu nah am Kartenrand"; + } + if( k!=bau_pos && !welt->is_within_limits(bau_pos-koord(1,1)) ) { + // need at least a single tile to navigate ... + return "Zu nah am Kartenrand"; + } + + // now we have the layout to test all relevant tiles + for( sint16 y = 0; y lookup_kartenboden(test_k)) { + if( !gr->is_water() ) { + // only allow at the side + bool stating_slope = (dx2 == koord::north && test_k.x==k.x) || (dx2 == koord::west && test_k.y==k.y); + if( stating_slope ) { + if( gr->get_grund_hang()!=hang ) { + return "Dock must be built on single slope!"; + } + // start tile on slope near water + if(gr->hat_wege() || gr->get_typ()!=grund_t::boden || gr->is_halt()) { + return NOTICE_TILE_FULL; + } } - else if(!halt.is_bound()) { - halt = test_halt; + else { + return NOTICE_UNSUITABLE_GROUND; } - else if(halt != test_halt) { - return "Several halts found."; + } + else { + // all other tiles in water (allowing one-tile docks on rivers) + if( !gr->is_water() && !(len==0 && i==1 && gr->hat_weg( water_wt )) ) { + return NOTICE_UNSUITABLE_GROUND; } + if( gr->find() || gr->get_depot() || gr->is_halt() ) { + return NOTICE_TILE_FULL; + } } - } - - // check whether we can build something - const grund_t *gr=welt->lookup_kartenboden(k-dx*i); - if (gr->get_hoehe() != pos.z) { - return NOTICE_UNSUITABLE_GROUND; - } - if (i <= len) { + // search for nearby stops + const planquadrat_t* pl = welt->access(test_k); + for( uint8 j=0; j < pl->get_boden_count(); j++ ) { + halthandle_t test_halt = pl->get_boden_bei(j)->get_halt(); + if(test_halt.is_bound()) { + if(!player_t::check_owner( player, test_halt->get_owner())) { + return "Das Feld gehoert\neinem anderen Spieler\n"; + } + else if(!halt.is_bound()) { + halt = test_halt; + } + else if(halt != test_halt) { + return "Several halts found."; + } + } + } + // can remove everything on it (shoudl be mostly empty anyway) if (const char *msg = gr->kann_alle_obj_entfernen(player)) { return msg; } } - - if (i==0) { - // start tile on slope near water - if(gr->hat_wege() || gr->get_typ()!=grund_t::boden || gr->is_halt()) { - return NOTICE_TILE_FULL; - } - } else { - // all other tiles in water (allowing one-tile docks on rivers) - if (!gr->is_water() && !(len==0 && i==1 && gr->hat_weg(water_wt))) { - return NOTICE_UNSUITABLE_GROUND; - } - if (gr->find() || gr->get_depot() || gr->is_halt()) { - return NOTICE_TILE_FULL; - } + dbg->error( "tool_station_dock_aux", "No ground inside the world at %s!", test_k.get_str() ); + return NOTICE_UNSUITABLE_GROUND; } } } + // todo: delete more than one tile + // remove everything from tile gr->obj_loesche_alle(player); - koord bau_pos = k; - int layout = 0; - koord dx2; - switch(hang) { - case slope_t::south: - case slope_t::south*2: - layout = 0; - dx2 = koord::west; - break; - case slope_t::east: - case slope_t::east*2: - layout = 1; - dx2 = koord::north; - break; - case slope_t::north: - case slope_t::north*2: - layout = 2; - dx2 = koord::west; - bau_pos = last_k; - break; - case slope_t::west: - case slope_t::west*2: - layout = 3; - dx2 = koord::north; - bau_pos = last_k; - break; - } - // handle 16 layouts bool change_layout = false; if(desc->get_all_layouts()==16) {