//-------------------------------------------------------------------
//
//  This code is copyright 2001 by G5 Software.
//  Any unauthorized usage, either in part or in whole of this code
//  is strictly prohibited. Violators WILL be prosecuted to the
//  maximum extent allowed by law.
//
//-------------------------------------------------------------------

///////////////////////////////////
//
// Mission 11 -- Draw Attention
//
///////////////////////////////////
class CMission11_AIController extends CBaseAIController
{
  array  ActivatePointCenterList = array(
    vector( 4750, 6700, 0 ),     // Supply Tank Soviet Convoy
    vector( 4015, 6760, 0 ),
    vector( 2890, 5270, 0 ),     // Katusha FireLine
    vector( 2249, 3464, 0 ),     // Soviet Strike Point of attack
    vector( 3768, 6904, 0 ),     // Point of Nazi Cross placing
    vector( 3330, 8060, 0 ),     // Point of Reserve attack
    vector( 2273, 3790, 0 ),     // SovietStrike attacket GB10
    vector( 3651, 7273, 0 )      // Activate Defender Patrol
    );    //


  array  ActivatePointRadiusList = array(
    50.0,                       //
    50.0,
    50.0,
    100.0,
    150.0,
    100.0,
    100.0,
    50.0);

  array  ActivatePointNameList = array(
    "A",
    "B",
    "C",
    "D",
    "E",
    "F",
    "G",
    "H");

  boolean OnKatuchaStartsFire  = false;
  boolean OnKatuchaChangedFire = false;
  boolean OnKatuchaStopsFire   = false;
  boolean OnKatuchaStopsMoving = false;

  void OnObjectEnterArea( int _AreaIndex, string _NavPointName, string _ObjectID)
  {
    if ( _AreaIndex == 0
      && Core_IsStringStartsWith( _ObjectID, "11_Soviet_Tank"))
    {
      Core_BroadcastEvent("OnConvoySTankStop");
    }
    if ( _AreaIndex == 1
      && Core_IsStringStartsWith( _ObjectID, "11_Platoon"))
    {
      Core_BroadcastEvent("OnConvoySPlatoonStop");
    }
    if ( _AreaIndex == 2
      && Core_IsStringStartsWith( _ObjectID, "11_Katusha"))
    {
      if ( !OnKatuchaStopsMoving )
        {
          OnKatuchaStopsMoving = true;
          Core_BroadcastEvent("OnConvoyKatushaStop");
        }
    }
    if ( _AreaIndex == 3
      && Core_IsStringStartsWith( _ObjectID, "11_Soviet_Strike"))
    {
      Core_BroadcastEvent("OnSovietSrikeStop");
    }
    if ( _AreaIndex == 4
      && Core_IsStringStartsWith( _ObjectID, "11_Soviet_Strike"))
    {
      if ( !OnKatuchaStartsFire )
        {
          OnKatuchaStartsFire = true;
          Core_BroadcastEvent("OnKatushaStartFire");
        }
    }
    if ( _AreaIndex == 6
      && Core_IsStringStartsWith( _ObjectID, "11_Soviet_Strike"))
    {
      Core_BroadcastEvent("OnKatushaStopFire");
    }
    if ( _AreaIndex == 7
      && Core_IsStringStartsWith( _ObjectID, "11_Soviet_Strike"))
    {
      Core_BroadcastEvent("OnDefenderStarts");
    }
    if ( Core_IsStringStartsWith( _NavPointName, "NavPoint_Change")
         && Core_IsStringStartsWith( _ObjectID, "11_Soviet_Strike"))
      {
        if ( !OnKatuchaChangedFire )
          {
            OnKatuchaChangedFire = true;
            Core_BroadcastEvent("Katusha_ChangeFire");
          }
      }
    if ( Core_IsStringStartsWith( _NavPointName, "NavPoint_Stop")
         && Core_IsStringStartsWith( _ObjectID, "11_Soviet_Strike"))
      {
        if ( !OnKatuchaStopsFire )
          {
            OnKatuchaStopsFire = true;
            Core_BroadcastEvent("Katusha_StopFire");
          }
      }
    if ( _AreaIndex == 5
      && Core_IsStringStartsWith( _ObjectID, "11_Katusha"))
    {
      Core_BroadcastEvent("OnNaziReserveStart");
    }
    if ( _AreaIndex == 4
      && Core_IsStringStartsWith( _ObjectID, "11_Nazi_Reserve"))
    {
      Core_BroadcastEvent("OnNaziReserveAttack");
    }
  }
}
//===============================================================================
class C11_NaziGB10_Tank extends CBaseAITask_BaseTask
{
  float  DisperceRadius = 50;
  float  OvertakeSpeed  = 25;
  void OnEnemyTargeted()
    {
    string EnemyID = GetTargetedEnemy();
    SetFireStyle_Enemy( EnemyID);
    GiveOrder_Disperse();
    }
  void GiveOrder_Disperse()
    {
    // set state
    SetOrder_StopNow();
        SetOrder_MoveTo(
            GetNowPosition() + vector( rand(DisperceRadius), rand(DisperceRadius), 0.0),
            OvertakeSpeed);
    }
}
//-----------------------------------------------------------------------------------
class C11_GB10_Defend extends C11_Soviet_Tank
{

