# File generated by Wizard 2.9.0 on Feb 3, 2026.
processor bs_fueling WSF_SCRIPT_PROCESSOR
   update_interval 10 s
   script_variables 
      double fuelRate = 50.0;
      Array<string> mplatforms = Array<string> ();
      bool isFuel = false;
      double addFuelRange = 30000;
      WsfGeoPoint p1 = WsfGeoPoint.Construct("32:04:34.53n 130:51:05.36e");
      string CenterPoint = "23:49:20.14n 121:01:08.01e";
      double Radius = 50000;
      bool isOver = false;
      string zoneName = "JY01";
      string shape = "polygon"; //polygon  circle
      bool aendflag = false;
   end_script_variables

    
   
   //
   // @ generateCirclePoints
   //
   script Array<WsfGeoPoint> generateCirclePoints(string Center , double radius)
      WsfGeoPoint center = WsfGeoPoint.Construct(Center);
      Array<WsfGeoPoint> circlePoints = {};
      double earthRadius = 6371000.0;
      double angularDistance = radius / earthRadius;
      Array<double> angles = {10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,290,300,310,320,330,340,350,360};
      foreach(double angle in angles)
      {
         double latCenter = center.Latitude() * MATH.PI() / 180.0;
         double lonCenter = center.Longitude() * MATH.PI() / 180.0;
         
         double lat = MATH.ASin(MATH.Sin(latCenter)
                      * MATH.Cos(angularDistance) 
                      + MATH.Cos(latCenter) 
                      * MATH.Sin(angularDistance) 
                      * MATH.Cos(angle));
         double lon = lonCenter + MATH.ATan2(MATH.Sin(angle) 
                                             * MATH.Sin(angularDistance) 
                                             * MATH.Cos(latCenter) 
                                             ,MATH.Cos(angularDistance) 
                                             - MATH.Sin(latCenter) 
                                             * MATH.Sin(lat));

         circlePoints.PushBack(WsfGeoPoint.Construct(lat*180.0/MATH.PI(),lon * 180.0 / MATH.PI(),5000));
      }
      return circlePoints;
   end_script
   
   
   //
   //@ circle execute
   //
   script  void executecircularPatrol()           
      Array<WsfGeoPoint> circlePoints = generateCirclePoints(CenterPoint,Radius);
      WsfRoute route;
      WsfRoute r1 = route.Create("lx");
      foreach(WsfGeoPoint vertex in circlePoints)
      {
         vertex.SetAltitudeHAE(10000);
         r1.Append(vertex,1500);
      }
      r1.Waypoint(0).SetLabel("start");
      r1.Waypoint(r1.Size() - 1).SetGoToLabel("start");
      PLATFORM.FollowRoute(r1);
      r1.Print();
      isOver = true;
   end_script
   
   //
   // @ bounds execute 
   //
   script  void executeBoundsAreaPatrol()
      WsfZone zone = WsfZone.FindZone(zoneName);           
      Array<WsfGeoPoint> boundsPoints = zone.PolyPoints();
      WsfRoute route;
      WsfRoute r1 = route.Create("lx");
      foreach(WsfGeoPoint vertex in boundsPoints)
      {
         vertex.SetAltitudeHAE(10000);
         r1.Append(vertex,1500);
      }
      r1.Waypoint(0).SetLabel("start");
      r1.Waypoint(r1.Size() - 1).SetGoToLabel("start");
      PLATFORM.FollowRoute(r1);

      isOver = true;
   end_script
