]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/aicontrol.cpp
Make AIControl states clearer
[r2c2.git] / source / libr2c2 / aicontrol.cpp
index c2f16e38a898a0efbdc702bdfe14fabbe84d82dd..2d48bf764a3f498047a078a34965461fc2985c2d 100644 (file)
@@ -19,8 +19,7 @@ AIControl::AIControl(Train &t, Controller *n):
        train(t),
        next_ctrl(n),
        target_speed(Control::continuous("speed", 0, 1000)),
-       blocked(false),
-       approach(false)
+       state(NORMAL)
 {
        target_speed.set(0);
 
@@ -41,10 +40,10 @@ void AIControl::set_control(const string &n, float v)
                        train.set_active(true);
 
                target_speed.set(v);
-               if(!blocked)
+               if(state!=BLOCKED)
                {
                        float approach_speed = 5*train.get_layout().get_catalogue().get_scale();
-                       if(approach && target_speed.value>approach_speed)
+                       if(state==APPROACH && target_speed.value>approach_speed)
                                next_ctrl->set_control("speed", approach_speed);
                        else
                                next_ctrl->set_control("speed", target_speed.value);
@@ -88,26 +87,36 @@ void AIControl::tick(const Time::TimeDelta &dt)
        float approach_speed = 5*scale;
        float margin = 10*scale;
 
-       if(!blocked && rsv_dist<brake_dist+margin)
-       {
-               blocked = true;
-               next_ctrl->set_control("speed", 0);
-       }
-       else if((!approach && rsv_dist<brake_dist*1.3+approach_margin) || (blocked && rsv_dist>brake_dist+margin*2))
+       State old_state = state;
+
+       if(state==FOLLOW && !train.get_preceding_train())
+               state = NORMAL;
+
+       if(rsv_dist<brake_dist+margin)
+               state = BLOCKED;
+       else if(rsv_dist>brake_dist+margin*2 && rsv_dist<brake_dist*1.3+approach_margin)
+               state = APPROACH;
+       else if(rsv_dist>brake_dist*1.3+approach_margin*2)
+               state = NORMAL;
+
+       if(state==NORMAL && train.get_preceding_train())
+               state = FOLLOW;
+
+       if(state!=old_state || state==FOLLOW)
        {
-               blocked = false;
-               approach = true;
-               if(target_speed.value>approach_speed)
-                       next_ctrl->set_control("speed", approach_speed);
+               float speed_limit = -1;
+               if(state==BLOCKED)
+                       speed_limit = 0;
+               else if(state==APPROACH)
+                       speed_limit = approach_speed;
+               else if(state==FOLLOW)
+                       speed_limit = train.get_preceding_train()->get_speed();
+
+               if(speed_limit>=0 && target_speed.value>speed_limit)
+                       next_ctrl->set_control("speed", speed_limit);
                else
                        next_ctrl->set_control("speed", target_speed.value);
        }
-       else if((blocked || approach) && rsv_dist>brake_dist*1.3+approach_margin*2)
-       {
-               blocked = false;
-               approach = false;
-               next_ctrl->set_control("speed", target_speed.value);
-       }
 
        next_ctrl->tick(dt);