  float OvertakeSpeed = 30;

  void OnDefenderStarts()
  {
    DestinationPoint = GetNavPoint("NavPoint_04");
    GiveOrder_MoveToTarget();
  }
  void OnConvoySTankStop()
  {
    ClearState();
  }

  void Init()
  {
    DestinationPoint = GetNavPoint("NavPoint_04");
    // give start order
    // GiveOrder_MoveToTarget();
  }

  void OnEnemyTargeted()
  {
    string EnemyID = GetTargetedEnemy();
    SetFireStyle_Enemy( EnemyID);
    GiveOrder_Disperse();
  }
  void GiveOrder_MoveToTarget()
  {
    //Core_LogMessage("" + Core_GetIdentificator() + ": order: move to target");

    string Leader = GetCommander("GB10Defend_Rank"); // find leader that we should followed by
    if ( Moving == true
      && Leader == CurLeader)
    {
      // nothing changed
      return;
    }

    // set state
    ClearState();
    Moving = true;
    CurLeader = Leader;

    if ( Leader == "")
    {
      // we are leader. go directly to destination
      SetOrder_MoveTo(
        DestinationPoint,
        CruiserSpeed);
    }
    else
    {
      // leader found. follow him
      SetOrder_Follow(
        Leader, // follow leader
        AutocadDistanceMin,
        AutocadDistanceOptimum,
        AutocadDistanceOvertake,
        CruiserSpeed,
        OvertakeSpeed);
    }
  }

}
///-----------------------------------------------------------------------
class C11_NaziGB9_Tank extends C11_NaziGB10_Tank
{
  void Unit_Destroyed( string ObjectID )
  {
    if ( Core_IsStringStartsWith( ObjectID, "11_Nazi_GB9_" ))
    {
      Core_BroadcastEvent( "Base09UnderAttack" );
    }
  }
}
//===========================================================================
class C11_Cross extends CNavPointUser, CBaseAITask_BaseTask
{
  boolean Attacked        = false;
  float   DisperceRadius  = 50;
  float OvertakeSpeed     = 30;
  void OnEnemyTargeted()
  {
    string EnemyID = GetTargetedEnemy();
    SetFireStyle_Enemy( EnemyID);
    GiveOrder_Disperse();
  }

  void GiveOrder_Disperse()
  {
    // set state
    SetOrder_StopNow();

        // move to random point
        SetOrder_MoveTo(
            GetNowPosition() + vector( rand(DisperceRadius), rand(DisperceRadius), 0.0),
            OvertakeSpeed);
  }

  void OnNoEnemy()
  {
    SetOrder_StopNow();
  }