/////////////////////////////////////////////////////////////
   
   script bool isAlreadyInQueue(string name)
      for(int i = 0; i < mplatforms.Size(); i = i + 1)
      {
         if(mplatforms.Get(i) == name)
         {
            return true;
         }
      }
      return false;
   end_script

   script int sendMessage()
      if(!mplatforms.Size() == 0)
      {
         if(WsfSimulation.FindPlatform(mplatforms.Front()).IsValid())
         {
            WsfPlatform p = WsfSimulation.FindPlatform(mplatforms.Front());
#            if(p.FuelRemaining() < p.FuelBingoQuantity())
#            {
               WsfComm trackComm = WsfSimulation.FindPlatform(mplatforms.Front()).Comm("sub_net");
               WsfMessage warningMessage = WsfMessage();
               warningMessage.SetType("CANFUEL");
               warningMessage.SetSubType(PLATFORM.Name());
               PLATFORM.Comm("sub_net").SendMessage(warningMessage,trackComm);
               return 0;
#            }
         }
         else
         {
            return 0;
         }
      }
      return 0;
   end_script
   
   script bool isRange()
      if(mplatforms.Size() != 0)
      {
         WsfPlatform p = WsfSimulation.FindPlatform(mplatforms.Front());
         if(p.IsValid())
         {
            if(PLATFORM.GroundRangeTo(p) <= addFuelRange)
            {
               return true;
            }
         }
         else
         {
            mplatforms.Reverse();
            mplatforms.PopBack();
            mplatforms.Reverse();
            return false;
         }
      }
      return false;
   end_script

   script  bool gotoFuel(double fuelRange,double fuelRate)
      WsfPlatform p = WsfSimulation.FindPlatform(mplatforms.Front());
      if(p.IsValid())
      {
         WsfFuel reciveFuel = p.Fuel();
         WsfPlatform tank = PLATFORM; 
   
            WsfFuel tankFuel = tank.Fuel();
            if(!tankFuel.IsValid())
            {
               writeln("This Platform : ",p.Name()," no fuel!!!!");
               return true;
            }
            if(PLATFORM.SlantRangeTo(p) < fuelRange)
            {
               reciveFuel.SetQuantityRemaining(reciveFuel.QuantityRemaining() + (fuelRate * 1));
               tankFuel.SetQuantityRemaining(tankFuel.QuantityRemaining() - (fuelRate * 1));
               writeln("zhengziagei ; ",p.Name());                
            }
            if(reciveFuel.QuantityRemaining() >= reciveFuel.MaximumQuantity()-300)
            {
               isFuel = true;
            }
      }
      else
      {
         isFuel = true;
      }
      return isFuel;         
   end_script

//
////////////////////////////on_message///////////////////////////////
//
   on_message 
      type FUELING
         script 
            WsfMessage warningMessage = (WsfMessage)MESSAGE;
            string originator = warningMessage.Originator();
            if(!isAlreadyInQueue(originator))
            {
               mplatforms.Insert(mplatforms.Size(), originator);
            }
            writeln(PLATFORM.Name()," Report: FUELING from ", originator);
         end_script
      
      type default
         script 
            writeln(PLATFORM.Name(),"Report: Message received");
         end_script      
   end_on_message  

   script bool isArrayNull()
      return mplatforms.Size() > 0;
   end_script
   
   script void updateArray()
      if(mplatforms.Size() != 0)
      {
         mplatforms.Reverse();
         mplatforms.PopBack();
         mplatforms.Reverse();
         isFuel = false;   
      }
   end_script  

///////////////////////////////////////////////////////////////////     
execute at_time 1 s absolute 
    PROCESSOR.SetState("start");
end_execute
///////////////////////////////////////////////////////////////////   
state start
   next_state DETECTED
      return true;
   end_next_state
end_state
   
state DETECTED
   on_entry 
   if(!aendflag)
   {
     executeBoundsAreaPatrol();
   }
   end_on_entry
   
   next_state gotoTarget
      return isArrayNull();
   end_next_state
   
   on_exit 
   end_on_exit
end_state

   state gotoTarget
      on_entry
         writeln("--------------------- :",mplatforms.ToString());
#         sendMessage();
      end_on_entry
      
      next_state FUEL
         sendMessage();
         return isRange();
      end_next_state
                       
      on_exit 

      end_on_exit
   end_state
   
   state FUEL
      on_entry
      end_on_entry
      
      next_state DETECTED
         return  gotoFuel(addFuelRange,fuelRate);
      end_next_state
      
      on_exit 
         updateArray();
         PLATFORM.GoToLocation(p1);
         aendflag = true;
      end_on_exit
   end_state 
end_processor