Binary files sim_comp_original/.DS_Store and sim_comp_change/.DS_Store differ Binary files sim_comp_original/besch/.DS_Store and sim_comp_change/besch/.DS_Store differ diff -u -r sim_comp_original/besch/reader/way_reader.cc sim_comp_change/besch/reader/way_reader.cc --- sim_comp_original/besch/reader/way_reader.cc 2014-05-31 12:00:48.000000000 +0900 +++ sim_comp_change/besch/reader/way_reader.cc 2017-02-07 21:56:28.000000000 +0900 @@ -55,6 +55,7 @@ besch->obsolete_date = DEFAULT_RETIRE_DATE*12; besch->wt = road_wt; besch->styp = 0; + besch->overtaking_info = 0; besch->draw_as_obj = false; besch->number_seasons = 0; } @@ -63,7 +64,22 @@ const uint16 v = decode_uint16(p); version = v & 0x7FFF; - if(version==6) { + if(version==7) { + //version 7, now with overtaking_info + besch->cost = decode_uint32(p); + besch->maintenance = decode_uint32(p); + besch->topspeed = decode_uint32(p); + besch->max_weight = decode_uint32(p); + besch->intro_date = decode_uint16(p); + besch->obsolete_date = decode_uint16(p); + besch->axle_load = decode_uint16(p); + besch->wt = decode_uint8(p); + besch->styp = decode_uint8(p); + besch->overtaking_info = decode_sint8(p); //new + besch->draw_as_obj = decode_uint8(p); + besch->number_seasons = decode_sint8(p); + } + else if(version==6) { // version 6, now with axle load besch->cost = decode_uint32(p); besch->maintenance = decode_uint32(p); @@ -157,6 +173,10 @@ besch->axle_load = 9999; } + if( version < 7 ) { + besch->overtaking_info = 0; + } + // front images from version 5 on besch->front_images = version > 4; diff -u -r sim_comp_original/besch/weg_besch.h sim_comp_change/besch/weg_besch.h --- sim_comp_original/besch/weg_besch.h 2016-01-09 22:36:24.000000000 +0900 +++ sim_comp_change/besch/weg_besch.h 2017-02-07 23:19:43.000000000 +0900 @@ -68,6 +68,12 @@ bool front_images; /** + * Overtaking info (0 = overtaking is allowed, 1 = overtaking a loading convoy only, 2 = overtaking is completely forbidden) + * @author teamhimeH + */ + sint8 overtaking_info; + + /** * calculates index of image list for flat ways * for winter and/or front images * add +1 and +2 to get slope and straight diagonal images, respectively @@ -215,6 +221,10 @@ } void calc_checksum(checksum_t *chk) const; + + sint8 get_overtaking_info() const { + return overtaking_info; + } }; #endif diff -u -r sim_comp_original/besch/writer/way_writer.cc sim_comp_change/besch/writer/way_writer.cc --- sim_comp_original/besch/writer/way_writer.cc 2014-04-21 12:28:56.000000000 +0900 +++ sim_comp_change/besch/writer/way_writer.cc 2017-02-07 23:26:06.000000000 +0900 @@ -25,17 +25,18 @@ }; int ribi, hang; - obj_node_t node(this, 28, &parent); + obj_node_t node(this, 29, &parent); // Hajo: Version needs high bit set as trigger -> this is required // as marker because formerly nodes were unversionend - uint16 version = 0x8006; + uint16 version = 0x8007; uint32 price = obj.get_int("cost", 100); uint32 maintenance = obj.get_int("maintenance", 100); sint32 topspeed = obj.get_int("topspeed", 999); uint32 max_weight = obj.get_int("max_weight", 999); uint16 axle_load = obj.get_int("axle_load", 9999); + sint8 overtaking_info = obj.get_int("overtaking_info", 9999); uint16 intro = obj.get_int("intro_year", DEFAULT_INTRO_DATE) * 12; intro += obj.get_int("intro_month", 1) - 1; @@ -67,7 +68,8 @@ node.write_uint16(outfp, axle_load, 22); node.write_uint8 (outfp, wtyp, 24); node.write_uint8 (outfp, styp, 25); - node.write_uint8 (outfp, draw_as_ding, 26); + node.write_sint8 (outfp, overtaking_info, 26); + node.write_uint8 (outfp, draw_as_ding, 27); static const char* const image_type[] = { "", "front" }; @@ -76,7 +78,7 @@ sprintf(buf, "image[%s][0]", ribi_codes[0]); string str = obj.get(buf); if (str.empty()) { - node.write_data_at(outfp, &number_seasons, 27, 1); + node.write_data_at(outfp, &number_seasons, 28, 1); write_head(outfp, node, obj); sprintf(buf, "image[%s]", ribi_codes[0]); @@ -145,7 +147,7 @@ number_seasons++; } - node.write_data_at(outfp, &number_seasons, 27, 1); + node.write_data_at(outfp, &number_seasons, 28, 1); write_head(outfp, node, obj); // has switch images for both directions? Binary files sim_comp_original/boden/.DS_Store and sim_comp_change/boden/.DS_Store differ diff -u -r sim_comp_original/boden/wege/weg.h sim_comp_change/boden/wege/weg.h --- sim_comp_original/boden/wege/weg.h 2015-01-24 20:36:34.000000000 +0900 +++ sim_comp_change/boden/wege/weg.h 2017-02-07 16:29:16.000000000 +0900 @@ -221,6 +221,12 @@ const char *get_name() const { return besch->get_name(); } /** + * Overtaking info (0 = overtaking is allowed, 1 = overtaking a loading convoy only, 2 = overtaking is completely forbidden) + * @author teamhimeH + */ + sint8 get_overtaking_info() const { return besch->get_overtaking_info(); } + + /** * Setzt neue Richtungsbits für einen Weg. * * Nachdem die ribis geändert werden, ist das weg_bild des diff -u -r sim_comp_original/simconvoi.cc sim_comp_change/simconvoi.cc --- sim_comp_original/simconvoi.cc 2016-02-01 20:38:42.000000000 +0900 +++ sim_comp_change/simconvoi.cc 2017-02-07 16:40:27.000000000 +0900 @@ -1,9 +1,10 @@ /** * convoi_t Class for vehicle associations - * Hansjörg Malthaner + * Hansj�rg Malthaner */ #include +#include #include "simdebug.h" #include "simunits.h" @@ -31,6 +32,7 @@ #include "gui/convoi_detail_t.h" #include "boden/grund.h" #include "boden/wege/schiene.h" // for railblocks +#include "boden/wege/strasse.h" #include "besch/vehikel_besch.h" #include "besch/roadsign_besch.h" @@ -992,7 +994,7 @@ /** * Berechne route von Start- zu Zielkoordinate - * @author Hanjsörg Malthaner + * @author Hansjörg Malthaner */ bool convoi_t::drive_to() { @@ -1131,7 +1133,7 @@ /** * Ein Fahrzeug hat ein Problem erkannt und erzwingt die * Berechnung einer neuen Route - * @author Hanjsörg Malthaner + * @author Hanjs�rg Malthaner */ void convoi_t::suche_neue_route() { @@ -3529,9 +3531,11 @@ return false; } +/* if (!other_overtaker->can_be_overtaken()) { return false; } + */ if( other_speed == 0 ) { /* overtaking a loading convoi @@ -3547,6 +3551,12 @@ // also this is not possible, since a car loads in front of is!?! return false; } + //Overtaking info (0 = overtaking is allowed, 1 = overtaking a loading convoy only, 2 = overtaking is completely forbidden) + sint8 overtaking_info = str->get_overtaking_info(); + if( overtaking_info == 2 ){ + // This road prohibits overtaking. + return false; + } uint16 idx = fahr[0]->get_route_index(); const sint32 tiles = (steps_other-1)/(CARUNITS_PER_TILE*VEHICLE_STEPS_PER_CARUNIT) + get_tile_length() + 1; @@ -3568,11 +3578,15 @@ if( str->is_crossing() ) { return false; } + /* if( ribi_t::is_threeway(str->get_ribi()) ) { return false; } + */ // Check for other vehicles on the next tile const uint8 top = gr->get_top(); + //These conditions is abandoned to overtake in traffic jam. + /* for( uint8 j=1; j(gr->obj_bei(j)) ) { // check for other traffic on the road @@ -3587,15 +3601,28 @@ } } } + */ } convoi_t *ocnv = dynamic_cast(other_overtaker); set_tiles_overtaking( 2 + ocnv->get_length()/CARUNITS_PER_TILE + get_length()/CARUNITS_PER_TILE ); return true; } + //The flag whether the convoi is in traffic jam. When this is true, we must calculate overtaking in a different way. + bool in_congestion = false; int diff_speed = akt_speed - other_speed; if( diff_speed < kmh_to_speed(5) ) { - return false; + grund_t *gr = welt->lookup(get_pos()); + strasse_t *str=(strasse_t *)gr->get_weg(road_wt); + if( str==NULL ) { + printf("street is NULL!\n"); + return false; + }else if( akt_speed < fmin(max_power_speed, str->get_max_speed())/2 && diff_speed >= kmh_to_speed(0) ){ + //Warning: diff_speed == 0 is acceptable. We must consider the case diff_speed == 0. + in_congestion = true; + }else{ + return false; + } } // Number of tiles overtaking will take @@ -3604,10 +3631,16 @@ // Distance it takes overtaking (unit: vehicle_steps) = my_speed * time_overtaking // time_overtaking = tiles_to_overtake/diff_speed // tiles_to_overtake = convoi_length + current pos within tile + (pos_other_convoi within tile + length of other convoi) - one tile - int distance = akt_speed*(fahr[0]->get_steps()+get_length_in_steps()+steps_other-VEHICLE_STEPS_PER_TILE)/diff_speed; + int distance = 1; + if( !in_congestion ){ + distance = akt_speed*(fahr[0]->get_steps()+get_length_in_steps()+steps_other-VEHICLE_STEPS_PER_TILE)/diff_speed; + }else{ + distance = max_power_speed*(fahr[0]->get_steps()+get_length_in_steps()+steps_other-VEHICLE_STEPS_PER_TILE)/(max_power_speed-other_speed); + } + int time_overtaking = 0; - // Conditions for overtaking: + // Conditions for overtaking (originally): // Flat tiles, with no stops, no crossings, no signs, no change of road speed limit // First phase: no traffic except me and my overtaken car in the dangerous zone unsigned int route_index = fahr[0]->get_route_index()+1; @@ -3624,7 +3657,7 @@ pos_next = route.position_bei(route_index++); grund_t *gr = welt->lookup(pos); // no ground, or slope => about - if( gr==NULL || gr->get_weg_hang()!=hang_t::flach ) { + if( gr==NULL ) { return false; } @@ -3632,21 +3665,30 @@ if( str==NULL ) { return false; } + //Overtaking info (0 = overtaking is allowed, 1 = overtaking a loading convoy only, 2 = overtaking is completely forbidden) + sint8 overtaking_info = str->get_overtaking_info(); + if( overtaking_info != 0 ){ + // Since the other vehicle is moving... + return false; + } // the only roadsign we must account for are choose points and traffic lights if( str->has_sign() ) { const roadsign_t *rs = gr->find(1); if(rs) { const roadsign_besch_t *rb = rs->get_besch(); - if(rb->is_choose_sign() || rb->is_traffic_light() ) { + //We do not consider traffic-lights. This causes a drawing crash when vehicle stopped during overtaking. + if( rb->is_choose_sign() ) { // because we need to stop here ... return false; } } } // not overtaking on railroad crossings or on normal crossings ... + /* if( str->is_crossing() || ribi_t::is_threeway(str->get_ribi()) ) { return false; } + */ // street gets too slow (TODO: should be able to be correctly accounted for) if( akt_speed > kmh_to_speed(str->get_max_speed()) ) { return false; @@ -3664,7 +3706,12 @@ const overtaker_t *ov = v->get_overtaker(); if(ov) { if(this!=ov && other_overtaker!=ov) { - return false; + //If ov goes same directory, should not return false + ribi_t::ribi their_direction = ribi_t::rueckwaerts( fahr[0]->calc_direction(pos_prev, pos_next) ); + vehicle_base_t* const v = obj_cast(gr->obj_bei(j)); + if (v && v->get_direction() == their_direction && v->get_overtaker()) { + return false; + } } } else if( v->get_waytype()==road_wt && v->get_typ()!=obj_t::pedestrian ) { @@ -3727,8 +3774,9 @@ pos = pos_next; } - set_tiles_overtaking( 1+n_tiles ); - other_overtaker->set_tiles_overtaking( -1-(n_tiles*(akt_speed-diff_speed))/akt_speed ); + set_tiles_overtaking( 3+n_tiles ); + //The parameter about being overtaken is no longer meaningful. + //other_overtaker->set_tiles_overtaking( -1-(n_tiles*(akt_speed-diff_speed))/akt_speed ); return true; } diff -u -r sim_comp_original/simconvoi.h sim_comp_change/simconvoi.h --- sim_comp_original/simconvoi.h 2016-01-09 22:36:24.000000000 +0900 +++ sim_comp_change/simconvoi.h 2017-02-07 14:06:48.000000000 +0900 @@ -256,7 +256,7 @@ * The convoi is not processed every sync step for various actions * (like waiting before signals, loading etc.) Such action will only * continue after a waiting time larger than wait_lock - * @author Hanjsörg Malthaner + * @author Hanjsörg Malthaner */ sint32 wait_lock; @@ -268,7 +268,7 @@ /** * accumulated profit over a year - * @author Hanjsörg Malthaner + * @author Hanjsörg Malthaner */ sint64 jahresgewinn; @@ -307,14 +307,14 @@ /** * Calculate route from Start to Target Coordinate - * @author Hanjsörg Malthaner + * @author Hanjsörg Malthaner */ bool drive_to(); /** * Setup vehicles for moving in same direction than before * if the direction is the same as before - * @author Hanjsörg Malthaner + * @author Hanjsörg Malthaner */ bool can_go_alte_richtung(); @@ -328,7 +328,7 @@ /** * Mark first and last vehicle. - * @author Hanjsörg Malthaner + * @author Hanjsörg Malthaner */ void set_erstes_letztes(); @@ -462,13 +462,13 @@ /** * The handle for ourselves. In Anlehnung an 'this' aber mit * allen checks beim Zugriff. - * @author Hanjsörg Malthaner + * @author Hanjsörg Malthaner */ convoihandle_t self; /** * The profit in this year - * @author Hanjsörg Malthaner + * @author Hanjsörg Malthaner */ const sint64 & get_jahresgewinn() const {return jahresgewinn;} @@ -517,7 +517,7 @@ /** * Called if a vehicle enters a depot - * @author Hanjsörg Malthaner + * @author Hanjsörg Malthaner */ void betrete_depot(depot_t *dep); @@ -622,7 +622,7 @@ /** * When a vehicle has detected a problem * force calculate a new route - * @author Hanjsörg Malthaner + * @author Hanjsörg Malthaner */ void suche_neue_route(); @@ -739,7 +739,7 @@ /** * Setup vehicles before starting to move - * @author Hanjsörg Malthaner + * @author Hanjsörg Malthaner */ void vorfahren(); diff -u -r sim_comp_original/vehicle/overtaker.h sim_comp_change/vehicle/overtaker.h --- sim_comp_original/vehicle/overtaker.h 2015-11-29 19:51:22.000000000 +0900 +++ sim_comp_change/vehicle/overtaker.h 2017-02-07 14:08:44.000000000 +0900 @@ -60,6 +60,8 @@ virtual bool can_overtake(overtaker_t *other_overtaker, sint32 other_speed, sint16 steps_other) = 0; sint32 get_max_power_speed() const { return max_power_speed; } + + sint8 get_tiles_overtaking() const { return tiles_overtaking; } }; #endif diff -u -r sim_comp_original/vehicle/simvehicle.cc sim_comp_change/vehicle/simvehicle.cc --- sim_comp_original/vehicle/simvehicle.cc 2016-01-25 20:42:10.000000000 +0900 +++ sim_comp_change/vehicle/simvehicle.cc 2017-02-07 17:39:21.000000000 +0900 @@ -519,6 +519,8 @@ */ vehicle_base_t *vehicle_base_t::no_cars_blocking( const grund_t *gr, const convoi_t *cnv, const uint8 current_direction, const uint8 next_direction, const uint8 next_90direction ) { + bool cnv_overtaking = false;//whether this convoi is on passing lane. + if( cnv ) cnv_overtaking = cnv -> is_overtaking(); // Search vehicle for( uint8 pos=1; pos<(volatile uint8)gr->get_top(); pos++ ) { if( vehicle_base_t* const v = obj_cast(gr->obj_bei(pos)) ) { @@ -529,6 +531,7 @@ // check for car uint8 other_direction=255; bool other_moving = false; + bool other_overtaking = false; if( road_vehicle_t const* const at = obj_cast(v) ) { // ignore ourself if( cnv == at->get_convoi() ) { @@ -536,24 +539,27 @@ } other_direction = at->get_direction(); other_moving = at->get_convoi()->get_akt_speed() > kmh_to_speed(1); + other_overtaking = at->get_convoi()->is_overtaking();//whether the other convoi is on passing lane. } // check for city car else if( v->get_waytype() == road_wt ) { other_direction = v->get_direction(); if( private_car_t const* const sa = obj_cast(v) ){ other_moving = sa->get_current_speed() > 1; + other_overtaking = sa->is_overtaking(); } } - // ok, there is another car ... if( other_direction != 255 ) { - if( next_direction == other_direction && !ribi_t::is_threeway(gr->get_weg_ribi(road_wt)) ) { + if( next_direction == other_direction && !ribi_t::is_threeway(gr->get_weg_ribi(road_wt)) && cnv_overtaking == other_overtaking ) { + // only consider cars on same lane. // cars going in the same direction and no crossing => that mean blocking ... return v; } const ribi_t::ribi other_90direction = (gr->get_pos().get_2d() == v->get_pos_next().get_2d()) ? other_direction : calc_direction(gr->get_pos(), v->get_pos_next()); - if( other_90direction == next_90direction ) { + if( other_90direction == next_90direction && cnv_overtaking == other_overtaking ) { + //Whether this code is safe is not clear!!(can ignore cars on the other lane?) // Want to exit in same as other ~50% of the time return v; } @@ -561,7 +567,8 @@ const bool drives_on_left = welt->get_settings().is_drive_left(); const bool across = next_direction == (drives_on_left ? ribi_t::rotate45l(next_90direction) : ribi_t::rotate45(next_90direction)); // turning across the opposite directions lane const bool other_across = other_direction == (drives_on_left ? ribi_t::rotate45l(other_90direction) : ribi_t::rotate45(other_90direction)); // other is turning across the opposite directions lane - if( other_direction == next_direction && !(other_across || across) ) { + if( other_direction == next_direction && !(other_across || across) && cnv_overtaking == other_overtaking) { + // only consider cars on same lane. // entering same straight waypoint as other ~18% return v; } @@ -583,6 +590,7 @@ return v; } else if( other_direction == current_direction && current_90direction == ribi_t::keine ) { + // !It is not clear whether we should consider opposite lane in this case! // entering same diagonal waypoint as other ~1% return v; } @@ -2107,7 +2115,8 @@ uint32 test_index = route_index + 1u; // way should be clear for overtaking: we checked previously - if( !cnv->is_overtaking() ) { + // Now we have to consider even if convoi is overtaking! + //if( !cnv->is_overtaking() ) { // calculate new direction route_t const& r = *cnv->get_route(); koord3d next = route_index < r.get_count() - 1u ? r.position_bei(route_index + 1u) : pos_next; @@ -2121,6 +2130,43 @@ const bool drives_on_left = welt->get_settings().is_drive_left(); bool int_block = ribi_t::is_threeway(str->get_ribi_unmasked()) && (((drives_on_left ? ribi_t::rotate90l(curr_90direction) : ribi_t::rotate90(curr_90direction)) & str->get_ribi_unmasked()) || curr_90direction != next_90direction || (rs && rs->get_besch()->is_traffic_light())); + //If this convoi is overtaking, the convoi must avoid a head-on crash. + if( cnv->is_overtaking() ){ + while( test_index < route_index + 4u && test_index < r.get_count() ){ + grund_t *grn = welt->lookup(r.position_bei(test_index)); + for( uint8 pos=1; pos<(volatile uint8)grn->get_top(); pos++ ){ + if( vehicle_base_t* const v = obj_cast(grn->obj_bei(pos)) ){ + if( v->get_typ()==obj_t::pedestrian ) { + continue; + } + ribi_t::ribi other_direction=255; + if( road_vehicle_t const* const at = obj_cast(v) ) { + //ignore ourself + if( cnv == at->get_convoi() ){ + continue; + } + other_direction = at->get_direction(); + } + //check for city car + else if( v->get_waytype() == road_wt ) { + other_direction = v->get_direction(); + } + if( other_direction != 255 ){ + //There is another car. We have to check if this convoi is facing or not. + //calc_direction(next,get_pos()):opposite direction of next_direction. + if( calc_direction(next,get_pos()) == other_direction ) { + //printf("crash avoid. Dist:%d\n", test_index-route_index); + cnv->set_tiles_overtaking(0); + } + } + } + } + test_index++; + } + } + + test_index = route_index + 1u;//reset test_index + // check exit from crossings and intersections, allow to proceed after 4 consecutive while( !obj && (str->is_crossing() || int_block) && test_index < r.get_count() && test_index < route_index + 4u ) { if( str->is_crossing() ) { @@ -2216,10 +2262,11 @@ } } } - } + //} // stuck message ... if( obj && !second_check_count ) { + /* if( obj->is_stuck() ) { // end of traffic jam, but no stuck message, because previous vehicle is stuck too restart_speed = 0; @@ -2227,23 +2274,26 @@ cnv->reset_waiting(); } else { + */ if( test_index == route_index + 1u ) { // no intersections or crossings, we might be able to overtake this one ... - overtaker_t *over = obj->get_overtaker(); - if( over && !over->is_overtaken() ) { + convoi_t *over = obj->get_overtaker_cv(); + if( over ) { + /* if( over->is_overtaking() ) { // otherwise we would stop every time being overtaken return true; } + */ // not overtaking/being overtake: we need to make a more thought test! if( road_vehicle_t const* const car = obj_cast(obj) ) { convoi_t* const ocnv = car->get_convoi(); - if( cnv->can_overtake( ocnv, (ocnv->get_state()==convoi_t::LOADING ? 0 : over->get_max_power_speed()), ocnv->get_length_in_steps()+ocnv->get_vehikel(0)->get_steps()) ) { + if( !cnv->is_overtaking() && can_change_lane() && cnv->can_overtake( ocnv, (ocnv->get_state()==convoi_t::LOADING ? 0 : over->get_akt_speed()), ocnv->get_length_in_steps()+ocnv->get_vehikel(0)->get_steps()) ) { return true; } } else if( private_car_t* const caut = obj_cast(obj) ) { - if( cnv->can_overtake(caut, caut->get_besch()->get_geschw(), VEHICLE_STEPS_PER_TILE) ) { + if( !cnv->is_overtaking() && can_change_lane() && cnv->can_overtake(caut, caut->get_besch()->get_geschw(), VEHICLE_STEPS_PER_TILE) ) { return true; } } @@ -2251,8 +2301,11 @@ } // we have to wait ... restart_speed = (cnv->get_akt_speed()*3)/4; - cnv->set_tiles_overtaking(0); - } + //While on passing lane and blocked by other vehicle, if possible, go back to traffic lane. + if( cnv->is_overtaking() && can_change_lane()){ + cnv->set_tiles_overtaking(0); + } + //} } return obj==NULL; @@ -2267,6 +2320,50 @@ return cnv; } +//return overtaker in "convoi_t" +convoi_t* road_vehicle_t::get_overtaker_cv() +{ + return cnv; +} + +bool road_vehicle_t::can_change_lane(){ + //This function calculate whether the convoi can change lane. + if( leading ){ + route_t const& r = *cnv->get_route(); + //check whether there's no car in -1 ~ +1 section. + for(uint32 test_index = route_index == 0 ? 0 : route_index - 1u; test_index <= route_index + 1u && test_index < r.get_count(); test_index++){ + grund_t *gr = welt->lookup(r.position_bei(test_index)); + for( uint8 pos=1; pos<(volatile uint8)gr->get_top(); pos++ ) { + if( vehicle_base_t* const v = obj_cast(gr->obj_bei(pos)) ) { + if( v->get_typ()==obj_t::pedestrian ) { + continue; + } + if( road_vehicle_t const* const at = obj_cast(v) ) { + // ignore ourself + if( cnv == at->get_convoi() ) { + continue; + } + if( cnv->is_overtaking() && at->get_convoi()->is_overtaking() ){ + continue; + } + if( !cnv->is_overtaking() && !(at->get_convoi()->is_overtaking()) ){ + //Prohibit going on passing lane when facing traffic exists. + ribi_t::ribi other_direction = at->get_direction(); + route_t const& r = *cnv->get_route(); + koord3d next = route_index < r.get_count() - 1u ? r.position_bei(route_index + 1u) : pos_next; + if( calc_direction(next,get_pos()) == other_direction ) { + return false; + } + continue; + } + return false; + } + } + } + } + } + return true; +} void road_vehicle_t::enter_tile(grund_t* gr) { @@ -2275,9 +2372,15 @@ const int cargo = get_total_cargo(); weg_t *str = gr->get_weg(road_wt); str->book(cargo, WAY_STAT_GOODS); - if (leading) { + if ( leading ) { str->book(1, WAY_STAT_CONVOIS); cnv->update_tiles_overtaking(); + //decide if overtaking convoi should go back to the traffic lane. + if( cnv->get_tiles_overtaking() == 1 && str->get_overtaking_info() == 0 ){ + if( !can_change_lane() ){ + cnv->set_tiles_overtaking(3); + } + } } } diff -u -r sim_comp_original/vehicle/simvehicle.h sim_comp_change/vehicle/simvehicle.h --- sim_comp_original/vehicle/simvehicle.h 2015-11-29 19:51:22.000000000 +0900 +++ sim_comp_change/vehicle/simvehicle.h 2017-02-07 14:10:05.000000000 +0900 @@ -164,6 +164,7 @@ virtual void leave_tile(); virtual overtaker_t *get_overtaker() { return NULL; } + virtual convoi_t* get_overtaker_cv() { return NULL; } vehicle_base_t(); @@ -511,6 +512,9 @@ schedule_t * generate_new_schedule() const; virtual overtaker_t* get_overtaker(); + virtual convoi_t* get_overtaker_cv(); + + virtual bool can_change_lane(); };