  void Unit_Destroyed( string ObjectID )
  {
    if ( (Core_IsStringStartsWith( ObjectID, "11_Cross" )) && (!Attacked) )
    {
      string EnemyID = GetTargetedEnemy();
      SetFireStyle_Enemy( EnemyID);

      Core_BroadcastEvent( "CrossRoadUnderAttack" );
      Attacked = true;
    }
  }
}
//=====================================================================
class C11_Soviet_Katusha extends CBaseAITask_BaseTask, CNavPointUser
     //CNavPointUser, CBaseAITask_BaseTask
{
  //
  // convoy parameters

  vector   DestinationPoint        = GetNavPoint("NavPoint_04");//GetNavPoint("NavPoint_04"); // where to go
  vector   FormationVector         = vector( -20, 0, 0);
  vector   PointOfFire             = vector( 2100, 3485, 130 );
  float    CruiserSpeed            = 25; // autocade with guard should keep this speed
  float    RunSpeed                = 25; // autocade wo guards should keep this speed
  float    OvertakeSpeed           = 28; // maximum allowed speed for overtake
  float    AutocadDistanceMin      = 20; // nearest allowed distance in autocade
  float    AutocadDistanceOptimum  = 25; // try to keep this distance in autocade
  float    AutocadDistanceOvertake = 30; // overtake distance
  float    DisperceRadius          = 60;
  string   CurLeader               = "";
  boolean  IsLeader                = false;
  boolean  OnTanksStops            = false;

  //
  // current state

  boolean  Moving   = false; // true when object is moving to destination
  boolean  Ambushed = false; // true when object is under ambush
  boolean  Retreat  = false; // true when object is retreating
  boolean  Run      = false; // true when object is running without stop to destination

  boolean MovingStatus = false;
  boolean m_MessageOnDisplay = false;

  void OnConvoyKatushaStop()
  {
      string Leader = GetCommander("SovietKatusha_Rank");
      OnTanksStops = true;
      if ( Leader != "" )
        {
        SetOrder_Formation(
          Leader,
          FormationVector,
          10, //#TMP
          15, //#TMP
          OvertakeSpeed/2,
          OvertakeSpeed/2);
        }
      if ( !m_MessageOnDisplay )
       {
        m_MessageOnDisplay = true;
        Core_SendEventTo(
            "Helicopter",
            "ShowEventPoint",
            vector( 2890, 5270, 0 ), //        - point to show
            80.0                    //        - distance from camera to point
        );
       }
  }

  void ClearState()
  {
    Moving    = false;
    Ambushed  = false;
    Retreat   = false;
    Run       = false;
    CurLeader = "";
    IsLeader  = false;
  }
  void OnKatushaStartFire()
   {
//   PointOfFire = vector( 2100, 3485, 130 );
    if ( OnTanksStops )
     {
//       Core_LogMessage("Katusha has been start of fire "+PointOfFire);
       SetFireStyle_Place( PointOfFire );
       Core_SendEventTo(
            "Helicopter",
            "ShowEventPoint",
            vector( 2890, 5270, 0 ), //        - point to show
            80.0                    //        - distance from camera to point
        );
     }
   }

  void Katusha_ChangeFire()
  {
    if ( OnTanksStops )
     {
       PointOfFire = vector( 2350, 3470, 140 );
//       Core_LogMessage("Katusha has been changed point of fire "+PointOfFire);
       SetFireStyle_Place( PointOfFire );
     }
  }
  void Katusha_StopFire()
   {
//    Core_LogMessage("Katusha has been stop fire");
    SetFireStyle_NoFire();
   }
  // start up initialization
  void Init()
  {
//    PointOfFire      = GetNavPoint("NavPoint_05");
    DestinationPoint = GetNavPoint("NavPoint_04");
    SetFireStyle_NoFire();
    // give start order
    GiveOrder_MoveToTarget();
  }

  void OnEnemyTargeted()
  {
    if ( !OnTanksStops )
    {
      GiveOrder_Disperse();
    }
  }

  void GiveOrder_Disperse()
  {
    // set state
    ClearState();
    Ambushed = true;

    SetOrder_StopNow();

        // move to random point
        SetOrder_MoveTo(
            GetNowPosition() + vector( rand(DisperceRadius), rand(DisperceRadius), 0.0),
            OvertakeSpeed);
  }

  void OnNoEnemy()
  {
    if ( !OnTanksStops )
      {
      GiveOrder_MoveToTarget();
      }
  }

  void GiveOrder_MoveToTarget()
  {
    //Core_LogMessage("" + Core_GetIdentificator() + ": order: move to target");

    string Leader = GetCommander("SovietKatusha_Rank"); // find leader that we should followed by
    if ( Moving == true
      && Leader == CurLeader)
    {
      // nothing changed
      return;
    }

    // set state
    ClearState();
    Moving = true;
    CurLeader = Leader;

    if ( Leader == "")
    {
      // we are leader. go directly to destination
      SetOrder_MoveTo(
        DestinationPoint,
        CruiserSpeed);
    }
    else
    {
      // leader found. follow him
      SetOrder_Follow(
        Leader, // follow leader
        AutocadDistanceMin,
        AutocadDistanceOptimum,
        AutocadDistanceOvertake,
        CruiserSpeed,
        OvertakeSpeed);
    };
  }

  void OnLeaderLost( string _LeaderID)
  {
    // reorder
    GiveOrder_MoveToTarget();
  }
};

