]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/train.cpp
Use different stopping margin depending on whether the next track is a turnout
[r2c2.git] / source / libr2c2 / train.cpp
index 0eaf1e9a0ec91fb62e6947ff15ae2a38851d378e..122ea9b18795ffcc64f4de01d065bd5d1fb46369 100644 (file)
@@ -443,8 +443,7 @@ void Train::unplace()
 
 bool Train::free_block(Block &block)
 {
-       float margin = 10*layout.get_catalogue().get_scale();
-       if(get_reserved_distance_until(&block, false)<controller->get_braking_distance()*1.3+margin)
+       if(get_reserved_distance_until(&block, false)<controller->get_braking_distance()*1.3)
                return false;
 
        unsigned nsens = 0;
@@ -534,7 +533,15 @@ int Train::get_entry_to_block(Block &block) const
 
 float Train::get_reserved_distance() const
 {
-       return get_reserved_distance_until(0, false);
+       if(blocks.empty())
+               return 0;
+
+       float margin = 0;
+       TrackIter next = blocks.back().next().track_iter();
+       if(next->get_type().is_turnout())
+               margin = 15*layout.get_catalogue().get_scale();
+
+       return max(get_reserved_distance_until(0, false)-margin, 0.0f);
 }
 
 void Train::tick(const Time::TimeStamp &t, const Time::TimeDelta &dt)
@@ -874,7 +881,10 @@ void Train::reserve_more()
                if(!block || block->get_endpoints().size()<2)
                {
                        if(!blocking_train)
+                       {
                                good_end = blocks.end();
+                               end_of_route = true;
+                       }
                        break;
                }
 
@@ -978,7 +988,7 @@ void Train::reserve_more()
                                contested_blocks.push_back(block);
                                continue;
                        }
-                       else if(divert_track && (entry_conflict || exit_conflict))
+                       else if(divert_track && (entry_conflict || exit_conflict || !other_train->is_active()))
                                // We are blocked, but there's a diversion possibility
                                try_divert = true;
 
@@ -1177,10 +1187,10 @@ unsigned Train::find_speed_step(float real) const
                if(real_speed[i].weight)
                {
                        last = i;
-                       if(real_speed[i].speed<real)
-                               low = i;
-                       else
+                       if(real_speed[i].speed>=real)
                                high = i;
+                       else if(real_speed[i].speed>real_speed[low].speed)
+                               low = i;
                }
        if(!high)
        {
@@ -1291,7 +1301,7 @@ bool Train::is_valid_diversion(const Route &diversion, const TrackIter &from)
 
                track1 = track1.next(path);
 
-               if(track1.looped())
+               if(!track1 || track1.looped())
                        return false;
        }
 
@@ -1309,6 +1319,8 @@ bool Train::is_valid_diversion(const Route &diversion, const TrackIter &from)
                bool ok = (track2!=from && diversion.has_track(*track2));
 
                track2 = track2.next(path);
+               if(!track2)
+                       return false;
 
                if(ok)
                        break;