//---------------------------------------------------------------------
class C11_NaziReserve extends C11_Soviet_Tank
{
  vector   DestinationPoint = GetNavPoint( "NavPoint_01" ); // where to go
  vector   FormationVector  = vector( -20, 5, 0);
  float    CruiserSpeed     = 29; // autocade with guard should keep this speed
  float    RunSpeed         = 29; // autocade wo guards should keep this speed
  float    OvertakeSpeed    = 30; // maximum allowed speed for overtake

  boolean ReserveStop        = false;
  boolean m_MessageOnDisplay = false;

  void Init()
    {
    DestinationPoint = GetNavPoint( "NavPoint_01" );
//    GiveOrder_MoveToTarget();
    }
  void OnEnemyTargeted()
    {
      if ( ReserveStop)
      {
        string EnemyID = GetTargetedEnemy();
        SetFireStyle_Enemy( EnemyID);
        GiveOrder_Disperse();
      }
    }

  void OnNaziReserveAttack()
    {
      ReserveStop = true;
    }
  void OnNaziReserveStart()
   {
    GiveOrder_MoveToTarget();
    if ( !m_MessageOnDisplay )
     {
        m_MessageOnDisplay = true;
        Core_SendEventTo(
            "Helicopter",
            "ShowEventObject",
            "11_Nazi_Reserve_03",   //        - point to show
            80.0                    //        - distance from camera to point
        );
     }
   }
  void OnStopped()
    {
    if( ReserveStop )
      {
        SetOrder_StopNow();
      }
    }
  // void OnSovietSrikeStop()
  //  {
  //  ReserveStop = true;
  //  }

  void GiveOrder_MoveToTarget()
    {
    //Core_LogMessage("" + Core_GetIdentificator() + ": order: move to target");

    string Leader = GetCommander("NaziReserve_Rank"); // find leader that we should followed by
    if ( Moving == true
      && Leader == CurLeader)
      {
      // nothing changed
      return;
      }

    // set state
    ClearState();
    Moving = true;
    CurLeader = Leader;

    if ( Leader == "")
      {
      // we are leader. go directly to destination
      SetOrder_MoveTo(
        DestinationPoint,
        CruiserSpeed);
      }
    else
      {
      // leader found. follow him
      SetOrder_Follow(
        Leader, // follow leader
        AutocadDistanceMin,
        AutocadDistanceOptimum,
        AutocadDistanceOvertake,
        CruiserSpeed,
        OvertakeSpeed);
      }
    }
}
//---------------------------------------------------------------------
class C11_NaziAAReserve extends C11_Soviet_Tank
{
  vector   DestinationPoint = GetNavPoint( "NavPoint_01" ); // where to go
  vector   FormationVector  = vector( -20, 5, 0);
  float    CruiserSpeed     = 30; // autocade with guard should keep this speed
  float    RunSpeed         = 30; // autocade wo guards should keep this speed
  float    OvertakeSpeed    = 32; // maximum allowed speed for overtake
  boolean  ReserveStop      = false;

  void Init()
    {
    DestinationPoint = GetNavPoint( "NavPoint_01" );
//    GiveOrder_MoveToTarget();
    }
  void OnNaziReserveStart()
    {
    GiveOrder_MoveToTarget();
    }
  void OnStopped()
    {
    if( ReserveStop )
      {
        SetOrder_StopNow();
      }
    }
  void OnEnemyTargeted()
    {
      if ( ReserveStop)
      {
        string EnemyID = GetTargetedEnemy();
        SetFireStyle_Enemy( EnemyID);
        GiveOrder_Disperse();
      }
    }
  void GiveOrder_MoveToTarget()
    {
    //Core_LogMessage("" + Core_GetIdentificator() + ": order: move to target");

    string Leader = GetCommander("NaziAAReserve_Rank"); // find leader that we should followed by
    if ( Moving == true
      && Leader == CurLeader)
      {
      // nothing changed
      return;
      }

    // set state
    ClearState();
    Moving = true;
    CurLeader = Leader;

    if ( Leader == "")
      {
      // we are leader. go directly to destination
      SetOrder_MoveTo(
        DestinationPoint,
        CruiserSpeed);
      }
    else
      {
      // leader found. follow him
      SetOrder_Follow(
        Leader, // follow leader
        AutocadDistanceMin,
        AutocadDistanceOptimum,
        AutocadDistanceOvertake,
        CruiserSpeed,
        OvertakeSpeed);
      }
    }
}

//---------------------------------------------------------------------
class C11_Soviet_Strike extends C11_Soviet_Tank
{
  vector   DestinationPoint        = vector( 2249, 3464, 0 ); // where to go
  vector   FormationVector         = vector( -20, 5, 0);
  float    CruiserSpeed            = 26; // autocade with guard should keep this speed
  float    RunSpeed                = 26; // autocade wo guards should keep this speed
  float    OvertakeSpeed           = 28; // maximum allowed speed for overtake

  void Init()
  {
    DestinationPoint = vector( 2249, 3464, 0 );
    GiveOrder_MoveToTarget();
  }
  void OnSovietSrikeStop()
  {
    SetOrder_StopNow();
  }

    void GiveOrder_MoveToTarget()
  {
    //Core_LogMessage("" + Core_GetIdentificator() + ": order: move to target");

    string Leader = GetCommander("SovietStrike_Rank"); // find leader that we should followed by
    if ( Moving == true
      && Leader == CurLeader)
    {
      // nothing changed
      return;
    }

    // set state
    ClearState();
    Moving = true;
    CurLeader = Leader;

    if ( Leader == "")
    {
      // we are leader. go directly to destination
      SetOrder_MoveTo(
        DestinationPoint,
        CruiserSpeed);
    }
    else
    {
      // leader found. follow him
      SetOrder_Follow(
        Leader, // follow leader
        AutocadDistanceMin,
        AutocadDistanceOptimum,
        AutocadDistanceOvertake,
        CruiserSpeed,
        OvertakeSpeed);
    }
  }
}
// ---------------------------------------------------------------------
class C11_Soviet_Tank extends CBaseAITask_BaseTask, CNavPointUser
     //CNavPointUser, CBaseAITask_BaseTask
{
  //
  // convoy parameters

  vector   DestinationPoint        = vector( 4750, 6700, 0); // where to go
  vector   FormationVector         = vector( -20, 5, 0);
  float    CruiserSpeed            = 27; // autocade with guard should keep this speed
  float    RunSpeed                = 27; // autocade wo guards should keep this speed
  float    OvertakeSpeed           = 30; // maximum allowed speed for overtake
  float    AutocadDistanceMin      = 20; // nearest allowed distance in autocade
  float    AutocadDistanceOptimum  = 25; // try to keep this distance in autocade
  float    AutocadDistanceOvertake = 30; // overtake distance
  float    DisperceRadius          = 50;
  string   CurLeader               = "";
  boolean  IsLeader                = false;
  boolean OnTanksStops             = false;

  //
  // current state

  boolean  Moving   = false; // true when object is moving to destination
  boolean  Ambushed = false; // true when object is under ambush
  boolean  Retreat  = false; // true when object is retreating
  boolean  Run      = false; // true when object is running without stop to destination

  boolean MovingStatus = false;

  void OnConvoySTankStop()
  {
      OnTanksStops = true;
      string Leader = GetCommander("SovietTank_Rank");
      if ( Leader != "" )
        {
        SetOrder_Formation(
          Leader,
          FormationVector,
          10, //#TMP
          15, //#TMP
          OvertakeSpeed/2,
          OvertakeSpeed/2);
        }
  }

  void ClearState()
  {
    Moving    = false;
    Ambushed  = false;
    Retreat   = false;
    Run       = false;
    CurLeader = "";
    IsLeader  = false;
  }

  //
  // start up initialization

  void Init()
  {
    DestinationPoint = vector( 4750, 6700, 0);
    // give start order
    GiveOrder_MoveToTarget();
  }

//  void OnUpdate()
//  {
//  }
  //
  // orders

  void OnEnemyTargeted()
  {
    string EnemyID = GetTargetedEnemy();
    SetFireStyle_Enemy( EnemyID);
    GiveOrder_Disperse();
  }

  void GiveOrder_Disperse()
  {
    // set state
    ClearState();
    Ambushed = true;

    SetOrder_StopNow();

        // move to random point
        SetOrder_MoveTo(
            GetNowPosition() + vector( rand(DisperceRadius), rand(DisperceRadius), 0.0),
            OvertakeSpeed);
  }

  void OnNoEnemy()
  {
      GiveOrder_MoveToTarget();
  }

  void GiveOrder_MoveToTarget()
  {
    //Core_LogMessage("" + Core_GetIdentificator() + ": order: move to target");

    string Leader = GetCommander("SovietTank_Rank"); // find leader that we should followed by
    if ( Moving == true
      && Leader == CurLeader)
    {
      // nothing changed
      return;
    }

    // set state
    ClearState();
    Moving = true;
    CurLeader = Leader;

    if ( Leader == "")
    {
      // we are leader. go directly to destination
      SetOrder_MoveTo(
        DestinationPoint,
        CruiserSpeed);
    }
    else
    {
      // leader found. follow him
      SetOrder_Follow(
        Leader, // follow leader
        AutocadDistanceMin,
        AutocadDistanceOptimum,
        AutocadDistanceOvertake,
        CruiserSpeed,
        OvertakeSpeed);
    }
  }

  void OnLeaderLost( string _LeaderID)
  {
    // reorder
    GiveOrder_MoveToTarget();
  }
}
// -----------------------------------------------------------------------------
class C11_Platoon extends CBaseAITask_BaseTask, CNavPointUser
{
  //
  // convoy parameters

  vector   DestinationPoint        = vector( 4015, 6760, 0); // where to go
  vector   FormationVector         = vector( 5, -90, 0);
  float    CruiserSpeed            = 20; // autocade with guard should keep this speed
  float    RunSpeed                = 20; // autocade wo guards should keep this speed
  float    OvertakeSpeed           = 25; // maximum allowed speed for overtake
  float    AutocadDistanceMin      = 20; // nearest allowed distance in autocade
  float    AutocadDistanceOptimum  = 25; // try to keep this distance in autocade
  float    AutocadDistanceOvertake = 30; // overtake distance
  float    DisperceRadius          = 50;
  string   CurLeader               = "";
  boolean  IsLeader                = false;
  boolean OnTanksStops             = false;

  //
  // current state

  boolean  Moving   = false; // true when object is moving to destination
  boolean  Ambushed = false; // true when object is under ambush
  boolean  Retreat  = false; // true when object is retreating
  boolean  Run      = false; // true when object is running without stop to destination

  boolean MovingStatus = false;

  void OnConvoySPlatoonStop()
  {
    if ( !OnTanksStops )
      {
        OnTanksStops = true;
        SetOrder_Formation(
          Leader,
          FormationVector,
          45, //#TMP
          15, //#TMP
          OvertakeSpeed/2,
          OvertakeSpeed/2);
      }
  }

  void ClearState()
  {
    Moving    = false;
    Ambushed  = false;
    Retreat   = false;
    Run       = false;
    CurLeader = "";
    IsLeader  = false;
  }

  //
  // start up initialization

  void Init()
  {
    SetFireStyle_Nearest();
    DestinationPoint = vector( 4015, 6760, 0);
    // give start order
  }

  void CrossRoadUnderAttack()
    {
      GiveOrder_MoveToTarget();
    }

//  void OnUpdate()
//  {
//  }
  //
  // orders

  void OnEnemyTargeted()
  {
    string EnemyID = GetTargetedEnemy();
    SetFireStyle_Enemy( EnemyID);
    GiveOrder_Disperse();
  }

  void GiveOrder_Disperse()
  {
    // set state
    ClearState();
    Ambushed = true;

    SetOrder_StopNow();

        // move to random point
        SetOrder_MoveTo(
            GetNowPosition() + vector( rand(DisperceRadius), rand(DisperceRadius), 0.0),
            OvertakeSpeed);
  }

  void OnNoEnemy()
  {
      GiveOrder_MoveToTarget();
  }

  void GiveOrder_MoveToTarget()
  {
    //Core_LogMessage("" + Core_GetIdentificator() + ": order: move to target");

    string Leader = GetCommander("Platoon_Rank"); // find leader that we should followed by
    if ( Moving == true
      && Leader == CurLeader)
    {
      // nothing changed
      return;
    }

    // set state
    ClearState();
    Moving = true;
    CurLeader = Leader;

    if ( Leader == "")
    {
      // we are leader. go directly to destination
      SetOrder_MoveTo(
        DestinationPoint,
        CruiserSpeed);
    }
    else
    {
      // leader found. follow him
      SetOrder_Follow(
        Leader, // follow leader
        AutocadDistanceMin,
        AutocadDistanceOptimum,
        AutocadDistanceOvertake,
        CruiserSpeed,
        OvertakeSpeed);
    };
  }

  void OnLeaderLost( string _LeaderID)
  {
    // reorder
    GiveOrder_MoveToTarget();
  }
};


